Skip to content

Commit

Permalink
Move breaker ignored exceptions to CommandInvoker
Browse files Browse the repository at this point in the history
  • Loading branch information
robhruska committed Apr 4, 2017
1 parent d677265 commit e787e52
Show file tree
Hide file tree
Showing 8 changed files with 223 additions and 84 deletions.
31 changes: 25 additions & 6 deletions Hudl.Mjolnir.Tests/Command/BreakerInvokerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Hudl.Mjolnir.Tests.Helper;
using Moq;
using Xunit;
using Hudl.Mjolnir.Bulkhead;

namespace Hudl.Mjolnir.Tests.Command
{
Expand All @@ -31,8 +32,11 @@ public async Task WhenRejected_FiresBreakerRejectedMetricEvent()
mockCommandContext.Setup(m => m.GetCircuitBreaker(It.IsAny<GroupKey>())).Returns(mockBreaker.Object);
mockCommandContext.SetupGet(m => m.MetricEvents).Returns(mockMetricEvents.Object);

var mockBreakerExceptionHandler = new Mock<IBreakerExceptionHandler>(MockBehavior.Strict);
mockBreakerExceptionHandler.Setup(m => m.IsExceptionIgnored(It.IsAny<Type>())).Returns(false);

var command = new NoOpAsyncCommand();
var invoker = new BreakerInvoker(mockCommandContext.Object);
var invoker = new BreakerInvoker(mockCommandContext.Object, mockBreakerExceptionHandler.Object);

await Assert.ThrowsAsync<CircuitBreakerRejectedException>(() => invoker.ExecuteWithBreakerAsync(command, CancellationToken.None));

Expand All @@ -54,8 +58,11 @@ public async Task WhenSuccessful_FiresBreakerSuccessCountMetricEvent()
mockCommandContext.Setup(m => m.GetCircuitBreaker(It.IsAny<GroupKey>())).Returns(mockBreaker.Object);
mockCommandContext.SetupGet(m => m.MetricEvents).Returns(mockMetricEvents.Object);

var mockBreakerExceptionHandler = new Mock<IBreakerExceptionHandler>(MockBehavior.Strict);
mockBreakerExceptionHandler.Setup(m => m.IsExceptionIgnored(It.IsAny<Type>())).Returns(false);

var command = new NoOpFailingAsyncCommand();
var invoker = new BreakerInvoker(mockCommandContext.Object);
var invoker = new BreakerInvoker(mockCommandContext.Object, mockBreakerExceptionHandler.Object);

await Assert.ThrowsAsync<ExpectedTestException>(() => invoker.ExecuteWithBreakerAsync(command, CancellationToken.None));

Expand All @@ -77,8 +84,11 @@ public async Task WhenFailed_FiresBreakerFailureCountMetricEvent()
mockCommandContext.Setup(m => m.GetCircuitBreaker(It.IsAny<GroupKey>())).Returns(mockBreaker.Object);
mockCommandContext.SetupGet(m => m.MetricEvents).Returns(mockMetricEvents.Object);

var mockBreakerExceptionHandler = new Mock<IBreakerExceptionHandler>(MockBehavior.Strict);
mockBreakerExceptionHandler.Setup(m => m.IsExceptionIgnored(It.IsAny<Type>())).Returns(false);

var command = new NoOpAsyncCommand(); // Should be successful.
var invoker = new BreakerInvoker(mockCommandContext.Object);
var invoker = new BreakerInvoker(mockCommandContext.Object, mockBreakerExceptionHandler.Object);

await invoker.ExecuteWithBreakerAsync(command, CancellationToken.None);

Expand All @@ -103,8 +113,11 @@ public void WhenRejected_FiresBreakerRejectedMetricEvent()
mockCommandContext.Setup(m => m.GetCircuitBreaker(It.IsAny<GroupKey>())).Returns(mockBreaker.Object);
mockCommandContext.SetupGet(m => m.MetricEvents).Returns(mockMetricEvents.Object);

var mockBreakerExceptionHandler = new Mock<IBreakerExceptionHandler>(MockBehavior.Strict);
mockBreakerExceptionHandler.Setup(m => m.IsExceptionIgnored(It.IsAny<Type>())).Returns(false);

var command = new NoOpCommand();
var invoker = new BreakerInvoker(mockCommandContext.Object);
var invoker = new BreakerInvoker(mockCommandContext.Object, mockBreakerExceptionHandler.Object);

Assert.Throws<CircuitBreakerRejectedException>(() => invoker.ExecuteWithBreaker(command, CancellationToken.None));

Expand All @@ -126,8 +139,11 @@ public void WhenSuccessful_FiresBreakerSuccessCountMetricEvent()
mockCommandContext.Setup(m => m.GetCircuitBreaker(It.IsAny<GroupKey>())).Returns(mockBreaker.Object);
mockCommandContext.SetupGet(m => m.MetricEvents).Returns(mockMetricEvents.Object);

var mockBreakerExceptionHandler = new Mock<IBreakerExceptionHandler>(MockBehavior.Strict);
mockBreakerExceptionHandler.Setup(m => m.IsExceptionIgnored(It.IsAny<Type>())).Returns(false);

var command = new NoOpFailingCommand();
var invoker = new BreakerInvoker(mockCommandContext.Object);
var invoker = new BreakerInvoker(mockCommandContext.Object, mockBreakerExceptionHandler.Object);

Assert.Throws<ExpectedTestException>(() => invoker.ExecuteWithBreaker(command, CancellationToken.None));

Expand All @@ -149,8 +165,11 @@ public void WhenFailed_FiresBreakerFailureCountMetricEvent()
mockCommandContext.Setup(m => m.GetCircuitBreaker(It.IsAny<GroupKey>())).Returns(mockBreaker.Object);
mockCommandContext.SetupGet(m => m.MetricEvents).Returns(mockMetricEvents.Object);

var mockBreakerExceptionHandler = new Mock<IBreakerExceptionHandler>(MockBehavior.Strict);
mockBreakerExceptionHandler.Setup(m => m.IsExceptionIgnored(It.IsAny<Type>())).Returns(false);

var command = new NoOpCommand(); // Should be successful.
var invoker = new BreakerInvoker(mockCommandContext.Object);
var invoker = new BreakerInvoker(mockCommandContext.Object, mockBreakerExceptionHandler.Object);

invoker.ExecuteWithBreaker(command, CancellationToken.None);

Expand Down
11 changes: 9 additions & 2 deletions Hudl.Mjolnir.Tests/Command/BulkheadInvokerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Threading.Tasks;
using Moq;
using Xunit;
using Hudl.Mjolnir.Breaker;

namespace Hudl.Mjolnir.Tests.Command
{
Expand All @@ -34,9 +35,12 @@ public void CallsTryEnterAndReleaseOnTheSameBulkheadDuringConfigChange()
var mockConfig = new Mock<IMjolnirConfig>(MockBehavior.Strict);
mockConfig.Setup(m => m.GetConfig("mjolnir.useCircuitBreakers", It.IsAny<bool>())).Returns(true);

var mockBreakerExceptionHandler = new Mock<IBreakerExceptionHandler>(MockBehavior.Strict);
mockBreakerExceptionHandler.Setup(m => m.IsExceptionIgnored(It.IsAny<Type>())).Returns(false);

// Use a real breaker invoker instead of a mocked one so that we actually
// invoke the command (to change the config).
var breakerInvoker = new BreakerInvoker(context);
var breakerInvoker = new BreakerInvoker(context, mockBreakerExceptionHandler.Object);
var command = new ChangeBulkheadLimitAsyncCommand(key, bulkheadConfig, 15); // Limit needs to be different from default.

// This is the bulkhead that should be used for both TryEnter and Release.
Expand Down Expand Up @@ -288,9 +292,12 @@ public void CallsTryEnterAndReleaseOnTheSameBulkheadDuringConfigChange()
var mockConfig = new Mock<IMjolnirConfig>(MockBehavior.Strict);
mockConfig.Setup(m => m.GetConfig("mjolnir.useCircuitBreakers", It.IsAny<bool>())).Returns(true);

var mockBreakerExceptionHandler = new Mock<IBreakerExceptionHandler>(MockBehavior.Strict);
mockBreakerExceptionHandler.Setup(m => m.IsExceptionIgnored(It.IsAny<Type>())).Returns(false);

// Use a real breaker invoker instead of a mocked one so that we actually
// invoke the command (to change the config).
var breakerInvoker = new BreakerInvoker(context);
var breakerInvoker = new BreakerInvoker(context, mockBreakerExceptionHandler.Object);
var command = new ChangeBulkheadLimitSyncCommand(key, bulkheadConfig, 15); // Limit needs to be different from default.

// This is the bulkhead that should be used for both TryEnter and Release.
Expand Down

0 comments on commit e787e52

Please sign in to comment.