public async Task CannotAddToDispatchedBatch() { BatchAsyncBatcher batchAsyncBatcher = new BatchAsyncBatcher(1, 1000, new CosmosJsonDotNetSerializer(), this.Executor, this.Retrier); ItemBatchOperation operation = this.CreateItemBatchOperation(); operation.AttachContext(new ItemBatchOperationContext(string.Empty)); Assert.IsTrue(batchAsyncBatcher.TryAdd(operation)); await batchAsyncBatcher.DispatchAsync(); Assert.IsFalse(batchAsyncBatcher.TryAdd(this.CreateItemBatchOperation())); }
public void TaskIsCreatedOnInitialization() { ItemBatchOperation operation = new ItemBatchOperation(OperationType.Create, 0, Cosmos.PartitionKey.Null); ItemBatchOperationContext batchAsyncOperationContext = new ItemBatchOperationContext(string.Empty); operation.AttachContext(batchAsyncOperationContext); Assert.IsNotNull(batchAsyncOperationContext.OperationTask); Assert.AreEqual(batchAsyncOperationContext, operation.Context); Assert.AreEqual(TaskStatus.WaitingForActivation, batchAsyncOperationContext.OperationTask.Status); }
private ItemBatchOperation CreateItemBatchOperation(bool withContext = false) { ItemBatchOperation operation = new ItemBatchOperation(OperationType.Create, 0, string.Empty, new MemoryStream(new byte[] { 0x41, 0x42 }, index: 0, count: 2, writable: false, publiclyVisible: true)); if (withContext) { operation.AttachContext(new ItemBatchOperationContext(string.Empty)); } return(operation); }
public async Task CannotAddToDispatchedBatch() { BatchAsyncBatcher batchAsyncBatcher = new BatchAsyncBatcher(1, 1000, MockCosmosUtil.Serializer, this.Executor, this.Retrier, BatchAsyncBatcherTests.MockClientContext()); ItemBatchOperation operation = this.CreateItemBatchOperation(); operation.AttachContext(new ItemBatchOperationContext(string.Empty)); Assert.IsTrue(batchAsyncBatcher.TryAdd(operation)); await batchAsyncBatcher.DispatchAsync(metric); Assert.IsFalse(batchAsyncBatcher.TryAdd(this.CreateItemBatchOperation())); }
public async Task ShouldRetry_WithPolicy_On429() { IDocumentClientRetryPolicy retryPolicy = new BulkPartitionKeyRangeGoneRetryPolicy( new ResourceThrottleRetryPolicy(1)); TransactionalBatchOperationResult result = new TransactionalBatchOperationResult((HttpStatusCode)StatusCodes.TooManyRequests); ItemBatchOperation operation = new ItemBatchOperation(OperationType.Create, 0, Cosmos.PartitionKey.Null); operation.AttachContext(new ItemBatchOperationContext(string.Empty, retryPolicy)); ShouldRetryResult shouldRetryResult = await operation.Context.ShouldRetryAsync(result, default(CancellationToken)); Assert.IsTrue(shouldRetryResult.ShouldRetry); }
public async Task ShouldRetry_WithPolicy_OnSuccess() { IDocumentClientRetryPolicy retryPolicy = new BulkPartitionKeyRangeGoneRetryPolicy( new ResourceThrottleRetryPolicy(1)); BatchOperationResult result = new BatchOperationResult(HttpStatusCode.OK); ItemBatchOperation operation = new ItemBatchOperation(OperationType.Create, 0); operation.AttachContext(new ItemBatchOperationContext(string.Empty, retryPolicy)); ShouldRetryResult shouldRetryResult = await operation.Context.ShouldRetryAsync(result, default(CancellationToken)); Assert.IsFalse(shouldRetryResult.ShouldRetry); }
public async Task DispatchWithLessResponses() { BatchAsyncBatcher batchAsyncBatcher = new BatchAsyncBatcher(10, 1000, MockCosmosUtil.Serializer, this.ExecutorWithLessResponses, this.Retrier, BatchAsyncBatcherTests.MockClientContext()); BatchAsyncBatcher secondAsyncBatcher = new BatchAsyncBatcher(10, 1000, MockCosmosUtil.Serializer, this.Executor, this.Retrier, BatchAsyncBatcherTests.MockClientContext()); List <ItemBatchOperation> operations = new List <ItemBatchOperation>(10); for (int i = 0; i < 10; i++) { ItemBatchOperation operation = new ItemBatchOperation(OperationType.Create, i, Cosmos.PartitionKey.Null, i.ToString()); ItemBatchOperationContext context = new ItemBatchOperationContext(string.Empty, NoOpTrace.Singleton); operation.AttachContext(context); operations.Add(operation); Assert.IsTrue(batchAsyncBatcher.TryAdd(operation)); } await batchAsyncBatcher.DispatchAsync(metric); // Responses 1 and 10 should be missing for (int i = 0; i < 10; i++) { ItemBatchOperation operation = operations[i]; // Some tasks should not be resolved if (i == 0 || i == 9) { Assert.IsTrue(operation.Context.OperationTask.Status == TaskStatus.WaitingForActivation); } else { Assert.IsTrue(operation.Context.OperationTask.Status == TaskStatus.RanToCompletion); } if (operation.Context.OperationTask.Status == TaskStatus.RanToCompletion) { TransactionalBatchOperationResult result = await operation.Context.OperationTask; Assert.AreEqual(i.ToString(), result.ETag); } else { // Pass the pending one to another batcher Assert.IsTrue(secondAsyncBatcher.TryAdd(operation)); } } await secondAsyncBatcher.DispatchAsync(metric); // All tasks should be completed for (int i = 0; i < 10; i++) { ItemBatchOperation operation = operations[i]; Assert.AreEqual(TaskStatus.RanToCompletion, operation.Context.OperationTask.Status); TransactionalBatchOperationResult result = await operation.Context.OperationTask; Assert.AreEqual(i.ToString(), result.ETag); } }
public void PartitionKeyRangeIdIsSetOnInitialization() { string expectedPkRangeId = Guid.NewGuid().ToString(); ItemBatchOperation operation = new ItemBatchOperation(OperationType.Create, 0); ItemBatchOperationContext batchAsyncOperationContext = new ItemBatchOperationContext(expectedPkRangeId); operation.AttachContext(batchAsyncOperationContext); Assert.IsNotNull(batchAsyncOperationContext.OperationTask); Assert.AreEqual(batchAsyncOperationContext, operation.Context); Assert.AreEqual(expectedPkRangeId, batchAsyncOperationContext.PartitionKeyRangeId); Assert.AreEqual(TaskStatus.WaitingForActivation, batchAsyncOperationContext.OperationTask.Status); }
public async Task ShouldRetry_WithPolicy_OnSuccess() { IDocumentClientRetryPolicy retryPolicy = new BulkPartitionKeyRangeGoneRetryPolicy( Mock.Of <ContainerInternal>(), new ResourceThrottleRetryPolicy(1)); TransactionalBatchOperationResult result = new TransactionalBatchOperationResult(HttpStatusCode.OK); ItemBatchOperation operation = new ItemBatchOperation(OperationType.Create, 0, Cosmos.PartitionKey.Null); operation.AttachContext(new ItemBatchOperationContext(string.Empty, retryPolicy)); ShouldRetryResult shouldRetryResult = await operation.Context.ShouldRetryAsync(result, default); Assert.IsFalse(shouldRetryResult.ShouldRetry); }
public async Task ShouldRetry_WithPolicy_On413_OnRead() { IDocumentClientRetryPolicy retryPolicy = new BulkExecutionRetryPolicy( Mock.Of <ContainerInternal>(), OperationType.Read, new ResourceThrottleRetryPolicy(1)); TransactionalBatchOperationResult result = new TransactionalBatchOperationResult(HttpStatusCode.RequestEntityTooLarge); ItemBatchOperation operation = new ItemBatchOperation(OperationType.Create, 0, Cosmos.PartitionKey.Null); operation.AttachContext(new ItemBatchOperationContext(string.Empty, retryPolicy)); ShouldRetryResult shouldRetryResult = await operation.Context.ShouldRetryAsync(result, default); Assert.IsTrue(shouldRetryResult.ShouldRetry); }
public async Task TaskResultIsSetOnCompleteAsync() { ItemBatchOperation operation = new ItemBatchOperation(OperationType.Create, 0, Cosmos.PartitionKey.Null); ItemBatchOperationContext batchAsyncOperationContext = new ItemBatchOperationContext(string.Empty, NoOpTrace.Singleton); operation.AttachContext(batchAsyncOperationContext); TransactionalBatchOperationResult expected = new TransactionalBatchOperationResult(HttpStatusCode.OK); batchAsyncOperationContext.Complete(null, expected); Assert.AreEqual(expected, await batchAsyncOperationContext.OperationTask); Assert.AreEqual(TaskStatus.RanToCompletion, batchAsyncOperationContext.OperationTask.Status); }
public async Task TaskResultIsSetOnCompleteAsync() { ItemBatchOperation operation = new ItemBatchOperation(OperationType.Create, 0); ItemBatchOperationContext batchAsyncOperationContext = new ItemBatchOperationContext(string.Empty); operation.AttachContext(batchAsyncOperationContext); BatchOperationResult expected = new BatchOperationResult(HttpStatusCode.OK); batchAsyncOperationContext.Complete(null, expected); Assert.AreEqual(expected, await batchAsyncOperationContext.OperationTask); Assert.AreEqual(TaskStatus.RanToCompletion, batchAsyncOperationContext.OperationTask.Status); }
public async Task ExceptionIsSetOnFailAsync() { Exception failure = new Exception("It failed"); ItemBatchOperation operation = new ItemBatchOperation(OperationType.Create, 0); ItemBatchOperationContext batchAsyncOperationContext = new ItemBatchOperationContext(string.Empty); operation.AttachContext(batchAsyncOperationContext); batchAsyncOperationContext.Fail(null, failure); Exception capturedException = await Assert.ThrowsExceptionAsync <Exception>(() => batchAsyncOperationContext.OperationTask); Assert.AreEqual(failure, capturedException); Assert.AreEqual(TaskStatus.Faulted, batchAsyncOperationContext.OperationTask.Status); }
public async Task ShouldRetry_WithPolicy_OnCompletingPartitionMigration() { IDocumentClientRetryPolicy retryPolicy = new BulkPartitionKeyRangeGoneRetryPolicy( new ResourceThrottleRetryPolicy(1)); TransactionalBatchOperationResult result = new TransactionalBatchOperationResult(HttpStatusCode.Gone) { SubStatusCode = SubStatusCodes.CompletingPartitionMigration }; ItemBatchOperation operation = new ItemBatchOperation(OperationType.Create, 0, Cosmos.PartitionKey.Null); operation.AttachContext(new ItemBatchOperationContext(string.Empty, retryPolicy)); ShouldRetryResult shouldRetryResult = await operation.Context.ShouldRetryAsync(result, default); Assert.IsTrue(shouldRetryResult.ShouldRetry); }
private ItemBatchOperation CreateItemBatchOperation(bool withContext = false) { ItemBatchOperation operation = new ItemBatchOperation( operationType: OperationType.Create, operationIndex: 0, partitionKey: Cosmos.PartitionKey.Null, id: string.Empty, resourceStream: new MemoryStream(new byte[] { 0x41, 0x42 }, index: 0, count: 2, writable: false, publiclyVisible: true)); if (withContext) { operation.AttachContext(new ItemBatchOperationContext(string.Empty, NoOpTrace.Singleton)); } return(operation); }
public async Task ShouldRetry_WithPolicy_OnCompletingSplit() { IDocumentClientRetryPolicy retryPolicy = new BulkExecutionRetryPolicy( GetSplitEnabledContainer(), OperationType.Read, new ResourceThrottleRetryPolicy(1)); TransactionalBatchOperationResult result = new TransactionalBatchOperationResult(HttpStatusCode.Gone) { SubStatusCode = SubStatusCodes.CompletingSplit }; ItemBatchOperation operation = new ItemBatchOperation(OperationType.Create, 0, Cosmos.PartitionKey.Null); operation.AttachContext(new ItemBatchOperationContext(string.Empty, NoOpTrace.Singleton, retryPolicy)); ShouldRetryResult shouldRetryResult = await operation.Context.ShouldRetryAsync(result, default); Assert.IsTrue(shouldRetryResult.ShouldRetry); }
public async Task ExceptionsFailOperationsAsync() { BatchAsyncBatcher batchAsyncBatcher = new BatchAsyncBatcher(2, 1000, MockCosmosUtil.Serializer, this.ExecutorWithFailure, this.Retrier, BatchAsyncBatcherTests.MockClientContext()); ItemBatchOperation operation1 = this.CreateItemBatchOperation(); ItemBatchOperation operation2 = this.CreateItemBatchOperation(); ItemBatchOperationContext context1 = new ItemBatchOperationContext(string.Empty, NoOpTrace.Singleton); operation1.AttachContext(context1); ItemBatchOperationContext context2 = new ItemBatchOperationContext(string.Empty, NoOpTrace.Singleton); operation2.AttachContext(context2); batchAsyncBatcher.TryAdd(operation1); batchAsyncBatcher.TryAdd(operation2); await batchAsyncBatcher.DispatchAsync(metric); Assert.AreEqual(TaskStatus.Faulted, context1.OperationTask.Status); Assert.AreEqual(TaskStatus.Faulted, context2.OperationTask.Status); Assert.AreEqual(expectedException, context1.OperationTask.Exception.InnerException); Assert.AreEqual(expectedException, context2.OperationTask.Exception.InnerException); }
public async Task ExceptionsFailOperationsAsync() { BatchAsyncBatcher batchAsyncBatcher = new BatchAsyncBatcher(2, 1000, new CosmosJsonDotNetSerializer(), this.ExecutorWithFailure, this.Retrier); ItemBatchOperation operation1 = this.CreateItemBatchOperation(); ItemBatchOperation operation2 = this.CreateItemBatchOperation(); ItemBatchOperationContext context1 = new ItemBatchOperationContext(string.Empty); operation1.AttachContext(context1); ItemBatchOperationContext context2 = new ItemBatchOperationContext(string.Empty); operation2.AttachContext(context2); batchAsyncBatcher.TryAdd(operation1); batchAsyncBatcher.TryAdd(operation2); await batchAsyncBatcher.DispatchAsync(); Assert.AreEqual(TaskStatus.Faulted, context1.OperationTask.Status); Assert.AreEqual(TaskStatus.Faulted, context2.OperationTask.Status); Assert.AreEqual(expectedException, context1.OperationTask.Exception.InnerException); Assert.AreEqual(expectedException, context2.OperationTask.Exception.InnerException); }
public async Task RetrierGetsCalledOnSplit() { ItemBatchOperation operation1 = this.CreateItemBatchOperation(); ItemBatchOperation operation2 = this.CreateItemBatchOperation(); operation1.AttachContext(new ItemBatchOperationContext(string.Empty)); operation2.AttachContext(new ItemBatchOperationContext(string.Empty)); Mock <BatchAsyncBatcherRetryDelegate> retryDelegate = new Mock <BatchAsyncBatcherRetryDelegate>(); BatchAsyncBatcher batchAsyncBatcher = new BatchAsyncBatcher(2, 1000, new CosmosJsonDotNetSerializer(), this.ExecutorWithSplit, retryDelegate.Object); Assert.IsTrue(batchAsyncBatcher.TryAdd(operation1)); Assert.IsTrue(batchAsyncBatcher.TryAdd(operation2)); await batchAsyncBatcher.DispatchAsync(); retryDelegate.Verify(a => a(It.Is <ItemBatchOperation>(o => o == operation1), It.IsAny <CancellationToken>()), Times.Once); retryDelegate.Verify(a => a(It.Is <ItemBatchOperation>(o => o == operation2), It.IsAny <CancellationToken>()), Times.Once); retryDelegate.Verify(a => a(It.IsAny <ItemBatchOperation>(), It.IsAny <CancellationToken>()), Times.Exactly(2)); }
public async Task TraceIsJoinedOnCompletionWithRetry() { IDocumentClientRetryPolicy retryPolicy = new BulkExecutionRetryPolicy( Mock.Of <ContainerInternal>(), OperationType.Read, new ResourceThrottleRetryPolicy(1)); Trace rootTrace = Trace.GetRootTrace(name: "RootTrace"); ItemBatchOperation operation = new ItemBatchOperation(OperationType.Create, 0, Cosmos.PartitionKey.Null); // Start with the base trace ItemBatchOperationContext batchAsyncOperationContext = new ItemBatchOperationContext(Guid.NewGuid().ToString(), rootTrace, retryPolicy); operation.AttachContext(batchAsyncOperationContext); // Simulate a retry scenario that should append to the context traces Trace retryTrace = Trace.GetRootTrace(name: "TransportTrace"); TransactionalBatchOperationResult retryResult = new TransactionalBatchOperationResult(HttpStatusCode.TooManyRequests) { Trace = retryTrace }; ShouldRetryResult shouldRetryResult = await batchAsyncOperationContext.ShouldRetryAsync(retryResult, default); Assert.IsTrue(shouldRetryResult.ShouldRetry); // Simulate the completion that should append to the context traces Trace transportTrace = Trace.GetRootTrace(name: "TransportTrace"); TransactionalBatchOperationResult result = new TransactionalBatchOperationResult(HttpStatusCode.OK) { Trace = transportTrace }; batchAsyncOperationContext.Complete(null, result); Assert.AreEqual(result, await batchAsyncOperationContext.OperationTask); Assert.AreEqual(2, result.Trace.Children.Count, "The final trace should have the initial trace, plus the retries, plus the final trace"); Assert.AreEqual(rootTrace, result.Trace, "The first trace child should be the initial root"); Assert.AreEqual(retryTrace, result.Trace.Children[0], "The second trace child should be the one from the retry"); Assert.AreEqual(transportTrace, result.Trace.Children[1], "The third trace child should be the one from the final result"); }
public async Task RetrierGetsCalledOnOverFlow() { ItemBatchOperation operation1 = this.CreateItemBatchOperation(); ItemBatchOperation operation2 = this.CreateItemBatchOperation(); operation1.AttachContext(new ItemBatchOperationContext(string.Empty, NoOpTrace.Singleton)); operation2.AttachContext(new ItemBatchOperationContext(string.Empty, NoOpTrace.Singleton)); Mock <BatchAsyncBatcherRetryDelegate> retryDelegate = new Mock <BatchAsyncBatcherRetryDelegate>(); Mock <BatchAsyncBatcherExecuteDelegate> executeDelegate = new Mock <BatchAsyncBatcherExecuteDelegate>(); BatchAsyncBatcherThatOverflows batchAsyncBatcher = new BatchAsyncBatcherThatOverflows(2, 1000, MockCosmosUtil.Serializer, executeDelegate.Object, retryDelegate.Object); Assert.IsTrue(batchAsyncBatcher.TryAdd(operation1)); Assert.IsTrue(batchAsyncBatcher.TryAdd(operation2)); await batchAsyncBatcher.DispatchAsync(metric); retryDelegate.Verify(a => a(It.Is <ItemBatchOperation>(o => o == operation1), It.IsAny <CancellationToken>()), Times.Never); retryDelegate.Verify(a => a(It.Is <ItemBatchOperation>(o => o == operation2), It.IsAny <CancellationToken>()), Times.Once); retryDelegate.Verify(a => a(It.IsAny <ItemBatchOperation>(), It.IsAny <CancellationToken>()), Times.Once); }
public async Task RetrierGetsCalledOn413_NoSubstatus() { IDocumentClientRetryPolicy retryPolicy1 = new BulkExecutionRetryPolicy( GetSplitEnabledContainer(), OperationType.Read, new ResourceThrottleRetryPolicy(1)); IDocumentClientRetryPolicy retryPolicy2 = new BulkExecutionRetryPolicy( GetSplitEnabledContainer(), OperationType.Read, new ResourceThrottleRetryPolicy(1)); IDocumentClientRetryPolicy retryPolicy3 = new BulkExecutionRetryPolicy( GetSplitEnabledContainer(), OperationType.Create, new ResourceThrottleRetryPolicy(1)); ItemBatchOperation operation1 = this.CreateItemBatchOperation(); ItemBatchOperation operation2 = this.CreateItemBatchOperation(); ItemBatchOperation operation3 = this.CreateItemBatchOperation(); operation1.AttachContext(new ItemBatchOperationContext(string.Empty, NoOpTrace.Singleton, retryPolicy1)); operation2.AttachContext(new ItemBatchOperationContext(string.Empty, NoOpTrace.Singleton, retryPolicy2)); operation3.AttachContext(new ItemBatchOperationContext(string.Empty, NoOpTrace.Singleton, retryPolicy3)); Mock <BatchAsyncBatcherRetryDelegate> retryDelegate = new Mock <BatchAsyncBatcherRetryDelegate>(); BatchAsyncBatcher batchAsyncBatcher = new BatchAsyncBatcher(3, 1000, MockCosmosUtil.Serializer, this.ExecutorWith413, retryDelegate.Object, BatchAsyncBatcherTests.MockClientContext()); Assert.IsTrue(batchAsyncBatcher.TryAdd(operation1)); Assert.IsTrue(batchAsyncBatcher.TryAdd(operation2)); Assert.IsTrue(batchAsyncBatcher.TryAdd(operation3)); await batchAsyncBatcher.DispatchAsync(metric); retryDelegate.Verify(a => a(It.Is <ItemBatchOperation>(o => o == operation1), It.IsAny <CancellationToken>()), Times.Never); retryDelegate.Verify(a => a(It.Is <ItemBatchOperation>(o => o == operation2), It.IsAny <CancellationToken>()), Times.Never); retryDelegate.Verify(a => a(It.Is <ItemBatchOperation>(o => o == operation3), It.IsAny <CancellationToken>()), Times.Never); retryDelegate.Verify(a => a(It.IsAny <ItemBatchOperation>(), It.IsAny <CancellationToken>()), Times.Never); }
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); } }