예제 #1
0
        public async Task IteratorTest()
        {
            using (CosmosClient cosmosClient = TestCommon.CreateCosmosClient(new CosmosClientOptions()
            {
                Serializer = new FaultySerializer()
            }))
            {
                // Should not use the custom serializer for these operations
                Scripts  scripts        = cosmosClient.GetContainer(this.database.Id, this.container.Id).Scripts;
                string   sprocBody      = "function() { { var x = 42; } }";
                int      numberOfSprocs = 3;
                string[] sprocIds       = new string[numberOfSprocs];

                for (int i = 0; i < numberOfSprocs; i++)
                {
                    string sprocId = Guid.NewGuid().ToString();
                    sprocIds[i] = sprocId;

                    StoredProcedureResponse storedProcedureResponse =
                        await scripts.CreateStoredProcedureAsync(new StoredProcedureProperties(sprocId, sprocBody));

                    Assert.AreEqual(HttpStatusCode.Created, storedProcedureResponse.StatusCode);
                }

                List <string> readSprocIds = new List <string>();
                FeedIterator <StoredProcedureProperties> iter = scripts.GetStoredProcedureQueryIterator <StoredProcedureProperties>();
                while (iter.HasMoreResults)
                {
                    FeedResponse <StoredProcedureProperties> currentResultSet = await iter.ReadNextAsync();

                    {
                        foreach (StoredProcedureProperties storedProcedureSettingsEntry in currentResultSet)
                        {
                            readSprocIds.Add(storedProcedureSettingsEntry.Id);
                        }
                    }
                }

                CollectionAssert.AreEquivalent(sprocIds, readSprocIds);
            }
        }
예제 #2
0
        internal static Container GetContainerWithItemTransportException(
            string databaseId,
            string containerId,
            Guid activityId,
            string transportExceptionSourceDescription)
        {
            CosmosClient clientWithIntercepter = TestCommon.CreateCosmosClient(
                builder =>
            {
                builder.WithTransportClientHandlerFactory(transportClient => new TransportClientWrapper(
                                                              transportClient,
                                                              (uri, resourceOperation, request) => TransportClientHelper.ThrowTransportExceptionOnItemOperation(
                                                                  uri,
                                                                  resourceOperation,
                                                                  request,
                                                                  activityId,
                                                                  transportExceptionSourceDescription)));
            });

            return(clientWithIntercepter.GetContainer(databaseId, containerId));
        }
예제 #3
0
        internal static Container GetContainerWithIntercepter(
            string databaseId,
            string containerId,
            Action <Uri, ResourceOperation, DocumentServiceRequest> interceptor,
            bool useGatewayMode = false)
        {
            CosmosClient clientWithIntercepter = TestCommon.CreateCosmosClient(
                builder =>
            {
                if (useGatewayMode)
                {
                    builder.WithConnectionModeGateway();
                }

                builder.WithTransportClientHandlerFactory(transportClient => new TransportClientWrapper(
                                                              transportClient,
                                                              interceptor));
            });

            return(clientWithIntercepter.GetContainer(databaseId, containerId));
        }
예제 #4
0
        public void VerifyClientIDForUserAgentString()
        {
            CosmosClient.numberOfClientsCreated = 0; // reset
            const int max = 10;

            for (int i = 1; i < max + 5; i++)
            {
                using (CosmosClient client = TestCommon.CreateCosmosClient())
                {
                    string userAgentString = client.DocumentClient.ConnectionPolicy.UserAgentContainer.UserAgent;
                    if (i <= max)
                    {
                        Assert.AreEqual(userAgentString.Split('|')[2], i.ToString());
                    }
                    else
                    {
                        Assert.AreEqual(userAgentString.Split('|')[2], max.ToString());
                    }
                }
            }
        }
예제 #5
0
        public async Task TestInitialize()
        {
            this.cancellationTokenSource = new CancellationTokenSource();
            this.cancellationToken       = this.cancellationTokenSource.Token;

            this.cosmosClient = TestCommon.CreateCosmosClient();
            this.database     = await this.cosmosClient.CreateDatabaseAsync(Guid.NewGuid().ToString(),
                                                                            cancellationToken : this.cancellationToken);

            this.documentClient = TestCommon.CreateClient(true, defaultConsistencyLevel: Documents.ConsistencyLevel.Session);

            string            PartitionKey = "/partitionKey";
            ContainerResponse response     = await this.database.CreateContainerAsync(
                new ContainerProperties(id : Guid.NewGuid().ToString(), partitionKeyPath : PartitionKey),
                cancellationToken : this.cancellationToken);

            Assert.IsNotNull(response);
            Assert.IsNotNull(response.Container);
            Assert.IsNotNull(response.Resource);
            this.Container = (ContainerCore)response;
        }
예제 #6
0
        public async Task TestKeyRangeCacheRefresh()
        {
            bool   validate     = false;
            bool   pass         = false;
            string expectedPath = null;
            HttpClientHandlerHelper httpClientHandler = new HttpClientHandlerHelper
            {
                RequestCallBack = (HttpRequestMessage request, CancellationToken cancellationToken) =>
                {
                    if (validate)
                    {
                        pass = request.RequestUri.LocalPath == expectedPath;
                    }

                    return(null);
                }
            };

            using (CosmosClient client = TestCommon.CreateCosmosClient(builder => builder
                                                                       .WithConnectionModeGateway()
                                                                       .WithHttpClientFactory(() => new HttpClient(httpClientHandler))))
            {
                ContainerInternal                containerInternal = client.GetContainer(this.database.Id, this.Container.Id) as ContainerInternal;
                CosmosQueryClientCore            queryClient       = new CosmosQueryClientCore(client.ClientContext, containerInternal);
                NetworkAttachedDocumentContainer networkAttachedDocumentContainer = new NetworkAttachedDocumentContainer(
                    containerInternal,
                    queryClient,
                    Guid.NewGuid());

                // warm up the caches
                _ = await containerInternal.ReadItemStreamAsync("doesnotexist", PartitionKey.Null);

                ContainerProperties containerProperties = await containerInternal.GetCachedContainerPropertiesAsync(false, NoOpTrace.Singleton, default);

                expectedPath = "/" + containerProperties.SelfLink + "pkranges";
                validate     = true;

                TryCatch result = await networkAttachedDocumentContainer.MonadicRefreshProviderAsync(
                    trace : NoOpTrace.Singleton,
                    cancellationToken : default);
예제 #7
0
        public async Task CreateIfNotExists()
        {
            RequestChargeHandlerHelper requestChargeHandler = new RequestChargeHandlerHelper();
            RequestHandlerHelper       requestHandlerHelper = new RequestHandlerHelper();

            CosmosClient client = TestCommon.CreateCosmosClient(x => x.AddCustomHandlers(requestChargeHandler, requestHandlerHelper));

            // Create a new database
            requestChargeHandler.TotalRequestCharges = 0;
            DatabaseResponse createResponse = await client.CreateDatabaseIfNotExistsAsync(Guid.NewGuid().ToString());

            Assert.AreEqual(requestChargeHandler.TotalRequestCharges, createResponse.RequestCharge);
            Assert.AreEqual(HttpStatusCode.Created, createResponse.StatusCode);

            requestChargeHandler.TotalRequestCharges = 0;
            DatabaseResponse createExistingResponse = await client.CreateDatabaseIfNotExistsAsync(createResponse.Resource.Id);

            Assert.AreEqual(HttpStatusCode.OK, createExistingResponse.StatusCode);
            Assert.AreEqual(requestChargeHandler.TotalRequestCharges, createExistingResponse.RequestCharge);
            Assert.IsNotNull(createExistingResponse.Diagnostics);
            string diagnostics = createExistingResponse.Diagnostics.ToString();

            Assert.IsFalse(string.IsNullOrEmpty(diagnostics));
            Assert.IsTrue(diagnostics.Contains("CreateDatabaseIfNotExistsAsync"));

            bool conflictReturned = false;

            requestHandlerHelper.CallBackOnResponse = (request, response) =>
            {
                if (request.OperationType == Documents.OperationType.Create &&
                    request.ResourceType == Documents.ResourceType.Database)
                {
                    conflictReturned = true;
                    // Simulate a race condition which results in a 409
                    return(CosmosExceptionFactory.Create(
                               statusCode: HttpStatusCode.Conflict,
                               message: "Fake 409 conflict",
                               stackTrace: string.Empty,
                               headers: response.Headers,
                               error: default,
        public async Task ItemBulkNoResponseTest()
        {
            ItemRequestOptions requestOptions = new ItemRequestOptions()
            {
                EnableContentResponseOnWrite = false
            };

            CosmosClient bulkClient    = TestCommon.CreateCosmosClient((builder) => builder.WithBulkExecution(true));
            Container    bulkContainer = bulkClient.GetContainer(this.database.Id, this.container.Id);

            string pkId = "TestBulkId";

            List <Task <ItemResponse <ToDoActivity> > > bulkOperations = new List <Task <ItemResponse <ToDoActivity> > >();
            List <ToDoActivity> items = new List <ToDoActivity>();

            for (int i = 0; i < 100; i++)
            {
                ToDoActivity item = ToDoActivity.CreateRandomToDoActivity(pk: pkId);
                items.Add(item);
                bulkOperations.Add(bulkContainer.CreateItemAsync <ToDoActivity>(item, requestOptions: requestOptions));
            }

            foreach (Task <ItemResponse <ToDoActivity> > result in bulkOperations)
            {
                ItemResponse <ToDoActivity> itemResponse = await result;
                this.ValidateItemNoContentResponse(itemResponse);
            }

            bulkOperations = new List <Task <ItemResponse <ToDoActivity> > >();
            foreach (ToDoActivity item in items)
            {
                bulkOperations.Add(bulkContainer.ReadItemAsync <ToDoActivity>(item.id, new PartitionKey(item.status), requestOptions: requestOptions));
            }

            foreach (Task <ItemResponse <ToDoActivity> > result in bulkOperations)
            {
                ItemResponse <ToDoActivity> itemResponse = await result;
                this.ValidateItemResponse(itemResponse);
            }
        }
예제 #9
0
        public async Task TestInitialize()
        {
            CosmosClientOptions clientOptions = new CosmosClientOptions()
            {
                SendingRequestEventArgs = this.SendingRequestEventHandlerUdfVerifier,
            };

            this.cosmosClient = TestCommon.CreateCosmosClient(clientOptions);
            this.database     = await this.cosmosClient.CreateDatabaseAsync(Guid.NewGuid().ToString(),
                                                                            cancellationToken : this.cancellationToken);

            string            PartitionKey = "/pk";
            ContainerResponse response     = await this.database.CreateContainerAsync(
                new ContainerProperties(id : Guid.NewGuid().ToString(), partitionKeyPath : PartitionKey),
                cancellationToken : this.cancellationToken);

            Assert.IsNotNull(response);
            Assert.IsNotNull(response.Container);
            Assert.IsNotNull(response.Resource);
            this.container = (ContainerInlineCore)response;
            this.scripts   = this.container.Scripts;
        }
        public async static Task Initialize(TestContext textContext)
        {
            cosmosClient = TestCommon.CreateCosmosClient((cosmosClientBuilder) => {
                cosmosClientBuilder.WithCustomSerializer(new CustomJsonSerializer(new JsonSerializerSettings()
                {
                    ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
                    // We want to simulate the property not exist so ignoring the null value
                    NullValueHandling = NullValueHandling.Ignore
                })).WithConnectionModeGateway();
            });

            try
            {
                await cosmosClient.GetDatabase(id : nameof(LinqSQLTranslationBaselineTest)).DeleteAsync();
            }
            catch (CosmosException ex) when(ex.StatusCode == HttpStatusCode.NotFound)
            {
                //swallow
            }

            testDb = await cosmosClient.CreateDatabaseAsync(nameof(LinqSQLTranslationBaselineTest));
        }
        public async Task BulkOperationDiagnostic()
        {
            string       pkValue       = "DiagnosticBulkTestPk";
            CosmosClient bulkClient    = TestCommon.CreateCosmosClient(builder => builder.WithBulkExecution(true));
            Container    bulkContainer = bulkClient.GetContainer(this.database.Id, this.Container.Id);
            List <Task <ItemResponse <ToDoActivity> > > createItemsTasks = new List <Task <ItemResponse <ToDoActivity> > >();

            for (int i = 0; i < 100; i++)
            {
                ToDoActivity item = ToDoActivity.CreateRandomToDoActivity(pk: pkValue);
                createItemsTasks.Add(bulkContainer.CreateItemAsync <ToDoActivity>(item, new PartitionKey(item.status)));
            }

            await Task.WhenAll(createItemsTasks);

            foreach (Task <ItemResponse <ToDoActivity> > createTask in createItemsTasks)
            {
                ItemResponse <ToDoActivity> itemResponse = await createTask;
                Assert.IsNotNull(itemResponse);
                CosmosDiagnosticsTests.VerifyBulkPointDiagnostics(itemResponse.Diagnostics);
            }
        }
        public async Task ValidateUserAgentHeaderWithMacOs(bool useMacOs)
        {
            this.SetEnvironmentInformation(useMacOs);

            const string suffix = " UserApplicationName/1.0";

            using (CosmosClient client = TestCommon.CreateCosmosClient(builder => builder.WithApplicationName(suffix)))
            {
                Cosmos.UserAgentContainer userAgentContainer = client.ClientOptions.GetConnectionPolicy().UserAgentContainer;

                string userAgentString = userAgentContainer.UserAgent;
                Assert.IsTrue(userAgentString.Contains(suffix));
                if (useMacOs)
                {
                    Assert.IsTrue(userAgentString.Contains("Darwin 18.0.0"));
                }

                Cosmos.Database db = await client.CreateDatabaseIfNotExistsAsync(Guid.NewGuid().ToString());

                Assert.IsNotNull(db);
                await db.DeleteAsync();
            }
        }
예제 #13
0
        public async Task TestRidRefreshOnNotFoundAsync()
        {
            CosmosClient resourceClient = TestCommon.CreateCosmosClient();

            string dbName        = Guid.NewGuid().ToString();
            string containerName = Guid.NewGuid().ToString();

            Database db = await resourceClient.CreateDatabaseAsync(dbName);

            Container container = await db.CreateContainerAsync(containerName, "/_id");

            CosmosClient      testClient    = TestCommon.CreateCosmosClient();
            ContainerInternal testContainer = (ContainerInlineCore)testClient.GetContainer(dbName, containerName);

            // Populate the RID cache.
            string cachedRidAsync = await testContainer.GetCachedRIDAsync(forceRefresh : false);

            // Delete the container (using resource client).
            await container.DeleteContainerAsync();

            // Because the RID is cached, this will now try to resolve the collection routing map.
            Assert.AreEqual(cachedRidAsync, await testContainer.GetCachedRIDAsync(forceRefresh: false));
            CosmosException notFoundException = await Assert.ThrowsExceptionAsync <CosmosException>(() => testContainer.GetRoutingMapAsync(cancellationToken: default));
        public async Task QueryPlanRetryTimeoutTestAsync()
        {
            HttpClientHandlerHelper httpClientHandler = new HttpClientHandlerHelper();

            using (CosmosClient client = TestCommon.CreateCosmosClient(builder => builder
                                                                       .WithConnectionModeGateway()
                                                                       .WithHttpClientFactory(() => new HttpClient(httpClientHandler))))
            {
                Cosmos.Database database = await client.CreateDatabaseAsync(Guid.NewGuid().ToString());

                ContainerInternal container = (ContainerInternal)await database.CreateContainerAsync(Guid.NewGuid().ToString(), "/pk");

                Container gatewayQueryPlanContainer = new ContainerInlineCore(
                    client.ClientContext,
                    (DatabaseInternal)database,
                    container.Id,
                    new DisableServiceInterop(client.ClientContext, container));

                bool isQueryRequestFound = false;
                httpClientHandler.RequestCallBack = (request, cancellationToken) =>
                {
                    if (request.Headers.TryGetValues(HttpConstants.HttpHeaders.IsQueryPlanRequest, out IEnumerable <string> isQueryPlan) &&
                        isQueryPlan.FirstOrDefault() == bool.TrueString)
                    {
                        Assert.IsFalse(isQueryRequestFound, "Should only call get query plan once.");
                        Assert.AreNotEqual(cancellationToken, default);
                        isQueryRequestFound = true;
                    }
                };

                using FeedIterator <JObject> iterator = gatewayQueryPlanContainer.GetItemQueryIterator <JObject>("select * From T order by T.status");
                FeedResponse <JObject> response       = await iterator.ReadNextAsync();

                Assert.IsTrue(isQueryRequestFound, "Query plan call back was not called.");
                await database.DeleteStreamAsync();
            }
        }
예제 #15
0
        public async Task TransportExceptionValidationTest()
        {
            CosmosClient cosmosClient = TestCommon.CreateCosmosClient(
                builder =>
            {
                builder.WithTransportClientHandlerFactory(transportClient => new TransportClientWrapper(
                                                              transportClient,
                                                              TransportWrapperTests.ThrowTransportExceptionOnItemOperation));
            });

            Cosmos.Database database = await cosmosClient.CreateDatabaseAsync(Guid.NewGuid().ToString());

            Container container = await database.CreateContainerAsync(Guid.NewGuid().ToString(), "/id");

            try
            {
                TestPayload payload1 = await container.CreateItemAsync <TestPayload>(new TestPayload { id = "bad" }, new Cosmos.PartitionKey("bad"));

                Assert.Fail("Create item should fail with TransportException");
            }
            catch (CosmosException ce)
            {
                this.ValidateTransportException(ce);
            }

            try
            {
                FeedIterator <TestPayload> feedIterator = container.GetItemQueryIterator <TestPayload>("select * from T where T.Random = 19827 ");
                await feedIterator.ReadNextAsync();

                Assert.Fail("Create item should fail with TransportException");
            }
            catch (CosmosException ce)
            {
                this.ValidateTransportException(ce);
            }
        }
예제 #16
0
        public async Task VerifyRequestOptionCustomRequestHeaders()
        {
            CustomHeaderValidationHandler headerValidationHandler = new CustomHeaderValidationHandler();

            using CosmosClient client = TestCommon.CreateCosmosClient(x => x.AddCustomHandlers(headerValidationHandler));
            Database database = null;

            try
            {
                database = await client.CreateDatabaseAsync(nameof(VerifyRequestOptionCustomRequestHeaders) + Guid.NewGuid().ToString());

                Container container = await database.CreateContainerAsync(
                    Guid.NewGuid().ToString(),
                    "/pk");

                ToDoActivity       toDoActivity   = ToDoActivity.CreateRandomToDoActivity();
                ItemRequestOptions requestOptions = new ItemRequestOptions
                {
                    AddRequestHeaders = (headers) => headers["x-ms-cosmos-database-rid"] = "databaseRidValue",
                };

                await container.CreateItemAsync(toDoActivity, new PartitionKey(toDoActivity.pk), requestOptions : requestOptions);

                // null pass
                requestOptions.AddRequestHeaders = null;

                await container.ReadItemAsync <ToDoActivity>(toDoActivity.id, new PartitionKey(toDoActivity.pk), requestOptions : requestOptions);
            }
            finally
            {
                if (database != null)
                {
                    await database.DeleteStreamAsync();
                }
            }
        }
        public async Task TestCustomJsonSerializer()
        {
            int toStreamCount   = 0;
            int fromStreamCount = 0;

            Mock <CosmosSerializer> mockJsonSerializer = new Mock <CosmosSerializer>();

            //The item object will be serialized with the custom json serializer.
            ToDoActivity testItem = ToDoActivity.CreateRandomToDoActivity();

            mockJsonSerializer.Setup(x => x.ToStream <ToDoActivity>(It.IsAny <ToDoActivity>()))
            .Callback(() => toStreamCount++)
            .Returns(TestCommon.SerializerCore.ToStream <ToDoActivity>(testItem));

            mockJsonSerializer.Setup(x => x.FromStream <ToDoActivity>(It.IsAny <Stream>()))
            .Callback <Stream>(x => { x.Dispose(); fromStreamCount++; })
            .Returns(testItem);

            //Create a new cosmos client with the mocked cosmos json serializer
            CosmosClient mockClient = TestCommon.CreateCosmosClient(
                (cosmosClientBuilder) => cosmosClientBuilder.WithCustomSerializer(mockJsonSerializer.Object));
            Container mockContainer = mockClient.GetContainer(this.database.Id, this.container.Id);

            Assert.AreEqual(mockJsonSerializer.Object, mockClient.ClientOptions.Serializer);

            //Validate that the custom json serializer is used for creating the item
            ItemResponse <ToDoActivity> response = await mockContainer.CreateItemAsync <ToDoActivity>(item : testItem);

            Assert.IsNotNull(response);
            Assert.AreEqual(HttpStatusCode.Created, response.StatusCode);

            Assert.AreEqual(1, toStreamCount);
            Assert.AreEqual(1, fromStreamCount);

            await mockContainer.DeleteItemAsync <ToDoActivity>(testItem.id, new Cosmos.PartitionKey(testItem.pk));
        }
        public async Task VerifyUserAgentWithFeatures(bool setApplicationName, bool useMacOs)
        {
            this.SetEnvironmentInformation(useMacOs);

            const string suffix = " UserApplicationName/1.0";
            CosmosClientOptionsFeatures featuresFlags = CosmosClientOptionsFeatures.NoFeatures;

            featuresFlags |= CosmosClientOptionsFeatures.AllowBulkExecution;
            featuresFlags |= CosmosClientOptionsFeatures.HttpClientFactory;

            string features = Convert.ToString((int)featuresFlags, 2).PadLeft(8, '0');

            Action <Fluent.CosmosClientBuilder> applicationNameBuilder = (builder) =>
            {
                if (setApplicationName)
                {
                    builder.WithApplicationName(suffix);
                }
            };

            using (CosmosClient client = TestCommon.CreateCosmosClient(builder => applicationNameBuilder(builder.WithBulkExecution(true).WithHttpClientFactory(() => new HttpClient()))))
            {
                Cosmos.UserAgentContainer userAgentContainer = client.ClientOptions.GetConnectionPolicy().UserAgentContainer;

                string userAgentString = userAgentContainer.UserAgent;
                if (setApplicationName)
                {
                    Assert.IsTrue(userAgentString.Contains(suffix));
                }
                else
                {
                    Assert.IsFalse(userAgentString.Contains(suffix));
                }

                Assert.IsTrue(userAgentString.Contains($"|F {features}"));
                if (useMacOs)
                {
                    Assert.IsTrue(userAgentString.Contains("Darwin 18.0.0"));
                }

                Cosmos.Database db = await client.CreateDatabaseIfNotExistsAsync(Guid.NewGuid().ToString());

                Assert.IsNotNull(db);
                await db.DeleteAsync();
            }

            using (CosmosClient client = TestCommon.CreateCosmosClient(builder => applicationNameBuilder(builder)))
            {
                Cosmos.UserAgentContainer userAgentContainer = client.ClientOptions.GetConnectionPolicy().UserAgentContainer;

                string userAgentString = userAgentContainer.UserAgent;
                if (setApplicationName)
                {
                    Assert.IsTrue(userAgentString.Contains(suffix));
                }
                else
                {
                    Assert.IsFalse(userAgentString.Contains(suffix));
                }

                Assert.IsFalse(userAgentString.Contains($"|F {features}"));
            }
        }
예제 #19
0
        public async Task ValidateCollectionIndexProgressHeadersRntbd()
        {
            var client = TestCommon.CreateCosmosClient(false);

            await ValidateCollectionIndexProgressHeaders(client);
        }
예제 #20
0
        public async Task ValidateCollectionIndexProgressHeadersGateway()
        {
            var client = TestCommon.CreateCosmosClient(true);

            await ValidateCollectionIndexProgressHeaders(client);
        }
예제 #21
0
        public async Task QueryRequestRateTest(bool directMode)
        {
            string firstItemIdAndPk = "BasicQueryItem" + Guid.NewGuid();

            // Prevent the test from changing the static client
            {
                CosmosClient client    = directMode ? DirectCosmosClient : GatewayCosmosClient;
                Container    container = client.GetContainer(DatabaseId, ContainerId);

                List <string> createdIds = new List <string>()
                {
                    firstItemIdAndPk,
                    "BasicQueryItem2" + Guid.NewGuid(),
                    "BasicQueryItem3" + Guid.NewGuid()
                };

                foreach (string id in createdIds)
                {
                    dynamic item = new
                    {
                        id = id,
                        pk = id,
                    };

                    await container.CreateItemAsync <dynamic>(item : item);
                }
            }

            CosmosClient clientWithThrottle;

            if (directMode)
            {
                clientWithThrottle = TestCommon.CreateCosmosClient();
            }
            else
            {
                clientWithThrottle = TestCommon.CreateCosmosClient((builder) => builder.WithConnectionModeGateway());
            }

            Container containerWithThrottle = clientWithThrottle.GetContainer(DatabaseId, ContainerId);

            // Do a read to warm up all the caches to prevent them from getting the throttle errors
            using (await containerWithThrottle.ReadItemStreamAsync(firstItemIdAndPk, new PartitionKey(firstItemIdAndPk))) { }

            Documents.IStoreModel        storeModel = clientWithThrottle.ClientContext.DocumentClient.StoreModel;
            Mock <Documents.IStoreModel> mockStore  = new Mock <Documents.IStoreModel>();

            clientWithThrottle.ClientContext.DocumentClient.StoreModel = mockStore.Object;

            // Cause 429 after the first call
            int    callCount    = 0;
            string activityId   = null;
            string errorMessage = "QueryRequestRateTest Resource Not Found";

            mockStore.Setup(x => x.ProcessMessageAsync(It.IsAny <Documents.DocumentServiceRequest>(), It.IsAny <CancellationToken>()))
            .Returns <Documents.DocumentServiceRequest, CancellationToken>((dsr, token) =>
            {
                callCount++;

                if (callCount > 1)
                {
                    INameValueCollection headers = new StoreRequestNameValueCollection();
                    headers.Add(Documents.HttpConstants.HttpHeaders.RetryAfterInMilliseconds, "42");
                    activityId = Guid.NewGuid().ToString();
                    headers.Add(Documents.HttpConstants.HttpHeaders.ActivityId, activityId);
                    Documents.DocumentServiceResponse response = new Documents.DocumentServiceResponse(
                        body: TestCommon.GenerateStreamFromString(@"{""Errors"":[""" + errorMessage + @"""]}"),
                        headers: headers,
                        statusCode: (HttpStatusCode)429,
                        clientSideRequestStatistics: dsr.RequestContext.ClientRequestStatistics);

                    return(Task.FromResult(response));
                }

                return(storeModel.ProcessMessageAsync(dsr, token));
            });

            List <dynamic> results = new List <dynamic>();

            try
            {
                using (FeedIterator <dynamic> feedIterator = containerWithThrottle.GetItemQueryIterator <dynamic>(
                           "select * from T where STARTSWITH(T.id, \"BasicQueryItem\")",
                           requestOptions: new QueryRequestOptions()
                {
                    MaxItemCount = 1,
                    MaxConcurrency = 1
                }))
                {
                    while (feedIterator.HasMoreResults)
                    {
                        FeedResponse <dynamic> response = await feedIterator.ReadNextAsync();

                        Assert.IsTrue(response.Count <= 1);
                        Assert.IsTrue(response.Resource.Count() <= 1);

                        results.AddRange(response);
                    }
                }
                Assert.Fail("Should throw 429 exception after the first page.");
            }
            catch (CosmosException ce)
            {
                Assert.IsTrue(ce.RetryAfter.HasValue);
                Assert.AreEqual(42, ce.RetryAfter.Value.TotalMilliseconds);
                Assert.AreEqual(activityId, ce.ActivityId);
                Assert.IsNotNull(ce.DiagnosticsContext);
                Assert.IsTrue(ce.Message.Contains(errorMessage));
            }

            callCount = 0;
            FeedIterator streamIterator = containerWithThrottle.GetItemQueryStreamIterator(
                "select * from T where STARTSWITH(T.id, \"BasicQueryItem\")",
                requestOptions: new QueryRequestOptions()
            {
                MaxItemCount   = 1,
                MaxConcurrency = 1
            });

            // First request should be a success
            using (ResponseMessage response = await streamIterator.ReadNextAsync())
            {
                response.EnsureSuccessStatusCode();
                Assert.IsNotNull(response.Content);
            }

            // Second page should be a failure
            using (ResponseMessage response = await streamIterator.ReadNextAsync())
            {
                Assert.AreEqual(429, (int)response.StatusCode);
                Assert.AreEqual("42", response.Headers.RetryAfterLiteral);
                Assert.AreEqual(activityId, response.Headers.ActivityId);
                Assert.IsNotNull(response.DiagnosticsContext);
                Assert.IsTrue(response.ErrorMessage.Contains(errorMessage));
            }
        }
        public async Task  TestJsonSerializerSettings(bool useGateway)
        {
            CosmosClient cosmosClient = TestCommon.CreateCosmosClient((cosmosClientBuilder) => {
                if (useGateway)
                {
                    cosmosClientBuilder.WithCustomSerializer(new CustomJsonSerializer(CustomSerializationTests.GetSerializerWithCustomConverterAndBinder())).WithConnectionModeGateway();
                }
                else
                {
                    cosmosClientBuilder.WithCustomSerializer(new CustomJsonSerializer(CustomSerializationTests.GetSerializerWithCustomConverterAndBinder())).WithConnectionModeDirect();
                }
            });
            Container container = cosmosClient.GetContainer(this.databaseName, this.partitionedCollectionName);

            Random rnd = new Random();

            byte[] bytes = new byte[100];
            rnd.NextBytes(bytes);
            TestDocument testDocument = new TestDocument(new KerberosTicketHashKey(bytes));

            //create and read
            ItemResponse <TestDocument> createResponse = await container.CreateItemAsync <TestDocument>(testDocument);

            ItemResponse <TestDocument> readResponse = await container.ReadItemAsync <TestDocument>(testDocument.Id, new Cosmos.PartitionKey(testDocument.Name));

            this.AssertEqual(testDocument, readResponse.Resource);
            this.AssertEqual(testDocument, createResponse.Resource);

            // upsert
            ItemResponse <TestDocument> upsertResponse = await container.UpsertItemAsync <TestDocument>(testDocument);

            readResponse = await container.ReadItemAsync <TestDocument>(testDocument.Id, new Cosmos.PartitionKey(testDocument.Name));

            this.AssertEqual(testDocument, readResponse.Resource);
            this.AssertEqual(testDocument, upsertResponse.Resource);

            // replace
            ItemResponse <TestDocument> replacedResponse = await container.ReplaceItemAsync <TestDocument>(testDocument, testDocument.Id);

            readResponse = await container.ReadItemAsync <TestDocument>(testDocument.Id, new Cosmos.PartitionKey(testDocument.Name));

            this.AssertEqual(testDocument, readResponse.Resource);
            this.AssertEqual(testDocument, replacedResponse.Resource);

            QueryDefinition             sql          = new QueryDefinition("select * from r");
            FeedIterator <TestDocument> feedIterator =
                container.GetItemQueryIterator <TestDocument>(queryDefinition: sql, requestOptions: new QueryRequestOptions()
            {
                MaxItemCount = 1
            });

            List <TestDocument> allDocuments = new List <TestDocument>();

            while (feedIterator.HasMoreResults)
            {
                allDocuments.AddRange(await feedIterator.ReadNextAsync());
            }

            this.AssertEqual(testDocument, allDocuments.First());

            //Will add LINQ test once it is available with new V3 OM
            // // LINQ Lambda
            // var query1 = client.CreateDocumentQuery<TestDocument>(partitionedCollectionUri, options)
            //            .Where(_ => _.Id.CompareTo(String.Empty) > 0)
            //            .Select(_ => _.Id);
            // string query1Str = query1.ToString();
            // var result = query1.ToList();
            // Assert.AreEqual(1, result.Count);
            // Assert.AreEqual(testDocument.Id, result[0]);

            // // LINQ Query
            // var query2 =
            //     from f in client.CreateDocumentQuery<TestDocument>(partitionedCollectionUri, options)
            //     where f.Id.CompareTo(String.Empty) > 0
            //     select f.Id;
            // string query2Str = query2.ToString();
            // var result2 = query2.ToList();
            // Assert.AreEqual(1, result2.Count);
            // Assert.AreEqual(testDocument.Id, result2[0]);
        }
        public async Task ReadReplaceThroughputResponseTests()
        {
            int toStreamCount   = 0;
            int fromStreamCount = 0;

            CosmosSerializerHelper mockJsonSerializer = new CosmosSerializerHelper(
                null,
                (x) => fromStreamCount++,
                (x) => toStreamCount++);

            //Create a new cosmos client with the mocked cosmos json serializer
            CosmosClient client = TestCommon.CreateCosmosClient(
                (cosmosClientBuilder) => cosmosClientBuilder.WithCustomSerializer(mockJsonSerializer));

            int databaseThroughput = 10000;

            Cosmos.Database databaseNoThroughput = await client.CreateDatabaseAsync(Guid.NewGuid().ToString(), null);

            Cosmos.Database databaseWithThroughput = await client.CreateDatabaseAsync(Guid.NewGuid().ToString(), databaseThroughput, null);


            string    containerId           = Guid.NewGuid().ToString();
            string    partitionPath         = "/users";
            Container containerNoThroughput = await databaseWithThroughput.CreateContainerAsync(containerId, partitionPath, throughput : null);

            try
            {
                await containerNoThroughput.ReadThroughputAsync(new RequestOptions());

                Assert.Fail("Should through not found exception as throughput is not configured");
            }
            catch (CosmosException exception)
            {
                Assert.AreEqual(HttpStatusCode.NotFound, exception.StatusCode);
            }

            try
            {
                await containerNoThroughput.ReplaceThroughputAsync(2000, new RequestOptions());

                Assert.Fail("Should through not found exception as throughput is not configured");
            }
            catch (CosmosException exception)
            {
                Assert.AreEqual(HttpStatusCode.NotFound, exception.StatusCode);
            }

            int       containerThroughput = 1000;
            Container container           = await databaseNoThroughput.CreateContainerAsync(Guid.NewGuid().ToString(), "/id", throughput : containerThroughput);

            int?containerResponseThroughput = await container.ReadThroughputAsync();

            Assert.AreEqual(containerThroughput, containerResponseThroughput);

            ThroughputResponse containerThroughputResponse = await container.ReadThroughputAsync(new RequestOptions());

            Assert.IsNotNull(containerThroughputResponse);
            Assert.IsNotNull(containerThroughputResponse.Resource);
            Assert.IsNotNull(containerThroughputResponse.MinThroughput);
            Assert.IsNotNull(containerThroughputResponse.Resource.Throughput);
            Assert.AreEqual(containerThroughput, containerThroughputResponse.Resource.Throughput.Value);

            containerThroughput        += 500;
            containerThroughputResponse = await container.ReplaceThroughputAsync(containerThroughput, new RequestOptions());

            Assert.IsNotNull(containerThroughputResponse);
            Assert.IsNotNull(containerThroughputResponse.Resource);
            Assert.IsNotNull(containerThroughputResponse.Resource.Throughput);
            Assert.AreEqual(containerThroughput, containerThroughputResponse.Resource.Throughput.Value);

            Assert.AreEqual(0, toStreamCount, "Custom serializer to stream should not be used for offer operations");
            Assert.AreEqual(0, fromStreamCount, "Custom serializer from stream should not be used for offer operations");
            await databaseNoThroughput.DeleteAsync();
        }
 public void TestInit()
 {
     this.cosmosClient = TestCommon.CreateCosmosClient();
 }
예제 #25
0
 public async Task TestInitializeAsync()
 {
     this.client   = TestCommon.CreateCosmosClient(true);
     this.database = await this.client.CreateDatabaseAsync(Guid.NewGuid().ToString());
 }
        public async Task PointOperationThrottledDiagnostic(bool disableDiagnostics)
        {
            string errorMessage        = "Mock throttle exception" + Guid.NewGuid().ToString();
            Guid   exceptionActivityId = Guid.NewGuid();
            // Set a small retry count to reduce test time
            CosmosClient throttleClient = TestCommon.CreateCosmosClient(builder =>
                                                                        builder.WithThrottlingRetryOptions(TimeSpan.FromSeconds(5), 5)
                                                                        .WithTransportClientHandlerFactory(transportClient => new TransportClientWrapper(
                                                                                                               transportClient,
                                                                                                               (uri, resourceOperation, request) => TransportClientHelper.ReturnThrottledStoreResponseOnItemOperation(
                                                                                                                   uri,
                                                                                                                   resourceOperation,
                                                                                                                   request,
                                                                                                                   exceptionActivityId,
                                                                                                                   errorMessage)))
                                                                        );

            ItemRequestOptions requestOptions = new ItemRequestOptions();

            if (disableDiagnostics)
            {
                requestOptions.DiagnosticContextFactory = () => EmptyCosmosDiagnosticsContext.Singleton;
            }
            ;

            Container containerWithThrottleException = throttleClient.GetContainer(
                this.database.Id,
                this.Container.Id);

            //Checking point operation diagnostics on typed operations
            ToDoActivity testItem = ToDoActivity.CreateRandomToDoActivity();

            try
            {
                ItemResponse <ToDoActivity> createResponse = await containerWithThrottleException.CreateItemAsync <ToDoActivity>(
                    item : testItem,
                    requestOptions : requestOptions);

                Assert.Fail("Should have thrown a request timeout exception");
            }
            catch (CosmosException ce) when((int)ce.StatusCode == (int)Documents.StatusCodes.TooManyRequests)
            {
                string exception = ce.ToString();

                Assert.IsNotNull(exception);
                Assert.IsTrue(exception.Contains(exceptionActivityId.ToString()));
                Assert.IsTrue(exception.Contains(errorMessage));

                string diagnosics = ce.Diagnostics.ToString();

                if (disableDiagnostics)
                {
                    Assert.IsTrue(string.IsNullOrEmpty(diagnosics));
                }
                else
                {
                    Assert.IsFalse(string.IsNullOrEmpty(diagnosics));
                    Assert.IsTrue(exception.Contains(diagnosics));
                    DiagnosticValidator.ValidatePointOperationDiagnostics(ce.DiagnosticsContext);
                }
            }
        }
예제 #27
0
        public static void ClassSetup(TestContext testContext = null)
        {
            CosmosClient client = TestCommon.CreateCosmosClient(false);

            QueryTestsBase.CleanUp(client).Wait();
        }
        public async Task InvalidSessionTokenAfterContainerRecreationAndCollectionCacheRefreshReproTest()
        {
            // ingestionClinet is dedicated client simulating the writes / container recreation in
            // the separate process - like Spark job
            using CosmosClient ingestionClient = TestCommon.CreateCosmosClient();
            Cosmos.Database ingestionDatabase = ingestionClient.GetDatabase(this.database.Id);

            ContainerProperties multiPartitionContainerSettings =
                new ContainerProperties(id: Guid.NewGuid().ToString(), partitionKeyPath: "/pk");
            Container ingestionContainer =
                await ingestionDatabase.CreateContainerAsync(multiPartitionContainerSettings);

            const int itemCountToBeIngested = 10;
            string    pk        = Guid.NewGuid().ToString("N");
            long?     latestLsn = null;

            Console.WriteLine("INGEST DOCUMENTS");
            for (int i = 0; i < itemCountToBeIngested; i++)
            {
                ToDoActivity testItem = ToDoActivity.CreateRandomToDoActivity();
                testItem.pk = pk;

                ItemResponse <ToDoActivity> response =
                    await ingestionContainer.CreateItemAsync <ToDoActivity>(item : testItem);

                Assert.IsNotNull(response);
                Assert.IsNotNull(response.Resource);
                Assert.IsNotNull(response.Diagnostics);
                long?lsnAfterCreate = await GetLSNFromSessionContainer(
                    ingestionContainer, multiPartitionContainerSettings, new PartitionKey(pk));

                Assert.IsNotNull(lsnAfterCreate);
                Assert.IsTrue(latestLsn == null || lsnAfterCreate.Value > latestLsn.Value);
                latestLsn = lsnAfterCreate;
                CosmosTraceDiagnostics diagnostics = (CosmosTraceDiagnostics)response.Diagnostics;
                Assert.IsFalse(diagnostics.IsGoneExceptionHit());
                Assert.IsFalse(string.IsNullOrEmpty(diagnostics.ToString()));
                Assert.IsTrue(diagnostics.GetClientElapsedTime() > TimeSpan.Zero);
            }

            // Dedciated query client used only for queries simulating the customer's app
            string    lastRequestedSessionToken = null;
            Container queryContainer            = TransportClientHelper.GetContainerWithIntercepter(
                this.database.Id,
                ingestionContainer.Id,
                (uri, operation, request) =>
            {
                if (request.ResourceType == ResourceType.Document &&
                    request.OperationType == OperationType.Query)
                {
                    lastRequestedSessionToken = request.Headers[HttpConstants.HttpHeaders.SessionToken];
                }
            },
                false,
                null);

            long?lsnAfterQueryOnOldContainer = null;

            // Issueing two queries - first won't use session tokens yet
            // second will provide session tokens captured from first request in the request to the backend
            for (int i = 0; i < 2; i++)
            {
                Console.WriteLine("RUN QUERY ON OLD CONTAINER ({0})", i);
                using FeedIterator <JObject> queryIteratorOldContainer = queryContainer.GetItemQueryIterator <JObject>(
                          new QueryDefinition("Select c.id FROM c"),
                          continuationToken: null,
                          new QueryRequestOptions
                {
                    ConsistencyLevel = Cosmos.ConsistencyLevel.Session,
                    PartitionKey     = new Cosmos.PartitionKey(pk)
                });
                int itemCountOldContainer = 0;
                while (queryIteratorOldContainer.HasMoreResults)
                {
                    FeedResponse <JObject> response = await queryIteratorOldContainer.ReadNextAsync();

                    if (i == 0)
                    {
                        string diagnosticString = response.Diagnostics.ToString();
                        Assert.IsTrue(diagnosticString.Contains("PKRangeCache Info("));
                        JObject diagnosticJobject = JObject.Parse(diagnosticString);
                        JToken  actualToken       = diagnosticJobject.SelectToken("$.children[0].children[?(@.name=='Get Partition Key Ranges')].children[?(@.name=='Try Get Overlapping Ranges')].data");
                        JToken  actualNode        = actualToken.Children().First().First();

                        Assert.IsTrue(actualNode["Previous Continuation Token"].ToString().Length == 0);
                        Assert.IsTrue(actualNode["Continuation Token"].ToString().Length > 0);
                    }

                    itemCountOldContainer += response.Count;
                }

                Assert.AreEqual(itemCountToBeIngested, itemCountOldContainer);
                lsnAfterQueryOnOldContainer = await GetLSNFromSessionContainer(
                    queryContainer, multiPartitionContainerSettings, new PartitionKey(pk));

                Assert.IsNotNull(lsnAfterQueryOnOldContainer);
                Assert.AreEqual(latestLsn.Value, lsnAfterQueryOnOldContainer.Value);
                if (i == 0)
                {
                    Assert.IsNull(lastRequestedSessionToken);
                }
                else
                {
                    Assert.IsNotNull(lastRequestedSessionToken);
                    Assert.AreEqual(latestLsn.Value, SessionTokenHelper.Parse(lastRequestedSessionToken).LSN);
                }
            }

            Console.WriteLine(
                "DELETE CONTAINER {0}",
                (await queryContainer.ReadContainerAsync()).Resource.ResourceId);
            await ingestionContainer.DeleteContainerAsync();

            Console.WriteLine("RECREATING CONTAINER...");
            ContainerResponse ingestionContainerResponse =
                await ingestionDatabase.CreateContainerAsync(multiPartitionContainerSettings);

            ingestionContainer = ingestionContainerResponse.Container;

            string responseSessionTokenValue =
                ingestionContainerResponse.Headers[HttpConstants.HttpHeaders.SessionToken];
            long?lsnAfterRecreatingContainerFromIngestionClient = responseSessionTokenValue != null?
                                                                  SessionTokenHelper.Parse(responseSessionTokenValue).LSN : null;

            Console.WriteLine(
                "RECREATED CONTAINER with new CollectionRid: {0} - LSN: {1}",
                ingestionContainerResponse.Resource.ResourceId,
                lsnAfterRecreatingContainerFromIngestionClient);

            // validates that the query container still uses the LSN captured from the old LSN
            long?lsnAfterCreatingNewContainerFromQueryClient = await GetLSNFromSessionContainer(
                queryContainer, multiPartitionContainerSettings, new PartitionKey(pk));

            Assert.IsNotNull(lsnAfterCreatingNewContainerFromQueryClient);
            Assert.AreEqual(latestLsn.Value, lsnAfterCreatingNewContainerFromQueryClient.Value);

            Console.WriteLine("GET FEED RANGES");
            // this will force a CollectionCache refresh - because no pk ranegs can be identified
            // for the old container anymore
            _ = await queryContainer.GetFeedRangesAsync();


            Console.WriteLine("RUN QUERY ON NEW CONTAINER");
            int itemCountNewContainer = 0;

            using FeedIterator <JObject> queryIteratorNewContainer = queryContainer.GetItemQueryIterator <JObject>(
                      new QueryDefinition("Select c.id FROM c"),
                      continuationToken: null,
                      new QueryRequestOptions
            {
                ConsistencyLevel = Cosmos.ConsistencyLevel.Session,
                PartitionKey     = new Cosmos.PartitionKey(pk),
            });
            Console.WriteLine("Query iterator created");
            while (queryIteratorNewContainer.HasMoreResults)
            {
                Console.WriteLine("Retrieving first page");
                try
                {
                    FeedResponse <JObject> response = await queryIteratorNewContainer.ReadNextAsync();

                    Console.WriteLine("Request Diagnostics for query against new container: {0}",
                                      response.Diagnostics.ToString());
                    itemCountNewContainer += response.Count;
                }
                catch (CosmosException cosmosException)
                {
                    Console.WriteLine("COSMOS EXCEPTION: {0}", cosmosException);
                    throw;
                }
            }

            Assert.AreEqual(0, itemCountNewContainer);
            long?lsnAfterQueryOnNewContainer = await GetLSNFromSessionContainer(
                queryContainer, multiPartitionContainerSettings, new PartitionKey(pk));

            Assert.IsNotNull(lsnAfterQueryOnNewContainer);
            Assert.IsTrue(
                lastRequestedSessionToken == null ||
                SessionTokenHelper.Parse(lastRequestedSessionToken).LSN ==
                lsnAfterRecreatingContainerFromIngestionClient,
                $"The requested session token {lastRequestedSessionToken} on the last query request should be null " +
                $"or have LSN '{lsnAfterRecreatingContainerFromIngestionClient}' (which is the LSN after " +
                "re-creating the container) if the session cache or the new CollectionName to Rid mapping was " +
                "correctly populated in the SessionCache.");
        }
예제 #29
0
        private static void InitializeDirectContainers()
        {
            BatchTestBase.Client   = TestCommon.CreateCosmosClient();
            BatchTestBase.Database = BatchTestBase.Client.CreateDatabaseAsync(Guid.NewGuid().ToString())
                                     .GetAwaiter().GetResult().Database;

            PartitionKeyDefinition partitionKeyDefinition = new PartitionKeyDefinition();

            partitionKeyDefinition.Paths.Add("/Status");

            BatchTestBase.LowThroughputJsonContainer = BatchTestBase.Database.CreateContainerAsync(
                new ContainerProperties()
            {
                Id           = Guid.NewGuid().ToString(),
                PartitionKey = partitionKeyDefinition
            },
                throughput: 400).GetAwaiter().GetResult().Container;

            BatchTestBase.PartitionKeyDefinition = ((ContainerCore)(ContainerInlineCore)BatchTestBase.LowThroughputJsonContainer).GetPartitionKeyDefinitionAsync(CancellationToken.None).GetAwaiter().GetResult();

            // Create a container with at least 2 physical partitions for effective cross-partition testing
            BatchTestBase.JsonContainer = BatchTestBase.Database.CreateContainerAsync(
                new ContainerProperties()
            {
                Id           = Guid.NewGuid().ToString(),
                PartitionKey = BatchTestBase.PartitionKeyDefinition
            },
                throughput: 12000).GetAwaiter().GetResult().Container;

            Serialization.HybridRow.Schemas.Schema testSchema = TestDoc.GetSchema();
            Namespace testNamespace = new Namespace()
            {
                Name    = "Test",
                Version = SchemaLanguageVersion.V1,
                Schemas = new List <Serialization.HybridRow.Schemas.Schema>()
                {
                    testSchema
                }
            };

            BatchTestBase.LayoutResolver = new LayoutResolverNamespace(testNamespace);
            BatchTestBase.TestDocLayout  = BatchTestBase.LayoutResolver.Resolve(testSchema.SchemaId);

            BatchContainerProperties schematizedContainerProperties = new BatchContainerProperties()
            {
                Id                = Guid.NewGuid().ToString(),
                PartitionKey      = BatchTestBase.PartitionKeyDefinition,
                DefaultTimeToLive = (int)TimeSpan.FromDays(1).TotalSeconds // allow for TTL testing
            };

            SchemaPolicy schemaPolicy = new SchemaPolicy()
            {
                TableSchema = testNamespace,
            };

            schematizedContainerProperties.SchemaPolicy = schemaPolicy;

            BatchTestBase.SchematizedContainer = BatchTestBase.Database.CreateContainerAsync(
                schematizedContainerProperties,
                throughput: 12000).GetAwaiter().GetResult().Container;
        }
 public static void Initialize(TestContext textContext)
 {
     CosmosNotFoundTests.client = TestCommon.CreateCosmosClient();
 }