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

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

このコミットは、Go言語の標準ライブラリであるnetパッケージ内のテストファイルsrc/pkg/net/server_test.goに対する変更です。このファイルは、ネットワークサーバーのテストケースを定義しており、TCP/UDPなどのネットワークプロトコルを用いた接続やパケット送受信のテストロジックを含んでいます。

コミット

このコミットは、Go言語のnetパッケージにおけるテストのログ出力フォーマットを一貫させることを目的としています。具体的には、t.Logf関数を用いたログ出力において、不要な改行文字の削除と、文字列のフォーマット指定子を%sから%qに変更することで、ログの可読性と統一性を向上させています。

  • コミットハッシュ: 8727b11dfb867f2e20b2f61f275a0a61dd28cd98
  • 作者: Mikio Hara mikioh.mikioh@gmail.com
  • コミット日時: 2012年1月16日 月曜日 14:57:18 +0900

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

https://github.com/golang/go/commit/8727b11dfb867f2e20b2f61f275a0a61dd28cd98

元コミット内容

net: consistent log format in test

R=golang-dev, adg
CC=golang-dev
https://golang.org/cl/5545062

変更の背景

Go言語のテストフレームワークでは、testingパッケージが提供され、テスト中に情報を出力するためにt.Logfのような関数が利用されます。この関数はfmt.Printfと同様のフォーマット指定子を使用しますが、t.Logfは内部的に出力の最後に自動的に改行を追加する特性があります。

元のコードでは、t.Logfのフォーマット文字列の末尾に明示的に\n(改行文字)が含まれていました。これにより、t.Logfが自動的に追加する改行と合わせて、二重の改行が出力されてしまい、テストログの可読性を損ねていました。

また、文字列を出力する際に%s(文字列)フォーマット指定子が使用されていましたが、ネットワークアドレスやその他の文字列引数にはスペースや特殊文字が含まれる可能性があり、ログ出力時にそれらの区切りが不明瞭になることがありました。テストログは、テストの実行状況や問題発生時のデバッグに不可欠であるため、そのフォーマットは一貫性があり、かつ明確であることが求められます。このコミットは、これらの問題を解決し、テストログの品質を向上させることを目的としています。

前提知識の解説

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

Go言語には、標準ライブラリとしてtestingパッケージが提供されており、ユニットテストやベンチマークテストを記述するための機能を提供します。テスト関数はfunc TestXxx(t *testing.T)というシグネチャを持ち、*testing.T型の引数tを通じてテストの状態を管理したり、テスト中に情報を出力したりします。

t.Logf(format string, args ...interface{})は、*testing.T型が提供するメソッドの一つで、テスト中にフォーマットされた文字列をログに出力するために使用されます。この関数はfmt.Printfと同様のフォーマット指定子をサポートしますが、重要な違いとして、t.Logfは出力の最後に自動的に改行を追加します。したがって、フォーマット文字列の末尾に\nを明示的に含める必要はありません。含めると二重改行になります。

Go言語のフォーマット動詞(Verb)

Go言語のfmtパッケージ(そしてt.Logfのようなfmtパッケージの機能を利用する関数)では、様々なフォーマット動詞(verbs)を使用して値の表示形式を制御します。

  • %s: 値をデフォルトの形式で文字列として出力します。例えば、string型の値はそのまま出力されます。
  • %q: 値をGoのシンタックスでクォートされた文字列として出力します。これは、文字列リテラルを表現する際に便利です。特に、文字列にスペース、タブ、改行などの非表示文字や特殊文字が含まれる場合に、それらがエスケープされて表示されるため、文字列の境界が明確になり、デバッグ時の可読性が向上します。例えば、"hello world""hello world"と出力され、"hello\nworld""hello\nworld"と出力されます。

テストログにおいて、ネットワークアドレスやその他の引数が文字列として渡される場合、%qを使用することで、それらの文字列が明確に区切られ、どの部分がどの引数に対応するのかが視覚的に分かりやすくなります。

技術的詳細

このコミットの技術的な変更点は、src/pkg/net/server_test.goファイル内のt.Logf呼び出しにおけるフォーマット文字列の修正に集約されます。

  1. 不要な改行文字の削除: t.Logfは、その性質上、出力の最後に自動的に改行を追加します。元のコードでは、フォーマット文字列の末尾に\nが明示的に含まれていました。これは冗長であり、テスト実行時にログに余分な空行を生成していました。このコミットでは、これらの冗長な\nを削除することで、ログ出力がより簡潔になり、可読性が向上します。

  2. %sから%qへのフォーマット指定子の変更: t.Logfの引数として渡されるnetwork, listenaddr, dialaddrは、ネットワークの種類やアドレスを表す文字列です。これらの文字列には、スペースや特殊文字が含まれる可能性があります。

    • %sを使用した場合、文字列はそのまま出力されます。例えば、"127.0.0.1:8080"127.0.0.1:8080と出力されます。
    • %qを使用した場合、文字列はGoの文字列リテラル形式でクォートされて出力されます。例えば、"127.0.0.1:8080""127.0.0.1:8080"と出力されます。これにより、ログ出力において各引数の文字列が明確に区切られ、特に複数の文字列引数が連続して表示される場合に、どの部分がどの引数に対応するのかが視覚的に分かりやすくなります。これは、テストのデバッグやログ解析において非常に有効です。

これらの変更は、テストログの出力フォーマットを一貫させ、視認性を高めることで、開発者がテスト結果をより効率的に理解し、問題の特定を容易にすることを目的としています。

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

--- a/src/pkg/net/server_test.go
+++ b/src/pkg/net/server_test.go
@@ -91,7 +91,7 @@ func connect(t *testing.T, network, addr string, isEmpty bool) {
 }
 
 func doTest(t *testing.T, network, listenaddr, dialaddr string) {
-	t.Logf("Test %q %q %q\n", network, listenaddr, dialaddr)
+	t.Logf("Test %q %q %q", network, listenaddr, dialaddr)
 	switch listenaddr {
 	case "", "0.0.0.0", "[::]", "[::ffff:0.0.0.0]":
 		if testing.Short() || avoidMacFirewall {
@@ -194,7 +194,7 @@ Run:
 }
 
 func doTestPacket(t *testing.T, network, listenaddr, dialaddr string, isEmpty bool) {
-	t.Logf("TestPacket %s %s %s\n", network, listenaddr, dialaddr)
+	t.Logf("TestPacket %q %q %q", network, listenaddr, dialaddr)
 	listening := make(chan string)
 	done := make(chan int)
 	if network == "udp" {

コアとなるコードの解説

変更はsrc/pkg/net/server_test.goファイル内の2箇所にあります。

  1. doTest関数内の変更:

    -	t.Logf("Test %q %q %q\n", network, listenaddr, dialaddr)
    +	t.Logf("Test %q %q %q", network, listenaddr, dialaddr)
    

    この変更では、フォーマット文字列の末尾にあった\nが削除されています。これにより、t.Logfが自動的に追加する改行と重複することがなくなり、ログ出力が1行に収まるようになります。%qは元々使用されていたため、この行ではフォーマット指定子の変更はありません。

  2. doTestPacket関数内の変更:

    -	t.Logf("TestPacket %s %s %s\n", network, listenaddr, dialaddr)
    +	t.Logf("TestPacket %q %q %q", network, listenaddr, dialaddr)
    

    この変更では、2つの修正が行われています。

    • フォーマット文字列の末尾にあった\nが削除されています。これはdoTest関数と同様の理由です。
    • 文字列のフォーマット指定子が%sから%qに変更されています。これにより、network, listenaddr, dialaddrの各文字列がログ出力時にGoの文字列リテラル形式でクォートされ、視覚的に明確に区切られるようになります。

これらの変更により、netパッケージのテストログはより一貫性があり、デバッグ時に必要な情報がより明確に表示されるようになります。

関連リンク

参考にした情報源リンク