From f46fc0c78702023a17bd9f717fbc37cfd2e8541c Mon Sep 17 00:00:00 2001 From: Karl Burtram Date: Fri, 28 Oct 2016 20:33:32 -0700 Subject: [PATCH] Add additional test cases (#125) Test-only changes for code coverage. Please review the comment and I'll include the changes in the next iteration. * Add more tests * Add some more additional test cases --- .../Workspace/Contracts/ScriptFile.cs | 101 ---- .../ServiceHost/AsyncLockTests.cs | 49 ++ .../ServiceHost/AsyncQueueTests.cs | 91 ++++ .../ServiceHost/ScriptFileTests.cs | 502 ++++++++++++++++++ .../Driver/ServiceTestDriver.cs | 4 +- .../Program.cs | 3 + .../Tests/ConnectionTests.cs | 45 ++ .../Tests/LanguageServiceTests.cs | 2 - .../Tests/QueryExecutionTests.cs | 41 +- 9 files changed, 732 insertions(+), 106 deletions(-) create mode 100644 test/Microsoft.SqlTools.ServiceLayer.Test/ServiceHost/AsyncLockTests.cs create mode 100644 test/Microsoft.SqlTools.ServiceLayer.Test/ServiceHost/AsyncQueueTests.cs create mode 100644 test/Microsoft.SqlTools.ServiceLayer.Test/ServiceHost/ScriptFileTests.cs create mode 100644 test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/ConnectionTests.cs 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);