1 // Copyright 2015 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
30 "cmd/go/internal/cache"
32 "cmd/go/internal/robustio"
37 canRun = true // whether we can run go or ./testgo
38 canRace = false // whether we can run the race detector
39 canCgo = false // whether we can use cgo
40 canMSan = false // whether we can run the memory sanitizer
42 exeSuffix string // ".exe" on Windows
44 skipExternal = false // skip external tests
47 func tooSlow(t *testing.T) {
49 // In -short mode; skip test, except run it on the {darwin,linux,windows}/amd64 builders.
50 if testenv.Builder() != "" && runtime.GOARCH == "amd64" && (runtime.GOOS == "linux" || runtime.GOOS == "darwin" || runtime.GOOS == "windows") {
53 t.Skip("skipping test in -short mode")
62 switch runtime.GOARCH {
67 switch runtime.GOARCH {
69 // many linux/arm machines are too slow to run
70 // the full set of external tests.
72 case "mips", "mipsle", "mips64", "mips64le":
75 if testenv.Builder() != "" {
76 // On the builders, skip the cmd/go
77 // tests. They're too slow and already
78 // covered by other ports. There's
79 // nothing os/arch specific in the
85 switch runtime.GOARCH {
87 // many freebsd/arm machines are too slow to run
88 // the full set of external tests.
93 switch runtime.GOARCH {
95 // many plan9/arm machines are too slow to run
96 // the full set of external tests.
104 // testGOROOT is the GOROOT to use when running testgo, a cmd/go binary
105 // build from this process's current GOROOT, but run from a different
107 var testGOROOT string
110 var testGOCACHE string
113 var testTmpDir string
116 // The TestMain function creates a go command for testing purposes and
117 // deletes it after the tests have been run.
118 func TestMain(m *testing.M) {
119 // $GO_GCFLAGS a compiler debug flag known to cmd/dist, make.bash, etc.
120 // It is not a standard go command flag; use os.Getenv, not cfg.Getenv.
121 if os.Getenv("GO_GCFLAGS") != "" {
122 fmt.Fprintf(os.Stderr, "testing: warning: no tests to run\n") // magic string for cmd/go
123 fmt.Printf("cmd/go test is not compatible with $GO_GCFLAGS being set\n")
130 if *proxyAddr != "" {
135 // Run with a temporary TMPDIR to check that the tests don't
136 // leave anything behind.
137 topTmpdir, err := ioutil.TempDir("", "cmd-go-test-")
142 defer removeAll(topTmpdir)
144 os.Setenv(tempEnvName(), topTmpdir)
146 dir, err := ioutil.TempDir(topTmpdir, "tmpdir")
152 defer removeAll(testTmpDir)
155 testGOCACHE = cache.DefaultDir()
157 testBin = filepath.Join(testTmpDir, "testbin")
158 if err := os.Mkdir(testBin, 0777); err != nil {
161 testGo = filepath.Join(testBin, "go"+exeSuffix)
162 args := []string{"build", "-tags", "testgo", "-o", testGo}
164 args = append(args, "-race")
166 gotool, err := testenv.GoTool()
168 fmt.Fprintln(os.Stderr, err)
172 goEnv := func(name string) string {
173 out, err := exec.Command(gotool, "env", name).CombinedOutput()
175 fmt.Fprintf(os.Stderr, "go env %s: %v\n%s", name, err, out)
178 return strings.TrimSpace(string(out))
180 testGOROOT = goEnv("GOROOT")
181 os.Setenv("TESTGO_GOROOT", testGOROOT)
182 // Ensure that GOROOT is set explicitly.
183 // Otherwise, if the toolchain was built with GOROOT_FINAL set but has not
184 // yet been moved to its final location, programs that invoke runtime.GOROOT
185 // may accidentally use the wrong path.
186 os.Setenv("GOROOT", testGOROOT)
188 // The whole GOROOT/pkg tree was installed using the GOHOSTOS/GOHOSTARCH
189 // toolchain (installed in GOROOT/pkg/tool/GOHOSTOS_GOHOSTARCH).
190 // The testgo.exe we are about to create will be built for GOOS/GOARCH,
191 // which means it will use the GOOS/GOARCH toolchain
192 // (installed in GOROOT/pkg/tool/GOOS_GOARCH).
193 // If these are not the same toolchain, then the entire standard library
194 // will look out of date (the compilers in those two different tool directories
195 // are built for different architectures and have different build IDs),
196 // which will cause many tests to do unnecessary rebuilds and some
197 // tests to attempt to overwrite the installed standard library.
198 // Bail out entirely in this case.
199 hostGOOS := goEnv("GOHOSTOS")
200 hostGOARCH := goEnv("GOHOSTARCH")
201 if hostGOOS != runtime.GOOS || hostGOARCH != runtime.GOARCH {
202 fmt.Fprintf(os.Stderr, "testing: warning: no tests to run\n") // magic string for cmd/go
203 fmt.Printf("cmd/go test is not compatible with GOOS/GOARCH != GOHOSTOS/GOHOSTARCH (%s/%s != %s/%s)\n", runtime.GOOS, runtime.GOARCH, hostGOOS, hostGOARCH)
208 buildCmd := exec.Command(gotool, args...)
209 buildCmd.Env = append(os.Environ(), "GOFLAGS=-mod=vendor")
210 out, err := buildCmd.CombinedOutput()
212 fmt.Fprintf(os.Stderr, "building testgo failed: %v\n%s", err, out)
216 out, err = exec.Command(gotool, "env", "CC").CombinedOutput()
218 fmt.Fprintf(os.Stderr, "could not find testing CC: %v\n%s", err, out)
221 testCC = strings.TrimSpace(string(out))
223 cmd := exec.Command(testGo, "env", "CGO_ENABLED")
224 cmd.Stderr = new(strings.Builder)
225 if out, err := cmd.Output(); err != nil {
226 fmt.Fprintf(os.Stderr, "running testgo failed: %v\n%s", err, cmd.Stderr)
229 canCgo, err = strconv.ParseBool(strings.TrimSpace(string(out)))
231 fmt.Fprintf(os.Stderr, "can't parse go env CGO_ENABLED output: %v\n", strings.TrimSpace(string(out)))
235 out, err = exec.Command(gotool, "env", "GOCACHE").CombinedOutput()
237 fmt.Fprintf(os.Stderr, "could not find testing GOCACHE: %v\n%s", err, out)
240 testGOCACHE = strings.TrimSpace(string(out))
242 canMSan = canCgo && sys.MSanSupported(runtime.GOOS, runtime.GOARCH)
243 canRace = canCgo && sys.RaceDetectorSupported(runtime.GOOS, runtime.GOARCH)
244 // The race detector doesn't work on Alpine Linux:
245 // golang.org/issue/14481
246 // gccgo does not support the race detector.
247 if isAlpineLinux() || runtime.Compiler == "gccgo" {
251 // Don't let these environment variables confuse the test.
252 os.Setenv("GOENV", "off")
254 os.Unsetenv("GOPATH")
255 os.Unsetenv("GIT_ALLOW_PROTOCOL")
256 os.Setenv("HOME", "/test-go-home-does-not-exist")
257 // On some systems the default C compiler is ccache.
258 // Setting HOME to a non-existent directory will break
259 // those systems. Disable ccache and use real compiler. Issue 17668.
260 os.Setenv("CCACHE_DISABLE", "1")
261 if cfg.Getenv("GOCACHE") == "" {
262 os.Setenv("GOCACHE", testGOCACHE) // because $HOME is gone
267 removeAll(testTmpDir) // os.Exit won't run defer
271 // There shouldn't be anything left in topTmpdir.
272 dirf, err := os.Open(topTmpdir)
276 names, err := dirf.Readdirnames(0)
281 log.Fatalf("unexpected files left in tmpdir: %v", names)
290 func isAlpineLinux() bool {
291 if runtime.GOOS != "linux" {
294 fi, err := os.Lstat("/etc/alpine-release")
295 return err == nil && fi.Mode().IsRegular()
298 // The length of an mtime tick on this system. This is an estimate of
299 // how long we need to sleep to ensure that the mtime of two files is
301 // We used to try to be clever but that didn't always work (see golang.org/issue/12205).
302 var mtimeTick time.Duration = 1 * time.Second
304 // Manage a single run of the testgo binary.
305 type testgoData struct {
312 stdout, stderr bytes.Buffer
313 execDir string // dir for tg.run
316 // skipIfGccgo skips the test if using gccgo.
317 func skipIfGccgo(t *testing.T, msg string) {
318 if runtime.Compiler == "gccgo" {
319 t.Skipf("skipping test not supported on gccgo: %s", msg)
323 // testgo sets up for a test that runs testgo.
324 func testgo(t *testing.T) *testgoData {
326 testenv.MustHaveGoBuild(t)
329 t.Skipf("skipping external tests on %s/%s", runtime.GOOS, runtime.GOARCH)
332 return &testgoData{t: t}
335 // must gives a fatal error if err is not nil.
336 func (tg *testgoData) must(err error) {
343 // check gives a test non-fatal error if err is not nil.
344 func (tg *testgoData) check(err error) {
351 // parallel runs the test in parallel by calling t.Parallel.
352 func (tg *testgoData) parallel() {
355 tg.t.Fatal("internal testsuite error: call to parallel after run")
357 for _, e := range tg.env {
358 if strings.HasPrefix(e, "GOROOT=") || strings.HasPrefix(e, "GOPATH=") || strings.HasPrefix(e, "GOBIN=") {
359 val := e[strings.Index(e, "=")+1:]
360 if strings.HasPrefix(val, "testdata") || strings.HasPrefix(val, "./testdata") {
361 tg.t.Fatalf("internal testsuite error: call to parallel with testdata in environment (%s)", e)
369 // pwd returns the current directory.
370 func (tg *testgoData) pwd() string {
372 wd, err := os.Getwd()
374 tg.t.Fatalf("could not get working directory: %v", err)
379 // sleep sleeps for one tick, where a tick is a conservative estimate
380 // of how long it takes for a file modification to get a different
382 func (tg *testgoData) sleep() {
383 time.Sleep(mtimeTick)
386 // setenv sets an environment variable to use when running the test go
388 func (tg *testgoData) setenv(name, val string) {
390 if tg.inParallel && (name == "GOROOT" || name == "GOPATH" || name == "GOBIN") && (strings.HasPrefix(val, "testdata") || strings.HasPrefix(val, "./testdata")) {
391 tg.t.Fatalf("internal testsuite error: call to setenv with testdata (%s=%s) after parallel", name, val)
394 tg.env = append(tg.env, name+"="+val)
397 // unsetenv removes an environment variable.
398 func (tg *testgoData) unsetenv(name string) {
400 tg.env = append([]string(nil), os.Environ()...)
401 tg.env = append(tg.env, "GO111MODULE=off")
403 for i, v := range tg.env {
404 if strings.HasPrefix(v, name+"=") {
405 tg.env = append(tg.env[:i], tg.env[i+1:]...)
411 func (tg *testgoData) goTool() string {
415 // doRun runs the test go command, recording stdout and stderr and
416 // returning exit status.
417 func (tg *testgoData) doRun(args []string) error {
420 panic("testgoData.doRun called but canRun false")
423 for _, arg := range args {
424 if strings.HasPrefix(arg, "testdata") || strings.HasPrefix(arg, "./testdata") {
425 tg.t.Fatal("internal testsuite error: parallel run using testdata")
431 for _, v := range tg.env {
432 if strings.HasPrefix(v, "GOROOT=") {
439 tg.setenv("GOROOT", testGOROOT)
442 tg.t.Logf("running testgo %v", args)
443 cmd := exec.Command(prog, args...)
447 cmd.Stdout = &tg.stdout
448 cmd.Stderr = &tg.stderr
451 if tg.stdout.Len() > 0 {
452 tg.t.Log("standard output:")
453 tg.t.Log(tg.stdout.String())
455 if tg.stderr.Len() > 0 {
456 tg.t.Log("standard error:")
457 tg.t.Log(tg.stderr.String())
463 // run runs the test go command, and expects it to succeed.
464 func (tg *testgoData) run(args ...string) {
466 if status := tg.doRun(args); status != nil {
468 tg.t.Logf("go %v failed unexpectedly in %s: %v", args, wd, status)
473 // runFail runs the test go command, and expects it to fail.
474 func (tg *testgoData) runFail(args ...string) {
476 if status := tg.doRun(args); status == nil {
477 tg.t.Fatal("testgo succeeded unexpectedly")
479 tg.t.Log("testgo failed as expected:", status)
483 // runGit runs a git command, and expects it to succeed.
484 func (tg *testgoData) runGit(dir string, args ...string) {
486 cmd := exec.Command("git", args...)
489 cmd.Stdout = &tg.stdout
490 cmd.Stderr = &tg.stderr
494 if tg.stdout.Len() > 0 {
495 tg.t.Log("git standard output:")
496 tg.t.Log(tg.stdout.String())
498 if tg.stderr.Len() > 0 {
499 tg.t.Log("git standard error:")
500 tg.t.Log(tg.stderr.String())
503 tg.t.Logf("git %v failed unexpectedly: %v", args, status)
508 // getStdout returns standard output of the testgo run as a string.
509 func (tg *testgoData) getStdout() string {
512 tg.t.Fatal("internal testsuite error: stdout called before run")
514 return tg.stdout.String()
517 // getStderr returns standard error of the testgo run as a string.
518 func (tg *testgoData) getStderr() string {
521 tg.t.Fatal("internal testsuite error: stdout called before run")
523 return tg.stderr.String()
526 // doGrepMatch looks for a regular expression in a buffer, and returns
527 // whether it is found. The regular expression is matched against
528 // each line separately, as with the grep command.
529 func (tg *testgoData) doGrepMatch(match string, b *bytes.Buffer) bool {
532 tg.t.Fatal("internal testsuite error: grep called before run")
534 re := regexp.MustCompile(match)
535 for _, ln := range bytes.Split(b.Bytes(), []byte{'\n'}) {
543 // doGrep looks for a regular expression in a buffer and fails if it
544 // is not found. The name argument is the name of the output we are
545 // searching, "output" or "error". The msg argument is logged on
547 func (tg *testgoData) doGrep(match string, b *bytes.Buffer, name, msg string) {
549 if !tg.doGrepMatch(match, b) {
551 tg.t.Logf("pattern %v not found in standard %s", match, name)
556 // grepStdout looks for a regular expression in the test run's
557 // standard output and fails, logging msg, if it is not found.
558 func (tg *testgoData) grepStdout(match, msg string) {
560 tg.doGrep(match, &tg.stdout, "output", msg)
563 // grepStderr looks for a regular expression in the test run's
564 // standard error and fails, logging msg, if it is not found.
565 func (tg *testgoData) grepStderr(match, msg string) {
567 tg.doGrep(match, &tg.stderr, "error", msg)
570 // grepBoth looks for a regular expression in the test run's standard
571 // output or stand error and fails, logging msg, if it is not found.
572 func (tg *testgoData) grepBoth(match, msg string) {
574 if !tg.doGrepMatch(match, &tg.stdout) && !tg.doGrepMatch(match, &tg.stderr) {
576 tg.t.Logf("pattern %v not found in standard output or standard error", match)
581 // doGrepNot looks for a regular expression in a buffer and fails if
582 // it is found. The name and msg arguments are as for doGrep.
583 func (tg *testgoData) doGrepNot(match string, b *bytes.Buffer, name, msg string) {
585 if tg.doGrepMatch(match, b) {
587 tg.t.Logf("pattern %v found unexpectedly in standard %s", match, name)
592 // grepStdoutNot looks for a regular expression in the test run's
593 // standard output and fails, logging msg, if it is found.
594 func (tg *testgoData) grepStdoutNot(match, msg string) {
596 tg.doGrepNot(match, &tg.stdout, "output", msg)
599 // grepStderrNot looks for a regular expression in the test run's
600 // standard error and fails, logging msg, if it is found.
601 func (tg *testgoData) grepStderrNot(match, msg string) {
603 tg.doGrepNot(match, &tg.stderr, "error", msg)
606 // grepBothNot looks for a regular expression in the test run's
607 // standard output or standard error and fails, logging msg, if it is
609 func (tg *testgoData) grepBothNot(match, msg string) {
611 if tg.doGrepMatch(match, &tg.stdout) || tg.doGrepMatch(match, &tg.stderr) {
613 tg.t.Fatalf("pattern %v found unexpectedly in standard output or standard error", match)
617 // doGrepCount counts the number of times a regexp is seen in a buffer.
618 func (tg *testgoData) doGrepCount(match string, b *bytes.Buffer) int {
621 tg.t.Fatal("internal testsuite error: doGrepCount called before run")
623 re := regexp.MustCompile(match)
625 for _, ln := range bytes.Split(b.Bytes(), []byte{'\n'}) {
633 // grepCountBoth returns the number of times a regexp is seen in both
634 // standard output and standard error.
635 func (tg *testgoData) grepCountBoth(match string) int {
637 return tg.doGrepCount(match, &tg.stdout) + tg.doGrepCount(match, &tg.stderr)
640 // creatingTemp records that the test plans to create a temporary file
641 // or directory. If the file or directory exists already, it will be
642 // removed. When the test completes, the file or directory will be
643 // removed if it exists.
644 func (tg *testgoData) creatingTemp(path string) {
646 if filepath.IsAbs(path) && !strings.HasPrefix(path, tg.tempdir) {
647 tg.t.Fatalf("internal testsuite error: creatingTemp(%q) with absolute path not in temporary directory", path)
649 tg.must(robustio.RemoveAll(path))
650 tg.temps = append(tg.temps, path)
653 // makeTempdir makes a temporary directory for a run of testgo. If
654 // the temporary directory was already created, this does nothing.
655 func (tg *testgoData) makeTempdir() {
657 if tg.tempdir == "" {
659 tg.tempdir, err = ioutil.TempDir("", "gotest")
664 // tempFile adds a temporary file for a run of testgo.
665 func (tg *testgoData) tempFile(path, contents string) {
668 tg.must(os.MkdirAll(filepath.Join(tg.tempdir, filepath.Dir(path)), 0755))
669 bytes := []byte(contents)
670 if strings.HasSuffix(path, ".go") {
671 formatted, err := format.Source(bytes)
676 tg.must(ioutil.WriteFile(filepath.Join(tg.tempdir, path), bytes, 0644))
679 // tempDir adds a temporary directory for a run of testgo.
680 func (tg *testgoData) tempDir(path string) {
683 if err := os.MkdirAll(filepath.Join(tg.tempdir, path), 0755); err != nil && !os.IsExist(err) {
688 // path returns the absolute pathname to file with the temporary
690 func (tg *testgoData) path(name string) string {
692 if tg.tempdir == "" {
693 tg.t.Fatalf("internal testsuite error: path(%q) with no tempdir", name)
698 return filepath.Join(tg.tempdir, name)
701 // mustExist fails if path does not exist.
702 func (tg *testgoData) mustExist(path string) {
704 if _, err := os.Stat(path); err != nil {
705 if os.IsNotExist(err) {
706 tg.t.Fatalf("%s does not exist but should", path)
708 tg.t.Fatalf("%s stat failed: %v", path, err)
712 // mustNotExist fails if path exists.
713 func (tg *testgoData) mustNotExist(path string) {
715 if _, err := os.Stat(path); err == nil || !os.IsNotExist(err) {
716 tg.t.Fatalf("%s exists but should not (%v)", path, err)
720 // mustHaveContent succeeds if filePath is a path to a file,
721 // and that file is readable and not empty.
722 func (tg *testgoData) mustHaveContent(filePath string) {
723 tg.mustExist(filePath)
724 f, err := os.Stat(filePath)
729 tg.t.Fatalf("expected %s to have data, but is empty", filePath)
733 // wantExecutable fails with msg if path is not executable.
734 func (tg *testgoData) wantExecutable(path, msg string) {
736 if st, err := os.Stat(path); err != nil {
737 if !os.IsNotExist(err) {
742 if runtime.GOOS != "windows" && st.Mode()&0111 == 0 {
743 tg.t.Fatalf("binary %s exists but is not executable", path)
748 // isStale reports whether pkg is stale, and why
749 func (tg *testgoData) isStale(pkg string) (bool, string) {
751 tg.run("list", "-f", "{{.Stale}}:{{.StaleReason}}", pkg)
752 v := strings.TrimSpace(tg.getStdout())
753 f := strings.SplitN(v, ":", 2)
762 tg.t.Fatalf("unexpected output checking staleness of package %v: %v", pkg, v)
766 // wantStale fails with msg if pkg is not stale.
767 func (tg *testgoData) wantStale(pkg, reason, msg string) {
769 stale, why := tg.isStale(pkg)
773 // We always accept the reason as being "not installed but
774 // available in build cache", because when that is the case go
775 // list doesn't try to sort out the underlying reason why the
776 // package is not installed.
777 if reason == "" && why != "" || !strings.Contains(why, reason) && !strings.Contains(why, "not installed but available in build cache") {
778 tg.t.Errorf("wrong reason for Stale=true: %q, want %q", why, reason)
782 // wantNotStale fails with msg if pkg is stale.
783 func (tg *testgoData) wantNotStale(pkg, reason, msg string) {
785 stale, why := tg.isStale(pkg)
789 if reason == "" && why != "" || !strings.Contains(why, reason) {
790 tg.t.Errorf("wrong reason for Stale=false: %q, want %q", why, reason)
794 // If -testwork is specified, the test prints the name of the temp directory
795 // and does not remove it when done, so that a programmer can
796 // poke at the test file tree afterward.
797 var testWork = flag.Bool("testwork", false, "")
799 // cleanup cleans up a test that runs testgo.
800 func (tg *testgoData) cleanup() {
803 tg.t.Logf("TESTWORK=%s\n", tg.path("."))
806 for _, path := range tg.temps {
807 tg.check(removeAll(path))
809 if tg.tempdir != "" {
810 tg.check(removeAll(tg.tempdir))
814 func removeAll(dir string) error {
815 // module cache has 0444 directories;
816 // make them writable in order to remove content.
817 filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
818 // chmod not only directories, but also things that we couldn't even stat
819 // due to permission errors: they may also be unreadable directories.
820 if err != nil || info.IsDir() {
825 return robustio.RemoveAll(dir)
828 // failSSH puts an ssh executable in the PATH that always fails.
829 // This is to stub out uses of ssh by go get.
830 func (tg *testgoData) failSSH() {
832 wd, err := os.Getwd()
836 fail := filepath.Join(wd, "testdata/failssh")
837 tg.setenv("PATH", fmt.Sprintf("%v%c%v", fail, filepath.ListSeparator, os.Getenv("PATH")))
840 func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) {
842 t.Skip("skipping lengthy test in short mode")
849 // Copy the runtime packages into a temporary GOROOT
850 // so that we can change files.
851 for _, copydir := range []string{
853 "src/internal/bytealg",
857 filepath.Join("pkg", runtime.GOOS+"_"+runtime.GOARCH),
858 filepath.Join("pkg/tool", runtime.GOOS+"_"+runtime.GOARCH),
861 srcdir := filepath.Join(testGOROOT, copydir)
862 tg.tempDir(filepath.Join("goroot", copydir))
863 err := filepath.Walk(srcdir,
864 func(path string, info os.FileInfo, err error) error {
871 srcrel, err := filepath.Rel(srcdir, path)
875 dest := filepath.Join("goroot", copydir, srcrel)
876 data, err := ioutil.ReadFile(path)
880 tg.tempFile(dest, string(data))
881 if err := os.Chmod(tg.path(dest), info.Mode()|0200); err != nil {
890 tg.setenv("GOROOT", tg.path("goroot"))
892 addVar := func(name string, idx int) (restore func()) {
893 data, err := ioutil.ReadFile(name)
898 data = append(data, fmt.Sprintf("var DummyUnusedVar%d bool\n", idx)...)
899 if err := ioutil.WriteFile(name, append(data, '\n'), 0666); err != nil {
904 if err := ioutil.WriteFile(name, old, 0666); err != nil {
910 // Every main package depends on the "runtime".
911 tg.tempFile("d1/src/p1/p1.go", `package main; func main(){}`)
912 tg.setenv("GOPATH", tg.path("d1"))
913 // Pass -i flag to rebuild everything outdated.
914 tg.run("install", "-i", "p1")
915 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, before any changes")
917 // Changing mtime of runtime/internal/sys/sys.go
918 // should have no effect: only the content matters.
919 // In fact this should be true even outside a release branch.
920 sys := tg.path("goroot/src/runtime/internal/sys/sys.go")
922 restore := addVar(sys, 0)
924 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, after updating mtime of runtime/internal/sys/sys.go")
926 // But changing content of any file should have an effect.
927 // Previously zversion.go was the only one that mattered;
928 // now they all matter, so keep using sys.go.
929 restore = addVar(sys, 1)
931 tg.wantStale("p1", "stale dependency: runtime/internal/sys", "./testgo list claims p1 is NOT stale, incorrectly, after changing sys.go")
933 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, after changing back to old release")
935 tg.wantStale("p1", "stale dependency: runtime", "./testgo list claims p1 is NOT stale, incorrectly, after changing sys.go again")
936 tg.run("install", "-i", "p1")
937 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after building with new release")
939 // Restore to "old" release.
941 tg.wantStale("p1", "stale dependency: runtime/internal/sys", "./testgo list claims p1 is NOT stale, incorrectly, after restoring sys.go")
942 tg.run("install", "-i", "p1")
943 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after building with old release")
946 // cmd/go: custom import path checking should not apply to Go packages without import comment.
947 func TestIssue10952(t *testing.T) {
948 testenv.MustHaveExternalNetwork(t)
949 testenv.MustHaveExecPath(t, "git")
955 tg.setenv("GOPATH", tg.path("."))
956 const importPath = "github.com/zombiezen/go-get-issue-10952"
957 tg.run("get", "-d", "-u", importPath)
958 repoDir := tg.path("src/" + importPath)
959 tg.runGit(repoDir, "remote", "set-url", "origin", "https://"+importPath+".git")
960 tg.run("get", "-d", "-u", importPath)
963 func TestIssue16471(t *testing.T) {
964 testenv.MustHaveExternalNetwork(t)
965 testenv.MustHaveExecPath(t, "git")
971 tg.setenv("GOPATH", tg.path("."))
972 tg.must(os.MkdirAll(tg.path("src/rsc.io/go-get-issue-10952"), 0755))
973 tg.runGit(tg.path("src/rsc.io"), "clone", "https://github.com/zombiezen/go-get-issue-10952")
974 tg.runFail("get", "-u", "rsc.io/go-get-issue-10952")
975 tg.grepStderr("rsc.io/go-get-issue-10952 is a custom import path for https://github.com/rsc/go-get-issue-10952, but .* is checked out from https://github.com/zombiezen/go-get-issue-10952", "did not detect updated import path")
978 // Test git clone URL that uses SCP-like syntax and custom import path checking.
979 func TestIssue11457(t *testing.T) {
980 testenv.MustHaveExternalNetwork(t)
981 testenv.MustHaveExecPath(t, "git")
987 tg.setenv("GOPATH", tg.path("."))
988 const importPath = "rsc.io/go-get-issue-11457"
989 tg.run("get", "-d", "-u", importPath)
990 repoDir := tg.path("src/" + importPath)
991 tg.runGit(repoDir, "remote", "set-url", "origin", "git@github.com:rsc/go-get-issue-11457")
993 // At this time, custom import path checking compares remotes verbatim (rather than
994 // just the host and path, skipping scheme and user), so we expect go get -u to fail.
995 // However, the goal of this test is to verify that gitRemoteRepo correctly parsed
996 // the SCP-like syntax, and we expect it to appear in the error message.
997 tg.runFail("get", "-d", "-u", importPath)
998 want := " is checked out from ssh://git@github.com/rsc/go-get-issue-11457"
999 if !strings.HasSuffix(strings.TrimSpace(tg.getStderr()), want) {
1000 t.Error("expected clone URL to appear in stderr")
1004 func TestGetGitDefaultBranch(t *testing.T) {
1005 testenv.MustHaveExternalNetwork(t)
1006 testenv.MustHaveExecPath(t, "git")
1012 tg.setenv("GOPATH", tg.path("."))
1014 // This repo has two branches, master and another-branch.
1015 // The another-branch is the default that you get from 'git clone'.
1016 // The go get command variants should not override this.
1017 const importPath = "github.com/rsc/go-get-default-branch"
1019 tg.run("get", "-d", importPath)
1020 repoDir := tg.path("src/" + importPath)
1021 tg.runGit(repoDir, "branch", "--contains", "HEAD")
1022 tg.grepStdout(`\* another-branch`, "not on correct default branch")
1024 tg.run("get", "-d", "-u", importPath)
1025 tg.runGit(repoDir, "branch", "--contains", "HEAD")
1026 tg.grepStdout(`\* another-branch`, "not on correct default branch")
1029 // Security issue. Don't disable. See golang.org/issue/22125.
1030 func TestAccidentalGitCheckout(t *testing.T) {
1031 testenv.MustHaveExternalNetwork(t)
1032 testenv.MustHaveExecPath(t, "git")
1033 testenv.MustHaveExecPath(t, "svn")
1040 tg.setenv("GOPATH", tg.path("."))
1042 tg.runFail("get", "-u", "vcs-test.golang.org/go/test1-svn-git")
1043 tg.grepStderr("src[\\\\/]vcs-test.* uses git, but parent .*src[\\\\/]vcs-test.* uses svn", "get did not fail for right reason")
1045 if _, err := os.Stat(tg.path("SrC")); err == nil {
1046 // This case only triggers on a case-insensitive file system.
1047 tg.runFail("get", "-u", "vcs-test.golang.org/go/test2-svn-git/test2main")
1048 tg.grepStderr("src[\\\\/]vcs-test.* uses git, but parent .*src[\\\\/]vcs-test.* uses svn", "get did not fail for right reason")
1052 func TestPackageMainTestCompilerFlags(t *testing.T) {
1057 tg.setenv("GOPATH", tg.path("."))
1058 tg.tempFile("src/p1/p1.go", "package main\n")
1059 tg.tempFile("src/p1/p1_test.go", "package main\nimport \"testing\"\nfunc Test(t *testing.T){}\n")
1060 tg.run("test", "-c", "-n", "p1")
1061 tg.grepBothNot(`([\\/]compile|gccgo).* (-p main|-fgo-pkgpath=main).*p1\.go`, "should not have run compile -p main p1.go")
1062 tg.grepStderr(`([\\/]compile|gccgo).* (-p p1|-fgo-pkgpath=p1).*p1\.go`, "should have run compile -p p1 p1.go")
1066 func TestGoTestWithPackageListedMultipleTimes(t *testing.T) {
1071 tg.run("test", "errors", "errors", "errors", "errors", "errors")
1072 if strings.Contains(strings.TrimSpace(tg.getStdout()), "\n") {
1073 t.Error("go test errors errors errors errors errors tested the same package multiple times")
1077 func TestGoListHasAConsistentOrder(t *testing.T) {
1082 tg.run("list", "std")
1083 first := tg.getStdout()
1084 tg.run("list", "std")
1085 if first != tg.getStdout() {
1086 t.Error("go list std ordering is inconsistent")
1090 func TestGoListStdDoesNotIncludeCommands(t *testing.T) {
1095 tg.run("list", "std")
1096 tg.grepStdoutNot("cmd/", "go list std shows commands")
1099 func TestGoListCmdOnlyShowsCommands(t *testing.T) {
1100 skipIfGccgo(t, "gccgo does not have GOROOT")
1105 tg.run("list", "cmd")
1106 out := strings.TrimSpace(tg.getStdout())
1107 for _, line := range strings.Split(out, "\n") {
1108 if !strings.Contains(line, "cmd/") {
1109 t.Error("go list cmd shows non-commands")
1115 func TestGoListDeps(t *testing.T) {
1119 tg.tempDir("src/p1/p2/p3/p4")
1120 tg.setenv("GOPATH", tg.path("."))
1121 tg.tempFile("src/p1/p.go", "package p1\nimport _ \"p1/p2\"\n")
1122 tg.tempFile("src/p1/p2/p.go", "package p2\nimport _ \"p1/p2/p3\"\n")
1123 tg.tempFile("src/p1/p2/p3/p.go", "package p3\nimport _ \"p1/p2/p3/p4\"\n")
1124 tg.tempFile("src/p1/p2/p3/p4/p.go", "package p4\n")
1125 tg.run("list", "-f", "{{.Deps}}", "p1")
1126 tg.grepStdout("p1/p2/p3/p4", "Deps(p1) does not mention p4")
1128 tg.run("list", "-deps", "p1")
1129 tg.grepStdout("p1/p2/p3/p4", "-deps p1 does not mention p4")
1131 if runtime.Compiler != "gccgo" {
1132 // Check the list is in dependency order.
1133 tg.run("list", "-deps", "math")
1134 want := "internal/cpu\nunsafe\nmath/bits\nmath\n"
1135 out := tg.stdout.String()
1136 if !strings.Contains(out, "internal/cpu") {
1137 // Some systems don't use internal/cpu.
1138 want = "unsafe\nmath/bits\nmath\n"
1140 if tg.stdout.String() != want {
1141 t.Fatalf("list -deps math: wrong order\nhave %q\nwant %q", tg.stdout.String(), want)
1146 func TestGoListTest(t *testing.T) {
1147 skipIfGccgo(t, "gccgo does not have standard packages")
1152 tg.setenv("GOCACHE", tg.tempdir)
1154 tg.run("list", "-test", "-deps", "sort")
1155 tg.grepStdout(`^sort.test$`, "missing test main")
1156 tg.grepStdout(`^sort$`, "missing real sort")
1157 tg.grepStdout(`^sort \[sort.test\]$`, "missing test copy of sort")
1158 tg.grepStdout(`^testing \[sort.test\]$`, "missing test copy of testing")
1159 tg.grepStdoutNot(`^testing$`, "unexpected real copy of testing")
1161 tg.run("list", "-test", "sort")
1162 tg.grepStdout(`^sort.test$`, "missing test main")
1163 tg.grepStdout(`^sort$`, "missing real sort")
1164 tg.grepStdout(`^sort \[sort.test\]$`, "unexpected test copy of sort")
1165 tg.grepStdoutNot(`^testing \[sort.test\]$`, "unexpected test copy of testing")
1166 tg.grepStdoutNot(`^testing$`, "unexpected real copy of testing")
1168 tg.run("list", "-test", "cmd/dist", "cmd/doc")
1169 tg.grepStdout(`^cmd/dist$`, "missing cmd/dist")
1170 tg.grepStdout(`^cmd/doc$`, "missing cmd/doc")
1171 tg.grepStdout(`^cmd/doc\.test$`, "missing cmd/doc test")
1172 tg.grepStdoutNot(`^cmd/dist\.test$`, "unexpected cmd/dist test")
1173 tg.grepStdoutNot(`^testing`, "unexpected testing")
1175 tg.run("list", "-test", "runtime/cgo")
1176 tg.grepStdout(`^runtime/cgo$`, "missing runtime/cgo")
1178 tg.run("list", "-deps", "-f", "{{if .DepOnly}}{{.ImportPath}}{{end}}", "sort")
1179 tg.grepStdout(`^internal/reflectlite$`, "missing internal/reflectlite")
1180 tg.grepStdoutNot(`^sort`, "unexpected sort")
1183 func TestGoListCompiledCgo(t *testing.T) {
1189 tg.setenv("GOCACHE", tg.tempdir)
1191 tg.run("list", "-f", `{{join .CgoFiles "\n"}}`, "net")
1192 if tg.stdout.String() == "" {
1193 t.Skip("net does not use cgo")
1195 if strings.Contains(tg.stdout.String(), tg.tempdir) {
1196 t.Fatalf(".CgoFiles unexpectedly mentioned cache %s", tg.tempdir)
1198 tg.run("list", "-compiled", "-f", `{{.Dir}}{{"\n"}}{{join .CompiledGoFiles "\n"}}`, "net")
1199 if !strings.Contains(tg.stdout.String(), tg.tempdir) {
1200 t.Fatalf(".CompiledGoFiles with -compiled did not mention cache %s", tg.tempdir)
1203 for _, file := range strings.Split(tg.stdout.String(), "\n") {
1211 if !strings.Contains(file, "/") && !strings.Contains(file, `\`) {
1212 file = filepath.Join(dir, file)
1214 if _, err := os.Stat(file); err != nil {
1215 t.Fatalf("cannot find .CompiledGoFiles result %s: %v", file, err)
1220 func TestGoListExport(t *testing.T) {
1221 skipIfGccgo(t, "gccgo does not have standard packages")
1226 tg.setenv("GOCACHE", tg.tempdir)
1228 tg.run("list", "-f", "{{.Export}}", "strings")
1229 if tg.stdout.String() != "" {
1230 t.Fatalf(".Export without -export unexpectedly set")
1232 tg.run("list", "-export", "-f", "{{.Export}}", "strings")
1233 file := strings.TrimSpace(tg.stdout.String())
1235 t.Fatalf(".Export with -export was empty")
1237 if _, err := os.Stat(file); err != nil {
1238 t.Fatalf("cannot find .Export result %s: %v", file, err)
1242 // Issue 4096. Validate the output of unsuccessful go install foo/quxx.
1243 func TestUnsuccessfulGoInstallShouldMentionMissingPackage(t *testing.T) {
1247 tg.runFail("install", "foo/quxx")
1248 if tg.grepCountBoth(`cannot find package "foo/quxx" in any of`) != 1 {
1249 t.Error(`go install foo/quxx expected error: .*cannot find package "foo/quxx" in any of`)
1253 func TestGOROOTSearchFailureReporting(t *testing.T) {
1257 tg.runFail("install", "foo/quxx")
1258 if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("foo", "quxx"))+` \(from \$GOROOT\)$`) != 1 {
1259 t.Error(`go install foo/quxx expected error: .*foo/quxx (from $GOROOT)`)
1263 func TestMultipleGOPATHEntriesReportedSeparately(t *testing.T) {
1267 sep := string(filepath.ListSeparator)
1268 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
1269 tg.runFail("install", "foo/quxx")
1270 if tg.grepCountBoth(`testdata[/\\].[/\\]src[/\\]foo[/\\]quxx`) != 2 {
1271 t.Error(`go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)\n.*testdata/b/src/foo/quxx`)
1275 // Test (from $GOPATH) annotation is reported for the first GOPATH entry,
1276 func TestMentionGOPATHInFirstGOPATHEntry(t *testing.T) {
1280 sep := string(filepath.ListSeparator)
1281 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
1282 tg.runFail("install", "foo/quxx")
1283 if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("testdata", "a", "src", "foo", "quxx"))+` \(from \$GOPATH\)$`) != 1 {
1284 t.Error(`go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)`)
1288 // but not on the second.
1289 func TestMentionGOPATHNotOnSecondEntry(t *testing.T) {
1293 sep := string(filepath.ListSeparator)
1294 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
1295 tg.runFail("install", "foo/quxx")
1296 if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("testdata", "b", "src", "foo", "quxx"))+`$`) != 1 {
1297 t.Error(`go install foo/quxx expected error: .*testdata/b/src/foo/quxx`)
1301 func homeEnvName() string {
1302 switch runtime.GOOS {
1304 return "USERPROFILE"
1312 func tempEnvName() string {
1313 switch runtime.GOOS {
1317 return "TMPDIR" // actually plan 9 doesn't have one at all but this is fine
1323 func TestDefaultGOPATH(t *testing.T) {
1327 tg.tempDir("home/go")
1328 tg.setenv(homeEnvName(), tg.path("home"))
1330 tg.run("env", "GOPATH")
1331 tg.grepStdout(regexp.QuoteMeta(tg.path("home/go")), "want GOPATH=$HOME/go")
1333 tg.setenv("GOROOT", tg.path("home/go"))
1334 tg.run("env", "GOPATH")
1335 tg.grepStdoutNot(".", "want unset GOPATH because GOROOT=$HOME/go")
1337 tg.setenv("GOROOT", tg.path("home/go")+"/")
1338 tg.run("env", "GOPATH")
1339 tg.grepStdoutNot(".", "want unset GOPATH because GOROOT=$HOME/go/")
1342 func TestDefaultGOPATHGet(t *testing.T) {
1343 testenv.MustHaveExternalNetwork(t)
1344 testenv.MustHaveExecPath(t, "git")
1349 tg.setenv("GOPATH", "")
1351 tg.setenv(homeEnvName(), tg.path("home"))
1353 // warn for creating directory
1354 tg.run("get", "-v", "github.com/golang/example/hello")
1355 tg.grepStderr("created GOPATH="+regexp.QuoteMeta(tg.path("home/go"))+"; see 'go help gopath'", "did not create GOPATH")
1357 // no warning if directory already exists
1358 tg.must(robustio.RemoveAll(tg.path("home/go")))
1359 tg.tempDir("home/go")
1360 tg.run("get", "github.com/golang/example/hello")
1361 tg.grepStderrNot(".", "expected no output on standard error")
1363 // error if $HOME/go is a file
1364 tg.must(robustio.RemoveAll(tg.path("home/go")))
1365 tg.tempFile("home/go", "")
1366 tg.runFail("get", "github.com/golang/example/hello")
1367 tg.grepStderr(`mkdir .*[/\\]go: .*(not a directory|cannot find the path)`, "expected error because $HOME/go is a file")
1370 func TestDefaultGOPATHPrintedSearchList(t *testing.T) {
1374 tg.setenv("GOPATH", "")
1376 tg.setenv(homeEnvName(), tg.path("home"))
1378 tg.runFail("install", "github.com/golang/example/hello")
1379 tg.grepStderr(regexp.QuoteMeta(tg.path("home/go/src/github.com/golang/example/hello"))+`.*from \$GOPATH`, "expected default GOPATH")
1382 func TestLdflagsArgumentsWithSpacesIssue3941(t *testing.T) {
1383 skipIfGccgo(t, "gccgo does not support -ldflags -X")
1388 tg.tempFile("main.go", `package main
1393 tg.run("run", "-ldflags", `-X "main.extern=hello world"`, tg.path("main.go"))
1394 tg.grepStderr("^hello world", `ldflags -X "main.extern=hello world"' failed`)
1397 func TestGoTestDashCDashOControlsBinaryLocation(t *testing.T) {
1398 skipIfGccgo(t, "gccgo has no standard packages")
1404 tg.run("test", "-c", "-o", tg.path("myerrors.test"+exeSuffix), "errors")
1405 tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -c -o myerrors.test did not create myerrors.test")
1408 func TestGoTestDashOWritesBinary(t *testing.T) {
1409 skipIfGccgo(t, "gccgo has no standard packages")
1415 tg.run("test", "-o", tg.path("myerrors.test"+exeSuffix), "errors")
1416 tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -o myerrors.test did not create myerrors.test")
1419 func TestGoTestDashIDashOWritesBinary(t *testing.T) {
1420 skipIfGccgo(t, "gccgo has no standard packages")
1427 // don't let test -i overwrite runtime
1428 tg.wantNotStale("runtime", "", "must be non-stale before test -i")
1430 tg.run("test", "-v", "-i", "-o", tg.path("myerrors.test"+exeSuffix), "errors")
1431 tg.grepBothNot("PASS|FAIL", "test should not have run")
1432 tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -o myerrors.test did not create myerrors.test")
1436 func TestInstallWithTags(t *testing.T) {
1442 tg.tempFile("src/example/a/main.go", `package main
1444 tg.tempFile("src/example/b/main.go", `// +build mytag
1448 tg.setenv("GOPATH", tg.path("."))
1449 tg.run("install", "-tags", "mytag", "example/a", "example/b")
1450 tg.wantExecutable(tg.path("bin/a"+exeSuffix), "go install example/a example/b did not install binaries")
1451 tg.wantExecutable(tg.path("bin/b"+exeSuffix), "go install example/a example/b did not install binaries")
1452 tg.must(os.Remove(tg.path("bin/a" + exeSuffix)))
1453 tg.must(os.Remove(tg.path("bin/b" + exeSuffix)))
1454 tg.run("install", "-tags", "mytag", "example/...")
1455 tg.wantExecutable(tg.path("bin/a"+exeSuffix), "go install example/... did not install binaries")
1456 tg.wantExecutable(tg.path("bin/b"+exeSuffix), "go install example/... did not install binaries")
1457 tg.run("list", "-tags", "mytag", "example/b...")
1458 if strings.TrimSpace(tg.getStdout()) != "example/b" {
1459 t.Error("go list example/b did not find example/b")
1463 // Issue 17451, 17662.
1464 func TestSymlinkWarning(t *testing.T) {
1469 tg.setenv("GOPATH", tg.path("."))
1471 tg.tempDir("src/example/xx")
1473 tg.tempFile("yy/zz/zz.go", "package zz\n")
1474 if err := os.Symlink(tg.path("yy"), tg.path("src/example/xx/yy")); err != nil {
1475 t.Skipf("symlink failed: %v", err)
1477 tg.run("list", "example/xx/z...")
1478 tg.grepStdoutNot(".", "list should not have matched anything")
1479 tg.grepStderr("matched no packages", "list should have reported that pattern matched no packages")
1480 tg.grepStderrNot("symlink", "list should not have reported symlink")
1482 tg.run("list", "example/xx/...")
1483 tg.grepStdoutNot(".", "list should not have matched anything")
1484 tg.grepStderr("matched no packages", "list should have reported that pattern matched no packages")
1485 tg.grepStderr("ignoring symlink", "list should have reported symlink")
1488 func TestCgoShowsFullPathNames(t *testing.T) {
1490 t.Skip("skipping because cgo not enabled")
1496 tg.tempFile("src/x/y/dirname/foo.go", `
1500 tg.setenv("GOPATH", tg.path("."))
1501 tg.runFail("build", "x/y/dirname")
1502 tg.grepBoth("x/y/dirname", "error did not use full path")
1505 func TestCgoHandlesWlORIGIN(t *testing.T) {
1508 t.Skip("skipping because cgo not enabled")
1514 tg.tempFile("src/origin/origin.go", `package origin
1515 // #cgo !darwin LDFLAGS: -Wl,-rpath,$ORIGIN
1518 func f() { C.f() }`)
1519 tg.setenv("GOPATH", tg.path("."))
1520 tg.run("build", "origin")
1523 func TestCgoPkgConfig(t *testing.T) {
1526 t.Skip("skipping because cgo not enabled")
1532 tg.run("env", "PKG_CONFIG")
1533 pkgConfig := strings.TrimSpace(tg.getStdout())
1534 testenv.MustHaveExecPath(t, pkgConfig)
1535 if out, err := exec.Command(pkgConfig, "--atleast-pkgconfig-version", "0.24").CombinedOutput(); err != nil {
1536 t.Skipf("%s --atleast-pkgconfig-version 0.24: %v\n%s", pkgConfig, err, out)
1539 // OpenBSD's pkg-config is strict about whitespace and only
1540 // supports backslash-escaped whitespace. It does not support
1541 // quotes, which the normal freedesktop.org pkg-config does
1542 // support. See https://man.openbsd.org/pkg-config.1
1543 tg.tempFile("foo.pc", `
1545 Description: The foo library
1547 Cflags: -Dhello=10 -Dworld=+32 -DDEFINED_FROM_PKG_CONFIG=hello\ world
1549 tg.tempFile("foo.go", `package main
1552 #cgo pkg-config: foo
1554 return DEFINED_FROM_PKG_CONFIG;
1561 if C.value() != 42 {
1562 println("value() =", C.value(), "wanted 42")
1567 tg.setenv("PKG_CONFIG_PATH", tg.path("."))
1568 tg.run("run", tg.path("foo.go"))
1571 func TestListTemplateContextFunction(t *testing.T) {
1573 for _, tt := range []struct {
1577 {"GOARCH", runtime.GOARCH},
1578 {"GOOS", runtime.GOOS},
1579 {"GOROOT", filepath.Clean(runtime.GOROOT())},
1580 {"GOPATH", os.Getenv("GOPATH")},
1582 {"UseAllFiles", ""},
1585 {"ReleaseTags", ""},
1586 {"InstallSuffix", ""},
1589 t.Run(tt.v, func(t *testing.T) {
1593 tmpl := "{{context." + tt.v + "}}"
1594 tg.run("list", "-f", tmpl)
1598 if got := strings.TrimSpace(tg.getStdout()); got != tt.want {
1599 t.Errorf("go list -f %q: got %q; want %q", tmpl, got, tt.want)
1605 // Test that you cannot use a local import in a package
1606 // accessed by a non-local import (found in a GOPATH/GOROOT).
1607 // See golang.org/issue/17475.
1608 func TestImportLocal(t *testing.T) {
1615 tg.tempFile("src/dir/x/x.go", `package x
1618 tg.setenv("GOPATH", tg.path("."))
1619 tg.run("build", "dir/x")
1621 // Ordinary import should work.
1622 tg.tempFile("src/dir/p0/p.go", `package p0
1626 tg.run("build", "dir/p0")
1628 // Relative import should not.
1629 tg.tempFile("src/dir/p1/p.go", `package p1
1633 tg.runFail("build", "dir/p1")
1634 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1636 // ... even in a test.
1637 tg.tempFile("src/dir/p2/p.go", `package p2
1639 tg.tempFile("src/dir/p2/p_test.go", `package p2
1643 func TestFoo(t *testing.T) {}
1645 tg.run("build", "dir/p2")
1646 tg.runFail("test", "dir/p2")
1647 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1649 // ... even in an xtest.
1650 tg.tempFile("src/dir/p2/p_test.go", `package p2_test
1654 func TestFoo(t *testing.T) {}
1656 tg.run("build", "dir/p2")
1657 tg.runFail("test", "dir/p2")
1658 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1660 // Relative import starting with ./ should not work either.
1661 tg.tempFile("src/dir/d.go", `package dir
1665 tg.runFail("build", "dir")
1666 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1668 // ... even in a test.
1669 tg.tempFile("src/dir/d.go", `package dir
1671 tg.tempFile("src/dir/d_test.go", `package dir
1675 func TestFoo(t *testing.T) {}
1677 tg.run("build", "dir")
1678 tg.runFail("test", "dir")
1679 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1681 // ... even in an xtest.
1682 tg.tempFile("src/dir/d_test.go", `package dir_test
1686 func TestFoo(t *testing.T) {}
1688 tg.run("build", "dir")
1689 tg.runFail("test", "dir")
1690 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1692 // Relative import plain ".." should not work.
1693 tg.tempFile("src/dir/x/y/y.go", `package dir
1697 tg.runFail("build", "dir/x/y")
1698 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1700 // ... even in a test.
1701 tg.tempFile("src/dir/x/y/y.go", `package y
1703 tg.tempFile("src/dir/x/y/y_test.go", `package y
1707 func TestFoo(t *testing.T) {}
1709 tg.run("build", "dir/x/y")
1710 tg.runFail("test", "dir/x/y")
1711 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1713 // ... even in an x test.
1714 tg.tempFile("src/dir/x/y/y_test.go", `package y_test
1718 func TestFoo(t *testing.T) {}
1720 tg.run("build", "dir/x/y")
1721 tg.runFail("test", "dir/x/y")
1722 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1724 // Relative import "." should not work.
1725 tg.tempFile("src/dir/x/xx.go", `package x
1729 tg.runFail("build", "dir/x")
1730 tg.grepStderr("cannot import current directory", "did not diagnose import current directory")
1732 // ... even in a test.
1733 tg.tempFile("src/dir/x/xx.go", `package x
1735 tg.tempFile("src/dir/x/xx_test.go", `package x
1739 func TestFoo(t *testing.T) {}
1741 tg.run("build", "dir/x")
1742 tg.runFail("test", "dir/x")
1743 tg.grepStderr("cannot import current directory", "did not diagnose import current directory")
1745 // ... even in an xtest.
1746 tg.tempFile("src/dir/x/xx.go", `package x
1748 tg.tempFile("src/dir/x/xx_test.go", `package x_test
1752 func TestFoo(t *testing.T) {}
1754 tg.run("build", "dir/x")
1755 tg.runFail("test", "dir/x")
1756 tg.grepStderr("cannot import current directory", "did not diagnose import current directory")
1759 func TestGoInstallPkgdir(t *testing.T) {
1760 skipIfGccgo(t, "gccgo has no standard packages")
1768 tg.run("install", "-pkgdir", pkg, "sync")
1769 tg.mustExist(filepath.Join(pkg, "sync.a"))
1770 tg.mustNotExist(filepath.Join(pkg, "sync/atomic.a"))
1771 tg.run("install", "-i", "-pkgdir", pkg, "sync")
1772 tg.mustExist(filepath.Join(pkg, "sync.a"))
1773 tg.mustExist(filepath.Join(pkg, "sync/atomic.a"))
1777 func TestParallelTest(t *testing.T) {
1783 const testSrc = `package package_test
1787 func TestTest(t *testing.T) {
1789 tg.tempFile("src/p1/p1_test.go", strings.Replace(testSrc, "package_test", "p1_test", 1))
1790 tg.tempFile("src/p2/p2_test.go", strings.Replace(testSrc, "package_test", "p2_test", 1))
1791 tg.tempFile("src/p3/p3_test.go", strings.Replace(testSrc, "package_test", "p3_test", 1))
1792 tg.tempFile("src/p4/p4_test.go", strings.Replace(testSrc, "package_test", "p4_test", 1))
1793 tg.setenv("GOPATH", tg.path("."))
1794 tg.run("test", "-p=4", "p1", "p2", "p3", "p4")
1797 func TestBinaryOnlyPackages(t *testing.T) {
1804 tg.setenv("GOPATH", tg.path("."))
1806 tg.tempFile("src/p1/p1.go", `//go:binary-only-package
1810 tg.wantStale("p1", "binary-only packages are no longer supported", "p1 is binary-only, and this message should always be printed")
1811 tg.runFail("install", "p1")
1812 tg.grepStderr("binary-only packages are no longer supported", "did not report attempt to compile binary-only package")
1814 tg.tempFile("src/p1/p1.go", `
1817 func F(b bool) { fmt.Printf("hello from p1\n"); if b { F(false) } }
1819 tg.run("install", "p1")
1820 os.Remove(tg.path("src/p1/p1.go"))
1821 tg.mustNotExist(tg.path("src/p1/p1.go"))
1823 tg.tempFile("src/p2/p2.go", `//go:binary-only-packages-are-not-great
1827 func F() { p1.F(true) }
1829 tg.runFail("install", "p2")
1830 tg.grepStderr("no Go files", "did not complain about missing sources")
1832 tg.tempFile("src/p1/missing.go", `//go:binary-only-package
1838 tg.wantStale("p1", "binary-only package", "should NOT want to rebuild p1 (first)")
1839 tg.runFail("install", "p2")
1840 tg.grepStderr("p1: binary-only packages are no longer supported", "did not report error for binary-only p1")
1842 tg.run("list", "-deps", "-f", "{{.ImportPath}}: {{.BinaryOnly}}", "p2")
1843 tg.grepStdout("p1: true", "p1 not listed as BinaryOnly")
1844 tg.grepStdout("p2: false", "p2 listed as BinaryOnly")
1847 // Issue 16050 and 21884.
1848 func TestLinkSysoFiles(t *testing.T) {
1849 if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
1850 t.Skip("not linux/amd64")
1856 tg.tempDir("src/syso")
1857 tg.tempFile("src/syso/a.syso", ``)
1858 tg.tempFile("src/syso/b.go", `package syso`)
1859 tg.setenv("GOPATH", tg.path("."))
1861 // We should see the .syso file regardless of the setting of
1864 tg.setenv("CGO_ENABLED", "1")
1865 tg.run("list", "-f", "{{.SysoFiles}}", "syso")
1866 tg.grepStdout("a.syso", "missing syso file with CGO_ENABLED=1")
1868 tg.setenv("CGO_ENABLED", "0")
1869 tg.run("list", "-f", "{{.SysoFiles}}", "syso")
1870 tg.grepStdout("a.syso", "missing syso file with CGO_ENABLED=0")
1872 tg.setenv("CGO_ENABLED", "1")
1873 tg.run("list", "-msan", "-f", "{{.SysoFiles}}", "syso")
1874 tg.grepStdoutNot("a.syso", "unexpected syso file with -msan")
1878 func TestGenerateUsesBuildContext(t *testing.T) {
1879 if runtime.GOOS == "windows" {
1880 t.Skip("this test won't run under Windows")
1886 tg.tempDir("src/gen")
1887 tg.tempFile("src/gen/gen.go", "package gen\n//go:generate echo $GOOS $GOARCH\n")
1888 tg.setenv("GOPATH", tg.path("."))
1890 tg.setenv("GOOS", "linux")
1891 tg.setenv("GOARCH", "amd64")
1892 tg.run("generate", "gen")
1893 tg.grepStdout("linux amd64", "unexpected GOOS/GOARCH combination")
1895 tg.setenv("GOOS", "darwin")
1896 tg.setenv("GOARCH", "arm64")
1897 tg.run("generate", "gen")
1898 tg.grepStdout("darwin arm64", "unexpected GOOS/GOARCH combination")
1901 func TestGoEnv(t *testing.T) {
1905 tg.setenv("GOOS", "freebsd") // to avoid invalid pair errors
1906 tg.setenv("GOARCH", "arm")
1907 tg.run("env", "GOARCH")
1908 tg.grepStdout("^arm$", "GOARCH not honored")
1910 tg.run("env", "GCCGO")
1911 tg.grepStdout(".", "GCCGO unexpectedly empty")
1913 tg.run("env", "CGO_CFLAGS")
1914 tg.grepStdout(".", "default CGO_CFLAGS unexpectedly empty")
1916 tg.setenv("CGO_CFLAGS", "-foobar")
1917 tg.run("env", "CGO_CFLAGS")
1918 tg.grepStdout("^-foobar$", "CGO_CFLAGS not honored")
1920 tg.setenv("CC", "gcc -fmust -fgo -ffaster")
1922 tg.grepStdout("gcc", "CC not found")
1923 tg.run("env", "GOGCCFLAGS")
1924 tg.grepStdout("-ffaster", "CC arguments not found")
1928 noMatchesPattern = `(?m)^ok.*\[no tests to run\]`
1929 okPattern = `(?m)^ok`
1933 func TestLdBindNow(t *testing.T) {
1937 tg.setenv("LD_BIND_NOW", "1")
1942 // This is really a cmd/asm issue but this is a convenient place to test it.
1943 func TestConcurrentAsm(t *testing.T) {
1944 skipIfGccgo(t, "gccgo does not use cmd/asm")
1948 asm := `DATA ·constants<>+0x0(SB)/8,$0
1949 GLOBL ·constants<>(SB),8,$8
1951 tg.tempFile("go/src/p/a.s", asm)
1952 tg.tempFile("go/src/p/b.s", asm)
1953 tg.tempFile("go/src/p/p.go", `package p`)
1954 tg.setenv("GOPATH", tg.path("go"))
1955 tg.run("build", "p")
1959 func TestFFLAGS(t *testing.T) {
1961 t.Skip("skipping because cgo not enabled")
1968 tg.tempFile("p/src/p/main.go", `package main
1969 // #cgo FFLAGS: -no-such-fortran-flag
1973 tg.tempFile("p/src/p/a.f", `! comment`)
1974 tg.setenv("GOPATH", tg.path("p"))
1976 // This should normally fail because we are passing an unknown flag,
1977 // but issue #19080 points to Fortran compilers that succeed anyhow.
1978 // To work either way we call doRun directly rather than run or runFail.
1979 tg.doRun([]string{"build", "-x", "p"})
1981 tg.grepStderr("no-such-fortran-flag", `missing expected "-no-such-fortran-flag"`)
1985 // This is really a cmd/link issue but this is a convenient place to test it.
1986 func TestDuplicateGlobalAsmSymbols(t *testing.T) {
1987 skipIfGccgo(t, "gccgo does not use cmd/asm")
1989 if runtime.GOARCH != "386" && runtime.GOARCH != "amd64" {
1990 t.Skipf("skipping test on %s", runtime.GOARCH)
1993 t.Skip("skipping because cgo not enabled")
2001 #include "textflag.h"
2003 DATA sym<>+0x0(SB)/8,$0
2004 GLOBL sym<>(SB),(NOPTR+RODATA),$8
2006 TEXT ·Data(SB),NOSPLIT,$0
2011 tg.tempFile("go/src/a/a.s", asm)
2012 tg.tempFile("go/src/a/a.go", `package a; func Data() uint8`)
2013 tg.tempFile("go/src/b/b.s", asm)
2014 tg.tempFile("go/src/b/b.go", `package b; func Data() uint8`)
2015 tg.tempFile("go/src/p/p.go", `
2021 _ = a.Data() + b.Data()
2024 tg.setenv("GOPATH", tg.path("go"))
2025 exe := tg.path("p.exe")
2026 tg.creatingTemp(exe)
2027 tg.run("build", "-o", exe, "p")
2030 func copyFile(src, dst string, perm os.FileMode) error {
2031 sf, err := os.Open(src)
2037 df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
2042 _, err = io.Copy(df, sf)
2050 func TestNeedVersion(t *testing.T) {
2051 skipIfGccgo(t, "gccgo does not use cmd/compile")
2055 tg.tempFile("goversion.go", `package main; func main() {}`)
2056 path := tg.path("goversion.go")
2057 tg.setenv("TESTGO_VERSION", "go1.testgo")
2058 tg.runFail("run", path)
2059 tg.grepStderr("compile", "does not match go tool version")
2062 func TestBuildmodePIE(t *testing.T) {
2063 if testing.Short() && testenv.Builder() == "" {
2064 t.Skipf("skipping in -short mode on non-builder")
2067 platform := fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)
2069 case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x",
2070 "android/amd64", "android/arm", "android/arm64", "android/386",
2072 "windows/386", "windows/amd64", "windows/arm":
2073 case "darwin/amd64":
2075 t.Skipf("skipping test because buildmode=pie is not supported on %s", platform)
2077 t.Run("non-cgo", func(t *testing.T) {
2078 testBuildmodePIE(t, false, true)
2081 switch runtime.GOOS {
2082 case "darwin", "freebsd", "linux", "windows":
2083 t.Run("cgo", func(t *testing.T) {
2084 testBuildmodePIE(t, true, true)
2090 func TestWindowsDefaultBuildmodIsPIE(t *testing.T) {
2091 if testing.Short() && testenv.Builder() == "" {
2092 t.Skipf("skipping in -short mode on non-builder")
2095 if runtime.GOOS != "windows" {
2096 t.Skip("skipping windows only test")
2099 t.Run("non-cgo", func(t *testing.T) {
2100 testBuildmodePIE(t, false, false)
2103 t.Run("cgo", func(t *testing.T) {
2104 testBuildmodePIE(t, true, false)
2109 func testBuildmodePIE(t *testing.T, useCgo, setBuildmodeToPIE bool) {
2118 tg.tempFile("main.go", fmt.Sprintf(`package main;%s func main() { print("hello") }`, s))
2119 src := tg.path("main.go")
2120 obj := tg.path("main.exe")
2121 args := []string{"build"}
2122 if setBuildmodeToPIE {
2123 args = append(args, "-buildmode=pie")
2125 args = append(args, "-o", obj, src)
2128 switch runtime.GOOS {
2129 case "linux", "android", "freebsd":
2130 f, err := elf.Open(obj)
2135 if f.Type != elf.ET_DYN {
2136 t.Errorf("PIE type must be ET_DYN, but %s", f.Type)
2139 f, err := macho.Open(obj)
2144 if f.Flags&macho.FlagDyldLink == 0 {
2145 t.Error("PIE must have DyldLink flag, but not")
2147 if f.Flags&macho.FlagPIE == 0 {
2148 t.Error("PIE must have PIE flag, but not")
2151 f, err := pe.Open(obj)
2156 if f.Section(".reloc") == nil {
2157 t.Error(".reloc section is not present")
2159 if (f.FileHeader.Characteristics & pe.IMAGE_FILE_RELOCS_STRIPPED) != 0 {
2160 t.Error("IMAGE_FILE_RELOCS_STRIPPED flag is set")
2163 switch oh := f.OptionalHeader.(type) {
2164 case *pe.OptionalHeader32:
2165 dc = oh.DllCharacteristics
2166 case *pe.OptionalHeader64:
2167 dc = oh.DllCharacteristics
2168 if (dc & pe.IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA) == 0 {
2169 t.Error("IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA flag is not set")
2172 t.Fatalf("unexpected optional header type of %T", f.OptionalHeader)
2174 if (dc & pe.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) == 0 {
2175 t.Error("IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE flag is not set")
2178 panic("unreachable")
2181 out, err := exec.Command(obj).CombinedOutput()
2186 if string(out) != "hello" {
2187 t.Errorf("got %q; want %q", out, "hello")
2191 func TestUpxCompression(t *testing.T) {
2192 if runtime.GOOS != "linux" ||
2193 (runtime.GOARCH != "amd64" && runtime.GOARCH != "386") {
2194 t.Skipf("skipping upx test on %s/%s", runtime.GOOS, runtime.GOARCH)
2197 testenv.MustHaveExecPath(t, "upx")
2198 out, err := exec.Command("upx", "--version").CombinedOutput()
2200 t.Fatalf("upx --version failed: %v", err)
2203 // upx --version prints `upx <version>` in the first line of output:
2206 re := regexp.MustCompile(`([[:digit:]]+)\.([[:digit:]]+)`)
2207 upxVersion := re.FindStringSubmatch(string(out))
2208 if len(upxVersion) != 3 {
2209 t.Fatalf("bad upx version string: %s", upxVersion)
2212 major, err1 := strconv.Atoi(upxVersion[1])
2213 minor, err2 := strconv.Atoi(upxVersion[2])
2214 if err1 != nil || err2 != nil {
2215 t.Fatalf("bad upx version string: %s", upxVersion[0])
2218 // Anything below 3.94 is known not to work with go binaries
2219 if (major < 3) || (major == 3 && minor < 94) {
2220 t.Skipf("skipping because upx version %v.%v is too old", major, minor)
2227 tg.tempFile("main.go", `package main; import "fmt"; func main() { fmt.Print("hello upx") }`)
2228 src := tg.path("main.go")
2229 obj := tg.path("main")
2230 tg.run("build", "-o", obj, src)
2232 out, err = exec.Command("upx", obj).CombinedOutput()
2234 t.Logf("executing upx\n%s\n", out)
2235 t.Fatalf("upx failed with %v", err)
2238 out, err = exec.Command(obj).CombinedOutput()
2241 t.Fatalf("running compressed go binary failed with error %s", err)
2243 if string(out) != "hello upx" {
2244 t.Fatalf("bad output from compressed go binary:\ngot %q; want %q", out, "hello upx")
2248 func TestCacheListStale(t *testing.T) {
2250 if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
2251 t.Skip("GODEBUG gocacheverify")
2257 tg.setenv("GOCACHE", tg.path("cache"))
2258 tg.tempFile("gopath/src/p/p.go", "package p; import _ \"q\"; func F(){}\n")
2259 tg.tempFile("gopath/src/q/q.go", "package q; func F(){}\n")
2260 tg.tempFile("gopath/src/m/m.go", "package main; import _ \"q\"; func main(){}\n")
2262 tg.setenv("GOPATH", tg.path("gopath"))
2263 tg.run("install", "p", "m")
2264 tg.run("list", "-f={{.ImportPath}} {{.Stale}}", "m", "q", "p")
2265 tg.grepStdout("^m false", "m should not be stale")
2266 tg.grepStdout("^q true", "q should be stale")
2267 tg.grepStdout("^p false", "p should not be stale")
2270 func TestCacheCoverage(t *testing.T) {
2273 if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
2274 t.Skip("GODEBUG gocacheverify")
2280 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
2283 tg.setenv("GOCACHE", tg.path("c1"))
2284 tg.run("test", "-cover", "-short", "strings")
2285 tg.run("test", "-cover", "-short", "math", "strings")
2288 func TestIssue22588(t *testing.T) {
2289 // Don't get confused by stderr coming from tools.
2294 if _, err := os.Stat("/usr/bin/time"); err != nil {
2298 tg.run("list", "-f={{.Stale}}", "runtime")
2299 tg.run("list", "-toolexec=/usr/bin/time", "-f={{.Stale}}", "runtime")
2300 tg.grepStdout("false", "incorrectly reported runtime as stale")
2303 func TestIssue22531(t *testing.T) {
2305 if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
2306 t.Skip("GODEBUG gocacheverify")
2312 tg.setenv("GOPATH", tg.tempdir)
2313 tg.setenv("GOCACHE", tg.path("cache"))
2314 tg.tempFile("src/m/main.go", "package main /* c1 */; func main() {}\n")
2315 tg.run("install", "-x", "m")
2316 tg.run("list", "-f", "{{.Stale}}", "m")
2317 tg.grepStdout("false", "reported m as stale after install")
2318 tg.run("tool", "buildid", tg.path("bin/m"+exeSuffix))
2320 // The link action ID did not include the full main build ID,
2321 // even though the full main build ID is written into the
2322 // eventual binary. That caused the following install to
2323 // be a no-op, thinking the gofmt binary was up-to-date,
2324 // even though .Stale could see it was not.
2325 tg.tempFile("src/m/main.go", "package main /* c2 */; func main() {}\n")
2326 tg.run("install", "-x", "m")
2327 tg.run("list", "-f", "{{.Stale}}", "m")
2328 tg.grepStdout("false", "reported m as stale after reinstall")
2329 tg.run("tool", "buildid", tg.path("bin/m"+exeSuffix))
2332 func TestIssue22596(t *testing.T) {
2334 if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
2335 t.Skip("GODEBUG gocacheverify")
2341 tg.setenv("GOCACHE", tg.path("cache"))
2342 tg.tempFile("gopath1/src/p/p.go", "package p; func F(){}\n")
2343 tg.tempFile("gopath2/src/p/p.go", "package p; func F(){}\n")
2345 tg.setenv("GOPATH", tg.path("gopath1"))
2346 tg.run("list", "-f={{.Target}}", "p")
2347 target1 := strings.TrimSpace(tg.getStdout())
2348 tg.run("install", "p")
2349 tg.wantNotStale("p", "", "p stale after install")
2351 tg.setenv("GOPATH", tg.path("gopath2"))
2352 tg.run("list", "-f={{.Target}}", "p")
2353 target2 := strings.TrimSpace(tg.getStdout())
2354 tg.must(os.MkdirAll(filepath.Dir(target2), 0777))
2355 tg.must(copyFile(target1, target2, 0666))
2356 tg.wantStale("p", "build ID mismatch", "p not stale after copy from gopath1")
2357 tg.run("install", "p")
2358 tg.wantNotStale("p", "", "p stale after install2")
2361 func TestTestCache(t *testing.T) {
2364 if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
2365 t.Skip("GODEBUG gocacheverify")
2371 tg.setenv("GOPATH", tg.tempdir)
2372 tg.setenv("GOCACHE", tg.path("cache"))
2374 // The -p=1 in the commands below just makes the -x output easier to read.
2376 t.Log("\n\nINITIAL\n\n")
2378 tg.tempFile("src/p1/p1.go", "package p1\nvar X = 1\n")
2379 tg.tempFile("src/p2/p2.go", "package p2\nimport _ \"p1\"\nvar X = 1\n")
2380 tg.tempFile("src/t/t1/t1_test.go", "package t\nimport \"testing\"\nfunc Test1(*testing.T) {}\n")
2381 tg.tempFile("src/t/t2/t2_test.go", "package t\nimport _ \"p1\"\nimport \"testing\"\nfunc Test2(*testing.T) {}\n")
2382 tg.tempFile("src/t/t3/t3_test.go", "package t\nimport \"p1\"\nimport \"testing\"\nfunc Test3(t *testing.T) {t.Log(p1.X)}\n")
2383 tg.tempFile("src/t/t4/t4_test.go", "package t\nimport \"p2\"\nimport \"testing\"\nfunc Test4(t *testing.T) {t.Log(p2.X)}")
2384 tg.run("test", "-x", "-v", "-short", "t/...")
2386 t.Log("\n\nREPEAT\n\n")
2388 tg.run("test", "-x", "-v", "-short", "t/...")
2389 tg.grepStdout(`ok \tt/t1\t\(cached\)`, "did not cache t1")
2390 tg.grepStdout(`ok \tt/t2\t\(cached\)`, "did not cache t2")
2391 tg.grepStdout(`ok \tt/t3\t\(cached\)`, "did not cache t3")
2392 tg.grepStdout(`ok \tt/t4\t\(cached\)`, "did not cache t4")
2393 tg.grepStderrNot(`[\\/](compile|gccgo) `, "incorrectly ran compiler")
2394 tg.grepStderrNot(`[\\/](link|gccgo) `, "incorrectly ran linker")
2395 tg.grepStderrNot(`p[0-9]\.test`, "incorrectly ran test")
2397 t.Log("\n\nCOMMENT\n\n")
2399 // Changing the program text without affecting the compiled package
2400 // should result in the package being rebuilt but nothing more.
2401 tg.tempFile("src/p1/p1.go", "package p1\nvar X = 01\n")
2402 tg.run("test", "-p=1", "-x", "-v", "-short", "t/...")
2403 tg.grepStdout(`ok \tt/t1\t\(cached\)`, "did not cache t1")
2404 tg.grepStdout(`ok \tt/t2\t\(cached\)`, "did not cache t2")
2405 tg.grepStdout(`ok \tt/t3\t\(cached\)`, "did not cache t3")
2406 tg.grepStdout(`ok \tt/t4\t\(cached\)`, "did not cache t4")
2407 tg.grepStderrNot(`([\\/](compile|gccgo) ).*t[0-9]_test\.go`, "incorrectly ran compiler")
2408 tg.grepStderrNot(`[\\/](link|gccgo) `, "incorrectly ran linker")
2409 tg.grepStderrNot(`t[0-9]\.test.*test\.short`, "incorrectly ran test")
2411 t.Log("\n\nCHANGE\n\n")
2413 // Changing the actual package should have limited effects.
2414 tg.tempFile("src/p1/p1.go", "package p1\nvar X = 02\n")
2415 tg.run("test", "-p=1", "-x", "-v", "-short", "t/...")
2417 // p2 should have been rebuilt.
2418 tg.grepStderr(`([\\/]compile|gccgo).*p2.go`, "did not recompile p2")
2420 // t1 does not import anything, should not have been rebuilt.
2421 tg.grepStderrNot(`([\\/]compile|gccgo).*t1_test.go`, "incorrectly recompiled t1")
2422 tg.grepStderrNot(`([\\/]link|gccgo).*t1_test`, "incorrectly relinked t1_test")
2423 tg.grepStdout(`ok \tt/t1\t\(cached\)`, "did not cache t/t1")
2425 // t2 imports p1 and must be rebuilt and relinked,
2426 // but the change should not have any effect on the test binary,
2427 // so the test should not have been rerun.
2428 tg.grepStderr(`([\\/]compile|gccgo).*t2_test.go`, "did not recompile t2")
2429 tg.grepStderr(`([\\/]link|gccgo).*t2\.test`, "did not relink t2_test")
2430 // This check does not currently work with gccgo, as garbage
2431 // collection of unused variables is not turned on by default.
2432 if runtime.Compiler != "gccgo" {
2433 tg.grepStdout(`ok \tt/t2\t\(cached\)`, "did not cache t/t2")
2436 // t3 imports p1, and changing X changes t3's test binary.
2437 tg.grepStderr(`([\\/]compile|gccgo).*t3_test.go`, "did not recompile t3")
2438 tg.grepStderr(`([\\/]link|gccgo).*t3\.test`, "did not relink t3_test")
2439 tg.grepStderr(`t3\.test.*-test.short`, "did not rerun t3_test")
2440 tg.grepStdoutNot(`ok \tt/t3\t\(cached\)`, "reported cached t3_test result")
2442 // t4 imports p2, but p2 did not change, so t4 should be relinked, not recompiled,
2444 tg.grepStderrNot(`([\\/]compile|gccgo).*t4_test.go`, "incorrectly recompiled t4")
2445 tg.grepStderr(`([\\/]link|gccgo).*t4\.test`, "did not relink t4_test")
2446 // This check does not currently work with gccgo, as garbage
2447 // collection of unused variables is not turned on by default.
2448 if runtime.Compiler != "gccgo" {
2449 tg.grepStdout(`ok \tt/t4\t\(cached\)`, "did not cache t/t4")
2453 func TestTestSkipVetAfterFailedBuild(t *testing.T) {
2458 tg.tempFile("x_test.go", `package x
2464 tg.runFail("test", tg.path("x_test.go"))
2465 tg.grepStderrNot(`vet`, "vet should be skipped after the failed build")
2468 func TestTestVetRebuild(t *testing.T) {
2474 // golang.org/issue/23701.
2475 // b_test imports b with augmented method from export_test.go.
2476 // b_test also imports a, which imports b.
2477 // Must not accidentally see un-augmented b propagate through a to b_test.
2478 tg.tempFile("src/a/a.go", `package a
2481 func (*Type) M() b.T {return 0}
2483 tg.tempFile("src/b/b.go", `package b
2485 type I interface {M() T}
2487 tg.tempFile("src/b/export_test.go", `package b
2488 func (*T) Method() *T { return nil }
2490 tg.tempFile("src/b/b_test.go", `package b_test
2496 func TestBroken(t *testing.T) {
2503 tg.setenv("GOPATH", tg.path("."))
2508 func TestInstallDeps(t *testing.T) {
2514 tg.setenv("GOPATH", tg.tempdir)
2516 tg.tempFile("src/p1/p1.go", "package p1\nvar X = 1\n")
2517 tg.tempFile("src/p2/p2.go", "package p2\nimport _ \"p1\"\n")
2518 tg.tempFile("src/main1/main.go", "package main\nimport _ \"p2\"\nfunc main() {}\n")
2520 tg.run("list", "-f={{.Target}}", "p1")
2521 p1 := strings.TrimSpace(tg.getStdout())
2522 tg.run("list", "-f={{.Target}}", "p2")
2523 p2 := strings.TrimSpace(tg.getStdout())
2524 tg.run("list", "-f={{.Target}}", "main1")
2525 main1 := strings.TrimSpace(tg.getStdout())
2527 tg.run("install", "main1")
2533 tg.run("install", "p2")
2537 // don't let install -i overwrite runtime
2538 tg.wantNotStale("runtime", "", "must be non-stale before install -i")
2540 tg.run("install", "-i", "main1")
2542 tg.must(os.Remove(p1))
2544 tg.run("install", "-i", "p2")
2549 func TestImportPath(t *testing.T) {
2555 tg.tempFile("src/a/a.go", `
2569 tg.tempFile("src/a/a_test.go", `
2577 func TestV(t *testing.T) {
2583 tg.tempFile("src/a/p-1.0/p.go", `
2591 tg.setenv("GOPATH", tg.path("."))
2592 tg.run("build", "-o", tg.path("a.exe"), "a")
2596 func TestBadCommandLines(t *testing.T) {
2601 tg.tempFile("src/x/x.go", "package x\n")
2602 tg.setenv("GOPATH", tg.path("."))
2604 tg.run("build", "x")
2606 tg.tempFile("src/x/@y.go", "package x\n")
2607 tg.runFail("build", "x")
2608 tg.grepStderr("invalid input file name \"@y.go\"", "did not reject @y.go")
2609 tg.must(os.Remove(tg.path("src/x/@y.go")))
2611 tg.tempFile("src/x/-y.go", "package x\n")
2612 tg.runFail("build", "x")
2613 tg.grepStderr("invalid input file name \"-y.go\"", "did not reject -y.go")
2614 tg.must(os.Remove(tg.path("src/x/-y.go")))
2616 if runtime.Compiler == "gccgo" {
2617 tg.runFail("build", "-gccgoflags=all=@x", "x")
2619 tg.runFail("build", "-gcflags=all=@x", "x")
2621 tg.grepStderr("invalid command-line argument @x in command", "did not reject @x during exec")
2623 tg.tempFile("src/@x/x.go", "package x\n")
2624 tg.setenv("GOPATH", tg.path("."))
2625 tg.runFail("build", "@x")
2626 tg.grepStderr("invalid input directory name \"@x\"|cannot use path@version syntax", "did not reject @x directory")
2628 tg.tempFile("src/@x/y/y.go", "package y\n")
2629 tg.setenv("GOPATH", tg.path("."))
2630 tg.runFail("build", "@x/y")
2631 tg.grepStderr("invalid import path \"@x/y\"|cannot use path@version syntax", "did not reject @x/y import path")
2633 tg.tempFile("src/-x/x.go", "package x\n")
2634 tg.setenv("GOPATH", tg.path("."))
2635 tg.runFail("build", "--", "-x")
2636 tg.grepStderr("invalid import path \"-x\"", "did not reject -x import path")
2638 tg.tempFile("src/-x/y/y.go", "package y\n")
2639 tg.setenv("GOPATH", tg.path("."))
2640 tg.runFail("build", "--", "-x/y")
2641 tg.grepStderr("invalid import path \"-x/y\"", "did not reject -x/y import path")
2644 func TestTwoPkgConfigs(t *testing.T) {
2648 if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
2649 t.Skipf("no shell scripts on %s", runtime.GOOS)
2655 tg.tempFile("src/x/a.go", `package x
2656 // #cgo pkg-config: --static a
2659 tg.tempFile("src/x/b.go", `package x
2660 // #cgo pkg-config: --static a
2663 tg.tempFile("pkg-config.sh", `#!/bin/sh
2664 echo $* >>`+tg.path("pkg-config.out"))
2665 tg.must(os.Chmod(tg.path("pkg-config.sh"), 0755))
2666 tg.setenv("GOPATH", tg.path("."))
2667 tg.setenv("PKG_CONFIG", tg.path("pkg-config.sh"))
2668 tg.run("build", "x")
2669 out, err := ioutil.ReadFile(tg.path("pkg-config.out"))
2671 out = bytes.TrimSpace(out)
2672 want := "--cflags --static --static -- a a\n--libs --static --static -- a a"
2673 if !bytes.Equal(out, []byte(want)) {
2674 t.Errorf("got %q want %q", out, want)
2678 func TestCgoCache(t *testing.T) {
2687 tg.tempFile("src/x/a.go", `package main
2694 func main() { fmt.Println(C.val) }
2696 tg.setenv("GOPATH", tg.path("."))
2697 exe := tg.path("x.exe")
2698 tg.run("build", "-o", exe, "x")
2699 tg.setenv("CGO_LDFLAGS", "-lnosuchlibraryexists")
2700 tg.runFail("build", "-o", exe, "x")
2701 tg.grepStderr(`nosuchlibraryexists`, "did not run linker with changed CGO_LDFLAGS")
2705 func TestFilepathUnderCwdFormat(t *testing.T) {
2709 tg.run("test", "-x", "-cover", "log")
2710 tg.grepStderrNot(`\.log\.cover\.go`, "-x output should contain correctly formatted filepath under cwd")
2714 func TestDontReportRemoveOfEmptyDir(t *testing.T) {
2718 tg.tempFile("src/a/a.go", `package a`)
2719 tg.setenv("GOPATH", tg.path("."))
2720 tg.run("install", "-x", "a")
2721 tg.run("install", "-x", "a")
2722 // The second install should have printed only a WORK= line,
2724 if bytes.Count(tg.stdout.Bytes(), []byte{'\n'})+bytes.Count(tg.stderr.Bytes(), []byte{'\n'}) > 1 {
2725 t.Error("unnecessary output when installing installed package")
2730 func TestLinkerTmpDirIsDeleted(t *testing.T) {
2731 skipIfGccgo(t, "gccgo does not use cmd/link")
2733 t.Skip("skipping because cgo not enabled")
2740 tg.tempFile("a.go", `package main; import "C"; func main() {}`)
2741 tg.run("build", "-ldflags", "-v", "-o", os.DevNull, tg.path("a.go"))
2742 // Find line that has "host link:" in linker output.
2743 stderr := tg.getStderr()
2744 var hostLinkLine string
2745 for _, line := range strings.Split(stderr, "\n") {
2746 if !strings.Contains(line, "host link:") {
2752 if hostLinkLine == "" {
2753 t.Fatal(`fail to find with "host link:" string in linker output`)
2755 // Find parameter, like "/tmp/go-link-408556474/go.o" inside of
2756 // "host link:" line, and extract temp directory /tmp/go-link-408556474
2758 tmpdir := hostLinkLine
2759 i := strings.Index(tmpdir, `go.o"`)
2761 t.Fatalf(`fail to find "go.o" in "host link:" line %q`, hostLinkLine)
2763 tmpdir = tmpdir[:i-1]
2764 i = strings.LastIndex(tmpdir, `"`)
2766 t.Fatalf(`fail to find " in "host link:" line %q`, hostLinkLine)
2768 tmpdir = tmpdir[i+1:]
2769 // Verify that temp directory has been removed.
2770 _, err := os.Stat(tmpdir)
2772 t.Fatalf("temp directory %q has not been removed", tmpdir)
2774 if !os.IsNotExist(err) {
2775 t.Fatalf("Stat(%q) returns unexpected error: %v", tmpdir, err)
2780 func TestCoverpkgTestOnly(t *testing.T) {
2781 skipIfGccgo(t, "gccgo has no cover tool")
2786 tg.tempFile("src/a/a.go", `package a
2790 tg.tempFile("src/atest/a_test.go", `
2792 import ( "a"; "testing" )
2793 func TestF(t *testing.T) { a.F(2) }
2795 tg.setenv("GOPATH", tg.path("."))
2796 tg.run("test", "-coverpkg=a", "atest")
2797 tg.grepStderrNot("no packages being tested depend on matches", "bad match message")
2798 tg.grepStdout("coverage: 100", "no coverage")