[インデックス 17384] ファイルの概要
このコミットは、Go言語の標準ライブラリ net
パッケージ内の TestDialFailPDLeak
テストの実行条件を変更するものです。具体的には、このテストが以前は特定のフラグ (-poller
) が有効な場合にのみ実行されていたのを、Goの標準的なテスト実行モードである「ショートモード」ではない場合に実行されるように修正しています。これにより、runtime.PollDesc
構造体のリークを検出する重要なテストが、より包括的な「ロングモード」のテストスイートで確実に実行されるようになります。
コミット
- コミットハッシュ:
33f3dffa7c3105b98e40c417df577683e341be87
- Author: Mikio Hara mikioh.mikioh@gmail.com
- Date: Sat Aug 24 22:05:14 2013 +0900
- コミットメッセージ:
net: allow TestDialFailPDLeak run in long-mode test R=golang-dev, dave CC=golang-dev https://golang.org/cl/12917050
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/33f3dffa7c3105b98e40c417df577683e341be87
元コミット内容
net: allow TestDialFailPDLeak run in long-mode test
このコミットは、net
パッケージ内の TestDialFailPDLeak
テストが、Goのテストフレームワークにおける「ロングモード」で実行されるように変更することを目的としています。
変更の背景
TestDialFailPDLeak
は、Goのネットワークダイアル処理が失敗した場合に、内部的な runtime.PollDesc
構造体がリークしないことを検証するための重要なテストです。runtime.PollDesc
はGoのネットワークI/Oの効率的な処理に不可欠な内部構造であり、そのリークはメモリ消費の増加やパフォーマンスの問題を引き起こす可能性があります。
このコミット以前は、TestDialFailPDLeak
テストは *testPoller
というフラグに依存していました。このフラグは、特定のプラットフォームがランタイム統合されたポーラーをサポートしているかどうかを示すもので、テストの実行を特定の環境に限定していました。しかし、このようなテストの実行条件は、テストスイート全体を網羅的に実行する際に、この重要なリークテストがスキップされてしまう可能性がありました。
開発者は、このテストがより広範なテスト実行、特に時間のかかる「ロングモード」のテストスイートで常に実行されることを望んでいました。これにより、runtime.PollDesc
のリークに関する回帰バグが早期に発見され、Goのネットワークスタックの堅牢性が向上します。
この変更の目的は、テストの実行条件を testing.Short()
に切り替えることで、テストの実行をより標準的なGoのテストメカニズムに統合し、TestDialFailPDLeak
がデフォルトでロングモードテストの一部として実行されるようにすることです。
前提知識の解説
runtime.PollDesc
runtime.PollDesc
は、Goランタイムの内部で非同期I/O操作を効率的に管理するために使用される重要なデータ構造です。GoのネットワークI/Oは、OSの提供する非同期I/Oメカニズム(Linuxのepoll
、macOS/BSDのkqueue
、WindowsのIOCP
など)を抽象化し、Goのゴルーチンが同期的なブロッキングI/Oのように振る舞えるようにします。この抽象化を実現するのが「ネットポーラー(netpoller)」と呼ばれるGoランタイムのサブシステムです。
runtime.PollDesc
は、特定のファイルディスクリプタ(ソケットなど)に関連付けられ、そのファイルディスクリプタ上でのI/Oイベント(読み込み可能、書き込み可能など)を監視するためにネットポーラーに登録されます。ゴルーチンがI/O操作でブロックされると、そのゴルーチンは一時的に中断され、PollDesc
がネットポーラーに登録されます。I/Oイベントが発生すると、ネットポーラーは対応するPollDesc
を介して中断されたゴルーチンを再開させます。
PollDesc
のリークは、I/O操作が完了しても関連するリソースが適切に解放されないことを意味し、時間の経過とともにメモリ使用量が増加し、最終的にはアプリケーションのパフォーマンス低下やクラッシュにつながる可能性があります。そのため、PollDesc
のリークがないことを検証するテストは非常に重要です。
Goのテストモード (testing.Short()
)
Goの標準テストパッケージ testing
には、testing.Short()
という関数が提供されています。これは、テストが「ショートモード」で実行されているかどうかを判定するために使用されます。
- ショートモード:
go test -short
コマンドでテストを実行すると、testing.Short()
はtrue
を返します。このモードは、開発者が迅速にテストを実行したい場合に利用され、時間のかかるテスト(例: ネットワークテスト、ファイルI/Oが多いテスト、大規模な計算を伴うテスト)をスキップするために使用されます。 - ロングモード:
go test
(フラグなし) またはgo test -run=...
などでテストを実行すると、testing.Short()
はfalse
を返します。このモードは、より包括的なテストを実行するために使用され、通常はCI/CDパイプラインやリリース前の最終検証などで利用されます。
テストコード内で if testing.Short() { t.Skip("skipping test in short mode") }
のように記述することで、ショートモードでのみ特定のテストをスキップし、ロングモードでは必ず実行されるように制御できます。
netpoller
Goの netpoller
は、Goランタイムが提供する非同期I/O多重化メカニズムです。これは、OSが提供するI/Oイベント通知API(epoll
, kqueue
, IOCP
)を利用して、多数のネットワーク接続を効率的に処理します。netpoller
は、ブロッキングI/O呼び出しを非ブロッキングI/Oに変換し、I/Oが準備できるまでゴルーチンをサスペンドし、準備ができたら再開させる役割を担います。これにより、Goアプリケーションは少数のOSスレッドで多数の同時接続を扱うことができ、高い並行性を実現します。runtime.PollDesc
はこの netpoller
の中核をなすデータ構造です。
技術的詳細
このコミットの技術的な変更は非常にシンプルですが、その影響は大きいです。
変更前は、TestDialFailPDLeak
テストの冒頭に以下の条件分岐がありました。
if !*testPoller {
t.Skip("test disabled; use -poller to enable")
}
ここで testPoller
は flag.Bool("poller", false, "platform supports runtime-integrated poller")
として定義されており、コマンドライン引数 -poller
が指定された場合にのみ true
となります。つまり、このテストはデフォルトではスキップされ、明示的に -poller
フラグを付けて go test
を実行した場合にのみ有効になるという挙動でした。これは、特定のプラットフォームでのみポーラーが利用可能であるという初期の設計判断に基づいていた可能性があります。
しかし、runtime.PollDesc
のリークチェックはプラットフォームに依存しない、Goのネットワークスタック全体の健全性に関わる重要な検証です。そのため、このテストが特定のフラグに依存してスキップされるのは望ましくありません。
変更後は、この条件分岐が以下のように修正されました。
if testing.Short() {
t.Skip("skipping test in short mode")
}
この変更により、テストの実行条件がGoの標準的なテストモードに統合されました。
go test -short
で実行された場合(ショートモード)、testing.Short()
はtrue
を返すため、テストはスキップされます。これは、ショートモードの目的(迅速なテスト実行)に合致します。go test
(フラグなし) やその他のロングモードで実行された場合、testing.Short()
はfalse
を返すため、テストはスキップされずに実行されます。
この修正により、TestDialFailPDLeak
はデフォルトでロングモードテストの一部として実行されるようになり、runtime.PollDesc
のリークに関する潜在的な問題をより確実に検出できるようになりました。これは、Goのネットワークライブラリの安定性と信頼性を高める上で重要な改善です。
コアとなるコードの変更箇所
--- a/src/pkg/net/dial_test.go
+++ b/src/pkg/net/dial_test.go
@@ -331,13 +331,11 @@ func numFD() int {
panic("numFDs not implemented on " + runtime.GOOS)
}
-var testPoller = flag.Bool("poller", false, "platform supports runtime-integrated poller")
-
// Assert that a failed Dial attempt does not leak
// runtime.PollDesc structures
func TestDialFailPDLeak(t *testing.T) {
-\tif !*testPoller {\n-\t\tt.Skip(\"test disabled; use -poller to enable\")\n+\tif testing.Short() {\n+\t\tt.Skip(\"skipping test in short mode\")\n \t}\n \n \tconst loops = 10
コアとなるコードの解説
このコミットは src/pkg/net/dial_test.go
ファイルに対して行われています。
-
var testPoller = flag.Bool(...)
の削除:TestDialFailPDLeak
テストの実行を制御していたtestPoller
というグローバル変数の定義が削除されました。これは、このテストが特定のコマンドラインフラグに依存するのではなく、Goの標準テストモードに統合されることを意味します。 -
条件分岐の変更:
TestDialFailPDLeak
関数の冒頭にあったテストスキップの条件が変更されました。- 変更前:
if !*testPoller { t.Skip("test disabled; use -poller to enable") }
これは、「testPoller
フラグがtrue
でない場合(つまり、-poller
が指定されていない場合)、テストをスキップし、『テストは無効です。有効にするには-poller
を使用してください』というメッセージを表示する」という意味でした。 - 変更後:
if testing.Short() { t.Skip("skipping test in short mode") }
これは、「テストがショートモードで実行されている場合(つまり、go test -short
が使用された場合)、テストをスキップし、『ショートモードではテストをスキップします』というメッセージを表示する」という意味です。
- 変更前:
この変更により、TestDialFailPDLeak
は、go test -short
が実行された場合にのみスキップされ、それ以外の通常の go test
実行(ロングモード)では必ず実行されるようになりました。これにより、runtime.PollDesc
のリークチェックがより広範なテストスイートで自動的に行われるようになり、Goのネットワークスタックの品質保証が強化されます。
関連リンク
- GoのChange List (CL)
https://golang.org/cl/12917050
は、ウェブ検索では詳細な情報が見つかりませんでした。これは、古いCL番号であるか、公開されていない内部的な参照である可能性があります。
参考にした情報源リンク
runtime.PollDesc
に関する情報: