@@ -3,6 +3,7 @@ package priorityqueue
33import (
44 "fmt"
55 "math/rand/v2"
6+ "strconv"
67 "sync"
78 "testing"
89 "testing/synctest"
@@ -103,6 +104,30 @@ var _ = Describe("Controllerworkqueue", func() {
103104 Expect (metrics .adds ["test" ]).To (Equal (1 ))
104105 })
105106
107+ It ("enqueues a locked item" , func () {
108+ q , metrics := newQueue ()
109+ defer q .ShutDown ()
110+
111+ q .AddWithOpts (AddOpts {}, "foo" )
112+ Expect (q .Len ()).To (Equal (1 ))
113+ item , priority , shutdown := q .GetWithPriority ()
114+ Expect (item ).To (Equal ("foo" ))
115+ Expect (priority ).To (Equal (0 ))
116+ Expect (shutdown ).To (BeFalse ())
117+
118+ q .AddWithOpts (AddOpts {}, "foo" )
119+ Expect (q .Len ()).To (Equal (1 ))
120+ q .Done ("foo" )
121+
122+ item , priority , shutdown = q .GetWithPriority ()
123+ Expect (item ).To (Equal ("foo" ))
124+ Expect (priority ).To (Equal (0 ))
125+ Expect (shutdown ).To (BeFalse ())
126+
127+ Expect (metrics .depth ["test" ]).To (Equal (map [int ]int {0 : 0 }))
128+ Expect (metrics .adds ["test" ]).To (Equal (2 ))
129+ })
130+
106131 It ("retains the highest priority" , func () {
107132 q , metrics := newQueue ()
108133 defer q .ShutDown ()
@@ -120,6 +145,23 @@ var _ = Describe("Controllerworkqueue", func() {
120145 Expect (metrics .adds ["test" ]).To (Equal (1 ))
121146 })
122147
148+ It ("will not decrease the priority" , func () {
149+ q , metrics := newQueue ()
150+ defer q .ShutDown ()
151+
152+ q .AddWithOpts (AddOpts {Priority : ptr .To (2 )}, "foo" )
153+ q .AddWithOpts (AddOpts {Priority : ptr .To (1 )}, "foo" )
154+
155+ item , priority , _ := q .GetWithPriority ()
156+ Expect (item ).To (Equal ("foo" ))
157+ Expect (priority ).To (Equal (2 ))
158+
159+ Expect (q .Len ()).To (Equal (0 ))
160+
161+ Expect (metrics .depth ["test" ]).To (Equal (map [int ]int {2 : 0 }))
162+ Expect (metrics .adds ["test" ]).To (Equal (1 ))
163+ })
164+
123165 It ("gets pushed to the front if the priority increases" , func () {
124166 q , metrics := newQueue ()
125167 defer q .ShutDown ()
@@ -251,6 +293,35 @@ var _ = Describe("Controllerworkqueue", func() {
251293 Expect (metrics .depth ["test" ]).To (Equal (map [int ]int {0 : 0 }))
252294 metrics .mu .Unlock ()
253295 })
296+
297+ It ("updates metrics correctly when an item with after is re-added with higher priority and no after" , func () {
298+ q , metrics := newQueue ()
299+ defer q .ShutDown ()
300+
301+ q .AddWithOpts (AddOpts {After : time .Hour , Priority : ptr .To (0 )}, "foo" )
302+ Expect (q .Len ()).To (Equal (0 ))
303+ metrics .mu .Lock ()
304+ Expect (metrics .depth ["test" ]).To (Equal (map [int ]int {}))
305+ metrics .mu .Unlock ()
306+
307+ q .AddWithOpts (AddOpts {Priority : ptr .To (1 )}, "foo" )
308+
309+ Expect (q .Len ()).To (Equal (1 ))
310+ metrics .mu .Lock ()
311+ Expect (metrics .depth ["test" ]).To (Equal (map [int ]int {1 : 1 }))
312+ metrics .mu .Unlock ()
313+
314+ item , priority , _ := q .GetWithPriority ()
315+ Expect (item ).To (Equal ("foo" ))
316+ Expect (priority ).To (Equal (1 ))
317+ Expect (q .Len ()).To (Equal (0 ))
318+
319+ metrics .mu .Lock ()
320+ Expect (metrics .depth ["test" ][1 ]).To (Equal (0 ))
321+ for _ , depth := range metrics .depth ["test" ] {
322+ Expect (depth ).To (Equal (0 ))
323+ }
324+ })
254325})
255326
256327func BenchmarkAddGetDone (b * testing.B ) {
@@ -443,56 +514,69 @@ func newQueueWithTimeForwarder() (_ *priorityqueue[string], _ *fakeMetricsProvid
443514
444515func TestHighPriorityItemsAreReturnedBeforeLowPriorityItemMultipleTimes (t * testing.T ) {
445516 t .Parallel ()
446- synctest .Test (t , func (t * testing.T ) {
447- g := NewWithT (t )
448-
449- q , metrics := newQueue ()
450- defer q .ShutDown ()
451-
452- const itemsPerPriority = 1000
453- lowPriority := 0
454- lowMiddlePriority := 5
455- middlePriority := 10
456- upperMiddlePriority := 15
457- highPriority := 20
458- for i := range itemsPerPriority {
459- q .AddWithOpts (AddOpts {Priority : & highPriority }, fmt .Sprintf ("high-%d" , i ))
460- q .AddWithOpts (AddOpts {Priority : & upperMiddlePriority }, fmt .Sprintf ("upperMiddle-%d" , i ))
461- q .AddWithOpts (AddOpts {Priority : & middlePriority }, fmt .Sprintf ("middle-%d" , i ))
462- q .AddWithOpts (AddOpts {Priority : & lowMiddlePriority }, fmt .Sprintf ("lowMiddle-%d" , i ))
463- q .AddWithOpts (AddOpts {Priority : & lowPriority }, fmt .Sprintf ("low-%d" , i ))
464- }
465- synctest .Wait ()
517+ for _ , after := range []time.Duration {- time .Second , 0 , time .Second } {
518+ t .Run (fmt .Sprintf ("after=%v" , after ), func (t * testing.T ) {
519+ t .Parallel ()
520+ synctest .Test (t , func (t * testing.T ) {
521+ g := NewWithT (t )
522+
523+ q , metrics , forwardQueueTimeBy := newQueueWithTimeForwarder ()
524+ defer q .ShutDown ()
525+
526+ const itemsPerPriority = 1000
527+ lowPriority := - 10
528+ lowMiddlePriority := - 5
529+ middlePriority := 0
530+ upperMiddlePriority := 5
531+ highPriority := 10
532+ for i := range itemsPerPriority {
533+ q .AddWithOpts (AddOpts {Priority : & highPriority , After : after }, fmt .Sprintf ("high-%d" , i ))
534+ q .AddWithOpts (AddOpts {Priority : & upperMiddlePriority , After : after }, fmt .Sprintf ("upperMiddle-%d" , i ))
535+ q .AddWithOpts (AddOpts {Priority : & middlePriority , After : after }, fmt .Sprintf ("middle-%d" , i ))
536+ q .AddWithOpts (AddOpts {Priority : & lowMiddlePriority , After : after }, fmt .Sprintf ("lowMiddle-%d" , i ))
537+ q .AddWithOpts (AddOpts {Priority : & lowPriority , After : after }, fmt .Sprintf ("low-%d" , i ))
538+ }
539+ synctest .Wait ()
540+ if after > 0 {
541+ forwardQueueTimeBy (after )
542+ synctest .Wait ()
543+ }
466544
467- for range itemsPerPriority {
468- key , prio , _ := q .GetWithPriority ()
469- g .Expect (prio ).To (Equal (highPriority ))
470- g .Expect (key ).To (HavePrefix ("high-" ))
471- }
472- for range itemsPerPriority {
473- key , prio , _ := q .GetWithPriority ()
474- g .Expect (prio ).To (Equal (upperMiddlePriority ))
475- g .Expect (key ).To (HavePrefix ("upperMiddle-" ))
476- }
477- for range itemsPerPriority {
478- key , prio , _ := q .GetWithPriority ()
479- g .Expect (prio ).To (Equal (middlePriority ))
480- g .Expect (key ).To (HavePrefix ("middle-" ))
481- }
482- for range itemsPerPriority {
483- key , prio , _ := q .GetWithPriority ()
484- g .Expect (prio ).To (Equal (lowMiddlePriority ))
485- g .Expect (key ).To (HavePrefix ("lowMiddle-" ))
486- }
487- for range itemsPerPriority {
488- key , prio , _ := q .GetWithPriority ()
489- g .Expect (prio ).To (Equal (lowPriority ))
490- g .Expect (key ).To (HavePrefix ("low-" ))
491- }
492- g .Expect (metrics .depth ["test" ]).To (Equal (map [int ]int {10 : 0 , 5 : 0 , 0 : 0 , 20 : 0 , 15 : 0 }))
493- g .Expect (metrics .adds ["test" ]).To (Equal (itemsPerPriority * 5 ))
494- g .Expect (metrics .retries ["test" ]).To (Equal (0 ))
495- })
545+ for i := range itemsPerPriority {
546+ key , prio , _ := q .GetWithPriority ()
547+ g .Expect (prio ).To (Equal (highPriority ))
548+ g .Expect (key ).To (Equal ("high-" + strconv .Itoa (i )))
549+ }
550+ for i := range itemsPerPriority {
551+ key , prio , _ := q .GetWithPriority ()
552+ g .Expect (prio ).To (Equal (upperMiddlePriority ))
553+ g .Expect (key ).To (Equal ("upperMiddle-" + strconv .Itoa (i )))
554+ }
555+ for i := range itemsPerPriority {
556+ key , prio , _ := q .GetWithPriority ()
557+ g .Expect (prio ).To (Equal (middlePriority ))
558+ g .Expect (key ).To (Equal ("middle-" + strconv .Itoa (i )))
559+ }
560+ for i := range itemsPerPriority {
561+ key , prio , _ := q .GetWithPriority ()
562+ g .Expect (prio ).To (Equal (lowMiddlePriority ))
563+ g .Expect (key ).To (Equal ("lowMiddle-" + strconv .Itoa (i )))
564+ }
565+ for i := range itemsPerPriority {
566+ key , prio , _ := q .GetWithPriority ()
567+ g .Expect (prio ).To (Equal (lowPriority ))
568+ g .Expect (key ).To (Equal ("low-" + strconv .Itoa (i )))
569+ }
570+ g .Expect (metrics .depth ["test" ]).To (Equal (map [int ]int {- 10 : 0 , - 5 : 0 , 0 : 0 , 5 : 0 , 10 : 0 }))
571+ g .Expect (metrics .adds ["test" ]).To (Equal (itemsPerPriority * 5 ))
572+ expectedRetries := 0
573+ if after > 0 {
574+ expectedRetries = itemsPerPriority * 5
575+ }
576+ g .Expect (metrics .retries ["test" ]).To (Equal (expectedRetries ))
577+ })
578+ })
579+ }
496580}
497581
498582func newQueue () (* priorityqueue [string ], * fakeMetricsProvider ) {
0 commit comments