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

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

このコミットは、Go言語の標準ライブラリである net パッケージ内のマルチキャスト関連のテスト (multicast_test.go) において、Windows環境でのみ特定の外部ネットワークテストを無効化する変更を加えています。これは、Windowsのファイアウォールが原因でテストが不安定になる問題を回避するための措置です。

コミット

commit c10650979f3d66f231b8e69e1cd8293cde4ca778
Author: Russ Cox <rsc@golang.org>
Date:   Wed Mar 7 00:02:07 2012 -0500

    net: disable another external network test
    
    I don't know enough about multicast.
    Should this be disabled on all systems, not just Windows?
    
    R=golang-dev
    CC=golang-dev
    https://golang.org/cl/5754060
---
 src/pkg/net/multicast_test.go | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/pkg/net/multicast_test.go b/src/pkg/net/multicast_test.go
index fe5e8de2f6..67261b1ee7 100644
--- a/src/pkg/net/multicast_test.go
+++ b/src/pkg/net/multicast_test.go
@@ -90,6 +90,11 @@ func TestSimpleMulticastListener(t *testing.T) {
 	case "plan9":
 		t.Logf("skipping test on %q", runtime.GOOS)
 		return
+	case "windows":
+		if testing.Short() || !*testExternal {
+			t.Logf("skipping test on windows to avoid firewall")
+			return
+		}
 	}
 
 	for _, tt := range multicastListenerTests {

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

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

元コミット内容

net: disable another external network test

このコミットは、Go言語の net パッケージにおける外部ネットワークテストをさらに無効化するものです。コミットメッセージには「マルチキャストについて十分に理解していない。Windowsだけでなく、すべてのシステムで無効にすべきか?」という疑問が記されており、マルチキャストテストの安定性に関する懸念が示唆されています。

変更の背景

この変更の背景には、Go言語の net パッケージにおけるマルチキャスト関連のテストが、特にWindows環境で不安定であったという問題があります。コミットメッセージにある「skipping test on windows to avoid firewall」(ファイアウォールを避けるためにWindowsでのテストをスキップする)というログメッセージから、Windowsのファイアウォール設定がマルチキャスト通信をブロックし、テストの失敗やハングアップを引き起こしていた可能性が高いと推測されます。

開発者は、テストの信頼性を確保し、CI/CDパイプラインの安定性を維持するために、一時的または恒久的に問題のあるテストを無効化する判断を下しました。特に、マルチキャストの複雑性やOSごとの挙動の違いが、このような決定の要因となったと考えられます。

前提知識の解説

マルチキャスト (Multicast)

マルチキャストは、ネットワーク通信の一種で、単一の送信元から特定のグループに属する複数の受信元に対してデータを送信する方式です。ユニキャスト(1対1)やブロードキャスト(1対全員)とは異なり、マルチキャストは「1対多」の通信を実現し、帯域幅の効率的な利用を可能にします。例えば、動画ストリーミングやオンラインゲーム、サービスディスカバリなどで利用されます。

Go言語の net パッケージ

Go言語の標準ライブラリである net パッケージは、ネットワークI/Oのプリミティブを提供します。TCP/IP、UDP、Unixドメインソケットなどのネットワークプロトコルを扱うための機能が含まれており、ネットワークアプリケーションを構築する上で基盤となります。マルチキャスト通信もこのパッケージを通じてサポートされています。

Go言語のテストフレームワーク (testing パッケージ)

Go言語には、標準で testing パッケージが提供されており、ユニットテストやベンチマークテストを記述できます。テスト関数は TestXxx(*testing.T) の形式で定義され、go test コマンドで実行されます。

  • t.Logf(...): テスト中にログメッセージを出力するために使用されます。
  • t.Skipf(...) / t.Skip(...): テストをスキップするために使用されます。特定の条件(例:特定のOS、外部リソースへの依存)が満たされない場合にテストを実行しないようにするために便利です。
  • testing.Short(): go test -short フラグが指定された場合に true を返します。これにより、時間がかかるテストや外部リソースに依存するテストを、開発中の高速なテスト実行時にはスキップすることができます。
  • *testExternal: これは、Goのテストでよく見られるパターンで、外部リソース(ネットワーク、ファイルシステムなど)に依存するテストを制御するためのコマンドラインフラグです。通常、var testExternal = flag.Bool("external", false, "run tests that use external network") のように定義され、go test -external のように実行時に指定することで、外部依存テストを実行するかどうかを切り替えます。このフラグが false の場合、外部ネットワークテストは実行されません。

runtime.GOOS

runtime.GOOS は、Goプログラムが実行されているオペレーティングシステムの名前(例: "linux", "windows", "darwin", "plan9" など)を文字列で返す定数です。これにより、OSに依存するコードの分岐や、特定のOSでのみテストをスキップするなどの処理が可能になります。

技術的詳細

このコミットは、TestSimpleMulticastListener というテスト関数内で、runtime.GOOS の値に基づいて条件付きでテストをスキップするロジックを追加しています。

既存のコードでは、plan9 環境でテストをスキップする処理が既に存在していました。今回の変更では、これに加えて windows 環境でのスキップ条件が追加されました。

追加された windows 環境でのスキップ条件は以下の通りです。

	case "windows":
		if testing.Short() || !*testExternal {
			t.Logf("skipping test on windows to avoid firewall")
			return
		}

このコードブロックは、以下のいずれかの条件が満たされた場合に、Windows環境でのテストをスキップします。

  1. testing.Short()true の場合: go test -short コマンドでテストが実行された場合。これは、開発者が高速なテスト実行を望んでいる場合に、時間のかかる外部ネットワークテストを避けるための一般的なプラクティスです。
  2. !*testExternaltrue の場合: testExternal フラグが false に設定されている場合。これは、外部ネットワークへのアクセスを必要とするテストを実行しないように明示的に指定された場合です。デフォルトでは false に設定されていることが多いため、通常は外部ネットワークテストは実行されません。

このロジックにより、Windows環境では、特にファイアウォールがマルチキャスト通信をブロックする可能性があるため、デフォルトではこのテストが実行されないようになります。これにより、CI/CD環境でのテストの不安定性を軽減し、開発者のローカル環境でのテスト実行時の問題を回避することができます。

コミットメッセージにある「I don't know enough about multicast. Should this be disabled on all systems, not just Windows?」というコメントは、開発者がマルチキャストの挙動、特に異なるOS環境での挙動について完全な理解が不足していることを示唆しています。これは、マルチキャスト通信がOSのネットワークスタックやファイアウォール設定に強く依存するため、クロスプラットフォームでの安定したテストが難しいという現実を反映しています。

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

--- a/src/pkg/net/multicast_test.go
+++ b/src/pkg/net/multicast_test.go
@@ -90,6 +90,11 @@ func TestSimpleMulticastListener(t *testing.T) {
 	case "plan9":
 		t.Logf("skipping test on %q", runtime.GOOS)
 		return
+	case "windows":
+		if testing.Short() || !*testExternal {
+			t.Logf("skipping test on windows to avoid firewall")
+			return
+		}
 	}
 
 	for _, tt := range multicastListenerTests {

コアとなるコードの解説

変更は src/pkg/net/multicast_test.go ファイルの TestSimpleMulticastListener 関数内で行われています。

この関数は、runtime.GOOS の値に基づいて switch ステートメントを使用し、特定のオペレーティングシステムでのテストの挙動を制御しています。

元のコードには、plan9 というOSの場合にテストをスキップする case "plan9": ブロックが存在していました。

今回のコミットでは、新たに case "windows": ブロックが追加されました。このブロックの中では、以下の条件が評価されます。

  • testing.Short(): テストが「ショートモード」で実行されているかどうかをチェックします。ショートモードは、go test -short コマンドで有効になり、通常は時間がかかるテストや外部依存のテストをスキップするために使用されます。
  • !*testExternal: testExternal というブール型フラグの逆をチェックします。このフラグは、外部ネットワークへのアクセスを必要とするテストを実行するかどうかを制御するために使用されます。!*testExternaltrue の場合、外部ネットワークテストは実行されません。

これらの条件のいずれかが true であれば(|| は論理OR演算子)、t.Logf("skipping test on windows to avoid firewall") というログメッセージを出力し、return ステートメントによって現在のテスト関数を終了(スキップ)します。

この変更により、Windows環境では、特にファイアウォールによる通信ブロックの問題を回避するために、デフォルトでこのマルチキャストテストが実行されなくなります。これにより、テストの信頼性が向上し、CI/CDパイプラインの安定化に貢献します。

関連リンク

参考にした情報源リンク

  • Go言語の testing パッケージに関する公式ドキュメント
  • Go言語の runtime パッケージに関する公式ドキュメント
  • マルチキャスト通信に関する一般的なネットワーク知識
  • Go言語のテストにおける go test -short および外部テストフラグに関する慣習