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  }