[インデックス 19006] ファイルの概要
このコミットは、Go言語の標準ライブラリである net
パッケージのテストコードに対する変更です。具体的には、src/pkg/net/conn_test.go
、src/pkg/net/protoconn_test.go
、src/pkg/net/server_test.go
の3つのファイルが修正されています。これらのファイルは、Goのネットワーク機能、特にUNIXドメインソケット(AF_UNIX
)と様々なソケットタイプ(SOCK_STREAM
、SOCK_DGRAM
、SOCK_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.Listen
や net.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
関数の引数名linuxonly
がlinuxOnly
に変更されました(大文字小文字の修正)。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
テストを実行できるようにすることです。
-
unixpacket
テストのプラットフォーム拡張:- 以前は、
unixpacket
ソケットのテストは主にLinuxに限定されていました。これは、conn_test.go
やserver_test.go
内のruntime.GOOS != "linux"
という条件でテストがスキップされていたためです。 - このコミットでは、このスキップ条件が緩和され、DragonFlyBSD、FreeBSD 9以降、NetBSD 6以降、Solaris (illumos) など、
SOCK_SEQPACKET
をサポートする他のUNIX系OSでもテストが実行されるようになりました。具体的には、conn_test.go
のTestConnAndListener
関数やserver_test.go
のTestSeqpacketConnServer
関数内のswitch runtime.GOOS
ブロックが更新され、これらのOSがスキップ対象から外されています。これにより、Goのnet
パッケージがこれらのプラットフォームでSOCK_SEQPACKET
を正しく扱えることが保証されます。 - FreeBSDに関しては、バージョン8以前では
unixpacket
のサポートが不完全であったため、freebsd
の場合は引き続きスキップするロジックが残されています。これは、Goのテストが特定のOSバージョンに依存する機能の差異を考慮していることを示しています。
- 以前は、
-
一時ファイルパスのポータビリティ向上:
src/pkg/net/protoconn_test.go
のtestUnixAddr
関数では、UNIXドメインソケットファイルを作成するための一時ファイルパスを生成しています。以前はioutil.TempFile("/tmp", "nettest")
のように/tmp
を明示的に指定していました。- この変更により、
ioutil.TempFile("", "nettest")
となり、第一引数が空文字列になりました。これは、Goのio/ioutil
パッケージが提供するTempFile
関数が、第一引数が空文字列の場合にシステムデフォルトの一時ディレクトリ(通常はos.TempDir()
が返すパス、多くの場合/tmp
やC:\Windows\Temp
など)を使用するという仕様に基づいています。 - この変更は、特定のOSや環境で
/tmp
ディレクトリへの書き込み権限がない場合や、より適切な一時ディレクトリが存在する場合に、テストの実行をより堅牢でポータブルにする効果があります。
-
テストコードの整理:
src/pkg/net/server_test.go
からtempfile
ヘルパー関数が削除され、代わりにprotoconn_test.go
で定義されているtestUnixAddr()
関数が再利用されるようになりました。これにより、一時UNIXソケットアドレス生成ロジックが一元化され、コードの重複が排除されています。linuxonly
という引数名がlinuxOnly
に変更され、Goのコーディング規約に沿ったキャメルケースになりました。
これらの変更により、Goの net
パッケージの unixpacket
テストは、より広範なUNIX系オペレーティングシステムで実行可能となり、Goのクロスプラットフォーム対応の品質が向上しました。
関連リンク
- Go Change-Id:
83390043
(Gerrit Code Review)
参考にした情報源リンク
- UNIXドメインソケットに関する一般的な情報:
SOCK_SEQPACKET
に関する情報:- https://man7.org/linux/man-pages/man2/socket.2.html (Linux man page for
socket
, describesSOCK_SEQPACKET
)
- https://man7.org/linux/man-pages/man2/socket.2.html (Linux man page for
- Go言語の
net
パッケージに関するドキュメント: - Go言語の
testing
パッケージに関するドキュメント: - Go言語の
runtime
パッケージに関するドキュメント: - Go言語の
io/ioutil
パッケージに関するドキュメント (現在はos
パッケージに統合):- https://pkg.go.dev/io/ioutil (旧ドキュメント)
- https://pkg.go.dev/os#CreateTemp (現在の
os.CreateTemp
に相当)
- FreeBSDの
unix(4)
man page (FreeBSDにおけるUNIXドメインソケットのサポート状況):- https://www.freebsd.org/cgi/man.cgi?query=unix&sektion=4 (FreeBSDのバージョンによって
SOCK_SEQPACKET
の記述が異なる場合がある)
- https://www.freebsd.org/cgi/man.cgi?query=unix&sektion=4 (FreeBSDのバージョンによって
- NetBSDの
unix(4)
man page: - DragonFlyBSDの
unix(4)
man page: - illumosの
unix(7P)
man page: