src/testing: support -bench option to run benchmarks matching the given pattern.

This commit is contained in:
Dan Kegel
2021-08-16 08:45:28 -07:00
committed by Ron Evans
parent c6678525a9
commit ee4e42ba1f
4 changed files with 79 additions and 16 deletions
+25 -1
View File
@@ -7,6 +7,7 @@
package testing
import (
"fmt"
"time"
)
@@ -187,6 +188,30 @@ func (r BenchmarkResult) AllocedBytesPerOp() int64 {
return 0 // Dummy version to allow running e.g. golang.org/test/fibo.go
}
func runBenchmarks(benchmarks []InternalBenchmark) bool {
if len(benchmarks) == 0 {
return true
}
main := &B{
common: common{
name: "Main",
},
benchTime: benchTime,
benchFunc: func(b *B) {
for _, Benchmark := range benchmarks {
if flagVerbose {
fmt.Printf("=== RUN %s\n", Benchmark.Name)
}
b.Run(Benchmark.Name, Benchmark.F)
fmt.Printf("--- Result: %d ns/op\n", b.result.NsPerOp())
}
},
}
main.runN(1)
return true
}
// Run benchmarks f as a subbenchmark with the given name. It reports
// true if the subbenchmark succeeded.
//
@@ -248,4 +273,3 @@ func Benchmark(f func(b *B)) BenchmarkResult {
}
return b.result
}
+38 -7
View File
@@ -18,9 +18,10 @@ import (
// Testing flags.
var (
flagVerbose bool
flagShort bool
flagRunRegexp string
flagVerbose bool
flagShort bool
flagRunRegexp string
flagBenchRegexp string
)
var initRan bool
@@ -35,6 +36,7 @@ func Init() {
flag.BoolVar(&flagVerbose, "test.v", false, "verbose: print additional output")
flag.BoolVar(&flagShort, "test.short", false, "short: run smaller test suite to save time")
flag.StringVar(&flagRunRegexp, "test.run", "", "run: regexp of tests to run")
flag.StringVar(&flagBenchRegexp, "test.bench", "", "run: regexp of benchmarks to run")
}
// common holds the elements common between T and B and
@@ -243,7 +245,8 @@ type InternalTest struct {
// M is a test suite.
type M struct {
// tests is a list of the test names to execute
Tests []InternalTest
Tests []InternalTest
Benchmarks []InternalBenchmark
deps testDeps
}
@@ -275,8 +278,33 @@ func (m *M) Run() int {
m.Tests = filtered
}
if flagBenchRegexp != "" {
var filtered []InternalBenchmark
if len(m.Tests) == 0 {
// pre-test the regexp; we don't want to bother logging one failure for every test name if the regexp is broken
if _, err := m.deps.MatchString(flagBenchRegexp, "some-test-name"); err != nil {
fmt.Println("testing: invalid regexp for -test.bench:", err.Error())
failures++
}
// filter the list of tests before we try to run them
for _, test := range m.Benchmarks {
// ignore the error; we already tested that the regexp compiles fine above
if match, _ := m.deps.MatchString(flagBenchRegexp, test.Name); match {
filtered = append(filtered, test)
}
}
m.Benchmarks = filtered
flagVerbose = true
if flagRunRegexp == "" {
m.Tests = []InternalTest{}
}
} else {
m.Benchmarks = []InternalBenchmark{}
}
if len(m.Tests) == 0 && len(m.Benchmarks) == 0 {
fmt.Fprintln(os.Stderr, "testing: warning: no tests to run")
}
@@ -307,6 +335,8 @@ func (m *M) Run() int {
}
}
runBenchmarks(m.Benchmarks)
if failures > 0 {
fmt.Println("FAIL")
} else {
@@ -358,8 +388,9 @@ type testDeps interface {
func MainStart(deps interface{}, tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample) *M {
Init()
return &M{
Tests: tests,
deps: deps.(testDeps),
Tests: tests,
Benchmarks: benchmarks,
deps: deps.(testDeps),
}
}