]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: rewrite testsuite from bash to Go
authorIan Lance Taylor <iant@golang.org>
Tue, 9 Jun 2015 17:30:08 +0000 (10:30 -0700)
committerIan Lance Taylor <iant@golang.org>
Wed, 10 Jun 2015 20:34:56 +0000 (20:34 +0000)
Change-Id: I8473e3f7653d5389d5fcd94862f0831049b8266e
Reviewed-on: https://go-review.googlesource.com/10809
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/cmd/go/go_test.go
src/cmd/go/test.bash [deleted file]

index b733d3a43296aea699f5cd6fffbe8dae8c2397d5..346bd6a6c1b57edd4179a861d02dce50f0a3dbfa 100644 (file)
@@ -12,14 +12,26 @@ import (
        "os"
        "os/exec"
        "path/filepath"
+       "regexp"
        "runtime"
+       "strconv"
        "strings"
        "testing"
+       "time"
 )
 
 // Whether we can run go or ./testgo.
 var canRun = true
 
+// The suffix for executables, because Windows.
+var exeSuffix string
+
+// Whether we can run the race detector.
+var canRace bool
+
+// Whether we can use cgo.
+var canCgo bool
+
 func init() {
        switch runtime.GOOS {
        case "android", "nacl":
@@ -30,6 +42,11 @@ func init() {
                        canRun = false
                }
        }
+
+       switch runtime.GOOS {
+       case "windows":
+               exeSuffix = ".exe"
+       }
 }
 
 // The TestMain function creates a go command for testing purposes and
@@ -38,12 +55,26 @@ func TestMain(m *testing.M) {
        flag.Parse()
 
        if canRun {
-               // We give the executable a .exe extension because Windows.
-               out, err := exec.Command("go", "build", "-tags", "testgo", "-o", "testgo.exe").CombinedOutput()
+               out, err := exec.Command("go", "build", "-tags", "testgo", "-o", "testgo"+exeSuffix).CombinedOutput()
                if err != nil {
                        fmt.Fprintf(os.Stderr, "building testgo failed: %v\n%s", err, out)
                        os.Exit(2)
                }
+
+               if out, err := exec.Command("./testgo"+exeSuffix, "env", "CGO_ENABLED").Output(); err != nil {
+                       fmt.Fprintf(os.Stderr, "running testgo failed: %v\n", err)
+                       canRun = false
+               } else {
+                       canCgo, err = strconv.ParseBool(strings.TrimSpace(string(out)))
+                       if err != nil {
+                               fmt.Fprintf(os.Stderr, "can't parse go env CGO_ENABLED output: %v\n", strings.TrimSpace(string(out)))
+                       }
+               }
+
+               switch runtime.GOOS {
+               case "linux", "darwin", "freebsd", "windows":
+                       canRace = canCgo && runtime.GOARCH == "amd64"
+               }
        }
 
        // Don't let these environment variables confuse the test.
@@ -54,14 +85,25 @@ func TestMain(m *testing.M) {
        r := m.Run()
 
        if canRun {
-               os.Remove("testgo.exe")
+               os.Remove("testgo" + exeSuffix)
        }
 
        os.Exit(r)
 }
 
-// Skip a test if we can't run ./testgo.
-func checkTestGo(t *testing.T) {
+// Manage a single run of the testgo binary.
+type testgoData struct {
+       t              *testing.T
+       temps          []string
+       wd             string
+       env            []string
+       tempdir        string
+       ran            bool
+       stdout, stderr bytes.Buffer
+}
+
+// testgo sets up for a test that runs testgo.
+func testgo(t *testing.T) *testgoData {
        if !canRun {
                switch runtime.GOOS {
                case "android", "nacl":
@@ -75,82 +117,1648 @@ func checkTestGo(t *testing.T) {
                        t.Skip("skipping for unknown reason")
                }
        }
+
+       return &testgoData{t: t}
+}
+
+// must gives a fatal error if err is not nil.
+func (tg *testgoData) must(err error) {
+       if err != nil {
+               tg.t.Fatal(err)
+       }
+}
+
+// check gives a test non-fatal error if err is not nil.
+func (tg *testgoData) check(err error) {
+       if err != nil {
+               tg.t.Error(err)
+       }
+}
+
+// pwd returns the current directory.
+func (tg *testgoData) pwd() string {
+       wd, err := os.Getwd()
+       if err != nil {
+               tg.t.Fatalf("could not get working directory: %v", err)
+       }
+       return wd
 }
 
-// runTestGo runs the test go command, returning stdout, stderr, and
-// status.  The contents of addEnv are added to the environment.
-func runTestGo(addEnv []string, args ...string) (stdout, stderr string, err error) {
+// cd changes the current directory to the named directory.  Note that
+// using this means that the test must not be run in parallel with any
+// other tests.
+func (tg *testgoData) cd(dir string) {
+       if tg.wd == "" {
+               tg.wd = tg.pwd()
+       }
+       tg.must(os.Chdir(dir))
+}
+
+// setenv sets an environment variable to use when running the test go
+// command.
+func (tg *testgoData) setenv(name, val string) {
+       tg.unsetenv(name)
+       tg.env = append(tg.env, name+"="+val)
+}
+
+// unsetenv removes an environment variable.
+func (tg *testgoData) unsetenv(name string) {
+       if tg.env == nil {
+               tg.env = append([]string(nil), os.Environ()...)
+       }
+       for i, v := range tg.env {
+               if strings.HasPrefix(v, name+"=") {
+                       tg.env = append(tg.env[:i], tg.env[i+1:]...)
+                       break
+               }
+       }
+}
+
+// doRun runs the test go command, recording stdout and stderr and
+// returning exit status.
+func (tg *testgoData) doRun(args []string) error {
        if !canRun {
-               panic("runTestGo called but canRun false")
+               panic("testgoData.doRun called but canRun false")
+       }
+       tg.t.Logf("running testgo %v", args)
+       var prog string
+       if tg.wd == "" {
+               prog = "./testgo" + exeSuffix
+       } else {
+               prog = filepath.Join(tg.wd, "testgo"+exeSuffix)
        }
+       cmd := exec.Command(prog, args...)
+       tg.stdout.Reset()
+       tg.stderr.Reset()
+       cmd.Stdout = &tg.stdout
+       cmd.Stderr = &tg.stderr
+       cmd.Env = tg.env
+       status := cmd.Run()
+       if tg.stdout.Len() > 0 {
+               tg.t.Log("standard output:")
+               tg.t.Log(tg.stdout.String())
+       }
+       if tg.stderr.Len() > 0 {
+               tg.t.Log("standard error:")
+               tg.t.Log(tg.stderr.String())
+       }
+       tg.ran = true
+       return status
+}
 
-       cmd := exec.Command("./testgo.exe", args...)
-       var ob, eb bytes.Buffer
-       cmd.Stdout = &ob
-       cmd.Stderr = &eb
-       if len(addEnv) > 0 {
-               cmd.Env = append(addEnv, os.Environ()...)
+// run runs the test go command, and expects it to succeed.
+func (tg *testgoData) run(args ...string) {
+       if status := tg.doRun(args); status != nil {
+               tg.t.Logf("go %v failed unexpectedly: %v", args, status)
+               tg.t.FailNow()
        }
-       err = cmd.Run()
-       return ob.String(), eb.String(), err
 }
 
-// tempFile describes a file to put into a temporary directory.
-type tempFile struct {
-       path     string
-       contents string
+// runFail runs the test go command, and expects it to fail.
+func (tg *testgoData) runFail(args ...string) {
+       if status := tg.doRun(args); status == nil {
+               tg.t.Fatal("testgo succeeded unexpectedly")
+       } else {
+               tg.t.Log("testgo failed as expected:", status)
+       }
 }
 
-// tempDir describes a temporary directory created for a single test.
-type tempDir struct {
-       name string
+// getStdout returns standard output of the testgo run as a string.
+func (tg *testgoData) getStdout() string {
+       if !tg.ran {
+               tg.t.Fatal("internal testsuite error: stdout called before run")
+       }
+       return tg.stdout.String()
 }
 
-// makeTempDir creates a temporary directory for a single test.
-func makeTempDir(t *testing.T, files []tempFile) *tempDir {
-       dir, err := ioutil.TempDir("", "gotest")
-       if err != nil {
-               t.Fatal(err)
+// getStderr returns standard error of the testgo run as a string.
+func (tg *testgoData) getStderr() string {
+       if !tg.ran {
+               tg.t.Fatal("internal testsuite error: stdout called before run")
+       }
+       return tg.stderr.String()
+}
+
+// doGrepMatch looks for a regular expression in a buffer, and returns
+// whether it is found.  The regular expression is matched against
+// each line separately, as with the grep command.
+func (tg *testgoData) doGrepMatch(match string, b *bytes.Buffer) bool {
+       if !tg.ran {
+               tg.t.Fatal("internal testsuite error: grep called before run")
        }
-       for _, f := range files {
-               if err := ioutil.WriteFile(filepath.Join(dir, f.path), []byte(f.contents), 0666); err != nil {
-                       t.Fatal(err)
+       re := regexp.MustCompile(match)
+       for _, ln := range bytes.Split(b.Bytes(), []byte{'\n'}) {
+               if re.Match(ln) {
+                       return true
                }
        }
-       return &tempDir{dir}
+       return false
 }
 
-// path returns the absolute pathname to file within tempDir.
-func (td *tempDir) path(name string) string {
-       return filepath.Join(td.name, name)
+// doGrep looks for a regular expression in a buffer and fails if it
+// is not found.  The name argument is the name of the output we are
+// searching, "output" or "error".  The msg argument is logged on
+// failure.
+func (tg *testgoData) doGrep(match string, b *bytes.Buffer, name, msg string) {
+       if !tg.doGrepMatch(match, b) {
+               tg.t.Log(msg)
+               tg.t.Logf("pattern %v not found in standard %s", match, name)
+               tg.t.FailNow()
+       }
+}
+
+// grepStdout looks for a regular expression in the test run's
+// standard output and fails, logging msg, if it is not found.
+func (tg *testgoData) grepStdout(match, msg string) {
+       tg.doGrep(match, &tg.stdout, "output", msg)
 }
 
-// Remove a temporary directory after a test completes.  This is
-// normally called via defer.
-func (td *tempDir) remove(t *testing.T) {
-       if err := os.RemoveAll(td.name); err != nil {
-               fmt.Fprintln(os.Stderr, err)
+// grepStderr looks for a regular expression in the test run's
+// standard error and fails, logging msg, if it is not found.
+func (tg *testgoData) grepStderr(match, msg string) {
+       tg.doGrep(match, &tg.stderr, "error", msg)
+}
+
+// grepBoth looks for a regular expression in the test run's standard
+// output or stand error and fails, logging msg, if it is not found.
+func (tg *testgoData) grepBoth(match, msg string) {
+       if !tg.doGrepMatch(match, &tg.stdout) && !tg.doGrepMatch(match, &tg.stderr) {
+               tg.t.Log(msg)
+               tg.t.Logf("pattern %v not found in standard output or standard error", match)
+               tg.t.FailNow()
+       }
+}
+
+// doGrepNot looks for a regular expression in a buffer and fails if
+// it is found.  The name and msg arguments are as for doGrep.
+func (tg *testgoData) doGrepNot(match string, b *bytes.Buffer, name, msg string) {
+       if tg.doGrepMatch(match, b) {
+               tg.t.Log(msg)
+               tg.t.Logf("pattern %v found unexpectedly in standard %s", match, name)
+               tg.t.FailNow()
+       }
+}
+
+// grepStdoutNot looks for a regular expression in the test run's
+// standard output and fails, logging msg, if it is found.
+func (tg *testgoData) grepStdoutNot(match, msg string) {
+       tg.doGrepNot(match, &tg.stdout, "output", msg)
+}
+
+// grepStderrNot looks for a regular expression in the test run's
+// standard error and fails, logging msg, if it is found.
+func (tg *testgoData) grepStderrNot(match, msg string) {
+       tg.doGrepNot(match, &tg.stderr, "error", msg)
+}
+
+// grepBothNot looks for a regular expression in the test run's
+// standard output or stand error and fails, logging msg, if it is
+// found.
+func (tg *testgoData) grepBothNot(match, msg string) {
+       if tg.doGrepMatch(match, &tg.stdout) || tg.doGrepMatch(match, &tg.stderr) {
+               tg.t.Log(msg)
+               tg.t.Fatalf("pattern %v found unexpectedly in standard output or standard error", match)
+       }
+}
+
+// doGrepCount counts the number of times a regexp is seen in a buffer.
+func (tg *testgoData) doGrepCount(match string, b *bytes.Buffer) int {
+       if !tg.ran {
+               tg.t.Fatal("internal testsuite error: doGrepCount called before run")
+       }
+       re := regexp.MustCompile(match)
+       c := 0
+       for _, ln := range bytes.Split(b.Bytes(), []byte{'\n'}) {
+               if re.Match(ln) {
+                       c++
+               }
+       }
+       return c
+}
+
+// grepCountStdout returns the number of times a regexp is seen in
+// standard output.
+func (tg *testgoData) grepCountStdout(match string) int {
+       return tg.doGrepCount(match, &tg.stdout)
+}
+
+// grepCountStderr returns the number of times a regexp is seen in
+// standard error.
+func (tg *testgoData) grepCountStderr(match string) int {
+       return tg.doGrepCount(match, &tg.stderr)
+}
+
+// grepCountBoth returns the number of times a regexp is seen in both
+// standard output and standard error.
+func (tg *testgoData) grepCountBoth(match string) int {
+       return tg.doGrepCount(match, &tg.stdout) + tg.doGrepCount(match, &tg.stderr)
+}
+
+// creatingTemp records that the test plans to create a temporary file
+// or directory.  If the file or directory exists already, it will be
+// removed.  When the test completes, the file or directory will be
+// removed if it exists.
+func (tg *testgoData) creatingTemp(path string) {
+       if filepath.IsAbs(path) && !strings.HasPrefix(path, tg.tempdir) {
+               tg.t.Fatal("internal testsuite error: creatingTemp(%q) with absolute path not in temporary directory")
+       }
+       // If we have changed the working directory, make sure we have
+       // an absolute path, because we are going to change directory
+       // back before we remove the temporary.
+       if tg.wd != "" && !filepath.IsAbs(path) {
+               path = filepath.Join(tg.pwd(), path)
+       }
+       tg.must(os.RemoveAll(path))
+       tg.temps = append(tg.temps, path)
+}
+
+// makeTempdir makes a temporary directory for a run of testgo.  If
+// the temporary directory was already created, this does nothing.
+func (tg *testgoData) makeTempdir() {
+       if tg.tempdir == "" {
+               var err error
+               tg.tempdir, err = ioutil.TempDir("", "gotest")
+               tg.must(err)
+       }
+}
+
+// tempFile adds a temporary file for a run of testgo.
+func (tg *testgoData) tempFile(path, contents string) {
+       tg.makeTempdir()
+       tg.must(os.MkdirAll(filepath.Join(tg.tempdir, filepath.Dir(path)), 0755))
+       tg.must(ioutil.WriteFile(filepath.Join(tg.tempdir, path), []byte(contents), 0644))
+}
+
+// tempDir adds a temporary directory for a run of testgo.
+func (tg *testgoData) tempDir(path string) {
+       tg.makeTempdir()
+       if err := os.MkdirAll(filepath.Join(tg.tempdir, path), 0755); err != nil && !os.IsExist(err) {
+               tg.t.Fatal(err)
+       }
+}
+
+// path returns the absolute pathname to file with the temporary
+// directory.
+func (tg *testgoData) path(name string) string {
+       if tg.tempdir == "" {
+               tg.t.Fatalf("internal testsuite error: path(%q) with no tempdir", name)
+       }
+       if name == "." {
+               return tg.tempdir
+       }
+       return filepath.Join(tg.tempdir, name)
+}
+
+// wantExecutable fails with msg if path is not executable.
+func (tg *testgoData) wantExecutable(path, msg string) {
+       if st, err := os.Stat(path); err != nil {
+               if !os.IsNotExist(err) {
+                       tg.t.Log(err)
+               }
+               tg.t.Fatal(msg)
+       } else {
+               if runtime.GOOS != "windows" && st.Mode()&0111 == 0 {
+                       tg.t.Fatalf("binary %s exists but is not executable", path)
+               }
+       }
+}
+
+// isStale returns whether pkg is stale.
+func (tg *testgoData) isStale(pkg string) bool {
+       tg.run("list", "-f", "{{.Stale}}", pkg)
+       switch v := strings.TrimSpace(tg.getStdout()); v {
+       case "true":
+               return true
+       case "false":
+               return false
+       default:
+               tg.t.Fatalf("unexpected output checking staleness of package %v: %v", pkg, v)
+               panic("unreachable")
+       }
+}
+
+// wantStale fails with msg if pkg is not stale.
+func (tg *testgoData) wantStale(pkg, msg string) {
+       if !tg.isStale(pkg) {
+               tg.t.Fatal(msg)
+       }
+}
+
+// wantNotStale fails with msg if pkg is stale.
+func (tg *testgoData) wantNotStale(pkg, msg string) {
+       if tg.isStale(pkg) {
+               tg.t.Fatal(msg)
+       }
+}
+
+// cleanup cleans up a test that runs testgo.
+func (tg *testgoData) cleanup() {
+       if tg.wd != "" {
+               if err := os.Chdir(tg.wd); err != nil {
+                       // We are unlikely to be able to continue.
+                       fmt.Fprintln(os.Stderr, "could not restore working directory, crashing:", err)
+                       os.Exit(2)
+               }
+       }
+       for _, path := range tg.temps {
+               tg.check(os.RemoveAll(path))
+       }
+       if tg.tempdir != "" {
+               tg.check(os.RemoveAll(tg.tempdir))
        }
 }
 
 func TestFileLineInErrorMessages(t *testing.T) {
-       checkTestGo(t)
-       td := makeTempDir(t, []tempFile{{"err.go", `package main; import "bar"`}})
-       defer td.remove(t)
-       path := td.path("err.go")
-       stdout, stderr, err := runTestGo(nil, "run", path)
-       if err == nil {
-               t.Fatal("go command did not fail")
-       }
-       lines := strings.Split(stderr, "\n")
-       for _, ln := range lines {
-               if strings.HasPrefix(ln, path+":") {
-                       // Test has passed.
-                       return
-               }
-       }
-       t.Log(err)
-       t.Log(stdout)
-       t.Log(stderr)
-       t.Error("missing file:line in error message")
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.tempFile("err.go", `package main; import "bar"`)
+       path := tg.path("err.go")
+       tg.runFail("run", path)
+       tg.grepStderr("^"+regexp.QuoteMeta(path)+":", "missing file:line in error message")
+}
+
+func TestProgramNameInCrashMessages(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.tempFile("triv.go", `package main; func main() {}`)
+       tg.runFail("build", "-ldflags", "-crash_for_testing", tg.path("triv.go"))
+       tg.grepStderr(`[/\\]tool[/\\].*[/\\]link`, "missing linker name in error message")
+}
+
+func TestBrokenTestsWithoutTestFunctionsAllFail(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.runFail("test", "./testdata/src/badtest/...")
+       tg.grepBothNot("^ok", "test passed unexpectedly")
+       tg.grepBoth("FAIL.*badtest/badexec", "test did not run everything")
+       tg.grepBoth("FAIL.*badtest/badsyntax", "test did not run everything")
+       tg.grepBoth("FAIL.*badtest/badvar", "test did not run everything")
+}
+
+func TestGoBuildDashAInDevBranch(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.run("install", "math") // should be up to date already but just in case
+       tg.setenv("TESTGO_IS_GO_RELEASE", "0")
+       tg.run("build", "-v", "-a", "math")
+       tg.grepStderr("runtime", "testgo build -a math in dev branch DID NOT build runtime, but should have")
+}
+
+func TestGoBuilDashAInReleaseBranch(t *testing.T) {
+       if testing.Short() {
+               t.Skip("don't rebuild the standard libary in short mode")
+       }
+
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.run("install", "math") // should be up to date already but just in case
+       tg.setenv("TESTGO_IS_GO_RELEASE", "1")
+       tg.run("build", "-v", "-a", "math")
+       tg.grepStderrNot("runtime", "testgo build -a math in dev branch DID build runtime, but should NOT have")
+}
+
+func TestGoInstallCleansUpAfterGoBuild(t *testing.T) {
+       if runtime.GOOS == "windows" {
+               t.Skip("skipping on Windows because of http://golang.org/issue/9645")
+       }
+
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.tempFile("src/mycmd/main.go", `package main; func main(){}`)
+       tg.setenv("GOPATH", tg.path("."))
+       tg.cd(tg.path("src/mycmd"))
+
+       doesNotExist := func(file, msg string) {
+               if _, err := os.Stat(file); err == nil {
+                       t.Fatal(msg)
+               } else if !os.IsNotExist(err) {
+                       // See http://golang.org/issue/11132.
+                       if runtime.GOOS == "plan9" && strings.Contains(err.Error(), "stat buffer too short") {
+                               return
+                       }
+                       t.Fatal(msg, "error:", err)
+               }
+       }
+
+       tg.run("build")
+       tg.wantExecutable("mycmd"+exeSuffix, "testgo build did not write command binary")
+       tg.run("install")
+       doesNotExist("mycmd"+exeSuffix, "testgo install did not remove command binary")
+       tg.run("build")
+       tg.wantExecutable("mycmd"+exeSuffix, "testgo build did not write command binary (second time)")
+       // Running install with arguments does not remove the target,
+       // even in the same directory.
+       tg.run("install", "mycmd")
+       tg.wantExecutable("mycmd"+exeSuffix, "testgo install mycmd removed command binary when run in mycmd")
+       tg.run("build")
+       tg.wantExecutable("mycmd"+exeSuffix, "testgo build did not write command binary (third time)")
+       // And especially not outside the directory.
+       tg.cd(tg.path("."))
+       if data, err := ioutil.ReadFile("src/mycmd/mycmd"); err != nil {
+               t.Fatal("could not read file:", err)
+       } else {
+               if err := ioutil.WriteFile("mycmd", data, 0555); err != nil {
+                       t.Fatal("could not write file:", err)
+               }
+       }
+       tg.run("install", "mycmd")
+       tg.wantExecutable("src/mycmd/mycmd"+exeSuffix, "testgo install mycmd removed command binary from its source dir when run outside mycmd")
+       tg.wantExecutable("mycmd"+exeSuffix, "testgo install mycmd removed command binary from current dir when run outside mycmd")
+}
+
+func TestGoInstallRebuildsStalePackagesInOtherGOPATH(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.tempFile("d1/src/p1/p1.go", `package p1
+
+import "p2"
+
+func F() { p2.F() }
+`)
+       tg.tempFile("d2/src/p2/p2.go", `package p2
+
+func F() {}
+`)
+       sep := string(filepath.ListSeparator)
+       tg.setenv("GOPATH", tg.path("d1")+sep+tg.path("d2"))
+       tg.run("install", "p1")
+       tg.wantNotStale("p1", "./testgo list mypkg claims p1 is stale, incorrectly")
+       tg.wantNotStale("p2", "./testgo list mypkg claims p2 is stale, incorrectly")
+       // TODO(iant): Sleep for one "tick", where a tick is the
+       // granularity of mtime on the file system.
+       time.Sleep(time.Second)
+       if f, err := os.OpenFile(tg.path("d2/src/p2/p2.go"), os.O_WRONLY|os.O_APPEND, 0); err != nil {
+               t.Fatal(err)
+       } else if _, err = f.WriteString(`func G() {}`); err != nil {
+               t.Fatal(err)
+       } else {
+               tg.must(f.Close())
+       }
+       tg.wantStale("p2", "./testgo list mypkg claims p2 is NOT stale, incorrectly")
+       tg.wantStale("p1", "./testgo list mypkg claims p1 is NOT stale, incorrectly")
+
+       tg.run("install", "p1")
+       tg.wantNotStale("p2", "./testgo list mypkg claims p2 is stale after reinstall, incorrectly")
+       tg.wantNotStale("p1", "./testgo list mypkg claims p1 is stale after reinstall, incorrectly")
+}
+
+func TestGoInstallDetectsRemovedFiles(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.tempFile("src/mypkg/x.go", `package mypkg`)
+       tg.tempFile("src/mypkg/y.go", `package mypkg`)
+       tg.tempFile("src/mypkg/z.go", `// +build missingtag
+
+package mypkg`)
+       tg.setenv("GOPATH", tg.path("."))
+       tg.run("install", "mypkg")
+       tg.wantNotStale("mypkg", "./testgo list mypkg claims mypkg is stale, incorrectly")
+       // z.go was not part of the build; removing it is okay.
+       tg.must(os.Remove(tg.path("src/mypkg/z.go")))
+       tg.wantNotStale("mypkg", "./testgo list mypkg claims mypkg is stale after removing z.go; should not be stale")
+       // y.go was part of the package; removing it should be detected.
+       tg.must(os.Remove(tg.path("src/mypkg/y.go")))
+       tg.wantStale("mypkg", "./testgo list mypkg claims mypkg is NOT stale after removing y.go; should be stale")
+}
+
+func TestGoInstsallDetectsRemovedFilesInPackageMain(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.tempFile("src/mycmd/x.go", `package main
+
+func main() {}
+`)
+       tg.tempFile("src/mycmd/y.go", `package main`)
+       tg.tempFile("src/mycmd/z.go", `// +build missingtag
+
+package main
+`)
+       tg.setenv("GOPATH", tg.path("."))
+       tg.run("install", "mycmd")
+       tg.wantNotStale("mycmd", "./testgo list mypkg claims mycmd is stale, incorrectly")
+       // z.go was not part of the build; removing it is okay.
+       tg.must(os.Remove(tg.path("src/mycmd/z.go")))
+       tg.wantNotStale("mycmd", "./testgo list mycmd claims mycmd is stale after removing z.go; should not be stale")
+       // y.go was part of the package; removing it should be detected.
+       tg.must(os.Remove(tg.path("src/mycmd/y.go")))
+       tg.wantStale("mycmd", "./testgo list mycmd claims mycmd is NOT stale after removing y.go; should be stale")
+}
+
+func testLocalRun(tg *testgoData, local, match string) {
+       out, err := exec.Command("./hello" + exeSuffix).Output()
+       if err != nil {
+               tg.t.Fatal("error running hello:", err)
+       }
+       if !regexp.MustCompile(match).Match(out) {
+               tg.t.Log(string(out))
+               tg.t.Errorf("testdata/%s/easy.go did not generate expected output", local)
+       }
+}
+
+func testLocalEasy(tg *testgoData, local string) {
+       tg.creatingTemp("./hello" + exeSuffix)
+       tg.run("build", "-o", "hello"+exeSuffix, filepath.Join("testdata", local, "easy.go"))
+       testLocalRun(tg, local, `(?m)^easysub\.Hello`)
+}
+
+func testLocalEasySub(tg *testgoData, local string) {
+       tg.creatingTemp("./hello" + exeSuffix)
+       tg.run("build", "-o", "hello"+exeSuffix, filepath.Join("testdata", local, "easysub", "main.go"))
+       testLocalRun(tg, local, `(?m)^easysub\.Hello`)
+}
+
+func testLocalHard(tg *testgoData, local string) {
+       tg.creatingTemp("./hello" + exeSuffix)
+       tg.run("build", "-o", "hello"+exeSuffix, filepath.Join("testdata", local, "hard.go"))
+       testLocalRun(tg, local, `(?m)^sub\.Hello`)
+}
+
+func testLocalInstall(tg *testgoData, local string) {
+       tg.runFail("install", filepath.Join("testdata", local, "easy.go"))
+}
+
+func TestLocalImportsEasy(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       testLocalEasy(tg, "local")
+}
+
+func TestLocalImportsEasySub(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       testLocalEasySub(tg, "local")
+}
+
+func TestLocalImportsHard(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       testLocalHard(tg, "local")
+}
+
+func TestLocalImportsGoInstallShouldFail(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       testLocalInstall(tg, "local")
+}
+
+const badDirName = `#$%:, &()*;<=>?\^{}`
+
+func copyBad(tg *testgoData) {
+       if runtime.GOOS == "windows" {
+               tg.t.Skipf("skipping test because %q is an invalid directory name", badDirName)
+       }
+
+       tg.must(filepath.Walk("testdata/local",
+               func(path string, info os.FileInfo, err error) error {
+                       if err != nil {
+                               return err
+                       }
+                       if info.IsDir() {
+                               return nil
+                       }
+                       var data []byte
+                       data, err = ioutil.ReadFile(path)
+                       if err != nil {
+                               return err
+                       }
+                       newpath := strings.Replace(path, "local", badDirName, 1)
+                       tg.tempFile(newpath, string(data))
+                       return nil
+               }))
+       tg.cd(tg.path("."))
+}
+
+func TestBadImportsEasy(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       copyBad(tg)
+       testLocalEasy(tg, badDirName)
+}
+
+func TestBadImportsEasySub(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       copyBad(tg)
+       testLocalEasySub(tg, badDirName)
+}
+
+func TestBadImportsHard(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       copyBad(tg)
+       testLocalHard(tg, badDirName)
+}
+
+func TestBadImportsGoInstallShouldFail(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       copyBad(tg)
+       testLocalInstall(tg, badDirName)
+}
+
+func TestInternalPackagesInGOROOTAreRespected(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.runFail("build", "-v", "./testdata/testinternal")
+       tg.grepBoth("use of internal package not allowed", "wrong error message for testdata/testinternal")
+}
+
+func TestInternalPackagesOutsideGOROOTAreRespected(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.runFail("build", "-v", "./testdata/testinternal2")
+       tg.grepBoth("use of internal package not allowed", "wrote error message for testdata/testinternal2")
+}
+
+func testMove(t *testing.T, vcs, url, base, config string) {
+       if testing.Short() {
+               t.Skip("skipping test that uses network in short mode")
+       }
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.tempDir("src")
+       tg.setenv("GOPATH", tg.path("."))
+       tg.run("get", "-d", url)
+       tg.run("get", "-d", "-u", url)
+       switch vcs {
+       case "svn":
+               // SVN doesn't believe in text files so we can't just edit the config.
+               // Check out a different repo into the wrong place.
+               tg.must(os.RemoveAll(tg.path("src/code.google.com/p/rsc-svn")))
+               tg.run("get", "-d", "-u", "code.google.com/p/rsc-svn2/trunk")
+               tg.must(os.Rename(tg.path("src/code.google.com/p/rsc-svn2"), tg.path("src/code.google.com/p/rsc-svn")))
+       default:
+               path := tg.path(filepath.Join("src", config))
+               data, err := ioutil.ReadFile(path)
+               tg.must(err)
+               data = bytes.Replace(data, []byte(base), []byte(base+"XXX"), -1)
+               tg.must(ioutil.WriteFile(path, data, 0644))
+       }
+       if vcs == "git" {
+               // git will ask for a username and password when we
+               // run go get -d -f -u.  An empty username and
+               // password will work.  Prevent asking by setting
+               // GIT_ASKPASS.
+               tg.creatingTemp("sink" + exeSuffix)
+               tg.tempFile("src/sink/sink.go", `package main; func main() {}`)
+               tg.run("build", "-o", "sink"+exeSuffix, "sink")
+               tg.setenv("GIT_ASKPASS", filepath.Join(tg.pwd(), "sink"+exeSuffix))
+       }
+       tg.runFail("get", "-d", "-u", url)
+       tg.grepStderr("is a custom import path for", "go get -d -u "+url+" failed for wrong reason")
+       tg.runFail("get", "-d", "-f", "-u", url)
+       tg.grepStderr("validating server certificate|not found", "go get -d -f -u "+url+" failed for wrong reason")
+}
+
+func TestMoveGit(t *testing.T) {
+       testMove(t, "git", "rsc.io/pdf", "pdf", "rsc.io/pdf/.git/config")
+}
+
+// TODO(rsc): Set up a test case on bitbucket for hg.
+// func TestMoveHG(t *testing.T) {
+//     testMove(t, "hg", "rsc.io/x86/x86asm", "x86", "rsc.io/x86/.hg/hgrc")
+// }
+
+// TODO(rsc): Set up a test case on SourceForge (?) for svn.
+// func testMoveSVN(t *testing.T) {
+//     testMove(t, "svn", "code.google.com/p/rsc-svn/trunk", "-", "-")
+// }
+
+func TestImportCommandMatch(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcom"))
+       tg.run("build", "./testdata/importcom/works.go")
+}
+
+func TestImportCommentMismatch(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcom"))
+       tg.runFail("build", "./testdata/importcom/wrongplace.go")
+       tg.grepStderr(`wrongplace expects import "my/x"`, "go build did not mention incorrect import")
+}
+
+func TestImportCommentSyntaxError(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcom"))
+       tg.runFail("build", "./testdata/importcom/bad.go")
+       tg.grepStderr("cannot parse import comment", "go build did not mention syntax error")
+}
+
+func TestImportCommentConflict(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcom"))
+       tg.runFail("build", "./testdata/importcom/conflict.go")
+       tg.grepStderr("found import comments", "go build did not mention comment conflict")
+}
+
+func TestDisallowedCSourceFiles(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+       tg.runFail("build", "badc")
+       tg.grepStderr("C source files not allowed", "go test did not say C source files not allowed")
+}
+
+func TestErrorMessageForSyntaxErrorInTestGoFileSaysFAIL(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+       tg.runFail("test", "syntaxerror")
+       tg.grepStderr("FAIL", "go test did not say FAIL")
+}
+
+func TestWildcardsDoNotLookInUselessDirectories(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+       tg.runFail("list", "...")
+       tg.grepBoth("badpkg", "go list ... failure does not mention badpkg")
+       tg.run("list", "m...")
+}
+
+func TestRelativeImportsGoTest(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.run("test", "./testdata/testimport")
+}
+
+func TestRelativeImportsGoTestDashI(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.run("test", "-i", "./testdata/testimport")
+}
+
+func TestRelativeImportsInCommandLinePackage(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       files, err := filepath.Glob("./testdata/testimport/*.go")
+       tg.must(err)
+       tg.run(append([]string{"test"}, files...)...)
+}
+
+func TestVersionControlErrorMessageIncludesCorrectDirectory(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/shadow/root1"))
+       tg.runFail("get", "-u", "foo")
+
+       // TODO(iant): We should not have to use strconv.Quote here.
+       // The code in vcs.go should be changed so that it is not required.
+       quoted := strconv.Quote(filepath.Join("testdata", "shadow", "root1", "src", "foo"))
+       quoted = quoted[1 : len(quoted)-1]
+
+       tg.grepStderr(regexp.QuoteMeta(quoted), "go get -u error does not mention shadow/root1/src/foo")
+}
+
+func TestInstallFailsWithNoBuildableFiles(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+       tg.setenv("CGO_ENABLED", "0")
+       tg.runFail("install", "cgotest")
+       tg.grepStderr("no buildable Go source files", "go install cgotest did not report 'no buildable Go Source files'")
+}
+
+// Test that without $GOBIN set, binaries get installed
+// into the GOPATH bin directory.
+func TestInstallIntoGOPATH(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.creatingTemp("testdata/bin/go-cmd-test" + exeSuffix)
+       tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+       tg.run("install", "go-cmd-test")
+       tg.wantExecutable("testdata/bin/go-cmd-test"+exeSuffix, "go install go-cmd-test did not write to testdata/bin/go-cmd-test")
+}
+
+func TestPackageMainTestImportsArchiveNotBinary(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       gobin := filepath.Join(tg.pwd(), "testdata", "bin")
+       tg.creatingTemp(gobin)
+       tg.setenv("GOBIN", gobin)
+       tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+       tg.must(os.Chtimes("./testdata/src/main_test/m.go", time.Now(), time.Now()))
+       tg.run("test", "main_test")
+       tg.run("install", "main_test")
+       tg.wantNotStale("main_test", "after go install, main listed as stale")
+       tg.run("test", "main_test")
+}
+
+// With $GOBIN set, binaries get installed to $GOBIN.
+func TestInstallIntoGOBIN(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       gobin := filepath.Join(tg.pwd(), "testdata", "bin1")
+       tg.creatingTemp(gobin)
+       tg.setenv("GOBIN", gobin)
+       tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+       tg.run("install", "go-cmd-test")
+       tg.wantExecutable("testdata/bin1/go-cmd-test"+exeSuffix, "go install go-cmd-test did not write to testdata/bin1/go-cmd-test")
+}
+
+// Without $GOBIN set, installing a program outside $GOPATH should fail
+// (there is nowhere to install it).
+func TestInstallWithoutDestinationFails(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.runFail("install", "testdata/src/go-cmd-test/helloworld.go")
+       tg.grepStderr("no install location for .go files listed on command line", "wrong error")
+}
+
+// With $GOBIN set, should install there.
+func TestInstallToGOBINCommandLinePackage(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       gobin := filepath.Join(tg.pwd(), "testdata", "bin1")
+       tg.creatingTemp(gobin)
+       tg.setenv("GOBIN", gobin)
+       tg.run("install", "testdata/src/go-cmd-test/helloworld.go")
+       tg.wantExecutable("testdata/bin1/helloworld"+exeSuffix, "go install testdata/src/go-cmd-test/helloworld.go did not write testdata/bin1/helloworld")
+}
+
+func TestGodocInstalls(t *testing.T) {
+       if testing.Short() {
+               t.Skip("skipping test that uses network in short mode")
+       }
+
+       // godoc installs into GOBIN
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.tempDir("gobin")
+       tg.setenv("GOPATH", tg.path("."))
+       tg.setenv("GOBIN", tg.path("gobin"))
+       tg.run("get", "golang.org/x/tools/cmd/godoc")
+       tg.wantExecutable(tg.path("gobin/godoc"), "did not install godoc to $GOBIN")
+       tg.unsetenv("GOBIN")
+
+       // godoc installs into GOROOT
+       goroot := runtime.GOROOT()
+       tg.setenv("GOROOT", goroot)
+       tg.check(os.RemoveAll(filepath.Join(goroot, "bin", "godoc")))
+       tg.run("install", "golang.org/x/tools/cmd/godoc")
+       tg.wantExecutable(filepath.Join(goroot, "bin", "godoc"), "did not install godoc to $GOROOT/bin")
+}
+
+func TestInstalls(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.tempDir("gobin")
+       tg.setenv("GOPATH", tg.path("."))
+       goroot := runtime.GOROOT()
+       tg.setenv("GOROOT", goroot)
+
+       // cmd/fix installs into tool
+       tg.run("env", "GOOS")
+       goos := strings.TrimSpace(tg.getStdout())
+       tg.setenv("GOOS", goos)
+       tg.run("env", "GOARCH")
+       goarch := strings.TrimSpace(tg.getStdout())
+       tg.setenv("GOARCH", goarch)
+       fixbin := filepath.Join(goroot, "pkg", "tool", goos+"_"+goarch, "fix") + exeSuffix
+       tg.must(os.RemoveAll(fixbin))
+       tg.run("install", "cmd/fix")
+       tg.wantExecutable(fixbin, "did not install cmd/fix to $GOROOT/pkg/tool")
+       tg.must(os.Remove(fixbin))
+       tg.setenv("GOBIN", tg.path("gobin"))
+       tg.run("install", "cmd/fix")
+       tg.wantExecutable(fixbin, "did not install cmd/fix to $GOROOT/pkg/tool with $GOBIN set")
+       tg.unsetenv("GOBIN")
+
+       // gopath program installs into GOBIN
+       tg.tempFile("src/progname/p.go", `package main; func main() {}`)
+       tg.setenv("GOBIN", tg.path("gobin"))
+       tg.run("install", "progname")
+       tg.unsetenv("GOBIN")
+       tg.wantExecutable(tg.path("gobin/progname")+exeSuffix, "did not install progname to $GOBIN/progname")
+
+       // gopath program installs into GOPATH/bin
+       tg.run("install", "progname")
+       tg.wantExecutable(tg.path("bin/progname")+exeSuffix, "did not install progname to $GOPATH/bin/progname")
+}
+
+func TestRejectRelativePathsInGOPATHCommandLinePackage(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.setenv("GOPATH", ".")
+       tg.runFail("build", "testdata/src/go-cmd-test/helloworld.go")
+}
+
+func TestRejectRelativePathsInGOPATH(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       sep := string(filepath.ListSeparator)
+       tg.setenv("GOPATH", sep+filepath.Join(tg.pwd(), "testdata")+sep+".")
+       tg.runFail("build", "go-cmd-test")
+}
+
+// Issue 4104.
+func TestGoTestWithPackageListedMultipleTimes(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.run("test", "fmt", "fmt", "fmt", "fmt", "fmt")
+       if strings.Index(strings.TrimSpace(tg.getStdout()), "\n") != -1 {
+               t.Error("go test fmt fmt fmt fmt fmt tested the same package multiple times")
+       }
+}
+
+func TestGoListHasAConsistentOrder(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.run("list", "std")
+       first := tg.getStdout()
+       tg.run("list", "std")
+       if first != tg.getStdout() {
+               t.Error("go list std ordering is inconsistent")
+       }
+}
+
+func TestGoListStdDoesNotIncludeCommands(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.run("list", "std")
+       tg.grepStdoutNot("cmd/", "go list std shows commands")
+}
+
+func TestGoListCmdOnlyShowsCommands(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.run("list", "cmd")
+       out := strings.TrimSpace(tg.getStdout())
+       for _, line := range strings.Split(out, "\n") {
+               if strings.Index(line, "cmd/") == -1 {
+                       t.Error("go list cmd shows non-commands")
+                       break
+               }
+       }
+}
+
+// Issue 4096. Validate the output of unsuccessful go install foo/quxx.
+func TestUnsuccessfulGoInstallShouldMentionMissingPackage(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.runFail("install", "foo/quxx")
+       if tg.grepCountBoth(`cannot find package "foo/quxx" in any of`) != 1 {
+               t.Error(`go install foo/quxx expected error: .*cannot find package "foo/quxx" in any of`)
+       }
+}
+
+func TestGOROOTSearchFailureReporting(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.runFail("install", "foo/quxx")
+       if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("foo", "quxx"))+` \(from \$GOROOT\)$`) != 1 {
+               t.Error(`go install foo/quxx expected error: .*foo/quxx (from $GOROOT)`)
+       }
+}
+
+func TestMultipleGOPATHEntriesReportedSeparately(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       sep := string(filepath.ListSeparator)
+       tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
+       tg.runFail("install", "foo/quxx")
+       if tg.grepCountBoth(`testdata[/\\].[/\\]src[/\\]foo[/\\]quxx`) != 2 {
+               t.Error(`go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)\n.*testdata/b/src/foo/quxx`)
+       }
+}
+
+// Test (from $GOPATH) annotation is reported for the first GOPATH entry,
+func TestMentionGOPATHInFirstGOPATHEntry(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       sep := string(filepath.ListSeparator)
+       tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
+       tg.runFail("install", "foo/quxx")
+       if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("testdata", "a", "src", "foo", "quxx"))+` \(from \$GOPATH\)$`) != 1 {
+               t.Error(`go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)`)
+       }
+}
+
+// but not on the second.
+func TestMentionGOPATHNotOnSecondEntry(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       sep := string(filepath.ListSeparator)
+       tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
+       tg.runFail("install", "foo/quxx")
+       if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("testdata", "b", "src", "foo", "quxx"))+`$`) != 1 {
+               t.Error(`go install foo/quxx expected error: .*testdata/b/src/foo/quxx`)
+       }
+}
+
+// Test missing GOPATH is reported.
+func TestMissingGOPATHIsReported(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.setenv("GOPATH", "")
+       tg.runFail("install", "foo/quxx")
+       if tg.grepCountBoth(`\(\$GOPATH not set\)$`) != 1 {
+               t.Error(`go install foo/quxx expected error: ($GOPATH not set)`)
+       }
+}
+
+// Issue 4186.  go get cannot be used to download packages to $GOROOT.
+// Test that without GOPATH set, go get should fail.
+func TestWithoutGOPATHGoGetFails(t *testing.T) {
+       if testing.Short() {
+               t.Skip("skipping test that uses network in short mode")
+       }
+
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.tempDir("src")
+       tg.setenv("GOPATH", "")
+       tg.setenv("GOROOT", tg.path("."))
+       tg.runFail("get", "-d", "golang.org/x/codereview/cmd/hgpatch")
+}
+
+// Test that with GOPATH=$GOROOT, go get should fail.
+func TestWithGOPATHEqualsGOROOTGoGetFails(t *testing.T) {
+       if testing.Short() {
+               t.Skip("skipping test that uses network in short mode")
+       }
+
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.tempDir("src")
+       tg.setenv("GOPATH", tg.path("."))
+       tg.setenv("GOROOT", tg.path("."))
+       tg.runFail("get", "-d", "golang.org/x/codereview/cmd/hgpatch")
+}
+
+func TestLdflagsArgumentsWithSpacesIssue3941(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.tempFile("main.go", `package main
+var extern string
+func main() {
+       println(extern)
+}`)
+       tg.run("run", "-ldflags", `-X main.extern "hello world"`, tg.path("main.go"))
+       tg.grepStderr("^hello world", `ldflags -X main.extern 'hello world' failed`)
+}
+
+func TestGoTestCpuprofileLeavesBinaryBehind(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.creatingTemp("strings.prof")
+       tg.creatingTemp("strings.test" + exeSuffix)
+       tg.run("test", "-cpuprofile", "strings.prof", "strings")
+       tg.wantExecutable("strings.test"+exeSuffix, "go test -cpuprofile did not create strings.test")
+}
+
+func TestGoTestCpuProfileDashOControlsBinaryLocation(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.creatingTemp("strings.prof")
+       tg.creatingTemp("mystrings.test" + exeSuffix)
+       tg.run("test", "-cpuprofile", "strings.prof", "-o", "mystrings.test"+exeSuffix, "strings")
+       tg.wantExecutable("mystrings.test"+exeSuffix, "go test -cpuprofile -o mystrings.test did not create mystrings.test")
+}
+
+func TestGoTestDashCDashOControlsBinaryLocation(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.creatingTemp("mystrings.test" + exeSuffix)
+       tg.run("test", "-c", "-o", "mystrings.test"+exeSuffix, "strings")
+       tg.wantExecutable("mystrings.test"+exeSuffix, "go test -c -o mystrings.test did not create mystrings.test")
+}
+
+func TestGoTestDashOWritesBinary(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.creatingTemp("mystrings.test" + exeSuffix)
+       tg.run("test", "-o", "mystrings.test"+exeSuffix, "strings")
+       tg.wantExecutable("mystrings.test"+exeSuffix, "go test -o mystrings.test did not create mystrings.test")
+}
+
+// Issue 4568.
+func TestSymlinksDoNotConfuseGoList(t *testing.T) {
+       switch runtime.GOOS {
+       case "plan9", "windows":
+               t.Skipf("skipping symlink test on %s", runtime.GOOS)
+       }
+
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.tempDir("src")
+       tg.must(os.Symlink(tg.path("."), tg.path("src/dir1")))
+       tg.tempFile("src/dir1/p.go", "package p")
+       tg.setenv("GOPATH", tg.path("."))
+       tg.cd(tg.path("src"))
+       tg.run("list", "-f", "{{.Root}}", "dir1")
+       if strings.TrimSpace(tg.getStdout()) != tg.path(".") {
+               t.Error("confused by symlinks")
+       }
+}
+
+// Issue 4515.
+func TestInstallWithTags(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.tempDir("bin")
+       tg.tempFile("src/example/a/main.go", `package main
+func main() {}`)
+       tg.tempFile("src/example/b/main.go", `// +build mytag
+
+package main
+func main() {}`)
+       tg.setenv("GOPATH", tg.path("."))
+       tg.run("install", "-tags", "mytag", "example/a", "example/b")
+       tg.wantExecutable(tg.path("bin/a"+exeSuffix), "go install example/a example/b did not install binaries")
+       tg.wantExecutable(tg.path("bin/b"+exeSuffix), "go install example/a example/b did not install binaries")
+       tg.must(os.Remove(tg.path("bin/a" + exeSuffix)))
+       tg.must(os.Remove(tg.path("bin/b" + exeSuffix)))
+       tg.run("install", "-tags", "mytag", "example/...")
+       tg.wantExecutable(tg.path("bin/a"+exeSuffix), "go install example/... did not install binaries")
+       tg.wantExecutable(tg.path("bin/b"+exeSuffix), "go install example/... did not install binaries")
+       tg.run("list", "-tags", "mytag", "example/b...")
+       if strings.TrimSpace(tg.getStdout()) != "example/b" {
+               t.Error("go list example/b did not find example/b")
+       }
+}
+
+// Issue 4773
+func TestCaseCollisions(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.tempDir("src/example/a/pkg")
+       tg.tempDir("src/example/a/Pkg")
+       tg.tempDir("src/example/b")
+       tg.setenv("GOPATH", tg.path("."))
+       tg.tempFile("src/example/a/a.go", `package p
+import (
+       _ "example/a/pkg"
+       _ "example/a/Pkg"
+)`)
+       tg.tempFile("src/example/a/pkg/pkg.go", `package pkg`)
+       tg.tempFile("src/example/a/Pkg/pkg.go", `package pkg`)
+       tg.runFail("list", "example/a")
+       tg.grepStderr("case-insensitive import collision", "go list example/a did not report import collision")
+       tg.tempFile("src/example/b/file.go", `package b`)
+       tg.tempFile("src/example/b/FILE.go", `package b`)
+       f, err := os.Open(tg.path("src/example/b"))
+       tg.must(err)
+       names, err := f.Readdirnames(0)
+       tg.must(err)
+       tg.check(f.Close())
+       args := []string{"list"}
+       if len(names) == 2 {
+               // case-sensitive file system, let directory read find both files
+               args = append(args, "example/b")
+       } else {
+               // case-insensitive file system, list files explicitly on command line
+               args = append(args, tg.path("src/example/b/file.go"), tg.path("src/example/b/FILE.go"))
+       }
+       tg.runFail(args...)
+       tg.grepStderr("case-insensitive file name collision", "go list example/b did not report file name collision")
+}
+
+// Issue 8181.
+func TestGoGetDashTIssue8181(t *testing.T) {
+       if testing.Short() {
+               t.Skip("skipping test that uses network in short mode")
+       }
+
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.makeTempdir()
+       tg.setenv("GOPATH", tg.path("."))
+       tg.run("get", "-t", "code.google.com/p/go-get-issue-8181/a", "code.google.com/p/go-get-issue-8181/b")
+       tg.runFail("list", "...")
+       tg.grepStdout("go.tools/godoc", "missing expected go.tools/godoc")
+}
+
+func TestShadowingLogic(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       pwd := tg.pwd()
+       sep := string(filepath.ListSeparator)
+       tg.setenv("GOPATH", filepath.Join(pwd, "testdata", "shadow", "root1")+sep+filepath.Join(pwd, "testdata", "shadow", "root2"))
+
+       // The math in root1 is not "math" because the standard math is.
+       tg.run("list", "-f", "({{.ImportPath}}) ({{.ConflictDir}})", "./testdata/shadow/root1/src/math")
+       pwdForwardSlash := strings.Replace(pwd, string(os.PathSeparator), "/", -1)
+       if !strings.HasPrefix(pwdForwardSlash, "/") {
+               pwdForwardSlash = "/" + pwdForwardSlash
+       }
+       // The output will have makeImportValid applies, but we only
+       // bother to deal with characters we might reasonably see.
+       pwdForwardSlash = strings.Replace(pwdForwardSlash, ":", "_", -1)
+       want := "(_" + pwdForwardSlash + "/testdata/shadow/root1/src/math) (" + filepath.Join(runtime.GOROOT(), "src", "math") + ")"
+       if strings.TrimSpace(tg.getStdout()) != want {
+               t.Error("shadowed math is not shadowed; looking for", want)
+       }
+
+       // The foo in root1 is "foo".
+       tg.run("list", "-f", "({{.ImportPath}}) ({{.ConflictDir}})", "./testdata/shadow/root1/src/foo")
+       if strings.TrimSpace(tg.getStdout()) != "(foo) ()" {
+               t.Error("unshadowed foo is shadowed")
+       }
+
+       // The foo in root2 is not "foo" because the foo in root1 got there first.
+       tg.run("list", "-f", "({{.ImportPath}}) ({{.ConflictDir}})", "./testdata/shadow/root2/src/foo")
+       want = "(_" + pwdForwardSlash + "/testdata/shadow/root2/src/foo) (" + filepath.Join(pwd, "testdata", "shadow", "root1", "src", "foo") + ")"
+       if strings.TrimSpace(tg.getStdout()) != want {
+               t.Error("shadowed foo is not shadowed; looking for", want)
+       }
+
+       // The error for go install should mention the conflicting directory.
+       tg.runFail("install", "./testdata/shadow/root2/src/foo")
+       want = "go install: no install location for " + filepath.Join(pwd, "testdata", "shadow", "root2", "src", "foo") + ": hidden by " + filepath.Join(pwd, "testdata", "shadow", "root1", "src", "foo")
+       if strings.TrimSpace(tg.getStderr()) != want {
+               t.Error("wrong shadowed install error; looking for", want)
+       }
+}
+
+// Only succeeds if source order is preserved.
+func TestSourceFileNameOrderPreserved(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.run("test", "testdata/example1_test.go", "testdata/example2_test.go")
+}
+
+// Check that coverage analysis works at all.
+// Don't worry about the exact numbers but require not 0.0%.
+func checkCoverage(tg *testgoData, data string) {
+       if regexp.MustCompile(`[^0-9]0\.0%`).MatchString(data) {
+               tg.t.Error("some coverage results are 0.0%")
+       }
+       tg.t.Log(data)
+}
+
+func TestCoverageRuns(t *testing.T) {
+       if testing.Short() {
+               t.Skip("don't build libraries for coverage in short mode")
+       }
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.run("test", "-short", "-coverpkg=strings", "strings", "regexp")
+       data := tg.getStdout() + tg.getStderr()
+       tg.run("test", "-short", "-cover", "strings", "math", "regexp")
+       data += tg.getStdout() + tg.getStderr()
+       checkCoverage(tg, data)
+}
+
+// Check that coverage analysis uses set mode.
+func TestCoverageUsesSetMode(t *testing.T) {
+       if testing.Short() {
+               t.Skip("don't build libraries for coverage in short mode")
+       }
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.creatingTemp("testdata/cover.out")
+       tg.run("test", "-short", "-cover", "encoding/binary", "-coverprofile=testdata/cover.out")
+       data := tg.getStdout() + tg.getStderr()
+       if out, err := ioutil.ReadFile("testdata/cover.out"); err != nil {
+               t.Error(err)
+       } else {
+               if !bytes.Contains(out, []byte("mode: set")) {
+                       t.Error("missing mode: set")
+               }
+       }
+       checkCoverage(tg, data)
+}
+
+func TestCoverageUsesAtomicModeForRace(t *testing.T) {
+       if testing.Short() {
+               t.Skip("don't build libraries for coverage in short mode")
+       }
+       if !canRace {
+               t.Skip("skipping because race detector not supported")
+       }
+
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.creatingTemp("testdata/cover.out")
+       tg.run("test", "-short", "-race", "-cover", "encoding/binary", "-coverprofile=testdata/cover.out")
+       data := tg.getStdout() + tg.getStderr()
+       if out, err := ioutil.ReadFile("testdata/cover.out"); err != nil {
+               t.Error(err)
+       } else {
+               if !bytes.Contains(out, []byte("mode: atomic")) {
+                       t.Error("missing mode: atomic")
+               }
+       }
+       checkCoverage(tg, data)
+}
+
+func TestCoverageUsesActualSettingToOverrideEvenForRace(t *testing.T) {
+       if testing.Short() {
+               t.Skip("don't build libraries for coverage in short mode")
+       }
+       if !canRace {
+               t.Skip("skipping because race detector not supported")
+       }
+
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.creatingTemp("testdata/cover.out")
+       tg.run("test", "-short", "-race", "-cover", "encoding/binary", "-covermode=count", "-coverprofile=testdata/cover.out")
+       data := tg.getStdout() + tg.getStderr()
+       if out, err := ioutil.ReadFile("testdata/cover.out"); err != nil {
+               t.Error(err)
+       } else {
+               if !bytes.Contains(out, []byte("mode: count")) {
+                       t.Error("missing mode: count")
+               }
+       }
+       checkCoverage(tg, data)
+}
+
+func TestCoverageWithCgo(t *testing.T) {
+       if !canCgo {
+               t.Skip("skipping because cgo not enabled")
+       }
+
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.run("test", "-short", "-cover", "./testdata/cgocover")
+       data := tg.getStdout() + tg.getStderr()
+       checkCoverage(tg, data)
+}
+
+func TestCgoDependsOnSyscall(t *testing.T) {
+       if testing.Short() {
+               t.Skip("skipping test that removes $GOROOT/pkg/*_race in short mode")
+       }
+       if !canCgo {
+               t.Skip("skipping because cgo not enabled")
+       }
+       if !canRace {
+               t.Skip("skipping because race detector not supported")
+       }
+
+       tg := testgo(t)
+       defer tg.cleanup()
+       files, err := filepath.Glob(filepath.Join(runtime.GOROOT(), "pkg", "*_race"))
+       tg.must(err)
+       for _, file := range files {
+               tg.check(os.RemoveAll(file))
+       }
+       tg.tempFile("src/foo/foo.go", `
+package foo
+//#include <stdio.h>
+import "C"`)
+       tg.setenv("GOPATH", tg.path("."))
+       tg.run("build", "-race", "foo")
+}
+
+func TestCgoShowsFullPathNames(t *testing.T) {
+       if !canCgo {
+               t.Skip("skipping because cgo not enabled")
+       }
+
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.tempFile("src/x/y/dirname/foo.go", `
+package foo
+import "C"
+func f() {`)
+       tg.setenv("GOPATH", tg.path("."))
+       tg.runFail("build", "x/y/dirname")
+       tg.grepBoth("x/y/dirname", "error did not use full path")
+}
+
+func TestCgoHandlesWlORIGIN(t *testing.T) {
+       if !canCgo {
+               t.Skip("skipping because cgo not enabled")
+       }
+
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.tempFile("src/origin/origin.go", `package origin
+// #cgo !darwin LDFLAGS: -Wl,-rpath -Wl,$ORIGIN
+// void f(void) {}
+import "C"
+
+func f() { C.f() }`)
+       tg.setenv("GOPATH", tg.path("."))
+       tg.run("build", "origin")
+}
+
+// "go test -c -test.bench=XXX fmt" should not hang'
+func TestIssue6480(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.creatingTemp("fmt.test" + exeSuffix)
+       tg.run("test", "-c", "-test.bench=XXX", "fmt")
+}
+
+// cmd/cgo: undefined reference when linking a C-library using gccgo
+func TestIssue7573(t *testing.T) {
+       if _, err := exec.LookPath("gccgo"); err != nil {
+               t.Skip("skipping because no gccgo compiler found")
+       }
+
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.tempFile("src/cgoref/cgoref.go", `
+package main
+// #cgo LDFLAGS: -L alibpath -lalib
+// void f(void) {}
+import "C"
+
+func main() { C.f() }`)
+       tg.setenv("GOPATH", tg.path("."))
+       tg.run("build", "-n", "-compiler", "gccgo", "cgoref")
+       tg.grepStderr(`gccgo.*\-L alibpath \-lalib`, `no Go-inline "#cgo LDFLAGS:" ("-L alibpath -lalib") passed to gccgo linking stage`)
+}
+
+func TestListTemplateCanUseContextFunction(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.run("list", "-f", "GOARCH: {{context.GOARCH}}")
+}
+
+// cmd/go: "go test" should fail if package does not build
+func TestIssue7108(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+       tg.runFail("test", "notest")
+}
+
+// cmd/go: go test -a foo does not rebuild regexp.
+func TestIssue6844(t *testing.T) {
+       if testing.Short() {
+               t.Skip("don't rebuild the standard libary in short mode")
+       }
+
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.creatingTemp("deps.test" + exeSuffix)
+       tg.run("test", "-x", "-a", "-c", "testdata/dep_test.go")
+       tg.grepStderr("regexp", "go test -x -a -c testdata/dep-test.go did not rebuild regexp")
+}
+
+func TestBuildDashIInstallsDependencies(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.tempFile("src/x/y/foo/foo.go", `package foo
+func F() {}`)
+       tg.tempFile("src/x/y/bar/bar.go", `package bar
+import "x/y/foo"
+func F() { foo.F() }`)
+       tg.setenv("GOPATH", tg.path("."))
+
+       checkbar := func(desc string) {
+               // TODO(iant): Sleep for one "tick", where a tick is
+               // the granularity of mtime on the file system.
+               time.Sleep(time.Second)
+               tg.must(os.Chtimes(tg.path("src/x/y/foo/foo.go"), time.Now(), time.Now()))
+               time.Sleep(time.Second)
+               tg.run("build", "-v", "-i", "x/y/bar")
+               tg.grepBoth("x/y/foo", "first build -i "+desc+" did not build x/y/foo")
+               tg.run("build", "-v", "-i", "x/y/bar")
+               tg.grepBothNot("x/y/foo", "second build -i "+desc+" built x/y/foo")
+       }
+       checkbar("pkg")
+       tg.creatingTemp("bar" + exeSuffix)
+       tg.tempFile("src/x/y/bar/bar.go", `package main
+import "x/y/foo"
+func main() { foo.F() }`)
+       checkbar("cmd")
+}
+
+func TestGoBuildInTestOnlyDirectoryFailsWithAGoodError(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.runFail("build", "./testdata/testonly")
+       tg.grepStderr("no buildable Go", "go build ./testdata/testonly produced unexpected error")
+}
+
+func TestGoTestDetectsTestOnlyImportCycles(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+       tg.runFail("test", "-c", "testcycle/p3")
+       tg.grepStderr("import cycle not allowed in test", "go test testcycle/p3 produced unexpected error")
+}
+
+func TestGoTestFooTestWorks(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.run("test", "testdata/standalone_test.go")
+}
+
+func TestGoTestXtestonlyWorks(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+       tg.run("clean", "-i", "xtestonly")
+       tg.run("test", "xtestonly")
+}
+
+func TestGoTestBuildsAnXtestContainingOnlyNonRunnableExamples(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.run("test", "-v", "./testdata/norunexample")
+       tg.grepStdout("File with non-runnable example was built.", "file with non-runnable example was not built")
+}
+
+func TestGoGenerateHandlesSimpleCommand(t *testing.T) {
+       if runtime.GOOS == "windows" {
+               t.Skip("skipping because windows has no echo command")
+       }
+
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.run("generate", "./testdata/generate/test1.go")
+       tg.grepStdout("Success", "go generate ./testdata/generate/test1.go generated wrong output")
+}
+
+func TestGoGenerateHandlesCommandAlias(t *testing.T) {
+       if runtime.GOOS == "windows" {
+               t.Skip("skipping because windows has no echo command")
+       }
+
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.run("generate", "./testdata/generate/test2.go")
+       tg.grepStdout("Now is the time for all good men", "go generate ./testdata/generate/test2.go generated wrong output")
+}
+
+func TestGoGenerateVariableSubstitution(t *testing.T) {
+       if runtime.GOOS == "windows" {
+               t.Skip("skipping because windows has no echo command")
+       }
+
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.run("generate", "./testdata/generate/test3.go")
+       tg.grepStdout(runtime.GOARCH+" test3.go:7 pabc xyzp/test3.go/123", "go generate ./testdata/generate/test3.go generated wrong output")
+}
+
+func TestGoGenerateRunFlag(t *testing.T) {
+       if runtime.GOOS == "windows" {
+               t.Skip("skipping because windows has no echo command")
+       }
+
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.run("generate", "-run", "y.s", "./testdata/generate/test4.go")
+       tg.grepStdout("yes", "go generate -run yes ./testdata/generate/test4.go did not select yes")
+       tg.grepStdoutNot("no", "go generate -run yes ./testdata/generate/test4.go selected no")
+}
+
+func TestGoGetWorksWithVanityWildcards(t *testing.T) {
+       if testing.Short() {
+               t.Skip("skipping test that uses network in short mode")
+       }
+
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.makeTempdir()
+       tg.setenv("GOPATH", tg.path("."))
+       tg.run("get", "-u", "rsc.io/pdf/...")
+       tg.wantExecutable(tg.path("bin/pdfpasswd"+exeSuffix), "did not build rsc/io/pdf/pdfpasswd")
+}
+
+func TestGoVetWithExternalTests(t *testing.T) {
+       if testing.Short() {
+               t.Skip("skipping test that uses network in short mode")
+       }
+
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.makeTempdir()
+       tg.setenv("GOPATH", tg.path("."))
+       tg.run("get", "golang.org/x/tools/cmd/vet")
+       tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+       tg.runFail("vet", "vetpkg")
+       tg.grepBoth("missing argument for Printf", "go vet vetpkg did not find missing argument for Printf")
+}
+
+func TestGoVetWithTags(t *testing.T) {
+       if testing.Short() {
+               t.Skip("skipping test that uses network in short mode")
+       }
+
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.makeTempdir()
+       tg.setenv("GOPATH", tg.path("."))
+       tg.run("get", "golang.org/x/tools/cmd/vet")
+       tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+       tg.runFail("vet", "-tags", "tagtest", "vetpkg")
+       tg.grepBoth(`c\.go.*wrong number of args for format`, "go get vetpkg did not run scan tagged file")
+}
+
+// Issue 9767.
+func TestGoGetRscIoToolstash(t *testing.T) {
+       if testing.Short() {
+               t.Skip("skipping test that uses network in short mode")
+       }
+
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.tempDir("src/rsc.io")
+       tg.setenv("GOPATH", tg.path("."))
+       tg.cd(tg.path("src/rsc.io"))
+       tg.run("get", "./toolstash")
 }
diff --git a/src/cmd/go/test.bash b/src/cmd/go/test.bash
deleted file mode 100755 (executable)
index d9ac3f7..0000000
+++ /dev/null
@@ -1,1330 +0,0 @@
-#!/bin/bash
-# Copyright 2012 The Go Authors.  All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-set -e
-go build -tags testgo -o testgo
-go() {
-       echo TEST ERROR: ran go, not testgo: go "$@" >&2
-       exit 2
-}
-
-started=false
-testdesc=""
-nl="
-"
-TEST() {
-       if $started; then
-               stop
-       fi
-       echo TEST: "$@"
-       testdesc="$@"
-       started=true
-       ok=true
-}
-stop() {
-       if ! $started; then
-               echo TEST ERROR: stop missing start >&2
-               exit 2
-       fi
-       started=false
-       if $ok; then
-               echo PASS
-       else
-               echo FAIL
-               testfail="$testfail     $testdesc$nl"
-               allok=false
-       fi
-}
-
-ok=true
-allok=true
-
-unset GOBIN
-unset GOPATH
-unset GOROOT
-
-TEST 'program name in crash messages'
-linker=$(./testgo env GOCHAR)l
-d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
-./testgo build -ldflags -crash_for_testing $(./testgo env GOROOT)/test/helloworld.go 2>$d/err.out || true
-if ! grep -q "/tool/.*/$linker" $d/err.out; then
-       echo "missing linker name in error message"
-       cat $d/err.out
-       ok=false
-fi
-rm -r $d
-
-TEST broken tests without Test functions all fail
-d=$(mktemp -d -t testgoXXX)
-./testgo test ./testdata/src/badtest/... >$d/err 2>&1 || true
-if grep -q '^ok' $d/err; then
-       echo test passed unexpectedly:
-       grep '^ok' $d/err
-       ok=false
-elif ! grep -q 'FAIL.*badtest/badexec' $d/err || ! grep -q 'FAIL.*badtest/badsyntax' $d/err || ! grep -q 'FAIL.*badtest/badvar' $d/err; then
-       echo test did not run everything
-       cat $d/err
-       ok=false
-fi
-rm -rf $d
-
-TEST 'go build -a in dev branch'
-./testgo install math || ok=false # should be up to date already but just in case
-d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
-if ! TESTGO_IS_GO_RELEASE=0 ./testgo build -v -a math 2>$d/err.out; then
-       cat $d/err.out
-       ok=false
-elif ! grep -q runtime $d/err.out; then
-       echo "testgo build -a math in dev branch DID NOT build runtime, but should have"
-       cat $d/err.out
-       ok=false
-fi
-rm -r $d
-
-TEST 'go build -a in release branch'
-./testgo install math || ok=false # should be up to date already but just in case
-d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
-if ! TESTGO_IS_GO_RELEASE=1 ./testgo build -v -a math 2>$d/err.out; then
-       cat $d/err.out
-       ok=false
-elif grep -q runtime $d/err.out; then
-       echo "testgo build -a math in dev branch DID build runtime, but should NOT have"
-       cat $d/err.out
-       ok=false
-fi
-rm -r $d
-
-TEST 'go install cleans up after go build'
-d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
-export GOPATH=$d
-mkdir -p $d/src/mycmd
-echo 'package main; func main(){}' >$d/src/mycmd/main.go
-old=$(pwd)
-cd $d/src/mycmd
-"$old/testgo" build
-if [ ! -x mycmd ]; then
-       echo "testgo build did not write command binary"
-       ok=false
-fi
-"$old/testgo" install
-if [ -e mycmd ]; then
-       echo "testgo install did not remove command binary"
-       ok=false
-fi
-"$old/testgo" build
-if [ ! -x mycmd ]; then
-       echo "testgo build did not write command binary (second time)"
-       ok=false
-fi
-# install with arguments does not remove the target,
-# even in the same directory
-"$old/testgo" install mycmd
-if [ ! -e mycmd ]; then
-       echo "testgo install mycmd removed command binary when run in mycmd"
-       ok=false
-fi
-"$old/testgo" build
-if [ ! -x mycmd ]; then
-       echo "testgo build did not write command binary (third time)"
-       ok=false
-fi
-# and especially not outside the directory
-cd $d
-cp src/mycmd/mycmd .
-"$old/testgo" install mycmd
-if [ ! -e $d/src/mycmd/mycmd ]; then
-       echo "testgo install mycmd removed command binary from its source dir when run outside mycmd"
-       ok=false
-fi
-if [ ! -e $d/mycmd ]; then
-       echo "testgo install mycmd removed command binary from current dir when run outside mycmd"
-       ok=false
-fi
-cd "$old"
-rm -r $d
-
-TEST 'go install rebuilds stale packages in other GOPATH'
-d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
-export GOPATH=$d/d1:$d/d2
-mkdir -p $d/d1/src/p1 $d/d2/src/p2
-echo 'package p1
-
-import "p2"
-
-func F() { p2.F() }
-' > $d/d1/src/p1/p1.go
-echo 'package p2
-
-func F() {}
-' > $d/d2/src/p2/p2.go
-if ! ./testgo install p1; then
-       echo "./testgo install p1 failed"
-       ok=false
-elif [ "$(./testgo list -f '{{.Stale}}' p1)" != false ]; then
-       echo "./testgo list mypkg claims p1 is stale, incorrectly"
-       ok=false
-elif [ "$(./testgo list -f '{{.Stale}}' p2)" != false ]; then
-       echo "./testgo list mypkg claims p2 is stale, incorrectly"
-       ok=false
-else
-       sleep 1
-       echo 'func G() {}' >>$d/d2/src/p2/p2.go
-       if [ "$(./testgo list -f '{{.Stale}}' p2)" != true ]; then
-               echo "./testgo list mypkg claims p2 is NOT stale, incorrectly"
-               ok=false
-       elif [ "$(./testgo list -f '{{.Stale}}' p1)" != true ]; then
-               echo "./testgo list mypkg claims p1 is NOT stale, incorrectly"
-               ok=false
-       fi
-       
-       if ! ./testgo install p1; then
-               echo "./testgo install p1 failed second time"
-               ok=false
-       else
-               if [ "$(./testgo list -f '{{.Stale}}' p2)" != false ]; then
-                       echo "./testgo list mypkg claims p2 is stale after reinstall, incorrectly"
-                       ok=false
-               elif [ "$(./testgo list -f '{{.Stale}}' p1)" != false ]; then
-                       echo "./testgo list mypkg claims p1 is stale after reinstall, incorrectly"
-                       ok=false
-               fi
-       fi              
-fi
-rm -r $d
-
-TEST 'go install detects removed files'
-d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
-export GOPATH=$d
-mkdir -p $d/src/mypkg
-echo package mypkg >$d/src/mypkg/x.go
-echo package mypkg >$d/src/mypkg/y.go
-echo '// +build missingtag
-
-package mypkg' >$d/src/mypkg/z.go
-if ! ./testgo install mypkg; then
-       echo "./testgo install mypkg failed"
-       ok=false
-elif [ "$(./testgo list -f '{{.Stale}}' mypkg)" != false ]; then
-       echo "./testgo list mypkg claims mypkg is stale, incorrectly"
-       ok=false
-else
-       # z.go was not part of the build; removing it is okay.
-       rm $d/src/mypkg/z.go
-       if [ "$(./testgo list -f '{{.Stale}}' mypkg)" != false ]; then
-               echo "./testgo list mypkg claims mypkg is stale after removing z.go; should not be stale"
-               ok=false
-               ./testgo install mypkg
-       fi
-       # y.go was part of the package; removing it should be detected.
-       rm $d/src/mypkg/y.go
-       if [ "$(./testgo list -f '{{.Stale}}' mypkg)" != true ]; then
-               echo "./testgo list mypkg claims mypkg is NOT stale after removing y.go; should be stale"
-               ok=false
-       fi
-fi
-rm -r $d
-
-TEST 'go install detects removed files in package main'
-d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
-export GOPATH=$d
-mkdir -p $d/src/mycmd
-echo 'package main
-
-func main() {}
-' >$d/src/mycmd/x.go
-echo package main >$d/src/mycmd/y.go
-echo '// +build missingtag
-
-package main' >$d/src/mycmd/z.go
-if ! ./testgo install mycmd; then
-       echo "./testgo install mycmd failed"
-       ok=false
-elif [ "$(./testgo list -f '{{.Stale}}' mycmd)" != false ]; then
-       echo "./testgo list mypkg claims mycmd is stale, incorrectly"
-       ok=false
-else
-       # z.go was not part of the build; removing it is okay.
-       rm $d/src/mycmd/z.go
-       if [ "$(./testgo list -f '{{.Stale}}' mycmd)" != false ]; then
-               echo "./testgo list mycmd claims mycmd is stale after removing z.go; should not be stale"
-               ok=false
-               ./testgo install mycmd
-       fi
-       # y.go was part of the package; removing it should be detected.
-       rm $d/src/mycmd/y.go
-       if [ "$(./testgo list -f '{{.Stale}}' mycmd)" != true ]; then
-               echo "./testgo list mycmd claims mycmd is NOT stale after removing y.go; should be stale"
-               ok=false
-       fi
-fi
-rm -r $d
-
-
-# Test local (./) imports.
-testlocal() {
-       local="$1"
-       TEST local imports $2 '(easy)'
-       ./testgo build -o hello "testdata/$local/easy.go" || ok=false
-       ./hello >hello.out || ok=false
-       if ! grep -q '^easysub\.Hello' hello.out; then
-               echo "testdata/$local/easy.go did not generate expected output"
-               cat hello.out
-               ok=false
-       fi
-       
-       TEST local imports $2 '(easysub)'
-       ./testgo build -o hello "testdata/$local/easysub/main.go" || ok=false
-       ./hello >hello.out || ok=false
-       if ! grep -q '^easysub\.Hello' hello.out; then
-               echo "testdata/$local/easysub/main.go did not generate expected output"
-               cat hello.out
-               ok=false
-       fi
-       
-       TEST local imports $2 '(hard)'
-       ./testgo build -o hello "testdata/$local/hard.go" || ok=false
-       ./hello >hello.out || ok=false
-       if ! grep -q '^sub\.Hello' hello.out || ! grep -q '^subsub\.Hello' hello.out ; then
-               echo "testdata/$local/hard.go did not generate expected output"
-               cat hello.out
-               ok=false
-       fi
-       
-       rm -f hello.out hello
-       
-       # Test that go install x.go fails.
-       TEST local imports $2 '(go install should fail)'
-       if ./testgo install "testdata/$local/easy.go" >/dev/null 2>&1; then
-               echo "go install testdata/$local/easy.go succeeded"
-               ok=false
-       fi
-}
-
-# Test local imports
-testlocal local ''
-
-# Test local imports again, with bad characters in the directory name.
-bad='#$%:, &()*;<=>?\^{}'
-rm -rf "testdata/$bad"
-cp -R testdata/local "testdata/$bad"
-testlocal "$bad" 'with bad characters in path'
-rm -rf "testdata/$bad"
-
-TEST 'internal packages in $GOROOT are respected'
-if ./testgo build -v ./testdata/testinternal >testdata/std.out 2>&1; then
-       echo "go build ./testdata/testinternal succeeded incorrectly"
-       ok=false
-elif ! grep 'use of internal package not allowed' testdata/std.out >/dev/null; then
-       echo "wrong error message for testdata/testinternal"
-       cat std.out
-       ok=false
-fi
-
-TEST 'internal packages outside $GOROOT are respected (as of Go 1.5)'
-if ./testgo build -v ./testdata/testinternal2 >testdata/std.out 2>&1; then
-       echo "go build ./testdata/testinternal2 succeeded incorrectly"
-       ok=false
-elif ! grep 'use of internal package not allowed' testdata/std.out >/dev/null; then
-       echo "wrong error message for testdata/testinternal2"
-       cat std.out
-       ok=false
-fi
-
-# Test that 'go get -u' reports moved packages.
-testmove() {
-       vcs=$1
-       url=$2
-       base=$3
-       config=$4
-
-       TEST go get -u notices $vcs package that moved
-       d=$(mktemp -d -t testgoXXX)
-       mkdir -p $d/src
-       if ! GOPATH=$d ./testgo get -d $url; then
-               echo 'go get -d $url failed'
-               ok=false
-       elif ! GOPATH=$d ./testgo get -d -u $url; then
-               echo 'go get -d -u $url failed'
-               ok=false
-       else
-               set +e
-               case "$vcs" in
-               svn)
-                       # SVN doesn't believe in text files so we can't just edit the config.
-                       # Check out a different repo into the wrong place.
-                       rm -rf $d/src/code.google.com/p/rsc-svn
-                       GOPATH=$d ./testgo get -d -u code.google.com/p/rsc-svn2/trunk
-                       mv $d/src/code.google.com/p/rsc-svn2 $d/src/code.google.com/p/rsc-svn
-                       ;;
-               *)
-                       echo '1,$s;'"$base"';'"$base"'XXX;
-w
-q' | ed $d/src/$config >/dev/null 2>&1
-               esac
-               set -e
-
-               if GOPATH=$d ./testgo get -d -u $url 2>$d/err; then
-                       echo "go get -d -u $url succeeded with wrong remote repo"
-                       cat $d/err
-                       ok=false
-               elif ! grep 'is a custom import path for' $d/err >/dev/null; then
-                       echo "go get -d -u $url failed for wrong reason"
-                       cat $d/err
-                       ok=false
-               fi
-               
-               if GOPATH=$d ./testgo get -d -f -u $url 2>$d/err; then
-                       echo "go get -d -u $url succeeded with wrong remote repo"
-                       cat $d/err
-                       ok=false
-               elif ! egrep -i 'validating server certificate|not found' $d/err >/dev/null; then
-                       echo "go get -d -f -u $url failed for wrong reason"
-                       cat $d/err
-                       ok=false
-               fi
-       fi
-       rm -rf $d
-}
-
-testmove git rsc.io/pdf pdf rsc.io/pdf/.git/config
-
-# TODO(rsc): Set up a test case on bitbucket for hg.
-# testmove hg rsc.io/x86/x86asm x86 rsc.io/x86/.hg/hgrc
-
-# TODO(rsc): Set up a test case on SourceForge (?) for svn.
-# testmove svn code.google.com/p/rsc-svn/trunk - -
-
-export GOPATH=$(pwd)/testdata/importcom
-TEST 'import comment - match'
-if ! ./testgo build ./testdata/importcom/works.go; then
-       echo 'go build ./testdata/importcom/works.go failed'
-       ok=false
-fi
-TEST 'import comment - mismatch'
-if ./testgo build ./testdata/importcom/wrongplace.go 2>testdata/err; then
-       echo 'go build ./testdata/importcom/wrongplace.go suceeded'
-       ok=false
-elif ! grep 'wrongplace expects import "my/x"' testdata/err >/dev/null; then
-       echo 'go build did not mention incorrect import:'
-       cat testdata/err
-       ok=false
-fi
-TEST 'import comment - syntax error'
-if ./testgo build ./testdata/importcom/bad.go 2>testdata/err; then
-       echo 'go build ./testdata/importcom/bad.go suceeded'
-       ok=false
-elif ! grep 'cannot parse import comment' testdata/err >/dev/null; then
-       echo 'go build did not mention syntax error:'
-       cat testdata/err
-       ok=false
-fi
-TEST 'import comment - conflict'
-if ./testgo build ./testdata/importcom/conflict.go 2>testdata/err; then
-       echo 'go build ./testdata/importcom/conflict.go suceeded'
-       ok=false
-elif ! grep 'found import comments' testdata/err >/dev/null; then
-       echo 'go build did not mention comment conflict:'
-       cat testdata/err
-       ok=false
-fi
-rm -f ./testdata/err
-unset GOPATH
-
-export GOPATH=$(pwd)/testdata/src
-TEST disallowed C source files
-export GOPATH=$(pwd)/testdata
-if ./testgo build badc 2>testdata/err; then
-       echo 'go build badc succeeded'
-       ok=false
-elif ! grep 'C source files not allowed' testdata/err >/dev/null; then
-       echo 'go test did not say C source files not allowed:'
-       cat testdata/err
-       ok=false
-fi
-rm -f ./testdata/err
-unset GOPATH
-
-TEST error message for syntax error in test go file says FAIL
-export GOPATH=$(pwd)/testdata
-if ./testgo test syntaxerror 2>testdata/err; then
-       echo 'go test syntaxerror succeeded'
-       ok=false
-elif ! grep FAIL testdata/err >/dev/null; then
-       echo 'go test did not say FAIL:'
-       cat testdata/err
-       ok=false
-fi
-rm -f ./testdata/err
-unset GOPATH
-
-TEST wildcards do not look in useless directories
-export GOPATH=$(pwd)/testdata
-if ./testgo list ... >testdata/err 2>&1; then
-       echo "go list ... succeeded"
-       ok=false
-elif ! grep badpkg testdata/err >/dev/null; then
-       echo "go list ... failure does not mention badpkg"
-       cat testdata/err
-       ok=false
-elif ! ./testgo list m... >testdata/err 2>&1; then
-       echo "go list m... failed"
-       ok=false
-fi
-rm -rf ./testdata/err
-unset GOPATH
-
-# Test tests with relative imports.
-TEST relative imports '(go test)'
-if ! ./testgo test ./testdata/testimport; then
-       echo "go test ./testdata/testimport failed"
-       ok=false
-fi
-
-# Test installation with relative imports.
-TEST relative imports '(go test -i)'
-if ! ./testgo test -i ./testdata/testimport; then
-    echo "go test -i ./testdata/testimport failed"
-    ok=false
-fi
-
-# Test tests with relative imports in packages synthesized
-# from Go files named on the command line.
-TEST relative imports in command-line package
-if ! ./testgo test ./testdata/testimport/*.go; then
-       echo "go test ./testdata/testimport/*.go failed"
-       ok=false
-fi
-
-TEST version control error message includes correct directory
-export GOPATH=$(pwd)/testdata/shadow/root1
-if ./testgo get -u foo 2>testdata/err; then
-       echo "go get -u foo succeeded unexpectedly"
-       ok=false
-elif ! grep testdata/shadow/root1/src/foo testdata/err >/dev/null; then
-       echo "go get -u error does not mention shadow/root1/src/foo:"
-       cat testdata/err
-       ok=false
-fi
-unset GOPATH
-
-TEST go install fails with no buildable files
-export GOPATH=$(pwd)/testdata
-export CGO_ENABLED=0
-if ./testgo install cgotest 2>testdata/err; then
-       echo "go install cgotest succeeded unexpectedly"
-elif ! grep 'no buildable Go source files' testdata/err >/dev/null; then
-       echo "go install cgotest did not report 'no buildable Go source files'"
-       cat testdata/err
-       ok=false
-fi
-unset CGO_ENABLED
-unset GOPATH
-
-# Test that without $GOBIN set, binaries get installed
-# into the GOPATH bin directory.
-TEST install into GOPATH
-rm -rf testdata/bin
-if ! GOPATH=$(pwd)/testdata ./testgo install go-cmd-test; then
-       echo "go install go-cmd-test failed"
-       ok=false
-elif ! test -x testdata/bin/go-cmd-test; then
-       echo "go install go-cmd-test did not write to testdata/bin/go-cmd-test"
-       ok=false
-fi
-
-TEST package main_test imports archive not binary
-export GOBIN=$(pwd)/testdata/bin
-mkdir -p $GOBIN
-export GOPATH=$(pwd)/testdata
-touch ./testdata/src/main_test/m.go
-if ! ./testgo test main_test; then
-       echo "go test main_test failed without install"
-       ok=false
-elif ! ./testgo install main_test; then
-       echo "go test main_test failed"
-       ok=false
-elif [ "$(./testgo list -f '{{.Stale}}' main_test)" != false ]; then
-       echo "after go install, main listed as stale"
-       ok=false
-elif ! ./testgo test main_test; then
-       echo "go test main_test failed after install"
-       ok=false
-fi
-rm -rf $GOBIN
-unset GOBIN
-
-# And with $GOBIN set, binaries get installed to $GOBIN.
-TEST install into GOBIN
-if ! GOBIN=$(pwd)/testdata/bin1 GOPATH=$(pwd)/testdata ./testgo install go-cmd-test; then
-       echo "go install go-cmd-test failed"
-       ok=false
-elif ! test -x testdata/bin1/go-cmd-test; then
-       echo "go install go-cmd-test did not write to testdata/bin1/go-cmd-test"
-       ok=false
-fi
-
-# Without $GOBIN set, installing a program outside $GOPATH should fail
-# (there is nowhere to install it).
-TEST install without destination fails
-if ./testgo install testdata/src/go-cmd-test/helloworld.go 2>testdata/err; then
-       echo "go install testdata/src/go-cmd-test/helloworld.go should have failed, did not"
-       ok=false
-elif ! grep 'no install location for .go files listed on command line' testdata/err; then
-       echo "wrong error:"
-       cat testdata/err
-       ok=false
-fi
-rm -f testdata/err
-
-# With $GOBIN set, should install there.
-TEST install to GOBIN '(command-line package)'
-if ! GOBIN=$(pwd)/testdata/bin1 ./testgo install testdata/src/go-cmd-test/helloworld.go; then
-       echo "go install testdata/src/go-cmd-test/helloworld.go failed"
-       ok=false
-elif ! test -x testdata/bin1/helloworld; then
-       echo "go install testdata/src/go-cmd-test/helloworld.go did not write testdata/bin1/helloworld"
-       ok=false
-fi
-
-TEST godoc installs into GOBIN
-d=$(mktemp -d -t testgoXXX)
-export GOPATH=$d
-mkdir $d/gobin
-GOBIN=$d/gobin ./testgo get golang.org/x/tools/cmd/godoc || ok=false
-if [ ! -x $d/gobin/godoc ]; then
-       echo did not install godoc to '$GOBIN'
-       GOBIN=$d/gobin ./testgo list -f 'Target: {{.Target}}' golang.org/x/tools/cmd/godoc || true
-       ok=false
-fi
-
-TEST godoc installs into GOROOT
-GOROOT=$(./testgo env GOROOT)
-rm -f $GOROOT/bin/godoc
-./testgo install golang.org/x/tools/cmd/godoc || ok=false
-if [ ! -x $GOROOT/bin/godoc ]; then
-       echo did not install godoc to '$GOROOT/bin'
-       ./testgo list -f 'Target: {{.Target}}' golang.org/x/tools/cmd/godoc || true
-       ok=false
-fi
-
-TEST cmd/fix installs into tool
-GOOS=$(./testgo env GOOS)
-GOARCH=$(./testgo env GOARCH)
-rm -f $GOROOT/pkg/tool/${GOOS}_${GOARCH}/fix
-./testgo install cmd/fix || ok=false
-if [ ! -x $GOROOT/pkg/tool/${GOOS}_${GOARCH}/fix ]; then
-       echo 'did not install cmd/fix to $GOROOT/pkg/tool'
-       GOBIN=$d/gobin ./testgo list -f 'Target: {{.Target}}' cmd/fix || true
-       ok=false
-fi
-rm -f $GOROOT/pkg/tool/${GOOS}_${GOARCH}/fix
-GOBIN=$d/gobin ./testgo install cmd/fix || ok=false
-if [ ! -x $GOROOT/pkg/tool/${GOOS}_${GOARCH}/fix ]; then
-       echo 'did not install cmd/fix to $GOROOT/pkg/tool with $GOBIN set'
-       GOBIN=$d/gobin ./testgo list -f 'Target: {{.Target}}' cmd/fix || true
-       ok=false
-fi
-
-TEST gopath program installs into GOBIN
-mkdir $d/src/progname
-echo 'package main; func main() {}' >$d/src/progname/p.go
-GOBIN=$d/gobin ./testgo install progname || ok=false
-if [ ! -x $d/gobin/progname ]; then
-       echo 'did not install progname to $GOBIN/progname'
-       ./testgo list -f 'Target: {{.Target}}' cmd/api || true
-       ok=false
-fi
-rm -f $d/gobin/progname $d/bin/progname
-
-TEST gopath program installs into GOPATH/bin
-./testgo install progname || ok=false
-if [ ! -x $d/bin/progname ]; then
-       echo 'did not install progname to $GOPATH/bin/progname'
-       ./testgo list -f 'Target: {{.Target}}' progname || true
-       ok=false
-fi
-
-unset GOPATH
-rm -rf $d
-
-# Reject relative paths in GOPATH.
-TEST reject relative paths in GOPATH '(command-line package)'
-if GOPATH=. ./testgo build testdata/src/go-cmd-test/helloworld.go; then
-    echo 'GOPATH="." go build should have failed, did not'
-    ok=false
-fi
-
-TEST reject relative paths in GOPATH 
-if GOPATH=:$(pwd)/testdata:. ./testgo build go-cmd-test; then
-    echo 'GOPATH=":$(pwd)/testdata:." go build should have failed, did not'
-    ok=false
-fi
-
-# issue 4104
-TEST go test with package listed multiple times
-if [ $(./testgo test fmt fmt fmt fmt fmt | wc -l) -ne 1 ] ; then
-    echo 'go test fmt fmt fmt fmt fmt tested the same package multiple times'
-    ok=false
-fi
-
-TEST go list has a consistent order
-./testgo list std > test_std.list || ok=false
-if ! ./testgo list std | cmp -s test_std.list - ; then
-       echo "go list std ordering is inconsistent"
-       ok=false
-fi
-rm -f test_std.list
-
-TEST go list std does not include commands
-if ./testgo list std | grep cmd/; then
-       echo "go list std shows commands"
-       ok=false
-fi
-
-TEST go list cmd only shows commands
-if ./testgo list cmd | grep -v 'cmd/'; then
-       echo "go list cmd shows non-commands"
-       ok=false
-fi
-
-# issue 4096. Validate the output of unsuccessful go install foo/quxx 
-TEST unsuccessful go install should mention missing package
-if [ $(./testgo install 'foo/quxx' 2>&1 | grep -c 'cannot find package "foo/quxx" in any of') -ne 1 ] ; then
-       echo 'go install foo/quxx expected error: .*cannot find package "foo/quxx" in any of'
-       ok=false
-fi 
-# test GOROOT search failure is reported
-TEST GOROOT search failure reporting
-if [ $(./testgo install 'foo/quxx' 2>&1 | egrep -c 'foo/quxx \(from \$GOROOT\)$') -ne 1 ] ; then
-        echo 'go install foo/quxx expected error: .*foo/quxx (from $GOROOT)'
-        ok=false
-fi
-# test multiple GOPATH entries are reported separately
-TEST multiple GOPATH entries reported separately
-if [ $(GOPATH=$(pwd)/testdata/a:$(pwd)/testdata/b ./testgo install 'foo/quxx' 2>&1 | egrep -c 'testdata/./src/foo/quxx') -ne 2 ] ; then
-        echo 'go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)\n.*testdata/b/src/foo/quxx'
-        ok=false
-fi
-# test (from $GOPATH) annotation is reported for the first GOPATH entry
-TEST mention GOPATH in first GOPATH entry
-if [ $(GOPATH=$(pwd)/testdata/a:$(pwd)/testdata/b ./testgo install 'foo/quxx' 2>&1 | egrep -c 'testdata/a/src/foo/quxx \(from \$GOPATH\)$') -ne 1 ] ; then
-        echo 'go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)'
-        ok=false
-fi
-# but not on the second
-TEST but not the second entry
-if [ $(GOPATH=$(pwd)/testdata/a:$(pwd)/testdata/b ./testgo install 'foo/quxx' 2>&1 | egrep -c 'testdata/b/src/foo/quxx$') -ne 1 ] ; then
-        echo 'go install foo/quxx expected error: .*testdata/b/src/foo/quxx'
-        ok=false
-fi
-# test missing GOPATH is reported
-TEST missing GOPATH is reported
-if [ $(GOPATH= ./testgo install 'foo/quxx' 2>&1 | egrep -c '\(\$GOPATH not set\)$') -ne 1 ] ; then
-        echo 'go install foo/quxx expected error: ($GOPATH not set)'
-        ok=false
-fi
-
-# issue 4186. go get cannot be used to download packages to $GOROOT
-# Test that without GOPATH set, go get should fail
-TEST without GOPATH, go get fails
-d=$(mktemp -d -t testgoXXX)
-mkdir -p $d/src
-if GOPATH= GOROOT=$d ./testgo get -d golang.org/x/codereview/cmd/hgpatch ; then 
-       echo 'go get golang.org/x/codereview/cmd/hgpatch should not succeed with $GOPATH unset'
-       ok=false
-fi     
-rm -rf $d
-
-# Test that with GOPATH=$GOROOT, go get should fail
-TEST with GOPATH=GOROOT, go get fails
-d=$(mktemp -d -t testgoXXX)
-mkdir -p $d/src
-if GOPATH=$d GOROOT=$d ./testgo get -d golang.org/x/codereview/cmd/hgpatch ; then
-        echo 'go get golang.org/x/codereview/cmd/hgpatch should not succeed with GOPATH=$GOROOT'
-        ok=false
-fi
-rm -rf $d
-
-TEST ldflags arguments with spaces '(issue 3941)'
-d=$(mktemp -d -t testgoXXX)
-cat >$d/main.go<<EOF
-package main
-var extern string
-func main() {
-       println(extern)
-}
-EOF
-./testgo run -ldflags '-X main.extern "hello world"' $d/main.go 2>hello.out || ok=false
-if ! grep -q '^hello world' hello.out; then
-       echo "ldflags -X main.extern 'hello world' failed. Output:"
-       cat hello.out
-       ok=false
-fi
-rm -rf $d hello.out
-
-TEST go test -cpuprofile leaves binary behind
-./testgo test -cpuprofile strings.prof strings || ok=false
-if [ ! -x strings.test ]; then
-       echo "go test -cpuprofile did not create strings.test"
-       ok=false
-fi
-rm -f strings.prof strings.test
-
-TEST go test -cpuprofile -o controls binary location
-./testgo test -cpuprofile strings.prof -o mystrings.test strings || ok=false
-if [ ! -x mystrings.test ]; then
-       echo "go test -cpuprofile -o mystrings.test did not create mystrings.test"
-       ok=false
-fi
-rm -f strings.prof mystrings.test
-
-TEST go test -c -o controls binary location
-./testgo test -c -o mystrings.test strings || ok=false
-if [ ! -x mystrings.test ]; then
-       echo "go test -c -o mystrings.test did not create mystrings.test"
-       ok=false
-fi
-rm -f mystrings.test
-
-TEST go test -o writes binary
-./testgo test -o mystrings.test strings || ok=false
-if [ ! -x mystrings.test ]; then
-       echo "go test -o mystrings.test did not create mystrings.test"
-       ok=false
-fi
-rm -f mystrings.test
-
-TEST symlinks do not confuse go list '(issue 4568)'
-old=$(pwd)
-tmp=$(cd /tmp && pwd -P)
-d=$(TMPDIR=$tmp mktemp -d -t testgoXXX)
-mkdir -p $d/src
-(
-       ln -s $d $d/src/dir1
-       cd $d/src
-       echo package p >dir1/p.go
-       export GOPATH=$d
-       if [ "$($old/testgo list -f '{{.Root}}' dir1)" != "$d" ]; then
-               echo Confused by symlinks.
-               echo "Package in current directory $(pwd) should have Root $d"
-               env|grep WD
-               $old/testgo list -json . dir1
-               touch $d/failed
-       fi              
-)
-if [ -f $d/failed ]; then
-       ok=false
-fi
-rm -rf $d
-
-TEST 'install with tags (issue 4515)'
-d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
-mkdir -p $d/src/example/a $d/src/example/b $d/bin
-cat >$d/src/example/a/main.go <<EOF
-package main
-func main() {}
-EOF
-cat >$d/src/example/b/main.go <<EOF
-// +build mytag
-
-package main
-func main() {}
-EOF
-GOPATH=$d ./testgo install -tags mytag example/a example/b || ok=false
-if [ ! -x $d/bin/a -o ! -x $d/bin/b ]; then
-       echo go install example/a example/b did not install binaries
-       ok=false
-fi
-rm -f $d/bin/*
-GOPATH=$d ./testgo install -tags mytag example/... || ok=false
-if [ ! -x $d/bin/a -o ! -x $d/bin/b ]; then
-       echo go install example/... did not install binaries
-       ok=false
-fi
-rm -f $d/bin/*go
-export GOPATH=$d
-if [ "$(./testgo list -tags mytag example/b...)" != "example/b" ]; then
-       echo go list example/b did not find example/b
-       ok=false
-fi
-unset GOPATH
-rm -rf $d
-
-TEST case collisions '(issue 4773)'
-d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
-export GOPATH=$d
-mkdir -p $d/src/example/{a/pkg,a/Pkg,b}
-cat >$d/src/example/a/a.go <<EOF
-package p
-import (
-       _ "example/a/pkg"
-       _ "example/a/Pkg"
-)
-EOF
-cat >$d/src/example/a/pkg/pkg.go <<EOF
-package pkg
-EOF
-cat >$d/src/example/a/Pkg/pkg.go <<EOF
-package pkg
-EOF
-if ./testgo list example/a 2>$d/out; then
-       echo go list example/a should have failed, did not.
-       ok=false
-elif ! grep "case-insensitive import collision" $d/out >/dev/null; then
-       echo go list example/a did not report import collision.
-       ok=false
-fi
-cat >$d/src/example/b/file.go <<EOF
-package b
-EOF
-cat >$d/src/example/b/FILE.go <<EOF
-package b
-EOF
-if [ $(ls $d/src/example/b | wc -l) = 2 ]; then
-       # case-sensitive file system, let directory read find both files
-       args="example/b"
-else
-       # case-insensitive file system, list files explicitly on command line.
-       args="$d/src/example/b/file.go $d/src/example/b/FILE.go"
-fi
-if ./testgo list $args 2>$d/out; then
-       echo go list example/b should have failed, did not.
-       ok=false
-elif ! grep "case-insensitive file name collision" $d/out >/dev/null; then
-       echo go list example/b did not report file name collision.
-       ok=false
-fi
-
-TEST go get -t "code.google.com/p/go-get-issue-8181/{a,b}"
-d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
-export GOPATH=$d
-if ./testgo get -t code.google.com/p/go-get-issue-8181/{a,b}; then
-       ./testgo list ... | grep go.tools/godoc > /dev/null || ok=false
-else
-       ok=false
-fi
-unset GOPATH
-rm -rf $d
-
-TEST shadowing logic
-export GOPATH=$(pwd)/testdata/shadow/root1:$(pwd)/testdata/shadow/root2
-
-# The math in root1 is not "math" because the standard math is.
-set +e
-cdir=$(./testgo list -f '({{.ImportPath}}) ({{.ConflictDir}})' ./testdata/shadow/root1/src/math)
-set -e
-if [ "$cdir" != "(_$(pwd)/testdata/shadow/root1/src/math) ($GOROOT/src/math)" ]; then
-       echo shadowed math is not shadowed: "$cdir"
-       ok=false
-fi
-
-# The foo in root1 is "foo".
-set +e
-cdir=$(./testgo list -f '({{.ImportPath}}) ({{.ConflictDir}})' ./testdata/shadow/root1/src/foo)
-set -e
-if [ "$cdir" != "(foo) ()" ]; then
-       echo unshadowed foo is shadowed: "$cdir"
-       ok=false
-fi
-
-# The foo in root2 is not "foo" because the foo in root1 got there first.
-set +e
-cdir=$(./testgo list -f '({{.ImportPath}}) ({{.ConflictDir}})' ./testdata/shadow/root2/src/foo)
-set -e
-if [ "$cdir" != "(_$(pwd)/testdata/shadow/root2/src/foo) ($(pwd)/testdata/shadow/root1/src/foo)" ]; then
-       echo shadowed foo is not shadowed: "$cdir"
-       ok=false
-fi
-
-# The error for go install should mention the conflicting directory.
-set +e
-err=$(./testgo install ./testdata/shadow/root2/src/foo 2>&1)
-set -e
-if [ "$err" != "go install: no install location for $(pwd)/testdata/shadow/root2/src/foo: hidden by $(pwd)/testdata/shadow/root1/src/foo" ]; then
-       echo wrong shadowed install error: "$err"
-       ok=false
-fi
-
-# Only succeeds if source order is preserved.
-TEST source file name order preserved
-./testgo test testdata/example[12]_test.go || ok=false
-
-# Check that coverage analysis works at all.
-# Don't worry about the exact numbers but require not 0.0%.
-checkcoverage() {
-       if grep '[^0-9]0\.0%' testdata/cover.txt >/dev/null; then
-               echo 'some coverage results are 0.0%'
-               ok=false
-       fi
-       cat testdata/cover.txt
-       rm -f testdata/cover.txt
-}
-       
-TEST coverage runs
-./testgo test -short -coverpkg=strings strings regexp >testdata/cover.txt 2>&1 || ok=false
-./testgo test -short -cover strings math regexp >>testdata/cover.txt 2>&1 || ok=false
-checkcoverage
-
-# Check that coverage analysis uses set mode.
-TEST coverage uses set mode
-if ./testgo test -short -cover encoding/binary -coverprofile=testdata/cover.out >testdata/cover.txt 2>&1; then
-       if ! grep -q 'mode: set' testdata/cover.out; then
-               ok=false
-       fi
-       checkcoverage
-else
-       ok=false
-fi
-rm -f testdata/cover.out testdata/cover.txt
-
-TEST coverage uses atomic mode for -race.
-if ./testgo test -short -race -cover encoding/binary -coverprofile=testdata/cover.out >testdata/cover.txt 2>&1; then
-       if ! grep -q 'mode: atomic' testdata/cover.out; then
-               ok=false
-       fi
-       checkcoverage
-else
-       ok=false
-fi
-rm -f testdata/cover.out
-
-TEST coverage uses actual setting to override even for -race.
-if ./testgo test -short -race -cover encoding/binary -covermode=count -coverprofile=testdata/cover.out >testdata/cover.txt 2>&1; then
-       if ! grep -q 'mode: count' testdata/cover.out; then
-               ok=false
-       fi
-       checkcoverage
-else
-       ok=false
-fi
-rm -f testdata/cover.out
-
-TEST coverage with cgo
-d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
-./testgo test -short -cover ./testdata/cgocover >testdata/cover.txt 2>&1 || ok=false
-checkcoverage
-
-TEST cgo depends on syscall
-rm -rf $GOROOT/pkg/*_race
-d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
-export GOPATH=$d
-mkdir -p $d/src/foo
-echo '
-package foo
-//#include <stdio.h>
-import "C"
-' >$d/src/foo/foo.go
-./testgo build -race foo || ok=false
-rm -rf $d
-unset GOPATH
-
-TEST cgo shows full path names
-d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
-export GOPATH=$d
-mkdir -p $d/src/x/y/dirname
-echo '
-package foo
-import "C"
-func f() {
-' >$d/src/x/y/dirname/foo.go
-if ./testgo build x/y/dirname >$d/err 2>&1; then
-       echo build succeeded unexpectedly.
-       ok=false
-elif ! grep x/y/dirname $d/err >/dev/null; then
-       echo error did not use full path.
-       cat $d/err
-       ok=false
-fi
-rm -rf $d
-unset GOPATH
-
-TEST 'cgo handles -Wl,$ORIGIN'
-d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
-export GOPATH=$d
-mkdir -p $d/src/origin
-echo '
-package origin
-// #cgo !darwin LDFLAGS: -Wl,-rpath -Wl,$ORIGIN
-// void f(void) {}
-import "C"
-
-func f() { C.f() }
-' >$d/src/origin/origin.go
-if ! ./testgo build origin; then
-       echo build failed
-       ok=false
-fi
-rm -rf $d
-unset GOPATH
-
-TEST 'Issue 6480: "go test -c -test.bench=XXX fmt" should not hang'
-if ! ./testgo test -c -test.bench=XXX fmt; then
-       echo build test failed
-       ok=false
-fi
-rm -f fmt.test
-
-if which gccgo >/dev/null; then
-       TEST 'Issue 7573: cmd/cgo: undefined reference when linking a C-library using gccgo'
-       d=$(mktemp -d -t testgoXXX)
-       export GOPATH=$d
-       mkdir -p $d/src/cgoref
-       ldflags="-L alibpath -lalib"
-       echo "
-       package main
-       // #cgo LDFLAGS: $ldflags
-       // void f(void) {}
-       import \"C\"
-       
-       func main() { C.f() }
-       " >$d/src/cgoref/cgoref.go
-       go_cmds="$(./testgo build -n -compiler gccgo cgoref 2>&1 1>/dev/null)"
-       ldflags_count="$(echo "$go_cmds" | egrep -c "^gccgo.*$(echo $ldflags | sed -e 's/-/\\-/g')" || true)"
-       if [ "$ldflags_count" -lt 1 ]; then
-               echo "No Go-inline "#cgo LDFLAGS:" (\"$ldflags\") passed to gccgo linking stage."
-               ok=false
-       fi
-       rm -rf $d
-       unset ldflags_count
-       unset go_cmds
-       unset ldflags
-       unset GOPATH
-fi
-
-TEST list template can use context function
-if ! ./testgo list -f "GOARCH: {{context.GOARCH}}"; then 
-       echo unable to use context in list template
-       ok=false
-fi
-
-TEST 'Issue 7108: cmd/go: "go test" should fail if package does not build'
-export GOPATH=$(pwd)/testdata
-if ./testgo test notest >/dev/null 2>&1; then
-       echo 'go test notest succeeded, but should fail'
-       ok=false
-fi
-unset GOPATH
-
-TEST 'Issue 6844: cmd/go: go test -a foo does not rebuild regexp'
-if ! ./testgo test -x -a -c testdata/dep_test.go 2>deplist; then
-       echo "go test -x -a -c testdata/dep_test.go failed"
-       ok=false
-elif ! grep -q regexp deplist; then
-       echo "go test -x -a -c testdata/dep_test.go did not rebuild regexp"
-       ok=false
-fi
-rm -f deplist
-rm -f deps.test
-
-TEST list template can use context function
-if ! ./testgo list -f "GOARCH: {{context.GOARCH}}"; then 
-       echo unable to use context in list template
-       ok=false
-fi
-
-TEST build -i installs dependencies
-d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
-export GOPATH=$d
-mkdir -p $d/src/x/y/foo $d/src/x/y/bar
-echo '
-package foo
-func F() {}
-' >$d/src/x/y/foo/foo.go
-checkbar() {
-       desc="$1"
-       sleep 1
-       touch $d/src/x/y/foo/foo.go
-       if ! ./testgo build -v -i x/y/bar &> $d/err; then
-               echo build -i "$1" failed
-               cat $d/err
-               ok=false
-       elif ! grep x/y/foo $d/err >/dev/null; then
-               echo first build -i "$1" did not build x/y/foo
-               cat $d/err
-               ok=false
-       fi
-       if ! ./testgo build -v -i x/y/bar &> $d/err; then
-               echo second build -i "$1" failed
-               cat $d/err
-               ok=false
-       elif grep x/y/foo $d/err >/dev/null; then
-               echo second build -i "$1" built x/y/foo
-               cat $d/err
-               ok=false
-       fi
-}
-
-echo '
-package bar
-import "x/y/foo"
-func F() { foo.F() }
-' >$d/src/x/y/bar/bar.go
-checkbar pkg
-
-TEST build -i installs dependencies for command
-echo '
-package main
-import "x/y/foo"
-func main() { foo.F() }
-' >$d/src/x/y/bar/bar.go
-checkbar cmd
-
-rm -rf $d bar
-unset GOPATH
-
-TEST 'go build in test-only directory fails with a good error'
-if ./testgo build ./testdata/testonly 2>testdata/err.out; then
-       echo "go build ./testdata/testonly succeeded, should have failed"
-       ok=false
-elif ! grep 'no buildable Go' testdata/err.out >/dev/null; then
-       echo "go build ./testdata/testonly produced unexpected error:"
-       cat testdata/err.out
-       ok=false
-fi
-rm -f testdata/err.out
-
-TEST 'go test detects test-only import cycles'
-export GOPATH=$(pwd)/testdata
-if ./testgo test -c testcycle/p3 2>testdata/err.out; then
-       echo "go test testcycle/p3 succeeded, should have failed"
-       ok=false
-elif ! grep 'import cycle not allowed in test' testdata/err.out >/dev/null; then
-       echo "go test testcycle/p3 produced unexpected error:"
-       cat testdata/err.out
-       ok=false
-fi
-rm -f testdata/err.out
-unset GOPATH
-
-TEST 'go test foo_test.go works'
-if ! ./testgo test testdata/standalone_test.go; then
-       echo "go test testdata/standalone_test.go failed"
-       ok=false
-fi
-
-TEST 'go test xtestonly works'
-export GOPATH=$(pwd)/testdata
-./testgo clean -i xtestonly || ok=false
-if ! ./testgo test xtestonly >/dev/null; then
-       echo "go test xtestonly failed"
-       ok=false
-fi
-unset GOPATH
-
-TEST 'go test builds an xtest containing only non-runnable examples'
-if ! ./testgo test -v ./testdata/norunexample > testdata/std.out; then
-       echo "go test ./testdata/norunexample failed"
-       ok=false
-elif ! grep 'File with non-runnable example was built.' testdata/std.out > /dev/null; then
-       echo "file with non-runnable example was not built"
-       ok=false
-fi
-rm -f testdata/std.out
-
-TEST 'go generate handles simple command'
-if ! ./testgo generate ./testdata/generate/test1.go > testdata/std.out; then
-       echo "go generate ./testdata/generate/test1.go failed to run"
-       ok=false
-elif ! grep 'Success' testdata/std.out > /dev/null; then
-       echo "go generate ./testdata/generate/test1.go generated wrong output"
-       ok=false
-fi
-
-TEST 'go generate handles command alias'
-if ! ./testgo generate ./testdata/generate/test2.go > testdata/std.out; then
-       echo "go generate ./testdata/generate/test2.go failed to run"
-       ok=false
-elif ! grep 'Now is the time for all good men' testdata/std.out > /dev/null; then
-       echo "go generate ./testdata/generate/test2.go generated wrong output"
-       ok=false
-fi
-
-TEST 'go generate variable substitution'
-if ! ./testgo generate ./testdata/generate/test3.go > testdata/std.out; then
-       echo "go generate ./testdata/generate/test3.go failed to run"
-       ok=false
-elif ! grep "$GOARCH test3.go:7 pabc xyzp/test3.go/123" testdata/std.out > /dev/null; then
-       echo "go generate ./testdata/generate/test3.go generated wrong output"
-       ok=false
-fi
-
-TEST 'go generate run flag'
-if ! ./testgo generate -run y.s ./testdata/generate/test4.go > testdata/std.out; then
-       echo "go test -run yes ./testdata/generate/test4.go failed to run"
-       ok=false
-elif ! grep "yes" testdata/std.out > /dev/null; then
-       echo "go generate -run yes ./testdata/generate/test4.go did not select yes"
-       ok=false
-elif grep "no" testdata/std.out > /dev/null; then
-       echo "go generate -run yes ./testdata/generate/test4.go selected no"
-       ok=false
-fi
-
-TEST go get works with vanity wildcards
-d=$(mktemp -d -t testgoXXX)
-export GOPATH=$d
-if ! ./testgo get -u rsc.io/pdf/...; then
-       ok=false
-elif [ ! -x $d/bin/pdfpasswd ]; then
-       echo did not build rsc.io/pdf/pdfpasswd
-       ok=false
-fi
-unset GOPATH
-rm -rf $d
-
-TEST go vet with external tests
-d=$(mktemp -d -t testgoXXX)
-export GOPATH=$d
-./testgo get golang.org/x/tools/cmd/vet
-export GOPATH=$(pwd)/testdata
-if ./testgo vet vetpkg >$d/err 2>&1; then
-       echo "go vet vetpkg passes incorrectly"
-       ok=false
-elif ! grep -q 'missing argument for Printf' $d/err; then
-       echo "go vet vetpkg did not find missing argument for Printf"
-       cat $d/err
-       ok=false
-fi
-unset GOPATH
-rm -rf $d
-
-TEST go vet with -tags
-d=$(mktemp -d -t testgoXXX)
-export GOPATH=$d
-./testgo get golang.org/x/tools/cmd/vet
-export GOPATH=$(pwd)/testdata
-if ./testgo vet -tags tagtest vetpkg >$d/err 2>&1; then
-       echo "go vet vetpkg passes incorrectly"
-       ok=false
-elif ! grep -q 'c\.go.*wrong number of args for format' $d/err; then
-       echo "go vet vetpkg did not scan tagged file"
-       cat $d/err
-       ok=false
-fi
-unset GOPATH
-rm -rf $d
-
-TEST go get ./rsc.io/toolstash '(golang.org/issue/9767)'
-d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
-export GOPATH=$d
-export testgo=$(pwd)/testgo
-mkdir -p $GOPATH/src/rsc.io
-(cd $GOPATH/src/rsc.io && $testgo get ./toolstash) || ok=false
-unset GOPATH
-unset testgo
-rm -rf $d
-
-# clean up
-if $started; then stop; fi
-rm -rf testdata/bin testdata/bin1 testdata/std.out
-rm -f testgo
-
-if $allok; then
-       echo PASS
-else
-       echo FAIL:
-       echo "$testfail"
-       exit 1
-fi