public void Should_report_cancellation_during_faulting_last_retry_execution_when_user_delegate_does_observe_cancellationToken()
        {
            RetryPolicy <ResultPrimitive> policy = Policy
                                                   .HandleResult(ResultPrimitive.Fault)
                                                   .Retry(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.Invoking(x => x.RaiseResultSequenceAndOrCancellation(scenario, cancellationTokenSource, onExecute,
                                                                        ResultPrimitive.Fault,
                                                                        ResultPrimitive.Fault,
                                                                        ResultPrimitive.Fault,
                                                                        ResultPrimitive.Fault,
                                                                        ResultPrimitive.Good))
            .Should().Throw <OperationCanceledException>()
            .And.CancellationToken.Should().Be(cancellationToken);

            attemptsInvoked.Should().Be(1 + 3);
        }
        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)
                                                   .Retry(3, (_, __) =>
            {
                cancellationTokenSource.Cancel();
            });

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

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

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

            attemptsInvoked.Should().Be(1);
        }
        public void Should_not_execute_action_when_cancellationToken_cancelled_before_execute()
        {
            RetryPolicy <ResultPrimitive> policy = Policy
                                                   .HandleResult(ResultPrimitive.Fault)
                                                   .Retry(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.Invoking(x => x.RaiseResultSequenceAndOrCancellation(scenario, cancellationTokenSource, onExecute,
                                                                        ResultPrimitive.Fault,
                                                                        ResultPrimitive.Fault,
                                                                        ResultPrimitive.Fault,
                                                                        ResultPrimitive.Good))
            .Should().Throw <OperationCanceledException>()
            .And.CancellationToken.Should().Be(cancellationToken);

            attemptsInvoked.Should().Be(0);
        }