Files
Packer-Cn/packer/build_test.go
T

492 lines
12 KiB
Go
Raw Normal View History

2013-04-20 19:55:02 -06:00
package packer
import (
"context"
"reflect"
2013-04-20 19:55:02 -06:00
"testing"
2019-12-17 13:41:48 -08:00
"github.com/hashicorp/packer/helper/common"
2013-04-20 19:55:02 -06:00
)
2019-04-03 11:32:49 -07:00
func boolPointer(tf bool) *bool {
return &tf
}
2019-12-17 11:25:56 +01:00
func testBuild() *CoreBuild {
return &CoreBuild{
Type: "test",
Builder: &MockBuilder{ArtifactId: "b"},
BuilderConfig: 42,
BuilderType: "foo",
hooks: map[string][]Hook{
2016-11-01 14:08:04 -07:00
"foo": {&MockHook{}},
},
2019-12-17 11:25:56 +01:00
Provisioners: []CoreBuildProvisioner{
{
PType: "mock-provisioner",
Provisioner: &MockProvisioner{},
config: []interface{}{42}},
},
2019-12-17 11:25:56 +01:00
PostProcessors: [][]CoreBuildPostProcessor{
2016-11-01 14:08:04 -07:00
{
2020-01-15 15:36:52 -08:00
{&MockPostProcessor{ArtifactId: "pp"}, "testPP", "testPPName", make(map[string]interface{}), boolPointer(true)},
2013-06-18 10:31:52 -07:00
},
},
2019-12-17 11:25:56 +01:00
Variables: make(map[string]string),
onError: "cleanup",
2013-04-20 19:55:02 -06:00
}
}
func testDefaultPackerConfig() map[string]interface{} {
return map[string]interface{}{
BuildNameConfigKey: "test",
BuilderTypeConfigKey: "foo",
DebugConfigKey: false,
ForceConfigKey: false,
OnErrorConfigKey: "cleanup",
2015-05-29 14:34:45 -07:00
TemplatePathKey: "",
UserVariablesConfigKey: make(map[string]string),
}
}
2013-05-09 11:32:03 -07:00
func TestBuild_Name(t *testing.T) {
build := testBuild()
2013-10-16 21:09:27 -10:00
if build.Name() != "test" {
t.Fatalf("bad: %s", build.Name())
}
2013-05-09 11:32:03 -07:00
}
2013-04-20 19:55:02 -06:00
func TestBuild_Prepare(t *testing.T) {
packerConfig := testDefaultPackerConfig()
2013-04-20 19:55:02 -06:00
build := testBuild()
2019-12-17 11:25:56 +01:00
builder := build.Builder.(*MockBuilder)
2013-12-27 09:17:51 -07:00
build.Prepare()
2013-11-02 22:31:12 -05:00
if !builder.PrepareCalled {
2013-10-16 21:09:27 -10:00
t.Fatal("should be called")
}
2013-11-02 22:31:12 -05:00
if !reflect.DeepEqual(builder.PrepareConfig, []interface{}{42, packerConfig}) {
t.Fatalf("bad: %#v", builder.PrepareConfig)
2013-10-16 21:09:27 -10:00
}
2019-12-17 11:25:56 +01:00
coreProv := build.Provisioners[0]
prov := coreProv.Provisioner.(*MockProvisioner)
2013-10-16 21:09:27 -10:00
if !prov.PrepCalled {
t.Fatal("prep should be called")
}
if !reflect.DeepEqual(prov.PrepConfigs, []interface{}{42, packerConfig, BasicPlaceholderData()}) {
2013-10-16 21:09:27 -10:00
t.Fatalf("bad: %#v", prov.PrepConfigs)
}
2013-06-18 10:31:52 -07:00
2019-12-17 11:25:56 +01:00
corePP := build.PostProcessors[0][0]
pp := corePP.PostProcessor.(*MockPostProcessor)
2015-05-26 09:28:59 -07:00
if !pp.ConfigureCalled {
2013-10-16 21:09:27 -10:00
t.Fatal("should be called")
}
if !reflect.DeepEqual(pp.ConfigureConfigs, []interface{}{make(map[string]interface{}), packerConfig, BasicPlaceholderData()}) {
2015-05-26 09:28:59 -07:00
t.Fatalf("bad: %#v", pp.ConfigureConfigs)
2013-10-16 21:09:27 -10:00
}
}
func TestBuild_Prepare_SkipWhenBuilderAlreadyInitialized(t *testing.T) {
build := testBuild()
builder := build.Builder.(*MockBuilder)
build.Prepared = true
build.Prepare()
if builder.PrepareCalled {
t.Fatal("should not be called")
}
}
func TestBuild_Prepare_Twice(t *testing.T) {
build := testBuild()
2013-12-27 09:17:51 -07:00
warn, err := build.Prepare()
2013-11-02 22:31:12 -05:00
if len(warn) > 0 {
t.Fatalf("bad: %#v", warn)
}
if err != nil {
t.Fatalf("bad error: %s", err)
}
defer func() {
p := recover()
if p == nil {
t.Fatalf("should've paniced")
}
if p.(string) != "prepare already called" {
t.Fatalf("Invalid panic: %s", p)
}
}()
2013-12-27 09:17:51 -07:00
build.Prepare()
}
2018-03-14 03:29:50 +00:00
func TestBuildPrepare_BuilderWarnings(t *testing.T) {
2013-11-02 22:31:12 -05:00
expected := []string{"foo"}
build := testBuild()
2019-12-17 11:25:56 +01:00
builder := build.Builder.(*MockBuilder)
2013-11-02 22:31:12 -05:00
builder.PrepareWarnings = expected
2013-12-27 09:17:51 -07:00
warn, err := build.Prepare()
2013-11-02 22:31:12 -05:00
if err != nil {
t.Fatalf("err: %s", err)
}
if !reflect.DeepEqual(warn, expected) {
t.Fatalf("bad: %#v", warn)
}
}
func TestBuild_Prepare_Debug(t *testing.T) {
packerConfig := testDefaultPackerConfig()
packerConfig[DebugConfigKey] = true
build := testBuild()
2019-12-17 11:25:56 +01:00
builder := build.Builder.(*MockBuilder)
build.SetDebug(true)
2013-12-27 09:17:51 -07:00
build.Prepare()
2013-11-02 22:31:12 -05:00
if !builder.PrepareCalled {
2013-10-16 21:09:27 -10:00
t.Fatalf("should be called")
}
2013-11-02 22:31:12 -05:00
if !reflect.DeepEqual(builder.PrepareConfig, []interface{}{42, packerConfig}) {
t.Fatalf("bad: %#v", builder.PrepareConfig)
2013-10-16 21:09:27 -10:00
}
2019-12-17 11:25:56 +01:00
coreProv := build.Provisioners[0]
prov := coreProv.Provisioner.(*MockProvisioner)
2013-10-16 21:09:27 -10:00
if !prov.PrepCalled {
t.Fatal("prepare should be called")
}
if !reflect.DeepEqual(prov.PrepConfigs, []interface{}{42, packerConfig, BasicPlaceholderData()}) {
2013-10-16 21:09:27 -10:00
t.Fatalf("bad: %#v", prov.PrepConfigs)
}
2013-04-20 19:55:02 -06:00
}
func TestBuildPrepare_variables_default(t *testing.T) {
packerConfig := testDefaultPackerConfig()
packerConfig[UserVariablesConfigKey] = map[string]string{
"foo": "bar",
}
build := testBuild()
2019-12-17 11:25:56 +01:00
build.Variables["foo"] = "bar"
builder := build.Builder.(*MockBuilder)
2013-12-27 09:17:51 -07:00
warn, err := build.Prepare()
2013-11-02 22:31:12 -05:00
if len(warn) > 0 {
t.Fatalf("bad: %#v", warn)
}
if err != nil {
t.Fatalf("err: %s", err)
}
2013-11-02 22:31:12 -05:00
if !builder.PrepareCalled {
t.Fatal("prepare should be called")
}
2013-11-02 22:31:12 -05:00
if !reflect.DeepEqual(builder.PrepareConfig[1], packerConfig) {
t.Fatalf("prepare bad: %#v", builder.PrepareConfig[1])
}
}
2019-12-17 13:41:48 -08:00
func TestBuildPrepare_ProvisionerGetsGeneratedMap(t *testing.T) {
packerConfig := testDefaultPackerConfig()
build := testBuild()
builder := build.Builder.(*MockBuilder)
builder.GeneratedVars = []string{"PartyVar"}
build.Prepare()
if !builder.PrepareCalled {
t.Fatalf("should be called")
}
if !reflect.DeepEqual(builder.PrepareConfig, []interface{}{42, packerConfig}) {
t.Fatalf("bad: %#v", builder.PrepareConfig)
}
coreProv := build.Provisioners[0]
prov := coreProv.Provisioner.(*MockProvisioner)
if !prov.PrepCalled {
t.Fatal("prepare should be called")
}
generated := BasicPlaceholderData()
generated["PartyVar"] = "Build_PartyVar. " + common.PlaceholderMsg
if !reflect.DeepEqual(prov.PrepConfigs, []interface{}{42, packerConfig, generated}) {
t.Fatalf("bad: %#v", prov.PrepConfigs)
}
}
2013-04-20 19:55:02 -06:00
func TestBuild_Run(t *testing.T) {
ui := testUi()
build := testBuild()
2013-12-27 09:17:51 -07:00
build.Prepare()
ctx := context.Background()
artifacts, err := build.Run(ctx, ui)
2013-10-16 21:09:27 -10:00
if err != nil {
t.Fatalf("err: %s", err)
}
if len(artifacts) != 2 {
t.Fatalf("bad: %#v", artifacts)
}
2013-04-20 19:55:02 -06:00
// Verify builder was run
2019-12-17 11:25:56 +01:00
builder := build.Builder.(*MockBuilder)
2013-11-02 22:31:12 -05:00
if !builder.RunCalled {
2013-10-16 21:09:27 -10:00
t.Fatal("should be called")
}
2018-03-13 07:38:01 +00:00
// Verify hooks are dispatchable
2013-11-02 22:31:12 -05:00
dispatchHook := builder.RunHook
dispatchHook.Run(ctx, "foo", nil, nil, 42)
2013-08-30 17:03:55 -07:00
hook := build.hooks["foo"][0].(*MockHook)
2013-10-16 21:09:27 -10:00
if !hook.RunCalled {
t.Fatal("should be called")
}
if hook.RunData != 42 {
t.Fatalf("bad: %#v", hook.RunData)
}
// Verify provisioners run
dispatchHook.Run(ctx, HookProvision, nil, new(MockCommunicator), 42)
2019-12-17 11:25:56 +01:00
prov := build.Provisioners[0].Provisioner.(*MockProvisioner)
2013-10-16 21:09:27 -10:00
if !prov.ProvCalled {
t.Fatal("should be called")
}
2013-06-18 10:54:22 -07:00
// Verify post-processor was run
2019-12-17 11:25:56 +01:00
pp := build.PostProcessors[0][0].PostProcessor.(*MockPostProcessor)
2015-05-26 09:28:59 -07:00
if !pp.PostProcessCalled {
2013-10-16 21:09:27 -10:00
t.Fatal("should be called")
}
2013-04-20 19:55:02 -06:00
}
2013-04-20 20:03:53 -06:00
func TestBuild_Run_Artifacts(t *testing.T) {
ui := testUi()
// Test case: Test that with no post-processors, we only get the
// main build.
build := testBuild()
2019-12-17 11:25:56 +01:00
build.PostProcessors = [][]CoreBuildPostProcessor{}
2013-12-27 09:17:51 -07:00
build.Prepare()
artifacts, err := build.Run(context.Background(), ui)
if err != nil {
t.Fatalf("err: %s", err)
}
expectedIds := []string{"b"}
artifactIds := make([]string, len(artifacts))
for i, artifact := range artifacts {
artifactIds[i] = artifact.Id()
}
if !reflect.DeepEqual(artifactIds, expectedIds) {
t.Fatalf("unexpected ids: %#v", artifactIds)
}
// Test case: Test that with a single post-processor that doesn't keep
// inputs, only that post-processors results are returned.
build = testBuild()
2019-12-17 11:25:56 +01:00
build.PostProcessors = [][]CoreBuildPostProcessor{
2016-11-01 14:08:04 -07:00
{
2020-01-15 15:36:52 -08:00
{&MockPostProcessor{ArtifactId: "pp"}, "pp", "testPPName", make(map[string]interface{}), boolPointer(false)},
},
}
2013-12-27 09:17:51 -07:00
build.Prepare()
artifacts, err = build.Run(context.Background(), ui)
if err != nil {
t.Fatalf("err: %s", err)
}
expectedIds = []string{"pp"}
artifactIds = make([]string, len(artifacts))
for i, artifact := range artifacts {
artifactIds[i] = artifact.Id()
}
if !reflect.DeepEqual(artifactIds, expectedIds) {
t.Fatalf("unexpected ids: %#v", artifactIds)
}
// Test case: Test that with multiple post-processors, as long as one
// keeps the original, the original is kept.
build = testBuild()
2019-12-17 11:25:56 +01:00
build.PostProcessors = [][]CoreBuildPostProcessor{
2016-11-01 14:08:04 -07:00
{
2020-01-15 15:36:52 -08:00
{&MockPostProcessor{ArtifactId: "pp1"}, "pp", "testPPName", make(map[string]interface{}), boolPointer(false)},
},
2016-11-01 14:08:04 -07:00
{
2020-01-15 15:36:52 -08:00
{&MockPostProcessor{ArtifactId: "pp2"}, "pp", "testPPName", make(map[string]interface{}), boolPointer(true)},
},
}
2013-12-27 09:17:51 -07:00
build.Prepare()
artifacts, err = build.Run(context.Background(), ui)
if err != nil {
t.Fatalf("err: %s", err)
}
expectedIds = []string{"b", "pp1", "pp2"}
artifactIds = make([]string, len(artifacts))
for i, artifact := range artifacts {
artifactIds[i] = artifact.Id()
}
if !reflect.DeepEqual(artifactIds, expectedIds) {
t.Fatalf("unexpected ids: %#v", artifactIds)
}
// Test case: Test that with sequences, intermediaries are kept if they
// want to be.
build = testBuild()
2019-12-17 11:25:56 +01:00
build.PostProcessors = [][]CoreBuildPostProcessor{
2016-11-01 14:08:04 -07:00
{
2020-01-15 15:36:52 -08:00
{&MockPostProcessor{ArtifactId: "pp1a"}, "pp", "testPPName", make(map[string]interface{}), boolPointer(false)},
{&MockPostProcessor{ArtifactId: "pp1b"}, "pp", "testPPName", make(map[string]interface{}), boolPointer(true)},
},
2016-11-01 14:08:04 -07:00
{
2020-01-15 15:36:52 -08:00
{&MockPostProcessor{ArtifactId: "pp2a"}, "pp", "testPPName", make(map[string]interface{}), boolPointer(false)},
{&MockPostProcessor{ArtifactId: "pp2b"}, "pp", "testPPName", make(map[string]interface{}), boolPointer(false)},
},
}
2013-12-27 09:17:51 -07:00
build.Prepare()
artifacts, err = build.Run(context.Background(), ui)
if err != nil {
t.Fatalf("err: %s", err)
}
expectedIds = []string{"pp1a", "pp1b", "pp2b"}
artifactIds = make([]string, len(artifacts))
for i, artifact := range artifacts {
artifactIds[i] = artifact.Id()
}
if !reflect.DeepEqual(artifactIds, expectedIds) {
t.Fatalf("unexpected ids: %#v", artifactIds)
}
// Test case: Test that with a single post-processor that forcibly
// keeps inputs, that the artifacts are kept.
build = testBuild()
2019-12-17 11:25:56 +01:00
build.PostProcessors = [][]CoreBuildPostProcessor{
2016-11-01 14:08:04 -07:00
{
{
2020-01-15 15:36:52 -08:00
&MockPostProcessor{ArtifactId: "pp", Keep: true, ForceOverride: true}, "pp", "testPPName", make(map[string]interface{}), boolPointer(false),
2019-04-03 11:32:49 -07:00
},
},
}
build.Prepare()
artifacts, err = build.Run(context.Background(), ui)
2019-04-03 11:32:49 -07:00
if err != nil {
t.Fatalf("err: %s", err)
}
expectedIds = []string{"b", "pp"}
artifactIds = make([]string, len(artifacts))
for i, artifact := range artifacts {
artifactIds[i] = artifact.Id()
}
if !reflect.DeepEqual(artifactIds, expectedIds) {
t.Fatalf("unexpected ids: %#v", artifactIds)
}
// Test case: Test that with a single post-processor that non-forcibly
// keeps inputs, that the artifacts are discarded if user overrides.
build = testBuild()
2019-12-17 11:25:56 +01:00
build.PostProcessors = [][]CoreBuildPostProcessor{
2019-04-03 11:32:49 -07:00
{
{
2020-01-15 15:36:52 -08:00
&MockPostProcessor{ArtifactId: "pp", Keep: true, ForceOverride: false}, "pp", "testPPName", make(map[string]interface{}), boolPointer(false),
2019-04-03 11:32:49 -07:00
},
},
}
build.Prepare()
artifacts, err = build.Run(context.Background(), ui)
2019-04-03 11:32:49 -07:00
if err != nil {
t.Fatalf("err: %s", err)
}
expectedIds = []string{"pp"}
artifactIds = make([]string, len(artifacts))
for i, artifact := range artifacts {
artifactIds[i] = artifact.Id()
}
if !reflect.DeepEqual(artifactIds, expectedIds) {
t.Fatalf("unexpected ids: %#v", artifactIds)
}
// Test case: Test that with a single post-processor that non-forcibly
// keeps inputs, that the artifacts are kept if user does not have preference.
build = testBuild()
2019-12-17 11:25:56 +01:00
build.PostProcessors = [][]CoreBuildPostProcessor{
2019-04-03 11:32:49 -07:00
{
{
2020-01-15 15:36:52 -08:00
&MockPostProcessor{ArtifactId: "pp", Keep: true, ForceOverride: false}, "pp", "testPPName", make(map[string]interface{}), nil,
},
},
}
2013-12-27 09:17:51 -07:00
build.Prepare()
artifacts, err = build.Run(context.Background(), ui)
if err != nil {
t.Fatalf("err: %s", err)
}
expectedIds = []string{"b", "pp"}
artifactIds = make([]string, len(artifacts))
for i, artifact := range artifacts {
artifactIds[i] = artifact.Id()
}
if !reflect.DeepEqual(artifactIds, expectedIds) {
t.Fatalf("unexpected ids: %#v", artifactIds)
}
}
2013-04-20 20:03:53 -06:00
func TestBuild_RunBeforePrepare(t *testing.T) {
defer func() {
p := recover()
2013-10-16 21:09:27 -10:00
if p == nil {
t.Fatal("should panic")
}
if p.(string) != "Prepare must be called first" {
t.Fatalf("bad: %s", p.(string))
}
2013-04-20 20:03:53 -06:00
}()
testBuild().Run(context.Background(), testUi())
2013-04-20 20:03:53 -06:00
}
func TestBuild_Cancel(t *testing.T) {
build := testBuild()
build.Prepare()
topCtx, topCtxCancel := context.WithCancel(context.Background())
2019-12-17 11:25:56 +01:00
builder := build.Builder.(*MockBuilder)
builder.RunFn = func(ctx context.Context) {
topCtxCancel()
}
_, err := build.Run(topCtx, testUi())
if err == nil {
t.Fatal("build should err")
2013-10-16 21:09:27 -10:00
}
}