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