public async Task InexistentPKRangeId()
        {
            ContainerInternal container = null;

            try
            {
                // Create a container large enough to have at least 2 partitions
                ContainerResponse containerResponse = await this.database.CreateContainerAsync(
                    id : Guid.NewGuid().ToString(),
                    partitionKeyPath : "/pk");

                container = (ContainerInlineCore)containerResponse;

                string    feedRangeSerialization = JsonConvert.SerializeObject(new { PKRangeId = "10" });
                FeedRange feedRange = FeedRange.FromJsonString(feedRangeSerialization);

                FeedIterator <ToDoActivity> feedIterator = container.GetItemQueryIterator <ToDoActivity>(
                    queryDefinition: new QueryDefinition("select * from T where STARTSWITH(T.id, \"BasicItem\")"),
                    feedRange: feedRange,
                    continuationToken: null);

                CosmosException exception = await Assert.ThrowsExceptionAsync <CosmosException>(() => feedIterator.ReadNextAsync());

                Assert.AreEqual(HttpStatusCode.Gone, exception.StatusCode);
                Assert.AreEqual((int)Documents.SubStatusCodes.PartitionKeyRangeGone, exception.SubStatusCode);
            }
            finally
            {
                await container?.DeleteContainerAsync();
            }
        }
        public async Task ReadFeedIteratorCore_OfT_WithFeedRange_ReadAll_StopResume()
        {
            int batchSize = 1000;

            await this.CreateRandomItems(this.LargerContainer, batchSize, randomPartitionKey : true);

            ContainerInternal         itemsCore = this.LargerContainer;
            IReadOnlyList <FeedRange> tokens    = await itemsCore.GetFeedRangesAsync();

            List <Task <int> > tasks = tokens.Select(token => Task.Run(async() =>
            {
                int count = 0;
                FeedIterator <ToDoActivity> feedIterator = itemsCore.GetItemQueryIterator <ToDoActivity>(queryDefinition: null, feedRange: token);
                string continuation = null;
                while (feedIterator.HasMoreResults)
                {
                    FeedResponse <ToDoActivity> response = await feedIterator.ReadNextAsync(this.cancellationToken);
                    count       += response.Count;
                    continuation = response.ContinuationToken;
                    break;
                }

                feedIterator = itemsCore.GetItemQueryIterator <ToDoActivity>(queryDefinition: null, continuationToken: continuation);
                while (feedIterator.HasMoreResults)
                {
                    FeedResponse <ToDoActivity> response = await feedIterator.ReadNextAsync(this.cancellationToken);
                    count += response.Count;
                }

                return(count);
            })).ToList();

            await Task.WhenAll(tasks);

            int documentsRead = 0;

            foreach (Task <int> task in tasks)
            {
                documentsRead += task.Result;
            }

            Assert.AreEqual(batchSize, documentsRead);
        }
        public async Task ReadFeedIteratorCore_OfT_ReadAll_StopResume()
        {
            int totalCount = 0;
            int batchSize  = 50;

            await this.CreateRandomItems(this.LargerContainer, batchSize, randomPartitionKey : true);

            ContainerInternal           itemsCore    = this.LargerContainer;
            FeedIterator <ToDoActivity> feedIterator = itemsCore.GetItemQueryIterator <ToDoActivity>(queryDefinition: null, requestOptions: new QueryRequestOptions()
            {
                MaxItemCount = 1
            });
            string continuation = null;

            while (feedIterator.HasMoreResults)
            {
                FeedResponse <ToDoActivity> response = await feedIterator.ReadNextAsync(this.cancellationToken);

                totalCount  += response.Count;
                continuation = response.ContinuationToken;
                break;
            }

            feedIterator = itemsCore.GetItemQueryIterator <ToDoActivity>(queryDefinition: null, continuationToken: continuation, requestOptions: new QueryRequestOptions()
            {
                MaxItemCount = 1
            });
            while (feedIterator.HasMoreResults)
            {
                FeedResponse <ToDoActivity> response = await feedIterator.ReadNextAsync(this.cancellationToken);

                totalCount += response.Count;
            }

            Assert.AreEqual(batchSize, totalCount);
        }
        // One of query or queryDefinition is to be passed in non-null
        private static async Task ValidateQueryResultsAsync(
            ContainerInternal containerCore,
            string query                    = null,
            TestDoc expectedDoc             = null,
            QueryDefinition queryDefinition = null)
        {
            QueryRequestOptions requestOptions = expectedDoc != null ? new QueryRequestOptions()
            {
                PartitionKey = new PartitionKey(expectedDoc.PK)
            } : null;
            FeedIterator <TestDoc> queryResponseIterator;

            if (query != null)
            {
                queryResponseIterator = containerCore.GetItemQueryIterator <TestDoc>(query, requestOptions: requestOptions);
            }
            else
            {
                queryResponseIterator = containerCore.GetItemQueryIterator <TestDoc>(queryDefinition, requestOptions: requestOptions);
            }

            FeedResponse <TestDoc> readDocs = await queryResponseIterator.ReadNextAsync();

            Assert.AreEqual(null, readDocs.ContinuationToken);

            if (expectedDoc != null)
            {
                Assert.AreEqual(1, readDocs.Count);
                TestDoc readDoc = readDocs.Single();
                Assert.AreEqual(expectedDoc, readDoc);
            }
            else
            {
                Assert.AreEqual(0, readDocs.Count);
            }
        }
        private static async Task ValidateQueryResultsMultipleDocumentsAsync(
            ContainerInternal containerCore,
            TestDoc testDoc1,
            TestDoc testDoc2,
            string query)
        {
            FeedIterator <TestDoc> queryResponseIterator = containerCore.GetItemQueryIterator <TestDoc>(query);
            FeedResponse <TestDoc> readDocs = await queryResponseIterator.ReadNextAsync();

            Assert.AreEqual(null, readDocs.ContinuationToken);
            Assert.AreEqual(2, readDocs.Count);
            foreach (TestDoc readDoc in readDocs)
            {
                Assert.AreEqual(readDoc, readDoc.Id.Equals(testDoc1.Id) ? testDoc1 : testDoc2);
            }
        }
        public async Task ParallelizeQueryThroughTokens_OfT()
        {
            ContainerInternal container = null;

            try
            {
                // Create a container large enough to have at least 2 partitions
                ContainerResponse containerResponse = await this.database.CreateContainerAsync(
                    id : Guid.NewGuid().ToString(),
                    partitionKeyPath : "/id",
                    throughput : 15000);

                container = (ContainerInlineCore)containerResponse;

                List <string> generatedIds = Enumerable.Range(0, 1000).Select(n => $"BasicItem{n}").ToList();
                foreach (string id in generatedIds)
                {
                    string item = $@"
                    {{    
                        ""id"": ""{id}""
                    }}";

                    using (ResponseMessage createResponse = await container.CreateItemStreamAsync(
                               QueryFeedRangeTests.GenerateStreamFromString(item),
                               new Cosmos.PartitionKey(id)))
                    {
                        Assert.IsTrue(createResponse.IsSuccessStatusCode);
                    }
                }

                IReadOnlyList <FeedRange> feedTokens = await container.GetFeedRangesAsync();

                Assert.IsTrue(feedTokens.Count > 1, " RUs of the container needs to be increased to ensure at least 2 partitions.");

                List <Task <List <string> > > tasks = feedTokens.Select(async feedToken =>
                {
                    List <string> results = new List <string>();
                    FeedIterator <ToDoActivity> feedIterator = container.GetItemQueryIterator <ToDoActivity>(queryDefinition: new QueryDefinition("select * from T where STARTSWITH(T.id, \"BasicItem\")"), feedRange: feedToken, requestOptions: new QueryRequestOptions()
                    {
                        MaxItemCount = 10
                    });
                    string continuation = null;
                    while (feedIterator.HasMoreResults)
                    {
                        FeedResponse <ToDoActivity> response = await feedIterator.ReadNextAsync();
                        foreach (ToDoActivity toDoActivity in response)
                        {
                            results.Add(toDoActivity.id);
                        }

                        continuation = response.ContinuationToken;
                        break;
                    }

                    feedIterator = container.GetItemQueryIterator <ToDoActivity>(queryDefinition: new QueryDefinition("select * from T where STARTSWITH(T.id, \"BasicItem\")"), feedRange: feedToken, continuationToken: continuation, requestOptions: new QueryRequestOptions()
                    {
                        MaxItemCount = 10
                    });
                    while (feedIterator.HasMoreResults)
                    {
                        FeedResponse <ToDoActivity> response = await feedIterator.ReadNextAsync();
                        foreach (ToDoActivity toDoActivity in response)
                        {
                            results.Add(toDoActivity.id);
                        }
                    }

                    return(results);
                }).ToList();

                await Task.WhenAll(tasks);

                CollectionAssert.AreEquivalent(generatedIds, tasks.SelectMany(t => t.Result).ToList());
            }
            finally
            {
                await container?.DeleteContainerAsync();
            }
        }