Skip to content

Commit

Permalink
Add SDKv2 Detailed Diff tests for list replacements
Browse files Browse the repository at this point in the history
  • Loading branch information
VenelinMartinov committed Dec 13, 2024
1 parent f94f380 commit bca1c95
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 bca1c95

Please sign in to comment.