[インデックス 19219] ファイルの概要
このコミットは、Go言語の cmd/nm
ツールに関連するテスト (nm_test.go
) の堅牢性を向上させるものです。具体的には、nm
コマンドの出力が期待される3カラム未満であった場合にテストが失敗する問題を修正し、特定のOSでのテストスキップを不要にしました。
コミット
cmd/nm: do not fail TestNM if symbol has less then 3 columns in nm output
Fixes #7829
LGTM=dave
R=golang-codereviews, aram, dave
CC=golang-codereviews
https://golang.org/cl/89830043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/296eeaa78df8537964821756c393cbd06174a119
元コミット内容
commit 296eeaa78df8537964821756c393cbd06174a119
Author: Alex Brainman <alex.brainman@gmail.com>
Date: Mon Apr 21 21:12:18 2014 +1000
cmd/nm: do not fail TestNM if symbol has less then 3 columns in nm output
Fixes #7829
LGTM=dave
R=golang-codereviews, aram, dave
CC=golang-codereviews
https://golang.org/cl/89830043
---
src/cmd/nm/nm_test.go | 5 -----
1 file changed, 5 deletions(-)
diff --git a/src/cmd/nm/nm_test.go b/src/cmd/nm/nm_test.go
index b2320bdf9f..829c844b49 100644
--- a/src/cmd/nm/nm_test.go
+++ b/src/cmd/nm/nm_test.go
@@ -19,16 +19,11 @@ import (
var testData uint32
func checkSymbols(t *testing.T, nmoutput []byte) {
-\tswitch runtime.GOOS {\n-\tcase \"linux\", \"darwin\", \"solaris\":\n-\t\tt.Skip(\"skipping test; see http://golang.org/issue/7829\")\n-\t}\n \tvar checkSymbolsFound, testDataFound bool\n \tscanner := bufio.NewScanner(bytes.NewBuffer(nmoutput))\n \tfor scanner.Scan() {\n \t\tf := strings.Fields(scanner.Text())\n \t\tif len(f) < 3 {\n-\t\t\tt.Error(\"nm must have at least 3 columns\")\n \t\t\tcontinue\n \t\t}\n \t\tswitch f[2] {\n
変更の背景
この変更は、Goの cmd/nm
ツールに対するテスト (nm_test.go
) が、特定の環境下で nm
コマンドの出力形式の違いにより失敗するという問題(Issue #7829)を解決するために行われました。
nm
コマンドは、オブジェクトファイルや実行可能ファイル内のシンボルテーブルを表示するために使用されます。その出力形式は通常、シンボルのアドレス、型、名前など、複数のカラムで構成されます。しかし、環境(OS、nm
のバージョン、または入力ファイルの種類)によっては、期待されるカラム数(特に3カラム)に満たない行が出力されることがありました。
以前の nm_test.go
の実装では、nm
の出力行をスペースで分割し、その結果が3カラム未満であった場合に t.Error
を呼び出してテストを失敗させていました。これは、nm
の出力が常に特定の形式であるという前提に基づいていたため、この前提が崩れる環境ではテストが不安定になっていました。
この問題に対する一時的な回避策として、以前のコードでは linux
, darwin
, solaris
といった特定のOSでテストをスキップする t.Skip
が導入されていました。しかし、これは根本的な解決策ではなく、テストの網羅性を低下させていました。
このコミットの目的は、nm
の出力形式の多様性に対応できるようテストロジックを修正し、t.Skip
による回避策を削除して、より堅牢で移植性の高いテストを実現することです。
前提知識の解説
nm
コマンド
nm
は、Unix系システムで利用されるコマンドラインユーティリティで、オブジェクトファイル、アーカイブファイル、または実行可能ファイル内のシンボルテーブル(関数名、変数名など)をリスト表示します。出力形式は通常、以下のようになります。
アドレス 型 シンボル名
例えば、0000000000401000 T main
のような形式です。ここで、0000000000401000
はシンボルのアドレス、T
はシンボルの型(ここではテキストセクションのグローバルシンボル)、main
はシンボル名です。このコミットで問題となったのは、この出力が常に3つのフィールド(カラム)を持つとは限らないという点です。
Goのテストフレームワーク (testing
パッケージ)
Go言語には、標準ライブラリとして testing
パッケージが提供されており、ユニットテストやベンチマークテストを記述するために使用されます。
func TestXxx(t *testing.T)
: テスト関数はTest
で始まり、*testing.T
型の引数を取ります。t.Error(args ...interface{})
: テストを失敗としてマークし、指定されたメッセージを出力します。テストの実行は継続されます。t.Skip(args ...interface{})
: テストをスキップします。通常、特定の環境や条件でテストを実行できない場合に利用されます。
bufio.NewScanner
と strings.Fields
bufio.NewScanner
:io.Reader
からデータを読み込み、行単位や単語単位でスキャンするためのユーティリティです。scanner.Scan()
は次のトークン(デフォルトでは行)を読み込み、scanner.Text()
でその内容を取得します。strings.Fields(s string)
: 文字列s
を一つ以上の連続する空白文字で分割し、空でない部分文字列のスライスを返します。例えば、" a b c "
は["a", "b", "c"]
となります。この関数は、nm
コマンドの出力をカラムごとに分割するために使用されていました。
runtime.GOOS
runtime.GOOS
は、Goプログラムがコンパイルまたは実行されているオペレーティングシステムを示す文字列定数です(例: "linux"
, "darwin"
, "windows"
)。以前のコードでは、この変数を使って特定のOSでのテストをスキップしていました。
技術的詳細
このコミットの技術的な核心は、nm
コマンドの出力形式に関する誤った仮定を修正することにあります。
src/cmd/nm/nm_test.go
内の checkSymbols
関数は、nm
コマンドの出力を解析し、特定のシンボルが存在するかどうかを確認する役割を担っていました。この関数は、bufio.NewScanner
を使用して nm
の出力を1行ずつ読み込み、strings.Fields
を使って各行を空白で分割していました。
問題のコードは以下の部分でした。
f := strings.Fields(scanner.Text())
if len(f) < 3 {
t.Error("nm must have at least 3 columns")
continue
}
このコードは、「nm
の出力は常に少なくとも3つのカラムを持つ」という前提に基づいていました。もし strings.Fields
が返すスライスの要素数(len(f)
)が3未満であった場合、それは不正な出力と見なされ、t.Error
が呼び出されてテストが失敗していました。
しかし、実際には、nm
コマンドの出力は、環境や入力ファイルの種類によっては、3カラム未満の行を含むことがあります。例えば、空行や、シンボル情報ではない警告メッセージなどが含まれる場合です。このような行に対して t.Error
を呼び出すことは、nm
コマンド自体の問題ではなく、テストが nm
の出力の多様性を考慮していないことによるものでした。
このコミットでは、t.Error("nm must have at least 3 columns")
の行が削除されました。これにより、len(f) < 3
の条件が満たされた場合でも、テストはエラーとしてマークされなくなります。代わりに continue
が残されているため、不正な形式の行は単にスキップされ、次の行の処理に移ります。
この変更により、テストは nm
の出力が常に厳密な3カラム形式であるという仮定から解放され、より柔軟になりました。結果として、以前は t.Skip
で回避されていた特定のOSでのテスト失敗が解消され、テストの網羅性が向上しました。
また、この修正により、switch runtime.GOOS
を使って linux
, darwin
, solaris
でテストをスキップしていたコードブロックも不要となり、削除されました。これは、根本的な問題が解決されたため、特定の環境での回避策がもはや必要なくなったことを意味します。
コアとなるコードの変更箇所
--- a/src/cmd/nm/nm_test.go
+++ b/src/cmd/nm/nm_test.go
@@ -19,16 +19,11 @@ import (
var testData uint32
func checkSymbols(t *testing.T, nmoutput []byte) {
-\tswitch runtime.GOOS {\n-\tcase \"linux\", \"darwin\", \"solaris\":\n-\t\tt.Skip(\"skipping test; see http://golang.org/issue/7829\")\n-\t}\n \tvar checkSymbolsFound, testDataFound bool\n \tscanner := bufio.NewScanner(bytes.NewBuffer(nmoutput))\n \tfor scanner.Scan() {\n \t\tf := strings.Fields(scanner.Text())\n \t\tif len(f) < 3 {\n-\t\t\tt.Error(\"nm must have at least 3 columns\")\n \t\t\tcontinue\n \t\t}\n \t\tswitch f[2] {\n
コアとなるコードの解説
このコミットでは、src/cmd/nm/nm_test.go
ファイル内の checkSymbols
関数が変更されています。
-
switch runtime.GOOS
ブロックの削除:- switch runtime.GOOS { - case "linux", "darwin", "solaris": - t.Skip("skipping test; see http://golang.org/issue/7829") - }
このブロックは、以前は
linux
,darwin
,solaris
の各OSでcheckSymbols
テストをスキップするために使用されていました。これは、これらのOSでnm
コマンドの出力形式が原因でテストが失敗する問題(Issue #7829)に対する一時的な回避策でした。今回のコミットで根本的な問題が解決されたため、このOS固有のスキップロジックは不要となり、削除されました。これにより、テストはすべてのサポート対象OSで実行されるようになり、テストの網羅性が向上しました。 -
if len(f) < 3
ブロック内のt.Error
の削除:- t.Error("nm must have at least 3 columns")
この行は、
nm
コマンドの出力行をstrings.Fields
で分割した結果(f
)が3カラム未満であった場合に、テストをエラーとしてマークしていました。このコミットでは、このt.Error
の呼び出しが削除されました。 これは、nm
の出力が常に3カラム以上であるという仮定が誤りであり、環境によっては3カラム未満の行(例えば、空行や非シンボル情報)が出力される可能性があることを認識したためです。テストがこのような「不正な」行で失敗するのではなく、単にそれらを無視して処理を続行するように変更されました。
変更後のコードでは、if len(f) < 3
の条件が真の場合、continue
ステートメントのみが実行されます。これにより、現在の行の残りの処理(シンボル名のチェックなど)はスキップされ、scanner.Scan()
によって次の行の読み込みに進みます。この修正により、nm
の出力形式が多様な環境でもテストが堅牢になり、不必要なテスト失敗が回避されるようになりました。
関連リンク
- GitHubコミットページ: https://github.com/golang/go/commit/296eeaa78df8537964821756c393cbd06174a119
- Go Change List (CL): https://golang.org/cl/89830043
- 関連するGo Issue (コミットメッセージより): #7829
参考にした情報源リンク
- コミットメッセージと差分 (
./commit_data/19219.txt
の内容) - Go言語の
testing
パッケージに関する一般的な知識 nm
コマンドに関する一般的な知識bufio
およびstrings
パッケージに関する一般的な知識runtime.GOOS
に関する一般的な知識