[インデックス 18516] ファイルの概要
このコミットは、Go言語の標準ライブラリnetパッケージ内のTestDNSThreadLimitというテストの挙動を変更するものです。具体的には、このテストがデフォルトで実行されないようにし、明示的なフラグ(-dnsflood)を指定した場合にのみ実行されるように修正しています。これにより、テストが引き起こす可能性のあるネットワークへの負荷や仮想環境での問題を防ぐことが目的です。
コミット
commit 2277e8d3c9c3f14aa9536f4aaeea6bfa6c316f3f
Author: Mikio Hara <mikioh.mikioh@gmail.com>
Date: Fri Feb 14 12:20:21 2014 +0900
net: disable TestDNSThreadLimit even in non-short mode by default
TestDNSThreadLimit creates tons of DNS queries and it occasionally
causes an unintentional traffic jam and/or crash of some virtual
machine software, especially its builtin networking stuff.
We can run TestDNSThreadLimit with -dnsflood flag instead.
LGTM=dave, rsc
R=rsc, dave
CC=golang-codereviews
https://golang.org/cl/63600043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/2277e8d3c9c3f14aa9536f4aaeea6bfa6c316f3f
元コミット内容
net: disable TestDNSThreadLimit even in non-short mode by default
TestDNSThreadLimitは大量のDNSクエリを生成するため、意図しないトラフィックジャムや、特に仮想マシンの内蔵ネットワーキング機能のクラッシュを引き起こすことがあります。
代わりに、-dnsfloodフラグを使ってTestDNSThreadLimitを実行できます。
変更の背景
TestDNSThreadLimitは、Goのnetパッケージが同時に処理できるDNSクエリのスレッド数やリミットをテストするために設計されたものです。このテストは、その性質上、短時間で非常に大量のDNSクエリを生成します。
コミットメッセージに明記されているように、この大量のDNSクエリの生成は、以下のような問題を引き起こす可能性がありました。
- 意図しないトラフィックジャム (unintentional traffic jam): テストが実行される環境のネットワーク帯域を一時的に飽和させたり、DNSサーバーに過度な負荷をかけたりする可能性があります。これは、共有ネットワーク環境や、テスト環境が本番環境と同一のDNSリゾルバを使用している場合に特に問題となります。
- 仮想マシンソフトウェアのクラッシュ (crash of some virtual machine software): 特に仮想化ソフトウェアに内蔵されているネットワーク機能が、短期間に集中する大量のDNSクエリ処理に耐えきれず、不安定になったりクラッシュしたりするケースがあったようです。これは、開発者がローカルの仮想環境でテストを実行する際に、予期せぬ問題に直面する原因となっていました。
これらの問題を回避し、開発者やCI/CD環境でのテスト実行の安定性を向上させるため、このテストをデフォルトで無効化し、必要に応じて明示的に有効化するメカニズムが導入されました。
前提知識の解説
1. DNS (Domain Name System)
DNSは、インターネット上のドメイン名(例: www.example.com)をIPアドレス(例: 192.0.2.1)に変換するための分散型データベースシステムです。ユーザーがウェブサイトにアクセスしたり、アプリケーションがリモートサービスと通信したりする際、まずDNSクエリを発行してドメイン名に対応するIPアドレスを解決します。TestDNSThreadLimitは、このDNSクエリを大量に発行することで、システムが同時に処理できるDNS解決の能力を試すテストです。
2. Go言語のtestingパッケージ
Go言語には、ユニットテストやベンチマークテストを記述するための標準パッケージtestingが用意されています。
func TestXxx(t *testing.T): テスト関数はTestで始まり、*testing.T型の引数を取ります。t.Skip(args ...interface{}): このメソッドが呼び出されると、現在のテストはスキップされます。テストが特定の条件を満たさない場合(例: 外部ネットワーク接続が必要なテストでネットワークがない場合、またはリソースを大量に消費するテストを通常実行したくない場合)に利用されます。testing.Short(): この関数は、go test -shortフラグが指定された場合にtrueを返します。通常、時間がかかるテストや外部リソースに依存するテストを、go test -short実行時にはスキップするために使用されます。これにより、開発中の迅速なテスト実行が可能になります。
3. Go言語のflagパッケージ
Go言語のflagパッケージは、コマンドライン引数を解析するための機能を提供します。
flag.Bool(name string, value bool, usage string) *bool: ブール型のコマンドラインフラグを定義します。nameはフラグ名(例:dnsflood)、valueはデフォルト値、usageはフラグの説明です。この関数は、フラグの値へのポインタを返します。flag.Parse(): コマンドライン引数を解析し、定義されたフラグに値を割り当てます。通常、main関数の冒頭で呼び出されます。
このコミットでは、flagパッケージを使用して新しいコマンドラインフラグ-dnsfloodを導入し、このフラグが指定された場合にのみTestDNSThreadLimitが実行されるように制御しています。
技術的詳細
このコミットの技術的な変更点は、src/pkg/net/z_last_test.goファイル内のTestDNSThreadLimit関数の冒頭にある条件分岐のロジックを変更したことです。
変更前は、以下の条件でテストがスキップされていました。
if testing.Short() || !*testExternal {
t.Skip("skipping test to avoid external network")
}
これは、「go test -shortが指定された場合」または「testExternalフラグがfalseの場合(つまり外部ネットワークへのアクセスを許可しない場合)」にテストをスキップするという意味です。TestDNSThreadLimitは大量のDNSクエリを生成するため、外部ネットワークへのアクセスが必須であり、また時間がかかるテストであるため、testing.Short()によるスキップは理にかなっていました。
しかし、このコミットでは、TestDNSThreadLimitが引き起こす可能性のある問題(トラフィックジャム、VMクラッシュ)が、testing.Short()モードではない通常実行時にも発生しうることが認識されました。そこで、より明示的な制御が必要と判断されました。
変更後、以下のようになりました。
var testDNSFlood = flag.Bool("dnsflood", false, "whether to test dns query flooding")
func TestDNSThreadLimit(t *testing.T) {
if !*testDNSFlood {
t.Skip("test disabled; use -dnsflood to enable")
}
// ... 既存のテストロジック ...
}
この変更により、以下の点が実現されました。
- 新しいフラグの導入:
flag.Bool("dnsflood", false, ...)によって、testDNSFloodという新しいブール型フラグが導入されました。このフラグのデフォルト値はfalseです。 - デフォルトでのテスト無効化:
if !*testDNSFloodという条件により、-dnsfloodフラグがコマンドラインで指定されない限り(つまりtestDNSFloodがfalseのままの場合)、TestDNSThreadLimitは常にスキップされるようになりました。 - 明示的な有効化: ユーザーがこのテストを実行したい場合は、
go test -dnsfloodのようにコマンドラインで明示的にフラグを指定する必要があります。これにより、テストが引き起こす可能性のある影響を理解した上で、意図的に実行することが求められるようになりました。 testing.Short()からの独立:testing.Short()によるスキップ条件は削除され、TestDNSThreadLimitの実行は完全に-dnsfloodフラグによって制御されるようになりました。これにより、go testの通常実行時でも、この負荷の高いテストが意図せず実行されることがなくなりました。
この変更は、テストの実行環境への影響を最小限に抑えつつ、必要に応じて特定のテストを実行できる柔軟性を提供する、Goのテストフレームワークにおける一般的なプラクティスを反映しています。
コアとなるコードの変更箇所
--- a/src/pkg/net/z_last_test.go
+++ b/src/pkg/net/z_last_test.go
@@ -5,13 +5,16 @@
package net
import (
+ "flag"
"fmt"
"testing"
)
+var testDNSFlood = flag.Bool("dnsflood", false, "whether to test dns query flooding")
+
func TestDNSThreadLimit(t *testing.T) {
- if testing.Short() || !*testExternal {
- t.Skip("skipping test to avoid external network")
+ if !*testDNSFlood {
+ t.Skip("test disabled; use -dnsflood to enable")
}
const N = 10000
コアとなるコードの解説
-
import "flag"の追加:flagパッケージを使用するために、インポートリストに"flag"が追加されました。 -
var testDNSFlood = flag.Bool("dnsflood", false, "whether to test dns query flooding")の追加: これは、新しいコマンドラインフラグdnsfloodを定義しています。"dnsflood": フラグの名前です。コマンドラインで-dnsfloodとして使用されます。false: このフラグのデフォルト値です。つまり、-dnsfloodが指定されない限り、testDNSFlood変数の値はfalseになります。"whether to test dns query flooding": このフラグの用途を説明するヘルプメッセージです。
-
TestDNSThreadLimit関数の条件分岐の変更:- 変更前:
この行は、if testing.Short() || !*testExternal { t.Skip("skipping test to avoid external network") }go test -shortが指定された場合、またはtestExternalフラグがfalse(外部ネットワークへのアクセスが許可されていない)の場合にテストをスキップしていました。 - 変更後:
この行は、if !*testDNSFlood { t.Skip("test disabled; use -dnsflood to enable") }testDNSFloodフラグがfalseの場合(つまり、コマンドラインで-dnsfloodが指定されていない場合)にテストをスキップするように変更されました。スキップメッセージも「テストは無効化されています。有効にするには-dnsfloodを使用してください」と、より具体的に変更されています。
- 変更前:
この変更により、TestDNSThreadLimitはデフォルトでは実行されなくなり、開発者やCIシステムが意図的に-dnsfloodフラグを指定した場合にのみ実行されるようになりました。これにより、テストが引き起こす可能性のあるネットワーク負荷や仮想環境の問題を回避し、テスト実行の安定性が向上します。
関連リンク
- Go言語の
testingパッケージドキュメント: https://pkg.go.dev/testing - Go言語の
flagパッケージドキュメント: https://pkg.go.dev/flag - このコミットのGo CL (Code Review) ページ: https://golang.org/cl/63600043
参考にした情報源リンク
- GitHubのコミットページ: https://github.com/golang/go/commit/2277e8d3c9c3f14aa9536f4aaeea6bfa6c316f3f
- Go言語の公式ドキュメント (testing, flagパッケージ): https://go.dev/pkg/
- DNSの基本概念に関する一般的な情報源 (例: Wikipedia, MDN Web Docsなど)