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 }