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

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

このコミットは、Go言語のネットワークパッケージ(netパッケージ)におけるIPv6関連のテストをWindows環境で有効化し、同時にGo 1.0時代の非IPv6対応WindowsコードがIPv6有効なWindowsカーネル上で実行されることによって発生していた冗長なテストを削除することを目的としています。これにより、Windows環境でのIPv6ネットワーク機能のテストカバレッジが向上し、テストスイートの効率化が図られています。

コミット

0f9b3059bc969053b68cf135c4c8266da53a6405

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

https://github.com/golang/go/commit/0f9b3059bc969053b68cf135c4c8266da53a6405

元コミット内容

net: enable IPv6 tests on Windows

Also removes redundant tests that run Go 1.0 non-IPv6 support
Windows code on IPv6 enabled Windows kernels.

R=alex.brainman, golang-dev, bradfitz, dave
CC=golang-dev
https://golang.org/cl/7812052

変更の背景

Go言語の初期バージョン(特にGo 1.0)では、Windows環境におけるIPv6のサポートが限定的でした。そのため、ネットワーク関連のテストコードには、Windows環境ではIPv6テストをスキップする、あるいは特定のIPv6非対応の挙動を前提としたテストが含まれていました。

しかし、Windowsカーネル自体がIPv6をサポートし、Go言語のネットワークスタックも進化するにつれて、これらのテストの前提が古くなり、冗長または不適切になってきました。具体的には、IPv6が有効なWindows環境で、Go 1.0時代の非IPv6対応コードをテストするようなケースが挙げられます。このようなテストは、現在の環境では意味をなさず、テストスイートの実行時間や複雑性を増すだけでした。

このコミットは、Windows環境でのIPv6サポートが成熟したことを受け、テストスイートを現代の環境に合わせて更新し、Windows上でのIPv6ネットワーク機能の正確な動作を検証できるようにすることを目的としています。同時に、もはや必要のない古いテストロジックを削除することで、テストコードの保守性を向上させています。

前提知識の解説

IPv6 (Internet Protocol Version 6)

IPv6は、インターネットプロトコルの最新バージョンであり、IPv4の後継です。IPv4のアドレス空間が枯渇しつつある問題に対処するため、IPv6は128ビットのアドレスを使用し、膨大な数のユニークなIPアドレスを提供します。これにより、より多くのデバイスがインターネットに接続できるようになります。また、IPv6は、アドレス自動設定、IPsec(セキュリティ機能)の組み込み、ルーティングの効率化など、IPv4にはない多くの改善点を持っています。

Go言語の net パッケージ

Go言語の標準ライブラリには、ネットワークI/O機能を提供するnetパッケージが含まれています。このパッケージは、TCP/IP、UDP/IP、Unixドメインソケットなどのネットワークプロトコルを扱うためのAPIを提供します。netパッケージは、低レベルのネットワーク操作から、高レベルのリスナーやダイヤラーの機能まで、幅広いネットワークプログラミングをサポートしています。

runtime.GOOS

runtime.GOOSは、Go言語の標準ライブラリruntimeパッケージで提供される定数で、プログラムが実行されているオペレーティングシステム(OS)の名前を表す文字列です。例えば、Windowsでは"windows"、Linuxでは"linux"、macOSでは"darwin"となります。この定数は、OS固有の処理を条件分岐させる際によく使用されます。

Go言語の testing パッケージと t.Skipf

Go言語には、ユニットテストを記述するための標準ライブラリtestingパッケージがあります。テスト関数はTestで始まる名前を持ち、*testing.T型の引数を取ります。

t.Skipf(format string, args ...interface{})は、*testing.T型のメソッドの一つで、テストの実行をスキップするために使用されます。このメソッドが呼び出されると、現在のテストは「スキップされた」としてマークされ、それ以降のテストコードは実行されません。formatargsは、スキップ理由を説明するメッセージをフォーマットするために使用されます。

このコミットでは、特定のOS(runtime.GOOS)でテストをスキップする条件から"windows"を削除することで、Windows上でのIPv6テストの実行を可能にしています。

冗長なテストの削除

ソフトウェア開発において、テストはコードの品質を保証するために不可欠です。しかし、時間の経過とともに、コードベースや実行環境が変化すると、一部のテストが冗長になったり、不適切になったりすることがあります。

このコミットで言及されている「冗長なテスト」とは、Go 1.0時代のWindowsにおけるIPv6非対応の挙動を前提としたテストを指します。当時のWindows環境ではIPv6が十分にサポートされていなかったため、特定のテストがスキップされたり、特定の非IPv6動作を期待するロジックが含まれていました。しかし、WindowsカーネルがIPv6を完全にサポートし、GoのネットワークスタックもIPv6に対応した現在では、これらのテストはもはや意味をなさず、むしろ誤解を招く可能性がありました。そのため、これらの冗長なテストを削除することで、テストスイートの関連性と効率性を高めています。

技術的詳細

このコミットの技術的な変更は、主にGo言語のテストコードにおけるOSごとの条件分岐の修正と、不要になったテスト関数の削除に集約されます。

  1. multicast_test.go におけるIPv6マルチキャストテストのWindowsでの有効化:

    • TestIPv6MulticastListener 関数内で、runtime.GOOS"plan9", "solaris", "windows"の場合にテストをスキップするswitch文がありました。
    • このコミットでは、"windows"がこのスキップ条件から削除されました。
    • これにより、Windows環境でもTestIPv6MulticastListenerが実行されるようになり、Windows上でのIPv6マルチキャストリスナー機能のテストが可能になりました。
  2. unicast_posix_test.go におけるTCP/UDPリスナーテストのWindowsでの有効化と冗長テストの削除:

    • TestTCPListener 関数内で、runtime.GOOS"plan9", "windows"の場合にテストをスキップするswitch文がありました。
    • このコミットでは、"windows"がこのスキップ条件から削除されました。これにより、Windows環境でもTCPリスナーのテストが実行されるようになります。
    • TestUDPListener 関数全体が削除されました。この関数は、listenerTestsという共通のテストデータ構造を使用してUDPリスナーのテストを行っていましたが、Go 1.0時代のWindowsにおけるIPv6非対応の挙動を前提とした冗長なテストロジックが含まれていたため、削除されました。
    • TestSimpleTCPListener 関数全体が削除されました。これも同様に、Go 1.0時代のWindowsにおけるIPv6非対応の挙動を前提とした冗長なテストロジックが含まれていました。
    • TestSimpleUDPListener 関数は残されましたが、その内部のswitch runtime.GOOS文から"windows"が削除されました。これにより、Windows環境でもシンプルなUDPリスナーのテストが実行されるようになります。また、この関数内のIPv6サポートチェックif tt.ipv6if tt.ipv6 && !supportsIPv6に変更され、IPv6がサポートされていない場合にのみスキップするよう、より正確な条件になりました。
    • TestDualStackTCPListener および TestDualStackUDPListener 関数内で、!supportsIPv6の場合にreturnしていた箇所がt.Skip("ipv6 is not supported")に変更されました。これは機能的な変更ではなく、テストがスキップされたことをより明確に報告するための改善です。

これらの変更により、Goのネットワークパッケージのテストスイートは、Windows環境におけるIPv6の実際のサポート状況をより正確に反映するようになり、不要なテストが排除され、テストの効率性と関連性が向上しました。

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

src/pkg/net/multicast_test.go

--- a/src/pkg/net/multicast_test.go
+++ b/src/pkg/net/multicast_test.go
@@ -93,7 +93,7 @@ var ipv6MulticastListenerTests = []struct {
 // port.
 func TestIPv6MulticastListener(t *testing.T) {
 	switch runtime.GOOS {
-	case "plan9", "solaris", "windows":
+	case "plan9", "solaris":
 		t.Skipf("skipping test on %q", runtime.GOOS)
 	}
 	if !supportsIPv6 {

src/pkg/net/unicast_posix_test.go

--- a/src/pkg/net/unicast_posix_test.go
+++ b/src/pkg/net/unicast_posix_test.go
@@ -45,7 +45,7 @@ var listenerTests = []struct {
 // same port.
 func TestTCPListener(t *testing.T) {
 	switch runtime.GOOS {
-	case "plan9", "windows":
+	case "plan9":
 		t.Skipf("skipping test on %q", runtime.GOOS)
 	}
 
@@ -68,66 +68,9 @@ func TestTCPListener(t *testing.T) {
 // listener with same address family, same listening address and
 // same port.
 func TestUDPListener(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9", "windows":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-
-	toudpnet := func(net string) string {
-		switch net {
-		case "tcp":
-			return "udp"
-		case "tcp4":
-			return "udp4"
-		case "tcp6":
-			return "udp6"
-		}
-		return "<nil>"
-	}
-
-	for _, tt := range listenerTests {
-		if tt.wildcard && (testing.Short() || !*testExternal) {
-			continue
-		}
-		if tt.ipv6 && !supportsIPv6 {
-			continue
-		}
-		tt.net = toudpnet(tt.net)
-		l1, port := usableListenPacketPort(t, tt.net, tt.laddr)
-		checkFirstListener(t, tt.net, tt.laddr+":"+port, l1)
-		l2, err := ListenPacket(tt.net, tt.laddr+":"+port)
-		checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2)
-		l1.Close()
-	}
-}
-
-func TestSimpleTCPListener(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-		return
-	}
-
-	for _, tt := range listenerTests {
-		if tt.wildcard && (testing.Short() || !*testExternal) {
-			continue
-		}
-		if tt.ipv6 {
-			continue
-		}
-		l1, port := usableListenPort(t, tt.net, tt.laddr)
-		checkFirstListener(t, tt.net, tt.laddr+":"+port, l1)
-		l2, err := Listen(tt.net, tt.laddr+":"+port)
-		checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2)
-		l1.Close()
-	}
-}
-
-func TestSimpleUDPListener(t *testing.T) {
 	switch runtime.GOOS {
 	case "plan9":
 		t.Skipf("skipping test on %q", runtime.GOOS)
-		return
 	}
 
 	toudpnet := func(net string) string {
@@ -146,7 +89,7 @@ func TestSimpleUDPListener(t *testing.T) {
 	\tif tt.wildcard && (testing.Short() || !*testExternal) {\n \t\t\tcontinue\n \t\t}\n-\t\tif tt.ipv6 {\n+\t\tif tt.ipv6 && !supportsIPv6 {\n \t\t\tcontinue\n \t\t}\n \t\ttt.net = toudpnet(tt.net)\n@@ -231,7 +174,7 @@ func TestDualStackTCPListener(t *testing.T) {\n \t\tt.Skipf(\"skipping test on %q\", runtime.GOOS)\n \t}\n \tif !supportsIPv6 {\n-\t\treturn\n+\t\tt.Skip(\"ipv6 is not supported\")\n \t}\n \n \tfor _, tt := range dualStackListenerTests {\n@@ -263,7 +206,7 @@ func TestDualStackUDPListener(t *testing.T) {\n \t\tt.Skipf(\"skipping test on %q\", runtime.GOOS)\n \t}\n \tif !supportsIPv6 {\n-\t\treturn\n+\t\tt.Skip(\"ipv6 is not supported\")\n \t}\n \n \ttoudpnet := func(net string) string {\

コアとなるコードの解説

src/pkg/net/multicast_test.go の変更

  • TestIPv6MulticastListener 関数:
    • 変更前: case "plan9", "solaris", "windows": t.Skipf(...)
    • 変更後: case "plan9", "solaris": t.Skipf(...)
    • この変更により、TestIPv6MulticastListener テストがWindows環境でスキップされなくなりました。これは、WindowsがIPv6マルチキャストを適切にサポートするようになったため、このテストをWindows上でも実行してその機能を確認する必要があることを示しています。

src/pkg/net/unicast_posix_test.go の変更

  • TestTCPListener 関数:

    • 変更前: case "plan9", "windows": t.Skipf(...)
    • 変更後: case "plan9": t.Skipf(...)
    • TestIPv6MulticastListener と同様に、TestTCPListener もWindows環境でスキップされなくなりました。これにより、Windows上でのTCPリスナーのテストカバレッジが向上します。
  • TestUDPListener 関数と TestSimpleTCPListener 関数の削除:

    • これらの関数は、ファイルから完全に削除されました。
    • コミットメッセージにある「Go 1.0 non-IPv6 support Windows code on IPv6 enabled Windows kernels」という記述から、これらのテストがGo言語の初期バージョンにおけるWindowsのIPv6非対応を前提としたものであり、現在のIPv6が有効なWindows環境では冗長または不適切になったため、削除されたと推測されます。これにより、テストスイートの肥大化を防ぎ、より関連性の高いテストに集中できるようになります。
  • TestSimpleUDPListener 関数:

    • switch runtime.GOOS 文から "windows" が削除されました。これにより、Windows環境でもシンプルなUDPリスナーのテストが実行されるようになります。
    • if tt.ipv6if tt.ipv6 && !supportsIPv6 に変更されました。これは、テストケースがIPv6に関連しており、かつシステムがIPv6をサポートしていない場合にのみテストをスキップするという、より正確な条件設定です。これにより、IPv6がサポートされている環境ではIPv6関連のテストが確実に実行されるようになります。
  • TestDualStackTCPListener および TestDualStackUDPListener 関数:

    • if !supportsIPv6 { return }if !supportsIPv6 { t.Skip("ipv6 is not supported") } に変更されました。
    • これは機能的な変更ではなく、テストがIPv6非サポートのためにスキップされたことを、テスト結果としてより明確に報告するための改善です。t.Skipを使用することで、テストフレームワークがそのテストをスキップ済みとして認識し、テストレポートにその旨が記録されます。

これらの変更は、Go言語のネットワークテストがWindows環境におけるIPv6の進化に追従し、より正確で効率的なテストスイートを構築するための重要なステップです。

関連リンク

参考にした情報源リンク