github.com/jdhenke/godel@v0.0.0-20161213181855-abeb3861bf0d/integration_test/integration_test.go (about) 1 // Copyright 2016 Palantir Technologies, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package integration_test 16 17 import ( 18 "fmt" 19 "io/ioutil" 20 "os" 21 "os/exec" 22 "path" 23 "path/filepath" 24 "regexp" 25 "strings" 26 "testing" 27 28 "github.com/nmiyake/pkg/dirs" 29 "github.com/nmiyake/pkg/gofiles" 30 "github.com/stretchr/testify/assert" 31 "github.com/stretchr/testify/require" 32 33 "github.com/palantir/godel/apps/distgo/pkg/git" 34 "github.com/palantir/godel/apps/distgo/pkg/git/gittest" 35 "github.com/palantir/godel/pkg/products" 36 ) 37 38 var ( 39 gödelTGZ string 40 testRootDir string 41 version string 42 ) 43 44 func TestMain(m *testing.M) { 45 os.Exit(runTestMain(m)) 46 } 47 48 func runTestMain(m *testing.M) int { 49 wd, err := os.Getwd() 50 if err != nil { 51 panic(err) 52 } 53 gödelProjectDir := path.Join(wd, "..") 54 version, err = git.ProjectVersion(gödelProjectDir) 55 if err != nil { 56 panic(fmt.Sprintf("Failed to get version from directory %s: %v", gödelProjectDir, err)) 57 } 58 59 gödelTGZ, err = products.Dist("godel") 60 if err != nil { 61 panic(fmt.Sprintf("Failed create distribution: %v", err)) 62 } 63 64 var cleanup func() 65 testRootDir, cleanup, err = dirs.TempDir(wd, "") 66 defer cleanup() 67 if err != nil { 68 panic(fmt.Sprintf("Failed to create temporary directory in %s: %v", wd, err)) 69 } 70 71 return m.Run() 72 } 73 74 func TestVersion(t *testing.T) { 75 testProjectDir := setUpGödelTestAndDownload(t, testRootDir, gödelTGZ, version) 76 77 cmd := exec.Command("./godelw", "--version") 78 cmd.Dir = testProjectDir 79 output, err := cmd.CombinedOutput() 80 require.NoError(t, err, "Command %v failed. Output:\n%v", cmd.Args, string(output)) 81 82 assert.Equal(t, fmt.Sprintf("godel version %v\n", version), string(output)) 83 } 84 85 func TestFormat(t *testing.T) { 86 testProjectDir := setUpGödelTestAndDownload(t, testRootDir, gödelTGZ, version) 87 88 src := `package main 89 import "fmt" 90 91 func main() { 92 fmt.Println("hello, world!") 93 }` 94 95 formattedSrc := `package main 96 97 import ( 98 "fmt" 99 ) 100 101 func main() { 102 fmt.Println("hello, world!") 103 } 104 ` 105 err := ioutil.WriteFile(path.Join(testProjectDir, "main.go"), []byte(src), 0644) 106 require.NoError(t, err) 107 108 cmd := exec.Command("./godelw", "format") 109 cmd.Dir = testProjectDir 110 output, err := cmd.CombinedOutput() 111 require.NoError(t, err, "Command %v failed. Output:\n%v", cmd.Args, string(output)) 112 113 content, err := ioutil.ReadFile(path.Join(testProjectDir, "main.go")) 114 require.NoError(t, err) 115 assert.Equal(t, formattedSrc, string(content)) 116 } 117 118 func TestImports(t *testing.T) { 119 testProjectDir := setUpGödelTestAndDownload(t, testRootDir, gödelTGZ, version) 120 121 const importsYML = `root-dirs: 122 - pkg` 123 err := ioutil.WriteFile(path.Join(testProjectDir, "godel", "config", "imports.yml"), []byte(importsYML), 0644) 124 require.NoError(t, err) 125 126 specs := []gofiles.GoFileSpec{ 127 { 128 RelPath: "pkg/foo/foo.go", 129 Src: `package foo; import _ "{{index . "bar.go"}}";`, 130 }, 131 { 132 RelPath: "bar.go", 133 Src: "package bar", 134 }, 135 } 136 137 files, err := gofiles.Write(testProjectDir, specs) 138 require.NoError(t, err) 139 140 want := fmt.Sprintf(`{ 141 "imports": [ 142 { 143 "path": "%s", 144 "numGoFiles": 1, 145 "numImportedGoFiles": 0, 146 "importedFrom": [ 147 "%s" 148 ] 149 } 150 ], 151 "mainOnlyImports": [], 152 "testOnlyImports": [] 153 }`, files["bar.go"].ImportPath, files["pkg/foo/foo.go"].ImportPath) 154 155 cmd := exec.Command("./godelw", "imports") 156 cmd.Dir = testProjectDir 157 output, err := cmd.CombinedOutput() 158 require.NoError(t, err, "Command %v failed. Output:\n%v", cmd.Args, string(output)) 159 160 content, err := ioutil.ReadFile(path.Join(testProjectDir, "pkg", "gocd_imports.json")) 161 require.NoError(t, err) 162 assert.Equal(t, want, string(content)) 163 } 164 165 func TestImportsVerify(t *testing.T) { 166 testProjectDir := setUpGödelTestAndDownload(t, testRootDir, gödelTGZ, version) 167 168 const importsYML = `root-dirs: 169 - pkg` 170 err := ioutil.WriteFile(path.Join(testProjectDir, "godel", "config", "imports.yml"), []byte(importsYML), 0644) 171 require.NoError(t, err) 172 173 specs := []gofiles.GoFileSpec{ 174 { 175 RelPath: "pkg/foo/foo.go", 176 Src: `package foo; import _ "{{index . "bar.go"}}";`, 177 }, 178 { 179 RelPath: "bar.go", 180 Src: "package bar", 181 }, 182 } 183 184 _, err = gofiles.Write(testProjectDir, specs) 185 require.NoError(t, err) 186 187 cmd := exec.Command("./godelw", "imports", "--verify") 188 cmd.Dir = testProjectDir 189 output, err := cmd.CombinedOutput() 190 require.Error(t, err) 191 assert.Equal(t, "gocd_imports.json out of date for 1 directory:\n\tpkg: gocd_imports.json does not exist\n", string(output)) 192 } 193 194 func TestLicense(t *testing.T) { 195 testProjectDir := setUpGödelTestAndDownload(t, testRootDir, gödelTGZ, version) 196 197 const licenseYML = `header: | 198 /* 199 Copyright 2016 Palantir Technologies, Inc. 200 201 Licensed under the Apache License, Version 2.0 (the "License"); 202 you may not use this file except in compliance with the License. 203 You may obtain a copy of the License at 204 205 http://www.apache.org/licenses/LICENSE-2.0 206 207 Unless required by applicable law or agreed to in writing, software 208 distributed under the License is distributed on an "AS IS" BASIS, 209 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 210 See the License for the specific language governing permissions and 211 limitations under the License. 212 */ 213 ` 214 err := ioutil.WriteFile(path.Join(testProjectDir, "godel", "config", "license.yml"), []byte(licenseYML), 0644) 215 require.NoError(t, err) 216 217 specs := []gofiles.GoFileSpec{ 218 { 219 RelPath: "foo.go", 220 Src: "package foo", 221 }, 222 { 223 RelPath: "vendor/github.com/bar.go", 224 Src: "package bar", 225 }, 226 } 227 228 files, err := gofiles.Write(testProjectDir, specs) 229 require.NoError(t, err) 230 231 want := `/* 232 Copyright 2016 Palantir Technologies, Inc. 233 234 Licensed under the Apache License, Version 2.0 (the "License"); 235 you may not use this file except in compliance with the License. 236 You may obtain a copy of the License at 237 238 http://www.apache.org/licenses/LICENSE-2.0 239 240 Unless required by applicable law or agreed to in writing, software 241 distributed under the License is distributed on an "AS IS" BASIS, 242 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 243 See the License for the specific language governing permissions and 244 limitations under the License. 245 */ 246 247 package foo` 248 249 cmd := exec.Command("./godelw", "license") 250 cmd.Dir = testProjectDir 251 output, err := cmd.CombinedOutput() 252 require.NoError(t, err, "Command %v failed. Output:\n%v", cmd.Args, string(output)) 253 254 content, err := ioutil.ReadFile(files["foo.go"].Path) 255 require.NoError(t, err) 256 assert.Equal(t, want, string(content)) 257 258 want = `package bar` 259 content, err = ioutil.ReadFile(files["vendor/github.com/bar.go"].Path) 260 require.NoError(t, err) 261 assert.Equal(t, want, string(content)) 262 } 263 264 func TestLicenseVerify(t *testing.T) { 265 testProjectDir := setUpGödelTestAndDownload(t, testRootDir, gödelTGZ, version) 266 267 const licenseYML = `header: | 268 /* 269 Copyright 2016 Palantir Technologies, Inc. 270 271 Licensed under the Apache License, Version 2.0 (the "License"); 272 you may not use this file except in compliance with the License. 273 You may obtain a copy of the License at 274 275 http://www.apache.org/licenses/LICENSE-2.0 276 277 Unless required by applicable law or agreed to in writing, software 278 distributed under the License is distributed on an "AS IS" BASIS, 279 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 280 See the License for the specific language governing permissions and 281 limitations under the License. 282 */ 283 ` 284 err := ioutil.WriteFile(path.Join(testProjectDir, "godel", "config", "license.yml"), []byte(licenseYML), 0644) 285 require.NoError(t, err) 286 287 specs := []gofiles.GoFileSpec{ 288 { 289 RelPath: "foo.go", 290 Src: "package foo", 291 }, 292 { 293 RelPath: "bar/bar.go", 294 Src: `/* 295 Copyright 2016 Palantir Technologies, Inc. 296 297 Licensed under the Apache License, Version 2.0 (the "License"); 298 you may not use this file except in compliance with the License. 299 You may obtain a copy of the License at 300 301 http://www.apache.org/licenses/LICENSE-2.0 302 303 Unless required by applicable law or agreed to in writing, software 304 distributed under the License is distributed on an "AS IS" BASIS, 305 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 306 See the License for the specific language governing permissions and 307 limitations under the License. 308 */ 309 310 package bar`, 311 }, 312 { 313 RelPath: "vendor/github.com/baz.go", 314 Src: "package baz", 315 }, 316 } 317 318 _, err = gofiles.Write(testProjectDir, specs) 319 require.NoError(t, err) 320 321 cmd := exec.Command("./godelw", "license", "--verify") 322 cmd.Dir = testProjectDir 323 output, err := cmd.CombinedOutput() 324 require.Error(t, err) 325 assert.Equal(t, "1 file does not have the correct license header:\n\tfoo.go\n", string(output)) 326 } 327 328 func TestCheck(t *testing.T) { 329 testProjectDir := setUpGödelTestAndDownload(t, testRootDir, gödelTGZ, version) 330 src := `package main 331 import "fmt" 332 333 func main() { 334 fmt.Println("hello, world!") 335 }` 336 err := ioutil.WriteFile(path.Join(testProjectDir, "main.go"), []byte(src), 0644) 337 require.NoError(t, err) 338 339 cmd := exec.Command("./godelw", "check") 340 cmd.Dir = testProjectDir 341 output, err := cmd.CombinedOutput() 342 require.NoError(t, err, "Command %v failed. Output:\n%v", cmd.Args, string(output)) 343 } 344 345 func TestProducts(t *testing.T) { 346 testProjectDir := setUpGödelTestAndDownload(t, testRootDir, gödelTGZ, version) 347 348 distYml := ` 349 products: 350 foo: 351 build: 352 main-pkg: ./foo 353 bar: 354 build: 355 main-pkg: ./bar 356 ` 357 err := ioutil.WriteFile(path.Join(testProjectDir, "godel", "config", "dist.yml"), []byte(distYml), 0644) 358 require.NoError(t, err) 359 360 src := `package main 361 import "fmt" 362 363 func main() { 364 fmt.Println("hello, world!") 365 }` 366 err = os.MkdirAll(path.Join(testProjectDir, "foo"), 0755) 367 require.NoError(t, err) 368 err = ioutil.WriteFile(path.Join(testProjectDir, "foo", "foo.go"), []byte(src), 0644) 369 require.NoError(t, err) 370 371 err = os.MkdirAll(path.Join(testProjectDir, "bar"), 0755) 372 require.NoError(t, err) 373 err = ioutil.WriteFile(path.Join(testProjectDir, "bar", "bar.go"), []byte(src), 0644) 374 require.NoError(t, err) 375 376 cmd := exec.Command("./godelw", "products") 377 cmd.Dir = testProjectDir 378 output, err := cmd.CombinedOutput() 379 require.NoError(t, err, "Command %v failed. Output:\n%v", cmd.Args, string(output)) 380 assert.Equal(t, "bar\nfoo\n", string(output)) 381 } 382 383 func TestArtifactsBuild(t *testing.T) { 384 testProjectDir := setUpGödelTestAndDownload(t, testRootDir, gödelTGZ, version) 385 gittest.InitGitDir(t, testProjectDir) 386 387 distYml := ` 388 products: 389 foo: 390 build: 391 main-pkg: ./foo 392 os-archs: 393 - os: darwin 394 arch: amd64 395 - os: linux 396 arch: amd64 397 bar: 398 build: 399 main-pkg: ./bar 400 os-archs: 401 - os: windows 402 arch: amd64 403 ` 404 err := ioutil.WriteFile(path.Join(testProjectDir, "godel", "config", "dist.yml"), []byte(distYml), 0644) 405 require.NoError(t, err) 406 407 src := `package main 408 import "fmt" 409 410 func main() { 411 fmt.Println("hello, world!") 412 }` 413 err = os.MkdirAll(path.Join(testProjectDir, "foo"), 0755) 414 require.NoError(t, err) 415 err = ioutil.WriteFile(path.Join(testProjectDir, "foo", "foo.go"), []byte(src), 0644) 416 require.NoError(t, err) 417 418 err = os.MkdirAll(path.Join(testProjectDir, "bar"), 0755) 419 require.NoError(t, err) 420 err = ioutil.WriteFile(path.Join(testProjectDir, "bar", "bar.go"), []byte(src), 0644) 421 require.NoError(t, err) 422 423 gittest.CommitAllFiles(t, testProjectDir, "Commit files") 424 gittest.CreateGitTag(t, testProjectDir, "0.1.0") 425 426 cmd := exec.Command("./godelw", "artifacts", "build") 427 cmd.Dir = testProjectDir 428 output, err := cmd.CombinedOutput() 429 require.NoError(t, err, "Command %v failed. Output:\n%v", cmd.Args, string(output)) 430 431 want := `build/0.1.0/windows-amd64/bar.exe 432 build/0.1.0/darwin-amd64/foo 433 build/0.1.0/linux-amd64/foo 434 ` 435 assert.Equal(t, want, string(output)) 436 } 437 438 func TestArtifactsDist(t *testing.T) { 439 testProjectDir := setUpGödelTestAndDownload(t, testRootDir, gödelTGZ, version) 440 gittest.InitGitDir(t, testProjectDir) 441 442 distYml := ` 443 products: 444 foo: 445 build: 446 main-pkg: ./foo 447 bar: 448 build: 449 main-pkg: ./bar 450 ` 451 err := ioutil.WriteFile(path.Join(testProjectDir, "godel", "config", "dist.yml"), []byte(distYml), 0644) 452 require.NoError(t, err) 453 454 src := `package main 455 import "fmt" 456 457 func main() { 458 fmt.Println("hello, world!") 459 }` 460 err = os.MkdirAll(path.Join(testProjectDir, "foo"), 0755) 461 require.NoError(t, err) 462 err = ioutil.WriteFile(path.Join(testProjectDir, "foo", "foo.go"), []byte(src), 0644) 463 require.NoError(t, err) 464 465 err = os.MkdirAll(path.Join(testProjectDir, "bar"), 0755) 466 require.NoError(t, err) 467 err = ioutil.WriteFile(path.Join(testProjectDir, "bar", "bar.go"), []byte(src), 0644) 468 require.NoError(t, err) 469 470 gittest.CommitAllFiles(t, testProjectDir, "Commit files") 471 gittest.CreateGitTag(t, testProjectDir, "0.1.0") 472 473 cmd := exec.Command("./godelw", "artifacts", "dist") 474 cmd.Dir = testProjectDir 475 output, err := cmd.CombinedOutput() 476 require.NoError(t, err, "Command %v failed. Output:\n%v", cmd.Args, string(output)) 477 assert.Equal(t, "dist/bar-0.1.0.sls.tgz\ndist/foo-0.1.0.sls.tgz\n", string(output)) 478 } 479 480 func TestTest(t *testing.T) { 481 testProjectDir := setUpGödelTestAndDownload(t, testRootDir, gödelTGZ, version) 482 src := `package foo_test 483 import "testing" 484 485 func TestFoo(t *testing.T) {}` 486 err := ioutil.WriteFile(path.Join(testProjectDir, "foo_test.go"), []byte(src), 0644) 487 require.NoError(t, err) 488 489 cmd := exec.Command("./godelw", "test") 490 cmd.Dir = testProjectDir 491 output, err := cmd.CombinedOutput() 492 require.NoError(t, err, "Command %v failed. Output:\n%v", cmd.Args, string(output)) 493 } 494 495 // Run "../godelw check" and ensure that it works (command supports being invoked from subdirectory). The action should 496 // execute with the subdirectory as the working directory. 497 func TestCheckFromNestedDirectory(t *testing.T) { 498 testProjectDir := setUpGödelTestAndDownload(t, testRootDir, gödelTGZ, version) 499 500 // write invalid Go file to root directory of project 501 badSrc := `badContentForGoFile` 502 err := ioutil.WriteFile(path.Join(testProjectDir, "main.go"), []byte(badSrc), 0644) 503 require.NoError(t, err) 504 505 // write valid Go file to child directory 506 childDir := path.Join(testProjectDir, "childDir") 507 err = os.MkdirAll(childDir, 0755) 508 require.NoError(t, err) 509 src := `package main 510 import "fmt" 511 512 func main() { 513 fmt.Println("hello, world!") 514 }` 515 err = ioutil.WriteFile(path.Join(childDir, "main.go"), []byte(src), 0644) 516 require.NoError(t, err) 517 518 cmd := exec.Command("../godelw", "check") 519 cmd.Dir = childDir 520 output, err := cmd.CombinedOutput() 521 require.NoError(t, err, "Command %v failed. Output:\n%v", cmd.Args, string(output)) 522 } 523 524 // Run "../godelw build" and ensure that it works (command supports being invoked from sub-directory). The build action 525 // should execute with the root project directory as the working directory. Verifies #235. 526 func TestBuildFromNestedDirectory(t *testing.T) { 527 testProjectDir := setUpGödelTestAndDownload(t, testRootDir, gödelTGZ, version) 528 src := `package main 529 import "fmt" 530 531 func main() { 532 fmt.Println("hello, world!") 533 }` 534 err := ioutil.WriteFile(path.Join(testProjectDir, "main.go"), []byte(src), 0644) 535 require.NoError(t, err) 536 537 childDir := path.Join(testProjectDir, "childDir") 538 err = os.MkdirAll(childDir, 0755) 539 require.NoError(t, err) 540 541 cmd := exec.Command("../godelw", "build") 542 cmd.Dir = childDir 543 output, err := cmd.CombinedOutput() 544 require.NoError(t, err, "Command %v failed. Output:\n%v", cmd.Args, string(output)) 545 546 info, err := os.Stat(path.Join(testProjectDir, "build")) 547 require.NoError(t, err) 548 assert.True(t, info.IsDir()) 549 } 550 551 // Run "./godelw publish" and verify that it prints a help message and exits with a non-0 exit code. Verifies #243. 552 func TestPublishWithNoAction(t *testing.T) { 553 testProjectDir := setUpGödelTestAndDownload(t, testRootDir, gödelTGZ, version) 554 src := `package main 555 import "fmt" 556 557 func main() { 558 fmt.Println("hello, world!") 559 }` 560 err := ioutil.WriteFile(path.Join(testProjectDir, "main.go"), []byte(src), 0644) 561 require.NoError(t, err) 562 563 cmd := exec.Command("./godelw", "publish") 564 cmd.Dir = testProjectDir 565 output, err := cmd.CombinedOutput() 566 require.Error(t, err) 567 assert.Regexp(t, regexp.MustCompile(`(?s)NAME:.+publish - Publish product distributions.+USAGE:.+godel publish.+SUBCOMMANDS:.+FLAGS:.+`), string(output)) 568 } 569 570 func TestVerify(t *testing.T) { 571 testProjectDir := setUpGödelTestAndDownload(t, testRootDir, gödelTGZ, version) 572 const ( 573 src = `package main 574 import "fmt" 575 576 func main() { 577 fmt.Println("hello, world!") 578 }` 579 testSrc = `package main_test 580 import "testing" 581 582 func TestFoo(t *testing.T) { 583 t=t 584 t.Fail() 585 }` 586 importsYML = `root-dirs: 587 - .` 588 licenseYML = `header: | 589 /* 590 Copyright 2016 Palantir Technologies, Inc. 591 592 Licensed under the Apache License, Version 2.0 (the "License"); 593 you may not use this file except in compliance with the License. 594 You may obtain a copy of the License at 595 596 http://www.apache.org/licenses/LICENSE-2.0 597 598 Unless required by applicable law or agreed to in writing, software 599 distributed under the License is distributed on an "AS IS" BASIS, 600 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 601 See the License for the specific language governing permissions and 602 limitations under the License. 603 */ 604 ` 605 ) 606 err := ioutil.WriteFile(path.Join(testProjectDir, "main.go"), []byte(src), 0644) 607 require.NoError(t, err) 608 err = ioutil.WriteFile(path.Join(testProjectDir, "main_test.go"), []byte(testSrc), 0644) 609 require.NoError(t, err) 610 err = ioutil.WriteFile(path.Join(testProjectDir, "godel", "config", "imports.yml"), []byte(importsYML), 0644) 611 require.NoError(t, err) 612 err = ioutil.WriteFile(path.Join(testProjectDir, "godel", "config", "license.yml"), []byte(licenseYML), 0644) 613 require.NoError(t, err) 614 615 for i, currCase := range []struct { 616 args []string 617 want string 618 }{ 619 {want: `(?s).+Failed tasks:\n\tformat -v -l\n\timports --verify\n\tlicense --verify\n\tcheck\n\ttest`}, 620 {args: []string{"--skip-format"}, want: `(?s).+Failed tasks:\n\timports --verify\n\tlicense --verify\n\tcheck\n\ttest`}, 621 {args: []string{"--skip-check"}, want: `(?s).+Failed tasks:\n\tformat -v -l\n\timports --verify\n\tlicense --verify\n\ttest`}, 622 {args: []string{"--skip-imports"}, want: `(?s).+Failed tasks:\n\tformat -v -l\n\tlicense --verify\n\tcheck\n\ttest`}, 623 {args: []string{"--skip-license"}, want: `(?s).+Failed tasks:\n\tformat -v -l\n\timports --verify\n\tcheck\n\ttest`}, 624 {args: []string{"--skip-test"}, want: `(?s).+Failed tasks:\n\tformat -v -l\n\timports --verify\n\tlicense --verify\n\tcheck`}, 625 } { 626 cmd := exec.Command("./godelw", append([]string{"verify", "--apply=false"}, currCase.args...)...) 627 cmd.Dir = testProjectDir 628 output, err := cmd.CombinedOutput() 629 require.Error(t, err) 630 assert.Regexp(t, regexp.MustCompile(currCase.want), string(output), "Case %d", i) 631 } 632 } 633 634 func TestVerifyApply(t *testing.T) { 635 testProjectDir := setUpGödelTestAndDownload(t, testRootDir, gödelTGZ, version) 636 const ( 637 src = `package main 638 import "fmt" 639 640 func main() { 641 fmt.Println("hello, world!") 642 }` 643 testSrc = `package main_test 644 import "testing" 645 646 func TestFoo(t *testing.T) { 647 t=t 648 t.Fail() 649 }` 650 formattedTestSrc = `package main_test 651 652 import ( 653 "testing" 654 ) 655 656 func TestFoo(t *testing.T) { 657 t = t 658 t.Fail() 659 } 660 ` 661 licensedTestSrc = `/* 662 Copyright 2016 Palantir Technologies, Inc. 663 664 Licensed under the Apache License, Version 2.0 (the "License"); 665 you may not use this file except in compliance with the License. 666 You may obtain a copy of the License at 667 668 http://www.apache.org/licenses/LICENSE-2.0 669 670 Unless required by applicable law or agreed to in writing, software 671 distributed under the License is distributed on an "AS IS" BASIS, 672 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 673 See the License for the specific language governing permissions and 674 limitations under the License. 675 */ 676 677 package main_test 678 import "testing" 679 680 func TestFoo(t *testing.T) { 681 t=t 682 t.Fail() 683 }` 684 licensedAndFormattedTestSrc = `/* 685 Copyright 2016 Palantir Technologies, Inc. 686 687 Licensed under the Apache License, Version 2.0 (the "License"); 688 you may not use this file except in compliance with the License. 689 You may obtain a copy of the License at 690 691 http://www.apache.org/licenses/LICENSE-2.0 692 693 Unless required by applicable law or agreed to in writing, software 694 distributed under the License is distributed on an "AS IS" BASIS, 695 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 696 See the License for the specific language governing permissions and 697 limitations under the License. 698 */ 699 700 package main_test 701 702 import ( 703 "testing" 704 ) 705 706 func TestFoo(t *testing.T) { 707 t = t 708 t.Fail() 709 } 710 ` 711 importsYML = `root-dirs: 712 - .` 713 importsJSON = `{ 714 "imports": [], 715 "mainOnlyImports": [], 716 "testOnlyImports": [] 717 }` 718 719 licenseYML = `header: | 720 /* 721 Copyright 2016 Palantir Technologies, Inc. 722 723 Licensed under the Apache License, Version 2.0 (the "License"); 724 you may not use this file except in compliance with the License. 725 You may obtain a copy of the License at 726 727 http://www.apache.org/licenses/LICENSE-2.0 728 729 Unless required by applicable law or agreed to in writing, software 730 distributed under the License is distributed on an "AS IS" BASIS, 731 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 732 See the License for the specific language governing permissions and 733 limitations under the License. 734 */ 735 ` 736 ) 737 err := ioutil.WriteFile(path.Join(testProjectDir, "main.go"), []byte(src), 0644) 738 require.NoError(t, err) 739 err = ioutil.WriteFile(path.Join(testProjectDir, "godel", "config", "imports.yml"), []byte(importsYML), 0644) 740 require.NoError(t, err) 741 err = ioutil.WriteFile(path.Join(testProjectDir, "godel", "config", "license.yml"), []byte(licenseYML), 0644) 742 require.NoError(t, err) 743 744 for i, currCase := range []struct { 745 args []string 746 want string 747 wantTestSrc string 748 wantImportsJSON string 749 }{ 750 {want: `(?s).+Failed tasks:\n\tcheck\n\ttest`, wantTestSrc: licensedAndFormattedTestSrc, wantImportsJSON: importsJSON}, 751 {args: []string{"--skip-format"}, want: `(?s).+Failed tasks:\n\tcheck\n\ttest`, wantTestSrc: licensedTestSrc, wantImportsJSON: importsJSON}, 752 {args: []string{"--skip-imports"}, want: `(?s).+Failed tasks:\n\tcheck\n\ttest`, wantTestSrc: licensedAndFormattedTestSrc}, 753 {args: []string{"--skip-license"}, want: `(?s).+Failed tasks:\n\tcheck\n\ttest`, wantTestSrc: formattedTestSrc, wantImportsJSON: importsJSON}, 754 {args: []string{"--skip-check"}, want: `(?s).+Failed tasks:\n\ttest`, wantTestSrc: licensedAndFormattedTestSrc, wantImportsJSON: importsJSON}, 755 {args: []string{"--skip-test"}, want: `(?s).+Failed tasks:\n\tcheck`, wantTestSrc: licensedAndFormattedTestSrc, wantImportsJSON: importsJSON}, 756 } { 757 err = ioutil.WriteFile(path.Join(testProjectDir, "main_test.go"), []byte(testSrc), 0644) 758 require.NoError(t, err, "Case %d", i) 759 760 cmd := exec.Command("./godelw", append([]string{"verify"}, currCase.args...)...) 761 cmd.Dir = testProjectDir 762 output, err := cmd.CombinedOutput() 763 require.Error(t, err, fmt.Sprintf("Case %d", i)) 764 assert.Regexp(t, regexp.MustCompile(currCase.want), string(output), "Case %d", i) 765 766 bytes, err := ioutil.ReadFile(path.Join(testProjectDir, "main_test.go")) 767 require.NoError(t, err, "Case %d", i) 768 assert.Equal(t, currCase.wantTestSrc, string(bytes), "Case %d", i) 769 770 importsJSONPath := path.Join(testProjectDir, "gocd_imports.json") 771 if currCase.wantImportsJSON == "" { 772 _, err = os.Stat(importsJSONPath) 773 assert.True(t, os.IsNotExist(err), "Case %d: gocd_imports.json should not exist", i) 774 } else { 775 bytes, err = ioutil.ReadFile(importsJSONPath) 776 require.NoError(t, err, "Case %d", i) 777 assert.Equal(t, currCase.wantImportsJSON, string(bytes), "Case %d", i) 778 err = os.Remove(importsJSONPath) 779 require.NoError(t, err, "Case %d", i) 780 } 781 } 782 } 783 784 func TestVerifyWithJUnitOutput(t *testing.T) { 785 testProjectDir := setUpGödelTestAndDownload(t, testRootDir, gödelTGZ, version) 786 src := `package main 787 import "fmt" 788 func main() { 789 fmt.Println("hello, world!") 790 }` 791 err := ioutil.WriteFile(path.Join(testProjectDir, "main.go"), []byte(src), 0644) 792 require.NoError(t, err) 793 testSrc := `package main_test 794 import "testing" 795 func TestFoo(t *testing.T) { 796 }` 797 err = ioutil.WriteFile(path.Join(testProjectDir, "main_test.go"), []byte(testSrc), 0644) 798 require.NoError(t, err) 799 800 junitOutputFile := "test-output.xml" 801 cmd := exec.Command("./godelw", "verify", "--apply=false", "--junit-output", junitOutputFile) 802 cmd.Dir = testProjectDir 803 err = cmd.Run() 804 require.Error(t, err) 805 806 fi, err := os.Stat(path.Join(testProjectDir, junitOutputFile)) 807 require.NoError(t, err) 808 809 assert.False(t, fi.IsDir()) 810 } 811 812 func TestDebugFlagPrintsStackTrace(t *testing.T) { 813 testProjectDir := setUpGödelTestAndDownload(t, testRootDir, gödelTGZ, version) 814 815 cmd := exec.Command("./godelw", "install", "foo") 816 cmd.Dir = testProjectDir 817 output, err := cmd.CombinedOutput() 818 require.Error(t, err) 819 assert.Regexp(t, `^Failed to install from foo into .+: foo does not exist\n$`, string(output)) 820 821 cmd = exec.Command("./godelw", "--debug", "install", "foo") 822 cmd.Dir = testProjectDir 823 output, err = cmd.CombinedOutput() 824 require.Error(t, err) 825 assert.Regexp(t, `(?s)^foo does not exist.+cmd/godel.localPkg.getPkg.+Failed to install from foo into .+`, string(output)) 826 } 827 828 // * Symlink "test-go" -> $GOPATH 829 // * Set current directory to test project inside the symlink 830 // * Verify that "./godelw check" works in sym-linked path 831 func TestCheckInGoPathSymLink(t *testing.T) { 832 testProjectDir := setUpGödelTestAndDownload(t, testRootDir, gödelTGZ, version) 833 src := `package foo_test 834 import "testing" 835 836 func TestFoo(t *testing.T) {}` 837 err := ioutil.WriteFile(path.Join(testProjectDir, "foo_test.go"), []byte(src), 0644) 838 require.NoError(t, err) 839 840 symLinkParentDir, cleanup, err := dirs.TempDir("", "") 841 defer cleanup() 842 require.NoError(t, err) 843 symLinkPath := path.Join(symLinkParentDir, "test-go") 844 845 originalGoPath := os.Getenv("GOPATH") 846 err = os.Symlink(originalGoPath, symLinkPath) 847 require.NoError(t, err) 848 849 testProjectRelPath, err := filepath.Rel(originalGoPath, testProjectDir) 850 require.NoError(t, err) 851 852 // use script to set cd because setting wd on exec.Command does not work for symlinks 853 projectPathInSymLink := path.Join(symLinkPath, testProjectRelPath) 854 scriptTemplate := `#!/bin/bash 855 cd %v 856 pwd 857 ` 858 scriptFilePath := path.Join(symLinkParentDir, "script.sh") 859 err = ioutil.WriteFile(scriptFilePath, []byte(fmt.Sprintf(scriptTemplate, projectPathInSymLink)), 0755) 860 require.NoError(t, err) 861 862 cmd := exec.Command(scriptFilePath) 863 output, err := cmd.CombinedOutput() 864 require.NoError(t, err, "Command %v failed. Output:\n%v", cmd.Args, string(output)) 865 assert.Equal(t, projectPathInSymLink, strings.TrimSpace(string(output))) 866 867 scriptTemplate = `#!/bin/bash 868 cd %v 869 ./godelw check 870 ` 871 err = ioutil.WriteFile(scriptFilePath, []byte(fmt.Sprintf(scriptTemplate, projectPathInSymLink)), 0755) 872 require.NoError(t, err) 873 874 cmd = exec.Command(scriptFilePath) 875 output, err = cmd.CombinedOutput() 876 require.NoError(t, err, "Command %v failed. Output:\n%v", cmd.Args, string(output)) 877 } 878 879 // * Symlink "test-go" -> $GOPATH 880 // * Set $GOPATH to be the symlink ("test-go") 881 // * Set current directory to test project inside the symlink 882 // * Verify that "./godelw check" works in sym-linked path 883 // * Restore $GOPATH to original value 884 func TestCheckInGoPathSymLinkGoPathSymLink(t *testing.T) { 885 testProjectDir := setUpGödelTestAndDownload(t, testRootDir, gödelTGZ, version) 886 src := `package foo_test 887 import "testing" 888 889 func TestFoo(t *testing.T) {}` 890 err := ioutil.WriteFile(path.Join(testProjectDir, "foo_test.go"), []byte(src), 0644) 891 require.NoError(t, err) 892 893 symLinkParentDir, cleanup, err := dirs.TempDir("", "") 894 defer cleanup() 895 require.NoError(t, err) 896 symLinkPath := path.Join(symLinkParentDir, "test-go") 897 898 originalGoPath := os.Getenv("GOPATH") 899 err = os.Symlink(originalGoPath, symLinkPath) 900 require.NoError(t, err) 901 902 err = os.Setenv("GOPATH", symLinkPath) 903 require.NoError(t, err) 904 defer func() { 905 if err := os.Setenv("GOPATH", originalGoPath); err != nil { 906 require.NoError(t, err, "failed to restore GOPATH environment variable in defer") 907 } 908 }() 909 910 testProjectRelPath, err := filepath.Rel(originalGoPath, testProjectDir) 911 require.NoError(t, err) 912 913 // use script to set cd because setting wd on exec.Command does not work for symlinks 914 projectPathInSymLink := path.Join(symLinkPath, testProjectRelPath) 915 scriptTemplate := `#!/bin/bash 916 cd %v 917 pwd 918 ` 919 scriptFilePath := path.Join(symLinkParentDir, "script.sh") 920 err = ioutil.WriteFile(scriptFilePath, []byte(fmt.Sprintf(scriptTemplate, projectPathInSymLink)), 0755) 921 require.NoError(t, err) 922 923 cmd := exec.Command(scriptFilePath) 924 output, err := cmd.CombinedOutput() 925 require.NoError(t, err, "Command %v failed. Output:\n%v", cmd.Args, string(output)) 926 assert.Equal(t, projectPathInSymLink, strings.TrimSpace(string(output))) 927 928 scriptTemplate = `#!/bin/bash 929 cd %v 930 ./godelw check 931 ` 932 err = ioutil.WriteFile(scriptFilePath, []byte(fmt.Sprintf(scriptTemplate, projectPathInSymLink)), 0755) 933 require.NoError(t, err) 934 935 cmd = exec.Command(scriptFilePath) 936 output, err = cmd.CombinedOutput() 937 require.NoError(t, err, "Command %v failed. Output:\n%v", cmd.Args, string(output)) 938 } 939 940 // * Symlink "test-go" -> $GOPATH 941 // * Set $GOPATH to be the symlink ("test-go") 942 // * Set current directory to real project (not inside symlink) 943 // * Verify that "./godelw check" works in real path 944 // * Restore $GOPATH to original value 945 func TestCheckInGoPathNonSymLinkWhenGoPathIsSymLink(t *testing.T) { 946 testProjectDir := setUpGödelTestAndDownload(t, testRootDir, gödelTGZ, version) 947 src := `package foo_test 948 import "testing" 949 950 func TestFoo(t *testing.T) {}` 951 err := ioutil.WriteFile(path.Join(testProjectDir, "foo_test.go"), []byte(src), 0644) 952 require.NoError(t, err) 953 954 symLinkParentDir, cleanup, err := dirs.TempDir("", "") 955 defer cleanup() 956 require.NoError(t, err) 957 symLinkPath := path.Join(symLinkParentDir, "test-go") 958 959 originalGoPath := os.Getenv("GOPATH") 960 err = os.Symlink(originalGoPath, symLinkPath) 961 require.NoError(t, err) 962 963 err = os.Setenv("GOPATH", symLinkPath) 964 require.NoError(t, err) 965 defer func() { 966 if err := os.Setenv("GOPATH", originalGoPath); err != nil { 967 require.NoError(t, err, "failed to restore GOPATH environment variable in defer") 968 } 969 }() 970 971 cmd := exec.Command("./godelw", "check") 972 cmd.Dir = testProjectDir 973 output, err := cmd.CombinedOutput() 974 require.NoError(t, err, "Command %v failed. Output:\n%v", cmd.Args, string(output)) 975 }