[インデックス 11587] ファイルの概要
このコミットは、Go言語のビルドシステムにおいて、テストが無限に実行され続けることを防ぐための変更を導入しています。具体的には、go test
コマンドにタイムアウトオプションを追加することで、テストの実行時間を制限し、ハングアップしたテストがビルドプロセス全体を停止させることを回避します。
コミット
commit 8f9434b6c187b590c542a5d211f771d63a8c5bbf
Author: Alex Brainman <alex.brainman@gmail.com>
Date: Fri Feb 3 16:45:51 2012 +1100
build: crash if test runs forever
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5604051
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/8f9434b6c187b590c542a5d211f771d63a8c5bbf
元コミット内容
build: crash if test runs forever
変更の背景
ソフトウェア開発において、テストはコードの品質と安定性を保証するために不可欠です。しかし、テストコード自体にバグがあったり、特定の環境下でデッドロックや無限ループに陥ったりすることがあります。このような状況が発生すると、テストスイート全体の実行が停止し、CI/CDパイプラインがブロックされたり、開発者の時間を無駄にしたりする可能性があります。
このコミットが行われた背景には、Go言語のビルドプロセスにおけるテスト実行が、何らかの理由でハングアップし、永遠に終了しないという問題があったと考えられます。このような問題は、特に大規模なプロジェクトや、並行処理を多用するシステムにおいて発生しやすく、ビルドシステムの信頼性を低下させます。この変更は、このようなハングアップを検出し、強制的にテストプロセスを終了させることで、ビルドの安定性と効率性を向上させることを目的としています。
前提知識の解説
go test
コマンド
go test
は、Go言語の標準的なテスト実行ツールです。Goのテストは、_test.go
というサフィックスを持つファイルに記述され、TestXxx
という形式の関数として定義されます。go test
コマンドは、これらのテスト関数を自動的に発見し、実行します。
テストのタイムアウト
テストのタイムアウトは、テストが指定された時間内に完了しない場合に、そのテストを強制的に終了させるメカニズムです。これは、テストが無限ループに陥ったり、デッドロックしたりするのを防ぐために非常に重要です。タイムアウトを設定することで、テストスイート全体の実行が長時間ブロックされることを避け、CI/CDパイプラインの効率を維持できます。
go test
コマンドには、-timeout
フラグがあり、これを使用することでテスト実行全体のタイムアウトを設定できます。このフラグに指定された時間を超えてテストバイナリが実行され続けると、パニック(強制終了)します。
src/run.bash
src/run.bash
は、Go言語のプロジェクトにおけるビルドやテストの実行スクリプトの一部である可能性が高いです。このようなスクリプトは、通常、開発者がGoプロジェクトをビルド、テスト、デプロイする際に使用する一連のコマンドを自動化するために使用されます。このファイルは、Goプロジェクトのテスト実行環境をセットアップし、go test
コマンドを呼び出す役割を担っていると考えられます。
技術的詳細
このコミットの技術的な核心は、go test
コマンドに -timeout
フラグを追加することです。
go test -timeout <duration>
ここで <duration>
は、テストが実行される最大時間を指定します。Go言語のduration形式(例: 10s
で10秒、5m
で5分、1h
で1時間)で指定します。
このコミットでは、120s
(120秒、つまり2分) のタイムアウトが設定されています。これは、以下の3つの主要なテスト実行に対して適用されています。
go test std -short
: 標準ライブラリのテストを短縮モードで実行します。go test runtime -short -cpu=1,2,4
:runtime
パッケージのテストを短縮モードで、CPUコア数を1, 2, 4で実行します。go test sync -short -cpu=10
:sync
パッケージのテストを短縮モードで、CPUコア数を10で実行します。
これらのテストは、Go言語のコア部分の安定性を保証するために非常に重要です。これらのテストにタイムアウトを設定することで、万が一テストがハングアップした場合でも、ビルドプロセス全体が無限に待機することなく、2分後に強制終了されるようになります。これにより、CI/CDシステムがテストのハングアップを検出し、迅速にフィードバックを提供できるようになります。
-timeout
フラグは、個々のテストケースではなく、go test
コマンドによって起動されるテストバイナリ全体に適用されます。つまり、指定された時間内にすべてのテストが完了しない場合、テストプロセス全体が終了します。
コアとなるコードの変更箇所
--- a/src/run.bash
+++ b/src/run.bash
@@ -38,15 +38,15 @@ fi
echo
echo '# Package tests'
-time go test std -short
+time go test std -short -timeout=120s
echo
echo '# runtime -cpu=1,2,4'
-go test runtime -short -cpu=1,2,4
+go test runtime -short -timeout=120s -cpu=1,2,4
echo
echo '# sync -cpu=10'
-go test sync -short -cpu=10
+go test sync -short -timeout=120s -cpu=10
echo
echo '# Build bootstrap scripts'
コアとなるコードの解説
上記のdiffは、src/run.bash
ファイルに対する変更を示しています。
-
で始まる行: 変更前の元のコードを示します。+
で始まる行: 変更後の新しいコードを示します。
具体的には、以下の3つの go test
コマンドの呼び出しに、-timeout=120s
オプションが追加されています。
time go test std -short
がtime go test std -short -timeout=120s
に変更。- これは、Goの標準ライブラリのテストを実行するコマンドです。
time
はコマンドの実行時間を計測するために使用されます。
- これは、Goの標準ライブラリのテストを実行するコマンドです。
go test runtime -short -cpu=1,2,4
がgo test runtime -short -timeout=120s -cpu=1,2,4
に変更。- これは、Goのランタイム(実行環境)に関するテストを実行するコマンドです。
-cpu=1,2,4
は、テストを異なるCPUコア数で実行し、並行処理のテストを行うためのオプションです。
- これは、Goのランタイム(実行環境)に関するテストを実行するコマンドです。
go test sync -short -cpu=10
がgo test sync -short -timeout=120s -cpu=10
に変更。- これは、Goの
sync
パッケージ(同期プリミティブ)に関するテストを実行するコマンドです。-cpu=10
は、テストを10個のCPUコアで実行することをシミュレートします。
- これは、Goの
これらの変更により、Goのビルドプロセスにおいて、主要なテストスイートが2分以上実行され続けた場合、自動的に強制終了されるようになりました。これにより、テストのハングアップによるビルドの停滞を防ぎ、開発サイクルをより効率的に保つことができます。
関連リンク
- Go言語の公式ドキュメント: https://golang.org/
- Goのテストに関するドキュメント: https://pkg.go.dev/testing
- このコミットに関連するGoの変更リスト (CL): https://golang.org/cl/5604051
参考にした情報源リンク
go test
command documentation (via web search)- Stack Overflow discussions on
go test -timeout
(via web search) - golangbridge.org discussions on
go test -timeout
(via web search)