github.com/jonathanlloyd/goreleaser@v0.91.1/internal/pipe/docker/docker_test.go (about) 1 package docker 2 3 import ( 4 "flag" 5 "io/ioutil" 6 "os" 7 "os/exec" 8 "path/filepath" 9 "regexp" 10 "syscall" 11 "testing" 12 13 "github.com/goreleaser/goreleaser/internal/artifact" 14 "github.com/goreleaser/goreleaser/internal/pipe" 15 "github.com/goreleaser/goreleaser/pkg/config" 16 "github.com/goreleaser/goreleaser/pkg/context" 17 "github.com/stretchr/testify/assert" 18 "github.com/stretchr/testify/require" 19 ) 20 21 var it = flag.Bool("it", false, "push images to docker hub") 22 var registry = "localhost:5000/" 23 var altRegistry = "localhost:5050/" 24 25 func TestMain(m *testing.M) { 26 flag.Parse() 27 if *it { 28 registry = "docker.io/" 29 } 30 os.Exit(m.Run()) 31 } 32 33 func start(t *testing.T) { 34 if *it { 35 return 36 } 37 if out, err := exec.Command( 38 "docker", "run", "-d", "-p", "5000:5000", "--name", "registry", "registry:2", 39 ).CombinedOutput(); err != nil { 40 t.Log("failed to start docker registry", string(out), err) 41 t.FailNow() 42 } 43 if out, err := exec.Command( 44 "docker", "run", "-d", "-p", "5050:5000", "--name", "alt_registry", "registry:2", 45 ).CombinedOutput(); err != nil { 46 t.Log("failed to start alternate docker registry", string(out), err) 47 t.FailNow() 48 } 49 } 50 51 func killAndRm(t *testing.T) { 52 if *it { 53 return 54 } 55 t.Log("killing registry") 56 _ = exec.Command("docker", "kill", "registry").Run() 57 _ = exec.Command("docker", "rm", "registry").Run() 58 _ = exec.Command("docker", "kill", "alt_registry").Run() 59 _ = exec.Command("docker", "rm", "alt_registry").Run() 60 } 61 62 func TestRunPipe(t *testing.T) { 63 type errChecker func(*testing.T, error) 64 var shouldErr = func(msg string) errChecker { 65 return func(t *testing.T, err error) { 66 require.Error(t, err) 67 require.Contains(t, err.Error(), msg) 68 } 69 } 70 var shouldNotErr = func(t *testing.T, err error) { 71 require.NoError(t, err) 72 } 73 type imageLabelFinder func(*testing.T, int) 74 var shouldFindImagesWithLabels = func(image string, filters ...string) func(*testing.T, int) { 75 return func(t *testing.T, count int) { 76 for _, filter := range filters { 77 output, err := exec.Command("docker", "images", "--filter", filter).CombinedOutput() 78 require.NoError(t, err) 79 80 matcher := regexp.MustCompile(image) 81 matches := matcher.FindAllStringIndex(string(output), -1) 82 require.Equal(t, count, len(matches)) 83 } 84 } 85 86 } 87 var noLabels = func(t *testing.T, count int) {} 88 89 var table = map[string]struct { 90 dockers []config.Docker 91 publish bool 92 expect []string 93 assertImageLabels imageLabelFinder 94 assertError errChecker 95 pubAssertError errChecker 96 }{ 97 "valid": { 98 publish: true, 99 dockers: []config.Docker{ 100 { 101 ImageTemplates: []string{ 102 registry + "goreleaser/test_run_pipe:{{.Tag}}-{{.Env.FOO}}", 103 registry + "goreleaser/test_run_pipe:v{{.Major}}", 104 registry + "goreleaser/test_run_pipe:v{{.Major}}.{{.Minor}}", 105 registry + "goreleaser/test_run_pipe:commit-{{.Commit}}", 106 registry + "goreleaser/test_run_pipe:le-{{.Os}}", 107 registry + "goreleaser/test_run_pipe:latest", 108 altRegistry + "goreleaser/test_run_pipe:{{.Tag}}-{{.Env.FOO}}", 109 altRegistry + "goreleaser/test_run_pipe:v{{.Major}}", 110 altRegistry + "goreleaser/test_run_pipe:v{{.Major}}.{{.Minor}}", 111 altRegistry + "goreleaser/test_run_pipe:commit-{{.Commit}}", 112 altRegistry + "goreleaser/test_run_pipe:le-{{.Os}}", 113 altRegistry + "goreleaser/test_run_pipe:latest", 114 }, 115 Goos: "linux", 116 Goarch: "amd64", 117 Dockerfile: "testdata/Dockerfile", 118 Binary: "mybin", 119 BuildFlagTemplates: []string{ 120 "--label=org.label-schema.schema-version=1.0", 121 "--label=org.label-schema.version={{.Version}}", 122 "--label=org.label-schema.vcs-ref={{.Commit}}", 123 "--label=org.label-schema.name={{.ProjectName}}", 124 "--build-arg=FRED={{.Tag}}", 125 }, 126 Files: []string{ 127 "testdata/extra_file.txt", 128 }, 129 }, 130 }, 131 expect: []string{ 132 registry + "goreleaser/test_run_pipe:v1.0.0-123", 133 registry + "goreleaser/test_run_pipe:v1", 134 registry + "goreleaser/test_run_pipe:v1.0", 135 registry + "goreleaser/test_run_pipe:commit-a1b2c3d4", 136 registry + "goreleaser/test_run_pipe:le-linux", 137 registry + "goreleaser/test_run_pipe:latest", 138 altRegistry + "goreleaser/test_run_pipe:v1.0.0-123", 139 altRegistry + "goreleaser/test_run_pipe:v1", 140 altRegistry + "goreleaser/test_run_pipe:v1.0", 141 altRegistry + "goreleaser/test_run_pipe:commit-a1b2c3d4", 142 altRegistry + "goreleaser/test_run_pipe:le-linux", 143 altRegistry + "goreleaser/test_run_pipe:latest", 144 }, 145 assertImageLabels: shouldFindImagesWithLabels( 146 "goreleaser/test_run_pipe", 147 "label=org.label-schema.schema-version=1.0", 148 "label=org.label-schema.version=1.0.0", 149 "label=org.label-schema.vcs-ref=a1b2c3d4", 150 "label=org.label-schema.name=mybin"), 151 assertError: shouldNotErr, 152 pubAssertError: shouldNotErr, 153 }, 154 "with deprecated image name & tag templates": { 155 publish: true, 156 dockers: []config.Docker{ 157 { 158 Image: registry + "goreleaser/test_run_pipe", 159 Goos: "linux", 160 Goarch: "amd64", 161 Dockerfile: "testdata/Dockerfile", 162 Binary: "mybin", 163 TagTemplates: []string{ 164 "{{.Tag}}-{{.Env.FOO}}", 165 }, 166 BuildFlagTemplates: []string{ 167 "--label=org.label-schema.version={{.Version}}", 168 }, 169 }, 170 }, 171 expect: []string{ 172 registry + "goreleaser/test_run_pipe:v1.0.0-123", 173 }, 174 assertImageLabels: shouldFindImagesWithLabels( 175 "goreleaser/test_run_pipe", 176 "label=org.label-schema.version=1.0.0", 177 ), 178 assertError: shouldNotErr, 179 pubAssertError: shouldNotErr, 180 }, 181 "multiple images with same extra file": { 182 publish: true, 183 dockers: []config.Docker{ 184 { 185 Image: registry + "goreleaser/multiplefiles1", 186 Goos: "linux", 187 Goarch: "amd64", 188 Dockerfile: "testdata/Dockerfile", 189 Binary: "mybin", 190 TagTemplates: []string{"latest"}, 191 Files: []string{"testdata/extra_file.txt"}, 192 }, 193 { 194 Image: registry + "goreleaser/multiplefiles2", 195 Goos: "linux", 196 Goarch: "amd64", 197 Dockerfile: "testdata/Dockerfile", 198 Binary: "mybin", 199 TagTemplates: []string{"latest"}, 200 Files: []string{"testdata/extra_file.txt"}, 201 }, 202 }, 203 expect: []string{ 204 registry + "goreleaser/multiplefiles1:latest", 205 registry + "goreleaser/multiplefiles2:latest", 206 }, 207 assertImageLabels: noLabels, 208 assertError: shouldNotErr, 209 pubAssertError: shouldNotErr, 210 }, 211 "multiple images with same dockerfile": { 212 publish: true, 213 dockers: []config.Docker{ 214 { 215 Image: registry + "goreleaser/test_run_pipe", 216 Goos: "linux", 217 Goarch: "amd64", 218 Dockerfile: "testdata/Dockerfile", 219 Binary: "mybin", 220 TagTemplates: []string{"latest"}, 221 }, 222 { 223 Image: registry + "goreleaser/test_run_pipe2", 224 Goos: "linux", 225 Goarch: "amd64", 226 Dockerfile: "testdata/Dockerfile", 227 Binary: "mybin", 228 TagTemplates: []string{"latest"}, 229 }, 230 }, 231 assertImageLabels: noLabels, 232 expect: []string{ 233 registry + "goreleaser/test_run_pipe:latest", 234 registry + "goreleaser/test_run_pipe2:latest", 235 }, 236 assertError: shouldNotErr, 237 pubAssertError: shouldNotErr, 238 }, 239 "valid_skip_push": { 240 publish: true, 241 dockers: []config.Docker{ 242 { 243 Image: registry + "goreleaser/test_run_pipe", 244 Goos: "linux", 245 Goarch: "amd64", 246 Dockerfile: "testdata/Dockerfile", 247 Binary: "mybin", 248 SkipPush: true, 249 TagTemplates: []string{"latest"}, 250 }, 251 }, 252 expect: []string{ 253 registry + "goreleaser/test_run_pipe:latest", 254 }, 255 assertImageLabels: noLabels, 256 assertError: shouldNotErr, 257 pubAssertError: shouldNotErr, 258 }, 259 "valid_no_latest": { 260 publish: true, 261 dockers: []config.Docker{ 262 { 263 Image: registry + "goreleaser/test_run_pipe", 264 Goos: "linux", 265 Goarch: "amd64", 266 Dockerfile: "testdata/Dockerfile", 267 Binary: "mybin", 268 TagTemplates: []string{"{{.Version}}"}, 269 }, 270 }, 271 expect: []string{ 272 registry + "goreleaser/test_run_pipe:1.0.0", 273 }, 274 assertImageLabels: noLabels, 275 assertError: shouldNotErr, 276 pubAssertError: shouldNotErr, 277 }, 278 "valid_dont_publish": { 279 publish: false, 280 dockers: []config.Docker{ 281 { 282 Image: registry + "goreleaser/test_run_pipe", 283 Goos: "linux", 284 Goarch: "amd64", 285 Dockerfile: "testdata/Dockerfile", 286 Binary: "mybin", 287 TagTemplates: []string{"latest"}, 288 }, 289 }, 290 expect: []string{ 291 registry + "goreleaser/test_run_pipe:latest", 292 }, 293 assertImageLabels: noLabels, 294 assertError: shouldNotErr, 295 pubAssertError: shouldNotErr, 296 }, 297 "valid build args": { 298 publish: false, 299 dockers: []config.Docker{ 300 { 301 Image: registry + "goreleaser/test_build_args", 302 Goos: "linux", 303 Goarch: "amd64", 304 Dockerfile: "testdata/Dockerfile", 305 Binary: "mybin", 306 TagTemplates: []string{"latest"}, 307 BuildFlagTemplates: []string{ 308 "--label=foo=bar", 309 }, 310 }, 311 }, 312 expect: []string{ 313 registry + "goreleaser/test_build_args:latest", 314 }, 315 assertImageLabels: noLabels, 316 assertError: shouldNotErr, 317 pubAssertError: shouldNotErr, 318 }, 319 "bad build args": { 320 publish: false, 321 dockers: []config.Docker{ 322 { 323 Image: registry + "goreleaser/test_build_args", 324 Goos: "linux", 325 Goarch: "amd64", 326 Dockerfile: "testdata/Dockerfile", 327 Binary: "mybin", 328 TagTemplates: []string{"latest"}, 329 BuildFlagTemplates: []string{ 330 "--bad-flag", 331 }, 332 }, 333 }, 334 assertImageLabels: noLabels, 335 assertError: shouldErr("unknown flag: --bad-flag"), 336 }, 337 "bad_dockerfile": { 338 publish: true, 339 dockers: []config.Docker{ 340 { 341 Image: registry + "goreleaser/bad_dockerfile", 342 Goos: "linux", 343 Goarch: "amd64", 344 Dockerfile: "testdata/Dockerfile.bad", 345 Binary: "mybin", 346 TagTemplates: []string{"latest"}, 347 }, 348 }, 349 assertImageLabels: noLabels, 350 assertError: shouldErr("pull access denied for nope, repository does not exist"), 351 }, 352 "tag_template_error": { 353 publish: true, 354 dockers: []config.Docker{ 355 { 356 Image: registry + "goreleaser/test_run_pipe", 357 Goos: "linux", 358 Goarch: "amd64", 359 Dockerfile: "testdata/Dockerfile", 360 Binary: "mybin", 361 TagTemplates: []string{ 362 "{{.Tag}", 363 }, 364 }, 365 }, 366 assertImageLabels: noLabels, 367 assertError: shouldErr(`template: tmpl:1: unexpected "}" in operand`), 368 }, 369 "build_flag_template_error": { 370 publish: true, 371 dockers: []config.Docker{ 372 { 373 Image: registry + "goreleaser/test_run_pipe", 374 Goos: "linux", 375 Goarch: "amd64", 376 Dockerfile: "testdata/Dockerfile", 377 Binary: "mybin", 378 TagTemplates: []string{"latest"}, 379 BuildFlagTemplates: []string{ 380 "--label=tag={{.Tag}", 381 }, 382 }, 383 }, 384 assertImageLabels: noLabels, 385 assertError: shouldErr(`template: tmpl:1: unexpected "}" in operand`), 386 }, 387 "missing_env_on_tag_template": { 388 publish: true, 389 dockers: []config.Docker{ 390 { 391 Image: registry + "goreleaser/test_run_pipe", 392 Goos: "linux", 393 Goarch: "amd64", 394 Dockerfile: "testdata/Dockerfile", 395 Binary: "mybin", 396 TagTemplates: []string{ 397 "{{.Env.NOPE}}", 398 }, 399 }, 400 }, 401 assertImageLabels: noLabels, 402 assertError: shouldErr(`template: tmpl:1:46: executing "tmpl" at <.Env.NOPE>: map has no entry for key "NOPE"`), 403 }, 404 "missing_env_on_build_flag_template": { 405 publish: true, 406 dockers: []config.Docker{ 407 { 408 Image: registry + "goreleaser/test_run_pipe", 409 Goos: "linux", 410 Goarch: "amd64", 411 Dockerfile: "testdata/Dockerfile", 412 Binary: "mybin", 413 TagTemplates: []string{"latest"}, 414 BuildFlagTemplates: []string{ 415 "--label=nope={{.Env.NOPE}}", 416 }, 417 }, 418 }, 419 assertImageLabels: noLabels, 420 assertError: shouldErr(`template: tmpl:1:19: executing "tmpl" at <.Env.NOPE>: map has no entry for key "NOPE"`), 421 }, 422 "image_has_projectname_template_variable": { 423 publish: true, 424 dockers: []config.Docker{ 425 { 426 Image: registry + "goreleaser/{{.ProjectName}}", 427 Goos: "linux", 428 Goarch: "amd64", 429 Dockerfile: "testdata/Dockerfile", 430 Binary: "mybin", 431 SkipPush: true, 432 TagTemplates: []string{ 433 "{{.Tag}}-{{.Env.FOO}}", 434 "latest", 435 }, 436 }, 437 }, 438 expect: []string{ 439 registry + "goreleaser/mybin:v1.0.0-123", 440 registry + "goreleaser/mybin:latest", 441 }, 442 assertImageLabels: noLabels, 443 assertError: shouldNotErr, 444 pubAssertError: shouldNotErr, 445 }, 446 "no_permissions": { 447 publish: true, 448 dockers: []config.Docker{ 449 { 450 Image: "docker.io/nope", 451 Goos: "linux", 452 Goarch: "amd64", 453 Binary: "mybin", 454 Dockerfile: "testdata/Dockerfile", 455 TagTemplates: []string{"latest"}, 456 }, 457 }, 458 expect: []string{ 459 "docker.io/nope:latest", 460 }, 461 assertImageLabels: noLabels, 462 assertError: shouldNotErr, 463 pubAssertError: shouldErr(`requested access to the resource is denied`), 464 }, 465 "dockerfile_doesnt_exist": { 466 publish: true, 467 dockers: []config.Docker{ 468 { 469 Image: "whatever", 470 Goos: "linux", 471 Goarch: "amd64", 472 Binary: "mybin", 473 Dockerfile: "testdata/Dockerfilezzz", 474 TagTemplates: []string{"latest"}, 475 }, 476 }, 477 assertImageLabels: noLabels, 478 assertError: shouldErr(`failed to link dockerfile`), 479 }, 480 "extra_file_doesnt_exist": { 481 publish: true, 482 dockers: []config.Docker{ 483 { 484 Image: "whatever", 485 Goos: "linux", 486 Goarch: "amd64", 487 Binary: "mybin", 488 Dockerfile: "testdata/Dockerfile", 489 TagTemplates: []string{"latest"}, 490 Files: []string{ 491 "testdata/nope.txt", 492 }, 493 }, 494 }, 495 assertImageLabels: noLabels, 496 assertError: shouldErr(`failed to link extra file 'testdata/nope.txt'`), 497 }, 498 "no_matching_binaries": { 499 publish: true, 500 dockers: []config.Docker{ 501 { 502 Image: "whatever", 503 Goos: "darwin", 504 Goarch: "amd64", 505 Binary: "mybinnnn", 506 Dockerfile: "testdata/Dockerfile", 507 }, 508 }, 509 assertImageLabels: noLabels, 510 assertError: shouldErr(`0 binaries match docker definition: mybinnnn: darwin_amd64_`), 511 }, 512 "mixed image and image template": { 513 publish: true, 514 dockers: []config.Docker{ 515 { 516 ImageTemplates: []string{ 517 registry + "goreleaser/test_run_pipe:latest", 518 }, 519 Image: registry + "goreleaser/test_run_pipe", 520 Goos: "darwin", 521 Goarch: "amd64", 522 Binary: "mybin", 523 Dockerfile: "testdata/Dockerfile", 524 TagTemplates: []string{"latest"}, 525 }, 526 }, 527 assertImageLabels: noLabels, 528 assertError: shouldErr("failed to process image, use either image_templates (preferred) or image, not both"), 529 }, 530 } 531 532 killAndRm(t) 533 start(t) 534 defer killAndRm(t) 535 536 for name, docker := range table { 537 t.Run(name, func(tt *testing.T) { 538 folder, err := ioutil.TempDir("", "dockertest") 539 require.NoError(tt, err) 540 var dist = filepath.Join(folder, "dist") 541 require.NoError(tt, os.Mkdir(dist, 0755)) 542 require.NoError(tt, os.Mkdir(filepath.Join(dist, "mybin"), 0755)) 543 var binPath = filepath.Join(dist, "mybin", "mybin") 544 _, err = os.Create(binPath) 545 require.NoError(tt, err) 546 547 var ctx = context.New(config.Project{ 548 ProjectName: "mybin", 549 Dist: dist, 550 Dockers: docker.dockers, 551 }) 552 ctx.SkipPublish = !docker.publish 553 ctx.Env = map[string]string{ 554 "FOO": "123", 555 } 556 ctx.Version = "1.0.0" 557 ctx.Git = context.GitInfo{ 558 CurrentTag: "v1.0.0", 559 Commit: "a1b2c3d4", 560 } 561 for _, os := range []string{"linux", "darwin"} { 562 for _, arch := range []string{"amd64", "386"} { 563 ctx.Artifacts.Add(artifact.Artifact{ 564 Name: "mybin", 565 Path: binPath, 566 Goarch: arch, 567 Goos: os, 568 Type: artifact.Binary, 569 Extra: map[string]string{ 570 "Binary": "mybin", 571 }, 572 }) 573 } 574 } 575 576 // this might fail as the image doesnt exist yet, so lets ignore the error 577 for _, img := range docker.expect { 578 _ = exec.Command("docker", "rmi", img).Run() 579 } 580 581 err = Pipe{}.Run(ctx) 582 docker.assertError(tt, err) 583 if err == nil { 584 docker.pubAssertError(tt, Pipe{}.Publish(ctx)) 585 } 586 587 for _, d := range docker.dockers { 588 if d.ImageTemplates == nil { 589 docker.assertImageLabels(tt, len(d.TagTemplates)) 590 } else { 591 docker.assertImageLabels(tt, len(d.ImageTemplates)) 592 } 593 } 594 595 // this might should not fail as the image should have been created when 596 // the step ran 597 for _, img := range docker.expect { 598 tt.Log("removing docker image", img) 599 require.NoError(tt, exec.Command("docker", "rmi", img).Run(), "could not delete image %s", img) 600 } 601 602 }) 603 } 604 } 605 606 func TestBuildCommand(t *testing.T) { 607 image := "goreleaser/test_build_flag" 608 tests := []struct { 609 name string 610 flags []string 611 expect []string 612 }{ 613 { 614 name: "no flags", 615 flags: []string{}, 616 expect: []string{"build", "-t", image, "."}, 617 }, 618 { 619 name: "single flag", 620 flags: []string{"--label=foo"}, 621 expect: []string{"build", "-t", image, ".", "--label=foo"}, 622 }, 623 { 624 name: "multiple flags", 625 flags: []string{"--label=foo", "--build-arg=bar=baz"}, 626 expect: []string{"build", "-t", image, ".", "--label=foo", "--build-arg=bar=baz"}, 627 }, 628 } 629 for _, tt := range tests { 630 t.Run(tt.name, func(t *testing.T) { 631 command := buildCommand(image, tt.flags) 632 assert.Equal(t, tt.expect, command) 633 }) 634 } 635 } 636 637 func TestDescription(t *testing.T) { 638 assert.NotEmpty(t, Pipe{}.String()) 639 } 640 641 func TestNoDockers(t *testing.T) { 642 assert.True(t, pipe.IsSkip(Pipe{}.Run(context.New(config.Project{})))) 643 } 644 645 func TestNoDockerWithoutImageName(t *testing.T) { 646 assert.True(t, pipe.IsSkip(Pipe{}.Run(context.New(config.Project{ 647 Dockers: []config.Docker{ 648 { 649 Goos: "linux", 650 }, 651 }, 652 })))) 653 } 654 655 func TestDockerNotInPath(t *testing.T) { 656 var path = os.Getenv("PATH") 657 defer func() { 658 assert.NoError(t, os.Setenv("PATH", path)) 659 }() 660 assert.NoError(t, os.Setenv("PATH", "")) 661 var ctx = &context.Context{ 662 Version: "1.0.0", 663 Config: config.Project{ 664 Dockers: []config.Docker{ 665 { 666 Image: "a/b", 667 }, 668 }, 669 }, 670 } 671 assert.EqualError(t, Pipe{}.Run(ctx), ErrNoDocker.Error()) 672 } 673 674 func TestDefault(t *testing.T) { 675 var ctx = &context.Context{ 676 Config: config.Project{ 677 Builds: []config.Build{ 678 { 679 Binary: "foo", 680 }, 681 }, 682 Dockers: []config.Docker{ 683 {}, 684 }, 685 }, 686 } 687 assert.NoError(t, Pipe{}.Default(ctx)) 688 assert.Len(t, ctx.Config.Dockers, 1) 689 var docker = ctx.Config.Dockers[0] 690 assert.Equal(t, "linux", docker.Goos) 691 assert.Equal(t, "amd64", docker.Goarch) 692 assert.Equal(t, ctx.Config.Builds[0].Binary, docker.Binary) 693 assert.Equal(t, "Dockerfile", docker.Dockerfile) 694 } 695 696 func TestDefaultNoDockers(t *testing.T) { 697 var ctx = &context.Context{ 698 Config: config.Project{ 699 Dockers: []config.Docker{}, 700 }, 701 } 702 assert.NoError(t, Pipe{}.Default(ctx)) 703 assert.Empty(t, ctx.Config.Dockers) 704 } 705 706 func TestDefaultSet(t *testing.T) { 707 var ctx = &context.Context{ 708 Config: config.Project{ 709 Dockers: []config.Docker{ 710 { 711 Goos: "windows", 712 Goarch: "i386", 713 Binary: "bar", 714 Dockerfile: "Dockerfile.foo", 715 }, 716 }, 717 }, 718 } 719 assert.NoError(t, Pipe{}.Default(ctx)) 720 assert.Len(t, ctx.Config.Dockers, 1) 721 var docker = ctx.Config.Dockers[0] 722 assert.Equal(t, "windows", docker.Goos) 723 assert.Equal(t, "i386", docker.Goarch) 724 assert.Equal(t, "bar", docker.Binary) 725 assert.Equal(t, "Dockerfile.foo", docker.Dockerfile) 726 } 727 728 func TestDefaultWithImage(t *testing.T) { 729 var ctx = &context.Context{ 730 Config: config.Project{ 731 Dockers: []config.Docker{ 732 { 733 Goos: "windows", 734 Goarch: "i386", 735 Binary: "bar", 736 Dockerfile: "Dockerfile.foo", 737 Image: "my/image", 738 }, 739 }, 740 }, 741 } 742 assert.NoError(t, Pipe{}.Default(ctx)) 743 assert.Len(t, ctx.Config.Dockers, 1) 744 var docker = ctx.Config.Dockers[0] 745 assert.Equal(t, "windows", docker.Goos) 746 assert.Equal(t, "i386", docker.Goarch) 747 assert.Equal(t, "bar", docker.Binary) 748 assert.Equal(t, []string{"{{ .Version }}"}, docker.TagTemplates) 749 assert.Equal(t, "Dockerfile.foo", docker.Dockerfile) 750 } 751 752 func Test_processImageTemplates(t *testing.T) { 753 754 var table = map[string]struct { 755 image string 756 tagTemplates []string 757 imageTemplates []string 758 expectImages []string 759 }{ 760 "with image templates": { 761 imageTemplates: []string{"user/image:{{.Tag}}", "gcr.io/image:{{.Tag}}-{{.Env.FOO}}", "gcr.io/image:v{{.Major}}.{{.Minor}}"}, 762 expectImages: []string{"user/image:v1.0.0", "gcr.io/image:v1.0.0-123", "gcr.io/image:v1.0"}, 763 }, 764 "with image name and tag template": { 765 image: "my/image", 766 tagTemplates: []string{"{{.Tag}}-{{.Env.FOO}}", "v{{.Major}}.{{.Minor}}"}, 767 expectImages: []string{"my/image:v1.0.0-123", "my/image:v1.0"}, 768 }, 769 } 770 771 for name, tt := range table { 772 t.Run(name, func(t *testing.T) { 773 774 var ctx = &context.Context{ 775 Config: config.Project{ 776 Dockers: []config.Docker{ 777 { 778 Binary: "foo", 779 Image: tt.image, 780 Dockerfile: "Dockerfile.foo", 781 ImageTemplates: tt.imageTemplates, 782 SkipPush: true, 783 TagTemplates: tt.tagTemplates, 784 }, 785 }, 786 }, 787 } 788 ctx.SkipPublish = true 789 ctx.Env = map[string]string{ 790 "FOO": "123", 791 } 792 ctx.Version = "1.0.0" 793 ctx.Git = context.GitInfo{ 794 CurrentTag: "v1.0.0", 795 Commit: "a1b2c3d4", 796 } 797 798 assert.NoError(t, Pipe{}.Default(ctx)) 799 assert.Len(t, ctx.Config.Dockers, 1) 800 801 docker := ctx.Config.Dockers[0] 802 assert.Equal(t, "Dockerfile.foo", docker.Dockerfile) 803 804 images, err := processImageTemplates(ctx, docker, artifact.Artifact{}) 805 assert.NoError(t, err) 806 assert.Equal(t, tt.expectImages, images) 807 }) 808 } 809 810 } 811 812 func TestLinkFile(t *testing.T) { 813 const srcFile = "/tmp/test" 814 const dstFile = "/tmp/linked" 815 err := ioutil.WriteFile(srcFile, []byte("foo"), 0644) 816 if err != nil { 817 t.Log("Cannot setup test file") 818 t.Fail() 819 } 820 err = link(srcFile, dstFile) 821 if err != nil { 822 t.Log("Failed to link: ", err) 823 t.Fail() 824 } 825 if inode(srcFile) != inode(dstFile) { 826 t.Log("Inodes do not match, destination file is not a link") 827 t.Fail() 828 } 829 // cleanup 830 os.Remove(srcFile) 831 os.Remove(dstFile) 832 } 833 834 func TestLinkDirectory(t *testing.T) { 835 const srcDir = "/tmp/testdir" 836 const testFile = "test" 837 const dstDir = "/tmp/linkedDir" 838 839 os.Mkdir(srcDir, 0755) 840 err := ioutil.WriteFile(srcDir+"/"+testFile, []byte("foo"), 0644) 841 if err != nil { 842 t.Log("Cannot setup test file") 843 t.Fail() 844 } 845 err = link(srcDir, dstDir) 846 if err != nil { 847 t.Log("Failed to link: ", err) 848 t.Fail() 849 } 850 if inode(srcDir+"/"+testFile) != inode(dstDir+"/"+testFile) { 851 t.Log("Inodes do not match, destination file is not a link") 852 t.Fail() 853 } 854 855 // cleanup 856 os.RemoveAll(srcDir) 857 os.RemoveAll(dstDir) 858 } 859 860 func TestLinkTwoLevelDirectory(t *testing.T) { 861 const srcDir = "/tmp/testdir" 862 const srcLevel2 = srcDir + "/level2" 863 const testFile = "test" 864 const dstDir = "/tmp/linkedDir" 865 866 os.Mkdir(srcDir, 0755) 867 os.Mkdir(srcLevel2, 0755) 868 err := ioutil.WriteFile(srcDir+"/"+testFile, []byte("foo"), 0644) 869 if err != nil { 870 t.Log("Cannot setup test file") 871 t.Fail() 872 } 873 err = ioutil.WriteFile(srcLevel2+"/"+testFile, []byte("foo"), 0644) 874 if err != nil { 875 t.Log("Cannot setup test file") 876 t.Fail() 877 } 878 err = link(srcDir, dstDir) 879 if err != nil { 880 t.Log("Failed to link: ", err) 881 t.Fail() 882 } 883 if inode(srcDir+"/"+testFile) != inode(dstDir+"/"+testFile) { 884 t.Log("Inodes do not match") 885 t.Fail() 886 } 887 if inode(srcLevel2+"/"+testFile) != inode(dstDir+"/level2/"+testFile) { 888 t.Log("Inodes do not match") 889 t.Fail() 890 } 891 // cleanup 892 os.RemoveAll(srcDir) 893 os.RemoveAll(dstDir) 894 } 895 896 func inode(file string) uint64 { 897 fileInfo, err := os.Stat(file) 898 if err != nil { 899 return 0 900 } 901 stat := fileInfo.Sys().(*syscall.Stat_t) 902 return stat.Ino 903 }