@@ -26,7 +26,6 @@ import (
2626 . "github.com/onsi/ginkgo"
2727 . "github.com/onsi/ginkgo/extensions/table"
2828 . "github.com/onsi/gomega"
29-
3029 corev1 "k8s.io/api/core/v1"
3130 apierrors "k8s.io/apimachinery/pkg/api/errors"
3231 "k8s.io/apimachinery/pkg/api/meta"
@@ -124,6 +123,203 @@ var _ = Describe("Informer Cache without DeepCopy", func() {
124123 CacheTest (cache .New , cache.Options {UnsafeDisableDeepCopyByObject : cache.DisableDeepCopyByObject {cache.ObjectAll {}: true }})
125124})
126125
126+ var _ = Describe ("ByNamespace Cache" , func () {
127+ defer GinkgoRecover ()
128+ var (
129+ informerCache cache.Cache
130+ informerCacheCtx context.Context
131+ informerCacheCancel context.CancelFunc
132+
133+ pod1a client.Object
134+ pod1b client.Object
135+ pod2a client.Object
136+ pod2b client.Object
137+ pod2c client.Object
138+ pod3a client.Object
139+ pod3b client.Object
140+ )
141+
142+ BeforeEach (func () {
143+ informerCacheCtx , informerCacheCancel = context .WithCancel (context .Background ())
144+ Expect (cfg ).NotTo (BeNil ())
145+ cl , err := client .New (cfg , client.Options {})
146+ Expect (err ).NotTo (HaveOccurred ())
147+ err = ensureNamespace (testNamespaceOne , cl )
148+ Expect (err ).NotTo (HaveOccurred ())
149+ err = ensureNamespace (testNamespaceTwo , cl )
150+ Expect (err ).NotTo (HaveOccurred ())
151+ err = ensureNamespace (testNamespaceThree , cl )
152+ Expect (err ).NotTo (HaveOccurred ())
153+ err = ensureNode (testNodeOne , cl )
154+ Expect (err ).NotTo (HaveOccurred ())
155+
156+ // namespace 1 stuff
157+ pod1a = createPod ("pod-1a" , testNamespaceOne , corev1 .RestartPolicyNever ) // matches (everything matches)
158+ pod1b = createPodWithLabels ("pod-1b" , testNamespaceOne , corev1 .RestartPolicyNever , map [string ]string {"other-match" : "true" }) // matches (everything matches)
159+
160+ // namespace 2 stuff
161+ pod2a = createPodWithLabels ("pod-2a" , testNamespaceTwo , corev1 .RestartPolicyNever , map [string ]string {"ns2-match" : "false" }) // no match (does not match ns2 label selector)
162+ pod2b = createPodWithLabels ("pod-2b" , testNamespaceTwo , corev1 .RestartPolicyNever , map [string ]string {"ns2-match" : "true" }) // matches (matches ns2 label selector)
163+ pod2c = createPodWithLabels ("pod-2c" , testNamespaceTwo , corev1 .RestartPolicyNever , map [string ]string {"other-match" : "true" }) // no match (does not match ns2 label selector)
164+
165+ // namespace 3 stuff
166+ pod3a = createPodWithLabels ("pod-3a" , testNamespaceThree , corev1 .RestartPolicyNever , map [string ]string {"other-match" : "false" }) // no match (does not match default cache label selector)
167+ pod3b = createPodWithLabels ("pod-3b" , testNamespaceThree , corev1 .RestartPolicyNever , map [string ]string {"other-match" : "true" }) // matches (matches default cache label selector)
168+
169+ By ("creating the informer cache" )
170+ informerCache , err = cache .BuilderByNamespace (cache.ByNamespaceOptions {
171+ NewNamespaceCaches : map [string ]cache.NewCacheFunc {
172+ // Everything in ns1
173+ testNamespaceOne : cache .New ,
174+
175+ // Only things in ns2 with label "ns2-match"="true"
176+ testNamespaceTwo : cache .BuilderWithOptions (cache.Options {
177+ DefaultSelector : cache.ObjectSelector {
178+ Label : labels.Set {"ns2-match" : "true" }.AsSelector (),
179+ },
180+ }),
181+ },
182+ // For all other namespaces, match "other-match"="true"
183+ NewDefaultNamespaceCache : cache .BuilderWithOptions (cache.Options {
184+ DefaultSelector : cache.ObjectSelector {
185+ Label : labels.Set {"other-match" : "true" }.AsSelector (),
186+ },
187+ }),
188+ // For cluster-scoped objects, only match metadata.name = "test-node-1"
189+ NewClusterCache : cache .BuilderWithOptions (cache.Options {
190+ DefaultSelector : cache.ObjectSelector {
191+ Field : fields .OneTermEqualSelector ("metadata.name" , testNodeOne ),
192+ },
193+ }),
194+ })(cfg , cache.Options {})
195+ Expect (err ).NotTo (HaveOccurred ())
196+ By ("running the cache and waiting for it to sync" )
197+ // pass as an arg so that we don't race between close and re-assign
198+ go func (ctx context.Context ) {
199+ defer GinkgoRecover ()
200+ Expect (informerCache .Start (ctx )).To (Succeed ())
201+ }(informerCacheCtx )
202+ Expect (informerCache .WaitForCacheSync (informerCacheCtx )).To (BeTrue ())
203+ })
204+ Describe ("Get" , func () {
205+ It ("should get an item from a namespace cache" , func () {
206+ pod := & corev1.Pod {}
207+ err := informerCache .Get (informerCacheCtx , client .ObjectKeyFromObject (pod1a ), pod )
208+ Expect (err ).NotTo (HaveOccurred ())
209+ })
210+ It ("should get an item from the default namespace cache" , func () {
211+ pod := & corev1.Pod {}
212+ err := informerCache .Get (informerCacheCtx , client .ObjectKeyFromObject (pod3b ), pod )
213+ Expect (err ).NotTo (HaveOccurred ())
214+ })
215+ It ("should get a cluster-scoped item" , func () {
216+ node := & corev1.Node {}
217+ err := informerCache .Get (informerCacheCtx , client.ObjectKey {Name : testNodeOne }, node )
218+ Expect (err ).NotTo (HaveOccurred ())
219+ })
220+ It ("should not find an item from a namespace-specific cache if it is not matched" , func () {
221+ pod := & corev1.Pod {}
222+ err := informerCache .Get (informerCacheCtx , client .ObjectKeyFromObject (pod2a ), pod )
223+ Expect (apierrors .IsNotFound (err )).To (BeTrue ())
224+ })
225+ It ("should not find an item from the default namespace cache if it is not matched" , func () {
226+ pod := & corev1.Pod {}
227+ err := informerCache .Get (informerCacheCtx , client .ObjectKeyFromObject (pod3a ), pod )
228+ Expect (apierrors .IsNotFound (err )).To (BeTrue ())
229+ })
230+ It ("should not find an item at the cluster-scope if it is not matched" , func () {
231+ ns := & corev1.Namespace {}
232+ err := informerCache .Get (informerCacheCtx , client.ObjectKey {Name : testNamespaceOne }, ns )
233+ Expect (apierrors .IsNotFound (err )).To (BeTrue ())
234+ })
235+ })
236+ Describe ("List" , func () {
237+ When ("Request is cluster-scoped" , func () {
238+ It ("Should list all pods and find exactly four" , func () {
239+ var pods corev1.PodList
240+ err := informerCache .List (informerCacheCtx , & pods )
241+ Expect (err ).NotTo (HaveOccurred ())
242+ sort .Slice (pods .Items , func (i , j int ) bool {
243+ if pods .Items [i ].Namespace != pods .Items [j ].Namespace {
244+ return pods .Items [i ].Namespace < pods .Items [j ].Namespace
245+ }
246+ return pods .Items [i ].Name < pods .Items [j ].Name
247+ })
248+
249+ Expect (pods .Items ).To (HaveLen (4 ))
250+ Expect (pods .Items [0 ].Namespace ).To (Equal (testNamespaceOne ))
251+ Expect (pods .Items [0 ].Name ).To (Equal ("pod-1a" ))
252+ Expect (pods .Items [1 ].Namespace ).To (Equal (testNamespaceOne ))
253+ Expect (pods .Items [1 ].Name ).To (Equal ("pod-1b" ))
254+ Expect (pods .Items [2 ].Namespace ).To (Equal (testNamespaceTwo ))
255+ Expect (pods .Items [2 ].Name ).To (Equal ("pod-2b" ))
256+ Expect (pods .Items [3 ].Namespace ).To (Equal (testNamespaceThree ))
257+ Expect (pods .Items [3 ].Name ).To (Equal ("pod-3b" ))
258+ })
259+ It ("Should list nodes and find exactly one" , func () {
260+ var nodes corev1.NodeList
261+ err := informerCache .List (informerCacheCtx , & nodes )
262+ Expect (err ).NotTo (HaveOccurred ())
263+ Expect (nodes .Items ).To (HaveLen (1 ))
264+ Expect (nodes .Items [0 ].Namespace ).To (Equal ("" ))
265+ Expect (nodes .Items [0 ].Name ).To (Equal (testNodeOne ))
266+ })
267+ It ("Should list namespaces and find none" , func () {
268+ var namespaces corev1.NamespaceList
269+ err := informerCache .List (informerCacheCtx , & namespaces )
270+ Expect (err ).NotTo (HaveOccurred ())
271+ Expect (namespaces .Items ).To (HaveLen (0 ))
272+ })
273+ })
274+ When ("Request is namespace-scoped" , func () {
275+ It ("Should list pods in namespace one" , func () {
276+ var pods corev1.PodList
277+ err := informerCache .List (informerCacheCtx , & pods , client .InNamespace (testNamespaceOne ))
278+ Expect (err ).NotTo (HaveOccurred ())
279+ sort .Slice (pods .Items , func (i , j int ) bool {
280+ if pods .Items [i ].Namespace != pods .Items [j ].Namespace {
281+ return pods .Items [i ].Namespace < pods .Items [j ].Namespace
282+ }
283+ return pods .Items [i ].Name < pods .Items [j ].Name
284+ })
285+
286+ Expect (pods .Items ).To (HaveLen (2 ))
287+ Expect (pods .Items [0 ].Namespace ).To (Equal (testNamespaceOne ))
288+ Expect (pods .Items [0 ].Name ).To (Equal ("pod-1a" ))
289+ Expect (pods .Items [1 ].Namespace ).To (Equal (testNamespaceOne ))
290+ Expect (pods .Items [1 ].Name ).To (Equal ("pod-1b" ))
291+ })
292+ It ("Should list pods in namespace two" , func () {
293+ var pods corev1.PodList
294+ err := informerCache .List (informerCacheCtx , & pods , client .InNamespace (testNamespaceTwo ))
295+ Expect (err ).NotTo (HaveOccurred ())
296+ Expect (pods .Items ).To (HaveLen (1 ))
297+ Expect (pods .Items [0 ].Namespace ).To (Equal (testNamespaceTwo ))
298+ Expect (pods .Items [0 ].Name ).To (Equal ("pod-2b" ))
299+ })
300+ It ("Should list pods in namespace three" , func () {
301+ var pods corev1.PodList
302+ err := informerCache .List (informerCacheCtx , & pods , client .InNamespace (testNamespaceThree ))
303+ Expect (err ).NotTo (HaveOccurred ())
304+ Expect (pods .Items ).To (HaveLen (1 ))
305+ Expect (pods .Items [0 ].Namespace ).To (Equal (testNamespaceThree ))
306+ Expect (pods .Items [0 ].Name ).To (Equal ("pod-3b" ))
307+ })
308+ })
309+ })
310+
311+ AfterEach (func () {
312+ deletePod (pod1a )
313+ deletePod (pod1b )
314+ deletePod (pod2a )
315+ deletePod (pod2b )
316+ deletePod (pod2c )
317+ deletePod (pod3a )
318+ deletePod (pod3b )
319+ informerCacheCancel ()
320+ })
321+ })
322+
127323var _ = Describe ("Cache with transformers" , func () {
128324 var (
129325 informerCache cache.Cache
0 commit comments