Skip to content

Commit 23c0b5a

Browse files
authored
[parallelisation] Added a WaitUntil utility (#628)
<!-- Copyright (C) 2020-2022 Arm Limited or its affiliates and Contributors. All rights reserved. SPDX-License-Identifier: Apache-2.0 --> ### Description Add a utility to wait until a condition is verified ### Test Coverage <!-- Please put an `x` in the correct box e.g. `[x]` to indicate the testing coverage of this change. --> - [x] This change is covered by existing or additional automated tests. - [ ] Manual testing has been performed (and evidence provided) as automated testing was not feasible. - [ ] Additional tests are not required for this change (e.g. documentation update).
1 parent 3aa0686 commit 23c0b5a

File tree

3 files changed

+74
-0
lines changed

3 files changed

+74
-0
lines changed

changes/20250606090227.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
:sparkles: `[parallelisation]` Added a `WaitUntil` utility

utils/parallelisation/parallelisation.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,3 +246,24 @@ func RunActionWithParallelCheck(ctx context.Context, action func(ctx context.Con
246246
}
247247
return err
248248
}
249+
250+
// WaitUntil waits for a condition evaluated by evalCondition to be verified
251+
func WaitUntil(ctx context.Context, evalCondition func(ctx2 context.Context) (bool, error), pauseBetweenEvaluations time.Duration) error {
252+
cancellableCtx, cancel := context.WithCancel(ctx)
253+
defer cancel()
254+
for {
255+
err := DetermineContextError(ctx)
256+
if err != nil {
257+
return err
258+
}
259+
260+
done, err := evalCondition(cancellableCtx)
261+
if err != nil {
262+
return err
263+
}
264+
if done {
265+
return nil
266+
}
267+
SleepWithContext(ctx, pauseBetweenEvaluations)
268+
}
269+
}

utils/parallelisation/parallelisation_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,3 +411,55 @@ func runActionWithParallelCheckFailAtRandom(t *testing.T, ctx context.Context) {
411411
require.Error(t, err)
412412
errortest.AssertError(t, err, commonerrors.ErrCancelled)
413413
}
414+
415+
func TestWaitUntil(t *testing.T) {
416+
verifiedCondition := func(ctx context.Context) (bool, error) {
417+
SleepWithContext(ctx, 50*time.Millisecond)
418+
return true, nil
419+
}
420+
421+
t.Run("cancelled", func(t *testing.T) {
422+
ctx, cancel := context.WithCancel(context.Background())
423+
cancel()
424+
err := WaitUntil(ctx, verifiedCondition, 10*time.Millisecond)
425+
require.Error(t, err)
426+
errortest.AssertError(t, err, commonerrors.ErrCancelled)
427+
})
428+
t.Run("verified", func(t *testing.T) {
429+
ctx, cancel := context.WithCancel(context.Background())
430+
defer cancel()
431+
err := WaitUntil(ctx, verifiedCondition, 10*time.Millisecond)
432+
require.NoError(t, err)
433+
})
434+
t.Run("verified after multiple attempts", func(t *testing.T) {
435+
ctx, cancel := context.WithCancel(context.Background())
436+
defer cancel()
437+
counter := atomic.NewInt32(0)
438+
verifiedConditionAfterAttempts := func(ctx context.Context) (bool, error) {
439+
SleepWithContext(ctx, time.Millisecond)
440+
if counter.Load() > 10 {
441+
return true, nil
442+
}
443+
counter.Inc()
444+
return false, nil
445+
}
446+
err := WaitUntil(ctx, verifiedConditionAfterAttempts, 10*time.Millisecond)
447+
require.NoError(t, err)
448+
})
449+
t.Run("verified with condition evaluation failure", func(t *testing.T) {
450+
ctx, cancel := context.WithCancel(context.Background())
451+
defer cancel()
452+
counter := atomic.NewInt32(0)
453+
verifiedConditionAfterAttempts := func(ctx context.Context) (bool, error) {
454+
SleepWithContext(ctx, time.Millisecond)
455+
if counter.Load() > 10 {
456+
return false, commonerrors.ErrUnexpected
457+
}
458+
counter.Inc()
459+
return false, nil
460+
}
461+
err := WaitUntil(ctx, verifiedConditionAfterAttempts, 10*time.Millisecond)
462+
require.Error(t, err)
463+
errortest.AssertError(t, err, commonerrors.ErrUnexpected)
464+
})
465+
}

0 commit comments

Comments
 (0)