From 105f9d51691d996c1698811ca3906b505639f49b Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Tue, 12 Sep 2023 14:50:50 -0400 Subject: os/exec: simplify Windows-specific tests - Use the test binary itself for printing paths instead of building a separate binary and running it through additional subprocesses. - Factor out a common chdir helper. - Use t.Setenv where appropriate. - Reduce indirection in test helpers. - Set NoDefaultCurrentDirectoryInExePath consistently in the environment. Also add a test case demonstrating an interesting behavior for relative paths that may interact with #62596. Fixes #62594. For #62596. Change-Id: I19b9325034edf78cd0ca747594476cd7432bb451 Reviewed-on: https://go-review.googlesource.com/c/go/+/528035 Reviewed-by: Ian Lance Taylor Auto-Submit: Bryan Mills LUCI-TryBot-Result: Go LUCI --- src/os/exec/exec_test.go | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'src/os/exec/exec_test.go') diff --git a/src/os/exec/exec_test.go b/src/os/exec/exec_test.go index 473f92ba8e..9783a133ba 100644 --- a/src/os/exec/exec_test.go +++ b/src/os/exec/exec_test.go @@ -77,6 +77,21 @@ func TestMain(m *testing.M) { if os.Getenv("GO_EXEC_TEST_PID") == "" { os.Setenv("GO_EXEC_TEST_PID", strconv.Itoa(pid)) + if runtime.GOOS == "windows" { + // Normalize environment so that test behavior is consistent. + // (The behavior of LookPath varies depending on this variable.) + // + // Ideally we would test both with the variable set and with it cleared, + // but I (bcmills) am not sure that that's feasible: it may already be set + // in the Windows registry, and I'm not sure if it is possible to remove + // a registry variable in a program's environment. + // + // Per https://learn.microsoft.com/en-us/windows/win32/api/processenv/nf-processenv-needcurrentdirectoryforexepathw#remarks, + // “the existence of the NoDefaultCurrentDirectoryInExePath environment + // variable is checked, and not its value.” + os.Setenv("NoDefaultCurrentDirectoryInExePath", "TRUE") + } + code := m.Run() if code == 0 && flag.Lookup("test.run").Value.String() == "" && flag.Lookup("test.list").Value.String() == "" { for cmd := range helperCommands { @@ -180,6 +195,28 @@ var exeOnce struct { sync.Once } +func chdir(t *testing.T, dir string) { + t.Helper() + + prev, err := os.Getwd() + if err != nil { + t.Fatal(err) + } + if err := os.Chdir(dir); err != nil { + t.Fatal(err) + } + t.Logf("Chdir(%#q)", dir) + + t.Cleanup(func() { + if err := os.Chdir(prev); err != nil { + // Couldn't chdir back to the original working directory. + // panic instead of t.Fatal so that we don't run other tests + // in an unexpected location. + panic("couldn't restore working directory: " + err.Error()) + } + }) +} + var helperCommandUsed sync.Map var helperCommands = map[string]func(...string){ -- cgit v1.3-5-g9baa