github.com/waldiirawan/apm-agent-go/v2@v2.2.2/internal/wildcard/matcher_test.go (about) 1 // Licensed to Elasticsearch B.V. under one or more contributor 2 // license agreements. See the NOTICE file distributed with 3 // this work for additional information regarding copyright 4 // ownership. Elasticsearch B.V. licenses this file to you under 5 // the Apache License, Version 2.0 (the "License"); you may 6 // 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, 12 // software distributed under the License is distributed on an 13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 // KIND, either express or implied. See the License for the 15 // specific language governing permissions and limitations 16 // under the License. 17 18 package wildcard 19 20 import ( 21 "encoding/json" 22 "fmt" 23 "io/ioutil" 24 "regexp" 25 "strings" 26 "testing" 27 28 "github.com/stretchr/testify/assert" 29 "github.com/stretchr/testify/require" 30 ) 31 32 func TestWildcardSpec(t *testing.T) { 33 // {name -> {pattern -> {input -> match?}}} 34 var tests map[string]map[string]map[string]bool 35 36 data, err := ioutil.ReadFile("../testdata/json-specs/wildcard_matcher_tests.json") 37 require.NoError(t, err) 38 err = json.Unmarshal(data, &tests) 39 require.NoError(t, err) 40 41 for name, patterns := range tests { 42 t.Run(name, func(t *testing.T) { 43 for pattern, inputs := range patterns { 44 origPattern := pattern 45 caseSensitivity := CaseInsensitive 46 if strings.HasPrefix(pattern, "(?-i)") { 47 caseSensitivity = CaseSensitive 48 pattern = pattern[len("(?-i)"):] 49 } 50 matcher := NewMatcher(pattern, caseSensitivity) 51 for input, expectMatch := range inputs { 52 match := matcher.Match(input) 53 assert.Equal(t, expectMatch, match, "Match(%q, %q)", origPattern, input) 54 } 55 } 56 }) 57 } 58 } 59 60 func TestWildcardStartsWith(t *testing.T) { 61 mS := NewMatcher("foo*", CaseSensitive) 62 mI := NewMatcher("foo*", CaseInsensitive) 63 for _, m := range []*Matcher{mS, mI} { 64 assert.True(t, m.Match("foo")) 65 assert.True(t, m.Match("foobar")) 66 assert.False(t, m.Match("bar")) 67 assert.False(t, m.Match("barfoo")) 68 assert.False(t, m.Match("")) 69 } 70 assert.True(t, mI.Match("FoO")) 71 assert.False(t, mS.Match("FoO")) 72 } 73 74 func TestWildcardEndsWith(t *testing.T) { 75 mS := NewMatcher("*foo", CaseSensitive) 76 mI := NewMatcher("*foo", CaseInsensitive) 77 for _, m := range []*Matcher{mS, mI} { 78 assert.True(t, m.Match("foo")) 79 assert.True(t, m.Match("barfoo")) 80 assert.True(t, m.Match("\xed\xbf\xbf\x80foo")) 81 assert.False(t, m.Match("foobar")) 82 assert.False(t, m.Match("bar")) 83 assert.False(t, m.Match("")) 84 } 85 assert.True(t, mI.Match("BaRFoO")) 86 assert.False(t, mS.Match("BaRFoO")) 87 } 88 89 func TestWildcardEqual(t *testing.T) { 90 mS := NewMatcher("foo", CaseSensitive) 91 mI := NewMatcher("foo", CaseInsensitive) 92 for _, m := range []*Matcher{mS, mI} { 93 assert.True(t, m.Match("foo")) 94 assert.False(t, m.Match("foobar")) 95 assert.False(t, m.Match("bar")) 96 assert.False(t, m.Match("barfoo")) 97 assert.False(t, m.Match("")) 98 } 99 assert.True(t, mI.Match("FoO")) 100 assert.False(t, mS.Match("FoO")) 101 } 102 103 func TestWildcardAll(t *testing.T) { 104 mS := NewMatcher("*", CaseSensitive) 105 mI := NewMatcher("*", CaseInsensitive) 106 for _, m := range []*Matcher{mS, mI} { 107 assert.True(t, m.Match("")) 108 assert.True(t, m.Match("x")) 109 } 110 } 111 112 func TestWildcardEmptyPattern(t *testing.T) { 113 mS := NewMatcher("", CaseSensitive) 114 mI := NewMatcher("", CaseInsensitive) 115 for _, m := range []*Matcher{mS, mI} { 116 assert.True(t, m.Match("")) 117 assert.False(t, m.Match("x")) 118 } 119 } 120 121 func TestWildcardMultiples(t *testing.T) { 122 mS := NewMatcher("a*b*c", CaseSensitive) 123 mI := NewMatcher("a*b*c", CaseInsensitive) 124 for _, m := range []*Matcher{mS, mI} { 125 assert.True(t, m.Match("abc")) 126 assert.True(t, m.Match("abbc")) 127 assert.True(t, m.Match("aabc")) 128 assert.True(t, m.Match("abcc")) 129 assert.False(t, m.Match("ab")) 130 assert.False(t, m.Match("bc")) 131 assert.False(t, m.Match("ac")) 132 assert.False(t, m.Match("_abc_")) 133 assert.False(t, m.Match("")) 134 } 135 } 136 137 func TestWildcardSandwich(t *testing.T) { 138 mS := NewMatcher("a*c", CaseSensitive) 139 mI := NewMatcher("a*c", CaseInsensitive) 140 for _, m := range []*Matcher{mS, mI} { 141 assert.True(t, m.Match("abc")) 142 assert.True(t, m.Match("abbc")) 143 assert.True(t, m.Match("aabc")) 144 assert.True(t, m.Match("abcc")) 145 assert.True(t, m.Match("ac")) 146 assert.False(t, m.Match("ab")) 147 assert.False(t, m.Match("bc")) 148 assert.False(t, m.Match("_abc_")) 149 assert.False(t, m.Match("")) 150 } 151 } 152 153 var benchmarkPatterns = []string{ 154 "password", 155 "passwd", 156 "pwd", 157 "secret", 158 "*key", 159 "*token", 160 "*session*", 161 "*credit*", 162 "*card*", 163 "*principal*", 164 } 165 166 func BenchmarkWildcardMatcher(b *testing.B) { 167 matchers := make(Matchers, len(benchmarkPatterns)) 168 for i, p := range benchmarkPatterns { 169 matchers[i] = NewMatcher(p, CaseInsensitive) 170 } 171 b.ResetTimer() 172 benchmarkMatch(b, matchers.MatchAny) 173 } 174 175 func BenchmarkRegexpMatcher(b *testing.B) { 176 patterns := make([]string, len(benchmarkPatterns)) 177 for i, p := range benchmarkPatterns { 178 patterns[i] = strings.Replace(p, "*", ".*", -1) 179 } 180 re := regexp.MustCompile(fmt.Sprintf("(?i:%s)", strings.Join(patterns, "|"))) 181 b.ResetTimer() 182 benchmarkMatch(b, re.MatchString) 183 } 184 185 func benchmarkMatch(b *testing.B, match func(s string) bool) { 186 var bytes int64 187 test := func(s string, expect bool) { 188 if match(s) != expect { 189 panic("nope") 190 } 191 bytes += int64(len(s)) 192 } 193 for i := 0; i < b.N; i++ { 194 test("foo", false) 195 test("session", true) 196 test("passwork", false) 197 test("pwd", true) 198 test("credit_card", true) 199 test("zing", false) 200 test("boop", false) 201 202 b.SetBytes(bytes) 203 bytes = 0 204 } 205 }