Commit 23a756d8 authored by Marcel van Lohuizen's avatar Marcel van Lohuizen

testing: expose subtest and subbenchmark functionality

Fixes #12166

Change-Id: Ie62cba2c39beb5732447ba3688c93c08ef12abb5
Reviewed-on: https://go-review.googlesource.com/18898Reviewed-by: default avatarRuss Cox <rsc@golang.org>
Run-TryBot: Marcel van Lohuizen <mpvl@golang.org>
parent 00a2a94c
...@@ -14,7 +14,7 @@ import ( ...@@ -14,7 +14,7 @@ import (
"time" "time"
) )
var matchBenchmarks = flag.String("test.bench", "", "regular expression to select benchmarks to run") var matchBenchmarks = flag.String("test.bench", "", "regular expression per path component to select benchmarks to run")
var benchTime = flag.Duration("test.benchtime", 1*time.Second, "approximate run time for each benchmark") var benchTime = flag.Duration("test.benchtime", 1*time.Second, "approximate run time for each benchmark")
var benchmarkMemory = flag.Bool("test.benchmem", false, "print memory allocations for benchmarks") var benchmarkMemory = flag.Bool("test.benchmem", false, "print memory allocations for benchmarks")
...@@ -380,7 +380,7 @@ func runBenchmarksInternal(matchString func(pat, str string) (bool, error), benc ...@@ -380,7 +380,7 @@ func runBenchmarksInternal(matchString func(pat, str string) (bool, error), benc
common: common{name: "Main"}, common: common{name: "Main"},
benchFunc: func(b *B) { benchFunc: func(b *B) {
for _, Benchmark := range bs { for _, Benchmark := range bs {
b.runBench(Benchmark.Name, Benchmark.F) b.Run(Benchmark.Name, Benchmark.F)
} }
}, },
benchTime: *benchTime, benchTime: *benchTime,
...@@ -429,12 +429,12 @@ func (ctx *benchContext) processBench(b *B) { ...@@ -429,12 +429,12 @@ func (ctx *benchContext) processBench(b *B) {
} }
} }
// runBench benchmarks f as a subbenchmark with the given name. It reports // Run benchmarks f as a subbenchmark with the given name. It reports
// whether there were any failures. // whether there were any failures.
// //
// A subbenchmark is like any other benchmark. A benchmark that calls Run at // A subbenchmark is like any other benchmark. A benchmark that calls Run at
// least once will not be measured itself. // least once will not be measured itself.
func (b *B) runBench(name string, f func(b *B)) bool { func (b *B) Run(name string, f func(b *B)) bool {
// Since b has subbenchmarks, we will no longer run it as a benchmark itself. // Since b has subbenchmarks, we will no longer run it as a benchmark itself.
// Release the lock and acquire it on exit to ensure locks stay paired. // Release the lock and acquire it on exit to ensure locks stay paired.
b.hasSub = true b.hasSub = true
...@@ -590,6 +590,9 @@ func (b *B) SetParallelism(p int) { ...@@ -590,6 +590,9 @@ func (b *B) SetParallelism(p int) {
// Benchmark benchmarks a single function. Useful for creating // Benchmark benchmarks a single function. Useful for creating
// custom benchmarks that do not use the "go test" command. // custom benchmarks that do not use the "go test" command.
//
// If f calls Run, the result will be an estimate of running all its
// subbenchmarks that don't call Run in sequence in a single benchmark.
func Benchmark(f func(b *B)) BenchmarkResult { func Benchmark(f func(b *B)) BenchmarkResult {
b := &B{ b := &B{
common: common{ common: common{
......
...@@ -107,9 +107,6 @@ func TestTestContext(t *T) { ...@@ -107,9 +107,6 @@ func TestTestContext(t *T) {
} }
} }
// TODO: remove this stub when API is exposed
func (t *T) Run(name string, f func(t *T)) bool { return t.run(name, f) }
func TestTRun(t *T) { func TestTRun(t *T) {
realTest := t realTest := t
testCases := []struct { testCases := []struct {
...@@ -330,9 +327,6 @@ func TestTRun(t *T) { ...@@ -330,9 +327,6 @@ func TestTRun(t *T) {
} }
} }
// TODO: remove this stub when API is exposed
func (b *B) Run(name string, f func(b *B)) bool { return b.runBench(name, f) }
func TestBRun(t *T) { func TestBRun(t *T) {
work := func(b *B) { work := func(b *B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
......
...@@ -548,9 +548,9 @@ func tRunner(t *T, fn func(t *T)) { ...@@ -548,9 +548,9 @@ func tRunner(t *T, fn func(t *T)) {
t.finished = true t.finished = true
} }
// run runs f as a subtest of t called name. It reports whether f succeeded. // Run runs f as a subtest of t called name. It reports whether f succeeded.
// Run will block until all its parallel subtests have completed. // Run will block until all its parallel subtests have completed.
func (t *T) run(name string, f func(t *T)) bool { func (t *T) Run(name string, f func(t *T)) bool {
testName, ok := t.context.match.fullName(&t.common, name) testName, ok := t.context.match.fullName(&t.common, name)
if !ok { if !ok {
return true return true
...@@ -721,7 +721,7 @@ func RunTests(matchString func(pat, str string) (bool, error), tests []InternalT ...@@ -721,7 +721,7 @@ func RunTests(matchString func(pat, str string) (bool, error), tests []InternalT
} }
tRunner(t, func(t *T) { tRunner(t, func(t *T) {
for _, test := range tests { for _, test := range tests {
t.run(test.Name, test.F) t.Run(test.Name, test.F)
} }
// Run catching the signal rather than the tRunner as a separate // Run catching the signal rather than the tRunner as a separate
// goroutine to avoid adding a goroutine during the sequential // goroutine to avoid adding a goroutine during the sequential
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment