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

[インデックス 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")
}

ここで testPollerflag.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 ファイルに対して行われています。

  1. var testPoller = flag.Bool(...) の削除: TestDialFailPDLeak テストの実行を制御していた testPoller というグローバル変数の定義が削除されました。これは、このテストが特定のコマンドラインフラグに依存するのではなく、Goの標準テストモードに統合されることを意味します。

  2. 条件分岐の変更: 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番号であるか、公開されていない内部的な参照である可能性があります。

参考にした情報源リンク