From 30b240b102652a7cf6b7df0748b4bc69f496e0bc Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 17 Oct 2022 14:29:37 -0400 Subject: [PATCH] testing: implement -cpu and -count for fuzz tests Fuzz tests are meant to be run just like ordinary tests, so copy the same loop cpu and count loops used in testing.go (and benchmark.go) into fuzz.go. Change-Id: Ic585df8ccc577869c877b1055e0493803dbeb828 Reviewed-on: https://go-review.googlesource.com/c/go/+/443377 Auto-Submit: Russ Cox Reviewed-by: Bryan Mills TryBot-Result: Gopher Robot Run-TryBot: Russ Cox --- src/testing/fuzz.go | 102 ++++++++++++++++++++++++++------------------ 1 file changed, 60 insertions(+), 42 deletions(-) diff --git a/src/testing/fuzz.go b/src/testing/fuzz.go index d88de9c99a..6e43ae7710 100644 --- a/src/testing/fuzz.go +++ b/src/testing/fuzz.go @@ -474,55 +474,73 @@ func runFuzzTests(deps testDeps, fuzzTests []InternalFuzzTarget, deadline time.T return ran, ok } m := newMatcher(deps.MatchString, *match, "-test.run", *skip) - tctx := newTestContext(*parallel, m) - tctx.deadline = deadline var mFuzz *matcher if *matchFuzz != "" { mFuzz = newMatcher(deps.MatchString, *matchFuzz, "-test.fuzz", *skip) } - fctx := &fuzzContext{deps: deps, mode: seedCorpusOnly} - root := common{w: os.Stdout} // gather output in one place - if Verbose() { - root.chatty = newChattyPrinter(root.w) - } - for _, ft := range fuzzTests { - if shouldFailFast() { - break - } - testName, matched, _ := tctx.match.fullName(nil, ft.Name) - if !matched { - continue - } - if mFuzz != nil { - if _, fuzzMatched, _ := mFuzz.fullName(nil, ft.Name); fuzzMatched { - // If this will be fuzzed, then don't run the seed corpus - // right now. That will happen later. - continue + + for _, procs := range cpuList { + runtime.GOMAXPROCS(procs) + for i := uint(0); i < *count; i++ { + if shouldFailFast() { + break + } + + tctx := newTestContext(*parallel, m) + tctx.deadline = deadline + fctx := &fuzzContext{deps: deps, mode: seedCorpusOnly} + root := common{w: os.Stdout} // gather output in one place + if Verbose() { + root.chatty = newChattyPrinter(root.w) + } + for _, ft := range fuzzTests { + if shouldFailFast() { + break + } + testName, matched, _ := tctx.match.fullName(nil, ft.Name) + if !matched { + continue + } + if mFuzz != nil { + if _, fuzzMatched, _ := mFuzz.fullName(nil, ft.Name); fuzzMatched { + // If this will be fuzzed, then don't run the seed corpus + // right now. That will happen later. + continue + } + } + f := &F{ + common: common{ + signal: make(chan bool), + barrier: make(chan bool), + name: testName, + parent: &root, + level: root.level + 1, + chatty: root.chatty, + }, + testContext: tctx, + fuzzContext: fctx, + } + f.w = indenter{&f.common} + if f.chatty != nil { + f.chatty.Updatef(f.name, "=== RUN %s\n", f.name) + } + go fRunner(f, ft.Fn) + <-f.signal + if f.chatty != nil && f.chatty.json { + f.chatty.Updatef(f.parent.name, "=== NAME %s\n", f.parent.name) + } + ok = ok && !f.Failed() + ran = ran || f.ran + } + if !ran { + // There were no tests to run on this iteration. + // This won't change, so no reason to keep trying. + break } - } - f := &F{ - common: common{ - signal: make(chan bool), - barrier: make(chan bool), - name: testName, - parent: &root, - level: root.level + 1, - chatty: root.chatty, - }, - testContext: tctx, - fuzzContext: fctx, - } - f.w = indenter{&f.common} - if f.chatty != nil { - f.chatty.Updatef(f.name, "=== RUN %s\n", f.name) - } - go fRunner(f, ft.Fn) - <-f.signal - if f.chatty != nil && f.chatty.json { - f.chatty.Updatef(f.parent.name, "=== NAME %s\n", f.parent.name) } } - return root.ran, !root.Failed() + + return ran, ok } // runFuzzing runs the fuzz test matching the pattern for -fuzz. Only one such -- 2.50.0