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

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

このコミットは、Go言語の標準ライブラリであるnetパッケージ内のテストファイルsrc/pkg/net/interface_unix_test.goに対する変更です。具体的には、特定のネットワーク機能(ポイントツーポイントインターフェースのテストやインターフェースの到着・離脱の監視テスト)を扱うテストが、go test -shortフラグが指定された「ショートモード」で実行される際にスキップされるように修正されています。

コミット

commit 2f2f9fef90d8397e666eed45b312d055099cb218
Author: Mikio Hara <mikioh.mikioh@gmail.com>
Date:   Mon Mar 25 13:25:28 2013 +0900

    net: disable tests with controlling network facilities in short mode
    
    Perhaps it would make FreeBSD 10-CURRENT/ARM on Raspberry Pi builders happy.
    
    R=golang-dev, dave
    CC=golang-dev
    https://golang.org/cl/8008043

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

https://github.com/golang/go/commit/2f2f9fef90d8397e666eed45b312d055099cb218

元コミット内容

net: disable tests with controlling network facilities in short mode

このコミットは、ネットワーク機能を制御するテストをショートモードで無効化します。

変更の背景

コミットメッセージには「Perhaps it would make FreeBSD 10-CURRENT/ARM on Raspberry Pi builders happy.」と明記されています。これは、Go言語のCI/CD(継続的インテグレーション/継続的デリバリー)システムにおいて、特にFreeBSD 10-CURRENT/ARMアーキテクチャを搭載したRaspberry Piのような特定のビルド環境で、これらのネットワーク関連テストが不安定になったり、実行に時間がかかりすぎたりする問題が発生していたことを示唆しています。

一般的なテストスイートでは、全てのテストを実行すると時間がかかりすぎる場合があります。そのため、開発者は通常、go test -shortフラグを使用して、高速に実行できるテストのサブセットのみを実行します。しかし、ネットワークインターフェースの作成や監視といったOSレベルの操作を伴うテストは、実行環境のネットワーク設定、OSのバージョン、あるいは必要な権限(例: root権限)によって挙動が異なったり、実行に時間がかかったりすることがあります。

このコミットの目的は、これらの不安定なテストがCI/CDパイプラインや開発者のローカル環境でgo test -shortが使用された際に、テストスイート全体の安定性と実行速度を向上させることにあります。テストを完全に削除するのではなく、特定の条件下(ショートモード)でのみスキップすることで、フルテスト実行時には引き続きこれらのテストが実行され、網羅性を保つことができます。

前提知識の解説

このコミットを理解するためには、以下のGo言語のテストに関する知識と、一般的なネットワーク操作に関する理解が必要です。

  1. Go言語のtestingパッケージ:

    • testing.T: Goのテスト関数は*testing.T型の引数を受け取ります。この型はテストの実行を制御するためのメソッド(例: t.Skip(), t.Error(), t.Fatal()など)を提供します。
    • testing.Short(): この関数は、go test -shortコマンドラインフラグが指定された場合にtrueを返します。開発者がテストを高速に実行したい場合に、時間のかかるテストやリソースを大量に消費するテストをスキップするために使用されます。
    • t.Skip(args ...interface{}): このメソッドが呼び出されると、現在のテストはスキップされ、テスト関数は直ちに終了します。スキップされたテストは、テスト結果のサマリーで「SKIP」として報告されます。これは、特定の環境や条件下でテストを実行したくない場合に非常に便利です。
  2. ネットワークインターフェースの操作:

    • TestPointToPointInterfaceTestInterfaceArrivalAndDepartureのようなテストは、オペレーティングシステムが提供するネットワークインターフェースを直接操作する可能性があります。これには、仮想インターフェースの作成、既存インターフェースの状態変更、またはネットワークイベントの監視などが含まれます。
    • これらの操作は、多くの場合、システムレベルの権限(例: Unix系OSでのroot権限)を必要とします。コミット内のコードにもos.Getuid() != 0というroot権限チェックが存在します。
    • 特定のOS(例: Darwin/macOS)では、一部のネットワーク機能のテストが異なる振る舞いをしたり、サポートされていなかったりすることがあります。
  3. Goのクロスコンパイルとビルド環境:

    • Goはクロスコンパイルに優れており、様々なOSやアーキテクチャ(例: GOOS=freebsd GOARCH=arm)向けにバイナリを生成できます。
    • CI/CDシステムでは、異なるプラットフォーム(Linux, Windows, macOS, FreeBSD, ARMなど)でテストを実行する「ビルダー」が稼働しています。これらの環境の中には、リソースが限られていたり、特定のハードウェアに依存していたりするもの(例: Raspberry Pi)があり、テストの安定性に影響を与えることがあります。

技術的詳細

このコミットの主要な変更点は、src/pkg/net/interface_unix_test.goファイル内の2つのテスト関数、TestPointToPointInterfaceTestInterfaceArrivalAndDepartureの冒頭に、testing.Short()のチェックを追加したことです。

変更前は、これらのテストはos.Getuid() != 0(root権限がない場合のスキップ)やruntime.GOOS == "darwin"(macOSでの特定のテストスキップ)といった条件に基づいてスキップされていました。

変更後は、これらの既存の条件に加えて、testing.Short()true(つまり、go test -shortで実行されている)の場合にもテストがスキップされるようになりました。

// TestPointToPointInterface 関数内
if testing.Short() { // 新しく追加された行
    t.Skip("skipping test in short mode") // 新しく追加された行
}
// ... 既存のコード ...

// TestInterfaceArrivalAndDeparture 関数内
if testing.Short() { // 新しく追加された行
    t.Skip("skipping test in short mode") // 新しく追加された行
}
// ... 既存のコード ...

これにより、これらのテストは以下のいずれかの条件が満たされた場合にスキップされます。

  • go test -shortフラグが指定されている場合。
  • root権限で実行されていない場合(TestPointToPointInterfaceTestInterfaceArrivalAndDepartureの両方)。
  • TestPointToPointInterfaceの場合、runtime.GOOS"darwin"である場合(読み取りテストのみ)。

また、TestPointToPointInterface関数内のswitch文の構文がswitch runtime.GOOS { case "darwin":からswitch { case runtime.GOOS == "darwin":に変更されています。これは機能的には同等ですが、より一般的なswitch構文を使用することで、将来的に複数の条件をcase句で組み合わせる柔軟性を持たせるためのリファクタリングと考えられます。

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

--- a/src/pkg/net/interface_unix_test.go
+++ b/src/pkg/net/interface_unix_test.go
@@ -41,8 +41,11 @@ func (ti *testInterface) teardown() error {
 }
 
 func TestPointToPointInterface(t *testing.T) {
-	switch runtime.GOOS {
-	case "darwin":
+	if testing.Short() {
+		t.Skip("skipping test in short mode")
+	}
+	switch {
+	case runtime.GOOS == "darwin":
 		t.Skipf("skipping read test on %q", runtime.GOOS)
 	}
 	if os.Getuid() != 0 {
@@ -90,6 +93,9 @@ func TestPointToPointInterface(t *testing.T) {
 }
 
 func TestInterfaceArrivalAndDeparture(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping test in short mode")
+	}
 	if os.Getuid() != 0 {
 		t.Skip("skipping test; must be root")
 	}

コアとなるコードの解説

このコミットの核心は、testing.Short()関数とt.Skip()メソッドの組み合わせです。

  • if testing.Short() { t.Skip("skipping test in short mode") }
    • testing.Short(): この関数は、Goのテストランナーが-shortフラグ付きで起動されたかどうかをチェックします。trueを返した場合、テストは「ショートモード」で実行されていると判断されます。
    • t.Skip("skipping test in short mode"): testing.Short()trueを返した場合、この行が実行されます。t.Skip()は現在のテスト関数を直ちに終了させ、そのテストがスキップされたことをテスト結果に記録します。引数として渡された文字列は、スキップ理由として表示されます。

この変更により、TestPointToPointInterfaceTestInterfaceArrivalAndDepartureという、おそらく時間のかかる、または特定の環境で不安定になりがちなネットワーク関連のテストが、開発者が高速なフィードバックを求める際に(go test -shortを使用した場合に)自動的にスキップされるようになります。これにより、CI/CDパイプラインの効率が向上し、特にリソースが限られた環境(例: Raspberry Pi)でのビルドの安定性が改善されます。

switch文の変更は、runtime.GOOSの値を直接switchの式として使うのではなく、switch {}という空のswitch式とcase runtime.GOOS == "darwin":という条件式を組み合わせる形になっています。これは、Goのswitch文がif-else ifの連鎖のように機能する柔軟な構文であることを示しており、この特定のケースでは機能的な違いはありませんが、より複雑な条件分岐を将来的に追加する際の準備とも解釈できます。

関連リンク

  • Gerrit Change-ID: https://golang.org/cl/8008043
    • Goプロジェクトでは、GitHubのプルリクエストの代わりにGerritというコードレビューシステムが使用されています。このリンクは、このコミットがレビューされた際のGerrit上の変更セットを示しています。

参考にした情報源リンク

  • Go言語 testing パッケージのドキュメント:
  • Go言語 runtime パッケージのドキュメント:
  • Go言語 os パッケージのドキュメント:
  • Go言語のテストに関する公式ブログ記事やチュートリアル:
    • Goのテストのベストプラクティスやgo testコマンドのオプションについて解説している記事全般。