diff options
| author | Katie Hockman <katie@golang.org> | 2020-10-05 14:24:21 -0400 |
|---|---|---|
| committer | Filippo Valsorda <filippo@golang.org> | 2020-12-04 19:17:29 +0100 |
| commit | 4fb2f3ca22de92e7ad6137fb988dcc1cd4449ceb (patch) | |
| tree | f8c95cb6134025ac0883a2da6a15b3727ca7105b /src/testing | |
| parent | aea29a9016cb5c3e160f94e6a95b197407de8c2c (diff) | |
| download | go-4fb2f3ca22de92e7ad6137fb988dcc1cd4449ceb.tar.xz | |
[dev.fuzz] testing: panic if certain testing.F functions are called in Fuzz func
Change-Id: I8ee513b2b157e6033d4bc9607d0e65f42bd6801f
Reviewed-on: https://go-review.googlesource.com/c/go/+/259657
Trust: Katie Hockman <katie@golang.org>
Trust: Jay Conrod <jayconrod@google.com>
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.go | 7 | ||||
| -rw-r--r-- | src/testing/testing.go | 37 |
2 files changed, 43 insertions, 1 deletions
diff --git a/src/testing/fuzz.go b/src/testing/fuzz.go index 6f985c7c38..01895e8d7d 100644 --- a/src/testing/fuzz.go +++ b/src/testing/fuzz.go @@ -87,11 +87,16 @@ func (f *F) Fuzz(ff interface{}) { } if err != nil { t.Fail() - t.output = []byte(fmt.Sprintf(" panic: %s\n", err)) + t.output = []byte(fmt.Sprintf(" %s", err)) } f.setRan() + f.inFuzzFn = false t.signal <- true // signal that the test has finished }() + // TODO(katiehockman, jayconrod): consider replacing inFuzzFn with + // general purpose flag that checks whether specific methods can be + // called. + f.inFuzzFn = true fn(t, b) t.finished = true } diff --git a/src/testing/testing.go b/src/testing/testing.go index 4fd628c0ff..7cf3323d51 100644 --- a/src/testing/testing.go +++ b/src/testing/testing.go @@ -399,6 +399,7 @@ type common struct { chatty *chattyPrinter // A copy of chattyPrinter, if the chatty flag is set. bench bool // Whether the current test is a benchmark. + inFuzzFn bool // Whether the test is executing a Fuzz function finished bool // Test function has completed. hasSub int32 // Written atomically. raceErrors int // Number of races detected during test. @@ -681,6 +682,9 @@ func (c *common) setRan() { // Fail marks the function as having failed but continues execution. func (c *common) Fail() { + if c.inFuzzFn { + panic("testing: f.Fail was called inside the f.Fuzz function") + } if c.parent != nil { c.parent.Fail() } @@ -710,6 +714,9 @@ func (c *common) Failed() bool { // created during the test. Calling FailNow does not stop // those other goroutines. func (c *common) FailNow() { + if c.inFuzzFn { + panic("testing: f.FailNow was called inside the f.Fuzz function") + } c.Fail() // Calling runtime.Goexit will exit the goroutine, which @@ -787,36 +794,54 @@ func (c *common) Logf(format string, args ...interface{}) { c.log(fmt.Sprintf(fo // Error is equivalent to Log followed by Fail. func (c *common) Error(args ...interface{}) { + if c.inFuzzFn { + panic("testing: f.Error was called inside the f.Fuzz function") + } c.log(fmt.Sprintln(args...)) c.Fail() } // Errorf is equivalent to Logf followed by Fail. func (c *common) Errorf(format string, args ...interface{}) { + if c.inFuzzFn { + panic("testing: f.Errorf was called inside the f.Fuzz function") + } c.log(fmt.Sprintf(format, args...)) c.Fail() } // Fatal is equivalent to Log followed by FailNow. func (c *common) Fatal(args ...interface{}) { + if c.inFuzzFn { + panic("testing: f.Fatal was called inside the f.Fuzz function") + } c.log(fmt.Sprintln(args...)) c.FailNow() } // Fatalf is equivalent to Logf followed by FailNow. func (c *common) Fatalf(format string, args ...interface{}) { + if c.inFuzzFn { + panic("testing: f.Fatalf was called inside the f.Fuzz function") + } c.log(fmt.Sprintf(format, args...)) c.FailNow() } // Skip is equivalent to Log followed by SkipNow. func (c *common) Skip(args ...interface{}) { + if c.inFuzzFn { + panic("testing: f.Skip was called inside the f.Fuzz function") + } c.log(fmt.Sprintln(args...)) c.SkipNow() } // Skipf is equivalent to Logf followed by SkipNow. func (c *common) Skipf(format string, args ...interface{}) { + if c.inFuzzFn { + panic("testing: f.Skipf was called inside the f.Fuzz function") + } c.log(fmt.Sprintf(format, args...)) c.SkipNow() } @@ -830,6 +855,9 @@ func (c *common) Skipf(format string, args ...interface{}) { // other goroutines created during the test. Calling SkipNow does not stop // those other goroutines. func (c *common) SkipNow() { + if c.inFuzzFn { + panic("testing: f.SkipNow was called inside the f.Fuzz function") + } c.skip() c.finished = true runtime.Goexit() @@ -852,6 +880,9 @@ func (c *common) Skipped() bool { // When printing file and line information, that function will be skipped. // Helper may be called simultaneously from multiple goroutines. func (c *common) Helper() { + if c.inFuzzFn { + panic("testing: f.Helper was called inside the f.Fuzz function") + } c.mu.Lock() defer c.mu.Unlock() if c.helpers == nil { @@ -864,6 +895,9 @@ func (c *common) Helper() { // subtests complete. Cleanup functions will be called in last added, // first called order. func (c *common) Cleanup(f func()) { + if c.inFuzzFn { + panic("testing: f.Cleanup was called inside the f.Fuzz function") + } var pc [maxStackLen]uintptr // Skip two extra frames to account for this function and runtime.Callers itself. n := runtime.Callers(2, pc[:]) @@ -902,6 +936,9 @@ var tempDirReplacer struct { // Each subsequent call to t.TempDir returns a unique directory; // if the directory creation fails, TempDir terminates the test by calling Fatal. func (c *common) TempDir() string { + if c.inFuzzFn { + panic("testing: f.TempDir was called inside the f.Fuzz function") + } // Use a single parent directory for all the temporary directories // created by a test, each numbered sequentially. c.tempDirMu.Lock() |
