aboutsummaryrefslogtreecommitdiff
path: root/src/testing
diff options
context:
space:
mode:
Diffstat (limited to 'src/testing')
-rw-r--r--src/testing/fuzz.go6
-rw-r--r--src/testing/testing.go26
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 {