sigs.k8s.io/gateway-api@v1.0.0/conformance/tests/httproute-request-header-modifier.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, HTTPRouteRequestHeaderModifier) 31 } 32 33 var HTTPRouteRequestHeaderModifier = suite.ConformanceTest{ 34 ShortName: "HTTPRouteRequestHeaderModifier", 35 Description: "An HTTPRoute has request header modifier filters applied correctly", 36 Features: []suite.SupportedFeature{ 37 suite.SupportGateway, 38 suite.SupportHTTPRoute, 39 }, 40 Manifests: []string{"tests/httproute-request-header-modifier.yaml"}, 41 Test: func(t *testing.T, suite *suite.ConformanceTestSuite) { 42 ns := "gateway-conformance-infra" 43 routeNN := types.NamespacedName{Name: "request-header-modifier", Namespace: ns} 44 gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns} 45 gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN) 46 kubernetes.HTTPRouteMustHaveResolvedRefsConditionsTrue(t, suite.Client, suite.TimeoutConfig, routeNN, gwNN) 47 48 testCases := []http.ExpectedResponse{{ 49 Request: http.Request{ 50 Path: "/set", 51 Headers: map[string]string{ 52 "Some-Other-Header": "val", 53 }, 54 }, 55 ExpectedRequest: &http.ExpectedRequest{ 56 Request: http.Request{ 57 Path: "/set", 58 Headers: map[string]string{ 59 "Some-Other-Header": "val", 60 "X-Header-Set": "set-overwrites-values", 61 }, 62 }, 63 }, 64 Backend: "infra-backend-v1", 65 Namespace: ns, 66 }, { 67 Request: http.Request{ 68 Path: "/set", 69 Headers: map[string]string{ 70 "Some-Other-Header": "val", 71 "X-Header-Set": "some-other-value", 72 }, 73 }, 74 ExpectedRequest: &http.ExpectedRequest{ 75 Request: http.Request{ 76 Path: "/set", 77 Headers: map[string]string{ 78 "Some-Other-Header": "val", 79 "X-Header-Set": "set-overwrites-values", 80 }, 81 }, 82 }, 83 Backend: "infra-backend-v1", 84 Namespace: ns, 85 }, { 86 Request: http.Request{ 87 Path: "/add", 88 Headers: map[string]string{ 89 "Some-Other-Header": "val", 90 }, 91 }, 92 ExpectedRequest: &http.ExpectedRequest{ 93 Request: http.Request{ 94 Path: "/add", 95 Headers: map[string]string{ 96 "Some-Other-Header": "val", 97 "X-Header-Add": "add-appends-values", 98 }, 99 }, 100 }, 101 Backend: "infra-backend-v1", 102 Namespace: ns, 103 }, { 104 Request: http.Request{ 105 Path: "/add", 106 Headers: map[string]string{ 107 "Some-Other-Header": "val", 108 "X-Header-Add": "some-other-value", 109 }, 110 }, 111 ExpectedRequest: &http.ExpectedRequest{ 112 Request: http.Request{ 113 Path: "/add", 114 Headers: map[string]string{ 115 "Some-Other-Header": "val", 116 "X-Header-Add": "some-other-value,add-appends-values", 117 }, 118 }, 119 }, 120 Backend: "infra-backend-v1", 121 Namespace: ns, 122 }, { 123 Request: http.Request{ 124 Path: "/remove", 125 Headers: map[string]string{ 126 "X-Header-Remove": "val", 127 }, 128 }, 129 ExpectedRequest: &http.ExpectedRequest{ 130 Request: http.Request{ 131 Path: "/remove", 132 }, 133 AbsentHeaders: []string{"X-Header-Remove"}, 134 }, 135 Backend: "infra-backend-v1", 136 Namespace: ns, 137 }, { 138 Request: http.Request{ 139 Path: "/multiple", 140 Headers: map[string]string{ 141 "X-Header-Set-2": "set-val-2", 142 "X-Header-Add-2": "add-val-2", 143 "X-Header-Remove-2": "remove-val-2", 144 "Another-Header": "another-header-val", 145 }, 146 }, 147 ExpectedRequest: &http.ExpectedRequest{ 148 Request: http.Request{ 149 Path: "/multiple", 150 Headers: map[string]string{ 151 "X-Header-Set-1": "header-set-1", 152 "X-Header-Set-2": "header-set-2", 153 "X-Header-Add-1": "header-add-1", 154 "X-Header-Add-2": "add-val-2,header-add-2", 155 "X-Header-Add-3": "header-add-3", 156 "Another-Header": "another-header-val", 157 }, 158 }, 159 AbsentHeaders: []string{"X-Header-Remove-1", "X-Header-Remove-2"}, 160 }, 161 Backend: "infra-backend-v1", 162 Namespace: ns, 163 }, { 164 Request: http.Request{ 165 Path: "/case-insensitivity", 166 // The filter uses canonicalized header names, 167 // the request uses lowercase names. 168 Headers: map[string]string{ 169 "x-header-set": "original-val-set", 170 "x-header-add": "original-val-add", 171 "x-header-remove": "original-val-remove", 172 "Another-Header": "another-header-val", 173 }, 174 }, 175 ExpectedRequest: &http.ExpectedRequest{ 176 Request: http.Request{ 177 Path: "/case-insensitivity", 178 Headers: map[string]string{ 179 "X-Header-Set": "header-set", 180 "X-Header-Add": "original-val-add,header-add", 181 "Another-Header": "another-header-val", 182 }, 183 }, 184 AbsentHeaders: []string{"x-header-remove", "X-Header-Remove"}, 185 }, 186 Backend: "infra-backend-v1", 187 Namespace: ns, 188 }} 189 190 for i := range testCases { 191 // Declare tc here to avoid loop variable 192 // reuse issues across parallel tests. 193 tc := testCases[i] 194 t.Run(tc.GetTestCaseName(i), func(t *testing.T) { 195 t.Parallel() 196 http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, tc) 197 }) 198 } 199 }, 200 }