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

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

このコミットは、Goランタイムのテストスイートにおいて、TestRuntimeGogoBytesという特定のテストがWindows環境で破損している(失敗する)ため、そのテストをWindows上ではスキップするように変更を加えるものです。これにより、Windows環境でのCI/CDパイプラインや開発者のローカル環境でのテスト実行が、この既知の問題によって妨げられることを防ぎます。

コミット

commit ae9e4db07cde3862286cf499c71af9a6fe876b77
Author: Alex Brainman <alex.brainman@gmail.com>
Date:   Wed Dec 18 14:17:47 2013 +1100

    runtime: skip broken TestRuntimeGogoBytes on windows
    
    R=golang-dev, bradfitz
    CC=golang-dev
    https://golang.org/cl/43730043
---
 src/pkg/runtime/runtime_test.go | 4 ++++\n 1 file changed, 4 insertions(+)

diff --git a/src/pkg/runtime/runtime_test.go b/src/pkg/runtime/runtime_test.go
index 238b70572f..f6b48ba3a6 100644
--- a/src/pkg/runtime/runtime_test.go
+++ b/src/pkg/runtime/runtime_test.go
@@ -93,6 +93,10 @@ 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) {
+\t// TODO(brainman): delete when issue 6973 is fixed.
+\tif GOOS == "windows" {
+\t\tt.Skip("skipping broken test on windows")
+\t}\n \tdir, err := ioutil.TempDir("", "go-build")
 \tif err != nil {
 \t\tt.Fatalf("failed to create temp directory: %v", err)

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

https://github.com/golang/go/commit/ae9e4db07cde3862286cf499c71af9a6fe876b77

元コミット内容

runtime: skip broken TestRuntimeGogoBytes on windows

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/43730043

変更の背景

このコミットの主な背景は、Goのランタイムパッケージに含まれるTestRuntimeGogoBytesというテストが、Windowsオペレーティングシステム上で正しく動作せず、常に失敗していたことです。テストが失敗し続けると、CI/CDシステムでのビルドが失敗したり、開発者がWindows環境で作業する際に誤ったエラーを頻繁に目にすることになり、開発効率が低下します。

コミットメッセージには「TODO(brainman): delete when issue 6973 is fixed.」というコメントがあり、これはこのテストの破損がGoのIssue 6973に関連していることを示唆しています。このIssueが修正されれば、このスキップ処理は削除されるべきであるという意図が込められています。ただし、現在の検索ではGoの公式リポジトリで「Issue 6973」という特定の番号の公開された問題は見つかりませんでした。これは、内部的な追跡番号であるか、あるいは非常に古い問題で現在は異なる番号に統合されているか、あるいは既に解決済みでアーカイブされている可能性が考えられます。

この変更は、テストスイート全体の安定性を向上させ、Windows環境での開発およびテストプロセスを円滑にすることを目的としています。一時的な回避策ではありますが、テストが常に失敗する状態を放置するよりも、既知の問題をスキップして他の重要なテストの実行を可能にすることが、開発ワークフローにおいては合理的です。

前提知識の解説

このコミットを理解するためには、以下のGo言語およびテストに関する基本的な知識が必要です。

  1. Goのテストフレームワーク (testing パッケージ):

    • Goには標準ライブラリとしてtestingパッケージが提供されており、これを使ってユニットテストやベンチマークテストを記述します。
    • テスト関数はTestXxxという形式で命名され、*testing.T型の引数を取ります。
    • go testコマンドを実行することで、これらのテストが発見され、実行されます。
  2. t.Skip():

    • *testing.T型が提供するメソッドの一つで、テストの実行を途中で中断し、そのテストを「スキップ」としてマークします。
    • テストが特定の環境や条件でのみ失敗する場合、あるいは一時的に無効化したい場合に利用されます。スキップされたテストは失敗とはみなされず、テスト結果には「SKIP」として表示されます。
  3. GOOS環境変数:

    • Goのビルドシステムが使用する環境変数の一つで、ターゲットとなるオペレーティングシステムを示します。例えば、windowslinuxdarwin(macOS)などがあります。
    • Goのコード内では、runtimeパッケージを通じてこの値にアクセスできます(例: runtime.GOOS)。また、ビルドタグ(例: // +build windows)を使って、特定のOSでのみコンパイルされるコードを記述することもできますが、このコミットでは実行時にGOOSの値をチェックしています。
  4. runtime パッケージ:

    • Goのランタイムシステムに関する低レベルな機能を提供するパッケージです。ガベージコレクション、スケジューラ、ゴルーチン管理、メモリ割り当てなど、Goプログラムの実行環境の根幹をなす機能が含まれています。
    • TestRuntimeGogoBytesのようなテストは、これらのランタイムの内部動作やパフォーマンスを検証するために書かれています。
  5. ioutil.TempDir:

    • io/ioutilパッケージ(Go 1.16以降はosパッケージに移行)の関数で、一時ディレクトリを作成するために使用されます。テスト中に一時的なファイルやディレクトリが必要な場合によく利用されます。

技術的詳細

TestRuntimeGogoBytesテストは、Goランタイムの内部関数であるruntime.gogoに関連するメモリ使用量や動作を検証していると考えられます。runtime.gogoは、ゴルーチンのコンテキストスイッチやスタック切り替えなど、低レベルな処理に関わる関数です。このような低レベルなテストは、OS固有の挙動、メモリ配置、システムコール、あるいはコンパイラの最適化など、非常にデリケートな要因によって異なる結果を示すことがあります。

Windows環境でこのテストが破損していた具体的な理由は、コミットメッセージからは明らかではありませんが、以下のような可能性が考えられます。

  • OS固有のメモリ管理: Windowsのメモリ管理やアロケータの挙動が、他のOS(LinuxやmacOS)と異なり、テストが期待するメモリレイアウトやアライメントを保証できない。
  • スタックの挙動: Windows上でのスタックの成長や割り当てに関する挙動が、テストの前提と異なる。
  • システムコールやAPIの違い: runtime.gogoが内部的に利用するシステムコールやOS APIが、Windowsと他のOSで微妙に異なり、それがテストの失敗につながる。
  • ツールチェインの差異: Windows版のGoコンパイラやリンカが生成するバイナリの特性が、テストの期待値と合わない。
  • 競合状態やタイミングの問題: Windowsのスケジューラやスレッドモデルの特性により、テスト内で特定の競合状態やタイミングの問題が発生しやすい。

テストをスキップするという決定は、その問題がすぐに修正できない、あるいは修正が複雑で時間がかかる場合に、開発ワークフローをブロックしないための実用的なアプローチです。TODOコメントは、このスキップが一時的なものであり、根本的な問題が解決され次第、テストを再度有効にする意図があることを明確に示しています。

この変更は、Goのクロスプラットフォーム対応における課題の一端を示しています。Goは様々なOSで動作するように設計されていますが、低レベルなランタイムの挙動はOS間で完全に同一ではないため、OS固有の調整やテストのスキップが必要になることがあります。

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

変更はsrc/pkg/runtime/runtime_test.goファイルに集中しており、以下の4行が追加されています。

--- a/src/pkg/runtime/runtime_test.go
+++ b/src/pkg/runtime/runtime_test.go
@@ -93,6 +93,10 @@ 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) {
+\t// TODO(brainman): delete when issue 6973 is fixed.
+\tif GOOS == "windows" {
+\t\tt.Skip("skipping broken test on windows")
+\t}\n \tdir, err := ioutil.TempDir("", "go-build")
 \tif err != nil {
 \t\tt.Fatalf("failed to create temp directory: %v", err)

コアとなるコードの解説

追加されたコードは、TestRuntimeGogoBytes関数の冒頭に配置されています。

  1. // TODO(brainman): delete when issue 6973 is fixed.

    • これは開発者向けのコメントで、このコードが一時的な回避策であり、GoのIssue 6973が解決された際には削除されるべきであることを示しています。brainmanはコミットの作者であるAlex Brainmanのハンドル名です。
  2. if GOOS == "windows" { ... }

    • この行は、現在のGoプログラムが実行されているオペレーティングシステムがWindowsであるかどうかをチェックしています。GOOSはGoのビルドシステムが設定する環境変数であり、Goのコード内ではruntime.GOOSとしてアクセスできますが、テストファイルではGOOSというグローバルな定数として利用できる場合があります(これはビルド時の環境変数から設定される)。
  3. t.Skip("skipping broken test on windows")

    • もしGOOSwindowsである場合、この行が実行されます。
    • t.Skip()は、現在のテストをスキップし、それ以上のテストコードの実行を停止します。引数として渡された文字列は、テスト結果の出力に表示され、なぜテストがスキップされたのかを説明します。この場合、「Windows上で破損したテストをスキップしています」というメッセージが表示されます。

このコードブロック全体として、Windows環境でのみTestRuntimeGogoBytesテストを条件付きで無効化し、テストスイートの安定性を保つ役割を果たしています。

関連リンク

参考にした情報源リンク