diff --git a/sqltoolsservice.sln b/sqltoolsservice.sln index 0d94b3dc..b338c5d3 100644 --- a/sqltoolsservice.sln +++ b/sqltoolsservice.sln @@ -55,6 +55,10 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.SqlTools.ServiceL EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.SqlTools.ServiceLayer.IntegrationTests", "test\Microsoft.SqlTools.ServiceLayer.IntegrationTests\Microsoft.SqlTools.ServiceLayer.IntegrationTests.xproj", "{08AF0209-D598-47BB-9DFD-FC9E74C0FE56}" EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.SqlTools.ServiceLayer.Test.Common", "test\Microsoft.SqlTools.ServiceLayer.Test.Common\Microsoft.SqlTools.ServiceLayer.Test.Common.xproj", "{B6F4BECE-82EE-4AB6-99AC-108AEE466274}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.SqlTools.ServiceLayer.TestDriver.Tests", "test\Microsoft.SqlTools.ServiceLayer.TestDriver.Tests\Microsoft.SqlTools.ServiceLayer.TestDriver.Tests.xproj", "{E7CF630E-E084-4DA4-BF69-F61BF0A8F5BE}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -92,6 +96,18 @@ Global {08AF0209-D598-47BB-9DFD-FC9E74C0FE56}.Integration|Any CPU.Build.0 = Integration|Any CPU {08AF0209-D598-47BB-9DFD-FC9E74C0FE56}.Release|Any CPU.ActiveCfg = Release|Any CPU {08AF0209-D598-47BB-9DFD-FC9E74C0FE56}.Release|Any CPU.Build.0 = Release|Any CPU + {B6F4BECE-82EE-4AB6-99AC-108AEE466274}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B6F4BECE-82EE-4AB6-99AC-108AEE466274}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B6F4BECE-82EE-4AB6-99AC-108AEE466274}.Integration|Any CPU.ActiveCfg = Debug|Any CPU + {B6F4BECE-82EE-4AB6-99AC-108AEE466274}.Integration|Any CPU.Build.0 = Debug|Any CPU + {B6F4BECE-82EE-4AB6-99AC-108AEE466274}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B6F4BECE-82EE-4AB6-99AC-108AEE466274}.Release|Any CPU.Build.0 = Release|Any CPU + {E7CF630E-E084-4DA4-BF69-F61BF0A8F5BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E7CF630E-E084-4DA4-BF69-F61BF0A8F5BE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E7CF630E-E084-4DA4-BF69-F61BF0A8F5BE}.Integration|Any CPU.ActiveCfg = Debug|Any CPU + {E7CF630E-E084-4DA4-BF69-F61BF0A8F5BE}.Integration|Any CPU.Build.0 = Debug|Any CPU + {E7CF630E-E084-4DA4-BF69-F61BF0A8F5BE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E7CF630E-E084-4DA4-BF69-F61BF0A8F5BE}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -104,5 +120,7 @@ Global {87D9C7D9-18F4-4AB9-B20D-66C02B6075E2} = {AB9CA2B8-6F70-431C-8A1D-67479D8A7BE4} {7E5968AB-83D7-4738-85A2-416A50F13D2F} = {AB9CA2B8-6F70-431C-8A1D-67479D8A7BE4} {08AF0209-D598-47BB-9DFD-FC9E74C0FE56} = {AB9CA2B8-6F70-431C-8A1D-67479D8A7BE4} + {B6F4BECE-82EE-4AB6-99AC-108AEE466274} = {AB9CA2B8-6F70-431C-8A1D-67479D8A7BE4} + {E7CF630E-E084-4DA4-BF69-F61BF0A8F5BE} = {AB9CA2B8-6F70-431C-8A1D-67479D8A7BE4} EndGlobalSection EndGlobal diff --git a/src/Microsoft.SqlTools.ServiceLayer/Credentials/CredentialService.cs b/src/Microsoft.SqlTools.ServiceLayer/Credentials/CredentialService.cs index 6cb3644e..5802a34d 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Credentials/CredentialService.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Credentials/CredentialService.cs @@ -93,54 +93,73 @@ namespace Microsoft.SqlTools.ServiceLayer.Credentials public async Task HandleReadCredentialRequest(Credential credential, RequestContext requestContext) { - Func doRead = () => + Func> doRead = () => { - return ReadCredential(credential); + return ReadCredentialAsync(credential); }; await HandleRequest(doRead, requestContext, "HandleReadCredentialRequest"); } - private Credential ReadCredential(Credential credential) + public async Task ReadCredentialAsync(Credential credential) { - Credential.ValidateForLookup(credential); - - Credential result = Credential.Copy(credential); - string password; - if (credStore.TryGetPassword(credential.CredentialId, out password)) + return await Task.Factory.StartNew(() => { - result.Password = password; - } - return result; + Credential.ValidateForLookup(credential); + + Credential result = Credential.Copy(credential); + string password; + if (credStore.TryGetPassword(credential.CredentialId, out password)) + { + result.Password = password; + } + return result; + }); } public async Task HandleSaveCredentialRequest(Credential credential, RequestContext requestContext) { - Func doSave = () => + Func> doSave = () => { - Credential.ValidateForSave(credential); - return credStore.Save(credential); + return SaveCredentialAsync(credential); }; await HandleRequest(doSave, requestContext, "HandleSaveCredentialRequest"); } + private async Task SaveCredentialAsync(Credential credential) + { + return await Task.Factory.StartNew(() => + { + Credential.ValidateForSave(credential); + return credStore.Save(credential); + }); + } + public async Task HandleDeleteCredentialRequest(Credential credential, RequestContext requestContext) { - Func doDelete = () => + Func> doDelete = () => { - Credential.ValidateForLookup(credential); - return credStore.DeletePassword(credential.CredentialId); + return DeletePasswordAsync(credential); }; await HandleRequest(doDelete, requestContext, "HandleDeleteCredentialRequest"); } - private async Task HandleRequest(Func handler, RequestContext requestContext, string requestType) + private async Task DeletePasswordAsync(Credential credential) + { + return await Task.Factory.StartNew(() => + { + Credential.ValidateForLookup(credential); + return credStore.DeletePassword(credential.CredentialId); + }); + } + + private async Task HandleRequest(Func> handler, RequestContext requestContext, string requestType) { Logger.Write(LogLevel.Verbose, requestType); try { - T result = handler(); + T result = await handler(); await requestContext.SendResult(result); } catch (Exception ex) diff --git a/src/Microsoft.SqlTools.ServiceLayer/Properties/AssemblyInfo.cs b/src/Microsoft.SqlTools.ServiceLayer/Properties/AssemblyInfo.cs index 83fec0a4..8533036c 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Properties/AssemblyInfo.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Properties/AssemblyInfo.cs @@ -43,3 +43,4 @@ using System.Runtime.InteropServices; [assembly: InternalsVisibleTo("Microsoft.SqlTools.ServiceLayer.Test")] [assembly: InternalsVisibleTo("Microsoft.SqlTools.ServiceLayer.IntegrationTests")] +[assembly: InternalsVisibleTo("Microsoft.SqlTools.ServiceLayer.Test.Common")] diff --git a/test/CodeCoverage/codecoverage.bat b/test/CodeCoverage/codecoverage.bat index 626980df..2dae0247 100644 --- a/test/CodeCoverage/codecoverage.bat +++ b/test/CodeCoverage/codecoverage.bat @@ -18,7 +18,10 @@ dotnet build %WORKINGDIR%..\..\src\Microsoft.SqlTools.ServiceLayer\project.json 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.TestDriver\project.json %DOTNETCONFIG% +dotnet build %WORKINGDIR%..\..\test\Microsoft.SqlTools.ServiceLayer.Tests.Common\project.json %DOTNETCONFIG% dotnet build %WORKINGDIR%..\..\test\Microsoft.SqlTools.ServiceLayer.IntegrationTests\project.json %DOTNETCONFIG% +dotnet build %WORKINGDIR%..\..\test\Microsoft.SqlTools.ServiceLayer.TestDriver.Tests\project.json %DOTNETCONFIG% + SET TEST_SERVER=localhost SET SQLTOOLSSERVICE_EXE=%WORKINGDIR%..\..\src\Microsoft.SqlTools.ServiceLayer\bin\Integration\netcoreapp1.0\win7-x64\Microsoft.SqlTools.ServiceLayer.exe @@ -26,15 +29,15 @@ 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%" +dotnet.exe test %WORKINGDIR%..\Microsoft.SqlTools.ServiceLayer.TestDriver.Tests\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.TestDriver.Tests\project.json %DOTNETCONFIG%" -oldstyle -filter:"+[Microsoft.SqlTools.*]* -[xunit*]* -[Microsoft.SqlTools.ServiceLayer.Test*]*" -output:coverage.xml -searchdirs:%WORKINGDIR%..\Microsoft.SqlTools.ServiceLayer.TestDriver.Tests\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\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*]* -[Microsoft.SqlTools.ServiceLayer.Test*]*" -output:coverage.xml -searchdirs:%WORKINGDIR%..\Microsoft.SqlTools.ServiceLayer.Test\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.IntegrationTests\project.json %DOTNETCONFIG%" -oldstyle -filter:"+[Microsoft.SqlTools.*]* -[xunit*]*" -output:coverage.xml -searchdirs:%WORKINGDIR%..\Microsoft.SqlTools.ServiceLayer.IntegrationTests\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.IntegrationTests\project.json %DOTNETCONFIG%" -oldstyle -filter:"+[Microsoft.SqlTools.*]* -[xunit*]* -[Microsoft.SqlTools.ServiceLayer.Test*]*" -output:coverage.xml -searchdirs:%WORKINGDIR%..\Microsoft.SqlTools.ServiceLayer.IntegrationTests\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\ReportGenerator.2.4.5.0\tools\ReportGenerator.exe" "-reports:coverage.xml" "-targetdir:%WORKINGDIR%\reports" diff --git a/test/CreateConnectionSettings.cmd b/test/CreateConnectionSettings.cmd new file mode 100644 index 00000000..8c90256c --- /dev/null +++ b/test/CreateConnectionSettings.cmd @@ -0,0 +1,15 @@ +echo "mssql.connections": [ { > %USERPROFILE%\settings.json +echo "server": "", >> %USERPROFILE%\settings.json +echo "authenticationType": "SqlLogin", >> %USERPROFILE%\settings.json +echo "user": "", >> %USERPROFILE%\settings.json +echo "password": "", >> %USERPROFILE%\settings.json +echo "serverType": "OnPrem" },{ >> %USERPROFILE%\settings.json +echo "server": "", >> %USERPROFILE%\settings.json +echo "authenticationType": "SqlLogin", >> %USERPROFILE%\settings.json +echo "user": "", >> %USERPROFILE%\settings.json +echo "password": "", >> %USERPROFILE%\settings.json +echo "serverType": "Azure" } >> %USERPROFILE%\settings.json +echo ] >> %USERPROFILE%\settings.json + +SET SettingsFileName=%USERPROFILE%\settings.json +REM The connection setting template is created here: "%USERPROFILE%\settings.json". Make sure to add the connection info before running the tests \ No newline at end of file diff --git a/test/CreateTestServerNameSettings.cmd b/test/CreateTestServerNameSettings.cmd new file mode 100644 index 00000000..b8f22602 --- /dev/null +++ b/test/CreateTestServerNameSettings.cmd @@ -0,0 +1,8 @@ +echo [{ > %USERPROFILE%\testServerNames.json +echo "serverName": "", >> %USERPROFILE%\testServerNames.json +echo "profileName": "", >> %USERPROFILE%\testServerNames.json +echo "serverType": "" >> %USERPROFILE%\testServerNames.json +echo }] >> %USERPROFILE%\testServerNames.json + +SET TestServerNamesFile=%USERPROFILE%\testServerNames.json +REM The server name setting template is created here: "%USERPROFILE%\testServerNames.json". Make sure to add the server names before running the tests \ No newline at end of file diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Connection/ReliableConnectionTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Connection/ReliableConnectionTests.cs index 49ac3e47..bd74e613 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Connection/ReliableConnectionTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Connection/ReliableConnectionTests.cs @@ -9,9 +9,12 @@ using System.Data; using System.Data.Common; using System.Data.SqlClient; using System.Threading; +using System.Threading.Tasks; using Microsoft.SqlTools.ServiceLayer.Connection; +using Microsoft.SqlTools.ServiceLayer.Connection.Contracts; using Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection; using Microsoft.SqlTools.ServiceLayer.QueryExecution; +using Microsoft.SqlTools.ServiceLayer.Test.Common; using Microsoft.SqlTools.ServiceLayer.Test.QueryExecution; using Microsoft.SqlTools.ServiceLayer.Test.Utility; using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts; @@ -30,6 +33,8 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Connection /// public class ReliableConnectionTests { + private TestConnectionProfileService connectionProfileService = new TestConnectionProfileService(); + internal class TestDataTransferErrorDetectionStrategy : DataTransferErrorDetectionStrategy { public bool InvokeCanRetrySqlException(SqlException exception) @@ -230,11 +235,23 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Connection /// /// Helper method to create an integrated auth connection builder for testing. /// - private SqlConnectionStringBuilder CreateTestConnectionStringBuilder() + private async Task CreateTestConnectionStringBuilder() { + ConnectParams connectParams = await this.connectionProfileService.GetConnectionParametersAsync(); SqlConnectionStringBuilder csb = new SqlConnectionStringBuilder(); - csb.DataSource = TestServerName; - csb.IntegratedSecurity = true; + csb.DataSource = connectParams.Connection.ServerName; + csb.IntegratedSecurity = connectParams.Connection.AuthenticationType == AuthenticationType.Integrated.ToString(); + if (connectParams.Connection.UserName != null) + { + csb.UserID = connectParams.Connection.UserName; + } + if (connectParams.Connection.Password != null) + { + csb.Password = connectParams.Connection.Password; + } + csb.ConnectTimeout = connectParams.Connection.ConnectTimeout.HasValue ? connectParams.Connection.ConnectTimeout.Value: 30; + csb.Encrypt = connectParams.Connection.Encrypt.HasValue ? connectParams.Connection.Encrypt.Value : false; + csb.TrustServerCertificate = connectParams.Connection.TrustServerCertificate.HasValue ? connectParams.Connection.TrustServerCertificate.Value : false; return csb; } @@ -242,9 +259,9 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Connection /// /// Helper method to create an integrated auth reliable connection for testing. /// - private DbConnection CreateTestConnection() + private async Task CreateTestConnection() { - SqlConnectionStringBuilder csb = CreateTestConnectionStringBuilder(); + SqlConnectionStringBuilder csb = await CreateTestConnectionStringBuilder(); RetryPolicy connectionRetryPolicy = RetryPolicyFactory.CreateDefaultConnectionRetryPolicy(); RetryPolicy commandRetryPolicy = RetryPolicyFactory.CreateDefaultConnectionRetryPolicy(); @@ -257,64 +274,59 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Connection /// Test ReliableConnectionHelper.GetDefaultDatabaseFilePath() /// [Fact] - public void TestGetDefaultDatabaseFilePath() + public async Task TestGetDefaultDatabaseFilePath() { - TestUtils.RunIfWindows(() => - { - var connectionBuilder = CreateTestConnectionStringBuilder(); - Assert.NotNull(connectionBuilder); - string filePath = string.Empty; - string logPath = string.Empty; + var connectionBuilder = await CreateTestConnectionStringBuilder(); + Assert.NotNull(connectionBuilder); - ReliableConnectionHelper.OpenConnection( - connectionBuilder, - usingConnection: (conn) => - { - filePath = ReliableConnectionHelper.GetDefaultDatabaseFilePath(conn); - logPath = ReliableConnectionHelper.GetDefaultDatabaseLogPath(conn); - }, - catchException: null, - useRetry: false); + string filePath = string.Empty; + string logPath = string.Empty; - Assert.False(string.IsNullOrWhiteSpace(filePath)); - Assert.False(string.IsNullOrWhiteSpace(logPath)); - }); + ReliableConnectionHelper.OpenConnection( + connectionBuilder, + usingConnection: (conn) => + { + filePath = ReliableConnectionHelper.GetDefaultDatabaseFilePath(conn); + logPath = ReliableConnectionHelper.GetDefaultDatabaseLogPath(conn); + }, + catchException: null, + useRetry: false); + + Assert.False(string.IsNullOrWhiteSpace(filePath)); + Assert.False(string.IsNullOrWhiteSpace(logPath)); } /// /// Test ReliableConnectionHelper.GetServerVersion() /// [Fact] - public void TestGetServerVersion() + public async Task TestGetServerVersion() { - TestUtils.RunIfWindows(() => + using (var connection = await CreateTestConnection()) { - using (var connection = CreateTestConnection()) + Assert.NotNull(connection); + connection.Open(); + + ReliableConnectionHelper.ServerInfo serverInfo = ReliableConnectionHelper.GetServerVersion(connection); + ReliableConnectionHelper.ServerInfo serverInfo2; + using (var connection2 = await CreateTestConnection()) { - Assert.NotNull(connection); - connection.Open(); - - ReliableConnectionHelper.ServerInfo serverInfo = ReliableConnectionHelper.GetServerVersion(connection); - ReliableConnectionHelper.ServerInfo serverInfo2; - using (var connection2 = CreateTestConnection()) - { - connection2.Open(); - serverInfo2 = ReliableConnectionHelper.GetServerVersion(connection); - } - - Assert.NotNull(serverInfo); - Assert.NotNull(serverInfo2); - Assert.True(serverInfo.ServerMajorVersion != 0); - Assert.True(serverInfo.ServerMajorVersion == serverInfo2.ServerMajorVersion); - Assert.True(serverInfo.ServerMinorVersion == serverInfo2.ServerMinorVersion); - Assert.True(serverInfo.ServerReleaseVersion == serverInfo2.ServerReleaseVersion); - Assert.True(serverInfo.ServerEdition == serverInfo2.ServerEdition); - Assert.True(serverInfo.IsCloud == serverInfo2.IsCloud); - Assert.True(serverInfo.AzureVersion == serverInfo2.AzureVersion); - Assert.True(serverInfo.IsAzureV1 == serverInfo2.IsAzureV1); + connection2.Open(); + serverInfo2 = ReliableConnectionHelper.GetServerVersion(connection); } - }); + + Assert.NotNull(serverInfo); + Assert.NotNull(serverInfo2); + Assert.True(serverInfo.ServerMajorVersion != 0); + Assert.True(serverInfo.ServerMajorVersion == serverInfo2.ServerMajorVersion); + Assert.True(serverInfo.ServerMinorVersion == serverInfo2.ServerMinorVersion); + Assert.True(serverInfo.ServerReleaseVersion == serverInfo2.ServerReleaseVersion); + Assert.True(serverInfo.ServerEdition == serverInfo2.ServerEdition); + Assert.True(serverInfo.IsCloud == serverInfo2.IsCloud); + Assert.True(serverInfo.AzureVersion == serverInfo2.AzureVersion); + Assert.True(serverInfo.IsAzureV1 == serverInfo2.IsAzureV1); + } } /// @@ -334,9 +346,9 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Connection /// Tests ReliableConnectionHelper.IsDatabaseReadonly() /// [Fact] - public void TestIsDatabaseReadonly() + public async Task TestIsDatabaseReadonly() { - var connectionBuilder = CreateTestConnectionStringBuilder(); + var connectionBuilder = await CreateTestConnectionStringBuilder(); Assert.NotNull(connectionBuilder); bool isReadOnly = ReliableConnectionHelper.IsDatabaseReadonly(connectionBuilder); @@ -350,22 +362,19 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Connection public void TestIsDatabaseReadonlyWithNullBuilder() { Assert.Throws(() => ReliableConnectionHelper.IsDatabaseReadonly(null)); - } + } /// /// Verify ANSI_NULL and QUOTED_IDENTIFIER settings can be set and retrieved for a session /// [Fact] - public void VerifyAnsiNullAndQuotedIdentifierSettingsReplayed() + public async Task VerifyAnsiNullAndQuotedIdentifierSettingsReplayed() { - TestUtils.RunIfWindows(() => + using (ReliableSqlConnection conn = (ReliableSqlConnection) ReliableConnectionHelper.OpenConnection(await CreateTestConnectionStringBuilder(), useRetry: true)) { - using (ReliableSqlConnection conn = (ReliableSqlConnection)ReliableConnectionHelper.OpenConnection(CreateTestConnectionStringBuilder(), useRetry: true)) - { - VerifySessionSettings(conn, true); - VerifySessionSettings(conn, false); - } - }); + VerifySessionSettings(conn, true); + VerifySessionSettings(conn, false); + } } private void VerifySessionSettings(ReliableSqlConnection conn, bool expectedSessionValue) @@ -468,73 +477,62 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Connection /// ReliableConnectionHelper.IsCloud() should be false for a local server /// [Fact] - public void TestIsCloudIsFalseForLocalServer() + public async Task TestIsCloudIsFalseForLocalServer() { - TestUtils.RunIfWindows(() => + using (var connection = await CreateTestConnection()) { - using (var connection = CreateTestConnection()) - { - Assert.NotNull(connection); + Assert.NotNull(connection); - connection.Open(); - Assert.False(ReliableConnectionHelper.IsCloud(connection)); - } - }); + connection.Open(); + Assert.False(ReliableConnectionHelper.IsCloud(connection)); + } } /// /// Tests that ReliableConnectionHelper.OpenConnection() opens a connection if it is closed /// [Fact] - public void TestOpenConnectionOpensConnection() + public async Task TestOpenConnectionOpensConnection() { - TestUtils.RunIfWindows(() => + using (var connection = await CreateTestConnection()) { - using (var connection = CreateTestConnection()) - { - Assert.NotNull(connection); + Assert.NotNull(connection); - Assert.True(connection.State == ConnectionState.Closed); - ReliableConnectionHelper.OpenConnection(connection); - Assert.True(connection.State == ConnectionState.Open); - } - }); + Assert.True(connection.State == ConnectionState.Closed); + ReliableConnectionHelper.OpenConnection(connection); + Assert.True(connection.State == ConnectionState.Open); + } } /// /// Tests that ReliableConnectionHelper.ExecuteNonQuery() runs successfully /// [Fact] - public void TestExecuteNonQuery() + public async Task TestExecuteNonQuery() { - TestUtils.RunIfWindows(() => - { - var result = ReliableConnectionHelper.ExecuteNonQuery( - CreateTestConnectionStringBuilder(), - "SET NOCOUNT ON; SET NOCOUNT OFF;", - ReliableConnectionHelper.SetCommandTimeout, - null, - true + var result = ReliableConnectionHelper.ExecuteNonQuery( + await CreateTestConnectionStringBuilder(), + "SET NOCOUNT ON; SET NOCOUNT OFF;", + ReliableConnectionHelper.SetCommandTimeout, + null, + true ); - Assert.NotNull(result); - }); + Assert.NotNull(result); } /// /// Test that TryGetServerVersion() gets server information /// [Fact] - public void TestTryGetServerVersion() + public async Task TestTryGetServerVersion() { - TestUtils.RunIfWindows(() => - { - ReliableConnectionHelper.ServerInfo info = null; - Assert.True(ReliableConnectionHelper.TryGetServerVersion(CreateTestConnectionStringBuilder().ConnectionString, out info)); + ReliableConnectionHelper.ServerInfo info = null; + var connBuilder = await CreateTestConnectionStringBuilder(); + Assert.True(ReliableConnectionHelper.TryGetServerVersion(connBuilder.ConnectionString, out info)); - Assert.NotNull(info); - Assert.NotNull(info.ServerVersion); - Assert.NotEmpty(info.ServerVersion); - }); + Assert.NotNull(info); + Assert.NotNull(info.ServerVersion); + Assert.NotEmpty(info.ServerVersion); } /// @@ -683,10 +681,10 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Connection } [Fact] - public void ReliableConnectionHelperTest() + public async Task ReliableConnectionHelperTest() { - ScriptFile scriptFile; - ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfo(out scriptFile); + var result = await TestObjects.InitLiveConnectionInfo(); + ConnectionInfo connInfo = result.ConnectionInfo; Assert.True(ReliableConnectionHelper.IsAuthenticatingDatabaseMaster(connInfo.SqlConnection)); @@ -699,7 +697,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Connection Assert.NotNull(ReliableConnectionHelper.GetAsSqlConnection(connInfo.SqlConnection)); - ServerInfo info = ReliableConnectionHelper.GetServerVersion(connInfo.SqlConnection); + ReliableConnectionHelper.ServerInfo info = ReliableConnectionHelper.GetServerVersion(connInfo.SqlConnection); Assert.NotNull(ReliableConnectionHelper.IsVersionGreaterThan2012RTM(info)); } @@ -726,10 +724,10 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Connection } [Fact] - public void InitReliableSqlConnectionTest() + public async Task InitReliableSqlConnectionTest() { - ScriptFile scriptFile; - ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfo(out scriptFile); + var result = await TestObjects.InitLiveConnectionInfo(); + ConnectionInfo connInfo = result.ConnectionInfo; var connection = connInfo.SqlConnection as ReliableSqlConnection; var command = new ReliableSqlConnection.ReliableSqlCommand(connection); @@ -742,10 +740,10 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Connection Assert.True(connection.ConnectionTimeout > 0); connection.ClearPool(); } - + [Fact] public void ThrottlingReasonTests() - { + { var reason = RetryPolicy.ThrottlingReason.Unknown; Assert.NotNull(reason.ThrottlingMode); Assert.NotNull(reason.ThrottledResources); diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/LanguageServer/LanguageServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/LanguageServer/LanguageServiceTests.cs index 27000d83..6a29b635 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/LanguageServer/LanguageServiceTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/LanguageServer/LanguageServiceTests.cs @@ -3,11 +3,13 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +using System.Threading.Tasks; using Microsoft.SqlServer.Management.SqlParser.Parser; using Microsoft.SqlTools.ServiceLayer.Connection; using Microsoft.SqlTools.ServiceLayer.LanguageServices; using Microsoft.SqlTools.ServiceLayer.LanguageServices.Completion; using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts; +using Microsoft.SqlTools.ServiceLayer.Test.Common; using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts; using Microsoft.SqlTools.Test.Utility; using Xunit; @@ -19,12 +21,9 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServer /// public class LanguageServiceTests { - private static void GetLiveAutoCompleteTestObjects( - out TextDocumentPosition textDocument, - out ScriptFile scriptFile, - out ConnectionInfo connInfo) + private async static Task GetLiveAutoCompleteTestObjects() { - textDocument = new TextDocumentPosition + var textDocument = new TextDocumentPosition { TextDocument = new TextDocumentIdentifier { Uri = TestObjects.ScriptUri }, Position = new Position @@ -34,7 +33,9 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServer } }; - connInfo = TestObjects.InitLiveConnectionInfo(out scriptFile); + var result = await TestObjects.InitLiveConnectionInfo(); + result.TextDocumentPosition = textDocument; + return result; } /// @@ -45,7 +46,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServer { try { - TestObjects.InitializeTestServices(); + TestServiceProvider.InitializeTestServices(); } catch (System.ArgumentException) { @@ -61,10 +62,10 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServer /// Test the service initialization code path and verify nothing throws /// [Fact] - public void PrepopulateCommonMetadata() + public async Task PrepopulateCommonMetadata() { - ScriptFile scriptFile; - ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfo(out scriptFile); + var result = await TestObjects.InitLiveConnectionInfo(); + var connInfo = result.ConnectionInfo; ScriptParseInfo scriptInfo = new ScriptParseInfo { IsConnected = true }; @@ -75,21 +76,18 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServer // SMO connected metadata provider. Since we don't want a live DB dependency // in the CI unit tests this scenario is currently disabled. [Fact] - public void AutoCompleteFindCompletions() + public async Task AutoCompleteFindCompletions() { - TextDocumentPosition textDocument; - ConnectionInfo connInfo; - ScriptFile scriptFile; - GetLiveAutoCompleteTestObjects(out textDocument, out scriptFile, out connInfo); + var result = await GetLiveAutoCompleteTestObjects(); - textDocument.Position.Character = 7; - scriptFile.Contents = "select "; + result.TextDocumentPosition.Position.Character = 7; + result.ScriptFile.Contents = "select "; var autoCompleteService = LanguageService.Instance; var completions = autoCompleteService.GetCompletionItems( - textDocument, - scriptFile, - connInfo); + result.TextDocumentPosition, + result.ScriptFile, + result.ConnectionInfo); Assert.True(completions.Length > 0); } @@ -100,21 +98,20 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServer /// provide signature help. /// [Fact] - public async void GetSignatureHelpReturnsNotNullIfParseInfoInitialized() + public async Task GetSignatureHelpReturnsNotNullIfParseInfoInitialized() { // When we make a connection to a live database - ScriptFile scriptFile; Hosting.ServiceHost.SendEventIgnoreExceptions = true; - ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfo(out scriptFile); + var result = await TestObjects.InitLiveConnectionInfo(); // And we place the cursor after a function that should prompt for signature help string queryWithFunction = "EXEC sys.fn_isrolemember "; - scriptFile.Contents = queryWithFunction; + result.ScriptFile.Contents = queryWithFunction; TextDocumentPosition textDocument = new TextDocumentPosition { TextDocument = new TextDocumentIdentifier { - Uri = scriptFile.ClientFilePath + Uri = result.ScriptFile.ClientFilePath }, Position = new Position { @@ -125,14 +122,14 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServer // If the SQL has already been parsed var service = LanguageService.Instance; - await service.UpdateLanguageServiceOnConnection(connInfo); + await service.UpdateLanguageServiceOnConnection(result.ConnectionInfo); // We should get back a non-null ScriptParseInfo - ScriptParseInfo parseInfo = service.GetScriptParseInfo(scriptFile.ClientFilePath); + ScriptParseInfo parseInfo = service.GetScriptParseInfo(result.ScriptFile.ClientFilePath); Assert.NotNull(parseInfo); // And we should get back a non-null SignatureHelp - SignatureHelp signatureHelp = service.GetSignatureHelp(textDocument, scriptFile); + SignatureHelp signatureHelp = service.GetSignatureHelp(textDocument, result.ScriptFile); Assert.NotNull(signatureHelp); } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/LanguageServer/PeekDefinitionTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/LanguageServer/PeekDefinitionTests.cs index 79030d22..d3113b86 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/LanguageServer/PeekDefinitionTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/LanguageServer/PeekDefinitionTests.cs @@ -35,32 +35,16 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServices /// public class PeekDefinitionTests { - private const int TaskTimeout = 30000; - - private readonly string testScriptUri = TestObjects.ScriptUri; - - private readonly string testConnectionKey = "testdbcontextkey"; - - private Mock bindingQueue; - - private Mock> workspaceService; - - private Mock> requestContext; - - private Mock binder; - - private TextDocumentPosition textDocument; - private const string OwnerUri = "testFile1"; /// /// Test get definition for a table object with active connection /// [Fact] - public void GetValidTableDefinitionTest() + public async Task GetValidTableDefinitionTest() { // Get live connectionInfo and serverConnection - ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfoForDefinition(); + ConnectionInfo connInfo = await TestObjects.InitLiveConnectionInfoForDefinition(); ServerConnection serverConnection = TestObjects.InitLiveServerConnectionForDefinition(connInfo); PeekDefinition peekDefinition = new PeekDefinition(serverConnection, connInfo); @@ -79,10 +63,10 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServices /// Test get definition for a invalid table object with active connection /// [Fact] - public void GetTableDefinitionInvalidObjectTest() + public async Task GetTableDefinitionInvalidObjectTest() { // Get live connectionInfo and serverConnection - ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfoForDefinition(); + ConnectionInfo connInfo = await TestObjects.InitLiveConnectionInfoForDefinition(); ServerConnection serverConnection = TestObjects.InitLiveServerConnectionForDefinition(connInfo); PeekDefinition peekDefinition = new PeekDefinition(serverConnection, connInfo); @@ -99,10 +83,10 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServices /// Test get definition for a valid table object with schema and active connection /// [Fact] - public void GetTableDefinitionWithSchemaTest() + public async Task GetTableDefinitionWithSchemaTest() { // Get live connectionInfo and serverConnection - ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfoForDefinition(); + ConnectionInfo connInfo = await TestObjects.InitLiveConnectionInfoForDefinition(); ServerConnection serverConnection = TestObjects.InitLiveServerConnectionForDefinition(connInfo); PeekDefinition peekDefinition = new PeekDefinition(serverConnection, connInfo); @@ -121,9 +105,8 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServices /// Test GetDefinition with an unsupported type(schema - dbo). Expect a error result. /// [Fact] - public void GetUnsupportedDefinitionErrorTest() + public async Task GetUnsupportedDefinitionErrorTest() { - ScriptFile scriptFile; TextDocumentPosition textDocument = new TextDocumentPosition { TextDocument = new TextDocumentIdentifier { Uri = OwnerUri }, @@ -134,14 +117,14 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServices Character = 16 } }; - ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfo(out scriptFile); - scriptFile.Contents = "select * from dbo.func ()"; + TestConnectionResult connectionResult = await TestObjects.InitLiveConnectionInfo(); + connectionResult.ScriptFile.Contents = "select * from dbo.func ()"; var languageService = new LanguageService(); ScriptParseInfo scriptInfo = new ScriptParseInfo { IsConnected = true }; languageService.ScriptParseInfoMap.Add(OwnerUri, scriptInfo); // When I call the language service - var result = languageService.GetDefinition(textDocument, scriptFile, connInfo); + var result = languageService.GetDefinition(textDocument, connectionResult.ScriptFile, connectionResult.ConnectionInfo); // Then I expect null locations and an error to be reported Assert.NotNull(result); @@ -152,9 +135,9 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServices /// Get Definition for a object with no definition. Expect a error result /// [Fact] - public void GetDefinitionWithNoResultsFoundError() + public async Task GetDefinitionWithNoResultsFoundError() { - ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfoForDefinition(); + ConnectionInfo connInfo = await TestObjects.InitLiveConnectionInfoForDefinition(); ServerConnection serverConnection = TestObjects.InitLiveServerConnectionForDefinition(connInfo); PeekDefinition peekDefinition = new PeekDefinition(serverConnection, connInfo); @@ -172,7 +155,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServices /// Test GetDefinition with a forced timeout. Expect a error result. /// [Fact] - public void GetDefinitionTimeoutTest() + public async Task GetDefinitionTimeoutTest() { // Given a binding queue that will automatically time out var languageService = new LanguageService(); @@ -198,7 +181,6 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServices }) .Returns(() => itemMock.Object); - ScriptFile scriptFile; TextDocumentPosition textDocument = new TextDocumentPosition { TextDocument = new TextDocumentIdentifier { Uri = OwnerUri }, @@ -208,7 +190,9 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServices Character = 20 } }; - ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfo(out scriptFile); + TestConnectionResult connectionResult = await TestObjects.InitLiveConnectionInfo(); + ScriptFile scriptFile = connectionResult.ScriptFile; + ConnectionInfo connInfo = connectionResult.ConnectionInfo; scriptFile.Contents = "select * from dbo.func ()"; ScriptParseInfo scriptInfo = new ScriptParseInfo { IsConnected = true }; @@ -228,9 +212,9 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServices /// Test get definition for a view object with active connection /// [Fact] - public void GetValidViewDefinitionTest() + public async Task GetValidViewDefinitionTest() { - ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfoForDefinition(); + ConnectionInfo connInfo = await TestObjects.InitLiveConnectionInfoForDefinition(); ServerConnection serverConnection = TestObjects.InitLiveServerConnectionForDefinition(connInfo); PeekDefinition peekDefinition = new PeekDefinition(serverConnection, connInfo); @@ -247,10 +231,10 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServices /// Test get definition for an invalid view object with no schema name and with active connection /// [Fact] - public void GetViewDefinitionInvalidObjectTest() + public async Task GetViewDefinitionInvalidObjectTest() { // Get live connectionInfo and serverConnection - ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfoForDefinition(); + ConnectionInfo connInfo = await TestObjects.InitLiveConnectionInfoForDefinition(); ServerConnection serverConnection = TestObjects.InitLiveServerConnectionForDefinition(connInfo); PeekDefinition peekDefinition = new PeekDefinition(serverConnection, connInfo); @@ -266,10 +250,10 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServices /// Test get definition for a stored procedure object with active connection /// [Fact] - public void GetStoredProcedureDefinitionTest() + public async Task GetStoredProcedureDefinitionTest() { // Get live connectionInfo and serverConnection - ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfoForDefinition(); + ConnectionInfo connInfo = await TestObjects.InitLiveConnectionInfoForDefinition(); ServerConnection serverConnection = TestObjects.InitLiveServerConnectionForDefinition(connInfo); PeekDefinition peekDefinition = new PeekDefinition(serverConnection, connInfo); @@ -287,10 +271,10 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServices /// Test get definition for a stored procedure object that does not exist with active connection /// [Fact] - public void GetStoredProcedureDefinitionFailureTest() + public async Task GetStoredProcedureDefinitionFailureTest() { // Get live connectionInfo and serverConnection - ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfoForDefinition(); + ConnectionInfo connInfo = await TestObjects.InitLiveConnectionInfoForDefinition(); ServerConnection serverConnection = TestObjects.InitLiveServerConnectionForDefinition(connInfo); PeekDefinition peekDefinition = new PeekDefinition(serverConnection, connInfo); @@ -306,10 +290,10 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServices /// Test get definition for a stored procedure object with active connection and no schema /// [Fact] - public void GetStoredProcedureDefinitionWithoutSchemaTest() + public async Task GetStoredProcedureDefinitionWithoutSchemaTest() { // Get live connectionInfo and serverConnection - ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfoForDefinition(); + ConnectionInfo connInfo = await TestObjects.InitLiveConnectionInfoForDefinition(); ServerConnection serverConnection = TestObjects.InitLiveServerConnectionForDefinition(connInfo); PeekDefinition peekDefinition = new PeekDefinition(serverConnection, connInfo); diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/QueryExecution/DataStorage/StorageDataReaderTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/QueryExecution/DataStorage/StorageDataReaderTests.cs index b139e180..4bb145a6 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/QueryExecution/DataStorage/StorageDataReaderTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/QueryExecution/DataStorage/StorageDataReaderTests.cs @@ -5,6 +5,7 @@ using System; using System.Data.Common; +using System.Threading.Tasks; using Microsoft.SqlTools.ServiceLayer.Connection; using Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage; using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts; @@ -15,14 +16,13 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.QueryExecution.DataSt { public class StorageDataReaderTests { - private StorageDataReader GetTestStorageDataReader(out DbDataReader reader, string query) + private async Task GetTestStorageDataReader(string query) { - ScriptFile scriptFile; - ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfo(out scriptFile); + var result = await TestObjects.InitLiveConnectionInfo(); - var command = connInfo.SqlConnection.CreateCommand(); + var command = result.ConnectionInfo.SqlConnection.CreateCommand(); command.CommandText = query; - reader = command.ExecuteReader(); + DbDataReader reader = command.ExecuteReader(); return new StorageDataReader(reader); } @@ -31,12 +31,11 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.QueryExecution.DataSt /// Validate GetBytesWithMaxCapacity /// [Fact] - public void GetBytesWithMaxCapacityTest() + public async Task GetBytesWithMaxCapacityTest() { - DbDataReader reader; - var storageReader = GetTestStorageDataReader( - out reader, + var storageReader = await GetTestStorageDataReader( "SELECT CAST([name] as TEXT) As TextName FROM sys.all_columns"); + DbDataReader reader = storageReader.DbDataReader; reader.Read(); Assert.False(storageReader.IsDBNull(0)); @@ -49,12 +48,11 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.QueryExecution.DataSt /// Validate GetCharsWithMaxCapacity /// [Fact] - public void GetCharsWithMaxCapacityTest() + public async Task GetCharsWithMaxCapacityTest() { - DbDataReader reader; - var storageReader = GetTestStorageDataReader( - out reader, + var storageReader = await GetTestStorageDataReader( "SELECT name FROM sys.all_columns"); + DbDataReader reader = storageReader.DbDataReader; reader.Read(); Assert.False(storageReader.IsDBNull(0)); @@ -72,12 +70,11 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.QueryExecution.DataSt /// Validate GetXmlWithMaxCapacity /// [Fact] - public void GetXmlWithMaxCapacityTest() + public async Task GetXmlWithMaxCapacityTest() { - DbDataReader reader; - var storageReader = GetTestStorageDataReader( - out reader, + var storageReader = await GetTestStorageDataReader( "SELECT CAST('Test XML context' AS XML) As XmlColumn"); + DbDataReader reader = storageReader.DbDataReader; reader.Read(); Assert.False(storageReader.IsDBNull(0)); diff --git a/test/Microsoft.SqlTools.ServiceLayer.PerfTests/CreateTestDbAttribute.cs b/test/Microsoft.SqlTools.ServiceLayer.PerfTests/CreateTestDbAttribute.cs index 2b705918..cb3ca53f 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.PerfTests/CreateTestDbAttribute.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.PerfTests/CreateTestDbAttribute.cs @@ -5,7 +5,7 @@ using System.Reflection; using System.Threading.Tasks; -using Microsoft.SqlTools.ServiceLayer.TestDriver.Utility; +using Microsoft.SqlTools.ServiceLayer.Test.Common; using Xunit.Sdk; namespace Microsoft.SqlTools.ServiceLayer.PerfTests @@ -28,7 +28,7 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests public TestServerType ServerType { get; set; } public override void Before(MethodInfo methodUnderTest) { - Task task = Common.CreateTestDatabase(ServerType); + Task task = SqlTestDb.CreateNew(ServerType, doNotCleanupDb: true, databaseName: Common.PerfTestDatabaseName, query: Scripts.CreateDatabaseObjectsQuery); task.Wait(); } diff --git a/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/Common.cs b/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/Common.cs index 7b8c8985..03457cad 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/Common.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/Common.cs @@ -3,109 +3,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using System; -using System.Globalization; -using System.Runtime.CompilerServices; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.SqlTools.ServiceLayer.TestDriver.Scripts; -using Microsoft.SqlTools.ServiceLayer.TestDriver.Tests; -using Microsoft.SqlTools.ServiceLayer.TestDriver.Utility; -using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts; -using Xunit; - namespace Microsoft.SqlTools.ServiceLayer.PerfTests { public class Common { public const string PerfTestDatabaseName = "SQLToolsCrossPlatPerfTestDb"; - public const string MasterDatabaseName = "master"; - - - internal static async Task ExecuteWithTimeout(TestTimer timer, int timeout, Func> repeatedCode, - TimeSpan? delay = null, [CallerMemberName] string testName = "") - { - while (true) - { - if (await repeatedCode()) - { - timer.EndAndPrint(testName); - break; - } - if (timer.TotalMilliSecondsUntilNow >= timeout) - { - Assert.True(false, $"{testName} timed out after {timeout} milliseconds"); - break; - } - if (delay.HasValue) - { - await Task.Delay(delay.Value); - } - } - } - - internal static async Task ConnectAsync(TestHelper testHelper, TestServerType serverType, string query, string ownerUri, string databaseName) - { - testHelper.WriteToFile(ownerUri, query); - - DidOpenTextDocumentNotification openParams = new DidOpenTextDocumentNotification - { - TextDocument = new TextDocumentItem - { - Uri = ownerUri, - LanguageId = "enu", - Version = 1, - Text = query - } - }; - - await testHelper.RequestOpenDocumentNotification(openParams); - - Thread.Sleep(500); - var connectParams = await testHelper.GetDatabaseConnectionAsync(serverType, databaseName); - - bool connected = await testHelper.Connect(ownerUri, connectParams); - Assert.True(connected, "Connection is successful"); - Console.WriteLine($"Connection to {connectParams.Connection.ServerName} is successful"); - - return connected; - } - - internal static async Task CalculateRunTime(Func> testToRun, bool printResult, [CallerMemberName] string testName = "") - { - TestTimer timer = new TestTimer() { PrintResult = printResult }; - T result = await testToRun(); - timer.EndAndPrint(testName); - - return result; - } - - /// - /// Create the test db if not already exists - /// - internal static async Task CreateTestDatabase(TestServerType serverType) - { - using (TestHelper testHelper = new TestHelper()) - using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - { - string databaseName = Common.PerfTestDatabaseName; - string createDatabaseQuery = Scripts.CreateDatabaseQuery.Replace("#DatabaseName#", databaseName); - await RunQuery(testHelper, serverType, Common.MasterDatabaseName, createDatabaseQuery); - Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Verified test database '{0}' is created", databaseName)); - await RunQuery(testHelper, serverType, databaseName, Scripts.CreateDatabaseObjectsQuery); - Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Verified test database '{0}' SQL types are created", databaseName)); - } - } - - internal static async Task RunQuery(TestHelper testHelper, TestServerType serverType, string databaseName, string query) - { - using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - { - await Common.ConnectAsync(testHelper, serverType, query, queryTempFile.FilePath, databaseName); - var queryResult = await Common.CalculateRunTime(() => testHelper.RunQuery(queryTempFile.FilePath, query, 50000), false); - - await testHelper.Disconnect(queryTempFile.FilePath); - } - } } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/ConnectionTests.cs b/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/ConnectionTests.cs index 44cc0be7..7b0dfbdf 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/ConnectionTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/ConnectionTests.cs @@ -5,9 +5,7 @@ using System.Threading; using System.Threading.Tasks; -using Microsoft.SqlTools.ServiceLayer.TestDriver.Scripts; -using Microsoft.SqlTools.ServiceLayer.TestDriver.Tests; -using Microsoft.SqlTools.ServiceLayer.TestDriver.Utility; +using Microsoft.SqlTools.ServiceLayer.Test.Common; using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts; using Xunit; @@ -22,10 +20,10 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests { TestServerType serverType = TestServerType.Azure; using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { const string query = Scripts.TestDbSimpleSelectQuery; - testHelper.WriteToFile(queryTempFile.FilePath, query); + testService.WriteToFile(queryTempFile.FilePath, query); DidOpenTextDocumentNotification openParams = new DidOpenTextDocumentNotification { @@ -38,13 +36,13 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests } }; - await testHelper.RequestOpenDocumentNotification(openParams); + await testService.RequestOpenDocumentNotification(openParams); Thread.Sleep(500); - var connected = await Common.CalculateRunTime(async () => + var connected = await testService.CalculateRunTime(async () => { - var connectParams = await testHelper.GetDatabaseConnectionAsync(serverType, Common.PerfTestDatabaseName); - return await testHelper.Connect(queryTempFile.FilePath, connectParams); + var connectParams = await testService.GetConnectionParametersAsync(serverType, Common.PerfTestDatabaseName); + return await testService.Connect(queryTempFile.FilePath, connectParams); }, true); Assert.True(connected, "Connection was not successful"); } @@ -57,10 +55,10 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests TestServerType serverType = TestServerType.OnPrem; using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { const string query = Scripts.TestDbSimpleSelectQuery; - testHelper.WriteToFile(queryTempFile.FilePath, query); + testService.WriteToFile(queryTempFile.FilePath, query); DidOpenTextDocumentNotification openParams = new DidOpenTextDocumentNotification { @@ -73,13 +71,13 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests } }; - await testHelper.RequestOpenDocumentNotification(openParams); + await testService.RequestOpenDocumentNotification(openParams); Thread.Sleep(500); - var connected = await Common.CalculateRunTime(async () => + var connected = await testService.CalculateRunTime(async () => { - var connectParams = await testHelper.GetDatabaseConnectionAsync(serverType, Common.PerfTestDatabaseName); - return await testHelper.Connect(queryTempFile.FilePath, connectParams); + var connectParams = await testService.GetConnectionParametersAsync(serverType, Common.PerfTestDatabaseName); + return await testService.Connect(queryTempFile.FilePath, connectParams); }, true); Assert.True(connected, "Connection was not successful"); } @@ -92,11 +90,11 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests TestServerType serverType = TestServerType.OnPrem; using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { - await Common.ConnectAsync(testHelper, serverType, Scripts.TestDbSimpleSelectQuery, queryTempFile.FilePath, Common.PerfTestDatabaseName); + await testService.ConnectForQuery(serverType, Scripts.TestDbSimpleSelectQuery, queryTempFile.FilePath, Common.PerfTestDatabaseName); Thread.Sleep(1000); - var connected = await Common.CalculateRunTime(() => testHelper.Disconnect(queryTempFile.FilePath), true); + var connected = await testService.CalculateRunTime(() => testService.Disconnect(queryTempFile.FilePath), true); Assert.True(connected); } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/IntellisenseTests.cs b/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/IntellisenseTests.cs index 3f84df16..b5173643 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/IntellisenseTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/IntellisenseTests.cs @@ -9,9 +9,7 @@ using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts; -using Microsoft.SqlTools.ServiceLayer.TestDriver.Scripts; -using Microsoft.SqlTools.ServiceLayer.TestDriver.Tests; -using Microsoft.SqlTools.ServiceLayer.TestDriver.Utility; +using Microsoft.SqlTools.ServiceLayer.Test.Common; using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts; using Xunit; @@ -24,14 +22,14 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests public async Task HoverTestOnPrem() { TestServerType serverType = TestServerType.OnPrem; - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) { const string query = Scripts.TestDbSimpleSelectQuery; - await Common.ConnectAsync(testHelper, serverType, query, queryTempFile.FilePath, Common.PerfTestDatabaseName); - Hover hover = await Common.CalculateRunTime(() => testHelper.RequestHover(queryTempFile.FilePath, query, 0, Scripts.TestDbComplexSelectQueries.Length + 1), true); + await testService.ConnectForQuery(serverType, query, queryTempFile.FilePath, Common.PerfTestDatabaseName); + Hover hover = await testService.CalculateRunTime(() => testService.RequestHover(queryTempFile.FilePath, query, 0, Scripts.TestDbComplexSelectQueries.Length + 1), true); Assert.NotNull(hover); - await testHelper.Disconnect(queryTempFile.FilePath); + await testService.Disconnect(queryTempFile.FilePath); } } @@ -40,14 +38,14 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests public async Task SuggestionsTest() { TestServerType serverType = TestServerType.OnPrem; - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) { const string query = Scripts.TestDbSimpleSelectQuery; - await Common.ConnectAsync(testHelper, serverType, query, queryTempFile.FilePath, Common.PerfTestDatabaseName); - await ValidateCompletionResponse(testHelper, queryTempFile.FilePath, false, Common.PerfTestDatabaseName, true); - await ValidateCompletionResponse(testHelper, queryTempFile.FilePath, true, Common.PerfTestDatabaseName, false); - await testHelper.Disconnect(queryTempFile.FilePath); + await testService.ConnectForQuery(serverType, query, queryTempFile.FilePath, Common.PerfTestDatabaseName); + await ValidateCompletionResponse(testService, queryTempFile.FilePath, false, Common.PerfTestDatabaseName, true); + await ValidateCompletionResponse(testService, queryTempFile.FilePath, true, Common.PerfTestDatabaseName, false); + await testService.Disconnect(queryTempFile.FilePath); } } @@ -56,12 +54,12 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests public async Task DiagnosticsTests() { TestServerType serverType = TestServerType.OnPrem; - await Common.CreateTestDatabase(serverType); + await SqlTestDb.CreateNew(serverType, doNotCleanupDb: true, databaseName: Common.PerfTestDatabaseName, query: Scripts.CreateDatabaseObjectsQuery); - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) { - await Common.ConnectAsync(testHelper, serverType, Scripts.TestDbSimpleSelectQuery, queryTempFile.FilePath, Common.PerfTestDatabaseName); + await testService.ConnectForQuery(serverType, Scripts.TestDbSimpleSelectQuery, queryTempFile.FilePath, Common.PerfTestDatabaseName); Thread.Sleep(500); var contentChanges = new TextDocumentChangeEvent[1]; @@ -94,13 +92,13 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests }; TestTimer timer = new TestTimer() { PrintResult = true }; - await testHelper.RequestChangeTextDocumentNotification(changeParams); - await Common.ExecuteWithTimeout(timer, 60000, async () => + await testService.RequestChangeTextDocumentNotification(changeParams); + await testService.ExecuteWithTimeout(timer, 60000, async () => { - var completeEvent = await testHelper.Driver.WaitForEvent(PublishDiagnosticsNotification.Type, 15000); + var completeEvent = await testService.Driver.WaitForEvent(PublishDiagnosticsNotification.Type, 15000); return completeEvent?.Diagnostics != null && completeEvent.Diagnostics.Length > 0; }); - await testHelper.Disconnect(queryTempFile.FilePath); + await testService.Disconnect(queryTempFile.FilePath); } } @@ -109,9 +107,9 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests public async Task BindingCacheColdAzureSimpleQuery() { TestServerType serverType = TestServerType.Azure; - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { - await VerifyBindingLoadScenario(testHelper, serverType, Scripts.TestDbSimpleSelectQuery, false); + await VerifyBindingLoadScenario(testService, serverType, Scripts.TestDbSimpleSelectQuery, false); } } @@ -120,9 +118,9 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests public async Task BindingCacheColdOnPremSimpleQuery() { TestServerType serverType = TestServerType.OnPrem; - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { - await VerifyBindingLoadScenario(testHelper, serverType, Scripts.TestDbSimpleSelectQuery, false); + await VerifyBindingLoadScenario(testService, serverType, Scripts.TestDbSimpleSelectQuery, false); } } @@ -132,11 +130,11 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests public async Task BindingCacheWarmAzureSimpleQuery() { TestServerType serverType = TestServerType.Azure; - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) { const string query = Scripts.TestDbSimpleSelectQuery; - await VerifyBindingLoadScenario(testHelper, serverType, query, true); + await VerifyBindingLoadScenario(testService, serverType, query, true); } } @@ -146,11 +144,11 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests { TestServerType serverType = TestServerType.OnPrem; - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) { const string query = Scripts.TestDbSimpleSelectQuery; - await VerifyBindingLoadScenario(testHelper, serverType, query, true); + await VerifyBindingLoadScenario(testService, serverType, query, true); } } @@ -160,9 +158,9 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests { TestServerType serverType = TestServerType.Azure; - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { - await VerifyBindingLoadScenario(testHelper, serverType, Scripts.TestDbComplexSelectQueries,false); + await VerifyBindingLoadScenario(testService, serverType, Scripts.TestDbComplexSelectQueries,false); } } @@ -171,9 +169,9 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests public async Task BindingCacheColdOnPremComplexQuery() { TestServerType serverType = TestServerType.OnPrem; - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { - await VerifyBindingLoadScenario(testHelper, serverType, Scripts.TestDbComplexSelectQueries, false); + await VerifyBindingLoadScenario(testService, serverType, Scripts.TestDbComplexSelectQueries, false); } } @@ -182,11 +180,11 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests public async Task BindingCacheWarmAzureComplexQuery() { using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { string query = Scripts.TestDbComplexSelectQueries; const TestServerType serverType = TestServerType.Azure; - await VerifyBindingLoadScenario(testHelper, serverType, query, true); + await VerifyBindingLoadScenario(testService, serverType, query, true); } } @@ -195,18 +193,18 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests public async Task BindingCacheWarmOnPremComplexQuery() { using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { string query = Scripts.TestDbComplexSelectQueries; const TestServerType serverType = TestServerType.OnPrem; - await VerifyBindingLoadScenario(testHelper, serverType, query, true); + await VerifyBindingLoadScenario(testService, serverType, query, true); } } #region Private Helper Methods private async Task VerifyBindingLoadScenario( - TestHelper testHelper, + TestServiceDriverProvider testService, TestServerType serverType, string query, bool preLoad, @@ -215,16 +213,16 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests string databaseName = Common.PerfTestDatabaseName; if (preLoad) { - await VerifyCompletationLoaded(testHelper, serverType, Scripts.TestDbSimpleSelectQuery, + await VerifyCompletationLoaded(testService, serverType, Scripts.TestDbSimpleSelectQuery, databaseName, printResult: false, testName: testName); Console.WriteLine("Intellisense cache loaded."); } - await VerifyCompletationLoaded(testHelper, serverType, query, databaseName, + await VerifyCompletationLoaded(testService, serverType, query, databaseName, printResult: true, testName: testName); } private async Task VerifyCompletationLoaded( - TestHelper testHelper, + TestServiceDriverProvider testService, TestServerType serverType, string query, string databaseName, @@ -233,16 +231,16 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests { using (SelfCleaningTempFile testTempFile = new SelfCleaningTempFile()) { - testHelper.WriteToFile(testTempFile.FilePath, query); - await Common.ConnectAsync(testHelper, serverType, query, testTempFile.FilePath, databaseName); - await ValidateCompletionResponse(testHelper, testTempFile.FilePath, printResult, databaseName, + testService.WriteToFile(testTempFile.FilePath, query); + await testService.ConnectForQuery(serverType, query, testTempFile.FilePath, databaseName); + await ValidateCompletionResponse(testService, testTempFile.FilePath, printResult, databaseName, waitForIntelliSense: true, testName: testName); - await testHelper.Disconnect(testTempFile.FilePath); + await testService.Disconnect(testTempFile.FilePath); } } private static async Task ValidateCompletionResponse( - TestHelper testHelper, + TestServiceDriverProvider testService, string ownerUri, bool printResult, string databaseName, @@ -251,12 +249,12 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests { TestTimer timer = new TestTimer() { PrintResult = printResult }; bool isReady = !waitForIntelliSense; - await Common.ExecuteWithTimeout(timer, 150000, async () => + await testService.ExecuteWithTimeout(timer, 150000, async () => { if (isReady) { string query = Scripts.SelectQuery; - CompletionItem[] completions = await testHelper.RequestCompletion(ownerUri, query, 0, query.Length + 1); + CompletionItem[] completions = await testService.RequestCompletion(ownerUri, query, 0, query.Length + 1); return completions != null && (completions.Any(x => string.Compare(x.Label, databaseName, StringComparison.OrdinalIgnoreCase) == 0 || string.Compare(x.Label, $"[{databaseName}]", StringComparison.OrdinalIgnoreCase) == 0 || @@ -264,7 +262,7 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests } else { - var completeEvent = await testHelper.Driver.WaitForEvent(IntelliSenseReadyNotification.Type, 100000); + var completeEvent = await testService.Driver.WaitForEvent(IntelliSenseReadyNotification.Type, 100000); isReady = completeEvent.OwnerUri == ownerUri; if (isReady) { diff --git a/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/QueryExecutionTests.cs b/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/QueryExecutionTests.cs index e5758458..f76780c6 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/QueryExecutionTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/QueryExecutionTests.cs @@ -7,9 +7,7 @@ using System; using System.Linq; using System.Threading.Tasks; using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts; -using Microsoft.SqlTools.ServiceLayer.TestDriver.Scripts; -using Microsoft.SqlTools.ServiceLayer.TestDriver.Tests; -using Microsoft.SqlTools.ServiceLayer.TestDriver.Utility; +using Microsoft.SqlTools.ServiceLayer.Test.Common; using Xunit; namespace Microsoft.SqlTools.ServiceLayer.PerfTests @@ -22,17 +20,17 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests TestServerType serverType = TestServerType.OnPrem; using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { const string query = Scripts.MasterBasicQuery; - await Common.ConnectAsync(testHelper, serverType, query, queryTempFile.FilePath, Common.MasterDatabaseName); - var queryResult = await Common.CalculateRunTime(() => testHelper.RunQuery(queryTempFile.FilePath, query), true); + await testService.ConnectForQuery(serverType, query, queryTempFile.FilePath, SqlTestDb.MasterDatabaseName); + var queryResult = await testService.CalculateRunTime(() => testService.RunQueryAndWaitToComplete(queryTempFile.FilePath, query), true); Assert.NotNull(queryResult); Assert.True(queryResult.BatchSummaries.Any(x => x.ResultSetSummaries.Any(r => r.RowCount > 0))); - await testHelper.Disconnect(queryTempFile.FilePath); + await testService.Disconnect(queryTempFile.FilePath); } } @@ -42,23 +40,23 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests TestServerType serverType = TestServerType.OnPrem; using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { const string query = Scripts.MasterBasicQuery; - await Common.ConnectAsync(testHelper, serverType, query, queryTempFile.FilePath, Common.MasterDatabaseName); + await testService.ConnectForQuery(serverType, query, queryTempFile.FilePath, SqlTestDb.MasterDatabaseName); - var queryResult = await Common.CalculateRunTime(async () => + var queryResult = await testService.CalculateRunTime(async () => { - await testHelper.RunQuery(queryTempFile.FilePath, query); - return await testHelper.ExecuteSubset(queryTempFile.FilePath, 0, 0, 0, 100); + await testService.RunQueryAndWaitToComplete(queryTempFile.FilePath, query); + return await testService.ExecuteSubset(queryTempFile.FilePath, 0, 0, 0, 100); }, true); Assert.NotNull(queryResult); Assert.NotNull(queryResult.ResultSubset); Assert.True(queryResult.ResultSubset.Rows.Any()); - await testHelper.Disconnect(queryTempFile.FilePath); + await testService.Disconnect(queryTempFile.FilePath); } } @@ -69,22 +67,22 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests TestServerType serverType = TestServerType.OnPrem; using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { - await Common.ConnectAsync(testHelper, serverType, Scripts.DelayQuery, queryTempFile.FilePath, Common.PerfTestDatabaseName); + await testService.ConnectForQuery(serverType, Scripts.DelayQuery, queryTempFile.FilePath, Common.PerfTestDatabaseName); var queryParams = new QueryExecuteParams { OwnerUri = queryTempFile.FilePath, QuerySelection = null }; - var result = await testHelper.Driver.SendRequest(QueryExecuteRequest.Type, queryParams); + var result = await testService.Driver.SendRequest(QueryExecuteRequest.Type, queryParams); if (result != null) { TestTimer timer = new TestTimer() { PrintResult = true }; - await Common.ExecuteWithTimeout(timer, 100000, async () => + await testService.ExecuteWithTimeout(timer, 100000, async () => { - var cancelQueryResult = await testHelper.CancelQuery(queryTempFile.FilePath); + var cancelQueryResult = await testService.CancelQuery(queryTempFile.FilePath); return true; }, TimeSpan.FromMilliseconds(10)); } @@ -93,7 +91,7 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests Assert.True(false, "Failed to run the query"); } - await testHelper.Disconnect(queryTempFile.FilePath); + await testService.Disconnect(queryTempFile.FilePath); } } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/SaveResultsTests.cs b/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/SaveResultsTests.cs index 298d325e..6caf02d3 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/SaveResultsTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/SaveResultsTests.cs @@ -4,9 +4,7 @@ // using System.Threading.Tasks; -using Microsoft.SqlTools.ServiceLayer.TestDriver.Scripts; -using Microsoft.SqlTools.ServiceLayer.TestDriver.Tests; -using Microsoft.SqlTools.ServiceLayer.TestDriver.Utility; +using Microsoft.SqlTools.ServiceLayer.Test.Common; using Xunit; namespace Microsoft.SqlTools.ServiceLayer.PerfTests @@ -20,15 +18,15 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) using (SelfCleaningTempFile outputTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { const string query = Scripts.MasterBasicQuery; // Execute a query - await Common.ConnectAsync(testHelper, serverType, query, queryTempFile.FilePath, Common.MasterDatabaseName); - await testHelper.RunQuery(queryTempFile.FilePath, query); - await Common.CalculateRunTime(() => testHelper.SaveAsCsv(queryTempFile.FilePath, outputTempFile.FilePath, 0, 0), true); - await testHelper.Disconnect(queryTempFile.FilePath); + await testService.ConnectForQuery(serverType, query, queryTempFile.FilePath, SqlTestDb.MasterDatabaseName); + await testService.RunQueryAndWaitToComplete(queryTempFile.FilePath, query); + await testService.CalculateRunTime(() => testService.SaveAsCsv(queryTempFile.FilePath, outputTempFile.FilePath, 0, 0), true); + await testService.Disconnect(queryTempFile.FilePath); } } @@ -39,15 +37,15 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) using (SelfCleaningTempFile outputTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { const string query = Scripts.MasterBasicQuery; // Execute a query - await Common.ConnectAsync(testHelper, serverType, query, queryTempFile.FilePath, Common.MasterDatabaseName); - await testHelper.RunQuery(queryTempFile.FilePath, query); - await Common.CalculateRunTime(() => testHelper.SaveAsJson(queryTempFile.FilePath, outputTempFile.FilePath, 0, 0), true); - await testHelper.Disconnect(queryTempFile.FilePath); + await testService.ConnectForQuery(serverType, query, queryTempFile.FilePath, SqlTestDb.MasterDatabaseName); + await testService.RunQueryAndWaitToComplete(queryTempFile.FilePath, query); + await testService.CalculateRunTime(() => testService.SaveAsJson(queryTempFile.FilePath, outputTempFile.FilePath, 0, 0), true); + await testService.Disconnect(queryTempFile.FilePath); } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.PerfTests/project.json b/test/Microsoft.SqlTools.ServiceLayer.PerfTests/project.json index 4eb7c6fd..4a796ee2 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.PerfTests/project.json +++ b/test/Microsoft.SqlTools.ServiceLayer.PerfTests/project.json @@ -11,7 +11,8 @@ "Microsoft.SqlTools.ServiceLayer": { "target": "project" }, - "Microsoft.SqlTools.ServiceLayer.TestDriver": "1.0.0-*" + "Microsoft.SqlTools.ServiceLayer.TestDriver": "1.0.0-*", + "Microsoft.SqlTools.ServiceLayer.Test.Common": "1.0.0-*" }, "testRunner": "xunit", diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Utility/Setting.cs b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/ConnectionSetting.cs similarity index 82% rename from test/Microsoft.SqlTools.ServiceLayer.TestDriver/Utility/Setting.cs rename to test/Microsoft.SqlTools.ServiceLayer.Test.Common/ConnectionSetting.cs index 7da7eecd..f94c9c7b 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Utility/Setting.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/ConnectionSetting.cs @@ -4,28 +4,28 @@ // using System.Collections.Generic; -using System.Linq; using System.Globalization; +using System.Linq; using Newtonsoft.Json; -namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Utility +namespace Microsoft.SqlTools.ServiceLayer.Test.Common { /// /// The model for deserializing settings.json /// - public class Setting + public class ConnectionSetting { [JsonProperty("mssql.connections")] public List Connections { get; set; } - public ConnectionProfile GetConnentProfile(string profilerName, string serverName) + public ConnectionProfile GetConnectionProfile(string profileName, string serverName) { - if (!string.IsNullOrEmpty(profilerName)) + if (!string.IsNullOrEmpty(profileName) && Connections != null) { - var byPrfileName = Connections.FirstOrDefault(x => x.ProfileName == profilerName); - if (byPrfileName != null) + var byProfileName = Connections.FirstOrDefault(x => x.ProfileName == profileName); + if (byProfileName != null) { - return byPrfileName; + return byProfileName; } } return Connections.FirstOrDefault(x => x.ServerName == serverName); @@ -56,6 +56,8 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Utility public TestServerType ServerType { get; set; } + public AuthenticationType AuthenticationType { get; set; } + public string formatCredentialId(string itemType = "Profile") { diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/Microsoft.SqlTools.ServiceLayer.Test.Common.xproj b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/Microsoft.SqlTools.ServiceLayer.Test.Common.xproj new file mode 100644 index 00000000..0f4bdfc9 --- /dev/null +++ b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/Microsoft.SqlTools.ServiceLayer.Test.Common.xproj @@ -0,0 +1,19 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + b6f4bece-82ee-4ab6-99ac-108aee466274 + Microsoft.SqlTools.ServiceLayer.Test.Common + .\obj + .\bin\ + v4.5.2 + + + 2.0 + + + \ No newline at end of file diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Scripts/CreateTestDatabase.sql b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/Scripts/CreateTestDatabase.sql similarity index 100% rename from test/Microsoft.SqlTools.ServiceLayer.TestDriver/Scripts/CreateTestDatabase.sql rename to test/Microsoft.SqlTools.ServiceLayer.Test.Common/Scripts/CreateTestDatabase.sql diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Scripts/CreateTestDatabaseObjects.sql b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/Scripts/CreateTestDatabaseObjects.sql similarity index 100% rename from test/Microsoft.SqlTools.ServiceLayer.TestDriver/Scripts/CreateTestDatabaseObjects.sql rename to test/Microsoft.SqlTools.ServiceLayer.Test.Common/Scripts/CreateTestDatabaseObjects.sql diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Scripts/Scripts.cs b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/Scripts/Scripts.cs similarity index 69% rename from test/Microsoft.SqlTools.ServiceLayer.TestDriver/Scripts/Scripts.cs rename to test/Microsoft.SqlTools.ServiceLayer.Test.Common/Scripts/Scripts.cs index 02aa695e..d5190bb1 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Scripts/Scripts.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/Scripts/Scripts.cs @@ -7,10 +7,12 @@ using System; using System.IO; using System.Reflection; -namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Scripts +namespace Microsoft.SqlTools.ServiceLayer.Test.Common { public class Scripts { + private const string ResourceNameRefix = "Microsoft.SqlTools.ServiceLayer.Test.Common.Scripts."; + public const string MasterBasicQuery = "SELECT * FROM sys.all_columns"; //basic queries should return at least 10000 rows public const string DelayQuery = "WAITFOR DELAY '00:01:00'"; @@ -19,6 +21,24 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Scripts public const string SelectQuery = "SELECT * FROM "; + public const string DropDatabaseIfExist = @" +IF EXISTS (SELECT 1 FROM [sys].[databases] WHERE [name] = '{0}') +BEGIN + ALTER DATABASE [{0}] + SET READ_WRITE; + ALTER DATABASE [{0}] + SET SINGLE_USER WITH ROLLBACK IMMEDIATE; + DROP DATABASE [{0}]; +END +"; + + public const string DropDatabaseIfExistAzure = @" +IF EXISTS (SELECT 1 FROM [sys].[databases] WHERE [name] = '{0}') +BEGIN + DROP DATABASE [{0}]; +END +"; + public static string CreateDatabaseObjectsQuery { get { return CreateDatabaseObjectsQueryInstance.Value; } } public static string CreateDatabaseQuery { get { return CreateDatabaseQueryInstance.Value; } } @@ -27,17 +47,17 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Scripts private static readonly Lazy CreateDatabaseObjectsQueryInstance = new Lazy(() => { - return GetScriptFileContent("Microsoft.SqlTools.ServiceLayer.TestDriver.Scripts.CreateTestDatabaseObjects.sql"); + return GetScriptFileContent(ResourceNameRefix + "CreateTestDatabaseObjects.sql"); }); private static readonly Lazy CreateDatabaseQueryInstance = new Lazy(() => { - return GetScriptFileContent("Microsoft.SqlTools.ServiceLayer.TestDriver.Scripts.CreateTestDatabase.sql"); + return GetScriptFileContent(ResourceNameRefix + "CreateTestDatabase.sql"); }); private static readonly Lazy TestDbSelectQueriesInstance = new Lazy(() => { - return GetScriptFileContent("Microsoft.SqlTools.ServiceLayer.TestDriver.Scripts.TestDbTableQueries.sql"); + return GetScriptFileContent(ResourceNameRefix + "TestDbTableQueries.sql"); }); private static string GetScriptFileContent(string fileName) diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Scripts/TestDbTableQueries.sql b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/Scripts/TestDbTableQueries.sql similarity index 100% rename from test/Microsoft.SqlTools.ServiceLayer.TestDriver/Scripts/TestDbTableQueries.sql rename to test/Microsoft.SqlTools.ServiceLayer.Test.Common/Scripts/TestDbTableQueries.sql diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Utility/SelfCleaningTempFile.cs b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/SelfCleaningTempFile.cs similarity index 94% rename from test/Microsoft.SqlTools.ServiceLayer.TestDriver/Utility/SelfCleaningTempFile.cs rename to test/Microsoft.SqlTools.ServiceLayer.Test.Common/SelfCleaningTempFile.cs index c991e3ff..25cb10fc 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Utility/SelfCleaningTempFile.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/SelfCleaningTempFile.cs @@ -6,7 +6,7 @@ using System; using System.IO; -namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Utility +namespace Microsoft.SqlTools.ServiceLayer.Test.Common { public class SelfCleaningTempFile : IDisposable { diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/SqlTestDb.cs b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/SqlTestDb.cs new file mode 100644 index 00000000..1c6c268f --- /dev/null +++ b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/SqlTestDb.cs @@ -0,0 +1,76 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System; +using System.Globalization; +using System.Threading.Tasks; + +namespace Microsoft.SqlTools.ServiceLayer.Test.Common +{ + /// + /// Creates a new test database + /// + public class SqlTestDb : IDisposable + { + public const string MasterDatabaseName = "master"; + + public string DatabaseName { get; set; } + + public TestServerType ServerType { get; set; } + + public bool DoNotCleanupDb { get; set; } + + /// + /// Create the test db if not already exists + /// + public static async Task CreateNew(TestServerType serverType, bool doNotCleanupDb = false, string databaseName = null, string query = null) + { + SqlTestDb testDb = new SqlTestDb(); + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) + { + databaseName = databaseName ?? GetUniqueDBName(""); + string createDatabaseQuery = Scripts.CreateDatabaseQuery.Replace("#DatabaseName#", databaseName); + await testService.RunQuery(serverType, MasterDatabaseName, createDatabaseQuery); + Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Verified test database '{0}' is created", databaseName)); + if (!string.IsNullOrEmpty(query)) + { + await testService.RunQuery(serverType, databaseName, query); + Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Verified test database '{0}' SQL types are created", databaseName)); + } + testDb.DatabaseName = databaseName; + testDb.ServerType = serverType; + testDb.DoNotCleanupDb = doNotCleanupDb; + } + + return testDb; + } + + /// + /// Returns a mangled name that unique based on Prefix + Machine + Process + /// + /// + /// + public static string GetUniqueDBName(string namePrefix) + { + string safeMachineName = Environment.MachineName.Replace('-', '_'); + return string.Format("{0}_{1}_{2}", + namePrefix, safeMachineName, Guid.NewGuid().ToString().Replace("-", "")); + } + + public void Dispose() + { + if(!DoNotCleanupDb) + { + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) + using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) + { + string dropDatabaseQuery = string.Format(CultureInfo.InvariantCulture, + (ServerType == TestServerType.Azure ? Scripts.DropDatabaseIfExistAzure : Scripts.DropDatabaseIfExist), DatabaseName); + testService.RunQuery(ServerType, MasterDatabaseName, dropDatabaseQuery).Wait(); + } + } + } + } +} diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestConnectionProfileService.cs b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestConnectionProfileService.cs new file mode 100644 index 00000000..13a10b7c --- /dev/null +++ b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestConnectionProfileService.cs @@ -0,0 +1,265 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Threading.Tasks; +using Microsoft.SqlTools.ServiceLayer.Connection.Contracts; +using Microsoft.SqlTools.ServiceLayer.Credentials; +using Microsoft.SqlTools.ServiceLayer.Credentials.Contracts; +using Microsoft.SqlTools.ServiceLayer.TestDriver.Driver; +using Xunit; + +namespace Microsoft.SqlTools.ServiceLayer.Test.Common +{ + /// + /// Service to get connection profiles from the configured settings + /// to get the credentials, test driver will be used if available otherwise the credential service will be called directly + /// + public class TestConnectionProfileService + { + private readonly IEnumerable _testServers = TestServersLazyInstance.Value; + private readonly ConnectionSetting _setting = ConnectionSettingLazyInstance.Value; + private static string _connectionSettingsFilename; + private static ConcurrentDictionary _connectionProfilesCache = new ConcurrentDictionary(); + + public TestConnectionProfileService(ServiceTestDriver driver) + { + Driver = driver; + } + + public TestConnectionProfileService() + { + } + + private static readonly Lazy> TestServersLazyInstance = + new Lazy>(InitTestServerNames); + + private static readonly Lazy ConnectionSettingLazyInstance = + new Lazy(InitSetting); + + private ServiceTestDriver Driver { get; set; } + + private ConnectionProfile GetConnectionProfile(TestServerType serverType) + { + ConnectionProfile connectionProfile = null; + + //Get the server or profile name for given type to use for database connection + TestServerIdentity serverIdentity = _testServers != null ? _testServers.FirstOrDefault(x => x.ServerType == serverType) : null; + + //Search for the connection info in settings.json + if (serverIdentity == null) + { + //If not server name found, try to find the connection info for given type + connectionProfile = _setting != null && _setting.Connections != null ? _setting.Connections.FirstOrDefault(x => x.ServerType == serverType) : null; + if (connectionProfile == null && _setting != null && _setting.Connections != null) + { + Console.WriteLine(string.Format(CultureInfo.InvariantCulture, + "Cannot find any connection profile for server type '{0}'. " + + " Make sure the serverType attribute is set in {1}. " + + "Or run CreateTestServerNameSettings.cmd to create a template for the server names", serverType, _connectionSettingsFilename)); + } + } + else + { + //Find the connection info for specific server name or profile name + connectionProfile = _setting != null ? _setting.GetConnectionProfile(serverIdentity.ProfileName, serverIdentity.ServerName) : null; + + } + + Assert.True(connectionProfile != null, "Cannot find any connection profile for server type " + serverType.ToString()); + + return connectionProfile; + } + + /// + /// Returns database connection parameters for given server type + /// + public async Task GetConnectionParametersAsync(TestServerType serverType = TestServerType.OnPrem, string databaseName = null) + { + ConnectionProfile connectionProfile; + if (!_connectionProfilesCache.TryGetValue(serverType, out connectionProfile)) + { + connectionProfile = GetConnectionProfile(serverType); + + if (connectionProfile != null) + { + //If the password is empty, get the credential using the service + if (connectionProfile.AuthenticationType == AuthenticationType.SqlLogin && string.IsNullOrEmpty(connectionProfile.Password)) + { + Credential credential = await ReadCredentialAsync(connectionProfile.formatCredentialId()); + connectionProfile.Password = credential.Password; + } + _connectionProfilesCache.GetOrAdd(serverType, connectionProfile); + } + } + + if (connectionProfile != null) + { + ConnectParams connenctParam = CreateConnectParams(connectionProfile, serverType, databaseName); + + return connenctParam; + } + return null; + } + + /// + /// Request a Read Credential for given credential id + /// + private async Task ReadCredentialAsync(string credentialId) + { + var credentialParams = new Credential(); + credentialParams.CredentialId = credentialId; + + ServiceTestDriver driver = Driver; + if (driver == null) + { + TestServiceProvider.InitializeTestServices(); + return await CredentialService.Instance.ReadCredentialAsync(credentialParams); + } + else + { + return await Driver.SendRequest(ReadCredentialRequest.Type, credentialParams); + } + } + + /// + /// Create a connection parameters object + /// + private ConnectParams CreateConnectParams(ConnectionProfile connectionProfile, TestServerType serverType, string databaseName) + { + ConnectParams connectParams = new ConnectParams(); + connectParams.Connection = new ConnectionDetails(); + connectParams.Connection.ServerName = connectionProfile.ServerName; + connectParams.Connection.DatabaseName = connectionProfile.Database; + connectParams.Connection.UserName = connectionProfile.User; + connectParams.Connection.Password = connectionProfile.Password; + connectParams.Connection.AuthenticationType = connectionProfile.AuthenticationType.ToString(); + if (!string.IsNullOrEmpty(databaseName)) + { + connectParams.Connection.DatabaseName = databaseName; + } + if (serverType == TestServerType.Azure) + { + connectParams.Connection.ConnectTimeout = 30; + connectParams.Connection.Encrypt = true; + connectParams.Connection.TrustServerCertificate = false; + } + return connectParams; + } + + private static IEnumerable InitTestServerNames() + { + try + { + string testServerNamesFileContent = GetTestServerNamesFileContent(); + if (!string.IsNullOrEmpty(testServerNamesFileContent)) + { + return Newtonsoft.Json.JsonConvert.DeserializeObject>(testServerNamesFileContent); + } + else + { + return Enumerable.Empty(); + } + } + catch (Exception ex) + { + Console.WriteLine("Failed to load the database connection server name settings. error: " + ex.Message); + return Enumerable.Empty(); + } + } + + private static ConnectionSetting InitSetting() + { + try + { + string settingsFileContents = GetSettingFileContent(); + ConnectionSetting setting = Newtonsoft.Json.JsonConvert.DeserializeObject(settingsFileContents); + Console.WriteLine("Connection Settings loaded successfully"); + return setting; + } + catch (Exception ex) + { + Console.WriteLine("Failed to load the connection settings. error: " + ex.Message); + return new ConnectionSetting(); + } + } + + /// + /// Get the location of testServerNames.json. Returns the value of environment variable 'SettingsFileName' and if it's empty returns + /// the location of vs code testServerNames.json + /// + /// + private static string GetTestServerNamesFileContent() + { + var testServerNameFilePath = Environment.GetEnvironmentVariable("TestServerNamesFile"); + string testServerFileName = "testServerNames.json"; + + if (string.IsNullOrEmpty(testServerNameFilePath)) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + testServerNameFilePath = Environment.GetEnvironmentVariable("APPDATA") + @"\\" + testServerFileName; + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + testServerNameFilePath = Environment.GetEnvironmentVariable("HOME") + @"/" + testServerFileName; + } + else + { + testServerNameFilePath = Environment.GetEnvironmentVariable("HOME") + @"/" + testServerFileName; + } + } + string testServerNamesFileContent = string.IsNullOrEmpty(testServerNameFilePath) ? string.Empty : File.ReadAllText(testServerNameFilePath); + + return testServerNamesFileContent; + } + + /// + /// Get the location of setting.json. Returns the value of environment variable 'SettingsFileName' and if it's empty returns + /// the location of vs code settings.json + /// + /// + private static string GetSettingFileContent() + { + var settingsFilename = Environment.GetEnvironmentVariable("SettingsFileName"); + + if (string.IsNullOrEmpty(settingsFilename)) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + settingsFilename = Environment.GetEnvironmentVariable("APPDATA") + @"\Code\User\settings.json"; + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + settingsFilename = Environment.GetEnvironmentVariable("HOME") + @"/Library/Application Support/Code/User/settings.json"; + } + else + { + settingsFilename = Environment.GetEnvironmentVariable("HOME") + @"/.config/Code/User/settings.json"; + } + } + + if (string.IsNullOrEmpty(settingsFilename)) + { + Console.WriteLine("Cannot find any connection settings. Please run CreateConnectionSettings.cmd to generate a template for the connection settings."); + } + else + { + Console.WriteLine("Connection settings: " + settingsFilename); + _connectionSettingsFilename = settingsFilename; + } + + string settingsFileContents = string.IsNullOrEmpty(settingsFilename) ? string.Empty : File.ReadAllText(settingsFilename); + + return settingsFileContents; + } + } +} diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestDatabaseService.cs b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestDatabaseService.cs new file mode 100644 index 00000000..84d505ee --- /dev/null +++ b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestDatabaseService.cs @@ -0,0 +1,48 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System; +using System.Globalization; +using System.Threading.Tasks; + +namespace Microsoft.SqlTools.ServiceLayer.Test.Common +{ + public class TestDatabaseService + { + public const string MasterDatabaseName = "master"; + + /// + /// Create the test db if not already exists + /// + internal static async Task CreateTestDatabase(TestServerType serverType, string databaseName = null, string query = null) + { + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) + using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) + { + databaseName = databaseName ?? GetUniqueDBName(""); + string createDatabaseQuery = Scripts.CreateDatabaseQuery.Replace("#DatabaseName#", databaseName); + await testService.RunQuery(serverType, MasterDatabaseName, createDatabaseQuery); + Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Verified test database '{0}' is created", databaseName)); + if (!string.IsNullOrEmpty(query)) + { + await testService.RunQuery(serverType, databaseName, query);// Scripts.CreateDatabaseObjectsQuery); + Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Verified test database '{0}' SQL types are created", databaseName)); + } + } + } + + /// + /// Returns a mangled name that unique based on Prefix + Machine + Process + /// + /// + /// + public static string GetUniqueDBName(string namePrefix) + { + string safeMachineName = Environment.MachineName.Replace('-', '_'); + return string.Format("{0}_{1}_{2}", + namePrefix, safeMachineName, Guid.NewGuid().ToString().Replace("-", "")); + } + } +} diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Utility/TestResult.cs b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestResult.cs similarity index 80% rename from test/Microsoft.SqlTools.ServiceLayer.TestDriver/Utility/TestResult.cs rename to test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestResult.cs index ac81c5d5..7c4b0c4b 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Utility/TestResult.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestResult.cs @@ -3,7 +3,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Utility +namespace Microsoft.SqlTools.ServiceLayer.Test.Common { public class TestResult { diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Utility/TestServerIdentity.cs b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestServerIdentity.cs similarity index 79% rename from test/Microsoft.SqlTools.ServiceLayer.TestDriver/Utility/TestServerIdentity.cs rename to test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestServerIdentity.cs index ce9b55fe..79c3c092 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Utility/TestServerIdentity.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestServerIdentity.cs @@ -3,7 +3,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Utility + +namespace Microsoft.SqlTools.ServiceLayer.Test.Common { /// /// The model to deserialize the server names json @@ -22,4 +23,10 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Utility Azure, OnPrem } + + public enum AuthenticationType + { + Integrated, + SqlLogin + } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/TestHelper.cs b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestServiceDriverProvider.cs similarity index 74% rename from test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/TestHelper.cs rename to test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestServiceDriverProvider.cs index 255f54a6..643aa5e0 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/TestHelper.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestServiceDriverProvider.cs @@ -1,30 +1,30 @@ -// +// // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. // using System; -using System.Linq; +using System.Runtime.CompilerServices; using System.Threading.Tasks; using Microsoft.SqlTools.ServiceLayer.Connection.Contracts; -using Microsoft.SqlTools.ServiceLayer.Credentials.Contracts; using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts; using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts; using Microsoft.SqlTools.ServiceLayer.SqlContext; using Microsoft.SqlTools.ServiceLayer.TestDriver.Driver; -using Microsoft.SqlTools.ServiceLayer.TestDriver.Utility; using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts; +using Xunit; -namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests +namespace Microsoft.SqlTools.ServiceLayer.Test.Common { /// - /// Base class for all test suites run by the test driver + /// Service class to execute SQL tools commands using the test driver or calling the service classed directly /// - public sealed class TestHelper : IDisposable + public sealed class TestServiceDriverProvider : IDisposable { private bool isRunning = false; + private TestConnectionProfileService testConnectionService; - public TestHelper() + public TestServiceDriverProvider() { Driver = new ServiceTestDriver(); Driver.Start().Wait(); @@ -47,7 +47,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests Driver.Stop().Wait(); Console.WriteLine("Successfully killed process."); } - catch(Exception e) + catch (Exception e) { Console.WriteLine($"Exception while waiting for service exit: {e.Message}"); } @@ -62,6 +62,14 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests private set; } + public TestConnectionProfileService TestConnectionService + { + get + { + return (testConnectionService = testConnectionService ?? new TestConnectionProfileService(Driver)); + } + } + private object fileLock = new Object(); /// @@ -69,7 +77,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests /// /// True if the connection completed successfully public async Task Connect(string ownerUri, ConnectParams connectParams, int timeout = 15000) - { + { connectParams.OwnerUri = ownerUri; var connectResult = await Driver.SendRequest(ConnectionRequest.Type, connectParams); if (connectResult) @@ -83,6 +91,52 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests } } + /// + /// Request a new connection to be created for given query + /// + public async Task ConnectForQuery(TestServerType serverType, string query, string ownerUri, string databaseName = null, int timeout = 15000) + { + if (!string.IsNullOrEmpty(query)) + { + WriteToFile(ownerUri, query); + } + + /* + DidOpenTextDocumentNotification openParams = new DidOpenTextDocumentNotification + { + TextDocument = new TextDocumentItem + { + Uri = ownerUri, + LanguageId = "enu", + Version = 1, + Text = query + } + }; + + await RequestOpenDocumentNotification(openParams); + + Thread.Sleep(500); + */ + + return await Connect(serverType, ownerUri, databaseName, timeout); + } + + /// + /// Request a new connection to be created for url + /// + public async Task Connect(TestServerType serverType, string ownerUri, string databaseName = null, int timeout = 15000) + { + + var connectParams = await GetConnectionParametersAsync(serverType, databaseName); + + bool connected = await Connect(ownerUri, connectParams, timeout); + Assert.True(connected, "Connection is successful"); + Console.WriteLine($"Connection to {connectParams.Connection.ServerName} is successful"); + + return connected; + } + + /// /// Request a disconnect /// @@ -148,7 +202,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests { await Driver.SendEvent(DidChangeTextDocumentNotification.Type, changeParams); } - + /// /// Request completion item resolve to look-up additional info /// @@ -158,56 +212,12 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests return result; } - /// - /// Request a Read Credential for given credential id - /// - public async Task ReadCredential(string credentialId) - { - var credentialParams = new Credential(); - credentialParams.CredentialId = credentialId; - - return await Driver.SendRequest(ReadCredentialRequest.Type, credentialParams); - } - /// /// Returns database connection parameters for given server type /// - public async Task GetDatabaseConnectionAsync(TestServerType serverType, string databaseName) + public async Task GetConnectionParametersAsync(TestServerType serverType, string databaseName = null) { - ConnectionProfile connectionProfile = null; - TestServerIdentity serverIdentiry = ConnectionTestUtils.TestServers.FirstOrDefault(x => x.ServerType == serverType); - if (serverIdentiry == null) - { - connectionProfile = ConnectionTestUtils.Setting.Connections.FirstOrDefault(x => x.ServerType == serverType); - } - else - { - connectionProfile = ConnectionTestUtils.Setting.GetConnentProfile(serverIdentiry.ProfileName, serverIdentiry.ServerName); - } - - if (connectionProfile != null) - { - string password = connectionProfile.Password; - if (string.IsNullOrEmpty(password)) - { - Credential credential = await ReadCredential(connectionProfile.formatCredentialId()); - password = credential.Password; - } - ConnectParams conenctParam = ConnectionTestUtils.CreateConnectParams(connectionProfile.ServerName, connectionProfile.Database, - connectionProfile.User, password); - if (!string.IsNullOrEmpty(databaseName)) - { - conenctParam.Connection.DatabaseName = databaseName; - } - if (serverType == TestServerType.Azure) - { - conenctParam.Connection.ConnectTimeout = 30; - conenctParam.Connection.Encrypt = true; - conenctParam.Connection.TrustServerCertificate = false; - } - return conenctParam; - } - return null; + return await TestConnectionService.GetConnectionParametersAsync(serverType, databaseName); } /// @@ -245,7 +255,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests var completionParams = new TextDocumentPosition { - TextDocument = new TextDocumentIdentifier {Uri = ownerUri}, + TextDocument = new TextDocumentIdentifier { Uri = ownerUri }, Position = new Position { Line = line, @@ -283,7 +293,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests /// /// Run a query using a given connection bound to a URI /// - public async Task RunQuery(string ownerUri, string query, int timeoutMilliseconds = 5000) + public async Task RunQueryAndWaitToComplete(string ownerUri, string query, int timeoutMilliseconds = 5000) { // Write the query text to a backing file WriteToFile(ownerUri, query); @@ -322,13 +332,55 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests return await Driver.SendRequest(QueryExecuteRequest.Type, queryParams); } - + + public async Task RunQuery(TestServerType serverType, string databaseName, string query) + { + using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) + { + await ConnectForQuery(serverType, query, queryTempFile.FilePath, databaseName); + var queryResult = await CalculateRunTime(() => RunQueryAndWaitToComplete(queryTempFile.FilePath, query, 50000), false); + + await Disconnect(queryTempFile.FilePath); + } + } + + public async Task CalculateRunTime(Func> testToRun, bool printResult, [CallerMemberName] string testName = "") + { + TestTimer timer = new TestTimer() { PrintResult = printResult }; + T result = await testToRun(); + timer.EndAndPrint(testName); + + return result; + } + + public async Task ExecuteWithTimeout(TestTimer timer, int timeout, Func> repeatedCode, + TimeSpan? delay = null, [CallerMemberName] string testName = "") + { + while (true) + { + if (await repeatedCode()) + { + timer.EndAndPrint(testName); + break; + } + if (timer.TotalMilliSecondsUntilNow >= timeout) + { + Assert.True(false, $"{testName} timed out after {timeout} milliseconds"); + break; + } + if (delay.HasValue) + { + await Task.Delay(delay.Value); + } + } + } + /// /// Request to cancel an executing query /// public async Task CancelQuery(string ownerUri) { - var cancelParams = new QueryCancelParams {OwnerUri = ownerUri}; + var cancelParams = new QueryCancelParams { OwnerUri = ownerUri }; var result = await Driver.SendRequest(QueryCancelRequest.Type, cancelParams); return result; diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestServiceProvider.cs b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestServiceProvider.cs new file mode 100644 index 00000000..8d28ac7b --- /dev/null +++ b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestServiceProvider.cs @@ -0,0 +1,57 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System; +using Microsoft.SqlTools.ServiceLayer.Connection; +using Microsoft.SqlTools.ServiceLayer.Credentials; +using Microsoft.SqlTools.ServiceLayer.Hosting; +using Microsoft.SqlTools.ServiceLayer.LanguageServices; +using Microsoft.SqlTools.ServiceLayer.QueryExecution; +using Microsoft.SqlTools.ServiceLayer.SqlContext; +using Microsoft.SqlTools.ServiceLayer.Workspace; + +namespace Microsoft.SqlTools.ServiceLayer.Test.Common +{ + /// + /// Class to provide SQL tools service classes + /// + public class TestServiceProvider + { + private static bool hasInitServices = false; + + public static void InitializeTestServices() + { + if (TestServiceProvider.hasInitServices) + { + return; + } + + TestServiceProvider.hasInitServices = true; + + const string hostName = "SQ Tools Test Service Host"; + const string hostProfileId = "SQLToolsTestService"; + Version hostVersion = new Version(1, 0); + + // set up the host details and profile paths + var hostDetails = new HostDetails(hostName, hostProfileId, hostVersion); + SqlToolsContext sqlToolsContext = new SqlToolsContext(hostDetails); + + // Grab the instance of the service host + ServiceHost serviceHost = ServiceHost.Instance; + + // Start the service + serviceHost.Start().Wait(); + + // Initialize the services that will be hosted here + WorkspaceService.Instance.InitializeService(serviceHost); + LanguageService.Instance.InitializeService(serviceHost, sqlToolsContext); + ConnectionService.Instance.InitializeService(serviceHost); + CredentialService.Instance.InitializeService(serviceHost); + QueryExecutionService.Instance.InitializeService(serviceHost); + + serviceHost.Initialize(); + } + } +} diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Utility/TestTimer.cs b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestTimer.cs similarity index 97% rename from test/Microsoft.SqlTools.ServiceLayer.TestDriver/Utility/TestTimer.cs rename to test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestTimer.cs index 05e4c00f..783f483a 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Utility/TestTimer.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestTimer.cs @@ -8,7 +8,7 @@ using System.Globalization; using System.IO; using System.Runtime.CompilerServices; -namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Utility +namespace Microsoft.SqlTools.ServiceLayer.Test.Common { /// /// Timer to calculate the test run time diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/project.json b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/project.json new file mode 100644 index 00000000..8c18a1fa --- /dev/null +++ b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/project.json @@ -0,0 +1,46 @@ +{ + "version": "1.0.0-*", + "buildOptions": { + "emitEntryPoint": false, + "embed": { + "includeFiles": [ + "Scripts/CreateTestDatabaseObjects.sql", + "Scripts/CreateTestDatabase.sql", + "Scripts/TestDbTableQueries.sql" + ] + } + }, + + "dependencies": { + "Newtonsoft.Json": "9.0.1", + "System.Runtime.Serialization.Primitives": "4.1.1", + "System.Data.Common": "4.1.0", + "System.Data.SqlClient": "4.4.0-sqltools-24613-04", + "Microsoft.SqlServer.Smo": "140.1.12", + "System.Security.SecureString": "4.0.0", + "System.Collections.Specialized": "4.0.1", + "System.ComponentModel.TypeConverter": "4.1.0", + "xunit": "2.1.0", + "dotnet-test-xunit": "1.0.0-rc2-192208-24", + "Microsoft.SqlTools.ServiceLayer": { + "target": "project" + }, + "Moq": "4.6.36-alpha", + "Microsoft.SqlTools.ServiceLayer.TestDriver": "1.0.0-*" + }, + "testRunner": "xunit", + "frameworks": { + "netcoreapp1.0": { + "dependencies": { + "Microsoft.NETCore.App": { + "type": "platform", + "version": "1.0.0" + } + }, + "imports": [ + "dotnet5.4", + "portable-net451+win8" + ] + } + } +} diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/Connection/ConnectionServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/Connection/ConnectionServiceTests.cs index 9ead2576..337274a9 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/Connection/ConnectionServiceTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/Connection/ConnectionServiceTests.cs @@ -122,7 +122,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection } [Fact] - public async void CanCancelConnectRequestByConnecting() + public async Task CanCancelConnectRequestByConnecting() { var testFile = "file:///my/test/file.sql"; @@ -269,7 +269,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection [Theory] [InlineDataAttribute(null)] [InlineDataAttribute("")] - public async void CanConnectWithEmptyDatabaseName(string databaseName) + public async Task CanConnectWithEmptyDatabaseName(string databaseName) { // Connect var connectionDetails = TestObjects.GetTestConnectionDetails(); @@ -293,7 +293,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection [Theory] [InlineDataAttribute("master")] [InlineDataAttribute("nonMasterDb")] - public async void ConnectToDefaultDatabaseRespondsWithActualDbName(string expectedDbName) + public async Task ConnectToDefaultDatabaseRespondsWithActualDbName(string expectedDbName) { // Given connecting with empty database name will return the expected DB name var connectionMock = new Mock { CallBase = true }; @@ -328,7 +328,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection /// connection, we disconnect first before connecting. /// [Fact] - public async void ConnectingWhenConnectionExistCausesDisconnectThenConnect() + public async Task ConnectingWhenConnectionExistCausesDisconnectThenConnect() { bool callbackInvoked = false; @@ -375,7 +375,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection /// Verify that when connecting with invalid credentials, an error is thrown. /// [Fact] - public async void ConnectingWithInvalidCredentialsYieldsErrorMessage() + public async Task ConnectingWithInvalidCredentialsYieldsErrorMessage() { var testConnectionDetails = TestObjects.GetTestConnectionDetails(); var invalidConnectionDetails = new ConnectionDetails(); @@ -414,7 +414,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection [InlineData("Integrated", "file://my/sample/file.sql", null, "test", "sa", "123456")] [InlineData("Integrated", "", "my-server", "test", "sa", "123456")] [InlineData("Integrated", "file://my/sample/file.sql", "", "test", "sa", "123456")] - public async void ConnectingWithInvalidParametersYieldsErrorMessage(string authType, string ownerUri, string server, string database, string userName, string password) + public async Task ConnectingWithInvalidParametersYieldsErrorMessage(string authType, string ownerUri, string server, string database, string userName, string password) { // Connect with invalid parameters var connectionResult = await @@ -448,7 +448,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection [InlineData("sa", "")] [InlineData(null, "12345678")] [InlineData("", "12345678")] - public async void ConnectingWithNoUsernameOrPasswordWorksForIntegratedAuth(string userName, string password) + public async Task ConnectingWithNoUsernameOrPasswordWorksForIntegratedAuth(string userName, string password) { // Connect var connectionResult = await @@ -473,7 +473,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection /// Verify that when connecting with a null parameters object, an error is thrown. /// [Fact] - public async void ConnectingWithNullParametersObjectYieldsErrorMessage() + public async Task ConnectingWithNullParametersObjectYieldsErrorMessage() { // Connect with null parameters var connectionResult = await @@ -551,7 +551,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection /// Verify that a connection changed event is fired when the database context changes. /// [Fact] - public async void ConnectionChangedEventIsFiredWhenDatabaseContextChanges() + public async Task ConnectionChangedEventIsFiredWhenDatabaseContextChanges() { var serviceHostMock = new Mock(); @@ -585,7 +585,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection /// Verify that the SQL parser correctly detects errors in text /// [Fact] - public async void ConnectToDatabaseTest() + public async Task ConnectToDatabaseTest() { // connect to a database instance string ownerUri = "file://my/sample/file.sql"; @@ -605,7 +605,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection /// Verify that we can disconnect from an active connection succesfully /// [Fact] - public async void DisconnectFromDatabaseTest() + public async Task DisconnectFromDatabaseTest() { // first connect string ownerUri = "file://my/sample/file.sql"; @@ -635,7 +635,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection /// Test that when a disconnect is performed, the callback event is fired /// [Fact] - public async void DisconnectFiresCallbackEvent() + public async Task DisconnectFiresCallbackEvent() { bool callbackInvoked = false; @@ -679,7 +679,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection /// Test that disconnecting an active connection removes the Owner URI -> ConnectionInfo mapping /// [Fact] - public async void DisconnectRemovesOwnerMapping() + public async Task DisconnectRemovesOwnerMapping() { // first connect string ownerUri = "file://my/sample/file.sql"; @@ -719,7 +719,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection [InlineDataAttribute(null)] [InlineDataAttribute("")] - public async void DisconnectValidatesParameters(string disconnectUri) + public async Task DisconnectValidatesParameters(string disconnectUri) { // first connect string ownerUri = "file://my/sample/file.sql"; @@ -751,7 +751,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection /// Verifies the the list databases operation lists database names for the server used by a connection. /// [Fact] - public async void ListDatabasesOnServerForCurrentConnectionReturnsDatabaseNames() + public async Task ListDatabasesOnServerForCurrentConnectionReturnsDatabaseNames() { // Result set for the query of database names Dictionary[] data = @@ -800,7 +800,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection /// Verify that the SQL parser correctly detects errors in text /// [Fact] - public async void OnConnectionCallbackHandlerTest() + public async Task OnConnectionCallbackHandlerTest() { bool callbackInvoked = false; @@ -854,7 +854,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection /// Verify when a connection is created that the URI -> Connection mapping is created in the connection service. /// [Fact] - public async void TestConnectRequestRegistersOwner() + public async Task TestConnectRequestRegistersOwner() { // Given a request to connect to a database var service = TestObjects.GetTestConnectionService(); diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/AutocompleteTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/AutocompleteTests.cs index b034609a..db5014cd 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/AutocompleteTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/AutocompleteTests.cs @@ -65,7 +65,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices // set up file for returning the query scriptFile = new Mock(); - scriptFile.SetupGet(file => file.Contents).Returns(Common.StandardQuery); + scriptFile.SetupGet(file => file.Contents).Returns(QueryExecution.Common.StandardQuery); scriptFile.SetupGet(file => file.ClientFilePath).Returns(this.testScriptUri); // set up workspace mock diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/PeekDefinitionTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/PeekDefinitionTests.cs index 99fd4a65..cc1d3e8e 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/PeekDefinitionTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/PeekDefinitionTests.cs @@ -27,6 +27,7 @@ using Microsoft.SqlTools.Test.Utility; using Moq; using Xunit; using Location = Microsoft.SqlTools.ServiceLayer.Workspace.Contracts.Location; +using Microsoft.SqlTools.ServiceLayer.Test.Common; namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices { @@ -71,7 +72,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices // set up file for returning the query var fileMock = new Mock(); - fileMock.SetupGet(file => file.Contents).Returns(Common.StandardQuery); + fileMock.SetupGet(file => file.Contents).Returns(QueryExecution.Common.StandardQuery); fileMock.SetupGet(file => file.ClientFilePath).Returns(this.testScriptUri); // set up workspace mock @@ -125,7 +126,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices [Fact] public async Task DefinitionsHandlerWithNoConnectionTest() { - TestObjects.InitializeTestServices(); + TestServiceProvider.InitializeTestServices(); InitializeTestObjects(); // request definition var definitionTask = await Task.WhenAny(LanguageService.HandleDefinitionRequest(textDocument, requestContext.Object), Task.Delay(TaskTimeout)); diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/CancelTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/CancelTests.cs index a121847d..c48e17e2 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/CancelTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/CancelTests.cs @@ -16,7 +16,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution public class CancelTests { [Fact] - public async void CancelInProgressQueryTest() + public async Task CancelInProgressQueryTest() { // If: // ... I request a query (doesn't matter what kind) and execute it @@ -45,7 +45,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution } [Fact] - public async void CancelExecutedQueryTest() + public async Task CancelExecutedQueryTest() { // If: // ... I request a query (doesn't matter what kind) and wait for execution diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/DisposeTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/DisposeTests.cs index 83ddea3f..1ddc420b 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/DisposeTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/DisposeTests.cs @@ -33,7 +33,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution } [Fact] - public async void DisposeExecutedQuery() + public async Task DisposeExecutedQuery() { // If: // ... I request a query (doesn't matter what kind) @@ -61,7 +61,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution } [Fact] - public async void QueryDisposeMissingQuery() + public async Task QueryDisposeMissingQuery() { // If: // ... I attempt to dispose a query that doesn't exist diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Execution/ServiceIntegrationTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Execution/ServiceIntegrationTests.cs index 975f16a0..6c26f60f 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Execution/ServiceIntegrationTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Execution/ServiceIntegrationTests.cs @@ -159,7 +159,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution } [Fact] - public async void QueryExecuteUnconnectedUriTest() + public async Task QueryExecuteUnconnectedUriTest() { // Given: // If: @@ -182,7 +182,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution } [Fact] - public async void QueryExecuteInProgressTest() + public async Task QueryExecuteInProgressTest() { // If: // ... I request to execute a query @@ -210,7 +210,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution } [Fact] - public async void QueryExecuteCompletedTest() + public async Task QueryExecuteCompletedTest() { // If: // ... I request to execute a query @@ -266,7 +266,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution } [Fact] - public async void QueryExecuteInvalidQueryTest() + public async Task QueryExecuteInvalidQueryTest() { // If: // ... I request to execute a query that is invalid diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/SaveResults/ServiceIntegrationTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/SaveResults/ServiceIntegrationTests.cs index 4421bfe7..1fee4fc7 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/SaveResults/ServiceIntegrationTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/SaveResults/ServiceIntegrationTests.cs @@ -50,7 +50,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.SaveResults } [Fact] - public async void SaveResultAsCsvFailure() + public async Task SaveResultAsCsvFailure() { // Given: // ... A working query and workspace service @@ -96,7 +96,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.SaveResults } [Fact] - public async void SaveResultsAsCsvSuccess() + public async Task SaveResultsAsCsvSuccess() { // Given: // ... A working query and workspace service @@ -167,7 +167,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.SaveResults } [Fact] - public async void SaveResultAsJsonFailure() + public async Task SaveResultAsJsonFailure() { // Given: // ... A working query and workspace service @@ -213,7 +213,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.SaveResults } [Fact] - public async void SaveResultsAsJsonSuccess() + public async Task SaveResultsAsJsonSuccess() { // Given: // ... A working query and workspace service diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/ServiceHost/ServiceHostTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/ServiceHost/ServiceHostTests.cs index c4a2b22d..faa79488 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/ServiceHost/ServiceHostTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/ServiceHost/ServiceHostTests.cs @@ -15,7 +15,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.ServiceHost public class ServiceHostTests { [Fact] - public async void InitializeResultShouldIncludeTheCharactersThatWouldTriggerTheCompletion() + public async Task InitializeResultShouldIncludeTheCharactersThatWouldTriggerTheCompletion() { Hosting.ServiceHost host = Hosting.ServiceHost.Instance; var requesContext = new Mock>(); diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestObjects.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestObjects.cs index 7af19715..95e4d1e3 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestObjects.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestObjects.cs @@ -10,14 +10,13 @@ using System.Data.Common; using System.Data.SqlClient; using System.IO; using System.Reflection; +using System.Threading.Tasks; using Microsoft.SqlServer.Management.Common; using Microsoft.SqlTools.ServiceLayer.Connection; using Microsoft.SqlTools.ServiceLayer.Connection.Contracts; -using Microsoft.SqlTools.ServiceLayer.Credentials; -using Microsoft.SqlTools.ServiceLayer.Hosting; using Microsoft.SqlTools.ServiceLayer.LanguageServices; -using Microsoft.SqlTools.ServiceLayer.QueryExecution; using Microsoft.SqlTools.ServiceLayer.SqlContext; +using Microsoft.SqlTools.ServiceLayer.Test.Common; using Microsoft.SqlTools.ServiceLayer.Test.Utility; using Microsoft.SqlTools.ServiceLayer.Workspace; using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts; @@ -29,7 +28,6 @@ namespace Microsoft.SqlTools.Test.Utility /// public class TestObjects { - private static bool hasInitServices = false; public const string ScriptUri = "file://some/file.sql"; /// @@ -74,23 +72,10 @@ namespace Microsoft.SqlTools.Test.Utility { return new ConnectionDetails() { - UserName = "sa", - Password = "...", - DatabaseName = "master", - ServerName = "localhost" - }; - } - - /// - /// Gets a ConnectionDetails for connecting to localhost with integrated auth - /// - public static ConnectionDetails GetIntegratedTestConnectionDetails() - { - return new ConnectionDetails() - { - DatabaseName = "master", - ServerName = "localhost", - AuthenticationType = "Integrated" + UserName = "user", + Password = "password", + DatabaseName = "databaseName", + ServerName = "serverName" }; } @@ -121,38 +106,7 @@ namespace Microsoft.SqlTools.Test.Utility return ConnectionService.Instance.ConnectionFactory; } - public static void InitializeTestServices() - { - if (TestObjects.hasInitServices) - { - return; - } - - TestObjects.hasInitServices = true; - - const string hostName = "SQ Tools Test Service Host"; - const string hostProfileId = "SQLToolsTestService"; - Version hostVersion = new Version(1,0); - - // set up the host details and profile paths - var hostDetails = new HostDetails(hostName, hostProfileId, hostVersion); - SqlToolsContext sqlToolsContext = new SqlToolsContext(hostDetails); - - // Grab the instance of the service host - ServiceHost serviceHost = ServiceHost.Instance; - - // Start the service - serviceHost.Start().Wait(); - - // Initialize the services that will be hosted here - WorkspaceService.Instance.InitializeService(serviceHost); - LanguageService.Instance.InitializeService(serviceHost, sqlToolsContext); - ConnectionService.Instance.InitializeService(serviceHost); - CredentialService.Instance.InitializeService(serviceHost); - QueryExecutionService.Instance.InitializeService(serviceHost); - - serviceHost.Initialize(); - } + public static string GetTestSqlFile() { @@ -170,12 +124,14 @@ namespace Microsoft.SqlTools.Test.Utility return filePath; } - public static ConnectionInfo InitLiveConnectionInfo(out ScriptFile scriptFile) + public static async Task InitLiveConnectionInfo() { - TestObjects.InitializeTestServices(); + TestServiceProvider.InitializeTestServices(); - string sqlFilePath = GetTestSqlFile(); - scriptFile = WorkspaceService.Instance.Workspace.GetFile(sqlFilePath); + string sqlFilePath = GetTestSqlFile(); + ScriptFile scriptFile = WorkspaceService.Instance.Workspace.GetFile(sqlFilePath); + TestConnectionProfileService connectionProfileService = new TestConnectionProfileService(); + ConnectParams connectParams = await connectionProfileService.GetConnectionParametersAsync(); string ownerUri = scriptFile.ClientFilePath; var connectionService = TestObjects.GetLiveTestConnectionService(); @@ -184,19 +140,21 @@ namespace Microsoft.SqlTools.Test.Utility .Connect(new ConnectParams() { OwnerUri = ownerUri, - Connection = TestObjects.GetIntegratedTestConnectionDetails() + Connection = connectParams.Connection }); connectionResult.Wait(); ConnectionInfo connInfo = null; connectionService.TryFindConnection(ownerUri, out connInfo); - return connInfo; + return new TestConnectionResult () { ConnectionInfo = connInfo, ScriptFile = scriptFile }; } - public static ConnectionInfo InitLiveConnectionInfoForDefinition() + public static async Task InitLiveConnectionInfoForDefinition() { - TestObjects.InitializeTestServices(); + TestServiceProvider.InitializeTestServices(); + TestConnectionProfileService connectionProfileService = new TestConnectionProfileService(); + ConnectParams connectParams = await connectionProfileService.GetConnectionParametersAsync(); string ownerUri = ScriptUri; var connectionService = TestObjects.GetLiveTestConnectionService(); @@ -205,7 +163,7 @@ namespace Microsoft.SqlTools.Test.Utility .Connect(new ConnectParams() { OwnerUri = ownerUri, - Connection = TestObjects.GetIntegratedTestConnectionDetails() + Connection = connectParams.Connection }); connectionResult.Wait(); @@ -351,4 +309,13 @@ namespace Microsoft.SqlTools.Test.Utility }; } } + + public class TestConnectionResult + { + public ConnectionInfo ConnectionInfo { get; set; } + + public ScriptFile ScriptFile { get; set; } + + public TextDocumentPosition TextDocumentPosition { get; set; } + } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestUtils.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestUtils.cs index 61887cc0..a1a88c13 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestUtils.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestUtils.cs @@ -1,6 +1,7 @@ using System; using System.Runtime.InteropServices; using System.Threading; +using System.Threading.Tasks; namespace Microsoft.SqlTools.ServiceLayer.Test.Utility { diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/project.json b/test/Microsoft.SqlTools.ServiceLayer.Test/project.json index cf4d78a3..2541b443 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/project.json +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/project.json @@ -27,7 +27,8 @@ "Microsoft.SqlTools.ServiceLayer": { "target": "project" }, - "Moq": "4.6.36-alpha" + "Moq": "4.6.36-alpha", + "Microsoft.SqlTools.ServiceLayer.Test.Common": "1.0.0-*" }, "testRunner": "xunit", "frameworks": { diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/ConnectionTests.cs b/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/ConnectionTests.cs new file mode 100644 index 00000000..f7b5e369 --- /dev/null +++ b/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/ConnectionTests.cs @@ -0,0 +1,78 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System.Threading; +using System.Threading.Tasks; +using Microsoft.SqlTools.ServiceLayer.Test.Common; +using Xunit; +using Microsoft.SqlTools.ServiceLayer.Connection.Contracts; + +namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests +{ + /// + /// Language Service end-to-end integration tests + /// + public class ConnectionTest + { + /// + /// Try to connect with invalid credentials + /// + [Fact] + public async Task InvalidConnection() + { + using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) + { + bool connected = await testService.Connect(queryTempFile.FilePath, InvalidConnectParams, 300000); + Assert.False(connected, "Invalid connection is failed to connect"); + + await testService.Connect(queryTempFile.FilePath, InvalidConnectParams, 300000); + + Thread.Sleep(1000); + + await testService.CancelConnect(queryTempFile.FilePath); + + await testService.Disconnect(queryTempFile.FilePath); + } + } + + /// + /// Validate list databases request + /// + [Fact] + public async Task ListDatabasesTest() + { + using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) + { + bool connected = await testService.Connect(TestServerType.OnPrem, queryTempFile.FilePath); + Assert.True(connected, "Connection successful"); + + var listDatabaseResult = await testService.ListDatabases(queryTempFile.FilePath); + Assert.True(listDatabaseResult.DatabaseNames.Length > 0); + + await testService.Disconnect(queryTempFile.FilePath); + } + } + + private static ConnectParams InvalidConnectParams + { + get + { + return new ConnectParams() + { + Connection = new ConnectionDetails() + { + DatabaseName = "master", + ServerName = "localhost", + AuthenticationType = "SqlLogin", + UserName = "invalid", + Password = ".." + } + }; + } + } + } +} diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/LanguageServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/LanguageServiceTests.cs similarity index 71% rename from test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/LanguageServiceTests.cs rename to test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/LanguageServiceTests.cs index dccee6c8..007fc3e6 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/LanguageServiceTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/LanguageServiceTests.cs @@ -4,12 +4,11 @@ // using System.IO; -using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts; using Microsoft.SqlTools.ServiceLayer.SqlContext; -using Microsoft.SqlTools.ServiceLayer.TestDriver.Utility; +using Microsoft.SqlTools.ServiceLayer.Test.Common; using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts; using Xunit; @@ -28,11 +27,11 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests public async Task HoverTest() { using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { string query = "SELECT * FROM sys.objects"; - testHelper.WriteToFile(queryTempFile.FilePath, query); + testService.WriteToFile(queryTempFile.FilePath, query); DidOpenTextDocumentNotification openParams = new DidOpenTextDocumentNotification { @@ -45,20 +44,20 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests } }; - await testHelper.RequestOpenDocumentNotification(openParams); + await testService.RequestOpenDocumentNotification(openParams); Thread.Sleep(500); - bool connected = await testHelper.Connect(queryTempFile.FilePath, ConnectionTestUtils.LocalhostConnection); + bool connected = await testService.Connect(TestServerType.OnPrem, queryTempFile.FilePath); Assert.True(connected, "Connection was not successful"); Thread.Sleep(10000); - Hover hover = await testHelper.RequestHover(queryTempFile.FilePath, query, 0, 15); + Hover hover = await testService.RequestHover(queryTempFile.FilePath, query, 0, 15); Assert.True(hover != null, "Hover tooltop is null"); - await testHelper.Disconnect(queryTempFile.FilePath); + await testService.Disconnect(queryTempFile.FilePath); } } @@ -69,11 +68,11 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests public async Task CompletionTest() { using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { string query = "SELECT * FROM sys.objects"; - testHelper.WriteToFile(queryTempFile.FilePath, query); + testService.WriteToFile(queryTempFile.FilePath, query); DidOpenTextDocumentNotification openParams = new DidOpenTextDocumentNotification { @@ -86,26 +85,26 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests } }; - await testHelper.RequestOpenDocumentNotification(openParams); + await testService.RequestOpenDocumentNotification(openParams); Thread.Sleep(500); - bool connected = await testHelper.Connect(queryTempFile.FilePath, ConnectionTestUtils.LocalhostConnection); + bool connected = await testService.Connect(TestServerType.OnPrem, queryTempFile.FilePath); Assert.True(connected, "Connection is successful"); Thread.Sleep(10000); - CompletionItem[] completions = await testHelper.RequestCompletion(queryTempFile.FilePath, query, 0, 15); + CompletionItem[] completions = await testService.RequestCompletion(queryTempFile.FilePath, query, 0, 15); Assert.True(completions != null && completions.Length > 0, "Completion items list is null or empty"); Thread.Sleep(50); - await testHelper.RequestResolveCompletion(completions[0]); + await testService.RequestResolveCompletion(completions[0]); Assert.True(completions != null && completions.Length > 0, "Completion items list is null or empty"); - await testHelper.Disconnect(queryTempFile.FilePath); + await testService.Disconnect(queryTempFile.FilePath); } } @@ -116,9 +115,9 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests public async Task DiagnosticsTests() { using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { - bool connected = await testHelper.Connect(queryTempFile.FilePath, ConnectionTestUtils.LocalhostConnection); + bool connected = await testService.Connect(TestServerType.OnPrem, queryTempFile.FilePath); Assert.True(connected, "Connection was not successful"); Thread.Sleep(500); @@ -136,7 +135,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests } }; - await testHelper.RequestOpenDocumentNotification(openParams); + await testService.RequestOpenDocumentNotification(openParams); Thread.Sleep(100); @@ -170,7 +169,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests } }; - await testHelper.RequestChangeTextDocumentNotification(changeParams); + await testService.RequestChangeTextDocumentNotification(changeParams); Thread.Sleep(100); @@ -203,11 +202,11 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests } }; - await testHelper.RequestChangeTextDocumentNotification(changeParams); + await testService.RequestChangeTextDocumentNotification(changeParams); Thread.Sleep(2500); - await testHelper.Disconnect(queryTempFile.FilePath); + await testService.Disconnect(queryTempFile.FilePath); } } @@ -219,13 +218,13 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests public async Task DefinitionTest() { using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { string query = "SELECT * FROM sys.objects"; int lineNumber = 0; int position = 23; - testHelper.WriteToFile(queryTempFile.FilePath, query); + testService.WriteToFile(queryTempFile.FilePath, query); DidOpenTextDocumentNotification openParams = new DidOpenTextDocumentNotification { @@ -238,19 +237,19 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests } }; - await testHelper.RequestOpenDocumentNotification(openParams); + await testService.RequestOpenDocumentNotification(openParams); Thread.Sleep(500); - bool connected = await testHelper.Connect(queryTempFile.FilePath, ConnectionTestUtils.LocalhostConnection); + bool connected = await testService.Connect(TestServerType.OnPrem, queryTempFile.FilePath); Assert.True(connected, "Connection is successful"); Thread.Sleep(10000); // Request definition for "objects" - Location[] locations = await testHelper.RequestDefinition(queryTempFile.FilePath, query, lineNumber, position); + Location[] locations = await testService.RequestDefinition(queryTempFile.FilePath, query, lineNumber, position); Assert.True(locations != null, "Location is not null and not empty"); - await testHelper.Disconnect(queryTempFile.FilePath); + await testService.Disconnect(queryTempFile.FilePath); } } @@ -261,9 +260,9 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests public async Task ChangeConfigurationTest() { using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { - bool connected = await testHelper.Connect(queryTempFile.FilePath, ConnectionTestUtils.LocalhostConnection); + bool connected = await testService.Connect(TestServerType.OnPrem, queryTempFile.FilePath); Assert.True(connected, "Connection was not successful"); Thread.Sleep(500); @@ -275,11 +274,11 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests Settings = settings }; - await testHelper.RequestChangeConfigurationNotification(configParams); + await testService.RequestChangeConfigurationNotification(configParams); Thread.Sleep(2000); - await testHelper.Disconnect(queryTempFile.FilePath); + await testService.Disconnect(queryTempFile.FilePath); } } @@ -287,17 +286,17 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests public async Task NotificationIsSentAfterOnConnectionAutoCompleteUpdate() { using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { // Connect - await testHelper.Connect(queryTempFile.FilePath, ConnectionTestUtils.LocalhostConnection); + await testService.Connect(TestServerType.OnPrem, queryTempFile.FilePath); // An event signalling that IntelliSense is ready should be sent shortly thereafter - var readyParams = await testHelper.Driver.WaitForEvent(IntelliSenseReadyNotification.Type, 30000); + var readyParams = await testService.Driver.WaitForEvent(IntelliSenseReadyNotification.Type, 30000); Assert.NotNull(readyParams); Assert.Equal(queryTempFile.FilePath, readyParams.OwnerUri); - await testHelper.Disconnect(queryTempFile.FilePath); + await testService.Disconnect(queryTempFile.FilePath); } } @@ -307,16 +306,16 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests string sqlText = "EXEC sys.fn_not_a_real_function "; using (SelfCleaningTempFile tempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { string ownerUri = tempFile.FilePath; File.WriteAllText(ownerUri, sqlText); // Connect - await testHelper.Connect(ownerUri, ConnectionTestUtils.LocalhostConnection); + await testService.Connect(TestServerType.OnPrem, ownerUri); // Wait for intellisense to be ready - var readyParams = await testHelper.Driver.WaitForEvent(IntelliSenseReadyNotification.Type, 30000); + var readyParams = await testService.Driver.WaitForEvent(IntelliSenseReadyNotification.Type, 30000); Assert.NotNull(readyParams); Assert.Equal(ownerUri, readyParams.OwnerUri); @@ -333,13 +332,13 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests Character = sqlText.Length } }; - var signatureHelp = await testHelper.Driver.SendRequest(SignatureHelpRequest.Type, position); + var signatureHelp = await testService.Driver.SendRequest(SignatureHelpRequest.Type, position); Assert.NotNull(signatureHelp); Assert.False(signatureHelp.ActiveSignature.HasValue); Assert.Null(signatureHelp.Signatures); - await testHelper.Disconnect(ownerUri); + await testService.Disconnect(ownerUri); } } @@ -349,16 +348,15 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests string sqlText = "EXEC sys.fn_isrolemember "; using (SelfCleaningTempFile tempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { string ownerUri = tempFile.FilePath; - File.WriteAllText(ownerUri, sqlText); // Connect - await testHelper.Connect(ownerUri, ConnectionTestUtils.LocalhostConnection); + await testService.ConnectForQuery(TestServerType.OnPrem, sqlText, ownerUri); // Wait for intellisense to be ready - var readyParams = await testHelper.Driver.WaitForEvent(IntelliSenseReadyNotification.Type, 30000); + var readyParams = await testService.Driver.WaitForEvent(IntelliSenseReadyNotification.Type, 30000); Assert.NotNull(readyParams); Assert.Equal(ownerUri, readyParams.OwnerUri); @@ -375,7 +373,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests Character = sqlText.Length } }; - var signatureHelp = await testHelper.Driver.SendRequest(SignatureHelpRequest.Type, position); + var signatureHelp = await testService.Driver.SendRequest(SignatureHelpRequest.Type, position); Assert.NotNull(signatureHelp); Assert.True(signatureHelp.ActiveSignature.HasValue); @@ -386,7 +384,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests Assert.NotEmpty(label); Assert.True(label.Contains("fn_isrolemember")); - await testHelper.Disconnect(ownerUri); + await testService.Disconnect(ownerUri); } } @@ -396,34 +394,34 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests string sqlText = "EXEC sys.fn_isrolemember 1, 'testing', 2"; using (SelfCleaningTempFile tempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { string ownerUri = tempFile.FilePath; File.WriteAllText(ownerUri, sqlText); // Connect - await testHelper.Connect(ownerUri, ConnectionTestUtils.LocalhostConnection); + await testService.Connect(TestServerType.OnPrem, ownerUri); // Wait for intellisense to be ready - var readyParams = await testHelper.Driver.WaitForEvent(IntelliSenseReadyNotification.Type, 30000); + var readyParams = await testService.Driver.WaitForEvent(IntelliSenseReadyNotification.Type, 30000); Assert.NotNull(readyParams); Assert.Equal(ownerUri, readyParams.OwnerUri); // Verify all parameters when the cursor is inside of parameters and at separator boundaries (,) - await VerifyFunctionSignatureHelpParameter(testHelper, ownerUri, 25, "fn_isrolemember", 0, "@mode int"); - await VerifyFunctionSignatureHelpParameter(testHelper, ownerUri, 26, "fn_isrolemember", 0, "@mode int"); - await VerifyFunctionSignatureHelpParameter(testHelper, ownerUri, 27, "fn_isrolemember", 1, "@login sysname"); - await VerifyFunctionSignatureHelpParameter(testHelper, ownerUri, 30, "fn_isrolemember", 1, "@login sysname"); - await VerifyFunctionSignatureHelpParameter(testHelper, ownerUri, 37, "fn_isrolemember", 1, "@login sysname"); - await VerifyFunctionSignatureHelpParameter(testHelper, ownerUri, 38, "fn_isrolemember", 2, "@tranpubid int"); - await VerifyFunctionSignatureHelpParameter(testHelper, ownerUri, 39, "fn_isrolemember", 2, "@tranpubid int"); + await VerifyFunctionSignatureHelpParameter(testService, ownerUri, 25, "fn_isrolemember", 0, "@mode int"); + await VerifyFunctionSignatureHelpParameter(testService, ownerUri, 26, "fn_isrolemember", 0, "@mode int"); + await VerifyFunctionSignatureHelpParameter(testService, ownerUri, 27, "fn_isrolemember", 1, "@login sysname"); + await VerifyFunctionSignatureHelpParameter(testService, ownerUri, 30, "fn_isrolemember", 1, "@login sysname"); + await VerifyFunctionSignatureHelpParameter(testService, ownerUri, 37, "fn_isrolemember", 1, "@login sysname"); + await VerifyFunctionSignatureHelpParameter(testService, ownerUri, 38, "fn_isrolemember", 2, "@tranpubid int"); + await VerifyFunctionSignatureHelpParameter(testService, ownerUri, 39, "fn_isrolemember", 2, "@tranpubid int"); - await testHelper.Disconnect(ownerUri); + await testService.Disconnect(ownerUri); } } public async Task VerifyFunctionSignatureHelpParameter( - TestHelper testHelper, + TestServiceDriverProvider TestService, string ownerUri, int character, string expectedFunctionName, @@ -442,7 +440,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests Character = character } }; - var signatureHelp = await testHelper.Driver.SendRequest(SignatureHelpRequest.Type, position); + var signatureHelp = await TestService.Driver.SendRequest(SignatureHelpRequest.Type, position); Assert.NotNull(signatureHelp); Assert.NotNull(signatureHelp.ActiveSignature); diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests.xproj b/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests.xproj new file mode 100644 index 00000000..4db71388 --- /dev/null +++ b/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests.xproj @@ -0,0 +1,22 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + e7cf630e-e084-4da4-bf69-f61bf0a8f5be + Microsoft.SqlTools.ServiceLayer.TestDriver.Tests + .\obj + .\bin\ + v4.5.2 + + + 2.0 + + + + + + \ No newline at end of file diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Program.cs b/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/Program.cs similarity index 89% rename from test/Microsoft.SqlTools.ServiceLayer.TestDriver/Program.cs rename to test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/Program.cs index 823b2efe..2453f112 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Program.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/Program.cs @@ -1,4 +1,4 @@ -// +// // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. // @@ -13,7 +13,7 @@ using Xunit; [assembly: CollectionBehavior(DisableTestParallelization = true)] -namespace Microsoft.SqlTools.ServiceLayer.TestDriver +namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests { internal class Program { @@ -21,8 +21,8 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver { if (args.Length < 1) { - Console.WriteLine( "Microsoft.SqlTools.ServiceLayer.TestDriver.exe [tests]" + Environment.NewLine + - " [tests] is a space-separated list of tests to run." + Environment.NewLine + + Console.WriteLine("Microsoft.SqlTools.ServiceLayer.TestDriver.exe [tests]" + Environment.NewLine + + " [tests] is a space-separated list of tests to run." + Environment.NewLine + " They are qualified within the Microsoft.SqlTools.ServiceLayer.TestDriver.Tests namespace" + Environment.NewLine + "Be sure to set the environment variable " + ServiceTestDriver.ServiceHostEnvironmentVariable + " to the full path of the sqltoolsservice executable."); return 0; @@ -31,7 +31,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver Logger.Initialize("testdriver", LogLevel.Verbose); int returnCode = 0; - Task.Run(async () => + Task.Run(async () => { string testNamespace = "Microsoft.SqlTools.ServiceLayer.TestDriver.Tests."; foreach (var test in args) @@ -41,8 +41,8 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver var testName = test.Contains(testNamespace) ? test.Replace(testNamespace, "") : test; bool containsTestName = testName.Contains("."); var className = containsTestName ? testName.Substring(0, testName.LastIndexOf('.')) : testName; - var methodName = containsTestName ? testName.Substring(testName.LastIndexOf('.') + 1) : null; - + var methodName = containsTestName ? testName.Substring(testName.LastIndexOf('.') + 1) : null; + var type = Type.GetType(testNamespace + className); if (type == null) { diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/Properties/AssemblyInfo.cs b/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..837d50fc --- /dev/null +++ b/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,19 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Microsoft.SqlTools.ServiceLayer.TestDriver.Tests")] +[assembly: AssemblyTrademark("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("e7cf630e-e084-4da4-bf69-f61bf0a8f5be")] diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/QueryExecutionTests.cs b/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/QueryExecutionTests.cs similarity index 60% rename from test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/QueryExecutionTests.cs rename to test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/QueryExecutionTests.cs index a9eb9ae7..61e20caa 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/QueryExecutionTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/QueryExecutionTests.cs @@ -3,14 +3,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using System.Collections.Generic; -using System.Linq; -using System.Threading; using System.Threading.Tasks; -using Microsoft.SqlTools.ServiceLayer; -using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts; -using Microsoft.SqlTools.ServiceLayer.TestDriver.Utility; -using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts; +using Microsoft.SqlTools.ServiceLayer.Test.Common; using Xunit; namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests @@ -24,23 +18,23 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests const string query = "SELECT * FROM sys.objects a CROSS JOIN sys.objects b CROSS JOIN sys.objects c"; using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestService testService = new TestService()) { - await testHelper.Connect(queryTempFile.FilePath, ConnectionTestUtils.AzureTestServerConnection); + await TestService.Connect(queryTempFile.FilePath, ConnectionTestUtils.AzureTestServerConnection); // Run and cancel 100 queries for (int i = 0; i < 100; i++) { - var queryTask = testHelper.RunQuery(queryTempFile.FilePath, query); + var queryTask = TestService.RunQuery(queryTempFile.FilePath, query); - var cancelResult = await testHelper.CancelQuery(queryTempFile.FilePath); + var cancelResult = await TestService.CancelQuery(queryTempFile.FilePath); Assert.NotNull(cancelResult); Assert.True(string.IsNullOrEmpty(cancelResult.Messages)); await queryTask; } - await testHelper.Disconnect(queryTempFile.FilePath); + await TestService.Disconnect(queryTempFile.FilePath); } } @@ -50,26 +44,26 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests const string query = "SELECT * FROM sys.objects a CROSS JOIN sys.objects b CROSS JOIN sys.objects c"; using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestService testService = new TestService()) { - await testHelper.Connect(queryTempFile.FilePath, ConnectionTestUtils.AzureTestServerConnection); + await TestService.Connect(queryTempFile.FilePath, ConnectionTestUtils.AzureTestServerConnection); // Start a long-running query - var queryTask = testHelper.RunQuery(queryTempFile.FilePath, query, 60000); + var queryTask = TestService.RunQuery(queryTempFile.FilePath, query, 60000); // Interact with the service. None of these requests should time out while waiting for the query to finish for (int i = 0; i < 10; i++) { using (SelfCleaningTempFile queryFile2 = new SelfCleaningTempFile()) { - await testHelper.Connect(queryFile2.FilePath, ConnectionTestUtils.AzureTestServerConnection); - Assert.NotNull(await testHelper.RequestCompletion(queryFile2.FilePath, "SELECT * FROM sys.objects", 0, 10)); - await testHelper.Disconnect(queryFile2.FilePath); + await TestService.Connect(queryFile2.FilePath, ConnectionTestUtils.AzureTestServerConnection); + Assert.NotNull(await TestService.RequestCompletion(queryFile2.FilePath, "SELECT * FROM sys.objects", 0, 10)); + await TestService.Disconnect(queryFile2.FilePath); } } - await testHelper.CancelQuery(queryTempFile.FilePath); - await testHelper.Disconnect(queryTempFile.FilePath); + await TestService.CancelQuery(queryTempFile.FilePath); + await TestService.Disconnect(queryTempFile.FilePath); } } @@ -79,21 +73,21 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests const int queryCount = 10; const string query = "SELECT * FROM sys.objects"; - using (TestHelper testHelper = new TestHelper()) + using (TestService testService = new TestService()) { // Create n connections SelfCleaningTempFile[] ownerUris = new SelfCleaningTempFile[queryCount]; for (int i = 0; i < queryCount; i++) { ownerUris[i] = new SelfCleaningTempFile(); - Assert.NotNull(await testHelper.Connect(ownerUris[i].FilePath, ConnectionTestUtils.AzureTestServerConnection)); + Assert.NotNull(await TestService.Connect(ownerUris[i].FilePath, ConnectionTestUtils.AzureTestServerConnection)); } // Run n queries at once var queryTasks = new Task[queryCount]; for (int i = 0; i < queryCount; i++) { - queryTasks[i] = testHelper.RunQuery(ownerUris[i].FilePath, query); + queryTasks[i] = TestService.RunQuery(ownerUris[i].FilePath, query); } await Task.WhenAll(queryTasks); @@ -102,7 +96,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests { Assert.NotNull(queryTasks[i].Result); Assert.NotNull(queryTasks[i].Result.BatchSummaries); - await testHelper.Disconnect(ownerUris[i].FilePath); + await TestService.Disconnect(ownerUris[i].FilePath); ownerUris[i].Dispose(); } } @@ -114,12 +108,12 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests const string query = "SELECT * FROM sys.objects"; using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestService testService = new TestService()) { - await testHelper.Connect(queryTempFile.FilePath, ConnectionTestUtils.AzureTestServerConnection); + await TestService.Connect(queryTempFile.FilePath, ConnectionTestUtils.AzureTestServerConnection); // Execute a query - await testHelper.RunQuery(queryTempFile.FilePath, query); + await TestService.RunQuery(queryTempFile.FilePath, query); // Spawn several tasks to save results var saveTasks = new Task[100]; @@ -127,11 +121,11 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests { if (i % 2 == 0) { - saveTasks[i] = testHelper.SaveAsCsv(queryTempFile.FilePath, System.IO.Path.GetTempFileName(), 0, 0); + saveTasks[i] = TestService.SaveAsCsv(queryTempFile.FilePath, System.IO.Path.GetTempFileName(), 0, 0); } else { - saveTasks[i] = testHelper.SaveAsJson(queryTempFile.FilePath, System.IO.Path.GetTempFileName(), 0, 0); + saveTasks[i] = TestService.SaveAsJson(queryTempFile.FilePath, System.IO.Path.GetTempFileName(), 0, 0); } } @@ -140,15 +134,15 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests { using(SelfCleaningTempFile queryFile2 = new SelfCleaningTempFile()) { - await testHelper.Connect(queryFile2.FilePath, ConnectionTestUtils.AzureTestServerConnection); - Assert.NotNull(await testHelper.RequestCompletion(queryFile2.FilePath, "SELECT * FROM sys.objects", 0, 10)); - await testHelper.Disconnect(queryFile2.FilePath); + await TestService.Connect(queryFile2.FilePath, ConnectionTestUtils.AzureTestServerConnection); + Assert.NotNull(await TestService.RequestCompletion(queryFile2.FilePath, "SELECT * FROM sys.objects", 0, 10)); + await TestService.Disconnect(queryFile2.FilePath); } } await Task.WhenAll(saveTasks); - await testHelper.Disconnect(queryTempFile.FilePath); + await TestService.Disconnect(queryTempFile.FilePath); } } @@ -158,18 +152,18 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests const string query = "SELECT * FROM sys.objects"; using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestService testService = new TestService()) { - await testHelper.Connect(queryTempFile.FilePath, ConnectionTestUtils.AzureTestServerConnection); + await TestService.Connect(queryTempFile.FilePath, ConnectionTestUtils.AzureTestServerConnection); // Execute a query - await testHelper.RunQuery(queryTempFile.FilePath, query); + await TestService.RunQuery(queryTempFile.FilePath, query); // Spawn several tasks for subset requests var subsetTasks = new Task[100]; for (int i = 0; i < 100; i++) { - subsetTasks[i] = testHelper.ExecuteSubset(queryTempFile.FilePath, 0, 0, 0, 100); + subsetTasks[i] = TestService.ExecuteSubset(queryTempFile.FilePath, 0, 0, 0, 100); } // Interact with the service. None of these requests should time out while waiting for the subset tasks to finish @@ -177,15 +171,15 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests { using (SelfCleaningTempFile queryFile2 = new SelfCleaningTempFile()) { - await testHelper.Connect(queryFile2.FilePath, ConnectionTestUtils.AzureTestServerConnection); - Assert.NotNull(await testHelper.RequestCompletion(queryFile2.FilePath, "SELECT * FROM sys.objects", 0, 10)); - await testHelper.Disconnect(queryFile2.FilePath); + await TestService.Connect(queryFile2.FilePath, ConnectionTestUtils.AzureTestServerConnection); + Assert.NotNull(await TestService.RequestCompletion(queryFile2.FilePath, "SELECT * FROM sys.objects", 0, 10)); + await TestService.Disconnect(queryFile2.FilePath); } } await Task.WhenAll(subsetTasks); - await testHelper.Disconnect(queryTempFile.FilePath); + await TestService.Disconnect(queryTempFile.FilePath); } } @@ -195,14 +189,14 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests const string query = "SELECT * FROM sys.objects a CROSS JOIN sys.objects b"; using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestService testService = new TestService()) { List tasks = new List(); - await testHelper.Connect(queryTempFile.FilePath, ConnectionTestUtils.AzureTestServerConnection); + await TestService.Connect(queryTempFile.FilePath, ConnectionTestUtils.AzureTestServerConnection); // Execute a long-running query - var queryTask = testHelper.RunQuery(queryTempFile.FilePath, query, 60000); + var queryTask = TestService.RunQuery(queryTempFile.FilePath, query, 60000); // Queue up some tasks that interact with the service for (int i = 0; i < 10; i++) @@ -211,18 +205,18 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests { tasks.Add(Task.Run(async () => { - await testHelper.Connect(queryFile2.FilePath, ConnectionTestUtils.AzureTestServerConnection); - await testHelper.RequestCompletion(queryFile2.FilePath, "SELECT * FROM sys.objects", 0, 10); - await testHelper.RunQuery(queryFile2.FilePath, "SELECT * FROM sys.objects"); - await testHelper.Disconnect(queryFile2.FilePath); + await TestService.Connect(queryFile2.FilePath, ConnectionTestUtils.AzureTestServerConnection); + await TestService.RequestCompletion(queryFile2.FilePath, "SELECT * FROM sys.objects", 0, 10); + await TestService.RunQuery(queryFile2.FilePath, "SELECT * FROM sys.objects"); + await TestService.Disconnect(queryFile2.FilePath); })); } } // Cancel the long-running query - await testHelper.CancelQuery(queryTempFile.FilePath); + await TestService.CancelQuery(queryTempFile.FilePath); - await testHelper.Disconnect(queryTempFile.FilePath); + await TestService.Disconnect(queryTempFile.FilePath); } } @@ -232,9 +226,9 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests const string query = "SELECT * FROM sys.all_columns c"; using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestService testService = new TestService()) { - bool connected = await testHelper.Connect(queryTempFile.FilePath, ConnectionTestUtils.LocalhostConnection); + bool connected = await TestService.Connect(TestServerType.OnPrem, string.Empty, queryTempFile.FilePath); Assert.True(connected, "Connection is successful"); Thread.Sleep(500); @@ -250,9 +244,9 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests } }; - await testHelper.RequestOpenDocumentNotification(openParams); + await TestService.RequestOpenDocumentNotification(openParams); - var queryResult = await testHelper.RunQuery(queryTempFile.FilePath, query, 10000); + var queryResult = await TestService.RunQuery(queryTempFile.FilePath, query, 10000); Assert.NotNull(queryResult); Assert.NotNull(queryResult.BatchSummaries); @@ -274,11 +268,11 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests RowsCount = 100, }; - var querySubset = await testHelper.RequestQueryExecuteSubset(subsetRequest); + var querySubset = await TestService.RequestQueryExecuteSubset(subsetRequest); Assert.NotNull(querySubset); Assert.True(querySubset.ResultSubset.RowCount == 100); - await testHelper.Disconnect(queryTempFile.FilePath); + await TestService.Disconnect(queryTempFile.FilePath); } } @@ -288,41 +282,41 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests const string query = "SELECT * FROM sys.objects"; using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestService testService = new TestService()) { List tasks = new List(); - await testHelper.Connect(queryTempFile.FilePath, ConnectionTestUtils.AzureTestServerConnection); + await TestService.Connect(queryTempFile.FilePath, ConnectionTestUtils.AzureTestServerConnection); - Enumerable.Range(0, 10).ToList().ForEach(arg => tasks.Add(testHelper.RequestCompletion(queryTempFile.FilePath, query, 0, 10))); - var queryTask = testHelper.RunQuery(queryTempFile.FilePath, query); + Enumerable.Range(0, 10).ToList().ForEach(arg => tasks.Add(TestService.RequestCompletion(queryTempFile.FilePath, query, 0, 10))); + var queryTask = TestService.RunQuery(queryTempFile.FilePath, query); tasks.Add(queryTask); await Task.WhenAll(tasks); Assert.NotNull(queryTask.Result); Assert.NotNull(queryTask.Result.BatchSummaries); - await testHelper.Connect(queryTempFile.FilePath, ConnectionTestUtils.DataToolsTelemetryAzureConnection); + await TestService.Connect(queryTempFile.FilePath, ConnectionTestUtils.DataToolsTelemetryAzureConnection); tasks.Clear(); - Enumerable.Range(0, 10).ToList().ForEach(arg => tasks.Add(testHelper.RequestCompletion(queryTempFile.FilePath, query, 0, 10))); - queryTask = testHelper.RunQuery(queryTempFile.FilePath, query); + Enumerable.Range(0, 10).ToList().ForEach(arg => tasks.Add(TestService.RequestCompletion(queryTempFile.FilePath, query, 0, 10))); + queryTask = TestService.RunQuery(queryTempFile.FilePath, query); tasks.Add(queryTask); await Task.WhenAll(tasks); Assert.NotNull(queryTask.Result); Assert.NotNull(queryTask.Result.BatchSummaries); - await testHelper.Connect(queryTempFile.FilePath, ConnectionTestUtils.SqlDataToolsAzureConnection); + await TestService.Connect(queryTempFile.FilePath, ConnectionTestUtils.SqlDataToolsAzureConnection); tasks.Clear(); - Enumerable.Range(0, 10).ToList().ForEach(arg => tasks.Add(testHelper.RequestCompletion(queryTempFile.FilePath, query, 0, 10))); - queryTask = testHelper.RunQuery(queryTempFile.FilePath, query); + Enumerable.Range(0, 10).ToList().ForEach(arg => tasks.Add(TestService.RequestCompletion(queryTempFile.FilePath, query, 0, 10))); + queryTask = TestService.RunQuery(queryTempFile.FilePath, query); tasks.Add(queryTask); await Task.WhenAll(tasks); Assert.NotNull(queryTask.Result); Assert.NotNull(queryTask.Result.BatchSummaries); - await testHelper.Disconnect(queryTempFile.FilePath); + await TestService.Disconnect(queryTempFile.FilePath); } } */ @@ -334,13 +328,13 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests public async Task NoOpQueryReturnsMessage(string query) { using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { - Assert.True(await testHelper.Connect(queryTempFile.FilePath, ConnectionTestUtils.LocalhostConnection)); + Assert.True(await testService.Connect(TestServerType.OnPrem, queryTempFile.FilePath)); // If: the query is executed... - var queryResult = await testHelper.RunQueryAsync(queryTempFile.FilePath, query); - var message = await testHelper.WaitForMessage(); + var queryResult = await testService.RunQueryAsync(queryTempFile.FilePath, query); + var message = await testService.WaitForMessage(); // Then: // ... I expect a query result to indicate successfully started query @@ -353,7 +347,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests Assert.False(message.Message.IsError); Assert.Null(message.Message.BatchId); - await testHelper.Disconnect(queryTempFile.FilePath); + await testService.Disconnect(queryTempFile.FilePath); } } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/StressTests.cs b/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/StressTests.cs similarity index 79% rename from test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/StressTests.cs rename to test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/StressTests.cs index bd39ee4a..d793cc49 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/StressTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/StressTests.cs @@ -7,7 +7,7 @@ using System; using System.Diagnostics; using System.Threading; using System.Threading.Tasks; -using Microsoft.SqlTools.ServiceLayer.TestDriver.Utility; +using Microsoft.SqlTools.ServiceLayer.Test.Common; using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts; using Xunit; @@ -34,10 +34,10 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { // Connect - bool connected = await testHelper.Connect(queryTempFile.FilePath, ConnectionTestUtils.LocalhostConnection); + bool connected = await testService.Connect(TestServerType.OnPrem, string.Empty, queryTempFile.FilePath); Assert.True(connected, "Connection was not successful"); Thread.Sleep(10000); // Wait for intellisense to warm up @@ -82,19 +82,19 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests } }; - await testHelper.RequestChangeTextDocumentNotification(changeParams); + await testService.RequestChangeTextDocumentNotification(changeParams); Thread.Sleep(50); // If we just typed a space, request/resolve completion if (textToType[i] == ' ') { - var completions = await testHelper.RequestCompletion(queryTempFile.FilePath, textToType.Substring(0, i + 1), 0, i + 1); + var completions = await testService.RequestCompletion(queryTempFile.FilePath, textToType.Substring(0, i + 1), 0, i + 1); Assert.True(completions != null && completions.Length > 0, "Completion items list was null or empty"); Thread.Sleep(50); - var item = await testHelper.RequestResolveCompletion(completions[0]); + var item = await testService.RequestResolveCompletion(completions[0]); Assert.NotNull(item); } @@ -133,10 +133,10 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests } }; - await testHelper.RequestChangeTextDocumentNotification(changeParams2); + await testService.RequestChangeTextDocumentNotification(changeParams2); } - await testHelper.Disconnect(queryTempFile.FilePath); + await testService.Disconnect(queryTempFile.FilePath); } } @@ -152,10 +152,10 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests "SELECT COUNT(*) FROM sys.objects"; using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { // Connect - bool connected = await testHelper.Connect(queryTempFile.FilePath, ConnectionTestUtils.LocalhostConnection); + bool connected = await testService.Connect(TestServerType.OnPrem, string.Empty, queryTempFile.FilePath); Assert.True(connected, "Connection is successful"); // Run queries repeatedly @@ -163,7 +163,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests stopwatch.Start(); while (stopwatch.Elapsed < TimeSpan.FromMinutes(60)) { - var queryResult = await testHelper.RunQuery(queryTempFile.FilePath, queryToRun, 10000); + var queryResult = await testService.RunQueryAndWaitToComplete(queryTempFile.FilePath, queryToRun, 10000); Assert.NotNull(queryResult); Assert.NotNull(queryResult.BatchSummaries); @@ -173,15 +173,15 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests Assert.NotNull(queryResult.BatchSummaries[2].ResultSetSummaries); Assert.NotNull(queryResult.BatchSummaries[3].ResultSetSummaries); - Assert.NotNull(await testHelper.ExecuteSubset(queryTempFile.FilePath, 0, 0, 0, 7)); - Assert.NotNull(await testHelper.ExecuteSubset(queryTempFile.FilePath, 1, 0, 0, 7)); - Assert.NotNull(await testHelper.ExecuteSubset(queryTempFile.FilePath, 2, 0, 0, 7)); - Assert.NotNull(await testHelper.ExecuteSubset(queryTempFile.FilePath, 3, 0, 0, 1)); + Assert.NotNull(await testService.ExecuteSubset(queryTempFile.FilePath, 0, 0, 0, 7)); + Assert.NotNull(await testService.ExecuteSubset(queryTempFile.FilePath, 1, 0, 0, 7)); + Assert.NotNull(await testService.ExecuteSubset(queryTempFile.FilePath, 2, 0, 0, 7)); + Assert.NotNull(await testService.ExecuteSubset(queryTempFile.FilePath, 3, 0, 0, 1)); Thread.Sleep(500); } - await testHelper.Disconnect(queryTempFile.FilePath); + await testService.Disconnect(queryTempFile.FilePath); } } @@ -193,22 +193,23 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests { string ownerUri = "file:///my/test/file.sql"; - var connection = ConnectionTestUtils.LocalhostConnection; - connection.Connection.Pooling = false; - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { + var connection = await testService.GetConnectionParametersAsync(TestServerType.OnPrem); + connection.Connection.Pooling = false; + // Connect/disconnect repeatedly Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); while (stopwatch.Elapsed < TimeSpan.FromMinutes(60)) { // Connect - bool connected = await testHelper.Connect(ownerUri, connection); + bool connected = await testService.Connect(ownerUri, connection); Assert.True(connected, "Connection is successful"); // Disconnect - bool disconnected = await testHelper.Disconnect(ownerUri); + bool disconnected = await testService.Disconnect(ownerUri); Assert.True(disconnected, "Disconnect is successful"); } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/WorkspaceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/WorkspaceTests.cs similarity index 78% rename from test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/WorkspaceTests.cs rename to test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/WorkspaceTests.cs index 59814534..31a400d0 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/WorkspaceTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/WorkspaceTests.cs @@ -6,6 +6,7 @@ using System.IO; using System.Threading.Tasks; using Microsoft.SqlTools.ServiceLayer.Hosting.Contracts; +using Microsoft.SqlTools.ServiceLayer.Test.Common; using Xunit; namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests @@ -21,7 +22,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests [Fact] public async Task InitializeRequestTest() { - using (TestHelper testHelper = new TestHelper()) + using (TestServiceDriverProvider testService = new TestServiceDriverProvider()) { InitializeRequest initializeRequest = new InitializeRequest() { @@ -29,7 +30,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests Capabilities = new ClientCapabilities() }; - InitializeResult result = await testHelper.Driver.SendRequest(InitializeRequest.Type, initializeRequest); + InitializeResult result = await testService.Driver.SendRequest(InitializeRequest.Type, initializeRequest); Assert.NotNull(result); } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/project.json b/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/project.json new file mode 100644 index 00000000..9bf1efdd --- /dev/null +++ b/test/Microsoft.SqlTools.ServiceLayer.TestDriver.Tests/project.json @@ -0,0 +1,35 @@ +{ + "name": "Microsoft.SqlTools.ServiceLayer.TestDriver.Tests", + "version": "1.0.0-*", + "buildOptions": { + "debugType": "portable", + "emitEntryPoint": true + }, + "dependencies": { + "xunit": "2.1.0", + "dotnet-test-xunit": "1.0.0-rc2-192208-24", + "Microsoft.SqlTools.ServiceLayer": { + "target": "project" + }, + "Microsoft.SqlTools.ServiceLayer.TestDriver": "1.0.0-*", + "Microsoft.SqlTools.ServiceLayer.Test.Common": "1.0.0-*" + }, + "testRunner": "xunit", + "frameworks": { + "netcoreapp1.0": { + "dependencies": { + "Microsoft.NETCore.App": { + "type": "platform", + "version": "1.0.0" + } + }, + "imports": [ + "dotnet5.4", + "portable-net451+win8" + ] + } + }, + "runtimes": { + "win7-x64": {} + } +} diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/ConnectionTests.cs b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/ConnectionTests.cs deleted file mode 100644 index 8aefb01b..00000000 --- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/ConnectionTests.cs +++ /dev/null @@ -1,59 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System.Threading; -using System.Threading.Tasks; -using Microsoft.SqlTools.ServiceLayer.TestDriver.Utility; -using Xunit; - -namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests -{ - /// - /// Language Service end-to-end integration tests - /// - public class ConnectionTest - { - /// - /// Try to connect with invalid credentials - /// - [Fact] - public async Task InvalidConnection() - { - using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) - { - bool connected = await testHelper.Connect(queryTempFile.FilePath, ConnectionTestUtils.InvalidConnection, 300000); - Assert.False(connected, "Invalid connection is failed to connect"); - - await testHelper.Connect(queryTempFile.FilePath, ConnectionTestUtils.InvalidConnection, 300000); - - Thread.Sleep(1000); - - await testHelper.CancelConnect(queryTempFile.FilePath); - - await testHelper.Disconnect(queryTempFile.FilePath); - } - } - - /// - /// Validate list databases request - /// - [Fact] - public async Task ListDatabasesTest() - { - using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - using (TestHelper testHelper = new TestHelper()) - { - bool connected = await testHelper.Connect(queryTempFile.FilePath, ConnectionTestUtils.LocalhostConnection); - Assert.True(connected, "Connection successful"); - - var listDatabaseResult = await testHelper.ListDatabases(queryTempFile.FilePath); - Assert.True(listDatabaseResult.DatabaseNames.Length > 0); - - await testHelper.Disconnect(queryTempFile.FilePath); - } - } - } -} diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Utility/ConnectionTestUtils.cs b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Utility/ConnectionTestUtils.cs deleted file mode 100644 index 273f8f22..00000000 --- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Utility/ConnectionTestUtils.cs +++ /dev/null @@ -1,184 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices; -using Microsoft.SqlTools.ServiceLayer.Connection.Contracts; -using Newtonsoft.Json.Linq; - -namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Utility -{ - /// - /// Contains useful utility methods for testing connections - /// - public class ConnectionTestUtils - { - public static IEnumerable TestServers = InitTestServerNames(); - public static Setting Setting = InitSetting(); - - private static readonly Lazy azureTestServerConnection = - new Lazy(() => GetConnectionFromVsCodeSettings("***REMOVED***")); - - private static IEnumerable InitTestServerNames() - { - try - { - string testServerNamesFilePath = Environment.GetEnvironmentVariable("TestServerNamesFile"); - if (!string.IsNullOrEmpty(testServerNamesFilePath)) - { - string jsonFileContent = File.ReadAllText(testServerNamesFilePath); - return Newtonsoft.Json.JsonConvert.DeserializeObject>(jsonFileContent); - } - else - { - return Enumerable.Empty(); - } - } - catch (Exception ex) - { - Console.WriteLine("Failed to load the database connection server name settings. error: " + ex.Message); - return null; - } - } - - private static Setting InitSetting() - { - try - { - string settingsFileContents = GetSettingFileContent(); - Setting setting = Newtonsoft.Json.JsonConvert.DeserializeObject(settingsFileContents); - - return setting; - } - catch (Exception ex) - { - Console.WriteLine("Failed to load the connection settings. error: " + ex.Message); - return null; - } - } - - public static ConnectParams AzureTestServerConnection - { - get { return azureTestServerConnection.Value; } - } - - public static ConnectParams LocalhostConnection - { - get - { - return new ConnectParams() - { - Connection = new ConnectionDetails() - { - DatabaseName = "master", - ServerName = "localhost", - AuthenticationType = "Integrated" - } - }; - } - } - - public static ConnectParams InvalidConnection - { - get - { - return new ConnectParams() - { - Connection = new ConnectionDetails() - { - DatabaseName = "master", - ServerName = "localhost", - AuthenticationType = "SqlLogin", - UserName = "invalid", - Password = ".." - } - }; - } - } - - private static readonly Lazy sqlDataToolsAzureConnection = - new Lazy(() => GetConnectionFromVsCodeSettings("***REMOVED***")); - - public static ConnectParams SqlDataToolsAzureConnection - { - get { return sqlDataToolsAzureConnection.Value; } - } - - private static readonly Lazy dataToolsTelemetryAzureConnection = - new Lazy(() => GetConnectionFromVsCodeSettings("***REMOVED***")); - - private static string GetSettingFileContent() - { - string settingsFilename; - settingsFilename = Environment.GetEnvironmentVariable("SettingsFileName"); - if (string.IsNullOrEmpty(settingsFilename)) - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - settingsFilename = Environment.GetEnvironmentVariable("APPDATA") + @"\Code\User\settings.json"; - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - settingsFilename = Environment.GetEnvironmentVariable("HOME") + @"/Library/Application Support/Code/User/settings.json"; - } - else - { - settingsFilename = Environment.GetEnvironmentVariable("HOME") + @"/.config/Code/User/settings.json"; - } - } - string settingsFileContents = File.ReadAllText(settingsFilename); - - return settingsFileContents; - } - - public static ConnectParams DataToolsTelemetryAzureConnection - { - get { return dataToolsTelemetryAzureConnection.Value; } - } - - /// - /// Create a connection parameters object - /// - public static ConnectParams CreateConnectParams(string server, string database, string username, string password) - { - ConnectParams connectParams = new ConnectParams(); - connectParams.Connection = new ConnectionDetails(); - connectParams.Connection.ServerName = server; - connectParams.Connection.DatabaseName = database; - connectParams.Connection.UserName = username; - connectParams.Connection.Password = password; - connectParams.Connection.AuthenticationType = "SqlLogin"; - return connectParams; - } - - /// - /// Retrieve connection parameters from the vscode settings file - /// - public static ConnectParams GetConnectionFromVsCodeSettings(string serverName) - { - try - { - string settingsFileContents = GetSettingFileContent(); - - JObject root = JObject.Parse(settingsFileContents); - JArray connections = (JArray)root["mssql.connections"]; - - var connectionObject = connections.Where(x => x["server"].ToString() == serverName).First(); - - return CreateConnectParams( connectionObject["server"].ToString(), - connectionObject["database"].ToString(), - connectionObject["user"].ToString(), - connectionObject["password"].ToString()); - } - catch (Exception ex) - { - throw new Exception("Unable to load connection " + serverName + " from the vscode settings.json. Ensure the file is formatted correctly.", ex); - } - } - } -} diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/project.json b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/project.json index 71f0ce7a..783170a1 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/project.json +++ b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/project.json @@ -2,20 +2,7 @@ "name": "Microsoft.SqlTools.ServiceLayer.TestDriver", "version": "1.0.0-*", "buildOptions": { - "debugType": "portable", - "emitEntryPoint": true, - "embed": { - "includeFiles": [ - "Scripts/CreateTestDatabaseObjects.sql", - "Scripts/CreateTestDatabase.sql", - "Scripts/TestDbTableQueries.sql" - ] - }, - "publishOptions": { - "include": [ - "Scripts/AdventureWorks.sql" - ] - } + "debugType": "portable" }, "dependencies": { "xunit": "2.1.0",