public async void TestRetryThrowsTimeoutException()
        {
            var customConfig = new RetryConfiguration()
            {
                MaxAttempts            = 10,
                TotalElapsedTimeInSecs = 1, // This makes sure the request timesout before returning error response.
                RetryableStatusCodes   = new List <int> {
                    404
                },
                GetNextDelayInSeconds = (retryAttempt) => Math.Pow(2, retryAttempt)
            };

            var retrier            = new GenericRetrier(customConfig);
            var mockCallHttpMethod = new Mock <Func <HttpRequestMessage, CancellationToken, Task <HttpResponseMessage> > >();
            var requestMessage     = new HttpRequestMessage();

            mockCallHttpMethod.Setup(httpMethod => httpMethod(It.IsAny <HttpRequestMessage>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new HttpResponseMessage()
            {
                StatusCode = System.Net.HttpStatusCode.NotFound
            });

            await Assert.ThrowsAsync <OciException>(() => retrier.MakeRetryingCall(
                                                        mockCallHttpMethod.Object,
                                                        requestMessage,
                                                        default));
        }
        public async void TestRetryForCustomConfig()
        {
            var customConfig = new RetryConfiguration()
            {
                MaxAttempts          = 10,
                RetryableStatusCodes = new List <int> {
                    404
                },
                GetNextDelayInSeconds = _ => 0
            };

            var retrier            = new GenericRetrier(customConfig);
            var mockCallHttpMethod = new Mock <Func <HttpRequestMessage, CancellationToken, Task <HttpResponseMessage> > >();
            var requestMessage     = new HttpRequestMessage();

            mockCallHttpMethod.Setup(httpMethod => httpMethod(It.IsAny <HttpRequestMessage>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new HttpResponseMessage()
            {
                StatusCode = System.Net.HttpStatusCode.NotFound
            });

            await retrier.MakeRetryingCall(
                mockCallHttpMethod.Object,
                requestMessage,
                default);

            mockCallHttpMethod.Verify(mock => mock.Invoke(It.IsAny <HttpRequestMessage>(), It.IsAny <CancellationToken>()), Times.Exactly(customConfig.MaxAttempts + 1));
        }
        public async void TestRetryForDefaultRetryConfig(int statusCode, string message)
        {
            var retrier = new GenericRetrier(new RetryConfiguration {
                GetNextDelayInSeconds = _ => 0
            });                                                                                           // disabling sleep time
            var mockCallHttpMethod = new Mock <Func <HttpRequestMessage, CancellationToken, Task <HttpResponseMessage> > >();
            var requestMessage     = new HttpRequestMessage();

            mockCallHttpMethod.Setup(httpMethod => httpMethod(It.IsAny <HttpRequestMessage>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new HttpResponseMessage()
            {
                StatusCode = (System.Net.HttpStatusCode)statusCode,
                Content    = ContentHelper.CreateHttpContent(new ErrorCodeAndMessage(message, "Some Error"))
            });

            await retrier.MakeRetryingCall(
                mockCallHttpMethod.Object,
                requestMessage,
                default);

            var maxDefaultRetries = RetryConfiguration.DefaultWaiterConfiguration.MaxAttempts;

            // verify the number of retries. Total tries = maxDefaultRetries + 1 (original request).
            mockCallHttpMethod.Verify(mock => mock.Invoke(It.IsAny <HttpRequestMessage>(), It.IsAny <CancellationToken>()), Times.Exactly(maxDefaultRetries + 1));
        }
        public async void TestRetryThrowsTimeoutException(int statusCode, string message)
        {
            var customConfig = new RetryConfiguration()
            {
                MaxAttempts            = 10,
                TotalElapsedTimeInSecs = 1, // This makes sure the request timesout before returning error response.
                GetNextDelayInSeconds  = (retryAttempt) => Math.Pow(2, retryAttempt)
            };

            var retrier            = new GenericRetrier(customConfig);
            var mockCallHttpMethod = new Mock <Func <HttpRequestMessage, CancellationToken, Task <HttpResponseMessage> > >();
            var requestMessage     = new HttpRequestMessage();

            mockCallHttpMethod.Setup(httpMethod => httpMethod(It.IsAny <HttpRequestMessage>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new HttpResponseMessage()
            {
                StatusCode = (System.Net.HttpStatusCode)statusCode,
                Content    = ContentHelper.CreateHttpContent(new ErrorCodeAndMessage(message, "Some Error"))
            });

            await Assert.ThrowsAsync <OciException>(() => retrier.MakeRetryingCall(
                                                        mockCallHttpMethod.Object,
                                                        requestMessage,
                                                        default));
        }
        public async void TestRetryForCustomConfig(int statusCode, string message)
        {
            var customConfig = new RetryConfiguration
            {
                MaxAttempts     = 10,
                RetryableErrors = new Collection <Tuple <int, string> > {
                    new Tuple <int, string>(statusCode, message)
                },
                GetNextDelayInSeconds = _ => 0
            };

            var retrier            = new GenericRetrier(customConfig);
            var mockCallHttpMethod = new Mock <Func <HttpRequestMessage, CancellationToken, Task <HttpResponseMessage> > >();
            var requestMessage     = new HttpRequestMessage();

            mockCallHttpMethod.Setup(httpMethod => httpMethod(It.IsAny <HttpRequestMessage>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new HttpResponseMessage()
            {
                StatusCode = (System.Net.HttpStatusCode)statusCode,
                Content    = ContentHelper.CreateHttpContent(new ErrorCodeAndMessage(message, "Some Error"))
            });

            await retrier.MakeRetryingCall(
                mockCallHttpMethod.Object,
                requestMessage,
                default);

            mockCallHttpMethod.Verify(mock => mock.Invoke(It.IsAny <HttpRequestMessage>(), It.IsAny <CancellationToken>()), Times.Exactly(customConfig.MaxAttempts + 1));
        }
        public async void TestNoRetryForSuccessFulResponse()
        {
            var retrier            = new GenericRetrier(new RetryConfiguration());
            var mockCallHttpMethod = new Mock <Func <HttpRequestMessage, CancellationToken, Task <HttpResponseMessage> > >();
            var requestMessage     = new HttpRequestMessage();

            mockCallHttpMethod.Setup(httpMethod => httpMethod(It.IsAny <HttpRequestMessage>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new HttpResponseMessage()
            {
                StatusCode = System.Net.HttpStatusCode.OK
            });

            await retrier.MakeRetryingCall(
                mockCallHttpMethod.Object,
                requestMessage,
                default);

            // Verify if httpMethod has been invoked only once.
            mockCallHttpMethod.Verify(mock => mock.Invoke(It.IsAny <HttpRequestMessage>(), It.IsAny <CancellationToken>()), Times.Exactly(1));
        }
        public async void TestNoRetryForNotImplemented()
        {
            var retrier            = new GenericRetrier(new RetryConfiguration());
            var mockCallHttpMethod = new Mock <Func <HttpRequestMessage, CancellationToken, Task <HttpResponseMessage> > >();
            var requestMessage     = new HttpRequestMessage();

            mockCallHttpMethod.Setup(httpMethod => httpMethod(It.IsAny <HttpRequestMessage>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new HttpResponseMessage()
            {
                StatusCode = System.Net.HttpStatusCode.NotImplemented,
                Content    = ContentHelper.CreateHttpContent(new ErrorCodeAndMessage("NotImplemented", "Some Error"))
            });

            await retrier.MakeRetryingCall(
                mockCallHttpMethod.Object,
                requestMessage,
                default);

            // Verify if httpMethod has been invoked only once.
            mockCallHttpMethod.Verify(mock => mock.Invoke(It.IsAny <HttpRequestMessage>(), It.IsAny <CancellationToken>()), Times.Exactly(1));
        }