From 0ba1fc8a7f7b96c1440a3a2185ee85a9c89cec12 Mon Sep 17 00:00:00 2001 From: Bruce Ma Date: Tue, 29 Mar 2022 20:57:31 +0800 Subject: [PATCH] returned objects of reference type should be unchangeable Signed-off-by: Bruce Ma --- pkg/cache/cache_test.go | 34 ++++++++++++++++++++++++++++++++++ pkg/cache/informer_cache.go | 4 ++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/pkg/cache/cache_test.go b/pkg/cache/cache_test.go index 4593cd17f5..07c96b1c24 100644 --- a/pkg/cache/cache_test.go +++ b/pkg/cache/cache_test.go @@ -1245,6 +1245,40 @@ func CacheTest(createCacheFunc func(config *rest.Config, opts cache.Options) (ca Expect(sii).To(BeNil()) Expect(apierrors.IsTimeout(err)).To(BeTrue()) }) + + It("should be able not to change indexer values after indexing cluster-scope objects", func() { + By("creating the cache") + informer, err := cache.New(cfg, cache.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("indexing the Namespace objects with fixed values before starting") + pod := &corev1.Namespace{} + indexerValues := []string{"a", "b", "c"} + fieldName := "fixedValues" + indexFunc := func(obj client.Object) []string { + return indexerValues + } + Expect(informer.IndexField(context.TODO(), pod, fieldName, indexFunc)).To(Succeed()) + + By("running the cache and waiting for it to sync") + go func() { + defer GinkgoRecover() + Expect(informer.Start(informerCacheCtx)).To(Succeed()) + }() + Expect(informer.WaitForCacheSync(informerCacheCtx)).NotTo(BeFalse()) + + By("listing Namespaces with fixed indexer") + listObj := &corev1.NamespaceList{} + Expect(informer.List(context.Background(), listObj, + client.MatchingFields{fieldName: "a"})).To(Succeed()) + Expect(listObj.Items).NotTo(BeZero()) + + By("verifying the indexing does not change fixed returned values") + Expect(indexerValues).Should(HaveLen(3)) + Expect(indexerValues[0]).To(Equal("a")) + Expect(indexerValues[1]).To(Equal("b")) + Expect(indexerValues[2]).To(Equal("c")) + }) }) Context("with unstructured objects", func() { It("should be able to get informer for the object", func() { diff --git a/pkg/cache/informer_cache.go b/pkg/cache/informer_cache.go index c5a25ca179..ac07be2a6e 100644 --- a/pkg/cache/informer_cache.go +++ b/pkg/cache/informer_cache.go @@ -193,8 +193,8 @@ func indexByField(indexer Informer, field string, extractor client.IndexerFunc) rawVals := extractor(obj) var vals []string if ns == "" { - // if we're not doubling the keys for the namespaced case, just re-use what was returned to us - vals = rawVals + // if we're not doubling the keys for the namespaced case, just create a new slice with same length + vals = make([]string, len(rawVals)) } else { // if we need to add non-namespaced versions too, double the length vals = make([]string, len(rawVals)*2)