]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[dev.fuzz] all: merge master (c95464f) into dev.fuzz
authorKatie Hockman <katie@golang.org>
Mon, 28 Jun 2021 16:43:12 +0000 (12:43 -0400)
committerKatie Hockman <katie@golang.org>
Mon, 28 Jun 2021 17:25:00 +0000 (13:25 -0400)
The new SetEnv method for *testing.T and *testing.B types
was automatically supported by *testing.F since it was added
to the *testing.common type. This function is not appropriate
for *testing.F since fuzzing is run in parallel by default.

Conflicts:

- api/next.txt

Merge List:

+ 2021-06-27 c95464f0ea internal/buildcfg: refactor GOEXPERIMENT parsing code somewhat
+ 2021-06-25 ed01ceaf48 runtime/race: use race build tag on syso_test.go
+ 2021-06-25 d1916e5e84 go/types: in TestCheck/issues.src, import regexp/syntax instead of cmd/compile/internal/syntax
+ 2021-06-25 5160896c69 go/types: in TestStdlib, import from source instead of export data
+ 2021-06-25 d01bc571f7 runtime: make ncgocall a global counter
+ 2021-06-25 37f9a8f69d go/types: fix a bug in package qualification logic
+ 2021-06-24 c309c89db5 reflect: document that InterfaceData is a low-entropy RNG
+ 2021-06-24 cce621431a cmd/compile: fix wrong type in SSA generation for OSLICE2ARRPTR
+ 2021-06-24 600a2a4ffb cmd/go: don't try to add replaced versions that won't be selected
+ 2021-06-24 a9bb38222a net: remove hard-coded timeout in dialClosedPort test helper
+ 2021-06-24 86d72fa2cb time: handle invalid UTF-8 byte sequences in quote to prevent panic
+ 2021-06-24 44a12e5f33 cmd/go: search breadth-first instead of depth-first for test dependency cycles
+ 2021-06-24 73496e0df0 net: use absDomainName in the Windows lookupPTR test helper
+ 2021-06-24 222ed1b38a os: enable TestFifoEOF on openbsd
+ 2021-06-22 0ebd5a8de0 cmd/go: update ToolTags based on GOARCH value
+ 2021-06-22 5bd09e5efc spec: unsafe.Add/Slice are not permitted in statement context
+ 2021-06-22 666315b4d3 runtime/internal/atomic: remove incorrect pointer indirection in comment
+ 2021-06-22 63daa774b5 go/types: guard against checking instantiation when generics is disabled
+ 2021-06-22 197a5ee2ab cmd/gofmt: remove stale documentation for the -G flag
+ 2021-06-22 9afd158eb2 go/parser: parse an ast.IndexExpr for a[]
+ 2021-06-21 1bd5a20e3c cmd/go: add a -go flag to 'go mod graph'
+ 2021-06-21 761edf71f6 cmd/internal/moddeps: use a temporary directory for GOMODCACHE if needed
+ 2021-06-21 a0400420ad cmd/internal/moddeps: use -mod=readonly instead of -mod=mod
+ 2021-06-21 3f9ec83b10 cmd/go: document GOPPC64 environment variable
+ 2021-06-21 20bdfba325 go/scanner: fall back to next() when encountering 0 bytes in parseIdentifier
+ 2021-06-21 44f9a3566c database/sql: fix deadlock test in prepare statement
+ 2021-06-21 16e82be454 runtime: fix crash during VDSO calls on PowerPC
+ 2021-06-21 2e542c3c06 runtime/pprof: deflake TestMorestack more
+ 2021-06-21 ced0fdbad0 doc/go1.17: note deprecation of 'go get' for installing commands
+ 2021-06-21 7a5e7047a4 doc/go1.17: add Go 1.18 pre-announcements
+ 2021-06-21 85a2e24afd doc/go1.17: add security-related release notes
+ 2021-06-21 1de332996c doc/go1.17: document go/parser.SkipObjectResolution
+ 2021-06-21 117ebe0f52 cmd/go: do not require the module cache to exist for 'go mod edit'
+ 2021-06-20 460900a7b5 os/signal: test with a significantly longer fatal timeout
+ 2021-06-19 b73cc4b02b database/sql: do not rely on timeout for deadlock test
+ 2021-06-18 86743e7d86 image: add RGBA64Image interface
+ 2021-06-18 9401172166 runtime: clarify Frames.Next documentation
+ 2021-06-18 57aaa19aae runtime: disable CPU profiling before removing the SIGPROF handler
+ 2021-06-18 6f22d2c682 doc/go1.17: fix typo
+ 2021-06-17 45f251ad6c cmd/pprof,runtime/pprof: disable test on more broken platforms
+ 2021-06-17 ed834853ad cmd/go: replace a TODO with an explanatory comment
+ 2021-06-17 4dede02550 cmd/pprof: make ObjAddr a no-op
+ 2021-06-17 97cee43c93 testing: drop unusual characters from TempDir directory name
+ 2021-06-17 b0355a3e72 time: fix receiver for Time.IsDST method
+ 2021-06-17 881b6ea7ba doc/go1.17: fix redundant space
+ 2021-06-16 0e67ce3d28 cmd/go: in lazy modules, add transitive imports for 'go get' arguments
+ 2021-06-16 6ea2af0890 cmd/go: add a regression test for #45979
+ 2021-06-16 a294e4e798 math/rand: mention half-open intervals explicitly
+ 2021-06-16 a6a853f94c cmd/asm: restore supporting of *1 scaling on ARM64
+ 2021-06-16 785a8f677f cmd/compile: better error message for invalid untyped operation
+ 2021-06-16 a752bc0746 syscall: fix TestGroupCleanupUserNamespace test failure on Fedora
+ 2021-06-15 d77f4c0c5c net/http: improve some server docs
+ 2021-06-15 219fe9d547 cmd/go: ignore UTF8 BOM when reading source code
+ 2021-06-15 723f199edd cmd/link: set correct flags in .dynamic for PIE buildmode
+ 2021-06-15 4d2d89ff42 cmd/go, go/build: update docs to use //go:build syntax
+ 2021-06-15 033d885315 doc/go1.17: document go run pkg@version
+ 2021-06-15 ea8612ef42 syscall: disable c-shared test when no cgo, for windows/arm
+ 2021-06-15 abc56fd1a0 internal/bytealg: remove duplicate go:build line
+ 2021-06-15 4061d3463b syscall: rewrite handle inheritance test to use C rather than Powershell
+ 2021-06-15 cf4e3e3d3b reflect: explain why convertible or comparable types may still panic
+ 2021-06-14 7841cb14d9 doc/go1.17: assorted fixes
+ 2021-06-14 8a5a6f46dc debug/elf: don't apply DWARF relocations for ET_EXEC binaries
+ 2021-06-14 9d13f8d43e runtime: update the variable name in comment
+ 2021-06-14 0fd20ed5b6 reflect: use same conversion panic in reflect and runtime
+ 2021-06-14 6bbb0a9d4a cmd/internal/sys: mark windows/arm64 as c-shared-capable
+ 2021-06-14 d4f34f8c63 doc/go1.17: reword "results" in stack trace printing
+ 2021-06-14 fdab5be159 doc/go1.17: further revise OpenBSD release notes
+ 2021-06-14 326ea438bb cmd/compile: rewrite a, b = f() to use temporaries when type not identical
+ 2021-06-14 3249b645c9 cmd/compile: factor out rewrite multi-valued f()
+ 2021-06-13 14305bf0b9 misc/cgo: generate Windows import libraries for clang
+ 2021-06-13 24cff0f044 cmd/go, misc/cgo: skip test if no .edata
+ 2021-06-13 67b1b6a2e3 cmd/compile: allow ir.OSLICE2ARRPTR in mayCall
+ 2021-06-12 1ed0d129e9 runtime: testprogcgo: don't call exported Go functions directly from Go
+ 2021-06-12 9d46ee5ac4 reflect: handle stack-to-register translation in callMethod
+ 2021-06-11 e552a6d312 cmd/go: remove hint when no module is suggested
+ 2021-06-11 16b5d766d8 syscall: do not load native libraries on non-native powershell on arm
+ 2021-06-11 77aa209b38 runtime: loop on EINTR in macOS sigNoteSleep
+ 2021-06-11 e2dc6dd5c9 doc/go1.17: clean up formatting of gofmt section
+ 2021-06-11 2f1128461d cmd/go: match Windows paths in TestScript/mod_invalid_version
+ 2021-06-11 2721da2608 doc/go1.17: fix formatting near httptest
+ 2021-06-10 770f1de8c5 net/http: remove test-only private key from production binaries
+ 2021-06-10 8d11b1d117 cmd/go: report the imports of CompiledGoFiles in ImportMap
+ 2021-06-10 dc00dc6c6b crypto/tls: let HTTP/1.1 clients connect to servers with NextProtos "h2"
+ 2021-06-09 27f83723e9 api: promote next to go1.17
+ 2021-06-09 182157c81a doc/go1.17: remove lingering TODO
+ 2021-06-09 a5bc060b42 doc/go1.17: document strconv changes for Go 1.17
+ 2021-06-09 1402b27d46 strconv: document parsing of leading +/-
+ 2021-06-09 df35ade067 doc/go1.17: document //go:build lines
+ 2021-06-09 e4e7807d24 net/http: add AllowQuerySemicolons
+ 2021-06-09 ec3026d032 doc/go1.17: remove TODO for ports section
+ 2021-06-09 e6dda19888 net/url: reject query values with semicolons
+ 2021-06-09 139e935d3c math/big: comment division
+ 2021-06-09 aa5540cd82 cmd/compile: make map.zero symbol content-addressable
+ 2021-06-09 07ca28d529 cmd/link: fix bug in -strictdups checking of BSS symbols
+ 2021-06-08 bcecae2af6 doc/go1.17: mention new possibility of type conversion panicking
+ 2021-06-08 63dcab2e91 doc/go1.17: mention new vet checks sigchanyzer and stdmethods.
+ 2021-06-08 6551763a60 doc/go1.17: mention block profile bias fix
+ 2021-06-08 cb80937bf6 Revert "doc/go1.17: mention block profile bias fix"
+ 2021-06-08 d3e3d03666 net: reject leading zeros in IP address parsers
+ 2021-06-08 da4a640141 doc/go1.17: revise OpenBSD release notes
+ 2021-06-08 689f4c7415 doc/go1.17: mention block profile bias fix
+ 2021-06-08 9afe071c60 doc/go1.17: remove TODO for Tools section
+ 2021-06-08 f753d7223e doc/go1.17: resolve TODO for cmd/cover
+ 2021-06-08 9498b0155d cmd/go: in Go 1.17+ modules, add indirect go.mod dependencies separately from direct ones
+ 2021-06-08 949f00cebe doc/go1.17: add release notes for crypto packages
+ 2021-06-08 0fb3e2c184 doc/go1.17: add a release note for the '-compat' flag to 'go mod tidy'
+ 2021-06-08 2169deb352 cmd/compile: use t.AllMethods when sorting typesByString
+ 2021-06-08 c20bcb6488 runtime: remove out-of-date comments about frame skipping
+ 2021-06-07 39c39ae52f doc: document Go 1.17 language changes
+ 2021-06-07 dc8b558951 cmd/dist: pass -Wno-lto-type-mismatch in swig_callback_lto
+ 2021-06-07 909dd5e010 strconv: ParseFloat: always return ErrSyntax for bad syntax
+ 2021-06-07 8212707871 crypto/elliptic: update P-521 docs to say it's constant-time
+ 2021-06-07 7406180012 fmt: split package documentation into more sections
+ 2021-06-07 e3176bbc3e crypto/tls: fix typo in Config.NextProtos docs
+ 2021-06-05 e1fa26026d spec: improve wording consistency by eliminating "specifier"
+ 2021-06-05 f490134126 spec: improve wording by choosing an official term "keyword"
+ 2021-06-05 e3cb381704 go/internal/gcimporter: don't waste CPU copying bytes in `io.ReadAll`
+ 2021-06-05 9d669ed47a misc/cgo/errors: use expected column numbers
+ 2021-06-04 95939e8de7 cmd/compile/internal/abi: fix typo in comment
+ 2021-06-04 831f9376d8 net/http: fix ResponseWriter.ReadFrom with short reads
+ 2021-06-04 3a9d906edc os: avoid finalizer race in windows process object
+ 2021-06-04 105c5b50e0 os: terminate windows processes via handle directly
+ 2021-06-04 79cd407f88 syscall: regenerate zsyscall_windows.go
+ 2021-06-04 c6b6211229 doc/go1.17: document testing changes for Go 1.17
+ 2021-06-04 0214440075 syscall: do not pass console handles to PROC_THREAD_ATTRIBUTE_HANDLE_LIST on Windows 7
+ 2021-06-04 962d5c997a cmd/compile,go/types: restrict use of unsafe.{Add,Slice} to go1.17 or newer
+ 2021-06-04 b29b123e07 cmd/compile: remove spurious ir.Dump
+ 2021-06-03 6d98301114 cmd/link: use correct alignment in PE DWARF sections
+ 2021-06-03 e0d029f758 runtime: avoid gp.lockedm race in exitsyscall0

Change-Id: I00216c3c36e64814c44c79f25d1f38e4df6c1f24

1  2 
api/next.txt
src/cmd/go/alldocs.go
src/cmd/go/internal/cfg/cfg.go
src/cmd/go/internal/load/pkg.go
src/cmd/go/internal/load/test.go
src/go/build/deps_test.go
src/testing/fuzz.go
src/testing/testing.go

diff --cc api/next.txt
index 564f672c690b9ed12e64623280b835ae34fab0c8,e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..6b568e285711170274b706556803cae3afa2e7b5
- pkg testing, method (*B) Setenv(string, string)
 +pkg compress/lzw, method (*Reader) Close() error
 +pkg compress/lzw, method (*Reader) Read([]uint8) (int, error)
 +pkg compress/lzw, method (*Reader) Reset(io.Reader, Order, int)
 +pkg compress/lzw, method (*Writer) Close() error
 +pkg compress/lzw, method (*Writer) Reset(io.Writer, Order, int)
 +pkg compress/lzw, method (*Writer) Write([]uint8) (int, error)
 +pkg compress/lzw, type Reader struct
 +pkg compress/lzw, type Writer struct
 +pkg crypto/tls, method (*CertificateRequestInfo) Context() context.Context
 +pkg crypto/tls, method (*ClientHelloInfo) Context() context.Context
 +pkg crypto/tls, method (*Conn) HandshakeContext(context.Context) error
 +pkg debug/elf, const SHT_MIPS_ABIFLAGS = 1879048234
 +pkg debug/elf, const SHT_MIPS_ABIFLAGS SectionType
 +pkg encoding/csv, method (*Reader) FieldPos(int) (int, int)
 +pkg go/ast, method (*FuncDecl) IsMethod() bool
 +pkg go/build, type Context struct, ToolTags []string
 +pkg go/parser, const SkipObjectResolution = 64
 +pkg go/parser, const SkipObjectResolution Mode
 +pkg go/types, type Config struct, GoVersion string
 +pkg io/fs, func FileInfoToDirEntry(FileInfo) DirEntry
 +pkg net, method (*ParseError) Temporary() bool
 +pkg net, method (*ParseError) Timeout() bool
 +pkg net, method (IP) IsPrivate() bool
 +pkg reflect, func VisibleFields(Type) []StructField
 +pkg reflect, method (Method) IsExported() bool
 +pkg reflect, method (StructField) IsExported() bool
 +pkg runtime/cgo (darwin-amd64-cgo), func NewHandle(interface{}) Handle
 +pkg runtime/cgo (darwin-amd64-cgo), method (Handle) Delete()
 +pkg runtime/cgo (darwin-amd64-cgo), method (Handle) Value() interface{}
 +pkg runtime/cgo (darwin-amd64-cgo), type Handle uintptr
 +pkg runtime/cgo (freebsd-386-cgo), func NewHandle(interface{}) Handle
 +pkg runtime/cgo (freebsd-386-cgo), method (Handle) Delete()
 +pkg runtime/cgo (freebsd-386-cgo), method (Handle) Value() interface{}
 +pkg runtime/cgo (freebsd-386-cgo), type Handle uintptr
 +pkg runtime/cgo (freebsd-amd64-cgo), func NewHandle(interface{}) Handle
 +pkg runtime/cgo (freebsd-amd64-cgo), method (Handle) Delete()
 +pkg runtime/cgo (freebsd-amd64-cgo), method (Handle) Value() interface{}
 +pkg runtime/cgo (freebsd-amd64-cgo), type Handle uintptr
 +pkg runtime/cgo (freebsd-arm-cgo), func NewHandle(interface{}) Handle
 +pkg runtime/cgo (freebsd-arm-cgo), method (Handle) Delete()
 +pkg runtime/cgo (freebsd-arm-cgo), method (Handle) Value() interface{}
 +pkg runtime/cgo (freebsd-arm-cgo), type Handle uintptr
 +pkg runtime/cgo (linux-386-cgo), func NewHandle(interface{}) Handle
 +pkg runtime/cgo (linux-386-cgo), method (Handle) Delete()
 +pkg runtime/cgo (linux-386-cgo), method (Handle) Value() interface{}
 +pkg runtime/cgo (linux-386-cgo), type Handle uintptr
 +pkg runtime/cgo (linux-amd64-cgo), func NewHandle(interface{}) Handle
 +pkg runtime/cgo (linux-amd64-cgo), method (Handle) Delete()
 +pkg runtime/cgo (linux-amd64-cgo), method (Handle) Value() interface{}
 +pkg runtime/cgo (linux-amd64-cgo), type Handle uintptr
 +pkg runtime/cgo (linux-arm-cgo), func NewHandle(interface{}) Handle
 +pkg runtime/cgo (linux-arm-cgo), method (Handle) Delete()
 +pkg runtime/cgo (linux-arm-cgo), method (Handle) Value() interface{}
 +pkg runtime/cgo (linux-arm-cgo), type Handle uintptr
 +pkg runtime/cgo (netbsd-386-cgo), func NewHandle(interface{}) Handle
 +pkg runtime/cgo (netbsd-386-cgo), method (Handle) Delete()
 +pkg runtime/cgo (netbsd-386-cgo), method (Handle) Value() interface{}
 +pkg runtime/cgo (netbsd-386-cgo), type Handle uintptr
 +pkg runtime/cgo (netbsd-amd64-cgo), func NewHandle(interface{}) Handle
 +pkg runtime/cgo (netbsd-amd64-cgo), method (Handle) Delete()
 +pkg runtime/cgo (netbsd-amd64-cgo), method (Handle) Value() interface{}
 +pkg runtime/cgo (netbsd-amd64-cgo), type Handle uintptr
 +pkg runtime/cgo (netbsd-arm-cgo), func NewHandle(interface{}) Handle
 +pkg runtime/cgo (netbsd-arm-cgo), method (Handle) Delete()
 +pkg runtime/cgo (netbsd-arm-cgo), method (Handle) Value() interface{}
 +pkg runtime/cgo (netbsd-arm-cgo), type Handle uintptr
 +pkg runtime/cgo (netbsd-arm64-cgo), func NewHandle(interface{}) Handle
 +pkg runtime/cgo (netbsd-arm64-cgo), method (Handle) Delete()
 +pkg runtime/cgo (netbsd-arm64-cgo), method (Handle) Value() interface{}
 +pkg runtime/cgo (netbsd-arm64-cgo), type Handle uintptr
 +pkg runtime/cgo (openbsd-386-cgo), func NewHandle(interface{}) Handle
 +pkg runtime/cgo (openbsd-386-cgo), method (Handle) Delete()
 +pkg runtime/cgo (openbsd-386-cgo), method (Handle) Value() interface{}
 +pkg runtime/cgo (openbsd-386-cgo), type Handle uintptr
 +pkg runtime/cgo (openbsd-amd64-cgo), func NewHandle(interface{}) Handle
 +pkg runtime/cgo (openbsd-amd64-cgo), method (Handle) Delete()
 +pkg runtime/cgo (openbsd-amd64-cgo), method (Handle) Value() interface{}
 +pkg runtime/cgo (openbsd-amd64-cgo), type Handle uintptr
 +pkg syscall (openbsd-386), const MSG_CMSG_CLOEXEC = 2048
 +pkg syscall (openbsd-386), const MSG_CMSG_CLOEXEC ideal-int
 +pkg syscall (openbsd-386-cgo), const MSG_CMSG_CLOEXEC = 2048
 +pkg syscall (openbsd-386-cgo), const MSG_CMSG_CLOEXEC ideal-int
 +pkg syscall (openbsd-amd64), const MSG_CMSG_CLOEXEC = 2048
 +pkg syscall (openbsd-amd64), const MSG_CMSG_CLOEXEC ideal-int
 +pkg syscall (openbsd-amd64-cgo), const MSG_CMSG_CLOEXEC = 2048
 +pkg syscall (openbsd-amd64-cgo), const MSG_CMSG_CLOEXEC ideal-int
 +pkg syscall (windows-386), type SysProcAttr struct, AdditionalInheritedHandles []Handle
 +pkg syscall (windows-386), type SysProcAttr struct, ParentProcess Handle
 +pkg syscall (windows-amd64), type SysProcAttr struct, AdditionalInheritedHandles []Handle
 +pkg syscall (windows-amd64), type SysProcAttr struct, ParentProcess Handle
- >>>>>>> origin/master
 +pkg testing, func Fuzz(func(*F)) FuzzResult
 +pkg testing, func MainStart(testDeps, []InternalTest, []InternalBenchmark, []InternalFuzzTarget, []InternalExample) *M
 +pkg testing, func RunFuzzTargets(func(string, string) (bool, error), []InternalFuzzTarget) bool
 +pkg testing, func RunFuzzing(func(string, string) (bool, error), []InternalFuzzTarget) bool
++pkg testing, method (*B) Setenv(string, string)
 +pkg testing, method (*F) Add(...interface{})
 +pkg testing, method (*F) Cleanup(func())
 +pkg testing, method (*F) Error(...interface{})
 +pkg testing, method (*F) Errorf(string, ...interface{})
 +pkg testing, method (*F) Fail()
 +pkg testing, method (*F) FailNow()
 +pkg testing, method (*F) Failed() bool
 +pkg testing, method (*F) Fatal(...interface{})
 +pkg testing, method (*F) Fatalf(string, ...interface{})
 +pkg testing, method (*F) Fuzz(interface{})
 +pkg testing, method (*F) Helper()
 +pkg testing, method (*F) Log(...interface{})
 +pkg testing, method (*F) Logf(string, ...interface{})
 +pkg testing, method (*F) Name() string
++pkg testing, method (*F) Setenv(string, string)
 +pkg testing, method (*F) Skip(...interface{})
 +pkg testing, method (*F) SkipNow()
 +pkg testing, method (*F) Skipf(string, ...interface{})
 +pkg testing, method (*F) Skipped() bool
 +pkg testing, method (*F) TempDir() string
 +pkg testing, method (*T) Setenv(string, string)
 +pkg testing, method (FuzzResult) String() string
 +pkg testing, type F struct
 +pkg testing, type FuzzResult struct
 +pkg testing, type FuzzResult struct, Crasher entry
 +pkg testing, type FuzzResult struct, Error error
 +pkg testing, type FuzzResult struct, N int
 +pkg testing, type FuzzResult struct, T time.Duration
 +pkg testing, type InternalFuzzTarget struct
 +pkg testing, type InternalFuzzTarget struct, Fn func(*F)
 +pkg testing, type InternalFuzzTarget struct, Name string
 +pkg text/template/parse, const SkipFuncCheck = 2
 +pkg text/template/parse, const SkipFuncCheck Mode
 +pkg time, func UnixMicro(int64) Time
 +pkg time, func UnixMilli(int64) Time
 +pkg time, method (*Time) IsDST() bool
 +pkg time, method (Time) UnixMicro() int64
 +pkg time, method (Time) UnixMilli() int64
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index d62eb55dec794eb9591e248326234a769c1f9fe9,0000000000000000000000000000000000000000..6f5cdcc3899b8032e3f621a2b09b234b95cdf0ab
mode 100644,000000..100644
--- /dev/null
@@@ -1,732 -1,0 +1,737 @@@
 +// Copyright 2020 The Go Authors. All rights reserved.
 +// Use of this source code is governed by a BSD-style
 +// license that can be found in the LICENSE file.
 +
 +package testing
 +
 +import (
 +      "errors"
 +      "flag"
 +      "fmt"
 +      "io"
 +      "os"
 +      "path/filepath"
 +      "reflect"
 +      "runtime"
 +      "sync/atomic"
 +      "time"
 +)
 +
 +func initFuzzFlags() {
 +      matchFuzz = flag.String("test.fuzz", "", "run the fuzz target matching `regexp`")
 +      flag.Var(&fuzzDuration, "test.fuzztime", "time to spend fuzzing; default is to run indefinitely")
 +      flag.Var(&minimizeDuration, "test.fuzzminimizetime", "time to spend minimizing a value after finding a crash")
 +      fuzzCacheDir = flag.String("test.fuzzcachedir", "", "directory where interesting fuzzing inputs are stored")
 +      isFuzzWorker = flag.Bool("test.fuzzworker", false, "coordinate with the parent process to fuzz random values")
 +}
 +
 +var (
 +      matchFuzz        *string
 +      fuzzDuration     durationOrCountFlag
 +      minimizeDuration = durationOrCountFlag{d: 60 * time.Second}
 +      fuzzCacheDir     *string
 +      isFuzzWorker     *bool
 +
 +      // corpusDir is the parent directory of the target's seed corpus within
 +      // the package.
 +      corpusDir = "testdata/corpus"
 +)
 +
 +// fuzzWorkerExitCode is used as an exit code by fuzz worker processes after an internal error.
 +// This distinguishes internal errors from uncontrolled panics and other crashes.
 +// Keep in sync with internal/fuzz.workerExitCode.
 +const fuzzWorkerExitCode = 70
 +
 +// InternalFuzzTarget is an internal type but exported because it is cross-package;
 +// it is part of the implementation of the "go test" command.
 +type InternalFuzzTarget struct {
 +      Name string
 +      Fn   func(f *F)
 +}
 +
 +// F is a type passed to fuzz targets for fuzz testing.
 +type F struct {
 +      common
 +      fuzzContext *fuzzContext
 +      testContext *testContext
 +      inFuzzFn    bool          // set to true when fuzz function is running
 +      corpus      []corpusEntry // corpus is the in-memory corpus
 +      result      FuzzResult    // result is the result of running the fuzz target
 +      fuzzCalled  bool
 +}
 +
 +var _ TB = (*F)(nil)
 +
 +// corpusEntry is an alias to the same type as internal/fuzz.CorpusEntry.
 +// We use a type alias because we don't want to export this type, and we can't
 +// importing internal/fuzz from testing.
 +type corpusEntry = struct {
 +      Parent     string
 +      Name       string
 +      Data       []byte
 +      Values     []interface{}
 +      Generation int
 +}
 +
 +// Cleanup registers a function to be called when the test and all its
 +// subtests complete. Cleanup functions will be called in last added,
 +// first called order.
 +func (f *F) Cleanup(fn func()) {
 +      if f.inFuzzFn {
 +              panic("testing: f.Cleanup was called inside the f.Fuzz function, use t.Cleanup instead")
 +      }
 +      f.common.Helper()
 +      f.common.Cleanup(fn)
 +}
 +
 +// Error is equivalent to Log followed by Fail.
 +func (f *F) Error(args ...interface{}) {
 +      if f.inFuzzFn {
 +              panic("testing: f.Error was called inside the f.Fuzz function, use t.Error instead")
 +      }
 +      f.common.Helper()
 +      f.common.Error(args...)
 +}
 +
 +// Errorf is equivalent to Logf followed by Fail.
 +func (f *F) Errorf(format string, args ...interface{}) {
 +      if f.inFuzzFn {
 +              panic("testing: f.Errorf was called inside the f.Fuzz function, use t.Errorf instead")
 +      }
 +      f.common.Helper()
 +      f.common.Errorf(format, args...)
 +}
 +
 +// Fail marks the function as having failed but continues execution.
 +func (f *F) Fail() {
 +      if f.inFuzzFn {
 +              panic("testing: f.Fail was called inside the f.Fuzz function, use t.Fail instead")
 +      }
 +      f.common.Helper()
 +      f.common.Fail()
 +}
 +
 +// FailNow marks the function as having failed and stops its execution
 +// by calling runtime.Goexit (which then runs all deferred calls in the
 +// current goroutine).
 +// Execution will continue at the next test or benchmark.
 +// FailNow must be called from the goroutine running the
 +// test or benchmark function, not from other goroutines
 +// created during the test. Calling FailNow does not stop
 +// those other goroutines.
 +func (f *F) FailNow() {
 +      if f.inFuzzFn {
 +              panic("testing: f.FailNow was called inside the f.Fuzz function, use t.FailNow instead")
 +      }
 +      f.common.Helper()
 +      f.common.FailNow()
 +}
 +
 +// Fatal is equivalent to Log followed by FailNow.
 +func (f *F) Fatal(args ...interface{}) {
 +      if f.inFuzzFn {
 +              panic("testing: f.Fatal was called inside the f.Fuzz function, use t.Fatal instead")
 +      }
 +      f.common.Helper()
 +      f.common.Fatal(args...)
 +}
 +
 +// Fatalf is equivalent to Logf followed by FailNow.
 +func (f *F) Fatalf(format string, args ...interface{}) {
 +      if f.inFuzzFn {
 +              panic("testing: f.Fatalf was called inside the f.Fuzz function, use t.Fatalf instead")
 +      }
 +      f.common.Helper()
 +      f.common.Fatalf(format, args...)
 +}
 +
 +// Helper marks the calling function as a test helper function.
 +// When printing file and line information, that function will be skipped.
 +// Helper may be called simultaneously from multiple goroutines.
 +func (f *F) Helper() {
 +      if f.inFuzzFn {
 +              panic("testing: f.Helper was called inside the f.Fuzz function, use t.Helper instead")
 +      }
 +
 +      // common.Helper is inlined here.
 +      // If we called it, it would mark F.Helper as the helper
 +      // instead of the caller.
 +      f.mu.Lock()
 +      defer f.mu.Unlock()
 +      if f.helperPCs == nil {
 +              f.helperPCs = make(map[uintptr]struct{})
 +      }
 +      // repeating code from callerName here to save walking a stack frame
 +      var pc [1]uintptr
 +      n := runtime.Callers(2, pc[:]) // skip runtime.Callers + Helper
 +      if n == 0 {
 +              panic("testing: zero callers found")
 +      }
 +      if _, found := f.helperPCs[pc[0]]; !found {
 +              f.helperPCs[pc[0]] = struct{}{}
 +              f.helperNames = nil // map will be recreated next time it is needed
 +      }
 +}
 +
++// Setenv is not supported since fuzzing runs in parallel.
++func (f *F) Setenv(key, value string) {
++      panic("testing: f.Setenv is not supported")
++}
++
 +// Skip is equivalent to Log followed by SkipNow.
 +func (f *F) Skip(args ...interface{}) {
 +      if f.inFuzzFn {
 +              panic("testing: f.Skip was called inside the f.Fuzz function, use t.Skip instead")
 +      }
 +      f.common.Helper()
 +      f.common.Skip(args...)
 +}
 +
 +// SkipNow marks the test as having been skipped and stops its execution
 +// by calling runtime.Goexit.
 +// If a test fails (see Error, Errorf, Fail) and is then skipped,
 +// it is still considered to have failed.
 +// Execution will continue at the next test or benchmark. See also FailNow.
 +// SkipNow must be called from the goroutine running the test, not from
 +// other goroutines created during the test. Calling SkipNow does not stop
 +// those other goroutines.
 +func (f *F) SkipNow() {
 +      if f.inFuzzFn {
 +              panic("testing: f.SkipNow was called inside the f.Fuzz function, use t.SkipNow instead")
 +      }
 +      f.common.Helper()
 +      f.common.SkipNow()
 +}
 +
 +// Skipf is equivalent to Logf followed by SkipNow.
 +func (f *F) Skipf(format string, args ...interface{}) {
 +      if f.inFuzzFn {
 +              panic("testing: f.Skipf was called inside the f.Fuzz function, use t.Skipf instead")
 +      }
 +      f.common.Helper()
 +      f.common.Skipf(format, args...)
 +}
 +
 +// TempDir returns a temporary directory for the test to use.
 +// The directory is automatically removed by Cleanup when the test and
 +// all its subtests complete.
 +// Each subsequent call to t.TempDir returns a unique directory;
 +// if the directory creation fails, TempDir terminates the test by calling Fatal.
 +func (f *F) TempDir() string {
 +      if f.inFuzzFn {
 +              panic("testing: f.TempDir was called inside the f.Fuzz function, use t.TempDir instead")
 +      }
 +      f.common.Helper()
 +      return f.common.TempDir()
 +}
 +
 +// Add will add the arguments to the seed corpus for the fuzz target. This will
 +// be a no-op if called after or within the Fuzz function. The args must match
 +// or be convertible to those in the Fuzz function.
 +func (f *F) Add(args ...interface{}) {
 +      var values []interface{}
 +      for i := range args {
 +              if t := reflect.TypeOf(args[i]); !supportedTypes[t] {
 +                      panic(fmt.Sprintf("testing: unsupported type to Add %v", t))
 +              }
 +              values = append(values, args[i])
 +      }
 +      f.corpus = append(f.corpus, corpusEntry{Values: values, Name: fmt.Sprintf("seed#%d", len(f.corpus))})
 +}
 +
 +// supportedTypes represents all of the supported types which can be fuzzed.
 +var supportedTypes = map[reflect.Type]bool{
 +      reflect.TypeOf(([]byte)("")):  true,
 +      reflect.TypeOf((string)("")):  true,
 +      reflect.TypeOf((bool)(false)): true,
 +      reflect.TypeOf((byte)(0)):     true,
 +      reflect.TypeOf((rune)(0)):     true,
 +      reflect.TypeOf((float32)(0)):  true,
 +      reflect.TypeOf((float64)(0)):  true,
 +      reflect.TypeOf((int)(0)):      true,
 +      reflect.TypeOf((int8)(0)):     true,
 +      reflect.TypeOf((int16)(0)):    true,
 +      reflect.TypeOf((int32)(0)):    true,
 +      reflect.TypeOf((int64)(0)):    true,
 +      reflect.TypeOf((uint)(0)):     true,
 +      reflect.TypeOf((uint8)(0)):    true,
 +      reflect.TypeOf((uint16)(0)):   true,
 +      reflect.TypeOf((uint32)(0)):   true,
 +      reflect.TypeOf((uint64)(0)):   true,
 +}
 +
 +// Fuzz runs the fuzz function, ff, for fuzz testing. If ff fails for a set of
 +// arguments, those arguments will be added to the seed corpus.
 +//
 +// ff must be a function with no return value whose first argument is *T and
 +// whose remaining arguments are the types to be fuzzed.
 +// For example:
 +//
 +// f.Fuzz(func(t *testing.T, b []byte, i int) { ... })
 +//
 +// This function should be fast, deterministic, and stateless.
 +// None of the pointers to any input data should be retained between executions.
 +//
 +// This is a terminal function which will terminate the currently running fuzz
 +// target by calling runtime.Goexit.
 +// To run any code after fuzzing stops, use (*F).Cleanup.
 +func (f *F) Fuzz(ff interface{}) {
 +      if f.fuzzCalled {
 +              panic("testing: F.Fuzz called more than once")
 +      }
 +      f.fuzzCalled = true
 +      if f.failed {
 +              return
 +      }
 +      f.Helper()
 +
 +      // ff should be in the form func(*testing.T, ...interface{})
 +      fn := reflect.ValueOf(ff)
 +      fnType := fn.Type()
 +      if fnType.Kind() != reflect.Func {
 +              panic("testing: F.Fuzz must receive a function")
 +      }
 +      if fnType.NumIn() < 2 || fnType.In(0) != reflect.TypeOf((*T)(nil)) {
 +              panic("testing: F.Fuzz function must receive at least two arguments, where the first argument is a *T")
 +      }
 +
 +      // Save the types of the function to compare against the corpus.
 +      var types []reflect.Type
 +      for i := 1; i < fnType.NumIn(); i++ {
 +              t := fnType.In(i)
 +              if !supportedTypes[t] {
 +                      panic(fmt.Sprintf("testing: unsupported type for fuzzing %v", t))
 +              }
 +              types = append(types, t)
 +      }
 +
 +      // Check the corpus provided by f.Add
 +      for _, c := range f.corpus {
 +              if err := f.fuzzContext.checkCorpus(c.Values, types); err != nil {
 +                      // TODO: Is there a way to save which line number is associated
 +                      // with the f.Add call that failed?
 +                      f.Fatal(err)
 +              }
 +      }
 +
 +      // Load seed corpus
 +      c, err := f.fuzzContext.readCorpus(filepath.Join(corpusDir, f.name), types)
 +      if err != nil {
 +              f.Fatal(err)
 +      }
 +      f.corpus = append(f.corpus, c...)
 +
 +      // run calls fn on a given input, as a subtest with its own T.
 +      // run is analogous to T.Run. The test filtering and cleanup works similarly.
 +      // fn is called in its own goroutine.
 +      //
 +      // TODO(jayconrod,katiehockman): dedupe testdata corpus with entries from f.Add
 +      run := func(e corpusEntry) error {
 +              if e.Values == nil {
 +                      // Every code path should have already unmarshaled Data into Values.
 +                      // It's our fault if it didn't.
 +                      panic(fmt.Sprintf("corpus file %q was not unmarshaled", e.Name))
 +              }
 +              if shouldFailFast() {
 +                      return nil
 +              }
 +              testName := f.common.name
 +              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.
 +              var pc [maxStackLen]uintptr
 +              n := runtime.Callers(2, pc[:])
 +              t := &T{
 +                      common: common{
 +                              barrier: make(chan bool),
 +                              signal:  make(chan bool),
 +                              name:    testName,
 +                              parent:  &f.common,
 +                              level:   f.level + 1,
 +                              creator: pc[:n],
 +                              chatty:  f.chatty,
 +                              fuzzing: true,
 +                      },
 +                      context: f.testContext,
 +              }
 +              t.w = indenter{&t.common}
 +              if t.chatty != nil {
 +                      t.chatty.Updatef(t.name, "=== RUN  %s\n", t.name)
 +              }
 +              f.inFuzzFn = true
 +              go tRunner(t, func(t *T) {
 +                      args := []reflect.Value{reflect.ValueOf(t)}
 +                      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.
 +                      defer f.fuzzContext.snapshotCoverage()
 +                      f.fuzzContext.resetCoverage()
 +                      fn.Call(args)
 +              })
 +              <-t.signal
 +              f.inFuzzFn = false
 +              if t.Failed() {
 +                      return errors.New(string(f.output))
 +              }
 +              return nil
 +      }
 +
 +      switch {
 +      case f.fuzzContext.coordinateFuzzing != nil:
 +              // Fuzzing is enabled, and this is the test process started by 'go test'.
 +              // Act as the coordinator process, and coordinate workers to perform the
 +              // actual fuzzing.
 +              corpusTargetDir := filepath.Join(corpusDir, f.name)
 +              cacheTargetDir := filepath.Join(*fuzzCacheDir, f.name)
 +              err := f.fuzzContext.coordinateFuzzing(
 +                      fuzzDuration.d,
 +                      int64(fuzzDuration.n),
 +                      minimizeDuration.d,
 +                      int64(minimizeDuration.n),
 +                      *parallel,
 +                      f.corpus,
 +                      types,
 +                      corpusTargetDir,
 +                      cacheTargetDir)
 +              if err != nil {
 +                      f.result = FuzzResult{Error: err}
 +                      f.Fail()
 +                      fmt.Fprintf(f.w, "%v\n", err)
 +                      if crashErr, ok := err.(fuzzCrashError); ok {
 +                              crashName := crashErr.CrashName()
 +                              fmt.Fprintf(f.w, "Crash written to %s\n", filepath.Join("testdata/corpus", f.name, crashName))
 +                              fmt.Fprintf(f.w, "To re-run:\ngo test %s -run=%s/%s\n", f.fuzzContext.importPath(), f.name, crashName)
 +                      }
 +              }
 +              // TODO(jayconrod,katiehockman): Aggregate statistics across workers
 +              // and add to FuzzResult (ie. time taken, num iterations)
 +
 +      case f.fuzzContext.runFuzzWorker != nil:
 +              // Fuzzing is enabled, and this is a worker process. Follow instructions
 +              // from the coordinator.
 +              if err := f.fuzzContext.runFuzzWorker(run); err != nil {
 +                      // Internal errors are marked with f.Fail; user code may call this too, before F.Fuzz.
 +                      // The worker will exit with fuzzWorkerExitCode, indicating this is a failure
 +                      // (and 'go test' should exit non-zero) but a crasher should not be recorded.
 +                      f.Errorf("communicating with fuzzing coordinator: %v", err)
 +              }
 +
 +      default:
 +              // Fuzzing is not enabled, or will be done later. Only run the seed
 +              // corpus now.
 +              for _, e := range f.corpus {
 +                      run(e)
 +              }
 +      }
 +
 +      // Record that the fuzz function (or coordinateFuzzing or runFuzzWorker)
 +      // returned normally. This is used to distinguish runtime.Goexit below
 +      // from panic(nil).
 +      f.finished = true
 +
 +      // Terminate the goroutine. F.Fuzz should not return.
 +      // We cannot call runtime.Goexit from a deferred function: if there is a
 +      // panic, that would replace the panic value with nil.
 +      runtime.Goexit()
 +}
 +
 +func (f *F) report() {
 +      if *isFuzzWorker || f.parent == nil {
 +              return
 +      }
 +      dstr := fmtDuration(f.duration)
 +      format := "--- %s: %s (%s)\n"
 +      if f.Failed() {
 +              f.flushToParent(f.name, format, "FAIL", f.name, dstr)
 +      } else if f.chatty != nil {
 +              if f.Skipped() {
 +                      f.flushToParent(f.name, format, "SKIP", f.name, dstr)
 +              } else {
 +                      f.flushToParent(f.name, format, "PASS", f.name, dstr)
 +              }
 +      }
 +}
 +
 +// FuzzResult contains the results of a fuzz run.
 +type FuzzResult struct {
 +      N     int           // The number of iterations.
 +      T     time.Duration // The total time taken.
 +      Error error         // Error is the error from the crash
 +}
 +
 +func (r FuzzResult) String() string {
 +      s := ""
 +      if r.Error == nil {
 +              return s
 +      }
 +      s = fmt.Sprintf("%s", r.Error.Error())
 +      return s
 +}
 +
 +// fuzzCrashError is satisfied by a crash detected within the fuzz function.
 +// These errors are written to the seed corpus and can be re-run with 'go test'.
 +// Errors within the fuzzing framework (like I/O errors between coordinator
 +// and worker processes) don't satisfy this interface.
 +type fuzzCrashError interface {
 +      error
 +      Unwrap() error
 +
 +      // CrashName returns the name of the subtest that corresponds to the saved
 +      // crash input file in the seed corpus. The test can be re-run with
 +      // go test $pkg -run=$target/$name where $pkg is the package's import path,
 +      // $target is the fuzz target name, and $name is the string returned here.
 +      CrashName() string
 +}
 +
 +// fuzzContext holds all fields that are common to all fuzz targets.
 +type fuzzContext struct {
 +      importPath        func() string
 +      coordinateFuzzing func(time.Duration, int64, time.Duration, int64, int, []corpusEntry, []reflect.Type, string, string) error
 +      runFuzzWorker     func(func(corpusEntry) error) error
 +      readCorpus        func(string, []reflect.Type) ([]corpusEntry, error)
 +      checkCorpus       func(vals []interface{}, types []reflect.Type) error
 +      resetCoverage     func()
 +      snapshotCoverage  func()
 +}
 +
 +// 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, 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,
 +              checkCorpus:      deps.CheckCorpus,
 +              resetCoverage:    deps.ResetCoverage,
 +              snapshotCoverage: deps.SnapshotCoverage,
 +      }
 +      root := common{w: os.Stdout} // gather output in one place
 +      if Verbose() {
 +              root.chatty = newChattyPrinter(root.w)
 +      }
 +      for _, ft := range fuzzTargets {
 +              if shouldFailFast() {
 +                      break
 +              }
 +              testName, matched, _ := tctx.match.fullName(nil, ft.Name)
 +              if !matched {
 +                      continue
 +              }
 +              f := &F{
 +                      common: common{
 +                              signal:  make(chan bool),
 +                              barrier: make(chan bool),
 +                              name:    testName,
 +                              parent:  &root,
 +                              level:   root.level + 1,
 +                              chatty:  root.chatty,
 +                      },
 +                      testContext: tctx,
 +                      fuzzContext: fctx,
 +              }
 +              f.w = indenter{&f.common}
 +              if f.chatty != nil {
 +                      f.chatty.Updatef(f.name, "=== RUN  %s\n", f.name)
 +              }
 +
 +              go fRunner(f, ft.Fn)
 +              <-f.signal
 +      }
 +      return root.ran, !root.Failed()
 +}
 +
 +// runFuzzing runs the fuzz target matching the pattern for -fuzz. Only one such
 +// fuzz target must match. This will run the fuzzing engine to generate and
 +// mutate new inputs against the f.Fuzz function.
 +//
 +// If fuzzing is disabled (-test.fuzz is not set), runFuzzing
 +// returns immediately.
 +func runFuzzing(deps testDeps, fuzzTargets []InternalFuzzTarget) (ran, ok bool) {
 +      // TODO(katiehockman,jayconrod): Should we do something special to make sure
 +      // we don't print f.Log statements again with runFuzzing, since we already
 +      // would have printed them when we ran runFuzzTargets (ie. seed corpus run)?
 +      if len(fuzzTargets) == 0 || *matchFuzz == "" {
 +              return false, true
 +      }
 +      m := newMatcher(deps.MatchString, *matchFuzz, "-test.fuzz")
 +      tctx := newTestContext(1, m)
 +      fctx := &fuzzContext{
 +              importPath:       deps.ImportPath,
 +              readCorpus:       deps.ReadCorpus,
 +              checkCorpus:      deps.CheckCorpus,
 +              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
 +      }
 +      if Verbose() && !*isFuzzWorker {
 +              root.chatty = newChattyPrinter(root.w)
 +      }
 +      var target *InternalFuzzTarget
 +      var f *F
 +      for i := range fuzzTargets {
 +              ft := &fuzzTargets[i]
 +              testName, matched, _ := tctx.match.fullName(nil, ft.Name)
 +              if !matched {
 +                      continue
 +              }
 +              if target != nil {
 +                      fmt.Fprintln(os.Stderr, "testing: warning: -fuzz matches more than one target, won't fuzz")
 +                      return false, true
 +              }
 +              target = ft
 +              f = &F{
 +                      common: common{
 +                              signal:  make(chan bool),
 +                              barrier: nil, // T.Parallel has no effect when fuzzing.
 +                              name:    testName,
 +                              parent:  &root,
 +                              level:   root.level + 1,
 +                              chatty:  root.chatty,
 +                      },
 +                      fuzzContext: fctx,
 +                      testContext: tctx,
 +              }
 +              f.w = indenter{&f.common}
 +      }
 +      if target == nil {
 +              return false, true
 +      }
 +      if f.chatty != nil {
 +              f.chatty.Updatef(f.name, "=== FUZZ  %s\n", f.name)
 +      }
 +      go fRunner(f, target.Fn)
 +      <-f.signal
 +      return f.ran, !f.failed
 +}
 +
 +// fRunner wraps a call to a fuzz target and ensures that cleanup functions are
 +// called and status flags are set. fRunner should be called in its own
 +// goroutine. To wait for its completion, receive f.signal.
 +//
 +// fRunner is analogous with tRunner, which wraps subtests started with T.Run.
 +// Tests and fuzz targets work a little differently, so for now, these functions
 +// aren't consolidated. In particular, because there are no F.Run and F.Parallel
 +// methods, i.e., no fuzz sub-targets or parallel fuzz targets, a few
 +// simplifications are made. We also require that F.Fuzz, F.Skip, or F.Fail is
 +// called.
 +func fRunner(f *F, fn func(*F)) {
 +      // When this goroutine is done, either because runtime.Goexit was called,
 +      // a panic started, or fn returned normally, record the duration and send
 +      // t.signal, indicating the fuzz target is done.
 +      defer func() {
 +              // Detect whether the fuzz target panicked or called runtime.Goexit without
 +              // calling F.Fuzz, F.Fail, or F.Skip. If it did, panic (possibly replacing
 +              // a nil panic value). Nothing should recover after fRunner unwinds,
 +              // so this should crash the process with a stack. Unfortunately, recovering
 +              // here adds stack frames, but the location of the original panic should
 +              // still be clear.
 +              if f.Failed() {
 +                      atomic.AddUint32(&numFailed, 1)
 +              }
 +              err := recover()
 +              f.mu.RLock()
 +              ok := f.skipped || f.failed || (f.fuzzCalled && f.finished)
 +              f.mu.RUnlock()
 +              if err == nil && !ok {
 +                      err = errNilPanicOrGoexit
 +              }
 +
 +              // Use a deferred call to ensure that we report that the test is
 +              // complete even if a cleanup function calls t.FailNow. See issue 41355.
 +              didPanic := false
 +              defer func() {
 +                      if didPanic {
 +                              return
 +                      }
 +                      if err != nil {
 +                              panic(err)
 +                      }
 +                      // Only report that the test is complete if it doesn't panic,
 +                      // as otherwise the test binary can exit before the panic is
 +                      // reported to the user. See issue 41479.
 +                      f.signal <- true
 +              }()
 +
 +              // If we recovered a panic or inappropriate runtime.Goexit, fail the test,
 +              // flush the output log up to the root, then panic.
 +              doPanic := func(err interface{}) {
 +                      f.Fail()
 +                      if r := f.runCleanup(recoverAndReturnPanic); r != nil {
 +                              f.Logf("cleanup panicked with %v", r)
 +                      }
 +                      for root := &f.common; root.parent != nil; root = root.parent {
 +                              root.mu.Lock()
 +                              root.duration += time.Since(root.start)
 +                              d := root.duration
 +                              root.mu.Unlock()
 +                              root.flushToParent(root.name, "--- FAIL: %s (%s)\n", root.name, fmtDuration(d))
 +                      }
 +                      didPanic = true
 +                      panic(err)
 +              }
 +              if err != nil {
 +                      doPanic(err)
 +              }
 +
 +              // No panic or inappropriate Goexit.
 +              f.duration += time.Since(f.start)
 +
 +              if len(f.sub) > 0 {
 +                      // Run parallel inputs.
 +                      // Release the parallel subtests.
 +                      close(f.barrier)
 +                      // Wait for the subtests to complete.
 +                      for _, sub := range f.sub {
 +                              <-sub.signal
 +                      }
 +                      cleanupStart := time.Now()
 +                      err := f.runCleanup(recoverAndReturnPanic)
 +                      f.duration += time.Since(cleanupStart)
 +                      if err != nil {
 +                              doPanic(err)
 +                      }
 +              }
 +
 +              // Report after all subtests have finished.
 +              f.report()
 +              f.done = true
 +              f.setRan()
 +      }()
 +      defer func() {
 +              if len(f.sub) == 0 {
 +                      f.runCleanup(normalPanic)
 +              }
 +      }()
 +
 +      f.start = time.Now()
 +      fn(f)
 +
 +      // Code beyond this point is only executed if fn returned normally.
 +      // That means fn did not call F.Fuzz or F.Skip. It should have called F.Fail.
 +      f.mu.Lock()
 +      defer f.mu.Unlock()
 +      if !f.failed {
 +              panic(f.name + " returned without calling F.Fuzz, F.Fail, or F.Skip")
 +      }
 +}
Simple merge