public async Task ShouldReturnNotModifiedAfterCyclingOnAllRanges() { // Setting mock to have 3 ranges, this test will get a 304 on all 3 ranges, do 3 backend requests, and return a 304 MultiRangeMockDocumentClient documentClient = new MultiRangeMockDocumentClient(); using CosmosClient client = MockCosmosUtil.CreateMockCosmosClient(); Mock <CosmosClientContext> mockContext = new Mock <CosmosClientContext>(); mockContext.Setup(x => x.ClientOptions).Returns(MockCosmosUtil.GetDefaultConfiguration()); mockContext.Setup(x => x.DocumentClient).Returns(documentClient); mockContext.Setup(x => x.SerializerCore).Returns(MockCosmosUtil.Serializer); mockContext.Setup(x => x.Client).Returns(client); mockContext.Setup(x => x.CreateLink(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>())).Returns("/dbs/test/colls/test"); ResponseMessage firstResponse = new ResponseMessage(HttpStatusCode.NotModified); firstResponse.Headers.ETag = "FirstContinuation"; ResponseMessage secondResponse = new ResponseMessage(HttpStatusCode.NotModified); secondResponse.Headers.ETag = "SecondContinuation"; ResponseMessage thirdResponse = new ResponseMessage(HttpStatusCode.NotModified); thirdResponse.Headers.ETag = "ThirdContinuation"; mockContext.SetupSequence(x => x.ProcessResourceOperationAsync <ResponseMessage>( It.IsAny <string>(), It.IsAny <Documents.ResourceType>(), It.IsAny <Documents.OperationType>(), It.IsAny <RequestOptions>(), It.IsAny <ContainerInternal>(), It.IsAny <Cosmos.FeedRange>(), It.IsAny <Stream>(), It.IsAny <Action <RequestMessage> >(), It.IsAny <Func <ResponseMessage, ResponseMessage> >(), It.IsAny <ITrace>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(firstResponse)) .Returns(Task.FromResult(secondResponse)) .Returns(Task.FromResult(thirdResponse)); DatabaseInternal databaseCore = new DatabaseInlineCore(mockContext.Object, "mydb"); StandByFeedIteratorCore iterator = new StandByFeedIteratorCore( mockContext.Object, new ContainerInlineCore(mockContext.Object, databaseCore, "myColl"), null, 10, new StandByFeedIteratorRequestOptions()); ResponseMessage firstRequest = await iterator.ReadNextAsync(); Assert.IsTrue(firstRequest.Headers.ContinuationToken.Contains(firstResponse.Headers.ETag), "Response should contain the first continuation"); Assert.IsTrue(firstRequest.Headers.ContinuationToken.Contains(secondResponse.Headers.ETag), "Response should contain the second continuation"); Assert.IsTrue(firstRequest.Headers.ContinuationToken.Contains(thirdResponse.Headers.ETag), "Response should contain the third continuation"); Assert.AreEqual(HttpStatusCode.NotModified, firstRequest.StatusCode); mockContext.Verify(x => x.ProcessResourceOperationAsync <ResponseMessage>( It.IsAny <string>(), It.IsAny <Documents.ResourceType>(), It.IsAny <Documents.OperationType>(), It.IsAny <RequestOptions>(), It.IsAny <ContainerInternal>(), It.IsAny <Cosmos.FeedRange>(), It.IsAny <Stream>(), It.IsAny <Action <RequestMessage> >(), It.IsAny <Func <ResponseMessage, ResponseMessage> >(), It.IsAny <ITrace>(), It.IsAny <CancellationToken>()), Times.Exactly(3)); }
private async Task VerifyItemNullExceptions( dynamic testItem, CosmosItemRequestOptions requestOptions = null) { TestHandler testHandler = new TestHandler((request, cancellationToken) => { Assert.Fail("Null partition key should be blocked without the correct request option"); return(null); }); CosmosClient client = MockCosmosUtil.CreateMockCosmosClient( (cosmosClientBuilder) => cosmosClientBuilder.AddCustomHandlers(testHandler)); CosmosContainer container = client.Databases["testdb"] .Containers["testcontainer"]; await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.CreateItemAsync <dynamic>( partitionKey: null, item: testItem, requestOptions: requestOptions); }, "CreateItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.ReadItemAsync <dynamic>( partitionKey: null, id: testItem.id, requestOptions: requestOptions); }, "ReadItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.UpsertItemAsync <dynamic>( partitionKey: null, item: testItem, requestOptions: requestOptions); }, "UpsertItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.ReplaceItemAsync <dynamic>( partitionKey: null, id: testItem.id, item: testItem, requestOptions: requestOptions); }, "ReplaceItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.DeleteItemAsync <dynamic>( partitionKey: null, id: testItem.id, requestOptions: requestOptions); }, "DeleteItemAsync should throw ArgumentNullException without the correct request option set."); CosmosDefaultJsonSerializer jsonSerializer = new CosmosDefaultJsonSerializer(); using (Stream itemStream = jsonSerializer.ToStream <dynamic>(testItem)) { await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.CreateItemStreamAsync( partitionKey: null, streamPayload: itemStream, requestOptions: requestOptions); }, "CreateItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.ReadItemStreamAsync( partitionKey: null, id: testItem.id, requestOptions: requestOptions); }, "ReadItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.UpsertItemStreamAsync( partitionKey: null, streamPayload: itemStream, requestOptions: requestOptions); }, "UpsertItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.ReplaceItemStreamAsync( partitionKey: null, id: testItem.id, streamPayload: itemStream, requestOptions: requestOptions); }, "ReplaceItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.Items.DeleteItemStreamAsync( partitionKey: null, id: testItem.id, requestOptions: requestOptions); }, "DeleteItemAsync should throw ArgumentNullException without the correct request option set."); } }
private static ContainerCore GetMockedContainer(Func <RequestMessage, CancellationToken, Task <ResponseMessage> > handlerFunc) { return(new ContainerCore(CosmosConflictTests.GetMockedClientContext(handlerFunc), MockCosmosUtil.CreateMockDatabase("conflictsDb").Object, "conflictsColl")); }
public async Task TestGetPartitionKeyValueFromStreamAsync() { ContainerInternal mockContainer = (ContainerInternal)MockCosmosUtil.CreateMockCosmosClient().GetContainer("TestDb", "Test"); Mock <ContainerInternal> containerMock = new Mock <ContainerInternal>(); ContainerInternal container = containerMock.Object; containerMock.Setup(e => e.GetPartitionKeyPathTokensAsync(It.IsAny <CancellationToken>())) .Returns(Task.FromResult((IReadOnlyList <IReadOnlyList <string> >) new List <IReadOnlyList <string> > { new List <string> { "pk" } })); containerMock .Setup( x => x.GetPartitionKeyValueFromStreamAsync( It.IsAny <Stream>(), It.IsAny <ITrace>(), It.IsAny <CancellationToken>())) .Returns <Stream, ITrace, CancellationToken>( (stream, trace, cancellationToken) => mockContainer.GetPartitionKeyValueFromStreamAsync( stream, trace, cancellationToken)); DateTime dateTime = new DateTime(2019, 05, 15, 12, 1, 2, 3, DateTimeKind.Utc); Guid guid = Guid.NewGuid(); //Test supported types List <dynamic> supportedTypesToTest = new List <dynamic> { new { pk = true }, new { pk = false }, new { pk = byte.MaxValue }, new { pk = sbyte.MaxValue }, new { pk = short.MaxValue }, new { pk = ushort.MaxValue }, new { pk = int.MaxValue }, new { pk = uint.MaxValue }, new { pk = long.MaxValue }, new { pk = ulong.MaxValue }, new { pk = float.MaxValue }, new { pk = double.MaxValue }, new { pk = decimal.MaxValue }, new { pk = char.MaxValue }, new { pk = "test" }, new { pk = dateTime }, new { pk = guid }, }; foreach (dynamic poco in supportedTypesToTest) { object pk = await container.GetPartitionKeyValueFromStreamAsync( MockCosmosUtil.Serializer.ToStream(poco), NoOpTrace.Singleton, default(CancellationToken)); if (pk is bool boolValue) { Assert.AreEqual(poco.pk, boolValue); } else if (pk is double doubleValue) { if (poco.pk is float) { Assert.AreEqual(poco.pk, Convert.ToSingle(pk)); } else if (poco.pk is double) { Assert.AreEqual(poco.pk, Convert.ToDouble(pk)); } else if (poco.pk is decimal) { Assert.AreEqual(Convert.ToDouble(poco.pk), (double)pk); } } else if (pk is string stringValue) { if (poco.pk is DateTime) { Assert.AreEqual(poco.pk.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"), stringValue); } else { Assert.AreEqual(poco.pk.ToString(), (string)pk); } } } //Unsupported types should throw List <dynamic> unsupportedTypesToTest = new List <dynamic> { new { pk = new { test = "test" } }, new { pk = new int[] { 1, 2, 3 } }, new { pk = new ArraySegment <byte>(new byte[] { 0 }) }, }; foreach (dynamic poco in unsupportedTypesToTest) { await Assert.ThrowsExceptionAsync <ArgumentException>(async() => await container.GetPartitionKeyValueFromStreamAsync( MockCosmosUtil.Serializer.ToStream(poco), NoOpTrace.Singleton, default(CancellationToken))); } //null should return null object pkValue = await container.GetPartitionKeyValueFromStreamAsync( MockCosmosUtil.Serializer.ToStream(new { pk = (object)null }), NoOpTrace.Singleton, default); Assert.AreEqual(Cosmos.PartitionKey.Null, pkValue); }
private async Task VerifyItemOperations( object partitionKey, string partitionKeySerialized, dynamic testItem, CosmosItemRequestOptions requestOptions = null) { CosmosResponseMessage response = null; HttpStatusCode httpStatusCode = HttpStatusCode.OK; int testHandlerHitCount = 0; TestHandler testHandler = new TestHandler((request, cancellationToken) => { Assert.IsTrue(request.RequestUri.OriginalString.StartsWith(@"/dbs/testdb/colls/testcontainer")); Assert.AreEqual(requestOptions, request.RequestOptions); Assert.AreEqual(ResourceType.Document, request.ResourceType); Assert.IsNotNull(request.Headers.PartitionKey); Assert.AreEqual(partitionKeySerialized, request.Headers.PartitionKey); testHandlerHitCount++; response = new CosmosResponseMessage(httpStatusCode, request, errorMessage: null); response.Content = request.Content; return(Task.FromResult(response)); }); CosmosClient client = MockCosmosUtil.CreateMockCosmosClient( (builder) => builder.AddCustomHandlers(testHandler)); CosmosContainer container = client.Databases["testdb"] .Containers["testcontainer"]; CosmosItemResponse <dynamic> itemResponse = await container.Items.CreateItemAsync <dynamic>( partitionKey : partitionKey, item : testItem, requestOptions : requestOptions); Assert.IsNotNull(itemResponse); Assert.AreEqual(httpStatusCode, itemResponse.StatusCode); itemResponse = await container.Items.ReadItemAsync <dynamic>( partitionKey : partitionKey, id : testItem.id, requestOptions : requestOptions); Assert.IsNotNull(itemResponse); Assert.AreEqual(httpStatusCode, itemResponse.StatusCode); itemResponse = await container.Items.UpsertItemAsync <dynamic>( partitionKey : partitionKey, item : testItem, requestOptions : requestOptions); Assert.IsNotNull(itemResponse); Assert.AreEqual(httpStatusCode, itemResponse.StatusCode); itemResponse = await container.Items.ReplaceItemAsync <dynamic>( partitionKey : partitionKey, id : testItem.id, item : testItem, requestOptions : requestOptions); Assert.IsNotNull(itemResponse); Assert.AreEqual(httpStatusCode, itemResponse.StatusCode); itemResponse = await container.Items.DeleteItemAsync <dynamic>( partitionKey : partitionKey, id : testItem.id, requestOptions : requestOptions); Assert.IsNotNull(itemResponse); Assert.AreEqual(httpStatusCode, itemResponse.StatusCode); Assert.AreEqual(5, testHandlerHitCount, "An operation did not make it to the handler"); CosmosDefaultJsonSerializer jsonSerializer = new CosmosDefaultJsonSerializer(); using (Stream itemStream = jsonSerializer.ToStream <dynamic>(testItem)) { using (CosmosResponseMessage streamResponse = await container.Items.CreateItemStreamAsync( partitionKey: partitionKey, streamPayload: itemStream)) { Assert.IsNotNull(streamResponse); Assert.AreEqual(httpStatusCode, streamResponse.StatusCode); } } using (Stream itemStream = jsonSerializer.ToStream <dynamic>(testItem)) { using (CosmosResponseMessage streamResponse = await container.Items.ReadItemStreamAsync( partitionKey: partitionKey, id: testItem.id, requestOptions: requestOptions)) { Assert.IsNotNull(streamResponse); Assert.AreEqual(httpStatusCode, streamResponse.StatusCode); } } using (Stream itemStream = jsonSerializer.ToStream <dynamic>(testItem)) { using (CosmosResponseMessage streamResponse = await container.Items.UpsertItemStreamAsync( partitionKey: partitionKey, streamPayload: itemStream, requestOptions: requestOptions)) { Assert.IsNotNull(streamResponse); Assert.AreEqual(httpStatusCode, streamResponse.StatusCode); } } using (Stream itemStream = jsonSerializer.ToStream <dynamic>(testItem)) { using (CosmosResponseMessage streamResponse = await container.Items.ReplaceItemStreamAsync( partitionKey: partitionKey, id: testItem.id, streamPayload: itemStream, requestOptions: requestOptions)) { Assert.IsNotNull(streamResponse); Assert.AreEqual(httpStatusCode, streamResponse.StatusCode); } } using (Stream itemStream = jsonSerializer.ToStream <dynamic>(testItem)) { using (CosmosResponseMessage streamResponse = await container.Items.DeleteItemStreamAsync( partitionKey: partitionKey, id: testItem.id, requestOptions: requestOptions)) { Assert.IsNotNull(streamResponse); Assert.AreEqual(httpStatusCode, streamResponse.StatusCode); } } Assert.AreEqual(10, testHandlerHitCount, "A stream operation did not make it to the handler"); }
public async Task TestMultipleNestedPartitionKeyValueFromStreamAsync() { ContainerInternal originalContainer = (ContainerInternal)MockCosmosUtil.CreateMockCosmosClient().GetContainer("TestDb", "Test"); Mock <ContainerCore> mockedContainer = new Mock <ContainerCore>( originalContainer.ClientContext, (DatabaseInternal)originalContainer.Database, originalContainer.Id, null) { CallBase = true }; mockedContainer.Setup(e => e.GetPartitionKeyPathTokensAsync(It.IsAny <CancellationToken>())) .Returns(Task.FromResult((IReadOnlyList <IReadOnlyList <string> >) new List <IReadOnlyList <string> > { new List <string> { "a", "b", "c" }, new List <string> { "a", "e", "f" } })); ContainerInternal containerWithMockPartitionKeyPath = mockedContainer.Object; List <dynamic> validNestedItems = new List <dynamic> { ( new // a/b/c (Specify only one partition key) { id = Guid.NewGuid().ToString(), a = new { b = new { c = 10, } } }, "[10.0,{}]" ), ( new // { id = Guid.NewGuid().ToString(), a = new { b = new { c = 10, }, e = new { f = 15, } } }, "[10.0,15.0]" ), ( new { id = Guid.NewGuid().ToString(), a = new { b = new { c = 10, }, e = new { f = default(string), //null } } }, "[10.0,null]" ), ( new { id = Guid.NewGuid().ToString(), a = new { e = new { f = 10, } } }, "[{},10.0]" ), ( new { id = Guid.NewGuid().ToString(), a = new { e = 10, b = new { k = 10, } } }, "[{},{}]" ) }; foreach (dynamic poco in validNestedItems) { Cosmos.PartitionKey pk = await containerWithMockPartitionKeyPath.GetPartitionKeyValueFromStreamAsync( MockCosmosUtil.Serializer.ToStream(poco.Item1), NoOpTrace.Singleton, default(CancellationToken)); string partitionKeyString = pk.InternalKey.ToJsonString(); Assert.AreEqual(poco.Item2, partitionKeyString); } }
private (ContainerInternal, Mock <BatchAsyncContainerExecutor>) CreateMockBulkCosmosClientContext() { CosmosClientContext context = MockCosmosUtil.CreateMockCosmosClient( builder => builder.WithBulkExecution(true)).ClientContext; Mock <CosmosClientContext> mockContext = new Mock <CosmosClientContext>(); mockContext.Setup(x => x.CreateLink(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>())) .Returns <string, string, string>((x, y, z) => context.CreateLink(x, y, z)); mockContext.Setup(x => x.ClientOptions).Returns(context.ClientOptions); mockContext.Setup(x => x.ResponseFactory).Returns(context.ResponseFactory); mockContext.Setup(x => x.SerializerCore).Returns(context.SerializerCore); mockContext.Setup(x => x.DocumentClient).Returns(context.DocumentClient); mockContext.Setup(x => x.OperationHelperAsync <ResponseMessage>( It.IsAny <string>(), It.IsAny <RequestOptions>(), It.IsAny <Func <ITrace, Task <ResponseMessage> > >(), It.IsAny <TraceComponent>(), It.IsAny <TraceLevel>())) .Returns <string, RequestOptions, Func <ITrace, Task <ResponseMessage> >, TraceComponent, TraceLevel>( (operationName, requestOptions, func, comp, level) => func(NoOpTrace.Singleton)); mockContext.Setup(x => x.OperationHelperAsync <ItemResponse <dynamic> >( It.IsAny <string>(), It.IsAny <RequestOptions>(), It.IsAny <Func <ITrace, Task <ItemResponse <dynamic> > > >(), It.IsAny <TraceComponent>(), It.IsAny <TraceLevel>())) .Returns <string, RequestOptions, Func <ITrace, Task <ItemResponse <dynamic> > >, TraceComponent, TraceLevel>( (operationName, requestOptions, func, comp, level) => func(NoOpTrace.Singleton)); mockContext.Setup(x => x.ProcessResourceOperationStreamAsync( It.IsAny <string>(), It.IsAny <ResourceType>(), It.IsAny <OperationType>(), It.IsAny <RequestOptions>(), It.IsAny <ContainerInternal>(), It.IsAny <Cosmos.PartitionKey?>(), It.IsAny <string>(), It.IsAny <Stream>(), It.IsAny <Action <RequestMessage> >(), It.IsAny <ITrace>(), It.IsAny <CancellationToken>())).Returns <string, ResourceType, OperationType, RequestOptions, ContainerInternal, Cosmos.PartitionKey, string, Stream, Action <RequestMessage>, ITrace, CancellationToken>( (uri, resourceType, operationType, requestOptions, containerInternal, pk, itemId, stream, requestEnricher, trace, cancellationToken) => context.ProcessResourceOperationStreamAsync( uri, resourceType, operationType, requestOptions, containerInternal, pk, itemId, stream, requestEnricher, trace, cancellationToken)); Mock <BatchAsyncContainerExecutor> mockedExecutor = this.GetMockedBatchExcecutor(); mockContext.Setup(x => x.GetExecutorForContainer(It.IsAny <ContainerInternal>())).Returns(mockedExecutor.Object); DatabaseInternal db = new DatabaseInlineCore(mockContext.Object, "test"); ContainerInternal container = new ContainerInlineCore(mockContext.Object, db, "test"); return(container, mockedExecutor); }
public async Task TestNestedPartitionKeyValueFromStreamAsync() { ContainerInternal originalContainer = (ContainerInternal)MockCosmosUtil.CreateMockCosmosClient().GetContainer("TestDb", "Test"); Mock <ContainerCore> mockedContainer = new Mock <ContainerCore>( originalContainer.ClientContext, (DatabaseInternal)originalContainer.Database, originalContainer.Id, null) { CallBase = true }; mockedContainer.Setup(e => e.GetPartitionKeyPathTokensAsync(It.IsAny <CancellationToken>())) .Returns(Task.FromResult((IReadOnlyList <IReadOnlyList <string> >) new List <IReadOnlyList <string> > { new List <string> { "a", "b", "c" } })); ContainerInternal containerWithMockPartitionKeyPath = mockedContainer.Object; List <dynamic> invalidNestedItems = new List <dynamic> { new // a/b/d (leaf invalid) { id = Guid.NewGuid().ToString(), a = new { b = new { d = "pk1", } } }, new // a/d/c (middle invalid) { id = Guid.NewGuid().ToString(), a = new { d = new { c = "pk1", } } }, new // nested/a/b/c (root invalid) { id = Guid.NewGuid().ToString(), nested = new { a = new { b = new { c = "pk1", } } } }, new // nested/a/b/c/d (root & tail invalid) { id = Guid.NewGuid().ToString(), nested = new { a = new { b = new { c = new { d = "pk1" } } } } } }; foreach (dynamic poco in invalidNestedItems) { object pk = await containerWithMockPartitionKeyPath.GetPartitionKeyValueFromStreamAsync( MockCosmosUtil.Serializer.ToStream(poco), NoOpTrace.Singleton, default(CancellationToken)); Assert.IsTrue(object.Equals(Cosmos.PartitionKey.None, pk)); } }
private async Task VerifyItemNullPartitionKeyExpectations( dynamic testItem, ItemRequestOptions requestOptions = null) { TestHandler testHandler = new TestHandler((request, cancellationToken) => { Assert.IsNotNull(request.Headers.PartitionKey); Assert.AreEqual(Documents.Routing.PartitionKeyInternal.Undefined.ToString(), request.Headers.PartitionKey.ToString()); return(Task.FromResult(new CosmosResponseMessage(HttpStatusCode.OK))); }); CosmosClient client = MockCosmosUtil.CreateMockCosmosClient( (cosmosClientBuilder) => cosmosClientBuilder.AddCustomHandlers(testHandler)); CosmosContainer container = client.GetDatabase("testdb") .GetContainer("testcontainer"); await container.CreateItemAsync <dynamic>( item : testItem, requestOptions : requestOptions); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.ReadItemAsync <dynamic>( partitionKey: null, id: testItem.id, requestOptions: requestOptions); }, "ReadItemAsync should throw ArgumentNullException without the correct request option set."); await container.UpsertItemAsync <dynamic>( item : testItem, requestOptions : requestOptions); await container.ReplaceItemAsync <dynamic>( id : testItem.id, item : testItem, requestOptions : requestOptions); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.DeleteItemAsync <dynamic>( partitionKey: null, id: testItem.id, requestOptions: requestOptions); }, "DeleteItemAsync should throw ArgumentNullException without the correct request option set."); CosmosJsonSerializerCore jsonSerializer = new CosmosJsonSerializerCore(); using (Stream itemStream = jsonSerializer.ToStream <dynamic>(testItem)) { await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.CreateItemStreamAsync( partitionKey: null, streamPayload: itemStream, requestOptions: requestOptions); }, "CreateItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.ReadItemStreamAsync( partitionKey: null, id: testItem.id, requestOptions: requestOptions); }, "ReadItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.UpsertItemStreamAsync( partitionKey: null, streamPayload: itemStream, requestOptions: requestOptions); }, "UpsertItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.ReplaceItemStreamAsync( partitionKey: null, id: testItem.id, streamPayload: itemStream, requestOptions: requestOptions); }, "ReplaceItemAsync should throw ArgumentNullException without the correct request option set."); await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => { await container.DeleteItemStreamAsync( partitionKey: null, id: testItem.id, requestOptions: requestOptions); }, "DeleteItemAsync should throw ArgumentNullException without the correct request option set."); } }
public async Task ContinuationTokenIsNotUpdatedOnFails() { MultiRangeMockDocumentClient documentClient = new MultiRangeMockDocumentClient(); CosmosClient client = MockCosmosUtil.CreateMockCosmosClient(); Mock <CosmosClientContext> mockContext = new Mock <CosmosClientContext>(); mockContext.Setup(x => x.ClientOptions).Returns(MockCosmosUtil.GetDefaultConfiguration()); mockContext.Setup(x => x.DocumentClient).Returns(documentClient); mockContext.Setup(x => x.SerializerCore).Returns(MockCosmosUtil.Serializer); mockContext.Setup(x => x.Client).Returns(client); mockContext.Setup(x => x.CreateLink(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>())).Returns(new Uri("/dbs/test/colls/test", UriKind.Relative)); ResponseMessage firstResponse = new ResponseMessage(HttpStatusCode.NotModified); firstResponse.Headers.ETag = "FirstContinuation"; ResponseMessage secondResponse = new ResponseMessage( statusCode: HttpStatusCode.NotFound, requestMessage: null, headers: new Headers() { ETag = "ShouldNotContainThis" }, cosmosException: CosmosExceptionFactory.CreateNotFoundException("something"), diagnostics: new CosmosDiagnosticsContextCore()); mockContext.SetupSequence(x => x.ProcessResourceOperationAsync <ResponseMessage>( It.IsAny <Uri>(), It.IsAny <Documents.ResourceType>(), It.IsAny <Documents.OperationType>(), It.IsAny <RequestOptions>(), It.IsAny <ContainerInternal>(), It.IsAny <PartitionKey?>(), It.IsAny <Stream>(), It.IsAny <Action <RequestMessage> >(), It.IsAny <Func <ResponseMessage, ResponseMessage> >(), It.IsAny <CosmosDiagnosticsContext>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(firstResponse)) .Returns(Task.FromResult(secondResponse)); DatabaseInternal databaseCore = new DatabaseInlineCore(mockContext.Object, "mydb"); StandByFeedIteratorCore iterator = new StandByFeedIteratorCore( mockContext.Object, new ContainerInlineCore(mockContext.Object, databaseCore, "myColl"), null, 10, new ChangeFeedRequestOptions()); ResponseMessage firstRequest = await iterator.ReadNextAsync(); Assert.IsTrue(firstRequest.Headers.ContinuationToken.Contains(firstResponse.Headers.ETag), "Response should contain the first continuation"); Assert.IsTrue(!firstRequest.Headers.ContinuationToken.Contains(secondResponse.Headers.ETag), "Response should not contain the second continuation"); Assert.AreEqual(HttpStatusCode.NotFound, firstRequest.StatusCode); mockContext.Verify(x => x.ProcessResourceOperationAsync <ResponseMessage>( It.IsAny <Uri>(), It.IsAny <Documents.ResourceType>(), It.IsAny <Documents.OperationType>(), It.IsAny <RequestOptions>(), It.IsAny <ContainerInternal>(), It.IsAny <PartitionKey?>(), It.IsAny <Stream>(), It.IsAny <Action <RequestMessage> >(), It.IsAny <Func <ResponseMessage, ResponseMessage> >(), It.IsAny <CosmosDiagnosticsContext>(), It.IsAny <CancellationToken>()), Times.Exactly(2)); }
public async Task VerifySendUsesOringianlContinuationOnDocumentClientExceptionAfterRetry() { Mock <PartitionRoutingHelper> partitionRoutingHelperMock = this.GetPartitionRoutingHelperMock(); //throw a DocumentClientException partitionRoutingHelperMock.Setup(m => m.TryAddPartitionKeyRangeToContinuationTokenAsync( It.IsAny <INameValueCollection>(), It.IsAny <List <Range <string> > >(), It.IsAny <IRoutingMapProvider>(), It.Is <string>(x => x == CollectionId), It.IsAny <ResolvedRangeInfo>(), It.IsAny <RntbdConstants.RntdbEnumerationDirection>() )).ThrowsAsync(new DocumentClientException("error", HttpStatusCode.ServiceUnavailable, SubStatusCodes.Unknown)); PartitionKeyRangeHandler partitionKeyRangeHandler = new PartitionKeyRangeHandler(MockCosmosUtil.CreateMockCosmosClient(), partitionRoutingHelperMock.Object); TestHandler testHandler = new TestHandler(async(request, cancellationToken) => { ResponseMessage successResponse = await TestHandler.ReturnSuccess(); successResponse.Headers.Remove(HttpConstants.HttpHeaders.Continuation); //Clobber original continuation return(successResponse); }); partitionKeyRangeHandler.InnerHandler = testHandler; //Pass valid collections path because it is required by DocumentServiceRequest's constructor. This can't be mocked because ToDocumentServiceRequest() is an extension method RequestMessage initialRequest = new RequestMessage(HttpMethod.Get, new Uri($"{Paths.DatabasesPathSegment}/test/{Paths.CollectionsPathSegment}/test", UriKind.Relative)); initialRequest.OperationType = OperationType.ReadFeed; initialRequest.Headers.Add(HttpConstants.HttpHeaders.Continuation, Continuation); ResponseMessage response = await partitionKeyRangeHandler.SendAsync(initialRequest, CancellationToken.None); Assert.IsFalse(response.IsSuccessStatusCode); Assert.AreEqual(System.Net.HttpStatusCode.ServiceUnavailable, response.StatusCode); //Check if original continuation was restored Assert.AreEqual(Continuation, response.Headers.GetValues(HttpConstants.HttpHeaders.Continuation).First()); Assert.AreEqual(Continuation, initialRequest.Headers.GetValues(HttpConstants.HttpHeaders.Continuation).First()); }
public async Task VerifySendUsesOringianlContinuationOnNonSuccessfulResponse() { Mock <PartitionRoutingHelper> partitionRoutingHelperMock = this.GetPartitionRoutingHelperMock(); PartitionKeyRangeHandler partitionKeyRangeHandler = new PartitionKeyRangeHandler(MockCosmosUtil.CreateMockCosmosClient(), partitionRoutingHelperMock.Object); TestHandler testHandler = new TestHandler(async(request, cancellationToken) => { ResponseMessage errorResponse = await TestHandler.ReturnStatusCode(HttpStatusCode.Gone); errorResponse.Headers.Remove(HttpConstants.HttpHeaders.Continuation); //Clobber original continuation return(errorResponse); }); partitionKeyRangeHandler.InnerHandler = testHandler; //Pass valid collections path because it is required by DocumentServiceRequest's constructor. This can't be mocked because ToDocumentServiceRequest() is an extension method RequestMessage initialRequest = new RequestMessage(HttpMethod.Get, new Uri($"{Paths.DatabasesPathSegment}/test/{Paths.CollectionsPathSegment}/test", UriKind.Relative)); initialRequest.OperationType = OperationType.ReadFeed; initialRequest.Headers.Add(HttpConstants.HttpHeaders.Continuation, Continuation); ResponseMessage response = await partitionKeyRangeHandler.SendAsync(initialRequest, CancellationToken.None); Assert.IsFalse(response.IsSuccessStatusCode); Assert.AreEqual(System.Net.HttpStatusCode.Gone, response.StatusCode); //Check if original continuation was restored Assert.AreEqual(Continuation, response.Headers.GetValues(HttpConstants.HttpHeaders.Continuation).First()); Assert.AreEqual(Continuation, initialRequest.Headers.GetValues(HttpConstants.HttpHeaders.Continuation).First()); }