Source file
src/cmd/go/go_test.go
1
2
3
4
5 package main_test
6
7 import (
8 "bytes"
9 "debug/elf"
10 "debug/macho"
11 "debug/pe"
12 "flag"
13 "fmt"
14 "go/format"
15 "internal/godebug"
16 "internal/platform"
17 "internal/testenv"
18 "io"
19 "io/fs"
20 "log"
21 "math"
22 "os"
23 "os/exec"
24 "path/filepath"
25 "regexp"
26 "runtime"
27 "slices"
28 "strconv"
29 "strings"
30 "testing"
31 "time"
32
33 "cmd/go/internal/base"
34 "cmd/go/internal/cache"
35 "cmd/go/internal/cfg"
36 "cmd/go/internal/gover"
37 "cmd/go/internal/search"
38 "cmd/go/internal/toolchain"
39 "cmd/go/internal/vcs"
40 "cmd/go/internal/vcweb/vcstest"
41 "cmd/go/internal/web/intercept"
42 "cmd/go/internal/work"
43 "cmd/internal/robustio"
44 "cmd/internal/sys"
45
46 cmdgo "cmd/go"
47 )
48
49 func init() {
50
51
52
53
54 os.Setenv("GOVCS", "*:all")
55 }
56
57 var (
58 canRace = false
59 canMSan = false
60 canASan = false
61 )
62
63 var (
64 goHostOS, goHostArch string
65 cgoEnabled string
66 )
67
68
69
70
71
72 var netTestSem chan struct{}
73
74 var exeSuffix string = func() string {
75 if runtime.GOOS == "windows" {
76 return ".exe"
77 }
78 return ""
79 }()
80
81 func tooSlow(t *testing.T, reason string) {
82 if testing.Short() {
83 t.Helper()
84 t.Skipf("skipping test in -short mode: %s", reason)
85 }
86 }
87
88
89
90
91 var testGOROOT string
92
93 var testGOCACHE string
94
95 var testGo string
96 var testTmpDir string
97 var testBin string
98
99
100
101 func TestMain(m *testing.M) {
102
103
104
105
106 if os.Getenv("CMDGO_TEST_RUN_MAIN") != "" {
107 cfg.SetGOROOT(cfg.GOROOT, true)
108 gover.TestVersion = os.Getenv("TESTGO_VERSION")
109 toolchain.TestVersionSwitch = os.Getenv("TESTGO_VERSION_SWITCH")
110 if v := os.Getenv("TESTGO_TOOLCHAIN_VERSION"); v != "" {
111 work.ToolchainVersion = v
112 }
113
114 if testGOROOT := os.Getenv("TESTGO_GOROOT"); testGOROOT != "" {
115
116
117 work.AllowInstall = func(a *work.Action) error {
118 if cfg.BuildN {
119 return nil
120 }
121
122 rel := search.InDir(a.Target, testGOROOT)
123 if rel == "" {
124 return nil
125 }
126
127 callerPos := ""
128 if _, file, line, ok := runtime.Caller(1); ok {
129 if shortFile := search.InDir(file, filepath.Join(testGOROOT, "src")); shortFile != "" {
130 file = shortFile
131 }
132 callerPos = fmt.Sprintf("%s:%d: ", file, line)
133 }
134 notice := "This error error can occur if GOROOT is stale, in which case rerunning make.bash will fix it."
135 return fmt.Errorf("%stestgo must not write to GOROOT (installing to %s) (%v)", callerPos, filepath.Join("GOROOT", rel), notice)
136 }
137 }
138
139 if vcsTestHost := os.Getenv("TESTGO_VCSTEST_HOST"); vcsTestHost != "" {
140 vcs.VCSTestRepoURL = "http://" + vcsTestHost
141 vcs.VCSTestHosts = vcstest.Hosts
142 vcsTestTLSHost := os.Getenv("TESTGO_VCSTEST_TLS_HOST")
143 vcsTestClient, err := vcstest.TLSClient(os.Getenv("TESTGO_VCSTEST_CERT"))
144 if err != nil {
145 fmt.Fprintf(os.Stderr, "loading certificates from $TESTGO_VCSTEST_CERT: %v", err)
146 }
147 var interceptors []intercept.Interceptor
148 for _, host := range vcstest.Hosts {
149 interceptors = append(interceptors,
150 intercept.Interceptor{Scheme: "http", FromHost: host, ToHost: vcsTestHost},
151 intercept.Interceptor{Scheme: "https", FromHost: host, ToHost: vcsTestTLSHost, Client: vcsTestClient})
152 }
153 intercept.EnableTestHooks(interceptors)
154 }
155
156 cmdgo.Main()
157 os.Exit(0)
158 }
159 os.Setenv("CMDGO_TEST_RUN_MAIN", "true")
160
161
162
163 if os.Getenv("GO_GCFLAGS") != "" {
164 fmt.Fprintf(os.Stderr, "testing: warning: no tests to run\n")
165 fmt.Printf("cmd/go test is not compatible with $GO_GCFLAGS being set\n")
166 fmt.Printf("SKIP\n")
167 return
168 }
169
170 flag.Parse()
171
172 if *proxyAddr != "" {
173 StartProxy()
174 select {}
175 }
176
177
178
179 topTmpdir, err := os.MkdirTemp("", "cmd-go-test-")
180 if err != nil {
181 log.Fatal(err)
182 }
183 if !*testWork {
184 defer removeAll(topTmpdir)
185 } else {
186 fmt.Fprintf(os.Stderr, "TESTWORK: preserving top level tempdir %s\n", topTmpdir)
187 }
188 os.Setenv(tempEnvName(), topTmpdir)
189
190 dir, err := os.MkdirTemp(topTmpdir, "tmpdir")
191 if err != nil {
192 log.Fatal(err)
193 }
194 testTmpDir = dir
195 if !*testWork {
196 defer removeAll(testTmpDir)
197 }
198
199 testGOCACHE, _, _ = cache.DefaultDir()
200 if testenv.HasGoBuild() {
201 testBin = filepath.Join(testTmpDir, "testbin")
202 if err := os.Mkdir(testBin, 0777); err != nil {
203 log.Fatal(err)
204 }
205 testGo = filepath.Join(testBin, "go"+exeSuffix)
206 gotool, err := testenv.GoTool()
207 if err != nil {
208 fmt.Fprintln(os.Stderr, "locating go tool: ", err)
209 os.Exit(2)
210 }
211
212 goEnv := func(name string) string {
213 out, err := exec.Command(gotool, "env", name).CombinedOutput()
214 if err != nil {
215 fmt.Fprintf(os.Stderr, "go env %s: %v\n%s", name, err, out)
216 os.Exit(2)
217 }
218 return strings.TrimSpace(string(out))
219 }
220 testGOROOT = goEnv("GOROOT")
221 os.Setenv("TESTGO_GOROOT", testGOROOT)
222 os.Setenv("GOROOT", testGOROOT)
223
224
225
226
227
228
229
230
231
232
233
234
235 goHostOS = goEnv("GOHOSTOS")
236 os.Setenv("TESTGO_GOHOSTOS", goHostOS)
237 goHostArch = goEnv("GOHOSTARCH")
238 os.Setenv("TESTGO_GOHOSTARCH", goHostArch)
239
240 cgoEnabled = goEnv("CGO_ENABLED")
241
242
243
244 testExe, err := os.Executable()
245 if err != nil {
246 log.Fatal(err)
247 }
248 if err := os.Symlink(testExe, testGo); err != nil {
249
250 src, err := os.Open(testExe)
251 if err != nil {
252 log.Fatal(err)
253 }
254 defer src.Close()
255
256 dst, err := os.OpenFile(testGo, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o777)
257 if err != nil {
258 log.Fatal(err)
259 }
260
261 _, err = io.Copy(dst, src)
262 if closeErr := dst.Close(); err == nil {
263 err = closeErr
264 }
265 if err != nil {
266 log.Fatal(err)
267 }
268 }
269
270 out, err := exec.Command(gotool, "env", "GOCACHE").CombinedOutput()
271 if err != nil {
272 fmt.Fprintf(os.Stderr, "could not find testing GOCACHE: %v\n%s", err, out)
273 os.Exit(2)
274 }
275 testGOCACHE = strings.TrimSpace(string(out))
276
277 canMSan = testenv.HasCGO() && platform.MSanSupported(runtime.GOOS, runtime.GOARCH)
278 canASan = testenv.HasCGO() && platform.ASanSupported(runtime.GOOS, runtime.GOARCH)
279 canRace = testenv.HasCGO() && platform.RaceDetectorSupported(runtime.GOOS, runtime.GOARCH)
280
281
282
283 if isAlpineLinux() || runtime.Compiler == "gccgo" {
284 canRace = false
285 }
286 }
287
288 if n, limited := base.NetLimit(); limited && n > 0 {
289
290
291
292
293 netTestLimit := int(math.Sqrt(float64(n)))
294 netTestSem = make(chan struct{}, netTestLimit)
295 reducedLimit := fmt.Sprintf(",%s=%d", base.NetLimitGodebug.Name(), n/netTestLimit)
296 os.Setenv("GODEBUG", os.Getenv("GODEBUG")+reducedLimit)
297 }
298
299
300 os.Setenv("GOENV", "off")
301 os.Unsetenv("GOFLAGS")
302 os.Unsetenv("GOBIN")
303 os.Unsetenv("GOPATH")
304 os.Unsetenv("GIT_ALLOW_PROTOCOL")
305 os.Setenv("HOME", "/test-go-home-does-not-exist")
306
307
308
309 os.Setenv("CCACHE_DISABLE", "1")
310 if cfg.Getenv("GOCACHE") == "" {
311 os.Setenv("GOCACHE", testGOCACHE)
312 }
313
314 if testenv.Builder() != "" || os.Getenv("GIT_TRACE_CURL") == "1" {
315
316
317 os.Setenv("GIT_TRACE_CURL", "1")
318 os.Setenv("GIT_TRACE_CURL_NO_DATA", "1")
319 os.Setenv("GIT_REDACT_COOKIES", "o,SSO,GSSO_Uberproxy")
320 }
321
322 r := m.Run()
323 if !*testWork {
324 removeAll(testTmpDir)
325 }
326
327 if !*testWork {
328
329 var extraFiles, extraDirs []string
330 err := filepath.WalkDir(topTmpdir, func(path string, d fs.DirEntry, err error) error {
331 if err != nil {
332 return err
333 }
334 if path == topTmpdir {
335 return nil
336 }
337
338 if rel, err := filepath.Rel(topTmpdir, path); err == nil {
339 path = rel
340 }
341 if d.IsDir() {
342 extraDirs = append(extraDirs, path)
343 } else {
344 extraFiles = append(extraFiles, path)
345 }
346 return nil
347 })
348 if err != nil {
349 log.Fatal(err)
350 }
351
352 if len(extraFiles) > 0 {
353 log.Fatalf("unexpected files left in tmpdir: %q", extraFiles)
354 } else if len(extraDirs) > 0 {
355 log.Fatalf("unexpected subdirectories left in tmpdir: %q", extraDirs)
356 }
357
358 removeAll(topTmpdir)
359 }
360
361 os.Exit(r)
362 }
363
364 func isAlpineLinux() bool {
365 if runtime.GOOS != "linux" {
366 return false
367 }
368 fi, err := os.Lstat("/etc/alpine-release")
369 return err == nil && fi.Mode().IsRegular()
370 }
371
372
373
374
375
376 var mtimeTick time.Duration = 1 * time.Second
377
378
379 type testgoData struct {
380 t *testing.T
381 temps []string
382 env []string
383 tempdir string
384 ran bool
385 inParallel bool
386 stdout, stderr bytes.Buffer
387 execDir string
388 }
389
390
391 func skipIfGccgo(t *testing.T, msg string) {
392 if runtime.Compiler == "gccgo" {
393 t.Skipf("skipping test not supported on gccgo: %s", msg)
394 }
395 }
396
397
398 func testgo(t *testing.T) *testgoData {
399 t.Helper()
400 testenv.MustHaveGoBuild(t)
401 testenv.SkipIfShortAndSlow(t)
402
403 return &testgoData{t: t}
404 }
405
406
407 func (tg *testgoData) must(err error) {
408 tg.t.Helper()
409 if err != nil {
410 tg.t.Fatal(err)
411 }
412 }
413
414
415 func (tg *testgoData) check(err error) {
416 tg.t.Helper()
417 if err != nil {
418 tg.t.Error(err)
419 }
420 }
421
422
423 func (tg *testgoData) parallel() {
424 tg.t.Helper()
425 if tg.ran {
426 tg.t.Fatal("internal testsuite error: call to parallel after run")
427 }
428 for _, e := range tg.env {
429 if strings.HasPrefix(e, "GOROOT=") || strings.HasPrefix(e, "GOPATH=") || strings.HasPrefix(e, "GOBIN=") {
430 val := e[strings.Index(e, "=")+1:]
431 if strings.HasPrefix(val, "testdata") || strings.HasPrefix(val, "./testdata") {
432 tg.t.Fatalf("internal testsuite error: call to parallel with testdata in environment (%s)", e)
433 }
434 }
435 }
436 tg.inParallel = true
437 tg.t.Parallel()
438 }
439
440
441 func (tg *testgoData) pwd() string {
442 tg.t.Helper()
443 wd, err := os.Getwd()
444 if err != nil {
445 tg.t.Fatalf("could not get working directory: %v", err)
446 }
447 return wd
448 }
449
450
451
452
453 func (tg *testgoData) sleep() {
454 time.Sleep(mtimeTick)
455 }
456
457
458
459 func (tg *testgoData) setenv(name, val string) {
460 tg.t.Helper()
461 tg.unsetenv(name)
462 tg.env = append(tg.env, name+"="+val)
463 }
464
465
466 func (tg *testgoData) unsetenv(name string) {
467 if tg.env == nil {
468 tg.env = append([]string(nil), os.Environ()...)
469 tg.env = append(tg.env, "GO111MODULE=off", "TESTGONETWORK=panic")
470 if testing.Short() {
471 tg.env = append(tg.env, "TESTGOVCSREMOTE=panic")
472 }
473 }
474 for i, v := range tg.env {
475 if strings.HasPrefix(v, name+"=") {
476 tg.env = slices.Delete(tg.env, i, i+1)
477 break
478 }
479 }
480 }
481
482 func (tg *testgoData) goTool() string {
483 return testGo
484 }
485
486
487
488 func (tg *testgoData) doRun(args []string) error {
489 tg.t.Helper()
490 if tg.inParallel {
491 for _, arg := range args {
492 if strings.HasPrefix(arg, "testdata") || strings.HasPrefix(arg, "./testdata") {
493 tg.t.Fatal("internal testsuite error: parallel run using testdata")
494 }
495 }
496 }
497
498 hasGoroot := false
499 for _, v := range tg.env {
500 if strings.HasPrefix(v, "GOROOT=") {
501 hasGoroot = true
502 break
503 }
504 }
505 prog := tg.goTool()
506 if !hasGoroot {
507 tg.setenv("GOROOT", testGOROOT)
508 }
509
510 tg.t.Logf("running testgo %v", args)
511 cmd := testenv.Command(tg.t, prog, args...)
512 tg.stdout.Reset()
513 tg.stderr.Reset()
514 cmd.Dir = tg.execDir
515 cmd.Stdout = &tg.stdout
516 cmd.Stderr = &tg.stderr
517 cmd.Env = tg.env
518 status := cmd.Run()
519 if tg.stdout.Len() > 0 {
520 tg.t.Log("standard output:")
521 tg.t.Log(tg.stdout.String())
522 }
523 if tg.stderr.Len() > 0 {
524 tg.t.Log("standard error:")
525 tg.t.Log(tg.stderr.String())
526 }
527 tg.ran = true
528 return status
529 }
530
531
532 func (tg *testgoData) run(args ...string) {
533 tg.t.Helper()
534 if status := tg.doRun(args); status != nil {
535 wd, _ := os.Getwd()
536 tg.t.Logf("go %v failed unexpectedly in %s: %v", args, wd, status)
537 tg.t.FailNow()
538 }
539 }
540
541
542 func (tg *testgoData) runFail(args ...string) {
543 tg.t.Helper()
544 if status := tg.doRun(args); status == nil {
545 tg.t.Fatal("testgo succeeded unexpectedly")
546 } else {
547 tg.t.Log("testgo failed as expected:", status)
548 }
549 }
550
551
552 func (tg *testgoData) getStdout() string {
553 tg.t.Helper()
554 if !tg.ran {
555 tg.t.Fatal("internal testsuite error: stdout called before run")
556 }
557 return tg.stdout.String()
558 }
559
560
561 func (tg *testgoData) getStderr() string {
562 tg.t.Helper()
563 if !tg.ran {
564 tg.t.Fatal("internal testsuite error: stdout called before run")
565 }
566 return tg.stderr.String()
567 }
568
569
570
571
572 func (tg *testgoData) doGrepMatch(match string, b *bytes.Buffer) bool {
573 tg.t.Helper()
574 if !tg.ran {
575 tg.t.Fatal("internal testsuite error: grep called before run")
576 }
577 re := regexp.MustCompile(match)
578 for _, ln := range bytes.Split(b.Bytes(), []byte{'\n'}) {
579 if re.Match(ln) {
580 return true
581 }
582 }
583 return false
584 }
585
586
587
588
589
590 func (tg *testgoData) doGrep(match string, b *bytes.Buffer, name, msg string) {
591 tg.t.Helper()
592 if !tg.doGrepMatch(match, b) {
593 tg.t.Log(msg)
594 tg.t.Logf("pattern %v not found in standard %s", match, name)
595 tg.t.FailNow()
596 }
597 }
598
599
600
601 func (tg *testgoData) grepStdout(match, msg string) {
602 tg.t.Helper()
603 tg.doGrep(match, &tg.stdout, "output", msg)
604 }
605
606
607
608 func (tg *testgoData) grepStderr(match, msg string) {
609 tg.t.Helper()
610 tg.doGrep(match, &tg.stderr, "error", msg)
611 }
612
613
614
615 func (tg *testgoData) grepBoth(match, msg string) {
616 tg.t.Helper()
617 if !tg.doGrepMatch(match, &tg.stdout) && !tg.doGrepMatch(match, &tg.stderr) {
618 tg.t.Log(msg)
619 tg.t.Logf("pattern %v not found in standard output or standard error", match)
620 tg.t.FailNow()
621 }
622 }
623
624
625
626 func (tg *testgoData) doGrepNot(match string, b *bytes.Buffer, name, msg string) {
627 tg.t.Helper()
628 if tg.doGrepMatch(match, b) {
629 tg.t.Log(msg)
630 tg.t.Logf("pattern %v found unexpectedly in standard %s", match, name)
631 tg.t.FailNow()
632 }
633 }
634
635
636
637 func (tg *testgoData) grepStdoutNot(match, msg string) {
638 tg.t.Helper()
639 tg.doGrepNot(match, &tg.stdout, "output", msg)
640 }
641
642
643
644 func (tg *testgoData) grepStderrNot(match, msg string) {
645 tg.t.Helper()
646 tg.doGrepNot(match, &tg.stderr, "error", msg)
647 }
648
649
650
651
652 func (tg *testgoData) grepBothNot(match, msg string) {
653 tg.t.Helper()
654 if tg.doGrepMatch(match, &tg.stdout) || tg.doGrepMatch(match, &tg.stderr) {
655 tg.t.Log(msg)
656 tg.t.Fatalf("pattern %v found unexpectedly in standard output or standard error", match)
657 }
658 }
659
660
661 func (tg *testgoData) doGrepCount(match string, b *bytes.Buffer) int {
662 tg.t.Helper()
663 if !tg.ran {
664 tg.t.Fatal("internal testsuite error: doGrepCount called before run")
665 }
666 re := regexp.MustCompile(match)
667 c := 0
668 for _, ln := range bytes.Split(b.Bytes(), []byte{'\n'}) {
669 if re.Match(ln) {
670 c++
671 }
672 }
673 return c
674 }
675
676
677
678 func (tg *testgoData) grepCountBoth(match string) int {
679 tg.t.Helper()
680 return tg.doGrepCount(match, &tg.stdout) + tg.doGrepCount(match, &tg.stderr)
681 }
682
683
684
685
686
687 func (tg *testgoData) creatingTemp(path string) {
688 tg.t.Helper()
689 if filepath.IsAbs(path) && !strings.HasPrefix(path, tg.tempdir) {
690 tg.t.Fatalf("internal testsuite error: creatingTemp(%q) with absolute path not in temporary directory", path)
691 }
692 tg.must(robustio.RemoveAll(path))
693 tg.temps = append(tg.temps, path)
694 }
695
696
697
698 func (tg *testgoData) makeTempdir() {
699 tg.t.Helper()
700 if tg.tempdir == "" {
701 var err error
702 tg.tempdir, err = os.MkdirTemp("", "gotest")
703 tg.must(err)
704 }
705 }
706
707
708 func (tg *testgoData) tempFile(path, contents string) {
709 tg.t.Helper()
710 tg.makeTempdir()
711 tg.must(os.MkdirAll(filepath.Join(tg.tempdir, filepath.Dir(path)), 0755))
712 bytes := []byte(contents)
713 if strings.HasSuffix(path, ".go") {
714 formatted, err := format.Source(bytes)
715 if err == nil {
716 bytes = formatted
717 }
718 }
719 tg.must(os.WriteFile(filepath.Join(tg.tempdir, path), bytes, 0644))
720 }
721
722
723 func (tg *testgoData) tempDir(path string) {
724 tg.t.Helper()
725 tg.makeTempdir()
726 if err := os.MkdirAll(filepath.Join(tg.tempdir, path), 0755); err != nil && !os.IsExist(err) {
727 tg.t.Fatal(err)
728 }
729 }
730
731
732
733 func (tg *testgoData) path(name string) string {
734 tg.t.Helper()
735 if tg.tempdir == "" {
736 tg.t.Fatalf("internal testsuite error: path(%q) with no tempdir", name)
737 }
738 if name == "." {
739 return tg.tempdir
740 }
741 return filepath.Join(tg.tempdir, name)
742 }
743
744
745 func (tg *testgoData) mustExist(path string) {
746 tg.t.Helper()
747 if _, err := os.Stat(path); err != nil {
748 if os.IsNotExist(err) {
749 tg.t.Fatalf("%s does not exist but should", path)
750 }
751 tg.t.Fatalf("%s stat failed: %v", path, err)
752 }
753 }
754
755
756 func (tg *testgoData) mustNotExist(path string) {
757 tg.t.Helper()
758 if _, err := os.Stat(path); err == nil || !os.IsNotExist(err) {
759 tg.t.Fatalf("%s exists but should not (%v)", path, err)
760 }
761 }
762
763
764 func (tg *testgoData) wantExecutable(path, msg string) {
765 tg.t.Helper()
766 if st, err := os.Stat(path); err != nil {
767 if !os.IsNotExist(err) {
768 tg.t.Log(err)
769 }
770 tg.t.Fatal(msg)
771 } else {
772 if runtime.GOOS != "windows" && st.Mode()&0111 == 0 {
773 tg.t.Fatalf("binary %s exists but is not executable", path)
774 }
775 }
776 }
777
778
779 func (tg *testgoData) isStale(pkg string) (bool, string) {
780 tg.t.Helper()
781 tg.run("list", "-f", "{{.Stale}}:{{.StaleReason}}", pkg)
782 v := strings.TrimSpace(tg.getStdout())
783 f := strings.SplitN(v, ":", 2)
784 if len(f) == 2 {
785 switch f[0] {
786 case "true":
787 return true, f[1]
788 case "false":
789 return false, f[1]
790 }
791 }
792 tg.t.Fatalf("unexpected output checking staleness of package %v: %v", pkg, v)
793 panic("unreachable")
794 }
795
796
797 func (tg *testgoData) wantStale(pkg, reason, msg string) {
798 tg.t.Helper()
799 stale, why := tg.isStale(pkg)
800 if !stale {
801 tg.t.Fatal(msg)
802 }
803
804
805
806
807 if reason == "" && why != "" || !strings.Contains(why, reason) && !strings.Contains(why, "not installed but available in build cache") {
808 tg.t.Errorf("wrong reason for Stale=true: %q, want %q", why, reason)
809 }
810 }
811
812
813 func (tg *testgoData) wantNotStale(pkg, reason, msg string) {
814 tg.t.Helper()
815 stale, why := tg.isStale(pkg)
816 if stale {
817 tg.t.Fatal(msg)
818 }
819 if reason == "" && why != "" || !strings.Contains(why, reason) {
820 tg.t.Errorf("wrong reason for Stale=false: %q, want %q", why, reason)
821 }
822 }
823
824
825
826
827 var testWork = flag.Bool("testwork", false, "")
828
829
830 func (tg *testgoData) cleanup() {
831 tg.t.Helper()
832 if *testWork {
833 if tg.tempdir != "" {
834 tg.t.Logf("TESTWORK=%s\n", tg.path("."))
835 }
836 return
837 }
838 for _, path := range tg.temps {
839 tg.check(removeAll(path))
840 }
841 if tg.tempdir != "" {
842 tg.check(removeAll(tg.tempdir))
843 }
844 }
845
846 func removeAll(dir string) error {
847
848
849 filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error {
850
851
852 if err != nil || info.IsDir() {
853 os.Chmod(path, 0777)
854 }
855 return nil
856 })
857 return robustio.RemoveAll(dir)
858 }
859
860 func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) {
861 if testing.Short() {
862 t.Skip("skipping lengthy test in short mode")
863 }
864
865 tg := testgo(t)
866 defer tg.cleanup()
867 tg.parallel()
868
869
870
871 tg.tempDir("gocache")
872 tg.setenv("GOCACHE", tg.path("gocache"))
873
874
875
876 var dirs []string
877 tg.run("list", "-deps", "runtime")
878 pkgs := strings.Split(strings.TrimSpace(tg.getStdout()), "\n")
879 for _, pkg := range pkgs {
880 dirs = append(dirs, filepath.Join("src", pkg))
881 }
882 dirs = append(dirs,
883 filepath.Join("pkg/tool", goHostOS+"_"+goHostArch),
884 "pkg/include",
885 )
886 for _, copydir := range dirs {
887 srcdir := filepath.Join(testGOROOT, copydir)
888 tg.tempDir(filepath.Join("goroot", copydir))
889 err := filepath.WalkDir(srcdir,
890 func(path string, info fs.DirEntry, err error) error {
891 if err != nil {
892 return err
893 }
894 if info.IsDir() {
895 return nil
896 }
897 srcrel, err := filepath.Rel(srcdir, path)
898 if err != nil {
899 return err
900 }
901 dest := filepath.Join("goroot", copydir, srcrel)
902 if _, err := os.Stat(dest); err == nil {
903 return nil
904 }
905 data, err := os.ReadFile(path)
906 if err != nil {
907 return err
908 }
909 tg.tempFile(dest, string(data))
910 if strings.Contains(copydir, filepath.Join("pkg", "tool")) {
911 os.Chmod(tg.path(dest), 0777)
912 }
913 return nil
914 })
915 if err != nil {
916 t.Fatal(err)
917 }
918 }
919 tg.setenv("GOROOT", tg.path("goroot"))
920
921 addVar := func(name string, idx int) (restore func()) {
922 data, err := os.ReadFile(name)
923 if err != nil {
924 t.Fatal(err)
925 }
926 old := data
927 data = append(data, fmt.Sprintf("var DummyUnusedVar%d bool\n", idx)...)
928 if err := os.WriteFile(name, append(data, '\n'), 0666); err != nil {
929 t.Fatal(err)
930 }
931 tg.sleep()
932 return func() {
933 if err := os.WriteFile(name, old, 0666); err != nil {
934 t.Fatal(err)
935 }
936 }
937 }
938
939
940 tg.tempFile("d1/src/p1/p1.go", `package main; func main(){}`)
941 tg.setenv("GOPATH", tg.path("d1"))
942
943 tg.run("install", "p1")
944 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, before any changes")
945
946
947
948
949 sys := tg.path("goroot/src/internal/runtime/sys/sys.go")
950 tg.sleep()
951 restore := addVar(sys, 0)
952 restore()
953 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, after updating mtime of internal/runtime/sys/sys.go")
954
955
956
957
958 restore = addVar(sys, 1)
959 defer restore()
960 tg.wantStale("p1", "stale dependency: internal/runtime/sys", "./testgo list claims p1 is NOT stale, incorrectly, after changing sys.go")
961 restore()
962 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, after changing back to old release")
963 addVar(sys, 2)
964 tg.wantStale("p1", "stale dependency: internal/runtime/sys", "./testgo list claims p1 is NOT stale, incorrectly, after changing sys.go again")
965 tg.run("install", "p1")
966 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after building with new release")
967
968
969 restore()
970 tg.wantStale("p1", "not installed but available in build cache", "./testgo list claims p1 is NOT stale, incorrectly, after restoring sys.go")
971 tg.run("install", "p1")
972 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after building with old release")
973 }
974
975 func TestPackageMainTestCompilerFlags(t *testing.T) {
976 tg := testgo(t)
977 defer tg.cleanup()
978 tg.parallel()
979 tg.makeTempdir()
980 tg.setenv("GOPATH", tg.path("."))
981 tg.tempFile("src/p1/p1.go", "package main\n")
982 tg.tempFile("src/p1/p1_test.go", "package main\nimport \"testing\"\nfunc Test(t *testing.T){}\n")
983 tg.run("test", "-c", "-n", "p1")
984 tg.grepBothNot(`([\\/]compile|gccgo).* (-p main|-fgo-pkgpath=main).*p1\.go`, "should not have run compile -p main p1.go")
985 tg.grepStderr(`([\\/]compile|gccgo).* (-p p1|-fgo-pkgpath=p1).*p1\.go`, "should have run compile -p p1 p1.go")
986 }
987
988
989 func TestGoTestWithPackageListedMultipleTimes(t *testing.T) {
990 tooSlow(t, "links and runs a test")
991
992 tg := testgo(t)
993 defer tg.cleanup()
994 tg.parallel()
995 tg.run("test", "errors", "errors", "errors", "errors", "errors")
996 if strings.Contains(strings.TrimSpace(tg.getStdout()), "\n") {
997 t.Error("go test errors errors errors errors errors tested the same package multiple times")
998 }
999 }
1000
1001 func TestGoListHasAConsistentOrder(t *testing.T) {
1002 tooSlow(t, "walks all of GOROOT/src twice")
1003
1004 tg := testgo(t)
1005 defer tg.cleanup()
1006 tg.parallel()
1007 tg.run("list", "std")
1008 first := tg.getStdout()
1009 tg.run("list", "std")
1010 if first != tg.getStdout() {
1011 t.Error("go list std ordering is inconsistent")
1012 }
1013 }
1014
1015 func TestGoListStdDoesNotIncludeCommands(t *testing.T) {
1016 tooSlow(t, "walks all of GOROOT/src")
1017
1018 tg := testgo(t)
1019 defer tg.cleanup()
1020 tg.parallel()
1021 tg.run("list", "std")
1022 tg.grepStdoutNot("cmd/", "go list std shows commands")
1023 }
1024
1025 func TestGoListCmdOnlyShowsCommands(t *testing.T) {
1026 skipIfGccgo(t, "gccgo does not have GOROOT")
1027 tooSlow(t, "walks all of GOROOT/src/cmd")
1028
1029 tg := testgo(t)
1030 defer tg.cleanup()
1031 tg.parallel()
1032 tg.run("list", "cmd")
1033 out := strings.TrimSpace(tg.getStdout())
1034 for _, line := range strings.Split(out, "\n") {
1035 if !strings.Contains(line, "cmd/") {
1036 t.Error("go list cmd shows non-commands")
1037 break
1038 }
1039 }
1040 }
1041
1042 func TestGoListDeps(t *testing.T) {
1043 tg := testgo(t)
1044 defer tg.cleanup()
1045 tg.parallel()
1046 tg.tempDir("src/p1/p2/p3/p4")
1047 tg.setenv("GOPATH", tg.path("."))
1048 tg.tempFile("src/p1/p.go", "package p1\nimport _ \"p1/p2\"\n")
1049 tg.tempFile("src/p1/p2/p.go", "package p2\nimport _ \"p1/p2/p3\"\n")
1050 tg.tempFile("src/p1/p2/p3/p.go", "package p3\nimport _ \"p1/p2/p3/p4\"\n")
1051 tg.tempFile("src/p1/p2/p3/p4/p.go", "package p4\n")
1052 tg.run("list", "-f", "{{.Deps}}", "p1")
1053 tg.grepStdout("p1/p2/p3/p4", "Deps(p1) does not mention p4")
1054
1055 tg.run("list", "-deps", "p1")
1056 tg.grepStdout("p1/p2/p3/p4", "-deps p1 does not mention p4")
1057
1058 if runtime.Compiler != "gccgo" {
1059
1060 tg.run("list", "-deps", "math")
1061 want := "unsafe\ninternal/cpu\nmath/bits\nmath\n"
1062 out := tg.stdout.String()
1063 if !strings.Contains(out, "internal/cpu") {
1064
1065 want = "unsafe\nmath/bits\nmath\n"
1066 }
1067 if tg.stdout.String() != want {
1068 t.Fatalf("list -deps math: wrong order\nhave %q\nwant %q", tg.stdout.String(), want)
1069 }
1070 }
1071 }
1072
1073 func TestGoListTest(t *testing.T) {
1074 skipIfGccgo(t, "gccgo does not have standard packages")
1075 tg := testgo(t)
1076 defer tg.cleanup()
1077 tg.parallel()
1078 tg.makeTempdir()
1079 tg.setenv("GOCACHE", tg.tempdir)
1080
1081 tg.run("list", "-test", "-deps", "bytes")
1082 tg.grepStdout(`^bytes.test$`, "missing test main")
1083 tg.grepStdout(`^bytes$`, "missing real bytes")
1084 tg.grepStdout(`^bytes \[bytes.test\]$`, "missing test copy of bytes")
1085 tg.grepStdout(`^testing \[bytes.test\]$`, "missing test copy of testing")
1086 tg.grepStdoutNot(`^testing$`, "unexpected real copy of testing")
1087
1088 tg.run("list", "-test", "bytes")
1089 tg.grepStdout(`^bytes.test$`, "missing test main")
1090 tg.grepStdout(`^bytes$`, "missing real bytes")
1091 tg.grepStdout(`^bytes \[bytes.test\]$`, "unexpected test copy of bytes")
1092 tg.grepStdoutNot(`^testing \[bytes.test\]$`, "unexpected test copy of testing")
1093 tg.grepStdoutNot(`^testing$`, "unexpected real copy of testing")
1094
1095 tg.run("list", "-test", "cmd/buildid", "cmd/gofmt")
1096 tg.grepStdout(`^cmd/buildid$`, "missing cmd/buildid")
1097 tg.grepStdout(`^cmd/gofmt$`, "missing cmd/gofmt")
1098 tg.grepStdout(`^cmd/gofmt\.test$`, "missing cmd/gofmt test")
1099 tg.grepStdoutNot(`^cmd/buildid\.test$`, "unexpected cmd/buildid test")
1100 tg.grepStdoutNot(`^testing`, "unexpected testing")
1101
1102 tg.run("list", "-test", "runtime/cgo")
1103 tg.grepStdout(`^runtime/cgo$`, "missing runtime/cgo")
1104
1105 tg.run("list", "-deps", "-f", "{{if .DepOnly}}{{.ImportPath}}{{end}}", "sort")
1106 tg.grepStdout(`^internal/reflectlite$`, "missing internal/reflectlite")
1107 tg.grepStdoutNot(`^sort`, "unexpected sort")
1108 }
1109
1110 func TestGoListCompiledCgo(t *testing.T) {
1111 tooSlow(t, "compiles cgo files")
1112
1113 tg := testgo(t)
1114 defer tg.cleanup()
1115 tg.parallel()
1116 tg.makeTempdir()
1117 tg.setenv("GOCACHE", tg.tempdir)
1118
1119 tg.run("list", "-f", `{{join .CgoFiles "\n"}}`, "net")
1120 if tg.stdout.String() == "" {
1121 t.Skip("net does not use cgo")
1122 }
1123 if strings.Contains(tg.stdout.String(), tg.tempdir) {
1124 t.Fatalf(".CgoFiles unexpectedly mentioned cache %s", tg.tempdir)
1125 }
1126 tg.run("list", "-compiled", "-f", `{{.Dir}}{{"\n"}}{{join .CompiledGoFiles "\n"}}`, "net")
1127 if !strings.Contains(tg.stdout.String(), tg.tempdir) {
1128 t.Fatalf(".CompiledGoFiles with -compiled did not mention cache %s", tg.tempdir)
1129 }
1130 dir := ""
1131 for _, file := range strings.Split(tg.stdout.String(), "\n") {
1132 if file == "" {
1133 continue
1134 }
1135 if dir == "" {
1136 dir = file
1137 continue
1138 }
1139 if !strings.Contains(file, "/") && !strings.Contains(file, `\`) {
1140 file = filepath.Join(dir, file)
1141 }
1142 if _, err := os.Stat(file); err != nil {
1143 t.Fatalf("cannot find .CompiledGoFiles result %s: %v", file, err)
1144 }
1145 }
1146 }
1147
1148 func TestGoListExport(t *testing.T) {
1149 tooSlow(t, "runs build for -export")
1150
1151 skipIfGccgo(t, "gccgo does not have standard packages")
1152 tg := testgo(t)
1153 defer tg.cleanup()
1154 tg.parallel()
1155 tg.makeTempdir()
1156 tg.setenv("GOCACHE", tg.tempdir)
1157
1158 tg.run("list", "-f", "{{.Export}}", "strings")
1159 if tg.stdout.String() != "" {
1160 t.Fatalf(".Export without -export unexpectedly set")
1161 }
1162 tg.run("list", "-export", "-f", "{{.Export}}", "strings")
1163 file := strings.TrimSpace(tg.stdout.String())
1164 if file == "" {
1165 t.Fatalf(".Export with -export was empty")
1166 }
1167 if _, err := os.Stat(file); err != nil {
1168 t.Fatalf("cannot find .Export result %s: %v", file, err)
1169 }
1170
1171 tg.run("list", "-export", "-f", "{{.BuildID}}", "strings")
1172 buildID := strings.TrimSpace(tg.stdout.String())
1173 if buildID == "" {
1174 t.Fatalf(".BuildID with -export was empty")
1175 }
1176
1177 tg.run("tool", "buildid", file)
1178 toolBuildID := strings.TrimSpace(tg.stdout.String())
1179 if buildID != toolBuildID {
1180 t.Fatalf(".BuildID with -export %q disagrees with 'go tool buildid' %q", buildID, toolBuildID)
1181 }
1182 }
1183
1184
1185 func TestUnsuccessfulGoInstallShouldMentionMissingPackage(t *testing.T) {
1186 tg := testgo(t)
1187 defer tg.cleanup()
1188 tg.parallel()
1189 tg.runFail("install", "foo/quxx")
1190 if tg.grepCountBoth(`cannot find package "foo/quxx" in any of`) != 1 {
1191 t.Error(`go install foo/quxx expected error: .*cannot find package "foo/quxx" in any of`)
1192 }
1193 }
1194
1195 func TestGOROOTSearchFailureReporting(t *testing.T) {
1196 tg := testgo(t)
1197 defer tg.cleanup()
1198 tg.parallel()
1199 tg.runFail("install", "foo/quxx")
1200 if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("foo", "quxx"))+` \(from \$GOROOT\)$`) != 1 {
1201 t.Error(`go install foo/quxx expected error: .*foo/quxx (from $GOROOT)`)
1202 }
1203 }
1204
1205 func TestMultipleGOPATHEntriesReportedSeparately(t *testing.T) {
1206 tg := testgo(t)
1207 defer tg.cleanup()
1208 tg.parallel()
1209 sep := string(filepath.ListSeparator)
1210 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
1211 tg.runFail("install", "foo/quxx")
1212 if tg.grepCountBoth(`testdata[/\\].[/\\]src[/\\]foo[/\\]quxx`) != 2 {
1213 t.Error(`go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)\n.*testdata/b/src/foo/quxx`)
1214 }
1215 }
1216
1217
1218 func TestMentionGOPATHInFirstGOPATHEntry(t *testing.T) {
1219 tg := testgo(t)
1220 defer tg.cleanup()
1221 tg.parallel()
1222 sep := string(filepath.ListSeparator)
1223 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
1224 tg.runFail("install", "foo/quxx")
1225 if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("testdata", "a", "src", "foo", "quxx"))+` \(from \$GOPATH\)$`) != 1 {
1226 t.Error(`go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)`)
1227 }
1228 }
1229
1230
1231 func TestMentionGOPATHNotOnSecondEntry(t *testing.T) {
1232 tg := testgo(t)
1233 defer tg.cleanup()
1234 tg.parallel()
1235 sep := string(filepath.ListSeparator)
1236 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b"))
1237 tg.runFail("install", "foo/quxx")
1238 if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("testdata", "b", "src", "foo", "quxx"))+`$`) != 1 {
1239 t.Error(`go install foo/quxx expected error: .*testdata/b/src/foo/quxx`)
1240 }
1241 }
1242
1243 func homeEnvName() string {
1244 switch runtime.GOOS {
1245 case "windows":
1246 return "USERPROFILE"
1247 case "plan9":
1248 return "home"
1249 default:
1250 return "HOME"
1251 }
1252 }
1253
1254 func tempEnvName() string {
1255 switch runtime.GOOS {
1256 case "windows":
1257 return "TMP"
1258 case "plan9":
1259 return "TMPDIR"
1260 default:
1261 return "TMPDIR"
1262 }
1263 }
1264
1265 func pathEnvName() string {
1266 switch runtime.GOOS {
1267 case "plan9":
1268 return "path"
1269 default:
1270 return "PATH"
1271 }
1272 }
1273
1274 func TestDefaultGOPATH(t *testing.T) {
1275 tg := testgo(t)
1276 defer tg.cleanup()
1277 tg.parallel()
1278 tg.tempDir("home/go")
1279 tg.setenv(homeEnvName(), tg.path("home"))
1280
1281
1282
1283 tg.setenv("TEST_TELEMETRY_DIR", "/no-telemetry-dir")
1284
1285 tg.run("env", "GOPATH")
1286 tg.grepStdout(regexp.QuoteMeta(tg.path("home/go")), "want GOPATH=$HOME/go")
1287
1288 tg.setenv("GOROOT", tg.path("home/go"))
1289 tg.run("env", "GOPATH")
1290 tg.grepStdoutNot(".", "want unset GOPATH because GOROOT=$HOME/go")
1291
1292 tg.setenv("GOROOT", tg.path("home/go")+"/")
1293 tg.run("env", "GOPATH")
1294 tg.grepStdoutNot(".", "want unset GOPATH because GOROOT=$HOME/go/")
1295 }
1296
1297 func TestDefaultGOPATHPrintedSearchList(t *testing.T) {
1298 tg := testgo(t)
1299 defer tg.cleanup()
1300 tg.parallel()
1301 tg.setenv("GOPATH", "")
1302 tg.tempDir("home")
1303 tg.setenv(homeEnvName(), tg.path("home"))
1304
1305
1306
1307 tg.setenv("TEST_TELEMETRY_DIR", "/no-telemetry-dir")
1308
1309 tg.runFail("install", "github.com/golang/example/hello")
1310 tg.grepStderr(regexp.QuoteMeta(tg.path("home/go/src/github.com/golang/example/hello"))+`.*from \$GOPATH`, "expected default GOPATH")
1311 }
1312
1313 func TestLdflagsArgumentsWithSpacesIssue3941(t *testing.T) {
1314 skipIfGccgo(t, "gccgo does not support -ldflags -X")
1315 tooSlow(t, "compiles and links a binary")
1316
1317 tg := testgo(t)
1318 defer tg.cleanup()
1319 tg.parallel()
1320 tg.tempFile("main.go", `package main
1321 var extern string
1322 func main() {
1323 println(extern)
1324 }`)
1325 tg.run("run", "-ldflags", `-X "main.extern=hello world"`, tg.path("main.go"))
1326 tg.grepStderr("^hello world", `ldflags -X "main.extern=hello world"' failed`)
1327 }
1328
1329 func TestLdFlagsLongArgumentsIssue42295(t *testing.T) {
1330
1331
1332 skipIfGccgo(t, "gccgo does not support -ldflags -X")
1333 tooSlow(t, "compiles and links a binary")
1334
1335 tg := testgo(t)
1336 defer tg.cleanup()
1337 tg.parallel()
1338 tg.tempFile("main.go", `package main
1339 var extern string
1340 func main() {
1341 print(extern)
1342 }`)
1343 testStr := "test test test test test \n\\ "
1344 var buf strings.Builder
1345 for buf.Len() < sys.ExecArgLengthLimit+1 {
1346 buf.WriteString(testStr)
1347 }
1348 tg.run("run", "-ldflags", fmt.Sprintf(`-X "main.extern=%s"`, buf.String()), tg.path("main.go"))
1349 if tg.stderr.String() != buf.String() {
1350 t.Errorf("strings differ")
1351 }
1352 }
1353
1354 func TestGoTestDashCDashOControlsBinaryLocation(t *testing.T) {
1355 skipIfGccgo(t, "gccgo has no standard packages")
1356 tooSlow(t, "compiles and links a test binary")
1357
1358 tg := testgo(t)
1359 defer tg.cleanup()
1360 tg.parallel()
1361 tg.makeTempdir()
1362 tg.run("test", "-c", "-o", tg.path("myerrors.test"+exeSuffix), "errors")
1363 tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -c -o myerrors.test did not create myerrors.test")
1364 }
1365
1366 func TestGoTestDashOWritesBinary(t *testing.T) {
1367 skipIfGccgo(t, "gccgo has no standard packages")
1368 tooSlow(t, "compiles and runs a test binary")
1369
1370 tg := testgo(t)
1371 defer tg.cleanup()
1372 tg.parallel()
1373 tg.makeTempdir()
1374 tg.run("test", "-o", tg.path("myerrors.test"+exeSuffix), "errors")
1375 tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -o myerrors.test did not create myerrors.test")
1376 }
1377
1378
1379 func TestInstallWithTags(t *testing.T) {
1380 tooSlow(t, "compiles and links binaries")
1381
1382 tg := testgo(t)
1383 defer tg.cleanup()
1384 tg.parallel()
1385 tg.tempDir("bin")
1386 tg.tempFile("src/example/a/main.go", `package main
1387 func main() {}`)
1388 tg.tempFile("src/example/b/main.go", `// +build mytag
1389
1390 package main
1391 func main() {}`)
1392 tg.setenv("GOPATH", tg.path("."))
1393 tg.run("install", "-tags", "mytag", "example/a", "example/b")
1394 tg.wantExecutable(tg.path("bin/a"+exeSuffix), "go install example/a example/b did not install binaries")
1395 tg.wantExecutable(tg.path("bin/b"+exeSuffix), "go install example/a example/b did not install binaries")
1396 tg.must(os.Remove(tg.path("bin/a" + exeSuffix)))
1397 tg.must(os.Remove(tg.path("bin/b" + exeSuffix)))
1398 tg.run("install", "-tags", "mytag", "example/...")
1399 tg.wantExecutable(tg.path("bin/a"+exeSuffix), "go install example/... did not install binaries")
1400 tg.wantExecutable(tg.path("bin/b"+exeSuffix), "go install example/... did not install binaries")
1401 tg.run("list", "-tags", "mytag", "example/b...")
1402 if strings.TrimSpace(tg.getStdout()) != "example/b" {
1403 t.Error("go list example/b did not find example/b")
1404 }
1405 }
1406
1407
1408 func TestSymlinkWarning(t *testing.T) {
1409 tg := testgo(t)
1410 defer tg.cleanup()
1411 tg.parallel()
1412 tg.makeTempdir()
1413 tg.setenv("GOPATH", tg.path("."))
1414
1415 tg.tempDir("src/example/xx")
1416 tg.tempDir("yy/zz")
1417 tg.tempFile("yy/zz/zz.go", "package zz\n")
1418 if err := os.Symlink(tg.path("yy"), tg.path("src/example/xx/yy")); err != nil {
1419 t.Skipf("symlink failed: %v", err)
1420 }
1421 tg.run("list", "example/xx/z...")
1422 tg.grepStdoutNot(".", "list should not have matched anything")
1423 tg.grepStderr("matched no packages", "list should have reported that pattern matched no packages")
1424 tg.grepStderrNot("symlink", "list should not have reported symlink")
1425
1426 tg.run("list", "example/xx/...")
1427 tg.grepStdoutNot(".", "list should not have matched anything")
1428 tg.grepStderr("matched no packages", "list should have reported that pattern matched no packages")
1429 tg.grepStderr("ignoring symlink", "list should have reported symlink")
1430 }
1431
1432 func TestCgoShowsFullPathNames(t *testing.T) {
1433 testenv.MustHaveCGO(t)
1434
1435 tg := testgo(t)
1436 defer tg.cleanup()
1437 tg.parallel()
1438 tg.tempFile("src/x/y/dirname/foo.go", `
1439 package foo
1440 import "C"
1441 func f() {`)
1442 tg.setenv("GOPATH", tg.path("."))
1443 tg.runFail("build", "x/y/dirname")
1444 tg.grepBoth("x/y/dirname", "error did not use full path")
1445 }
1446
1447 func TestCgoHandlesWlORIGIN(t *testing.T) {
1448 tooSlow(t, "compiles cgo files")
1449 testenv.MustHaveCGO(t)
1450
1451 tg := testgo(t)
1452 defer tg.cleanup()
1453 tg.parallel()
1454 tg.tempFile("src/origin/origin.go", `package origin
1455 // #cgo !darwin,!windows LDFLAGS: -Wl,-rpath,$ORIGIN
1456 // void f(void) {}
1457 import "C"
1458 func f() { C.f() }`)
1459 tg.setenv("GOPATH", tg.path("."))
1460 tg.run("build", "origin")
1461 }
1462
1463 func TestCgoPkgConfig(t *testing.T) {
1464 tooSlow(t, "compiles cgo files")
1465 testenv.MustHaveCGO(t)
1466
1467 tg := testgo(t)
1468 defer tg.cleanup()
1469 tg.parallel()
1470
1471 tg.run("env", "PKG_CONFIG")
1472 pkgConfig := strings.TrimSpace(tg.getStdout())
1473 testenv.MustHaveExecPath(t, pkgConfig)
1474 if out, err := testenv.Command(t, pkgConfig, "--atleast-pkgconfig-version", "0.24").CombinedOutput(); err != nil {
1475 t.Skipf("%s --atleast-pkgconfig-version 0.24: %v\n%s", pkgConfig, err, out)
1476 }
1477
1478
1479
1480
1481
1482 tg.tempFile("foo.pc", `
1483 Name: foo
1484 Description: The foo library
1485 Version: 1.0.0
1486 Cflags: -Dhello=10 -Dworld=+32 -DDEFINED_FROM_PKG_CONFIG=hello\ world
1487 `)
1488 tg.tempFile("foo.go", `package main
1489
1490 /*
1491 #cgo pkg-config: foo
1492 int value() {
1493 return DEFINED_FROM_PKG_CONFIG;
1494 }
1495 */
1496 import "C"
1497 import "os"
1498
1499 func main() {
1500 if C.value() != 42 {
1501 println("value() =", C.value(), "wanted 42")
1502 os.Exit(1)
1503 }
1504 }
1505 `)
1506 tg.setenv("PKG_CONFIG_PATH", tg.path("."))
1507 tg.run("run", tg.path("foo.go"))
1508
1509 if runtime.GOOS != "darwin" {
1510
1511 tg.tempFile("bar.pc", `
1512 Name: bar
1513 Description: The bar library
1514 Version: 1.0.0
1515 Libs: -Wl,-rpath=/path\ with\ spaces/bin
1516 `)
1517 }
1518
1519 tg.tempFile("bar.go", `package main
1520 /*
1521 #cgo pkg-config: bar
1522 */
1523 import "C"
1524 func main() {}
1525 `)
1526 tg.run("run", tg.path("bar.go"))
1527 }
1528
1529 func TestListTemplateContextFunction(t *testing.T) {
1530 t.Parallel()
1531 for _, tt := range []struct {
1532 v string
1533 want string
1534 }{
1535 {"GOARCH", runtime.GOARCH},
1536 {"GOOS", runtime.GOOS},
1537 {"GOROOT", testGOROOT},
1538 {"GOPATH", os.Getenv("GOPATH")},
1539 {"CgoEnabled", ""},
1540 {"UseAllFiles", ""},
1541 {"Compiler", ""},
1542 {"BuildTags", ""},
1543 {"ReleaseTags", ""},
1544 {"InstallSuffix", ""},
1545 } {
1546 tt := tt
1547 t.Run(tt.v, func(t *testing.T) {
1548 tg := testgo(t)
1549 tg.parallel()
1550 defer tg.cleanup()
1551 tmpl := "{{context." + tt.v + "}}"
1552 tg.run("list", "-f", tmpl)
1553 if tt.want == "" {
1554 return
1555 }
1556 if got := strings.TrimSpace(tg.getStdout()); got != tt.want {
1557 t.Errorf("go list -f %q: got %q; want %q", tmpl, got, tt.want)
1558 }
1559 })
1560 }
1561 }
1562
1563
1564
1565
1566 func TestImportLocal(t *testing.T) {
1567 tooSlow(t, "builds a lot of sequential packages")
1568
1569 tg := testgo(t)
1570 tg.parallel()
1571 defer tg.cleanup()
1572
1573 tg.tempFile("src/dir/x/x.go", `package x
1574 var X int
1575 `)
1576 tg.setenv("GOPATH", tg.path("."))
1577 tg.run("build", "dir/x")
1578
1579
1580 tg.tempFile("src/dir/p0/p.go", `package p0
1581 import "dir/x"
1582 var _ = x.X
1583 `)
1584 tg.run("build", "dir/p0")
1585
1586
1587 tg.tempFile("src/dir/p1/p.go", `package p1
1588 import "../x"
1589 var _ = x.X
1590 `)
1591 tg.runFail("build", "dir/p1")
1592 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1593
1594
1595 tg.tempFile("src/dir/p2/p.go", `package p2
1596 `)
1597 tg.tempFile("src/dir/p2/p_test.go", `package p2
1598 import "../x"
1599 import "testing"
1600 var _ = x.X
1601 func TestFoo(t *testing.T) {}
1602 `)
1603 tg.run("build", "dir/p2")
1604 tg.runFail("test", "dir/p2")
1605 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1606
1607
1608 tg.tempFile("src/dir/p2/p_test.go", `package p2_test
1609 import "../x"
1610 import "testing"
1611 var _ = x.X
1612 func TestFoo(t *testing.T) {}
1613 `)
1614 tg.run("build", "dir/p2")
1615 tg.runFail("test", "dir/p2")
1616 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1617
1618
1619 tg.tempFile("src/dir/d.go", `package dir
1620 import "./x"
1621 var _ = x.X
1622 `)
1623 tg.runFail("build", "dir")
1624 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1625
1626
1627 tg.tempFile("src/dir/d.go", `package dir
1628 `)
1629 tg.tempFile("src/dir/d_test.go", `package dir
1630 import "./x"
1631 import "testing"
1632 var _ = x.X
1633 func TestFoo(t *testing.T) {}
1634 `)
1635 tg.run("build", "dir")
1636 tg.runFail("test", "dir")
1637 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1638
1639
1640 tg.tempFile("src/dir/d_test.go", `package dir_test
1641 import "./x"
1642 import "testing"
1643 var _ = x.X
1644 func TestFoo(t *testing.T) {}
1645 `)
1646 tg.run("build", "dir")
1647 tg.runFail("test", "dir")
1648 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1649
1650
1651 tg.tempFile("src/dir/x/y/y.go", `package dir
1652 import ".."
1653 var _ = x.X
1654 `)
1655 tg.runFail("build", "dir/x/y")
1656 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1657
1658
1659 tg.tempFile("src/dir/x/y/y.go", `package y
1660 `)
1661 tg.tempFile("src/dir/x/y/y_test.go", `package y
1662 import ".."
1663 import "testing"
1664 var _ = x.X
1665 func TestFoo(t *testing.T) {}
1666 `)
1667 tg.run("build", "dir/x/y")
1668 tg.runFail("test", "dir/x/y")
1669 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1670
1671
1672 tg.tempFile("src/dir/x/y/y_test.go", `package y_test
1673 import ".."
1674 import "testing"
1675 var _ = x.X
1676 func TestFoo(t *testing.T) {}
1677 `)
1678 tg.run("build", "dir/x/y")
1679 tg.runFail("test", "dir/x/y")
1680 tg.grepStderr("local import.*in non-local package", "did not diagnose local import")
1681
1682
1683 tg.tempFile("src/dir/x/xx.go", `package x
1684 import "."
1685 var _ = x.X
1686 `)
1687 tg.runFail("build", "dir/x")
1688 tg.grepStderr("cannot import current directory", "did not diagnose import current directory")
1689
1690
1691 tg.tempFile("src/dir/x/xx.go", `package x
1692 `)
1693 tg.tempFile("src/dir/x/xx_test.go", `package x
1694 import "."
1695 import "testing"
1696 var _ = x.X
1697 func TestFoo(t *testing.T) {}
1698 `)
1699 tg.run("build", "dir/x")
1700 tg.runFail("test", "dir/x")
1701 tg.grepStderr("cannot import current directory", "did not diagnose import current directory")
1702
1703
1704 tg.tempFile("src/dir/x/xx.go", `package x
1705 `)
1706 tg.tempFile("src/dir/x/xx_test.go", `package x_test
1707 import "."
1708 import "testing"
1709 var _ = x.X
1710 func TestFoo(t *testing.T) {}
1711 `)
1712 tg.run("build", "dir/x")
1713 tg.runFail("test", "dir/x")
1714 tg.grepStderr("cannot import current directory", "did not diagnose import current directory")
1715 }
1716
1717 func TestGoInstallPkgdir(t *testing.T) {
1718 skipIfGccgo(t, "gccgo has no standard packages")
1719 tooSlow(t, "builds a package with cgo dependencies")
1720
1721
1722
1723 testenv.MustHaveCGO(t)
1724
1725 tg := testgo(t)
1726 tg.parallel()
1727 tg.setenv("GODEBUG", "installgoroot=all")
1728 defer tg.cleanup()
1729 tg.makeTempdir()
1730 pkg := tg.path(".")
1731 tg.run("install", "-pkgdir", pkg, "net")
1732 tg.mustExist(filepath.Join(pkg, "net.a"))
1733 tg.mustNotExist(filepath.Join(pkg, "runtime/cgo.a"))
1734 }
1735
1736
1737 func TestParallelTest(t *testing.T) {
1738 tooSlow(t, "links and runs test binaries")
1739
1740 tg := testgo(t)
1741 tg.parallel()
1742 defer tg.cleanup()
1743 tg.makeTempdir()
1744 const testSrc = `package package_test
1745 import (
1746 "testing"
1747 )
1748 func TestTest(t *testing.T) {
1749 }`
1750 tg.tempFile("src/p1/p1_test.go", strings.Replace(testSrc, "package_test", "p1_test", 1))
1751 tg.tempFile("src/p2/p2_test.go", strings.Replace(testSrc, "package_test", "p2_test", 1))
1752 tg.tempFile("src/p3/p3_test.go", strings.Replace(testSrc, "package_test", "p3_test", 1))
1753 tg.tempFile("src/p4/p4_test.go", strings.Replace(testSrc, "package_test", "p4_test", 1))
1754 tg.setenv("GOPATH", tg.path("."))
1755 tg.run("test", "-p=4", "p1", "p2", "p3", "p4")
1756 }
1757
1758 func TestBinaryOnlyPackages(t *testing.T) {
1759 tooSlow(t, "compiles several packages sequentially")
1760
1761 tg := testgo(t)
1762 defer tg.cleanup()
1763 tg.parallel()
1764 tg.makeTempdir()
1765 tg.setenv("GOPATH", tg.path("."))
1766
1767 tg.tempFile("src/p1/p1.go", `//go:binary-only-package
1768
1769 package p1
1770 `)
1771 tg.wantStale("p1", "binary-only packages are no longer supported", "p1 is binary-only, and this message should always be printed")
1772 tg.runFail("install", "p1")
1773 tg.grepStderr("binary-only packages are no longer supported", "did not report attempt to compile binary-only package")
1774
1775 tg.tempFile("src/p1/p1.go", `
1776 package p1
1777 import "fmt"
1778 func F(b bool) { fmt.Printf("hello from p1\n"); if b { F(false) } }
1779 `)
1780 tg.run("install", "p1")
1781 os.Remove(tg.path("src/p1/p1.go"))
1782 tg.mustNotExist(tg.path("src/p1/p1.go"))
1783
1784 tg.tempFile("src/p2/p2.go", `//go:binary-only-packages-are-not-great
1785
1786 package p2
1787 import "p1"
1788 func F() { p1.F(true) }
1789 `)
1790 tg.runFail("install", "p2")
1791 tg.grepStderr("no Go files", "did not complain about missing sources")
1792
1793 tg.tempFile("src/p1/missing.go", `//go:binary-only-package
1794
1795 package p1
1796 import _ "fmt"
1797 func G()
1798 `)
1799 tg.wantStale("p1", "binary-only package", "should NOT want to rebuild p1 (first)")
1800 tg.runFail("install", "p2")
1801 tg.grepStderr("p1: binary-only packages are no longer supported", "did not report error for binary-only p1")
1802
1803 tg.run("list", "-deps", "-f", "{{.ImportPath}}: {{.BinaryOnly}}", "p2")
1804 tg.grepStdout("p1: true", "p1 not listed as BinaryOnly")
1805 tg.grepStdout("p2: false", "p2 listed as BinaryOnly")
1806 }
1807
1808
1809 func TestLinkSysoFiles(t *testing.T) {
1810 if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
1811 t.Skip("not linux/amd64")
1812 }
1813
1814 tg := testgo(t)
1815 defer tg.cleanup()
1816 tg.parallel()
1817 tg.tempDir("src/syso")
1818 tg.tempFile("src/syso/a.syso", ``)
1819 tg.tempFile("src/syso/b.go", `package syso`)
1820 tg.setenv("GOPATH", tg.path("."))
1821
1822
1823
1824
1825 tg.setenv("CGO_ENABLED", "1")
1826 tg.run("list", "-f", "{{.SysoFiles}}", "syso")
1827 tg.grepStdout("a.syso", "missing syso file with CGO_ENABLED=1")
1828
1829 tg.setenv("CGO_ENABLED", "0")
1830 tg.run("list", "-f", "{{.SysoFiles}}", "syso")
1831 tg.grepStdout("a.syso", "missing syso file with CGO_ENABLED=0")
1832
1833 tg.setenv("CGO_ENABLED", "1")
1834 tg.run("list", "-msan", "-f", "{{.SysoFiles}}", "syso")
1835 tg.grepStdoutNot("a.syso", "unexpected syso file with -msan")
1836 }
1837
1838
1839 func TestGenerateUsesBuildContext(t *testing.T) {
1840 if runtime.GOOS == "windows" {
1841 t.Skip("this test won't run under Windows")
1842 }
1843
1844 tg := testgo(t)
1845 defer tg.cleanup()
1846 tg.parallel()
1847 tg.tempDir("src/gen")
1848 tg.tempFile("src/gen/gen.go", "package gen\n//go:generate echo $GOOS $GOARCH\n")
1849 tg.setenv("GOPATH", tg.path("."))
1850
1851 tg.setenv("GOOS", "linux")
1852 tg.setenv("GOARCH", "amd64")
1853 tg.run("generate", "gen")
1854 tg.grepStdout("linux amd64", "unexpected GOOS/GOARCH combination")
1855
1856 tg.setenv("GOOS", "darwin")
1857 tg.setenv("GOARCH", "arm64")
1858 tg.run("generate", "gen")
1859 tg.grepStdout("darwin arm64", "unexpected GOOS/GOARCH combination")
1860 }
1861
1862 func TestGoEnv(t *testing.T) {
1863 tg := testgo(t)
1864 tg.parallel()
1865 defer tg.cleanup()
1866 tg.setenv("GOOS", "freebsd")
1867 tg.setenv("GOARCH", "arm")
1868 tg.run("env", "GOARCH")
1869 tg.grepStdout("^arm$", "GOARCH not honored")
1870
1871 tg.run("env", "GCCGO")
1872 tg.grepStdout(".", "GCCGO unexpectedly empty")
1873
1874 tg.run("env", "CGO_CFLAGS")
1875 tg.grepStdout(".", "default CGO_CFLAGS unexpectedly empty")
1876
1877 tg.setenv("CGO_CFLAGS", "-foobar")
1878 tg.run("env", "CGO_CFLAGS")
1879 tg.grepStdout("^-foobar$", "CGO_CFLAGS not honored")
1880
1881 tg.setenv("CC", "gcc -fmust -fgo -ffaster")
1882 tg.run("env", "CC")
1883 tg.grepStdout("gcc", "CC not found")
1884 tg.run("env", "GOGCCFLAGS")
1885 tg.grepStdout("-ffaster", "CC arguments not found")
1886
1887 tg.run("env", "GOVERSION")
1888 envVersion := strings.TrimSpace(tg.stdout.String())
1889
1890 tg.run("version")
1891 cmdVersion := strings.TrimSpace(tg.stdout.String())
1892
1893
1894
1895 if cmdVersion == envVersion || !strings.Contains(cmdVersion, envVersion) {
1896 t.Fatalf("'go env GOVERSION' %q should be a shorter substring of 'go version' %q", envVersion, cmdVersion)
1897 }
1898 }
1899
1900 const (
1901 noMatchesPattern = `(?m)^ok.*\[no tests to run\]`
1902 okPattern = `(?m)^ok`
1903 )
1904
1905
1906 func TestLdBindNow(t *testing.T) {
1907 tg := testgo(t)
1908 defer tg.cleanup()
1909 tg.parallel()
1910 tg.setenv("LD_BIND_NOW", "1")
1911 tg.run("help")
1912 }
1913
1914
1915
1916 func TestConcurrentAsm(t *testing.T) {
1917 skipIfGccgo(t, "gccgo does not use cmd/asm")
1918 tg := testgo(t)
1919 defer tg.cleanup()
1920 tg.parallel()
1921 asm := `DATA ·constants<>+0x0(SB)/8,$0
1922 GLOBL ·constants<>(SB),8,$8
1923 `
1924 tg.tempFile("go/src/p/a.s", asm)
1925 tg.tempFile("go/src/p/b.s", asm)
1926 tg.tempFile("go/src/p/p.go", `package p`)
1927 tg.setenv("GOPATH", tg.path("go"))
1928 tg.run("build", "p")
1929 }
1930
1931
1932 func TestFFLAGS(t *testing.T) {
1933 testenv.MustHaveCGO(t)
1934
1935 tg := testgo(t)
1936 defer tg.cleanup()
1937 tg.parallel()
1938
1939 tg.tempFile("p/src/p/main.go", `package main
1940 // #cgo FFLAGS: -no-such-fortran-flag
1941 import "C"
1942 func main() {}
1943 `)
1944 tg.tempFile("p/src/p/a.f", `! comment`)
1945 tg.setenv("GOPATH", tg.path("p"))
1946
1947
1948
1949
1950 tg.doRun([]string{"build", "-x", "p"})
1951
1952 tg.grepStderr("no-such-fortran-flag", `missing expected "-no-such-fortran-flag"`)
1953 }
1954
1955
1956
1957 func TestDuplicateGlobalAsmSymbols(t *testing.T) {
1958 skipIfGccgo(t, "gccgo does not use cmd/asm")
1959 tooSlow(t, "links a binary with cgo dependencies")
1960 if runtime.GOARCH != "386" && runtime.GOARCH != "amd64" {
1961 t.Skipf("skipping test on %s", runtime.GOARCH)
1962 }
1963 testenv.MustHaveCGO(t)
1964
1965 tg := testgo(t)
1966 defer tg.cleanup()
1967 tg.parallel()
1968
1969 asm := `
1970 #include "textflag.h"
1971
1972 DATA sym<>+0x0(SB)/8,$0
1973 GLOBL sym<>(SB),(NOPTR+RODATA),$8
1974
1975 TEXT ·Data(SB),NOSPLIT,$0
1976 MOVB sym<>(SB), AX
1977 MOVB AX, ret+0(FP)
1978 RET
1979 `
1980 tg.tempFile("go/src/a/a.s", asm)
1981 tg.tempFile("go/src/a/a.go", `package a; func Data() uint8`)
1982 tg.tempFile("go/src/b/b.s", asm)
1983 tg.tempFile("go/src/b/b.go", `package b; func Data() uint8`)
1984 tg.tempFile("go/src/p/p.go", `
1985 package main
1986 import "a"
1987 import "b"
1988 import "C"
1989 func main() {
1990 _ = a.Data() + b.Data()
1991 }
1992 `)
1993 tg.setenv("GOPATH", tg.path("go"))
1994 exe := tg.path("p.exe")
1995 tg.creatingTemp(exe)
1996 tg.run("build", "-o", exe, "p")
1997 }
1998
1999 func copyFile(src, dst string, perm fs.FileMode) error {
2000 sf, err := os.Open(src)
2001 if err != nil {
2002 return err
2003 }
2004 defer sf.Close()
2005
2006 df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
2007 if err != nil {
2008 return err
2009 }
2010
2011 _, err = io.Copy(df, sf)
2012 err2 := df.Close()
2013 if err != nil {
2014 return err
2015 }
2016 return err2
2017 }
2018
2019 func TestNeedVersion(t *testing.T) {
2020 skipIfGccgo(t, "gccgo does not use cmd/compile")
2021 tg := testgo(t)
2022 defer tg.cleanup()
2023 tg.parallel()
2024 tg.tempFile("goversion.go", `package main; func main() {}`)
2025 path := tg.path("goversion.go")
2026 tg.setenv("TESTGO_TOOLCHAIN_VERSION", "go1.testgo")
2027 tg.runFail("run", path)
2028 tg.grepStderr("compile", "does not match go tool version")
2029 }
2030
2031 func TestBuildmodePIE(t *testing.T) {
2032 tooSlow(t, "links binaries")
2033
2034 if !platform.BuildModeSupported(runtime.Compiler, "pie", runtime.GOOS, runtime.GOARCH) {
2035 t.Skipf("skipping test because buildmode=pie is not supported on %s/%s", runtime.GOOS, runtime.GOARCH)
2036 }
2037
2038 if strings.HasSuffix(testenv.Builder(), "-alpine") {
2039 t.Skip("skipping PIE tests on alpine; see https://go.dev/issues/54354")
2040 }
2041 t.Run("non-cgo", func(t *testing.T) {
2042 testBuildmodePIE(t, false, true)
2043 })
2044 t.Run("cgo", func(t *testing.T) {
2045 testenv.MustHaveCGO(t)
2046 testBuildmodePIE(t, true, true)
2047 })
2048 }
2049
2050 func TestWindowsDefaultBuildmodIsPIE(t *testing.T) {
2051 if runtime.GOOS != "windows" {
2052 t.Skip("skipping windows only test")
2053 }
2054 tooSlow(t, "links binaries")
2055
2056 t.Run("non-cgo", func(t *testing.T) {
2057 testBuildmodePIE(t, false, false)
2058 })
2059 t.Run("cgo", func(t *testing.T) {
2060 testenv.MustHaveCGO(t)
2061 testBuildmodePIE(t, true, false)
2062 })
2063 }
2064
2065 func testBuildmodePIE(t *testing.T, useCgo, setBuildmodeToPIE bool) {
2066 tg := testgo(t)
2067 defer tg.cleanup()
2068 tg.parallel()
2069
2070 var s string
2071 if useCgo {
2072 s = `import "C";`
2073 }
2074 tg.tempFile("main.go", fmt.Sprintf(`package main;%s func main() { print("hello") }`, s))
2075 src := tg.path("main.go")
2076 obj := tg.path("main.exe")
2077 args := []string{"build"}
2078 if setBuildmodeToPIE {
2079 args = append(args, "-buildmode=pie")
2080 }
2081 args = append(args, "-o", obj, src)
2082 tg.run(args...)
2083
2084 switch runtime.GOOS {
2085 case "linux", "android", "freebsd":
2086 f, err := elf.Open(obj)
2087 if err != nil {
2088 t.Fatal(err)
2089 }
2090 defer f.Close()
2091 if f.Type != elf.ET_DYN {
2092 t.Errorf("PIE type must be ET_DYN, but %s", f.Type)
2093 }
2094 case "darwin", "ios":
2095 f, err := macho.Open(obj)
2096 if err != nil {
2097 t.Fatal(err)
2098 }
2099 defer f.Close()
2100 if f.Flags&macho.FlagDyldLink == 0 {
2101 t.Error("PIE must have DyldLink flag, but not")
2102 }
2103 if f.Flags&macho.FlagPIE == 0 {
2104 t.Error("PIE must have PIE flag, but not")
2105 }
2106 case "windows":
2107 f, err := pe.Open(obj)
2108 if err != nil {
2109 t.Fatal(err)
2110 }
2111 defer f.Close()
2112 if f.Section(".reloc") == nil {
2113 t.Error(".reloc section is not present")
2114 }
2115 if (f.FileHeader.Characteristics & pe.IMAGE_FILE_RELOCS_STRIPPED) != 0 {
2116 t.Error("IMAGE_FILE_RELOCS_STRIPPED flag is set")
2117 }
2118 var dc uint16
2119 switch oh := f.OptionalHeader.(type) {
2120 case *pe.OptionalHeader32:
2121 dc = oh.DllCharacteristics
2122 case *pe.OptionalHeader64:
2123 dc = oh.DllCharacteristics
2124 if (dc & pe.IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA) == 0 {
2125 t.Error("IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA flag is not set")
2126 }
2127 default:
2128 t.Fatalf("unexpected optional header type of %T", f.OptionalHeader)
2129 }
2130 if (dc & pe.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) == 0 {
2131 t.Error("IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE flag is not set")
2132 }
2133 default:
2134
2135
2136 t.Skipf("skipping test: test helper does not support %s", runtime.GOOS)
2137 }
2138
2139 out, err := testenv.Command(t, obj).CombinedOutput()
2140 if err != nil {
2141 t.Fatal(err)
2142 }
2143
2144 if string(out) != "hello" {
2145 t.Errorf("got %q; want %q", out, "hello")
2146 }
2147 }
2148
2149 func TestUpxCompression(t *testing.T) {
2150 if runtime.GOOS != "linux" ||
2151 (runtime.GOARCH != "amd64" && runtime.GOARCH != "386") {
2152 t.Skipf("skipping upx test on %s/%s", runtime.GOOS, runtime.GOARCH)
2153 }
2154
2155 testenv.MustHaveExecPath(t, "upx")
2156 out, err := testenv.Command(t, "upx", "--version").CombinedOutput()
2157 if err != nil {
2158 t.Fatalf("upx --version failed: %v", err)
2159 }
2160
2161
2162
2163
2164 re := regexp.MustCompile(`([[:digit:]]+)\.([[:digit:]]+)`)
2165 upxVersion := re.FindStringSubmatch(string(out))
2166 if len(upxVersion) != 3 {
2167 t.Fatalf("bad upx version string: %s", upxVersion)
2168 }
2169
2170 major, err1 := strconv.Atoi(upxVersion[1])
2171 minor, err2 := strconv.Atoi(upxVersion[2])
2172 if err1 != nil || err2 != nil {
2173 t.Fatalf("bad upx version string: %s", upxVersion[0])
2174 }
2175
2176
2177 if (major < 3) || (major == 3 && minor < 94) {
2178 t.Skipf("skipping because upx version %v.%v is too old", major, minor)
2179 }
2180
2181 tg := testgo(t)
2182 defer tg.cleanup()
2183 tg.parallel()
2184
2185 tg.tempFile("main.go", `package main; import "fmt"; func main() { fmt.Print("hello upx") }`)
2186 src := tg.path("main.go")
2187 obj := tg.path("main")
2188 tg.run("build", "-o", obj, src)
2189
2190 out, err = testenv.Command(t, "upx", obj).CombinedOutput()
2191 if err != nil {
2192 t.Logf("executing upx\n%s\n", out)
2193 t.Fatalf("upx failed with %v", err)
2194 }
2195
2196 out, err = testenv.Command(t, obj).CombinedOutput()
2197 if err != nil {
2198 t.Logf("%s", out)
2199 t.Fatalf("running compressed go binary failed with error %s", err)
2200 }
2201 if string(out) != "hello upx" {
2202 t.Fatalf("bad output from compressed go binary:\ngot %q; want %q", out, "hello upx")
2203 }
2204 }
2205
2206 var gocacheverify = godebug.New("#gocacheverify")
2207
2208 func TestCacheListStale(t *testing.T) {
2209 tooSlow(t, "links a binary")
2210 if gocacheverify.Value() == "1" {
2211 t.Skip("GODEBUG gocacheverify")
2212 }
2213
2214 tg := testgo(t)
2215 defer tg.cleanup()
2216 tg.parallel()
2217 tg.makeTempdir()
2218 tg.setenv("GOCACHE", tg.path("cache"))
2219 tg.tempFile("gopath/src/p/p.go", "package p; import _ \"q\"; func F(){}\n")
2220 tg.tempFile("gopath/src/q/q.go", "package q; func F(){}\n")
2221 tg.tempFile("gopath/src/m/m.go", "package main; import _ \"q\"; func main(){}\n")
2222
2223 tg.setenv("GOPATH", tg.path("gopath"))
2224 tg.run("install", "p", "m")
2225 tg.run("list", "-f={{.ImportPath}} {{.Stale}}", "m", "q", "p")
2226 tg.grepStdout("^m false", "m should not be stale")
2227 tg.grepStdout("^q true", "q should be stale")
2228 tg.grepStdout("^p false", "p should not be stale")
2229 }
2230
2231 func TestCacheCoverage(t *testing.T) {
2232 tooSlow(t, "links and runs a test binary with coverage enabled")
2233 if gocacheverify.Value() == "1" {
2234 t.Skip("GODEBUG gocacheverify")
2235 }
2236
2237 tg := testgo(t)
2238 defer tg.cleanup()
2239 tg.parallel()
2240 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
2241 tg.makeTempdir()
2242
2243 tg.setenv("GOCACHE", tg.path("c1"))
2244 tg.run("test", "-cover", "-short", "strings")
2245 tg.run("test", "-cover", "-short", "math", "strings")
2246 }
2247
2248 func TestIssue22588(t *testing.T) {
2249
2250 tg := testgo(t)
2251 defer tg.cleanup()
2252 tg.parallel()
2253
2254 tg.wantNotStale("runtime", "", "must be non-stale to compare staleness under -toolexec")
2255
2256 if _, err := os.Stat("/usr/bin/time"); err != nil {
2257 t.Skip(err)
2258 }
2259
2260 tg.run("list", "-f={{.Stale}}", "runtime")
2261 tg.run("list", "-toolexec=/usr/bin/time", "-f={{.Stale}}", "runtime")
2262 tg.grepStdout("false", "incorrectly reported runtime as stale")
2263 }
2264
2265 func TestIssue22531(t *testing.T) {
2266 tooSlow(t, "links binaries")
2267 if gocacheverify.Value() == "1" {
2268 t.Skip("GODEBUG gocacheverify")
2269 }
2270
2271 tg := testgo(t)
2272 defer tg.cleanup()
2273 tg.parallel()
2274 tg.makeTempdir()
2275 tg.setenv("GOPATH", tg.tempdir)
2276 tg.setenv("GOCACHE", tg.path("cache"))
2277 tg.tempFile("src/m/main.go", "package main /* c1 */; func main() {}\n")
2278 tg.run("install", "-x", "m")
2279 tg.run("list", "-f", "{{.Stale}}", "m")
2280 tg.grepStdout("false", "reported m as stale after install")
2281 tg.run("tool", "buildid", tg.path("bin/m"+exeSuffix))
2282
2283
2284
2285
2286
2287
2288 tg.tempFile("src/m/main.go", "package main /* c2 */; func main() {}\n")
2289 tg.run("install", "-x", "m")
2290 tg.run("list", "-f", "{{.Stale}}", "m")
2291 tg.grepStdout("false", "reported m as stale after reinstall")
2292 tg.run("tool", "buildid", tg.path("bin/m"+exeSuffix))
2293 }
2294
2295 func TestIssue22596(t *testing.T) {
2296 tooSlow(t, "links binaries")
2297 if gocacheverify.Value() == "1" {
2298 t.Skip("GODEBUG gocacheverify")
2299 }
2300
2301 tg := testgo(t)
2302 defer tg.cleanup()
2303 tg.parallel()
2304 tg.makeTempdir()
2305 tg.setenv("GOCACHE", tg.path("cache"))
2306 tg.tempFile("gopath1/src/p/p.go", "package p; func F(){}\n")
2307 tg.tempFile("gopath2/src/p/p.go", "package p; func F(){}\n")
2308
2309 tg.setenv("GOPATH", tg.path("gopath1"))
2310 tg.run("list", "-f={{.Target}}", "p")
2311 target1 := strings.TrimSpace(tg.getStdout())
2312 tg.run("install", "p")
2313 tg.wantNotStale("p", "", "p stale after install")
2314
2315 tg.setenv("GOPATH", tg.path("gopath2"))
2316 tg.run("list", "-f={{.Target}}", "p")
2317 target2 := strings.TrimSpace(tg.getStdout())
2318 tg.must(os.MkdirAll(filepath.Dir(target2), 0777))
2319 tg.must(copyFile(target1, target2, 0666))
2320 tg.wantStale("p", "build ID mismatch", "p not stale after copy from gopath1")
2321 tg.run("install", "p")
2322 tg.wantNotStale("p", "", "p stale after install2")
2323 }
2324
2325 func TestTestCache(t *testing.T) {
2326 tooSlow(t, "links and runs test binaries")
2327 if gocacheverify.Value() == "1" {
2328 t.Skip("GODEBUG gocacheverify")
2329 }
2330
2331 tg := testgo(t)
2332 defer tg.cleanup()
2333 tg.parallel()
2334 tg.makeTempdir()
2335 tg.setenv("GOPATH", tg.tempdir)
2336 tg.setenv("GOCACHE", tg.path("cache"))
2337
2338
2339
2340 t.Log("\n\nINITIAL\n\n")
2341
2342 tg.tempFile("src/p1/p1.go", "package p1\nvar X = 1\n")
2343 tg.tempFile("src/p2/p2.go", "package p2\nimport _ \"p1\"\nvar X = 1\n")
2344 tg.tempFile("src/t/t1/t1_test.go", "package t\nimport \"testing\"\nfunc Test1(*testing.T) {}\n")
2345 tg.tempFile("src/t/t2/t2_test.go", "package t\nimport _ \"p1\"\nimport \"testing\"\nfunc Test2(*testing.T) {}\n")
2346 tg.tempFile("src/t/t3/t3_test.go", "package t\nimport \"p1\"\nimport \"testing\"\nfunc Test3(t *testing.T) {t.Log(p1.X)}\n")
2347 tg.tempFile("src/t/t4/t4_test.go", "package t\nimport \"p2\"\nimport \"testing\"\nfunc Test4(t *testing.T) {t.Log(p2.X)}")
2348 tg.run("test", "-x", "-v", "-short", "t/...")
2349
2350 t.Log("\n\nREPEAT\n\n")
2351
2352 tg.run("test", "-x", "-v", "-short", "t/...")
2353 tg.grepStdout(`ok \tt/t1\t\(cached\)`, "did not cache t1")
2354 tg.grepStdout(`ok \tt/t2\t\(cached\)`, "did not cache t2")
2355 tg.grepStdout(`ok \tt/t3\t\(cached\)`, "did not cache t3")
2356 tg.grepStdout(`ok \tt/t4\t\(cached\)`, "did not cache t4")
2357 tg.grepStderrNot(`[\\/](compile|gccgo) `, "incorrectly ran compiler")
2358 tg.grepStderrNot(`[\\/](link|gccgo) `, "incorrectly ran linker")
2359 tg.grepStderrNot(`p[0-9]\.test`, "incorrectly ran test")
2360
2361 t.Log("\n\nCOMMENT\n\n")
2362
2363
2364
2365 tg.tempFile("src/p1/p1.go", "package p1\nvar X = 01\n")
2366 tg.run("test", "-p=1", "-x", "-v", "-short", "t/...")
2367 tg.grepStdout(`ok \tt/t1\t\(cached\)`, "did not cache t1")
2368 tg.grepStdout(`ok \tt/t2\t\(cached\)`, "did not cache t2")
2369 tg.grepStdout(`ok \tt/t3\t\(cached\)`, "did not cache t3")
2370 tg.grepStdout(`ok \tt/t4\t\(cached\)`, "did not cache t4")
2371 tg.grepStderrNot(`([\\/](compile|gccgo) ).*t[0-9]_test\.go`, "incorrectly ran compiler")
2372 tg.grepStderrNot(`[\\/](link|gccgo) `, "incorrectly ran linker")
2373 tg.grepStderrNot(`t[0-9]\.test.*test\.short`, "incorrectly ran test")
2374
2375 t.Log("\n\nCHANGE\n\n")
2376
2377
2378 tg.tempFile("src/p1/p1.go", "package p1\nvar X = 02\n")
2379 tg.run("test", "-p=1", "-x", "-v", "-short", "t/...")
2380
2381
2382 tg.grepStderr(`([\\/]compile|gccgo).*p2.go`, "did not recompile p2")
2383
2384
2385 tg.grepStderrNot(`([\\/]compile|gccgo).*t1_test.go`, "incorrectly recompiled t1")
2386 tg.grepStderrNot(`([\\/]link|gccgo).*t1_test`, "incorrectly relinked t1_test")
2387 tg.grepStdout(`ok \tt/t1\t\(cached\)`, "did not cache t/t1")
2388
2389
2390
2391
2392 tg.grepStderr(`([\\/]compile|gccgo).*t2_test.go`, "did not recompile t2")
2393 tg.grepStderr(`([\\/]link|gccgo).*t2\.test`, "did not relink t2_test")
2394
2395
2396 if runtime.Compiler != "gccgo" {
2397 tg.grepStdout(`ok \tt/t2\t\(cached\)`, "did not cache t/t2")
2398 }
2399
2400
2401 tg.grepStderr(`([\\/]compile|gccgo).*t3_test.go`, "did not recompile t3")
2402 tg.grepStderr(`([\\/]link|gccgo).*t3\.test`, "did not relink t3_test")
2403 tg.grepStderr(`t3\.test.*-test.short`, "did not rerun t3_test")
2404 tg.grepStdoutNot(`ok \tt/t3\t\(cached\)`, "reported cached t3_test result")
2405
2406
2407
2408 tg.grepStderrNot(`([\\/]compile|gccgo).*t4_test.go`, "incorrectly recompiled t4")
2409 tg.grepStderr(`([\\/]link|gccgo).*t4\.test`, "did not relink t4_test")
2410
2411
2412 if runtime.Compiler != "gccgo" {
2413 tg.grepStdout(`ok \tt/t4\t\(cached\)`, "did not cache t/t4")
2414 }
2415 }
2416
2417 func TestTestSkipVetAfterFailedBuild(t *testing.T) {
2418 tg := testgo(t)
2419 defer tg.cleanup()
2420 tg.parallel()
2421
2422 tg.tempFile("x_test.go", `package x
2423 func f() {
2424 return 1
2425 }
2426 `)
2427
2428 tg.runFail("test", tg.path("x_test.go"))
2429 tg.grepStderrNot(`vet`, "vet should be skipped after the failed build")
2430 }
2431
2432 func TestTestVetRebuild(t *testing.T) {
2433 tooSlow(t, "links and runs test binaries")
2434
2435 tg := testgo(t)
2436 defer tg.cleanup()
2437 tg.parallel()
2438
2439
2440
2441
2442
2443 tg.tempFile("src/a/a.go", `package a
2444 import "b"
2445 type Type struct{}
2446 func (*Type) M() b.T {return 0}
2447 `)
2448 tg.tempFile("src/b/b.go", `package b
2449 type T int
2450 type I interface {M() T}
2451 `)
2452 tg.tempFile("src/b/export_test.go", `package b
2453 func (*T) Method() *T { return nil }
2454 `)
2455 tg.tempFile("src/b/b_test.go", `package b_test
2456 import (
2457 "testing"
2458 "a"
2459 . "b"
2460 )
2461 func TestBroken(t *testing.T) {
2462 x := new(T)
2463 x.Method()
2464 _ = new(a.Type)
2465 }
2466 `)
2467
2468 tg.setenv("GOPATH", tg.path("."))
2469 tg.run("test", "b")
2470 tg.run("vet", "b")
2471 }
2472
2473 func TestInstallDeps(t *testing.T) {
2474 tooSlow(t, "links a binary")
2475
2476 tg := testgo(t)
2477 defer tg.cleanup()
2478 tg.parallel()
2479 tg.makeTempdir()
2480 tg.setenv("GOPATH", tg.tempdir)
2481
2482 tg.tempFile("src/p1/p1.go", "package p1\nvar X = 1\n")
2483 tg.tempFile("src/p2/p2.go", "package p2\nimport _ \"p1\"\n")
2484 tg.tempFile("src/main1/main.go", "package main\nimport _ \"p2\"\nfunc main() {}\n")
2485
2486 tg.run("list", "-f={{.Target}}", "p1")
2487 p1 := strings.TrimSpace(tg.getStdout())
2488 tg.run("list", "-f={{.Target}}", "p2")
2489 p2 := strings.TrimSpace(tg.getStdout())
2490 tg.run("list", "-f={{.Target}}", "main1")
2491 main1 := strings.TrimSpace(tg.getStdout())
2492
2493 tg.run("install", "main1")
2494
2495 tg.mustExist(main1)
2496 tg.mustNotExist(p2)
2497 tg.mustNotExist(p1)
2498
2499 tg.run("install", "p2")
2500 tg.mustExist(p2)
2501 tg.mustNotExist(p1)
2502 }
2503
2504
2505 func TestImportPath(t *testing.T) {
2506 tooSlow(t, "links and runs a test binary")
2507
2508 tg := testgo(t)
2509 defer tg.cleanup()
2510 tg.parallel()
2511
2512 tg.tempFile("src/a/a.go", `
2513 package main
2514
2515 import (
2516 "log"
2517 p "a/p-1.0"
2518 )
2519
2520 func main() {
2521 if !p.V {
2522 log.Fatal("false")
2523 }
2524 }`)
2525
2526 tg.tempFile("src/a/a_test.go", `
2527 package main_test
2528
2529 import (
2530 p "a/p-1.0"
2531 "testing"
2532 )
2533
2534 func TestV(t *testing.T) {
2535 if !p.V {
2536 t.Fatal("false")
2537 }
2538 }`)
2539
2540 tg.tempFile("src/a/p-1.0/p.go", `
2541 package p
2542
2543 var V = true
2544
2545 func init() {}
2546 `)
2547
2548 tg.setenv("GOPATH", tg.path("."))
2549 tg.run("build", "-o", tg.path("a.exe"), "a")
2550 tg.run("test", "a")
2551 }
2552
2553 func TestBadCommandLines(t *testing.T) {
2554 tg := testgo(t)
2555 defer tg.cleanup()
2556 tg.parallel()
2557
2558 tg.tempFile("src/x/x.go", "package x\n")
2559 tg.setenv("GOPATH", tg.path("."))
2560
2561 tg.run("build", "x")
2562
2563 tg.tempFile("src/x/@y.go", "package x\n")
2564 tg.runFail("build", "x")
2565 tg.grepStderr("invalid input file name \"@y.go\"", "did not reject @y.go")
2566 tg.must(os.Remove(tg.path("src/x/@y.go")))
2567
2568 tg.tempFile("src/x/-y.go", "package x\n")
2569 tg.runFail("build", "x")
2570 tg.grepStderr("invalid input file name \"-y.go\"", "did not reject -y.go")
2571 tg.must(os.Remove(tg.path("src/x/-y.go")))
2572
2573 if runtime.Compiler == "gccgo" {
2574 tg.runFail("build", "-gccgoflags=all=@x", "x")
2575 } else {
2576 tg.runFail("build", "-gcflags=all=@x", "x")
2577 }
2578 tg.grepStderr("invalid command-line argument @x in command", "did not reject @x during exec")
2579
2580 tg.tempFile("src/@x/x.go", "package x\n")
2581 tg.setenv("GOPATH", tg.path("."))
2582 tg.runFail("build", "@x")
2583 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")
2584
2585 tg.tempFile("src/@x/y/y.go", "package y\n")
2586 tg.setenv("GOPATH", tg.path("."))
2587 tg.runFail("build", "@x/y")
2588 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")
2589
2590 tg.tempFile("src/-x/x.go", "package x\n")
2591 tg.setenv("GOPATH", tg.path("."))
2592 tg.runFail("build", "--", "-x")
2593 tg.grepStderr("invalid import path \"-x\"", "did not reject -x import path")
2594
2595 tg.tempFile("src/-x/y/y.go", "package y\n")
2596 tg.setenv("GOPATH", tg.path("."))
2597 tg.runFail("build", "--", "-x/y")
2598 tg.grepStderr("invalid import path \"-x/y\"", "did not reject -x/y import path")
2599 }
2600
2601 func TestTwoPkgConfigs(t *testing.T) {
2602 testenv.MustHaveCGO(t)
2603 if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
2604 t.Skipf("no shell scripts on %s", runtime.GOOS)
2605 }
2606 tooSlow(t, "builds a package with cgo dependencies")
2607
2608 tg := testgo(t)
2609 defer tg.cleanup()
2610 tg.parallel()
2611 tg.tempFile("src/x/a.go", `package x
2612 // #cgo pkg-config: --static a
2613 import "C"
2614 `)
2615 tg.tempFile("src/x/b.go", `package x
2616 // #cgo pkg-config: --static a
2617 import "C"
2618 `)
2619 tg.tempFile("pkg-config.sh", `#!/bin/sh
2620 echo $* >>`+tg.path("pkg-config.out"))
2621 tg.must(os.Chmod(tg.path("pkg-config.sh"), 0755))
2622 tg.setenv("GOPATH", tg.path("."))
2623 tg.setenv("PKG_CONFIG", tg.path("pkg-config.sh"))
2624 tg.run("build", "x")
2625 out, err := os.ReadFile(tg.path("pkg-config.out"))
2626 tg.must(err)
2627 out = bytes.TrimSpace(out)
2628 want := "--cflags --static --static -- a a\n--libs --static --static -- a a"
2629 if !bytes.Equal(out, []byte(want)) {
2630 t.Errorf("got %q want %q", out, want)
2631 }
2632 }
2633
2634 func TestCgoCache(t *testing.T) {
2635 testenv.MustHaveCGO(t)
2636 tooSlow(t, "builds a package with cgo dependencies")
2637
2638 tg := testgo(t)
2639 defer tg.cleanup()
2640 tg.parallel()
2641 tg.tempFile("src/x/a.go", `package main
2642 // #ifndef VAL
2643 // #define VAL 0
2644 // #endif
2645 // int val = VAL;
2646 import "C"
2647 import "fmt"
2648 func main() { fmt.Println(C.val) }
2649 `)
2650 tg.setenv("GOPATH", tg.path("."))
2651 exe := tg.path("x.exe")
2652 tg.run("build", "-o", exe, "x")
2653 tg.setenv("CGO_LDFLAGS", "-lnosuchlibraryexists")
2654 tg.runFail("build", "-o", exe, "x")
2655 tg.grepStderr(`nosuchlibraryexists`, "did not run linker with changed CGO_LDFLAGS")
2656 }
2657
2658
2659 func TestFilepathUnderCwdFormat(t *testing.T) {
2660 tg := testgo(t)
2661 defer tg.cleanup()
2662 tg.parallel()
2663 tg.run("test", "-x", "-cover", "log")
2664 tg.grepStderrNot(`\.log\.cover\.go`, "-x output should contain correctly formatted filepath under cwd")
2665 }
2666
2667
2668 func TestDontReportRemoveOfEmptyDir(t *testing.T) {
2669 tg := testgo(t)
2670 defer tg.cleanup()
2671 tg.parallel()
2672 tg.tempFile("src/a/a.go", `package a`)
2673 tg.setenv("GOPATH", tg.path("."))
2674 tg.run("install", "-x", "a")
2675 tg.run("install", "-x", "a")
2676
2677
2678 if bytes.Count(tg.stdout.Bytes(), []byte{'\n'})+bytes.Count(tg.stderr.Bytes(), []byte{'\n'}) > 1 {
2679 t.Error("unnecessary output when installing installed package")
2680 }
2681 }
2682
2683
2684 func TestLinkerTmpDirIsDeleted(t *testing.T) {
2685 skipIfGccgo(t, "gccgo does not use cmd/link")
2686 testenv.MustHaveCGO(t)
2687 tooSlow(t, "builds a package with cgo dependencies")
2688
2689 tg := testgo(t)
2690 defer tg.cleanup()
2691 tg.parallel()
2692 tg.tempFile("a.go", `package main; import "C"; func main() {}`)
2693 tg.run("build", "-ldflags", "-v", "-o", os.DevNull, tg.path("a.go"))
2694
2695 stderr := tg.getStderr()
2696 var hostLinkLine string
2697 for _, line := range strings.Split(stderr, "\n") {
2698 if !strings.Contains(line, "host link:") {
2699 continue
2700 }
2701 hostLinkLine = line
2702 break
2703 }
2704 if hostLinkLine == "" {
2705 t.Fatal(`fail to find with "host link:" string in linker output`)
2706 }
2707
2708
2709
2710 tmpdir := hostLinkLine
2711 i := strings.Index(tmpdir, `go.o"`)
2712 if i == -1 {
2713 t.Fatalf(`fail to find "go.o" in "host link:" line %q`, hostLinkLine)
2714 }
2715 tmpdir = tmpdir[:i-1]
2716 i = strings.LastIndex(tmpdir, `"`)
2717 if i == -1 {
2718 t.Fatalf(`fail to find " in "host link:" line %q`, hostLinkLine)
2719 }
2720 tmpdir = tmpdir[i+1:]
2721
2722 _, err := os.Stat(tmpdir)
2723 if err == nil {
2724 t.Fatalf("temp directory %q has not been removed", tmpdir)
2725 }
2726 if !os.IsNotExist(err) {
2727 t.Fatalf("Stat(%q) returns unexpected error: %v", tmpdir, err)
2728 }
2729 }
2730
2731
2732 func TestCoverpkgTestOnly(t *testing.T) {
2733 skipIfGccgo(t, "gccgo has no cover tool")
2734 tooSlow(t, "links and runs a test binary with coverage enabled")
2735
2736 tg := testgo(t)
2737 defer tg.cleanup()
2738 tg.parallel()
2739 tg.tempFile("src/a/a.go", `package a
2740 func F(i int) int {
2741 return i*i
2742 }`)
2743 tg.tempFile("src/atest/a_test.go", `
2744 package a_test
2745 import ( "a"; "testing" )
2746 func TestF(t *testing.T) { a.F(2) }
2747 `)
2748 tg.setenv("GOPATH", tg.path("."))
2749 tg.run("test", "-coverpkg=a", "atest")
2750 tg.grepStderrNot("no packages being tested depend on matches", "bad match message")
2751 tg.grepStdout("coverage: 100", "no coverage")
2752 }
2753
2754
2755
2756 func TestExecInDeletedDir(t *testing.T) {
2757 switch runtime.GOOS {
2758 case "windows", "plan9",
2759 "aix",
2760 "solaris", "illumos":
2761 t.Skipf("%v does not support removing the current working directory", runtime.GOOS)
2762 }
2763 tg := testgo(t)
2764 defer tg.cleanup()
2765
2766 tg.makeTempdir()
2767 t.Chdir(tg.tempdir)
2768
2769 tg.check(os.Remove(tg.tempdir))
2770
2771
2772 tg.run("version")
2773 }
2774
View as plain text