public async Task RetrierGetsCalledOn413_OnWrite()
        {
            IDocumentClientRetryPolicy retryPolicy1 = new BulkExecutionRetryPolicy(
                GetSplitEnabledContainer(),
                OperationType.Create,
                new ResourceThrottleRetryPolicy(1));

            IDocumentClientRetryPolicy retryPolicy2 = new BulkExecutionRetryPolicy(
                GetSplitEnabledContainer(),
                OperationType.Create,
                new ResourceThrottleRetryPolicy(1));

            ItemBatchOperation operation1 = this.CreateItemBatchOperation();
            ItemBatchOperation operation2 = this.CreateItemBatchOperation();

            operation1.AttachContext(new ItemBatchOperationContext(string.Empty, NoOpTrace.Singleton, retryPolicy1));
            operation2.AttachContext(new ItemBatchOperationContext(string.Empty, NoOpTrace.Singleton, retryPolicy2));

            Mock <BatchAsyncBatcherRetryDelegate> retryDelegate = new Mock <BatchAsyncBatcherRetryDelegate>();

            BatchAsyncBatcher batchAsyncBatcher = new BatchAsyncBatcher(2, 1000, MockCosmosUtil.Serializer, this.ExecutorWith413, retryDelegate.Object, BatchAsyncBatcherTests.MockClientContext());

            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.Never);
            retryDelegate.Verify(a => a(It.IsAny <ItemBatchOperation>(), It.IsAny <CancellationToken>()), Times.Never);
        }
 public BatchAsyncBatcherThatOverflows(
     int maxBatchOperationCount,
     int maxBatchByteSize,
     CosmosSerializerCore serializerCore,
     BatchAsyncBatcherExecuteDelegate executor,
     BatchAsyncBatcherRetryDelegate retrier) : base(maxBatchOperationCount, maxBatchByteSize, serializerCore, executor, retrier, BatchAsyncBatcherTests.MockClientContext())
 {
 }
        public void IsNotEmptyWithOperations()
        {
            BatchAsyncBatcher batchAsyncBatcher = new BatchAsyncBatcher(1, 1000, MockCosmosUtil.Serializer, this.Executor, this.Retrier, BatchAsyncBatcherTests.MockClientContext());

            Assert.IsTrue(batchAsyncBatcher.TryAdd(this.CreateItemBatchOperation(true)));
            Assert.IsFalse(batchAsyncBatcher.IsEmpty);
        }
        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, NoOpTrace.Singleton));
            Assert.IsTrue(batchAsyncBatcher.TryAdd(operation));
            await batchAsyncBatcher.DispatchAsync(metric);

            Assert.IsFalse(batchAsyncBatcher.TryAdd(this.CreateItemBatchOperation()));
        }
        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 IsEmptyWithNoOperations()
        {
            BatchAsyncBatcher batchAsyncBatcher = new BatchAsyncBatcher(10, 1000, MockCosmosUtil.Serializer, this.Executor, this.Retrier, BatchAsyncBatcherTests.MockClientContext());

            Assert.IsTrue(batchAsyncBatcher.IsEmpty);
        }
        public async Task DispatchProcessInOrderAsync()
        {
            BatchAsyncBatcher         batchAsyncBatcher = 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: OperationType.Create,
                    operationIndex: i,
                    partitionKey: new Cosmos.PartitionKey(i.ToString()),
                    id: 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);

            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 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 HasFixedByteSize()
        {
            ItemBatchOperation itemBatchOperation = this.CreateItemBatchOperation(true);
            await itemBatchOperation.MaterializeResourceAsync(MockCosmosUtil.Serializer, default);

            // Each operation is 2 bytes
            BatchAsyncBatcher batchAsyncBatcher = new BatchAsyncBatcher(3, 4, MockCosmosUtil.Serializer, this.Executor, this.Retrier, BatchAsyncBatcherTests.MockClientContext());

            Assert.IsTrue(batchAsyncBatcher.TryAdd(itemBatchOperation));
            Assert.IsTrue(batchAsyncBatcher.TryAdd(itemBatchOperation));
            Assert.IsFalse(batchAsyncBatcher.TryAdd(itemBatchOperation));
        }
 public void ValidatesSerializer()
 {
     _ = new BatchAsyncBatcher(1, 1, null, this.Executor, this.Retrier, BatchAsyncBatcherTests.MockClientContext());
 }
 public void ValidatesByteSize(int size)
 {
     _ = new BatchAsyncBatcher(1, size, MockCosmosUtil.Serializer, this.Executor, this.Retrier, BatchAsyncBatcherTests.MockClientContext());
 }