From f1d14dd0720d479765f5d74ccdc4c32be65a5b4d Mon Sep 17 00:00:00 2001 From: Lucas Sanches <3931027+lcssanches@users.noreply.github.com> Date: Fri, 19 Jul 2024 12:25:56 -0300 Subject: [PATCH 1/4] Update terraform_state_test.go --- terraformstate/terraform_state_test.go | 145 +++++++++++++++++++++++++ 1 file changed, 145 insertions(+) diff --git a/terraformstate/terraform_state_test.go b/terraformstate/terraform_state_test.go index d155a78..1b5765b 100644 --- a/terraformstate/terraform_state_test.go +++ b/terraformstate/terraform_state_test.go @@ -32,6 +32,151 @@ func TestResourceChangeColor(t *testing.T) { assert.Equal(t, color, ColorMagenta) } +func TestGetAllResourceChanges(t *testing.T) { + input := []byte(` + { + "resource_changes": [ + { + "address": "aws_instance.example1", + "change": { + "actions": ["create"] + } + }, + { + "address": "aws_instance.example2", + "change": { + "actions": ["delete"] + } + }, + { + "address": "aws_instance.example3", + "change": { + "actions": ["update"] + } + }, + { + "address": "aws_instance.example4", + "change": { + "actions": ["create", "delete"] + } + }, + { + "address": "aws_instance.example5", + "change": { + "importing": { + "id": "example5" + } + } + } + ] + }`) + + plan, err := Parse(input) + if err != nil { + t.Fatalf("failed to parse input: %v", err) + } + + expected := map[string]ResourceChanges{ + "import": { + &tfjson.ResourceChange{ + Address: "aws_instance.example5", + Change: tfjson.Change{ + Importing: &tfjson.Import{ + ID: "example5", + }, + }, + }, + }, + "add": { + &tfjson.ResourceChange{ + Address: "aws_instance.example1", + Change: tfjson.Change{ + Actions: []string{"create"}, + }, + }, + }, + "delete": { + &tfjson.ResourceChange{ + Address: "aws_instance.example2", + Change: tfjson.Change{ + Actions: []string{"delete"}, + }, + }, + }, + "update": { + &tfjson.ResourceChange{ + Address: "aws_instance.example3", + Change: tfjson.Change{ + Actions: []string{"update"}, + }, + }, + }, + "recreate": { + &tfjson.ResourceChange{ + Address: "aws_instance.example4", + Change: tfjson.Change{ + Actions: []string{"create", "delete"}, + }, + }, + }, + } + + result := GetAllResourceChanges(plan) + + for key, expectedChanges := range expected { + if len(result[key]) != len(expectedChanges) { + t.Errorf("Expected length of %s to be %d, got %d", key, len(expectedChanges), len(result[key])) + } + for i, expectedChange := range expectedChanges { + if result[key][i].Address != expectedChange.Address { + t.Errorf("Expected %s address at index %d to be %s, got %s", key, i, expectedChange.Address, result[key][i].Address) + } + } + } +} + +func TestGetAllOutputChanges(t *testing.T) { + input := []byte(` + { + "output_changes": { + "output1": { + "actions": ["create"] + }, + "output2": { + "actions": ["delete"] + }, + "output3": { + "actions": ["update"] + } + } + }`) + + plan := tfjson.Plan{} + err := json.Unmarshal(input, &plan) + if err != nil { + t.Fatalf("failed to parse input: %v", err) + } + + expected := map[string][]string{ + "add": {"output1"}, + "delete": {"output2"}, + "update": {"output3"}, + } + + result := GetAllOutputChanges(plan) + + for key, expectedOutputs := range expected { + if len(result[key]) != len(expectedOutputs)) { + t.Errorf("Expected length of %s to be %d, got %d", key, len(expectedOutputs), len(result[key])) + } + for i, expectedOutput := range expectedOutputs { + if result[key][i] != expectedOutput { + t.Errorf("Expected %s output at index %d to be %s, got %s", key, i, expectedOutput, result[key][i]) + } + } + } +} + func TestResourceChangeSuffix(t *testing.T) { ExpectedSuffix := map[Action]string{ ActionCreate: "(+)", From 9f91ea2001b87a1712e094e5347303bb24d6b80d Mon Sep 17 00:00:00 2001 From: Lucas Sanches <3931027+lcssanches@users.noreply.github.com> Date: Fri, 19 Jul 2024 12:27:24 -0300 Subject: [PATCH 2/4] Update terraform_state_test.go --- terraformstate/terraform_state_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terraformstate/terraform_state_test.go b/terraformstate/terraform_state_test.go index 1b5765b..d3f44c2 100644 --- a/terraformstate/terraform_state_test.go +++ b/terraformstate/terraform_state_test.go @@ -166,7 +166,7 @@ func TestGetAllOutputChanges(t *testing.T) { result := GetAllOutputChanges(plan) for key, expectedOutputs := range expected { - if len(result[key]) != len(expectedOutputs)) { + if (len(result[key]) != len(expectedOutputs)) { t.Errorf("Expected length of %s to be %d, got %d", key, len(expectedOutputs), len(result[key])) } for i, expectedOutput := range expectedOutputs { From 8d5c1a859f30f6a09e1112b697484686c8fc85db Mon Sep 17 00:00:00 2001 From: Lucas Sanches <3931027+lcssanches@users.noreply.github.com> Date: Fri, 19 Jul 2024 12:52:10 -0300 Subject: [PATCH 3/4] Add tests to GetAllOutputChanges and GetAllResourceChanges --- terraformstate/terraform_state.go | 14 +-- terraformstate/terraform_state_test.go | 165 +++++++------------------ 2 files changed, 51 insertions(+), 128 deletions(-) diff --git a/terraformstate/terraform_state.go b/terraformstate/terraform_state.go index 26e3892..9f67da0 100644 --- a/terraformstate/terraform_state.go +++ b/terraformstate/terraform_state.go @@ -3,7 +3,7 @@ package terraformstate import ( "encoding/json" "fmt" - "sort" + "sort" tfjson "github.com/hashicorp/terraform-json" ) @@ -113,13 +113,13 @@ func GetAllResourceChanges(plan tfjson.Plan) map[string]ResourceChanges { return resources[i].Address < resources[j].Address }) } - + sortResources(addedResources) sortResources(deletedResources) sortResources(updatedResources) sortResources(recreatedResources) sortResources(importedResources) - + return map[string]ResourceChanges{ "import": importedResources, "add": addedResources, @@ -135,11 +135,11 @@ func GetAllOutputChanges(plan tfjson.Plan) map[string][]string { addedResources := filterOutputs(plan.OutputChanges, "create") deletedResources := filterOutputs(plan.OutputChanges, "delete") updatedResources := filterOutputs(plan.OutputChanges, "update") - + sort.Strings(addedResources) - sort.Strings(deletedResources) - sort.Strings(updatedResources) - + sort.Strings(deletedResources) + sort.Strings(updatedResources) + return map[string][]string{ "add": addedResources, "delete": deletedResources, diff --git a/terraformstate/terraform_state_test.go b/terraformstate/terraform_state_test.go index d3f44c2..f30ca77 100644 --- a/terraformstate/terraform_state_test.go +++ b/terraformstate/terraform_state_test.go @@ -33,148 +33,71 @@ func TestResourceChangeColor(t *testing.T) { } func TestGetAllResourceChanges(t *testing.T) { - input := []byte(` - { - "resource_changes": [ - { - "address": "aws_instance.example1", - "change": { - "actions": ["create"] - } - }, - { - "address": "aws_instance.example2", - "change": { - "actions": ["delete"] - } - }, - { - "address": "aws_instance.example3", - "change": { - "actions": ["update"] - } - }, - { - "address": "aws_instance.example4", - "change": { - "actions": ["create", "delete"] - } - }, - { - "address": "aws_instance.example5", - "change": { - "importing": { - "id": "example5" - } - } - } - ] - }`) - - plan, err := Parse(input) - if err != nil { - t.Fatalf("failed to parse input: %v", err) + resourceChanges := ResourceChanges{ + &ResourceChange{Address: "create2", Change: &Change{Actions: Actions{ActionCreate}}}, + &ResourceChange{Address: "create1", Change: &Change{Actions: Actions{ActionCreate}}}, + &ResourceChange{Address: "delete2", Change: &Change{Actions: Actions{ActionDelete}}}, + &ResourceChange{Address: "delete1", Change: &Change{Actions: Actions{ActionDelete}}}, + &ResourceChange{Address: "update2", Change: &Change{Actions: Actions{ActionUpdate}}}, + &ResourceChange{Address: "update1", Change: &Change{Actions: Actions{ActionUpdate}}}, + &ResourceChange{Address: "import2", Change: &Change{Importing: &Importing{ID: "id1"}}}, + &ResourceChange{Address: "import1", Change: &Change{Importing: &Importing{ID: "id2"}}}, + + &ResourceChange{Address: "recreate2", Change: &Change{Actions: Actions{ActionDelete, ActionCreate}}}, + &ResourceChange{Address: "recreate1", Change: &Change{Actions: Actions{ActionDelete, ActionCreate}}}, } + plan := tfjson.Plan{ResourceChanges: resourceChanges} - expected := map[string]ResourceChanges{ - "import": { - &tfjson.ResourceChange{ - Address: "aws_instance.example5", - Change: tfjson.Change{ - Importing: &tfjson.Import{ - ID: "example5", - }, - }, - }, - }, + result := GetAllResourceChanges(plan) + + expectedResourceChanges := map[string]ResourceChanges{ "add": { - &tfjson.ResourceChange{ - Address: "aws_instance.example1", - Change: tfjson.Change{ - Actions: []string{"create"}, - }, - }, + &ResourceChange{Address: "create1", Change: &Change{Actions: Actions{ActionCreate}}}, + &ResourceChange{Address: "create2", Change: &Change{Actions: Actions{ActionCreate}}}, }, "delete": { - &tfjson.ResourceChange{ - Address: "aws_instance.example2", - Change: tfjson.Change{ - Actions: []string{"delete"}, - }, - }, + &ResourceChange{Address: "delete1", Change: &Change{Actions: Actions{ActionDelete}}}, + &ResourceChange{Address: "delete2", Change: &Change{Actions: Actions{ActionDelete}}}, }, "update": { - &tfjson.ResourceChange{ - Address: "aws_instance.example3", - Change: tfjson.Change{ - Actions: []string{"update"}, - }, - }, + &ResourceChange{Address: "update1", Change: &Change{Actions: Actions{ActionUpdate}}}, + &ResourceChange{Address: "update2", Change: &Change{Actions: Actions{ActionUpdate}}}, }, "recreate": { - &tfjson.ResourceChange{ - Address: "aws_instance.example4", - Change: tfjson.Change{ - Actions: []string{"create", "delete"}, - }, - }, + &ResourceChange{Address: "recreate1", Change: &Change{Actions: Actions{ActionDelete, ActionCreate}}}, + &ResourceChange{Address: "recreate2", Change: &Change{Actions: Actions{ActionDelete, ActionCreate}}}, + }, + "import": { + &ResourceChange{Address: "import1", Change: &Change{Importing: &Importing{ID: "id2"}}}, + &ResourceChange{Address: "import2", Change: &Change{Importing: &Importing{ID: "id1"}}}, }, } - result := GetAllResourceChanges(plan) - - for key, expectedChanges := range expected { - if len(result[key]) != len(expectedChanges) { - t.Errorf("Expected length of %s to be %d, got %d", key, len(expectedChanges), len(result[key])) - } - for i, expectedChange := range expectedChanges { - if result[key][i].Address != expectedChange.Address { - t.Errorf("Expected %s address at index %d to be %s, got %s", key, i, expectedChange.Address, result[key][i].Address) - } - } - } + assert.Equal(t, expectedResourceChanges, result) } func TestGetAllOutputChanges(t *testing.T) { - input := []byte(` - { - "output_changes": { - "output1": { - "actions": ["create"] - }, - "output2": { - "actions": ["delete"] - }, - "output3": { - "actions": ["update"] - } - } - }`) - - plan := tfjson.Plan{} - err := json.Unmarshal(input, &plan) - if err != nil { - t.Fatalf("failed to parse input: %v", err) - } - expected := map[string][]string{ - "add": {"output1"}, - "delete": {"output2"}, - "update": {"output3"}, + outputChanges := map[string]*Change{ + "create2": {Actions: Actions{ActionCreate}}, + "create1": {Actions: Actions{ActionCreate}}, + "delete2": {Actions: Actions{ActionDelete}}, + "delete1": {Actions: Actions{ActionDelete}}, + "update2": {Actions: Actions{ActionUpdate}}, + "update1": {Actions: Actions{ActionUpdate}}, } + plan := tfjson.Plan{OutputChanges: outputChanges} + result := GetAllOutputChanges(plan) - for key, expectedOutputs := range expected { - if (len(result[key]) != len(expectedOutputs)) { - t.Errorf("Expected length of %s to be %d, got %d", key, len(expectedOutputs), len(result[key])) - } - for i, expectedOutput := range expectedOutputs { - if result[key][i] != expectedOutput { - t.Errorf("Expected %s output at index %d to be %s, got %s", key, i, expectedOutput, result[key][i]) - } - } + expectedResourceChanges := map[string][]string{ + "add": {"create1", "create2"}, + "delete": {"delete1", "delete2"}, + "update": {"update1", "update2"}, } + + assert.Equal(t, expectedResourceChanges, result) } func TestResourceChangeSuffix(t *testing.T) { From 544f06ac79de2cedfd5ee573db3a984dc4838af6 Mon Sep 17 00:00:00 2001 From: Lucas Sanches <3931027+lcssanches@users.noreply.github.com> Date: Fri, 19 Jul 2024 12:53:06 -0300 Subject: [PATCH 4/4] Update terraform_state_test.go --- terraformstate/terraform_state_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/terraformstate/terraform_state_test.go b/terraformstate/terraform_state_test.go index f30ca77..00caaa7 100644 --- a/terraformstate/terraform_state_test.go +++ b/terraformstate/terraform_state_test.go @@ -42,7 +42,6 @@ func TestGetAllResourceChanges(t *testing.T) { &ResourceChange{Address: "update1", Change: &Change{Actions: Actions{ActionUpdate}}}, &ResourceChange{Address: "import2", Change: &Change{Importing: &Importing{ID: "id1"}}}, &ResourceChange{Address: "import1", Change: &Change{Importing: &Importing{ID: "id2"}}}, - &ResourceChange{Address: "recreate2", Change: &Change{Actions: Actions{ActionDelete, ActionCreate}}}, &ResourceChange{Address: "recreate1", Change: &Change{Actions: Actions{ActionDelete, ActionCreate}}}, }