github.com/nginxinc/kubernetes-ingress@v1.12.5/pkg/apis/configuration/validation/transportserver_test.go (about) 1 package validation 2 3 import ( 4 "testing" 5 6 "github.com/nginxinc/kubernetes-ingress/pkg/apis/configuration/v1alpha1" 7 "k8s.io/apimachinery/pkg/util/sets" 8 "k8s.io/apimachinery/pkg/util/validation/field" 9 ) 10 11 func createTransportServerValidator() *TransportServerValidator { 12 return &TransportServerValidator{} 13 } 14 15 func TestValidateTransportServer(t *testing.T) { 16 ts := v1alpha1.TransportServer{ 17 Spec: v1alpha1.TransportServerSpec{ 18 Listener: v1alpha1.TransportServerListener{ 19 Name: "tcp-listener", 20 Protocol: "TCP", 21 }, 22 Upstreams: []v1alpha1.Upstream{ 23 { 24 Name: "upstream1", 25 Service: "test-1", 26 Port: 5501, 27 }, 28 }, 29 Action: &v1alpha1.Action{ 30 Pass: "upstream1", 31 }, 32 }, 33 } 34 35 tsv := createTransportServerValidator() 36 37 err := tsv.ValidateTransportServer(&ts) 38 if err != nil { 39 t.Errorf("ValidateTransportServer() returned error %v for valid input", err) 40 } 41 } 42 43 func TestValidateTransportServerFails(t *testing.T) { 44 ts := v1alpha1.TransportServer{ 45 Spec: v1alpha1.TransportServerSpec{ 46 Listener: v1alpha1.TransportServerListener{ 47 Name: "tcp-listener", 48 Protocol: "TCP", 49 }, 50 Upstreams: []v1alpha1.Upstream{ 51 { 52 Name: "upstream1", 53 Service: "test-1", 54 Port: 5501, 55 }, 56 }, 57 Action: nil, 58 }, 59 } 60 61 tsv := createTransportServerValidator() 62 63 err := tsv.ValidateTransportServer(&ts) 64 if err == nil { 65 t.Errorf("ValidateTransportServer() returned no error for invalid input") 66 } 67 } 68 69 func TestValidateTransportServerUpstreams(t *testing.T) { 70 tests := []struct { 71 upstreams []v1alpha1.Upstream 72 expectedUpstreamNames sets.String 73 msg string 74 }{ 75 { 76 upstreams: []v1alpha1.Upstream{}, 77 expectedUpstreamNames: sets.String{}, 78 msg: "no upstreams", 79 }, 80 { 81 upstreams: []v1alpha1.Upstream{ 82 { 83 Name: "upstream1", 84 Service: "test-1", 85 Port: 80, 86 }, 87 { 88 Name: "upstream2", 89 Service: "test-2", 90 Port: 80, 91 }, 92 }, 93 expectedUpstreamNames: map[string]sets.Empty{ 94 "upstream1": {}, 95 "upstream2": {}, 96 }, 97 msg: "2 valid upstreams", 98 }, 99 } 100 101 for _, test := range tests { 102 allErrs, resultUpstreamNames := validateTransportServerUpstreams(test.upstreams, field.NewPath("upstreams"), true) 103 if len(allErrs) > 0 { 104 t.Errorf("validateTransportServerUpstreams() returned errors %v for valid input for the case of %s", allErrs, test.msg) 105 } 106 if !resultUpstreamNames.Equal(test.expectedUpstreamNames) { 107 t.Errorf("validateTransportServerUpstreams() returned %v expected %v for the case of %s", resultUpstreamNames, test.expectedUpstreamNames, test.msg) 108 } 109 } 110 } 111 112 func TestValidateTransportServerUpstreamsFails(t *testing.T) { 113 tests := []struct { 114 upstreams []v1alpha1.Upstream 115 expectedUpstreamNames sets.String 116 msg string 117 }{ 118 { 119 upstreams: []v1alpha1.Upstream{ 120 { 121 Name: "@upstream1", 122 Service: "test-1", 123 Port: 80, 124 }, 125 }, 126 expectedUpstreamNames: sets.String{}, 127 msg: "invalid upstream name", 128 }, 129 { 130 upstreams: []v1alpha1.Upstream{ 131 { 132 Name: "upstream1", 133 Service: "@test-1", 134 Port: 80, 135 }, 136 }, 137 expectedUpstreamNames: map[string]sets.Empty{ 138 "upstream1": {}, 139 }, 140 msg: "invalid service", 141 }, 142 { 143 upstreams: []v1alpha1.Upstream{ 144 { 145 Name: "upstream1", 146 Service: "test-1", 147 Port: -80, 148 }, 149 }, 150 expectedUpstreamNames: map[string]sets.Empty{ 151 "upstream1": {}, 152 }, 153 msg: "invalid port", 154 }, 155 { 156 upstreams: []v1alpha1.Upstream{ 157 { 158 Name: "upstream1", 159 Service: "test-1", 160 Port: 80, 161 }, 162 { 163 Name: "upstream1", 164 Service: "test-2", 165 Port: 80, 166 }, 167 }, 168 expectedUpstreamNames: map[string]sets.Empty{ 169 "upstream1": {}, 170 }, 171 msg: "duplicated upstreams", 172 }, 173 } 174 175 for _, test := range tests { 176 allErrs, resultUpstreamNames := validateTransportServerUpstreams(test.upstreams, field.NewPath("upstreams"), true) 177 if len(allErrs) == 0 { 178 t.Errorf("validateTransportServerUpstreams() returned no errors for the case of %s", test.msg) 179 } 180 if !resultUpstreamNames.Equal(test.expectedUpstreamNames) { 181 t.Errorf("validateTransportServerUpstreams() returned %v expected %v for the case of %s", resultUpstreamNames, test.expectedUpstreamNames, test.msg) 182 } 183 } 184 } 185 186 func TestValidateTransportServerHost(t *testing.T) { 187 tests := []struct { 188 host string 189 isTLSPassthroughListener bool 190 }{ 191 { 192 host: "", 193 isTLSPassthroughListener: false, 194 }, 195 { 196 host: "nginx.org", 197 isTLSPassthroughListener: true, 198 }, 199 } 200 201 for _, test := range tests { 202 allErrs := validateTransportServerHost(test.host, field.NewPath("host"), test.isTLSPassthroughListener) 203 if len(allErrs) > 0 { 204 t.Errorf("validateTransportServerHost(%q, %v) returned errors %v for valid input", test.host, test.isTLSPassthroughListener, allErrs) 205 } 206 } 207 } 208 209 func TestValidateTransportServerLoadBalancingMethod(t *testing.T) { 210 tests := []struct { 211 method string 212 isPlus bool 213 hasError bool 214 }{ 215 { 216 method: "", 217 isPlus: false, 218 hasError: false, 219 }, 220 { 221 method: "", 222 isPlus: true, 223 hasError: false, 224 }, 225 { 226 method: "hash", 227 isPlus: false, 228 hasError: true, 229 }, 230 { 231 method: "hash ${remote_addr}", 232 isPlus: false, 233 hasError: false, 234 }, 235 { 236 method: "hash ${remote_addr}AAA", 237 isPlus: false, 238 hasError: false, 239 }, 240 { 241 method: `hash ${remote_addr}"`, 242 isPlus: false, 243 hasError: true, 244 }, 245 { 246 method: "hash ${invalid_var}", 247 isPlus: false, 248 hasError: true, 249 }, 250 { 251 method: "hash not_var", 252 isPlus: false, 253 hasError: false, 254 }, 255 { 256 method: "hash ${remote_addr} toomany", 257 isPlus: false, 258 hasError: true, 259 }, 260 { 261 method: "hash ${remote_addr} consistent", 262 isPlus: false, 263 hasError: false, 264 }, 265 { 266 method: "hash ${remote_addr} toomany consistent", 267 isPlus: false, 268 hasError: true, 269 }, 270 { 271 method: "invalid", 272 isPlus: false, 273 hasError: true, 274 }, 275 { 276 method: "least_conn", 277 isPlus: false, 278 hasError: false, 279 }, 280 { 281 method: "random", 282 isPlus: false, 283 hasError: false, 284 }, 285 { 286 method: "random two", 287 isPlus: false, 288 hasError: false, 289 }, 290 { 291 method: "random two least_conn", 292 isPlus: false, 293 hasError: false, 294 }, 295 { 296 method: "random two least_time", 297 isPlus: false, 298 hasError: true, 299 }, 300 { 301 method: "random two least_time", 302 isPlus: true, 303 hasError: true, 304 }, { 305 method: "random two least_time=connect", 306 isPlus: true, 307 hasError: true, 308 }, 309 } 310 311 for _, test := range tests { 312 allErrs := validateLoadBalancingMethod(test.method, field.NewPath("method"), test.isPlus) 313 if !test.hasError && len(allErrs) > 0 { 314 t.Errorf("validateLoadBalancingMethod(%q, %v) returned errors %v for valid input", test.method, test.isPlus, allErrs) 315 } 316 if test.hasError && len(allErrs) < 1 { 317 t.Errorf("validateLoadBalancingMethod(%q, %v) failed to return an error for invalid input", test.method, test.isPlus) 318 } 319 } 320 } 321 322 func TestValidateTransportServerSnippet(t *testing.T) { 323 tests := []struct { 324 snippet string 325 isSnippetsEnabled bool 326 expectError bool 327 }{ 328 { 329 snippet: "", 330 isSnippetsEnabled: false, 331 expectError: false, 332 }, 333 { 334 snippet: "deny 192.168.1.1;", 335 isSnippetsEnabled: false, 336 expectError: true, 337 }, 338 { 339 snippet: "deny 192.168.1.1;", 340 isSnippetsEnabled: true, 341 expectError: false, 342 }, 343 } 344 345 for _, test := range tests { 346 allErrs := validateSnippets(test.snippet, field.NewPath("serverSnippet"), test.isSnippetsEnabled) 347 if test.expectError { 348 if len(allErrs) < 1 { 349 t.Errorf("validateSnippets(%q, %v) failed to return an error for invalid input", test.snippet, test.isSnippetsEnabled) 350 } 351 } else { 352 if len(allErrs) > 0 { 353 t.Errorf("validateSnippets(%q, %v) returned errors %v for valid input", test.snippet, test.isSnippetsEnabled, allErrs) 354 } 355 } 356 } 357 } 358 359 func TestValidateTransportServerHostFails(t *testing.T) { 360 tests := []struct { 361 host string 362 isTLSPassthroughListener bool 363 }{ 364 { 365 host: "nginx.org", 366 isTLSPassthroughListener: false, 367 }, 368 { 369 host: "", 370 isTLSPassthroughListener: true, 371 }, 372 } 373 374 for _, test := range tests { 375 allErrs := validateTransportServerHost(test.host, field.NewPath("host"), test.isTLSPassthroughListener) 376 if len(allErrs) == 0 { 377 t.Errorf("validateTransportServerHost(%q, %v) returned no errors for invalid input", test.host, test.isTLSPassthroughListener) 378 } 379 } 380 } 381 382 func TestValidateTransportListener(t *testing.T) { 383 tests := []struct { 384 listener *v1alpha1.TransportServerListener 385 tlsPassthrough bool 386 }{ 387 { 388 listener: &v1alpha1.TransportServerListener{ 389 Name: "tcp-listener", 390 Protocol: "TCP", 391 }, 392 tlsPassthrough: false, 393 }, 394 { 395 listener: &v1alpha1.TransportServerListener{ 396 Name: "tcp-listener", 397 Protocol: "TCP", 398 }, 399 tlsPassthrough: true, 400 }, 401 { 402 listener: &v1alpha1.TransportServerListener{ 403 Name: "tls-passthrough", 404 Protocol: "TLS_PASSTHROUGH", 405 }, 406 tlsPassthrough: true, 407 }, 408 } 409 410 for _, test := range tests { 411 tsv := &TransportServerValidator{ 412 tlsPassthrough: test.tlsPassthrough, 413 } 414 415 allErrs := tsv.validateTransportListener(test.listener, field.NewPath("listener")) 416 if len(allErrs) > 0 { 417 t.Errorf("validateTransportListener() returned errors %v for valid input %+v when tlsPassithrough is %v", allErrs, test.listener, test.tlsPassthrough) 418 } 419 } 420 } 421 422 func TestValidateTransportListenerFails(t *testing.T) { 423 tests := []struct { 424 listener *v1alpha1.TransportServerListener 425 tlsPassthrough bool 426 }{ 427 { 428 listener: &v1alpha1.TransportServerListener{ 429 Name: "tls-passthrough", 430 Protocol: "TLS_PASSTHROUGH", 431 }, 432 tlsPassthrough: false, 433 }, 434 { 435 listener: &v1alpha1.TransportServerListener{ 436 Name: "tls-passthrough", 437 Protocol: "abc", 438 }, 439 tlsPassthrough: true, 440 }, 441 { 442 listener: &v1alpha1.TransportServerListener{ 443 Name: "tls-passthrough", 444 Protocol: "abc", 445 }, 446 tlsPassthrough: false, 447 }, 448 { 449 listener: &v1alpha1.TransportServerListener{ 450 Name: "abc", 451 Protocol: "TLS_PASSTHROUGH", 452 }, 453 tlsPassthrough: true, 454 }, 455 { 456 listener: &v1alpha1.TransportServerListener{ 457 Name: "abc", 458 Protocol: "TLS_PASSTHROUGH", 459 }, 460 tlsPassthrough: false, 461 }, 462 } 463 464 for _, test := range tests { 465 tsv := &TransportServerValidator{ 466 tlsPassthrough: test.tlsPassthrough, 467 } 468 469 allErrs := tsv.validateTransportListener(test.listener, field.NewPath("listener")) 470 if len(allErrs) == 0 { 471 t.Errorf("validateTransportListener() returned no errors for invalid input %+v when tlsPassthrough is %v", test.listener, test.tlsPassthrough) 472 } 473 } 474 } 475 476 func TestValidateIsPotentialTLSPassthroughListener(t *testing.T) { 477 tests := []struct { 478 listener *v1alpha1.TransportServerListener 479 expected bool 480 }{ 481 { 482 listener: &v1alpha1.TransportServerListener{ 483 Name: "tls-passthrough", 484 Protocol: "abc", 485 }, 486 expected: true, 487 }, 488 { 489 listener: &v1alpha1.TransportServerListener{ 490 Name: "abc", 491 Protocol: "TLS_PASSTHROUGH", 492 }, 493 expected: true, 494 }, 495 { 496 listener: &v1alpha1.TransportServerListener{ 497 Name: "tcp", 498 Protocol: "TCP", 499 }, 500 expected: false, 501 }, 502 } 503 504 for _, test := range tests { 505 result := isPotentialTLSPassthroughListener(test.listener) 506 if result != test.expected { 507 t.Errorf("isPotentialTLSPassthroughListener(%+v) returned %v but expected %v", test.listener, result, test.expected) 508 } 509 } 510 } 511 512 func TestValidateListenerProtocol(t *testing.T) { 513 validProtocols := []string{ 514 "TCP", 515 "UDP", 516 } 517 518 for _, p := range validProtocols { 519 allErrs := validateListenerProtocol(p, field.NewPath("protocol")) 520 if len(allErrs) > 0 { 521 t.Errorf("validateListenerProtocol(%q) returned errors %v for valid input", p, allErrs) 522 } 523 } 524 525 invalidProtocols := []string{ 526 "", 527 "HTTP", 528 "udp", 529 "UDP ", 530 } 531 532 for _, p := range invalidProtocols { 533 allErrs := validateListenerProtocol(p, field.NewPath("protocol")) 534 if len(allErrs) == 0 { 535 t.Errorf("validateListenerProtocol(%q) returned no errors for invalid input", p) 536 } 537 } 538 } 539 540 func TestValidateTSUpstreamHealthChecks(t *testing.T) { 541 tests := []struct { 542 healthCheck *v1alpha1.HealthCheck 543 msg string 544 }{ 545 { 546 healthCheck: nil, 547 msg: "nil health check", 548 }, 549 { 550 healthCheck: &v1alpha1.HealthCheck{}, 551 msg: "non nil health check", 552 }, 553 { 554 healthCheck: &v1alpha1.HealthCheck{ 555 Enabled: true, 556 Timeout: "30s", 557 Jitter: "5s", 558 Port: 88, 559 Interval: "10", 560 Passes: 3, 561 Fails: 4, 562 }, 563 msg: "valid Health check", 564 }, 565 } 566 for _, test := range tests { 567 allErrs := validateTSUpstreamHealthChecks(test.healthCheck, field.NewPath("healthCheck")) 568 if len(allErrs) > 0 { 569 t.Errorf("validateTSUpstreamHealthChecks() returned errors %v for valid input for the case of %s", allErrs, test.msg) 570 } 571 } 572 } 573 574 func TestValidateTSUpstreamHealthChecksFails(t *testing.T) { 575 tests := []struct { 576 healthCheck *v1alpha1.HealthCheck 577 msg string 578 }{ 579 { 580 healthCheck: &v1alpha1.HealthCheck{ 581 Enabled: true, 582 Timeout: "-30s", 583 Jitter: "5s", 584 Port: 88, 585 Interval: "10", 586 Passes: 3, 587 Fails: 4, 588 }, 589 msg: "invalid timeout", 590 }, 591 { 592 healthCheck: &v1alpha1.HealthCheck{ 593 Enabled: true, 594 Timeout: "30s", 595 Jitter: "5s", 596 Port: 4000000000000000, 597 Interval: "10", 598 Passes: 3, 599 Fails: 4, 600 }, 601 msg: "invalid port number", 602 }, 603 { 604 healthCheck: &v1alpha1.HealthCheck{ 605 Enabled: true, 606 Timeout: "30s", 607 Jitter: "5s", 608 Port: 40, 609 Interval: "10", 610 Passes: -3, 611 Fails: 4, 612 }, 613 msg: "invalid passes value", 614 }, 615 { 616 healthCheck: &v1alpha1.HealthCheck{ 617 Enabled: true, 618 Timeout: "30s", 619 Jitter: "5s", 620 Port: 40, 621 Interval: "10", 622 Passes: 3, 623 Fails: -4, 624 }, 625 msg: "invalid fails value", 626 }, 627 { 628 healthCheck: &v1alpha1.HealthCheck{ 629 Enabled: true, 630 Timeout: "30s", 631 Jitter: "5s", 632 Port: 40, 633 Interval: "ten", 634 Passes: 3, 635 Fails: 4, 636 }, 637 msg: "invalid interval value", 638 }, 639 { 640 healthCheck: &v1alpha1.HealthCheck{ 641 Enabled: true, 642 Timeout: "30s", 643 Jitter: "5sec", 644 Port: 40, 645 Interval: "10", 646 Passes: 3, 647 Fails: 4, 648 }, 649 msg: "invalid jitter value", 650 }, 651 } 652 653 for _, test := range tests { 654 allErrs := validateTSUpstreamHealthChecks(test.healthCheck, field.NewPath("healthCheck")) 655 if len(allErrs) == 0 { 656 t.Errorf("validateTSUpstreamHealthChecks() returned no error for invalid input %v", test.msg) 657 } 658 } 659 } 660 661 func TestValidateUpstreamParameters(t *testing.T) { 662 tests := []struct { 663 parameters *v1alpha1.UpstreamParameters 664 msg string 665 }{ 666 { 667 parameters: nil, 668 msg: "nil parameters", 669 }, 670 { 671 parameters: &v1alpha1.UpstreamParameters{}, 672 msg: "Non-nil parameters", 673 }, 674 } 675 676 for _, test := range tests { 677 allErrs := validateTransportServerUpstreamParameters(test.parameters, field.NewPath("upstreamParameters"), "UDP") 678 if len(allErrs) > 0 { 679 t.Errorf("validateTransportServerUpstreamParameters() returned errors %v for valid input for the case of %s", allErrs, test.msg) 680 } 681 } 682 } 683 684 func TestValidateSessionParameters(t *testing.T) { 685 tests := []struct { 686 parameters *v1alpha1.SessionParameters 687 msg string 688 }{ 689 { 690 parameters: nil, 691 msg: "nil parameters", 692 }, 693 { 694 parameters: &v1alpha1.SessionParameters{}, 695 msg: "Non-nil parameters", 696 }, 697 { 698 parameters: &v1alpha1.SessionParameters{ 699 Timeout: "60s", 700 }, 701 msg: "valid parameters", 702 }, 703 } 704 705 for _, test := range tests { 706 allErrs := validateSessionParameters(test.parameters, field.NewPath("sessionParameters")) 707 if len(allErrs) > 0 { 708 t.Errorf("validateSessionParameters() returned errors %v for valid input for the case of %s", allErrs, test.msg) 709 } 710 } 711 } 712 713 func TestValidateSessionParametersFails(t *testing.T) { 714 tests := []struct { 715 parameters *v1alpha1.SessionParameters 716 msg string 717 }{ 718 { 719 parameters: &v1alpha1.SessionParameters{ 720 Timeout: "-1s", 721 }, 722 msg: "invalid timeout", 723 }, 724 } 725 726 for _, test := range tests { 727 allErrs := validateSessionParameters(test.parameters, field.NewPath("sessionParameters")) 728 if len(allErrs) == 0 { 729 t.Errorf("validateSessionParameters() returned no errors for invalid input: %v", test.msg) 730 } 731 } 732 } 733 734 func TestValidateUDPUpstreamParameter(t *testing.T) { 735 validInput := []struct { 736 parameter *int 737 protocol string 738 }{ 739 { 740 parameter: nil, 741 protocol: "TCP", 742 }, 743 { 744 parameter: nil, 745 protocol: "UDP", 746 }, 747 { 748 parameter: createPointerFromInt(0), 749 protocol: "UDP", 750 }, 751 { 752 parameter: createPointerFromInt(1), 753 protocol: "UDP", 754 }, 755 } 756 757 for _, input := range validInput { 758 allErrs := validateUDPUpstreamParameter(input.parameter, field.NewPath("parameter"), input.protocol) 759 if len(allErrs) > 0 { 760 t.Errorf("validateUDPUpstreamParameter(%v, %q) returned errors %v for valid input", input.parameter, input.protocol, allErrs) 761 } 762 } 763 } 764 765 func TestValidateUDPUpstreamParameterFails(t *testing.T) { 766 invalidInput := []struct { 767 parameter *int 768 protocol string 769 }{ 770 { 771 parameter: createPointerFromInt(0), 772 protocol: "TCP", 773 }, 774 { 775 parameter: createPointerFromInt(-1), 776 protocol: "UDP", 777 }, 778 } 779 780 for _, input := range invalidInput { 781 allErrs := validateUDPUpstreamParameter(input.parameter, field.NewPath("parameter"), input.protocol) 782 if len(allErrs) == 0 { 783 t.Errorf("validateUDPUpstreamParameter(%v, %q) returned no errors for invalid input", input.parameter, input.protocol) 784 } 785 } 786 } 787 788 func TestValidateTransportServerAction(t *testing.T) { 789 upstreamNames := map[string]sets.Empty{ 790 "test": {}, 791 } 792 793 action := &v1alpha1.Action{ 794 Pass: "test", 795 } 796 797 allErrs := validateTransportServerAction(action, field.NewPath("action"), upstreamNames) 798 if len(allErrs) > 0 { 799 t.Errorf("validateTransportServerAction() returned errors %v for valid input", allErrs) 800 } 801 } 802 803 func TestValidateTransportServerActionFails(t *testing.T) { 804 upstreamNames := map[string]sets.Empty{} 805 806 tests := []struct { 807 action *v1alpha1.Action 808 msg string 809 }{ 810 { 811 action: &v1alpha1.Action{ 812 Pass: "", 813 }, 814 msg: "missing pass field", 815 }, 816 { 817 action: &v1alpha1.Action{ 818 Pass: "non-existing", 819 }, 820 msg: "pass references a non-existing upstream", 821 }, 822 } 823 824 for _, test := range tests { 825 allErrs := validateTransportServerAction(test.action, field.NewPath("action"), upstreamNames) 826 if len(allErrs) == 0 { 827 t.Errorf("validateTransportServerAction() returned no errors for invalid input for the case of %s", test.msg) 828 } 829 } 830 } 831 832 func TestValidateMatchSend(t *testing.T) { 833 validInput := []string{ 834 "", 835 "abc", 836 "hello${world}", 837 `hello\x00`, 838 } 839 invalidInput := []string{ 840 `hello"world`, 841 `\x1x`, 842 } 843 844 for _, send := range validInput { 845 allErrs := validateMatchSend(send, field.NewPath("send")) 846 if len(allErrs) > 0 { 847 t.Errorf("validateMatchSend(%q) returned errors %v for valid input", send, allErrs) 848 } 849 } 850 for _, send := range invalidInput { 851 allErrs := validateMatchSend(send, field.NewPath("send")) 852 if len(allErrs) == 0 { 853 t.Errorf("validateMatchSend(%q) returned no errors for invalid input", send) 854 } 855 } 856 } 857 858 func TestValidateHexString(t *testing.T) { 859 validInput := []string{ 860 "", 861 "abc", 862 `\x00`, 863 `\xaa`, 864 `\xaA`, 865 `\xff`, 866 `\xaaFFabc\x12`, 867 } 868 invalidInput := []string{ 869 `\x`, 870 `\x1`, 871 `\xax`, 872 `\x\b`, 873 `\xaaFFabc\xx12`, // \xx1 is invalid 874 } 875 876 for _, s := range validInput { 877 err := validateHexString(s) 878 if err != nil { 879 t.Errorf("validateHexString(%q) returned error %v for valid input", s, err) 880 } 881 } 882 for _, s := range invalidInput { 883 err := validateHexString(s) 884 if err == nil { 885 t.Errorf("validateHexString(%q) returned no error for invalid input", s) 886 } 887 } 888 } 889 890 func TestValidateMatchExpect(t *testing.T) { 891 validInput := []string{ 892 ``, 893 `abc`, 894 `abc\x00`, 895 `~* 200 OK`, 896 `~ 2\d\d`, 897 `~`, 898 `~*`, 899 } 900 invalidInput := []string{ 901 `hello"world`, 902 `~hello"world`, 903 `~*hello"world`, 904 `\x1x`, 905 `~\x1x`, 906 `~*\x1x`, 907 `~[{`, 908 `~{1}`, 909 } 910 911 for _, input := range validInput { 912 allErrs := validateMatchExpect(input, field.NewPath("expect")) 913 if len(allErrs) > 0 { 914 t.Errorf("validateMatchExpect(%q) returned errors %v for valid input", input, allErrs) 915 } 916 } 917 for _, input := range invalidInput { 918 allErrs := validateMatchExpect(input, field.NewPath("expect")) 919 if len(allErrs) == 0 { 920 t.Errorf("validateMatchExpect(%q) returned no errors for invalid input", input) 921 } 922 } 923 }