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