[インデックス 15918] ファイルの概要
このコミットは、Go言語のビルドシステムにおけるARMアーキテクチャ向けのテストタイムアウト値を増加させる変更です。具体的には、src/run.bash
スクリプト内で、go test
コマンドに渡されるタイムアウト値をARM環境の場合に3倍にすることで、freebsd-arm-pi
やnetbsd-arm-qemu
といった特定のビルダーがテストを正常に完了できるようにすることを目的としています。
コミット
commit 0a517e458ce6c109e9516e9bfedaad9ee1667f2c
Author: Shenghou Ma <minux.ma@gmail.com>
Date: Sun Mar 24 16:31:28 2013 +0800
build: increase timeout for ARM
in an effort to make builder freebsd-arm-pi and netbsd-arm-qemu pass again.
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/7621050
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/0a517e458ce6c109e9516e9bfedaad9ee1667f2c
元コミット内容
build: increase timeout for ARM
in an effort to make builder freebsd-arm-pi and netbsd-arm-qemu pass again.
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/7621050
変更の背景
このコミットの背景には、Go言語の継続的インテグレーション(CI)システムにおける特定のARMベースのビルダー(freebsd-arm-pi
とnetbsd-arm-qemu
)が、テスト実行時にタイムアウトエラーで失敗していたという問題があります。これらの環境は、Raspberry Piのような組み込みシステムやQEMUのようなエミュレーション環境であり、一般的にx86/x64アーキテクチャの高性能なサーバー環境と比較して、CPU性能やI/O速度が劣る傾向にあります。
テストスイートが複雑であったり、計算負荷が高かったりする場合、これらのリソースが限られた環境では、設定されたデフォルトのタイムアウト時間内にテストが完了しないことが頻繁に発生します。テストの失敗は、コードのバグではなく、単に実行環境の性能不足に起因するものであるため、CIパイプラインの健全性を保つためには、これらの環境に合わせたタイムアウト調整が必要とされました。この変更は、これらのビルダーが再び正常にテストをパスできるようにするための直接的な対応策として導入されました。
前提知識の解説
- Go言語のビルドシステム: Go言語は、ソースコードから実行可能ファイルを生成するための独自のビルドツールチェーンを持っています。
go build
コマンドやgo test
コマンドなどがその一部です。Goのビルドシステムは、クロスコンパイル(異なるアーキテクチャやOS向けのバイナリを生成すること)を容易にする設計が特徴です。 go test
コマンド: Go言語の標準テストツールです。パッケージ内のテスト関数を実行し、結果を報告します。-timeout
フラグを使用すると、テスト全体の実行時間の上限を設定できます。この時間を超えると、テストは強制的に終了され、タイムアウトエラーとなります。- ARMアーキテクチャ: Advanced RISC Machinesの略で、モバイルデバイス、組み込みシステム、IoTデバイスなどで広く使用されているCPUアーキテクチャです。x86/x64アーキテクチャと比較して、一般的に消費電力が低く、性能あたりのコストが低いという特徴があります。しかし、その分、単一のタスク処理能力は高性能なサーバー向けCPUに劣ることが多いです。
freebsd-arm-pi
: FreeBSDオペレーティングシステム上で動作するARMベースのRaspberry Piデバイスを指すGoのビルダー名です。Raspberry Piは、低コストで高性能なシングルボードコンピュータであり、Goのテスト環境としても利用されていました。netbsd-arm-qemu
: NetBSDオペレーティングシステム上で動作するARMベースのQEMUエミュレーション環境を指すGoのビルダー名です。QEMUは、異なるCPUアーキテクチャをエミュレートできる仮想化ソフトウェアであり、物理的なARMハードウェアがなくてもテスト環境を構築するために使用されます。エミュレーションは通常、ネイティブ実行よりも性能が低下します。src/run.bash
: Goプロジェクトのルートディレクトリにあるシェルスクリプトで、Goのテストスイートを実行するためのスクリプトです。GoのCIシステムや開発者がローカルでテストを実行する際に使用されます。$GOARCH
環境変数: Goのビルドシステムで使用される環境変数で、ターゲットとするCPUアーキテクチャを示します。例えば、amd64
、arm
、arm64
などがあります。この変数の値に基づいて、ビルドやテストの動作を調整することができます。GOMAXPROCS
環境変数: Goのランタイムが同時に実行できるOSスレッドの最大数を制御する環境変数です。この値は、Goのスケジューラが利用可能なCPUコア数を決定する際に影響を与えます。テストによっては、特定のGOMAXPROCS
設定で実行されることがあります。
技術的詳細
このコミットの技術的な核心は、シェルスクリプトsrc/run.bash
内で、$GOARCH
環境変数の値に基づいてテストのタイムアウト値を動的に調整するロジックを追加した点にあります。
変更前は、go test
コマンドの-timeout
フラグには固定値(例: 120s
や240s
)が直接指定されていました。これは、高性能な環境では問題ありませんでしたが、ARMのようなリソースが限られた環境では、テストが完了する前にタイムアウトしてしまう原因となっていました。
変更後、スクリプトは以下のロジックを導入しました。
timeout_scale
という変数を導入し、初期値を1
とします。$GOARCH
がarm
であるかどうかをチェックします。- もし
$GOARCH
がarm
であれば、timeout_scale
の値を3
に設定します。 - 各
go test
コマンドの-timeout
フラグに渡す値は、元の固定値に$timeout_scale
を乗算した結果を使用するように変更されました。例えば、120s
だったタイムアウトは、ARM環境では$(expr 120 \* $timeout_scale)s
、つまり360s
(6分)になります。
このアプローチにより、ARM環境でのみテストのタイムアウト時間を延長し、他の高性能な環境では従来のタイムアウト時間を維持することができます。これにより、ARM環境でのテストの安定性を向上させつつ、他の環境でのテストが不必要に長く実行されることを防ぎます。expr
コマンドは、シェルスクリプト内で算術演算を行うために使用されます。
コアとなるコードの変更箇所
変更はsrc/run.bash
ファイルに集中しています。
--- a/src/run.bash
+++ b/src/run.bash
@@ -35,16 +35,20 @@ fi
# at least runtime/debug test will fail.
unset GOROOT_FINAL
+# increase timeout for ARM up to 3 times the normal value
+timeout_scale=1
+[ "$GOARCH" == "arm" ] && timeout_scale=3
+
echo '# Testing packages.'
-time go test std -short -timeout=120s
+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=240s -cpu=1,2,4
+GOMAXPROCS=2 go test runtime -short -timeout=$(expr 240 \* $timeout_scale)s -cpu=1,2,4
echo
echo '# sync -cpu=10'
-go test sync -short -timeout=120s -cpu=10
+go test sync -short -timeout=$(expr 120 \* $timeout_scale)s -cpu=10
# Race detector only supported on Linux and OS X,
# and only on amd64, and only when cgo is enabled.
コアとなるコードの解説
-
timeout_scale=1
:timeout_scale
というシェル変数を定義し、デフォルト値を1
に設定しています。これは、ARM以外のアーキテクチャの場合にタイムアウト値を変更しないことを意味します。 -
[ "$GOARCH" == "arm" ] && timeout_scale=3
: この行は、シェルスクリプトにおける条件分岐と論理AND演算子の組み合わせです。[ "$GOARCH" == "arm" ]
:$GOARCH
環境変数の値が文字列"arm"
と等しいかどうかをテストします。これは、GoのビルドターゲットがARMアーキテクチャである場合に真となります。&&
: 論理AND演算子です。左側のコマンド(ここでは[
コマンド)が成功した場合(終了ステータスが0の場合)にのみ、右側のコマンドが実行されます。timeout_scale=3
:$GOARCH
がarm
である場合にのみ、timeout_scale
変数の値を3
に設定します。
これにより、ARMアーキテクチャでのみ
timeout_scale
が3
となり、それ以外のアーキテクチャでは1
のままとなります。 -
time go test std -short -timeout=$(expr 120 \* $timeout_scale)s
: この行は、標準パッケージのテストを実行するコマンドです。$(expr 120 \* $timeout_scale)
: シェルのコマンド置換機能を使用しています。expr
コマンドは、引数として与えられた式を評価し、その結果を標準出力に出力します。ここでは、120
に$timeout_scale
の値を乗算しています。例えば、$timeout_scale
が3
であれば、expr
は360
を返します。s
:go test
の-timeout
フラグは、時間の単位(s
は秒、m
は分など)を必要とするため、s
が追加されています。
同様の変更が、
runtime
パッケージとsync
パッケージのテストコマンドにも適用されています。これにより、各テストのタイムアウト時間が、ARM環境では3倍に延長されることになります。
この変更は、特定のハードウェア特性(ARMの処理能力)を考慮し、CIパイプラインの信頼性を向上させるための実用的な調整であり、Goのビルドシステムが多様な環境で安定して動作するための継続的な努力の一環と言えます。
関連リンク
- Go言語の公式ドキュメント: https://go.dev/doc/
go test
コマンドのドキュメント: https://go.dev/cmd/go/#hdr-Test_packages- Goの環境変数(
GOARCH
,GOMAXPROCS
など)に関するドキュメント: https://go.dev/doc/install/source#environment - QEMUプロジェクトのウェブサイト: https://www.qemu.org/
- Raspberry Piの公式ウェブサイト: https://www.raspberrypi.com/
参考にした情報源リンク
- Go言語のソースコード(GitHubリポジトリ): https://github.com/golang/go
- Goのコードレビューシステム(Gerrit): https://go-review.googlesource.com/ (コミットメッセージに記載されている
https://golang.org/cl/7621050
は、このGerritの変更リストへのリンクです。) - シェルスクリプトの基本的な構文とコマンド(
expr
,[
など)に関する一般的な情報源。 - ARMアーキテクチャに関する一般的な情報源。
- 継続的インテグレーション(CI)の概念に関する一般的な情報源。