Skip to content

Commit

Permalink
Add SDKv2 Detailed Diff tests for list replacements (#2735)
Browse files Browse the repository at this point in the history
This adds Detailed Diff tests for the SDKv2 bridge for lists with
ForceNew. Some of the tests are skipped because of
#2726
  • Loading branch information
VenelinMartinov authored Dec 13, 2024
1 parent f94f380 commit 82a4eec
Show file tree
Hide file tree
Showing 34 changed files with 1,271 additions and 0 deletions.
108 changes: 108 additions & 0 deletions pkg/tests/detailed_diff_list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,17 @@ func TestDetailedDiffList(t *testing.T) {
},
}

listAttrSchemaForceNew := schema.Resource{
Schema: map[string]*schema.Schema{
"list_attr": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
ForceNew: true,
},
},
}

maxItemsOneAttrSchema := schema.Resource{
Schema: map[string]*schema.Schema{
"list_attr": {
Expand All @@ -34,6 +45,18 @@ func TestDetailedDiffList(t *testing.T) {
},
}

maxItemsOneAttrSchemaForceNew := schema.Resource{
Schema: map[string]*schema.Schema{
"list_attr": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Schema{Type: schema.TypeString},
ForceNew: true,
},
},
}

listBlockSchema := schema.Resource{
Schema: map[string]*schema.Schema{
"list_block": {
Expand All @@ -51,6 +74,43 @@ func TestDetailedDiffList(t *testing.T) {
},
}

listBlockSchemaForceNew := schema.Resource{
Schema: map[string]*schema.Schema{
"list_block": {
Type: schema.TypeList,
Optional: true,
ForceNew: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"prop": {
Type: schema.TypeString,
Optional: true,
},
},
},
},
},
}

listBlockSchemaNestedForceNew := schema.Resource{
Schema: map[string]*schema.Schema{
"list_block": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"nested_prop": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
},
},
},
},
}
_ = listBlockSchemaNestedForceNew

maxItemsOneBlockSchema := schema.Resource{
Schema: map[string]*schema.Schema{
"list_block": {
Expand All @@ -69,6 +129,46 @@ func TestDetailedDiffList(t *testing.T) {
},
}

maxItemsOneBlockSchemaForceNew := schema.Resource{
Schema: map[string]*schema.Schema{
"list_block": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
ForceNew: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"nested_prop": {
Type: schema.TypeString,
Optional: true,
},
},
},
},
},
}
_ = maxItemsOneBlockSchemaForceNew

maxItemsOneBlockSchemaNestedForceNew := schema.Resource{
Schema: map[string]*schema.Schema{
"list_block": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"nested_prop": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
},
},
},
},
}
_ = maxItemsOneBlockSchemaNestedForceNew

attrList := func(arr *[]string) map[string]cty.Value {
if arr == nil {
return map[string]cty.Value{}
Expand Down Expand Up @@ -135,7 +235,11 @@ func TestDetailedDiffList(t *testing.T) {
valueMaker func(*[]string) map[string]cty.Value
}{
{"list attribute", listAttrSchema, attrList},
{"list attribute force new", listAttrSchemaForceNew, attrList},
{"list block", listBlockSchema, blockList},
{"list block force new", listBlockSchemaForceNew, blockList},
// TODO[pulumi/pulumi-terraform-bridge#2726]: These tests fail to produce the correct replacement plan
// {"list block nested force new", listBlockSchemaNestedForceNew, blockList},
}

maxItemsOnePairs := []struct {
Expand All @@ -144,7 +248,11 @@ func TestDetailedDiffList(t *testing.T) {
valueMaker func(*[]string) map[string]cty.Value
}{
{"max items one attribute", maxItemsOneAttrSchema, attrList},
{"max items one attribute force new", maxItemsOneAttrSchemaForceNew, attrList},
{"max items one block", maxItemsOneBlockSchema, nestedBlockList},
// TODO[pulumi/pulumi-terraform-bridge#2726]: These tests fail to produce the correct replacement plan
// {"max items one block force new", maxItemsOneBlockSchemaForceNew, nestedBlockList},
// {"max items one block nested force new", maxItemsOneBlockSchemaNestedForceNew, nestedBlockList},
}

oneElementScenarios := []struct {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
tests.testOutput{
changeValue: &[]string{},
tfOut: `
No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration
and found no differences, so no changes are needed.
`,
pulumiOut: `Previewing update (test):
pulumi:pulumi:Stack: (same)
[urn=urn:pulumi:test::project::pulumi:pulumi:Stack::project-test]
Resources:
2 unchanged
`,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
tests.testOutput{
changeValue: &[]string{
"val1",
},
tfOut: `
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+/- create replacement and then destroy

Terraform will perform the following actions:

# crossprovider_test_res.example must be replaced
+/- resource "crossprovider_test_res" "example" {
~ id = "newid" -> (known after apply)
+ list_attr = [ # forces replacement
+ "val1",
]
}

Plan: 1 to add, 0 to change, 1 to destroy.

`,
pulumiOut: `Previewing update (test):
pulumi:pulumi:Stack: (same)
[urn=urn:pulumi:test::project::pulumi:pulumi:Stack::project-test]
+-crossprovider:index/testRes:TestRes: (replace)
[id=newid]
[urn=urn:pulumi:test::project::crossprovider:index/testRes:TestRes::example]
+ listAttrs: [
+ [0]: "val1"
]
Resources:
+-1 to replace
1 unchanged
`,
detailedDiff: map[string]interface{}{"listAttrs": map[string]interface{}{"kind": "ADD_REPLACE"}},
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
tests.testOutput{
initialValue: &[]string{
"val1",
},
changeValue: &[]string{"val2"},
tfOut: `
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+/- create replacement and then destroy

Terraform will perform the following actions:

# crossprovider_test_res.example must be replaced
+/- resource "crossprovider_test_res" "example" {
~ id = "newid" -> (known after apply)
~ list_attr = [ # forces replacement
~ "val1" -> "val2",
]
}

Plan: 1 to add, 0 to change, 1 to destroy.

`,
pulumiOut: `Previewing update (test):
pulumi:pulumi:Stack: (same)
[urn=urn:pulumi:test::project::pulumi:pulumi:Stack::project-test]
+-crossprovider:index/testRes:TestRes: (replace)
[id=newid]
[urn=urn:pulumi:test::project::crossprovider:index/testRes:TestRes::example]
~ listAttrs: [
~ [0]: "val1" => "val2"
]
Resources:
+-1 to replace
1 unchanged
`,
detailedDiff: map[string]interface{}{"listAttrs[0]": map[string]interface{}{"kind": "UPDATE_REPLACE"}},
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
tests.testOutput{
initialValue: &[]string{
"val1",
"val2",
},
changeValue: &[]string{
"val1",
"val2",
"val3",
},
tfOut: `
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+/- create replacement and then destroy

Terraform will perform the following actions:

# crossprovider_test_res.example must be replaced
+/- resource "crossprovider_test_res" "example" {
~ id = "newid" -> (known after apply)
~ list_attr = [ # forces replacement
# (1 unchanged element hidden)
"val2",
+ "val3",
]
}

Plan: 1 to add, 0 to change, 1 to destroy.

`,
pulumiOut: `Previewing update (test):
pulumi:pulumi:Stack: (same)
[urn=urn:pulumi:test::project::pulumi:pulumi:Stack::project-test]
+-crossprovider:index/testRes:TestRes: (replace)
[id=newid]
[urn=urn:pulumi:test::project::crossprovider:index/testRes:TestRes::example]
~ listAttrs: [
+ [2]: "val3"
]
Resources:
+-1 to replace
1 unchanged
`,
detailedDiff: map[string]interface{}{"listAttrs[2]": map[string]interface{}{"kind": "ADD_REPLACE"}},
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
tests.testOutput{
initialValue: &[]string{
"val2",
"val3",
},
changeValue: &[]string{
"val1",
"val2",
"val3",
},
tfOut: `
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+/- create replacement and then destroy

Terraform will perform the following actions:

# crossprovider_test_res.example must be replaced
+/- resource "crossprovider_test_res" "example" {
~ id = "newid" -> (known after apply)
~ list_attr = [ # forces replacement
+ "val1",
"val2",
# (1 unchanged element hidden)
]
}

Plan: 1 to add, 0 to change, 1 to destroy.

`,
pulumiOut: `Previewing update (test):
pulumi:pulumi:Stack: (same)
[urn=urn:pulumi:test::project::pulumi:pulumi:Stack::project-test]
+-crossprovider:index/testRes:TestRes: (replace)
[id=newid]
[urn=urn:pulumi:test::project::crossprovider:index/testRes:TestRes::example]
~ listAttrs: [
~ [0]: "val2" => "val1"
~ [1]: "val3" => "val2"
+ [2]: "val3"
]
Resources:
+-1 to replace
1 unchanged
`,
detailedDiff: map[string]interface{}{
"listAttrs[0]": map[string]interface{}{"kind": "UPDATE_REPLACE"},
"listAttrs[1]": map[string]interface{}{"kind": "UPDATE_REPLACE"},
"listAttrs[2]": map[string]interface{}{"kind": "ADD_REPLACE"},
},
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
tests.testOutput{
initialValue: &[]string{
"val1",
"val3",
},
changeValue: &[]string{
"val1",
"val2",
"val3",
},
tfOut: `
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+/- create replacement and then destroy

Terraform will perform the following actions:

# crossprovider_test_res.example must be replaced
+/- resource "crossprovider_test_res" "example" {
~ id = "newid" -> (known after apply)
~ list_attr = [ # forces replacement
"val1",
+ "val2",
"val3",
]
}

Plan: 1 to add, 0 to change, 1 to destroy.

`,
pulumiOut: `Previewing update (test):
pulumi:pulumi:Stack: (same)
[urn=urn:pulumi:test::project::pulumi:pulumi:Stack::project-test]
+-crossprovider:index/testRes:TestRes: (replace)
[id=newid]
[urn=urn:pulumi:test::project::crossprovider:index/testRes:TestRes::example]
~ listAttrs: [
~ [1]: "val3" => "val2"
+ [2]: "val3"
]
Resources:
+-1 to replace
1 unchanged
`,
detailedDiff: map[string]interface{}{
"listAttrs[1]": map[string]interface{}{"kind": "UPDATE_REPLACE"},
"listAttrs[2]": map[string]interface{}{"kind": "ADD_REPLACE"},
},
}
Loading

0 comments on commit 82a4eec

Please sign in to comment.