mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-16 10:58:30 -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:
@@ -48,7 +48,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Credentials
|
|||||||
/// Default constructor is private since it's a singleton class
|
/// Default constructor is private since it's a singleton class
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private CredentialService()
|
private CredentialService()
|
||||||
: this(null, new LinuxCredentialStore.StoreConfig()
|
: this(null, new StoreConfig()
|
||||||
{ CredentialFolder = DefaultSecretsFolder, CredentialFile = DefaultSecretsFile, IsRelativeToUserHomeDir = true})
|
{ CredentialFolder = DefaultSecretsFolder, CredentialFile = DefaultSecretsFile, IsRelativeToUserHomeDir = true})
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -56,7 +56,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Credentials
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Internal for testing purposes only
|
/// Internal for testing purposes only
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal CredentialService(ICredentialStore store, LinuxCredentialStore.StoreConfig config)
|
internal CredentialService(ICredentialStore store, StoreConfig config)
|
||||||
{
|
{
|
||||||
this.credStore = store != null ? store : GetStoreForOS(config);
|
this.credStore = store != null ? store : GetStoreForOS(config);
|
||||||
}
|
}
|
||||||
@@ -64,12 +64,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Credentials
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Internal for testing purposes only
|
/// Internal for testing purposes only
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static ICredentialStore GetStoreForOS(LinuxCredentialStore.StoreConfig config)
|
internal static ICredentialStore GetStoreForOS(StoreConfig config)
|
||||||
{
|
{
|
||||||
if(RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
if(RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||||
{
|
{
|
||||||
return new Win32CredentialStore();
|
return new Win32CredentialStore();
|
||||||
}
|
}
|
||||||
|
#if !WINDOWS_ONLY_BUILD
|
||||||
else if(RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
else if(RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||||
{
|
{
|
||||||
return new OSXCredentialStore();
|
return new OSXCredentialStore();
|
||||||
@@ -78,6 +79,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Credentials
|
|||||||
{
|
{
|
||||||
return new LinuxCredentialStore(config);
|
return new LinuxCredentialStore(config);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
throw new InvalidOperationException("Platform not currently supported");
|
throw new InvalidOperationException("Platform not currently supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ using Newtonsoft.Json;
|
|||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.Credentials.Linux
|
namespace Microsoft.SqlTools.ServiceLayer.Credentials.Linux
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#if !WINDOWS_ONLY_BUILD
|
||||||
|
|
||||||
public class FileTokenStorage
|
public class FileTokenStorage
|
||||||
{
|
{
|
||||||
private const int OwnerAccessMode = 384; // Permission 0600 - owner read/write, nobody else has access
|
private const int OwnerAccessMode = 384; // Permission 0600 - owner read/write, nobody else has access
|
||||||
@@ -84,4 +87,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Credentials.Linux
|
|||||||
Interop.Sys.ChMod(filePath, OwnerAccessMode);
|
Interop.Sys.ChMod(filePath, OwnerAccessMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ using System.Runtime.InteropServices;
|
|||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.Credentials
|
namespace Microsoft.SqlTools.ServiceLayer.Credentials
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#if !WINDOWS_ONLY_BUILD
|
||||||
|
|
||||||
internal static partial class Interop
|
internal static partial class Interop
|
||||||
{
|
{
|
||||||
/// <summary>Common Unix errno error codes.</summary>
|
/// <summary>Common Unix errno error codes.</summary>
|
||||||
@@ -218,4 +221,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Credentials
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,9 @@ using System.Runtime.InteropServices;
|
|||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.Credentials
|
namespace Microsoft.SqlTools.ServiceLayer.Credentials
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#if !WINDOWS_ONLY_BUILD
|
||||||
|
|
||||||
internal static partial class Interop
|
internal static partial class Interop
|
||||||
{
|
{
|
||||||
internal static partial class Sys
|
internal static partial class Sys
|
||||||
@@ -37,6 +40,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Credentials
|
|||||||
internal const string SystemNative = "System.Native";
|
internal const string SystemNative = "System.Native";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@@ -15,6 +14,18 @@ using Microsoft.SqlTools.ServiceLayer.Utility;
|
|||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.Credentials.Linux
|
namespace Microsoft.SqlTools.ServiceLayer.Credentials.Linux
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Store configuration struct
|
||||||
|
/// </summary>
|
||||||
|
internal struct StoreConfig
|
||||||
|
{
|
||||||
|
public string CredentialFolder { get; set; }
|
||||||
|
public string CredentialFile { get; set; }
|
||||||
|
public bool IsRelativeToUserHomeDir { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !WINDOWS_ONLY_BUILD
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Linux implementation of the credential store.
|
/// Linux implementation of the credential store.
|
||||||
///
|
///
|
||||||
@@ -25,13 +36,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Credentials.Linux
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal class LinuxCredentialStore : ICredentialStore
|
internal class LinuxCredentialStore : ICredentialStore
|
||||||
{
|
{
|
||||||
internal struct StoreConfig
|
|
||||||
{
|
|
||||||
public string CredentialFolder { get; set; }
|
|
||||||
public string CredentialFile { get; set; }
|
|
||||||
public bool IsRelativeToUserHomeDir { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private string credentialFolderPath;
|
private string credentialFolderPath;
|
||||||
private string credentialFileName;
|
private string credentialFileName;
|
||||||
private FileTokenStorage storage;
|
private FileTokenStorage storage;
|
||||||
@@ -228,4 +232,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Credentials.Linux
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ using Microsoft.SqlTools.ServiceLayer.Utility;
|
|||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.Credentials.OSX
|
namespace Microsoft.SqlTools.ServiceLayer.Credentials.OSX
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#if !WINDOWS_ONLY_BUILD
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// OSX implementation of the credential store
|
/// OSX implementation of the credential store
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -155,4 +158,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Credentials.OSX
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,16 @@
|
|||||||
"debugType": "portable",
|
"debugType": "portable",
|
||||||
"emitEntryPoint": true
|
"emitEntryPoint": true
|
||||||
},
|
},
|
||||||
|
"configurations": {
|
||||||
|
"Integration": {
|
||||||
|
"buildOptions": {
|
||||||
|
"define": [
|
||||||
|
"WINDOWS_ONLY_BUILD"
|
||||||
|
],
|
||||||
|
"emitEntryPoint": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Newtonsoft.Json": "9.0.1",
|
"Newtonsoft.Json": "9.0.1",
|
||||||
"System.Data.Common": "4.1.0",
|
"System.Data.Common": "4.1.0",
|
||||||
|
|||||||
@@ -17,7 +17,20 @@ dotnet build %WORKINGDIR%..\..\src\Microsoft.SqlTools.ServiceLayer\project.json
|
|||||||
|
|
||||||
REM run the tests through OpenCover and generate a report
|
REM run the tests through OpenCover and generate a report
|
||||||
dotnet build %WORKINGDIR%..\..\test\Microsoft.SqlTools.ServiceLayer.Test\project.json %DOTNETCONFIG%
|
dotnet build %WORKINGDIR%..\..\test\Microsoft.SqlTools.ServiceLayer.Test\project.json %DOTNETCONFIG%
|
||||||
"%WORKINGDIR%packages\OpenCover.4.6.519\tools\OpenCover.Console.exe" -register:user -target:dotnet.exe -targetargs:"test %WORKINGDIR%..\Microsoft.SqlTools.ServiceLayer.Test\project.json %DOTNETCONFIG%" -oldstyle -filter:"+[Microsoft.SqlTools.*]* -[xunit*]*" -output:coverage.xml -searchdirs:%WORKINGDIR%..\Microsoft.SqlTools.ServiceLayer.Test\bin\Debug\netcoreapp1.0
|
|
||||||
|
SET SQLTOOLSSERVICE_EXE=%WORKINGDIR%..\..\src\Microsoft.SqlTools.ServiceLayer\bin\Integration\netcoreapp1.0\win7-x64\Microsoft.SqlTools.ServiceLayer.exe
|
||||||
|
SET SERVICECODECOVERAGE=TRUE
|
||||||
|
SET CODECOVERAGETOOL="%WORKINGDIR%packages\OpenCover.4.6.519\tools\OpenCover.Console.exe"
|
||||||
|
SET CODECOVERAGEOUTPUT=coverage.xml
|
||||||
|
|
||||||
|
dotnet.exe test %WORKINGDIR%..\Microsoft.SqlTools.ServiceLayer.TestDriver\project.json %DOTNETCONFIG%"
|
||||||
|
|
||||||
|
SET SERVICECODECOVERAGE=FALSE
|
||||||
|
|
||||||
|
"%WORKINGDIR%packages\OpenCover.4.6.519\tools\OpenCover.Console.exe" -mergeoutput -register:user -target:dotnet.exe -targetargs:"test %WORKINGDIR%..\Microsoft.SqlTools.ServiceLayer.TestDriver\project.json %DOTNETCONFIG%" -oldstyle -filter:"+[Microsoft.SqlTools.*]* -[xunit*]*" -output:coverage.xml -searchdirs:%WORKINGDIR%..\Microsoft.SqlTools.ServiceLayer.TestDriver\bin\Debug\netcoreapp1.0
|
||||||
|
|
||||||
|
"%WORKINGDIR%packages\OpenCover.4.6.519\tools\OpenCover.Console.exe" -mergeoutput -register:user -target:dotnet.exe -targetargs:"test %WORKINGDIR%..\Microsoft.SqlTools.ServiceLayer.Test\project.json %DOTNETCONFIG%" -oldstyle -filter:"+[Microsoft.SqlTools.*]* -[xunit*]*" -output:coverage.xml -searchdirs:%WORKINGDIR%..\Microsoft.SqlTools.ServiceLayer.Test\bin\Debug\netcoreapp1.0
|
||||||
|
|
||||||
"%WORKINGDIR%packages\OpenCoverToCoberturaConverter.0.2.4.0\tools\OpenCoverToCoberturaConverter.exe" -input:coverage.xml -output:outputCobertura.xml -sources:%WORKINGDIR%..\..\src\Microsoft.SqlTools.ServiceLayer
|
"%WORKINGDIR%packages\OpenCoverToCoberturaConverter.0.2.4.0\tools\OpenCoverToCoberturaConverter.exe" -input:coverage.xml -output:outputCobertura.xml -sources:%WORKINGDIR%..\..\src\Microsoft.SqlTools.ServiceLayer
|
||||||
"%WORKINGDIR%packages\ReportGenerator.2.4.5.0\tools\ReportGenerator.exe" "-reports:coverage.xml" "-targetdir:%WORKINGDIR%\reports"
|
"%WORKINGDIR%packages\ReportGenerator.2.4.5.0\tools\ReportGenerator.exe" "-reports:coverage.xml" "-targetdir:%WORKINGDIR%\reports"
|
||||||
|
|
||||||
|
|||||||
4
test/CodeCoverage/runintegration.bat
Normal file
4
test/CodeCoverage/runintegration.bat
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
set DOTNETCONFIG=-c Integration
|
||||||
|
|
||||||
|
cmd /c npm install
|
||||||
|
gulp
|
||||||
@@ -24,7 +24,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class CredentialServiceTests : IDisposable
|
public class CredentialServiceTests : IDisposable
|
||||||
{
|
{
|
||||||
private static readonly LinuxCredentialStore.StoreConfig config = new LinuxCredentialStore.StoreConfig()
|
private static readonly StoreConfig config = new StoreConfig()
|
||||||
{
|
{
|
||||||
CredentialFolder = ".testsecrets",
|
CredentialFolder = ".testsecrets",
|
||||||
CredentialFile = "sqltestsecrets.json",
|
CredentialFile = "sqltestsecrets.json",
|
||||||
@@ -61,6 +61,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
|||||||
{
|
{
|
||||||
credStore.DeletePassword(credentialId);
|
credStore.DeletePassword(credentialId);
|
||||||
credStore.DeletePassword(otherCredId);
|
credStore.DeletePassword(otherCredId);
|
||||||
|
|
||||||
|
#if !WINDOWS_ONLY_BUILD
|
||||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||||
{
|
{
|
||||||
string credsFolder = ((LinuxCredentialStore)credStore).CredentialFolderPath;
|
string credsFolder = ((LinuxCredentialStore)credStore).CredentialFolderPath;
|
||||||
@@ -69,6 +71,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
|||||||
Directory.Delete(credsFolder, true);
|
Directory.Delete(credsFolder, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|||||||
@@ -15,23 +15,25 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Credentials
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void GetEUidReturnsInt()
|
public void GetEUidReturnsInt()
|
||||||
{
|
{
|
||||||
|
#if !WINDOWS_ONLY_BUILD
|
||||||
TestUtils.RunIfLinux(() =>
|
TestUtils.RunIfLinux(() =>
|
||||||
{
|
{
|
||||||
Assert.NotNull(Interop.Sys.GetEUid());
|
Assert.NotNull(Interop.Sys.GetEUid());
|
||||||
});
|
});
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void GetHomeDirectoryFromPwFindsHomeDir()
|
public void GetHomeDirectoryFromPwFindsHomeDir()
|
||||||
{
|
{
|
||||||
|
#if !WINDOWS_ONLY_BUILD
|
||||||
TestUtils.RunIfLinux(() =>
|
TestUtils.RunIfLinux(() =>
|
||||||
{
|
{
|
||||||
string userDir = LinuxCredentialStore.GetHomeDirectoryFromPw();
|
string userDir = LinuxCredentialStore.GetHomeDirectoryFromPw();
|
||||||
Assert.StartsWith("/", userDir);
|
Assert.StartsWith("/", userDir);
|
||||||
});
|
});
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,8 @@
|
|||||||
"Integration": {
|
"Integration": {
|
||||||
"buildOptions": {
|
"buildOptions": {
|
||||||
"define": [
|
"define": [
|
||||||
"LIVE_CONNECTION_TESTS"
|
"LIVE_CONNECTION_TESTS",
|
||||||
|
"WINDOWS_ONLY_BUILD"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol;
|
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol;
|
||||||
@@ -22,19 +23,55 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Driver
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class ServiceTestDriver : TestDriverBase
|
public class ServiceTestDriver : TestDriverBase
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public const string ServiceCodeCoverageEnvironmentVariable = "SERVICECODECOVERAGE";
|
||||||
|
|
||||||
|
public const string CodeCoverageToolEnvironmentVariable = "CODECOVERAGETOOL";
|
||||||
|
|
||||||
|
public const string CodeCoverageOutputEnvironmentVariable = "CODECOVERAGEOUTPUT";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Environment variable that stores the path to the service host executable.
|
/// Environment variable that stores the path to the service host executable.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string ServiceHostEnvironmentVariable
|
public static string ServiceHostEnvironmentVariable
|
||||||
{
|
{
|
||||||
get { return "SQLTOOLSSERVICE_EXE"; }
|
get { return "SQLTOOLSSERVICE_EXE"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsCoverageRun { get; set; }
|
||||||
|
|
||||||
public ServiceTestDriver()
|
public ServiceTestDriver()
|
||||||
{
|
{
|
||||||
string serviceHostExecutable = Environment.GetEnvironmentVariable(ServiceHostEnvironmentVariable);
|
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);
|
this.protocolClient = new ProtocolEndpoint(clientChannel, MessageProtocolType.LanguageServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,10 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol;
|
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Channel;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Contracts;
|
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Contracts;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Utility;
|
using Microsoft.SqlTools.ServiceLayer.Utility;
|
||||||
|
|
||||||
@@ -24,12 +26,29 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Driver
|
|||||||
{
|
{
|
||||||
protected ProtocolEndpoint protocolClient;
|
protected ProtocolEndpoint protocolClient;
|
||||||
|
|
||||||
|
protected StdioClientChannel clientChannel;
|
||||||
|
|
||||||
private ConcurrentDictionary<string, AsyncQueue<object>> eventQueuePerType =
|
private ConcurrentDictionary<string, AsyncQueue<object>> eventQueuePerType =
|
||||||
new ConcurrentDictionary<string, AsyncQueue<object>>();
|
new ConcurrentDictionary<string, AsyncQueue<object>>();
|
||||||
|
|
||||||
private ConcurrentDictionary<string, AsyncQueue<object>> requestQueuePerType =
|
private ConcurrentDictionary<string, AsyncQueue<object>> requestQueuePerType =
|
||||||
new ConcurrentDictionary<string, AsyncQueue<object>>();
|
new ConcurrentDictionary<string, AsyncQueue<object>>();
|
||||||
|
|
||||||
|
public Process ServiceProcess
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Process.GetProcessById(clientChannel.ProcessId);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Task<TResult> SendRequest<TParams, TResult>(
|
public Task<TResult> SendRequest<TParams, TResult>(
|
||||||
RequestType<TParams, TResult> requestType,
|
RequestType<TParams, TResult> requestType,
|
||||||
TParams requestParams)
|
TParams requestParams)
|
||||||
|
|||||||
@@ -3,8 +3,11 @@
|
|||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.SqlTools.ServiceLayer.TestDriver.Utility;
|
using Microsoft.SqlTools.ServiceLayer.TestDriver.Utility;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
@@ -16,40 +19,49 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public async Task TestQueryingAfterCompletionRequests()
|
public async Task TestQueryingAfterCompletionRequests()
|
||||||
{
|
{
|
||||||
string ownerUri = System.IO.Path.GetTempFileName();
|
try
|
||||||
string query = "SELECT * FROM sys.objects";
|
{
|
||||||
List<Task> tasks = new List<Task>();
|
string ownerUri = System.IO.Path.GetTempFileName();
|
||||||
|
string query = "SELECT * FROM sys.objects";
|
||||||
|
List<Task> tasks = new List<Task>();
|
||||||
|
|
||||||
await Connect(ownerUri, ConnectionTestUtils.AzureTestServerConnection);
|
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);
|
|
||||||
|
|
||||||
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);
|
await Connect(ownerUri, ConnectionTestUtils.DataToolsTelemetryAzureConnection);
|
||||||
tasks.Clear();
|
tasks.Clear();
|
||||||
Enumerable.Range(0, 10).ToList().ForEach(arg => tasks.Add(RequestCompletion(ownerUri, query, 0, 10)));
|
Enumerable.Range(0, 10).ToList().ForEach(arg => tasks.Add(RequestCompletion(ownerUri, query, 0, 10)));
|
||||||
queryTask = RunQuery(ownerUri, query);
|
queryTask = RunQuery(ownerUri, query);
|
||||||
tasks.Add(queryTask);
|
tasks.Add(queryTask);
|
||||||
await Task.WhenAll(tasks);
|
await Task.WhenAll(tasks);
|
||||||
|
|
||||||
Assert.NotNull(queryTask.Result);
|
Assert.NotNull(queryTask.Result);
|
||||||
Assert.NotNull(queryTask.Result.BatchSummaries);
|
Assert.NotNull(queryTask.Result.BatchSummaries);
|
||||||
|
|
||||||
await Connect(ownerUri, ConnectionTestUtils.SqlDataToolsAzureConnection);
|
await Connect(ownerUri, ConnectionTestUtils.SqlDataToolsAzureConnection);
|
||||||
tasks.Clear();
|
tasks.Clear();
|
||||||
Enumerable.Range(0, 10).ToList().ForEach(arg => tasks.Add(RequestCompletion(ownerUri, query, 0, 10)));
|
Enumerable.Range(0, 10).ToList().ForEach(arg => tasks.Add(RequestCompletion(ownerUri, query, 0, 10)));
|
||||||
queryTask = RunQuery(ownerUri, query);
|
queryTask = RunQuery(ownerUri, query);
|
||||||
tasks.Add(queryTask);
|
tasks.Add(queryTask);
|
||||||
await Task.WhenAll(tasks);
|
await Task.WhenAll(tasks);
|
||||||
|
|
||||||
Assert.NotNull(queryTask.Result);
|
Assert.NotNull(queryTask.Result);
|
||||||
Assert.NotNull(queryTask.Result.BatchSummaries);
|
Assert.NotNull(queryTask.Result.BatchSummaries);
|
||||||
|
|
||||||
await Disconnect(ownerUri);
|
await Disconnect(ownerUri);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
WaitForExit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||||
using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts;
|
using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts;
|
||||||
@@ -18,15 +19,37 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class TestBase : IDisposable
|
public class TestBase : IDisposable
|
||||||
{
|
{
|
||||||
|
private bool isRunning = false;
|
||||||
|
|
||||||
public TestBase()
|
public TestBase()
|
||||||
{
|
{
|
||||||
Driver = new ServiceTestDriver();
|
Driver = new ServiceTestDriver();
|
||||||
Driver.Start().Wait();
|
Driver.Start().Wait();
|
||||||
|
this.isRunning = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
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>
|
/// <summary>
|
||||||
@@ -43,9 +66,9 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Request a new connection to be created
|
/// Request a new connection to be created
|
||||||
/// </summary>
|
/// </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)
|
protected async Task<bool> Connect(string ownerUri, ConnectParams connectParams)
|
||||||
{
|
{
|
||||||
connectParams.OwnerUri = ownerUri;
|
connectParams.OwnerUri = ownerUri;
|
||||||
var connectResult = await Driver.SendRequest(ConnectionRequest.Type, connectParams);
|
var connectResult = await Driver.SendRequest(ConnectionRequest.Type, connectParams);
|
||||||
if (connectResult)
|
if (connectResult)
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
"imports": [
|
"imports": [
|
||||||
"dotnet5.4",
|
"dotnet5.4",
|
||||||
"portable-net451+win8"
|
"portable-net451+win8"
|
||||||
],
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"runtimes": {
|
"runtimes": {
|
||||||
|
|||||||
Reference in New Issue
Block a user