]> git.feebdaed.xyz Git - 0xmirror/go.git/commitdiff
crypto: clean up subprocess-spawning tests
authorFilippo Valsorda <filippo@golang.org>
Tue, 9 Dec 2025 13:46:57 +0000 (14:46 +0100)
committerGopher Robot <gobot@golang.org>
Wed, 10 Dec 2025 21:46:04 +0000 (13:46 -0800)
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 <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: Daniel McCarney <daniel@binaryparadox.net>
Auto-Submit: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
20 files changed:
src/crypto/cipher/gcm_fips140v2.0_test.go
src/crypto/cipher/gcm_test.go
src/crypto/ecdh/ecdh_test.go
src/crypto/fips140/enforcement_test.go
src/crypto/fips140/testdata/enforcement_test.go [deleted file]
src/crypto/internal/cryptotest/fetchmodule.go
src/crypto/internal/fips140deps/fipsdeps_test.go
src/crypto/internal/fips140test/acvp_test.go
src/crypto/internal/fips140test/cast_test.go
src/crypto/internal/fips140test/check_test.go
src/crypto/internal/sysrand/rand_linux_test.go
src/crypto/internal/sysrand/rand_test.go
src/crypto/purego_test.go
src/crypto/rand/rand_test.go
src/crypto/tls/bogo_shim_test.go
src/crypto/tls/link_test.go
src/crypto/x509/bettertls_test.go
src/crypto/x509/name_constraints_test.go
src/crypto/x509/root_linux_test.go
src/crypto/x509/x509_test.go

index 4983822cc62d011a65594a16da1f34a9cca705e2..d3a8ea5c63bb826a4d6418a36aedf405bc9a37fa 100644 (file)
@@ -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)
                }
index 7bcfe9d7dced8db67f3f3a97d3b148198286e8d8..8daa0ded22e1769ae50b84b108c5610bd01da70d 100644 (file)
@@ -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)
                }
index 8a3eb87061ad8c90b448c74c6afeaab015e0aea4..cfa919ade97ad06be3096fdbe7fb7fb549a6d0a2 100644 (file)
@@ -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") {
index 708c7f7a15ee9e7918d964fd404947932b65566a..c2f66d544bfbd063b28e2d68825ea4d2eaa44553 100644 (file)
@@ -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 (file)
index a8fde3b..0000000
+++ /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")
-       }
-}
index 37f2a094972b9d2cebec7cffbb693ca4912ee854..5df340a697531e63a71c6a8000fcfa27bdba21ab 100644 (file)
@@ -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)
        }
index 29a56047c3c5fd3f36f48a7d9d059027cdb9e672..e2d1d1836c836ffd43f594a75a5a17ef55dbdca8 100644 (file)
@@ -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)
        }
index daa9b4bf247823bda6b999c3212af89cfa51fcfa..e94bab74fd5774df09541e050dce130709f42569 100644 (file)
@@ -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) {
index 1978356ea5d8e3b17d9357d8380453cd2bbd371e..5a80006622c4c2b30fe1116822b98e7990453af4 100644 (file)
@@ -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)
index 2ceef6dd883d0ab8244eb2254c62f04b44498e76..8aef1f9b9b609e55ae7097ee36d7b38dc8ce80df 100644 (file)
@@ -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")
        }
index ee28ebe1350349cc699b122a18b2f620ab200d2b..8dca4b6efd65479a9186ae63deeac1f0fe88aec8 100644 (file)
@@ -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
                }
 
index 1d8eb00f5669358bb7c5e430b1d21c03db084696..1e81974b2f43ac6c78226d659dae3e51b6d5abfd 100644 (file)
@@ -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 {
index 62be347e0c6822f8f879326d266850c116da80b0..ebc9110cecee82bcaea66d2a95987f309a36e633 100644 (file)
@@ -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)
        }
index 22ccb8a35334c9f509282021ce10277248fdc176..3bb3d5f1acda25ccf123ffa0990782cc8f6e513d 100644 (file)
@@ -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 {
index a14386a61c23f45eed67f711af4f158b11751f09..1b5fc49c4f319cbfa0a0a0c5e49fd11328158815 100644 (file)
@@ -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 {
index 454d370c8852bb875504dd68385e645205e6eae0..cc681d1dfbd0d0a5f5aaf9f151f79b4f3900cbe1 100644 (file)
@@ -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)) {
index 3a0b98cd74c13bb7dc50d58e230ba1ee67ba65c6..3ef67b05a91753ed2b1ea52e3c7486a5b69fac05 100644 (file)
@@ -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)
index 32b6823c4ce67cc6f8705cc5367448acecab2f29..9a796e100d4719f8cc8b47873344a43ce61f3bea 100644 (file)
@@ -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 {
index d4f92e0972b123bedb8d2c2f99ebf3cd7165f8ab..8b8a29beeadcaf9096ebd72e89b142348d63d2da 100644 (file)
@@ -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
                        }
index 183ee303faec985e961edb564f3e45734ce37985..dd53168559ad426ad979d672f106a27457a38aa0 100644 (file)
@@ -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)
        }
 }