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