github.com/HashDataInc/packer@v1.3.2/packer/core_test.go (about)

     1  package packer
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  	"reflect"
     7  	"testing"
     8  
     9  	configHelper "github.com/hashicorp/packer/helper/config"
    10  	"github.com/hashicorp/packer/template"
    11  )
    12  
    13  func TestCoreBuildNames(t *testing.T) {
    14  	cases := []struct {
    15  		File   string
    16  		Vars   map[string]string
    17  		Result []string
    18  	}{
    19  		{
    20  			"build-names-basic.json",
    21  			nil,
    22  			[]string{"something"},
    23  		},
    24  
    25  		{
    26  			"build-names-func.json",
    27  			nil,
    28  			[]string{"TUBES"},
    29  		},
    30  	}
    31  
    32  	for _, tc := range cases {
    33  		tpl, err := template.ParseFile(fixtureDir(tc.File))
    34  		if err != nil {
    35  			t.Fatalf("err: %s\n\n%s", tc.File, err)
    36  		}
    37  
    38  		core, err := NewCore(&CoreConfig{
    39  			Template:  tpl,
    40  			Variables: tc.Vars,
    41  		})
    42  		if err != nil {
    43  			t.Fatalf("err: %s\n\n%s", tc.File, err)
    44  		}
    45  
    46  		names := core.BuildNames()
    47  		if !reflect.DeepEqual(names, tc.Result) {
    48  			t.Fatalf("err: %s\n\n%#v", tc.File, names)
    49  		}
    50  	}
    51  }
    52  
    53  func TestCoreBuild_basic(t *testing.T) {
    54  	config := TestCoreConfig(t)
    55  	testCoreTemplate(t, config, fixtureDir("build-basic.json"))
    56  	b := TestBuilder(t, config, "test")
    57  	core := TestCore(t, config)
    58  
    59  	b.ArtifactId = "hello"
    60  
    61  	build, err := core.Build("test")
    62  	if err != nil {
    63  		t.Fatalf("err: %s", err)
    64  	}
    65  
    66  	if _, err := build.Prepare(); err != nil {
    67  		t.Fatalf("err: %s", err)
    68  	}
    69  
    70  	artifact, err := build.Run(nil, nil)
    71  	if err != nil {
    72  		t.Fatalf("err: %s", err)
    73  	}
    74  	if len(artifact) != 1 {
    75  		t.Fatalf("bad: %#v", artifact)
    76  	}
    77  
    78  	if artifact[0].Id() != b.ArtifactId {
    79  		t.Fatalf("bad: %s", artifact[0].Id())
    80  	}
    81  }
    82  
    83  func TestCoreBuild_basicInterpolated(t *testing.T) {
    84  	config := TestCoreConfig(t)
    85  	testCoreTemplate(t, config, fixtureDir("build-basic-interpolated.json"))
    86  	b := TestBuilder(t, config, "test")
    87  	core := TestCore(t, config)
    88  
    89  	b.ArtifactId = "hello"
    90  
    91  	build, err := core.Build("NAME")
    92  	if err != nil {
    93  		t.Fatalf("err: %s", err)
    94  	}
    95  
    96  	if _, err := build.Prepare(); err != nil {
    97  		t.Fatalf("err: %s", err)
    98  	}
    99  
   100  	artifact, err := build.Run(nil, nil)
   101  	if err != nil {
   102  		t.Fatalf("err: %s", err)
   103  	}
   104  	if len(artifact) != 1 {
   105  		t.Fatalf("bad: %#v", artifact)
   106  	}
   107  
   108  	if artifact[0].Id() != b.ArtifactId {
   109  		t.Fatalf("bad: %s", artifact[0].Id())
   110  	}
   111  }
   112  
   113  func TestCoreBuild_env(t *testing.T) {
   114  	os.Setenv("PACKER_TEST_ENV", "test")
   115  	defer os.Setenv("PACKER_TEST_ENV", "")
   116  
   117  	config := TestCoreConfig(t)
   118  	testCoreTemplate(t, config, fixtureDir("build-env.json"))
   119  	b := TestBuilder(t, config, "test")
   120  	core := TestCore(t, config)
   121  
   122  	b.ArtifactId = "hello"
   123  
   124  	build, err := core.Build("test")
   125  	if err != nil {
   126  		t.Fatalf("err: %s", err)
   127  	}
   128  
   129  	if _, err := build.Prepare(); err != nil {
   130  		t.Fatalf("err: %s", err)
   131  	}
   132  
   133  	// Interpolate the config
   134  	var result map[string]interface{}
   135  	err = configHelper.Decode(&result, nil, b.PrepareConfig...)
   136  	if err != nil {
   137  		t.Fatalf("err: %s", err)
   138  	}
   139  
   140  	if result["value"] != "test" {
   141  		t.Fatalf("bad: %#v", result)
   142  	}
   143  }
   144  
   145  func TestCoreBuild_buildNameVar(t *testing.T) {
   146  	config := TestCoreConfig(t)
   147  	testCoreTemplate(t, config, fixtureDir("build-var-build-name.json"))
   148  	b := TestBuilder(t, config, "test")
   149  	core := TestCore(t, config)
   150  
   151  	b.ArtifactId = "hello"
   152  
   153  	build, err := core.Build("test")
   154  	if err != nil {
   155  		t.Fatalf("err: %s", err)
   156  	}
   157  
   158  	if _, err := build.Prepare(); err != nil {
   159  		t.Fatalf("err: %s", err)
   160  	}
   161  
   162  	// Interpolate the config
   163  	var result map[string]interface{}
   164  	err = configHelper.Decode(&result, nil, b.PrepareConfig...)
   165  	if err != nil {
   166  		t.Fatalf("err: %s", err)
   167  	}
   168  
   169  	if result["value"] != "test" {
   170  		t.Fatalf("bad: %#v", result)
   171  	}
   172  }
   173  
   174  func TestCoreBuild_buildTypeVar(t *testing.T) {
   175  	config := TestCoreConfig(t)
   176  	testCoreTemplate(t, config, fixtureDir("build-var-build-type.json"))
   177  	b := TestBuilder(t, config, "test")
   178  	core := TestCore(t, config)
   179  
   180  	b.ArtifactId = "hello"
   181  
   182  	build, err := core.Build("test")
   183  	if err != nil {
   184  		t.Fatalf("err: %s", err)
   185  	}
   186  
   187  	if _, err := build.Prepare(); err != nil {
   188  		t.Fatalf("err: %s", err)
   189  	}
   190  
   191  	// Interpolate the config
   192  	var result map[string]interface{}
   193  	err = configHelper.Decode(&result, nil, b.PrepareConfig...)
   194  	if err != nil {
   195  		t.Fatalf("err: %s", err)
   196  	}
   197  
   198  	if result["value"] != "test" {
   199  		t.Fatalf("bad: %#v", result)
   200  	}
   201  }
   202  
   203  func TestCoreBuild_nonExist(t *testing.T) {
   204  	config := TestCoreConfig(t)
   205  	testCoreTemplate(t, config, fixtureDir("build-basic.json"))
   206  	TestBuilder(t, config, "test")
   207  	core := TestCore(t, config)
   208  
   209  	_, err := core.Build("nope")
   210  	if err == nil {
   211  		t.Fatal("should error")
   212  	}
   213  }
   214  
   215  func TestCoreBuild_prov(t *testing.T) {
   216  	config := TestCoreConfig(t)
   217  	testCoreTemplate(t, config, fixtureDir("build-prov.json"))
   218  	b := TestBuilder(t, config, "test")
   219  	p := TestProvisioner(t, config, "test")
   220  	core := TestCore(t, config)
   221  
   222  	b.ArtifactId = "hello"
   223  
   224  	build, err := core.Build("test")
   225  	if err != nil {
   226  		t.Fatalf("err: %s", err)
   227  	}
   228  
   229  	if _, err := build.Prepare(); err != nil {
   230  		t.Fatalf("err: %s", err)
   231  	}
   232  
   233  	artifact, err := build.Run(nil, nil)
   234  	if err != nil {
   235  		t.Fatalf("err: %s", err)
   236  	}
   237  	if len(artifact) != 1 {
   238  		t.Fatalf("bad: %#v", artifact)
   239  	}
   240  
   241  	if artifact[0].Id() != b.ArtifactId {
   242  		t.Fatalf("bad: %s", artifact[0].Id())
   243  	}
   244  	if !p.ProvCalled {
   245  		t.Fatal("provisioner not called")
   246  	}
   247  }
   248  
   249  func TestCoreBuild_provSkip(t *testing.T) {
   250  	config := TestCoreConfig(t)
   251  	testCoreTemplate(t, config, fixtureDir("build-prov-skip.json"))
   252  	b := TestBuilder(t, config, "test")
   253  	p := TestProvisioner(t, config, "test")
   254  	core := TestCore(t, config)
   255  
   256  	b.ArtifactId = "hello"
   257  
   258  	build, err := core.Build("test")
   259  	if err != nil {
   260  		t.Fatalf("err: %s", err)
   261  	}
   262  
   263  	if _, err := build.Prepare(); err != nil {
   264  		t.Fatalf("err: %s", err)
   265  	}
   266  
   267  	artifact, err := build.Run(nil, nil)
   268  	if err != nil {
   269  		t.Fatalf("err: %s", err)
   270  	}
   271  	if len(artifact) != 1 {
   272  		t.Fatalf("bad: %#v", artifact)
   273  	}
   274  
   275  	if artifact[0].Id() != b.ArtifactId {
   276  		t.Fatalf("bad: %s", artifact[0].Id())
   277  	}
   278  	if p.ProvCalled {
   279  		t.Fatal("provisioner should not be called")
   280  	}
   281  }
   282  
   283  func TestCoreBuild_provSkipInclude(t *testing.T) {
   284  	config := TestCoreConfig(t)
   285  	testCoreTemplate(t, config, fixtureDir("build-prov-skip-include.json"))
   286  	b := TestBuilder(t, config, "test")
   287  	p := TestProvisioner(t, config, "test")
   288  	core := TestCore(t, config)
   289  
   290  	b.ArtifactId = "hello"
   291  
   292  	build, err := core.Build("test")
   293  	if err != nil {
   294  		t.Fatalf("err: %s", err)
   295  	}
   296  
   297  	if _, err := build.Prepare(); err != nil {
   298  		t.Fatalf("err: %s", err)
   299  	}
   300  
   301  	artifact, err := build.Run(nil, nil)
   302  	if err != nil {
   303  		t.Fatalf("err: %s", err)
   304  	}
   305  	if len(artifact) != 1 {
   306  		t.Fatalf("bad: %#v", artifact)
   307  	}
   308  
   309  	if artifact[0].Id() != b.ArtifactId {
   310  		t.Fatalf("bad: %s", artifact[0].Id())
   311  	}
   312  	if !p.ProvCalled {
   313  		t.Fatal("provisioner should be called")
   314  	}
   315  }
   316  
   317  func TestCoreBuild_provOverride(t *testing.T) {
   318  	config := TestCoreConfig(t)
   319  	testCoreTemplate(t, config, fixtureDir("build-prov-override.json"))
   320  	b := TestBuilder(t, config, "test")
   321  	p := TestProvisioner(t, config, "test")
   322  	core := TestCore(t, config)
   323  
   324  	b.ArtifactId = "hello"
   325  
   326  	build, err := core.Build("test")
   327  	if err != nil {
   328  		t.Fatalf("err: %s", err)
   329  	}
   330  
   331  	if _, err := build.Prepare(); err != nil {
   332  		t.Fatalf("err: %s", err)
   333  	}
   334  
   335  	artifact, err := build.Run(nil, nil)
   336  	if err != nil {
   337  		t.Fatalf("err: %s", err)
   338  	}
   339  	if len(artifact) != 1 {
   340  		t.Fatalf("bad: %#v", artifact)
   341  	}
   342  
   343  	if artifact[0].Id() != b.ArtifactId {
   344  		t.Fatalf("bad: %s", artifact[0].Id())
   345  	}
   346  	if !p.ProvCalled {
   347  		t.Fatal("provisioner not called")
   348  	}
   349  
   350  	found := false
   351  	for _, raw := range p.PrepConfigs {
   352  		if m, ok := raw.(map[string]interface{}); ok {
   353  			if _, ok := m["foo"]; ok {
   354  				found = true
   355  				break
   356  			}
   357  		}
   358  	}
   359  	if !found {
   360  		t.Fatal("override not called")
   361  	}
   362  }
   363  
   364  func TestCoreBuild_postProcess(t *testing.T) {
   365  	config := TestCoreConfig(t)
   366  	testCoreTemplate(t, config, fixtureDir("build-pp.json"))
   367  	b := TestBuilder(t, config, "test")
   368  	p := TestPostProcessor(t, config, "test")
   369  	core := TestCore(t, config)
   370  	ui := TestUi(t)
   371  
   372  	b.ArtifactId = "hello"
   373  	p.ArtifactId = "goodbye"
   374  
   375  	build, err := core.Build("test")
   376  	if err != nil {
   377  		t.Fatalf("err: %s", err)
   378  	}
   379  
   380  	if _, err := build.Prepare(); err != nil {
   381  		t.Fatalf("err: %s", err)
   382  	}
   383  
   384  	artifact, err := build.Run(ui, nil)
   385  	if err != nil {
   386  		t.Fatalf("err: %s", err)
   387  	}
   388  	if len(artifact) != 1 {
   389  		t.Fatalf("bad: %#v", artifact)
   390  	}
   391  
   392  	if artifact[0].Id() != p.ArtifactId {
   393  		t.Fatalf("bad: %s", artifact[0].Id())
   394  	}
   395  	if p.PostProcessArtifact.Id() != b.ArtifactId {
   396  		t.Fatalf("bad: %s", p.PostProcessArtifact.Id())
   397  	}
   398  }
   399  
   400  func TestCoreBuild_templatePath(t *testing.T) {
   401  	config := TestCoreConfig(t)
   402  	testCoreTemplate(t, config, fixtureDir("build-template-path.json"))
   403  	b := TestBuilder(t, config, "test")
   404  	core := TestCore(t, config)
   405  
   406  	expected, _ := filepath.Abs("./test-fixtures")
   407  
   408  	build, err := core.Build("test")
   409  	if err != nil {
   410  		t.Fatalf("err: %s", err)
   411  	}
   412  
   413  	if _, err := build.Prepare(); err != nil {
   414  		t.Fatalf("err: %s", err)
   415  	}
   416  
   417  	// Interpolate the config
   418  	var result map[string]interface{}
   419  	err = configHelper.Decode(&result, nil, b.PrepareConfig...)
   420  	if err != nil {
   421  		t.Fatalf("err: %s", err)
   422  	}
   423  
   424  	if result["value"] != expected {
   425  		t.Fatalf("bad: %#v", result)
   426  	}
   427  }
   428  
   429  func TestCore_pushInterpolate(t *testing.T) {
   430  	cases := []struct {
   431  		File   string
   432  		Vars   map[string]string
   433  		Result template.Push
   434  	}{
   435  		{
   436  			"push-vars.json",
   437  			map[string]string{"foo": "bar"},
   438  			template.Push{Name: "bar"},
   439  		},
   440  	}
   441  
   442  	for _, tc := range cases {
   443  		tpl, err := template.ParseFile(fixtureDir(tc.File))
   444  		if err != nil {
   445  			t.Fatalf("err: %s\n\n%s", tc.File, err)
   446  		}
   447  
   448  		core, err := NewCore(&CoreConfig{
   449  			Template:  tpl,
   450  			Variables: tc.Vars,
   451  		})
   452  		if err != nil {
   453  			t.Fatalf("err: %s\n\n%s", tc.File, err)
   454  		}
   455  
   456  		expected := core.Template.Push
   457  		if !reflect.DeepEqual(expected, tc.Result) {
   458  			t.Fatalf("err: %s\n\n%#v", tc.File, expected)
   459  		}
   460  	}
   461  }
   462  
   463  func TestCoreValidate(t *testing.T) {
   464  	cases := []struct {
   465  		File string
   466  		Vars map[string]string
   467  		Err  bool
   468  	}{
   469  		{
   470  			"validate-dup-builder.json",
   471  			nil,
   472  			true,
   473  		},
   474  
   475  		// Required variable not set
   476  		{
   477  			"validate-req-variable.json",
   478  			nil,
   479  			true,
   480  		},
   481  
   482  		{
   483  			"validate-req-variable.json",
   484  			map[string]string{"foo": "bar"},
   485  			false,
   486  		},
   487  
   488  		// Min version good
   489  		{
   490  			"validate-min-version.json",
   491  			map[string]string{"foo": "bar"},
   492  			false,
   493  		},
   494  
   495  		{
   496  			"validate-min-version-high.json",
   497  			map[string]string{"foo": "bar"},
   498  			true,
   499  		},
   500  	}
   501  
   502  	for _, tc := range cases {
   503  		f, err := os.Open(fixtureDir(tc.File))
   504  		if err != nil {
   505  			t.Fatalf("err: %s", err)
   506  		}
   507  
   508  		tpl, err := template.Parse(f)
   509  		f.Close()
   510  		if err != nil {
   511  			t.Fatalf("err: %s\n\n%s", tc.File, err)
   512  		}
   513  
   514  		_, err = NewCore(&CoreConfig{
   515  			Template:  tpl,
   516  			Variables: tc.Vars,
   517  			Version:   "1.0.0",
   518  		})
   519  
   520  		if (err != nil) != tc.Err {
   521  			t.Fatalf("err: %s\n\n%s", tc.File, err)
   522  		}
   523  	}
   524  }
   525  
   526  func TestSensitiveVars(t *testing.T) {
   527  	cases := []struct {
   528  		File          string
   529  		Vars          map[string]string
   530  		SensitiveVars []string
   531  		Expected      string
   532  		Err           bool
   533  	}{
   534  		// hardcoded
   535  		{
   536  			"sensitive-variables.json",
   537  			map[string]string{"foo": "bar"},
   538  			[]string{"foo"},
   539  			"bar",
   540  			false,
   541  		},
   542  		// interpolated
   543  		{
   544  			"sensitive-variables.json",
   545  			map[string]string{"foo": "{{build_name}}"},
   546  			[]string{"foo"},
   547  			"test",
   548  			false,
   549  		},
   550  	}
   551  
   552  	for _, tc := range cases {
   553  		f, err := os.Open(fixtureDir(tc.File))
   554  		if err != nil {
   555  			t.Fatalf("err: %s", err)
   556  		}
   557  
   558  		tpl, err := template.Parse(f)
   559  		f.Close()
   560  		if err != nil {
   561  			t.Fatalf("err: %s\n\n%s", tc.File, err)
   562  		}
   563  
   564  		_, err = NewCore(&CoreConfig{
   565  			Template:  tpl,
   566  			Variables: tc.Vars,
   567  			Version:   "1.0.0",
   568  		})
   569  
   570  		if (err != nil) != tc.Err {
   571  			t.Fatalf("err: %s\n\n%s", tc.File, err)
   572  		}
   573  		filtered := LogSecretFilter.get()
   574  		if filtered[0] != tc.Expected && len(filtered) != 1 {
   575  			t.Fatalf("not filtering sensitive vars; filtered is %#v", filtered)
   576  		}
   577  	}
   578  }
   579  
   580  func testComponentFinder() *ComponentFinder {
   581  	builderFactory := func(n string) (Builder, error) { return new(MockBuilder), nil }
   582  	ppFactory := func(n string) (PostProcessor, error) { return new(MockPostProcessor), nil }
   583  	provFactory := func(n string) (Provisioner, error) { return new(MockProvisioner), nil }
   584  	return &ComponentFinder{
   585  		Builder:       builderFactory,
   586  		PostProcessor: ppFactory,
   587  		Provisioner:   provFactory,
   588  	}
   589  }
   590  
   591  func testCoreTemplate(t *testing.T, c *CoreConfig, p string) {
   592  	tpl, err := template.ParseFile(p)
   593  	if err != nil {
   594  		t.Fatalf("err: %s\n\n%s", p, err)
   595  	}
   596  
   597  	c.Template = tpl
   598  }