From 33584b84fa211431a5ff233e4b1da242e0ba209a Mon Sep 17 00:00:00 2001 From: Artem Tiupin Date: Tue, 9 May 2023 12:31:12 +0100 Subject: [PATCH 01/12] test: Add unit-tests for UnMarshallLimitNamespace (#167) --- pkg/common/common_test.go | 77 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/pkg/common/common_test.go b/pkg/common/common_test.go index a2c275066..d35ce6742 100644 --- a/pkg/common/common_test.go +++ b/pkg/common/common_test.go @@ -205,3 +205,80 @@ func TestNamespacedNameToObjectKey(t *testing.T) { } }) } + +func TestUnMarshallLimitNamespace(t *testing.T) { + testCases := []struct { + name string + namespace string + expectedKey client.ObjectKey + expectedDomain string + expectedError bool + }{ + { + name: "when namespace is valid and contains both namespace and domain then return the correct values", + namespace: "exampleNS/exampleGW#domain.com", + expectedKey: client.ObjectKey{Name: "exampleGW", Namespace: "exampleNS"}, + expectedDomain: "domain.com", + expectedError: false, + }, + { + name: "when namespace is invalid (no '#domain') then return an error", + namespace: "exampleNS/exampleGW", + expectedKey: client.ObjectKey{}, + expectedDomain: "", + expectedError: true, + }, + { + name: "when namespace contains more than one '#' then return an error", + namespace: "exampleNS/exampleGW#domain.com#extra", + expectedKey: client.ObjectKey{}, + expectedDomain: "", + expectedError: true, + }, + { + name: "when namespace missing both namespace and gateway parts then return an error", + namespace: "#domain.com", + expectedKey: client.ObjectKey{}, + expectedDomain: "", + expectedError: true, + }, + { + name: "when namespace only has gateway name (missing 'namespace/') then return an error", + namespace: "exampleGW#domain.com", + expectedKey: client.ObjectKey{}, + expectedDomain: "", + expectedError: true, + }, + { + name: "when namespace only has namespace name (missing '/gwName') then return an error", + namespace: "exampleNS#domain.com", + expectedKey: client.ObjectKey{}, + expectedDomain: "", + expectedError: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + key, domain, err := UnMarshallLimitNamespace(tc.namespace) + + if tc.expectedError { + if err == nil { + t.Errorf("Expected an error, but got %v", err) + } + } else { + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + + if key != tc.expectedKey { + t.Errorf("Expected %v, but got %v", tc.expectedKey, key) + } + + if domain != tc.expectedDomain { + t.Errorf("Expected %v, but got %v", tc.expectedDomain, domain) + } + } + }) + } +} From 8b044acac8050acfdd2103665315c2d5ff18fcd7 Mon Sep 17 00:00:00 2001 From: Artem Tiupin Date: Tue, 9 May 2023 12:48:44 +0100 Subject: [PATCH 02/12] test: Add two FAILING unit-tests for UnMarshallLimitNamespace (#167) The two failing test cases include: - when namespace has no gateway name then return an error - when namespace has no domain name then return an error In these test-cases we leave the separator (either "/" or "#"), which causes the function to return an error when the gateway name or domain name is missing. In the last two test cases: - when namespace only has gateway name (missing 'namespace/') and domain then return an error - when namespace only has namespace name (missing '/gwName') and domain then return an error the separator (/) is missing along with the namespace or gateway names, causing the function to return the correct error message. --- pkg/common/common_test.go | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/pkg/common/common_test.go b/pkg/common/common_test.go index d35ce6742..ea20a0e5e 100644 --- a/pkg/common/common_test.go +++ b/pkg/common/common_test.go @@ -243,14 +243,28 @@ func TestUnMarshallLimitNamespace(t *testing.T) { expectedError: true, }, { - name: "when namespace only has gateway name (missing 'namespace/') then return an error", + name: "when namespace has no gateway name then return an error", + namespace: "exampleNS/#domain.com", + expectedKey: client.ObjectKey{}, + expectedDomain: "", + expectedError: true, + }, + { + name: "when namespace has no domain name then return an error", + namespace: "exampleNS/exampleGW#", + expectedKey: client.ObjectKey{}, + expectedDomain: "", + expectedError: true, + }, + { + name: "when namespace only has gateway name (missing 'namespace/') and domain then return an error", namespace: "exampleGW#domain.com", expectedKey: client.ObjectKey{}, expectedDomain: "", expectedError: true, }, { - name: "when namespace only has namespace name (missing '/gwName') then return an error", + name: "when namespace only has namespace name (missing '/gwName') and domain then return an error", namespace: "exampleNS#domain.com", expectedKey: client.ObjectKey{}, expectedDomain: "", From 2bf876982151d72b31d2e2d0a50174679e9a3657 Mon Sep 17 00:00:00 2001 From: Artem Tiupin Date: Tue, 9 May 2023 13:34:28 +0100 Subject: [PATCH 03/12] refactor: Add comment to UnMarshallLimitNamespace (#167) --- pkg/common/common.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/common/common.go b/pkg/common/common.go index 83b9f2003..a83d6ad81 100644 --- a/pkg/common/common.go +++ b/pkg/common/common.go @@ -171,6 +171,10 @@ func MarshallNamespace(gwKey client.ObjectKey, domain string) string { return fmt.Sprintf("%s/%s#%s", gwKey.Namespace, gwKey.Name, domain) } +// UnMarshallObjectKey takes a string input and converts it into an ObjectKey struct that +// can be used to access a specific Kubernetes object. The input string is expected to be in the format "namespace/name". +// If the input string does not contain a NamespaceSeparator (typically '/') +// or has too few components, this function returns an error. func UnMarshallObjectKey(keyStr string) (client.ObjectKey, error) { keySplit := strings.Split(keyStr, string(NamespaceSeparator)) if len(keySplit) < 2 { From ba535d3fce11e10a960019a778168679137ebb63 Mon Sep 17 00:00:00 2001 From: Artem Tiupin Date: Tue, 9 May 2023 16:00:07 +0100 Subject: [PATCH 04/12] test: Add unit-tests for MarshallNamespace (#167) --- pkg/common/common_test.go | 43 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/pkg/common/common_test.go b/pkg/common/common_test.go index ea20a0e5e..4c1d226e6 100644 --- a/pkg/common/common_test.go +++ b/pkg/common/common_test.go @@ -296,3 +296,46 @@ func TestUnMarshallLimitNamespace(t *testing.T) { }) } } + +func TestMarshallNamespace(t *testing.T) { + testCases := []struct { + name string + gwKey client.ObjectKey + domain string + expected string + }{ + { + name: "when input is valid then return expected output", + gwKey: client.ObjectKey{ + Namespace: "test", + Name: "myGwName", + }, + domain: "example.com", + expected: "test/myGwName#example.com", + }, + { + name: "when input is empty then return expected output", + gwKey: client.ObjectKey{}, + domain: "", + expected: "/#", + }, + { + name: "when input contains special characters then return expected output", + gwKey: client.ObjectKey{ + Namespace: "test", + Name: "myG.w-N*ame", + }, + domain: "example%-com", + expected: "test/myG.w-N*ame#example%-com", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + result := MarshallNamespace(tc.gwKey, tc.domain) + if !reflect.DeepEqual(result, tc.expected) { + t.Errorf("Expected %v, but got %v", tc.expected, result) + } + }) + } +} From 6fbb65d0cbf2b0333e9a325bf8f46216614052e4 Mon Sep 17 00:00:00 2001 From: Artem Tiupin Date: Wed, 10 May 2023 12:54:01 +0100 Subject: [PATCH 05/12] test: Add unit-tests for UnMarshallObjectKey (#167) --- pkg/common/common_test.go | 65 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/pkg/common/common_test.go b/pkg/common/common_test.go index 4c1d226e6..94184b21b 100644 --- a/pkg/common/common_test.go +++ b/pkg/common/common_test.go @@ -3,6 +3,7 @@ package common import ( + "fmt" "os" "reflect" "testing" @@ -339,3 +340,67 @@ func TestMarshallNamespace(t *testing.T) { }) } } + +func TestUnMarshallObjectKey(t *testing.T) { + testCases := []struct { + name string + input string + expectedOutput client.ObjectKey + expectedError error + }{ + { + name: "when valid key string then return valid ObjectKey", + input: "default/object1", + expectedOutput: client.ObjectKey{Namespace: "default", Name: "object1"}, + expectedError: nil, + }, + { + name: "when valid key string with non-default namespace then return valid ObjectKey", + input: "kube-system/object2", + expectedOutput: client.ObjectKey{Namespace: "kube-system", Name: "object2"}, + expectedError: nil, + }, + { + name: "when invalid namespace and name then return empty ObjectKey and error", + input: "invalid", + expectedOutput: client.ObjectKey{}, + expectedError: fmt.Errorf("failed to split on %s: 'invalid'", string(NamespaceSeparator)), + }, + { + name: "when '#' separator used instead of '/' then return an error", + input: "default#object1", + expectedOutput: client.ObjectKey{}, + expectedError: fmt.Errorf("failed to split on %s: 'default#object1'", string(NamespaceSeparator)), + }, + { + name: "when input string is empty then return an error", + input: "", + expectedOutput: client.ObjectKey{}, + expectedError: fmt.Errorf("failed to split on %s: ''", string(NamespaceSeparator)), + }, + { + name: "when empty namespace and name then return valid empty ObjectKey", + input: "/", + expectedOutput: client.ObjectKey{}, + expectedError: nil, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + output, err := UnMarshallObjectKey(tc.input) + + if err != nil && tc.expectedError == nil { + t.Errorf("unexpected error: got %v, want nil", err) + } else if err == nil && tc.expectedError != nil { + t.Errorf("expected error but got nil") + } else if err != nil && tc.expectedError != nil && err.Error() != tc.expectedError.Error() { + t.Errorf("unexpected error: got '%v', want '%v'", err, tc.expectedError) + } + + if output != tc.expectedOutput { + t.Errorf("unexpected output: got %v, want %v", output, tc.expectedOutput) + } + }) + } +} From 49a9f8eda99c54e90d48c713be334a9b2aeaf5af Mon Sep 17 00:00:00 2001 From: Artem Tiupin Date: Wed, 10 May 2023 13:06:33 +0100 Subject: [PATCH 06/12] test: Add unit-tests for HostnamesToStrings (#167) --- pkg/common/common_test.go | 44 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/pkg/common/common_test.go b/pkg/common/common_test.go index 94184b21b..ea15e491c 100644 --- a/pkg/common/common_test.go +++ b/pkg/common/common_test.go @@ -9,6 +9,7 @@ import ( "testing" "sigs.k8s.io/controller-runtime/pkg/client" + gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" ) func TestValidSubdomains(t *testing.T) { @@ -404,3 +405,46 @@ func TestUnMarshallObjectKey(t *testing.T) { }) } } + +func TestHostnamesToStrings(t *testing.T) { + testCases := []struct { + name string + inputHostnames []gatewayapiv1alpha2.Hostname + expectedOutput []string + }{ + { + name: "when input is empty then return empty output", + inputHostnames: []gatewayapiv1alpha2.Hostname{}, + expectedOutput: []string{}, + }, + { + name: "when input has a single precise hostname then return a single string", + inputHostnames: []gatewayapiv1alpha2.Hostname{"example.com"}, + expectedOutput: []string{"example.com"}, + }, + { + name: "when input has multiple precise hostnames then return the corresponding strings", + inputHostnames: []gatewayapiv1alpha2.Hostname{"example.com", "test.com", "localhost"}, + expectedOutput: []string{"example.com", "test.com", "localhost"}, + }, + { + name: "when input has a wildcard hostname then return the wildcard string", + inputHostnames: []gatewayapiv1alpha2.Hostname{"*.example.com"}, + expectedOutput: []string{"*.example.com"}, + }, + { + name: "when input has both precise and wildcard hostnames then return the corresponding strings", + inputHostnames: []gatewayapiv1alpha2.Hostname{"example.com", "*.test.com"}, + expectedOutput: []string{"example.com", "*.test.com"}, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + output := HostnamesToStrings(tc.inputHostnames) + if !reflect.DeepEqual(tc.expectedOutput, output) { + t.Errorf("Unexpected output. Expected %v but got %v", tc.expectedOutput, output) + } + }) + } +} From dcad23a6cf174e810883775a23d87c3430c74f55 Mon Sep 17 00:00:00 2001 From: artem_tiupin <70763601+art-tapin@users.noreply.github.com> Date: Wed, 10 May 2023 16:02:53 +0100 Subject: [PATCH 07/12] [test] Optimizations, improvements, and unit tests for common/common.go (part 2 of 3) (#182) * test: Add unit-tests for Contains (#167) * refactor: Add comment to Contains (#167) * test: Add unit-tests for Map (#167) * refactor: Add comment to Map (#167) * refactor: Add names to Map test cases (#167) * test: Add unit-tests for SliceCopy (#167) * refactor: Add comment to SliceCopy (#167) * test: Add unit-tests for ReverseSlice (#167) * refactor: Add comment to ReverseSlice (#167) * test: Add unit-tests for MergeMapStringString (#167) * refactor: Add missing import 'reflect' --- pkg/common/common.go | 5 + pkg/common/common_test.go | 206 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 211 insertions(+) diff --git a/pkg/common/common.go b/pkg/common/common.go index 83b9f2003..e527e99f8 100644 --- a/pkg/common/common.go +++ b/pkg/common/common.go @@ -85,6 +85,8 @@ func NamespacedNameToObjectKey(namespacedName, defaultNamespace string) client.O return client.ObjectKey{Namespace: defaultNamespace, Name: namespacedName} } +// Contains checks if the given target string is present in the slice of strings 'slice'. +// It returns true if the target string is found in the slice, false otherwise. func Contains(slice []string, target string) bool { for idx := range slice { if slice[idx] == target { @@ -103,6 +105,7 @@ func Find[T any](slice []T, match func(T) bool) (*T, bool) { return nil, false } +// Map applies the given mapper function to each element in the input slice and returns a new slice with the results. func Map[T, U any](slice []T, f func(T) U) []U { arr := make([]U, len(slice)) for i, e := range slice { @@ -111,12 +114,14 @@ func Map[T, U any](slice []T, f func(T) U) []U { return arr } +// SliceCopy copies the elements from the input slice into the output slice, and returns the output slice. func SliceCopy[T any](s1 []T) []T { s2 := make([]T, len(s1)) copy(s2, s1) return s2 } +// ReverseSlice creates a reversed copy of the input slice. func ReverseSlice[T any](input []T) []T { inputLen := len(input) output := make([]T, inputLen) diff --git a/pkg/common/common_test.go b/pkg/common/common_test.go index a2c275066..734f9f34d 100644 --- a/pkg/common/common_test.go +++ b/pkg/common/common_test.go @@ -205,3 +205,209 @@ func TestNamespacedNameToObjectKey(t *testing.T) { } }) } + +func TestContains(t *testing.T) { + testCases := []struct { + name string + slice []string + target string + expected bool + }{ + { + name: "when slice has one target item then return true", + slice: []string{"test-gw"}, + target: "test-gw", + expected: true, + }, + { + name: "when slice is empty then return false", + slice: []string{}, + target: "test-gw", + expected: false, + }, + { + name: "when target is in a slice then return true", + slice: []string{"test-gw1", "test-gw2", "test-gw3"}, + target: "test-gw2", + expected: true, + }, + { + name: "when no target in a slice then return false", + slice: []string{"test-gw1", "test-gw2", "test-gw3"}, + target: "test-gw4", + expected: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + if Contains(tc.slice, tc.target) != tc.expected { + t.Errorf("when slice=%v and target=%s, expected=%v, but got=%v", tc.slice, tc.target, tc.expected, !tc.expected) + } + }) + } +} + +func TestMap(t *testing.T) { + slice1 := []int{1, 2, 3, 4} + f1 := func(x int) int { return x + 1 } + expected1 := []int{2, 3, 4, 5} + result1 := Map(slice1, f1) + t.Run("when mapping an int slice with an increment function then return new slice with the incremented values", func(t *testing.T) { + if !reflect.DeepEqual(result1, expected1) { + t.Errorf("result1 = %v; expected %v", result1, expected1) + } + }) + + slice2 := []string{"hello", "world", "buz", "a"} + f2 := func(s string) int { return len(s) } + expected2 := []int{5, 5, 3, 1} + result2 := Map(slice2, f2) + t.Run("when mapping a string slice with string->int mapping then return new slice with the mapped values", func(t *testing.T) { + if !reflect.DeepEqual(result2, expected2) { + t.Errorf("result2 = %v; expected %v", result2, expected2) + } + }) + + slice3 := []int{} + f3 := func(x int) float32 { return float32(x) / 2 } + expected3 := []float32{} + result3 := Map(slice3, f3) + t.Run("when mapping an empty int slice then return an empty slice", func(t *testing.T) { + if !reflect.DeepEqual(result3, expected3) { + t.Errorf("result3 = %v; expected %v", result3, expected3) + } + }) +} + +func TestSliceCopy(t *testing.T) { + input1 := []int{1, 2, 3} + expected1 := []int{1, 2, 3} + output1 := SliceCopy(input1) + t.Run("when given slice of integers then return a copy of the input slice", func(t *testing.T) { + if !reflect.DeepEqual(output1, expected1) { + t.Errorf("SliceCopy(%v) = %v; expected %v", input1, output1, expected1) + } + }) + + input2 := []string{"foo", "bar", "baz"} + expected2 := []string{"foo", "bar", "baz"} + output2 := SliceCopy(input2) + t.Run("when given slice of strings then return a copy of the input slice", func(t *testing.T) { + if !reflect.DeepEqual(output2, expected2) { + t.Errorf("SliceCopy(%v) = %v; expected %v", input2, output2, expected2) + } + }) + + type person struct { + name string + age int + } + input3 := []person{{"Artem", 65}, {"DD", 18}, {"Charlie", 23}} + expected3 := []person{{"Artem", 65}, {"DD", 18}, {"Charlie", 23}} + output3 := SliceCopy(input3) + t.Run("when given slice of structs then return a copy of the input slice", func(t *testing.T) { + if !reflect.DeepEqual(output3, expected3) { + t.Errorf("SliceCopy(%v) = %v; expected %v", input3, output3, expected3) + } + }) + + input4 := []int{1, 2, 3} + expected4 := []int{1, 2, 3} + output4 := SliceCopy(input4) + t.Run("when modifying the original input slice then does not affect the returned copy", func(t *testing.T) { + if !reflect.DeepEqual(output4, expected4) { + t.Errorf("SliceCopy(%v) = %v; expected %v", input4, output4, expected4) + } + input4[0] = 4 + if reflect.DeepEqual(output4, input4) { + t.Errorf("modifying the original input slice should not change the output slice") + } + }) +} + +func TestReverseSlice(t *testing.T) { + input1 := []int{1, 2, 3} + expected1 := []int{3, 2, 1} + output1 := ReverseSlice(input1) + t.Run("when given slice of integers then return reversed copy of the input slice", func(t *testing.T) { + if !reflect.DeepEqual(output1, expected1) { + t.Errorf("ReverseSlice(%v) = %v; expected %v", input1, output1, expected1) + } + }) + + input2 := []string{"foo", "bar", "baz"} + expected2 := []string{"baz", "bar", "foo"} + output2 := ReverseSlice(input2) + t.Run("when given slice of strings then return reversed copy of the input slice", func(t *testing.T) { + if !reflect.DeepEqual(output2, expected2) { + t.Errorf("ReverseSlice(%v) = %v; expected %v", input2, output2, expected2) + } + }) + + input3 := []int{} + expected3 := []int{} + output3 := ReverseSlice(input3) + t.Run("when given an empty slice then return empty slice", func(t *testing.T) { + if !reflect.DeepEqual(output3, expected3) { + t.Errorf("ReverseSlice(%v) = %v; expected %v", input3, output3, expected3) + } + }) +} + +func TestMergeMapStringString(t *testing.T) { + testCases := []struct { + name string + existing map[string]string + desired map[string]string + expected bool + expectedState map[string]string + }{ + { + name: "when existing and desired are empty then return false and not modify the existing map", + existing: map[string]string{}, + desired: map[string]string{}, + expected: false, + expectedState: map[string]string{}, + }, + { + name: "when existing is empty and desired has values then return true and set the values in the existing map", + existing: map[string]string{}, + desired: map[string]string{"a": "1", "b": "2"}, + expected: true, + expectedState: map[string]string{"a": "1", "b": "2"}, + }, + { + name: "when existing has some values and desired has different/new values then return true and modify the existing map", + existing: map[string]string{"a": "1", "b": "2"}, + desired: map[string]string{"a": "3", "c": "4"}, + expected: true, + expectedState: map[string]string{"a": "3", "b": "2", "c": "4"}, + }, + { + name: "when existing has all the values from desired then return false and not modify the existing map", + existing: map[string]string{"a": "1", "b": "2"}, + desired: map[string]string{"a": "1", "b": "2"}, + expected: false, + expectedState: map[string]string{"a": "1", "b": "2"}, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + existingCopy := make(map[string]string, len(tc.existing)) + for k, v := range tc.existing { + existingCopy[k] = v + } + modified := MergeMapStringString(&existingCopy, tc.desired) + + if modified != tc.expected { + t.Errorf("MergeMapStringString(%v, %v) returned %v; expected %v", tc.existing, tc.desired, modified, tc.expected) + } + + if !reflect.DeepEqual(existingCopy, tc.expectedState) { + t.Errorf("MergeMapStringString(%v, %v) modified the existing map to %v; expected %v", tc.existing, tc.desired, existingCopy, tc.expectedState) + } + }) + } +} From 4f9ed21673690544a7a73e22e28a1a75888bd12b Mon Sep 17 00:00:00 2001 From: Guilherme Cassolato Date: Wed, 10 May 2023 17:37:39 +0200 Subject: [PATCH 08/12] fix: Ensure Istio gateways created in the tests are ready ('Programmed') by setting ClusterIP service type (#185) --- controllers/ratelimitpolicy_controller_test.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/controllers/ratelimitpolicy_controller_test.go b/controllers/ratelimitpolicy_controller_test.go index 8437c9cd6..f06bb4413 100644 --- a/controllers/ratelimitpolicy_controller_test.go +++ b/controllers/ratelimitpolicy_controller_test.go @@ -12,6 +12,7 @@ import ( . "github.com/onsi/gomega" istioclientgoextensionv1alpha1 "istio.io/client-go/pkg/apis/extensions/v1alpha1" istioclientnetworkingv1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -31,9 +32,10 @@ func testBuildBasicGateway(gwName, ns string) *gatewayapiv1alpha2.Gateway { APIVersion: gatewayapiv1alpha2.GroupVersion.String(), }, ObjectMeta: metav1.ObjectMeta{ - Name: gwName, - Namespace: ns, - Labels: map[string]string{"app": "rlptest"}, + Name: gwName, + Namespace: ns, + Labels: map[string]string{"app": "rlptest"}, + Annotations: map[string]string{"networking.istio.io/service-type": string(corev1.ServiceTypeClusterIP)}, }, Spec: gatewayapiv1alpha2.GatewaySpec{ GatewayClassName: gatewayapiv1alpha2.ObjectName("istio"), From e22eff65ef2d0ad5d42cdd50f5299f9ce0f22272 Mon Sep 17 00:00:00 2001 From: Eguzki Astiz Lezaun Date: Wed, 10 May 2023 17:59:51 +0200 Subject: [PATCH 09/12] changelog (#184) --- CHANGELOG.md | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a3d36ebf..3f6eb269a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,39 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +## [0.3.0] - 2023-05-09 + +## What's Changed +* [refactor] GW utils for all types of policies by @guicassolato in https://github.com/Kuadrant/kuadrant-operator/pull/134 +* wasm shim image env var name does not match deployment var name by @eguzki in https://github.com/Kuadrant/kuadrant-operator/pull/136 +* fix: `ComputeGatewayDiffs` when missing target HTTPRoute by @guicassolato in https://github.com/Kuadrant/kuadrant-operator/pull/139 +* Istio workload selector fetched from the gateway service spec by @guicassolato in https://github.com/Kuadrant/kuadrant-operator/pull/143 +* Improve policy constraint error message by @didierofrivia in https://github.com/Kuadrant/kuadrant-operator/pull/145 +* Doc install operator by @eguzki in https://github.com/Kuadrant/kuadrant-operator/pull/148 +* Simplify RateLimitPolicy by @eguzki in https://github.com/Kuadrant/kuadrant-operator/pull/144 +* RLP conditions and variables order does not matter by @eguzki in https://github.com/Kuadrant/kuadrant-operator/pull/147 +* Update limitador api to 0.4.0 by @eguzki in https://github.com/Kuadrant/kuadrant-operator/pull/150 +* Bump Kind version from 0.11.1 to 0.17.0 by @art-tapin in https://github.com/Kuadrant/kuadrant-operator/pull/152 +* Makefile: fix installing kind tool by @eguzki in https://github.com/Kuadrant/kuadrant-operator/pull/154 +* Schedule build images with git sha reference by @didierofrivia in https://github.com/Kuadrant/kuadrant-operator/pull/149 +* Fix GH Workflow inputs error by @didierofrivia in https://github.com/Kuadrant/kuadrant-operator/pull/155 +* Inheriting all secrets from caller workflow by @didierofrivia in https://github.com/Kuadrant/kuadrant-operator/pull/157 +* Fix bundle generation by @didierofrivia in https://github.com/Kuadrant/kuadrant-operator/pull/158 +* Refactoring Github workflows by @didierofrivia in https://github.com/Kuadrant/kuadrant-operator/pull/161 +* Update kind-cluster config by @art-tapin in https://github.com/Kuadrant/kuadrant-operator/pull/160 +* Fix update action variables for dependencies by @didierofrivia in https://github.com/Kuadrant/kuadrant-operator/pull/162 +* Fix scheduled build by @didierofrivia in https://github.com/Kuadrant/kuadrant-operator/pull/165 +* Storing all dependencies sha by @didierofrivia in https://github.com/Kuadrant/kuadrant-operator/pull/170 +* Fix inclusion of related wasm shim image by @didierofrivia in https://github.com/Kuadrant/kuadrant-operator/pull/171 +* [test] Improve test coverage and performance in apimachinery_status_conditions by @art-tapin in https://github.com/Kuadrant/kuadrant-operator/pull/172 +* [test] Add tests for authorino_conditions.go in common package by @art-tapin in https://github.com/Kuadrant/kuadrant-operator/pull/173 +* [test] Add tests for hostname.go in common package by @art-tapin in https://github.com/Kuadrant/kuadrant-operator/pull/174 +* Fixing image repo URL by @didierofrivia in https://github.com/Kuadrant/kuadrant-operator/pull/177 +* Removing release workflow by @didierofrivia in https://github.com/Kuadrant/kuadrant-operator/pull/178 + +## New Contributors +* @art-tapin made their first contribution in https://github.com/Kuadrant/kuadrant-operator/pull/152 + ## [0.2.0] - 2022-12-16 ### What's Changed @@ -77,5 +110,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/). **Full Changelog**: https://github.com/Kuadrant/kuadrant-operator/commits/v0.1.0 -[Unreleased]: https://github.com/Kuadrant/kuadrant-operator/compare/v0.2.0...HEAD +[Unreleased]: https://github.com/Kuadrant/kuadrant-operator/compare/v0.3.0...HEAD +[0.3.0]: https://github.com/Kuadrant/kuadrant-operator/compare/v0.2.0...v0.3.0 [0.2.0]: https://github.com/Kuadrant/kuadrant-operator/compare/v0.1.0...v0.2.0 From 7c6e1df9632fa73db7ca6872556040c5dfd490d1 Mon Sep 17 00:00:00 2001 From: Artem Tiupin Date: Mon, 15 May 2023 15:53:32 +0100 Subject: [PATCH 10/12] test: Add two test-cases for UnMarshallObjectKey (#167) 1. when valid namespace and empty name (strKey ends with '/') then return valid ObjectKey with namespace only 2. when valid name and empty namespace (strKey starts with '/') then return valid ObjectKey with name only Changes were discussed here: https://github.com/Kuadrant/kuadrant-operator/pull/187#discussion_r1193713905 --- pkg/common/common_test.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pkg/common/common_test.go b/pkg/common/common_test.go index 5b1847ee5..27e84406e 100644 --- a/pkg/common/common_test.go +++ b/pkg/common/common_test.go @@ -591,6 +591,18 @@ func TestUnMarshallObjectKey(t *testing.T) { expectedOutput: client.ObjectKey{}, expectedError: nil, }, + { + name: "when valid namespace and empty name (strKey ends with '/') then return valid ObjectKey with namespace only", + input: "default/", + expectedOutput: client.ObjectKey{Namespace: "default", Name: ""}, + expectedError: nil, + }, + { + name: "when valid name and empty namespace (strKey starts with '/') then return valid ObjectKey with name only", + input: "/object", + expectedOutput: client.ObjectKey{Namespace: "", Name: "object"}, + expectedError: nil, + }, } for _, tc := range testCases { From 426e8689147176b915d5e3fea0f2ee2916f1465e Mon Sep 17 00:00:00 2001 From: Artem Tiupin Date: Tue, 16 May 2023 17:18:15 +0100 Subject: [PATCH 11/12] test: Delete test case for UnMarshallLimitNamespace The test case "when namespace has no gateway name then return an error" has been removed from the test suite for UnMarshallLimitNamespace. This test case was tightly connected to the implementation of UnMarshallObjectKey, making it impossible to properly test the desired behavior in the context of UnMarshallLimitNamespace. --- pkg/common/common_test.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/pkg/common/common_test.go b/pkg/common/common_test.go index 27e84406e..57d9911c6 100644 --- a/pkg/common/common_test.go +++ b/pkg/common/common_test.go @@ -450,13 +450,6 @@ func TestUnMarshallLimitNamespace(t *testing.T) { expectedDomain: "", expectedError: true, }, - { - name: "when namespace has no gateway name then return an error", - namespace: "exampleNS/#domain.com", - expectedKey: client.ObjectKey{}, - expectedDomain: "", - expectedError: true, - }, { name: "when namespace has no domain name then return an error", namespace: "exampleNS/exampleGW#", From 700a30c7cc4dce3a2e766244705c048bd14a81e9 Mon Sep 17 00:00:00 2001 From: Artem Tiupin Date: Tue, 16 May 2023 17:32:33 +0100 Subject: [PATCH 12/12] refactor: Add clarity to the test name Describing the '/' separator as a default one we show that it is a default constant value. --- pkg/common/common_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/common/common_test.go b/pkg/common/common_test.go index 57d9911c6..a121d152b 100644 --- a/pkg/common/common_test.go +++ b/pkg/common/common_test.go @@ -567,7 +567,7 @@ func TestUnMarshallObjectKey(t *testing.T) { expectedError: fmt.Errorf("failed to split on %s: 'invalid'", string(NamespaceSeparator)), }, { - name: "when '#' separator used instead of '/' then return an error", + name: "when '#' separator used instead of default separator ('/') then return an error", input: "default#object1", expectedOutput: client.ObjectKey{}, expectedError: fmt.Errorf("failed to split on %s: 'default#object1'", string(NamespaceSeparator)),