backend/local tests tests tests

converted the existing testPlanState() from terraform.State to
states.State to fix various plan tests.

reverted the "bandaid" in plans/planfile/tfplan.go - at this moment the
backend tests do not include backend configuration, and so the planfile
package can write the plan file but not read it back in. That will be
revisted in a separate track of work.
This commit is contained in:
Kristin Laemmert 2018-10-08 15:22:59 -07:00 committed by Martin Atkins
parent 6a37ee9277
commit 2d3cb87789
4 changed files with 41 additions and 61 deletions

View File

@ -8,11 +8,13 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/backend" "github.com/hashicorp/terraform/backend"
"github.com/hashicorp/terraform/configs/configload" "github.com/hashicorp/terraform/configs/configload"
"github.com/hashicorp/terraform/configs/configschema" "github.com/hashicorp/terraform/configs/configschema"
"github.com/hashicorp/terraform/plans" "github.com/hashicorp/terraform/plans"
"github.com/hashicorp/terraform/plans/planfile" "github.com/hashicorp/terraform/plans/planfile"
"github.com/hashicorp/terraform/states"
"github.com/hashicorp/terraform/terraform" "github.com/hashicorp/terraform/terraform"
"github.com/mitchellh/cli" "github.com/mitchellh/cli"
"github.com/zclconf/go-cty/cty" "github.com/zclconf/go-cty/cty"
@ -133,7 +135,7 @@ func TestLocal_planRefreshFalse(t *testing.T) {
defer cleanup() defer cleanup()
p := TestLocalProvider(t, b, "test", planFixtureSchema()) p := TestLocalProvider(t, b, "test", planFixtureSchema())
terraform.TestStateFile(t, b.StatePath, testPlanState()) testStateFile(t, b.StatePath, testPlanState())
op, configCleanup := testOperationPlan(t, "./test-fixtures/plan") op, configCleanup := testOperationPlan(t, "./test-fixtures/plan")
defer configCleanup() defer configCleanup()
@ -161,7 +163,7 @@ func TestLocal_planDestroy(t *testing.T) {
defer cleanup() defer cleanup()
p := TestLocalProvider(t, b, "test", planFixtureSchema()) p := TestLocalProvider(t, b, "test", planFixtureSchema())
terraform.TestStateFile(t, b.StatePath, testPlanState()) testStateFile(t, b.StatePath, testPlanState())
outDir := testTempDir(t) outDir := testTempDir(t)
defer os.RemoveAll(outDir) defer os.RemoveAll(outDir)
@ -202,7 +204,7 @@ func TestLocal_planOutPathNoChange(t *testing.T) {
b, cleanup := TestLocal(t) b, cleanup := TestLocal(t)
defer cleanup() defer cleanup()
TestLocalProvider(t, b, "test", planFixtureSchema()) TestLocalProvider(t, b, "test", planFixtureSchema())
terraform.TestStateFile(t, b.StatePath, testPlanState()) testStateFile(t, b.StatePath, testPlanState())
outDir := testTempDir(t) outDir := testTempDir(t)
defer os.RemoveAll(outDir) defer os.RemoveAll(outDir)
@ -222,14 +224,10 @@ func TestLocal_planOutPathNoChange(t *testing.T) {
} }
plan := testReadPlan(t, planPath) plan := testReadPlan(t, planPath)
// This statement can be removed when the test is fixed and replaced with the
// commented-out test below. if !plan.Changes.Empty() {
if plan == nil { t.Fatalf("expected empty plan to be written")
t.Fatalf("plan is nil")
} }
// if !plan.Changes.Empty() {
// t.Fatalf("expected empty plan to be written")
// }
} }
// TestLocal_planScaleOutNoDupeCount tests a Refresh/Plan sequence when a // TestLocal_planScaleOutNoDupeCount tests a Refresh/Plan sequence when a
@ -242,29 +240,7 @@ func TestLocal_planScaleOutNoDupeCount(t *testing.T) {
b, cleanup := TestLocal(t) b, cleanup := TestLocal(t)
defer cleanup() defer cleanup()
TestLocalProvider(t, b, "test", planFixtureSchema()) TestLocalProvider(t, b, "test", planFixtureSchema())
state := &terraform.State{ testStateFile(t, b.StatePath, testPlanState())
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)
actual := new(CountHook) actual := new(CountHook)
b.ContextOpts.Hooks = append(b.ContextOpts.Hooks, actual) b.ContextOpts.Hooks = append(b.ContextOpts.Hooks, actual)
@ -309,24 +285,32 @@ func testOperationPlan(t *testing.T, configDir string) (*backend.Operation, func
}, configCleanup }, configCleanup
} }
// testPlanState is just a common state that we use for testing refresh. // testPlanState is just a common state that we use for testing plan.
func testPlanState() *terraform.State { func testPlanState() *states.State {
return &terraform.State{ state := states.NewState()
Version: 2, rootModule := state.RootModule()
Modules: []*terraform.ModuleState{ rootModule.SetResourceInstanceCurrent(
&terraform.ModuleState{ addrs.Resource{
Path: []string{"root"}, Mode: addrs.ManagedResourceMode,
Resources: map[string]*terraform.ResourceState{
"test_instance.foo": &terraform.ResourceState{
Type: "test_instance", Type: "test_instance",
Primary: &terraform.InstanceState{ Name: "foo",
ID: "bar", }.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 { func testReadPlan(t *testing.T, path string) *plans.Plan {

View File

@ -1,5 +1,5 @@
resource "test_instance" "foo" { resource "test_instance" "foo" {
count = 3 count = 2
ami = "bar" ami = "bar"
# This is here because at some point it caused a test failure # This is here because at some point it caused a test failure

View File

@ -8,6 +8,7 @@ import (
"github.com/hashicorp/terraform/backend" "github.com/hashicorp/terraform/backend"
"github.com/hashicorp/terraform/providers" "github.com/hashicorp/terraform/providers"
"github.com/hashicorp/terraform/states"
"github.com/hashicorp/terraform/states/statemgr" "github.com/hashicorp/terraform/states/statemgr"
"github.com/hashicorp/terraform/terraform" "github.com/hashicorp/terraform/terraform"
"github.com/hashicorp/terraform/tfdiags" "github.com/hashicorp/terraform/tfdiags"
@ -61,12 +62,6 @@ func TestLocalProvider(t *testing.T, b *Local, name string, schema *terraform.Pr
PlannedPrivate: req.PriorPrivate, 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 { p.ReadResourceFn = func(req providers.ReadResourceRequest) providers.ReadResourceResponse {
return providers.ReadResourceResponse{NewState: req.PriorState} return providers.ReadResourceResponse{NewState: req.PriorState}
} }
@ -171,3 +166,8 @@ func testTempDir(t *testing.T) string {
return d return d
} }
func testStateFile(t *testing.T, path string, s *states.State) {
stateFile := statemgr.NewFilesystem(path)
stateFile.WriteState(s)
}

View File

@ -277,10 +277,6 @@ func changeFromTfplan(rawChange *planproto.Change) (*plans.ChangeSrc, error) {
} }
func valueFromTfplan(rawV *planproto.DynamicValue) (plans.DynamicValue, 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 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") return nil, fmt.Errorf("dynamic value does not have msgpack serialization")
} }