public void SendAsync_NullRequest_ThrowsArgumentNullException() { var transport = new MockTransportHandler(); var handler = new MockHandler(transport); Assert.Throws <ArgumentNullException>(() => { Task t = handler.TestSendAsync(null, CancellationToken.None); }); }
public async Task TransportHandler_DoesNotCatch_For412(bool goThroughGateway) { MockTransportHandler transportHandler = await TransportHandlerRunScenario((int)HttpStatusCode.PreconditionFailed, goThroughGateway); Assert.IsFalse(transportHandler.ProcessMessagesAsyncThrew); Assert.IsTrue(transportHandler.SendAsyncCalls == 1); }
public void SendAsync_NullRequest_ThrowsArgumentNullException() { var transport = new MockTransportHandler(); var handler = new MockHandler(transport); Assert.Throws<ArgumentNullException>(() => { Task t = handler.TestSendAsync(null, CancellationToken.None); }); }
public async Task TransportHandler_DoesNotCatch_For429(bool goThroughGateway) { MockTransportHandler transportHandler = await TransportHandlerRunScenario((int)StatusCodes.TooManyRequests, goThroughGateway); Assert.IsFalse(transportHandler.ProcessMessagesAsyncThrew); Assert.IsTrue(transportHandler.SendAsyncCalls > 1); }
public async Task SendAsync_CallMethod_ProcessRequestAndProcessResponseCalled() { var transport = new MockTransportHandler(); var handler = new MockHandler(transport); await handler.TestSendAsync(new HttpRequestMessage(), CancellationToken.None); Assert.Equal(1, handler.ProcessRequestCount); Assert.Equal(1, handler.ProcessResponseCount); }
public async Task SendAsync_InnerHandlerReturnsNullResponse_ThrowInvalidOperationExceptionWithoutCallingProcessRequest() { var transport = new MockTransportHandler(() => { return null; }); var handler = new MockHandler(transport); await Assert.ThrowsAsync<InvalidOperationException>(() => handler.TestSendAsync(new HttpRequestMessage(), CancellationToken.None)); Assert.Equal(1, handler.ProcessRequestCount); Assert.Equal(0, handler.ProcessResponseCount); }
public async Task SendAsync_InnerHandlerThrows_ThrowWithoutCallingProcessRequest() { var transport = new MockTransportHandler(true); // Throw if Send/SendAsync() is called. var handler = new MockHandler(transport); await Assert.ThrowsAsync<MockException>(() => handler.TestSendAsync(new HttpRequestMessage(), CancellationToken.None)); Assert.Equal(1, handler.ProcessRequestCount); Assert.Equal(0, handler.ProcessResponseCount); }
public async Task SendAsync_InnerHandlerThrows_ThrowWithoutCallingProcessRequest() { var transport = new MockTransportHandler(true); // Throw if Send/SendAsync() is called. var handler = new MockHandler(transport); await Assert.ThrowsAsync <MockException>(() => handler.TestSendAsync(new HttpRequestMessage(), CancellationToken.None)); Assert.Equal(1, handler.ProcessRequestCount); Assert.Equal(0, handler.ProcessResponseCount); }
public async Task SendAsync_InnerHandlerReturnsNullResponse_ThrowInvalidOperationExceptionWithoutCallingProcessRequest() { var transport = new MockTransportHandler(() => { return(null); }); var handler = new MockHandler(transport); await Assert.ThrowsAsync <InvalidOperationException>(() => handler.TestSendAsync(new HttpRequestMessage(), CancellationToken.None)); Assert.Equal(1, handler.ProcessRequestCount); Assert.Equal(0, handler.ProcessResponseCount); }
public void Dispose_CallDispose_OverriddenDisposeMethodCalled() { var innerHandler = new MockTransportHandler(); var handler = new MockHandler(innerHandler); handler.Dispose(); Assert.Equal(1, handler.DisposeCount); Assert.Equal(1, innerHandler.DisposeCount); }
public async Task SendAsync_CallMethod_InnerHandlerSendAsyncIsCalled() { var transport = new MockTransportHandler(); var handler = new MockHandler(transport); await handler.TestSendAsync(new HttpRequestMessage(), CancellationToken.None); Assert.Equal(1, handler.SendAsyncCount); Assert.Equal(1, transport.SendAsyncCount); }
public async Task SendAsync_OperationCanceledWhileProcessResponseIsExecuted_TaskSetToIsCanceled() { var cts = new CancellationTokenSource(); var transport = new MockTransportHandler(); // ProcessResponse will cancel. var handler = new MockHandler(transport, false, () => { cts.Cancel(); cts.Token.ThrowIfCancellationRequested(); }); await Assert.ThrowsAsync <TaskCanceledException>(() => handler.TestSendAsync(new HttpRequestMessage(), cts.Token)); }
public async Task SendAsync_SetInnerHandlerAfterCallMethod_ThrowsInvalidOperationException() { var transport = new MockTransportHandler(); var handler = new MockHandler(transport); await handler.TestSendAsync(new HttpRequestMessage(), CancellationToken.None); Assert.Equal(1, handler.SendAsyncCount); Assert.Equal(1, transport.SendAsyncCount); Assert.Throws <InvalidOperationException>(() => handler.InnerHandler = transport); }
public void SendAsync_Disposed_Throws() { var transport = new MockTransportHandler(); var handler = new MockHandler(transport); handler.Dispose(); Assert.Throws <ObjectDisposedException>(() => { Task t = handler.TestSendAsync(new HttpRequestMessage(), CancellationToken.None); }); Assert.Throws <ObjectDisposedException>(() => handler.InnerHandler = new MockHandler()); Assert.Equal(transport, handler.InnerHandler); }
public async Task SendAsync_ProcessResponseThrows_TaskIsFaulted() { var transport = new MockTransportHandler(); // ProcessResponse() throws exception. var handler = new MockHandler(transport, false, () => { throw new MockException(); }); // Throwing an exception in ProcessResponse() will cause the Task to complete as 'faulted'. await Assert.ThrowsAsync <MockException>(() => handler.TestSendAsync(new HttpRequestMessage(), CancellationToken.None)); Assert.Equal(1, transport.SendAsyncCount); Assert.Equal(1, handler.ProcessRequestCount); Assert.Equal(1, handler.ProcessResponseCount); }
public async Task SendAsync_OperationCanceledWhileInnerHandlerIsWorking_TaskSetToIsCanceled() { var cts = new CancellationTokenSource(); // We simulate a cancellation happening while the inner handler was processing the request, by letting // the inner mock handler call Cancel() and behave like if another thread called cancel while it was // processing. var transport = new MockTransportHandler(cts); // inner handler will cancel. var handler = new MockHandler(transport); await Assert.ThrowsAsync <TaskCanceledException>(() => handler.TestSendAsync(new HttpRequestMessage(), cts.Token)); Assert.Equal(0, handler.ProcessResponseCount); }
/// <summary> /// Creates a CosmosClient with a mock TransportHandler that will capture and detect Exceptions happening inside ProcessChangesAsync. /// Since we want to be Exception-less, this will help detect if the Store Model is throwing or not. /// </summary> /// <param name="goThroughGateway">Whether or not to run the scenario using Gateway. If false, Direct will be used.</param> private static async Task <MockTransportHandler> TransportHandlerRunScenario(int responseStatusCode, bool goThroughGateway = true) { async Task <HttpResponseMessage> sendFunc(HttpRequestMessage httpRequest) { return(await Task.FromResult(new HttpResponseMessage((HttpStatusCode)responseStatusCode) { Content = new StringContent("{}"), RequestMessage = httpRequest })); } StoreResponse sendDirectFunc(TransportAddressUri uri, DocumentServiceRequest request) { return(new StoreResponse() { ResponseBody = Stream.Null, Status = responseStatusCode, Headers = new StoreResponseNameValueCollection() }); } // This is needed because in order to Mock a TransportClient we previously need an instance of CosmosClient using CosmosClient internalClient = MockCosmosUtil.CreateMockCosmosClient(); internalClient.DocumentClient.GatewayStoreModel = MockGatewayStoreModel(sendFunc); internalClient.DocumentClient.StoreModel = MockServerStoreModel(internalClient.DocumentClient.Session, sendDirectFunc); RetryHandler retryHandler = new RetryHandler(internalClient); MockTransportHandler transportHandler = new MockTransportHandler(internalClient); using CosmosClient client = MockCosmosUtil.CreateMockCosmosClient( (builder) => builder.AddCustomHandlers(retryHandler, transportHandler)); try { if (goThroughGateway) { DatabaseResponse response = await client.CreateDatabaseAsync("test"); } else { ItemResponse <dynamic> response = await client.GetContainer("test", "test").CreateItemAsync <dynamic>(item: new { id = "id" }, partitionKey: new Cosmos.PartitionKey("id")); } } catch (CosmosException) { // Swallow CosmosExceptions as the point is to test the TransportHandler } return(transportHandler); }
public async Task SendAsync_OperationCanceledWhileProcessRequestIsExecuted_TaskSetToIsCanceled() { var cts = new CancellationTokenSource(); var transport = new MockTransportHandler(); // ProcessRequest will cancel. var handler = new MockHandler(transport, true, () => { cts.Cancel(); cts.Token.ThrowIfCancellationRequested(); }); // Note that even ProcessMessage() is called on the same thread, we don't expect SendAsync() to throw. // SendAsync() must complete successfully, but the Task will be canceled. await Assert.ThrowsAsync <TaskCanceledException>(() => handler.TestSendAsync(new HttpRequestMessage(), cts.Token)); Assert.Equal(0, handler.ProcessResponseCount); }
public async Task SendAsync_ProcessResponseThrowsOperationCanceledExceptionNotBoundToCts_TaskSetToIsFaulted() { var cts = new CancellationTokenSource(); var transport = new MockTransportHandler(); // ProcessResponse will throw a random OperationCanceledException() not related to cts. We also cancel // the cts to make sure the code behaves correctly even if cts is canceled & an OperationCanceledException // was thrown. var handler = new MockHandler(transport, false, () => { cts.Cancel(); throw new OperationCanceledException("custom"); }); await Assert.ThrowsAsync <OperationCanceledException>(() => handler.TestSendAsync(new HttpRequestMessage(), cts.Token)); Assert.Equal(1, handler.ProcessResponseCount); }
public async Task SendAsync_ProcessRequestThrows_ThrowWithoutCallingProcessRequestNorInnerHandler() { var transport = new MockTransportHandler(); // ProcessRequest() throws exception. var handler = new MockHandler(transport, true, () => { throw new MockException(); }); // Note that ProcessRequest() is called by SendAsync(). However, the exception is not thrown // by SendAsync(). Instead, the returned Task is marked as faulted and contains the exception. await Assert.ThrowsAsync <MockException>(() => handler.TestSendAsync(new HttpRequestMessage(), CancellationToken.None)); Assert.Equal(0, transport.SendAsyncCount); Assert.Equal(1, handler.ProcessRequestCount); Assert.Equal(0, handler.ProcessResponseCount); }
/// <summary> /// Creates a CosmosClient with a mock TransportHandler that will capture and detect Exceptions happening inside ProcessChangesAsync. /// Since we want to be Exception-less, this will help detect if the Store Model is throwing or not. /// </summary> /// <param name="goThroughGateway">Whether or not to run the scenario using Gateway. If false, Direct will be used.</param> private static async Task <MockTransportHandler> TransportHandlerRunScenario(int responseStatusCode, bool goThroughGateway = true) { Func <HttpRequestMessage, Task <HttpResponseMessage> > sendFunc = async httpRequest => await Task.FromResult(new HttpResponseMessage((HttpStatusCode)responseStatusCode) { Content = new StringContent("{}"), RequestMessage = httpRequest }); Func <Uri, DocumentServiceRequest, StoreResponse> sendDirectFunc = (uri, request) => new StoreResponse() { ResponseBody = Stream.Null, Status = responseStatusCode, ResponseHeaderNames = Array.Empty <string>(), ResponseHeaderValues = Array.Empty <string>() }; // This is needed because in order to Mock a TransportClient we previously need an instance of CosmosClient CosmosClient internalClient = MockCosmosUtil.CreateMockCosmosClient(); internalClient.DocumentClient.GatewayStoreModel = MockGatewayStoreModel(sendFunc); internalClient.DocumentClient.StoreModel = MockServerStoreModel(internalClient.DocumentClient.Session, sendDirectFunc); RetryHandler retryHandler = new RetryHandler(internalClient.DocumentClient.ResetSessionTokenRetryPolicy); MockTransportHandler transportHandler = new MockTransportHandler(internalClient); CosmosClient client = MockCosmosUtil.CreateMockCosmosClient( (builder) => { builder .AddCustomHandlers(retryHandler, transportHandler); }); try { if (goThroughGateway) { DatabaseResponse response = await client.Databases.CreateDatabaseAsync("test"); } else { ItemResponse <dynamic> response = await client.Databases["test"].Containers["test"].CreateItemAsync <dynamic>(partitionKey: "id", item: new { id = "id" }); } } catch (CosmosException) { // Swallow CosmosExceptions as the point is to test the TransportHandler } return(transportHandler); }
public async Task SendAsync_SetInnerHandlerTwiceCallMethod_SecondInnerHandlerSendIsCalled() { var handler = new MockHandler(); var transport1 = new MockTransportHandler(); var transport2 = new MockTransportHandler(); handler.InnerHandler = transport1; handler.InnerHandler = transport2; HttpResponseMessage response = await handler.TestSendAsync(new HttpRequestMessage(), CancellationToken.None); Assert.NotNull(response); Assert.Equal(1, handler.SendAsyncCount); Assert.Equal(0, transport1.SendAsyncCount); Assert.Equal(1, transport2.SendAsyncCount); }
public async Task SendAsync_SetInnerHandlerCallMethod_InnerHandlerSendIsCalled() { var handler = new MockHandler(); var transport = new MockTransportHandler(); handler.InnerHandler = transport; HttpResponseMessage response = await handler.TestSendAsync(new HttpRequestMessage(), CancellationToken.None); Assert.NotNull(response); Assert.Equal(1, handler.SendAsyncCount); Assert.Equal(1, transport.SendAsyncCount); Assert.Throws<InvalidOperationException>(() => handler.InnerHandler = transport); Assert.Equal(transport, handler.InnerHandler); }
public async Task SendAsync_SetInnerHandlerCallMethod_InnerHandlerSendIsCalled() { var handler = new MockHandler(); var transport = new MockTransportHandler(); handler.InnerHandler = transport; HttpResponseMessage response = await handler.TestSendAsync(new HttpRequestMessage(), CancellationToken.None); Assert.NotNull(response); Assert.Equal(1, handler.SendAsyncCount); Assert.Equal(1, transport.SendAsyncCount); Assert.Throws <InvalidOperationException>(() => handler.InnerHandler = transport); Assert.Equal(transport, handler.InnerHandler); }
public async Task SendAsync_OperationCanceledWhileProcessRequestIsExecuted_TaskSetToIsCanceled() { var cts = new CancellationTokenSource(); var transport = new MockTransportHandler(); // ProcessRequest will cancel. var handler = new MockHandler(transport, true, () => { cts.Cancel(); cts.Token.ThrowIfCancellationRequested(); }); // Note that even ProcessMessage() is called on the same thread, we don't expect SendAsync() to throw. // SendAsync() must complete successfully, but the Task will be canceled. await Assert.ThrowsAsync<TaskCanceledException>(() => handler.TestSendAsync(new HttpRequestMessage(), cts.Token)); Assert.Equal(0, handler.ProcessResponseCount); }
public async Task SendAsync_OperationCanceledWhileProcessResponseIsExecuted_TaskSetToIsCanceled() { var cts = new CancellationTokenSource(); var transport = new MockTransportHandler(); // ProcessResponse will cancel. var handler = new MockHandler(transport, false, () => { cts.Cancel(); cts.Token.ThrowIfCancellationRequested(); }); await Assert.ThrowsAsync<TaskCanceledException>(() => handler.TestSendAsync(new HttpRequestMessage(), cts.Token)); }
public async Task SendAsync_ProcessResponseThrowsOperationCanceledExceptionUsingOtherCts_TaskSetToIsFaulted() { var cts = new CancellationTokenSource(); var otherCts = new CancellationTokenSource(); var transport = new MockTransportHandler(); // ProcessResponse will throw a random OperationCanceledException() not related to cts. We also cancel // the cts to make sure the code behaves correctly even if cts is canceled & an OperationCanceledException // was thrown. var handler = new MockHandler(transport, false, () => { cts.Cancel(); throw new OperationCanceledException("custom", otherCts.Token); }); await Assert.ThrowsAsync<OperationCanceledException>(() => handler.TestSendAsync(new HttpRequestMessage(), cts.Token)); Assert.Equal(1, handler.ProcessResponseCount); }
public async Task SendAsync_ProcessRequestThrows_ThrowWithoutCallingProcessRequestNorInnerHandler() { var transport = new MockTransportHandler(); // ProcessRequest() throws exception. var handler = new MockHandler(transport, true, () => { throw new MockException(); }); // Note that ProcessRequest() is called by SendAsync(). However, the exception is not thrown // by SendAsync(). Instead, the returned Task is marked as faulted and contains the exception. await Assert.ThrowsAsync<MockException>(() => handler.TestSendAsync(new HttpRequestMessage(), CancellationToken.None)); Assert.Equal(0, transport.SendAsyncCount); Assert.Equal(1, handler.ProcessRequestCount); Assert.Equal(0, handler.ProcessResponseCount); }
public async Task SendAsync_SetInnerHandlerAfterCallMethod_ThrowsInvalidOperationException() { var transport = new MockTransportHandler(); var handler = new MockHandler(transport); await handler.TestSendAsync(new HttpRequestMessage(), CancellationToken.None); Assert.Equal(1, handler.SendAsyncCount); Assert.Equal(1, transport.SendAsyncCount); Assert.Throws<InvalidOperationException>(() => handler.InnerHandler = transport); }
public void Dispose_CallDisposeMultipleTimes_OverriddenDisposeMethodCalled() { var innerHandler = new MockTransportHandler(); var handler = new MockHandler(innerHandler); handler.Dispose(); handler.Dispose(); handler.Dispose(); Assert.Equal(3, handler.DisposeCount); Assert.Equal(1, innerHandler.DisposeCount); }
public async Task SendAsync_OperationCanceledWhileInnerHandlerIsWorking_TaskSetToIsCanceled() { var cts = new CancellationTokenSource(); // We simulate a cancellation happening while the inner handler was processing the request, by letting // the inner mock handler call Cancel() and behave like if another thread called cancel while it was // processing. var transport = new MockTransportHandler(cts); // inner handler will cancel. var handler = new MockHandler(transport); await Assert.ThrowsAsync<TaskCanceledException>(() => handler.TestSendAsync(new HttpRequestMessage(), cts.Token)); Assert.Equal(0, handler.ProcessResponseCount); }
public void SendAsync_Disposed_Throws() { var transport = new MockTransportHandler(); var handler = new MockHandler(transport); handler.Dispose(); Assert.Throws<ObjectDisposedException>(() => { Task t = handler.TestSendAsync(new HttpRequestMessage(), CancellationToken.None); }); Assert.Throws<ObjectDisposedException>(() => handler.InnerHandler = new MockHandler()); Assert.Equal(transport, handler.InnerHandler); }
public async Task SendAsync_ProcessResponseThrows_TaskIsFaulted() { var transport = new MockTransportHandler(); // ProcessResponse() throws exception. var handler = new MockHandler(transport, false, () => { throw new MockException(); }); // Throwing an exception in ProcessResponse() will cause the Task to complete as 'faulted'. await Assert.ThrowsAsync<MockException>(() => handler.TestSendAsync(new HttpRequestMessage(), CancellationToken.None)); Assert.Equal(1, transport.SendAsyncCount); Assert.Equal(1, handler.ProcessRequestCount); Assert.Equal(1, handler.ProcessResponseCount); }