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

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

本コミットは、Go言語の初期開発段階におけるテストインフラストラクチャの改善を目的としています。具体的には、テスト実行スクリプト test/run に変更を加え、テスト結果の出力ファイル test/golden.out のフォーマットを調整することで、テスト出力の可読性を向上させています。

コミット

commit 2f538554f6ce8ec8b0cdb3c448759e1670cad1ff
Author: Robert Griesemer <gri@golang.org>
Date:   Fri Jun 6 15:08:24 2008 -0700

    - fix to func.go
    - extra empty line between test output

    SVN=121499

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

https://github.com/golang/go/commit/2f538554f6ce8ec8b0cdb3c448759e1670cad1ff

元コミット内容

- fix to func.go
- extra empty line between test output

SVN=121499

変更の背景

このコミットは2008年6月に行われており、Go言語がまだGoogle社内で開発されていた非常に初期の段階に当たります。Go言語は2009年11月にオープンソースとして公開されるまで、内部で活発な開発が進められていました。この時期のコミットは、言語仕様の策定、コンパイラやランタイムの基礎実装、そして開発効率を高めるためのツールやテストインフラの整備に焦点が当てられていました。

test/golden.out は、Go言語のコンパイラやランタイムが生成する出力(エラーメッセージ、実行結果など)を記録し、期待される「ゴールデン」な出力と比較するためのファイルです。test/run スクリプトは、これらのテストを実行し、その出力を golden.out と比較する役割を担っていたと考えられます。

コミットメッセージにある「fix to func.go」は、おそらく func.go というテストファイルに関連する問題の修正を示唆していますが、具体的な内容は diff からは読み取れません。しかし、主要な変更は「extra empty line between test output」(テスト出力間に余分な空行を追加)という点にあります。これは、多数のテストケースの出力が連続して表示される際に、各テストの区切りを明確にし、テスト結果の視認性と可読性を向上させるための改善であると推測されます。初期のシステム開発では、デバッグや問題特定のためにログや出力のフォーマットが非常に重要であり、このような細かな改善が開発効率に寄与します。

前提知識の解説

1. Go言語の初期開発

Go言語は、GoogleのRobert Griesemer、Rob Pike、Ken Thompsonによって設計されました。彼らはC++の複雑さやJavaの冗長性といった既存言語の課題を解決し、大規模なソフトウェア開発に適した、シンプルで効率的な言語を目指しました。2008年時点では、Goはまだ社内プロジェクトであり、言語仕様、コンパイラ、標準ライブラリなどが活発に開発・試行錯誤されていました。この時期のコミットは、言語の根幹を形成する重要な変更が多く含まれています。

2. ゴールデンファイルテスト (Golden File Testing)

ゴールデンファイルテスト(またはスナップショットテスト)は、プログラムの出力が時間の経過とともに変化しないことを保証するためのテスト手法です。

  • 仕組み:
    1. テスト対象のプログラムを実行し、その出力を「ゴールデンファイル」(またはリファレンスファイル、スナップショット)として保存します。
    2. その後のテスト実行では、プログラムの現在の出力を生成し、それを既存のゴールデンファイルと比較します。
    3. 両者が完全に一致すればテストは成功です。一致しない場合、テストは失敗し、出力が変更されたことを開発者に通知します。
  • 利点:
    • 複雑な出力(例: コンパイラのASTダンプ、コード生成結果、レンダリングされた画像、CLIの標準出力)のテストに特に有効です。
    • テストコード自体が簡潔になり、期待される出力全体をテストコード内にハードコードする必要がありません。
    • 意図しない変更(リグレッション)を早期に検出できます。
  • 課題:
    • 意図的な出力変更があった場合、ゴールデンファイルを更新する必要があります。この更新プロセスが煩雑だと、テストが形骸化する可能性があります。
    • ゴールデンファイルが大きくなると、バージョン管理システムでの差分が大きくなり、レビューが難しくなることがあります。

Go言語のコンパイラやツールチェインの開発において、コンパイラの各ステージの出力や、特定のコードに対する実行結果が期待通りであることを保証するために、ゴールデンファイルテストは非常に有効な手段でした。

3. SVN (Subversion)

コミットメッセージにある SVN=121499 は、このコミットが元々Subversion(SVN)リポジトリで行われたことを示しています。SVNは、Gitが普及する以前に広く使われていた集中型バージョン管理システムです。Go言語のプロジェクトは、初期にはSVNで管理されており、後にGitに移行しました。このSVNリビジョン番号は、Gitリポジトリにインポートされた際の元のSVNリビジョンを示しています。

技術的詳細

このコミットの技術的詳細は、Go言語のテストハーネスの出力フォーマットに関するものです。

test/golden.out は、Go言語のテストスイートが生成する標準出力やエラー出力の「期待値」を記録したファイルです。このファイルは、Goコンパイラやランタイムの動作が正しく、かつ安定していることを検証するために使用されます。各テストケースの出力は、=========== <ファイル名> という区切り行で識別されます。

test/run スクリプトは、Go言語のテストを実行するためのシェルスクリプトです。このスクリプトは、test ディレクトリとそのサブディレクトリ(例: ken)内の .go ファイルをループ処理し、それぞれのGoプログラムを実行してその出力をキャプチャします。そして、そのキャプチャした出力を golden.out に記録された期待値と比較することで、テストの合否を判定します。

本コミットでは、test/run スクリプトに echo コマンドを追加することで、各テストファイルの出力ブロックの前に空行を挿入するように変更しています。これにより、test/golden.out の内容も更新され、各テスト結果の間に視覚的な区切りが追加されています。

この変更は、テスト結果を人間がレビューする際の利便性を高めることを目的としています。特に、多数のテストが連続して実行され、それぞれの出力が長い場合、空行による区切りは、どの出力がどのテストファイルに属するのかを瞬時に把握するのに役立ちます。これは、デバッグ作業や、テストが失敗した際に問題箇所を特定する時間を短縮する上で、小さな改善ながらも重要な意味を持ちます。

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

test/golden.out の変更

test/golden.out ファイルには、各テストファイルの出力ブロックの前に新しい空行が追加されています。

--- a/test/golden.out
+++ b/test/golden.out
@@ -1,8 +1,10 @@
+
 =========== ./char_lit.go
 char_lit.go:5: syntax error
 char_lit.go:17: unknown escape sequence: \\\
 char_lit.go:19: unknown escape sequence: "
 BUG: known to fail incorrectly
+
 =========== ./float_lit.go
 float_lit.go:5: syntax error
 float_lit.go:28: overflow in float constant
@@ -10,30 +12,46 @@ float_lit.go:56: overflow in float constant
 float_lit.go:60: overflow in float constant
 float_lit.go:64: overflow in float constant
 BUG: known to fail incorrectly
+
 =========== ./for.go
 for.go:45: fatal error: optoas: no entry MOD-<int32>INT32
 BUG: known to fail incorrectly
+
 =========== ./func.go
+main_f4: doasm: notfound from=75 to=10 (24)    IDIVL   $2,AX
+main_f4: doasm: notfound from=75 to=10 (24)    IDIVL   $2,AX
+main_f4: doasm: notfound from=75 to=10 (24)    IDIVL   $2,AX
+BUG: known to fail incorrectly
+
 =========== ./hashmap.go
 hashmap.go:46: fatal error: optoas: no entry LSH-<uint32>UINT32
 BUG: known to fail incorrectly
+
 =========== ./helloworld.go
 hello, world
+
 =========== ./if.go
+
 =========== ./int_lit.go
 int_lit.go:5: syntax error
 BUG: known to fail incorrectly
+
 =========== ./iota.go
+
 =========== ./literal.go
+
 =========== ./sieve.go
 sieve.go:8: fatal error: walktype: switch 1 unknown op SEND l(8)
 BUG: known to fail incorrectly
+
 =========== ./string_lit.go
 string_lit.go:5: syntax error
 string_lit.go:12: unknown escape sequence: \\\
 string_lit.go:12: unknown escape sequence: '
 BUG: known to fail incorrectly
+
 =========== ./switch.go
+
 =========== ./test0.go
 test0.go:23: addtyp: renaming Point/<Point>{<x><int32>INT32;<y><int32>INT32;} to Point2/<Point2>FORW
 test0.go:48: illegal types for operand
@@ -47,43 +65,69 @@ test0.go:54: function call must be single valued (0)
 test0.go:54: illegal types for operand
 	(<Point2>{}) AS ({})
 BUG: known to fail incorrectly
+
 =========== ./turing.go
 Hello World!
+
 =========== ken/for.go
+
 =========== ken/interfun.go
+
 =========== ken/intervar.go
  print 1 bio 2 file 3 -- abc
+
 =========== ken/label.go
 100
+
 =========== ken/litfun.go
+
 =========== ken/mfunc.go
 ken/mfunc.go:13: function call must be single valued (2)
 BUG: known to fail incorrectly
+
 =========== ken/ptrfun.go
+
 =========== ken/ptrvar.go
+
 =========== ken/rob1.go
+
 =========== ken/rob2.go
+
 =========== ken/robfor.go
 ken/robfor.go:45: fatal error: optoas: no entry MOD-<int32>INT32
 BUG: known to fail incorrectly
+
 =========== ken/robfunc.go
 ken/robfunc.go:74: function call must be single valued (2)
 ken/robfunc.go:79: function call must be single valued (2)
 ken/robfunc.go:84: function call must be single valued (2)
 BUG: known to fail incorrectly
+
 =========== ken/robif.go
+
 =========== ken/robiota.go
+
 =========== ken/robliteral.go
+
 =========== ken/robswitch.go
+
 =========== ken/simparray.go
+
 =========== ken/simpbool.go
+
 =========== ken/simpconv.go
+
 =========== ken/simpfun.go
+
 =========== ken/simpprint.go
 hello world
+
 =========== ken/simpswitch.go
 0out01out12out2aout34out4fiveout56out6aout78out89out9
+
 =========== ken/simpvar.go
+
 =========== ken/string.go
 abcxyz-abcxyz-abcxyz-abcxyz-abcxyz-abcxyz-abcxyz
+
 =========== ken/strvar.go

test/run の変更

test/run スクリプトに、echo コマンドが追加されています。

--- a/test/run
+++ b/test/run
@@ -23,6 +23,7 @@ for dir in . ken
 do
 	for i in $dir/*.go
 	do
+		echo
 		echo '===========' $i
 		export F=$(basename $i .go)
 		export D=$dir

コアとなるコードの解説

test/run スクリプトの変更

変更は test/run スクリプトの以下の部分にあります。

for dir in . ken
do
	for i in $dir/*.go
	do
		echo  # <-- 追加された行
		echo '===========' $i
		export F=$(basename $i .go)
		export D=$dir
		# ... (後続のテスト実行ロジック)
	done
done

追加された echo コマンドは、シェルスクリプトにおいて単に改行を出力する役割を果たします。この echoecho '===========' $i の直前に配置されたことで、各テストファイルの出力ブロックの前に必ず空行が挿入されるようになりました。

test/golden.out の変更

test/golden.out は、test/run スクリプトの実行結果を反映したものです。test/run の変更により、各テストの区切りを示す =========== <ファイル名> の行の前に空行が追加されたため、golden.out もそれに合わせて更新されています。これは、ゴールデンファイルテストの性質上、テストハーネスの出力フォーマットが変更された場合に、期待される出力もそれに合わせて更新する必要があるためです。

この変更自体はGo言語のコンパイラやランタイムの機能に直接影響を与えるものではなく、あくまでテスト出力のフォーマットに関する改善です。しかし、開発者がテスト結果をより効率的にレビューできるようにするための、ユーザビリティ向上のための重要な変更と言えます。

関連リンク

参考にした情報源リンク

本コミットは、Go言語の初期開発段階におけるテストインフラストラクチャの改善を目的としています。具体的には、テスト実行スクリプト test/run に変更を加え、テスト結果の出力ファイル test/golden.out のフォーマットを調整することで、テスト出力の可読性を向上させています。

コミット

commit 2f538554f6ce8ec8b0cdb3c448759e1670cad1ff
Author: Robert Griesemer <gri@golang.org>
Date:   Fri Jun 6 15:08:24 2008 -0700

    - fix to func.go
    - extra empty line between test output

    SVN=121499

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

https://github.com/golang/go/commit/2f538554f6ce8ec8b0cdb3c448759e1670cad1ff

元コミット内容

- fix to func.go
- extra empty line between test output

SVN=121499

変更の背景

このコミットは2008年6月に行われており、Go言語がまだGoogle社内で開発されていた非常に初期の段階に当たります。Go言語は2009年11月にオープンソースとして公開されるまで、内部で活発な開発が進められていました。この時期のコミットは、言語仕様の策定、コンパイラやランタイムの基礎実装、そして開発効率を高めるためのツールやテストインフラの整備に焦点が当てられていました。

test/golden.out は、Go言語のコンパイラやランタイムが生成する出力(エラーメッセージ、実行結果など)を記録し、期待される「ゴールデン」な出力と比較するためのファイルです。test/run スクリプトは、これらのテストを実行し、その出力を golden.out と比較する役割を担っていたと考えられます。

コミットメッセージにある「fix to func.go」は、おそらく func.go というテストファイルに関連する問題の修正を示唆していますが、具体的な内容は diff からは読み取れません。しかし、主要な変更は「extra empty line between test output」(テスト出力間に余分な空行を追加)という点にあります。これは、多数のテストケースの出力が連続して表示される際に、各テストの区切りを明確にし、テスト結果の視認性と可読性を向上させるための改善であると推測されます。初期のシステム開発では、デバッグや問題特定のためにログや出力のフォーマットが非常に重要であり、このような細かな改善が開発効率に寄与します。

前提知識の解説

1. Go言語の初期開発

Go言語は、GoogleのRobert Griesemer、Rob Pike、Ken Thompsonによって設計されました。彼らはC++の複雑さやJavaの冗長性といった既存言語の課題を解決し、大規模なソフトウェア開発に適した、シンプルで効率的な言語を目指しました。2008年時点では、Goはまだ社内プロジェクトであり、言語仕様、コンパイラ、標準ライブラリなどが活発に開発・試行錯誤されていました。この時期のコミットは、言語の根幹を形成する重要な変更が多く含まれています。

2. ゴールデンファイルテスト (Golden File Testing)

ゴールデンファイルテスト(またはスナップショットテスト)は、プログラムの出力が時間の経過とともに変化しないことを保証するためのテスト手法です。

  • 仕組み:
    1. テスト対象のプログラムを実行し、その出力を「ゴールデンファイル」(またはリファレンスファイル、スナップショット)として保存します。
    2. その後のテスト実行では、プログラムの現在の出力を生成し、それを既存のゴールデンファイルと比較します。
    3. 両者が完全に一致すればテストは成功です。一致しない場合、テストは失敗し、出力が変更されたことを開発者に通知します。
  • 利点:
    • 複雑な出力(例: コンパイラのASTダンプ、コード生成結果、レンダリングされた画像、CLIの標準出力)のテストに特に有効です。
    • テストコード自体が簡潔になり、期待される出力全体をテストコード内にハードコードする必要がありません。
    • 意図しない変更(リグレッション)を早期に検出できます。
  • 課題:
    • 意図的な出力変更があった場合、ゴールデンファイルを更新する必要があります。この更新プロセスが煩雑だと、テストが形骸化する可能性があります。
    • ゴールデンファイルが大きくなると、バージョン管理システムでの差分が大きくなり、レビューが難しくなることがあります。

Go言語のコンパイラやツールチェインの開発において、コンパイラの各ステージの出力や、特定のコードに対する実行結果が期待通りであることを保証するために、ゴールデンファイルテストは非常に有効な手段でした。

3. SVN (Subversion)

コミットメッセージにある SVN=121499 は、このコミットが元々Subversion(SVN)リポジトリで行われたことを示しています。SVNは、Gitが普及する以前に広く使われていた集中型バージョン管理システムです。Go言語のプロジェクトは、初期にはSVNで管理されており、後にGitに移行しました。このSVNリビジョン番号は、Gitリポジトリにインポートされた際の元のSVNリビジョンを示しています。

技術的詳細

このコミットの技術的詳細は、Go言語のテストハーネスの出力フォーマットに関するものです。

test/golden.out は、Go言語のテストスイートが生成する標準出力やエラー出力の「期待値」を記録したファイルです。このファイルは、Goコンパイラやランタイムの動作が正しく、かつ安定していることを検証するために使用されます。各テストケースの出力は、=========== <ファイル名> という区切り行で識別されます。

test/run スクリプトは、Go言語のテストを実行するためのシェルスクリプトです。このスクリプトは、test ディレクトリとそのサブディレクトリ(例: ken)内の .go ファイルをループ処理し、それぞれのGoプログラムを実行してその出力をキャプチャします。そして、そのキャプチャした出力を golden.out に記録された期待値と比較することで、テストの合否を判定します。

本コミットでは、test/run スクリプトに echo コマンドを追加することで、各テストファイルの出力ブロックの前に空行を挿入するように変更しています。これにより、test/golden.out の内容も更新され、各テスト結果の間に視覚的な区切りが追加されています。

この変更は、テスト結果を人間がレビューする際の利便性を高めることを目的としています。特に、多数のテストが連続して実行され、それぞれの出力が長い場合、空行による区切りは、どの出力がどのテストファイルに属するのかを瞬時に把握するのに役立ちます。これは、デバッグ作業や、テストが失敗した際に問題箇所を特定する時間を短縮する上で、小さな改善ながらも重要な意味を持ちます。

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

test/golden.out の変更

test/golden.out ファイルには、各テストファイルの出力ブロックの前に新しい空行が追加されています。

--- a/test/golden.out
+++ b/test/golden.out
@@ -1,8 +1,10 @@
+
 =========== ./char_lit.go
 char_lit.go:5: syntax error
 char_lit.go:17: unknown escape sequence: \\\
 char_lit.go:19: unknown escape sequence: "
 BUG: known to fail incorrectly
+
 =========== ./float_lit.go
 float_lit.go:5: syntax error
 float_lit.go:28: overflow in float constant
@@ -10,30 +12,46 @@ float_lit.go:56: overflow in float constant
 float_lit.go:60: overflow in float constant
 float_lit.go:64: overflow in float constant
 BUG: known to fail incorrectly
+
 =========== ./for.go
 for.go:45: fatal error: optoas: no entry MOD-<int32>INT32
 BUG: known to fail incorrectly
+
 =========== ./func.go
+main_f4: doasm: notfound from=75 to=10 (24)    IDIVL   $2,AX
+main_f4: doasm: notfound from=75 to=10 (24)    IDIVL   $2,AX
+main_f4: doasm: notfound from=75 to=10 (24)    IDIVL   $2,AX
+BUG: known to fail incorrectly
+
 =========== ./hashmap.go
 hashmap.go:46: fatal error: optoas: no entry LSH-<uint32>UINT32
 BUG: known to fail incorrectly
+
 =========== ./helloworld.go
 hello, world
+
 =========== ./if.go
+
 =========== ./int_lit.go
 int_lit.go:5: syntax error
 BUG: known to fail incorrectly
+
 =========== ./iota.go
+
 =========== ./literal.go
+
 =========== ./sieve.go
 sieve.go:8: fatal error: walktype: switch 1 unknown op SEND l(8)
 BUG: known to fail incorrectly
+
 =========== ./string_lit.go
 string_lit.go:5: syntax error
 string_lit.go:12: unknown escape sequence: \\\
 string_lit.go:12: unknown escape sequence: '
 BUG: known to fail incorrectly
+
 =========== ./switch.go
+
 =========== ./test0.go
 test0.go:23: addtyp: renaming Point/<Point>{<x><int32>INT32;<y><int32>INT32;} to Point2/<Point2>FORW
 test0.go:48: illegal types for operand
@@ -47,43 +65,69 @@ test0.go:54: function call must be single valued (0)
 test0.go:54: illegal types for operand
 	(<Point2>{}) AS ({})
 BUG: known to fail incorrectly
+
 =========== ./turing.go
 Hello World!
+
 =========== ken/for.go
+
 =========== ken/interfun.go
+
 =========== ken/intervar.go
  print 1 bio 2 file 3 -- abc
+
 =========== ken/label.go
 100
+
 =========== ken/litfun.go
+
 =========== ken/mfunc.go
 ken/mfunc.go:13: function call must be single valued (2)
 BUG: known to fail incorrectly
+
 =========== ken/ptrfun.go
+
 =========== ken/ptrvar.go
+
 =========== ken/rob1.go
+
 =========== ken/rob2.go
+
 =========== ken/robfor.go
 ken/robfor.go:45: fatal error: optoas: no entry MOD-<int32>INT32
 BUG: known to fail incorrectly
+
 =========== ken/robfunc.go
 ken/robfunc.go:74: function call must be single valued (2)
 ken/robfunc.go:79: function call must be single valued (2)
 ken/robfunc.go:84: function call must be single valued (2)
 BUG: known to fail incorrectly
+
 =========== ken/robif.go
+
 =========== ken/robiota.go
+
 =========== ken/robliteral.go
+
 =========== ken/robswitch.go
+
 =========== ken/simparray.go
+
 =========== ken/simpbool.go
+
 =========== ken/simpconv.go
+
 =========== ken/simpfun.go
+
 =========== ken/simpprint.go
 hello world
+
 =========== ken/simpswitch.go
 0out01out12out2aout34out4fiveout56out6aout78out89out9
+
 =========== ken/simpvar.go
+
 =========== ken/string.go
 abcxyz-abcxyz-abcxyz-abcxyz-abcxyz-abcxyz-abcxyz
+
 =========== ken/strvar.go

test/run の変更

test/run スクリプトに、echo コマンドが追加されています。

--- a/test/run
+++ b/test/run
@@ -23,6 +23,7 @@ for dir in . ken
 do
 	for i in $dir/*.go
 	do
+		echo
 		echo '===========' $i
 		export F=$(basename $i .go)
 		export D=$dir

コアとなるコードの解説

test/run スクリプトの変更

変更は test/run スクリプトの以下の部分にあります。

for dir in . ken
do
	for i in $dir/*.go
	do
		echo  # <-- 追加された行
		echo '===========' $i
		export F=$(basename $i .go)
		export D=$dir
		# ... (後続のテスト実行ロジック)
	done
done

追加された echo コマンドは、シェルスクリプトにおいて単に改行を出力する役割を果たします。この echoecho '===========' $i の直前に配置されたことで、各テストファイルの出力ブロックの前に必ず空行が挿入されるようになりました。

test/golden.out の変更

test/golden.out は、test/run スクリプトの実行結果を反映したものです。test/run の変更により、各テストの区切りを示す =========== <ファイル名> の行の前に空行が追加されたため、golden.out もそれに合わせて更新されています。これは、ゴールデンファイルテストの性質上、テストハーネスの出力フォーマットが変更された場合に、期待される出力もそれに合わせて更新する必要があるためです。

この変更自体はGo言語のコンパイラやランタイムの機能に直接影響を与えるものではなく、あくまでテスト出力のフォーマットに関する改善です。しかし、開発者がテスト結果をより効率的にレビューできるようにするための、ユーザビリティ向上のための重要な変更と言えます。

関連リンク

参考にした情報源リンク