[インデックス 10832] ファイルの概要
このコミットは、Go言語の標準ライブラリ os/exec
パッケージのテストコードにおける変更を扱っています。具体的には、go test
コマンドの -test.run
フラグに渡す引数の形式を、新しい go test
の挙動に合わせて修正しています。これにより、テストヘルパープロセスを起動する際のテスト名指定が適切に行われるようになります。
コミット
os/exec: fix -test.run argument for new 'go test'
In 'go test' I deleted the leading package. prefix
from all the test names, since it contained no actual
information. Adjust the -test.run argument accordingly.
This will still work with the current gotest too, since
the argument is an unanchored pattern.
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5491058
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/b53856c16dc1facdc5c0257bd8b0ef4cff13d350
元コミット内容
os/exec: fix -test.run argument for new 'go test'
In 'go test' I deleted the leading package. prefix
from all the test names, since it contained no actual
information. Adjust the -test.run argument accordingly.
This will still work with the current gotest too, since
the argument is an unanchored pattern.
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5491058
変更の背景
この変更は、Go言語のテストツール go test
の内部的な挙動変更に対応するために行われました。以前の go test
では、テスト関数名が パッケージ名.テスト関数名
の形式で認識されていました(例: exec.TestHelperProcess
)。しかし、この「パッケージ名.」の部分は冗長であり、実際のテスト関数を特定する上で不要な情報でした。
Russ Cox氏による go test
の変更(このコミットの少し前に行われたと推測されます)により、テスト関数名からこの先頭のパッケージプレフィックスが削除され、単に テスト関数名
の形式で扱われるようになりました(例: TestHelperProcess
)。
os/exec
パッケージのテストコードでは、helperCommand
という関数内で、自身をテストヘルパープロセスとして再起動する際に、-test.run
フラグを使って特定のテスト関数(TestHelperProcess
)を実行するように指定していました。この指定が古い形式(exec.TestHelperProcess
)のままでは、新しい go test
の挙動と合致せず、テストが正しく実行されない可能性がありました。
このコミットは、この不整合を解消し、go test
の新しい命名規則に合わせて -test.run
の引数を修正することで、テストの互換性と正確性を維持することを目的としています。コミットメッセージにある「This will still work with the current gotest too, since the argument is an unanchored pattern.」という記述は、この変更が古い go test
のバージョンでも問題なく動作することを示しており、これは -test.run
が正規表現パターンを受け付け、そのパターンが文字列の先頭に固定されていない(unanchored)ため、部分一致でも機能するという特性を利用していることを意味します。
前提知識の解説
Go言語のテスト (go test
)
Go言語には、標準で強力なテストフレームワークが組み込まれています。go test
コマンドは、Goのソースコード内のテストファイル(ファイル名が _test.go
で終わるもの)を自動的に検出し、テスト関数(関数名が Test
で始まるもの)を実行します。
-test.run
フラグ
go test
コマンドには様々なフラグがありますが、-test.run
は特定のテスト関数やテストスイートのみを実行するために使用されます。このフラグには正規表現パターンを引数として渡すことができ、そのパターンにマッチする名前のテスト関数のみが実行されます。
例:
go test -test.run TestMyFunction
:TestMyFunction
という名前のテスト関数のみを実行。go test -test.run "Test.*"
:Test
で始まるすべてのテスト関数を実行。
テストヘルパープロセス (Test Helper Process)
Goのテストでは、特定のシナリオ(例えば、外部コマンドの実行、ネットワーク通信のシミュレーションなど)をテストするために、テストコード自身を別のプロセスとして起動し、そのプロセスに特定の処理を行わせる「テストヘルパープロセス」というテクニックがよく用いられます。
これは通常、以下のようなパターンで実装されます。
- メインのテスト関数内で、
os.Args[0]
(現在の実行可能ファイルのパス)を使って自身を再起動するexec.Command
を作成します。 - 再起動するコマンドの引数に、特定の環境変数(例:
GO_WANT_HELPER_PROCESS=1
)や、-test.run
フラグでヘルパー関数を指定します。 - プログラムのエントリポイント(
main
関数など)で、その環境変数が設定されているかどうかをチェックし、設定されていればヘルパー関数を実行して終了します。
このコミットの対象となっている os/exec
パッケージは、まさに外部コマンドの実行を扱うため、このようなヘルパープロセスを利用してテストを行っています。
正規表現 (Regular Expression)
正規表現は、文字列のパターンを記述するための強力なツールです。-test.run
フラグは正規表現パターンを受け入れるため、部分一致や複雑なマッチングが可能です。このコミットの文脈では、「unanchored pattern」(アンカーされていないパターン)という点が重要です。これは、パターンが文字列の先頭や末尾に固定されていないことを意味し、文字列のどの位置にパターンが出現してもマッチすることを許容します。
例えば、パターン TestHelperProcess
は、exec.TestHelperProcess
の中にも TestHelperProcess
の中にも部分的にマッチします。これが、古い go test
の挙動でもこの変更が機能する理由です。
技術的詳細
このコミットの技術的な核心は、go test
コマンドがテスト関数名をどのように解釈するか、そして -test.run
フラグがその解釈にどのように影響するかという点にあります。
以前の go test
では、テスト関数は内部的に パッケージ名.テスト関数名
という完全修飾名で管理されていました。例えば、os/exec
パッケージ内の TestHelperProcess
関数は exec.TestHelperProcess
として扱われていました。
しかし、この完全修飾名は、テストの実行やフィルタリングにおいて冗長であり、特にユーザーが -test.run
でテストを指定する際に、常にパッケージ名を含める必要があるのは不便でした。そのため、go test
の改善の一環として、テスト関数名から先頭のパッケージプレフィックスを削除し、より簡潔な テスト関数名
の形式で扱うように変更されました。
この変更により、os/exec
パッケージの exec_test.go
内の helperCommand
関数が影響を受けました。この関数は、テストヘルパープロセスを起動する際に、os.Args[0]
を使って現在のテストバイナリを再実行し、-test.run=exec.TestHelperProcess
という引数を渡していました。新しい go test
の挙動では、exec.TestHelperProcess
という名前のテスト関数は存在しないため、この引数では目的の TestHelperProcess
関数が実行されなくなります。
コミットは、この引数を TestHelperProcess
に変更することで、新しい go test
の命名規則に適合させました。
重要なのは、この変更が古い go test
のバージョンでも動作するという点です。これは、-test.run
が正規表現パターンを受け入れるためです。
- 古い
go test
の場合、内部的にはexec.TestHelperProcess
という名前のテスト関数が存在します。 - 新しい
-test.run=TestHelperProcess
というパターンは、exec.TestHelperProcess
という文字列に対して部分的にマッチします(TestHelperProcess
の部分がマッチ)。 -test.run
のパターンは「unanchored」(アンカーされていない)であるため、文字列のどの位置にパターンが出現してもマッチします。
したがって、この修正は後方互換性を保ちつつ、将来の go test
の挙動にも対応できる賢明な変更と言えます。
コアとなるコードの変更箇所
変更は src/pkg/os/exec/exec_test.go
ファイルの1箇所のみです。
--- a/src/pkg/os/exec/exec_test.go
+++ b/src/pkg/os/exec/exec_test.go
@@ -18,7 +18,7 @@ import (
)
func helperCommand(s ...string) *Cmd {
- cs := []string{"-test.run=exec.TestHelperProcess", "--"}
+ cs := []string{"-test.run=TestHelperProcess", "--"}
cs = append(cs, s...)\n cmd := Command(os.Args[0], cs...)
cmd.Env = append([]string{"GO_WANT_HELPER_PROCESS=1"}, os.Environ()...)
具体的には、helperCommand
関数内で cs
スライスを初期化する行が変更されています。
- 変更前:
cs := []string{"-test.run=exec.TestHelperProcess", "--"}
- 変更後:
cs := []string{"-test.run=TestHelperProcess", "--"}
exec.TestHelperProcess
から exec.
プレフィックスが削除され、TestHelperProcess
になっています。
コアとなるコードの解説
helperCommand
関数は、os/exec
パッケージのテストにおいて、ヘルパープロセスを起動するためのユーティリティ関数です。
func helperCommand(s ...string) *Cmd {
// cs は、現在のテストバイナリを再実行する際の引数を格納するスライス
// "-test.run=TestHelperProcess" は、再実行されたバイナリが
// TestHelperProcess という名前のテスト関数のみを実行するように指示する
// "--" は、それ以降の引数がテストフレームワークではなく、
// テストヘルパープロセス自身の引数として扱われることを示す
cs := []string{"-test.run=TestHelperProcess", "--"}
// s... は、helperCommand に渡された追加の引数(例えば、ヘルパープロセスに渡したいコマンドライン引数)を
// cs スライスに追加する
cs = append(cs, s...)
// Command 関数を使って、現在の実行可能ファイル (os.Args[0]) を
// 指定された引数 (cs...) で実行するコマンドを作成する
cmd := Command(os.Args[0], cs...)
// cmd.Env に環境変数を追加する
// "GO_WANT_HELPER_PROCESS=1" は、再実行されたバイナリが
// ヘルパープロセスとして動作すべきであることを示すマーカー
// os.Environ()... は、現在の環境変数をすべて引き継ぐ
cmd.Env = append([]string{"GO_WANT_HELPER_PROCESS=1"}, os.Environ()...)
return cmd
}
この関数の目的は、os/exec
パッケージが外部コマンドをどのように実行するかをテストするために、テスト自身を「外部コマンド」として振る舞わせることです。
変更された行は、このヘルパープロセスが起動された際に、どのテスト関数を実行すべきかを go test
に伝える部分です。以前は exec.TestHelperProcess
という完全修飾名を使っていましたが、go test
の内部的な変更により、パッケージプレフィックスが不要になったため、TestHelperProcess
という簡潔な名前に修正されました。これにより、ヘルパープロセスが正しく目的のテストロジックを実行できるようになります。
関連リンク
- https://golang.org/cl/5491058 (Go Gerrit Code Review)
参考にした情報源リンク
- Go の公式ドキュメント (go test コマンド、testing パッケージ)
- Go のソースコード (特に
cmd/go/test.go
やsrc/testing/testing.go
の変更履歴) - Go のメーリングリストやIssueトラッカー (過去の
go test
の変更に関する議論) - Go Command: go test
- The Go Programming Language Specification: Test packages
- Go testing helper processes (テストヘルパープロセスに関する一般的な解説)
- Go: How to test helper processes (テストヘルパープロセスに関する詳細な解説)
- Go issue: cmd/go: remove package prefix from test names (関連する可能性のあるGoのIssue)
- Go commit: cmd/go: remove package prefix from test names (具体的なコミットは特定できなかったが、このような変更があったことを示唆する検索結果)
- (注: 2011年当時のGoのコミット履歴を直接検索するのは困難なため、一般的な情報源と、コミットメッセージから推測される変更内容に基づいています。)
go test
の-test.run
の挙動に関する変更は、Go 1.0 リリース前の開発段階で頻繁に行われていた可能性があります。```markdown
[インデックス 10832] ファイルの概要
このコミットは、Go言語の標準ライブラリ os/exec
パッケージのテストコードにおける変更を扱っています。具体的には、go test
コマンドの -test.run
フラグに渡す引数の形式を、新しい go test
の挙動に合わせて修正しています。これにより、テストヘルパープロセスを起動する際のテスト名指定が適切に行われるようになります。
コミット
os/exec: fix -test.run argument for new 'go test'
In 'go test' I deleted the leading package. prefix
from all the test names, since it contained no actual
information. Adjust the -test.run argument accordingly.
This will still work with the current gotest too, since
the argument is an unanchored pattern.
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5491058
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/b53856c16dc1facdc5c0257bd8b0ef4cff13d350
元コミット内容
os/exec: fix -test.run argument for new 'go test'
In 'go test' I deleted the leading package. prefix
from all the test names, since it contained no actual
information. Adjust the -test.run argument accordingly.
This will still work with the current gotest too, since
the argument is an unanchored pattern.
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5491058
変更の背景
この変更は、Go言語のテストツール go test
の内部的な挙動変更に対応するために行われました。以前の go test
では、テスト関数名が パッケージ名.テスト関数名
の形式で認識されていました(例: exec.TestHelperProcess
)。しかし、この「パッケージ名.」の部分は冗長であり、実際のテスト関数を特定する上で不要な情報でした。
Russ Cox氏による go test
の変更(このコミットの少し前に行われたと推測されます)により、テスト関数名からこの先頭のパッケージプレフィックスが削除され、単に テスト関数名
の形式で扱われるようになりました(例: TestHelperProcess
)。
os/exec
パッケージのテストコードでは、helperCommand
という関数内で、自身をテストヘルパープロセスとして再起動する際に、-test.run
フラグを使って特定のテスト関数(TestHelperProcess
)を実行するように指定していました。この指定が古い形式(exec.TestHelperProcess
)のままでは、新しい go test
の挙動と合致せず、テストが正しく実行されない可能性がありました。
このコミットは、この不整合を解消し、go test
の新しい命名規則に合わせて -test.run
の引数を修正することで、テストの互換性と正確性を維持することを目的としています。コミットメッセージにある「This will still work with the current gotest too, since the argument is an unanchored pattern.」という記述は、この変更が古い go test
のバージョンでも問題なく動作することを示しており、これは -test.run
が正規表現パターンを受け付け、そのパターンが文字列の先頭に固定されていない(unanchored)ため、部分一致でも機能するという特性を利用していることを意味します。
前提知識の解説
Go言語のテスト (go test
)
Go言語には、標準で強力なテストフレームワークが組み込まれています。go test
コマンドは、Goのソースコード内のテストファイル(ファイル名が _test.go
で終わるもの)を自動的に検出し、テスト関数(関数名が Test
で始まるもの)を実行します。
-test.run
フラグ
go test
コマンドには様々なフラグがありますが、-test.run
は特定のテスト関数やテストスイートのみを実行するために使用されます。このフラグには正規表現パターンを引数として渡すことができ、そのパターンにマッチする名前のテスト関数のみが実行されます。
例:
go test -test.run TestMyFunction
:TestMyFunction
という名前のテスト関数のみを実行。go test -test.run "Test.*"
:Test
で始まるすべてのテスト関数を実行。
テストヘルパープロセス (Test Helper Process)
Goのテストでは、特定のシナリオ(例えば、外部コマンドの実行、ネットワーク通信のシミュレーションなど)をテストするために、テストコード自身を別のプロセスとして起動し、そのプロセスに特定の処理を行わせる「テストヘルパープロセス」というテクニックがよく用いられます。
これは通常、以下のようなパターンで実装されます。
- メインのテスト関数内で、
os.Args[0]
(現在の実行可能ファイルのパス)を使って自身を再起動するexec.Command
を作成します。 - 再起動するコマンドの引数に、特定の環境変数(例:
GO_WANT_HELPER_PROCESS=1
)や、-test.run
フラグでヘルパー関数を指定します。 - プログラムのエントリポイント(
main
関数など)で、その環境変数が設定されているかどうかをチェックし、設定されていればヘルパー関数を実行して終了します。
このコミットの対象となっている os/exec
パッケージは、まさに外部コマンドの実行を扱うため、このようなヘルパープロセスを利用してテストを行っています。
正規表現 (Regular Expression)
正規表現は、文字列のパターンを記述するための強力なツールです。-test.run
フラグは正規表現パターンを受け入れるため、部分一致や複雑なマッチングが可能です。このコミットの文脈では、「unanchored pattern」(アンカーされていないパターン)という点が重要です。これは、パターンが文字列の先頭や末尾に固定されていないことを意味し、文字列のどの位置にパターンが出現してもマッチすることを許容します。
例えば、パターン TestHelperProcess
は、exec.TestHelperProcess
の中にも TestHelperProcess
の中にも部分的にマッチします。これが、古い go test
の挙動でもこの変更が機能する理由です。
技術的詳細
このコミットの技術的な核心は、go test
コマンドがテスト関数名をどのように解釈するか、そして -test.run
フラグがその解釈にどのように影響するかという点にあります。
以前の go test
では、テスト関数は内部的に パッケージ名.テスト関数名
という完全修飾名で管理されていました。例えば、os/exec
パッケージ内の TestHelperProcess
関数は exec.TestHelperProcess
として扱われていました。
しかし、この完全修飾名は、テストの実行やフィルタリングにおいて冗長であり、特にユーザーが -test.run
でテストを指定する際に、常にパッケージ名を含める必要があるのは不便でした。そのため、go test
の改善の一環として、テスト関数名から先頭のパッケージプレフィックスを削除し、より簡潔な テスト関数名
の形式で扱うように変更されました。
この変更により、os/exec
パッケージの exec_test.go
内の helperCommand
関数が影響を受けました。この関数は、テストヘルパープロセスを起動する際に、os.Args[0]
を使って現在のテストバイナリを再実行し、-test.run=exec.TestHelperProcess
という引数を渡していました。新しい go test
の挙動では、exec.TestHelperProcess
という名前のテスト関数は存在しないため、この引数では目的の TestHelperProcess
関数が実行されなくなります。
コミットは、この引数を TestHelperProcess
に変更することで、新しい go test
の命名規則に適合させました。
重要なのは、この変更が古い go test
のバージョンでも動作するという点です。これは、-test.run
が正規表現パターンを受け入れるためです。
- 古い
go test
の場合、内部的にはexec.TestHelperProcess
という名前のテスト関数が存在します。 - 新しい
-test.run=TestHelperProcess
というパターンは、exec.TestHelperProcess
という文字列に対して部分的にマッチします(TestHelperProcess
の部分がマッチ)。 -test.run
のパターンは「unanchored」(アンカーされていない)であるため、文字列のどの位置にパターンが出現してもマッチします。
したがって、この修正は後方互換性を保ちつつ、将来の go test
の挙動にも対応できる賢明な変更と言えます。
コアとなるコードの変更箇所
変更は src/pkg/os/exec/exec_test.go
ファイルの1箇所のみです。
--- a/src/pkg/os/exec/exec_test.go
+++ b/src/pkg/os/exec/exec_test.go
@@ -18,7 +18,7 @@ import (
)
func helperCommand(s ...string) *Cmd {
- cs := []string{"-test.run=exec.TestHelperProcess", "--"}
+ cs := []string{"-test.run=TestHelperProcess", "--"}
cs = append(cs, s...)\n cmd := Command(os.Args[0], cs...)
cmd.Env = append([]string{"GO_WANT_HELPER_PROCESS=1"}, os.Environ()...)
具体的には、helperCommand
関数内で cs
スライスを初期化する行が変更されています。
- 変更前:
cs := []string{"-test.run=exec.TestHelperProcess", "--"}
- 変更後:
cs := []string{"-test.run=TestHelperProcess", "--"}
exec.TestHelperProcess
から exec.
プレフィックスが削除され、TestHelperProcess
になっています。
コアとなるコードの解説
helperCommand
関数は、os/exec
パッケージのテストにおいて、ヘルパープロセスを起動するためのユーティリティ関数です。
func helperCommand(s ...string) *Cmd {
// cs は、現在のテストバイナリを再実行する際の引数を格納するスライス
// "-test.run=TestHelperProcess" は、再実行されたバイナリが
// TestHelperProcess という名前のテスト関数のみを実行するように指示する
// "--" は、それ以降の引数がテストフレームワークではなく、
// テストヘルパープロセス自身の引数として扱われることを示す
cs := []string{"-test.run=TestHelperProcess", "--"}
// s... は、helperCommand に渡された追加の引数(例えば、ヘルパープロセスに渡したいコマンドライン引数)を
// cs スライスに追加する
cs = append(cs, s...)
// Command 関数を使って、現在の実行可能ファイル (os.Args[0]) を
// 指定された引数 (cs...) で実行するコマンドを作成する
cmd := Command(os.Args[0], cs...)
// cmd.Env に環境変数を追加する
// "GO_WANT_HELPER_PROCESS=1" は、再実行されたバイナリが
// ヘルパープロセスとして動作すべきであることを示すマーカー
// os.Environ()... は、現在の環境変数をすべて引き継ぐ
cmd.Env = append([]string{"GO_WANT_HELPER_PROCESS=1"}, os.Environ()...)
return cmd
}
この関数の目的は、os/exec
パッケージが外部コマンドをどのように実行するかをテストするために、テスト自身を「外部コマンド」として振る舞わせることです。
変更された行は、このヘルパープロセスが起動された際に、どのテスト関数を実行すべきかを go test
に伝える部分です。以前は exec.TestHelperProcess
という完全修飾名を使っていましたが、go test
の内部的な変更により、パッケージプレフィックスが不要になったため、TestHelperProcess
という簡潔な名前に修正されました。これにより、ヘルパープロセスが正しく目的のテストロジックを実行できるようになります。
関連リンク
- https://golang.org/cl/5491058 (Go Gerrit Code Review)
参考にした情報源リンク
- Go の公式ドキュメント (go test コマンド、testing パッケージ)
- Go のソースコード (特に
cmd/go/test.go
やsrc/testing/testing.go
の変更履歴) - Go のメーリングリストやIssueトラッカー (過去の
go test
の変更に関する議論) - Go Command: go test
- The Go Programming Language Specification: Test packages
- Go testing helper processes (テストヘルパープロセスに関する一般的な解説)
- Go: How to test helper processes (テストヘルパープロセスに関する詳細な解説)
- Go issue: cmd/go: remove package prefix from test names (関連する可能性のあるGoのIssue)
- Go commit: cmd/go: remove package prefix from test names (具体的なコミットは特定できなかったが、このような変更があったことを示唆する検索結果)
- (注: 2011年当時のGoのコミット履歴を直接検索するのは困難なため、一般的な情報源と、コミットメッセージから推測される変更内容に基づいています。)
go test
の-test.run
の挙動に関する変更は、Go 1.0 リリース前の開発段階で頻繁に行われていた可能性があります。