github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/internal/xds/matcher/matcher_header_test.go (about) 1 /* 2 * 3 * Copyright 2020 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package matcher 20 21 import ( 22 "regexp" 23 "testing" 24 25 "github.com/hxx258456/ccgo/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 // Doesn't match comma-concatenated string. 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 }