public async Task RetryHandlerDoesNotRetryOnException() { CosmosClient client = MockDocumentClient.CreateMockCosmosClient(); RetryHandler retryHandler = new RetryHandler(client.DocumentClient.ResetSessionTokenRetryPolicy); int handlerCalls = 0; int expectedHandlerCalls = 2; TestHandler testHandler = new TestHandler((request, cancellationToken) => { handlerCalls++; if (handlerCalls == expectedHandlerCalls) { Assert.Fail("Should not retry on exception."); } throw new Exception("You shall not retry."); }); retryHandler.InnerHandler = testHandler; RequestInvokerHandler invoker = new RequestInvokerHandler(client); invoker.InnerHandler = retryHandler; CosmosRequestMessage requestMessage = new CosmosRequestMessage(HttpMethod.Get, new System.Uri("https://dummy.documents.azure.com:443/dbs")); requestMessage.Headers.Add(HttpConstants.HttpHeaders.PartitionKey, "[]"); requestMessage.ResourceType = ResourceType.Document; requestMessage.OperationType = OperationType.Read; await invoker.SendAsync(requestMessage, new CancellationToken()); }
public async Task PartitionKeyRangeGoneRetryHandlerOn410() { CosmosClient client = MockDocumentClient.CreateMockCosmosClient(); int handlerCalls = 0; TestHandler testHandler = new TestHandler((request, response) => { if (handlerCalls == 0) { handlerCalls++; return(TestHandler.ReturnStatusCode((HttpStatusCode)StatusCodes.Gone, SubStatusCodes.PartitionKeyRangeGone)); } handlerCalls++; return(TestHandler.ReturnSuccess()); }); PartitionKeyRangeGoneRetryHandler retryHandler = new PartitionKeyRangeGoneRetryHandler(client); retryHandler.InnerHandler = testHandler; RequestInvokerHandler invoker = new RequestInvokerHandler(client); invoker.InnerHandler = retryHandler; CosmosRequestMessage requestMessage = new CosmosRequestMessage(HttpMethod.Get, new Uri("https://localhost/dbs/db1/colls/col1/docs/doc1")); await invoker.SendAsync(requestMessage, new CancellationToken()); int expectedHandlerCalls = 2; Assert.AreEqual(expectedHandlerCalls, handlerCalls); }
public async Task RetryHandlerRetriesOn429() { CosmosClient client = MockDocumentClient.CreateMockCosmosClient(); RetryHandler retryHandler = new RetryHandler(client.DocumentClient.ResetSessionTokenRetryPolicy); int handlerCalls = 0; int expectedHandlerCalls = 2; TestHandler testHandler = new TestHandler((request, cancellationToken) => { if (handlerCalls == 0) { handlerCalls++; return(TestHandler.ReturnStatusCode((HttpStatusCode)StatusCodes.TooManyRequests)); } handlerCalls++; return(TestHandler.ReturnSuccess()); }); retryHandler.InnerHandler = testHandler; RequestInvokerHandler invoker = new RequestInvokerHandler(client); invoker.InnerHandler = retryHandler; CosmosRequestMessage requestMessage = new CosmosRequestMessage(HttpMethod.Delete, RetryHandlerTests.TestUri); requestMessage.Headers.Add(HttpConstants.HttpHeaders.PartitionKey, "[]"); requestMessage.ResourceType = ResourceType.Document; requestMessage.OperationType = OperationType.Read; await invoker.SendAsync(requestMessage, new CancellationToken()); Assert.AreEqual(expectedHandlerCalls, handlerCalls); }
public async Task InvalidPartitionExceptionRetryHandlerDoesNotRetryOn410() { CosmosClient client = MockDocumentClient.CreateMockCosmosClient(); NamedCacheRetryHandler retryHandler = new NamedCacheRetryHandler(client); int handlerCalls = 0; int expectedHandlerCalls = 2; TestHandler testHandler = new TestHandler((request, cancellationToken) => { if (handlerCalls == 0) { handlerCalls++; return(TestHandler.ReturnStatusCode((HttpStatusCode)StatusCodes.Gone, SubStatusCodes.NameCacheIsStale)); } handlerCalls++; return(TestHandler.ReturnSuccess()); }); retryHandler.InnerHandler = testHandler; RequestInvokerHandler invoker = new RequestInvokerHandler(client); invoker.InnerHandler = retryHandler; CosmosRequestMessage requestMessage = new CosmosRequestMessage(HttpMethod.Get, new Uri("https://dummy.documents.azure.com:443/dbs")); await invoker.SendAsync(requestMessage, new CancellationToken()); Assert.AreEqual(expectedHandlerCalls, handlerCalls); }
public async Task VerifyCosmosDefaultResultSetStreamIteratorOperationType() { CosmosClient mockClient = MockDocumentClient.CreateMockCosmosClient(); CosmosDatabase database = new CosmosDatabase(mockClient, "database"); CosmosContainer container = new CosmosContainer(database, "container"); CosmosItems item = new CosmosItems(container); CosmosSqlQueryDefinition sql = new CosmosSqlQueryDefinition("select * from r"); CosmosResultSetIterator setIterator = item .CreateItemQueryAsStream(sql, "pk", requestOptions: new CosmosQueryRequestOptions()); TestHandler testHandler = new TestHandler((request, cancellationToken) => { Assert.AreEqual( 15, //OperationType.SqlQuery (int)request.GetType().GetProperty("OperationType", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(request, null) ); return(TestHandler.ReturnSuccess()); }); mockClient.RequestHandler.InnerHandler = testHandler; mockClient.CosmosConfiguration.UseConnectionModeDirect(); CosmosResponseMessage response = await setIterator.FetchNextSetAsync(); testHandler = new TestHandler((request, cancellationToken) => { Assert.AreEqual( 14, //OperationType.Query (int)request.GetType().GetProperty("OperationType", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(request, null) ); return(TestHandler.ReturnSuccess()); }); mockClient.RequestHandler.InnerHandler = testHandler; mockClient.CosmosConfiguration.UseConnectionModeGateway(); response = await setIterator.FetchNextSetAsync(); }
private async Task RetryHandlerDontRetryOnStatusCode( HttpStatusCode statusCode, SubStatusCodes subStatusCode = SubStatusCodes.Unknown) { int handlerCalls = 0; TestHandler testHandler = new TestHandler((request, response) => { handlerCalls++; if (handlerCalls == 0) { return(TestHandler.ReturnStatusCode(statusCode, subStatusCode)); } return(TestHandler.ReturnSuccess()); }); CosmosClient client = MockDocumentClient.CreateMockCosmosClient(); RetryHandler retryHandler = new RetryHandler(client.DocumentClient.ResetSessionTokenRetryPolicy); retryHandler.InnerHandler = testHandler; RequestInvokerHandler invoker = new RequestInvokerHandler(client); invoker.InnerHandler = retryHandler; CosmosRequestMessage requestMessage = new CosmosRequestMessage(HttpMethod.Delete, RetryHandlerTests.TestUri); requestMessage.Headers.Add(HttpConstants.HttpHeaders.PartitionKey, "[]"); requestMessage.ResourceType = ResourceType.Document; requestMessage.OperationType = OperationType.Read; await invoker.SendAsync(requestMessage, new CancellationToken()); int expectedHandlerCalls = 1; Assert.AreEqual(expectedHandlerCalls, handlerCalls); }
public async Task RequestOptionsHandlerCanHandleDataPlaneRequestOptions() { const string Condition = "*"; const string SessionToken = "test"; CosmosItemRequestOptions options = new CosmosItemRequestOptions { AccessCondition = new AccessCondition { Type = AccessConditionType.IfNoneMatch, Condition = Condition }, ConsistencyLevel = (Cosmos.ConsistencyLevel)ConsistencyLevel.Eventual, SessionToken = SessionToken }; TestHandler testHandler = new TestHandler((request, cancellationToken) => { Assert.AreEqual(Condition, request.Headers.GetValues(HttpConstants.HttpHeaders.IfNoneMatch).First()); Assert.AreEqual(ConsistencyLevel.Eventual.ToString(), request.Headers.GetValues(HttpConstants.HttpHeaders.ConsistencyLevel).First()); Assert.AreEqual(SessionToken, request.Headers.GetValues(HttpConstants.HttpHeaders.SessionToken).First()); return(TestHandler.ReturnSuccess()); }); CosmosClient client = MockDocumentClient.CreateMockCosmosClient(); RequestInvokerHandler invoker = new RequestInvokerHandler(client); invoker.InnerHandler = testHandler; CosmosRequestMessage requestMessage = new CosmosRequestMessage(HttpMethod.Get, new System.Uri("https://dummy.documents.azure.com:443/dbs")); requestMessage.Headers.Add(HttpConstants.HttpHeaders.PartitionKey, "[]"); requestMessage.ResourceType = ResourceType.Document; requestMessage.OperationType = OperationType.Read; requestMessage.RequestOptions = options; await invoker.SendAsync(requestMessage, new CancellationToken()); }
public async Task VerifyCosmosDefaultResultSetStreamIteratorOperationType() { CosmosClient mockClient = MockDocumentClient.CreateMockCosmosClient( (cosmosClientBuilder) => cosmosClientBuilder.UseConnectionModeDirect()); CosmosContainer container = mockClient.Databases["database"].Containers["container"]; CosmosSqlQueryDefinition sql = new CosmosSqlQueryDefinition("select * from r"); CosmosResultSetIterator setIterator = container.Items.CreateItemQueryAsStream( sqlQueryDefinition: sql, maxConcurrency: 1, partitionKey: "pk", requestOptions: new CosmosQueryRequestOptions()); TestHandler testHandler = new TestHandler((request, cancellationToken) => { Assert.AreEqual( 15, //OperationType.SqlQuery (int)request.GetType().GetProperty("OperationType", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(request, null) ); return(TestHandler.ReturnSuccess()); }); mockClient.RequestHandler.InnerHandler = testHandler; CosmosQueryResponse response = await setIterator.FetchNextSetAsync(); //Test gateway mode mockClient = MockDocumentClient.CreateMockCosmosClient( (cosmosClientBuilder) => cosmosClientBuilder.UseConnectionModeGateway()); container = mockClient.Databases["database"].Containers["container"]; setIterator = container.Items.CreateItemQueryAsStream( sqlQueryDefinition: sql, maxConcurrency: 1, partitionKey: "pk", requestOptions: new CosmosQueryRequestOptions()); testHandler = new TestHandler((request, cancellationToken) => { Assert.AreEqual( 14, //OperationType.Query (int)request.GetType().GetProperty("OperationType", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(request, null) ); return(TestHandler.ReturnSuccess()); }); mockClient.RequestHandler.InnerHandler = testHandler; response = await setIterator.FetchNextSetAsync(); }
public async Task TestPreProcessingHandler() { CosmosRequestHandler preProcessHandler = new PreProcessingTestHandler(); CosmosClient client = MockDocumentClient.CreateMockCosmosClient((builder) => builder.AddCustomHandlers(preProcessHandler)); Assert.IsTrue(typeof(RequestInvokerHandler).Equals(client.RequestHandler.GetType())); Assert.IsTrue(typeof(PreProcessingTestHandler).Equals(client.RequestHandler.InnerHandler.GetType())); CosmosContainer container = client.Databases["testdb"] .Containers["testcontainer"]; HttpStatusCode[] testHttpStatusCodes = new HttpStatusCode[] { HttpStatusCode.OK, HttpStatusCode.NotFound }; // User operations foreach (HttpStatusCode code in testHttpStatusCodes) { CosmosItemRequestOptions options = new CosmosItemRequestOptions(); options.Properties = new Dictionary <string, object>(); options.Properties.Add(PreProcessingTestHandler.StatusCodeName, code); CosmosItemResponse <object> response = await container.Items.ReadItemAsync <object>("pk1", "id1", options); Console.WriteLine($"Got status code {response.StatusCode}"); Assert.AreEqual(code, response.StatusCode); } // Meta-data operations foreach (HttpStatusCode code in testHttpStatusCodes) { CosmosContainerRequestOptions options = new CosmosContainerRequestOptions(); options.Properties = new Dictionary <string, object>(); options.Properties.Add(PreProcessingTestHandler.StatusCodeName, code); CosmosContainerResponse response = await container.DeleteAsync(options); Console.WriteLine($"Got status code {response.StatusCode}"); Assert.AreEqual(code, response.StatusCode); } }
public async Task PartitionKeyRangeGoneRetryHandlerOnSuccess() { CosmosClient client = MockDocumentClient.CreateMockCosmosClient(); PartitionKeyRangeGoneRetryHandler retryHandler = new PartitionKeyRangeGoneRetryHandler(client); int handlerCalls = 0; int expectedHandlerCalls = 1; TestHandler testHandler = new TestHandler((request, cancellationToken) => { handlerCalls++; return(TestHandler.ReturnSuccess()); }); retryHandler.InnerHandler = testHandler; RequestInvokerHandler invoker = new RequestInvokerHandler(client); invoker.InnerHandler = retryHandler; CosmosRequestMessage requestMessage = new CosmosRequestMessage(HttpMethod.Get, new Uri("https://dummy.documents.azure.com:443/dbs")); await invoker.SendAsync(requestMessage, new CancellationToken()); Assert.AreEqual(expectedHandlerCalls, handlerCalls); }
public void HandlerOrder() { CosmosClient client = MockDocumentClient.CreateMockCosmosClient(); Type[] types = new Type[] { typeof(RequestInvokerHandler), typeof(RetryHandler), typeof(RouterHandler) }; CosmosRequestHandler handler = client.RequestHandler; foreach (Type type in types) { Assert.IsTrue(type.Equals(handler.GetType())); handler = (CosmosRequestHandler)handler.InnerHandler; } Assert.IsNull(handler); }
public async Task RequestOptionsHandlerCanHandleRequestOptions() { const string PropertyKey = "propkey"; const string Condition = "*"; object propertyValue = Encoding.UTF8.GetBytes("test"); CosmosRequestOptions options = new CosmosItemRequestOptions { Properties = new Dictionary <string, object>(new List <KeyValuePair <string, object> > { new KeyValuePair <string, object>(PropertyKey, propertyValue) }), AccessCondition = new AccessCondition { Type = AccessConditionType.IfMatch, Condition = Condition } }; TestHandler testHandler = new TestHandler((request, cancellationToken) => { Assert.AreEqual(propertyValue, request.Properties[PropertyKey]); Assert.AreEqual(Condition, request.Headers.GetValues(HttpConstants.HttpHeaders.IfMatch).First()); return(TestHandler.ReturnSuccess()); }); CosmosClient client = MockDocumentClient.CreateMockCosmosClient(); RequestInvokerHandler invoker = new RequestInvokerHandler(client); invoker.InnerHandler = testHandler; CosmosRequestMessage requestMessage = new CosmosRequestMessage(HttpMethod.Get, new System.Uri("https://dummy.documents.azure.com:443/dbs")); requestMessage.Headers.Add(HttpConstants.HttpHeaders.PartitionKey, "[]"); requestMessage.ResourceType = ResourceType.Document; requestMessage.OperationType = OperationType.Read; requestMessage.RequestOptions = options; await invoker.SendAsync(requestMessage, new CancellationToken()); }
private async Task VerifyItemNullExceptions( dynamic testItem, CosmosItemRequestOptions requestOptions = null) { TestHandler testHandler = new TestHandler((request, cancellationToken) => { Assert.Fail("Null partition key should be blocked without the correct request option"); return(null); }); CosmosClient client = MockDocumentClient.CreateMockCosmosClient( (cosmosClientBuilder) => cosmosClientBuilder.AddCustomHandlers(testHandler)); CosmosContainer container = client.Databases["testdb"] .Containers["testcontainer"]; await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.CreateItemAsync <dynamic>( partitionKey: null, item: testItem, requestOptions: requestOptions); }, "CreateItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.ReadItemAsync <dynamic>( partitionKey: null, id: testItem.id, requestOptions: requestOptions); }, "ReadItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.UpsertItemAsync <dynamic>( partitionKey: null, item: testItem, requestOptions: requestOptions); }, "UpsertItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.ReplaceItemAsync <dynamic>( partitionKey: null, id: testItem.id, item: testItem, requestOptions: requestOptions); }, "ReplaceItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.DeleteItemAsync <dynamic>( partitionKey: null, id: testItem.id, requestOptions: requestOptions); }, "DeleteItemAsync should throw ArgumentNullException without the correct request option set."); CosmosDefaultJsonSerializer jsonSerializer = new CosmosDefaultJsonSerializer(); using (Stream itemStream = jsonSerializer.ToStream <dynamic>(testItem)) { await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.CreateItemStreamAsync( partitionKey: null, streamPayload: itemStream, requestOptions: requestOptions); }, "CreateItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.ReadItemStreamAsync( partitionKey: null, id: testItem.id, requestOptions: requestOptions); }, "ReadItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.UpsertItemStreamAsync( partitionKey: null, streamPayload: itemStream, requestOptions: requestOptions); }, "UpsertItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.ReplaceItemStreamAsync( partitionKey: null, id: testItem.id, streamPayload: itemStream, requestOptions: requestOptions); }, "ReplaceItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.DeleteItemStreamAsync( partitionKey: null, id: testItem.id, requestOptions: requestOptions); }, "DeleteItemAsync should throw ArgumentNullException without the correct request option set."); } }
private async Task VerifyItemOperations( object partitionKey, string partitionKeySerialized, dynamic testItem, CosmosItemRequestOptions requestOptions = null) { CosmosResponseMessage response = null; HttpStatusCode httpStatusCode = HttpStatusCode.OK; int testHandlerHitCount = 0; TestHandler testHandler = new TestHandler((request, cancellationToken) => { Assert.IsTrue(request.RequestUri.OriginalString.StartsWith(@"/dbs/testdb/colls/testcontainer")); Assert.AreEqual(requestOptions, request.RequestOptions); Assert.AreEqual(ResourceType.Document, request.ResourceType); Assert.IsNotNull(request.Headers.PartitionKey); Assert.AreEqual(partitionKeySerialized, request.Headers.PartitionKey); testHandlerHitCount++; response = new CosmosResponseMessage(httpStatusCode, request, errorMessage: null); response.Content = request.Content; return(Task.FromResult(response)); }); CosmosClient client = MockDocumentClient.CreateMockCosmosClient( (builder) => builder.AddCustomHandlers(testHandler)); CosmosContainer container = client.Databases["testdb"] .Containers["testcontainer"]; CosmosItemResponse <dynamic> itemResponse = await container.Items.CreateItemAsync <dynamic>( partitionKey : partitionKey, item : testItem, requestOptions : requestOptions); Assert.IsNotNull(itemResponse); Assert.AreEqual(httpStatusCode, itemResponse.StatusCode); itemResponse = await container.Items.ReadItemAsync <dynamic>( partitionKey : partitionKey, id : testItem.id, requestOptions : requestOptions); Assert.IsNotNull(itemResponse); Assert.AreEqual(httpStatusCode, itemResponse.StatusCode); itemResponse = await container.Items.UpsertItemAsync <dynamic>( partitionKey : partitionKey, item : testItem, requestOptions : requestOptions); Assert.IsNotNull(itemResponse); Assert.AreEqual(httpStatusCode, itemResponse.StatusCode); itemResponse = await container.Items.ReplaceItemAsync <dynamic>( partitionKey : partitionKey, id : testItem.id, item : testItem, requestOptions : requestOptions); Assert.IsNotNull(itemResponse); Assert.AreEqual(httpStatusCode, itemResponse.StatusCode); itemResponse = await container.Items.DeleteItemAsync <dynamic>( partitionKey : partitionKey, id : testItem.id, requestOptions : requestOptions); Assert.IsNotNull(itemResponse); Assert.AreEqual(httpStatusCode, itemResponse.StatusCode); Assert.AreEqual(5, testHandlerHitCount, "An operation did not make it to the handler"); CosmosDefaultJsonSerializer jsonSerializer = new CosmosDefaultJsonSerializer(); using (Stream itemStream = jsonSerializer.ToStream <dynamic>(testItem)) { using (CosmosResponseMessage streamResponse = await container.Items.CreateItemStreamAsync( partitionKey: partitionKey, streamPayload: itemStream)) { Assert.IsNotNull(streamResponse); Assert.AreEqual(httpStatusCode, streamResponse.StatusCode); } } using (Stream itemStream = jsonSerializer.ToStream <dynamic>(testItem)) { using (CosmosResponseMessage streamResponse = await container.Items.ReadItemStreamAsync( partitionKey: partitionKey, id: testItem.id, requestOptions: requestOptions)) { Assert.IsNotNull(streamResponse); Assert.AreEqual(httpStatusCode, streamResponse.StatusCode); } } using (Stream itemStream = jsonSerializer.ToStream <dynamic>(testItem)) { using (CosmosResponseMessage streamResponse = await container.Items.UpsertItemStreamAsync( partitionKey: partitionKey, streamPayload: itemStream, requestOptions: requestOptions)) { Assert.IsNotNull(streamResponse); Assert.AreEqual(httpStatusCode, streamResponse.StatusCode); } } using (Stream itemStream = jsonSerializer.ToStream <dynamic>(testItem)) { using (CosmosResponseMessage streamResponse = await container.Items.ReplaceItemStreamAsync( partitionKey: partitionKey, id: testItem.id, streamPayload: itemStream, requestOptions: requestOptions)) { Assert.IsNotNull(streamResponse); Assert.AreEqual(httpStatusCode, streamResponse.StatusCode); } } using (Stream itemStream = jsonSerializer.ToStream <dynamic>(testItem)) { using (CosmosResponseMessage streamResponse = await container.Items.DeleteItemStreamAsync( partitionKey: partitionKey, id: testItem.id, requestOptions: requestOptions)) { Assert.IsNotNull(streamResponse); Assert.AreEqual(httpStatusCode, streamResponse.StatusCode); } } Assert.AreEqual(10, testHandlerHitCount, "A stream operation did not make it to the handler"); }