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 }