istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pkg/kube/krt/singleton_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 krt_test 16 17 import ( 18 "fmt" 19 "testing" 20 21 corev1 "k8s.io/api/core/v1" 22 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 23 24 "istio.io/istio/pkg/config" 25 "istio.io/istio/pkg/kube" 26 "istio.io/istio/pkg/kube/kclient/clienttest" 27 "istio.io/istio/pkg/kube/krt" 28 "istio.io/istio/pkg/ptr" 29 "istio.io/istio/pkg/slices" 30 "istio.io/istio/pkg/test" 31 "istio.io/istio/pkg/test/util/assert" 32 ) 33 34 func TestSingleton(t *testing.T) { 35 c := kube.NewFakeClient() 36 ConfigMaps := krt.NewInformer[*corev1.ConfigMap](c) 37 stop := test.NewStop(t) 38 c.RunAndWait(stop) 39 cmt := clienttest.NewWriter[*corev1.ConfigMap](t, c) 40 ConfigMapNames := krt.NewSingleton[string]( 41 func(ctx krt.HandlerContext) *string { 42 cms := krt.Fetch(ctx, ConfigMaps) 43 return ptr.Of(slices.Join(",", slices.Map(cms, func(c *corev1.ConfigMap) string { 44 return config.NamespacedName(c).String() 45 })...)) 46 }, 47 ) 48 ConfigMapNames.AsCollection().Synced().WaitUntilSynced(stop) 49 tt := assert.NewTracker[string](t) 50 ConfigMapNames.Register(TrackerHandler[string](tt)) 51 tt.WaitOrdered("add/") 52 53 assert.Equal(t, *ConfigMapNames.Get(), "") 54 55 cmt.Create(&corev1.ConfigMap{ 56 ObjectMeta: metav1.ObjectMeta{ 57 Name: "a", 58 Namespace: "ns", 59 }, 60 }) 61 tt.WaitUnordered("delete/", "add/ns/a") 62 assert.Equal(t, *ConfigMapNames.Get(), "ns/a") 63 } 64 65 func TestNewStatic(t *testing.T) { 66 tt := assert.NewTracker[string](t) 67 s := krt.NewStatic[string](nil) 68 s.Register(TrackerHandler[string](tt)) 69 70 assert.Equal(t, s.Get(), nil) 71 72 s.Set(ptr.Of("foo")) 73 assert.Equal(t, s.Get(), ptr.Of("foo")) 74 tt.WaitOrdered("add/foo") 75 76 s.Set(nil) 77 assert.Equal(t, s.Get(), nil) 78 tt.WaitOrdered("delete/foo") 79 80 s.Set(ptr.Of("bar")) 81 assert.Equal(t, s.Get(), ptr.Of("bar")) 82 tt.WaitOrdered("add/bar") 83 84 s.Set(ptr.Of("bar2")) 85 assert.Equal(t, s.Get(), ptr.Of("bar2")) 86 tt.WaitOrdered("update/bar2") 87 } 88 89 // TrackerHandler returns an object handler that records each event 90 func TrackerHandler[T any](tracker *assert.Tracker[string]) func(krt.Event[T]) { 91 return func(o krt.Event[T]) { 92 tracker.Record(fmt.Sprintf("%v/%v", o.Event, krt.GetKey(o.Latest()))) 93 } 94 } 95 96 func BatchedTrackerHandler[T any](tracker *assert.Tracker[string]) func([]krt.Event[T], bool) { 97 return func(o []krt.Event[T], initialSync bool) { 98 tracker.Record(slices.Join(",", slices.Map(o, func(o krt.Event[T]) string { 99 return fmt.Sprintf("%v/%v", o.Event, krt.GetKey(o.Latest())) 100 })...)) 101 } 102 }