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/search"
35 "cmd/go/internal/work"
42 // GOVCS defaults to public:git|hg,private:all,
43 // which breaks many tests here - they can't use non-git, non-hg VCS at all!
44 // Change to fully permissive.
45 // The tests of the GOVCS setting itself are in ../../testdata/script/govcs.txt.
46 os.Setenv("GOVCS", "*:all")
50 canRace = false // whether we can run the race detector
51 canCgo = false // whether we can use cgo
52 canMSan = false // whether we can run the memory sanitizer
53 canASan = false // whether we can run the address sanitizer
54 canFuzz = false // whether we can search for new fuzz failures
55 fuzzInstrumented = false // whether fuzzing uses instrumentation
58 var exeSuffix string = func() string {
59 if runtime.GOOS == "windows" {
65 func tooSlow(t *testing.T) {
67 // In -short mode; skip test, except run it on the {darwin,linux,windows}/amd64 builders.
68 if testenv.Builder() != "" && runtime.GOARCH == "amd64" && (runtime.GOOS == "linux" || runtime.GOOS == "darwin" || runtime.GOOS == "windows") {
72 t.Skip("skipping test in -short mode")
76 // testGOROOT is the GOROOT to use when running testgo, a cmd/go binary
77 // build from this process's current GOROOT, but run from a different
81 var testGOCACHE string
87 // The TestMain function creates a go command for testing purposes and
88 // deletes it after the tests have been run.
89 func TestMain(m *testing.M) {
90 // When CMDGO_TEST_RUN_MAIN is set, we're reusing the test binary as cmd/go.
91 // Enable the special behavior needed in cmd/go/internal/work,
92 // run the main func exported via export_test.go, and exit.
93 // We set CMDGO_TEST_RUN_MAIN via os.Setenv and testScript.setup.
94 if os.Getenv("CMDGO_TEST_RUN_MAIN") != "" {
95 if v := os.Getenv("TESTGO_VERSION"); v != "" {
96 work.RuntimeVersion = v
99 if testGOROOT := os.Getenv("TESTGO_GOROOT"); testGOROOT != "" {
100 // Disallow installs to the GOROOT from which testgo was built.
101 // Installs to other GOROOTs — such as one set explicitly within a test — are ok.
102 work.AllowInstall = func(a *work.Action) error {
107 rel := search.InDir(a.Target, testGOROOT)
113 if _, file, line, ok := runtime.Caller(1); ok {
114 if shortFile := search.InDir(file, filepath.Join(testGOROOT, "src")); shortFile != "" {
117 callerPos = fmt.Sprintf("%s:%d: ", file, line)
119 return fmt.Errorf("%stestgo must not write to GOROOT (installing to %s)", callerPos, filepath.Join("GOROOT", rel))
125 os.Setenv("CMDGO_TEST_RUN_MAIN", "true")
127 // $GO_GCFLAGS a compiler debug flag known to cmd/dist, make.bash, etc.
128 // It is not a standard go command flag; use os.Getenv, not cfg.Getenv.
129 if os.Getenv("GO_GCFLAGS") != "" {
130 fmt.Fprintf(os.Stderr, "testing: warning: no tests to run\n") // magic string for cmd/go
131 fmt.Printf("cmd/go test is not compatible with $GO_GCFLAGS being set\n")
138 if *proxyAddr != "" {
143 // Run with a temporary TMPDIR to check that the tests don't
144 // leave anything behind.
145 topTmpdir, err := os.MkdirTemp("", "cmd-go-test-")
150 defer removeAll(topTmpdir)
152 os.Setenv(tempEnvName(), topTmpdir)
154 dir, err := os.MkdirTemp(topTmpdir, "tmpdir")
160 defer removeAll(testTmpDir)
163 testGOCACHE = cache.DefaultDir()
164 if testenv.HasGoBuild() {
165 testBin = filepath.Join(testTmpDir, "testbin")
166 if err := os.Mkdir(testBin, 0777); err != nil {
169 testGo = filepath.Join(testBin, "go"+exeSuffix)
170 gotool, err := testenv.GoTool()
172 fmt.Fprintln(os.Stderr, "locating go tool: ", err)
176 goEnv := func(name string) string {
177 out, err := exec.Command(gotool, "env", name).CombinedOutput()
179 fmt.Fprintf(os.Stderr, "go env %s: %v\n%s", name, err, out)
182 return strings.TrimSpace(string(out))
184 testGOROOT = goEnv("GOROOT")
185 os.Setenv("TESTGO_GOROOT", testGOROOT)
186 // Ensure that GOROOT is set explicitly.
187 // Otherwise, if the toolchain was built with GOROOT_FINAL set but has not
188 // yet been moved to its final location, programs that invoke runtime.GOROOT
189 // may accidentally use the wrong path.
190 os.Setenv("GOROOT", testGOROOT)
192 // The whole GOROOT/pkg tree was installed using the GOHOSTOS/GOHOSTARCH
193 // toolchain (installed in GOROOT/pkg/tool/GOHOSTOS_GOHOSTARCH).
194 // The testgo.exe we are about to create will be built for GOOS/GOARCH,
195 // which means it will use the GOOS/GOARCH toolchain
196 // (installed in GOROOT/pkg/tool/GOOS_GOARCH).
197 // If these are not the same toolchain, then the entire standard library
198 // will look out of date (the compilers in those two different tool directories
199 // are built for different architectures and have different build IDs),
200 // which will cause many tests to do unnecessary rebuilds and some
201 // tests to attempt to overwrite the installed standard library.
202 // Bail out entirely in this case.
203 hostGOOS := goEnv("GOHOSTOS")
204 hostGOARCH := goEnv("GOHOSTARCH")
205 if hostGOOS != runtime.GOOS || hostGOARCH != runtime.GOARCH {
206 fmt.Fprintf(os.Stderr, "testing: warning: no tests to run\n") // magic string for cmd/go
207 fmt.Printf("cmd/go test is not compatible with GOOS/GOARCH != GOHOSTOS/GOHOSTARCH (%s/%s != %s/%s)\n", runtime.GOOS, runtime.GOARCH, hostGOOS, hostGOARCH)
212 // Duplicate the test executable into the path at testGo, for $PATH.
213 // If the OS supports symlinks, use them instead of copying bytes.
214 testExe, err := os.Executable()
218 if err := os.Symlink(testExe, testGo); err != nil {
219 // Otherwise, copy the bytes.
220 src, err := os.Open(testExe)
226 dst, err := os.OpenFile(testGo, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o777)
231 _, err = io.Copy(dst, src)
232 if closeErr := dst.Close(); err == nil {
240 cmd := exec.Command(testGo, "env", "CGO_ENABLED")
241 cmd.Stderr = new(strings.Builder)
242 if out, err := cmd.Output(); err != nil {
243 fmt.Fprintf(os.Stderr, "running testgo failed: %v\n%s", err, cmd.Stderr)
246 canCgo, err = strconv.ParseBool(strings.TrimSpace(string(out)))
248 fmt.Fprintf(os.Stderr, "can't parse go env CGO_ENABLED output: %v\n", strings.TrimSpace(string(out)))
252 out, err := exec.Command(gotool, "env", "GOCACHE").CombinedOutput()
254 fmt.Fprintf(os.Stderr, "could not find testing GOCACHE: %v\n%s", err, out)
257 testGOCACHE = strings.TrimSpace(string(out))
259 canMSan = canCgo && sys.MSanSupported(runtime.GOOS, runtime.GOARCH)
260 canASan = canCgo && sys.ASanSupported(runtime.GOOS, runtime.GOARCH)
261 canRace = canCgo && sys.RaceDetectorSupported(runtime.GOOS, runtime.GOARCH)
262 // The race detector doesn't work on Alpine Linux:
263 // golang.org/issue/14481
264 // gccgo does not support the race detector.
265 if isAlpineLinux() || runtime.Compiler == "gccgo" {
268 canFuzz = sys.FuzzSupported(runtime.GOOS, runtime.GOARCH)
269 fuzzInstrumented = sys.FuzzInstrumented(runtime.GOOS, runtime.GOARCH)
271 // Don't let these environment variables confuse the test.
272 os.Setenv("GOENV", "off")
273 os.Unsetenv("GOFLAGS")
275 os.Unsetenv("GOPATH")
276 os.Unsetenv("GIT_ALLOW_PROTOCOL")
277 os.Setenv("HOME", "/test-go-home-does-not-exist")
278 // On some systems the default C compiler is ccache.
279 // Setting HOME to a non-existent directory will break
280 // those systems. Disable ccache and use real compiler. Issue 17668.
281 os.Setenv("CCACHE_DISABLE", "1")
282 if cfg.Getenv("GOCACHE") == "" {
283 os.Setenv("GOCACHE", testGOCACHE) // because $HOME is gone
288 removeAll(testTmpDir) // os.Exit won't run defer
292 // There shouldn't be anything left in topTmpdir.
293 dirf, err := os.Open(topTmpdir)
297 names, err := dirf.Readdirnames(0)
302 log.Fatalf("unexpected files left in tmpdir: %v", names)
311 func isAlpineLinux() bool {
312 if runtime.GOOS != "linux" {
315 fi, err := os.Lstat("/etc/alpine-release")
316 return err == nil && fi.Mode().IsRegular()
319 // The length of an mtime tick on this system. This is an estimate of
320 // how long we need to sleep to ensure that the mtime of two files is
322 // We used to try to be clever but that didn't always work (see golang.org/issue/12205).
323 var mtimeTick time.Duration = 1 * time.Second
325 // Manage a single run of the testgo binary.
326 type testgoData struct {
333 stdout, stderr bytes.Buffer
334 execDir string // dir for tg.run
337 // skipIfGccgo skips the test if using gccgo.
338 func skipIfGccgo(t *testing.T, msg string) {
339 if runtime.Compiler == "gccgo" {
340 t.Skipf("skipping test not supported on gccgo: %s", msg)
344 // testgo sets up for a test that runs testgo.
345 func testgo(t *testing.T) *testgoData {
347 testenv.MustHaveGoBuild(t)
348 testenv.SkipIfShortAndSlow(t)
350 return &testgoData{t: t}
353 // must gives a fatal error if err is not nil.
354 func (tg *testgoData) must(err error) {
361 // check gives a test non-fatal error if err is not nil.
362 func (tg *testgoData) check(err error) {
369 // parallel runs the test in parallel by calling t.Parallel.
370 func (tg *testgoData) parallel() {
373 tg.t.Fatal("internal testsuite error: call to parallel after run")
375 for _, e := range tg.env {
376 if strings.HasPrefix(e, "GOROOT=") || strings.HasPrefix(e, "GOPATH=") || strings.HasPrefix(e, "GOBIN=") {
377 val := e[strings.Index(e, "=")+1:]
378 if strings.HasPrefix(val, "testdata") || strings.HasPrefix(val, "./testdata") {
379 tg.t.Fatalf("internal testsuite error: call to parallel with testdata in environment (%s)", e)
387 // pwd returns the current directory.
388 func (tg *testgoData) pwd() string {
390 wd, err := os.Getwd()
392 tg.t.Fatalf("could not get working directory: %v", err)
397 // sleep sleeps for one tick, where a tick is a conservative estimate
398 // of how long it takes for a file modification to get a different
400 func (tg *testgoData) sleep() {
401 time.Sleep(mtimeTick)
404 // setenv sets an environment variable to use when running the test go
406 func (tg *testgoData) setenv(name, val string) {
408 if tg.inParallel && (name == "GOROOT" || name == "GOPATH" || name == "GOBIN") && (strings.HasPrefix(val, "testdata") || strings.HasPrefix(val, "./testdata")) {
409 tg.t.Fatalf("internal testsuite error: call to setenv with testdata (%s=%s) after parallel", name, val)
412 tg.env = append(tg.env, name+"="+val)
415 // unsetenv removes an environment variable.
416 func (tg *testgoData) unsetenv(name string) {
418 tg.env = append([]string(nil), os.Environ()...)
419 tg.env = append(tg.env, "GO111MODULE=off")
421 for i, v := range tg.env {
422 if strings.HasPrefix(v, name+"=") {
423 tg.env = append(tg.env[:i], tg.env[i+1:]...)
429 func (tg *testgoData) goTool() string {
433 // doRun runs the test go command, recording stdout and stderr and
434 // returning exit status.
435 func (tg *testgoData) doRun(args []string) error {
438 for _, arg := range args {
439 if strings.HasPrefix(arg, "testdata") || strings.HasPrefix(arg, "./testdata") {
440 tg.t.Fatal("internal testsuite error: parallel run using testdata")
446 for _, v := range tg.env {
447 if strings.HasPrefix(v, "GOROOT=") {
454 tg.setenv("GOROOT", testGOROOT)
457 tg.t.Logf("running testgo %v", args)
458 cmd := exec.Command(prog, args...)
462 cmd.Stdout = &tg.stdout
463 cmd.Stderr = &tg.stderr
466 if tg.stdout.Len() > 0 {
467 tg.t.Log("standard output:")
468 tg.t.Log(tg.stdout.String())
470 if tg.stderr.Len() > 0 {
471 tg.t.Log("standard error:")
472 tg.t.Log(tg.stderr.String())
478 // run runs the test go command, and expects it to succeed.
479 func (tg *testgoData) run(args ...string) {
481 if status := tg.doRun(args); status != nil {
483 tg.t.Logf("go %v failed unexpectedly in %s: %v", args, wd, status)
488 // runFail runs the test go command, and expects it to fail.
489 func (tg *testgoData) runFail(args ...string) {
491 if status := tg.doRun(args); status == nil {
492 tg.t.Fatal("testgo succeeded unexpectedly")
494 tg.t.Log("testgo failed as expected:", status)
498 // runGit runs a git command, and expects it to succeed.
499 func (tg *testgoData) runGit(dir string, args ...string) {
501 cmd := exec.Command("git", args...)
504 cmd.Stdout = &tg.stdout
505 cmd.Stderr = &tg.stderr
509 if tg.stdout.Len() > 0 {
510 tg.t.Log("git standard output:")
511 tg.t.Log(tg.stdout.String())
513 if tg.stderr.Len() > 0 {
514 tg.t.Log("git standard error:")
515 tg.t.Log(tg.stderr.String())
518 tg.t.Logf("git %v failed unexpectedly: %v", args, status)
523 // getStdout returns standard output of the testgo run as a string.
524 func (tg *testgoData) getStdout() string {
527 tg.t.Fatal("internal testsuite error: stdout called before run")
529 return tg.stdout.String()
532 // getStderr returns standard error of the testgo run as a string.
533 func (tg *testgoData) getStderr() string {
536 tg.t.Fatal("internal testsuite error: stdout called before run")
538 return tg.stderr.String()
541 // doGrepMatch looks for a regular expression in a buffer, and returns
542 // whether it is found. The regular expression is matched against
543 // each line separately, as with the grep command.
544 func (tg *testgoData) doGrepMatch(match string, b *bytes.Buffer) bool {
547 tg.t.Fatal("internal testsuite error: grep called before run")
549 re := regexp.MustCompile(match)
550 for _, ln := range bytes.Split(b.Bytes(), []byte{'\n'}) {
558 // doGrep looks for a regular expression in a buffer and fails if it
559 // is not found. The name argument is the name of the output we are
560 // searching, "output" or "error". The msg argument is logged on
562 func (tg *testgoData) doGrep(match string, b *bytes.Buffer, name, msg string) {
564 if !tg.doGrepMatch(match, b) {
566 tg.t.Logf("pattern %v not found in standard %s", match, name)
571 // grepStdout looks for a regular expression in the test run's
572 // standard output and fails, logging msg, if it is not found.
573 func (tg *testgoData) grepStdout(match, msg string) {
575 tg.doGrep(match, &tg.stdout, "output", msg)
578 // grepStderr looks for a regular expression in the test run's
579 // standard error and fails, logging msg, if it is not found.
580 func (tg *testgoData) grepStderr(match, msg string) {
582 tg.doGrep(match, &tg.stderr, "error", msg)
585 // grepBoth looks for a regular expression in the test run's standard
586 // output or stand error and fails, logging msg, if it is not found.
587 func (tg *testgoData) grepBoth(match, msg string) {
589 if !tg.doGrepMatch(match, &tg.stdout) && !tg.doGrepMatch(match, &tg.stderr) {
591 tg.t.Logf("pattern %v not found in standard output or standard error", match)
596 // doGrepNot looks for a regular expression in a buffer and fails if
597 // it is found. The name and msg arguments are as for doGrep.
598 func (tg *testgoData) doGrepNot(match string, b *bytes.Buffer, name, msg string) {
600 if tg.doGrepMatch(match, b) {
602 tg.t.Logf("pattern %v found unexpectedly in standard %s", match, name)
607 // grepStdoutNot looks for a regular expression in the test run's
608 // standard output and fails, logging msg, if it is found.
609 func (tg *testgoData) grepStdoutNot(match, msg string) {
611 tg.doGrepNot(match, &tg.stdout, "output", msg)
614 // grepStderrNot looks for a regular expression in the test run's
615 // standard error and fails, logging msg, if it is found.
616 func (tg *testgoData) grepStderrNot(match, msg string) {
618 tg.doGrepNot(match, &tg.stderr, "error", msg)
621 // grepBothNot looks for a regular expression in the test run's
622 // standard output or standard error and fails, logging msg, if it is
624 func (tg *testgoData) grepBothNot(match, msg string) {
626 if tg.doGrepMatch(match, &tg.stdout) || tg.doGrepMatch(match, &tg.stderr) {
628 tg.t.Fatalf("pattern %v found unexpectedly in standard output or standard error", match)
632 // doGrepCount counts the number of times a regexp is seen in a buffer.
633 func (tg *testgoData) doGrepCount(match string, b *bytes.Buffer) int {
636 tg.t.Fatal("internal testsuite error: doGrepCount called before run")
638 re := regexp.MustCompile(match)
640 for _, ln := range bytes.Split(b.Bytes(), []byte{'\n'}) {
648 // grepCountBoth returns the number of times a regexp is seen in both
649 // standard output and standard error.
650 func (tg *testgoData) grepCountBoth(match string) int {
652 return tg.doGrepCount(match, &tg.stdout) + tg.doGrepCount(match, &tg.stderr)
655 // creatingTemp records that the test plans to create a temporary file
656 // or directory. If the file or directory exists already, it will be
657 // removed. When the test completes, the file or directory will be
658 // removed if it exists.
659 func (tg *testgoData) creatingTemp(path string) {
661 if filepath.IsAbs(path) && !strings.HasPrefix(path, tg.tempdir) {
662 tg.t.Fatalf("internal testsuite error: creatingTemp(%q) with absolute path not in temporary directory", path)
664 tg.must(robustio.RemoveAll(path))
665 tg.temps = append(tg.temps, path)
668 // makeTempdir makes a temporary directory for a run of testgo. If
669 // the temporary directory was already created, this does nothing.
670 func (tg *testgoData) makeTempdir() {
672 if tg.tempdir == "" {
674 tg.tempdir, err = os.MkdirTemp("", "gotest")
679 // tempFile adds a temporary file for a run of testgo.
680 func (tg *testgoData) tempFile(path, contents string) {
683 tg.must(os.MkdirAll(filepath.Join(tg.tempdir, filepath.Dir(path)), 0755))
684 bytes := []byte(contents)
685 if strings.HasSuffix(path, ".go") {
686 formatted, err := format.Source(bytes)
691 tg.must(os.WriteFile(filepath.Join(tg.tempdir, path), bytes, 0644))
694 // tempDir adds a temporary directory for a run of testgo.
695 func (tg *testgoData) tempDir(path string) {
698 if err := os.MkdirAll(filepath.Join(tg.tempdir, path), 0755); err != nil && !os.IsExist(err) {
703 // path returns the absolute pathname to file with the temporary
705 func (tg *testgoData) path(name string) string {
707 if tg.tempdir == "" {
708 tg.t.Fatalf("internal testsuite error: path(%q) with no tempdir", name)
713 return filepath.Join(tg.tempdir, name)
716 // mustExist fails if path does not exist.
717 func (tg *testgoData) mustExist(path string) {
719 if _, err := os.Stat(path); err != nil {
720 if os.IsNotExist(err) {
721 tg.t.Fatalf("%s does not exist but should", path)
723 tg.t.Fatalf("%s stat failed: %v", path, err)
727 // mustNotExist fails if path exists.
728 func (tg *testgoData) mustNotExist(path string) {
730 if _, err := os.Stat(path); err == nil || !os.IsNotExist(err) {
731 tg.t.Fatalf("%s exists but should not (%v)", path, err)
735 // mustHaveContent succeeds if filePath is a path to a file,
736 // and that file is readable and not empty.
737 func (tg *testgoData) mustHaveContent(filePath string) {
738 tg.mustExist(filePath)
739 f, err := os.Stat(filePath)
744 tg.t.Fatalf("expected %s to have data, but is empty", filePath)
748 // wantExecutable fails with msg if path is not executable.
749 func (tg *testgoData) wantExecutable(path, msg string) {
751 if st, err := os.Stat(path); err != nil {
752 if !os.IsNotExist(err) {
757 if runtime.GOOS != "windows" && st.Mode()&0111 == 0 {
758 tg.t.Fatalf("binary %s exists but is not executable", path)
763 // isStale reports whether pkg is stale, and why
764 func (tg *testgoData) isStale(pkg string) (bool, string) {
766 tg.run("list", "-f", "{{.Stale}}:{{.StaleReason}}", pkg)
767 v := strings.TrimSpace(tg.getStdout())
768 f := strings.SplitN(v, ":", 2)
777 tg.t.Fatalf("unexpected output checking staleness of package %v: %v", pkg, v)
781 // wantStale fails with msg if pkg is not stale.
782 func (tg *testgoData) wantStale(pkg, reason, msg string) {
784 stale, why := tg.isStale(pkg)
788 // We always accept the reason as being "not installed but
789 // available in build cache", because when that is the case go
790 // list doesn't try to sort out the underlying reason why the
791 // package is not installed.
792 if reason == "" && why != "" || !strings.Contains(why, reason) && !strings.Contains(why, "not installed but available in build cache") {
793 tg.t.Errorf("wrong reason for Stale=true: %q, want %q", why, reason)
797 // wantNotStale fails with msg if pkg is stale.
798 func (tg *testgoData) wantNotStale(pkg, reason, msg string) {
800 stale, why := tg.isStale(pkg)
804 if reason == "" && why != "" || !strings.Contains(why, reason) {
805 tg.t.Errorf("wrong reason for Stale=false: %q, want %q", why, reason)
809 // If -testwork is specified, the test prints the name of the temp directory
810 // and does not remove it when done, so that a programmer can
811 // poke at the test file tree afterward.
812 var testWork = flag.Bool("testwork", false, "")
814 // cleanup cleans up a test that runs testgo.
815 func (tg *testgoData) cleanup() {
818 tg.t.Logf("TESTWORK=%s\n", tg.path("."))
821 for _, path := range tg.temps {
822 tg.check(removeAll(path))
824 if tg.tempdir != "" {
825 tg.check(removeAll(tg.tempdir))
829 func removeAll(dir string) error {
830 // module cache has 0444 directories;
831 // make them writable in order to remove content.
832 filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error {
833 // chmod not only directories, but also things that we couldn't even stat
834 // due to permission errors: they may also be unreadable directories.
835 if err != nil || info.IsDir() {
840 return robustio.RemoveAll(dir)
843 // failSSH puts an ssh executable in the PATH that always fails.
844 // This is to stub out uses of ssh by go get.
845 func (tg *testgoData) failSSH() {
847 wd, err := os.Getwd()
851 fail := filepath.Join(wd, "testdata/failssh")
852 tg.setenv("PATH", fmt.Sprintf("%v%c%v", fail, filepath.ListSeparator, os.Getenv("PATH")))
855 func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) {
857 t.Skip("skipping lengthy test in short mode")
864 // Copy the runtime packages into a temporary GOROOT
865 // so that we can change files.
866 for _, copydir := range []string{
869 "src/internal/bytealg",
871 "src/internal/goarch",
872 "src/internal/goexperiment",
876 filepath.Join("pkg", runtime.GOOS+"_"+runtime.GOARCH),
877 filepath.Join("pkg/tool", runtime.GOOS+"_"+runtime.GOARCH),
880 srcdir := filepath.Join(testGOROOT, copydir)
881 tg.tempDir(filepath.Join("goroot", copydir))
882 err := filepath.WalkDir(srcdir,
883 func(path string, info fs.DirEntry, err error) error {
890 srcrel, err := filepath.Rel(srcdir, path)
894 dest := filepath.Join("goroot", copydir, srcrel)
895 data, err := os.ReadFile(path)
899 tg.tempFile(dest, string(data))
900 if strings.Contains(copydir, filepath.Join("pkg", "tool")) {
901 os.Chmod(tg.path(dest), 0777)
909 tg.setenv("GOROOT", tg.path("goroot"))
911 addVar := func(name string, idx int) (restore func()) {
912 data, err := os.ReadFile(name)
917 data = append(data, fmt.Sprintf("var DummyUnusedVar%d bool\n", idx)...)
918 if err := os.WriteFile(name, append(data, '\n'), 0666); err != nil {
923 if err := os.WriteFile(name, old, 0666); err != nil {
929 // Every main package depends on the "runtime".
930 tg.tempFile("d1/src/p1/p1.go", `package main; func main(){}`)
931 tg.setenv("GOPATH", tg.path("d1"))
932 // Pass -i flag to rebuild everything outdated.
933 tg.run("install", "-i", "p1")
934 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, before any changes")
936 // Changing mtime of runtime/internal/sys/sys.go
937 // should have no effect: only the content matters.
938 // In fact this should be true even outside a release branch.
939 sys := tg.path("goroot/src/runtime/internal/sys/sys.go")
941 restore := addVar(sys, 0)
943 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, after updating mtime of runtime/internal/sys/sys.go")
945 // But changing content of any file should have an effect.
946 // Previously zversion.go was the only one that mattered;
947 // now they all matter, so keep using sys.go.
948 restore = addVar(sys, 1)
950 tg.wantStale("p1", "stale dependency: runtime/internal/sys", "./testgo list claims p1 is NOT stale, incorrectly, after changing sys.go")
952 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, after changing back to old release")
954 tg.wantStale("p1", "stale dependency: runtime", "./testgo list claims p1 is NOT stale, incorrectly, after changing sys.go again")
955 tg.run("install", "-i", "p1")
956 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after building with new release")
958 // Restore to "old" release.
960 tg.wantStale("p1", "stale dependency: runtime/internal/sys", "./testgo list claims p1 is NOT stale, incorrectly, after restoring sys.go")
961 tg.run("install", "-i", "p1")
962 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after building with old release")
965 // cmd/go: custom import path checking should not apply to Go packages without import comment.
966 func TestIssue10952(t *testing.T) {
967 testenv.MustHaveExternalNetwork(t)
968 testenv.MustHaveExecPath(t, "git")
974 tg.setenv("GOPATH", tg.path("."))
975 const importPath = "github.com/zombiezen/go-get-issue-10952"
976 tg.run("get", "-d", "-u", importPath)
977 repoDir := tg.path("src/" + importPath)
978 tg.runGit(repoDir, "remote", "set-url", "origin", "https://"+importPath+".git")
979 tg.run("get", "-d", "-u", importPath)
982 func TestIssue16471(t *testing.T) {
983 testenv.MustHaveExternalNetwork(t)
984 testenv.MustHaveExecPath(t, "git")
990 tg.setenv("GOPATH", tg.path("."))
991 tg.must(os.MkdirAll(tg.path("src/rsc.io/go-get-issue-10952"), 0755))
992 tg.runGit(tg.path("src/rsc.io"), "clone", "https://github.com/zombiezen/go-get-issue-10952")
993 tg.runFail("get", "-u", "rsc.io/go-get-issue-10952")
994 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")
997 // Test git clone URL that uses SCP-like syntax and custom import path checking.
998 func TestIssue11457(t *testing.T) {
999 testenv.MustHaveExternalNetwork(t)
1000 testenv.MustHaveExecPath(t, "git")
1006 tg.setenv("GOPATH", tg.path("."))
1007 const importPath = "rsc.io/go-get-issue-11457"
1008 tg.run("get", "-d", "-u", importPath)
1009 repoDir := tg.path("src/" + importPath)
1010 tg.runGit(repoDir, "remote", "set-url", "origin", "git@github.com:rsc/go-get-issue-11457")
1012 // At this time, custom import path checking compares remotes verbatim (rather than
1013 // just the host and path, skipping scheme and user), so we expect go get -u to fail.
1014 // However, the goal of this test is to verify that gitRemoteRepo correctly parsed
1015 // the SCP-like syntax, and we expect it to appear in the error message.
1016 tg.runFail("get", "-d", "-u", importPath)
1017 want := " is checked out from ssh://git@github.com/rsc/go-get-issue-11457"
1018 if !strings.HasSuffix(strings.TrimSpace(tg.getStderr()), want) {
1019 t.Error("expected clone URL to appear in stderr")
1023 func TestGetGitDefaultBranch(t *testing.T) {
1024 testenv.MustHaveExternalNetwork(t)
1025 testenv.MustHaveExecPath(t, "git")
1031 tg.setenv("GOPATH", tg.path("."))
1033 // This repo has two branches, master and another-branch.
1034 // The another-branch is the default that you get from 'git clone'.
1035 // The go get command variants should not override this.
1036 const importPath = "github.com/rsc/go-get-default-branch"
1038 tg.run("get", "-d", importPath)
1039 repoDir := tg.path("src/" + importPath)
1040 tg.runGit(repoDir, "branch", "--contains", "HEAD")
1041 tg.grepStdout(`\* another-branch`, "not on correct default branch")
1043 tg.run("get", "-d", "-u", importPath)
1044 tg.runGit(repoDir, "branch", "--contains", "HEAD")
1045 tg.grepStdout(`\* another-branch`, "not on correct default branch")
1048 // Security issue. Don't disable. See golang.org/issue/22125.
1049 func TestAccidentalGitCheckout(t *testing.T) {
1050 testenv.MustHaveExternalNetwork(t)
1051 testenv.MustHaveExecPath(t, "git")
1052 testenv.MustHaveExecPath(t, "svn")
1059 tg.setenv("GOPATH", tg.path("."))
1061 tg.runFail("get", "-u", "vcs-test.golang.org/go/test1-svn-git")
1062 tg.grepStderr("src[\\\\/]vcs-test.* uses git, but parent .*src[\\\\/]vcs-test.* uses svn", "get did not fail for right reason")
1064 if _, err := os.Stat(tg.path("SrC")); err == nil {
1065 // This case only triggers on a case-insensitive file system.
1066 tg.runFail("get", "-u", "vcs-test.golang.org/go/test2-svn-git/test2main")
1067 tg.grepStderr("src[\\\\/]vcs-test.* uses git, but parent .*src[\\\\/]vcs-test.* uses svn", "get did not fail for right reason")
1071 func TestPackageMainTestCompilerFlags(t *testing.T) {
1076 tg.setenv("GOPATH", tg.path("."))
1077 tg.tempFile("src/p1/p1.go", "package main\n")
1078 tg.tempFile("src/p1/p1_test.go", "package main\nimport \"testing\"\nfunc Test(t *testing.T){}\n")
1079 tg.run("test", "-c", "-n", "p1")
1080 tg.grepBothNot(`([\\/]compile|gccgo).* (-p main|-fgo-pkgpath=main).*p1\.go`, "should not have run compile -p main p1.go")
1081 tg.grepStderr(`([\\/]compile|gccgo).* (-p p1|-fgo-pkgpath=p1).*p1\.go`, "should have run compile -p p1 p1.go")
1085 func TestGoTestWithPackageListedMultipleTimes(t *testing.T) {
1090 tg.run("test", "errors", "errors", "errors", "errors", "errors")
1091 if strings.Contains(strings.TrimSpace(tg.getStdout()), "\n") {
1092 t.Error("go test errors errors errors errors errors tested the same package multiple times")
1096 func TestGoListHasAConsistentOrder(t *testing.T) {
1101 tg.run("list", "std")
1102 first := tg.getStdout()
1103 tg.run("list", "std")
1104 if first != tg.getStdout() {
1105 t.Error("go list std ordering is inconsistent")
1109 func TestGoListStdDoesNotIncludeCommands(t *testing.T) {
1114 tg.run("list", "std")
1115 tg.grepStdoutNot("cmd/", "go list std shows commands")
1118 func TestGoListCmdOnlyShowsCommands(t *testing.T) {
1119 skipIfGccgo(t, "gccgo does not have GOROOT")
1124 tg.run("list", "cmd")
1125 out := strings.TrimSpace(tg.getStdout())
1126 for _, line := range strings.Split(out, "\n") {
1127 if !strings.Contains(line, "cmd/") {
1128 t.Error("go list cmd shows non-commands")
1134 func TestGoListDeps(t *testing.T) {
1138 tg.tempDir("src/p1/p2/p3/p4")
1139 tg.setenv("GOPATH", tg.path("."))
1140 tg.tempFile("src/p1/p.go", "package p1\nimport _ \"p1/p2\"\n")
1141 tg.tempFile("src/p1/p2/p.go", "package p2\nimport _ \"p1/p2/p3\"\n")
1142 tg.tempFile("src/p1/p2/p3/p.go", "package p3\nimport _ \"p1/p2/p3/p4\"\n")
1143 tg.tempFile("src/p1/p2/p3/p4/p.go", "package p4\n")
1144 tg.run("list", "-f", "{{.Deps}}", "p1")
1145 tg.grepStdout("p1/p2/p3/p4", "Deps(p1) does not mention p4")
1147 tg.run("list", "-deps", "p1")
1148 tg.grepStdout("p1/p2/p3/p4", "-deps p1 does not mention p4")
1150 if runtime.Compiler != "gccgo" {
1151 // Check the list is in dependency order.
1152 tg.run("list", "-deps", "math")
1153 want := "internal/cpu\nunsafe\nmath/bits\nmath\n"
1154 out := tg.stdout.String()
1155 if !strings.Contains(out, "internal/cpu") {
1156 // Some systems don't use internal/cpu.
1157 want = "unsafe\nmath/bits\nmath\n"
1159 if tg.stdout.String() != want {
1160 t.Fatalf("list -deps math: wrong order\nhave %q\nwant %q", tg.stdout.String(), want)
1165 func TestGoListTest(t *testing.T) {
1166 skipIfGccgo(t, "gccgo does not have standard packages")
1171 tg.setenv("GOCACHE", tg.tempdir)
1173 tg.run("list", "-test", "-deps", "sort")
1174 tg.grepStdout(`^sort.test$`, "missing test main")
1175 tg.grepStdout(`^sort$`, "missing real sort")
1176 tg.grepStdout(`^sort \[sort.test\]$`, "missing test copy of sort")
1177 tg.grepStdout(`^testing \[sort.test\]$`, "missing test copy of testing")
1178 tg.grepStdoutNot(`^testing$`, "unexpected real copy of testing")
1180 tg.run("list", "-test", "sort")
1181 tg.grepStdout(`^sort.test$`, "missing test main")
1182 tg.grepStdout(`^sort$`, "missing real sort")
1183 tg.grepStdout(`^sort \[sort.test\]$`, "unexpected test copy of sort")
1184 tg.grepStdoutNot(`^testing \[sort.test\]$`, "unexpected test copy of testing")
1185 tg.grepStdoutNot(`^testing$`, "unexpected real copy of testing")
1187 tg.run("list", "-test", "cmd/buildid", "cmd/doc")
1188 tg.grepStdout(`^cmd/buildid$`, "missing cmd/buildid")
1189 tg.grepStdout(`^cmd/doc$`, "missing cmd/doc")
1190 tg.grepStdout(`^cmd/doc\.test$`, "missing cmd/doc test")
1191 tg.grepStdoutNot(`^cmd/buildid\.test$`, "unexpected cmd/buildid test")
1192 tg.grepStdoutNot(`^testing`, "unexpected testing")
1194 tg.run("list", "-test", "runtime/cgo")
1195 tg.grepStdout(`^runtime/cgo$`, "missing runtime/cgo")
1197 tg.run("list", "-deps", "-f", "{{if .DepOnly}}{{.ImportPath}}{{end}}", "sort")
1198 tg.grepStdout(`^internal/reflectlite$`, "missing internal/reflectlite")
1199 tg.grepStdoutNot(`^sort`, "unexpected sort")
1202 func TestGoListCompiledCgo(t *testing.T) {
1208 tg.setenv("GOCACHE", tg.tempdir)
1210 tg.run("list", "-f", `{{join .CgoFiles "\n"}}`, "net")
1211 if tg.stdout.String() == "" {
1212 t.Skip("net does not use cgo")
1214 if strings.Contains(tg.stdout.String(), tg.tempdir) {
1215 t.Fatalf(".CgoFiles unexpectedly mentioned cache %s", tg.tempdir)
1217 tg.run("list", "-compiled", "-f", `{{.Dir}}{{"\n"}}{{join .CompiledGoFiles "\n"}}`, "net")
1218 if !strings.Contains(tg.stdout.String(), tg.tempdir) {
1219 t.Fatalf(".CompiledGoFiles with -compiled did not mention cache %s", tg.tempdir)
1222 for _, file := range strings.Split(tg.stdout.String(), "\n") {
1230 if !strings.Contains(file, "/") && !strings.Contains(file, `\`) {
1231 file = filepath.Join(dir, file)
1233 if _, err := os.Stat(file); err != nil {
1234 t.Fatalf("cannot find .CompiledGoFiles result %s: %v", file, err)
1239 func TestGoListExport(t *testing.T) {
1240 skipIfGccgo(t, "gccgo does not have standard packages")
1245 tg.setenv("GOCACHE", tg.tempdir)
1247 tg.run("list", "-f", "{{.Export}}", "strings")
1248 if tg.stdout.String() != "" {
1249 t.Fatalf(".Export without -export unexpectedly set")
1251 tg.run("list", "-export", "-f", "{{.Export}}", "strings")
1252 file := strings.TrimSpace(tg.stdout.String())
1254 t.Fatalf(".Export with -export was empty")
1256 if _, err := os.Stat(file); err != nil {
1257 t.Fatalf("cannot find .Export result %s: %v", file, err)
1260 tg.run("list", "-export", "-f", "{{.BuildID}}", "strings")
1261 buildID := strings.TrimSpace(tg.stdout.String())
1263 t.Fatalf(".BuildID with -export was empty")
1266 tg.run("tool", "buildid", file)
1267 toolBuildID := strings.TrimSpace(tg.stdout.String())
1268 if buildID != toolBuildID {
1269 t.Fatalf(".BuildID with -export %q disagrees with 'go tool buildid' %q", buildID, toolBuildID)
1273 // Issue 4096. Validate the output of unsuccessful go install foo/quxx.
1274 func TestUnsuccessfulGoInstallShouldMentionMissingPackage(t *testing.T) {
1278 tg.runFail("install", "foo/quxx")
1279 if tg.grepCountBoth(`cannot find package "foo/quxx" in any of`) != 1 {
1280 t.Error(`go install foo/quxx expected error: .*cannot find package "foo/quxx" in any of`)
1284 func TestGOROOTSearchFailureReporting(t *testing.T) {
1288 tg.runFail("install", "foo/quxx")
1289 if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("foo", "quxx"))+` \(from \$GOROOT\)$`) != 1 {
1290 t.Error(`go install foo/quxx expected error: .*foo/quxx (from $GOROOT)`)
1294 func TestMultipleGOPATHEntriesReportedSeparately(t *testing.T) {
1298 sep := string(filepath.ListSeparator)
1299 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
1300 tg.runFail("install", "foo/quxx")
1301 if tg.grepCountBoth(`testdata[/\\].[/\\]src[/\\]foo[/\\]quxx`) != 2 {
1302 t.Error(`go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)\n.*testdata/b/src/foo/quxx`)
1306 // Test (from $GOPATH) annotation is reported for the first GOPATH entry,
1307 func TestMentionGOPATHInFirstGOPATHEntry(t *testing.T) {
1311 sep := string(filepath.ListSeparator)
1312 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
1313 tg.runFail("install", "foo/quxx")
1314 if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("testdata", "a", "src", "foo", "quxx"))+` \(from \$GOPATH\)$`) != 1 {
1315 t.Error(`go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)`)
1319 // but not on the second.
1320 func TestMentionGOPATHNotOnSecondEntry(t *testing.T) {
1324 sep := string(filepath.ListSeparator)
1325 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
1326 tg.runFail("install", "foo/quxx")
1327 if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("testdata", "b", "src", "foo", "quxx"))+`$`) != 1 {
1328 t.Error(`go install foo/quxx expected error: .*testdata/b/src/foo/quxx`)
1332 func homeEnvName() string {
1333 switch runtime.GOOS {
1335 return "USERPROFILE"
1343 func tempEnvName() string {
1344 switch runtime.GOOS {
1348 return "TMPDIR" // actually plan 9 doesn't have one at all but this is fine
1354 func TestDefaultGOPATH(t *testing.T) {
1358 tg.tempDir("home/go")
1359 tg.setenv(homeEnvName(), tg.path("home"))
1361 tg.run("env", "GOPATH")
1362 tg.grepStdout(regexp.QuoteMeta(tg.path("home/go")), "want GOPATH=$HOME/go")
1364 tg.setenv("GOROOT", tg.path("home/go"))
1365 tg.run("env", "GOPATH")
1366 tg.grepStdoutNot(".", "want unset GOPATH because GOROOT=$HOME/go")
1368 tg.setenv("GOROOT", tg.path("home/go")+"/")
1369 tg.run("env", "GOPATH")
1370 tg.grepStdoutNot(".", "want unset GOPATH because GOROOT=$HOME/go/")
1373 func TestDefaultGOPATHGet(t *testing.T) {
1374 testenv.MustHaveExternalNetwork(t)
1375 testenv.MustHaveExecPath(t, "git")
1380 tg.setenv("GOPATH", "")
1382 tg.setenv(homeEnvName(), tg.path("home"))
1384 // warn for creating directory
1385 tg.run("get", "-v", "github.com/golang/example/hello")
1386 tg.grepStderr("created GOPATH="+regexp.QuoteMeta(tg.path("home/go"))+"; see 'go help gopath'", "did not create GOPATH")
1388 // no warning if directory already exists
1389 tg.must(robustio.RemoveAll(tg.path("home/go")))
1390 tg.tempDir("home/go")
1391 tg.run("get", "github.com/golang/example/hello")
1392 tg.grepStderrNot(".", "expected no output on standard error")
1394 // error if $HOME/go is a file
1395 tg.must(robustio.RemoveAll(tg.path("home/go")))
1396 tg.tempFile("home/go", "")
1397 tg.runFail("get", "github.com/golang/example/hello")
1398 tg.grepStderr(`mkdir .*[/\\]go: .*(not a directory|cannot find the path)`, "expected error because $HOME/go is a file")
1401 func TestDefaultGOPATHPrintedSearchList(t *testing.T) {
1405 tg.setenv("GOPATH", "")
1407 tg.setenv(homeEnvName(), tg.path("home"))
1409 tg.runFail("install", "github.com/golang/example/hello")
1410 tg.grepStderr(regexp.QuoteMeta(tg.path("home/go/src/github.com/golang/example/hello"))+`.*from \$GOPATH`, "expected default GOPATH")
1413 func TestLdflagsArgumentsWithSpacesIssue3941(t *testing.T) {
1414 skipIfGccgo(t, "gccgo does not support -ldflags -X")
1419 tg.tempFile("main.go", `package main
1424 tg.run("run", "-ldflags", `-X "main.extern=hello world"`, tg.path("main.go"))
1425 tg.grepStderr("^hello world", `ldflags -X "main.extern=hello world"' failed`)
1428 func TestLdFlagsLongArgumentsIssue42295(t *testing.T) {
1429 // Test the extremely long command line arguments that contain '\n' characters
1430 // get encoded and passed correctly.
1431 skipIfGccgo(t, "gccgo does not support -ldflags -X")
1436 tg.tempFile("main.go", `package main
1441 testStr := "test test test test test \n\\ "
1442 var buf bytes.Buffer
1443 for buf.Len() < sys.ExecArgLengthLimit+1 {
1444 buf.WriteString(testStr)
1446 tg.run("run", "-ldflags", fmt.Sprintf(`-X "main.extern=%s"`, buf.String()), tg.path("main.go"))
1447 if tg.stderr.String() != buf.String() {
1448 t.Errorf("strings differ")
1452 func TestGoTestDashCDashOControlsBinaryLocation(t *testing.T) {
1453 skipIfGccgo(t, "gccgo has no standard packages")
1459 tg.run("test", "-c", "-o", tg.path("myerrors.test"+exeSuffix), "errors")
1460 tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -c -o myerrors.test did not create myerrors.test")
1463 func TestGoTestDashOWritesBinary(t *testing.T) {
1464 skipIfGccgo(t, "gccgo has no standard packages")
1470 tg.run("test", "-o", tg.path("myerrors.test"+exeSuffix), "errors")
1471 tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -o myerrors.test did not create myerrors.test")
1474 func TestGoTestDashIDashOWritesBinary(t *testing.T) {
1475 skipIfGccgo(t, "gccgo has no standard packages")
1482 // don't let test -i overwrite runtime
1483 tg.wantNotStale("runtime", "", "must be non-stale before test -i")
1485 tg.run("test", "-v", "-i", "-o", tg.path("myerrors.test"+exeSuffix), "errors")
1486 tg.grepBothNot("PASS|FAIL", "test should not have run")
1487 tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -o myerrors.test did not create myerrors.test")
1491 func TestInstallWithTags(t *testing.T) {
1497 tg.tempFile("src/example/a/main.go", `package main
1499 tg.tempFile("src/example/b/main.go", `// +build mytag
1503 tg.setenv("GOPATH", tg.path("."))
1504 tg.run("install", "-tags", "mytag", "example/a", "example/b")
1505 tg.wantExecutable(tg.path("bin/a"+exeSuffix), "go install example/a example/b did not install binaries")
1506 tg.wantExecutable(tg.path("bin/b"+exeSuffix), "go install example/a example/b did not install binaries")
1507 tg.must(os.Remove(tg.path("bin/a" + exeSuffix)))
1508 tg.must(os.Remove(tg.path("bin/b" + exeSuffix)))
1509 tg.run("install", "-tags", "mytag", "example/...")
1510 tg.wantExecutable(tg.path("bin/a"+exeSuffix), "go install example/... did not install binaries")
1511 tg.wantExecutable(tg.path("bin/b"+exeSuffix), "go install example/... did not install binaries")
1512 tg.run("list", "-tags", "mytag", "example/b...")
1513 if strings.TrimSpace(tg.getStdout()) != "example/b" {
1514 t.Error("go list example/b did not find example/b")
1518 // Issue 17451, 17662.
1519 func TestSymlinkWarning(t *testing.T) {
1524 tg.setenv("GOPATH", tg.path("."))
1526 tg.tempDir("src/example/xx")
1528 tg.tempFile("yy/zz/zz.go", "package zz\n")
1529 if err := os.Symlink(tg.path("yy"), tg.path("src/example/xx/yy")); err != nil {
1530 t.Skipf("symlink failed: %v", err)
1532 tg.run("list", "example/xx/z...")
1533 tg.grepStdoutNot(".", "list should not have matched anything")
1534 tg.grepStderr("matched no packages", "list should have reported that pattern matched no packages")
1535 tg.grepStderrNot("symlink", "list should not have reported symlink")
1537 tg.run("list", "example/xx/...")
1538 tg.grepStdoutNot(".", "list should not have matched anything")
1539 tg.grepStderr("matched no packages", "list should have reported that pattern matched no packages")
1540 tg.grepStderr("ignoring symlink", "list should have reported symlink")
1543 func TestCgoShowsFullPathNames(t *testing.T) {
1545 t.Skip("skipping because cgo not enabled")
1551 tg.tempFile("src/x/y/dirname/foo.go", `
1555 tg.setenv("GOPATH", tg.path("."))
1556 tg.runFail("build", "x/y/dirname")
1557 tg.grepBoth("x/y/dirname", "error did not use full path")
1560 func TestCgoHandlesWlORIGIN(t *testing.T) {
1563 t.Skip("skipping because cgo not enabled")
1569 tg.tempFile("src/origin/origin.go", `package origin
1570 // #cgo !darwin LDFLAGS: -Wl,-rpath,$ORIGIN
1573 func f() { C.f() }`)
1574 tg.setenv("GOPATH", tg.path("."))
1575 tg.run("build", "origin")
1578 func TestCgoPkgConfig(t *testing.T) {
1581 t.Skip("skipping because cgo not enabled")
1587 tg.run("env", "PKG_CONFIG")
1588 pkgConfig := strings.TrimSpace(tg.getStdout())
1589 testenv.MustHaveExecPath(t, pkgConfig)
1590 if out, err := exec.Command(pkgConfig, "--atleast-pkgconfig-version", "0.24").CombinedOutput(); err != nil {
1591 t.Skipf("%s --atleast-pkgconfig-version 0.24: %v\n%s", pkgConfig, err, out)
1594 // OpenBSD's pkg-config is strict about whitespace and only
1595 // supports backslash-escaped whitespace. It does not support
1596 // quotes, which the normal freedesktop.org pkg-config does
1597 // support. See https://man.openbsd.org/pkg-config.1
1598 tg.tempFile("foo.pc", `
1600 Description: The foo library
1602 Cflags: -Dhello=10 -Dworld=+32 -DDEFINED_FROM_PKG_CONFIG=hello\ world
1604 tg.tempFile("foo.go", `package main
1607 #cgo pkg-config: foo
1609 return DEFINED_FROM_PKG_CONFIG;
1616 if C.value() != 42 {
1617 println("value() =", C.value(), "wanted 42")
1622 tg.setenv("PKG_CONFIG_PATH", tg.path("."))
1623 tg.run("run", tg.path("foo.go"))
1626 func TestListTemplateContextFunction(t *testing.T) {
1628 for _, tt := range []struct {
1632 {"GOARCH", runtime.GOARCH},
1633 {"GOOS", runtime.GOOS},
1634 {"GOROOT", testGOROOT},
1635 {"GOPATH", os.Getenv("GOPATH")},
1637 {"UseAllFiles", ""},
1640 {"ReleaseTags", ""},
1641 {"InstallSuffix", ""},
1644 t.Run(tt.v, func(t *testing.T) {
1648 tmpl := "{{context." + tt.v + "}}"
1649 tg.run("list", "-f", tmpl)
1653 if got := strings.TrimSpace(tg.getStdout()); got != tt.want {
1654 t.Errorf("go list -f %q: got %q; want %q", tmpl, got, tt.want)
1660 // Test that you cannot use a local import in a package
1661 // accessed by a non-local import (found in a GOPATH/GOROOT).
1662 // See golang.org/issue/17475.
1663 func TestImportLocal(t *testing.T) {
1670 tg.tempFile("src/dir/x/x.go", `package x
1673 tg.setenv("GOPATH", tg.path("."))
1674 tg.run("build", "dir/x")
1676 // Ordinary import should work.
1677 tg.tempFile("src/dir/p0/p.go", `package p0
1681 tg.run("build", "dir/p0")
1683 // Relative import should not.
1684 tg.tempFile("src/dir/p1/p.go", `package p1
1688 tg.runFail("build", "dir/p1")
1689 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1691 // ... even in a test.
1692 tg.tempFile("src/dir/p2/p.go", `package p2
1694 tg.tempFile("src/dir/p2/p_test.go", `package p2
1698 func TestFoo(t *testing.T) {}
1700 tg.run("build", "dir/p2")
1701 tg.runFail("test", "dir/p2")
1702 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1704 // ... even in an xtest.
1705 tg.tempFile("src/dir/p2/p_test.go", `package p2_test
1709 func TestFoo(t *testing.T) {}
1711 tg.run("build", "dir/p2")
1712 tg.runFail("test", "dir/p2")
1713 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1715 // Relative import starting with ./ should not work either.
1716 tg.tempFile("src/dir/d.go", `package dir
1720 tg.runFail("build", "dir")
1721 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1723 // ... even in a test.
1724 tg.tempFile("src/dir/d.go", `package dir
1726 tg.tempFile("src/dir/d_test.go", `package dir
1730 func TestFoo(t *testing.T) {}
1732 tg.run("build", "dir")
1733 tg.runFail("test", "dir")
1734 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1736 // ... even in an xtest.
1737 tg.tempFile("src/dir/d_test.go", `package dir_test
1741 func TestFoo(t *testing.T) {}
1743 tg.run("build", "dir")
1744 tg.runFail("test", "dir")
1745 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1747 // Relative import plain ".." should not work.
1748 tg.tempFile("src/dir/x/y/y.go", `package dir
1752 tg.runFail("build", "dir/x/y")
1753 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1755 // ... even in a test.
1756 tg.tempFile("src/dir/x/y/y.go", `package y
1758 tg.tempFile("src/dir/x/y/y_test.go", `package y
1762 func TestFoo(t *testing.T) {}
1764 tg.run("build", "dir/x/y")
1765 tg.runFail("test", "dir/x/y")
1766 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1768 // ... even in an x test.
1769 tg.tempFile("src/dir/x/y/y_test.go", `package y_test
1773 func TestFoo(t *testing.T) {}
1775 tg.run("build", "dir/x/y")
1776 tg.runFail("test", "dir/x/y")
1777 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1779 // Relative import "." should not work.
1780 tg.tempFile("src/dir/x/xx.go", `package x
1784 tg.runFail("build", "dir/x")
1785 tg.grepStderr("cannot import current directory", "did not diagnose import current directory")
1787 // ... even in a test.
1788 tg.tempFile("src/dir/x/xx.go", `package x
1790 tg.tempFile("src/dir/x/xx_test.go", `package x
1794 func TestFoo(t *testing.T) {}
1796 tg.run("build", "dir/x")
1797 tg.runFail("test", "dir/x")
1798 tg.grepStderr("cannot import current directory", "did not diagnose import current directory")
1800 // ... even in an xtest.
1801 tg.tempFile("src/dir/x/xx.go", `package x
1803 tg.tempFile("src/dir/x/xx_test.go", `package x_test
1807 func TestFoo(t *testing.T) {}
1809 tg.run("build", "dir/x")
1810 tg.runFail("test", "dir/x")
1811 tg.grepStderr("cannot import current directory", "did not diagnose import current directory")
1814 func TestGoInstallPkgdir(t *testing.T) {
1815 skipIfGccgo(t, "gccgo has no standard packages")
1823 tg.run("install", "-pkgdir", pkg, "sync")
1824 tg.mustExist(filepath.Join(pkg, "sync.a"))
1825 tg.mustNotExist(filepath.Join(pkg, "sync/atomic.a"))
1826 tg.run("install", "-i", "-pkgdir", pkg, "sync")
1827 tg.mustExist(filepath.Join(pkg, "sync.a"))
1828 tg.mustExist(filepath.Join(pkg, "sync/atomic.a"))
1832 func TestParallelTest(t *testing.T) {
1838 const testSrc = `package package_test
1842 func TestTest(t *testing.T) {
1844 tg.tempFile("src/p1/p1_test.go", strings.Replace(testSrc, "package_test", "p1_test", 1))
1845 tg.tempFile("src/p2/p2_test.go", strings.Replace(testSrc, "package_test", "p2_test", 1))
1846 tg.tempFile("src/p3/p3_test.go", strings.Replace(testSrc, "package_test", "p3_test", 1))
1847 tg.tempFile("src/p4/p4_test.go", strings.Replace(testSrc, "package_test", "p4_test", 1))
1848 tg.setenv("GOPATH", tg.path("."))
1849 tg.run("test", "-p=4", "p1", "p2", "p3", "p4")
1852 func TestBinaryOnlyPackages(t *testing.T) {
1859 tg.setenv("GOPATH", tg.path("."))
1861 tg.tempFile("src/p1/p1.go", `//go:binary-only-package
1865 tg.wantStale("p1", "binary-only packages are no longer supported", "p1 is binary-only, and this message should always be printed")
1866 tg.runFail("install", "p1")
1867 tg.grepStderr("binary-only packages are no longer supported", "did not report attempt to compile binary-only package")
1869 tg.tempFile("src/p1/p1.go", `
1872 func F(b bool) { fmt.Printf("hello from p1\n"); if b { F(false) } }
1874 tg.run("install", "p1")
1875 os.Remove(tg.path("src/p1/p1.go"))
1876 tg.mustNotExist(tg.path("src/p1/p1.go"))
1878 tg.tempFile("src/p2/p2.go", `//go:binary-only-packages-are-not-great
1882 func F() { p1.F(true) }
1884 tg.runFail("install", "p2")
1885 tg.grepStderr("no Go files", "did not complain about missing sources")
1887 tg.tempFile("src/p1/missing.go", `//go:binary-only-package
1893 tg.wantStale("p1", "binary-only package", "should NOT want to rebuild p1 (first)")
1894 tg.runFail("install", "p2")
1895 tg.grepStderr("p1: binary-only packages are no longer supported", "did not report error for binary-only p1")
1897 tg.run("list", "-deps", "-f", "{{.ImportPath}}: {{.BinaryOnly}}", "p2")
1898 tg.grepStdout("p1: true", "p1 not listed as BinaryOnly")
1899 tg.grepStdout("p2: false", "p2 listed as BinaryOnly")
1902 // Issue 16050 and 21884.
1903 func TestLinkSysoFiles(t *testing.T) {
1904 if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
1905 t.Skip("not linux/amd64")
1911 tg.tempDir("src/syso")
1912 tg.tempFile("src/syso/a.syso", ``)
1913 tg.tempFile("src/syso/b.go", `package syso`)
1914 tg.setenv("GOPATH", tg.path("."))
1916 // We should see the .syso file regardless of the setting of
1919 tg.setenv("CGO_ENABLED", "1")
1920 tg.run("list", "-f", "{{.SysoFiles}}", "syso")
1921 tg.grepStdout("a.syso", "missing syso file with CGO_ENABLED=1")
1923 tg.setenv("CGO_ENABLED", "0")
1924 tg.run("list", "-f", "{{.SysoFiles}}", "syso")
1925 tg.grepStdout("a.syso", "missing syso file with CGO_ENABLED=0")
1927 tg.setenv("CGO_ENABLED", "1")
1928 tg.run("list", "-msan", "-f", "{{.SysoFiles}}", "syso")
1929 tg.grepStdoutNot("a.syso", "unexpected syso file with -msan")
1933 func TestGenerateUsesBuildContext(t *testing.T) {
1934 if runtime.GOOS == "windows" {
1935 t.Skip("this test won't run under Windows")
1941 tg.tempDir("src/gen")
1942 tg.tempFile("src/gen/gen.go", "package gen\n//go:generate echo $GOOS $GOARCH\n")
1943 tg.setenv("GOPATH", tg.path("."))
1945 tg.setenv("GOOS", "linux")
1946 tg.setenv("GOARCH", "amd64")
1947 tg.run("generate", "gen")
1948 tg.grepStdout("linux amd64", "unexpected GOOS/GOARCH combination")
1950 tg.setenv("GOOS", "darwin")
1951 tg.setenv("GOARCH", "arm64")
1952 tg.run("generate", "gen")
1953 tg.grepStdout("darwin arm64", "unexpected GOOS/GOARCH combination")
1956 func TestGoEnv(t *testing.T) {
1960 tg.setenv("GOOS", "freebsd") // to avoid invalid pair errors
1961 tg.setenv("GOARCH", "arm")
1962 tg.run("env", "GOARCH")
1963 tg.grepStdout("^arm$", "GOARCH not honored")
1965 tg.run("env", "GCCGO")
1966 tg.grepStdout(".", "GCCGO unexpectedly empty")
1968 tg.run("env", "CGO_CFLAGS")
1969 tg.grepStdout(".", "default CGO_CFLAGS unexpectedly empty")
1971 tg.setenv("CGO_CFLAGS", "-foobar")
1972 tg.run("env", "CGO_CFLAGS")
1973 tg.grepStdout("^-foobar$", "CGO_CFLAGS not honored")
1975 tg.setenv("CC", "gcc -fmust -fgo -ffaster")
1977 tg.grepStdout("gcc", "CC not found")
1978 tg.run("env", "GOGCCFLAGS")
1979 tg.grepStdout("-ffaster", "CC arguments not found")
1981 tg.run("env", "GOVERSION")
1982 envVersion := strings.TrimSpace(tg.stdout.String())
1985 cmdVersion := strings.TrimSpace(tg.stdout.String())
1987 // If 'go version' is "go version <version> <goos>/<goarch>", then
1988 // 'go env GOVERSION' is just "<version>".
1989 if cmdVersion == envVersion || !strings.Contains(cmdVersion, envVersion) {
1990 t.Fatalf("'go env GOVERSION' %q should be a shorter substring of 'go version' %q", envVersion, cmdVersion)
1995 noMatchesPattern = `(?m)^ok.*\[no tests to run\]`
1996 okPattern = `(?m)^ok`
2000 func TestLdBindNow(t *testing.T) {
2004 tg.setenv("LD_BIND_NOW", "1")
2009 // This is really a cmd/asm issue but this is a convenient place to test it.
2010 func TestConcurrentAsm(t *testing.T) {
2011 skipIfGccgo(t, "gccgo does not use cmd/asm")
2015 asm := `DATA ·constants<>+0x0(SB)/8,$0
2016 GLOBL ·constants<>(SB),8,$8
2018 tg.tempFile("go/src/p/a.s", asm)
2019 tg.tempFile("go/src/p/b.s", asm)
2020 tg.tempFile("go/src/p/p.go", `package p`)
2021 tg.setenv("GOPATH", tg.path("go"))
2022 tg.run("build", "p")
2026 func TestFFLAGS(t *testing.T) {
2028 t.Skip("skipping because cgo not enabled")
2035 tg.tempFile("p/src/p/main.go", `package main
2036 // #cgo FFLAGS: -no-such-fortran-flag
2040 tg.tempFile("p/src/p/a.f", `! comment`)
2041 tg.setenv("GOPATH", tg.path("p"))
2043 // This should normally fail because we are passing an unknown flag,
2044 // but issue #19080 points to Fortran compilers that succeed anyhow.
2045 // To work either way we call doRun directly rather than run or runFail.
2046 tg.doRun([]string{"build", "-x", "p"})
2048 tg.grepStderr("no-such-fortran-flag", `missing expected "-no-such-fortran-flag"`)
2052 // This is really a cmd/link issue but this is a convenient place to test it.
2053 func TestDuplicateGlobalAsmSymbols(t *testing.T) {
2054 skipIfGccgo(t, "gccgo does not use cmd/asm")
2056 if runtime.GOARCH != "386" && runtime.GOARCH != "amd64" {
2057 t.Skipf("skipping test on %s", runtime.GOARCH)
2060 t.Skip("skipping because cgo not enabled")
2068 #include "textflag.h"
2070 DATA sym<>+0x0(SB)/8,$0
2071 GLOBL sym<>(SB),(NOPTR+RODATA),$8
2073 TEXT ·Data(SB),NOSPLIT,$0
2078 tg.tempFile("go/src/a/a.s", asm)
2079 tg.tempFile("go/src/a/a.go", `package a; func Data() uint8`)
2080 tg.tempFile("go/src/b/b.s", asm)
2081 tg.tempFile("go/src/b/b.go", `package b; func Data() uint8`)
2082 tg.tempFile("go/src/p/p.go", `
2088 _ = a.Data() + b.Data()
2091 tg.setenv("GOPATH", tg.path("go"))
2092 exe := tg.path("p.exe")
2093 tg.creatingTemp(exe)
2094 tg.run("build", "-o", exe, "p")
2097 func copyFile(src, dst string, perm fs.FileMode) error {
2098 sf, err := os.Open(src)
2104 df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
2109 _, err = io.Copy(df, sf)
2117 func TestNeedVersion(t *testing.T) {
2118 skipIfGccgo(t, "gccgo does not use cmd/compile")
2122 tg.tempFile("goversion.go", `package main; func main() {}`)
2123 path := tg.path("goversion.go")
2124 tg.setenv("TESTGO_VERSION", "go1.testgo")
2125 tg.runFail("run", path)
2126 tg.grepStderr("compile", "does not match go tool version")
2129 func TestBuildmodePIE(t *testing.T) {
2130 if testing.Short() && testenv.Builder() == "" {
2131 t.Skipf("skipping in -short mode on non-builder")
2134 platform := fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)
2136 case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/riscv64", "linux/s390x",
2137 "android/amd64", "android/arm", "android/arm64", "android/386",
2139 "windows/386", "windows/amd64", "windows/arm":
2140 case "darwin/amd64":
2142 t.Skipf("skipping test because buildmode=pie is not supported on %s", platform)
2144 t.Run("non-cgo", func(t *testing.T) {
2145 testBuildmodePIE(t, false, true)
2148 switch runtime.GOOS {
2149 case "darwin", "freebsd", "linux", "windows":
2150 t.Run("cgo", func(t *testing.T) {
2151 testBuildmodePIE(t, true, true)
2157 func TestWindowsDefaultBuildmodIsPIE(t *testing.T) {
2158 if testing.Short() && testenv.Builder() == "" {
2159 t.Skipf("skipping in -short mode on non-builder")
2162 if runtime.GOOS != "windows" {
2163 t.Skip("skipping windows only test")
2166 t.Run("non-cgo", func(t *testing.T) {
2167 testBuildmodePIE(t, false, false)
2170 t.Run("cgo", func(t *testing.T) {
2171 testBuildmodePIE(t, true, false)
2176 func testBuildmodePIE(t *testing.T, useCgo, setBuildmodeToPIE bool) {
2185 tg.tempFile("main.go", fmt.Sprintf(`package main;%s func main() { print("hello") }`, s))
2186 src := tg.path("main.go")
2187 obj := tg.path("main.exe")
2188 args := []string{"build"}
2189 if setBuildmodeToPIE {
2190 args = append(args, "-buildmode=pie")
2192 args = append(args, "-o", obj, src)
2195 switch runtime.GOOS {
2196 case "linux", "android", "freebsd":
2197 f, err := elf.Open(obj)
2202 if f.Type != elf.ET_DYN {
2203 t.Errorf("PIE type must be ET_DYN, but %s", f.Type)
2206 f, err := macho.Open(obj)
2211 if f.Flags&macho.FlagDyldLink == 0 {
2212 t.Error("PIE must have DyldLink flag, but not")
2214 if f.Flags&macho.FlagPIE == 0 {
2215 t.Error("PIE must have PIE flag, but not")
2218 f, err := pe.Open(obj)
2223 if f.Section(".reloc") == nil {
2224 t.Error(".reloc section is not present")
2226 if (f.FileHeader.Characteristics & pe.IMAGE_FILE_RELOCS_STRIPPED) != 0 {
2227 t.Error("IMAGE_FILE_RELOCS_STRIPPED flag is set")
2230 switch oh := f.OptionalHeader.(type) {
2231 case *pe.OptionalHeader32:
2232 dc = oh.DllCharacteristics
2233 case *pe.OptionalHeader64:
2234 dc = oh.DllCharacteristics
2235 if (dc & pe.IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA) == 0 {
2236 t.Error("IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA flag is not set")
2239 t.Fatalf("unexpected optional header type of %T", f.OptionalHeader)
2241 if (dc & pe.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) == 0 {
2242 t.Error("IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE flag is not set")
2245 // Test that only one symbol is exported (#40795).
2246 // PIE binaries don´t require .edata section but unfortunately
2247 // binutils doesn´t generate a .reloc section unless there is
2248 // at least one symbol exported.
2249 // See https://sourceware.org/bugzilla/show_bug.cgi?id=19011
2250 section := f.Section(".edata")
2252 t.Skip(".edata section is not present")
2254 // TODO: deduplicate this struct from cmd/link/internal/ld/pe.go
2255 type IMAGE_EXPORT_DIRECTORY struct {
2259 NumberOfFunctions uint32
2260 NumberOfNames uint32
2263 var e IMAGE_EXPORT_DIRECTORY
2264 if err := binary.Read(section.Open(), binary.LittleEndian, &e); err != nil {
2265 t.Fatalf("binary.Read failed: %v", err)
2268 // Only _cgo_dummy_export should be exported
2269 if e.NumberOfFunctions != 1 {
2270 t.Fatalf("got %d exported functions; want 1", e.NumberOfFunctions)
2272 if e.NumberOfNames != 1 {
2273 t.Fatalf("got %d exported names; want 1", e.NumberOfNames)
2277 panic("unreachable")
2280 out, err := exec.Command(obj).CombinedOutput()
2285 if string(out) != "hello" {
2286 t.Errorf("got %q; want %q", out, "hello")
2290 func TestUpxCompression(t *testing.T) {
2291 if runtime.GOOS != "linux" ||
2292 (runtime.GOARCH != "amd64" && runtime.GOARCH != "386") {
2293 t.Skipf("skipping upx test on %s/%s", runtime.GOOS, runtime.GOARCH)
2296 testenv.MustHaveExecPath(t, "upx")
2297 out, err := exec.Command("upx", "--version").CombinedOutput()
2299 t.Fatalf("upx --version failed: %v", err)
2302 // upx --version prints `upx <version>` in the first line of output:
2305 re := regexp.MustCompile(`([[:digit:]]+)\.([[:digit:]]+)`)
2306 upxVersion := re.FindStringSubmatch(string(out))
2307 if len(upxVersion) != 3 {
2308 t.Fatalf("bad upx version string: %s", upxVersion)
2311 major, err1 := strconv.Atoi(upxVersion[1])
2312 minor, err2 := strconv.Atoi(upxVersion[2])
2313 if err1 != nil || err2 != nil {
2314 t.Fatalf("bad upx version string: %s", upxVersion[0])
2317 // Anything below 3.94 is known not to work with go binaries
2318 if (major < 3) || (major == 3 && minor < 94) {
2319 t.Skipf("skipping because upx version %v.%v is too old", major, minor)
2326 tg.tempFile("main.go", `package main; import "fmt"; func main() { fmt.Print("hello upx") }`)
2327 src := tg.path("main.go")
2328 obj := tg.path("main")
2329 tg.run("build", "-o", obj, src)
2331 out, err = exec.Command("upx", obj).CombinedOutput()
2333 t.Logf("executing upx\n%s\n", out)
2334 t.Fatalf("upx failed with %v", err)
2337 out, err = exec.Command(obj).CombinedOutput()
2340 t.Fatalf("running compressed go binary failed with error %s", err)
2342 if string(out) != "hello upx" {
2343 t.Fatalf("bad output from compressed go binary:\ngot %q; want %q", out, "hello upx")
2347 func TestCacheListStale(t *testing.T) {
2349 if godebug.Get("gocacheverify") == "1" {
2350 t.Skip("GODEBUG gocacheverify")
2356 tg.setenv("GOCACHE", tg.path("cache"))
2357 tg.tempFile("gopath/src/p/p.go", "package p; import _ \"q\"; func F(){}\n")
2358 tg.tempFile("gopath/src/q/q.go", "package q; func F(){}\n")
2359 tg.tempFile("gopath/src/m/m.go", "package main; import _ \"q\"; func main(){}\n")
2361 tg.setenv("GOPATH", tg.path("gopath"))
2362 tg.run("install", "p", "m")
2363 tg.run("list", "-f={{.ImportPath}} {{.Stale}}", "m", "q", "p")
2364 tg.grepStdout("^m false", "m should not be stale")
2365 tg.grepStdout("^q true", "q should be stale")
2366 tg.grepStdout("^p false", "p should not be stale")
2369 func TestCacheCoverage(t *testing.T) {
2372 if godebug.Get("gocacheverify") == "1" {
2373 t.Skip("GODEBUG gocacheverify")
2379 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
2382 tg.setenv("GOCACHE", tg.path("c1"))
2383 tg.run("test", "-cover", "-short", "strings")
2384 tg.run("test", "-cover", "-short", "math", "strings")
2387 func TestIssue22588(t *testing.T) {
2388 // Don't get confused by stderr coming from tools.
2393 if _, err := os.Stat("/usr/bin/time"); err != nil {
2397 tg.run("list", "-f={{.Stale}}", "runtime")
2398 tg.run("list", "-toolexec=/usr/bin/time", "-f={{.Stale}}", "runtime")
2399 tg.grepStdout("false", "incorrectly reported runtime as stale")
2402 func TestIssue22531(t *testing.T) {
2404 if godebug.Get("gocacheverify") == "1" {
2405 t.Skip("GODEBUG gocacheverify")
2411 tg.setenv("GOPATH", tg.tempdir)
2412 tg.setenv("GOCACHE", tg.path("cache"))
2413 tg.tempFile("src/m/main.go", "package main /* c1 */; func main() {}\n")
2414 tg.run("install", "-x", "m")
2415 tg.run("list", "-f", "{{.Stale}}", "m")
2416 tg.grepStdout("false", "reported m as stale after install")
2417 tg.run("tool", "buildid", tg.path("bin/m"+exeSuffix))
2419 // The link action ID did not include the full main build ID,
2420 // even though the full main build ID is written into the
2421 // eventual binary. That caused the following install to
2422 // be a no-op, thinking the gofmt binary was up-to-date,
2423 // even though .Stale could see it was not.
2424 tg.tempFile("src/m/main.go", "package main /* c2 */; func main() {}\n")
2425 tg.run("install", "-x", "m")
2426 tg.run("list", "-f", "{{.Stale}}", "m")
2427 tg.grepStdout("false", "reported m as stale after reinstall")
2428 tg.run("tool", "buildid", tg.path("bin/m"+exeSuffix))
2431 func TestIssue22596(t *testing.T) {
2433 if godebug.Get("gocacheverify") == "1" {
2434 t.Skip("GODEBUG gocacheverify")
2440 tg.setenv("GOCACHE", tg.path("cache"))
2441 tg.tempFile("gopath1/src/p/p.go", "package p; func F(){}\n")
2442 tg.tempFile("gopath2/src/p/p.go", "package p; func F(){}\n")
2444 tg.setenv("GOPATH", tg.path("gopath1"))
2445 tg.run("list", "-f={{.Target}}", "p")
2446 target1 := strings.TrimSpace(tg.getStdout())
2447 tg.run("install", "p")
2448 tg.wantNotStale("p", "", "p stale after install")
2450 tg.setenv("GOPATH", tg.path("gopath2"))
2451 tg.run("list", "-f={{.Target}}", "p")
2452 target2 := strings.TrimSpace(tg.getStdout())
2453 tg.must(os.MkdirAll(filepath.Dir(target2), 0777))
2454 tg.must(copyFile(target1, target2, 0666))
2455 tg.wantStale("p", "build ID mismatch", "p not stale after copy from gopath1")
2456 tg.run("install", "p")
2457 tg.wantNotStale("p", "", "p stale after install2")
2460 func TestTestCache(t *testing.T) {
2463 if godebug.Get("gocacheverify") == "1" {
2464 t.Skip("GODEBUG gocacheverify")
2470 tg.setenv("GOPATH", tg.tempdir)
2471 tg.setenv("GOCACHE", tg.path("cache"))
2473 // The -p=1 in the commands below just makes the -x output easier to read.
2475 t.Log("\n\nINITIAL\n\n")
2477 tg.tempFile("src/p1/p1.go", "package p1\nvar X = 1\n")
2478 tg.tempFile("src/p2/p2.go", "package p2\nimport _ \"p1\"\nvar X = 1\n")
2479 tg.tempFile("src/t/t1/t1_test.go", "package t\nimport \"testing\"\nfunc Test1(*testing.T) {}\n")
2480 tg.tempFile("src/t/t2/t2_test.go", "package t\nimport _ \"p1\"\nimport \"testing\"\nfunc Test2(*testing.T) {}\n")
2481 tg.tempFile("src/t/t3/t3_test.go", "package t\nimport \"p1\"\nimport \"testing\"\nfunc Test3(t *testing.T) {t.Log(p1.X)}\n")
2482 tg.tempFile("src/t/t4/t4_test.go", "package t\nimport \"p2\"\nimport \"testing\"\nfunc Test4(t *testing.T) {t.Log(p2.X)}")
2483 tg.run("test", "-x", "-v", "-short", "t/...")
2485 t.Log("\n\nREPEAT\n\n")
2487 tg.run("test", "-x", "-v", "-short", "t/...")
2488 tg.grepStdout(`ok \tt/t1\t\(cached\)`, "did not cache t1")
2489 tg.grepStdout(`ok \tt/t2\t\(cached\)`, "did not cache t2")
2490 tg.grepStdout(`ok \tt/t3\t\(cached\)`, "did not cache t3")
2491 tg.grepStdout(`ok \tt/t4\t\(cached\)`, "did not cache t4")
2492 tg.grepStderrNot(`[\\/](compile|gccgo) `, "incorrectly ran compiler")
2493 tg.grepStderrNot(`[\\/](link|gccgo) `, "incorrectly ran linker")
2494 tg.grepStderrNot(`p[0-9]\.test`, "incorrectly ran test")
2496 t.Log("\n\nCOMMENT\n\n")
2498 // Changing the program text without affecting the compiled package
2499 // should result in the package being rebuilt but nothing more.
2500 tg.tempFile("src/p1/p1.go", "package p1\nvar X = 01\n")
2501 tg.run("test", "-p=1", "-x", "-v", "-short", "t/...")
2502 tg.grepStdout(`ok \tt/t1\t\(cached\)`, "did not cache t1")
2503 tg.grepStdout(`ok \tt/t2\t\(cached\)`, "did not cache t2")
2504 tg.grepStdout(`ok \tt/t3\t\(cached\)`, "did not cache t3")
2505 tg.grepStdout(`ok \tt/t4\t\(cached\)`, "did not cache t4")
2506 tg.grepStderrNot(`([\\/](compile|gccgo) ).*t[0-9]_test\.go`, "incorrectly ran compiler")
2507 tg.grepStderrNot(`[\\/](link|gccgo) `, "incorrectly ran linker")
2508 tg.grepStderrNot(`t[0-9]\.test.*test\.short`, "incorrectly ran test")
2510 t.Log("\n\nCHANGE\n\n")
2512 // Changing the actual package should have limited effects.
2513 tg.tempFile("src/p1/p1.go", "package p1\nvar X = 02\n")
2514 tg.run("test", "-p=1", "-x", "-v", "-short", "t/...")
2516 // p2 should have been rebuilt.
2517 tg.grepStderr(`([\\/]compile|gccgo).*p2.go`, "did not recompile p2")
2519 // t1 does not import anything, should not have been rebuilt.
2520 tg.grepStderrNot(`([\\/]compile|gccgo).*t1_test.go`, "incorrectly recompiled t1")
2521 tg.grepStderrNot(`([\\/]link|gccgo).*t1_test`, "incorrectly relinked t1_test")
2522 tg.grepStdout(`ok \tt/t1\t\(cached\)`, "did not cache t/t1")
2524 // t2 imports p1 and must be rebuilt and relinked,
2525 // but the change should not have any effect on the test binary,
2526 // so the test should not have been rerun.
2527 tg.grepStderr(`([\\/]compile|gccgo).*t2_test.go`, "did not recompile t2")
2528 tg.grepStderr(`([\\/]link|gccgo).*t2\.test`, "did not relink t2_test")
2529 // This check does not currently work with gccgo, as garbage
2530 // collection of unused variables is not turned on by default.
2531 if runtime.Compiler != "gccgo" {
2532 tg.grepStdout(`ok \tt/t2\t\(cached\)`, "did not cache t/t2")
2535 // t3 imports p1, and changing X changes t3's test binary.
2536 tg.grepStderr(`([\\/]compile|gccgo).*t3_test.go`, "did not recompile t3")
2537 tg.grepStderr(`([\\/]link|gccgo).*t3\.test`, "did not relink t3_test")
2538 tg.grepStderr(`t3\.test.*-test.short`, "did not rerun t3_test")
2539 tg.grepStdoutNot(`ok \tt/t3\t\(cached\)`, "reported cached t3_test result")
2541 // t4 imports p2, but p2 did not change, so t4 should be relinked, not recompiled,
2543 tg.grepStderrNot(`([\\/]compile|gccgo).*t4_test.go`, "incorrectly recompiled t4")
2544 tg.grepStderr(`([\\/]link|gccgo).*t4\.test`, "did not relink t4_test")
2545 // This check does not currently work with gccgo, as garbage
2546 // collection of unused variables is not turned on by default.
2547 if runtime.Compiler != "gccgo" {
2548 tg.grepStdout(`ok \tt/t4\t\(cached\)`, "did not cache t/t4")
2552 func TestTestSkipVetAfterFailedBuild(t *testing.T) {
2557 tg.tempFile("x_test.go", `package x
2563 tg.runFail("test", tg.path("x_test.go"))
2564 tg.grepStderrNot(`vet`, "vet should be skipped after the failed build")
2567 func TestTestVetRebuild(t *testing.T) {
2573 // golang.org/issue/23701.
2574 // b_test imports b with augmented method from export_test.go.
2575 // b_test also imports a, which imports b.
2576 // Must not accidentally see un-augmented b propagate through a to b_test.
2577 tg.tempFile("src/a/a.go", `package a
2580 func (*Type) M() b.T {return 0}
2582 tg.tempFile("src/b/b.go", `package b
2584 type I interface {M() T}
2586 tg.tempFile("src/b/export_test.go", `package b
2587 func (*T) Method() *T { return nil }
2589 tg.tempFile("src/b/b_test.go", `package b_test
2595 func TestBroken(t *testing.T) {
2602 tg.setenv("GOPATH", tg.path("."))
2607 func TestInstallDeps(t *testing.T) {
2613 tg.setenv("GOPATH", tg.tempdir)
2615 tg.tempFile("src/p1/p1.go", "package p1\nvar X = 1\n")
2616 tg.tempFile("src/p2/p2.go", "package p2\nimport _ \"p1\"\n")
2617 tg.tempFile("src/main1/main.go", "package main\nimport _ \"p2\"\nfunc main() {}\n")
2619 tg.run("list", "-f={{.Target}}", "p1")
2620 p1 := strings.TrimSpace(tg.getStdout())
2621 tg.run("list", "-f={{.Target}}", "p2")
2622 p2 := strings.TrimSpace(tg.getStdout())
2623 tg.run("list", "-f={{.Target}}", "main1")
2624 main1 := strings.TrimSpace(tg.getStdout())
2626 tg.run("install", "main1")
2632 tg.run("install", "p2")
2636 // don't let install -i overwrite runtime
2637 tg.wantNotStale("runtime", "", "must be non-stale before install -i")
2639 tg.run("install", "-i", "main1")
2641 tg.must(os.Remove(p1))
2643 tg.run("install", "-i", "p2")
2648 func TestImportPath(t *testing.T) {
2654 tg.tempFile("src/a/a.go", `
2668 tg.tempFile("src/a/a_test.go", `
2676 func TestV(t *testing.T) {
2682 tg.tempFile("src/a/p-1.0/p.go", `
2690 tg.setenv("GOPATH", tg.path("."))
2691 tg.run("build", "-o", tg.path("a.exe"), "a")
2695 func TestBadCommandLines(t *testing.T) {
2700 tg.tempFile("src/x/x.go", "package x\n")
2701 tg.setenv("GOPATH", tg.path("."))
2703 tg.run("build", "x")
2705 tg.tempFile("src/x/@y.go", "package x\n")
2706 tg.runFail("build", "x")
2707 tg.grepStderr("invalid input file name \"@y.go\"", "did not reject @y.go")
2708 tg.must(os.Remove(tg.path("src/x/@y.go")))
2710 tg.tempFile("src/x/-y.go", "package x\n")
2711 tg.runFail("build", "x")
2712 tg.grepStderr("invalid input file name \"-y.go\"", "did not reject -y.go")
2713 tg.must(os.Remove(tg.path("src/x/-y.go")))
2715 if runtime.Compiler == "gccgo" {
2716 tg.runFail("build", "-gccgoflags=all=@x", "x")
2718 tg.runFail("build", "-gcflags=all=@x", "x")
2720 tg.grepStderr("invalid command-line argument @x in command", "did not reject @x during exec")
2722 tg.tempFile("src/@x/x.go", "package x\n")
2723 tg.setenv("GOPATH", tg.path("."))
2724 tg.runFail("build", "@x")
2725 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")
2727 tg.tempFile("src/@x/y/y.go", "package y\n")
2728 tg.setenv("GOPATH", tg.path("."))
2729 tg.runFail("build", "@x/y")
2730 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")
2732 tg.tempFile("src/-x/x.go", "package x\n")
2733 tg.setenv("GOPATH", tg.path("."))
2734 tg.runFail("build", "--", "-x")
2735 tg.grepStderr("invalid import path \"-x\"", "did not reject -x import path")
2737 tg.tempFile("src/-x/y/y.go", "package y\n")
2738 tg.setenv("GOPATH", tg.path("."))
2739 tg.runFail("build", "--", "-x/y")
2740 tg.grepStderr("invalid import path \"-x/y\"", "did not reject -x/y import path")
2743 func TestTwoPkgConfigs(t *testing.T) {
2747 if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
2748 t.Skipf("no shell scripts on %s", runtime.GOOS)
2754 tg.tempFile("src/x/a.go", `package x
2755 // #cgo pkg-config: --static a
2758 tg.tempFile("src/x/b.go", `package x
2759 // #cgo pkg-config: --static a
2762 tg.tempFile("pkg-config.sh", `#!/bin/sh
2763 echo $* >>`+tg.path("pkg-config.out"))
2764 tg.must(os.Chmod(tg.path("pkg-config.sh"), 0755))
2765 tg.setenv("GOPATH", tg.path("."))
2766 tg.setenv("PKG_CONFIG", tg.path("pkg-config.sh"))
2767 tg.run("build", "x")
2768 out, err := os.ReadFile(tg.path("pkg-config.out"))
2770 out = bytes.TrimSpace(out)
2771 want := "--cflags --static --static -- a a\n--libs --static --static -- a a"
2772 if !bytes.Equal(out, []byte(want)) {
2773 t.Errorf("got %q want %q", out, want)
2777 func TestCgoCache(t *testing.T) {
2786 tg.tempFile("src/x/a.go", `package main
2793 func main() { fmt.Println(C.val) }
2795 tg.setenv("GOPATH", tg.path("."))
2796 exe := tg.path("x.exe")
2797 tg.run("build", "-o", exe, "x")
2798 tg.setenv("CGO_LDFLAGS", "-lnosuchlibraryexists")
2799 tg.runFail("build", "-o", exe, "x")
2800 tg.grepStderr(`nosuchlibraryexists`, "did not run linker with changed CGO_LDFLAGS")
2804 func TestFilepathUnderCwdFormat(t *testing.T) {
2808 tg.run("test", "-x", "-cover", "log")
2809 tg.grepStderrNot(`\.log\.cover\.go`, "-x output should contain correctly formatted filepath under cwd")
2813 func TestDontReportRemoveOfEmptyDir(t *testing.T) {
2817 tg.tempFile("src/a/a.go", `package a`)
2818 tg.setenv("GOPATH", tg.path("."))
2819 tg.run("install", "-x", "a")
2820 tg.run("install", "-x", "a")
2821 // The second install should have printed only a WORK= line,
2823 if bytes.Count(tg.stdout.Bytes(), []byte{'\n'})+bytes.Count(tg.stderr.Bytes(), []byte{'\n'}) > 1 {
2824 t.Error("unnecessary output when installing installed package")
2829 func TestLinkerTmpDirIsDeleted(t *testing.T) {
2830 skipIfGccgo(t, "gccgo does not use cmd/link")
2832 t.Skip("skipping because cgo not enabled")
2839 tg.tempFile("a.go", `package main; import "C"; func main() {}`)
2840 tg.run("build", "-ldflags", "-v", "-o", os.DevNull, tg.path("a.go"))
2841 // Find line that has "host link:" in linker output.
2842 stderr := tg.getStderr()
2843 var hostLinkLine string
2844 for _, line := range strings.Split(stderr, "\n") {
2845 if !strings.Contains(line, "host link:") {
2851 if hostLinkLine == "" {
2852 t.Fatal(`fail to find with "host link:" string in linker output`)
2854 // Find parameter, like "/tmp/go-link-408556474/go.o" inside of
2855 // "host link:" line, and extract temp directory /tmp/go-link-408556474
2857 tmpdir := hostLinkLine
2858 i := strings.Index(tmpdir, `go.o"`)
2860 t.Fatalf(`fail to find "go.o" in "host link:" line %q`, hostLinkLine)
2862 tmpdir = tmpdir[:i-1]
2863 i = strings.LastIndex(tmpdir, `"`)
2865 t.Fatalf(`fail to find " in "host link:" line %q`, hostLinkLine)
2867 tmpdir = tmpdir[i+1:]
2868 // Verify that temp directory has been removed.
2869 _, err := os.Stat(tmpdir)
2871 t.Fatalf("temp directory %q has not been removed", tmpdir)
2873 if !os.IsNotExist(err) {
2874 t.Fatalf("Stat(%q) returns unexpected error: %v", tmpdir, err)
2879 func TestCoverpkgTestOnly(t *testing.T) {
2880 skipIfGccgo(t, "gccgo has no cover tool")
2885 tg.tempFile("src/a/a.go", `package a
2889 tg.tempFile("src/atest/a_test.go", `
2891 import ( "a"; "testing" )
2892 func TestF(t *testing.T) { a.F(2) }
2894 tg.setenv("GOPATH", tg.path("."))
2895 tg.run("test", "-coverpkg=a", "atest")
2896 tg.grepStderrNot("no packages being tested depend on matches", "bad match message")
2897 tg.grepStdout("coverage: 100", "no coverage")
2900 // Regression test for golang.org/issue/34499: version command should not crash
2901 // when executed in a deleted directory on Linux.
2902 func TestExecInDeletedDir(t *testing.T) {
2903 switch runtime.GOOS {
2904 case "windows", "plan9",
2905 "aix", // Fails with "device busy".
2906 "solaris", "illumos": // Fails with "invalid argument".
2907 t.Skipf("%v does not support removing the current working directory", runtime.GOOS)
2912 wd, err := os.Getwd()
2915 tg.check(os.Chdir(tg.tempdir))
2916 defer func() { tg.check(os.Chdir(wd)) }()
2918 tg.check(os.Remove(tg.tempdir))
2920 // `go version` should not fail
2924 // A missing C compiler should not force the net package to be stale.
2926 func TestMissingCC(t *testing.T) {
2928 t.Skip("test is only meaningful on systems with cgo")
2930 cc := os.Getenv("CC")
2934 if filepath.IsAbs(cc) {
2935 t.Skipf(`"CC" (%s) is an absolute path`, cc)
2937 _, err := exec.LookPath(cc)
2939 t.Skipf(`"CC" (%s) not on PATH`, cc)
2944 netStale, _ := tg.isStale("net")
2946 t.Skip(`skipping test because "net" package is currently stale`)
2949 tg.setenv("PATH", "") // No C compiler on PATH.
2950 netStale, _ = tg.isStale("net")
2952 t.Error(`clearing "PATH" causes "net" to be stale`)