Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 19094] ファイルの概要

このコミットは、Goランタイムのテストファイル src/pkg/runtime/stack_test.go に加えられた変更です。具体的には、TestStackGrowth というスタック成長に関するテストが、testing.Short() モードでスキップされなくなるように修正されています。

コミット

commit d7ac73c869cce4f8fe5978345d74de94c319b1c0
Author: David du Colombier <0intro@gmail.com>
Date:   Thu Apr 10 06:37:30 2014 +0200

    runtime: no longer skip stack growth test in short mode
    
    We originally decided to skip this test in short mode
    to prevent the parallel runtime test to timeout on the
    Plan 9 builder. This should no longer be required since
    the issue was fixed in CL 86210043.
    
    LGTM=dave, bradfitz
    R=dvyukov, dave, bradfitz
    CC=golang-codereviews, rsc
    https://golang.org/cl/84790044

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/d7ac73c869cce4f8fe5978345d74de94c319b1c0

元コミット内容

このコミットは、Goランタイムのスタック成長テストが、go test -short コマンドで実行される「ショートモード」でスキップされないように変更します。元々、このテストはPlan 9ビルダ上での並列ランタイムテストがタイムアウトするのを防ぐためにスキップされていましたが、その根本的な問題が CL 86210043 で修正されたため、スキップする必要がなくなったという内容です。

変更の背景

この変更の背景には、Goのテストフレームワークと、特定の環境(Plan 9ビルダ)でのテスト実行におけるパフォーマンス問題がありました。

元々、TestStackGrowth テストは、go test -short オプションが指定された場合にスキップされるように実装されていました。これは、Plan 9ビルダという特定の環境で、このテストが並列実行される他のランタイムテストと競合し、タイムアウトを引き起こす可能性があったためです。Plan 9は、ベル研究所で開発された分散オペレーティングシステムであり、Goの初期開発において重要なターゲットプラットフォームの一つでした。

しかし、CL 86210043 という別の変更セット(Change List)によって、このタイムアウト問題の根本原因が解決されました。CL 86210043 は「runtime: fix stack overflow during panic」というタイトルで、パニック処理中に発生する可能性のあるスタックオーバーフローのバグを修正するものでした。この修正により、Goランタイムがパニックをより堅牢に処理できるようになり、深くネストされた関数呼び出しや大きなスタックフレームが関与するシナリオでも、パニック処理中にプログラムがスタックオーバーフローでクラッシュするのを防ぐことができました。

この根本的な問題が解決されたことで、TestStackGrowth テストをショートモードでスキップする必要がなくなりました。テストのスキップは、テストカバレッジの低下を意味するため、問題が解決された以上、テストを常に実行することが望ましいと判断されました。これにより、Goランタイムのスタック成長メカニズムが、ショートモードでのテスト実行時にも適切に検証されるようになります。

前提知識の解説

このコミットを理解するためには、以下のGo言語およびテストに関する前提知識が必要です。

  1. Goのスタック管理: Goランタイムは、goroutineごとに動的にサイズが変更されるスタックを使用します。関数呼び出しの深さに応じてスタックは自動的に拡張(grow)または縮小(shrink)します。これは、C/C++のような固定サイズのスタックとは異なり、スタックオーバーフローのリスクを軽減し、メモリ効率を高めるための重要な機能です。TestStackGrowth は、このスタックの動的な成長メカニズムが正しく機能するかを検証するテストです。

  2. testing パッケージ: Goの標準ライブラリ testing パッケージは、ユニットテストやベンチマークテストを記述するためのフレームワークを提供します。

    • *testing.T: テスト関数に渡される型で、テストの失敗報告、ログ出力、テストのスキップなどの機能を提供します。
    • t.Skip(reason string): このメソッドが呼び出されると、現在のテストはスキップされ、指定された理由が出力されます。
    • testing.Short(): この関数は、go test -short コマンドが実行された場合に true を返します。開発者がテストスイート全体を高速に実行したい場合に、時間のかかるテストをスキップするために使用されます。
  3. t.Parallel(): t.Parallel() メソッドは、テスト関数内で呼び出されると、そのテストが他の並列テストと同時に実行されることを示します。これにより、テストの実行時間を短縮できますが、並列実行によってリソース競合やデッドロックなどの問題が発生しないように、テストコードが適切に設計されている必要があります。このコミットの背景にあったPlan 9ビルダでのタイムアウト問題は、この並列実行が原因で発生していました。

  4. GoのChange List (CL): Goプロジェクトでは、コードの変更は「Change List (CL)」として提出され、レビューされます。CL 86210043CL 84790044 は、それぞれ特定の変更セットを指す識別子です。

技術的詳細

このコミットの技術的な変更は非常にシンプルですが、その背後にある意味は重要です。

変更前は、TestStackGrowth 関数内で以下のような条件分岐がありました。

func TestStackGrowth(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode")
	}
	t.Parallel()
	// ...
}

このコードは、go test -short コマンドが実行された場合(testing.Short()true を返す場合)に、t.Skip() を呼び出してテストをスキップしていました。これにより、テストの実行時間が短縮され、特にPlan 9ビルダのようなリソースが限られた環境でのタイムアウトを防ぐ目的がありました。

しかし、CL 86210043 によって、パニック時のスタックオーバーフローという根本的な問題が解決されました。この問題が解決されたことで、TestStackGrowth が並列実行される他のテストと競合してタイムアウトを引き起こす可能性がなくなった、あるいは大幅に減少したと判断されました。

したがって、このコミットでは、上記の if testing.Short() { ... } ブロック全体が削除されました。

--- a/src/pkg/runtime/stack_test.go
+++ b/src/pkg/runtime/stack_test.go
@@ -123,9 +123,6 @@ func TestStackMem(t *testing.T) {
 
 // Test stack growing in different contexts.
 func TestStackGrowth(t *testing.T) {
-\tif testing.Short() {\n-\t\tt.Skip("skipping test in short mode")\n-\t}\n \tt.Parallel()\n \tvar wg sync.WaitGroup\n 

この変更により、TestStackGrowthgo test -short が指定された場合でも常に実行されるようになります。これは、テストカバレッジを向上させ、Goランタイムのスタック成長メカニズムが様々な条件下で正しく機能することを保証するために重要です。テストのスキップは、必要な場合にのみ行われるべきであり、根本的な問題が解決された場合は削除されるべきであるという、テストプラクティスに沿った変更と言えます。

コアとなるコードの変更箇所

変更は src/pkg/runtime/stack_test.go ファイルの TestStackGrowth 関数内で行われました。

--- a/src/pkg/runtime/stack_test.go
+++ b/src/pkg/runtime/stack_test.go
@@ -123,9 +123,6 @@ func TestStackMem(t *testing.T) {
 
 // Test stack growing in different contexts.
 func TestStackGrowth(t *testing.T) {
-\tif testing.Short() {\n-\t\tt.Skip("skipping test in short mode")\n-\t}\n \tt.Parallel()\n \tvar wg sync.WaitGroup\n 

具体的には、以下の3行が削除されました。

	if testing.Short() {
		t.Skip("skipping test in short mode")
	}

コアとなるコードの解説

削除されたコードブロックは、Goのテストフレームワークが提供する testing.Short() 関数を利用して、テストがショートモードで実行されているかどうかを判定し、その場合に t.Skip() を呼び出してテストをスキップする役割を担っていました。

  • if testing.Short() {: この条件文は、go test -short コマンドが実行された場合に true となります。これにより、ショートモードでのテスト実行時にのみ、内部のブロックが実行されるように制御されていました。

  • t.Skip("skipping test in short mode"): t.Skip() メソッドは、現在のテストの実行を中断し、そのテストがスキップされたことをテスト結果に記録します。引数として渡された文字列は、スキップの理由として表示されます。

このコードブロックが削除されたことにより、TestStackGrowth テストは、go test -short が指定されているかどうかにかかわらず、常に実行されるようになりました。これは、前述の通り、Plan 9ビルダでのタイムアウト問題が CL 86210043 によって解決されたため、もはやこのテストをスキップする必要がなくなったという判断に基づいています。テストの完全性を保ち、スタック成長メカニズムの検証を常に行うことが、この変更の目的です。

関連リンク

  • このコミットのChange List: https://golang.org/cl/84790044
  • 関連する修正のChange List (CL 86210043): このコミットメッセージには直接リンクがありませんが、Web検索で得られた情報に基づくと、パニック時のスタックオーバーフローを修正したコミットです。

参考にした情報源リンク

  • Google Web Search (for CL 86210043): CL 86210043 golang の検索結果から、このCLが「runtime: fix stack overflow during panic」という内容であることが確認されました。
  • Go言語の公式ドキュメント (testingパッケージ): testing.Short()t.Parallel() の挙動について理解するために参照しました。
  • Go言語のスタック管理に関する一般的な情報: Goの動的なスタック成長メカニズムについて理解するために参照しました。