[インデックス 19679] ファイルの概要
このコミットは、Go言語のobjdump
コマンドのテストに関する変更です。具体的には、objdump_test.go
ファイルが修正され、AndroidおよびNaCl(Native Client)環境でのテスト実行がスキップされるように変更されました。これは、これらの環境でgo tool nm
コマンドが利用できないことに起因するテストの失敗を回避するための対応です。
コミット
commit 8543ed3df5595e584e9b06ae937c7ba72dea9bfe
Author: David Crawshaw <david.crawshaw@zentus.com>
Date: Tue Jul 8 13:43:22 2014 -0400
cmd/objdump: skip test on android (no Go tool)
LGTM=minux, iant
R=golang-codereviews, minux, iant
CC=golang-codereviews
https://golang.org/cl/109570043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/8543ed3df5595e584e9b06ae937c7ba72dea9bfe
元コミット内容
cmd/objdump: skip test on android (no Go tool)
このコミットは、cmd/objdump
のテストをAndroid環境でスキップするように変更します。その理由は、Android環境ではgo tool
が利用できないためです。
変更の背景
Go言語の開発では、様々なプラットフォーム(OSやアーキテクチャ)での動作を保証するために、広範なテストが行われます。cmd/objdump
は、Goのバイナリを逆アセンブルしてシンボル情報などを表示するためのツールです。このツールのテストは、内部でgo tool nm
というコマンドを使用しています。go tool nm
は、Goのバイナリからシンボルテーブルを抽出するために使われるユーティリティです。
しかし、AndroidやNaClのような特定の環境では、Goのツールチェイン全体が利用できるわけではありません。特に、go tool nm
のような開発・デバッグ用のツールは、これらの組み込み・特殊な環境では提供されないことが一般的です。このため、objdump
のテストがこれらの環境で実行されると、必要なgo tool nm
コマンドが見つからずにテストが失敗するという問題が発生していました。
このコミットは、このような環境依存のテスト失敗を回避し、CI/CDパイプラインの健全性を保つことを目的としています。テストが失敗する原因がツールの欠如である場合、その環境でのテストをスキップすることで、他の重要なテストの実行を妨げずに、開発プロセスをスムーズに進めることができます。
前提知識の解説
-
cmd/objdump
: Go言語の標準ツールの一つで、Goの実行可能バイナリやオブジェクトファイルを解析し、その内容(特にアセンブリコードやシンボル情報)を表示するために使用されます。C/C++におけるobjdump
コマンドと同様の機能を提供しますが、Goのバイナリ構造に特化しています。デバッグやパフォーマンス分析において、バイナリの内部構造を理解するのに役立ちます。 -
go tool nm
: Go言語のツールチェインに含まれるユーティリティの一つです。Goの実行可能バイナリやオブジェクトファイルからシンボルテーブル(関数名、変数名などのシンボルとそのアドレス情報)を抽出するために使用されます。nm
は"name list"の略で、Unix系のシステムで広く使われている同名のコマンドに由来します。objdump
のテストでは、このnm
ツールを使ってシンボル情報を取得し、objdump
が正しくシンボルを解析できるかを確認していました。 -
runtime.GOOS
: Go言語の標準ライブラリruntime
パッケージで提供される定数で、プログラムが実行されているオペレーティングシステム(OS)の名前を表す文字列です。例えば、Linuxでは"linux"
、macOSでは"darwin"
、Windowsでは"windows"
、Androidでは"android"
、Native Clientでは"nacl"
といった値を取ります。この定数を利用することで、OSに依存する処理を条件分岐させることができます。 -
t.Skip()
/t.Skipf()
: Go言語の標準テストパッケージtesting
で提供されるメソッドです。テスト関数内でt.Skip("理由")
またはt.Skipf("フォーマット文字列", 引数...)
を呼び出すと、そのテストはスキップされ、テスト結果には「SKIP」として記録されます。これは、特定の環境でのみ実行できないテストや、まだ実装されていない機能のテストなどを一時的に無効にする際に便利です。テストが失敗するのではなく、意図的にスキップされたことを明確に示します。 -
AndroidとGoのツールチェイン: AndroidはLinuxカーネルをベースとしたモバイルOSですが、その実行環境は一般的なデスクトップLinuxとは異なります。Go言語はAndroidアプリケーションの開発(Go Mobileプロジェクトなど)もサポートしていますが、Androidデバイス上でGoのコンパイラや開発ツールチェイン全体を直接実行することは通常想定されていません。Goのプログラムはクロスコンパイルされ、Androidデバイスにデプロイされます。そのため、
go tool nm
のような開発ツールがAndroid環境で利用できないのは自然なことです。 -
NaCl (Native Client): Googleが開発した、Webブラウザ内でネイティブコードを安全に実行するための技術です。Go言語もNaClをターゲットとしてサポートしていましたが、現在は非推奨となっています。NaCl環境もまた、Goの完全なツールチェインが利用できる環境ではありませんでした。
技術的詳細
このコミットの技術的な変更は非常にシンプルで、objdump_test.go
内のテスト関数が実行される前に、現在のOSがAndroidまたはNaClであるかをチェックし、該当する場合はテストをスキップするというものです。
変更前は、loadSyms
, runObjDump
, buildObjdump
の各関数内で、runtime.GOOS == "nacl"
という条件でNaCl環境でのみスキップしていました。これは、NaCl環境でもgo tool nm
が利用できないためです。
変更後は、この条件がswitch runtime.GOOS
文に拡張され、"android"
と"nacl"
の両方でテストがスキップされるようになりました。これにより、Android環境でも同様の問題が解決されます。
具体的には、以下のコードパターンが適用されています。
// 変更前
if runtime.GOOS == "nacl" {
t.Skip("skipping on nacl")
}
// 変更後
switch runtime.GOOS {
case "android", "nacl":
t.Skipf("skipping on %s", runtime.GOOS)
}
t.Skipf
を使用することで、スキップ理由に現在のOS名を含めることができ、テストレポートの可読性が向上します。
この変更は、Goのクロスプラットフォーム開発における現実的な課題への対応を示しています。すべてのプラットフォームで同じテストを完全に実行できるわけではないため、特定の環境で利用できないツールや機能に依存するテストは、その環境でスキップするというプラクティスが採用されています。これにより、テストスイート全体の実行時間を短縮し、無関係な環境でのテスト失敗によるノイズを減らすことができます。
コアとなるコードの変更箇所
変更はsrc/cmd/objdump/objdump_test.go
ファイルに集中しています。
--- a/src/cmd/objdump/objdump_test.go
+++ b/src/cmd/objdump/objdump_test.go
@@ -19,8 +19,9 @@ import (
)
func loadSyms(t *testing.T) map[string]string {
- if runtime.GOOS == "nacl" {
- t.Skip("skipping on nacl")
+ switch runtime.GOOS {
+ case "android", "nacl":
+ t.Skipf("skipping on %s", runtime.GOOS)
}
cmd := exec.Command("go", "tool", "nm", os.Args[0])
@@ -44,8 +45,9 @@ func loadSyms(t *testing.T) map[string]string {
}
func runObjDump(t *testing.T, exe, startaddr, endaddr string) (path, lineno string) {
- if runtime.GOOS == "nacl" {
- t.Skip("skipping on nacl")
+ switch runtime.GOOS {
+ case "android", "nacl":
+ t.Skipf("skipping on %s", runtime.GOOS)
}
cmd := exec.Command(exe, os.Args[0], startaddr, endaddr)
@@ -111,8 +113,9 @@ func TestObjDump(t *testing.T) {
}
func buildObjdump(t *testing.T) (tmp, exe string) {
- if runtime.GOOS == "nacl" {
- t.Skip("skipping on nacl")
+ switch runtime.GOOS {
+ case "android", "nacl":
+ t.Skipf("skipping on %s", runtime.GOOS)
}
tmp, err := ioutil.TempDir("", "TestObjDump")
コアとなるコードの解説
上記のdiffが示すように、loadSyms
, runObjDump
, buildObjdump
という3つのテストヘルパー関数(またはテスト関連関数)の冒頭に、OS判定とスキップ処理が追加されています。
-
func loadSyms(t *testing.T) map[string]string
: この関数は、テスト対象のバイナリからシンボル情報をロードするためにgo tool nm
コマンドを実行します。変更前はNaCl環境でのみスキップしていましたが、変更後はAndroid環境でもスキップするようになりました。 -
func runObjDump(t *testing.T, exe, startaddr, endaddr string) (path, lineno string)
: この関数は、objdump
コマンドを実際に実行し、その出力を解析します。この関数もgo tool nm
の出力に依存する可能性があるため、同様にAndroidとNaClでスキップされます。 -
func buildObjdump(t *testing.T) (tmp, exe string)
: この関数は、objdump
のテストに必要な一時ファイルや実行可能ファイルをビルドする役割を担っています。ビルドプロセス自体がgo tool
に依存する可能性があるため、ここでもAndroidとNaClでのスキップが導入されました。
これらの変更により、AndroidおよびNaCl環境でgo tool nm
が利用できないことによるテストの失敗が回避され、CIシステムがより正確な結果を報告できるようになります。t.Skipf
を使用することで、どのOSでテストがスキップされたのかがテストログに明示的に表示され、デバッグやテスト結果の理解に役立ちます。
関連リンク
- Go言語の
objdump
コマンドのドキュメント(Goのバージョンによって内容は異なる可能性があります): https://pkg.go.dev/cmd/objdump - Go言語の
nm
コマンドのドキュメント(Goのバージョンによって内容は異なる可能性があります): https://pkg.go.dev/cmd/go#hdr-Go_tool_nm - Go言語の
runtime
パッケージのドキュメント: https://pkg.go.dev/runtime - Go言語の
testing
パッケージのドキュメント: https://pkg.go.dev/testing
参考にした情報源リンク
- Go言語の公式ドキュメント
- Go言語のソースコード(特に
src/cmd/objdump/objdump_test.go
) - Go言語のIssueトラッカーやコードレビューシステム(CL 109570043)
- 一般的なGo言語のテストプラクティスに関する情報