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

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

このコミットは、Go言語の標準ライブラリにおけるテストの実行時間を短縮することを目的としています。特に、go test -short フラグを使用した際のテスト実行が大幅に加速されるように、runtime パッケージと time パッケージ内のテストファイルが修正されています。これにより、開発者がテストをより迅速に実行できるようになり、開発サイクル全体の効率が向上します。

コミット

commit 2a6e6999a45a88999930cd879c919f6b93aaa868
Author: Rémy Oudompheng <oudomphe@phare.normalesup.org>
Date:   Tue Feb 14 22:13:19 2012 +0100

    runtime, time: accelerate tests in short mode.
    
                                       before   after
    go test -short time                4.144s  1.215s
    go test -short runtime             1.315s  0.351s
    go test -short -cpu=1,2,4 runtime  4.376s  1.266s
    
    Partially solves issue 3015.
    
    R=golang-dev, r
    CC=golang-dev, remy
    https://golang.org/cl/5673045

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

https://github.com/golang/go/commit/2a6e6999a45a88999930cd879c919f6b93aaa868

元コミット内容

このコミットの元の内容は、runtime および time パッケージのテストを「ショートモード」で高速化することです。具体的には、go test -short コマンドでテストを実行した際の時間が大幅に短縮されたことが示されています。

  • go test -short time: 4.144秒 → 1.215秒
  • go test -short runtime: 1.315秒 → 0.351秒
  • go test -short -cpu=1,2,4 runtime: 4.376秒 → 1.266秒

この変更は、GoのIssue 3015を部分的に解決するものです。

変更の背景

この変更の背景には、Go言語のテストスイートの実行時間が長くなるという問題がありました。特に、開発中に頻繁に実行されるテストにおいて、その実行時間が長いと開発者の生産性が低下します。go test -short フラグは、このような状況に対応するために、時間のかかるテストの一部をスキップしたり、テストの反復回数を減らしたりして、テストを高速化するためのメカニズムを提供します。

このコミットは、runtime パッケージ(ガベージコレクションのテストなど)と time パッケージ(時間関連の機能テストなど)におけるテストが、ショートモードで実行された際に期待通りに高速化されていないという課題に対応しています。コミットメッセージに記載されている「Partially solves issue 3015」は、この問題がGoのIssueトラッカーで追跡されていたことを示唆しています。Issue 3015は、go test -short が一部のテストで期待されるほど高速化されないというパフォーマンスの問題に関するものでした。このコミットは、その問題に対する具体的な改善策として、テストの反復回数や待機時間を調整することで、テストの実行時間を短縮しています。

前提知識の解説

Go言語のテスト

Go言語には、標準でテストフレームワークが組み込まれており、go test コマンドを使用してテストを実行します。テストファイルは通常、テスト対象のファイルと同じディレクトリに _test.go というサフィックスを付けて配置されます。

go test -short フラグ

go test -short は、Goのテストコマンド go test に渡すことができるフラグの一つです。このフラグを使用すると、テストコード内で testing.Short() 関数を呼び出すことで、テストがショートモードで実行されているかどうかを判定できます。開発者は、この判定結果に基づいて、時間のかかるテスト(例: 多数の反復を伴うテスト、長いスリープを伴うテスト、外部リソースへのアクセスを伴うテストなど)の実行ロジックを調整し、テスト時間を短縮することができます。

例えば、通常モードでは100万回のループを実行するテストを、ショートモードでは10万回に減らす、といった最適化が可能です。これにより、CI/CDパイプラインでのフルテスト実行は時間がかかっても、開発者がローカルで頻繁にテストを実行する際には高速なフィードバックを得られるようになります。

testing.Short() 関数

testing.Short() は、Goの testing パッケージで提供される関数です。この関数は、go test -short フラグが指定されてテストが実行された場合に true を返します。テストコード内でこの関数の戻り値を確認することで、テストの実行モードに応じた条件分岐を行うことができます。

time.Durationtime.Millisecond

Go言語の time パッケージは、時間に関する操作を提供します。time.Duration は時間の長さを表す型で、time.Millisecond はミリ秒を表す time.Duration の定数です。例えば、100 * time.Millisecond は100ミリ秒の時間を表します。テストにおいて、time.Sleep などで待機時間を設定する際にこれらの定数が使用されます。

技術的詳細

このコミットの技術的な詳細は、主に以下の3つのテストファイルにおける条件付きロジックの導入と、時間関連の定数の調整にあります。

  1. src/pkg/runtime/gc_test.go:

    • TestGcSys 関数において、ガベージコレクションのテストにおける反復回数を制御しています。
    • 通常モードでは itercount1000000 (100万回) ですが、testing.Short()true の場合(ショートモードの場合)は 100000 (10万回) に減らされます。これにより、ガベージコレクションのテストが大幅に高速化されます。
  2. src/pkg/time/sleep_test.go:

    • TestAfter および TestAfterTick 関数において、time.Aftertime.Tick のテストにおける待機時間 Delta を調整しています。
    • 通常モードでは Delta100 * Millisecond (100ミリ秒) ですが、ショートモードでは 10 * Millisecond (10ミリ秒) に短縮されます。
    • testAfterQueuing 関数でも同様に、Delta が通常モードの 100 * Millisecond からショートモードの 20 * Millisecond に変更されています。
    • これにより、時間ベースのテストがより短い間隔で実行され、テスト全体の時間が短縮されます。
  3. src/pkg/time/tick_test.go:

    • TestTicker 関数において、time.NewTicker のテストにおける待機時間 Delta を調整しています。
    • 通常モードでは Delta100 * Millisecond (100ミリ秒) ですが、ショートモードでは 10 * Millisecond (10ミリ秒) に短縮されます。
    • TestTeardown 関数でも同様に、time.NewTicker の引数である Delta が通常モードの 1e8 (100ミリ秒) からショートモードの 20 * Millisecond に変更されています。
    • これにより、Ticker のテストも高速化されます。

これらの変更は、testing.Short() の結果に基づいてテストの実行パラメータを動的に変更するという、Go言語のテストにおける一般的な最適化パターンを適用したものです。

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

src/pkg/runtime/gc_test.go

--- a/src/pkg/runtime/gc_test.go
+++ b/src/pkg/runtime/gc_test.go
@@ -15,7 +15,11 @@ func TestGcSys(t *testing.T) {
 	runtime.ReadMemStats(memstats)
 	sys := memstats.Sys
 
-	for i := 0; i < 1000000; i++ {
+	itercount := 1000000
+	if testing.Short() {
+		itercount = 100000
+	}
+	for i := 0; i < itercount; i++ {
 		workthegc()
 	}
 

src/pkg/time/sleep_test.go

--- a/src/pkg/time/sleep_test.go
+++ b/src/pkg/time/sleep_test.go
@@ -108,10 +108,11 @@ func TestAfter(t *testing.T) {
 }
 
 func TestAfterTick(t *testing.T) {
-	const (
-		Delta = 100 * Millisecond
-		Count = 10
-	)
+	const Count = 10
+	Delta := 100 * Millisecond
+	if testing.Short() {
+		Delta = 10 * Millisecond
+	}
 	t0 := Now()
 	for i := 0; i < Count; i++ {
 		<-After(Delta)
@@ -176,9 +177,10 @@ func await(slot int, result chan<- afterResult, ac <-chan Time) {
 }
 
 func testAfterQueuing(t *testing.T) error {
-	const (
-		Delta = 100 * Millisecond
-	)
+	Delta := 100 * Millisecond
+	if testing.Short() {
+		Delta = 20 * Millisecond
+	}
 	// make the result channel buffered because we don't want
 	// to depend on channel queueing semantics that might
 	// possibly change in the future.

src/pkg/time/tick_test.go

--- a/src/pkg/time/tick_test.go
+++ b/src/pkg/time/tick_test.go
@@ -10,10 +10,11 @@ import (
 )
 
 func TestTicker(t *testing.T) {
-	const (
-		Delta = 100 * Millisecond
-		Count = 10
-	)
+	const Count = 10
+	Delta := 100 * Millisecond
+	if testing.Short() {
+		Delta = 10 * Millisecond
+	}
 	ticker := NewTicker(Delta)
 	t0 := Now()
 	for i := 0; i < Count; i++ {
@@ -39,8 +40,12 @@ func TestTicker(t *testing.T) {
 
 // Test that a bug tearing down a ticker has been fixed.  This routine should not deadlock.\n func TestTeardown(t *testing.T) {
+\tDelta := 100 * Millisecond
+\tif testing.Short() {
+\t\tDelta = 20 * Millisecond
+\t}\n \tfor i := 0; i < 3; i++ {\n-\t\tticker := NewTicker(1e8)\n+\t\tticker := NewTicker(Delta)\n \t\t<-ticker.C\n \t\tticker.Stop()\n \t}\n```

## コアとなるコードの解説

### `src/pkg/runtime/gc_test.go` の変更

`TestGcSys` 関数は、ガベージコレクションのシステムコールに関するテストです。元のコードでは、`for` ループが常に100万回実行されていました。

変更後、`itercount` という変数が導入され、その初期値は100万回です。しかし、`if testing.Short() { itercount = 100000 }` という条件分岐が追加されました。これにより、`go test -short` フラグが指定されている場合、`itercount` は10万回に設定されます。結果として、ショートモードでのテスト実行時にはループの回数が10分の1になり、テスト時間が大幅に短縮されます。

### `src/pkg/time/sleep_test.go` の変更

`TestAfterTick` 関数は、`time.After` と `time.Tick` の動作をテストします。元のコードでは、`Delta` という定数が `100 * Millisecond` とハードコードされていました。

変更後、`Delta` は定数ではなく変数として宣言され、初期値は `100 * Millisecond` です。しかし、`if testing.Short() { Delta = 10 * Millisecond }` という条件分岐が追加され、ショートモードでは `Delta` が `10 * Millisecond` に短縮されます。これにより、テスト内の待機時間が短くなり、テストが高速化されます。

同様に、`testAfterQueuing` 関数でも `Delta` が変数化され、ショートモードでは `20 * Millisecond` に設定されるよう変更されています。

### `src/pkg/time/tick_test.go` の変更

`TestTicker` 関数は `time.NewTicker` の動作をテストします。`TestAfterTick` と同様に、`Delta` が定数から変数に変更され、ショートモードでは `10 * Millisecond` に短縮されます。

`TestTeardown` 関数は、`Ticker` のシャットダウンに関するバグが修正されたことをテストします。ここでも `time.NewTicker` の引数として渡される時間が、ショートモードでは `20 * Millisecond` に短縮されるように変更されています。元のコードでは `1e8` (100ミリ秒) が直接渡されていましたが、これも `Delta` 変数を通じて制御されるようになりました。

これらの変更はすべて、`testing.Short()` の結果に基づいてテストの実行パラメータ(反復回数や待機時間)を動的に調整することで、`go test -short` コマンド使用時のテスト実行時間を最適化するという共通のパターンに従っています。

## 関連リンク

*   Go言語のテストに関する公式ドキュメント: [https://go.dev/doc/code#Testing](https://go.dev/doc/code#Testing)
*   `testing` パッケージのドキュメント: [https://pkg.go.dev/testing](https://pkg.go.dev/testing)
*   GoのIssue 3015 (関連する可能性のあるIssue): [https://github.com/golang/go/issues/3015](https://github.com/golang/go/issues/3015) (※このコミットが解決した具体的なIssue 3015は、コミット当時のGoのIssueトラッカーで確認する必要がありますが、一般的なパフォーマンス改善のIssueとして参照しています。)

## 参考にした情報源リンク

*   Go言語の公式ドキュメント
*   Go言語の `testing` パッケージのソースコードとドキュメント
*   Go言語のコミット履歴と関連するコードレビュー (Go CL 5673045)
*   `go test -short` の動作に関する一般的なGoコミュニティの議論とベストプラクティス
# [インデックス 11903] ファイルの概要

このコミットは、Go言語の標準ライブラリにおけるテストの実行時間を短縮することを目的としています。特に、`go test -short` フラグを使用した際のテスト実行が大幅に加速されるように、`runtime` パッケージと `time` パッケージ内のテストファイルが修正されています。これにより、開発者がテストをより迅速に実行できるようになり、開発サイクル全体の効率が向上します。

## コミット

commit 2a6e6999a45a88999930cd879c919f6b93aaa868 Author: Rémy Oudompheng oudomphe@phare.normalesup.org Date: Tue Feb 14 22:13:19 2012 +0100

runtime, time: accelerate tests in short mode.

                                   before   after
go test -short time                4.144s  1.215s
go test -short runtime             1.315s  0.351s
go test -short -cpu=1,2,4 runtime  4.376s  1.266s

Partially solves issue 3015.

R=golang-dev, r
CC=golang-dev, remy
https://golang.org/cl/5673045

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

[https://github.com/golang/go/commit/2a6e6999a45a88999930cd879c919f6b93aaa868](https://github.com/golang/go/commit/2a6e6999a45a88999930cd879c919f6b93aaa868)

## 元コミット内容

このコミットの元の内容は、`runtime` および `time` パッケージのテストを「ショートモード」で高速化することです。具体的には、`go test -short` コマンドでテストを実行した際の時間が大幅に短縮されたことが示されています。

- `go test -short time`: 4.144秒 → 1.215秒
- `go test -short runtime`: 1.315秒 → 0.351秒
- `go test -short -cpu=1,2,4 runtime`: 4.376秒 → 1.266秒

この変更は、GoのIssue 3015を部分的に解決するものです。

## 変更の背景

この変更の背景には、Go言語のテストスイートの実行時間が長くなるという問題がありました。特に、開発中に頻繁に実行されるテストにおいて、その実行時間が長いと開発者の生産性が低下します。`go test -short` フラグは、このような状況に対応するために、時間のかかるテストの一部をスキップしたり、テストの反復回数を減らしたりして、テストを高速化するためのメカニズムを提供します。

このコミットは、`runtime` パッケージ(ガベージコレクションのテストなど)と `time` パッケージ(時間関連の機能テストなど)におけるテストが、ショートモードで実行された際に期待通りに高速化されていないという課題に対応しています。コミットメッセージに記載されている「Partially solves issue 3015」は、この問題がGoのIssueトラッカーで追跡されていたことを示唆しています。Issue 3015は、`go test -short` が一部のテストで期待されるほど高速化されないというパフォーマンスの問題に関するものでした。このコミットは、その問題に対する具体的な改善策として、テストの反復回数や待機時間を調整することで、テストの実行時間を短縮しています。

## 前提知識の解説

### Go言語のテスト

Go言語には、標準でテストフレームワークが組み込まれており、`go test` コマンドを使用してテストを実行します。テストファイルは通常、テスト対象のファイルと同じディレクトリに `_test.go` というサフィックスを付けて配置されます。

### `go test -short` フラグ

`go test -short` は、Goのテストコマンド `go test` に渡すことができるフラグの一つです。このフラグを使用すると、テストコード内で `testing.Short()` 関数を呼び出すことで、テストがショートモードで実行されているかどうかを判定できます。開発者は、この判定結果に基づいて、時間のかかるテスト(例: 多数の反復を伴うテスト、長いスリープを伴うテスト、外部リソースへのアクセスを伴うテストなど)の実行ロジックを調整し、テスト時間を短縮することができます。

例えば、通常モードでは100万回のループを実行するテストを、ショートモードでは10万回に減らす、といった最適化が可能です。これにより、CI/CDパイプラインでのフルテスト実行は時間がかかっても、開発者がローカルで頻繁にテストを実行する際には高速なフィードバックを得られるようになります。

### `testing.Short()` 関数

`testing.Short()` は、Goの `testing` パッケージで提供される関数です。この関数は、`go test -short` フラグが指定されてテストが実行された場合に `true` を返します。テストコード内でこの関数の戻り値を確認することで、テストの実行モードに応じた条件分岐を行うことができます。

### `time.Duration` と `time.Millisecond`

Go言語の `time` パッケージは、時間に関する操作を提供します。`time.Duration` は時間の長さを表す型で、`time.Millisecond` はミリ秒を表す `time.Duration` の定数です。例えば、`100 * time.Millisecond` は100ミリ秒の時間を表します。テストにおいて、`time.Sleep` などで待機時間を設定する際にこれらの定数が使用されます。

## 技術的詳細

このコミットの技術的な詳細は、主に以下の3つのテストファイルにおける条件付きロジックの導入と、時間関連の定数の調整にあります。

1.  **`src/pkg/runtime/gc_test.go`**:
    *   `TestGcSys` 関数において、ガベージコレクションのテストにおける反復回数を制御しています。
    *   通常モードでは `itercount` が `1000000` (100万回) ですが、`testing.Short()` が `true` の場合(ショートモードの場合)は `100000` (10万回) に減らされます。これにより、ガベージコレクションのテストが大幅に高速化されます。

2.  **`src/pkg/time/sleep_test.go`**:
    *   `TestAfter` および `TestAfterTick` 関数において、`time.After` や `time.Tick` のテストにおける待機時間 `Delta` を調整しています。
    *   通常モードでは `Delta` が `100 * Millisecond` (100ミリ秒) ですが、ショートモードでは `10 * Millisecond` (10ミリ秒) に短縮されます。
    *   `testAfterQueuing` 関数でも同様に、`Delta` が通常モードの `100 * Millisecond` からショートモードの `20 * Millisecond` に変更されています。
    *   これにより、時間ベースのテストがより短い間隔で実行され、テスト全体の時間が短縮されます。

3.  **`src/pkg/time/tick_test.go`**:
    *   `TestTicker` 関数において、`time.NewTicker` のテストにおける待機時間 `Delta` を調整しています。
    *   通常モードでは `Delta` が `100 * Millisecond` (100ミリ秒) ですが、ショートモードでは `10 * Millisecond` (10ミリ秒) に短縮されます。
    *   `TestTeardown` 関数でも同様に、`time.NewTicker` の引数である `Delta` が通常モードの `1e8` (100ミリ秒) からショートモードの `20 * Millisecond` に変更されています。
    *   これにより、`Ticker` のテストも高速化されます。

これらの変更は、`testing.Short()` の結果に基づいてテストの実行パラメータを動的に変更するという、Go言語のテストにおける一般的な最適化パターンを適用したものです。

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

### `src/pkg/runtime/gc_test.go`

```diff
--- a/src/pkg/runtime/gc_test.go
+++ b/src/pkg/runtime/gc_test.go
@@ -15,7 +15,11 @@ func TestGcSys(t *testing.T) {
 	runtime.ReadMemStats(memstats)
 	sys := memstats.Sys
 
-	for i := 0; i < 1000000; i++ {
+	itercount := 1000000
+	if testing.Short() {
+		itercount = 100000
+	}
+	for i := 0; i < itercount; i++ {
 		workthegc()
 	}
 

src/pkg/time/sleep_test.go

--- a/src/pkg/time/sleep_test.go
+++ b/src/pkg/time/sleep_test.go
@@ -108,10 +108,11 @@ func TestAfter(t *testing.T) {
 }
 
 func TestAfterTick(t *testing.T) {
-	const (
-		Delta = 100 * Millisecond
-		Count = 10
-	)
+	const Count = 10
+	Delta := 100 * Millisecond
+	if testing.Short() {
+		Delta = 10 * Millisecond
+	}
 	t0 := Now()
 	for i := 0; i < Count; i++ {
 		<-After(Delta)
@@ -176,9 +177,10 @@ func await(slot int, result chan<- afterResult, ac <-chan Time) {
 }
 
 func testAfterQueuing(t *testing.T) error {
-	const (
-		Delta = 100 * Millisecond
-	)
+	Delta := 100 * Millisecond
+	if testing.Short() {
+		Delta = 20 * Millisecond
+	}
 	// make the result channel buffered because we don't want
 	// to depend on channel queueing semantics that might
 	// possibly change in the future.

src/pkg/time/tick_test.go

--- a/src/pkg/time/tick_test.go
+++ b/src/pkg/time/tick_test.go
@@ -10,10 +10,11 @@ import (
 )
 
 func TestTicker(t *testing.T) {
-	const (
-		Delta = 100 * Millisecond
-		Count = 10
-	)
+	const Count = 10
+	Delta := 100 * Millisecond
+	if testing.Short() {
+		Delta = 10 * Millisecond
+	}
 	ticker := NewTicker(Delta)
 	t0 := Now()
 	for i := 0; i < Count; i++ {
@@ -39,8 +40,12 @@ func TestTicker(t *testing.T) {
 
 // Test that a bug tearing down a ticker has been fixed.  This routine should not deadlock.\n func TestTeardown(t *testing.T) {
+\tDelta := 100 * Millisecond
+\tif testing.Short() {
+\t\tDelta = 20 * Millisecond
+\t}\n \tfor i := 0; i < 3; i++ {\n-\t\tticker := NewTicker(1e8)\n+\t\tticker := NewTicker(Delta)\n \t\t<-ticker.C\n \t\tticker.Stop()\n \t}\n```

## コアとなるコードの解説

### `src/pkg/runtime/gc_test.go` の変更

`TestGcSys` 関数は、ガベージコレクションのシステムコールに関するテストです。元のコードでは、`for` ループが常に100万回実行されていました。

変更後、`itercount` という変数が導入され、その初期値は100万回です。しかし、`if testing.Short() { itercount = 100000 }` という条件分岐が追加されました。これにより、`go test -short` フラグが指定されている場合、`itercount` は10万回に設定されます。結果として、ショートモードでのテスト実行時にはループの回数が10分の1になり、テスト時間が大幅に短縮されます。

### `src/pkg/time/sleep_test.go` の変更

`TestAfterTick` 関数は、`time.After` と `time.Tick` の動作をテストします。元のコードでは、`Delta` という定数が `100 * Millisecond` とハードコードされていました。

変更後、`Delta` は定数ではなく変数として宣言され、初期値は `100 * Millisecond` です。しかし、`if testing.Short() { Delta = 10 * Millisecond }` という条件分岐が追加され、ショートモードでは `Delta` が `10 * Millisecond` に短縮されます。これにより、テスト内の待機時間が短くなり、テストが高速化されます。

同様に、`testAfterQueuing` 関数でも `Delta` が変数化され、ショートモードでは `20 * Millisecond` に設定されるよう変更されています。

### `src/pkg/time/tick_test.go` の変更

`TestTicker` 関数は `time.NewTicker` の動作をテストします。`TestAfterTick` と同様に、`Delta` が定数から変数に変更され、ショートモードでは `10 * Millisecond` に短縮されます。

`TestTeardown` 関数は、`Ticker` のシャットダウンに関するバグが修正されたことをテストします。ここでも `time.NewTicker` の引数として渡される時間が、ショートモードでは `20 * Millisecond` に短縮されるように変更されています。元のコードでは `1e8` (100ミリ秒) が直接渡されていましたが、これも `Delta` 変数を通じて制御されるようになりました。

これらの変更はすべて、`testing.Short()` の結果に基づいてテストの実行パラメータ(反復回数や待機時間)を動的に調整することで、`go test -short` コマンド使用時のテスト実行時間を最適化するという共通のパターンに従っています。

## 関連リンク

*   Go言語のテストに関する公式ドキュメント: [https://go.dev/doc/code#Testing](https://go.dev/doc/code#Testing)
*   `testing` パッケージのドキュメント: [https://pkg.go.dev/testing](https://pkg.go.dev/testing)
*   GoのIssue 3015 (関連する可能性のあるIssue): [https://github.com/golang/go/issues/3015](https://github.com/golang/go/issues/3015) (※このコミットが解決した具体的なIssue 3015は、コミット当時のGoのIssueトラッカーで確認する必要がありますが、一般的なパフォーマンス改善のIssueとして参照しています。)

## 参考にした情報源リンク

*   Go言語の公式ドキュメント
*   Go言語の `testing` パッケージのソースコードとドキュメント
*   Go言語のコミット履歴と関連するコードレビュー (Go CL 5673045)
*   `go test -short` の動作に関する一般的なGoコミュニティの議論とベストプラクティス