public async Task Should_handle_handled_fault_and_execute_fallback_following_faulting_action_execution_when_user_delegate_does_not_observe_cancellationtoken()
        {
            bool fallbackActionExecuted = false;
            Func <CancellationToken, Task <ResultPrimitive> > fallbackAction = ct => { fallbackActionExecuted = true; return(Task.FromResult(ResultPrimitive.Substitute)); };

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken       cancellationToken       = cancellationTokenSource.Token;

            FallbackPolicy <ResultPrimitive> policy = Policy
                                                      .HandleResult(ResultPrimitive.Fault)
                                                      .OrResult(ResultPrimitive.FaultAgain)
                                                      .FallbackAsync(fallbackAction);

            int    attemptsInvoked = 0;
            Action onExecute       = () => attemptsInvoked++;

            Scenario scenario = new Scenario
            {
                AttemptDuringWhichToCancel = 1,
                ActionObservesCancellation = false
            };

            (await policy.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, ResultPrimitive.Fault).ConfigureAwait(false))
            .Should().Be(ResultPrimitive.Substitute);
            attemptsInvoked.Should().Be(1);

            fallbackActionExecuted.Should().BeTrue();
        }
示例#2
0
        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;
            Func <CancellationToken, Task <ResultPrimitive> > fallbackAction = _ => { fallbackActionExecuted = true; return(Task.FromResult(ResultPrimitive.Substitute)); };

            var policy = Policy
                         .HandleResult(ResultPrimitive.Fault)
                         .OrResult(ResultPrimitive.FaultAgain)
                         .FallbackAsync(fallbackAction);

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken       cancellationToken       = cancellationTokenSource.Token;

            int    attemptsInvoked = 0;
            Action onExecute       = () => attemptsInvoked++;

            Scenario scenario = new Scenario
            {
                AttemptDuringWhichToCancel = 1,
                ActionObservesCancellation = false
            };

            (await policy.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, ResultPrimitive.FaultYetAgain))
            .Should().Be(ResultPrimitive.FaultYetAgain);
            attemptsInvoked.Should().Be(1);

            fallbackActionExecuted.Should().BeFalse();
        }
示例#3
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;

            RetryPolicy <ResultPrimitive> policy = Policy
                                                   .HandleResult(ResultPrimitive.Fault)
                                                   .RetryAsync(3, (_, __) =>
            {
                cancellationTokenSource.Cancel();
            });

            int    attemptsInvoked = 0;
            Action onExecute       = () => attemptsInvoked++;

            Scenario scenario = new Scenario
            {
                AttemptDuringWhichToCancel = null, // Cancellation during onRetry instead - see above.
                ActionObservesCancellation = false
            };

            policy.Awaiting(async x => await x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute,
                                                                                         ResultPrimitive.Fault,
                                                                                         ResultPrimitive.Fault,
                                                                                         ResultPrimitive.Fault,
                                                                                         ResultPrimitive.Good))
            .ShouldThrow <TaskCanceledException>()
            .And.CancellationToken.Should().Be(cancellationToken);

            attemptsInvoked.Should().Be(1);
        }
        public void Should_not_execute_action_when_cancellationtoken_cancelled_before_execute()
        {
            bool fallbackActionExecuted = false;
            Func <CancellationToken, Task <ResultPrimitive> > fallbackAction = ct => { fallbackActionExecuted = true; return(Task.FromResult(ResultPrimitive.Substitute)); };

            FallbackPolicy <ResultPrimitive> policy = Policy
                                                      .HandleResult(ResultPrimitive.Fault)
                                                      .OrResult(ResultPrimitive.FaultAgain)
                                                      .FallbackAsync(fallbackAction);

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken       cancellationToken       = cancellationTokenSource.Token;

            int    attemptsInvoked = 0;
            Action onExecute       = () => attemptsInvoked++;

            Scenario scenario = new Scenario
            {
                AttemptDuringWhichToCancel = null, // Cancellation token cancelled manually below - before any scenario execution.
            };

            cancellationTokenSource.Cancel();

            policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, ResultPrimitive.Fault))
            .ShouldThrow <OperationCanceledException>()
            .And.CancellationToken.Should().Be(cancellationToken);
            attemptsInvoked.Should().Be(0);

            fallbackActionExecuted.Should().BeFalse();
        }
示例#5
0
        public void Should_report_cancellation_during_faulting_last_retry_execution_when_user_delegate_does_observe_cancellationtoken()
        {
            RetryPolicy <ResultPrimitive> policy = Policy
                                                   .HandleResult(ResultPrimitive.Fault)
                                                   .RetryAsync(3);

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken       cancellationToken       = cancellationTokenSource.Token;

            int    attemptsInvoked = 0;
            Action onExecute       = () => attemptsInvoked++;

            Scenario scenario = new Scenario
            {
                AttemptDuringWhichToCancel = 1 + 3,
                ActionObservesCancellation = true
            };

            policy.Awaiting(async x => await x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute,
                                                                                         ResultPrimitive.Fault,
                                                                                         ResultPrimitive.Fault,
                                                                                         ResultPrimitive.Fault,
                                                                                         ResultPrimitive.Fault,
                                                                                         ResultPrimitive.Good))
            .ShouldThrow <TaskCanceledException>()
            .And.CancellationToken.Should().Be(cancellationToken);

            attemptsInvoked.Should().Be(1 + 3);
        }
示例#6
0
        public async void Should_execute_all_tries_when_faulting_and_cancellationtoken_not_cancelled()
        {
            RetryPolicy <ResultPrimitive> policy = Policy
                                                   .HandleResult(ResultPrimitive.Fault)
                                                   .RetryAsync(3);

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken       cancellationToken       = cancellationTokenSource.Token;

            int    attemptsInvoked = 0;
            Action onExecute       = () => attemptsInvoked++;

            Scenario scenario = new Scenario
            {
                AttemptDuringWhichToCancel = null,
            };

            (await policy.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute,
                                                                    ResultPrimitive.Fault,
                                                                    ResultPrimitive.Fault,
                                                                    ResultPrimitive.Fault,
                                                                    ResultPrimitive.Good).ConfigureAwait(false))
            .Should().Be(ResultPrimitive.Good);

            attemptsInvoked.Should().Be(1 + 3);
        }
示例#7
0
        public void Should_not_execute_action_when_cancellationtoken_cancelled_before_execute()
        {
            RetryPolicy <ResultPrimitive> policy = Policy
                                                   .HandleResult(ResultPrimitive.Fault)
                                                   .RetryAsync(3);

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken       cancellationToken       = cancellationTokenSource.Token;

            int    attemptsInvoked = 0;
            Action onExecute       = () => attemptsInvoked++;

            Scenario scenario = new Scenario
            {
                AttemptDuringWhichToCancel = null, // Cancellation token cancelled manually below - before any scenario execution.
            };

            cancellationTokenSource.Cancel();

            policy.Awaiting(async x => await x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute,
                                                                                         ResultPrimitive.Fault,
                                                                                         ResultPrimitive.Fault,
                                                                                         ResultPrimitive.Fault,
                                                                                         ResultPrimitive.Good))
            .ShouldThrow <TaskCanceledException>()
            .And.CancellationToken.Should().Be(cancellationToken);

            attemptsInvoked.Should().Be(0);
        }
示例#8
0
        public void 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)
                         .RetryAsync(3);

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken       cancellationToken       = cancellationTokenSource.Token;

            int    attemptsInvoked = 0;
            Action onExecute       = () => attemptsInvoked++;

            Scenario scenario = new Scenario
            {
                AttemptDuringWhichToCancel = 2,
                ActionObservesCancellation = false
            };

            policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute,
                                                                             ResultPrimitive.Fault,
                                                                             ResultPrimitive.Fault,
                                                                             ResultPrimitive.Fault,
                                                                             ResultPrimitive.Good))
            .Should().Throw <OperationCanceledException>()
            .And.CancellationToken.Should().Be(cancellationToken);

            attemptsInvoked.Should().Be(2);
        }
        public async Task Should_execute_action_when_non_faulting_and_cancellationtoken_not_cancelled()
        {
            bool fallbackActionExecuted = false;
            Func <CancellationToken, Task <ResultPrimitive> > fallbackAction = ct => { fallbackActionExecuted = true; return(Task.FromResult(ResultPrimitive.Substitute)); };

            FallbackPolicy <ResultPrimitive> policy = Policy
                                                      .HandleResult(ResultPrimitive.Fault)
                                                      .OrResult(ResultPrimitive.FaultAgain)
                                                      .FallbackAsync(fallbackAction);

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken       cancellationToken       = cancellationTokenSource.Token;

            int    attemptsInvoked = 0;
            Action onExecute       = () => attemptsInvoked++;

            Scenario scenario = new Scenario
            {
                AttemptDuringWhichToCancel = null,
            };

            (await policy.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, ResultPrimitive.Good).ConfigureAwait(false))
            .Should().Be(ResultPrimitive.Good);
            attemptsInvoked.Should().Be(1);

            fallbackActionExecuted.Should().BeFalse();
        }
        public static async Task <TResult> RaiseResultSequenceAndOrCancellationAsync <TResult>(
            this AsyncPolicy <TResult> policy, Scenario scenario, CancellationTokenSource cancellationTokenSource,
            Action onExecute, IEnumerable <TResult> resultsToRaise)
        {
            int counter = 0;

            CancellationToken cancellationToken = cancellationTokenSource.Token;

            using (var enumerator = resultsToRaise.GetEnumerator())
            {
                return(await policy.ExecuteAsync(ct =>
                {
                    onExecute();

                    counter++;

                    if (!enumerator.MoveNext())
                    {
                        throw new ArgumentOutOfRangeException(nameof(resultsToRaise), $"Not enough {typeof(TResult).Name}  values in {nameof(resultsToRaise)}.");
                    }

                    if (scenario.AttemptDuringWhichToCancel.HasValue && counter >= scenario.AttemptDuringWhichToCancel.Value)
                    {
                        cancellationTokenSource.Cancel();
                    }

                    if (scenario.ActionObservesCancellation)
                    {
                        ct.ThrowIfCancellationRequested();
                    }

                    return Task.FromResult(enumerator.Current);
                }, cancellationToken));
            }
        }
示例#11
0
        public async void Should_report_faulting_from_faulting_last_retry_execution_when_user_delegate_does_not_observe_cancellation_raised_during_last_retry()
        {
            RetryPolicy <ResultPrimitive> policy = Policy
                                                   .HandleResult(ResultPrimitive.Fault)
                                                   .RetryAsync(3);

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken       cancellationToken       = cancellationTokenSource.Token;

            int    attemptsInvoked = 0;
            Action onExecute       = () => attemptsInvoked++;

            Scenario scenario = new Scenario
            {
                AttemptDuringWhichToCancel = 1 + 3,
                ActionObservesCancellation = false
            };

            (await policy.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute,
                                                                    ResultPrimitive.Fault,
                                                                    ResultPrimitive.Fault,
                                                                    ResultPrimitive.Fault,
                                                                    ResultPrimitive.Fault,
                                                                    ResultPrimitive.Good).ConfigureAwait(false))
            .Should().Be(ResultPrimitive.Fault);

            attemptsInvoked.Should().Be(1 + 3);
        }
示例#12
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 <ResultPrimitive> > fallbackAction = ct => { fallbackActionExecuted = true; return(Task.FromResult(ResultPrimitive.Substitute)); };

            FallbackPolicy <ResultPrimitive> policy = Policy
                                                      .HandleResult(ResultPrimitive.Fault)
                                                      .OrResult(ResultPrimitive.FaultAgain)
                                                      .FallbackAsync(fallbackAction);

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken       cancellationToken       = cancellationTokenSource.Token;

            int    attemptsInvoked = 0;
            Action onExecute       = () => attemptsInvoked++;

            Scenario scenario = new Scenario
            {
                AttemptDuringWhichToCancel = 1,
                ActionObservesCancellation = true
            };

            policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, ResultPrimitive.Good))
            .ShouldThrow <OperationCanceledException>()
            .And.CancellationToken.Should().Be(cancellationToken);
            attemptsInvoked.Should().Be(1);

            fallbackActionExecuted.Should().BeFalse();
        }
示例#13
0
 public static Task <TResult> RaiseResultSequenceAndOrCancellationAsync <TResult>(this Policy <TResult> policy,
                                                                                  Scenario scenario, CancellationTokenSource cancellationTokenSource, Action onExecute,
                                                                                  params TResult[] resultsToRaise)
 {
     return(policy.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute,
                                                             resultsToRaise.ToList()));
 }
        public async void Should_execute_action_when_non_faulting_and_cancellationtoken_not_cancelled()
        {
            var durationOfBreak = TimeSpan.FromMinutes(1);
            CircuitBreakerPolicy<ResultPrimitive> breaker = Policy
                .HandleResult(ResultPrimitive.Fault)
                            .CircuitBreakerAsync(2, durationOfBreak);

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken cancellationToken = cancellationTokenSource.Token;

            int attemptsInvoked = 0;
            Action onExecute = () => attemptsInvoked++;

            Scenario scenario = new Scenario
            {
                AttemptDuringWhichToCancel = null,
            };

            (await breaker.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, 
                ResultPrimitive.Good).ConfigureAwait(false))
                .Should().Be(ResultPrimitive.Good);

            attemptsInvoked.Should().Be(1);
        }
        public void Should_not_execute_action_when_cancellationtoken_cancelled_before_execute()
        {
            bool fallbackActionExecuted = false;
            Func<CancellationToken, Task<ResultPrimitive>> fallbackAction = ct => { fallbackActionExecuted = true; return Task.FromResult(ResultPrimitive.Substitute); };

            FallbackPolicy<ResultPrimitive> policy = Policy
                .HandleResult(ResultPrimitive.Fault)
                .OrResult(ResultPrimitive.FaultAgain)
                .FallbackAsync(fallbackAction);

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken cancellationToken = cancellationTokenSource.Token;

            int attemptsInvoked = 0;
            Action onExecute = () => attemptsInvoked++;

            Scenario scenario = new Scenario
            {
                AttemptDuringWhichToCancel = null, // Cancellation token cancelled manually below - before any scenario execution.
            };

            cancellationTokenSource.Cancel();

            policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, ResultPrimitive.Fault))
                .ShouldThrow<OperationCanceledException>()
                .And.CancellationToken.Should().Be(cancellationToken);
            attemptsInvoked.Should().Be(0);

            fallbackActionExecuted.Should().BeFalse();

        }
        public async 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<ResultPrimitive>> fallbackAction = ct => { fallbackActionExecuted = true; return Task.FromResult(ResultPrimitive.Substitute); };

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken cancellationToken = cancellationTokenSource.Token;

            FallbackPolicy<ResultPrimitive> policy = Policy
                .HandleResult(ResultPrimitive.Fault)
                .OrResult(ResultPrimitive.FaultAgain)
                .FallbackAsync(fallbackAction);

            int attemptsInvoked = 0;
            Action onExecute = () => attemptsInvoked++;

            Scenario scenario = new Scenario
            {
                AttemptDuringWhichToCancel = 1,
                ActionObservesCancellation = false
            };

            (await policy.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, ResultPrimitive.Fault).ConfigureAwait(false))
                .Should().Be(ResultPrimitive.Substitute);
            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;

            RetryPolicy<ResultPrimitive> policy = Policy
           .HandleResult(ResultPrimitive.Fault)
           .RetryAsync(3, (_, __) =>
           {
               cancellationTokenSource.Cancel();
           });

            int attemptsInvoked = 0;
            Action onExecute = () => attemptsInvoked++;

            Scenario scenario = new Scenario
            {
                AttemptDuringWhichToCancel = null, // Cancellation during onRetry instead - see above.
                ActionObservesCancellation = false
            };

            policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute,
                   ResultPrimitive.Fault,
                   ResultPrimitive.Fault,
                   ResultPrimitive.Fault,
                   ResultPrimitive.Good))
                .ShouldThrow<TaskCanceledException>()
                .And.CancellationToken.Should().Be(cancellationToken);

            attemptsInvoked.Should().Be(1);
        }
        public void Should_report_cancellation_during_faulting_last_retry_execution_when_user_delegate_does_not_observe_cancellationtoken()
        {
            RetryPolicy<ResultPrimitive> policy = Policy
                       .HandleResult(ResultPrimitive.Fault)
                       .RetryAsync(3);

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken cancellationToken = cancellationTokenSource.Token;

            int attemptsInvoked = 0;
            Action onExecute = () => attemptsInvoked++;

            Scenario scenario = new Scenario
            {
                AttemptDuringWhichToCancel = 1 + 3,
                ActionObservesCancellation = false
            };

            policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute,
                   ResultPrimitive.Fault,
                   ResultPrimitive.Fault,
                   ResultPrimitive.Fault,
                   ResultPrimitive.Good))
                .ShouldThrow<TaskCanceledException>()
                .And.CancellationToken.Should().Be(cancellationToken);

            attemptsInvoked.Should().Be(1 + 3);
        }
        public void Should_not_execute_action_when_cancellationtoken_cancelled_before_execute()
        {
            RetryPolicy<ResultPrimitive> policy = Policy
                .HandleResult(ResultPrimitive.Fault)
                .RetryAsync(3);

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken cancellationToken = cancellationTokenSource.Token;

            int attemptsInvoked = 0;
            Action onExecute = () => attemptsInvoked++;

            Scenario scenario = new Scenario
            {
                AttemptDuringWhichToCancel = null, // Cancellation token cancelled manually below - before any scenario execution.
            };

            cancellationTokenSource.Cancel();

            policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute,
                   ResultPrimitive.Fault,
                   ResultPrimitive.Fault,
                   ResultPrimitive.Fault,
                   ResultPrimitive.Good))
                .ShouldThrow<TaskCanceledException>()
                .And.CancellationToken.Should().Be(cancellationToken);

            attemptsInvoked.Should().Be(0);
        }
        public async void Should_execute_all_tries_when_faulting_and_cancellationtoken_not_cancelled()
        {
            RetryPolicy<ResultPrimitive> policy = Policy
                .HandleResult(ResultPrimitive.Fault)
                .RetryAsync(3);

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken cancellationToken = cancellationTokenSource.Token;

            int attemptsInvoked = 0;
            Action onExecute = () => attemptsInvoked++;

            Scenario scenario = new Scenario
            {
                AttemptDuringWhichToCancel = null,
            };

            (await policy.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute,
                    ResultPrimitive.Fault,
                    ResultPrimitive.Fault,
                    ResultPrimitive.Fault,
                    ResultPrimitive.Good).ConfigureAwait(false))
                    .Should().Be(ResultPrimitive.Good);

            attemptsInvoked.Should().Be(1 + 3);
        }
        public void Should_not_execute_action_when_cancellationtoken_cancelled_before_execute()
        {
            var durationOfBreak = TimeSpan.FromMinutes(1);
            CircuitBreakerPolicy<ResultPrimitive> breaker = Policy
                .HandleResult(ResultPrimitive.Fault)
                .CircuitBreakerAsync(2, durationOfBreak);

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken cancellationToken = cancellationTokenSource.Token;

            int attemptsInvoked = 0;
            Action onExecute = () => attemptsInvoked++;

            Scenario scenario = new Scenario
            {
                AttemptDuringWhichToCancel = null, // Cancellation token cancelled manually below - before any scenario execution.
            };

            cancellationTokenSource.Cancel();

            breaker.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute,
               ResultPrimitive.Fault,
               ResultPrimitive.Fault,
               ResultPrimitive.Good))
            .ShouldThrow<TaskCanceledException>()
            .And.CancellationToken.Should().Be(cancellationToken);

            attemptsInvoked.Should().Be(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<ResultPrimitive>> fallbackAction = ct => { fallbackActionExecuted = true; return Task.FromResult(ResultPrimitive.Substitute); };

            FallbackPolicy<ResultPrimitive> policy = Policy
                .HandleResult(ResultPrimitive.Fault)
                .OrResult(ResultPrimitive.FaultAgain)
                .FallbackAsync(fallbackAction);

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken cancellationToken = cancellationTokenSource.Token;

            int attemptsInvoked = 0;
            Action onExecute = () => attemptsInvoked++;

            Scenario scenario = new Scenario
            {
                AttemptDuringWhichToCancel = 1,
                ActionObservesCancellation = true
            };

            policy.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute, ResultPrimitive.Good))
                .ShouldThrow<OperationCanceledException>()
                .And.CancellationToken.Should().Be(cancellationToken);
            attemptsInvoked.Should().Be(1);

            fallbackActionExecuted.Should().BeFalse();
        }
示例#23
0
        public void Should_report_cancellation_during_otherwise_non_faulting_action_execution_and_cancel_further_retries_when_user_delegate_observes_cancellationtoken()
        {
            RetryPolicy<ResultPrimitive> policy = Policy
                .HandleResult(ResultPrimitive.Fault)
                .RetryAsync(3);

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken cancellationToken = cancellationTokenSource.Token;

            int attemptsInvoked = 0;
            Action onExecute = () => attemptsInvoked++;

            Scenario scenario = new Scenario
            {
                AttemptDuringWhichToCancel = 1,
                ActionObservesCancellation = true
            };

            policy.Awaiting(async x => await x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute,
                   ResultPrimitive.Good,
                   ResultPrimitive.Good,
                   ResultPrimitive.Good,
                   ResultPrimitive.Good))
                .ShouldThrow<TaskCanceledException>()
                .And.CancellationToken.Should().Be(cancellationToken);

            attemptsInvoked.Should().Be(1);
        }
        public async void Should_report_cancellation_when_both_open_circuit_and_cancellation()
        {
            CircuitBreakerPolicy<ResultPrimitive> breaker = Policy
                .HandleResult(ResultPrimitive.Fault)
                .CircuitBreakerAsync(1, TimeSpan.FromMinutes(1));

            (await breaker.RaiseResultSequenceAsync(ResultPrimitive.Fault).ConfigureAwait(false))
                .Should().Be(ResultPrimitive.Fault);

            breaker.Awaiting(x => x.RaiseResultSequenceAsync(ResultPrimitive.Fault))
                .ShouldThrow<BrokenCircuitException>()
                .WithMessage("The circuit is now open and is not allowing calls.");
            // Circuit is now broken.

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken cancellationToken = cancellationTokenSource.Token;

            int attemptsInvoked = 0;
            Action onExecute = () => attemptsInvoked++;

            cancellationTokenSource.Cancel();

            Scenario scenario = new Scenario
            {
                AttemptDuringWhichToCancel = null, // Cancelled manually instead - see above.
                ActionObservesCancellation = false
            };

            breaker.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute,
                   ResultPrimitive.Fault,
                   ResultPrimitive.Good))
                .ShouldThrow<TaskCanceledException>()
                .And.CancellationToken.Should().Be(cancellationToken);

            attemptsInvoked.Should().Be(0);
        }
        public void Should_report_cancellation_during_faulting_action_execution_when_user_delegate_does_not_observe_cancellationtoken()
        {
            var durationOfBreak = TimeSpan.FromMinutes(1);
            CircuitBreakerPolicy<ResultPrimitive> breaker = Policy
                            .HandleResult(ResultPrimitive.Fault)
                            .CircuitBreakerAsync(2, durationOfBreak);

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken cancellationToken = cancellationTokenSource.Token;

            int attemptsInvoked = 0;
            Action onExecute = () => attemptsInvoked++;

            Scenario scenario = new Scenario
            {
                AttemptDuringWhichToCancel = 1,
                ActionObservesCancellation = false
            };

            breaker.Awaiting(x => x.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute,
                   ResultPrimitive.Fault,
                   ResultPrimitive.Good))
                .ShouldThrow<TaskCanceledException>()
                .And.CancellationToken.Should().Be(cancellationToken);

            attemptsInvoked.Should().Be(1);
        }
示例#26
0
        public async void Should_report_faulting_from_faulting_last_retry_execution_when_user_delegate_does_not_observe_cancellation_raised_during_last_retry()
        {
            RetryPolicy<ResultPrimitive> policy = Policy
                       .HandleResult(ResultPrimitive.Fault)
                       .RetryAsync(3);

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            CancellationToken cancellationToken = cancellationTokenSource.Token;

            int attemptsInvoked = 0;
            Action onExecute = () => attemptsInvoked++;

            Scenario scenario = new Scenario
            {
                AttemptDuringWhichToCancel = 1 + 3,
                ActionObservesCancellation = false
            };

            (await policy.RaiseResultSequenceAndOrCancellationAsync(scenario, cancellationTokenSource, onExecute,
                   ResultPrimitive.Fault,
                   ResultPrimitive.Fault,
                   ResultPrimitive.Fault,
                   ResultPrimitive.Fault,
                   ResultPrimitive.Good).ConfigureAwait(false))
               .Should().Be(ResultPrimitive.Fault);

            attemptsInvoked.Should().Be(1 + 3);
        }