diff --git a/backend/local/backend_apply_test.go b/backend/local/backend_apply_test.go index ebf1d0785..6757d4ec5 100644 --- a/backend/local/backend_apply_test.go +++ b/backend/local/backend_apply_test.go @@ -11,16 +11,18 @@ import ( "testing" "github.com/hashicorp/terraform/backend" + "github.com/hashicorp/terraform/config/configschema" "github.com/hashicorp/terraform/configs/configload" "github.com/hashicorp/terraform/state" "github.com/hashicorp/terraform/terraform" "github.com/mitchellh/cli" + "github.com/zclconf/go-cty/cty" ) func TestLocal_applyBasic(t *testing.T) { b, cleanup := TestLocal(t) defer cleanup() - p := TestLocalProvider(t, b, "test") + p := TestLocalProvider(t, b, "test", applyFixtureSchema()) p.ApplyReturn = &terraform.InstanceState{ID: "yes"} @@ -59,7 +61,7 @@ func TestLocal_applyEmptyDir(t *testing.T) { b, cleanup := TestLocal(t) defer cleanup() - p := TestLocalProvider(t, b, "test") + p := TestLocalProvider(t, b, "test", &terraform.ProviderSchema{}) p.ApplyReturn = &terraform.InstanceState{ID: "yes"} @@ -87,7 +89,7 @@ func TestLocal_applyEmptyDir(t *testing.T) { func TestLocal_applyEmptyDirDestroy(t *testing.T) { b, cleanup := TestLocal(t) defer cleanup() - p := TestLocalProvider(t, b, "test") + p := TestLocalProvider(t, b, "test", &terraform.ProviderSchema{}) p.ApplyReturn = nil @@ -114,10 +116,20 @@ func TestLocal_applyEmptyDirDestroy(t *testing.T) { func TestLocal_applyError(t *testing.T) { b, cleanup := TestLocal(t) defer cleanup() - p := TestLocalProvider(t, b, "test") + p := TestLocalProvider(t, b, "test", nil) var lock sync.Mutex errored := false + p.GetSchemaReturn = &terraform.ProviderSchema{ + ResourceTypes: map[string]*configschema.Block{ + "test_instance": { + Attributes: map[string]*configschema.Attribute{ + "ami": {Type: cty.String, Optional: true}, + "error": {Type: cty.String, Optional: true}, + }, + }, + }, + } p.ApplyFn = func( info *terraform.InstanceInfo, s *terraform.InstanceState, @@ -183,7 +195,7 @@ func TestLocal_applyBackendFail(t *testing.T) { b.Backend = &backendWithFailingState{} b.CLI = new(cli.MockUi) - p := TestLocalProvider(t, b, "test") + p := TestLocalProvider(t, b, "test", applyFixtureSchema()) p.ApplyReturn = &terraform.InstanceState{ID: "yes"} @@ -198,7 +210,7 @@ func TestLocal_applyBackendFail(t *testing.T) { msgStr := b.CLI.(*cli.MockUi).ErrorWriter.String() if !strings.Contains(msgStr, "Failed to save state: fake failure") { - t.Fatalf("missing original error message in output:\n%s", msgStr) + t.Fatalf("missing \"fake failure\" message in output:\n%s", msgStr) } // The fallback behavior should've created a file errored.tfstate in the @@ -261,3 +273,18 @@ func testApplyState() *terraform.State { }, } } + +// applyFixtureSchema returns a schema suitable for processing the +// configuration in test-fixtures/apply . This schema should be +// assigned to a mock provider named "test". +func applyFixtureSchema() *terraform.ProviderSchema { + return &terraform.ProviderSchema{ + ResourceTypes: map[string]*configschema.Block{ + "test_instance": { + Attributes: map[string]*configschema.Attribute{ + "ami": {Type: cty.String, Optional: true}, + }, + }, + }, + } +} diff --git a/backend/local/backend_plan_test.go b/backend/local/backend_plan_test.go index 8c92d0d37..e23f387a6 100644 --- a/backend/local/backend_plan_test.go +++ b/backend/local/backend_plan_test.go @@ -9,15 +9,17 @@ import ( "testing" "github.com/hashicorp/terraform/backend" + "github.com/hashicorp/terraform/config/configschema" "github.com/hashicorp/terraform/configs/configload" "github.com/hashicorp/terraform/terraform" "github.com/mitchellh/cli" + "github.com/zclconf/go-cty/cty" ) func TestLocal_planBasic(t *testing.T) { b, cleanup := TestLocal(t) defer cleanup() - p := TestLocalProvider(t, b, "test") + p := TestLocalProvider(t, b, "test", planFixtureSchema()) op, configCleanup := testOperationPlan(t, "./test-fixtures/plan") defer configCleanup() @@ -40,7 +42,7 @@ func TestLocal_planBasic(t *testing.T) { func TestLocal_planInAutomation(t *testing.T) { b, cleanup := TestLocal(t) defer cleanup() - TestLocalProvider(t, b, "test") + TestLocalProvider(t, b, "test", planFixtureSchema()) const msg = `You didn't specify an "-out" parameter` @@ -101,7 +103,7 @@ func TestLocal_planInAutomation(t *testing.T) { func TestLocal_planNoConfig(t *testing.T) { b, cleanup := TestLocal(t) defer cleanup() - TestLocalProvider(t, b, "test") + TestLocalProvider(t, b, "test", &terraform.ProviderSchema{}) b.CLI = cli.NewMockUi() @@ -127,7 +129,7 @@ func TestLocal_planNoConfig(t *testing.T) { func TestLocal_planRefreshFalse(t *testing.T) { b, cleanup := TestLocal(t) defer cleanup() - p := TestLocalProvider(t, b, "test") + p := TestLocalProvider(t, b, "test", &terraform.ProviderSchema{}) terraform.TestStateFile(t, b.StatePath, testPlanState()) op, configCleanup := testOperationPlan(t, "./test-fixtures/empty") @@ -154,7 +156,7 @@ func TestLocal_planRefreshFalse(t *testing.T) { func TestLocal_planDestroy(t *testing.T) { b, cleanup := TestLocal(t) defer cleanup() - p := TestLocalProvider(t, b, "test") + p := TestLocalProvider(t, b, "test", planFixtureSchema()) terraform.TestStateFile(t, b.StatePath, testPlanState()) outDir := testTempDir(t) @@ -197,7 +199,7 @@ func TestLocal_planDestroy(t *testing.T) { func TestLocal_planOutPathNoChange(t *testing.T) { b, cleanup := TestLocal(t) defer cleanup() - TestLocalProvider(t, b, "test") + TestLocalProvider(t, b, "test", planFixtureSchema()) terraform.TestStateFile(t, b.StatePath, testPlanState()) outDir := testTempDir(t) @@ -232,7 +234,7 @@ func TestLocal_planOutPathNoChange(t *testing.T) { func TestLocal_planScaleOutNoDupeCount(t *testing.T) { b, cleanup := TestLocal(t) defer cleanup() - TestLocalProvider(t, b, "test") + TestLocalProvider(t, b, "test", planFixtureSchema()) state := &terraform.State{ Version: 2, Modules: []*terraform.ModuleState{ @@ -334,3 +336,29 @@ func testReadPlan(t *testing.T, path string) *terraform.Plan { return p } + +// planFixtureSchema returns a schema suitable for processing the +// configuration in test-fixtures/plan . This schema should be +// assigned to a mock provider named "test". +func planFixtureSchema() *terraform.ProviderSchema { + return &terraform.ProviderSchema{ + ResourceTypes: map[string]*configschema.Block{ + "test_instance": { + Attributes: map[string]*configschema.Attribute{ + "ami": {Type: cty.String, Optional: true}, + }, + BlockTypes: map[string]*configschema.NestedBlock{ + "network_interface": { + Nesting: configschema.NestingList, + Block: configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "device_index": {Type: cty.Number, Optional: true}, + "description": {Type: cty.String, Optional: true}, + }, + }, + }, + }, + }, + }, + } +} diff --git a/backend/local/backend_refresh_test.go b/backend/local/backend_refresh_test.go index dc65423c2..d0328a962 100644 --- a/backend/local/backend_refresh_test.go +++ b/backend/local/backend_refresh_test.go @@ -6,15 +6,17 @@ import ( "testing" "github.com/hashicorp/terraform/backend" + "github.com/hashicorp/terraform/config/configschema" "github.com/hashicorp/terraform/configs/configload" "github.com/hashicorp/terraform/terraform" + "github.com/zclconf/go-cty/cty" ) func TestLocal_refresh(t *testing.T) { b, cleanup := TestLocal(t) defer cleanup() - p := TestLocalProvider(t, b, "test") + p := TestLocalProvider(t, b, "test", refreshFixtureSchema()) terraform.TestStateFile(t, b.StatePath, testRefreshState()) p.RefreshFn = nil @@ -43,7 +45,7 @@ test_instance.foo: func TestLocal_refreshNoConfig(t *testing.T) { b, cleanup := TestLocal(t) defer cleanup() - p := TestLocalProvider(t, b, "test") + p := TestLocalProvider(t, b, "test", &terraform.ProviderSchema{}) terraform.TestStateFile(t, b.StatePath, testRefreshState()) p.RefreshFn = nil @@ -73,7 +75,7 @@ test_instance.foo: func TestLocal_refreshNilModuleWithInput(t *testing.T) { b, cleanup := TestLocal(t) defer cleanup() - p := TestLocalProvider(t, b, "test") + p := TestLocalProvider(t, b, "test", &terraform.ProviderSchema{}) terraform.TestStateFile(t, b.StatePath, testRefreshState()) p.RefreshFn = nil @@ -104,9 +106,23 @@ test_instance.foo: func TestLocal_refreshInput(t *testing.T) { b, cleanup := TestLocal(t) defer cleanup() - p := TestLocalProvider(t, b, "test") + p := TestLocalProvider(t, b, "test", nil) terraform.TestStateFile(t, b.StatePath, testRefreshState()) + p.GetSchemaReturn = &terraform.ProviderSchema{ + Provider: &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "value": {Type: cty.String, Optional: true}, + }, + }, + ResourceTypes: map[string]*configschema.Block{ + "test_instance": { + Attributes: map[string]*configschema.Attribute{ + "foo": {Type: cty.String, Optional: true}, + }, + }, + }, + } p.ConfigureFn = func(c *terraform.ResourceConfig) error { if v, ok := c.Get("value"); !ok || v != "bar" { return fmt.Errorf("no value set") @@ -146,7 +162,7 @@ test_instance.foo: func TestLocal_refreshValidate(t *testing.T) { b, cleanup := TestLocal(t) defer cleanup() - p := TestLocalProvider(t, b, "test") + p := TestLocalProvider(t, b, "test", refreshFixtureSchema()) terraform.TestStateFile(t, b.StatePath, testRefreshState()) p.RefreshFn = nil @@ -207,3 +223,18 @@ func testRefreshState() *terraform.State { }, } } + +// refreshFixtureSchema returns a schema suitable for processing the +// configuration in test-fixtures/refresh . This schema should be +// assigned to a mock provider named "test". +func refreshFixtureSchema() *terraform.ProviderSchema { + return &terraform.ProviderSchema{ + ResourceTypes: map[string]*configschema.Block{ + "test_instance": { + Attributes: map[string]*configschema.Attribute{ + "ami": {Type: cty.String, Optional: true}, + }, + }, + }, + } +} diff --git a/backend/local/testing.go b/backend/local/testing.go index 8c109c793..0d0c70f2f 100644 --- a/backend/local/testing.go +++ b/backend/local/testing.go @@ -50,9 +50,10 @@ 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) *terraform.MockResourceProvider { +func TestLocalProvider(t *testing.T, b *Local, name string, schema *terraform.ProviderSchema) *terraform.MockResourceProvider { // 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,