diff --git a/src/Polly.Specs/Bulkhead/BulkheadAsyncSpecs.cs b/src/Polly.Specs/Bulkhead/BulkheadAsyncSpecs.cs index da37e103487..e25222f4a9e 100644 --- a/src/Polly.Specs/Bulkhead/BulkheadAsyncSpecs.cs +++ b/src/Polly.Specs/Bulkhead/BulkheadAsyncSpecs.cs @@ -52,7 +52,7 @@ public void Should_throw_when_onBulkheadRejected_is_null() #region onBulkheadRejected delegate [Fact] - public void Should_call_onBulkheadRejected_with_passed_context() + public async Task Should_call_onBulkheadRejected_with_passed_context() { string operationKey = "SomeKey"; Context contextPassedToExecute = new Context(operationKey); @@ -65,11 +65,11 @@ public void Should_call_onBulkheadRejected_with_passed_context() TaskCompletionSource tcs = new TaskCompletionSource(); using (CancellationTokenSource cancellationSource = new CancellationTokenSource()) { - Task.Run(() => { bulkhead.ExecuteAsync(async () => { await tcs.Task; }); }); + _ = Task.Run(() => { bulkhead.ExecuteAsync(async () => { await tcs.Task; }); }); Within(CohesionTimeLimit, () => Expect(0, () => bulkhead.BulkheadAvailableCount, nameof(bulkhead.BulkheadAvailableCount))); - bulkhead.Awaiting(b => b.ExecuteAsync(_ => TaskHelper.EmptyTask, contextPassedToExecute)).Should().Throw(); + await bulkhead.Awaiting(b => b.ExecuteAsync(_ => TaskHelper.EmptyTask, contextPassedToExecute)).Should().ThrowAsync(); cancellationSource.Cancel(); tcs.SetCanceled(); diff --git a/src/Polly.Specs/Bulkhead/BulkheadTResultAsyncSpecs.cs b/src/Polly.Specs/Bulkhead/BulkheadTResultAsyncSpecs.cs index 3bf4862a945..f5ca561eaab 100644 --- a/src/Polly.Specs/Bulkhead/BulkheadTResultAsyncSpecs.cs +++ b/src/Polly.Specs/Bulkhead/BulkheadTResultAsyncSpecs.cs @@ -53,7 +53,7 @@ public void Should_throw_when_onBulkheadRejected_is_null() #region onBulkheadRejected delegate [Fact] - public void Should_call_onBulkheadRejected_with_passed_context() + public async Task Should_call_onBulkheadRejected_with_passed_context() { string operationKey = "SomeKey"; Context contextPassedToExecute = new Context(operationKey); @@ -66,7 +66,7 @@ public void Should_call_onBulkheadRejected_with_passed_context() TaskCompletionSource tcs = new TaskCompletionSource(); using (CancellationTokenSource cancellationSource = new CancellationTokenSource()) { - Task.Run(() => { + _ = Task.Run(() => { bulkhead.ExecuteAsync(async () => { await tcs.Task; @@ -76,7 +76,7 @@ public void Should_call_onBulkheadRejected_with_passed_context() Within(CohesionTimeLimit, () => Expect(0, () => bulkhead.BulkheadAvailableCount, nameof(bulkhead.BulkheadAvailableCount))); - bulkhead.Awaiting(b => b.ExecuteAsync(_ => Task.FromResult(1), contextPassedToExecute)).Should().Throw(); + await bulkhead.Awaiting(b => b.ExecuteAsync(_ => Task.FromResult(1), contextPassedToExecute)).Should().ThrowAsync(); cancellationSource.Cancel(); tcs.SetCanceled(); diff --git a/src/Polly.Specs/Caching/CacheAsyncSpecs.cs b/src/Polly.Specs/Caching/CacheAsyncSpecs.cs index fd8884db1e1..83fdb8091a1 100644 --- a/src/Polly.Specs/Caching/CacheAsyncSpecs.cs +++ b/src/Polly.Specs/Caching/CacheAsyncSpecs.cs @@ -475,8 +475,8 @@ public async Task Should_honour_cancellation_even_if_prior_execution_has_cached( tokenSource.Cancel(); - cache.Awaiting(policy => policy.ExecuteAsync(func, new Context(operationKey), tokenSource.Token)) - .Should().Throw(); + await cache.Awaiting(policy => policy.ExecuteAsync(func, new Context(operationKey), tokenSource.Token)) + .Should().ThrowAsync(); delegateInvocations.Should().Be(1); } @@ -499,8 +499,8 @@ public async Task Should_honour_cancellation_during_delegate_execution_and_not_p return valueToReturn; }; - cache.Awaiting(policy => policy.ExecuteAsync(func, new Context(operationKey), tokenSource.Token)) - .Should().Throw(); + await cache.Awaiting(policy => policy.ExecuteAsync(func, new Context(operationKey), tokenSource.Token)) + .Should().ThrowAsync(); (bool cacheHit, object fromCache) = await stubCacheProvider.TryGetAsync(operationKey, CancellationToken.None, false); cacheHit.Should().BeFalse(); diff --git a/src/Polly.Specs/Caching/CacheTResultAsyncSpecs.cs b/src/Polly.Specs/Caching/CacheTResultAsyncSpecs.cs index e58fb6fe45b..d7f038e65c4 100644 --- a/src/Polly.Specs/Caching/CacheTResultAsyncSpecs.cs +++ b/src/Polly.Specs/Caching/CacheTResultAsyncSpecs.cs @@ -459,8 +459,8 @@ public async Task Should_honour_cancellation_even_if_prior_execution_has_cached( tokenSource.Cancel(); - cache.Awaiting(policy => policy.ExecuteAsync(func, new Context(operationKey), tokenSource.Token)) - .Should().Throw(); + await cache.Awaiting(policy => policy.ExecuteAsync(func, new Context(operationKey), tokenSource.Token)) + .Should().ThrowAsync(); delegateInvocations.Should().Be(1); } @@ -483,8 +483,8 @@ public async Task Should_honour_cancellation_during_delegate_execution_and_not_p return valueToReturn; }; - cache.Awaiting(policy => policy.ExecuteAsync(func, new Context(operationKey), tokenSource.Token)) - .Should().Throw(); + await cache.Awaiting(policy => policy.ExecuteAsync(func, new Context(operationKey), tokenSource.Token)) + .Should().ThrowAsync(); (bool cacheHit, object fromCache) = await stubCacheProvider.TryGetAsync(operationKey, CancellationToken.None, false); cacheHit.Should().BeFalse(); diff --git a/src/Polly.Specs/Caching/RelativeTtlSpecs.cs b/src/Polly.Specs/Caching/RelativeTtlSpecs.cs index c2f4731ff75..b3edd1da1c4 100644 --- a/src/Polly.Specs/Caching/RelativeTtlSpecs.cs +++ b/src/Polly.Specs/Caching/RelativeTtlSpecs.cs @@ -40,7 +40,7 @@ public void Should_return_configured_timespan() RelativeTtl ttlStrategy = new RelativeTtl(ttl); Ttl retrieved = ttlStrategy.GetTtl(new Context("someOperationKey"), null); - retrieved.Timespan.Should().BeCloseTo(ttl); + retrieved.Timespan.Should().BeCloseTo(ttl, TimeSpan.Zero); retrieved.SlidingExpiration.Should().BeFalse(); } @@ -56,7 +56,7 @@ public void Should_return_configured_timespan_from_time_requested() SystemClock.DateTimeOffsetUtcNow = () => fixedTime.Add(delay); Ttl retrieved = ttlStrategy.GetTtl(new Context("someOperationKey"), null); - retrieved.Timespan.Should().BeCloseTo(ttl); + retrieved.Timespan.Should().BeCloseTo(ttl, TimeSpan.Zero); retrieved.SlidingExpiration.Should().BeFalse(); } } diff --git a/src/Polly.Specs/CircuitBreaker/AdvancedCircuitBreakerAsyncSpecs.cs b/src/Polly.Specs/CircuitBreaker/AdvancedCircuitBreakerAsyncSpecs.cs index f1817c01715..7bef1149303 100644 --- a/src/Polly.Specs/CircuitBreaker/AdvancedCircuitBreakerAsyncSpecs.cs +++ b/src/Polly.Specs/CircuitBreaker/AdvancedCircuitBreakerAsyncSpecs.cs @@ -19,14 +19,14 @@ public class AdvancedCircuitBreakerAsyncSpecs : IDisposable #region Configuration tests [Fact] - public void Should_be_able_to_handle_a_duration_of_timespan_maxvalue() + public async Task Should_be_able_to_handle_a_duration_of_timespan_maxvalue() { var breaker = Policy .Handle() .AdvancedCircuitBreakerAsync(0.5, TimeSpan.FromSeconds(10), 4, TimeSpan.MaxValue); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } [Fact] @@ -170,7 +170,7 @@ public void Should_initialise_to_closed_state() // These provide easy values for testing for failure and throughput thresholds each being met and non-met, in combination. [Fact] - public void Should_not_open_circuit_if_failure_threshold_and_minimum_threshold_is_equalled_but_last_call_is_success() + public async Task Should_not_open_circuit_if_failure_threshold_and_minimum_threshold_is_equalled_but_last_call_is_success() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -185,28 +185,28 @@ public void Should_not_open_circuit_if_failure_threshold_and_minimum_threshold_i ); // Three of three actions in this test throw handled failures. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // Failure threshold exceeded, but throughput threshold not yet. // Throughput threshold will be exceeded by the below successful call, but we never break on a successful call; hence don't break on this. - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // No adjustment to SystemClock.UtcNow, so all exceptions were raised within same timeslice } [Fact] - public void Should_not_open_circuit_if_exceptions_raised_are_not_one_of_the_specified_exceptions() + public async Task Should_not_open_circuit_if_exceptions_raised_are_not_one_of_the_specified_exceptions() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -222,20 +222,20 @@ public void Should_not_open_circuit_if_exceptions_raised_are_not_one_of_the_spec ); // Four of four actions in this test throw unhandled failures. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); } @@ -250,7 +250,7 @@ public void Should_not_open_circuit_if_exceptions_raised_are_not_one_of_the_spec // These provide easy values for testing for failure and throughput thresholds each being met and non-met, in combination. [Fact] - public void Should_open_circuit_blocking_executions_and_noting_the_last_raised_exception_if_failure_threshold_exceeded_and_throughput_threshold_equalled_within_timeslice_in_same_window() + public async Task Should_open_circuit_blocking_executions_and_noting_the_last_raised_exception_if_failure_threshold_exceeded_and_throughput_threshold_equalled_within_timeslice_in_same_window() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -265,36 +265,36 @@ public void Should_open_circuit_blocking_executions_and_noting_the_last_raised_e ); // Four of four actions in this test throw handled failures. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // No adjustment to SystemClock.UtcNow, so all exceptions raised within same timeslice - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); bool delegateExecutedWhenBroken = false; - breaker.Awaiting(x => x.ExecuteAsync(() => { delegateExecutedWhenBroken = true; return TaskHelper.EmptyTask; })) - .Should().Throw() - .WithMessage("The circuit is now open and is not allowing calls.") - .WithInnerException(); + var ex = await breaker.Awaiting(x => x.ExecuteAsync(() => { delegateExecutedWhenBroken = true; return TaskHelper.EmptyTask; })) + .Should().ThrowAsync() + .WithMessage("The circuit is now open and is not allowing calls."); + ex.WithInnerException(); breaker.CircuitState.Should().Be(CircuitState.Open); delegateExecutedWhenBroken.Should().BeFalse(); } [Fact] - public void Should_open_circuit_with_the_last_raised_exception_if_failure_threshold_exceeded_and_throughput_threshold_equalled_within_timeslice_in_different_windows() + public async Task Should_open_circuit_with_the_last_raised_exception_if_failure_threshold_exceeded_and_throughput_threshold_equalled_within_timeslice_in_different_windows() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -311,16 +311,16 @@ public void Should_open_circuit_with_the_last_raised_exception_if_failure_thresh ); // Four of four actions in this test throw handled failures. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // Placing the rest of the invocations ('samplingDuration' / 2) + 1 seconds later @@ -328,20 +328,20 @@ public void Should_open_circuit_with_the_last_raised_exception_if_failure_thresh // They are still placed within same timeslice. SystemClock.UtcNow = () => time.AddSeconds(samplingDuration.Seconds / 2d + 1); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw() - .WithMessage("The circuit is now open and is not allowing calls.") - .WithInnerException(); + var ex = await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync() + .WithMessage("The circuit is now open and is not allowing calls."); + ex.WithInnerException(); breaker.CircuitState.Should().Be(CircuitState.Open); } [Fact] - public void Should_open_circuit_with_the_last_raised_exception_if_failure_threshold_exceeded_though_not_all_are_failures_and_throughput_threshold_equalled_within_timeslice_in_same_window() + public async Task Should_open_circuit_with_the_last_raised_exception_if_failure_threshold_exceeded_though_not_all_are_failures_and_throughput_threshold_equalled_within_timeslice_in_same_window() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -356,33 +356,33 @@ public void Should_open_circuit_with_the_last_raised_exception_if_failure_thresh ); // Three of four actions in this test throw handled failures. - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); // No adjustment to SystemClock.UtcNow, so all exceptions were raised within same timeslice - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw() - .WithMessage("The circuit is now open and is not allowing calls.") - .WithInnerException(); + var ex = await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync() + .WithMessage("The circuit is now open and is not allowing calls."); + ex.WithInnerException(); breaker.CircuitState.Should().Be(CircuitState.Open); } [Fact] - public void Should_open_circuit_with_the_last_raised_exception_if_failure_threshold_exceeded_though_not_all_are_failures_and_throughput_threshold_equalled_within_timeslice_in_different_windows() + public async Task Should_open_circuit_with_the_last_raised_exception_if_failure_threshold_exceeded_though_not_all_are_failures_and_throughput_threshold_equalled_within_timeslice_in_different_windows() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -399,20 +399,20 @@ public void Should_open_circuit_with_the_last_raised_exception_if_failure_thresh ); // Three of four actions in this test throw handled failures. - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); // Placing the rest of the invocations ('samplingDuration' / 2) + 1 seconds later @@ -420,16 +420,16 @@ public void Should_open_circuit_with_the_last_raised_exception_if_failure_thresh // They are still placed within same timeslice SystemClock.UtcNow = () => time.AddSeconds(samplingDuration.Seconds / 2d + 1); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw() - .WithMessage("The circuit is now open and is not allowing calls.") - .WithInnerException(); + var ex = await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync() + .WithMessage("The circuit is now open and is not allowing calls."); + ex.WithInnerException(); breaker.CircuitState.Should().Be(CircuitState.Open); } [Fact] - public void Should_open_circuit_with_the_last_raised_exception_if_failure_threshold_equalled_and_throughput_threshold_equalled_within_timeslice_in_same_window() + public async Task Should_open_circuit_with_the_last_raised_exception_if_failure_threshold_equalled_and_throughput_threshold_equalled_within_timeslice_in_same_window() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -444,33 +444,33 @@ public void Should_open_circuit_with_the_last_raised_exception_if_failure_thresh ); // Two of four actions in this test throw handled failures. - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); // No adjustment to SystemClock.UtcNow, so all exceptions were raised within same timeslice - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw() - .WithMessage("The circuit is now open and is not allowing calls.") - .WithInnerException(); + var ex = await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync() + .WithMessage("The circuit is now open and is not allowing calls."); + ex.WithInnerException(); breaker.CircuitState.Should().Be(CircuitState.Open); } [Fact] - public void Should_open_circuit_with_the_last_raised_exception_if_failure_threshold_equalled_and_throughput_threshold_equalled_within_timeslice_in_different_windows() + public async Task Should_open_circuit_with_the_last_raised_exception_if_failure_threshold_equalled_and_throughput_threshold_equalled_within_timeslice_in_different_windows() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -487,20 +487,20 @@ public void Should_open_circuit_with_the_last_raised_exception_if_failure_thresh ); // Two of four actions in this test throw handled failures. - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); // Placing the rest of the invocations ('samplingDuration' / 2) + 1 seconds later @@ -508,16 +508,16 @@ public void Should_open_circuit_with_the_last_raised_exception_if_failure_thresh // They are still placed within same timeslice SystemClock.UtcNow = () => time.AddSeconds(samplingDuration.Seconds / 2d + 1); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw() - .WithMessage("The circuit is now open and is not allowing calls.") - .WithInnerException(); + var ex = await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync() + .WithMessage("The circuit is now open and is not allowing calls."); + ex.WithInnerException(); breaker.CircuitState.Should().Be(CircuitState.Open); } [Fact] - public void Should_not_open_circuit_if_failure_threshold_exceeded_but_throughput_threshold_not_met_before_timeslice_expires() + public async Task Should_not_open_circuit_if_failure_threshold_exceeded_but_throughput_threshold_not_met_before_timeslice_expires() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -534,29 +534,29 @@ public void Should_not_open_circuit_if_failure_threshold_exceeded_but_throughput ); // Four of four actions in this test throw handled failures; but only the first three within the timeslice. - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // Adjust SystemClock so that timeslice (clearly) expires; fourth exception thrown in next-recorded timeslice. SystemClock.UtcNow = () => time.Add(samplingDuration).Add(samplingDuration); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); } [Fact] - public void Should_not_open_circuit_if_failure_threshold_exceeded_but_throughput_threshold_not_met_before_timeslice_expires_even_if_timeslice_expires_only_exactly() + public async Task Should_not_open_circuit_if_failure_threshold_exceeded_but_throughput_threshold_not_met_before_timeslice_expires_even_if_timeslice_expires_only_exactly() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -573,29 +573,29 @@ public void Should_not_open_circuit_if_failure_threshold_exceeded_but_throughput ); // Four of four actions in this test throw handled failures; but only the first three within the timeslice. - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // Adjust SystemClock so that timeslice (just) expires; fourth exception thrown in following timeslice. SystemClock.UtcNow = () => time.Add(samplingDuration); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); } [Fact] - public void Should_not_open_circuit_if_failure_threshold_exceeded_but_throughput_threshold_not_met_before_timeslice_expires_even_if_error_occurring_just_at_the_end_of_the_duration() + public async Task Should_not_open_circuit_if_failure_threshold_exceeded_but_throughput_threshold_not_met_before_timeslice_expires_even_if_error_occurring_just_at_the_end_of_the_duration() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -614,32 +614,32 @@ public void Should_not_open_circuit_if_failure_threshold_exceeded_but_throughput // Four of four actions in this test throw handled failures; but only the first three within the original timeslice. // Two actions at the start of the original timeslice. - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // Creates a new window right at the end of the original timeslice. SystemClock.UtcNow = () => time.AddTicks(samplingDuration.Ticks - 1); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // Adjust SystemClock so that timeslice (just) expires; fourth exception thrown in following timeslice. If timeslice/window rollover is precisely defined, this should cause first two actions to be forgotten from statistics (rolled out of the window of relevance), and thus the circuit not to break. SystemClock.UtcNow = () => time.Add(samplingDuration); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); } [Fact] - public void Should_open_circuit_with_the_last_raised_exception_if_failure_threshold_equalled_and_throughput_threshold_equalled_even_if_only_just_within_timeslice() + public async Task Should_open_circuit_with_the_last_raised_exception_if_failure_threshold_equalled_and_throughput_threshold_equalled_even_if_only_just_within_timeslice() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -656,35 +656,35 @@ public void Should_open_circuit_with_the_last_raised_exception_if_failure_thresh ); // Four of four actions in this test throw handled failures. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // Adjust SystemClock so that timeslice doesn't quite expire; fourth exception thrown in same timeslice. SystemClock.UtcNow = () => time.AddTicks(samplingDuration.Ticks - 1); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw() - .WithMessage("The circuit is now open and is not allowing calls.") - .WithInnerException(); + var ex = await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync() + .WithMessage("The circuit is now open and is not allowing calls."); + ex.WithInnerException(); breaker.CircuitState.Should().Be(CircuitState.Open); } [Fact] - public void Should_not_open_circuit_if_failure_threshold_not_met_and_throughput_threshold_not_met() + public async Task Should_not_open_circuit_if_failure_threshold_not_met_and_throughput_threshold_not_met() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -699,22 +699,22 @@ public void Should_not_open_circuit_if_failure_threshold_not_met_and_throughput_ ); // One of three actions in this test throw handled failures. - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // No adjustment to SystemClock.UtcNow, so all exceptions were raised within same timeslice } [Fact] - public void Should_not_open_circuit_if_failure_threshold_not_met_but_throughput_threshold_met_before_timeslice_expires() + public async Task Should_not_open_circuit_if_failure_threshold_not_met_but_throughput_threshold_met_before_timeslice_expires() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -729,26 +729,26 @@ public void Should_not_open_circuit_if_failure_threshold_not_met_but_throughput_ ); // One of four actions in this test throw handled failures. - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // No adjustment to SystemClock.UtcNow, so all exceptions were raised within same timeslice } [Fact] - public void Should_open_circuit_if_failures_at_end_of_last_timeslice_below_failure_threshold_and_failures_in_beginning_of_new_timeslice_where_total_equals_failure_threshold() + public async Task Should_open_circuit_if_failures_at_end_of_last_timeslice_below_failure_threshold_and_failures_in_beginning_of_new_timeslice_where_total_equals_failure_threshold() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -766,8 +766,8 @@ public void Should_open_circuit_if_failures_at_end_of_last_timeslice_below_failu // Executing a single invocation to ensure timeslice is created // This invocation is not be counted against the threshold - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // The time is set to just at the end of the sampling duration ensuring @@ -775,16 +775,16 @@ public void Should_open_circuit_if_failures_at_end_of_last_timeslice_below_failu SystemClock.UtcNow = () => time.AddTicks(samplingDuration.Ticks - 1); // Three of four actions in this test occur within the first timeslice. - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // Setting the time to just barely into the new timeslice @@ -793,13 +793,13 @@ public void Should_open_circuit_if_failures_at_end_of_last_timeslice_below_failu // This failure opens the circuit, because it is the second failure of four calls // equalling the failure threshold. The minimum threshold within the defined // sampling duration is met, when using rolling windows. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); } [Fact] - public void Should_not_open_circuit_if_failures_at_end_of_last_timeslice_and_failures_in_beginning_of_new_timeslice_when_below_minimum_throughput_threshold() + public async Task Should_not_open_circuit_if_failures_at_end_of_last_timeslice_and_failures_in_beginning_of_new_timeslice_when_below_minimum_throughput_threshold() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -817,8 +817,8 @@ public void Should_not_open_circuit_if_failures_at_end_of_last_timeslice_and_fai // Executing a single invocation to ensure timeslice is created // This invocation is not be counted against the threshold - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // The time is set to just at the end of the sampling duration ensuring @@ -826,12 +826,12 @@ public void Should_not_open_circuit_if_failures_at_end_of_last_timeslice_and_fai SystemClock.UtcNow = () => time.AddTicks(samplingDuration.Ticks - 1); // Two of three actions in this test occur within the first timeslice. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // Setting the time to just barely into the new timeslice @@ -840,13 +840,13 @@ public void Should_not_open_circuit_if_failures_at_end_of_last_timeslice_and_fai // A third failure occurs just at the beginning of the new timeslice making // the number of failures above the failure threshold. However, the throughput is // below the minimum threshold as to open the circuit. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); } [Fact] - public void Should_open_circuit_if_failures_in_second_window_of_last_timeslice_and_failures_in_first_window_in_next_timeslice_exceeds_failure_threshold_and_minimum_threshold() + public async Task Should_open_circuit_if_failures_in_second_window_of_last_timeslice_and_failures_in_first_window_in_next_timeslice_exceeds_failure_threshold_and_minimum_threshold() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -865,31 +865,31 @@ public void Should_open_circuit_if_failures_in_second_window_of_last_timeslice_a // Executing a single invocation to ensure timeslice is created // This invocation is not be counted against the threshold - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // Setting the time to the second window in the rolling metrics SystemClock.UtcNow = () => time.AddSeconds(samplingDuration.Seconds / (double)numberOfWindowsDefinedInCircuitBreaker); // Three actions occur in the second window of the first timeslice - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // Setting the time to just barely into the new timeslice SystemClock.UtcNow = () => time.Add(samplingDuration); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); } @@ -904,7 +904,7 @@ public void Should_open_circuit_if_failures_in_second_window_of_last_timeslice_a // These provide easy values for testing for failure and throughput thresholds each being met and non-met, in combination. [Fact] - public void Should_open_circuit_with_the_last_raised_exception_if_failure_threshold_exceeded_and_throughput_threshold_equalled_within_timeslice_low_sampling_duration() + public async Task Should_open_circuit_with_the_last_raised_exception_if_failure_threshold_exceeded_and_throughput_threshold_equalled_within_timeslice_low_sampling_duration() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -919,34 +919,34 @@ public void Should_open_circuit_with_the_last_raised_exception_if_failure_thresh ); // Four of four actions in this test throw handled failures. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // No adjustment to SystemClock.UtcNow, so all exceptions raised within same timeslice - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw() - .WithMessage("The circuit is now open and is not allowing calls.") - .WithInnerException(); + var ex = await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync() + .WithMessage("The circuit is now open and is not allowing calls."); + ex.WithInnerException(); breaker.CircuitState.Should().Be(CircuitState.Open); } [Fact] - public void Should_open_circuit_with_the_last_raised_exception_if_failure_threshold_exceeded_though_not_all_are_failures_and_throughput_threshold_equalled_within_timeslice_low_sampling_duration() + public async Task Should_open_circuit_with_the_last_raised_exception_if_failure_threshold_exceeded_though_not_all_are_failures_and_throughput_threshold_equalled_within_timeslice_low_sampling_duration() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -961,33 +961,33 @@ public void Should_open_circuit_with_the_last_raised_exception_if_failure_thresh ); // Three of four actions in this test throw handled failures. - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); // No adjustment to SystemClock.UtcNow, so all exceptions were raised within same timeslice - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw() - .WithMessage("The circuit is now open and is not allowing calls.") - .WithInnerException(); + var ex = await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync() + .WithMessage("The circuit is now open and is not allowing calls."); + ex.WithInnerException(); breaker.CircuitState.Should().Be(CircuitState.Open); } [Fact] - public void Should_open_circuit_with_the_last_raised_exception_if_failure_threshold_equalled_and_throughput_threshold_equalled_within_timeslice_low_sampling_duration() + public async Task Should_open_circuit_with_the_last_raised_exception_if_failure_threshold_equalled_and_throughput_threshold_equalled_within_timeslice_low_sampling_duration() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -1002,33 +1002,33 @@ public void Should_open_circuit_with_the_last_raised_exception_if_failure_thresh ); // Two of four actions in this test throw handled failures. - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); // No adjustment to SystemClock.UtcNow, so all exceptions were raised within same timeslice - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw() - .WithMessage("The circuit is now open and is not allowing calls.") - .WithInnerException(); + var ex = await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync() + .WithMessage("The circuit is now open and is not allowing calls."); + ex.WithInnerException(); breaker.CircuitState.Should().Be(CircuitState.Open); } [Fact] - public void Should_not_open_circuit_if_failure_threshold_exceeded_but_throughput_threshold_not_met_before_timeslice_expires_low_sampling_duration() + public async Task Should_not_open_circuit_if_failure_threshold_exceeded_but_throughput_threshold_not_met_before_timeslice_expires_low_sampling_duration() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -1045,29 +1045,29 @@ public void Should_not_open_circuit_if_failure_threshold_exceeded_but_throughput ); // Four of four actions in this test throw handled failures; but only the first within the timeslice. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // Adjust SystemClock so that timeslice (clearly) expires; fourth exception thrown in next-recorded timeslice. SystemClock.UtcNow = () => time.Add(samplingDuration).Add(samplingDuration); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); } [Fact] - public void Should_not_open_circuit_if_failure_threshold_exceeded_but_throughput_threshold_not_met_before_timeslice_expires_even_if_timeslice_expires_only_exactly_low_sampling_duration() + public async Task Should_not_open_circuit_if_failure_threshold_exceeded_but_throughput_threshold_not_met_before_timeslice_expires_even_if_timeslice_expires_only_exactly_low_sampling_duration() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -1084,29 +1084,29 @@ public void Should_not_open_circuit_if_failure_threshold_exceeded_but_throughput ); // Two of four actions in this test throw handled failures; but only the first within the timeslice. - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // Adjust SystemClock so that timeslice (just) expires; fourth exception thrown in following timeslice. SystemClock.UtcNow = () => time.Add(samplingDuration); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); } [Fact] - public void Should_open_circuit_with_the_last_raised_exception_if_failure_threshold_equalled_and_throughput_threshold_equalled_even_if_only_just_within_timeslice_low_sampling_duration() + public async Task Should_open_circuit_with_the_last_raised_exception_if_failure_threshold_equalled_and_throughput_threshold_equalled_even_if_only_just_within_timeslice_low_sampling_duration() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -1123,35 +1123,35 @@ public void Should_open_circuit_with_the_last_raised_exception_if_failure_thresh ); // Four of four actions in this test throw handled failures. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // Adjust SystemClock so that timeslice doesn't quite expire; fourth exception thrown in same timeslice. SystemClock.UtcNow = () => time.AddTicks(samplingDuration.Ticks - 1); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw() - .WithMessage("The circuit is now open and is not allowing calls.") - .WithInnerException(); + var ex = await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync() + .WithMessage("The circuit is now open and is not allowing calls."); + ex.WithInnerException(); breaker.CircuitState.Should().Be(CircuitState.Open); } [Fact] - public void Should_not_open_circuit_if_failure_threshold_not_met_and_throughput_threshold_not_met_low_sampling_duration() + public async Task Should_not_open_circuit_if_failure_threshold_not_met_and_throughput_threshold_not_met_low_sampling_duration() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -1166,22 +1166,22 @@ public void Should_not_open_circuit_if_failure_threshold_not_met_and_throughput_ ); // One of three actions in this test throw handled failures. - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // No adjustment to SystemClock.UtcNow, so all exceptions were raised within same timeslice } [Fact] - public void Should_not_open_circuit_if_failure_threshold_not_met_but_throughput_threshold_met_before_timeslice_expires_low_sampling_duration() + public async Task Should_not_open_circuit_if_failure_threshold_not_met_but_throughput_threshold_met_before_timeslice_expires_low_sampling_duration() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -1196,26 +1196,26 @@ public void Should_not_open_circuit_if_failure_threshold_not_met_but_throughput_ ); // One of four actions in this test throw handled failures. - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // No adjustment to SystemClock.UtcNow, so all exceptions were raised within same timeslice } [Fact] - public void Should_not_open_circuit_if_failures_at_end_of_last_timeslice_below_failure_threshold_and_failures_in_beginning_of_new_timeslice_where_total_equals_failure_threshold_low_sampling_duration() + public async Task Should_not_open_circuit_if_failures_at_end_of_last_timeslice_below_failure_threshold_and_failures_in_beginning_of_new_timeslice_where_total_equals_failure_threshold_low_sampling_duration() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -1233,8 +1233,8 @@ public void Should_not_open_circuit_if_failures_at_end_of_last_timeslice_below_f // Executing a single invocation to ensure timeslice is created // This invocation is not be counted against the threshold - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // The time is set to just at the end of the sampling duration ensuring @@ -1242,16 +1242,16 @@ public void Should_not_open_circuit_if_failures_at_end_of_last_timeslice_below_f SystemClock.UtcNow = () => time.AddTicks(samplingDuration.Ticks - 1); // Three of four actions in this test occur within the first timeslice. - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // Setting the time to just barely into the new timeslice @@ -1259,8 +1259,8 @@ public void Should_not_open_circuit_if_failures_at_end_of_last_timeslice_below_f // This failure does not open the circuit, because a new duration should have // started and with such low sampling duration, windows should not be used. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); } @@ -1271,7 +1271,7 @@ public void Should_not_open_circuit_if_failures_at_end_of_last_timeslice_below_f #region Circuit-breaker open->half-open->open/closed tests [Fact] - public void Should_halfopen_circuit_after_the_specified_duration_has_passed_with_failures_in_same_window() + public async Task Should_halfopen_circuit_after_the_specified_duration_has_passed_with_failures_in_same_window() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -1288,20 +1288,20 @@ public void Should_halfopen_circuit_after_the_specified_duration_has_passed_with ); // Four of four actions in this test throw handled failures. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); @@ -1309,12 +1309,12 @@ public void Should_halfopen_circuit_after_the_specified_duration_has_passed_with // duration has passed, circuit now half open breaker.CircuitState.Should().Be(CircuitState.HalfOpen); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } [Fact] - public void Should_halfopen_circuit_after_the_specified_duration_has_passed_with_failures_in_different_windows() + public async Task Should_halfopen_circuit_after_the_specified_duration_has_passed_with_failures_in_different_windows() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -1332,16 +1332,16 @@ public void Should_halfopen_circuit_after_the_specified_duration_has_passed_with ); // Four of four actions in this test throw handled failures. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // Placing the rest of the invocations ('samplingDuration' / 2) + 1 seconds later @@ -1350,8 +1350,8 @@ public void Should_halfopen_circuit_after_the_specified_duration_has_passed_with var anotherWindowDuration = samplingDuration.Seconds / 2d + 1; SystemClock.UtcNow = () => time.AddSeconds(anotherWindowDuration); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); @@ -1364,12 +1364,12 @@ public void Should_halfopen_circuit_after_the_specified_duration_has_passed_with // duration has passed, circuit now half open breaker.CircuitState.Should().Be(CircuitState.HalfOpen); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } [Fact] - public void Should_open_circuit_again_after_the_specified_duration_has_passed_if_the_next_call_raises_an_exception() + public async Task Should_open_circuit_again_after_the_specified_duration_has_passed_if_the_next_call_raises_an_exception() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -1386,20 +1386,20 @@ public void Should_open_circuit_again_after_the_specified_duration_has_passed_if ); // Four of four actions in this test throw handled failures. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); @@ -1409,11 +1409,11 @@ public void Should_open_circuit_again_after_the_specified_duration_has_passed_if breaker.CircuitState.Should().Be(CircuitState.HalfOpen); // first call after duration raises an exception, so circuit should open again - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } @@ -1435,20 +1435,20 @@ public async Task Should_reset_circuit_after_the_specified_duration_has_passed_i ); // Four of four actions in this test throw handled failures. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); @@ -1463,7 +1463,7 @@ public async Task Should_reset_circuit_after_the_specified_duration_has_passed_i } [Fact] - public void Should_only_allow_single_execution_on_first_entering_halfopen_state__test_execution_permit_directly() + public async Task Should_only_allow_single_execution_on_first_entering_halfopen_state__test_execution_permit_directly() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -1478,10 +1478,10 @@ public void Should_only_allow_single_execution_on_first_entering_halfopen_state_ durationOfBreak: durationOfBreak ); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); // exception raised, circuit is now open. breaker.CircuitState.Should().Be(CircuitState.Open); @@ -1501,7 +1501,7 @@ public void Should_only_allow_single_execution_on_first_entering_halfopen_state_ } [Fact] - public void Should_allow_single_execution_per_break_duration_in_halfopen_state__test_execution_permit_directly() + public async Task Should_allow_single_execution_per_break_duration_in_halfopen_state__test_execution_permit_directly() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -1516,10 +1516,10 @@ public void Should_allow_single_execution_per_break_duration_in_halfopen_state__ durationOfBreak: durationOfBreak ); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); // exception raised, circuit is now open. breaker.CircuitState.Should().Be(CircuitState.Open); @@ -1547,7 +1547,7 @@ public void Should_allow_single_execution_per_break_duration_in_halfopen_state__ } [Fact] - public void Should_only_allow_single_execution_on_first_entering_halfopen_state__integration_test() + public async Task Should_only_allow_single_execution_on_first_entering_halfopen_state__integration_test() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -1562,10 +1562,10 @@ public void Should_only_allow_single_execution_on_first_entering_halfopen_state_ durationOfBreak: durationOfBreak ); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); // exceptions raised, circuit is now open. breaker.CircuitState.Should().Be(CircuitState.Open); @@ -1587,9 +1587,9 @@ public void Should_only_allow_single_execution_on_first_entering_halfopen_state_ bool firstExecutionActive = false; // First execution in HalfOpen state: we should be able to verify state is HalfOpen as it executes. - Task firstExecution = Task.Factory.StartNew(() => + Task firstExecution = Task.Factory.StartNew(async () => { - breaker.Awaiting(x => x.ExecuteAsync(async () => + await breaker.Awaiting(x => x.ExecuteAsync(async () => { firstDelegateExecutedInHalfOpenState = breaker.CircuitState == CircuitState.HalfOpen; // For readability of test results, we assert on this at test end rather than nested in Task and breaker here. @@ -1602,7 +1602,7 @@ public void Should_only_allow_single_execution_on_first_entering_halfopen_state_ await TaskHelper.EmptyTask; firstExecutionActive = false; - })).Should().NotThrow(); + })).Should().NotThrowAsync(); }, TaskCreationOptions.LongRunning); // Attempt a second execution, signalled by the first execution to ensure they overlap: we should be able to verify it doesn't execute, and is rejected by a breaker in a HalfOpen state. @@ -1653,7 +1653,7 @@ await breaker.ExecuteAsync(async () => } [Fact] - public void Should_allow_single_execution_per_break_duration_in_halfopen_state__integration_test() + public async Task Should_allow_single_execution_per_break_duration_in_halfopen_state__integration_test() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -1668,10 +1668,10 @@ public void Should_allow_single_execution_per_break_duration_in_halfopen_state__ durationOfBreak: durationOfBreak ); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); // exception raised, circuit is now open. breaker.CircuitState.Should().Be(CircuitState.Open); @@ -1694,9 +1694,9 @@ public void Should_allow_single_execution_per_break_duration_in_halfopen_state__ bool firstExecutionActive = false; // First execution in HalfOpen state: we should be able to verify state is HalfOpen as it executes. - Task firstExecution = Task.Factory.StartNew(() => + Task firstExecution = Task.Factory.StartNew(async () => { - breaker.Awaiting(x => x.ExecuteAsync(async () => + await breaker.Awaiting(x => x.ExecuteAsync(async () => { firstDelegateExecutedInHalfOpenState = breaker.CircuitState == CircuitState.HalfOpen; // For readability of test results, we assert on this at test end rather than nested in Task and breaker here. @@ -1708,7 +1708,7 @@ public void Should_allow_single_execution_per_break_duration_in_halfopen_state__ permitFirstExecutionEnd.WaitOne(testTimeoutToExposeDeadlocks); await TaskHelper.EmptyTask; firstExecutionActive = false; - })).Should().NotThrow(); + })).Should().NotThrowAsync(); }, TaskCreationOptions.LongRunning); // Attempt a second execution, signalled by the first execution to ensure they overlap; start it one breakDuration later. We should be able to verify it does execute, though the breaker is still in a HalfOpen state. @@ -1765,7 +1765,7 @@ await breaker.ExecuteAsync(async () => #region Isolate and reset tests [Fact] - public void Should_open_circuit_and_block_calls_if_manual_override_open() + public async Task Should_open_circuit_and_block_calls_if_manual_override_open() { var breaker = Policy .Handle() @@ -1778,15 +1778,15 @@ public void Should_open_circuit_and_block_calls_if_manual_override_open() // circuit manually broken: execution should be blocked; even non-exception-throwing executions should not reset circuit bool delegateExecutedWhenBroken = false; - breaker.Awaiting(x => x.ExecuteAsync(() => { delegateExecutedWhenBroken = true; return TaskHelper.EmptyTask; })) - .Should().Throw(); + await breaker.Awaiting(x => x.ExecuteAsync(() => { delegateExecutedWhenBroken = true; return TaskHelper.EmptyTask; })) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Isolated); breaker.LastException.Should().BeOfType(); delegateExecutedWhenBroken.Should().BeFalse(); } [Fact] - public void Should_hold_circuit_open_despite_elapsed_time_if_manual_override_open() + public async Task Should_hold_circuit_open_despite_elapsed_time_if_manual_override_open() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -1804,13 +1804,13 @@ public void Should_hold_circuit_open_despite_elapsed_time_if_manual_override_ope breaker.CircuitState.Should().Be(CircuitState.Isolated); bool delegateExecutedWhenBroken = false; - breaker.Awaiting(x => x.ExecuteAsync(() => { delegateExecutedWhenBroken = true; return TaskHelper.EmptyTask; })) - .Should().Throw(); + await breaker.Awaiting(x => x.ExecuteAsync(() => { delegateExecutedWhenBroken = true; return TaskHelper.EmptyTask; })) + .Should().ThrowAsync(); delegateExecutedWhenBroken.Should().BeFalse(); } [Fact] - public void Should_close_circuit_again_on_reset_after_manual_override() + public async Task Should_close_circuit_again_on_reset_after_manual_override() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -1823,17 +1823,17 @@ public void Should_close_circuit_again_on_reset_after_manual_override() breaker.Isolate(); breaker.CircuitState.Should().Be(CircuitState.Isolated); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().Throw(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().ThrowAsync(); breaker.Reset(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); } [Fact] - public void Should_be_able_to_reset_automatically_opened_circuit_without_specified_duration_passing() + public async Task Should_be_able_to_reset_automatically_opened_circuit_without_specified_duration_passing() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -1850,28 +1850,28 @@ public void Should_be_able_to_reset_automatically_opened_circuit_without_specifi ); // Four of four actions in this test throw handled failures. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); // reset circuit, with no time having passed breaker.Reset(); SystemClock.UtcNow().Should().Be(time); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); } #endregion @@ -1894,7 +1894,7 @@ public void Should_not_call_onreset_on_initialise() } [Fact] - public void Should_call_onbreak_when_breaking_circuit_automatically() + public async Task Should_call_onbreak_when_breaking_circuit_automatically() { bool onBreakCalled = false; Action onBreak = (_, _) => { onBreakCalled = true; }; @@ -1915,22 +1915,22 @@ public void Should_call_onbreak_when_breaking_circuit_automatically() ); // Four of four actions in this test throw handled failures. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // No adjustment to SystemClock.UtcNow, so all exceptions raised within same timeslice - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); onBreakCalled.Should().BeTrue(); @@ -1956,7 +1956,7 @@ public void Should_call_onbreak_when_breaking_circuit_manually() } [Fact] - public void Should_call_onbreak_when_breaking_circuit_first_time_but_not_for_subsequent_calls_placed_through_open_circuit() + public async Task Should_call_onbreak_when_breaking_circuit_first_time_but_not_for_subsequent_calls_placed_through_open_circuit() { int onBreakCalled = 0; Action onBreak = (_, _) => { onBreakCalled++; }; @@ -1977,39 +1977,39 @@ public void Should_call_onbreak_when_breaking_circuit_first_time_but_not_for_sub ); // Four of four actions in this test throw handled failures. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); onBreakCalled.Should().Be(0); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); onBreakCalled.Should().Be(0); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); onBreakCalled.Should().Be(0); // No adjustment to SystemClock.UtcNow, so all exceptions raised within same timeslice - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); onBreakCalled.Should().Be(1); // call through circuit when already broken - should not retrigger onBreak - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); onBreakCalled.Should().Be(1); } [Fact] - public void Should_call_onbreak_when_breaking_circuit_first_time_but_not_for_subsequent_call_failure_which_arrives_on_open_state_though_started_on_closed_state() + public async Task Should_call_onbreak_when_breaking_circuit_first_time_but_not_for_subsequent_call_failure_which_arrives_on_open_state_though_started_on_closed_state() { int onBreakCalled = 0; Action onBreak = (_, _) => { onBreakCalled++; }; @@ -2032,11 +2032,11 @@ public void Should_call_onbreak_when_breaking_circuit_first_time_but_not_for_sub using (ManualResetEvent permitLongRunningExecutionToReturnItsFailure = new ManualResetEvent(false)) using (ManualResetEvent permitMainThreadToOpenCircuit = new ManualResetEvent(false)) { - Task longRunningExecution = Task.Factory.StartNew(() => + Task longRunningExecution = Task.Factory.StartNew(async () => { breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(async () => + await breaker.Awaiting(x => x.ExecuteAsync(async () => { await TaskHelper.EmptyTask; @@ -2049,7 +2049,7 @@ public void Should_call_onbreak_when_breaking_circuit_first_time_but_not_for_sub breaker.CircuitState.Should().Be(CircuitState.Open); throw new DivideByZeroException(); - })).Should().Throw(); // However, since execution started when circuit was closed, BrokenCircuitException will not have been thrown on entry; the original exception will still be thrown. + })).Should().ThrowAsync(); // However, since execution started when circuit was closed, BrokenCircuitException will not have been thrown on entry; the original exception will still be thrown. }, TaskCreationOptions.LongRunning); permitMainThreadToOpenCircuit.WaitOne(testTimeoutToExposeDeadlocks).Should().BeTrue(); @@ -2057,10 +2057,10 @@ public void Should_call_onbreak_when_breaking_circuit_first_time_but_not_for_sub // Break circuit in the normal manner: onBreak() should be called once. breaker.CircuitState.Should().Be(CircuitState.Closed); onBreakCalled.Should().Be(0); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); onBreakCalled.Should().Be(1); @@ -2103,22 +2103,22 @@ public async Task Should_call_onreset_when_automatically_closing_circuit_but_not ); // Four of four actions in this test throw handled failures. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // No adjustment to SystemClock.UtcNow, so all exceptions raised within same timeslice - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); onBreakCalled.Should().Be(1); @@ -2187,25 +2187,25 @@ public async Task Should_call_onhalfopen_when_automatically_transitioning_to_hal ); // Four of four actions in this test throw handled failures. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); onBreakCalled.Should().Be(0); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); onBreakCalled.Should().Be(0); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); onBreakCalled.Should().Be(0); // No adjustment to SystemClock.UtcNow, so all exceptions raised within same timeslice - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); onBreakCalled.Should().Be(1); @@ -2222,7 +2222,7 @@ public async Task Should_call_onhalfopen_when_automatically_transitioning_to_hal } [Fact] - public void Should_call_onhalfopen_when_automatically_transitioning_to_halfopen_due_to_state_read() + public async Task Should_call_onhalfopen_when_automatically_transitioning_to_halfopen_due_to_state_read() { int onBreakCalled = 0; int onResetCalled = 0; @@ -2249,25 +2249,25 @@ public void Should_call_onhalfopen_when_automatically_transitioning_to_halfopen_ ); // Four of four actions in this test throw handled failures. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); onBreakCalled.Should().Be(0); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); onBreakCalled.Should().Be(0); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); onBreakCalled.Should().Be(0); // No adjustment to SystemClock.UtcNow, so all exceptions raised within same timeslice - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); onBreakCalled.Should().Be(1); @@ -2279,7 +2279,7 @@ public void Should_call_onhalfopen_when_automatically_transitioning_to_halfopen_ } [Fact] - public void Should_call_onreset_when_manually_resetting_circuit() + public async Task Should_call_onreset_when_manually_resetting_circuit() { int onBreakCalled = 0; int onResetCalled = 0; @@ -2299,22 +2299,22 @@ public void Should_call_onreset_when_manually_resetting_circuit() onBreakCalled.Should().Be(1); breaker.CircuitState.Should().Be(CircuitState.Isolated); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().Throw(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().ThrowAsync(); onResetCalled.Should().Be(0); breaker.Reset(); onResetCalled.Should().Be(1); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().NotThrowAsync(); } #region Tests of supplied parameters to onBreak delegate [Fact] - public void Should_call_onbreak_with_the_last_raised_exception() + public async Task Should_call_onbreak_with_the_last_raised_exception() { Exception passedException = null; @@ -2333,29 +2333,29 @@ public void Should_call_onbreak_with_the_last_raised_exception() ); // Four of four actions in this test throw handled failures. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // No adjustment to SystemClock.UtcNow, so all exceptions raised within same timeslice - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); passedException?.Should().BeOfType(); } [Fact] - public void Should_call_onbreak_with_a_state_of_closed() + public async Task Should_call_onbreak_with_a_state_of_closed() { CircuitState? transitionedState = null; @@ -2375,29 +2375,29 @@ public void Should_call_onbreak_with_a_state_of_closed() onHalfOpen: onHalfOpen ); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // No adjustment to SystemClock.UtcNow, so all exceptions raised within same timeslice - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); transitionedState?.Should().Be(CircuitState.Closed); } [Fact] - public void Should_call_onbreak_with_a_state_of_half_open() + public async Task Should_call_onbreak_with_a_state_of_half_open() { List transitionedStates = new List(); @@ -2423,20 +2423,20 @@ public void Should_call_onbreak_with_a_state_of_half_open() ); // Four of four actions in this test throw handled failures. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); @@ -2446,18 +2446,18 @@ public void Should_call_onbreak_with_a_state_of_half_open() breaker.CircuitState.Should().Be(CircuitState.HalfOpen); // first call after duration raises an exception, so circuit should open again - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); transitionedStates[0].Should().Be(CircuitState.Closed); transitionedStates[1].Should().Be(CircuitState.HalfOpen); } [Fact] - public void Should_call_onbreak_with_the_correct_timespan() + public async Task Should_call_onbreak_with_the_correct_timespan() { TimeSpan? passedBreakTimespan = null; @@ -2478,22 +2478,22 @@ public void Should_call_onbreak_with_the_correct_timespan() ); // Four of four actions in this test throw handled failures. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); // No adjustment to SystemClock.UtcNow, so all exceptions raised within same timeslice - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); passedBreakTimespan.Should().Be(durationOfBreak); @@ -2533,7 +2533,7 @@ public void Should_open_circuit_with_timespan_maxvalue_if_manual_override_open() #region Tests that supplied context is passed to stage-change delegates [Fact] - public void Should_call_onbreak_with_the_passed_context() + public async Task Should_call_onbreak_with_the_passed_context() { IDictionary contextData = null; @@ -2555,21 +2555,21 @@ public void Should_call_onbreak_with_the_passed_context() ); // Four of four actions in this test throw handled failures. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync( + await breaker.Awaiting(x => x.RaiseExceptionAsync( new { key1 = "value1", key2 = "value2" }.AsDictionary() - )).Should().Throw(); + )).Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); contextData.Should() @@ -2602,20 +2602,20 @@ public async Task Should_call_onreset_with_the_passed_context() ); // Four of four actions in this test throw handled failures. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); @@ -2633,7 +2633,7 @@ public async Task Should_call_onreset_with_the_passed_context() } [Fact] - public void Context_should_be_empty_if_execute_not_called_with_any_context_data() + public async Task Context_should_be_empty_if_execute_not_called_with_any_context_data() { IDictionary contextData = new { key1 = "value1", key2 = "value2" }.AsDictionary(); @@ -2655,20 +2655,20 @@ public void Context_should_be_empty_if_execute_not_called_with_any_context_data( ); // Four of four actions in this test throw handled failures. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); @@ -2702,20 +2702,20 @@ public async Task Should_create_new_context_for_each_call_to_execute() ); // Four of four actions in this test throw handled failures. - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync(new { key = "original_value" }.AsDictionary())) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync(new { key = "original_value" }.AsDictionary())) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); contextValue.Should().Be("original_value"); @@ -2754,7 +2754,7 @@ public void Should_initialise_LastException_to_null_on_creation() } [Fact] - public void Should_set_LastException_on_handling_exception_even_when_not_breaking() + public async Task Should_set_LastException_on_handling_exception_even_when_not_breaking() { var breaker = Policy .Handle() @@ -2765,15 +2765,15 @@ public void Should_set_LastException_on_handling_exception_even_when_not_breakin durationOfBreak: TimeSpan.FromSeconds(30) ); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); breaker.LastException.Should().BeOfType(); } [Fact] - public void Should_set_LastException_to_last_raised_exception_when_breaking() + public async Task Should_set_LastException_to_last_raised_exception_when_breaking() { var breaker = Policy .Handle() @@ -2784,19 +2784,19 @@ public void Should_set_LastException_to_last_raised_exception_when_breaking() durationOfBreak: TimeSpan.FromSeconds(30) ); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); breaker.LastException.Should().BeOfType(); } [Fact] - public void Should_set_LastException_to_null_on_circuit_reset() + public async Task Should_set_LastException_to_null_on_circuit_reset() { var breaker = Policy .Handle() @@ -2807,12 +2807,12 @@ public void Should_set_LastException_to_null_on_circuit_reset() durationOfBreak: TimeSpan.FromSeconds(30) ); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); breaker.LastException.Should().BeOfType(); @@ -2827,7 +2827,7 @@ public void Should_set_LastException_to_null_on_circuit_reset() #region Cancellation support [Fact] - public void Should_execute_action_when_non_faulting_and_cancellationToken_not_cancelled() + public async Task Should_execute_action_when_non_faulting_and_cancellationToken_not_cancelled() { var durationOfBreak = TimeSpan.FromMinutes(1); var breaker = Policy @@ -2845,14 +2845,14 @@ public void Should_execute_action_when_non_faulting_and_cancellationToken_not_ca AttemptDuringWhichToCancel = null, }; - breaker.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().NotThrowAsync(); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_not_execute_action_when_cancellationToken_cancelled_before_execute() + public async Task Should_not_execute_action_when_cancellationToken_cancelled_before_execute() { var durationOfBreak = TimeSpan.FromMinutes(1); var breaker = Policy @@ -2873,15 +2873,15 @@ public void Should_not_execute_action_when_cancellationToken_cancelled_before_ex cancellationTokenSource.Cancel(); - breaker.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await breaker.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(0); } [Fact] - public void Should_report_cancellation_during_otherwise_non_faulting_action_execution_when_user_delegate_observes_cancellationToken() + public async Task Should_report_cancellation_during_otherwise_non_faulting_action_execution_when_user_delegate_observes_cancellationToken() { var durationOfBreak = TimeSpan.FromMinutes(1); var breaker = Policy @@ -2901,15 +2901,15 @@ public void Should_report_cancellation_during_otherwise_non_faulting_action_exec ActionObservesCancellation = true }; - breaker.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await breaker.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_report_cancellation_during_faulting_action_execution_when_user_delegate_observes_cancellationToken() + public async Task Should_report_cancellation_during_faulting_action_execution_when_user_delegate_observes_cancellationToken() { var durationOfBreak = TimeSpan.FromMinutes(1); var breaker = Policy @@ -2929,15 +2929,15 @@ public void Should_report_cancellation_during_faulting_action_execution_when_use ActionObservesCancellation = true }; - breaker.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await breaker.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_report_faulting_from_faulting_action_execution_when_user_delegate_does_not_observe_cancellation() + public async Task Should_report_faulting_from_faulting_action_execution_when_user_delegate_does_not_observe_cancellation() { var durationOfBreak = TimeSpan.FromMinutes(1); var breaker = Policy @@ -2956,30 +2956,30 @@ public void Should_report_faulting_from_faulting_action_execution_when_user_dele ActionObservesCancellation = false }; - breaker.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_report_cancellation_when_both_open_circuit_and_cancellation() + public async Task Should_report_cancellation_when_both_open_circuit_and_cancellation() { var durationOfBreak = TimeSpan.FromMinutes(1); var breaker = Policy .Handle() .AdvancedCircuitBreakerAsync(0.5, TimeSpan.FromSeconds(10), 2, durationOfBreak); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw() - .WithMessage("The circuit is now open and is not allowing calls.") - .WithInnerException(); + var ex = await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync() + .WithMessage("The circuit is now open and is not allowing calls."); + ex.WithInnerException(); // Circuit is now broken. CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); @@ -2997,15 +2997,15 @@ public void Should_report_cancellation_when_both_open_circuit_and_cancellation() ActionObservesCancellation = false }; - breaker.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex2 = await breaker.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex2.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(0); } [Fact] - public void Should_honour_different_cancellationToken_captured_implicitly_by_action() + public async Task Should_honour_different_cancellationToken_captured_implicitly_by_action() { // Before CancellationToken support was built in to Polly, users of the library may have implicitly captured a CancellationToken and used it to cancel actions. For backwards compatibility, Polly should not confuse these with its own CancellationToken; it should distinguish TaskCanceledExceptions thrown with different CancellationTokens. @@ -3024,20 +3024,21 @@ public void Should_honour_different_cancellationToken_captured_implicitly_by_act int attemptsInvoked = 0; - breaker.Awaiting(x => x.ExecuteAsync(async _ => + var ex = await breaker.Awaiting(x => x.ExecuteAsync(async _ => { attemptsInvoked++; await TaskHelper.EmptyTask; implicitlyCapturedActionCancellationToken.ThrowIfCancellationRequested(); }, policyCancellationToken)) - .Should().Throw() - .And.CancellationToken.Should().Be(implicitlyCapturedActionCancellationToken); + .Should().ThrowAsync(); + + ex.And.CancellationToken.Should().Be(implicitlyCapturedActionCancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_execute_func_returning_value_when_cancellationToken_not_cancelled() + public async Task Should_execute_func_returning_value_when_cancellationToken_not_cancelled() { var durationOfBreak = TimeSpan.FromMinutes(1); var breaker = Policy @@ -3059,8 +3060,8 @@ public void Should_execute_func_returning_value_when_cancellationToken_not_cance }; Func action = async x => result = await x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, true); - breaker.Awaiting(action) - .Should().NotThrow(); + await breaker.Awaiting(action) + .Should().NotThrowAsync(); result.Should().BeTrue(); @@ -3068,7 +3069,7 @@ public void Should_execute_func_returning_value_when_cancellationToken_not_cance } [Fact] - public void Should_honour_and_report_cancellation_during_func_execution() + public async Task Should_honour_and_report_cancellation_during_func_execution() { var durationOfBreak = TimeSpan.FromMinutes(1); var breaker = Policy @@ -3091,8 +3092,9 @@ public void Should_honour_and_report_cancellation_during_func_execution() }; Func action = async x => result = await x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, true); - breaker.Awaiting(action) - .Should().Throw().And.CancellationToken.Should().Be(cancellationToken); + var ex = await breaker.Awaiting(action) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); result.Should().Be(null); diff --git a/src/Polly.Specs/CircuitBreaker/CircuitBreakerAsyncSpecs.cs b/src/Polly.Specs/CircuitBreaker/CircuitBreakerAsyncSpecs.cs index 375c71209cd..3116cf86673 100644 --- a/src/Polly.Specs/CircuitBreaker/CircuitBreakerAsyncSpecs.cs +++ b/src/Polly.Specs/CircuitBreaker/CircuitBreakerAsyncSpecs.cs @@ -19,14 +19,14 @@ public class CircuitBreakerAsyncSpecs : IDisposable #region Configuration tests [Fact] - public void Should_be_able_to_handle_a_duration_of_timespan_maxvalue() + public async Task Should_be_able_to_handle_a_duration_of_timespan_maxvalue() { var breaker = Policy .Handle() .CircuitBreakerAsync(1, TimeSpan.MaxValue); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } [Fact] @@ -79,113 +79,113 @@ public void Should_initialise_to_closed_state() #region Circuit-breaker threshold-to-break tests [Fact] - public void Should_not_open_circuit_if_specified_number_of_specified_exception_are_not_raised_consecutively() + public async Task Should_not_open_circuit_if_specified_number_of_specified_exception_are_not_raised_consecutively() { var breaker = Policy .Handle() .CircuitBreakerAsync(2, TimeSpan.FromMinutes(1)); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(b => b.ExecuteAsync(() => TaskHelper.EmptyTask)).Should().NotThrow(); + await breaker.Awaiting(b => b.ExecuteAsync(() => TaskHelper.EmptyTask)).Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); } [Fact] - public void Should_open_circuit_blocking_executions_and_noting_the_last_raised_exception_after_specified_number_of_specified_exception_have_been_raised() + public async Task Should_open_circuit_blocking_executions_and_noting_the_last_raised_exception_after_specified_number_of_specified_exception_have_been_raised() { var breaker = Policy .Handle() .CircuitBreakerAsync(2, TimeSpan.FromMinutes(1)); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); bool delegateExecutedWhenBroken = false; - breaker.Awaiting(x => x.ExecuteAsync(() => { delegateExecutedWhenBroken = true; return TaskHelper.EmptyTask; })) - .Should().Throw() - .WithMessage("The circuit is now open and is not allowing calls.") - .WithInnerException(); + var ex = await breaker.Awaiting(x => x.ExecuteAsync(() => { delegateExecutedWhenBroken = true; return TaskHelper.EmptyTask; })) + .Should().ThrowAsync() + .WithMessage("The circuit is now open and is not allowing calls."); + ex.WithInnerException(); breaker.CircuitState.Should().Be(CircuitState.Open); delegateExecutedWhenBroken.Should().BeFalse(); } [Fact] - public void Should_open_circuit_blocking_executions_and_noting_the_last_raised_exception_after_specified_number_of_one_of_the_specified_exceptions_have_been_raised() + public async Task Should_open_circuit_blocking_executions_and_noting_the_last_raised_exception_after_specified_number_of_one_of_the_specified_exceptions_have_been_raised() { var breaker = Policy .Handle() .Or() .CircuitBreakerAsync(2, TimeSpan.FromMinutes(1)); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); // 2 exception raised, circuit is now open bool delegateExecutedWhenBroken = false; - breaker.Awaiting(x => x.ExecuteAsync(() => { delegateExecutedWhenBroken = true; return TaskHelper.EmptyTask; })) - .Should().Throw() - .WithMessage("The circuit is now open and is not allowing calls.") - .WithInnerException(); + var ex = await breaker.Awaiting(x => x.ExecuteAsync(() => { delegateExecutedWhenBroken = true; return TaskHelper.EmptyTask; })) + .Should().ThrowAsync() + .WithMessage("The circuit is now open and is not allowing calls."); + ex.WithInnerException(); breaker.CircuitState.Should().Be(CircuitState.Open); delegateExecutedWhenBroken.Should().BeFalse(); } [Fact] - public void Should_not_open_circuit_if_exception_raised_is_not_the_specified_exception() + public async Task Should_not_open_circuit_if_exception_raised_is_not_the_specified_exception() { var breaker = Policy .Handle() .CircuitBreakerAsync(2, TimeSpan.FromMinutes(1)); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); } [Fact] - public void Should_not_open_circuit_if_exception_raised_is_not_one_of_the_specified_exceptions() + public async Task Should_not_open_circuit_if_exception_raised_is_not_one_of_the_specified_exceptions() { var breaker = Policy .Handle() .Or() .CircuitBreakerAsync(2, TimeSpan.FromMinutes(1)); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); } @@ -194,7 +194,7 @@ public void Should_not_open_circuit_if_exception_raised_is_not_one_of_the_specif #region Circuit-breaker open->half-open->open/closed tests [Fact] - public void Should_halfopen_circuit_after_the_specified_duration_has_passed() + public async Task Should_halfopen_circuit_after_the_specified_duration_has_passed() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -205,29 +205,29 @@ public void Should_halfopen_circuit_after_the_specified_duration_has_passed() .Handle() .CircuitBreakerAsync(2, durationOfBreak); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); // 2 exception raised, circuit is now open - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); SystemClock.UtcNow = () => time.Add(durationOfBreak); // duration has passed, circuit now half open breaker.CircuitState.Should().Be(CircuitState.HalfOpen); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } [Fact] - public void Should_open_circuit_again_after_the_specified_duration_has_passed_if_the_next_call_raises_an_exception() + public async Task Should_open_circuit_again_after_the_specified_duration_has_passed_if_the_next_call_raises_an_exception() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -238,17 +238,17 @@ public void Should_open_circuit_again_after_the_specified_duration_has_passed_if .Handle() .CircuitBreakerAsync(2, durationOfBreak); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); // 2 exception raised, circuit is now open - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); SystemClock.UtcNow = () => time.Add(durationOfBreak); @@ -256,12 +256,11 @@ public void Should_open_circuit_again_after_the_specified_duration_has_passed_if // duration has passed, circuit now half open breaker.CircuitState.Should().Be(CircuitState.HalfOpen); // first call after duration raises an exception, so circuit should break again - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); - + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } [Fact] @@ -276,17 +275,17 @@ public async Task Should_reset_circuit_after_the_specified_duration_has_passed_i .Handle() .CircuitBreakerAsync(2, durationOfBreak); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); // 2 exception raised, circuit is now open - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); SystemClock.UtcNow = () => time.Add(durationOfBreak); @@ -298,21 +297,21 @@ public async Task Should_reset_circuit_after_the_specified_duration_has_passed_i breaker.CircuitState.Should().Be(CircuitState.Closed); // circuit has been reset so should once again allow 2 exceptions to be raised before breaking - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); } [Fact] - public void Should_only_allow_single_execution_on_first_entering_halfopen_state__test_execution_permit_directly() + public async Task Should_only_allow_single_execution_on_first_entering_halfopen_state__test_execution_permit_directly() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -322,8 +321,8 @@ public void Should_only_allow_single_execution_on_first_entering_halfopen_state_ .Handle() .CircuitBreakerAsync(1, durationOfBreak); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); // exception raised, circuit is now open. breaker.CircuitState.Should().Be(CircuitState.Open); @@ -343,7 +342,7 @@ public void Should_only_allow_single_execution_on_first_entering_halfopen_state_ } [Fact] - public void Should_allow_single_execution_per_break_duration_in_halfopen_state__test_execution_permit_directly() + public async Task Should_allow_single_execution_per_break_duration_in_halfopen_state__test_execution_permit_directly() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -353,8 +352,8 @@ public void Should_allow_single_execution_per_break_duration_in_halfopen_state__ .Handle() .CircuitBreakerAsync(1, durationOfBreak); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); // exception raised, circuit is now open. breaker.CircuitState.Should().Be(CircuitState.Open); @@ -382,7 +381,7 @@ public void Should_allow_single_execution_per_break_duration_in_halfopen_state__ } [Fact] - public void Should_only_allow_single_execution_on_first_entering_halfopen_state__integration_test() + public async Task Should_only_allow_single_execution_on_first_entering_halfopen_state__integration_test() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -392,8 +391,8 @@ public void Should_only_allow_single_execution_on_first_entering_halfopen_state_ .Handle() .CircuitBreakerAsync(1, durationOfBreak); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); // exception raised, circuit is now open. breaker.CircuitState.Should().Be(CircuitState.Open); @@ -415,9 +414,9 @@ public void Should_only_allow_single_execution_on_first_entering_halfopen_state_ bool firstExecutionActive = false; // First execution in HalfOpen state: we should be able to verify state is HalfOpen as it executes. - Task firstExecution = Task.Factory.StartNew(() => + Task firstExecution = Task.Factory.StartNew(async () => { - breaker.Awaiting(x => x.ExecuteAsync(async () => + await breaker.Awaiting(x => x.ExecuteAsync(async () => { firstDelegateExecutedInHalfOpenState = breaker.CircuitState == CircuitState.HalfOpen; // For readability of test results, we assert on this at test end rather than nested in Task and breaker here. @@ -430,7 +429,7 @@ public void Should_only_allow_single_execution_on_first_entering_halfopen_state_ await TaskHelper.EmptyTask; firstExecutionActive = false; - })).Should().NotThrow(); + })).Should().NotThrowAsync(); }, TaskCreationOptions.LongRunning); // Attempt a second execution, signalled by the first execution to ensure they overlap: we should be able to verify it doesn't execute, and is rejected by a breaker in a HalfOpen state. @@ -481,7 +480,7 @@ await breaker.ExecuteAsync(async () => } [Fact] - public void Should_allow_single_execution_per_break_duration_in_halfopen_state__integration_test() + public async Task Should_allow_single_execution_per_break_duration_in_halfopen_state__integration_test() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -491,8 +490,8 @@ public void Should_allow_single_execution_per_break_duration_in_halfopen_state__ .Handle() .CircuitBreakerAsync(1, durationOfBreak); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); // exception raised, circuit is now open. breaker.CircuitState.Should().Be(CircuitState.Open); @@ -515,9 +514,9 @@ public void Should_allow_single_execution_per_break_duration_in_halfopen_state__ bool firstExecutionActive = false; // First execution in HalfOpen state: we should be able to verify state is HalfOpen as it executes. - Task firstExecution = Task.Factory.StartNew(() => + Task firstExecution = Task.Factory.StartNew(async () => { - breaker.Awaiting(x => x.ExecuteAsync(async () => + await breaker.Awaiting(x => x.ExecuteAsync(async () => { firstDelegateExecutedInHalfOpenState = breaker.CircuitState == CircuitState.HalfOpen; // For readability of test results, we assert on this at test end rather than nested in Task and breaker here. @@ -529,7 +528,7 @@ public void Should_allow_single_execution_per_break_duration_in_halfopen_state__ permitFirstExecutionEnd.WaitOne(testTimeoutToExposeDeadlocks); await TaskHelper.EmptyTask; firstExecutionActive = false; - })).Should().NotThrow(); + })).Should().NotThrowAsync(); }, TaskCreationOptions.LongRunning); // Attempt a second execution, signalled by the first execution to ensure they overlap; start it one breakDuration later. We should be able to verify it does execute, though the breaker is still in a HalfOpen state. @@ -586,7 +585,7 @@ await breaker.ExecuteAsync(async () => #region Isolate and reset tests [Fact] - public void Should_open_circuit_and_block_calls_if_manual_override_open() + public async Task Should_open_circuit_and_block_calls_if_manual_override_open() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -604,8 +603,8 @@ public void Should_open_circuit_and_block_calls_if_manual_override_open() // circuit manually broken: execution should be blocked; even non-exception-throwing executions should not reset circuit bool delegateExecutedWhenBroken = false; - breaker.Awaiting(x => x.ExecuteAsync(() => { delegateExecutedWhenBroken = true; return TaskHelper.EmptyTask; })) - .Should().Throw(); + await breaker.Awaiting(x => x.ExecuteAsync(() => { delegateExecutedWhenBroken = true; return TaskHelper.EmptyTask; })) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Isolated); breaker.LastException.Should().BeOfType(); delegateExecutedWhenBroken.Should().BeFalse(); @@ -613,7 +612,7 @@ public void Should_open_circuit_and_block_calls_if_manual_override_open() } [Fact] - public void Should_hold_circuit_open_despite_elapsed_time_if_manual_override_open() + public async Task Should_hold_circuit_open_despite_elapsed_time_if_manual_override_open() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -631,13 +630,13 @@ public void Should_hold_circuit_open_despite_elapsed_time_if_manual_override_ope SystemClock.UtcNow = () => time.Add(durationOfBreak); breaker.CircuitState.Should().Be(CircuitState.Isolated); bool delegateExecutedWhenBroken = false; - breaker.Awaiting(x => x.ExecuteAsync(() => { delegateExecutedWhenBroken = true; return TaskHelper.EmptyTask; })) - .Should().Throw(); + await breaker.Awaiting(x => x.ExecuteAsync(() => { delegateExecutedWhenBroken = true; return TaskHelper.EmptyTask; })) + .Should().ThrowAsync(); delegateExecutedWhenBroken.Should().BeFalse(); } [Fact] - public void Should_close_circuit_again_on_reset_after_manual_override() + public async Task Should_close_circuit_again_on_reset_after_manual_override() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -651,16 +650,16 @@ public void Should_close_circuit_again_on_reset_after_manual_override() breaker.Isolate(); breaker.CircuitState.Should().Be(CircuitState.Isolated); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().Throw(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().ThrowAsync(); breaker.Reset(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)).Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)).Should().NotThrowAsync(); } [Fact] - public void Should_be_able_to_reset_automatically_opened_circuit_without_specified_duration_passing() + public async Task Should_be_able_to_reset_automatically_opened_circuit_without_specified_duration_passing() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -671,24 +670,24 @@ public void Should_be_able_to_reset_automatically_opened_circuit_without_specifi .Handle() .CircuitBreakerAsync(2, durationOfBreak); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); // 2 exception raised, circuit is now open - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); // reset circuit, with no time having passed breaker.Reset(); SystemClock.UtcNow().Should().Be(time); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)).Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)).Should().NotThrowAsync(); } #endregion @@ -710,7 +709,7 @@ public void Should_not_call_onreset_on_initialise() } [Fact] - public void Should_call_onbreak_when_breaking_circuit_automatically() + public async Task Should_call_onbreak_when_breaking_circuit_automatically() { bool onBreakCalled = false; Action onBreak = (_, _) => { onBreakCalled = true; }; @@ -720,14 +719,14 @@ public void Should_call_onbreak_when_breaking_circuit_automatically() .Handle() .CircuitBreakerAsync(2, TimeSpan.FromMinutes(1), onBreak, onReset); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); onBreakCalled.Should().BeFalse(); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); onBreakCalled.Should().BeTrue(); @@ -751,7 +750,7 @@ public void Should_call_onbreak_when_breaking_circuit_manually() } [Fact] - public void Should_call_onbreak_when_breaking_circuit_first_time_but_not_for_subsequent_calls_placed_through_open_circuit() + public async Task Should_call_onbreak_when_breaking_circuit_first_time_but_not_for_subsequent_calls_placed_through_open_circuit() { int onBreakCalled = 0; Action onBreak = (_, _) => { onBreakCalled++; }; @@ -761,28 +760,28 @@ public void Should_call_onbreak_when_breaking_circuit_first_time_but_not_for_sub .Handle() .CircuitBreakerAsync(2, TimeSpan.FromMinutes(1), onBreak, onReset); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); onBreakCalled.Should().Be(0); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); onBreakCalled.Should().Be(1); // call through circuit when already broken - should not retrigger onBreak - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); onBreakCalled.Should().Be(1); } [Fact] - public void Should_call_onbreak_when_breaking_circuit_first_time_but_not_for_subsequent_call_failure_which_arrives_on_open_state_though_started_on_closed_state() + public async Task Should_call_onbreak_when_breaking_circuit_first_time_but_not_for_subsequent_call_failure_which_arrives_on_open_state_though_started_on_closed_state() { int onBreakCalled = 0; Action onBreak = (_, _) => { onBreakCalled++; }; @@ -797,11 +796,11 @@ public void Should_call_onbreak_when_breaking_circuit_first_time_but_not_for_sub using (ManualResetEvent permitLongRunningExecutionToReturnItsFailure = new ManualResetEvent(false)) using (ManualResetEvent permitMainThreadToOpenCircuit = new ManualResetEvent(false)) { - Task longRunningExecution = Task.Factory.StartNew(() => + Task longRunningExecution = Task.Factory.StartNew(async () => { breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(async () => + await breaker.Awaiting(x => x.ExecuteAsync(async () => { await TaskHelper.EmptyTask; @@ -814,7 +813,7 @@ public void Should_call_onbreak_when_breaking_circuit_first_time_but_not_for_sub breaker.CircuitState.Should().Be(CircuitState.Open); throw new DivideByZeroException(); - })).Should().Throw(); // However, since execution started when circuit was closed, BrokenCircuitException will not have been thrown on entry; the original exception will still be thrown. + })).Should().ThrowAsync(); // However, since execution started when circuit was closed, BrokenCircuitException will not have been thrown on entry; the original exception will still be thrown. }, TaskCreationOptions.LongRunning); permitMainThreadToOpenCircuit.WaitOne(testTimeoutToExposeDeadlocks).Should().BeTrue(); @@ -822,8 +821,8 @@ public void Should_call_onbreak_when_breaking_circuit_first_time_but_not_for_sub // Break circuit in the normal manner: onBreak() should be called once. breaker.CircuitState.Should().Be(CircuitState.Closed); onBreakCalled.Should().Be(0); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); onBreakCalled.Should().Be(1); @@ -842,7 +841,7 @@ public void Should_call_onbreak_when_breaking_circuit_first_time_but_not_for_sub } [Fact] - public void Should_call_onreset_when_automatically_closing_circuit_but_not_when_halfopen() + public async Task Should_call_onreset_when_automatically_closing_circuit_but_not_when_halfopen() { int onBreakCalled = 0; int onResetCalled = 0; @@ -860,17 +859,17 @@ public void Should_call_onreset_when_automatically_closing_circuit_but_not_when_ onBreakCalled.Should().Be(0); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); onBreakCalled.Should().Be(0); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); onBreakCalled.Should().Be(1); // 2 exception raised, circuit is now open - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); onBreakCalled.Should().Be(1); @@ -882,13 +881,13 @@ public void Should_call_onreset_when_automatically_closing_circuit_but_not_when_ onResetCalled.Should().Be(0); // first call after duration is successful, so circuit should reset - breaker.ExecuteAsync(() => TaskHelper.EmptyTask); + await breaker.ExecuteAsync(() => TaskHelper.EmptyTask); breaker.CircuitState.Should().Be(CircuitState.Closed); onResetCalled.Should().Be(1); } [Fact] - public void Should_not_call_onreset_on_successive_successful_calls() + public async Task Should_not_call_onreset_on_successive_successful_calls() { Action onBreak = (_, _) => { }; bool onResetCalled = false; @@ -900,17 +899,17 @@ public void Should_not_call_onreset_on_successive_successful_calls() onResetCalled.Should().BeFalse(); - breaker.ExecuteAsync(() => TaskHelper.EmptyTask); + await breaker.ExecuteAsync(() => TaskHelper.EmptyTask); breaker.CircuitState.Should().Be(CircuitState.Closed); onResetCalled.Should().BeFalse(); - breaker.ExecuteAsync(() => TaskHelper.EmptyTask); + await breaker.ExecuteAsync(() => TaskHelper.EmptyTask); breaker.CircuitState.Should().Be(CircuitState.Closed); onResetCalled.Should().BeFalse(); } [Fact] - public void Should_call_onhalfopen_when_automatically_transitioning_to_halfopen_due_to_subsequent_execution() + public async Task Should_call_onhalfopen_when_automatically_transitioning_to_halfopen_due_to_subsequent_execution() { int onBreakCalled = 0; int onResetCalled = 0; @@ -930,17 +929,17 @@ public void Should_call_onhalfopen_when_automatically_transitioning_to_halfopen_ onBreakCalled.Should().Be(0); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); onBreakCalled.Should().Be(0); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); onBreakCalled.Should().Be(1); // 2 exception raised, circuit is now open - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); onBreakCalled.Should().Be(1); @@ -949,14 +948,14 @@ public void Should_call_onhalfopen_when_automatically_transitioning_to_halfopen_ onHalfOpenCalled.Should().Be(0); // not yet transitioned to half-open, because we have not queried state // first call after duration is successful, so circuit should reset - breaker.ExecuteAsync(() => TaskHelper.EmptyTask); + await breaker.ExecuteAsync(() => TaskHelper.EmptyTask); onHalfOpenCalled.Should().Be(1); breaker.CircuitState.Should().Be(CircuitState.Closed); onResetCalled.Should().Be(1); } [Fact] - public void Should_call_onhalfopen_when_automatically_transitioning_to_halfopen_due_to_state_read() + public async Task Should_call_onhalfopen_when_automatically_transitioning_to_halfopen_due_to_state_read() { int onBreakCalled = 0; int onResetCalled = 0; @@ -976,17 +975,17 @@ public void Should_call_onhalfopen_when_automatically_transitioning_to_halfopen_ onBreakCalled.Should().Be(0); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); onBreakCalled.Should().Be(0); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); onBreakCalled.Should().Be(1); // 2 exception raised, circuit is now open - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); onBreakCalled.Should().Be(1); @@ -997,7 +996,7 @@ public void Should_call_onhalfopen_when_automatically_transitioning_to_halfopen_ } [Fact] - public void Should_call_onreset_when_manually_resetting_circuit() + public async Task Should_call_onreset_when_manually_resetting_circuit() { int onBreakCalled = 0; int onResetCalled = 0; @@ -1018,21 +1017,21 @@ public void Should_call_onreset_when_manually_resetting_circuit() onBreakCalled.Should().Be(1); breaker.CircuitState.Should().Be(CircuitState.Isolated); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) - .Should().Throw(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)) + .Should().ThrowAsync(); onResetCalled.Should().Be(0); breaker.Reset(); onResetCalled.Should().Be(1); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)).Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => TaskHelper.EmptyTask)).Should().NotThrowAsync(); } #region Tests of supplied parameters to onBreak delegate [Fact] - public void Should_call_onbreak_with_the_last_raised_exception() + public async Task Should_call_onbreak_with_the_last_raised_exception() { Exception passedException = null; @@ -1043,19 +1042,19 @@ public void Should_call_onbreak_with_the_last_raised_exception() .Handle() .CircuitBreakerAsync(2, TimeSpan.FromMinutes(1), onBreak, onReset); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); passedException?.Should().BeOfType(); } [Fact] - public void Should_call_onbreak_with_a_state_of_closed() + public async Task Should_call_onbreak_with_a_state_of_closed() { CircuitState? transitionedState = null; @@ -1067,19 +1066,19 @@ public void Should_call_onbreak_with_a_state_of_closed() .Handle() .CircuitBreakerAsync(2, TimeSpan.FromMinutes(1), onBreak, onReset, onHalfOpen); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); transitionedState?.Should().Be(CircuitState.Closed); } [Fact] - public void Should_call_onbreak_with_a_state_of_half_open() + public async Task Should_call_onbreak_with_a_state_of_half_open() { List transitionedStates = new List(); @@ -1096,17 +1095,17 @@ public void Should_call_onbreak_with_a_state_of_half_open() .Handle() .CircuitBreakerAsync(2, TimeSpan.FromMinutes(1), onBreak, onReset, onHalfOpen); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); // 2 exception raised, circuit is now open - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); SystemClock.UtcNow = () => time.Add(durationOfBreak); @@ -1114,18 +1113,18 @@ public void Should_call_onbreak_with_a_state_of_half_open() // duration has passed, circuit now half open breaker.CircuitState.Should().Be(CircuitState.HalfOpen); // first call after duration raises an exception, so circuit should break again - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); transitionedStates[0].Should().Be(CircuitState.Closed); transitionedStates[1].Should().Be(CircuitState.HalfOpen); } [Fact] - public void Should_rethrow_and_call_onbreak_with_the_last_raised_exception_unwrapped_if_matched_as_inner() + public async Task Should_rethrow_and_call_onbreak_with_the_last_raised_exception_unwrapped_if_matched_as_inner() { Exception passedException = null; @@ -1142,11 +1141,12 @@ public void Should_rethrow_and_call_onbreak_with_the_last_raised_exception_unwra Exception toRaiseAsInner = new DivideByZeroException(); Exception withInner = new AggregateException(toRaiseAsInner); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); - breaker.Awaiting(x => x.RaiseExceptionAsync(withInner)) - .Should().Throw().Which.Should().BeSameAs(toRaiseAsInner); + var ex = await breaker.Awaiting(x => x.RaiseExceptionAsync(withInner)) + .Should().ThrowAsync(); + ex.Which.Should().BeSameAs(toRaiseAsInner); breaker.CircuitState.Should().Be(CircuitState.Open); @@ -1154,7 +1154,7 @@ public void Should_rethrow_and_call_onbreak_with_the_last_raised_exception_unwra } [Fact] - public void Should_call_onbreak_with_the_correct_timespan() + public async Task Should_call_onbreak_with_the_correct_timespan() { TimeSpan? passedBreakTimespan = null; @@ -1167,12 +1167,12 @@ public void Should_call_onbreak_with_the_correct_timespan() .Handle() .CircuitBreakerAsync(2, durationOfBreak, onBreak, onReset); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); passedBreakTimespan.Should().Be(durationOfBreak); @@ -1205,7 +1205,7 @@ public void Should_open_circuit_with_timespan_maxvalue_if_manual_override_open() #region Tests that supplied context is passed to stage-change delegates [Fact] - public void Should_call_onbreak_with_the_passed_context() + public async Task Should_call_onbreak_with_the_passed_context() { IDictionary contextData = null; @@ -1216,12 +1216,12 @@ public void Should_call_onbreak_with_the_passed_context() .Handle() .CircuitBreakerAsync(2, TimeSpan.FromMinutes(1), onBreak, onReset); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); - breaker.Awaiting(x => x.RaiseExceptionAsync( + await breaker.Awaiting(x => x.RaiseExceptionAsync( new { key1 = "value1", key2 = "value2" }.AsDictionary() - )).Should().Throw(); + )).Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); @@ -1247,10 +1247,10 @@ public async Task Should_call_onreset_with_the_passed_context() .Handle() .CircuitBreakerAsync(2, durationOfBreak, onBreak, onReset); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); SystemClock.UtcNow = () => time.Add(durationOfBreak); @@ -1265,7 +1265,7 @@ public async Task Should_call_onreset_with_the_passed_context() } [Fact] - public void Context_should_be_empty_if_execute_not_called_with_any_context_data() + public async Task Context_should_be_empty_if_execute_not_called_with_any_context_data() { IDictionary contextData = new { key1 = "value1", key2 = "value2" }.AsDictionary(); @@ -1276,11 +1276,11 @@ public void Context_should_be_empty_if_execute_not_called_with_any_context_data( .Handle() .CircuitBreakerAsync(2, TimeSpan.FromMinutes(1), onBreak, onReset); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); @@ -1288,7 +1288,7 @@ public void Context_should_be_empty_if_execute_not_called_with_any_context_data( } [Fact] - public void Should_create_new_context_for_each_call_to_execute() + public async Task Should_create_new_context_for_each_call_to_execute() { string contextValue = null; @@ -1304,12 +1304,12 @@ public void Should_create_new_context_for_each_call_to_execute() var durationOfBreak = TimeSpan.FromMinutes(1); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); // 2 exception raised, circuit is now open - breaker.Awaiting(x => x.RaiseExceptionAsync(new { key = "original_value" }.AsDictionary())) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync(new { key = "original_value" }.AsDictionary())) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); contextValue.Should().Be("original_value"); @@ -1320,7 +1320,7 @@ public void Should_create_new_context_for_each_call_to_execute() // but not yet reset // first call after duration is successful, so circuit should reset - breaker.ExecuteAsync(_ => TaskHelper.EmptyTask, new { key = "new_value" }.AsDictionary()); + await breaker.ExecuteAsync(_ => TaskHelper.EmptyTask, new { key = "new_value" }.AsDictionary()); breaker.CircuitState.Should().Be(CircuitState.Closed); contextValue.Should().Be("new_value"); } @@ -1342,14 +1342,14 @@ public void Should_initialise_LastException_to_null_on_creation() } [Fact] - public void Should_set_LastException_on_handling_exception_even_when_not_breaking() + public async Task Should_set_LastException_on_handling_exception_even_when_not_breaking() { var breaker = Policy .Handle() .CircuitBreakerAsync(2, TimeSpan.FromMinutes(1)); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); @@ -1357,7 +1357,7 @@ public void Should_set_LastException_on_handling_exception_even_when_not_breakin } [Fact] - public void Should_set_LastException_on_handling_inner_exception_even_when_not_breaking() + public async Task Should_set_LastException_on_handling_inner_exception_even_when_not_breaking() { var breaker = Policy .HandleInner() @@ -1366,8 +1366,9 @@ public void Should_set_LastException_on_handling_inner_exception_even_when_not_b Exception toRaiseAsInner = new DivideByZeroException(); Exception withInner = new AggregateException(toRaiseAsInner); - breaker.Awaiting(x => x.RaiseExceptionAsync(withInner)) - .Should().Throw().Which.Should().BeSameAs(toRaiseAsInner); + var ex = await breaker.Awaiting(x => x.RaiseExceptionAsync(withInner)) + .Should().ThrowAsync(); + ex.Which.Should().BeSameAs(toRaiseAsInner); breaker.CircuitState.Should().Be(CircuitState.Closed); @@ -1375,17 +1376,17 @@ public void Should_set_LastException_on_handling_inner_exception_even_when_not_b } [Fact] - public void Should_set_LastException_to_last_raised_exception_when_breaking() + public async Task Should_set_LastException_to_last_raised_exception_when_breaking() { var breaker = Policy .Handle() .CircuitBreakerAsync(2, TimeSpan.FromMinutes(1)); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); @@ -1393,17 +1394,17 @@ public void Should_set_LastException_to_last_raised_exception_when_breaking() } [Fact] - public void Should_set_LastException_to_null_on_circuit_reset() + public async Task Should_set_LastException_to_null_on_circuit_reset() { var breaker = Policy .Handle() .CircuitBreakerAsync(2, TimeSpan.FromMinutes(1)); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); @@ -1419,7 +1420,7 @@ public void Should_set_LastException_to_null_on_circuit_reset() #region Cancellation support [Fact] - public void Should_execute_action_when_non_faulting_and_cancellationToken_not_cancelled() + public async Task Should_execute_action_when_non_faulting_and_cancellationToken_not_cancelled() { var durationOfBreak = TimeSpan.FromMinutes(1); var breaker = Policy @@ -1437,14 +1438,14 @@ public void Should_execute_action_when_non_faulting_and_cancellationToken_not_ca AttemptDuringWhichToCancel = null, }; - breaker.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().NotThrow(); + await breaker.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().NotThrowAsync(); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_not_execute_action_when_cancellationToken_cancelled_before_execute() + public async Task Should_not_execute_action_when_cancellationToken_cancelled_before_execute() { var durationOfBreak = TimeSpan.FromMinutes(1); var breaker = Policy @@ -1465,15 +1466,15 @@ public void Should_not_execute_action_when_cancellationToken_cancelled_before_ex cancellationTokenSource.Cancel(); - breaker.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await breaker.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(0); } [Fact] - public void Should_report_cancellation_during_otherwise_non_faulting_action_execution_when_user_delegate_observes_cancellationToken() + public async Task Should_report_cancellation_during_otherwise_non_faulting_action_execution_when_user_delegate_observes_cancellationToken() { var durationOfBreak = TimeSpan.FromMinutes(1); var breaker = Policy @@ -1493,15 +1494,15 @@ public void Should_report_cancellation_during_otherwise_non_faulting_action_exec ActionObservesCancellation = true }; - breaker.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await breaker.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_report_cancellation_during_faulting_action_execution_when_user_delegate_observes_cancellationToken() + public async Task Should_report_cancellation_during_faulting_action_execution_when_user_delegate_observes_cancellationToken() { var durationOfBreak = TimeSpan.FromMinutes(1); var breaker = Policy @@ -1521,15 +1522,15 @@ public void Should_report_cancellation_during_faulting_action_execution_when_use ActionObservesCancellation = true }; - breaker.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await breaker.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_report_faulting_from_faulting_action_execution_when_user_delegate_does_not_observe_cancellation() + public async Task Should_report_faulting_from_faulting_action_execution_when_user_delegate_does_not_observe_cancellation() { var durationOfBreak = TimeSpan.FromMinutes(1); var breaker = Policy @@ -1548,26 +1549,26 @@ public void Should_report_faulting_from_faulting_action_execution_when_user_dele ActionObservesCancellation = false }; - breaker.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_report_cancellation_when_both_open_circuit_and_cancellation() + public async Task Should_report_cancellation_when_both_open_circuit_and_cancellation() { var breaker = Policy .Handle() .CircuitBreakerAsync(1, TimeSpan.FromMinutes(1)); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); - breaker.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw() - .WithMessage("The circuit is now open and is not allowing calls.") - .WithInnerException(); + var ex = await breaker.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync() + .WithMessage("The circuit is now open and is not allowing calls."); + ex.WithInnerException(); // Circuit is now broken. CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); @@ -1585,15 +1586,15 @@ public void Should_report_cancellation_when_both_open_circuit_and_cancellation() ActionObservesCancellation = false }; - breaker.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex2 = await breaker.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex2.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(0); } [Fact] - public void Should_honour_different_cancellationToken_captured_implicitly_by_action() + public async Task Should_honour_different_cancellationToken_captured_implicitly_by_action() { // Before CancellationToken support was built in to Polly, users of the library may have implicitly captured a CancellationToken and used it to cancel actions. For backwards compatibility, Polly should not confuse these with its own CancellationToken; it should distinguish TaskCanceledExceptions thrown with different CancellationTokens. @@ -1612,20 +1613,20 @@ public void Should_honour_different_cancellationToken_captured_implicitly_by_act int attemptsInvoked = 0; - breaker.Awaiting(x => x.ExecuteAsync(async _ => + var ex = await breaker.Awaiting(x => x.ExecuteAsync(async _ => { attemptsInvoked++; await TaskHelper.EmptyTask; implicitlyCapturedActionCancellationToken.ThrowIfCancellationRequested(); }, policyCancellationToken)) - .Should().Throw() - .And.CancellationToken.Should().Be(implicitlyCapturedActionCancellationToken); + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(implicitlyCapturedActionCancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_execute_func_returning_value_when_cancellationToken_not_cancelled() + public async Task Should_execute_func_returning_value_when_cancellationToken_not_cancelled() { var durationOfBreak = TimeSpan.FromMinutes(1); var breaker = Policy @@ -1647,8 +1648,8 @@ public void Should_execute_func_returning_value_when_cancellationToken_not_cance }; Func action = async x => result = await x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, true); - breaker.Awaiting(action) - .Should().NotThrow(); + await breaker.Awaiting(action) + .Should().NotThrowAsync(); result.Should().BeTrue(); @@ -1656,7 +1657,7 @@ public void Should_execute_func_returning_value_when_cancellationToken_not_cance } [Fact] - public void Should_honour_and_report_cancellation_during_func_execution() + public async Task Should_honour_and_report_cancellation_during_func_execution() { var breaker = Policy .Handle() @@ -1678,8 +1679,9 @@ public void Should_honour_and_report_cancellation_during_func_execution() }; Func action = async x => result = await x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, true); - breaker.Awaiting(action) - .Should().Throw().And.CancellationToken.Should().Be(cancellationToken); + var ex = await breaker.Awaiting(action) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); result.Should().Be(null); diff --git a/src/Polly.Specs/CircuitBreaker/CircuitBreakerTResultAsyncSpecs.cs b/src/Polly.Specs/CircuitBreaker/CircuitBreakerTResultAsyncSpecs.cs index a8aa3d864d9..4e897abbf5d 100644 --- a/src/Polly.Specs/CircuitBreaker/CircuitBreakerTResultAsyncSpecs.cs +++ b/src/Polly.Specs/CircuitBreaker/CircuitBreakerTResultAsyncSpecs.cs @@ -113,8 +113,8 @@ public async Task Should_open_circuit_with_the_last_handled_result_after_specifi .Should().Be(ResultPrimitive.Fault); breaker.CircuitState.Should().Be(CircuitState.Open); - breaker.Awaiting(b => b.RaiseResultSequenceAsync(ResultPrimitive.Fault)) - .Should().Throw>() + await breaker.Awaiting(b => b.RaiseResultSequenceAsync(ResultPrimitive.Fault)) + .Should().ThrowAsync>() .WithMessage("The circuit is now open and is not allowing calls.") .Where(e => e.Result == ResultPrimitive.Fault); @@ -138,8 +138,8 @@ public async Task Should_open_circuit_with_the_last_handled_result_after_specifi breaker.CircuitState.Should().Be(CircuitState.Open); // 2 exception or fault raised, circuit is now open - breaker.Awaiting(b => b.RaiseResultSequenceAsync(ResultPrimitive.Fault)) - .Should().Throw>() + await breaker.Awaiting(b => b.RaiseResultSequenceAsync(ResultPrimitive.Fault)) + .Should().ThrowAsync>() .WithMessage("The circuit is now open and is not allowing calls.") .Where(e => e.Result == ResultPrimitive.FaultAgain); breaker.CircuitState.Should().Be(CircuitState.Open); @@ -160,8 +160,8 @@ public async Task Should_open_circuit_with_the_last_handled_result_after_specifi .ResultCode.Should().Be(ResultPrimitive.Fault); breaker.CircuitState.Should().Be(CircuitState.Open); - breaker.Awaiting(b => b.RaiseResultSequenceAsync(new ResultClass(ResultPrimitive.Good))) - .Should().Throw>() + await breaker.Awaiting(b => b.RaiseResultSequenceAsync(new ResultClass(ResultPrimitive.Good))) + .Should().ThrowAsync>() .WithMessage("The circuit is now open and is not allowing calls.") .Where(e => e.Result.ResultCode == ResultPrimitive.Fault); @@ -275,8 +275,8 @@ public async Task Should_halfopen_circuit_after_the_specified_duration_has_passe breaker.CircuitState.Should().Be(CircuitState.Open); // 2 exception or fault raised, circuit is now open - breaker.Awaiting(b => b.RaiseResultSequenceAsync(ResultPrimitive.Fault)) - .Should().Throw(); + await breaker.Awaiting(b => b.RaiseResultSequenceAsync(ResultPrimitive.Fault)) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); SystemClock.UtcNow = () => time.Add(durationOfBreak); @@ -308,8 +308,8 @@ public async Task Should_open_circuit_again_after_the_specified_duration_has_pas breaker.CircuitState.Should().Be(CircuitState.Open); // 2 exception or fault raised, circuit is now open - breaker.Awaiting(b => b.RaiseResultSequenceAsync(ResultPrimitive.Fault)) - .Should().Throw(); + await breaker.Awaiting(b => b.RaiseResultSequenceAsync(ResultPrimitive.Fault)) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); SystemClock.UtcNow = () => time.Add(durationOfBreak); @@ -321,8 +321,8 @@ public async Task Should_open_circuit_again_after_the_specified_duration_has_pas (await breaker.RaiseResultSequenceAsync(ResultPrimitive.Fault)) .Should().Be(ResultPrimitive.Fault); breaker.CircuitState.Should().Be(CircuitState.Open); - breaker.Awaiting(b => b.RaiseResultSequenceAsync(ResultPrimitive.Fault)) - .Should().Throw(); + await breaker.Awaiting(b => b.RaiseResultSequenceAsync(ResultPrimitive.Fault)) + .Should().ThrowAsync(); } [Fact] @@ -346,8 +346,8 @@ public async Task Should_reset_circuit_after_the_specified_duration_has_passed_i breaker.CircuitState.Should().Be(CircuitState.Open); // 2 exception or fault raised, circuit is now open - breaker.Awaiting(b => b.RaiseResultSequenceAsync(ResultPrimitive.Fault)) - .Should().Throw(); + await breaker.Awaiting(b => b.RaiseResultSequenceAsync(ResultPrimitive.Fault)) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); SystemClock.UtcNow = () => time.Add(durationOfBreak); @@ -368,8 +368,8 @@ public async Task Should_reset_circuit_after_the_specified_duration_has_passed_i .Should().Be(ResultPrimitive.Fault); breaker.CircuitState.Should().Be(CircuitState.Open); - breaker.Awaiting(b => b.RaiseResultSequenceAsync(ResultPrimitive.Fault)) - .Should().Throw(); + await breaker.Awaiting(b => b.RaiseResultSequenceAsync(ResultPrimitive.Fault)) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); } @@ -477,9 +477,9 @@ public async Task Should_only_allow_single_execution_on_first_entering_halfopen_ bool firstExecutionActive = false; // First execution in HalfOpen state: we should be able to verify state is HalfOpen as it executes. - Task firstExecution = Task.Factory.StartNew(() => + Task firstExecution = Task.Factory.StartNew(async () => { - breaker.Awaiting(x => x.ExecuteAsync(async () => + await breaker.Awaiting(x => x.ExecuteAsync(async () => { firstDelegateExecutedInHalfOpenState = breaker.CircuitState == CircuitState.HalfOpen; // For readability of test results, we assert on this at test end rather than nested in Task and breaker here. @@ -493,7 +493,7 @@ public async Task Should_only_allow_single_execution_on_first_entering_halfopen_ firstExecutionActive = false; return ResultPrimitive.Good; - })).Should().NotThrow(); + })).Should().NotThrowAsync(); }, TaskCreationOptions.LongRunning); // Attempt a second execution, signalled by the first execution to ensure they overlap: we should be able to verify it doesn't execute, and is rejected by a breaker in a HalfOpen state. @@ -581,9 +581,9 @@ public async Task Should_allow_single_execution_per_break_duration_in_halfopen_s bool firstExecutionActive = false; // First execution in HalfOpen state: we should be able to verify state is HalfOpen as it executes. - Task firstExecution = Task.Factory.StartNew(() => + Task firstExecution = Task.Factory.StartNew(async () => { - breaker.Awaiting(x => x.ExecuteAsync(async () => + await breaker.Awaiting(x => x.ExecuteAsync(async () => { firstDelegateExecutedInHalfOpenState = breaker.CircuitState == CircuitState.HalfOpen; // For readability of test results, we assert on this at test end rather than nested in Task and breaker here. @@ -597,7 +597,7 @@ public async Task Should_allow_single_execution_per_break_duration_in_halfopen_s firstExecutionActive = false; return ResultPrimitive.Good; - })).Should().NotThrow(); + })).Should().NotThrowAsync(); }, TaskCreationOptions.LongRunning); // Attempt a second execution, signalled by the first execution to ensure they overlap; start it one breakDuration later. We should be able to verify it does execute, though the breaker is still in a HalfOpen state. @@ -656,7 +656,7 @@ await breaker.ExecuteAsync(async () => #region Isolate and reset tests [Fact] - public void Should_open_circuit_and_block_calls_if_manual_override_open() + public async Task Should_open_circuit_and_block_calls_if_manual_override_open() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -674,8 +674,8 @@ public void Should_open_circuit_and_block_calls_if_manual_override_open() // circuit manually broken: execution should be blocked; even non-fault-returning executions should not reset circuit bool delegateExecutedWhenBroken = false; - breaker.Awaiting(b => b.ExecuteAsync(() => { delegateExecutedWhenBroken = true; return Task.FromResult(ResultPrimitive.Good); })) - .Should().Throw(); + await breaker.Awaiting(b => b.ExecuteAsync(() => { delegateExecutedWhenBroken = true; return Task.FromResult(ResultPrimitive.Good); })) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Isolated); breaker.LastException.Should().BeOfType(); delegateExecutedWhenBroken.Should().BeFalse(); @@ -683,7 +683,7 @@ public void Should_open_circuit_and_block_calls_if_manual_override_open() } [Fact] - public void Should_hold_circuit_open_despite_elapsed_time_if_manual_override_open() + public async Task Should_hold_circuit_open_despite_elapsed_time_if_manual_override_open() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -702,13 +702,13 @@ public void Should_hold_circuit_open_despite_elapsed_time_if_manual_override_ope breaker.CircuitState.Should().Be(CircuitState.Isolated); bool delegateExecutedWhenBroken = false; - breaker.Awaiting(x => x.ExecuteAsync(() => { delegateExecutedWhenBroken = true; return Task.FromResult(ResultPrimitive.Good); })) - .Should().Throw(); + await breaker.Awaiting(x => x.ExecuteAsync(() => { delegateExecutedWhenBroken = true; return Task.FromResult(ResultPrimitive.Good); })) + .Should().ThrowAsync(); delegateExecutedWhenBroken.Should().BeFalse(); } [Fact] - public void Should_close_circuit_again_on_reset_after_manual_override() + public async Task Should_close_circuit_again_on_reset_after_manual_override() { var time = 1.January(2000); SystemClock.UtcNow = () => time; @@ -722,12 +722,12 @@ public void Should_close_circuit_again_on_reset_after_manual_override() breaker.Isolate(); breaker.CircuitState.Should().Be(CircuitState.Isolated); - breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))) - .Should().Throw(); + await breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))) + .Should().ThrowAsync(); breaker.Reset(); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))).Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))).Should().NotThrowAsync(); } [Fact] @@ -751,15 +751,15 @@ public async Task Should_be_able_to_reset_automatically_opened_circuit_without_s breaker.CircuitState.Should().Be(CircuitState.Open); // 2 exception or fault raised, circuit is now open - breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))) - .Should().Throw(); + await breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); // reset circuit, with no time having passed breaker.Reset(); SystemClock.UtcNow().Should().Be(time); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))).Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))).Should().NotThrowAsync(); } #endregion @@ -845,8 +845,8 @@ public async Task Should_call_onbreak_when_breaking_circuit_first_time_but_not_f onBreakCalled.Should().Be(1); // call through circuit when already broken - should not retrigger onBreak - breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))) - .Should().Throw(); + await breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); onBreakCalled.Should().Be(1); @@ -940,8 +940,8 @@ public async Task Should_call_onreset_when_automatically_closing_circuit_but_not onBreakCalled.Should().Be(1); // 2 exception or fault raised, circuit is now open - breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))) - .Should().Throw(); + await breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); onBreakCalled.Should().Be(1); @@ -953,13 +953,13 @@ public async Task Should_call_onreset_when_automatically_closing_circuit_but_not onResetCalled.Should().Be(0); // first call after duration is successful, so circuit should reset - breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))).Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))).Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); onResetCalled.Should().Be(1); } [Fact] - public void Should_not_call_onreset_on_successive_successful_calls() + public async Task Should_not_call_onreset_on_successive_successful_calls() { Action, TimeSpan> onBreak = (_, _) => { }; bool onResetCalled = false; @@ -971,11 +971,11 @@ public void Should_not_call_onreset_on_successive_successful_calls() onResetCalled.Should().BeFalse(); - breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))).Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))).Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); onResetCalled.Should().BeFalse(); - breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))).Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))).Should().NotThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); onResetCalled.Should().BeFalse(); } @@ -1010,8 +1010,8 @@ public async Task Should_call_onhalfopen_when_automatically_transitioning_to_hal onBreakCalled.Should().Be(1); // 2 exception or fault raised, circuit is now open - breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))) - .Should().Throw(); + await breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); onBreakCalled.Should().Be(1); @@ -1020,8 +1020,8 @@ public async Task Should_call_onhalfopen_when_automatically_transitioning_to_hal onHalfOpenCalled.Should().Be(0); // not yet transitioned to half-open, because we have not queried state // first call after duration is successful, so circuit should reset - breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))) + .Should().NotThrowAsync(); onHalfOpenCalled.Should().Be(1); breaker.CircuitState.Should().Be(CircuitState.Closed); onResetCalled.Should().Be(1); @@ -1057,8 +1057,8 @@ public async Task Should_call_onhalfopen_when_automatically_transitioning_to_hal onBreakCalled.Should().Be(1); // 2 exception or fault raised, circuit is now open - breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))) - .Should().Throw(); + await breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); onBreakCalled.Should().Be(1); @@ -1069,7 +1069,7 @@ public async Task Should_call_onhalfopen_when_automatically_transitioning_to_hal } [Fact] - public void Should_call_onreset_when_manually_resetting_circuit() + public async Task Should_call_onreset_when_manually_resetting_circuit() { int onBreakCalled = 0; int onResetCalled = 0; @@ -1090,16 +1090,16 @@ public void Should_call_onreset_when_manually_resetting_circuit() onBreakCalled.Should().Be(1); breaker.CircuitState.Should().Be(CircuitState.Isolated); - breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))) - .Should().Throw(); + await breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))) + .Should().ThrowAsync(); onResetCalled.Should().Be(0); breaker.Reset(); onResetCalled.Should().Be(1); breaker.CircuitState.Should().Be(CircuitState.Closed); - breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))) - .Should().NotThrow(); + await breaker.Awaiting(x => x.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good))) + .Should().NotThrowAsync(); } #region Tests of supplied parameters to onBreak delegate @@ -1411,7 +1411,7 @@ public async Task Should_execute_action_when_non_faulting_and_cancellationToken_ } [Fact] - public void Should_not_execute_action_when_cancellationToken_cancelled_before_execute() + public async Task Should_not_execute_action_when_cancellationToken_cancelled_before_execute() { var durationOfBreak = TimeSpan.FromMinutes(1); var breaker = Policy @@ -1431,18 +1431,18 @@ public void Should_not_execute_action_when_cancellationToken_cancelled_before_ex cancellationTokenSource.Cancel(); - breaker.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, + var ex = await breaker.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, ResultPrimitive.Fault, ResultPrimitive.Fault, ResultPrimitive.Good)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(0); } [Fact] - public void Should_report_cancellation_during_otherwise_non_faulting_action_execution_when_user_delegate_observes_cancellationToken() + public async Task Should_report_cancellation_during_otherwise_non_faulting_action_execution_when_user_delegate_observes_cancellationToken() { var durationOfBreak = TimeSpan.FromMinutes(1); var breaker = Policy @@ -1461,17 +1461,17 @@ public void Should_report_cancellation_during_otherwise_non_faulting_action_exec ActionObservesCancellation = true }; - breaker.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, + var ex = await breaker.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, ResultPrimitive.Good, ResultPrimitive.Good)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_report_cancellation_during_faulting_action_execution_when_user_delegate_observes_cancellationToken() + public async Task Should_report_cancellation_during_faulting_action_execution_when_user_delegate_observes_cancellationToken() { var durationOfBreak = TimeSpan.FromMinutes(1); var breaker = Policy @@ -1490,11 +1490,11 @@ public void Should_report_cancellation_during_faulting_action_execution_when_use ActionObservesCancellation = true }; - breaker.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, + var ex = await breaker.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, ResultPrimitive.Fault, ResultPrimitive.Good)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } @@ -1535,8 +1535,8 @@ public async Task Should_report_cancellation_when_both_open_circuit_and_cancella (await breaker.RaiseResultSequenceAsync(ResultPrimitive.Fault)) .Should().Be(ResultPrimitive.Fault); - breaker.Awaiting(x => x.RaiseResultSequenceAsync(ResultPrimitive.Fault)) - .Should().Throw() + var ex = await breaker.Awaiting(x => x.RaiseResultSequenceAsync(ResultPrimitive.Fault)) + .Should().ThrowAsync() .WithMessage("The circuit is now open and is not allowing calls."); // Circuit is now broken. @@ -1554,17 +1554,17 @@ public async Task Should_report_cancellation_when_both_open_circuit_and_cancella ActionObservesCancellation = false }; - breaker.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, + var ex2 = await breaker.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, ResultPrimitive.Fault, ResultPrimitive.Good)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + .Should().ThrowAsync(); + ex2.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(0); } [Fact] - public void Should_honour_different_cancellationToken_captured_implicitly_by_action() + public async Task Should_honour_different_cancellationToken_captured_implicitly_by_action() { // Before CancellationToken support was built in to Polly, users of the library may have implicitly captured a CancellationToken and used it to cancel actions. For backwards compatibility, Polly should not confuse these with its own CancellationToken; it should distinguish TaskCanceledExceptions thrown with different CancellationTokens. @@ -1583,15 +1583,15 @@ public void Should_honour_different_cancellationToken_captured_implicitly_by_act int attemptsInvoked = 0; - breaker.Awaiting(x => x.ExecuteAsync(async _ => + var ex = await breaker.Awaiting(x => x.ExecuteAsync(async _ => { attemptsInvoked++; await TaskHelper.EmptyTask; implicitlyCapturedActionCancellationToken.ThrowIfCancellationRequested(); return ResultPrimitive.Good; }, policyCancellationToken)) - .Should().Throw() - .And.CancellationToken.Should().Be(implicitlyCapturedActionCancellationToken); + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(implicitlyCapturedActionCancellationToken); attemptsInvoked.Should().Be(1); } diff --git a/src/Polly.Specs/Custom/CustomAsyncSpecs.cs b/src/Polly.Specs/Custom/CustomAsyncSpecs.cs index 82da36f3d21..9f2c7493e11 100644 --- a/src/Polly.Specs/Custom/CustomAsyncSpecs.cs +++ b/src/Polly.Specs/Custom/CustomAsyncSpecs.cs @@ -26,15 +26,15 @@ public void Should_be_able_to_construct_active_policy() } [Fact] - public void Active_policy_should_execute() + public async Task Active_policy_should_execute() { bool preExecuted = false; AsyncPreExecutePolicy policy = AsyncPreExecutePolicy.CreateAsync(() => { preExecuted = true; return Task.CompletedTask; }); bool executed = false; - policy.Awaiting(x => x.ExecuteAsync(() => { executed = true; return Task.CompletedTask; })) - .Should().NotThrow(); + await policy.Awaiting(x => x.ExecuteAsync(() => { executed = true; return Task.CompletedTask; })) + .Should().NotThrowAsync(); executed.Should().BeTrue(); preExecuted.Should().BeTrue(); @@ -57,7 +57,7 @@ public void Should_be_able_to_construct_reactive_policy() } [Fact] - public void Reactive_policy_should_handle_exception() + public async Task Reactive_policy_should_handle_exception() { Exception handled = null; AsyncAddBehaviourIfHandlePolicy policy = Policy.Handle().WithBehaviourAsync(async ex => { handled = ex; await Task.CompletedTask; }); @@ -65,19 +65,20 @@ public void Reactive_policy_should_handle_exception() Exception toThrow = new InvalidOperationException(); bool executed = false; - policy.Awaiting(x => x.ExecuteAsync(() => + var ex = await policy.Awaiting(x => x.ExecuteAsync(() => { executed = true; throw toThrow; })) - .Should().Throw().Which.Should().Be(toThrow); + .Should().ThrowAsync(); + ex.Which.Should().Be(toThrow); executed.Should().BeTrue(); handled.Should().Be(toThrow); } [Fact] - public void Reactive_policy_should_be_able_to_ignore_unhandled_exception() + public async Task Reactive_policy_should_be_able_to_ignore_unhandled_exception() { Exception handled = null; AsyncAddBehaviourIfHandlePolicy policy = Policy.Handle().WithBehaviourAsync(async ex => { handled = ex; await Task.CompletedTask; }); @@ -85,12 +86,13 @@ public void Reactive_policy_should_be_able_to_ignore_unhandled_exception() Exception toThrow = new NotImplementedException(); bool executed = false; - policy.Awaiting(x => x.ExecuteAsync(() => + var ex = await policy.Awaiting(x => x.ExecuteAsync(() => { executed = true; throw toThrow; })) - .Should().Throw().Which.Should().Be(toThrow); + .Should().ThrowAsync(); + ex.Which.Should().Be(toThrow); executed.Should().BeTrue(); handled.Should().Be(null); diff --git a/src/Polly.Specs/Custom/CustomTResultAsyncSpecs.cs b/src/Polly.Specs/Custom/CustomTResultAsyncSpecs.cs index f48cfffd514..539de07c8d9 100644 --- a/src/Polly.Specs/Custom/CustomTResultAsyncSpecs.cs +++ b/src/Polly.Specs/Custom/CustomTResultAsyncSpecs.cs @@ -27,14 +27,14 @@ public void Should_be_able_to_construct_active_policy() } [Fact] - public void Active_policy_should_execute() + public async Task Active_policy_should_execute() { bool preExecuted = false; AsyncPreExecutePolicy policy = AsyncPreExecutePolicy.CreateAsync(() => { preExecuted = true; return Task.CompletedTask; }); bool executed = false; - policy.Awaiting(x => x.ExecuteAsync(async () => { executed = true; await Task.CompletedTask; return ResultPrimitive.Undefined; })) - .Should().NotThrow(); + await policy.Awaiting(x => x.ExecuteAsync(async () => { executed = true; await Task.CompletedTask; return ResultPrimitive.Undefined; })) + .Should().NotThrowAsync(); executed.Should().BeTrue(); preExecuted.Should().BeTrue(); diff --git a/src/Polly.Specs/Fallback/FallbackAsyncSpecs.cs b/src/Polly.Specs/Fallback/FallbackAsyncSpecs.cs index a71db753b4a..5989fb1099d 100644 --- a/src/Polly.Specs/Fallback/FallbackAsyncSpecs.cs +++ b/src/Polly.Specs/Fallback/FallbackAsyncSpecs.cs @@ -104,7 +104,7 @@ public async Task Should_not_execute_fallback_when_executed_delegate_does_not_th } [Fact] - public void Should_not_execute_fallback_when_executed_delegate_throws_exception_not_handled_by_policy() + public async Task Should_not_execute_fallback_when_executed_delegate_throws_exception_not_handled_by_policy() { bool fallbackActionExecuted = false; Func fallbackActionAsync = _ => { fallbackActionExecuted = true; return TaskHelper.EmptyTask; }; @@ -113,13 +113,13 @@ public void Should_not_execute_fallback_when_executed_delegate_throws_exception_ .Handle() .FallbackAsync(fallbackActionAsync); - fallbackPolicy.Awaiting(x => x.RaiseExceptionAsync()).Should().Throw(); + await fallbackPolicy.Awaiting(x => x.RaiseExceptionAsync()).Should().ThrowAsync(); fallbackActionExecuted.Should().BeFalse(); } [Fact] - public void Should_execute_fallback_when_executed_delegate_throws_exception_handled_by_policy() + public async Task Should_execute_fallback_when_executed_delegate_throws_exception_handled_by_policy() { bool fallbackActionExecuted = false; Func fallbackActionAsync = _ => { fallbackActionExecuted = true; return TaskHelper.EmptyTask; }; @@ -128,14 +128,14 @@ public void Should_execute_fallback_when_executed_delegate_throws_exception_hand .Handle() .FallbackAsync(fallbackActionAsync); - fallbackPolicy.Awaiting(x => x.RaiseExceptionAsync()).Should().NotThrow(); + await fallbackPolicy.Awaiting(x => x.RaiseExceptionAsync()).Should().NotThrowAsync(); fallbackActionExecuted.Should().BeTrue(); } [Fact] - public void Should_execute_fallback_when_executed_delegate_throws_one_of_exceptions_handled_by_policy() + public async Task Should_execute_fallback_when_executed_delegate_throws_one_of_exceptions_handled_by_policy() { bool fallbackActionExecuted = false; Func fallbackActionAsync = _ => { fallbackActionExecuted = true; return TaskHelper.EmptyTask; }; @@ -145,14 +145,14 @@ public void Should_execute_fallback_when_executed_delegate_throws_one_of_excepti .Or() .FallbackAsync(fallbackActionAsync); - fallbackPolicy.Awaiting(x => x.RaiseExceptionAsync()).Should().NotThrow(); + await fallbackPolicy.Awaiting(x => x.RaiseExceptionAsync()).Should().NotThrowAsync(); fallbackActionExecuted.Should().BeTrue(); } [Fact] - public void Should_not_execute_fallback_when_executed_delegate_throws_exception_not_one_of_exceptions_handled_by_policy() + public async Task Should_not_execute_fallback_when_executed_delegate_throws_exception_not_one_of_exceptions_handled_by_policy() { bool fallbackActionExecuted = false; Func fallbackActionAsync = _ => { fallbackActionExecuted = true; return TaskHelper.EmptyTask; }; @@ -162,13 +162,13 @@ public void Should_not_execute_fallback_when_executed_delegate_throws_exception_ .Or() .FallbackAsync(fallbackActionAsync); - fallbackPolicy.Awaiting(x => x.RaiseExceptionAsync()).Should().Throw(); + await fallbackPolicy.Awaiting(x => x.RaiseExceptionAsync()).Should().ThrowAsync(); fallbackActionExecuted.Should().BeFalse(); } [Fact] - public void Should_not_execute_fallback_when_exception_thrown_does_not_match_handling_predicates() + public async Task Should_not_execute_fallback_when_exception_thrown_does_not_match_handling_predicates() { bool fallbackActionExecuted = false; Func fallbackActionAsync = _ => { fallbackActionExecuted = true; return TaskHelper.EmptyTask; }; @@ -177,13 +177,13 @@ public void Should_not_execute_fallback_when_exception_thrown_does_not_match_han .Handle(_ => false) .FallbackAsync(fallbackActionAsync); - fallbackPolicy.Awaiting(x => x.RaiseExceptionAsync()).Should().Throw(); + await fallbackPolicy.Awaiting(x => x.RaiseExceptionAsync()).Should().ThrowAsync(); fallbackActionExecuted.Should().BeFalse(); } [Fact] - public void Should_not_execute_fallback_when_exception_thrown_does_not_match_any_of_handling_predicates() + public async Task Should_not_execute_fallback_when_exception_thrown_does_not_match_any_of_handling_predicates() { bool fallbackActionExecuted = false; Func fallbackActionAsync = _ => { fallbackActionExecuted = true; return TaskHelper.EmptyTask; }; @@ -193,13 +193,13 @@ public void Should_not_execute_fallback_when_exception_thrown_does_not_match_any .Or(_ => false) .FallbackAsync(fallbackActionAsync); - fallbackPolicy.Awaiting(x => x.RaiseExceptionAsync()).Should().Throw(); + await fallbackPolicy.Awaiting(x => x.RaiseExceptionAsync()).Should().ThrowAsync(); fallbackActionExecuted.Should().BeFalse(); } [Fact] - public void Should_execute_fallback_when_exception_thrown_matches_handling_predicates() + public async Task Should_execute_fallback_when_exception_thrown_matches_handling_predicates() { bool fallbackActionExecuted = false; Func fallbackActionAsync = _ => { fallbackActionExecuted = true; return TaskHelper.EmptyTask; }; @@ -208,14 +208,14 @@ public void Should_execute_fallback_when_exception_thrown_matches_handling_predi .Handle(_ => true) .FallbackAsync(fallbackActionAsync); - fallbackPolicy.Awaiting(x => x.RaiseExceptionAsync()).Should().NotThrow(); + await fallbackPolicy.Awaiting(x => x.RaiseExceptionAsync()).Should().NotThrowAsync(); fallbackActionExecuted.Should().BeTrue(); } [Fact] - public void Should_execute_fallback_when_exception_thrown_matches_one_of_handling_predicates() + public async Task Should_execute_fallback_when_exception_thrown_matches_one_of_handling_predicates() { bool fallbackActionExecuted = false; Func fallbackActionAsync = _ => { fallbackActionExecuted = true; return TaskHelper.EmptyTask; }; @@ -225,13 +225,13 @@ public void Should_execute_fallback_when_exception_thrown_matches_one_of_handlin .Or() .FallbackAsync(fallbackActionAsync); - fallbackPolicy.Awaiting(x => x.RaiseExceptionAsync()).Should().NotThrow(); + await fallbackPolicy.Awaiting(x => x.RaiseExceptionAsync()).Should().NotThrowAsync(); fallbackActionExecuted.Should().BeTrue(); } [Fact] - public void Should_not_handle_exception_thrown_by_fallback_delegate_even_if_is_exception_handled_by_policy() + public async Task Should_not_handle_exception_thrown_by_fallback_delegate_even_if_is_exception_handled_by_policy() { bool fallbackActionExecuted = false; Func fallbackActionAsync = _ => @@ -244,20 +244,21 @@ public void Should_not_handle_exception_thrown_by_fallback_delegate_even_if_is_e .Handle() .FallbackAsync(fallbackActionAsync); - fallbackPolicy.Awaiting(x => x.RaiseExceptionAsync((e, _) => e.HelpLink = "FromExecuteDelegate")) - .Should().Throw().And.HelpLink.Should().Be("FromFallbackAction"); + var ex = await fallbackPolicy.Awaiting(x => x.RaiseExceptionAsync((e, _) => e.HelpLink = "FromExecuteDelegate")) + .Should().ThrowAsync(); + ex.And.HelpLink.Should().Be("FromFallbackAction"); fallbackActionExecuted.Should().BeTrue(); } [Fact] - public void Should_throw_for_generic_method_execution_on_non_generic_policy() + public async Task Should_throw_for_generic_method_execution_on_non_generic_policy() { var fallbackPolicy = Policy .Handle() .FallbackAsync(_ => TaskHelper.EmptyTask); - fallbackPolicy.Awaiting(p => p.ExecuteAsync(() => Task.FromResult(0))).Should().Throw(); + await fallbackPolicy.Awaiting(p => p.ExecuteAsync(() => Task.FromResult(0))).Should().ThrowAsync(); } #endregion @@ -307,7 +308,7 @@ public async Task Should_not_call_onFallback_when_executed_delegate_does_not_thr #region Context passing tests [Fact] - public void Should_call_onFallback_with_the_passed_context() + public async Task Should_call_onFallback_with_the_passed_context() { Func fallbackActionAsync = (_, _) => TaskHelper.EmptyTask; @@ -319,9 +320,9 @@ public void Should_call_onFallback_with_the_passed_context() .Handle() .FallbackAsync(fallbackActionAsync, onFallbackAsync); - fallbackPolicy.Awaiting(p => p.ExecuteAsync(_ => throw new ArgumentNullException(), + await fallbackPolicy.Awaiting(p => p.ExecuteAsync(_ => throw new ArgumentNullException(), new { key1 = "value1", key2 = "value2" }.AsDictionary())) - .Should().NotThrow(); + .Should().NotThrowAsync(); contextData.Should() .ContainKeys("key1", "key2").And @@ -329,7 +330,7 @@ public void Should_call_onFallback_with_the_passed_context() } [Fact] - public void Should_call_onFallback_with_the_passed_context_when_execute_and_capture() + public async Task Should_call_onFallback_with_the_passed_context_when_execute_and_capture() { Func fallbackActionAsync = (_, _) => TaskHelper.EmptyTask; @@ -341,9 +342,9 @@ public void Should_call_onFallback_with_the_passed_context_when_execute_and_capt .Handle() .FallbackAsync(fallbackActionAsync, onFallbackAsync); - fallbackPolicy.Awaiting(p => p.ExecuteAndCaptureAsync(_ => throw new ArgumentNullException(), + await fallbackPolicy.Awaiting(p => p.ExecuteAndCaptureAsync(_ => throw new ArgumentNullException(), new { key1 = "value1", key2 = "value2" }.AsDictionary())) - .Should().NotThrow(); + .Should().NotThrowAsync(); contextData.Should() .ContainKeys("key1", "key2").And @@ -351,7 +352,7 @@ public void Should_call_onFallback_with_the_passed_context_when_execute_and_capt } [Fact] - public void Should_call_onFallback_with_independent_context_for_independent_calls() + public async Task Should_call_onFallback_with_independent_context_for_independent_calls() { Func fallbackActionAsync = (_, _) => TaskHelper.EmptyTask; @@ -364,11 +365,11 @@ public void Should_call_onFallback_with_independent_context_for_independent_call .Or() .FallbackAsync(fallbackActionAsync, onFallbackAsync); - fallbackPolicy.Awaiting(p => p.ExecuteAsync(_ => throw new ArgumentNullException(), new { key = "value1" }.AsDictionary())) - .Should().NotThrow(); + await fallbackPolicy.Awaiting(p => p.ExecuteAsync(_ => throw new ArgumentNullException(), new { key = "value1" }.AsDictionary())) + .Should().NotThrowAsync(); - fallbackPolicy.Awaiting(p => p.ExecuteAsync(_ => throw new DivideByZeroException(), new { key = "value2" }.AsDictionary())) - .Should().NotThrow(); + await fallbackPolicy.Awaiting(p => p.ExecuteAsync(_ => throw new DivideByZeroException(), new { key = "value2" }.AsDictionary())) + .Should().NotThrowAsync(); contextData.Count.Should().Be(2); contextData.Keys.Should().Contain(typeof(ArgumentNullException)); @@ -399,7 +400,7 @@ public async Task Context_should_be_empty_if_execute_not_called_with_any_context } [Fact] - public void Should_call_fallbackAction_with_the_passed_context() + public async Task Should_call_fallbackAction_with_the_passed_context() { IDictionary contextData = null; @@ -411,9 +412,9 @@ public void Should_call_fallbackAction_with_the_passed_context() .Handle() .FallbackAsync(fallbackActionAsync, onFallbackAsync); - fallbackPolicy.Awaiting(p => p.ExecuteAsync(_ => throw new ArgumentNullException(), + await fallbackPolicy.Awaiting(p => p.ExecuteAsync(_ => throw new ArgumentNullException(), new { key1 = "value1", key2 = "value2" }.AsDictionary())) - .Should().NotThrow(); + .Should().NotThrowAsync(); contextData.Should() .ContainKeys("key1", "key2").And @@ -421,7 +422,7 @@ public void Should_call_fallbackAction_with_the_passed_context() } [Fact] - public void Should_call_fallbackAction_with_the_passed_context_when_execute_and_capture() + public async Task Should_call_fallbackAction_with_the_passed_context_when_execute_and_capture() { IDictionary contextData = null; @@ -433,9 +434,9 @@ public void Should_call_fallbackAction_with_the_passed_context_when_execute_and_ .Handle() .FallbackAsync(fallbackActionAsync, onFallbackAsync); - fallbackPolicy.Awaiting(p => p.ExecuteAndCaptureAsync(_ => throw new ArgumentNullException(), + await fallbackPolicy.Awaiting(p => p.ExecuteAndCaptureAsync(_ => throw new ArgumentNullException(), new { key1 = "value1", key2 = "value2" }.AsDictionary())) - .Should().NotThrow(); + .Should().NotThrowAsync(); contextData.Should() .ContainKeys("key1", "key2").And @@ -468,7 +469,7 @@ public async Task Context_should_be_empty_at_fallbackAction_if_execute_not_calle #region Exception passing tests [Fact] - public void Should_call_fallbackAction_with_the_exception() + public async Task Should_call_fallbackAction_with_the_exception() { Exception fallbackException = null; @@ -481,14 +482,14 @@ public void Should_call_fallbackAction_with_the_exception() .FallbackAsync(fallbackFunc, onFallback); Exception instanceToThrow = new ArgumentNullException("myParam"); - fallbackPolicy.Awaiting(p => p.RaiseExceptionAsync(instanceToThrow)) - .Should().NotThrow(); + await fallbackPolicy.Awaiting(p => p.RaiseExceptionAsync(instanceToThrow)) + .Should().NotThrowAsync(); fallbackException.Should().Be(instanceToThrow); } [Fact] - public void Should_call_fallbackAction_with_the_exception_when_execute_and_capture() + public async Task Should_call_fallbackAction_with_the_exception_when_execute_and_capture() { Exception fallbackException = null; @@ -500,15 +501,15 @@ public void Should_call_fallbackAction_with_the_exception_when_execute_and_captu .Handle() .FallbackAsync(fallbackFunc, onFallback); - fallbackPolicy.Awaiting(p => p.ExecuteAndCaptureAsync(() => throw new ArgumentNullException())) - .Should().NotThrow(); + await fallbackPolicy.Awaiting(p => p.ExecuteAndCaptureAsync(() => throw new ArgumentNullException())) + .Should().NotThrowAsync(); fallbackException.Should().NotBeNull() .And.BeOfType(typeof(ArgumentNullException)); } [Fact] - public void Should_call_fallbackAction_with_the_matched_inner_exception_unwrapped() + public async Task Should_call_fallbackAction_with_the_matched_inner_exception_unwrapped() { Exception fallbackException = null; @@ -522,14 +523,14 @@ public void Should_call_fallbackAction_with_the_matched_inner_exception_unwrappe Exception instanceToCapture = new ArgumentNullException("myParam"); Exception instanceToThrow = new Exception(String.Empty, instanceToCapture); - fallbackPolicy.Awaiting(p => p.RaiseExceptionAsync(instanceToThrow)) - .Should().NotThrow(); + await fallbackPolicy.Awaiting(p => p.RaiseExceptionAsync(instanceToThrow)) + .Should().NotThrowAsync(); fallbackException.Should().Be(instanceToCapture); } [Fact] - public void Should_call_fallbackAction_with_the_matched_inner_of_aggregate_exception_unwrapped() + public async Task Should_call_fallbackAction_with_the_matched_inner_of_aggregate_exception_unwrapped() { Exception fallbackException = null; @@ -543,14 +544,14 @@ public void Should_call_fallbackAction_with_the_matched_inner_of_aggregate_excep Exception instanceToCapture = new ArgumentNullException("myParam"); Exception instanceToThrow = new AggregateException(instanceToCapture); - fallbackPolicy.Awaiting(p => p.RaiseExceptionAsync(instanceToThrow)) - .Should().NotThrow(); + await fallbackPolicy.Awaiting(p => p.RaiseExceptionAsync(instanceToThrow)) + .Should().NotThrowAsync(); fallbackException.Should().Be(instanceToCapture); } [Fact] - public void Should_not_call_fallbackAction_with_the_exception_if_exception_unhandled() + public async Task Should_not_call_fallbackAction_with_the_exception_if_exception_unhandled() { Exception fallbackException = null; @@ -562,8 +563,8 @@ public void Should_not_call_fallbackAction_with_the_exception_if_exception_unhan .Handle() .FallbackAsync(fallbackFunc, onFallback); - fallbackPolicy.Awaiting(p => p.ExecuteAsync(() => throw new ArgumentNullException())) - .Should().Throw(); + await fallbackPolicy.Awaiting(p => p.ExecuteAsync(() => throw new ArgumentNullException())) + .Should().ThrowAsync(); fallbackException.Should().BeNull(); } @@ -573,7 +574,7 @@ public void Should_not_call_fallbackAction_with_the_exception_if_exception_unhan #region Cancellation tests [Fact] - public void Should_execute_action_when_non_faulting_and_cancellationToken_not_cancelled() + public async Task Should_execute_action_when_non_faulting_and_cancellationToken_not_cancelled() { bool fallbackActionExecuted = false; Func fallbackActionAsync = _ => { fallbackActionExecuted = true; return TaskHelper.EmptyTask; }; @@ -594,15 +595,15 @@ public void Should_execute_action_when_non_faulting_and_cancellationToken_not_ca AttemptDuringWhichToCancel = null, }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().NotThrowAsync(); attemptsInvoked.Should().Be(1); fallbackActionExecuted.Should().BeFalse(); } [Fact] - public void Should_execute_fallback_when_faulting_and_cancellationToken_not_cancelled() + public async Task Should_execute_fallback_when_faulting_and_cancellationToken_not_cancelled() { bool fallbackActionExecuted = false; Func fallbackActionAsync = _ => { fallbackActionExecuted = true; return TaskHelper.EmptyTask; }; @@ -623,15 +624,15 @@ public void Should_execute_fallback_when_faulting_and_cancellationToken_not_canc AttemptDuringWhichToCancel = null, }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().NotThrowAsync(); attemptsInvoked.Should().Be(1); fallbackActionExecuted.Should().BeTrue(); } [Fact] - public void Should_not_execute_action_when_cancellationToken_cancelled_before_execute() + public async Task Should_not_execute_action_when_cancellationToken_cancelled_before_execute() { bool fallbackActionExecuted = false; Func fallbackActionAsync = _ => { fallbackActionExecuted = true; return TaskHelper.EmptyTask; }; @@ -654,9 +655,9 @@ public void Should_not_execute_action_when_cancellationToken_cancelled_before_ex cancellationTokenSource.Cancel(); - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(0); fallbackActionExecuted.Should().BeFalse(); @@ -664,7 +665,7 @@ public void Should_not_execute_action_when_cancellationToken_cancelled_before_ex } [Fact] - public void Should_report_cancellation_and_not_execute_fallback_during_otherwise_non_faulting_action_execution_when_user_delegate_observes_cancellationToken_and_fallback_does_not_handle_cancellations() + public async Task Should_report_cancellation_and_not_execute_fallback_during_otherwise_non_faulting_action_execution_when_user_delegate_observes_cancellationToken_and_fallback_does_not_handle_cancellations() { bool fallbackActionExecuted = false; Func fallbackActionAsync = _ => { fallbackActionExecuted = true; return TaskHelper.EmptyTask; }; @@ -686,16 +687,16 @@ public void Should_report_cancellation_and_not_execute_fallback_during_otherwise ActionObservesCancellation = true }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); fallbackActionExecuted.Should().BeFalse(); } [Fact] - public void Should_handle_cancellation_and_execute_fallback_during_otherwise_non_faulting_action_execution_when_user_delegate_observes_cancellationToken_and_fallback_handles_cancellations() + public async Task Should_handle_cancellation_and_execute_fallback_during_otherwise_non_faulting_action_execution_when_user_delegate_observes_cancellationToken_and_fallback_handles_cancellations() { bool fallbackActionExecuted = false; Func fallbackActionAsync = _ => { fallbackActionExecuted = true; return TaskHelper.EmptyTask; }; @@ -718,15 +719,15 @@ public void Should_handle_cancellation_and_execute_fallback_during_otherwise_non ActionObservesCancellation = true }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().NotThrowAsync(); attemptsInvoked.Should().Be(1); fallbackActionExecuted.Should().BeTrue(); } [Fact] - public void Should_not_report_cancellation_and_not_execute_fallback_if_non_faulting_action_execution_completes_and_user_delegate_does_not_observe_the_set_cancellationToken() + public async Task Should_not_report_cancellation_and_not_execute_fallback_if_non_faulting_action_execution_completes_and_user_delegate_does_not_observe_the_set_cancellationToken() { bool fallbackActionExecuted = false; @@ -749,15 +750,15 @@ public void Should_not_report_cancellation_and_not_execute_fallback_if_non_fault ActionObservesCancellation = false }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().NotThrowAsync(); attemptsInvoked.Should().Be(1); fallbackActionExecuted.Should().BeFalse(); } [Fact] - public void Should_report_unhandled_fault_and_not_execute_fallback_if_action_execution_raises_unhandled_fault_and_user_delegate_does_not_observe_the_set_cancellationToken() + public async Task Should_report_unhandled_fault_and_not_execute_fallback_if_action_execution_raises_unhandled_fault_and_user_delegate_does_not_observe_the_set_cancellationToken() { bool fallbackActionExecuted = false; @@ -781,15 +782,15 @@ public void Should_report_unhandled_fault_and_not_execute_fallback_if_action_exe ActionObservesCancellation = false }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); attemptsInvoked.Should().Be(1); fallbackActionExecuted.Should().BeFalse(); } [Fact] - public void Should_handle_handled_fault_and_execute_fallback_following_faulting_action_execution_when_user_delegate_does_not_observe_cancellationToken() + public async Task Should_handle_handled_fault_and_execute_fallback_following_faulting_action_execution_when_user_delegate_does_not_observe_cancellationToken() { bool fallbackActionExecuted = false; @@ -813,8 +814,8 @@ public void Should_handle_handled_fault_and_execute_fallback_following_faulting_ ActionObservesCancellation = false }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().NotThrowAsync(); attemptsInvoked.Should().Be(1); fallbackActionExecuted.Should().BeTrue(); diff --git a/src/Polly.Specs/Fallback/FallbackTResultAsyncSpecs.cs b/src/Polly.Specs/Fallback/FallbackTResultAsyncSpecs.cs index 5c88b6fa565..f5bd03da6d0 100644 --- a/src/Polly.Specs/Fallback/FallbackTResultAsyncSpecs.cs +++ b/src/Polly.Specs/Fallback/FallbackTResultAsyncSpecs.cs @@ -460,7 +460,7 @@ public void Should_call_fallbackAction_with_the_passed_context() } [Fact] - public void Should_call_fallbackAction_with_the_passed_context_when_execute_and_capture() + public async Task Should_call_fallbackAction_with_the_passed_context_when_execute_and_capture() { IDictionary contextData = null; @@ -472,9 +472,9 @@ public void Should_call_fallbackAction_with_the_passed_context_when_execute_and_ .HandleResult(ResultPrimitive.Fault) .FallbackAsync(fallbackActionAsync, onFallbackAsync); - fallbackPolicy.Awaiting(p => p.ExecuteAndCaptureAsync(_ => Task.FromResult(ResultPrimitive.Fault), + await fallbackPolicy.Awaiting(p => p.ExecuteAndCaptureAsync(_ => Task.FromResult(ResultPrimitive.Fault), new { key1 = "value1", key2 = "value2" }.AsDictionary())) - .Should().NotThrow(); + .Should().NotThrowAsync(); contextData.Should() .ContainKeys("key1", "key2").And @@ -636,7 +636,7 @@ public async Task Should_execute_fallback_when_faulting_and_cancellationToken_no } [Fact] - public void Should_not_execute_action_when_cancellationToken_cancelled_before_execute() + public async Task Should_not_execute_action_when_cancellationToken_cancelled_before_execute() { bool fallbackActionExecuted = false; Func> fallbackAction = _ => { fallbackActionExecuted = true; return Task.FromResult(ResultPrimitive.Substitute); }; @@ -659,9 +659,9 @@ public void Should_not_execute_action_when_cancellationToken_cancelled_before_ex cancellationTokenSource.Cancel(); - policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, ResultPrimitive.Fault)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, ResultPrimitive.Fault)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(0); fallbackActionExecuted.Should().BeFalse(); @@ -669,7 +669,7 @@ public void Should_not_execute_action_when_cancellationToken_cancelled_before_ex } [Fact] - public void Should_report_cancellation_and_not_execute_fallback_during_otherwise_non_faulting_action_execution_when_user_delegate_observes_cancellationToken_and_fallback_does_not_handle_cancellations() + public async Task Should_report_cancellation_and_not_execute_fallback_during_otherwise_non_faulting_action_execution_when_user_delegate_observes_cancellationToken_and_fallback_does_not_handle_cancellations() { bool fallbackActionExecuted = false; Func> fallbackAction = _ => { fallbackActionExecuted = true; return Task.FromResult(ResultPrimitive.Substitute); }; @@ -691,9 +691,9 @@ public void Should_report_cancellation_and_not_execute_fallback_during_otherwise ActionObservesCancellation = true }; - policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, ResultPrimitive.Good)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, ResultPrimitive.Good)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); fallbackActionExecuted.Should().BeFalse(); diff --git a/src/Polly.Specs/IAsyncPolicyExtensionsSpecs.cs b/src/Polly.Specs/IAsyncPolicyExtensionsSpecs.cs index 78b392604ea..70116521bd1 100644 --- a/src/Polly.Specs/IAsyncPolicyExtensionsSpecs.cs +++ b/src/Polly.Specs/IAsyncPolicyExtensionsSpecs.cs @@ -30,7 +30,7 @@ public async Task Converting_a_nongeneric_IAsyncPolicy_to_generic_should_return_ (await genericPolicy.ExecuteAsync(deleg)).Should().Be(ResultPrimitive.Good); breaker.Isolate(); - genericPolicy.Awaiting(p => p.ExecuteAsync(deleg)).Should().Throw(); + await genericPolicy.Awaiting(p => p.ExecuteAsync(deleg)).Should().ThrowAsync(); } } diff --git a/src/Polly.Specs/NoOp/NoOpAsyncSpecs.cs b/src/Polly.Specs/NoOp/NoOpAsyncSpecs.cs index ccb5f15d200..c11807ebaba 100644 --- a/src/Polly.Specs/NoOp/NoOpAsyncSpecs.cs +++ b/src/Polly.Specs/NoOp/NoOpAsyncSpecs.cs @@ -1,4 +1,5 @@ using System.Threading; +using System.Threading.Tasks; using FluentAssertions; using Polly.Utilities; using Xunit; @@ -8,19 +9,19 @@ namespace Polly.Specs.NoOp public class NoOpAsyncSpecs { [Fact] - public void Should_execute_user_delegate() + public async Task Should_execute_user_delegate() { var policy = Policy.NoOpAsync(); bool executed = false; - policy.Awaiting(p => p.ExecuteAsync(() => { executed = true; return TaskHelper.EmptyTask; })) - .Should().NotThrow(); + await policy.Awaiting(p => p.ExecuteAsync(() => { executed = true; return TaskHelper.EmptyTask; })) + .Should().NotThrowAsync(); executed.Should().BeTrue(); } [Fact] - public void Should_execute_user_delegate_without_adding_extra_cancellation_behaviour() + public async Task Should_execute_user_delegate_without_adding_extra_cancellation_behaviour() { var policy = Policy.NoOpAsync(); @@ -30,9 +31,9 @@ public void Should_execute_user_delegate_without_adding_extra_cancellation_behav { cts.Cancel(); - policy.Awaiting(p => p.ExecuteAsync( + await policy.Awaiting(p => p.ExecuteAsync( _ => { executed = true; return TaskHelper.EmptyTask; }, cts.Token)) - .Should().NotThrow(); + .Should().NotThrowAsync(); } executed.Should().BeTrue(); diff --git a/src/Polly.Specs/NoOp/NoOpTResultAsyncSpecs.cs b/src/Polly.Specs/NoOp/NoOpTResultAsyncSpecs.cs index 50979d539d0..10f81a209dd 100644 --- a/src/Polly.Specs/NoOp/NoOpTResultAsyncSpecs.cs +++ b/src/Polly.Specs/NoOp/NoOpTResultAsyncSpecs.cs @@ -10,21 +10,21 @@ namespace Polly.Specs.NoOp public class NoOpTResultAsyncSpecs { [Fact] - public void Should_execute_user_delegate() + public async Task Should_execute_user_delegate() { var policy = Policy.NoOpAsync(); int? result = null; Func, Task> action = async p => result = await p.ExecuteAsync(() => Task.FromResult((int?)10)); - policy.Awaiting(action) - .Should().NotThrow(); + await policy.Awaiting(action) + .Should().NotThrowAsync(); result.HasValue.Should().BeTrue(); result.Should().Be(10); } [Fact] - public void Should_execute_user_delegate_without_adding_extra_cancellation_behaviour() + public async Task Should_execute_user_delegate_without_adding_extra_cancellation_behaviour() { var policy = Policy.NoOpAsync(); int? result = null; @@ -34,8 +34,8 @@ public void Should_execute_user_delegate_without_adding_extra_cancellation_behav cts.Cancel(); Func, Task> action = async p => result = await p.ExecuteAsync(_ => Task.FromResult((int?)10), cts.Token); - policy.Awaiting(action) - .Should().NotThrow(); + await policy.Awaiting(action) + .Should().NotThrowAsync(); } result.HasValue.Should().BeTrue(); diff --git a/src/Polly.Specs/PolicyAsyncSpecs.cs b/src/Polly.Specs/PolicyAsyncSpecs.cs index 4835ac5154e..ac645347500 100644 --- a/src/Polly.Specs/PolicyAsyncSpecs.cs +++ b/src/Polly.Specs/PolicyAsyncSpecs.cs @@ -165,49 +165,49 @@ public async Task Executing_the_policy_function_and_failing_with_an_unhandled_ex #region Context tests [Fact] - public void Executing_the_policy_action_should_throw_when_context_data_is_null() + public async Task Executing_the_policy_action_should_throw_when_context_data_is_null() { var policy = Policy .Handle() .RetryAsync((_, _, _) => { }); - policy.Awaiting(p => p.ExecuteAsync(_ => TaskHelper.EmptyTask, (IDictionary)null)) - .Should().Throw(); + await policy.Awaiting(p => p.ExecuteAsync(_ => TaskHelper.EmptyTask, (IDictionary)null)) + .Should().ThrowAsync(); } [Fact] - public void Executing_the_policy_action_should_throw_when_context_is_null() + public async Task Executing_the_policy_action_should_throw_when_context_is_null() { var policy = Policy .Handle() .RetryAsync((_, _, _) => { }); - policy.Awaiting(p => p.ExecuteAsync(_ => TaskHelper.EmptyTask, (Context)null)) - .Should().Throw().And - .ParamName.Should().Be("context"); + var ex = await policy.Awaiting(p => p.ExecuteAsync(_ => TaskHelper.EmptyTask, (Context)null)) + .Should().ThrowAsync(); + ex.And.ParamName.Should().Be("context"); } [Fact] - public void Executing_the_policy_function_should_throw_when_context_data_is_null() + public async Task Executing_the_policy_function_should_throw_when_context_data_is_null() { var policy = Policy .Handle() .RetryAsync((_, _, _) => { }); - policy.Awaiting(p => p.ExecuteAsync(_ => Task.FromResult(2), (IDictionary)null)) - .Should().Throw(); + await policy.Awaiting(p => p.ExecuteAsync(_ => Task.FromResult(2), (IDictionary)null)) + .Should().ThrowAsync(); } [Fact] - public void Executing_the_policy_function_should_throw_when_context_is_null() + public async Task Executing_the_policy_function_should_throw_when_context_is_null() { var policy = Policy .Handle() .RetryAsync((_, _, _) => { }); - policy.Awaiting(p => p.ExecuteAsync(_ => Task.FromResult(2), (Context)null)) - .Should().Throw().And - .ParamName.Should().Be("context"); + var ex = await policy.Awaiting(p => p.ExecuteAsync(_ => Task.FromResult(2), (Context)null)) + .Should().ThrowAsync(); + ex.And.ParamName.Should().Be("context"); } [Fact] @@ -225,49 +225,49 @@ public async Task Executing_the_policy_function_should_pass_context_to_executed_ } [Fact] - public void Execute_and_capturing_the_policy_action_should_throw_when_context_data_is_null() + public async Task Execute_and_capturing_the_policy_action_should_throw_when_context_data_is_null() { var policy = Policy .Handle() .RetryAsync((_, _, _) => { }); - policy.Awaiting(p => p.ExecuteAndCaptureAsync(_ => TaskHelper.EmptyTask, (IDictionary)null)) - .Should().Throw(); + await policy.Awaiting(p => p.ExecuteAndCaptureAsync(_ => TaskHelper.EmptyTask, (IDictionary)null)) + .Should().ThrowAsync(); } [Fact] - public void Execute_and_capturing_the_policy_action_should_throw_when_context_is_null() + public async Task Execute_and_capturing_the_policy_action_should_throw_when_context_is_null() { var policy = Policy .Handle() .RetryAsync((_, _, _) => { }); - policy.Awaiting(p => p.ExecuteAndCaptureAsync(_ => TaskHelper.EmptyTask, (Context)null)) - .Should().Throw().And - .ParamName.Should().Be("context"); + var ex = await policy.Awaiting(p => p.ExecuteAndCaptureAsync(_ => TaskHelper.EmptyTask, (Context)null)) + .Should().ThrowAsync(); + ex.And.ParamName.Should().Be("context"); } [Fact] - public void Execute_and_capturing_the_policy_function_should_throw_when_context_data_is_null() + public async Task Execute_and_capturing_the_policy_function_should_throw_when_context_data_is_null() { var policy = Policy .Handle() .RetryAsync((_, _, _) => { }); - policy.Awaiting(p => p.ExecuteAndCaptureAsync(_ => Task.FromResult(2), (IDictionary)null)) - .Should().Throw(); + await policy.Awaiting(p => p.ExecuteAndCaptureAsync(_ => Task.FromResult(2), (IDictionary)null)) + .Should().ThrowAsync(); } [Fact] - public void Execute_and_capturing_the_policy_function_should_throw_when_context_is_null() + public async Task Execute_and_capturing_the_policy_function_should_throw_when_context_is_null() { var policy = Policy .Handle() .RetryAsync((_, _, _) => { }); - policy.Awaiting(p => p.ExecuteAndCaptureAsync(_ => Task.FromResult(2), (Context)null)) - .Should().Throw().And - .ParamName.Should().Be("context"); + var ex = await policy.Awaiting(p => p.ExecuteAndCaptureAsync(_ => Task.FromResult(2), (Context)null)) + .Should().ThrowAsync(); + ex.And.ParamName.Should().Be("context"); } [Fact] diff --git a/src/Polly.Specs/PolicyTResultAsyncSpecs.cs b/src/Polly.Specs/PolicyTResultAsyncSpecs.cs index 94ac159d8c7..d9638ef5ca3 100644 --- a/src/Polly.Specs/PolicyTResultAsyncSpecs.cs +++ b/src/Polly.Specs/PolicyTResultAsyncSpecs.cs @@ -96,38 +96,38 @@ public async Task Executing_the_policy_function_and_returning_an_unhandled_resul [Fact] - public void Executing_the_policy_function_should_throw_when_context_data_is_null() + public async Task Executing_the_policy_function_should_throw_when_context_data_is_null() { var policy = Policy .HandleResult(ResultPrimitive.Fault) .RetryAsync((_, _, _) => { }); - policy.Awaiting(p => p.ExecuteAsync(_ => Task.FromResult(ResultPrimitive.Good), (IDictionary)null)) - .Should().Throw(); + await policy.Awaiting(p => p.ExecuteAsync(_ => Task.FromResult(ResultPrimitive.Good), (IDictionary)null)) + .Should().ThrowAsync(); } [Fact] - public void Executing_the_policy_function_should_throw_when_context_is_null() + public async Task Executing_the_policy_function_should_throw_when_context_is_null() { var policy = Policy .HandleResult(ResultPrimitive.Fault) .RetryAsync((_, _, _) => { }); - policy.Awaiting(p => p.ExecuteAsync(_ => Task.FromResult(ResultPrimitive.Good), (Context)null)) - .Should().Throw().And - .ParamName.Should().Be("context"); + var ex = await policy.Awaiting(p => p.ExecuteAsync(_ => Task.FromResult(ResultPrimitive.Good), (Context)null)) + .Should().ThrowAsync(); + ex.And.ParamName.Should().Be("context"); } [Fact] - public void Execute_and_capturing_the_policy_function_should_throw_when_context_data_is_null() + public async Task Execute_and_capturing_the_policy_function_should_throw_when_context_data_is_null() { var policy = Policy .HandleResult(ResultPrimitive.Fault) .RetryAsync((_, _, _) => { }); - policy.Awaiting(p => p.ExecuteAndCaptureAsync(_ => Task.FromResult(ResultPrimitive.Good), (Context)null)) - .Should().Throw().And - .ParamName.Should().Be("context"); + var ex = await policy.Awaiting(p => p.ExecuteAndCaptureAsync(_ => Task.FromResult(ResultPrimitive.Good), (Context)null)) + .Should().ThrowAsync(); + ex.And.ParamName.Should().Be("context"); } [Fact] @@ -145,15 +145,15 @@ public async Task Executing_the_policy_function_should_pass_context_to_executed_ } [Fact] - public void Execute_and_capturing_the_policy_function_should_throw_when_context_is_null() + public async Task Execute_and_capturing_the_policy_function_should_throw_when_context_is_null() { var policy = Policy .HandleResult(ResultPrimitive.Fault) .RetryAsync((_, _, _) => { }); - policy.Awaiting(p => p.ExecuteAndCaptureAsync(_ => Task.FromResult(ResultPrimitive.Good), (Context)null)) - .Should().Throw().And - .ParamName.Should().Be("context"); + var ex = await policy.Awaiting(p => p.ExecuteAndCaptureAsync(_ => Task.FromResult(ResultPrimitive.Good), (Context)null)) + .Should().ThrowAsync(); + ex.And.ParamName.Should().Be("context"); } [Fact] diff --git a/src/Polly.Specs/Polly.Specs.csproj b/src/Polly.Specs/Polly.Specs.csproj index 6ad7be03aec..b1d6577c94b 100644 --- a/src/Polly.Specs/Polly.Specs.csproj +++ b/src/Polly.Specs/Polly.Specs.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/Polly.Specs/Registry/ReadOnlyPolicyRegistrySpecs.cs b/src/Polly.Specs/Registry/ReadOnlyPolicyRegistrySpecs.cs index e05b5948c05..57dab67b038 100644 --- a/src/Polly.Specs/Registry/ReadOnlyPolicyRegistrySpecs.cs +++ b/src/Polly.Specs/Registry/ReadOnlyPolicyRegistrySpecs.cs @@ -282,7 +282,10 @@ public void Policies_Should_Be_Added_To_The_Registry_When_Using_Collection_Initi {key, policy} }; - testRegistry.Should().Equal(new KeyValuePair(key, policy)); + testRegistry.Should().Equal(new Dictionary + { + {key, policy} + }); } #endregion } diff --git a/src/Polly.Specs/Retry/RetryAsyncSpecs.cs b/src/Polly.Specs/Retry/RetryAsyncSpecs.cs index da10076de10..00704b7ad50 100644 --- a/src/Polly.Specs/Retry/RetryAsyncSpecs.cs +++ b/src/Polly.Specs/Retry/RetryAsyncSpecs.cs @@ -29,141 +29,141 @@ public void Should_throw_when_retry_count_is_less_than_zero_without_context() } [Fact] - public void Should_not_throw_when_specified_exception_thrown_same_number_of_times_as_retry_count() + public async Task Should_not_throw_when_specified_exception_thrown_same_number_of_times_as_retry_count() { var policy = Policy .Handle() .RetryAsync(3); - policy.Awaiting(x => x.RaiseExceptionAsync(3)) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync(3)) + .Should().NotThrowAsync(); } [Fact] - public void Should_not_throw_when_one_of_the_specified_exceptions_thrown_same_number_of_times_as_retry_count() + public async Task Should_not_throw_when_one_of_the_specified_exceptions_thrown_same_number_of_times_as_retry_count() { var policy = Policy .Handle() .Or() .RetryAsync(3); - policy.Awaiting(x => x.RaiseExceptionAsync(3)) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync(3)) + .Should().NotThrowAsync(); } [Fact] - public void Should_not_throw_when_specified_exception_thrown_less_number_of_times_than_retry_count() + public async Task Should_not_throw_when_specified_exception_thrown_less_number_of_times_than_retry_count() { var policy = Policy .Handle() .RetryAsync(3); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().NotThrowAsync(); } [Fact] - public void Should_not_throw_when_one_of_the_specified_exceptions_thrown_less_number_of_times_than_retry_count() + public async Task Should_not_throw_when_one_of_the_specified_exceptions_thrown_less_number_of_times_than_retry_count() { var policy = Policy .Handle() .Or() .RetryAsync(3); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().NotThrowAsync(); } [Fact] - public void Should_throw_when_specified_exception_thrown_more_times_then_retry_count() + public async Task Should_throw_when_specified_exception_thrown_more_times_then_retry_count() { var policy = Policy .Handle() .RetryAsync(3); - policy.Awaiting(x => x.RaiseExceptionAsync(3 + 1)) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync(3 + 1)) + .Should().ThrowAsync(); } [Fact] - public void Should_throw_when_one_of_the_specified_exceptions_are_thrown_more_times_then_retry_count() + public async Task Should_throw_when_one_of_the_specified_exceptions_are_thrown_more_times_then_retry_count() { var policy = Policy .Handle() .Or() .RetryAsync(3); - policy.Awaiting(x => x.RaiseExceptionAsync(3 + 1)) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync(3 + 1)) + .Should().ThrowAsync(); } [Fact] - public void Should_throw_when_exception_thrown_is_not_the_specified_exception_type() + public async Task Should_throw_when_exception_thrown_is_not_the_specified_exception_type() { var policy = Policy .Handle() .RetryAsync(); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } [Fact] - public void Should_throw_when_exception_thrown_is_not_one_of_the_specified_exception_types() + public async Task Should_throw_when_exception_thrown_is_not_one_of_the_specified_exception_types() { var policy = Policy .Handle() .Or() .RetryAsync(); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } [Fact] - public void Should_throw_when_specified_exception_predicate_is_not_satisfied() + public async Task Should_throw_when_specified_exception_predicate_is_not_satisfied() { var policy = Policy .Handle(_ => false) .RetryAsync(); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } [Fact] - public void Should_throw_when_none_of_the_specified_exception_predicates_are_satisfied() + public async Task Should_throw_when_none_of_the_specified_exception_predicates_are_satisfied() { var policy = Policy .Handle(_ => false) .Or(_ => false) .RetryAsync(); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } [Fact] - public void Should_not_throw_when_specified_exception_predicate_is_satisfied() + public async Task Should_not_throw_when_specified_exception_predicate_is_satisfied() { var policy = Policy .Handle(_ => true) .RetryAsync(); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().NotThrowAsync(); } [Fact] - public void Should_not_throw_when_one_of_the_specified_exception_predicates_are_satisfied() + public async Task Should_not_throw_when_one_of_the_specified_exception_predicates_are_satisfied() { var policy = Policy .Handle(_ => true) .Or(_ => true) .RetryAsync(); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().NotThrowAsync(); } [Fact] @@ -185,7 +185,7 @@ public async Task Should_call_onretry_on_each_retry_with_the_current_retry_count [Fact] public async Task Should_call_onretry_on_each_retry_with_the_current_exception() { - var expectedExceptions = new object[] { "Exception #1", "Exception #2", "Exception #3" }; + var expectedExceptions = new string[] { "Exception #1", "Exception #2", "Exception #3" }; var retryExceptions = new List(); var policy = Policy @@ -218,7 +218,7 @@ public async Task Should_call_onretry_with_a_handled_innerexception() } [Fact] - public void Should_not_call_onretry_when_no_retries_are_performed() + public async Task Should_not_call_onretry_when_no_retries_are_performed() { var retryCounts = new List(); @@ -226,25 +226,25 @@ public void Should_not_call_onretry_when_no_retries_are_performed() .Handle() .RetryAsync((_, retryCount) => retryCounts.Add(retryCount)); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); retryCounts.Should() .BeEmpty(); } [Fact] - public void Should_create_new_state_for_each_call_to_policy() + public async Task Should_create_new_state_for_each_call_to_policy() { var policy = Policy .Handle() .RetryAsync(); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().NotThrowAsync(); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().NotThrowAsync(); } [Fact] @@ -266,7 +266,7 @@ public void Should_call_onretry_with_the_passed_context() } [Fact] - public void Should_call_onretry_with_the_passed_context_when_execute_and_capture() + public async Task Should_call_onretry_with_the_passed_context_when_execute_and_capture() { IDictionary contextData = null; @@ -274,9 +274,9 @@ public void Should_call_onretry_with_the_passed_context_when_execute_and_capture .Handle() .RetryAsync((_, _, context) => contextData = context); - policy.Awaiting(p => p.ExecuteAndCaptureAsync(_ => { throw new DivideByZeroException(); }, + await policy.Awaiting(p => p.ExecuteAndCaptureAsync(_ => { throw new DivideByZeroException(); }, new { key1 = "value1", key2 = "value2" }.AsDictionary())) - .Should().NotThrow(); + .Should().NotThrowAsync(); contextData.Should() .ContainKeys("key1", "key2").And @@ -284,7 +284,7 @@ public void Should_call_onretry_with_the_passed_context_when_execute_and_capture } [Fact] - public void Context_should_be_empty_if_execute_not_called_with_any_data() + public async Task Context_should_be_empty_if_execute_not_called_with_any_data() { Context capturedContext = null; @@ -292,7 +292,7 @@ public void Context_should_be_empty_if_execute_not_called_with_any_data() .Handle() .RetryAsync((_, _, context) => capturedContext = context); - policy.Awaiting(x => x.RaiseExceptionAsync()).Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync()).Should().NotThrowAsync(); capturedContext.Should() .BeEmpty(); @@ -321,7 +321,7 @@ public void Should_create_new_context_for_each_call_to_execute() } [Fact] - public void Should_create_new_context_for_each_call_to_execute_and_capture() + public async Task Should_create_new_context_for_each_call_to_execute_and_capture() { string contextValue = null; @@ -329,21 +329,21 @@ public void Should_create_new_context_for_each_call_to_execute_and_capture() .Handle() .RetryAsync((_, _, context) => contextValue = context["key"].ToString()); - policy.Awaiting(p => p.ExecuteAndCaptureAsync(_ => throw new DivideByZeroException(), + await policy.Awaiting(p => p.ExecuteAndCaptureAsync(_ => throw new DivideByZeroException(), new { key = "original_value" }.AsDictionary())) - .Should().NotThrow(); + .Should().NotThrowAsync(); contextValue.Should().Be("original_value"); - policy.Awaiting(p => p.ExecuteAndCaptureAsync(_ => throw new DivideByZeroException(), + await policy.Awaiting(p => p.ExecuteAndCaptureAsync(_ => throw new DivideByZeroException(), new { key = "new_value" }.AsDictionary())) - .Should().NotThrow(); + .Should().NotThrowAsync(); contextValue.Should().Be("new_value"); } [Fact] - public void Should_not_call_onretry_when_retry_count_is_zero() + public async Task Should_not_call_onretry_when_retry_count_is_zero() { bool retryInvoked = false; @@ -353,8 +353,8 @@ public void Should_not_call_onretry_when_retry_count_is_zero() .Handle() .RetryAsync(0, onRetry); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); retryInvoked.Should().BeFalse(); } @@ -362,7 +362,7 @@ public void Should_not_call_onretry_when_retry_count_is_zero() #region Async and cancellation tests [Fact] - public void Should_wait_asynchronously_for_async_onretry_delegate() + public async Task Should_wait_asynchronously_for_async_onretry_delegate() { // This test relates to https://github.com/App-vNext/Polly/issues/107. // An async (...) => { ... } anonymous delegate with no return type may compile to either an async void or an async Task method; which assign to an Action<...> or Func<..., Task> respectively. However, if it compiles to async void (assigning to Action<...>), then the delegate, when run, will return at the first await, and execution continues without waiting for the Action to complete, as described by Stephen Toub: http://blogs.msdn.com/b/pfxteam/archive/2012/02/08/10265476.aspx @@ -382,12 +382,12 @@ public void Should_wait_asynchronously_for_async_onretry_delegate() executeDelegateInvocationsWhenOnRetryExits = executeDelegateInvocations; }); - policy.Awaiting(p => p.ExecuteAsync(async () => + await policy.Awaiting(p => p.ExecuteAsync(async () => { executeDelegateInvocations++; await TaskHelper.EmptyTask; throw new DivideByZeroException(); - })).Should().Throw(); + })).Should().ThrowAsync(); while (executeDelegateInvocationsWhenOnRetryExits == 0) { } // Wait for the onRetry delegate to complete. @@ -396,7 +396,7 @@ public void Should_wait_asynchronously_for_async_onretry_delegate() } [Fact] - public void Should_execute_action_when_non_faulting_and_cancellationToken_not_cancelled() + public async Task Should_execute_action_when_non_faulting_and_cancellationToken_not_cancelled() { var policy = Policy .Handle() @@ -414,14 +414,14 @@ public void Should_execute_action_when_non_faulting_and_cancellationToken_not_ca AttemptDuringWhichToCancel = null, }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().NotThrowAsync(); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_execute_all_tries_when_faulting_and_cancellationToken_not_cancelled() + public async Task Should_execute_all_tries_when_faulting_and_cancellationToken_not_cancelled() { var policy = Policy .Handle() @@ -439,14 +439,14 @@ public void Should_execute_all_tries_when_faulting_and_cancellationToken_not_can AttemptDuringWhichToCancel = null, }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); attemptsInvoked.Should().Be(1 + 3); } [Fact] - public void Should_not_execute_action_when_cancellationToken_cancelled_before_execute() + public async Task Should_not_execute_action_when_cancellationToken_cancelled_before_execute() { var policy = Policy .Handle() @@ -466,15 +466,15 @@ public void Should_not_execute_action_when_cancellationToken_cancelled_before_ex cancellationTokenSource.Cancel(); - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(0); } [Fact] - public void Should_report_cancellation_during_otherwise_non_faulting_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() + public async Task Should_report_cancellation_during_otherwise_non_faulting_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() { var policy = Policy .Handle() @@ -493,15 +493,15 @@ public void Should_report_cancellation_during_otherwise_non_faulting_action_exec ActionObservesCancellation = true }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_report_cancellation_during_faulting_initial_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() + public async Task Should_report_cancellation_during_faulting_initial_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() { var policy = Policy .Handle() @@ -520,15 +520,15 @@ public void Should_report_cancellation_during_faulting_initial_action_execution_ ActionObservesCancellation = true }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_report_cancellation_during_faulting_initial_action_execution_and_cancel_further_retries_when_user_delegate_does_not_observe_cancellationToken() + public async Task Should_report_cancellation_during_faulting_initial_action_execution_and_cancel_further_retries_when_user_delegate_does_not_observe_cancellationToken() { var policy = Policy .Handle() @@ -547,15 +547,15 @@ public void Should_report_cancellation_during_faulting_initial_action_execution_ ActionObservesCancellation = false }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_report_cancellation_during_faulting_retried_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() + public async Task Should_report_cancellation_during_faulting_retried_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() { var policy = Policy .Handle() @@ -574,15 +574,15 @@ public void Should_report_cancellation_during_faulting_retried_action_execution_ ActionObservesCancellation = true }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(2); } [Fact] - public void Should_report_cancellation_during_faulting_retried_action_execution_and_cancel_further_retries_when_user_delegate_does_not_observe_cancellationToken() + public async Task Should_report_cancellation_during_faulting_retried_action_execution_and_cancel_further_retries_when_user_delegate_does_not_observe_cancellationToken() { var policy = Policy .Handle() @@ -601,15 +601,15 @@ public void Should_report_cancellation_during_faulting_retried_action_execution_ ActionObservesCancellation = false }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(2); } [Fact] - public void Should_report_cancellation_during_faulting_last_retry_execution_when_user_delegate_does_observe_cancellationToken() + public async Task Should_report_cancellation_during_faulting_last_retry_execution_when_user_delegate_does_observe_cancellationToken() { var policy = Policy .Handle() @@ -628,15 +628,15 @@ public void Should_report_cancellation_during_faulting_last_retry_execution_when ActionObservesCancellation = true }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1 + 3); } [Fact] - public void Should_report_faulting_from_faulting_last_retry_execution_when_user_delegate_does_not_observe_cancellation_raised_during_last_retry() + public async Task Should_report_faulting_from_faulting_last_retry_execution_when_user_delegate_does_not_observe_cancellation_raised_during_last_retry() { var policy = Policy .Handle() @@ -655,14 +655,14 @@ public void Should_report_faulting_from_faulting_last_retry_execution_when_user_ ActionObservesCancellation = false }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); attemptsInvoked.Should().Be(1 + 3); } [Fact] - public void Should_report_cancellation_after_faulting_action_execution_and_cancel_further_retries_if_onRetry_invokes_cancellation() + public async Task Should_report_cancellation_after_faulting_action_execution_and_cancel_further_retries_if_onRetry_invokes_cancellation() { CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; @@ -684,15 +684,15 @@ public void Should_report_cancellation_after_faulting_action_execution_and_cance ActionObservesCancellation = false }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_execute_func_returning_value_when_cancellationToken_not_cancelled() + public async Task Should_execute_func_returning_value_when_cancellationToken_not_cancelled() { var policy = Policy .Handle() @@ -713,8 +713,8 @@ public void Should_execute_func_returning_value_when_cancellationToken_not_cance }; Func action = async x => result = await x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, true); - policy.Awaiting(action) - .Should().NotThrow(); + await policy.Awaiting(action) + .Should().NotThrowAsync(); result.Should().BeTrue(); @@ -722,7 +722,7 @@ public void Should_execute_func_returning_value_when_cancellationToken_not_cance } [Fact] - public void Should_honour_and_report_cancellation_during_func_execution() + public async Task Should_honour_and_report_cancellation_during_func_execution() { var policy = Policy .Handle() @@ -744,8 +744,8 @@ public void Should_honour_and_report_cancellation_during_func_execution() }; Func action = async x => result = await x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, true); - policy.Awaiting(action) - .Should().Throw().And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(action).Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); result.Should().Be(null); diff --git a/src/Polly.Specs/Retry/RetryForeverAsyncSpecs.cs b/src/Polly.Specs/Retry/RetryForeverAsyncSpecs.cs index a96eb9e3c95..81487a8c303 100644 --- a/src/Polly.Specs/Retry/RetryForeverAsyncSpecs.cs +++ b/src/Polly.Specs/Retry/RetryForeverAsyncSpecs.cs @@ -16,101 +16,101 @@ namespace Polly.Specs.Retry public class RetryForeverAsyncSpecs { [Fact] - public void Should_not_throw_regardless_of_how_many_times_the_specified_exception_is_raised() + public async Task Should_not_throw_regardless_of_how_many_times_the_specified_exception_is_raised() { var policy = Policy .Handle() .RetryForeverAsync(); - policy.Awaiting(x => x.RaiseExceptionAsync(3)) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync(3)) + .Should().NotThrowAsync(); } [Fact] - public void Should_not_throw_regardless_of_how_many_times_one_of_the_specified_exception_is_raised() + public async Task Should_not_throw_regardless_of_how_many_times_one_of_the_specified_exception_is_raised() { var policy = Policy .Handle() .Or() .RetryForeverAsync(); - policy.Awaiting(x => x.RaiseExceptionAsync(3)) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync(3)) + .Should().NotThrowAsync(); } [Fact] - public void Should_throw_when_exception_thrown_is_not_the_specified_exception_type() + public async Task Should_throw_when_exception_thrown_is_not_the_specified_exception_type() { var policy = Policy .Handle() .RetryForeverAsync(); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } [Fact] - public void Should_throw_when_exception_thrown_is_not_one_of_the_specified_exception_types() + public async Task Should_throw_when_exception_thrown_is_not_one_of_the_specified_exception_types() { var policy = Policy .Handle() .Or() .RetryForeverAsync(); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } [Fact] - public void Should_throw_when_specified_exception_predicate_is_not_satisfied() + public async Task Should_throw_when_specified_exception_predicate_is_not_satisfied() { var policy = Policy .Handle(_ => false) .RetryForeverAsync(); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } [Fact] - public void Should_throw_when_none_of_the_specified_exception_predicates_are_satisfied() + public async Task Should_throw_when_none_of_the_specified_exception_predicates_are_satisfied() { var policy = Policy .Handle(_ => false) .Or(_ => false) .RetryForeverAsync(); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } [Fact] - public void Should_not_throw_when_specified_exception_predicate_is_satisfied() + public async Task Should_not_throw_when_specified_exception_predicate_is_satisfied() { var policy = Policy .Handle(_ => true) .RetryForeverAsync(); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().NotThrowAsync(); } [Fact] - public void Should_not_throw_when_one_of_the_specified_exception_predicates_are_satisfied() + public async Task Should_not_throw_when_one_of_the_specified_exception_predicates_are_satisfied() { var policy = Policy .Handle(_ => true) .Or(_ => true) .RetryForeverAsync(); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().NotThrowAsync(); } [Fact] public async Task Should_call_onretry_on_each_retry_with_the_current_exception() { - var expectedExceptions = new object[] {"Exception #1", "Exception #2", "Exception #3"}; + var expectedExceptions = new string[] {"Exception #1", "Exception #2", "Exception #3"}; var retryExceptions = new List(); var policy = Policy @@ -160,7 +160,7 @@ public void Should_call_onretry_on_each_retry_with_the_current_retry_count() } [Fact] - public void Context_should_be_empty_if_execute_not_called_with_any_data() + public async Task Context_should_be_empty_if_execute_not_called_with_any_data() { Context capturedContext = null; @@ -168,7 +168,7 @@ public void Context_should_be_empty_if_execute_not_called_with_any_data() .Handle() .RetryForeverAsync((_, context) => capturedContext = context); - policy.Awaiting(x => x.RaiseExceptionAsync()).Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync()).Should().NotThrowAsync(); capturedContext.Should() .BeEmpty(); @@ -197,7 +197,7 @@ public void Should_create_new_context_for_each_call_to_execute() } [Fact] - public void Should_not_call_onretry_when_no_retries_are_performed() + public async Task Should_not_call_onretry_when_no_retries_are_performed() { var retryExceptions = new List(); @@ -205,15 +205,15 @@ public void Should_not_call_onretry_when_no_retries_are_performed() .Handle() .RetryForeverAsync(exception => retryExceptions.Add(exception)); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); retryExceptions.Should() .BeEmpty(); } [Fact] - public void Should_wait_asynchronously_for_async_onretry_delegate() + public async Task Should_wait_asynchronously_for_async_onretry_delegate() { // This test relates to https://github.com/App-vNext/Polly/issues/107. // An async (...) => { ... } anonymous delegate with no return type may compile to either an async void or an async Task method; which assign to an Action<...> or Func<..., Task> respectively. However, if it compiles to async void (assigning tp Action<...>), then the delegate, when run, will return at the first await, and execution continues without waiting for the Action to complete, as described by Stephen Toub: http://blogs.msdn.com/b/pfxteam/archive/2012/02/08/10265476.aspx @@ -233,12 +233,12 @@ public void Should_wait_asynchronously_for_async_onretry_delegate() executeDelegateInvocationsWhenOnRetryExits = executeDelegateInvocations; }); - policy.Awaiting(p => p.ExecuteAsync(async () => + await policy.Awaiting(p => p.ExecuteAsync(async () => { executeDelegateInvocations++; await TaskHelper.EmptyTask; if (executeDelegateInvocations == 1) { throw new DivideByZeroException(); } - })).Should().NotThrow(); + })).Should().NotThrowAsync(); while (executeDelegateInvocationsWhenOnRetryExits == 0) { } // Wait for the onRetry delegate to complete. @@ -247,7 +247,7 @@ public void Should_wait_asynchronously_for_async_onretry_delegate() } [Fact] - public void Should_execute_action_when_non_faulting_and_cancellationToken_not_cancelled() + public async Task Should_execute_action_when_non_faulting_and_cancellationToken_not_cancelled() { var policy = Policy .Handle() @@ -265,14 +265,14 @@ public void Should_execute_action_when_non_faulting_and_cancellationToken_not_ca AttemptDuringWhichToCancel = null, }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().NotThrowAsync(); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_not_execute_action_when_cancellationToken_cancelled_before_execute() + public async Task Should_not_execute_action_when_cancellationToken_cancelled_before_execute() { var policy = Policy .Handle() @@ -292,15 +292,15 @@ public void Should_not_execute_action_when_cancellationToken_cancelled_before_ex cancellationTokenSource.Cancel(); - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(0); } [Fact] - public void Should_report_cancellation_during_otherwise_non_faulting_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() + public async Task Should_report_cancellation_during_otherwise_non_faulting_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() { var policy = Policy .Handle() @@ -319,15 +319,15 @@ public void Should_report_cancellation_during_otherwise_non_faulting_action_exec ActionObservesCancellation = true }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_report_cancellation_during_faulting_initial_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() + public async Task Should_report_cancellation_during_faulting_initial_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() { var policy = Policy .Handle() @@ -346,15 +346,15 @@ public void Should_report_cancellation_during_faulting_initial_action_execution_ ActionObservesCancellation = true }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_report_cancellation_during_faulting_initial_action_execution_and_cancel_further_retries_when_user_delegate_does_not_observe_cancellationToken() + public async Task Should_report_cancellation_during_faulting_initial_action_execution_and_cancel_further_retries_when_user_delegate_does_not_observe_cancellationToken() { var policy = Policy .Handle() @@ -373,15 +373,15 @@ public void Should_report_cancellation_during_faulting_initial_action_execution_ ActionObservesCancellation = false }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_report_cancellation_during_faulting_retried_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() + public async Task Should_report_cancellation_during_faulting_retried_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() { var policy = Policy .Handle() @@ -400,15 +400,15 @@ public void Should_report_cancellation_during_faulting_retried_action_execution_ ActionObservesCancellation = true }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(2); } [Fact] - public void Should_report_cancellation_during_faulting_retried_action_execution_and_cancel_further_retries_when_user_delegate_does_not_observe_cancellationToken() + public async Task Should_report_cancellation_during_faulting_retried_action_execution_and_cancel_further_retries_when_user_delegate_does_not_observe_cancellationToken() { var policy = Policy .Handle() @@ -427,15 +427,15 @@ public void Should_report_cancellation_during_faulting_retried_action_execution_ ActionObservesCancellation = false }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(2); } [Fact] - public void Should_report_cancellation_after_faulting_action_execution_and_cancel_further_retries_if_onRetry_invokes_cancellation() + public async Task Should_report_cancellation_after_faulting_action_execution_and_cancel_further_retries_if_onRetry_invokes_cancellation() { CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; @@ -458,15 +458,15 @@ public void Should_report_cancellation_after_faulting_action_execution_and_cance ActionObservesCancellation = false }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_execute_func_returning_value_when_cancellationToken_not_cancelled() + public async Task Should_execute_func_returning_value_when_cancellationToken_not_cancelled() { var policy = Policy .Handle() @@ -487,8 +487,8 @@ public void Should_execute_func_returning_value_when_cancellationToken_not_cance }; Func action = async x => result = await x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, true); - policy.Awaiting(action) - .Should().NotThrow(); + await policy.Awaiting(action) + .Should().NotThrowAsync(); result.Should().BeTrue(); @@ -496,7 +496,7 @@ public void Should_execute_func_returning_value_when_cancellationToken_not_cance } [Fact] - public void Should_honour_and_report_cancellation_during_func_execution() + public async Task Should_honour_and_report_cancellation_during_func_execution() { var policy = Policy .Handle() @@ -518,8 +518,8 @@ public void Should_honour_and_report_cancellation_during_func_execution() }; Func action = async x => result = await x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, true); - policy.Awaiting(action) - .Should().Throw().And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(action).Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); result.Should().Be(null); diff --git a/src/Polly.Specs/Retry/RetryForeverSpecs.cs b/src/Polly.Specs/Retry/RetryForeverSpecs.cs index 811eaf9e97f..bb6cdfe5c14 100644 --- a/src/Polly.Specs/Retry/RetryForeverSpecs.cs +++ b/src/Polly.Specs/Retry/RetryForeverSpecs.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using FluentAssertions; using Polly.Specs.Helpers; using Xunit; @@ -70,14 +71,14 @@ public void Should_throw_when_exception_thrown_is_not_the_specified_exception_ty } [Fact] - public void Should_throw_when_exception_thrown_is_not_the_specified_exception_type_async() + public async Task Should_throw_when_exception_thrown_is_not_the_specified_exception_type_async() { var policy = Policy .Handle() .RetryForeverAsync(); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } [Fact] @@ -127,14 +128,14 @@ public void Should_not_throw_when_specified_exception_predicate_is_satisfied() } [Fact] - public void Should_not_throw_when_specified_exception_predicate_is_satisfied_async() + public async Task Should_not_throw_when_specified_exception_predicate_is_satisfied_async() { var policy = Policy .Handle(_ => true) .RetryForeverAsync(); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().NotThrowAsync(); } [Fact] @@ -150,21 +151,21 @@ public void Should_not_throw_when_one_of_the_specified_exception_predicates_are_ } [Fact] - public void Should_not_throw_when_one_of_the_specified_exception_predicates_are_satisfied_async() + public async Task Should_not_throw_when_one_of_the_specified_exception_predicates_are_satisfied_async() { var policy = Policy .Handle(_ => true) .Or(_ => true) .RetryForeverAsync(); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().NotThrowAsync(); } [Fact] public void Should_call_onretry_on_each_retry_with_the_current_exception() { - var expectedExceptions = new object[] {"Exception #1", "Exception #2", "Exception #3"}; + var expectedExceptions = new string[] {"Exception #1", "Exception #2", "Exception #3"}; var retryExceptions = new List(); var policy = Policy diff --git a/src/Polly.Specs/Retry/RetrySpecs.cs b/src/Polly.Specs/Retry/RetrySpecs.cs index 705fd6b18a1..2d5f6aee1bc 100644 --- a/src/Polly.Specs/Retry/RetrySpecs.cs +++ b/src/Polly.Specs/Retry/RetrySpecs.cs @@ -219,7 +219,7 @@ public void Should_call_onretry_on_each_retry_with_the_current_retry_count() [Fact] public void Should_call_onretry_on_each_retry_with_the_current_exception() { - var expectedExceptions = new object[] { "Exception #1", "Exception #2", "Exception #3" }; + var expectedExceptions = new string[] { "Exception #1", "Exception #2", "Exception #3" }; var retryExceptions = new List(); var policy = Policy diff --git a/src/Polly.Specs/Retry/RetryTResultSpecsAsync.cs b/src/Polly.Specs/Retry/RetryTResultSpecsAsync.cs index 2f4b940a48f..8d03d0b7110 100644 --- a/src/Polly.Specs/Retry/RetryTResultSpecsAsync.cs +++ b/src/Polly.Specs/Retry/RetryTResultSpecsAsync.cs @@ -482,7 +482,7 @@ public async Task Should_execute_all_tries_when_faulting_and_cancellationToken_n } [Fact] - public void Should_not_execute_action_when_cancellationToken_cancelled_before_execute() + public async Task Should_not_execute_action_when_cancellationToken_cancelled_before_execute() { var policy = Policy .HandleResult(ResultPrimitive.Fault) @@ -501,19 +501,19 @@ public void Should_not_execute_action_when_cancellationToken_cancelled_before_ex cancellationTokenSource.Cancel(); - policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, + var ex = await policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, ResultPrimitive.Fault, ResultPrimitive.Fault, ResultPrimitive.Fault, ResultPrimitive.Good)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(0); } [Fact] - public void Should_report_cancellation_during_otherwise_non_faulting_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() + public async Task Should_report_cancellation_during_otherwise_non_faulting_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() { var policy = Policy .HandleResult(ResultPrimitive.Fault) @@ -531,19 +531,19 @@ public void Should_report_cancellation_during_otherwise_non_faulting_action_exec ActionObservesCancellation = true }; - policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, + var ex = await policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, ResultPrimitive.Good, ResultPrimitive.Good, ResultPrimitive.Good, ResultPrimitive.Good)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_report_cancellation_during_faulting_initial_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() + public async Task Should_report_cancellation_during_faulting_initial_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() { var policy = Policy .HandleResult(ResultPrimitive.Fault) @@ -561,19 +561,19 @@ public void Should_report_cancellation_during_faulting_initial_action_execution_ ActionObservesCancellation = true }; - policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, + var ex = await policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, ResultPrimitive.Fault, ResultPrimitive.Fault, ResultPrimitive.Fault, ResultPrimitive.Good)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_report_cancellation_during_faulting_initial_action_execution_and_cancel_further_retries_when_user_delegate_does_not_observe_cancellationToken() + public async Task Should_report_cancellation_during_faulting_initial_action_execution_and_cancel_further_retries_when_user_delegate_does_not_observe_cancellationToken() { var policy = Policy .HandleResult(ResultPrimitive.Fault) @@ -591,19 +591,19 @@ public void Should_report_cancellation_during_faulting_initial_action_execution_ ActionObservesCancellation = false }; - policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, + var ex = await policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, ResultPrimitive.Fault, ResultPrimitive.Fault, ResultPrimitive.Fault, ResultPrimitive.Good)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_report_cancellation_during_faulting_retried_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() + public async Task Should_report_cancellation_during_faulting_retried_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() { var policy = Policy .HandleResult(ResultPrimitive.Fault) @@ -621,19 +621,19 @@ public void Should_report_cancellation_during_faulting_retried_action_execution_ ActionObservesCancellation = true }; - policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, + var ex = await policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, ResultPrimitive.Fault, ResultPrimitive.Fault, ResultPrimitive.Fault, ResultPrimitive.Good)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(2); } [Fact] - public void Should_report_cancellation_during_faulting_retried_action_execution_and_cancel_further_retries_when_user_delegate_does_not_observe_cancellationToken() + public async Task Should_report_cancellation_during_faulting_retried_action_execution_and_cancel_further_retries_when_user_delegate_does_not_observe_cancellationToken() { var policy = Policy .HandleResult(ResultPrimitive.Fault) @@ -651,19 +651,19 @@ public void Should_report_cancellation_during_faulting_retried_action_execution_ ActionObservesCancellation = false }; - policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, + var ex = await policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, ResultPrimitive.Fault, ResultPrimitive.Fault, ResultPrimitive.Fault, ResultPrimitive.Good)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(2); } [Fact] - public void Should_report_cancellation_during_faulting_last_retry_execution_when_user_delegate_does_observe_cancellationToken() + public async Task Should_report_cancellation_during_faulting_last_retry_execution_when_user_delegate_does_observe_cancellationToken() { var policy = Policy .HandleResult(ResultPrimitive.Fault) @@ -681,14 +681,14 @@ public void Should_report_cancellation_during_faulting_last_retry_execution_when ActionObservesCancellation = true }; - policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, + var ex = await policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, ResultPrimitive.Fault, ResultPrimitive.Fault, ResultPrimitive.Fault, ResultPrimitive.Fault, ResultPrimitive.Good)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1 + 3); } @@ -724,7 +724,7 @@ public async Task Should_report_faulting_from_faulting_last_retry_execution_when } [Fact] - public void Should_report_cancellation_after_faulting_action_execution_and_cancel_further_retries_if_onRetry_invokes_cancellation() + public async Task Should_report_cancellation_after_faulting_action_execution_and_cancel_further_retries_if_onRetry_invokes_cancellation() { CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; @@ -745,13 +745,13 @@ public void Should_report_cancellation_after_faulting_action_execution_and_cance ActionObservesCancellation = false }; - policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, + var ex = await policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, ResultPrimitive.Fault, ResultPrimitive.Fault, ResultPrimitive.Fault, ResultPrimitive.Good)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } diff --git a/src/Polly.Specs/Retry/WaitAndRetryAsyncSpecs.cs b/src/Polly.Specs/Retry/WaitAndRetryAsyncSpecs.cs index 97d17ae1103..85ec50b620a 100644 --- a/src/Polly.Specs/Retry/WaitAndRetryAsyncSpecs.cs +++ b/src/Polly.Specs/Retry/WaitAndRetryAsyncSpecs.cs @@ -51,7 +51,7 @@ public void Should_throw_when_onretry_action_is_null_without_context() } [Fact] - public void Should_not_throw_when_specified_exception_thrown_same_number_of_times_as_there_are_sleep_durations() + public async Task Should_not_throw_when_specified_exception_thrown_same_number_of_times_as_there_are_sleep_durations() { var policy = Policy .Handle() @@ -62,12 +62,12 @@ public void Should_not_throw_when_specified_exception_thrown_same_number_of_time 3.Seconds() }); - policy.Awaiting(x => x.RaiseExceptionAsync(3)) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync(3)) + .Should().NotThrowAsync(); } [Fact] - public void Should_not_throw_when_one_of_the_specified_exceptions_thrown_same_number_of_times_as_there_are_sleep_durations() + public async Task Should_not_throw_when_one_of_the_specified_exceptions_thrown_same_number_of_times_as_there_are_sleep_durations() { var policy = Policy .Handle() @@ -79,12 +79,12 @@ public void Should_not_throw_when_one_of_the_specified_exceptions_thrown_same_nu 3.Seconds() }); - policy.Awaiting(x => x.RaiseExceptionAsync(3)) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync(3)) + .Should().NotThrowAsync(); } [Fact] - public void Should_not_throw_when_specified_exception_thrown_less_number_of_times_than_there_are_sleep_durations() + public async Task Should_not_throw_when_specified_exception_thrown_less_number_of_times_than_there_are_sleep_durations() { var policy = Policy .Handle() @@ -95,12 +95,12 @@ public void Should_not_throw_when_specified_exception_thrown_less_number_of_time 3.Seconds() }); - policy.Awaiting(x => x.RaiseExceptionAsync(2)) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync(2)) + .Should().NotThrowAsync(); } [Fact] - public void Should_not_throw_when_one_of_the_specified_exceptions_thrown_less_number_of_times_than_there_are_sleep_durations() + public async Task Should_not_throw_when_one_of_the_specified_exceptions_thrown_less_number_of_times_than_there_are_sleep_durations() { var policy = Policy .Handle() @@ -112,12 +112,12 @@ public void Should_not_throw_when_one_of_the_specified_exceptions_thrown_less_nu 3.Seconds() }); - policy.Awaiting(x => x.RaiseExceptionAsync(2)) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync(2)) + .Should().NotThrowAsync(); } [Fact] - public void Should_throw_when_specified_exception_thrown_more_times_than_there_are_sleep_durations() + public async Task Should_throw_when_specified_exception_thrown_more_times_than_there_are_sleep_durations() { var policy = Policy .Handle() @@ -128,12 +128,12 @@ public void Should_throw_when_specified_exception_thrown_more_times_than_there_a 3.Seconds() }); - policy.Awaiting(x => x.RaiseExceptionAsync(3 + 1)) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync(3 + 1)) + .Should().ThrowAsync(); } [Fact] - public void Should_throw_when_one_of_the_specified_exceptions_are_thrown_more_times_than_there_are_sleep_durations() + public async Task Should_throw_when_one_of_the_specified_exceptions_are_thrown_more_times_than_there_are_sleep_durations() { var policy = Policy .Handle() @@ -145,58 +145,58 @@ public void Should_throw_when_one_of_the_specified_exceptions_are_thrown_more_ti 3.Seconds() }); - policy.Awaiting(x => x.RaiseExceptionAsync(3 + 1)) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync(3 + 1)) + .Should().ThrowAsync(); } [Fact] - public void Should_throw_when_exception_thrown_is_not_the_specified_exception_type() + public async Task Should_throw_when_exception_thrown_is_not_the_specified_exception_type() { var policy = Policy .Handle() .WaitAndRetryAsync(Enumerable.Empty()); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } [Fact] - public void Should_throw_when_exception_thrown_is_not_one_of_the_specified_exception_types() + public async Task Should_throw_when_exception_thrown_is_not_one_of_the_specified_exception_types() { var policy = Policy .Handle() .Or() .WaitAndRetryAsync(Enumerable.Empty()); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } [Fact] - public void Should_throw_when_specified_exception_predicate_is_not_satisfied() + public async Task Should_throw_when_specified_exception_predicate_is_not_satisfied() { var policy = Policy .Handle(_ => false) .WaitAndRetryAsync(Enumerable.Empty()); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } [Fact] - public void Should_throw_when_none_of_the_specified_exception_predicates_are_satisfied() + public async Task Should_throw_when_none_of_the_specified_exception_predicates_are_satisfied() { var policy = Policy .Handle(_ => false) .Or(_ => false) .WaitAndRetryAsync(Enumerable.Empty()); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } [Fact] - public void Should_not_throw_when_specified_exception_predicate_is_satisfied() + public async Task Should_not_throw_when_specified_exception_predicate_is_satisfied() { var policy = Policy .Handle(_ => true) @@ -205,12 +205,12 @@ public void Should_not_throw_when_specified_exception_predicate_is_satisfied() 1.Seconds() }); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().NotThrowAsync(); } [Fact] - public void Should_not_throw_when_one_of_the_specified_exception_predicates_are_satisfied() + public async Task Should_not_throw_when_one_of_the_specified_exception_predicates_are_satisfied() { var policy = Policy .Handle(_ => true) @@ -220,8 +220,8 @@ public void Should_not_throw_when_one_of_the_specified_exception_predicates_are_ 1.Seconds() }); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().NotThrowAsync(); } [Fact] @@ -251,7 +251,7 @@ public async Task Should_sleep_for_the_specified_duration_each_retry_when_specif } [Fact] - public void Should_sleep_for_the_specified_duration_each_retry_when_specified_exception_thrown_more_number_of_times_than_there_are_sleep_durations() + public async Task Should_sleep_for_the_specified_duration_each_retry_when_specified_exception_thrown_more_number_of_times_than_there_are_sleep_durations() { var totalTimeSlept = 0; @@ -270,8 +270,8 @@ public void Should_sleep_for_the_specified_duration_each_retry_when_specified_ex return TaskHelper.EmptyTask; }; - policy.Awaiting(x => x.RaiseExceptionAsync(3 + 1)) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync(3 + 1)) + .Should().ThrowAsync(); totalTimeSlept.Should() .Be(1 + 2 + 3); @@ -304,7 +304,7 @@ public async Task Should_sleep_for_the_specified_duration_each_retry_when_specif } [Fact] - public void Should_not_sleep_if_no_retries() + public async Task Should_not_sleep_if_no_retries() { var totalTimeSlept = 0; @@ -318,8 +318,8 @@ public void Should_not_sleep_if_no_retries() return TaskHelper.EmptyTask; }; - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); totalTimeSlept.Should() .Be(0); @@ -355,7 +355,7 @@ public async Task Should_call_onretry_on_each_retry_with_the_current_timespan() [Fact] public async Task Should_call_onretry_on_each_retry_with_the_current_exception() { - var expectedExceptions = new object[] { "Exception #1", "Exception #2", "Exception #3" }; + var expectedExceptions = new string[] { "Exception #1", "Exception #2", "Exception #3" }; var retryExceptions = new List(); var policy = Policy @@ -397,7 +397,7 @@ public async Task Should_call_onretry_on_each_retry_with_the_current_retry_count } [Fact] - public void Should_not_call_onretry_when_no_retries_are_performed() + public async Task Should_not_call_onretry_when_no_retries_are_performed() { var retryExceptions = new List(); @@ -405,14 +405,14 @@ public void Should_not_call_onretry_when_no_retries_are_performed() .Handle() .WaitAndRetryAsync(Enumerable.Empty(), (exception, _) => retryExceptions.Add(exception)); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); retryExceptions.Should().BeEmpty(); } [Fact] - public void Should_create_new_state_for_each_call_to_policy() + public async Task Should_create_new_state_for_each_call_to_policy() { var policy = Policy .Handle() @@ -421,11 +421,11 @@ public void Should_create_new_state_for_each_call_to_policy() 1.Seconds() }); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().NotThrowAsync(); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().NotThrowAsync(); } [Fact] @@ -452,7 +452,7 @@ await policy.RaiseExceptionAsync( } [Fact] - public void Context_should_be_empty_if_execute_not_called_with_any_data() + public async Task Context_should_be_empty_if_execute_not_called_with_any_data() { Context capturedContext = null; @@ -464,7 +464,7 @@ public void Context_should_be_empty_if_execute_not_called_with_any_data() 2.Seconds(), 3.Seconds() }, (_, _, context) => capturedContext = context); - policy.Awaiting(x => x.RaiseExceptionAsync()).Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync()).Should().NotThrowAsync(); capturedContext.Should() .BeEmpty(); @@ -651,7 +651,7 @@ await policy.ExecuteAsync(async (context, _) => } [Fact] - public void Should_not_call_onretry_when_retry_count_is_zero() + public async Task Should_not_call_onretry_when_retry_count_is_zero() { bool retryInvoked = false; @@ -661,14 +661,14 @@ public void Should_not_call_onretry_when_retry_count_is_zero() .Handle() .WaitAndRetryAsync(0, _ => TimeSpan.FromSeconds(1), onRetry); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); retryInvoked.Should().BeFalse(); } [Fact] - public void Should_wait_asynchronously_for_async_onretry_delegate() + public async Task Should_wait_asynchronously_for_async_onretry_delegate() { // This test relates to https://github.com/App-vNext/Polly/issues/107. // An async (...) => { ... } anonymous delegate with no return type may compile to either an async void or an async Task method; which assign to an Action<...> or Func<..., Task> respectively. However, if it compiles to async void (assigning tp Action<...>), then the delegate, when run, will return at the first await, and execution continues without waiting for the Action to complete, as described by Stephen Toub: http://blogs.msdn.com/b/pfxteam/archive/2012/02/08/10265476.aspx @@ -690,12 +690,12 @@ public void Should_wait_asynchronously_for_async_onretry_delegate() executeDelegateInvocationsWhenOnRetryExits = executeDelegateInvocations; }); - policy.Awaiting(p => p.ExecuteAsync(async () => + await policy.Awaiting(p => p.ExecuteAsync(async () => { executeDelegateInvocations++; await TaskHelper.EmptyTask; throw new DivideByZeroException(); - })).Should().Throw(); + })).Should().ThrowAsync(); while (executeDelegateInvocationsWhenOnRetryExits == 0) { } // Wait for the onRetry delegate to complete. @@ -704,7 +704,7 @@ public void Should_wait_asynchronously_for_async_onretry_delegate() } [Fact] - public void Should_execute_action_when_non_faulting_and_cancellationToken_not_cancelled() + public async Task Should_execute_action_when_non_faulting_and_cancellationToken_not_cancelled() { var policy = Policy .Handle() @@ -722,14 +722,14 @@ public void Should_execute_action_when_non_faulting_and_cancellationToken_not_ca AttemptDuringWhichToCancel = null, }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().NotThrowAsync(); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_execute_all_tries_when_faulting_and_cancellationToken_not_cancelled() + public async Task Should_execute_all_tries_when_faulting_and_cancellationToken_not_cancelled() { var policy = Policy .Handle() @@ -747,14 +747,14 @@ public void Should_execute_all_tries_when_faulting_and_cancellationToken_not_can AttemptDuringWhichToCancel = null, }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); attemptsInvoked.Should().Be(1 + 3); } [Fact] - public void Should_not_execute_action_when_cancellationToken_cancelled_before_execute() + public async Task Should_not_execute_action_when_cancellationToken_cancelled_before_execute() { var policy = Policy .Handle() @@ -774,15 +774,15 @@ public void Should_not_execute_action_when_cancellationToken_cancelled_before_ex cancellationTokenSource.Cancel(); - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(0); } [Fact] - public void Should_report_cancellation_during_otherwise_non_faulting_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() + public async Task Should_report_cancellation_during_otherwise_non_faulting_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() { var policy = Policy .Handle() @@ -801,15 +801,15 @@ public void Should_report_cancellation_during_otherwise_non_faulting_action_exec ActionObservesCancellation = true }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_report_cancellation_during_faulting_initial_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() + public async Task Should_report_cancellation_during_faulting_initial_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() { var policy = Policy .Handle() @@ -828,15 +828,15 @@ public void Should_report_cancellation_during_faulting_initial_action_execution_ ActionObservesCancellation = true }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_report_cancellation_during_faulting_initial_action_execution_and_cancel_further_retries_when_user_delegate_does_not_observe_cancellationToken() + public async Task Should_report_cancellation_during_faulting_initial_action_execution_and_cancel_further_retries_when_user_delegate_does_not_observe_cancellationToken() { var policy = Policy .Handle() @@ -855,15 +855,15 @@ public void Should_report_cancellation_during_faulting_initial_action_execution_ ActionObservesCancellation = false }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_report_cancellation_during_faulting_retried_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() + public async Task Should_report_cancellation_during_faulting_retried_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() { var policy = Policy .Handle() @@ -882,15 +882,15 @@ public void Should_report_cancellation_during_faulting_retried_action_execution_ ActionObservesCancellation = true }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(2); } [Fact] - public void Should_report_cancellation_during_faulting_retried_action_execution_and_cancel_further_retries_when_user_delegate_does_not_observe_cancellationToken() + public async Task Should_report_cancellation_during_faulting_retried_action_execution_and_cancel_further_retries_when_user_delegate_does_not_observe_cancellationToken() { var policy = Policy .Handle() @@ -909,15 +909,15 @@ public void Should_report_cancellation_during_faulting_retried_action_execution_ ActionObservesCancellation = false }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(2); } [Fact] - public void Should_report_cancellation_during_faulting_last_retry_execution_when_user_delegate_does_observe_cancellationToken() + public async Task Should_report_cancellation_during_faulting_last_retry_execution_when_user_delegate_does_observe_cancellationToken() { var policy = Policy .Handle() @@ -936,15 +936,15 @@ public void Should_report_cancellation_during_faulting_last_retry_execution_when ActionObservesCancellation = true }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1 + 3); } [Fact] - public void Should_report_faulting_from_faulting_last_retry_execution_when_user_delegate_does_not_observe_cancellation_raised_during_last_retry() + public async Task Should_report_faulting_from_faulting_last_retry_execution_when_user_delegate_does_not_observe_cancellation_raised_during_last_retry() { var policy = Policy .Handle() @@ -963,14 +963,14 @@ public void Should_report_faulting_from_faulting_last_retry_execution_when_user_ ActionObservesCancellation = false }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); attemptsInvoked.Should().Be(1 + 3); } [Fact] - public void Should_honour_cancellation_immediately_during_wait_phase_of_waitandretry() + public async Task Should_honour_cancellation_immediately_during_wait_phase_of_waitandretry() { CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; @@ -999,19 +999,19 @@ public void Should_honour_cancellation_immediately_during_wait_phase_of_waitandr cancellationTokenSource.CancelAfter(shimTimeSpan); - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); watch.Stop(); attemptsInvoked.Should().Be(1); watch.Elapsed.Should().BeLessThan(retryDelay); - watch.Elapsed.Should().BeCloseTo(shimTimeSpan, precision: (int)(shimTimeSpan.TotalMilliseconds) / 2); // Consider increasing shimTimeSpan, or loosening precision, if test fails transiently in different environments. + watch.Elapsed.Should().BeCloseTo(shimTimeSpan, precision: TimeSpan.FromMilliseconds((int)shimTimeSpan.TotalMilliseconds / 2)); // Consider increasing shimTimeSpan, or loosening precision, if test fails transiently in different environments. } [Fact] - public void Should_report_cancellation_after_faulting_action_execution_and_cancel_further_retries_if_onRetry_invokes_cancellation() + public async Task Should_report_cancellation_after_faulting_action_execution_and_cancel_further_retries_if_onRetry_invokes_cancellation() { CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; @@ -1034,15 +1034,15 @@ public void Should_report_cancellation_after_faulting_action_execution_and_cance ActionObservesCancellation = false }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_execute_func_returning_value_when_cancellationToken_not_cancelled() + public async Task Should_execute_func_returning_value_when_cancellationToken_not_cancelled() { var policy = Policy .Handle() @@ -1063,8 +1063,8 @@ public void Should_execute_func_returning_value_when_cancellationToken_not_cance }; Func action = async x => result = await x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, true); - policy.Awaiting(action) - .Should().NotThrow(); + await policy.Awaiting(action) + .Should().NotThrowAsync(); result.Should().BeTrue(); @@ -1072,7 +1072,7 @@ public void Should_execute_func_returning_value_when_cancellationToken_not_cance } [Fact] - public void Should_honour_and_report_cancellation_during_func_execution() + public async Task Should_honour_and_report_cancellation_during_func_execution() { var policy = Policy .Handle() @@ -1094,8 +1094,8 @@ public void Should_honour_and_report_cancellation_during_func_execution() }; Func action = async x => result = await x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, true); - policy.Awaiting(action) - .Should().Throw().And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(action).Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); result.Should().Be(null); diff --git a/src/Polly.Specs/Retry/WaitAndRetryForeverAsyncSpecs.cs b/src/Polly.Specs/Retry/WaitAndRetryForeverAsyncSpecs.cs index 3a312efe95d..9abd93b3d1c 100644 --- a/src/Polly.Specs/Retry/WaitAndRetryForeverAsyncSpecs.cs +++ b/src/Polly.Specs/Retry/WaitAndRetryForeverAsyncSpecs.cs @@ -78,30 +78,30 @@ public void Should_throw_when_onretry_action_is_null_with_context() } [Fact] - public void Should_not_throw_regardless_of_how_many_times_the_specified_exception_is_raised() + public async Task Should_not_throw_regardless_of_how_many_times_the_specified_exception_is_raised() { var policy = Policy .Handle() .WaitAndRetryForeverAsync(_ => TimeSpan.Zero); - policy.Awaiting(x => x.RaiseExceptionAsync(3)) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync(3)) + .Should().NotThrowAsync(); } [Fact] - public void Should_not_throw_regardless_of_how_many_times_one_of_the_specified_exception_is_raised() + public async Task Should_not_throw_regardless_of_how_many_times_one_of_the_specified_exception_is_raised() { var policy = Policy .Handle() .Or() .WaitAndRetryForeverAsync(_ => TimeSpan.Zero); - policy.Awaiting(x => x.RaiseExceptionAsync(3)) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync(3)) + .Should().NotThrowAsync(); } [Fact] - public void Should_throw_when_exception_thrown_is_not_the_specified_exception_type() + public async Task Should_throw_when_exception_thrown_is_not_the_specified_exception_type() { Func provider = _ => TimeSpan.Zero; @@ -109,12 +109,12 @@ public void Should_throw_when_exception_thrown_is_not_the_specified_exception_ty .Handle() .WaitAndRetryForeverAsync(provider); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } [Fact] - public void Should_throw_when_exception_thrown_is_not_one_of_the_specified_exception_types() + public async Task Should_throw_when_exception_thrown_is_not_one_of_the_specified_exception_types() { Func provider = _ => TimeSpan.Zero; @@ -123,12 +123,12 @@ public void Should_throw_when_exception_thrown_is_not_one_of_the_specified_excep .Or() .WaitAndRetryForeverAsync(provider); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } [Fact] - public void Should_throw_when_specified_exception_predicate_is_not_satisfied() + public async Task Should_throw_when_specified_exception_predicate_is_not_satisfied() { Func provider = _ => TimeSpan.Zero; @@ -136,12 +136,12 @@ public void Should_throw_when_specified_exception_predicate_is_not_satisfied() .Handle(_ => false) .WaitAndRetryForeverAsync(provider); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } [Fact] - public void Should_throw_when_none_of_the_specified_exception_predicates_are_satisfied() + public async Task Should_throw_when_none_of_the_specified_exception_predicates_are_satisfied() { Func provider = _ => TimeSpan.Zero; @@ -150,12 +150,12 @@ public void Should_throw_when_none_of_the_specified_exception_predicates_are_sat .Or(_ => false) .WaitAndRetryForeverAsync(provider); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } [Fact] - public void Should_not_throw_when_specified_exception_predicate_is_satisfied() + public async Task Should_not_throw_when_specified_exception_predicate_is_satisfied() { Func provider = _ => 1.Seconds(); @@ -163,12 +163,12 @@ public void Should_not_throw_when_specified_exception_predicate_is_satisfied() .Handle(_ => true) .WaitAndRetryForeverAsync(provider); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().NotThrowAsync(); } [Fact] - public void Should_not_throw_when_one_of_the_specified_exception_predicates_are_satisfied() + public async Task Should_not_throw_when_one_of_the_specified_exception_predicates_are_satisfied() { Func provider = _ => 1.Seconds(); @@ -177,12 +177,12 @@ public void Should_not_throw_when_one_of_the_specified_exception_predicates_are_ .Or(_ => true) .WaitAndRetryForeverAsync(provider); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().NotThrowAsync(); } [Fact] - public void Should_not_sleep_if_no_retries() + public async Task Should_not_sleep_if_no_retries() { Func provider = _ => 1.Seconds(); @@ -194,8 +194,8 @@ public void Should_not_sleep_if_no_retries() SystemClock.Sleep = (span, _) => totalTimeSlept += span.Seconds; - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); totalTimeSlept.Should() .Be(0); @@ -204,7 +204,7 @@ public void Should_not_sleep_if_no_retries() [Fact] public async Task Should_call_onretry_on_each_retry_with_the_current_exception() { - var expectedExceptions = new object[] { "Exception #1", "Exception #2", "Exception #3" }; + var expectedExceptions = new string[] { "Exception #1", "Exception #2", "Exception #3" }; var retryExceptions = new List(); Func provider = _ => TimeSpan.Zero; @@ -238,7 +238,7 @@ public void Should_call_onretry_on_each_retry_with_the_current_retry_count() } [Fact] - public void Should_not_call_onretry_when_no_retries_are_performed() + public async Task Should_not_call_onretry_when_no_retries_are_performed() { Func provider = _ => 1.Seconds(); var retryExceptions = new List(); @@ -247,8 +247,8 @@ public void Should_not_call_onretry_when_no_retries_are_performed() .Handle() .WaitAndRetryForeverAsync(provider, (exception, _) => retryExceptions.Add(exception)); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); retryExceptions.Should().BeEmpty(); } @@ -374,7 +374,7 @@ await policy.ExecuteAsync(async (context, _) => } [Fact] - public void Should_wait_asynchronously_for_async_onretry_delegate() + public async Task Should_wait_asynchronously_for_async_onretry_delegate() { // This test relates to https://github.com/App-vNext/Polly/issues/107. // An async (...) => { ... } anonymous delegate with no return type may compile to either an async void or an async Task method; which assign to an Action<...> or Func<..., Task> respectively. However, if it compiles to async void (assigning tp Action<...>), then the delegate, when run, will return at the first await, and execution continues without waiting for the Action to complete, as described by Stephen Toub: http://blogs.msdn.com/b/pfxteam/archive/2012/02/08/10265476.aspx @@ -396,12 +396,12 @@ public void Should_wait_asynchronously_for_async_onretry_delegate() executeDelegateInvocationsWhenOnRetryExits = executeDelegateInvocations; }); - policy.Awaiting(p => p.ExecuteAsync(async () => + await policy.Awaiting(p => p.ExecuteAsync(async () => { executeDelegateInvocations++; await TaskHelper.EmptyTask; if (executeDelegateInvocations == 1) { throw new DivideByZeroException(); } - })).Should().NotThrow(); + })).Should().NotThrowAsync(); while (executeDelegateInvocationsWhenOnRetryExits == 0) { } // Wait for the onRetry delegate to complete. @@ -410,7 +410,7 @@ public void Should_wait_asynchronously_for_async_onretry_delegate() } [Fact] - public void Should_execute_action_when_non_faulting_and_cancellationToken_not_cancelled() + public async Task Should_execute_action_when_non_faulting_and_cancellationToken_not_cancelled() { Func provider = _ => TimeSpan.Zero; @@ -429,14 +429,14 @@ public void Should_execute_action_when_non_faulting_and_cancellationToken_not_ca AttemptDuringWhichToCancel = null, }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().NotThrowAsync(); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_not_execute_action_when_cancellationToken_cancelled_before_execute() + public async Task Should_not_execute_action_when_cancellationToken_cancelled_before_execute() { Func provider = _ => TimeSpan.Zero; @@ -458,15 +458,15 @@ public void Should_not_execute_action_when_cancellationToken_cancelled_before_ex cancellationTokenSource.Cancel(); - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(0); } [Fact] - public void Should_report_cancellation_during_otherwise_non_faulting_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() + public async Task Should_report_cancellation_during_otherwise_non_faulting_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() { Func provider = _ => TimeSpan.Zero; @@ -487,15 +487,15 @@ public void Should_report_cancellation_during_otherwise_non_faulting_action_exec ActionObservesCancellation = true }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_report_cancellation_during_faulting_initial_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() + public async Task Should_report_cancellation_during_faulting_initial_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() { Func provider = _ => TimeSpan.Zero; @@ -516,15 +516,15 @@ public void Should_report_cancellation_during_faulting_initial_action_execution_ ActionObservesCancellation = true }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_report_cancellation_during_faulting_initial_action_execution_and_cancel_further_retries_when_user_delegate_does_not_observe_cancellationToken() + public async Task Should_report_cancellation_during_faulting_initial_action_execution_and_cancel_further_retries_when_user_delegate_does_not_observe_cancellationToken() { Func provider = _ => TimeSpan.Zero; @@ -545,15 +545,15 @@ public void Should_report_cancellation_during_faulting_initial_action_execution_ ActionObservesCancellation = false }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_report_cancellation_during_faulting_retried_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() + public async Task Should_report_cancellation_during_faulting_retried_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() { Func provider = _ => TimeSpan.Zero; @@ -574,15 +574,15 @@ public void Should_report_cancellation_during_faulting_retried_action_execution_ ActionObservesCancellation = true }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(2); } [Fact] - public void Should_report_cancellation_during_faulting_retried_action_execution_and_cancel_further_retries_when_user_delegate_does_not_observe_cancellationToken() + public async Task Should_report_cancellation_during_faulting_retried_action_execution_and_cancel_further_retries_when_user_delegate_does_not_observe_cancellationToken() { Func provider = _ => TimeSpan.Zero; @@ -603,15 +603,15 @@ public void Should_report_cancellation_during_faulting_retried_action_execution_ ActionObservesCancellation = false }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(2); } [Fact] - public void Should_report_cancellation_after_faulting_action_execution_and_cancel_further_retries_if_onRetry_invokes_cancellation() + public async Task Should_report_cancellation_after_faulting_action_execution_and_cancel_further_retries_if_onRetry_invokes_cancellation() { Func provider = _ => TimeSpan.Zero; @@ -636,15 +636,15 @@ public void Should_report_cancellation_after_faulting_action_execution_and_cance ActionObservesCancellation = false }; - policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) - .Should().Throw() - .And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute)) + .Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); } [Fact] - public void Should_execute_func_returning_value_when_cancellationToken_not_cancelled() + public async Task Should_execute_func_returning_value_when_cancellationToken_not_cancelled() { Func provider = _ => TimeSpan.Zero; @@ -666,7 +666,7 @@ public void Should_execute_func_returning_value_when_cancellationToken_not_cance }; Func action = async x => result = await x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, true); - policy.Awaiting(action).Should().NotThrow(); + await policy.Awaiting(action).Should().NotThrowAsync(); result.Should().BeTrue(); @@ -674,7 +674,7 @@ public void Should_execute_func_returning_value_when_cancellationToken_not_cance } [Fact] - public void Should_honour_and_report_cancellation_during_func_execution() + public async Task Should_honour_and_report_cancellation_during_func_execution() { Func provider = _ => TimeSpan.Zero; @@ -698,8 +698,8 @@ public void Should_honour_and_report_cancellation_during_func_execution() }; Func action = async x => result = await x.RaiseExceptionAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, true); - policy.Awaiting(action) - .Should().Throw().And.CancellationToken.Should().Be(cancellationToken); + var ex = await policy.Awaiting(action).Should().ThrowAsync(); + ex.And.CancellationToken.Should().Be(cancellationToken); result.Should().Be(null); diff --git a/src/Polly.Specs/Retry/WaitAndRetryForeverSpecs.cs b/src/Polly.Specs/Retry/WaitAndRetryForeverSpecs.cs index b7b795eaafe..cbd9a4752ea 100644 --- a/src/Polly.Specs/Retry/WaitAndRetryForeverSpecs.cs +++ b/src/Polly.Specs/Retry/WaitAndRetryForeverSpecs.cs @@ -201,7 +201,7 @@ public void Should_not_sleep_if_no_retries() [Fact] public void Should_call_onretry_on_each_retry_with_the_current_exception() { - var expectedExceptions = new object[] { "Exception #1", "Exception #2", "Exception #3" }; + var expectedExceptions = new string[] { "Exception #1", "Exception #2", "Exception #3" }; var retryExceptions = new List(); Func provider = _ => TimeSpan.Zero; diff --git a/src/Polly.Specs/Retry/WaitAndRetrySpecs.cs b/src/Polly.Specs/Retry/WaitAndRetrySpecs.cs index c95b002007e..022f45aa30b 100644 --- a/src/Polly.Specs/Retry/WaitAndRetrySpecs.cs +++ b/src/Polly.Specs/Retry/WaitAndRetrySpecs.cs @@ -210,14 +210,14 @@ public void Should_throw_when_exception_thrown_is_not_the_specified_exception_ty } [Fact] - public void Should_throw_when_exception_thrown_is_not_the_specified_exception_type_async() + public async Task Should_throw_when_exception_thrown_is_not_the_specified_exception_type_async() { var policy = Policy .Handle() .WaitAndRetryAsync(Enumerable.Empty()); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } [Fact] @@ -233,15 +233,15 @@ public void Should_throw_when_exception_thrown_is_not_one_of_the_specified_excep } [Fact] - public void Should_throw_when_exception_thrown_is_not_one_of_the_specified_exception_types_async() + public async Task Should_throw_when_exception_thrown_is_not_one_of_the_specified_exception_types_async() { var policy = Policy .Handle() .Or() .WaitAndRetryAsync(Enumerable.Empty()); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().Throw(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().ThrowAsync(); } [Fact] @@ -282,7 +282,7 @@ public void Should_not_throw_when_specified_exception_predicate_is_satisfied() } [Fact] - public void Should_not_throw_when_specified_exception_predicate_is_satisfied_async() + public async Task Should_not_throw_when_specified_exception_predicate_is_satisfied_async() { var policy = Policy .Handle(_ => true) @@ -291,8 +291,8 @@ public void Should_not_throw_when_specified_exception_predicate_is_satisfied_asy 1.Seconds() }); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().NotThrowAsync(); } [Fact] @@ -311,7 +311,7 @@ public void Should_not_throw_when_one_of_the_specified_exception_predicates_are_ } [Fact] - public void Should_not_throw_when_one_of_the_specified_exception_predicates_are_satisfied_async() + public async Task Should_not_throw_when_one_of_the_specified_exception_predicates_are_satisfied_async() { var policy = Policy .Handle(_ => true) @@ -321,8 +321,8 @@ public void Should_not_throw_when_one_of_the_specified_exception_predicates_are_ 1.Seconds() }); - policy.Awaiting(x => x.RaiseExceptionAsync()) - .Should().NotThrow(); + await policy.Awaiting(x => x.RaiseExceptionAsync()) + .Should().NotThrowAsync(); } [Fact] @@ -440,7 +440,7 @@ public void Should_call_onretry_on_each_retry_with_the_current_timespan() [Fact] public void Should_call_onretry_on_each_retry_with_the_current_exception() { - var expectedExceptions = new object[] { "Exception #1", "Exception #2", "Exception #3" }; + var expectedExceptions = new string[] { "Exception #1", "Exception #2", "Exception #3" }; var retryExceptions = new List(); var policy = Policy @@ -1097,7 +1097,7 @@ public void Should_honour_cancellation_immediately_during_wait_phase_of_waitandr attemptsInvoked.Should().Be(1); watch.Elapsed.Should().BeLessThan(retryDelay); - watch.Elapsed.Should().BeCloseTo(shimTimeSpan, precision: (int)(shimTimeSpan.TotalMilliseconds) / 2); // Consider increasing shimTimeSpan, or loosening precision, if test fails transiently in different environments. + watch.Elapsed.Should().BeCloseTo(shimTimeSpan, precision: TimeSpan.FromMilliseconds((int)shimTimeSpan.TotalMilliseconds / 2)); // Consider increasing shimTimeSpan, or loosening precision, if test fails transiently in different environments. } [Fact] diff --git a/src/Polly.Specs/Timeout/TimeoutAsyncSpecs.cs b/src/Polly.Specs/Timeout/TimeoutAsyncSpecs.cs index a1923d69f7e..949a4196a5b 100644 --- a/src/Polly.Specs/Timeout/TimeoutAsyncSpecs.cs +++ b/src/Polly.Specs/Timeout/TimeoutAsyncSpecs.cs @@ -199,17 +199,17 @@ public void Should_be_able_to_configure_with_timeout_func() #region Timeout operation - pessimistic [Fact] - public void Should_throw_when_timeout_is_less_than_execution_duration__pessimistic() + public async Task Should_throw_when_timeout_is_less_than_execution_duration__pessimistic() { TimeSpan timeout = TimeSpan.FromMilliseconds(50); var policy = Policy.TimeoutAsync(timeout, TimeoutStrategy.Pessimistic); - policy.Awaiting(p => p.ExecuteAsync(async () => + await policy.Awaiting(p => p.ExecuteAsync(async () => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); - })).Should().Throw(); + })).Should().ThrowAsync(); } [Fact] @@ -224,12 +224,12 @@ public void Should_not_throw_when_timeout_is_greater_than_execution_duration__pe result = await policy.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good)); }; - act.Should().NotThrow(); + act.Should().NotThrowAsync(); result.Should().Be(ResultPrimitive.Good); } [Fact] - public void Should_throw_timeout_after_correct_duration__pessimistic() + public async Task Should_throw_timeout_after_correct_duration__pessimistic() { Stopwatch watch = new Stopwatch(); @@ -239,23 +239,23 @@ public void Should_throw_timeout_after_correct_duration__pessimistic() TimeSpan tolerance = TimeSpan.FromSeconds(3); // Consider increasing tolerance, if test fails transiently in different test/build environments. watch.Start(); - policy.Awaiting(p => p.ExecuteAsync(async () => + await policy.Awaiting(p => p.ExecuteAsync(async () => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(10), CancellationToken.None); })) - .Should().Throw(); + .Should().ThrowAsync(); watch.Stop(); - watch.Elapsed.Should().BeCloseTo(timeout, ((int)tolerance.TotalMilliseconds)); + watch.Elapsed.Should().BeCloseTo(timeout, TimeSpan.FromMilliseconds(tolerance.TotalMilliseconds)); } [Fact] - public void Should_rethrow_exception_from_inside_delegate__pessimistic() + public async Task Should_rethrow_exception_from_inside_delegate__pessimistic() { var policy = Policy.TimeoutAsync(TimeSpan.FromSeconds(10), TimeoutStrategy.Pessimistic); - policy.Awaiting(p => p.ExecuteAsync(() => throw new NotImplementedException())).Should().Throw(); + await policy.Awaiting(p => p.ExecuteAsync(() => throw new NotImplementedException())).Should().ThrowAsync(); } #endregion @@ -264,19 +264,19 @@ public void Should_rethrow_exception_from_inside_delegate__pessimistic() #region Timeout operation - optimistic [Fact] - public void Should_throw_when_timeout_is_less_than_execution_duration__optimistic() + public async Task Should_throw_when_timeout_is_less_than_execution_duration__optimistic() { TimeSpan timeout = TimeSpan.FromMilliseconds(50); var policy = Policy.TimeoutAsync(timeout, TimeoutStrategy.Optimistic); var userCancellationToken = CancellationToken.None; - policy.Awaiting(p => p.ExecuteAsync(async ct => + await policy.Awaiting(p => p.ExecuteAsync(async ct => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), ct); }, userCancellationToken)) - .Should().Throw(); + .Should().ThrowAsync(); } [Fact] @@ -294,12 +294,12 @@ public void Should_not_throw_when_timeout_is_greater_than_execution_duration__op }, userCancellationToken); }; - act.Should().NotThrow(); + act.Should().NotThrowAsync(); result.Should().Be(ResultPrimitive.Good); } [Fact] - public void Should_throw_timeout_after_correct_duration__optimistic() + public async Task Should_throw_timeout_after_correct_duration__optimistic() { Stopwatch watch = new Stopwatch(); @@ -310,23 +310,22 @@ public void Should_throw_timeout_after_correct_duration__optimistic() TimeSpan tolerance = TimeSpan.FromSeconds(3); // Consider increasing tolerance, if test fails transiently in different test/build environments. watch.Start(); - policy.Awaiting(p => p.ExecuteAsync(async ct => + await policy.Awaiting(p => p.ExecuteAsync(async ct => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(10), ct); - }, userCancellationToken)) - .Should().Throw(); + .Should().ThrowAsync(); watch.Stop(); - watch.Elapsed.Should().BeCloseTo(timeout, ((int)tolerance.TotalMilliseconds)); + watch.Elapsed.Should().BeCloseTo(timeout, TimeSpan.FromMilliseconds(tolerance.TotalMilliseconds)); } [Fact] - public void Should_rethrow_exception_from_inside_delegate__optimistic() + public async Task Should_rethrow_exception_from_inside_delegate__optimistic() { var policy = Policy.TimeoutAsync(TimeSpan.FromSeconds(10), TimeoutStrategy.Optimistic); - policy.Awaiting(p => p.ExecuteAsync(() => throw new NotImplementedException())).Should().Throw(); + await policy.Awaiting(p => p.ExecuteAsync(() => throw new NotImplementedException())).Should().ThrowAsync(); } #endregion @@ -334,26 +333,26 @@ public void Should_rethrow_exception_from_inside_delegate__optimistic() #region Non-timeout cancellation - pessimistic (user-delegate does not observe cancellation) [Fact] - public void Should_not_be_able_to_cancel_with_unobserved_user_cancellation_token_before_timeout__pessimistic() + public async Task Should_not_be_able_to_cancel_with_unobserved_user_cancellation_token_before_timeout__pessimistic() { int timeout = 5; var policy = Policy.TimeoutAsync(timeout, TimeoutStrategy.Pessimistic); using (CancellationTokenSource userTokenSource = new CancellationTokenSource()) { - policy.Awaiting(p => p.ExecuteAsync(async + await policy.Awaiting(p => p.ExecuteAsync(async _ => { userTokenSource.Cancel(); // User token cancels in the middle of execution ... await SystemClock.SleepAsync(TimeSpan.FromSeconds(timeout * 2), CancellationToken.None // ... but if the executed delegate does not observe it ); }, userTokenSource.Token) - ).Should().Throw(); // ... it's still the timeout we expect. + ).Should().ThrowAsync(); // ... it's still the timeout we expect. } } [Fact] - public void Should_not_execute_user_delegate_if_user_cancellationToken_cancelled_before_delegate_reached__pessimistic() + public async Task Should_not_execute_user_delegate_if_user_cancellationToken_cancelled_before_delegate_reached__pessimistic() { var policy = Policy.TimeoutAsync(10, TimeoutStrategy.Pessimistic); @@ -363,12 +362,12 @@ public void Should_not_execute_user_delegate_if_user_cancellationToken_cancelled { cts.Cancel(); - policy.Awaiting(p => p.ExecuteAsync(_ => + await policy.Awaiting(p => p.ExecuteAsync(_ => { executed = true; return TaskHelper.EmptyTask; }, cts.Token)) - .Should().Throw(); + .Should().ThrowAsync(); } executed.Should().BeFalse(); @@ -379,24 +378,24 @@ public void Should_not_execute_user_delegate_if_user_cancellationToken_cancelled #region Non-timeout cancellation - optimistic (user-delegate observes cancellation) [Fact] - public void Should_be_able_to_cancel_with_user_cancellation_token_before_timeout__optimistic() + public async Task Should_be_able_to_cancel_with_user_cancellation_token_before_timeout__optimistic() { int timeout = 10; var policy = Policy.TimeoutAsync(timeout, TimeoutStrategy.Optimistic); using (CancellationTokenSource userTokenSource = new CancellationTokenSource()) { - policy.Awaiting(p => p.ExecuteAsync( + await policy.Awaiting(p => p.ExecuteAsync( ct => { userTokenSource.Cancel(); ct.ThrowIfCancellationRequested(); // Simulate cancel in the middle of execution return TaskHelper.EmptyTask; }, userTokenSource.Token) // ... with user token. - ).Should().Throw(); + ).Should().ThrowAsync(); } } [Fact] - public void Should_not_execute_user_delegate_if_user_cancellationToken_cancelled_before_delegate_reached__optimistic() + public async Task Should_not_execute_user_delegate_if_user_cancellationToken_cancelled_before_delegate_reached__optimistic() { var policy = Policy.TimeoutAsync(10, TimeoutStrategy.Optimistic); @@ -406,25 +405,25 @@ public void Should_not_execute_user_delegate_if_user_cancellationToken_cancelled { cts.Cancel(); - policy.Awaiting(p => p.ExecuteAsync(_ => + await policy.Awaiting(p => p.ExecuteAsync(_ => { executed = true; return TaskHelper.EmptyTask; }, cts.Token)) - .Should().Throw(); + .Should().ThrowAsync(); } executed.Should().BeFalse(); } [Fact] - public void Should_not_mask_user_exception_if_user_exception_overlaps_with_timeout() + public async Task Should_not_mask_user_exception_if_user_exception_overlaps_with_timeout() { var userException = new Exception(); var shimTimeSpan = TimeSpan.FromSeconds(0.2); var policy = Policy.TimeoutAsync(shimTimeSpan, TimeoutStrategy.Optimistic); - var thrown = policy.Awaiting(p => p.ExecuteAsync(async _ => + var thrown = await policy.Awaiting(p => p.ExecuteAsync(async _ => { try { @@ -443,13 +442,12 @@ public void Should_not_mask_user_exception_if_user_exception_overlaps_with_timeo }, CancellationToken.None)) .Should() - .Throw() - .Which; + .ThrowAsync(); - thrown.Should().NotBeOfType(); - thrown.Should().NotBeOfType(); - thrown.Should().NotBeOfType(); - thrown.Should().BeSameAs(userException); + thrown.NotBeOfType(); + thrown.NotBeOfType(); + thrown.NotBeOfType(); + thrown.Which.Should().BeSameAs(userException); } #endregion @@ -457,7 +455,7 @@ public void Should_not_mask_user_exception_if_user_exception_overlaps_with_timeo #region onTimeout overload - pessimistic [Fact] - public void Should_call_ontimeout_with_configured_timeout__pessimistic() + public async Task Should_call_ontimeout_with_configured_timeout__pessimistic() { TimeSpan timeoutPassedToConfiguration = TimeSpan.FromMilliseconds(250); @@ -470,18 +468,17 @@ public void Should_call_ontimeout_with_configured_timeout__pessimistic() var policy = Policy.TimeoutAsync(timeoutPassedToConfiguration, TimeoutStrategy.Pessimistic, onTimeoutAsync); - policy.Awaiting(p => p.ExecuteAsync(async () => + await policy.Awaiting(p => p.ExecuteAsync(async () => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); - })) - .Should().Throw(); + .Should().ThrowAsync(); timeoutPassedToOnTimeout.Should().Be(timeoutPassedToConfiguration); } [Fact] - public void Should_call_ontimeout_with_passed_context__pessimistic() + public async Task Should_call_ontimeout_with_passed_context__pessimistic() { string operationKey = "SomeKey"; Context contextPassedToExecute = new Context(operationKey); @@ -496,12 +493,11 @@ public void Should_call_ontimeout_with_passed_context__pessimistic() TimeSpan timeout = TimeSpan.FromMilliseconds(250); var policy = Policy.TimeoutAsync(timeout, TimeoutStrategy.Pessimistic, onTimeoutAsync); - policy.Awaiting(p => p.ExecuteAsync(async _ => + await policy.Awaiting(p => p.ExecuteAsync(async _ => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); - }, contextPassedToExecute)) - .Should().Throw(); + .Should().ThrowAsync(); contextPassedToOnTimeout.Should().NotBeNull(); contextPassedToOnTimeout.OperationKey.Should().Be(operationKey); @@ -512,7 +508,7 @@ public void Should_call_ontimeout_with_passed_context__pessimistic() [InlineData(1)] [InlineData(2)] [InlineData(3)] - public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execution_by_evaluating_func__pessimistic(int programaticallyControlledDelay) + public async Task Should_call_ontimeout_with_timeout_supplied_different_for_each_execution_by_evaluating_func__pessimistic(int programaticallyControlledDelay) { Func timeoutFunc = () => TimeSpan.FromMilliseconds(25*programaticallyControlledDelay); @@ -525,11 +521,11 @@ public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execu var policy = Policy.TimeoutAsync(timeoutFunc, TimeoutStrategy.Pessimistic, onTimeoutAsync); - policy.Awaiting(p => p.ExecuteAsync(async () => + await policy.Awaiting(p => p.ExecuteAsync(async () => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); })) - .Should().Throw(); + .Should().ThrowAsync(); timeoutPassedToOnTimeout.Should().Be(timeoutFunc()); } @@ -538,7 +534,7 @@ public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execu [InlineData(1)] [InlineData(2)] [InlineData(3)] - public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execution_by_evaluating_func_influenced_by_context__pessimistic(int programaticallyControlledDelay) + public async Task Should_call_ontimeout_with_timeout_supplied_different_for_each_execution_by_evaluating_func_influenced_by_context__pessimistic(int programaticallyControlledDelay) { Func timeoutProvider = ctx => (TimeSpan)ctx["timeout"]; @@ -554,17 +550,17 @@ public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execu // Supply a programatically-controlled timeout, via the execution context. Context context = new Context("SomeOperationKey") { ["timeout"] = TimeSpan.FromMilliseconds(25 * programaticallyControlledDelay) }; - policy.Awaiting(p => p.ExecuteAsync(async _ => + await policy.Awaiting(p => p.ExecuteAsync(async _ => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); }, context)) - .Should().Throw(); + .Should().ThrowAsync(); timeoutPassedToOnTimeout.Should().Be(timeoutProvider(context)); } [Fact] - public void Should_call_ontimeout_with_task_wrapping_abandoned_action__pessimistic() + public async Task Should_call_ontimeout_with_task_wrapping_abandoned_action__pessimistic() { Task taskPassedToOnTimeout = null; Func onTimeoutAsync = (_, _, task) => @@ -576,11 +572,11 @@ public void Should_call_ontimeout_with_task_wrapping_abandoned_action__pessimist TimeSpan timeout = TimeSpan.FromMilliseconds(250); var policy = Policy.TimeoutAsync(timeout, TimeoutStrategy.Pessimistic, onTimeoutAsync); - policy.Awaiting(p => p.ExecuteAsync(async () => + await policy.Awaiting(p => p.ExecuteAsync(async () => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); })) - .Should().Throw(); + .Should().ThrowAsync(); taskPassedToOnTimeout.Should().NotBeNull(); } @@ -605,12 +601,12 @@ public async Task Should_call_ontimeout_with_task_wrapping_abandoned_action_allo TimeSpan thriceShimTimeSpan = shimTimespan + shimTimespan + shimTimespan; var policy = Policy.TimeoutAsync(shimTimespan, TimeoutStrategy.Pessimistic, onTimeoutAsync); - policy.Awaiting(p => p.ExecuteAsync(async () => + await policy.Awaiting(p => p.ExecuteAsync(async () => { await SystemClock.SleepAsync(thriceShimTimeSpan, CancellationToken.None); throw exceptionToThrow; })) - .Should().Throw(); + .Should().ThrowAsync(); await SystemClock.SleepAsync(thriceShimTimeSpan, CancellationToken.None); exceptionObservedFromTaskPassedToOnTimeout.Should().NotBeNull(); @@ -619,7 +615,7 @@ public async Task Should_call_ontimeout_with_task_wrapping_abandoned_action_allo } [Fact] - public void Should_call_ontimeout_with_timing_out_exception__pessimistic() + public async Task Should_call_ontimeout_with_timing_out_exception__pessimistic() { TimeSpan timeoutPassedToConfiguration = TimeSpan.FromMilliseconds(250); @@ -632,12 +628,11 @@ public void Should_call_ontimeout_with_timing_out_exception__pessimistic() var policy = Policy.TimeoutAsync(timeoutPassedToConfiguration, TimeoutStrategy.Pessimistic, onTimeoutAsync); - policy.Awaiting(p => p.ExecuteAsync(async () => + await policy.Awaiting(p => p.ExecuteAsync(async () => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); - })) - .Should().Throw(); + .Should().ThrowAsync(); exceptionPassedToOnTimeout.Should().NotBeNull(); exceptionPassedToOnTimeout.Should().BeOfType(typeof(OperationCanceledException)); @@ -648,7 +643,7 @@ public void Should_call_ontimeout_with_timing_out_exception__pessimistic() #region onTimeout overload - optimistic [Fact] - public void Should_call_ontimeout_with_configured_timeout__optimistic() + public async Task Should_call_ontimeout_with_configured_timeout__optimistic() { TimeSpan timeoutPassedToConfiguration = TimeSpan.FromMilliseconds(250); @@ -662,18 +657,17 @@ public void Should_call_ontimeout_with_configured_timeout__optimistic() var policy = Policy.TimeoutAsync(timeoutPassedToConfiguration, TimeoutStrategy.Optimistic, onTimeoutAsync); var userCancellationToken = CancellationToken.None; - policy.Awaiting(p => p.ExecuteAsync(async ct => + await policy.Awaiting(p => p.ExecuteAsync(async ct => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), ct); - }, userCancellationToken)) - .Should().Throw(); + .Should().ThrowAsync(); timeoutPassedToOnTimeout.Should().Be(timeoutPassedToConfiguration); } [Fact] - public void Should_call_ontimeout_with_passed_context__optimistic() + public async Task Should_call_ontimeout_with_passed_context__optimistic() { string operationKey = "SomeKey"; Context contextPassedToExecute = new Context(operationKey); @@ -689,12 +683,11 @@ public void Should_call_ontimeout_with_passed_context__optimistic() var policy = Policy.TimeoutAsync(timeout, TimeoutStrategy.Optimistic, onTimeoutAsync); var userCancellationToken = CancellationToken.None; - policy.Awaiting(p => p.ExecuteAsync(async (_, ct) => + await policy.Awaiting(p => p.ExecuteAsync(async (_, ct) => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), ct); - }, contextPassedToExecute, userCancellationToken)) - .Should().Throw(); + .Should().ThrowAsync(); contextPassedToOnTimeout.Should().NotBeNull(); contextPassedToOnTimeout.OperationKey.Should().Be(operationKey); @@ -705,7 +698,7 @@ public void Should_call_ontimeout_with_passed_context__optimistic() [InlineData(1)] [InlineData(2)] [InlineData(3)] - public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execution_by_evaluating_func__optimistic(int programaticallyControlledDelay) + public async Task Should_call_ontimeout_with_timeout_supplied_different_for_each_execution_by_evaluating_func__optimistic(int programaticallyControlledDelay) { Func timeoutFunc = () => TimeSpan.FromMilliseconds(25* programaticallyControlledDelay); @@ -719,12 +712,11 @@ public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execu var policy = Policy.TimeoutAsync(timeoutFunc, TimeoutStrategy.Optimistic, onTimeoutAsync); var userCancellationToken = CancellationToken.None; - policy.Awaiting(p => p.ExecuteAsync(async ct => + await policy.Awaiting(p => p.ExecuteAsync(async ct => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), ct); - }, userCancellationToken)) - .Should().Throw(); + .Should().ThrowAsync(); timeoutPassedToOnTimeout.Should().Be(timeoutFunc()); } @@ -733,7 +725,7 @@ public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execu [InlineData(1)] [InlineData(2)] [InlineData(3)] - public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execution_by_evaluating_func_influenced_by_context__optimistic(int programaticallyControlledDelay) + public async Task Should_call_ontimeout_with_timeout_supplied_different_for_each_execution_by_evaluating_func_influenced_by_context__optimistic(int programaticallyControlledDelay) { Func timeoutProvider = ctx => (TimeSpan)ctx["timeout"]; @@ -753,18 +745,18 @@ public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execu ["timeout"] = TimeSpan.FromMilliseconds(25 * programaticallyControlledDelay) }; - policy.Awaiting(p => p.ExecuteAsync(async (_, ct) => + await policy.Awaiting(p => p.ExecuteAsync(async (_, ct) => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), ct); }, context, userCancellationToken)) - .Should().Throw(); + .Should().ThrowAsync(); timeoutPassedToOnTimeout.Should().Be(timeoutProvider(context)); } [Fact] - public void Should_call_ontimeout_but_not_with_task_wrapping_abandoned_action__optimistic() + public async Task Should_call_ontimeout_but_not_with_task_wrapping_abandoned_action__optimistic() { Task taskPassedToOnTimeout = null; Func onTimeoutAsync = (_, _, task) => @@ -777,18 +769,17 @@ public void Should_call_ontimeout_but_not_with_task_wrapping_abandoned_action__o var policy = Policy.TimeoutAsync(timeout, TimeoutStrategy.Optimistic, onTimeoutAsync); var userCancellationToken = CancellationToken.None; - policy.Awaiting(p => p.ExecuteAsync(async ct => + await policy.Awaiting(p => p.ExecuteAsync(async ct => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), ct); - }, userCancellationToken)) - .Should().Throw(); + .Should().ThrowAsync(); taskPassedToOnTimeout.Should().BeNull(); } [Fact] - public void Should_call_ontimeout_with_timing_out_exception__optimistic() + public async Task Should_call_ontimeout_with_timing_out_exception__optimistic() { TimeSpan timeoutPassedToConfiguration = TimeSpan.FromMilliseconds(250); @@ -802,12 +793,11 @@ public void Should_call_ontimeout_with_timing_out_exception__optimistic() var policy = Policy.TimeoutAsync(timeoutPassedToConfiguration, TimeoutStrategy.Optimistic, onTimeoutAsync); var userCancellationToken = CancellationToken.None; - policy.Awaiting(p => p.ExecuteAsync(async ct => + await policy.Awaiting(p => p.ExecuteAsync(async ct => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), ct); - }, userCancellationToken)) - .Should().Throw(); + .Should().ThrowAsync(); exceptionPassedToOnTimeout.Should().NotBeNull(); exceptionPassedToOnTimeout.Should().BeOfType(typeof(OperationCanceledException)); diff --git a/src/Polly.Specs/Timeout/TimeoutSpecs.cs b/src/Polly.Specs/Timeout/TimeoutSpecs.cs index c8bc4aa1342..ba832b25c96 100644 --- a/src/Polly.Specs/Timeout/TimeoutSpecs.cs +++ b/src/Polly.Specs/Timeout/TimeoutSpecs.cs @@ -260,7 +260,7 @@ public void Should_throw_timeout_after_correct_duration__pessimistic() .Should().Throw(); watch.Stop(); - watch.Elapsed.Should().BeCloseTo(timeout, ((int)tolerance.TotalMilliseconds)); + watch.Elapsed.Should().BeCloseTo(timeout, TimeSpan.FromMilliseconds(tolerance.TotalMilliseconds)); } [Fact] @@ -401,7 +401,7 @@ public void Should_throw_timeout_after_correct_duration__optimistic() .Should().Throw(); watch.Stop(); - watch.Elapsed.Should().BeCloseTo(timeout, ((int)tolerance.TotalMilliseconds)); + watch.Elapsed.Should().BeCloseTo(timeout, TimeSpan.FromMilliseconds(tolerance.TotalMilliseconds)); } [Fact] diff --git a/src/Polly.Specs/Timeout/TimeoutTResultAsyncSpecs.cs b/src/Polly.Specs/Timeout/TimeoutTResultAsyncSpecs.cs index a178dbbfd1d..de3b85e60b4 100644 --- a/src/Polly.Specs/Timeout/TimeoutTResultAsyncSpecs.cs +++ b/src/Polly.Specs/Timeout/TimeoutTResultAsyncSpecs.cs @@ -200,17 +200,17 @@ public void Should_be_able_to_configure_with_timeout_func() #region Timeout operation - pessimistic [Fact] - public void Should_throw_when_timeout_is_less_than_execution_duration__pessimistic() + public async Task Should_throw_when_timeout_is_less_than_execution_duration__pessimistic() { TimeSpan timeout = TimeSpan.FromMilliseconds(50); var policy = Policy.TimeoutAsync(timeout, TimeoutStrategy.Pessimistic); - policy.Awaiting(p => p.ExecuteAsync(async () => + await policy.Awaiting(p => p.ExecuteAsync(async () => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); return ResultPrimitive.WhateverButTooLate; - })).Should().Throw(); + })).Should().ThrowAsync(); } [Fact] @@ -222,12 +222,12 @@ public void Should_not_throw_when_timeout_is_greater_than_execution_duration__pe Func act = async () => result = await policy.ExecuteAsync(() => Task.FromResult(ResultPrimitive.Good)); - act.Should().NotThrow(); + act.Should().NotThrowAsync(); result.Should().Be(ResultPrimitive.Good); } [Fact] - public void Should_throw_timeout_after_correct_duration__pessimistic() + public async Task Should_throw_timeout_after_correct_duration__pessimistic() { Stopwatch watch = new Stopwatch(); @@ -237,23 +237,23 @@ public void Should_throw_timeout_after_correct_duration__pessimistic() TimeSpan tolerance = TimeSpan.FromSeconds(3); // Consider increasing tolerance, if test fails transiently in different test/build environments. watch.Start(); - policy.Awaiting(p => p.ExecuteAsync(async () => + await policy.Awaiting(p => p.ExecuteAsync(async () => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(10), CancellationToken.None); return ResultPrimitive.WhateverButTooLate; })) - .Should().Throw(); + .Should().ThrowAsync(); watch.Stop(); - watch.Elapsed.Should().BeCloseTo(timeout, ((int)tolerance.TotalMilliseconds)); + watch.Elapsed.Should().BeCloseTo(timeout, TimeSpan.FromMilliseconds(tolerance.TotalMilliseconds)); } [Fact] - public void Should_rethrow_exception_from_inside_delegate__pessimistic() + public async Task Should_rethrow_exception_from_inside_delegate__pessimistic() { var policy = Policy.TimeoutAsync(TimeSpan.FromSeconds(10), TimeoutStrategy.Pessimistic); - policy.Awaiting(p => p.ExecuteAsync(() => throw new NotImplementedException())).Should().Throw(); + await policy.Awaiting(p => p.ExecuteAsync(() => throw new NotImplementedException())).Should().ThrowAsync(); } #endregion @@ -261,16 +261,16 @@ public void Should_rethrow_exception_from_inside_delegate__pessimistic() #region Timeout operation - optimistic [Fact] - public void Should_throw_when_timeout_is_less_than_execution_duration__optimistic() + public async Task Should_throw_when_timeout_is_less_than_execution_duration__optimistic() { var policy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(50), TimeoutStrategy.Optimistic); var userCancellationToken = CancellationToken.None; - policy.Awaiting(p => p.ExecuteAsync(async ct => + await policy.Awaiting(p => p.ExecuteAsync(async ct => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), ct); return ResultPrimitive.WhateverButTooLate; - }, userCancellationToken)).Should().Throw(); + }, userCancellationToken)).Should().ThrowAsync(); } [Fact] @@ -283,12 +283,12 @@ public void Should_not_throw_when_timeout_is_greater_than_execution_duration__op Func act = async () => result = await policy.ExecuteAsync(_ => Task.FromResult(ResultPrimitive.Good), userCancellationToken); - act.Should().NotThrow(); + act.Should().NotThrowAsync(); result.Should().Be(ResultPrimitive.Good); } [Fact] - public void Should_throw_timeout_after_correct_duration__optimistic() + public async Task Should_throw_timeout_after_correct_duration__optimistic() { Stopwatch watch = new Stopwatch(); @@ -299,23 +299,23 @@ public void Should_throw_timeout_after_correct_duration__optimistic() TimeSpan tolerance = TimeSpan.FromSeconds(3); // Consider increasing tolerance, if test fails transiently in different test/build environments. watch.Start(); - policy.Awaiting(p => p.ExecuteAsync(async ct => + await policy.Awaiting(p => p.ExecuteAsync(async ct => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(10), ct); return ResultPrimitive.WhateverButTooLate; }, userCancellationToken)) - .Should().Throw(); + .Should().ThrowAsync(); watch.Stop(); - watch.Elapsed.Should().BeCloseTo(timeout, ((int)tolerance.TotalMilliseconds)); + watch.Elapsed.Should().BeCloseTo(timeout, TimeSpan.FromMilliseconds(tolerance.TotalMilliseconds)); } [Fact] - public void Should_rethrow_exception_from_inside_delegate__optimistic() + public async Task Should_rethrow_exception_from_inside_delegate__optimistic() { var policy = Policy.TimeoutAsync(TimeSpan.FromSeconds(10), TimeoutStrategy.Optimistic); - policy.Awaiting(p => p.ExecuteAsync(() => throw new NotImplementedException())).Should().Throw(); + await policy.Awaiting(p => p.ExecuteAsync(() => throw new NotImplementedException())).Should().ThrowAsync(); } #endregion @@ -323,14 +323,14 @@ public void Should_rethrow_exception_from_inside_delegate__optimistic() #region Non-timeout cancellation - pessimistic (user-delegate does not observe cancellation) [Fact] - public void Should_not_be_able_to_cancel_with_unobserved_user_cancellation_token_before_timeout__pessimistic() + public async Task Should_not_be_able_to_cancel_with_unobserved_user_cancellation_token_before_timeout__pessimistic() { int timeout = 5; var policy = Policy.TimeoutAsync(timeout, TimeoutStrategy.Pessimistic); using (CancellationTokenSource userTokenSource = new CancellationTokenSource()) { - policy.Awaiting(p => p.ExecuteAsync(async + await policy.Awaiting(p => p.ExecuteAsync(async _ => { userTokenSource.Cancel(); // User token cancels in the middle of execution ... await SystemClock.SleepAsync(TimeSpan.FromSeconds(timeout * 2), @@ -338,12 +338,12 @@ await SystemClock.SleepAsync(TimeSpan.FromSeconds(timeout * 2), ); return ResultPrimitive.WhateverButTooLate; }, userTokenSource.Token) - ).Should().Throw(); // ... it's still the timeout we expect. + ).Should().ThrowAsync(); // ... it's still the timeout we expect. } } [Fact] - public void Should_not_execute_user_delegate_if_user_cancellationToken_cancelled_before_delegate_reached__pessimistic() + public async Task Should_not_execute_user_delegate_if_user_cancellationToken_cancelled_before_delegate_reached__pessimistic() { var policy = Policy.TimeoutAsync(10, TimeoutStrategy.Pessimistic); @@ -353,13 +353,13 @@ public void Should_not_execute_user_delegate_if_user_cancellationToken_cancelled { cts.Cancel(); - policy.Awaiting(p => p.ExecuteAsync(async _ => + await policy.Awaiting(p => p.ExecuteAsync(async _ => { executed = true; await TaskHelper.EmptyTask; return ResultPrimitive.WhateverButTooLate; }, cts.Token)) - .Should().Throw(); + .Should().ThrowAsync(); } executed.Should().BeFalse(); @@ -370,23 +370,23 @@ public void Should_not_execute_user_delegate_if_user_cancellationToken_cancelled #region Non-timeout cancellation - optimistic (user-delegate observes cancellation) [Fact] - public void Should_be_able_to_cancel_with_user_cancellation_token_before_timeout__optimistic() + public async Task Should_be_able_to_cancel_with_user_cancellation_token_before_timeout__optimistic() { int timeout = 10; var policy = Policy.TimeoutAsync(timeout, TimeoutStrategy.Optimistic); using (CancellationTokenSource userTokenSource = new CancellationTokenSource()) { - policy.Awaiting(p => p.ExecuteAsync( + await policy.Awaiting(p => p.ExecuteAsync( ct => { userTokenSource.Cancel(); ct.ThrowIfCancellationRequested(); // Simulate cancel in the middle of execution return Task.FromResult(ResultPrimitive.WhateverButTooLate); }, userTokenSource.Token) // ... with user token. - ).Should().Throw(); + ).Should().ThrowAsync(); } } [Fact] - public void Should_not_execute_user_delegate_if_user_cancellationToken_cancelled_before_delegate_reached__optimistic() + public async Task Should_not_execute_user_delegate_if_user_cancellationToken_cancelled_before_delegate_reached__optimistic() { var policy = Policy.TimeoutAsync(10, TimeoutStrategy.Optimistic); @@ -396,13 +396,13 @@ public void Should_not_execute_user_delegate_if_user_cancellationToken_cancelled { cts.Cancel(); - policy.Awaiting(p => p.ExecuteAsync(async _ => + await policy.Awaiting(p => p.ExecuteAsync(async _ => { executed = true; await TaskHelper.EmptyTask; return ResultPrimitive.WhateverButTooLate; }, cts.Token)) - .Should().Throw(); + .Should().ThrowAsync(); } executed.Should().BeFalse(); @@ -413,7 +413,7 @@ public void Should_not_execute_user_delegate_if_user_cancellationToken_cancelled #region onTimeout overload - pessimistic [Fact] - public void Should_call_ontimeout_with_configured_timeout__pessimistic() + public async Task Should_call_ontimeout_with_configured_timeout__pessimistic() { TimeSpan timeoutPassedToConfiguration = TimeSpan.FromMilliseconds(250); @@ -426,18 +426,18 @@ public void Should_call_ontimeout_with_configured_timeout__pessimistic() var policy = Policy.TimeoutAsync(timeoutPassedToConfiguration, TimeoutStrategy.Pessimistic, onTimeoutAsync); - policy.Awaiting(p => p.ExecuteAsync(async () => + await policy.Awaiting(p => p.ExecuteAsync(async () => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); return ResultPrimitive.WhateverButTooLate; })) - .Should().Throw(); + .Should().ThrowAsync(); timeoutPassedToOnTimeout.Should().Be(timeoutPassedToConfiguration); } [Fact] - public void Should_call_ontimeout_with_passed_context__pessimistic() + public async Task Should_call_ontimeout_with_passed_context__pessimistic() { string operationKey = "SomeKey"; Context contextPassedToExecute = new Context(operationKey); @@ -452,12 +452,12 @@ public void Should_call_ontimeout_with_passed_context__pessimistic() TimeSpan timeout = TimeSpan.FromMilliseconds(250); var policy = Policy.TimeoutAsync(timeout, TimeoutStrategy.Pessimistic, onTimeoutAsync); - policy.Awaiting(p => p.ExecuteAsync(async _ => + await policy.Awaiting(p => p.ExecuteAsync(async _ => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); return ResultPrimitive.WhateverButTooLate; }, contextPassedToExecute)) - .Should().Throw(); + .Should().ThrowAsync(); contextPassedToOnTimeout.Should().NotBeNull(); contextPassedToOnTimeout.OperationKey.Should().Be(operationKey); @@ -468,7 +468,7 @@ public void Should_call_ontimeout_with_passed_context__pessimistic() [InlineData(1)] [InlineData(2)] [InlineData(3)] - public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execution_by_evaluating_func__pessimistic(int programaticallyControlledDelay) + public async Task Should_call_ontimeout_with_timeout_supplied_different_for_each_execution_by_evaluating_func__pessimistic(int programaticallyControlledDelay) { Func timeoutFunc = () => TimeSpan.FromMilliseconds(25* programaticallyControlledDelay); @@ -481,12 +481,12 @@ public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execu var policy = Policy.TimeoutAsync(timeoutFunc, TimeoutStrategy.Pessimistic, onTimeoutAsync); - policy.Awaiting(p => p.ExecuteAsync(async () => + await policy.Awaiting(p => p.ExecuteAsync(async () => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); return ResultPrimitive.WhateverButTooLate; })) - .Should().Throw(); + .Should().ThrowAsync(); timeoutPassedToOnTimeout.Should().Be(timeoutFunc()); } @@ -495,7 +495,7 @@ public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execu [InlineData(1)] [InlineData(2)] [InlineData(3)] - public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execution_by_evaluating_func_influenced_by_context__pessimistic(int programaticallyControlledDelay) + public async Task Should_call_ontimeout_with_timeout_supplied_different_for_each_execution_by_evaluating_func_influenced_by_context__pessimistic(int programaticallyControlledDelay) { Func timeoutProvider = ctx => (TimeSpan)ctx["timeout"]; @@ -511,18 +511,18 @@ public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execu // Supply a programatically-controlled timeout, via the execution context. Context context = new Context("SomeOperationKey") { ["timeout"] = TimeSpan.FromMilliseconds(25 * programaticallyControlledDelay) }; - policy.Awaiting(p => p.ExecuteAsync(async _ => + await policy.Awaiting(p => p.ExecuteAsync(async _ => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); return ResultPrimitive.WhateverButTooLate; }, context)) - .Should().Throw(); + .Should().ThrowAsync(); timeoutPassedToOnTimeout.Should().Be(timeoutProvider(context)); } [Fact] - public void Should_call_ontimeout_with_task_wrapping_abandoned_action__pessimistic() + public async Task Should_call_ontimeout_with_task_wrapping_abandoned_action__pessimistic() { Task taskPassedToOnTimeout = null; Func onTimeoutAsync = (_, _, task) => @@ -534,12 +534,12 @@ public void Should_call_ontimeout_with_task_wrapping_abandoned_action__pessimist TimeSpan timeout = TimeSpan.FromMilliseconds(250); var policy = Policy.TimeoutAsync(timeout, TimeoutStrategy.Pessimistic, onTimeoutAsync); - policy.Awaiting(p => p.ExecuteAsync(async () => + await policy.Awaiting(p => p.ExecuteAsync(async () => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); return ResultPrimitive.WhateverButTooLate; })) - .Should().Throw(); + .Should().ThrowAsync(); taskPassedToOnTimeout.Should().NotBeNull(); } @@ -564,12 +564,12 @@ public async Task Should_call_ontimeout_with_task_wrapping_abandoned_action_allo TimeSpan thriceShimTimeSpan = shimTimespan + shimTimespan + shimTimespan; var policy = Policy.TimeoutAsync(shimTimespan, TimeoutStrategy.Pessimistic, onTimeoutAsync); - policy.Awaiting(p => p.ExecuteAsync(async () => + await policy.Awaiting(p => p.ExecuteAsync(async () => { await SystemClock.SleepAsync(thriceShimTimeSpan, CancellationToken.None); throw exceptionToThrow; })) - .Should().Throw(); + .Should().ThrowAsync(); await SystemClock.SleepAsync(thriceShimTimeSpan, CancellationToken.None); exceptionObservedFromTaskPassedToOnTimeout.Should().NotBeNull(); @@ -578,7 +578,7 @@ public async Task Should_call_ontimeout_with_task_wrapping_abandoned_action_allo } [Fact] - public void Should_call_ontimeout_with_timing_out_exception__pessimistic() + public async Task Should_call_ontimeout_with_timing_out_exception__pessimistic() { TimeSpan timeoutPassedToConfiguration = TimeSpan.FromMilliseconds(250); @@ -591,12 +591,12 @@ public void Should_call_ontimeout_with_timing_out_exception__pessimistic() var policy = Policy.TimeoutAsync(timeoutPassedToConfiguration, TimeoutStrategy.Pessimistic, onTimeoutAsync); - policy.Awaiting(p => p.ExecuteAsync(async () => + await policy.Awaiting(p => p.ExecuteAsync(async () => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); return ResultPrimitive.WhateverButTooLate; })) - .Should().Throw(); + .Should().ThrowAsync(); exceptionPassedToOnTimeout.Should().NotBeNull(); exceptionPassedToOnTimeout.Should().BeOfType(typeof(OperationCanceledException)); @@ -607,7 +607,7 @@ public void Should_call_ontimeout_with_timing_out_exception__pessimistic() #region onTimeout overload - optimistic [Fact] - public void Should_call_ontimeout_with_configured_timeout__optimistic() + public async Task Should_call_ontimeout_with_configured_timeout__optimistic() { TimeSpan timeoutPassedToConfiguration = TimeSpan.FromMilliseconds(250); @@ -621,18 +621,18 @@ public void Should_call_ontimeout_with_configured_timeout__optimistic() var policy = Policy.TimeoutAsync(timeoutPassedToConfiguration, TimeoutStrategy.Optimistic, onTimeoutAsync); var userCancellationToken = CancellationToken.None; - policy.Awaiting(p => p.ExecuteAsync(async ct => + await policy.Awaiting(p => p.ExecuteAsync(async ct => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), ct); return ResultPrimitive.WhateverButTooLate; }, userCancellationToken)) - .Should().Throw(); + .Should().ThrowAsync(); timeoutPassedToOnTimeout.Should().Be(timeoutPassedToConfiguration); } [Fact] - public void Should_call_ontimeout_with_passed_context__optimistic() + public async Task Should_call_ontimeout_with_passed_context__optimistic() { string operationKey = "SomeKey"; Context contextPassedToExecute = new Context(operationKey); @@ -648,12 +648,12 @@ public void Should_call_ontimeout_with_passed_context__optimistic() var policy = Policy.TimeoutAsync(timeout, TimeoutStrategy.Optimistic, onTimeoutAsync); var userCancellationToken = CancellationToken.None; - policy.Awaiting(p => p.ExecuteAsync(async (_, ct) => + await policy.Awaiting(p => p.ExecuteAsync(async (_, ct) => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), ct); return ResultPrimitive.WhateverButTooLate; }, contextPassedToExecute, userCancellationToken)) - .Should().Throw(); + .Should().ThrowAsync(); contextPassedToOnTimeout.Should().NotBeNull(); contextPassedToOnTimeout.OperationKey.Should().Be(operationKey); @@ -664,7 +664,7 @@ public void Should_call_ontimeout_with_passed_context__optimistic() [InlineData(1)] [InlineData(2)] [InlineData(3)] - public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execution_by_evaluating_func__optimistic(int programaticallyControlledDelay) + public async Task Should_call_ontimeout_with_timeout_supplied_different_for_each_execution_by_evaluating_func__optimistic(int programaticallyControlledDelay) { Func timeoutFunc = () => TimeSpan.FromMilliseconds(25*programaticallyControlledDelay); @@ -679,12 +679,12 @@ public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execu var policy = Policy.TimeoutAsync(timeoutFunc, TimeoutStrategy.Optimistic, onTimeoutAsync); var userCancellationToken = CancellationToken.None; - policy.Awaiting(p => p.ExecuteAsync(async ct => + await policy.Awaiting(p => p.ExecuteAsync(async ct => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), ct); return ResultPrimitive.WhateverButTooLate; }, userCancellationToken)) - .Should().Throw(); + .Should().ThrowAsync(); timeoutPassedToOnTimeout.Should().Be(timeoutFunc()); } @@ -693,7 +693,7 @@ public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execu [InlineData(1)] [InlineData(2)] [InlineData(3)] - public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execution_by_evaluating_func_influenced_by_context__optimistic(int programaticallyControlledDelay) + public async Task Should_call_ontimeout_with_timeout_supplied_different_for_each_execution_by_evaluating_func_influenced_by_context__optimistic(int programaticallyControlledDelay) { Func timeoutProvider = ctx => (TimeSpan)ctx["timeout"]; @@ -713,18 +713,18 @@ public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execu ["timeout"] = TimeSpan.FromMilliseconds(25 * programaticallyControlledDelay) }; - policy.Awaiting(p => p.ExecuteAsync(async (_, ct) => + await policy.Awaiting(p => p.ExecuteAsync(async (_, ct) => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), ct); return ResultPrimitive.WhateverButTooLate; }, context, userCancellationToken)) - .Should().Throw(); + .Should().ThrowAsync(); timeoutPassedToOnTimeout.Should().Be(timeoutProvider(context)); } [Fact] - public void Should_call_ontimeout_but_not_with_task_wrapping_abandoned_action__optimistic() + public async Task Should_call_ontimeout_but_not_with_task_wrapping_abandoned_action__optimistic() { Task taskPassedToOnTimeout = null; Func onTimeoutAsync = (_, _, task) => @@ -737,18 +737,18 @@ public void Should_call_ontimeout_but_not_with_task_wrapping_abandoned_action__o var policy = Policy.TimeoutAsync(timeout, TimeoutStrategy.Optimistic, onTimeoutAsync); var userCancellationToken = CancellationToken.None; - policy.Awaiting(p => p.ExecuteAsync(async ct => + await policy.Awaiting(p => p.ExecuteAsync(async ct => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), ct); return ResultPrimitive.WhateverButTooLate; }, userCancellationToken)) - .Should().Throw(); + .Should().ThrowAsync(); taskPassedToOnTimeout.Should().BeNull(); } [Fact] - public void Should_call_ontimeout_with_timing_out_exception__optimistic() + public async Task Should_call_ontimeout_with_timing_out_exception__optimistic() { TimeSpan timeoutPassedToConfiguration = TimeSpan.FromMilliseconds(250); @@ -762,12 +762,12 @@ public void Should_call_ontimeout_with_timing_out_exception__optimistic() var policy = Policy.TimeoutAsync(timeoutPassedToConfiguration, TimeoutStrategy.Optimistic, onTimeoutAsync); var userCancellationToken = CancellationToken.None; - policy.Awaiting(p => p.ExecuteAsync(async ct => + await policy.Awaiting(p => p.ExecuteAsync(async ct => { await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), ct); return ResultPrimitive.WhateverButTooLate; }, userCancellationToken)) - .Should().Throw(); + .Should().ThrowAsync(); exceptionPassedToOnTimeout.Should().NotBeNull(); exceptionPassedToOnTimeout.Should().BeOfType(typeof(OperationCanceledException)); diff --git a/src/Polly.Specs/Timeout/TimeoutTResultSpecs.cs b/src/Polly.Specs/Timeout/TimeoutTResultSpecs.cs index 1cbf43fe6ad..ec887ff92db 100644 --- a/src/Polly.Specs/Timeout/TimeoutTResultSpecs.cs +++ b/src/Polly.Specs/Timeout/TimeoutTResultSpecs.cs @@ -251,7 +251,7 @@ public void Should_throw_timeout_after_correct_duration__pessimistic() .Should().Throw(); watch.Stop(); - watch.Elapsed.Should().BeCloseTo(timeout, ((int)tolerance.TotalMilliseconds)); + watch.Elapsed.Should().BeCloseTo(timeout, TimeSpan.FromMilliseconds(tolerance.TotalMilliseconds)); } [Fact] @@ -402,7 +402,7 @@ public void Should_throw_timeout_after_correct_duration__optimistic() .Should().Throw(); watch.Stop(); - watch.Elapsed.Should().BeCloseTo(timeout, ((int)tolerance.TotalMilliseconds)); + watch.Elapsed.Should().BeCloseTo(timeout, TimeSpan.FromMilliseconds(tolerance.TotalMilliseconds)); } [Fact] diff --git a/src/Polly.Specs/Wrap/PolicyWrapSpecsAsync.cs b/src/Polly.Specs/Wrap/PolicyWrapSpecsAsync.cs index 5b0f9e85e91..dcd7d3f0493 100644 --- a/src/Polly.Specs/Wrap/PolicyWrapSpecsAsync.cs +++ b/src/Polly.Specs/Wrap/PolicyWrapSpecsAsync.cs @@ -360,7 +360,7 @@ public void Wrapping_policies_using_static_wrap_strongly_typed_syntax_should_set #region Instance-configured: execution tests [Fact] - public void Wrapping_two_policies_by_instance_syntax_and_executing_should_wrap_outer_then_inner_around_delegate() + public async Task Wrapping_two_policies_by_instance_syntax_and_executing_should_wrap_outer_then_inner_around_delegate() { var retry = Policy.Handle().RetryAsync(1); // Two tries in total: first try, plus one retry. var breaker = Policy.Handle().CircuitBreakerAsync(2, TimeSpan.MaxValue); @@ -370,14 +370,14 @@ public void Wrapping_two_policies_by_instance_syntax_and_executing_should_wrap_o // When the retry wraps the breaker, the retry (being outer) should cause the call to be put through the breaker twice - causing the breaker to break. breaker.Reset(); - retryWrappingBreaker.Awaiting(x => x.RaiseExceptionAsync(2)) - .Should().Throw(); + await retryWrappingBreaker.Awaiting(x => x.RaiseExceptionAsync(2)) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); // When the breaker wraps the retry, the retry (being inner) should retry twice before throwing the exception back on the breaker - the exception only hits the breaker once - so the breaker should not break. breaker.Reset(); - breakerWrappingRetry.Awaiting(x => x.RaiseExceptionAsync(2)) - .Should().Throw(); + await breakerWrappingRetry.Awaiting(x => x.RaiseExceptionAsync(2)) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); } @@ -408,7 +408,7 @@ public async Task Wrapping_two_generic_policies_by_instance_syntax_and_executing #region Static-configured: execution tests [Fact] - public void Wrapping_two_policies_by_static_syntax_and_executing_should_wrap_outer_then_inner_around_delegate() + public async Task Wrapping_two_policies_by_static_syntax_and_executing_should_wrap_outer_then_inner_around_delegate() { var retry = Policy.Handle().RetryAsync(1); // Two tries in total: first try, plus one retry. var breaker = Policy.Handle().CircuitBreakerAsync(2, TimeSpan.MaxValue); @@ -418,14 +418,14 @@ public void Wrapping_two_policies_by_static_syntax_and_executing_should_wrap_out // When the retry wraps the breaker, the retry (being outer) should cause the call to be put through the breaker twice - causing the breaker to break. breaker.Reset(); - retryWrappingBreaker.Awaiting(x => x.RaiseExceptionAsync(2)) - .Should().Throw(); + await retryWrappingBreaker.Awaiting(x => x.RaiseExceptionAsync(2)) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Open); // When the breaker wraps the retry, the retry (being inner) should retry twice before throwing the exception back on the breaker - the exception only hits the breaker once - so the breaker should not break. breaker.Reset(); - breakerWrappingRetry.Awaiting(x => x.RaiseExceptionAsync(2)) - .Should().Throw(); + await breakerWrappingRetry.Awaiting(x => x.RaiseExceptionAsync(2)) + .Should().ThrowAsync(); breaker.CircuitState.Should().Be(CircuitState.Closed); } diff --git a/src/Polly/Polly.csproj b/src/Polly/Polly.csproj index 12e76e76815..d1b5712018a 100644 --- a/src/Polly/Polly.csproj +++ b/src/Polly/Polly.csproj @@ -1,4 +1,4 @@ - + netstandard1.1;netstandard2.0;net461;net472