diff --git a/backend/local/backend_apply_test.go b/backend/local/backend_apply_test.go index e7e7a53a9..f8de90479 100644 --- a/backend/local/backend_apply_test.go +++ b/backend/local/backend_apply_test.go @@ -123,8 +123,7 @@ func TestLocal_applyError(t *testing.T) { b, cleanup := TestLocal(t) defer cleanup() - p := TestLocalProvider(t, b, "test", nil) - p.GetSchemaReturn = &terraform.ProviderSchema{ + schema := &terraform.ProviderSchema{ ResourceTypes: map[string]*configschema.Block{ "test_instance": { Attributes: map[string]*configschema.Attribute{ @@ -134,6 +133,7 @@ func TestLocal_applyError(t *testing.T) { }, }, } + p := TestLocalProvider(t, b, "test", schema) var lock sync.Mutex errored := false diff --git a/backend/local/testing.go b/backend/local/testing.go index 05f7600f9..dccddb5da 100644 --- a/backend/local/testing.go +++ b/backend/local/testing.go @@ -6,7 +6,11 @@ import ( "path/filepath" "testing" + "github.com/zclconf/go-cty/cty" + + "github.com/hashicorp/terraform/addrs" "github.com/hashicorp/terraform/backend" + "github.com/hashicorp/terraform/configs/configschema" "github.com/hashicorp/terraform/providers" "github.com/hashicorp/terraform/states" "github.com/hashicorp/terraform/states/statemgr" @@ -38,9 +42,14 @@ func TestLocal(t *testing.T) (*Local, func()) { // function, t.Helper doesn't apply and so the log source // isn't correctly shown in the test log output. This seems // unavoidable as long as this is happening so indirectly. - t.Log(diag.Description().Summary) + desc := diag.Description() + if desc.Detail != "" { + t.Logf("%s: %s", desc.Summary, desc.Detail) + } else { + t.Log(desc.Summary) + } if local.CLI != nil { - local.CLI.Error(diag.Description().Summary) + local.CLI.Error(desc.Summary) } } } @@ -59,10 +68,34 @@ func TestLocal(t *testing.T) (*Local, func()) { 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) + + if schema == nil { + schema = &terraform.ProviderSchema{} // default schema is empty + } p.GetSchemaReturn = schema + p.PlanResourceChangeFn = func(req providers.PlanResourceChangeRequest) providers.PlanResourceChangeResponse { + rSchema, _ := schema.SchemaForResourceType(addrs.ManagedResourceMode, req.TypeName) + if rSchema == nil { + rSchema = &configschema.Block{} // default schema is empty + } + plannedVals := map[string]cty.Value{} + for name, attrS := range rSchema.Attributes { + val := req.ProposedNewState.GetAttr(name) + if attrS.Computed && val.IsNull() { + val = cty.UnknownVal(attrS.Type) + } + plannedVals[name] = val + } + for name := range rSchema.BlockTypes { + // For simplicity's sake we just copy the block attributes over + // verbatim, since this package's mock providers are all relatively + // simple -- we're testing the backend, not esoteric provider features. + plannedVals[name] = req.ProposedNewState.GetAttr(name) + } + return providers.PlanResourceChangeResponse{ - PlannedState: req.ProposedNewState, + PlannedState: cty.ObjectVal(plannedVals), PlannedPrivate: req.PriorPrivate, } }