mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-22 09:35:38 -05:00
Code coverage improvements (#121)
These are test-only changes to improve code coverage so I'll merge directly. Please review the commit and I'll pickup those changes in the next iteration. * Add integration test batch file * Exclude Linux and MacOS from Windows code coverage builds * Enable code coverage for test driver e2e tests * Use the windows only build for code coverage runs
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol;
|
||||
@@ -22,19 +23,55 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Driver
|
||||
/// </summary>
|
||||
public class ServiceTestDriver : TestDriverBase
|
||||
{
|
||||
|
||||
public const string ServiceCodeCoverageEnvironmentVariable = "SERVICECODECOVERAGE";
|
||||
|
||||
public const string CodeCoverageToolEnvironmentVariable = "CODECOVERAGETOOL";
|
||||
|
||||
public const string CodeCoverageOutputEnvironmentVariable = "CODECOVERAGEOUTPUT";
|
||||
|
||||
/// <summary>
|
||||
/// Environment variable that stores the path to the service host executable.
|
||||
/// </summary>
|
||||
public static string ServiceHostEnvironmentVariable
|
||||
{
|
||||
get { return "SQLTOOLSSERVICE_EXE"; }
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsCoverageRun { get; set; }
|
||||
|
||||
public ServiceTestDriver()
|
||||
{
|
||||
string serviceHostExecutable = Environment.GetEnvironmentVariable(ServiceHostEnvironmentVariable);
|
||||
string serviceHostArguments = "--enable-logging";
|
||||
|
||||
var clientChannel = new StdioClientChannel(serviceHostExecutable, "--enable-logging");
|
||||
//setup the service host for code coverage if the envvar is enabled
|
||||
if (Environment.GetEnvironmentVariable(ServiceCodeCoverageEnvironmentVariable) == "True")
|
||||
{
|
||||
string coverageToolPath = Environment.GetEnvironmentVariable(CodeCoverageToolEnvironmentVariable);
|
||||
if (!string.IsNullOrWhiteSpace(coverageToolPath))
|
||||
{
|
||||
string serviceHostDirectory = Path.GetDirectoryName(serviceHostExecutable);
|
||||
if (string.IsNullOrWhiteSpace(serviceHostDirectory))
|
||||
{
|
||||
serviceHostDirectory = ".";
|
||||
}
|
||||
|
||||
string coverageOutput = Environment.GetEnvironmentVariable(CodeCoverageOutputEnvironmentVariable);
|
||||
if (string.IsNullOrWhiteSpace(coverageOutput))
|
||||
{
|
||||
coverageOutput = "coverage.xml";
|
||||
}
|
||||
|
||||
serviceHostArguments = "-target:" + serviceHostExecutable + " -targetargs:" + serviceHostArguments
|
||||
+ " -register:user -oldstyle -filter:\"+[Microsoft.SqlTools.*]* -[xunit*]*\" -output:" + coverageOutput + " -searchdirs:" + serviceHostDirectory;
|
||||
serviceHostExecutable = coverageToolPath;
|
||||
|
||||
this.IsCoverageRun = true;
|
||||
}
|
||||
}
|
||||
|
||||
this.clientChannel = new StdioClientChannel(serviceHostExecutable, serviceHostArguments);
|
||||
this.protocolClient = new ProtocolEndpoint(clientChannel, MessageProtocolType.LanguageServer);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,8 +10,10 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol;
|
||||
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Channel;
|
||||
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.Utility;
|
||||
|
||||
@@ -24,12 +26,29 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Driver
|
||||
{
|
||||
protected ProtocolEndpoint protocolClient;
|
||||
|
||||
protected StdioClientChannel clientChannel;
|
||||
|
||||
private ConcurrentDictionary<string, AsyncQueue<object>> eventQueuePerType =
|
||||
new ConcurrentDictionary<string, AsyncQueue<object>>();
|
||||
|
||||
private ConcurrentDictionary<string, AsyncQueue<object>> requestQueuePerType =
|
||||
new ConcurrentDictionary<string, AsyncQueue<object>>();
|
||||
|
||||
public Process ServiceProcess
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return Process.GetProcessById(clientChannel.ProcessId);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Task<TResult> SendRequest<TParams, TResult>(
|
||||
RequestType<TParams, TResult> requestType,
|
||||
TParams requestParams)
|
||||
|
||||
@@ -3,8 +3,11 @@
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.ServiceLayer.TestDriver.Utility;
|
||||
using Xunit;
|
||||
@@ -16,40 +19,49 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests
|
||||
[Fact]
|
||||
public async Task TestQueryingAfterCompletionRequests()
|
||||
{
|
||||
string ownerUri = System.IO.Path.GetTempFileName();
|
||||
string query = "SELECT * FROM sys.objects";
|
||||
List<Task> tasks = new List<Task>();
|
||||
try
|
||||
{
|
||||
string ownerUri = System.IO.Path.GetTempFileName();
|
||||
string query = "SELECT * FROM sys.objects";
|
||||
List<Task> tasks = new List<Task>();
|
||||
|
||||
await Connect(ownerUri, ConnectionTestUtils.AzureTestServerConnection);
|
||||
Enumerable.Range(0, 10).ToList().ForEach(arg => tasks.Add(RequestCompletion(ownerUri, query, 0, 10)));
|
||||
var queryTask = RunQuery(ownerUri, query);
|
||||
tasks.Add(queryTask);
|
||||
await Task.WhenAll(tasks);
|
||||
await Connect(ownerUri, ConnectionTestUtils.AzureTestServerConnection);
|
||||
|
||||
Assert.NotNull(queryTask.Result);
|
||||
Assert.NotNull(queryTask.Result.BatchSummaries);
|
||||
|
||||
Enumerable.Range(0, 10).ToList().ForEach(arg => tasks.Add(RequestCompletion(ownerUri, query, 0, 10)));
|
||||
var queryTask = RunQuery(ownerUri, query);
|
||||
tasks.Add(queryTask);
|
||||
await Task.WhenAll(tasks);
|
||||
|
||||
Assert.NotNull(queryTask.Result);
|
||||
Assert.NotNull(queryTask.Result.BatchSummaries);
|
||||
|
||||
await Connect(ownerUri, ConnectionTestUtils.DataToolsTelemetryAzureConnection);
|
||||
tasks.Clear();
|
||||
Enumerable.Range(0, 10).ToList().ForEach(arg => tasks.Add(RequestCompletion(ownerUri, query, 0, 10)));
|
||||
queryTask = RunQuery(ownerUri, query);
|
||||
tasks.Add(queryTask);
|
||||
await Task.WhenAll(tasks);
|
||||
await Connect(ownerUri, ConnectionTestUtils.DataToolsTelemetryAzureConnection);
|
||||
tasks.Clear();
|
||||
Enumerable.Range(0, 10).ToList().ForEach(arg => tasks.Add(RequestCompletion(ownerUri, query, 0, 10)));
|
||||
queryTask = RunQuery(ownerUri, query);
|
||||
tasks.Add(queryTask);
|
||||
await Task.WhenAll(tasks);
|
||||
|
||||
Assert.NotNull(queryTask.Result);
|
||||
Assert.NotNull(queryTask.Result.BatchSummaries);
|
||||
Assert.NotNull(queryTask.Result);
|
||||
Assert.NotNull(queryTask.Result.BatchSummaries);
|
||||
|
||||
await Connect(ownerUri, ConnectionTestUtils.SqlDataToolsAzureConnection);
|
||||
tasks.Clear();
|
||||
Enumerable.Range(0, 10).ToList().ForEach(arg => tasks.Add(RequestCompletion(ownerUri, query, 0, 10)));
|
||||
queryTask = RunQuery(ownerUri, query);
|
||||
tasks.Add(queryTask);
|
||||
await Task.WhenAll(tasks);
|
||||
await Connect(ownerUri, ConnectionTestUtils.SqlDataToolsAzureConnection);
|
||||
tasks.Clear();
|
||||
Enumerable.Range(0, 10).ToList().ForEach(arg => tasks.Add(RequestCompletion(ownerUri, query, 0, 10)));
|
||||
queryTask = RunQuery(ownerUri, query);
|
||||
tasks.Add(queryTask);
|
||||
await Task.WhenAll(tasks);
|
||||
|
||||
Assert.NotNull(queryTask.Result);
|
||||
Assert.NotNull(queryTask.Result.BatchSummaries);
|
||||
Assert.NotNull(queryTask.Result);
|
||||
Assert.NotNull(queryTask.Result.BatchSummaries);
|
||||
|
||||
await Disconnect(ownerUri);
|
||||
await Disconnect(ownerUri);
|
||||
}
|
||||
finally
|
||||
{
|
||||
WaitForExit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts;
|
||||
@@ -18,15 +19,37 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests
|
||||
/// </summary>
|
||||
public class TestBase : IDisposable
|
||||
{
|
||||
private bool isRunning = false;
|
||||
|
||||
public TestBase()
|
||||
{
|
||||
Driver = new ServiceTestDriver();
|
||||
Driver.Start().Wait();
|
||||
this.isRunning = true;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Driver.Stop().Wait();
|
||||
if (this.isRunning)
|
||||
{
|
||||
WaitForExit();
|
||||
}
|
||||
}
|
||||
|
||||
public void WaitForExit()
|
||||
{
|
||||
this.isRunning = false;
|
||||
|
||||
if (!Driver.IsCoverageRun)
|
||||
{
|
||||
Driver.Stop().Wait();
|
||||
}
|
||||
else
|
||||
{
|
||||
var p = Process.Start("taskkill", "/IM Microsoft.SqlTools.ServiceLayer.exe /F");
|
||||
p.WaitForExit();
|
||||
Driver.ServiceProcess?.WaitForExit();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -43,9 +66,9 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests
|
||||
/// <summary>
|
||||
/// Request a new connection to be created
|
||||
/// </summary>
|
||||
/// <returns>True if the connection completed successfully</returns>
|
||||
/// <returns>True if the connection completed successfully</returns>
|
||||
protected async Task<bool> Connect(string ownerUri, ConnectParams connectParams)
|
||||
{
|
||||
{
|
||||
connectParams.OwnerUri = ownerUri;
|
||||
var connectResult = await Driver.SendRequest(ConnectionRequest.Type, connectParams);
|
||||
if (connectResult)
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
"imports": [
|
||||
"dotnet5.4",
|
||||
"portable-net451+win8"
|
||||
],
|
||||
]
|
||||
}
|
||||
},
|
||||
"runtimes": {
|
||||
|
||||
Reference in New Issue
Block a user