1
2
3
4
19
20 package main
21
22 import (
23 "fmt"
24 "testing"
25 "time"
26
27 gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
28
29 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
30 )
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 func TestHTTPRouteParentRefExperimental(t *testing.T) {
48 tests := []struct {
49 name string
50 wantErrors []string
51 parentRefs []gatewayv1.ParentReference
52 }{
53 {
54 name: "invalid because duplicate parent refs without port or section name",
55 wantErrors: []string{"sectionName or port must be unique when parentRefs includes 2 or more references to the same parent"},
56 parentRefs: []gatewayv1.ParentReference{{
57 Kind: ptrTo(gatewayv1.Kind("Gateway")),
58 Group: ptrTo(gatewayv1.Group("gateway.networking.k8s.io")),
59 Name: "example",
60 }, {
61 Kind: ptrTo(gatewayv1.Kind("Gateway")),
62 Group: ptrTo(gatewayv1.Group("gateway.networking.k8s.io")),
63 Name: "example",
64 }},
65 },
66 {
67 name: "invalid because duplicate parent refs with only one port",
68 wantErrors: []string{"sectionName or port must be specified when parentRefs includes 2 or more references to the same parent"},
69 parentRefs: []gatewayv1.ParentReference{{
70 Kind: ptrTo(gatewayv1.Kind("Gateway")),
71 Group: ptrTo(gatewayv1.Group("gateway.networking.k8s.io")),
72 Name: "example",
73 }, {
74 Kind: ptrTo(gatewayv1.Kind("Gateway")),
75 Group: ptrTo(gatewayv1.Group("gateway.networking.k8s.io")),
76 Name: "example",
77 Port: ptrTo(gatewayv1.PortNumber(80)),
78 }},
79 },
80 {
81 name: "invalid because duplicate parent refs with only one sectionName and port",
82 wantErrors: []string{"sectionName or port must be specified when parentRefs includes 2 or more references to the same parent"},
83 parentRefs: []gatewayv1.ParentReference{{
84 Kind: ptrTo(gatewayv1.Kind("Gateway")),
85 Group: ptrTo(gatewayv1.Group("gateway.networking.k8s.io")),
86 Name: "example",
87 }, {
88 Kind: ptrTo(gatewayv1.Kind("Gateway")),
89 Group: ptrTo(gatewayv1.Group("gateway.networking.k8s.io")),
90 Name: "example",
91 SectionName: ptrTo(gatewayv1.SectionName("foo")),
92 Port: ptrTo(gatewayv1.PortNumber(80)),
93 }},
94 },
95 {
96 name: "invalid because duplicate parent refs with duplicate ports",
97 wantErrors: []string{"sectionName or port must be unique when parentRefs includes 2 or more references to the same parent"},
98 parentRefs: []gatewayv1.ParentReference{{
99 Kind: ptrTo(gatewayv1.Kind("Gateway")),
100 Group: ptrTo(gatewayv1.Group("gateway.networking.k8s.io")),
101 Name: "example",
102 Port: ptrTo(gatewayv1.PortNumber(80)),
103 }, {
104 Kind: ptrTo(gatewayv1.Kind("Gateway")),
105 Group: ptrTo(gatewayv1.Group("gateway.networking.k8s.io")),
106 Name: "example",
107 Port: ptrTo(gatewayv1.PortNumber(80)),
108 }},
109 },
110 {
111 name: "valid single parentRef without sectionName or port",
112 wantErrors: []string{},
113 parentRefs: []gatewayv1.ParentReference{{
114 Kind: ptrTo(gatewayv1.Kind("Gateway")),
115 Group: ptrTo(gatewayv1.Group("gateway.networking.k8s.io")),
116 Name: "example",
117 }},
118 },
119 {
120 name: "valid single parentRef with sectionName and port",
121 wantErrors: []string{},
122 parentRefs: []gatewayv1.ParentReference{{
123 Kind: ptrTo(gatewayv1.Kind("Gateway")),
124 Group: ptrTo(gatewayv1.Group("gateway.networking.k8s.io")),
125 Name: "example",
126 SectionName: ptrTo(gatewayv1.SectionName("foo")),
127 Port: ptrTo(gatewayv1.PortNumber(443)),
128 }},
129 },
130 {
131 name: "valid because duplicate parent refs with different ports",
132 wantErrors: []string{},
133 parentRefs: []gatewayv1.ParentReference{{
134 Kind: ptrTo(gatewayv1.Kind("Gateway")),
135 Group: ptrTo(gatewayv1.Group("gateway.networking.k8s.io")),
136 Name: "example",
137 Port: ptrTo(gatewayv1.PortNumber(80)),
138 }, {
139 Kind: ptrTo(gatewayv1.Kind("Gateway")),
140 Group: ptrTo(gatewayv1.Group("gateway.networking.k8s.io")),
141 Name: "example",
142 Port: ptrTo(gatewayv1.PortNumber(443)),
143 }},
144 },
145 {
146 name: "invalid ParentRefs with multiple mixed references to the same parent",
147 wantErrors: []string{"sectionName or port must be specified when parentRefs includes 2 or more references to the same parent"},
148 parentRefs: []gatewayv1.ParentReference{{
149 Kind: ptrTo(gatewayv1.Kind("Gateway")),
150 Group: ptrTo(gatewayv1.Group("gateway.networking.k8s.io")),
151 Name: "example",
152 SectionName: ptrTo(gatewayv1.SectionName("foo")),
153 }, {
154 Kind: ptrTo(gatewayv1.Kind("Gateway")),
155 Group: ptrTo(gatewayv1.Group("gateway.networking.k8s.io")),
156 Name: "example",
157 Port: ptrTo(gatewayv1.PortNumber(443)),
158 }},
159 },
160 {
161 name: "valid ParentRefs with multiple same port references to different section of a parent",
162 wantErrors: []string{},
163 parentRefs: []gatewayv1.ParentReference{{
164 Name: "example",
165 Port: ptrTo(gatewayv1.PortNumber(443)),
166 SectionName: ptrTo(gatewayv1.SectionName("foo")),
167 }, {
168 Name: "example",
169 Port: ptrTo(gatewayv1.PortNumber(443)),
170 SectionName: ptrTo(gatewayv1.SectionName("bar")),
171 }},
172 },
173 {
174
175
176
177 name: "invalid because duplicate parent refs with first having sectionName and second having both sectionName and port",
178 wantErrors: []string{"sectionName or port must be specified when parentRefs includes 2 or more references to the same parent"},
179 parentRefs: []gatewayv1.ParentReference{{
180 Kind: ptrTo(gatewayv1.Kind("Gateway")),
181 Group: ptrTo(gatewayv1.Group("gateway.networking.k8s.io")),
182 Name: "example",
183 SectionName: ptrTo(gatewayv1.SectionName("foo")),
184 }, {
185 Kind: ptrTo(gatewayv1.Kind("Gateway")),
186 Group: ptrTo(gatewayv1.Group("gateway.networking.k8s.io")),
187 Name: "example",
188 Port: ptrTo(gatewayv1.PortNumber(443)),
189 SectionName: ptrTo(gatewayv1.SectionName("foo")),
190 }},
191 },
192 {
193 name: "valid because first parentRef has namespace while second doesn't",
194 wantErrors: []string{},
195 parentRefs: []gatewayv1.ParentReference{{
196 Kind: ptrTo(gatewayv1.Kind("Gateway")),
197 Group: ptrTo(gatewayv1.Group("gateway.networking.k8s.io")),
198 Name: "example",
199 Namespace: ptrTo(gatewayv1.Namespace("test")),
200 }, {
201 Kind: ptrTo(gatewayv1.Kind("Gateway")),
202 Group: ptrTo(gatewayv1.Group("gateway.networking.k8s.io")),
203 Name: "example",
204 }},
205 },
206 {
207 name: "valid because second parentRef has namespace while first doesn't",
208 wantErrors: []string{},
209 parentRefs: []gatewayv1.ParentReference{{
210 Kind: ptrTo(gatewayv1.Kind("Gateway")),
211 Group: ptrTo(gatewayv1.Group("gateway.networking.k8s.io")),
212 Name: "example",
213 }, {
214 Kind: ptrTo(gatewayv1.Kind("Gateway")),
215 Group: ptrTo(gatewayv1.Group("gateway.networking.k8s.io")),
216 Name: "example",
217 Namespace: ptrTo(gatewayv1.Namespace("test")),
218 }},
219 },
220 }
221
222 for _, tc := range tests {
223 t.Run(tc.name, func(t *testing.T) {
224 route := &gatewayv1.HTTPRoute{
225 ObjectMeta: metav1.ObjectMeta{
226 Name: fmt.Sprintf("foo-%v", time.Now().UnixNano()),
227 Namespace: metav1.NamespaceDefault,
228 },
229 Spec: gatewayv1.HTTPRouteSpec{
230 CommonRouteSpec: gatewayv1.CommonRouteSpec{
231 ParentRefs: tc.parentRefs,
232 },
233 },
234 }
235 validateHTTPRoute(t, route, tc.wantErrors)
236 })
237 }
238 }
239
240 func toDuration(durationString string) *gatewayv1.Duration {
241 return (*gatewayv1.Duration)(&durationString)
242 }
243
244 func TestHTTPRouteTimeouts(t *testing.T) {
245 tests := []struct {
246 name string
247 wantErrors []string
248 rules []gatewayv1.HTTPRouteRule
249 }{
250 {
251 name: "invalid timeout unit us is not supported",
252 wantErrors: []string{"Invalid value: \"100us\": spec.rules[0].timeouts.request in body should match '^([0-9]{1,5}(h|m|s|ms)){1,4}$'"},
253 rules: []gatewayv1.HTTPRouteRule{
254 {
255 Timeouts: &gatewayv1.HTTPRouteTimeouts{
256 Request: toDuration("100us"),
257 },
258 },
259 },
260 },
261 {
262 name: "invalid timeout unit ns is not supported",
263 wantErrors: []string{"Invalid value: \"500ns\": spec.rules[0].timeouts.request in body should match '^([0-9]{1,5}(h|m|s|ms)){1,4}$'"},
264 rules: []gatewayv1.HTTPRouteRule{
265 {
266 Timeouts: &gatewayv1.HTTPRouteTimeouts{
267 Request: toDuration("500ns"),
268 },
269 },
270 },
271 },
272 {
273 name: "valid timeout request and backendRequest",
274 rules: []gatewayv1.HTTPRouteRule{
275 {
276 Timeouts: &gatewayv1.HTTPRouteTimeouts{
277 Request: toDuration("4s"),
278 BackendRequest: toDuration("2s"),
279 },
280 },
281 },
282 },
283 {
284 name: "valid timeout request",
285 rules: []gatewayv1.HTTPRouteRule{
286 {
287 Timeouts: &gatewayv1.HTTPRouteTimeouts{
288 Request: toDuration("0s"),
289 },
290 },
291 },
292 },
293 {
294 name: "invalid timeout request day unit not supported",
295 wantErrors: []string{"Invalid value: \"1d\": spec.rules[0].timeouts.request in body should match '^([0-9]{1,5}(h|m|s|ms)){1,4}$'"},
296 rules: []gatewayv1.HTTPRouteRule{
297 {
298 Timeouts: &gatewayv1.HTTPRouteTimeouts{
299 Request: toDuration("1d"),
300 },
301 },
302 },
303 },
304 {
305 name: "invalid timeout request decimal not supported ",
306 wantErrors: []string{"Invalid value: \"0.5s\": spec.rules[0].timeouts.request in body should match '^([0-9]{1,5}(h|m|s|ms)){1,4}$'"},
307 rules: []gatewayv1.HTTPRouteRule{
308 {
309 Timeouts: &gatewayv1.HTTPRouteTimeouts{
310 Request: toDuration("0.5s"),
311 },
312 },
313 },
314 },
315 {
316 name: "valid timeout request infinite greater than backendRequest 1ms",
317 rules: []gatewayv1.HTTPRouteRule{
318 {
319 Timeouts: &gatewayv1.HTTPRouteTimeouts{
320 Request: toDuration("0s"),
321 BackendRequest: toDuration("1ms"),
322 },
323 },
324 },
325 },
326 {
327 name: "valid timeout request 1s greater than backendRequest 200ms",
328 rules: []gatewayv1.HTTPRouteRule{
329 {
330 Timeouts: &gatewayv1.HTTPRouteTimeouts{
331 Request: toDuration("1s"),
332 BackendRequest: toDuration("200ms"),
333 },
334 },
335 },
336 },
337 {
338 name: "valid timeout request 10s equal backendRequest 10s",
339 rules: []gatewayv1.HTTPRouteRule{
340 {
341 Timeouts: &gatewayv1.HTTPRouteTimeouts{
342 Request: toDuration("10s"),
343 BackendRequest: toDuration("10s"),
344 },
345 },
346 },
347 },
348 {
349 name: "invalid timeout request 200ms less than backendRequest 1s",
350 wantErrors: []string{"Invalid value: \"object\": backendRequest timeout cannot be longer than request timeout"},
351 rules: []gatewayv1.HTTPRouteRule{
352 {
353 Timeouts: &gatewayv1.HTTPRouteTimeouts{
354 Request: toDuration("200ms"),
355 BackendRequest: toDuration("1s"),
356 },
357 },
358 },
359 },
360 }
361
362 for _, tc := range tests {
363 t.Run(tc.name, func(t *testing.T) {
364 route := &gatewayv1.HTTPRoute{
365 ObjectMeta: metav1.ObjectMeta{
366 Name: fmt.Sprintf("foo-%v", time.Now().UnixNano()),
367 Namespace: metav1.NamespaceDefault,
368 },
369 Spec: gatewayv1.HTTPRouteSpec{Rules: tc.rules},
370 }
371 validateHTTPRoute(t, route, tc.wantErrors)
372 })
373 }
374 }
375
View as plain text