aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2017-06-22 20:08:00 -0400
committerRuss Cox <rsc@golang.org>2017-06-23 15:35:55 +0000
commitc23948a2b83bfbe21d2d721f38a7f18f737ba7bb (patch)
treeec2f7d54121a1ea0f6b8b9f569c493ecb76c98a4
parent3445ece2128b0721cae4f6e84b159539acd314ef (diff)
downloadgo-c23948a2b83bfbe21d2d721f38a7f18f737ba7bb.tar.gz
go-c23948a2b83bfbe21d2d721f38a7f18f737ba7bb.zip
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>
-rw-r--r--src/cmd/go/go_test.go122
1 files changed, 62 insertions, 60 deletions
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index 239b9c37a4..60c0c6f369 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -4031,76 +4031,78 @@ func TestExecutableGOROOT(t *testing.T) {
t.Skipf("test case does not work on %s, missing os.Executable", runtime.GOOS)
}
- tg := testgo(t)
- defer tg.cleanup()
-
- tg.makeTempdir()
- tg.tempDir("newgoroot/bin")
- newGoTool := tg.path("newgoroot/bin/go" + exeSuffix)
- err := copyFile(tg.goTool(), newGoTool, 0775)
- if err != nil {
- t.Fatalf("error copying go tool %v", err)
+ // Env with no GOROOT.
+ var env []string
+ for _, e := range os.Environ() {
+ if !strings.HasPrefix(e, "GOROOT=") {
+ env = append(env, e)
+ }
}
- goroot := func(goTool string) string {
- cmd := exec.Command(goTool, "env", "GOROOT")
- cmd.Env = os.Environ()
- for i, val := range cmd.Env {
- if strings.HasPrefix(val, "GOROOT=") {
- cmd.Env = append(cmd.Env[:i], cmd.Env[i+1:]...)
- break
- }
- }
+ 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.Fatalf("copied go tool failed %v: %s", err, out)
+ t.Fatal(err)
}
- root := strings.TrimSpace(string(out))
- resolved, err := filepath.EvalSymlinks(root)
+ goroot, err := filepath.EvalSymlinks(strings.TrimSpace(string(out)))
if err != nil {
- t.Fatalf("EvalSymlinks(%q) failed: %v", root, err)
+ 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)
}
- return resolved
- }
-
- // Filenames are case insensitive on Windows.
- // There should probably be a path/filepath function for this.
- equal := func(a, b string) bool { return a == b }
- if runtime.GOOS == "windows" {
- equal = strings.EqualFold
- }
-
- // macOS uses a symlink for /tmp.
- resolvedTestGOROOT, err := filepath.EvalSymlinks(testGOROOT)
- if err != nil {
- t.Fatalf("could not eval testgoroot symlinks: %v", err)
- }
-
- // Missing GOROOT/pkg/tool, the go tool should fall back to
- // its default path.
- if got, want := goroot(newGoTool), resolvedTestGOROOT; !equal(got, want) {
- t.Fatalf("%s env GOROOT = %q, want %q", newGoTool, got, want)
- }
-
- // Now the executable's path looks like a GOROOT.
- 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))
+ // Note: Must not call tg methods inside subtests: tg is attached to outer t.
+ tg := testgo(t)
+ defer tg.cleanup()
- if got, want := goroot(symGoTool), resolvedNewGOROOT; !equal(got, want) {
- t.Fatalf("%s env GOROOT = %q, want %q", symGoTool, got, want)
- }
+ tg.makeTempdir()
+ tg.tempDir("new/bin")
+ newGoTool := tg.path("new/bin/go" + exeSuffix)
+ tg.must(copyFile(tg.goTool(), newGoTool, 0775))
+ newRoot := tg.path("new")
+
+ t.Run("RelocatedExe", func(t *testing.T) {
+ // Should fall back to default location in binary.
+ // No way to dig out other than look at source code.
+ data, err := ioutil.ReadFile("../../runtime/internal/sys/zversion.go")
+ if err != nil {
+ t.Fatal(err)
+ }
+ m := regexp.MustCompile("const DefaultGoroot = `([^`]+)`").FindStringSubmatch(string(data))
+ if m == nil {
+ t.Fatal("cannot find DefaultGoroot in ../../runtime/internal/sys/zversion.go")
+ }
+ check(t, newGoTool, m[1])
+ })
+
+ // If the binary is sitting in a bin dir next to ../pkg/tool, that counts as a GOROOT,
+ // so it should find the new tree.
+ tg.tempDir("new/pkg/tool")
+ t.Run("RelocatedTree", func(t *testing.T) {
+ check(t, newGoTool, newRoot)
+ })
+
+ tg.tempDir("other/bin")
+ symGoTool := tg.path("other/bin/go" + exeSuffix)
+
+ // Symlink into go tree should still find go tree.
+ t.Run("SymlinkedExe", func(t *testing.T) {
+ testenv.MustHaveSymlink(t)
+ if err := os.Symlink(newGoTool, symGoTool); err != nil {
+ t.Fatal(err)
+ }
+ check(t, symGoTool, newRoot)
+ })
}
func TestNeedVersion(t *testing.T) {