github.com/fsouza/go@v0.0.0-20160225033436-e14546fefa5e/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 // grepCountStdout returns the number of times a regexp is seen in 425 // standard output. 426 func (tg *testgoData) grepCountStdout(match string) int { 427 return tg.doGrepCount(match, &tg.stdout) 428 } 429 430 // grepCountStderr returns the number of times a regexp is seen in 431 // standard error. 432 func (tg *testgoData) grepCountStderr(match string) int { 433 return tg.doGrepCount(match, &tg.stderr) 434 } 435 436 // grepCountBoth returns the number of times a regexp is seen in both 437 // standard output and standard error. 438 func (tg *testgoData) grepCountBoth(match string) int { 439 return tg.doGrepCount(match, &tg.stdout) + tg.doGrepCount(match, &tg.stderr) 440 } 441 442 // creatingTemp records that the test plans to create a temporary file 443 // or directory. If the file or directory exists already, it will be 444 // removed. When the test completes, the file or directory will be 445 // removed if it exists. 446 func (tg *testgoData) creatingTemp(path string) { 447 if filepath.IsAbs(path) && !strings.HasPrefix(path, tg.tempdir) { 448 tg.t.Fatalf("internal testsuite error: creatingTemp(%q) with absolute path not in temporary directory", path) 449 } 450 // If we have changed the working directory, make sure we have 451 // an absolute path, because we are going to change directory 452 // back before we remove the temporary. 453 if tg.wd != "" && !filepath.IsAbs(path) { 454 path = filepath.Join(tg.pwd(), path) 455 } 456 tg.must(os.RemoveAll(path)) 457 tg.temps = append(tg.temps, path) 458 } 459 460 // makeTempdir makes a temporary directory for a run of testgo. If 461 // the temporary directory was already created, this does nothing. 462 func (tg *testgoData) makeTempdir() { 463 if tg.tempdir == "" { 464 var err error 465 tg.tempdir, err = ioutil.TempDir("", "gotest") 466 tg.must(err) 467 } 468 } 469 470 // tempFile adds a temporary file for a run of testgo. 471 func (tg *testgoData) tempFile(path, contents string) { 472 tg.makeTempdir() 473 tg.must(os.MkdirAll(filepath.Join(tg.tempdir, filepath.Dir(path)), 0755)) 474 bytes := []byte(contents) 475 if strings.HasSuffix(path, ".go") { 476 formatted, err := format.Source(bytes) 477 if err == nil { 478 bytes = formatted 479 } 480 } 481 tg.must(ioutil.WriteFile(filepath.Join(tg.tempdir, path), bytes, 0644)) 482 } 483 484 // tempDir adds a temporary directory for a run of testgo. 485 func (tg *testgoData) tempDir(path string) { 486 tg.makeTempdir() 487 if err := os.MkdirAll(filepath.Join(tg.tempdir, path), 0755); err != nil && !os.IsExist(err) { 488 tg.t.Fatal(err) 489 } 490 } 491 492 // path returns the absolute pathname to file with the temporary 493 // directory. 494 func (tg *testgoData) path(name string) string { 495 if tg.tempdir == "" { 496 tg.t.Fatalf("internal testsuite error: path(%q) with no tempdir", name) 497 } 498 if name == "." { 499 return tg.tempdir 500 } 501 return filepath.Join(tg.tempdir, name) 502 } 503 504 // mustNotExist fails if path exists. 505 func (tg *testgoData) mustNotExist(path string) { 506 if _, err := os.Stat(path); err == nil || !os.IsNotExist(err) { 507 tg.t.Fatalf("%s exists but should not (%v)", path, err) 508 } 509 } 510 511 // wantExecutable fails with msg if path is not executable. 512 func (tg *testgoData) wantExecutable(path, msg string) { 513 if st, err := os.Stat(path); err != nil { 514 if !os.IsNotExist(err) { 515 tg.t.Log(err) 516 } 517 tg.t.Fatal(msg) 518 } else { 519 if runtime.GOOS != "windows" && st.Mode()&0111 == 0 { 520 tg.t.Fatalf("binary %s exists but is not executable", path) 521 } 522 } 523 } 524 525 // wantArchive fails if path is not an archive. 526 func (tg *testgoData) wantArchive(path string) { 527 f, err := os.Open(path) 528 if err != nil { 529 tg.t.Fatal(err) 530 } 531 buf := make([]byte, 100) 532 io.ReadFull(f, buf) 533 f.Close() 534 if !bytes.HasPrefix(buf, []byte("!<arch>\n")) { 535 tg.t.Fatalf("file %s exists but is not an archive", path) 536 } 537 } 538 539 // isStale returns whether pkg is stale. 540 func (tg *testgoData) isStale(pkg string) bool { 541 tg.run("list", "-f", "{{.Stale}}", pkg) 542 switch v := strings.TrimSpace(tg.getStdout()); v { 543 case "true": 544 return true 545 case "false": 546 return false 547 default: 548 tg.t.Fatalf("unexpected output checking staleness of package %v: %v", pkg, v) 549 panic("unreachable") 550 } 551 } 552 553 // wantStale fails with msg if pkg is not stale. 554 func (tg *testgoData) wantStale(pkg, msg string) { 555 if !tg.isStale(pkg) { 556 tg.t.Fatal(msg) 557 } 558 } 559 560 // wantNotStale fails with msg if pkg is stale. 561 func (tg *testgoData) wantNotStale(pkg, msg string) { 562 if tg.isStale(pkg) { 563 tg.t.Fatal(msg) 564 } 565 } 566 567 // cleanup cleans up a test that runs testgo. 568 func (tg *testgoData) cleanup() { 569 if tg.wd != "" { 570 if err := os.Chdir(tg.wd); err != nil { 571 // We are unlikely to be able to continue. 572 fmt.Fprintln(os.Stderr, "could not restore working directory, crashing:", err) 573 os.Exit(2) 574 } 575 } 576 for _, path := range tg.temps { 577 tg.check(os.RemoveAll(path)) 578 } 579 if tg.tempdir != "" { 580 tg.check(os.RemoveAll(tg.tempdir)) 581 } 582 } 583 584 // resetReadOnlyFlagAll resets windows read-only flag 585 // set on path and any children it contains. 586 // The flag is set by git and has to be removed. 587 // os.Remove refuses to remove files with read-only flag set. 588 func (tg *testgoData) resetReadOnlyFlagAll(path string) { 589 fi, err := os.Stat(path) 590 if err != nil { 591 tg.t.Fatalf("resetReadOnlyFlagAll(%q) failed: %v", path, err) 592 } 593 if !fi.IsDir() { 594 err := os.Chmod(path, 0666) 595 if err != nil { 596 tg.t.Fatalf("resetReadOnlyFlagAll(%q) failed: %v", path, err) 597 } 598 } 599 fd, err := os.Open(path) 600 if err != nil { 601 tg.t.Fatalf("resetReadOnlyFlagAll(%q) failed: %v", path, err) 602 } 603 defer fd.Close() 604 names, _ := fd.Readdirnames(-1) 605 for _, name := range names { 606 tg.resetReadOnlyFlagAll(path + string(filepath.Separator) + name) 607 } 608 } 609 610 // failSSH puts an ssh executable in the PATH that always fails. 611 // This is to stub out uses of ssh by go get. 612 func (tg *testgoData) failSSH() { 613 wd, err := os.Getwd() 614 if err != nil { 615 tg.t.Fatal(err) 616 } 617 fail := filepath.Join(wd, "testdata/failssh") 618 tg.setenv("PATH", fmt.Sprintf("%v%c%v", fail, filepath.ListSeparator, os.Getenv("PATH"))) 619 } 620 621 func TestFileLineInErrorMessages(t *testing.T) { 622 tg := testgo(t) 623 defer tg.cleanup() 624 tg.parallel() 625 tg.tempFile("err.go", `package main; import "bar"`) 626 path := tg.path("err.go") 627 tg.runFail("run", path) 628 shortPath := path 629 if rel, err := filepath.Rel(tg.pwd(), path); err == nil && len(rel) < len(path) { 630 shortPath = rel 631 } 632 tg.grepStderr("^"+regexp.QuoteMeta(shortPath)+":", "missing file:line in error message") 633 } 634 635 func TestProgramNameInCrashMessages(t *testing.T) { 636 tg := testgo(t) 637 defer tg.cleanup() 638 tg.parallel() 639 tg.tempFile("triv.go", `package main; func main() {}`) 640 tg.runFail("build", "-ldflags", "-crash_for_testing", tg.path("triv.go")) 641 tg.grepStderr(`[/\\]tool[/\\].*[/\\]link`, "missing linker name in error message") 642 } 643 644 func TestBrokenTestsWithoutTestFunctionsAllFail(t *testing.T) { 645 tg := testgo(t) 646 defer tg.cleanup() 647 tg.runFail("test", "./testdata/src/badtest/...") 648 tg.grepBothNot("^ok", "test passed unexpectedly") 649 tg.grepBoth("FAIL.*badtest/badexec", "test did not run everything") 650 tg.grepBoth("FAIL.*badtest/badsyntax", "test did not run everything") 651 tg.grepBoth("FAIL.*badtest/badvar", "test did not run everything") 652 } 653 654 func TestGoBuildDashAInDevBranch(t *testing.T) { 655 if testing.Short() { 656 t.Skip("don't rebuild the standard library in short mode") 657 } 658 659 tg := testgo(t) 660 defer tg.cleanup() 661 tg.run("install", "math") // should be up to date already but just in case 662 tg.setenv("TESTGO_IS_GO_RELEASE", "0") 663 tg.run("build", "-v", "-a", "math") 664 tg.grepStderr("runtime", "testgo build -a math in dev branch DID NOT build runtime, but should have") 665 666 // Everything is out of date. Rebuild to leave things in a better state. 667 tg.run("install", "std") 668 } 669 670 func TestGoBuildDashAInReleaseBranch(t *testing.T) { 671 if testing.Short() { 672 t.Skip("don't rebuild the standard library in short mode") 673 } 674 675 tg := testgo(t) 676 defer tg.cleanup() 677 tg.run("install", "math", "net/http") // should be up to date already but just in case 678 tg.setenv("TESTGO_IS_GO_RELEASE", "1") 679 tg.run("install", "-v", "-a", "math") 680 tg.grepStderr("runtime", "testgo build -a math in release branch DID NOT build runtime, but should have") 681 682 // Now runtime.a is updated (newer mtime), so everything would look stale if not for being a release. 683 tg.run("build", "-v", "net/http") 684 tg.grepStderrNot("strconv", "testgo build -v net/http in release branch with newer runtime.a DID build strconv but should not have") 685 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") 686 tg.grepStderrNot("net/http", "testgo build -v net/http in release branch with newer runtime.a DID build net/http but should not have") 687 688 // Everything is out of date. Rebuild to leave things in a better state. 689 tg.run("install", "std") 690 } 691 692 func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) { 693 if testing.Short() { 694 t.Skip("don't rebuild the standard library in short mode") 695 } 696 697 tg := testgo(t) 698 defer tg.cleanup() 699 700 addNL := func(name string) (restore func()) { 701 data, err := ioutil.ReadFile(name) 702 if err != nil { 703 t.Fatal(err) 704 } 705 old := data 706 data = append(data, '\n') 707 if err := ioutil.WriteFile(name, append(data, '\n'), 0666); err != nil { 708 t.Fatal(err) 709 } 710 tg.sleep() 711 return func() { 712 if err := ioutil.WriteFile(name, old, 0666); err != nil { 713 t.Fatal(err) 714 } 715 } 716 } 717 718 tg.setenv("TESTGO_IS_GO_RELEASE", "1") 719 720 tg.tempFile("d1/src/p1/p1.go", `package p1`) 721 tg.setenv("GOPATH", tg.path("d1")) 722 tg.run("install", "-a", "p1") 723 tg.wantNotStale("p1", "./testgo list claims p1 is stale, incorrectly") 724 tg.sleep() 725 726 // Changing mtime and content of runtime/internal/sys/sys.go 727 // should have no effect: we're in a release, which doesn't rebuild 728 // for general mtime or content changes. 729 sys := runtime.GOROOT() + "/src/runtime/internal/sys/sys.go" 730 restore := addNL(sys) 731 defer restore() 732 tg.wantNotStale("p1", "./testgo list claims p1 is stale, incorrectly, after updating runtime/internal/sys/sys.go") 733 restore() 734 tg.wantNotStale("p1", "./testgo list claims p1 is stale, incorrectly, after restoring runtime/internal/sys/sys.go") 735 736 // But changing runtime/internal/sys/zversion.go should have an effect: 737 // that's how we tell when we flip from one release to another. 738 zversion := runtime.GOROOT() + "/src/runtime/internal/sys/zversion.go" 739 restore = addNL(zversion) 740 defer restore() 741 tg.wantStale("p1", "./testgo list claims p1 is NOT stale, incorrectly, after changing to new release") 742 restore() 743 tg.wantNotStale("p1", "./testgo list claims p1 is stale, incorrectly, after changing back to old release") 744 addNL(zversion) 745 tg.wantStale("p1", "./testgo list claims p1 is NOT stale, incorrectly, after changing again to new release") 746 tg.run("install", "p1") 747 tg.wantNotStale("p1", "./testgo list claims p1 is stale after building with new release") 748 749 // Restore to "old" release. 750 restore() 751 tg.wantStale("p1", "./testgo list claims p1 is NOT stale, incorrectly, after changing to old release after new build") 752 tg.run("install", "p1") 753 tg.wantNotStale("p1", "./testgo list claims p1 is stale after building with old release") 754 755 // Everything is out of date. Rebuild to leave things in a better state. 756 tg.run("install", "std") 757 } 758 759 func TestGoListStandard(t *testing.T) { 760 tg := testgo(t) 761 defer tg.cleanup() 762 tg.cd(runtime.GOROOT() + "/src") 763 tg.run("list", "-f", "{{if not .Standard}}{{.ImportPath}}{{end}}", "./...") 764 stdout := tg.getStdout() 765 for _, line := range strings.Split(stdout, "\n") { 766 if strings.HasPrefix(line, "_/") && strings.HasSuffix(line, "/src") { 767 // $GOROOT/src shows up if there are any .go files there. 768 // We don't care. 769 continue 770 } 771 if line == "" { 772 continue 773 } 774 t.Errorf("package in GOROOT not listed as standard: %v", line) 775 } 776 777 // Similarly, expanding std should include some of our vendored code. 778 tg.run("list", "std", "cmd") 779 tg.grepStdout("golang.org/x/net/http2/hpack", "list std cmd did not mention vendored hpack") 780 tg.grepStdout("golang.org/x/arch/x86/x86asm", "list std cmd did not mention vendored x86asm") 781 } 782 783 func TestGoInstallCleansUpAfterGoBuild(t *testing.T) { 784 tg := testgo(t) 785 defer tg.cleanup() 786 tg.tempFile("src/mycmd/main.go", `package main; func main(){}`) 787 tg.setenv("GOPATH", tg.path(".")) 788 tg.cd(tg.path("src/mycmd")) 789 790 doesNotExist := func(file, msg string) { 791 if _, err := os.Stat(file); err == nil { 792 t.Fatal(msg) 793 } else if !os.IsNotExist(err) { 794 t.Fatal(msg, "error:", err) 795 } 796 } 797 798 tg.run("build") 799 tg.wantExecutable("mycmd"+exeSuffix, "testgo build did not write command binary") 800 tg.run("install") 801 doesNotExist("mycmd"+exeSuffix, "testgo install did not remove command binary") 802 tg.run("build") 803 tg.wantExecutable("mycmd"+exeSuffix, "testgo build did not write command binary (second time)") 804 // Running install with arguments does not remove the target, 805 // even in the same directory. 806 tg.run("install", "mycmd") 807 tg.wantExecutable("mycmd"+exeSuffix, "testgo install mycmd removed command binary when run in mycmd") 808 tg.run("build") 809 tg.wantExecutable("mycmd"+exeSuffix, "testgo build did not write command binary (third time)") 810 // And especially not outside the directory. 811 tg.cd(tg.path(".")) 812 if data, err := ioutil.ReadFile("src/mycmd/mycmd" + exeSuffix); err != nil { 813 t.Fatal("could not read file:", err) 814 } else { 815 if err := ioutil.WriteFile("mycmd"+exeSuffix, data, 0555); err != nil { 816 t.Fatal("could not write file:", err) 817 } 818 } 819 tg.run("install", "mycmd") 820 tg.wantExecutable("src/mycmd/mycmd"+exeSuffix, "testgo install mycmd removed command binary from its source dir when run outside mycmd") 821 tg.wantExecutable("mycmd"+exeSuffix, "testgo install mycmd removed command binary from current dir when run outside mycmd") 822 } 823 824 func TestGoInstallRebuildsStalePackagesInOtherGOPATH(t *testing.T) { 825 tg := testgo(t) 826 defer tg.cleanup() 827 tg.parallel() 828 tg.tempFile("d1/src/p1/p1.go", `package p1 829 import "p2" 830 func F() { p2.F() }`) 831 tg.tempFile("d2/src/p2/p2.go", `package p2 832 func F() {}`) 833 sep := string(filepath.ListSeparator) 834 tg.setenv("GOPATH", tg.path("d1")+sep+tg.path("d2")) 835 tg.run("install", "p1") 836 tg.wantNotStale("p1", "./testgo list claims p1 is stale, incorrectly") 837 tg.wantNotStale("p2", "./testgo list claims p2 is stale, incorrectly") 838 tg.sleep() 839 if f, err := os.OpenFile(tg.path("d2/src/p2/p2.go"), os.O_WRONLY|os.O_APPEND, 0); err != nil { 840 t.Fatal(err) 841 } else if _, err = f.WriteString(`func G() {}`); err != nil { 842 t.Fatal(err) 843 } else { 844 tg.must(f.Close()) 845 } 846 tg.wantStale("p2", "./testgo list claims p2 is NOT stale, incorrectly") 847 tg.wantStale("p1", "./testgo list claims p1 is NOT stale, incorrectly") 848 849 tg.run("install", "p1") 850 tg.wantNotStale("p2", "./testgo list claims p2 is stale after reinstall, incorrectly") 851 tg.wantNotStale("p1", "./testgo list claims p1 is stale after reinstall, incorrectly") 852 } 853 854 func TestGoInstallDetectsRemovedFiles(t *testing.T) { 855 tg := testgo(t) 856 defer tg.cleanup() 857 tg.parallel() 858 tg.tempFile("src/mypkg/x.go", `package mypkg`) 859 tg.tempFile("src/mypkg/y.go", `package mypkg`) 860 tg.tempFile("src/mypkg/z.go", `// +build missingtag 861 862 package mypkg`) 863 tg.setenv("GOPATH", tg.path(".")) 864 tg.run("install", "mypkg") 865 tg.wantNotStale("mypkg", "./testgo list mypkg claims mypkg is stale, incorrectly") 866 // z.go was not part of the build; removing it is okay. 867 tg.must(os.Remove(tg.path("src/mypkg/z.go"))) 868 tg.wantNotStale("mypkg", "./testgo list mypkg claims mypkg is stale after removing z.go; should not be stale") 869 // y.go was part of the package; removing it should be detected. 870 tg.must(os.Remove(tg.path("src/mypkg/y.go"))) 871 tg.wantStale("mypkg", "./testgo list mypkg claims mypkg is NOT stale after removing y.go; should be stale") 872 } 873 874 func TestWildcardMatchesSyntaxErrorDirs(t *testing.T) { 875 tg := testgo(t) 876 defer tg.cleanup() 877 tg.tempFile("src/mypkg/x.go", `package mypkg`) 878 tg.tempFile("src/mypkg/y.go", `pkg mypackage`) 879 tg.setenv("GOPATH", tg.path(".")) 880 tg.cd(tg.path("src/mypkg")) 881 tg.runFail("list", "./...") 882 tg.runFail("build", "./...") 883 tg.runFail("install", "./...") 884 } 885 886 func TestGoListWithTags(t *testing.T) { 887 tg := testgo(t) 888 defer tg.cleanup() 889 tg.tempFile("src/mypkg/x.go", "// +build thetag\n\npackage mypkg\n") 890 tg.setenv("GOPATH", tg.path(".")) 891 tg.cd(tg.path("./src")) 892 tg.run("list", "-tags=thetag", "./my...") 893 tg.grepStdout("mypkg", "did not find mypkg") 894 } 895 896 func TestGoInstallErrorOnCrossCompileToBin(t *testing.T) { 897 if testing.Short() { 898 t.Skip("don't install into GOROOT in short mode") 899 } 900 901 tg := testgo(t) 902 defer tg.cleanup() 903 tg.tempFile("src/mycmd/x.go", `package main 904 func main() {}`) 905 tg.setenv("GOPATH", tg.path(".")) 906 tg.cd(tg.path("src/mycmd")) 907 908 tg.run("build", "mycmd") 909 910 goarch := "386" 911 if runtime.GOARCH == "386" { 912 goarch = "amd64" 913 } 914 tg.setenv("GOOS", "linux") 915 tg.setenv("GOARCH", goarch) 916 tg.run("install", "mycmd") 917 tg.setenv("GOBIN", tg.path(".")) 918 tg.runFail("install", "mycmd") 919 tg.run("install", "cmd/pack") 920 } 921 922 func TestGoInstallDetectsRemovedFilesInPackageMain(t *testing.T) { 923 tg := testgo(t) 924 defer tg.cleanup() 925 tg.parallel() 926 tg.tempFile("src/mycmd/x.go", `package main 927 func main() {}`) 928 tg.tempFile("src/mycmd/y.go", `package main`) 929 tg.tempFile("src/mycmd/z.go", `// +build missingtag 930 931 package main`) 932 tg.setenv("GOPATH", tg.path(".")) 933 tg.run("install", "mycmd") 934 tg.wantNotStale("mycmd", "./testgo list mypkg claims mycmd is stale, incorrectly") 935 // z.go was not part of the build; removing it is okay. 936 tg.must(os.Remove(tg.path("src/mycmd/z.go"))) 937 tg.wantNotStale("mycmd", "./testgo list mycmd claims mycmd is stale after removing z.go; should not be stale") 938 // y.go was part of the package; removing it should be detected. 939 tg.must(os.Remove(tg.path("src/mycmd/y.go"))) 940 tg.wantStale("mycmd", "./testgo list mycmd claims mycmd is NOT stale after removing y.go; should be stale") 941 } 942 943 func testLocalRun(tg *testgoData, exepath, local, match string) { 944 out, err := exec.Command(exepath).Output() 945 if err != nil { 946 tg.t.Fatalf("error running %v: %v", exepath, err) 947 } 948 if !regexp.MustCompile(match).Match(out) { 949 tg.t.Log(string(out)) 950 tg.t.Errorf("testdata/%s/easy.go did not generate expected output", local) 951 } 952 } 953 954 func testLocalEasy(tg *testgoData, local string) { 955 exepath := "./easy" + exeSuffix 956 tg.creatingTemp(exepath) 957 tg.run("build", "-o", exepath, filepath.Join("testdata", local, "easy.go")) 958 testLocalRun(tg, exepath, local, `(?m)^easysub\.Hello`) 959 } 960 961 func testLocalEasySub(tg *testgoData, local string) { 962 exepath := "./easysub" + exeSuffix 963 tg.creatingTemp(exepath) 964 tg.run("build", "-o", exepath, filepath.Join("testdata", local, "easysub", "main.go")) 965 testLocalRun(tg, exepath, local, `(?m)^easysub\.Hello`) 966 } 967 968 func testLocalHard(tg *testgoData, local string) { 969 exepath := "./hard" + exeSuffix 970 tg.creatingTemp(exepath) 971 tg.run("build", "-o", exepath, filepath.Join("testdata", local, "hard.go")) 972 testLocalRun(tg, exepath, local, `(?m)^sub\.Hello`) 973 } 974 975 func testLocalInstall(tg *testgoData, local string) { 976 tg.runFail("install", filepath.Join("testdata", local, "easy.go")) 977 } 978 979 func TestLocalImportsEasy(t *testing.T) { 980 tg := testgo(t) 981 defer tg.cleanup() 982 testLocalEasy(tg, "local") 983 } 984 985 func TestLocalImportsEasySub(t *testing.T) { 986 tg := testgo(t) 987 defer tg.cleanup() 988 testLocalEasySub(tg, "local") 989 } 990 991 func TestLocalImportsHard(t *testing.T) { 992 tg := testgo(t) 993 defer tg.cleanup() 994 testLocalHard(tg, "local") 995 } 996 997 func TestLocalImportsGoInstallShouldFail(t *testing.T) { 998 tg := testgo(t) 999 defer tg.cleanup() 1000 testLocalInstall(tg, "local") 1001 } 1002 1003 const badDirName = `#$%:, &()*;<=>?\^{}` 1004 1005 func copyBad(tg *testgoData) { 1006 if runtime.GOOS == "windows" { 1007 tg.t.Skipf("skipping test because %q is an invalid directory name", badDirName) 1008 } 1009 1010 tg.must(filepath.Walk("testdata/local", 1011 func(path string, info os.FileInfo, err error) error { 1012 if err != nil { 1013 return err 1014 } 1015 if info.IsDir() { 1016 return nil 1017 } 1018 var data []byte 1019 data, err = ioutil.ReadFile(path) 1020 if err != nil { 1021 return err 1022 } 1023 newpath := strings.Replace(path, "local", badDirName, 1) 1024 tg.tempFile(newpath, string(data)) 1025 return nil 1026 })) 1027 tg.cd(tg.path(".")) 1028 } 1029 1030 func TestBadImportsEasy(t *testing.T) { 1031 tg := testgo(t) 1032 defer tg.cleanup() 1033 copyBad(tg) 1034 testLocalEasy(tg, badDirName) 1035 } 1036 1037 func TestBadImportsEasySub(t *testing.T) { 1038 tg := testgo(t) 1039 defer tg.cleanup() 1040 copyBad(tg) 1041 testLocalEasySub(tg, badDirName) 1042 } 1043 1044 func TestBadImportsHard(t *testing.T) { 1045 tg := testgo(t) 1046 defer tg.cleanup() 1047 copyBad(tg) 1048 testLocalHard(tg, badDirName) 1049 } 1050 1051 func TestBadImportsGoInstallShouldFail(t *testing.T) { 1052 tg := testgo(t) 1053 defer tg.cleanup() 1054 copyBad(tg) 1055 testLocalInstall(tg, badDirName) 1056 } 1057 1058 func TestInternalPackagesInGOROOTAreRespected(t *testing.T) { 1059 tg := testgo(t) 1060 defer tg.cleanup() 1061 tg.runFail("build", "-v", "./testdata/testinternal") 1062 tg.grepBoth("use of internal package not allowed", "wrong error message for testdata/testinternal") 1063 } 1064 1065 func TestInternalPackagesOutsideGOROOTAreRespected(t *testing.T) { 1066 tg := testgo(t) 1067 defer tg.cleanup() 1068 tg.runFail("build", "-v", "./testdata/testinternal2") 1069 tg.grepBoth("use of internal package not allowed", "wrote error message for testdata/testinternal2") 1070 } 1071 1072 func TestRunInternal(t *testing.T) { 1073 tg := testgo(t) 1074 defer tg.cleanup() 1075 dir := filepath.Join(tg.pwd(), "testdata") 1076 tg.setenv("GOPATH", dir) 1077 tg.run("run", filepath.Join(dir, "src/run/good.go")) 1078 tg.runFail("run", filepath.Join(dir, "src/run/bad.go")) 1079 tg.grepStderr("use of internal package not allowed", "unexpected error for run/bad.go") 1080 } 1081 1082 func testMove(t *testing.T, vcs, url, base, config string) { 1083 testenv.MustHaveExternalNetwork(t) 1084 1085 tg := testgo(t) 1086 defer tg.cleanup() 1087 tg.parallel() 1088 tg.tempDir("src") 1089 tg.setenv("GOPATH", tg.path(".")) 1090 tg.run("get", "-d", url) 1091 tg.run("get", "-d", "-u", url) 1092 switch vcs { 1093 case "svn": 1094 // SVN doesn't believe in text files so we can't just edit the config. 1095 // Check out a different repo into the wrong place. 1096 tg.must(os.RemoveAll(tg.path("src/code.google.com/p/rsc-svn"))) 1097 tg.run("get", "-d", "-u", "code.google.com/p/rsc-svn2/trunk") 1098 tg.must(os.Rename(tg.path("src/code.google.com/p/rsc-svn2"), tg.path("src/code.google.com/p/rsc-svn"))) 1099 default: 1100 path := tg.path(filepath.Join("src", config)) 1101 data, err := ioutil.ReadFile(path) 1102 tg.must(err) 1103 data = bytes.Replace(data, []byte(base), []byte(base+"XXX"), -1) 1104 tg.must(ioutil.WriteFile(path, data, 0644)) 1105 } 1106 if vcs == "git" { 1107 // git will ask for a username and password when we 1108 // run go get -d -f -u. An empty username and 1109 // password will work. Prevent asking by setting 1110 // GIT_ASKPASS. 1111 tg.creatingTemp("sink" + exeSuffix) 1112 tg.tempFile("src/sink/sink.go", `package main; func main() {}`) 1113 tg.run("build", "-o", "sink"+exeSuffix, "sink") 1114 tg.setenv("GIT_ASKPASS", filepath.Join(tg.pwd(), "sink"+exeSuffix)) 1115 } 1116 tg.runFail("get", "-d", "-u", url) 1117 tg.grepStderr("is a custom import path for", "go get -d -u "+url+" failed for wrong reason") 1118 tg.runFail("get", "-d", "-f", "-u", url) 1119 tg.grepStderr("validating server certificate|not found", "go get -d -f -u "+url+" failed for wrong reason") 1120 } 1121 1122 func TestInternalPackageErrorsAreHandled(t *testing.T) { 1123 tg := testgo(t) 1124 defer tg.cleanup() 1125 tg.run("list", "./testdata/testinternal3") 1126 } 1127 1128 func TestInternalCache(t *testing.T) { 1129 tg := testgo(t) 1130 defer tg.cleanup() 1131 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/testinternal4")) 1132 tg.runFail("build", "p") 1133 tg.grepStderr("internal", "did not fail to build p") 1134 } 1135 1136 func TestMoveGit(t *testing.T) { 1137 testMove(t, "git", "rsc.io/pdf", "pdf", "rsc.io/pdf/.git/config") 1138 } 1139 1140 // TODO(rsc): Set up a test case on bitbucket for hg. 1141 // func TestMoveHG(t *testing.T) { 1142 // testMove(t, "hg", "rsc.io/x86/x86asm", "x86", "rsc.io/x86/.hg/hgrc") 1143 // } 1144 1145 // TODO(rsc): Set up a test case on SourceForge (?) for svn. 1146 // func testMoveSVN(t *testing.T) { 1147 // testMove(t, "svn", "code.google.com/p/rsc-svn/trunk", "-", "-") 1148 // } 1149 1150 func TestImportCommandMatch(t *testing.T) { 1151 tg := testgo(t) 1152 defer tg.cleanup() 1153 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcom")) 1154 tg.run("build", "./testdata/importcom/works.go") 1155 } 1156 1157 func TestImportCommentMismatch(t *testing.T) { 1158 tg := testgo(t) 1159 defer tg.cleanup() 1160 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcom")) 1161 tg.runFail("build", "./testdata/importcom/wrongplace.go") 1162 tg.grepStderr(`wrongplace expects import "my/x"`, "go build did not mention incorrect import") 1163 } 1164 1165 func TestImportCommentSyntaxError(t *testing.T) { 1166 tg := testgo(t) 1167 defer tg.cleanup() 1168 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcom")) 1169 tg.runFail("build", "./testdata/importcom/bad.go") 1170 tg.grepStderr("cannot parse import comment", "go build did not mention syntax error") 1171 } 1172 1173 func TestImportCommentConflict(t *testing.T) { 1174 tg := testgo(t) 1175 defer tg.cleanup() 1176 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/importcom")) 1177 tg.runFail("build", "./testdata/importcom/conflict.go") 1178 tg.grepStderr("found import comments", "go build did not mention comment conflict") 1179 } 1180 1181 // cmd/go: custom import path checking should not apply to github.com/xxx/yyy. 1182 func TestIssue10952(t *testing.T) { 1183 testenv.MustHaveExternalNetwork(t) 1184 if _, err := exec.LookPath("git"); err != nil { 1185 t.Skip("skipping because git binary not found") 1186 } 1187 1188 tg := testgo(t) 1189 defer tg.cleanup() 1190 tg.parallel() 1191 tg.tempDir("src") 1192 tg.setenv("GOPATH", tg.path(".")) 1193 const importPath = "github.com/zombiezen/go-get-issue-10952" 1194 tg.run("get", "-d", "-u", importPath) 1195 repoDir := tg.path("src/" + importPath) 1196 defer tg.resetReadOnlyFlagAll(repoDir) 1197 tg.runGit(repoDir, "remote", "set-url", "origin", "https://"+importPath+".git") 1198 tg.run("get", "-d", "-u", importPath) 1199 } 1200 1201 func TestGetGitDefaultBranch(t *testing.T) { 1202 testenv.MustHaveExternalNetwork(t) 1203 if _, err := exec.LookPath("git"); err != nil { 1204 t.Skip("skipping because git binary not found") 1205 } 1206 1207 tg := testgo(t) 1208 defer tg.cleanup() 1209 tg.parallel() 1210 tg.tempDir("src") 1211 tg.setenv("GOPATH", tg.path(".")) 1212 1213 // This repo has two branches, master and another-branch. 1214 // The another-branch is the default that you get from 'git clone'. 1215 // The go get command variants should not override this. 1216 const importPath = "github.com/rsc/go-get-default-branch" 1217 1218 tg.run("get", "-d", importPath) 1219 repoDir := tg.path("src/" + importPath) 1220 defer tg.resetReadOnlyFlagAll(repoDir) 1221 tg.runGit(repoDir, "branch", "--contains", "HEAD") 1222 tg.grepStdout(`\* another-branch`, "not on correct default branch") 1223 1224 tg.run("get", "-d", "-u", importPath) 1225 tg.runGit(repoDir, "branch", "--contains", "HEAD") 1226 tg.grepStdout(`\* another-branch`, "not on correct default branch") 1227 } 1228 1229 func TestDisallowedCSourceFiles(t *testing.T) { 1230 tg := testgo(t) 1231 defer tg.cleanup() 1232 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1233 tg.runFail("build", "badc") 1234 tg.grepStderr("C source files not allowed", "go test did not say C source files not allowed") 1235 } 1236 1237 func TestErrorMessageForSyntaxErrorInTestGoFileSaysFAIL(t *testing.T) { 1238 tg := testgo(t) 1239 defer tg.cleanup() 1240 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1241 tg.runFail("test", "syntaxerror") 1242 tg.grepStderr("FAIL", "go test did not say FAIL") 1243 } 1244 1245 func TestWildcardsDoNotLookInUselessDirectories(t *testing.T) { 1246 tg := testgo(t) 1247 defer tg.cleanup() 1248 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1249 tg.runFail("list", "...") 1250 tg.grepBoth("badpkg", "go list ... failure does not mention badpkg") 1251 tg.run("list", "m...") 1252 } 1253 1254 func TestRelativeImportsGoTest(t *testing.T) { 1255 tg := testgo(t) 1256 defer tg.cleanup() 1257 tg.run("test", "./testdata/testimport") 1258 } 1259 1260 func TestRelativeImportsGoTestDashI(t *testing.T) { 1261 tg := testgo(t) 1262 defer tg.cleanup() 1263 tg.run("test", "-i", "./testdata/testimport") 1264 } 1265 1266 func TestRelativeImportsInCommandLinePackage(t *testing.T) { 1267 tg := testgo(t) 1268 defer tg.cleanup() 1269 files, err := filepath.Glob("./testdata/testimport/*.go") 1270 tg.must(err) 1271 tg.run(append([]string{"test"}, files...)...) 1272 } 1273 1274 func TestVersionControlErrorMessageIncludesCorrectDirectory(t *testing.T) { 1275 tg := testgo(t) 1276 defer tg.cleanup() 1277 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/shadow/root1")) 1278 tg.runFail("get", "-u", "foo") 1279 1280 // TODO(iant): We should not have to use strconv.Quote here. 1281 // The code in vcs.go should be changed so that it is not required. 1282 quoted := strconv.Quote(filepath.Join("testdata", "shadow", "root1", "src", "foo")) 1283 quoted = quoted[1 : len(quoted)-1] 1284 1285 tg.grepStderr(regexp.QuoteMeta(quoted), "go get -u error does not mention shadow/root1/src/foo") 1286 } 1287 1288 func TestInstallFailsWithNoBuildableFiles(t *testing.T) { 1289 tg := testgo(t) 1290 defer tg.cleanup() 1291 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1292 tg.setenv("CGO_ENABLED", "0") 1293 tg.runFail("install", "cgotest") 1294 tg.grepStderr("no buildable Go source files", "go install cgotest did not report 'no buildable Go Source files'") 1295 } 1296 1297 func TestRelativeGOBINFail(t *testing.T) { 1298 tg := testgo(t) 1299 defer tg.cleanup() 1300 tg.tempFile("triv.go", `package main; func main() {}`) 1301 tg.setenv("GOBIN", ".") 1302 tg.runFail("install") 1303 tg.grepStderr("cannot install, GOBIN must be an absolute path", "go install must fail if $GOBIN is a relative path") 1304 } 1305 1306 // Test that without $GOBIN set, binaries get installed 1307 // into the GOPATH bin directory. 1308 func TestInstallIntoGOPATH(t *testing.T) { 1309 tg := testgo(t) 1310 defer tg.cleanup() 1311 tg.creatingTemp("testdata/bin/go-cmd-test" + exeSuffix) 1312 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1313 tg.run("install", "go-cmd-test") 1314 tg.wantExecutable("testdata/bin/go-cmd-test"+exeSuffix, "go install go-cmd-test did not write to testdata/bin/go-cmd-test") 1315 } 1316 1317 // Issue 12407 1318 func TestBuildOutputToDevNull(t *testing.T) { 1319 if runtime.GOOS == "plan9" { 1320 t.Skip("skipping because /dev/null is a regular file on plan9") 1321 } 1322 tg := testgo(t) 1323 defer tg.cleanup() 1324 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1325 tg.run("build", "-o", os.DevNull, "go-cmd-test") 1326 } 1327 1328 func TestPackageMainTestImportsArchiveNotBinary(t *testing.T) { 1329 tg := testgo(t) 1330 defer tg.cleanup() 1331 tg.parallel() 1332 gobin := filepath.Join(tg.pwd(), "testdata", "bin") 1333 tg.creatingTemp(gobin) 1334 tg.setenv("GOBIN", gobin) 1335 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1336 tg.must(os.Chtimes("./testdata/src/main_test/m.go", time.Now(), time.Now())) 1337 tg.sleep() 1338 tg.run("test", "main_test") 1339 tg.run("install", "main_test") 1340 tg.wantNotStale("main_test", "after go install, main listed as stale") 1341 tg.run("test", "main_test") 1342 } 1343 1344 // Issue 12690 1345 func TestPackageNotStaleWithTrailingSlash(t *testing.T) { 1346 tg := testgo(t) 1347 defer tg.cleanup() 1348 goroot := runtime.GOROOT() 1349 tg.setenv("GOROOT", goroot+"/") 1350 tg.wantNotStale("runtime", "with trailing slash in GOROOT, runtime listed as stale") 1351 tg.wantNotStale("os", "with trailing slash in GOROOT, os listed as stale") 1352 tg.wantNotStale("io", "with trailing slash in GOROOT, io listed as stale") 1353 } 1354 1355 // With $GOBIN set, binaries get installed to $GOBIN. 1356 func TestInstallIntoGOBIN(t *testing.T) { 1357 tg := testgo(t) 1358 defer tg.cleanup() 1359 gobin := filepath.Join(tg.pwd(), "testdata", "bin1") 1360 tg.creatingTemp(gobin) 1361 tg.setenv("GOBIN", gobin) 1362 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1363 tg.run("install", "go-cmd-test") 1364 tg.wantExecutable("testdata/bin1/go-cmd-test"+exeSuffix, "go install go-cmd-test did not write to testdata/bin1/go-cmd-test") 1365 } 1366 1367 // Issue 11065 1368 func TestInstallToCurrentDirectoryCreatesExecutable(t *testing.T) { 1369 tg := testgo(t) 1370 defer tg.cleanup() 1371 pkg := filepath.Join(tg.pwd(), "testdata", "src", "go-cmd-test") 1372 tg.creatingTemp(filepath.Join(pkg, "go-cmd-test"+exeSuffix)) 1373 tg.setenv("GOBIN", pkg) 1374 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1375 tg.cd(pkg) 1376 tg.run("install") 1377 tg.wantExecutable("go-cmd-test"+exeSuffix, "go install did not write to current directory") 1378 } 1379 1380 // Without $GOBIN set, installing a program outside $GOPATH should fail 1381 // (there is nowhere to install it). 1382 func TestInstallWithoutDestinationFails(t *testing.T) { 1383 tg := testgo(t) 1384 defer tg.cleanup() 1385 tg.runFail("install", "testdata/src/go-cmd-test/helloworld.go") 1386 tg.grepStderr("no install location for .go files listed on command line", "wrong error") 1387 } 1388 1389 // With $GOBIN set, should install there. 1390 func TestInstallToGOBINCommandLinePackage(t *testing.T) { 1391 tg := testgo(t) 1392 defer tg.cleanup() 1393 gobin := filepath.Join(tg.pwd(), "testdata", "bin1") 1394 tg.creatingTemp(gobin) 1395 tg.setenv("GOBIN", gobin) 1396 tg.run("install", "testdata/src/go-cmd-test/helloworld.go") 1397 tg.wantExecutable("testdata/bin1/helloworld"+exeSuffix, "go install testdata/src/go-cmd-test/helloworld.go did not write testdata/bin1/helloworld") 1398 } 1399 1400 func TestGodocInstalls(t *testing.T) { 1401 testenv.MustHaveExternalNetwork(t) 1402 1403 // godoc installs into GOBIN 1404 tg := testgo(t) 1405 defer tg.cleanup() 1406 tg.parallel() 1407 tg.tempDir("gobin") 1408 tg.setenv("GOPATH", tg.path(".")) 1409 tg.setenv("GOBIN", tg.path("gobin")) 1410 tg.run("get", "golang.org/x/tools/cmd/godoc") 1411 tg.wantExecutable(tg.path("gobin/godoc"), "did not install godoc to $GOBIN") 1412 tg.unsetenv("GOBIN") 1413 1414 // godoc installs into GOROOT 1415 goroot := runtime.GOROOT() 1416 tg.setenv("GOROOT", goroot) 1417 tg.check(os.RemoveAll(filepath.Join(goroot, "bin", "godoc"))) 1418 tg.run("install", "golang.org/x/tools/cmd/godoc") 1419 tg.wantExecutable(filepath.Join(goroot, "bin", "godoc"), "did not install godoc to $GOROOT/bin") 1420 } 1421 1422 func TestGoGetNonPkg(t *testing.T) { 1423 testenv.MustHaveExternalNetwork(t) 1424 1425 tg := testgo(t) 1426 defer tg.cleanup() 1427 tg.tempDir("gobin") 1428 tg.setenv("GOPATH", tg.path(".")) 1429 tg.setenv("GOBIN", tg.path("gobin")) 1430 tg.runFail("get", "-d", "golang.org/x/tools") 1431 tg.grepStderr("golang.org/x/tools: no buildable Go source files", "missing error") 1432 tg.runFail("get", "-d", "-u", "golang.org/x/tools") 1433 tg.grepStderr("golang.org/x/tools: no buildable Go source files", "missing error") 1434 tg.runFail("get", "-d", "golang.org/x/tools") 1435 tg.grepStderr("golang.org/x/tools: no buildable Go source files", "missing error") 1436 } 1437 1438 func TestInstalls(t *testing.T) { 1439 if testing.Short() { 1440 t.Skip("don't install into GOROOT in short mode") 1441 } 1442 1443 tg := testgo(t) 1444 defer tg.cleanup() 1445 tg.parallel() 1446 tg.tempDir("gobin") 1447 tg.setenv("GOPATH", tg.path(".")) 1448 goroot := runtime.GOROOT() 1449 tg.setenv("GOROOT", goroot) 1450 1451 // cmd/fix installs into tool 1452 tg.run("env", "GOOS") 1453 goos := strings.TrimSpace(tg.getStdout()) 1454 tg.setenv("GOOS", goos) 1455 tg.run("env", "GOARCH") 1456 goarch := strings.TrimSpace(tg.getStdout()) 1457 tg.setenv("GOARCH", goarch) 1458 fixbin := filepath.Join(goroot, "pkg", "tool", goos+"_"+goarch, "fix") + exeSuffix 1459 tg.must(os.RemoveAll(fixbin)) 1460 tg.run("install", "cmd/fix") 1461 tg.wantExecutable(fixbin, "did not install cmd/fix to $GOROOT/pkg/tool") 1462 tg.must(os.Remove(fixbin)) 1463 tg.setenv("GOBIN", tg.path("gobin")) 1464 tg.run("install", "cmd/fix") 1465 tg.wantExecutable(fixbin, "did not install cmd/fix to $GOROOT/pkg/tool with $GOBIN set") 1466 tg.unsetenv("GOBIN") 1467 1468 // gopath program installs into GOBIN 1469 tg.tempFile("src/progname/p.go", `package main; func main() {}`) 1470 tg.setenv("GOBIN", tg.path("gobin")) 1471 tg.run("install", "progname") 1472 tg.unsetenv("GOBIN") 1473 tg.wantExecutable(tg.path("gobin/progname")+exeSuffix, "did not install progname to $GOBIN/progname") 1474 1475 // gopath program installs into GOPATH/bin 1476 tg.run("install", "progname") 1477 tg.wantExecutable(tg.path("bin/progname")+exeSuffix, "did not install progname to $GOPATH/bin/progname") 1478 } 1479 1480 func TestRejectRelativeDotPathInGOPATHCommandLinePackage(t *testing.T) { 1481 tg := testgo(t) 1482 defer tg.cleanup() 1483 tg.setenv("GOPATH", ".") 1484 tg.runFail("build", "testdata/src/go-cmd-test/helloworld.go") 1485 tg.grepStderr("GOPATH entry is relative", "expected an error message rejecting relative GOPATH entries") 1486 } 1487 1488 func TestRejectRelativePathsInGOPATH(t *testing.T) { 1489 tg := testgo(t) 1490 defer tg.cleanup() 1491 sep := string(filepath.ListSeparator) 1492 tg.setenv("GOPATH", sep+filepath.Join(tg.pwd(), "testdata")+sep+".") 1493 tg.runFail("build", "go-cmd-test") 1494 tg.grepStderr("GOPATH entry is relative", "expected an error message rejecting relative GOPATH entries") 1495 } 1496 1497 func TestRejectRelativePathsInGOPATHCommandLinePackage(t *testing.T) { 1498 tg := testgo(t) 1499 defer tg.cleanup() 1500 tg.setenv("GOPATH", "testdata") 1501 tg.runFail("build", "testdata/src/go-cmd-test/helloworld.go") 1502 tg.grepStderr("GOPATH entry is relative", "expected an error message rejecting relative GOPATH entries") 1503 } 1504 1505 // Issue 4104. 1506 func TestGoTestWithPackageListedMultipleTimes(t *testing.T) { 1507 tg := testgo(t) 1508 defer tg.cleanup() 1509 tg.parallel() 1510 tg.run("test", "errors", "errors", "errors", "errors", "errors") 1511 if strings.Index(strings.TrimSpace(tg.getStdout()), "\n") != -1 { 1512 t.Error("go test errors errors errors errors errors tested the same package multiple times") 1513 } 1514 } 1515 1516 func TestGoListHasAConsistentOrder(t *testing.T) { 1517 tg := testgo(t) 1518 defer tg.cleanup() 1519 tg.run("list", "std") 1520 first := tg.getStdout() 1521 tg.run("list", "std") 1522 if first != tg.getStdout() { 1523 t.Error("go list std ordering is inconsistent") 1524 } 1525 } 1526 1527 func TestGoListStdDoesNotIncludeCommands(t *testing.T) { 1528 tg := testgo(t) 1529 defer tg.cleanup() 1530 tg.run("list", "std") 1531 tg.grepStdoutNot("cmd/", "go list std shows commands") 1532 } 1533 1534 func TestGoListCmdOnlyShowsCommands(t *testing.T) { 1535 tg := testgo(t) 1536 defer tg.cleanup() 1537 tg.run("list", "cmd") 1538 out := strings.TrimSpace(tg.getStdout()) 1539 for _, line := range strings.Split(out, "\n") { 1540 if strings.Index(line, "cmd/") == -1 { 1541 t.Error("go list cmd shows non-commands") 1542 break 1543 } 1544 } 1545 } 1546 1547 func TestGoListDedupsPackages(t *testing.T) { 1548 tg := testgo(t) 1549 defer tg.cleanup() 1550 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 1551 tg.run("list", "xtestonly", "./testdata/src/xtestonly/...") 1552 got := strings.TrimSpace(tg.getStdout()) 1553 const want = "xtestonly" 1554 if got != want { 1555 t.Errorf("got %q; want %q", got, want) 1556 } 1557 } 1558 1559 // Issue 4096. Validate the output of unsuccessful go install foo/quxx. 1560 func TestUnsuccessfulGoInstallShouldMentionMissingPackage(t *testing.T) { 1561 tg := testgo(t) 1562 defer tg.cleanup() 1563 tg.runFail("install", "foo/quxx") 1564 if tg.grepCountBoth(`cannot find package "foo/quxx" in any of`) != 1 { 1565 t.Error(`go install foo/quxx expected error: .*cannot find package "foo/quxx" in any of`) 1566 } 1567 } 1568 1569 func TestGOROOTSearchFailureReporting(t *testing.T) { 1570 tg := testgo(t) 1571 defer tg.cleanup() 1572 tg.runFail("install", "foo/quxx") 1573 if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("foo", "quxx"))+` \(from \$GOROOT\)$`) != 1 { 1574 t.Error(`go install foo/quxx expected error: .*foo/quxx (from $GOROOT)`) 1575 } 1576 } 1577 1578 func TestMultipleGOPATHEntriesReportedSeparately(t *testing.T) { 1579 tg := testgo(t) 1580 defer tg.cleanup() 1581 sep := string(filepath.ListSeparator) 1582 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b")) 1583 tg.runFail("install", "foo/quxx") 1584 if tg.grepCountBoth(`testdata[/\\].[/\\]src[/\\]foo[/\\]quxx`) != 2 { 1585 t.Error(`go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)\n.*testdata/b/src/foo/quxx`) 1586 } 1587 } 1588 1589 // Test (from $GOPATH) annotation is reported for the first GOPATH entry, 1590 func TestMentionGOPATHInFirstGOPATHEntry(t *testing.T) { 1591 tg := testgo(t) 1592 defer tg.cleanup() 1593 sep := string(filepath.ListSeparator) 1594 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b")) 1595 tg.runFail("install", "foo/quxx") 1596 if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("testdata", "a", "src", "foo", "quxx"))+` \(from \$GOPATH\)$`) != 1 { 1597 t.Error(`go install foo/quxx expected error: .*testdata/a/src/foo/quxx (from $GOPATH)`) 1598 } 1599 } 1600 1601 // but not on the second. 1602 func TestMentionGOPATHNotOnSecondEntry(t *testing.T) { 1603 tg := testgo(t) 1604 defer tg.cleanup() 1605 sep := string(filepath.ListSeparator) 1606 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata", "a")+sep+filepath.Join(tg.pwd(), "testdata", "b")) 1607 tg.runFail("install", "foo/quxx") 1608 if tg.grepCountBoth(regexp.QuoteMeta(filepath.Join("testdata", "b", "src", "foo", "quxx"))+`$`) != 1 { 1609 t.Error(`go install foo/quxx expected error: .*testdata/b/src/foo/quxx`) 1610 } 1611 } 1612 1613 // Test missing GOPATH is reported. 1614 func TestMissingGOPATHIsReported(t *testing.T) { 1615 tg := testgo(t) 1616 defer tg.cleanup() 1617 tg.setenv("GOPATH", "") 1618 tg.runFail("install", "foo/quxx") 1619 if tg.grepCountBoth(`\(\$GOPATH not set\)$`) != 1 { 1620 t.Error(`go install foo/quxx expected error: ($GOPATH not set)`) 1621 } 1622 } 1623 1624 // Issue 4186. go get cannot be used to download packages to $GOROOT. 1625 // Test that without GOPATH set, go get should fail. 1626 func TestWithoutGOPATHGoGetFails(t *testing.T) { 1627 testenv.MustHaveExternalNetwork(t) 1628 1629 tg := testgo(t) 1630 defer tg.cleanup() 1631 tg.parallel() 1632 tg.tempDir("src") 1633 tg.setenv("GOPATH", "") 1634 tg.setenv("GOROOT", tg.path(".")) 1635 tg.runFail("get", "-d", "golang.org/x/codereview/cmd/hgpatch") 1636 } 1637 1638 // Test that with GOPATH=$GOROOT, go get should fail. 1639 func TestWithGOPATHEqualsGOROOTGoGetFails(t *testing.T) { 1640 testenv.MustHaveExternalNetwork(t) 1641 1642 tg := testgo(t) 1643 defer tg.cleanup() 1644 tg.parallel() 1645 tg.tempDir("src") 1646 tg.setenv("GOPATH", tg.path(".")) 1647 tg.setenv("GOROOT", tg.path(".")) 1648 tg.runFail("get", "-d", "golang.org/x/codereview/cmd/hgpatch") 1649 } 1650 1651 func TestLdflagsArgumentsWithSpacesIssue3941(t *testing.T) { 1652 tg := testgo(t) 1653 defer tg.cleanup() 1654 tg.parallel() 1655 tg.tempFile("main.go", `package main 1656 var extern string 1657 func main() { 1658 println(extern) 1659 }`) 1660 tg.run("run", "-ldflags", `-X main.extern "hello world"`, tg.path("main.go")) 1661 tg.grepStderr("^hello world", `ldflags -X main.extern 'hello world' failed`) 1662 } 1663 1664 func TestGoTestCpuprofileLeavesBinaryBehind(t *testing.T) { 1665 tg := testgo(t) 1666 defer tg.cleanup() 1667 tg.makeTempdir() 1668 tg.cd(tg.path(".")) 1669 tg.run("test", "-cpuprofile", "errors.prof", "errors") 1670 tg.wantExecutable("errors.test"+exeSuffix, "go test -cpuprofile did not create errors.test") 1671 } 1672 1673 func TestGoTestCpuprofileDashOControlsBinaryLocation(t *testing.T) { 1674 tg := testgo(t) 1675 defer tg.cleanup() 1676 tg.makeTempdir() 1677 tg.cd(tg.path(".")) 1678 tg.run("test", "-cpuprofile", "errors.prof", "-o", "myerrors.test"+exeSuffix, "errors") 1679 tg.wantExecutable("myerrors.test"+exeSuffix, "go test -cpuprofile -o myerrors.test did not create myerrors.test") 1680 } 1681 1682 func TestGoTestDashCDashOControlsBinaryLocation(t *testing.T) { 1683 tg := testgo(t) 1684 defer tg.cleanup() 1685 tg.parallel() 1686 tg.makeTempdir() 1687 tg.run("test", "-c", "-o", tg.path("myerrors.test"+exeSuffix), "errors") 1688 tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -c -o myerrors.test did not create myerrors.test") 1689 } 1690 1691 func TestGoTestDashOWritesBinary(t *testing.T) { 1692 tg := testgo(t) 1693 defer tg.cleanup() 1694 tg.parallel() 1695 tg.makeTempdir() 1696 tg.run("test", "-o", tg.path("myerrors.test"+exeSuffix), "errors") 1697 tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -o myerrors.test did not create myerrors.test") 1698 } 1699 1700 // Issue 4568. 1701 func TestSymlinksList(t *testing.T) { 1702 switch runtime.GOOS { 1703 case "plan9", "windows": 1704 t.Skipf("skipping symlink test on %s", runtime.GOOS) 1705 } 1706 1707 tg := testgo(t) 1708 defer tg.cleanup() 1709 tg.tempDir("src") 1710 tg.must(os.Symlink(tg.path("."), tg.path("src/dir1"))) 1711 tg.tempFile("src/dir1/p.go", "package p") 1712 tg.setenv("GOPATH", tg.path(".")) 1713 tg.cd(tg.path("src")) 1714 tg.run("list", "-f", "{{.Root}}", "dir1") 1715 if strings.TrimSpace(tg.getStdout()) != tg.path(".") { 1716 t.Error("confused by symlinks") 1717 } 1718 } 1719 1720 // Issue 14054. 1721 func TestSymlinksVendor(t *testing.T) { 1722 switch runtime.GOOS { 1723 case "plan9", "windows": 1724 t.Skipf("skipping symlink test on %s", runtime.GOOS) 1725 } 1726 1727 tg := testgo(t) 1728 defer tg.cleanup() 1729 tg.setenv("GO15VENDOREXPERIMENT", "1") 1730 tg.tempDir("gopath/src/dir1/vendor/v") 1731 tg.tempFile("gopath/src/dir1/p.go", "package main\nimport _ `v`\nfunc main(){}") 1732 tg.tempFile("gopath/src/dir1/vendor/v/v.go", "package v") 1733 tg.must(os.Symlink(tg.path("gopath/src/dir1"), tg.path("symdir1"))) 1734 tg.setenv("GOPATH", tg.path("gopath")) 1735 tg.cd(tg.path("symdir1")) 1736 tg.run("list", "-f", "{{.Root}}", ".") 1737 if strings.TrimSpace(tg.getStdout()) != tg.path("gopath") { 1738 t.Error("list confused by symlinks") 1739 } 1740 1741 // All of these should succeed, not die in vendor-handling code. 1742 tg.run("run", "p.go") 1743 tg.run("build") 1744 tg.run("install") 1745 } 1746 1747 func TestSymlinksInternal(t *testing.T) { 1748 switch runtime.GOOS { 1749 case "plan9", "windows": 1750 t.Skipf("skipping symlink test on %s", runtime.GOOS) 1751 } 1752 1753 tg := testgo(t) 1754 defer tg.cleanup() 1755 tg.tempDir("gopath/src/dir1/internal/v") 1756 tg.tempFile("gopath/src/dir1/p.go", "package main\nimport _ `dir1/internal/v`\nfunc main(){}") 1757 tg.tempFile("gopath/src/dir1/internal/v/v.go", "package v") 1758 tg.must(os.Symlink(tg.path("gopath/src/dir1"), tg.path("symdir1"))) 1759 tg.setenv("GOPATH", tg.path("gopath")) 1760 tg.cd(tg.path("symdir1")) 1761 tg.run("list", "-f", "{{.Root}}", ".") 1762 if strings.TrimSpace(tg.getStdout()) != tg.path("gopath") { 1763 t.Error("list confused by symlinks") 1764 } 1765 1766 // All of these should succeed, not die in internal-handling code. 1767 tg.run("run", "p.go") 1768 tg.run("build") 1769 tg.run("install") 1770 } 1771 1772 // Issue 4515. 1773 func TestInstallWithTags(t *testing.T) { 1774 tg := testgo(t) 1775 defer tg.cleanup() 1776 tg.parallel() 1777 tg.tempDir("bin") 1778 tg.tempFile("src/example/a/main.go", `package main 1779 func main() {}`) 1780 tg.tempFile("src/example/b/main.go", `// +build mytag 1781 1782 package main 1783 func main() {}`) 1784 tg.setenv("GOPATH", tg.path(".")) 1785 tg.run("install", "-tags", "mytag", "example/a", "example/b") 1786 tg.wantExecutable(tg.path("bin/a"+exeSuffix), "go install example/a example/b did not install binaries") 1787 tg.wantExecutable(tg.path("bin/b"+exeSuffix), "go install example/a example/b did not install binaries") 1788 tg.must(os.Remove(tg.path("bin/a" + exeSuffix))) 1789 tg.must(os.Remove(tg.path("bin/b" + exeSuffix))) 1790 tg.run("install", "-tags", "mytag", "example/...") 1791 tg.wantExecutable(tg.path("bin/a"+exeSuffix), "go install example/... did not install binaries") 1792 tg.wantExecutable(tg.path("bin/b"+exeSuffix), "go install example/... did not install binaries") 1793 tg.run("list", "-tags", "mytag", "example/b...") 1794 if strings.TrimSpace(tg.getStdout()) != "example/b" { 1795 t.Error("go list example/b did not find example/b") 1796 } 1797 } 1798 1799 // Issue 4773 1800 func TestCaseCollisions(t *testing.T) { 1801 tg := testgo(t) 1802 defer tg.cleanup() 1803 tg.parallel() 1804 tg.tempDir("src/example/a/pkg") 1805 tg.tempDir("src/example/a/Pkg") 1806 tg.tempDir("src/example/b") 1807 tg.setenv("GOPATH", tg.path(".")) 1808 tg.tempFile("src/example/a/a.go", `package p 1809 import ( 1810 _ "example/a/pkg" 1811 _ "example/a/Pkg" 1812 )`) 1813 tg.tempFile("src/example/a/pkg/pkg.go", `package pkg`) 1814 tg.tempFile("src/example/a/Pkg/pkg.go", `package pkg`) 1815 tg.runFail("list", "example/a") 1816 tg.grepStderr("case-insensitive import collision", "go list example/a did not report import collision") 1817 tg.tempFile("src/example/b/file.go", `package b`) 1818 tg.tempFile("src/example/b/FILE.go", `package b`) 1819 f, err := os.Open(tg.path("src/example/b")) 1820 tg.must(err) 1821 names, err := f.Readdirnames(0) 1822 tg.must(err) 1823 tg.check(f.Close()) 1824 args := []string{"list"} 1825 if len(names) == 2 { 1826 // case-sensitive file system, let directory read find both files 1827 args = append(args, "example/b") 1828 } else { 1829 // case-insensitive file system, list files explicitly on command line 1830 args = append(args, tg.path("src/example/b/file.go"), tg.path("src/example/b/FILE.go")) 1831 } 1832 tg.runFail(args...) 1833 tg.grepStderr("case-insensitive file name collision", "go list example/b did not report file name collision") 1834 } 1835 1836 // Issue 8181. 1837 func TestGoGetDashTIssue8181(t *testing.T) { 1838 if testing.Short() { 1839 t.Skip("skipping test that uses network in short mode") 1840 } 1841 1842 tg := testgo(t) 1843 defer tg.cleanup() 1844 tg.parallel() 1845 tg.makeTempdir() 1846 tg.setenv("GOPATH", tg.path(".")) 1847 tg.run("get", "-v", "-t", "github.com/rsc/go-get-issue-8181/a", "github.com/rsc/go-get-issue-8181/b") 1848 tg.run("list", "...") 1849 tg.grepStdout("x/build/cmd/cl", "missing expected x/build/cmd/cl") 1850 } 1851 1852 func TestIssue11307(t *testing.T) { 1853 // go get -u was not working except in checkout directory 1854 if testing.Short() { 1855 t.Skip("skipping test that uses network in short mode") 1856 } 1857 1858 tg := testgo(t) 1859 defer tg.cleanup() 1860 tg.parallel() 1861 tg.makeTempdir() 1862 tg.setenv("GOPATH", tg.path(".")) 1863 tg.run("get", "github.com/rsc/go-get-issue-11307") 1864 tg.run("get", "-u", "github.com/rsc/go-get-issue-11307") // was failing 1865 } 1866 1867 func TestShadowingLogic(t *testing.T) { 1868 tg := testgo(t) 1869 defer tg.cleanup() 1870 pwd := tg.pwd() 1871 sep := string(filepath.ListSeparator) 1872 tg.setenv("GOPATH", filepath.Join(pwd, "testdata", "shadow", "root1")+sep+filepath.Join(pwd, "testdata", "shadow", "root2")) 1873 1874 // The math in root1 is not "math" because the standard math is. 1875 tg.run("list", "-f", "({{.ImportPath}}) ({{.ConflictDir}})", "./testdata/shadow/root1/src/math") 1876 pwdForwardSlash := strings.Replace(pwd, string(os.PathSeparator), "/", -1) 1877 if !strings.HasPrefix(pwdForwardSlash, "/") { 1878 pwdForwardSlash = "/" + pwdForwardSlash 1879 } 1880 // The output will have makeImportValid applies, but we only 1881 // bother to deal with characters we might reasonably see. 1882 pwdForwardSlash = strings.Replace(pwdForwardSlash, ":", "_", -1) 1883 want := "(_" + pwdForwardSlash + "/testdata/shadow/root1/src/math) (" + filepath.Join(runtime.GOROOT(), "src", "math") + ")" 1884 if strings.TrimSpace(tg.getStdout()) != want { 1885 t.Error("shadowed math is not shadowed; looking for", want) 1886 } 1887 1888 // The foo in root1 is "foo". 1889 tg.run("list", "-f", "({{.ImportPath}}) ({{.ConflictDir}})", "./testdata/shadow/root1/src/foo") 1890 if strings.TrimSpace(tg.getStdout()) != "(foo) ()" { 1891 t.Error("unshadowed foo is shadowed") 1892 } 1893 1894 // The foo in root2 is not "foo" because the foo in root1 got there first. 1895 tg.run("list", "-f", "({{.ImportPath}}) ({{.ConflictDir}})", "./testdata/shadow/root2/src/foo") 1896 want = "(_" + pwdForwardSlash + "/testdata/shadow/root2/src/foo) (" + filepath.Join(pwd, "testdata", "shadow", "root1", "src", "foo") + ")" 1897 if strings.TrimSpace(tg.getStdout()) != want { 1898 t.Error("shadowed foo is not shadowed; looking for", want) 1899 } 1900 1901 // The error for go install should mention the conflicting directory. 1902 tg.runFail("install", "./testdata/shadow/root2/src/foo") 1903 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") 1904 if strings.TrimSpace(tg.getStderr()) != want { 1905 t.Error("wrong shadowed install error; looking for", want) 1906 } 1907 } 1908 1909 // Only succeeds if source order is preserved. 1910 func TestSourceFileNameOrderPreserved(t *testing.T) { 1911 tg := testgo(t) 1912 defer tg.cleanup() 1913 tg.run("test", "testdata/example1_test.go", "testdata/example2_test.go") 1914 } 1915 1916 // Check that coverage analysis works at all. 1917 // Don't worry about the exact numbers but require not 0.0%. 1918 func checkCoverage(tg *testgoData, data string) { 1919 if regexp.MustCompile(`[^0-9]0\.0%`).MatchString(data) { 1920 tg.t.Error("some coverage results are 0.0%") 1921 } 1922 tg.t.Log(data) 1923 } 1924 1925 func TestCoverageRuns(t *testing.T) { 1926 if testing.Short() { 1927 t.Skip("don't build libraries for coverage in short mode") 1928 } 1929 tg := testgo(t) 1930 defer tg.cleanup() 1931 tg.run("test", "-short", "-coverpkg=strings", "strings", "regexp") 1932 data := tg.getStdout() + tg.getStderr() 1933 tg.run("test", "-short", "-cover", "strings", "math", "regexp") 1934 data += tg.getStdout() + tg.getStderr() 1935 checkCoverage(tg, data) 1936 } 1937 1938 // Check that coverage analysis uses set mode. 1939 func TestCoverageUsesSetMode(t *testing.T) { 1940 if testing.Short() { 1941 t.Skip("don't build libraries for coverage in short mode") 1942 } 1943 tg := testgo(t) 1944 defer tg.cleanup() 1945 tg.creatingTemp("testdata/cover.out") 1946 tg.run("test", "-short", "-cover", "encoding/binary", "-coverprofile=testdata/cover.out") 1947 data := tg.getStdout() + tg.getStderr() 1948 if out, err := ioutil.ReadFile("testdata/cover.out"); err != nil { 1949 t.Error(err) 1950 } else { 1951 if !bytes.Contains(out, []byte("mode: set")) { 1952 t.Error("missing mode: set") 1953 } 1954 } 1955 checkCoverage(tg, data) 1956 } 1957 1958 func TestCoverageUsesAtomicModeForRace(t *testing.T) { 1959 if testing.Short() { 1960 t.Skip("don't build libraries for coverage in short mode") 1961 } 1962 if !canRace { 1963 t.Skip("skipping because race detector not supported") 1964 } 1965 1966 tg := testgo(t) 1967 defer tg.cleanup() 1968 tg.creatingTemp("testdata/cover.out") 1969 tg.run("test", "-short", "-race", "-cover", "encoding/binary", "-coverprofile=testdata/cover.out") 1970 data := tg.getStdout() + tg.getStderr() 1971 if out, err := ioutil.ReadFile("testdata/cover.out"); err != nil { 1972 t.Error(err) 1973 } else { 1974 if !bytes.Contains(out, []byte("mode: atomic")) { 1975 t.Error("missing mode: atomic") 1976 } 1977 } 1978 checkCoverage(tg, data) 1979 } 1980 1981 func TestCoverageUsesActualSettingToOverrideEvenForRace(t *testing.T) { 1982 if testing.Short() { 1983 t.Skip("don't build libraries for coverage in short mode") 1984 } 1985 if !canRace { 1986 t.Skip("skipping because race detector not supported") 1987 } 1988 1989 tg := testgo(t) 1990 defer tg.cleanup() 1991 tg.creatingTemp("testdata/cover.out") 1992 tg.run("test", "-short", "-race", "-cover", "encoding/binary", "-covermode=count", "-coverprofile=testdata/cover.out") 1993 data := tg.getStdout() + tg.getStderr() 1994 if out, err := ioutil.ReadFile("testdata/cover.out"); err != nil { 1995 t.Error(err) 1996 } else { 1997 if !bytes.Contains(out, []byte("mode: count")) { 1998 t.Error("missing mode: count") 1999 } 2000 } 2001 checkCoverage(tg, data) 2002 } 2003 2004 func TestCoverageWithCgo(t *testing.T) { 2005 if !canCgo { 2006 t.Skip("skipping because cgo not enabled") 2007 } 2008 2009 tg := testgo(t) 2010 defer tg.cleanup() 2011 tg.run("test", "-short", "-cover", "./testdata/cgocover") 2012 data := tg.getStdout() + tg.getStderr() 2013 checkCoverage(tg, data) 2014 } 2015 2016 func TestCgoDependsOnSyscall(t *testing.T) { 2017 if testing.Short() { 2018 t.Skip("skipping test that removes $GOROOT/pkg/*_race in short mode") 2019 } 2020 if !canCgo { 2021 t.Skip("skipping because cgo not enabled") 2022 } 2023 if !canRace { 2024 t.Skip("skipping because race detector not supported") 2025 } 2026 2027 tg := testgo(t) 2028 defer tg.cleanup() 2029 files, err := filepath.Glob(filepath.Join(runtime.GOROOT(), "pkg", "*_race")) 2030 tg.must(err) 2031 for _, file := range files { 2032 tg.check(os.RemoveAll(file)) 2033 } 2034 tg.tempFile("src/foo/foo.go", ` 2035 package foo 2036 //#include <stdio.h> 2037 import "C"`) 2038 tg.setenv("GOPATH", tg.path(".")) 2039 tg.run("build", "-race", "foo") 2040 } 2041 2042 func TestCgoShowsFullPathNames(t *testing.T) { 2043 if !canCgo { 2044 t.Skip("skipping because cgo not enabled") 2045 } 2046 2047 tg := testgo(t) 2048 defer tg.cleanup() 2049 tg.parallel() 2050 tg.tempFile("src/x/y/dirname/foo.go", ` 2051 package foo 2052 import "C" 2053 func f() {`) 2054 tg.setenv("GOPATH", tg.path(".")) 2055 tg.runFail("build", "x/y/dirname") 2056 tg.grepBoth("x/y/dirname", "error did not use full path") 2057 } 2058 2059 func TestCgoHandlesWlORIGIN(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/origin/origin.go", `package origin 2068 // #cgo !darwin LDFLAGS: -Wl,-rpath -Wl,$ORIGIN 2069 // void f(void) {} 2070 import "C" 2071 func f() { C.f() }`) 2072 tg.setenv("GOPATH", tg.path(".")) 2073 tg.run("build", "origin") 2074 } 2075 2076 // "go test -c -test.bench=XXX errors" should not hang 2077 func TestIssue6480(t *testing.T) { 2078 tg := testgo(t) 2079 defer tg.cleanup() 2080 tg.makeTempdir() 2081 tg.cd(tg.path(".")) 2082 tg.run("test", "-c", "-test.bench=XXX", "errors") 2083 } 2084 2085 // cmd/cgo: undefined reference when linking a C-library using gccgo 2086 func TestIssue7573(t *testing.T) { 2087 if !canCgo { 2088 t.Skip("skipping because cgo not enabled") 2089 } 2090 if _, err := exec.LookPath("gccgo"); err != nil { 2091 t.Skip("skipping because no gccgo compiler found") 2092 } 2093 2094 tg := testgo(t) 2095 defer tg.cleanup() 2096 tg.parallel() 2097 tg.tempFile("src/cgoref/cgoref.go", ` 2098 package main 2099 // #cgo LDFLAGS: -L alibpath -lalib 2100 // void f(void) {} 2101 import "C" 2102 2103 func main() { C.f() }`) 2104 tg.setenv("GOPATH", tg.path(".")) 2105 tg.run("build", "-n", "-compiler", "gccgo", "cgoref") 2106 tg.grepStderr(`gccgo.*\-L alibpath \-lalib`, `no Go-inline "#cgo LDFLAGS:" ("-L alibpath -lalib") passed to gccgo linking stage`) 2107 } 2108 2109 func TestListTemplateCanUseContextFunction(t *testing.T) { 2110 tg := testgo(t) 2111 defer tg.cleanup() 2112 tg.run("list", "-f", "GOARCH: {{context.GOARCH}}") 2113 } 2114 2115 // cmd/go: "go test" should fail if package does not build 2116 func TestIssue7108(t *testing.T) { 2117 tg := testgo(t) 2118 defer tg.cleanup() 2119 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 2120 tg.runFail("test", "notest") 2121 } 2122 2123 // cmd/go: go test -a foo does not rebuild regexp. 2124 func TestIssue6844(t *testing.T) { 2125 if testing.Short() { 2126 t.Skip("don't rebuild the standard libary in short mode") 2127 } 2128 2129 tg := testgo(t) 2130 defer tg.cleanup() 2131 tg.creatingTemp("deps.test" + exeSuffix) 2132 tg.run("test", "-x", "-a", "-c", "testdata/dep_test.go") 2133 tg.grepStderr("regexp", "go test -x -a -c testdata/dep-test.go did not rebuild regexp") 2134 } 2135 2136 func TestBuildDashIInstallsDependencies(t *testing.T) { 2137 tg := testgo(t) 2138 defer tg.cleanup() 2139 tg.parallel() 2140 tg.tempFile("src/x/y/foo/foo.go", `package foo 2141 func F() {}`) 2142 tg.tempFile("src/x/y/bar/bar.go", `package bar 2143 import "x/y/foo" 2144 func F() { foo.F() }`) 2145 tg.setenv("GOPATH", tg.path(".")) 2146 2147 checkbar := func(desc string) { 2148 tg.sleep() 2149 tg.must(os.Chtimes(tg.path("src/x/y/foo/foo.go"), time.Now(), time.Now())) 2150 tg.sleep() 2151 tg.run("build", "-v", "-i", "x/y/bar") 2152 tg.grepBoth("x/y/foo", "first build -i "+desc+" did not build x/y/foo") 2153 tg.run("build", "-v", "-i", "x/y/bar") 2154 tg.grepBothNot("x/y/foo", "second build -i "+desc+" built x/y/foo") 2155 } 2156 checkbar("pkg") 2157 tg.creatingTemp("bar" + exeSuffix) 2158 tg.tempFile("src/x/y/bar/bar.go", `package main 2159 import "x/y/foo" 2160 func main() { foo.F() }`) 2161 checkbar("cmd") 2162 } 2163 2164 func TestGoBuildInTestOnlyDirectoryFailsWithAGoodError(t *testing.T) { 2165 tg := testgo(t) 2166 defer tg.cleanup() 2167 tg.runFail("build", "./testdata/testonly") 2168 tg.grepStderr("no buildable Go", "go build ./testdata/testonly produced unexpected error") 2169 } 2170 2171 func TestGoTestDetectsTestOnlyImportCycles(t *testing.T) { 2172 tg := testgo(t) 2173 defer tg.cleanup() 2174 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 2175 tg.runFail("test", "-c", "testcycle/p3") 2176 tg.grepStderr("import cycle not allowed in test", "go test testcycle/p3 produced unexpected error") 2177 2178 tg.runFail("test", "-c", "testcycle/q1") 2179 tg.grepStderr("import cycle not allowed in test", "go test testcycle/q1 produced unexpected error") 2180 } 2181 2182 func TestGoTestFooTestWorks(t *testing.T) { 2183 tg := testgo(t) 2184 defer tg.cleanup() 2185 tg.run("test", "testdata/standalone_test.go") 2186 } 2187 2188 func TestGoTestFlagsAfterPackage(t *testing.T) { 2189 tg := testgo(t) 2190 defer tg.cleanup() 2191 tg.run("test", "testdata/flag_test.go", "-v", "-args", "-v=7") // Two distinct -v flags. 2192 tg.run("test", "-v", "testdata/flag_test.go", "-args", "-v=7") // Two distinct -v flags. 2193 } 2194 2195 func TestGoTestXtestonlyWorks(t *testing.T) { 2196 tg := testgo(t) 2197 defer tg.cleanup() 2198 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 2199 tg.run("clean", "-i", "xtestonly") 2200 tg.run("test", "xtestonly") 2201 } 2202 2203 func TestGoTestBuildsAnXtestContainingOnlyNonRunnableExamples(t *testing.T) { 2204 tg := testgo(t) 2205 defer tg.cleanup() 2206 tg.run("test", "-v", "./testdata/norunexample") 2207 tg.grepStdout("File with non-runnable example was built.", "file with non-runnable example was not built") 2208 } 2209 2210 func TestGoGenerateHandlesSimpleCommand(t *testing.T) { 2211 if runtime.GOOS == "windows" { 2212 t.Skip("skipping because windows has no echo command") 2213 } 2214 2215 tg := testgo(t) 2216 defer tg.cleanup() 2217 tg.run("generate", "./testdata/generate/test1.go") 2218 tg.grepStdout("Success", "go generate ./testdata/generate/test1.go generated wrong output") 2219 } 2220 2221 func TestGoGenerateHandlesCommandAlias(t *testing.T) { 2222 if runtime.GOOS == "windows" { 2223 t.Skip("skipping because windows has no echo command") 2224 } 2225 2226 tg := testgo(t) 2227 defer tg.cleanup() 2228 tg.run("generate", "./testdata/generate/test2.go") 2229 tg.grepStdout("Now is the time for all good men", "go generate ./testdata/generate/test2.go generated wrong output") 2230 } 2231 2232 func TestGoGenerateVariableSubstitution(t *testing.T) { 2233 if runtime.GOOS == "windows" { 2234 t.Skip("skipping because windows has no echo command") 2235 } 2236 2237 tg := testgo(t) 2238 defer tg.cleanup() 2239 tg.run("generate", "./testdata/generate/test3.go") 2240 tg.grepStdout(runtime.GOARCH+" test3.go:7 pabc xyzp/test3.go/123", "go generate ./testdata/generate/test3.go generated wrong output") 2241 } 2242 2243 func TestGoGenerateRunFlag(t *testing.T) { 2244 if runtime.GOOS == "windows" { 2245 t.Skip("skipping because windows has no echo command") 2246 } 2247 2248 tg := testgo(t) 2249 defer tg.cleanup() 2250 tg.run("generate", "-run", "y.s", "./testdata/generate/test4.go") 2251 tg.grepStdout("yes", "go generate -run yes ./testdata/generate/test4.go did not select yes") 2252 tg.grepStdoutNot("no", "go generate -run yes ./testdata/generate/test4.go selected no") 2253 } 2254 2255 func TestGoGenerateEnv(t *testing.T) { 2256 switch runtime.GOOS { 2257 case "plan9", "windows": 2258 t.Skipf("skipping because %s does not have the env command", runtime.GOOS) 2259 } 2260 tg := testgo(t) 2261 defer tg.cleanup() 2262 tg.parallel() 2263 tg.tempFile("env.go", "package main\n\n//go:generate env") 2264 tg.run("generate", tg.path("env.go")) 2265 for _, v := range []string{"GOARCH", "GOOS", "GOFILE", "GOLINE", "GOPACKAGE", "DOLLAR"} { 2266 tg.grepStdout("^"+v+"=", "go generate environment missing "+v) 2267 } 2268 } 2269 2270 func TestGoGetCustomDomainWildcard(t *testing.T) { 2271 testenv.MustHaveExternalNetwork(t) 2272 2273 tg := testgo(t) 2274 defer tg.cleanup() 2275 tg.makeTempdir() 2276 tg.setenv("GOPATH", tg.path(".")) 2277 tg.run("get", "-u", "rsc.io/pdf/...") 2278 tg.wantExecutable(tg.path("bin/pdfpasswd"+exeSuffix), "did not build rsc/io/pdf/pdfpasswd") 2279 } 2280 2281 func TestGoGetInternalWildcard(t *testing.T) { 2282 testenv.MustHaveExternalNetwork(t) 2283 2284 tg := testgo(t) 2285 defer tg.cleanup() 2286 tg.makeTempdir() 2287 tg.setenv("GOPATH", tg.path(".")) 2288 // used to fail with errors about internal packages 2289 tg.run("get", "github.com/rsc/go-get-issue-11960/...") 2290 } 2291 2292 func TestGoVetWithExternalTests(t *testing.T) { 2293 testenv.MustHaveExternalNetwork(t) 2294 2295 tg := testgo(t) 2296 defer tg.cleanup() 2297 tg.makeTempdir() 2298 tg.setenv("GOPATH", tg.path(".")) 2299 tg.run("get", "golang.org/x/tools/cmd/vet") 2300 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 2301 tg.runFail("vet", "vetpkg") 2302 tg.grepBoth("missing argument for Printf", "go vet vetpkg did not find missing argument for Printf") 2303 } 2304 2305 func TestGoVetWithTags(t *testing.T) { 2306 testenv.MustHaveExternalNetwork(t) 2307 2308 tg := testgo(t) 2309 defer tg.cleanup() 2310 tg.makeTempdir() 2311 tg.setenv("GOPATH", tg.path(".")) 2312 tg.run("get", "golang.org/x/tools/cmd/vet") 2313 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 2314 tg.runFail("vet", "-tags", "tagtest", "vetpkg") 2315 tg.grepBoth(`c\.go.*wrong number of args for format`, "go get vetpkg did not run scan tagged file") 2316 } 2317 2318 // Issue 9767. 2319 func TestGoGetRscIoToolstash(t *testing.T) { 2320 testenv.MustHaveExternalNetwork(t) 2321 2322 tg := testgo(t) 2323 defer tg.cleanup() 2324 tg.tempDir("src/rsc.io") 2325 tg.setenv("GOPATH", tg.path(".")) 2326 tg.cd(tg.path("src/rsc.io")) 2327 tg.run("get", "./toolstash") 2328 } 2329 2330 // Issue 13037: Was not parsing <meta> tags in 404 served over HTTPS 2331 func TestGoGetHTTPS404(t *testing.T) { 2332 testenv.MustHaveExternalNetwork(t) 2333 2334 tg := testgo(t) 2335 defer tg.cleanup() 2336 tg.tempDir("src") 2337 tg.setenv("GOPATH", tg.path(".")) 2338 tg.run("get", "bazil.org/fuse/fs/fstestutil") 2339 } 2340 2341 // Test that you can not import a main package. 2342 func TestIssue4210(t *testing.T) { 2343 tg := testgo(t) 2344 defer tg.cleanup() 2345 tg.tempFile("src/x/main.go", `package main 2346 var X int 2347 func main() {}`) 2348 tg.tempFile("src/y/main.go", `package main 2349 import "fmt" 2350 import xmain "x" 2351 func main() { 2352 fmt.Println(xmain.X) 2353 }`) 2354 tg.setenv("GOPATH", tg.path(".")) 2355 tg.runFail("build", "y") 2356 tg.grepBoth("is a program", `did not find expected error message ("is a program")`) 2357 } 2358 2359 func TestGoGetInsecure(t *testing.T) { 2360 testenv.MustHaveExternalNetwork(t) 2361 2362 tg := testgo(t) 2363 defer tg.cleanup() 2364 tg.makeTempdir() 2365 tg.setenv("GOPATH", tg.path(".")) 2366 tg.failSSH() 2367 2368 const repo = "wh3rd.net/git.git" 2369 2370 // Try go get -d of HTTP-only repo (should fail). 2371 tg.runFail("get", "-d", repo) 2372 2373 // Try again with -insecure (should succeed). 2374 tg.run("get", "-d", "-insecure", repo) 2375 2376 // Try updating without -insecure (should fail). 2377 tg.runFail("get", "-d", "-u", "-f", repo) 2378 } 2379 2380 func TestGoGetUpdateInsecure(t *testing.T) { 2381 testenv.MustHaveExternalNetwork(t) 2382 2383 tg := testgo(t) 2384 defer tg.cleanup() 2385 tg.makeTempdir() 2386 tg.setenv("GOPATH", tg.path(".")) 2387 2388 const repo = "github.com/golang/example" 2389 2390 // Clone the repo via HTTP manually. 2391 cmd := exec.Command("git", "clone", "-q", "http://"+repo, tg.path("src/"+repo)) 2392 if out, err := cmd.CombinedOutput(); err != nil { 2393 t.Fatalf("cloning %v repo: %v\n%s", repo, err, out) 2394 } 2395 2396 // Update without -insecure should fail. 2397 // Update with -insecure should succeed. 2398 // We need -f to ignore import comments. 2399 const pkg = repo + "/hello" 2400 tg.runFail("get", "-d", "-u", "-f", pkg) 2401 tg.run("get", "-d", "-u", "-f", "-insecure", pkg) 2402 } 2403 2404 func TestGoGetInsecureCustomDomain(t *testing.T) { 2405 testenv.MustHaveExternalNetwork(t) 2406 2407 tg := testgo(t) 2408 defer tg.cleanup() 2409 tg.makeTempdir() 2410 tg.setenv("GOPATH", tg.path(".")) 2411 2412 const repo = "wh3rd.net/repo" 2413 tg.runFail("get", "-d", repo) 2414 tg.run("get", "-d", "-insecure", repo) 2415 } 2416 2417 func TestIssue10193(t *testing.T) { 2418 t.Skip("depends on code.google.com") 2419 testenv.MustHaveExternalNetwork(t) 2420 if _, err := exec.LookPath("hg"); err != nil { 2421 t.Skip("skipping because hg binary not found") 2422 } 2423 2424 tg := testgo(t) 2425 defer tg.cleanup() 2426 tg.parallel() 2427 tg.tempDir("src") 2428 tg.setenv("GOPATH", tg.path(".")) 2429 tg.runFail("get", "code.google.com/p/rsc/pdf") 2430 tg.grepStderr("is shutting down", "missed warning about code.google.com") 2431 } 2432 2433 func TestGoRunDirs(t *testing.T) { 2434 tg := testgo(t) 2435 defer tg.cleanup() 2436 tg.cd("testdata/rundir") 2437 tg.runFail("run", "x.go", "sub/sub.go") 2438 tg.grepStderr("named files must all be in one directory; have ./ and sub/", "wrong output") 2439 tg.runFail("run", "sub/sub.go", "x.go") 2440 tg.grepStderr("named files must all be in one directory; have sub/ and ./", "wrong output") 2441 } 2442 2443 func TestGoInstallPkgdir(t *testing.T) { 2444 tg := testgo(t) 2445 defer tg.cleanup() 2446 tg.makeTempdir() 2447 pkg := tg.path(".") 2448 tg.run("install", "-pkgdir", pkg, "errors") 2449 _, err := os.Stat(filepath.Join(pkg, "errors.a")) 2450 tg.must(err) 2451 _, err = os.Stat(filepath.Join(pkg, "runtime.a")) 2452 tg.must(err) 2453 } 2454 2455 func TestGoTestRaceInstallCgo(t *testing.T) { 2456 switch sys := runtime.GOOS + "/" + runtime.GOARCH; sys { 2457 case "darwin/amd64", "freebsd/amd64", "linux/amd64", "windows/amd64": 2458 // ok 2459 default: 2460 t.Skip("no race detector on %s", sys) 2461 } 2462 2463 if !build.Default.CgoEnabled { 2464 t.Skip("no race detector without cgo") 2465 } 2466 2467 // golang.org/issue/10500. 2468 // This used to install a race-enabled cgo. 2469 tg := testgo(t) 2470 defer tg.cleanup() 2471 tg.run("tool", "-n", "cgo") 2472 cgo := strings.TrimSpace(tg.stdout.String()) 2473 old, err := os.Stat(cgo) 2474 tg.must(err) 2475 tg.run("test", "-race", "-i", "runtime/race") 2476 new, err := os.Stat(cgo) 2477 tg.must(err) 2478 if new.ModTime() != old.ModTime() { 2479 t.Fatalf("go test -i runtime/race reinstalled cmd/cgo") 2480 } 2481 } 2482 2483 func TestGoTestImportErrorStack(t *testing.T) { 2484 const out = `package testdep/p1 (test) 2485 imports testdep/p2 2486 imports testdep/p3: no buildable Go source files` 2487 2488 tg := testgo(t) 2489 defer tg.cleanup() 2490 tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) 2491 tg.runFail("test", "testdep/p1") 2492 if !strings.Contains(tg.stderr.String(), out) { 2493 t.Fatalf("did not give full import stack:\n\n%s", tg.stderr.String()) 2494 } 2495 } 2496 2497 func TestGoGetUpdate(t *testing.T) { 2498 // golang.org/issue/9224. 2499 // The recursive updating was trying to walk to 2500 // former dependencies, not current ones. 2501 2502 testenv.MustHaveExternalNetwork(t) 2503 2504 tg := testgo(t) 2505 defer tg.cleanup() 2506 tg.makeTempdir() 2507 tg.setenv("GOPATH", tg.path(".")) 2508 2509 rewind := func() { 2510 tg.run("get", "github.com/rsc/go-get-issue-9224-cmd") 2511 cmd := exec.Command("git", "reset", "--hard", "HEAD~") 2512 cmd.Dir = tg.path("src/github.com/rsc/go-get-issue-9224-lib") 2513 out, err := cmd.CombinedOutput() 2514 if err != nil { 2515 t.Fatalf("git: %v\n%s", err, out) 2516 } 2517 } 2518 2519 rewind() 2520 tg.run("get", "-u", "github.com/rsc/go-get-issue-9224-cmd") 2521 2522 // Again with -d -u. 2523 rewind() 2524 tg.run("get", "-d", "-u", "github.com/rsc/go-get-issue-9224-cmd") 2525 } 2526 2527 func TestGoGetDomainRoot(t *testing.T) { 2528 // golang.org/issue/9357. 2529 // go get foo.io (not foo.io/subdir) was not working consistently. 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 // go-get-issue-9357.appspot.com is running 2539 // the code at github.com/rsc/go-get-issue-9357, 2540 // a trivial Go on App Engine app that serves a 2541 // <meta> tag for the domain root. 2542 tg.run("get", "-d", "go-get-issue-9357.appspot.com") 2543 tg.run("get", "go-get-issue-9357.appspot.com") 2544 tg.run("get", "-u", "go-get-issue-9357.appspot.com") 2545 2546 tg.must(os.RemoveAll(tg.path("src/go-get-issue-9357.appspot.com"))) 2547 tg.run("get", "go-get-issue-9357.appspot.com") 2548 2549 tg.must(os.RemoveAll(tg.path("src/go-get-issue-9357.appspot.com"))) 2550 tg.run("get", "-u", "go-get-issue-9357.appspot.com") 2551 } 2552 2553 func TestGoInstallShadowedGOPATH(t *testing.T) { 2554 // golang.org/issue/3652. 2555 // go get foo.io (not foo.io/subdir) was not working consistently. 2556 2557 testenv.MustHaveExternalNetwork(t) 2558 2559 tg := testgo(t) 2560 defer tg.cleanup() 2561 tg.makeTempdir() 2562 tg.setenv("GOPATH", tg.path("gopath1")+string(filepath.ListSeparator)+tg.path("gopath2")) 2563 2564 tg.tempDir("gopath1/src/test") 2565 tg.tempDir("gopath2/src/test") 2566 tg.tempFile("gopath2/src/test/main.go", "package main\nfunc main(){}\n") 2567 2568 tg.cd(tg.path("gopath2/src/test")) 2569 tg.runFail("install") 2570 tg.grepStderr("no install location for.*gopath2.src.test: hidden by .*gopath1.src.test", "missing error") 2571 } 2572 2573 func TestGoBuildGOPATHOrder(t *testing.T) { 2574 // golang.org/issue/14176#issuecomment-179895769 2575 // golang.org/issue/14192 2576 // -I arguments to compiler could end up not in GOPATH order, 2577 // leading to unexpected import resolution in the compiler. 2578 // This is still not a complete fix (see golang.org/issue/14271 and next test) 2579 // but it is clearly OK and enough to fix both of the two reported 2580 // instances of the underlying problem. It will have to do for now. 2581 2582 tg := testgo(t) 2583 defer tg.cleanup() 2584 tg.makeTempdir() 2585 tg.setenv("GOPATH", tg.path("p1")+string(filepath.ListSeparator)+tg.path("p2")) 2586 2587 tg.tempFile("p1/src/foo/foo.go", "package foo\n") 2588 tg.tempFile("p2/src/baz/baz.go", "package baz\n") 2589 tg.tempFile("p2/pkg/"+runtime.GOOS+"_"+runtime.GOARCH+"/foo.a", "bad\n") 2590 tg.tempFile("p1/src/bar/bar.go", ` 2591 package bar 2592 import _ "baz" 2593 import _ "foo" 2594 `) 2595 2596 tg.run("install", "-x", "bar") 2597 } 2598 2599 func TestGoBuildGOPATHOrderBroken(t *testing.T) { 2600 // This test is known not to work. 2601 // See golang.org/issue/14271. 2602 t.Skip("golang.org/issue/14271") 2603 2604 tg := testgo(t) 2605 defer tg.cleanup() 2606 tg.makeTempdir() 2607 2608 tg.tempFile("p1/src/foo/foo.go", "package foo\n") 2609 tg.tempFile("p2/src/baz/baz.go", "package baz\n") 2610 tg.tempFile("p1/pkg/"+runtime.GOOS+"_"+runtime.GOARCH+"/baz.a", "bad\n") 2611 tg.tempFile("p2/pkg/"+runtime.GOOS+"_"+runtime.GOARCH+"/foo.a", "bad\n") 2612 tg.tempFile("p1/src/bar/bar.go", ` 2613 package bar 2614 import _ "baz" 2615 import _ "foo" 2616 `) 2617 2618 colon := string(filepath.ListSeparator) 2619 tg.setenv("GOPATH", tg.path("p1")+colon+tg.path("p2")) 2620 tg.run("install", "-x", "bar") 2621 2622 tg.setenv("GOPATH", tg.path("p2")+colon+tg.path("p1")) 2623 tg.run("install", "-x", "bar") 2624 } 2625 2626 func TestIssue11709(t *testing.T) { 2627 tg := testgo(t) 2628 defer tg.cleanup() 2629 tg.tempFile("run.go", ` 2630 package main 2631 import "os" 2632 func main() { 2633 if os.Getenv("TERM") != "" { 2634 os.Exit(1) 2635 } 2636 }`) 2637 tg.unsetenv("TERM") 2638 tg.run("run", tg.path("run.go")) 2639 } 2640 2641 func TestIssue12096(t *testing.T) { 2642 tg := testgo(t) 2643 defer tg.cleanup() 2644 tg.tempFile("test_test.go", ` 2645 package main 2646 import ("os"; "testing") 2647 func TestEnv(t *testing.T) { 2648 if os.Getenv("TERM") != "" { 2649 t.Fatal("TERM is set") 2650 } 2651 }`) 2652 tg.unsetenv("TERM") 2653 tg.run("test", tg.path("test_test.go")) 2654 } 2655 2656 func TestGoBuildOutput(t *testing.T) { 2657 tg := testgo(t) 2658 defer tg.cleanup() 2659 2660 tg.makeTempdir() 2661 tg.cd(tg.path(".")) 2662 2663 nonExeSuffix := ".exe" 2664 if exeSuffix == ".exe" { 2665 nonExeSuffix = "" 2666 } 2667 2668 tg.tempFile("x.go", "package main\nfunc main(){}\n") 2669 tg.run("build", "x.go") 2670 tg.wantExecutable("x"+exeSuffix, "go build x.go did not write x"+exeSuffix) 2671 tg.must(os.Remove(tg.path("x" + exeSuffix))) 2672 tg.mustNotExist("x" + nonExeSuffix) 2673 2674 tg.run("build", "-o", "myprog", "x.go") 2675 tg.mustNotExist("x") 2676 tg.mustNotExist("x.exe") 2677 tg.wantExecutable("myprog", "go build -o myprog x.go did not write myprog") 2678 tg.mustNotExist("myprog.exe") 2679 2680 tg.tempFile("p.go", "package p\n") 2681 tg.run("build", "p.go") 2682 tg.mustNotExist("p") 2683 tg.mustNotExist("p.a") 2684 tg.mustNotExist("p.o") 2685 tg.mustNotExist("p.exe") 2686 2687 tg.run("build", "-o", "p.a", "p.go") 2688 tg.wantArchive("p.a") 2689 2690 tg.run("build", "cmd/gofmt") 2691 tg.wantExecutable("gofmt"+exeSuffix, "go build cmd/gofmt did not write gofmt"+exeSuffix) 2692 tg.must(os.Remove(tg.path("gofmt" + exeSuffix))) 2693 tg.mustNotExist("gofmt" + nonExeSuffix) 2694 2695 tg.run("build", "-o", "mygofmt", "cmd/gofmt") 2696 tg.wantExecutable("mygofmt", "go build -o mygofmt cmd/gofmt did not write mygofmt") 2697 tg.mustNotExist("mygofmt.exe") 2698 tg.mustNotExist("gofmt") 2699 tg.mustNotExist("gofmt.exe") 2700 2701 tg.run("build", "sync/atomic") 2702 tg.mustNotExist("atomic") 2703 tg.mustNotExist("atomic.exe") 2704 2705 tg.run("build", "-o", "myatomic.a", "sync/atomic") 2706 tg.wantArchive("myatomic.a") 2707 tg.mustNotExist("atomic") 2708 tg.mustNotExist("atomic.a") 2709 tg.mustNotExist("atomic.exe") 2710 2711 tg.runFail("build", "-o", "whatever", "cmd/gofmt", "sync/atomic") 2712 tg.grepStderr("multiple packages", "did not reject -o with multiple packages") 2713 } 2714 2715 func TestGoBuildARM(t *testing.T) { 2716 if testing.Short() { 2717 t.Skip("skipping cross-compile in short mode") 2718 } 2719 2720 tg := testgo(t) 2721 defer tg.cleanup() 2722 2723 tg.makeTempdir() 2724 tg.cd(tg.path(".")) 2725 2726 tg.setenv("GOARCH", "arm") 2727 tg.setenv("GOOS", "linux") 2728 tg.setenv("GOARM", "5") 2729 tg.tempFile("hello.go", `package main 2730 func main() {}`) 2731 tg.run("build", "hello.go") 2732 tg.grepStderrNot("unable to find math.a", "did not build math.a correctly") 2733 } 2734 2735 func TestIssue13655(t *testing.T) { 2736 tg := testgo(t) 2737 defer tg.cleanup() 2738 for _, pkg := range []string{"runtime", "runtime/internal/atomic"} { 2739 tg.run("list", "-f", "{{.Deps}}", pkg) 2740 tg.grepStdout("runtime/internal/sys", "did not find required dependency of "+pkg+" on runtime/internal/sys") 2741 } 2742 } 2743 2744 // For issue 14337. 2745 func TestParallelTest(t *testing.T) { 2746 tg := testgo(t) 2747 defer tg.cleanup() 2748 tg.makeTempdir() 2749 const testSrc = `package package_test 2750 import ( 2751 "testing" 2752 ) 2753 func TestTest(t *testing.T) { 2754 }` 2755 tg.tempFile("src/p1/p1_test.go", strings.Replace(testSrc, "package_test", "p1_test", 1)) 2756 tg.tempFile("src/p2/p2_test.go", strings.Replace(testSrc, "package_test", "p2_test", 1)) 2757 tg.tempFile("src/p3/p3_test.go", strings.Replace(testSrc, "package_test", "p3_test", 1)) 2758 tg.tempFile("src/p4/p4_test.go", strings.Replace(testSrc, "package_test", "p4_test", 1)) 2759 tg.setenv("GOPATH", tg.path(".")) 2760 tg.run("test", "-p=4", "p1", "p2", "p3", "p4") 2761 }