From 1285fb757217c09e739673c3fa379062d900c4fd Mon Sep 17 00:00:00 2001 From: Binh Tran Date: Fri, 30 Jul 2021 16:48:01 -0400 Subject: [PATCH] Fix a bug with `Limit` list opt. Previously, `Limit(n)` only looks at the first `n` objects. This could cause `List` to return less than `n` objects if other `opts` apply further filtering, even though there are more than `n` total number of objects matching the list options. --- pkg/cache/cache_test.go | 9 +++++++++ pkg/cache/internal/cache_reader.go | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/pkg/cache/cache_test.go b/pkg/cache/cache_test.go index 2ca78f9f4a..b8df99ede1 100644 --- a/pkg/cache/cache_test.go +++ b/pkg/cache/cache_test.go @@ -312,6 +312,15 @@ func CacheTest(createCacheFunc func(config *rest.Config, opts cache.Options) (ca Expect(informerCache.List(context.Background(), listObj, opts)).To(Succeed()) Expect(listObj.Items).Should(HaveLen(3)) }) + + It("should return a limited result set matching the correct label", func() { + listObj := &corev1.PodList{} + labelOpt := client.MatchingLabels(map[string]string{"common-label": "common"}) + limitOpt := client.Limit(1) + By("verifying that only Limit (1) number of objects are retrieved from the cache") + Expect(informerCache.List(context.Background(), listObj, labelOpt, limitOpt)).To(Succeed()) + Expect(listObj.Items).Should(HaveLen(1)) + }) }) Context("with unstructured objects", func() { diff --git a/pkg/cache/internal/cache_reader.go b/pkg/cache/internal/cache_reader.go index 5a495693ed..95084821fe 100644 --- a/pkg/cache/internal/cache_reader.go +++ b/pkg/cache/internal/cache_reader.go @@ -129,10 +129,10 @@ func (c *CacheReader) List(_ context.Context, out client.ObjectList, opts ...cli limitSet := listOpts.Limit > 0 runtimeObjs := make([]runtime.Object, 0, len(objs)) - for i, item := range objs { + for _, item := range objs { // if the Limit option is set and the number of items // listed exceeds this limit, then stop reading. - if limitSet && int64(i) >= listOpts.Limit { + if limitSet && int64(len(runtimeObjs)) >= listOpts.Limit { break } obj, isObj := item.(runtime.Object)