Skip to content

Commit

Permalink
Merge pull request #33482 from hashicorp/jbardin/schema-cache
Browse files Browse the repository at this point in the history
Refactor providers.Schemas and add a global schema cache
  • Loading branch information
jbardin authored Jul 6, 2023
2 parents d1a5dfa + a77baa8 commit 6be6f69
Show file tree
Hide file tree
Showing 58 changed files with 752 additions and 762 deletions.
8 changes: 1 addition & 7 deletions internal/backend/local/backend_apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,7 @@ func (b *Local) opApply(
// plan.Errored will be true in this case, which our plan
// renderer can rely on to tailor its messaging.
if plan != nil && (len(plan.Changes.Resources) != 0 || len(plan.Changes.Outputs) != 0) {
schemas, moreDiags := lr.Core.Schemas(lr.Config, lr.InputState)
// If schema loading returns errors then we'll just give up and
// ignore them to avoid distracting from the plan-time errors we're
// mainly trying to report here.
if !moreDiags.HasErrors() {
op.View.Plan(plan, schemas)
}
op.View.Plan(plan, schemas)
}
op.ReportResult(runningOp, diags)
return
Expand Down
31 changes: 17 additions & 14 deletions internal/backend/local/backend_apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import (
"github.com/hashicorp/terraform/internal/states"
"github.com/hashicorp/terraform/internal/states/statemgr"
"github.com/hashicorp/terraform/internal/terminal"
"github.com/hashicorp/terraform/internal/terraform"
"github.com/hashicorp/terraform/internal/tfdiags"
)

Expand Down Expand Up @@ -123,7 +122,7 @@ func TestLocal_applyCheck(t *testing.T) {
func TestLocal_applyEmptyDir(t *testing.T) {
b := TestLocal(t)

p := TestLocalProvider(t, b, "test", &terraform.ProviderSchema{})
p := TestLocalProvider(t, b, "test", providers.ProviderSchema{})
p.ApplyResourceChangeResponse = &providers.ApplyResourceChangeResponse{NewState: cty.ObjectVal(map[string]cty.Value{"id": cty.StringVal("yes")})}

op, configCleanup, done := testOperationApply(t, "./testdata/empty")
Expand Down Expand Up @@ -157,7 +156,7 @@ func TestLocal_applyEmptyDir(t *testing.T) {
func TestLocal_applyEmptyDirDestroy(t *testing.T) {
b := TestLocal(t)

p := TestLocalProvider(t, b, "test", &terraform.ProviderSchema{})
p := TestLocalProvider(t, b, "test", providers.ProviderSchema{})
p.ApplyResourceChangeResponse = &providers.ApplyResourceChangeResponse{}

op, configCleanup, done := testOperationApply(t, "./testdata/empty")
Expand Down Expand Up @@ -187,12 +186,14 @@ func TestLocal_applyEmptyDirDestroy(t *testing.T) {
func TestLocal_applyError(t *testing.T) {
b := TestLocal(t)

schema := &terraform.ProviderSchema{
ResourceTypes: map[string]*configschema.Block{
schema := providers.ProviderSchema{
ResourceTypes: map[string]providers.Schema{
"test_instance": {
Attributes: map[string]*configschema.Attribute{
"ami": {Type: cty.String, Optional: true},
"id": {Type: cty.String, Computed: true},
Block: &configschema.Block{
Attributes: map[string]*configschema.Attribute{
"ami": {Type: cty.String, Optional: true},
"id": {Type: cty.String, Computed: true},
},
},
},
},
Expand Down Expand Up @@ -386,13 +387,15 @@ func testOperationApply(t *testing.T, configDir string) (*backend.Operation, fun
// applyFixtureSchema returns a schema suitable for processing the
// configuration in testdata/apply . This schema should be
// assigned to a mock provider named "test".
func applyFixtureSchema() *terraform.ProviderSchema {
return &terraform.ProviderSchema{
ResourceTypes: map[string]*configschema.Block{
func applyFixtureSchema() providers.ProviderSchema {
return providers.ProviderSchema{
ResourceTypes: map[string]providers.Schema{
"test_instance": {
Attributes: map[string]*configschema.Attribute{
"ami": {Type: cty.String, Optional: true},
"id": {Type: cty.String, Computed: true},
Block: &configschema.Block{
Attributes: map[string]*configschema.Attribute{
"ami": {Type: cty.String, Optional: true},
"id": {Type: cty.String, Computed: true},
},
},
},
},
Expand Down
39 changes: 22 additions & 17 deletions internal/backend/local/backend_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/hashicorp/terraform/internal/initwd"
"github.com/hashicorp/terraform/internal/plans"
"github.com/hashicorp/terraform/internal/plans/planfile"
"github.com/hashicorp/terraform/internal/providers"
"github.com/hashicorp/terraform/internal/states"
"github.com/hashicorp/terraform/internal/terminal"
"github.com/hashicorp/terraform/internal/terraform"
Expand Down Expand Up @@ -88,7 +89,7 @@ func TestLocal_planInAutomation(t *testing.T) {

func TestLocal_planNoConfig(t *testing.T) {
b := TestLocal(t)
TestLocalProvider(t, b, "test", &terraform.ProviderSchema{})
TestLocalProvider(t, b, "test", providers.ProviderSchema{})

op, configCleanup, done := testOperationPlan(t, "./testdata/empty")
defer configCleanup()
Expand Down Expand Up @@ -854,30 +855,34 @@ func testReadPlan(t *testing.T, path string) *plans.Plan {
// planFixtureSchema returns a schema suitable for processing the
// configuration in testdata/plan . This schema should be
// assigned to a mock provider named "test".
func planFixtureSchema() *terraform.ProviderSchema {
return &terraform.ProviderSchema{
ResourceTypes: map[string]*configschema.Block{
func planFixtureSchema() providers.ProviderSchema {
return providers.ProviderSchema{
ResourceTypes: map[string]providers.Schema{
"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},
Block: &configschema.Block{
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},
},
},
},
},
},
},
},
DataSources: map[string]*configschema.Block{
DataSources: map[string]providers.Schema{
"test_ds": {
Attributes: map[string]*configschema.Attribute{
"filter": {Type: cty.String, Required: true},
Block: &configschema.Block{
Attributes: map[string]*configschema.Attribute{
"filter": {Type: cty.String, Required: true},
},
},
},
},
Expand Down
56 changes: 33 additions & 23 deletions internal/backend/local/backend_refresh_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,22 @@ test_instance.foo:
func TestLocal_refreshInput(t *testing.T) {
b := TestLocal(t)

schema := &terraform.ProviderSchema{
Provider: &configschema.Block{
Attributes: map[string]*configschema.Attribute{
"value": {Type: cty.String, Optional: true},
schema := providers.ProviderSchema{
Provider: providers.Schema{
Block: &configschema.Block{
Attributes: map[string]*configschema.Attribute{
"value": {Type: cty.String, Optional: true},
},
},
},
ResourceTypes: map[string]*configschema.Block{
ResourceTypes: map[string]providers.Schema{
"test_instance": {
Attributes: map[string]*configschema.Attribute{
"id": {Type: cty.String, Computed: true},
"foo": {Type: cty.String, Optional: true},
"ami": {Type: cty.String, Optional: true},
Block: &configschema.Block{
Attributes: map[string]*configschema.Attribute{
"id": {Type: cty.String, Computed: true},
"foo": {Type: cty.String, Optional: true},
"ami": {Type: cty.String, Optional: true},
},
},
},
},
Expand Down Expand Up @@ -154,17 +158,21 @@ test_instance.foo:
func TestLocal_refreshValidateProviderConfigured(t *testing.T) {
b := TestLocal(t)

schema := &terraform.ProviderSchema{
Provider: &configschema.Block{
Attributes: map[string]*configschema.Attribute{
"value": {Type: cty.String, Optional: true},
schema := providers.ProviderSchema{
Provider: providers.Schema{
Block: &configschema.Block{
Attributes: map[string]*configschema.Attribute{
"value": {Type: cty.String, Optional: true},
},
},
},
ResourceTypes: map[string]*configschema.Block{
ResourceTypes: map[string]providers.Schema{
"test_instance": {
Attributes: map[string]*configschema.Attribute{
"id": {Type: cty.String, Computed: true},
"ami": {Type: cty.String, Optional: true},
Block: &configschema.Block{
Attributes: map[string]*configschema.Attribute{
"id": {Type: cty.String, Computed: true},
"ami": {Type: cty.String, Optional: true},
},
},
},
},
Expand Down Expand Up @@ -297,13 +305,15 @@ func testRefreshState() *states.State {
// refreshFixtureSchema returns a schema suitable for processing the
// configuration in testdata/refresh . This schema should be
// assigned to a mock provider named "test".
func refreshFixtureSchema() *terraform.ProviderSchema {
return &terraform.ProviderSchema{
ResourceTypes: map[string]*configschema.Block{
func refreshFixtureSchema() providers.ProviderSchema {
return providers.ProviderSchema{
ResourceTypes: map[string]providers.Schema{
"test_instance": {
Attributes: map[string]*configschema.Attribute{
"ami": {Type: cty.String, Optional: true},
"id": {Type: cty.String, Computed: true},
Block: &configschema.Block{
Attributes: map[string]*configschema.Attribute{
"ami": {Type: cty.String, Optional: true},
"id": {Type: cty.String, Computed: true},
},
},
},
},
Expand Down
21 changes: 2 additions & 19 deletions internal/backend/local/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,28 +42,11 @@ func TestLocal(t *testing.T) *Local {

// 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.MockProvider {
func TestLocalProvider(t *testing.T, b *Local, name string, schema providers.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.GetProviderSchemaResponse = &providers.GetProviderSchemaResponse{
Provider: providers.Schema{Block: schema.Provider},
ProviderMeta: providers.Schema{Block: schema.ProviderMeta},
ResourceTypes: map[string]providers.Schema{},
DataSources: map[string]providers.Schema{},
}
for name, res := range schema.ResourceTypes {
p.GetProviderSchemaResponse.ResourceTypes[name] = providers.Schema{
Block: res,
Version: int64(schema.ResourceTypeSchemaVersions[name]),
}
}
for name, dat := range schema.DataSources {
p.GetProviderSchemaResponse.DataSources[name] = providers.Schema{Block: dat}
}
p.GetProviderSchemaResponse = &schema

p.PlanResourceChangeFn = func(req providers.PlanResourceChangeRequest) (resp providers.PlanResourceChangeResponse) {
// this is a destroy plan,
Expand Down
10 changes: 6 additions & 4 deletions internal/backend/remote/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,11 +182,13 @@ func testLocalBackend(t *testing.T, remote *Remote) backend.Enhanced {
b := backendLocal.NewWithBackend(remote)

// Add a test provider to the local backend.
p := backendLocal.TestLocalProvider(t, b, "null", &terraform.ProviderSchema{
ResourceTypes: map[string]*configschema.Block{
p := backendLocal.TestLocalProvider(t, b, "null", providers.ProviderSchema{
ResourceTypes: map[string]providers.Schema{
"null_resource": {
Attributes: map[string]*configschema.Attribute{
"id": {Type: cty.String, Computed: true},
Block: &configschema.Block{
Attributes: map[string]*configschema.Attribute{
"id": {Type: cty.String, Computed: true},
},
},
},
},
Expand Down
10 changes: 6 additions & 4 deletions internal/cloud/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -345,11 +345,13 @@ func testLocalBackend(t *testing.T, cloud *Cloud) backend.Enhanced {
b := backendLocal.NewWithBackend(cloud)

// Add a test provider to the local backend.
p := backendLocal.TestLocalProvider(t, b, "null", &terraform.ProviderSchema{
ResourceTypes: map[string]*configschema.Block{
p := backendLocal.TestLocalProvider(t, b, "null", providers.ProviderSchema{
ResourceTypes: map[string]providers.Schema{
"null_resource": {
Attributes: map[string]*configschema.Attribute{
"id": {Type: cty.String, Computed: true},
Block: &configschema.Block{
Attributes: map[string]*configschema.Attribute{
"id": {Type: cty.String, Computed: true},
},
},
},
},
Expand Down
14 changes: 9 additions & 5 deletions internal/command/jsonformat/plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6987,13 +6987,17 @@ func runTestCases(t *testing.T, testCases map[string]testCase) {
}

tfschemas := &terraform.Schemas{
Providers: map[addrs.Provider]*providers.Schemas{
Providers: map[addrs.Provider]providers.ProviderSchema{
src.ProviderAddr.Provider: {
ResourceTypes: map[string]*configschema.Block{
src.Addr.Resource.Resource.Type: tc.Schema,
ResourceTypes: map[string]providers.Schema{
src.Addr.Resource.Resource.Type: {
Block: tc.Schema,
},
},
DataSources: map[string]*configschema.Block{
src.Addr.Resource.Resource.Type: tc.Schema,
DataSources: map[string]providers.Schema{
src.Addr.Resource.Resource.Type: {
Block: tc.Schema,
},
},
},
},
Expand Down
4 changes: 2 additions & 2 deletions internal/command/jsonformat/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ func testProviderSchema() *providers.GetProviderSchemaResponse {
func testSchemas() *terraform.Schemas {
provider := testProvider()
return &terraform.Schemas{
Providers: map[addrs.Provider]*terraform.ProviderSchema{
addrs.NewDefaultProvider("test"): provider.ProviderSchema(),
Providers: map[addrs.Provider]providers.ProviderSchema{
addrs.NewDefaultProvider("test"): provider.GetProviderSchema(),
},
}
}
Expand Down
19 changes: 10 additions & 9 deletions internal/command/jsonplan/values_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/hashicorp/terraform/internal/addrs"
"github.com/hashicorp/terraform/internal/configs/configschema"
"github.com/hashicorp/terraform/internal/plans"
"github.com/hashicorp/terraform/internal/providers"
"github.com/hashicorp/terraform/internal/terraform"
"github.com/zclconf/go-cty/cty"
)
Expand Down Expand Up @@ -344,19 +345,19 @@ func TestMarshalPlanValuesNoopDeposed(t *testing.T) {

func testSchemas() *terraform.Schemas {
return &terraform.Schemas{
Providers: map[addrs.Provider]*terraform.ProviderSchema{
addrs.NewDefaultProvider("test"): &terraform.ProviderSchema{
ResourceTypes: map[string]*configschema.Block{
Providers: map[addrs.Provider]providers.ProviderSchema{
addrs.NewDefaultProvider("test"): providers.ProviderSchema{
ResourceTypes: map[string]providers.Schema{
"test_thing": {
Attributes: map[string]*configschema.Attribute{
"woozles": {Type: cty.String, Optional: true, Computed: true},
"foozles": {Type: cty.String, Optional: true},
Version: 1,
Block: &configschema.Block{
Attributes: map[string]*configschema.Attribute{
"woozles": {Type: cty.String, Optional: true, Computed: true},
"foozles": {Type: cty.String, Optional: true},
},
},
},
},
ResourceTypeSchemaVersions: map[string]uint64{
"test_thing": 1,
},
},
},
}
Expand Down
Loading

0 comments on commit 6be6f69

Please sign in to comment.