mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-24 17:24:14 -05:00
Batch Start Notification (#169)
This change is part of the progressive results code. It will submit a notification from the service layer to indicate when execution of a batch has completed. This notification will contain the selection for batch, execution start time, and its ID. This will enable the extension to produce a header for the batch before the batch completes, in order to make it more clear to the user that execution is going on. * Adding new event for batch start * Unit tests * Fixing comments as per @kevcunnane
This commit is contained in:
@@ -46,22 +46,34 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
// ... The summary should have the same info
|
||||
Assert.False(batch.Summary.HasError);
|
||||
Assert.Equal(Common.Ordinal, batch.Summary.Id);
|
||||
Assert.Empty(batch.Summary.ResultSetSummaries);
|
||||
Assert.Empty(batch.Summary.Messages);
|
||||
Assert.Null(batch.Summary.ResultSetSummaries);
|
||||
Assert.Null(batch.Summary.Messages);
|
||||
Assert.Equal(0, batch.Summary.Selection.StartLine);
|
||||
Assert.NotEqual(default(DateTime).ToString("o"), batch.Summary.ExecutionStart); // Should have been set at construction
|
||||
Assert.Equal(default(DateTime).ToString("o"), batch.Summary.ExecutionEnd);
|
||||
Assert.Equal((default(DateTime) - DateTime.Parse(batch.Summary.ExecutionStart)).ToString(), batch.Summary.ExecutionElapsed);
|
||||
Assert.Null(batch.Summary.ExecutionEnd);
|
||||
Assert.Null(batch.Summary.ExecutionElapsed);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Note: This test also tests the start notification feature
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void BatchExecuteNoResultSets()
|
||||
{
|
||||
// Setup: Create a callback for batch completion
|
||||
BatchSummary batchSummaryFromCallback = null;
|
||||
Batch.BatchAsyncEventHandler batchCallback = b =>
|
||||
// Setup:
|
||||
// ... Create a callback for batch start
|
||||
BatchSummary batchSummaryFromStart = null;
|
||||
Batch.BatchAsyncEventHandler batchStartCallback = b =>
|
||||
{
|
||||
batchSummaryFromCallback = b.Summary;
|
||||
batchSummaryFromStart = b.Summary;
|
||||
return Task.FromResult(0);
|
||||
};
|
||||
|
||||
// ... Create a callback for batch completion
|
||||
BatchSummary batchSummaryFromCompletion = null;
|
||||
Batch.BatchAsyncEventHandler batchCompleteCallback = b =>
|
||||
{
|
||||
batchSummaryFromCompletion = b.Summary;
|
||||
return Task.FromResult(0);
|
||||
};
|
||||
|
||||
@@ -76,7 +88,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
// If I execute a query that should get no result sets
|
||||
var fileStreamFactory = Common.GetFileStreamFactory(new Dictionary<string, byte[]>());
|
||||
Batch batch = new Batch(Common.StandardQuery, Common.SubsectionDocument, Common.Ordinal, fileStreamFactory);
|
||||
batch.BatchCompletion += batchCallback;
|
||||
batch.BatchStart += batchStartCallback;
|
||||
batch.BatchCompletion += batchCompleteCallback;
|
||||
batch.ResultSetCompletion += resultSetCallback;
|
||||
batch.Execute(GetConnection(Common.CreateTestConnectionInfo(null, false)), CancellationToken.None).Wait();
|
||||
|
||||
@@ -96,21 +109,32 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
// ... There should be a message for how many rows were affected
|
||||
Assert.Equal(1, batch.ResultMessages.Count());
|
||||
|
||||
// ... The callback for batch start should have been called
|
||||
// ... The info from it should have been basic
|
||||
Assert.NotNull(batchSummaryFromStart);
|
||||
Assert.False(batchSummaryFromStart.HasError);
|
||||
Assert.Equal(Common.Ordinal, batchSummaryFromStart.Id);
|
||||
Assert.Equal(Common.SubsectionDocument, batchSummaryFromStart.Selection);
|
||||
Assert.True(DateTime.Parse(batchSummaryFromStart.ExecutionStart) > default(DateTime));
|
||||
Assert.Null(batchSummaryFromStart.ResultSetSummaries);
|
||||
Assert.Null(batchSummaryFromStart.Messages);
|
||||
Assert.Null(batchSummaryFromStart.ExecutionElapsed);
|
||||
Assert.Null(batchSummaryFromStart.ExecutionEnd);
|
||||
|
||||
// ... The callback for batch completion should have been fired
|
||||
Assert.NotNull(batchSummaryFromCallback);
|
||||
// ... The summary should match the expected info
|
||||
Assert.NotNull(batchSummaryFromCompletion);
|
||||
Assert.False(batchSummaryFromCompletion.HasError);
|
||||
Assert.Equal(Common.Ordinal, batchSummaryFromCompletion.Id);
|
||||
Assert.Equal(0, batchSummaryFromCompletion.ResultSetSummaries.Length);
|
||||
Assert.Equal(1, batchSummaryFromCompletion.Messages.Length);
|
||||
Assert.Equal(Common.SubsectionDocument, batchSummaryFromCompletion.Selection);
|
||||
Assert.True(DateTime.Parse(batchSummaryFromCompletion.ExecutionStart) > default(DateTime));
|
||||
Assert.True(DateTime.Parse(batchSummaryFromCompletion.ExecutionEnd) > default(DateTime));
|
||||
Assert.NotNull(batchSummaryFromCompletion.ExecutionElapsed);
|
||||
|
||||
// ... The callback for the result set should NOT have been fired
|
||||
Assert.False(resultCallbackFired);
|
||||
|
||||
// ... The summary should have the same info
|
||||
Assert.False(batch.Summary.HasError);
|
||||
Assert.Equal(Common.Ordinal, batch.Summary.Id);
|
||||
Assert.Equal(0, batch.Summary.ResultSetSummaries.Length);
|
||||
Assert.Equal(1, batch.Summary.Messages.Length);
|
||||
Assert.Equal(0, batch.Summary.Selection.StartLine);
|
||||
Assert.True(DateTime.Parse(batch.Summary.ExecutionStart) > default(DateTime));
|
||||
Assert.True(DateTime.Parse(batch.Summary.ExecutionEnd) > default(DateTime));
|
||||
Assert.NotNull(batch.Summary.ExecutionElapsed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -239,9 +263,18 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
[Fact]
|
||||
public void BatchExecuteInvalidQuery()
|
||||
{
|
||||
// Setup: Create a callback for batch completion
|
||||
// Setup:
|
||||
// ... Create a callback for batch start
|
||||
bool batchStartCalled = false;
|
||||
Batch.BatchAsyncEventHandler batchStartCallback = b =>
|
||||
{
|
||||
batchStartCalled = true;
|
||||
return Task.FromResult(0);
|
||||
};
|
||||
|
||||
// ... Create a callback for batch completion
|
||||
BatchSummary batchSummaryFromCallback = null;
|
||||
Batch.BatchAsyncEventHandler batchCallback = b =>
|
||||
Batch.BatchAsyncEventHandler batchCompleteCallback = b =>
|
||||
{
|
||||
batchSummaryFromCallback = b.Summary;
|
||||
return Task.FromResult(0);
|
||||
@@ -258,7 +291,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
// If I execute a batch that is invalid
|
||||
var fileStreamFactory = Common.GetFileStreamFactory(new Dictionary<string, byte[]>());
|
||||
Batch batch = new Batch(Common.StandardQuery, Common.SubsectionDocument, Common.Ordinal, fileStreamFactory);
|
||||
batch.BatchCompletion += batchCallback;
|
||||
batch.BatchStart += batchStartCallback;
|
||||
batch.BatchCompletion += batchCompleteCallback;
|
||||
batch.ResultSetCompletion += resultSetCallback;
|
||||
batch.Execute(GetConnection(ci), CancellationToken.None).Wait();
|
||||
|
||||
@@ -276,6 +310,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
|
||||
// ... The callback for batch completion should have been fired
|
||||
Assert.NotNull(batchSummaryFromCallback);
|
||||
|
||||
// ... The callback for batch start should have been fired
|
||||
Assert.True(batchStartCalled);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -293,20 +330,24 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
Assert.True(batch.HasExecuted, "The batch should have been marked executed.");
|
||||
Assert.False(batch.HasError, "The batch should not have an error");
|
||||
|
||||
// Setup for part 2: Create a callback for batch completion
|
||||
BatchSummary batchSummaryFromCallback = null;
|
||||
bool completionCallbackFired = false;
|
||||
Batch.BatchAsyncEventHandler callback = b =>
|
||||
// Setup for part 2:
|
||||
// ... Create a callback for batch completion
|
||||
Batch.BatchAsyncEventHandler completeCallback = b =>
|
||||
{
|
||||
completionCallbackFired = true;
|
||||
batchSummaryFromCallback = b.Summary;
|
||||
return Task.FromResult(0);
|
||||
throw new Exception("Batch completion callback should not have been called");
|
||||
};
|
||||
|
||||
// ... Create a callback for batch start
|
||||
Batch.BatchAsyncEventHandler startCallback = b =>
|
||||
{
|
||||
throw new Exception("Batch start callback should not have been called");
|
||||
};
|
||||
|
||||
// If I execute it again
|
||||
// Then:
|
||||
// ... It should throw an invalid operation exception
|
||||
batch.BatchCompletion += callback;
|
||||
batch.BatchStart += startCallback;
|
||||
batch.BatchCompletion += completeCallback;
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() =>
|
||||
batch.Execute(GetConnection(ci), CancellationToken.None));
|
||||
|
||||
@@ -315,10 +356,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
Assert.True(batch.HasExecuted, "The batch should still be marked executed.");
|
||||
Assert.NotEmpty(batch.ResultSets);
|
||||
Assert.NotEmpty(batch.ResultSummaries);
|
||||
|
||||
// ... The callback for batch completion should not have been fired for the second run
|
||||
Assert.False(completionCallbackFired);
|
||||
Assert.Null(batchSummaryFromCallback);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
||||
@@ -63,11 +63,19 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
public void QueryExecuteSingleBatch()
|
||||
{
|
||||
// Setup:
|
||||
// ... Create a callback for batch completion
|
||||
int batchCallbacksReceived = 0;
|
||||
Batch.BatchAsyncEventHandler batchCallback = summary =>
|
||||
// ... Create a callback for atch start
|
||||
int batchStartCallbacksReceived = 0;
|
||||
Batch.BatchAsyncEventHandler batchStartCallback = b =>
|
||||
{
|
||||
batchCallbacksReceived++;
|
||||
batchStartCallbacksReceived++;
|
||||
return Task.FromResult(0);
|
||||
};
|
||||
|
||||
// ... Create a callback for batch completion
|
||||
int batchCompleteCallbacksReceived = 0;
|
||||
Batch.BatchAsyncEventHandler batchCompleteCallback = summary =>
|
||||
{
|
||||
batchCompleteCallbacksReceived++;
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
|
||||
@@ -76,7 +84,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
ConnectionInfo ci = Common.CreateTestConnectionInfo(null, false);
|
||||
var fileStreamFactory = Common.GetFileStreamFactory(new Dictionary<string, byte[]>());
|
||||
Query query = new Query(Common.StandardQuery, ci, new QueryExecutionSettings(), fileStreamFactory);
|
||||
query.BatchCompleted += batchCallback;
|
||||
query.BatchStarted += batchStartCallback;
|
||||
query.BatchCompleted += batchCompleteCallback;
|
||||
|
||||
// Then:
|
||||
// ... I should get a single batch to execute that hasn't been executed
|
||||
@@ -97,16 +106,23 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
Assert.NotEmpty(query.BatchSummaries);
|
||||
Assert.Equal(1, query.BatchSummaries.Length);
|
||||
|
||||
// ... The batch callback should have been called precisely 1 time
|
||||
Assert.Equal(1, batchCallbacksReceived);
|
||||
// ... The batch callbacks should have been called precisely 1 time
|
||||
Assert.Equal(1, batchStartCallbacksReceived);
|
||||
Assert.Equal(1, batchCompleteCallbacksReceived);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void QueryExecuteNoOpBatch()
|
||||
{
|
||||
// Setup:
|
||||
// ... Create a callback for batch startup
|
||||
Batch.BatchAsyncEventHandler batchStartCallback = b =>
|
||||
{
|
||||
throw new Exception("Batch startup callback should not have been called.");
|
||||
};
|
||||
|
||||
// ... Create a callback for batch completion
|
||||
Batch.BatchAsyncEventHandler batchCallback = summary =>
|
||||
Batch.BatchAsyncEventHandler batchCompletionCallback = summary =>
|
||||
{
|
||||
throw new Exception("Batch completion callback was called");
|
||||
};
|
||||
@@ -116,7 +132,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
ConnectionInfo ci = Common.CreateTestConnectionInfo(null, false);
|
||||
var fileStreamFactory = Common.GetFileStreamFactory(new Dictionary<string, byte[]>());
|
||||
Query query = new Query(Common.NoOpQuery, ci, new QueryExecutionSettings(), fileStreamFactory);
|
||||
query.BatchCompleted += batchCallback;
|
||||
query.BatchStarted += batchStartCallback;
|
||||
query.BatchCompleted += batchCompletionCallback;
|
||||
|
||||
// Then:
|
||||
// ... I should get no batches back
|
||||
@@ -140,12 +157,20 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
public void QueryExecuteMultipleBatches()
|
||||
{
|
||||
// Setup:
|
||||
// ... Create a callback for batch completion
|
||||
int batchCallbacksReceived = 0;
|
||||
Batch.BatchAsyncEventHandler batchCallback = summary =>
|
||||
// ... Create a callback for batch start
|
||||
int batchStartCallbacksReceived = 0;
|
||||
Batch.BatchAsyncEventHandler batchStartCallback = b =>
|
||||
{
|
||||
batchCallbacksReceived++;
|
||||
return Task.CompletedTask;
|
||||
batchStartCallbacksReceived++;
|
||||
return Task.FromResult(0);
|
||||
};
|
||||
|
||||
// ... Create a callback for batch completion
|
||||
int batchCompletedCallbacksReceived = 0;
|
||||
Batch.BatchAsyncEventHandler batchCompletedCallback = summary =>
|
||||
{
|
||||
batchCompletedCallbacksReceived++;
|
||||
return Task.FromResult(0);
|
||||
};
|
||||
|
||||
// If:
|
||||
@@ -154,7 +179,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
string queryText = string.Format("{0}\r\nGO\r\n{0}", Common.StandardQuery);
|
||||
var fileStreamFactory = Common.GetFileStreamFactory(new Dictionary<string, byte[]>());
|
||||
Query query = new Query(queryText, ci, new QueryExecutionSettings(), fileStreamFactory);
|
||||
query.BatchCompleted += batchCallback;
|
||||
query.BatchStarted += batchStartCallback;
|
||||
query.BatchCompleted += batchCompletedCallback;
|
||||
|
||||
// Then:
|
||||
// ... I should get back two batches to execute that haven't been executed
|
||||
@@ -175,19 +201,28 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
Assert.NotEmpty(query.BatchSummaries);
|
||||
Assert.Equal(2, query.BatchSummaries.Length);
|
||||
|
||||
// ... The batch callback should have been called precisely 2 times
|
||||
Assert.Equal(2, batchCallbacksReceived);
|
||||
// ... The batch start and completion callbacks should have been called precisely 2 times
|
||||
Assert.Equal(2, batchStartCallbacksReceived);
|
||||
Assert.Equal(2, batchCompletedCallbacksReceived);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void QueryExecuteMultipleBatchesWithNoOp()
|
||||
{
|
||||
// Setup:
|
||||
// ... Create a callback for batch completion
|
||||
int batchCallbacksReceived = 0;
|
||||
Batch.BatchAsyncEventHandler batchCallback = summary =>
|
||||
// ... Create a callback for batch start
|
||||
int batchStartCallbacksReceived = 0;
|
||||
Batch.BatchAsyncEventHandler batchStartCallback = b =>
|
||||
{
|
||||
batchCallbacksReceived++;
|
||||
batchStartCallbacksReceived++;
|
||||
return Task.FromResult(0);
|
||||
};
|
||||
|
||||
// ... Create a callback for batch completion
|
||||
int batchCompletionCallbacksReceived = 0;
|
||||
Batch.BatchAsyncEventHandler batchCompletionCallback = summary =>
|
||||
{
|
||||
batchCompletionCallbacksReceived++;
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
|
||||
@@ -197,7 +232,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
string queryText = string.Format("{0}\r\nGO\r\n{1}", Common.StandardQuery, Common.NoOpQuery);
|
||||
var fileStreamFactory = Common.GetFileStreamFactory(new Dictionary<string, byte[]>());
|
||||
Query query = new Query(queryText, ci, new QueryExecutionSettings(), fileStreamFactory);
|
||||
query.BatchCompleted += batchCallback;
|
||||
query.BatchStarted += batchStartCallback;
|
||||
query.BatchCompleted += batchCompletionCallback;
|
||||
|
||||
// Then:
|
||||
// ... I should get back one batch to execute that hasn't been executed
|
||||
@@ -217,19 +253,28 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
Assert.NotEmpty(query.BatchSummaries);
|
||||
Assert.Equal(1, query.BatchSummaries.Length);
|
||||
|
||||
// ... The batch callback should have been called precisely 1 time
|
||||
Assert.Equal(1, batchCallbacksReceived);
|
||||
// ... The batch callbacks should have been called precisely 1 time
|
||||
Assert.Equal(1, batchStartCallbacksReceived);
|
||||
Assert.Equal(1, batchCompletionCallbacksReceived);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void QueryExecuteInvalidBatch()
|
||||
{
|
||||
// Setup:
|
||||
// ... Create a callback for batch completion
|
||||
int batchCallbacksReceived = 0;
|
||||
Batch.BatchAsyncEventHandler batchCallback = summary =>
|
||||
// ... Create a callback for batch start
|
||||
int batchStartCallbacksReceived = 0;
|
||||
Batch.BatchAsyncEventHandler batchStartCallback = b =>
|
||||
{
|
||||
batchCallbacksReceived++;
|
||||
batchStartCallbacksReceived++;
|
||||
return Task.FromResult(0);
|
||||
};
|
||||
|
||||
// ... Create a callback for batch completion
|
||||
int batchCompletionCallbacksReceived = 0;
|
||||
Batch.BatchAsyncEventHandler batchCompltionCallback = summary =>
|
||||
{
|
||||
batchCompletionCallbacksReceived++;
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
|
||||
@@ -238,7 +283,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
ConnectionInfo ci = Common.CreateTestConnectionInfo(null, true);
|
||||
var fileStreamFactory = Common.GetFileStreamFactory(new Dictionary<string, byte[]>());
|
||||
Query query = new Query(Common.InvalidQuery, ci, new QueryExecutionSettings(), fileStreamFactory);
|
||||
query.BatchCompleted += batchCallback;
|
||||
query.BatchStarted += batchStartCallback;
|
||||
query.BatchCompleted += batchCompltionCallback;
|
||||
|
||||
// Then:
|
||||
// ... I should get back a query with one batch not executed
|
||||
@@ -261,8 +307,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
Assert.True(query.BatchSummaries[0].HasError);
|
||||
Assert.NotEmpty(query.BatchSummaries[0].Messages);
|
||||
|
||||
// ... The batch callback should have been called once
|
||||
Assert.Equal(1, batchCallbacksReceived);
|
||||
// ... The batch callbacks should have been called once
|
||||
Assert.Equal(1, batchStartCallbacksReceived);
|
||||
Assert.Equal(1, batchCompletionCallbacksReceived);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,9 +36,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
|
||||
QueryExecuteResult result = null;
|
||||
QueryExecuteCompleteParams completeParams = null;
|
||||
QueryExecuteBatchCompleteParams batchCompleteParams = null;
|
||||
QueryExecuteBatchNotificationParams batchStartParams = null;
|
||||
QueryExecuteBatchNotificationParams batchCompleteParams = null;
|
||||
var requestContext = RequestContextMocks.Create<QueryExecuteResult>(qer => result = qer)
|
||||
.AddEventHandling(QueryExecuteCompleteEvent.Type, (et, p) => completeParams = p)
|
||||
.AddEventHandling(QueryExecuteBatchStartEvent.Type, (et, p) => batchStartParams = p)
|
||||
.AddEventHandling(QueryExecuteBatchCompleteEvent.Type, (et, p) => batchCompleteParams = p)
|
||||
.AddEventHandling(QueryExecuteResultSetCompleteEvent.Type, null);
|
||||
await Common.AwaitExecution(queryService, queryParams, requestContext.Object);
|
||||
@@ -49,14 +51,23 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
// ... A completion event should have been fired with empty results
|
||||
// ... A batch completion event should have been fired with empty results
|
||||
// ... A result set completion event should not have been fired
|
||||
VerifyQueryExecuteCallCount(requestContext, Times.Once(), Times.Once(), Times.Once(), Times.Never(), Times.Never());
|
||||
VerifyQueryExecuteCallCount(requestContext, Times.Once(), Times.Once(), Times.Once(), Times.Once(), Times.Never(), Times.Never());
|
||||
Assert.Null(result.Messages);
|
||||
|
||||
Assert.Equal(1, completeParams.BatchSummaries.Length);
|
||||
Assert.Empty(completeParams.BatchSummaries[0].ResultSetSummaries);
|
||||
Assert.NotEmpty(completeParams.BatchSummaries[0].Messages);
|
||||
|
||||
// ... Batch start summary should not contain result sets, messages, but should contain owner URI
|
||||
Assert.NotNull(batchStartParams);
|
||||
Assert.NotNull(batchStartParams.BatchSummary);
|
||||
Assert.Null(batchStartParams.BatchSummary.Messages);
|
||||
Assert.Null(batchStartParams.BatchSummary.ResultSetSummaries);
|
||||
Assert.Equal(Common.OwnerUri, batchStartParams.OwnerUri);
|
||||
|
||||
// ... Batch completion summary should contain result sets, messages, and the owner URI
|
||||
Assert.NotNull(batchCompleteParams);
|
||||
Assert.NotNull(batchCompleteParams.BatchSummary);
|
||||
Assert.Empty(batchCompleteParams.BatchSummary.ResultSetSummaries);
|
||||
Assert.NotEmpty(batchCompleteParams.BatchSummary.Messages);
|
||||
Assert.Equal(Common.OwnerUri, batchCompleteParams.OwnerUri);
|
||||
@@ -80,10 +91,12 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
|
||||
QueryExecuteResult result = null;
|
||||
QueryExecuteCompleteParams completeParams = null;
|
||||
QueryExecuteBatchCompleteParams batchCompleteParams = null;
|
||||
QueryExecuteBatchNotificationParams batchStartParams = null;
|
||||
QueryExecuteBatchNotificationParams batchCompleteParams = null;
|
||||
QueryExecuteResultSetCompleteParams resultCompleteParams = null;
|
||||
var requestContext = RequestContextMocks.Create<QueryExecuteResult>(qer => result = qer)
|
||||
.AddEventHandling(QueryExecuteCompleteEvent.Type, (et, p) => completeParams = p)
|
||||
.AddEventHandling(QueryExecuteBatchStartEvent.Type, (et, p) => batchStartParams = p)
|
||||
.AddEventHandling(QueryExecuteBatchCompleteEvent.Type, (et, p) => batchCompleteParams = p)
|
||||
.AddEventHandling(QueryExecuteResultSetCompleteEvent.Type, (et, p) => resultCompleteParams = p);
|
||||
await Common.AwaitExecution(queryService, queryParams, requestContext.Object);
|
||||
@@ -94,7 +107,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
// ... A completion event should have been fired with one result
|
||||
// ... A batch completion event should have been fired
|
||||
// ... A resultset completion event should have been fired
|
||||
VerifyQueryExecuteCallCount(requestContext, Times.Once(), Times.Once(), Times.Once(), Times.Once(), Times.Never());
|
||||
VerifyQueryExecuteCallCount(requestContext, Times.Once(), Times.Once(), Times.Once(), Times.Once(), Times.Once(), Times.Never());
|
||||
Assert.Null(result.Messages);
|
||||
|
||||
Assert.Equal(1, completeParams.BatchSummaries.Length);
|
||||
@@ -102,6 +115,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
Assert.NotEmpty(completeParams.BatchSummaries[0].Messages);
|
||||
Assert.False(completeParams.BatchSummaries[0].HasError);
|
||||
|
||||
// ... Batch start summary should not contain result sets, messages, but should contain owner URI
|
||||
Assert.NotNull(batchStartParams);
|
||||
Assert.NotNull(batchStartParams.BatchSummary);
|
||||
Assert.Null(batchStartParams.BatchSummary.Messages);
|
||||
Assert.Null(batchStartParams.BatchSummary.ResultSetSummaries);
|
||||
Assert.Equal(Common.OwnerUri, batchStartParams.OwnerUri);
|
||||
|
||||
Assert.NotNull(batchCompleteParams);
|
||||
Assert.NotEmpty(batchCompleteParams.BatchSummary.ResultSetSummaries);
|
||||
Assert.NotEmpty(batchCompleteParams.BatchSummary.Messages);
|
||||
@@ -131,10 +151,12 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
|
||||
QueryExecuteResult result = null;
|
||||
QueryExecuteCompleteParams completeParams = null;
|
||||
QueryExecuteBatchCompleteParams batchCompleteParams = null;
|
||||
QueryExecuteBatchNotificationParams batchStartParams = null;
|
||||
QueryExecuteBatchNotificationParams batchCompleteParams = null;
|
||||
List<QueryExecuteResultSetCompleteParams> resultCompleteParams = new List<QueryExecuteResultSetCompleteParams>();
|
||||
var requestContext = RequestContextMocks.Create<QueryExecuteResult>(qer => result = qer)
|
||||
.AddEventHandling(QueryExecuteCompleteEvent.Type, (et, p) => completeParams = p)
|
||||
.AddEventHandling(QueryExecuteBatchStartEvent.Type, (et, p) => batchStartParams = p)
|
||||
.AddEventHandling(QueryExecuteBatchCompleteEvent.Type, (et, p) => batchCompleteParams = p)
|
||||
.AddEventHandling(QueryExecuteResultSetCompleteEvent.Type, (et, p) => resultCompleteParams.Add(p));
|
||||
await Common.AwaitExecution(queryService, queryParams, requestContext.Object);
|
||||
@@ -145,7 +167,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
// ... A completion event should have been fired with one result
|
||||
// ... A batch completion event should have been fired
|
||||
// ... Two resultset completion events should have been fired
|
||||
VerifyQueryExecuteCallCount(requestContext, Times.Once(), Times.Once(), Times.Once(), Times.Exactly(2), Times.Never());
|
||||
VerifyQueryExecuteCallCount(requestContext, Times.Once(), Times.Once(), Times.Once(), Times.Once(), Times.Exactly(2), Times.Never());
|
||||
Assert.Null(result.Messages);
|
||||
|
||||
Assert.Equal(1, completeParams.BatchSummaries.Length);
|
||||
@@ -153,6 +175,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
Assert.NotEmpty(completeParams.BatchSummaries[0].Messages);
|
||||
Assert.False(completeParams.BatchSummaries[0].HasError);
|
||||
|
||||
// ... Batch start summary should not contain result sets, messages, but should contain owner URI
|
||||
Assert.NotNull(batchStartParams);
|
||||
Assert.NotNull(batchStartParams.BatchSummary);
|
||||
Assert.Null(batchStartParams.BatchSummary.Messages);
|
||||
Assert.Null(batchStartParams.BatchSummary.ResultSetSummaries);
|
||||
Assert.Equal(Common.OwnerUri, batchStartParams.OwnerUri);
|
||||
|
||||
Assert.NotNull(batchCompleteParams);
|
||||
Assert.NotEmpty(batchCompleteParams.BatchSummary.ResultSetSummaries);
|
||||
Assert.NotEmpty(batchCompleteParams.BatchSummary.Messages);
|
||||
@@ -183,10 +212,12 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
|
||||
QueryExecuteResult result = null;
|
||||
QueryExecuteCompleteParams completeParams = null;
|
||||
List<QueryExecuteBatchCompleteParams> batchCompleteParams = new List<QueryExecuteBatchCompleteParams>();
|
||||
List<QueryExecuteBatchNotificationParams> batchStartParams = new List<QueryExecuteBatchNotificationParams>();
|
||||
List<QueryExecuteBatchNotificationParams> batchCompleteParams = new List<QueryExecuteBatchNotificationParams>();
|
||||
List<QueryExecuteResultSetCompleteParams> resultCompleteParams = new List<QueryExecuteResultSetCompleteParams>();
|
||||
var requestContext = RequestContextMocks.Create<QueryExecuteResult>(qer => result = qer)
|
||||
.AddEventHandling(QueryExecuteCompleteEvent.Type, (et, p) => completeParams = p)
|
||||
.AddEventHandling(QueryExecuteBatchStartEvent.Type, (et, p) => batchStartParams.Add(p))
|
||||
.AddEventHandling(QueryExecuteBatchCompleteEvent.Type, (et, p) => batchCompleteParams.Add(p))
|
||||
.AddEventHandling(QueryExecuteResultSetCompleteEvent.Type, (et, p) => resultCompleteParams.Add(p));
|
||||
await Common.AwaitExecution(queryService, queryParams, requestContext.Object);
|
||||
@@ -195,7 +226,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
// ... No errors should have been sent
|
||||
// ... A successful result should have been sent without messages
|
||||
|
||||
VerifyQueryExecuteCallCount(requestContext, Times.Once(), Times.Once(), Times.Exactly(2), Times.Exactly(2), Times.Never());
|
||||
VerifyQueryExecuteCallCount(requestContext, Times.Once(), Times.Once(), Times.Exactly(2), Times.Exactly(2), Times.Exactly(2), Times.Never());
|
||||
Assert.Null(result.Messages);
|
||||
|
||||
// ... A completion event should have been fired with one two batch summaries, one result each
|
||||
@@ -205,6 +236,15 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
Assert.NotEmpty(completeParams.BatchSummaries[0].Messages);
|
||||
Assert.NotEmpty(completeParams.BatchSummaries[1].Messages);
|
||||
|
||||
// ... Two batch start events should have been fired
|
||||
Assert.Equal(2, batchStartParams.Count);
|
||||
foreach (var batch in batchStartParams)
|
||||
{
|
||||
Assert.Null(batch.BatchSummary.Messages);
|
||||
Assert.Null(batch.BatchSummary.ResultSetSummaries);
|
||||
Assert.Equal(Common.OwnerUri, batch.OwnerUri);
|
||||
}
|
||||
|
||||
// ... Two batch completion events should have been fired
|
||||
Assert.Equal(2, batchCompleteParams.Count);
|
||||
foreach (var batch in batchCompleteParams)
|
||||
@@ -250,7 +290,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
// ... No result should have been returned
|
||||
// ... No completion event should have been fired
|
||||
// ... There should be no active queries
|
||||
VerifyQueryExecuteCallCount(requestContext, Times.Never(), Times.Never(), Times.Never(), Times.Never(), Times.Once());
|
||||
VerifyQueryExecuteCallCount(requestContext, Times.Never(), Times.Never(), Times.Never(), Times.Never(), Times.Never(), Times.Once());
|
||||
Assert.IsType<string>(error);
|
||||
Assert.NotEmpty((string)error);
|
||||
Assert.Empty(queryService.ActiveQueries);
|
||||
@@ -285,7 +325,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
// ... No completion event should have been fired
|
||||
// ... A batch completion event should have fired, but not a resultset event
|
||||
// ... There should only be one active query
|
||||
VerifyQueryExecuteCallCount(secondRequestContext, Times.Never(), Times.AtMostOnce(), Times.AtMostOnce(), Times.Never(), Times.Once());
|
||||
VerifyQueryExecuteCallCount(secondRequestContext, Times.Never(), Times.AtMostOnce(), Times.AtMostOnce(), Times.AtMostOnce(), Times.Never(), Times.Once());
|
||||
Assert.IsType<string>(error);
|
||||
Assert.NotEmpty((string)error);
|
||||
Assert.Equal(1, queryService.ActiveQueries.Count);
|
||||
@@ -311,9 +351,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
// ... And then I request another query after waiting for the first to complete
|
||||
QueryExecuteResult result = null;
|
||||
QueryExecuteCompleteParams complete = null;
|
||||
QueryExecuteBatchCompleteParams batchComplete = null;
|
||||
QueryExecuteBatchNotificationParams batchStart = null;
|
||||
QueryExecuteBatchNotificationParams batchComplete = null;
|
||||
var secondRequestContext = RequestContextMocks.Create<QueryExecuteResult>(qer => result = qer)
|
||||
.AddEventHandling(QueryExecuteCompleteEvent.Type, (et, qecp) => complete = qecp)
|
||||
.AddEventHandling(QueryExecuteBatchStartEvent.Type, (et, p) => batchStart = p)
|
||||
.AddEventHandling(QueryExecuteBatchCompleteEvent.Type, (et, p) => batchComplete = p);
|
||||
await Common.AwaitExecution(queryService, queryParams, secondRequestContext.Object);
|
||||
|
||||
@@ -322,20 +364,20 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
// ... A result should have been sent with no errors
|
||||
// ... There should only be one active query
|
||||
// ... A batch completion event should have fired, but not a result set completion event
|
||||
VerifyQueryExecuteCallCount(secondRequestContext, Times.Once(), Times.Once(), Times.Once(), Times.Never(), Times.Never());
|
||||
VerifyQueryExecuteCallCount(secondRequestContext, Times.Once(), Times.Once(), Times.Once(), Times.Once(), Times.Never(), Times.Never());
|
||||
Assert.Null(result.Messages);
|
||||
|
||||
Assert.False(complete.BatchSummaries.Any(b => b.HasError));
|
||||
Assert.Equal(1, queryService.ActiveQueries.Count);
|
||||
|
||||
Assert.NotNull(batchStart);
|
||||
Assert.NotNull(batchComplete);
|
||||
Assert.False(batchComplete.BatchSummary.HasError);
|
||||
Assert.Equal(complete.OwnerUri, batchComplete.OwnerUri);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(null)]
|
||||
public async Task QueryExecuteMissingSelectionTest(SelectionData selection)
|
||||
[Fact]
|
||||
public async Task QueryExecuteMissingSelectionTest()
|
||||
{
|
||||
// Given:
|
||||
// ... A workspace with a standard query is configured
|
||||
@@ -357,7 +399,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
// ... No result should have been sent
|
||||
// ... No completion events should have been fired
|
||||
// ... An active query should not have been added
|
||||
VerifyQueryExecuteCallCount(requestContext, Times.Never(), Times.Never(), Times.Never(), Times.Never(), Times.Once());
|
||||
VerifyQueryExecuteCallCount(requestContext, Times.Never(), Times.Never(), Times.Never(), Times.Never(), Times.Never(), Times.Once());
|
||||
Assert.NotNull(errorResult);
|
||||
Assert.IsType<string>(errorResult);
|
||||
Assert.DoesNotContain(Common.OwnerUri, queryService.ActiveQueries.Keys);
|
||||
@@ -380,9 +422,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
|
||||
QueryExecuteResult result = null;
|
||||
QueryExecuteCompleteParams complete = null;
|
||||
QueryExecuteBatchCompleteParams batchComplete = null;
|
||||
QueryExecuteBatchNotificationParams batchStart = null;
|
||||
QueryExecuteBatchNotificationParams batchComplete = null;
|
||||
var requestContext = RequestContextMocks.Create<QueryExecuteResult>(qer => result = qer)
|
||||
.AddEventHandling(QueryExecuteCompleteEvent.Type, (et, qecp) => complete = qecp)
|
||||
.AddEventHandling(QueryExecuteBatchStartEvent.Type, (et, p) => batchStart = p)
|
||||
.AddEventHandling(QueryExecuteBatchCompleteEvent.Type, (et, p) => batchComplete = p);
|
||||
await Common.AwaitExecution(queryService, queryParams, requestContext.Object);
|
||||
|
||||
@@ -390,29 +434,43 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
// ... No errors should have been sent
|
||||
// ... A result should have been sent with success (we successfully started the query)
|
||||
// ... A completion event (query, batch, not resultset) should have been sent with error
|
||||
VerifyQueryExecuteCallCount(requestContext, Times.Once(), Times.Once(), Times.Once(), Times.Never(), Times.Never());
|
||||
VerifyQueryExecuteCallCount(requestContext, Times.Once(), Times.Once(), Times.Once(), Times.Once(), Times.Never(), Times.Never());
|
||||
Assert.Null(result.Messages);
|
||||
|
||||
Assert.Equal(1, complete.BatchSummaries.Length);
|
||||
Assert.True(complete.BatchSummaries[0].HasError);
|
||||
Assert.NotEmpty(complete.BatchSummaries[0].Messages);
|
||||
|
||||
Assert.NotNull(batchStart);
|
||||
Assert.False(batchStart.BatchSummary.HasError);
|
||||
Assert.Null(batchStart.BatchSummary.Messages);
|
||||
Assert.Null(batchStart.BatchSummary.ResultSetSummaries);
|
||||
Assert.Equal(Common.OwnerUri, batchStart.OwnerUri);
|
||||
|
||||
Assert.NotNull(batchComplete);
|
||||
Assert.True(batchComplete.BatchSummary.HasError);
|
||||
Assert.NotEmpty(batchComplete.BatchSummary.Messages);
|
||||
Assert.Equal(complete.OwnerUri, batchComplete.OwnerUri);
|
||||
Assert.Equal(Common.OwnerUri, batchComplete.OwnerUri);
|
||||
}
|
||||
|
||||
private static void VerifyQueryExecuteCallCount(Mock<RequestContext<QueryExecuteResult>> mock, Times sendResultCalls,
|
||||
Times sendCompletionEventCalls, Times sendBatchCompletionEvent, Times sendResultCompleteEvent, Times sendErrorCalls)
|
||||
private static void VerifyQueryExecuteCallCount(Mock<RequestContext<QueryExecuteResult>> mock,
|
||||
Times sendResultCalls,
|
||||
Times sendCompletionEventCalls,
|
||||
Times sendBatchStartEvent,
|
||||
Times sendBatchCompletionEvent,
|
||||
Times sendResultCompleteEvent,
|
||||
Times sendErrorCalls)
|
||||
{
|
||||
mock.Verify(rc => rc.SendResult(It.IsAny<QueryExecuteResult>()), sendResultCalls);
|
||||
mock.Verify(rc => rc.SendEvent(
|
||||
It.Is<EventType<QueryExecuteCompleteParams>>(m => m == QueryExecuteCompleteEvent.Type),
|
||||
It.IsAny<QueryExecuteCompleteParams>()), sendCompletionEventCalls);
|
||||
mock.Verify(rc => rc.SendEvent(
|
||||
It.Is<EventType<QueryExecuteBatchCompleteParams>>(m => m == QueryExecuteBatchCompleteEvent.Type),
|
||||
It.IsAny<QueryExecuteBatchCompleteParams>()), sendBatchCompletionEvent);
|
||||
It.Is<EventType<QueryExecuteBatchNotificationParams>>(m => m == QueryExecuteBatchCompleteEvent.Type),
|
||||
It.IsAny<QueryExecuteBatchNotificationParams>()), sendBatchCompletionEvent);
|
||||
mock.Verify(rc => rc.SendEvent(
|
||||
It.Is<EventType<QueryExecuteBatchNotificationParams>>(m => m== QueryExecuteBatchStartEvent.Type),
|
||||
It.IsAny<QueryExecuteBatchNotificationParams>()), sendBatchStartEvent);
|
||||
mock.Verify(rc => rc.SendEvent(
|
||||
It.Is<EventType<QueryExecuteResultSetCompleteParams>>(m => m == QueryExecuteResultSetCompleteEvent.Type),
|
||||
It.IsAny<QueryExecuteResultSetCompleteParams>()), sendResultCompleteEvent);
|
||||
|
||||
Reference in New Issue
Block a user