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

[インデックス 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 TestMyFunctionTestMyFunction という名前のテスト関数のみを実行。
  • go test -test.run "Test.*"Test で始まるすべてのテスト関数を実行。

テストヘルパープロセス (Test Helper Process)

Goのテストでは、特定のシナリオ(例えば、外部コマンドの実行、ネットワーク通信のシミュレーションなど)をテストするために、テストコード自身を別のプロセスとして起動し、そのプロセスに特定の処理を行わせる「テストヘルパープロセス」というテクニックがよく用いられます。

これは通常、以下のようなパターンで実装されます。

  1. メインのテスト関数内で、os.Args[0](現在の実行可能ファイルのパス)を使って自身を再起動する exec.Command を作成します。
  2. 再起動するコマンドの引数に、特定の環境変数(例: GO_WANT_HELPER_PROCESS=1)や、-test.run フラグでヘルパー関数を指定します。
  3. プログラムのエントリポイント(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 という簡潔な名前に修正されました。これにより、ヘルパープロセスが正しく目的のテストロジックを実行できるようになります。

関連リンク

参考にした情報源リンク

[インデックス 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 TestMyFunctionTestMyFunction という名前のテスト関数のみを実行。
  • go test -test.run "Test.*"Test で始まるすべてのテスト関数を実行。

テストヘルパープロセス (Test Helper Process)

Goのテストでは、特定のシナリオ(例えば、外部コマンドの実行、ネットワーク通信のシミュレーションなど)をテストするために、テストコード自身を別のプロセスとして起動し、そのプロセスに特定の処理を行わせる「テストヘルパープロセス」というテクニックがよく用いられます。

これは通常、以下のようなパターンで実装されます。

  1. メインのテスト関数内で、os.Args[0](現在の実行可能ファイルのパス)を使って自身を再起動する exec.Command を作成します。
  2. 再起動するコマンドの引数に、特定の環境変数(例: GO_WANT_HELPER_PROCESS=1)や、-test.run フラグでヘルパー関数を指定します。
  3. プログラムのエントリポイント(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 という簡潔な名前に修正されました。これにより、ヘルパープロセスが正しく目的のテストロジックを実行できるようになります。

関連リンク

参考にした情報源リンク