Skip to content

Commit

Permalink
Refactor providerbuilder Resource to apply defaults in NewResource (#…
Browse files Browse the repository at this point in the history
…2630)

This PR is a refactor of the test utilities in PF for creating
Resources.

We now have a `NewResource` function to create `pb.Resource` which fills
in reasonable defaults which were previously handled in `NewProvider`.
This in turn will allow us to use `pb.Resource` as an argument in `Diff`
cross-tests.

The concrete use case I am after with this is for `Diff` cross-tests for
Computed properties, which require a custom Create and Update function.
  • Loading branch information
VenelinMartinov authored Nov 19, 2024
1 parent a3ccb9f commit 9f433fd
Show file tree
Hide file tree
Showing 19 changed files with 138 additions and 91 deletions.
7 changes: 6 additions & 1 deletion pkg/pf/tests/diff_list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hexops/autogold/v2"
crosstests "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/pf/tests/internal/cross-tests"
pb "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/pf/tests/internal/providerbuilder"
"github.com/zclconf/go-cty/cty"
)

Expand Down Expand Up @@ -217,8 +218,12 @@ func TestDetailedDiffList(t *testing.T) {
initialValue := schemaValueMakerPair.valueMaker(scenario.initialValue)
changeValue := schemaValueMakerPair.valueMaker(scenario.changeValue)

res := pb.NewResource(pb.NewResourceArgs{
ResourceSchema: schemaValueMakerPair.schema,
})

diff := crosstests.Diff(
t, schemaValueMakerPair.schema, map[string]cty.Value{"key": initialValue}, map[string]cty.Value{"key": changeValue})
t, res, map[string]cty.Value{"key": initialValue}, map[string]cty.Value{"key": changeValue})

autogold.ExpectFile(t, testOutput{
initialValue: scenario.initialValue,
Expand Down
6 changes: 5 additions & 1 deletion pkg/pf/tests/diff_map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hexops/autogold/v2"
crosstests "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/pf/tests/internal/cross-tests"
pb "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/pf/tests/internal/providerbuilder"
"github.com/zclconf/go-cty/cty"
)

Expand Down Expand Up @@ -171,8 +172,11 @@ func TestDetailedDiffMap(t *testing.T) {
t.Parallel()
initialValue := schemaValueMakerPair.valueMaker(scenario.initialValue)
changeValue := schemaValueMakerPair.valueMaker(scenario.changeValue)
res := pb.NewResource(pb.NewResourceArgs{
ResourceSchema: schemaValueMakerPair.schema,
})

diff := crosstests.Diff(t, schemaValueMakerPair.schema, map[string]cty.Value{"key": initialValue}, map[string]cty.Value{"key": changeValue})
diff := crosstests.Diff(t, res, map[string]cty.Value{"key": initialValue}, map[string]cty.Value{"key": changeValue})

autogold.ExpectFile(t, testOutput{
initialValue: scenario.initialValue,
Expand Down
11 changes: 9 additions & 2 deletions pkg/pf/tests/diff_object_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
"github.com/hexops/autogold/v2"
crosstests "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/pf/tests/internal/cross-tests"
pb "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/pf/tests/internal/providerbuilder"
"github.com/zclconf/go-cty/cty"
)

Expand Down Expand Up @@ -331,7 +332,10 @@ func TestDetailedDiffObject(t *testing.T) {
t.Parallel()
initialValue := map[string]cty.Value{"key": makeValue(scenario.initialValue)}
changeValue := map[string]cty.Value{"key": makeValue(scenario.changeValue)}
diff := crosstests.Diff(t, schema.schema, initialValue, changeValue)
res := pb.NewResource(pb.NewResourceArgs{
ResourceSchema: schema.schema,
})
diff := crosstests.Diff(t, res, initialValue, changeValue)
autogold.ExpectFile(t, testOutput{
initialValue: scenario.initialValue,
changeValue: scenario.changeValue,
Expand All @@ -347,7 +351,10 @@ func TestDetailedDiffObject(t *testing.T) {
t.Parallel()
initialValue := map[string]cty.Value{"key": makeValue(scenario.initialValue)}
changeValue := map[string]cty.Value{"key": makeValue(scenario.changeValue)}
diff := crosstests.Diff(t, schema.schema, initialValue, changeValue)
res := pb.NewResource(pb.NewResourceArgs{
ResourceSchema: schema.schema,
})
diff := crosstests.Diff(t, res, initialValue, changeValue)
autogold.ExpectFile(t, testOutput{
initialValue: scenario.initialValue,
changeValue: scenario.changeValue,
Expand Down
6 changes: 5 additions & 1 deletion pkg/pf/tests/diff_set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hexops/autogold/v2"
crosstests "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/pf/tests/internal/cross-tests"
pb "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/pf/tests/internal/providerbuilder"
"github.com/zclconf/go-cty/cty"
)

Expand Down Expand Up @@ -225,7 +226,10 @@ func TestDetailedDiffSet(t *testing.T) {
initialValue := schemaValueMakerPair.valueMaker(scenario.initialValue)
changeValue := schemaValueMakerPair.valueMaker(scenario.changeValue)

diff := crosstests.Diff(t, schemaValueMakerPair.schema, map[string]cty.Value{"key": initialValue}, map[string]cty.Value{"key": changeValue})
res := pb.NewResource(pb.NewResourceArgs{
ResourceSchema: schemaValueMakerPair.schema,
})
diff := crosstests.Diff(t, res, map[string]cty.Value{"key": initialValue}, map[string]cty.Value{"key": changeValue})

autogold.ExpectFile(t, testOutput{
initialValue: scenario.initialValue,
Expand Down
19 changes: 13 additions & 6 deletions pkg/pf/tests/diff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
"github.com/hexops/autogold/v2"
crosstests "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/pf/tests/internal/cross-tests"
pb "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/pf/tests/internal/providerbuilder"
"github.com/zclconf/go-cty/cty"
)

Expand All @@ -25,7 +26,10 @@ func TestSimpleNoDiff(t *testing.T) {
},
}

res := crosstests.Diff(t, sch,
res := pb.NewResource(pb.NewResourceArgs{
ResourceSchema: sch,
})
diff := crosstests.Diff(t, res,
map[string]cty.Value{"key": cty.StringVal("value")},
map[string]cty.Value{"key": cty.StringVal("value1")},
)
Expand All @@ -45,7 +49,7 @@ Terraform will perform the following actions:
Plan: 0 to add, 1 to change, 0 to destroy.
`).Equal(t, res.TFOut)
`).Equal(t, diff.TFOut)
autogold.Expect(`Previewing update (test):
pulumi:pulumi:Stack: (same)
[urn=urn:pulumi:test::project::pulumi:pulumi:Stack::project-test]
Expand All @@ -56,7 +60,7 @@ Plan: 0 to add, 1 to change, 0 to destroy.
Resources:
~ 1 to update
1 unchanged
`).Equal(t, res.PulumiOut)
`).Equal(t, diff.PulumiOut)
}

type stringDefault string
Expand Down Expand Up @@ -186,13 +190,16 @@ func TestDetailedDiffStringAttribute(t *testing.T) {
initialValue := makeValue(scenario.initialValue)
changeValue := makeValue(scenario.changeValue)

res := crosstests.Diff(t, schema.schema, map[string]cty.Value{"key": initialValue}, map[string]cty.Value{"key": changeValue})
res := pb.NewResource(pb.NewResourceArgs{
ResourceSchema: schema.schema,
})
diff := crosstests.Diff(t, res, map[string]cty.Value{"key": initialValue}, map[string]cty.Value{"key": changeValue})

autogold.ExpectFile(t, testOutput{
initialValue: scenario.initialValue,
changeValue: scenario.changeValue,
tfOut: res.TFOut,
pulumiOut: res.PulumiOut,
tfOut: diff.TFOut,
pulumiOut: diff.PulumiOut,
})
})
}
Expand Down
8 changes: 4 additions & 4 deletions pkg/pf/tests/dynamic_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ func TestCreateResourceWithDynamicAttribute(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
r := pb.Resource{
r := pb.NewResource(pb.NewResourceArgs{
Name: "r",
CreateFunc: func(
ctx context.Context,
Expand Down Expand Up @@ -266,10 +266,10 @@ func TestCreateResourceWithDynamicAttribute(t *testing.T) {
},
},
},
}
})

// Define an aux resource to produce unknown values for testing.
r0 := pb.Resource{
r0 := pb.NewResource(pb.NewResourceArgs{
Name: "r0",
CreateFunc: func(
ctx context.Context,
Expand Down Expand Up @@ -298,7 +298,7 @@ func TestCreateResourceWithDynamicAttribute(t *testing.T) {
},
},
},
}
})

p := pb.NewProvider(pb.NewProviderArgs{
AllResources: []pb.Resource{r, r0},
Expand Down
4 changes: 2 additions & 2 deletions pkg/pf/tests/extract_inputs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -904,10 +904,10 @@ func TestExtractInputsFromOutputsPF(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
prov := pb.NewProvider(pb.NewProviderArgs{
AllResources: []pb.Resource{
{
pb.NewResource(pb.NewResourceArgs{
Name: "test",
ResourceSchema: tc.resSchema,
},
}),
},
})

Expand Down
8 changes: 5 additions & 3 deletions pkg/pf/tests/internal/cross-tests/configure.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,11 @@ func Configure(t T, schema pschema.Schema, tfConfig map[string]cty.Value, option
ConfigureFunc: func(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
*config = req.Config
},
AllResources: []pb.Resource{{
Name: "res",
}},
AllResources: []pb.Resource{
pb.NewResource(pb.NewResourceArgs{
Name: "res",
}),
},
})
}

Expand Down
10 changes: 3 additions & 7 deletions pkg/pf/tests/internal/cross-tests/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ package crosstests
import (
"bytes"

rschema "github.com/hashicorp/terraform-plugin-framework/resource/schema"
crosstests "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/internal/tests/cross-tests"
crosstestsimpl "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/internal/tests/cross-tests/impl"
"github.com/pulumi/pulumi-terraform-bridge/v3/pkg/internal/tests/cross-tests/impl/hclwrite"
Expand Down Expand Up @@ -50,7 +49,7 @@ func yamlResource(t T, properties resource.PropertyMap) map[string]any {
// when computed by Terraform and Pulumi.
//
// Diff should be safe to run in parallel.
func Diff(t T, schema rschema.Schema, tfConfig1, tfConfig2 map[string]cty.Value, options ...DiffOption) crosstestsimpl.DiffResult {
func Diff(t T, res pb.Resource, tfConfig1, tfConfig2 map[string]cty.Value, options ...DiffOption) crosstestsimpl.DiffResult {
skipUnlessLinux(t)

var opts diffOpts
Expand All @@ -59,18 +58,15 @@ func Diff(t T, schema rschema.Schema, tfConfig1, tfConfig2 map[string]cty.Value,
}

prov := pb.NewProvider(pb.NewProviderArgs{
AllResources: []pb.Resource{{
Name: "test",
ResourceSchema: schema,
}},
AllResources: []pb.Resource{res},
})

shimProvider := tfbridge.ShimProvider(prov)

// Run the TF part
var hcl1 bytes.Buffer

sch := hclSchemaPFResource(schema)
sch := hclSchemaPFResource(res.ResourceSchema)
err := hclwrite.WriteResource(&hcl1, sch, "testprovider_test", "res", tfConfig1,
hclwrite.WithCreateBeforeDestroy(true))
require.NoError(t, err)
Expand Down
8 changes: 4 additions & 4 deletions pkg/pf/tests/internal/pftfcheck/pftf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ func TestBasic(t *testing.T) {
t.Parallel()
prov := pb.NewProvider(pb.NewProviderArgs{
AllResources: []pb.Resource{
{
pb.NewResource(pb.NewResourceArgs{
Name: "res",
ResourceSchema: rschema.Schema{
Attributes: map[string]rschema.Attribute{
"s": rschema.StringAttribute{Optional: true},
},
},
},
}),
},
})

Expand All @@ -48,7 +48,7 @@ func TestDefaults(t *testing.T) {
t.Parallel()
prov := pb.NewProvider(pb.NewProviderArgs{
AllResources: []pb.Resource{
{
pb.NewResource(pb.NewResourceArgs{
Name: "res",
ResourceSchema: rschema.Schema{
Attributes: map[string]rschema.Attribute{
Expand All @@ -59,7 +59,7 @@ func TestDefaults(t *testing.T) {
},
},
},
},
}),
},
})

Expand Down
31 changes: 0 additions & 31 deletions pkg/pf/tests/internal/providerbuilder/build_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,10 @@ import (

"github.com/hashicorp/terraform-plugin-framework/datasource"
dschema "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/provider"
"github.com/hashicorp/terraform-plugin-framework/provider/schema"
"github.com/hashicorp/terraform-plugin-framework/providerserver"
"github.com/hashicorp/terraform-plugin-framework/resource"
rschema "github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
)
Expand Down Expand Up @@ -114,33 +110,6 @@ func NewProvider(params NewProviderArgs) *Provider {
prov.Version = "0.0.1"
}

for i := range prov.AllResources {
r := &prov.AllResources[i]
if r.ResourceSchema.Attributes == nil {
r.ResourceSchema.Attributes = map[string]rschema.Attribute{}
}

if r.ResourceSchema.Attributes["id"] == nil {
r.ResourceSchema.Attributes["id"] = rschema.StringAttribute{
Computed: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
}
}
if r.CreateFunc == nil {
r.CreateFunc = func(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
resp.State = tfsdk.State(req.Plan)
resp.State.SetAttribute(ctx, path.Root("id"), "test-id")
}
}
if r.UpdateFunc == nil {
r.UpdateFunc = func(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
resp.State = tfsdk.State(req.Plan)
}
}
}

for i := range prov.AllDataSources {
d := &prov.AllDataSources[i]
if d.DataSourceSchema.Attributes == nil {
Expand Down
51 changes: 51 additions & 0 deletions pkg/pf/tests/internal/providerbuilder/build_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,61 @@ package providerbuilder
import (
"context"

"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
)

type NewResourceArgs struct {
// Name is the name of the resource. Defaults to "test".
Name string
ResourceSchema schema.Schema

CreateFunc func(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse)
ReadFunc func(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse)
UpdateFunc func(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse)
DeleteFunc func(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse)
ImportStateFunc func(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse)
}

// NewResource creates a new Resource with the given parameters, filling reasonable defaults.
func NewResource(args NewResourceArgs) Resource {
if args.Name == "" {
args.Name = "test"
}

if args.ResourceSchema.Attributes == nil {
args.ResourceSchema.Attributes = map[string]schema.Attribute{}
}

if args.ResourceSchema.Attributes["id"] == nil {
args.ResourceSchema.Attributes["id"] = schema.StringAttribute{
Computed: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
}
}

if args.CreateFunc == nil {
args.CreateFunc = func(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
resp.State = tfsdk.State(req.Plan)
resp.State.SetAttribute(ctx, path.Root("id"), "test-id")
}
}
if args.UpdateFunc == nil {
args.UpdateFunc = func(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
resp.State = tfsdk.State(req.Plan)
}
}

return Resource(args)
}

// Resource is a utility type that helps define PF resources. Prefer creating via NewResource.
type Resource struct {
Name string
ResourceSchema schema.Schema
Expand Down
Loading

0 comments on commit 9f433fd

Please sign in to comment.