]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/nm: use the test binary as 'nm' instead of rebuilding it
authorBryan C. Mills <bcmills@google.com>
Tue, 15 Nov 2022 15:30:10 +0000 (10:30 -0500)
committerGopher Robot <gobot@golang.org>
Tue, 15 Nov 2022 20:22:16 +0000 (20:22 +0000)
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 <bcmills@google.com>
Auto-Submit: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/nm/nm_test.go

index 4bc9bf90792bea3646bb63297ba97f37d03d0729..7d8358e294dd28f74b177f177987a695b47f66d2 100644 (file)
@@ -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))
-}
-
-func testMain(m *testing.M) int {
-       if !testenv.HasGoBuild() {
-               return 0
+       if os.Getenv("GO_NMTEST_IS_NM") != "" {
+               main()
+               os.Exit(0)
        }
 
-       tmpDir, err := os.MkdirTemp("", "TestNM")
-       if err != nil {
-               fmt.Println("TempDir failed:", err)
-               return 2
-       }
-       defer os.RemoveAll(tmpDir)
+       os.Setenv("GO_NMTEST_IS_NM", "1") // Set for subprocesses to inherit.
+       os.Exit(m.Run())
+}
 
-       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
-       }
+// nmPath returns the path to the "nm" binary to run.
+func nmPath(t testing.TB) string {
+       t.Helper()
+       testenv.MustHaveExec(t)
 
-       return m.Run()
+       nmPathOnce.Do(func() {
+               nmExePath, nmPathErr = os.Executable()
+       })
+       if nmPathErr != nil {
+               t.Fatal(nmPathErr)
+       }
+       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))
        }