github.com/HashDataInc/packer@v1.3.2/packer/core_test.go (about) 1 package packer 2 3 import ( 4 "os" 5 "path/filepath" 6 "reflect" 7 "testing" 8 9 configHelper "github.com/hashicorp/packer/helper/config" 10 "github.com/hashicorp/packer/template" 11 ) 12 13 func TestCoreBuildNames(t *testing.T) { 14 cases := []struct { 15 File string 16 Vars map[string]string 17 Result []string 18 }{ 19 { 20 "build-names-basic.json", 21 nil, 22 []string{"something"}, 23 }, 24 25 { 26 "build-names-func.json", 27 nil, 28 []string{"TUBES"}, 29 }, 30 } 31 32 for _, tc := range cases { 33 tpl, err := template.ParseFile(fixtureDir(tc.File)) 34 if err != nil { 35 t.Fatalf("err: %s\n\n%s", tc.File, err) 36 } 37 38 core, err := NewCore(&CoreConfig{ 39 Template: tpl, 40 Variables: tc.Vars, 41 }) 42 if err != nil { 43 t.Fatalf("err: %s\n\n%s", tc.File, err) 44 } 45 46 names := core.BuildNames() 47 if !reflect.DeepEqual(names, tc.Result) { 48 t.Fatalf("err: %s\n\n%#v", tc.File, names) 49 } 50 } 51 } 52 53 func TestCoreBuild_basic(t *testing.T) { 54 config := TestCoreConfig(t) 55 testCoreTemplate(t, config, fixtureDir("build-basic.json")) 56 b := TestBuilder(t, config, "test") 57 core := TestCore(t, config) 58 59 b.ArtifactId = "hello" 60 61 build, err := core.Build("test") 62 if err != nil { 63 t.Fatalf("err: %s", err) 64 } 65 66 if _, err := build.Prepare(); err != nil { 67 t.Fatalf("err: %s", err) 68 } 69 70 artifact, err := build.Run(nil, nil) 71 if err != nil { 72 t.Fatalf("err: %s", err) 73 } 74 if len(artifact) != 1 { 75 t.Fatalf("bad: %#v", artifact) 76 } 77 78 if artifact[0].Id() != b.ArtifactId { 79 t.Fatalf("bad: %s", artifact[0].Id()) 80 } 81 } 82 83 func TestCoreBuild_basicInterpolated(t *testing.T) { 84 config := TestCoreConfig(t) 85 testCoreTemplate(t, config, fixtureDir("build-basic-interpolated.json")) 86 b := TestBuilder(t, config, "test") 87 core := TestCore(t, config) 88 89 b.ArtifactId = "hello" 90 91 build, err := core.Build("NAME") 92 if err != nil { 93 t.Fatalf("err: %s", err) 94 } 95 96 if _, err := build.Prepare(); err != nil { 97 t.Fatalf("err: %s", err) 98 } 99 100 artifact, err := build.Run(nil, nil) 101 if err != nil { 102 t.Fatalf("err: %s", err) 103 } 104 if len(artifact) != 1 { 105 t.Fatalf("bad: %#v", artifact) 106 } 107 108 if artifact[0].Id() != b.ArtifactId { 109 t.Fatalf("bad: %s", artifact[0].Id()) 110 } 111 } 112 113 func TestCoreBuild_env(t *testing.T) { 114 os.Setenv("PACKER_TEST_ENV", "test") 115 defer os.Setenv("PACKER_TEST_ENV", "") 116 117 config := TestCoreConfig(t) 118 testCoreTemplate(t, config, fixtureDir("build-env.json")) 119 b := TestBuilder(t, config, "test") 120 core := TestCore(t, config) 121 122 b.ArtifactId = "hello" 123 124 build, err := core.Build("test") 125 if err != nil { 126 t.Fatalf("err: %s", err) 127 } 128 129 if _, err := build.Prepare(); err != nil { 130 t.Fatalf("err: %s", err) 131 } 132 133 // Interpolate the config 134 var result map[string]interface{} 135 err = configHelper.Decode(&result, nil, b.PrepareConfig...) 136 if err != nil { 137 t.Fatalf("err: %s", err) 138 } 139 140 if result["value"] != "test" { 141 t.Fatalf("bad: %#v", result) 142 } 143 } 144 145 func TestCoreBuild_buildNameVar(t *testing.T) { 146 config := TestCoreConfig(t) 147 testCoreTemplate(t, config, fixtureDir("build-var-build-name.json")) 148 b := TestBuilder(t, config, "test") 149 core := TestCore(t, config) 150 151 b.ArtifactId = "hello" 152 153 build, err := core.Build("test") 154 if err != nil { 155 t.Fatalf("err: %s", err) 156 } 157 158 if _, err := build.Prepare(); err != nil { 159 t.Fatalf("err: %s", err) 160 } 161 162 // Interpolate the config 163 var result map[string]interface{} 164 err = configHelper.Decode(&result, nil, b.PrepareConfig...) 165 if err != nil { 166 t.Fatalf("err: %s", err) 167 } 168 169 if result["value"] != "test" { 170 t.Fatalf("bad: %#v", result) 171 } 172 } 173 174 func TestCoreBuild_buildTypeVar(t *testing.T) { 175 config := TestCoreConfig(t) 176 testCoreTemplate(t, config, fixtureDir("build-var-build-type.json")) 177 b := TestBuilder(t, config, "test") 178 core := TestCore(t, config) 179 180 b.ArtifactId = "hello" 181 182 build, err := core.Build("test") 183 if err != nil { 184 t.Fatalf("err: %s", err) 185 } 186 187 if _, err := build.Prepare(); err != nil { 188 t.Fatalf("err: %s", err) 189 } 190 191 // Interpolate the config 192 var result map[string]interface{} 193 err = configHelper.Decode(&result, nil, b.PrepareConfig...) 194 if err != nil { 195 t.Fatalf("err: %s", err) 196 } 197 198 if result["value"] != "test" { 199 t.Fatalf("bad: %#v", result) 200 } 201 } 202 203 func TestCoreBuild_nonExist(t *testing.T) { 204 config := TestCoreConfig(t) 205 testCoreTemplate(t, config, fixtureDir("build-basic.json")) 206 TestBuilder(t, config, "test") 207 core := TestCore(t, config) 208 209 _, err := core.Build("nope") 210 if err == nil { 211 t.Fatal("should error") 212 } 213 } 214 215 func TestCoreBuild_prov(t *testing.T) { 216 config := TestCoreConfig(t) 217 testCoreTemplate(t, config, fixtureDir("build-prov.json")) 218 b := TestBuilder(t, config, "test") 219 p := TestProvisioner(t, config, "test") 220 core := TestCore(t, config) 221 222 b.ArtifactId = "hello" 223 224 build, err := core.Build("test") 225 if err != nil { 226 t.Fatalf("err: %s", err) 227 } 228 229 if _, err := build.Prepare(); err != nil { 230 t.Fatalf("err: %s", err) 231 } 232 233 artifact, err := build.Run(nil, nil) 234 if err != nil { 235 t.Fatalf("err: %s", err) 236 } 237 if len(artifact) != 1 { 238 t.Fatalf("bad: %#v", artifact) 239 } 240 241 if artifact[0].Id() != b.ArtifactId { 242 t.Fatalf("bad: %s", artifact[0].Id()) 243 } 244 if !p.ProvCalled { 245 t.Fatal("provisioner not called") 246 } 247 } 248 249 func TestCoreBuild_provSkip(t *testing.T) { 250 config := TestCoreConfig(t) 251 testCoreTemplate(t, config, fixtureDir("build-prov-skip.json")) 252 b := TestBuilder(t, config, "test") 253 p := TestProvisioner(t, config, "test") 254 core := TestCore(t, config) 255 256 b.ArtifactId = "hello" 257 258 build, err := core.Build("test") 259 if err != nil { 260 t.Fatalf("err: %s", err) 261 } 262 263 if _, err := build.Prepare(); err != nil { 264 t.Fatalf("err: %s", err) 265 } 266 267 artifact, err := build.Run(nil, nil) 268 if err != nil { 269 t.Fatalf("err: %s", err) 270 } 271 if len(artifact) != 1 { 272 t.Fatalf("bad: %#v", artifact) 273 } 274 275 if artifact[0].Id() != b.ArtifactId { 276 t.Fatalf("bad: %s", artifact[0].Id()) 277 } 278 if p.ProvCalled { 279 t.Fatal("provisioner should not be called") 280 } 281 } 282 283 func TestCoreBuild_provSkipInclude(t *testing.T) { 284 config := TestCoreConfig(t) 285 testCoreTemplate(t, config, fixtureDir("build-prov-skip-include.json")) 286 b := TestBuilder(t, config, "test") 287 p := TestProvisioner(t, config, "test") 288 core := TestCore(t, config) 289 290 b.ArtifactId = "hello" 291 292 build, err := core.Build("test") 293 if err != nil { 294 t.Fatalf("err: %s", err) 295 } 296 297 if _, err := build.Prepare(); err != nil { 298 t.Fatalf("err: %s", err) 299 } 300 301 artifact, err := build.Run(nil, nil) 302 if err != nil { 303 t.Fatalf("err: %s", err) 304 } 305 if len(artifact) != 1 { 306 t.Fatalf("bad: %#v", artifact) 307 } 308 309 if artifact[0].Id() != b.ArtifactId { 310 t.Fatalf("bad: %s", artifact[0].Id()) 311 } 312 if !p.ProvCalled { 313 t.Fatal("provisioner should be called") 314 } 315 } 316 317 func TestCoreBuild_provOverride(t *testing.T) { 318 config := TestCoreConfig(t) 319 testCoreTemplate(t, config, fixtureDir("build-prov-override.json")) 320 b := TestBuilder(t, config, "test") 321 p := TestProvisioner(t, config, "test") 322 core := TestCore(t, config) 323 324 b.ArtifactId = "hello" 325 326 build, err := core.Build("test") 327 if err != nil { 328 t.Fatalf("err: %s", err) 329 } 330 331 if _, err := build.Prepare(); err != nil { 332 t.Fatalf("err: %s", err) 333 } 334 335 artifact, err := build.Run(nil, nil) 336 if err != nil { 337 t.Fatalf("err: %s", err) 338 } 339 if len(artifact) != 1 { 340 t.Fatalf("bad: %#v", artifact) 341 } 342 343 if artifact[0].Id() != b.ArtifactId { 344 t.Fatalf("bad: %s", artifact[0].Id()) 345 } 346 if !p.ProvCalled { 347 t.Fatal("provisioner not called") 348 } 349 350 found := false 351 for _, raw := range p.PrepConfigs { 352 if m, ok := raw.(map[string]interface{}); ok { 353 if _, ok := m["foo"]; ok { 354 found = true 355 break 356 } 357 } 358 } 359 if !found { 360 t.Fatal("override not called") 361 } 362 } 363 364 func TestCoreBuild_postProcess(t *testing.T) { 365 config := TestCoreConfig(t) 366 testCoreTemplate(t, config, fixtureDir("build-pp.json")) 367 b := TestBuilder(t, config, "test") 368 p := TestPostProcessor(t, config, "test") 369 core := TestCore(t, config) 370 ui := TestUi(t) 371 372 b.ArtifactId = "hello" 373 p.ArtifactId = "goodbye" 374 375 build, err := core.Build("test") 376 if err != nil { 377 t.Fatalf("err: %s", err) 378 } 379 380 if _, err := build.Prepare(); err != nil { 381 t.Fatalf("err: %s", err) 382 } 383 384 artifact, err := build.Run(ui, nil) 385 if err != nil { 386 t.Fatalf("err: %s", err) 387 } 388 if len(artifact) != 1 { 389 t.Fatalf("bad: %#v", artifact) 390 } 391 392 if artifact[0].Id() != p.ArtifactId { 393 t.Fatalf("bad: %s", artifact[0].Id()) 394 } 395 if p.PostProcessArtifact.Id() != b.ArtifactId { 396 t.Fatalf("bad: %s", p.PostProcessArtifact.Id()) 397 } 398 } 399 400 func TestCoreBuild_templatePath(t *testing.T) { 401 config := TestCoreConfig(t) 402 testCoreTemplate(t, config, fixtureDir("build-template-path.json")) 403 b := TestBuilder(t, config, "test") 404 core := TestCore(t, config) 405 406 expected, _ := filepath.Abs("./test-fixtures") 407 408 build, err := core.Build("test") 409 if err != nil { 410 t.Fatalf("err: %s", err) 411 } 412 413 if _, err := build.Prepare(); err != nil { 414 t.Fatalf("err: %s", err) 415 } 416 417 // Interpolate the config 418 var result map[string]interface{} 419 err = configHelper.Decode(&result, nil, b.PrepareConfig...) 420 if err != nil { 421 t.Fatalf("err: %s", err) 422 } 423 424 if result["value"] != expected { 425 t.Fatalf("bad: %#v", result) 426 } 427 } 428 429 func TestCore_pushInterpolate(t *testing.T) { 430 cases := []struct { 431 File string 432 Vars map[string]string 433 Result template.Push 434 }{ 435 { 436 "push-vars.json", 437 map[string]string{"foo": "bar"}, 438 template.Push{Name: "bar"}, 439 }, 440 } 441 442 for _, tc := range cases { 443 tpl, err := template.ParseFile(fixtureDir(tc.File)) 444 if err != nil { 445 t.Fatalf("err: %s\n\n%s", tc.File, err) 446 } 447 448 core, err := NewCore(&CoreConfig{ 449 Template: tpl, 450 Variables: tc.Vars, 451 }) 452 if err != nil { 453 t.Fatalf("err: %s\n\n%s", tc.File, err) 454 } 455 456 expected := core.Template.Push 457 if !reflect.DeepEqual(expected, tc.Result) { 458 t.Fatalf("err: %s\n\n%#v", tc.File, expected) 459 } 460 } 461 } 462 463 func TestCoreValidate(t *testing.T) { 464 cases := []struct { 465 File string 466 Vars map[string]string 467 Err bool 468 }{ 469 { 470 "validate-dup-builder.json", 471 nil, 472 true, 473 }, 474 475 // Required variable not set 476 { 477 "validate-req-variable.json", 478 nil, 479 true, 480 }, 481 482 { 483 "validate-req-variable.json", 484 map[string]string{"foo": "bar"}, 485 false, 486 }, 487 488 // Min version good 489 { 490 "validate-min-version.json", 491 map[string]string{"foo": "bar"}, 492 false, 493 }, 494 495 { 496 "validate-min-version-high.json", 497 map[string]string{"foo": "bar"}, 498 true, 499 }, 500 } 501 502 for _, tc := range cases { 503 f, err := os.Open(fixtureDir(tc.File)) 504 if err != nil { 505 t.Fatalf("err: %s", err) 506 } 507 508 tpl, err := template.Parse(f) 509 f.Close() 510 if err != nil { 511 t.Fatalf("err: %s\n\n%s", tc.File, err) 512 } 513 514 _, err = NewCore(&CoreConfig{ 515 Template: tpl, 516 Variables: tc.Vars, 517 Version: "1.0.0", 518 }) 519 520 if (err != nil) != tc.Err { 521 t.Fatalf("err: %s\n\n%s", tc.File, err) 522 } 523 } 524 } 525 526 func TestSensitiveVars(t *testing.T) { 527 cases := []struct { 528 File string 529 Vars map[string]string 530 SensitiveVars []string 531 Expected string 532 Err bool 533 }{ 534 // hardcoded 535 { 536 "sensitive-variables.json", 537 map[string]string{"foo": "bar"}, 538 []string{"foo"}, 539 "bar", 540 false, 541 }, 542 // interpolated 543 { 544 "sensitive-variables.json", 545 map[string]string{"foo": "{{build_name}}"}, 546 []string{"foo"}, 547 "test", 548 false, 549 }, 550 } 551 552 for _, tc := range cases { 553 f, err := os.Open(fixtureDir(tc.File)) 554 if err != nil { 555 t.Fatalf("err: %s", err) 556 } 557 558 tpl, err := template.Parse(f) 559 f.Close() 560 if err != nil { 561 t.Fatalf("err: %s\n\n%s", tc.File, err) 562 } 563 564 _, err = NewCore(&CoreConfig{ 565 Template: tpl, 566 Variables: tc.Vars, 567 Version: "1.0.0", 568 }) 569 570 if (err != nil) != tc.Err { 571 t.Fatalf("err: %s\n\n%s", tc.File, err) 572 } 573 filtered := LogSecretFilter.get() 574 if filtered[0] != tc.Expected && len(filtered) != 1 { 575 t.Fatalf("not filtering sensitive vars; filtered is %#v", filtered) 576 } 577 } 578 } 579 580 func testComponentFinder() *ComponentFinder { 581 builderFactory := func(n string) (Builder, error) { return new(MockBuilder), nil } 582 ppFactory := func(n string) (PostProcessor, error) { return new(MockPostProcessor), nil } 583 provFactory := func(n string) (Provisioner, error) { return new(MockProvisioner), nil } 584 return &ComponentFinder{ 585 Builder: builderFactory, 586 PostProcessor: ppFactory, 587 Provisioner: provFactory, 588 } 589 } 590 591 func testCoreTemplate(t *testing.T, c *CoreConfig, p string) { 592 tpl, err := template.ParseFile(p) 593 if err != nil { 594 t.Fatalf("err: %s\n\n%s", p, err) 595 } 596 597 c.Template = tpl 598 }