public void ExceptionIsThrownWhenAllRetriesFailDuringAsyncBegin()
        {
            var policy = this.retryManager.GetRetryPolicy <MockErrorDetectionStrategy>("Exponential Backoff, 5 retries");

            int count1 = 0;

            policy.Retrying += (s, args) =>
            {
                Assert.IsInstanceOfType(args.LastException, typeof(InvalidCastException));
                count1 = args.CurrentRetryCount;
            };

            TestAsyncOperation asyncInstance = new TestAsyncOperation();

            asyncInstance.CountToThrowAtBegin     = 15;
            asyncInstance.ExceptionToThrowAtBegin = new InvalidCastException();
            try
            {
                policy
                .ExecuteAsync(() =>
                              Task.Factory.FromAsync(asyncInstance.BeginMethod, asyncInstance.EndMethod, null))
                .Wait(TimeSpan.FromSeconds(5));
            }
            catch (AggregateException ex)
            {
                Assert.AreEqual(5, count1);
                Assert.AreEqual(1, ex.InnerExceptions.Count);

                throw ex.InnerException;
            }

            Assert.Fail("Test should throw");
        }
        public void ExceptionIsThrownWhenNonTransientExceptionOccursDuringAsyncEnd()
        {
            var policy = this.retryManager.GetRetryPolicy <MockErrorDetectionStrategy>("Incremental, 5 retries");

            int count1 = 0;

            policy.Retrying += (s, args) =>
            {
                Assert.IsInstanceOfType(args.LastException, typeof(InvalidCastException));
                count1 = args.CurrentRetryCount;
            };

            TestAsyncOperation asyncInstance = new TestAsyncOperation();

            asyncInstance.CountToThrowAtEnd          = 3;
            asyncInstance.ExceptionToThrowAtEnd      = new InvalidCastException();
            asyncInstance.FatalException             = new MissingFieldException();
            asyncInstance.ThrowFatalExceptionAtBegin = false;
            try
            {
                policy
                .ExecuteAsync(() =>
                              Task.Factory.FromAsync(asyncInstance.BeginMethod, asyncInstance.EndMethod, null))
                .Wait(TimeSpan.FromSeconds(5));
            }
            catch (AggregateException ex)
            {
                Assert.AreEqual(2, count1);
                Assert.AreEqual(1, ex.InnerExceptions.Count);

                throw ex.InnerException;
            }

            Assert.Fail("Test should throw");
        }
        protected override void Arrange()
        {
            base.Arrange();

            this.asyncOperation = new TestAsyncOperation(new Exception());

            this.countdownEvent = new CountdownEvent(1);
        }
        protected override void Arrange()
        {
            base.Arrange();

            this.asyncOperation = new TestAsyncOperation();

            this.asyncOperationFinished = new AutoResetEvent(false);

            this.detectionStrategyMock = new Mock<ITransientErrorDetectionStrategy>();
            this.detectionStrategyMock.Setup(ds => ds.IsTransient(It.Is<Exception>(e => e is InvalidOperationException))).Returns(true);

            this.retryPolicy = new RetryPolicy(this.detectionStrategyMock.Object, 2);
        }
        public static void Throw()
        {
            // Test that exceptions get passed all the way through PostOperationCompleted(callback, AsyncCompletedEventArgs)
            Task.Run(() =>
            {
                var operation = new TestAsyncOperation(op =>
                {
                    throw new TestException("Test throw");
                });

                Assert.Throws <TestException>(() => operation.Wait());
            }).GetAwaiter().GetResult();
        }
        public static void ThrowAfterAsyncComplete()
        {
            Task.Run(() =>
            {
                var operation = new TestAsyncOperation(op => { });
                operation.Wait();

                SendOrPostCallback noopCallback = state => { };
                Assert.Throws <InvalidOperationException>(() => operation.AsyncOperation.Post(noopCallback, null));
                Assert.Throws <InvalidOperationException>(() => operation.AsyncOperation.PostOperationCompleted(noopCallback, null));
                Assert.Throws <InvalidOperationException>(() => operation.AsyncOperation.OperationCompleted());
            }).GetAwaiter().GetResult();
        }
        public static void Noop()
        {
            // Test that a simple AsyncOperation can be dispatched and completed via AsyncOperationManager
            Task.Run(() =>
            {
                var operation = new TestAsyncOperation(op => { });
                operation.Wait();

                Assert.True(operation.Completed);
                Assert.False(operation.Cancelled);
                Assert.Null(operation.Exception);
            }).GetAwaiter().GetResult();
        }
        protected override void Arrange()
        {
            base.Arrange();

            this.asyncOperation = new TestAsyncOperation();

            this.asyncOperationFinished = new AutoResetEvent(false);

            this.detectionStrategyMock = new Mock <ITransientErrorDetectionStrategy>();
            this.detectionStrategyMock.Setup(ds => ds.IsTransient(It.Is <Exception>(e => e is InvalidOperationException))).Returns(true);

            this.retryPolicy = new RetryPolicy(this.detectionStrategyMock.Object, 2);
        }
        public static void ThrowAfterAsyncComplete()
        {
            Task.Run(() =>
                {
                    var operation = new TestAsyncOperation(op => { });
                    operation.Wait();

                    SendOrPostCallback noopCallback = state => { };
                    Assert.Throws<InvalidOperationException>(() => operation.AsyncOperation.Post(noopCallback, null));
                    Assert.Throws<InvalidOperationException>(() => operation.AsyncOperation.PostOperationCompleted(noopCallback, null));
                    Assert.Throws<InvalidOperationException>(() => operation.AsyncOperation.OperationCompleted());
                }).Wait();
        }
        public static void Noop()
        {
            // Test that a simple AsyncOperation can be dispatched and completed via AsyncOperationManager
            Task.Run(() =>
                {
                    var operation = new TestAsyncOperation(op => { });
                    operation.Wait();

                    Assert.True(operation.Completed);
                    Assert.False(operation.Cancelled);
                    Assert.Null(operation.Exception);

                }).Wait();
        }
        public static void Cancel()
        {
            // Test that cancellation gets passed all the way through PostOperationCompleted(callback, AsyncCompletedEventArgs)
            Task.Run(() =>
            {
                var cancelEvent = new ManualResetEventSlim();
                var operation   = new TestAsyncOperation(op =>
                {
                    Assert.True(cancelEvent.Wait(TimeSpan.FromSeconds(SpinTimeoutSeconds)));
                }, cancelEvent: cancelEvent);

                operation.Cancel();
                operation.Wait();
                Assert.True(operation.Completed);
                Assert.True(operation.Cancelled);
                Assert.Null(operation.Exception);
            }).GetAwaiter().GetResult();
        }
        public static void Cancel()
        {
            // Test that cancellation gets passed all the way through PostOperationCompleted(callback, AsyncCompletedEventArgs)
            Task.Run(() =>
             {
                 var cancelEvent = new ManualResetEventSlim();
                 var operation = new TestAsyncOperation(op =>
                 {
                     Assert.True(cancelEvent.Wait(TimeSpan.FromSeconds(SpinTimeoutSeconds)));
                 }, cancelEvent: cancelEvent);

                 operation.Cancel();
                 operation.Wait();
                 Assert.True(operation.Completed);
                 Assert.True(operation.Cancelled);
                 Assert.Null(operation.Exception);
             }).GetAwaiter().GetResult();
        }
        public void ActionIsExecutedWhenSomeRetriesFailDuringAsyncBeginAndThenSucceeds()
        {
            var policy = this.retryManager.GetRetryPolicy <MockErrorDetectionStrategy>("Incremental, 5 retries");

            int count1 = 0;

            policy.Retrying += (s, args) =>
            {
                Assert.IsInstanceOfType(args.LastException, typeof(InvalidCastException));
                count1 = args.CurrentRetryCount;
            };

            TestAsyncOperation asyncInstance = new TestAsyncOperation();

            asyncInstance.CountToThrowAtBegin     = 3;
            asyncInstance.ExceptionToThrowAtBegin = new InvalidCastException();
            policy
            .ExecuteAsync(() =>
                          Task.Factory.FromAsync(asyncInstance.BeginMethod, asyncInstance.EndMethod, null))
            .Wait(TimeSpan.FromSeconds(5));

            Assert.AreEqual(2, count1);
        }
        protected override void Arrange()
        {
            base.Arrange();

            this.asyncOperation = new TestAsyncOperation();

            this.countdownEvent = new CountdownEvent(1);
        }
        public static void Throw()
        {
            // Test that exceptions get passed all the way through PostOperationCompleted(callback, AsyncCompletedEventArgs)
            Task.Run(() =>
            {
                var operation = new TestAsyncOperation(op =>
                {
                    throw new TestException("Test throw");
                });

                Assert.Throws<TestException>(() => operation.Wait());
            }).Wait();
        }