Skip to content

Commit d5e53fa

Browse files
committed
Fix benchtime too long leads timeout :
1. handles overflows 2. add an unit test
1 parent 0985990 commit d5e53fa

File tree

2 files changed

+54
-28
lines changed

2 files changed

+54
-28
lines changed

src/testing/benchmark.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -323,10 +323,17 @@ func (b *B) launch() {
323323
// which can hide an order of magnitude in execution time.
324324
// So multiply first, then divide.
325325
n = goalns * prevIters / prevns
326-
// Run more iterations than we think we'll need (1.2x).
327-
n += n / 5
328-
// Don't grow too fast in case we had timing errors previously.
329-
n = min(n, 100*last)
326+
// Can't restore goalns means overflows.
327+
if n*prevns/prevIters != goalns {
328+
// Overflows means need to be executed many many times,
329+
// otherwise it is easy to be timeout.
330+
n = 100 * last
331+
} else {
332+
// Run more iterations than we think we'll need (1.2x).
333+
n += n / 5
334+
// Don't grow too fast in case we had timing errors previously.
335+
n = min(n, 100*last)
336+
}
330337
// Be sure to run at least one more than last time.
331338
n = max(n, last+1)
332339
// Don't run more than 1e9 times. (This also keeps n in int range on 32 bit platforms.)

src/testing/benchmark_test.go

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
package testing_test
5+
package testing
66

77
import (
88
"bytes"
99
"runtime"
1010
"sort"
1111
"strings"
1212
"sync/atomic"
13-
"testing"
1413
"text/template"
1514
"time"
1615
)
@@ -32,19 +31,19 @@ var prettyPrintTests = []struct {
3231
{0.0000999949999, " 0.0001000 x"},
3332
}
3433

35-
func TestPrettyPrint(t *testing.T) {
34+
func TestPrettyPrint(t *T) {
3635
for _, tt := range prettyPrintTests {
3736
buf := new(strings.Builder)
38-
testing.PrettyPrint(buf, tt.v, "x")
37+
PrettyPrint(buf, tt.v, "x")
3938
if tt.expected != buf.String() {
4039
t.Errorf("prettyPrint(%v): expected %q, actual %q", tt.v, tt.expected, buf.String())
4140
}
4241
}
4342
}
4443

45-
func TestResultString(t *testing.T) {
44+
func TestResultString(t *T) {
4645
// Test fractional ns/op handling
47-
r := testing.BenchmarkResult{
46+
r := BenchmarkResult{
4847
N: 100,
4948
T: 240 * time.Nanosecond,
5049
}
@@ -68,15 +67,15 @@ func TestResultString(t *testing.T) {
6867
}
6968
}
7069

71-
func TestRunParallel(t *testing.T) {
72-
if testing.Short() {
70+
func TestRunParallel(t *T) {
71+
if Short() {
7372
t.Skip("skipping in short mode")
7473
}
75-
testing.Benchmark(func(b *testing.B) {
74+
Benchmark(func(b *B) {
7675
procs := uint32(0)
7776
iters := uint64(0)
7877
b.SetParallelism(3)
79-
b.RunParallel(func(pb *testing.PB) {
78+
b.RunParallel(func(pb *PB) {
8079
atomic.AddUint32(&procs, 1)
8180
for pb.Next() {
8281
atomic.AddUint64(&iters, 1)
@@ -91,9 +90,9 @@ func TestRunParallel(t *testing.T) {
9190
})
9291
}
9392

94-
func TestRunParallelFail(t *testing.T) {
95-
testing.Benchmark(func(b *testing.B) {
96-
b.RunParallel(func(pb *testing.PB) {
93+
func TestRunParallelFail(t *T) {
94+
Benchmark(func(b *B) {
95+
b.RunParallel(func(pb *PB) {
9796
// The function must be able to log/abort
9897
// w/o crashing/deadlocking the whole benchmark.
9998
b.Log("log")
@@ -102,9 +101,9 @@ func TestRunParallelFail(t *testing.T) {
102101
})
103102
}
104103

105-
func TestRunParallelFatal(t *testing.T) {
106-
testing.Benchmark(func(b *testing.B) {
107-
b.RunParallel(func(pb *testing.PB) {
104+
func TestRunParallelFatal(t *T) {
105+
Benchmark(func(b *B) {
106+
b.RunParallel(func(pb *PB) {
108107
for pb.Next() {
109108
if b.N > 1 {
110109
b.Fatal("error")
@@ -114,9 +113,9 @@ func TestRunParallelFatal(t *testing.T) {
114113
})
115114
}
116115

117-
func TestRunParallelSkipNow(t *testing.T) {
118-
testing.Benchmark(func(b *testing.B) {
119-
b.RunParallel(func(pb *testing.PB) {
116+
func TestRunParallelSkipNow(t *T) {
117+
Benchmark(func(b *B) {
118+
b.RunParallel(func(pb *PB) {
120119
for pb.Next() {
121120
if b.N > 1 {
122121
b.SkipNow()
@@ -128,11 +127,11 @@ func TestRunParallelSkipNow(t *testing.T) {
128127

129128
func ExampleB_RunParallel() {
130129
// Parallel benchmark for text/template.Template.Execute on a single object.
131-
testing.Benchmark(func(b *testing.B) {
130+
Benchmark(func(b *B) {
132131
templ := template.Must(template.New("test").Parse("Hello, {{.}}!"))
133132
// RunParallel will create GOMAXPROCS goroutines
134133
// and distribute work among them.
135-
b.RunParallel(func(pb *testing.PB) {
134+
b.RunParallel(func(pb *PB) {
136135
// Each goroutine has its own bytes.Buffer.
137136
var buf bytes.Buffer
138137
for pb.Next() {
@@ -144,8 +143,8 @@ func ExampleB_RunParallel() {
144143
})
145144
}
146145

147-
func TestReportMetric(t *testing.T) {
148-
res := testing.Benchmark(func(b *testing.B) {
146+
func TestReportMetric(t *T) {
147+
res := Benchmark(func(b *B) {
149148
b.ReportMetric(12345, "ns/op")
150149
b.ReportMetric(0.2, "frobs/op")
151150
})
@@ -164,7 +163,7 @@ func TestReportMetric(t *testing.T) {
164163
func ExampleB_ReportMetric() {
165164
// This reports a custom benchmark metric relevant to a
166165
// specific algorithm (in this case, sorting).
167-
testing.Benchmark(func(b *testing.B) {
166+
Benchmark(func(b *B) {
168167
var compares int64
169168
for i := 0; i < b.N; i++ {
170169
s := []int{5, 4, 3, 2, 1}
@@ -178,3 +177,23 @@ func ExampleB_ReportMetric() {
178177
b.ReportMetric(float64(compares)/float64(b.N), "compares/op")
179178
})
180179
}
180+
181+
func TestBenchmarkLaunch(t *T) {
182+
tmp := benchTime
183+
t.cleanups = append(t.cleanups, func() {
184+
t.Logf("reset benchTime")
185+
benchTime = tmp
186+
})
187+
// Set a long benchtime.
188+
benchTime = durationOrCountFlag{
189+
d: 150 * time.Second,
190+
}
191+
var try int32 = 0
192+
Benchmark(func(b *B) {
193+
c := atomic.AddInt32(&try, 1)
194+
t.Logf("try %d %d\n", c, b.N)
195+
if c > 6 {
196+
t.Fatalf("benchmark try to many times %d", c)
197+
}
198+
})
199+
}

0 commit comments

Comments
 (0)