diff --git a/src/Microsoft.SqlTools.ServiceLayer/Workspace/Contracts/ScriptFile.cs b/src/Microsoft.SqlTools.ServiceLayer/Workspace/Contracts/ScriptFile.cs
index 279f9b7f..4cb5948c 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Workspace/Contracts/ScriptFile.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/Workspace/Contracts/ScriptFile.cs
@@ -94,15 +94,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Workspace.Contracts
private set;
}
- ///
- /// Gets the array of filepaths dot sourced in this ScriptFile
- ///
- public string[] ReferencedFiles
- {
- get;
- private set;
- }
-
#endregion
#region Constructors
@@ -299,9 +290,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Workspace.Contracts
this.FileLines.Insert(currentLineNumber - 1, finalLine);
currentLineNumber++;
}
-
- // Parse the script again to be up-to-date
- this.ParseFileContents();
}
///
@@ -447,97 +435,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Workspace.Contracts
.Split('\n')
.Select(line => line.TrimEnd('\r'))
.ToList();
-
- // Parse the contents to get syntax tree and errors
- this.ParseFileContents();
}
#endregion
-
- #region Private Methods
-
- ///
- /// Parses the current file contents to get the AST, tokens,
- /// and parse errors.
- ///
- private void ParseFileContents()
- {
-#if false
- ParseError[] parseErrors = null;
-
- // First, get the updated file range
- int lineCount = this.FileLines.Count;
- if (lineCount > 0)
- {
- this.FileRange =
- new BufferRange(
- new BufferPosition(1, 1),
- new BufferPosition(
- lineCount + 1,
- this.FileLines[lineCount - 1].Length + 1));
- }
- else
- {
- this.FileRange = BufferRange.None;
- }
-
- try
- {
-#if SqlToolsv5r2
- // This overload appeared with Windows 10 Update 1
- if (this.SqlToolsVersion.Major >= 5 &&
- this.SqlToolsVersion.Build >= 10586)
- {
- // Include the file path so that module relative
- // paths are evaluated correctly
- this.ScriptAst =
- Parser.ParseInput(
- this.Contents,
- this.FilePath,
- out this.scriptTokens,
- out parseErrors);
- }
- else
- {
- this.ScriptAst =
- Parser.ParseInput(
- this.Contents,
- out this.scriptTokens,
- out parseErrors);
- }
-#else
- this.ScriptAst =
- Parser.ParseInput(
- this.Contents,
- out this.scriptTokens,
- out parseErrors);
-#endif
- }
- catch (RuntimeException ex)
- {
- var parseError =
- new ParseError(
- null,
- ex.ErrorRecord.FullyQualifiedErrorId,
- ex.Message);
-
- parseErrors = new[] { parseError };
- this.scriptTokens = new Token[0];
- this.ScriptAst = null;
- }
-
- // Translate parse errors into syntax markers
- this.SyntaxMarkers =
- parseErrors
- .Select(ScriptFileMarker.FromParseError)
- .ToArray();
-
- //Get all dot sourced referenced files and store them
- this.ReferencedFiles =
- AstOperations.FindDotSourcedIncludes(this.ScriptAst);
-#endif
- }
-
-#endregion
}
}
diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/ServiceHost/AsyncLockTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/ServiceHost/AsyncLockTests.cs
new file mode 100644
index 00000000..fdf966c9
--- /dev/null
+++ b/test/Microsoft.SqlTools.ServiceLayer.Test/ServiceHost/AsyncLockTests.cs
@@ -0,0 +1,49 @@
+//
+// 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.Threading;
+using System.Threading.Tasks;
+using Microsoft.SqlTools.ServiceLayer.Utility;
+using Xunit;
+
+namespace Microsoft.SqlTools.ServiceLayer.Test.ServiceHost
+{
+ public class AsyncLockTests
+ {
+ [Fact]
+ public async Task AsyncLockSynchronizesAccess()
+ {
+ AsyncLock asyncLock = new AsyncLock();
+
+ Task lockOne = asyncLock.LockAsync();
+ Task lockTwo = asyncLock.LockAsync();
+
+ Assert.Equal(TaskStatus.RanToCompletion, lockOne.Status);
+ Assert.Equal(TaskStatus.WaitingForActivation, lockTwo.Status);
+ lockOne.Result.Dispose();
+
+ await lockTwo;
+ Assert.Equal(TaskStatus.RanToCompletion, lockTwo.Status);
+ }
+
+ [Fact]
+ public void AsyncLockCancelsWhenRequested()
+ {
+ CancellationTokenSource cts = new CancellationTokenSource();
+ AsyncLock asyncLock = new AsyncLock();
+
+ Task lockOne = asyncLock.LockAsync();
+ Task lockTwo = asyncLock.LockAsync(cts.Token);
+
+ // Cancel the second lock before the first is released
+ cts.Cancel();
+ lockOne.Result.Dispose();
+
+ Assert.Equal(TaskStatus.RanToCompletion, lockOne.Status);
+ Assert.Equal(TaskStatus.Canceled, lockTwo.Status);
+ }
+ }
+}
diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/ServiceHost/AsyncQueueTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/ServiceHost/AsyncQueueTests.cs
new file mode 100644
index 00000000..df268417
--- /dev/null
+++ b/test/Microsoft.SqlTools.ServiceLayer.Test/ServiceHost/AsyncQueueTests.cs
@@ -0,0 +1,91 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.SqlTools.ServiceLayer.Utility;
+using Xunit;
+
+namespace Microsoft.SqlTools.ServiceLayer.Test.ServiceHost
+{
+ public class AsyncQueueTests
+ {
+ [Fact]
+ public async Task AsyncQueueSynchronizesAccess()
+ {
+ ConcurrentBag outputItems = new ConcurrentBag();
+ AsyncQueue inputQueue = new AsyncQueue(Enumerable.Range(0, 100));
+ CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
+
+ try
+ {
+ // Start 5 consumers
+ await Task.WhenAll(
+ Task.Run(() => ConsumeItems(inputQueue, outputItems, cancellationTokenSource.Token)),
+ Task.Run(() => ConsumeItems(inputQueue, outputItems, cancellationTokenSource.Token)),
+ Task.Run(() => ConsumeItems(inputQueue, outputItems, cancellationTokenSource.Token)),
+ Task.Run(() => ConsumeItems(inputQueue, outputItems, cancellationTokenSource.Token)),
+ Task.Run(() => ConsumeItems(inputQueue, outputItems, cancellationTokenSource.Token)),
+ Task.Run(
+ async () =>
+ {
+ // Wait for a bit and then add more items to the queue
+ await Task.Delay(250);
+
+ foreach (var i in Enumerable.Range(100, 200))
+ {
+ await inputQueue.EnqueueAsync(i);
+ }
+
+ // Cancel the waiters
+ cancellationTokenSource.Cancel();
+ }));
+ }
+ catch (TaskCanceledException)
+ {
+ // Do nothing, this is expected.
+ }
+
+ // At this point, numbers 0 through 299 should be in the outputItems
+ IEnumerable expectedItems = Enumerable.Range(0, 300);
+ Assert.Equal(0, expectedItems.Except(outputItems).Count());
+ }
+
+ [Fact]
+ public async Task AsyncQueueSkipsCancelledTasks()
+ {
+ AsyncQueue inputQueue = new AsyncQueue();
+
+ // Queue up a couple of tasks to wait for input
+ CancellationTokenSource cancellationSource = new CancellationTokenSource();
+ Task taskOne = inputQueue.DequeueAsync(cancellationSource.Token);
+ Task taskTwo = inputQueue.DequeueAsync();
+
+ // Cancel the first task and then enqueue a number
+ cancellationSource.Cancel();
+ await inputQueue.EnqueueAsync(1);
+
+ // Did the second task get the number?
+ Assert.Equal(TaskStatus.Canceled, taskOne.Status);
+ Assert.Equal(TaskStatus.RanToCompletion, taskTwo.Status);
+ Assert.Equal(1, taskTwo.Result);
+ }
+
+ private async Task ConsumeItems(
+ AsyncQueue inputQueue,
+ ConcurrentBag outputItems,
+ CancellationToken cancellationToken)
+ {
+ while (!cancellationToken.IsCancellationRequested)
+ {
+ int consumedItem = await inputQueue.DequeueAsync(cancellationToken);
+ outputItems.Add(consumedItem);
+ }
+ }
+ }
+}
diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/ServiceHost/ScriptFileTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/ServiceHost/ScriptFileTests.cs
new file mode 100644
index 00000000..b3efd939
--- /dev/null
+++ b/test/Microsoft.SqlTools.ServiceLayer.Test/ServiceHost/ScriptFileTests.cs
@@ -0,0 +1,502 @@
+//
+// 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.IO;
+using System.Linq;
+using Microsoft.SqlTools.ServiceLayer.Utility;
+using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts;
+using Xunit;
+
+namespace Microsoft.SqlTools.ServiceLayer.Test.ServiceHost
+{
+ ///
+ /// ScriptFile test case
+ ///
+ public class ScriptFileTests
+ {
+ internal static object fileLock = new object();
+
+ private static readonly string query =
+ "SELECT * FROM sys.objects as o1" + Environment.NewLine +
+ "SELECT * FROM sys.objects as o2" + Environment.NewLine +
+ "SELECT * FROM sys.objects as o3" + Environment.NewLine;
+
+ internal static ScriptFile GetTestScriptFile(string initialText = null)
+ {
+ if (initialText == null)
+ {
+ initialText = ScriptFileTests.query;
+ }
+
+ string ownerUri = System.IO.Path.GetTempFileName();
+
+ // Write the query text to a backing file
+ lock (fileLock)
+ {
+ System.IO.File.WriteAllText(ownerUri, initialText);
+ }
+
+ return new ScriptFile(ownerUri, ownerUri, initialText);
+ }
+
+ ///
+ /// Validate GetLinesInRange with invalid range
+ ///
+ [Fact]
+ public void GetLinesInRangeWithInvalidRangeTest()
+ {
+ ScriptFile scriptFile = GetTestScriptFile();
+
+ bool exceptionRaised = false;
+ try
+ {
+ scriptFile.GetLinesInRange(
+ new BufferRange(
+ new BufferPosition(1, 0),
+ new BufferPosition(2, 0)));
+ }
+ catch (ArgumentOutOfRangeException)
+ {
+ exceptionRaised = true;
+ }
+
+ Assert.True(exceptionRaised, "ArgumentOutOfRangeException raised for invalid index");
+
+ }
+
+ ///
+ /// Validate GetLinesInRange
+ ///
+ [Fact]
+ public void GetLinesInRangeTest()
+ {
+ ScriptFile scriptFile = GetTestScriptFile();
+
+ string id = scriptFile.Id;
+ Assert.True(!string.IsNullOrWhiteSpace(id));
+
+ BufferRange range =scriptFile.FileRange;
+ Assert.Null(range);
+
+ string[] lines = scriptFile.GetLinesInRange(
+ new BufferRange(
+ new BufferPosition(2, 1),
+ new BufferPosition(2, 7)));
+
+ Assert.True(lines.Length == 1, "One line in range");
+ Assert.True(lines[0].Equals("SELECT"), "Range text is correct");
+
+ string[] queryLines = query.Split('\n');
+
+ string line = scriptFile.GetLine(2);
+ Assert.True(queryLines[1].StartsWith(line), "GetLine text is correct");
+ }
+
+ [Fact]
+ public void GetOffsetAtPositionTest()
+ {
+ ScriptFile scriptFile = GetTestScriptFile();
+ int offset = scriptFile.GetOffsetAtPosition(2, 5);
+ Assert.True(offset == 37, "Offset is at expected location");
+
+ BufferPosition position = scriptFile.GetPositionAtOffset(offset);
+ Assert.True(position.Line == 2 && position.Column == 5, "Position is at expected location");
+ }
+
+ [Fact]
+ public void GetRangeBetweenOffsetsTest()
+ {
+ ScriptFile scriptFile = GetTestScriptFile();
+ BufferRange range = scriptFile.GetRangeBetweenOffsets(
+ scriptFile.GetOffsetAtPosition(2, 1),
+ scriptFile.GetOffsetAtPosition(2, 7));
+ Assert.NotNull(range);
+ }
+
+ [Fact]
+ public void CanApplySingleLineInsert()
+ {
+ this.AssertFileChange(
+ "This is a test.",
+ "This is a working test.",
+ new FileChange
+ {
+ Line = 1,
+ EndLine = 1,
+ Offset = 10,
+ EndOffset = 10,
+ InsertString = " working"
+ });
+ }
+
+ [Fact]
+ public void CanApplySingleLineReplace()
+ {
+ this.AssertFileChange(
+ "This is a potentially broken test.",
+ "This is a working test.",
+ new FileChange
+ {
+ Line = 1,
+ EndLine = 1,
+ Offset = 11,
+ EndOffset = 29,
+ InsertString = "working"
+ });
+ }
+
+ [Fact]
+ public void CanApplySingleLineDelete()
+ {
+ this.AssertFileChange(
+ "This is a test of the emergency broadcasting system.",
+ "This is a test.",
+ new FileChange
+ {
+ Line = 1,
+ EndLine = 1,
+ Offset = 15,
+ EndOffset = 52,
+ InsertString = ""
+ });
+ }
+
+ [Fact]
+ public void CanApplyMultiLineInsert()
+ {
+ this.AssertFileChange(
+ "first\r\nsecond\r\nfifth",
+ "first\r\nsecond\r\nthird\r\nfourth\r\nfifth",
+ new FileChange
+ {
+ Line = 3,
+ EndLine = 3,
+ Offset = 1,
+ EndOffset = 1,
+ InsertString = "third\r\nfourth\r\n"
+ });
+ }
+
+ [Fact]
+ public void CanApplyMultiLineReplace()
+ {
+ this.AssertFileChange(
+ "first\r\nsecoXX\r\nXXfth",
+ "first\r\nsecond\r\nthird\r\nfourth\r\nfifth",
+ new FileChange
+ {
+ Line = 2,
+ EndLine = 3,
+ Offset = 5,
+ EndOffset = 3,
+ InsertString = "nd\r\nthird\r\nfourth\r\nfi"
+ });
+ }
+
+ [Fact]
+ public void CanApplyMultiLineReplaceWithRemovedLines()
+ {
+ this.AssertFileChange(
+ "first\r\nsecoXX\r\nREMOVE\r\nTHESE\r\nLINES\r\nXXfth",
+ "first\r\nsecond\r\nthird\r\nfourth\r\nfifth",
+ new FileChange
+ {
+ Line = 2,
+ EndLine = 6,
+ Offset = 5,
+ EndOffset = 3,
+ InsertString = "nd\r\nthird\r\nfourth\r\nfi"
+ });
+ }
+
+ [Fact]
+ public void CanApplyMultiLineDelete()
+ {
+ this.AssertFileChange(
+ "first\r\nsecond\r\nREMOVE\r\nTHESE\r\nLINES\r\nthird",
+ "first\r\nsecond\r\nthird",
+ new FileChange
+ {
+ Line = 3,
+ EndLine = 6,
+ Offset = 1,
+ EndOffset = 1,
+ InsertString = ""
+ });
+ }
+
+ [Fact]
+ public void ThrowsExceptionWithEditOutsideOfRange()
+ {
+ Assert.Throws(
+ typeof(ArgumentOutOfRangeException),
+ () =>
+ {
+ this.AssertFileChange(
+ "first\r\nsecond\r\nREMOVE\r\nTHESE\r\nLINES\r\nthird",
+ "first\r\nsecond\r\nthird",
+ new FileChange
+ {
+ Line = 3,
+ EndLine = 7,
+ Offset = 1,
+ EndOffset = 1,
+ InsertString = ""
+ });
+ });
+ }
+
+ private void AssertFileChange(
+ string initialString,
+ string expectedString,
+ FileChange fileChange)
+ {
+ // Create an in-memory file from the StringReader
+ ScriptFile fileToChange = GetTestScriptFile(initialString);
+
+ // Apply the FileChange and assert the resulting contents
+ fileToChange.ApplyChange(fileChange);
+ Assert.Equal(expectedString, fileToChange.Contents);
+ }
+ }
+
+ public class ScriptFileGetLinesTests
+ {
+ private ScriptFile scriptFile;
+
+ private const string TestString = "Line One\r\nLine Two\r\nLine Three\r\nLine Four\r\nLine Five";
+ private readonly string[] TestStringLines =
+ TestString.Split(
+ new string[] { "\r\n" },
+ StringSplitOptions.None);
+
+ public ScriptFileGetLinesTests()
+ {
+ this.scriptFile =
+ ScriptFileTests.GetTestScriptFile(
+ "Line One\r\nLine Two\r\nLine Three\r\nLine Four\r\nLine Five\r\n");
+ }
+
+ [Fact]
+ public void CanGetWholeLine()
+ {
+ string[] lines =
+ this.scriptFile.GetLinesInRange(
+ new BufferRange(5, 1, 5, 10));
+
+ Assert.Equal(1, lines.Length);
+ Assert.Equal("Line Five", lines[0]);
+ }
+
+ [Fact]
+ public void CanGetMultipleWholeLines()
+ {
+ string[] lines =
+ this.scriptFile.GetLinesInRange(
+ new BufferRange(2, 1, 4, 10));
+
+ Assert.Equal(TestStringLines.Skip(1).Take(3), lines);
+ }
+
+ [Fact]
+ public void CanGetSubstringInSingleLine()
+ {
+ string[] lines =
+ this.scriptFile.GetLinesInRange(
+ new BufferRange(4, 3, 4, 8));
+
+ Assert.Equal(1, lines.Length);
+ Assert.Equal("ne Fo", lines[0]);
+ }
+
+ [Fact]
+ public void CanGetEmptySubstringRange()
+ {
+ string[] lines =
+ this.scriptFile.GetLinesInRange(
+ new BufferRange(4, 3, 4, 3));
+
+ Assert.Equal(1, lines.Length);
+ Assert.Equal("", lines[0]);
+ }
+
+ [Fact]
+ public void CanGetSubstringInMultipleLines()
+ {
+ string[] expectedLines = new string[]
+ {
+ "Two",
+ "Line Three",
+ "Line Fou"
+ };
+
+ string[] lines =
+ this.scriptFile.GetLinesInRange(
+ new BufferRange(2, 6, 4, 9));
+
+ Assert.Equal(expectedLines, lines);
+ }
+
+ [Fact]
+ public void CanGetRangeAtLineBoundaries()
+ {
+ string[] expectedLines = new string[]
+ {
+ "",
+ "Line Three",
+ ""
+ };
+
+ string[] lines =
+ this.scriptFile.GetLinesInRange(
+ new BufferRange(2, 9, 4, 1));
+
+ Assert.Equal(expectedLines, lines);
+ }
+ }
+
+ public class ScriptFilePositionTests
+ {
+ private ScriptFile scriptFile;
+
+ public ScriptFilePositionTests()
+ {
+ this.scriptFile =
+ ScriptFileTests.GetTestScriptFile(@"
+First line
+ Second line is longer
+ Third line
+");
+ }
+
+ [Fact]
+ public void CanOffsetByLine()
+ {
+ this.AssertNewPosition(
+ 1, 1,
+ 2, 0,
+ 3, 1);
+
+ this.AssertNewPosition(
+ 3, 1,
+ -2, 0,
+ 1, 1);
+ }
+
+ [Fact]
+ public void CanOffsetByColumn()
+ {
+ this.AssertNewPosition(
+ 2, 1,
+ 0, 2,
+ 2, 3);
+
+ this.AssertNewPosition(
+ 2, 5,
+ 0, -3,
+ 2, 2);
+ }
+
+ [Fact]
+ public void ThrowsWhenPositionOutOfRange()
+ {
+ // Less than line range
+ Assert.Throws(
+ typeof(ArgumentOutOfRangeException),
+ () =>
+ {
+ scriptFile.CalculatePosition(
+ new BufferPosition(1, 1),
+ -10, 0);
+ });
+
+ // Greater than line range
+ Assert.Throws(
+ typeof(ArgumentOutOfRangeException),
+ () =>
+ {
+ scriptFile.CalculatePosition(
+ new BufferPosition(1, 1),
+ 10, 0);
+ });
+
+ // Less than column range
+ Assert.Throws(
+ typeof(ArgumentOutOfRangeException),
+ () =>
+ {
+ scriptFile.CalculatePosition(
+ new BufferPosition(1, 1),
+ 0, -10);
+ });
+
+ // Greater than column range
+ Assert.Throws(
+ typeof(ArgumentOutOfRangeException),
+ () =>
+ {
+ scriptFile.CalculatePosition(
+ new BufferPosition(1, 1),
+ 0, 10);
+ });
+ }
+
+ [Fact]
+ public void CanFindBeginningOfLine()
+ {
+ this.AssertNewPosition(
+ 4, 12,
+ pos => pos.GetLineStart(),
+ 4, 5);
+ }
+
+ [Fact]
+ public void CanFindEndOfLine()
+ {
+ this.AssertNewPosition(
+ 4, 12,
+ pos => pos.GetLineEnd(),
+ 4, 15);
+ }
+
+ [Fact]
+ public void CanComposePositionOperations()
+ {
+ this.AssertNewPosition(
+ 4, 12,
+ pos => pos.AddOffset(-1, 1).GetLineStart(),
+ 3, 3);
+ }
+
+ private void AssertNewPosition(
+ int originalLine, int originalColumn,
+ int lineOffset, int columnOffset,
+ int expectedLine, int expectedColumn)
+ {
+ this.AssertNewPosition(
+ originalLine, originalColumn,
+ pos => pos.AddOffset(lineOffset, columnOffset),
+ expectedLine, expectedColumn);
+ }
+
+ private void AssertNewPosition(
+ int originalLine, int originalColumn,
+ Func positionOperation,
+ int expectedLine, int expectedColumn)
+ {
+ var newPosition =
+ positionOperation(
+ new FilePosition(
+ this.scriptFile,
+ originalLine,
+ originalColumn));
+
+ Assert.Equal(expectedLine, newPosition.Line);
+ Assert.Equal(expectedColumn, newPosition.Column);
+ }
+
+
+ }
+}
diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Driver/ServiceTestDriver.cs b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Driver/ServiceTestDriver.cs
index 6351f032..ce4002f3 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Driver/ServiceTestDriver.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Driver/ServiceTestDriver.cs
@@ -62,8 +62,8 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Driver
{
coverageOutput = "coverage.xml";
}
-
- serviceHostArguments = "-target:" + serviceHostExecutable + " -targetargs:" + serviceHostArguments
+
+ serviceHostArguments = "-mergeoutput -target:" + serviceHostExecutable + " -targetargs:" + serviceHostArguments
+ " -register:user -oldstyle -filter:\"+[Microsoft.SqlTools.*]* -[xunit*]*\" -output:" + coverageOutput + " -searchdirs:" + serviceHostDirectory;
serviceHostExecutable = coverageToolPath;
diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Program.cs b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Program.cs
index c06173fd..42936ec0 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Program.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Program.cs
@@ -8,6 +8,9 @@ using System.Reflection;
using System.Threading.Tasks;
using Microsoft.SqlTools.ServiceLayer.TestDriver.Driver;
using Microsoft.SqlTools.ServiceLayer.Utility;
+using Xunit;
+
+[assembly: CollectionBehavior(DisableTestParallelization = true)]
namespace Microsoft.SqlTools.ServiceLayer.TestDriver
{
diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/ConnectionTests.cs b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/ConnectionTests.cs
new file mode 100644
index 00000000..171649d3
--- /dev/null
+++ b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/ConnectionTests.cs
@@ -0,0 +1,45 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts;
+using Microsoft.SqlTools.ServiceLayer.TestDriver.Utility;
+using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts;
+using Xunit;
+
+namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests
+{
+ ///
+ /// Language Service end-to-end integration tests
+ ///
+ public class ConnectionTests : TestBase
+ {
+ ///
+ /// Try to connect with invalid credentials
+ ///
+ //[Fact]
+ public async Task InvalidConnection()
+ {
+ try
+ {
+ string ownerUri = System.IO.Path.GetTempFileName();
+ bool connected = await Connect(ownerUri, ConnectionTestUtils.InvalidConnection);
+ Assert.False(connected, "Invalid connection is failed to connect");
+
+ await Disconnect(ownerUri);
+ }
+ finally
+ {
+ WaitForExit();
+ }
+ }
+
+ }
+}
diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/LanguageServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/LanguageServiceTests.cs
index 9a6edb47..5480db11 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/LanguageServiceTests.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/LanguageServiceTests.cs
@@ -155,7 +155,6 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests
string query = "SELECT *** FROM sys.objects";
-
DidOpenTextDocumentNotification openParams = new DidOpenTextDocumentNotification()
{
TextDocument = new TextDocumentItem()
@@ -168,7 +167,6 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests
};
await RequestOpenDocumentNotification(openParams);
-
Thread.Sleep(5000);
diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/QueryExecutionTests.cs b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/QueryExecutionTests.cs
index 0552a557..d6d3113c 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/QueryExecutionTests.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/QueryExecutionTests.cs
@@ -10,12 +10,52 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.SqlTools.ServiceLayer.TestDriver.Utility;
+using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts;
using Xunit;
namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests
{
public class QueryExecutionTests : TestBase
{
+ [Fact]
+ public async Task ExecuteBasicQueryTest()
+ {
+ try
+ {
+ string ownerUri = System.IO.Path.GetTempFileName();
+ bool connected = await Connect(ownerUri, ConnectionTestUtils.LocalhostConnection);
+ Assert.True(connected, "Connection is successful");
+
+ Thread.Sleep(500);
+
+ string query = "SELECT * FROM sys.objects";
+
+ DidOpenTextDocumentNotification openParams = new DidOpenTextDocumentNotification()
+ {
+ TextDocument = new TextDocumentItem()
+ {
+ Uri = ownerUri,
+ LanguageId = "enu",
+ Version = 1,
+ Text = query
+ }
+ };
+
+ await RequestOpenDocumentNotification(openParams);
+
+ var queryResult = await RunQuery(ownerUri, query);
+
+ Assert.NotNull(queryResult);
+ Assert.NotNull(queryResult.BatchSummaries);
+
+ await Disconnect(ownerUri);
+ }
+ finally
+ {
+ WaitForExit();
+ }
+ }
+
//[Fact]
public async Task TestQueryingAfterCompletionRequests()
{
@@ -27,7 +67,6 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests
await Connect(ownerUri, ConnectionTestUtils.AzureTestServerConnection);
-
Enumerable.Range(0, 10).ToList().ForEach(arg => tasks.Add(RequestCompletion(ownerUri, query, 0, 10)));
var queryTask = RunQuery(ownerUri, query);
tasks.Add(queryTask);