public void Should_report_cancellation_during_otherwise_non_faulting_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationtoken() { var policy = Policy .Handle <DivideByZeroException>() .WaitAndRetryAsync(new[] { 1.Seconds(), 2.Seconds(), 3.Seconds() }); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 0, AttemptDuringWhichToCancel = 1, ActionObservesCancellation = true }; policy.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync <DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldThrow <TaskCanceledException>() .And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); }
public void Should_report_cancellation_during_faulting_retried_action_execution_and_cancel_further_retries_when_user_delegate_does_not_observe_cancellationtoken() { Func <int, TimeSpan> provider = i => TimeSpan.Zero; var policy = Policy .Handle <DivideByZeroException>() .WaitAndRetryForeverAsync(provider); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 1 + 3, AttemptDuringWhichToCancel = 2, ActionObservesCancellation = false }; policy.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync <DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldThrow <TaskCanceledException>() .And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(2); }
public void Should_execute_action_when_non_faulting_and_cancellationtoken_not_cancelled() { bool fallbackActionExecuted = false; Func <CancellationToken, Task> fallbackActionAsync = _ => { fallbackActionExecuted = true; return(TaskHelper.EmptyTask); }; var policy = Policy .Handle <DivideByZeroException>() .FallbackAsync(fallbackActionAsync); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 0, AttemptDuringWhichToCancel = null, }; policy.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync <DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldNotThrow(); attemptsInvoked.Should().Be(1); fallbackActionExecuted.Should().BeFalse(); }
public void Should_not_execute_action_when_cancellationToken_cancelled_before_execute() { var policy = Policy .Handle <DivideByZeroException>() .WaitAndRetryAsync(new[] { 1.Seconds(), 2.Seconds(), 3.Seconds() }); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 1 + 3, AttemptDuringWhichToCancel = null, // Cancellation token cancelled manually below - before any scenario execution. }; cancellationTokenSource.Cancel(); policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync <DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .Should().Throw <OperationCanceledException>() .And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(0); }
public void Should_report_cancellation_after_faulting_action_execution_and_cancel_further_retries_if_onRetry_invokes_cancellation() { CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; var policy = Policy .Handle <DivideByZeroException>() .WaitAndRetryAsync(new[] { 1.Seconds(), 2.Seconds(), 3.Seconds() }, (_, _) => { cancellationTokenSource.Cancel(); }); int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 1 + 3, AttemptDuringWhichToCancel = null, // Cancellation during onRetry instead - see above. ActionObservesCancellation = false }; policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync <DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .Should().Throw <OperationCanceledException>() .And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); }
public void Should_report_cancellation_during_faulting_last_retry_execution_when_user_delegate_does_observe_cancellationToken() { var policy = Policy .Handle <DivideByZeroException>() .WaitAndRetryAsync(new[] { 1.Seconds(), 2.Seconds(), 3.Seconds() }); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 1 + 3, AttemptDuringWhichToCancel = 1 + 3, ActionObservesCancellation = true }; policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync <DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .Should().Throw <OperationCanceledException>() .And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1 + 3); }
public void Should_execute_func_returning_value_when_cancellationToken_not_cancelled() { var policy = Policy .Handle <DivideByZeroException>() .WaitAndRetryAsync(new[] { 1.Seconds(), 2.Seconds(), 3.Seconds() }); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; bool?result = null; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 0, AttemptDuringWhichToCancel = null }; policy.Awaiting(async x => result = await x.RaiseExceptionAndOrCancellationAsync <DivideByZeroException, bool>(scenario, cancellationTokenSource, onExecute, true).ConfigureAwait(false)) .Should().NotThrow(); result.Should().BeTrue(); attemptsInvoked.Should().Be(1); }
public void Should_not_execute_action_when_cancellationtoken_cancelled_before_execute() { bool fallbackActionExecuted = false; Func <CancellationToken, Task> fallbackActionAsync = _ => { fallbackActionExecuted = true; return(TaskHelper.EmptyTask); }; FallbackPolicy policy = Policy .Handle <DivideByZeroException>() .FallbackAsync(fallbackActionAsync); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 1, AttemptDuringWhichToCancel = null, // Cancellation token cancelled manually below - before any scenario execution. }; cancellationTokenSource.Cancel(); policy.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync <DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldThrow <OperationCanceledException>() .And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(0); fallbackActionExecuted.Should().BeFalse(); }
public void Should_execute_func_returning_value_when_cancellationtoken_not_cancelled() { Func <int, TimeSpan> provider = i => TimeSpan.Zero; var policy = Policy .Handle <DivideByZeroException>() .WaitAndRetryForeverAsync(provider); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; bool?result = null; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 0, AttemptDuringWhichToCancel = null, }; policy.Awaiting(async x => result = await x.RaiseExceptionAndOrCancellationAsync <DivideByZeroException, bool>(scenario, cancellationTokenSource, onExecute, true).ConfigureAwait(false)) .ShouldNotThrow(); result.Should().BeTrue(); attemptsInvoked.Should().Be(1); }
public void Should_honour_and_report_cancellation_during_func_execution() { Func <int, TimeSpan> provider = i => TimeSpan.Zero; var policy = Policy .Handle <DivideByZeroException>() .WaitAndRetryForeverAsync(provider); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; bool?result = null; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 0, AttemptDuringWhichToCancel = 1, ActionObservesCancellation = true }; policy.Awaiting(async x => result = await x.RaiseExceptionAndOrCancellationAsync <DivideByZeroException, bool>(scenario, cancellationTokenSource, onExecute, true).ConfigureAwait(false)) .ShouldThrow <TaskCanceledException>().And.CancellationToken.Should().Be(cancellationToken); result.Should().Be(null); attemptsInvoked.Should().Be(1); }
public void Should_report_cancellation_after_faulting_action_execution_and_cancel_further_retries_if_onRetry_invokes_cancellation() { Func <int, TimeSpan> provider = i => TimeSpan.Zero; CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; var policy = Policy .Handle <DivideByZeroException>() .WaitAndRetryForeverAsync(provider, (_, __) => { cancellationTokenSource.Cancel(); }); int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 1 + 3, AttemptDuringWhichToCancel = null, // Cancellation during onRetry instead - see above. ActionObservesCancellation = false }; policy.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync <DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldThrow <TaskCanceledException>() .And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); }
public void Should_execute_func_returning_value_when_cancellationToken_not_cancelled() { var policy = Policy .Handle <DivideByZeroException>() .RetryForeverAsync(); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; bool?result = null; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 0, AttemptDuringWhichToCancel = null, }; Func <AsyncRetryPolicy, Task> action = async x => result = await x.RaiseExceptionAndOrCancellationAsync <DivideByZeroException, bool>(scenario, cancellationTokenSource, onExecute, true); policy.Awaiting(action) .Should().NotThrow(); result.Should().BeTrue(); attemptsInvoked.Should().Be(1); }
public void Should_honour_and_report_cancellation_during_func_execution() { var policy = Policy .Handle <DivideByZeroException>() .RetryForeverAsync(); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; bool?result = null; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 0, AttemptDuringWhichToCancel = 1, ActionObservesCancellation = true }; Func <AsyncRetryPolicy, Task> action = async x => result = await x.RaiseExceptionAndOrCancellationAsync <DivideByZeroException, bool>(scenario, cancellationTokenSource, onExecute, true); policy.Awaiting(action) .Should().Throw <OperationCanceledException>().And.CancellationToken.Should().Be(cancellationToken); result.Should().Be(null); attemptsInvoked.Should().Be(1); }
public void Should_not_execute_action_when_cancellationtoken_cancelled_before_execute() { Func <int, TimeSpan> provider = i => TimeSpan.Zero; var policy = Policy .Handle <DivideByZeroException>() .WaitAndRetryForeverAsync(provider); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 1 + 3, AttemptDuringWhichToCancel = null, // Cancellation token cancelled manually below - before any scenario execution. }; cancellationTokenSource.Cancel(); policy.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync <DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldThrow <TaskCanceledException>() .And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(0); }
public void Should_report_cancellation_during_faulting_retried_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationToken() { var policy = Policy .Handle <DivideByZeroException>() .RetryForeverAsync(); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 1 + 3, AttemptDuringWhichToCancel = 2, ActionObservesCancellation = true }; policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync <DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .Should().Throw <OperationCanceledException>() .And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(2); }
public void Should_handle_handled_fault_and_execute_fallback_following_faulting_action_execution_when_user_delegate_does_not_observe_cancellationtoken() { bool fallbackActionExecuted = false; Func <CancellationToken, Task> fallbackActionAsync = _ => { fallbackActionExecuted = true; return(TaskHelper.EmptyTask); }; CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; FallbackPolicy policy = Policy .Handle <DivideByZeroException>() .FallbackAsync(fallbackActionAsync); int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 1, AttemptDuringWhichToCancel = 1, ActionObservesCancellation = false }; policy.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync <DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldNotThrow(); attemptsInvoked.Should().Be(1); fallbackActionExecuted.Should().BeTrue(); }
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() { bool fallbackActionExecuted = false; Func <CancellationToken, Task> fallbackActionAsync = _ => { fallbackActionExecuted = true; return(TaskHelper.EmptyTask); }; var policy = Policy .Handle <DivideByZeroException>() .FallbackAsync(fallbackActionAsync); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 0, AttemptDuringWhichToCancel = 1, ActionObservesCancellation = true }; policy.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync <DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldThrow <OperationCanceledException>() .And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); fallbackActionExecuted.Should().BeFalse(); }
public void Should_honour_cancellation_immediately_during_wait_phase_of_waitandretry() { CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; SystemClock.SleepAsync = Task.Delay; TimeSpan shimTimeSpan = TimeSpan.FromSeconds(1); // Consider increasing shimTimeSpan if test fails transiently in different environments. TimeSpan retryDelay = shimTimeSpan + shimTimeSpan + shimTimeSpan; var policy = Policy .Handle <DivideByZeroException>() .WaitAndRetryAsync(new[] { retryDelay }); int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Stopwatch watch = new Stopwatch(); watch.Start(); Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 1 + 1, AttemptDuringWhichToCancel = null, // Cancellation invoked after delay - see below. ActionObservesCancellation = false }; cancellationTokenSource.CancelAfter(shimTimeSpan); policy.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync <DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldThrow <TaskCanceledException>() .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. }
public void Should_execute_action_when_non_faulting_and_cancellationtoken_not_cancelled() { var policy = Policy .Handle <DivideByZeroException>() .WaitAndRetryAsync(new[] { 1.Seconds(), 2.Seconds(), 3.Seconds() }); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 0, AttemptDuringWhichToCancel = null, }; policy.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync <DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldNotThrow(); attemptsInvoked.Should().Be(1); }
public void Should_execute_all_tries_when_faulting_and_cancellationToken_not_cancelled() { var policy = Policy .Handle <DivideByZeroException>() .RetryAsync(3); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 1 + 3, AttemptDuringWhichToCancel = null, }; policy.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync <DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .Should().Throw <DivideByZeroException>(); attemptsInvoked.Should().Be(1 + 3); }
public void Should_report_faulting_from_faulting_last_retry_execution_when_user_delegate_does_not_observe_cancellation_raised_during_last_retry() { var policy = Policy .Handle <DivideByZeroException>() .RetryAsync(3); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 1 + 3, AttemptDuringWhichToCancel = 1 + 3, ActionObservesCancellation = false }; policy.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync <DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .Should().Throw <DivideByZeroException>(); attemptsInvoked.Should().Be(1 + 3); }
public void Should_execute_action_when_non_faulting_and_cancellationtoken_not_cancelled() { Func <int, TimeSpan> provider = i => TimeSpan.Zero; var policy = Policy .Handle <DivideByZeroException>() .WaitAndRetryForeverAsync(provider); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 0, AttemptDuringWhichToCancel = null, }; policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync <DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldNotThrow(); attemptsInvoked.Should().Be(1); }
public void Should_execute_action_when_non_faulting_and_cancellationtoken_not_cancelled() { var durationOfBreak = TimeSpan.FromMinutes(1); CircuitBreakerPolicy breaker = Policy .Handle<DivideByZeroException>() .CircuitBreakerAsync(2, durationOfBreak); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 0, AttemptDuringWhichToCancel = null, }; breaker.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync<DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldNotThrow(); attemptsInvoked.Should().Be(1); }
public void Should_honour_and_report_cancellation_during_func_execution() { CircuitBreakerPolicy breaker = Policy .Handle<DivideByZeroException>() .CircuitBreakerAsync(2, TimeSpan.FromMinutes(1)); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; bool? result = null; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 0, AttemptDuringWhichToCancel = 1, ActionObservesCancellation = true }; breaker.Awaiting(async x => result = await x.RaiseExceptionAndOrCancellationAsync<DivideByZeroException, bool>(scenario, cancellationTokenSource, onExecute, true).ConfigureAwait(false)) .ShouldThrow<TaskCanceledException>().And.CancellationToken.Should().Be(cancellationToken); result.Should().Be(null); attemptsInvoked.Should().Be(1); }
public void Should_execute_func_returning_value_when_cancellationtoken_not_cancelled() { var durationOfBreak = TimeSpan.FromMinutes(1); CircuitBreakerPolicy breaker = Policy .Handle<DivideByZeroException>() .CircuitBreakerAsync(2, durationOfBreak); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; bool? result = null; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 0, AttemptDuringWhichToCancel = null, }; breaker.Awaiting(async x => result = await x.RaiseExceptionAndOrCancellationAsync<DivideByZeroException, bool>(scenario, cancellationTokenSource, onExecute, true).ConfigureAwait(false)) .ShouldNotThrow(); result.Should().BeTrue(); attemptsInvoked.Should().Be(1); }
public void Should_report_cancellation_when_both_open_circuit_and_cancellation() { CircuitBreakerPolicy breaker = Policy .Handle<DivideByZeroException>() .CircuitBreakerAsync(1, TimeSpan.FromMinutes(1)); breaker.Awaiting(async x => await x.RaiseExceptionAsync<DivideByZeroException>()) .ShouldThrow<DivideByZeroException>(); breaker.Awaiting(async x => await x.RaiseExceptionAsync<DivideByZeroException>()) .ShouldThrow<BrokenCircuitException>() .WithMessage("The circuit is now open and is not allowing calls.") .WithInnerException<DivideByZeroException>(); // Circuit is now broken. CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; cancellationTokenSource.Cancel(); Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 1, AttemptDuringWhichToCancel = null, // Cancelled manually instead - see above. ActionObservesCancellation = false }; breaker.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync<DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldThrow<TaskCanceledException>() .And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(0); }
public void Should_report_cancellation_during_faulting_last_retry_execution_when_user_delegate_does_not_observe_cancellationtoken() { var policy = Policy .Handle<DivideByZeroException>() .WaitAndRetryAsync(new[] { 1.Seconds(), 2.Seconds(), 3.Seconds() }); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 1 + 3, AttemptDuringWhichToCancel = 1 + 3, ActionObservesCancellation = false }; policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync<DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldThrow<TaskCanceledException>() .And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1 + 3); }
public void Should_not_execute_action_when_cancellationtoken_cancelled_before_execute() { bool fallbackActionExecuted = false; Func<CancellationToken, Task> fallbackActionAsync = _ => { fallbackActionExecuted = true; return TaskHelper.EmptyTask; }; FallbackPolicy policy = Policy .Handle<DivideByZeroException>() .FallbackAsync(fallbackActionAsync); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 1, AttemptDuringWhichToCancel = null, // Cancellation token cancelled manually below - before any scenario execution. }; cancellationTokenSource.Cancel(); policy.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync<DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldThrow<OperationCanceledException>() .And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(0); fallbackActionExecuted.Should().BeFalse(); }
public void Should_honour_cancellation_immediately_during_wait_phase_of_waitandretry() { CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; SystemClock.SleepAsync = Task.Delay; TimeSpan shimTimeSpan = TimeSpan.FromSeconds(1); // Consider increasing shimTimeSpan if test fails transiently in different environments. TimeSpan retryDelay = shimTimeSpan + shimTimeSpan + shimTimeSpan; var policy = Policy .Handle<DivideByZeroException>() .WaitAndRetryAsync(new[] { retryDelay }); int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Stopwatch watch = new Stopwatch(); watch.Start(); Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 1 + 1, AttemptDuringWhichToCancel = null, // Cancellation invoked after delay - see below. ActionObservesCancellation = false }; cancellationTokenSource.CancelAfter(shimTimeSpan); policy.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync<DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldThrow<TaskCanceledException>() .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. }
public void Should_not_execute_action_when_cancellationtoken_cancelled_before_execute() { var policy = Policy .Handle<DivideByZeroException>() .RetryAsync(3); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 1 + 3, AttemptDuringWhichToCancel = null, // Cancellation token cancelled manually below - before any scenario execution. }; cancellationTokenSource.Cancel(); policy.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync<DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldThrow<TaskCanceledException>() .And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(0); }
public void Should_execute_all_tries_when_faulting_and_cancellationtoken_not_cancelled() { var policy = Policy .Handle<DivideByZeroException>() .RetryAsync(3); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 1 + 3, AttemptDuringWhichToCancel = null, }; policy.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync<DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldThrow<DivideByZeroException>(); attemptsInvoked.Should().Be(1 + 3); }
public void Should_honour_and_report_cancellation_during_func_execution() { var policy = Policy .Handle<DivideByZeroException>() .WaitAndRetryAsync(new[] { 1.Seconds(), 2.Seconds(), 3.Seconds() }); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; bool? result = null; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 0, AttemptDuringWhichToCancel = 1, ActionObservesCancellation = true }; policy.Awaiting(async x => result = await x.RaiseExceptionAndOrCancellationAsync<DivideByZeroException, bool>(scenario, cancellationTokenSource, onExecute, true).ConfigureAwait(false)) .ShouldThrow<TaskCanceledException>().And.CancellationToken.Should().Be(cancellationToken); result.Should().Be(null); attemptsInvoked.Should().Be(1); }
public void Should_execute_action_when_non_faulting_and_cancellationtoken_not_cancelled() { Func<int, TimeSpan> provider = i => TimeSpan.Zero; var policy = Policy .Handle<DivideByZeroException>() .WaitAndRetryForeverAsync(provider); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 0, AttemptDuringWhichToCancel = null, }; policy.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync<DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldNotThrow(); attemptsInvoked.Should().Be(1); }
public void Should_report_cancellation_during_faulting_initial_action_execution_and_cancel_further_retries_when_user_delegate_does_not_observe_cancellationtoken() { Func<int, TimeSpan> provider = i => TimeSpan.Zero; var policy = Policy .Handle<DivideByZeroException>() .WaitAndRetryForeverAsync(provider); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 1 + 3, AttemptDuringWhichToCancel = 1, ActionObservesCancellation = false }; policy.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync<DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldThrow<TaskCanceledException>() .And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); }
public void Should_not_execute_action_when_cancellationtoken_cancelled_before_execute() { var durationOfBreak = TimeSpan.FromMinutes(1); CircuitBreakerPolicy breaker = Policy .Handle<DivideByZeroException>() .CircuitBreakerAsync(2, durationOfBreak); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 0, AttemptDuringWhichToCancel = null, // Cancellation token cancelled manually below - before any scenario execution. }; cancellationTokenSource.Cancel(); breaker.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync<DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldThrow<TaskCanceledException>() .And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(0); }
public void Should_report_cancellation_during_faulting_retried_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationtoken() { var policy = Policy .Handle<DivideByZeroException>() .RetryAsync(3); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 1 + 3, AttemptDuringWhichToCancel = 2, ActionObservesCancellation = true }; policy.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync<DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldThrow<TaskCanceledException>() .And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(2); }
public void Should_report_cancellation_during_faulting_action_execution_when_user_delegate_observes_cancellationtoken() { var durationOfBreak = TimeSpan.FromMinutes(1); CircuitBreakerPolicy breaker = Policy .Handle<DivideByZeroException>() .CircuitBreakerAsync(2, durationOfBreak); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 1, AttemptDuringWhichToCancel = 1, ActionObservesCancellation = true }; breaker.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync<DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldThrow<TaskCanceledException>() .And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); }
public void Should_report_faulting_from_faulting_last_retry_execution_when_user_delegate_does_not_observe_cancellation_raised_during_last_retry() { var policy = Policy .Handle<DivideByZeroException>() .RetryAsync(3); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 1 + 3, AttemptDuringWhichToCancel = 1 + 3, ActionObservesCancellation = false }; policy.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync<DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldThrow<DivideByZeroException>(); attemptsInvoked.Should().Be(1 + 3); }
public void Should_handle_handled_fault_and_execute_fallback_following_faulting_action_execution_when_user_delegate_does_not_observe_cancellationtoken() { bool fallbackActionExecuted = false; Func<CancellationToken, Task> fallbackActionAsync = _ => { fallbackActionExecuted = true; return TaskHelper.EmptyTask; }; CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; FallbackPolicy policy = Policy .Handle<DivideByZeroException>() .FallbackAsync(fallbackActionAsync); int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 1, AttemptDuringWhichToCancel = 1, ActionObservesCancellation = false }; policy.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync<DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldNotThrow(); attemptsInvoked.Should().Be(1); fallbackActionExecuted.Should().BeTrue(); }
public void Should_report_cancellation_after_faulting_action_execution_and_cancel_further_retries_if_onRetry_invokes_cancellation() { CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; var policy = Policy .Handle<DivideByZeroException>() .RetryAsync(3, (_, __) => { cancellationTokenSource.Cancel(); }); int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 1 + 3, AttemptDuringWhichToCancel = null, // Cancellation during onRetry instead - see above. ActionObservesCancellation = false }; policy.Awaiting(async x => await x.RaiseExceptionAndOrCancellationAsync<DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldThrow<TaskCanceledException>() .And.CancellationToken.Should().Be(cancellationToken); attemptsInvoked.Should().Be(1); }
public void Should_execute_action_when_non_faulting_and_cancellationtoken_not_cancelled() { var policy = Policy .Handle<DivideByZeroException>() .WaitAndRetryAsync(new[] { 1.Seconds(), 2.Seconds(), 3.Seconds() }); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 0, AttemptDuringWhichToCancel = null, }; policy.Awaiting(x => x.RaiseExceptionAndOrCancellationAsync<DivideByZeroException>(scenario, cancellationTokenSource, onExecute)) .ShouldNotThrow(); attemptsInvoked.Should().Be(1); }
public void Should_execute_func_returning_value_when_cancellationtoken_not_cancelled() { Func<int, TimeSpan> provider = i => TimeSpan.Zero; var policy = Policy .Handle<DivideByZeroException>() .WaitAndRetryForeverAsync(provider); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); int attemptsInvoked = 0; Action onExecute = () => attemptsInvoked++; bool? result = null; Scenario scenario = new Scenario { NumberOfTimesToRaiseException = 0, AttemptDuringWhichToCancel = null, }; policy.Awaiting(async x => result = await x.RaiseExceptionAndOrCancellationAsync<DivideByZeroException, bool>(scenario, cancellationTokenSource, onExecute, true).ConfigureAwait(false)) .ShouldNotThrow(); result.Should().BeTrue(); attemptsInvoked.Should().Be(1); }