public async Task RetrySetRetryPolicyVerifyInternalsSuccess() { // arrange var innerHandlerMock = Substitute.For <IDelegatingHandler>(); var contextMock = Substitute.For <PipelineContext>(); contextMock.ConnectionStatusChangesHandler = new ConnectionStatusChangesHandler(delegate(ConnectionStatus status, ConnectionStatusChangeReason reason) { }); var sut = new RetryDelegatingHandler(contextMock, innerHandlerMock); var retryPolicy = new TestRetryPolicy(); sut.SetRetryPolicy(retryPolicy); int innerHandlerCallCounter = 0; innerHandlerMock.OpenAsync(Arg.Any <CancellationToken>()).Returns(t => { innerHandlerCallCounter++; throw new IotHubCommunicationException(); }); // act and assert await sut.OpenAsync(CancellationToken.None).ExpectedAsync <IotHubCommunicationException>().ConfigureAwait(false); innerHandlerCallCounter.Should().Be(2); retryPolicy.Counter.Should().Be(2); var noretry = new NoRetry(); sut.SetRetryPolicy(noretry); await sut.OpenAsync(CancellationToken.None).ExpectedAsync <IotHubCommunicationException>().ConfigureAwait(false); innerHandlerCallCounter.Should().Be(3); retryPolicy.Counter.Should().Be(2); }
public async Task OpenAsyncTwoCallersOnlyOneOpenCalled() { var contextMock = Substitute.For <PipelineContext>(); contextMock.ConnectionStatusChangesHandler = new ConnectionStatusChangesHandler(delegate(ConnectionStatus status, ConnectionStatusChangeReason reason) { }); var tcs = new TaskCompletionSource <int>(); var innerHandlerMock = Substitute.For <IDelegatingHandler>(); int callCounter = 0; innerHandlerMock.OpenAsync(Arg.Any <CancellationToken>()).Returns(t => { callCounter++; return(tcs.Task); }); innerHandlerMock.WaitForTransportClosedAsync().Returns(Task.Delay(TimeSpan.FromSeconds(10))); var sut = new RetryDelegatingHandler(contextMock, innerHandlerMock); var cancellationToken = new CancellationToken(); Task firstOpen = sut.OpenAsync(cancellationToken); Task secondOpen = sut.OpenAsync(cancellationToken); tcs.SetResult(0); await Task.WhenAll(firstOpen, secondOpen).ConfigureAwait(false); Assert.AreEqual(1, callCounter); }
public async Task RetrySetRetryPolicyVerifyInternalsSuccess() { var innerHandlerMock = Substitute.For <IDelegatingHandler>(); var contextMock = Substitute.For <IPipelineContext>(); var sut = new RetryDelegatingHandler(contextMock, innerHandlerMock); var retryPolicy = new TestRetryPolicy(); sut.SetRetryPolicy(retryPolicy); int innerHandlerCallCounter = 0; innerHandlerMock.OpenAsync(Arg.Any <CancellationToken>()).Returns(t => { innerHandlerCallCounter++; throw new IotHubCommunicationException(); }); await sut.OpenAsync(CancellationToken.None).ExpectedAsync <IotHubCommunicationException>().ConfigureAwait(false); Assert.AreEqual(2, innerHandlerCallCounter); Assert.AreEqual(2, retryPolicy.Counter); var noretry = new NoRetry(); sut.SetRetryPolicy(noretry); await sut.OpenAsync(CancellationToken.None).ExpectedAsync <IotHubCommunicationException>().ConfigureAwait(false); Assert.AreEqual(3, innerHandlerCallCounter); Assert.AreEqual(2, retryPolicy.Counter); }
public async Task OpenAsyncInnerFailedSutIsOpenAndCanBeReopen() { var contextMock = Substitute.For <PipelineContext>(); contextMock.ConnectionStatusChangesHandler = new ConnectionStatusChangesHandler(delegate(ConnectionStatus status, ConnectionStatusChangeReason reason) { }); var innerHandlerMock = Substitute.For <IDelegatingHandler>(); bool shouldThrow = true; innerHandlerMock.OpenAsync(Arg.Any <CancellationToken>()).Returns(ci => { if (shouldThrow) { throw new IOException(); } else { return(TaskHelpers.CompletedTask);; } }); var sut = new RetryDelegatingHandler(contextMock, innerHandlerMock); var cancellationToken = new CancellationToken(); await sut.OpenAsync(cancellationToken).ExpectedAsync <IOException>().ConfigureAwait(false); shouldThrow = false; await sut.OpenAsync(cancellationToken).ConfigureAwait(false); }
public async Task RetryTransientErrorOccuredRetried() { int callCounter = 0; var contextMock = Substitute.For <IPipelineContext>(); var innerHandlerMock = Substitute.For <IDelegatingHandler>(); innerHandlerMock.OpenAsync(Arg.Any <CancellationToken>()).Returns(t => { callCounter++; if (callCounter == 1) { throw new IotHubException("Test transient exception", isTransient: true); } return(Task.CompletedTask); }); var sut = new RetryDelegatingHandler(contextMock, innerHandlerMock); var cancellationToken = new CancellationToken(); await sut.OpenAsync(cancellationToken).ConfigureAwait(false); Assert.AreEqual(2, callCounter); }
public async Task Retry_CloseAsyncSuccessDisposesHandler_Throws() { var contextMock = Substitute.For <IPipelineContext>(); var innerHandlerMock = Substitute.For <IDelegatingHandler>(); var cancellationToken = new CancellationToken(); innerHandlerMock.OpenAsync(cancellationToken).Returns(t => TaskHelpers.CompletedTask); innerHandlerMock.CloseAsync(cancellationToken).Returns(t => TaskHelpers.CompletedTask); var sut = new RetryDelegatingHandler(contextMock, innerHandlerMock); await sut.OpenAsync(cancellationToken).ConfigureAwait(false); await sut.CloseAsync(cancellationToken).ConfigureAwait(false); await((Func <Task>)(() => sut.OpenAsync(cancellationToken))).ExpectedAsync <ObjectDisposedException>().ConfigureAwait(false); }
public async Task Retry_NonTransientErrorThrown_Throws() { int callCounter = 0; var contextMock = Substitute.For <IPipelineContext>(); var innerHandlerMock = Substitute.For <IDelegatingHandler>(); innerHandlerMock.OpenAsync(true, Arg.Any <CancellationToken>()).Returns(t => { callCounter++; if (callCounter == 1) { throw new InvalidOperationException(""); } return(TaskConstants.Completed); }); var sut = new RetryDelegatingHandler(contextMock); sut.ContinuationFactory = c => innerHandlerMock; var cancellationToken = new CancellationToken(); await sut.OpenAsync(true, cancellationToken).ExpectedAsync <InvalidOperationException>(); Assert.AreEqual(callCounter, 1); }
public async Task Retry_TransientErrorOccured_Retried() { int callCounter = 0; var contextMock = Substitute.For <IPipelineContext>(); var innerHandlerMock = Substitute.For <IDelegatingHandler>(); innerHandlerMock.OpenAsync(true, Arg.Any <CancellationToken>()).Returns(t => { callCounter++; if (callCounter == 1) { throw new IotHubClientTransientException(""); } return(TaskConstants.Completed); }); var sut = new RetryDelegatingHandler(contextMock); sut.ContinuationFactory = c => innerHandlerMock; var cancellationToken = new CancellationToken(); await sut.OpenAsync(true, cancellationToken); Assert.AreEqual(2, callCounter); }
public async Task DeviceNotFoundExceptionReturnsDeviceDisabledStatus() { // arrange var contextMock = Substitute.For <PipelineContext>(); var innerHandlerMock = Substitute.For <IDelegatingHandler>(); innerHandlerMock.OpenAsync(Arg.Any <CancellationToken>()).Returns(t => throw new DeviceNotFoundException()); ConnectionStatus? status = null; ConnectionStatusChangeReason? statusChangeReason = null; ConnectionStatusChangesHandler statusChangeHandler = (s, r) => { status = s; statusChangeReason = r; }; contextMock.ConnectionStatusChangesHandler = statusChangeHandler; var sut = new RetryDelegatingHandler(contextMock, innerHandlerMock); // act await((Func <Task>)(() => sut .OpenAsync(CancellationToken.None))) .ExpectedAsync <DeviceNotFoundException>() .ConfigureAwait(false); // assert status.Should().Be(ConnectionStatus.Disconnected); statusChangeReason.Should().Be(ConnectionStatusChangeReason.Device_Disabled); }
public async Task DeviceNotFoundExceptionReturnsDeviceDisabledStatus() { var contextMock = Substitute.For <IPipelineContext>(); var innerHandlerMock = Substitute.For <IDelegatingHandler>(); innerHandlerMock.OpenAsync(Arg.Any <CancellationToken>()).Returns(t => throw new DeviceNotFoundException()); ConnectionStatus? status = null; ConnectionStatusChangeReason? statusChangeReason = null; ConnectionStatusChangesHandler statusChangeHandler = (s, r) => { status = s; statusChangeReason = r; }; contextMock.Get <ConnectionStatusChangesHandler>().Returns(statusChangeHandler); var cancellationToken = new CancellationToken(); var testee = new RetryDelegatingHandler(contextMock, innerHandlerMock); await((Func <Task>)(() => testee.OpenAsync(cancellationToken))).ExpectedAsync <DeviceNotFoundException>().ConfigureAwait(false); Assert.AreEqual(ConnectionStatus.Disconnected, status); Assert.AreEqual(ConnectionStatusChangeReason.Device_Disabled, statusChangeReason); }
public async Task RetryNonTransientErrorThrownThrows() { // arrange int callCounter = 0; var contextMock = Substitute.For <PipelineContext>(); contextMock.ConnectionStatusChangesHandler = new ConnectionStatusChangesHandler(delegate(ConnectionStatus status, ConnectionStatusChangeReason reason) { }); var innerHandlerMock = Substitute.For <IDelegatingHandler>(); innerHandlerMock .OpenAsync(Arg.Any <CancellationToken>()) .Returns(t => { if (++callCounter == 1) { throw new InvalidOperationException(""); } return(TaskHelpers.CompletedTask); }); var sut = new RetryDelegatingHandler(contextMock, innerHandlerMock); // arrange await sut.OpenAsync(CancellationToken.None).ExpectedAsync <InvalidOperationException>().ConfigureAwait(false); // act callCounter.Should().Be(1); }
public async Task RetryDelegatingHandler_OpenAsyncRetries() { // arrange int callCounter = 0; var ct = CancellationToken.None; PipelineContext contextMock = Substitute.For <PipelineContext>(); contextMock.ConnectionStatusChangesHandler = new ConnectionStatusChangesHandler(delegate(ConnectionStatus status, ConnectionStatusChangeReason reason) { }); IDelegatingHandler innerHandlerMock = Substitute.For <IDelegatingHandler>(); innerHandlerMock .OpenAsync(ct) .Returns(t => { return(++callCounter == 1 ? throw new IotHubException("Test transient exception", isTransient: true) : TaskHelpers.CompletedTask); }); innerHandlerMock.WaitForTransportClosedAsync().Returns(Task.Delay(TimeSpan.FromSeconds(10))); var retryDelegatingHandler = new RetryDelegatingHandler(contextMock, innerHandlerMock); // act await retryDelegatingHandler.OpenAsync(ct).ConfigureAwait(false); // assert callCounter.Should().Be(2); }
public async Task OpenAsyncInnerCancelledSutIsOpenAndCanBeReopen() { var contextMock = Substitute.For <IPipelineContext>(); var tcs = new TaskCompletionSource(); tcs.SetCanceled(); var innerHandlerMock = Substitute.For <IDelegatingHandler>(); innerHandlerMock.OpenAsync(Arg.Any <CancellationToken>()).Returns(tcs.Task); var sut = new RetryDelegatingHandler(contextMock, innerHandlerMock); var cancellationToken = new CancellationToken(); await sut.OpenAsync(cancellationToken).ExpectedAsync <TaskCanceledException>().ConfigureAwait(false); innerHandlerMock.OpenAsync(Arg.Any <CancellationToken>()).Returns(t => Task.CompletedTask); await sut.OpenAsync(cancellationToken).ConfigureAwait(false); }
public async Task OpenAsyncInnerCompletedSubjIsOpen() { var contextMock = Substitute.For <IPipelineContext>(); var innerHandlerMock = Substitute.For <IDelegatingHandler>(); innerHandlerMock.OpenAsync(Arg.Any <CancellationToken>()).Returns(t => Task.CompletedTask); var cancellationToken = new CancellationToken(); var sut = new RetryDelegatingHandler(contextMock, innerHandlerMock); await sut.OpenAsync(cancellationToken).ConfigureAwait(false); }
public async Task Retry_CancellationTokenCanceled_Open() { var innerHandlerMock = Substitute.For <IDelegatingHandler>(); innerHandlerMock.OpenAsync(Arg.Any <bool>(), Arg.Any <CancellationToken>()).Returns(TaskConstants.Completed); var sut = new RetryDelegatingHandler(innerHandlerMock); var cancellationTokenSource = new CancellationTokenSource(); cancellationTokenSource.Cancel(); await sut.OpenAsync(Arg.Any <bool>(), cancellationTokenSource.Token).ExpectedAsync <TaskCanceledException>(); }
public async Task OpenAsyncInnerCompletedSubjIsOpen() { var contextMock = Substitute.For <PipelineContext>(); contextMock.ConnectionStatusChangesHandler = new ConnectionStatusChangesHandler(delegate(ConnectionStatus status, ConnectionStatusChangeReason reason) { }); var innerHandlerMock = Substitute.For <IDelegatingHandler>(); innerHandlerMock.OpenAsync(Arg.Any <CancellationToken>()).Returns(t => TaskHelpers.CompletedTask); var cancellationToken = new CancellationToken(); var sut = new RetryDelegatingHandler(contextMock, innerHandlerMock); await sut.OpenAsync(cancellationToken).ConfigureAwait(false); }
public async Task RetryCancellationTokenCanceledOpen() { var innerHandlerMock = Substitute.For <IDelegatingHandler>(); var cancellationTokenSource = new CancellationTokenSource(); cancellationTokenSource.Cancel(); innerHandlerMock.OpenAsync(Arg.Any <CancellationToken>()).Returns(TaskHelpers.CompletedTask); var contextMock = Substitute.For <IPipelineContext>(); var sut = new RetryDelegatingHandler(contextMock, innerHandlerMock); await sut.OpenAsync(cancellationTokenSource.Token).ExpectedAsync <TaskCanceledException>().ConfigureAwait(false); }
public async Task Retry_TransientErrorThrownAfterNumberOfRetries_Throws() { var innerHandlerMock = Substitute.For <IDelegatingHandler>(); innerHandlerMock.OpenAsync(Arg.Is(true)).Returns(t => { throw new IotHubClientTransientException(""); }); var sut = new RetryDelegatingHandler(innerHandlerMock); await sut.OpenAsync(true).ExpectedAsync <IotHubClientTransientException>(); }
public async Task OpenAsyncTwoCallersOnlyOneOpenCalled() { var contextMock = Substitute.For <IPipelineContext>(); var tcs = new TaskCompletionSource(); var innerHandlerMock = Substitute.For <IDelegatingHandler>(); int callCounter = 0; innerHandlerMock.OpenAsync(Arg.Any <CancellationToken>()).Returns(t => { callCounter++; return(tcs.Task); }); var sut = new RetryDelegatingHandler(contextMock, innerHandlerMock); var cancellationToken = new CancellationToken(); Task firstOpen = sut.OpenAsync(cancellationToken); Task secondOpen = sut.OpenAsync(cancellationToken); tcs.Complete(); await Task.WhenAll(firstOpen, secondOpen).ConfigureAwait(false); Assert.AreEqual(1, callCounter); }
public async Task RetryCancellationTokenCanceledOpen() { var innerHandlerMock = Substitute.For <IDelegatingHandler>(); var cancellationTokenSource = new CancellationTokenSource(); cancellationTokenSource.Cancel(); innerHandlerMock.OpenAsync(Arg.Any <bool>(), Arg.Any <CancellationToken>()).Returns(TaskConstants.Completed); var contextMock = Substitute.For <IPipelineContext>(); var sut = new RetryDelegatingHandler(contextMock); sut.ContinuationFactory = c => innerHandlerMock; await sut.OpenAsync(true, cancellationTokenSource.Token).ExpectedAsync <TaskCanceledException>().ConfigureAwait(false); }
public async Task Retry_TransientErrorThrownAfterNumberOfRetries_Throws() { var contextMock = Substitute.For <IPipelineContext>(); var innerHandlerMock = Substitute.For <IDelegatingHandler>(); innerHandlerMock.OpenAsync(Arg.Is(true), Arg.Any <CancellationToken>()).Returns(t => { throw new IotHubClientTransientException(""); }); var sut = new RetryDelegatingHandler(contextMock); sut.ContinuationFactory = c => innerHandlerMock; var cancellationToken = new CancellationToken(); await sut.OpenAsync(true, cancellationToken).ExpectedAsync <IotHubClientTransientException>(); }
public async Task RetryTransientErrorThrownAfterNumberOfRetriesThrows() { var contextMock = Substitute.For <IPipelineContext>(); var innerHandlerMock = Substitute.For <IDelegatingHandler>(); innerHandlerMock.OpenAsync(Arg.Any <CancellationToken>()).Returns(t => { throw new IotHubException(TestExceptionMessage, isTransient: true); }); var sut = new RetryDelegatingHandler(contextMock, innerHandlerMock); using (var cts = new CancellationTokenSource(100)) { IotHubException exception = await sut.OpenAsync(cts.Token).ExpectedAsync <IotHubException>().ConfigureAwait(false); Assert.AreEqual(TestExceptionMessage, exception.Message); } }
public async Task Retry_TransientErrorOccured_Retried() { int callCounter = 0; var innerHandlerMock = Substitute.For <IDelegatingHandler>(); innerHandlerMock.OpenAsync(true).Returns(t => { callCounter++; if (callCounter == 1) { throw new IotHubClientTransientException(""); } return(TaskConstants.Completed); }); var sut = new RetryDelegatingHandler(innerHandlerMock); await sut.OpenAsync(true); Assert.AreEqual(2, callCounter); }
public async Task Retry_NonTransientErrorThrown_Throws() { int callCounter = 0; var innerHandlerMock = Substitute.For <IDelegatingHandler>(); innerHandlerMock.OpenAsync(true).Returns(t => { callCounter++; if (callCounter == 1) { throw new InvalidOperationException(""); } return(TaskConstants.Completed); }); var sut = new RetryDelegatingHandler(innerHandlerMock); await sut.OpenAsync(true).ExpectedAsync <InvalidOperationException>(); Assert.AreEqual(callCounter, 1); }
public async Task RetryNonTransientErrorThrownThrows() { int callCounter = 0; var contextMock = Substitute.For <IPipelineContext>(); var innerHandlerMock = Substitute.For <IDelegatingHandler>(); innerHandlerMock.OpenAsync(Arg.Any <CancellationToken>()).Returns(t => { callCounter++; if (callCounter == 1) { throw new InvalidOperationException(""); } return(TaskHelpers.CompletedTask);; }); var sut = new RetryDelegatingHandler(contextMock, innerHandlerMock); var cancellationToken = new CancellationToken(); await sut.OpenAsync(cancellationToken).ExpectedAsync <InvalidOperationException>().ConfigureAwait(false); Assert.AreEqual(callCounter, 1); }
public async Task RetryDelegatingHandler_OpenAsyncRetries() { // arrange int callCounter = 0; IPipelineContext contextMock = Substitute.For <IPipelineContext>(); IDelegatingHandler innerHandlerMock = Substitute.For <IDelegatingHandler>(); innerHandlerMock.OpenAsync(Arg.Any <CancellationToken>()).Returns(t => { return(++callCounter == 1 ? throw new IotHubException("Test transient exception", isTransient: true) : TaskHelpers.CompletedTask); }); innerHandlerMock.WaitForTransportClosedAsync().Returns(Task.Delay(TimeSpan.FromSeconds(10))); var retryDelegatingHandler = new RetryDelegatingHandler(contextMock, innerHandlerMock); // act await retryDelegatingHandler.OpenAsync(new CancellationToken()).ConfigureAwait(false); // assert Assert.AreEqual(2, callCounter); }
public async Task RetryTransientErrorThrownAfterNumberOfRetriesThrows() { // arrange using var cts = new CancellationTokenSource(100); var contextMock = Substitute.For <PipelineContext>(); contextMock.ConnectionStatusChangesHandler = new ConnectionStatusChangesHandler(delegate(ConnectionStatus status, ConnectionStatusChangeReason reason) { }); var innerHandlerMock = Substitute.For <IDelegatingHandler>(); innerHandlerMock .OpenAsync(cts.Token) .Returns(t => throw new IotHubException(TestExceptionMessage, isTransient: true)); var sut = new RetryDelegatingHandler(contextMock, innerHandlerMock); IotHubException exception = await sut .OpenAsync(cts.Token) .ExpectedAsync <IotHubException>() .ConfigureAwait(false); // act // assert exception.Message.Should().Be(TestExceptionMessage); }