Source file
src/testing/loop_test.go
1
2
3
4
5 package testing
6
7 import (
8 "bytes"
9 "strings"
10 "time"
11 )
12
13
14
15 func TestBenchmarkBLoop(t *T) {
16 var initialStart highPrecisionTime
17 var firstStart highPrecisionTime
18 var scaledStart highPrecisionTime
19 var runningEnd bool
20 runs := 0
21 iters := 0
22 firstBN := 0
23 restBN := 0
24 finalBN := 0
25 bRet := Benchmark(func(b *B) {
26 initialStart = b.start
27 runs++
28 for b.Loop() {
29 if iters == 0 {
30 firstStart = b.start
31 firstBN = b.N
32 } else {
33 restBN = max(restBN, b.N)
34 }
35 if iters == 1 {
36 scaledStart = b.start
37 }
38 iters++
39 }
40 finalBN = b.N
41 runningEnd = b.timerOn
42 })
43
44 if runs != 1 {
45 t.Errorf("want runs == 1, got %d", runs)
46 }
47
48 if iters == 0 {
49 t.Fatalf("no iterations ran")
50 }
51
52 if finalBN != iters || bRet.N != iters {
53 t.Errorf("benchmark iterations mismatch: %d loop iterations, final b.N=%d, bRet.N=%d", iters, finalBN, bRet.N)
54 }
55
56 if firstBN != 0 {
57 t.Errorf("want b.N == 0 on first iteration, got %d", firstBN)
58 }
59 if restBN != 0 {
60 t.Errorf("want b.N == 0 on subsequent iterations, got %d", restBN)
61 }
62
63 if bRet.T < benchTime.d {
64 t.Fatalf("benchmark ran for %s, want >= %s", bRet.T, benchTime.d)
65 }
66
67 if firstStart == initialStart {
68 t.Errorf("b.Loop did not reset the timer")
69 }
70 if scaledStart != firstStart {
71 t.Errorf("b.Loop stops and restarts the timer during iteration")
72 }
73
74 if runningEnd {
75 t.Errorf("timer was still running after last iteration")
76 }
77 }
78
79 func TestBenchmarkBLoopCheapEarlyTerminate(t *T) {
80 if Short() {
81 t.Skip("B.Loop test needs to run for > 1s to saturate 1e9 iterations")
82 }
83 runCnt := 0
84
85
86
87
88
89
90 const maxBenchTime = time.Second * 30
91 res := Benchmark(func(b *B) {
92
93 b.benchTime.d = maxBenchTime
94 for b.Loop() {
95 runCnt++
96 }
97 })
98 if runCnt > maxBenchPredictIters {
99 t.Errorf("loop body ran more than max (%d) times: %d", maxBenchPredictIters, runCnt)
100 if res.T >= maxBenchTime {
101 t.Logf("cheap benchmark exhausted time budget: %s; ran for %s", maxBenchTime, res.T)
102 }
103 }
104
105 if res.N != runCnt {
106 t.Errorf("disagreeing loop counts: res.N reported %d, while b.Loop() iterated %d times", res.N, runCnt)
107 }
108
109 if res.N > maxBenchPredictIters {
110 t.Errorf("benchmark result claims more runs than max (%d) times: %d", maxBenchPredictIters, res.N)
111 }
112
113 }
114
115 func TestBenchmarkBLoopBreak(t *T) {
116 var bState *B
117 var bLog bytes.Buffer
118 bRet := Benchmark(func(b *B) {
119
120
121 bState = b
122 b.common.w = &bLog
123
124 for i := 0; b.Loop(); i++ {
125 if i == 2 {
126 break
127 }
128 }
129 })
130 if !bState.failed {
131 t.Errorf("benchmark should have failed")
132 }
133 const wantLog = "benchmark function returned without B.Loop"
134 if log := bLog.String(); !strings.Contains(log, wantLog) {
135 t.Errorf("missing error %q in output:\n%s", wantLog, log)
136 }
137
138
139 if bRet.N != 0 {
140 t.Errorf("want N == 0, got %d", bRet.N)
141 }
142 }
143
144 func TestBenchmarkBLoopError(t *T) {
145
146
147 var bState *B
148 var bLog bytes.Buffer
149 bRet := Benchmark(func(b *B) {
150 bState = b
151 b.common.w = &bLog
152
153 for i := 0; b.Loop(); i++ {
154 b.Error("error")
155 return
156 }
157 })
158 if !bState.failed {
159 t.Errorf("benchmark should have failed")
160 }
161 const noWantLog = "benchmark function returned without B.Loop"
162 if log := bLog.String(); strings.Contains(log, noWantLog) {
163 t.Errorf("unexpected error %q in output:\n%s", noWantLog, log)
164 }
165 if bRet.N != 0 {
166 t.Errorf("want N == 0, got %d", bRet.N)
167 }
168 }
169
170 func TestBenchmarkBLoopStop(t *T) {
171 var bState *B
172 var bLog bytes.Buffer
173 bRet := Benchmark(func(b *B) {
174 bState = b
175 b.common.w = &bLog
176
177 for i := 0; b.Loop(); i++ {
178 b.StopTimer()
179 }
180 })
181 if !bState.failed {
182 t.Errorf("benchmark should have failed")
183 }
184 const wantLog = "B.Loop called with timer stopped"
185 if log := bLog.String(); !strings.Contains(log, wantLog) {
186 t.Errorf("missing error %q in output:\n%s", wantLog, log)
187 }
188 if bRet.N != 0 {
189 t.Errorf("want N == 0, got %d", bRet.N)
190 }
191 }
192
View as plain text