示例#1
0
        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);
        }
示例#3
0
        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();
        }
示例#4
0
        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);
        }
示例#5
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);
        }
示例#6
0
        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);
        }
示例#8
0
        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);
        }
示例#12
0
        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);
        }
示例#13
0
        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);
        }
示例#14
0
        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);
        }
示例#15
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);
        }
示例#16
0
        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();
        }
示例#17
0
        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();
        }
示例#18
0
        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.
        }
示例#19
0
        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);
        }
示例#20
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))
            .Should().Throw <DivideByZeroException>();

            attemptsInvoked.Should().Be(1 + 3);
        }
示例#21
0
        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);
        }
示例#22
0
        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);
        }
示例#23
0
        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);
        }
示例#24
0
        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);
        }
示例#25
0
        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);
        }
示例#26
0
        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);
        }
示例#28
0
        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();

        }
示例#29
0
        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.
        }
示例#30
0
        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);
        }
示例#31
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);
        }
示例#32
0
        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);
        }
示例#35
0
        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);
        }
示例#36
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);
        }
示例#37
0
        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);
        }
示例#38
0
        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);
        }
示例#39
0
        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();
        }
示例#40
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>()
                .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);
        }