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 sudo: required
dist: trusty dist: xenial
os: os:
- linux - linux
@@ -7,7 +7,8 @@ os:
# - osx # - osx
mono: none mono: none
dotnet: 2.2.100-preview3-009430 dotnet: 2.2
# was dotnet: 2.2.100-preview3-009430
# safelist # safelist
branches: branches:
@@ -38,4 +39,3 @@ script:
- dotnet test test/Microsoft.SqlTools.ServiceLayer.UnitTests - dotnet test test/Microsoft.SqlTools.ServiceLayer.UnitTests
- dotnet build src/Microsoft.SqlTools.CoreServices - dotnet build src/Microsoft.SqlTools.CoreServices
- dotnet test test/Microsoft.SqlTools.Hosting.UnitTests - dotnet test test/Microsoft.SqlTools.Hosting.UnitTests

View File

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

View File

@@ -238,6 +238,14 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser
if (LookaheadTokenType == LexerTokenType.Text) if (LookaheadTokenType == LexerTokenType.Text)
{ {
string text = ResolveVariables(LookaheadToken, 0, null); 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++) for (int i = 0; i < text.Length; i++)
{ {
if (Char.IsDigit(text[i]) == false) if (Char.IsDigit(text[i]) == false)
@@ -245,11 +253,6 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser
RaiseError(ErrorCode.InvalidNumber); RaiseError(ErrorCode.InvalidNumber);
} }
} }
bool result = Int32.TryParse(text, out repeatCount);
if (result == false)
{
RaiseError(ErrorCode.InvalidNumber);
}
Accept(LexerTokenType.Text); Accept(LexerTokenType.Text);
AcceptWhitespaceOrComment(); AcceptWhitespaceOrComment();
} }

View File

@@ -4,6 +4,7 @@
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo> <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems> <EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems>
<DebugType>portable</DebugType>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Localization\transXliff\" /> <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.IntegrationTests")]
[assembly: InternalsVisibleTo("Microsoft.SqlTools.ServiceLayer.Test.Common")] [assembly: InternalsVisibleTo("Microsoft.SqlTools.ServiceLayer.Test.Common")]
[assembly: InternalsVisibleTo("MicrosoftSqlToolsServiceLayer")] [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 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.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.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.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\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 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 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.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.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.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\Microsoft.SqlTools.ResourceProvider.csproj portable full
cscript /nologo ReplaceText.vbs %REPOROOT%\src\Microsoft.SqlTools.ResourceProvider.Core\Microsoft.SqlTools.ResourceProvider.Core.csproj portable full cscript /nologo ReplaceText.vbs %REPOROOT%\src\Microsoft.SqlTools.ResourceProvider.Core\Microsoft.SqlTools.ResourceProvider.Core.csproj portable full
@@ -30,6 +32,8 @@ dotnet restore %REPOROOT%\src\Microsoft.SqlTools.Credentials\Microsoft.SqlTools.
dotnet build %REPOROOT%\src\Microsoft.SqlTools.Credentials\Microsoft.SqlTools.Credentials.csproj %DOTNETCONFIG% dotnet build %REPOROOT%\src\Microsoft.SqlTools.Credentials\Microsoft.SqlTools.Credentials.csproj %DOTNETCONFIG%
dotnet restore %REPOROOT%\src\Microsoft.SqlTools.Hosting\Microsoft.SqlTools.Hosting.csproj 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 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 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 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 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 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 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 TEST_SERVER=localhost
SET SQLTOOLSSERVICE_EXE=%REPOROOT%\src\Microsoft.SqlTools.ServiceLayer\bin\Integration\netcoreapp2.2\win7-x64\MicrosoftSqlToolsServiceLayer.exe 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 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 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\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\ReportGenerator.2.4.5.0\tools\ReportGenerator.exe" "-reports:coverage.xml" "-targetdir:%WORKINGDIR%\reports"
REM restore original project.json 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 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 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 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 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 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 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 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

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

View File

@@ -4,9 +4,9 @@
// //
using System; using System;
using System.Globalization;
using System.IO; using System.IO;
using System.Text; using System.Text;
using System.Globalization;
using Microsoft.SqlTools.ServiceLayer.BatchParser; using Microsoft.SqlTools.ServiceLayer.BatchParser;
namespace Microsoft.SqlTools.ManagedBatchParser.UnitTests.BatchParser namespace Microsoft.SqlTools.ManagedBatchParser.UnitTests.BatchParser

View File

@@ -7,42 +7,30 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using Microsoft.SqlTools.ServiceLayer.BatchParser; using Microsoft.SqlTools.ServiceLayer.BatchParser;
using Microsoft.SqlTools.ServiceLayer.BatchParser.ExecutionEngineCode;
namespace Microsoft.SqlTools.ManagedBatchParser.UnitTests.BatchParser namespace Microsoft.SqlTools.ManagedBatchParser.UnitTests.BatchParser
{ {
internal sealed class TestVariableResolver : IVariableResolver internal sealed class TestVariableResolver : IVariableResolver
{ {
Dictionary<string, string> variables = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
private StringBuilder outputString; private StringBuilder outputString;
private BatchParserSqlCmd batchParserSqlCmd;
public TestVariableResolver(StringBuilder outputString) public TestVariableResolver(StringBuilder outputString)
{ {
this.outputString = outputString; this.outputString = outputString;
batchParserSqlCmd = new BatchParserSqlCmd();
} }
public string GetVariable(PositionStruct pos, string name) public string GetVariable(PositionStruct pos, string name)
{ {
if (variables.ContainsKey(name)) return batchParserSqlCmd.GetVariable(pos, name);
{
return variables[name];
}
else
{
return null;
}
} }
public void SetVariable(PositionStruct pos, string name, string value) public void SetVariable(PositionStruct pos, string name, string value)
{ {
outputString.AppendFormat("Setting variable {0} to [{1}]\n", name, value); outputString.AppendFormat("Setting variable {0} to [{1}]\n", name, value);
if (value == null) batchParserSqlCmd.SetVariable(pos, name, value);
{
variables.Remove(name);
}
else
{
variables[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;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.SqlTools.ServiceLayer.BatchParser.ExecutionEngineCode;
using System.Data.SqlClient; using System.Data.SqlClient;
using Microsoft.SqlTools.ServiceLayer.BatchParser.ExecutionEngineCode;
namespace Microsoft.SqlTools.ManagedBatchParser.IntegrationTests.TSQLExecutionEngine
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
{ {
internal class BatchEventHandler: IBatchEventsHandler internal class BatchEventHandler : IBatchEventsHandler
{ {
List<int> resultCounts = new List<int>(); private List<int> resultCounts = new List<int>();
List<string> sqlMessages = new List<string>(); private List<string> sqlMessages = new List<string>();
List<string> errorMessage = new List<string>(); private List<string> errorMessage = new List<string>();
int batchfinishedEventCounter = 0; private int batchfinishedEventCounter = 0;
SqlDataReader dr = null; private SqlDataReader dr = null;
bool cancelEventFired = false; private bool cancelEventFired = false;
#region Public properties #region Public properties
public List<int> ResultCounts public List<int> ResultCounts
{ {
get get
@@ -52,6 +52,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
return batchfinishedEventCounter; return batchfinishedEventCounter;
} }
} }
public bool CancelFired public bool CancelFired
{ {
get get
@@ -59,9 +60,11 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
return cancelEventFired; return cancelEventFired;
} }
} }
#endregion
#endregion Public properties
#region IBatchEventHandlers Members #region IBatchEventHandlers Members
public void OnBatchCancelling(object sender, EventArgs args) public void OnBatchCancelling(object sender, EventArgs args)
{ {
Console.WriteLine("\tOnBatchCancelling:"); Console.WriteLine("\tOnBatchCancelling:");
@@ -118,6 +121,6 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
} }
} }
#endregion #endregion IBatchEventHandlers Members
} }
} }

View File

@@ -3,20 +3,18 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
// //
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data.SqlClient; using System.Data.SqlClient;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
using Microsoft.SqlTools.ManagedBatchParser.IntegrationTests.Utility;
using Microsoft.SqlTools.ServiceLayer.BatchParser.ExecutionEngineCode; using Microsoft.SqlTools.ServiceLayer.BatchParser.ExecutionEngineCode;
using Microsoft.SqlTools.ServiceLayer.Connection; using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility;
using Microsoft.SqlTools.ServiceLayer.Test.Common; using Microsoft.SqlTools.ServiceLayer.Test.Common;
using Moq;
using Xunit; using Xunit;
using System.Threading.Tasks;
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine namespace Microsoft.SqlTools.ManagedBatchParser.IntegrationTests.TSQLExecutionEngine
{ {
/// <summary> /// <summary>
///This is a test class for Microsoft.Data.Tools.Schema.Common.ExecutionEngine.ExecutionEngine and is intended ///This is a test class for Microsoft.Data.Tools.Schema.Common.ExecutionEngine.ExecutionEngine and is intended
@@ -75,9 +73,10 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
connection = null; connection = null;
} }
#endregion #endregion Test Initialize And Cleanup
#region Valid scripts #region Valid scripts
/// <summary> /// <summary>
///A test for a simple SQL script ///A test for a simple SQL script
///</summary> ///</summary>
@@ -171,9 +170,11 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
Assert.Equal(ScriptExecutionResult.Success, executor.ExecutionResult); Assert.Equal(ScriptExecutionResult.Success, executor.ExecutionResult);
Assert.True(CompareTwoIntLists(executor.ResultCountQueue, expResultCounts)); Assert.True(CompareTwoIntLists(executor.ResultCountQueue, expResultCounts));
} }
#endregion
#endregion Valid scripts
#region Invalid Scripts #region Invalid Scripts
/// <summary> /// <summary>
/// Test with a invalid query using the default execution condition /// Test with a invalid query using the default execution condition
/// </summary> /// </summary>
@@ -191,7 +192,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
List<string> batchScripts = executor.BatchScripts; List<string> batchScripts = executor.BatchScripts;
ExecuteSqlBatch(batchScripts, connection); 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(!executor.ParserExecutionError);
Assert.True(CompareTwoStringLists(executor.ErrorMessageQueue, expErrorMessage)); Assert.True(CompareTwoStringLists(executor.ErrorMessageQueue, expErrorMessage));
Assert.True(CompareTwoIntLists(executor.ResultCountQueue, expResultCounts)); Assert.True(CompareTwoIntLists(executor.ResultCountQueue, expResultCounts));
@@ -306,11 +307,12 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
{ {
ExecutionEngine engine = new ExecutionEngine(); ExecutionEngine engine = new ExecutionEngine();
Assert.True(ConnectionDiscardWrapper(engine)); Assert.True(ConnectionDiscardWrapper(engine));
} }
#endregion
#endregion Invalid Scripts
#region Different execution conditions #region Different execution conditions
/// <summary> /// <summary>
/// Test HaltOnError execution condition /// Test HaltOnError execution condition
/// </summary> /// </summary>
@@ -334,7 +336,6 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
Assert.True(CompareTwoStringLists(executor.ErrorMessageQueue, expErrorMessage)); Assert.True(CompareTwoStringLists(executor.ErrorMessageQueue, expErrorMessage));
Assert.True(CompareTwoIntLists(executor.ResultCountQueue, expResultCounts)); Assert.True(CompareTwoIntLists(executor.ResultCountQueue, expResultCounts));
Assert.True(executor.ResultCountQueue.Count == 0); Assert.True(executor.ResultCountQueue.Count == 0);
} }
/// <summary> /// <summary>
@@ -361,7 +362,6 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
Assert.True(CompareTwoIntLists(executor.ResultCountQueue, expResultCounts)); Assert.True(CompareTwoIntLists(executor.ResultCountQueue, expResultCounts));
Assert.True(executor.ResultCountQueue.Count == 0); Assert.True(executor.ResultCountQueue.Count == 0);
Assert.Equal(0, executor.BatchFinshedEventCounter); Assert.Equal(0, executor.BatchFinshedEventCounter);
} }
/// <summary> /// <summary>
@@ -464,7 +464,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
// 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 // 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> /// <summary>
@@ -489,9 +489,11 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
Assert.Equal(ScriptExecutionResult.Success, executor.ExecutionResult); Assert.Equal(ScriptExecutionResult.Success, executor.ExecutionResult);
Assert.True(CompareTwoIntLists(executor.ResultCountQueue, expResultCounts)); Assert.True(CompareTwoIntLists(executor.ResultCountQueue, expResultCounts));
} }
#endregion
#endregion Different execution conditions
#region SQL Commands #region SQL Commands
/// <summary> /// <summary>
/// Test with SQL commands /// Test with SQL commands
/// </summary> /// </summary>
@@ -526,11 +528,12 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
executor.Run(); executor.Run();
Assert.True(executor.ResultCountQueue.Count == 0); Assert.True(executor.ResultCountQueue.Count == 0);
} }
} }
#endregion
#endregion SQL Commands
#region Threading #region Threading
/// <summary> /// <summary>
/// Test synchronous cancel /// Test synchronous cancel
/// </summary> /// </summary>
@@ -551,7 +554,6 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
Assert.NotNull(executor.ScriptExecuteThread); Assert.NotNull(executor.ScriptExecuteThread);
Assert.Equal(ScriptExecutionResult.Cancel, executor.ExecutionResult); Assert.Equal(ScriptExecutionResult.Cancel, executor.ExecutionResult);
Assert.True(executor.CancelEventFired); Assert.True(executor.CancelEventFired);
} }
/// <summary> /// <summary>
@@ -588,7 +590,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
//TEST_DOESNOTWORK[TestMethod()] //TEST_DOESNOTWORK[TestMethod()]
public void ExecutionEngineTest_SyncCancelAfterExecutionDone() public void ExecutionEngineTest_SyncCancelAfterExecutionDone()
{ {
string sqlStatement = "select 1" ; string sqlStatement = "select 1";
ExecutionEngineConditions conditions = new ExecutionEngineConditions(); ExecutionEngineConditions conditions = new ExecutionEngineConditions();
conditions.IsTransactionWrapped = true; conditions.IsTransactionWrapped = true;
@@ -603,7 +605,6 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
if (executor.ScriptExecuteThread != null) if (executor.ScriptExecuteThread != null)
Assert.True(!executor.ScriptExecuteThread.IsAlive); Assert.True(!executor.ScriptExecuteThread.IsAlive);
Assert.Equal(ScriptExecutionResult.Success | ScriptExecutionResult.Cancel, executor.ExecutionResult); Assert.Equal(ScriptExecutionResult.Success | ScriptExecutionResult.Cancel, executor.ExecutionResult);
} }
/// <summary> /// <summary>
@@ -612,7 +613,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
[Fact] [Fact]
public void ExecutionEngineTest_ASyncCancelAfterExecutionDone() public void ExecutionEngineTest_ASyncCancelAfterExecutionDone()
{ {
string sqlStatement ="select 1"; string sqlStatement = "select 1";
ExecutionEngineConditions conditions = new ExecutionEngineConditions(); ExecutionEngineConditions conditions = new ExecutionEngineConditions();
conditions.IsTransactionWrapped = true; conditions.IsTransactionWrapped = true;
@@ -688,7 +689,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
await SqlTestDb.DropDatabase(connection3.Database); await SqlTestDb.DropDatabase(connection3.Database);
} }
#endregion #endregion Threading
#region Get/Set Methods #region Get/Set Methods
@@ -751,9 +752,10 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
Assert.Equal(conditions.BatchSeparator, "GO"); Assert.Equal(conditions.BatchSeparator, "GO");
} }
#endregion #endregion Get/Set Methods
#region Private methods #region Private methods
/// <summary> /// <summary>
/// Connection to a database /// Connection to a database
/// </summary> /// </summary>
@@ -830,7 +832,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
private bool CompareTwoStringLists(List<string> l1, List<string> l2) private bool CompareTwoStringLists(List<string> l1, List<string> l2)
{ {
bool isSame = true; bool isSame = true;
if(l1.Count != l2.Count) if (l1.Count != l2.Count)
{ {
isSame = false; isSame = false;
Console.WriteLine("The count of elements in two lists are not the same"); 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); engine.Close(false, true, true);
return 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.ServiceLayer.BatchParser.ExecutionEngineCode;
using Microsoft.SqlTools.Utility; 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 #region Private variables
string sqlStatement;
ExecutionEngineConditions conditions = new ExecutionEngineConditions(); private string sqlStatement;
BatchEventHandler eventHandler = new BatchEventHandler(); private ExecutionEngineConditions conditions = new ExecutionEngineConditions();
SqlConnection connection = null; private BatchEventHandler eventHandler = new BatchEventHandler();
static Thread _executionThread; private SqlConnection connection = null;
bool _syncCancel = true; private static Thread _executionThread;
bool _isFinished = false; private bool _syncCancel = true;
bool _cancel = false; private bool _isFinished = false;
int _cancelTimeout = 500; private bool _cancel = false;
int exeTimeOut = 0; private int _cancelTimeout = 500;
private int exeTimeOut = 0;
//For verification //For verification
List<int> resultCounts = new List<int>(); private List<int> resultCounts = new List<int>();
List<string> sqlMessages = new List<string>();
List<string> errorMessage = new List<string>(); private List<string> sqlMessages = new List<string>();
List<bool> batchFinished = new List<bool>(); private List<string> errorMessage = new List<string>();
static ScriptExecutionResult execResult = ScriptExecutionResult.All; private List<bool> batchFinished = new List<bool>();
static List<string> batchScripts = new List<string>(); private static ScriptExecutionResult execResult = ScriptExecutionResult.All;
static Thread exeThread = null; private static List<string> batchScripts = new List<string>();
static bool parserExecutionError = false; private static Thread exeThread = null;
#endregion private static bool parserExecutionError = false;
#endregion Private variables
#region private methods #region private methods
/// <summary> /// <summary>
/// Execut the script /// Execute the script
/// </summary> /// </summary>
/// <param name="exec">Execution Engine</param> /// <param name="exec">Execution Engine</param>
/// <param name="connection">SQL connection</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="conditions">Execution condition</param>
/// <param name="batchHandler">Batch event handler</param> /// <param name="batchHandler">Batch event handler</param>
/// <param name="timeout">time out value</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(exec), exec);
Validate.IsNotNull(nameof(connection), connection); Validate.IsNotNull(nameof(connection), connection);
@@ -70,7 +74,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
/// <param name="exec">Execution Engine</param> /// <param name="exec">Execution Engine</param>
/// <param name="isSynchronous">Cancel the execution synchronously or not</param> /// <param name="isSynchronous">Cancel the execution synchronously or not</param>
/// <param name="timeout">sycn canceo timeout</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); //exec.BeginCancellingExecution(isSynchronous, timeout);
@@ -109,9 +113,11 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
} }
Thread.Sleep(5000); Thread.Sleep(5000);
} }
#endregion
#endregion private methods
#region Public properties #region Public properties
public bool SyncCancel public bool SyncCancel
{ {
get get
@@ -207,10 +213,12 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
return parserExecutionError; return parserExecutionError;
} }
} }
#endregion
#endregion Public properties
#region Constructors #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)
{ {
} }
@@ -232,16 +240,18 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
batchScripts = new List<string>(); batchScripts = new List<string>();
exeThread = null; exeThread = null;
parserExecutionError = false; parserExecutionError = false;
} }
public TestExecutor(string batch, SqlConnection conn, ExecutionEngineConditions exeCondition, int timeOut) public TestExecutor(string batch, SqlConnection conn, ExecutionEngineConditions exeCondition, int timeOut)
: this(batch, conn, exeCondition, false) : this(batch, conn, exeCondition, false)
{ {
exeTimeOut = timeOut; exeTimeOut = timeOut;
} }
#endregion
#endregion Constructors
#region public methods #region public methods
/// <summary> /// <summary>
/// Execute the test engine /// Execute the test engine
/// </summary> /// </summary>
@@ -282,15 +292,17 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
} }
} }
} }
#endregion
#endregion public methods
#region ParserEvent #region ParserEvent
/// <summary> /// <summary>
/// Called when batch is called /// Called when batch is called
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
static void OnBatchParserExecutionStart(object sender, BatchParserExecutionStartEventArgs e) private static void OnBatchParserExecutionStart(object sender, BatchParserExecutionStartEventArgs e)
{ {
Console.WriteLine("****************"); Console.WriteLine("****************");
Console.WriteLine(e.Batch.Text); Console.WriteLine(e.Batch.Text);
@@ -306,7 +318,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></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); 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) if (execResult == ScriptExecutionResult.All)
@@ -320,12 +332,11 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></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("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); Console.WriteLine("\t Error Description: " + e.Description);
parserExecutionError = true; parserExecutionError = true;
} }
/// <summary> /// <summary>
@@ -341,18 +352,21 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.TSQLExecutionEngine
if (execResult == ScriptExecutionResult.All) if (execResult == ScriptExecutionResult.All)
execResult = e.ExecutionResult; execResult = e.ExecutionResult;
else else
execResult = execResult|e.ExecutionResult; execResult = execResult | e.ExecutionResult;
resultCounts = eventHandler.ResultCounts; resultCounts = eventHandler.ResultCounts;
sqlMessages = eventHandler.SqlMessages; sqlMessages = eventHandler.SqlMessages;
errorMessage = eventHandler.ErrorMessages; errorMessage = eventHandler.ErrorMessages;
} }
#endregion
#endregion ParserEvent
#region IDisposable Members #region IDisposable Members
public void Dispose() 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;
}
}
}
}