public void HttpRetryMessageHandler_WaitAndRetryAsync_ThrowsException_If_Cancellation_Requested()
        {
            // Arrange
            int maxReTries = 3;
            var cancellationTokenSource = new CancellationTokenSource();
            var httpRequestMessage      = new HttpRequestMessage(HttpMethod.Get, "http://localhostTestApi.com");

            var handler = new HttpRetryMessageHandler(maxReTries)
            {
                InnerHandler = new TestHttpMessageHandlerCancelAfterFirstTry()
                {
                    CancellationTokenSource = cancellationTokenSource
                }
            };

            var invoker = new HttpMessageInvoker(handler);

            // Act
            var exception = Assert.Catch <Exception>(() =>
            {
                var result = invoker.SendAsync(httpRequestMessage, cancellationTokenSource.Token).Result;
            });

            // Assert
            Assert.IsNotNull(exception);
            Assert.IsTrue(this.IsOperationCanceledException(exception));
            Assert.AreEqual(((TestHttpMessageHandlerCancelAfterFirstTry)handler.InnerHandler).AttemptedTries, 1);
        }
        public void GetHttpClientMaxRetriesHandler_Sets_DefaultTimeOut_For_LessNumber_Of_Retries()
        {
            // Arrange
            var handler          = new HttpRetryMessageHandler(1);
            var estimatedTimeOut = HttpClientHelper.TimeOutInSecs(handler.MaxRetries);

            var defaultTimeOut = new HttpClient().Timeout;

            // Act
            var httpClient    = HttpClientHelper.GetHttpClientWithMaxRetriesHandler(handler.MaxRetries);
            var actualTimeOut = httpClient.Timeout.TotalSeconds;

            // Assert
            Assert.IsTrue(estimatedTimeOut < defaultTimeOut.TotalSeconds);
            Assert.AreEqual(defaultTimeOut, httpClient.Timeout);
        }
        public void HttpGet_Success_In_FirstTry()
        {
            // Arrange
            var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "http://localhostTestApi.com");

            var handler = new HttpRetryMessageHandler()
            {
                InnerHandler = new TestHttpRetryMessageHandlerSuccess()
            };
            var invoker = new HttpMessageInvoker(handler);

            // Act
            var result = invoker.SendAsync(httpRequestMessage, CancellationToken.None).Result;

            // Assert
            Assert.AreEqual(((TestHttpRetryMessageHandlerSuccess)handler.InnerHandler).AttemptedTries, 1);
        }
        public void GetHttpClientMaxRetriesHandler_SetsTimeOutBased_On_MaxRetries()
        {
            // Arrange
            var    handler         = new HttpRetryMessageHandler(5);
            double expectedTimeOut = 20 * (handler.MaxRetries + 1);

            for (int reAttemptNo = 1; reAttemptNo <= handler.MaxRetries; reAttemptNo++)
            {
                expectedTimeOut += HttpClientHelper.ExponentialSleepDuration(reAttemptNo).TotalSeconds;
            }

            // Act
            var httpClient    = HttpClientHelper.GetHttpClientWithMaxRetriesHandler(handler.MaxRetries);
            var actualTimeOut = httpClient.Timeout.TotalSeconds;

            // Assert
            Assert.IsTrue(actualTimeOut >= 100);
            Assert.IsTrue(Math.Abs(expectedTimeOut - actualTimeOut) <= 1);
        }
        public void TotalTimeOutInSecs_Returns_TimeOut_Based_On_MaxRetries()
        {
            for (int maxRetries = 1; maxRetries <= HttpClientHelper.DefaultMaxRetries; maxRetries++)
            {
                // Arrange
                var    handler         = new HttpRetryMessageHandler(maxRetries);
                double expectedTimeOut = 20 * (handler.MaxRetries + 1);
                for (int reAttemptNo = 1; reAttemptNo <= handler.MaxRetries; reAttemptNo++)
                {
                    expectedTimeOut += HttpClientHelper.ExponentialSleepDuration(reAttemptNo).TotalSeconds;
                }

                // Act
                var actualTimeOut = HttpClientHelper.TimeOutInSecs(handler.MaxRetries);

                // Assert
                Assert.IsTrue(Math.Abs(expectedTimeOut - actualTimeOut) <= 1);
            }
        }
        public void HttpGet_MaxRetries_OnFailure()
        {
            // Arrange
            int maxReTries         = 2;
            var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "http://localhostTestApi.com");

            var handler = new HttpRetryMessageHandler(maxReTries)
            {
                InnerHandler = new TestHttpRetryMessageHandlerFailure()
            };

            var invoker = new HttpMessageInvoker(handler);

            // Act
            var result = invoker.SendAsync(httpRequestMessage, CancellationToken.None).Result;

            // Assert
            Assert.AreEqual(((TestHttpRetryMessageHandlerFailure)handler.InnerHandler).AttemptedTries, maxReTries + 1);
        }
        public void GetTotalSleepDurationInSecs_Returns_SumOf_SleepTimes_Between_Each_Retry()
        {
            for (int maxRetries = 1; maxRetries <= HttpClientHelper.DefaultMaxRetries; maxRetries++)
            {
                // Arrange
                var handler = new HttpRetryMessageHandler(maxRetries);

                double expectedSleepTimeInSecs = 0;
                for (int reAttemptNo = 1; reAttemptNo <= handler.MaxRetries; reAttemptNo++)
                {
                    expectedSleepTimeInSecs += HttpClientHelper.ExponentialSleepDuration(reAttemptNo).TotalSeconds;
                }

                // Act
                var actualSleepTimeInSecs = HttpClientHelper.GetTotalSleepDurationInSecs(handler.MaxRetries);

                // Assert
                Assert.IsTrue(Math.Abs(expectedSleepTimeInSecs - actualSleepTimeInSecs) <= 1);
            }
        }