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

[インデックス 13917] ファイルの概要

このコミットは、Go言語のテストインフラストラクチャにおけるマイナーな修正を目的としています。具体的には、test/runスクリプトとtest/testlibライブラリに対して、テスト実行の堅牢性とクリーンアップを改善するための変更が加えられています。

コミット

commit 3cd890dd5a8e5be33ce6f65ab7690ba0e1c235ef
Author: Russ Cox <rsc@golang.org>
Date:   Mon Sep 24 00:06:31 2012 -0400

    test: minor fixes in run and testlib
    
    Can tell this doesn't get run very often, but it is still important
    for when you've broken everything else.
    
    R=golang-dev, r
    CC=golang-dev
    https://golang.org/cl/6547065

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/3cd890dd5a8e5be33ce6f65ab7690ba0e1c235ef

元コミット内容

test: minor fixes in run and testlib

Can tell this doesn't get run very often, but it is still important
for when you've broken everything else.

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/6547065

変更の背景

このコミットの背景には、Go言語のテストスイートの信頼性と保守性の向上が挙げられます。コミットメッセージにある「Can tell this doesn't get run very often, but it is still important for when you've broken everything else.」という記述から、これらのテストスクリプトが日常的に頻繁に実行されるものではないものの、Goコンパイラやランタイムの根幹部分に大きな変更が加えられ、他のテストが機能しなくなったような「すべてが壊れた」状況において、システムの健全性を検証するための最終防衛線として非常に重要であることが示唆されています。

具体的には、テスト実行中に生成される一時ファイルのクリーンアップ不足や、コンパイル時の引数不足といった、テストインフラ自体の潜在的な問題に対処することで、より堅牢で信頼性の高いテスト環境を維持しようとしています。これにより、開発者がGoのコア部分に変更を加える際に、テストの実行がよりスムーズになり、誤ったテスト結果に惑わされることなく、問題の特定と修正に集中できるようになります。

前提知識の解説

このコミットを理解するためには、以下の前提知識が必要です。

  • Go言語のテストフレームワーク: Go言語には標準でtestingパッケージが提供されており、ユニットテスト、ベンチマークテスト、サンプルテストなどを記述できます。しかし、Goプロジェクト全体のビルドやテストの実行を管理するためには、シェルスクリプトやMakefileのようなツールが用いられることが一般的です。
  • test/runスクリプト: Goのソースコードリポジトリ(golang/go)のtest/ディレクトリには、Go言語のコンパイラ、ランタイム、標準ライブラリなどの広範なテストを実行するためのシェルスクリプト群が含まれています。test/runはその中でも主要なスクリプトの一つであり、テストの実行フローを制御し、結果を収集する役割を担っています。これは、Goのビルドシステムと密接に連携し、様々なテストケースを自動的に実行するために使用されます。
  • test/testlibライブラリ: test/testlibは、test/runのようなテストスクリプトから共通のテストヘルパー関数やユーティリティ関数を呼び出すためのシェルスクリプトライブラリです。例えば、Goプログラムのコンパイル、実行、出力の検証など、テストで頻繁に行われる操作を抽象化し、テストスクリプトの記述を簡潔にする役割を果たします。
  • 一時ファイル: プログラムのコンパイルやテストの実行中に、中間ファイルや一時的な出力ファイルが生成されることがあります。これらのファイルはテストの完了後に適切にクリーンアップされるべきですが、テストが中断された場合などに残ってしまうことがあります。
  • go build-Iフラグ: Go言語のコンパイラ(go buildコマンドなど)は、ソースコードをコンパイルする際に、インポートパスを解決するために特定のディレクトリを検索します。-Iフラグは、追加のインポートパスを指定するために使用されます。これは、特にテスト環境において、テスト対象のパッケージやモジュールが標準のGOPATH以外の場所に配置されている場合に重要となります。

技術的詳細

このコミットは、Go言語のテストインフラストラクチャにおける2つの具体的な問題を解決しています。

  1. 一時ファイルのクリーンアップの改善:

    • test/runスクリプトにrm -f tmp.goという行が追加されました。これは、一部のテストによって生成され、テストが中断された場合に残りうるtmp.goという一時ファイルを明示的に削除するためのものです。
    • tmp.goのような一時ファイルが残存すると、後続のテスト実行に影響を与えたり、ディスクスペースを不必要に消費したりする可能性があります。この修正により、テスト環境のクリーンさが保たれ、テストの再現性と信頼性が向上します。
  2. コンパイル時のインポートパスの指定:

    • test/testlibcompiledir関数において、Goコンパイラ($G変数で参照される)の呼び出しに-I.オプションが追加されました。変更前は$G ${gofile}でしたが、変更後は$G -I. "$gofile"となっています。
    • compiledir関数は、特定のディレクトリ内の複数のGoファイルをコンパイルするために使用されます。
    • -I.オプションは、現在のディレクトリ(.)をインポートパスとして追加することを意味します。これにより、コンパイル対象のGoファイルが、同じディレクトリ内にある他のGoファイルやパッケージをインポートしている場合に、コンパイラがそれらを正しく見つけられるようになります。
    • この修正は、特にテスト環境において、テスト対象のコードが相対パスでインポートを行っている場合や、テスト固有のヘルパーパッケージがテスト対象と同じディレクトリに配置されている場合に、コンパイルエラーを防ぐために重要です。これにより、テストのコンパイルがより堅牢になります。

これらの変更は、Goのテストスイートが「すべてが壊れた」状況でも信頼性高く機能することを保証するための、細かではあるが重要な改善です。

コアとなるコードの変更箇所

test/run

--- a/test/run
+++ b/test/run
@@ -54,6 +54,8 @@ true >pass.out >times.out
 exclude=false	# exclude nothing
 golden=golden.out
 
+rm -f tmp.go  # generated by some tests, left behind if interrupted
+
 filterout() {
 	grep '^'"$2"'$' $1 >/dev/null
 }

test/testlib

--- a/test/testlib
+++ b/test/testlib
@@ -12,7 +12,7 @@ compile() {
 compiledir() {
 	for gofile in $D/$F.dir/*.go
 	do
-		$G ${gofile} || return 1
+		$G -I. "$gofile" || return 1
 	done
 }
 

コアとなるコードの解説

test/runの変更

test/runスクリプトの変更は非常にシンプルです。

+rm -f tmp.go  # generated by some tests, left behind if interrupted

この行は、テスト実行の初期段階でtmp.goというファイルが存在すれば、それを強制的に削除します。コメントにあるように、このファイルは一部のテストによって生成される一時ファイルであり、テストが何らかの理由で中断された場合に、クリーンアップされずに残ってしまう可能性があります。以前のテスト実行で残されたtmp.goファイルが、現在のテスト実行に予期せぬ影響を与えることを防ぐための予防的な措置です。-fオプションは、ファイルが存在しなくてもエラーを出さずに処理を続行し、書き込み権限がない場合でも削除を試みることを意味します。

test/testlibの変更

test/testlibcompiledir関数の変更は、Goコンパイラの呼び出し方法を改善しています。

-		$G ${gofile} || return 1
+		$G -I. "$gofile" || return 1

compiledir関数は、引数として渡されたディレクトリ内のすべての.goファイルをループ処理し、それぞれをGoコンパイラ($G変数で表される、通常はgo tool compileまたはgo build)でコンパイルします。

変更前は、単に$G ${gofile}としてGoファイルをコンパイラに渡していました。しかし、Goのパッケージシステムでは、あるGoファイルが同じディレクトリ内の別のGoファイルで定義されたパッケージや型をインポートする場合、コンパイラはそのインポートパスを解決する必要があります。

変更後の$G -I. "$gofile"では、-I.オプションが追加されています。

  • -Iは、Goコンパイラに対して、追加のインポートパスを指定するためのフラグです。
  • .は、現在のディレクトリを意味します。

これにより、コンパイラは"$gofile"をコンパイルする際に、現在のディレクトリ(つまり、"$gofile"が存在するディレクトリ)もインポートパスとして検索するようになります。これは、特にテストケースが複数のGoファイルに分割されており、それらが互いに依存している場合に、コンパイルエラーを防ぐために重要です。例えば、testdata/mytest.gotestdata/myhelper.goで定義されたパッケージをインポートしている場合、-I.がないとコンパイルが失敗する可能性があります。この修正により、テストのコンパイルがより堅牢になり、テスト環境のセットアップが簡素化されます。|| return 1は、コンパイルが失敗した場合に、関数がエラーコード1を返して終了することを示しています。

関連リンク

参考にした情報源リンク

  • Go言語のgo buildコマンドに関するドキュメント(-Iフラグについて言及されている可能性がありますが、Goのバージョンによってドキュメントの場所が異なる場合があります)
  • Go言語のテストに関する一般的な情報源やチュートリアル
  • Go言語のソースコードリポジトリ内のtest/ディレクトリの構造とスクリプトの役割に関する情報(GitHubのコードを直接参照)
  • Goのコードレビューシステム(Gerrit)のCL(Change List)ページ: https://golang.org/cl/6547065 (このリンクはコミットメッセージに記載されています)
  • GoのIssue Tracker (もし関連するバグ報告や議論があれば)
  • Goのメーリングリストやフォーラムでの議論 (もし関連する議論があれば)
# [インデックス 13917] ファイルの概要

このコミットは、Go言語のテストインフラストラクチャにおけるマイナーな修正を目的としています。具体的には、`test/run`スクリプトと`test/testlib`ライブラリに対して、テスト実行の堅牢性とクリーンアップを改善するための変更が加えられています。

## コミット

commit 3cd890dd5a8e5be33ce6f65ab7690ba0e1c235ef Author: Russ Cox rsc@golang.org Date: Mon Sep 24 00:06:31 2012 -0400

test: minor fixes in run and testlib

Can tell this doesn't get run very often, but it is still important
for when you've broken everything else.

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/6547065

## GitHub上でのコミットページへのリンク

[https://github.com/golang/go/commit/3cd890dd5a8e5be33ce6f65ab7690ba0e1c235ef](https://github.com/golang/go/commit/3cd890dd5a8e5be33ce6f65ab7690ba0e1c235ef)

## 元コミット内容

test: minor fixes in run and testlib

Can tell this doesn't get run very often, but it is still important for when you've broken everything else.

R=golang-dev, r CC=golang-dev https://golang.org/cl/6547065


## 変更の背景

このコミットの背景には、Go言語のテストスイートの信頼性と保守性の向上が挙げられます。コミットメッセージにある「Can tell this doesn't get run very often, but it is still important for when you've broken everything else.」という記述から、これらのテストスクリプトが日常的に頻繁に実行されるものではないものの、Goコンパイラやランタイムの根幹部分に大きな変更が加えられ、他のテストが機能しなくなったような「すべてが壊れた」状況において、システムの健全性を検証するための最終防衛線として非常に重要であることが示唆されています。

具体的には、テスト実行中に生成される一時ファイルのクリーンアップ不足や、コンパイル時の引数不足といった、テストインフラ自体の潜在的な問題に対処することで、より堅牢で信頼性の高いテスト環境を維持しようとしています。これにより、開発者がGoのコア部分に変更を加える際に、テストの実行がよりスムーズになり、誤ったテスト結果に惑わされることなく、問題の特定と修正に集中できるようになります。

## 前提知識の解説

このコミットを理解するためには、以下の前提知識が必要です。

*   **Go言語のテストフレームワーク**: Go言語には標準で`testing`パッケージが提供されており、ユニットテスト、ベンチマークテスト、サンプルテストなどを記述できます。しかし、Goプロジェクト全体のビルドやテストの実行を管理するためには、シェルスクリプトやMakefileのようなツールが用いられることが一般的です。
*   **`test/run`スクリプト**: Goのソースコードリポジトリ(`golang/go`)の`test/`ディレクトリには、Go言語のコンパイラ、ランタイム、標準ライブラリなどの広範なテストを実行するためのシェルスクリプト群が含まれています。`test/run`はその中でも主要なスクリプトの一つであり、テストの実行フローを制御し、結果を収集する役割を担っています。これは、Goのビルドシステムと密接に連携し、様々なテストケースを自動的に実行するために使用されます。
*   **`test/testlib`ライブラリ**: `test/testlib`は、`test/run`のようなテストスクリプトから共通のテストヘルパー関数やユーティリティ関数を呼び出すためのシェルスクリプトライブラリです。例えば、Goプログラムのコンパイル、実行、出力の検証など、テストで頻繁に行われる操作を抽象化し、テストスクリプトの記述を簡潔にする役割を果たします。
*   **一時ファイル**: プログラムのコンパイルやテストの実行中に、中間ファイルや一時的な出力ファイルが生成されることがあります。これらのファイルはテストの完了後に適切にクリーンアップされるべきですが、テストが中断された場合などに残ってしまうことがあります。
*   **`go build`と`-I`フラグ**: Go言語のコンパイラ(`go build`コマンドなど)は、ソースコードをコンパイルする際に、インポートパスを解決するために特定のディレクトリを検索します。`-I`フラグは、追加のインポートパスを指定するために使用されます。これは、特にテスト環境において、テスト対象のパッケージやモジュールが標準のGOPATH以外の場所に配置されている場合に重要となります。

## 技術的詳細

このコミットは、Go言語のテストインフラストラクチャにおける2つの具体的な問題を解決しています。

1.  **一時ファイルのクリーンアップの改善**:
    *   `test/run`スクリプトに`rm -f tmp.go`という行が追加されました。これは、一部のテストによって生成され、テストが中断された場合に残りうる`tmp.go`という一時ファイルを明示的に削除するためのものです。
    *   `tmp.go`のような一時ファイルが残存すると、後続のテスト実行に影響を与えたり、ディスクスペースを不必要に消費したりする可能性があります。この修正により、テスト環境のクリーンさが保たれ、テストの再現性と信頼性が向上します。

2.  **コンパイル時のインポートパスの指定**:
    *   `test/testlib`の`compiledir`関数において、Goコンパイラ(`$G`変数で参照される)の呼び出しに`-I.`オプションが追加されました。変更前は`$G ${gofile}`でしたが、変更後は`$G -I. "$gofile"`となっています。
    *   `compiledir`関数は、特定のディレクトリ内の複数のGoファイルをコンパイルするために使用されます。
    *   `-I.`オプションは、現在のディレクトリ(`.`)をインポートパスとして追加することを意味します。これにより、コンパイル対象のGoファイルが、同じディレクトリ内にある他のGoファイルやパッケージをインポートしている場合に、コンパイラがそれらを正しく見つけられるようになります。
    *   この修正は、特にテスト環境において、テスト対象のコードが相対パスでインポートを行っている場合や、テスト固有のヘルパーパッケージがテスト対象と同じディレクトリに配置されている場合に、コンパイルエラーを防ぐために重要です。これにより、テストのコンパイルがより堅牢になります。

これらの変更は、Goのテストスイートが「すべてが壊れた」状況でも信頼性高く機能することを保証するための、細かではあるが重要な改善です。

## コアとなるコードの変更箇所

### `test/run`

```diff
--- a/test/run
+++ b/test/run
@@ -54,6 +54,8 @@ true >pass.out >times.out
 exclude=false	# exclude nothing
 golden=golden.out
 
+rm -f tmp.go  # generated by some tests, left behind if interrupted
+
 filterout() {
 	grep '^'"$2"'$' $1 >/dev/null
 }

test/testlib

--- a/test/testlib
+++ b/test/testlib
@@ -12,7 +12,7 @@ compile() {
 compiledir() {
 	for gofile in $D/$F.dir/*.go
 	do
-		$G ${gofile} || return 1
+		$G -I. "$gofile" || return 1
 	done
 }
 

コアとなるコードの解説

test/runの変更

test/runスクリプトの変更は非常にシンプルです。

+rm -f tmp.go  # generated by some tests, left behind if interrupted

この行は、テスト実行の初期段階でtmp.goというファイルが存在すれば、それを強制的に削除します。コメントにあるように、このファイルは一部のテストによって生成される一時ファイルであり、テストが何らかの理由で中断された場合に、クリーンアップされずに残ってしまう可能性があります。以前のテスト実行で残されたtmp.goファイルが、現在のテスト実行に予期せぬ影響を与えることを防ぐための予防的な措置です。-fオプションは、ファイルが存在しなくてもエラーを出さずに処理を続行し、書き込み権限がない場合でも削除を試みることを意味します。

test/testlibの変更

test/testlibcompiledir関数の変更は、Goコンパイラの呼び出し方法を改善しています。

-		$G ${gofile} || return 1
+		$G -I. "$gofile" || return 1

compiledir関数は、引数として渡されたディレクトリ内のすべての.goファイルをループ処理し、それぞれをGoコンパイラ($G変数で表される、通常はgo tool compileまたはgo build)でコンパイルします。

変更前は、単に$G ${gofile}としてGoファイルをコンパイラに渡していました。しかし、Goのパッケージシステムでは、あるGoファイルが同じディレクトリ内の別のGoファイルで定義されたパッケージや型をインポートする場合、コンパイラはそのインポートパスを解決する必要があります。

変更後の$G -I. "$gofile"では、-I.オプションが追加されています。

  • -Iは、Goコンパイラに対して、追加のインポートパスを指定するためのフラグです。
  • .は、現在のディレクトリを意味します。

これにより、コンパイラは"$gofile"をコンパイルする際に、現在のディレクトリ(つまり、"$gofile"が存在するディレクトリ)もインポートパスとして検索するようになります。これは、特にテストケースが複数のGoファイルに分割されており、それらが互いに依存している場合に、コンパイルエラーを防ぐために重要です。例えば、testdata/mytest.gotestdata/myhelper.goで定義されたパッケージをインポートしている場合、-I.がないとコンパイルが失敗する可能性があります。この修正により、テストのコンパイルがより堅牢になり、テスト環境のセットアップが簡素化されます。|| return 1は、コンパイルが失敗した場合に、関数がエラーコード1を返して終了することを示しています。

関連リンク

参考にした情報源リンク

  • Go言語のgo buildコマンドに関するドキュメント(-Iフラグについて言及されている可能性がありますが、Goのバージョンによってドキュメントの場所が異なる場合があります)
  • Go言語のテストに関する一般的な情報源やチュートリアル
  • Go言語のソースコードリポジトリ内のtest/ディレクトリの構造とスクリプトの役割に関する情報(GitHubのコードを直接参照)
  • Goのコードレビューシステム(Gerrit)のCL(Change List)ページ: https://golang.org/cl/6547065 (このリンクはコミットメッセージに記載されています)
  • GoのIssue Tracker (もし関連するバグ報告や議論があれば)
  • Goのメーリングリストやフォーラムでの議論 (もし関連する議論があれば)