diff --git a/src/core/Akka.Tests/Pattern/CircuitBreakerSpec.cs b/src/core/Akka.Tests/Pattern/CircuitBreakerSpec.cs index 7a3d51eba57..57dcc43d7da 100644 --- a/src/core/Akka.Tests/Pattern/CircuitBreakerSpec.cs +++ b/src/core/Akka.Tests/Pattern/CircuitBreakerSpec.cs @@ -6,6 +6,7 @@ //----------------------------------------------------------------------- using System; +using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Runtime.ExceptionServices; @@ -85,11 +86,11 @@ public async Task Must_increment_failure_count_on_callTimeout_before_call_finish var breaker = ShortCallTimeoutCb(); #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed // meant to run as detached task - Task.Run(() => breaker.Instance.WithSyncCircuitBreaker(() => Thread.Sleep(Dilated(TimeSpan.FromSeconds(1))))); + var t = Task.Run(() => breaker.Instance.WithSyncCircuitBreaker(() => Thread.Sleep(Dilated(TimeSpan.FromSeconds(1))))); + await AwaitConditionAsync(() => t.Status >= TaskStatus.Running); // need to kick off the task before we can check the latch #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed var epsilon = TimeSpan.FromMilliseconds(500); // need to pad timeouts due to non-determinism of OS scheduler - await WithinAsync(TimeSpan.FromMilliseconds(900) + epsilon, - () => AwaitConditionAsync(() => breaker.Instance.CurrentFailureCount == 1, Dilated(TimeSpan.FromMilliseconds(100)), TimeSpan.FromMilliseconds(100))); + await AwaitConditionAsync(() => breaker.Instance.CurrentFailureCount == 1, TimeSpan.FromMilliseconds(900) + epsilon, TimeSpan.FromMilliseconds(100)); } } @@ -226,10 +227,10 @@ public void Must_increment_failure_count_on_async_failure() public async Task Must_reset_failure_count_after_success() { var breaker = MultiFailureCb(); - _ = breaker.Instance.WithCircuitBreaker(() => Task.Run(SayHi)); - Enumerable.Range(1, 4).ForEach(_ => breaker.Instance.WithCircuitBreaker(() => Task.Run(ThrowException))); + await WaitForTaskToBeScheduled(breaker.Instance.WithCircuitBreaker(() => Task.Run(SayHi))); + await WaitForTaskToBeScheduled(Enumerable.Range(1, 4).Select(_ => breaker.Instance.WithCircuitBreaker(() => Task.Run(ThrowException))).ToList()); await AwaitAssertAsync(() => breaker.Instance.CurrentFailureCount.ShouldBe(4), AwaitTimeout); - _ = breaker.Instance.WithCircuitBreaker(() => Task.Run(SayHi)); + await WaitForTaskToBeScheduled(breaker.Instance.WithCircuitBreaker(() => Task.Run(SayHi))); await AwaitAssertAsync(() => breaker.Instance.CurrentFailureCount.ShouldBe(0), AwaitTimeout); } @@ -354,6 +355,16 @@ public class CircuitBreakerSpecBase : AkkaSpec public bool CheckLatch(CountdownEvent latch) => latch.Wait(AwaitTimeout); + public Task WaitForTaskToBeScheduled(Task childTask) + { + return AwaitConditionAsync(() => childTask.Status >= TaskStatus.Running); + } + + public Task WaitForTaskToBeScheduled(IReadOnlyCollection childTasks) + { + return AwaitConditionAsync(() => childTasks.All(t => t.Status >= TaskStatus.Running)); + } + [DebuggerStepThrough] public static void ThrowException() => throw new TestException("Test Exception");