Skip to content

Commit c46ba91

Browse files
committed
src/testing: support -bench option to run benchmarks matching the given pattern.
1 parent e485688 commit c46ba91

File tree

4 files changed

+79
-16
lines changed

4 files changed

+79
-16
lines changed

main.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ func Build(pkgName, outpath string, options *compileopts.Options) error {
178178

179179
// Test runs the tests in the given package. Returns whether the test passed and
180180
// possibly an error if the test failed to run.
181-
func Test(pkgName string, stdout, stderr io.Writer, options *compileopts.Options, testCompileOnly, testVerbose, testShort bool, testRunRegexp string, outpath string) (bool, error) {
181+
func Test(pkgName string, stdout, stderr io.Writer, options *compileopts.Options, testCompileOnly, testVerbose, testShort bool, testRunRegexp string, testBenchRegexp string, outpath string) (bool, error) {
182182
options.TestConfig.CompileTestBinary = true
183183
config, err := builder.NewConfig(options)
184184
if err != nil {
@@ -209,7 +209,7 @@ func Test(pkgName string, stdout, stderr io.Writer, options *compileopts.Options
209209
}()
210210
start := time.Now()
211211
var err error
212-
passed, err = runPackageTest(config, stdout, stderr, result, testVerbose, testShort, testRunRegexp)
212+
passed, err = runPackageTest(config, stdout, stderr, result, testVerbose, testShort, testRunRegexp, testBenchRegexp)
213213
if err != nil {
214214
return err
215215
}
@@ -235,7 +235,7 @@ func Test(pkgName string, stdout, stderr io.Writer, options *compileopts.Options
235235
// runPackageTest runs a test binary that was previously built. The return
236236
// values are whether the test passed and any errors encountered while trying to
237237
// run the binary.
238-
func runPackageTest(config *compileopts.Config, stdout, stderr io.Writer, result builder.BuildResult, testVerbose, testShort bool, testRunRegexp string) (bool, error) {
238+
func runPackageTest(config *compileopts.Config, stdout, stderr io.Writer, result builder.BuildResult, testVerbose, testShort bool, testRunRegexp string, testBenchRegexp string) (bool, error) {
239239
var cmd *exec.Cmd
240240
if len(config.Target.Emulator) == 0 {
241241
// Run directly.
@@ -249,6 +249,9 @@ func runPackageTest(config *compileopts.Config, stdout, stderr io.Writer, result
249249
if testRunRegexp != "" {
250250
flags = append(flags, "-test.run="+testRunRegexp)
251251
}
252+
if testBenchRegexp != "" {
253+
flags = append(flags, "-test.bench="+testBenchRegexp)
254+
}
252255
cmd = executeCommand(config.Options, result.Binary, flags...)
253256
} else {
254257
// Run in an emulator.
@@ -266,6 +269,9 @@ func runPackageTest(config *compileopts.Config, stdout, stderr io.Writer, result
266269
if testRunRegexp != "" {
267270
args = append(args, "-test.run="+testRunRegexp)
268271
}
272+
if testBenchRegexp != "" {
273+
args = append(args, "-test.bench="+testBenchRegexp)
274+
}
269275
}
270276
cmd = executeCommand(config.Options, config.Target.Emulator[0], args...)
271277
}
@@ -1189,12 +1195,14 @@ func main() {
11891195
flag.StringVar(&outpath, "o", "", "output filename")
11901196
}
11911197
var testCompileOnlyFlag, testVerboseFlag, testShortFlag *bool
1198+
var testBenchRegexp *string
11921199
var testRunRegexp *string
11931200
if command == "help" || command == "test" {
11941201
testCompileOnlyFlag = flag.Bool("c", false, "compile the test binary but do not run it")
11951202
testVerboseFlag = flag.Bool("v", false, "verbose: print additional output")
11961203
testShortFlag = flag.Bool("short", false, "short: run smaller test suite to save time")
11971204
testRunRegexp = flag.String("run", "", "run: regexp of tests to run")
1205+
testBenchRegexp = flag.String("bench", "", "run: regexp of benchmarks to run")
11981206
}
11991207

12001208
// Early command processing, before commands are interpreted by the Go flag
@@ -1418,7 +1426,7 @@ func main() {
14181426
defer close(buf.done)
14191427
stdout := (*testStdout)(buf)
14201428
stderr := (*testStderr)(buf)
1421-
passed, err := Test(pkgName, stdout, stderr, options, *testCompileOnlyFlag, *testVerboseFlag, *testShortFlag, *testRunRegexp, outpath)
1429+
passed, err := Test(pkgName, stdout, stderr, options, *testCompileOnlyFlag, *testVerboseFlag, *testShortFlag, *testRunRegexp, *testBenchRegexp, outpath)
14221430
if err != nil {
14231431
printCompilerError(func(args ...interface{}) {
14241432
fmt.Fprintln(stderr, args...)

main_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ func TestTest(t *testing.T) {
516516
defer out.Close()
517517

518518
opts := targ.opts
519-
passed, err := Test("github.com/tinygo-org/tinygo/tests/testing/pass", out, out, &opts, false, false, false, "", "")
519+
passed, err := Test("github.com/tinygo-org/tinygo/tests/testing/pass", out, out, &opts, false, false, false, "", "", "")
520520
if err != nil {
521521
t.Errorf("test error: %v", err)
522522
}
@@ -537,7 +537,7 @@ func TestTest(t *testing.T) {
537537
defer out.Close()
538538

539539
opts := targ.opts
540-
passed, err := Test("github.com/tinygo-org/tinygo/tests/testing/fail", out, out, &opts, false, false, false, "", "")
540+
passed, err := Test("github.com/tinygo-org/tinygo/tests/testing/fail", out, out, &opts, false, false, false, "", "", "")
541541
if err != nil {
542542
t.Errorf("test error: %v", err)
543543
}
@@ -564,7 +564,7 @@ func TestTest(t *testing.T) {
564564

565565
var output bytes.Buffer
566566
opts := targ.opts
567-
passed, err := Test("github.com/tinygo-org/tinygo/tests/testing/nothing", io.MultiWriter(&output, out), out, &opts, false, false, false, "", "")
567+
passed, err := Test("github.com/tinygo-org/tinygo/tests/testing/nothing", io.MultiWriter(&output, out), out, &opts, false, false, false, "", "", "")
568568
if err != nil {
569569
t.Errorf("test error: %v", err)
570570
}
@@ -588,7 +588,7 @@ func TestTest(t *testing.T) {
588588
defer out.Close()
589589

590590
opts := targ.opts
591-
passed, err := Test("github.com/tinygo-org/tinygo/tests/testing/builderr", out, out, &opts, false, false, false, "", "")
591+
passed, err := Test("github.com/tinygo-org/tinygo/tests/testing/builderr", out, out, &opts, false, false, false, "", "", "")
592592
if err == nil {
593593
t.Error("test did not error")
594594
}

src/testing/benchmark.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
package testing
88

99
import (
10+
"fmt"
1011
"time"
1112
)
1213

@@ -187,6 +188,30 @@ func (r BenchmarkResult) AllocedBytesPerOp() int64 {
187188
return 0 // Dummy version to allow running e.g. golang.org/test/fibo.go
188189
}
189190

191+
func runBenchmarks(benchmarks []InternalBenchmark) bool {
192+
if len(benchmarks) == 0 {
193+
return true
194+
}
195+
main := &B{
196+
common: common{
197+
name: "Main",
198+
},
199+
benchTime: benchTime,
200+
benchFunc: func(b *B) {
201+
for _, Benchmark := range benchmarks {
202+
if flagVerbose {
203+
fmt.Printf("=== RUN %s\n", Benchmark.Name)
204+
}
205+
b.Run(Benchmark.Name, Benchmark.F)
206+
fmt.Printf("--- Result: %d ns/op\n", b.result.NsPerOp())
207+
}
208+
},
209+
}
210+
211+
main.runN(1)
212+
return true
213+
}
214+
190215
// Run benchmarks f as a subbenchmark with the given name. It reports
191216
// true if the subbenchmark succeeded.
192217
//
@@ -248,4 +273,3 @@ func Benchmark(f func(b *B)) BenchmarkResult {
248273
}
249274
return b.result
250275
}
251-

src/testing/testing.go

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ import (
1818

1919
// Testing flags.
2020
var (
21-
flagVerbose bool
22-
flagShort bool
23-
flagRunRegexp string
21+
flagVerbose bool
22+
flagShort bool
23+
flagRunRegexp string
24+
flagBenchRegexp string
2425
)
2526

2627
var initRan bool
@@ -35,6 +36,7 @@ func Init() {
3536
flag.BoolVar(&flagVerbose, "test.v", false, "verbose: print additional output")
3637
flag.BoolVar(&flagShort, "test.short", false, "short: run smaller test suite to save time")
3738
flag.StringVar(&flagRunRegexp, "test.run", "", "run: regexp of tests to run")
39+
flag.StringVar(&flagBenchRegexp, "test.bench", "", "run: regexp of benchmarks to run")
3840
}
3941

4042
// common holds the elements common between T and B and
@@ -243,7 +245,8 @@ type InternalTest struct {
243245
// M is a test suite.
244246
type M struct {
245247
// tests is a list of the test names to execute
246-
Tests []InternalTest
248+
Tests []InternalTest
249+
Benchmarks []InternalBenchmark
247250

248251
deps testDeps
249252
}
@@ -275,8 +278,33 @@ func (m *M) Run() int {
275278

276279
m.Tests = filtered
277280
}
281+
if flagBenchRegexp != "" {
282+
var filtered []InternalBenchmark
278283

279-
if len(m.Tests) == 0 {
284+
// pre-test the regexp; we don't want to bother logging one failure for every test name if the regexp is broken
285+
if _, err := m.deps.MatchString(flagBenchRegexp, "some-test-name"); err != nil {
286+
fmt.Println("testing: invalid regexp for -test.bench:", err.Error())
287+
failures++
288+
}
289+
290+
// filter the list of tests before we try to run them
291+
for _, test := range m.Benchmarks {
292+
// ignore the error; we already tested that the regexp compiles fine above
293+
if match, _ := m.deps.MatchString(flagBenchRegexp, test.Name); match {
294+
filtered = append(filtered, test)
295+
}
296+
}
297+
298+
m.Benchmarks = filtered
299+
flagVerbose = true
300+
if flagRunRegexp == "" {
301+
m.Tests = []InternalTest{}
302+
}
303+
} else {
304+
m.Benchmarks = []InternalBenchmark{}
305+
}
306+
307+
if len(m.Tests) == 0 && len(m.Benchmarks) == 0 {
280308
fmt.Fprintln(os.Stderr, "testing: warning: no tests to run")
281309
}
282310

@@ -307,6 +335,8 @@ func (m *M) Run() int {
307335
}
308336
}
309337

338+
runBenchmarks(m.Benchmarks)
339+
310340
if failures > 0 {
311341
fmt.Println("FAIL")
312342
} else {
@@ -358,8 +388,9 @@ type testDeps interface {
358388
func MainStart(deps interface{}, tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample) *M {
359389
Init()
360390
return &M{
361-
Tests: tests,
362-
deps: deps.(testDeps),
391+
Tests: tests,
392+
Benchmarks: benchmarks,
393+
deps: deps.(testDeps),
363394
}
364395
}
365396

0 commit comments

Comments
 (0)