diff --git a/backend/local/backend_plan_test.go b/backend/local/backend_plan_test.go index e58d03f67..7ce9e8452 100644 --- a/backend/local/backend_plan_test.go +++ b/backend/local/backend_plan_test.go @@ -8,11 +8,13 @@ import ( "strings" "testing" + "github.com/hashicorp/terraform/addrs" "github.com/hashicorp/terraform/backend" "github.com/hashicorp/terraform/configs/configload" "github.com/hashicorp/terraform/configs/configschema" "github.com/hashicorp/terraform/plans" "github.com/hashicorp/terraform/plans/planfile" + "github.com/hashicorp/terraform/states" "github.com/hashicorp/terraform/terraform" "github.com/mitchellh/cli" "github.com/zclconf/go-cty/cty" @@ -133,7 +135,7 @@ func TestLocal_planRefreshFalse(t *testing.T) { defer cleanup() p := TestLocalProvider(t, b, "test", planFixtureSchema()) - terraform.TestStateFile(t, b.StatePath, testPlanState()) + testStateFile(t, b.StatePath, testPlanState()) op, configCleanup := testOperationPlan(t, "./test-fixtures/plan") defer configCleanup() @@ -161,7 +163,7 @@ func TestLocal_planDestroy(t *testing.T) { defer cleanup() p := TestLocalProvider(t, b, "test", planFixtureSchema()) - terraform.TestStateFile(t, b.StatePath, testPlanState()) + testStateFile(t, b.StatePath, testPlanState()) outDir := testTempDir(t) defer os.RemoveAll(outDir) @@ -202,7 +204,7 @@ func TestLocal_planOutPathNoChange(t *testing.T) { b, cleanup := TestLocal(t) defer cleanup() TestLocalProvider(t, b, "test", planFixtureSchema()) - terraform.TestStateFile(t, b.StatePath, testPlanState()) + testStateFile(t, b.StatePath, testPlanState()) outDir := testTempDir(t) defer os.RemoveAll(outDir) @@ -222,14 +224,10 @@ func TestLocal_planOutPathNoChange(t *testing.T) { } plan := testReadPlan(t, planPath) - // This statement can be removed when the test is fixed and replaced with the - // commented-out test below. - if plan == nil { - t.Fatalf("plan is nil") + + if !plan.Changes.Empty() { + t.Fatalf("expected empty plan to be written") } - // if !plan.Changes.Empty() { - // t.Fatalf("expected empty plan to be written") - // } } // TestLocal_planScaleOutNoDupeCount tests a Refresh/Plan sequence when a @@ -242,29 +240,7 @@ func TestLocal_planScaleOutNoDupeCount(t *testing.T) { b, cleanup := TestLocal(t) defer cleanup() TestLocalProvider(t, b, "test", planFixtureSchema()) - state := &terraform.State{ - Version: 2, - Modules: []*terraform.ModuleState{ - &terraform.ModuleState{ - Path: []string{"root"}, - Resources: map[string]*terraform.ResourceState{ - "test_instance.foo.0": &terraform.ResourceState{ - Type: "test_instance", - Primary: &terraform.InstanceState{ - ID: "bar", - }, - }, - "test_instance.foo.1": &terraform.ResourceState{ - Type: "test_instance", - Primary: &terraform.InstanceState{ - ID: "bar", - }, - }, - }, - }, - }, - } - terraform.TestStateFile(t, b.StatePath, state) + testStateFile(t, b.StatePath, testPlanState()) actual := new(CountHook) b.ContextOpts.Hooks = append(b.ContextOpts.Hooks, actual) @@ -309,24 +285,32 @@ func testOperationPlan(t *testing.T, configDir string) (*backend.Operation, func }, configCleanup } -// testPlanState is just a common state that we use for testing refresh. -func testPlanState() *terraform.State { - return &terraform.State{ - Version: 2, - Modules: []*terraform.ModuleState{ - &terraform.ModuleState{ - Path: []string{"root"}, - Resources: map[string]*terraform.ResourceState{ - "test_instance.foo": &terraform.ResourceState{ - Type: "test_instance", - Primary: &terraform.InstanceState{ - ID: "bar", - }, - }, - }, - }, +// testPlanState is just a common state that we use for testing plan. +func testPlanState() *states.State { + state := states.NewState() + rootModule := state.RootModule() + rootModule.SetResourceInstanceCurrent( + addrs.Resource{ + Mode: addrs.ManagedResourceMode, + Type: "test_instance", + Name: "foo", + }.Instance(addrs.IntKey(0)), + &states.ResourceInstanceObjectSrc{ + Status: states.ObjectReady, + SchemaVersion: 1, + AttrsJSON: []byte(`{ + "ami": "bar", + "network_interface": [{ + "device_index": 0, + "description": "Main network interface" + }] + }`), }, - } + addrs.ProviderConfig{ + Type: "test", + }.Absolute(addrs.RootModuleInstance), + ) + return state } func testReadPlan(t *testing.T, path string) *plans.Plan { diff --git a/backend/local/test-fixtures/plan-scaleout/main.tf b/backend/local/test-fixtures/plan-scaleout/main.tf index 4067af592..4fc97bafa 100644 --- a/backend/local/test-fixtures/plan-scaleout/main.tf +++ b/backend/local/test-fixtures/plan-scaleout/main.tf @@ -1,5 +1,5 @@ resource "test_instance" "foo" { - count = 3 + count = 2 ami = "bar" # This is here because at some point it caused a test failure diff --git a/backend/local/testing.go b/backend/local/testing.go index d9d01b561..8b4710c22 100644 --- a/backend/local/testing.go +++ b/backend/local/testing.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/backend" "github.com/hashicorp/terraform/providers" + "github.com/hashicorp/terraform/states" "github.com/hashicorp/terraform/states/statemgr" "github.com/hashicorp/terraform/terraform" "github.com/hashicorp/terraform/tfdiags" @@ -61,12 +62,6 @@ func TestLocalProvider(t *testing.T, b *Local, name string, schema *terraform.Pr PlannedPrivate: req.PriorPrivate, } } - p.DiffFn = func( - info *terraform.InstanceInfo, - s *terraform.InstanceState, - r *terraform.ResourceConfig) (*terraform.InstanceDiff, error) { - return nil, nil - } p.ReadResourceFn = func(req providers.ReadResourceRequest) providers.ReadResourceResponse { return providers.ReadResourceResponse{NewState: req.PriorState} } @@ -171,3 +166,8 @@ func testTempDir(t *testing.T) string { return d } + +func testStateFile(t *testing.T, path string, s *states.State) { + stateFile := statemgr.NewFilesystem(path) + stateFile.WriteState(s) +} diff --git a/plans/planfile/tfplan.go b/plans/planfile/tfplan.go index 6e4972fda..2db909b9f 100644 --- a/plans/planfile/tfplan.go +++ b/plans/planfile/tfplan.go @@ -277,10 +277,6 @@ func changeFromTfplan(rawChange *planproto.Change) (*plans.ChangeSrc, error) { } func valueFromTfplan(rawV *planproto.DynamicValue) (plans.DynamicValue, error) { - if rawV.Msgpack == nil { - return plans.DynamicValue(nil), nil - } - if len(rawV.Msgpack) == 0 { // len(0) because that's the default value for a "bytes" in protobuf return nil, fmt.Errorf("dynamic value does not have msgpack serialization") }