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

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

このコミットは、Go言語の標準ライブラリである net パッケージのテストコードに対する変更です。具体的には、src/pkg/net/conn_test.gosrc/pkg/net/protoconn_test.gosrc/pkg/net/server_test.go の3つのファイルが修正されています。これらのファイルは、Goのネットワーク機能、特にUNIXドメインソケット(AF_UNIX)と様々なソケットタイプ(SOCK_STREAMSOCK_DGRAMSOCK_SEQPACKET)の動作を検証するためのテストケースを含んでいます。

コミット

このコミットの目的は、AF_UNIX ドメインにおける SOCK_SEQPACKET ソケットをサポートするオペレーティングシステム上で、unixpacket タイプのネットワークテストを有効にすることです。これにより、Goの net パッケージがこれらのプラットフォームで SOCK_SEQPACKET を正しく扱えることを保証し、テストカバレッジを向上させます。

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

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

元コミット内容

net: enable unixpacket test on available platforms

DragonFlyBSD, FreeBSD 9 and beyond, NetBSD 6 and beyond, and
Solaris (illumos) support AF_UNIX+SOCK_SEQPACKET socket.

LGTM=dave
R=golang-codereviews, dave
CC=golang-codereviews
https://golang.org/cl/83390043

変更の背景

Go言語の net パッケージは、様々なネットワークプロトコルとソケットタイプをサポートしています。UNIXドメインソケットは、同一ホスト内のプロセス間通信(IPC)に広く利用されており、その中でも SOCK_SEQPACKET は、信頼性のある接続指向のデータグラム通信を提供する特殊なソケットタイプです。

これまでのGoのテストスイートでは、unixpacket ソケットに関するテストが、特定のプラットフォーム(主にLinux)に限定されていました。しかし、DragonFlyBSD、FreeBSD 9以降、NetBSD 6以降、そしてSolaris(illumos)といった他のUNIX系オペレーティングシステムも、AF_UNIX ドメインで SOCK_SEQPACKET ソケットをサポートしています。

このコミットの背景には、Goの net パッケージがこれらのプラットフォームでも SOCK_SEQPACKET を正しく実装し、動作することを検証するためのテストカバレッジを拡大したいという意図があります。テストを有効にすることで、将来的な回帰バグを防ぎ、より堅牢なクロスプラットフォーム対応を実現します。

前提知識の解説

1. UNIXドメインソケット (AF_UNIX / AF_LOCAL)

UNIXドメインソケットは、同じホストマシン上で動作するプロセス間で通信を行うためのメカニズムです。TCP/IPソケットとは異なり、ネットワークスタックを介さず、ファイルシステム上のパス名(ソケットファイル)または抽象的な名前空間(Linuxのみ)を使用して通信相手を識別します。これにより、ネットワークオーバーヘッドなしに高速なプロセス間通信が可能です。

2. ソケットタイプ

ソケットにはいくつかのタイプがあり、それぞれ異なる通信特性を持ちます。

  • SOCK_STREAM: 接続指向の信頼性のあるバイトストリームを提供します。データは順序通りに配信され、重複や欠落はありません。TCPソケットに相当します。
  • SOCK_DGRAM: コネクションレスなデータグラム通信を提供します。データはパケット単位で送信され、順序保証や信頼性保証はありません。UDPソケットに相当します。
  • SOCK_SEQPACKET: 接続指向の信頼性のあるデータグラム通信を提供します。SOCK_STREAM と同様に接続を確立しますが、SOCK_DGRAM のようにメッセージの境界(パケット)が保持されます。つまり、送信されたパケットは、受信側でも同じパケットとして受け取られ、途中で結合されたり分割されたりしません。これは、特定のプロトコル(例: SCTP)や、メッセージの境界が重要なIPCにおいて有用です。

3. Goの net パッケージ

Go言語の net パッケージは、ネットワークI/Oのプリミティブを提供します。これには、TCP/UDPソケット、IPソケット、UNIXドメインソケットの作成、接続、リスニング、データの送受信などが含まれます。net.Listennet.Dial といった関数を通じて、様々なネットワークタイプとアドレス形式を指定して通信を行うことができます。

4. runtime.GOOS

Go言語の runtime パッケージは、Goプログラムが実行されている環境に関する情報を提供します。runtime.GOOS は、現在のオペレーティングシステムの名前(例: "linux", "darwin", "windows", "freebsd" など)を文字列で返します。テストコードでは、この値を利用して特定のOSに依存するテストをスキップしたり、異なるロジックを適用したりすることがよく行われます。

5. t.Skipf

Goの testing パッケージで提供される t.Skipf 関数は、テストの実行中に特定の条件が満たされない場合に、そのテストをスキップするために使用されます。引数にはフォーマット文字列と引数を取り、スキップ理由を出力できます。これにより、プラットフォーム固有の機能や外部依存関係がない環境でテストが失敗するのを防ぎ、テストスイートのポータビリティを向上させます。

技術的詳細

このコミットの核心は、AF_UNIX ドメインにおける SOCK_SEQPACKET ソケットのサポート状況がオペレーティングシステムによって異なるという事実に基づいています。

  • Linux: 以前から AF_UNIX+SOCK_SEQPACKET をサポートしており、Goのテストもこれに対応していました。
  • DragonFlyBSD: SOCK_SEQPACKET をサポートしています。
  • FreeBSD 9以降: FreeBSD 8以前では SOCK_SEQPACKET のサポートが不完全でしたが、バージョン9以降で完全にサポートされました。
  • NetBSD 6以降: NetBSD 6以降で SOCK_SEQPACKET をサポートしています。
  • Solaris (illumos): Solaris系OS(illumosを含む)も SOCK_SEQPACKET をサポートしています。

このコミットでは、これらのプラットフォームで unixpacket テストが実行されるように、テストコード内のOS判定ロジックが修正されました。具体的には、unixpacket テストをスキップする条件から、上記のサポートOSを除外しています。

また、一時的なUNIXソケットファイルを作成する際のパス指定も変更されています。以前は /tmp ディレクトリを明示的に指定していましたが、ioutil.TempFile の第一引数を空文字列にすることで、システムが提供するデフォルトの一時ディレクトリ(通常は TMPDIR 環境変数で指定される場所)を使用するように変更されました。これにより、一時ファイルの作成場所に関するポータビリティが向上し、特定の環境でのファイル作成権限の問題を回避できる可能性があります。

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

src/pkg/net/conn_test.go

  • connTests 構造体の addr フィールドの型が func() string から string に変更され、初期化時に testUnixAddr() の結果が直接代入されるようになりました。
  • TestConnAndListener 関数内で、unixpacket ネットワークタイプに対するスキップロジックが変更されました。
    • 以前は runtime.GOOS != "linux" の場合に unixpacket テストをスキップしていましたが、この条件がより詳細になりました。
    • darwin, nacl, openbsd, plan9, windows では引き続きスキップされます。
    • freebsd の場合、FreeBSD 8では unixpacket がサポートされていないためスキップされますが、FreeBSD 9以降ではテストが実行されるようになります(コード上は freebsd 全体をスキップしていますが、これはFreeBSD 8以前を対象としたもので、FreeBSD 9以降は他の条件でカバーされることを示唆しています)。

src/pkg/net/protoconn_test.go

  • testUnixAddr 関数内で、ioutil.TempFile の第一引数が "/tmp" から空文字列 "" に変更されました。これにより、一時ファイルがシステムデフォルトの一時ディレクトリに作成されるようになります。

src/pkg/net/server_test.go

  • skipServerTest 関数の引数名 linuxonlylinuxOnly に変更されました(大文字小文字の修正)。
  • tempfile ヘルパー関数が削除され、代わりに testUnixAddr() が使用されるようになりました。
  • TestSeqpacketConnServer 関数内で、unixpacket テストのスキップロジックが変更されました。
    • 以前は runtime.GOOS != "linux" の場合にスキップしていましたが、conn_test.go と同様に、darwin, nacl, openbsd, plan9, windows, freebsd (FreeBSD 8以前を想定) でスキップされるようになりました。
    • linuxOnly フラグが設定されているテストケースについては、runtime.GOOS != "linux" の場合にスキップするロジックが追加されました。これにより、Linux固有の抽象UNIXドメインソケットのテストが他のOSで実行されないようにしています。

コアとなるコードの解説

このコミットの主要な変更は、Goの net パッケージのテストスイートが、AF_UNIX ドメインにおける SOCK_SEQPACKET ソケットをサポートするより多くのオペレーティングシステムで unixpacket テストを実行できるようにすることです。

  1. unixpacket テストのプラットフォーム拡張:

    • 以前は、unixpacket ソケットのテストは主にLinuxに限定されていました。これは、conn_test.goserver_test.go 内の runtime.GOOS != "linux" という条件でテストがスキップされていたためです。
    • このコミットでは、このスキップ条件が緩和され、DragonFlyBSD、FreeBSD 9以降、NetBSD 6以降、Solaris (illumos) など、SOCK_SEQPACKET をサポートする他のUNIX系OSでもテストが実行されるようになりました。具体的には、conn_test.goTestConnAndListener 関数や server_test.goTestSeqpacketConnServer 関数内の switch runtime.GOOS ブロックが更新され、これらのOSがスキップ対象から外されています。これにより、Goの net パッケージがこれらのプラットフォームで SOCK_SEQPACKET を正しく扱えることが保証されます。
    • FreeBSDに関しては、バージョン8以前では unixpacket のサポートが不完全であったため、freebsd の場合は引き続きスキップするロジックが残されています。これは、Goのテストが特定のOSバージョンに依存する機能の差異を考慮していることを示しています。
  2. 一時ファイルパスのポータビリティ向上:

    • src/pkg/net/protoconn_test.gotestUnixAddr 関数では、UNIXドメインソケットファイルを作成するための一時ファイルパスを生成しています。以前は ioutil.TempFile("/tmp", "nettest") のように /tmp を明示的に指定していました。
    • この変更により、ioutil.TempFile("", "nettest") となり、第一引数が空文字列になりました。これは、Goの io/ioutil パッケージが提供する TempFile 関数が、第一引数が空文字列の場合にシステムデフォルトの一時ディレクトリ(通常は os.TempDir() が返すパス、多くの場合 /tmpC:\Windows\Temp など)を使用するという仕様に基づいています。
    • この変更は、特定のOSや環境で /tmp ディレクトリへの書き込み権限がない場合や、より適切な一時ディレクトリが存在する場合に、テストの実行をより堅牢でポータブルにする効果があります。
  3. テストコードの整理:

    • src/pkg/net/server_test.go から tempfile ヘルパー関数が削除され、代わりに protoconn_test.go で定義されている testUnixAddr() 関数が再利用されるようになりました。これにより、一時UNIXソケットアドレス生成ロジックが一元化され、コードの重複が排除されています。
    • linuxonly という引数名が linuxOnly に変更され、Goのコーディング規約に沿ったキャメルケースになりました。

これらの変更により、Goの net パッケージの unixpacket テストは、より広範なUNIX系オペレーティングシステムで実行可能となり、Goのクロスプラットフォーム対応の品質が向上しました。

関連リンク

参考にした情報源リンク