Skip to content

Commit fd5a1e8

Browse files
PF cross-tests for computed set attributes
1 parent 20a909d commit fd5a1e8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1758
-14
lines changed

pkg/pf/tests/diff_set_test.go

Lines changed: 92 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"testing"
66

7+
"github.com/hashicorp/terraform-plugin-framework/attr"
78
"github.com/hashicorp/terraform-plugin-framework/resource"
89
rschema "github.com/hashicorp/terraform-plugin-framework/resource/schema"
910
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
@@ -151,7 +152,80 @@ func TestDetailedDiffSet(t *testing.T) {
151152
},
152153
})
153154

154-
computedCreateFunc := func(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
155+
computedAttributeCreateFunc := func(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
156+
type ObjectModel struct {
157+
ID types.String `tfsdk:"id"`
158+
Keys types.Set `tfsdk:"key"`
159+
}
160+
reqVal := ObjectModel{}
161+
diags := req.Plan.Get(ctx, &reqVal)
162+
contract.Assertf(diags.ErrorsCount() == 0, "failed to get attribute: %v", diags)
163+
164+
respVal := ObjectModel{
165+
ID: types.StringValue("test-id"),
166+
}
167+
if reqVal.Keys.IsUnknown() {
168+
respVal.Keys = types.SetValueMust(types.StringType, []attr.Value{
169+
types.StringValue("value"),
170+
})
171+
} else {
172+
respVal.Keys = reqVal.Keys
173+
}
174+
175+
diags = resp.State.Set(ctx, &respVal)
176+
contract.Assertf(diags.ErrorsCount() == 0, "failed to set attribute: %v", diags)
177+
}
178+
179+
computedAttributeUpdateFunc := func(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
180+
createResp := resource.CreateResponse{
181+
State: resp.State,
182+
Diagnostics: resp.Diagnostics,
183+
}
184+
computedAttributeCreateFunc(ctx, resource.CreateRequest{
185+
Plan: req.Plan,
186+
Config: req.Config,
187+
ProviderMeta: req.ProviderMeta,
188+
}, &createResp)
189+
resp.State = createResp.State
190+
resp.Diagnostics = createResp.Diagnostics
191+
}
192+
193+
computedSetAttributeSchema := pb.NewResource(pb.NewResourceArgs{
194+
ResourceSchema: rschema.Schema{
195+
Attributes: map[string]rschema.Attribute{
196+
"key": rschema.SetAttribute{
197+
Optional: true,
198+
ElementType: types.StringType,
199+
Computed: true,
200+
PlanModifiers: []planmodifier.Set{
201+
setplanmodifier.UseStateForUnknown(),
202+
},
203+
},
204+
},
205+
},
206+
CreateFunc: computedAttributeCreateFunc,
207+
UpdateFunc: computedAttributeUpdateFunc,
208+
})
209+
210+
computedSetAttributeReplaceSchema := pb.NewResource(pb.NewResourceArgs{
211+
ResourceSchema: rschema.Schema{
212+
Attributes: map[string]rschema.Attribute{
213+
"key": rschema.SetAttribute{
214+
Optional: true,
215+
ElementType: types.StringType,
216+
Computed: true,
217+
PlanModifiers: []planmodifier.Set{
218+
setplanmodifier.RequiresReplace(),
219+
setplanmodifier.UseStateForUnknown(),
220+
},
221+
},
222+
},
223+
},
224+
CreateFunc: computedAttributeCreateFunc,
225+
UpdateFunc: computedAttributeUpdateFunc,
226+
})
227+
228+
computedBlockCreateFunc := func(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
155229
type Nested struct {
156230
Nested types.String `tfsdk:"nested"`
157231
Computed types.String `tfsdk:"computed"`
@@ -192,12 +266,12 @@ func TestDetailedDiffSet(t *testing.T) {
192266
contract.Assertf(diags.ErrorsCount() == 0, "failed to set attribute: %v", diags)
193267
}
194268

195-
computedUpdateFunc := func(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
269+
computedBlockUpdateFunc := func(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
196270
createResp := resource.CreateResponse{
197271
State: resp.State,
198272
Diagnostics: resp.Diagnostics,
199273
}
200-
computedCreateFunc(ctx, resource.CreateRequest{
274+
computedBlockCreateFunc(ctx, resource.CreateRequest{
201275
Plan: req.Plan,
202276
Config: req.Config,
203277
ProviderMeta: req.ProviderMeta,
@@ -226,8 +300,8 @@ func TestDetailedDiffSet(t *testing.T) {
226300
},
227301
},
228302
},
229-
CreateFunc: computedCreateFunc,
230-
UpdateFunc: computedUpdateFunc,
303+
CreateFunc: computedBlockCreateFunc,
304+
UpdateFunc: computedBlockUpdateFunc,
231305
})
232306

233307
blockSchemaWithComputedNoStateForUnknown := pb.NewResource(pb.NewResourceArgs{
@@ -246,8 +320,8 @@ func TestDetailedDiffSet(t *testing.T) {
246320
},
247321
},
248322
},
249-
CreateFunc: computedCreateFunc,
250-
UpdateFunc: computedUpdateFunc,
323+
CreateFunc: computedBlockCreateFunc,
324+
UpdateFunc: computedBlockUpdateFunc,
251325
})
252326

253327
blockSchemaWithComputedReplace := pb.NewResource(pb.NewResourceArgs{
@@ -272,8 +346,8 @@ func TestDetailedDiffSet(t *testing.T) {
272346
},
273347
},
274348
},
275-
CreateFunc: computedCreateFunc,
276-
UpdateFunc: computedUpdateFunc,
349+
CreateFunc: computedBlockCreateFunc,
350+
UpdateFunc: computedBlockUpdateFunc,
277351
})
278352

279353
blockSchemaWithComputedNestedReplace := pb.NewResource(pb.NewResourceArgs{
@@ -300,8 +374,8 @@ func TestDetailedDiffSet(t *testing.T) {
300374
},
301375
},
302376
},
303-
CreateFunc: computedCreateFunc,
304-
UpdateFunc: computedUpdateFunc,
377+
CreateFunc: computedBlockCreateFunc,
378+
UpdateFunc: computedBlockUpdateFunc,
305379
})
306380

307381
blockSchemaWithComputedComputedRequiresReplace := pb.NewResource(pb.NewResourceArgs{
@@ -324,8 +398,8 @@ func TestDetailedDiffSet(t *testing.T) {
324398
},
325399
},
326400
},
327-
CreateFunc: computedCreateFunc,
328-
UpdateFunc: computedUpdateFunc,
401+
CreateFunc: computedBlockCreateFunc,
402+
UpdateFunc: computedBlockUpdateFunc,
329403
})
330404

331405
attrList := func(arr *[]string) cty.Value {
@@ -393,7 +467,11 @@ func TestDetailedDiffSet(t *testing.T) {
393467
{"block requires replace", blockReplaceSchema, nestedAttrList},
394468
{"block nested requires replace", blockNestedReplaceSchema, nestedAttrList},
395469

396-
// Computed, each state we test both the behaviour when the computed value is specified in the program and when it is not.
470+
// Computed attributes
471+
{"attribute with computed no replace", computedSetAttributeSchema, attrList},
472+
{"attribute with computed requires replace", computedSetAttributeReplaceSchema, attrList},
473+
474+
// Computed blocks, each state we test both the behaviour when the computed value is specified in the program and when it is not.
397475
{"block with computed no replace computed", blockSchemaWithComputed, nestedAttrList},
398476
{"block with computed no replace computed specified in program", blockSchemaWithComputed, nestedAttrListWithComputedSpecified},
399477
{"block with computed requires replace", blockSchemaWithComputedReplace, nestedAttrList},
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
tfbridgetests.testOutput{
2+
initialValue: &[]string{},
3+
changeValue: &[]string{"value"},
4+
tfOut: `
5+
Terraform used the selected providers to generate the following execution
6+
plan. Resource actions are indicated with the following symbols:
7+
~ update in-place
8+
9+
Terraform will perform the following actions:
10+
11+
# testprovider_test.res will be updated in-place
12+
~ resource "testprovider_test" "res" {
13+
id = "test-id"
14+
~ key = [
15+
+ "value",
16+
]
17+
}
18+
19+
Plan: 0 to add, 1 to change, 0 to destroy.
20+
21+
`,
22+
pulumiOut: `Previewing update (test):
23+
pulumi:pulumi:Stack: (same)
24+
[urn=urn:pulumi:test::project::pulumi:pulumi:Stack::project-test]
25+
~ testprovider:index/test:Test: (update)
26+
[id=test-id]
27+
[urn=urn:pulumi:test::project::testprovider:index/test:Test::p]
28+
~ keys: [
29+
+ [0]: "value"
30+
]
31+
Resources:
32+
~ 1 to update
33+
1 unchanged
34+
`,
35+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
tfbridgetests.testOutput{
2+
initialValue: &[]string{
3+
"val1",
4+
"val2",
5+
},
6+
changeValue: &[]string{
7+
"val1",
8+
"val2",
9+
"val3",
10+
},
11+
tfOut: `
12+
Terraform used the selected providers to generate the following execution
13+
plan. Resource actions are indicated with the following symbols:
14+
~ update in-place
15+
16+
Terraform will perform the following actions:
17+
18+
# testprovider_test.res will be updated in-place
19+
~ resource "testprovider_test" "res" {
20+
id = "test-id"
21+
~ key = [
22+
+ "val3",
23+
# (2 unchanged elements hidden)
24+
]
25+
}
26+
27+
Plan: 0 to add, 1 to change, 0 to destroy.
28+
29+
`,
30+
pulumiOut: `Previewing update (test):
31+
pulumi:pulumi:Stack: (same)
32+
[urn=urn:pulumi:test::project::pulumi:pulumi:Stack::project-test]
33+
~ testprovider:index/test:Test: (update)
34+
[id=test-id]
35+
[urn=urn:pulumi:test::project::testprovider:index/test:Test::p]
36+
~ keys: [
37+
[0]: "val1"
38+
[1]: "val2"
39+
+ [2]: "val3"
40+
]
41+
Resources:
42+
~ 1 to update
43+
1 unchanged
44+
`,
45+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
tfbridgetests.testOutput{
2+
initialValue: &[]string{
3+
"val2",
4+
"val3",
5+
},
6+
changeValue: &[]string{
7+
"val2",
8+
"val3",
9+
"val1",
10+
},
11+
tfOut: `
12+
Terraform used the selected providers to generate the following execution
13+
plan. Resource actions are indicated with the following symbols:
14+
~ update in-place
15+
16+
Terraform will perform the following actions:
17+
18+
# testprovider_test.res will be updated in-place
19+
~ resource "testprovider_test" "res" {
20+
id = "test-id"
21+
~ key = [
22+
+ "val1",
23+
# (2 unchanged elements hidden)
24+
]
25+
}
26+
27+
Plan: 0 to add, 1 to change, 0 to destroy.
28+
29+
`,
30+
pulumiOut: `Previewing update (test):
31+
pulumi:pulumi:Stack: (same)
32+
[urn=urn:pulumi:test::project::pulumi:pulumi:Stack::project-test]
33+
~ testprovider:index/test:Test: (update)
34+
[id=test-id]
35+
[urn=urn:pulumi:test::project::testprovider:index/test:Test::p]
36+
~ keys: [
37+
[0]: "val2"
38+
[1]: "val3"
39+
+ [2]: "val1"
40+
]
41+
Resources:
42+
~ 1 to update
43+
1 unchanged
44+
`,
45+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
tfbridgetests.testOutput{
2+
initialValue: &[]string{
3+
"val2",
4+
"val3",
5+
},
6+
changeValue: &[]string{
7+
"val1",
8+
"val2",
9+
"val3",
10+
},
11+
tfOut: `
12+
Terraform used the selected providers to generate the following execution
13+
plan. Resource actions are indicated with the following symbols:
14+
~ update in-place
15+
16+
Terraform will perform the following actions:
17+
18+
# testprovider_test.res will be updated in-place
19+
~ resource "testprovider_test" "res" {
20+
id = "test-id"
21+
~ key = [
22+
+ "val1",
23+
# (2 unchanged elements hidden)
24+
]
25+
}
26+
27+
Plan: 0 to add, 1 to change, 0 to destroy.
28+
29+
`,
30+
pulumiOut: `Previewing update (test):
31+
pulumi:pulumi:Stack: (same)
32+
[urn=urn:pulumi:test::project::pulumi:pulumi:Stack::project-test]
33+
~ testprovider:index/test:Test: (update)
34+
[id=test-id]
35+
[urn=urn:pulumi:test::project::testprovider:index/test:Test::p]
36+
~ keys: [
37+
~ [0]: "val2" => "val1"
38+
~ [1]: "val3" => "val2"
39+
+ [2]: "val3"
40+
]
41+
Resources:
42+
~ 1 to update
43+
1 unchanged
44+
`,
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
tfbridgetests.testOutput{
2+
initialValue: &[]string{
3+
"val3",
4+
"val1",
5+
},
6+
changeValue: &[]string{
7+
"val2",
8+
"val3",
9+
"val1",
10+
},
11+
tfOut: `
12+
Terraform used the selected providers to generate the following execution
13+
plan. Resource actions are indicated with the following symbols:
14+
~ update in-place
15+
16+
Terraform will perform the following actions:
17+
18+
# testprovider_test.res will be updated in-place
19+
~ resource "testprovider_test" "res" {
20+
id = "test-id"
21+
~ key = [
22+
+ "val2",
23+
# (2 unchanged elements hidden)
24+
]
25+
}
26+
27+
Plan: 0 to add, 1 to change, 0 to destroy.
28+
29+
`,
30+
pulumiOut: `Previewing update (test):
31+
pulumi:pulumi:Stack: (same)
32+
[urn=urn:pulumi:test::project::pulumi:pulumi:Stack::project-test]
33+
~ testprovider:index/test:Test: (update)
34+
[id=test-id]
35+
[urn=urn:pulumi:test::project::testprovider:index/test:Test::p]
36+
~ keys: [
37+
~ [0]: "val3" => "val2"
38+
~ [1]: "val1" => "val3"
39+
+ [2]: "val1"
40+
]
41+
Resources:
42+
~ 1 to update
43+
1 unchanged
44+
`,
45+
}

0 commit comments

Comments
 (0)