aboutsummaryrefslogtreecommitdiff
path: root/src/testing
diff options
context:
space:
mode:
authorKatie Hockman <katie@golang.org>2021-09-13 12:23:43 -0400
committerKatie Hockman <katie@golang.org>2021-09-16 13:37:34 +0000
commit5ed7dd0650cf32edd000d2268df961e2b825aab4 (patch)
tree0c99214585ec74b8820671203e940ce9a4cec8d0 /src/testing
parent4304cf62e9ba6a85e37d5fec33cfa580ce7ac6d1 (diff)
downloadgo-5ed7dd0650cf32edd000d2268df961e2b825aab4.tar.gz
go-5ed7dd0650cf32edd000d2268df961e2b825aab4.zip
[dev.fuzz] internal/fuzz: rework default test behavior before fuzzing
This change refactors some of the code to support skipping a run of the seed corpus by the go command before runFuzzing occurs. Previously, the go command would run all seed corpus for all targets that match the provided `run` argument. This will be redundant when fuzzing a target. Now, the seed corpus is only run by targets other than the one that's about to be fuzzed, and the worker handles running and reporting issues with the seed corpus. Part of the logic that needed close inspection is what to do if a failure occurs during a testing-only or coverage-only fail. If the input is already in the seed corpus, the fuzzing engine shouldn't add it. If the input is currently in the cache, then it should be written to testdata. In all cases, if an error occurs, we need to report this to the user with enough information for them to debug it. This uncovered some issues with our code when fuzzing without instrumentation, and when -run=None was provided. There are some logic fixes in this change, and some small refactors. Fixes golang/go#48327 Fixes golang/go#48296 Change-Id: I9ce2be0219c5b09277ddd308df8bc5a46d4558fa Reviewed-on: https://go-review.googlesource.com/c/go/+/349630 Trust: Katie Hockman <katie@golang.org> Run-TryBot: Katie Hockman <katie@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Jay Conrod <jayconrod@google.com>
Diffstat (limited to 'src/testing')
-rw-r--r--src/testing/fuzz.go24
1 files changed, 18 insertions, 6 deletions
diff --git a/src/testing/fuzz.go b/src/testing/fuzz.go
index c2d9db843d..3a1b0bdeaa 100644
--- a/src/testing/fuzz.go
+++ b/src/testing/fuzz.go
@@ -84,6 +84,7 @@ type corpusEntry = struct {
Data []byte
Values []interface{}
Generation int
+ IsSeed bool
}
// Cleanup registers a function to be called after the fuzz function has been
@@ -258,7 +259,7 @@ func (f *F) Add(args ...interface{}) {
}
values = append(values, args[i])
}
- f.corpus = append(f.corpus, corpusEntry{Values: values, Name: fmt.Sprintf("seed#%d", len(f.corpus))})
+ f.corpus = append(f.corpus, corpusEntry{Values: values, IsSeed: true, Name: fmt.Sprintf("seed#%d", len(f.corpus))})
}
// supportedTypes represents all of the supported types which can be fuzzed.
@@ -344,11 +345,11 @@ func (f *F) Fuzz(ff interface{}) {
if err != nil {
f.Fatal(err)
}
-
- // If this is the coordinator process, zero the values, since we don't need
- // to hold onto them.
- if f.fuzzContext.mode == fuzzCoordinator {
- for i := range c {
+ for i := range c {
+ c[i].IsSeed = true // these are all seed corpus values
+ if f.fuzzContext.mode == fuzzCoordinator {
+ // If this is the coordinator process, zero the values, since we don't need
+ // to hold onto them.
c[i].Values = nil
}
}
@@ -550,6 +551,10 @@ func runFuzzTargets(deps testDeps, fuzzTargets []InternalFuzzTarget, deadline ti
m := newMatcher(deps.MatchString, *match, "-test.run")
tctx := newTestContext(*parallel, m)
tctx.deadline = deadline
+ var mFuzz *matcher
+ if *matchFuzz != "" {
+ mFuzz = newMatcher(deps.MatchString, *matchFuzz, "-test.fuzz")
+ }
fctx := &fuzzContext{deps: deps, mode: seedCorpusOnly}
root := common{w: os.Stdout} // gather output in one place
if Verbose() {
@@ -563,6 +568,13 @@ func runFuzzTargets(deps testDeps, fuzzTargets []InternalFuzzTarget, deadline ti
if !matched {
continue
}
+ if mFuzz != nil {
+ if _, fuzzMatched, _ := mFuzz.fullName(nil, ft.Name); fuzzMatched {
+ // If this target 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),