public async Task SetsExecutionTimeOnCommandWhenInvokedWithoutBreakerAndCommandFails() { // Arrange var key = AnyString; var groupKey = GroupKey.Named(key); var mockMetricEvents = new Mock <IMetricEvents>(); var mockBreakerInvoker = new Mock <IBreakerInvoker>(); var mockBulkhead = new Mock <ISemaphoreBulkhead>(); mockBulkhead.Setup(m => m.TryEnter()).Returns(true); mockBulkhead.SetupGet(m => m.Name).Returns(key); var mockBulkheadFactory = new Mock <IBulkheadFactory>(MockBehavior.Strict); mockBulkheadFactory.Setup(m => m.GetBulkhead(groupKey)).Returns(mockBulkhead.Object); var mockConfig = new MjolnirConfiguration { UseCircuitBreakers = false }; // Pass false for useCircuitBreakers to bypass the breaker; we're testing that here. var invoker = new BulkheadInvoker(mockBreakerInvoker.Object, mockBulkheadFactory.Object, mockMetricEvents.Object, mockConfig); var command = new ConfigurableKeyThrowingAsyncCommand(key); // Act + Assert await Assert.ThrowsAsync <ExpectedTestException>(() => invoker.ExecuteWithBulkheadAsync(command, CancellationToken.None)); Assert.True(command.ExecutionTimeMillis > 0); }
public async Task DoesntSetExecutionTimeOnCommandWhenInvokedWithBreakerAndCommandSucceeds() { // If we execute on the breaker, the breaker should set the execution time instead // of the bulkhead invoker. // Arrange var key = AnyString; var groupKey = GroupKey.Named(key); var mockMetricEvents = new Mock <IMetricEvents>(); var mockBreakerInvoker = new Mock <IBreakerInvoker>(); var mockBulkhead = new Mock <ISemaphoreBulkhead>(); mockBulkhead.Setup(m => m.TryEnter()).Returns(true); mockBulkhead.SetupGet(m => m.Name).Returns(key); var mockBulkheadFactory = new Mock <IBulkheadFactory>(MockBehavior.Strict); mockBulkheadFactory.Setup(m => m.GetBulkhead(groupKey)).Returns(mockBulkhead.Object); var command = new ConfigurableKeyThrowingAsyncCommand(key); mockBreakerInvoker.Setup(m => m.ExecuteWithBreakerAsync(command, It.IsAny <CancellationToken>())) .Returns(Task.FromResult(true)); var mockConfig = new MjolnirConfiguration { UseCircuitBreakers = true }; // Pass true for useCircuitBreakers, we need to test that behavior here. var invoker = new BulkheadInvoker(mockBreakerInvoker.Object, mockBulkheadFactory.Object, mockMetricEvents.Object, mockConfig); // Act await invoker.ExecuteWithBulkheadAsync(command, CancellationToken.None); // Assert Assert.Equal(0, command.ExecutionTimeMillis); }
public async Task FiresMetricEventWhenEnteringAndLeavingBulkheadAndCommandFails() { // Arrange var key = AnyString; var groupKey = GroupKey.Named(key); var mockMetricEvents = new Mock <IMetricEvents>(); var mockBreakerInvoker = new Mock <IBreakerInvoker>(); var mockBulkhead = new Mock <ISemaphoreBulkhead>(); mockBulkhead.Setup(m => m.TryEnter()).Returns(true); mockBulkhead.SetupGet(m => m.Name).Returns(key); var mockBulkheadFactory = new Mock <IBulkheadFactory>(MockBehavior.Strict); mockBulkheadFactory.Setup(m => m.GetBulkhead(groupKey)).Returns(mockBulkhead.Object); var mockConfig = new MjolnirConfiguration { UseCircuitBreakers = false }; // The breaker invoker behavior doesn't matter here, we shouldn't get to the point // where we try to use it. Pass a "false" value for useCircuitBreakers to help // ensure that. var invoker = new BulkheadInvoker(mockBreakerInvoker.Object, mockBulkheadFactory.Object, mockMetricEvents.Object, mockConfig); var command = new ConfigurableKeyThrowingAsyncCommand(key); // Act + Assert await Assert.ThrowsAsync <ExpectedTestException>(() => invoker.ExecuteWithBulkheadAsync(command, CancellationToken.None)); mockMetricEvents.Verify(m => m.EnterBulkhead(key, command.Name)); mockMetricEvents.Verify(m => m.LeaveBulkhead(key, command.Name)); }