github.com/liujq9674git/golang-src-1.7@v0.0.0-20230517174348-17f6ec47f3f8/src/cmd/go/go_test.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package main_test 6 7 import ( 8 "bytes" 9 "flag" 10 "fmt" 11 "go/build" 12 "go/format" 13 "internal/race" 14 "internal/testenv" 15 "io" 16 "io/ioutil" 17 "os" 18 "os/exec" 19 "path/filepath" 20 "regexp" 21 "runtime" 22 "strconv" 23 "strings" 24 "testing" 25 "time" 26 ) 27 28 var ( 29 canRun = true // whether we can run go or ./testgo 30 canRace = false // whether we can run the race detector 31 canCgo = false // whether we can use cgo 32 33 exeSuffix string // ".exe" on Windows 34 35 skipExternal = false // skip external tests 36 ) 37 38 func init() { 39 switch runtime.GOOS { 40 case "android", "nacl": 41 canRun = false 42 case "darwin": 43 switch runtime.GOARCH { 44 case "arm", "arm64": 45 canRun = false 46 } 47 case "linux": 48 switch runtime.GOARCH { 49 case "arm": 50 // many linux/arm machines are too slow to run 51 // the full set of external tests. 52 skipExternal = true 53 } 54 case "freebsd": 55 switch runtime.GOARCH { 56 case "arm": 57 // many freebsd/arm machines are too slow to run 58 // the full set of external tests. 59 skipExternal = true 60 canRun = false 61 } 62 case "windows": 63 exeSuffix = ".exe" 64 } 65 } 66 67 // The TestMain function creates a go command for testing purposes and 68 // deletes it after the tests have been run. 69 func TestMain(m *testing.M) { 70 flag.Parse() 71 72 if canRun { 73 args := []string{"build", "-tags", "testgo", "-o", "testgo" + exeSuffix} 74 if race.Enabled { 75 args = append(args, "-race") 76 } 77 out, err := exec.Command("go", args...).CombinedOutput() 78 if err != nil { 79 fmt.Fprintf(os.Stderr, "building testgo failed: %v\n%s", err, out) 80 os.Exit(2) 81 } 82 83 if out, err := exec.Command("./testgo"+exeSuffix, "env", "CGO_ENABLED").Output(); err != nil { 84 fmt.Fprintf(os.Stderr, "running testgo failed: %v\n", err) 85 canRun = false 86 } else { 87 canCgo, err = strconv.ParseBool(strings.TrimSpace(string(out))) 88 if err != nil { 89 fmt.Fprintf(os.Stderr, "can't parse go env CGO_ENABLED output: %v\n", strings.TrimSpace(string(out))) 90 } 91 } 92 93 switch runtime.GOOS { 94 case "linux", "darwin", "freebsd", "windows": 95 canRace = canCgo && runtime.GOARCH == "amd64" 96 } 97 } 98 99 // Don't let these environment variables confuse the test. 100 os.Unsetenv("GOBIN") 101 os.Unsetenv("GOPATH") 102 103 r := m.Run() 104 105 if canRun { 106 os.Remove("testgo" + exeSuffix) 107 } 108 109 os.Exit(r) 110 } 111 112 // The length of an mtime tick on this system. This is an estimate of 113 // how long we need to sleep to ensure that the mtime of two files is 114 // different. 115 // We used to try to be clever but that didn't always work (see golang.org/issue/12205). 116 var mtimeTick time.Duration = 1 * time.Second 117 118 // Manage a single run of the testgo binary. 119 type testgoData struct { 120 t *testing.T 121 temps []string 122 wd string 123 env []string 124 tempdir string 125 ran bool 126 inParallel bool 127 stdout, stderr bytes.Buffer 128 } 129 130 // testgo sets up for a test that runs testgo. 131 func testgo(t *testing.T) *testgoData { 132 testenv.MustHaveGoBuild(t) 133 134 if skipExternal { 135 t.Skip("skipping external tests on %s/%s", runtime.GOOS, runtime.GOARCH) 136 } 137 138 return &testgoData{t: t} 139 } 140 141 // must gives a fatal error if err is not nil. 142 func (tg *testgoData) must(err error) { 143 if err != nil { 144 tg.t.Fatal(err) 145 } 146 } 147 148 // check gives a test non-fatal error if err is not nil. 149 func (tg *testgoData) check(err error) { 150 if err != nil { 151 tg.t.Error(err) 152 } 153 } 154 155 // parallel runs the test in parallel by calling t.Parallel. 156 func (tg *testgoData) parallel() { 157 if tg.ran { 158 tg.t.Fatal("internal testsuite error: call to parallel after run") 159 } 160 if tg.wd != "" { 161 tg.t.Fatal("internal testsuite error: call to parallel after cd") 162 } 163 for _, e := range tg.env { 164 if strings.HasPrefix(e, "GOROOT=") || strings.HasPrefix(e, "GOPATH=") || strings.HasPrefix(e, "GOBIN=") { 165 val := e[strings.Index(e, "=")+1:] 166 if strings.HasPrefix(val, "testdata") || strings.HasPrefix(val, "./testdata") { 167 tg.t.Fatalf("internal testsuite error: call to parallel with testdata in environment (%s)", e) 168 } 169 } 170 } 171 tg.inParallel = true 172 tg.t.Parallel() 173 } 174 175 // pwd returns the current directory. 176 func (tg *testgoData) pwd() string { 177 wd, err := os.Getwd() 178 if err != nil { 179 tg.t.Fatalf("could not get working directory: %v", err) 180 } 181 return wd 182 } 183 184 // cd changes the current directory to the named directory. Note that 185 // using this means that the test must not be run in parallel with any 186 // other tests. 187 func (tg *testgoData) cd(dir string) { 188 if tg.inParallel { 189 tg.t.Fatal("internal testsuite error: changing directory when running in parallel") 190 } 191 if tg.wd == "" { 192 tg.wd = tg.pwd() 193 } 194 abs, err := filepath.Abs(dir) 195 tg.must(os.Chdir(dir)) 196 if err == nil { 197 tg.setenv("PWD", abs) 198 } 199 } 200 201 // sleep sleeps for one tick, where a tick is a conservative estimate 202 // of how long it takes for a file modification to get a different 203 // mtime. 204 func (tg *testgoData) sleep() { 205 time.Sleep(mtimeTick) 206 } 207 208 // setenv sets an environment variable to use when running the test go 209 // command. 210 func (tg *testgoData) setenv(name, val string) { 211 if tg.inParallel && (name == "GOROOT" || name == "GOPATH" || name == "GOBIN") && (strings.HasPrefix(val, "testdata") || strings.HasPrefix(val, "./testdata")) { 212 tg.t.Fatalf("internal testsuite error: call to setenv with testdata (%s=%s) after parallel", name, val) 213 } 214 tg.unsetenv(name) 215 tg.env = append(tg.env, name+"="+val) 216 } 217 218 // unsetenv removes an environment variable. 219 func (tg *testgoData) unsetenv(name string) { 220 if tg.env == nil { 221 tg.env = append([]string(nil), os.Environ()...) 222 } 223 for i, v := range tg.env { 224 if strings.HasPrefix(v, name+"=") { 225 tg.env = append(tg.env[:i], tg.env[i+1:]...) 226 break 227 } 228 } 229 } 230 231 // doRun runs the test go command, recording stdout and stderr and 232 // returning exit status. 233 func (tg *testgoData) doRun(args []string) error { 234 if !canRun { 235 panic("testgoData.doRun called but canRun false") 236 } 237 if tg.inParallel { 238 for _, arg := range args { 239 if strings.HasPrefix(arg, "testdata") || strings.HasPrefix(arg, "./testdata") { 240 tg.t.Fatal("internal testsuite error: parallel run using testdata") 241 } 242 } 243 } 244 tg.t.Logf("running testgo %v", args) 245 var prog string 246 if tg.wd == "" { 247 prog = "./testgo" + exeSuffix 248 } else { 249 prog = filepath.Join(tg.wd, "testgo"+exeSuffix) 250 } 251 cmd := exec.Command(prog, args...) 252 tg.stdout.Reset() 253 tg.stderr.Reset() 254 cmd.Stdout = &tg.stdout 255 cmd.Stderr = &tg.stderr 256 cmd.Env = tg.env 257 status := cmd.Run() 258 if tg.stdout.Len() > 0 { 259 tg.t.Log("standard output:") 260 tg.t.Log(tg.stdout.String()) 261 } 262 if tg.stderr.Len() > 0 { 263 tg.t.Log("standard error:") 264 tg.t.Log(tg.stderr.String()) 265 } 266 tg.ran = true 267 return status 268 } 269 270 // run runs the test go command, and expects it to succeed. 271 func (tg *testgoData) run(args ...string) { 272 if status := tg.doRun(args); status != nil { 273 tg.t.Logf("go %v failed unexpectedly: %v", args, status) 274 tg.t.FailNow() 275 } 276 } 277 278 // runFail runs the test go command, and expects it to fail. 279 func (tg *testgoData) runFail(args ...string) { 280 if status := tg.doRun(args); status == nil { 281 tg.t.Fatal("testgo succeeded unexpectedly") 282 } else { 283 tg.t.Log("testgo failed as expected:", status) 284 } 285 } 286 287 // runGit runs a git command, and expects it to succeed. 288 func (tg *testgoData) runGit(dir string, args ...string) { 289 cmd := exec.Command("git", args...) 290 tg.stdout.Reset() 291 tg.stderr.Reset() 292 cmd.Stdout = &tg.stdout 293 cmd.Stderr = &tg.stderr 294 cmd.Dir = dir 295 cmd.Env = tg.env 296 status := cmd.Run() 297 if tg.stdout.Len() > 0 { 298 tg.t.Log("git standard output:") 299 tg.t.Log(tg.stdout.String()) 300 } 301 if tg.stderr.Len() > 0 { 302 tg.t.Log("git standard error:") 303 tg.t.Log(tg.stderr.String()) 304 } 305 if status != nil { 306 tg.t.Logf("git %v failed unexpectedly: %v", args, status) 307 tg.t.FailNow() 308 } 309 } 310 311 // getStdout returns standard output of the testgo run as a string. 312 func (tg *testgoData) getStdout() string { 313 if !tg.ran { 314 tg.t.Fatal("internal testsuite error: stdout called before run") 315 } 316 return tg.stdout.String() 317 } 318 319 // getStderr returns standard error of the testgo run as a string. 320 func (tg *testgoData) getStderr() string { 321 if !tg.ran { 322 tg.t.Fatal("internal testsuite error: stdout called before run") 323 } 324 return tg.stderr.String() 325 } 326 327 // doGrepMatch looks for a regular expression in a buffer, and returns 328 // whether it is found. The regular expression is matched against 329 // each line separately, as with the grep command. 330 func (tg *testgoData) doGrepMatch(match string, b *bytes.Buffer) bool { 331 if !tg.ran { 332 tg.t.Fatal("internal testsuite error: grep called before run") 333 } 334 re := regexp.MustCompile(match) 335 for _, ln := range bytes.Split(b.Bytes(), []byte{'\n'}) { 336 if re.Match(ln) { 337 return true 338 } 339 } 340 return false 341 } 342 343 // doGrep looks for a regular expression in a buffer and fails if it 344 // is not found. The name argument is the name of the output we are 345 // searching, "output" or "error". The msg argument is logged on 346 // failure. 347 func (tg *testgoData) doGrep(match string, b *bytes.Buffer, name, msg string) { 348 if !tg.doGrepMatch(match, b) { 349 tg.t.Log(msg) 350 tg.t.Logf("pattern %v not found in standard %s", match, name) 351 tg.t.FailNow() 352 } 353 } 354 355 // grepStdout looks for a regular expression in the test run's 356 // standard output and fails, logging msg, if it is not found. 357 func (tg *testgoData) grepStdout(match, msg string) { 358 tg.doGrep(match, &tg.stdout, "output", msg) 359 } 360 361 // grepStderr looks for a regular expression in the test run's 362 // standard error and fails, logging msg, if it is not found. 363 func (tg *testgoData) grepStderr(match, msg string) { 364 tg.doGrep(match, &tg.stderr, "error", msg) 365 } 366 367 // grepBoth looks for a regular expression in the test run's standard 368 // output or stand error and fails, logging msg, if it is not found. 369 func (tg *testgoData) grepBoth(match, msg string) { 370 if !tg.doGrepMatch(match, &tg.stdout) && !tg.doGrepMatch(match, &tg.stderr) { 371 tg.t.Log(msg) 372 tg.t.Logf("pattern %v not found in standard output or standard error", match) 373 tg.t.FailNow() 374 } 375 } 376 377 // doGrepNot looks for a regular expression in a buffer and fails if 378 // it is found. The name and msg arguments are as for doGrep. 379 func (tg *testgoData) doGrepNot(match string, b *bytes.Buffer, name, msg string) { 380 if tg.doGrepMatch(match, b) { 381 tg.t.Log(msg) 382 tg.t.Logf("pattern %v found unexpectedly in standard %s", match, name) 383 tg.t.FailNow() 384 } 385 } 386 387 // grepStdoutNot looks for a regular expression in the test run's 388 // standard output and fails, logging msg, if it is found. 389 func (tg *testgoData) grepStdoutNot(match, msg string) { 390 tg.doGrepNot(match, &tg.stdout, "output", msg) 391 } 392 393 // grepStderrNot looks for a regular expression in the test run's 394 // standard error and fails, logging msg, if it is found. 395 func (tg *testgoData) grepStderrNot(match, msg string) { 396 tg.doGrepNot(match, &tg.stderr, "error", msg) 397 } 398 399 // grepBothNot looks for a regular expression in the test run's 400 // standard output or stand error and fails, logging msg, if it is 401 // found. 402 func (tg *testgoData) grepBothNot(match, msg string) { 403 if tg.doGrepMatch(match, &tg.stdout) || tg.doGrepMatch(match, &tg.stderr) { 404 tg.t.Log(msg) 405 tg.t.Fatalf("pattern %v found unexpectedly in standard output or standard error", match) 406 } 407 } 408 409 // doGrepCount counts the number of times a regexp is seen in a buffer. 410 func (tg *testgoData) doGrepCount(match string, b *bytes.Buffer) int { 411 if !tg.ran { 412 tg.t.Fatal("internal testsuite error: doGrepCount called before run") 413 } 414 re := regexp.MustCompile(match) 415 c := 0 416 for _, ln := range bytes.Split(b.Bytes(), []byte{'\n'}) { 417 if re.Match(ln) { 418 c++ 419 } 420 } 421 return c 422 } 423 424 // grepCountBoth returns the number of times a regexp is seen in both 425 // standard output and standard error. 426 func (tg *testgoData) grepCountBoth(match string) int { 427 return tg.doGrepCount(match, &tg.stdout) + tg.doGrepCount(match, &tg.stderr) 428 } 429 430 // creatingTemp records that the test plans to create a temporary file 431 // or directory. If the file or directory exists already, it will be 432 // removed. When the test completes, the file or directory will be 433 // removed if it exists. 434 func (tg *testgoData) creatingTemp(path string) { 435 if filepath.IsAbs(path) && !strings.HasPrefix(path, tg.tempdir) { 436 tg.t.Fatalf("internal testsuite error: creatingTemp(%q) with absolute path not in temporary directory", path) 437 } 438 // If we have changed the working directory, make sure we have 439 // an absolute path, because we are going to change directory 440 // back before we remove the temporary. 441 if tg.wd != "" && !filepath.IsAbs(path) { 442 path = filepath.Join(tg.pwd(), path) 443 } 444 tg.must(os.RemoveAll(path)) 445 tg.temps = append(tg.temps, path) 446 } 447 448 // makeTempdir makes a temporary directory for a run of testgo. If 449 // the temporary directory was already created, this does nothing. 450 func (tg *testgoData) makeTempdir() { 451 if tg.tempdir == "" { 452 var err error 453 tg.tempdir, err = ioutil.TempDir("", "gotest") 454 tg.must(err) 455 } 456 } 457 458 // tempFile adds a temporary file for a run of testgo. 459 func (tg *testgoData) tempFile(path, contents string) { 460 tg.makeTempdir() 461 tg.must(os.MkdirAll(filepath.Join(tg.tempdir, filepath.Dir(path)), 0755)) 462 bytes := []byte(contents) 463 if strings.HasSuffix(path, ".go") { 464 formatted, err := format.Source(bytes) 465 if err == nil { 466 bytes = formatted 467 } 468 } 469 tg.must(ioutil.WriteFile(filepath.Join(tg.tempdir, path), bytes, 0644)) 470 } 471 472 // tempDir adds a temporary directory for a run of testgo. 473 func (tg *testgoData) tempDir(path string) { 474 tg.makeTempdir() 475 if err := os.MkdirAll(filepath.Join(tg.tempdir, path), 0755); err != nil && !os.IsExist(err) { 476 tg.t.Fatal(err) 477 } 478 } 479 480 // path returns the absolute pathname to file with the temporary 481 // directory. 482 func (tg *testgoData) path(name string) string { 483 if tg.tempdir == "" { 484 tg.t.Fatalf("internal testsuite error: path(%q) with no tempdir", name) 485 } 486 if name == "." { 487 return tg.tempdir 488 } 489 return filepath.Join(tg.tempdir, name) 490 } 491 492 // mustExist fails if path does not exist. 493 func (tg *testgoData) mustExist(path string) { 494 if _, err := os.Stat(path); err != nil { 495 if os.IsNotExist(err) { 496 tg.t.Fatalf("%s does not exist but should", path) 497 } 498 tg.t.Fatalf("%s stat failed: %v", path, err) 499 } 500 } 501 502 // mustNotExist fails if path exists. 503 func (tg *testgoData) mustNotExist(path string) { 504 if _, err := os.Stat(path); err == nil || !os.IsNotExist(err) { 505 tg.t.Fatalf("%s exists but should not (%v)", path, err) 506 } 507 } 508 509 // wantExecutable fails with msg if path is not executable. 510 func (tg *testgoData) wantExecutable(path, msg string) { 511 if st, err := os.Stat(path); err != nil { 512 if !os.IsNotExist(err) { 513 tg.t.Log(err) 514 } 515 tg.t.Fatal(msg) 516 } else { 517 if runtime.GOOS != "windows" && st.Mode()&0111 == 0 { 518 tg.t.Fatalf("binary %s exists but is not executable", path) 519 } 520 } 521 } 522 523 // wantArchive fails if path is not an archive. 524 func (tg *testgoData) wantArchive(path string) { 525 f, err := os.Open(path) 526 if err != nil { 527 tg.t.Fatal(err) 528 } 529 buf := make([]byte, 100) 530 io.ReadFull(f, buf) 531 f.Close() 532 if !bytes.HasPrefix(buf, []byte("!<arch>\n")) { 533 tg.t.Fatalf("file %s exists but is not an archive", path) 534 } 535 } 536 537 // isStale reports whether pkg is stale, and why 538 func (tg *testgoData) isStale(pkg string) (bool, string) { 539 tg.run("list", "-f", "{{.Stale}}:{{.StaleReason}}", pkg) 540 v := strings.TrimSpace(tg.getStdout()) 541 f := strings.SplitN(v, ":", 2) 542 if len(f) == 2 { 543 switch f[0] { 544 case "true": 545 return true, f[1] 546 case "false": 547 return false, f[1] 548 } 549 } 550 tg.t.Fatalf("unexpected output checking staleness of package %v: %v", pkg, v) 551 panic("unreachable") 552 } 553 554 // wantStale fails with msg if pkg is not stale. 555 func (tg *testgoData) wantStale(pkg, reason, msg string) { 556 stale, why := tg.isStale(pkg) 557 if !stale { 558 tg.t.Fatal(msg) 559 } 560 if reason == "" && why != "" || !strings.Contains(why, reason) { 561 tg.t.Errorf("wrong reason for Stale=true: %q, want %q", why, reason) 562 } 563 } 564 565 // wantNotStale fails with msg if pkg is stale. 566 func (tg *testgoData) wantNotStale(pkg, reason, msg string) { 567 stale, why := tg.isStale(pkg) 568 if stale { 569 tg.t.Fatal(msg) 570 } 571 if reason == "" && why != "" || !strings.Contains(why, reason) { 572 tg.t.Errorf("wrong reason for Stale=false: %q, want %q", why, reason) 573 } 574 } 575 576 // cleanup cleans up a test that runs testgo. 577 func (tg *testgoData) cleanup() { 578 if tg.wd != "" { 579 if err := os.Chdir(tg.wd); err != nil { 580 // We are unlikely to be able to continue. 581 fmt.Fprintln(os.Stderr, "could not restore working directory, crashing:", err) 582 os.Exit(2) 583 } 584 } 585 for _, path := range tg.temps { 586 tg.check(os.RemoveAll(path)) 587 } 588 if tg.tempdir != "" { 589 tg.check(os.RemoveAll(tg.tempdir)) 590 } 591 } 592 593 // failSSH puts an ssh executable in the PATH that always fails. 594 // This is to stub out uses of ssh by go get. 595 func (tg *testgoData) failSSH() { 596 wd, err := os.Getwd() 597 if err != nil { 598 tg.t.Fatal(err) 599 } 600 fail := filepath.Join(wd, "testdata/failssh") 601 tg.setenv("PATH", fmt.Sprintf("%v%c%v", fail, filepath.ListSeparator, os.Getenv("PATH"))) 602 } 603 604 func TestFileLineInErrorMessages(t *testing.T) { 605 tg := testgo(t) 606 defer tg.cleanup() 607 tg.parallel() 608 tg.tempFile("err.go", `package main; import "bar"`) 609 path := tg.path("err.go") 610 tg.runFail("run", path) 611 shortPath := path 612 if rel, err := filepath.Rel(tg.pwd(), path); err == nil && len(rel) < len(path) { 613 shortPath = rel 614 } 615 tg.grepStderr("^"+regexp.QuoteMeta(shortPath)+":", "missing file:line in error message") 616 } 617 618 func TestProgramNameInCrashMessages(t *testing.T) { 619 tg := testgo(t) 620 defer tg.cleanup() 621 tg.parallel() 622 tg.tempFile("triv.go", `package main; func main() {}`) 623 tg.runFail("build", "-ldflags", "-crash_for_testing", tg.path("triv.go")) 624 tg.grepStderr(`[/\\]tool[/\\].*[/\\]link`, "missing linker name in error message") 625 } 626 627 func TestBrokenTestsWithoutTestFunctionsAllFail(t *testing.T) { 628 tg := testgo(t) 629 defer tg.cleanup() 630 tg.runFail("test", "./testdata/src/badtest/...") 631 tg.grepBothNot("^ok", "test passed unexpectedly") 632 tg.grepBoth("FAIL.*badtest/badexec", "test did not run everything") 633 tg.grepBoth("FAIL.*badtest/badsyntax", "test did not run everything") 634 tg.grepBoth("FAIL.*badtest/badvar", "test did not run everything") 635 } 636 637 func TestGoBuildDashAInDevBranch(t *testing.T) { 638 if testing.Short() { 639 t.Skip("don't rebuild the standard library in short mode") 640 } 641 642 tg := testgo(t) 643 defer tg.cleanup() 644 tg.run("install", "math") // should be up to date already but just in case 645 tg.setenv("TESTGO_IS_GO_RELEASE", "0") 646 tg.run("build", "-v", "-a", "math") 647 tg.grepStderr("runtime", "testgo build -a math in dev branch DID NOT build runtime, but should have") 648 649 // Everything is out of date. Rebuild to leave things in a better state. 650 tg.run("install", "std") 651 } 652 653 func TestGoBuildDashAInReleaseBranch(t *testing.T) { 654 if testing.Short() { 655 t.Skip("don't rebuild the standard library in short mode") 656 } 657 658 tg := testgo(t) 659 defer tg.cleanup() 660 tg.run("install", "math", "net/http") // should be up to date already but just in case 661 tg.setenv("TESTGO_IS_GO_RELEASE", "1") 662 tg.run("install", "-v", "-a", "math") 663 tg.grepStderr("runtime", "testgo build -a math in release branch DID NOT build runtime, but should have") 664 665 // Now runtime.a is updated (newer mtime), so everything would look stale if not for being a release. 666 tg.run("build", "-v", "net/http") 667 tg.grepStderrNot("strconv", "testgo build -v net/http in release branch with newer runtime.a DID build strconv but should not have") 668 tg.grepStderrNot("golang.org/x/net/http2/hpack", "testgo build -v net/http in release branch with newer runtime.a DID build .../golang.org/x/net/http2/hpack but should not have") 669 tg.grepStderrNot("net/http", "testgo build -v net/http in release branch with newer runtime.a DID build net/http but should not have") 670 671 // Everything is out of date. Rebuild to leave things in a better state. 672 tg.run("install", "std") 673 } 674 675 func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) { 676 if testing.Short() { 677 t.Skip("don't rebuild the standard library in short mode") 678 } 679 680 tg := testgo(t) 681 defer tg.cleanup() 682 683 addNL := func(name string) (restore func()) { 684 data, err := ioutil.ReadFile(name) 685 if err != nil { 686 t.Fatal(err) 687 } 688 old := data 689 data = append(data, '\n') 690 if err := ioutil.WriteFile(name, append(data, '\n'), 0666); err != nil { 691 t.Fatal(err) 692 } 693 tg.sleep() 694 return func() { 695 if err := ioutil.WriteFile(name, old, 0666); err != nil { 696 t.Fatal(err) 697 } 698 } 699 } 700 701 tg.setenv("TESTGO_IS_GO_RELEASE", "1") 702 703 tg.tempFile("d1/src/p1/p1.go", `package p1`) 704 tg.setenv("GOPATH", tg.path("d1")) 705 tg.run("install", "-a", "p1") 706 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly") 707 tg.sleep() 708 709 // Changing mtime and content of runtime/internal/sys/sys.go 710 // should have no effect: we're in a release, which doesn't rebuild 711 // for general mtime or content changes. 712 sys := runtime.GOROOT() + "/src/runtime/internal/sys/sys.go" 713 restore := addNL(sys) 714 defer restore() 715 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, after updating runtime/internal/sys/sys.go") 716 restore() 717 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, after restoring runtime/internal/sys/sys.go") 718 719 // But changing runtime/internal/sys/zversion.go should have an effect: 720 // that's how we tell when we flip from one release to another. 721 zversion := runtime.GOROOT() + "/src/runtime/internal/sys/zversion.go" 722 restore = addNL(zversion) 723 defer restore() 724 tg.wantStale("p1", "build ID mismatch", "./testgo list claims p1 is NOT stale, incorrectly, after changing to new release") 725 restore() 726 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, after changing back to old release") 727 addNL(zversion) 728 tg.wantStale("p1", "build ID mismatch", "./testgo list claims p1 is NOT stale, incorrectly, after changing again to new release") 729 tg.run("install", "p1") 730 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after building with new release") 731 732 // Restore to "old" release. 733 restore() 734 tg.wantStale("p1", "build ID mismatch", "./testgo list claims p1 is NOT stale, incorrectly, after changing to old release after new build") 735 tg.run("install", "p1") 736 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after building with old release") 737 738 // Everything is out of date. Rebuild to leave things in a better state. 739 tg.run("install", "std") 740 } 741 742 func TestGoListStandard(t *testing.T) { 743 tg := testgo(t) 744 defer tg.cleanup() 745 tg.cd(runtime.GOROOT() + "/src") 746 tg.run("list", "-f", "{{if not .Standard}}{{.ImportPath}}{{end}}", "./...") 747 stdout := tg.getStdout() 748 for _, line := range strings.Split(stdout, "\n") { 749 if strings.HasPrefix(line, "_/") && strings.HasSuffix(line, "/src") { 750 // $GOROOT/src shows up if there are any .go files there. 751 // We don't care. 752 continue 753 } 754 if line == "" { 755 continue 756 } 757 t.Errorf("package in GOROOT not listed as standard: %v", line) 758 } 759 760 // Similarly, expanding std should include some of our vendored code. 761 tg.run("list", "std", "cmd") 762 tg.grepStdout("golang.org/x/net/http2/hpack", "list std cmd did not mention vendored hpack") 763 tg.grepStdout("golang.org/x/arch/x86/x86asm", "list std cmd did not mention vendored x86asm") 764 } 765 766 func TestGoInstallCleansUpAfterGoBuild(t *testing.T) { 767 tg := testgo(t) 768 defer tg.cleanup() 769 tg.tempFile("src/mycmd/main.go", `package main; func main(){}`) 770 tg.setenv("GOPATH", tg.path(".")) 771 tg.cd(tg.path("src/mycmd")) 772 773 doesNotExist := func(file, msg string) { 774 if _, err := os.Stat(file); err == nil { 775 t.Fatal(msg) 776 } else if !os.IsNotExist(err) { 777 t.Fatal(msg, "error:", err) 778 } 779 } 780 781 tg.run("build") 782 tg.wantExecutable("mycmd"+exeSuffix, "testgo build did not write command binary") 783 tg.run("install") 784 doesNotExist("mycmd"+exeSuffix, "testgo install did not remove command binary") 785 tg.run("build") 786 tg.wantExecutable("mycmd"+exeSuffix, "testgo build did not write command binary (second time)") 787 // Running install with arguments does not remove the target, 788 // even in the same directory. 789 tg.run("install", "mycmd") 790 tg.wantExecutable("mycmd"+exeSuffix, "testgo install mycmd removed command binary when run in mycmd") 791 tg.run("build") 792 tg.wantExecutable("mycmd"+exeSuffix, "testgo build did not write command binary (third time)") 793 // And especially not outside the directory. 794 tg.cd(tg.path(".")) 795 if data, err := ioutil.ReadFile("src/mycmd/mycmd" + exeSuffix); err != nil { 796 t.Fatal("could not read file:", err) 797 } else { 798 if err := ioutil.WriteFile("mycmd"+exeSuffix, data, 0555); err != nil { 799 t.Fatal("could not write file:", err) 800 } 801 } 802 tg.run("install", "mycmd") 803 tg.wantExecutable("src/mycmd/mycmd"+exeSuffix, "testgo install mycmd removed command binary from its source dir when run outside mycmd") 804 tg.wantExecutable("mycmd"+exeSuffix, "testgo install mycmd removed command binary from current dir when run outside mycmd") 805 } 806 807 func TestGoInstallRebuildsStalePackagesInOtherGOPATH(t *testing.T) { 808 tg := testgo(t) 809 defer tg.cleanup() 810 tg.parallel() 811 tg.tempFile("d1/src/p1/p1.go", `package p1 812 import "p2" 813 func F() { p2.F() }`) 814 tg.tempFile("d2/src/p2/p2.go", `package p2 815 func F() {}`) 816 sep := string(filepath.ListSeparator) 817 tg.setenv("GOPATH", tg.path("d1")+sep+tg.path("d2")) 818 tg.run("install", "p1") 819 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly") 820 tg.wantNotStale("p2", "", "./testgo list claims p2 is stale, incorrectly") 821 tg.sleep() 822 if f, err := os.OpenFile(tg.path("d2/src/p2/p2.go"), os.O_WRONLY|os.O_APPEND, 0); err != nil { 823 t.Fatal(err) 824 } else if _, err = f.WriteString(`func G() {}`); err != nil { 825 t.Fatal(err) 826 } else { 827 tg.must(f.Close()) 828 } 829 tg.wantStale("p2", "newer source file", "./testgo list claims p2 is NOT stale, incorrectly") 830 tg.wantStale("p1", "stale dependency", "./testgo list claims p1 is NOT stale, incorrectly") 831 832 tg.run("install", "p1") 833 tg.wantNotStale("p2", "", "./testgo list claims p2 is stale after reinstall, incorrectly") 834 tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after reinstall, incorrectly") 835 } 836 837 func TestGoInstallDetectsRemovedFiles(t *testing.T) { 838 tg := testgo(t) 839 defer tg.cleanup() 840 tg.parallel() 841 tg.tempFile("src/mypkg/x.go", `package mypkg`) 842 tg.tempFile("src/mypkg/y.go", `package mypkg`) 843 tg.tempFile("src/mypkg/z.go", `// +build missingtag 844 845 package mypkg`) 846 tg.setenv("GOPATH", tg.path(".")) 847 tg.run("install", "mypkg") 848 tg.wantNotStale("mypkg", "", "./testgo list mypkg claims mypkg is stale, incorrectly") 849 // z.go was not part of the build; removing it is okay. 850 tg.must(os.Remove(tg.path("src/mypkg/z.go"))) 851 tg.wantNotStale("mypkg", "", "./testgo list mypkg claims mypkg is stale after removing z.go; should not be stale") 852 // y.go was part of the package; removing it should be detected. 853 tg.must(os.Remove(tg.path("src/mypkg/y.go"))) 854 tg.wantStale("mypkg", "build ID mismatch", "./testgo list mypkg claims mypkg is NOT stale after removing y.go; should be stale") 855 } 856 857 func TestWildcardMatchesSyntaxErrorDirs(t *testing.T) { 858 tg := testgo(t) 859 defer tg.cleanup() 860 tg.tempFile("src/mypkg/x.go", `package mypkg`) 861 tg.tempFile("src/mypkg/y.go", `pkg mypackage`) 862 tg.setenv("GOPATH", tg.path(".")) 863 tg.cd(tg.path("src/mypkg")) 864 tg.runFail("list", "./...") 865 tg.runFail("build", "./...") 866 tg.runFail("install", "./...") 867 } 868 869 func TestGoListWithTags(t *testing.T) { 870 tg := testgo(t) 871 defer tg.cleanup() 872 tg.tempFile("src/mypkg/x.go", "// +build thetag\n\npackage mypkg\n") 873 tg.setenv("GOPATH", tg.path(".")) 874 tg.cd(tg.path("./src")) 875 tg.run("list", "-tags=thetag", "./my...") 876 tg.grepStdout("mypkg", "did not find mypkg") 877 } 878 879 func TestGoInstallErrorOnCrossCompileToBin(t *testing.T) { 880 if testing.Short() { 881 t.Skip("don't install into GOROOT in short mode") 882 } 883 884 tg := testgo(t) 885 defer tg.cleanup() 886 tg.tempFile("src/mycmd/x.go", `package main 887 func main() {}`) 888 tg.setenv("GOPATH", tg.path(".")) 889 tg.cd(tg.path("src/mycmd")) 890 891 tg.run("build", "mycmd") 892 893 goarch := "386" 894 if runtime.GOARCH == "386" { 895 goarch = "amd64" 896 } 897 tg.setenv("GOOS", "linux") 898 tg.setenv("GOARCH", goarch) 899 tg.run("install", "mycmd") 900 tg.setenv("GOBIN", tg.path(".")) 901 tg.runFail("install", "mycmd") 902 tg.run("install", "cmd/pack") 903 } 904 905 func TestGoInstallDetectsRemovedFilesInPackageMain(t *testing.T) { 906 tg := testgo(t) 907 defer tg.cleanup() 908 tg.parallel() 909 tg.tempFile("src/mycmd/x.go", `package main 910 func main() {}`) 911 tg.tempFile("src/mycmd/y.go", `package main`) 912 tg.tempFile("src/mycmd/z.go", `// +build missingtag 913 914 package main`) 915 tg.setenv("GOPATH", tg.path(".")) 916 tg.run("install", "mycmd") 917 tg.wantNotStale("mycmd", "", "./testgo list mypkg claims mycmd is stale, incorrectly") 918 // z.go was not part of the build; removing it is okay. 919 tg.must(os.Remove(tg.path("src/mycmd/z.go"))) 920 tg.wantNotStale("mycmd", "", "./testgo list mycmd claims mycmd is stale after removing z.go; should not be stale") 921 // y.go was part of the package; removing it should be detected. 922 tg.must(os.Remove(tg.path("src/mycmd/y.go"))) 923 tg.wantStale("mycmd", "build ID mismatch", "./testgo list mycmd claims mycmd is NOT stale after removing y.go; should be stale") 924 } 925 926 func testLocalRun(tg *testgoData, exepath, local, match string) { 927 out, err := exec.Command(exepath).Output() 928 if err != nil { 929 tg.t.Fatalf("error running %v: %v", exepath, err) 930 } 931 if !regexp.MustCompile(match).Match(out) { 932 tg.t.Log(string(out)) 933 tg.t.Errorf("testdata/%s/easy.go did not generate expected output", local) 934 } 935 } 936 937 func testLocalEasy(tg *testgoData, local string) { 938 exepath := "./easy" + exeSuffix 939 tg.creatingTemp(exepath) 940 tg.run("build", "-o", exepath, filepath.Join("testdata", local, "easy.go")) 941 testLocalRun(tg, exepath, local, `(?m)^easysub\.Hello`) 942 } 943 944 func testLocalEasySub(tg *testgoData, local string) { 945 exepath := "./easysub" + exeSuffix 946 tg.creatingTemp(exepath) 947 tg.run("build", "-o", exepath, filepath.Join("testdata", local, "easysub", "main.go")) 948 testLocalRun(tg, exepath, local, `(?m)^easysub\.Hello`) 949 } 950 951 func testLocalHard(tg *testgoData, local string) { 952 exepath := "./hard" + exeSuffix 953 tg.creatingTemp(exepath) 954 tg.run("build", "-o", exepath, filepath.Join("testdata", local, "hard.go")) 955 testLocalRun(tg, exepath, local, `(?m)^sub\.Hello`) 956 } 957 958 func testLocalInstall(tg *testgoData, local string) { 959 tg.runFail("install", filepath.Join("testdata", local, "easy.go")) 960 } 961 962 func TestLocalImportsEasy(t *testing.T) { 963 tg := testgo(t) 964 defer tg.cleanup() 965 testLocalEasy(tg, "local") 966 } 967 968 func TestLocalImportsEasySub(t *testing.T) { 969 tg := testgo(t) 970 defer tg.cleanup() 971 testLocalEasySub(tg, "local") 972 } 973 974 func TestLocalImportsHard(t *testing.T) { 975 tg := testgo(t) 976 defer tg.cleanup() 977 testLocalHard(tg, "local") 978 } 979 980 func TestLocalImportsGoInstallShouldFail(t *testing.T) { 981 tg := testgo(t) 982 defer tg.cleanup() 983 testLocalInstall(tg, "local") 984 } 985 986 const badDirName = `#$%:, &()*;<=>?\^{}` 987 988 func copyBad(tg *testgoData) { 989 if runtime.GOOS == "windows" { 990 tg.t.Skipf("skipping test because %q is an invalid directory name", badDirName) 991 } 992 993 tg.must(filepath.Walk("testdata/local", 994 func(path string, info os.FileInfo, err error) error { 995 if err != nil { 996 return err 997 } 998 if info.IsDir() { 999 return nil 1000 } 1001 var data []byte 1002 data, err = ioutil.ReadFile(path) 1003 if err != nil { 1004 return err 1005 } 1006 newpath := strings.Replace(path, "local", badDirName, 1) 1007 tg.tempFile(newpath, string(data)) 1008 return nil 1009 })) 1010 tg.cd(tg.path(".")) 1011 } 1012 1013 func TestBadImportsEasy(t *testing.T) { 1014 tg := testgo(t) 1015 defer tg.cleanup() 1016 copyBad(tg) 1017 testLocalEasy(tg, badDirName) 1018 } 1019 1020 func TestBadImportsEasySub(t *testing.T) { 1021 tg := testgo(t) 1022 defer tg.cleanup() 1023 copyBad(tg) 1024 testLocalEasySub(tg, badDirName) 1025 } 1026 1027 func TestBadImportsHard(t *testing.T) { 1028 tg := testgo(t) 1029 defer tg.cleanup() 1030 copyBad(tg) 1031 testLocalHard(tg, badDirName) 1032 } 1033 1034 func TestBadImportsGoInstallShouldFail(t *testing.T) { 1035 tg := testgo(t) 1036 defer tg.cleanup() 1037 copyBad(tg) 1038 testLocalInstall(tg, badDirName) 1039 } 1040 1041 func TestInternalPackagesInGOROOTAreRespected(t *testing.T) { 1042 tg := testgo(t) 1043 defer tg.cleanup() 1044 tg.runFail("build", "-v", "./testdata/testinternal") 1045 tg.grepBoth("use of internal package not allowed", "wrong error message for testdata/testinternal") 1046 } 1047 1048 func TestInternalPackagesOutsideGOROOTAreRespected(t *testing.T) { 1049 tg := testgo(t) 1050 defer tg.cleanup() 1051 tg.runFail("build", "-v", "./testdata/testinternal2") 1052 tg.grepBoth("use of internal package not allowed", "wrote error message for testdata/testinternal2") 1053 } 1054 1055 func TestRunInternal(t *testing.T) { 1056 tg := testgo(t) 1057 defer tg.cleanup() 1058 dir := filepath.Join(tg.pwd(), "testdata") 1059 tg.setenv("GOPATH", dir) 1060 tg.run("run", filepath.Join(dir, "src/run/good.go")) 1061 tg.runFail("run", filepath.Join(dir, "src/run/bad.go")) 1062 tg.grepStderr("use of internal package not allowed", "unexpected error for run/bad.go") 1063 } 1064 1065 func testMove(t *testing.T, vcs, url, base, config string) { 1066 testenv.MustHaveExternalNetwork(t) 1067 1068 tg := testgo(t) 1069 defer tg.cleanup() 1070 tg.parallel() 1071 tg.tempDir("src") 1072 tg.setenv("GOPATH", tg.path(".")) 1073 tg.run("get", "-d", url) 1074 tg.run("get", "-d", "-u", url) 1075 switch vcs { 1076 case "svn": 1077 // SVN doesn't believe in text files so we can't just edit the config. 1078 // Check out a different repo into the wrong place. 1079 tg.must(os.RemoveAll(tg.path("src/code.google.com/p/rsc-svn"))) 1080 tg.run("get", "-d", "-u", "code.google.com/p/rsc-svn2/trunk") 1081 tg.must(os.Rename(tg.path("src/code.google.com/p/rsc-svn2"), tg.path("src/code.google.com/p/rsc-svn"))) 1082 default: 1083 path := tg.path(filepath.Join("src", config)) 1084 data, err := ioutil.ReadFile(path) 1085 tg.must(err) 1086 data = bytes.Replace(data, []byte(base), []byte(base+"XXX"), -1) 1087 tg.must(ioutil.WriteFile(path, data, 0644)) 1088 } 1089 if vcs == "git" { 1090 // git will ask for a username and password when we 1091 // run go get -d -f -u. An empty username and 1092 // password will work. Prevent asking by setting 1093 // GIT_ASKPASS. 1094 tg.creatingTemp("sink" + exeSuffix) 1095 tg.tempFile("src/sink/sink.go", `package main; func main() {}`) 1096 tg.run("build", "-o", "sink"+exeSuffix, "sink") 1097 tg.setenv("GIT_ASKPASS", filepath.Join(tg.pwd(), "sink"+exeSuffix)) 1098 } 1099 tg.runFail("get", "-d", "-u", url) 1100 tg.grepStderr("is a custom import path for", "go get -d -u "+url+" failed for wrong reason") 1101 tg.runFail("get", "-d", "-f", "-u", url) 1102 tg.grepStderr("validating server certificate|not found", "go get -d -f -u "+url+" failed for wrong reason") 1103 } 1104 1105 func TestInternalPackageErrorsAreHandled(t *testing.T) { 1106 tg := testgo(t) 1107 defer tg.cleanup() 1108 tg.run("list", "./testdata/testinternal3") 1109 } 1110 1111 func TestInternalCache(t *testing.T) { 1112 tg := testgo(t) 1113 defer tg.cleanup() 1114 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/testinternal4")) 1115 tg.runFail("build", "p") 1116 tg.grepStderr("internal", "did not fail to build p") 1117 } 1118 1119 func TestMoveGit(t *testing.T) { 1120 testMove(t, "git", "rsc.io/pdf", "pdf", "rsc.io/pdf/.git/config") 1121 } 1122 1123 // TODO(rsc): Set up a test case on bitbucket for hg. 1124 // func TestMoveHG(t *testing.T) { 1125 // testMove(t, "hg", "rsc.io/x86/x86asm", "x86", "rsc.io/x86/.hg/hgrc") 1126 // } 1127 1128 // TODO(rsc): Set up a test case on SourceForge (?) for svn. 1129 // func testMoveSVN(t *testing.T) { 1130 // testMove(t, "svn", "code.google.com/p/rsc-svn/trunk", "-", "-") 1131 // } 1132 1133 func TestImportCommandMatch(t *testing.T) { 1134 tg := testgo(t) 1135 defer tg.cleanup() 1136 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcom")) 1137 tg.run("build", "./testdata/importcom/works.go") 1138 } 1139 1140 func TestImportCommentMismatch(t *testing.T) { 1141 tg := testgo(t) 1142 defer tg.cleanup() 1143 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcom")) 1144 tg.runFail("build", "./testdata/importcom/wrongplace.go") 1145 tg.grepStderr(`wrongplace expects import "my/x"`, "go build did not mention incorrect import") 1146 } 1147 1148 func TestImportCommentSyntaxError(t *testing.T) { 1149 tg := testgo(t) 1150 defer tg.cleanup() 1151 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcom")) 1152 tg.runFail("build", "./testdata/importcom/bad.go") 1153 tg.grepStderr("cannot parse import comment", "go build did not mention syntax error") 1154 } 1155 1156 func TestImportCommentConflict(t *testing.T) { 1157 tg := testgo(t) 1158 defer tg.cleanup() 1159 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcom")) 1160 tg.runFail("build", "./testdata/importcom/conflict.go") 1161 tg.grepStderr("found import comments", "go build did not mention comment conflict") 1162 } 1163 1164 // cmd/go: custom import path checking should not apply to Go packages without import comment. 1165 func TestIssue10952(t *testing.T) { 1166 testenv.MustHaveExternalNetwork(t) 1167 if _, err := exec.LookPath("git"); err != nil { 1168 t.Skip("skipping because git binary not found") 1169 } 1170 1171 tg := testgo(t) 1172 defer tg.cleanup() 1173 tg.parallel() 1174 tg.tempDir("src") 1175 tg.setenv("GOPATH", tg.path(".")) 1176 const importPath = "github.com/zombiezen/go-get-issue-10952" 1177 tg.run("get", "-d", "-u", importPath) 1178 repoDir := tg.path("src/" + importPath) 1179 tg.runGit(repoDir, "remote", "set-url", "origin", "https://"+importPath+".git") 1180 tg.run("get", "-d", "-u", importPath) 1181 } 1182 1183 // Test git clone URL that uses SCP-like syntax and custom import path checking. 1184 func TestIssue11457(t *testing.T) { 1185 testenv.MustHaveExternalNetwork(t) 1186 if _, err := exec.LookPath("git"); err != nil { 1187 t.Skip("skipping because git binary not found") 1188 } 1189 1190 tg := testgo(t) 1191 defer tg.cleanup() 1192 tg.parallel() 1193 tg.tempDir("src") 1194 tg.setenv("GOPATH", tg.path(".")) 1195 const importPath = "github.com/rsc/go-get-issue-11457" 1196 tg.run("get", "-d", "-u", importPath) 1197 repoDir := tg.path("src/" + importPath) 1198 tg.runGit(repoDir, "remote", "set-url", "origin", "git@github.com:rsc/go-get-issue-11457") 1199 1200 // At this time, custom import path checking compares remotes verbatim (rather than 1201 // just the host and path, skipping scheme and user), so we expect go get -u to fail. 1202 // However, the goal of this test is to verify that gitRemoteRepo correctly parsed 1203 // the SCP-like syntax, and we expect it to appear in the error message. 1204 tg.runFail("get", "-d", "-u", importPath) 1205 want := " is checked out from ssh://git@github.com/rsc/go-get-issue-11457" 1206 if !strings.HasSuffix(strings.TrimSpace(tg.getStderr()), want) { 1207 t.Error("expected clone URL to appear in stderr") 1208 } 1209 } 1210 1211 func TestGetGitDefaultBranch(t *testing.T) { 1212 testenv.MustHaveExternalNetwork(t) 1213 if _, err := exec.LookPath("git"); err != nil { 1214 t.Skip("skipping because git binary not found") 1215 } 1216 1217 tg := testgo(t) 1218 defer tg.cleanup() 1219 tg.parallel() 1220 tg.tempDir("src") 1221 tg.setenv("GOPATH", tg.path(".")) 1222 1223 // This repo has two branches, master and another-branch. 1224 // The another-branch is the default that you get from 'git clone'. 1225 // The go get command variants should not override this. 1226 const importPath = "github.com/rsc/go-get-default-branch" 1227 1228 tg.run("get", "-d", importPath) 1229 repoDir := tg.path("src/" + importPath) 1230 tg.runGit(repoDir, "branch", "--contains", "HEAD") 1231 tg.grepStdout(`\* another-branch`, "not on correct default branch") 1232 1233 tg.run("get", "-d", "-u", importPath) 1234 tg.runGit(repoDir, "branch", "--contains", "HEAD") 1235 tg.grepStdout(`\* another-branch`, "not on correct default branch") 1236 } 1237 1238 func TestErrorMessageForSyntaxErrorInTestGoFileSaysFAIL(t *testing.T) { 1239 tg := testgo(t) 1240 defer tg.cleanup() 1241 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1242 tg.runFail("test", "syntaxerror") 1243 tg.grepStderr("FAIL", "go test did not say FAIL") 1244 } 1245 1246 func TestWildcardsDoNotLookInUselessDirectories(t *testing.T) { 1247 tg := testgo(t) 1248 defer tg.cleanup() 1249 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1250 tg.runFail("list", "...") 1251 tg.grepBoth("badpkg", "go list ... failure does not mention badpkg") 1252 tg.run("list", "m...") 1253 } 1254 1255 func TestRelativeImportsGoTest(t *testing.T) { 1256 tg := testgo(t) 1257 defer tg.cleanup() 1258 tg.run("test", "./testdata/testimport") 1259 } 1260 1261 func TestRelativeImportsGoTestDashI(t *testing.T) { 1262 tg := testgo(t) 1263 defer tg.cleanup() 1264 tg.run("test", "-i", "./testdata/testimport") 1265 } 1266 1267 func TestRelativeImportsInCommandLinePackage(t *testing.T) { 1268 tg := testgo(t) 1269 defer tg.cleanup() 1270 files, err := filepath.Glob("./testdata/testimport/*.go") 1271 tg.must(err) 1272 tg.run(append([]string{"test"}, files...)...) 1273 } 1274 1275 func TestVersionControlErrorMessageIncludesCorrectDirectory(t *testing.T) { 1276 tg := testgo(t) 1277 defer tg.cleanup() 1278 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/shadow/root1")) 1279 tg.runFail("get", "-u", "foo") 1280 1281 // TODO(iant): We should not have to use strconv.Quote here. 1282 // The code in vcs.go should be changed so that it is not required. 1283 quoted := strconv.Quote(filepath.Join("testdata", "shadow", "root1", "src", "foo")) 1284 quoted = quoted[1 : len(quoted)-1] 1285 1286 tg.grepStderr(regexp.QuoteMeta(quoted), "go get -u error does not mention shadow/root1/src/foo") 1287 } 1288 1289 func TestInstallFailsWithNoBuildableFiles(t *testing.T) { 1290 tg := testgo(t) 1291 defer tg.cleanup() 1292 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1293 tg.setenv("CGO_ENABLED", "0") 1294 tg.runFail("install", "cgotest") 1295 tg.grepStderr("no buildable Go source files", "go install cgotest did not report 'no buildable Go Source files'") 1296 } 1297 1298 func TestRelativeGOBINFail(t *testing.T) { 1299 tg := testgo(t) 1300 defer tg.cleanup() 1301 tg.tempFile("triv.go", `package main; func main() {}`) 1302 tg.setenv("GOBIN", ".") 1303 tg.runFail("install") 1304 tg.grepStderr("cannot install, GOBIN must be an absolute path", "go install must fail if $GOBIN is a relative path") 1305 } 1306 1307 // Test that without $GOBIN set, binaries get installed 1308 // into the GOPATH bin directory. 1309 func TestInstallIntoGOPATH(t *testing.T) { 1310 tg := testgo(t) 1311 defer tg.cleanup() 1312 tg.creatingTemp("testdata/bin/go-cmd-test" + exeSuffix) 1313 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1314 tg.run("install", "go-cmd-test") 1315 tg.wantExecutable("testdata/bin/go-cmd-test"+exeSuffix, "go install go-cmd-test did not write to testdata/bin/go-cmd-test") 1316 } 1317 1318 // Issue 12407 1319 func TestBuildOutputToDevNull(t *testing.T) { 1320 if runtime.GOOS == "plan9" { 1321 t.Skip("skipping because /dev/null is a regular file on plan9") 1322 } 1323 tg := testgo(t) 1324 defer tg.cleanup() 1325 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1326 tg.run("build", "-o", os.DevNull, "go-cmd-test") 1327 } 1328 1329 func TestPackageMainTestImportsArchiveNotBinary(t *testing.T) { 1330 tg := testgo(t) 1331 defer tg.cleanup() 1332 tg.parallel() 1333 gobin := filepath.Join(tg.pwd(), "testdata", "bin") 1334 tg.creatingTemp(gobin) 1335 tg.setenv("GOBIN", gobin) 1336 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1337 tg.must(os.Chtimes("./testdata/src/main_test/m.go", time.Now(), time.Now())) 1338 tg.sleep() 1339 tg.run("test", "main_test") 1340 tg.run("install", "main_test") 1341 tg.wantNotStale("main_test", "", "after go install, main listed as stale") 1342 tg.run("test", "main_test") 1343 } 1344 1345 // The runtime version string takes one of two forms: 1346 // "go1.X[.Y]" for Go releases, and "devel +hash" at tip. 1347 // Determine whether we are in a released copy by 1348 // inspecting the version. 1349 var isGoRelease = strings.HasPrefix(runtime.Version(), "go1") 1350 1351 // Issue 12690 1352 func TestPackageNotStaleWithTrailingSlash(t *testing.T) { 1353 tg := testgo(t) 1354 defer tg.cleanup() 1355 1356 // Make sure the packages below are not stale. 1357 tg.run("install", "runtime", "os", "io") 1358 1359 goroot := runtime.GOROOT() 1360 tg.setenv("GOROOT", goroot+"/") 1361 1362 want := "" 1363 if isGoRelease { 1364 want = "standard package in Go release distribution" 1365 } 1366 1367 tg.wantNotStale("runtime", want, "with trailing slash in GOROOT, runtime listed as stale") 1368 tg.wantNotStale("os", want, "with trailing slash in GOROOT, os listed as stale") 1369 tg.wantNotStale("io", want, "with trailing slash in GOROOT, io listed as stale") 1370 } 1371 1372 // With $GOBIN set, binaries get installed to $GOBIN. 1373 func TestInstallIntoGOBIN(t *testing.T) { 1374 tg := testgo(t) 1375 defer tg.cleanup() 1376 gobin := filepath.Join(tg.pwd(), "testdata", "bin1") 1377 tg.creatingTemp(gobin) 1378 tg.setenv("GOBIN", gobin) 1379 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1380 tg.run("install", "go-cmd-test") 1381 tg.wantExecutable("testdata/bin1/go-cmd-test"+exeSuffix, "go install go-cmd-test did not write to testdata/bin1/go-cmd-test") 1382 } 1383 1384 // Issue 11065 1385 func TestInstallToCurrentDirectoryCreatesExecutable(t *testing.T) { 1386 tg := testgo(t) 1387 defer tg.cleanup() 1388 pkg := filepath.Join(tg.pwd(), "testdata", "src", "go-cmd-test") 1389 tg.creatingTemp(filepath.Join(pkg, "go-cmd-test"+exeSuffix)) 1390 tg.setenv("GOBIN", pkg) 1391 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1392 tg.cd(pkg) 1393 tg.run("install") 1394 tg.wantExecutable("go-cmd-test"+exeSuffix, "go install did not write to current directory") 1395 } 1396 1397 // Without $GOBIN set, installing a program outside $GOPATH should fail 1398 // (there is nowhere to install it). 1399 func TestInstallWithoutDestinationFails(t *testing.T) { 1400 tg := testgo(t) 1401 defer tg.cleanup() 1402 tg.runFail("install", "testdata/src/go-cmd-test/helloworld.go") 1403 tg.grepStderr("no install location for .go files listed on command line", "wrong error") 1404 } 1405 1406 // With $GOBIN set, should install there. 1407 func TestInstallToGOBINCommandLinePackage(t *testing.T) { 1408 tg := testgo(t) 1409 defer tg.cleanup() 1410 gobin := filepath.Join(tg.pwd(), "testdata", "bin1") 1411 tg.creatingTemp(gobin) 1412 tg.setenv("GOBIN", gobin) 1413 tg.run("install", "testdata/src/go-cmd-test/helloworld.go") 1414 tg.wantExecutable("testdata/bin1/helloworld"+exeSuffix, "go install testdata/src/go-cmd-test/helloworld.go did not write testdata/bin1/helloworld") 1415 } 1416 1417 func TestGoGetNonPkg(t *testing.T) { 1418 testenv.MustHaveExternalNetwork(t) 1419 1420 tg := testgo(t) 1421 defer tg.cleanup() 1422 tg.tempDir("gobin") 1423 tg.setenv("GOPATH", tg.path(".")) 1424 tg.setenv("GOBIN", tg.path("gobin")) 1425 tg.runFail("get", "-d", "golang.org/x/tools") 1426 tg.grepStderr("golang.org/x/tools: no buildable Go source files", "missing error") 1427 tg.runFail("get", "-d", "-u", "golang.org/x/tools") 1428 tg.grepStderr("golang.org/x/tools: no buildable Go source files", "missing error") 1429 tg.runFail("get", "-d", "golang.org/x/tools") 1430 tg.grepStderr("golang.org/x/tools: no buildable Go source files", "missing error") 1431 } 1432 1433 func TestInstalls(t *testing.T) { 1434 if testing.Short() { 1435 t.Skip("don't install into GOROOT in short mode") 1436 } 1437 1438 tg := testgo(t) 1439 defer tg.cleanup() 1440 tg.parallel() 1441 tg.tempDir("gobin") 1442 tg.setenv("GOPATH", tg.path(".")) 1443 goroot := runtime.GOROOT() 1444 tg.setenv("GOROOT", goroot) 1445 1446 // cmd/fix installs into tool 1447 tg.run("env", "GOOS") 1448 goos := strings.TrimSpace(tg.getStdout()) 1449 tg.setenv("GOOS", goos) 1450 tg.run("env", "GOARCH") 1451 goarch := strings.TrimSpace(tg.getStdout()) 1452 tg.setenv("GOARCH", goarch) 1453 fixbin := filepath.Join(goroot, "pkg", "tool", goos+"_"+goarch, "fix") + exeSuffix 1454 tg.must(os.RemoveAll(fixbin)) 1455 tg.run("install", "cmd/fix") 1456 tg.wantExecutable(fixbin, "did not install cmd/fix to $GOROOT/pkg/tool") 1457 tg.must(os.Remove(fixbin)) 1458 tg.setenv("GOBIN", tg.path("gobin")) 1459 tg.run("install", "cmd/fix") 1460 tg.wantExecutable(fixbin, "did not install cmd/fix to $GOROOT/pkg/tool with $GOBIN set") 1461 tg.unsetenv("GOBIN") 1462 1463 // gopath program installs into GOBIN 1464 tg.tempFile("src/progname/p.go", `package main; func main() {}`) 1465 tg.setenv("GOBIN", tg.path("gobin")) 1466 tg.run("install", "progname") 1467 tg.unsetenv("GOBIN") 1468 tg.wantExecutable(tg.path("gobin/progname")+exeSuffix, "did not install progname to $GOBIN/progname") 1469 1470 // gopath program installs into GOPATH/bin 1471 tg.run("install", "progname") 1472 tg.wantExecutable(tg.path("bin/progname")+exeSuffix, "did not install progname to $GOPATH/bin/progname") 1473 } 1474 1475 func TestRejectRelativeDotPathInGOPATHCommandLinePackage(t *testing.T) { 1476 tg := testgo(t) 1477 defer tg.cleanup() 1478 tg.setenv("GOPATH", ".") 1479 tg.runFail("build", "testdata/src/go-cmd-test/helloworld.go") 1480 tg.grepStderr("GOPATH entry is relative", "expected an error message rejecting relative GOPATH entries") 1481 } 1482 1483 func TestRejectRelativePathsInGOPATH(t *testing.T) { 1484 tg := testgo(t) 1485 defer tg.cleanup() 1486 sep := string(filepath.ListSeparator) 1487 tg.setenv("GOPATH", sep+filepath.Join(tg.pwd(), "testdata")+sep+".") 1488 tg.runFail("build", "go-cmd-test") 1489 tg.grepStderr("GOPATH entry is relative", "expected an error message rejecting relative GOPATH entries") 1490 } 1491 1492 func TestRejectRelativePathsInGOPATHCommandLinePackage(t *testing.T) { 1493 tg := testgo(t) 1494 defer tg.cleanup() 1495 tg.setenv("GOPATH", "testdata") 1496 tg.runFail("build", "testdata/src/go-cmd-test/helloworld.go") 1497 tg.grepStderr("GOPATH entry is relative", "expected an error message rejecting relative GOPATH entries") 1498 } 1499 1500 // Issue 4104. 1501 func TestGoTestWithPackageListedMultipleTimes(t *testing.T) { 1502 tg := testgo(t) 1503 defer tg.cleanup() 1504 tg.parallel() 1505 tg.run("test", "errors", "errors", "errors", "errors", "errors") 1506 if strings.Contains(strings.TrimSpace(tg.getStdout()), "\n") { 1507 t.Error("go test errors errors errors errors errors tested the same package multiple times") 1508 } 1509 } 1510 1511 func TestGoListHasAConsistentOrder(t *testing.T) { 1512 tg := testgo(t) 1513 defer tg.cleanup() 1514 tg.run("list", "std") 1515 first := tg.getStdout() 1516 tg.run("list", "std") 1517 if first != tg.getStdout() { 1518 t.Error("go list std ordering is inconsistent") 1519 } 1520 } 1521 1522 func TestGoListStdDoesNotIncludeCommands(t *testing.T) { 1523 tg := testgo(t) 1524 defer tg.cleanup() 1525 tg.run("list", "std") 1526 tg.grepStdoutNot("cmd/", "go list std shows commands") 1527 } 1528 1529 func TestGoListCmdOnlyShowsCommands(t *testing.T) { 1530 tg := testgo(t) 1531 defer tg.cleanup() 1532 tg.run("list", "cmd") 1533 out := strings.TrimSpace(tg.getStdout()) 1534 for _, line := range strings.Split(out, "\n") { 1535 if !strings.Contains(line, "cmd/") { 1536 t.Error("go list cmd shows non-commands") 1537 break 1538 } 1539 } 1540 } 1541 1542 func TestGoListDedupsPackages(t *testing.T) { 1543 tg := testgo(t) 1544 defer tg.cleanup() 1545 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1546 tg.run("list", "xtestonly", "./testdata/src/xtestonly/...") 1547 got := strings.TrimSpace(tg.getStdout()) 1548 const want = "xtestonly" 1549 if got != want { 1550 t.Errorf("got %q; want %q", got, want) 1551 } 1552 } 1553 1554 // Issue 4096. Validate the output of unsuccessful go install foo/quxx. 1555 func TestUnsuccessfulGoInstallShouldMentionMissingPackage(t *testing.T) { 1556 tg := testgo(t) 1557 defer tg.cleanup() 1558 tg.runFail("install", "foo/quxx") 1559 if tg.grepCountBoth(`cannot find package "foo/quxx" in any of`) != 1 { 1560 t.Error(`go install foo/quxx expected error: .*cannot find package "foo/quxx" in any of`) 1561 } 1562 } 1563 1564 func TestGOROOTSearchFailureReporting(t *testing.T) { 1565 tg := testgo(t) 1566 defer tg.cleanup() 1567 tg.runFail("install", "foo/quxx") 1568 if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("foo", "quxx"))+` \(from \$GOROOT\)$`) != 1 { 1569 t.Error(`go install foo/quxx expected error: .*foo/quxx (from $GOROOT)`) 1570 } 1571 } 1572 1573 func TestMultipleGOPATHEntriesReportedSeparately(t *testing.T) { 1574 tg := testgo(t) 1575 defer tg.cleanup() 1576 sep := string(filepath.ListSeparator) 1577 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b")) 1578 tg.runFail("install", "foo/quxx") 1579 if tg.grepCountBoth(`testdata[/\\].[/\\]src[/\\]foo[/\\]quxx`) != 2 { 1580 t.Error(`go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)\n.*testdata/b/src/foo/quxx`) 1581 } 1582 } 1583 1584 // Test (from $GOPATH) annotation is reported for the first GOPATH entry, 1585 func TestMentionGOPATHInFirstGOPATHEntry(t *testing.T) { 1586 tg := testgo(t) 1587 defer tg.cleanup() 1588 sep := string(filepath.ListSeparator) 1589 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b")) 1590 tg.runFail("install", "foo/quxx") 1591 if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("testdata", "a", "src", "foo", "quxx"))+` \(from \$GOPATH\)$`) != 1 { 1592 t.Error(`go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)`) 1593 } 1594 } 1595 1596 // but not on the second. 1597 func TestMentionGOPATHNotOnSecondEntry(t *testing.T) { 1598 tg := testgo(t) 1599 defer tg.cleanup() 1600 sep := string(filepath.ListSeparator) 1601 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b")) 1602 tg.runFail("install", "foo/quxx") 1603 if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("testdata", "b", "src", "foo", "quxx"))+`$`) != 1 { 1604 t.Error(`go install foo/quxx expected error: .*testdata/b/src/foo/quxx`) 1605 } 1606 } 1607 1608 // Test missing GOPATH is reported. 1609 func TestMissingGOPATHIsReported(t *testing.T) { 1610 tg := testgo(t) 1611 defer tg.cleanup() 1612 tg.setenv("GOPATH", "") 1613 tg.runFail("install", "foo/quxx") 1614 if tg.grepCountBoth(`\(\$GOPATH not set\)$`) != 1 { 1615 t.Error(`go install foo/quxx expected error: ($GOPATH not set)`) 1616 } 1617 } 1618 1619 // Issue 4186. go get cannot be used to download packages to $GOROOT. 1620 // Test that without GOPATH set, go get should fail. 1621 func TestWithoutGOPATHGoGetFails(t *testing.T) { 1622 testenv.MustHaveExternalNetwork(t) 1623 1624 tg := testgo(t) 1625 defer tg.cleanup() 1626 tg.parallel() 1627 tg.tempDir("src") 1628 tg.setenv("GOPATH", "") 1629 tg.setenv("GOROOT", tg.path(".")) 1630 tg.runFail("get", "-d", "golang.org/x/codereview/cmd/hgpatch") 1631 } 1632 1633 // Test that with GOPATH=$GOROOT, go get should fail. 1634 func TestWithGOPATHEqualsGOROOTGoGetFails(t *testing.T) { 1635 testenv.MustHaveExternalNetwork(t) 1636 1637 tg := testgo(t) 1638 defer tg.cleanup() 1639 tg.parallel() 1640 tg.tempDir("src") 1641 tg.setenv("GOPATH", tg.path(".")) 1642 tg.setenv("GOROOT", tg.path(".")) 1643 tg.runFail("get", "-d", "golang.org/x/codereview/cmd/hgpatch") 1644 } 1645 1646 func TestLdflagsArgumentsWithSpacesIssue3941(t *testing.T) { 1647 tg := testgo(t) 1648 defer tg.cleanup() 1649 tg.parallel() 1650 tg.tempFile("main.go", `package main 1651 var extern string 1652 func main() { 1653 println(extern) 1654 }`) 1655 tg.run("run", "-ldflags", `-X "main.extern=hello world"`, tg.path("main.go")) 1656 tg.grepStderr("^hello world", `ldflags -X "main.extern=hello world"' failed`) 1657 } 1658 1659 func TestGoTestCpuprofileLeavesBinaryBehind(t *testing.T) { 1660 tg := testgo(t) 1661 defer tg.cleanup() 1662 tg.makeTempdir() 1663 tg.cd(tg.path(".")) 1664 tg.run("test", "-cpuprofile", "errors.prof", "errors") 1665 tg.wantExecutable("errors.test"+exeSuffix, "go test -cpuprofile did not create errors.test") 1666 } 1667 1668 func TestGoTestCpuprofileDashOControlsBinaryLocation(t *testing.T) { 1669 tg := testgo(t) 1670 defer tg.cleanup() 1671 tg.makeTempdir() 1672 tg.cd(tg.path(".")) 1673 tg.run("test", "-cpuprofile", "errors.prof", "-o", "myerrors.test"+exeSuffix, "errors") 1674 tg.wantExecutable("myerrors.test"+exeSuffix, "go test -cpuprofile -o myerrors.test did not create myerrors.test") 1675 } 1676 1677 func TestGoTestDashCDashOControlsBinaryLocation(t *testing.T) { 1678 tg := testgo(t) 1679 defer tg.cleanup() 1680 tg.parallel() 1681 tg.makeTempdir() 1682 tg.run("test", "-c", "-o", tg.path("myerrors.test"+exeSuffix), "errors") 1683 tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -c -o myerrors.test did not create myerrors.test") 1684 } 1685 1686 func TestGoTestDashOWritesBinary(t *testing.T) { 1687 tg := testgo(t) 1688 defer tg.cleanup() 1689 tg.parallel() 1690 tg.makeTempdir() 1691 tg.run("test", "-o", tg.path("myerrors.test"+exeSuffix), "errors") 1692 tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -o myerrors.test did not create myerrors.test") 1693 } 1694 1695 // Issue 4568. 1696 func TestSymlinksList(t *testing.T) { 1697 switch runtime.GOOS { 1698 case "plan9", "windows": 1699 t.Skipf("skipping symlink test on %s", runtime.GOOS) 1700 } 1701 1702 tg := testgo(t) 1703 defer tg.cleanup() 1704 tg.tempDir("src") 1705 tg.must(os.Symlink(tg.path("."), tg.path("src/dir1"))) 1706 tg.tempFile("src/dir1/p.go", "package p") 1707 tg.setenv("GOPATH", tg.path(".")) 1708 tg.cd(tg.path("src")) 1709 tg.run("list", "-f", "{{.Root}}", "dir1") 1710 if strings.TrimSpace(tg.getStdout()) != tg.path(".") { 1711 t.Error("confused by symlinks") 1712 } 1713 } 1714 1715 // Issue 14054. 1716 func TestSymlinksVendor(t *testing.T) { 1717 switch runtime.GOOS { 1718 case "plan9", "windows": 1719 t.Skipf("skipping symlink test on %s", runtime.GOOS) 1720 } 1721 1722 tg := testgo(t) 1723 defer tg.cleanup() 1724 tg.tempDir("gopath/src/dir1/vendor/v") 1725 tg.tempFile("gopath/src/dir1/p.go", "package main\nimport _ `v`\nfunc main(){}") 1726 tg.tempFile("gopath/src/dir1/vendor/v/v.go", "package v") 1727 tg.must(os.Symlink(tg.path("gopath/src/dir1"), tg.path("symdir1"))) 1728 tg.setenv("GOPATH", tg.path("gopath")) 1729 tg.cd(tg.path("symdir1")) 1730 tg.run("list", "-f", "{{.Root}}", ".") 1731 if strings.TrimSpace(tg.getStdout()) != tg.path("gopath") { 1732 t.Error("list confused by symlinks") 1733 } 1734 1735 // All of these should succeed, not die in vendor-handling code. 1736 tg.run("run", "p.go") 1737 tg.run("build") 1738 tg.run("install") 1739 } 1740 1741 func TestSymlinksInternal(t *testing.T) { 1742 switch runtime.GOOS { 1743 case "plan9", "windows": 1744 t.Skipf("skipping symlink test on %s", runtime.GOOS) 1745 } 1746 1747 tg := testgo(t) 1748 defer tg.cleanup() 1749 tg.tempDir("gopath/src/dir1/internal/v") 1750 tg.tempFile("gopath/src/dir1/p.go", "package main\nimport _ `dir1/internal/v`\nfunc main(){}") 1751 tg.tempFile("gopath/src/dir1/internal/v/v.go", "package v") 1752 tg.must(os.Symlink(tg.path("gopath/src/dir1"), tg.path("symdir1"))) 1753 tg.setenv("GOPATH", tg.path("gopath")) 1754 tg.cd(tg.path("symdir1")) 1755 tg.run("list", "-f", "{{.Root}}", ".") 1756 if strings.TrimSpace(tg.getStdout()) != tg.path("gopath") { 1757 t.Error("list confused by symlinks") 1758 } 1759 1760 // All of these should succeed, not die in internal-handling code. 1761 tg.run("run", "p.go") 1762 tg.run("build") 1763 tg.run("install") 1764 } 1765 1766 // Issue 4515. 1767 func TestInstallWithTags(t *testing.T) { 1768 tg := testgo(t) 1769 defer tg.cleanup() 1770 tg.parallel() 1771 tg.tempDir("bin") 1772 tg.tempFile("src/example/a/main.go", `package main 1773 func main() {}`) 1774 tg.tempFile("src/example/b/main.go", `// +build mytag 1775 1776 package main 1777 func main() {}`) 1778 tg.setenv("GOPATH", tg.path(".")) 1779 tg.run("install", "-tags", "mytag", "example/a", "example/b") 1780 tg.wantExecutable(tg.path("bin/a"+exeSuffix), "go install example/a example/b did not install binaries") 1781 tg.wantExecutable(tg.path("bin/b"+exeSuffix), "go install example/a example/b did not install binaries") 1782 tg.must(os.Remove(tg.path("bin/a" + exeSuffix))) 1783 tg.must(os.Remove(tg.path("bin/b" + exeSuffix))) 1784 tg.run("install", "-tags", "mytag", "example/...") 1785 tg.wantExecutable(tg.path("bin/a"+exeSuffix), "go install example/... did not install binaries") 1786 tg.wantExecutable(tg.path("bin/b"+exeSuffix), "go install example/... did not install binaries") 1787 tg.run("list", "-tags", "mytag", "example/b...") 1788 if strings.TrimSpace(tg.getStdout()) != "example/b" { 1789 t.Error("go list example/b did not find example/b") 1790 } 1791 } 1792 1793 // Issue 4773 1794 func TestCaseCollisions(t *testing.T) { 1795 tg := testgo(t) 1796 defer tg.cleanup() 1797 tg.parallel() 1798 tg.tempDir("src/example/a/pkg") 1799 tg.tempDir("src/example/a/Pkg") 1800 tg.tempDir("src/example/b") 1801 tg.setenv("GOPATH", tg.path(".")) 1802 tg.tempFile("src/example/a/a.go", `package p 1803 import ( 1804 _ "example/a/pkg" 1805 _ "example/a/Pkg" 1806 )`) 1807 tg.tempFile("src/example/a/pkg/pkg.go", `package pkg`) 1808 tg.tempFile("src/example/a/Pkg/pkg.go", `package pkg`) 1809 tg.runFail("list", "example/a") 1810 tg.grepStderr("case-insensitive import collision", "go list example/a did not report import collision") 1811 tg.tempFile("src/example/b/file.go", `package b`) 1812 tg.tempFile("src/example/b/FILE.go", `package b`) 1813 f, err := os.Open(tg.path("src/example/b")) 1814 tg.must(err) 1815 names, err := f.Readdirnames(0) 1816 tg.must(err) 1817 tg.check(f.Close()) 1818 args := []string{"list"} 1819 if len(names) == 2 { 1820 // case-sensitive file system, let directory read find both files 1821 args = append(args, "example/b") 1822 } else { 1823 // case-insensitive file system, list files explicitly on command line 1824 args = append(args, tg.path("src/example/b/file.go"), tg.path("src/example/b/FILE.go")) 1825 } 1826 tg.runFail(args...) 1827 tg.grepStderr("case-insensitive file name collision", "go list example/b did not report file name collision") 1828 } 1829 1830 // Issue 8181. 1831 func TestGoGetDashTIssue8181(t *testing.T) { 1832 if testing.Short() { 1833 t.Skip("skipping test that uses network in short mode") 1834 } 1835 1836 tg := testgo(t) 1837 defer tg.cleanup() 1838 tg.parallel() 1839 tg.makeTempdir() 1840 tg.setenv("GOPATH", tg.path(".")) 1841 tg.run("get", "-v", "-t", "github.com/rsc/go-get-issue-8181/a", "github.com/rsc/go-get-issue-8181/b") 1842 tg.run("list", "...") 1843 tg.grepStdout("x/build/cmd/cl", "missing expected x/build/cmd/cl") 1844 } 1845 1846 func TestIssue11307(t *testing.T) { 1847 // go get -u was not working except in checkout directory 1848 if testing.Short() { 1849 t.Skip("skipping test that uses network in short mode") 1850 } 1851 1852 tg := testgo(t) 1853 defer tg.cleanup() 1854 tg.parallel() 1855 tg.makeTempdir() 1856 tg.setenv("GOPATH", tg.path(".")) 1857 tg.run("get", "github.com/rsc/go-get-issue-11307") 1858 tg.run("get", "-u", "github.com/rsc/go-get-issue-11307") // was failing 1859 } 1860 1861 func TestShadowingLogic(t *testing.T) { 1862 tg := testgo(t) 1863 defer tg.cleanup() 1864 pwd := tg.pwd() 1865 sep := string(filepath.ListSeparator) 1866 tg.setenv("GOPATH", filepath.Join(pwd, "testdata", "shadow", "root1")+sep+filepath.Join(pwd, "testdata", "shadow", "root2")) 1867 1868 // The math in root1 is not "math" because the standard math is. 1869 tg.run("list", "-f", "({{.ImportPath}}) ({{.ConflictDir}})", "./testdata/shadow/root1/src/math") 1870 pwdForwardSlash := strings.Replace(pwd, string(os.PathSeparator), "/", -1) 1871 if !strings.HasPrefix(pwdForwardSlash, "/") { 1872 pwdForwardSlash = "/" + pwdForwardSlash 1873 } 1874 // The output will have makeImportValid applies, but we only 1875 // bother to deal with characters we might reasonably see. 1876 for _, r := range " :" { 1877 pwdForwardSlash = strings.Replace(pwdForwardSlash, string(r), "_", -1) 1878 } 1879 want := "(_" + pwdForwardSlash + "/testdata/shadow/root1/src/math) (" + filepath.Join(runtime.GOROOT(), "src", "math") + ")" 1880 if strings.TrimSpace(tg.getStdout()) != want { 1881 t.Error("shadowed math is not shadowed; looking for", want) 1882 } 1883 1884 // The foo in root1 is "foo". 1885 tg.run("list", "-f", "({{.ImportPath}}) ({{.ConflictDir}})", "./testdata/shadow/root1/src/foo") 1886 if strings.TrimSpace(tg.getStdout()) != "(foo) ()" { 1887 t.Error("unshadowed foo is shadowed") 1888 } 1889 1890 // The foo in root2 is not "foo" because the foo in root1 got there first. 1891 tg.run("list", "-f", "({{.ImportPath}}) ({{.ConflictDir}})", "./testdata/shadow/root2/src/foo") 1892 want = "(_" + pwdForwardSlash + "/testdata/shadow/root2/src/foo) (" + filepath.Join(pwd, "testdata", "shadow", "root1", "src", "foo") + ")" 1893 if strings.TrimSpace(tg.getStdout()) != want { 1894 t.Error("shadowed foo is not shadowed; looking for", want) 1895 } 1896 1897 // The error for go install should mention the conflicting directory. 1898 tg.runFail("install", "./testdata/shadow/root2/src/foo") 1899 want = "go install: no install location for " + filepath.Join(pwd, "testdata", "shadow", "root2", "src", "foo") + ": hidden by " + filepath.Join(pwd, "testdata", "shadow", "root1", "src", "foo") 1900 if strings.TrimSpace(tg.getStderr()) != want { 1901 t.Error("wrong shadowed install error; looking for", want) 1902 } 1903 } 1904 1905 // Only succeeds if source order is preserved. 1906 func TestSourceFileNameOrderPreserved(t *testing.T) { 1907 tg := testgo(t) 1908 defer tg.cleanup() 1909 tg.run("test", "testdata/example1_test.go", "testdata/example2_test.go") 1910 } 1911 1912 // Check that coverage analysis works at all. 1913 // Don't worry about the exact numbers but require not 0.0%. 1914 func checkCoverage(tg *testgoData, data string) { 1915 if regexp.MustCompile(`[^0-9]0\.0%`).MatchString(data) { 1916 tg.t.Error("some coverage results are 0.0%") 1917 } 1918 tg.t.Log(data) 1919 } 1920 1921 func TestCoverageRuns(t *testing.T) { 1922 if testing.Short() { 1923 t.Skip("don't build libraries for coverage in short mode") 1924 } 1925 tg := testgo(t) 1926 defer tg.cleanup() 1927 tg.run("test", "-short", "-coverpkg=strings", "strings", "regexp") 1928 data := tg.getStdout() + tg.getStderr() 1929 tg.run("test", "-short", "-cover", "strings", "math", "regexp") 1930 data += tg.getStdout() + tg.getStderr() 1931 checkCoverage(tg, data) 1932 } 1933 1934 // Check that coverage analysis uses set mode. 1935 func TestCoverageUsesSetMode(t *testing.T) { 1936 if testing.Short() { 1937 t.Skip("don't build libraries for coverage in short mode") 1938 } 1939 tg := testgo(t) 1940 defer tg.cleanup() 1941 tg.creatingTemp("testdata/cover.out") 1942 tg.run("test", "-short", "-cover", "encoding/binary", "-coverprofile=testdata/cover.out") 1943 data := tg.getStdout() + tg.getStderr() 1944 if out, err := ioutil.ReadFile("testdata/cover.out"); err != nil { 1945 t.Error(err) 1946 } else { 1947 if !bytes.Contains(out, []byte("mode: set")) { 1948 t.Error("missing mode: set") 1949 } 1950 } 1951 checkCoverage(tg, data) 1952 } 1953 1954 func TestCoverageUsesAtomicModeForRace(t *testing.T) { 1955 if testing.Short() { 1956 t.Skip("don't build libraries for coverage in short mode") 1957 } 1958 if !canRace { 1959 t.Skip("skipping because race detector not supported") 1960 } 1961 1962 tg := testgo(t) 1963 defer tg.cleanup() 1964 tg.creatingTemp("testdata/cover.out") 1965 tg.run("test", "-short", "-race", "-cover", "encoding/binary", "-coverprofile=testdata/cover.out") 1966 data := tg.getStdout() + tg.getStderr() 1967 if out, err := ioutil.ReadFile("testdata/cover.out"); err != nil { 1968 t.Error(err) 1969 } else { 1970 if !bytes.Contains(out, []byte("mode: atomic")) { 1971 t.Error("missing mode: atomic") 1972 } 1973 } 1974 checkCoverage(tg, data) 1975 } 1976 1977 func TestCoverageUsesActualSettingToOverrideEvenForRace(t *testing.T) { 1978 if testing.Short() { 1979 t.Skip("don't build libraries for coverage in short mode") 1980 } 1981 if !canRace { 1982 t.Skip("skipping because race detector not supported") 1983 } 1984 1985 tg := testgo(t) 1986 defer tg.cleanup() 1987 tg.creatingTemp("testdata/cover.out") 1988 tg.run("test", "-short", "-race", "-cover", "encoding/binary", "-covermode=count", "-coverprofile=testdata/cover.out") 1989 data := tg.getStdout() + tg.getStderr() 1990 if out, err := ioutil.ReadFile("testdata/cover.out"); err != nil { 1991 t.Error(err) 1992 } else { 1993 if !bytes.Contains(out, []byte("mode: count")) { 1994 t.Error("missing mode: count") 1995 } 1996 } 1997 checkCoverage(tg, data) 1998 } 1999 2000 func TestBuildDryRunWithCgo(t *testing.T) { 2001 if !canCgo { 2002 t.Skip("skipping because cgo not enabled") 2003 } 2004 2005 tg := testgo(t) 2006 defer tg.cleanup() 2007 tg.tempFile("foo.go", `package main 2008 2009 /* 2010 #include <limits.h> 2011 */ 2012 import "C" 2013 2014 func main() { 2015 println(C.INT_MAX) 2016 }`) 2017 tg.run("build", "-n", tg.path("foo.go")) 2018 tg.grepStderrNot(`os.Stat .* no such file or directory`, "unexpected stat of archive file") 2019 } 2020 2021 func TestCoverageWithCgo(t *testing.T) { 2022 if !canCgo { 2023 t.Skip("skipping because cgo not enabled") 2024 } 2025 2026 tg := testgo(t) 2027 defer tg.cleanup() 2028 tg.run("test", "-short", "-cover", "./testdata/cgocover") 2029 data := tg.getStdout() + tg.getStderr() 2030 checkCoverage(tg, data) 2031 } 2032 2033 func TestCgoDependsOnSyscall(t *testing.T) { 2034 if testing.Short() { 2035 t.Skip("skipping test that removes $GOROOT/pkg/*_race in short mode") 2036 } 2037 if !canCgo { 2038 t.Skip("skipping because cgo not enabled") 2039 } 2040 if !canRace { 2041 t.Skip("skipping because race detector not supported") 2042 } 2043 2044 tg := testgo(t) 2045 defer tg.cleanup() 2046 files, err := filepath.Glob(filepath.Join(runtime.GOROOT(), "pkg", "*_race")) 2047 tg.must(err) 2048 for _, file := range files { 2049 tg.check(os.RemoveAll(file)) 2050 } 2051 tg.tempFile("src/foo/foo.go", ` 2052 package foo 2053 //#include <stdio.h> 2054 import "C"`) 2055 tg.setenv("GOPATH", tg.path(".")) 2056 tg.run("build", "-race", "foo") 2057 } 2058 2059 func TestCgoShowsFullPathNames(t *testing.T) { 2060 if !canCgo { 2061 t.Skip("skipping because cgo not enabled") 2062 } 2063 2064 tg := testgo(t) 2065 defer tg.cleanup() 2066 tg.parallel() 2067 tg.tempFile("src/x/y/dirname/foo.go", ` 2068 package foo 2069 import "C" 2070 func f() {`) 2071 tg.setenv("GOPATH", tg.path(".")) 2072 tg.runFail("build", "x/y/dirname") 2073 tg.grepBoth("x/y/dirname", "error did not use full path") 2074 } 2075 2076 func TestCgoHandlesWlORIGIN(t *testing.T) { 2077 if !canCgo { 2078 t.Skip("skipping because cgo not enabled") 2079 } 2080 2081 tg := testgo(t) 2082 defer tg.cleanup() 2083 tg.parallel() 2084 tg.tempFile("src/origin/origin.go", `package origin 2085 // #cgo !darwin LDFLAGS: -Wl,-rpath -Wl,$ORIGIN 2086 // void f(void) {} 2087 import "C" 2088 func f() { C.f() }`) 2089 tg.setenv("GOPATH", tg.path(".")) 2090 tg.run("build", "origin") 2091 } 2092 2093 // "go test -c -test.bench=XXX errors" should not hang 2094 func TestIssue6480(t *testing.T) { 2095 tg := testgo(t) 2096 defer tg.cleanup() 2097 tg.makeTempdir() 2098 tg.cd(tg.path(".")) 2099 tg.run("test", "-c", "-test.bench=XXX", "errors") 2100 } 2101 2102 // cmd/cgo: undefined reference when linking a C-library using gccgo 2103 func TestIssue7573(t *testing.T) { 2104 if !canCgo { 2105 t.Skip("skipping because cgo not enabled") 2106 } 2107 if _, err := exec.LookPath("gccgo"); err != nil { 2108 t.Skip("skipping because no gccgo compiler found") 2109 } 2110 2111 tg := testgo(t) 2112 defer tg.cleanup() 2113 tg.parallel() 2114 tg.tempFile("src/cgoref/cgoref.go", ` 2115 package main 2116 // #cgo LDFLAGS: -L alibpath -lalib 2117 // void f(void) {} 2118 import "C" 2119 2120 func main() { C.f() }`) 2121 tg.setenv("GOPATH", tg.path(".")) 2122 tg.run("build", "-n", "-compiler", "gccgo", "cgoref") 2123 tg.grepStderr(`gccgo.*\-L alibpath \-lalib`, `no Go-inline "#cgo LDFLAGS:" ("-L alibpath -lalib") passed to gccgo linking stage`) 2124 } 2125 2126 func TestListTemplateContextFunction(t *testing.T) { 2127 tg := testgo(t) 2128 defer tg.cleanup() 2129 for _, tt := range []struct { 2130 v string 2131 want string 2132 }{ 2133 {"GOARCH", runtime.GOARCH}, 2134 {"GOOS", runtime.GOOS}, 2135 {"GOROOT", filepath.Clean(runtime.GOROOT())}, 2136 {"GOPATH", os.Getenv("GOPATH")}, 2137 {"CgoEnabled", ""}, 2138 {"UseAllFiles", ""}, 2139 {"Compiler", ""}, 2140 {"BuildTags", ""}, 2141 {"ReleaseTags", ""}, 2142 {"InstallSuffix", ""}, 2143 } { 2144 tmpl := "{{context." + tt.v + "}}" 2145 tg.run("list", "-f", tmpl) 2146 if tt.want == "" { 2147 continue 2148 } 2149 if got := strings.TrimSpace(tg.getStdout()); got != tt.want { 2150 t.Errorf("go list -f %q: got %q; want %q", tmpl, got, tt.want) 2151 } 2152 } 2153 } 2154 2155 // cmd/go: "go test" should fail if package does not build 2156 func TestIssue7108(t *testing.T) { 2157 tg := testgo(t) 2158 defer tg.cleanup() 2159 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 2160 tg.runFail("test", "notest") 2161 } 2162 2163 // cmd/go: go test -a foo does not rebuild regexp. 2164 func TestIssue6844(t *testing.T) { 2165 if testing.Short() { 2166 t.Skip("don't rebuild the standard library in short mode") 2167 } 2168 2169 tg := testgo(t) 2170 defer tg.cleanup() 2171 tg.creatingTemp("deps.test" + exeSuffix) 2172 tg.run("test", "-x", "-a", "-c", "testdata/dep_test.go") 2173 tg.grepStderr("regexp", "go test -x -a -c testdata/dep-test.go did not rebuild regexp") 2174 } 2175 2176 func TestBuildDashIInstallsDependencies(t *testing.T) { 2177 tg := testgo(t) 2178 defer tg.cleanup() 2179 tg.parallel() 2180 tg.tempFile("src/x/y/foo/foo.go", `package foo 2181 func F() {}`) 2182 tg.tempFile("src/x/y/bar/bar.go", `package bar 2183 import "x/y/foo" 2184 func F() { foo.F() }`) 2185 tg.setenv("GOPATH", tg.path(".")) 2186 2187 checkbar := func(desc string) { 2188 tg.sleep() 2189 tg.must(os.Chtimes(tg.path("src/x/y/foo/foo.go"), time.Now(), time.Now())) 2190 tg.sleep() 2191 tg.run("build", "-v", "-i", "x/y/bar") 2192 tg.grepBoth("x/y/foo", "first build -i "+desc+" did not build x/y/foo") 2193 tg.run("build", "-v", "-i", "x/y/bar") 2194 tg.grepBothNot("x/y/foo", "second build -i "+desc+" built x/y/foo") 2195 } 2196 checkbar("pkg") 2197 tg.creatingTemp("bar" + exeSuffix) 2198 tg.tempFile("src/x/y/bar/bar.go", `package main 2199 import "x/y/foo" 2200 func main() { foo.F() }`) 2201 checkbar("cmd") 2202 } 2203 2204 func TestGoBuildInTestOnlyDirectoryFailsWithAGoodError(t *testing.T) { 2205 tg := testgo(t) 2206 defer tg.cleanup() 2207 tg.runFail("build", "./testdata/testonly") 2208 tg.grepStderr("no buildable Go", "go build ./testdata/testonly produced unexpected error") 2209 } 2210 2211 func TestGoTestDetectsTestOnlyImportCycles(t *testing.T) { 2212 tg := testgo(t) 2213 defer tg.cleanup() 2214 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 2215 tg.runFail("test", "-c", "testcycle/p3") 2216 tg.grepStderr("import cycle not allowed in test", "go test testcycle/p3 produced unexpected error") 2217 2218 tg.runFail("test", "-c", "testcycle/q1") 2219 tg.grepStderr("import cycle not allowed in test", "go test testcycle/q1 produced unexpected error") 2220 } 2221 2222 func TestGoTestFooTestWorks(t *testing.T) { 2223 tg := testgo(t) 2224 defer tg.cleanup() 2225 tg.run("test", "testdata/standalone_test.go") 2226 } 2227 2228 func TestGoTestFlagsAfterPackage(t *testing.T) { 2229 tg := testgo(t) 2230 defer tg.cleanup() 2231 tg.run("test", "testdata/flag_test.go", "-v", "-args", "-v=7") // Two distinct -v flags. 2232 tg.run("test", "-v", "testdata/flag_test.go", "-args", "-v=7") // Two distinct -v flags. 2233 } 2234 2235 func TestGoTestXtestonlyWorks(t *testing.T) { 2236 tg := testgo(t) 2237 defer tg.cleanup() 2238 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 2239 tg.run("clean", "-i", "xtestonly") 2240 tg.run("test", "xtestonly") 2241 } 2242 2243 func TestGoTestBuildsAnXtestContainingOnlyNonRunnableExamples(t *testing.T) { 2244 tg := testgo(t) 2245 defer tg.cleanup() 2246 tg.run("test", "-v", "./testdata/norunexample") 2247 tg.grepStdout("File with non-runnable example was built.", "file with non-runnable example was not built") 2248 } 2249 2250 func TestGoGenerateHandlesSimpleCommand(t *testing.T) { 2251 if runtime.GOOS == "windows" { 2252 t.Skip("skipping because windows has no echo command") 2253 } 2254 2255 tg := testgo(t) 2256 defer tg.cleanup() 2257 tg.run("generate", "./testdata/generate/test1.go") 2258 tg.grepStdout("Success", "go generate ./testdata/generate/test1.go generated wrong output") 2259 } 2260 2261 func TestGoGenerateHandlesCommandAlias(t *testing.T) { 2262 if runtime.GOOS == "windows" { 2263 t.Skip("skipping because windows has no echo command") 2264 } 2265 2266 tg := testgo(t) 2267 defer tg.cleanup() 2268 tg.run("generate", "./testdata/generate/test2.go") 2269 tg.grepStdout("Now is the time for all good men", "go generate ./testdata/generate/test2.go generated wrong output") 2270 } 2271 2272 func TestGoGenerateVariableSubstitution(t *testing.T) { 2273 if runtime.GOOS == "windows" { 2274 t.Skip("skipping because windows has no echo command") 2275 } 2276 2277 tg := testgo(t) 2278 defer tg.cleanup() 2279 tg.run("generate", "./testdata/generate/test3.go") 2280 tg.grepStdout(runtime.GOARCH+" test3.go:7 pabc xyzp/test3.go/123", "go generate ./testdata/generate/test3.go generated wrong output") 2281 } 2282 2283 func TestGoGenerateRunFlag(t *testing.T) { 2284 if runtime.GOOS == "windows" { 2285 t.Skip("skipping because windows has no echo command") 2286 } 2287 2288 tg := testgo(t) 2289 defer tg.cleanup() 2290 tg.run("generate", "-run", "y.s", "./testdata/generate/test4.go") 2291 tg.grepStdout("yes", "go generate -run yes ./testdata/generate/test4.go did not select yes") 2292 tg.grepStdoutNot("no", "go generate -run yes ./testdata/generate/test4.go selected no") 2293 } 2294 2295 func TestGoGenerateEnv(t *testing.T) { 2296 switch runtime.GOOS { 2297 case "plan9", "windows": 2298 t.Skipf("skipping because %s does not have the env command", runtime.GOOS) 2299 } 2300 tg := testgo(t) 2301 defer tg.cleanup() 2302 tg.parallel() 2303 tg.tempFile("env.go", "package main\n\n//go:generate env") 2304 tg.run("generate", tg.path("env.go")) 2305 for _, v := range []string{"GOARCH", "GOOS", "GOFILE", "GOLINE", "GOPACKAGE", "DOLLAR"} { 2306 tg.grepStdout("^"+v+"=", "go generate environment missing "+v) 2307 } 2308 } 2309 2310 func TestGoGetCustomDomainWildcard(t *testing.T) { 2311 testenv.MustHaveExternalNetwork(t) 2312 2313 tg := testgo(t) 2314 defer tg.cleanup() 2315 tg.makeTempdir() 2316 tg.setenv("GOPATH", tg.path(".")) 2317 tg.run("get", "-u", "rsc.io/pdf/...") 2318 tg.wantExecutable(tg.path("bin/pdfpasswd"+exeSuffix), "did not build rsc/io/pdf/pdfpasswd") 2319 } 2320 2321 func TestGoGetInternalWildcard(t *testing.T) { 2322 testenv.MustHaveExternalNetwork(t) 2323 2324 tg := testgo(t) 2325 defer tg.cleanup() 2326 tg.makeTempdir() 2327 tg.setenv("GOPATH", tg.path(".")) 2328 // used to fail with errors about internal packages 2329 tg.run("get", "github.com/rsc/go-get-issue-11960/...") 2330 } 2331 2332 func TestGoVetWithExternalTests(t *testing.T) { 2333 testenv.MustHaveExternalNetwork(t) 2334 2335 tg := testgo(t) 2336 defer tg.cleanup() 2337 tg.makeTempdir() 2338 tg.run("install", "cmd/vet") 2339 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 2340 tg.runFail("vet", "vetpkg") 2341 tg.grepBoth("missing argument for Printf", "go vet vetpkg did not find missing argument for Printf") 2342 } 2343 2344 func TestGoVetWithTags(t *testing.T) { 2345 testenv.MustHaveExternalNetwork(t) 2346 2347 tg := testgo(t) 2348 defer tg.cleanup() 2349 tg.makeTempdir() 2350 tg.run("install", "cmd/vet") 2351 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 2352 tg.runFail("vet", "-tags", "tagtest", "vetpkg") 2353 tg.grepBoth(`c\.go.*wrong number of args for format`, "go get vetpkg did not run scan tagged file") 2354 } 2355 2356 // Issue 9767. 2357 func TestGoGetRscIoToolstash(t *testing.T) { 2358 testenv.MustHaveExternalNetwork(t) 2359 2360 tg := testgo(t) 2361 defer tg.cleanup() 2362 tg.tempDir("src/rsc.io") 2363 tg.setenv("GOPATH", tg.path(".")) 2364 tg.cd(tg.path("src/rsc.io")) 2365 tg.run("get", "./toolstash") 2366 } 2367 2368 // Issue 13037: Was not parsing <meta> tags in 404 served over HTTPS 2369 func TestGoGetHTTPS404(t *testing.T) { 2370 testenv.MustHaveExternalNetwork(t) 2371 switch runtime.GOOS { 2372 case "darwin", "linux", "freebsd": 2373 default: 2374 t.Skipf("test case does not work on %s", runtime.GOOS) 2375 } 2376 2377 tg := testgo(t) 2378 defer tg.cleanup() 2379 tg.tempDir("src") 2380 tg.setenv("GOPATH", tg.path(".")) 2381 tg.run("get", "bazil.org/fuse/fs/fstestutil") 2382 } 2383 2384 // Test that you cannot import a main package. 2385 func TestIssue4210(t *testing.T) { 2386 tg := testgo(t) 2387 defer tg.cleanup() 2388 tg.tempFile("src/x/main.go", `package main 2389 var X int 2390 func main() {}`) 2391 tg.tempFile("src/y/main.go", `package main 2392 import "fmt" 2393 import xmain "x" 2394 func main() { 2395 fmt.Println(xmain.X) 2396 }`) 2397 tg.setenv("GOPATH", tg.path(".")) 2398 tg.runFail("build", "y") 2399 tg.grepBoth("is a program", `did not find expected error message ("is a program")`) 2400 } 2401 2402 func TestGoGetInsecure(t *testing.T) { 2403 testenv.MustHaveExternalNetwork(t) 2404 2405 t.Skip("golang.org/issue/15410") 2406 2407 tg := testgo(t) 2408 defer tg.cleanup() 2409 tg.makeTempdir() 2410 tg.setenv("GOPATH", tg.path(".")) 2411 tg.failSSH() 2412 2413 const repo = "wh3rd.net/git.git" 2414 2415 // Try go get -d of HTTP-only repo (should fail). 2416 tg.runFail("get", "-d", repo) 2417 2418 // Try again with -insecure (should succeed). 2419 tg.run("get", "-d", "-insecure", repo) 2420 2421 // Try updating without -insecure (should fail). 2422 tg.runFail("get", "-d", "-u", "-f", repo) 2423 } 2424 2425 func TestGoGetUpdateInsecure(t *testing.T) { 2426 testenv.MustHaveExternalNetwork(t) 2427 2428 tg := testgo(t) 2429 defer tg.cleanup() 2430 tg.makeTempdir() 2431 tg.setenv("GOPATH", tg.path(".")) 2432 2433 const repo = "github.com/golang/example" 2434 2435 // Clone the repo via HTTP manually. 2436 cmd := exec.Command("git", "clone", "-q", "http://"+repo, tg.path("src/"+repo)) 2437 if out, err := cmd.CombinedOutput(); err != nil { 2438 t.Fatalf("cloning %v repo: %v\n%s", repo, err, out) 2439 } 2440 2441 // Update without -insecure should fail. 2442 // Update with -insecure should succeed. 2443 // We need -f to ignore import comments. 2444 const pkg = repo + "/hello" 2445 tg.runFail("get", "-d", "-u", "-f", pkg) 2446 tg.run("get", "-d", "-u", "-f", "-insecure", pkg) 2447 } 2448 2449 func TestGoGetInsecureCustomDomain(t *testing.T) { 2450 testenv.MustHaveExternalNetwork(t) 2451 2452 tg := testgo(t) 2453 defer tg.cleanup() 2454 tg.makeTempdir() 2455 tg.setenv("GOPATH", tg.path(".")) 2456 2457 const repo = "wh3rd.net/repo" 2458 tg.runFail("get", "-d", repo) 2459 tg.run("get", "-d", "-insecure", repo) 2460 } 2461 2462 func TestGoRunDirs(t *testing.T) { 2463 tg := testgo(t) 2464 defer tg.cleanup() 2465 tg.cd("testdata/rundir") 2466 tg.runFail("run", "x.go", "sub/sub.go") 2467 tg.grepStderr("named files must all be in one directory; have ./ and sub/", "wrong output") 2468 tg.runFail("run", "sub/sub.go", "x.go") 2469 tg.grepStderr("named files must all be in one directory; have sub/ and ./", "wrong output") 2470 } 2471 2472 func TestGoInstallPkgdir(t *testing.T) { 2473 tg := testgo(t) 2474 defer tg.cleanup() 2475 tg.makeTempdir() 2476 pkg := tg.path(".") 2477 tg.run("install", "-pkgdir", pkg, "errors") 2478 _, err := os.Stat(filepath.Join(pkg, "errors.a")) 2479 tg.must(err) 2480 _, err = os.Stat(filepath.Join(pkg, "runtime.a")) 2481 tg.must(err) 2482 } 2483 2484 func TestGoTestRaceInstallCgo(t *testing.T) { 2485 switch sys := runtime.GOOS + "/" + runtime.GOARCH; sys { 2486 case "darwin/amd64", "freebsd/amd64", "linux/amd64", "windows/amd64": 2487 // ok 2488 default: 2489 t.Skip("no race detector on %s", sys) 2490 } 2491 2492 if !build.Default.CgoEnabled { 2493 t.Skip("no race detector without cgo") 2494 } 2495 2496 // golang.org/issue/10500. 2497 // This used to install a race-enabled cgo. 2498 tg := testgo(t) 2499 defer tg.cleanup() 2500 tg.run("tool", "-n", "cgo") 2501 cgo := strings.TrimSpace(tg.stdout.String()) 2502 old, err := os.Stat(cgo) 2503 tg.must(err) 2504 tg.run("test", "-race", "-i", "runtime/race") 2505 new, err := os.Stat(cgo) 2506 tg.must(err) 2507 if new.ModTime() != old.ModTime() { 2508 t.Fatalf("go test -i runtime/race reinstalled cmd/cgo") 2509 } 2510 } 2511 2512 func TestGoTestImportErrorStack(t *testing.T) { 2513 const out = `package testdep/p1 (test) 2514 imports testdep/p2 2515 imports testdep/p3: no buildable Go source files` 2516 2517 tg := testgo(t) 2518 defer tg.cleanup() 2519 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 2520 tg.runFail("test", "testdep/p1") 2521 if !strings.Contains(tg.stderr.String(), out) { 2522 t.Fatalf("did not give full import stack:\n\n%s", tg.stderr.String()) 2523 } 2524 } 2525 2526 func TestGoGetUpdate(t *testing.T) { 2527 // golang.org/issue/9224. 2528 // The recursive updating was trying to walk to 2529 // former dependencies, not current ones. 2530 2531 testenv.MustHaveExternalNetwork(t) 2532 2533 tg := testgo(t) 2534 defer tg.cleanup() 2535 tg.makeTempdir() 2536 tg.setenv("GOPATH", tg.path(".")) 2537 2538 rewind := func() { 2539 tg.run("get", "github.com/rsc/go-get-issue-9224-cmd") 2540 cmd := exec.Command("git", "reset", "--hard", "HEAD~") 2541 cmd.Dir = tg.path("src/github.com/rsc/go-get-issue-9224-lib") 2542 out, err := cmd.CombinedOutput() 2543 if err != nil { 2544 t.Fatalf("git: %v\n%s", err, out) 2545 } 2546 } 2547 2548 rewind() 2549 tg.run("get", "-u", "github.com/rsc/go-get-issue-9224-cmd") 2550 2551 // Again with -d -u. 2552 rewind() 2553 tg.run("get", "-d", "-u", "github.com/rsc/go-get-issue-9224-cmd") 2554 } 2555 2556 func TestGoGetDomainRoot(t *testing.T) { 2557 // golang.org/issue/9357. 2558 // go get foo.io (not foo.io/subdir) was not working consistently. 2559 2560 testenv.MustHaveExternalNetwork(t) 2561 2562 tg := testgo(t) 2563 defer tg.cleanup() 2564 tg.makeTempdir() 2565 tg.setenv("GOPATH", tg.path(".")) 2566 2567 // go-get-issue-9357.appspot.com is running 2568 // the code at github.com/rsc/go-get-issue-9357, 2569 // a trivial Go on App Engine app that serves a 2570 // <meta> tag for the domain root. 2571 tg.run("get", "-d", "go-get-issue-9357.appspot.com") 2572 tg.run("get", "go-get-issue-9357.appspot.com") 2573 tg.run("get", "-u", "go-get-issue-9357.appspot.com") 2574 2575 tg.must(os.RemoveAll(tg.path("src/go-get-issue-9357.appspot.com"))) 2576 tg.run("get", "go-get-issue-9357.appspot.com") 2577 2578 tg.must(os.RemoveAll(tg.path("src/go-get-issue-9357.appspot.com"))) 2579 tg.run("get", "-u", "go-get-issue-9357.appspot.com") 2580 } 2581 2582 func TestGoInstallShadowedGOPATH(t *testing.T) { 2583 // golang.org/issue/3652. 2584 // go get foo.io (not foo.io/subdir) was not working consistently. 2585 2586 testenv.MustHaveExternalNetwork(t) 2587 2588 tg := testgo(t) 2589 defer tg.cleanup() 2590 tg.makeTempdir() 2591 tg.setenv("GOPATH", tg.path("gopath1")+string(filepath.ListSeparator)+tg.path("gopath2")) 2592 2593 tg.tempDir("gopath1/src/test") 2594 tg.tempDir("gopath2/src/test") 2595 tg.tempFile("gopath2/src/test/main.go", "package main\nfunc main(){}\n") 2596 2597 tg.cd(tg.path("gopath2/src/test")) 2598 tg.runFail("install") 2599 tg.grepStderr("no install location for.*gopath2.src.test: hidden by .*gopath1.src.test", "missing error") 2600 } 2601 2602 func TestGoBuildGOPATHOrder(t *testing.T) { 2603 // golang.org/issue/14176#issuecomment-179895769 2604 // golang.org/issue/14192 2605 // -I arguments to compiler could end up not in GOPATH order, 2606 // leading to unexpected import resolution in the compiler. 2607 // This is still not a complete fix (see golang.org/issue/14271 and next test) 2608 // but it is clearly OK and enough to fix both of the two reported 2609 // instances of the underlying problem. It will have to do for now. 2610 2611 tg := testgo(t) 2612 defer tg.cleanup() 2613 tg.makeTempdir() 2614 tg.setenv("GOPATH", tg.path("p1")+string(filepath.ListSeparator)+tg.path("p2")) 2615 2616 tg.tempFile("p1/src/foo/foo.go", "package foo\n") 2617 tg.tempFile("p2/src/baz/baz.go", "package baz\n") 2618 tg.tempFile("p2/pkg/"+runtime.GOOS+"_"+runtime.GOARCH+"/foo.a", "bad\n") 2619 tg.tempFile("p1/src/bar/bar.go", ` 2620 package bar 2621 import _ "baz" 2622 import _ "foo" 2623 `) 2624 2625 tg.run("install", "-x", "bar") 2626 } 2627 2628 func TestGoBuildGOPATHOrderBroken(t *testing.T) { 2629 // This test is known not to work. 2630 // See golang.org/issue/14271. 2631 t.Skip("golang.org/issue/14271") 2632 2633 tg := testgo(t) 2634 defer tg.cleanup() 2635 tg.makeTempdir() 2636 2637 tg.tempFile("p1/src/foo/foo.go", "package foo\n") 2638 tg.tempFile("p2/src/baz/baz.go", "package baz\n") 2639 tg.tempFile("p1/pkg/"+runtime.GOOS+"_"+runtime.GOARCH+"/baz.a", "bad\n") 2640 tg.tempFile("p2/pkg/"+runtime.GOOS+"_"+runtime.GOARCH+"/foo.a", "bad\n") 2641 tg.tempFile("p1/src/bar/bar.go", ` 2642 package bar 2643 import _ "baz" 2644 import _ "foo" 2645 `) 2646 2647 colon := string(filepath.ListSeparator) 2648 tg.setenv("GOPATH", tg.path("p1")+colon+tg.path("p2")) 2649 tg.run("install", "-x", "bar") 2650 2651 tg.setenv("GOPATH", tg.path("p2")+colon+tg.path("p1")) 2652 tg.run("install", "-x", "bar") 2653 } 2654 2655 func TestIssue11709(t *testing.T) { 2656 tg := testgo(t) 2657 defer tg.cleanup() 2658 tg.tempFile("run.go", ` 2659 package main 2660 import "os" 2661 func main() { 2662 if os.Getenv("TERM") != "" { 2663 os.Exit(1) 2664 } 2665 }`) 2666 tg.unsetenv("TERM") 2667 tg.run("run", tg.path("run.go")) 2668 } 2669 2670 func TestIssue12096(t *testing.T) { 2671 tg := testgo(t) 2672 defer tg.cleanup() 2673 tg.tempFile("test_test.go", ` 2674 package main 2675 import ("os"; "testing") 2676 func TestEnv(t *testing.T) { 2677 if os.Getenv("TERM") != "" { 2678 t.Fatal("TERM is set") 2679 } 2680 }`) 2681 tg.unsetenv("TERM") 2682 tg.run("test", tg.path("test_test.go")) 2683 } 2684 2685 func TestGoBuildOutput(t *testing.T) { 2686 tg := testgo(t) 2687 defer tg.cleanup() 2688 2689 tg.makeTempdir() 2690 tg.cd(tg.path(".")) 2691 2692 nonExeSuffix := ".exe" 2693 if exeSuffix == ".exe" { 2694 nonExeSuffix = "" 2695 } 2696 2697 tg.tempFile("x.go", "package main\nfunc main(){}\n") 2698 tg.run("build", "x.go") 2699 tg.wantExecutable("x"+exeSuffix, "go build x.go did not write x"+exeSuffix) 2700 tg.must(os.Remove(tg.path("x" + exeSuffix))) 2701 tg.mustNotExist("x" + nonExeSuffix) 2702 2703 tg.run("build", "-o", "myprog", "x.go") 2704 tg.mustNotExist("x") 2705 tg.mustNotExist("x.exe") 2706 tg.wantExecutable("myprog", "go build -o myprog x.go did not write myprog") 2707 tg.mustNotExist("myprog.exe") 2708 2709 tg.tempFile("p.go", "package p\n") 2710 tg.run("build", "p.go") 2711 tg.mustNotExist("p") 2712 tg.mustNotExist("p.a") 2713 tg.mustNotExist("p.o") 2714 tg.mustNotExist("p.exe") 2715 2716 tg.run("build", "-o", "p.a", "p.go") 2717 tg.wantArchive("p.a") 2718 2719 tg.run("build", "cmd/gofmt") 2720 tg.wantExecutable("gofmt"+exeSuffix, "go build cmd/gofmt did not write gofmt"+exeSuffix) 2721 tg.must(os.Remove(tg.path("gofmt" + exeSuffix))) 2722 tg.mustNotExist("gofmt" + nonExeSuffix) 2723 2724 tg.run("build", "-o", "mygofmt", "cmd/gofmt") 2725 tg.wantExecutable("mygofmt", "go build -o mygofmt cmd/gofmt did not write mygofmt") 2726 tg.mustNotExist("mygofmt.exe") 2727 tg.mustNotExist("gofmt") 2728 tg.mustNotExist("gofmt.exe") 2729 2730 tg.run("build", "sync/atomic") 2731 tg.mustNotExist("atomic") 2732 tg.mustNotExist("atomic.exe") 2733 2734 tg.run("build", "-o", "myatomic.a", "sync/atomic") 2735 tg.wantArchive("myatomic.a") 2736 tg.mustNotExist("atomic") 2737 tg.mustNotExist("atomic.a") 2738 tg.mustNotExist("atomic.exe") 2739 2740 tg.runFail("build", "-o", "whatever", "cmd/gofmt", "sync/atomic") 2741 tg.grepStderr("multiple packages", "did not reject -o with multiple packages") 2742 } 2743 2744 func TestGoBuildARM(t *testing.T) { 2745 if testing.Short() { 2746 t.Skip("skipping cross-compile in short mode") 2747 } 2748 2749 tg := testgo(t) 2750 defer tg.cleanup() 2751 2752 tg.makeTempdir() 2753 tg.cd(tg.path(".")) 2754 2755 tg.setenv("GOARCH", "arm") 2756 tg.setenv("GOOS", "linux") 2757 tg.setenv("GOARM", "5") 2758 tg.tempFile("hello.go", `package main 2759 func main() {}`) 2760 tg.run("build", "hello.go") 2761 tg.grepStderrNot("unable to find math.a", "did not build math.a correctly") 2762 } 2763 2764 func TestIssue13655(t *testing.T) { 2765 tg := testgo(t) 2766 defer tg.cleanup() 2767 for _, pkg := range []string{"runtime", "runtime/internal/atomic"} { 2768 tg.run("list", "-f", "{{.Deps}}", pkg) 2769 tg.grepStdout("runtime/internal/sys", "did not find required dependency of "+pkg+" on runtime/internal/sys") 2770 } 2771 } 2772 2773 // For issue 14337. 2774 func TestParallelTest(t *testing.T) { 2775 tg := testgo(t) 2776 defer tg.cleanup() 2777 tg.makeTempdir() 2778 const testSrc = `package package_test 2779 import ( 2780 "testing" 2781 ) 2782 func TestTest(t *testing.T) { 2783 }` 2784 tg.tempFile("src/p1/p1_test.go", strings.Replace(testSrc, "package_test", "p1_test", 1)) 2785 tg.tempFile("src/p2/p2_test.go", strings.Replace(testSrc, "package_test", "p2_test", 1)) 2786 tg.tempFile("src/p3/p3_test.go", strings.Replace(testSrc, "package_test", "p3_test", 1)) 2787 tg.tempFile("src/p4/p4_test.go", strings.Replace(testSrc, "package_test", "p4_test", 1)) 2788 tg.setenv("GOPATH", tg.path(".")) 2789 tg.run("test", "-p=4", "p1", "p2", "p3", "p4") 2790 } 2791 2792 func TestCgoConsistentResults(t *testing.T) { 2793 if !canCgo { 2794 t.Skip("skipping because cgo not enabled") 2795 } 2796 if runtime.GOOS == "solaris" { 2797 // See https://golang.org/issue/13247 2798 t.Skip("skipping because Solaris builds are known to be inconsistent; see #13247") 2799 } 2800 2801 tg := testgo(t) 2802 defer tg.cleanup() 2803 tg.parallel() 2804 tg.makeTempdir() 2805 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 2806 exe1 := tg.path("cgotest1" + exeSuffix) 2807 exe2 := tg.path("cgotest2" + exeSuffix) 2808 tg.run("build", "-o", exe1, "cgotest") 2809 tg.run("build", "-x", "-o", exe2, "cgotest") 2810 b1, err := ioutil.ReadFile(exe1) 2811 tg.must(err) 2812 b2, err := ioutil.ReadFile(exe2) 2813 tg.must(err) 2814 2815 if !tg.doGrepMatch(`-fdebug-prefix-map=\$WORK`, &tg.stderr) { 2816 t.Skip("skipping because C compiler does not support -fdebug-prefix-map") 2817 } 2818 if !bytes.Equal(b1, b2) { 2819 t.Error("building cgotest twice did not produce the same output") 2820 } 2821 } 2822 2823 // Issue 14444: go get -u .../ duplicate loads errors 2824 func TestGoGetUpdateAllDoesNotTryToLoadDuplicates(t *testing.T) { 2825 testenv.MustHaveExternalNetwork(t) 2826 2827 tg := testgo(t) 2828 defer tg.cleanup() 2829 tg.makeTempdir() 2830 tg.setenv("GOPATH", tg.path(".")) 2831 tg.run("get", "-u", ".../") 2832 tg.grepStderrNot("duplicate loads of", "did not remove old packages from cache") 2833 } 2834 2835 func TestFatalInBenchmarkCauseNonZeroExitStatus(t *testing.T) { 2836 tg := testgo(t) 2837 defer tg.cleanup() 2838 tg.runFail("test", "-bench", ".", "./testdata/src/benchfatal") 2839 tg.grepBothNot("^ok", "test passed unexpectedly") 2840 tg.grepBoth("FAIL.*benchfatal", "test did not run everything") 2841 } 2842 2843 func TestBinaryOnlyPackages(t *testing.T) { 2844 tg := testgo(t) 2845 defer tg.cleanup() 2846 tg.makeTempdir() 2847 tg.setenv("GOPATH", tg.path(".")) 2848 2849 tg.tempFile("src/p1/p1.go", `//go:binary-only-package 2850 2851 package p1 2852 `) 2853 tg.wantStale("p1", "cannot access install target", "p1 is binary-only but has no binary, should be stale") 2854 tg.runFail("install", "p1") 2855 tg.grepStderr("missing or invalid package binary", "did not report attempt to compile binary-only package") 2856 2857 tg.tempFile("src/p1/p1.go", ` 2858 package p1 2859 import "fmt" 2860 func F(b bool) { fmt.Printf("hello from p1\n"); if b { F(false) } } 2861 `) 2862 tg.run("install", "p1") 2863 os.Remove(tg.path("src/p1/p1.go")) 2864 tg.mustNotExist(tg.path("src/p1/p1.go")) 2865 2866 tg.tempFile("src/p2/p2.go", `//go:binary-only-packages-are-not-great 2867 2868 package p2 2869 import "p1" 2870 func F() { p1.F(true) } 2871 `) 2872 tg.runFail("install", "p2") 2873 tg.grepStderr("no buildable Go source files", "did not complain about missing sources") 2874 2875 tg.tempFile("src/p1/missing.go", `//go:binary-only-package 2876 2877 package p1 2878 func G() 2879 `) 2880 tg.wantNotStale("p1", "no source code", "should NOT want to rebuild p1 (first)") 2881 tg.run("install", "-x", "p1") // no-op, up to date 2882 tg.grepBothNot("/compile", "should not have run compiler") 2883 tg.run("install", "p2") // does not rebuild p1 (or else p2 will fail) 2884 tg.wantNotStale("p2", "", "should NOT want to rebuild p2") 2885 2886 // changes to the non-source-code do not matter, 2887 // and only one file needs the special comment. 2888 tg.tempFile("src/p1/missing2.go", ` 2889 package p1 2890 func H() 2891 `) 2892 tg.wantNotStale("p1", "no source code", "should NOT want to rebuild p1 (second)") 2893 tg.wantNotStale("p2", "", "should NOT want to rebuild p2") 2894 2895 tg.tempFile("src/p3/p3.go", ` 2896 package main 2897 import ( 2898 "p1" 2899 "p2" 2900 ) 2901 func main() { 2902 p1.F(false) 2903 p2.F() 2904 } 2905 `) 2906 tg.run("install", "p3") 2907 2908 tg.run("run", tg.path("src/p3/p3.go")) 2909 tg.grepStdout("hello from p1", "did not see message from p1") 2910 } 2911 2912 // Issue 16050. 2913 func TestAlwaysLinkSysoFiles(t *testing.T) { 2914 tg := testgo(t) 2915 defer tg.cleanup() 2916 tg.parallel() 2917 tg.tempDir("src/syso") 2918 tg.tempFile("src/syso/a.syso", ``) 2919 tg.tempFile("src/syso/b.go", `package syso`) 2920 tg.setenv("GOPATH", tg.path(".")) 2921 2922 // We should see the .syso file regardless of the setting of 2923 // CGO_ENABLED. 2924 2925 tg.setenv("CGO_ENABLED", "1") 2926 tg.run("list", "-f", "{{.SysoFiles}}", "syso") 2927 tg.grepStdout("a.syso", "missing syso file with CGO_ENABLED=1") 2928 2929 tg.setenv("CGO_ENABLED", "0") 2930 tg.run("list", "-f", "{{.SysoFiles}}", "syso") 2931 tg.grepStdout("a.syso", "missing syso file with CGO_ENABLED=0") 2932 } 2933 2934 // Issue 16120. 2935 func TestGenerateUsesBuildContext(t *testing.T) { 2936 if runtime.GOOS == "windows" { 2937 t.Skip("this test won't run under Windows") 2938 } 2939 2940 tg := testgo(t) 2941 defer tg.cleanup() 2942 tg.parallel() 2943 tg.tempDir("src/gen") 2944 tg.tempFile("src/gen/gen.go", "package gen\n//go:generate echo $GOOS $GOARCH\n") 2945 tg.setenv("GOPATH", tg.path(".")) 2946 2947 tg.setenv("GOOS", "linux") 2948 tg.setenv("GOARCH", "amd64") 2949 tg.run("generate", "gen") 2950 tg.grepStdout("linux amd64", "unexpected GOOS/GOARCH combination") 2951 2952 tg.setenv("GOOS", "darwin") 2953 tg.setenv("GOARCH", "386") 2954 tg.run("generate", "gen") 2955 tg.grepStdout("darwin 386", "unexpected GOOS/GOARCH combination") 2956 }