public void ToResponseMessage_MapsProperties() { BatchOperationResult result = new BatchOperationResult(HttpStatusCode.OK) { ResourceStream = new MemoryStream(new byte[] { 0x41, 0x42 }, index: 0, count: 2, writable: false, publiclyVisible: true), ETag = "1234", SubStatusCode = SubStatusCodes.CompletingSplit, RetryAfter = TimeSpan.FromSeconds(10) }; ResponseMessage response = result.ToResponseMessage(); Assert.AreEqual(result.ResourceStream, response.Content); Assert.AreEqual(result.SubStatusCode, response.Headers.SubStatusCode); Assert.AreEqual(result.RetryAfter, response.Headers.RetryAfter); Assert.AreEqual(result.StatusCode, response.StatusCode); }
public void ToResponseMessage_MapsProperties() { BatchOperationResult result = new BatchOperationResult(HttpStatusCode.OK) { ResourceStream = new MemoryStream(new byte[] { 0x41, 0x42 }, index: 0, count: 2, writable: false, publiclyVisible: true), ETag = "1234", SubStatusCode = SubStatusCodes.CompletingSplit, RetryAfter = TimeSpan.FromSeconds(10), Diagnostics = new PointOperationStatistics(HttpStatusCode.OK, SubStatusCodes.Unknown, 0, string.Empty, HttpMethod.Get, new Uri("http://localhost"), new CosmosClientSideRequestStatistics()) }; ResponseMessage response = result.ToResponseMessage(); Assert.AreEqual(result.ResourceStream, response.Content); Assert.AreEqual(result.SubStatusCode, response.Headers.SubStatusCode); Assert.AreEqual(result.RetryAfter, response.Headers.RetryAfter); Assert.AreEqual(result.StatusCode, response.StatusCode); Assert.AreEqual(result.Diagnostics, response.Diagnostics); }
public async Task DispatchesAsync() { // Expect all operations to complete as their batches get dispached BatchAsyncStreamer batchAsyncStreamer = new BatchAsyncStreamer(2, MaxBatchByteSize, DispatchTimerInSeconds, this.TimerPool, new CosmosJsonDotNetSerializer(), this.Executor, this.Retrier); List <Task <BatchOperationResult> > contexts = new List <Task <BatchOperationResult> >(10); for (int i = 0; i < 10; i++) { ItemBatchOperation operation = new ItemBatchOperation(OperationType.Create, i, i.ToString()); ItemBatchOperationContext context = AttachContext(operation); batchAsyncStreamer.Add(operation); contexts.Add(context.OperationTask); } await Task.WhenAll(contexts); for (int i = 0; i < 10; i++) { Task <BatchOperationResult> context = contexts[i]; Assert.AreEqual(TaskStatus.RanToCompletion, context.Status); BatchOperationResult result = await context; Assert.AreEqual(i.ToString(), result.ETag); } }
private static async Task <ResponseMessage> GetBatchResponseMessageAsync(List <ItemBatchOperation> operations, int rateLimitedOperationCount = 0) { BatchOperationResult okOperationResult = new BatchOperationResult(HttpStatusCode.OK); BatchOperationResult rateLimitedOperationResult = new BatchOperationResult((HttpStatusCode)StatusCodes.TooManyRequests); List <BatchOperationResult> resultsFromServer = new List <BatchOperationResult>(); for (int operationIndex = 0; operationIndex < operations.Count - rateLimitedOperationCount; operationIndex++) { resultsFromServer.Add(okOperationResult); } for (int index = 0; index < rateLimitedOperationCount; index++) { resultsFromServer.Add(rateLimitedOperationResult); } HttpStatusCode batchStatus = rateLimitedOperationCount > 0 ? (HttpStatusCode)StatusCodes.MultiStatus : HttpStatusCode.OK; return(new ResponseMessage(batchStatus, requestMessage: null, errorMessage: null) { Content = await new BatchResponsePayloadWriter(resultsFromServer).GeneratePayloadAsync() }); }
public async Task DispatchProcessInOrderAsync() { BatchAsyncBatcher batchAsyncBatcher = new BatchAsyncBatcher(10, 1000, new CosmosJsonDotNetSerializer(), this.Executor, this.Retrier); List <ItemBatchOperationContext> contexts = new List <ItemBatchOperationContext>(10); for (int i = 0; i < 10; i++) { ItemBatchOperation operation = new ItemBatchOperation(OperationType.Create, i, i.ToString()); ItemBatchOperationContext context = new ItemBatchOperationContext(string.Empty); operation.AttachContext(context); contexts.Add(context); Assert.IsTrue(batchAsyncBatcher.TryAdd(operation)); } await batchAsyncBatcher.DispatchAsync(); for (int i = 0; i < 10; i++) { ItemBatchOperationContext context = contexts[i]; Assert.AreEqual(TaskStatus.RanToCompletion, context.OperationTask.Status); BatchOperationResult result = await context.OperationTask; Assert.AreEqual(i.ToString(), result.ETag); } }
private static Result WriteResult(ref RowWriter writer, TypeArgument typeArg, BatchOperationResult result) { Result r = writer.WriteInt32("statusCode", (int)result.StatusCode); if (r != Result.Success) { return(r); } if (result.SubStatusCode != SubStatusCodes.Unknown) { r = writer.WriteInt32("subStatusCode", (int)result.SubStatusCode); if (r != Result.Success) { return(r); } } if (result.ETag != null) { r = writer.WriteString("eTag", result.ETag); if (r != Result.Success) { return(r); } } if (result.ResourceStream != null) { r = writer.WriteBinary("resourceBody", BatchResponsePayloadWriter.StreamToBytes(result.ResourceStream)); if (r != Result.Success) { return(r); } } if (result.RetryAfter != null) { r = writer.WriteUInt32("retryAfterMilliseconds", (uint)result.RetryAfter.TotalMilliseconds); if (r != Result.Success) { return(r); } } return(Result.Success); }
public async Task DoesNotRecalculatePartitionKeyRangeOnNoSplits() { ItemBatchOperation itemBatchOperation = CreateItem("test"); Mock <CosmosClientContext> mockedContext = new Mock <CosmosClientContext>(); mockedContext.Setup(c => c.ClientOptions).Returns(new CosmosClientOptions()); mockedContext .Setup(c => c.ProcessResourceOperationStreamAsync( It.IsAny <Uri>(), It.IsAny <ResourceType>(), It.IsAny <OperationType>(), It.IsAny <RequestOptions>(), It.IsAny <ContainerCore>(), It.IsAny <Cosmos.PartitionKey?>(), It.IsAny <Stream>(), It.IsAny <Action <RequestMessage> >(), It.IsAny <CancellationToken>())) .Returns(this.GenerateOkResponseAsync(itemBatchOperation)); mockedContext.Setup(c => c.CosmosSerializer).Returns(new CosmosJsonDotNetSerializer()); Uri link = new Uri($"/dbs/db/colls/colls", UriKind.Relative); Mock <ContainerCore> mockContainer = new Mock <ContainerCore>(); mockContainer.Setup(x => x.LinkUri).Returns(link); mockContainer.Setup(x => x.GetPartitionKeyDefinitionAsync(It.IsAny <CancellationToken>())).Returns(Task.FromResult(new PartitionKeyDefinition() { Paths = new Collection <string>() { "/id" } })); CollectionRoutingMap routingMap = CollectionRoutingMap.TryCreateCompleteRoutingMap( new[] { Tuple.Create(new PartitionKeyRange { Id = "0", MinInclusive = "", MaxExclusive = "FF" }, (ServiceIdentity)null) }, string.Empty); mockContainer.Setup(x => x.GetRoutingMapAsync(It.IsAny <CancellationToken>())).Returns(Task.FromResult(routingMap)); BatchAsyncContainerExecutor executor = new BatchAsyncContainerExecutor(mockContainer.Object, mockedContext.Object, 20, Constants.MaxDirectModeBatchRequestBodySizeInBytes, 1); BatchOperationResult result = await executor.AddAsync(itemBatchOperation); Mock.Get(mockContainer.Object) .Verify(x => x.GetPartitionKeyDefinitionAsync(It.IsAny <CancellationToken>()), Times.Once); Mock.Get(mockedContext.Object) .Verify(c => c.ProcessResourceOperationStreamAsync( It.IsAny <Uri>(), It.IsAny <ResourceType>(), It.IsAny <OperationType>(), It.IsAny <RequestOptions>(), It.IsAny <ContainerCore>(), It.IsAny <Cosmos.PartitionKey?>(), It.IsAny <Stream>(), It.IsAny <Action <RequestMessage> >(), It.IsAny <CancellationToken>()), Times.Once); Assert.AreEqual(HttpStatusCode.OK, result.StatusCode); }
public async Task RetryOnSplit() { ItemBatchOperation itemBatchOperation = CreateItem("test"); Mock <CosmosClientContext> mockedContext = new Mock <CosmosClientContext>(); mockedContext.Setup(c => c.ClientOptions).Returns(new CosmosClientOptions()); mockedContext .SetupSequence(c => c.ProcessResourceOperationStreamAsync( It.IsAny <Uri>(), It.IsAny <ResourceType>(), It.IsAny <OperationType>(), It.IsAny <RequestOptions>(), It.IsAny <ContainerCore>(), It.IsAny <Cosmos.PartitionKey?>(), It.IsAny <Stream>(), It.IsAny <Action <RequestMessage> >(), It.IsAny <CancellationToken>())) .Returns(this.GenerateSplitResponseAsync(itemBatchOperation)) .Returns(this.GenerateOkResponseAsync(itemBatchOperation)); mockedContext.Setup(c => c.CosmosSerializer).Returns(new CosmosJsonDotNetSerializer()); Uri link = new Uri($"/dbs/db/colls/colls", UriKind.Relative); Mock <ContainerCore> mockContainer = new Mock <ContainerCore>(); mockContainer.Setup(x => x.LinkUri).Returns(link); mockContainer.Setup(x => x.GetPartitionKeyDefinitionAsync(It.IsAny <CancellationToken>())).Returns(Task.FromResult(new PartitionKeyDefinition() { Paths = new Collection <string>() { "/id" } })); CollectionRoutingMap routingMap = CollectionRoutingMap.TryCreateCompleteRoutingMap( new[] { Tuple.Create(new PartitionKeyRange { Id = "0", MinInclusive = "", MaxExclusive = "FF" }, (ServiceIdentity)null) }, string.Empty); mockContainer.Setup(x => x.GetRoutingMapAsync(It.IsAny <CancellationToken>())).Returns(Task.FromResult(routingMap)); BatchAsyncContainerExecutor executor = new BatchAsyncContainerExecutor(mockContainer.Object, mockedContext.Object, 20, Constants.MaxDirectModeBatchRequestBodySizeInBytes, 1); BatchOperationResult result = await executor.AddAsync(itemBatchOperation); Mock.Get(mockContainer.Object) .Verify(x => x.GetPartitionKeyDefinitionAsync(It.IsAny <CancellationToken>()), Times.Exactly(2)); Mock.Get(mockedContext.Object) .Verify(c => c.ProcessResourceOperationStreamAsync( It.IsAny <Uri>(), It.IsAny <ResourceType>(), It.IsAny <OperationType>(), It.IsAny <RequestOptions>(), It.IsAny <ContainerCore>(), It.IsAny <Cosmos.PartitionKey?>(), It.IsAny <Stream>(), It.IsAny <Action <RequestMessage> >(), It.IsAny <CancellationToken>()), Times.Exactly(2)); Assert.AreEqual(HttpStatusCode.OK, result.StatusCode); Assert.IsNotNull(result.Diagnostics); int diagnosticsLines = 0; string diagnosticsString = result.Diagnostics.ToString(); int index = diagnosticsString.IndexOf(Environment.NewLine); while (index > -1) { diagnosticsLines++; index = diagnosticsString.IndexOf(Environment.NewLine, index + 1); } Assert.IsTrue(diagnosticsLines > 1, "Diagnostics might be missing"); }