public async Task ValidateInvalidRequestOptionsAsync() { BatchAsyncContainerExecutor executor = new BatchAsyncContainerExecutor(this.cosmosContainer, this.cosmosContainer.ClientContext, 20, Constants.MaxDirectModeBatchRequestBodySizeInBytes); string id = Guid.NewGuid().ToString(); MyDocument myDocument = new MyDocument() { id = id, Status = id }; await Assert.ThrowsExceptionAsync <InvalidOperationException>(() => executor.ValidateOperationAsync(new ItemBatchOperation(OperationType.Replace, 0, new Cosmos.PartitionKey(id), id, cosmosDefaultJsonSerializer.ToStream(myDocument)), new ItemRequestOptions() { SessionToken = "something" })); await Assert.ThrowsExceptionAsync <InvalidOperationException>(() => executor.ValidateOperationAsync( new ItemBatchOperation(OperationType.Replace, 0, new Cosmos.PartitionKey(id), id, cosmosDefaultJsonSerializer.ToStream(myDocument)), new ItemRequestOptions() { Properties = new Dictionary <string, object>() { { "test", "test" } } })); await Assert.ThrowsExceptionAsync <InvalidOperationException>(() => executor.ValidateOperationAsync( new ItemBatchOperation(OperationType.Replace, 0, new Cosmos.PartitionKey(id), id, cosmosDefaultJsonSerializer.ToStream(myDocument)), new ItemRequestOptions() { DedicatedGatewayRequestOptions = new DedicatedGatewayRequestOptions { MaxIntegratedCacheStaleness = TimeSpan.FromMinutes(3) } })); }
public async Task DoOperationsAsync() { BatchAsyncContainerExecutor executor = new BatchAsyncContainerExecutor(this.cosmosContainer, this.cosmosContainer.ClientContext, 20, Constants.MaxDirectModeBatchRequestBodySizeInBytes); List <Task <TransactionalBatchOperationResult> > tasks = new List <Task <TransactionalBatchOperationResult> >(); for (int i = 0; i < 100; i++) { tasks.Add(executor.AddAsync(CreateItem(i.ToString()), null, default(CancellationToken))); } await Task.WhenAll(tasks); for (int i = 0; i < 100; i++) { Task <TransactionalBatchOperationResult> task = tasks[i]; TransactionalBatchOperationResult result = await task; Assert.AreEqual(HttpStatusCode.Created, result.StatusCode); MyDocument document = cosmosDefaultJsonSerializer.FromStream <MyDocument>(result.ResourceStream); Assert.AreEqual(i.ToString(), document.id); ItemResponse <MyDocument> storedDoc = await this.cosmosContainer.ReadItemAsync <MyDocument>(i.ToString(), new Cosmos.PartitionKey(i.ToString())); Assert.IsNotNull(storedDoc.Resource); } executor.Dispose(); }
public async Task BatchOperationsTest(ConnectionMode mode) { Container container = await this.CreateClientAndContainer(mode, Microsoft.Azure.Cosmos.ConsistencyLevel.Eventual); // Client level consistency using (BatchAsyncContainerExecutor executor = new BatchAsyncContainerExecutor( (ContainerInlineCore)container, ((ContainerInlineCore)container).ClientContext, 20, Documents.Constants.MaxDirectModeBatchRequestBodySizeInBytes) ) { List <Task <TransactionalBatchOperationResult> > tasks = new List <Task <TransactionalBatchOperationResult> >(); for (int i = 0; i < 10; i++) { tasks.Add(executor.AddAsync(CreateItem(i.ToString()), NoOpTrace.Singleton, default)); } await Task.WhenAll(tasks); } IDictionary <string, long> expectedRecordCountInOperation = new Dictionary <string, long> { { Documents.OperationType.Batch.ToString(), 1 } }; await this.WaitAndAssert(expectedOperationCount : 2, expectedConsistencyLevel : Microsoft.Azure.Cosmos.ConsistencyLevel.Eventual, expectedOperationRecordCountMap : expectedRecordCountInOperation); }
public async Task SingleTaskScheduler_ExecutorTest() { CosmosClientContext context = this.MockClientContext(); DatabaseInternal db = new DatabaseInlineCore(context, "test"); List <Task <ContainerInternal> > tasks = new List <Task <ContainerInternal> >(); for (int i = 0; i < 20; i++) { tasks.Add( Task.Factory.StartNew(() => (ContainerInternal) new ContainerInlineCore(context, db, "test"), CancellationToken.None, TaskCreationOptions.None, new SingleTaskScheduler())); } await Task.WhenAll(tasks); BatchAsyncContainerExecutor firstExecutor = tasks[0].Result.BatchExecutor; Assert.IsNotNull(firstExecutor); for (int i = 1; i < 20; i++) { BatchAsyncContainerExecutor otherExecutor = tasks[i].Result.BatchExecutor; Assert.AreEqual(firstExecutor, otherExecutor); } }
public async Task ValidateInvalidDocumentSizeAsync() { BatchAsyncContainerExecutor executor = new BatchAsyncContainerExecutor(this.cosmosContainer, this.cosmosContainer.ClientContext, 50, 2); string id = Guid.NewGuid().ToString(); MyDocument myDocument = new MyDocument() { id = id, Status = id }; await Assert.ThrowsExceptionAsync <ArgumentException>(() => executor.ValidateOperationAsync(new ItemBatchOperation(OperationType.Replace, 0, new Cosmos.PartitionKey(id), id, cosmosDefaultJsonSerializer.ToStream(myDocument)))); }
public async Task ValidateInvalidRequestOptionsAsync() { BatchAsyncContainerExecutor executor = new BatchAsyncContainerExecutor(this.cosmosContainer, this.cosmosContainer.ClientContext, 20, Constants.MaxDirectModeBatchRequestBodySizeInBytes); string id = Guid.NewGuid().ToString(); MyDocument myDocument = new MyDocument() { id = id, Status = id }; await Assert.ThrowsExceptionAsync <InvalidOperationException>(() => executor.ValidateOperationAsync(new ItemBatchOperation(OperationType.Replace, 0, new Cosmos.PartitionKey(id), id, cosmosDefaultJsonSerializer.ToStream(myDocument)), new ItemRequestOptions() { SessionToken = "something" })); }
public async Task SingleTaskScheduler_ExecutorTest() { Mock <CosmosClient> mockClient = new Mock <CosmosClient>(); mockClient.Setup(x => x.Endpoint).Returns(new Uri("http://localhost")); CosmosClientContext context = new ClientContextCore( client: mockClient.Object, clientOptions: new CosmosClientOptions() { AllowBulkExecution = true }, userJsonSerializer: null, defaultJsonSerializer: null, sqlQuerySpecSerializer: null, cosmosResponseFactory: null, requestHandler: null, documentClient: null); DatabaseCore db = new DatabaseCore(context, "test"); List <Task <ContainerCore> > tasks = new List <Task <ContainerCore> >(); for (int i = 0; i < 20; i++) { tasks.Add( Task.Factory.StartNew(() => (ContainerCore)db.GetContainer("test"), CancellationToken.None, TaskCreationOptions.None, new SingleTaskScheduler())); } await Task.WhenAll(tasks); BatchAsyncContainerExecutor firstExecutor = tasks[0].Result.BatchExecutor; Assert.IsNotNull(firstExecutor); for (int i = 1; i < 20; i++) { BatchAsyncContainerExecutor otherExecutor = tasks[i].Result.BatchExecutor; Assert.AreEqual(firstExecutor, otherExecutor); } }
public async Task ConcurrentGet_ReturnsSameExecutorInstance() { Mock <CosmosClient> mockClient = new Mock <CosmosClient>(); mockClient.Setup(x => x.Endpoint).Returns(new Uri("http://localhost")); CosmosClientContext context = new ClientContextCore( client: mockClient.Object, clientOptions: new CosmosClientOptions() { AllowBulkExecution = true }, serializerCore: null, cosmosResponseFactory: null, requestHandler: null, documentClient: null, userAgent: null); DatabaseCore db = new DatabaseCore(context, "test"); List <Task <ContainerCore> > tasks = new List <Task <ContainerCore> >(); for (int i = 0; i < 20; i++) { tasks.Add(Task.Run(() => Task.FromResult(new ContainerCore(context, db, "test")))); } await Task.WhenAll(tasks); BatchAsyncContainerExecutor firstExecutor = tasks[0].Result.BatchExecutor; Assert.IsNotNull(firstExecutor); for (int i = 1; i < 20; i++) { BatchAsyncContainerExecutor otherExecutor = tasks[i].Result.BatchExecutor; Assert.AreEqual(firstExecutor, otherExecutor); } }
public async Task BatchOperationsTest(ConnectionMode mode) { Container container = await this.GetContainer(mode); using (BatchAsyncContainerExecutor executor = new BatchAsyncContainerExecutor( (ContainerInlineCore)container, ((ContainerInlineCore)container).ClientContext, 20, Documents.Constants.MaxDirectModeBatchRequestBodySizeInBytes) ) { List <Task <TransactionalBatchOperationResult> > tasks = new List <Task <TransactionalBatchOperationResult> >(); for (int i = 0; i < 10; i++) { tasks.Add(executor.AddAsync(CreateItem(i.ToString()), NoOpTrace.Singleton, default)); } await Task.WhenAll(tasks); } await this.WaitAndAssert(2); }
public async Task ConcurrentGet_ReturnsSameExecutorInstance() { CosmosClientContext context = this.MockClientContext(); DatabaseInternal db = new DatabaseInlineCore(context, "test"); List <Task <ContainerInternal> > tasks = new List <Task <ContainerInternal> >(); for (int i = 0; i < 20; i++) { tasks.Add(Task.Run(() => Task.FromResult((ContainerInternal) new ContainerInlineCore(context, db, "test")))); } await Task.WhenAll(tasks); BatchAsyncContainerExecutor firstExecutor = tasks[0].Result.BatchExecutor; Assert.IsNotNull(firstExecutor); for (int i = 1; i < 20; i++) { BatchAsyncContainerExecutor otherExecutor = tasks[i].Result.BatchExecutor; Assert.AreEqual(firstExecutor, otherExecutor); } }
public async Task RetryOnNameStale() { 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 <string>(), It.IsAny <ResourceType>(), It.IsAny <OperationType>(), It.IsAny <RequestOptions>(), It.IsAny <ContainerInternal>(), It.IsAny <Cosmos.PartitionKey?>(), It.IsAny <Stream>(), It.IsAny <Action <RequestMessage> >(), It.IsAny <CosmosDiagnosticsContext>(), It.IsAny <ITrace>(), It.IsAny <CancellationToken>())) .Returns(this.GenerateCacheStaleResponseAsync(itemBatchOperation)) .Returns(this.GenerateOkResponseAsync(itemBatchOperation)); mockedContext.Setup(c => c.SerializerCore).Returns(MockCosmosUtil.Serializer); string link = "/dbs/db/colls/colls"; Mock <ContainerInternal> mockContainer = new Mock <ContainerInternal>(); 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, BatchAsyncContainerExecutorCache.DefaultMaxBulkRequestBodySizeInBytes); TransactionalBatchOperationResult 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 <string>(), It.IsAny <ResourceType>(), It.IsAny <OperationType>(), It.IsAny <RequestOptions>(), It.IsAny <ContainerInternal>(), It.IsAny <Cosmos.PartitionKey?>(), It.IsAny <Stream>(), It.IsAny <Action <RequestMessage> >(), It.IsAny <CosmosDiagnosticsContext>(), It.IsAny <ITrace>(), It.IsAny <CancellationToken>()), Times.Exactly(2)); Assert.AreEqual(HttpStatusCode.OK, result.StatusCode); Assert.IsNotNull(result.DiagnosticsContext); string diagnosticsString = result.DiagnosticsContext.ToString(); Assert.IsTrue(diagnosticsString.Contains("PointOperationStatistics"), "Diagnostics might be missing"); }
public async Task RetryOnSplit() { ItemBatchOperation itemBatchOperation = CreateItem("test"); Mock <CosmosClientContext> mockedContext = this.MockClientContext(); mockedContext.Setup(c => c.ClientOptions).Returns(new CosmosClientOptions()); mockedContext .SetupSequence(c => c.ProcessResourceOperationStreamAsync( It.IsAny <string>(), It.IsAny <ResourceType>(), It.IsAny <OperationType>(), It.IsAny <RequestOptions>(), It.IsAny <ContainerInternal>(), It.IsAny <Cosmos.FeedRange>(), It.IsAny <Stream>(), It.IsAny <Action <RequestMessage> >(), It.IsAny <ITrace>(), It.IsAny <CancellationToken>())) .Returns(GenerateSplitResponseAsync(itemBatchOperation)) .Returns(GenerateOkResponseAsync(itemBatchOperation)); mockedContext.Setup(c => c.SerializerCore).Returns(MockCosmosUtil.Serializer); string link = "/dbs/db/colls/colls"; Mock <ContainerInternal> mockContainer = new Mock <ContainerInternal>(); mockContainer.Setup(x => x.LinkUri).Returns(link); mockContainer.Setup(x => x.GetCachedContainerPropertiesAsync(It.IsAny <bool>(), It.IsAny <ITrace>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(new ContainerProperties() { PartitionKey = new PartitionKeyDefinition() { Paths = new Collection <string>() { "/id" } } })); Mock <CosmosClientContext> context = this.MockClientContext(); mockContainer.Setup(c => c.ClientContext).Returns(context.Object); context.Setup(c => c.DocumentClient).Returns(new ClientWithSplitDetection()); 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, BatchAsyncContainerExecutorCache.DefaultMaxBulkRequestBodySizeInBytes); TransactionalBatchOperationResult result = await executor.AddAsync(itemBatchOperation, NoOpTrace.Singleton); Mock.Get(mockContainer.Object) .Verify(x => x.GetCachedContainerPropertiesAsync(It.IsAny <bool>(), It.IsAny <ITrace>(), It.IsAny <CancellationToken>()), Times.Exactly(2)); Mock.Get(mockedContext.Object) .Verify(c => c.ProcessResourceOperationStreamAsync( It.IsAny <string>(), It.IsAny <ResourceType>(), It.IsAny <OperationType>(), It.IsAny <RequestOptions>(), It.IsAny <ContainerInternal>(), It.IsAny <Cosmos.FeedRange>(), It.IsAny <Stream>(), It.IsAny <Action <RequestMessage> >(), It.IsAny <ITrace>(), It.IsAny <CancellationToken>()), Times.Exactly(2)); Assert.AreEqual(HttpStatusCode.OK, result.StatusCode); Assert.IsNotNull(result.ToResponseMessage().Trace); }
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 <ContainerInternal>(), It.IsAny <Cosmos.PartitionKey?>(), It.IsAny <Stream>(), It.IsAny <Action <RequestMessage> >(), It.IsAny <CosmosDiagnosticsContext>(), It.IsAny <CancellationToken>())) .Returns(this.GenerateOkResponseAsync(itemBatchOperation)); mockedContext.Setup(c => c.SerializerCore).Returns(MockCosmosUtil.Serializer); Uri link = new Uri($"/dbs/db/colls/colls", UriKind.Relative); Mock <ContainerInternal> mockContainer = new Mock <ContainerInternal>(); 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); TransactionalBatchOperationResult 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 <ContainerInternal>(), It.IsAny <Cosmos.PartitionKey?>(), It.IsAny <Stream>(), It.IsAny <Action <RequestMessage> >(), It.IsAny <CosmosDiagnosticsContext>(), 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); TransactionalBatchOperationResult 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"); }