[インデックス 14410] ファイルの概要
このコミットは、Go言語のテスト実行スクリプト(run.bash, run.bat, run.rc)において、../test ディレクトリ内のテストを実行する前に環境変数 GOMAXPROCS を一時的に解除(unset)する変更を導入しています。これにより、並列テスト実行やアロケーション測定を行うテストが、予期せぬ GOMAXPROCS の値によって失敗する問題を解決します。
コミット
commit 36c4a73fb2aa9f9665c71f563a3e8125c29223e2
Author: Dave Cheney <dave@cheney.net>
Date: Thu Nov 15 11:40:10 2012 +1100
run.{bash,bat,rc}: unset GOMAXPROCS before ../test
test/run.go already executes tests in parallel where
possible. An unknown GOMAXPROCS value during the tests
is known to cause failures with tests that measure
allocations.
ref: https://groups.google.com/d/topic/golang-nuts/tgMhFJ3F5WY/discussion
R=fullung, minux.ma, r
CC=golang-dev
https://golang.org/cl/6847050
---
src/run.bash | 2 +-\n src/run.bat | 7 +++++++\n src/run.rc | 2 +-\n 3 files changed, 9 insertions(+), 2 deletions(-)\n
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/36c4a73fb2aa9f9665c71f563a3e8125c29223e2
元コミット内容
run.{bash,bat,rc}: ../test を実行する前に GOMAXPROCS を解除する。
test/run.go は、可能な限りテストを並列で実行します。テスト中に不明な GOMAXPROCS の値が存在すると、アロケーションを測定するテストで失敗を引き起こすことが知られています。
参照: https://groups.google.com/d/topic/golang-nuts/tgMhFJ3F5WY/discussion
変更の背景
この変更の背景には、Go言語のテストスイートが抱えていた特定の問題があります。Goのテストフレームワークは、GOMAXPROCS 環境変数の設定に依存して、テストの並列実行を制御します。test/run.go は、Goの標準テストスイートの一部であり、テストを並列で実行する機能を持っています。
しかし、ユーザーやCI/CD環境などで GOMAXPROCS が事前に設定されている場合、その値がテスト実行に予期せぬ影響を与えることがありました。特に、メモリのアロケーション(割り当て)量を測定するようなベンチマークテストや、並列処理の挙動に敏感なテストにおいて、GOMAXPROCS の値がテスト結果の不安定化や誤った失敗を引き起こすことが報告されていました。
コミットメッセージで参照されている golang-nuts の議論(https://groups.google.com/d/topic/golang-nuts/tgMhFJ3F5WY/discussion)では、この問題が具体的に議論されています。この議論では、GOMAXPROCS が設定されていると、runtime.ReadMemStats を使用したアロケーション測定が正しく機能しないケースが指摘されています。これは、GOMAXPROCS が設定されていると、Goランタイムが利用可能なCPUコア数をその値に制限し、ガベージコレクションやスケジューリングの挙動に影響を与えるためです。アロケーション測定は、これらのランタイムの内部挙動に非常に敏感であり、GOMAXPROCS の不適切な設定がテストの信頼性を損なう原因となっていました。
このコミットは、テストの実行環境をクリーンに保ち、外部の GOMAXPROCS 設定に左右されずにテストが安定して実行されるようにするための修正です。
前提知識の解説
Go言語の環境変数 GOMAXPROCS
GOMAXPROCS は、Goランタイムが同時に実行できるOSスレッドの最大数を制御する環境変数です。Goのスケジューラは、この値に基づいてGoルーチンをOSスレッドにマッピングし、並列実行を管理します。
- デフォルト値: Go 1.5以降、
GOMAXPROCSのデフォルト値は利用可能なCPUコア数に設定されます。それ以前のバージョンでは、デフォルトは1でした。 - 影響:
GOMAXPROCSの値を変更すると、Goプログラムの並列実行性能や、ガベージコレクションのタイミング、メモリ使用量などに影響を与える可能性があります。特に、CPUバウンドな処理では、この値が性能に直結します。 - テストへの影響: テスト、特にベンチマークテストや並列処理のテストでは、
GOMAXPROCSの値がテスト結果の再現性や正確性に大きく影響することがあります。例えば、アロケーションを測定するテストでは、Goランタイムの内部的な動作(ガベージコレクションの頻度やタイミングなど)が結果に影響するため、GOMAXPROCSの設定が重要になります。
go test コマンド
go test は、Go言語のパッケージのテストを実行するためのコマンドです。
- 機能: テスト関数の実行、ベンチマークテストの実行、カバレッジレポートの生成など、Goのテストに関する主要な機能を提供します。
- 並列実行:
go testは、デフォルトでテストを並列に実行しようとします。この並列度は、GOMAXPROCSの値や、テスト関数内でt.Parallel()を呼び出すかどうかによって制御されます。
go run コマンド
go run は、Goのソースファイルをコンパイルして実行するためのコマンドです。
- 機能: ソースファイルを一時的にコンパイルし、その実行可能ファイルを生成して実行します。開発中のスクリプトや簡単なプログラムの実行によく使われます。
- テストスクリプトでの利用: このコミットで変更されている
run.goは、Goのテストスイート全体を管理・実行するためのスクリプトであり、go run run.goの形で実行されます。これは、Goのビルドシステムやテストインフラの一部として機能します。
シェルスクリプト(bash, bat, rc)
Goのプロジェクトでは、様々なプラットフォームでテストやビルドを実行するために、異なるシェルスクリプトが使用されます。
run.bash: LinuxやmacOSなどのUnix系システムで使われるBashスクリプト。run.bat: Windowsシステムで使われるバッチファイル。run.rc: Plan 9オペレーティングシステムで使われるrcシェルスクリプト。
これらのスクリプトは、Goのテストスイートを実行するための共通のインターフェースを提供し、環境変数の設定やコマンドの実行順序を制御します。
技術的詳細
このコミットの技術的な核心は、Goのテスト実行環境における GOMAXPROCS の管理です。
Goのテストスイート、特に test/run.go は、Goの標準ライブラリやランタイムのテストを網羅的に実行します。これらのテストの中には、メモリのアロケーションパターンやガベージコレクションの挙動を厳密に測定するものがあります。
GOMAXPROCS 環境変数が設定されていると、Goランタイムは指定された数のOSスレッドしか利用しません。これにより、以下のような問題が発生する可能性があります。
- アロケーション測定の不正確さ:
GOMAXPROCSが小さい値に設定されている場合、Goランタイムは利用可能なCPUリソースを十分に活用できず、ガベージコレクションの頻度やタイミングが変化します。これにより、アロケーションを測定するテスト(例:testing.B.ReportAllocs()を使用するベンチマークテスト)が、実際のメモリ使用量やパフォーマンスを正確に反映しない、あるいは予期せぬ結果を返すことがあります。 - 並列テストのデッドロックやハング:
test/run.goはテストを並列実行しますが、GOMAXPROCSが非常に小さい値(例:1)に設定されていると、並列実行が効果的に行われず、テストがデッドロックに陥ったり、タイムアウトしたりする可能性があります。これは、テストが複数のGoルーチンを起動し、それらが同時に実行されることを前提としている場合に顕著になります。 - テストの再現性の低下: 開発者の環境やCI/CDパイプラインで
GOMAXPROCSが異なる値に設定されていると、同じテストコードでも異なる結果(成功/失敗)を生じる可能性があります。これは、テストの信頼性を著しく損ないます。
このコミットは、これらの問題を解決するために、../test ディレクトリ内のテストを実行する直前に GOMAXPROCS を一時的に解除するというアプローチを取っています。
GOMAXPROCS=(Bash/rc): Bashやrcシェルでは、GOMAXPROCS=のように値を指定せずに環境変数を設定すると、その変数が解除(unset)されます。これにより、Goランタイムはデフォルトの挙動(通常は利用可能なCPUコア数を使用)に戻り、テストがより安定した環境で実行されるようになります。set GOMAXPROCS=(Batch): Windowsのバッチファイルでは、set VAR=とすることで変数を解除できます。ただし、バッチファイルでは変数のスコープが異なるため、元の値を保存し、テスト後に復元する処理が追加されています。これは、バッチファイルが環境変数を扱う際の一般的なプラクティスです。
この変更により、Goのテストスイートは、外部の GOMAXPROCS 設定に依存せず、一貫した環境で実行されるようになり、テストの信頼性と再現性が向上します。
コアとなるコードの変更箇所
このコミットでは、以下の3つのファイルが変更されています。
src/run.bash
--- a/src/run.bash
+++ b/src/run.bash
@@ -115,7 +115,7 @@ echo '#' ../test/bench/go1
go test ../test/bench/go1
(xcd ../test
-time go run run.go
+GOMAXPROCS= time go run run.go
) || exit $?
echo
src/run.bat
--- a/src/run.bat
+++ b/src/run.bat
@@ -96,15 +96,22 @@ echo.
:: TODO: The other tests in run.bash.
+
+set OLDGOMAXPROCS=%GOMAXPROCS%
+
echo # ..\test
cd ..\test
set FAIL=0
+set GOMAXPROCS=
go run run.go
if errorlevel 1 set FAIL=1
cd ..\src
echo.
if %FAIL%==1 goto fail
+set GOMAXPROCS=%OLDGOMAXPROCS%
+set OLDGOMAXPROCS=
+
echo # Checking API compatibility.
go tool api -c ..\api\go1.txt -next ..\api\next.txt -except ..\api\\except.txt
if errorlevel 1 goto fail
src/run.rc
--- a/src/run.rc
+++ b/src/run.rc
@@ -43,7 +43,7 @@ go test ../test/bench/go1
@{
xcd ../test
- time go run run.go
+ GOMAXPROCS='' time go run run.go
}
echo
コアとなるコードの解説
各スクリプトでの変更は、それぞれのシェル環境における環境変数の設定方法の違いを反映しています。
src/run.bash (Bashスクリプト)
(xcd ../test
GOMAXPROCS= time go run run.go
) || exit $?
xcd ../test:../testディレクトリに移動します。xcdはGoのビルドシステム内で定義されたヘルパー関数である可能性がありますが、ここではcdと同様にディレクトリ移動を意味します。GOMAXPROCS= time go run run.go:GOMAXPROCS=: これがこの変更の核心です。go run run.goコマンドを実行する際に、そのコマンドの環境変数GOMAXPROCSを空文字列に設定します。Bashでは、このように変数を空に設定することで、実質的にその変数を解除(unset)したのと同じ効果が得られます。これにより、run.goが実行するテストは、外部で設定されたGOMAXPROCSの影響を受けず、GoランタイムがデフォルトのCPUコア数を使用するようになります。time: コマンドの実行時間を測定します。go run run.go:test/run.goスクリプトを実行します。このスクリプトがGoのテストスイート全体を管理・実行します。
) || exit $?:go run run.goの実行が失敗した場合(終了ステータスが0以外の場合)、スクリプト全体の実行を終了します。
src/run.bat (Windowsバッチファイル)
set OLDGOMAXPROCS=%GOMAXPROCS%
echo # ..\test
cd ..\test
set FAIL=0
set GOMAXPROCS=
go run run.go
if errorlevel 1 set FAIL=1
cd ..\src
echo.
if %FAIL%==1 goto fail
set GOMAXPROCS=%OLDGOMAXPROCS%
set OLDGOMAXPROCS=
set OLDGOMAXPROCS=%GOMAXPROCS%:go run run.goを実行する前に、現在のGOMAXPROCSの値をOLDGOMAXPROCSという一時変数に保存します。これは、テスト実行後に元のGOMAXPROCSの値を復元するためです。バッチファイルでは、変数のスコープがグローバルになりがちなので、このような配慮が必要です。set GOMAXPROCS=:GOMAXPROCS環境変数を空文字列に設定します。これにより、go run run.goはGOMAXPROCSが設定されていない状態で実行されます。go run run.go:test/run.goスクリプトを実行します。set GOMAXPROCS=%OLDGOMAXPROCS%:go run run.goの実行後、保存しておいたOLDGOMAXPROCSの値をGOMAXPROCSに戻します。set OLDGOMAXPROCS=: 一時変数OLDGOMAXPROCSを解除します。
src/run.rc (Plan 9 rcシェルスクリプト)
@{
xcd ../test
GOMAXPROCS='' time go run run.go
}
@{ ... }: rcシェルにおけるコマンドブロックです。xcd ../test:../testディレクトリに移動します。GOMAXPROCS='' time go run run.go: Bashスクリプトと同様に、GOMAXPROCSを空文字列に設定してgo run run.goを実行します。rcシェルでは、変数を空文字列に設定することで解除と同じ効果が得られます。
これらの変更により、Goのテストスイートは、異なるオペレーティングシステムやシェル環境においても、GOMAXPROCS の外部設定に影響されずに安定して実行されるようになります。
関連リンク
- Go言語の公式Issue/CL: https://golang.org/cl/6847050
- golang-nuts議論: https://groups.google.com/d/topic/golang-nuts/tgMhFJ3F5WY/discussion
参考にした情報源リンク
- Go言語の公式ドキュメント (GOMAXPROCSに関する情報)
- Go言語のテストに関するドキュメント
- Bash, Windows Batch, Plan 9 rcシェルの環境変数に関するドキュメント
- https://groups.google.com/d/topic/golang-nuts/tgMhFJ3F5WY/discussion (コミットメッセージに記載の参照元)
- Go言語のソースコード (特に
src/run.bash,src/run.bat,src/run.rc,test/run.goの関連部分) - Go言語の
testingパッケージのドキュメント (アロケーション測定に関する情報) - Go言語のスケジューラに関する情報 (GOMAXPROCSとの関連)
- Dave Cheney氏のブログやGoに関する記事 (Goのパフォーマンスやランタイムに関する知見)
- Stack Overflowや技術ブログでのGoのGOMAXPROCSに関する議論```markdown
[インデックス 14410] ファイルの概要
このコミットは、Go言語のテスト実行スクリプト(run.bash, run.bat, run.rc)において、../test ディレクトリ内のテストを実行する前に環境変数 GOMAXPROCS を一時的に解除(unset)する変更を導入しています。これにより、並列テスト実行やアロケーション測定を行うテストが、予期せぬ GOMAXPROCS の値によって失敗する問題を解決します。
コミット
commit 36c4a73fb2aa9f9665c71f563a3e8125c29223e2
Author: Dave Cheney <dave@cheney.net>
Date: Thu Nov 15 11:40:10 2012 +1100
run.{bash,bat,rc}: unset GOMAXPROCS before ../test
test/run.go already executes tests in parallel where
possible. An unknown GOMAXPROCS value during the tests
is known to cause failures with tests that measure
allocations.
ref: https://groups.google.com/d/topic/golang-nuts/tgMhFJ3F5WY/discussion
R=fullung, minux.ma, r
CC=golang-dev
https://golang.org/cl/6847050
---
src/run.bash | 2 +-\n src/run.bat | 7 +++++++\n src/run.rc | 2 +-\n 3 files changed, 9 insertions(+), 2 deletions(-)\n
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/36c4a73fb2aa9f9665c71f563a3e8125c29223e2
元コミット内容
run.{bash,bat,rc}: ../test を実行する前に GOMAXPROCS を解除する。
test/run.go は、可能な限りテストを並列で実行します。テスト中に不明な GOMAXPROCS の値が存在すると、アロケーションを測定するテストで失敗を引き起こすことが知られています。
参照: https://groups.google.com/d/topic/golang-nuts/tgMhFJ3F5WY/discussion
変更の背景
この変更の背景には、Go言語のテストスイートが抱えていた特定の問題があります。Goのテストフレームワークは、GOMAXPROCS 環境変数の設定に依存して、テストの並列実行を制御します。test/run.go は、Goの標準テストスイートの一部であり、テストを並列で実行する機能を持っています。
しかし、ユーザーやCI/CD環境などで GOMAXPROCS が事前に設定されている場合、その値がテスト実行に予期せぬ影響を与えることがありました。特に、メモリのアロケーション(割り当て)量を測定するようなベンチマークテストや、並列処理の挙動に敏感なテストにおいて、GOMAXPROCS の値がテスト結果の不安定化や誤った失敗を引き起こすことが報告されていました。
コミットメッセージで参照されている golang-nuts の議論(https://groups.google.com/d/topic/golang-nuts/tgMhFJ3F5WY/discussion)では、この問題が具体的に議論されています。この議論では、GOMAXPROCS が設定されていると、runtime.ReadMemStats を使用したアロケーション測定が正しく機能しないケースが指摘されています。これは、GOMAXPROCS が設定されていると、Goランタイムが利用可能なCPUコア数をその値に制限し、ガベージコレクションやスケジューリングの挙動に影響を与えるためです。アロケーション測定は、これらのランタイムの内部挙動に非常に敏感であり、GOMAXPROCS の不適切な設定がテストの信頼性を損なう原因となっていました。
このコミットは、テストの実行環境をクリーンに保ち、外部の GOMAXPROCS 設定に左右されずにテストが安定して実行されるようにするための修正です。
前提知識の解説
Go言語の環境変数 GOMAXPROCS
GOMAXPROCS は、Goランタイムが同時に実行できるOSスレッドの最大数を制御する環境変数です。Goのスケジューラは、この値に基づいてGoルーチンをOSスレッドにマッピングし、並列実行を管理します。
- デフォルト値: Go 1.5以降、
GOMAXPROCSのデフォルト値は利用可能なCPUコア数に設定されます。それ以前のバージョンでは、デフォルトは1でした。 - 影響:
GOMAXPROCSの値を変更すると、Goプログラムの並列実行性能や、ガベージコレクションのタイミング、メモリ使用量などに影響を与える可能性があります。特に、CPUバウンドな処理では、この値が性能に直結します。 - テストへの影響: テスト、特にベンチマークテストや並列処理のテストでは、
GOMAXPROCSの値がテスト結果の再現性や正確性に大きく影響することがあります。例えば、アロケーションを測定するテストでは、Goランタイムの内部的な動作(ガベージコレクションの頻度やタイミングなど)が結果に影響するため、GOMAXPROCSの設定が重要になります。
go test コマンド
go test は、Go言語のパッケージのテストを実行するためのコマンドです。
- 機能: テスト関数の実行、ベンチマークテストの実行、カバレッジレポートの生成など、Goのテストに関する主要な機能を提供します。
- 並列実行:
go testは、デフォルトでテストを並列に実行しようとします。この並列度は、GOMAXPROCSの値や、テスト関数内でt.Parallel()を呼び出すかどうかによって制御されます。
go run コマンド
go run は、Goのソースファイルをコンパイルして実行するためのコマンドです。
- 機能: ソースファイルを一時的にコンパイルし、その実行可能ファイルを生成して実行します。開発中のスクリプトや簡単なプログラムの実行によく使われます。
- テストスクリプトでの利用: このコミットで変更されている
run.goは、Goのテストスイート全体を管理・実行するためのスクリプトであり、go run run.goの形で実行されます。これは、Goのビルドシステムやテストインフラの一部として機能します。
シェルスクリプト(bash, bat, rc)
Goのプロジェクトでは、様々なプラットフォームでテストやビルドを実行するために、異なるシェルスクリプトが使用されます。
run.bash: LinuxやmacOSなどのUnix系システムで使われるBashスクリプト。run.bat: Windowsシステムで使われるバッチファイル。run.rc: Plan 9オペレーティングシステムで使われるrcシェルスクリプト。
これらのスクリプトは、Goのテストスイートを実行するための共通のインターフェースを提供し、環境変数の設定やコマンドの実行順序を制御します。
技術的詳細
このコミットの技術的な核心は、Goのテスト実行環境における GOMAXPROCS の管理です。
Goのテストスイート、特に test/run.go は、Goの標準ライブラリやランタイムのテストを網羅的に実行します。これらのテストの中には、メモリのアロケーションパターンやガベージコレクションの挙動を厳密に測定するものがあります。
GOMAXPROCS 環境変数が設定されていると、Goランタイムは指定された数のOSスレッドしか利用しません。これにより、以下のような問題が発生する可能性があります。
- アロケーション測定の不正確さ:
GOMAXPROCSが小さい値に設定されている場合、Goランタイムは利用可能なCPUリソースを十分に活用できず、ガベージコレクションの頻度やタイミングが変化します。これにより、アロケーションを測定するテスト(例:testing.B.ReportAllocs()を使用するベンチマークテスト)が、実際のメモリ使用量やパフォーマンスを正確に反映しない、あるいは予期せぬ結果を返すことがあります。 - 並列テストのデッドロックやハング:
test/run.goはテストを並列実行しますが、GOMAXPROCSが非常に小さい値(例:1)に設定されていると、並列実行が効果的に行われず、テストがデッドロックに陥ったり、タイムアウトしたりする可能性があります。これは、テストが複数のGoルーチンを起動し、それらが同時に実行されることを前提としている場合に顕著になります。 - テストの再現性の低下: 開発者の環境やCI/CDパイプラインで
GOMAXPROCSが異なる値に設定されていると、同じテストコードでも異なる結果(成功/失敗)を生じる可能性があります。これは、テストの信頼性を著しく損ないます。
このコミットは、これらの問題を解決するために、../test ディレクトリ内のテストを実行する直前に GOMAXPROCS を一時的に解除するというアプローチを取っています。
GOMAXPROCS=(Bash/rc): Bashやrcシェルでは、GOMAXPROCS=のように値を指定せずに環境変数を設定すると、その変数が解除(unset)されます。これにより、Goランタイムはデフォルトの挙動(通常は利用可能なCPUコア数を使用)に戻り、テストがより安定した環境で実行されるようになります。set GOMAXPROCS=(Batch): Windowsのバッチファイルでは、set VAR=とすることで変数を解除できます。ただし、バッチファイルでは変数のスコープが異なるため、元の値を保存し、テスト後に復元する処理が追加されています。これは、バッチファイルが環境変数を扱う際の一般的なプラクティスです。
この変更により、Goのテストスイートは、外部の GOMAXPROCS 設定に依存せず、一貫した環境で実行されるようになり、テストの信頼性と再現性が向上します。
コアとなるコードの変更箇所
このコミットでは、以下の3つのファイルが変更されています。
src/run.bash
--- a/src/run.bash
+++ b/src/run.bash
@@ -115,7 +115,7 @@ echo '#' ../test/bench/go1
go test ../test/bench/go1
(xcd ../test
-time go run run.go
+GOMAXPROCS= time go run run.go
) || exit $?
echo
src/run.bat
--- a/src/run.bat
+++ b/src/run.bat
@@ -96,15 +96,22 @@ echo.
:: TODO: The other tests in run.bash.
+
+set OLDGOMAXPROCS=%GOMAXPROCS%
+
echo # ..\test
cd ..\test
set FAIL=0
+set GOMAXPROCS=
go run run.go
if errorlevel 1 set FAIL=1
cd ..\src
echo.
if %FAIL%==1 goto fail
+set GOMAXPROCS=%OLDGOMAXPROCS%
+set OLDGOMAXPROCS=
+
echo # Checking API compatibility.
go tool api -c ..\api\go1.txt -next ..\api\\next.txt -except ..\api\\except.txt
if errorlevel 1 goto fail
src/run.rc
--- a/src/run.rc
+++ b/src/run.rc
@@ -43,7 +43,7 @@ go test ../test/bench/go1
@{
xcd ../test
- time go run run.go
+ GOMAXPROCS='' time go run run.go
}
echo
コアとなるコードの解説
各スクリプトでの変更は、それぞれのシェル環境における環境変数の設定方法の違いを反映しています。
src/run.bash (Bashスクリプト)
(xcd ../test
GOMAXPROCS= time go run run.go
) || exit $?
xcd ../test:../testディレクトリに移動します。xcdはGoのビルドシステム内で定義されたヘルパー関数である可能性がありますが、ここではcdと同様にディレクトリ移動を意味します。GOMAXPROCS= time go run run.go:GOMAXPROCS=: これがこの変更の核心です。go run run.goコマンドを実行する際に、そのコマンドの環境変数GOMAXPROCSを空文字列に設定します。Bashでは、このように変数を空に設定することで、実質的にその変数を解除(unset)したのと同じ効果が得られます。これにより、run.goが実行するテストは、外部で設定されたGOMAXPROCSの影響を受けず、GoランタイムがデフォルトのCPUコア数を使用するようになります。time: コマンドの実行時間を測定します。go run run.go:test/run.goスクリプトを実行します。このスクリプトがGoのテストスイート全体を管理・実行します。
) || exit $?:go run run.goの実行が失敗した場合(終了ステータスが0以外の場合)、スクリプト全体の実行を終了します。
src/run.bat (Windowsバッチファイル)
set OLDGOMAXPROCS=%GOMAXPROCS%
echo # ..\test
cd ..\test
set FAIL=0
set GOMAXPROCS=
go run run.go
if errorlevel 1 set FAIL=1
cd ..\src
echo.
if %FAIL%==1 goto fail
set GOMAXPROCS=%OLDGOMAXPROCS%
set OLDGOMAXPROCS=
set OLDGOMAXPROCS=%GOMAXPROCS%:go run run.goを実行する前に、現在のGOMAXPROCSの値をOLDGOMAXPROCSという一時変数に保存します。これは、テスト実行後に元のGOMAXPROCSの値を復元するためです。バッチファイルでは、変数のスコープがグローバルになりがちなので、このような配慮が必要です。set GOMAXPROCS=:GOMAXPROCS環境変数を空文字列に設定します。これにより、go run run.goはGOMAXPROCSが設定されていない状態で実行されます。go run run.go:test/run.goスクリプトを実行します。set GOMAXPROCS=%OLDGOMAXPROCS%:go run run.goの実行後、保存しておいたOLDGOMAXPROCSの値をGOMAXPROCSに戻します。set OLDGOMAXPROCS=: 一時変数OLDGOMAXPROCSを解除します。
src/run.rc (Plan 9 rcシェルスクリプト)
@{
xcd ../test
GOMAXPROCS='' time go run run.go
}
@{ ... }: rcシェルにおけるコマンドブロックです。xcd ../test:../testディレクトリに移動します。GOMAXPROCS='' time go run run.go: Bashスクリプトと同様に、GOMAXPROCSを空文字列に設定してgo run run.goを実行します。rcシェルでは、変数を空文字列に設定することで解除と同じ効果が得られます。
これらの変更により、Goのテストスイートは、異なるオペレーティングシステムやシェル環境においても、GOMAXPROCS の外部設定に影響されずに安定して実行されるようになります。
関連リンク
- Go言語の公式Issue/CL: https://golang.org/cl/6847050
- golang-nuts議論: https://groups.google.com/d/topic/golang-nuts/tgMhFJ3F5WY/discussion
参考にした情報源リンク
- Go言語の公式ドキュメント (GOMAXPROCSに関する情報)
- Go言語のテストに関するドキュメント
- Bash, Windows Batch, Plan 9 rcシェルの環境変数に関するドキュメント
- https://groups.google.com/d/topic/golang-nuts/tgMhFJ3F5WY/discussion (コミットメッセージに記載の参照元)
- Go言語のソースコード (特に
src/run.bash,src/run.bat,src/run.rc,test/run.goの関連部分) - Go言語の
testingパッケージのドキュメント (アロケーション測定に関する情報) - Go言語のスケジューラに関する情報 (GOMAXPROCSとの関連)
- Dave Cheney氏のブログやGoに関する記事 (Goのパフォーマンスやランタイムに関する知見)
- Stack Overflowや技術ブログでのGoのGOMAXPROCSに関する議論