diff options
Diffstat (limited to 'src/testing')
| -rw-r--r-- | src/testing/fuzz.go | 6 | ||||
| -rw-r--r-- | src/testing/testing.go | 26 |
2 files changed, 29 insertions, 3 deletions
diff --git a/src/testing/fuzz.go b/src/testing/fuzz.go index 9364b27eaf..78a0a600fa 100644 --- a/src/testing/fuzz.go +++ b/src/testing/fuzz.go @@ -8,6 +8,7 @@ import ( "errors" "flag" "fmt" + "io" "os" "path/filepath" "reflect" @@ -313,6 +314,7 @@ func (f *F) Fuzz(ff interface{}) { 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. @@ -327,6 +329,7 @@ func (f *F) Fuzz(ff interface{}) { level: f.level + 1, creator: pc[:n], chatty: f.chatty, + fuzzing: true, }, context: f.testContext, } @@ -541,12 +544,13 @@ func runFuzzing(deps testDeps, fuzzTargets []InternalFuzzTarget) (ran, ok bool) resetCoverage: deps.ResetCoverage, snapshotCoverage: deps.SnapshotCoverage, } + root := common{w: os.Stdout} if *isFuzzWorker { + root.w = io.Discard fctx.runFuzzWorker = deps.RunFuzzWorker } else { fctx.coordinateFuzzing = deps.CoordinateFuzzing } - root := common{w: os.Stdout} if Verbose() && !*isFuzzWorker { root.chatty = newChattyPrinter(root.w) } diff --git a/src/testing/testing.go b/src/testing/testing.go index 07ef625538..82b422a414 100644 --- a/src/testing/testing.go +++ b/src/testing/testing.go @@ -448,6 +448,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. + fuzzing bool // Whether the current test is a fuzzing target. hasSub int32 // Written atomically. raceErrors int // Number of races detected during test. runner string // Function name of tRunner running the test. @@ -655,6 +656,20 @@ func (c *common) flushToParent(testName, format string, args ...interface{}) { } } +// isFuzzing returns whether the current context, or any of the parent contexts, +// are a fuzzing target +func (c *common) isFuzzing() bool { + if c.fuzzing { + return true + } + for parent := c.parent; parent != nil; parent = parent.parent { + if parent.fuzzing { + return true + } + } + return false +} + type indenter struct { c *common } @@ -1221,10 +1236,11 @@ func tRunner(t *T, fn func(t *T)) { // complete even if a cleanup function calls t.FailNow. See issue 41355. didPanic := false defer func() { - if didPanic { + isFuzzing := t.common.isFuzzing() + if didPanic && !isFuzzing { return } - if err != nil { + if err != nil && !isFuzzing { panic(err) } // Only report that the test is complete if it doesn't panic, @@ -1250,6 +1266,12 @@ func tRunner(t *T, fn func(t *T)) { } } didPanic = true + if t.common.fuzzing { + for root := &t.common; root.parent != nil; root = root.parent { + fmt.Fprintf(root.parent.w, "panic: %s\n%s\n", err, string(debug.Stack())) + } + return + } panic(err) } if err != nil { |
