1
18
19 package matcher
20
21 import (
22 "regexp"
23 "testing"
24
25 "google.golang.org/grpc/metadata"
26 )
27
28 func TestHeaderExactMatcherMatch(t *testing.T) {
29 tests := []struct {
30 name string
31 key, exact string
32 md metadata.MD
33 want bool
34 invert bool
35 }{
36 {
37 name: "one value one match",
38 key: "th",
39 exact: "tv",
40 md: metadata.Pairs("th", "tv"),
41 want: true,
42 },
43 {
44 name: "two value one match",
45 key: "th",
46 exact: "tv",
47 md: metadata.Pairs("th", "abc", "th", "tv"),
48
49 want: false,
50 },
51 {
52 name: "two value match concatenated",
53 key: "th",
54 exact: "abc,tv",
55 md: metadata.Pairs("th", "abc", "th", "tv"),
56 want: true,
57 },
58 {
59 name: "not match",
60 key: "th",
61 exact: "tv",
62 md: metadata.Pairs("th", "abc"),
63 want: false,
64 },
65 {
66 name: "invert header not present",
67 key: "th",
68 exact: "tv",
69 md: metadata.Pairs(":method", "GET"),
70 want: false,
71 invert: true,
72 },
73 {
74 name: "invert header match",
75 key: "th",
76 exact: "tv",
77 md: metadata.Pairs("th", "tv"),
78 want: false,
79 invert: true,
80 },
81 {
82 name: "invert header not match",
83 key: "th",
84 exact: "tv",
85 md: metadata.Pairs("th", "tvv"),
86 want: true,
87 invert: true,
88 },
89 }
90 for _, tt := range tests {
91 t.Run(tt.name, func(t *testing.T) {
92 hem := NewHeaderExactMatcher(tt.key, tt.exact, tt.invert)
93 if got := hem.Match(tt.md); got != tt.want {
94 t.Errorf("match() = %v, want %v", got, tt.want)
95 }
96 })
97 }
98 }
99
100 func TestHeaderRegexMatcherMatch(t *testing.T) {
101 tests := []struct {
102 name string
103 key, regexStr string
104 md metadata.MD
105 want bool
106 invert bool
107 }{
108 {
109 name: "one value one match",
110 key: "th",
111 regexStr: "^t+v*$",
112 md: metadata.Pairs("th", "tttvv"),
113 want: true,
114 },
115 {
116 name: "two value one match",
117 key: "th",
118 regexStr: "^t+v*$",
119 md: metadata.Pairs("th", "abc", "th", "tttvv"),
120 want: false,
121 },
122 {
123 name: "two value match concatenated",
124 key: "th",
125 regexStr: "^[abc]*,t+v*$",
126 md: metadata.Pairs("th", "abc", "th", "tttvv"),
127 want: true,
128 },
129 {
130 name: "no match",
131 key: "th",
132 regexStr: "^t+v*$",
133 md: metadata.Pairs("th", "abc"),
134 want: false,
135 },
136 {
137 name: "no match because only part of value matches with regex",
138 key: "header",
139 regexStr: "^a+$",
140 md: metadata.Pairs("header", "ab"),
141 want: false,
142 },
143 {
144 name: "match because full value matches with regex",
145 key: "header",
146 regexStr: "^a+$",
147 md: metadata.Pairs("header", "aa"),
148 want: true,
149 },
150 {
151 name: "invert header not present",
152 key: "th",
153 regexStr: "^t+v*$",
154 md: metadata.Pairs(":method", "GET"),
155 want: false,
156 invert: true,
157 },
158 {
159 name: "invert header match",
160 key: "th",
161 regexStr: "^t+v*$",
162 md: metadata.Pairs("th", "tttvv"),
163 want: false,
164 invert: true,
165 },
166 {
167 name: "invert header not match",
168 key: "th",
169 regexStr: "^t+v*$",
170 md: metadata.Pairs("th", "abc"),
171 want: true,
172 invert: true,
173 },
174 }
175 for _, tt := range tests {
176 t.Run(tt.name, func(t *testing.T) {
177 hrm := NewHeaderRegexMatcher(tt.key, regexp.MustCompile(tt.regexStr), tt.invert)
178 if got := hrm.Match(tt.md); got != tt.want {
179 t.Errorf("match() = %v, want %v", got, tt.want)
180 }
181 })
182 }
183 }
184
185 func TestHeaderRangeMatcherMatch(t *testing.T) {
186 tests := []struct {
187 name string
188 key string
189 start, end int64
190 md metadata.MD
191 want bool
192 invert bool
193 }{
194 {
195 name: "match",
196 key: "th",
197 start: 1, end: 10,
198 md: metadata.Pairs("th", "5"),
199 want: true,
200 },
201 {
202 name: "equal to start",
203 key: "th",
204 start: 1, end: 10,
205 md: metadata.Pairs("th", "1"),
206 want: true,
207 },
208 {
209 name: "equal to end",
210 key: "th",
211 start: 1, end: 10,
212 md: metadata.Pairs("th", "10"),
213 want: false,
214 },
215 {
216 name: "negative",
217 key: "th",
218 start: -10, end: 10,
219 md: metadata.Pairs("th", "-5"),
220 want: true,
221 },
222 {
223 name: "invert header not present",
224 key: "th",
225 start: 1, end: 10,
226 md: metadata.Pairs(":method", "GET"),
227 want: false,
228 invert: true,
229 },
230 {
231 name: "invert header match",
232 key: "th",
233 start: 1, end: 10,
234 md: metadata.Pairs("th", "5"),
235 want: false,
236 invert: true,
237 },
238 {
239 name: "invert header not match",
240 key: "th",
241 start: 1, end: 9,
242 md: metadata.Pairs("th", "10"),
243 want: true,
244 invert: true,
245 },
246 }
247 for _, tt := range tests {
248 t.Run(tt.name, func(t *testing.T) {
249 hrm := NewHeaderRangeMatcher(tt.key, tt.start, tt.end, tt.invert)
250 if got := hrm.Match(tt.md); got != tt.want {
251 t.Errorf("match() = %v, want %v", got, tt.want)
252 }
253 })
254 }
255 }
256
257 func TestHeaderPresentMatcherMatch(t *testing.T) {
258 tests := []struct {
259 name string
260 key string
261 present bool
262 md metadata.MD
263 want bool
264 invert bool
265 }{
266 {
267 name: "want present is present",
268 key: "th",
269 present: true,
270 md: metadata.Pairs("th", "tv"),
271 want: true,
272 },
273 {
274 name: "want present not present",
275 key: "th",
276 present: true,
277 md: metadata.Pairs("abc", "tv"),
278 want: false,
279 },
280 {
281 name: "want not present is present",
282 key: "th",
283 present: false,
284 md: metadata.Pairs("th", "tv"),
285 want: false,
286 },
287 {
288 name: "want not present is not present",
289 key: "th",
290 present: false,
291 md: metadata.Pairs("abc", "tv"),
292 want: true,
293 },
294 {
295 name: "invert header not present",
296 key: "th",
297 present: true,
298 md: metadata.Pairs(":method", "GET"),
299 want: true,
300 invert: true,
301 },
302 {
303 name: "invert header match",
304 key: "th",
305 present: true,
306 md: metadata.Pairs("th", "tv"),
307 want: false,
308 invert: true,
309 },
310 {
311 name: "invert header not match",
312 key: "th",
313 present: true,
314 md: metadata.Pairs(":method", "GET"),
315 want: true,
316 invert: true,
317 },
318 }
319 for _, tt := range tests {
320 t.Run(tt.name, func(t *testing.T) {
321 hpm := NewHeaderPresentMatcher(tt.key, tt.present, tt.invert)
322 if got := hpm.Match(tt.md); got != tt.want {
323 t.Errorf("match() = %v, want %v", got, tt.want)
324 }
325 })
326 }
327 }
328
329 func TestHeaderPrefixMatcherMatch(t *testing.T) {
330 tests := []struct {
331 name string
332 key, prefix string
333 md metadata.MD
334 want bool
335 invert bool
336 }{
337 {
338 name: "one value one match",
339 key: "th",
340 prefix: "tv",
341 md: metadata.Pairs("th", "tv123"),
342 want: true,
343 },
344 {
345 name: "two value one match",
346 key: "th",
347 prefix: "tv",
348 md: metadata.Pairs("th", "abc", "th", "tv123"),
349 want: false,
350 },
351 {
352 name: "two value match concatenated",
353 key: "th",
354 prefix: "tv",
355 md: metadata.Pairs("th", "tv123", "th", "abc"),
356 want: true,
357 },
358 {
359 name: "not match",
360 key: "th",
361 prefix: "tv",
362 md: metadata.Pairs("th", "abc"),
363 want: false,
364 },
365 {
366 name: "invert header not present",
367 key: "th",
368 prefix: "tv",
369 md: metadata.Pairs(":method", "GET"),
370 want: false,
371 invert: true,
372 },
373 {
374 name: "invert header match",
375 key: "th",
376 prefix: "tv",
377 md: metadata.Pairs("th", "tv123"),
378 want: false,
379 invert: true,
380 },
381 {
382 name: "invert header not match",
383 key: "th",
384 prefix: "tv",
385 md: metadata.Pairs("th", "abc"),
386 want: true,
387 invert: true,
388 },
389 }
390 for _, tt := range tests {
391 t.Run(tt.name, func(t *testing.T) {
392 hpm := NewHeaderPrefixMatcher(tt.key, tt.prefix, tt.invert)
393 if got := hpm.Match(tt.md); got != tt.want {
394 t.Errorf("match() = %v, want %v", got, tt.want)
395 }
396 })
397 }
398 }
399
400 func TestHeaderSuffixMatcherMatch(t *testing.T) {
401 tests := []struct {
402 name string
403 key, suffix string
404 md metadata.MD
405 want bool
406 invert bool
407 }{
408 {
409 name: "one value one match",
410 key: "th",
411 suffix: "tv",
412 md: metadata.Pairs("th", "123tv"),
413 want: true,
414 },
415 {
416 name: "two value one match",
417 key: "th",
418 suffix: "tv",
419 md: metadata.Pairs("th", "123tv", "th", "abc"),
420 want: false,
421 },
422 {
423 name: "two value match concatenated",
424 key: "th",
425 suffix: "tv",
426 md: metadata.Pairs("th", "abc", "th", "123tv"),
427 want: true,
428 },
429 {
430 name: "not match",
431 key: "th",
432 suffix: "tv",
433 md: metadata.Pairs("th", "abc"),
434 want: false,
435 },
436 {
437 name: "invert header not present",
438 key: "th",
439 suffix: "tv",
440 md: metadata.Pairs(":method", "GET"),
441 want: false,
442 invert: true,
443 },
444 {
445 name: "invert header match",
446 key: "th",
447 suffix: "tv",
448 md: metadata.Pairs("th", "123tv"),
449 want: false,
450 invert: true,
451 },
452 {
453 name: "invert header not match",
454 key: "th",
455 suffix: "tv",
456 md: metadata.Pairs("th", "abc"),
457 want: true,
458 invert: true,
459 },
460 }
461 for _, tt := range tests {
462 t.Run(tt.name, func(t *testing.T) {
463 hsm := NewHeaderSuffixMatcher(tt.key, tt.suffix, tt.invert)
464 if got := hsm.Match(tt.md); got != tt.want {
465 t.Errorf("match() = %v, want %v", got, tt.want)
466 }
467 })
468 }
469 }
470
471 func TestHeaderStringMatch(t *testing.T) {
472 tests := []struct {
473 name string
474 key string
475 sm StringMatcher
476 invert bool
477 md metadata.MD
478 want bool
479 }{
480 {
481 name: "should-match",
482 key: "th",
483 sm: StringMatcher{
484 exactMatch: newStringP("tv"),
485 },
486 invert: false,
487 md: metadata.Pairs("th", "tv"),
488 want: true,
489 },
490 {
491 name: "not match",
492 key: "th",
493 sm: StringMatcher{
494 containsMatch: newStringP("tv"),
495 },
496 invert: false,
497 md: metadata.Pairs("th", "not-match"),
498 want: false,
499 },
500 {
501 name: "invert string match",
502 key: "th",
503 sm: StringMatcher{
504 containsMatch: newStringP("tv"),
505 },
506 invert: true,
507 md: metadata.Pairs("th", "not-match"),
508 want: true,
509 },
510 {
511 name: "header missing",
512 key: "th",
513 sm: StringMatcher{
514 containsMatch: newStringP("tv"),
515 },
516 invert: false,
517 md: metadata.Pairs("not-specified-key", "not-match"),
518 want: false,
519 },
520 {
521 name: "header missing invert true",
522 key: "th",
523 sm: StringMatcher{
524 containsMatch: newStringP("tv"),
525 },
526 invert: true,
527 md: metadata.Pairs("not-specified-key", "not-match"),
528 want: false,
529 },
530 {
531 name: "header empty string invert",
532 key: "th",
533 sm: StringMatcher{
534 containsMatch: newStringP("tv"),
535 },
536 invert: true,
537 md: metadata.Pairs("th", ""),
538 want: true,
539 },
540 }
541 for _, test := range tests {
542 t.Run(test.name, func(t *testing.T) {
543 hsm := NewHeaderStringMatcher(test.key, test.sm, test.invert)
544 if got := hsm.Match(test.md); got != test.want {
545 t.Errorf("match() = %v, want %v", got, test.want)
546 }
547 })
548 }
549 }
550
View as plain text