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

[インデックス 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つの主要なテスト実行に対して適用されています。

  1. go test std -short: 標準ライブラリのテストを短縮モードで実行します。
  2. go test runtime -short -cpu=1,2,4: runtime パッケージのテストを短縮モードで、CPUコア数を1, 2, 4で実行します。
  3. 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 オプションが追加されています。

  1. time go test std -shorttime go test std -short -timeout=120s に変更。
    • これは、Goの標準ライブラリのテストを実行するコマンドです。time はコマンドの実行時間を計測するために使用されます。
  2. go test runtime -short -cpu=1,2,4go test runtime -short -timeout=120s -cpu=1,2,4 に変更。
    • これは、Goのランタイム(実行環境)に関するテストを実行するコマンドです。-cpu=1,2,4 は、テストを異なるCPUコア数で実行し、並行処理のテストを行うためのオプションです。
  3. go test sync -short -cpu=10go test sync -short -timeout=120s -cpu=10 に変更。
    • これは、Goの sync パッケージ(同期プリミティブ)に関するテストを実行するコマンドです。-cpu=10 は、テストを10個のCPUコアで実行することをシミュレートします。

これらの変更により、Goのビルドプロセスにおいて、主要なテストスイートが2分以上実行され続けた場合、自動的に強制終了されるようになりました。これにより、テストのハングアップによるビルドの停滞を防ぎ、開発サイクルをより効率的に保つことができます。

関連リンク

参考にした情報源リンク

  • 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)