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

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

このコミットは、Go言語の標準ライブラリである net/http パッケージ内のテストに関するものです。具体的には、Plan 9オペレーティングシステム上で失敗する特定のテストを一時的に無効化する変更が加えられています。

コミット

commit 73b0d84c83833b21968ed9bf4d00cbfbc2ec2fdb
Author: David du Colombier <0intro@gmail.com>
Date:   Thu Jan 30 11:12:08 2014 +0100

    net/http: temporarily disable the failing tests on Plan 9
    
    Update #7237
    
    LGTM=bradfitz
    R=jas, bradfitz
    CC=golang-codereviews
    https://golang.org/cl/57190045

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

https://github.com/golang/go/commit/73b0d84c83833b21968ed9bf4d00cbfbc2ec2fdb

元コミット内容

net/http: temporarily disable the failing tests on Plan 9

このコミットは、Plan 9環境で失敗する net/http パッケージのテストを一時的に無効化します。

変更の背景

この変更の背景には、Go言語の net/http パッケージにおける特定のテストが、Plan 9オペレーティングシステム上で予期せぬ失敗を起こしていたという問題があります。コミットメッセージに Update #7237 とあることから、GoのIssueトラッカーで報告された問題(Issue 7237)に対応するための措置であることがわかります。

一般的に、異なるオペレーティングシステムやアーキテクチャでは、ネットワークスタックの実装、システムコール、タイマーの精度、あるいはその他の低レベルな動作に差異があるため、特定のテストケースが異なる振る舞いを示すことがあります。この場合、net/http パッケージのテスト、特にタイムアウトやコネクションの振る舞いに関連するテストが、Plan 9の環境特性と合致せず、安定してパスしない状況が発生していたと考えられます。

開発チームは、この問題の根本原因を特定し、修正するまでの間、CI/CDパイプラインや開発者のローカル環境でのテスト実行を妨げないように、一時的な回避策として該当テストを無効化することを選択しました。これは、テストスイート全体の健全性を維持しつつ、特定の環境依存の問題が全体の開発フローをブロックするのを避けるための一般的なプラクティスです。

前提知識の解説

  • Go言語の net/http パッケージ: Go言語の標準ライブラリの一部であり、HTTPクライアントとサーバーの実装を提供します。Webアプリケーションの構築やHTTP通信を行う上で中心的な役割を担います。このパッケージは、低レベルなTCP/IPソケット通信の上にHTTPプロトコルを抽象化し、開発者が容易にHTTPリクエストの送受信やHTTPサーバーの構築を行えるように設計されています。
  • Plan 9: ベル研究所で開発された分散オペレーティングシステムです。Unixの後継として設計され、"Everything is a file"(すべてはファイルである)という哲学に基づいています。Go言語はPlan 9の思想に影響を受けており、初期のGo開発環境はPlan 9上で構築されていました。しかし、Plan 9のネットワークスタックやシステムコールは、一般的なLinuxやWindows、macOSとは異なる特性を持つ場合があります。
  • runtime.GOOS: Go言語の標準ライブラリ runtime パッケージで提供される定数で、プログラムが実行されているオペレーティングシステムの名前(例: "linux", "windows", "darwin", "plan9"など)を文字列で返します。これを利用することで、特定のOSに依存するコードの条件分岐を行うことができます。
  • t.Skip(): Go言語のテストフレームワーク testing パッケージで提供されるメソッドです。テスト関数内で t.Skip("理由") を呼び出すと、そのテストはスキップされ、テスト結果には「SKIP」として記録されます。これは、特定の環境で実行できないテストや、一時的に無効化したいテストに対して使用されます。
  • Issueトラッカー (#7237): ソフトウェア開発プロジェクトでは、バグ報告、機能要望、改善提案などを管理するためにIssueトラッカーが使用されます。Go言語プロジェクトでは、GitHub Issuesが利用されており、#7237 は特定のIssueの識別子です。この番号を参照することで、問題の詳細な議論や解決状況を確認できます。

技術的詳細

このコミットは、Go言語のテストコードに条件付きのスキップロジックを追加することで、Plan 9環境でのテスト失敗を回避しています。具体的には、src/pkg/net/http/serve_test.gosrc/pkg/net/http/transport_test.go の2つのテストファイルが変更されています。

変更の核心は、各テスト関数の冒頭に以下のコードスニペットを追加することです。

if runtime.GOOS == "plan9" {
    t.Skip("skipping test; see http://golang.org/issue/7237")
}

このコードは、GoプログラムがPlan 9オペレーティングシステム上で実行されているかどうかを runtime.GOOS の値でチェックします。もしPlan 9であれば、t.Skip() メソッドが呼び出され、テストがスキップされます。スキップの理由として、関連するIssue番号(http://golang.org/issue/7237)が明記されており、将来的にこの問題が解決された際に、なぜテストがスキップされているのかを容易に追跡できるように配慮されています。

このアプローチは、テストの失敗が特定の環境に起因する場合に、CI/CDパイプラインをブロックすることなく、問題の根本原因の調査と修正を並行して進めるための標準的な手法です。テストを完全に削除するのではなく、条件付きでスキップすることで、他のOS環境でのテストカバレッジを維持しつつ、Plan 9での問題を一時的に無視することができます。

Issue 7237の内容を調査すると、net/http パッケージのタイムアウト関連のテストがPlan 9で失敗するという報告が見られます。これは、Plan 9のネットワークスタックやタイマーの実装が、他のOS(特にUnix系OS)とは異なる振る舞いをすることが原因である可能性が高いです。例えば、TCPコネクションの確立やデータの送受信におけるタイムアウトの挙動、あるいはゴルーチンのスケジューリングとタイマーの相互作用などが、テストの期待値と異なる結果を生み出していたと考えられます。

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

変更は以下の2つのファイルに集中しています。

  1. src/pkg/net/http/serve_test.go
  2. src/pkg/net/http/transport_test.go

これらのファイル内の複数のテスト関数(例: TestServerTimeouts, TestOnlyWriteTimeout, TestTLSHandshakeTimeout, TestClientWriteShutdown, TestTransportPersistConnLeak, TestTransportPersistConnLeakShortBody, TestIssue4191_InfiniteGetTimeout, TestIssue4191_InfiniteGetToPutTimeout)の冒頭に、Plan 9での実行時にテストをスキップする条件分岐が追加されています。

具体的な変更は、各テスト関数の先頭に以下の3行が追加されたことです。

--- a/src/pkg/net/http/serve_test.go
+++ b/src/pkg/net/http/serve_test.go
@@ -441,6 +441,9 @@ func TestMuxRedirectLeadingSlashes(t *testing.T) {
 }
 
 func TestServerTimeouts(t *testing.T) {
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping test; see http://golang.org/issue/7237")
+	}
 	defer afterTest(t)
 	reqNum := 0
 	ts := httptest.NewUnstartedServer(HandlerFunc(func(res ResponseWriter, req *Request) {
...

コアとなるコードの解説

追加されたコードスニペットは非常にシンプルですが、その意図は明確です。

if runtime.GOOS == "plan9" {
    t.Skip("skipping test; see http://golang.org/issue/7237")
}
  • runtime.GOOS == "plan9": これは、現在のGoプログラムがPlan 9オペレーティングシステム上で実行されているかどうかをチェックする条件式です。runtime.GOOS はビルド時に決定される定数であり、実行環境のOSを識別するために使用されます。
  • t.Skip(...): testing.T 型のメソッドで、このメソッドが呼び出されると、現在のテスト関数はそれ以上実行されずにスキップされます。テスト結果のレポートには、このテストがスキップされたことと、引数で指定された理由(この場合はIssue 7237への参照)が表示されます。

この変更により、Plan 9環境でこれらのテストを実行しても、失敗として報告される代わりにスキップとして扱われるようになります。これにより、Plan 9でのビルドやテストのCIが中断されることなく、開発者は他のOSでの開発を継続できます。同時に、Issue 7237が解決されれば、この条件分岐を削除してテストを再度有効にすることができます。これは、特定の環境でのみ発生する問題を一時的に隔離し、全体の開発プロセスを円滑に進めるための効果的な手段です。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント
  • GitHubのGoリポジトリのIssueトラッカー
  • Plan 9に関する一般的な情報源 (Wikipediaなど)
  • Go言語のテストに関する一般的なプラクティス
  • コミットメッセージと変更されたコード自体