From: Filippo Valsorda Date: Tue, 9 Dec 2025 13:46:57 +0000 (+0100) Subject: crypto: clean up subprocess-spawning tests X-Git-Url: https://git.feebdaed.xyz/?a=commitdiff_plain;h=fc66a5655be8ac334b92fb6dedc6aca5a0621681;p=0xmirror%2Fgo.git crypto: clean up subprocess-spawning tests Consistently use testenv.Command and testenv.Executable, avoid redundant testenv.Must, use testenv.CleanCmdEnv where the output is parsed, always log the output with a preceding newline, invoke tests with -v, and always use cmd.Environ() to preserve existing env. Change-Id: I647ff1a8b7d162e5e8df9424030fac446a6a6964 Reviewed-on: https://go-review.googlesource.com/c/go/+/728641 LUCI-TryBot-Result: Go LUCI Reviewed-by: Roland Shoemaker Reviewed-by: Daniel McCarney Auto-Submit: Filippo Valsorda Reviewed-by: Dmitri Shuralyov --- diff --git a/src/crypto/cipher/gcm_fips140v2.0_test.go b/src/crypto/cipher/gcm_fips140v2.0_test.go index 4983822cc6..d3a8ea5c63 100644 --- a/src/crypto/cipher/gcm_fips140v2.0_test.go +++ b/src/crypto/cipher/gcm_fips140v2.0_test.go @@ -22,12 +22,9 @@ func TestGCMNoncesFIPSV2(t *testing.T) { cryptotest.MustSupportFIPS140(t) if !fips140.Enabled { cmd := testenv.Command(t, testenv.Executable(t), "-test.run=^TestGCMNoncesFIPSV2$", "-test.v") - cmd = testenv.CleanCmdEnv(cmd) - cmd.Env = append(cmd.Env, "GODEBUG=fips140=on") + cmd.Env = append(cmd.Environ(), "GODEBUG=fips140=on") out, err := cmd.CombinedOutput() - if len(out) != 0 { - t.Logf("\n%s", out) - } + t.Logf("running with GODEBUG=fips140=on:\n%s", out) if err != nil { t.Errorf("fips140=on subprocess failed: %v", err) } diff --git a/src/crypto/cipher/gcm_test.go b/src/crypto/cipher/gcm_test.go index 7bcfe9d7dc..8daa0ded22 100644 --- a/src/crypto/cipher/gcm_test.go +++ b/src/crypto/cipher/gcm_test.go @@ -766,12 +766,9 @@ func TestGCMNoncesFIPSV1(t *testing.T) { cryptotest.MustSupportFIPS140(t) if !fips140.Enabled { cmd := testenv.Command(t, testenv.Executable(t), "-test.run=^TestGCMNoncesFIPSV1$", "-test.v") - cmd = testenv.CleanCmdEnv(cmd) - cmd.Env = append(cmd.Env, "GODEBUG=fips140=on") + cmd.Env = append(cmd.Environ(), "GODEBUG=fips140=on") out, err := cmd.CombinedOutput() - if len(out) != 0 { - t.Logf("\n%s", out) - } + t.Logf("running with GODEBUG=fips140=on:\n%s", out) if err != nil { t.Errorf("fips140=on subprocess failed: %v", err) } diff --git a/src/crypto/ecdh/ecdh_test.go b/src/crypto/ecdh/ecdh_test.go index 8a3eb87061..cfa919ade9 100644 --- a/src/crypto/ecdh/ecdh_test.go +++ b/src/crypto/ecdh/ecdh_test.go @@ -16,7 +16,6 @@ import ( "internal/testenv" "io" "os" - "os/exec" "path/filepath" "regexp" "strings" @@ -450,7 +449,6 @@ func TestLinker(t *testing.T) { if testing.Short() { t.Skip("test requires running 'go build'") } - testenv.MustHaveGoBuild(t) dir := t.TempDir() hello := filepath.Join(dir, "hello.go") @@ -460,17 +458,16 @@ func TestLinker(t *testing.T) { } run := func(args ...string) string { - cmd := exec.Command(args[0], args[1:]...) + cmd := testenv.Command(t, args[0], args[1:]...) cmd.Dir = dir - out, err := cmd.CombinedOutput() + out, err := testenv.CleanCmdEnv(cmd).CombinedOutput() if err != nil { t.Fatalf("%v: %v\n%s", args, err, string(out)) } return string(out) } - goBin := testenv.GoToolPath(t) - run(goBin, "build", "-o", "hello.exe", "hello.go") + run(testenv.GoToolPath(t), "build", "-o", "hello.exe", "hello.go") if out := run("./hello.exe"); out != "OK\n" { t.Error("unexpected output:", out) } @@ -478,7 +475,7 @@ func TestLinker(t *testing.T) { // List all text symbols under crypto/... and make sure there are some for // P256, but none for the other curves. var consistent bool - nm := run(goBin, "tool", "nm", "hello.exe") + nm := run(testenv.GoToolPath(t), "tool", "nm", "hello.exe") for _, match := range regexp.MustCompile(`(?m)T (crypto/.*)$`).FindAllStringSubmatch(nm, -1) { symbol := strings.ToLower(match[1]) if strings.Contains(symbol, "p256") { diff --git a/src/crypto/fips140/enforcement_test.go b/src/crypto/fips140/enforcement_test.go index 708c7f7a15..c2f66d544b 100644 --- a/src/crypto/fips140/enforcement_test.go +++ b/src/crypto/fips140/enforcement_test.go @@ -5,42 +5,77 @@ package fips140_test import ( + "crypto/des" + "crypto/fips140" "crypto/internal/cryptotest" "internal/testenv" - "path/filepath" - "strings" "testing" ) +func expectAllowed(t *testing.T, why string, expected bool) { + t.Helper() + result := isAllowed() + if result != expected { + t.Fatalf("%v: expected: %v, got: %v", why, expected, result) + } +} + +func isAllowed() bool { + _, err := des.NewCipher(make([]byte, 8)) + return err == nil +} + func TestWithoutEnforcement(t *testing.T) { - testenv.MustHaveExec(t) - testenv.MustHaveGoBuild(t) cryptotest.MustSupportFIPS140(t) - - tool, _ := testenv.GoTool() - tmpdir := t.TempDir() - binFile := filepath.Join(tmpdir, "fips140.test") - cmd := testenv.Command(t, tool, "test", "-c", "-o", binFile, "./testdata") - out, err := cmd.CombinedOutput() - if err != nil { - t.Log(string(out)) - t.Errorf("Could not build enforcement tests") - } - cmd = testenv.Command(t, binFile, "-test.list", ".") - list, err := cmd.CombinedOutput() - if err != nil { - t.Log(string(out)) - t.Errorf("Could not get enforcement test list") + if !fips140.Enforced() { + cmd := testenv.Command(t, testenv.Executable(t), "-test.run=^TestWithoutEnforcement$", "-test.v") + cmd.Env = append(cmd.Environ(), "GODEBUG=fips140=only") + out, err := cmd.CombinedOutput() + t.Logf("running with GODEBUG=fips140=only:\n%s", out) + if err != nil { + t.Errorf("fips140=only subprocess failed: %v", err) + } + return } - for test := range strings.Lines(string(list)) { - test = strings.TrimSpace(test) - t.Run(test, func(t *testing.T) { - cmd = testenv.Command(t, binFile, "-test.run", "^"+test+"$") - cmd.Env = append(cmd.Env, "GODEBUG=fips140=only") - out, err := cmd.CombinedOutput() - if err != nil { - t.Error(string(out)) - } + + t.Run("Disabled", func(t *testing.T) { + expectAllowed(t, "before enforcement disabled", false) + fips140.WithoutEnforcement(func() { + expectAllowed(t, "inside WithoutEnforcement", true) }) - } + // make sure that bypass doesn't live on after returning + expectAllowed(t, "after WithoutEnforcement", false) + }) + + t.Run("Nested", func(t *testing.T) { + expectAllowed(t, "before enforcement bypass", false) + fips140.WithoutEnforcement(func() { + fips140.WithoutEnforcement(func() { + expectAllowed(t, "inside nested WithoutEnforcement", true) + }) + expectAllowed(t, "inside nested WithoutEnforcement", true) + }) + expectAllowed(t, "after enforcement bypass", false) + }) + + t.Run("GoroutineInherit", func(t *testing.T) { + ch := make(chan bool, 2) + expectAllowed(t, "before enforcement bypass", false) + fips140.WithoutEnforcement(func() { + go func() { + ch <- isAllowed() + }() + }) + allowed := <-ch + if !allowed { + t.Fatal("goroutine didn't inherit enforcement bypass") + } + go func() { + ch <- isAllowed() + }() + allowed = <-ch + if allowed { + t.Fatal("goroutine inherited bypass after WithoutEnforcement return") + } + }) } diff --git a/src/crypto/fips140/testdata/enforcement_test.go b/src/crypto/fips140/testdata/enforcement_test.go deleted file mode 100644 index a8fde3b5bc..0000000000 --- a/src/crypto/fips140/testdata/enforcement_test.go +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2025 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 fips140_test - -import ( - "crypto/des" - "crypto/fips140" - "testing" -) - -func expectAllowed(t *testing.T, why string, expected bool) { - t.Helper() - result := isAllowed() - if result != expected { - t.Fatalf("%v: expected: %v, got: %v", why, expected, result) - } -} - -func isAllowed() bool { - _, err := des.NewCipher(make([]byte, 8)) - return err == nil -} - -func TestDisabled(t *testing.T) { - expectAllowed(t, "before enforcement disabled", false) - fips140.WithoutEnforcement(func() { - expectAllowed(t, "inside WithoutEnforcement", true) - }) - // make sure that bypass doesn't live on after returning - expectAllowed(t, "after WithoutEnforcement", false) -} - -func TestNested(t *testing.T) { - expectAllowed(t, "before enforcement bypass", false) - fips140.WithoutEnforcement(func() { - fips140.WithoutEnforcement(func() { - expectAllowed(t, "inside nested WithoutEnforcement", true) - }) - expectAllowed(t, "inside nested WithoutEnforcement", true) - }) - expectAllowed(t, "after enforcement bypass", false) -} - -func TestGoroutineInherit(t *testing.T) { - ch := make(chan bool, 2) - expectAllowed(t, "before enforcement bypass", false) - fips140.WithoutEnforcement(func() { - go func() { - ch <- isAllowed() - }() - }) - allowed := <-ch - if !allowed { - t.Fatal("goroutine didn't inherit enforcement bypass") - } - go func() { - ch <- isAllowed() - }() - allowed = <-ch - if allowed { - t.Fatal("goroutine inherited bypass after WithoutEnforcement return") - } -} diff --git a/src/crypto/internal/cryptotest/fetchmodule.go b/src/crypto/internal/cryptotest/fetchmodule.go index 37f2a09497..5df340a697 100644 --- a/src/crypto/internal/cryptotest/fetchmodule.go +++ b/src/crypto/internal/cryptotest/fetchmodule.go @@ -18,13 +18,12 @@ import ( // possible in this environment. func FetchModule(t *testing.T, module, version string) string { testenv.MustHaveExternalNetwork(t) - goTool := testenv.GoToolPath(t) // If the default GOMODCACHE doesn't exist, use a temporary directory // instead. (For example, run.bash sets GOPATH=/nonexist-gopath.) - out, err := testenv.Command(t, goTool, "env", "GOMODCACHE").Output() + out, err := testenv.CleanCmdEnv(testenv.Command(t, testenv.GoToolPath(t), "env", "GOMODCACHE")).Output() if err != nil { - t.Errorf("%s env GOMODCACHE: %v\n%s", goTool, err, out) + t.Errorf("%s env GOMODCACHE: %v\n%s", testenv.GoToolPath(t), err, out) if ee, ok := err.(*exec.ExitError); ok { t.Logf("%s", ee.Stderr) } @@ -44,7 +43,7 @@ func FetchModule(t *testing.T, module, version string) string { t.Logf("fetching %s@%s\n", module, version) - output, err := testenv.Command(t, goTool, "mod", "download", "-json", module+"@"+version).CombinedOutput() + output, err := testenv.Command(t, testenv.GoToolPath(t), "mod", "download", "-json", module+"@"+version).CombinedOutput() if err != nil { t.Fatalf("failed to download %s@%s: %s\n%s\n", module, version, err, output) } diff --git a/src/crypto/internal/fips140deps/fipsdeps_test.go b/src/crypto/internal/fips140deps/fipsdeps_test.go index 29a56047c3..e2d1d1836c 100644 --- a/src/crypto/internal/fips140deps/fipsdeps_test.go +++ b/src/crypto/internal/fips140deps/fipsdeps_test.go @@ -44,7 +44,7 @@ func TestImports(t *testing.T) { {{range .XTestImports -}} {{$path}} {{.}} {{end -}}`, "crypto/internal/fips140/...") - bout, err := cmd.CombinedOutput() + bout, err := testenv.CleanCmdEnv(cmd).CombinedOutput() if err != nil { t.Fatalf("go list: %v\n%s", err, bout) } diff --git a/src/crypto/internal/fips140test/acvp_test.go b/src/crypto/internal/fips140test/acvp_test.go index daa9b4bf24..e94bab74fd 100644 --- a/src/crypto/internal/fips140test/acvp_test.go +++ b/src/crypto/internal/fips140test/acvp_test.go @@ -23,7 +23,7 @@ import ( "bytes" "crypto/elliptic" "crypto/internal/cryptotest" - "crypto/internal/entropy/v1.0.0" + entropy "crypto/internal/entropy/v1.0.0" "crypto/internal/fips140" "crypto/internal/fips140/aes" "crypto/internal/fips140/aes/gcm" @@ -2128,16 +2128,13 @@ func TestACVP(t *testing.T) { // Build the acvptool binary. toolPath := filepath.Join(t.TempDir(), "acvptool.exe") - goTool := testenv.GoToolPath(t) - cmd := testenv.Command(t, goTool, + cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", toolPath, "./util/fipstools/acvp/acvptool") cmd.Dir = bsslDir - out := &strings.Builder{} - cmd.Stderr = out - if err := cmd.Run(); err != nil { - t.Fatalf("failed to build acvptool: %s\n%s", err, out.String()) + if out, err := cmd.CombinedOutput(); err != nil { + t.Fatalf("failed to build acvptool: %s\n%s", err, out) } // Similarly, fetch the ACVP data module that has vectors/expected answers. @@ -2163,17 +2160,17 @@ func TestACVP(t *testing.T) { "-module-wrappers", "go:" + os.Args[0], "-tests", configPath, } - cmd = testenv.Command(t, goTool, args...) + cmd = testenv.Command(t, testenv.GoToolPath(t), args...) cmd.Dir = dataDir cmd.Env = append(os.Environ(), "ACVP_WRAPPER=1", "GODEBUG=fips140=on", ) - output, err := cmd.CombinedOutput() + out, err := cmd.CombinedOutput() + t.Logf("\n%s", out) if err != nil { - t.Fatalf("failed to run acvp tests: %s\n%s", err, string(output)) + t.Fatalf("failed to run acvp tests: %s", err) } - t.Log(string(output)) } func TestTooFewArgs(t *testing.T) { diff --git a/src/crypto/internal/fips140test/cast_test.go b/src/crypto/internal/fips140test/cast_test.go index 1978356ea5..5a80006622 100644 --- a/src/crypto/internal/fips140test/cast_test.go +++ b/src/crypto/internal/fips140test/cast_test.go @@ -78,7 +78,7 @@ func TestAllCASTs(t *testing.T) { // Ask "go list" for the location of the crypto/internal/fips140 tree, as it // might be the unpacked frozen tree selected with GOFIPS140. cmd := testenv.Command(t, testenv.GoToolPath(t), "list", "-f", `{{.Dir}}`, "crypto/internal/fips140") - out, err := cmd.CombinedOutput() + out, err := testenv.CleanCmdEnv(cmd).CombinedOutput() if err != nil { t.Fatalf("go list: %v\n%s", err, out) } @@ -161,13 +161,12 @@ func TestConditionals(t *testing.T) { func TestCASTPasses(t *testing.T) { moduleStatus(t) - testenv.MustHaveExec(t) cryptotest.MustSupportFIPS140(t) cmd := testenv.Command(t, testenv.Executable(t), "-test.run=^TestConditionals$", "-test.v") - cmd.Env = append(cmd.Env, "GODEBUG=fips140=debug") + cmd.Env = append(cmd.Environ(), "GODEBUG=fips140=debug") out, err := cmd.CombinedOutput() - t.Logf("%s", out) + t.Logf("running with GODEBUG=fips140=debug:\n%s", out) if err != nil || !strings.Contains(string(out), "completed successfully") { t.Errorf("TestConditionals did not complete successfully") } @@ -185,7 +184,6 @@ func TestCASTPasses(t *testing.T) { func TestCASTFailures(t *testing.T) { moduleStatus(t) - testenv.MustHaveExec(t) cryptotest.MustSupportFIPS140(t) for _, name := range allCASTs { @@ -197,11 +195,12 @@ func TestCASTFailures(t *testing.T) { } t.Logf("Testing CAST/PCT failure...") cmd := testenv.Command(t, testenv.Executable(t), "-test.run=^TestConditionals$", "-test.v") - cmd.Env = append(cmd.Env, fmt.Sprintf("GODEBUG=failfipscast=%s,fips140=on", name)) + GODEBUG := fmt.Sprintf("GODEBUG=failfipscast=%s,fips140=on", name) + cmd.Env = append(cmd.Environ(), GODEBUG) out, err := cmd.CombinedOutput() - t.Logf("%s", out) + t.Logf("running with %s:\n%s", GODEBUG, out) if err == nil { - t.Fatal("Test did not fail as expected") + t.Fatal("test did not fail as expected") } if strings.Contains(string(out), "completed successfully") { t.Errorf("CAST/PCT %s failure did not stop the program", name) diff --git a/src/crypto/internal/fips140test/check_test.go b/src/crypto/internal/fips140test/check_test.go index 2ceef6dd88..8aef1f9b9b 100644 --- a/src/crypto/internal/fips140test/check_test.go +++ b/src/crypto/internal/fips140test/check_test.go @@ -44,7 +44,6 @@ func TestIntegrityCheck(t *testing.T) { func TestIntegrityCheckFailure(t *testing.T) { moduleStatus(t) - testenv.MustHaveExec(t) cryptotest.MustSupportFIPS140(t) bin, err := os.ReadFile(os.Args[0]) @@ -73,7 +72,7 @@ func TestIntegrityCheckFailure(t *testing.T) { cmd := testenv.Command(t, binPath, "-test.v", "-test.run=^TestIntegrityCheck$") cmd.Env = append(cmd.Environ(), "GODEBUG=fips140=on") out, err := cmd.CombinedOutput() - t.Logf("%s", out) + t.Logf("running with GODEBUG=fips140=on:\n%s", out) if err == nil { t.Errorf("modified binary did not fail as expected") } diff --git a/src/crypto/internal/sysrand/rand_linux_test.go b/src/crypto/internal/sysrand/rand_linux_test.go index ee28ebe135..8dca4b6efd 100644 --- a/src/crypto/internal/sysrand/rand_linux_test.go +++ b/src/crypto/internal/sysrand/rand_linux_test.go @@ -34,7 +34,7 @@ func TestNoGetrandom(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode") } - testenv.MustHaveExec(t) + testenv.MustHaveExec(t) // testenv.Command can't skip from a goroutine done := make(chan struct{}) go func() { @@ -52,8 +52,9 @@ func TestNoGetrandom(t *testing.T) { cmd := testenv.Command(t, testenv.Executable(t), "-test.v") cmd.Env = append(os.Environ(), "GO_GETRANDOM_DISABLED=1") out, err := cmd.CombinedOutput() + t.Logf("running with GO_GETRANDOM_DISABLED=1:\n%s", out) if err != nil { - t.Errorf("subprocess failed: %v\n%s", err, out) + t.Errorf("subprocess failed: %v", err) return } diff --git a/src/crypto/internal/sysrand/rand_test.go b/src/crypto/internal/sysrand/rand_test.go index 1d8eb00f56..1e81974b2f 100644 --- a/src/crypto/internal/sysrand/rand_test.go +++ b/src/crypto/internal/sysrand/rand_test.go @@ -95,7 +95,6 @@ func TestReadError(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode") } - testenv.MustHaveExec(t) // We run this test in a subprocess because it's expected to crash. if os.Getenv("GO_TEST_READ_ERROR") == "1" { @@ -105,7 +104,7 @@ func TestReadError(t *testing.T) { return } - cmd := testenv.Command(t, testenv.Executable(t), "-test.run=^TestReadError$") + cmd := testenv.Command(t, testenv.Executable(t), "-test.run=^TestReadError$", "-test.v") cmd.Env = append(os.Environ(), "GO_TEST_READ_ERROR=1") out, err := cmd.CombinedOutput() if err == nil { diff --git a/src/crypto/purego_test.go b/src/crypto/purego_test.go index 62be347e0c..ebc9110cec 100644 --- a/src/crypto/purego_test.go +++ b/src/crypto/purego_test.go @@ -9,7 +9,6 @@ import ( "internal/testenv" "log" "os" - "os/exec" "strings" "testing" ) @@ -19,8 +18,9 @@ import ( // such as TinyGo. See also the "crypto/...:purego" test in cmd/dist, which // ensures the packages build correctly. func TestPureGoTag(t *testing.T) { - cmd := exec.Command(testenv.GoToolPath(t), "list", "-e", "crypto/...", "math/big") - cmd.Env = append(cmd.Env, "GOOS=linux") + cmd := testenv.Command(t, testenv.GoToolPath(t), "list", "-e", "crypto/...", "math/big") + cmd = testenv.CleanCmdEnv(cmd) + cmd.Env = append(cmd.Environ(), "GOOS=linux", "GOFIPS140=off") cmd.Stderr = os.Stderr out, err := cmd.Output() if err != nil { @@ -28,9 +28,9 @@ func TestPureGoTag(t *testing.T) { } pkgs := strings.Split(strings.TrimSpace(string(out)), "\n") - cmd = exec.Command(testenv.GoToolPath(t), "tool", "dist", "list") + cmd = testenv.Command(t, testenv.GoToolPath(t), "tool", "dist", "list") cmd.Stderr = os.Stderr - out, err = cmd.Output() + out, err = testenv.CleanCmdEnv(cmd).Output() if err != nil { log.Fatalf("loading architecture list: %v\n%s", err, out) } diff --git a/src/crypto/rand/rand_test.go b/src/crypto/rand/rand_test.go index 22ccb8a353..3bb3d5f1ac 100644 --- a/src/crypto/rand/rand_test.go +++ b/src/crypto/rand/rand_test.go @@ -180,7 +180,7 @@ func TestReadError(t *testing.T) { return } - cmd := testenv.Command(t, testenv.Executable(t), "-test.run=^TestReadError$") + cmd := testenv.Command(t, testenv.Executable(t), "-test.run=^TestReadError$", "-test.v") cmd.Env = append(os.Environ(), "GO_TEST_READ_ERROR=1") out, err := cmd.CombinedOutput() if err == nil { diff --git a/src/crypto/tls/bogo_shim_test.go b/src/crypto/tls/bogo_shim_test.go index a14386a61c..1b5fc49c4f 100644 --- a/src/crypto/tls/bogo_shim_test.go +++ b/src/crypto/tls/bogo_shim_test.go @@ -542,7 +542,6 @@ func orderlyShutdown(tlsConn *Conn) { } func TestBogoSuite(t *testing.T) { - testenv.MustHaveGoBuild(t) if testing.Short() { t.Skip("skipping in short mode") } @@ -589,10 +588,8 @@ func TestBogoSuite(t *testing.T) { } cmd := testenv.Command(t, testenv.GoToolPath(t), args...) - out := &strings.Builder{} - cmd.Stderr = out cmd.Dir = filepath.Join(bogoDir, "ssl/test/runner") - err = cmd.Run() + out, err := cmd.CombinedOutput() // NOTE: we don't immediately check the error, because the failure could be either because // the runner failed for some unexpected reason, or because a test case failed, and we // cannot easily differentiate these cases. We check if the JSON results file was written, @@ -707,7 +704,6 @@ func ensureLocalBogo(t *testing.T, localBogoDir string) { } t.Logf("using fresh local bogo checkout from %q", localBogoDir) - return } func generateReport(results bogoResults, outPath string) error { diff --git a/src/crypto/tls/link_test.go b/src/crypto/tls/link_test.go index 454d370c88..cc681d1dfb 100644 --- a/src/crypto/tls/link_test.go +++ b/src/crypto/tls/link_test.go @@ -8,7 +8,6 @@ import ( "bytes" "internal/testenv" "os" - "os/exec" "path/filepath" "testing" ) @@ -19,8 +18,6 @@ func TestLinkerGC(t *testing.T) { t.Skip("skipping in short mode") } t.Parallel() - goBin := testenv.GoToolPath(t) - testenv.MustHaveGoBuild(t) tests := []struct { name string @@ -80,17 +77,17 @@ func main() { tls.Dial("", "", nil) } t.Fatal(err) } os.Remove(exeFile) - cmd := exec.Command(goBin, "build", "-o", "x.exe", "x.go") + cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", "x.exe", "x.go") cmd.Dir = tmpDir if out, err := cmd.CombinedOutput(); err != nil { - t.Fatalf("compile: %v, %s", err, out) + t.Fatalf("compile: %v\n%s", err, out) } - cmd = exec.Command(goBin, "tool", "nm", "x.exe") + cmd = testenv.Command(t, testenv.GoToolPath(t), "tool", "nm", "x.exe") cmd.Dir = tmpDir - nm, err := cmd.CombinedOutput() + nm, err := testenv.CleanCmdEnv(cmd).CombinedOutput() if err != nil { - t.Fatalf("nm: %v, %s", err, nm) + t.Fatalf("nm: %v\n%s", err, nm) } for _, sym := range tt.want { if !bytes.Contains(nm, []byte(sym)) { diff --git a/src/crypto/x509/bettertls_test.go b/src/crypto/x509/bettertls_test.go index 3a0b98cd74..3ef67b05a9 100644 --- a/src/crypto/x509/bettertls_test.go +++ b/src/crypto/x509/bettertls_test.go @@ -148,13 +148,9 @@ func betterTLSTestData(t *testing.T) (betterTLS, *CertPool) { "export-tests", "--out", testsJSONPath) cmd.Dir = bettertlsDir - t.Log("running bettertls export-tests command") - output, err := cmd.CombinedOutput() - if err != nil { - t.Fatalf( - "failed to run bettertls export-tests: %v\nOutput: %s", - err, output) + if out, err := cmd.CombinedOutput(); err != nil { + t.Fatalf("failed to run bettertls export-tests: %v\n%s", err, out) } jsonData, err := os.ReadFile(testsJSONPath) diff --git a/src/crypto/x509/name_constraints_test.go b/src/crypto/x509/name_constraints_test.go index 32b6823c4c..9a796e100d 100644 --- a/src/crypto/x509/name_constraints_test.go +++ b/src/crypto/x509/name_constraints_test.go @@ -14,6 +14,7 @@ import ( "encoding/hex" "encoding/pem" "fmt" + "internal/testenv" "math/big" "net" "net/url" @@ -2044,13 +2045,9 @@ func testChainAgainstOpenSSL(t *testing.T, leaf *Certificate, intermediates, roo } args = append(args, leafFile.Name()) - var output bytes.Buffer - cmd := exec.Command("openssl", args...) - cmd.Stdout = &output - cmd.Stderr = &output - - err := cmd.Run() - return output.String(), err + cmd := testenv.Command(t, "openssl", args...) + out, err := cmd.CombinedOutput() + return string(out), err } var rfc2821Tests = []struct { diff --git a/src/crypto/x509/root_linux_test.go b/src/crypto/x509/root_linux_test.go index d4f92e0972..8b8a29beea 100644 --- a/src/crypto/x509/root_linux_test.go +++ b/src/crypto/x509/root_linux_test.go @@ -11,7 +11,6 @@ import ( "fmt" "internal/testenv" "os" - "os/exec" "syscall" "testing" ) @@ -20,13 +19,12 @@ func TestSetFallbackRoots(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode") } - testenv.MustHaveExec(t) test := func(t *testing.T, name string, f func(t *testing.T)) { t.Run(name, func(t *testing.T) { if os.Getenv("CRYPTO_X509_SETFALLBACKROOTS_TEST") != "1" { // Execute test in a separate process with CRYPTO_X509_SETFALBACKROOTS_TEST env. - cmd := exec.Command(os.Args[0], fmt.Sprintf("-test.run=^%v$", t.Name())) + cmd := testenv.Command(t, testenv.Executable(t), fmt.Sprintf("-test.run=^%v$", t.Name()), "-test.v") cmd.Env = append(os.Environ(), "CRYPTO_X509_SETFALLBACKROOTS_TEST=1") cmd.SysProcAttr = &syscall.SysProcAttr{ Cloneflags: syscall.CLONE_NEWNS | syscall.CLONE_NEWUSER, @@ -34,11 +32,12 @@ func TestSetFallbackRoots(t *testing.T) { GidMappings: []syscall.SysProcIDMap{{ContainerID: 0, HostID: os.Getgid(), Size: 1}}, } out, err := cmd.CombinedOutput() + if testenv.SyscallIsNotSupported(err) { + t.Skipf("skipping: could not start process with CLONE_NEWNS and CLONE_NEWUSER: %v", err) + } + t.Logf("running with CRYPTO_X509_SETFALLBACKROOTS_TEST=1:\n%s", out) if err != nil { - if testenv.SyscallIsNotSupported(err) { - t.Skipf("skipping: could not start process with CLONE_NEWNS and CLONE_NEWUSER: %v", err) - } - t.Errorf("%v\n%s", err, out) + t.Errorf("CRYPTO_X509_SETFALLBACKROOTS_TEST=1 subprocess failed: %v", err) } return } diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go index 183ee303fa..dd53168559 100644 --- a/src/crypto/x509/x509_test.go +++ b/src/crypto/x509/x509_test.go @@ -30,7 +30,6 @@ import ( "math/big" "net" "net/url" - "os/exec" "reflect" "runtime" "slices" @@ -1461,9 +1460,7 @@ func TestImports(t *testing.T) { if testing.Short() { t.Skip("skipping in -short mode") } - testenv.MustHaveGoRun(t) - - if out, err := exec.Command(testenv.GoToolPath(t), "run", "x509_test_import.go").CombinedOutput(); err != nil { + if out, err := testenv.Command(t, testenv.GoToolPath(t), "run", "x509_test_import.go").CombinedOutput(); err != nil { t.Errorf("failed to run x509_test_import.go: %s\n%s", err, out) } }