Skip to content

Commit 2804185

Browse files
hiddecokrancour
andauthored
chore(backport release-1.3): fix: soak time bug (#3739)
Co-authored-by: Kent Rancourt <[email protected]>
1 parent 9b41a28 commit 2804185

File tree

5 files changed

+31
-40
lines changed

5 files changed

+31
-40
lines changed

api/v1alpha1/stage_helpers.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ func (s *Stage) ListAvailableFreight(
141141
AvailabilityStrategy: req.Sources.AvailabilityStrategy,
142142
}
143143
if requiredSoak := req.Sources.RequiredSoakTime; requiredSoak != nil {
144-
listOpts.VerifiedBefore = &metav1.Time{Time: time.Now().Add(-requiredSoak.Duration)}
144+
listOpts.RequiredSoakTime = &requiredSoak.Duration
145145
}
146146
}
147147
freightFromWarehouse, err := warehouse.ListFreight(ctx, c, listOpts)

api/v1alpha1/stage_helpers_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ func TestStage_ListAvailableFreight(t *testing.T) {
335335
Status: FreightStatus{
336336
VerifiedIn: map[string]VerifiedStage{
337337
testStage: {
338-
VerifiedAt: &metav1.Time{Time: time.Now()},
338+
LongestCompletedSoak: &metav1.Duration{Duration: 30 * time.Minute},
339339
},
340340
},
341341
},
@@ -349,7 +349,7 @@ func TestStage_ListAvailableFreight(t *testing.T) {
349349
Status: FreightStatus{
350350
VerifiedIn: map[string]VerifiedStage{
351351
testStage: {
352-
VerifiedAt: &metav1.Time{Time: time.Now().Add(-time.Hour * 2)},
352+
LongestCompletedSoak: &metav1.Duration{Duration: 2 * time.Hour},
353353
},
354354
},
355355
},

api/v1alpha1/warehouse_helpers.go

+8-11
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,10 @@ type ListWarehouseFreightOptions struct {
8282
//
8383
// IMPORTANT: This is OR'ed with the ApprovedFor field.
8484
VerifiedIn []string
85-
// VerifiedBefore optionally specifies a time before which a Freight verified
86-
// in any of the Stages named in the VerifiedIn field must have been verified.
87-
// This is useful for filtering out Freight whose soak time has not yet
88-
// elapsed.
89-
VerifiedBefore *metav1.Time
85+
// RequiredSoakTime optionally specifies a minimum duration that a piece of
86+
// Freight must have continuously remained in a Stage at any time after being
87+
// verified.
88+
RequiredSoakTime *time.Duration
9089
// AvailabilityStrategy specifies the semantics for how Freight is determined
9190
// to be available. If not set, the default is to consider Freight available
9291
// if it has been verified in any of the provided VerifiedIn stages.
@@ -193,7 +192,7 @@ func (w *Warehouse) ListFreight(
193192
return lhs.Name == rhs.Name
194193
})
195194

196-
if len(opts.VerifiedIn) == 0 || opts.VerifiedBefore == nil {
195+
if len(opts.VerifiedIn) == 0 || opts.RequiredSoakTime == nil {
197196
// Nothing left to do
198197
return freight, nil
199198
}
@@ -211,11 +210,9 @@ func (w *Warehouse) ListFreight(
211210
// Track set of Stages that have passed the verification soak time
212211
// for the Freight.
213212
verifiedStages := sets.New[string]()
214-
for stage, ver := range f.Status.VerifiedIn {
215-
if verifiedAt := ver.VerifiedAt; verifiedAt != nil {
216-
if verifiedAt.Time.Before(opts.VerifiedBefore.Time) {
217-
verifiedStages.Insert(stage)
218-
}
213+
for stage := range f.Status.VerifiedIn {
214+
if f.GetLongestSoak(stage) >= *opts.RequiredSoakTime {
215+
verifiedStages.Insert(stage)
219216
}
220217
}
221218

api/v1alpha1/warehouse_helpers_test.go

+17-22
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,11 @@ func TestWarehouse_ListFreight(t *testing.T) {
172172
},
173173
},
174174
{
175-
name: "success with VerifiedIn and VerifiedBefore options",
175+
name: "success with VerifiedIn and RequiredSoakTime options",
176176
opts: &ListWarehouseFreightOptions{
177-
ApprovedFor: testStage,
178-
VerifiedIn: []string{testUpstreamStage},
179-
VerifiedBefore: &metav1.Time{Time: time.Now().Add(-1 * time.Hour)},
180-
},
177+
ApprovedFor: testStage,
178+
VerifiedIn: []string{testUpstreamStage},
179+
RequiredSoakTime: ptr.To(time.Hour)},
181180
objects: []client.Object{
182181
&Freight{ // This should not be returned
183182
ObjectMeta: metav1.ObjectMeta{
@@ -194,7 +193,9 @@ func TestWarehouse_ListFreight(t *testing.T) {
194193
ApprovedFor: map[string]ApprovedStage{testStage: {}},
195194
// Doesn't matter that it's verified upstream, because this is the
196195
// wrong warehouse
197-
VerifiedIn: map[string]VerifiedStage{testUpstreamStage: {}},
196+
VerifiedIn: map[string]VerifiedStage{testUpstreamStage: {
197+
LongestCompletedSoak: &metav1.Duration{Duration: 2 * time.Hour},
198+
}},
198199
},
199200
},
200201
&Freight{ // This should not be returned
@@ -236,7 +237,7 @@ func TestWarehouse_ListFreight(t *testing.T) {
236237
// yet elapsed
237238
VerifiedIn: map[string]VerifiedStage{
238239
testUpstreamStage: {
239-
VerifiedAt: ptr.To(metav1.Now()),
240+
LongestCompletedSoak: &metav1.Duration{Duration: 30 * time.Minute},
240241
},
241242
},
242243
},
@@ -255,7 +256,7 @@ func TestWarehouse_ListFreight(t *testing.T) {
255256
// elapsed
256257
VerifiedIn: map[string]VerifiedStage{
257258
testUpstreamStage: {
258-
VerifiedAt: ptr.To(metav1.NewTime(time.Now().Add(-2 * time.Hour))),
259+
LongestCompletedSoak: &metav1.Duration{Duration: 2 * time.Hour},
259260
},
260261
},
261262
},
@@ -276,7 +277,7 @@ func TestWarehouse_ListFreight(t *testing.T) {
276277
AvailabilityStrategy: FreightAvailabilityStrategyAll,
277278
ApprovedFor: testStage,
278279
VerifiedIn: []string{testUpstreamStage, testUpstreamStage2},
279-
VerifiedBefore: &metav1.Time{Time: time.Now().Add(-1 * time.Hour)},
280+
RequiredSoakTime: ptr.To(time.Hour),
280281
},
281282
objects: []client.Object{
282283
&Freight{ // This should be returned as its approved for the Stage
@@ -292,11 +293,7 @@ func TestWarehouse_ListFreight(t *testing.T) {
292293
// This is approved for the Stage
293294
ApprovedFor: map[string]ApprovedStage{testStage: {}},
294295
// This is only verified in a single upstream Stage
295-
VerifiedIn: map[string]VerifiedStage{
296-
testUpstreamStage: {
297-
VerifiedAt: ptr.To(metav1.Now()),
298-
},
299-
},
296+
VerifiedIn: map[string]VerifiedStage{},
300297
},
301298
},
302299
&Freight{ // This should be returned because its verified in both upstream Stages and soak time has lapsed
@@ -314,10 +311,10 @@ func TestWarehouse_ListFreight(t *testing.T) {
314311
// This is verified in all of the upstream Stages and the soak time has lapsed
315312
VerifiedIn: map[string]VerifiedStage{
316313
testUpstreamStage: {
317-
VerifiedAt: ptr.To(metav1.NewTime(time.Now().Add(-2 * time.Hour))),
314+
LongestCompletedSoak: &metav1.Duration{Duration: 2 * time.Hour},
318315
},
319316
testUpstreamStage2: {
320-
VerifiedAt: ptr.To(metav1.NewTime(time.Now().Add(-2 * time.Hour))),
317+
LongestCompletedSoak: &metav1.Duration{Duration: 2 * time.Hour},
321318
},
322319
},
323320
},
@@ -336,9 +333,7 @@ func TestWarehouse_ListFreight(t *testing.T) {
336333
ApprovedFor: map[string]ApprovedStage{},
337334
// This is not verified in all of the upstream Stages
338335
VerifiedIn: map[string]VerifiedStage{
339-
testUpstreamStage: {
340-
VerifiedAt: ptr.To(metav1.Now()),
341-
},
336+
testUpstreamStage: {},
342337
},
343338
},
344339
},
@@ -357,10 +352,10 @@ func TestWarehouse_ListFreight(t *testing.T) {
357352
// This is verified in all of the upstream Stages but only passed the soak time of one
358353
VerifiedIn: map[string]VerifiedStage{
359354
testUpstreamStage: {
360-
VerifiedAt: ptr.To(metav1.NewTime(time.Now().Add(-2 * time.Hour))),
355+
LongestCompletedSoak: &metav1.Duration{Duration: 2 * time.Hour},
361356
},
362357
testUpstreamStage2: {
363-
VerifiedAt: ptr.To(metav1.Now()),
358+
LongestCompletedSoak: &metav1.Duration{Duration: 30 * time.Minute},
364359
},
365360
},
366361
},
@@ -381,7 +376,7 @@ func TestWarehouse_ListFreight(t *testing.T) {
381376
AvailabilityStrategy: "Invalid",
382377
ApprovedFor: testStage,
383378
VerifiedIn: []string{testUpstreamStage, testUpstreamStage2},
384-
VerifiedBefore: &metav1.Time{Time: time.Now().Add(-1 * time.Hour)},
379+
RequiredSoakTime: ptr.To(time.Hour),
385380
},
386381
assertions: func(t *testing.T, _ []Freight, err error) {
387382
require.ErrorContains(t, err, "unsupported AvailabilityStrategy")

internal/controller/stages/regular_stages_test.go

+3-4
Original file line numberDiff line numberDiff line change
@@ -4809,7 +4809,7 @@ func TestRegularStageReconciler_autoPromoteFreight(t *testing.T) {
48094809
},
48104810
},
48114811
{
4812-
name: "handles verified freight from upstream stages with verification duration requirement",
4812+
name: "handles verified freight from upstream stages with soak time requirement",
48134813
stage: &kargoapi.Stage{
48144814
ObjectMeta: metav1.ObjectMeta{
48154815
Namespace: "fake-project",
@@ -4889,9 +4889,8 @@ func TestRegularStageReconciler_autoPromoteFreight(t *testing.T) {
48894889
Status: kargoapi.FreightStatus{
48904890
VerifiedIn: map[string]kargoapi.VerifiedStage{
48914891
"upstream-stage": {
4892-
// Should be selected because it was verified
4893-
// after the required duration.
4894-
VerifiedAt: &metav1.Time{Time: now.Add(-2 * time.Hour)},
4892+
// Should be selected because the soak time has elapsed
4893+
LongestCompletedSoak: &metav1.Duration{Duration: 2 * time.Hour},
48954894
},
48964895
},
48974896
},

0 commit comments

Comments
 (0)