示例#1
0
        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));
        }
示例#2
0
        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.");
            }
        }
示例#3
0
 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);
        }
示例#5
0
        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.");
            }
        }
示例#10
0
        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));
        }
示例#11
0
        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());
        }
示例#12
0
        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());
        }