[dev.fuzz] testing: report T.Deadline when running seed values

T.Deadline should return the test deadline, set with -timeout. When
fuzz targets are run with seed values as unit tests, either with or
without -fuzz, T.Deadline should work inside the fuzz function.

There is no deadline when fuzzing, even if -fuzztime is set, since
workers may have much shorter deadlines, and fuzz function behavior
shouldn't be time-dependent anyway.

Fixes #46220

Change-Id: I84aaeb9d7bfdc12bdcb6f1ab3fe67b3067ad2dfe
Reviewed-on: https://go-review.googlesource.com/c/go/+/330509
Trust: Jay Conrod <jayconrod@google.com>
Trust: Katie Hockman <katie@golang.org>
Run-TryBot: Jay Conrod <jayconrod@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Katie Hockman <katie@golang.org>
This commit is contained in:
Jay Conrod 2021-06-23 16:23:37 -07:00
parent df99a270b3
commit cc04ab463d
3 changed files with 40 additions and 2 deletions

View File

@ -0,0 +1,37 @@
# TODO(jayconrod): support shared memory on more platforms.
[!darwin] [!linux] [!windows] skip
[short] skip
# The fuzz function should be able to detect whether -timeout
# was set with T.Deadline. Note there is no F.Deadline, and
# there is no timeout while fuzzing, even if -fuzztime is set.
go test -run=FuzzDeadline -wantdeadline=true # -timeout defaults to 10m
go test -run=FuzzDeadline -timeout=0 -wantdeadline=false
! go test -run=FuzzDeadline -timeout=1s -wantdeadline=false
go test -run=FuzzDeadline -timeout=1s -wantdeadline=true
go test -fuzz=FuzzDeadline -timeout=0 -fuzztime=1s -wantdeadline=false
go test -fuzz=FuzzDeadline -timeout=0 -fuzztime=100x -wantdeadline=false
-- go.mod --
module fzz
go 1.16
-- fuzz_deadline_test.go --
package fuzz_test
import (
"flag"
"testing"
)
var wantDeadline = flag.Bool("wantdeadline", false, "whether the test should have a deadline")
func FuzzDeadline(f *testing.F) {
f.Add("run once")
f.Fuzz(func (t *testing.T, _ string) {
if _, hasDeadline := t.Deadline(); hasDeadline != *wantDeadline {
t.Fatalf("function got %v; want %v", hasDeadline, *wantDeadline)
}
})
}

View File

@ -491,13 +491,14 @@ type fuzzContext struct {
// runFuzzTargets runs the fuzz targets matching the pattern for -run. This will
// only run the f.Fuzz function for each seed corpus without using the fuzzing
// engine to generate or mutate inputs.
func runFuzzTargets(deps testDeps, fuzzTargets []InternalFuzzTarget) (ran, ok bool) {
func runFuzzTargets(deps testDeps, fuzzTargets []InternalFuzzTarget, deadline time.Time) (ran, ok bool) {
ok = true
if len(fuzzTargets) == 0 || *isFuzzWorker {
return ran, ok
}
m := newMatcher(deps.MatchString, *match, "-test.run")
tctx := newTestContext(*parallel, m)
tctx.deadline = deadline
fctx := &fuzzContext{
importPath: deps.ImportPath,
readCorpus: deps.ReadCorpus,

View File

@ -1595,7 +1595,7 @@ func (m *M) Run() (code int) {
deadline := m.startAlarm()
haveExamples = len(m.examples) > 0
testRan, testOk := runTests(m.deps.MatchString, m.tests, deadline)
fuzzTargetsRan, fuzzTargetsOk := runFuzzTargets(m.deps, m.fuzzTargets)
fuzzTargetsRan, fuzzTargetsOk := runFuzzTargets(m.deps, m.fuzzTargets, deadline)
exampleRan, exampleOk := runExamples(m.deps.MatchString, m.examples)
m.stopAlarm()
if !testRan && !exampleRan && !fuzzTargetsRan && *matchBenchmarks == "" && *matchFuzz == "" {