From 2808df48eca9950c4106c51c52e5fa5fe87cadcf Mon Sep 17 00:00:00 2001 From: Kristin Laemmert Date: Fri, 28 Sep 2018 14:04:57 -0700 Subject: [PATCH] backend/local WIP commit - fixing tests --- backend/local/backend.go | 2 +- backend/local/backend_apply.go | 1 + backend/local/backend_apply_test.go | 29 +++++++----- backend/local/backend_plan_test.go | 14 +++--- backend/local/backend_refresh_test.go | 41 ++++++++--------- backend/local/backend_test.go | 6 +-- backend/local/testing.go | 65 ++++++++++++++------------- 7 files changed, 85 insertions(+), 73 deletions(-) diff --git a/backend/local/backend.go b/backend/local/backend.go index f0ec55401..4badd8961 100644 --- a/backend/local/backend.go +++ b/backend/local/backend.go @@ -330,8 +330,8 @@ func (b *Local) Operation(ctx context.Context, op *backend.Operation) (*backend. err := op.StateLocker.Unlock(nil) if err != nil { b.ShowDiagnostics(err) + runningOp.Result = backend.OperationFailure } - runningOp.Result = backend.OperationFailure }() defer b.opLock.Unlock() diff --git a/backend/local/backend_apply.go b/backend/local/backend_apply.go index 1b479c752..c0465aee1 100644 --- a/backend/local/backend_apply.go +++ b/backend/local/backend_apply.go @@ -84,6 +84,7 @@ func (b *Local) opApply( } trivialPlan := plan.Changes.Empty() + hasUI := op.UIOut != nil && op.UIIn != nil mustConfirm := hasUI && ((op.Destroy && (!op.DestroyForce && !op.AutoApprove)) || (!op.Destroy && !op.AutoApprove && !trivialPlan)) if mustConfirm { diff --git a/backend/local/backend_apply_test.go b/backend/local/backend_apply_test.go index 059543e8c..55bef527a 100644 --- a/backend/local/backend_apply_test.go +++ b/backend/local/backend_apply_test.go @@ -16,6 +16,7 @@ import ( "github.com/hashicorp/terraform/backend" "github.com/hashicorp/terraform/configs/configload" "github.com/hashicorp/terraform/configs/configschema" + "github.com/hashicorp/terraform/providers" "github.com/hashicorp/terraform/states" "github.com/hashicorp/terraform/states/statemgr" "github.com/hashicorp/terraform/terraform" @@ -26,7 +27,10 @@ func TestLocal_applyBasic(t *testing.T) { defer cleanup() p := TestLocalProvider(t, b, "test", applyFixtureSchema()) - p.ApplyReturn = &terraform.InstanceState{ID: "yes"} + p.ApplyResourceChangeResponse = providers.ApplyResourceChangeResponse{NewState: cty.ObjectVal(map[string]cty.Value{ + "id": cty.StringVal("yes"), + "ami": cty.StringVal("bar"), + })} op, configCleanup := testOperationApply(t, "./test-fixtures/apply") defer configCleanup() @@ -40,15 +44,15 @@ func TestLocal_applyBasic(t *testing.T) { t.Fatal("operation failed") } - if p.RefreshCalled { - t.Fatal("refresh should not be called") + if p.ReadResourceCalled { + t.Fatal("ReadResource should not be called") } - if !p.DiffCalled { + if !p.PlanResourceChangeCalled { t.Fatal("diff should be called") } - if !p.ApplyCalled { + if !p.ApplyResourceChangeCalled { t.Fatal("apply should be called") } @@ -56,7 +60,8 @@ func TestLocal_applyBasic(t *testing.T) { test_instance.foo: ID = yes provider = provider.test - `) + ami = bar +`) } func TestLocal_applyEmptyDir(t *testing.T) { @@ -64,8 +69,7 @@ func TestLocal_applyEmptyDir(t *testing.T) { defer cleanup() p := TestLocalProvider(t, b, "test", &terraform.ProviderSchema{}) - - p.ApplyReturn = &terraform.InstanceState{ID: "yes"} + p.ApplyResourceChangeResponse = providers.ApplyResourceChangeResponse{NewState: cty.ObjectVal(map[string]cty.Value{"id": cty.StringVal("yes")})} op, configCleanup := testOperationApply(t, "./test-fixtures/empty") defer configCleanup() @@ -79,7 +83,7 @@ func TestLocal_applyEmptyDir(t *testing.T) { t.Fatal("operation succeeded; want error") } - if p.ApplyCalled { + if p.ApplyResourceChangeCalled { t.Fatal("apply should not be called") } @@ -93,7 +97,7 @@ func TestLocal_applyEmptyDirDestroy(t *testing.T) { defer cleanup() p := TestLocalProvider(t, b, "test", &terraform.ProviderSchema{}) - p.ApplyReturn = nil + p.ApplyResourceChangeResponse = providers.ApplyResourceChangeResponse{} op, configCleanup := testOperationApply(t, "./test-fixtures/empty") defer configCleanup() @@ -108,7 +112,7 @@ func TestLocal_applyEmptyDirDestroy(t *testing.T) { t.Fatalf("apply operation failed") } - if p.ApplyCalled { + if p.ApplyResourceChangeCalled { t.Fatal("apply should not be called") } @@ -199,7 +203,7 @@ func TestLocal_applyBackendFail(t *testing.T) { b.CLI = new(cli.MockUi) p := TestLocalProvider(t, b, "test", applyFixtureSchema()) - p.ApplyReturn = &terraform.InstanceState{ID: "yes"} + p.ApplyResourceChangeResponse = providers.ApplyResourceChangeResponse{NewState: cty.ObjectVal(map[string]cty.Value{"id": cty.StringVal("yes")})} run, err := b.Operation(context.Background(), op) if err != nil { @@ -283,6 +287,7 @@ func applyFixtureSchema() *terraform.ProviderSchema { "test_instance": { Attributes: map[string]*configschema.Attribute{ "ami": {Type: cty.String, Optional: true}, + "id": {Type: cty.String, Computed: true}, }, }, }, diff --git a/backend/local/backend_plan_test.go b/backend/local/backend_plan_test.go index b41e18599..56105ea44 100644 --- a/backend/local/backend_plan_test.go +++ b/backend/local/backend_plan_test.go @@ -9,8 +9,8 @@ import ( "testing" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/configs/configschema" "github.com/hashicorp/terraform/configs/configload" + "github.com/hashicorp/terraform/configs/configschema" "github.com/hashicorp/terraform/terraform" "github.com/mitchellh/cli" "github.com/zclconf/go-cty/cty" @@ -34,8 +34,8 @@ func TestLocal_planBasic(t *testing.T) { t.Fatalf("plan operation failed") } - if !p.DiffCalled { - t.Fatal("diff should be called") + if !p.PlanResourceChangeCalled { + t.Fatal("PlanResourceChange should be called") } } @@ -144,8 +144,8 @@ func TestLocal_planRefreshFalse(t *testing.T) { t.Fatalf("plan operation failed") } - if p.RefreshCalled { - t.Fatal("refresh should not be called") + if p.ReadResourceCalled { + t.Fatal("ReadResource should not be called") } if !run.PlanEmpty { @@ -178,8 +178,8 @@ func TestLocal_planDestroy(t *testing.T) { t.Fatalf("plan operation failed") } - if !p.RefreshCalled { - t.Fatal("refresh should be called") + if !p.ReadResourceCalled { + t.Fatal("ReadResource should be called") } if run.PlanEmpty { diff --git a/backend/local/backend_refresh_test.go b/backend/local/backend_refresh_test.go index 68a3680a0..ebd55dafb 100644 --- a/backend/local/backend_refresh_test.go +++ b/backend/local/backend_refresh_test.go @@ -6,8 +6,8 @@ import ( "testing" "github.com/hashicorp/terraform/backend" - "github.com/hashicorp/terraform/configs/configschema" "github.com/hashicorp/terraform/configs/configload" + "github.com/hashicorp/terraform/configs/configschema" "github.com/hashicorp/terraform/terraform" "github.com/zclconf/go-cty/cty" ) @@ -19,8 +19,8 @@ func TestLocal_refresh(t *testing.T) { p := TestLocalProvider(t, b, "test", refreshFixtureSchema()) terraform.TestStateFile(t, b.StatePath, testRefreshState()) - p.RefreshFn = nil - p.RefreshReturn = &terraform.InstanceState{ID: "yes"} + // p.RefreshFn = nil + // p.RefreshReturn = &terraform.InstanceState{ID: "yes"} op, configCleanup := testOperationRefresh(t, "./test-fixtures/refresh") defer configCleanup() @@ -31,8 +31,8 @@ func TestLocal_refresh(t *testing.T) { } <-run.Done() - if !p.RefreshCalled { - t.Fatal("refresh should be called") + if !p.ReadResourceCalled { + t.Fatal("ReadResource should be called") } checkState(t, b.StateOutPath, ` @@ -48,8 +48,8 @@ func TestLocal_refreshNoConfig(t *testing.T) { p := TestLocalProvider(t, b, "test", &terraform.ProviderSchema{}) terraform.TestStateFile(t, b.StatePath, testRefreshState()) - p.RefreshFn = nil - p.RefreshReturn = &terraform.InstanceState{ID: "yes"} + // p.RefreshFn = nil + // p.RefreshReturn = &terraform.InstanceState{ID: "yes"} op, configCleanup := testOperationRefresh(t, "./test-fixtures/empty") defer configCleanup() @@ -60,8 +60,8 @@ func TestLocal_refreshNoConfig(t *testing.T) { } <-run.Done() - if !p.RefreshCalled { - t.Fatal("refresh should be called") + if !p.ReadResourceCalled { + t.Fatal("ReadResource should be called") } checkState(t, b.StateOutPath, ` @@ -78,8 +78,8 @@ func TestLocal_refreshNilModuleWithInput(t *testing.T) { p := TestLocalProvider(t, b, "test", &terraform.ProviderSchema{}) terraform.TestStateFile(t, b.StatePath, testRefreshState()) - p.RefreshFn = nil - p.RefreshReturn = &terraform.InstanceState{ID: "yes"} + // p.RefreshFn = nil + // p.RefreshReturn = &terraform.InstanceState{ID: "yes"} b.OpInput = true @@ -92,8 +92,8 @@ func TestLocal_refreshNilModuleWithInput(t *testing.T) { } <-run.Done() - if !p.RefreshCalled { - t.Fatal("refresh should be called") + if !p.ReadResourceCalled { + t.Fatal("ReadResource should be called") } checkState(t, b.StateOutPath, ` @@ -131,8 +131,8 @@ func TestLocal_refreshInput(t *testing.T) { return nil } - p.RefreshFn = nil - p.RefreshReturn = &terraform.InstanceState{ID: "yes"} + // p.RefreshFn = nil + // p.RefreshReturn = &terraform.InstanceState{ID: "yes"} // Enable input asking since it is normally disabled by default b.OpInput = true @@ -148,8 +148,8 @@ func TestLocal_refreshInput(t *testing.T) { } <-run.Done() - if !p.RefreshCalled { - t.Fatal("refresh should be called") + if !p.ReadResourceCalled { + t.Fatal("ReadResource should be called") } checkState(t, b.StateOutPath, ` @@ -165,8 +165,8 @@ func TestLocal_refreshValidate(t *testing.T) { p := TestLocalProvider(t, b, "test", refreshFixtureSchema()) terraform.TestStateFile(t, b.StatePath, testRefreshState()) - p.RefreshFn = nil - p.RefreshReturn = &terraform.InstanceState{ID: "yes"} + // p.RefreshFn = nil + // p.RefreshReturn = &terraform.InstanceState{ID: "yes"} // Enable validation b.OpValidation = true @@ -180,7 +180,8 @@ func TestLocal_refreshValidate(t *testing.T) { } <-run.Done() - if !p.ValidateCalled { + // what are we validating? + if !p.ValidateProviderConfigCalled { t.Fatal("validate should be called") } diff --git a/backend/local/backend_test.go b/backend/local/backend_test.go index 29561d6bb..f936acd82 100644 --- a/backend/local/backend_test.go +++ b/backend/local/backend_test.go @@ -10,8 +10,8 @@ import ( "testing" "github.com/hashicorp/terraform/backend" + "github.com/hashicorp/terraform/states/statefile" "github.com/hashicorp/terraform/states/statemgr" - "github.com/hashicorp/terraform/terraform" ) func TestLocal_impl(t *testing.T) { @@ -35,13 +35,13 @@ func checkState(t *testing.T, path, expected string) { t.Fatalf("err: %s", err) } - state, err := terraform.ReadState(f) + state, err := statefile.Read(f) f.Close() if err != nil { t.Fatalf("err: %s", err) } - actual := strings.TrimSpace(state.String()) + actual := state.State.String() expected = strings.TrimSpace(expected) if actual != expected { t.Fatalf("state does not match! actual:\n%s\n\nexpected:\n%s", actual, expected) diff --git a/backend/local/testing.go b/backend/local/testing.go index 346bce1c4..6f53436ea 100644 --- a/backend/local/testing.go +++ b/backend/local/testing.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/hashicorp/terraform/backend" + "github.com/hashicorp/terraform/providers" "github.com/hashicorp/terraform/states/statemgr" "github.com/hashicorp/terraform/terraform" "github.com/hashicorp/terraform/tfdiags" @@ -41,7 +42,7 @@ func TestLocal(t *testing.T) (*Local, func()) { } cleanup := func() { if err := os.RemoveAll(tempDir); err != nil { - t.Fatal("error clecanup up test:", err) + t.Fatal("error cleanup up test:", err) } } @@ -50,39 +51,43 @@ func TestLocal(t *testing.T) (*Local, func()) { // TestLocalProvider modifies the ContextOpts of the *Local parameter to // have a provider with the given name. -func TestLocalProvider(t *testing.T, b *Local, name string, schema *terraform.ProviderSchema) *terraform.MockResourceProvider { - t.Fatalf("TestLocalProvider is not yet updated to use the new provider types") - return nil - /* - // Build a mock resource provider for in-memory operations - p := new(terraform.MockResourceProvider) - p.GetSchemaReturn = schema - p.DiffReturn = &terraform.InstanceDiff{} - p.RefreshFn = func( - info *terraform.InstanceInfo, - s *terraform.InstanceState) (*terraform.InstanceState, error) { - return s, nil - } - p.ResourcesReturn = []terraform.ResourceType{ - terraform.ResourceType{ - Name: "test_instance", - }, +func TestLocalProvider(t *testing.T, b *Local, name string, schema *terraform.ProviderSchema) *terraform.MockProvider { + // Build a mock resource provider for in-memory operations + p := new(terraform.MockProvider) + p.GetSchemaReturn = schema + p.PlanResourceChangeFn = func(req providers.PlanResourceChangeRequest) providers.PlanResourceChangeResponse { + return providers.PlanResourceChangeResponse{ + PlannedState: req.ProposedNewState, + PlannedPrivate: req.PriorPrivate, } + } + // p.DiffReturn = &terraform.InstanceDiff{} - // Initialize the opts - if b.ContextOpts == nil { - b.ContextOpts = &terraform.ContextOpts{} - } + // p.RefreshFn = func( + // info *terraform.InstanceInfo, + // s *terraform.InstanceState) (*terraform.InstanceState, error) { + // return s, nil + // } + // p.ResourcesReturn = []terraform.ResourceType{ + // terraform.ResourceType{ + // Name: "test_instance", + // }, + // } - // Setup our provider - b.ContextOpts.ProviderResolver = providers.ResolverFixed( - map[string]providers.Factory{ - name: providers.FactoryFixed(p), - }, - ) + // Initialize the opts + if b.ContextOpts == nil { + b.ContextOpts = &terraform.ContextOpts{} + } + + // Setup our provider + b.ContextOpts.ProviderResolver = providers.ResolverFixed( + map[string]providers.Factory{ + name: providers.FactoryFixed(p), + }, + ) + + return p - return p - */ } // TestNewLocalSingle is a factory for creating a TestLocalSingleState.