mirror of
https://github.com/golang/go
synced 2024-09-30 10:18:32 -06:00
cmd/go: fix TestExecutableGOROOT when GOROOT_FINAL is set
If GOROOT_FINAL was set during the build, the default GOROOT will not be testGOROOT. Determine the default GOROOT by reading the right source file instead of guessing. (GOROOT_FINAL may no longer be set when the test is actually run.) Also refactor a bit. Fixes #20284. Change-Id: I2274595a235bee10c3f3a5ffecf4bb976f4d9982 Reviewed-on: https://go-review.googlesource.com/46428 Run-TryBot: Russ Cox <rsc@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
3445ece212
commit
c23948a2b8
@ -4031,76 +4031,78 @@ func TestExecutableGOROOT(t *testing.T) {
|
|||||||
t.Skipf("test case does not work on %s, missing os.Executable", runtime.GOOS)
|
t.Skipf("test case does not work on %s, missing os.Executable", runtime.GOOS)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Env with no GOROOT.
|
||||||
|
var env []string
|
||||||
|
for _, e := range os.Environ() {
|
||||||
|
if !strings.HasPrefix(e, "GOROOT=") {
|
||||||
|
env = append(env, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
check := func(t *testing.T, exe, want string) {
|
||||||
|
cmd := exec.Command(exe, "env", "GOROOT")
|
||||||
|
cmd.Env = env
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
goroot, err := filepath.EvalSymlinks(strings.TrimSpace(string(out)))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
want, err = filepath.EvalSymlinks(want)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !strings.EqualFold(goroot, want) {
|
||||||
|
t.Errorf("go env GOROOT:\nhave %s\nwant %s", goroot, want)
|
||||||
|
} else {
|
||||||
|
t.Logf("go env GOROOT: %s", goroot)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: Must not call tg methods inside subtests: tg is attached to outer t.
|
||||||
tg := testgo(t)
|
tg := testgo(t)
|
||||||
defer tg.cleanup()
|
defer tg.cleanup()
|
||||||
|
|
||||||
tg.makeTempdir()
|
tg.makeTempdir()
|
||||||
tg.tempDir("newgoroot/bin")
|
tg.tempDir("new/bin")
|
||||||
newGoTool := tg.path("newgoroot/bin/go" + exeSuffix)
|
newGoTool := tg.path("new/bin/go" + exeSuffix)
|
||||||
err := copyFile(tg.goTool(), newGoTool, 0775)
|
tg.must(copyFile(tg.goTool(), newGoTool, 0775))
|
||||||
if err != nil {
|
newRoot := tg.path("new")
|
||||||
t.Fatalf("error copying go tool %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
goroot := func(goTool string) string {
|
t.Run("RelocatedExe", func(t *testing.T) {
|
||||||
cmd := exec.Command(goTool, "env", "GOROOT")
|
// Should fall back to default location in binary.
|
||||||
cmd.Env = os.Environ()
|
// No way to dig out other than look at source code.
|
||||||
for i, val := range cmd.Env {
|
data, err := ioutil.ReadFile("../../runtime/internal/sys/zversion.go")
|
||||||
if strings.HasPrefix(val, "GOROOT=") {
|
|
||||||
cmd.Env = append(cmd.Env[:i], cmd.Env[i+1:]...)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out, err := cmd.CombinedOutput()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("copied go tool failed %v: %s", err, out)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
root := strings.TrimSpace(string(out))
|
m := regexp.MustCompile("const DefaultGoroot = `([^`]+)`").FindStringSubmatch(string(data))
|
||||||
resolved, err := filepath.EvalSymlinks(root)
|
if m == nil {
|
||||||
if err != nil {
|
t.Fatal("cannot find DefaultGoroot in ../../runtime/internal/sys/zversion.go")
|
||||||
t.Fatalf("EvalSymlinks(%q) failed: %v", root, err)
|
|
||||||
}
|
}
|
||||||
return resolved
|
check(t, newGoTool, m[1])
|
||||||
}
|
})
|
||||||
|
|
||||||
// Filenames are case insensitive on Windows.
|
// If the binary is sitting in a bin dir next to ../pkg/tool, that counts as a GOROOT,
|
||||||
// There should probably be a path/filepath function for this.
|
// so it should find the new tree.
|
||||||
equal := func(a, b string) bool { return a == b }
|
tg.tempDir("new/pkg/tool")
|
||||||
if runtime.GOOS == "windows" {
|
t.Run("RelocatedTree", func(t *testing.T) {
|
||||||
equal = strings.EqualFold
|
check(t, newGoTool, newRoot)
|
||||||
}
|
})
|
||||||
|
|
||||||
// macOS uses a symlink for /tmp.
|
tg.tempDir("other/bin")
|
||||||
resolvedTestGOROOT, err := filepath.EvalSymlinks(testGOROOT)
|
symGoTool := tg.path("other/bin/go" + exeSuffix)
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("could not eval testgoroot symlinks: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Missing GOROOT/pkg/tool, the go tool should fall back to
|
// Symlink into go tree should still find go tree.
|
||||||
// its default path.
|
t.Run("SymlinkedExe", func(t *testing.T) {
|
||||||
if got, want := goroot(newGoTool), resolvedTestGOROOT; !equal(got, want) {
|
testenv.MustHaveSymlink(t)
|
||||||
t.Fatalf("%s env GOROOT = %q, want %q", newGoTool, got, want)
|
if err := os.Symlink(newGoTool, symGoTool); err != nil {
|
||||||
}
|
t.Fatal(err)
|
||||||
|
}
|
||||||
// Now the executable's path looks like a GOROOT.
|
check(t, symGoTool, newRoot)
|
||||||
tg.tempDir("newgoroot/pkg/tool")
|
})
|
||||||
resolvedNewGOROOT, err := filepath.EvalSymlinks(tg.path("newgoroot"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("could not eval newgoroot symlinks: %v", err)
|
|
||||||
}
|
|
||||||
if got, want := goroot(newGoTool), resolvedNewGOROOT; !equal(got, want) {
|
|
||||||
t.Fatalf("%s env GOROOT = %q with pkg/tool, want %q", newGoTool, got, want)
|
|
||||||
}
|
|
||||||
|
|
||||||
testenv.MustHaveSymlink(t)
|
|
||||||
|
|
||||||
tg.tempDir("notgoroot/bin")
|
|
||||||
symGoTool := tg.path("notgoroot/bin/go" + exeSuffix)
|
|
||||||
tg.must(os.Symlink(newGoTool, symGoTool))
|
|
||||||
|
|
||||||
if got, want := goroot(symGoTool), resolvedNewGOROOT; !equal(got, want) {
|
|
||||||
t.Fatalf("%s env GOROOT = %q, want %q", symGoTool, got, want)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNeedVersion(t *testing.T) {
|
func TestNeedVersion(t *testing.T) {
|
||||||
|
Loading…
Reference in New Issue
Block a user