aboutsummaryrefslogtreecommitdiff
path: root/src/testing
diff options
context:
space:
mode:
authorRoland Shoemaker <roland@golang.org>2021-05-01 18:46:22 -0700
committerRoland Shoemaker <roland@golang.org>2021-05-07 14:24:10 +0000
commit510e711dd36999f1800678909bb7fdb448aa074f (patch)
treef0b530310fabc4cc01f0f9a3a4f59f8c5d58fefe /src/testing
parentaf3237eaf9cf46e6a02a3b53447e49c55abd4f00 (diff)
downloadgo-510e711dd36999f1800678909bb7fdb448aa074f.tar.xz
[dev.fuzz] testing,internal/fuzz: prevent unbounded memory growth
Usage of f.testContext.match.fullName to generate the test name causes unbounded memory growth, eventually causing the fuzzer to slow down as memory pressure increases. Each time fuzzFn is invoked it generates a unique string and stores it in a map. With the fuzzer running at around 100k executions per second this consumed around ~30GB of memory in a handful of minutes. Instead just use the base name of the test for mutated inputs, a special name for seeded inputs, and the filename for inputs from the input corpus. Change-Id: I083f47df7e82f0c6b0bda244f158233784a13029 Reviewed-on: https://go-review.googlesource.com/c/go/+/316030 Trust: Roland Shoemaker <roland@golang.org> Trust: Katie Hockman <katie@golang.org> Run-TryBot: Roland Shoemaker <roland@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Katie Hockman <katie@golang.org>
Diffstat (limited to 'src/testing')
-rw-r--r--src/testing/fuzz.go14
1 files changed, 6 insertions, 8 deletions
diff --git a/src/testing/fuzz.go b/src/testing/fuzz.go
index 70e1b414a8..7afd24d258 100644
--- a/src/testing/fuzz.go
+++ b/src/testing/fuzz.go
@@ -226,7 +226,7 @@ func (f *F) Add(args ...interface{}) {
}
values = append(values, args[i])
}
- f.corpus = append(f.corpus, corpusEntry{Values: values})
+ f.corpus = append(f.corpus, corpusEntry{Values: values, Name: fmt.Sprintf("seed#%d", len(f.corpus))})
}
// supportedTypes represents all of the supported types which can be fuzzed.
@@ -298,21 +298,19 @@ func (f *F) Fuzz(ff interface{}) {
// fn is called in its own goroutine.
//
// TODO(jayconrod,katiehockman): dedupe testdata corpus with entries from f.Add
- // TODO(jayconrod,katiehockman): improve output when running the subtest.
- // e.g. instead of
- // --- FAIL: FuzzSomethingError/#00 (0.00s)
- // do
- // --- FAIL: FuzzSomethingError/<hash> (0.00s)
run := func(e corpusEntry) error {
if e.Values == nil {
// Every code path should have already unmarshaled Data into Values.
// It's our fault if it didn't.
panic(fmt.Sprintf("corpus file %q was not unmarshaled", e.Name))
}
- testName, ok, _ := f.testContext.match.fullName(&f.common, e.Name)
- if !ok || shouldFailFast() {
+ if shouldFailFast() {
return nil
}
+ testName := f.common.name
+ if e.Name != "" {
+ testName = fmt.Sprintf("%s/%s", testName, e.Name)
+ }
// Record the stack trace at the point of this call so that if the subtest
// function - which runs in a separate stack - is marked as a helper, we can
// continue walking the stack into the parent test.