-
Notifications
You must be signed in to change notification settings - Fork 17.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cmd/internal/script: new hook for adding in toolchain script conditions
Introduce a new function AddToolChainScriptConditions that augments a default "script.Cond" set with a collection of useful conditions, including godebug/goexperiment, cgo, race support, buildmode, asan, msan, and so on. Having these conditions available makes it easier to write script tests that deal with specific build-flavor corner cases. The functions backing the new conditions are helper functions migrated over from the Go command's script test setup. Updates #68606. Change-Id: I14def1115b54dc47529c983abcd2c5ea9326b9de Reviewed-on: https://go-review.googlesource.com/c/go/+/601715 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Cherry Mui <[email protected]>
- Loading branch information
Showing
5 changed files
with
126 additions
and
93 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
// Copyright 2024 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 scripttest | ||
|
||
import ( | ||
"cmd/internal/script" | ||
"fmt" | ||
"internal/buildcfg" | ||
"internal/platform" | ||
"internal/testenv" | ||
"runtime" | ||
"strings" | ||
"testing" | ||
) | ||
|
||
// AddToolChainConditions accepts a script.Cond map and adds into it a | ||
// set of commonly used conditions for doing toolchains testing, | ||
// including whether the platform supports cgo, a buildmode condition, | ||
// support for GOEXPERIMENT testing, etc. Callers must also pass in | ||
// current GOHOSTOOS/GOHOSTARCH settings, since some of the conditions | ||
// introduced can be influenced by them. | ||
func AddToolChainScriptConditions(t *testing.T, conds map[string]script.Cond, goHostOS, goHostArch string) { | ||
add := func(name string, cond script.Cond) { | ||
if _, ok := conds[name]; ok { | ||
t.Fatalf("condition %q is already registered", name) | ||
} | ||
conds[name] = cond | ||
} | ||
|
||
lazyBool := func(summary string, f func() bool) script.Cond { | ||
return script.OnceCondition(summary, func() (bool, error) { return f(), nil }) | ||
} | ||
|
||
add("asan", sysCondition("-asan", platform.ASanSupported, true, goHostOS, goHostArch)) | ||
add("buildmode", script.PrefixCondition("go supports -buildmode=<suffix>", hasBuildmode)) | ||
add("cgo", script.BoolCondition("host CGO_ENABLED", testenv.HasCGO())) | ||
add("cgolinkext", script.Condition("platform requires external linking for cgo", cgoLinkExt)) | ||
add("cross", script.BoolCondition("cmd/go GOOS/GOARCH != GOHOSTOS/GOHOSTARCH", goHostOS != runtime.GOOS || goHostArch != runtime.GOARCH)) | ||
add("fuzz", sysCondition("-fuzz", platform.FuzzSupported, false, goHostOS, goHostArch)) | ||
add("fuzz-instrumented", sysCondition("-fuzz with instrumentation", platform.FuzzInstrumented, false, goHostOS, goHostArch)) | ||
add("GODEBUG", script.PrefixCondition("GODEBUG contains <suffix>", hasGodebug)) | ||
add("GOEXPERIMENT", script.PrefixCondition("GOEXPERIMENT <suffix> is enabled", hasGoexperiment)) | ||
add("go-builder", script.BoolCondition("GO_BUILDER_NAME is non-empty", testenv.Builder() != "")) | ||
add("link", lazyBool("testenv.HasLink()", testenv.HasLink)) | ||
add("msan", sysCondition("-msan", platform.MSanSupported, true, goHostOS, goHostArch)) | ||
add("mustlinkext", script.Condition("platform always requires external linking", mustLinkExt)) | ||
add("pielinkext", script.Condition("platform requires external linking for PIE", pieLinkExt)) | ||
add("race", sysCondition("-race", platform.RaceDetectorSupported, true, goHostOS, goHostArch)) | ||
add("symlink", lazyBool("testenv.HasSymlink()", testenv.HasSymlink)) | ||
} | ||
|
||
func sysCondition(flag string, f func(goos, goarch string) bool, needsCgo bool, goHostOS, goHostArch string) script.Cond { | ||
return script.Condition( | ||
"GOOS/GOARCH supports "+flag, | ||
func(s *script.State) (bool, error) { | ||
GOOS, _ := s.LookupEnv("GOOS") | ||
GOARCH, _ := s.LookupEnv("GOARCH") | ||
cross := goHostOS != GOOS || goHostArch != GOARCH | ||
return (!needsCgo || (testenv.HasCGO() && !cross)) && f(GOOS, GOARCH), nil | ||
}) | ||
} | ||
|
||
func hasBuildmode(s *script.State, mode string) (bool, error) { | ||
GOOS, _ := s.LookupEnv("GOOS") | ||
GOARCH, _ := s.LookupEnv("GOARCH") | ||
return platform.BuildModeSupported(runtime.Compiler, mode, GOOS, GOARCH), nil | ||
} | ||
|
||
func cgoLinkExt(s *script.State) (bool, error) { | ||
GOOS, _ := s.LookupEnv("GOOS") | ||
GOARCH, _ := s.LookupEnv("GOARCH") | ||
return platform.MustLinkExternal(GOOS, GOARCH, true), nil | ||
} | ||
|
||
func mustLinkExt(s *script.State) (bool, error) { | ||
GOOS, _ := s.LookupEnv("GOOS") | ||
GOARCH, _ := s.LookupEnv("GOARCH") | ||
return platform.MustLinkExternal(GOOS, GOARCH, false), nil | ||
} | ||
|
||
func pieLinkExt(s *script.State) (bool, error) { | ||
GOOS, _ := s.LookupEnv("GOOS") | ||
GOARCH, _ := s.LookupEnv("GOARCH") | ||
return !platform.InternalLinkPIESupported(GOOS, GOARCH), nil | ||
} | ||
|
||
func hasGodebug(s *script.State, value string) (bool, error) { | ||
godebug, _ := s.LookupEnv("GODEBUG") | ||
for _, p := range strings.Split(godebug, ",") { | ||
if strings.TrimSpace(p) == value { | ||
return true, nil | ||
} | ||
} | ||
return false, nil | ||
} | ||
|
||
func hasGoexperiment(s *script.State, value string) (bool, error) { | ||
GOOS, _ := s.LookupEnv("GOOS") | ||
GOARCH, _ := s.LookupEnv("GOARCH") | ||
goexp, _ := s.LookupEnv("GOEXPERIMENT") | ||
flags, err := buildcfg.ParseGOEXPERIMENT(GOOS, GOARCH, goexp) | ||
if err != nil { | ||
return false, err | ||
} | ||
for _, exp := range flags.All() { | ||
if value == exp { | ||
return true, nil | ||
} | ||
if strings.TrimPrefix(value, "no") == strings.TrimPrefix(exp, "no") { | ||
return false, nil | ||
} | ||
} | ||
return false, fmt.Errorf("unrecognized GOEXPERIMENT %q", value) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters