From 77aaed8d88f945defaf18b3fa7eabd55fba1003b Mon Sep 17 00:00:00 2001 From: Giuseppe Chiesa Date: Tue, 16 Apr 2024 12:04:20 +0200 Subject: [PATCH 1/4] feat: add support for JSONPath testcases --- pkg/scenario/stage.go | 63 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/pkg/scenario/stage.go b/pkg/scenario/stage.go index 91c089d..30ece2c 100644 --- a/pkg/scenario/stage.go +++ b/pkg/scenario/stage.go @@ -1,6 +1,9 @@ package scenario import ( + "fmt" + "github.com/gruntwork-io/terratest/modules/k8s" + "github.com/stretchr/testify/assert" "reflect" "strconv" "testing" @@ -13,6 +16,22 @@ import ( type StageClient struct{} +type TestType int + +const ( + ShouldContain = iota + ShouldNOTContain + ShouldBeEqual +) + +type JsonPathTestCases struct { + TestName string + ExpectedValue interface{} + JsonPathToCompare string + AllowDifferentType bool + TestType TestType +} + type Stage interface { DestroyStage(t *testing.T, options *terraform.Options) PlanStage(t *testing.T, options *terraform.Options) @@ -166,6 +185,50 @@ func (c *StageClient) PlanWithSpecificVariableValueToExpect(t *testing.T, option compareValues(t, actualValue, expectedValue, variable) } +// PlanAndAssertJsonWithJsonPath performs JSON path planning and assertion in Go testing. +// +// t *testing.T: Testing object +// options *terraform.Options: Terraform options +// testCases []JsonPathTestCases: Array of JSON path test cases +func (c *StageClient) PlanAndAssertJsonWithJsonPath(t *testing.T, options *terraform.Options, testCases []JsonPathTestCases) { + jsonPlan := terraform.InitAndPlanAndShow(t, options) + + for _, testCase := range testCases { + t.Run(testCase.TestName, func(t *testing.T) { + var result []interface{} + k8s.UnmarshalJSONPath(t, []byte(jsonPlan), testCase.JsonPathToCompare, &result) + assert.NotNil(t, result) + + // if expected is slice then it's ok to compare entire slice + if reflect.TypeOf(testCase.ExpectedValue).Kind() == reflect.Slice { + assert.ObjectsAreEqual(testCase.ExpectedValue, result) + } else { + // work on the result[0] + t.Logf("result returned raw: %v", result) + v := result[0] + if !testCase.AllowDifferentType { + assert.Equal(t, reflect.TypeOf(testCase.ExpectedValue).Kind(), reflect.TypeOf(v).Kind()) + } + applyTestType(t, testCase.TestType, v, testCase.ExpectedValue, fmt.Sprintf("JSONPATH query: %s", testCase.JsonPathToCompare)) + } + }) + } +} + +func applyTestType(t *testing.T, testType TestType, actual interface{}, expected interface{}, additionalMessage string) { + switch testType { + case ShouldContain: + msg := fmt.Sprintf("Output did not contains the expected value. Expected: %v, Actual: %v, %s", expected, actual, additionalMessage) + assert.Contains(t, actual, expected, msg) + case ShouldNOTContain: + msg := fmt.Sprintf("Output is expected NOT to contains the value. Expected: %v, Actual: %v, %s", expected, actual, additionalMessage) + assert.NotContains(t, actual, expected, msg) + case ShouldBeEqual: + msg := fmt.Sprintf("Output did not match with expected value. Expected: %v, Actual: %v, %s", expected, actual, additionalMessage) + assert.EqualValuesf(t, actual, expected, msg) + } +} + func compareValues(t *testing.T, actual interface{}, expected, variableName string) { actualType := reflect.TypeOf(actual) if actualType == nil { From 72c60022270858eeb2f6f550911b4d20bb329577 Mon Sep 17 00:00:00 2001 From: Giuseppe Chiesa Date: Tue, 16 Apr 2024 12:57:54 +0200 Subject: [PATCH 2/4] fix: lint issues --- pkg/scenario/stage.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/scenario/stage.go b/pkg/scenario/stage.go index 30ece2c..4995df5 100644 --- a/pkg/scenario/stage.go +++ b/pkg/scenario/stage.go @@ -24,10 +24,10 @@ const ( ShouldBeEqual ) -type JsonPathTestCases struct { +type JSONPathTestCases struct { TestName string ExpectedValue interface{} - JsonPathToCompare string + JSONPathToCompare string AllowDifferentType bool TestType TestType } @@ -185,18 +185,18 @@ func (c *StageClient) PlanWithSpecificVariableValueToExpect(t *testing.T, option compareValues(t, actualValue, expectedValue, variable) } -// PlanAndAssertJsonWithJsonPath performs JSON path planning and assertion in Go testing. +// PlanAndAssertJSONWithJSONPath performs JSON path planning and assertion in Go testing. // // t *testing.T: Testing object // options *terraform.Options: Terraform options -// testCases []JsonPathTestCases: Array of JSON path test cases -func (c *StageClient) PlanAndAssertJsonWithJsonPath(t *testing.T, options *terraform.Options, testCases []JsonPathTestCases) { +// testCases []JSONPathTestCases: Array of JSON path test cases +func (c *StageClient) PlanAndAssertJSONWithJSONPath(t *testing.T, options *terraform.Options, testCases []JSONPathTestCases) { jsonPlan := terraform.InitAndPlanAndShow(t, options) for _, testCase := range testCases { t.Run(testCase.TestName, func(t *testing.T) { var result []interface{} - k8s.UnmarshalJSONPath(t, []byte(jsonPlan), testCase.JsonPathToCompare, &result) + k8s.UnmarshalJSONPath(t, []byte(jsonPlan), testCase.JSONPathToCompare, &result) assert.NotNil(t, result) // if expected is slice then it's ok to compare entire slice @@ -209,7 +209,7 @@ func (c *StageClient) PlanAndAssertJsonWithJsonPath(t *testing.T, options *terra if !testCase.AllowDifferentType { assert.Equal(t, reflect.TypeOf(testCase.ExpectedValue).Kind(), reflect.TypeOf(v).Kind()) } - applyTestType(t, testCase.TestType, v, testCase.ExpectedValue, fmt.Sprintf("JSONPATH query: %s", testCase.JsonPathToCompare)) + applyTestType(t, testCase.TestType, v, testCase.ExpectedValue, fmt.Sprintf("JSONPATH query: %s", testCase.JSONPathToCompare)) } }) } From 1bb3f7a650146a478873b50b6cd7c698e4a222af Mon Sep 17 00:00:00 2001 From: Giuseppe Chiesa Date: Tue, 16 Apr 2024 13:30:39 +0200 Subject: [PATCH 3/4] fix: lint issues --- pkg/scenario/stage.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/scenario/stage.go b/pkg/scenario/stage.go index 4995df5..60639c1 100644 --- a/pkg/scenario/stage.go +++ b/pkg/scenario/stage.go @@ -215,7 +215,7 @@ func (c *StageClient) PlanAndAssertJSONWithJSONPath(t *testing.T, options *terra } } -func applyTestType(t *testing.T, testType TestType, actual interface{}, expected interface{}, additionalMessage string) { +func applyTestType(t *testing.T, testType TestType, actual, expected interface{}, additionalMessage string) { switch testType { case ShouldContain: msg := fmt.Sprintf("Output did not contains the expected value. Expected: %v, Actual: %v, %s", expected, actual, additionalMessage) From 550e62a9e3f9da938358a1d99d1a2da592846823 Mon Sep 17 00:00:00 2001 From: Giuseppe Chiesa Date: Tue, 16 Apr 2024 13:55:41 +0200 Subject: [PATCH 4/4] fix: add function signature in the interface --- pkg/scenario/stage.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/scenario/stage.go b/pkg/scenario/stage.go index 60639c1..451b956 100644 --- a/pkg/scenario/stage.go +++ b/pkg/scenario/stage.go @@ -45,6 +45,7 @@ type Stage interface { PlanWithResourcesExpectedToBeDeleted(t *testing.T, options *terraform.Options, resources []string) PlanWithResourcesExpectedToBeUpdated(t *testing.T, options *terraform.Options, resources []string) PlanWithSpecificVariableValueToExpect(t *testing.T, options *terraform.Options, variable, value string) + PlanAndAssertJSONWithJSONPath(t *testing.T, options *terraform.Options, testCases []JSONPathTestCases) } func (c *StageClient) DestroyStage(t *testing.T, options *terraform.Options) {