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