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_ThreadPoolRejects_InvokesFallback() { var exception = new IsolationThreadPoolRejectedException(); var pool = new RejectingIsolationThreadPool(exception); var command = new SuccessfulEchoCommandWithFallback(new { }) { ThreadPool = pool, }; await command.InvokeAsync(); // Won't throw because there's a successful fallback. Assert.True(command.FallbackCalled); }
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 RejectingIsolationThreadPool(IsolationThreadPoolRejectedException exceptionToThrow) { _exceptionToThrow = exceptionToThrow; }