[インデックス 18275] ファイルの概要
このコミットは、Go言語のnet
パッケージにおけるTestDualStackTCPListener
テストが、go test -short
モードで実行された際にスキップされるように変更するものです。これは、特定の環境(特にLinuxサーバー)でこのテストが不安定(flaky)であり、CIビルドの失敗を引き起こしていた問題(Issue 5001)への暫定的な対応として導入されました。
コミット
commit 8bc32785b99eccf27cede237c974172988bb0c81
Author: Dave Cheney <dave@cheney.net>
Date: Fri Jan 17 09:49:38 2014 +1100
net: skip TestDualStackTCPListener in short mode
Update #5001
This test is flakey on linux servers and fails otherwise good builds. Mikio has some proposals to fix the test, but they require additional plumbing.
In the meantime, disable this test in -short mode so it will run during the full net test suite, but not during builder ci.
R=golang-codereviews, iant
CC=golang-codereviews
https://golang.org/cl/53410043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/8bc32785b99eccf27cede237c974172988bb0c81
元コミット内容
このコミット自体が、既存のテストの振る舞いを変更するものです。元のTestDualStackTCPListener
テストは、Goのネットワークパッケージがデュアルスタック(IPv4とIPv6の両方)のTCPリスナーを正しく処理できるかを検証するために設計されていました。このテストは、様々なアドレスファミリー、異なるリスニングアドレス、同じポートでの単一および二重のリスニングをテストすることを目的としていました。
変更の背景
変更の背景には、GoのIssue 5001が存在します。このIssueは、TestDualStackTCPListener
がLinuxサーバー上で不安定であり、本来問題のないビルドを失敗させてしまうという報告でした。テストの不安定さ(flakiness)は、CI/CDパイプラインにおいて大きな問題となります。CIシステムは、コードの変更が既存の機能に悪影響を与えないことを保証するためにテストを実行しますが、テスト自体が不安定であると、コードの品質とは無関係にビルドが失敗し、開発者の生産性を低下させます。
コミットメッセージによると、このテストの根本的な修正には「追加の配管(additional plumbing)」が必要であり、すぐに実装できるものではなかったようです。そのため、一時的な対策として、go test -short
モードでの実行時にこのテストをスキップする決定がなされました。これにより、開発者がローカルで迅速にテストを実行する際や、CIシステムがより高速な「ショート」テストスイートを実行する際に、この不安定なテストによる影響を回避できるようになります。完全なネットワークテストスイートでは引き続き実行されるため、問題の検出機会は残されます。
前提知識の解説
Goのテストフレームワークと testing.Short()
Go言語には、標準ライブラリとしてtesting
パッケージが提供されており、これを用いてユニットテストやベンチマークテストを記述します。テスト関数はTest
で始まる名前を持ち、*testing.T
型の引数を取ります。
testing.Short()
関数は、テストが「ショートモード」で実行されているかどうかを判断するために使用されます。ショートモードは、go test -short
コマンドを実行することで有効になります。このモードは、通常、時間がかかるテスト(例: ネットワークテスト、ファイルI/Oを伴うテスト、外部サービスに依存するテスト)をスキップするために使用されます。これにより、開発者は変更を迅速に検証でき、CIシステムもより高速なフィードバックを提供できます。
デュアルスタックTCPリスナー
デュアルスタックTCPリスナーとは、IPv4とIPv6の両方のアドレスからの接続を受け入れることができるTCPソケットのことです。現代のネットワーク環境では、IPv4とIPv6が混在していることが多いため、サーバーアプリケーションが両方のプロトコルに対応できることは重要です。Goのnet
パッケージは、このデュアルスタック機能を提供しており、ListenTCP
などの関数で適切なアドレスを指定することで、デュアルスタックリスナーを作成できます。
テストの不安定さ(Flakiness)
テストの不安定さ(flakiness)とは、コードが変更されていないにもかかわらず、テストが成功したり失敗したりする現象を指します。これは、テストが外部要因(ネットワークの遅延、OSのスケジューリング、リソースの競合、時間依存性など)に依存している場合に発生しやすいです。不安定なテストは、開発者の信頼を損ない、CI/CDパイプラインの効率を低下させるため、ソフトウェア開発において避けるべき問題とされています。
技術的詳細
このコミットの技術的な変更は、src/pkg/net/unicast_posix_test.go
ファイル内のTestDualStackTCPListener
関数に条件付きのスキップロジックを追加することに集約されます。
具体的には、TestDualStackTCPListener
関数の冒頭に以下のコードが追加されました。
if testing.Short() {
t.Skip("skipping in -short mode, see issue 5001")
}
このコードは、testing.Short()
がtrue
(つまり、go test -short
で実行されている)の場合に、t.Skip()
を呼び出してテストをスキップします。t.Skip()
が呼び出されると、そのテスト関数はそれ以上実行されず、テスト結果には「SKIP」と表示されます。これにより、不安定なテストがショートモードで実行されることを防ぎ、CIビルドの安定性を向上させます。
また、既存のif tt.wildcard && (testing.Short() || !*testExternal)
という条件式からtesting.Short()
の条件が削除されました。これは、TestDualStackTCPListener
全体がtesting.Short()
でスキップされるようになったため、内部の特定のテストケースで再度testing.Short()
をチェックする必要がなくなったためです。この変更により、コードの冗長性が排除され、意図がより明確になりました。
コアとなるコードの変更箇所
--- a/src/pkg/net/unicast_posix_test.go
+++ b/src/pkg/net/unicast_posix_test.go
@@ -166,9 +166,12 @@ var dualStackListenerTests = []struct {
}
// TestDualStackTCPListener tests both single and double listen
-// to a test listener with various address families, differnet
+// to a test listener with various address families, different
// listening address and same port.
func TestDualStackTCPListener(t *testing.T) {
+ if testing.Short() {
+ t.Skip("skipping in -short mode, see issue 5001")
+ }
switch runtime.GOOS {
case "plan9":
t.Skipf("skipping test on %q", runtime.GOOS)
@@ -178,7 +181,7 @@ func TestDualStackTCPListener(t *testing.T) {
}
for _, tt := range dualStackListenerTests {
- if tt.wildcard && (testing.Short() || !*testExternal) {
+ if tt.wildcard && !*testExternal {
continue
}
switch runtime.GOOS {
コアとなるコードの解説
-
func TestDualStackTCPListener(t *testing.T) {
: これは、Goのテスト関数であり、net
パッケージのデュアルスタックTCPリスナーの機能をテストします。t *testing.T
はテストの状態と結果を報告するためのオブジェクトです。 -
+ if testing.Short() {
: この行が追加された主要な変更点です。testing.Short()
関数は、現在のテスト実行がショートモード(go test -short
)である場合にtrue
を返します。 -
+ t.Skip("skipping in -short mode, see issue 5001")
:testing.Short()
がtrue
の場合、この行が実行されます。t.Skip()
は、現在のテストをスキップし、テストの実行を終了させます。引数として渡された文字列は、テスト結果にスキップ理由として表示されます。ここでは、Issue 5001への参照が含まれており、なぜこのテストがスキップされたのかを明確にしています。 -
- if tt.wildcard && (testing.Short() || !*testExternal) {
: この行は変更前のコードです。dualStackListenerTests
というテストケースのループ内で、特定の条件(tt.wildcard
が真かつtesting.Short()
が真、またはtestExternal
が偽)の場合にテストケースをスキップしていました。 -
+ if tt.wildcard && !*testExternal {
: この行は変更後のコードです。テスト関数全体の冒頭でtesting.Short()
によるスキップが導入されたため、個々のテストケース内で再度testing.Short()
をチェックする必要がなくなりました。これにより、コードが簡潔になり、意図がより明確になりました。testExternal
は、外部ネットワークへの接続を伴うテストを実行するかどうかを制御するフラグであると推測されます。
この変更により、TestDualStackTCPListener
は、開発者が迅速なテスト実行を求める場合や、CIシステムがショートテストスイートを実行する場合に、不安定な挙動を示すことなくスキップされるようになります。これにより、開発ワークフローの効率とCIの安定性が向上します。
関連リンク
- Go Issue 5001: https://github.com/golang/go/issues/5001
- Gerrit Change-Id:
I8bc32785b99eccf27cede237c974172988bb0c81
(これはコミットハッシュと同じですが、Gerritの変更IDとして参照されることがあります) - Go CL 53410043: https://golang.org/cl/53410043 (Gerritの変更リストへのリンク)
参考にした情報源リンク
- Go
testing
パッケージのドキュメント: https://pkg.go.dev/testing - Go
net
パッケージのドキュメント: https://pkg.go.dev/net - Goのテストに関する公式ブログ記事やドキュメント(一般的な情報源として)
- Goのデュアルスタックソケットに関する情報(一般的な情報源として)
- ソフトウェアテストにおけるFlakinessに関する一般的な情報源
- Go Issue 5001の議論内容 (Web検索で確認)