public async Task InvokeAsync_RejectedException() { var mockStats = new Mock <IStats>(); var mockBreaker = new Mock <ICircuitBreaker>(); mockBreaker.Setup(m => m.IsAllowing()).Returns(false); // Will have been set by TestFixture constructor. Assert.True(new ConfigurableValue <bool>("mjolnir.useCircuitBreakers").Value); var command = new SuccessfulEchoCommandWithoutFallback("Test") { Stats = mockStats.Object, CircuitBreaker = mockBreaker.Object, }; try { await command.InvokeAsync(); } catch (CommandFailedException e) { Assert.True(e.GetBaseException() is CircuitBreakerRejectedException); mockStats.Verify(m => m.Elapsed("mjolnir command test.SuccessfulEchoCommandWithoutFallback total", "Rejected", It.IsAny <TimeSpan>()), Times.Once); mockStats.Verify(m => m.Elapsed("mjolnir command test.SuccessfulEchoCommandWithoutFallback execute", "Rejected", It.IsAny <TimeSpan>()), Times.Once); return; // Expected. } AssertX.FailExpectedException(); }
public async Task InvokeAsync_ThreadPoolRejects_NotCountedByCircuitBreakerMetrics() { var exception = new IsolationThreadPoolRejectedException(); var pool = new RejectingIsolationThreadPool(exception); var mockMetrics = new Mock <ICommandMetrics>(); var mockBreaker = new Mock <ICircuitBreaker>(); mockBreaker.Setup(m => m.IsAllowing()).Returns(true); mockBreaker.SetupGet(m => m.Metrics).Returns(mockMetrics.Object); var command = new SuccessfulEchoCommandWithoutFallback(new { }) { CircuitBreaker = mockBreaker.Object, ThreadPool = pool, }; try { await command.InvokeAsync(); } catch (CommandFailedException e) { Assert.True(e.InnerException is IsolationThreadPoolRejectedException); mockMetrics.Verify(m => m.MarkCommandFailure(), Times.Never); mockMetrics.Verify(m => m.MarkCommandSuccess(), Times.Never); return; // Expected. } AssertX.FailExpectedException(); }
public async Task InvokeAsync_WhenCalledTwiceForTheSameInstance_ThrowsException() { var command = new SuccessfulEchoCommandWithoutFallback(new { }); await command.InvokeAsync(); try { await command.InvokeAsync(); // Should throw. } catch (InvalidOperationException e) { Assert.Equal("A command instance may only be invoked once", e.Message); return; // Expected } AssertX.FailExpectedException(); }
public void InvokeAsync_WhenUsingDotResult_DoesntDeadlock() { var expected = new { }; var command = new SuccessfulEchoCommandWithoutFallback(expected); var result = command.InvokeAsync().Result; // Will deadlock if we don't .ConfigureAwait(false) when awaiting. Assert.Equal(expected, result); }
public async Task InvokeAsync_WhenBreakerNotAllowing_ThrowsException() { var mockBreaker = CreateMockBreaker(false); var command = new SuccessfulEchoCommandWithoutFallback(null) { CircuitBreaker = mockBreaker.Object, }; var e = await Assert.ThrowsAsync<CommandRejectedException>(() => command.InvokeAsync()); Assert.True(e.InnerException is CircuitBreakerRejectedException); }
public async Task InvokeAsync_WhenCommandSuccessful_MarksBreakerSuccess() { var mockBreaker = CreateMockBreaker(true); var command = new SuccessfulEchoCommandWithoutFallback(null) { CircuitBreaker = mockBreaker.Object, }; await command.InvokeAsync(); mockBreaker.Verify(m => m.MarkSuccess(It.IsAny <long>()), Times.Once); }
public async Task InvokeAsync_SuccessAndFallbackNotImplemented() { var mockStats = new Mock <IStats>(); var command = new SuccessfulEchoCommandWithoutFallback("foo") { Stats = mockStats.Object, }; await command.InvokeAsync(); mockStats.Verify(m => m.Elapsed(It.IsRegex(".*fallback.*"), It.IsAny <string>(), It.IsAny <TimeSpan>()), Times.Never); }
public async Task InvokeAsync_WhenCommandSuccessful_MarksBreakerSuccess() { var mockBreaker = CreateMockBreaker(true); var command = new SuccessfulEchoCommandWithoutFallback(null) { CircuitBreaker = mockBreaker.Object, }; await command.InvokeAsync(); mockBreaker.Verify(m => m.MarkSuccess(It.IsAny<long>()), Times.Once); }
public async Task InvokeAsync_WhenCommandSuccessful_MarksMetricsCommandSuccess() { var mockMetrics = new Mock <ICommandMetrics>(); var mockBreaker = CreateMockBreaker(true, mockMetrics); var command = new SuccessfulEchoCommandWithoutFallback(null) { CircuitBreaker = mockBreaker.Object, }; await command.InvokeAsync(); mockMetrics.Verify(m => m.MarkCommandSuccess(), Times.Once); }
public async Task InvokeAsync_WhenCommandSuccessful_MarksMetricsCommandSuccess() { var mockMetrics = new Mock<ICommandMetrics>(); var mockBreaker = CreateMockBreaker(true, mockMetrics); var command = new SuccessfulEchoCommandWithoutFallback(null) { CircuitBreaker = mockBreaker.Object, }; await command.InvokeAsync(); mockMetrics.Verify(m => m.MarkCommandSuccess(), Times.Once); }
public async Task InvokeAsync_WhenSuccessful_ReturnsCommandResult() { var expected = DateTime.UtcNow.Ticks; var mockBreaker = CreateMockBreaker(true); var command = new SuccessfulEchoCommandWithoutFallback(expected) { CircuitBreaker = mockBreaker.Object, }; var result = await command.InvokeAsync(); Assert.Equal(expected, result); }
public async Task InvokeAsync_WhenBreakerNotAllowing_ThrowsException() { var mockBreaker = CreateMockBreaker(false); var command = new SuccessfulEchoCommandWithoutFallback(null) { CircuitBreaker = mockBreaker.Object, }; try { await command.InvokeAsync(); } catch (CommandFailedException e) { Assert.True(e.InnerException is CircuitBreakerRejectedException); return; // Expected. } AssertX.FailExpectedException(); }
public async Task InvokeAsync_ThreadPoolRejects_ThrowsCommandFailedExceptionWithRejectedStatusAndInnerException() { var exception = new IsolationThreadPoolRejectedException(); var pool = new RejectingIsolationThreadPool(exception); // Had a tough time getting It.IsAny<Func<Task<object>>> to work with a mock pool, so I just stubbed one here. var command = new SuccessfulEchoCommandWithoutFallback(new {}) { ThreadPool = pool, }; try { await command.InvokeAsync(); } catch (CommandFailedException e) { Assert.Equal(CommandCompletionStatus.Rejected, e.Status); Assert.Equal(exception, e.InnerException); return; } AssertX.FailExpectedException(); }
public async Task InvokeAsync_RejectedException() { var mockStats = new Mock<IStats>(); var mockBreaker = new Mock<ICircuitBreaker>(); mockBreaker.Setup(m => m.IsAllowing()).Returns(false); // Will have been set by TestFixture constructor. Assert.True(new ConfigurableValue<bool>("mjolnir.useCircuitBreakers").Value); var command = new SuccessfulEchoCommandWithoutFallback("Test") { Stats = mockStats.Object, CircuitBreaker = mockBreaker.Object, }; try { await command.InvokeAsync(); } catch (CommandFailedException e) { Assert.True(e.GetBaseException() is CircuitBreakerRejectedException); mockStats.Verify(m => m.Elapsed("mjolnir command test.SuccessfulEchoCommandWithoutFallback total", "Rejected", It.IsAny<TimeSpan>()), Times.Once); mockStats.Verify(m => m.Elapsed("mjolnir command test.SuccessfulEchoCommandWithoutFallback execute", "Rejected", It.IsAny<TimeSpan>()), Times.Once); return; // Expected. } AssertX.FailExpectedException(); }
public async Task InvokeAsync_SuccessAndFallbackNotImplemented() { var mockStats = new Mock<IStats>(); var command = new SuccessfulEchoCommandWithoutFallback("foo") { Stats = mockStats.Object, }; await command.InvokeAsync(); mockStats.Verify(m => m.Elapsed(It.IsRegex(".*fallback.*"), It.IsAny<string>(), It.IsAny<TimeSpan>()), Times.Never); }