Beispiel #1
0
        public async Task Tracing()
        {
            List <CosmosObject> documents = new List <CosmosObject>();

            for (int i = 0; i < 250; i++)
            {
                documents.Add(CosmosObject.Parse($"{{\"pk\" : {i} }}"));
            }

            IDocumentContainer documentContainer = await CreateDocumentContainerAsync(documents);

            IQueryPipelineStage pipelineStage = CreatePipeline(documentContainer, "SELECT * FROM c", pageSize: 10);

            Trace rootTrace;
            int   numTraces = 1;

            using (rootTrace = Trace.GetRootTrace("Cross Partition Query"))
            {
                while (await pipelineStage.MoveNextAsync(rootTrace))
                {
                    TryCatch <QueryPage> tryGetQueryPage = pipelineStage.Current;
                    tryGetQueryPage.ThrowIfFailed();

                    numTraces++;
                }
            }

            string traceString = TraceWriter.TraceToText(rootTrace);

            Console.WriteLine(traceString);

            Assert.AreEqual(numTraces, rootTrace.Children.Count);
        }
        public async Task Tracing()
        {
            List <CosmosObject> documents = new List <CosmosObject>();

            for (int i = 0; i < 250; i++)
            {
                documents.Add(CosmosObject.Parse($"{{\"pk\" : {i} }}"));
            }

            IDocumentContainer documentContainer = await CreateDocumentContainerAsync(documents);

            IQueryPipelineStage pipelineStage = await CreatePipelineAsync(documentContainer, "SELECT * FROM c", pageSize : 10);

            Trace rootTrace;
            int   numTraces = (await documentContainer.GetFeedRangesAsync(NoOpTrace.Singleton, default)).Count;

            using (rootTrace = Trace.GetRootTrace("Cross Partition Query"))
            {
                while (await pipelineStage.MoveNextAsync(rootTrace))
                {
                    TryCatch <QueryPage> tryGetQueryPage = pipelineStage.Current;
                    tryGetQueryPage.ThrowIfFailed();

                    numTraces++;
                }
            }

            Assert.AreEqual(numTraces, rootTrace.Children.Count);
        }
        public async Task BasicTests()
        {
            IReadOnlyList <TestCase> testCases = new List <TestCase>()
            {
                MakeTest(
                    input: Enumerable
                    .Repeat(EmptyPagePipelineStage.PageType.Empty, 2000)
                    .Concat(Enumerable.Repeat(EmptyPagePipelineStage.PageType.NonEmpty, 1)),
                    expected: Enumerable.Repeat(true, 1)),
                MakeTest(
                    input: Enumerable
                    .Repeat(EmptyPagePipelineStage.PageType.Empty, 100)
                    .Concat(Enumerable.Repeat(EmptyPagePipelineStage.PageType.NonEmpty, 5))
                    .Concat(Enumerable.Repeat(EmptyPagePipelineStage.PageType.Empty, 27))
                    .Concat(Enumerable.Repeat(EmptyPagePipelineStage.PageType.NonEmpty, 3))
                    .Concat(Enumerable.Repeat(EmptyPagePipelineStage.PageType.Empty, 32))
                    .Concat(Enumerable.Repeat(EmptyPagePipelineStage.PageType.NonEmpty, 3)),
                    expected: Enumerable.Repeat(true, 11)),
                MakeTest(
                    input: Enumerable
                    .Repeat(EmptyPagePipelineStage.PageType.Empty, 100)
                    .Concat(Enumerable.Repeat(EmptyPagePipelineStage.PageType.NonEmpty, 5))
                    .Concat(Enumerable.Repeat(EmptyPagePipelineStage.PageType.Empty, 27))
                    .Concat(Enumerable.Repeat(EmptyPagePipelineStage.PageType.Error, 3))
                    .Concat(Enumerable.Repeat(EmptyPagePipelineStage.PageType.Empty, 32))
                    .Concat(Enumerable.Repeat(EmptyPagePipelineStage.PageType.NonEmpty, 3)),
                    expected: Enumerable.Repeat(true, 5)
                    .Concat(Enumerable.Repeat(false, 3))
                    .Concat(Enumerable.Repeat(true, 3))),
                MakeTest(
                    input: Enumerable.Repeat(EmptyPagePipelineStage.PageType.NonEmpty, 500),
                    expected: Enumerable.Repeat(true, 500)),
                MakeTest(
                    input: Enumerable.Repeat(EmptyPagePipelineStage.PageType.Error, 500),
                    expected: Enumerable.Repeat(false, 500))
            };

            foreach (TestCase testCase in testCases)
            {
                await using IQueryPipelineStage pipeline = CreatePipeline(testCase.Input);
                for (int index = 0; index < testCase.Expected.Count; ++index)
                {
                    Assert.IsTrue(await pipeline.MoveNextAsync(NoOpTrace.Singleton));

                    if (testCase.Expected[index])
                    {
                        Assert.IsTrue(pipeline.Current.Succeeded);
                        Assert.AreEqual(1, pipeline.Current.Result.Documents.Count);
                        Assert.AreEqual("42", pipeline.Current.Result.Documents[0].ToString());
                    }
                    else
                    {
                        Assert.IsTrue(pipeline.Current.Failed);
                    }
                }
            }
        }
        public async Task StackOverflowTest()
        {
            await using IQueryPipelineStage pipeline = CreatePipeline(Enumerable
                                                                      .Repeat(EmptyPagePipelineStage.PageType.Empty, 2000)
                                                                      .Concat(Enumerable.Repeat(EmptyPagePipelineStage.PageType.Error, 1))
                                                                      .ToList());
            bool hasNext = await pipeline.MoveNextAsync(NoOpTrace.Singleton);

            Assert.IsTrue(hasNext);
            TryCatch <QueryPage> result = pipeline.Current;

            Assert.IsFalse(result.Succeeded);
        }
Beispiel #5
0
        private static async Task <List <CosmosElement> > DrainWithoutStateAsync(string query, IDocumentContainer documentContainer, int pageSize = 10)
        {
            IQueryPipelineStage pipelineStage = CreatePipeline(documentContainer, query, pageSize);

            List <CosmosElement> elements = new List <CosmosElement>();

            while (await pipelineStage.MoveNextAsync())
            {
                TryCatch <QueryPage> tryGetQueryPage = pipelineStage.Current;
                tryGetQueryPage.ThrowIfFailed();

                elements.AddRange(tryGetQueryPage.Result.Documents);
            }

            return(elements);
        }
Beispiel #6
0
        public async Task TestMerge()
        {
            List <CosmosObject> documents = Enumerable
                                            .Range(0, 100)
                                            .Select(x => CosmosObject.Parse($"{{\"pk\" : {x} }}"))
                                            .ToList();

            MergeTestUtil mergeTest = new MergeTestUtil();

            mergeTest.DocumentContainer = await CreateDocumentContainerAsync(
                documents : documents,
                numPartitions : 2,
                failureConfigs : new FlakyDocumentContainer.FailureConfigs(
                    inject429s: false,
                    injectEmptyPages: false,
                    shouldReturnFailure: mergeTest.ShouldReturnFailure));

            string query    = "SELECT * FROM c ORDER BY c._ts";
            int    pageSize = 10;
            IQueryPipelineStage pipelineStage = CreatePipeline(mergeTest.DocumentContainer, query, pageSize);

            List <CosmosElement> elements = new List <CosmosElement>();
            int iteration = 0;

            while (await pipelineStage.MoveNextAsync())
            {
                TryCatch <QueryPage> tryGetQueryPage = pipelineStage.Current;
                tryGetQueryPage.ThrowIfFailed();

                elements.AddRange(tryGetQueryPage.Result.Documents);
                ++iteration;

                if (iteration == 1)
                {
                    mergeTest.ShouldMerge = MergeTestUtil.TriState.Ready;
                }
            }

            Assert.AreEqual(expected: documents.Count, actual: elements.Count);
        }
Beispiel #7
0
        public async Task QueryAsync()
        {
            int numItems = 100;
            IDocumentContainer documentContainer = await this.CreateDocumentContainerAsync(numItems);

            IQueryPipelineStage pipelineStage = CreatePipeline(documentContainer, "SELECT * FROM c", pageSize: 10);

            Trace rootTrace;
            int   numChildren = 1; // One extra since we need to read one past the last user page to get the null continuation.

            using (rootTrace = Trace.GetRootTrace("Cross Partition Query"))
            {
                while (await pipelineStage.MoveNextAsync(rootTrace))
                {
                    numChildren++;
                }
            }

            string traceString = TraceWriter.TraceToText(rootTrace);

            Console.WriteLine(traceString);

            Assert.AreEqual(numChildren, rootTrace.Children.Count);
        }
Beispiel #8
0
        public async Task TestCosmosQueryPartitionKeyDefinition()
        {
            PartitionKeyDefinition partitionKeyDefinition = new PartitionKeyDefinition();
            QueryRequestOptions    queryRequestOptions    = new QueryRequestOptions
            {
                Properties = new Dictionary <string, object>()
                {
                    { "x-ms-query-partitionkey-definition", partitionKeyDefinition }
                }
            };

            SqlQuerySpec            sqlQuerySpec = new SqlQuerySpec(@"select * from t where t.something = 42 ");
            bool                    allowNonValueAggregateQuery = true;
            bool                    isContinuationExpected      = true;
            CancellationTokenSource cancellationTokenSource     = new CancellationTokenSource();
            CancellationToken       cancellationtoken           = cancellationTokenSource.Token;

            Mock <CosmosQueryClient> client = new Mock <CosmosQueryClient>();
            string exceptionMessage         = "Verified that the PartitionKeyDefinition was correctly set. Cancel the rest of the query";

            client
            .Setup(x => x.GetCachedContainerQueryPropertiesAsync(It.IsAny <string>(), It.IsAny <Cosmos.PartitionKey?>(), cancellationtoken))
            .ReturnsAsync(new ContainerQueryProperties("mockContainer", null, partitionKeyDefinition));
            client
            .Setup(x => x.ByPassQueryParsing())
            .Returns(false);
            client
            .Setup(x => x.TryGetPartitionedQueryExecutionInfoAsync(
                       It.IsAny <SqlQuerySpec>(),
                       It.IsAny <PartitionKeyDefinition>(),
                       It.IsAny <bool>(),
                       It.IsAny <bool>(),
                       It.IsAny <bool>(),
                       It.IsAny <bool>(),
                       It.IsAny <CancellationToken>()))
            .ReturnsAsync(TryCatch <PartitionedQueryExecutionInfo> .FromException(
                              new InvalidOperationException(
                                  exceptionMessage)));

            CosmosQueryExecutionContextFactory.InputParameters inputParameters = new CosmosQueryExecutionContextFactory.InputParameters(
                sqlQuerySpec: sqlQuerySpec,
                initialUserContinuationToken: null,
                initialFeedRange: null,
                maxConcurrency: queryRequestOptions?.MaxConcurrency,
                maxItemCount: queryRequestOptions?.MaxItemCount,
                maxBufferedItemCount: queryRequestOptions?.MaxBufferedItemCount,
                partitionKey: queryRequestOptions?.PartitionKey,
                properties: queryRequestOptions?.Properties,
                partitionedQueryExecutionInfo: null,
                executionEnvironment: queryRequestOptions?.ExecutionEnvironment,
                returnResultsInDeterministicOrder: true,
                forcePassthrough: false,
                testInjections: queryRequestOptions?.TestSettings);

            CosmosQueryContext cosmosQueryContext = new CosmosQueryContextCore(
                client: client.Object,
                queryRequestOptions: queryRequestOptions,
                resourceTypeEnum: ResourceType.Document,
                operationType: OperationType.Query,
                resourceType: typeof(QueryResponse),
                resourceLink: "dbs/mockdb/colls/mockColl",
                isContinuationExpected: isContinuationExpected,
                allowNonValueAggregateQuery: allowNonValueAggregateQuery,
                diagnosticsContext: new CosmosDiagnosticsContextCore(),
                correlatedActivityId: new Guid("221FC86C-1825-4284-B10E-A6029652CCA6"));

            IQueryPipelineStage pipelineStage = CosmosQueryExecutionContextFactory.Create(
                documentContainer: null,
                cosmosQueryContext,
                inputParameters);

            Assert.IsTrue(await pipelineStage.MoveNextAsync());
            TryCatch <QueryPage> tryGetPage = pipelineStage.Current;

            Assert.IsTrue(tryGetPage.Failed);
            Assert.AreEqual(HttpStatusCode.BadRequest, (tryGetPage.InnerMostException as CosmosException).StatusCode);
            Assert.IsTrue(
                (tryGetPage.InnerMostException as CosmosException).ToString().Contains(exceptionMessage),
                "response error message did not contain the proper substring.");
        }
        public async Task ScenariosAsync()
        {
            List <Input> inputs = new List <Input>();

            int startLineNumber;
            int endLineNumber;

            //----------------------------------------------------------------
            //  ReadFeed
            //----------------------------------------------------------------
            {
                startLineNumber = GetLineNumber();
                int numItems = 100;
                IDocumentContainer documentContainer = await CreateDocumentContainerAsync(numItems);

                CrossPartitionReadFeedAsyncEnumerator enumerator = CrossPartitionReadFeedAsyncEnumerator.Create(
                    documentContainer,
                    new CrossFeedRangeState <ReadFeedState>(ReadFeedCrossFeedRangeState.CreateFromBeginning().FeedRangeStates),
                    new ReadFeedPaginationOptions(pageSizeHint: 10),
                    cancellationToken: default);

                int numChildren = 1; // One extra since we need to read one past the last user page to get the null continuation.
                TraceForBaselineTesting rootTrace;
                using (rootTrace = TraceForBaselineTesting.GetRootTrace())
                {
                    while (await enumerator.MoveNextAsync(rootTrace))
                    {
                        numChildren++;
                    }
                }

                Assert.AreEqual(numChildren, rootTrace.Children.Count);
                endLineNumber = GetLineNumber();

                inputs.Add(new Input("ReadFeed", rootTrace, startLineNumber, endLineNumber));
            }
            //----------------------------------------------------------------

            //----------------------------------------------------------------
            //  ChangeFeed
            //----------------------------------------------------------------
            {
                startLineNumber = GetLineNumber();
                int numItems = 100;
                IDocumentContainer documentContainer = await CreateDocumentContainerAsync(numItems);

                CrossPartitionChangeFeedAsyncEnumerator enumerator = CrossPartitionChangeFeedAsyncEnumerator.Create(
                    documentContainer,
                    new CrossFeedRangeState <ChangeFeedState>(
                        ChangeFeedCrossFeedRangeState.CreateFromBeginning().FeedRangeStates),
                    new ChangeFeedPaginationOptions(
                        ChangeFeedMode.Incremental,
                        pageSizeHint: int.MaxValue),
                    cancellationToken: default);

                int numChildren = 0;
                TraceForBaselineTesting rootTrace;
                using (rootTrace = TraceForBaselineTesting.GetRootTrace())
                {
                    while (await enumerator.MoveNextAsync(rootTrace))
                    {
                        numChildren++;

                        if (enumerator.Current.Result.Page is ChangeFeedNotModifiedPage)
                        {
                            break;
                        }
                    }
                }

                Assert.AreEqual(numChildren, rootTrace.Children.Count);
                endLineNumber = GetLineNumber();

                inputs.Add(new Input("ChangeFeed", rootTrace, startLineNumber, endLineNumber));
            }
            //----------------------------------------------------------------

            //----------------------------------------------------------------
            //  Query
            //----------------------------------------------------------------
            {
                startLineNumber = GetLineNumber();
                int numItems = 100;
                IDocumentContainer documentContainer = await CreateDocumentContainerAsync(numItems);

                IQueryPipelineStage pipelineStage = CreatePipeline(documentContainer, "SELECT * FROM c", pageSize: 10);

                TraceForBaselineTesting rootTrace;
                int numChildren = 1; // One extra since we need to read one past the last user page to get the null continuation.
                using (rootTrace = TraceForBaselineTesting.GetRootTrace())
                {
                    while (await pipelineStage.MoveNextAsync(rootTrace))
                    {
                        numChildren++;
                    }
                }

                Assert.AreEqual(numChildren, rootTrace.Children.Count);
                endLineNumber = GetLineNumber();

                inputs.Add(new Input("Query", rootTrace, startLineNumber, endLineNumber));
            }
            //----------------------------------------------------------------

            this.ExecuteTestSuite(inputs);
        }
Beispiel #10
0
        public override PassThroughQueryTestOutput ExecuteTest(PassThroughQueryTestInput input)
        {
            // gets DocumentContainer
            IMonadicDocumentContainer monadicDocumentContainer = new InMemoryContainer(input.PartitionKeyDefinition);
            DocumentContainer         documentContainer        = new DocumentContainer(monadicDocumentContainer);

            SqlQuerySpec sqlQuerySpec = new SqlQuerySpec(input.Query);

            // gets query context
            string databaseId   = "db1234";
            string resourceLink = string.Format("dbs/{0}/colls", databaseId);
            CosmosQueryContextCore cosmosQueryContextCore = new CosmosQueryContextCore(
                client: new TestCosmosQueryClient(),
                resourceTypeEnum: Documents.ResourceType.Document,
                operationType: Documents.OperationType.Query,
                resourceType: typeof(QueryResponseCore),
                resourceLink: resourceLink,
                isContinuationExpected: false,
                allowNonValueAggregateQuery: true,
                useSystemPrefix: false,
                correlatedActivityId: Guid.NewGuid());

            //  gets input parameters
            QueryRequestOptions queryRequestOptions = new QueryRequestOptions();

            CosmosSerializerCore serializerCore = new();

            using StreamReader streamReader = new(serializerCore.ToStreamSqlQuerySpec(sqlQuerySpec, Documents.ResourceType.Document));
            string sqlQuerySpecJsonString = streamReader.ReadToEnd();

            PartitionedQueryExecutionInfo partitionedQueryExecutionInfo = GetPartitionedQueryExecutionInfo(sqlQuerySpecJsonString, input.PartitionKeyDefinition);

            if (input.PartitionKeyValue == default || input.PartitionKeyValue == Cosmos.PartitionKey.None)
            {
                input.PartitionKeyValue = Cosmos.PartitionKey.Null;
            }

            CosmosQueryExecutionContextFactory.InputParameters inputParameters = new CosmosQueryExecutionContextFactory.InputParameters(
                sqlQuerySpec: sqlQuerySpec,
                initialUserContinuationToken: null,
                initialFeedRange: null,
                maxConcurrency: queryRequestOptions.MaxConcurrency,
                maxItemCount: queryRequestOptions.MaxItemCount,
                maxBufferedItemCount: queryRequestOptions.MaxBufferedItemCount,
                partitionKey: input.PartitionKeyValue,
                properties: queryRequestOptions.Properties,
                partitionedQueryExecutionInfo: partitionedQueryExecutionInfo,
                executionEnvironment: null,
                returnResultsInDeterministicOrder: null,
                forcePassthrough: true,
                testInjections: null);

            IQueryPipelineStage queryPipelineStage = CosmosQueryExecutionContextFactory.Create(
                documentContainer,
                cosmosQueryContextCore,
                inputParameters,
                NoOpTrace.Singleton);
            bool result = queryPipelineStage.MoveNextAsync(NoOpTrace.Singleton).Result;

            Assert.AreEqual(input.ExpectedPassThrough, inputParameters.SqlQuerySpec.PassThrough);
            Assert.IsNotNull(queryPipelineStage);
            Assert.IsTrue(result);

            return(new PassThroughQueryTestOutput(inputParameters.SqlQuerySpec.PassThrough));
        }