@@ -18,6 +18,7 @@ package source_test
18
18
19
19
import (
20
20
"fmt"
21
+ "time"
21
22
22
23
"github.com/kubernetes-sigs/controller-runtime/pkg/cache/informertest"
23
24
"github.com/kubernetes-sigs/controller-runtime/pkg/controller/event"
@@ -26,10 +27,11 @@ import (
26
27
"github.com/kubernetes-sigs/controller-runtime/pkg/runtime/inject"
27
28
. "github.com/onsi/ginkgo"
28
29
. "github.com/onsi/gomega"
29
- "k8s.io/client-go/util/workqueue"
30
30
31
31
"github.com/kubernetes-sigs/controller-runtime/pkg/controller/predicate"
32
32
corev1 "k8s.io/api/core/v1"
33
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
34
+ "k8s.io/client-go/util/workqueue"
33
35
)
34
36
35
37
var _ = Describe ("Source" , func () {
@@ -251,11 +253,194 @@ var _ = Describe("Source", func() {
251
253
})
252
254
253
255
Describe ("ChannelSource" , func () {
254
- It ("TODO(community): implement this" , func (done Done ) {
255
- instance := source .ChannelSource (make (chan event.GenericEvent ))
256
- instance .Start (nil , nil )
256
+ var stop chan struct {}
257
+ var ch chan event.GenericEvent
257
258
258
- close (done )
259
+ BeforeEach (func () {
260
+ stop = make (chan struct {})
261
+ ch = make (chan event.GenericEvent )
262
+ })
263
+
264
+ AfterEach (func () {
265
+ close (stop )
266
+ close (ch )
267
+ })
268
+
269
+ Context ("for a source" , func () {
270
+ It ("should provide a GenericEvent" , func (done Done ) {
271
+ ch := make (chan event.GenericEvent )
272
+ c := make (chan struct {})
273
+ p := & corev1.Pod {
274
+ ObjectMeta : metav1.ObjectMeta {Name : "foo" , Namespace : "bar" },
275
+ }
276
+ evt := event.GenericEvent {
277
+ Object : p ,
278
+ Meta : p ,
279
+ }
280
+
281
+ q := workqueue .NewNamedRateLimitingQueue (workqueue .DefaultControllerRateLimiter (), "test" )
282
+ instance := & source.ChannelSource {Source : ch }
283
+ inject .DoStop (stop , instance )
284
+ err := instance .Start (eventhandler.Funcs {
285
+ CreateFunc : func (workqueue.RateLimitingInterface , event.CreateEvent ) {
286
+ defer GinkgoRecover ()
287
+ Fail ("Unexpected CreateEvent" )
288
+ },
289
+ UpdateFunc : func (workqueue.RateLimitingInterface , event.UpdateEvent ) {
290
+ defer GinkgoRecover ()
291
+ Fail ("Unexpected UpdateEvent" )
292
+ },
293
+ DeleteFunc : func (workqueue.RateLimitingInterface , event.DeleteEvent ) {
294
+ defer GinkgoRecover ()
295
+ Fail ("Unexpected DeleteEvent" )
296
+ },
297
+ GenericFunc : func (q2 workqueue.RateLimitingInterface , evt event.GenericEvent ) {
298
+ defer GinkgoRecover ()
299
+ Expect (q2 ).To (Equal (q ))
300
+ Expect (evt .Meta ).To (Equal (p ))
301
+ Expect (evt .Object ).To (Equal (p ))
302
+ close (c )
303
+ },
304
+ }, q )
305
+ Expect (err ).NotTo (HaveOccurred ())
306
+
307
+ ch <- evt
308
+ <- c
309
+ close (done )
310
+ })
311
+ It ("should block if exceed buffer size" , func (done Done ) {
312
+ ch := make (chan event.GenericEvent )
313
+ evt := event.GenericEvent {}
314
+ interval := 5 * time .Second
315
+
316
+ q := workqueue .NewNamedRateLimitingQueue (workqueue .DefaultControllerRateLimiter (), "test" )
317
+ // Add a handler to get distribution blocked
318
+ instance := & source.ChannelSource {Source : ch }
319
+ instance .DestBufferSize = 1
320
+ inject .DoStop (stop , instance )
321
+ err := instance .Start (eventhandler.Funcs {
322
+ CreateFunc : func (workqueue.RateLimitingInterface , event.CreateEvent ) {
323
+ defer GinkgoRecover ()
324
+ Fail ("Unexpected CreateEvent" )
325
+ },
326
+ UpdateFunc : func (workqueue.RateLimitingInterface , event.UpdateEvent ) {
327
+ defer GinkgoRecover ()
328
+ Fail ("Unexpected UpdateEvent" )
329
+ },
330
+ DeleteFunc : func (workqueue.RateLimitingInterface , event.DeleteEvent ) {
331
+ defer GinkgoRecover ()
332
+ Fail ("Unexpected DeleteEvent" )
333
+ },
334
+ GenericFunc : func (q2 workqueue.RateLimitingInterface , evt event.GenericEvent ) {
335
+ defer GinkgoRecover ()
336
+ time .Sleep (interval )
337
+ },
338
+ }, q )
339
+ Expect (err ).NotTo (HaveOccurred ())
340
+
341
+ // get channel blocked
342
+ ch <- evt
343
+ ch <- evt
344
+ ch <- evt
345
+
346
+ beforeEvent := time .Now ()
347
+ ch <- evt
348
+ // validate event distribution get blocked.
349
+ distributeInterval := time .Now ().Sub (beforeEvent )
350
+ Expect (distributeInterval >= interval ).To (BeTrue ())
351
+ close (done )
352
+ }, 15 )
353
+ It ("should get error if no source specified" , func (done Done ) {
354
+ q := workqueue .NewNamedRateLimitingQueue (workqueue .DefaultControllerRateLimiter (), "test" )
355
+ instance := & source.ChannelSource { /*no source specified*/ }
356
+ inject .DoStop (stop , instance )
357
+ err := instance .Start (eventhandler.Funcs {}, q )
358
+ Expect (err ).To (Equal (fmt .Errorf ("must specify ChannelSource.Source" )))
359
+ close (done )
360
+ })
361
+ It ("should get error if no stop channel injected" , func (done Done ) {
362
+ q := workqueue .NewNamedRateLimitingQueue (workqueue .DefaultControllerRateLimiter (), "test" )
363
+ instance := & source.ChannelSource {Source : ch }
364
+ err := instance .Start (eventhandler.Funcs {}, q )
365
+ Expect (err ).To (Equal (fmt .Errorf ("must call InjectStop on ChannelSource before calling Start" )))
366
+ close (done )
367
+ })
368
+
369
+ })
370
+ Context ("for multi sources (handlers)" , func () {
371
+ It ("should provide GenericEvents for all handlers" , func (done Done ) {
372
+ ch := make (chan event.GenericEvent )
373
+ p := & corev1.Pod {
374
+ ObjectMeta : metav1.ObjectMeta {Name : "foo" , Namespace : "bar" },
375
+ }
376
+ evt := event.GenericEvent {
377
+ Object : p ,
378
+ Meta : p ,
379
+ }
380
+
381
+ var resEvent1 , resEvent2 event.GenericEvent
382
+ c1 := make (chan struct {})
383
+ c2 := make (chan struct {})
384
+
385
+ q := workqueue .NewNamedRateLimitingQueue (workqueue .DefaultControllerRateLimiter (), "test" )
386
+ instance := & source.ChannelSource {Source : ch }
387
+ inject .DoStop (stop , instance )
388
+ err := instance .Start (eventhandler.Funcs {
389
+ CreateFunc : func (workqueue.RateLimitingInterface , event.CreateEvent ) {
390
+ defer GinkgoRecover ()
391
+ Fail ("Unexpected CreateEvent" )
392
+ },
393
+ UpdateFunc : func (workqueue.RateLimitingInterface , event.UpdateEvent ) {
394
+ defer GinkgoRecover ()
395
+ Fail ("Unexpected UpdateEvent" )
396
+ },
397
+ DeleteFunc : func (workqueue.RateLimitingInterface , event.DeleteEvent ) {
398
+ defer GinkgoRecover ()
399
+ Fail ("Unexpected DeleteEvent" )
400
+ },
401
+ GenericFunc : func (q2 workqueue.RateLimitingInterface , evt event.GenericEvent ) {
402
+ defer GinkgoRecover ()
403
+ Expect (q2 ).To (Equal (q ))
404
+ Expect (evt .Meta ).To (Equal (p ))
405
+ Expect (evt .Object ).To (Equal (p ))
406
+ resEvent1 = evt
407
+ close (c1 )
408
+ },
409
+ }, q )
410
+ Expect (err ).NotTo (HaveOccurred ())
411
+
412
+ err = instance .Start (eventhandler.Funcs {
413
+ CreateFunc : func (workqueue.RateLimitingInterface , event.CreateEvent ) {
414
+ defer GinkgoRecover ()
415
+ Fail ("Unexpected CreateEvent" )
416
+ },
417
+ UpdateFunc : func (workqueue.RateLimitingInterface , event.UpdateEvent ) {
418
+ defer GinkgoRecover ()
419
+ Fail ("Unexpected UpdateEvent" )
420
+ },
421
+ DeleteFunc : func (workqueue.RateLimitingInterface , event.DeleteEvent ) {
422
+ defer GinkgoRecover ()
423
+ Fail ("Unexpected DeleteEvent" )
424
+ },
425
+ GenericFunc : func (q2 workqueue.RateLimitingInterface , evt event.GenericEvent ) {
426
+ defer GinkgoRecover ()
427
+ Expect (q2 ).To (Equal (q ))
428
+ Expect (evt .Meta ).To (Equal (p ))
429
+ Expect (evt .Object ).To (Equal (p ))
430
+ resEvent2 = evt
431
+ close (c2 )
432
+ },
433
+ }, q )
434
+ Expect (err ).NotTo (HaveOccurred ())
435
+
436
+ ch <- evt
437
+ <- c1
438
+ <- c2
439
+
440
+ // Validate the two handlers received same event
441
+ Expect (resEvent1 ).To (Equal (resEvent2 ))
442
+ close (done )
443
+ })
259
444
})
260
445
})
261
446
})
0 commit comments