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