[インデックス 11006] ファイルの概要
このコミットは、Go言語のテストフレームワークにおける-test.timeout
フラグの挙動を変更し、時間指定の柔軟性と明確性を向上させるものです。具体的には、タイムアウト値を秒単位の整数(int64
)で受け取る形式から、time.Duration
型で表現される期間(例: "10s", "2m")で受け取る形式へと変更しています。これにより、ユーザーはより直感的で読みやすい形式でテストのタイムアウトを設定できるようになります。
コミット
commit 57c9bb4a07b0ac483935e321ef760c0c52f8efd4
Author: David Symonds <dsymonds@golang.org>
Date: Sun Dec 25 16:07:05 2011 +1100
testing: use flag.Duration for -timeout flag.
R=golang-dev, gustavo, r
CC=golang-dev
https://golang.org/cl/5498077
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/57c9bb4a07b0ac483935e321ef760c0c52f8efd4
元コミット内容
testing: use flag.Duration for -timeout flag.
R=golang-dev, gustavo, r
CC=golang-dev
https://golang.org/cl/5498077
変更の背景
Go言語のテストフレームワークには、テストが無限に実行されるのを防ぐためのタイムアウト機能が備わっています。以前は、このタイムアウトは-test.timeout N
のように、N
に秒数を指定する形式でした。しかし、この形式では、例えば「2分」や「300ミリ秒」といった、より人間が理解しやすい時間単位での指定ができませんでした。また、内部的にはint64
型で秒数を管理していたため、time.Duration
型が提供する時間単位の表現力を活用できていませんでした。
このコミットの背景には、ユーザーエクスペリエンスの向上と、Go言語の標準ライブラリであるtime
パッケージのDuration
型との整合性を高める目的があります。time.Duration
は、時間量を表現するための型であり、"ns", "us", "ms", "s", "m", "h"といった単位をサポートしています。これにより、ユーザーはより直感的で柔軟なタイムアウト指定が可能になります。
前提知識の解説
Go言語のflag
パッケージ
Go言語のflag
パッケージは、コマンドライン引数を解析するための標準ライブラリです。プログラムの起動時にユーザーが指定するオプション(フラグ)を定義し、その値をプログラム内で利用できるようにします。例えば、-timeout
のようなフラグを定義し、その値を取得するためにflag.Int64
やflag.String
などの関数を使用します。このコミットでは、新たにflag.Duration
という関数が利用されています。
Go言語のtime
パッケージとtime.Duration
型
Go言語のtime
パッケージは、時間と日付を扱うための機能を提供します。その中でもtime.Duration
型は、時間の長さを表現するための型です。これはナノ秒単位の整数として内部的に表現されますが、time.ParseDuration
関数やtime.Duration
型のメソッド(例: String()
)を使うことで、"10s"(10秒)や"2m"(2分)のような人間が読みやすい文字列形式と相互変換できます。これにより、時間に関する処理をより安全かつ直感的に記述できるようになります。
Go言語のテストフレームワーク
Go言語には、go test
コマンドを通じて実行される組み込みのテストフレームワークがあります。開発者は_test.go
というサフィックスを持つファイルにテストコードを記述し、testing
パッケージの機能を利用してユニットテスト、ベンチマークテスト、サンプルコードなどを実行します。-test.timeout
フラグは、このテスト実行全体または個々のテストの実行時間に上限を設けるために使用されます。
技術的詳細
このコミットの主要な変更点は、-test.timeout
フラグの型をint64
からtime.Duration
に変更したことです。
-
flag.Int64
からflag.Duration
への変更:src/pkg/testing/testing.go
において、timeout
変数の定義がflag.Int64("test.timeout", 0, ...)
からflag.Duration("test.timeout", 0, ...)
に変更されました。flag.Duration
は、コマンドラインから"10s"や"2m"のような文字列を受け取り、それをtime.Duration
型にパースして変数に格納します。これにより、ユーザーはより自然な時間単位でタイムアウトを指定できるようになります。
-
time.Duration
型の直接利用:- 以前は、
*timeout
(int64
型)に秒数が格納されており、time.Duration(*timeout)*time.Second
のようにtime.Second
を掛けてtime.Duration
型に変換していました。 - 変更後は、
*timeout
自体がtime.Duration
型であるため、time.AfterFunc(*timeout, alarm)
のように直接time.AfterFunc
に渡すことができるようになりました。これにより、コードがより簡潔になり、型変換の誤りを防ぐことができます。
- 以前は、
-
ドキュメントと使用例の更新:
src/cmd/go/test.go
とsrc/cmd/gotest/doc.go
のドキュメントが更新され、-test.timeout
フラグの引数が「n秒」から「t(期間)」へと変更されました。src/Make.pkg
では、testshort
ターゲットの-test.timeout
の値が120
(秒)から2m
(2分)に変更され、新しい使用法が反映されています。これは、ビルドシステムやスクリプトが新しい形式に対応する必要があることを示しています。
この変更により、Goのテストフレームワークは、時間指定に関してより堅牢でユーザーフレンドリーなインターフェースを提供するようになりました。
コアとなるコードの変更箇所
src/Make.pkg
--- a/src/Make.pkg
+++ b/src/Make.pkg
@@ -65,7 +65,7 @@ test:
gotest
testshort:
- gotest -test.short -test.timeout=120
+ gotest -test.short -test.timeout=2m
bench:
gotest -test.bench=. -test.run="Do not run tests"
src/cmd/go/test.go
--- a/src/cmd/go/test.go
+++ b/src/cmd/go/test.go
@@ -118,8 +118,8 @@ The resulting test binary, called test.out, has its own flags:
the Go tree can run a sanity check but not spend time running
exhaustive tests.
-\t-test.timeout n
-\t\tIf a test runs longer than n seconds, panic.
+\t-test.timeout t
+\t\tIf a test runs longer than t, panic.
\t-test.benchtime n
\t\tRun enough iterations of each benchmark to take n seconds.
src/cmd/gotest/doc.go
--- a/src/cmd/gotest/doc.go
+++ b/src/cmd/gotest/doc.go
@@ -75,7 +75,7 @@ Usage:
\t\t[-test.cpuprofile=cpu.out] \\\
\t\t[-test.memprofile=mem.out] [-test.memprofilerate=1] \\\
\t\t[-test.parallel=$GOMAXPROCS] \\\
-\t\t[-test.timeout=10] [-test.short] \\\
+\t\t[-test.timeout=10s] [-test.short] \\\
\t\t[-test.benchtime=3] [-test.cpu=1,2,3,4]\n
The -test.v flag causes the tests to be logged as they run. The
@@ -117,7 +117,7 @@ time. It is off by default but set by all.bash so installations of
the Go tree can do a sanity check but not spend time running
exhaustive tests.\n
-The -test.timeout flag sets a timeout for the test in seconds. If the
+The -test.timeout flag sets a timeout for the test. If the
test runs for longer than that, it will panic, dumping a stack trace
of all existing goroutines.
src/pkg/testing/testing.go
--- a/src/pkg/testing/testing.go
+++ b/src/pkg/testing/testing.go
@@ -63,7 +63,7 @@ var (
memProfile = flag.String("test.memprofile", "", "write a memory profile to the named file after execution")
memProfileRate = flag.Int("test.memprofilerate", 0, "if >=0, sets runtime.MemProfileRate")
cpuProfile = flag.String("test.cpuprofile", "", "write a cpu profile to the named file during execution")
-\ttimeout = flag.Int64("test.timeout", 0, "if > 0, sets time limit for tests in seconds")
+\ttimeout = flag.Duration("test.timeout", 0, "if positive, sets an aggregate time limit for all tests")
cpuListStr = flag.String("test.cpu", "", "comma-separated list of number of CPUs to use for each test")
parallel = flag.Int("test.parallel", runtime.GOMAXPROCS(0), "maximum test parallelism")
@@ -346,7 +346,7 @@ var timer *time.Timer
// startAlarm starts an alarm if requested.
func startAlarm() {
if *timeout > 0 {
-\t\ttimer = time.AfterFunc(time.Duration(*timeout)*time.Second, alarm)
+\t\ttimer = time.AfterFunc(*timeout, alarm)
}
}
コアとなるコードの解説
src/pkg/testing/testing.go
-
timeout = flag.Duration("test.timeout", 0, "if positive, sets an aggregate time limit for all tests")
:- この行が、
-test.timeout
フラグの型をint64
からtime.Duration
に変更する核心部分です。flag.Duration
関数を使用することで、コマンドラインから"10s"や"2m"のような時間文字列を直接受け取り、それをtime.Duration
型の変数timeout
にパースして格納するようになります。これにより、時間単位の指定がより直感的になります。 - コメントも「秒単位でテストの時間制限を設定する」から「すべてのテストの集計時間制限を設定する」に変更され、
time.Duration
が単一のテストではなく、テストスイート全体の時間制限を意味することが明確化されています。
- この行が、
-
timer = time.AfterFunc(*timeout, alarm)
:- 以前は
time.Duration(*timeout)*time.Second
のように、int64
型の*timeout
にtime.Second
を掛けてtime.Duration
型に変換していました。 - 変更後は、
timeout
変数がすでにtime.Duration
型であるため、*timeout
を直接time.AfterFunc
に渡すことができます。これにより、コードが簡潔になり、意図がより明確になります。time.AfterFunc
は指定された期間が経過した後にalarm
関数を実行するタイマーを設定します。
- 以前は
src/cmd/go/test.go
および src/cmd/gotest/doc.go
- これらのファイルは、
go test
コマンドおよびgotest
コマンドのヘルプメッセージとドキュメントを更新しています。 -test.timeout
フラグの説明が「n秒」から「t(期間)」に変更され、新しい時間指定形式(例: "10s")が示されています。これは、ユーザーが新しい形式でタイムアウトを指定する必要があることを明確に伝えるための変更です。
src/Make.pkg
testshort
ターゲットの-test.timeout
の値が120
から2m
に変更されています。これは、ビルドスクリプトやMakefileのような自動化された環境でも、新しいtime.Duration
形式を使用するように更新する必要があることを示す具体的な例です。2m
は2分を意味し、以前の120秒と同じ期間を表しますが、より読みやすくなっています。
これらの変更は全体として、Goのテストフレームワークにおけるタイムアウト機能の使いやすさと堅牢性を向上させています。
関連リンク
参考にした情報源リンク
- Go言語のtimeパッケージ
- Go言語のflagパッケージ
- Go言語のtestingパッケージ
- Go言語のコマンドライン引数とflagパッケージ (一般的な
flag
パッケージの解説として) - Go言語のDuration型について (
time.Duration
の概念理解のために)