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  }