diff --git a/.golangci.yml b/.golangci.yml index fc3480b4f4..612f33b232 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -43,3 +43,5 @@ issues: - gocyclo - errcheck - dupl + exclude: + - Using the variable on range scope `tc` in function literal diff --git a/apis/v1alpha1/validation/validation_test.go b/apis/v1alpha1/validation/validation_test.go index 88060c6ba4..ab1a4c3576 100644 --- a/apis/v1alpha1/validation/validation_test.go +++ b/apis/v1alpha1/validation/validation_test.go @@ -147,7 +147,6 @@ func TestValidateGateway(t *testing.T) { } for name, tc := range testCases { - tc := tc t.Run(name, func(t *testing.T) { gw := baseGateway.DeepCopy() tc.mutate(gw) @@ -405,13 +404,11 @@ func TestValidateHTTPRoute(t *testing.T) { errCount: 0, }, } - for _, tt := range tests { - // copy variable to avoid scope problems with ranges - tt := tt - t.Run(tt.name, func(t *testing.T) { - errs := ValidateHTTPRoute(&tt.hRoute) - if len(errs) != tt.errCount { - t.Errorf("ValidateHTTPRoute() got %v errors, want %v errors", len(errs), tt.errCount) + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + errs := ValidateHTTPRoute(&tc.hRoute) + if len(errs) != tc.errCount { + t.Errorf("ValidateHTTPRoute() got %v errors, want %v errors", len(errs), tc.errCount) } }) } @@ -490,11 +487,10 @@ func TestValidateGatewayClassUpdate(t *testing.T) { want: nil, }, } - for _, tt := range tests { - tt := tt - t.Run(tt.name, func(t *testing.T) { - if got := ValidateGatewayClassUpdate(tt.args.oldClass, tt.args.newClass); !reflect.DeepEqual(got, tt.want) { - t.Errorf("ValidateGatewayClassUpdate() = %v, want %v", got, tt.want) + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + if got := ValidateGatewayClassUpdate(tc.args.oldClass, tc.args.newClass); !reflect.DeepEqual(got, tc.want) { + t.Errorf("ValidateGatewayClassUpdate() = %v, want %v", got, tc.want) } }) } diff --git a/apis/v1alpha2/validation/gatewayclass_test.go b/apis/v1alpha2/validation/gatewayclass_test.go index 0518ddb1f9..dc14eac072 100644 --- a/apis/v1alpha2/validation/gatewayclass_test.go +++ b/apis/v1alpha2/validation/gatewayclass_test.go @@ -88,11 +88,10 @@ func TestValidateGatewayClassUpdate(t *testing.T) { want: nil, }, } - for _, tt := range tests { - tt := tt - t.Run(tt.name, func(t *testing.T) { - if got := ValidateGatewayClassUpdate(tt.args.oldClass, tt.args.newClass); !reflect.DeepEqual(got, tt.want) { - t.Errorf("ValidateGatewayClassUpdate() = %v, want %v", got, tt.want) + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + if got := ValidateGatewayClassUpdate(tc.args.oldClass, tc.args.newClass); !reflect.DeepEqual(got, tc.want) { + t.Errorf("ValidateGatewayClassUpdate() = %v, want %v", got, tc.want) } }) } diff --git a/apis/v1alpha2/validation/httproute.go b/apis/v1alpha2/validation/httproute.go index ca5a9115f2..eb5603885d 100644 --- a/apis/v1alpha2/validation/httproute.go +++ b/apis/v1alpha2/validation/httproute.go @@ -55,7 +55,7 @@ func validateHTTPRouteUniqueFilters(rules []gatewayv1a2.HTTPRouteRule, path *fie } // custom filters don't have any validation for _, key := range repeatableHTTPRouteFilters { - counts[key] = 0 + delete(counts, key) } for filterType, count := range counts { @@ -64,7 +64,32 @@ func validateHTTPRouteUniqueFilters(rules []gatewayv1a2.HTTPRouteRule, path *fie } } + if errList := validateHTTPBackendUniqueFilters(rule.BackendRefs, path, i); len(errList) > 0 { + errs = append(errs, errList...) + } } return errs } + +func validateHTTPBackendUniqueFilters(ref []gatewayv1a2.HTTPBackendRef, path *field.Path, i int) field.ErrorList { + var errs field.ErrorList + + for _, bkr := range ref { + counts := map[gatewayv1a2.HTTPRouteFilterType]int{} + for _, filter := range bkr.Filters { + counts[filter.Type]++ + } + + for _, key := range repeatableHTTPRouteFilters { + delete(counts, key) + } + + for filterType, count := range counts { + if count > 1 { + errs = append(errs, field.Invalid(path.Index(i).Child("BackendRefs"), filterType, "cannot be used multiple times in the same backend")) + } + } + } + return errs +} diff --git a/apis/v1alpha2/validation/httproute_test.go b/apis/v1alpha2/validation/httproute_test.go index 3923f75fdc..e6ccd3c36b 100644 --- a/apis/v1alpha2/validation/httproute_test.go +++ b/apis/v1alpha2/validation/httproute_test.go @@ -19,9 +19,11 @@ package validation import ( "testing" + "k8s.io/apimachinery/pkg/util/validation/field" utilpointer "k8s.io/utils/pointer" gatewayv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + pkgutils "sigs.k8s.io/gateway-api/pkg/util" ) func TestValidateHTTPRoute(t *testing.T) { @@ -29,33 +31,29 @@ func TestValidateHTTPRoute(t *testing.T) { specialService := "special-service" tests := []struct { name string - hRoute gatewayv1a2.HTTPRoute + rules []gatewayv1a2.HTTPRouteRule errCount int }{ { name: "valid httpRoute with no filters", - hRoute: gatewayv1a2.HTTPRoute{ - Spec: gatewayv1a2.HTTPRouteSpec{ - Rules: []gatewayv1a2.HTTPRouteRule{ + rules: []gatewayv1a2.HTTPRouteRule{ + { + Matches: []gatewayv1a2.HTTPRouteMatch{ { - Matches: []gatewayv1a2.HTTPRouteMatch{ - { - Path: &gatewayv1a2.HTTPPathMatch{ - Type: pathMatchTypePtr("Prefix"), - Value: utilpointer.String("/"), - }, - }, + Path: &gatewayv1a2.HTTPPathMatch{ + Type: pkgutils.PathMatchTypePtr("Prefix"), + Value: utilpointer.String("/"), }, - BackendRefs: []gatewayv1a2.HTTPBackendRef{ - { - BackendRef: gatewayv1a2.BackendRef{ - BackendObjectReference: gatewayv1a2.BackendObjectReference{ - Name: testService, - Port: portNumberPtr(8080), - }, - Weight: utilpointer.Int32(100), - }, + }, + }, + BackendRefs: []gatewayv1a2.HTTPBackendRef{ + { + BackendRef: gatewayv1a2.BackendRef{ + BackendObjectReference: gatewayv1a2.BackendObjectReference{ + Name: testService, + Port: pkgutils.PortNumberPtr(8080), }, + Weight: utilpointer.Int32(100), }, }, }, @@ -65,27 +63,23 @@ func TestValidateHTTPRoute(t *testing.T) { }, { name: "valid httpRoute with 1 filter", - hRoute: gatewayv1a2.HTTPRoute{ - Spec: gatewayv1a2.HTTPRouteSpec{ - Rules: []gatewayv1a2.HTTPRouteRule{ + rules: []gatewayv1a2.HTTPRouteRule{ + { + Matches: []gatewayv1a2.HTTPRouteMatch{ { - Matches: []gatewayv1a2.HTTPRouteMatch{ - { - Path: &gatewayv1a2.HTTPPathMatch{ - Type: pathMatchTypePtr("Prefix"), - Value: utilpointer.String("/"), - }, - }, + Path: &gatewayv1a2.HTTPPathMatch{ + Type: pkgutils.PathMatchTypePtr("Prefix"), + Value: utilpointer.String("/"), }, - Filters: []gatewayv1a2.HTTPRouteFilter{ - { - Type: gatewayv1a2.HTTPRouteFilterRequestMirror, - RequestMirror: &gatewayv1a2.HTTPRequestMirrorFilter{ - BackendRef: gatewayv1a2.BackendObjectReference{ - Name: testService, - Port: portNumberPtr(8081), - }, - }, + }, + }, + Filters: []gatewayv1a2.HTTPRouteFilter{ + { + Type: gatewayv1a2.HTTPRouteFilterRequestMirror, + RequestMirror: &gatewayv1a2.HTTPRequestMirrorFilter{ + BackendRef: gatewayv1a2.BackendObjectReference{ + Name: testService, + Port: pkgutils.PortNumberPtr(8081), }, }, }, @@ -96,36 +90,32 @@ func TestValidateHTTPRoute(t *testing.T) { }, { name: "invalid httpRoute with 2 extended filters", - hRoute: gatewayv1a2.HTTPRoute{ - Spec: gatewayv1a2.HTTPRouteSpec{ - Rules: []gatewayv1a2.HTTPRouteRule{ + rules: []gatewayv1a2.HTTPRouteRule{ + { + Matches: []gatewayv1a2.HTTPRouteMatch{ { - Matches: []gatewayv1a2.HTTPRouteMatch{ - { - Path: &gatewayv1a2.HTTPPathMatch{ - Type: pathMatchTypePtr("Prefix"), - Value: utilpointer.String("/"), - }, - }, + Path: &gatewayv1a2.HTTPPathMatch{ + Type: pkgutils.PathMatchTypePtr("Prefix"), + Value: utilpointer.String("/"), }, - Filters: []gatewayv1a2.HTTPRouteFilter{ - { - Type: gatewayv1a2.HTTPRouteFilterRequestMirror, - RequestMirror: &gatewayv1a2.HTTPRequestMirrorFilter{ - BackendRef: gatewayv1a2.BackendObjectReference{ - Name: testService, - Port: portNumberPtr(8080), - }, - }, + }, + }, + Filters: []gatewayv1a2.HTTPRouteFilter{ + { + Type: gatewayv1a2.HTTPRouteFilterRequestMirror, + RequestMirror: &gatewayv1a2.HTTPRequestMirrorFilter{ + BackendRef: gatewayv1a2.BackendObjectReference{ + Name: testService, + Port: pkgutils.PortNumberPtr(8080), }, - { - Type: gatewayv1a2.HTTPRouteFilterRequestMirror, - RequestMirror: &gatewayv1a2.HTTPRequestMirrorFilter{ - BackendRef: gatewayv1a2.BackendObjectReference{ - Name: specialService, - Port: portNumberPtr(8080), - }, - }, + }, + }, + { + Type: gatewayv1a2.HTTPRouteFilterRequestMirror, + RequestMirror: &gatewayv1a2.HTTPRequestMirrorFilter{ + BackendRef: gatewayv1a2.BackendObjectReference{ + Name: specialService, + Port: pkgutils.PortNumberPtr(8080), }, }, }, @@ -136,48 +126,44 @@ func TestValidateHTTPRoute(t *testing.T) { }, { name: "invalid httpRoute with mix of filters and one duplicate", - hRoute: gatewayv1a2.HTTPRoute{ - Spec: gatewayv1a2.HTTPRouteSpec{ - Rules: []gatewayv1a2.HTTPRouteRule{ + rules: []gatewayv1a2.HTTPRouteRule{ + { + Matches: []gatewayv1a2.HTTPRouteMatch{ { - Matches: []gatewayv1a2.HTTPRouteMatch{ - { - Path: &gatewayv1a2.HTTPPathMatch{ - Type: pathMatchTypePtr("Prefix"), - Value: utilpointer.String("/"), - }, - }, + Path: &gatewayv1a2.HTTPPathMatch{ + Type: pkgutils.PathMatchTypePtr("Prefix"), + Value: utilpointer.String("/"), }, - Filters: []gatewayv1a2.HTTPRouteFilter{ - { - Type: gatewayv1a2.HTTPRouteFilterRequestHeaderModifier, - RequestHeaderModifier: &gatewayv1a2.HTTPRequestHeaderFilter{ - Set: []gatewayv1a2.HTTPHeader{ - { - Name: "special-header", - Value: "foo", - }, - }, + }, + }, + Filters: []gatewayv1a2.HTTPRouteFilter{ + { + Type: gatewayv1a2.HTTPRouteFilterRequestHeaderModifier, + RequestHeaderModifier: &gatewayv1a2.HTTPRequestHeaderFilter{ + Set: []gatewayv1a2.HTTPHeader{ + { + Name: "special-header", + Value: "foo", }, }, - { - Type: gatewayv1a2.HTTPRouteFilterRequestMirror, - RequestMirror: &gatewayv1a2.HTTPRequestMirrorFilter{ - BackendRef: gatewayv1a2.BackendObjectReference{ - Name: testService, - Port: portNumberPtr(8080), - }, - }, + }, + }, + { + Type: gatewayv1a2.HTTPRouteFilterRequestMirror, + RequestMirror: &gatewayv1a2.HTTPRequestMirrorFilter{ + BackendRef: gatewayv1a2.BackendObjectReference{ + Name: testService, + Port: pkgutils.PortNumberPtr(8080), }, - { - Type: gatewayv1a2.HTTPRouteFilterRequestHeaderModifier, - RequestHeaderModifier: &gatewayv1a2.HTTPRequestHeaderFilter{ - Add: []gatewayv1a2.HTTPHeader{ - { - Name: "my-header", - Value: "bar", - }, - }, + }, + }, + { + Type: gatewayv1a2.HTTPRouteFilterRequestHeaderModifier, + RequestHeaderModifier: &gatewayv1a2.HTTPRequestHeaderFilter{ + Add: []gatewayv1a2.HTTPHeader{ + { + Name: "my-header", + Value: "bar", }, }, }, @@ -189,134 +175,216 @@ func TestValidateHTTPRoute(t *testing.T) { }, { name: "invalid httpRoute with multiple duplicate filters", - hRoute: gatewayv1a2.HTTPRoute{ - Spec: gatewayv1a2.HTTPRouteSpec{ - Rules: []gatewayv1a2.HTTPRouteRule{ + rules: []gatewayv1a2.HTTPRouteRule{ + { + Matches: []gatewayv1a2.HTTPRouteMatch{ { - Matches: []gatewayv1a2.HTTPRouteMatch{ - { - Path: &gatewayv1a2.HTTPPathMatch{ - Type: pathMatchTypePtr("Prefix"), - Value: utilpointer.String("/"), + Path: &gatewayv1a2.HTTPPathMatch{ + Type: pkgutils.PathMatchTypePtr("Prefix"), + Value: utilpointer.String("/"), + }, + }, + }, + Filters: []gatewayv1a2.HTTPRouteFilter{ + { + Type: gatewayv1a2.HTTPRouteFilterRequestMirror, + RequestMirror: &gatewayv1a2.HTTPRequestMirrorFilter{ + BackendRef: gatewayv1a2.BackendObjectReference{ + Name: testService, + Port: pkgutils.PortNumberPtr(8080), + }, + }, + }, + { + Type: gatewayv1a2.HTTPRouteFilterRequestHeaderModifier, + RequestHeaderModifier: &gatewayv1a2.HTTPRequestHeaderFilter{ + Set: []gatewayv1a2.HTTPHeader{ + { + Name: "special-header", + Value: "foo", }, }, }, - Filters: []gatewayv1a2.HTTPRouteFilter{ - { - Type: gatewayv1a2.HTTPRouteFilterRequestMirror, - RequestMirror: &gatewayv1a2.HTTPRequestMirrorFilter{ - BackendRef: gatewayv1a2.BackendObjectReference{ - Name: testService, - Port: portNumberPtr(8080), - }, + }, + { + Type: gatewayv1a2.HTTPRouteFilterRequestMirror, + RequestMirror: &gatewayv1a2.HTTPRequestMirrorFilter{ + BackendRef: gatewayv1a2.BackendObjectReference{ + Name: testService, + Port: pkgutils.PortNumberPtr(8080), + }, + }, + }, + { + Type: gatewayv1a2.HTTPRouteFilterRequestHeaderModifier, + RequestHeaderModifier: &gatewayv1a2.HTTPRequestHeaderFilter{ + Add: []gatewayv1a2.HTTPHeader{ + { + Name: "my-header", + Value: "bar", }, }, - { - Type: gatewayv1a2.HTTPRouteFilterRequestHeaderModifier, - RequestHeaderModifier: &gatewayv1a2.HTTPRequestHeaderFilter{ - Set: []gatewayv1a2.HTTPHeader{ - { - Name: "special-header", - Value: "foo", - }, - }, + }, + }, + { + Type: gatewayv1a2.HTTPRouteFilterRequestMirror, + RequestMirror: &gatewayv1a2.HTTPRequestMirrorFilter{ + BackendRef: gatewayv1a2.BackendObjectReference{ + Name: specialService, + Port: pkgutils.PortNumberPtr(8080), + }, + }, + }, + }, + }, + }, + errCount: 2, + }, + { + name: "valid httpRoute with duplicate ExtensionRef filters", + rules: []gatewayv1a2.HTTPRouteRule{ + { + Matches: []gatewayv1a2.HTTPRouteMatch{ + { + Path: &gatewayv1a2.HTTPPathMatch{ + Type: pkgutils.PathMatchTypePtr("Prefix"), + Value: utilpointer.String("/"), + }, + }, + }, + Filters: []gatewayv1a2.HTTPRouteFilter{ + { + Type: gatewayv1a2.HTTPRouteFilterRequestHeaderModifier, + RequestHeaderModifier: &gatewayv1a2.HTTPRequestHeaderFilter{ + Set: []gatewayv1a2.HTTPHeader{ + { + Name: "special-header", + Value: "foo", }, }, + }, + }, + { + Type: gatewayv1a2.HTTPRouteFilterRequestMirror, + RequestMirror: &gatewayv1a2.HTTPRequestMirrorFilter{ + BackendRef: gatewayv1a2.BackendObjectReference{ + Name: testService, + Port: pkgutils.PortNumberPtr(8080), + }, + }, + }, + { + Type: "ExtensionRef", + }, + { + Type: "ExtensionRef", + }, + { + Type: "ExtensionRef", + }, + }, + }, + }, + errCount: 0, + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + errs := validateHTTPRouteUniqueFilters(tc.rules, field.NewPath("spec").Child("rules")) + if len(errs) != tc.errCount { + t.Errorf("ValidateHTTPRoute() got %v errors, want %v errors", len(errs), tc.errCount) + } + }) + } +} + +func TestValidateHTTPBackendUniqueFilters(t *testing.T) { + var testService = "testService" + var specialService = "specialService" + tests := []struct { + name string + hRoute gatewayv1a2.HTTPRoute + errCount int + }{ + { + name: "valid httpRoute Rules backendref filters", + hRoute: gatewayv1a2.HTTPRoute{ + Spec: gatewayv1a2.HTTPRouteSpec{ + Rules: []gatewayv1a2.HTTPRouteRule{ + { + BackendRefs: []gatewayv1a2.HTTPBackendRef{ { - Type: gatewayv1a2.HTTPRouteFilterRequestMirror, - RequestMirror: &gatewayv1a2.HTTPRequestMirrorFilter{ - BackendRef: gatewayv1a2.BackendObjectReference{ + BackendRef: gatewayv1a2.BackendRef{ + BackendObjectReference: gatewayv1a2.BackendObjectReference{ Name: testService, - Port: portNumberPtr(8080), + Port: pkgutils.PortNumberPtr(8080), }, + Weight: utilpointer.Int32(100), }, - }, - { - Type: gatewayv1a2.HTTPRouteFilterRequestHeaderModifier, - RequestHeaderModifier: &gatewayv1a2.HTTPRequestHeaderFilter{ - Add: []gatewayv1a2.HTTPHeader{ - { - Name: "my-header", - Value: "bar", + Filters: []gatewayv1a2.HTTPRouteFilter{ + { + Type: gatewayv1a2.HTTPRouteFilterRequestMirror, + RequestMirror: &gatewayv1a2.HTTPRequestMirrorFilter{ + BackendRef: gatewayv1a2.BackendObjectReference{ + Name: testService, + Port: pkgutils.PortNumberPtr(8080), + }, }, }, }, }, - { - Type: gatewayv1a2.HTTPRouteFilterRequestMirror, - RequestMirror: &gatewayv1a2.HTTPRequestMirrorFilter{ - BackendRef: gatewayv1a2.BackendObjectReference{ - Name: specialService, - Port: portNumberPtr(8080), - }, - }, - }, }, }, }, }, }, - errCount: 2, + errCount: 0, }, { - name: "valid httpRoute with duplicate ExtensionRef filters", + name: "invalid httpRoute Rules backendref filters", hRoute: gatewayv1a2.HTTPRoute{ Spec: gatewayv1a2.HTTPRouteSpec{ Rules: []gatewayv1a2.HTTPRouteRule{ { - Matches: []gatewayv1a2.HTTPRouteMatch{ - { - Path: &gatewayv1a2.HTTPPathMatch{ - Type: pathMatchTypePtr("Prefix"), - Value: utilpointer.String("/"), - }, - }, - }, - Filters: []gatewayv1a2.HTTPRouteFilter{ + BackendRefs: []gatewayv1a2.HTTPBackendRef{ { - Type: gatewayv1a2.HTTPRouteFilterRequestHeaderModifier, - RequestHeaderModifier: &gatewayv1a2.HTTPRequestHeaderFilter{ - Set: []gatewayv1a2.HTTPHeader{ - { - Name: "special-header", - Value: "foo", + Filters: []gatewayv1a2.HTTPRouteFilter{ + { + Type: gatewayv1a2.HTTPRouteFilterRequestMirror, + RequestMirror: &gatewayv1a2.HTTPRequestMirrorFilter{ + BackendRef: gatewayv1a2.BackendObjectReference{ + Name: testService, + Port: pkgutils.PortNumberPtr(8080), + }, }, }, - }, - }, - { - Type: gatewayv1a2.HTTPRouteFilterRequestMirror, - RequestMirror: &gatewayv1a2.HTTPRequestMirrorFilter{ - BackendRef: gatewayv1a2.BackendObjectReference{ - Name: testService, - Port: portNumberPtr(8080), + { + Type: gatewayv1a2.HTTPRouteFilterRequestMirror, + RequestMirror: &gatewayv1a2.HTTPRequestMirrorFilter{ + BackendRef: gatewayv1a2.BackendObjectReference{ + Name: specialService, + Port: pkgutils.PortNumberPtr(8080), + }, + }, }, }, }, - { - Type: "ExtensionRef", - }, - { - Type: "ExtensionRef", - }, - { - Type: "ExtensionRef", - }, }, }, }, }, }, - errCount: 0, + errCount: 1, }, } - for _, tt := range tests { - // copy variable to avoid scope problems with ranges - tt := tt - t.Run(tt.name, func(t *testing.T) { - errs := ValidateHTTPRoute(&tt.hRoute) - if len(errs) != tt.errCount { - t.Errorf("ValidateHTTPRoute() got %v errors, want %v errors", len(errs), tt.errCount) + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + for index, rule := range tc.hRoute.Spec.Rules { + errs := validateHTTPBackendUniqueFilters(rule.BackendRefs, field.NewPath("spec").Child("rules"), index) + if len(errs) != tc.errCount { + t.Errorf("ValidateHTTPRoute() got %d errors, want %d errors", len(errs), tc.errCount) + } } }) } diff --git a/apis/v1alpha2/validation/validation_test.go b/pkg/util/utils.go similarity index 76% rename from apis/v1alpha2/validation/validation_test.go rename to pkg/util/utils.go index 44dd28d82c..9513bbff27 100644 --- a/apis/v1alpha2/validation/validation_test.go +++ b/pkg/util/utils.go @@ -14,18 +14,20 @@ See the License for the specific language governing permissions and limitations under the License. */ -package validation +package utils import ( gatewayv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" ) -func pathMatchTypePtr(s string) *gatewayv1a2.PathMatchType { +// PathMatchTypePtr translates a string to *PathMatchType +func PathMatchTypePtr(s string) *gatewayv1a2.PathMatchType { result := gatewayv1a2.PathMatchType(s) return &result } -func portNumberPtr(p int) *gatewayv1a2.PortNumber { +// PortNumberPtr translates an int to a *PortNumber +func PortNumberPtr(p int) *gatewayv1a2.PortNumber { result := gatewayv1a2.PortNumber(p) return &result } diff --git a/pkg/util/utils_test.go b/pkg/util/utils_test.go new file mode 100644 index 0000000000..65345bdee9 --- /dev/null +++ b/pkg/util/utils_test.go @@ -0,0 +1,104 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package utils + +import ( + "testing" + + gatewayv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" +) + +func Test_PortNumberPtr(t *testing.T) { + var exportedPort65535 gatewayv1a2.PortNumber = 65535 + var exportedPort1 gatewayv1a2.PortNumber = 1 + var exportedPort0 gatewayv1a2.PortNumber = 0 + var exportedPort65536 gatewayv1a2.PortNumber = 65536 + + portNumberPtrTests := []struct { + name string + port int + expectedPort *gatewayv1a2.PortNumber + }{ + { + name: "invalid port number", + port: 0, + expectedPort: &exportedPort0, + }, + { + name: "valid port number", + port: 65535, + expectedPort: &exportedPort65535, + }, + { + name: "invalid port number", + port: 65536, + expectedPort: &exportedPort65536, + }, + { + name: "valid port number", + port: 1, + expectedPort: &exportedPort1, + }, + } + + for _, tc := range portNumberPtrTests { + t.Run(tc.name, func(t *testing.T) { + port := PortNumberPtr(tc.port) + if port == nil || tc.expectedPort == nil { + if port != tc.expectedPort { + t.Errorf("Expected port %d, got %d", tc.expectedPort, port) + } + } else if *port != *tc.expectedPort { + t.Errorf("Expected port %d, got %d", *tc.expectedPort, *port) + } + }) + } +} + +func Test_PathMatchTypePtr(t *testing.T) { + pathMatchTypePtrTests := []struct { + name string + pathType string + expectedPath gatewayv1a2.PathMatchType + }{ + { + name: "valid path exact match", + pathType: "Exact", + expectedPath: gatewayv1a2.PathMatchExact, + }, + + { + name: "valid path prefix match", + pathType: "Prefix", + expectedPath: gatewayv1a2.PathMatchPrefix, + }, + { + name: "valid path regular expression match", + pathType: "RegularExpression", + expectedPath: gatewayv1a2.PathMatchRegularExpression, + }, + } + + for _, tc := range pathMatchTypePtrTests { + t.Run(tc.name, func(t *testing.T) { + path := PathMatchTypePtr(tc.pathType) + if *path != tc.expectedPath { + t.Errorf("Expected path %s, got %s", tc.expectedPath, *path) + } + }) + } +}