github.com/daniellockard/packer@v0.7.6-0.20141210173435-5a9390934716/packer/template_test.go (about) 1 package packer 2 3 import ( 4 "io/ioutil" 5 "os" 6 "reflect" 7 "sort" 8 "testing" 9 "time" 10 ) 11 12 func testTemplateComponentFinder() *ComponentFinder { 13 builder := new(MockBuilder) 14 pp := new(TestPostProcessor) 15 provisioner := &MockProvisioner{} 16 17 builderMap := map[string]Builder{ 18 "test-builder": builder, 19 } 20 21 ppMap := map[string]PostProcessor{ 22 "test-pp": pp, 23 } 24 25 provisionerMap := map[string]Provisioner{ 26 "test-prov": provisioner, 27 } 28 29 builderFactory := func(n string) (Builder, error) { return builderMap[n], nil } 30 ppFactory := func(n string) (PostProcessor, error) { return ppMap[n], nil } 31 provFactory := func(n string) (Provisioner, error) { return provisionerMap[n], nil } 32 return &ComponentFinder{ 33 Builder: builderFactory, 34 PostProcessor: ppFactory, 35 Provisioner: provFactory, 36 } 37 } 38 39 func TestParseTemplateFile_basic(t *testing.T) { 40 data := ` 41 { 42 "builders": [{"type": "something"}] 43 } 44 ` 45 46 tf, err := ioutil.TempFile("", "packer") 47 if err != nil { 48 t.Fatalf("err: %s", err) 49 } 50 tf.Write([]byte(data)) 51 tf.Close() 52 53 result, err := ParseTemplateFile(tf.Name(), nil) 54 if err != nil { 55 t.Fatalf("err: %s", err) 56 } 57 58 if len(result.Builders) != 1 { 59 t.Fatalf("bad: %#v", result.Builders) 60 } 61 } 62 63 func TestParseTemplateFile_minPackerVersionBad(t *testing.T) { 64 data := ` 65 { 66 "min_packer_version": "27.0.0", 67 "builders": [{"type": "something"}] 68 } 69 ` 70 71 tf, err := ioutil.TempFile("", "packer") 72 if err != nil { 73 t.Fatalf("err: %s", err) 74 } 75 tf.Write([]byte(data)) 76 tf.Close() 77 78 _, err = ParseTemplateFile(tf.Name(), nil) 79 if err == nil { 80 t.Fatal("expects error") 81 } 82 } 83 84 func TestParseTemplateFile_minPackerVersionFormat(t *testing.T) { 85 data := ` 86 { 87 "min_packer_version": "NOPE NOPE NOPE", 88 "builders": [{"type": "something"}] 89 } 90 ` 91 92 tf, err := ioutil.TempFile("", "packer") 93 if err != nil { 94 t.Fatalf("err: %s", err) 95 } 96 tf.Write([]byte(data)) 97 tf.Close() 98 99 _, err = ParseTemplateFile(tf.Name(), nil) 100 if err == nil { 101 t.Fatal("expects error") 102 } 103 } 104 105 func TestParseTemplateFile_minPackerVersionGood(t *testing.T) { 106 data := ` 107 { 108 "min_packer_version": "0.1", 109 "builders": [{"type": "something"}] 110 } 111 ` 112 113 tf, err := ioutil.TempFile("", "packer") 114 if err != nil { 115 t.Fatalf("err: %s", err) 116 } 117 tf.Write([]byte(data)) 118 tf.Close() 119 120 _, err = ParseTemplateFile(tf.Name(), nil) 121 if err != nil { 122 t.Fatalf("err: %s", err) 123 } 124 } 125 126 func TestParseTemplateFile_stdin(t *testing.T) { 127 data := ` 128 { 129 "builders": [{"type": "something"}] 130 } 131 ` 132 133 tf, err := ioutil.TempFile("", "packer") 134 if err != nil { 135 t.Fatalf("err: %s", err) 136 } 137 defer tf.Close() 138 tf.Write([]byte(data)) 139 140 // Sync and seek to the beginning so that we can re-read the contents 141 tf.Sync() 142 tf.Seek(0, 0) 143 144 // Set stdin to something we control 145 oldStdin := os.Stdin 146 defer func() { os.Stdin = oldStdin }() 147 os.Stdin = tf 148 149 result, err := ParseTemplateFile("-", nil) 150 if err != nil { 151 t.Fatalf("err: %s", err) 152 } 153 154 if len(result.Builders) != 1 { 155 t.Fatalf("bad: %#v", result.Builders) 156 } 157 } 158 159 func TestParseTemplate_Basic(t *testing.T) { 160 data := ` 161 { 162 "builders": [{"type": "something"}] 163 } 164 ` 165 166 result, err := ParseTemplate([]byte(data), nil) 167 if err != nil { 168 t.Fatalf("err: %s", err) 169 } 170 if result == nil { 171 t.Fatal("should have result") 172 } 173 if len(result.Builders) != 1 { 174 t.Fatalf("bad: %#v", result.Builders) 175 } 176 } 177 178 func TestParseTemplate_Description(t *testing.T) { 179 data := ` 180 { 181 "description": "Foo", 182 "builders": [{"type": "something"}] 183 } 184 ` 185 186 result, err := ParseTemplate([]byte(data), nil) 187 if err != nil { 188 t.Fatalf("err: %s", err) 189 } 190 if result == nil { 191 t.Fatal("should have result") 192 } 193 if result.Description != "Foo" { 194 t.Fatalf("bad: %#v", result.Description) 195 } 196 } 197 198 func TestParseTemplate_Invalid(t *testing.T) { 199 // Note there is an extra comma below for a purposeful 200 // syntax error in the JSON. 201 data := ` 202 { 203 "builders": [], 204 } 205 ` 206 207 result, err := ParseTemplate([]byte(data), nil) 208 if err == nil { 209 t.Fatal("shold have error") 210 } 211 if result != nil { 212 t.Fatal("should not have result") 213 } 214 } 215 216 func TestParseTemplate_InvalidKeys(t *testing.T) { 217 // Note there is an extra comma below for a purposeful 218 // syntax error in the JSON. 219 data := ` 220 { 221 "builders": [{"type": "foo"}], 222 "what is this": "" 223 } 224 ` 225 226 result, err := ParseTemplate([]byte(data), nil) 227 if err == nil { 228 t.Fatal("should have error") 229 } 230 if result != nil { 231 t.Fatal("should not have result") 232 } 233 } 234 235 func TestParseTemplate_BuilderWithoutType(t *testing.T) { 236 data := ` 237 { 238 "builders": [{}] 239 } 240 ` 241 242 _, err := ParseTemplate([]byte(data), nil) 243 if err == nil { 244 t.Fatal("should have error") 245 } 246 } 247 248 func TestParseTemplate_BuilderWithNonStringType(t *testing.T) { 249 data := ` 250 { 251 "builders": [{ 252 "type": 42 253 }] 254 } 255 ` 256 257 _, err := ParseTemplate([]byte(data), nil) 258 if err == nil { 259 t.Fatal("should have error") 260 } 261 } 262 263 func TestParseTemplate_BuilderWithoutName(t *testing.T) { 264 data := ` 265 { 266 "builders": [ 267 { 268 "type": "amazon-ebs" 269 } 270 ] 271 } 272 ` 273 274 result, err := ParseTemplate([]byte(data), nil) 275 if err != nil { 276 t.Fatalf("err: %s", err) 277 } 278 if result == nil { 279 t.Fatal("should have result") 280 } 281 if len(result.Builders) != 1 { 282 t.Fatalf("bad: %#v", result.Builders) 283 } 284 285 builder, ok := result.Builders["amazon-ebs"] 286 if !ok { 287 t.Fatal("should be ok") 288 } 289 if builder.Type != "amazon-ebs" { 290 t.Fatalf("bad: %#v", builder.Type) 291 } 292 } 293 294 func TestParseTemplate_BuilderWithName(t *testing.T) { 295 data := ` 296 { 297 "builders": [ 298 { 299 "name": "bob", 300 "type": "amazon-ebs" 301 } 302 ] 303 } 304 ` 305 306 result, err := ParseTemplate([]byte(data), nil) 307 if err != nil { 308 t.Fatalf("err: %s", err) 309 } 310 if result == nil { 311 t.Fatal("should have result") 312 } 313 if len(result.Builders) != 1 { 314 t.Fatalf("bad: %#v", result.Builders) 315 } 316 317 builder, ok := result.Builders["bob"] 318 if !ok { 319 t.Fatal("should be ok") 320 } 321 if builder.Type != "amazon-ebs" { 322 t.Fatalf("bad: %#v", builder.Type) 323 } 324 325 RawConfig := builder.RawConfig 326 if RawConfig == nil { 327 t.Fatal("missing builder raw config") 328 } 329 330 expected := map[string]interface{}{ 331 "type": "amazon-ebs", 332 } 333 334 if !reflect.DeepEqual(RawConfig, expected) { 335 t.Fatalf("bad raw: %#v", RawConfig) 336 } 337 } 338 339 func TestParseTemplate_BuilderWithConflictingName(t *testing.T) { 340 data := ` 341 { 342 "builders": [ 343 { 344 "name": "bob", 345 "type": "amazon-ebs" 346 }, 347 { 348 "name": "bob", 349 "type": "foo", 350 } 351 ] 352 } 353 ` 354 355 _, err := ParseTemplate([]byte(data), nil) 356 if err == nil { 357 t.Fatal("should have error") 358 } 359 } 360 361 func TestParseTemplate_Hooks(t *testing.T) { 362 data := ` 363 { 364 365 "builders": [{"type": "foo"}], 366 367 "hooks": { 368 "event": ["foo", "bar"] 369 } 370 } 371 ` 372 373 result, err := ParseTemplate([]byte(data), nil) 374 if err != nil { 375 t.Fatalf("err: %s", err) 376 } 377 if result == nil { 378 t.Fatal("should have result") 379 } 380 if len(result.Hooks) != 1 { 381 t.Fatalf("bad: %#v", result.Hooks) 382 } 383 384 hooks, ok := result.Hooks["event"] 385 if !ok { 386 t.Fatal("should be okay") 387 } 388 if !reflect.DeepEqual(hooks, []string{"foo", "bar"}) { 389 t.Fatalf("bad: %#v", hooks) 390 } 391 } 392 393 func TestParseTemplate_PostProcessors(t *testing.T) { 394 data := ` 395 { 396 "builders": [{"type": "foo"}], 397 398 "post-processors": [ 399 "simple", 400 401 { "type": "detailed" }, 402 403 [ "foo", { "type": "bar" } ] 404 ] 405 } 406 ` 407 408 tpl, err := ParseTemplate([]byte(data), nil) 409 if err != nil { 410 t.Fatalf("error parsing: %s", err) 411 } 412 413 if len(tpl.PostProcessors) != 3 { 414 t.Fatalf("bad number of post-processors: %d", len(tpl.PostProcessors)) 415 } 416 417 pp := tpl.PostProcessors[0] 418 if len(pp) != 1 { 419 t.Fatalf("wrong number of configs in simple: %d", len(pp)) 420 } 421 422 if pp[0].Type != "simple" { 423 t.Fatalf("wrong type for simple: %s", pp[0].Type) 424 } 425 426 pp = tpl.PostProcessors[1] 427 if len(pp) != 1 { 428 t.Fatalf("wrong number of configs in detailed: %d", len(pp)) 429 } 430 431 if pp[0].Type != "detailed" { 432 t.Fatalf("wrong type for detailed: %s", pp[0].Type) 433 } 434 435 pp = tpl.PostProcessors[2] 436 if len(pp) != 2 { 437 t.Fatalf("wrong number of configs for sequence: %d", len(pp)) 438 } 439 440 if pp[0].Type != "foo" { 441 t.Fatalf("wrong type for sequence 0: %s", pp[0].Type) 442 } 443 444 if pp[1].Type != "bar" { 445 t.Fatalf("wrong type for sequence 1: %s", pp[1].Type) 446 } 447 } 448 449 func TestParseTemplate_ProvisionerWithoutType(t *testing.T) { 450 data := ` 451 { 452 "builders": [{"type": "foo"}], 453 454 "provisioners": [{}] 455 } 456 ` 457 458 _, err := ParseTemplate([]byte(data), nil) 459 if err == nil { 460 t.Fatal("err should not be nil") 461 } 462 } 463 464 func TestParseTemplate_ProvisionerWithNonStringType(t *testing.T) { 465 data := ` 466 { 467 "builders": [{"type": "foo"}], 468 469 "provisioners": [{ 470 "type": 42 471 }] 472 } 473 ` 474 475 _, err := ParseTemplate([]byte(data), nil) 476 if err == nil { 477 t.Fatal("should have error") 478 } 479 } 480 481 func TestParseTemplate_Provisioners(t *testing.T) { 482 data := ` 483 { 484 "builders": [{"type": "foo"}], 485 486 "provisioners": [ 487 { 488 "type": "shell" 489 } 490 ] 491 } 492 ` 493 494 result, err := ParseTemplate([]byte(data), nil) 495 if err != nil { 496 t.Fatal("err: %s", err) 497 } 498 if result == nil { 499 t.Fatal("should have result") 500 } 501 if len(result.Provisioners) != 1 { 502 t.Fatalf("bad: %#v", result.Provisioners) 503 } 504 if result.Provisioners[0].Type != "shell" { 505 t.Fatalf("bad: %#v", result.Provisioners[0].Type) 506 } 507 if result.Provisioners[0].RawConfig == nil { 508 t.Fatal("should have raw config") 509 } 510 } 511 512 func TestParseTemplate_ProvisionerPauseBefore(t *testing.T) { 513 data := ` 514 { 515 "builders": [{"type": "foo"}], 516 517 "provisioners": [ 518 { 519 "type": "shell", 520 "pause_before": "10s" 521 } 522 ] 523 } 524 ` 525 526 result, err := ParseTemplate([]byte(data), nil) 527 if err != nil { 528 t.Fatal("err: %s", err) 529 } 530 if result == nil { 531 t.Fatal("should have result") 532 } 533 if len(result.Provisioners) != 1 { 534 t.Fatalf("bad: %#v", result.Provisioners) 535 } 536 if result.Provisioners[0].Type != "shell" { 537 t.Fatalf("bad: %#v", result.Provisioners[0].Type) 538 } 539 if result.Provisioners[0].pauseBefore != 10*time.Second { 540 t.Fatalf("bad: %s", result.Provisioners[0].pauseBefore) 541 } 542 } 543 544 func TestParseTemplateFile_push(t *testing.T) { 545 data := ` 546 { 547 "builders": [{"type": "something"}], 548 549 "push": { 550 "name": "hello", 551 "include": ["one"], 552 "exclude": ["two"] 553 } 554 } 555 ` 556 557 tf, err := ioutil.TempFile("", "packer") 558 if err != nil { 559 t.Fatalf("err: %s", err) 560 } 561 tf.Write([]byte(data)) 562 tf.Close() 563 564 result, err := ParseTemplateFile(tf.Name(), nil) 565 if err != nil { 566 t.Fatalf("err: %s", err) 567 } 568 569 expected := &PushConfig{ 570 Name: "hello", 571 Include: []string{"one"}, 572 Exclude: []string{"two"}, 573 } 574 if !reflect.DeepEqual(result.Push, expected) { 575 t.Fatalf("bad: %#v", result.Push) 576 } 577 } 578 579 func TestParseTemplate_Variables(t *testing.T) { 580 data := ` 581 { 582 "variables": { 583 "foo": "bar", 584 "bar": null, 585 "baz": 27 586 }, 587 588 "builders": [{"type": "something"}] 589 } 590 ` 591 592 result, err := ParseTemplate([]byte(data), map[string]string{ 593 "bar": "bar", 594 }) 595 if err != nil { 596 t.Fatalf("err: %s", err) 597 } 598 599 if result.Variables == nil || len(result.Variables) != 3 { 600 t.Fatalf("bad vars: %#v", result.Variables) 601 } 602 603 if result.Variables["foo"].Default != "bar" { 604 t.Fatal("foo default is not right") 605 } 606 if result.Variables["foo"].Required { 607 t.Fatal("foo should not be required") 608 } 609 if result.Variables["foo"].HasValue { 610 t.Fatal("foo should not have value") 611 } 612 613 if result.Variables["bar"].Default != "" { 614 t.Fatal("default should be empty") 615 } 616 if !result.Variables["bar"].Required { 617 t.Fatal("bar should be required") 618 } 619 if !result.Variables["bar"].HasValue { 620 t.Fatal("bar should have value") 621 } 622 if result.Variables["bar"].Value != "bar" { 623 t.Fatal("bad value") 624 } 625 626 if result.Variables["baz"].Default != "27" { 627 t.Fatal("default should be empty") 628 } 629 630 if result.Variables["baz"].Required { 631 t.Fatal("baz should not be required") 632 } 633 } 634 635 func TestParseTemplate_variablesSet(t *testing.T) { 636 data := ` 637 { 638 "variables": { 639 "foo": "bar" 640 }, 641 642 "builders": [ 643 { 644 "name": "test1", 645 "type": "test-builder" 646 } 647 ] 648 } 649 ` 650 651 template, err := ParseTemplate([]byte(data), map[string]string{ 652 "foo": "value", 653 }) 654 if err != nil { 655 t.Fatalf("err: %s", err) 656 } 657 658 if len(template.Variables) != 1 { 659 t.Fatalf("bad vars: %#v", template.Variables) 660 } 661 if template.Variables["foo"].Value != "value" { 662 t.Fatalf("bad: %#v", template.Variables["foo"]) 663 } 664 } 665 666 func TestParseTemplate_variablesSetUnknown(t *testing.T) { 667 data := ` 668 { 669 "variables": { 670 "foo": "bar" 671 }, 672 673 "builders": [ 674 { 675 "name": "test1", 676 "type": "test-builder" 677 } 678 ] 679 } 680 ` 681 682 _, err := ParseTemplate([]byte(data), map[string]string{ 683 "what": "value", 684 }) 685 if err == nil { 686 t.Fatal("should error") 687 } 688 } 689 690 func TestParseTemplate_variablesBadDefault(t *testing.T) { 691 data := ` 692 { 693 "variables": { 694 "foo": 7, 695 }, 696 697 "builders": [{"type": "something"}] 698 } 699 ` 700 701 _, err := ParseTemplate([]byte(data), nil) 702 if err == nil { 703 t.Fatal("should have error") 704 } 705 } 706 707 func TestTemplate_BuildNames(t *testing.T) { 708 data := ` 709 { 710 "builders": [ 711 { 712 "name": "bob", 713 "type": "amazon-ebs" 714 }, 715 { 716 "name": "chris", 717 "type": "another" 718 } 719 ] 720 } 721 ` 722 723 result, err := ParseTemplate([]byte(data), nil) 724 if err != nil { 725 t.Fatalf("err: %s", err) 726 } 727 728 buildNames := result.BuildNames() 729 sort.Strings(buildNames) 730 if !reflect.DeepEqual(buildNames, []string{"bob", "chris"}) { 731 t.Fatalf("bad: %#v", buildNames) 732 } 733 } 734 735 func TestTemplate_BuildUnknown(t *testing.T) { 736 data := ` 737 { 738 "builders": [ 739 { 740 "name": "test1", 741 "type": "test-builder" 742 } 743 ] 744 } 745 ` 746 747 template, err := ParseTemplate([]byte(data), nil) 748 if err != nil { 749 t.Fatalf("bad: %s", err) 750 } 751 752 build, err := template.Build("nope", nil) 753 if build != nil { 754 t.Fatalf("build should be nil: %#v", build) 755 } 756 if err == nil { 757 t.Fatal("should have error") 758 } 759 } 760 761 func TestTemplate_BuildUnknownBuilder(t *testing.T) { 762 data := ` 763 { 764 "builders": [ 765 { 766 "name": "test1", 767 "type": "test-builder" 768 } 769 ] 770 } 771 ` 772 773 template, err := ParseTemplate([]byte(data), nil) 774 if err != nil { 775 t.Fatalf("err: %s", err) 776 } 777 778 builderFactory := func(string) (Builder, error) { return nil, nil } 779 components := &ComponentFinder{Builder: builderFactory} 780 build, err := template.Build("test1", components) 781 if err == nil { 782 t.Fatal("should have error") 783 } 784 if build != nil { 785 t.Fatalf("bad: %#v", build) 786 } 787 } 788 789 func TestTemplateBuild_envInVars(t *testing.T) { 790 data := ` 791 { 792 "variables": { 793 "foo": "{{env \"foo\"}}" 794 }, 795 796 "builders": [ 797 { 798 "name": "test1", 799 "type": "test-builder" 800 } 801 ] 802 } 803 ` 804 805 defer os.Setenv("foo", os.Getenv("foo")) 806 if err := os.Setenv("foo", "bar"); err != nil { 807 t.Fatalf("err: %s", err) 808 } 809 810 template, err := ParseTemplate([]byte(data), map[string]string{}) 811 if err != nil { 812 t.Fatalf("err: %s", err) 813 } 814 815 b, err := template.Build("test1", testComponentFinder()) 816 if err != nil { 817 t.Fatalf("err: %s", err) 818 } 819 820 coreBuild, ok := b.(*coreBuild) 821 if !ok { 822 t.Fatal("should be ok") 823 } 824 825 if coreBuild.variables["foo"] != "bar" { 826 t.Fatalf("bad: %#v", coreBuild.variables) 827 } 828 } 829 830 func TestTemplateBuild_names(t *testing.T) { 831 data := ` 832 { 833 "variables": { 834 "foo": null 835 }, 836 837 "builders": [ 838 { 839 "name": "test1", 840 "type": "test-builder" 841 }, 842 { 843 "name": "test2-{{user \"foo\"}}", 844 "type": "test-builder" 845 } 846 ] 847 } 848 ` 849 850 template, err := ParseTemplate([]byte(data), map[string]string{"foo": "bar"}) 851 if err != nil { 852 t.Fatalf("err: %s", err) 853 } 854 855 b, err := template.Build("test1", testComponentFinder()) 856 if err != nil { 857 t.Fatalf("err: %s", err) 858 } 859 if b.Name() != "test1" { 860 t.Fatalf("bad: %#v", b.Name()) 861 } 862 863 b, err = template.Build("test2-{{user \"foo\"}}", testComponentFinder()) 864 if err != nil { 865 t.Fatalf("err: %s", err) 866 } 867 if b.Name() != "test2-bar" { 868 t.Fatalf("bad: %#v", b.Name()) 869 } 870 } 871 872 func TestTemplate_Build_NilBuilderFunc(t *testing.T) { 873 data := ` 874 { 875 "builders": [ 876 { 877 "name": "test1", 878 "type": "test-builder" 879 } 880 ], 881 882 "provisioners": [ 883 { 884 "type": "test-prov" 885 } 886 ] 887 } 888 ` 889 890 template, err := ParseTemplate([]byte(data), nil) 891 if err != nil { 892 t.Fatalf("err: %s", err) 893 } 894 895 defer func() { 896 p := recover() 897 if p == nil { 898 t.Fatal("should panic") 899 } 900 901 if p.(string) != "no builder function" { 902 t.Fatalf("bad panic: %s", p.(string)) 903 } 904 }() 905 906 template.Build("test1", &ComponentFinder{}) 907 } 908 909 func TestTemplate_Build_NilProvisionerFunc(t *testing.T) { 910 data := ` 911 { 912 "builders": [ 913 { 914 "name": "test1", 915 "type": "test-builder" 916 } 917 ], 918 919 "provisioners": [ 920 { 921 "type": "test-prov" 922 } 923 ] 924 } 925 ` 926 927 template, err := ParseTemplate([]byte(data), nil) 928 if err != nil { 929 t.Fatalf("err: %s", err) 930 } 931 932 defer func() { 933 p := recover() 934 if p == nil { 935 t.Fatal("should panic") 936 } 937 938 if p.(string) != "no provisioner function" { 939 t.Fatalf("bad panic: %s", p.(string)) 940 } 941 }() 942 943 template.Build("test1", &ComponentFinder{ 944 Builder: func(string) (Builder, error) { return nil, nil }, 945 }) 946 } 947 948 func TestTemplate_Build_NilProvisionerFunc_WithNoProvisioners(t *testing.T) { 949 data := ` 950 { 951 "builders": [ 952 { 953 "name": "test1", 954 "type": "test-builder" 955 } 956 ], 957 958 "provisioners": [] 959 } 960 ` 961 962 template, err := ParseTemplate([]byte(data), nil) 963 if err != nil { 964 t.Fatalf("err: %s", err) 965 } 966 967 template.Build("test1", &ComponentFinder{ 968 Builder: func(string) (Builder, error) { return nil, nil }, 969 }) 970 } 971 972 func TestTemplate_Build(t *testing.T) { 973 data := ` 974 { 975 "builders": [ 976 { 977 "name": "test1", 978 "type": "test-builder" 979 } 980 ], 981 982 "provisioners": [ 983 { 984 "type": "test-prov" 985 } 986 ], 987 988 "post-processors": [ 989 "simple", 990 [ 991 "simple", 992 { "type": "simple", "keep_input_artifact": true } 993 ] 994 ] 995 } 996 ` 997 998 expectedConfig := map[string]interface{}{ 999 "type": "test-builder", 1000 } 1001 1002 template, err := ParseTemplate([]byte(data), nil) 1003 if err != nil { 1004 t.Fatalf("err: %s", err) 1005 } 1006 1007 builder := new(MockBuilder) 1008 builderMap := map[string]Builder{ 1009 "test-builder": builder, 1010 } 1011 1012 provisioner := &MockProvisioner{} 1013 provisionerMap := map[string]Provisioner{ 1014 "test-prov": provisioner, 1015 } 1016 1017 pp := new(TestPostProcessor) 1018 ppMap := map[string]PostProcessor{ 1019 "simple": pp, 1020 } 1021 1022 builderFactory := func(n string) (Builder, error) { return builderMap[n], nil } 1023 ppFactory := func(n string) (PostProcessor, error) { return ppMap[n], nil } 1024 provFactory := func(n string) (Provisioner, error) { return provisionerMap[n], nil } 1025 components := &ComponentFinder{ 1026 Builder: builderFactory, 1027 PostProcessor: ppFactory, 1028 Provisioner: provFactory, 1029 } 1030 1031 // Get the build, verifying we can get it without issue, but also 1032 // that the proper builder was looked up and used for the build. 1033 build, err := template.Build("test1", components) 1034 if err != nil { 1035 t.Fatalf("err: %s", err) 1036 } 1037 1038 coreBuild, ok := build.(*coreBuild) 1039 if !ok { 1040 t.Fatal("should be ok") 1041 } 1042 if coreBuild.builder != builder { 1043 t.Fatalf("bad: %#v", coreBuild.builder) 1044 } 1045 if !reflect.DeepEqual(coreBuild.builderConfig, expectedConfig) { 1046 t.Fatalf("bad: %#v", coreBuild.builderConfig) 1047 } 1048 if len(coreBuild.provisioners) != 1 { 1049 t.Fatalf("bad: %#v", coreBuild.provisioners) 1050 } 1051 if len(coreBuild.postProcessors) != 2 { 1052 t.Fatalf("bad: %#v", coreBuild.postProcessors) 1053 } 1054 1055 if len(coreBuild.postProcessors[0]) != 1 { 1056 t.Fatalf("bad: %#v", coreBuild.postProcessors[0]) 1057 } 1058 if len(coreBuild.postProcessors[1]) != 2 { 1059 t.Fatalf("bad: %#v", coreBuild.postProcessors[1]) 1060 } 1061 1062 if coreBuild.postProcessors[1][0].keepInputArtifact { 1063 t.Fatal("postProcessors[1][0] should not keep input artifact") 1064 } 1065 if !coreBuild.postProcessors[1][1].keepInputArtifact { 1066 t.Fatal("postProcessors[1][1] should keep input artifact") 1067 } 1068 1069 config := coreBuild.postProcessors[1][1].config 1070 if _, ok := config["keep_input_artifact"]; ok { 1071 t.Fatal("should not have keep_input_artifact") 1072 } 1073 } 1074 1075 func TestTemplateBuild_exceptOnlyPP(t *testing.T) { 1076 data := ` 1077 { 1078 "builders": [ 1079 { 1080 "name": "test1", 1081 "type": "test-builder" 1082 }, 1083 { 1084 "name": "test2", 1085 "type": "test-builder" 1086 } 1087 ], 1088 1089 "post-processors": [ 1090 { 1091 "type": "test-pp", 1092 "except": ["test1"], 1093 "only": ["test1"] 1094 } 1095 ] 1096 } 1097 ` 1098 1099 _, err := ParseTemplate([]byte(data), nil) 1100 if err == nil { 1101 t.Fatal("should have error") 1102 } 1103 } 1104 1105 func TestTemplateBuild_exceptOnlyProv(t *testing.T) { 1106 data := ` 1107 { 1108 "builders": [ 1109 { 1110 "name": "test1", 1111 "type": "test-builder" 1112 }, 1113 { 1114 "name": "test2", 1115 "type": "test-builder" 1116 } 1117 ], 1118 1119 "provisioners": [ 1120 { 1121 "type": "test-prov", 1122 "except": ["test1"], 1123 "only": ["test1"] 1124 } 1125 ] 1126 } 1127 ` 1128 1129 _, err := ParseTemplate([]byte(data), nil) 1130 if err == nil { 1131 t.Fatal("should have error") 1132 } 1133 } 1134 1135 func TestTemplateBuild_exceptPPInvalid(t *testing.T) { 1136 data := ` 1137 { 1138 "builders": [ 1139 { 1140 "name": "test1", 1141 "type": "test-builder" 1142 }, 1143 { 1144 "name": "test2", 1145 "type": "test-builder" 1146 } 1147 ], 1148 1149 "post-processors": [ 1150 { 1151 "type": "test-pp", 1152 "except": ["test5"] 1153 } 1154 ] 1155 } 1156 ` 1157 1158 _, err := ParseTemplate([]byte(data), nil) 1159 if err == nil { 1160 t.Fatal("should have error") 1161 } 1162 } 1163 1164 func TestTemplateBuild_exceptPP(t *testing.T) { 1165 data := ` 1166 { 1167 "builders": [ 1168 { 1169 "name": "test1", 1170 "type": "test-builder" 1171 }, 1172 { 1173 "name": "test2", 1174 "type": "test-builder" 1175 } 1176 ], 1177 1178 "post-processors": [ 1179 { 1180 "type": "test-pp", 1181 "except": ["test1"] 1182 } 1183 ] 1184 } 1185 ` 1186 1187 template, err := ParseTemplate([]byte(data), nil) 1188 if err != nil { 1189 t.Fatalf("err: %s", err) 1190 } 1191 1192 // Verify test1 has no post-processors 1193 build, err := template.Build("test1", testTemplateComponentFinder()) 1194 if err != nil { 1195 t.Fatalf("err: %s", err) 1196 } 1197 1198 cbuild := build.(*coreBuild) 1199 if len(cbuild.postProcessors) > 0 { 1200 t.Fatal("should have no postProcessors") 1201 } 1202 1203 // Verify test2 has one post-processors 1204 build, err = template.Build("test2", testTemplateComponentFinder()) 1205 if err != nil { 1206 t.Fatalf("err: %s", err) 1207 } 1208 1209 cbuild = build.(*coreBuild) 1210 if len(cbuild.postProcessors) != 1 { 1211 t.Fatalf("invalid: %d", len(cbuild.postProcessors)) 1212 } 1213 } 1214 1215 func TestTemplateBuild_exceptPPConfigTemplateName(t *testing.T) { 1216 data := ` 1217 { 1218 "variables": { 1219 "foo": null 1220 }, 1221 1222 "builders": [ 1223 { 1224 "name": "test1-{{user \"foo\"}}", 1225 "type": "test-builder" 1226 }, 1227 { 1228 "name": "test2", 1229 "type": "test-builder" 1230 } 1231 ], 1232 1233 "post-processors": [ 1234 { 1235 "type": "test-pp", 1236 "except": ["test1-{{user \"foo\"}}"] 1237 } 1238 ] 1239 } 1240 ` 1241 1242 template, err := ParseTemplate([]byte(data), map[string]string{"foo": "bar"}) 1243 if err != nil { 1244 t.Fatalf("err: %s", err) 1245 } 1246 1247 // Verify test1 has no post-processors 1248 build, err := template.Build("test1-{{user \"foo\"}}", testTemplateComponentFinder()) 1249 if err != nil { 1250 t.Fatalf("err: %s", err) 1251 } 1252 1253 cbuild := build.(*coreBuild) 1254 if len(cbuild.postProcessors) > 0 { 1255 t.Fatal("should have no postProcessors") 1256 } 1257 1258 // Verify test2 has one post-processors 1259 build, err = template.Build("test2", testTemplateComponentFinder()) 1260 if err != nil { 1261 t.Fatalf("err: %s", err) 1262 } 1263 1264 cbuild = build.(*coreBuild) 1265 if len(cbuild.postProcessors) != 1 { 1266 t.Fatalf("invalid: %d", len(cbuild.postProcessors)) 1267 } 1268 } 1269 1270 func TestTemplateBuild_exceptProvInvalid(t *testing.T) { 1271 data := ` 1272 { 1273 "builders": [ 1274 { 1275 "name": "test1", 1276 "type": "test-builder" 1277 }, 1278 { 1279 "name": "test2", 1280 "type": "test-builder" 1281 } 1282 ], 1283 1284 "provisioners": [ 1285 { 1286 "type": "test-prov", 1287 "except": ["test5"] 1288 } 1289 ] 1290 } 1291 ` 1292 1293 _, err := ParseTemplate([]byte(data), nil) 1294 if err == nil { 1295 t.Fatal("should have error") 1296 } 1297 } 1298 1299 func TestTemplateBuild_exceptProv(t *testing.T) { 1300 data := ` 1301 { 1302 "builders": [ 1303 { 1304 "name": "test1", 1305 "type": "test-builder" 1306 }, 1307 { 1308 "name": "test2", 1309 "type": "test-builder" 1310 } 1311 ], 1312 1313 "provisioners": [ 1314 { 1315 "type": "test-prov", 1316 "except": ["test1"] 1317 } 1318 ] 1319 } 1320 ` 1321 1322 template, err := ParseTemplate([]byte(data), nil) 1323 if err != nil { 1324 t.Fatalf("err: %s", err) 1325 } 1326 1327 // Verify test1 has no provisioners 1328 build, err := template.Build("test1", testTemplateComponentFinder()) 1329 if err != nil { 1330 t.Fatalf("err: %s", err) 1331 } 1332 1333 cbuild := build.(*coreBuild) 1334 if len(cbuild.provisioners) > 0 { 1335 t.Fatal("should have no provisioners") 1336 } 1337 1338 // Verify test2 has one provisioners 1339 build, err = template.Build("test2", testTemplateComponentFinder()) 1340 if err != nil { 1341 t.Fatalf("err: %s", err) 1342 } 1343 1344 cbuild = build.(*coreBuild) 1345 if len(cbuild.provisioners) != 1 { 1346 t.Fatalf("invalid: %d", len(cbuild.provisioners)) 1347 } 1348 } 1349 1350 func TestTemplateBuild_exceptProvConfigTemplateName(t *testing.T) { 1351 data := ` 1352 { 1353 "variables": { 1354 "foo": null 1355 }, 1356 1357 "builders": [ 1358 { 1359 "name": "test1-{{user \"foo\"}}", 1360 "type": "test-builder" 1361 }, 1362 { 1363 "name": "test2", 1364 "type": "test-builder" 1365 } 1366 ], 1367 1368 "provisioners": [ 1369 { 1370 "type": "test-prov", 1371 "except": ["test1-{{user \"foo\"}}"] 1372 } 1373 ] 1374 } 1375 ` 1376 1377 template, err := ParseTemplate([]byte(data), map[string]string{"foo": "bar"}) 1378 if err != nil { 1379 t.Fatalf("err: %s", err) 1380 } 1381 1382 // Verify test1 has no provisioners 1383 build, err := template.Build("test1-{{user \"foo\"}}", testTemplateComponentFinder()) 1384 if err != nil { 1385 t.Fatalf("err: %s", err) 1386 } 1387 1388 cbuild := build.(*coreBuild) 1389 if len(cbuild.provisioners) > 0 { 1390 t.Fatal("should have no provisioners") 1391 } 1392 1393 // Verify test2 has one provisioners 1394 build, err = template.Build("test2", testTemplateComponentFinder()) 1395 if err != nil { 1396 t.Fatalf("err: %s", err) 1397 } 1398 1399 cbuild = build.(*coreBuild) 1400 if len(cbuild.provisioners) != 1 { 1401 t.Fatalf("invalid: %d", len(cbuild.provisioners)) 1402 } 1403 } 1404 1405 func TestTemplateBuild_onlyPPInvalid(t *testing.T) { 1406 data := ` 1407 { 1408 "builders": [ 1409 { 1410 "name": "test1", 1411 "type": "test-builder" 1412 }, 1413 { 1414 "name": "test2", 1415 "type": "test-builder" 1416 } 1417 ], 1418 1419 "post-processors": [ 1420 { 1421 "type": "test-pp", 1422 "only": ["test5"] 1423 } 1424 ] 1425 } 1426 ` 1427 1428 _, err := ParseTemplate([]byte(data), nil) 1429 if err == nil { 1430 t.Fatal("should have error") 1431 } 1432 } 1433 1434 func TestTemplateBuild_onlyPP(t *testing.T) { 1435 data := ` 1436 { 1437 "builders": [ 1438 { 1439 "name": "test1", 1440 "type": "test-builder" 1441 }, 1442 { 1443 "name": "test2", 1444 "type": "test-builder" 1445 } 1446 ], 1447 1448 "post-processors": [ 1449 { 1450 "type": "test-pp", 1451 "only": ["test2"] 1452 } 1453 ] 1454 } 1455 ` 1456 1457 template, err := ParseTemplate([]byte(data), nil) 1458 if err != nil { 1459 t.Fatalf("err: %s", err) 1460 } 1461 1462 // Verify test1 has no post-processors 1463 build, err := template.Build("test1", testTemplateComponentFinder()) 1464 if err != nil { 1465 t.Fatalf("err: %s", err) 1466 } 1467 1468 cbuild := build.(*coreBuild) 1469 if len(cbuild.postProcessors) > 0 { 1470 t.Fatal("should have no postProcessors") 1471 } 1472 1473 // Verify test2 has one post-processors 1474 build, err = template.Build("test2", testTemplateComponentFinder()) 1475 if err != nil { 1476 t.Fatalf("err: %s", err) 1477 } 1478 1479 cbuild = build.(*coreBuild) 1480 if len(cbuild.postProcessors) != 1 { 1481 t.Fatalf("invalid: %d", len(cbuild.postProcessors)) 1482 } 1483 } 1484 1485 func TestTemplateBuild_onlyPPConfigTemplateName(t *testing.T) { 1486 data := ` 1487 { 1488 "variables": { 1489 "foo": null 1490 }, 1491 1492 "builders": [ 1493 { 1494 "name": "test1", 1495 "type": "test-builder" 1496 }, 1497 { 1498 "name": "test2-{{user \"foo\"}}", 1499 "type": "test-builder" 1500 } 1501 ], 1502 1503 "post-processors": [ 1504 { 1505 "type": "test-pp", 1506 "only": ["test2-{{user \"foo\"}}"] 1507 } 1508 ] 1509 } 1510 ` 1511 1512 template, err := ParseTemplate([]byte(data), map[string]string{"foo": "bar"}) 1513 if err != nil { 1514 t.Fatalf("err: %s", err) 1515 } 1516 1517 // Verify test1 has no post-processors 1518 build, err := template.Build("test1", testTemplateComponentFinder()) 1519 if err != nil { 1520 t.Fatalf("err: %s", err) 1521 } 1522 1523 cbuild := build.(*coreBuild) 1524 if len(cbuild.postProcessors) > 0 { 1525 t.Fatal("should have no postProcessors") 1526 } 1527 1528 // Verify test2 has one post-processors 1529 build, err = template.Build("test2-{{user \"foo\"}}", testTemplateComponentFinder()) 1530 if err != nil { 1531 t.Fatalf("err: %s", err) 1532 } 1533 1534 cbuild = build.(*coreBuild) 1535 if len(cbuild.postProcessors) != 1 { 1536 t.Fatalf("invalid: %d", len(cbuild.postProcessors)) 1537 } 1538 } 1539 1540 func TestTemplateBuild_onlyProvInvalid(t *testing.T) { 1541 data := ` 1542 { 1543 "builders": [ 1544 { 1545 "name": "test1", 1546 "type": "test-builder" 1547 }, 1548 { 1549 "name": "test2", 1550 "type": "test-builder" 1551 } 1552 ], 1553 1554 "provisioners": [ 1555 { 1556 "type": "test-prov", 1557 "only": ["test5"] 1558 } 1559 ] 1560 } 1561 ` 1562 1563 _, err := ParseTemplate([]byte(data), nil) 1564 if err == nil { 1565 t.Fatal("should have error") 1566 } 1567 } 1568 1569 func TestTemplateBuild_onlyProv(t *testing.T) { 1570 data := ` 1571 { 1572 "builders": [ 1573 { 1574 "name": "test1", 1575 "type": "test-builder" 1576 }, 1577 { 1578 "name": "test2", 1579 "type": "test-builder" 1580 } 1581 ], 1582 1583 "provisioners": [ 1584 { 1585 "type": "test-prov", 1586 "only": ["test2"] 1587 } 1588 ] 1589 } 1590 ` 1591 1592 template, err := ParseTemplate([]byte(data), nil) 1593 if err != nil { 1594 t.Fatalf("err: %s", err) 1595 } 1596 1597 // Verify test1 has no provisioners 1598 build, err := template.Build("test1", testTemplateComponentFinder()) 1599 if err != nil { 1600 t.Fatalf("err: %s", err) 1601 } 1602 1603 cbuild := build.(*coreBuild) 1604 if len(cbuild.provisioners) > 0 { 1605 t.Fatal("should have no provisioners") 1606 } 1607 1608 // Verify test2 has one provisioners 1609 build, err = template.Build("test2", testTemplateComponentFinder()) 1610 if err != nil { 1611 t.Fatalf("err: %s", err) 1612 } 1613 1614 cbuild = build.(*coreBuild) 1615 if len(cbuild.provisioners) != 1 { 1616 t.Fatalf("invalid: %d", len(cbuild.provisioners)) 1617 } 1618 } 1619 1620 func TestTemplateBuild_onlyProvConfigTemplateName(t *testing.T) { 1621 data := ` 1622 { 1623 "variables": { 1624 "foo": null 1625 }, 1626 1627 "builders": [ 1628 { 1629 "name": "test1", 1630 "type": "test-builder" 1631 }, 1632 { 1633 "name": "test2-{{user \"foo\"}}", 1634 "type": "test-builder" 1635 } 1636 ], 1637 1638 "provisioners": [ 1639 { 1640 "type": "test-prov", 1641 "only": ["test2-{{user \"foo\"}}"] 1642 } 1643 ] 1644 } 1645 ` 1646 1647 template, err := ParseTemplate([]byte(data), map[string]string{"foo": "bar"}) 1648 if err != nil { 1649 t.Fatalf("err: %s", err) 1650 } 1651 1652 // Verify test1 has no provisioners 1653 build, err := template.Build("test1", testTemplateComponentFinder()) 1654 if err != nil { 1655 t.Fatalf("err: %s", err) 1656 } 1657 1658 cbuild := build.(*coreBuild) 1659 if len(cbuild.provisioners) > 0 { 1660 t.Fatal("should have no provisioners") 1661 } 1662 1663 // Verify test2 has one provisioners 1664 build, err = template.Build("test2-{{user \"foo\"}}", testTemplateComponentFinder()) 1665 if err != nil { 1666 t.Fatalf("err: %s", err) 1667 } 1668 1669 cbuild = build.(*coreBuild) 1670 if len(cbuild.provisioners) != 1 { 1671 t.Fatalf("invalid: %d", len(cbuild.provisioners)) 1672 } 1673 } 1674 1675 func TestTemplate_Build_ProvisionerOverride(t *testing.T) { 1676 data := ` 1677 { 1678 "builders": [ 1679 { 1680 "name": "test1", 1681 "type": "test-builder" 1682 } 1683 ], 1684 1685 "provisioners": [ 1686 { 1687 "type": "test-prov", 1688 1689 "override": { 1690 "test1": {} 1691 } 1692 } 1693 ] 1694 } 1695 ` 1696 1697 template, err := ParseTemplate([]byte(data), nil) 1698 if err != nil { 1699 t.Fatalf("err: %s", err) 1700 } 1701 1702 RawConfig := template.Provisioners[0].RawConfig 1703 if RawConfig == nil { 1704 t.Fatal("missing provisioner raw config") 1705 } 1706 1707 expected := map[string]interface{}{ 1708 "type": "test-prov", 1709 } 1710 1711 if !reflect.DeepEqual(RawConfig, expected) { 1712 t.Fatalf("bad raw: %#v", RawConfig) 1713 } 1714 1715 builder := new(MockBuilder) 1716 builderMap := map[string]Builder{ 1717 "test-builder": builder, 1718 } 1719 1720 provisioner := &MockProvisioner{} 1721 provisionerMap := map[string]Provisioner{ 1722 "test-prov": provisioner, 1723 } 1724 1725 builderFactory := func(n string) (Builder, error) { return builderMap[n], nil } 1726 provFactory := func(n string) (Provisioner, error) { return provisionerMap[n], nil } 1727 components := &ComponentFinder{ 1728 Builder: builderFactory, 1729 Provisioner: provFactory, 1730 } 1731 1732 // Get the build, verifying we can get it without issue, but also 1733 // that the proper builder was looked up and used for the build. 1734 build, err := template.Build("test1", components) 1735 if err != nil { 1736 t.Fatalf("err: %s", err) 1737 } 1738 1739 coreBuild, ok := build.(*coreBuild) 1740 if !ok { 1741 t.Fatal("should be okay") 1742 } 1743 if len(coreBuild.provisioners) != 1 { 1744 t.Fatalf("bad: %#v", coreBuild.provisioners) 1745 } 1746 if len(coreBuild.provisioners[0].config) != 2 { 1747 t.Fatalf("bad: %#v", coreBuild.provisioners[0].config) 1748 } 1749 } 1750 1751 func TestTemplate_Build_ProvisionerOverrideBad(t *testing.T) { 1752 data := ` 1753 { 1754 "builders": [ 1755 { 1756 "name": "test1", 1757 "type": "test-builder" 1758 } 1759 ], 1760 1761 "provisioners": [ 1762 { 1763 "type": "test-prov", 1764 1765 "override": { 1766 "testNope": {} 1767 } 1768 } 1769 ] 1770 } 1771 ` 1772 1773 _, err := ParseTemplate([]byte(data), nil) 1774 if err == nil { 1775 t.Fatal("should have error") 1776 } 1777 } 1778 1779 func TestTemplateBuild_ProvisionerPauseBefore(t *testing.T) { 1780 data := ` 1781 { 1782 "builders": [ 1783 { 1784 "name": "test1", 1785 "type": "test-builder" 1786 } 1787 ], 1788 1789 "provisioners": [ 1790 { 1791 "type": "test-prov", 1792 "pause_before": "5s" 1793 } 1794 ] 1795 } 1796 ` 1797 1798 template, err := ParseTemplate([]byte(data), nil) 1799 if err != nil { 1800 t.Fatalf("err: %s", err) 1801 } 1802 1803 builder := new(MockBuilder) 1804 builderMap := map[string]Builder{ 1805 "test-builder": builder, 1806 } 1807 1808 provisioner := &MockProvisioner{} 1809 provisionerMap := map[string]Provisioner{ 1810 "test-prov": provisioner, 1811 } 1812 1813 builderFactory := func(n string) (Builder, error) { return builderMap[n], nil } 1814 provFactory := func(n string) (Provisioner, error) { return provisionerMap[n], nil } 1815 components := &ComponentFinder{ 1816 Builder: builderFactory, 1817 Provisioner: provFactory, 1818 } 1819 1820 // Get the build, verifying we can get it without issue, but also 1821 // that the proper builder was looked up and used for the build. 1822 build, err := template.Build("test1", components) 1823 if err != nil { 1824 t.Fatalf("err: %s", err) 1825 } 1826 1827 coreBuild, ok := build.(*coreBuild) 1828 if !ok { 1829 t.Fatal("should be okay") 1830 } 1831 if len(coreBuild.provisioners) != 1 { 1832 t.Fatalf("bad: %#v", coreBuild.provisioners) 1833 } 1834 if pp, ok := coreBuild.provisioners[0].provisioner.(*PausedProvisioner); !ok { 1835 t.Fatalf("should be paused provisioner") 1836 } else { 1837 if pp.PauseBefore != 5*time.Second { 1838 t.Fatalf("bad: %#v", pp.PauseBefore) 1839 } 1840 } 1841 1842 config := coreBuild.provisioners[0].config[0].(map[string]interface{}) 1843 if _, ok := config["pause_before"]; ok { 1844 t.Fatal("pause_before should be removed") 1845 } 1846 } 1847 1848 func TestTemplateBuild_variables(t *testing.T) { 1849 data := ` 1850 { 1851 "variables": { 1852 "foo": "bar" 1853 }, 1854 1855 "builders": [ 1856 { 1857 "name": "test1", 1858 "type": "test-builder" 1859 } 1860 ] 1861 } 1862 ` 1863 1864 template, err := ParseTemplate([]byte(data), nil) 1865 if err != nil { 1866 t.Fatalf("err: %s", err) 1867 } 1868 1869 build, err := template.Build("test1", testComponentFinder()) 1870 if err != nil { 1871 t.Fatalf("err: %s", err) 1872 } 1873 1874 coreBuild, ok := build.(*coreBuild) 1875 if !ok { 1876 t.Fatalf("couldn't convert!") 1877 } 1878 1879 expected := map[string]string{"foo": "bar"} 1880 if !reflect.DeepEqual(coreBuild.variables, expected) { 1881 t.Fatalf("bad vars: %#v", coreBuild.variables) 1882 } 1883 } 1884 1885 func TestTemplateBuild_variablesRequiredNotSet(t *testing.T) { 1886 data := ` 1887 { 1888 "variables": { 1889 "foo": null 1890 }, 1891 1892 "builders": [ 1893 { 1894 "name": "test1", 1895 "type": "test-builder" 1896 } 1897 ] 1898 } 1899 ` 1900 1901 template, err := ParseTemplate([]byte(data), map[string]string{}) 1902 if err != nil { 1903 t.Fatalf("err: %s", err) 1904 } 1905 1906 _, err = template.Build("test1", testComponentFinder()) 1907 if err == nil { 1908 t.Fatal("should error") 1909 } 1910 }