@@ -11,6 +11,7 @@ import (
1111 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1212 k8sruntime "k8s.io/apimachinery/pkg/runtime"
1313 "k8s.io/apimachinery/pkg/types"
14+ "k8s.io/utils/ptr"
1415 ctrl "sigs.k8s.io/controller-runtime"
1516 "sigs.k8s.io/controller-runtime/pkg/client"
1617 "sigs.k8s.io/controller-runtime/pkg/client/fake"
@@ -63,8 +64,11 @@ func TestReconcile(t *testing.T) {
6364 testCases := []struct {
6465 name string
6566 promos []client.Object
66- promoteFn func (context.Context , kargoapi.Promotion ,
67- * kargoapi.Freight ) (* kargoapi.PromotionStatus , error )
67+ promoteFn func (
68+ context.Context ,
69+ kargoapi.Promotion ,
70+ * kargoapi.Freight ,
71+ ) (* kargoapi.PromotionStatus , * time.Duration , error )
6872 terminateFn func (context.Context , * kargoapi.Promotion ) error
6973 promoToReconcile * types.NamespacedName // if nil, uses the first of the promos
7074 expectPromoteFnCalled bool
@@ -238,7 +242,11 @@ func TestReconcile(t *testing.T) {
238242 newPromo ("fake-namespace" , "fake-promo" , "fake-stage" , kargoapi .PromotionPhasePending , before ),
239243 },
240244 promoToReconcile : & types.NamespacedName {Namespace : "fake-namespace" , Name : "fake-promo" },
241- promoteFn : func (_ context.Context , _ kargoapi.Promotion , _ * kargoapi.Freight ) (* kargoapi.PromotionStatus , error ) {
245+ promoteFn : func (
246+ context.Context ,
247+ kargoapi.Promotion ,
248+ * kargoapi.Freight ,
249+ ) (* kargoapi.PromotionStatus , * time.Duration , error ) {
242250 panic ("expected panic" )
243251 },
244252 },
@@ -263,8 +271,12 @@ func TestReconcile(t *testing.T) {
263271 newPromo ("fake-namespace" , "fake-promo" , "fake-stage" , kargoapi .PromotionPhasePending , before ),
264272 },
265273 promoToReconcile : & types.NamespacedName {Namespace : "fake-namespace" , Name : "fake-promo" },
266- promoteFn : func (_ context.Context , _ kargoapi.Promotion , _ * kargoapi.Freight ) (* kargoapi.PromotionStatus , error ) {
267- return nil , errors .New ("expected error" )
274+ promoteFn : func (
275+ context.Context ,
276+ kargoapi.Promotion ,
277+ * kargoapi.Freight ,
278+ ) (* kargoapi.PromotionStatus , * time.Duration , error ) {
279+ return nil , nil , errors .New ("expected error" )
268280 },
269281 },
270282 {
@@ -300,12 +312,14 @@ func TestReconcile(t *testing.T) {
300312 p kargoapi.Promotion ,
301313 _ * kargoapi.Stage ,
302314 f * kargoapi.Freight ,
303- ) (* kargoapi.PromotionStatus , error ) {
315+ ) (* kargoapi.PromotionStatus , * time. Duration , error ) {
304316 promoteWasCalled = true
305317 if tc .promoteFn != nil {
306318 return tc .promoteFn (ctx , p , f )
307319 }
308- return & kargoapi.PromotionStatus {Phase : kargoapi .PromotionPhaseSucceeded }, nil
320+ return & kargoapi.PromotionStatus {
321+ Phase : kargoapi .PromotionPhaseSucceeded ,
322+ }, nil , nil
309323 }
310324
311325 terminateWasCalled := false
@@ -620,9 +634,10 @@ func Test_calculateRequeueInterval(t *testing.T) {
620634 require .Greater (t , testTimeout , defaultRequeueInterval )
621635
622636 testCases := []struct {
623- name string
624- promo * kargoapi.Promotion
625- assertions func (* testing.T , time.Duration )
637+ name string
638+ promo * kargoapi.Promotion
639+ suggestedRequeueInterval * time.Duration
640+ assertions func (* testing.T , time.Duration )
626641 }{
627642 {
628643 name : "current step out of bounds" ,
@@ -698,7 +713,62 @@ func Test_calculateRequeueInterval(t *testing.T) {
698713 },
699714 },
700715 {
701- name : "timeout occurs after next interval" ,
716+ name : "timeout would occur after suggested interval elapses" ,
717+ suggestedRequeueInterval : ptr .To (time .Minute ),
718+ promo : & kargoapi.Promotion {
719+ Spec : kargoapi.PromotionSpec {
720+ Steps : []kargoapi.PromotionStep {{
721+ Uses : testStepKindWithTimeout ,
722+ }},
723+ },
724+ Status : kargoapi.PromotionStatus {
725+ CurrentStep : 0 ,
726+ StepExecutionMetadata : []kargoapi.StepExecutionMetadata {{
727+ // If the step started now and times out after an interval greater
728+ // than the default requeue interval, then the wall clock time of
729+ // the timeout will be AFTER the wall clock time of the next
730+ // reconciliation.
731+ StartedAt : & metav1.Time {Time : time .Now ()},
732+ }},
733+ },
734+ },
735+ assertions : func (t * testing.T , requeueInterval time.Duration ) {
736+ // The request should be requeued according to the suggestion.
737+ require .Equal (t , time .Minute , requeueInterval )
738+ // Sanity check that the requeue interval is always greater than 0.
739+ require .Greater (t , requeueInterval , time .Duration (0 ))
740+ },
741+ },
742+ {
743+ name : "timeout would occur before suggested interval elapses" ,
744+ suggestedRequeueInterval : ptr .To (time .Minute ),
745+ promo : & kargoapi.Promotion {
746+ Spec : kargoapi.PromotionSpec {
747+ Steps : []kargoapi.PromotionStep {{
748+ Uses : testStepKindWithTimeout ,
749+ }},
750+ },
751+ Status : kargoapi.PromotionStatus {
752+ CurrentStep : 0 ,
753+ StepExecutionMetadata : []kargoapi.StepExecutionMetadata {{
754+ // If the step has only a minute to go before timeout, then the wall
755+ // clock time of the timeout will be BEFORE the wall clock time of
756+ // the next reconciliation.
757+ StartedAt : & metav1.Time {
758+ Time : metav1 .Now ().Add (- testTimeout ).Add (time .Minute ),
759+ },
760+ }},
761+ },
762+ },
763+ assertions : func (t * testing.T , requeueInterval time.Duration ) {
764+ // The interval to the next reconciliation should be shortened.
765+ require .Less (t , requeueInterval , time .Minute )
766+ // Sanity check that the requeue interval is always greater than 0.
767+ require .Greater (t , requeueInterval , time .Duration (0 ))
768+ },
769+ },
770+ {
771+ name : "timeout would occur after default interval elapses" ,
702772 promo : & kargoapi.Promotion {
703773 Spec : kargoapi.PromotionSpec {
704774 Steps : []kargoapi.PromotionStep {{
@@ -724,7 +794,7 @@ func Test_calculateRequeueInterval(t *testing.T) {
724794 },
725795 },
726796 {
727- name : "timeout occurs before next interval" ,
797+ name : "timeout would occur before next default interval elapses " ,
728798 promo : & kargoapi.Promotion {
729799 Spec : kargoapi.PromotionSpec {
730800 Steps : []kargoapi.PromotionStep {{
@@ -753,7 +823,13 @@ func Test_calculateRequeueInterval(t *testing.T) {
753823 }
754824 for _ , testCase := range testCases {
755825 t .Run (testCase .name , func (t * testing.T ) {
756- testCase .assertions (t , calculateRequeueInterval (testCase .promo ))
826+ testCase .assertions (
827+ t ,
828+ calculateRequeueInterval (
829+ testCase .promo ,
830+ testCase .suggestedRequeueInterval ,
831+ ),
832+ )
757833 })
758834 }
759835}
0 commit comments