Include ManagedBatchParser tests to improve code coverage (#793)

* Include ManagedBatchParser test to improve code coverage

* Fix some failing test cases and revert appveyor.yml
This commit is contained in:
Dhruva N
2019-04-22 17:35:48 -07:00
committed by Karl Burtram
parent 9e14336293
commit e9bf57bc67
24 changed files with 1033 additions and 438 deletions

View File

@@ -1,5 +1,5 @@
sudo: required
dist: trusty
dist: xenial
os:
- linux
@@ -7,7 +7,8 @@ os:
# - osx
mono: none
dotnet: 2.2.100-preview3-009430
dotnet: 2.2
# was dotnet: 2.2.100-preview3-009430
# safelist
branches:
@@ -37,5 +38,4 @@ script:
- dotnet build src/Microsoft.SqlTools.ServiceLayer
- dotnet test test/Microsoft.SqlTools.ServiceLayer.UnitTests
- dotnet build src/Microsoft.SqlTools.CoreServices
- dotnet test test/Microsoft.SqlTools.Hosting.UnitTests
- dotnet test test/Microsoft.SqlTools.Hosting.UnitTests

View File

@@ -30,4 +30,4 @@ after_test:
- cmd: packages\coveralls.io.1.3.4\tools\coveralls.net.exe --opencover coverage.xml
cache:
- '%USERPROFILE%\.nuget\packages'
- '%USERPROFILE%\.nuget\packages'

View File

@@ -93,6 +93,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.SqlTools.Hosting.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.SqlTools.ManagedBatchParser", "src\Microsoft.SqlTools.ManagedBatchParser\Microsoft.SqlTools.ManagedBatchParser.csproj", "{3F82F298-700A-48DF-8A69-D048DFBA782C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.SqlTools.ManagedBatchParser.IntegrationTests", "test\Microsoft.SqlTools.ManagedBatchParser.IntegrationTests\Microsoft.SqlTools.ManagedBatchParser.IntegrationTests.csproj", "{D3696EFA-FB1E-4848-A726-FF7B168AFB96}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -220,6 +222,12 @@ Global
{3F82F298-700A-48DF-8A69-D048DFBA782C}.Integration|Any CPU.Build.0 = Debug|Any CPU
{3F82F298-700A-48DF-8A69-D048DFBA782C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3F82F298-700A-48DF-8A69-D048DFBA782C}.Release|Any CPU.Build.0 = Release|Any CPU
{D3696EFA-FB1E-4848-A726-FF7B168AFB96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D3696EFA-FB1E-4848-A726-FF7B168AFB96}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D3696EFA-FB1E-4848-A726-FF7B168AFB96}.Integration|Any CPU.ActiveCfg = Debug|Any CPU
{D3696EFA-FB1E-4848-A726-FF7B168AFB96}.Integration|Any CPU.Build.0 = Debug|Any CPU
{D3696EFA-FB1E-4848-A726-FF7B168AFB96}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D3696EFA-FB1E-4848-A726-FF7B168AFB96}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -247,6 +255,7 @@ Global
{8EE5B06A-2EB2-4A47-812D-1D5B98D0F49A} = {AB9CA2B8-6F70-431C-8A1D-67479D8A7BE4}
{EF02F89F-417E-4A40-B7E6-B102EE2DF24D} = {2BBD7364-054F-4693-97CD-1C395E3E84A9}
{3F82F298-700A-48DF-8A69-D048DFBA782C} = {2BBD7364-054F-4693-97CD-1C395E3E84A9}
{D3696EFA-FB1E-4848-A726-FF7B168AFB96} = {AB9CA2B8-6F70-431C-8A1D-67479D8A7BE4}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B31CDF4B-2851-45E5-8C5F-BE97125D9DD8}

View File

@@ -238,6 +238,14 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser
if (LookaheadTokenType == LexerTokenType.Text)
{
string text = ResolveVariables(LookaheadToken, 0, null);
// This statement originally placed after the for loop, But it moved here, the reason is:
// When passing the long number like 999999999999999999999999, instead of throwing error
// it accept and iterate the loop
bool result = Int32.TryParse(text, out repeatCount);
if (result == false)
{
RaiseError(ErrorCode.InvalidNumber);
}
for (int i = 0; i < text.Length; i++)
{
if (Char.IsDigit(text[i]) == false)
@@ -245,11 +253,6 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser
RaiseError(ErrorCode.InvalidNumber);
}
}
bool result = Int32.TryParse(text, out repeatCount);
if (result == false)
{
RaiseError(ErrorCode.InvalidNumber);
}
Accept(LexerTokenType.Text);
AcceptWhitespaceOrComment();
}

View File

@@ -4,6 +4,7 @@
<TargetFramework>netstandard2.0</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems>
<DebugType>portable</DebugType>
</PropertyGroup>
<ItemGroup>
<Folder Include="Localization\transXliff\" />

View File

@@ -40,4 +40,4 @@ using System.Runtime.InteropServices;
[assembly: InternalsVisibleTo("Microsoft.SqlTools.ServiceLayer.IntegrationTests")]
[assembly: InternalsVisibleTo("Microsoft.SqlTools.ServiceLayer.Test.Common")]
[assembly: InternalsVisibleTo("MicrosoftSqlToolsServiceLayer")]
[assembly: InternalsVisibleTo("Microsoft.SqlTools.ManagedBatchParser.UnitTests")]
[assembly: InternalsVisibleTo("Microsoft.SqlTools.ManagedBatchParser.IntegrationTests")]

View File

@@ -11,6 +11,7 @@ REM Setup repo base path
REM backup current CSPROJ files
COPY /Y %REPOROOT%\src\Microsoft.SqlTools.Credentials\Microsoft.SqlTools.Credentials.csproj %REPOROOT%\src\Microsoft.SqlTools.Credentials\Microsoft.SqlTools.Credentials.csproj.BAK
COPY /Y %REPOROOT%\src\Microsoft.SqlTools.Hosting\Microsoft.SqlTools.Hosting.csproj %REPOROOT%\src\Microsoft.SqlTools.Hosting\Microsoft.SqlTools.Hosting.csproj.BAK
COPY /Y %REPOROOT%\src\Microsoft.SqlTools.ManagedBatchParser\Microsoft.SqlTools.ManagedBatchParser.csproj %REPOROOT%\src\Microsoft.SqlTools.ManagedBatchParser\Microsoft.SqlTools.ManagedBatchParser.csproj.BAK
COPY /Y %REPOROOT%\src\Microsoft.SqlTools.ServiceLayer\Microsoft.SqlTools.ServiceLayer.csproj %REPOROOT%\src\Microsoft.SqlTools.ServiceLayer\Microsoft.SqlTools.ServiceLayer.csproj.BAK
COPY /Y %REPOROOT%\src\Microsoft.SqlTools.ResourceProvider\Microsoft.SqlTools.ResourceProvider.csproj %REPOROOT%\src\Microsoft.SqlTools.ResourceProvider\Microsoft.SqlTools.ResourceProvider.csproj.BAK
COPY /Y %REPOROOT%\src\Microsoft.SqlTools.ResourceProvider.Core\Microsoft.SqlTools.ResourceProvider.Core.csproj %REPOROOT%\src\Microsoft.SqlTools.ResourceProvider.Core\Microsoft.SqlTools.ResourceProvider.Core.csproj.BAK
@@ -20,6 +21,7 @@ REM switch PDB type to Full since that is required by OpenCover for now
REM we should remove this step on OpenCover supports portable PDB
cscript /nologo ReplaceText.vbs %REPOROOT%\src\Microsoft.SqlTools.Credentials\Microsoft.SqlTools.Credentials.csproj portable full
cscript /nologo ReplaceText.vbs %REPOROOT%\src\Microsoft.SqlTools.Hosting\Microsoft.SqlTools.Hosting.csproj portable full
cscript /nologo ReplaceText.vbs %REPOROOT%\src\Microsoft.SqlTools.ManagedBatchParser\Microsoft.SqlTools.ManagedBatchParser.csproj portable full
cscript /nologo ReplaceText.vbs %REPOROOT%\src\Microsoft.SqlTools.ServiceLayer\Microsoft.SqlTools.ServiceLayer.csproj portable full
cscript /nologo ReplaceText.vbs %REPOROOT%\src\Microsoft.SqlTools.ResourceProvider\Microsoft.SqlTools.ResourceProvider.csproj portable full
cscript /nologo ReplaceText.vbs %REPOROOT%\src\Microsoft.SqlTools.ResourceProvider.Core\Microsoft.SqlTools.ResourceProvider.Core.csproj portable full
@@ -29,7 +31,9 @@ REM rebuild the SqlToolsService project
dotnet restore %REPOROOT%\src\Microsoft.SqlTools.Credentials\Microsoft.SqlTools.Credentials.csproj
dotnet build %REPOROOT%\src\Microsoft.SqlTools.Credentials\Microsoft.SqlTools.Credentials.csproj %DOTNETCONFIG%
dotnet restore %REPOROOT%\src\Microsoft.SqlTools.Hosting\Microsoft.SqlTools.Hosting.csproj
dotnet build %REPOROOT%\src\Microsoft.SqlTools.Hosting\Microsoft.SqlTools.Hosting.csproj %DOTNETCONFIG%
dotnet build %REPOROOT%\src\Microsoft.SqlTools.Hosting\Microsoft.SqlTools.Hosting.csproj %DOTNETCONFIG%
dotnet restore %REPOROOT%\src\Microsoft.SqlTools.ManagedBatchParser\Microsoft.SqlTools.ManagedBatchParser.csproj
dotnet build %REPOROOT%\src\Microsoft.SqlTools.ManagedBatchParser\Microsoft.SqlTools.ManagedBatchParser.csproj %DOTNETCONFIG% -r win7-x64
dotnet restore %REPOROOT%\src\Microsoft.SqlTools.ServiceLayer\Microsoft.SqlTools.ServiceLayer.csproj
dotnet build %REPOROOT%\src\Microsoft.SqlTools.ServiceLayer\Microsoft.SqlTools.ServiceLayer.csproj %DOTNETCONFIG% -r win7-x64
dotnet restore %REPOROOT%\src\Microsoft.SqlTools.ResourceProvider\Microsoft.SqlTools.ResourceProvider.csproj
@@ -50,6 +54,8 @@ dotnet restore %REPOROOT%\test\Microsoft.SqlTools.ServiceLayer.IntegrationTests\
dotnet build %REPOROOT%\test\Microsoft.SqlTools.ServiceLayer.IntegrationTests\Microsoft.SqlTools.ServiceLayer.IntegrationTests.csproj %DOTNETCONFIG%
dotnet restore %REPOROOT%\test\Microsoft.SqlTools.ServiceLayer.TestDriver.Tests\Microsoft.SqlTools.ServiceLayer.TestDriver.Tests.csproj
dotnet build %REPOROOT%\test\Microsoft.SqlTools.ServiceLayer.TestDriver.Tests\Microsoft.SqlTools.ServiceLayer.TestDriver.Tests.csproj %DOTNETCONFIG%
dotnet restore %REPOROOT%\test\Microsoft.SqlTools.ManagedBatchParser.IntegrationTests\Microsoft.SqlTools.ManagedBatchParser.IntegrationTests.csproj
dotnet build %REPOROOT%\test\Microsoft.SqlTools.ManagedBatchParser.IntegrationTests\Microsoft.SqlTools.ManagedBatchParser.IntegrationTests.csproj %DOTNETCONFIG%
SET TEST_SERVER=localhost
SET SQLTOOLSSERVICE_EXE=%REPOROOT%\src\Microsoft.SqlTools.ServiceLayer\bin\Integration\netcoreapp2.2\win7-x64\MicrosoftSqlToolsServiceLayer.exe
@@ -61,23 +67,27 @@ REM dotnet.exe test %REPOROOT%\test\Microsoft.SqlTools.ServiceLayer.TestDriver.T
SET SERVICECODECOVERAGE=FALSE
%CODECOVERAGETOOL% -mergeoutput -register:user -target:dotnet.exe -targetargs:"test %REPOROOT%\test\Microsoft.SqlTools.ServiceLayer.TestDriver.Tests\Microsoft.SqlTools.ServiceLayer.TestDriver.Tests.csproj %DOTNETCONFIG%" -oldstyle -filter:"+[Microsoft.SqlTools.*]* +[MicrosoftSqlToolsServiceLayer*]* +[MicrosoftSqlToolsCredentials*]* -[xunit*]* -[Microsoft.SqlTools.ServiceLayer.Test*]* -[Microsoft.SqlTools.ServiceLayer.*Test*] -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Agent.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.DisasterRecovery.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Profiler.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Admin.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Management.*" -output:coverage.xml -hideskipped:All -searchdirs:%REPOROOT%\test\Microsoft.SqlTools.ServiceLayer.TestDriver.Tests\bin\Debug\netcoreapp2.2
%CODECOVERAGETOOL% -mergeoutput -register:user -target:dotnet.exe -targetargs:"test %REPOROOT%\test\Microsoft.SqlTools.ServiceLayer.TestDriver.Tests\Microsoft.SqlTools.ServiceLayer.TestDriver.Tests.csproj %DOTNETCONFIG%" -oldstyle -filter:"+[Microsoft.SqlTools.*]* +[MicrosoftSqlToolsServiceLayer*]* +[MicrosoftSqlToolsCredentials*]* -[xunit*]* -[Microsoft.SqlTools.ServiceLayer.Test*]* -[Microsoft.SqlTools.ServiceLayer.*Test*]* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Agent.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.DisasterRecovery.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Profiler.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Admin.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Management.*" -output:coverage.xml -hideskipped:All -searchdirs:%REPOROOT%\test\Microsoft.SqlTools.ServiceLayer.TestDriver.Tests\bin\Debug\netcoreapp2.2
%CODECOVERAGETOOL% -mergeoutput -register:user -target:dotnet.exe -targetargs:"test %REPOROOT%\test\Microsoft.SqlTools.ServiceLayer.UnitTests\Microsoft.SqlTools.ServiceLayer.UnitTests.csproj %DOTNETCONFIG%" -oldstyle -filter:"+[Microsoft.SqlTools.*]* +[MicrosoftSqlToolsServiceLayer*]* +[MicrosoftSqlToolsCredentials*]* -[xunit*]* -[Microsoft.SqlTools.ServiceLayer.*Test*]* -[Microsoft.SqlTools.ServiceLayer.Test*]* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Agent.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.DisasterRecovery.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Profiler.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Admin.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Management.*" -output:coverage.xml -hideskipped:All -searchdirs:%REPOROOT%\test\Microsoft.SqlTools.ServiceLayer.UnitTests\bin\Debug\netcoreapp2.2
%CODECOVERAGETOOL% -mergeoutput -register:user -target:dotnet.exe -targetargs:"test %REPOROOT%\test\Microsoft.SqlTools.ServiceLayer.UnitTests\Microsoft.SqlTools.ServiceLayer.UnitTests.csproj %DOTNETCONFIG%" -oldstyle -filter:"+[Microsoft.SqlTools.*]* +[MicrosoftSqlToolsServiceLayer*]* +[MicrosoftSqlToolsCredentials*]* -[xunit*]* -[Microsoft.SqlTools.ServiceLayer.Test*]* -[Microsoft.SqlTools.ServiceLayer.*Test*]* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Agent.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.DisasterRecovery.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Profiler.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Admin.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Management.*" -output:coverage.xml -hideskipped:All -searchdirs:%REPOROOT%\test\Microsoft.SqlTools.ServiceLayer.UnitTests\bin\Debug\netcoreapp2.2
%CODECOVERAGETOOL% -mergeoutput -register:user -target:dotnet.exe -targetargs:"test %REPOROOT%\test\Microsoft.SqlTools.ServiceLayer.IntegrationTests\Microsoft.SqlTools.ServiceLayer.IntegrationTests.csproj %DOTNETCONFIG%" -oldstyle -filter:"+[Microsoft.SqlTools.*]* +[MicrosoftSqlToolsServiceLayer*]* +[MicrosoftSqlToolsCredentials*]* [Microsoft.SqlTools.*]* -[xunit*]* -[Microsoft.SqlTools.ServiceLayer.Test*]* -[Microsoft.SqlTools.ServiceLayer.*Test*]* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Agent.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.DisasterRecovery.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Profiler.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Admin.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Management.*" -output:coverage.xml -hideskipped:All -searchdirs:%REPOROOT%\test\Microsoft.SqlTools.ServiceLayer.IntegrationTests\bin\Debug\netcoreapp2.2
%CODECOVERAGETOOL% -mergeoutput -register:user -target:dotnet.exe -targetargs:"test %REPOROOT%\test\Microsoft.SqlTools.ServiceLayer.IntegrationTests\Microsoft.SqlTools.ServiceLayer.IntegrationTests.csproj %DOTNETCONFIG%" -oldstyle -filter:"+[Microsoft.SqlTools.*]* +[MicrosoftSqlToolsServiceLayer*]* +[MicrosoftSqlToolsCredentials*]* -[xunit*]* -[Microsoft.SqlTools.ServiceLayer.Test*]* -[Microsoft.SqlTools.ServiceLayer.*Test*]* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Agent.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.DisasterRecovery.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Profiler.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Admin.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Management.*" -output:coverage.xml -hideskipped:All -searchdirs:%REPOROOT%\test\Microsoft.SqlTools.ServiceLayer.IntegrationTests\bin\Debug\netcoreapp2.2
%CODECOVERAGETOOL% -mergeoutput -register:user -target:dotnet.exe -targetargs:"test %REPOROOT%\test\Microsoft.SqlTools.ManagedBatchParser.IntegrationTests\Microsoft.SqlTools.ManagedBatchParser.IntegrationTests.csproj %DOTNETCONFIG%" -oldstyle -filter:"+[Microsoft.SqlTools.*]* +[MicrosoftSqlToolsServiceLayer*]* +[MicrosoftSqlToolsCredentials*]* -[xunit*]* -[Microsoft.SqlTools.ServiceLayer.Test*]* -[Microsoft.SqlTools.ServiceLayer.*Test*]* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Agent.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.DisasterRecovery.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Profiler.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Admin.* -[MicrosoftSqlToolsServiceLayer]Microsoft.SqlTools.ServiceLayer.Management.*" -output:coverage.xml -hideskipped:All -searchdirs:%REPOROOT%\test\Microsoft.SqlTools.ManagedBatchParser.IntegrationTests\bin\Debug\netcoreapp2.2
REM Generate the report
"%WORKINGDIR%packages\OpenCoverToCoberturaConverter.0.2.4.0\tools\OpenCoverToCoberturaConverter.exe" -input:coverage.xml -output:outputCobertura.xml -sources:%REPOROOT%\src\Microsoft.SqlTools.ServiceLayer
"%WORKINGDIR%packages\ReportGenerator.2.4.5.0\tools\ReportGenerator.exe" "-reports:coverage.xml" "-targetdir:%WORKINGDIR%\reports"
"%WORKINGDIR%packages\OpenCoverToCoberturaConverter.0.2.4.0\tools\OpenCoverToCoberturaConverter.exe" -input:coverage.xml -output:outputCobertura.xml -sources:%REPOROOT%\src\Microsoft.SqlTools.ServiceLayer
"%WORKINGDIR%packages\ReportGenerator.2.4.5.0\tools\ReportGenerator.exe" "-reports:coverage.xml" "-targetdir:%WORKINGDIR%\reports"
REM restore original project.json
COPY /Y %REPOROOT%\src\Microsoft.SqlTools.ServiceLayer\Microsoft.SqlTools.ServiceLayer.csproj.BAK %REPOROOT%\src\Microsoft.SqlTools.ServiceLayer\Microsoft.SqlTools.ServiceLayer.csproj
DEL %REPOROOT%\src\Microsoft.SqlTools.ServiceLayer\Microsoft.SqlTools.ServiceLayer.csproj.BAK
COPY /Y %REPOROOT%\src\Microsoft.SqlTools.Credentials\Microsoft.SqlTools.Credentials.csproj.BAK %REPOROOT%\src\Microsoft.SqlTools.Credentials\Microsoft.SqlTools.Credentials.csproj
DEL %REPOROOT%\src\Microsoft.SqlTools.Credentials\Microsoft.SqlTools.Credentials.csproj.BAK
COPY /Y %REPOROOT%\src\Microsoft.SqlTools.Hosting\Microsoft.SqlTools.Hosting.csproj.BAK %REPOROOT%\src\Microsoft.SqlTools.Hosting\Microsoft.SqlTools.Hosting.csproj
DEL %REPOROOT%\src\Microsoft.SqlTools.Hosting\Microsoft.SqlTools.Hosting.csproj.BAK
COPY /Y %REPOROOT%\src\Microsoft.SqlTools.ManagedBatchParser\Microsoft.SqlTools.ManagedBatchParser.csproj.BAK %REPOROOT%\src\Microsoft.SqlTools.ManagedBatchParser\Microsoft.SqlTools.ManagedBatchParser.csproj
DEL %REPOROOT%\src\Microsoft.SqlTools.ManagedBatchParser\Microsoft.SqlTools.ManagedBatchParser.csproj.BAK
COPY /Y %REPOROOT%\src\Microsoft.SqlTools.ServiceLayer\Microsoft.SqlTools.ServiceLayer.csproj.BAK %REPOROOT%\src\Microsoft.SqlTools.ServiceLayer\Microsoft.SqlTools.ServiceLayer.csproj
DEL %REPOROOT%\src\Microsoft.SqlTools.ServiceLayer\Microsoft.SqlTools.ServiceLayer.csproj.BAK
COPY /Y %REPOROOT%\src\Microsoft.SqlTools.ResourceProvider\Microsoft.SqlTools.ResourceProvider.csproj.BAK %REPOROOT%\src\Microsoft.SqlTools.ResourceProvider\Microsoft.SqlTools.ResourceProvider.csproj
DEL %REPOROOT%\src\Microsoft.SqlTools.ResourceProvider\Microsoft.SqlTools.ResourceProvider.csproj.BAK
COPY /Y %REPOROOT%\src\Microsoft.SqlTools.ResourceProvider.Core\Microsoft.SqlTools.ResourceProvider.Core.csproj.BAK %REPOROOT%\src\Microsoft.SqlTools.ResourceProvider.Core\Microsoft.SqlTools.ResourceProvider.Core.csproj

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="xunit.methodDisplay" value="method" />
</appSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
</configuration>

View File

@@ -0,0 +1,8 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Xunit;
[assembly: CollectionBehavior(DisableTestParallelization = true)]

View File

@@ -43,10 +43,10 @@ namespace Microsoft.SqlTools.ManagedBatchParser.UnitTests.BatchParser
public void OnBatchResultSetFinished(object sender, EventArgs args) { }
/// <summary>
/// fired when the batch recieved cancel request BEFORE it
/// fired when the batch recieved cancel request BEFORE it
/// initiates cancel operation. Note that it is fired from a
/// different thread then the one used to kick off execution
/// </summary>
public void OnBatchCancelling(object sender, EventArgs args) { }
}
}
}

View File

@@ -7,7 +7,6 @@ using System;
using System.IO;
using Microsoft.SqlTools.ServiceLayer.BatchParser;
using Microsoft.SqlTools.ServiceLayer.BatchParser.ExecutionEngineCode;
using Moq;
using Xunit;
namespace Microsoft.SqlTools.ManagedBatchParser.UnitTests.BatchParser
@@ -16,6 +15,7 @@ namespace Microsoft.SqlTools.ManagedBatchParser.UnitTests.BatchParser
{
private BatchParserSqlCmd bpcmd;
private PositionStruct testPOS;
public BatchParserSqlCmdTests()
{
bpcmd = new BatchParserSqlCmd();
@@ -85,7 +85,6 @@ namespace Microsoft.SqlTools.ManagedBatchParser.UnitTests.BatchParser
string outString = "out";
var result = bpcmd.Include(null, out textReader, out outString);
Assert.Equal(result, BatchParserAction.Abort);
}
[Fact]
@@ -113,6 +112,5 @@ namespace Microsoft.SqlTools.ManagedBatchParser.UnitTests.BatchParser
var result = bpcmd.GetVariable(testPOS, "variable1");
Assert.Null(result);
}
}
}
}

View File

@@ -0,0 +1,557 @@
//
// 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.Data.SqlClient;
using System.Globalization;
using System.IO;
using System.Text;
using Microsoft.SqlTools.ManagedBatchParser.IntegrationTests.TSQLExecutionEngine;
using Microsoft.SqlTools.ManagedBatchParser.IntegrationTests.Utility;
using Microsoft.SqlTools.ServiceLayer.BatchParser;
using Microsoft.SqlTools.ServiceLayer.BatchParser.ExecutionEngineCode;
using Microsoft.SqlTools.ServiceLayer.Test.Common;
using Microsoft.SqlTools.ServiceLayer.Test.Common.Baselined;
using Xunit;
namespace Microsoft.SqlTools.ManagedBatchParser.UnitTests.BatchParser
{
public class BatchParserTests : BaselinedTest
{
private bool testFailed = false;
private static ScriptExecutionResult executionResult = ScriptExecutionResult.All;
private const string CONNECTION_STRING = "Data Source=.;Initial Catalog=master;Integrated Security=True";
public BatchParserTests()
{
InitializeTest();
}
public void InitializeTest()
{
CategoryName = "BatchParser";
this.TraceOutputDirectory = RunEnvironmentInfo.GetTraceOutputLocation();
TestInitialize();
}
[Fact]
public void VerifyThrowOnUnresolvedVariable()
{
string script = "print '$(NotDefined)'";
StringBuilder output = new StringBuilder();
TestCommandHandler handler = new TestCommandHandler(output);
IVariableResolver resolver = new TestVariableResolver(new StringBuilder());
using (Parser p = new Parser(
handler,
resolver,
new StringReader(script),
"test"))
{
p.ThrowOnUnresolvedVariable = true;
handler.SetParser(p);
Assert.Throws<BatchParserException>(() => p.Parse());
}
}
/// <summary>
/// Variable parameter in powershell: Specifies, as a string array, a sqlcmd scripting variable
/// for use in the sqlcmd script, and sets a value for the variable.
/// </summary>
[Fact]
public void VerifyVariableResolverUsingVaribleParameter()
{
string query = @" Invoke-Sqlcmd -Query ""SELECT `$(calcOne)"" -Variable ""calcOne = 10 + 20"" ";
TestCommandHandler handler = new TestCommandHandler(new StringBuilder());
IVariableResolver resolver = new TestVariableResolver(new StringBuilder());
using (Parser p = new Parser(
handler,
resolver,
new StringReader(query),
"test"))
{
p.ThrowOnUnresolvedVariable = true;
handler.SetParser(p);
Assert.Throws<BatchParserException>(() => p.Parse());
}
}
// Verify the starting identifier of Both parameter and variable are same.
[Fact]
public void VerifyVariableResolverIsStartIdentifierChar()
{
// instead of using variable calcOne, I purposely used In-variable 0alcOne
string query = @" Invoke-Sqlcmd -Query ""SELECT `$(0alcOne)"" -Variable ""calcOne1 = 1"" ";
TestCommandHandler handler = new TestCommandHandler(new StringBuilder());
IVariableResolver resolver = new TestVariableResolver(new StringBuilder());
using (Parser p = new Parser(
handler,
resolver,
new StringReader(query),
"test"))
{
p.ThrowOnUnresolvedVariable = true;
handler.SetParser(p);
Assert.Throws<BatchParserException>(() => p.Parse());
}
}
// Verify all the characters inside variable are valid Identifier.
[Fact]
public void VerifyVariableResolverIsIdentifierChar()
{
// instead of using variable calcOne, I purposely used In-variable 0alcOne
string query = @" Invoke-Sqlcmd -Query ""SELECT `$(ca@lcOne)"" -Variable ""calcOne = 1"" ";
TestCommandHandler handler = new TestCommandHandler(new StringBuilder());
IVariableResolver resolver = new TestVariableResolver(new StringBuilder());
using (Parser p = new Parser(
handler,
resolver,
new StringReader(query),
"test"))
{
p.ThrowOnUnresolvedVariable = true;
handler.SetParser(p);
Assert.Throws<BatchParserException>(() => p.Parse());
}
}
// Verify the execution by passing long value , Except a exception.
[Fact]
public void VerifyInvalidNumber()
{
string query = @" SELECT 1+1
GO 999999999999999999999999999999999999999";
TestCommandHandler handler = new TestCommandHandler(new StringBuilder());
IVariableResolver resolver = new TestVariableResolver(new StringBuilder());
using (Parser p = new Parser(
handler,
resolver,
new StringReader(query),
"test"))
{
p.ThrowOnUnresolvedVariable = true;
handler.SetParser(p);
// This test will fail because we are passing invalid number.
// Exception will be raised from ParseGo()
Assert.Throws<BatchParserException>(() => p.Parse());
}
}
// Verify the Batch execution is executed successfully.
[Fact]
public void VerifyExecute()
{
Batch batch = new Batch(sqlText: "SELECT 1+1", isResultExpected: true, execTimeout: 15);
using (SqlConnection con = new SqlConnection(CONNECTION_STRING))
{
con.Open();
if (con.State.ToString().ToLower() == "open")
{
executionResult = batch.Execute(con, ShowPlanType.AllShowPlan);
}
}
Assert.Equal<ScriptExecutionResult>(ScriptExecutionResult.Success, executionResult);
}
// Verify the exeception is handled by passing invalid keyword.
[Fact]
public void VerifyHandleExceptionMessage()
{
Batch batch = new Batch(sqlText: "SEL@ECT 1+1", isResultExpected: true, execTimeout: 15);
using (SqlConnection con = new SqlConnection(CONNECTION_STRING))
{
con.Open();
if (con.State.ToString().ToLower() == "open")
{
ScriptExecutionResult result = batch.Execute(con, ShowPlanType.AllShowPlan);
}
}
ScriptExecutionResult finalResult = (batch.RowsAffected > 0) ? ScriptExecutionResult.Success : ScriptExecutionResult.Failure;
Assert.Equal<ScriptExecutionResult>(finalResult, ScriptExecutionResult.Failure);
}
// Verify the passing query has valid text.
[Fact]
public void VerifyHasValidText()
{
Batch batch = new Batch(sqlText: null, isResultExpected: true, execTimeout: 15);
ScriptExecutionResult finalResult = ScriptExecutionResult.All;
using (SqlConnection con = new SqlConnection(CONNECTION_STRING))
{
con.Open();
if (con.State.ToString().ToLower() == "open")
{
ScriptExecutionResult result = batch.Execute(con, ShowPlanType.AllShowPlan);
}
}
finalResult = (batch.RowsAffected > 0) ? ScriptExecutionResult.Success : ScriptExecutionResult.Failure;
Assert.Equal<ScriptExecutionResult>(finalResult, ScriptExecutionResult.Failure);
}
// Verify the cancel functionality is working fine.
[Fact]
public void VerifyCancel()
{
ScriptExecutionResult result = ScriptExecutionResult.All;
Batch batch = new Batch(sqlText: "SELECT 1+1", isResultExpected: true, execTimeout: 15);
using (SqlConnection con = new SqlConnection(CONNECTION_STRING))
{
con.Open();
if (con.State.ToString().ToLower() == "open")
{
batch.Cancel();
result = batch.Execute(con, ShowPlanType.AllShowPlan);
}
}
Assert.Equal<ScriptExecutionResult>(result, ScriptExecutionResult.Cancel);
}
// verify weather lexer can consume token for SqlCmd variable
[Fact]
public void VerifyLexerSetState()
{
try
{
string query = ":SETVAR a 10";
var inputStream = GenerateStreamFromString(query);
using (Lexer lexer = new Lexer(new StreamReader(inputStream), "Test.sql"))
{
lexer.ConsumeToken();
}
executionResult = ScriptExecutionResult.Success;
}
catch (Exception ex)
{
executionResult = ScriptExecutionResult.Failure;
}
// we doesn't expect any exception or testCase failures
Assert.Equal<ScriptExecutionResult>(ScriptExecutionResult.Success, executionResult);
}
// Verify the custom exception functionality by raising user defined error.
[Fact]
public void VerifyCustomBatchParserException()
{
string message = "This is userDefined Error";
Token token = new Token(LexerTokenType.Text, new PositionStruct(), new PositionStruct(), message, "test");
BatchParserException batchParserException = new BatchParserException(ErrorCode.VariableNotDefined, token, message);
try
{
throw new BatchParserException(ErrorCode.UnrecognizedToken, token, "test");
}
catch (Exception ex)
{
Assert.Equal(batchParserException.ErrorCode.ToString(), ErrorCode.VariableNotDefined.ToString());
Assert.Equal(message, batchParserException.Text);
Assert.Equal(LexerTokenType.Text.ToString(), batchParserException.TokenType.ToString());
Assert.IsType<BatchParserException>(ex);
}
}
// Verify whether the executionEngine execute script
[Fact]
public void VerifyExecuteScript()
{
using (ExecutionEngine executionEngine = new ExecutionEngine())
{
string query = @"SELECT 1+2
Go 2";
using (SqlConnection con = new SqlConnection(CONNECTION_STRING))
{
con.Open();
TestExecutor testExecutor = new TestExecutor(query, con, new ExecutionEngineConditions());
testExecutor.Run();
ScriptExecutionResult result = (testExecutor.ExecutionResult == ScriptExecutionResult.Success) ? ScriptExecutionResult.Success : ScriptExecutionResult.Failure;
Assert.Equal<ScriptExecutionResult>(ScriptExecutionResult.Success, result);
}
}
}
// Verify whether the batchParser execute SqlCmd.
//[Fact] // This Testcase should execute and pass, But it is failing now.
public void VerifyIsSqlCmd()
{
using (ExecutionEngine executionEngine = new ExecutionEngine())
{
string query = @"sqlcmd -Q ""select 1 + 2 as col"" ";
using (SqlConnection con = new SqlConnection(CONNECTION_STRING))
{
con.Open();
TestExecutor testExecutor = new TestExecutor(query, con, new ExecutionEngineConditions());
testExecutor.Run();
Assert.True(testExecutor.ResultCountQueue.Count >= 1);
}
}
}
// Verify whether the executionEngine execute Batch
[Fact]
public void VerifyExecuteBatch()
{
using (ExecutionEngine executionEngine = new ExecutionEngine())
{
string query = "SELECT 1+2";
using (SqlConnection con = new SqlConnection(CONNECTION_STRING))
{
con.Open();
executionEngine.BatchParserExecutionFinished += OnBatchParserExecutionFinished;
executionEngine.ExecuteBatch(new ScriptExecutionArgs(query, con, 15, new ExecutionEngineConditions(), new BatchParserMockEventHandler()));
Assert.Equal(ScriptExecutionResult.Success, executionResult);
}
}
}
// Capture the event once batch finish execution.
private void OnBatchParserExecutionFinished(object sender, BatchParserExecutionFinishedEventArgs e)
{
executionResult = e.ExecutionResult;
}
[Fact]
public void CanceltheBatch()
{
Batch batch = new Batch();
batch.Cancel();
}
private static Stream GenerateStreamFromString(string s)
{
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
writer.Write(s);
writer.Flush();
stream.Position = 0;
return stream;
}
public void TokenizeWithLexer(string filename, StringBuilder output)
{
// Create a new file by changing CRLFs to LFs and generate a new steam
// or the tokens generated by the lexer will always have off by one errors
string input = File.ReadAllText(filename).Replace("\r\n", "\n");
var inputStream = GenerateStreamFromString(input);
using (Lexer lexer = new Lexer(new StreamReader(inputStream), filename))
{
string inputText = File.ReadAllText(filename);
inputText = inputText.Replace("\r\n", "\n");
StringBuilder roundtripTextBuilder = new StringBuilder();
StringBuilder outputBuilder = new StringBuilder();
StringBuilder tokenizedInput = new StringBuilder();
bool lexerError = false;
Token token = null;
try
{
do
{
lexer.ConsumeToken();
token = lexer.CurrentToken;
roundtripTextBuilder.Append(token.Text.Replace("\r\n", "\n"));
outputBuilder.AppendLine(GetTokenString(token));
tokenizedInput.Append('[').Append(GetTokenCode(token.TokenType)).Append(':').Append(token.Text.Replace("\r\n", "\n")).Append(']');
} while (token.TokenType != LexerTokenType.Eof);
}
catch (BatchParserException ex)
{
lexerError = true;
outputBuilder.AppendLine(string.Format(CultureInfo.CurrentCulture, "[ERROR: code {0} at {1} - {2} in {3}, message: {4}]", ex.ErrorCode, GetPositionString(ex.Begin), GetPositionString(ex.End), GetFilenameOnly(ex.Begin.Filename), ex.Message));
}
output.AppendLine("Lexer tokenized input:");
output.AppendLine("======================");
output.AppendLine(tokenizedInput.ToString());
output.AppendLine("Tokens:");
output.AppendLine("=======");
output.AppendLine(outputBuilder.ToString());
if (lexerError == false)
{
// Verify that all text from tokens can be recombined into original string
Assert.Equal<string>(inputText, roundtripTextBuilder.ToString());
}
}
}
private string GetTokenCode(LexerTokenType lexerTokenType)
{
switch (lexerTokenType)
{
case LexerTokenType.Text:
return "T";
case LexerTokenType.Whitespace:
return "WS";
case LexerTokenType.NewLine:
return "NL";
case LexerTokenType.Comment:
return "C";
default:
return lexerTokenType.ToString();
}
}
private static void CopyToOutput(string sourceDirectory, string filename)
{
File.Copy(Path.Combine(sourceDirectory, filename), filename, true);
FileUtilities.SetFileReadWrite(filename);
}
// [Fact]
public void BatchParserTest()
{
CopyToOutput(FilesLocation, "TS-err-cycle1.txt");
CopyToOutput(FilesLocation, "cycle2.txt");
Start("err-blockComment");
Start("err-blockComment2");
Start("err-varDefinition");
Start("err-varDefinition2");
Start("err-varDefinition3");
Start("err-varDefinition4");
Start("err-varDefinition5");
Start("err-varDefinition6");
Start("err-varDefinition7");
Start("err-varDefinition8");
Start("err-varDefinition9");
Start("err-variableRef");
Start("err-variableRef2");
Start("err-variableRef3");
Start("err-variableRef4");
Start("err-cycle1");
Start("input");
Start("input2");
Start("pass-blockComment");
Start("pass-lineComment");
Start("pass-lineComment2");
Start("pass-noBlockComments");
Start("pass-noLineComments");
Start("pass-varDefinition");
Start("pass-varDefinition2");
Start("pass-varDefinition3");
Start("pass-varDefinition4");
Start("pass-command-and-comment");
Assert.False(testFailed, "At least one of test cases failed. Check output for details.");
}
public void TestParser(string filename, StringBuilder output)
{
try
{
// Create a new file by changing CRLFs to LFs and generate a new steam
// or the tokens generated by the lexer will always have off by one errors
TestCommandHandler commandHandler = new TestCommandHandler(output);
string input = File.ReadAllText(filename).Replace("\r\n", "\n");
var inputStream = GenerateStreamFromString(input);
StreamReader streamReader = new StreamReader(inputStream);
using (Parser parser = new Parser(
commandHandler,
new TestVariableResolver(output),
streamReader,
filename))
{
commandHandler.SetParser(parser);
parser.Parse();
}
}
catch (BatchParserException ex)
{
output.AppendLine(string.Format(CultureInfo.CurrentCulture, "[PARSER ERROR: code {0} at {1} - {2} in {3}, token text: {4}, message: {5}]", ex.ErrorCode, GetPositionString(ex.Begin), GetPositionString(ex.End), GetFilenameOnly(ex.Begin.Filename), ex.Text, ex.Message));
}
}
private string GetPositionString(PositionStruct pos)
{
return string.Format(CultureInfo.InvariantCulture, "{0}:{1} [{2}]", pos.Line, pos.Column, pos.Offset);
}
private string GetTokenString(Token token)
{
if (token == null)
{
return "(null)";
}
else
{
string tokenText = token.Text;
if (tokenText != null)
{
tokenText = tokenText.Replace("\r\n", "\\n").Replace("\n", "\\n").Replace("\r", "\\r").Replace("\t", "\\t");
}
string tokenFilename = token.Filename;
tokenFilename = GetFilenameOnly(tokenFilename);
return string.Format(CultureInfo.CurrentCulture, "[Token {0} at {1}({2}:{3} [{4}] - {5}:{6} [{7}]): '{8}']",
token.TokenType,
tokenFilename,
token.Begin.Line, token.Begin.Column, token.Begin.Offset,
token.End.Line, token.End.Column, token.End.Offset,
tokenText);
}
}
internal static string GetFilenameOnly(string fullPath)
{
return fullPath != null ? Path.GetFileName(fullPath) : null;
}
public override void Run()
{
string inputFilename = GetTestscriptFilePath(CurrentTestName);
StringBuilder output = new StringBuilder();
TokenizeWithLexer(inputFilename, output);
TestParser(inputFilename, output);
string baselineFilename = GetBaselineFilePath(CurrentTestName);
string baseline;
try
{
baseline = GetFileContent(baselineFilename).Replace("\r\n", "\n");
}
catch (FileNotFoundException)
{
baseline = string.Empty;
}
string outputString = output.ToString().Replace("\r\n", "\n");
//Console.WriteLine(baselineFilename);
if (string.Compare(baseline, outputString, StringComparison.Ordinal) != 0)
{
DumpToTrace(CurrentTestName, outputString);
string outputFilename = Path.Combine(TraceFilePath, GetBaselineFileName(CurrentTestName));
Console.WriteLine(":: Output does not match the baseline!");
Console.WriteLine("code --diff \"" + baselineFilename + "\" \"" + outputFilename + "\"");
Console.WriteLine();
Console.WriteLine(":: To update the baseline:");
Console.WriteLine("copy \"" + outputFilename + "\" \"" + baselineFilename + "\"");
Console.WriteLine();
testFailed = true;
}
}
}
}

View File

@@ -30,6 +30,24 @@ namespace Microsoft.SqlTools.ManagedBatchParser.UnitTests.BatchParser
}
}
[Fact]
public void CheckSimpleMultipleQLBatchStatement()
{
using (BatchParserWrapper parserWrapper = new BatchParserWrapper())
{
string sqlScript = @"SELECT 'FirstLine';
GO
SELECT 'MiddleLine_1';
GO
SELECT 'MiddleLine_1'
GO
SELECT 'LastLine'";
var batches = parserWrapper.GetBatches(sqlScript);
// Each select statement is one batch , so we are expecting 4 batches.
Assert.Equal(4, batches.Count);
}
}
[Fact]
public void CheckSQLBatchStatementWithRepeatExecution()
{

View File

@@ -4,9 +4,9 @@
//
using System;
using System.Globalization;
using System.IO;
using System.Text;
using System.Globalization;
using Microsoft.SqlTools.ServiceLayer.BatchParser;
namespace Microsoft.SqlTools.ManagedBatchParser.UnitTests.BatchParser
@@ -36,7 +36,7 @@ namespace Microsoft.SqlTools.ManagedBatchParser.UnitTests.BatchParser
batch.GetText(true, out textWithVariablesResolved, out lineInfoVarsResolved);
batch.GetText(false, out textWithVariablesUnresolved, out lineInfoVarsUnresolved);
outputString.AppendFormat(CultureInfo.InvariantCulture, "*** Execute batch ({0})\n", repeatCount);
if (string.Compare(textWithVariablesUnresolved, textWithVariablesResolved, StringComparison.Ordinal) != 0)
{
outputString.AppendLine("Text with variables not resolved:");
@@ -49,10 +49,10 @@ namespace Microsoft.SqlTools.ManagedBatchParser.UnitTests.BatchParser
{
PositionStruct pos = lineInfoVarsResolved.GetStreamPositionForOffset(i);
string character = i < textWithVariablesResolved.Length ? ("" + textWithVariablesResolved[i]).Replace("\n", @"\n").Replace("\r", @"\r") : "EOF";
outputString.AppendFormat(CultureInfo.InvariantCulture, "Pos [{0}] {1}:{2} \"{3}\"",
i,
BatchParserTests.GetFilenameOnly(pos.Filename),
pos.Offset,
outputString.AppendFormat(CultureInfo.InvariantCulture, "Pos [{0}] {1}:{2} \"{3}\"",
i,
BatchParserTests.GetFilenameOnly(pos.Filename),
pos.Offset,
character);
outputString.AppendLine();
i++;
@@ -89,4 +89,4 @@ namespace Microsoft.SqlTools.ManagedBatchParser.UnitTests.BatchParser
return BatchParserAction.Continue;
}
}
}
}

View File

@@ -7,42 +7,30 @@ using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SqlTools.ServiceLayer.BatchParser;
using Microsoft.SqlTools.ServiceLayer.BatchParser.ExecutionEngineCode;
namespace Microsoft.SqlTools.ManagedBatchParser.UnitTests.BatchParser
{
internal sealed class TestVariableResolver : IVariableResolver
{
Dictionary<string, string> variables = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
private StringBuilder outputString;
private BatchParserSqlCmd batchParserSqlCmd;
public TestVariableResolver(StringBuilder outputString)
{
this.outputString = outputString;
batchParserSqlCmd = new BatchParserSqlCmd();
}
public string GetVariable(PositionStruct pos, string name)
{
if (variables.ContainsKey(name))
{
return variables[name];
}
else
{
return null;
}
return batchParserSqlCmd.GetVariable(pos, name);
}
public void SetVariable(PositionStruct pos, string name, string value)
{
outputString.AppendFormat("Setting variable {0} to [{1}]\n", name, value);
if (value == null)
{
variables.Remove(name);
}
else
{
variables[name] = value;
}
batchParserSqlCmd.SetVariable(pos, name, value);
}
}
}
}

View File

@@ -0,0 +1,46 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../Common.props" />
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<DebugType>portable</DebugType>
<AssemblyName>Microsoft.SqlTools.ManagedBatchParser.IntegrationTests</AssemblyName>
<PackageId>Microsoft.SqlTools.ManagedBatchParser.IntegrationTests</PackageId>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<DefineConstants>$(DefineConstants);TRACE</DefineConstants>
</PropertyGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json">
<HintPath>../../bin/ref/Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="Moq">
<HintPath>../../bin/ref/Moq.dll</HintPath>
</Reference>
<Reference Include="Castle.Core">
<HintPath>../../bin/ref/Castle.Core.dll</HintPath>
</Reference>
<ProjectReference Include="../../src/Microsoft.SqlTools.Hosting/Microsoft.SqlTools.Hosting.csproj" />
<ProjectReference Include="../../src/Microsoft.SqlTools.Credentials/Microsoft.SqlTools.Credentials.csproj" />
<ProjectReference Include="../Microsoft.SqlTools.ServiceLayer.Test.Common/Microsoft.SqlTools.ServiceLayer.Test.Common.csproj" />
<ProjectReference Include="../../src/Microsoft.SqlTools.ManagedBatchParser/Microsoft.SqlTools.ManagedBatchParser.csproj" />
<ProjectReference Include="../Microsoft.SqlTools.ServiceLayer.UnitTests/Microsoft.SqlTools.ServiceLayer.UnitTests.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Net.Http" Version="4.3.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
<PackageReference Include="System.Data.SqlClient" Version="4.6.0" />
<PackageReference Include="Microsoft.SqlServer.SqlManagementObjects" Version="$(SmoPackageVersion)" />
<PackageReference Include="Microsoft.SqlServer.DacFx" Version="150.4316.1-preview" />
</ItemGroup>
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Integration' ">
<DefineConstants>$(DefineConstants);WINDOWS_ONLY_BUILD</DefineConstants>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,40 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System.Reflection;
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: AssemblyTitle("Microsoft.SqlTools.ManagedBatchParser.IntegrationTests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Microsoft.SqlTools.ManagedBatchParser.IntegrationTests")]
[assembly: AssemblyCopyright("Copyright <20> 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 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("340E4742-BF01-4EF8-B2A5-9CEC1075A842")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -5,22 +5,22 @@
using System;
using System.Collections.Generic;
using Microsoft.SqlTools.ServiceLayer.BatchParser.ExecutionEngineCode;
using System.Data.SqlClient;
using Microsoft.SqlTools.ServiceLayer.BatchParser.ExecutionEngineCode;
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
namespace Microsoft.SqlTools.ManagedBatchParser.IntegrationTests.TSQLExecutionEngine
{
internal class BatchEventHandler: IBatchEventsHandler
internal class BatchEventHandler : IBatchEventsHandler
{
List<int> resultCounts = new List<int>();
List<string> sqlMessages = new List<string>();
List<string> errorMessage = new List<string>();
int batchfinishedEventCounter = 0;
SqlDataReader dr = null;
bool cancelEventFired = false;
private List<int> resultCounts = new List<int>();
private List<string> sqlMessages = new List<string>();
private List<string> errorMessage = new List<string>();
private int batchfinishedEventCounter = 0;
private SqlDataReader dr = null;
private bool cancelEventFired = false;
#region Public properties
public List<int> ResultCounts
{
get
@@ -52,6 +52,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
return batchfinishedEventCounter;
}
}
public bool CancelFired
{
get
@@ -59,9 +60,11 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
return cancelEventFired;
}
}
#endregion
#endregion Public properties
#region IBatchEventHandlers Members
public void OnBatchCancelling(object sender, EventArgs args)
{
Console.WriteLine("\tOnBatchCancelling:");
@@ -103,9 +106,9 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
}
public void OnBatchResultSetProcessing(object sender, BatchResultSetEventArgs args)
{
{
lock (this)
{
{
Console.WriteLine("\tOnBatchResultProcessing...");
dr = args.DataReader as SqlDataReader;
int count = 0;
@@ -118,6 +121,6 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
}
}
#endregion
#endregion IBatchEventHandlers Members
}
}
}

View File

@@ -3,26 +3,24 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.SqlTools.ManagedBatchParser.IntegrationTests.Utility;
using Microsoft.SqlTools.ServiceLayer.BatchParser.ExecutionEngineCode;
using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility;
using Microsoft.SqlTools.ServiceLayer.Test.Common;
using Moq;
using Xunit;
using System.Threading.Tasks;
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
namespace Microsoft.SqlTools.ManagedBatchParser.IntegrationTests.TSQLExecutionEngine
{
/// <summary>
///This is a test class for Microsoft.Data.Tools.Schema.Common.ExecutionEngine.ExecutionEngine and is intended
///to contain all Microsoft.Data.Tools.Schema.Common.ExecutionEngine.ExecutionEngine Unit Tests
///</summary>
public class ExecutionEngineTest : IDisposable
{
private SqlConnection connection;
@@ -73,11 +71,12 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
//Task.Run(() => SqlTestDb.DropDatabase(connection.Database));
CloseConnection(connection);
connection = null;
}
}
#endregion
#endregion Test Initialize And Cleanup
#region Valid scripts
/// <summary>
///A test for a simple SQL script
///</summary>
@@ -91,7 +90,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
conditions.IsParseOnly = false;
conditions.IsHaltOnError = false;
TestExecutor executor = new TestExecutor(sqlStatement, connection, conditions);
TestExecutor executor = new TestExecutor(sqlStatement, connection, conditions);
executor.Run();
//Get the expected values
@@ -171,9 +170,11 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
Assert.Equal(ScriptExecutionResult.Success, executor.ExecutionResult);
Assert.True(CompareTwoIntLists(executor.ResultCountQueue, expResultCounts));
}
#endregion
#endregion Valid scripts
#region Invalid Scripts
/// <summary>
/// Test with a invalid query using the default execution condition
/// </summary>
@@ -191,7 +192,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
List<string> batchScripts = executor.BatchScripts;
ExecuteSqlBatch(batchScripts, connection);
Assert.Equal( ScriptExecutionResult.Success | ScriptExecutionResult.Failure, executor.ExecutionResult);
Assert.Equal(ScriptExecutionResult.Success | ScriptExecutionResult.Failure, executor.ExecutionResult);
Assert.True(!executor.ParserExecutionError);
Assert.True(CompareTwoStringLists(executor.ErrorMessageQueue, expErrorMessage));
Assert.True(CompareTwoIntLists(executor.ResultCountQueue, expResultCounts));
@@ -235,10 +236,10 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
conditions.IsTransactionWrapped = true;
conditions.IsParseOnly = false;
conditions.IsHaltOnError = false;
TestExecutor executor = new TestExecutor(sqlStatement, connection, conditions);
executor.Run();
//Get the expected values
List<string> batchScripts = executor.BatchScripts;
ExecuteSqlBatch(batchScripts, connection);
@@ -306,11 +307,12 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
{
ExecutionEngine engine = new ExecutionEngine();
Assert.True(ConnectionDiscardWrapper(engine));
}
#endregion
#endregion Invalid Scripts
#region Different execution conditions
/// <summary>
/// Test HaltOnError execution condition
/// </summary>
@@ -334,7 +336,6 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
Assert.True(CompareTwoStringLists(executor.ErrorMessageQueue, expErrorMessage));
Assert.True(CompareTwoIntLists(executor.ResultCountQueue, expResultCounts));
Assert.True(executor.ResultCountQueue.Count == 0);
}
/// <summary>
@@ -361,7 +362,6 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
Assert.True(CompareTwoIntLists(executor.ResultCountQueue, expResultCounts));
Assert.True(executor.ResultCountQueue.Count == 0);
Assert.Equal(0, executor.BatchFinshedEventCounter);
}
/// <summary>
@@ -462,9 +462,9 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
TestExecutor executor = new TestExecutor(sqlStatement, connection, conditions);
executor.Run();
// Note: this used to also return Halted at some point in the distant past.
// Note: this used to also return Halted at some point in the distant past.
// However since that gets mapped to Failure anyhow, consider "Failure" as acceptable here
Assert.True(executor.ExecutionResult.HasFlag(ScriptExecutionResult.Failure), "Expected failure when invalid connection is present" );
Assert.True(executor.ExecutionResult.HasFlag(ScriptExecutionResult.Failure), "Expected failure when invalid connection is present");
}
/// <summary>
@@ -489,16 +489,18 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
Assert.Equal(ScriptExecutionResult.Success, executor.ExecutionResult);
Assert.True(CompareTwoIntLists(executor.ResultCountQueue, expResultCounts));
}
#endregion
#endregion Different execution conditions
#region SQL Commands
/// <summary>
/// Test with SQL commands
/// </summary>
[Fact]
public void ExecutionEngineTest_SQLCmds()
{
string[] sqlStatements = {
string[] sqlStatements = {
"select $(INVALIDVAR) from sysobjects",
":help",
"exit",
@@ -517,7 +519,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
":perftrace STDOUT",
"exit (Select count(*) from sysobjects)"
};
ExecutionEngineConditions conditions = new ExecutionEngineConditions();
foreach (string stmt in sqlStatements)
@@ -526,11 +528,12 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
executor.Run();
Assert.True(executor.ResultCountQueue.Count == 0);
}
}
#endregion
#endregion SQL Commands
#region Threading
/// <summary>
/// Test synchronous cancel
/// </summary>
@@ -547,11 +550,10 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
TestExecutor executor = new TestExecutor(sqlStatement, connection, conditions, true);
executor.CancelTimeOut = 3000;
executor.Run();
Assert.NotNull(executor.ScriptExecuteThread);
Assert.Equal(ScriptExecutionResult.Cancel, executor.ExecutionResult);
Assert.True(executor.CancelEventFired);
}
/// <summary>
@@ -582,13 +584,13 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
/// <summary>
/// Test sync cancel when the execution is done
/// </summary>
///
/// Disabled test, has race condition where Sql statement will finish
///
/// Disabled test, has race condition where Sql statement will finish
/// before harness has an opportunity to cancel.
//TEST_DOESNOTWORK[TestMethod()]
public void ExecutionEngineTest_SyncCancelAfterExecutionDone()
{
string sqlStatement = "select 1" ;
string sqlStatement = "select 1";
ExecutionEngineConditions conditions = new ExecutionEngineConditions();
conditions.IsTransactionWrapped = true;
@@ -603,7 +605,6 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
if (executor.ScriptExecuteThread != null)
Assert.True(!executor.ScriptExecuteThread.IsAlive);
Assert.Equal(ScriptExecutionResult.Success | ScriptExecutionResult.Cancel, executor.ExecutionResult);
}
/// <summary>
@@ -612,7 +613,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
[Fact]
public void ExecutionEngineTest_ASyncCancelAfterExecutionDone()
{
string sqlStatement ="select 1";
string sqlStatement = "select 1";
ExecutionEngineConditions conditions = new ExecutionEngineConditions();
conditions.IsTransactionWrapped = true;
@@ -688,7 +689,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
await SqlTestDb.DropDatabase(connection3.Database);
}
#endregion
#endregion Threading
#region Get/Set Methods
@@ -751,9 +752,10 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
Assert.Equal(conditions.BatchSeparator, "GO");
}
#endregion
#endregion Get/Set Methods
#region Private methods
/// <summary>
/// Connection to a database
/// </summary>
@@ -774,7 +776,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
{
foreach (string script in sqlBatch)
{
ExecuteSqlCommand(script, connection);
ExecuteSqlCommand(script, connection);
}
}
@@ -788,7 +790,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
SqlCommand cmd = new SqlCommand(sqlCmdTxt, connection);
SqlTransaction transaction = connection.BeginTransaction();
cmd.Transaction = transaction;
try
{
using (SqlDataReader dr = cmd.ExecuteReader())
@@ -806,7 +808,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
transaction.Commit();
}
catch (Exception e)
{
{
Console.WriteLine("Executing command throws exception: " + e.Message);
expErrorMessage.Add(e.Message);
try
@@ -830,7 +832,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
private bool CompareTwoStringLists(List<string> l1, List<string> l2)
{
bool isSame = true;
if(l1.Count != l2.Count)
if (l1.Count != l2.Count)
{
isSame = false;
Console.WriteLine("The count of elements in two lists are not the same");
@@ -893,6 +895,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
engine.Close(false, true, true);
return true;
}
#endregion
#endregion Private methods
}
}
}

View File

@@ -10,36 +10,40 @@ using System.Threading;
using Microsoft.SqlTools.ServiceLayer.BatchParser.ExecutionEngineCode;
using Microsoft.SqlTools.Utility;
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
namespace Microsoft.SqlTools.ManagedBatchParser.IntegrationTests.TSQLExecutionEngine
{
class TestExecutor : IDisposable
internal class TestExecutor : IDisposable
{
#region Private variables
string sqlStatement;
ExecutionEngineConditions conditions = new ExecutionEngineConditions();
BatchEventHandler eventHandler = new BatchEventHandler();
SqlConnection connection = null;
static Thread _executionThread;
bool _syncCancel = true;
bool _isFinished = false;
bool _cancel = false;
int _cancelTimeout = 500;
int exeTimeOut = 0;
private string sqlStatement;
private ExecutionEngineConditions conditions = new ExecutionEngineConditions();
private BatchEventHandler eventHandler = new BatchEventHandler();
private SqlConnection connection = null;
private static Thread _executionThread;
private bool _syncCancel = true;
private bool _isFinished = false;
private bool _cancel = false;
private int _cancelTimeout = 500;
private int exeTimeOut = 0;
//For verification
List<int> resultCounts = new List<int>();
List<string> sqlMessages = new List<string>();
List<string> errorMessage = new List<string>();
List<bool> batchFinished = new List<bool>();
static ScriptExecutionResult execResult = ScriptExecutionResult.All;
static List<string> batchScripts = new List<string>();
static Thread exeThread = null;
static bool parserExecutionError = false;
#endregion
private List<int> resultCounts = new List<int>();
private List<string> sqlMessages = new List<string>();
private List<string> errorMessage = new List<string>();
private List<bool> batchFinished = new List<bool>();
private static ScriptExecutionResult execResult = ScriptExecutionResult.All;
private static List<string> batchScripts = new List<string>();
private static Thread exeThread = null;
private static bool parserExecutionError = false;
#endregion Private variables
#region private methods
/// <summary>
/// Execut the script
/// Execute the script
/// </summary>
/// <param name="exec">Execution Engine</param>
/// <param name="connection">SQL connection</param>
@@ -47,7 +51,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
/// <param name="conditions">Execution condition</param>
/// <param name="batchHandler">Batch event handler</param>
/// <param name="timeout">time out value</param>
static void ExecuteScript(ExecutionEngine exec, SqlConnection connection, string script, ExecutionEngineConditions conditions, IBatchEventsHandler batchHandler, int timeout)
private static void ExecuteScript(ExecutionEngine exec, SqlConnection connection, string script, ExecutionEngineConditions conditions, IBatchEventsHandler batchHandler, int timeout)
{
Validate.IsNotNull(nameof(exec), exec);
Validate.IsNotNull(nameof(connection), connection);
@@ -70,7 +74,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
/// <param name="exec">Execution Engine</param>
/// <param name="isSynchronous">Cancel the execution synchronously or not</param>
/// <param name="timeout">sycn canceo timeout</param>
static void Cancel(ExecutionEngine exec, bool isSynchronous, int millisecondsTimeOut)
private static void Cancel(ExecutionEngine exec, bool isSynchronous, int millisecondsTimeOut)
{
//exec.BeginCancellingExecution(isSynchronous, timeout);
@@ -109,9 +113,11 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
}
Thread.Sleep(5000);
}
#endregion
#endregion private methods
#region Public properties
public bool SyncCancel
{
get
@@ -207,10 +213,12 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
return parserExecutionError;
}
}
#endregion
#endregion Public properties
#region Constructors
public TestExecutor(string batch, SqlConnection conn, ExecutionEngineConditions exeCondition): this(batch, conn, exeCondition, false)
public TestExecutor(string batch, SqlConnection conn, ExecutionEngineConditions exeCondition) : this(batch, conn, exeCondition, false)
{
}
@@ -219,9 +227,9 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
sqlStatement = batch;
conditions.IsHaltOnError = exeCondition.IsHaltOnError;
conditions.IsParseOnly = exeCondition.IsParseOnly;
conditions.IsTransactionWrapped = exeCondition.IsTransactionWrapped;
conditions.IsNoExec = exeCondition.IsNoExec;
conditions.IsStatisticsIO = exeCondition.IsStatisticsIO;
conditions.IsTransactionWrapped = exeCondition.IsTransactionWrapped;
conditions.IsNoExec = exeCondition.IsNoExec;
conditions.IsStatisticsIO = exeCondition.IsStatisticsIO;
conditions.IsStatisticsTime = exeCondition.IsStatisticsTime;
_cancel = cancelExecution;
@@ -232,16 +240,18 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
batchScripts = new List<string>();
exeThread = null;
parserExecutionError = false;
}
public TestExecutor(string batch, SqlConnection conn, ExecutionEngineConditions exeCondition, int timeOut)
: this(batch, conn, exeCondition, false)
{
exeTimeOut = timeOut;
}
#endregion
#endregion Constructors
#region public methods
/// <summary>
/// Execute the test engine
/// </summary>
@@ -282,15 +292,17 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
}
}
}
#endregion
#endregion public methods
#region ParserEvent
/// <summary>
/// Called when batch is called
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
static void OnBatchParserExecutionStart(object sender, BatchParserExecutionStartEventArgs e)
private static void OnBatchParserExecutionStart(object sender, BatchParserExecutionStartEventArgs e)
{
Console.WriteLine("****************");
Console.WriteLine(e.Batch.Text);
@@ -306,7 +318,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
static void OnBatchParserExecutionFinished(object sender, BatchParserExecutionFinishedEventArgs e)
private static void OnBatchParserExecutionFinished(object sender, BatchParserExecutionFinishedEventArgs e)
{
Console.WriteLine("ON_BATCH_PARSER_EXECUTION_FINISHED : Done executing batch \n\t{0}\n\t with result... {1} ", e.Batch.Text, e.ExecutionResult);
if (execResult == ScriptExecutionResult.All)
@@ -320,12 +332,11 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
static void OnBatchParserExecutionError(object sender, BatchParserExecutionErrorEventArgs e)
{
private static void OnBatchParserExecutionError(object sender, BatchParserExecutionErrorEventArgs e)
{
Console.WriteLine("ON_BATCH_PARSER_EXECUTION_ERROR : {0} found... at line {1}: {2}", e.MessageType.ToString(), e.Line.ToString(), e.Message);
Console.WriteLine("\t Error Description: " + e.Description);
parserExecutionError = true;
}
/// <summary>
@@ -341,18 +352,21 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
if (execResult == ScriptExecutionResult.All)
execResult = e.ExecutionResult;
else
execResult = execResult|e.ExecutionResult;
execResult = execResult | e.ExecutionResult;
resultCounts = eventHandler.ResultCounts;
sqlMessages = eventHandler.SqlMessages;
errorMessage = eventHandler.ErrorMessages;
}
#endregion
#endregion ParserEvent
#region IDisposable Members
public void Dispose()
{
}
#endregion
#endregion IDisposable Members
}
}
}

View File

@@ -0,0 +1,20 @@
using System.IO;
namespace Microsoft.SqlTools.ManagedBatchParser.IntegrationTests.Utility
{
internal class FileUtilities
{
/// <summary>
/// Turns off the read-only attribute for this file
/// </summary>
/// <param name="fullFilePath"></param>
internal static void SetFileReadWrite(string fullFilePath)
{
if (!string.IsNullOrEmpty(fullFilePath) &&
File.Exists(fullFilePath))
{
File.SetAttributes(fullFilePath, FileAttributes.Normal);
}
}
}
}

View File

@@ -0,0 +1,149 @@
using System;
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.Test.Common;
using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts;
using Xunit;
namespace Microsoft.SqlTools.ManagedBatchParser.IntegrationTests.Utility
{
public class LiveConnectionHelper
{
public static string GetTestSqlFile(string fileName = null)
{
string filePath = null;
if (string.IsNullOrEmpty(fileName))
{
filePath = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "sqltest.sql");
}
else
{
filePath = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), fileName + ".sql");
}
if (File.Exists(filePath))
{
File.Delete(filePath);
}
File.WriteAllText(filePath, "SELECT * FROM sys.objects\n");
return filePath;
}
public static TestConnectionResult InitLiveConnectionInfo(string databaseName = null, string ownerUri = null)
{
ScriptFile scriptFile = null;
ConnectParams connectParams = TestServiceProvider.Instance.ConnectionProfileService.GetConnectionParameters(TestServerType.OnPrem, databaseName);
if (string.IsNullOrEmpty(ownerUri))
{
ownerUri = GetTestSqlFile();
scriptFile = TestServiceProvider.Instance.WorkspaceService.Workspace.GetFile(ownerUri);
ownerUri = scriptFile.ClientFilePath;
}
var connectionService = GetLiveTestConnectionService();
var connectionResult =
connectionService
.Connect(new ConnectParams
{
OwnerUri = ownerUri,
Connection = connectParams.Connection
});
connectionResult.Wait();
ConnectionInfo connInfo = null;
connectionService.TryFindConnection(ownerUri, out connInfo);
return new TestConnectionResult() { ConnectionInfo = connInfo, ScriptFile = scriptFile };
}
public static async Task<TestConnectionResult> InitLiveConnectionInfoAsync(string databaseName = null, string ownerUri = null,
string connectionType = ServiceLayer.Connection.ConnectionType.Default)
{
ScriptFile scriptFile = null;
if (string.IsNullOrEmpty(ownerUri))
{
ownerUri = GetTestSqlFile();
scriptFile = TestServiceProvider.Instance.WorkspaceService.Workspace.GetFile(ownerUri);
ownerUri = scriptFile.ClientFilePath;
}
ConnectParams connectParams = TestServiceProvider.Instance.ConnectionProfileService.GetConnectionParameters(TestServerType.OnPrem, databaseName);
var connectionService = GetLiveTestConnectionService();
var connectionResult =
await connectionService
.Connect(new ConnectParams
{
OwnerUri = ownerUri,
Connection = connectParams.Connection,
Type = connectionType
});
if (!string.IsNullOrEmpty(connectionResult.ErrorMessage))
{
Console.WriteLine(connectionResult.ErrorMessage);
}
ConnectionInfo connInfo = null;
connectionService.TryFindConnection(ownerUri, out connInfo);
return new TestConnectionResult() { ConnectionInfo = connInfo, ScriptFile = scriptFile };
}
public static ConnectionInfo InitLiveConnectionInfoForDefinition(string databaseName = null)
{
using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile())
{
ConnectParams connectParams = TestServiceProvider.Instance.ConnectionProfileService.GetConnectionParameters(TestServerType.OnPrem, databaseName);
string ownerUri = queryTempFile.FilePath;
var connectionService = GetLiveTestConnectionService();
var connectionResult =
connectionService
.Connect(new ConnectParams
{
OwnerUri = ownerUri,
Connection = connectParams.Connection
});
connectionResult.Wait();
ConnectionInfo connInfo = null;
connectionService.TryFindConnection(ownerUri, out connInfo);
Assert.NotNull(connInfo);
return connInfo;
}
}
public static ServerConnection InitLiveServerConnectionForDefinition(ConnectionInfo connInfo)
{
SqlConnection sqlConn = new SqlConnection(ConnectionService.BuildConnectionString(connInfo.ConnectionDetails));
return new ServerConnection(sqlConn);
}
/// <summary>
/// Creates a test sql connection factory instance
/// </summary>
public static ISqlConnectionFactory GetLiveTestSqlConnectionFactory()
{
// connect to a real server instance
return ConnectionService.Instance.ConnectionFactory;
}
public static ConnectionService GetLiveTestConnectionService()
{
// connect to a real server instance
return ConnectionService.Instance;
}
public class TestConnectionResult
{
public ConnectionInfo ConnectionInfo { get; set; }
public ScriptFile ScriptFile { get; set; }
public TextDocumentPosition TextDocumentPosition { get; set; }
}
}
}

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="8.0.2" targetFramework="net461" />
<package id="xunit" version="2.1.0" targetFramework="net45" />
<package id="xunit.abstractions" version="2.0.0" targetFramework="net45" />
<package id="xunit.assert" version="2.1.0" targetFramework="net45" />
<package id="xunit.core" version="2.1.0" targetFramework="net45" />
<package id="xunit.extensibility.core" version="2.1.0" targetFramework="net45" />
<package id="xunit.extensibility.execution" version="2.1.0" targetFramework="net45" />
<package id="xunit.runner.visualstudio" version="2.1.0" targetFramework="net45" />
</packages>

View File

@@ -1,292 +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.Globalization;
using System.IO;
using System.Text;
using Microsoft.SqlTools.ServiceLayer.BatchParser;
using Microsoft.SqlTools.ServiceLayer.Test.Common;
using Microsoft.SqlTools.ServiceLayer.Test.Common.Baselined;
using Xunit;
using Microsoft.SqlTools.ServiceLayer.Utility;
using Microsoft.SqlTools.ServiceLayer.BatchParser.ExecutionEngineCode;
using Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine;
namespace Microsoft.SqlTools.ManagedBatchParser.UnitTests.BatchParser
{
public class BatchParserTests : BaselinedTest
{
private bool testFailed = false;
public BatchParserTests()
{
InitializeTest();
}
public void InitializeTest()
{
CategoryName = "BatchParser";
this.TraceOutputDirectory = RunEnvironmentInfo.GetTraceOutputLocation();
TestInitialize();
}
[Fact]
public void VerifyThrowOnUnresolvedVariable()
{
string script = "print '$(NotDefined)'";
StringBuilder output = new StringBuilder();
TestCommandHandler handler = new TestCommandHandler(output);
IVariableResolver resolver = new TestVariableResolver(new StringBuilder());
using (Parser p = new Parser(
handler,
resolver,
new StringReader(script),
"test"))
{
p.ThrowOnUnresolvedVariable = true;
handler.SetParser(p);
Assert.Throws<BatchParserException>(() => p.Parse());
}
}
[Fact]
public void VerifyExecuteScript()
{
string query = "select @@version";
ExecutionEngineTest executionEngineTest = new ExecutionEngineTest();
executionEngineTest.TestInitialize();
using (ExecutionEngine engine = new ExecutionEngine())
{
engine.ExecuteScript(query);
}
}
[Fact]
public void CanceltheBatch()
{
Batch batch = new Batch();
batch.Cancel();
}
private static Stream GenerateStreamFromString(string s)
{
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
writer.Write(s);
writer.Flush();
stream.Position = 0;
return stream;
}
public void TokenizeWithLexer(string filename, StringBuilder output)
{
// Create a new file by changing CRLFs to LFs and generate a new steam
// or the tokens generated by the lexer will always have off by one errors
string input = File.ReadAllText(filename).Replace("\r\n", "\n");
var inputStream = GenerateStreamFromString(input);
using (Lexer lexer = new Lexer(new StreamReader(inputStream), filename))
{
string inputText = File.ReadAllText(filename);
inputText = inputText.Replace("\r\n", "\n");
StringBuilder roundtripTextBuilder = new StringBuilder();
StringBuilder outputBuilder = new StringBuilder();
StringBuilder tokenizedInput = new StringBuilder();
bool lexerError = false;
Token token = null;
try
{
do
{
lexer.ConsumeToken();
token = lexer.CurrentToken;
roundtripTextBuilder.Append(token.Text.Replace("\r\n", "\n"));
outputBuilder.AppendLine(GetTokenString(token));
tokenizedInput.Append('[').Append(GetTokenCode(token.TokenType)).Append(':').Append(token.Text.Replace("\r\n", "\n")).Append(']');
} while (token.TokenType != LexerTokenType.Eof);
}
catch (BatchParserException ex)
{
lexerError = true;
outputBuilder.AppendLine(string.Format(CultureInfo.CurrentCulture, "[ERROR: code {0} at {1} - {2} in {3}, message: {4}]", ex.ErrorCode, GetPositionString(ex.Begin), GetPositionString(ex.End), GetFilenameOnly(ex.Begin.Filename), ex.Message));
}
output.AppendLine("Lexer tokenized input:");
output.AppendLine("======================");
output.AppendLine(tokenizedInput.ToString());
output.AppendLine("Tokens:");
output.AppendLine("=======");
output.AppendLine(outputBuilder.ToString());
if (lexerError == false)
{
// Verify that all text from tokens can be recombined into original string
Assert.Equal<string>(inputText, roundtripTextBuilder.ToString());
}
}
}
private string GetTokenCode(LexerTokenType lexerTokenType)
{
switch (lexerTokenType)
{
case LexerTokenType.Text:
return "T";
case LexerTokenType.Whitespace:
return "WS";
case LexerTokenType.NewLine:
return "NL";
case LexerTokenType.Comment:
return "C";
default:
return lexerTokenType.ToString();
}
}
private static void CopyToOutput(string sourceDirectory, string filename)
{
File.Copy(Path.Combine(sourceDirectory, filename), filename, true);
FileUtilities.SetFileReadWrite(filename);
}
// [Fact]
public void BatchParserTest()
{
CopyToOutput(FilesLocation, "TS-err-cycle1.txt");
CopyToOutput(FilesLocation, "cycle2.txt");
Start("err-blockComment");
Start("err-blockComment2");
Start("err-varDefinition");
Start("err-varDefinition2");
Start("err-varDefinition3");
Start("err-varDefinition4");
Start("err-varDefinition5");
Start("err-varDefinition6");
Start("err-varDefinition7");
Start("err-varDefinition8");
Start("err-varDefinition9");
Start("err-variableRef");
Start("err-variableRef2");
Start("err-variableRef3");
Start("err-variableRef4");
Start("err-cycle1");
Start("input");
Start("input2");
Start("pass-blockComment");
Start("pass-lineComment");
Start("pass-lineComment2");
Start("pass-noBlockComments");
Start("pass-noLineComments");
Start("pass-varDefinition");
Start("pass-varDefinition2");
Start("pass-varDefinition3");
Start("pass-varDefinition4");
Start("pass-command-and-comment");
Assert.False(testFailed, "At least one of test cases failed. Check output for details.");
}
public void TestParser(string filename, StringBuilder output)
{
try
{
// Create a new file by changing CRLFs to LFs and generate a new steam
// or the tokens generated by the lexer will always have off by one errors
TestCommandHandler commandHandler = new TestCommandHandler(output);
string input = File.ReadAllText(filename).Replace("\r\n", "\n");
var inputStream = GenerateStreamFromString(input);
StreamReader streamReader = new StreamReader(inputStream);
using (Parser parser = new Parser(
commandHandler,
new TestVariableResolver(output),
streamReader,
filename))
{
commandHandler.SetParser(parser);
parser.Parse();
}
}
catch (BatchParserException ex)
{
output.AppendLine(string.Format(CultureInfo.CurrentCulture, "[PARSER ERROR: code {0} at {1} - {2} in {3}, token text: {4}, message: {5}]", ex.ErrorCode, GetPositionString(ex.Begin), GetPositionString(ex.End), GetFilenameOnly(ex.Begin.Filename), ex.Text, ex.Message));
}
}
private string GetPositionString(PositionStruct pos)
{
return string.Format(CultureInfo.InvariantCulture, "{0}:{1} [{2}]", pos.Line, pos.Column, pos.Offset);
}
private string GetTokenString(Token token)
{
if (token == null)
{
return "(null)";
}
else
{
string tokenText = token.Text;
if (tokenText != null)
{
tokenText = tokenText.Replace("\r\n", "\\n").Replace("\n", "\\n").Replace("\r", "\\r").Replace("\t", "\\t");
}
string tokenFilename = token.Filename;
tokenFilename = GetFilenameOnly(tokenFilename);
return string.Format(CultureInfo.CurrentCulture, "[Token {0} at {1}({2}:{3} [{4}] - {5}:{6} [{7}]): '{8}']",
token.TokenType,
tokenFilename,
token.Begin.Line, token.Begin.Column, token.Begin.Offset,
token.End.Line, token.End.Column, token.End.Offset,
tokenText);
}
}
internal static string GetFilenameOnly(string fullPath)
{
return fullPath != null ? Path.GetFileName(fullPath) : null;
}
public override void Run()
{
string inputFilename = GetTestscriptFilePath(CurrentTestName);
StringBuilder output = new StringBuilder();
TokenizeWithLexer(inputFilename, output);
TestParser(inputFilename, output);
string baselineFilename = GetBaselineFilePath(CurrentTestName);
string baseline;
try
{
baseline = GetFileContent(baselineFilename).Replace("\r\n", "\n");
}
catch (FileNotFoundException)
{
baseline = string.Empty;
}
string outputString = output.ToString().Replace("\r\n", "\n");
//Console.WriteLine(baselineFilename);
if (string.Compare(baseline, outputString, StringComparison.Ordinal) != 0)
{
DumpToTrace(CurrentTestName, outputString);
string outputFilename = Path.Combine(TraceFilePath, GetBaselineFileName(CurrentTestName));
Console.WriteLine(":: Output does not match the baseline!");
Console.WriteLine("code --diff \"" + baselineFilename + "\" \"" + outputFilename + "\"");
Console.WriteLine();
Console.WriteLine(":: To update the baseline:");
Console.WriteLine("copy \"" + outputFilename + "\" \"" + baselineFilename + "\"");
Console.WriteLine();
testFailed = true;
}
}
}
}