diff options
| author | Jay Conrod <jayconrod@google.com> | 2021-05-14 13:59:26 -0400 |
|---|---|---|
| committer | Jay Conrod <jayconrod@google.com> | 2021-05-19 16:43:15 +0000 |
| commit | ad24be022be1c3124887ff22fc742494ee12dfb8 (patch) | |
| tree | a5e8d7da6bf2dd59ac3009be6ca357a6cb1ccd66 /src/testing | |
| parent | 2212a1a339c7ac72ff2133855c97ae097444cb5c (diff) | |
| download | go-ad24be022be1c3124887ff22fc742494ee12dfb8.tar.xz | |
[dev.fuzz] internal/fuzz: make minimization tests more reliable
* Introduced -fuzzminimizetime flag to control the number of time or
the number of calls to spend minimizing. Defaults to 60s. Only works
for unrecoverable crashes for now.
* Moved the count (used by -fuzztime=1000x) into shared
memory. Calling workerClient.fuzz resets it, but it will remain
after the worker processes crashes. workerClient.minimize resets it
once before restarting the worker the first time, but the total
number of runs should still be limited during minimization, even
after multiple terminations and restarts.
* Renamed fuzzArgs.Count to Limit to avoid confusion.
* Several other small fixes and refactorings.
Change-Id: I03faa4c94405041f6dfe48568e5ead502f8dbbd2
Reviewed-on: https://go-review.googlesource.com/c/go/+/320171
Trust: Jay Conrod <jayconrod@google.com>
Trust: Katie Hockman <katie@golang.org>
Run-TryBot: Jay Conrod <jayconrod@google.com>
Reviewed-by: Katie Hockman <katie@golang.org>
Diffstat (limited to 'src/testing')
| -rw-r--r-- | src/testing/fuzz.go | 25 | ||||
| -rw-r--r-- | src/testing/internal/testdeps/deps.go | 29 | ||||
| -rw-r--r-- | src/testing/testing.go | 4 |
3 files changed, 40 insertions, 18 deletions
diff --git a/src/testing/fuzz.go b/src/testing/fuzz.go index d81796b4fc..9364b27eaf 100644 --- a/src/testing/fuzz.go +++ b/src/testing/fuzz.go @@ -18,16 +18,18 @@ import ( func initFuzzFlags() { matchFuzz = flag.String("test.fuzz", "", "run the fuzz target matching `regexp`") - flag.Var(&fuzzDuration, "test.fuzztime", "time to spend fuzzing default is to run indefinitely") + flag.Var(&fuzzDuration, "test.fuzztime", "time to spend fuzzing; default is to run indefinitely") + flag.Var(&minimizeDuration, "test.fuzzminimizetime", "time to spend minimizing a value after finding a crash; default is to minimize for 60s") fuzzCacheDir = flag.String("test.fuzzcachedir", "", "directory where interesting fuzzing inputs are stored") isFuzzWorker = flag.Bool("test.fuzzworker", false, "coordinate with the parent process to fuzz random values") } var ( - matchFuzz *string - fuzzDuration durationOrCountFlag - fuzzCacheDir *string - isFuzzWorker *bool + matchFuzz *string + fuzzDuration durationOrCountFlag + minimizeDuration = durationOrCountFlag{d: 60 * time.Second} + fuzzCacheDir *string + isFuzzWorker *bool // corpusDir is the parent directory of the target's seed corpus within // the package. @@ -357,7 +359,16 @@ func (f *F) Fuzz(ff interface{}) { // actual fuzzing. corpusTargetDir := filepath.Join(corpusDir, f.name) cacheTargetDir := filepath.Join(*fuzzCacheDir, f.name) - err := f.fuzzContext.coordinateFuzzing(fuzzDuration.d, int64(fuzzDuration.n), *parallel, f.corpus, types, corpusTargetDir, cacheTargetDir) + err := f.fuzzContext.coordinateFuzzing( + fuzzDuration.d, + int64(fuzzDuration.n), + minimizeDuration.d, + int64(minimizeDuration.n), + *parallel, + f.corpus, + types, + corpusTargetDir, + cacheTargetDir) if err != nil { f.result = FuzzResult{Error: err} f.Fail() @@ -451,7 +462,7 @@ type fuzzCrashError interface { // fuzzContext holds all fields that are common to all fuzz targets. type fuzzContext struct { importPath func() string - coordinateFuzzing func(time.Duration, int64, int, []corpusEntry, []reflect.Type, string, string) error + coordinateFuzzing func(time.Duration, int64, time.Duration, int64, int, []corpusEntry, []reflect.Type, string, string) error runFuzzWorker func(func(corpusEntry) error) error readCorpus func(string, []reflect.Type) ([]corpusEntry, error) resetCoverage func() diff --git a/src/testing/internal/testdeps/deps.go b/src/testing/internal/testdeps/deps.go index 24ef7c4d62..01390f51d3 100644 --- a/src/testing/internal/testdeps/deps.go +++ b/src/testing/internal/testdeps/deps.go @@ -133,21 +133,32 @@ func (TestDeps) SetPanicOnExit0(v bool) { testlog.SetPanicOnExit0(v) } -func (TestDeps) CoordinateFuzzing(timeout time.Duration, count int64, parallel int, seed []fuzz.CorpusEntry, types []reflect.Type, corpusDir, cacheDir string) (err error) { +func (TestDeps) CoordinateFuzzing( + timeout time.Duration, + limit int64, + minimizeTimeout time.Duration, + minimizeLimit int64, + parallel int, + seed []fuzz.CorpusEntry, + types []reflect.Type, + corpusDir, + cacheDir string) (err error) { // Fuzzing may be interrupted with a timeout or if the user presses ^C. // In either case, we'll stop worker processes gracefully and save // crashers and interesting values. ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) defer cancel() err = fuzz.CoordinateFuzzing(ctx, fuzz.CoordinateFuzzingOpts{ - Log: os.Stderr, - Timeout: timeout, - Count: count, - Parallel: parallel, - Seed: seed, - Types: types, - CorpusDir: corpusDir, - CacheDir: cacheDir, + Log: os.Stderr, + Timeout: timeout, + Limit: limit, + MinimizeTimeout: minimizeTimeout, + MinimizeLimit: minimizeLimit, + Parallel: parallel, + Seed: seed, + Types: types, + CorpusDir: corpusDir, + CacheDir: cacheDir, }) if err == ctx.Err() { return nil diff --git a/src/testing/testing.go b/src/testing/testing.go index 6b710d26d5..07ef625538 100644 --- a/src/testing/testing.go +++ b/src/testing/testing.go @@ -1434,7 +1434,7 @@ func (f matchStringOnly) ImportPath() string { return " func (f matchStringOnly) StartTestLog(io.Writer) {} func (f matchStringOnly) StopTestLog() error { return errMain } func (f matchStringOnly) SetPanicOnExit0(bool) {} -func (f matchStringOnly) CoordinateFuzzing(time.Duration, int64, int, []corpusEntry, []reflect.Type, string, string) error { +func (f matchStringOnly) CoordinateFuzzing(time.Duration, int64, time.Duration, int64, int, []corpusEntry, []reflect.Type, string, string) error { return errMain } func (f matchStringOnly) RunFuzzWorker(func(corpusEntry) error) error { return errMain } @@ -1485,7 +1485,7 @@ type testDeps interface { StartTestLog(io.Writer) StopTestLog() error WriteProfileTo(string, io.Writer, int) error - CoordinateFuzzing(time.Duration, int64, int, []corpusEntry, []reflect.Type, string, string) error + CoordinateFuzzing(time.Duration, int64, time.Duration, int64, int, []corpusEntry, []reflect.Type, string, string) error RunFuzzWorker(func(corpusEntry) error) error ReadCorpus(string, []reflect.Type) ([]corpusEntry, error) ResetCoverage() |
