Exemple #1
0
        public async Task AddCircuitBreakerPolicy_RandomHandledHttpErrors_OnlyBreakWhenConsecutiveHandledErrorsDetected()
        {
            var statusCodeInOrder = new[] { HttpStatusCode.RequestTimeout, HttpStatusCode.RequestTimeout, HttpStatusCode.TooManyRequests,
                                            HttpStatusCode.RequestTimeout, HttpStatusCode.RequestTimeout, HttpStatusCode.RequestTimeout, HttpStatusCode.RequestTimeout };
            var exceptionAllowedBeforeBreaking = 3;
            var circuitBreakDuration           = 400;
            var mockInterface = new Mock <IFakeInterface>();

            mockInterface.Setup(exp => exp.DoSomethingAsync(It.IsAny <int>()))
            .Returns((int count) => Task.FromResult(new HttpResponseMessage(statusCodeInOrder[count])));
            var mockInstance = mockInterface.Object;
            var policy       = HttpClientPollyPolicy.Initialise()
                               .AddCircuitBreakerPolicy(exceptionAllowedBeforeBreaking, TimeSpan.FromMilliseconds(circuitBreakDuration))
                               .Build();

            Func <int, Task <HttpResponseMessage> > action        = (int index) => policy.ExecuteAsync(() => mockInstance.DoSomethingAsync(index));
            Func <Task <HttpResponseMessage> >      actionNoParam = () => policy.ExecuteAsync(() => mockInstance.DoSomethingAsync(3));

            Assert.Equal(statusCodeInOrder[0], (await action(0)).StatusCode);
            Assert.Equal(statusCodeInOrder[1], (await action(1)).StatusCode);
            Assert.Equal(statusCodeInOrder[2], (await action(2)).StatusCode);
            Assert.Equal(statusCodeInOrder[3], (await action(3)).StatusCode);
            Assert.Equal(statusCodeInOrder[4], (await action(4)).StatusCode);
            Assert.Equal(statusCodeInOrder[5], (await action(5)).StatusCode);

            await Assert.ThrowsAsync <BrokenCircuitException <HttpResponseMessage> >(actionNoParam);

            await Task.Delay(circuitBreakDuration);

            Assert.Equal(statusCodeInOrder[6], (await action(6)).StatusCode);
        }
Exemple #2
0
        public async Task AddCircuitBreakerPolicy_HavingRepeatedHttpRequestException_ActivateCircuitBreak()
        {
            var exceptionAllowedBeforeBreaking = 2;
            var circuitBreakDuration           = 400;
            var message       = "sample exception";
            var mockInterface = new Mock <IFakeInterface>();

            mockInterface.Setup(exp => exp.DoSomethingAsync(1))
            .Throws(new HttpRequestException(message));
            mockInterface.Setup(exp => exp.DoSomethingAsync(2))
            .Returns(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)));
            var mockInstance = mockInterface.Object;
            var policy       = HttpClientPollyPolicy.Initialise()
                               .AddCircuitBreakerPolicy(exceptionAllowedBeforeBreaking, TimeSpan.FromMilliseconds(circuitBreakDuration))
                               .Build();

            Func <int, Task <HttpResponseMessage> > action = count => policy.ExecuteAsync(() => mockInstance.DoSomethingAsync(count));

            await Assert.ThrowsAsync <HttpRequestException>(() => action(1));

            await Assert.ThrowsAsync <HttpRequestException>(() => action(1));

            await Assert.ThrowsAsync <BrokenCircuitException>(() => action(1));

            await Task.Delay(circuitBreakDuration);

            //Half Open goes to Close
            var result = await action(2);

            Assert.Equal(HttpStatusCode.OK, result.StatusCode);

            await Assert.ThrowsAsync <HttpRequestException>(() => action(1));
        }
Exemple #3
0
        public async Task AddCircuitBreakerPolicy_HavingRepeatedUnhandledException_DoesNotActivateCircuitBreak(Type exceptionType)
        {
            var exceptionAllowedBeforeBreaking = 2;
            var circuitBreakDuration           = 400;
            var mockInterface = new Mock <IFakeInterface>();

            mockInterface.Setup(exp => exp.DoSomethingAsync(It.IsAny <int>()))
            .Throws(Activator.CreateInstance(exceptionType) as Exception);
            var mockInstance = mockInterface.Object;
            var policy       = HttpClientPollyPolicy.Initialise()
                               .AddCircuitBreakerPolicy(exceptionAllowedBeforeBreaking, TimeSpan.FromMilliseconds(circuitBreakDuration))
                               .Build();

            Func <Task <HttpResponseMessage> > action = () => policy.ExecuteAsync(() => mockInstance.DoSomethingAsync(3));

            await Assert.ThrowsAsync(exceptionType, action);

            await Assert.ThrowsAsync(exceptionType, action);

            await Assert.ThrowsAsync(exceptionType, action);

            await Assert.ThrowsAsync(exceptionType, action);

            await Task.Delay(circuitBreakDuration);

            await Assert.ThrowsAsync(exceptionType, action);
        }
Exemple #4
0
        public async Task HttpClientPolicy_CombinePolicies_BehavesAccordingToPolicy()
        {
            var retryCount = 3;
            var exceptionAllowedBeforeBreaking = retryCount + 2;
            var circuitBreakDurationInMs       = 10000;
            var timeoutInSeconds = 25;

            var foo = new FooStub();

            var policy = HttpClientPollyPolicy.Initialise()
                         .AddWaitRetryPolicy(retryCount)
                         .AddFallbackPolicy(() => foo.FakeCallback())
                         .AddCircuitBreakerPolicy(exceptionAllowedBeforeBreaking, TimeSpan.FromMilliseconds(circuitBreakDurationInMs))
                         .AddTimeoutPolicy(timeoutInSeconds)
                         .Build();

            Func <bool, int?, Task <HttpResponseMessage> > barAsync = (bool returnFailureMessage, int?fakeTimeoutInSeconds) => policy.ExecuteAsync(() => foo.BarAsync(returnFailureMessage, fakeTimeoutInSeconds));

            var result = await barAsync(true, null);

            int barAsyncMethodInvocationCount = retryCount + 1;

            Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode);

            result = await barAsync(true, null);

            barAsyncMethodInvocationCount++;
            int callbackMethodInvocationCount = 3;

            Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode);

            await Task.Delay(circuitBreakDurationInMs);

            //Return unhandled error code to transition circuit from half-open to close
            result = await barAsync(false, null);

            barAsyncMethodInvocationCount++;
            Assert.Equal(HttpStatusCode.OK, result.StatusCode);

            result = await barAsync(true, null);

            barAsyncMethodInvocationCount += retryCount + 1;
            Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode);

            result = await barAsync(true, timeoutInSeconds);

            barAsyncMethodInvocationCount++;
            callbackMethodInvocationCount++;
            Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode);

            Assert.Equal(callbackMethodInvocationCount, foo.FallbackCount);
            Assert.Equal(barAsyncMethodInvocationCount, foo.BarAsyncCount);
        }
Exemple #5
0
        public async Task AddWaitRetryPolicy_CallSucceedInitially_DoesNotRetry()
        {
            var policy = HttpClientPollyPolicy.Initialise()
                         .AddWaitRetryPolicy(2)
                         .Build();
            var mockInterface = new Mock <IFakeInterface>();

            mockInterface.Setup(exp => exp.DoSomethingAsync(It.IsAny <int>()))
            .Returns(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)));
            var mockInstance = mockInterface.Object;

            var result = await policy.ExecuteAsync(() => mockInstance.DoSomethingAsync(3));

            Assert.Equal(HttpStatusCode.OK, result.StatusCode);
            mockInterface.Verify(exp => exp.DoSomethingAsync(It.IsAny <int>()), Times.Exactly(1));
        }
Exemple #6
0
        public async Task AddWaitRetryPolicy_ReturnHttpTransientError_RetryUptoCount(HttpStatusCode transientStatusCode)
        {
            var retryCount = 2;
            var policy     = HttpClientPollyPolicy.Initialise()
                             .AddWaitRetryPolicy(retryCount)
                             .Build();
            var mockInterface = new Mock <IFakeInterface>();

            mockInterface.Setup(exp => exp.DoSomethingAsync(It.IsAny <int>()))
            .Returns(Task.FromResult(new HttpResponseMessage(transientStatusCode)));
            var mockInstance = mockInterface.Object;

            var result = await policy.ExecuteAsync(() => mockInstance.DoSomethingAsync(3));

            Assert.Equal(transientStatusCode, result.StatusCode);
            mockInterface.Verify(exp => exp.DoSomethingAsync(It.IsAny <int>()), Times.Exactly(retryCount + 1));
        }
Exemple #7
0
        public async Task AddTimeoutPolicy_OperationCompleteWithinTimeoutPeriod_CompleteSuccessfully()
        {
            var timeoutInMilliseconds = 1000;
            var policy = HttpClientPollyPolicy.Initialise()
                         .AddTimeoutPolicy(timeoutInMilliseconds / 1000)
                         .Build();
            var mockInterface = new Mock <IFakeInterface>();

            mockInterface.Setup(exp => exp.DoSomethingAsync(It.IsAny <int>()))
            .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.OK), TimeSpan.FromMilliseconds(timeoutInMilliseconds / 2));
            var mockInstance = mockInterface.Object;

            var result = await policy.ExecuteAsync(() => mockInstance.DoSomethingAsync(3));

            Assert.Equal(HttpStatusCode.OK, result.StatusCode);
            mockInterface.Verify(exp => exp.DoSomethingAsync(It.IsAny <int>()), Times.Exactly(1));
        }
Exemple #8
0
        public async Task AddWaitRetryPolicy_ThrowNullException_DoesNotRetry()
        {
            var retryCount = 2;
            var policy     = HttpClientPollyPolicy.Initialise()
                             .AddWaitRetryPolicy(retryCount)
                             .Build();
            var mockInterface = new Mock <IFakeInterface>();

            mockInterface.Setup(exp => exp.DoSomethingAsync(It.IsAny <int>()))
            .Throws(new NullReferenceException());
            var mockInstance = mockInterface.Object;

            Func <Task <HttpResponseMessage> > action = () => policy.ExecuteAsync(() => mockInstance.DoSomethingAsync(3));

            await Assert.ThrowsAsync <NullReferenceException>(action);

            mockInterface.Verify(exp => exp.DoSomethingAsync(It.IsAny <int>()), Times.Exactly(1));
        }
Exemple #9
0
        public async Task AddTimeoutPolicy_OperationExceedTimeoutPeriod_ThrowsPollyTimeoutRejectedException()
        {
            var timeoutInMilliseconds = 1000;
            var policy = HttpClientPollyPolicy.Initialise()
                         .AddTimeoutPolicy(timeoutInMilliseconds / 1000)
                         .Build();
            var mockInterface = new Mock <IFakeInterface>();

            mockInterface.Setup(exp => exp.DoSomethingAsync(It.IsAny <int>()))
            .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.OK), TimeSpan.FromMilliseconds(timeoutInMilliseconds + 20));
            var mockInstance = mockInterface.Object;

            Func <Task <HttpResponseMessage> > action = () => policy.ExecuteAsync(() => mockInstance.DoSomethingAsync(3));

            await Assert.ThrowsAsync <TimeoutRejectedException>(action);

            mockInterface.Verify(exp => exp.DoSomethingAsync(It.IsAny <int>()), Times.Exactly(1));
        }
Exemple #10
0
        public async Task AddFallbackPolicy_WithUnhandledHttpErrors_DoesNotInvokeFallbackMethod(HttpStatusCode httpStatusCode)
        {
            var mockInterface = new Mock <IFakeInterface>();

            mockInterface.Setup(exp => exp.DoSomethingAsync(It.IsAny <int>()))
            .Returns(Task.FromResult(new HttpResponseMessage(httpStatusCode)));
            mockInterface.Setup(exp => exp.FakeCallback())
            .Returns(Task.FromResult(new HttpResponseMessage(HttpStatusCode.Accepted)));
            var mockInstance = mockInterface.Object;
            var policy       = HttpClientPollyPolicy.Initialise()
                               .AddFallbackPolicy(() => mockInstance.FakeCallback())
                               .Build();

            var result = await policy.ExecuteAsync(() => mockInstance.DoSomethingAsync(3));

            Assert.Equal(httpStatusCode, result.StatusCode);
            mockInterface.Verify(exp => exp.DoSomethingAsync(It.IsAny <int>()), Times.Exactly(1));
            mockInterface.Verify(exp => exp.FakeCallback(), Times.Never);
        }
Exemple #11
0
        public async Task AddFallbackPolicy_WithHandledExceptions_InvokeFallbackMethod(Type exceptionType)
        {
            var mockInterface = new Mock <IFakeInterface>();

            mockInterface.Setup(exp => exp.DoSomethingAsync(It.IsAny <int>()))
            .Throws(Activator.CreateInstance(exceptionType) as Exception);
            mockInterface.Setup(exp => exp.FakeCallback())
            .Returns(Task.FromResult(new HttpResponseMessage(HttpStatusCode.Accepted)));
            var mockInstance = mockInterface.Object;
            var policy       = HttpClientPollyPolicy.Initialise()
                               .AddFallbackPolicy(() => mockInstance.FakeCallback())
                               .Build();

            var result = await policy.ExecuteAsync(() => mockInstance.DoSomethingAsync(3));

            Assert.Equal(HttpStatusCode.Accepted, result.StatusCode);
            mockInterface.Verify(exp => exp.DoSomethingAsync(It.IsAny <int>()), Times.Exactly(1));
            mockInterface.Verify(exp => exp.FakeCallback(), Times.Exactly(1));
        }
Exemple #12
0
        public async Task AddCircuitBreakerPolicy_HavingRepeatedUnHandledHttpErrors_DoesNotActivateCircuitBreak(HttpStatusCode httpStatusCode)
        {
            var exceptionAllowedBeforeBreaking = 2;
            var circuitBreakDuration           = 400;
            var mockInterface = new Mock <IFakeInterface>();

            mockInterface.Setup(exp => exp.DoSomethingAsync(It.IsAny <int>()))
            .Returns(Task.FromResult(new HttpResponseMessage(httpStatusCode)));
            var mockInstance = mockInterface.Object;
            var policy       = HttpClientPollyPolicy.Initialise()
                               .AddCircuitBreakerPolicy(exceptionAllowedBeforeBreaking, TimeSpan.FromMilliseconds(circuitBreakDuration))
                               .Build();

            Func <Task <HttpResponseMessage> > action = () => policy.ExecuteAsync(() => mockInstance.DoSomethingAsync(3));

            Assert.Equal(httpStatusCode, (await action()).StatusCode);
            Assert.Equal(httpStatusCode, (await action()).StatusCode);
            Assert.Equal(httpStatusCode, (await action()).StatusCode);
            await Task.Delay(circuitBreakDuration);

            Assert.Equal(httpStatusCode, (await action()).StatusCode);
        }