mirror of
https://github.com/golang/go
synced 2024-09-30 04:34:33 -06:00
cmd/go: consolidate fuzz-support checks
We had been repeating conditions for specific platforms and architectures to gate fuzzing tests, but the more of those tests we add the more we will have to update if the set of supported platforms and archictures expands over time. We also ought to provide a friendlier error message when 'go test -fuzz' is used on non-supported platforms. This change adds predicates in cmd/internal/sys, which already contains similar predicates for related functionality (such as the race detector), and uses those predicates in 'go test' and TestScript. For #48495 Change-Id: If24c3997aeb4d201258e21e5b6cf4f7c08fbadd7 Reviewed-on: https://go-review.googlesource.com/c/go/+/359481 Trust: Bryan C. Mills <bcmills@google.com> Trust: Katie Hockman <katie@golang.org> Run-TryBot: Bryan C. Mills <bcmills@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Katie Hockman <katie@golang.org>
This commit is contained in:
parent
834e36ec77
commit
e741e2fe0e
@ -43,10 +43,12 @@ func init() {
|
||||
}
|
||||
|
||||
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 {
|
||||
@ -206,6 +208,8 @@ func TestMain(m *testing.M) {
|
||||
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")
|
||||
|
@ -31,9 +31,10 @@ import (
|
||||
"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"
|
||||
)
|
||||
|
||||
@ -651,8 +652,13 @@ func runTest(ctx context.Context, cmd *base.Command, args []string) {
|
||||
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())
|
||||
|
@ -67,20 +67,7 @@ func BuildInit() {
|
||||
// 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"}
|
||||
|
@ -357,6 +357,10 @@ Script:
|
||||
ok = canASan
|
||||
case "race":
|
||||
ok = canRace
|
||||
case "fuzz":
|
||||
ok = canFuzz
|
||||
case "fuzz-instrumented":
|
||||
ok = fuzzInstrumented
|
||||
case "net":
|
||||
ok = testenv.HasExternalNetwork()
|
||||
case "link":
|
||||
|
2
src/cmd/go/testdata/script/README
vendored
2
src/cmd/go/testdata/script/README
vendored
@ -80,6 +80,8 @@ should only run when the condition is satisfied. The available conditions are:
|
||||
- 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
|
||||
|
5
src/cmd/go/testdata/script/test_fuzz.txt
vendored
5
src/cmd/go/testdata/script/test_fuzz.txt
vendored
@ -1,5 +1,4 @@
|
||||
# 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.
|
||||
@ -495,4 +494,4 @@ go test fuzz v1
|
||||
[]byte("12345")
|
||||
-- corpustesting/testdata/fuzz/FuzzWrongType/1 --
|
||||
go test fuzz v1
|
||||
int("00000")
|
||||
int("00000")
|
||||
|
@ -1,9 +1,4 @@
|
||||
# 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
|
||||
|
@ -1,6 +1,4 @@
|
||||
# TODO(jayconrod): support shared memory on more platforms.
|
||||
[!darwin] [!linux] [!windows] skip
|
||||
|
||||
[!fuzz] skip
|
||||
[short] skip
|
||||
|
||||
# Run chatty fuzz targets with an error.
|
||||
|
@ -1,5 +1,4 @@
|
||||
# TODO(jayconrod): support shared memory on more platforms.
|
||||
[!darwin] [!linux] [!windows] skip
|
||||
[!fuzz] skip
|
||||
[short] skip
|
||||
|
||||
# Cleanup should run after F.Skip.
|
||||
|
@ -1,6 +1,4 @@
|
||||
# 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
|
||||
|
@ -1,6 +1,4 @@
|
||||
# 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.
|
||||
|
@ -6,7 +6,7 @@
|
||||
# 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.
|
||||
|
@ -1,5 +1,4 @@
|
||||
# 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
|
||||
|
@ -1,6 +1,4 @@
|
||||
# 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.
|
||||
|
@ -1,8 +1,4 @@
|
||||
# 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.
|
||||
|
@ -2,9 +2,7 @@
|
||||
# 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.
|
||||
|
@ -1,5 +1,4 @@
|
||||
# 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
|
||||
|
@ -1,5 +1,4 @@
|
||||
# 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.
|
||||
|
@ -1,5 +1,4 @@
|
||||
# TODO(jayconrod): support shared memory on more platforms.
|
||||
[!darwin] [!linux] [!windows] skip
|
||||
[!fuzz] skip
|
||||
|
||||
# Test basic fuzzing mutator behavior.
|
||||
#
|
||||
|
@ -1,7 +1,7 @@
|
||||
# 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.
|
||||
|
@ -1,6 +1,4 @@
|
||||
# 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
|
||||
|
6
src/cmd/go/testdata/script/test_fuzz_run.txt
vendored
6
src/cmd/go/testdata/script/test_fuzz_run.txt
vendored
@ -1,6 +1,4 @@
|
||||
# TODO(jayconrod): support shared memory on more platforms.
|
||||
[!darwin] [!linux] [!windows] skip
|
||||
|
||||
[!fuzz] skip
|
||||
[short] skip
|
||||
env GOCACHE=$WORK/cache
|
||||
|
||||
@ -142,4 +140,4 @@ go test fuzz v1
|
||||
string("fails")
|
||||
-- testdata/fuzz/FuzzFoo/thispasses --
|
||||
go test fuzz v1
|
||||
string("passes")
|
||||
string("passes")
|
||||
|
@ -1,10 +1,4 @@
|
||||
# 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
|
||||
|
||||
@ -206,4 +200,4 @@ go test fuzz v1
|
||||
int(10)
|
||||
-- cache-file-bytes --
|
||||
go test fuzz v1
|
||||
[]byte("11111111111111111111")
|
||||
[]byte("11111111111111111111")
|
||||
|
@ -1,5 +1,5 @@
|
||||
[!fuzz] skip
|
||||
[short] skip
|
||||
[!darwin] [!linux] [!windows] skip
|
||||
|
||||
go test -fuzz=FuzzA -fuzztime=100x fuzz_setenv_test.go
|
||||
|
||||
|
18
src/cmd/go/testdata/script/test_fuzz_unsupported.txt
vendored
Normal file
18
src/cmd/go/testdata/script/test_fuzz_unsupported.txt
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
[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) {})
|
||||
}
|
@ -45,6 +45,29 @@ func ASanSupported(goos, goarch string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
|
@ -2,6 +2,12 @@
|
||||
// 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
|
||||
|
@ -2,7 +2,8 @@
|
||||
// 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
|
||||
|
Loading…
Reference in New Issue
Block a user