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.
31 "cmd/go/internal/cache"
33 "cmd/go/internal/robustio"
34 "cmd/go/internal/work"
39 // GOVCS defaults to public:git|hg,private:all,
40 // which breaks many tests here - they can't use non-git, non-hg VCS at all!
41 // Change to fully permissive.
42 // The tests of the GOVCS setting itself are in ../../testdata/script/govcs.txt.
43 os.Setenv("GOVCS", "*:all")
47 canRace = false // whether we can run the race detector
48 canCgo = false // whether we can use cgo
49 canMSan = false // whether we can run the memory sanitizer
52 var exeSuffix string = func() string {
53 if runtime.GOOS == "windows" {
59 func tooSlow(t *testing.T) {
61 // In -short mode; skip test, except run it on the {darwin,linux,windows}/amd64 builders.
62 if testenv.Builder() != "" && runtime.GOARCH == "amd64" && (runtime.GOOS == "linux" || runtime.GOOS == "darwin" || runtime.GOOS == "windows") {
66 t.Skip("skipping test in -short mode")
70 // testGOROOT is the GOROOT to use when running testgo, a cmd/go binary
71 // build from this process's current GOROOT, but run from a different
75 var testGOCACHE string
81 // The TestMain function creates a go command for testing purposes and
82 // deletes it after the tests have been run.
83 func TestMain(m *testing.M) {
84 // $GO_GCFLAGS a compiler debug flag known to cmd/dist, make.bash, etc.
85 // It is not a standard go command flag; use os.Getenv, not cfg.Getenv.
86 if os.Getenv("GO_GCFLAGS") != "" {
87 fmt.Fprintf(os.Stderr, "testing: warning: no tests to run\n") // magic string for cmd/go
88 fmt.Printf("cmd/go test is not compatible with $GO_GCFLAGS being set\n")
100 // Run with a temporary TMPDIR to check that the tests don't
101 // leave anything behind.
102 topTmpdir, err := os.MkdirTemp("", "cmd-go-test-")
107 defer removeAll(topTmpdir)
109 os.Setenv(tempEnvName(), topTmpdir)
111 dir, err := os.MkdirTemp(topTmpdir, "tmpdir")
117 defer removeAll(testTmpDir)
120 testGOCACHE = cache.DefaultDir()
121 if testenv.HasGoBuild() {
122 testBin = filepath.Join(testTmpDir, "testbin")
123 if err := os.Mkdir(testBin, 0777); err != nil {
126 testGo = filepath.Join(testBin, "go"+exeSuffix)
127 args := []string{"build", "-tags", "testgo", "-o", testGo}
129 args = append(args, "-race")
131 gotool, err := testenv.GoTool()
133 fmt.Fprintln(os.Stderr, err)
137 goEnv := func(name string) string {
138 out, err := exec.Command(gotool, "env", name).CombinedOutput()
140 fmt.Fprintf(os.Stderr, "go env %s: %v\n%s", name, err, out)
143 return strings.TrimSpace(string(out))
145 testGOROOT = goEnv("GOROOT")
146 os.Setenv("TESTGO_GOROOT", testGOROOT)
147 // Ensure that GOROOT is set explicitly.
148 // Otherwise, if the toolchain was built with GOROOT_FINAL set but has not
149 // yet been moved to its final location, programs that invoke runtime.GOROOT
150 // may accidentally use the wrong path.
151 os.Setenv("GOROOT", testGOROOT)
153 // The whole GOROOT/pkg tree was installed using the GOHOSTOS/GOHOSTARCH
154 // toolchain (installed in GOROOT/pkg/tool/GOHOSTOS_GOHOSTARCH).
155 // The testgo.exe we are about to create will be built for GOOS/GOARCH,
156 // which means it will use the GOOS/GOARCH toolchain
157 // (installed in GOROOT/pkg/tool/GOOS_GOARCH).
158 // If these are not the same toolchain, then the entire standard library
159 // will look out of date (the compilers in those two different tool directories
160 // are built for different architectures and have different build IDs),
161 // which will cause many tests to do unnecessary rebuilds and some
162 // tests to attempt to overwrite the installed standard library.
163 // Bail out entirely in this case.
164 hostGOOS := goEnv("GOHOSTOS")
165 hostGOARCH := goEnv("GOHOSTARCH")
166 if hostGOOS != runtime.GOOS || hostGOARCH != runtime.GOARCH {
167 fmt.Fprintf(os.Stderr, "testing: warning: no tests to run\n") // magic string for cmd/go
168 fmt.Printf("cmd/go test is not compatible with GOOS/GOARCH != GOHOSTOS/GOHOSTARCH (%s/%s != %s/%s)\n", runtime.GOOS, runtime.GOARCH, hostGOOS, hostGOARCH)
173 buildCmd := exec.Command(gotool, args...)
174 buildCmd.Env = append(os.Environ(), "GOFLAGS=-mod=vendor")
175 out, err := buildCmd.CombinedOutput()
177 fmt.Fprintf(os.Stderr, "building testgo failed: %v\n%s", err, out)
181 cmd := exec.Command(testGo, "env", "CGO_ENABLED")
182 cmd.Stderr = new(strings.Builder)
183 if out, err := cmd.Output(); err != nil {
184 fmt.Fprintf(os.Stderr, "running testgo failed: %v\n%s", err, cmd.Stderr)
187 canCgo, err = strconv.ParseBool(strings.TrimSpace(string(out)))
189 fmt.Fprintf(os.Stderr, "can't parse go env CGO_ENABLED output: %v\n", strings.TrimSpace(string(out)))
193 out, err = exec.Command(gotool, "env", "GOCACHE").CombinedOutput()
195 fmt.Fprintf(os.Stderr, "could not find testing GOCACHE: %v\n%s", err, out)
198 testGOCACHE = strings.TrimSpace(string(out))
200 canMSan = canCgo && sys.MSanSupported(runtime.GOOS, runtime.GOARCH)
201 canRace = canCgo && sys.RaceDetectorSupported(runtime.GOOS, runtime.GOARCH)
202 // The race detector doesn't work on Alpine Linux:
203 // golang.org/issue/14481
204 // gccgo does not support the race detector.
205 if isAlpineLinux() || runtime.Compiler == "gccgo" {
209 // Don't let these environment variables confuse the test.
210 os.Setenv("GOENV", "off")
211 os.Unsetenv("GOFLAGS")
213 os.Unsetenv("GOPATH")
214 os.Unsetenv("GIT_ALLOW_PROTOCOL")
215 os.Setenv("HOME", "/test-go-home-does-not-exist")
216 // On some systems the default C compiler is ccache.
217 // Setting HOME to a non-existent directory will break
218 // those systems. Disable ccache and use real compiler. Issue 17668.
219 os.Setenv("CCACHE_DISABLE", "1")
220 if cfg.Getenv("GOCACHE") == "" {
221 os.Setenv("GOCACHE", testGOCACHE) // because $HOME is gone
226 removeAll(testTmpDir) // os.Exit won't run defer
230 // There shouldn't be anything left in topTmpdir.
231 dirf, err := os.Open(topTmpdir)
235 names, err := dirf.Readdirnames(0)
240 log.Fatalf("unexpected files left in tmpdir: %v", names)
249 func isAlpineLinux() bool {
250 if runtime.GOOS != "linux" {
253 fi, err := os.Lstat("/etc/alpine-release")
254 return err == nil && fi.Mode().IsRegular()
257 // The length of an mtime tick on this system. This is an estimate of
258 // how long we need to sleep to ensure that the mtime of two files is
260 // We used to try to be clever but that didn't always work (see golang.org/issue/12205).
261 var mtimeTick time.Duration = 1 * time.Second
263 // Manage a single run of the testgo binary.
264 type testgoData struct {
271 stdout, stderr bytes.Buffer
272 execDir string // dir for tg.run
275 // skipIfGccgo skips the test if using gccgo.
276 func skipIfGccgo(t *testing.T, msg string) {
277 if runtime.Compiler == "gccgo" {
278 t.Skipf("skipping test not supported on gccgo: %s", msg)
282 // testgo sets up for a test that runs testgo.
283 func testgo(t *testing.T) *testgoData {
285 testenv.MustHaveGoBuild(t)
286 testenv.SkipIfShortAndSlow(t)
288 return &testgoData{t: t}
291 // must gives a fatal error if err is not nil.
292 func (tg *testgoData) must(err error) {
299 // check gives a test non-fatal error if err is not nil.
300 func (tg *testgoData) check(err error) {
307 // parallel runs the test in parallel by calling t.Parallel.
308 func (tg *testgoData) parallel() {
311 tg.t.Fatal("internal testsuite error: call to parallel after run")
313 for _, e := range tg.env {
314 if strings.HasPrefix(e, "GOROOT=") || strings.HasPrefix(e, "GOPATH=") || strings.HasPrefix(e, "GOBIN=") {
315 val := e[strings.Index(e, "=")+1:]
316 if strings.HasPrefix(val, "testdata") || strings.HasPrefix(val, "./testdata") {
317 tg.t.Fatalf("internal testsuite error: call to parallel with testdata in environment (%s)", e)
325 // pwd returns the current directory.
326 func (tg *testgoData) pwd() string {
328 wd, err := os.Getwd()
330 tg.t.Fatalf("could not get working directory: %v", err)
335 // sleep sleeps for one tick, where a tick is a conservative estimate
336 // of how long it takes for a file modification to get a different
338 func (tg *testgoData) sleep() {
339 time.Sleep(mtimeTick)
342 // setenv sets an environment variable to use when running the test go
344 func (tg *testgoData) setenv(name, val string) {
346 if tg.inParallel && (name == "GOROOT" || name == "GOPATH" || name == "GOBIN") && (strings.HasPrefix(val, "testdata") || strings.HasPrefix(val, "./testdata")) {
347 tg.t.Fatalf("internal testsuite error: call to setenv with testdata (%s=%s) after parallel", name, val)
350 tg.env = append(tg.env, name+"="+val)
353 // unsetenv removes an environment variable.
354 func (tg *testgoData) unsetenv(name string) {
356 tg.env = append([]string(nil), os.Environ()...)
357 tg.env = append(tg.env, "GO111MODULE=off")
359 for i, v := range tg.env {
360 if strings.HasPrefix(v, name+"=") {
361 tg.env = append(tg.env[:i], tg.env[i+1:]...)
367 func (tg *testgoData) goTool() string {
371 // doRun runs the test go command, recording stdout and stderr and
372 // returning exit status.
373 func (tg *testgoData) doRun(args []string) error {
376 for _, arg := range args {
377 if strings.HasPrefix(arg, "testdata") || strings.HasPrefix(arg, "./testdata") {
378 tg.t.Fatal("internal testsuite error: parallel run using testdata")
384 for _, v := range tg.env {
385 if strings.HasPrefix(v, "GOROOT=") {
392 tg.setenv("GOROOT", testGOROOT)
395 tg.t.Logf("running testgo %v", args)
396 cmd := exec.Command(prog, args...)
400 cmd.Stdout = &tg.stdout
401 cmd.Stderr = &tg.stderr
404 if tg.stdout.Len() > 0 {
405 tg.t.Log("standard output:")
406 tg.t.Log(tg.stdout.String())
408 if tg.stderr.Len() > 0 {
409 tg.t.Log("standard error:")
410 tg.t.Log(tg.stderr.String())
416 // run runs the test go command, and expects it to succeed.
417 func (tg *testgoData) run(args ...string) {
419 if status := tg.doRun(args); status != nil {
421 tg.t.Logf("go %v failed unexpectedly in %s: %v", args, wd, status)
426 // runFail runs the test go command, and expects it to fail.
427 func (tg *testgoData) runFail(args ...string) {
429 if status := tg.doRun(args); status == nil {
430 tg.t.Fatal("testgo succeeded unexpectedly")
432 tg.t.Log("testgo failed as expected:", status)
436 // runGit runs a git command, and expects it to succeed.
437 func (tg *testgoData) runGit(dir string, args ...string) {
439 cmd := exec.Command("git", args...)
442 cmd.Stdout = &tg.stdout
443 cmd.Stderr = &tg.stderr
447 if tg.stdout.Len() > 0 {
448 tg.t.Log("git standard output:")
449 tg.t.Log(tg.stdout.String())
451 if tg.stderr.Len() > 0 {
452 tg.t.Log("git standard error:")
453 tg.t.Log(tg.stderr.String())
456 tg.t.Logf("git %v failed unexpectedly: %v", args, status)
461 // getStdout returns standard output of the testgo run as a string.
462 func (tg *testgoData) getStdout() string {
465 tg.t.Fatal("internal testsuite error: stdout called before run")
467 return tg.stdout.String()
470 // getStderr returns standard error of the testgo run as a string.
471 func (tg *testgoData) getStderr() string {
474 tg.t.Fatal("internal testsuite error: stdout called before run")
476 return tg.stderr.String()
479 // doGrepMatch looks for a regular expression in a buffer, and returns
480 // whether it is found. The regular expression is matched against
481 // each line separately, as with the grep command.
482 func (tg *testgoData) doGrepMatch(match string, b *bytes.Buffer) bool {
485 tg.t.Fatal("internal testsuite error: grep called before run")
487 re := regexp.MustCompile(match)
488 for _, ln := range bytes.Split(b.Bytes(), []byte{'\n'}) {
496 // doGrep looks for a regular expression in a buffer and fails if it
497 // is not found. The name argument is the name of the output we are
498 // searching, "output" or "error". The msg argument is logged on
500 func (tg *testgoData) doGrep(match string, b *bytes.Buffer, name, msg string) {
502 if !tg.doGrepMatch(match, b) {
504 tg.t.Logf("pattern %v not found in standard %s", match, name)
509 // grepStdout looks for a regular expression in the test run's
510 // standard output and fails, logging msg, if it is not found.
511 func (tg *testgoData) grepStdout(match, msg string) {
513 tg.doGrep(match, &tg.stdout, "output", msg)
516 // grepStderr looks for a regular expression in the test run's
517 // standard error and fails, logging msg, if it is not found.
518 func (tg *testgoData) grepStderr(match, msg string) {
520 tg.doGrep(match, &tg.stderr, "error", msg)
523 // grepBoth looks for a regular expression in the test run's standard
524 // output or stand error and fails, logging msg, if it is not found.
525 func (tg *testgoData) grepBoth(match, msg string) {
527 if !tg.doGrepMatch(match, &tg.stdout) && !tg.doGrepMatch(match, &tg.stderr) {
529 tg.t.Logf("pattern %v not found in standard output or standard error", match)
534 // doGrepNot looks for a regular expression in a buffer and fails if
535 // it is found. The name and msg arguments are as for doGrep.
536 func (tg *testgoData) doGrepNot(match string, b *bytes.Buffer, name, msg string) {
538 if tg.doGrepMatch(match, b) {
540 tg.t.Logf("pattern %v found unexpectedly in standard %s", match, name)
545 // grepStdoutNot looks for a regular expression in the test run's
546 // standard output and fails, logging msg, if it is found.
547 func (tg *testgoData) grepStdoutNot(match, msg string) {
549 tg.doGrepNot(match, &tg.stdout, "output", msg)
552 // grepStderrNot looks for a regular expression in the test run's
553 // standard error and fails, logging msg, if it is found.
554 func (tg *testgoData) grepStderrNot(match, msg string) {
556 tg.doGrepNot(match, &tg.stderr, "error", msg)
559 // grepBothNot looks for a regular expression in the test run's
560 // standard output or standard error and fails, logging msg, if it is
562 func (tg *testgoData) grepBothNot(match, msg string) {
564 if tg.doGrepMatch(match, &tg.stdout) || tg.doGrepMatch(match, &tg.stderr) {
566 tg.t.Fatalf("pattern %v found unexpectedly in standard output or standard error", match)
570 // doGrepCount counts the number of times a regexp is seen in a buffer.
571 func (tg *testgoData) doGrepCount(match string, b *bytes.Buffer) int {
574 tg.t.Fatal("internal testsuite error: doGrepCount called before run")
576 re := regexp.MustCompile(match)
578 for _, ln := range bytes.Split(b.Bytes(), []byte{'\n'}) {
586 // grepCountBoth returns the number of times a regexp is seen in both
587 // standard output and standard error.
588 func (tg *testgoData) grepCountBoth(match string) int {
590 return tg.doGrepCount(match, &tg.stdout) + tg.doGrepCount(match, &tg.stderr)
593 // creatingTemp records that the test plans to create a temporary file
594 // or directory. If the file or directory exists already, it will be
595 // removed. When the test completes, the file or directory will be
596 // removed if it exists.
597 func (tg *testgoData) creatingTemp(path string) {
599 if filepath.IsAbs(path) && !strings.HasPrefix(path, tg.tempdir) {
600 tg.t.Fatalf("internal testsuite error: creatingTemp(%q) with absolute path not in temporary directory", path)
602 tg.must(robustio.RemoveAll(path))
603 tg.temps = append(tg.temps, path)
606 // makeTempdir makes a temporary directory for a run of testgo. If
607 // the temporary directory was already created, this does nothing.
608 func (tg *testgoData) makeTempdir() {
610 if tg.tempdir == "" {
612 tg.tempdir, err = os.MkdirTemp("", "gotest")
617 // tempFile adds a temporary file for a run of testgo.
618 func (tg *testgoData) tempFile(path, contents string) {
621 tg.must(os.MkdirAll(filepath.Join(tg.tempdir, filepath.Dir(path)), 0755))
622 bytes := []byte(contents)
623 if strings.HasSuffix(path, ".go") {
624 formatted, err := format.Source(bytes)
629 tg.must(os.WriteFile(filepath.Join(tg.tempdir, path), bytes, 0644))
632 // tempDir adds a temporary directory for a run of testgo.
633 func (tg *testgoData) tempDir(path string) {
636 if err := os.MkdirAll(filepath.Join(tg.tempdir, path), 0755); err != nil && !os.IsExist(err) {
641 // path returns the absolute pathname to file with the temporary
643 func (tg *testgoData) path(name string) string {
645 if tg.tempdir == "" {
646 tg.t.Fatalf("internal testsuite error: path(%q) with no tempdir", name)
651 return filepath.Join(tg.tempdir, name)
654 // mustExist fails if path does not exist.
655 func (tg *testgoData) mustExist(path string) {
657 if _, err := os.Stat(path); err != nil {
658 if os.IsNotExist(err) {
659 tg.t.Fatalf("%s does not exist but should", path)
661 tg.t.Fatalf("%s stat failed: %v", path, err)
665 // mustNotExist fails if path exists.
666 func (tg *testgoData) mustNotExist(path string) {
668 if _, err := os.Stat(path); err == nil || !os.IsNotExist(err) {
669 tg.t.Fatalf("%s exists but should not (%v)", path, err)
673 // mustHaveContent succeeds if filePath is a path to a file,
674 // and that file is readable and not empty.
675 func (tg *testgoData) mustHaveContent(filePath string) {
676 tg.mustExist(filePath)
677 f, err := os.Stat(filePath)
682 tg.t.Fatalf("expected %s to have data, but is empty", filePath)
686 // wantExecutable fails with msg if path is not executable.
687 func (tg *testgoData) wantExecutable(path, msg string) {
689 if st, err := os.Stat(path); err != nil {
690 if !os.IsNotExist(err) {
695 if runtime.GOOS != "windows" && st.Mode()&0111 == 0 {
696 tg.t.Fatalf("binary %s exists but is not executable", path)
701 // isStale reports whether pkg is stale, and why
702 func (tg *testgoData) isStale(pkg string) (bool, string) {
704 tg.run("list", "-f", "{{.Stale}}:{{.StaleReason}}", pkg)
705 v := strings.TrimSpace(tg.getStdout())
706 f := strings.SplitN(v, ":", 2)
715 tg.t.Fatalf("unexpected output checking staleness of package %v: %v", pkg, v)
719 // wantStale fails with msg if pkg is not stale.
720 func (tg *testgoData) wantStale(pkg, reason, msg string) {
722 stale, why := tg.isStale(pkg)
726 // We always accept the reason as being "not installed but
727 // available in build cache", because when that is the case go
728 // list doesn't try to sort out the underlying reason why the
729 // package is not installed.
730 if reason == "" && why != "" || !strings.Contains(why, reason) && !strings.Contains(why, "not installed but available in build cache") {
731 tg.t.Errorf("wrong reason for Stale=true: %q, want %q", why, reason)
735 // wantNotStale fails with msg if pkg is stale.
736 func (tg *testgoData) wantNotStale(pkg, reason, msg string) {
738 stale, why := tg.isStale(pkg)
742 if reason == "" && why != "" || !strings.Contains(why, reason) {
743 tg.t.Errorf("wrong reason for Stale=false: %q, want %q", why, reason)
747 // If -testwork is specified, the test prints the name of the temp directory
748 // and does not remove it when done, so that a programmer can
749 // poke at the test file tree afterward.
750 var testWork = flag.Bool("testwork", false, "")
752 // cleanup cleans up a test that runs testgo.
753 func (tg *testgoData) cleanup() {
756 tg.t.Logf("TESTWORK=%s\n", tg.path("."))
759 for _, path := range tg.temps {
760 tg.check(removeAll(path))
762 if tg.tempdir != "" {
763 tg.check(removeAll(tg.tempdir))
767 func removeAll(dir string) error {
768 // module cache has 0444 directories;
769 // make them writable in order to remove content.
770 filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error {
771 // chmod not only directories, but also things that we couldn't even stat
772 // due to permission errors: they may also be unreadable directories.
773 if err != nil || info.IsDir() {
778 return robustio.RemoveAll(dir)
781 // failSSH puts an ssh executable in the PATH that always fails.
782 // This is to stub out uses of ssh by go get.
783 func (tg *testgoData) failSSH() {
785 wd, err := os.Getwd()
789 fail := filepath.Join(wd, "testdata/failssh")
790 tg.setenv("PATH", fmt.Sprintf("%v%c%v", fail, filepath.ListSeparator, os.Getenv("PATH")))
793 func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) {
795 t.Skip("skipping lengthy test in short mode")
802 // Copy the runtime packages into a temporary GOROOT
803 // so that we can change files.
804 for _, copydir := range []string{
807 "src/internal/bytealg",
809 "src/internal/goarch",
810 "src/internal/goexperiment",
814 filepath.Join("pkg", runtime.GOOS+"_"+runtime.GOARCH),
815 filepath.Join("pkg/tool", runtime.GOOS+"_"+runtime.GOARCH),
818 srcdir := filepath.Join(testGOROOT, copydir)
819 tg.tempDir(filepath.Join("goroot", copydir))
820 err := filepath.WalkDir(srcdir,
821 func(path string, info fs.DirEntry, err error) error {
828 srcrel, err := filepath.Rel(srcdir, path)
832 dest := filepath.Join("goroot", copydir, srcrel)
833 data, err := os.ReadFile(path)
837 tg.tempFile(dest, string(data))
838 if strings.Contains(copydir, filepath.Join("pkg", "tool")) {
839 os.Chmod(tg.path(dest), 0777)
847 tg.setenv("GOROOT", tg.path("goroot"))
849 addVar := func(name string, idx int) (restore func()) {
850 data, err := os.ReadFile(name)
855 data = append(data, fmt.Sprintf("var DummyUnusedVar%d bool\n", idx)...)
856 if err := os.WriteFile(name, append(data, '\n'), 0666); err != nil {
861 if err := os.WriteFile(name, old, 0666); err != nil {
867 // Every main package depends on the "runtime".
868 tg.tempFile("d1/src/p1/p1.go", `package main; func main(){}`)
869 tg.setenv("GOPATH", tg.path("d1"))
870 // Pass -i flag to rebuild everything outdated.
871 tg.run("install", "-i", "p1")
872 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, before any changes")
874 // Changing mtime of runtime/internal/sys/sys.go
875 // should have no effect: only the content matters.
876 // In fact this should be true even outside a release branch.
877 sys := tg.path("goroot/src/runtime/internal/sys/sys.go")
879 restore := addVar(sys, 0)
881 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, after updating mtime of runtime/internal/sys/sys.go")
883 // But changing content of any file should have an effect.
884 // Previously zversion.go was the only one that mattered;
885 // now they all matter, so keep using sys.go.
886 restore = addVar(sys, 1)
888 tg.wantStale("p1", "stale dependency: runtime/internal/sys", "./testgo list claims p1 is NOT stale, incorrectly, after changing sys.go")
890 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, after changing back to old release")
892 tg.wantStale("p1", "stale dependency: runtime", "./testgo list claims p1 is NOT stale, incorrectly, after changing sys.go again")
893 tg.run("install", "-i", "p1")
894 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after building with new release")
896 // Restore to "old" release.
898 tg.wantStale("p1", "stale dependency: runtime/internal/sys", "./testgo list claims p1 is NOT stale, incorrectly, after restoring sys.go")
899 tg.run("install", "-i", "p1")
900 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after building with old release")
903 // cmd/go: custom import path checking should not apply to Go packages without import comment.
904 func TestIssue10952(t *testing.T) {
905 testenv.MustHaveExternalNetwork(t)
906 testenv.MustHaveExecPath(t, "git")
912 tg.setenv("GOPATH", tg.path("."))
913 const importPath = "github.com/zombiezen/go-get-issue-10952"
914 tg.run("get", "-d", "-u", importPath)
915 repoDir := tg.path("src/" + importPath)
916 tg.runGit(repoDir, "remote", "set-url", "origin", "https://"+importPath+".git")
917 tg.run("get", "-d", "-u", importPath)
920 func TestIssue16471(t *testing.T) {
921 testenv.MustHaveExternalNetwork(t)
922 testenv.MustHaveExecPath(t, "git")
928 tg.setenv("GOPATH", tg.path("."))
929 tg.must(os.MkdirAll(tg.path("src/rsc.io/go-get-issue-10952"), 0755))
930 tg.runGit(tg.path("src/rsc.io"), "clone", "https://github.com/zombiezen/go-get-issue-10952")
931 tg.runFail("get", "-u", "rsc.io/go-get-issue-10952")
932 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")
935 // Test git clone URL that uses SCP-like syntax and custom import path checking.
936 func TestIssue11457(t *testing.T) {
937 testenv.MustHaveExternalNetwork(t)
938 testenv.MustHaveExecPath(t, "git")
944 tg.setenv("GOPATH", tg.path("."))
945 const importPath = "rsc.io/go-get-issue-11457"
946 tg.run("get", "-d", "-u", importPath)
947 repoDir := tg.path("src/" + importPath)
948 tg.runGit(repoDir, "remote", "set-url", "origin", "git@github.com:rsc/go-get-issue-11457")
950 // At this time, custom import path checking compares remotes verbatim (rather than
951 // just the host and path, skipping scheme and user), so we expect go get -u to fail.
952 // However, the goal of this test is to verify that gitRemoteRepo correctly parsed
953 // the SCP-like syntax, and we expect it to appear in the error message.
954 tg.runFail("get", "-d", "-u", importPath)
955 want := " is checked out from ssh://git@github.com/rsc/go-get-issue-11457"
956 if !strings.HasSuffix(strings.TrimSpace(tg.getStderr()), want) {
957 t.Error("expected clone URL to appear in stderr")
961 func TestGetGitDefaultBranch(t *testing.T) {
962 testenv.MustHaveExternalNetwork(t)
963 testenv.MustHaveExecPath(t, "git")
969 tg.setenv("GOPATH", tg.path("."))
971 // This repo has two branches, master and another-branch.
972 // The another-branch is the default that you get from 'git clone'.
973 // The go get command variants should not override this.
974 const importPath = "github.com/rsc/go-get-default-branch"
976 tg.run("get", "-d", importPath)
977 repoDir := tg.path("src/" + importPath)
978 tg.runGit(repoDir, "branch", "--contains", "HEAD")
979 tg.grepStdout(`\* another-branch`, "not on correct default branch")
981 tg.run("get", "-d", "-u", importPath)
982 tg.runGit(repoDir, "branch", "--contains", "HEAD")
983 tg.grepStdout(`\* another-branch`, "not on correct default branch")
986 // Security issue. Don't disable. See golang.org/issue/22125.
987 func TestAccidentalGitCheckout(t *testing.T) {
988 testenv.MustHaveExternalNetwork(t)
989 testenv.MustHaveExecPath(t, "git")
990 testenv.MustHaveExecPath(t, "svn")
997 tg.setenv("GOPATH", tg.path("."))
999 tg.runFail("get", "-u", "vcs-test.golang.org/go/test1-svn-git")
1000 tg.grepStderr("src[\\\\/]vcs-test.* uses git, but parent .*src[\\\\/]vcs-test.* uses svn", "get did not fail for right reason")
1002 if _, err := os.Stat(tg.path("SrC")); err == nil {
1003 // This case only triggers on a case-insensitive file system.
1004 tg.runFail("get", "-u", "vcs-test.golang.org/go/test2-svn-git/test2main")
1005 tg.grepStderr("src[\\\\/]vcs-test.* uses git, but parent .*src[\\\\/]vcs-test.* uses svn", "get did not fail for right reason")
1009 func TestPackageMainTestCompilerFlags(t *testing.T) {
1014 tg.setenv("GOPATH", tg.path("."))
1015 tg.tempFile("src/p1/p1.go", "package main\n")
1016 tg.tempFile("src/p1/p1_test.go", "package main\nimport \"testing\"\nfunc Test(t *testing.T){}\n")
1017 tg.run("test", "-c", "-n", "p1")
1018 tg.grepBothNot(`([\\/]compile|gccgo).* (-p main|-fgo-pkgpath=main).*p1\.go`, "should not have run compile -p main p1.go")
1019 tg.grepStderr(`([\\/]compile|gccgo).* (-p p1|-fgo-pkgpath=p1).*p1\.go`, "should have run compile -p p1 p1.go")
1023 func TestGoTestWithPackageListedMultipleTimes(t *testing.T) {
1028 tg.run("test", "errors", "errors", "errors", "errors", "errors")
1029 if strings.Contains(strings.TrimSpace(tg.getStdout()), "\n") {
1030 t.Error("go test errors errors errors errors errors tested the same package multiple times")
1034 func TestGoListHasAConsistentOrder(t *testing.T) {
1039 tg.run("list", "std")
1040 first := tg.getStdout()
1041 tg.run("list", "std")
1042 if first != tg.getStdout() {
1043 t.Error("go list std ordering is inconsistent")
1047 func TestGoListStdDoesNotIncludeCommands(t *testing.T) {
1052 tg.run("list", "std")
1053 tg.grepStdoutNot("cmd/", "go list std shows commands")
1056 func TestGoListCmdOnlyShowsCommands(t *testing.T) {
1057 skipIfGccgo(t, "gccgo does not have GOROOT")
1062 tg.run("list", "cmd")
1063 out := strings.TrimSpace(tg.getStdout())
1064 for _, line := range strings.Split(out, "\n") {
1065 if !strings.Contains(line, "cmd/") {
1066 t.Error("go list cmd shows non-commands")
1072 func TestGoListDeps(t *testing.T) {
1076 tg.tempDir("src/p1/p2/p3/p4")
1077 tg.setenv("GOPATH", tg.path("."))
1078 tg.tempFile("src/p1/p.go", "package p1\nimport _ \"p1/p2\"\n")
1079 tg.tempFile("src/p1/p2/p.go", "package p2\nimport _ \"p1/p2/p3\"\n")
1080 tg.tempFile("src/p1/p2/p3/p.go", "package p3\nimport _ \"p1/p2/p3/p4\"\n")
1081 tg.tempFile("src/p1/p2/p3/p4/p.go", "package p4\n")
1082 tg.run("list", "-f", "{{.Deps}}", "p1")
1083 tg.grepStdout("p1/p2/p3/p4", "Deps(p1) does not mention p4")
1085 tg.run("list", "-deps", "p1")
1086 tg.grepStdout("p1/p2/p3/p4", "-deps p1 does not mention p4")
1088 if runtime.Compiler != "gccgo" {
1089 // Check the list is in dependency order.
1090 tg.run("list", "-deps", "math")
1091 want := "internal/cpu\nunsafe\nmath/bits\nmath\n"
1092 out := tg.stdout.String()
1093 if !strings.Contains(out, "internal/cpu") {
1094 // Some systems don't use internal/cpu.
1095 want = "unsafe\nmath/bits\nmath\n"
1097 if tg.stdout.String() != want {
1098 t.Fatalf("list -deps math: wrong order\nhave %q\nwant %q", tg.stdout.String(), want)
1103 func TestGoListTest(t *testing.T) {
1104 skipIfGccgo(t, "gccgo does not have standard packages")
1109 tg.setenv("GOCACHE", tg.tempdir)
1111 tg.run("list", "-test", "-deps", "sort")
1112 tg.grepStdout(`^sort.test$`, "missing test main")
1113 tg.grepStdout(`^sort$`, "missing real sort")
1114 tg.grepStdout(`^sort \[sort.test\]$`, "missing test copy of sort")
1115 tg.grepStdout(`^testing \[sort.test\]$`, "missing test copy of testing")
1116 tg.grepStdoutNot(`^testing$`, "unexpected real copy of testing")
1118 tg.run("list", "-test", "sort")
1119 tg.grepStdout(`^sort.test$`, "missing test main")
1120 tg.grepStdout(`^sort$`, "missing real sort")
1121 tg.grepStdout(`^sort \[sort.test\]$`, "unexpected test copy of sort")
1122 tg.grepStdoutNot(`^testing \[sort.test\]$`, "unexpected test copy of testing")
1123 tg.grepStdoutNot(`^testing$`, "unexpected real copy of testing")
1125 tg.run("list", "-test", "cmd/dist", "cmd/doc")
1126 tg.grepStdout(`^cmd/dist$`, "missing cmd/dist")
1127 tg.grepStdout(`^cmd/doc$`, "missing cmd/doc")
1128 tg.grepStdout(`^cmd/doc\.test$`, "missing cmd/doc test")
1129 tg.grepStdoutNot(`^cmd/dist\.test$`, "unexpected cmd/dist test")
1130 tg.grepStdoutNot(`^testing`, "unexpected testing")
1132 tg.run("list", "-test", "runtime/cgo")
1133 tg.grepStdout(`^runtime/cgo$`, "missing runtime/cgo")
1135 tg.run("list", "-deps", "-f", "{{if .DepOnly}}{{.ImportPath}}{{end}}", "sort")
1136 tg.grepStdout(`^internal/reflectlite$`, "missing internal/reflectlite")
1137 tg.grepStdoutNot(`^sort`, "unexpected sort")
1140 func TestGoListCompiledCgo(t *testing.T) {
1146 tg.setenv("GOCACHE", tg.tempdir)
1148 tg.run("list", "-f", `{{join .CgoFiles "\n"}}`, "net")
1149 if tg.stdout.String() == "" {
1150 t.Skip("net does not use cgo")
1152 if strings.Contains(tg.stdout.String(), tg.tempdir) {
1153 t.Fatalf(".CgoFiles unexpectedly mentioned cache %s", tg.tempdir)
1155 tg.run("list", "-compiled", "-f", `{{.Dir}}{{"\n"}}{{join .CompiledGoFiles "\n"}}`, "net")
1156 if !strings.Contains(tg.stdout.String(), tg.tempdir) {
1157 t.Fatalf(".CompiledGoFiles with -compiled did not mention cache %s", tg.tempdir)
1160 for _, file := range strings.Split(tg.stdout.String(), "\n") {
1168 if !strings.Contains(file, "/") && !strings.Contains(file, `\`) {
1169 file = filepath.Join(dir, file)
1171 if _, err := os.Stat(file); err != nil {
1172 t.Fatalf("cannot find .CompiledGoFiles result %s: %v", file, err)
1177 func TestGoListExport(t *testing.T) {
1178 skipIfGccgo(t, "gccgo does not have standard packages")
1183 tg.setenv("GOCACHE", tg.tempdir)
1185 tg.run("list", "-f", "{{.Export}}", "strings")
1186 if tg.stdout.String() != "" {
1187 t.Fatalf(".Export without -export unexpectedly set")
1189 tg.run("list", "-export", "-f", "{{.Export}}", "strings")
1190 file := strings.TrimSpace(tg.stdout.String())
1192 t.Fatalf(".Export with -export was empty")
1194 if _, err := os.Stat(file); err != nil {
1195 t.Fatalf("cannot find .Export result %s: %v", file, err)
1198 tg.run("list", "-export", "-f", "{{.BuildID}}", "strings")
1199 buildID := strings.TrimSpace(tg.stdout.String())
1201 t.Fatalf(".BuildID with -export was empty")
1204 tg.run("tool", "buildid", file)
1205 toolBuildID := strings.TrimSpace(tg.stdout.String())
1206 if buildID != toolBuildID {
1207 t.Fatalf(".BuildID with -export %q disagrees with 'go tool buildid' %q", buildID, toolBuildID)
1211 // Issue 4096. Validate the output of unsuccessful go install foo/quxx.
1212 func TestUnsuccessfulGoInstallShouldMentionMissingPackage(t *testing.T) {
1216 tg.runFail("install", "foo/quxx")
1217 if tg.grepCountBoth(`cannot find package "foo/quxx" in any of`) != 1 {
1218 t.Error(`go install foo/quxx expected error: .*cannot find package "foo/quxx" in any of`)
1222 func TestGOROOTSearchFailureReporting(t *testing.T) {
1226 tg.runFail("install", "foo/quxx")
1227 if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("foo", "quxx"))+` \(from \$GOROOT\)$`) != 1 {
1228 t.Error(`go install foo/quxx expected error: .*foo/quxx (from $GOROOT)`)
1232 func TestMultipleGOPATHEntriesReportedSeparately(t *testing.T) {
1236 sep := string(filepath.ListSeparator)
1237 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
1238 tg.runFail("install", "foo/quxx")
1239 if tg.grepCountBoth(`testdata[/\\].[/\\]src[/\\]foo[/\\]quxx`) != 2 {
1240 t.Error(`go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)\n.*testdata/b/src/foo/quxx`)
1244 // Test (from $GOPATH) annotation is reported for the first GOPATH entry,
1245 func TestMentionGOPATHInFirstGOPATHEntry(t *testing.T) {
1249 sep := string(filepath.ListSeparator)
1250 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
1251 tg.runFail("install", "foo/quxx")
1252 if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("testdata", "a", "src", "foo", "quxx"))+` \(from \$GOPATH\)$`) != 1 {
1253 t.Error(`go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)`)
1257 // but not on the second.
1258 func TestMentionGOPATHNotOnSecondEntry(t *testing.T) {
1262 sep := string(filepath.ListSeparator)
1263 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
1264 tg.runFail("install", "foo/quxx")
1265 if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("testdata", "b", "src", "foo", "quxx"))+`$`) != 1 {
1266 t.Error(`go install foo/quxx expected error: .*testdata/b/src/foo/quxx`)
1270 func homeEnvName() string {
1271 switch runtime.GOOS {
1273 return "USERPROFILE"
1281 func tempEnvName() string {
1282 switch runtime.GOOS {
1286 return "TMPDIR" // actually plan 9 doesn't have one at all but this is fine
1292 func TestDefaultGOPATH(t *testing.T) {
1296 tg.tempDir("home/go")
1297 tg.setenv(homeEnvName(), tg.path("home"))
1299 tg.run("env", "GOPATH")
1300 tg.grepStdout(regexp.QuoteMeta(tg.path("home/go")), "want GOPATH=$HOME/go")
1302 tg.setenv("GOROOT", tg.path("home/go"))
1303 tg.run("env", "GOPATH")
1304 tg.grepStdoutNot(".", "want unset GOPATH because GOROOT=$HOME/go")
1306 tg.setenv("GOROOT", tg.path("home/go")+"/")
1307 tg.run("env", "GOPATH")
1308 tg.grepStdoutNot(".", "want unset GOPATH because GOROOT=$HOME/go/")
1311 func TestDefaultGOPATHGet(t *testing.T) {
1312 testenv.MustHaveExternalNetwork(t)
1313 testenv.MustHaveExecPath(t, "git")
1318 tg.setenv("GOPATH", "")
1320 tg.setenv(homeEnvName(), tg.path("home"))
1322 // warn for creating directory
1323 tg.run("get", "-v", "github.com/golang/example/hello")
1324 tg.grepStderr("created GOPATH="+regexp.QuoteMeta(tg.path("home/go"))+"; see 'go help gopath'", "did not create GOPATH")
1326 // no warning if directory already exists
1327 tg.must(robustio.RemoveAll(tg.path("home/go")))
1328 tg.tempDir("home/go")
1329 tg.run("get", "github.com/golang/example/hello")
1330 tg.grepStderrNot(".", "expected no output on standard error")
1332 // error if $HOME/go is a file
1333 tg.must(robustio.RemoveAll(tg.path("home/go")))
1334 tg.tempFile("home/go", "")
1335 tg.runFail("get", "github.com/golang/example/hello")
1336 tg.grepStderr(`mkdir .*[/\\]go: .*(not a directory|cannot find the path)`, "expected error because $HOME/go is a file")
1339 func TestDefaultGOPATHPrintedSearchList(t *testing.T) {
1343 tg.setenv("GOPATH", "")
1345 tg.setenv(homeEnvName(), tg.path("home"))
1347 tg.runFail("install", "github.com/golang/example/hello")
1348 tg.grepStderr(regexp.QuoteMeta(tg.path("home/go/src/github.com/golang/example/hello"))+`.*from \$GOPATH`, "expected default GOPATH")
1351 func TestLdflagsArgumentsWithSpacesIssue3941(t *testing.T) {
1352 skipIfGccgo(t, "gccgo does not support -ldflags -X")
1357 tg.tempFile("main.go", `package main
1362 tg.run("run", "-ldflags", `-X "main.extern=hello world"`, tg.path("main.go"))
1363 tg.grepStderr("^hello world", `ldflags -X "main.extern=hello world"' failed`)
1366 func TestLdFlagsLongArgumentsIssue42295(t *testing.T) {
1367 // Test the extremely long command line arguments that contain '\n' characters
1368 // get encoded and passed correctly.
1369 skipIfGccgo(t, "gccgo does not support -ldflags -X")
1374 tg.tempFile("main.go", `package main
1379 testStr := "test test test test test \n\\ "
1380 var buf bytes.Buffer
1381 for buf.Len() < work.ArgLengthForResponseFile+1 {
1382 buf.WriteString(testStr)
1384 tg.run("run", "-ldflags", fmt.Sprintf(`-X "main.extern=%s"`, buf.String()), tg.path("main.go"))
1385 if tg.stderr.String() != buf.String() {
1386 t.Errorf("strings differ")
1390 func TestGoTestDashCDashOControlsBinaryLocation(t *testing.T) {
1391 skipIfGccgo(t, "gccgo has no standard packages")
1397 tg.run("test", "-c", "-o", tg.path("myerrors.test"+exeSuffix), "errors")
1398 tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -c -o myerrors.test did not create myerrors.test")
1401 func TestGoTestDashOWritesBinary(t *testing.T) {
1402 skipIfGccgo(t, "gccgo has no standard packages")
1408 tg.run("test", "-o", tg.path("myerrors.test"+exeSuffix), "errors")
1409 tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -o myerrors.test did not create myerrors.test")
1412 func TestGoTestDashIDashOWritesBinary(t *testing.T) {
1413 skipIfGccgo(t, "gccgo has no standard packages")
1420 // don't let test -i overwrite runtime
1421 tg.wantNotStale("runtime", "", "must be non-stale before test -i")
1423 tg.run("test", "-v", "-i", "-o", tg.path("myerrors.test"+exeSuffix), "errors")
1424 tg.grepBothNot("PASS|FAIL", "test should not have run")
1425 tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -o myerrors.test did not create myerrors.test")
1429 func TestInstallWithTags(t *testing.T) {
1435 tg.tempFile("src/example/a/main.go", `package main
1437 tg.tempFile("src/example/b/main.go", `// +build mytag
1441 tg.setenv("GOPATH", tg.path("."))
1442 tg.run("install", "-tags", "mytag", "example/a", "example/b")
1443 tg.wantExecutable(tg.path("bin/a"+exeSuffix), "go install example/a example/b did not install binaries")
1444 tg.wantExecutable(tg.path("bin/b"+exeSuffix), "go install example/a example/b did not install binaries")
1445 tg.must(os.Remove(tg.path("bin/a" + exeSuffix)))
1446 tg.must(os.Remove(tg.path("bin/b" + exeSuffix)))
1447 tg.run("install", "-tags", "mytag", "example/...")
1448 tg.wantExecutable(tg.path("bin/a"+exeSuffix), "go install example/... did not install binaries")
1449 tg.wantExecutable(tg.path("bin/b"+exeSuffix), "go install example/... did not install binaries")
1450 tg.run("list", "-tags", "mytag", "example/b...")
1451 if strings.TrimSpace(tg.getStdout()) != "example/b" {
1452 t.Error("go list example/b did not find example/b")
1456 // Issue 17451, 17662.
1457 func TestSymlinkWarning(t *testing.T) {
1462 tg.setenv("GOPATH", tg.path("."))
1464 tg.tempDir("src/example/xx")
1466 tg.tempFile("yy/zz/zz.go", "package zz\n")
1467 if err := os.Symlink(tg.path("yy"), tg.path("src/example/xx/yy")); err != nil {
1468 t.Skipf("symlink failed: %v", err)
1470 tg.run("list", "example/xx/z...")
1471 tg.grepStdoutNot(".", "list should not have matched anything")
1472 tg.grepStderr("matched no packages", "list should have reported that pattern matched no packages")
1473 tg.grepStderrNot("symlink", "list should not have reported symlink")
1475 tg.run("list", "example/xx/...")
1476 tg.grepStdoutNot(".", "list should not have matched anything")
1477 tg.grepStderr("matched no packages", "list should have reported that pattern matched no packages")
1478 tg.grepStderr("ignoring symlink", "list should have reported symlink")
1481 func TestCgoShowsFullPathNames(t *testing.T) {
1483 t.Skip("skipping because cgo not enabled")
1489 tg.tempFile("src/x/y/dirname/foo.go", `
1493 tg.setenv("GOPATH", tg.path("."))
1494 tg.runFail("build", "x/y/dirname")
1495 tg.grepBoth("x/y/dirname", "error did not use full path")
1498 func TestCgoHandlesWlORIGIN(t *testing.T) {
1501 t.Skip("skipping because cgo not enabled")
1507 tg.tempFile("src/origin/origin.go", `package origin
1508 // #cgo !darwin LDFLAGS: -Wl,-rpath,$ORIGIN
1511 func f() { C.f() }`)
1512 tg.setenv("GOPATH", tg.path("."))
1513 tg.run("build", "origin")
1516 func TestCgoPkgConfig(t *testing.T) {
1519 t.Skip("skipping because cgo not enabled")
1525 tg.run("env", "PKG_CONFIG")
1526 pkgConfig := strings.TrimSpace(tg.getStdout())
1527 testenv.MustHaveExecPath(t, pkgConfig)
1528 if out, err := exec.Command(pkgConfig, "--atleast-pkgconfig-version", "0.24").CombinedOutput(); err != nil {
1529 t.Skipf("%s --atleast-pkgconfig-version 0.24: %v\n%s", pkgConfig, err, out)
1532 // OpenBSD's pkg-config is strict about whitespace and only
1533 // supports backslash-escaped whitespace. It does not support
1534 // quotes, which the normal freedesktop.org pkg-config does
1535 // support. See https://man.openbsd.org/pkg-config.1
1536 tg.tempFile("foo.pc", `
1538 Description: The foo library
1540 Cflags: -Dhello=10 -Dworld=+32 -DDEFINED_FROM_PKG_CONFIG=hello\ world
1542 tg.tempFile("foo.go", `package main
1545 #cgo pkg-config: foo
1547 return DEFINED_FROM_PKG_CONFIG;
1554 if C.value() != 42 {
1555 println("value() =", C.value(), "wanted 42")
1560 tg.setenv("PKG_CONFIG_PATH", tg.path("."))
1561 tg.run("run", tg.path("foo.go"))
1564 func TestListTemplateContextFunction(t *testing.T) {
1566 for _, tt := range []struct {
1570 {"GOARCH", runtime.GOARCH},
1571 {"GOOS", runtime.GOOS},
1572 {"GOROOT", filepath.Clean(runtime.GOROOT())},
1573 {"GOPATH", os.Getenv("GOPATH")},
1575 {"UseAllFiles", ""},
1578 {"ReleaseTags", ""},
1579 {"InstallSuffix", ""},
1582 t.Run(tt.v, func(t *testing.T) {
1586 tmpl := "{{context." + tt.v + "}}"
1587 tg.run("list", "-f", tmpl)
1591 if got := strings.TrimSpace(tg.getStdout()); got != tt.want {
1592 t.Errorf("go list -f %q: got %q; want %q", tmpl, got, tt.want)
1598 // Test that you cannot use a local import in a package
1599 // accessed by a non-local import (found in a GOPATH/GOROOT).
1600 // See golang.org/issue/17475.
1601 func TestImportLocal(t *testing.T) {
1608 tg.tempFile("src/dir/x/x.go", `package x
1611 tg.setenv("GOPATH", tg.path("."))
1612 tg.run("build", "dir/x")
1614 // Ordinary import should work.
1615 tg.tempFile("src/dir/p0/p.go", `package p0
1619 tg.run("build", "dir/p0")
1621 // Relative import should not.
1622 tg.tempFile("src/dir/p1/p.go", `package p1
1626 tg.runFail("build", "dir/p1")
1627 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1629 // ... even in a test.
1630 tg.tempFile("src/dir/p2/p.go", `package p2
1632 tg.tempFile("src/dir/p2/p_test.go", `package p2
1636 func TestFoo(t *testing.T) {}
1638 tg.run("build", "dir/p2")
1639 tg.runFail("test", "dir/p2")
1640 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1642 // ... even in an xtest.
1643 tg.tempFile("src/dir/p2/p_test.go", `package p2_test
1647 func TestFoo(t *testing.T) {}
1649 tg.run("build", "dir/p2")
1650 tg.runFail("test", "dir/p2")
1651 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1653 // Relative import starting with ./ should not work either.
1654 tg.tempFile("src/dir/d.go", `package dir
1658 tg.runFail("build", "dir")
1659 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1661 // ... even in a test.
1662 tg.tempFile("src/dir/d.go", `package dir
1664 tg.tempFile("src/dir/d_test.go", `package dir
1668 func TestFoo(t *testing.T) {}
1670 tg.run("build", "dir")
1671 tg.runFail("test", "dir")
1672 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1674 // ... even in an xtest.
1675 tg.tempFile("src/dir/d_test.go", `package dir_test
1679 func TestFoo(t *testing.T) {}
1681 tg.run("build", "dir")
1682 tg.runFail("test", "dir")
1683 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1685 // Relative import plain ".." should not work.
1686 tg.tempFile("src/dir/x/y/y.go", `package dir
1690 tg.runFail("build", "dir/x/y")
1691 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1693 // ... even in a test.
1694 tg.tempFile("src/dir/x/y/y.go", `package y
1696 tg.tempFile("src/dir/x/y/y_test.go", `package y
1700 func TestFoo(t *testing.T) {}
1702 tg.run("build", "dir/x/y")
1703 tg.runFail("test", "dir/x/y")
1704 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1706 // ... even in an x test.
1707 tg.tempFile("src/dir/x/y/y_test.go", `package y_test
1711 func TestFoo(t *testing.T) {}
1713 tg.run("build", "dir/x/y")
1714 tg.runFail("test", "dir/x/y")
1715 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1717 // Relative import "." should not work.
1718 tg.tempFile("src/dir/x/xx.go", `package x
1722 tg.runFail("build", "dir/x")
1723 tg.grepStderr("cannot import current directory", "did not diagnose import current directory")
1725 // ... even in a test.
1726 tg.tempFile("src/dir/x/xx.go", `package x
1728 tg.tempFile("src/dir/x/xx_test.go", `package x
1732 func TestFoo(t *testing.T) {}
1734 tg.run("build", "dir/x")
1735 tg.runFail("test", "dir/x")
1736 tg.grepStderr("cannot import current directory", "did not diagnose import current directory")
1738 // ... even in an xtest.
1739 tg.tempFile("src/dir/x/xx.go", `package x
1741 tg.tempFile("src/dir/x/xx_test.go", `package x_test
1745 func TestFoo(t *testing.T) {}
1747 tg.run("build", "dir/x")
1748 tg.runFail("test", "dir/x")
1749 tg.grepStderr("cannot import current directory", "did not diagnose import current directory")
1752 func TestGoInstallPkgdir(t *testing.T) {
1753 skipIfGccgo(t, "gccgo has no standard packages")
1761 tg.run("install", "-pkgdir", pkg, "sync")
1762 tg.mustExist(filepath.Join(pkg, "sync.a"))
1763 tg.mustNotExist(filepath.Join(pkg, "sync/atomic.a"))
1764 tg.run("install", "-i", "-pkgdir", pkg, "sync")
1765 tg.mustExist(filepath.Join(pkg, "sync.a"))
1766 tg.mustExist(filepath.Join(pkg, "sync/atomic.a"))
1770 func TestParallelTest(t *testing.T) {
1776 const testSrc = `package package_test
1780 func TestTest(t *testing.T) {
1782 tg.tempFile("src/p1/p1_test.go", strings.Replace(testSrc, "package_test", "p1_test", 1))
1783 tg.tempFile("src/p2/p2_test.go", strings.Replace(testSrc, "package_test", "p2_test", 1))
1784 tg.tempFile("src/p3/p3_test.go", strings.Replace(testSrc, "package_test", "p3_test", 1))
1785 tg.tempFile("src/p4/p4_test.go", strings.Replace(testSrc, "package_test", "p4_test", 1))
1786 tg.setenv("GOPATH", tg.path("."))
1787 tg.run("test", "-p=4", "p1", "p2", "p3", "p4")
1790 func TestBinaryOnlyPackages(t *testing.T) {
1797 tg.setenv("GOPATH", tg.path("."))
1799 tg.tempFile("src/p1/p1.go", `//go:binary-only-package
1803 tg.wantStale("p1", "binary-only packages are no longer supported", "p1 is binary-only, and this message should always be printed")
1804 tg.runFail("install", "p1")
1805 tg.grepStderr("binary-only packages are no longer supported", "did not report attempt to compile binary-only package")
1807 tg.tempFile("src/p1/p1.go", `
1810 func F(b bool) { fmt.Printf("hello from p1\n"); if b { F(false) } }
1812 tg.run("install", "p1")
1813 os.Remove(tg.path("src/p1/p1.go"))
1814 tg.mustNotExist(tg.path("src/p1/p1.go"))
1816 tg.tempFile("src/p2/p2.go", `//go:binary-only-packages-are-not-great
1820 func F() { p1.F(true) }
1822 tg.runFail("install", "p2")
1823 tg.grepStderr("no Go files", "did not complain about missing sources")
1825 tg.tempFile("src/p1/missing.go", `//go:binary-only-package
1831 tg.wantStale("p1", "binary-only package", "should NOT want to rebuild p1 (first)")
1832 tg.runFail("install", "p2")
1833 tg.grepStderr("p1: binary-only packages are no longer supported", "did not report error for binary-only p1")
1835 tg.run("list", "-deps", "-f", "{{.ImportPath}}: {{.BinaryOnly}}", "p2")
1836 tg.grepStdout("p1: true", "p1 not listed as BinaryOnly")
1837 tg.grepStdout("p2: false", "p2 listed as BinaryOnly")
1840 // Issue 16050 and 21884.
1841 func TestLinkSysoFiles(t *testing.T) {
1842 if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
1843 t.Skip("not linux/amd64")
1849 tg.tempDir("src/syso")
1850 tg.tempFile("src/syso/a.syso", ``)
1851 tg.tempFile("src/syso/b.go", `package syso`)
1852 tg.setenv("GOPATH", tg.path("."))
1854 // We should see the .syso file regardless of the setting of
1857 tg.setenv("CGO_ENABLED", "1")
1858 tg.run("list", "-f", "{{.SysoFiles}}", "syso")
1859 tg.grepStdout("a.syso", "missing syso file with CGO_ENABLED=1")
1861 tg.setenv("CGO_ENABLED", "0")
1862 tg.run("list", "-f", "{{.SysoFiles}}", "syso")
1863 tg.grepStdout("a.syso", "missing syso file with CGO_ENABLED=0")
1865 tg.setenv("CGO_ENABLED", "1")
1866 tg.run("list", "-msan", "-f", "{{.SysoFiles}}", "syso")
1867 tg.grepStdoutNot("a.syso", "unexpected syso file with -msan")
1871 func TestGenerateUsesBuildContext(t *testing.T) {
1872 if runtime.GOOS == "windows" {
1873 t.Skip("this test won't run under Windows")
1879 tg.tempDir("src/gen")
1880 tg.tempFile("src/gen/gen.go", "package gen\n//go:generate echo $GOOS $GOARCH\n")
1881 tg.setenv("GOPATH", tg.path("."))
1883 tg.setenv("GOOS", "linux")
1884 tg.setenv("GOARCH", "amd64")
1885 tg.run("generate", "gen")
1886 tg.grepStdout("linux amd64", "unexpected GOOS/GOARCH combination")
1888 tg.setenv("GOOS", "darwin")
1889 tg.setenv("GOARCH", "arm64")
1890 tg.run("generate", "gen")
1891 tg.grepStdout("darwin arm64", "unexpected GOOS/GOARCH combination")
1894 func TestGoEnv(t *testing.T) {
1898 tg.setenv("GOOS", "freebsd") // to avoid invalid pair errors
1899 tg.setenv("GOARCH", "arm")
1900 tg.run("env", "GOARCH")
1901 tg.grepStdout("^arm$", "GOARCH not honored")
1903 tg.run("env", "GCCGO")
1904 tg.grepStdout(".", "GCCGO unexpectedly empty")
1906 tg.run("env", "CGO_CFLAGS")
1907 tg.grepStdout(".", "default CGO_CFLAGS unexpectedly empty")
1909 tg.setenv("CGO_CFLAGS", "-foobar")
1910 tg.run("env", "CGO_CFLAGS")
1911 tg.grepStdout("^-foobar$", "CGO_CFLAGS not honored")
1913 tg.setenv("CC", "gcc -fmust -fgo -ffaster")
1915 tg.grepStdout("gcc", "CC not found")
1916 tg.run("env", "GOGCCFLAGS")
1917 tg.grepStdout("-ffaster", "CC arguments not found")
1919 tg.run("env", "GOVERSION")
1920 envVersion := strings.TrimSpace(tg.stdout.String())
1923 cmdVersion := strings.TrimSpace(tg.stdout.String())
1925 // If 'go version' is "go version <version> <goos>/<goarch>", then
1926 // 'go env GOVERSION' is just "<version>".
1927 if cmdVersion == envVersion || !strings.Contains(cmdVersion, envVersion) {
1928 t.Fatalf("'go env GOVERSION' %q should be a shorter substring of 'go version' %q", envVersion, cmdVersion)
1933 noMatchesPattern = `(?m)^ok.*\[no tests to run\]`
1934 okPattern = `(?m)^ok`
1938 func TestLdBindNow(t *testing.T) {
1942 tg.setenv("LD_BIND_NOW", "1")
1947 // This is really a cmd/asm issue but this is a convenient place to test it.
1948 func TestConcurrentAsm(t *testing.T) {
1949 skipIfGccgo(t, "gccgo does not use cmd/asm")
1953 asm := `DATA ·constants<>+0x0(SB)/8,$0
1954 GLOBL ·constants<>(SB),8,$8
1956 tg.tempFile("go/src/p/a.s", asm)
1957 tg.tempFile("go/src/p/b.s", asm)
1958 tg.tempFile("go/src/p/p.go", `package p`)
1959 tg.setenv("GOPATH", tg.path("go"))
1960 tg.run("build", "p")
1964 func TestFFLAGS(t *testing.T) {
1966 t.Skip("skipping because cgo not enabled")
1973 tg.tempFile("p/src/p/main.go", `package main
1974 // #cgo FFLAGS: -no-such-fortran-flag
1978 tg.tempFile("p/src/p/a.f", `! comment`)
1979 tg.setenv("GOPATH", tg.path("p"))
1981 // This should normally fail because we are passing an unknown flag,
1982 // but issue #19080 points to Fortran compilers that succeed anyhow.
1983 // To work either way we call doRun directly rather than run or runFail.
1984 tg.doRun([]string{"build", "-x", "p"})
1986 tg.grepStderr("no-such-fortran-flag", `missing expected "-no-such-fortran-flag"`)
1990 // This is really a cmd/link issue but this is a convenient place to test it.
1991 func TestDuplicateGlobalAsmSymbols(t *testing.T) {
1992 skipIfGccgo(t, "gccgo does not use cmd/asm")
1994 if runtime.GOARCH != "386" && runtime.GOARCH != "amd64" {
1995 t.Skipf("skipping test on %s", runtime.GOARCH)
1998 t.Skip("skipping because cgo not enabled")
2006 #include "textflag.h"
2008 DATA sym<>+0x0(SB)/8,$0
2009 GLOBL sym<>(SB),(NOPTR+RODATA),$8
2011 TEXT ·Data(SB),NOSPLIT,$0
2016 tg.tempFile("go/src/a/a.s", asm)
2017 tg.tempFile("go/src/a/a.go", `package a; func Data() uint8`)
2018 tg.tempFile("go/src/b/b.s", asm)
2019 tg.tempFile("go/src/b/b.go", `package b; func Data() uint8`)
2020 tg.tempFile("go/src/p/p.go", `
2026 _ = a.Data() + b.Data()
2029 tg.setenv("GOPATH", tg.path("go"))
2030 exe := tg.path("p.exe")
2031 tg.creatingTemp(exe)
2032 tg.run("build", "-o", exe, "p")
2035 func copyFile(src, dst string, perm fs.FileMode) error {
2036 sf, err := os.Open(src)
2042 df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
2047 _, err = io.Copy(df, sf)
2055 func TestNeedVersion(t *testing.T) {
2056 skipIfGccgo(t, "gccgo does not use cmd/compile")
2060 tg.tempFile("goversion.go", `package main; func main() {}`)
2061 path := tg.path("goversion.go")
2062 tg.setenv("TESTGO_VERSION", "go1.testgo")
2063 tg.runFail("run", path)
2064 tg.grepStderr("compile", "does not match go tool version")
2067 func TestBuildmodePIE(t *testing.T) {
2068 if testing.Short() && testenv.Builder() == "" {
2069 t.Skipf("skipping in -short mode on non-builder")
2072 platform := fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)
2074 case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/riscv64", "linux/s390x",
2075 "android/amd64", "android/arm", "android/arm64", "android/386",
2077 "windows/386", "windows/amd64", "windows/arm":
2078 case "darwin/amd64":
2080 t.Skipf("skipping test because buildmode=pie is not supported on %s", platform)
2082 t.Run("non-cgo", func(t *testing.T) {
2083 testBuildmodePIE(t, false, true)
2086 switch runtime.GOOS {
2087 case "darwin", "freebsd", "linux", "windows":
2088 t.Run("cgo", func(t *testing.T) {
2089 testBuildmodePIE(t, true, true)
2095 func TestWindowsDefaultBuildmodIsPIE(t *testing.T) {
2096 if testing.Short() && testenv.Builder() == "" {
2097 t.Skipf("skipping in -short mode on non-builder")
2100 if runtime.GOOS != "windows" {
2101 t.Skip("skipping windows only test")
2104 t.Run("non-cgo", func(t *testing.T) {
2105 testBuildmodePIE(t, false, false)
2108 t.Run("cgo", func(t *testing.T) {
2109 testBuildmodePIE(t, true, false)
2114 func testBuildmodePIE(t *testing.T, useCgo, setBuildmodeToPIE bool) {
2123 tg.tempFile("main.go", fmt.Sprintf(`package main;%s func main() { print("hello") }`, s))
2124 src := tg.path("main.go")
2125 obj := tg.path("main.exe")
2126 args := []string{"build"}
2127 if setBuildmodeToPIE {
2128 args = append(args, "-buildmode=pie")
2130 args = append(args, "-o", obj, src)
2133 switch runtime.GOOS {
2134 case "linux", "android", "freebsd":
2135 f, err := elf.Open(obj)
2140 if f.Type != elf.ET_DYN {
2141 t.Errorf("PIE type must be ET_DYN, but %s", f.Type)
2144 f, err := macho.Open(obj)
2149 if f.Flags&macho.FlagDyldLink == 0 {
2150 t.Error("PIE must have DyldLink flag, but not")
2152 if f.Flags&macho.FlagPIE == 0 {
2153 t.Error("PIE must have PIE flag, but not")
2156 f, err := pe.Open(obj)
2161 if f.Section(".reloc") == nil {
2162 t.Error(".reloc section is not present")
2164 if (f.FileHeader.Characteristics & pe.IMAGE_FILE_RELOCS_STRIPPED) != 0 {
2165 t.Error("IMAGE_FILE_RELOCS_STRIPPED flag is set")
2168 switch oh := f.OptionalHeader.(type) {
2169 case *pe.OptionalHeader32:
2170 dc = oh.DllCharacteristics
2171 case *pe.OptionalHeader64:
2172 dc = oh.DllCharacteristics
2173 if (dc & pe.IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA) == 0 {
2174 t.Error("IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA flag is not set")
2177 t.Fatalf("unexpected optional header type of %T", f.OptionalHeader)
2179 if (dc & pe.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) == 0 {
2180 t.Error("IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE flag is not set")
2183 // Test that only one symbol is exported (#40795).
2184 // PIE binaries don´t require .edata section but unfortunately
2185 // binutils doesn´t generate a .reloc section unless there is
2186 // at least one symbol exported.
2187 // See https://sourceware.org/bugzilla/show_bug.cgi?id=19011
2188 section := f.Section(".edata")
2190 t.Skip(".edata section is not present")
2192 // TODO: deduplicate this struct from cmd/link/internal/ld/pe.go
2193 type IMAGE_EXPORT_DIRECTORY struct {
2197 NumberOfFunctions uint32
2198 NumberOfNames uint32
2201 var e IMAGE_EXPORT_DIRECTORY
2202 if err := binary.Read(section.Open(), binary.LittleEndian, &e); err != nil {
2203 t.Fatalf("binary.Read failed: %v", err)
2206 // Only _cgo_dummy_export should be exported
2207 if e.NumberOfFunctions != 1 {
2208 t.Fatalf("got %d exported functions; want 1", e.NumberOfFunctions)
2210 if e.NumberOfNames != 1 {
2211 t.Fatalf("got %d exported names; want 1", e.NumberOfNames)
2215 panic("unreachable")
2218 out, err := exec.Command(obj).CombinedOutput()
2223 if string(out) != "hello" {
2224 t.Errorf("got %q; want %q", out, "hello")
2228 func TestUpxCompression(t *testing.T) {
2229 if runtime.GOOS != "linux" ||
2230 (runtime.GOARCH != "amd64" && runtime.GOARCH != "386") {
2231 t.Skipf("skipping upx test on %s/%s", runtime.GOOS, runtime.GOARCH)
2234 testenv.MustHaveExecPath(t, "upx")
2235 out, err := exec.Command("upx", "--version").CombinedOutput()
2237 t.Fatalf("upx --version failed: %v", err)
2240 // upx --version prints `upx <version>` in the first line of output:
2243 re := regexp.MustCompile(`([[:digit:]]+)\.([[:digit:]]+)`)
2244 upxVersion := re.FindStringSubmatch(string(out))
2245 if len(upxVersion) != 3 {
2246 t.Fatalf("bad upx version string: %s", upxVersion)
2249 major, err1 := strconv.Atoi(upxVersion[1])
2250 minor, err2 := strconv.Atoi(upxVersion[2])
2251 if err1 != nil || err2 != nil {
2252 t.Fatalf("bad upx version string: %s", upxVersion[0])
2255 // Anything below 3.94 is known not to work with go binaries
2256 if (major < 3) || (major == 3 && minor < 94) {
2257 t.Skipf("skipping because upx version %v.%v is too old", major, minor)
2264 tg.tempFile("main.go", `package main; import "fmt"; func main() { fmt.Print("hello upx") }`)
2265 src := tg.path("main.go")
2266 obj := tg.path("main")
2267 tg.run("build", "-o", obj, src)
2269 out, err = exec.Command("upx", obj).CombinedOutput()
2271 t.Logf("executing upx\n%s\n", out)
2272 t.Fatalf("upx failed with %v", err)
2275 out, err = exec.Command(obj).CombinedOutput()
2278 t.Fatalf("running compressed go binary failed with error %s", err)
2280 if string(out) != "hello upx" {
2281 t.Fatalf("bad output from compressed go binary:\ngot %q; want %q", out, "hello upx")
2285 func TestCacheListStale(t *testing.T) {
2287 if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
2288 t.Skip("GODEBUG gocacheverify")
2294 tg.setenv("GOCACHE", tg.path("cache"))
2295 tg.tempFile("gopath/src/p/p.go", "package p; import _ \"q\"; func F(){}\n")
2296 tg.tempFile("gopath/src/q/q.go", "package q; func F(){}\n")
2297 tg.tempFile("gopath/src/m/m.go", "package main; import _ \"q\"; func main(){}\n")
2299 tg.setenv("GOPATH", tg.path("gopath"))
2300 tg.run("install", "p", "m")
2301 tg.run("list", "-f={{.ImportPath}} {{.Stale}}", "m", "q", "p")
2302 tg.grepStdout("^m false", "m should not be stale")
2303 tg.grepStdout("^q true", "q should be stale")
2304 tg.grepStdout("^p false", "p should not be stale")
2307 func TestCacheCoverage(t *testing.T) {
2310 if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
2311 t.Skip("GODEBUG gocacheverify")
2317 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
2320 tg.setenv("GOCACHE", tg.path("c1"))
2321 tg.run("test", "-cover", "-short", "strings")
2322 tg.run("test", "-cover", "-short", "math", "strings")
2325 func TestIssue22588(t *testing.T) {
2326 // Don't get confused by stderr coming from tools.
2331 if _, err := os.Stat("/usr/bin/time"); err != nil {
2335 tg.run("list", "-f={{.Stale}}", "runtime")
2336 tg.run("list", "-toolexec=/usr/bin/time", "-f={{.Stale}}", "runtime")
2337 tg.grepStdout("false", "incorrectly reported runtime as stale")
2340 func TestIssue22531(t *testing.T) {
2342 if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
2343 t.Skip("GODEBUG gocacheverify")
2349 tg.setenv("GOPATH", tg.tempdir)
2350 tg.setenv("GOCACHE", tg.path("cache"))
2351 tg.tempFile("src/m/main.go", "package main /* c1 */; func main() {}\n")
2352 tg.run("install", "-x", "m")
2353 tg.run("list", "-f", "{{.Stale}}", "m")
2354 tg.grepStdout("false", "reported m as stale after install")
2355 tg.run("tool", "buildid", tg.path("bin/m"+exeSuffix))
2357 // The link action ID did not include the full main build ID,
2358 // even though the full main build ID is written into the
2359 // eventual binary. That caused the following install to
2360 // be a no-op, thinking the gofmt binary was up-to-date,
2361 // even though .Stale could see it was not.
2362 tg.tempFile("src/m/main.go", "package main /* c2 */; func main() {}\n")
2363 tg.run("install", "-x", "m")
2364 tg.run("list", "-f", "{{.Stale}}", "m")
2365 tg.grepStdout("false", "reported m as stale after reinstall")
2366 tg.run("tool", "buildid", tg.path("bin/m"+exeSuffix))
2369 func TestIssue22596(t *testing.T) {
2371 if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
2372 t.Skip("GODEBUG gocacheverify")
2378 tg.setenv("GOCACHE", tg.path("cache"))
2379 tg.tempFile("gopath1/src/p/p.go", "package p; func F(){}\n")
2380 tg.tempFile("gopath2/src/p/p.go", "package p; func F(){}\n")
2382 tg.setenv("GOPATH", tg.path("gopath1"))
2383 tg.run("list", "-f={{.Target}}", "p")
2384 target1 := strings.TrimSpace(tg.getStdout())
2385 tg.run("install", "p")
2386 tg.wantNotStale("p", "", "p stale after install")
2388 tg.setenv("GOPATH", tg.path("gopath2"))
2389 tg.run("list", "-f={{.Target}}", "p")
2390 target2 := strings.TrimSpace(tg.getStdout())
2391 tg.must(os.MkdirAll(filepath.Dir(target2), 0777))
2392 tg.must(copyFile(target1, target2, 0666))
2393 tg.wantStale("p", "build ID mismatch", "p not stale after copy from gopath1")
2394 tg.run("install", "p")
2395 tg.wantNotStale("p", "", "p stale after install2")
2398 func TestTestCache(t *testing.T) {
2401 if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
2402 t.Skip("GODEBUG gocacheverify")
2408 tg.setenv("GOPATH", tg.tempdir)
2409 tg.setenv("GOCACHE", tg.path("cache"))
2411 // The -p=1 in the commands below just makes the -x output easier to read.
2413 t.Log("\n\nINITIAL\n\n")
2415 tg.tempFile("src/p1/p1.go", "package p1\nvar X = 1\n")
2416 tg.tempFile("src/p2/p2.go", "package p2\nimport _ \"p1\"\nvar X = 1\n")
2417 tg.tempFile("src/t/t1/t1_test.go", "package t\nimport \"testing\"\nfunc Test1(*testing.T) {}\n")
2418 tg.tempFile("src/t/t2/t2_test.go", "package t\nimport _ \"p1\"\nimport \"testing\"\nfunc Test2(*testing.T) {}\n")
2419 tg.tempFile("src/t/t3/t3_test.go", "package t\nimport \"p1\"\nimport \"testing\"\nfunc Test3(t *testing.T) {t.Log(p1.X)}\n")
2420 tg.tempFile("src/t/t4/t4_test.go", "package t\nimport \"p2\"\nimport \"testing\"\nfunc Test4(t *testing.T) {t.Log(p2.X)}")
2421 tg.run("test", "-x", "-v", "-short", "t/...")
2423 t.Log("\n\nREPEAT\n\n")
2425 tg.run("test", "-x", "-v", "-short", "t/...")
2426 tg.grepStdout(`ok \tt/t1\t\(cached\)`, "did not cache t1")
2427 tg.grepStdout(`ok \tt/t2\t\(cached\)`, "did not cache t2")
2428 tg.grepStdout(`ok \tt/t3\t\(cached\)`, "did not cache t3")
2429 tg.grepStdout(`ok \tt/t4\t\(cached\)`, "did not cache t4")
2430 tg.grepStderrNot(`[\\/](compile|gccgo) `, "incorrectly ran compiler")
2431 tg.grepStderrNot(`[\\/](link|gccgo) `, "incorrectly ran linker")
2432 tg.grepStderrNot(`p[0-9]\.test`, "incorrectly ran test")
2434 t.Log("\n\nCOMMENT\n\n")
2436 // Changing the program text without affecting the compiled package
2437 // should result in the package being rebuilt but nothing more.
2438 tg.tempFile("src/p1/p1.go", "package p1\nvar X = 01\n")
2439 tg.run("test", "-p=1", "-x", "-v", "-short", "t/...")
2440 tg.grepStdout(`ok \tt/t1\t\(cached\)`, "did not cache t1")
2441 tg.grepStdout(`ok \tt/t2\t\(cached\)`, "did not cache t2")
2442 tg.grepStdout(`ok \tt/t3\t\(cached\)`, "did not cache t3")
2443 tg.grepStdout(`ok \tt/t4\t\(cached\)`, "did not cache t4")
2444 tg.grepStderrNot(`([\\/](compile|gccgo) ).*t[0-9]_test\.go`, "incorrectly ran compiler")
2445 tg.grepStderrNot(`[\\/](link|gccgo) `, "incorrectly ran linker")
2446 tg.grepStderrNot(`t[0-9]\.test.*test\.short`, "incorrectly ran test")
2448 t.Log("\n\nCHANGE\n\n")
2450 // Changing the actual package should have limited effects.
2451 tg.tempFile("src/p1/p1.go", "package p1\nvar X = 02\n")
2452 tg.run("test", "-p=1", "-x", "-v", "-short", "t/...")
2454 // p2 should have been rebuilt.
2455 tg.grepStderr(`([\\/]compile|gccgo).*p2.go`, "did not recompile p2")
2457 // t1 does not import anything, should not have been rebuilt.
2458 tg.grepStderrNot(`([\\/]compile|gccgo).*t1_test.go`, "incorrectly recompiled t1")
2459 tg.grepStderrNot(`([\\/]link|gccgo).*t1_test`, "incorrectly relinked t1_test")
2460 tg.grepStdout(`ok \tt/t1\t\(cached\)`, "did not cache t/t1")
2462 // t2 imports p1 and must be rebuilt and relinked,
2463 // but the change should not have any effect on the test binary,
2464 // so the test should not have been rerun.
2465 tg.grepStderr(`([\\/]compile|gccgo).*t2_test.go`, "did not recompile t2")
2466 tg.grepStderr(`([\\/]link|gccgo).*t2\.test`, "did not relink t2_test")
2467 // This check does not currently work with gccgo, as garbage
2468 // collection of unused variables is not turned on by default.
2469 if runtime.Compiler != "gccgo" {
2470 tg.grepStdout(`ok \tt/t2\t\(cached\)`, "did not cache t/t2")
2473 // t3 imports p1, and changing X changes t3's test binary.
2474 tg.grepStderr(`([\\/]compile|gccgo).*t3_test.go`, "did not recompile t3")
2475 tg.grepStderr(`([\\/]link|gccgo).*t3\.test`, "did not relink t3_test")
2476 tg.grepStderr(`t3\.test.*-test.short`, "did not rerun t3_test")
2477 tg.grepStdoutNot(`ok \tt/t3\t\(cached\)`, "reported cached t3_test result")
2479 // t4 imports p2, but p2 did not change, so t4 should be relinked, not recompiled,
2481 tg.grepStderrNot(`([\\/]compile|gccgo).*t4_test.go`, "incorrectly recompiled t4")
2482 tg.grepStderr(`([\\/]link|gccgo).*t4\.test`, "did not relink t4_test")
2483 // This check does not currently work with gccgo, as garbage
2484 // collection of unused variables is not turned on by default.
2485 if runtime.Compiler != "gccgo" {
2486 tg.grepStdout(`ok \tt/t4\t\(cached\)`, "did not cache t/t4")
2490 func TestTestSkipVetAfterFailedBuild(t *testing.T) {
2495 tg.tempFile("x_test.go", `package x
2501 tg.runFail("test", tg.path("x_test.go"))
2502 tg.grepStderrNot(`vet`, "vet should be skipped after the failed build")
2505 func TestTestVetRebuild(t *testing.T) {
2511 // golang.org/issue/23701.
2512 // b_test imports b with augmented method from export_test.go.
2513 // b_test also imports a, which imports b.
2514 // Must not accidentally see un-augmented b propagate through a to b_test.
2515 tg.tempFile("src/a/a.go", `package a
2518 func (*Type) M() b.T {return 0}
2520 tg.tempFile("src/b/b.go", `package b
2522 type I interface {M() T}
2524 tg.tempFile("src/b/export_test.go", `package b
2525 func (*T) Method() *T { return nil }
2527 tg.tempFile("src/b/b_test.go", `package b_test
2533 func TestBroken(t *testing.T) {
2540 tg.setenv("GOPATH", tg.path("."))
2545 func TestInstallDeps(t *testing.T) {
2551 tg.setenv("GOPATH", tg.tempdir)
2553 tg.tempFile("src/p1/p1.go", "package p1\nvar X = 1\n")
2554 tg.tempFile("src/p2/p2.go", "package p2\nimport _ \"p1\"\n")
2555 tg.tempFile("src/main1/main.go", "package main\nimport _ \"p2\"\nfunc main() {}\n")
2557 tg.run("list", "-f={{.Target}}", "p1")
2558 p1 := strings.TrimSpace(tg.getStdout())
2559 tg.run("list", "-f={{.Target}}", "p2")
2560 p2 := strings.TrimSpace(tg.getStdout())
2561 tg.run("list", "-f={{.Target}}", "main1")
2562 main1 := strings.TrimSpace(tg.getStdout())
2564 tg.run("install", "main1")
2570 tg.run("install", "p2")
2574 // don't let install -i overwrite runtime
2575 tg.wantNotStale("runtime", "", "must be non-stale before install -i")
2577 tg.run("install", "-i", "main1")
2579 tg.must(os.Remove(p1))
2581 tg.run("install", "-i", "p2")
2586 func TestImportPath(t *testing.T) {
2592 tg.tempFile("src/a/a.go", `
2606 tg.tempFile("src/a/a_test.go", `
2614 func TestV(t *testing.T) {
2620 tg.tempFile("src/a/p-1.0/p.go", `
2628 tg.setenv("GOPATH", tg.path("."))
2629 tg.run("build", "-o", tg.path("a.exe"), "a")
2633 func TestBadCommandLines(t *testing.T) {
2638 tg.tempFile("src/x/x.go", "package x\n")
2639 tg.setenv("GOPATH", tg.path("."))
2641 tg.run("build", "x")
2643 tg.tempFile("src/x/@y.go", "package x\n")
2644 tg.runFail("build", "x")
2645 tg.grepStderr("invalid input file name \"@y.go\"", "did not reject @y.go")
2646 tg.must(os.Remove(tg.path("src/x/@y.go")))
2648 tg.tempFile("src/x/-y.go", "package x\n")
2649 tg.runFail("build", "x")
2650 tg.grepStderr("invalid input file name \"-y.go\"", "did not reject -y.go")
2651 tg.must(os.Remove(tg.path("src/x/-y.go")))
2653 if runtime.Compiler == "gccgo" {
2654 tg.runFail("build", "-gccgoflags=all=@x", "x")
2656 tg.runFail("build", "-gcflags=all=@x", "x")
2658 tg.grepStderr("invalid command-line argument @x in command", "did not reject @x during exec")
2660 tg.tempFile("src/@x/x.go", "package x\n")
2661 tg.setenv("GOPATH", tg.path("."))
2662 tg.runFail("build", "@x")
2663 tg.grepStderr("invalid input directory name \"@x\"|can only use path@version syntax with 'go get' and 'go install' in module-aware mode", "did not reject @x directory")
2665 tg.tempFile("src/@x/y/y.go", "package y\n")
2666 tg.setenv("GOPATH", tg.path("."))
2667 tg.runFail("build", "@x/y")
2668 tg.grepStderr("invalid import path \"@x/y\"|can only use path@version syntax with 'go get' and 'go install' in module-aware mode", "did not reject @x/y import path")
2670 tg.tempFile("src/-x/x.go", "package x\n")
2671 tg.setenv("GOPATH", tg.path("."))
2672 tg.runFail("build", "--", "-x")
2673 tg.grepStderr("invalid import path \"-x\"", "did not reject -x import path")
2675 tg.tempFile("src/-x/y/y.go", "package y\n")
2676 tg.setenv("GOPATH", tg.path("."))
2677 tg.runFail("build", "--", "-x/y")
2678 tg.grepStderr("invalid import path \"-x/y\"", "did not reject -x/y import path")
2681 func TestTwoPkgConfigs(t *testing.T) {
2685 if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
2686 t.Skipf("no shell scripts on %s", runtime.GOOS)
2692 tg.tempFile("src/x/a.go", `package x
2693 // #cgo pkg-config: --static a
2696 tg.tempFile("src/x/b.go", `package x
2697 // #cgo pkg-config: --static a
2700 tg.tempFile("pkg-config.sh", `#!/bin/sh
2701 echo $* >>`+tg.path("pkg-config.out"))
2702 tg.must(os.Chmod(tg.path("pkg-config.sh"), 0755))
2703 tg.setenv("GOPATH", tg.path("."))
2704 tg.setenv("PKG_CONFIG", tg.path("pkg-config.sh"))
2705 tg.run("build", "x")
2706 out, err := os.ReadFile(tg.path("pkg-config.out"))
2708 out = bytes.TrimSpace(out)
2709 want := "--cflags --static --static -- a a\n--libs --static --static -- a a"
2710 if !bytes.Equal(out, []byte(want)) {
2711 t.Errorf("got %q want %q", out, want)
2715 func TestCgoCache(t *testing.T) {
2724 tg.tempFile("src/x/a.go", `package main
2731 func main() { fmt.Println(C.val) }
2733 tg.setenv("GOPATH", tg.path("."))
2734 exe := tg.path("x.exe")
2735 tg.run("build", "-o", exe, "x")
2736 tg.setenv("CGO_LDFLAGS", "-lnosuchlibraryexists")
2737 tg.runFail("build", "-o", exe, "x")
2738 tg.grepStderr(`nosuchlibraryexists`, "did not run linker with changed CGO_LDFLAGS")
2742 func TestFilepathUnderCwdFormat(t *testing.T) {
2746 tg.run("test", "-x", "-cover", "log")
2747 tg.grepStderrNot(`\.log\.cover\.go`, "-x output should contain correctly formatted filepath under cwd")
2751 func TestDontReportRemoveOfEmptyDir(t *testing.T) {
2755 tg.tempFile("src/a/a.go", `package a`)
2756 tg.setenv("GOPATH", tg.path("."))
2757 tg.run("install", "-x", "a")
2758 tg.run("install", "-x", "a")
2759 // The second install should have printed only a WORK= line,
2761 if bytes.Count(tg.stdout.Bytes(), []byte{'\n'})+bytes.Count(tg.stderr.Bytes(), []byte{'\n'}) > 1 {
2762 t.Error("unnecessary output when installing installed package")
2767 func TestLinkerTmpDirIsDeleted(t *testing.T) {
2768 skipIfGccgo(t, "gccgo does not use cmd/link")
2770 t.Skip("skipping because cgo not enabled")
2777 tg.tempFile("a.go", `package main; import "C"; func main() {}`)
2778 tg.run("build", "-ldflags", "-v", "-o", os.DevNull, tg.path("a.go"))
2779 // Find line that has "host link:" in linker output.
2780 stderr := tg.getStderr()
2781 var hostLinkLine string
2782 for _, line := range strings.Split(stderr, "\n") {
2783 if !strings.Contains(line, "host link:") {
2789 if hostLinkLine == "" {
2790 t.Fatal(`fail to find with "host link:" string in linker output`)
2792 // Find parameter, like "/tmp/go-link-408556474/go.o" inside of
2793 // "host link:" line, and extract temp directory /tmp/go-link-408556474
2795 tmpdir := hostLinkLine
2796 i := strings.Index(tmpdir, `go.o"`)
2798 t.Fatalf(`fail to find "go.o" in "host link:" line %q`, hostLinkLine)
2800 tmpdir = tmpdir[:i-1]
2801 i = strings.LastIndex(tmpdir, `"`)
2803 t.Fatalf(`fail to find " in "host link:" line %q`, hostLinkLine)
2805 tmpdir = tmpdir[i+1:]
2806 // Verify that temp directory has been removed.
2807 _, err := os.Stat(tmpdir)
2809 t.Fatalf("temp directory %q has not been removed", tmpdir)
2811 if !os.IsNotExist(err) {
2812 t.Fatalf("Stat(%q) returns unexpected error: %v", tmpdir, err)
2817 func TestCoverpkgTestOnly(t *testing.T) {
2818 skipIfGccgo(t, "gccgo has no cover tool")
2823 tg.tempFile("src/a/a.go", `package a
2827 tg.tempFile("src/atest/a_test.go", `
2829 import ( "a"; "testing" )
2830 func TestF(t *testing.T) { a.F(2) }
2832 tg.setenv("GOPATH", tg.path("."))
2833 tg.run("test", "-coverpkg=a", "atest")
2834 tg.grepStderrNot("no packages being tested depend on matches", "bad match message")
2835 tg.grepStdout("coverage: 100", "no coverage")
2838 // Regression test for golang.org/issue/34499: version command should not crash
2839 // when executed in a deleted directory on Linux.
2840 func TestExecInDeletedDir(t *testing.T) {
2841 switch runtime.GOOS {
2842 case "windows", "plan9",
2843 "aix", // Fails with "device busy".
2844 "solaris", "illumos": // Fails with "invalid argument".
2845 t.Skipf("%v does not support removing the current working directory", runtime.GOOS)
2850 wd, err := os.Getwd()
2853 tg.check(os.Chdir(tg.tempdir))
2854 defer func() { tg.check(os.Chdir(wd)) }()
2856 tg.check(os.Remove(tg.tempdir))
2858 // `go version` should not fail
2862 // A missing C compiler should not force the net package to be stale.
2864 func TestMissingCC(t *testing.T) {
2866 t.Skip("test is only meaningful on systems with cgo")
2868 cc := os.Getenv("CC")
2872 if filepath.IsAbs(cc) {
2873 t.Skipf(`"CC" (%s) is an absolute path`, cc)
2875 _, err := exec.LookPath(cc)
2877 t.Skipf(`"CC" (%s) not on PATH`, cc)
2882 netStale, _ := tg.isStale("net")
2884 t.Skip(`skipping test because "net" package is currently stale`)
2887 tg.setenv("PATH", "") // No C compiler on PATH.
2888 netStale, _ = tg.isStale("net")
2890 t.Error(`clearing "PATH" causes "net" to be stale`)