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{
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))
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)
}
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))
}
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()
}
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))
}