[インデックス 13739] ファイルの概要
このコミットは、Go言語のドキュメントに含まれるサンプルプログラムのテスト方法を改善し、特にWindows環境でのテスト実行を test/run.go スクリプトを使用するように変更するものです。これにより、Windows上でのテストの互換性と信頼性が向上します。また、特定のプログラム(cgo関連や go1.go)が現状ではテストできないことを明示し、その理由をコメントで補足しています。
コミット
- コミットハッシュ:
5b7562dd6fe04aa3e827c66ee7ac7b57b6afa667 - 作者: Shenghou Ma minux.ma@gmail.com
- コミット日時: Mon Sep 3 03:49:03 2012 +0800
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/5b7562dd6fe04aa3e827c66ee7ac7b57b6afa667
元コミット内容
doc/progs: use test/run.go for testing on Windows
cgo[1-4].go, go1.go couldn't be tested now
(cgo[1-4].go can only be tested when cgo is enabled, go1.go
contain a list of filenames in the current directory)
R=golang-dev, alex.brainman, rsc
CC=golang-dev
https://golang.org/cl/6218048
変更の背景
この変更の主な背景は、Go言語のドキュメントに含まれるサンプルコード(doc/progs ディレクトリ内のGoプログラム)のテストプロセスを、特にWindows環境において改善することにあります。
当時のGoプロジェクトでは、テストの実行方法がプラットフォームによって異なる場合がありました。特にWindows環境では、Unix系システムで一般的に使用されるシェルスクリプト(例: run.bash)が直接実行できないため、テストの自動化や一貫性に課題がありました。
このコミット以前は、doc/progs 内のサンプルコードのテストがWindowsで適切に機能していなかったか、あるいは手動での介入が必要だった可能性があります。cgo[1-4].go のようなCgoを使用するプログラムや、カレントディレクトリのファイルリストを出力する go1.go のようなプログラムは、その性質上、特定の環境設定(Cgoの有効化)や実行時のコンテキスト(ファイルリストの比較)に依存するため、一般的なテストフレームワークでは扱いにくい側面がありました。
このコミットは、test/run.go というGo言語で書かれたテストヘルパースクリプトを導入することで、Windowsを含む様々なプラットフォームで doc/progs 内のサンプルコードをより堅牢かつ自動的にテストできるようにすることを目的としています。これにより、ドキュメントのコード例が常に正しく動作することを保証し、開発者がGo言語の機能を学習する際の信頼性を高めることができます。
前提知識の解説
このコミットを理解するためには、以下のGo言語および関連技術に関する知識が必要です。
- Go言語のテストフレームワーク: Go言語には標準で
testingパッケージが用意されており、go testコマンドを使ってテストを実行します。しかし、このコミットで扱われているのは、Goのソースコードリポジトリ内の特定のテストヘルパースクリプト (test/run.go) や、ドキュメントのサンプルコードを検証するためのカスタムなテストメカニズムです。 test/run.go: これはGo言語の公式リポジトリ内に存在する、Goプログラムのテスト実行を補助するためのユーティリティスクリプトです。通常のgo testとは異なり、特定のディレクトリ内のGoファイルをコンパイル・実行し、その出力や挙動を検証するような、より柔軟なテストシナリオに対応するために使用されます。特に、Goのビルドシステムやテストインフラストラクチャの一部として機能します。- Cgo: CgoはGoプログラムからC言語のコードを呼び出すためのGoの機能です。Cgoを使用するプログラムは、Cコンパイラやリンカがシステムにインストールされている必要があり、通常のGoプログラムよりもビルド・実行環境の依存関係が複雑になります。そのため、Cgoプログラムのテストは、Cgoが有効な環境でのみ実行可能です。
Makefile:Makefileはmakeコマンドによって実行されるビルド自動化ツールです。Goプロジェクトでは、テストの実行、コードの生成、ドキュメントのビルドなど、様々なタスクを自動化するために使用されます。このコミットでは、doc/Makefileがドキュメントのサンプルコードのテストに関連するターゲットを持つことが示唆されています。*.batファイル (Windows Batch Script): Windows環境でコマンドを実行するためのスクリプトファイルです。Unix系OSのシェルスクリプト (.shや.bash) に相当します。src/run.batは、Goのテストスイート全体を実行するためのWindows固有のスクリプトであり、このコミットではdoc/progsのテストをtest/run.go経由で実行するように変更されています。- ドキュメントのサンプルコードのテスト: Goの公式ドキュメント(特に
effective_go.htmlなど)には、Go言語の機能を示すためのコード例が埋め込まれています。これらのコード例が常に正しく動作することを保証するために、自動テストが実行されます。このコミットは、そのテストメカニズムの一部を修正しています。 // skip,// cmpout,// compile,// runディレクティブ: Goのテストシステムやドキュメント生成システムで使用される、特別なコメントディレクティブです。これらは、Goのソースファイルの上部に記述され、そのファイルがどのようにテストされるべきか、あるいはドキュメントにどのように組み込まれるべきかを指示します。// skip: そのファイルをテストから除外します。// cmpout: プログラムの実行結果を、対応する.outファイルの内容と比較して検証します。// compile: プログラムがコンパイルできることを検証します(実行はしません)。// run: プログラムを実行し、その実行がエラーなく完了することを検証します。
技術的詳細
このコミットは、Go言語のドキュメント (doc/) 内のサンプルプログラムのテスト方法に複数の変更を加えています。
doc/progsディレクトリ内のGoプログラムへのディレクティブ追加:cgo1.goからcgo4.goには// skipディレクティブが追加されました。これは、これらのファイルがCgoを必要とし、現在のテスト環境(特にWindowsでのtest/run.goを使用したテスト)ではCgoが有効になっていないため、テストをスキップすることを示します。コミットメッセージにも「cgo[1-4].go can only be tested when cgo is enabled」と明記されています。defer.go,defer2.go,eff_bytesize.go,eff_sequence.go,image_package1.goからimage_package6.go,interface2.go,json2.goには// cmpoutディレクティブが追加されました。これは、これらのプログラムを実行し、その標準出力が対応する.outファイル(例:defer.out)の内容と一致することを検証するテストであることを示します。defer.out,defer2.out,eff_bytesize.out,eff_sequence.out,image_package1.outからimage_package6.out,interface2.out,json2.outといった新しい.outファイルが追加されました。これらは、// cmpoutディレクティブを持つGoプログラムの期待される出力を含んでいます。eff_qr.go,error.goからerror4.go,gobs1.go,gobs2.go,image_draw.go,interface.go,json3.go,json5.go,slices.go,timeout1.go,timeout2.goには// compileディレクティブが追加されました。これは、これらのプログラムがコンパイル可能であることを検証するテストであることを示します。json1.go,json4.goには// runディレクティブが追加されました。これは、これらのプログラムが実行可能であることを検証するテストであることを示します。go1.goには// compileディレクティブと、// this file will output a list of filenames in cwd, not suitable for cmpoutというコメントが追加されました。これは、このプログラムがカレントディレクトリのファイルリストを出力するため、出力比較テストには適さないことを示唆しています。
doc/Makefileの変更:compareという新しいmakeターゲットが追加されました。このターゲットは、RAWHTML変数で指定されたHTMLファイル(Goドキュメントの生HTML)をgodoc -urlコマンドで処理し、その出力と元のHTMLファイルをdiff -uで比較します。これは、ドキュメントのHTMLがgodocによって正しく生成されることを検証するためのものです。
doc/progs/update.bashの新規追加:- このシェルスクリプトは、
doc/progsディレクトリ内のGoプログラムのテスト結果を自動的に生成するためのものです。 - 既存の
.out,.rej,.origファイルなどを削除します。 // cmpoutディレクティブを持つGoファイルを見つけ、go runで実行し、その出力を対応する.outファイルにリダイレクトします。これにより、期待される出力ファイルが自動的に更新されます。これは、テストの基準となる出力を簡単に更新するためのユーティリティです。
- このシェルスクリプトは、
src/run.batの変更:- Windows環境でのテスト実行スクリプトである
src/run.batに、doc\progsディレクトリのテストを実行するための行が追加されました。 - 具体的には、
go run %GOROOT%\test\run.go - ..\doc\progsというコマンドが追加され、doc\progsディレクトリ内のGoプログラムがtest/run.goを介してテストされるようになりました。 - また、
..\misc\cgo\stdioのテストもtest/run.goを使用するように変更されています。 - 以前はコメントアウトされていた
:: TODO(brainman): disabled, because it fails with: mkdir C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\2.....\\go\\misc\\cgo\\: The filename or extension is too long.というCgoテストに関するコメントが残されており、Windowsでのパスの長さ制限による問題がまだ存在することを示唆しています。
- Windows環境でのテスト実行スクリプトである
これらの変更により、Goドキュメントのサンプルコードのテストがより自動化され、特にWindows環境でのテストの実行可能性と信頼性が向上しました。
コアとなるコードの変更箇所
このコミットにおけるコアとなるコードの変更箇所は以下の通りです。
doc/progs/*.goファイル群:- 多数のGoプログラムファイルに、
// skip,// cmpout,// compile,// runといった特別なコメントディレクティブが追加されました。 - 例:
doc/progs/cgo1.goに+// skipが追加。 - 例:
doc/progs/defer.goに+// cmpoutが追加。 - 例:
doc/progs/eff_qr.goに+// compileが追加。 - 例:
doc/progs/json1.goに+// runが追加。
- 多数のGoプログラムファイルに、
doc/progs/*.outファイル群:// cmpoutディレクティブを持つGoプログラムに対応する、期待される出力を含む新しい.outファイルが多数追加されました。- 例:
doc/progs/defer.out(新規ファイル) - 例:
doc/progs/defer2.out(新規ファイル)
doc/Makefile:compareという新しいmakeターゲットが追加され、godocの出力と既存のHTMLファイルを比較するロジックが記述されました。
doc/progs/update.bash:// cmpoutディレクティブを持つGoプログラムの.outファイルを自動生成・更新するためのシェルスクリプトが新規追加されました。
src/run.bat:- Windows環境でのテスト実行スクリプトに、
doc\progsディレクトリのテストをtest/run.goを使用して実行するコマンドが追加されました。
- Windows環境でのテスト実行スクリプトに、
コアとなるコードの解説
doc/progs/*.go ファイルへのディレクティブ追加
Goのテストシステムは、Goソースファイルの先頭に記述された特定のコメント行を特別なディレクティブとして解釈します。このコミットでは、doc/progs ディレクトリ内の各サンプルプログラムに対して、そのプログラムがどのようにテストされるべきかを指示するディレクティブが追加されました。
-
// skip:// skip // Copyright 2012 The Go Authors. All rights reserved. // ...cgo[1-4].goに追加されました。これは、これらのファイルがCgoに依存しており、現在のテスト環境ではCgoが有効になっていないため、テストをスキップするように指示します。これにより、Cgoが利用できない環境でのテスト失敗を防ぎます。 -
// cmpout:// cmpout // Copyright 2011 The Go Authors. All rights reserved. // ...defer.go,defer2.goなど多数のファイルに追加されました。このディレクティブは、test/run.goスクリプトに対して、このGoプログラムを実行し、その標準出力が同じベース名を持つ.outファイル(例:defer.out)の内容と完全に一致するかどうかを検証するように指示します。これは、プログラムの出力が期待通りであることを保証するための回帰テストとして機能します。 -
// compile:// compile // Copyright 2009 The Go Authors. All rights reserved. // ...eff_qr.go,error.goなど多数のファイルに追加されました。このディレクティブは、test/run.goスクリプトに対して、このGoプログラムがエラーなくコンパイルできることを検証するように指示します。これは、構文エラーや型エラーがないことを確認するための基本的な健全性チェックです。 -
// run:// run // Copyright 2012 The Go Authors. All rights reserved. // ...json1.go,json4.goに追加されました。このディレクティブは、test/run.goスクリプトに対して、このGoプログラムを実行し、実行時にパニックやランタイムエラーが発生しないことを検証するように指示します。出力の比較は行いませんが、プログラムが正常に終了することを確認します。
doc/progs/*.out ファイルの新規追加
// cmpout ディレクティブが追加されたGoプログラムに対応して、そのプログラムの期待される出力を格納する .out ファイルが新規作成されました。例えば、doc/progs/defer.go に // cmpout が追加された場合、doc/progs/defer.out が作成され、defer.go を実行した際の期待される出力が記述されます。これらのファイルは、test/run.go が出力比較テストを実行する際の基準となります。
doc/Makefile の compare ターゲット
compare:
for i in $(RAWHTML); do \
godoc -url /doc/$${i/.rawhtml/.html} | diff -u $$i -; \
done
この新しい compare ターゲットは、GoドキュメントのHTMLファイルが godoc コマンドによって正しく生成されることを検証するためのものです。RAWHTML 変数に含まれる各生HTMLファイル (.rawhtml) に対して、godoc -url コマンドを使ってそのHTMLを再生成し、元のファイルと diff -u で比較します。これにより、ドキュメントの生成プロセスが意図した通りに機能しているか、あるいは意図しない変更がないかを確認できます。
doc/progs/update.bash スクリプト
#!/usr/bin/env bash
# ...
set -e
rm -f *.out *.rej *.orig [568].out
for i in *.go; do
if grep -q '^// cmpout$' $i; then
echo $i
go run $i &> ${i/.go/.out}
fi
done
このシェルスクリプトは、doc/progs ディレクトリ内の // cmpout ディレクティブを持つGoプログラムの期待される出力ファイル (.out ファイル) を自動的に生成または更新するためのユーティリティです。
set -e: コマンドが失敗した場合にスクリプトを即座に終了させます。rm -f ...: 以前のテスト実行で生成された可能性のある不要なファイルを削除し、クリーンな状態にします。for i in *.go; do ... done: ディレクトリ内のすべてのGoファイルに対してループします。if grep -q '^// cmpout$' $i; then ... fi: 現在のGoファイルが// cmpoutディレクティブを含んでいるかどうかをチェックします。go run $i &> ${i/.go/.out}:// cmpoutディレクティブを持つGoファイルを実行し、その標準出力と標準エラー出力を、対応する.outファイルにリダイレクトして保存します。これにより、プログラムの現在の出力が.outファイルに書き込まれ、テストの基準が更新されます。これは、プログラムの挙動が変更された際に、手動で.outファイルを更新する手間を省くための非常に便利なツールです。
src/run.bat の変更
echo # ..\doc\progs
go run %GOROOT%\test\run.go - ..\doc\progs
if errorlevel 1 goto fail
echo.
Windows環境でのGoのテストスイート全体を実行する src/run.bat に、doc\progs ディレクトリのテストを実行する行が追加されました。
go run %GOROOT%\test\run.go - ..\doc\progs コマンドは、test/run.go スクリプトをGoプログラムとして実行し、引数として ..\doc\progs を渡します。これにより、test/run.go は doc/progs ディレクトリ内のGoプログラムを検出し、それぞれのディレクティブ(// skip, // cmpout など)に従ってテストを実行します。
if errorlevel 1 goto fail は、コマンドの実行結果がエラーであった場合に、スクリプトを fail ラベルにジャンプさせるWindowsバッチスクリプトの一般的なエラーハンドリングです。
これらの変更は、Goのドキュメントに含まれるサンプルコードの品質を維持し、特にWindows環境でのテストの自動化と信頼性を高める上で重要な役割を果たしています。
関連リンク
- Go CL (Change List): https://golang.org/cl/6218048
参考にした情報源リンク
- 上記のGo CLのリンク
- Go言語の公式ドキュメント (特に
go testコマンドやcgoに関するセクション) - Go言語のソースコードリポジトリ (
test/run.goやdoc/ディレクトリの構造) - Gitの
diffコマンドの出力形式に関する一般的な知識 Makefileおよびbashスクリプトに関する一般的な知識- Windowsバッチスクリプトに関する一般的な知識
- Go言語の
effective_go.htmlドキュメント (コミットで変更されたファイル) godocコマンドの機能