[インデックス 14281] ファイルの概要
このコミットは、Go言語のテストスクリプト src/run.bash
に、データ競合検出器(Race Detector)の健全性テストを追加するものです。これにより、データ競合検出器が正しく機能していることを継続的に検証できるようになります。
コミット
- コミットハッシュ:
95329d4cd4c036f5b0ab77eaea7927f124d81c97
- 作者: Dmitriy Vyukov dvyukov@google.com
- コミット日時: 2012年11月1日 木曜日 22:02:52 +0400
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/95329d4cd4c036f5b0ab77eaea7927f124d81c97
元コミット内容
run.bash: add sanity test for race detector
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/6612064
変更の背景
Go言語には、並行処理における一般的なバグであるデータ競合(data race)を検出するための強力なツールである「データ競合検出器(Race Detector)」が組み込まれています。この検出器は、Goプログラムの並行実行中に発生する可能性のあるメモリ競合を特定し、開発者がこれらのバグを修正するのに役立ちます。
このコミットが行われた2012年当時、Goのデータ競合検出器は比較的新しい機能でした。このような重要なツールが常に正しく機能することを保証するためには、その機能自体をテストする仕組みが必要です。src/run.bash
はGoプロジェクトの主要なテストスクリプトの一つであり、様々なGoパッケージのテストを実行する役割を担っています。このスクリプトにデータ競合検出器の健全性テストを追加することで、Goのビルドおよびテストプロセスの一部として、検出器の動作が継続的に検証されるようになります。これにより、検出器自体のリグレッション(退行)を防ぎ、その信頼性を高めることが目的です。
前提知識の解説
データ競合(Data Race)
データ競合とは、複数のゴルーチン(Goの軽量スレッド)が同時に同じメモリ位置にアクセスし、少なくとも1つのアクセスが書き込みであり、かつそれらのアクセスが同期メカニズムによって保護されていない場合に発生する並行処理のバグです。データ競合は予測不能な動作、プログラムのクラッシュ、または誤った結果を引き起こす可能性があります。
Goのデータ競合検出器(Race Detector)
Go言語には、実行時にデータ競合を検出する組み込みのツールがあります。これは、go build -race
、go run -race
、または go test -race
コマンドを使用することで有効にできます。データ競合検出器は、プログラムの実行を監視し、競合が発生した可能性のある場所を特定して報告します。これにより、開発者は並行処理のバグを効率的にデバッグできます。
go test -race
go test -race
コマンドは、指定されたパッケージのテストをデータ競合検出器を有効にして実行します。テスト中にデータ競合が検出された場合、検出器は詳細なレポート(スタックトレースなど)を出力し、テストは失敗します。
go test -race -i
-i
フラグは、テストの依存関係をインストール(ビルド)する際にデータ競合検出器を有効にするよう指示します。これは、テスト対象のコードだけでなく、その依存関係にも競合検出を適用したい場合に有用です。
go test -race -short
-short
フラグは、テストの実行時間を短縮するために、一部のテストをスキップするよう指示します。これは、CI/CDパイプラインなど、迅速なフィードバックが必要な場合に便利です。データ競合検出器の健全性テストにおいては、完全なテストスイートを実行する代わりに、基本的な機能が動作することを確認するための迅速なチェックとして使用されます。
src/run.bash
src/run.bash
は、Goプロジェクトのルートディレクトリにあるシェルスクリプトで、Goの標準ライブラリやツールのテストスイート全体を実行するために使用されます。これは、Goの継続的インテグレーション(CI)システムや開発者がローカルで広範なテストを実行する際に利用される重要なスクリプトです。
技術的詳細
このコミットは、src/run.bash
スクリプトに、特定のプラットフォーム(linux-linux-amd64
および darwin-darwin-amd64
)でのみ実行されるデータ競合検出器の健全性テストを追加します。
追加されたコードは以下の通りです。
case "$GOHOSTOS-$GOOS-$GOARCH" in
linux-linux-amd64 | darwin-darwin-amd64)
echo
echo '# Testing race detector.'
go test -race -i flag
go test -race -short flag
esac
case "$GOHOSTOS-$GOOS-$GOARCH" in ... esac
: これはシェルスクリプトのcase
文で、現在のGoのビルド環境(ホストOS、ターゲットOS、ターゲットアーキテクチャ)に基づいて条件分岐を行います。$GOHOSTOS
: Goツールチェインが動作しているホストOS。$GOOS
: ビルド対象のOS。$GOARCH
: ビルド対象のアーキテクチャ。
linux-linux-amd64 | darwin-darwin-amd64)
: このパターンは、ホストOSがLinuxでターゲットOSがLinux、アーキテクチャがAMD64の場合、またはホストOSがmacOS(Darwin)でターゲットOSがmacOS、アーキテクチャがAMD64の場合にマッチします。これは、データ競合検出器がこれらの主要な64ビットプラットフォームでサポートされ、かつ最も頻繁にテストされる環境であることを示唆しています。echo '# Testing race detector.'
: テストの開始を示すメッセージを出力します。go test -race -i flag
:flag
パッケージに対してデータ競合検出器を有効にしてテストを実行し、依存関係も競合検出を有効にしてビルドします。flag
パッケージはGoの標準ライブラリの一部であり、比較的シンプルで安定しているため、データ競合検出器の基本的な機能が動作するかどうかを確認するのに適しています。go test -race -short flag
: 同様にflag
パッケージに対してデータ競合検出器を有効にしてテストを実行しますが、-short
フラグが付いているため、より迅速なテストが実行されます。これは、検出器の基本的な動作確認を素早く行うためのものです。
これらのテストは、flag
パッケージ自体にデータ競合があることを検出するのではなく、データ競合検出器が正しく有効になり、テストプロセスに統合されていることを確認するための「健全性チェック」として機能します。もしデータ競合検出器に問題があれば、これらのテストが失敗するか、期待される出力が得られないことで、その問題が早期に発見されることになります。
コアとなるコードの変更箇所
--- a/src/run.bash
+++ b/src/run.bash
@@ -46,6 +46,14 @@ echo
echo '# sync -cpu=10'
go test sync -short -timeout=120s -cpu=10
+case "$GOHOSTOS-$GOOS-$GOARCH" in
+linux-linux-amd64 | darwin-darwin-amd64)
+ echo
+ echo '# Testing race detector.'
+ go test -race -i flag
+ go test -race -short flag
+esac
+
xcd() {
echo
echo '#' $1
コアとなるコードの解説
変更は src/run.bash
ファイルの46行目以降に追加されています。
case "$GOHOSTOS-$GOOS-$GOARCH" in
:- 現在のGoのビルド環境(ホストOS-ターゲットOS-ターゲットアーキテクチャ)の組み合わせを取得し、それに基づいて条件分岐を開始します。
- 例:
linux-linux-amd64
は、Linuxホスト上でLinuxターゲット向けにAMD64アーキテクチャでビルドしていることを意味します。
linux-linux-amd64 | darwin-darwin-amd64)
:- この行は、
case
文のパターンマッチング部分です。 - もし現在の環境が
linux-linux-amd64
またはdarwin-darwin-amd64
のいずれかであれば、続くコマンドが実行されます。 - これは、データ競合検出器がこれらの主要な64ビットプラットフォームでサポートされているため、これらの環境でのみテストを実行するように制限していることを示します。
- この行は、
echo
:- 空行を出力し、視覚的な区切りを提供します。
echo '# Testing race detector.'
:- 標準出力に「# Testing race detector.」というメッセージを出力します。これは、スクリプトの実行ログにおいて、これからデータ競合検出器のテストが開始されることを示すマーカーとなります。
go test -race -i flag
:flag
パッケージのテストをデータ競合検出器を有効にして実行します。-race
フラグはデータ競合検出器を有効にします。-i
フラグは、テストの依存関係もデータ競合検出器を有効にしてビルドするよう指示します。これにより、テスト対象のコードだけでなく、その依存関係における潜在的な競合も検出対象となります。
go test -race -short flag
:- 再び
flag
パッケージのテストをデータ競合検出器を有効にして実行します。 -short
フラグは、テストの実行時間を短縮するために、一部のテストをスキップするよう指示します。これは、データ競合検出器の基本的な機能が迅速に検証されることを保証するための、より軽量なチェックです。
- 再び
esac
:case
文の終わりを示します。
これらの追加により、Goのビルドシステムは、主要なプラットフォームにおいてデータ競合検出器が正しく機能していることを自動的に検証するようになります。
関連リンク
- Go CL 6612064: https://golang.org/cl/6612064
参考にした情報源リンク
- Go言語のデータ競合検出器に関する一般的な知識
- Goの
go test
コマンドのドキュメント - シェルスクリプトの
case
文に関する一般的な知識