github.com/tonnydourado/packer@v0.6.1-0.20140701134019-5d0cd9676a37/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 TestParseTemplate_Variables(t *testing.T) {
   545  	data := `
   546  	{
   547  		"variables": {
   548  			"foo": "bar",
   549  			"bar": null,
   550  			"baz": 27
   551  		},
   552  
   553  		"builders": [{"type": "something"}]
   554  	}
   555  	`
   556  
   557  	result, err := ParseTemplate([]byte(data), map[string]string{
   558  		"bar": "bar",
   559  	})
   560  	if err != nil {
   561  		t.Fatalf("err: %s", err)
   562  	}
   563  
   564  	if result.Variables == nil || len(result.Variables) != 3 {
   565  		t.Fatalf("bad vars: %#v", result.Variables)
   566  	}
   567  
   568  	if result.Variables["foo"].Default != "bar" {
   569  		t.Fatal("foo default is not right")
   570  	}
   571  	if result.Variables["foo"].Required {
   572  		t.Fatal("foo should not be required")
   573  	}
   574  	if result.Variables["foo"].HasValue {
   575  		t.Fatal("foo should not have value")
   576  	}
   577  
   578  	if result.Variables["bar"].Default != "" {
   579  		t.Fatal("default should be empty")
   580  	}
   581  	if !result.Variables["bar"].Required {
   582  		t.Fatal("bar should be required")
   583  	}
   584  	if !result.Variables["bar"].HasValue {
   585  		t.Fatal("bar should have value")
   586  	}
   587  	if result.Variables["bar"].Value != "bar" {
   588  		t.Fatal("bad value")
   589  	}
   590  
   591  	if result.Variables["baz"].Default != "27" {
   592  		t.Fatal("default should be empty")
   593  	}
   594  
   595  	if result.Variables["baz"].Required {
   596  		t.Fatal("baz should not be required")
   597  	}
   598  }
   599  
   600  func TestParseTemplate_variablesSet(t *testing.T) {
   601  	data := `
   602  	{
   603  		"variables": {
   604  			"foo": "bar"
   605  		},
   606  
   607  		"builders": [
   608  			{
   609  				"name": "test1",
   610  				"type": "test-builder"
   611  			}
   612  		]
   613  	}
   614  	`
   615  
   616  	template, err := ParseTemplate([]byte(data), map[string]string{
   617  		"foo": "value",
   618  	})
   619  	if err != nil {
   620  		t.Fatalf("err: %s", err)
   621  	}
   622  
   623  	if len(template.Variables) != 1 {
   624  		t.Fatalf("bad vars: %#v", template.Variables)
   625  	}
   626  	if template.Variables["foo"].Value != "value" {
   627  		t.Fatalf("bad: %#v", template.Variables["foo"])
   628  	}
   629  }
   630  
   631  func TestParseTemplate_variablesSetUnknown(t *testing.T) {
   632  	data := `
   633  	{
   634  		"variables": {
   635  			"foo": "bar"
   636  		},
   637  
   638  		"builders": [
   639  			{
   640  				"name": "test1",
   641  				"type": "test-builder"
   642  			}
   643  		]
   644  	}
   645  	`
   646  
   647  	_, err := ParseTemplate([]byte(data), map[string]string{
   648  		"what": "value",
   649  	})
   650  	if err == nil {
   651  		t.Fatal("should error")
   652  	}
   653  }
   654  
   655  func TestParseTemplate_variablesBadDefault(t *testing.T) {
   656  	data := `
   657  	{
   658  		"variables": {
   659  			"foo": 7,
   660  		},
   661  
   662  		"builders": [{"type": "something"}]
   663  	}
   664  	`
   665  
   666  	_, err := ParseTemplate([]byte(data), nil)
   667  	if err == nil {
   668  		t.Fatal("should have error")
   669  	}
   670  }
   671  
   672  func TestTemplate_BuildNames(t *testing.T) {
   673  	data := `
   674  	{
   675  		"builders": [
   676  			{
   677  				"name": "bob",
   678  				"type": "amazon-ebs"
   679  			},
   680  			{
   681  				"name": "chris",
   682  				"type": "another"
   683  			}
   684  		]
   685  	}
   686  	`
   687  
   688  	result, err := ParseTemplate([]byte(data), nil)
   689  	if err != nil {
   690  		t.Fatalf("err: %s", err)
   691  	}
   692  
   693  	buildNames := result.BuildNames()
   694  	sort.Strings(buildNames)
   695  	if !reflect.DeepEqual(buildNames, []string{"bob", "chris"}) {
   696  		t.Fatalf("bad: %#v", buildNames)
   697  	}
   698  }
   699  
   700  func TestTemplate_BuildUnknown(t *testing.T) {
   701  	data := `
   702  	{
   703  		"builders": [
   704  			{
   705  				"name": "test1",
   706  				"type": "test-builder"
   707  			}
   708  		]
   709  	}
   710  	`
   711  
   712  	template, err := ParseTemplate([]byte(data), nil)
   713  	if err != nil {
   714  		t.Fatalf("bad: %s", err)
   715  	}
   716  
   717  	build, err := template.Build("nope", nil)
   718  	if build != nil {
   719  		t.Fatalf("build should be nil: %#v", build)
   720  	}
   721  	if err == nil {
   722  		t.Fatal("should have error")
   723  	}
   724  }
   725  
   726  func TestTemplate_BuildUnknownBuilder(t *testing.T) {
   727  	data := `
   728  	{
   729  		"builders": [
   730  			{
   731  				"name": "test1",
   732  				"type": "test-builder"
   733  			}
   734  		]
   735  	}
   736  	`
   737  
   738  	template, err := ParseTemplate([]byte(data), nil)
   739  	if err != nil {
   740  		t.Fatalf("err: %s", err)
   741  	}
   742  
   743  	builderFactory := func(string) (Builder, error) { return nil, nil }
   744  	components := &ComponentFinder{Builder: builderFactory}
   745  	build, err := template.Build("test1", components)
   746  	if err == nil {
   747  		t.Fatal("should have error")
   748  	}
   749  	if build != nil {
   750  		t.Fatalf("bad: %#v", build)
   751  	}
   752  }
   753  
   754  func TestTemplateBuild_envInVars(t *testing.T) {
   755  	data := `
   756  	{
   757  		"variables": {
   758  			"foo": "{{env \"foo\"}}"
   759  		},
   760  
   761  		"builders": [
   762  			{
   763  				"name": "test1",
   764  				"type": "test-builder"
   765  			}
   766  		]
   767  	}
   768  	`
   769  
   770  	defer os.Setenv("foo", os.Getenv("foo"))
   771  	if err := os.Setenv("foo", "bar"); err != nil {
   772  		t.Fatalf("err: %s", err)
   773  	}
   774  
   775  	template, err := ParseTemplate([]byte(data), map[string]string{})
   776  	if err != nil {
   777  		t.Fatalf("err: %s", err)
   778  	}
   779  
   780  	b, err := template.Build("test1", testComponentFinder())
   781  	if err != nil {
   782  		t.Fatalf("err: %s", err)
   783  	}
   784  
   785  	coreBuild, ok := b.(*coreBuild)
   786  	if !ok {
   787  		t.Fatal("should be ok")
   788  	}
   789  
   790  	if coreBuild.variables["foo"] != "bar" {
   791  		t.Fatalf("bad: %#v", coreBuild.variables)
   792  	}
   793  }
   794  
   795  func TestTemplateBuild_names(t *testing.T) {
   796  	data := `
   797  	{
   798  		"variables": {
   799  			"foo": null
   800  		},
   801  
   802  		"builders": [
   803  			{
   804  				"name": "test1",
   805  				"type": "test-builder"
   806  			},
   807  			{
   808  				"name": "test2-{{user \"foo\"}}",
   809  				"type": "test-builder"
   810  			}
   811  		]
   812  	}
   813  	`
   814  
   815  	template, err := ParseTemplate([]byte(data), map[string]string{"foo": "bar"})
   816  	if err != nil {
   817  		t.Fatalf("err: %s", err)
   818  	}
   819  
   820  	b, err := template.Build("test1", testComponentFinder())
   821  	if err != nil {
   822  		t.Fatalf("err: %s", err)
   823  	}
   824  	if b.Name() != "test1" {
   825  		t.Fatalf("bad: %#v", b.Name())
   826  	}
   827  
   828  	b, err = template.Build("test2-{{user \"foo\"}}", testComponentFinder())
   829  	if err != nil {
   830  		t.Fatalf("err: %s", err)
   831  	}
   832  	if b.Name() != "test2-bar" {
   833  		t.Fatalf("bad: %#v", b.Name())
   834  	}
   835  }
   836  
   837  func TestTemplate_Build_NilBuilderFunc(t *testing.T) {
   838  	data := `
   839  	{
   840  		"builders": [
   841  			{
   842  				"name": "test1",
   843  				"type": "test-builder"
   844  			}
   845  		],
   846  
   847  		"provisioners": [
   848  			{
   849  				"type": "test-prov"
   850  			}
   851  		]
   852  	}
   853  	`
   854  
   855  	template, err := ParseTemplate([]byte(data), nil)
   856  	if err != nil {
   857  		t.Fatalf("err: %s", err)
   858  	}
   859  
   860  	defer func() {
   861  		p := recover()
   862  		if p == nil {
   863  			t.Fatal("should panic")
   864  		}
   865  
   866  		if p.(string) != "no builder function" {
   867  			t.Fatalf("bad panic: %s", p.(string))
   868  		}
   869  	}()
   870  
   871  	template.Build("test1", &ComponentFinder{})
   872  }
   873  
   874  func TestTemplate_Build_NilProvisionerFunc(t *testing.T) {
   875  	data := `
   876  	{
   877  		"builders": [
   878  			{
   879  				"name": "test1",
   880  				"type": "test-builder"
   881  			}
   882  		],
   883  
   884  		"provisioners": [
   885  			{
   886  				"type": "test-prov"
   887  			}
   888  		]
   889  	}
   890  	`
   891  
   892  	template, err := ParseTemplate([]byte(data), nil)
   893  	if err != nil {
   894  		t.Fatalf("err: %s", err)
   895  	}
   896  
   897  	defer func() {
   898  		p := recover()
   899  		if p == nil {
   900  			t.Fatal("should panic")
   901  		}
   902  
   903  		if p.(string) != "no provisioner function" {
   904  			t.Fatalf("bad panic: %s", p.(string))
   905  		}
   906  	}()
   907  
   908  	template.Build("test1", &ComponentFinder{
   909  		Builder: func(string) (Builder, error) { return nil, nil },
   910  	})
   911  }
   912  
   913  func TestTemplate_Build_NilProvisionerFunc_WithNoProvisioners(t *testing.T) {
   914  	data := `
   915  	{
   916  		"builders": [
   917  			{
   918  				"name": "test1",
   919  				"type": "test-builder"
   920  			}
   921  		],
   922  
   923  		"provisioners": []
   924  	}
   925  	`
   926  
   927  	template, err := ParseTemplate([]byte(data), nil)
   928  	if err != nil {
   929  		t.Fatalf("err: %s", err)
   930  	}
   931  
   932  	template.Build("test1", &ComponentFinder{
   933  		Builder: func(string) (Builder, error) { return nil, nil },
   934  	})
   935  }
   936  
   937  func TestTemplate_Build(t *testing.T) {
   938  	data := `
   939  	{
   940  		"builders": [
   941  			{
   942  				"name": "test1",
   943  				"type": "test-builder"
   944  			}
   945  		],
   946  
   947  		"provisioners": [
   948  			{
   949  				"type": "test-prov"
   950  			}
   951  		],
   952  
   953  		"post-processors": [
   954  			"simple",
   955  			[
   956  				"simple",
   957  				{ "type": "simple", "keep_input_artifact": true }
   958  			]
   959  		]
   960  	}
   961  	`
   962  
   963  	expectedConfig := map[string]interface{}{
   964  		"type": "test-builder",
   965  	}
   966  
   967  	template, err := ParseTemplate([]byte(data), nil)
   968  	if err != nil {
   969  		t.Fatalf("err: %s", err)
   970  	}
   971  
   972  	builder := new(MockBuilder)
   973  	builderMap := map[string]Builder{
   974  		"test-builder": builder,
   975  	}
   976  
   977  	provisioner := &MockProvisioner{}
   978  	provisionerMap := map[string]Provisioner{
   979  		"test-prov": provisioner,
   980  	}
   981  
   982  	pp := new(TestPostProcessor)
   983  	ppMap := map[string]PostProcessor{
   984  		"simple": pp,
   985  	}
   986  
   987  	builderFactory := func(n string) (Builder, error) { return builderMap[n], nil }
   988  	ppFactory := func(n string) (PostProcessor, error) { return ppMap[n], nil }
   989  	provFactory := func(n string) (Provisioner, error) { return provisionerMap[n], nil }
   990  	components := &ComponentFinder{
   991  		Builder:       builderFactory,
   992  		PostProcessor: ppFactory,
   993  		Provisioner:   provFactory,
   994  	}
   995  
   996  	// Get the build, verifying we can get it without issue, but also
   997  	// that the proper builder was looked up and used for the build.
   998  	build, err := template.Build("test1", components)
   999  	if err != nil {
  1000  		t.Fatalf("err: %s", err)
  1001  	}
  1002  
  1003  	coreBuild, ok := build.(*coreBuild)
  1004  	if !ok {
  1005  		t.Fatal("should be ok")
  1006  	}
  1007  	if coreBuild.builder != builder {
  1008  		t.Fatalf("bad: %#v", coreBuild.builder)
  1009  	}
  1010  	if !reflect.DeepEqual(coreBuild.builderConfig, expectedConfig) {
  1011  		t.Fatalf("bad: %#v", coreBuild.builderConfig)
  1012  	}
  1013  	if len(coreBuild.provisioners) != 1 {
  1014  		t.Fatalf("bad: %#v", coreBuild.provisioners)
  1015  	}
  1016  	if len(coreBuild.postProcessors) != 2 {
  1017  		t.Fatalf("bad: %#v", coreBuild.postProcessors)
  1018  	}
  1019  
  1020  	if len(coreBuild.postProcessors[0]) != 1 {
  1021  		t.Fatalf("bad: %#v", coreBuild.postProcessors[0])
  1022  	}
  1023  	if len(coreBuild.postProcessors[1]) != 2 {
  1024  		t.Fatalf("bad: %#v", coreBuild.postProcessors[1])
  1025  	}
  1026  
  1027  	if coreBuild.postProcessors[1][0].keepInputArtifact {
  1028  		t.Fatal("postProcessors[1][0] should not keep input artifact")
  1029  	}
  1030  	if !coreBuild.postProcessors[1][1].keepInputArtifact {
  1031  		t.Fatal("postProcessors[1][1] should keep input artifact")
  1032  	}
  1033  
  1034  	config := coreBuild.postProcessors[1][1].config
  1035  	if _, ok := config["keep_input_artifact"]; ok {
  1036  		t.Fatal("should not have keep_input_artifact")
  1037  	}
  1038  }
  1039  
  1040  func TestTemplateBuild_exceptOnlyPP(t *testing.T) {
  1041  	data := `
  1042  	{
  1043  		"builders": [
  1044  			{
  1045  				"name": "test1",
  1046  				"type": "test-builder"
  1047  			},
  1048  			{
  1049  				"name": "test2",
  1050  				"type": "test-builder"
  1051  			}
  1052  		],
  1053  
  1054  		"post-processors": [
  1055  			{
  1056  				"type": "test-pp",
  1057  				"except": ["test1"],
  1058  				"only": ["test1"]
  1059  			}
  1060  		]
  1061  	}
  1062  	`
  1063  
  1064  	_, err := ParseTemplate([]byte(data), nil)
  1065  	if err == nil {
  1066  		t.Fatal("should have error")
  1067  	}
  1068  }
  1069  
  1070  func TestTemplateBuild_exceptOnlyProv(t *testing.T) {
  1071  	data := `
  1072  	{
  1073  		"builders": [
  1074  			{
  1075  				"name": "test1",
  1076  				"type": "test-builder"
  1077  			},
  1078  			{
  1079  				"name": "test2",
  1080  				"type": "test-builder"
  1081  			}
  1082  		],
  1083  
  1084  		"provisioners": [
  1085  			{
  1086  				"type": "test-prov",
  1087  				"except": ["test1"],
  1088  				"only": ["test1"]
  1089  			}
  1090  		]
  1091  	}
  1092  	`
  1093  
  1094  	_, err := ParseTemplate([]byte(data), nil)
  1095  	if err == nil {
  1096  		t.Fatal("should have error")
  1097  	}
  1098  }
  1099  
  1100  func TestTemplateBuild_exceptPPInvalid(t *testing.T) {
  1101  	data := `
  1102  	{
  1103  		"builders": [
  1104  			{
  1105  				"name": "test1",
  1106  				"type": "test-builder"
  1107  			},
  1108  			{
  1109  				"name": "test2",
  1110  				"type": "test-builder"
  1111  			}
  1112  		],
  1113  
  1114  		"post-processors": [
  1115  			{
  1116  				"type": "test-pp",
  1117  				"except": ["test5"]
  1118  			}
  1119  		]
  1120  	}
  1121  	`
  1122  
  1123  	_, err := ParseTemplate([]byte(data), nil)
  1124  	if err == nil {
  1125  		t.Fatal("should have error")
  1126  	}
  1127  }
  1128  
  1129  func TestTemplateBuild_exceptPP(t *testing.T) {
  1130  	data := `
  1131  	{
  1132  		"builders": [
  1133  			{
  1134  				"name": "test1",
  1135  				"type": "test-builder"
  1136  			},
  1137  			{
  1138  				"name": "test2",
  1139  				"type": "test-builder"
  1140  			}
  1141  		],
  1142  
  1143  		"post-processors": [
  1144  			{
  1145  				"type": "test-pp",
  1146  				"except": ["test1"]
  1147  			}
  1148  		]
  1149  	}
  1150  	`
  1151  
  1152  	template, err := ParseTemplate([]byte(data), nil)
  1153  	if err != nil {
  1154  		t.Fatalf("err: %s", err)
  1155  	}
  1156  
  1157  	// Verify test1 has no post-processors
  1158  	build, err := template.Build("test1", testTemplateComponentFinder())
  1159  	if err != nil {
  1160  		t.Fatalf("err: %s", err)
  1161  	}
  1162  
  1163  	cbuild := build.(*coreBuild)
  1164  	if len(cbuild.postProcessors) > 0 {
  1165  		t.Fatal("should have no postProcessors")
  1166  	}
  1167  
  1168  	// Verify test2 has no post-processors
  1169  	build, err = template.Build("test2", testTemplateComponentFinder())
  1170  	if err != nil {
  1171  		t.Fatalf("err: %s", err)
  1172  	}
  1173  
  1174  	cbuild = build.(*coreBuild)
  1175  	if len(cbuild.postProcessors) != 1 {
  1176  		t.Fatalf("invalid: %d", len(cbuild.postProcessors))
  1177  	}
  1178  }
  1179  
  1180  func TestTemplateBuild_exceptProvInvalid(t *testing.T) {
  1181  	data := `
  1182  	{
  1183  		"builders": [
  1184  			{
  1185  				"name": "test1",
  1186  				"type": "test-builder"
  1187  			},
  1188  			{
  1189  				"name": "test2",
  1190  				"type": "test-builder"
  1191  			}
  1192  		],
  1193  
  1194  		"provisioners": [
  1195  			{
  1196  				"type": "test-prov",
  1197  				"except": ["test5"]
  1198  			}
  1199  		]
  1200  	}
  1201  	`
  1202  
  1203  	_, err := ParseTemplate([]byte(data), nil)
  1204  	if err == nil {
  1205  		t.Fatal("should have error")
  1206  	}
  1207  }
  1208  
  1209  func TestTemplateBuild_exceptProv(t *testing.T) {
  1210  	data := `
  1211  	{
  1212  		"builders": [
  1213  			{
  1214  				"name": "test1",
  1215  				"type": "test-builder"
  1216  			},
  1217  			{
  1218  				"name": "test2",
  1219  				"type": "test-builder"
  1220  			}
  1221  		],
  1222  
  1223  		"provisioners": [
  1224  			{
  1225  				"type": "test-prov",
  1226  				"except": ["test1"]
  1227  			}
  1228  		]
  1229  	}
  1230  	`
  1231  
  1232  	template, err := ParseTemplate([]byte(data), nil)
  1233  	if err != nil {
  1234  		t.Fatalf("err: %s", err)
  1235  	}
  1236  
  1237  	// Verify test1 has no provisioners
  1238  	build, err := template.Build("test1", testTemplateComponentFinder())
  1239  	if err != nil {
  1240  		t.Fatalf("err: %s", err)
  1241  	}
  1242  
  1243  	cbuild := build.(*coreBuild)
  1244  	if len(cbuild.provisioners) > 0 {
  1245  		t.Fatal("should have no provisioners")
  1246  	}
  1247  
  1248  	// Verify test2 has no provisioners
  1249  	build, err = template.Build("test2", testTemplateComponentFinder())
  1250  	if err != nil {
  1251  		t.Fatalf("err: %s", err)
  1252  	}
  1253  
  1254  	cbuild = build.(*coreBuild)
  1255  	if len(cbuild.provisioners) != 1 {
  1256  		t.Fatalf("invalid: %d", len(cbuild.provisioners))
  1257  	}
  1258  }
  1259  
  1260  func TestTemplateBuild_onlyPPInvalid(t *testing.T) {
  1261  	data := `
  1262  	{
  1263  		"builders": [
  1264  			{
  1265  				"name": "test1",
  1266  				"type": "test-builder"
  1267  			},
  1268  			{
  1269  				"name": "test2",
  1270  				"type": "test-builder"
  1271  			}
  1272  		],
  1273  
  1274  		"post-processors": [
  1275  			{
  1276  				"type": "test-pp",
  1277  				"only": ["test5"]
  1278  			}
  1279  		]
  1280  	}
  1281  	`
  1282  
  1283  	_, err := ParseTemplate([]byte(data), nil)
  1284  	if err == nil {
  1285  		t.Fatal("should have error")
  1286  	}
  1287  }
  1288  
  1289  func TestTemplateBuild_onlyPP(t *testing.T) {
  1290  	data := `
  1291  	{
  1292  		"builders": [
  1293  			{
  1294  				"name": "test1",
  1295  				"type": "test-builder"
  1296  			},
  1297  			{
  1298  				"name": "test2",
  1299  				"type": "test-builder"
  1300  			}
  1301  		],
  1302  
  1303  		"post-processors": [
  1304  			{
  1305  				"type": "test-pp",
  1306  				"only": ["test2"]
  1307  			}
  1308  		]
  1309  	}
  1310  	`
  1311  
  1312  	template, err := ParseTemplate([]byte(data), nil)
  1313  	if err != nil {
  1314  		t.Fatalf("err: %s", err)
  1315  	}
  1316  
  1317  	// Verify test1 has no post-processors
  1318  	build, err := template.Build("test1", testTemplateComponentFinder())
  1319  	if err != nil {
  1320  		t.Fatalf("err: %s", err)
  1321  	}
  1322  
  1323  	cbuild := build.(*coreBuild)
  1324  	if len(cbuild.postProcessors) > 0 {
  1325  		t.Fatal("should have no postProcessors")
  1326  	}
  1327  
  1328  	// Verify test2 has no post-processors
  1329  	build, err = template.Build("test2", testTemplateComponentFinder())
  1330  	if err != nil {
  1331  		t.Fatalf("err: %s", err)
  1332  	}
  1333  
  1334  	cbuild = build.(*coreBuild)
  1335  	if len(cbuild.postProcessors) != 1 {
  1336  		t.Fatalf("invalid: %d", len(cbuild.postProcessors))
  1337  	}
  1338  }
  1339  
  1340  func TestTemplateBuild_onlyProvInvalid(t *testing.T) {
  1341  	data := `
  1342  	{
  1343  		"builders": [
  1344  			{
  1345  				"name": "test1",
  1346  				"type": "test-builder"
  1347  			},
  1348  			{
  1349  				"name": "test2",
  1350  				"type": "test-builder"
  1351  			}
  1352  		],
  1353  
  1354  		"provisioners": [
  1355  			{
  1356  				"type": "test-prov",
  1357  				"only": ["test5"]
  1358  			}
  1359  		]
  1360  	}
  1361  	`
  1362  
  1363  	_, err := ParseTemplate([]byte(data), nil)
  1364  	if err == nil {
  1365  		t.Fatal("should have error")
  1366  	}
  1367  }
  1368  
  1369  func TestTemplateBuild_onlyProv(t *testing.T) {
  1370  	data := `
  1371  	{
  1372  		"builders": [
  1373  			{
  1374  				"name": "test1",
  1375  				"type": "test-builder"
  1376  			},
  1377  			{
  1378  				"name": "test2",
  1379  				"type": "test-builder"
  1380  			}
  1381  		],
  1382  
  1383  		"provisioners": [
  1384  			{
  1385  				"type": "test-prov",
  1386  				"only": ["test2"]
  1387  			}
  1388  		]
  1389  	}
  1390  	`
  1391  
  1392  	template, err := ParseTemplate([]byte(data), nil)
  1393  	if err != nil {
  1394  		t.Fatalf("err: %s", err)
  1395  	}
  1396  
  1397  	// Verify test1 has no provisioners
  1398  	build, err := template.Build("test1", testTemplateComponentFinder())
  1399  	if err != nil {
  1400  		t.Fatalf("err: %s", err)
  1401  	}
  1402  
  1403  	cbuild := build.(*coreBuild)
  1404  	if len(cbuild.provisioners) > 0 {
  1405  		t.Fatal("should have no provisioners")
  1406  	}
  1407  
  1408  	// Verify test2 has no provisioners
  1409  	build, err = template.Build("test2", testTemplateComponentFinder())
  1410  	if err != nil {
  1411  		t.Fatalf("err: %s", err)
  1412  	}
  1413  
  1414  	cbuild = build.(*coreBuild)
  1415  	if len(cbuild.provisioners) != 1 {
  1416  		t.Fatalf("invalid: %d", len(cbuild.provisioners))
  1417  	}
  1418  }
  1419  
  1420  func TestTemplate_Build_ProvisionerOverride(t *testing.T) {
  1421  	data := `
  1422  	{
  1423  		"builders": [
  1424  			{
  1425  				"name": "test1",
  1426  				"type": "test-builder"
  1427  			}
  1428  		],
  1429  
  1430  		"provisioners": [
  1431  			{
  1432  				"type": "test-prov",
  1433  
  1434  				"override": {
  1435  					"test1": {}
  1436  				}
  1437  			}
  1438  		]
  1439  	}
  1440  	`
  1441  
  1442  	template, err := ParseTemplate([]byte(data), nil)
  1443  	if err != nil {
  1444  		t.Fatalf("err: %s", err)
  1445  	}
  1446  
  1447  	RawConfig := template.Provisioners[0].RawConfig
  1448  	if RawConfig == nil {
  1449  		t.Fatal("missing provisioner raw config")
  1450  	}
  1451  
  1452  	expected := map[string]interface{}{
  1453  		"type": "test-prov",
  1454  	}
  1455  
  1456  	if !reflect.DeepEqual(RawConfig, expected) {
  1457  		t.Fatalf("bad raw: %#v", RawConfig)
  1458  	}
  1459  
  1460  	builder := new(MockBuilder)
  1461  	builderMap := map[string]Builder{
  1462  		"test-builder": builder,
  1463  	}
  1464  
  1465  	provisioner := &MockProvisioner{}
  1466  	provisionerMap := map[string]Provisioner{
  1467  		"test-prov": provisioner,
  1468  	}
  1469  
  1470  	builderFactory := func(n string) (Builder, error) { return builderMap[n], nil }
  1471  	provFactory := func(n string) (Provisioner, error) { return provisionerMap[n], nil }
  1472  	components := &ComponentFinder{
  1473  		Builder:     builderFactory,
  1474  		Provisioner: provFactory,
  1475  	}
  1476  
  1477  	// Get the build, verifying we can get it without issue, but also
  1478  	// that the proper builder was looked up and used for the build.
  1479  	build, err := template.Build("test1", components)
  1480  	if err != nil {
  1481  		t.Fatalf("err: %s", err)
  1482  	}
  1483  
  1484  	coreBuild, ok := build.(*coreBuild)
  1485  	if !ok {
  1486  		t.Fatal("should be okay")
  1487  	}
  1488  	if len(coreBuild.provisioners) != 1 {
  1489  		t.Fatalf("bad: %#v", coreBuild.provisioners)
  1490  	}
  1491  	if len(coreBuild.provisioners[0].config) != 2 {
  1492  		t.Fatalf("bad: %#v", coreBuild.provisioners[0].config)
  1493  	}
  1494  }
  1495  
  1496  func TestTemplate_Build_ProvisionerOverrideBad(t *testing.T) {
  1497  	data := `
  1498  	{
  1499  		"builders": [
  1500  			{
  1501  				"name": "test1",
  1502  				"type": "test-builder"
  1503  			}
  1504  		],
  1505  
  1506  		"provisioners": [
  1507  			{
  1508  				"type": "test-prov",
  1509  
  1510  				"override": {
  1511  					"testNope": {}
  1512  				}
  1513  			}
  1514  		]
  1515  	}
  1516  	`
  1517  
  1518  	_, err := ParseTemplate([]byte(data), nil)
  1519  	if err == nil {
  1520  		t.Fatal("should have error")
  1521  	}
  1522  }
  1523  
  1524  func TestTemplateBuild_ProvisionerPauseBefore(t *testing.T) {
  1525  	data := `
  1526  	{
  1527  		"builders": [
  1528  			{
  1529  				"name": "test1",
  1530  				"type": "test-builder"
  1531  			}
  1532  		],
  1533  
  1534  		"provisioners": [
  1535  			{
  1536  				"type": "test-prov",
  1537  				"pause_before": "5s"
  1538  			}
  1539  		]
  1540  	}
  1541  	`
  1542  
  1543  	template, err := ParseTemplate([]byte(data), nil)
  1544  	if err != nil {
  1545  		t.Fatalf("err: %s", err)
  1546  	}
  1547  
  1548  	builder := new(MockBuilder)
  1549  	builderMap := map[string]Builder{
  1550  		"test-builder": builder,
  1551  	}
  1552  
  1553  	provisioner := &MockProvisioner{}
  1554  	provisionerMap := map[string]Provisioner{
  1555  		"test-prov": provisioner,
  1556  	}
  1557  
  1558  	builderFactory := func(n string) (Builder, error) { return builderMap[n], nil }
  1559  	provFactory := func(n string) (Provisioner, error) { return provisionerMap[n], nil }
  1560  	components := &ComponentFinder{
  1561  		Builder:     builderFactory,
  1562  		Provisioner: provFactory,
  1563  	}
  1564  
  1565  	// Get the build, verifying we can get it without issue, but also
  1566  	// that the proper builder was looked up and used for the build.
  1567  	build, err := template.Build("test1", components)
  1568  	if err != nil {
  1569  		t.Fatalf("err: %s", err)
  1570  	}
  1571  
  1572  	coreBuild, ok := build.(*coreBuild)
  1573  	if !ok {
  1574  		t.Fatal("should be okay")
  1575  	}
  1576  	if len(coreBuild.provisioners) != 1 {
  1577  		t.Fatalf("bad: %#v", coreBuild.provisioners)
  1578  	}
  1579  	if pp, ok := coreBuild.provisioners[0].provisioner.(*PausedProvisioner); !ok {
  1580  		t.Fatalf("should be paused provisioner")
  1581  	} else {
  1582  		if pp.PauseBefore != 5*time.Second {
  1583  			t.Fatalf("bad: %#v", pp.PauseBefore)
  1584  		}
  1585  	}
  1586  
  1587  	config := coreBuild.provisioners[0].config[0].(map[string]interface{})
  1588  	if _, ok := config["pause_before"]; ok {
  1589  		t.Fatal("pause_before should be removed")
  1590  	}
  1591  }
  1592  
  1593  func TestTemplateBuild_variables(t *testing.T) {
  1594  	data := `
  1595  	{
  1596  		"variables": {
  1597  			"foo": "bar"
  1598  		},
  1599  
  1600  		"builders": [
  1601  			{
  1602  				"name": "test1",
  1603  				"type": "test-builder"
  1604  			}
  1605  		]
  1606  	}
  1607  	`
  1608  
  1609  	template, err := ParseTemplate([]byte(data), nil)
  1610  	if err != nil {
  1611  		t.Fatalf("err: %s", err)
  1612  	}
  1613  
  1614  	build, err := template.Build("test1", testComponentFinder())
  1615  	if err != nil {
  1616  		t.Fatalf("err: %s", err)
  1617  	}
  1618  
  1619  	coreBuild, ok := build.(*coreBuild)
  1620  	if !ok {
  1621  		t.Fatalf("couldn't convert!")
  1622  	}
  1623  
  1624  	expected := map[string]string{"foo": "bar"}
  1625  	if !reflect.DeepEqual(coreBuild.variables, expected) {
  1626  		t.Fatalf("bad vars: %#v", coreBuild.variables)
  1627  	}
  1628  }
  1629  
  1630  func TestTemplateBuild_variablesRequiredNotSet(t *testing.T) {
  1631  	data := `
  1632  	{
  1633  		"variables": {
  1634  			"foo": null
  1635  		},
  1636  
  1637  		"builders": [
  1638  			{
  1639  				"name": "test1",
  1640  				"type": "test-builder"
  1641  			}
  1642  		]
  1643  	}
  1644  	`
  1645  
  1646  	template, err := ParseTemplate([]byte(data), map[string]string{})
  1647  	if err != nil {
  1648  		t.Fatalf("err: %s", err)
  1649  	}
  1650  
  1651  	_, err = template.Build("test1", testComponentFinder())
  1652  	if err == nil {
  1653  		t.Fatal("should error")
  1654  	}
  1655  }