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