diff --git a/dynamic/dynamicinformer/informer_test.go b/dynamic/dynamicinformer/informer_test.go index 08d66945..b3b10ef7 100644 --- a/dynamic/dynamicinformer/informer_test.go +++ b/dynamic/dynamicinformer/informer_test.go @@ -32,6 +32,99 @@ import ( "k8s.io/client-go/tools/cache" ) +type triggerFunc func(gvr schema.GroupVersionResource, ns string, fakeClient *fake.FakeDynamicClient, testObject *unstructured.Unstructured) *unstructured.Unstructured + +func triggerFactory(t *testing.T) triggerFunc { + return func(gvr schema.GroupVersionResource, ns string, fakeClient *fake.FakeDynamicClient, _ *unstructured.Unstructured) *unstructured.Unstructured { + testObject := newUnstructured("apps/v1", "Deployment", "ns-foo", "name-foo") + createdObj, err := fakeClient.Resource(gvr).Namespace(ns).Create(context.TODO(), testObject, metav1.CreateOptions{}) + if err != nil { + t.Error(err) + } + return createdObj + } +} + +func handler(rcvCh chan<- *unstructured.Unstructured) *cache.ResourceEventHandlerFuncs { + return &cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) { + rcvCh <- obj.(*unstructured.Unstructured) + }, + } +} + +func TestFilteredDynamicSharedInformerFactory(t *testing.T) { + scenarios := []struct { + name string + existingObj *unstructured.Unstructured + gvr schema.GroupVersionResource + informNS string + ns string + trigger func(gvr schema.GroupVersionResource, ns string, fakeClient *fake.FakeDynamicClient, testObject *unstructured.Unstructured) *unstructured.Unstructured + handler func(rcvCh chan<- *unstructured.Unstructured) *cache.ResourceEventHandlerFuncs + }{ + // scenario 1 + { + name: "scenario 1: test adding an object in different namespace should not trigger AddFunc", + informNS: "ns-bar", + ns: "ns-foo", + gvr: schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"}, + trigger: triggerFactory(t), + handler: handler, + }, + // scenario 2 + { + name: "scenario 2: test adding an object should trigger AddFunc", + informNS: "ns-foo", + ns: "ns-foo", + gvr: schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"}, + trigger: triggerFactory(t), + handler: handler, + }, + } + + for _, ts := range scenarios { + t.Run(ts.name, func(t *testing.T) { + // test data + timeout := time.Duration(3 * time.Second) + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + scheme := runtime.NewScheme() + informerReciveObjectCh := make(chan *unstructured.Unstructured, 1) + objs := []runtime.Object{} + if ts.existingObj != nil { + objs = append(objs, ts.existingObj) + } + fakeClient := fake.NewSimpleDynamicClient(scheme, objs...) + target := dynamicinformer.NewFilteredDynamicSharedInformerFactory(fakeClient, 0, ts.informNS, nil) + + // act + informerListerForGvr := target.ForResource(ts.gvr) + informerListerForGvr.Informer().AddEventHandler(ts.handler(informerReciveObjectCh)) + target.Start(ctx.Done()) + if synced := target.WaitForCacheSync(ctx.Done()); !synced[ts.gvr] { + t.Errorf("informer for %s hasn't synced", ts.gvr) + } + + testObject := ts.trigger(ts.gvr, ts.ns, fakeClient, ts.existingObj) + select { + case objFromInformer := <-informerReciveObjectCh: + if ts.ns != ts.informNS { + t.Errorf("informer received an object for namespace %s when watching namespace %s", ts.ns, ts.informNS) + } + if !equality.Semantic.DeepEqual(testObject, objFromInformer) { + t.Fatalf("%v", diff.ObjectDiff(testObject, objFromInformer)) + } + case <-ctx.Done(): + if ts.ns == ts.informNS { + t.Errorf("tested informer haven't received an object, waited %v", timeout) + } + } + }) + } + +} + func TestDynamicSharedInformerFactory(t *testing.T) { scenarios := []struct { name string