diff options
author | Katie Hockman <katie@golang.org> | 2021-12-22 10:34:55 -0500 |
---|---|---|
committer | Katie Hockman <katie@golang.org> | 2022-01-06 22:12:11 +0000 |
commit | b9cae6f78f129bb3f1b3293da5375040f5c4f356 (patch) | |
tree | c12964f62c18faa2b375a6f3831cdbf1c79534c4 /src | |
parent | 61014f00f24df8b144d9d235fe3e25ff64b96521 (diff) | |
download | go-b9cae6f78f129bb3f1b3293da5375040f5c4f356.tar.gz go-b9cae6f78f129bb3f1b3293da5375040f5c4f356.zip |
testing: fix deadlock with t.Parallel in testing seed corpus
The c.startParallel channel on the testContext is stuck
in t.Parallel() because c.running starts at 1 for the main
fuzz parent test, and is causing a deadlock because it is
never released. It would normally be released by tRunner,
but needs to instead be released by fRunner instead for fuzz
tests.
Fixes #50217
Change-Id: I2d010e9adddfd8e8321ff2f9dd2e43daf46c128f
Reviewed-on: https://go-review.googlesource.com/c/go/+/374054
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
Trust: Katie Hockman <katie@golang.org>
Run-TryBot: Katie Hockman <katie@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/cmd/go/testdata/script/test_fuzz_parallel.txt | 7 | ||||
-rw-r--r-- | src/testing/fuzz.go | 9 |
2 files changed, 12 insertions, 4 deletions
diff --git a/src/cmd/go/testdata/script/test_fuzz_parallel.txt b/src/cmd/go/testdata/script/test_fuzz_parallel.txt index 1795e0b2a5..e6325208d0 100644 --- a/src/cmd/go/testdata/script/test_fuzz_parallel.txt +++ b/src/cmd/go/testdata/script/test_fuzz_parallel.txt @@ -13,6 +13,13 @@ go test -run=FuzzSeed ! go test -run=FuzzMutate -fuzz=FuzzMutate exists testdata/fuzz/FuzzMutate +# Testdata should now contain a corpus entry which will fail FuzzMutate. +# Run the test without fuzzing, setting -parallel to different values to make +# sure it fails, and doesn't hang. +! go test -run=FuzzMutate -parallel=1 +! go test -run=FuzzMutate -parallel=2 +! go test -run=FuzzMutate -parallel=4 + -- go.mod -- module fuzz_parallel diff --git a/src/testing/fuzz.go b/src/testing/fuzz.go index efb59b3e57..037d531acf 100644 --- a/src/testing/fuzz.go +++ b/src/testing/fuzz.go @@ -323,10 +323,10 @@ func (f *F) Fuzz(ff any) { for _, v := range e.Values { args = append(args, reflect.ValueOf(v)) } - // Before reseting the current coverage, defer the snapshot so that we - // make sure it is called right before the tRunner function exits, - // regardless of whether it was executed cleanly, panicked, or if the - // fuzzFn called t.Fatal. + // Before resetting the current coverage, defer the snapshot so that + // we make sure it is called right before the tRunner function + // exits, regardless of whether it was executed cleanly, panicked, + // or if the fuzzFn called t.Fatal. defer f.fuzzContext.deps.SnapshotCoverage() f.fuzzContext.deps.ResetCoverage() fn.Call(args) @@ -666,6 +666,7 @@ func fRunner(f *F, fn func(*F)) { // This only affects fuzz tests run as normal tests. // While fuzzing, T.Parallel has no effect, so f.sub is empty, and this // branch is not taken. f.barrier is nil in that case. + f.testContext.release() close(f.barrier) // Wait for the subtests to complete. for _, sub := range f.sub { |