sigs.k8s.io/gateway-api@v1.0.0/conformance/tests/httproute-method-matching.go (about) 1 /* 2 Copyright 2022 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package tests 18 19 import ( 20 "testing" 21 22 "k8s.io/apimachinery/pkg/types" 23 24 "sigs.k8s.io/gateway-api/conformance/utils/http" 25 "sigs.k8s.io/gateway-api/conformance/utils/kubernetes" 26 "sigs.k8s.io/gateway-api/conformance/utils/suite" 27 ) 28 29 func init() { 30 ConformanceTests = append(ConformanceTests, HTTPRouteMethodMatching) 31 } 32 33 var HTTPRouteMethodMatching = suite.ConformanceTest{ 34 ShortName: "HTTPRouteMethodMatching", 35 Description: "A single HTTPRoute with method matching for different backends", 36 Manifests: []string{"tests/httproute-method-matching.yaml"}, 37 Features: []suite.SupportedFeature{ 38 suite.SupportGateway, 39 suite.SupportHTTPRoute, 40 suite.SupportHTTPRouteMethodMatching, 41 }, 42 Test: func(t *testing.T, suite *suite.ConformanceTestSuite) { 43 ns := "gateway-conformance-infra" 44 routeNN := types.NamespacedName{Name: "method-matching", Namespace: ns} 45 gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns} 46 gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN) 47 kubernetes.HTTPRouteMustHaveResolvedRefsConditionsTrue(t, suite.Client, suite.TimeoutConfig, routeNN, gwNN) 48 49 testCases := []http.ExpectedResponse{ 50 { 51 Request: http.Request{Method: "POST", Path: "/"}, 52 Backend: "infra-backend-v1", 53 Namespace: ns, 54 }, { 55 Request: http.Request{Method: "GET", Path: "/"}, 56 Backend: "infra-backend-v2", 57 Namespace: ns, 58 }, { 59 Request: http.Request{Method: "HEAD", Path: "/"}, 60 Response: http.Response{StatusCode: 404}, 61 }, 62 } 63 64 // Combinations of method matching with other core matches. 65 testCases = append(testCases, []http.ExpectedResponse{ 66 { 67 Request: http.Request{Path: "/path1", Method: "GET"}, 68 Backend: "infra-backend-v1", 69 Namespace: ns, 70 }, 71 { 72 Request: http.Request{Headers: map[string]string{"version": "one"}, Path: "/", Method: "PUT"}, 73 Backend: "infra-backend-v2", 74 Namespace: ns, 75 }, 76 { 77 Request: http.Request{Headers: map[string]string{"version": "two"}, Path: "/path2", Method: "POST"}, 78 Backend: "infra-backend-v3", 79 Namespace: ns, 80 }, 81 }...) 82 83 // Ensure that combinations of matches which are OR'd together match 84 // even if only one of them is used in the request. 85 testCases = append(testCases, []http.ExpectedResponse{ 86 { 87 Request: http.Request{Path: "/path3", Method: "PATCH"}, 88 Backend: "infra-backend-v1", 89 Namespace: ns, 90 }, 91 { 92 Request: http.Request{Headers: map[string]string{"version": "three"}, Path: "/path4", Method: "DELETE"}, 93 Backend: "infra-backend-v1", 94 Namespace: ns, 95 }, 96 }...) 97 98 // Ensure that combinations of match types which are ANDed together do not match 99 // when only a subset of match types is used in the request. 100 testCases = append(testCases, []http.ExpectedResponse{ 101 { 102 Request: http.Request{Path: "/", Method: "PUT"}, 103 Response: http.Response{StatusCode: 404}, 104 }, 105 { 106 Request: http.Request{Path: "/path4", Method: "DELETE"}, 107 Response: http.Response{StatusCode: 404}, 108 }, 109 }...) 110 111 // For requests that satisfy multiple matches, ensure precedence order 112 // defined by the Gateway API spec is maintained. 113 testCases = append(testCases, []http.ExpectedResponse{ 114 { 115 Request: http.Request{Path: "/path5", Method: "PATCH"}, 116 Backend: "infra-backend-v1", 117 Namespace: ns, 118 }, 119 { 120 Request: http.Request{Headers: map[string]string{"version": "four"}, Path: "/", Method: "PATCH"}, 121 Backend: "infra-backend-v2", 122 Namespace: ns, 123 }, 124 }...) 125 126 for i := range testCases { 127 // Declare tc here to avoid loop variable 128 // reuse issues across parallel tests. 129 tc := testCases[i] 130 t.Run(tc.GetTestCaseName(i), func(t *testing.T) { 131 t.Parallel() 132 http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, tc) 133 }) 134 } 135 }, 136 }