github.com/cilium/cilium@v1.16.2/pkg/fqdn/matchpattern/matchpattern_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package matchpattern 5 6 import ( 7 "regexp" 8 "testing" 9 10 "github.com/stretchr/testify/require" 11 ) 12 13 // TestMatchPatternREConversion tests that we can validate and convert a 14 // matchPattern to a compilable regexp. 15 // It tests: 16 // cilium.io. -> cilium[.]io[.] 17 // *.cilium.io. -> [-a-zA-Z0-9]+.cilium[.]io[.] 18 // *cilium.io. -> "([a-zA-Z0-9]+[.])?cilium[.]io[.] 19 func TestAnchoredMatchPatternREConversion(t *testing.T) { 20 for source, target := range map[string]string{ 21 "cilium.io.": "^cilium[.]io[.]$", 22 "*.cilium.io.": "^" + allowedDNSCharsREGroup + "*[.]cilium[.]io[.]$", 23 "*": "(^(" + allowedDNSCharsREGroup + "+[.])+$)|(^[.]$)", 24 ".": "^[.]$", 25 } { 26 reStr := ToAnchoredRegexp(source) 27 _, err := regexp.Compile(reStr) 28 require.NoErrorf(t, err, "Regexp generated from pattern %q is not valid", source) 29 require.Equal(t, target, reStr, "Regexp generated from pattern %q isn't expected", source) 30 } 31 } 32 33 func TestUnAnchoredMatchPatternREConversion(t *testing.T) { 34 for source, target := range map[string]string{ 35 "cilium.io.": "cilium[.]io[.]", 36 "*.cilium.io.": allowedDNSCharsREGroup + "*[.]cilium[.]io[.]", 37 "*": MatchAllUnAnchoredPattern, 38 ".": "[.]", 39 } { 40 reStr := ToUnAnchoredRegexp(source) 41 _, err := regexp.Compile(reStr) 42 require.NoErrorf(t, err, "Regexp generated from pattern %q is not valid", source) 43 require.Equal(t, target, reStr, "Regexp generated from pattern %q isn't expected", source) 44 } 45 } 46 47 // TestMatchPatternMatching tests that patterns actually match what we expect: 48 // cilium.io. matches only cilium.io. 49 // *.cilium.io. matches anysub.cilium.io. but not cilium.io. 50 // *cilium.io. matches anysub.cilium.io. and cilium.io. 51 // *.ci*.io. matches anysub.cilium.io. anysub.ci.io., anysub.ciliumandmore.io. but not cilium.io. 52 func TestAnchoredMatchPatternMatching(t *testing.T) { 53 for _, testCase := range []struct { 54 pattern string 55 accept []string 56 reject []string 57 }{ 58 { 59 pattern: "cilium.io.", 60 accept: []string{"cilium.io."}, 61 reject: []string{"", "anysub.cilium.io.", "anysub.ci.io.", "anysub.ciliumandmore.io."}, 62 }, 63 { 64 pattern: "*.cilium.io.", 65 accept: []string{"anysub.cilium.io."}, 66 reject: []string{"", "cilium.io.", "anysub.ci.io.", "anysub.ciliumandmore.io."}, 67 }, 68 { 69 pattern: "*.ci*.io.", 70 accept: []string{"anysub.cilium.io.", "anysub.ci.io.", "anysub.ciliumandmore.io."}, 71 reject: []string{"", "cilium.io."}, 72 }, 73 { 74 pattern: "*", 75 accept: []string{".", "io.", "cilium.io.", "svc.cluster.local.", "service.namesace.svc.cluster.local.", "_foobar._tcp.cilium.io."}, // the last is for SRV RFC-2782 and DNS-SD RFC6763 76 reject: []string{"", ".io.", ".cilium.io.", ".svc.cluster.local.", "cilium.io"}, // note no final . on this last one 77 }, 78 { 79 pattern: ".", 80 accept: []string{"."}, 81 reject: []string{"", ".io.", ".cilium.io"}, 82 }, 83 84 // These are more explicit tests for SRV RFC-2782 and DNS-SD RFC6763 85 { 86 pattern: "_foobar._tcp.cilium.io.", 87 accept: []string{"_foobar._tcp.cilium.io."}, 88 reject: []string{"", "_tcp.cilium.io.", "cilium.io."}, 89 }, 90 { 91 pattern: "*.*.cilium.io.", 92 accept: []string{"_foobar._tcp.cilium.io."}, 93 reject: []string{""}, 94 }, 95 } { 96 reStr := ToAnchoredRegexp(testCase.pattern) 97 re, err := regexp.Compile(reStr) 98 require.NoError(t, err, "Regexp generated from pattern is not valid") 99 for _, accept := range testCase.accept { 100 require.Equal(t, true, re.MatchString(accept), "Regexp generated from pattern %s/%s rejected a correct DNS name %s", testCase.pattern, re, accept) 101 } 102 for _, reject := range testCase.reject { 103 require.Equal(t, false, re.MatchString(reject), "Regexp generated from pattern %s/%s accepted a bad DNS name %s", testCase.pattern, re, reject) 104 } 105 } 106 } 107 108 // TestMatchPatternSanitize tests that Sanitize handles any special cases 109 func TestMatchPatternSanitize(t *testing.T) { 110 for source, target := range map[string]string{ 111 "*": "*", 112 "*.": "*.", 113 "*.com": "*.com.", 114 } { 115 sanitized := Sanitize(source) 116 require.Equal(t, target, sanitized, "matchPattern: %s not sanitized correctly", source) 117 } 118 }