Esempio n. 1
0
        void VerifyReadResultToEnd(ResultSet resultSet, ResultSetSummary resultSummaryFromAvailableCallback, ResultSetSummary resultSummaryFromCompleteCallback, List <ResultSetSummary> resultSummariesFromUpdatedCallback)
        {
            // ... The callback for result set available, update and completion callbacks should have been fired.
            //
            Assert.True(null != resultSummaryFromCompleteCallback, "completeResultSummary is null" + $"\r\n\t\tupdateResultSets: {string.Join("\r\n\t\t\t", resultSummariesFromUpdatedCallback)}");
            Assert.True(null != resultSummaryFromAvailableCallback, "availableResultSummary is null" + $"\r\n\t\tavailableResultSet: {resultSummaryFromAvailableCallback}");

            // ... resultSetAvailable is not marked Complete
            //
            Assert.True(false == resultSummaryFromAvailableCallback.Complete, "availableResultSummary.Complete is true" + $"\r\n\t\tavailableResultSet: {resultSummaryFromAvailableCallback}");

            // insert availableResult at the top of the resultSummariesFromUpdatedCallback list as the available result set is the first update in that series.
            //
            resultSummariesFromUpdatedCallback.Insert(0, resultSummaryFromAvailableCallback);

            // ... The no of rows in available result set should be non-zero
            //
            // Assert.True(0 != resultSummaryFromAvailableCallback.RowCount, "availableResultSet RowCount is 0");

            // ... The final updateResultSet must have 'Complete' flag set to true
            //
            Assert.True(resultSummariesFromUpdatedCallback.Last().Complete,
                        $"Complete Check failed.\r\n\t\t resultSummariesFromUpdatedCallback:{string.Join("\r\n\t\t\t", resultSummariesFromUpdatedCallback)}");


            // ... The no of rows in the final updateResultSet/AvailableResultSet should be equal to that in the Complete Result Set.
            //
            Assert.True(resultSummaryFromCompleteCallback.RowCount == resultSummariesFromUpdatedCallback.Last().RowCount,
                        $"The row counts of the complete Result Set and Final update result set do not match"
                        + $"\r\n\t\tcompleteResultSet: {resultSummaryFromCompleteCallback}"
                        + $"\r\n\t\tupdateResultSets: {string.Join("\r\n\t\t\t", resultSummariesFromUpdatedCallback)}"
                        );

            // ... RowCount should be in increasing order in updateResultSet callbacks
            // ..... and there should be only one resultSummary with Complete flag set to true.
            //
            int completeFlagCount = 0;

            Parallel.ForEach(Partitioner.Create(0, resultSummariesFromUpdatedCallback.Count), (range) =>
            {
                int start = range.Item1 == 0 ? 1 : range.Item1;
                for (int i = start; i < range.Item2; i++)
                {
                    Assert.True(resultSummariesFromUpdatedCallback[i].RowCount >= resultSummariesFromUpdatedCallback[i - 1].RowCount,
                                $"Row Count of {i}th updateResultSet was smaller than that of the previous one"
                                + $"\r\n\t\tupdateResultSets: {string.Join("\r\n\t\t\t", resultSummariesFromUpdatedCallback)}"
                                );
                    if (resultSummariesFromUpdatedCallback[i].Complete)
                    {
                        Interlocked.Increment(ref completeFlagCount);
                    }
                }
            });
            Assert.True(completeFlagCount == 1, "Number of update events with complete flag event set should be 1" + $"\r\n\t\tupdateResultSets: {string.Join("\r\n\t\t\t", resultSummariesFromUpdatedCallback)}");
        }
Esempio n. 2
0
        public async Task ReadToEndForXmlJson(string forType)
        {
            // Setup:
            // ... Build a FOR XML or FOR JSON data set
            string columnName = string.Format("{0}_F52E2B61-18A1-11d1-B105-00805F49916B", forType);
            List <Dictionary <string, string> > data = new List <Dictionary <string, string> >();

            for (int i = 0; i < Common.StandardRows; i++)
            {
                data.Add(new Dictionary <string, string> {
                    { columnName, "test data" }
                });
            }
            Dictionary <string, string>[][] dataSets = { data.ToArray() };

            // ... Create a callback for resultset completion
            ResultSetSummary resultSummary = null;

            ResultSet.ResultSetAsyncEventHandler callback = r =>
            {
                resultSummary = r.Summary;
                return(Task.FromResult(0));
            };

            // If:
            // ... I create a new resultset with a valid db data reader that is FOR XML/JSON
            // ... and I read it to the end
            DbDataReader mockReader        = GetReader(dataSets, false, Common.StandardQuery);
            var          fileStreamFactory = Common.GetFileStreamFactory(new Dictionary <string, byte[]>());
            ResultSet    resultSet         = new ResultSet(mockReader, Common.Ordinal, Common.Ordinal, fileStreamFactory);

            resultSet.ResultCompletion += callback;
            await resultSet.ReadResultToEnd(CancellationToken.None);

            // Then:
            // ... There should only be one column
            // ... There should only be one row
            // ... The result should be marked as complete
            Assert.Equal(1, resultSet.Columns.Length);
            Assert.Equal(1, resultSet.RowCount);

            // ... The callback should have been called
            Assert.NotNull(resultSummary);

            // If:
            // ... I attempt to read back the results
            // Then:
            // ... I should only get one row
            var subset = await resultSet.GetSubset(0, 10);

            Assert.Equal(1, subset.RowCount);
        }
        public async Task ReadToEndForXmlJson(string forType)
        {
            // Setup:
            // ... Build a FOR XML or FOR JSON data set
            DbColumn[]      columns  = { new TestDbColumn(string.Format("{0}_F52E2B61-18A1-11d1-B105-00805F49916B", forType)) };
            object[][]      rows     = Enumerable.Repeat(new object[] { "test data" }, Common.StandardRows).ToArray();
            TestResultSet[] dataSets = { new TestResultSet(columns, rows) };

            // ... Create a callback for resultset completion
            ResultSetSummary resultSummary = null;

            ResultSet.ResultSetAsyncEventHandler callback = r =>
            {
                resultSummary = r.Summary;
                return(Task.FromResult(0));
            };

            // If:
            // ... I create a new resultset with a valid db data reader that is FOR XML/JSON
            // ... and I read it to the end
            DbDataReader mockReader        = GetReader(dataSets, false, Constants.StandardQuery);
            var          fileStreamFactory = MemoryFileSystem.GetFileStreamFactory();
            ResultSet    resultSet         = new ResultSet(Common.Ordinal, Common.Ordinal, fileStreamFactory);

            resultSet.ResultCompletion += callback;
            await resultSet.ReadResultToEnd(mockReader, CancellationToken.None);

            // Then:
            // ... There should only be one column
            // ... There should only be one row
            // ... The result should be marked as complete
            Assert.Equal(1, resultSet.Columns.Length);
            Assert.Equal(1, resultSet.RowCount);

            // ... The callback should have been called
            Assert.NotNull(resultSummary);

            // If:
            // ... I attempt to read back the results
            // Then:
            // ... I should only get one row
            var subset = await resultSet.GetSubset(0, 10);

            Assert.Equal(1, subset.RowCount);
        }
Esempio n. 4
0
        public static EventFlowValidator <TRequestContext> ValidateResultSetSummaries <TRequestContext>(
            this EventFlowValidator <TRequestContext> efv, List <ResultSetEventParams> resultSetEventParamList)
        {
            string GetResultSetKey(ResultSetSummary summary) => $"BatchId:{summary.BatchId}, ResultId:{summary.Id}";

            // Separate the result set resultSetEventParamsList by batchid, resultsetid and by resultseteventtype.
            ConcurrentDictionary <string, List <ResultSetEventParams> > resultSetDictionary =
                new ConcurrentDictionary <string, List <ResultSetEventParams> >();

            foreach (var resultSetEventParam in resultSetEventParamList)
            {
                resultSetDictionary
                .GetOrAdd(GetResultSetKey(resultSetEventParam.ResultSetSummary), (key) => new List <ResultSetEventParams>())
                .Add(resultSetEventParam);
            }

            foreach (var(key, list) in resultSetDictionary)
            {
                ResultSetSummary completeSummary = null, lastResultSetSummary = null;
                int completeFlagCount = 0;
                for (int i = 0; i < list.Count; i++)
                {
                    VerifyResultSummary(key, i, list, ref completeSummary, ref lastResultSetSummary, ref completeFlagCount);
                }

                // Verify that the completeEvent and lastResultSetSummary has same number of rows
                //
                if (lastResultSetSummary != null && completeSummary != null)
                {
                    Assert.True(lastResultSetSummary.RowCount == completeSummary.RowCount, $"CompleteSummary and last Update Summary should have same number of rows, updateSummaryRowCount: {lastResultSetSummary.RowCount}, CompleteSummaryRowCount: {completeSummary.RowCount}");
                }

                // Verify that we got exactly on complete Flag Count.
                //
                Assert.True(1 == completeFlagCount, $"Complete flag should be set in exactly once on Update Result Summary Event. Observed Count: {completeFlagCount}, \r\nresultSetEventParamsList is:{string.Join("\r\n\t\t", list.ConvertAll((p) => p.GetType() + ":" + p.ResultSetSummary))}");

                // Verify that the complete event was set on the last updateResultSet event.
                //
                Assert.True(list.Last().ResultSetSummary.Complete, $"Complete flag should be set on the last Update Result Summary event, , \r\nresultSetEventParamsList is:{string.Join("\r\n\t\t", list.ConvertAll((p) => p.GetType() + ":" + p.ResultSetSummary))}");
            }


            return(efv);
        }
        public static EventFlowValidator <TRequestContext> ValidateResultSetSummaries <TRequestContext>(
            this EventFlowValidator <TRequestContext> efv, List <ResultSetEventParams> resultSetEventParamList)
        {
            string GetResultSetKey(ResultSetSummary summary)
            {
                return($"BatchId:{summary.BatchId}, ResultId:{summary.Id}");
            }

            // Separate the result set resultSetEventParamsList by batchid, resultsetid and by resultseteventtype.
            ConcurrentDictionary <string, List <ResultSetEventParams> > resultSetDictionary =
                new ConcurrentDictionary <string, List <ResultSetEventParams> >();

            foreach (var resultSetEventParam in resultSetEventParamList)
            {
                resultSetDictionary
                .GetOrAdd(GetResultSetKey(resultSetEventParam.ResultSetSummary), (key) => new List <ResultSetEventParams>())
                .Add(resultSetEventParam);
            }

            foreach (var(key, list) in resultSetDictionary)
            {
                ResultSetSummary completeSummary = null, lastResultSetSummary = null;
                for (int i = 0; i < list.Count; i++)
                {
                    VerifyResultSummary(key, i, list, ref completeSummary, ref lastResultSetSummary);
                }

                // Verify that the completeEvent and lastResultSetSummary has same number of rows
                //
                if (lastResultSetSummary != null && completeSummary != null)
                {
                    Assert.True(lastResultSetSummary.RowCount == completeSummary.RowCount, "CompleteSummary and last Update Summary should have same number of rows");
                }
            }


            return(efv);
        }
        public async Task ReadToEndSuccess()
        {
            // Setup: Create a callback for resultset completion
            ResultSetSummary resultSummaryFromCallback = null;

            ResultSet.ResultSetAsyncEventHandler callback = r =>
            {
                resultSummaryFromCallback = r.Summary;
                return(Task.FromResult(0));
            };

            // If:
            // ... I create a new resultset with a valid db data reader that has data
            // ... and I read it to the end
            DbDataReader mockReader        = GetReader(Common.StandardTestDataSet, false, Constants.StandardQuery);
            var          fileStreamFactory = MemoryFileSystem.GetFileStreamFactory();
            ResultSet    resultSet         = new ResultSet(Common.Ordinal, Common.Ordinal, fileStreamFactory);

            resultSet.ResultCompletion += callback;
            await resultSet.ReadResultToEnd(mockReader, CancellationToken.None);

            // Then:
            // ... The columns should be set
            // ... There should be rows to read back
            Assert.NotNull(resultSet.Columns);
            Assert.Equal(Common.StandardColumns, resultSet.Columns.Length);
            Assert.Equal(Common.StandardRows, resultSet.RowCount);

            // ... The summary should have the same info
            Assert.NotNull(resultSet.Summary.ColumnInfo);
            Assert.Equal(Common.StandardColumns, resultSet.Summary.ColumnInfo.Length);
            Assert.Equal(Common.StandardRows, resultSet.Summary.RowCount);

            // ... The callback for result set completion should have been fired
            Assert.NotNull(resultSummaryFromCallback);
        }
        public void ReadToEndSuccess()
        {
            // Setup: Create a results Available callback for result set
            //
            ResultSetSummary resultSummaryFromAvailableCallback = null;

            Task AvailableCallback(ResultSet r)
            {
                Debug.WriteLine($"available result notification sent, result summary was: {r.Summary}");
                resultSummaryFromAvailableCallback = r.Summary;
                return(Task.CompletedTask);
            }

            // Setup: Create a results updated callback for result set
            //
            List <ResultSetSummary> resultSummariesFromUpdatedCallback = new List <ResultSetSummary>();

            Task UpdatedCallback(ResultSet r)
            {
                Debug.WriteLine($"updated result notification sent, result summary was: {r.Summary}");
                resultSummariesFromUpdatedCallback.Add(r.Summary);
                return(Task.CompletedTask);
            }

            // Setup: Create a  results complete callback for result set
            //
            ResultSetSummary resultSummaryFromCompleteCallback = null;

            Task CompleteCallback(ResultSet r)
            {
                Debug.WriteLine($"Completed result notification sent, result summary was: {r.Summary}");
                resultSummaryFromCompleteCallback = r.Summary;
                return(Task.CompletedTask);
            }

            // If:
            // ... I create a new resultset with a valid db data reader that has data
            // ... and I read it to the end
            DbDataReader mockReader        = GetReader(Common.StandardTestDataSet, false, Constants.StandardQuery);
            var          fileStreamFactory = MemoryFileSystem.GetFileStreamFactory();
            ResultSet    resultSet         = new ResultSet(Common.Ordinal, Common.Ordinal, fileStreamFactory);

            resultSet.ResultAvailable  += AvailableCallback;
            resultSet.ResultUpdated    += UpdatedCallback;
            resultSet.ResultCompletion += CompleteCallback;
            resultSet.ReadResultToEnd(mockReader, CancellationToken.None).Wait();

            Thread.Yield();
            resultSet.ResultAvailable  -= AvailableCallback;
            resultSet.ResultUpdated    -= UpdatedCallback;
            resultSet.ResultCompletion -= CompleteCallback;

            // Then:
            // ... The columns should be set
            // ... There should be rows to read back
            Assert.NotNull(resultSet.Columns);
            Assert.Equal(Common.StandardColumns, resultSet.Columns.Length);
            Assert.Equal(Common.StandardRows, resultSet.RowCount);

            // ... The summary should have the same info
            Assert.NotNull(resultSet.Summary.ColumnInfo);
            Assert.Equal(Common.StandardColumns, resultSet.Summary.ColumnInfo.Length);
            Assert.Equal(Common.StandardRows, resultSet.Summary.RowCount);

            // and:
            // disabling verification due to: https://github.com/Microsoft/sqltoolsservice/issues/746
            //
            // VerifyReadResultToEnd(resultSet, resultSummaryFromAvailableCallback, resultSummaryFromCompleteCallback, resultSummariesFromUpdatedCallback);
        }
        /// <summary>
        /// Verifies that a ResultSummary at a given position as expected within the list of ResultSummary items
        /// </summary>
        /// <param name="batchIdResultSetId">The batchId and ResultSetId for this list of events</param>
        /// <param name="position">The position with resultSetEventParamsList that we are verifying in this call<</param>
        /// <param name="resultSetEventParamsList">The list of resultSetParams that we are verifying</param>
        /// <param name="completeSummary"> This should be null when we start validating the list of ResultSetEventParams</param>
        /// <param name="lastResultSetSummary"> This should be null when we start validating the list of ResultSetEventParams</param>
        private static void VerifyResultSummary(string batchIdResultSetId, int position, List <ResultSetEventParams> resultSetEventParamsList, ref ResultSetSummary completeSummary, ref ResultSetSummary lastResultSetSummary)
        {
            ResultSetEventParams resultSetEventParams = resultSetEventParamsList[position];

            switch (resultSetEventParams.GetType().Name)
            {
            case nameof(ResultSetAvailableEventParams):
                // Save the lastResultSetSummary for this event for other verifications.
                //
                lastResultSetSummary = resultSetEventParams.ResultSetSummary;
                break;

            case nameof(ResultSetUpdatedEventParams):
                // Verify that the updateEvent is not the first in the sequence. Since we set lastResultSetSummary on each available or updatedEvent, we check that there has been no lastResultSetSummary previously set yet.
                //
                Assert.True(null != lastResultSetSummary,
                            $"UpdateResultSet was found to be the first message received for {batchIdResultSetId}"
                            + $"\r\nresultSetEventParamsList is:{string.Join("\r\n\t\t", resultSetEventParamsList.ConvertAll((p) => p.GetType() + ":" + p.ResultSetSummary))}"
                            );

                // Verify that the number of rows in the current updatedSummary is >= those in the lastResultSetSummary
                //
                Assert.True(resultSetEventParams.ResultSetSummary.RowCount >= lastResultSetSummary.RowCount,
                            $"UpdatedResultSetSummary at position: {position} has less rows than LastUpdatedSummary (or AvailableSummary) received for {batchIdResultSetId}"
                            + $"\r\nresultSetEventParamsList is:{string.Join("\r\n\t\t", resultSetEventParamsList.ConvertAll((p) => p.GetType() + ":" + p.ResultSetSummary))}"
                            + $"\r\n\t\t LastUpdatedSummary (or Available):{lastResultSetSummary}"
                            + $"\r\n\t\t UpdatedResultSetSummary:{resultSetEventParams.ResultSetSummary}");

                // Save the lastResultSetSummary for this event for other verifications.
                //
                lastResultSetSummary = resultSetEventParams.ResultSetSummary;
                break;

            case nameof(ResultSetCompleteEventParams):
                // Verify that there is only one completeEvent
                //
                Assert.True(null == completeSummary,
                            $"CompleteResultSet was received multiple times for {batchIdResultSetId}"
                            + $"\r\nresultSetEventParamsList is:{string.Join("\r\n\t\t", resultSetEventParamsList.ConvertAll((p) => p.GetType() + ":" + p.ResultSetSummary))}"
                            );

                // Save the completeSummary for this event for other verifications.
                //
                completeSummary = resultSetEventParams.ResultSetSummary;

                // Verify that the complete flag is set
                //
                Assert.True(completeSummary.Complete,
                            $"completeSummary.Complete is not true"
                            + $"\r\nresultSetEventParamsList is:{string.Join("\r\n\t\t", resultSetEventParamsList.ConvertAll((p) => p.GetType() + ":" + p.ResultSetSummary))}"
                            );
                break;

            default:
                throw new AssertionException(
                          $"Unknown type of ResultSetEventParams, actual type received is: {resultSetEventParams.GetType().Name}");
            }
        }
Esempio n. 9
0
        public async Task ReadToEndForXmlJson(string forType)
        {
            // Setup:
            // ... Build a FOR XML or FOR JSON data set
            //
            DbColumn[]      columns  = { new TestDbColumn(string.Format("{0}_F52E2B61-18A1-11d1-B105-00805F49916B", forType)) };
            object[][]      rows     = Enumerable.Repeat(new object[] { "test data" }, Common.StandardRows).ToArray();
            TestResultSet[] dataSets = { new TestResultSet(columns, rows) };

            // Setup: Create a results Available callback for result set
            //
            ResultSetSummary resultSummaryFromAvailableCallback = null;

            Task AvailableCallback(ResultSet r)
            {
                Debug.WriteLine($"available result notification sent, result summary was: {r.Summary}");
                resultSummaryFromAvailableCallback = r.Summary;
                return(Task.CompletedTask);
            }

            // Setup: Create a results updated callback for result set
            //
            List <ResultSetSummary> resultSummariesFromUpdatedCallback = new List <ResultSetSummary>();

            Task UpdatedCallback(ResultSet r)
            {
                Debug.WriteLine($"updated result notification sent, result summary was: {r.Summary}");
                resultSummariesFromUpdatedCallback.Add(r.Summary);
                return(Task.CompletedTask);
            }

            // Setup: Create a  results complete callback for result set
            //
            ResultSetSummary resultSummaryFromCompleteCallback = null;

            Task CompleteCallback(ResultSet r)
            {
                Debug.WriteLine($"Completed result notification sent, result summary was: {r.Summary}");
                Assert.True(r.Summary.Complete);
                resultSummaryFromCompleteCallback = r.Summary;
                return(Task.CompletedTask);
            }

            // If:
            // ... I create a new result set with a valid db data reader that is FOR XML/JSON
            // ... and I read it to the end
            //
            DbDataReader mockReader        = GetReader(dataSets, false, Constants.StandardQuery);
            var          fileStreamFactory = MemoryFileSystem.GetFileStreamFactory();
            ResultSet    resultSet         = new ResultSet(Common.Ordinal, Common.Ordinal, fileStreamFactory);

            resultSet.ResultAvailable  += AvailableCallback;
            resultSet.ResultUpdated    += UpdatedCallback;
            resultSet.ResultCompletion += CompleteCallback;
            var   readResultTask = resultSet.ReadResultToEnd(mockReader, CancellationToken.None);
            await readResultTask;

            Debug.AutoFlush = true;
            Debug.Assert(readResultTask.IsCompletedSuccessfully, $"readResultTask did not Complete Successfully. Status: {readResultTask.Status}");
            Thread.Yield();
            resultSet.ResultAvailable  -= AvailableCallback;
            resultSet.ResultUpdated    -= UpdatedCallback;
            resultSet.ResultCompletion -= CompleteCallback;
            // Then:
            // ... There should only be one column
            // ... There should only be one row
            //
            Assert.Equal(1, resultSet.Columns.Length);
            Assert.Equal(1, resultSet.RowCount);


            // and:
            //
            VerifyReadResultToEnd(resultSet, resultSummaryFromAvailableCallback, resultSummaryFromCompleteCallback, resultSummariesFromUpdatedCallback);

            // If:
            // ... I attempt to read back the results
            // Then:
            // ... I should only get one row
            //
            var task = resultSet.GetSubset(0, 10);

            task.Wait();
            var subset = task.Result;

            Assert.Equal(1, subset.RowCount);
        }