github.com/rothwerx/packer@v0.9.0/packer/build_test.go (about)

     1  package packer
     2  
     3  import (
     4  	"reflect"
     5  	"testing"
     6  )
     7  
     8  func testBuild() *coreBuild {
     9  	return &coreBuild{
    10  		name:          "test",
    11  		builder:       &MockBuilder{ArtifactId: "b"},
    12  		builderConfig: 42,
    13  		builderType:   "foo",
    14  		hooks: map[string][]Hook{
    15  			"foo": []Hook{&MockHook{}},
    16  		},
    17  		provisioners: []coreBuildProvisioner{
    18  			coreBuildProvisioner{&MockProvisioner{}, []interface{}{42}},
    19  		},
    20  		postProcessors: [][]coreBuildPostProcessor{
    21  			[]coreBuildPostProcessor{
    22  				coreBuildPostProcessor{&MockPostProcessor{ArtifactId: "pp"}, "testPP", make(map[string]interface{}), true},
    23  			},
    24  		},
    25  		variables: make(map[string]string),
    26  	}
    27  }
    28  
    29  func testDefaultPackerConfig() map[string]interface{} {
    30  	return map[string]interface{}{
    31  		BuildNameConfigKey:     "test",
    32  		BuilderTypeConfigKey:   "foo",
    33  		DebugConfigKey:         false,
    34  		ForceConfigKey:         false,
    35  		TemplatePathKey:        "",
    36  		UserVariablesConfigKey: make(map[string]string),
    37  	}
    38  }
    39  func TestBuild_Name(t *testing.T) {
    40  	build := testBuild()
    41  	if build.Name() != "test" {
    42  		t.Fatalf("bad: %s", build.Name())
    43  	}
    44  }
    45  
    46  func TestBuild_Prepare(t *testing.T) {
    47  	packerConfig := testDefaultPackerConfig()
    48  
    49  	build := testBuild()
    50  	builder := build.builder.(*MockBuilder)
    51  
    52  	build.Prepare()
    53  	if !builder.PrepareCalled {
    54  		t.Fatal("should be called")
    55  	}
    56  	if !reflect.DeepEqual(builder.PrepareConfig, []interface{}{42, packerConfig}) {
    57  		t.Fatalf("bad: %#v", builder.PrepareConfig)
    58  	}
    59  
    60  	coreProv := build.provisioners[0]
    61  	prov := coreProv.provisioner.(*MockProvisioner)
    62  	if !prov.PrepCalled {
    63  		t.Fatal("prep should be called")
    64  	}
    65  	if !reflect.DeepEqual(prov.PrepConfigs, []interface{}{42, packerConfig}) {
    66  		t.Fatalf("bad: %#v", prov.PrepConfigs)
    67  	}
    68  
    69  	corePP := build.postProcessors[0][0]
    70  	pp := corePP.processor.(*MockPostProcessor)
    71  	if !pp.ConfigureCalled {
    72  		t.Fatal("should be called")
    73  	}
    74  	if !reflect.DeepEqual(pp.ConfigureConfigs, []interface{}{make(map[string]interface{}), packerConfig}) {
    75  		t.Fatalf("bad: %#v", pp.ConfigureConfigs)
    76  	}
    77  }
    78  
    79  func TestBuild_Prepare_Twice(t *testing.T) {
    80  	build := testBuild()
    81  	warn, err := build.Prepare()
    82  	if len(warn) > 0 {
    83  		t.Fatalf("bad: %#v", warn)
    84  	}
    85  	if err != nil {
    86  		t.Fatalf("bad error: %s", err)
    87  	}
    88  
    89  	defer func() {
    90  		p := recover()
    91  		if p == nil {
    92  			t.Fatalf("should've paniced")
    93  		}
    94  
    95  		if p.(string) != "prepare already called" {
    96  			t.Fatalf("Invalid panic: %s", p)
    97  		}
    98  	}()
    99  
   100  	build.Prepare()
   101  }
   102  
   103  func TestBuildPrepare_BuilderWarniings(t *testing.T) {
   104  	expected := []string{"foo"}
   105  
   106  	build := testBuild()
   107  	builder := build.builder.(*MockBuilder)
   108  	builder.PrepareWarnings = expected
   109  
   110  	warn, err := build.Prepare()
   111  	if err != nil {
   112  		t.Fatalf("err: %s", err)
   113  	}
   114  	if !reflect.DeepEqual(warn, expected) {
   115  		t.Fatalf("bad: %#v", warn)
   116  	}
   117  }
   118  
   119  func TestBuild_Prepare_Debug(t *testing.T) {
   120  	packerConfig := testDefaultPackerConfig()
   121  	packerConfig[DebugConfigKey] = true
   122  
   123  	build := testBuild()
   124  	builder := build.builder.(*MockBuilder)
   125  
   126  	build.SetDebug(true)
   127  	build.Prepare()
   128  	if !builder.PrepareCalled {
   129  		t.Fatalf("should be called")
   130  	}
   131  	if !reflect.DeepEqual(builder.PrepareConfig, []interface{}{42, packerConfig}) {
   132  		t.Fatalf("bad: %#v", builder.PrepareConfig)
   133  	}
   134  
   135  	coreProv := build.provisioners[0]
   136  	prov := coreProv.provisioner.(*MockProvisioner)
   137  	if !prov.PrepCalled {
   138  		t.Fatal("prepare should be called")
   139  	}
   140  	if !reflect.DeepEqual(prov.PrepConfigs, []interface{}{42, packerConfig}) {
   141  		t.Fatalf("bad: %#v", prov.PrepConfigs)
   142  	}
   143  }
   144  
   145  func TestBuildPrepare_variables_default(t *testing.T) {
   146  	packerConfig := testDefaultPackerConfig()
   147  	packerConfig[UserVariablesConfigKey] = map[string]string{
   148  		"foo": "bar",
   149  	}
   150  
   151  	build := testBuild()
   152  	build.variables["foo"] = "bar"
   153  	builder := build.builder.(*MockBuilder)
   154  
   155  	warn, err := build.Prepare()
   156  	if len(warn) > 0 {
   157  		t.Fatalf("bad: %#v", warn)
   158  	}
   159  	if err != nil {
   160  		t.Fatalf("err: %s", err)
   161  	}
   162  
   163  	if !builder.PrepareCalled {
   164  		t.Fatal("prepare should be called")
   165  	}
   166  
   167  	if !reflect.DeepEqual(builder.PrepareConfig[1], packerConfig) {
   168  		t.Fatalf("prepare bad: %#v", builder.PrepareConfig[1])
   169  	}
   170  }
   171  
   172  func TestBuild_Run(t *testing.T) {
   173  	cache := &TestCache{}
   174  	ui := testUi()
   175  
   176  	build := testBuild()
   177  	build.Prepare()
   178  	artifacts, err := build.Run(ui, cache)
   179  	if err != nil {
   180  		t.Fatalf("err: %s", err)
   181  	}
   182  	if len(artifacts) != 2 {
   183  		t.Fatalf("bad: %#v", artifacts)
   184  	}
   185  
   186  	// Verify builder was run
   187  	builder := build.builder.(*MockBuilder)
   188  	if !builder.RunCalled {
   189  		t.Fatal("should be called")
   190  	}
   191  
   192  	// Verify hooks are disapatchable
   193  	dispatchHook := builder.RunHook
   194  	dispatchHook.Run("foo", nil, nil, 42)
   195  
   196  	hook := build.hooks["foo"][0].(*MockHook)
   197  	if !hook.RunCalled {
   198  		t.Fatal("should be called")
   199  	}
   200  	if hook.RunData != 42 {
   201  		t.Fatalf("bad: %#v", hook.RunData)
   202  	}
   203  
   204  	// Verify provisioners run
   205  	dispatchHook.Run(HookProvision, nil, new(MockCommunicator), 42)
   206  	prov := build.provisioners[0].provisioner.(*MockProvisioner)
   207  	if !prov.ProvCalled {
   208  		t.Fatal("should be called")
   209  	}
   210  
   211  	// Verify post-processor was run
   212  	pp := build.postProcessors[0][0].processor.(*MockPostProcessor)
   213  	if !pp.PostProcessCalled {
   214  		t.Fatal("should be called")
   215  	}
   216  }
   217  
   218  func TestBuild_Run_Artifacts(t *testing.T) {
   219  	cache := &TestCache{}
   220  	ui := testUi()
   221  
   222  	// Test case: Test that with no post-processors, we only get the
   223  	// main build.
   224  	build := testBuild()
   225  	build.postProcessors = [][]coreBuildPostProcessor{}
   226  
   227  	build.Prepare()
   228  	artifacts, err := build.Run(ui, cache)
   229  	if err != nil {
   230  		t.Fatalf("err: %s", err)
   231  	}
   232  
   233  	expectedIds := []string{"b"}
   234  	artifactIds := make([]string, len(artifacts))
   235  	for i, artifact := range artifacts {
   236  		artifactIds[i] = artifact.Id()
   237  	}
   238  
   239  	if !reflect.DeepEqual(artifactIds, expectedIds) {
   240  		t.Fatalf("unexpected ids: %#v", artifactIds)
   241  	}
   242  
   243  	// Test case: Test that with a single post-processor that doesn't keep
   244  	// inputs, only that post-processors results are returned.
   245  	build = testBuild()
   246  	build.postProcessors = [][]coreBuildPostProcessor{
   247  		[]coreBuildPostProcessor{
   248  			coreBuildPostProcessor{&MockPostProcessor{ArtifactId: "pp"}, "pp", make(map[string]interface{}), false},
   249  		},
   250  	}
   251  
   252  	build.Prepare()
   253  	artifacts, err = build.Run(ui, cache)
   254  	if err != nil {
   255  		t.Fatalf("err: %s", err)
   256  	}
   257  
   258  	expectedIds = []string{"pp"}
   259  	artifactIds = make([]string, len(artifacts))
   260  	for i, artifact := range artifacts {
   261  		artifactIds[i] = artifact.Id()
   262  	}
   263  
   264  	if !reflect.DeepEqual(artifactIds, expectedIds) {
   265  		t.Fatalf("unexpected ids: %#v", artifactIds)
   266  	}
   267  
   268  	// Test case: Test that with multiple post-processors, as long as one
   269  	// keeps the original, the original is kept.
   270  	build = testBuild()
   271  	build.postProcessors = [][]coreBuildPostProcessor{
   272  		[]coreBuildPostProcessor{
   273  			coreBuildPostProcessor{&MockPostProcessor{ArtifactId: "pp1"}, "pp", make(map[string]interface{}), false},
   274  		},
   275  		[]coreBuildPostProcessor{
   276  			coreBuildPostProcessor{&MockPostProcessor{ArtifactId: "pp2"}, "pp", make(map[string]interface{}), true},
   277  		},
   278  	}
   279  
   280  	build.Prepare()
   281  	artifacts, err = build.Run(ui, cache)
   282  	if err != nil {
   283  		t.Fatalf("err: %s", err)
   284  	}
   285  
   286  	expectedIds = []string{"b", "pp1", "pp2"}
   287  	artifactIds = make([]string, len(artifacts))
   288  	for i, artifact := range artifacts {
   289  		artifactIds[i] = artifact.Id()
   290  	}
   291  
   292  	if !reflect.DeepEqual(artifactIds, expectedIds) {
   293  		t.Fatalf("unexpected ids: %#v", artifactIds)
   294  	}
   295  
   296  	// Test case: Test that with sequences, intermediaries are kept if they
   297  	// want to be.
   298  	build = testBuild()
   299  	build.postProcessors = [][]coreBuildPostProcessor{
   300  		[]coreBuildPostProcessor{
   301  			coreBuildPostProcessor{&MockPostProcessor{ArtifactId: "pp1a"}, "pp", make(map[string]interface{}), false},
   302  			coreBuildPostProcessor{&MockPostProcessor{ArtifactId: "pp1b"}, "pp", make(map[string]interface{}), true},
   303  		},
   304  		[]coreBuildPostProcessor{
   305  			coreBuildPostProcessor{&MockPostProcessor{ArtifactId: "pp2a"}, "pp", make(map[string]interface{}), false},
   306  			coreBuildPostProcessor{&MockPostProcessor{ArtifactId: "pp2b"}, "pp", make(map[string]interface{}), false},
   307  		},
   308  	}
   309  
   310  	build.Prepare()
   311  	artifacts, err = build.Run(ui, cache)
   312  	if err != nil {
   313  		t.Fatalf("err: %s", err)
   314  	}
   315  
   316  	expectedIds = []string{"pp1a", "pp1b", "pp2b"}
   317  	artifactIds = make([]string, len(artifacts))
   318  	for i, artifact := range artifacts {
   319  		artifactIds[i] = artifact.Id()
   320  	}
   321  
   322  	if !reflect.DeepEqual(artifactIds, expectedIds) {
   323  		t.Fatalf("unexpected ids: %#v", artifactIds)
   324  	}
   325  
   326  	// Test case: Test that with a single post-processor that forcibly
   327  	// keeps inputs, that the artifacts are kept.
   328  	build = testBuild()
   329  	build.postProcessors = [][]coreBuildPostProcessor{
   330  		[]coreBuildPostProcessor{
   331  			coreBuildPostProcessor{
   332  				&MockPostProcessor{ArtifactId: "pp", Keep: true}, "pp", make(map[string]interface{}), false,
   333  			},
   334  		},
   335  	}
   336  
   337  	build.Prepare()
   338  	artifacts, err = build.Run(ui, cache)
   339  	if err != nil {
   340  		t.Fatalf("err: %s", err)
   341  	}
   342  
   343  	expectedIds = []string{"b", "pp"}
   344  	artifactIds = make([]string, len(artifacts))
   345  	for i, artifact := range artifacts {
   346  		artifactIds[i] = artifact.Id()
   347  	}
   348  
   349  	if !reflect.DeepEqual(artifactIds, expectedIds) {
   350  		t.Fatalf("unexpected ids: %#v", artifactIds)
   351  	}
   352  }
   353  
   354  func TestBuild_RunBeforePrepare(t *testing.T) {
   355  	defer func() {
   356  		p := recover()
   357  		if p == nil {
   358  			t.Fatal("should panic")
   359  		}
   360  
   361  		if p.(string) != "Prepare must be called first" {
   362  			t.Fatalf("bad: %s", p.(string))
   363  		}
   364  	}()
   365  
   366  	testBuild().Run(testUi(), &TestCache{})
   367  }
   368  
   369  func TestBuild_Cancel(t *testing.T) {
   370  	build := testBuild()
   371  	build.Cancel()
   372  
   373  	builder := build.builder.(*MockBuilder)
   374  	if !builder.CancelCalled {
   375  		t.Fatal("cancel should be called")
   376  	}
   377  }