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

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

このコミットは、Goランタイムのテストスイートにおいて、クラッシュテストがAndroid環境でスキップされるように変更を加えるものです。具体的には、runtime.GOOSの値が"android"または"nacl"の場合に、テストが実行されないように修正されています。これにより、特定のプラットフォームでのテストの不安定性や互換性の問題を回避し、CI/CDパイプラインの安定化に貢献します。

コミット

commit 1648df672824f64f30070d0c6b671329ce0e2b77
Author: David Crawshaw <david.crawshaw@zentus.com>
Date:   Tue Jul 8 14:47:52 2014 -0400

    runtime: skip crash test on android
    
    LGTM=bradfitz
    R=golang-codereviews, bradfitz, minux
    CC=golang-codereviews
    https://golang.org/cl/110400043

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

https://github.com/golang/go/commit/1648df672824f64f30070d0c6b671329ce0e2b77

元コミット内容

runtime: skip crash test on android

変更の背景

Go言語のランタイムテストは、様々なオペレーティングシステムやアーキテクチャ上でGoが正しく動作することを保証するために非常に重要です。しかし、特定の環境、特にモバイルプラットフォームや組み込みシステムでは、テストの実行環境がデスクトップやサーバー環境とは異なる特性を持つことがあります。

このコミットの背景には、GoのクラッシュテストがAndroid環境で問題を引き起こしていた可能性が考えられます。クラッシュテストは、意図的にパニックやセグメンテーション違反などの異常な状態を発生させ、ランタイムがそれらを適切に処理できるかを確認するものです。AndroidのようなモバイルOSでは、メモリ管理、シグナルハンドリング、プロセス分離などの挙動がデスクトップOSとは異なり、テストが期待通りに動作しない、あるいはテスト自体が環境を不安定にする可能性があります。

このような場合、テストの失敗がGoランタイム自体のバグではなく、テスト環境の制約やプラットフォーム固有の挙動に起因することがあります。そのため、開発プロセスを円滑に進め、CI/CDパイプラインの安定性を保つために、特定のプラットフォームで問題のあるテストを一時的にスキップする判断がなされることがあります。このコミットは、Android上でのクラッシュテストの実行をスキップすることで、この問題を解決しようとしています。

前提知識の解説

runtime.GOOS

runtime.GOOSはGo言語の標準ライブラリruntimeパッケージで提供される定数で、Goプログラムがコンパイルされ、実行されるオペレーティングシステムの名前を表す文字列です。例えば、Linuxでは"linux"、macOSでは"darwin"、Windowsでは"windows"、そしてAndroidでは"android"となります。この定数を使用することで、プラットフォーム固有のコードパスを条件分岐させることができます。

nacl (Native Client)

naclはGoogleが開発したサンドボックス技術で、ウェブブラウザ内でネイティブコードを安全に実行することを可能にします。Go言語はかつてnaclをターゲットプラットフォームの一つとしてサポートしていました。nacl環境もまた、通常のデスクトップOSとは異なる制約やセキュリティモデルを持つため、特定のテストがスキップされる対象となることがありました。

testing.T.Skip および testing.T.Skipf

Go言語のテストフレームワークであるtestingパッケージには、テストの実行をスキップするためのメソッドが用意されています。

  • t.Skip(args ...interface{}): テストをスキップし、指定された引数をログに出力します。
  • t.Skipf(format string, args ...interface{}): t.Skipと同様にテストをスキップしますが、fmt.Printf形式でフォーマットされた文字列をログに出力できます。

これらのメソッドは、特定の環境でのみ問題が発生するテストや、まだ実装されていない機能のテストなど、テストを一時的に無効にしたい場合に利用されます。テストがスキップされても、テストスイート全体は成功とみなされますが、スキップされたテストがあることが報告されます。

技術的詳細

このコミットの技術的な変更は、Goのテストコードにおけるプラットフォーム判定ロジックの改善にあります。

元々のコードでは、runtime.GOOS == "nacl"というif文を使って、nacl環境でのみテストをスキップしていました。これは単一の条件をチェックする場合には問題ありませんが、将来的に複数のプラットフォームで同様のスキップが必要になった場合、if文を連ねる形になり、コードの可読性や拡張性が低下します。

このコミットでは、このif文をswitch文に置き換えることで、複数のプラットフォーム(この場合は"android""nacl")を簡潔に扱うことができるようにしています。

// 変更前
if runtime.GOOS == "nacl" {
    t.Skip("skipping on nacl")
}

// 変更後
switch runtime.GOOS {
case "android", "nacl":
    t.Skipf("skipping on %s", runtime.GOOS)
}

switch文のcase "android", "nacl":という構文は、runtime.GOOS"android"または"nacl"のいずれかに一致する場合に、そのブロック内のコードが実行されることを意味します。これにより、コードがより整理され、将来的に他のプラットフォームを追加する際も、新しいcaseを追加するだけで済み、変更が容易になります。

また、t.Skipからt.Skipfへの変更も行われています。t.Skipfを使用することで、スキップ理由のメッセージにruntime.GOOSの値を埋め込むことができ、どのOSでスキップされたのかがログから一目でわかるようになります。これはデバッグやテスト結果の分析において非常に有用です。

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

このコミットでは、以下の2つのファイルが変更されています。

  1. src/pkg/runtime/crash_test.go
  2. src/pkg/runtime/runtime_test.go

それぞれのファイルにおける変更の差分は以下の通りです。

diff --git a/src/pkg/runtime/crash_test.go b/src/pkg/runtime/crash_test.go
index b0277f293c..8552d2fe66 100644
--- a/src/pkg/runtime/crash_test.go
+++ b/src/pkg/runtime/crash_test.go
@@ -32,8 +32,9 @@ func testEnv(cmd *exec.Cmd) *exec.Cmd {
 }
 
 func executeTest(t *testing.T, templ string, data interface{}) string {
-if runtime.GOOS == "nacl" {
-t.Skip("skipping on nacl")
+switch runtime.GOOS {
+case "android", "nacl":
+t.Skipf("skipping on %s", runtime.GOOS)
}
 
 checkStaleRuntime(t)
diff --git a/src/pkg/runtime/runtime_test.go b/src/pkg/runtime/runtime_test.go
index a726f500d1..5e24e2570c 100644
--- a/src/pkg/runtime/runtime_test.go
+++ b/src/pkg/runtime/runtime_test.go
@@ -95,8 +95,9 @@ func BenchmarkDeferMany(b *testing.B) {
 // The value reported will include the padding between runtime.gogo and the
 // next function in memory. That's fine.
 func TestRuntimeGogoBytes(t *testing.T) {
-if GOOS == "nacl" {
-t.Skip("skipping on nacl")
+switch GOOS {
+case "android", "nacl":
+t.Skipf("skipping on %s", GOOS)
}
 
 dir, err := ioutil.TempDir("", "go-build")

コアとなるコードの解説

src/pkg/runtime/crash_test.go の変更

executeTest関数は、Goランタイムのクラッシュテストを実行するためのヘルパー関数です。この関数内で、テストをスキップするロジックが変更されました。

  • 変更前:

    if runtime.GOOS == "nacl" {
        t.Skip("skipping on nacl")
    }
    

    ここでは、runtime.GOOSが厳密に"nacl"である場合にのみ、t.Skipが呼び出され、テストがスキップされていました。

  • 変更後:

    switch runtime.GOOS {
    case "android", "nacl":
        t.Skipf("skipping on %s", runtime.GOOS)
    }
    

    if文がswitch文に置き換えられ、"android""nacl"の両方がcaseとして追加されました。これにより、Android環境でもこのクラッシュテストがスキップされるようになりました。また、t.Skipt.Skipfに変更され、スキップメッセージに現在のOS名が含まれるようになり、より詳細な情報が提供されます。

src/pkg/runtime/runtime_test.go の変更

TestRuntimeGogoBytes関数も同様に、テストをスキップするロジックが変更されました。このテストは、Goランタイムの内部的なメモリレイアウトや関数呼び出しに関するもので、特定の環境で問題が発生する可能性があったと考えられます。

  • 変更前:

    if GOOS == "nacl" {
        t.Skip("skipping on nacl")
    }
    

    ここでも、nacl環境でのみテストがスキップされていました。GOOSは、このコンテキストではruntime.GOOSと同じ値を参照しています。

  • 変更後:

    switch GOOS {
    case "android", "nacl":
        t.Skipf("skipping on %s", GOOS)
    }
    

    crash_test.goと同様に、if文がswitch文に置き換えられ、"android"がスキップ対象に追加されました。これにより、Android環境でもTestRuntimeGogoBytesテストがスキップされるようになります。

これらの変更は、Goランタイムのテストスイートの堅牢性を高め、特定のプラットフォームでのテストの不安定性を軽減することを目的としています。

関連リンク

参考にした情報源リンク

  • なし (コミットメッセージとGoのドキュメントに基づいています)