From 5e73f6a02928518bd8ea0a7b1112ce5e536d5dd6 Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Tue, 15 Nov 2022 10:30:10 -0500 Subject: [PATCH] cmd/nm: use the test binary as 'nm' instead of rebuilding it This not only reduces the latency of the test, but also respects build flags like '-race' and '-cover' passed to the 'go test' command. Change-Id: Iffdc60d444a9ff1d4ff5e688bca1c2ef0dfa03c8 Reviewed-on: https://go-review.googlesource.com/c/go/+/450703 Run-TryBot: Bryan Mills Auto-Submit: Bryan Mills TryBot-Result: Gopher Robot Reviewed-by: Than McIntosh --- src/cmd/nm/nm_test.go | 68 ++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/src/cmd/nm/nm_test.go b/src/cmd/nm/nm_test.go index 4bc9bf9079..7d8358e294 100644 --- a/src/cmd/nm/nm_test.go +++ b/src/cmd/nm/nm_test.go @@ -5,53 +5,49 @@ package main import ( - "fmt" "internal/obscuretestdata" "internal/testenv" "os" - "os/exec" "path/filepath" "runtime" "strings" + "sync" "testing" "text/template" ) -var testnmpath string // path to nm command created for testing purposes - -// The TestMain function creates a nm command for testing purposes and -// deletes it after the tests have been run. +// TestMain executes the test binary as the nm command if +// GO_NMTEST_IS_NM is set, and runs the tests otherwise. func TestMain(m *testing.M) { - os.Exit(testMain(m)) + if os.Getenv("GO_NMTEST_IS_NM") != "" { + main() + os.Exit(0) + } + + os.Setenv("GO_NMTEST_IS_NM", "1") // Set for subprocesses to inherit. + os.Exit(m.Run()) } -func testMain(m *testing.M) int { - if !testenv.HasGoBuild() { - return 0 - } +// nmPath returns the path to the "nm" binary to run. +func nmPath(t testing.TB) string { + t.Helper() + testenv.MustHaveExec(t) - tmpDir, err := os.MkdirTemp("", "TestNM") - if err != nil { - fmt.Println("TempDir failed:", err) - return 2 + nmPathOnce.Do(func() { + nmExePath, nmPathErr = os.Executable() + }) + if nmPathErr != nil { + t.Fatal(nmPathErr) } - defer os.RemoveAll(tmpDir) - - testnmpath = filepath.Join(tmpDir, "testnm.exe") - gotool, err := testenv.GoTool() - if err != nil { - fmt.Println("GoTool failed:", err) - return 2 - } - out, err := exec.Command(gotool, "build", "-o", testnmpath, "cmd/nm").CombinedOutput() - if err != nil { - fmt.Printf("go build -o %v cmd/nm: %v\n%s", testnmpath, err, string(out)) - return 2 - } - - return m.Run() + return nmExePath } +var ( + nmPathOnce sync.Once + nmExePath string + nmPathErr error +) + func TestNonGoExecs(t *testing.T) { t.Parallel() testfiles := []string{ @@ -77,7 +73,7 @@ func TestNonGoExecs(t *testing.T) { exepath = tf } - cmd := exec.Command(testnmpath, exepath) + cmd := testenv.Command(t, nmPath(t), exepath) out, err := cmd.CombinedOutput() if err != nil { t.Errorf("go tool nm %v: %v\n%s", exepath, err, string(out)) @@ -116,12 +112,12 @@ func testGoExec(t *testing.T, iscgo, isexternallinker bool) { args = append(args, "-ldflags", "-linkmode="+linkmode) } args = append(args, src) - out, err := exec.Command(testenv.GoToolPath(t), args...).CombinedOutput() + out, err := testenv.Command(t, testenv.GoToolPath(t), args...).CombinedOutput() if err != nil { t.Fatalf("building test executable failed: %s %s", err, out) } - out, err = exec.Command(exe).CombinedOutput() + out, err = testenv.Command(t, exe).CombinedOutput() if err != nil { t.Fatalf("running test executable failed: %s %s", err, out) } @@ -151,7 +147,7 @@ func testGoExec(t *testing.T, iscgo, isexternallinker bool) { runtimeSyms["runtime.epclntab"] = "D" } - out, err = exec.Command(testnmpath, exe).CombinedOutput() + out, err = testenv.Command(t, nmPath(t), exe).CombinedOutput() if err != nil { t.Fatalf("go tool nm: %v\n%s", err, string(out)) } @@ -250,7 +246,7 @@ func testGoLib(t *testing.T, iscgo bool) { t.Fatal(err) } - cmd := exec.Command(testenv.GoToolPath(t), "build", "-buildmode=archive", "-o", "mylib.a", ".") + cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-buildmode=archive", "-o", "mylib.a", ".") cmd.Dir = libpath cmd.Env = append(os.Environ(), "GOPATH="+gopath) out, err := cmd.CombinedOutput() @@ -259,7 +255,7 @@ func testGoLib(t *testing.T, iscgo bool) { } mylib := filepath.Join(libpath, "mylib.a") - out, err = exec.Command(testnmpath, mylib).CombinedOutput() + out, err = testenv.Command(t, nmPath(t), mylib).CombinedOutput() if err != nil { t.Fatalf("go tool nm: %v\n%s", err, string(out)) }