This makes running benchmarks repeatedly easier.
Этот коммит содержится в:
Damian Gryski 2023-03-30 18:14:02 -07:00 коммит произвёл Ron Evans
родитель e6ccdd9d1a
коммит 698b1f19c6
3 изменённых файлов: 40 добавлений и 25 удалений

Просмотреть файл

@ -216,7 +216,7 @@ func Build(pkgName, outpath string, options *compileopts.Options) error {
// Test runs the tests in the given package. Returns whether the test passed and // Test runs the tests in the given package. Returns whether the test passed and
// possibly an error if the test failed to run. // possibly an error if the test failed to run.
func Test(pkgName string, stdout, stderr io.Writer, options *compileopts.Options, testCompileOnly, testVerbose, testShort bool, testRunRegexp string, testBenchRegexp string, testBenchTime string, testBenchMem bool, outpath string) (bool, error) { func Test(pkgName string, stdout, stderr io.Writer, options *compileopts.Options, testCompileOnly, testVerbose, testShort bool, testRunRegexp string, testCount int, testBenchRegexp string, testBenchTime string, testBenchMem bool, outpath string) (bool, error) {
options.TestConfig.CompileTestBinary = true options.TestConfig.CompileTestBinary = true
config, err := builder.NewConfig(options) config, err := builder.NewConfig(options)
if err != nil { if err != nil {
@ -243,6 +243,9 @@ func Test(pkgName string, stdout, stderr io.Writer, options *compileopts.Options
if testBenchMem { if testBenchMem {
flags = append(flags, "-test.benchmem") flags = append(flags, "-test.benchmem")
} }
if testCount != 1 {
flags = append(flags, "-test.count="+strconv.Itoa(testCount))
}
buf := bytes.Buffer{} buf := bytes.Buffer{}
passed := false passed := false
@ -1405,6 +1408,7 @@ func main() {
flag.StringVar(&outpath, "o", "", "output filename") flag.StringVar(&outpath, "o", "", "output filename")
} }
var testCompileOnlyFlag, testVerboseFlag, testShortFlag *bool var testCompileOnlyFlag, testVerboseFlag, testShortFlag *bool
var testCount *int
var testBenchRegexp *string var testBenchRegexp *string
var testBenchTime *string var testBenchTime *string
var testRunRegexp *string var testRunRegexp *string
@ -1414,6 +1418,7 @@ func main() {
testVerboseFlag = flag.Bool("v", false, "verbose: print additional output") testVerboseFlag = flag.Bool("v", false, "verbose: print additional output")
testShortFlag = flag.Bool("short", false, "short: run smaller test suite to save time") testShortFlag = flag.Bool("short", false, "short: run smaller test suite to save time")
testRunRegexp = flag.String("run", "", "run: regexp of tests to run") testRunRegexp = flag.String("run", "", "run: regexp of tests to run")
testCount = flag.Int("count", 1, "count: number of times to run tests/benchmarks `count` times")
testBenchRegexp = flag.String("bench", "", "run: regexp of benchmarks to run") testBenchRegexp = flag.String("bench", "", "run: regexp of benchmarks to run")
testBenchTime = flag.String("benchtime", "", "run each benchmark for duration `d`") testBenchTime = flag.String("benchtime", "", "run each benchmark for duration `d`")
testBenchMem = flag.Bool("benchmem", false, "show memory stats for benchmarks") testBenchMem = flag.Bool("benchmem", false, "show memory stats for benchmarks")
@ -1659,7 +1664,7 @@ func main() {
defer close(buf.done) defer close(buf.done)
stdout := (*testStdout)(buf) stdout := (*testStdout)(buf)
stderr := (*testStderr)(buf) stderr := (*testStderr)(buf)
passed, err := Test(pkgName, stdout, stderr, options, *testCompileOnlyFlag, *testVerboseFlag, *testShortFlag, *testRunRegexp, *testBenchRegexp, *testBenchTime, *testBenchMem, outpath) passed, err := Test(pkgName, stdout, stderr, options, *testCompileOnlyFlag, *testVerboseFlag, *testShortFlag, *testRunRegexp, *testCount, *testBenchRegexp, *testBenchTime, *testBenchMem, outpath)
if err != nil { if err != nil {
printCompilerError(func(args ...interface{}) { printCompilerError(func(args ...interface{}) {
fmt.Fprintln(stderr, args...) fmt.Fprintln(stderr, args...)

Просмотреть файл

@ -27,6 +27,7 @@ var (
matchBenchmarks *string matchBenchmarks *string
benchmarkMemory *bool benchmarkMemory *bool
benchTime = benchTimeFlag{d: 1 * time.Second} // changed during test of testing package benchTime = benchTimeFlag{d: 1 * time.Second} // changed during test of testing package
testCount *int
) )
type benchTimeFlag struct { type benchTimeFlag struct {
@ -213,11 +214,14 @@ func (b *B) doBench() BenchmarkResult {
// of benchmark iterations until the benchmark runs for the requested benchtime. // of benchmark iterations until the benchmark runs for the requested benchtime.
// run1 must have been called on b. // run1 must have been called on b.
func (b *B) launch() { func (b *B) launch() {
runtime.GC()
// Run the benchmark for at least the specified amount of time. // Run the benchmark for at least the specified amount of time.
if b.benchTime.n > 0 { if b.benchTime.n > 0 {
b.runN(b.benchTime.n) b.runN(b.benchTime.n)
} else { } else {
d := b.benchTime.d d := b.benchTime.d
b.failed = false
b.duration = 0
for n := int64(1); !b.failed && b.duration < d && n < 1e9; { for n := int64(1); !b.failed && b.duration < d && n < 1e9; {
last := n last := n
// Predict required iterations. // Predict required iterations.
@ -394,24 +398,26 @@ func runBenchmarks(matchString func(pat, str string) (bool, error), benchmarks [
func (b *B) processBench(ctx *benchContext) { func (b *B) processBench(ctx *benchContext) {
benchName := b.name benchName := b.name
if ctx != nil { for i := 0; i < flagCount; i++ {
fmt.Printf("%-*s\t", ctx.maxLen, benchName) if ctx != nil {
} fmt.Printf("%-*s\t", ctx.maxLen, benchName)
r := b.doBench() }
if b.failed { r := b.doBench()
// The output could be very long here, but probably isn't. if b.failed {
// We print it all, regardless, because we don't want to trim the reason // The output could be very long here, but probably isn't.
// the benchmark failed. // We print it all, regardless, because we don't want to trim the reason
fmt.Printf("--- FAIL: %s\n%s", benchName, "") // b.output) // the benchmark failed.
return fmt.Printf("--- FAIL: %s\n%s", benchName, "") // b.output)
} return
if ctx != nil { }
results := r.String() if ctx != nil {
results := r.String()
if *benchmarkMemory || b.showAllocResult {
results += "\t" + r.MemString() if *benchmarkMemory || b.showAllocResult {
results += "\t" + r.MemString()
}
fmt.Println(results)
} }
fmt.Println(results)
} }
} }

Просмотреть файл

@ -26,6 +26,7 @@ var (
flagVerbose bool flagVerbose bool
flagShort bool flagShort bool
flagRunRegexp string flagRunRegexp string
flagCount int
) )
var initRan bool var initRan bool
@ -40,6 +41,7 @@ func Init() {
flag.BoolVar(&flagVerbose, "test.v", false, "verbose: print additional output") 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.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(&flagRunRegexp, "test.run", "", "run: regexp of tests to run")
flag.IntVar(&flagCount, "test.count", 1, "run each test or benchmark `count` times")
initBenchmarkFlags() initBenchmarkFlags()
} }
@ -485,12 +487,14 @@ func runTests(matchString func(pat, str string) (bool, error), tests []InternalT
context: ctx, context: ctx,
} }
tRunner(t, func(t *T) { for i := 0; i < flagCount; i++ {
for _, test := range tests { tRunner(t, func(t *T) {
t.Run(test.Name, test.F) for _, test := range tests {
ok = ok && !t.Failed() t.Run(test.Name, test.F)
} ok = ok && !t.Failed()
}) }
})
}
return t.ran, ok return t.ran, ok
} }