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

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

このコミットは、Go言語の標準ライブラリであるnetパッケージのテストスイートを、Plan 9オペレーティングシステム上で適切に実行できるように調整するものです。具体的には、Plan 9環境で問題を引き起こす特定のテストをスキップし、以前はスキップされていたが現在はパスするようになったテストを再有効化する変更が含まれています。これにより、GoのnetパッケージがPlan 9環境においても期待通りに動作し、テストが正確な結果を反映するようになります。

コミット

commit b2249f2018155184abe10781633b8d66e566fa86
Author: Akshat Kumar <seed@mail.nanosouffle.net>
Date:   Thu Feb 28 07:18:02 2013 +0100

    net: pass tests on Plan 9
    
    Ignore problematic tests and un-ignore one
    we can now pass.
    
    R=rsc, rminnich, ality, dave, bradfitz
    CC=golang-dev
    https://golang.org/cl/7396060

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

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

元コミット内容

このコミットの元の内容は以下の通りです。

net: pass tests on Plan 9

Ignore problematic tests and un-ignore one
we can now pass.

R=rsc, rminnich, ality, dave, bradfitz
CC=golang-dev
https://golang.org/cl/7396060

変更の背景

Go言語はクロスプラットフォーム対応を重視しており、様々なオペレーティングシステム上で動作するように設計されています。その中には、一般的なLinux、Windows、macOSだけでなく、Plan 9のようなニッチなOSも含まれます。しかし、OSごとにシステムコールやネットワークスタックの実装が異なるため、特定の機能や挙動がOS間で一致しないことがあります。

このコミットの背景には、GoのnetパッケージのテストがPlan 9環境で失敗するか、または不適切にスキップされているという問題がありました。テストの失敗は、Plan 9のネットワーク実装が他のOSと異なるために発生する可能性があり、また、不必要なスキップは、本来テストされるべき機能が検証されないことを意味します。

このコミットは、Plan 9上でのGoのnetパッケージのテストの健全性を向上させることを目的としています。具体的には、Plan 9の特性に起因するテストの失敗を回避するために、問題のあるテストを明示的にスキップし、一方で、以前はスキップされていたが、Goの改善やPlan 9環境の調整によりパスするようになったテストを再有効化することで、テストカバレッジと信頼性を最適化しています。

前提知識の解説

Plan 9 from Bell Labs

Plan 9は、ベル研究所によって開発された分散オペレーティングシステムです。Unixの設計思想をさらに推し進め、すべてのリソース(ファイル、デバイス、ネットワーク接続など)をファイルシステムとして表現するという特徴を持っています。これにより、ネットワーク透過性が高く、分散システムを構築しやすいという利点があります。Go言語の開発者の一部はPlan 9の開発にも携わっており、Go言語自体もPlan 9の影響を受けている部分があります。

Go言語のnetパッケージ

Go言語のnetパッケージは、ネットワークI/O機能を提供する標準ライブラリです。TCP/IP、UDP、Unixドメインソケットなどのプロトコルをサポートし、ネットワーク接続の確立、データの送受信、リスニングなどの機能を提供します。このパッケージは、Goアプリケーションがネットワーク通信を行う上で基盤となる重要なコンポーネントです。

Go言語のテストとt.Skipf

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

t.Skipfは、*testing.Tオブジェクトのメソッドの一つで、テストをスキップするために使用されます。特定の条件(例:特定のOS上での実行)が満たされた場合にテストを実行しないようにするために利用されます。これにより、プラットフォーム固有の挙動や、まだ解決されていないバグのためにテストが失敗するのを防ぎつつ、他のプラットフォームではテストを実行し続けることができます。

runtime.GOOS

runtime.GOOSは、Go言語のruntimeパッケージで提供される定数で、Goプログラムが実行されているオペレーティングシステムの名前(例: "linux", "windows", "darwin", "plan9"など)を表す文字列です。この定数を使用することで、プログラムの実行時にOSに応じた条件分岐を行うことができます。今回のコミットでは、このruntime.GOOSを利用して、Plan 9環境でのみ特定のテストをスキップするロジックが実装されています。

技術的詳細

このコミットの技術的な核心は、Goのテストコード内でruntime.GOOS定数を利用した条件付きスキップロジックを導入または変更することにあります。

Goのnetパッケージは、OSのネットワークスタックと密接に連携して動作します。Plan 9のネットワークスタックは、他のUnix系OSやWindowsとは異なる設計思想に基づいています。例えば、Plan 9ではネットワークデバイスや接続もファイルシステム上の特殊なファイルとして扱われるため、ソケットの作成、接続、データの送受信といった操作が、他のOSとは異なるセマンティクスを持つ場合があります。

具体的には、以下のテストファイルが変更されています。

  1. src/pkg/net/file_test.go:

    • TestFileListenerテストにおいて、以前はplan9windowsの両方でスキップされていましたが、このコミットによりwindowsのみでスキップされるように変更されました。これは、Plan 9上でのファイルリスナー関連のテストが、Goの改善またはPlan 9環境の調整によりパスするようになったことを示唆しています。
  2. src/pkg/net/net_test.go:

    • TestTCPCloseテストに、plan9環境でのスキップロジックが追加されました。これは、Plan 9上でのTCP接続のクローズに関する特定の挙動が、このテストの期待値と合致しないため、一時的にスキップする必要があることを示しています。
  3. src/pkg/net/protoconn_test.go:

    • TestTCPListenerSpecificMethodsテストに、plan9環境でのスキップロジックが追加されました。これは、Plan 9上でのTCPリスナーの特定のメソッドの挙動が、このテストの期待値と異なるため、スキップが必要であることを示しています。
  4. src/pkg/net/timeout_test.go:

    • testVariousDeadlinesTestReadDeadlineDataAvailableTestWriteDeadlineBufferAvailableの各テストに、plan9環境でのスキップロジックが追加されました。これは、Plan 9上でのネットワークI/Oのタイムアウト処理やデッドラインの挙動が、他のOSと異なる可能性があり、これらのテストがPlan 9で安定してパスしないため、スキップが必要であることを示しています。

これらの変更は、Plan 9のネットワーク実装の特性を考慮し、GoのテストスイートがPlan 9上でより正確かつ安定して動作するようにするための調整です。テストをスキップすることは、その機能がPlan 9で完全にサポートされていないか、またはそのテストがPlan 9の特定の挙動を考慮していないことを意味する場合があります。しかし、これにより、他のプラットフォームでのテストの実行を妨げることなく、Plan 9固有の問題を特定し、将来的に解決するための道筋をつけることができます。

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

このコミットにおけるコアとなるコードの変更箇所は、Goのテストファイル内でswitch runtime.GOOS文を用いて、Plan 9オペレーティングシステムでのみ特定のテストをスキップするロジックを追加または修正している点です。

src/pkg/net/file_test.go

--- a/src/pkg/net/file_test.go
+++ b/src/pkg/net/file_test.go
@@ -89,7 +89,7 @@ var fileListenerTests = []struct {
 
 func TestFileListener(t *testing.T) {
 	switch runtime.GOOS {
-	case "plan9", "windows":
+	case "windows":
 		t.Skipf("skipping test on %q", runtime.GOOS)
 	}
 

src/pkg/net/net_test.go

--- a/src/pkg/net/net_test.go
+++ b/src/pkg/net/net_test.go
@@ -173,6 +173,10 @@ func TestUDPListenClose(t *testing.T) {
 }
 
 func TestTCPClose(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("skipping test on %q", runtime.GOOS)
+	}
 	l, err := Listen("tcp", "127.0.0.1:0")
 	if err != nil {
 		t.Fatal(err)

src/pkg/net/protoconn_test.go

--- a/src/pkg/net/protoconn_test.go
+++ b/src/pkg/net/protoconn_test.go
@@ -25,6 +25,11 @@ var condErrorf = func() func(*testing.T, string, ...interface{}) {
 }()
 
 func TestTCPListenerSpecificMethods(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("skipping test on %q", runtime.GOOS)
+	}
+
 	la, err := ResolveTCPAddr("tcp4", "127.0.0.1:0")
 	if err != nil {
 		t.Fatalf("net.ResolveTCPAddr failed: %v", err)

src/pkg/net/timeout_test.go

--- a/src/pkg/net/timeout_test.go
+++ b/src/pkg/net/timeout_test.go
@@ -420,6 +420,11 @@ func TestVariousDeadlines4Proc(t *testing.T) {
 }
 
 func testVariousDeadlines(t *testing.T, maxProcs int) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("skipping test on %q", runtime.GOOS)
+	}
+
 	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
 	ln := newLocalListener(t)
 	defer ln.Close()
@@ -518,6 +523,11 @@ func testVariousDeadlines(t *testing.T, maxProcs int) {
 // TestReadDeadlineDataAvailable tests that read deadlines work, even
 // if there's data ready to be read.
 func TestReadDeadlineDataAvailable(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("skipping test on %q", runtime.GOOS)
+	}
+
 	ln := newLocalListener(t)
 	defer ln.Close()
 
@@ -552,6 +562,11 @@ func TestWriteDeadlineBufferAvailable(t *testing.T) {
 // if there's buffer space available to write.
 func TestWriteDeadlineBufferAvailable(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("skipping test on %q", runtime.GOOS)
+	}
+
 	ln := newLocalListener(t)
 	defer ln.Close()
 

コアとなるコードの解説

上記の変更箇所では、Goのテストフレームワークが提供する*testing.T型のSkipfメソッドと、Goのランタイム情報を提供するruntime.GOOS定数を組み合わせて使用しています。

各テスト関数の冒頭または関連するテストロジックの前に、以下のようなswitch文が追加されています。

	switch runtime.GOOS {
	case "plan9":
		t.Skipf("skipping test on %q", runtime.GOOS)
	}

このコードスニペットは、以下の処理を行います。

  1. runtime.GOOSの値を確認します。これは、現在Goプログラムが実行されているオペレーティングシステムの名前(例: "linux", "windows", "plan9"など)を文字列で返します。
  2. もしruntime.GOOS"plan9"と一致した場合、t.Skipfメソッドが呼び出されます。
  3. t.Skipfは、現在のテストをスキップし、指定されたフォーマット文字列と引数(この場合は"skipping test on %q"runtime.GOOSの値)を使用して、スキップ理由をテスト結果に出力します。

src/pkg/net/file_test.goTestFileListenerでは、以前は"plan9""windows"の両方でスキップされていましたが、このコミットで"plan9"が削除され、"windows"のみでスキップされるようになりました。これは、Plan 9上でのTestFileListenerがパスするようになったため、スキップする必要がなくなったことを意味します。

その他のテスト(TestTCPClose, TestTCPListenerSpecificMethods, testVariousDeadlines, TestReadDeadlineDataAvailable, TestWriteDeadlineBufferAvailable)では、新たに"plan9"でのスキップロジックが追加されています。これは、これらのテストがPlan 9環境で安定してパスしない、またはPlan 9のネットワーク実装の特性上、テストの意図する挙動が異なるため、一時的にスキップする必要があると判断されたことを示しています。

これらの変更により、GoのテストスイートはPlan 9の特定の挙動に適応し、テストの実行結果がより正確にシステムの互換性を反映するようになります。これにより、開発者はPlan 9上でのGoのnetパッケージの動作に関する問題をより効果的に特定し、対処できるようになります。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント
  • Go言語のソースコード(特にnetパッケージのテストファイル)
  • Plan 9に関する一般的な情報源(Wikipediaなど)
  • Go言語のテストに関する一般的な情報源(ブログ記事、チュートリアルなど)
  • コミットメッセージに記載されているGoのコードレビューリンク: https://golang.org/cl/7396060 (現在はhttps://go.googlesource.com/go/+/7396060にリダイレクトされます)