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

[インデックス 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言語および関連技術に関する知識が必要です。

  1. Go言語のテストフレームワーク: Go言語には標準で testing パッケージが用意されており、go test コマンドを使ってテストを実行します。しかし、このコミットで扱われているのは、Goのソースコードリポジトリ内の特定のテストヘルパースクリプト (test/run.go) や、ドキュメントのサンプルコードを検証するためのカスタムなテストメカニズムです。
  2. test/run.go: これはGo言語の公式リポジトリ内に存在する、Goプログラムのテスト実行を補助するためのユーティリティスクリプトです。通常の go test とは異なり、特定のディレクトリ内のGoファイルをコンパイル・実行し、その出力や挙動を検証するような、より柔軟なテストシナリオに対応するために使用されます。特に、Goのビルドシステムやテストインフラストラクチャの一部として機能します。
  3. Cgo: CgoはGoプログラムからC言語のコードを呼び出すためのGoの機能です。Cgoを使用するプログラムは、Cコンパイラやリンカがシステムにインストールされている必要があり、通常のGoプログラムよりもビルド・実行環境の依存関係が複雑になります。そのため、Cgoプログラムのテストは、Cgoが有効な環境でのみ実行可能です。
  4. Makefile: Makefilemake コマンドによって実行されるビルド自動化ツールです。Goプロジェクトでは、テストの実行、コードの生成、ドキュメントのビルドなど、様々なタスクを自動化するために使用されます。このコミットでは、doc/Makefile がドキュメントのサンプルコードのテストに関連するターゲットを持つことが示唆されています。
  5. *.bat ファイル (Windows Batch Script): Windows環境でコマンドを実行するためのスクリプトファイルです。Unix系OSのシェルスクリプト (.sh.bash) に相当します。src/run.bat は、Goのテストスイート全体を実行するためのWindows固有のスクリプトであり、このコミットでは doc/progs のテストを test/run.go 経由で実行するように変更されています。
  6. ドキュメントのサンプルコードのテスト: Goの公式ドキュメント(特に effective_go.html など)には、Go言語の機能を示すためのコード例が埋め込まれています。これらのコード例が常に正しく動作することを保証するために、自動テストが実行されます。このコミットは、そのテストメカニズムの一部を修正しています。
  7. // skip, // cmpout, // compile, // run ディレクティブ: Goのテストシステムやドキュメント生成システムで使用される、特別なコメントディレクティブです。これらは、Goのソースファイルの上部に記述され、そのファイルがどのようにテストされるべきか、あるいはドキュメントにどのように組み込まれるべきかを指示します。
    • // skip: そのファイルをテストから除外します。
    • // cmpout: プログラムの実行結果を、対応する .out ファイルの内容と比較して検証します。
    • // compile: プログラムがコンパイルできることを検証します(実行はしません)。
    • // run: プログラムを実行し、その実行がエラーなく完了することを検証します。

技術的詳細

このコミットは、Go言語のドキュメント (doc/) 内のサンプルプログラムのテスト方法に複数の変更を加えています。

  1. 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 というコメントが追加されました。これは、このプログラムがカレントディレクトリのファイルリストを出力するため、出力比較テストには適さないことを示唆しています。
  2. doc/Makefile の変更:
    • compare という新しい make ターゲットが追加されました。このターゲットは、RAWHTML 変数で指定されたHTMLファイル(Goドキュメントの生HTML)を godoc -url コマンドで処理し、その出力と元のHTMLファイルを diff -u で比較します。これは、ドキュメントのHTMLが godoc によって正しく生成されることを検証するためのものです。
  3. doc/progs/update.bash の新規追加:
    • このシェルスクリプトは、doc/progs ディレクトリ内のGoプログラムのテスト結果を自動的に生成するためのものです。
    • 既存の .out, .rej, .orig ファイルなどを削除します。
    • // cmpout ディレクティブを持つGoファイルを見つけ、go run で実行し、その出力を対応する .out ファイルにリダイレクトします。これにより、期待される出力ファイルが自動的に更新されます。これは、テストの基準となる出力を簡単に更新するためのユーティリティです。
  4. 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でのパスの長さ制限による問題がまだ存在することを示唆しています。

これらの変更により、Goドキュメントのサンプルコードのテストがより自動化され、特にWindows環境でのテストの実行可能性と信頼性が向上しました。

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

このコミットにおけるコアとなるコードの変更箇所は以下の通りです。

  1. 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 が追加。
  2. doc/progs/*.out ファイル群:
    • // cmpout ディレクティブを持つGoプログラムに対応する、期待される出力を含む新しい .out ファイルが多数追加されました。
    • 例: doc/progs/defer.out (新規ファイル)
    • 例: doc/progs/defer2.out (新規ファイル)
  3. doc/Makefile:
    • compare という新しい make ターゲットが追加され、godoc の出力と既存のHTMLファイルを比較するロジックが記述されました。
  4. doc/progs/update.bash:
    • // cmpout ディレクティブを持つGoプログラムの .out ファイルを自動生成・更新するためのシェルスクリプトが新規追加されました。
  5. src/run.bat:
    • Windows環境でのテスト実行スクリプトに、doc\progs ディレクトリのテストを test/run.go を使用して実行するコマンドが追加されました。

コアとなるコードの解説

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/Makefilecompare ターゲット

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 ファイル) を自動的に生成または更新するためのユーティリティです。

  1. set -e: コマンドが失敗した場合にスクリプトを即座に終了させます。
  2. rm -f ...: 以前のテスト実行で生成された可能性のある不要なファイルを削除し、クリーンな状態にします。
  3. for i in *.go; do ... done: ディレクトリ内のすべてのGoファイルに対してループします。
  4. if grep -q '^// cmpout$' $i; then ... fi: 現在のGoファイルが // cmpout ディレクティブを含んでいるかどうかをチェックします。
  5. 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.godoc/progs ディレクトリ内のGoプログラムを検出し、それぞれのディレクティブ(// skip, // cmpout など)に従ってテストを実行します。 if errorlevel 1 goto fail は、コマンドの実行結果がエラーであった場合に、スクリプトを fail ラベルにジャンプさせるWindowsバッチスクリプトの一般的なエラーハンドリングです。

これらの変更は、Goのドキュメントに含まれるサンプルコードの品質を維持し、特にWindows環境でのテストの自動化と信頼性を高める上で重要な役割を果たしています。

関連リンク

参考にした情報源リンク

  • 上記のGo CLのリンク
  • Go言語の公式ドキュメント (特に go test コマンドや cgo に関するセクション)
  • Go言語のソースコードリポジトリ (test/run.godoc/ ディレクトリの構造)
  • Gitの diff コマンドの出力形式に関する一般的な知識
  • Makefile および bash スクリプトに関する一般的な知識
  • Windowsバッチスクリプトに関する一般的な知識
  • Go言語の effective_go.html ドキュメント (コミットで変更されたファイル)
  • godoc コマンドの機能