knative.dev/pkg@v0.0.0-20260602142205-ac97e43f6622/webhook/psbinding/index_test.go (about) 1 /* 2 Copyright 2019 The Knative Authors 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package psbinding 18 19 import ( 20 "testing" 21 22 "github.com/google/go-cmp/cmp" 23 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 24 "k8s.io/apimachinery/pkg/labels" 25 26 . "knative.dev/pkg/testing/duck" 27 ) 28 29 func TestExact(t *testing.T) { 30 em := make(exactMatcher, 1) 31 32 want := &TestBindable{ 33 ObjectMeta: metav1.ObjectMeta{ 34 Namespace: "blah", 35 Name: "asdf", 36 }, 37 } 38 39 gvk := want.GetGroupVersionKind() 40 key := exactKey{ 41 Group: gvk.Group, 42 Kind: gvk.Kind, 43 Namespace: want.GetNamespace(), 44 Name: want.GetName(), 45 } 46 47 // Before we add something, we shouldn't be able to get anything. 48 if got := em.get(key); len(got) != 0 { 49 t.Errorf("Get(%+v) = %v; wanted empty list", key, got) 50 } 51 52 // Now add it. 53 em.add(key, want) 54 55 // After we add something, we should be able to get it. 56 wanted := []Bindable{want} 57 if got := em.get(key); !cmp.Equal(got, wanted) { 58 t.Error("Get (-want, +got):", cmp.Diff(wanted, got)) 59 } 60 61 otherKey := exactKey{ 62 Group: "apps", 63 Kind: "Deployment", 64 Namespace: "foo", 65 Name: "bar", 66 } 67 68 // After we add something, we still shouldn't return things for other keys. 69 if got := em.get(otherKey); len(got) != 0 { 70 t.Errorf("Get(%+v) = %v; wanted empty list", key, got) 71 } 72 73 // Add another Binding with the same coordinates. 74 alsoWant := &TestBindable{ 75 ObjectMeta: metav1.ObjectMeta{ 76 Namespace: "blah", 77 Name: "asdf", 78 }, 79 } 80 em.add(key, want) 81 82 // We should now get both Bindings. 83 wanted = []Bindable{want, alsoWant} 84 if got := em.get(key); !cmp.Equal(got, wanted) { 85 t.Error("Get (-want, +got):", cmp.Diff(wanted, got)) 86 } 87 } 88 89 func TestInexact(t *testing.T) { 90 want := &TestBindable{ 91 ObjectMeta: metav1.ObjectMeta{ 92 Namespace: "blah", 93 Name: "asdf", 94 Labels: map[string]string{ 95 "foo": "bar", 96 "baz": "blah", 97 }, 98 }, 99 } 100 ls := labels.Set(want.Labels) 101 102 gvk := want.GetGroupVersionKind() 103 key := inexactKey{ 104 Group: gvk.Group, 105 Kind: gvk.Kind, 106 Namespace: want.GetNamespace(), 107 } 108 109 t.Run("empty matcher doesn't match", func(t *testing.T) { 110 im := make(inexactMatcher, 1) 111 if got := im.get(key, ls); len(got) != 0 { 112 t.Errorf("Get(%+v) = %v; wanted empty list", key, got) 113 } 114 }) 115 116 t.Run("matcher with exact labels matches", func(t *testing.T) { 117 im := make(inexactMatcher, 1) 118 119 // Use exactly the labels from the resource. 120 selector := ls.AsSelector() 121 122 im.add(key, selector, want) 123 124 // With an appropriate selector, we match and get the binding. 125 wanted := []Bindable{want} 126 if got := im.get(key, ls); !cmp.Equal(got, wanted) { 127 t.Error("Get (-want, +got):", cmp.Diff(wanted, got)) 128 } 129 }) 130 131 t.Run("matcher for everything matches", func(t *testing.T) { 132 im := make(inexactMatcher, 1) 133 134 // Match everything. 135 selector := labels.Everything() 136 137 im.add(key, selector, want) 138 139 // With an appropriate selector, we match and get the binding. 140 wanted := []Bindable{want} 141 if got := im.get(key, ls); !cmp.Equal(got, wanted) { 142 t.Error("Get (-want, +got):", cmp.Diff(wanted, got)) 143 } 144 }) 145 146 t.Run("matcher for nothing does not match", func(t *testing.T) { 147 im := make(inexactMatcher, 1) 148 149 // Match nothing. 150 selector := labels.Nothing() 151 152 im.add(key, selector, want) 153 154 if got := im.get(key, ls); len(got) != 0 { 155 t.Errorf("Get(%+v) = %v; wanted empty list", key, got) 156 } 157 }) 158 159 t.Run("matcher with a subset of labels matches", func(t *testing.T) { 160 im := make(inexactMatcher, 1) 161 162 // Use a subset of the resources labels. 163 selector := labels.Set(map[string]string{ 164 "foo": "bar", 165 }).AsSelector() 166 167 im.add(key, selector, want) 168 169 // With an appropriate selector, we match and get the binding. 170 wanted := []Bindable{want} 171 if got := im.get(key, ls); !cmp.Equal(got, wanted) { 172 t.Error("Get (-want, +got):", cmp.Diff(wanted, got)) 173 } 174 }) 175 176 t.Run("matcher with overlapping labels does not match", func(t *testing.T) { 177 im := make(inexactMatcher, 1) 178 179 // Use a subset of the resources labels. 180 selector := labels.Set(map[string]string{ 181 "foo": "bar", 182 "not": "found", 183 }).AsSelector() 184 185 im.add(key, selector, want) 186 187 // We shouldn't match because the second labels shouldn't match. 188 if got := im.get(key, ls); len(got) != 0 { 189 t.Errorf("Get(%+v) = %v; wanted empty list", key, got) 190 } 191 }) 192 193 t.Run("matcher with exact labels doesn't match a different namespace", func(t *testing.T) { 194 im := make(inexactMatcher, 1) 195 196 // Use exactly the labels from the resource. 197 selector := ls.AsSelector() 198 199 im.add(key, selector, want) 200 201 otherKey := key 202 otherKey.Namespace = "another" 203 204 // We shouldn't match because the second labels shouldn't match. 205 if got := im.get(otherKey, ls); len(got) != 0 { 206 t.Errorf("Get(%+v) = %v; wanted empty list", key, got) 207 } 208 }) 209 210 t.Run("multiple Bindings match", func(t *testing.T) { 211 alsoWant := &TestBindable{ 212 ObjectMeta: metav1.ObjectMeta{ 213 Namespace: "blah", 214 Name: "asdf", 215 Labels: map[string]string{ 216 "foo": "bar", 217 "baz": "blah", 218 }, 219 }, 220 } 221 222 im := make(inexactMatcher, 1) 223 224 // Use a subset of the resources labels. 225 selector := labels.Set(map[string]string{ 226 "foo": "bar", 227 }).AsSelector() 228 229 im.add(key, selector, want) 230 im.add(key, selector, alsoWant) 231 232 // With an appropriate selector, we match and get both bindings. 233 wanted := []Bindable{want, alsoWant} 234 if got := im.get(key, ls); !cmp.Equal(got, wanted) { 235 t.Error("Get (-want, +got):", cmp.Diff(wanted, got)) 236 } 237 }) 238 } 239 240 func TestIndex(t *testing.T) { 241 wantExact1 := &TestBindable{ 242 ObjectMeta: metav1.ObjectMeta{ 243 Namespace: "a", 244 Name: "b", 245 Labels: map[string]string{ 246 "colour": "red", 247 }, 248 }, 249 } 250 251 wantExact2 := &TestBindable{ 252 ObjectMeta: metav1.ObjectMeta{ 253 Namespace: "a", 254 Name: "b", 255 Labels: map[string]string{ 256 "colour": "blue", 257 }, 258 }, 259 } 260 261 wantInexact1 := &TestBindable{ 262 ObjectMeta: metav1.ObjectMeta{ 263 Namespace: "a", 264 Name: "b", 265 Labels: map[string]string{ 266 "colour": "red", 267 }, 268 }, 269 } 270 271 wantInexact2 := &TestBindable{ 272 ObjectMeta: metav1.ObjectMeta{ 273 Namespace: "a", 274 Name: "b", 275 Labels: map[string]string{ 276 "colour": "blue", 277 }, 278 }, 279 } 280 281 gvk := wantExact1.GetGroupVersionKind() 282 eKey := exactKey{ 283 Group: gvk.Group, 284 Kind: gvk.Kind, 285 Namespace: wantExact1.GetNamespace(), 286 Name: wantExact1.GetName(), 287 } 288 iKey := inexactKey{ 289 Group: gvk.Group, 290 Kind: gvk.Kind, 291 Namespace: wantExact1.GetNamespace(), 292 } 293 redLabels := labels.Set(wantInexact1.Labels) 294 redSelector := redLabels.AsSelector() 295 blueLabels := labels.Set(wantInexact2.Labels) 296 blueSelector := blueLabels.AsSelector() 297 none := make(labels.Set) 298 allSelector := none.AsSelector() 299 300 t.Run("single exact match is found", func(t *testing.T) { 301 var index index 302 newIndexBuilder(). 303 associate(eKey, wantExact1). 304 build(&index) 305 306 wanted := []Bindable{wantExact1} 307 if got := index.lookUp(eKey, none); !cmp.Equal(got, wanted) { 308 t.Error("Get (-want, +got):", cmp.Diff(wanted, got)) 309 } 310 }) 311 312 t.Run("single inexact match is found", func(t *testing.T) { 313 var index index 314 newIndexBuilder(). 315 associateSelection(iKey, redSelector, wantInexact1). 316 build(&index) 317 318 wanted := []Bindable{wantInexact1} 319 if got := index.lookUp(eKey, redLabels); !cmp.Equal(got, wanted) { 320 t.Error("Get (-want, +got):", cmp.Diff(wanted, got)) 321 } 322 }) 323 324 t.Run("multiple exact matches are found", func(t *testing.T) { 325 var index index 326 newIndexBuilder(). 327 associate(eKey, wantExact1). 328 associate(eKey, wantExact2). 329 build(&index) 330 331 wanted := []Bindable{wantExact1, wantExact2} 332 if got := index.lookUp(eKey, none); !cmp.Equal(got, wanted) { 333 t.Error("Get (-want, +got):", cmp.Diff(wanted, got)) 334 } 335 }) 336 337 t.Run("multiple inexact matches are found", func(t *testing.T) { 338 var index index 339 newIndexBuilder(). 340 associateSelection(iKey, allSelector, wantInexact1). 341 associateSelection(iKey, allSelector, wantInexact2). 342 build(&index) 343 344 wanted := []Bindable{wantInexact1, wantInexact2} 345 if got := index.lookUp(eKey, redLabels); !cmp.Equal(got, wanted) { 346 t.Error("Get (-want, +got):", cmp.Diff(wanted, got)) 347 } 348 }) 349 350 t.Run("multiple exact and inexact matches are found", func(t *testing.T) { 351 var index index 352 newIndexBuilder(). 353 associate(eKey, wantExact1). 354 associate(eKey, wantExact2). 355 associateSelection(iKey, allSelector, wantInexact1). 356 associateSelection(iKey, allSelector, wantInexact2). 357 build(&index) 358 359 wanted := []Bindable{wantExact1, wantExact2, wantInexact1, wantInexact2} 360 if got := index.lookUp(eKey, none); !cmp.Equal(got, wanted) { 361 t.Error("Get (-want, +got):", cmp.Diff(wanted, got)) 362 } 363 }) 364 365 t.Run("the correct exact and inexact matches are found", func(t *testing.T) { 366 var index index 367 newIndexBuilder(). 368 associate(eKey, wantExact1). 369 associate(eKey, wantExact2). 370 associateSelection(iKey, redSelector, wantInexact1). 371 associateSelection(iKey, blueSelector, wantInexact2). 372 build(&index) 373 374 wanted := []Bindable{wantExact1, wantExact2, wantInexact1} 375 if got := index.lookUp(eKey, redLabels); !cmp.Equal(got, wanted) { 376 t.Error("Get (-want, +got):", cmp.Diff(wanted, got)) 377 } 378 }) 379 }