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

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

このコミットは、Go言語の標準ライブラリであるnetパッケージ内のテストTestFirstFavoriteAddrが、単一のIPスタック(IPv4のみまたはIPv6のみ)を持つカーネル環境で失敗する問題を修正するものです。具体的には、テスト実行前にIPv4とIPv6の両方がサポートされているかを確認するスキップ条件を追加することで、テストの信頼性を向上させています。

コミット

  • コミットハッシュ: c576bcbad5e7671ae24d499d77a4b2371c4ab981
  • 作者: Mikio Hara mikioh.mikioh@gmail.com
  • コミット日時: 2013年9月2日 月曜日 16:44:51 +0900
  • コミットメッセージ: net: fix TestFirstFavoriteAddr failure on single IP stack kernel
  • 関連するIssue:
    • Update #3610
    • Update #5267
    • Update #5707
  • 変更ファイル: src/pkg/net/ipsock_test.go (1ファイル変更、4行追加)

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

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

元コミット内容

net: fix TestFirstFavoriteAddr failure on single IP stack kernel

Update #3610
Update #5267
Update #5707

R=golang-dev, bradfitz, dave
CC=golang-dev
https://golang.org/cl/13465043

変更の背景

このコミットは、Go言語のネットワークパッケージにおける特定のテストが、一部のシステム環境で予期せぬ失敗を引き起こす問題を解決するために導入されました。具体的には、TestFirstFavoriteAddrというテストが、IPv4またはIPv6のいずれか一方のIPスタックしかサポートしていないカーネル(オペレーティングシステム)上で実行された場合に失敗するという報告がありました。

関連するIssueは以下の通りです。

  • Issue #3610: "net: TestFirstFavoriteAddr fails on IPv6-only system" - IPv6のみのシステムでテストが失敗する問題。
  • Issue #5267: "net: TestFirstFavoriteAddr fails on IPv4-only system" - IPv4のみのシステムでテストが失敗する問題。
  • Issue #5707: "net: TestFirstFavoriteAddr fails on systems without IPv4 or IPv6" - IPv4またはIPv6のいずれもサポートしていないシステムでテストが失敗する問題(これは稀なケースですが、テストの堅牢性を高めるために考慮されました)。

これらの問題は、TestFirstFavoriteAddrがIPv4とIPv6の両方のネットワークアドレスを期待してテストケースを実行する設計になっていたため発生しました。しかし、すべての実行環境が両方のプロトコルをサポートしているわけではないため、テストが環境依存で不安定になるという課題がありました。このコミットは、テストが実行される環境のIPスタックサポート状況を適切に検出し、サポートされていない場合はテストをスキップすることで、この不安定性を解消することを目的としています。

前提知識の解説

IPスタック (IP Stack)

IPスタックとは、オペレーティングシステム(OS)が提供するネットワークプロトコル群の実装を指します。これには、IP (Internet Protocol) だけでなく、TCP (Transmission Control Protocol)、UDP (User Datagram Protocol) など、ネットワーク通信に必要な様々なプロトコルが含まれます。現代のOSは通常、IPv4とIPv6の両方をサポートするデュアルスタック構成ですが、古いシステムや特定の組み込みシステム、あるいは意図的に設定された環境では、IPv4のみ、またはIPv6のみのシングルスタック構成である場合があります。

  • IPv4 (Internet Protocol version 4): 現在広く普及しているIPアドレスのバージョンで、32ビットのアドレス空間を持ちます。例: 192.168.1.1
  • IPv6 (Internet Protocol version 6): IPv4のアドレス枯渇問題に対応するために開発された次世代のIPアドレスで、128ビットのアドレス空間を持ちます。例: 2001:0db8:85a3:0000:0000:8a2e:0370:7334

Go言語のnetパッケージ

Go言語の標準ライブラリであるnetパッケージは、ネットワークI/Oのプリミティブな機能を提供します。TCP/IP、UDP、IP、Unixドメインソケットなどのネットワークプロトコルを扱うためのインターフェースや関数が含まれています。このパッケージは、ネットワークアプリケーションを構築する上で非常に重要な役割を果たします。

firstFavoriteAddr関数

firstFavoriteAddrは、Goのnetパッケージ内部で使用される可能性のある関数で、与えられたIPアドレスのリストの中から、システムが「好む」最初のアドレス(例えば、IPv4が優先される環境ではIPv4アドレス、IPv6が優先される環境ではIPv6アドレス)を選択するロジックを持つと推測されます。この関数は、ネットワーク接続を確立する際に、利用可能な複数のIPアドレスの中から最適なものを選択するために利用されることがあります。

Go言語のテストフレームワークとt.Skip()

Go言語には、標準でテストフレームワークが組み込まれています。テストファイルは通常、テスト対象のファイルと同じディレクトリに_test.goというサフィックスを付けて配置されます。テスト関数はTestで始まり、*testing.T型の引数を取ります。

*testing.T型が提供するメソッドの一つにSkip()があります。これは、特定の条件が満たされない場合にテストの実行を中断し、そのテストをスキップ済みとしてマークするために使用されます。これにより、環境依存のテストや、まだ実装されていない機能のテストなどを、テストスイート全体の失敗とせずに扱うことができます。

supportsIPv4supportsIPv6

これらはGoのnetパッケージ内部で定義されている(またはそのテストコード内で利用される)ブール変数で、それぞれ現在のシステムがIPv4およびIPv6をサポートしているかどうかを示すフラグです。これらのフラグは、OSのネットワーク設定やカーネルの機能に基づいて動的に決定されます。

技術的詳細

TestFirstFavoriteAddrは、firstFavoriteAddr関数の動作を検証するためのテストです。この関数は、与えられたIPアドレスのリストとフィルタリング条件に基づいて、最適なIPアドレスを選択することを目的としています。テストケースには、IPv4とIPv6の両方のアドレスを含むシナリオが含まれていました。

問題は、テストが実行される環境が常にIPv4とIPv6の両方をサポートしているとは限らない点にありました。例えば、IPv4のみをサポートするシステムでは、テストケースに含まれるIPv6アドレスの処理が期待通りに行えず、テストが失敗していました。同様に、IPv6のみをサポートするシステムではIPv4アドレスの処理で問題が発生しました。

このコミットによる修正は、この環境依存のテスト失敗を根本的に解決します。具体的には、TestFirstFavoriteAddr関数の冒頭に以下の条件を追加しました。

if !supportsIPv4 || !supportsIPv6 {
    t.Skip("ipv4 or ipv6 is not supported")
}

このコードは、supportsIPv4またはsupportsIPv6のいずれかがfalse(つまり、IPv4またはIPv6のいずれかがサポートされていない)である場合に、t.Skip()を呼び出してテストをスキップします。これにより、TestFirstFavoriteAddrは、IPv4とIPv6の両方が完全に機能する環境でのみ実行されるようになり、単一IPスタックカーネル上での不必要なテスト失敗を防ぐことができます。

このアプローチは、テストの堅牢性を高めると同時に、GoのCI/CDパイプラインや開発者のローカル環境でのテスト実行において、誤った失敗報告を減らすことに貢献します。テストは、そのテストが意図する前提条件が満たされる環境でのみ実行されるべきであるという原則に基づいています。

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

変更はsrc/pkg/net/ipsock_test.goファイルに集中しています。

--- a/src/pkg/net/ipsock_test.go
+++ b/src/pkg/net/ipsock_test.go
@@ -177,6 +177,10 @@ var firstFavoriteAddrTests = []struct {
 }
 
 func TestFirstFavoriteAddr(t *testing.T) {
+	if !supportsIPv4 || !supportsIPv6 {
+		t.Skip("ipv4 or ipv6 is not supported")
+	}
+
 	for i, tt := range firstFavoriteAddrTests {
 		addr, err := firstFavoriteAddr(tt.filter, tt.ips, tt.inetaddr)
 		if err != tt.err {

具体的には、TestFirstFavoriteAddr関数の定義直後に4行が追加されています。

コアとなるコードの解説

追加されたコードは以下の通りです。

if !supportsIPv4 || !supportsIPv6 {
	t.Skip("ipv4 or ipv6 is not supported")
}
  • !supportsIPv4: これは、現在のシステムがIPv4をサポートしていない場合にtrueとなります。
  • !supportsIPv6: これは、現在のシステムがIPv6をサポートしていない場合にtrueとなります。
  • || (論理OR演算子): !supportsIPv4または!supportsIPv6のいずれか一方がtrueであれば、条件式全体がtrueとなります。つまり、IPv4とIPv6のどちらか一方でもサポートされていない場合に、ifブロック内のコードが実行されます。
  • t.Skip("ipv4 or ipv6 is not supported"): if条件がtrueの場合、この行が実行されます。t.Skip()は、現在のテストをスキップし、指定された文字列(この場合は"ipv4 or ipv6 is not supported")をスキップ理由として出力します。これにより、テストスイートは続行されますが、この特定のテストは失敗とはみなされず、スキップされたものとして報告されます。

この変更により、TestFirstFavoriteAddrは、IPv4とIPv6の両方が利用可能な環境でのみ実行されることが保証されます。これにより、テストの信頼性が向上し、特定のネットワーク構成を持つシステムでの誤ったテスト失敗が解消されます。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント (netパッケージ、testingパッケージ)
  • GitHubのGoリポジトリのIssueトラッカー
  • Go Code Reviewのアーカイブ# [インデックス 17459] ファイルの概要

このコミットは、Go言語の標準ライブラリであるnetパッケージ内のテストTestFirstFavoriteAddrが、単一のIPスタック(IPv4のみまたはIPv6のみ)を持つカーネル環境で失敗する問題を修正するものです。具体的には、テスト実行前にIPv4とIPv6の両方がサポートされているかを確認するスキップ条件を追加することで、テストの信頼性を向上させています。

コミット

  • コミットハッシュ: c576bcbad5e7671ae24d499d77a4b2371c4ab981
  • 作者: Mikio Hara mikioh.mikioh@gmail.com
  • コミット日時: 2013年9月2日 月曜日 16:44:51 +0900
  • コミットメッセージ: net: fix TestFirstFavoriteAddr failure on single IP stack kernel
  • 関連するIssue:
    • Update #3610
    • Update #5267
    • Update #5707
  • 変更ファイル: src/pkg/net/ipsock_test.go (1ファイル変更、4行追加)

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

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

元コミット内容

net: fix TestFirstFavoriteAddr failure on single IP stack kernel

Update #3610
Update #5267
Update #5707

R=golang-dev, bradfitz, dave
CC=golang-dev
https://golang.org/cl/13465043

変更の背景

このコミットは、Go言語のネットワークパッケージにおける特定のテストが、一部のシステム環境で予期せぬ失敗を引き起こす問題を解決するために導入されました。具体的には、TestFirstFavoriteAddrというテストが、IPv4またはIPv6のいずれか一方のIPスタックしかサポートしていないカーネル(オペレーティングシステム)上で実行された場合に失敗するという報告がありました。

関連するIssueは以下の通りです。

  • Issue #3610: "net: TestFirstFavoriteAddr fails on IPv6-only system" - IPv6のみのシステムでテストが失敗する問題。
  • Issue #5267: "net: TestFirstFavoriteAddr fails on IPv4-only system" - IPv4のみのシステムでテストが失敗する問題。
  • Issue #5707: "net: TestFirstFavoriteAddr fails on systems without IPv4 or IPv6" - IPv4またはIPv6のいずれもサポートしていないシステムでテストが失敗する問題(これは稀なケースですが、テストの堅牢性を高めるために考慮されました)。

これらの問題は、TestFirstFavoriteAddrがIPv4とIPv6の両方のネットワークアドレスを期待してテストケースを実行する設計になっていたため発生しました。しかし、すべての実行環境が両方のプロトコルをサポートしているわけではないため、テストが環境依存で不安定になるという課題がありました。このコミットは、テストが実行される環境のIPスタックサポート状況を適切に検出し、サポートされていない場合はテストをスキップすることで、この不安定性を解消することを目的としています。

前提知識の解説

IPスタック (IP Stack)

IPスタックとは、オペレーティングシステム(OS)が提供するネットワークプロトコル群の実装を指します。これには、IP (Internet Protocol) だけでなく、TCP (Transmission Control Protocol)、UDP (User Datagram Protocol) など、ネットワーク通信に必要な様々なプロトコルが含まれます。現代のOSは通常、IPv4とIPv6の両方をサポートするデュアルスタック構成ですが、古いシステムや特定の組み込みシステム、あるいは意図的に設定された環境では、IPv4のみ、またはIPv6のみのシングルスタック構成である場合があります。

  • IPv4 (Internet Protocol version 4): 現在広く普及しているIPアドレスのバージョンで、32ビットのアドレス空間を持ちます。例: 192.168.1.1
  • IPv6 (Internet Protocol version 6): IPv4のアドレス枯渇問題に対応するために開発された次世代のIPアドレスで、128ビットのアドレス空間を持ちます。例: 2001:0db8:85a3:0000:0000:8a2e:0370:7334

Go言語のnetパッケージ

Go言語の標準ライブラリであるnetパッケージは、ネットワークI/Oのプリミティブな機能を提供します。TCP/IP、UDP、IP、Unixドメインソケットなどのネットワークプロトコルを扱うためのインターフェースや関数が含まれています。このパッケージは、ネットワークアプリケーションを構築する上で非常に重要な役割を果たします。

firstFavoriteAddr関数

firstFavoriteAddrは、Goのnetパッケージ内部で使用される可能性のある関数で、与えられたIPアドレスのリストの中から、システムが「好む」最初のアドレス(例えば、IPv4が優先される環境ではIPv4アドレス、IPv6が優先される環境ではIPv6アドレス)を選択するロジックを持つと推測されます。この関数は、ネットワーク接続を確立する際に、利用可能な複数のIPアドレスの中から最適なものを選択するために利用されることがあります。

Go言語のテストフレームワークとt.Skip()

Go言語には、標準でテストフレームワークが組み込まれています。テストファイルは通常、テスト対象のファイルと同じディレクトリに_test.goというサフィックスを付けて配置されます。テスト関数はTestで始まり、*testing.T型の引数を取ります。

*testing.T型が提供するメソッドの一つにSkip()があります。これは、特定の条件が満たされない場合にテストの実行を中断し、そのテストをスキップ済みとしてマークするために使用されます。これにより、環境依存のテストや、まだ実装されていない機能のテストなどを、テストスイート全体の失敗とせずに扱うことができます。

supportsIPv4supportsIPv6

これらはGoのnetパッケージ内部で定義されている(またはそのテストコード内で利用される)ブール変数で、それぞれ現在のシステムがIPv4およびIPv6をサポートしているかどうかを示すフラグです。これらのフラグは、OSのネットワーク設定やカーネルの機能に基づいて動的に決定されます。

技術的詳細

TestFirstFavoriteAddrは、firstFavoriteAddr関数の動作を検証するためのテストです。この関数は、与えられたIPアドレスのリストとフィルタリング条件に基づいて、最適なIPアドレスを選択することを目的としています。テストケースには、IPv4とIPv6の両方のアドレスを含むシナリオが含まれていました。

問題は、テストが実行される環境が常にIPv4とIPv6の両方をサポートしているとは限らない点にありました。例えば、IPv4のみをサポートするシステムでは、テストケースに含まれるIPv6アドレスの処理が期待通りに行えず、テストが失敗していました。同様に、IPv6のみをサポートするシステムではIPv4アドレスの処理で問題が発生しました。

このコミットによる修正は、この環境依存のテスト失敗を根本的に解決します。具体的には、TestFirstFavoriteAddr関数の冒頭に以下の条件を追加しました。

if !supportsIPv4 || !supportsIPv6 {
    t.Skip("ipv4 or ipv6 is not supported")
}

このコードは、supportsIPv4またはsupportsIPv6のいずれかがfalse(つまり、IPv4またはIPv6のいずれかがサポートされていない)である場合に、t.Skip()を呼び出してテストをスキップします。これにより、TestFirstFavoriteAddrは、IPv4とIPv6の両方が完全に機能する環境でのみ実行されるようになり、単一IPスタックカーネル上での不必要なテスト失敗を防ぐことができます。

このアプローチは、テストの堅牢性を高めると同時に、GoのCI/CDパイプラインや開発者のローカル環境でのテスト実行において、誤った失敗報告を減らすことに貢献します。テストは、そのテストが意図する前提条件が満たされる環境でのみ実行されるべきであるという原則に基づいています。

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

変更はsrc/pkg/net/ipsock_test.goファイルに集中しています。

--- a/src/pkg/net/ipsock_test.go
+++ b/src/pkg/net/ipsock_test.go
@@ -177,6 +177,10 @@ var firstFavoriteAddrTests = []struct {
 }
 
 func TestFirstFavoriteAddr(t *testing.T) {
+	if !supportsIPv4 || !supportsIPv6 {
+		t.Skip("ipv4 or ipv6 is not supported")
+	}
+
 	for i, tt := range firstFavoriteAddrTests {
 		addr, err := firstFavoriteAddr(tt.filter, tt.ips, tt.inetaddr)
 		if err != tt.err {

具体的には、TestFirstFavoriteAddr関数の定義直後に4行が追加されています。

コアとなるコードの解説

追加されたコードは以下の通りです。

if !supportsIPv4 || !supportsIPv6 {
	t.Skip("ipv4 or ipv6 is not supported")
}
  • !supportsIPv4: これは、現在のシステムがIPv4をサポートしていない場合にtrueとなります。
  • !supportsIPv6: これは、現在のシステムがIPv6をサポートしていない場合にtrueとなります。
  • || (論理OR演算子): !supportsIPv4または!supportsIPv6のいずれか一方がtrueであれば、条件式全体がtrueとなります。つまり、IPv4とIPv6のどちらか一方でもサポートされていない場合に、ifブロック内のコードが実行されます。
  • t.Skip("ipv4 or ipv6 is not supported"): if条件がtrueの場合、この行が実行されます。t.Skip()は、現在のテストをスキップし、指定された文字列(この場合は"ipv4 or ipv6 is not supported")をスキップ理由として出力します。これにより、テストスイートは続行されますが、この特定のテストは失敗とはみなされず、スキップされたものとして報告されます。

この変更により、TestFirstFavoriteAddrは、IPv4とIPv6の両方が利用可能な環境でのみ実行されることが保証されます。これにより、テストの信頼性が向上し、特定のネットワーク構成を持つシステムでの誤ったテスト失敗が解消されます。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント (netパッケージ、testingパッケージ)
  • GitHubのGoリポジトリのIssueトラッカー
  • Go Code Reviewのアーカイブ