public async Task BatchInvalidOptionsAsync() { Container container = BatchUnitTests.GetContainer(); List <RequestOptions> badBatchOptionsList = new List <RequestOptions>() { new RequestOptions() { IfMatchEtag = "cond", }, new RequestOptions() { IfNoneMatchEtag = "cond2", } }; foreach (RequestOptions batchOptions in badBatchOptionsList) { BatchCore batch = (BatchCore) new BatchCore((ContainerInternal)container, new Cosmos.PartitionKey(BatchUnitTests.PartitionKey1)) .ReadItem("someId"); await BatchUnitTests.VerifyExceptionThrownOnExecuteAsync( batch, typeof(ArgumentException), ClientResources.BatchRequestOptionNotSupported, batchOptions); } }
public async Task BatchSingleServerResponseAsync() { List <TransactionalBatchOperationResult> expectedResults = new List <TransactionalBatchOperationResult>(); CosmosJsonDotNetSerializer jsonSerializer = new CosmosJsonDotNetSerializer(); TestItem testItem = new TestItem("tst"); Stream itemStream = jsonSerializer.ToStream <TestItem>(testItem); MemoryStream resourceStream = itemStream as MemoryStream; if (resourceStream == null) { await itemStream.CopyToAsync(resourceStream); resourceStream.Position = 0; } expectedResults.Add( new TransactionalBatchOperationResult(HttpStatusCode.OK) { ETag = "theETag", SubStatusCode = (SubStatusCodes)1100, ResourceStream = resourceStream }); expectedResults.Add(new TransactionalBatchOperationResult(HttpStatusCode.Conflict)); double requestCharge = 3.6; TestHandler testHandler = new TestHandler(async(request, cancellationToken) => { ResponseMessage responseMessage = new ResponseMessage(HttpStatusCode.OK, requestMessage: null, errorMessage: null) { Content = await new BatchResponsePayloadWriter(expectedResults).GeneratePayloadAsync() }; responseMessage.Headers.RequestCharge = requestCharge; return(responseMessage); }); Container container = BatchUnitTests.GetContainer(testHandler); TransactionalBatchResponse batchResponse = await new BatchCore((ContainerInternal)container, new Cosmos.PartitionKey(BatchUnitTests.PartitionKey1)) .ReadItem("id1") .ReadItem("id2") .ExecuteAsync(); Assert.AreEqual(HttpStatusCode.OK, batchResponse.StatusCode); Assert.AreEqual(requestCharge, batchResponse.RequestCharge); TransactionalBatchOperationResult <TestItem> result0 = batchResponse.GetOperationResultAtIndex <TestItem>(0); Assert.AreEqual(expectedResults[0].StatusCode, result0.StatusCode); Assert.AreEqual(expectedResults[0].SubStatusCode, result0.SubStatusCode); Assert.AreEqual(expectedResults[0].ETag, result0.ETag); Assert.AreEqual(testItem, result0.Resource); Assert.AreEqual(expectedResults[1].StatusCode, batchResponse[1].StatusCode); Assert.AreEqual(SubStatusCodes.Unknown, batchResponse[1].SubStatusCode); Assert.IsNull(batchResponse[1].ETag); Assert.IsNull(batchResponse[1].ResourceStream); }
public async Task BatchNoOperationsAsync() { Container container = BatchUnitTests.GetContainer(); TransactionalBatch batch = new BatchCore((ContainerInternal)container, new Cosmos.PartitionKey(BatchUnitTests.PartitionKey1)); await BatchUnitTests.VerifyExceptionThrownOnExecuteAsync( batch, typeof(ArgumentException), ClientResources.BatchNoOperations); }
public async Task BatchWithTooManyOperationsAsync() { Container container = BatchUnitTests.GetContainer(); const int operationCount = Constants.MaxOperationsInDirectModeBatchRequest + 1; Batch batch = new BatchCore((ContainerCore)container, new Cosmos.PartitionKey(BatchUnitTests.PartitionKey1)); for (int i = 0; i < operationCount; i++) { batch.ReadItem("someId"); } await BatchUnitTests.VerifyExceptionThrownOnExecuteAsync( batch, typeof(ArgumentException), ClientResources.BatchTooLarge); }
public async Task BatchInvalidItemOptionsAsync() { Container container = BatchUnitTests.GetContainer(); List <TransactionalBatchItemRequestOptions> badItemOptionsList = new List <TransactionalBatchItemRequestOptions>() { new TransactionalBatchItemRequestOptions() { Properties = new Dictionary <string, object> { // EPK without string representation { WFConstants.BackendHeaders.EffectivePartitionKey, new byte[1] { 0x41 } } } }, new TransactionalBatchItemRequestOptions() { Properties = new Dictionary <string, object> { // EPK string without corresponding byte representation { WFConstants.BackendHeaders.EffectivePartitionKeyString, "epk" } } }, new TransactionalBatchItemRequestOptions() { Properties = new Dictionary <string, object> { // Partition key without EPK string { HttpConstants.HttpHeaders.PartitionKey, "epk" } } } }; foreach (TransactionalBatchItemRequestOptions itemOptions in badItemOptionsList) { TransactionalBatch batch = new BatchCore((ContainerInternal)container, new Cosmos.PartitionKey(BatchUnitTests.PartitionKey1)) .ReplaceItem("someId", new TestItem("repl"), itemOptions); await BatchUnitTests.VerifyExceptionThrownOnExecuteAsync( batch, typeof(ArgumentException)); } }
public async Task BatchLargerThanServerRequestAsync() { Container container = BatchUnitTests.GetContainer(); const int operationCount = 20; int appxDocSize = Constants.MaxDirectModeBatchRequestBodySizeInBytes / operationCount; // Increase the doc size by a bit so all docs won't fit in one server request. appxDocSize = (int)(appxDocSize * 1.05); Batch batch = new BatchCore((ContainerCore)container, new Cosmos.PartitionKey(BatchUnitTests.PartitionKey1)); for (int i = 0; i < operationCount; i++) { TestItem testItem = new TestItem(new string('x', appxDocSize)); batch.CreateItem(testItem); } await BatchUnitTests.VerifyExceptionThrownOnExecuteAsync( batch, typeof(RequestEntityTooLargeException)); }
public async Task BatchJsonServerResponseAsync() { TestHandler testHandler = new TestHandler((request, cancellationToken) => { HttpStatusCode serverStatusCode = HttpStatusCode.Gone; Stream serverContent = new MemoryStream(Encoding.UTF8.GetBytes("{ \"random\": 1 }")); ResponseMessage responseMessage = new ResponseMessage(serverStatusCode, requestMessage: null, errorMessage: null) { Content = serverContent }; return(Task.FromResult(responseMessage)); }); Container container = BatchUnitTests.GetContainer(testHandler); TransactionalBatchResponse batchResponse = await new BatchCore((ContainerInternal)container, new Cosmos.PartitionKey(BatchUnitTests.PartitionKey1)) .ReadItem("id1") .ReadItem("id2") .ExecuteAsync(); Assert.AreEqual(HttpStatusCode.Gone, batchResponse.StatusCode); }
public async Task BatchCrudRequestAsync() { Random random = new Random(); TestItem createItem = new TestItem("create"); byte[] createStreamContent = new byte[20]; random.NextBytes(createStreamContent); byte[] createStreamBinaryId = new byte[20]; random.NextBytes(createStreamBinaryId); int createTtl = 45; TransactionalBatchItemRequestOptions createRequestOptions = new TransactionalBatchItemRequestOptions() { Properties = new Dictionary <string, object>() { { WFConstants.BackendHeaders.BinaryId, createStreamBinaryId }, { WFConstants.BackendHeaders.TimeToLiveInSeconds, createTtl.ToString() }, }, IndexingDirective = Microsoft.Azure.Cosmos.IndexingDirective.Exclude }; string readId = Guid.NewGuid().ToString(); byte[] readStreamBinaryId = new byte[20]; random.NextBytes(readStreamBinaryId); TransactionalBatchItemRequestOptions readRequestOptions = new TransactionalBatchItemRequestOptions() { Properties = new Dictionary <string, object>() { { WFConstants.BackendHeaders.BinaryId, readStreamBinaryId } }, IfNoneMatchEtag = "readCondition" }; TestItem replaceItem = new TestItem("repl"); byte[] replaceStreamContent = new byte[20]; random.NextBytes(replaceStreamContent); const string replaceStreamId = "replStream"; byte[] replaceStreamBinaryId = new byte[20]; random.NextBytes(replaceStreamBinaryId); TransactionalBatchItemRequestOptions replaceRequestOptions = new TransactionalBatchItemRequestOptions() { Properties = new Dictionary <string, object>() { { WFConstants.BackendHeaders.BinaryId, replaceStreamBinaryId } }, IfMatchEtag = "replCondition", IndexingDirective = Microsoft.Azure.Cosmos.IndexingDirective.Exclude }; TestItem upsertItem = new TestItem("upsert"); byte[] upsertStreamContent = new byte[20]; random.NextBytes(upsertStreamContent); byte[] upsertStreamBinaryId = new byte[20]; random.NextBytes(upsertStreamBinaryId); TransactionalBatchItemRequestOptions upsertRequestOptions = new TransactionalBatchItemRequestOptions() { Properties = new Dictionary <string, object>() { { WFConstants.BackendHeaders.BinaryId, upsertStreamBinaryId } }, IfMatchEtag = "upsertCondition", IndexingDirective = Microsoft.Azure.Cosmos.IndexingDirective.Exclude }; string deleteId = Guid.NewGuid().ToString(); byte[] deleteStreamBinaryId = new byte[20]; random.NextBytes(deleteStreamBinaryId); TransactionalBatchItemRequestOptions deleteRequestOptions = new TransactionalBatchItemRequestOptions() { Properties = new Dictionary <string, object>() { { WFConstants.BackendHeaders.BinaryId, deleteStreamBinaryId } }, IfNoneMatchEtag = "delCondition" }; CosmosJsonDotNetSerializer jsonSerializer = new CosmosJsonDotNetSerializer(); BatchTestHandler testHandler = new BatchTestHandler((request, operations) => { Assert.AreEqual(new Cosmos.PartitionKey(BatchUnitTests.PartitionKey1).ToString(), request.Headers.PartitionKey); Assert.AreEqual(bool.TrueString, request.Headers[HttpConstants.HttpHeaders.IsBatchAtomic]); Assert.AreEqual(bool.TrueString, request.Headers[HttpConstants.HttpHeaders.IsBatchOrdered]); Assert.IsFalse(request.Headers.TryGetValue(HttpConstants.HttpHeaders.ShouldBatchContinueOnError, out string unused)); Assert.AreEqual(16, operations.Count); int operationIndex = 0; // run the loop twice, once for operations without item request options, and one for with item request options for (int loopCount = 0; loopCount < 2; loopCount++) { bool hasItemRequestOptions = loopCount == 1; ItemBatchOperation operation = operations[operationIndex++]; Assert.AreEqual(OperationType.Create, operation.OperationType); Assert.IsNull(operation.Id); Assert.AreEqual(createItem, BatchUnitTests.Deserialize(operation.ResourceBody, jsonSerializer)); BatchUnitTests.VerifyBatchItemRequestOptionsAreEqual(hasItemRequestOptions ? createRequestOptions : null, operation.RequestOptions); operation = operations[operationIndex++]; Assert.AreEqual(OperationType.Read, operation.OperationType); Assert.AreEqual(readId, operation.Id); BatchUnitTests.VerifyBatchItemRequestOptionsAreEqual(hasItemRequestOptions ? readRequestOptions : null, operation.RequestOptions); operation = operations[operationIndex++]; Assert.AreEqual(OperationType.Replace, operation.OperationType); Assert.AreEqual(replaceItem.Id, operation.Id); Assert.AreEqual(replaceItem, BatchUnitTests.Deserialize(operation.ResourceBody, jsonSerializer)); BatchUnitTests.VerifyBatchItemRequestOptionsAreEqual(hasItemRequestOptions ? replaceRequestOptions : null, operation.RequestOptions); operation = operations[operationIndex++]; Assert.AreEqual(OperationType.Upsert, operation.OperationType); Assert.IsNull(operation.Id); Assert.AreEqual(upsertItem, BatchUnitTests.Deserialize(operation.ResourceBody, jsonSerializer)); BatchUnitTests.VerifyBatchItemRequestOptionsAreEqual(hasItemRequestOptions ? upsertRequestOptions : null, operation.RequestOptions); operation = operations[operationIndex++]; Assert.AreEqual(OperationType.Delete, operation.OperationType); Assert.AreEqual(deleteId, operation.Id); BatchUnitTests.VerifyBatchItemRequestOptionsAreEqual(hasItemRequestOptions ? deleteRequestOptions : null, operation.RequestOptions); operation = operations[operationIndex++]; Assert.AreEqual(OperationType.Create, operation.OperationType); Assert.IsNull(operation.Id); Assert.IsTrue(operation.ResourceBody.Span.SequenceEqual(createStreamContent)); BatchUnitTests.VerifyBatchItemRequestOptionsAreEqual(hasItemRequestOptions ? createRequestOptions : null, operation.RequestOptions); operation = operations[operationIndex++]; Assert.AreEqual(OperationType.Replace, operation.OperationType); Assert.AreEqual(replaceStreamId, operation.Id); Assert.IsTrue(operation.ResourceBody.Span.SequenceEqual(replaceStreamContent)); BatchUnitTests.VerifyBatchItemRequestOptionsAreEqual(hasItemRequestOptions ? replaceRequestOptions : null, operation.RequestOptions); operation = operations[operationIndex++]; Assert.AreEqual(OperationType.Upsert, operation.OperationType); Assert.IsNull(operation.Id); Assert.IsTrue(operation.ResourceBody.Span.SequenceEqual(upsertStreamContent)); BatchUnitTests.VerifyBatchItemRequestOptionsAreEqual(hasItemRequestOptions ? upsertRequestOptions : null, operation.RequestOptions); } return(Task.FromResult(new ResponseMessage(HttpStatusCode.OK))); }); Container container = BatchUnitTests.GetContainer(testHandler); TransactionalBatchResponse batchResponse = await new BatchCore((ContainerInternal)container, new Cosmos.PartitionKey(BatchUnitTests.PartitionKey1)) .CreateItem(createItem) .ReadItem(readId) .ReplaceItem(replaceItem.Id, replaceItem) .UpsertItem(upsertItem) .DeleteItem(deleteId) // stream .CreateItemStream(new MemoryStream(createStreamContent)) .ReplaceItemStream(replaceStreamId, new MemoryStream(replaceStreamContent)) .UpsertItemStream(new MemoryStream(upsertStreamContent)) // regular with options .CreateItem(createItem, createRequestOptions) .ReadItem(readId, readRequestOptions) .ReplaceItem(replaceItem.Id, replaceItem, replaceRequestOptions) .UpsertItem(upsertItem, upsertRequestOptions) .DeleteItem(deleteId, deleteRequestOptions) // stream with options .CreateItemStream(new MemoryStream(createStreamContent), createRequestOptions) .ReplaceItemStream(replaceStreamId, new MemoryStream(replaceStreamContent), replaceRequestOptions) .UpsertItemStream(new MemoryStream(upsertStreamContent), upsertRequestOptions) .ExecuteAsync(); }