mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-17 09:35:37 -05:00
Inter-Service API for executing queries (#223)
Adding new methods for executing queries from other services (such as the upcoming edit data service). The code is written to avoid duplicating logic by using lambdas to perform custom logic. Additionally, the service host protocol has been slightly modified to split the IMessageSender into IEventSender and IRequestSender. This allows us to use either a ServiceHost or any RequestContext<T> to send events. It becomes very convenient to use another service's request context to send the events for query execution. **Breaking Change**: This removes the messages property for query dispose results and instead elects to use error for any errors encountered during query disposal. A result is only used when something is successful. * Splitting IMessageSender into IEventSender and IRequestSender * Adding inter-service method for executing queries * Adding inter-service method for disposing of a query * Adding null checking for the success/error handlers
This commit is contained in:
@@ -48,11 +48,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution
|
||||
// ... And then I dispose of the query
|
||||
var disposeParams = new QueryDisposeParams {OwnerUri = Common.OwnerUri};
|
||||
var disposeRequest = new EventFlowValidator<QueryDisposeResult>()
|
||||
.AddResultValidation(r =>
|
||||
{
|
||||
// Then: Messages should be null
|
||||
Assert.Null(r.Messages);
|
||||
}).Complete();
|
||||
.AddStandardQueryDisposeValidator()
|
||||
.Complete();
|
||||
await queryService.HandleDisposeRequest(disposeParams, disposeRequest.Object);
|
||||
|
||||
// Then:
|
||||
@@ -71,13 +68,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution
|
||||
var disposeParams = new QueryDisposeParams {OwnerUri = Common.OwnerUri};
|
||||
|
||||
var disposeRequest = new EventFlowValidator<QueryDisposeResult>()
|
||||
.AddResultValidation(r =>
|
||||
{
|
||||
// Then: Messages should not be null
|
||||
Assert.NotNull(r.Messages);
|
||||
Assert.NotEmpty(r.Messages);
|
||||
}).Complete();
|
||||
.AddErrorValidation<string>(Assert.NotEmpty)
|
||||
.Complete();
|
||||
await queryService.HandleDisposeRequest(disposeParams, disposeRequest.Object);
|
||||
|
||||
// Then: I should have received an error
|
||||
disposeRequest.Validate();
|
||||
}
|
||||
|
||||
@@ -107,4 +102,16 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution
|
||||
Assert.Empty(queryService.ActiveQueries);
|
||||
}
|
||||
}
|
||||
|
||||
public static class QueryDisposeEventFlowValidatorExtensions
|
||||
{
|
||||
public static EventFlowValidator<QueryDisposeResult> AddStandardQueryDisposeValidator(
|
||||
this EventFlowValidator<QueryDisposeResult> evf)
|
||||
{
|
||||
// We just need to make sure that the result is not null
|
||||
evf.AddResultValidation(Assert.NotNull);
|
||||
|
||||
return evf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,97 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
|
||||
#endregion
|
||||
|
||||
#region Inter-Service API Tests
|
||||
|
||||
[Fact]
|
||||
public async Task InterServiceExecuteNullExecuteParams()
|
||||
{
|
||||
// Setup: Create a query service
|
||||
var qes = new QueryExecutionService(null, null);
|
||||
var eventSender = new EventFlowValidator<ExecuteRequestResult>().Complete().Object;
|
||||
Func<Task> successFunc = () => Task.FromResult(0);
|
||||
Func<string, Task> errorFunc = Task.FromResult;
|
||||
|
||||
|
||||
// If: I call the inter-service API to execute with a null execute params
|
||||
// Then: It should throw
|
||||
await Assert.ThrowsAsync<ArgumentNullException>(
|
||||
() => qes.InterServiceExecuteQuery(null, eventSender, successFunc, errorFunc));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InterServiceExecuteNullEventSender()
|
||||
{
|
||||
// Setup: Create a query service, and execute params
|
||||
var qes = new QueryExecutionService(null, null);
|
||||
var executeParams = new ExecuteStringParams();
|
||||
Func<Task> successFunc = () => Task.FromResult(0);
|
||||
Func<string, Task> errorFunc = Task.FromResult;
|
||||
|
||||
// If: I call the inter-service API to execute a query with a a null event sender
|
||||
// Then: It should throw
|
||||
await Assert.ThrowsAsync<ArgumentNullException>(
|
||||
() => qes.InterServiceExecuteQuery(executeParams, null, successFunc, errorFunc));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InterServiceExecuteNullSuccessFunc()
|
||||
{
|
||||
// Setup: Create a query service, and execute params
|
||||
var qes = new QueryExecutionService(null, null);
|
||||
var executeParams = new ExecuteStringParams();
|
||||
var eventSender = new EventFlowValidator<ExecuteRequestResult>().Complete().Object;
|
||||
Func<string, Task> errorFunc = Task.FromResult;
|
||||
|
||||
// If: I call the inter-service API to execute a query with a a null success function
|
||||
// Then: It should throw
|
||||
await Assert.ThrowsAsync<ArgumentNullException>(
|
||||
() => qes.InterServiceExecuteQuery(executeParams, eventSender, null, errorFunc));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InterServiceExecuteNullFailureFunc()
|
||||
{
|
||||
// Setup: Create a query service, and execute params
|
||||
var qes = new QueryExecutionService(null, null);
|
||||
var executeParams = new ExecuteStringParams();
|
||||
var eventSender = new EventFlowValidator<ExecuteRequestResult>().Complete().Object;
|
||||
Func<Task> successFunc = () => Task.FromResult(0);
|
||||
|
||||
// If: I call the inter-service API to execute a query with a a null failure function
|
||||
// Then: It should throw
|
||||
await Assert.ThrowsAsync<ArgumentNullException>(
|
||||
() => qes.InterServiceExecuteQuery(executeParams, eventSender, successFunc, null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InterServiceDisposeNullSuccessFunc()
|
||||
{
|
||||
// Setup: Create a query service and dispose params
|
||||
var qes = new QueryExecutionService(null, null);
|
||||
Func<string, Task> failureFunc = Task.FromResult;
|
||||
|
||||
// If: I call the inter-service API to dispose a query with a null success function
|
||||
// Then: It should throw
|
||||
await Assert.ThrowsAsync<ArgumentNullException>(
|
||||
() => qes.InterServiceDisposeQuery(Common.OwnerUri, null, failureFunc));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InterServiceDisposeNullFailureFunc()
|
||||
{
|
||||
// Setup: Create a query service and dispose params
|
||||
var qes = new QueryExecutionService(null, null);
|
||||
Func<Task> successFunc = () => Task.FromResult(0);
|
||||
|
||||
// If: I call the inter-service API to dispose a query with a null success function
|
||||
// Then: It should throw
|
||||
await Assert.ThrowsAsync<ArgumentNullException>(
|
||||
() => qes.InterServiceDisposeQuery(Common.OwnerUri, successFunc, null));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Execution Tests
|
||||
// NOTE: In order to limit test duplication, we're running the ExecuteDocumentSelection
|
||||
// version of execute query. The code paths are almost identical.
|
||||
@@ -378,7 +469,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
|
||||
}
|
||||
}
|
||||
|
||||
public static class EventFlowValidatorExtensions
|
||||
public static class QueryExecutionEventFlowValidatorExtensions
|
||||
{
|
||||
public static EventFlowValidator<ExecuteRequestResult> AddStandardQueryResultValidator(
|
||||
this EventFlowValidator<ExecuteRequestResult> efv)
|
||||
|
||||
Reference in New Issue
Block a user