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

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

このコミットは、Go言語のランタイムテストにおけるタイムアウト時間の延長に関するものです。特に、netbsd-arm-qemu ビルダー上でのテスト実行時間が、既存のタイムアウト制限に非常に近づいていた問題に対処しています。

コミット

  • コミットハッシュ: 0ce56e60b80d65c9677d148e885b575e21583260
  • 作者: Shenghou Ma minux.ma@gmail.com
  • コミット日時: 2013年7月13日 土曜日 02:00:07 +0800

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

https://github.com/golang/go/commit/0ce56e60b80d65c9677d148e885b575e21583260

元コミット内容

    run.bash: enlarge timeout of runtime tests
    Recently addition to runtime test makes it take very close to 720s
    of timeout limit on the netbsd-arm-qemu builder.
    
    R=golang-dev, go.peter.90, rsc
    CC=golang-dev
    https://golang.org/cl/10935043

変更の背景

このコミットの背景には、Go言語の継続的インテグレーション (CI) システムにおける特定のビルダー、netbsd-arm-qemu 上でのランタイムテストの実行時間に関する問題があります。

Goプロジェクトでは、様々なアーキテクチャやオペレーティングシステム上でコードが正しく動作することを保証するために、多数のビルダー(CIエージェント)が使用されています。netbsd-arm-qemu は、NetBSDオペレーティングシステム上でARMアーキテクチャをQEMU(Quick Emulator)を用いてエミュレートする環境を指します。このようなエミュレーション環境は、実際のハードウェアよりも処理能力が低いことが一般的です。

コミットメッセージによると、「最近のランタイムテストへの追加」により、このnetbsd-arm-qemu ビルダー上でのテスト実行時間が、設定されていた720秒(12分)のタイムアウト制限に「非常に近づいて」いました。これは、テストが不安定になり、タイムアウトによって失敗する可能性が高まっていることを意味します。テストの失敗は、実際のバグではなく、単に実行環境の制約によるものであるため、開発プロセスを妨げ、誤ったアラートを引き起こす可能性があります。

この問題を解決し、テストの安定性を確保するために、ランタイムテストのタイムアウト時間を延長する必要が生じました。

前提知識の解説

このコミットを理解するためには、以下のGo言語のテストおよびビルドシステムに関する知識が役立ちます。

  1. go test コマンド: go test は、Go言語の標準的なテスト実行ツールです。パッケージ内のテスト関数(Testで始まる関数)を実行し、結果を報告します。

    • -short フラグ: テストの実行時間を短縮するためのフラグです。通常、時間のかかるテストをスキップするために使用されます。CI環境では、迅速なフィードバックを得るためにこのフラグがよく使われます。
    • -timeout フラグ: テストの実行時間の上限を設定します。指定された時間を超えてテストが完了しない場合、テストは強制終了され、タイムアウトエラーとして報告されます。このフラグは、無限ループやデッドロックなど、テストがハングアップするのを防ぐために重要です。単位は秒(s)、分(m)、時間(h)などで指定できます。
    • -cpu フラグ: テストを並行して実行するCPUの数を指定します。例えば、-cpu=1,2,4 は、テストを1コア、2コア、4コアのそれぞれで実行し、並行処理における挙動を確認するために使用されます。
  2. GOMAXPROCS 環境変数: GOMAXPROCS は、Goランタイムが同時に実行できるOSスレッドの最大数を制御する環境変数です。この値は、Goスケジューラが利用できる論理プロセッサの数を決定します。GOMAXPROCS=2 と設定することは、Goランタイムが最大2つのOSスレッドを使用してGoルーチンを実行することを意味します。これは、並行処理のテストや、特定のCPUコア数でのパフォーマンス特性を評価する際に重要です。

  3. runtime パッケージのテスト: Goの runtime パッケージは、ガベージコレクタ、スケジューラ、メモリ管理など、Goプログラムの実行を支える低レベルな機能を提供します。このパッケージのテストは、Goランタイムの安定性とパフォーマンスを保証するために非常に重要であり、しばしば計算資源を多く消費し、実行に時間がかかる傾向があります。

  4. run.bash スクリプト: Goプロジェクトのルートディレクトリにある run.bash は、Goのテストスイート全体を実行するためのシェルスクリプトです。CIシステムや開発者がローカルでテストを実行する際に使用されます。このスクリプト内で、様々なテストコマンド(go test stdgo test runtimeなど)が、特定のフラグや環境変数とともに呼び出されます。

  5. timeout_scale 変数: run.bash スクリプト内で使用されている timeout_scale は、テストのタイムアウト時間を調整するための変数です。これは、異なる環境(例えば、低速なビルダーやエミュレーション環境)でテストを実行する際に、タイムアウト値を柔軟にスケーリングするために導入されたものと考えられます。この変数を乗算することで、基本となるタイムアウト値が環境に応じて調整されます。

  6. netbsd-arm-qemu ビルダー: 前述の通り、これはNetBSD上でARMアーキテクチャをQEMUでエミュレートするCI環境です。エミュレーションによるオーバーヘッドのため、物理的なハードウェアと比較してCPUやI/Oのパフォーマンスが著しく低いことが予想されます。これが、テストがタイムアウトに近づく原因となった主要な要因です。

技術的詳細

このコミットの技術的な変更は非常にシンプルですが、その背後にはGoのCIシステムとテストの安定性に関する重要な考慮事項があります。

変更は、src/run.bash スクリプト内の go test runtime コマンドのタイムアウト設定に焦点を当てています。

元の設定では、GOMAXPROCS=2 で実行される go test runtime のタイムアウトは $(expr 240 \* $timeout_scale)s となっていました。ここで 240 は基本となる秒数です。

新しい設定では、この基本秒数が 240 から 300 に変更されています。これにより、go test runtime のタイムアウト時間が (300 - 240) * $timeout_scale 秒だけ延長されます。

コミットメッセージによると、netbsd-arm-qemu ビルダーでのタイムアウト制限が720秒(12分)であり、テストがこの値に非常に近づいていたとのことです。元のタイムアウト設定が 240 * $timeout_scale であった場合、$timeout_scale720 / 240 = 3 程度であったと推測できます。この場合、元のタイムアウトは 240 * 3 = 720 秒となります。

タイムアウトを 300 * $timeout_scale に変更することで、新しいタイムアウトは 300 * 3 = 900 秒(15分)となります。これにより、netbsd-arm-qemu のような低速な環境でも、ランタイムテストが安定して完了するための十分な猶予が与えられます。

この変更は、テストのロジック自体を変更するものではなく、テストが完了するまでの許容時間を増やすことで、CIの信頼性を向上させることを目的としています。テストがタイムアウトで失敗することは、開発者にとって誤解を招く可能性があり、実際のバグではないにもかかわらず、調査に時間を要する場合があります。タイムアウトの延長は、このような「偽陽性」の失敗を減らし、CIパイプラインのスムーズな運用に貢献します。

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

変更は src/run.bash ファイルの1行のみです。

--- a/src/run.bash
+++ b/src/run.bash
@@ -49,7 +49,7 @@ time go test std -short -timeout=$(expr 120 \* $timeout_scale)s
 echo
 
 echo '# GOMAXPROCS=2 runtime -cpu=1,2,4'
-GOMAXPROCS=2 go test runtime -short -timeout=$(expr 240 \* $timeout_scale)s -cpu=1,2,4
+GOMAXPROCS=2 go test runtime -short -timeout=$(expr 300 \* $timeout_scale)s -cpu=1,2,4
 echo
 
 echo '# sync -cpu=10'

コアとなるコードの解説

変更された行は以下の通りです。

GOMAXPROCS=2 go test runtime -short -timeout=$(expr 300 \* $timeout_scale)s -cpu=1,2,4

この行は、go test コマンドを使用してGoの runtime パッケージのテストを実行しています。

  • GOMAXPROCS=2: Goランタイムが最大2つのOSスレッドを使用するように設定しています。これは、並行処理のテストシナリオをシミュレートするためです。
  • go test runtime: runtime パッケージ内のテストを実行します。
  • -short: 短時間で完了するテストのみを実行します。
  • -timeout=$(expr 300 \* $timeout_scale)s: テストのタイムアウト時間を設定しています。expr 300 \* $timeout_scale は、300timeout_scale 変数の値を乗算した結果を秒単位のタイムアウトとして指定します。元の値は 240 でしたが、このコミットで 300 に変更されました。
  • -cpu=1,2,4: テストを1コア、2コア、4コアのそれぞれで実行し、異なるCPU設定でのランタイムの挙動を検証します。

この変更により、runtime テストが netbsd-arm-qemu のような低速な環境でも、タイムアウトせずに完了する可能性が高まりました。

関連リンク

参考にした情報源リンク