}
var (
- canRace = false // whether we can run the race detector
- canCgo = false // whether we can use cgo
- canMSan = false // whether we can run the memory sanitizer
- canASan = false // whether we can run the address sanitizer
+ canRace = false // whether we can run the race detector
+ canCgo = false // whether we can use cgo
+ canMSan = false // whether we can run the memory sanitizer
+ canASan = false // whether we can run the address sanitizer
+ canFuzz = false // whether we can search for new fuzz failures
+ fuzzInstrumented = false // whether fuzzing uses instrumentation
)
var exeSuffix string = func() string {
if isAlpineLinux() || runtime.Compiler == "gccgo" {
canRace = false
}
+ canFuzz = sys.FuzzSupported(runtime.GOOS, runtime.GOARCH)
+ fuzzInstrumented = sys.FuzzInstrumented(runtime.GOOS, runtime.GOARCH)
}
// Don't let these environment variables confuse the test.
os.Setenv("GOENV", "off")
"cmd/go/internal/lockedfile"
"cmd/go/internal/modload"
"cmd/go/internal/search"
+ "cmd/go/internal/str"
"cmd/go/internal/trace"
"cmd/go/internal/work"
- "cmd/go/internal/str"
+ "cmd/internal/sys"
"cmd/internal/test2json"
)
if testO != "" && len(pkgs) != 1 {
base.Fatalf("cannot use -o flag with multiple packages")
}
- if testFuzz != "" && len(pkgs) != 1 {
- base.Fatalf("cannot use -fuzz flag with multiple packages")
+ if testFuzz != "" {
+ if !sys.FuzzSupported(cfg.Goos, cfg.Goarch) {
+ base.Fatalf("-fuzz flag is not supported on %s/%s", cfg.Goos, cfg.Goarch)
+ }
+ if len(pkgs) != 1 {
+ base.Fatalf("cannot use -fuzz flag with multiple packages")
+ }
}
if testProfile() != "" && len(pkgs) != 1 {
base.Fatalf("cannot use %s flag with multiple packages", testProfile())
// instrumentation is added. 'go test -fuzz' still works without coverage,
// but it generates random inputs without guidance, so it's much less effective.
func fuzzInstrumentFlags() []string {
- // TODO: expand the set of supported platforms, with testing. Nothing about
- // the instrumentation is OS specific, but only amd64 and arm64 are
- // supported in the runtime. See src/runtime/libfuzzer*.
- //
- // Keep in sync with build constraints in
- // internal/fuzz/counters_{un,}supported.go
- switch cfg.Goos {
- case "darwin", "freebsd", "linux", "windows":
- default:
- return nil
- }
- switch cfg.Goarch {
- case "amd64", "arm64":
- default:
+ if !sys.FuzzInstrumented(cfg.Goos, cfg.Goarch) {
return nil
}
return []string{"-d=libfuzzer"}
ok = canASan
case "race":
ok = canRace
+ case "fuzz":
+ ok = canFuzz
+ case "fuzz-instrumented":
+ ok = fuzzInstrumented
case "net":
ok = testenv.HasExternalNetwork()
case "link":
- Test environment details:
- [short] for testing.Short()
- [cgo], [msan], [asan], [race] for whether cgo, msan, asan, and the race detector can be used
+ - [fuzz] for whether 'go test -fuzz' can be used at all
+ - [fuzz-instrumented] for whether 'go test -fuzz' uses coverage-instrumented binaries
- [net] for whether the external network can be used
- [link] for testenv.HasLink()
- [root] for os.Geteuid() == 0
-# TODO(jayconrod): support shared memory on more platforms.
-[!darwin] [!linux] [!windows] skip
+[!fuzz] skip
# Test that running a fuzz target that returns without failing or calling
# f.Fuzz fails and causes a non-zero exit status.
[]byte("12345")
-- corpustesting/testdata/fuzz/FuzzWrongType/1 --
go test fuzz v1
-int("00000")
\ No newline at end of file
+int("00000")
-# TODO(jayconrod): support shared memory on more platforms.
-[!darwin] [!linux] [!windows] skip
-
-# Instrumentation not supported on other archs.
-# See #14565.
-[!amd64] [!arm64] skip
+[!fuzz-instrumented] skip
[short] skip
env GOCACHE=$WORK/cache
-# TODO(jayconrod): support shared memory on more platforms.
-[!darwin] [!linux] [!windows] skip
-
+[!fuzz] skip
[short] skip
# Run chatty fuzz targets with an error.
-# TODO(jayconrod): support shared memory on more platforms.
-[!darwin] [!linux] [!windows] skip
+[!fuzz] skip
[short] skip
# Cleanup should run after F.Skip.
-# TODO(jayconrod): support shared memory on more platforms.
-[!darwin] [!linux] [!windows] skip
-
+[!fuzz] skip
[short] skip
# The fuzz function should be able to detect whether -timeout
-# TODO(jayconrod): support shared memory on more platforms.
-[!darwin] [!linux] [!windows] skip
-
+[!fuzz] skip
[short] skip
# There are no seed values, so 'go test' should finish quickly.
# This is unlikely, but possible. It's difficult to simulate interruptions
# due to ^C and EOF errors which are more common. We don't report those.
[short] skip
-[!darwin] [!linux] [!windows] skip
+[!fuzz] skip
# If the I/O error occurs before F.Fuzz is called, the coordinator should
# stop the worker and say that.
-# TODO(jayconrod): support shared memory on more platforms.
-[!darwin] [!linux] [!windows] skip
+[!fuzz] skip
# Matches only fuzz targets to test.
go test standalone_fuzz_test.go
-# TODO(jayconrod): support shared memory on more platforms.
-[!darwin] [!linux] [!windows] skip
-
+[!fuzz] skip
[short] skip
# We clean the fuzz cache during this test. Don't clean the user's cache.
-# TODO(jayconrod): support shared memory on more platforms.
-[!darwin] [!linux] [!windows] skip
-
-# Instrumentation only supported on 64-bit architectures.
-[!amd64] [!arm64] skip
+[!fuzz-instrumented] skip
# Test that when an interesting value is discovered (one that expands coverage),
# the fuzzing engine minimizes it before writing it to the cache.
# enabled, and multiple package or multiple fuzz targets match.
# TODO(#46312): support fuzzing multiple targets in multiple packages.
-# TODO(jayconrod): support shared memory on more platforms.
-[!darwin] [!linux] [!windows] skip
-
+[!fuzz] skip
[short] skip
# With fuzzing disabled, multiple targets can be tested.
-# TODO(jayconrod): support shared memory on more platforms.
-[!darwin] [!linux] [!windows] skip
+[!fuzz] skip
# Tests that a crash caused by a mutator-discovered input writes the bad input
# to testdata, and fails+reports correctly. This tests the end-to-end behavior
-# TODO(jayconrod): support shared memory on more platforms.
-[!darwin] [!linux] [!windows] skip
+[!fuzz] skip
# Check that if a worker does not call F.Fuzz or calls F.Fail first,
# 'go test' exits non-zero and no crasher is recorded.
-# TODO(jayconrod): support shared memory on more platforms.
-[!darwin] [!linux] [!windows] skip
+[!fuzz] skip
# Test basic fuzzing mutator behavior.
#
# NOTE: this test is skipped on Windows, since there's no concept of signals.
# When a process terminates another process, it provides an exit code.
-# TODO(jayconrod): support shared memory on more platforms.
-[!darwin] [!freebsd] [!linux] skip
+[windows] skip
+[!fuzz] skip
[short] skip
# FuzzNonCrash sends itself a signal that does not appear to be a crash.
-# TODO(jayconrod): support shared memory on more platforms.
-[!darwin] [!linux] [!windows] skip
-
+[!fuzz] skip
[short] skip
# When running seed inputs, T.Parallel should let multiple inputs run in
-# TODO(jayconrod): support shared memory on more platforms.
-[!darwin] [!linux] [!windows] skip
-
+[!fuzz] skip
[short] skip
env GOCACHE=$WORK/cache
string("fails")
-- testdata/fuzz/FuzzFoo/thispasses --
go test fuzz v1
-string("passes")
\ No newline at end of file
+string("passes")
-# TODO(jayconrod): support shared memory on more platforms.
-[!darwin] [!linux] [!windows] skip
-
-# Instrumentation not supported on other archs.
-# See #14565.
-[!amd64] [!arm64] skip
-
+[!fuzz-instrumented] skip
[short] skip
env GOCACHE=$WORK/cache
int(10)
-- cache-file-bytes --
go test fuzz v1
-[]byte("11111111111111111111")
\ No newline at end of file
+[]byte("11111111111111111111")
+[!fuzz] skip
[short] skip
-[!darwin] [!linux] [!windows] skip
go test -fuzz=FuzzA -fuzztime=100x fuzz_setenv_test.go
--- /dev/null
+[fuzz] skip
+
+! go test -fuzz=. -fuzztime=1x
+! stdout .
+stderr '^-fuzz flag is not supported on '$GOOS'/'$GOARCH'$'
+
+-- go.mod --
+module example
+
+go 1.18
+-- fuzz_test.go --
+package example
+
+import "testing"
+
+func FuzzTrivial(f *testing.F) {
+ f.Fuzz(func(t *testing.T, _ []byte) {})
+}
}
}
+// FuzzSupported reports whether goos/goarch supports fuzzing
+// ('go test -fuzz=.').
+func FuzzSupported(goos, goarch string) bool {
+ switch goos {
+ case "darwin", "linux", "windows":
+ return true
+ default:
+ return false
+ }
+}
+
+// FuzzInstrumented reports whether fuzzing on goos/goarch uses coverage
+// instrumentation. (FuzzInstrumented implies FuzzSupported.)
+func FuzzInstrumented(goos, goarch string) bool {
+ switch goarch {
+ case "amd64", "arm64":
+ // TODO(#14565): support more architectures.
+ return FuzzSupported(goos, goarch)
+ default:
+ return false
+ }
+}
+
// MustLinkExternal reports whether goos/goarch requires external linking.
// (This is the opposite of internal/testenv.CanInternalLink. Keep them in sync.)
func MustLinkExternal(goos, goarch string) bool {
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+// TODO: expand the set of supported platforms, with testing. Nothing about
+// the instrumentation is OS specific, but only amd64 and arm64 are
+// supported in the runtime. See src/runtime/libfuzzer*.
+//
+// If you update this constraint, also update cmd/internal/sys.FuzzInstrumeted.
+//
//go:build !((darwin || linux || windows || freebsd) && (amd64 || arm64))
package fuzz
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// TODO(jayconrod): support more platforms.
+// If you update this constraint, also update cmd/internal/sys.FuzzSupported.
+//
//go:build !darwin && !linux && !windows
package fuzz