istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pilot/pkg/security/authz/matcher/string_test.go (about) 1 // Copyright Istio Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package matcher 16 17 import ( 18 "testing" 19 20 matcher "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3" 21 "github.com/google/go-cmp/cmp" 22 "google.golang.org/protobuf/testing/protocmp" 23 ) 24 25 type testCase struct { 26 name string 27 v string 28 prefix string 29 want *matcher.StringMatcher 30 } 31 32 func TestStringMatcherWithPrefix(t *testing.T) { 33 testCases := []testCase{ 34 { 35 name: "wildcardAsRequired", 36 v: "*", 37 prefix: "abc", 38 want: StringMatcherRegex(".+"), 39 }, 40 { 41 name: "prefix", 42 v: "-prefix-*", 43 prefix: "abc", 44 want: &matcher.StringMatcher{ 45 MatchPattern: &matcher.StringMatcher_Prefix{ 46 Prefix: "abc-prefix-", 47 }, 48 }, 49 }, 50 { 51 name: "suffix-empty-prefix", 52 v: "*-suffix", 53 prefix: "", 54 want: &matcher.StringMatcher{ 55 MatchPattern: &matcher.StringMatcher_Suffix{ 56 Suffix: "-suffix", 57 }, 58 }, 59 }, 60 { 61 name: "suffix", 62 v: "*-suffix", 63 prefix: "abc", 64 want: StringMatcherRegex("abc.*-suffix"), 65 }, 66 { 67 name: "exact", 68 v: "-exact", 69 prefix: "abc", 70 want: &matcher.StringMatcher{ 71 MatchPattern: &matcher.StringMatcher_Exact{ 72 Exact: "abc-exact", 73 }, 74 }, 75 }, 76 } 77 78 for _, tc := range testCases { 79 t.Run(tc.name, func(t *testing.T) { 80 actual := StringMatcherWithPrefix(tc.v, tc.prefix) 81 if !cmp.Equal(actual, tc.want, protocmp.Transform()) { 82 t.Errorf("want %s but got %s", tc.want.String(), actual.String()) 83 } 84 }) 85 } 86 } 87 88 func TestStringMatcherRegex(t *testing.T) { 89 testCases := []testCase{ 90 { 91 name: "wildcardAsRequired", 92 v: "*", 93 want: &matcher.StringMatcher{ 94 MatchPattern: &matcher.StringMatcher_SafeRegex{ 95 SafeRegex: &matcher.RegexMatcher{ 96 Regex: "*", 97 }, 98 }, 99 }, 100 }, 101 { 102 name: "regexExpression", 103 v: "+?", 104 want: &matcher.StringMatcher{ 105 MatchPattern: &matcher.StringMatcher_SafeRegex{ 106 SafeRegex: &matcher.RegexMatcher{ 107 Regex: "+?", 108 }, 109 }, 110 }, 111 }, 112 } 113 114 for _, tc := range testCases { 115 t.Run(tc.name, func(t *testing.T) { 116 if actual := StringMatcherRegex(tc.v); !cmp.Equal(actual, tc.want, protocmp.Transform()) { 117 t.Errorf("want %s but got %s", tc.want.String(), actual.String()) 118 } 119 }) 120 } 121 } 122 123 func TestStringMatcherPrefix(t *testing.T) { 124 testCases := []struct { 125 name string 126 str string 127 ignoreCase bool 128 want *matcher.StringMatcher 129 }{ 130 { 131 name: "prefix1", 132 str: "foo", 133 ignoreCase: true, 134 want: &matcher.StringMatcher{ 135 IgnoreCase: true, 136 MatchPattern: &matcher.StringMatcher_Prefix{ 137 Prefix: "foo", 138 }, 139 }, 140 }, 141 { 142 name: "prefix2", 143 str: "bar", 144 ignoreCase: false, 145 want: &matcher.StringMatcher{ 146 IgnoreCase: false, 147 MatchPattern: &matcher.StringMatcher_Prefix{ 148 Prefix: "bar", 149 }, 150 }, 151 }, 152 } 153 154 for _, tc := range testCases { 155 t.Run(tc.name, func(t *testing.T) { 156 got := StringMatcherPrefix(tc.str, tc.ignoreCase) 157 if !cmp.Equal(got, tc.want, protocmp.Transform()) { 158 t.Errorf("want %v but got %v", tc.want, got) 159 } 160 }) 161 } 162 } 163 164 func TestStringMatcherSuffix(t *testing.T) { 165 testCases := []struct { 166 name string 167 str string 168 ignoreCase bool 169 want *matcher.StringMatcher 170 }{ 171 { 172 name: "suffix1", 173 str: "foo", 174 ignoreCase: true, 175 want: &matcher.StringMatcher{ 176 IgnoreCase: true, 177 MatchPattern: &matcher.StringMatcher_Suffix{ 178 Suffix: "foo", 179 }, 180 }, 181 }, 182 { 183 name: "suffix2", 184 str: "bar", 185 ignoreCase: false, 186 want: &matcher.StringMatcher{ 187 IgnoreCase: false, 188 MatchPattern: &matcher.StringMatcher_Suffix{ 189 Suffix: "bar", 190 }, 191 }, 192 }, 193 } 194 195 for _, tc := range testCases { 196 t.Run(tc.name, func(t *testing.T) { 197 got := StringMatcherSuffix(tc.str, tc.ignoreCase) 198 if !cmp.Equal(got, tc.want, protocmp.Transform()) { 199 t.Errorf("want %v but got %v", tc.want, got) 200 } 201 }) 202 } 203 } 204 205 func TestStringMatcherExact(t *testing.T) { 206 testCases := []struct { 207 name string 208 str string 209 ignoreCase bool 210 want *matcher.StringMatcher 211 }{ 212 { 213 name: "exact1", 214 str: "foo", 215 ignoreCase: true, 216 want: &matcher.StringMatcher{ 217 IgnoreCase: true, 218 MatchPattern: &matcher.StringMatcher_Exact{ 219 Exact: "foo", 220 }, 221 }, 222 }, 223 { 224 name: "exact2", 225 str: "bar", 226 ignoreCase: false, 227 want: &matcher.StringMatcher{ 228 IgnoreCase: false, 229 MatchPattern: &matcher.StringMatcher_Exact{ 230 Exact: "bar", 231 }, 232 }, 233 }, 234 } 235 236 for _, tc := range testCases { 237 t.Run(tc.name, func(t *testing.T) { 238 got := StringMatcherExact(tc.str, tc.ignoreCase) 239 if !cmp.Equal(got, tc.want, protocmp.Transform()) { 240 t.Errorf("want %v but got %v", tc.want, got) 241 } 242 }) 243 } 244 }