aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/go/script_test.go
diff options
context:
space:
mode:
authorBryan C. Mills <bcmills@google.com>2021-10-15 11:35:25 -0400
committerGopher Robot <gobot@golang.org>2022-08-18 14:52:30 +0000
commite64c87157d1e8fbc512a670b8c0af8abc3afa7c1 (patch)
tree7db458aa825bad56d005d1ca5c69b8509b19af98 /src/cmd/go/script_test.go
parentd8f90ce0f8119bf593efb6fb91825de5b61fcda7 (diff)
downloadgo-e64c87157d1e8fbc512a670b8c0af8abc3afa7c1.tar.gz
go-e64c87157d1e8fbc512a670b8c0af8abc3afa7c1.zip
cmd/go: run tests when cmd/go is cross-compiled
When the GOOS or GOARCH of the cmd/go test binary does not match the GOOS or GOARCH of the installed 'go' binary itself, the test currently attempts to trick 'go test' into thinking that there were no test functions to run. That makes it very difficult to discover how to actually run the tests, which in turn makes it difficult to diagnose and fix regressions in, say, the linux-386-longtest builders. (We have had a few of those lately, and they shouldn't be as much of an ordeal to fix as they currently are.) There are three underlying problems: 1. cmd/go uses its own GOOS and GOARCH to figure out which variant of other tools to use, and the cache keys for all installed tools and libraries include the IDs of the tools used to build them. So when cmd/go's GOARCH changes, all installed tools and binaries appear stale *even if* they were just installed by invoking the native cmd/go with the appropriate GOARCH value set. 2. The "go/build" library used by cmd/go toggles its default CGO_ENABLED behavior depending on whether the GOOS and GOARCH being imported match runtime.GOOS and runtime.GOARCH. 3. A handful of cmd/go tests explicitly use gccgo, but the user's installed gccgo binary cannot necessarily cross-compile to the same platforms as cmd/go. To address the cache-invalidation problem, we modify the test variant of cmd/go to use the host's native toolchain (as indicated by the new TESTGO_GOHOSTOS and TESTGO_GOHOSTARCH environment variables) instead of the toolchain matching the test binary itself. That allows a test cmd/go binary compiled with GOARCH=386 to use libraries and tools cross-compiled by the native toolchain, so that $ GOARCH=386 go install std cmd suffices to make the packages in std and cmd non-stale in the tests. To address the CGO_ENABLED mismatch, we set CGO_ENABLED explicitly in the test's environment whenever it may differ from the default. Since script tests that use cgo are already expected to use a [cgo] condition, setting the environment to match that condition fixes the cgo-specific tests. To address the gccgo-specific cross-compilation failures, we add a new script condition, [cross], which evaluates to true whenever the platform of the test binary differs from that of the native toolchain. We can then use that condition to explicitly skip the handful of gccgo tests that fail under cross-compilation. Fixes #53936. Change-Id: I8633944f674eb5941ccc95df928991660e7e8137 Reviewed-on: https://go-review.googlesource.com/c/go/+/356611 Run-TryBot: Bryan Mills <bcmills@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Auto-Submit: Bryan Mills <bcmills@google.com> Reviewed-by: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/cmd/go/script_test.go')
-rw-r--r--src/cmd/go/script_test.go21
1 files changed, 18 insertions, 3 deletions
diff --git a/src/cmd/go/script_test.go b/src/cmd/go/script_test.go
index 809dfb452f..e37a7b192b 100644
--- a/src/cmd/go/script_test.go
+++ b/src/cmd/go/script_test.go
@@ -167,11 +167,13 @@ func (ts *testScript) setup() {
homeEnvName() + "=/no-home",
"CCACHE_DISABLE=1", // ccache breaks with non-existent HOME
"GOARCH=" + runtime.GOARCH,
+ "TESTGO_GOHOSTARCH=" + goHostArch,
"GOCACHE=" + testGOCACHE,
"GODEBUG=" + os.Getenv("GODEBUG"),
"GOEXE=" + cfg.ExeSuffix,
"GOEXPERIMENT=" + os.Getenv("GOEXPERIMENT"),
"GOOS=" + runtime.GOOS,
+ "TESTGO_GOHOSTOS=" + goHostOS,
"GOPATH=" + filepath.Join(ts.workdir, "gopath"),
"GOPROXY=" + proxyURL,
"GOPRIVATE=",
@@ -200,6 +202,12 @@ func (ts *testScript) setup() {
if !testenv.HasExternalNetwork() {
ts.env = append(ts.env, "TESTGONETWORK=panic", "TESTGOVCS=panic")
}
+ if os.Getenv("CGO_ENABLED") != "" || runtime.GOOS != goHostOS || runtime.GOARCH != goHostArch {
+ // If the actual CGO_ENABLED might not match the cmd/go default, set it
+ // explicitly in the environment. Otherwise, leave it unset so that we also
+ // cover the default behaviors.
+ ts.env = append(ts.env, "CGO_ENABLED="+cgoEnabled)
+ }
for _, key := range extraEnvKeys {
if val := os.Getenv(key); val != "" {
@@ -360,6 +368,8 @@ Script:
switch cond.tag {
case runtime.GOOS, runtime.GOARCH, runtime.Compiler:
ok = true
+ case "cross":
+ ok = goHostOS != runtime.GOOS || goHostArch != runtime.GOARCH
case "short":
ok = testing.Short()
case "cgo":
@@ -943,9 +953,9 @@ func (ts *testScript) cmdStale(want simpleStatus, args []string) {
tmpl := "{{if .Error}}{{.ImportPath}}: {{.Error.Err}}{{else}}"
switch want {
case failure:
- tmpl += "{{if .Stale}}{{.ImportPath}} is unexpectedly stale: {{.StaleReason}}{{end}}"
+ tmpl += `{{if .Stale}}{{.ImportPath}} ({{.Target}}) is unexpectedly stale:{{"\n\t"}}{{.StaleReason}}{{end}}`
case success:
- tmpl += "{{if not .Stale}}{{.ImportPath}} is unexpectedly NOT stale{{end}}"
+ tmpl += "{{if not .Stale}}{{.ImportPath}} ({{.Target}}) is unexpectedly NOT stale{{end}}"
default:
ts.fatalf("unsupported: %v stale", want)
}
@@ -953,10 +963,15 @@ func (ts *testScript) cmdStale(want simpleStatus, args []string) {
goArgs := append([]string{"list", "-e", "-f=" + tmpl}, args...)
stdout, stderr, err := ts.exec(testGo, goArgs...)
if err != nil {
+ // Print stdout before stderr, because stderr may explain the error
+ // independent of whatever we may have printed to stdout.
ts.fatalf("go list: %v\n%s%s", err, stdout, stderr)
}
if stdout != "" {
- ts.fatalf("%s", stdout)
+ // Print stderr before stdout, because stderr may contain verbose
+ // debugging info (for example, if GODEBUG=gocachehash=1 is set)
+ // and we know that stdout contains a useful summary.
+ ts.fatalf("%s%s", stderr, stdout)
}
}