@@ -38,6 +38,7 @@ import (
3838 "sigs.k8s.io/controller-runtime/pkg/cache/informertest"
3939 "sigs.k8s.io/controller-runtime/pkg/client"
4040 "sigs.k8s.io/controller-runtime/pkg/controller/controllertest"
41+ "sigs.k8s.io/controller-runtime/pkg/controller/priorityqueue"
4142 "sigs.k8s.io/controller-runtime/pkg/event"
4243 "sigs.k8s.io/controller-runtime/pkg/handler"
4344 ctrlmetrics "sigs.k8s.io/controller-runtime/pkg/internal/controller/metrics"
@@ -345,9 +346,10 @@ var _ = Describe("controller", func() {
345346 })
346347
347348 It ("should check for correct TypedSyncingSource if custom types are used" , func () {
348- queue := & controllertest.TypedQueue [TestRequest ]{
349- TypedInterface : workqueue .NewTyped [TestRequest ](),
350- }
349+ queue := & priorityQueueWrapper [TestRequest ]{
350+ TypedRateLimitingInterface : & controllertest.TypedQueue [TestRequest ]{
351+ TypedInterface : workqueue .NewTyped [TestRequest ](),
352+ }}
351353 ctrl := & Controller [TestRequest ]{
352354 NewQueue : func (string , workqueue.TypedRateLimiter [TestRequest ]) workqueue.TypedRateLimitingInterface [TestRequest ] {
353355 return queue
@@ -400,10 +402,6 @@ var _ = Describe("controller", func() {
400402 Eventually (func () int { return queue .NumRequeues (request ) }).Should (Equal (0 ))
401403 })
402404
403- PIt ("should forget an item if it is not a Request and continue processing items" , func () {
404- // TODO(community): write this test
405- })
406-
407405 It ("should requeue a Request if there is an error and continue processing items" , func () {
408406 ctx , cancel := context .WithCancel (context .Background ())
409407 defer cancel ()
@@ -523,6 +521,37 @@ var _ = Describe("controller", func() {
523521 Eventually (func () int { return dq .NumRequeues (request ) }).Should (Equal (0 ))
524522 })
525523
524+ It ("should retain the priority when the reconciler requests a requeue" , func () {
525+ q := & fakePriorityQueue {PriorityQueue : priorityqueue.New [reconcile.Request ]("controller1" )}
526+ ctrl .NewQueue = func (string , workqueue.TypedRateLimiter [reconcile.Request ]) workqueue.TypedRateLimitingInterface [reconcile.Request ] {
527+ return q
528+ }
529+
530+ ctx , cancel := context .WithCancel (context .Background ())
531+ defer cancel ()
532+ go func () {
533+ defer GinkgoRecover ()
534+ Expect (ctrl .Start (ctx )).NotTo (HaveOccurred ())
535+ }()
536+
537+ q .PriorityQueue .AddWithOpts (priorityqueue.AddOpts {Priority : 10 }, request )
538+
539+ By ("Invoking Reconciler which will request a requeue" )
540+ fakeReconcile .AddResult (reconcile.Result {Requeue : true }, nil )
541+ Expect (<- reconciled ).To (Equal (request ))
542+ Eventually (func () []priorityQueueAddition {
543+ q .lock .Lock ()
544+ defer q .lock .Unlock ()
545+ return q .added
546+ }).Should (Equal ([]priorityQueueAddition {{
547+ AddOpts : priorityqueue.AddOpts {
548+ RateLimited : true ,
549+ Priority : 10 ,
550+ },
551+ items : []reconcile.Request {request },
552+ }}))
553+ })
554+
526555 It ("should requeue a Request after a duration (but not rate-limitted) if the Result sets RequeueAfter (regardless of Requeue)" , func () {
527556 dq := & DelegatingQueue {TypedRateLimitingInterface : ctrl .NewQueue ("controller1" , nil )}
528557 ctrl .NewQueue = func (string , workqueue.TypedRateLimiter [reconcile.Request ]) workqueue.TypedRateLimitingInterface [reconcile.Request ] {
@@ -555,6 +584,37 @@ var _ = Describe("controller", func() {
555584 Eventually (func () int { return dq .NumRequeues (request ) }).Should (Equal (0 ))
556585 })
557586
587+ It ("should retain the priority with RequeAfter" , func () {
588+ q := & fakePriorityQueue {PriorityQueue : priorityqueue.New [reconcile.Request ]("controller1" )}
589+ ctrl .NewQueue = func (string , workqueue.TypedRateLimiter [reconcile.Request ]) workqueue.TypedRateLimitingInterface [reconcile.Request ] {
590+ return q
591+ }
592+
593+ ctx , cancel := context .WithCancel (context .Background ())
594+ defer cancel ()
595+ go func () {
596+ defer GinkgoRecover ()
597+ Expect (ctrl .Start (ctx )).NotTo (HaveOccurred ())
598+ }()
599+
600+ q .PriorityQueue .AddWithOpts (priorityqueue.AddOpts {Priority : 10 }, request )
601+
602+ By ("Invoking Reconciler which will ask for RequeueAfter" )
603+ fakeReconcile .AddResult (reconcile.Result {RequeueAfter : time .Millisecond * 100 }, nil )
604+ Expect (<- reconciled ).To (Equal (request ))
605+ Eventually (func () []priorityQueueAddition {
606+ q .lock .Lock ()
607+ defer q .lock .Unlock ()
608+ return q .added
609+ }).Should (Equal ([]priorityQueueAddition {{
610+ AddOpts : priorityqueue.AddOpts {
611+ After : time .Millisecond * 100 ,
612+ Priority : 10 ,
613+ },
614+ items : []reconcile.Request {request },
615+ }}))
616+ })
617+
558618 It ("should perform error behavior if error is not nil, regardless of RequeueAfter" , func () {
559619 dq := & DelegatingQueue {TypedRateLimitingInterface : ctrl .NewQueue ("controller1" , nil )}
560620 ctrl .NewQueue = func (string , workqueue.TypedRateLimiter [reconcile.Request ]) workqueue.TypedRateLimitingInterface [reconcile.Request ] {
@@ -586,6 +646,37 @@ var _ = Describe("controller", func() {
586646 Eventually (func () int { return dq .NumRequeues (request ) }).Should (Equal (0 ))
587647 })
588648
649+ It ("should retain the priority when there was an error" , func () {
650+ q := & fakePriorityQueue {PriorityQueue : priorityqueue.New [reconcile.Request ]("controller1" )}
651+ ctrl .NewQueue = func (string , workqueue.TypedRateLimiter [reconcile.Request ]) workqueue.TypedRateLimitingInterface [reconcile.Request ] {
652+ return q
653+ }
654+
655+ ctx , cancel := context .WithCancel (context .Background ())
656+ defer cancel ()
657+ go func () {
658+ defer GinkgoRecover ()
659+ Expect (ctrl .Start (ctx )).NotTo (HaveOccurred ())
660+ }()
661+
662+ q .PriorityQueue .AddWithOpts (priorityqueue.AddOpts {Priority : 10 }, request )
663+
664+ By ("Invoking Reconciler which will return an error" )
665+ fakeReconcile .AddResult (reconcile.Result {}, errors .New ("oups, I did it again" ))
666+ Expect (<- reconciled ).To (Equal (request ))
667+ Eventually (func () []priorityQueueAddition {
668+ q .lock .Lock ()
669+ defer q .lock .Unlock ()
670+ return q .added
671+ }).Should (Equal ([]priorityQueueAddition {{
672+ AddOpts : priorityqueue.AddOpts {
673+ RateLimited : true ,
674+ Priority : 10 ,
675+ },
676+ items : []reconcile.Request {request },
677+ }}))
678+ })
679+
589680 PIt ("should return if the queue is shutdown" , func () {
590681 // TODO(community): write this test
591682 })
@@ -977,3 +1068,21 @@ func (t *bisignallingSource[T]) WaitForSync(ctx context.Context) error {
9771068 return ctx .Err ()
9781069 }
9791070}
1071+
1072+ type priorityQueueAddition struct {
1073+ priorityqueue.AddOpts
1074+ items []reconcile.Request
1075+ }
1076+
1077+ type fakePriorityQueue struct {
1078+ priorityqueue.PriorityQueue [reconcile.Request ]
1079+
1080+ lock sync.Mutex
1081+ added []priorityQueueAddition
1082+ }
1083+
1084+ func (f * fakePriorityQueue ) AddWithOpts (o priorityqueue.AddOpts , items ... reconcile.Request ) {
1085+ f .lock .Lock ()
1086+ defer f .lock .Unlock ()
1087+ f .added = append (f .added , priorityQueueAddition {AddOpts : o , items : items })
1088+ }
0 commit comments