diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 00000000..1ccae023
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,40 @@
+sudo: required
+dist: trusty
+
+os:
+ - linux
+ - osx
+
+dotnet: 1.0.0-preview2-003131
+
+# safelist
+branches:
+ only:
+ - master
+ - dev
+
+language: csharp
+solution: sqltoolsservice.sln
+
+before_install:
+ - if [ $TRAVIS_OS_NAME == "linux" ]; then
+ sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ trusty main" > /etc/apt/sources.list.d/dotnetdev.list';
+ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 417A0893;
+ sudo apt-get update;
+ sudo apt-get install dotnet-dev-1.0.0-preview2.1-003177;
+ else
+ brew update;
+ brew install openssl;
+ mkdir -p /usr/local/lib;
+ ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/;
+ ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/;
+ brew cask install dotnet;
+ export PATH="/usr/local/share/dotnet/:$PATH";
+ fi
+install:
+ - dotnet restore
+
+script:
+ - dotnet build src/Microsoft.SqlTools.ServiceLayer
+ - dotnet test test/Microsoft.SqlTools.ServiceLayer.Test
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 8282a7ff..c85f7883 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,7 @@
+[](https://travis-ci.org/Microsoft/sqltoolsservice)
+[](https://ci.appveyor.com/project/kburtram/sqltoolsservice)
+[](https://coveralls.io/github/Microsoft/sqltoolsservice?branch=dev)
+
# Microsoft SQL Tools Service
The SQL Tools Service is an application that provides core functionality for various SQL Server tools. These features include the following:
* Connection management
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 00000000..86a04482
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,31 @@
+# Note: This file isn't used in current setup. Instead its parts have been
+# set directly in the AppVeyor project settings - Environment, General, Build, Test sections.
+# This allows us to get Coveralls to run on PRs, but is more work than just using this file.
+# Preserving this here so that it's easy to replicate for others
+environment:
+ COVERALLS_REPO_TOKEN:
+ secure: KjiClJjgj/eB1zo52GBz/CHCmdxj6ut+q6+LD5G3sYhy9Hi4kEF6CWi8vOQPH1oy
+
+# safelist
+branches:
+ only:
+ - master
+ - dev
+
+before_build:
+- appveyor-retry dotnet restore -v Minimal
+
+build_script:
+ - dotnet build src/Microsoft.SqlTools.ServiceLayer
+
+test_script:
+ - dotnet test test/Microsoft.SqlTools.ServiceLayer.Test
+
+after_test:
+ - cd test/CodeCoverage
+ - npm install -g gulp-cli
+ - runintegration.bat
+ - cmd: packages\coveralls.io.1.3.4\tools\coveralls.net.exe --opencover coverage.xml
+
+cache:
+- '%USERPROFILE%\.nuget\packages'
diff --git a/bin/nuget/Microsoft.SqlServer.Smo.140.1.11.nupkg b/bin/nuget/Microsoft.SqlServer.Smo.140.1.11.nupkg
deleted file mode 100644
index f0280385..00000000
Binary files a/bin/nuget/Microsoft.SqlServer.Smo.140.1.11.nupkg and /dev/null differ
diff --git a/bin/nuget/Microsoft.SqlServer.Smo.140.1.12.nupkg b/bin/nuget/Microsoft.SqlServer.Smo.140.1.12.nupkg
new file mode 100644
index 00000000..4eab97ea
Binary files /dev/null and b/bin/nuget/Microsoft.SqlServer.Smo.140.1.12.nupkg differ
diff --git a/nuget.config b/nuget.config
index 6a020190..52296d60 100644
--- a/nuget.config
+++ b/nuget.config
@@ -3,7 +3,8 @@
-
+
+
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs b/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs
index 0ace6c92..1b28daba 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs
@@ -360,19 +360,26 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
if (ServiceHost != null)
{
- // Send a telemetry notification for intellisense performance metrics
- ServiceHost.SendEvent(TelemetryNotification.Type, new TelemetryParams()
+ try
{
- Params = new TelemetryProperties
+ // Send a telemetry notification for intellisense performance metrics
+ ServiceHost.SendEvent(TelemetryNotification.Type, new TelemetryParams()
{
- Properties = new Dictionary
- {
- { "IsAzure", info.IsAzure ? "1" : "0" }
- },
- EventName = TelemetryEventNames.IntellisenseQuantile,
- Measures = info.IntellisenseMetrics.Quantile
- }
- });
+ Params = new TelemetryProperties
+ {
+ Properties = new Dictionary
+ {
+ { "IsAzure", info.IsAzure ? "1" : "0" }
+ },
+ EventName = TelemetryEventNames.IntellisenseQuantile,
+ Measures = info.IntellisenseMetrics.Quantile
+ }
+ });
+ }
+ catch (Exception ex)
+ {
+ Logger.Write(LogLevel.Verbose, "Could not send Connection telemetry event " + ex.ToString());
+ }
}
// Close the connection
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/AmbientSettings.cs b/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/AmbientSettings.cs
index fc8e7302..f1022ecb 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/AmbientSettings.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/AmbientSettings.cs
@@ -48,12 +48,12 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection
internal const string DoNotSerializeQueryStoreSettingsIndex = "DoNotSerializeQueryStoreSettings";
internal const string AlwaysEncryptedWizardMigrationIndex = "AlwaysEncryptedWizardMigration";
- private static readonly AmbientData _defaultSettings;
+ internal static AmbientData _defaultSettings;
static AmbientSettings()
{
_defaultSettings = new AmbientData();
- }
+ }
///
/// Access to the default ambient settings. Access to these settings is made available
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/ReliableConnectionHelper.cs b/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/ReliableConnectionHelper.cs
index 4f31fcf3..3ce8c9e8 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/ReliableConnectionHelper.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/ReliableConnectionHelper.cs
@@ -801,7 +801,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection
public string DatabaseName;
}
- private static bool TryGetConnectionStringBuilder(string connectionString, out SqlConnectionStringBuilder builder)
+ internal static bool TryGetConnectionStringBuilder(string connectionString, out SqlConnectionStringBuilder builder)
{
builder = null;
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/ReliableSqlCommand.cs b/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/ReliableSqlCommand.cs
index 4f051688..eaacdfb0 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/ReliableSqlCommand.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/ReliableSqlCommand.cs
@@ -235,7 +235,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection
return _command;
}
- private void ValidateConnectionIsSet()
+ internal void ValidateConnectionIsSet()
{
if (_connection == null)
{
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/RetryLimitExceededException.cs b/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/RetryLimitExceededException.cs
index 0ae8b4e7..c4f99e59 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/RetryLimitExceededException.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/RetryLimitExceededException.cs
@@ -34,5 +34,12 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection
[Serializable]
internal sealed class RetryLimitExceededException : Exception
{
+ internal RetryLimitExceededException() : base()
+ {
+ }
+
+ internal RetryLimitExceededException(string m, Exception e) : base(m, e)
+ {
+ }
}
}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/RetryPolicy.cs b/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/RetryPolicy.cs
index 23159d3e..37be0b15 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/RetryPolicy.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/RetryPolicy.cs
@@ -292,7 +292,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection
}
*/
- private static int? GetErrorNumber(Exception ex)
+ internal static int? GetErrorNumber(Exception ex)
{
SqlException sqlEx = ex as SqlException;
if (sqlEx == null)
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Hosting/Protocol/Constants.cs b/src/Microsoft.SqlTools.ServiceLayer/Hosting/Protocol/Constants.cs
index 14f3d762..7daa6b97 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Hosting/Protocol/Constants.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/Hosting/Protocol/Constants.cs
@@ -13,6 +13,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Hosting.Protocol
public const string ContentLengthFormatString = "Content-Length: {0}\r\n\r\n";
public static readonly JsonSerializerSettings JsonSerializerSettings;
+ public static readonly string SqlLoginAuthenticationType = "SqlLogin";
+
static Constants()
{
JsonSerializerSettings = new JsonSerializerSettings();
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Hosting/Protocol/MessageDispatcher.cs b/src/Microsoft.SqlTools.ServiceLayer/Hosting/Protocol/MessageDispatcher.cs
index 3b3d11c8..4c711cdb 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Hosting/Protocol/MessageDispatcher.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/Hosting/Protocol/MessageDispatcher.cs
@@ -23,10 +23,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Hosting.Protocol
private AsyncContextThread messageLoopThread;
- private Dictionary> requestHandlers =
+ internal Dictionary> requestHandlers =
new Dictionary>();
- private Dictionary> eventHandlers =
+ internal Dictionary> eventHandlers =
new Dictionary>();
private Action responseHandler;
@@ -218,10 +218,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Hosting.Protocol
{
string message = string.Format("Exception occurred while parsing message: {0}", e.Message);
Logger.Write(LogLevel.Error, message);
- await MessageWriter.WriteEvent(HostingErrorEvent.Type, new HostingErrorParams
- {
- Message = message
- });
+ await MessageWriter.WriteEvent(HostingErrorEvent.Type, new HostingErrorParams { Message = message });
// Continue the loop
continue;
@@ -236,10 +233,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Hosting.Protocol
// Log the error and send an error event to the client
string message = string.Format("Exception occurred while receiving message: {0}", e.Message);
Logger.Write(LogLevel.Error, message);
- await MessageWriter.WriteEvent(HostingErrorEvent.Type, new HostingErrorParams
- {
- Message = message
- });
+ await MessageWriter.WriteEvent(HostingErrorEvent.Type, new HostingErrorParams { Message = message });
// Continue the loop
continue;
@@ -273,10 +267,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Hosting.Protocol
{
handlerToAwait = requestHandler(messageToDispatch, messageWriter);
}
- else
- {
- // TODO: Message not supported error
- }
+ // else
+ // {
+ // // TODO: Message not supported error
+ // }
}
else if (messageToDispatch.MessageType == MessageType.Response)
{
@@ -297,10 +291,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Hosting.Protocol
// TODO: Message not supported error
}
}
- else
- {
- // TODO: Return message not supported
- }
+ // else
+ // {
+ // // TODO: Return message not supported
+ // }
if (handlerToAwait != null)
{
@@ -325,7 +319,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Hosting.Protocol
}
}
- private void OnListenTaskCompleted(Task listenTask)
+ internal void OnListenTaskCompleted(Task listenTask)
{
if (listenTask.IsFaulted)
{
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Hosting/Protocol/Serializers/V8MessageSerializer.cs b/src/Microsoft.SqlTools.ServiceLayer/Hosting/Protocol/Serializers/V8MessageSerializer.cs
index f1385e00..f0e144e6 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Hosting/Protocol/Serializers/V8MessageSerializer.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/Hosting/Protocol/Serializers/V8MessageSerializer.cs
@@ -89,10 +89,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Serializers
messageJson.GetValue("message"));
}
}
- else
- {
- // TODO: Parse error
- }
+ // else
+ // {
+ // // TODO: Parse error
+ // }
}
else if (string.Equals("event", messageType, StringComparison.CurrentCultureIgnoreCase))
diff --git a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/BindingQueue.cs b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/BindingQueue.cs
index 07623afb..b7808509 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/BindingQueue.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/BindingQueue.cs
@@ -57,7 +57,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
///
/// Queue a binding request item
///
- public QueueItem QueueBindingOperation(
+ public virtual QueueItem QueueBindingOperation(
string key,
Func bindOperation,
Func timeoutOperation = null,
diff --git a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/Contracts/Definition.cs b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/Contracts/Definition.cs
index d17930e1..61ba3f82 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/Contracts/Definition.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/Contracts/Definition.cs
@@ -14,5 +14,16 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts
RequestType Type =
RequestType.Create("textDocument/definition");
}
+
+ ///
+ /// Error object for Definition
+ ///
+ public class DefinitionError
+ {
+ ///
+ /// Error message
+ ///
+ public string message { get; set; }
+ }
}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/Contracts/StatusChangedNotification.cs b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/Contracts/StatusChangedNotification.cs
new file mode 100644
index 00000000..4e5d1b92
--- /dev/null
+++ b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/Contracts/StatusChangedNotification.cs
@@ -0,0 +1,35 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Contracts;
+
+namespace Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts
+{
+ ///
+ /// Parameters sent back with an status change event
+ ///
+ public class StatusChangeParams
+ {
+ ///
+ /// URI identifying the text document
+ ///
+ public string OwnerUri { get; set; }
+
+ ///
+ /// The new status for the document
+ ///
+ public string Status { get; set; }
+ }
+
+ ///
+ /// Event sent for language service status change notification
+ ///
+ public class StatusChangedNotification
+ {
+ public static readonly
+ EventType Type =
+ EventType.Create("textDocument/statusChanged");
+ }
+}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/DocumentStatusHelper.cs b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/DocumentStatusHelper.cs
new file mode 100644
index 00000000..8e580196
--- /dev/null
+++ b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/DocumentStatusHelper.cs
@@ -0,0 +1,58 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+using System.Threading.Tasks;
+using Microsoft.SqlTools.ServiceLayer.Hosting;
+using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol;
+using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts;
+using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts;
+
+namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
+{
+ ///
+ /// Helper class to send events to the client
+ ///
+ public class DocumentStatusHelper
+ {
+ public const string DefinitionRequested = "DefinitionRequested";
+ public const string DefinitionRequestCompleted = "DefinitionRequestCompleted";
+
+ ///
+ /// Sends an event for specific document using the existing request context
+ ///
+ public static void SendStatusChange(RequestContext requestContext, TextDocumentPosition textDocumentPosition, string status)
+ {
+ Task.Factory.StartNew(async () =>
+ {
+ if (requestContext != null)
+ {
+ string ownerUri = textDocumentPosition != null && textDocumentPosition.TextDocument != null ? textDocumentPosition.TextDocument.Uri : "";
+ await requestContext.SendEvent(StatusChangedNotification.Type, new StatusChangeParams()
+ {
+ OwnerUri = ownerUri,
+ Status = status
+ });
+ }
+ });
+ }
+
+ ///
+ /// Sends a telemetry event for specific document using the existing request context
+ ///
+ public static void SendTelemetryEvent(RequestContext requestContext, string telemetryEvent)
+ {
+ Task.Factory.StartNew(async () =>
+ {
+ await requestContext.SendEvent(TelemetryNotification.Type, new TelemetryParams()
+ {
+ Params = new TelemetryProperties
+ {
+ EventName = telemetryEvent
+ }
+ });
+ });
+ }
+ }
+}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/LanguageService.cs b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/LanguageService.cs
index c5f3ae3b..b123c76c 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/LanguageService.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/LanguageService.cs
@@ -236,6 +236,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
// Store the SqlToolsContext for future use
Context = context;
+
}
#endregion
@@ -282,7 +283,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
///
///
///
- private static async Task HandleCompletionResolveRequest(
+ internal static async Task HandleCompletionResolveRequest(
CompletionItem completionItem,
RequestContext requestContext)
{
@@ -300,28 +301,37 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
internal static async Task HandleDefinitionRequest(TextDocumentPosition textDocumentPosition, RequestContext requestContext)
{
+ // Send a notification to signal that definition is sent
+ await requestContext.SendEvent(TelemetryNotification.Type, new TelemetryParams()
+ {
+ Params = new TelemetryProperties
+ {
+ EventName = TelemetryEventNames.PeekDefinitionRequested
+ }
+ });
+ DocumentStatusHelper.SendTelemetryEvent(requestContext, TelemetryEventNames.PeekDefinitionRequested);
+ DocumentStatusHelper.SendStatusChange(requestContext, textDocumentPosition, DocumentStatusHelper.DefinitionRequested);
+
if (WorkspaceService.Instance.CurrentSettings.IsIntelliSenseEnabled)
{
// Retrieve document and connection
ConnectionInfo connInfo;
var scriptFile = LanguageService.WorkspaceServiceInstance.Workspace.GetFile(textDocumentPosition.TextDocument.Uri);
LanguageService.ConnectionServiceInstance.TryFindConnection(scriptFile.ClientFilePath, out connInfo);
-
- Location[] locations = LanguageService.Instance.GetDefinition(textDocumentPosition, scriptFile, connInfo);
- if (locations != null)
- {
- await requestContext.SendResult(locations);
-
- // Send a notification to signal that definition is sent
- await ServiceHost.Instance.SendEvent(TelemetryNotification.Type, new TelemetryParams()
+ DefinitionResult definitionResult = LanguageService.Instance.GetDefinition(textDocumentPosition, scriptFile, connInfo);
+ if (definitionResult != null)
+ {
+ if (definitionResult.IsErrorResult)
{
- Params = new TelemetryProperties
- {
- EventName = TelemetryEventNames.PeekDefinitionRequested
- }
- });
+ await requestContext.SendError( new DefinitionError { message = definitionResult.Message });
+ }
+ else
+ {
+ await requestContext.SendResult(definitionResult.Locations);
+ }
}
}
+ DocumentStatusHelper.SendStatusChange(requestContext, textDocumentPosition, DocumentStatusHelper.DefinitionRequestCompleted);
}
// turn off this code until needed (10/28/2016)
@@ -341,7 +351,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
}
#endif
- private static async Task HandleSignatureHelpRequest(
+ internal static async Task HandleSignatureHelpRequest(
TextDocumentPosition textDocumentPosition,
RequestContext requestContext)
{
@@ -685,7 +695,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
///
///
/// Location with the URI of the script file
- internal Location[] GetDefinition(TextDocumentPosition textDocumentPosition, ScriptFile scriptFile, ConnectionInfo connInfo)
+ internal DefinitionResult GetDefinition(TextDocumentPosition textDocumentPosition, ScriptFile scriptFile, ConnectionInfo connInfo)
{
// Parse sql
ScriptParseInfo scriptParseInfo = GetScriptParseInfo(textDocumentPosition.TextDocument.Uri);
@@ -723,29 +733,57 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
int parserLine = textDocumentPosition.Position.Line + 1;
int parserColumn = textDocumentPosition.Position.Character + 1;
IEnumerable declarationItems = Resolver.FindCompletions(
- scriptParseInfo.ParseResult,
- parserLine, parserColumn,
+ scriptParseInfo.ParseResult,
+ parserLine, parserColumn,
bindingContext.MetadataDisplayInfoProvider);
// Match token with the suggestions(declaration items) returned
- string schemaName = this.GetSchemaName(scriptParseInfo, textDocumentPosition.Position, scriptFile);
- PeekDefinition peekDefinition = new PeekDefinition(connInfo);
- return peekDefinition.GetScript(declarationItems, tokenText, schemaName);
-
+ string schemaName = this.GetSchemaName(scriptParseInfo, textDocumentPosition.Position, scriptFile);
+ PeekDefinition peekDefinition = new PeekDefinition(bindingContext.ServerConnection, connInfo);
+ return peekDefinition.GetScript(declarationItems, tokenText, schemaName);
+ },
+ timeoutOperation: (bindingContext) =>
+ {
+ // return error result
+ return new DefinitionResult
+ {
+ IsErrorResult = true,
+ Message = SR.PeekDefinitionTimedoutError,
+ Locations = null
+ };
});
// wait for the queue item
queueItem.ItemProcessed.WaitOne();
- return queueItem.GetResultAsT();
+ return queueItem.GetResultAsT();
+ }
+ catch (Exception ex)
+ {
+ // if any exceptions are raised return error result with message
+ Logger.Write(LogLevel.Error, "Exception in GetDefinition " + ex.ToString());
+ return new DefinitionResult
+ {
+ IsErrorResult = true,
+ Message = SR.PeekDefinitionError(ex.Message),
+ Locations = null
+ };
}
finally
{
Monitor.Exit(scriptParseInfo.BuildingMetadataLock);
}
}
-
- return null;
+ else
+ {
+ // User is not connected.
+ return new DefinitionResult
+ {
+ IsErrorResult = true,
+ Message = SR.PeekDefinitionNotConnectedError,
+ Locations = null
+ };
+ }
}
///
@@ -754,7 +792,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
///
///
///
- /// schema nama
+ /// schema name
private string GetSchemaName(ScriptParseInfo scriptParseInfo, Position position, ScriptFile scriptFile)
{
// Offset index by 1 for sql parser
@@ -1040,11 +1078,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
}
catch (Exception e)
{
- Logger.Write(
- LogLevel.Error,
- string.Format(
- "Exception while cancelling analysis task:\n\n{0}",
- e.ToString()));
+ Logger.Write(LogLevel.Error, string.Format("Exception while cancelling analysis task:\n\n{0}", e.ToString()));
TaskCompletionSource cancelTask = new TaskCompletionSource();
cancelTask.SetCanceled();
@@ -1168,7 +1202,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
}
}
- private bool RemoveScriptParseInfo(string uri)
+ internal bool RemoveScriptParseInfo(string uri)
{
lock (this.parseMapLock)
{
@@ -1187,7 +1221,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
/// Returns a flag indicating if the ScriptFile refers to the output window.
///
///
- private bool IsPreviewWindow(ScriptFile scriptFile)
+ internal bool IsPreviewWindow(ScriptFile scriptFile)
{
if (scriptFile != null && !string.IsNullOrWhiteSpace(scriptFile.ClientFilePath))
{
diff --git a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/PeekDefinition.cs b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/PeekDefinition.cs
index 07293ba6..d01d1d26 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/PeekDefinition.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/PeekDefinition.cs
@@ -7,12 +7,12 @@ using System.IO;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data.SqlClient;
-using System.Runtime.InteropServices;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.SqlParser.Intellisense;
using Microsoft.SqlTools.ServiceLayer.Utility;
using Microsoft.SqlTools.ServiceLayer.Connection;
+using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol;
using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts;
namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
@@ -23,7 +23,11 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
///
internal class PeekDefinition
{
+ private bool error;
+ private string errorMessage;
+ private ServerConnection serverConnection;
private ConnectionInfo connectionInfo;
+ private Database database;
private string tempPath;
internal delegate StringCollection ScriptGetter(string objectName, string schemaName);
@@ -35,38 +39,56 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
// Dictionary that holds the object name (as appears on the TSQL create statement)
private Dictionary sqlObjectTypes = new Dictionary();
+ ///
+ /// Initialize a Peek Definition helper object
+ ///
+ /// SMO Server connection
+ internal PeekDefinition(ServerConnection serverConnection, ConnectionInfo connInfo)
+ {
+ this.serverConnection = serverConnection;
+ this.connectionInfo = connInfo;
+
+ DirectoryInfo tempScriptDirectory = Directory.CreateDirectory(Path.GetTempPath() + "mssql_definition");
+ this.tempPath = tempScriptDirectory.FullName;
+ Initialize();
+ }
+
private Database Database
{
get
{
- if (this.connectionInfo.SqlConnection != null)
+ if (this.database == null)
{
- try
+ if (this.serverConnection != null && !string.IsNullOrEmpty(this.serverConnection.DatabaseName))
{
- // Get server object from connection
- string connectionString = ConnectionService.BuildConnectionString(this.connectionInfo.ConnectionDetails);
- SqlConnection sqlConn = new SqlConnection(connectionString);
- sqlConn.Open();
- ServerConnection serverConn = new ServerConnection(sqlConn);
- Server server = new Server(serverConn);
- return server.Databases[this.connectionInfo.SqlConnection.Database];
+ try
+ {
+ // Get server object from connection
+ SqlConnection sqlConn = new SqlConnection(this.serverConnection.ConnectionString);
+ sqlConn.Open();
+ ServerConnection peekConnection = new ServerConnection(sqlConn);
+ Server server = new Server(peekConnection);
+ this.database = new Database(server, peekConnection.DatabaseName);
+ }
+ catch (ConnectionFailureException cfe)
+ {
+ Logger.Write(LogLevel.Error, "Exception at PeekDefinition Database.get() : " + cfe.Message);
+ this.error = true;
+ this.errorMessage = (connectionInfo != null && connectionInfo.IsAzure)? SR.PeekDefinitionAzureError(cfe.Message) : SR.PeekDefinitionError(cfe.Message);
+ return null;
+ }
+ catch (Exception ex)
+ {
+ Logger.Write(LogLevel.Error, "Exception at PeekDefinition Database.get() : " + ex.Message);
+ this.error = true;
+ this.errorMessage = SR.PeekDefinitionError(ex.Message);
+ return null;
+ }
}
- catch(Exception ex)
- {
- Logger.Write(LogLevel.Error, "Exception at PeekDefinition Database.get() : " + ex.Message);
- return null;
- }
- }
- return null;
- }
- }
- internal PeekDefinition(ConnectionInfo connInfo)
- {
- this.connectionInfo = connInfo;
- DirectoryInfo tempScriptDirectory = Directory.CreateDirectory(Path.GetTempPath() + "mssql_definition");
- this.tempPath = tempScriptDirectory.FullName;
- Initialize();
+ }
+ return this.database;
+ }
}
///
@@ -103,7 +125,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
{
if (Path.DirectorySeparatorChar.Equals('/'))
{
- tempFileName = "file:" + tempFileName;
+ tempFileName = "file:" + tempFileName;
}
else
{
@@ -129,7 +151,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
string[] lines = script.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
for (int lineNumber = 0; lineNumber < lines.Length; lineNumber++)
{
- if (lines[lineNumber].IndexOf( createString, StringComparison.OrdinalIgnoreCase) >= 0)
+ if (lines[lineNumber].IndexOf(createString, StringComparison.OrdinalIgnoreCase) >= 0)
{
return lineNumber;
}
@@ -144,7 +166,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
///
///
/// Location object of the script file
- internal Location[] GetScript(IEnumerable declarationItems, string tokenText, string schemaName)
+ internal DefinitionResult GetScript(IEnumerable declarationItems, string tokenText, string schemaName)
{
foreach (Declaration declarationItem in declarationItems)
{
@@ -156,29 +178,38 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
if (declarationItem.Title.Equals(tokenText))
{
// Script object using SMO based on type
- DeclarationType type = declarationItem.Type;
+ DeclarationType type = declarationItem.Type;
if (sqlScriptGetters.ContainsKey(type) && sqlObjectTypes.ContainsKey(type))
{
// On *nix and mac systems, the defaultSchema property throws an Exception when accessed.
// This workaround ensures that a schema name is present by attempting
// to get the schema name from the declaration item
// If all fails, the default schema name is assumed to be "dbo"
- if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && string.IsNullOrEmpty(schemaName))
+ if ((connectionInfo != null && connectionInfo.ConnectionDetails.AuthenticationType.Equals(Constants.SqlLoginAuthenticationType)) && string.IsNullOrEmpty(schemaName))
{
string fullObjectName = declarationItem.DatabaseQualifiedName;
schemaName = this.GetSchemaFromDatabaseQualifiedName(fullObjectName, tokenText);
}
- return GetSqlObjectDefinition(
+ Location[] locations = GetSqlObjectDefinition(
sqlScriptGetters[type],
tokenText,
schemaName,
sqlObjectTypes[type]
);
+ DefinitionResult result = new DefinitionResult
+ {
+ IsErrorResult = this.error,
+ Message = this.errorMessage,
+ Locations = locations
+ };
+ return result;
}
- return null;
+ // sql object type is currently not supported
+ return GetDefinitionErrorResult(SR.PeekDefinitionTypeNotSupportedError);
}
}
- return null;
+ // no definition found
+ return GetDefinitionErrorResult(SR.PeekDefinitionNoResultsError);
}
///
@@ -192,9 +223,9 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
string[] tokens = fullObjectName.Split('.');
for (int i = tokens.Length - 1; i > 0; i--)
{
- if(tokens[i].Equals(objectName))
+ if (tokens[i].Equals(objectName))
{
- return tokens[i-1];
+ return tokens[i - 1];
}
}
return "dbo";
@@ -208,8 +239,21 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
/// String collection of scripts
internal StringCollection GetTableScripts(string tableName, string schemaName)
{
- return (schemaName != null) ? Database?.Tables[tableName, schemaName]?.Script()
- : Database?.Tables[tableName]?.Script();
+ try
+ {
+ Table table = string.IsNullOrEmpty(schemaName)
+ ? new Table(this.Database, tableName)
+ : new Table(this.Database, tableName, schemaName);
+
+ table.Refresh();
+
+ return table.Script();
+ }
+ catch (Exception ex)
+ {
+ Logger.Write(LogLevel.Error, "Exception at PeekDefinition GetTableScripts : " + ex.Message);
+ return null;
+ }
}
///
@@ -220,8 +264,21 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
/// String collection of scripts
internal StringCollection GetViewScripts(string viewName, string schemaName)
{
- return (schemaName != null) ? Database?.Views[viewName, schemaName]?.Script()
- : Database?.Views[viewName]?.Script();
+ try
+ {
+ View view = string.IsNullOrEmpty(schemaName)
+ ? new View(this.Database, viewName)
+ : new View(this.Database, viewName, schemaName);
+
+ view.Refresh();
+
+ return view.Script();
+ }
+ catch (Exception ex)
+ {
+ Logger.Write(LogLevel.Error, "Exception at PeekDefinition GetViewScripts : " + ex.Message);
+ return null;
+ }
}
///
@@ -230,10 +287,23 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
/// Stored Procedure name
/// Schema Name
/// String collection of scripts
- internal StringCollection GetStoredProcedureScripts(string viewName, string schemaName)
+ internal StringCollection GetStoredProcedureScripts(string sprocName, string schemaName)
{
- return (schemaName != null) ? Database?.StoredProcedures[viewName, schemaName]?.Script()
- : Database?.StoredProcedures[viewName]?.Script();
+ try
+ {
+ StoredProcedure sproc = string.IsNullOrEmpty(schemaName)
+ ? new StoredProcedure(this.Database, sprocName)
+ : new StoredProcedure(this.Database, sprocName, schemaName);
+
+ sproc.Refresh();
+
+ return sproc.Script();
+ }
+ catch (Exception ex)
+ {
+ Logger.Write(LogLevel.Error, "Exception at PeekDefinition GetStoredProcedureScripts : " + ex.Message);
+ return null;
+ }
}
///
@@ -250,30 +320,49 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
string schemaName,
string objectType)
{
- StringCollection scripts = sqlScriptGetter(objectName, schemaName);
- string tempFileName = (schemaName != null) ? Path.Combine(this.tempPath, string.Format("{0}.{1}.sql", schemaName, objectName))
- : Path.Combine(this.tempPath, string.Format("{0}.sql", objectName));
+ StringCollection scripts = sqlScriptGetter(objectName, schemaName);
+ string tempFileName = (schemaName != null) ? Path.Combine(this.tempPath, string.Format("{0}.{1}.sql", schemaName, objectName))
+ : Path.Combine(this.tempPath, string.Format("{0}.sql", objectName));
- if (scripts != null)
+ if (scripts != null)
+ {
+ int lineNumber = 0;
+ using (StreamWriter scriptFile = new StreamWriter(File.Open(tempFileName, FileMode.Create, FileAccess.ReadWrite)))
{
- int lineNumber = 0;
- using (StreamWriter scriptFile = new StreamWriter(File.Open(tempFileName, FileMode.Create, FileAccess.ReadWrite)))
- {
- foreach (string script in scripts)
+ foreach (string script in scripts)
+ {
+ string createSyntax = string.Format("CREATE {0}", objectType);
+ if (script.IndexOf(createSyntax, StringComparison.OrdinalIgnoreCase) >= 0)
{
- string createSyntax = string.Format("CREATE {0}", objectType);
- if (script.IndexOf(createSyntax, StringComparison.OrdinalIgnoreCase) >= 0)
- {
- scriptFile.WriteLine(script);
- lineNumber = GetStartOfCreate(script, createSyntax);
- }
+ scriptFile.WriteLine(script);
+ lineNumber = GetStartOfCreate(script, createSyntax);
}
}
- return GetLocationFromFile(tempFileName, lineNumber);
}
+ return GetLocationFromFile(tempFileName, lineNumber);
+ }
+ else
+ {
+ this.error = true;
+ this.errorMessage = SR.PeekDefinitionNoResultsError;
+ return null;
+ }
+ }
- return null;
+ ///
+ /// Helper method to create definition error result object
+ ///
+ /// Error message
+ /// DefinitionResult
+ internal DefinitionResult GetDefinitionErrorResult(string errorMessage)
+ {
+ return new DefinitionResult
+ {
+ IsErrorResult = true,
+ Message = errorMessage,
+ Locations = null
+ };
}
}
}
\ No newline at end of file
diff --git a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/PeekDefinitionResult.cs b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/PeekDefinitionResult.cs
new file mode 100644
index 00000000..2234d6e8
--- /dev/null
+++ b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/PeekDefinitionResult.cs
@@ -0,0 +1,28 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts;
+namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
+{
+ ///
+ /// /// Result object for PeekDefinition
+ ///
+ public class DefinitionResult
+ {
+ ///
+ /// True, if definition error occured
+ ///
+ public bool IsErrorResult;
+
+ ///
+ /// Error message, if any
+ ///
+ public string Message { get; set; }
+
+ ///
+ /// Location object representing the definition script file
+ ///
+ public Location[] Locations;
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/QueueItem.cs b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/QueueItem.cs
index a320f842..2b45de8b 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/QueueItem.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/QueueItem.cs
@@ -39,7 +39,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
///
/// Gets or sets an event to signal when this queue item has been processed
///
- public ManualResetEvent ItemProcessed { get; set; }
+ public virtual ManualResetEvent ItemProcessed { get; set; }
///
/// Gets or sets the result of the queued task
diff --git a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/ScriptDocumentInfo.cs b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/ScriptDocumentInfo.cs
index fd15ad82..2735abea 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/ScriptDocumentInfo.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/ScriptDocumentInfo.cs
@@ -92,7 +92,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices.Completion
///
/// The token text in the file content used for completion list
///
- public string TokenText
+ public virtual string TokenText
{
get
{
diff --git a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/Batch.cs b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/Batch.cs
index 7336cec2..c7c379c9 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/Batch.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/Batch.cs
@@ -48,7 +48,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
///
/// Internal representation of the messages so we can modify internally
///
- private readonly List resultMessages;
+ internal readonly List resultMessages;
///
/// Internal representation of the result sets so we can modify internally
@@ -379,7 +379,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
///
/// Sender of the event
/// Arguments for the event
- private void StatementCompletedHandler(object sender, StatementCompletedEventArgs args)
+ internal void StatementCompletedHandler(object sender, StatementCompletedEventArgs args)
{
// Add a message for the number of rows the query returned
string message;
@@ -414,7 +414,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
/// cannot be converted to SqlException, the message is written to the messages list.
///
/// The exception to unwrap
- private void UnwrapDbException(DbException dbe)
+ internal void UnwrapDbException(DbException dbe)
{
SqlException se = dbe as SqlException;
if (se != null)
diff --git a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/Contracts/DbColumnWrapper.cs b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/Contracts/DbColumnWrapper.cs
index 09beae29..3ab13705 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/Contracts/DbColumnWrapper.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/Contracts/DbColumnWrapper.cs
@@ -19,7 +19,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts
///
/// All types supported by the server, stored as a hash set to provide O(1) lookup
///
- private static readonly HashSet AllServerDataTypes = new HashSet
+ internal static readonly HashSet AllServerDataTypes = new HashSet
{
"bigint",
"binary",
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Utility/LongList.cs b/src/Microsoft.SqlTools.ServiceLayer/Utility/LongList.cs
index afacc98f..306019df 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Utility/LongList.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/Utility/LongList.cs
@@ -20,15 +20,16 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility
///
/// Type of the values to store
public class LongList : IEnumerable
- {
+ {
#region Member Variables
-
+
+ private int expandListSize = int.MaxValue;
private List> expandedList;
private readonly List shortList;
#endregion
- ///
+ ///
/// Creates a new long list
///
public LongList()
@@ -46,7 +47,22 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility
public T this[long index]
{
- get { return GetItem(index); }
+ get
+ {
+ return GetItem(index);
+ }
+ }
+
+ public int ExpandListSize
+ {
+ get
+ {
+ return this.expandListSize;
+ }
+ internal set
+ {
+ this.expandListSize = value;
+ }
}
#endregion
@@ -60,7 +76,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility
/// Index of the item that was just added
public long Add(T val)
{
- if (Count <= int.MaxValue)
+ if (Count <= this.ExpandListSize)
{
shortList.Add(val);
}
@@ -73,7 +89,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility
expandedList = new List> {shortList};
}
- int arrayIndex = (int)(Count/int.MaxValue); // 0 based
+ int arrayIndex = (int)(Count / this.ExpandListSize); // 0 based
List arr;
if (expandedList.Count <= arrayIndex) // need to make a new array
@@ -99,19 +115,19 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility
{
T val = default(T);
- if (Count <= int.MaxValue)
+ if (Count <= this.ExpandListSize)
{
int i32Index = Convert.ToInt32(index);
val = shortList[i32Index];
}
else
{
- int iArray32Index = (int) (Count/int.MaxValue);
+ int iArray32Index = (int) (Count / this.ExpandListSize);
if (expandedList.Count > iArray32Index)
{
List arr = expandedList[iArray32Index];
- int i32Index = (int) (Count%int.MaxValue);
+ int i32Index = (int) (Count % this.ExpandListSize);
if (arr.Count > i32Index)
{
val = arr[i32Index];
@@ -128,7 +144,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility
/// The index to remove from the list
public void RemoveAt(long index)
{
- if (Count <= int.MaxValue)
+ if (Count <= this.ExpandListSize)
{
int iArray32MemberIndex = Convert.ToInt32(index); // 0 based
shortList.RemoveAt(iArray32MemberIndex);
@@ -136,21 +152,21 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility
else // handle the case of multiple arrays
{
// find out which array it is in
- int arrayIndex = (int) (index/int.MaxValue);
+ int arrayIndex = (int) (index / this.ExpandListSize);
List arr = expandedList[arrayIndex];
// find out index into this array
- int iArray32MemberIndex = (int) (index%int.MaxValue);
+ int iArray32MemberIndex = (int) (index % this.ExpandListSize);
arr.RemoveAt(iArray32MemberIndex);
// now shift members of the array back one
- int iArray32TotalIndex = (int) (Count/Int32.MaxValue);
+ int iArray32TotalIndex = (int) (Count / this.ExpandListSize);
for (int i = arrayIndex + 1; i < iArray32TotalIndex; i++)
{
List arr1 = expandedList[i - 1];
List arr2 = expandedList[i];
- arr1.Add(arr2[int.MaxValue - 1]);
+ arr1.Add(arr2[this.ExpandListSize - 1]);
arr2.RemoveAt(0);
}
}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Workspace/Workspace.cs b/src/Microsoft.SqlTools.ServiceLayer/Workspace/Workspace.cs
index 1c798a5d..e3954d39 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Workspace/Workspace.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/Workspace/Workspace.cs
@@ -194,7 +194,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Workspace
this.workspaceFiles.Remove(scriptFile.Id);
}
- private string GetBaseFilePath(string filePath)
+ internal string GetBaseFilePath(string filePath)
{
if (IsPathInMemory(filePath))
{
@@ -215,7 +215,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Workspace
return Path.GetDirectoryName(filePath);
}
- private string ResolveRelativeScriptPath(string baseFilePath, string relativePath)
+ internal string ResolveRelativeScriptPath(string baseFilePath, string relativePath)
{
if (Path.IsPathRooted(relativePath))
{
diff --git a/src/Microsoft.SqlTools.ServiceLayer/project.json b/src/Microsoft.SqlTools.ServiceLayer/project.json
index c8e55c35..9cad9751 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/project.json
+++ b/src/Microsoft.SqlTools.ServiceLayer/project.json
@@ -19,7 +19,7 @@
"Newtonsoft.Json": "9.0.1",
"System.Data.Common": "4.1.0",
"System.Data.SqlClient": "4.4.0-sqltools-24613-04",
- "Microsoft.SqlServer.Smo": "140.1.11",
+ "Microsoft.SqlServer.Smo": "140.1.12",
"System.Security.SecureString": "4.0.0",
"System.Collections.Specialized": "4.0.1",
"System.ComponentModel.TypeConverter": "4.1.0",
diff --git a/src/Microsoft.SqlTools.ServiceLayer/sr.cs b/src/Microsoft.SqlTools.ServiceLayer/sr.cs
index c8abeed3..9c162533 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/sr.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/sr.cs
@@ -13,7 +13,7 @@ namespace Microsoft.SqlTools.ServiceLayer
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class SR
{
- protected SR()
+ internal SR()
{ }
public static CultureInfo Culture
@@ -341,6 +341,38 @@ namespace Microsoft.SqlTools.ServiceLayer
}
}
+ public static string PeekDefinitionNoResultsError
+ {
+ get
+ {
+ return Keys.GetString(Keys.PeekDefinitionNoResultsError);
+ }
+ }
+
+ public static string PeekDefinitionNotConnectedError
+ {
+ get
+ {
+ return Keys.GetString(Keys.PeekDefinitionNotConnectedError);
+ }
+ }
+
+ public static string PeekDefinitionTimedoutError
+ {
+ get
+ {
+ return Keys.GetString(Keys.PeekDefinitionTimedoutError);
+ }
+ }
+
+ public static string PeekDefinitionTypeNotSupportedError
+ {
+ get
+ {
+ return Keys.GetString(Keys.PeekDefinitionTypeNotSupportedError);
+ }
+ }
+
public static string WorkspaceServicePositionLineOutOfRange
{
get
@@ -384,6 +416,16 @@ namespace Microsoft.SqlTools.ServiceLayer
return Keys.GetString(Keys.QueryServiceQueryFailed, message);
}
+ public static string PeekDefinitionAzureError(string errorMessage)
+ {
+ return Keys.GetString(Keys.PeekDefinitionAzureError, errorMessage);
+ }
+
+ public static string PeekDefinitionError(string errorMessage)
+ {
+ return Keys.GetString(Keys.PeekDefinitionError, errorMessage);
+ }
+
public static string WorkspaceServicePositionColumnOutOfRange(int line)
{
return Keys.GetString(Keys.WorkspaceServicePositionColumnOutOfRange, line);
@@ -397,7 +439,7 @@ namespace Microsoft.SqlTools.ServiceLayer
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Keys
{
- static ResourceManager resourceManager = new ResourceManager(typeof(SR));
+ static ResourceManager resourceManager = new ResourceManager("Microsoft.SqlTools.ServiceLayer.SR", typeof(SR).GetTypeInfo().Assembly);
static CultureInfo _culture = null;
@@ -540,6 +582,24 @@ namespace Microsoft.SqlTools.ServiceLayer
public const string QueryServiceResultSetNoColumnSchema = "QueryServiceResultSetNoColumnSchema";
+ public const string PeekDefinitionAzureError = "PeekDefinitionAzureError";
+
+
+ public const string PeekDefinitionError = "PeekDefinitionError";
+
+
+ public const string PeekDefinitionNoResultsError = "PeekDefinitionNoResultsError";
+
+
+ public const string PeekDefinitionNotConnectedError = "PeekDefinitionNotConnectedError";
+
+
+ public const string PeekDefinitionTimedoutError = "PeekDefinitionTimedoutError";
+
+
+ public const string PeekDefinitionTypeNotSupportedError = "PeekDefinitionTypeNotSupportedError";
+
+
public const string WorkspaceServicePositionLineOutOfRange = "WorkspaceServicePositionLineOutOfRange";
@@ -549,7 +609,7 @@ namespace Microsoft.SqlTools.ServiceLayer
public const string WorkspaceServiceBufferPositionOutOfOrder = "WorkspaceServiceBufferPositionOutOfOrder";
- private Keys()
+ internal Keys()
{ }
public static CultureInfo Culture
diff --git a/src/Microsoft.SqlTools.ServiceLayer/sr.resx b/src/Microsoft.SqlTools.ServiceLayer/sr.resx
index 5494a742..bf5ed353 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/sr.resx
+++ b/src/Microsoft.SqlTools.ServiceLayer/sr.resx
@@ -308,6 +308,32 @@
Could not retrieve column schema for result set
+
+ This feature is currently not supported on Azure SQL DB and Data Warehouse: {0}
+ .
+ Parameters: 0 - errorMessage (string)
+
+
+ An unexpected error occurred during Peek Definition execution: {0}
+ .
+ Parameters: 0 - errorMessage (string)
+
+
+ No results were found.
+
+
+
+ Please connect to a server.
+
+
+
+ Operation timed out.
+
+
+
+ This object type is currently not supported by this feature.
+
+
Position is outside of file line range
diff --git a/src/Microsoft.SqlTools.ServiceLayer/sr.strings b/src/Microsoft.SqlTools.ServiceLayer/sr.strings
index 67534aed..fee7f907 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/sr.strings
+++ b/src/Microsoft.SqlTools.ServiceLayer/sr.strings
@@ -139,6 +139,21 @@ QueryServiceResultSetRowCountOutOfRange = Row count must be a positive integer
QueryServiceResultSetNoColumnSchema = Could not retrieve column schema for result set
+############################################################################
+# Language Service
+
+PeekDefinitionAzureError(string errorMessage) = This feature is currently not supported on Azure SQL DB and Data Warehouse: {0}
+
+PeekDefinitionError(string errorMessage) = An unexpected error occurred during Peek Definition execution: {0}
+
+PeekDefinitionNoResultsError = No results were found.
+
+PeekDefinitionNotConnectedError = Please connect to a server.
+
+PeekDefinitionTimedoutError = Operation timed out.
+
+PeekDefinitionTypeNotSupportedError = This object type is currently not supported by this feature.
+
############################################################################
# Workspace Service
diff --git a/test/CodeCoverage/package.json b/test/CodeCoverage/package.json
index 0d4efd10..003b9c85 100644
--- a/test/CodeCoverage/package.json
+++ b/test/CodeCoverage/package.json
@@ -4,11 +4,13 @@
"description": "SQL Tools Service Layer",
"main": "gulpfile.js",
"dependencies": {
- "gulp": "github:gulpjs/gulp#4.0",
"del": "^2.2.1",
+ "gulp": "github:gulpjs/gulp#4.0",
"gulp-hub": "frankwallis/gulp-hub#registry-init",
"gulp-install": "^0.6.0",
- "request": "^2.73.0"
+ "gulp-util": "^3.0.7",
+ "request": "^2.73.0",
+ "through2": "^2.0.3"
},
"devDependencies": {},
"author": "Microsoft",
diff --git a/test/CodeCoverage/packages.config b/test/CodeCoverage/packages.config
index 2b659d64..5d0c66b9 100644
--- a/test/CodeCoverage/packages.config
+++ b/test/CodeCoverage/packages.config
@@ -3,4 +3,5 @@
+
diff --git a/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/IntellisenseTests.cs b/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/IntellisenseTests.cs
index cffe764c..3f84df16 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/IntellisenseTests.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.PerfTests/Tests/IntellisenseTests.cs
@@ -122,7 +122,7 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests
TestServerType serverType = TestServerType.OnPrem;
using (TestHelper testHelper = new TestHelper())
{
- await VerifyBindingLoadScenario(testHelper, TestServerType.OnPrem, Scripts.TestDbSimpleSelectQuery, false);
+ await VerifyBindingLoadScenario(testHelper, serverType, Scripts.TestDbSimpleSelectQuery, false);
}
}
@@ -170,10 +170,10 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests
[CreateTestDb(TestServerType.Azure)]
public async Task BindingCacheColdOnPremComplexQuery()
{
- TestServerType serverType = TestServerType.Azure;
+ TestServerType serverType = TestServerType.OnPrem;
using (TestHelper testHelper = new TestHelper())
{
- await VerifyBindingLoadScenario(testHelper, TestServerType.OnPrem, Scripts.TestDbComplexSelectQueries, false);
+ await VerifyBindingLoadScenario(testHelper, serverType, Scripts.TestDbComplexSelectQueries, false);
}
}
@@ -257,7 +257,10 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests
{
string query = Scripts.SelectQuery;
CompletionItem[] completions = await testHelper.RequestCompletion(ownerUri, query, 0, query.Length + 1);
- return completions != null && completions.Any(x => x.Label == databaseName);
+ return completions != null &&
+ (completions.Any(x => string.Compare(x.Label, databaseName, StringComparison.OrdinalIgnoreCase) == 0 ||
+ string.Compare(x.Label, $"[{databaseName}]", StringComparison.OrdinalIgnoreCase) == 0 ||
+ string.Compare(x.Label, $"\"{databaseName}\"", StringComparison.OrdinalIgnoreCase) == 0));
}
else
{
diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/Connection/ConnectionServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/Connection/ConnectionServiceTests.cs
index 3bc7b14c..9ead2576 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.Test/Connection/ConnectionServiceTests.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.Test/Connection/ConnectionServiceTests.cs
@@ -536,6 +536,17 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
Assert.True(connectionString.Contains(connectionStringMarker));
}
+ ///
+ /// Build connection string with an invalid auth type
+ ///
+ [Fact]
+ public void BuildConnectionStringWithInvalidAuthType()
+ {
+ ConnectionDetails details = TestObjects.GetTestConnectionDetails();
+ details.AuthenticationType = "NotAValidAuthType";
+ Assert.Throws(() => ConnectionService.BuildConnectionString(details));
+ }
+
///
/// Verify that a connection changed event is fired when the database context changes.
///
@@ -892,6 +903,29 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
});
}
+ //
+ /// Test that cancel connection with a null connection parameter
+ ///
+ [Fact]
+ public void TestCancelConnectionNullParam()
+ {
+ var service = TestObjects.GetTestConnectionService();
+ Assert.False(service.CancelConnect(null));
+ }
+
+ //
+ /// Test that cancel connection with a null connection parameter
+ ///
+ [Fact]
+ public void TestListDatabasesInvalidParams()
+ {
+ var service = TestObjects.GetTestConnectionService();
+ var listParams = new ListDatabasesParams();
+ Assert.Throws(() => service.ListDatabases(listParams));
+ listParams.OwnerUri = "file://notmyfile.sql";
+ Assert.Throws(() => service.ListDatabases(listParams));
+ }
+
///
/// Test that the connection complete notification type can be created.
///
diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/Connection/ReliableConnectionTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/Connection/ReliableConnectionTests.cs
index 95194a55..65ff5eaf 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.Test/Connection/ReliableConnectionTests.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.Test/Connection/ReliableConnectionTests.cs
@@ -10,8 +10,11 @@ using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
+using System.Threading;
using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection;
+using Microsoft.SqlTools.ServiceLayer.QueryExecution;
+using Microsoft.SqlTools.ServiceLayer.Test.QueryExecution;
using Microsoft.SqlTools.ServiceLayer.Test.Utility;
using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts;
using Microsoft.SqlTools.Test.Utility;
@@ -70,6 +73,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
{
return ShouldRetryImpl(retryStateObj);
}
+
+ public void DoOnIgnoreErrorOccurred(RetryState retryState)
+ {
+ OnIgnoreErrorOccurred(retryState);
+ }
}
internal class TestProgressiveRetryPolicy : ProgressiveRetryPolicy
@@ -126,10 +134,46 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
strategy: new NetworkConnectivityErrorDetectionStrategy(),
maxRetryCount: 3,
intervalBetweenRetries: TimeSpan.FromMilliseconds(100));
- bool shouldRety = policy.InvokeShouldRetryImpl(new RetryStateEx());
+ var retryState = new RetryStateEx();
+ bool shouldRety = policy.InvokeShouldRetryImpl(retryState);
+ policy.DoOnIgnoreErrorOccurred(retryState);
Assert.True(shouldRety);
}
+ [Fact]
+ public void FixedDelayPolicyExecuteActionTest()
+ {
+ TestFixedDelayPolicy policy = new TestFixedDelayPolicy(
+ strategy: new NetworkConnectivityErrorDetectionStrategy(),
+ maxRetryCount: 3,
+ intervalBetweenRetries: TimeSpan.FromMilliseconds(20));
+
+ // execute an action that throws a retry limit exception
+ CancellationToken token = new CancellationToken();
+ Assert.Equal(policy.ExecuteAction((s) => { throw new RetryLimitExceededException(); }, token), default(int));
+
+ // execute an action that throws a retry limit exeception with an inner exception
+ Assert.Throws(() =>
+ {
+ policy.ExecuteAction((s) =>
+ {
+ var e = new RetryLimitExceededException("retry", new Exception());
+ throw e;
+ });
+ });
+ }
+
+ [Fact]
+ public void IsRetryableExceptionTest()
+ {
+ TestFixedDelayPolicy policy = new TestFixedDelayPolicy(
+ strategy: new NetworkConnectivityErrorDetectionStrategy(),
+ maxRetryCount: 3,
+ intervalBetweenRetries: TimeSpan.FromMilliseconds(20));
+
+ Assert.False(policy.IsRetryableException(new Exception()));
+ }
+
[Fact]
public void ProgressiveRetryPolicyTest()
{
@@ -140,6 +184,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
increment: TimeSpan.FromMilliseconds(100));
bool shouldRety = policy.InvokeShouldRetryImpl(new RetryStateEx());
Assert.True(shouldRety);
+ Assert.NotNull(policy.CommandTimeoutInSeconds);
+ policy.ShouldIgnoreOnFirstTry = false;
+ Assert.False(policy.ShouldIgnoreOnFirstTry);
}
[Fact]
@@ -157,6 +204,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
Assert.True(shouldRety);
}
+
+ [Fact]
+ public void GetErrorNumberWithNullExceptionTest()
+ {
+ Assert.Null(RetryPolicy.GetErrorNumber(null));
+ }
+
///
/// Environment variable that stores the name of the test server hosting the SQL Server instance.
///
@@ -260,6 +314,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
Assert.True(serverInfo.ServerEdition == serverInfo2.ServerEdition);
Assert.True(serverInfo.IsCloud == serverInfo2.IsCloud);
Assert.True(serverInfo.AzureVersion == serverInfo2.AzureVersion);
+ Assert.True(serverInfo.IsAzureV1 == serverInfo2.IsAzureV1);
}
});
}
@@ -290,6 +345,15 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
Assert.False(isReadOnly);
}
+ ///
+ /// /// Tests ReliableConnectionHelper.IsDatabaseReadonly() with null builder parameter
+ ///
+ [Fact]
+ public void TestIsDatabaseReadonlyWithNullBuilder()
+ {
+ Assert.Throws(() => ReliableConnectionHelper.IsDatabaseReadonly(null));
+ }
+
///
/// Verify ANSI_NULL and QUOTED_IDENTIFIER settings can be set and retrieved for a session
///
@@ -475,6 +539,18 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
});
}
+ ///
+ /// Test that TryGetServerVersion() fails with invalid connection string
+ ///
+ [Fact]
+ public void TestTryGetServerVersionInvalidConnectionString()
+ {
+ TestUtils.RunIfWindows(() =>
+ {
+ ReliableConnectionHelper.ServerInfo info = null;
+ Assert.False(ReliableConnectionHelper.TryGetServerVersion("this is not a valid connstr", out info));
+ });
+ }
///
/// Validate ambient static settings
@@ -561,6 +637,28 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
data.TraceSettings();
}
+ [Fact]
+ public void RaiseAmbientRetryMessageTest()
+ {
+ bool handlerCalled = false;
+ var data = new AmbientSettings.AmbientData();
+ data.ConnectionRetryMessageHandler = (a) => handlerCalled = true;
+ AmbientSettings._defaultSettings = data;
+ RetryPolicyUtils.RaiseAmbientRetryMessage(new RetryStateEx() { LastError = new Exception() }, 100);
+ Assert.True(handlerCalled);
+ }
+
+ [Fact]
+ public void RaiseAmbientIgnoreMessageTest()
+ {
+ bool handlerCalled = false;
+ var data = new AmbientSettings.AmbientData();
+ data.ConnectionRetryMessageHandler = (a) => handlerCalled = true;
+ AmbientSettings._defaultSettings = data;
+ RetryPolicyUtils.RaiseAmbientIgnoreMessage(new RetryStateEx() { LastError = new Exception() }, 100);
+ Assert.True(handlerCalled);
+ }
+
[Fact]
public void RetryPolicyFactoryTest()
{
@@ -681,6 +779,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
var detectionStrategy2 = new TestSqlAzureTemporaryAndIgnorableErrorDetectionStrategy();
Assert.NotNull(detectionStrategy2.InvokeCanRetrySqlException(sqlException));
Assert.NotNull(detectionStrategy2.InvokeShouldIgnoreSqlException(sqlException));
+
+ Batch batch = new Batch(Common.StandardQuery, Common.SubsectionDocument, Common.Ordinal, Common.GetFileStreamFactory(null));
+ batch.UnwrapDbException(sqlException);
}
var unknownCodeReason = RetryPolicy.ThrottlingReason.FromReasonCode(-1);
@@ -736,6 +837,119 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
Assert.Equal(exception, args.Exception);
Assert.Equal(timespan, args.Delay);
}
+
+ [Fact]
+ public void CheckStaticVariables()
+ {
+ Assert.NotNull(ReliableConnectionHelper.BuilderWithDefaultApplicationName);
+ }
+
+ [Fact]
+ public void SetLockAndCommandTimeoutThrowsOnNull()
+ {
+ Assert.Throws(typeof(ArgumentNullException), () => ReliableConnectionHelper.SetLockAndCommandTimeout(null));
+ }
+
+ [Fact]
+ public void StandardExceptionHandlerTests()
+ {
+ Assert.True(ReliableConnectionHelper.StandardExceptionHandler(new InvalidCastException()));
+ Assert.False(ReliableConnectionHelper.StandardExceptionHandler(new Exception()));
+ }
+
+ [Fact]
+ public void GetConnectionStringBuilderNullConnectionString()
+ {
+ SqlConnectionStringBuilder builder;
+ Assert.False(ReliableConnectionHelper.TryGetConnectionStringBuilder(null, out builder));
+ }
+
+ [Fact]
+ public void GetConnectionStringBuilderExceptionTests()
+ {
+ SqlConnectionStringBuilder builder;
+
+ // throws ArgumentException
+ Assert.False(ReliableConnectionHelper.TryGetConnectionStringBuilder("IntegratedGoldFish=True", out builder));
+
+ // throws FormatException
+ Assert.False(ReliableConnectionHelper.TryGetConnectionStringBuilder("rabbits**frogs**lizards", out builder));
+ }
+
+ [Fact]
+ public void GetCompleteServerNameTests()
+ {
+ Assert.Null(ReliableConnectionHelper.GetCompleteServerName(null));
+
+ Assert.NotNull(ReliableConnectionHelper.GetCompleteServerName("localhost"));
+
+ Assert.NotNull(ReliableConnectionHelper.GetCompleteServerName("mytestservername"));
+ }
+
+ [Fact]
+ public void ReliableSqlCommandConstructorTests()
+ {
+ // verify default constructor doesn't throw
+ Assert.NotNull(new ReliableSqlConnection.ReliableSqlCommand());
+
+ // verify constructor with null connection doesn't throw
+ Assert.NotNull(new ReliableSqlConnection.ReliableSqlCommand(null));
+ }
+
+ [Fact]
+ public void ReliableSqlCommandProperties()
+ {
+ var command = new ReliableSqlConnection.ReliableSqlCommand();
+ command.CommandText = "SELECT 1";
+ Assert.Equal(command.CommandText, "SELECT 1");
+ Assert.NotNull(command.CommandTimeout);
+ Assert.NotNull(command.CommandType);
+ command.DesignTimeVisible = true;
+ Assert.True(command.DesignTimeVisible);
+ command.UpdatedRowSource = UpdateRowSource.None;
+ Assert.Equal(command.UpdatedRowSource, UpdateRowSource.None);
+ Assert.NotNull(command.GetUnderlyingCommand());
+ Assert.Throws(() => command.ValidateConnectionIsSet());
+ command.Prepare();
+ Assert.NotNull(command.CreateParameter());
+ command.Cancel();
+ }
+
+ [Fact]
+ public void ReliableConnectionResourcesTests()
+ {
+ Assert.NotNull(Resources.ConnectionPassedToIsCloudShouldBeOpen);
+ Assert.NotNull(Resources.ExceptionCannotBeRetried);
+ Assert.NotNull(Resources.FailedToCacheIsCloud);
+ Assert.NotNull(Resources.FailedToParseConnectionString);
+ Assert.NotNull(Resources.InvalidCommandType);
+ Assert.NotNull(Resources.InvalidConnectionType);
+ Assert.NotNull(Resources.OnlyReliableConnectionSupported);
+ Assert.NotNull(Resources.UnableToAssignValue);
+ Assert.NotNull(Resources.UnableToRetrieveAzureSessionId);
+ }
+
+ [Fact]
+ public void CalcExponentialRetryDelayWithSchemaDefaultsTest()
+ {
+ Assert.NotNull(RetryPolicyUtils.CalcExponentialRetryDelayWithSchemaDefaults(1));
+ }
+
+ [Fact]
+ public void IsSupportedCommandNullCommandTest()
+ {
+ Assert.False(DbCommandWrapper.IsSupportedCommand(null));
+ }
+
+ [Fact]
+ public void StatementCompletedTests()
+ {
+ bool handlerCalled = false;
+ StatementCompletedEventHandler handler = (s, e) => handlerCalled = true;
+ var command = new DbCommandWrapper(new SqlCommand());
+ command.StatementCompleted += handler;
+ command.StatementCompleted -= handler;
+ }
}
}
diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/AutocompleteTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/AutocompleteTests.cs
index a9e346cd..b034609a 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/AutocompleteTests.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/AutocompleteTests.cs
@@ -39,8 +39,12 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
private Mock> requestContext;
+ private Mock scriptFile;
+
private Mock binder;
+ private ScriptParseInfo scriptParseInfo;
+
private TextDocumentPosition textDocument;
private void InitializeTestObjects()
@@ -60,14 +64,14 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
WorkspaceService.Instance.CurrentSettings = new SqlToolsSettings();
// set up file for returning the query
- var fileMock = new Mock();
- fileMock.SetupGet(file => file.Contents).Returns(Common.StandardQuery);
- fileMock.SetupGet(file => file.ClientFilePath).Returns(this.testScriptUri);
+ scriptFile = new Mock();
+ scriptFile.SetupGet(file => file.Contents).Returns(Common.StandardQuery);
+ scriptFile.SetupGet(file => file.ClientFilePath).Returns(this.testScriptUri);
// set up workspace mock
workspaceService = new Mock>();
workspaceService.Setup(service => service.Workspace.GetFile(It.IsAny()))
- .Returns(fileMock.Object);
+ .Returns(scriptFile.Object);
// setup binding queue mock
bindingQueue = new Mock();
@@ -93,16 +97,113 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
It.IsAny(),
It.IsAny()));
- var testScriptParseInfo = new ScriptParseInfo();
- LanguageService.Instance.AddOrUpdateScriptParseInfo(this.testScriptUri, testScriptParseInfo);
- testScriptParseInfo.IsConnected = true;
- testScriptParseInfo.ConnectionKey = LanguageService.Instance.BindingQueue.AddConnectionContext(connectionInfo);
+ scriptParseInfo = new ScriptParseInfo();
+ LanguageService.Instance.AddOrUpdateScriptParseInfo(this.testScriptUri, scriptParseInfo);
+ scriptParseInfo.IsConnected = true;
+ scriptParseInfo.ConnectionKey = LanguageService.Instance.BindingQueue.AddConnectionContext(connectionInfo);
// setup the binding context object
ConnectedBindingContext bindingContext = new ConnectedBindingContext();
bindingContext.Binder = binder.Object;
bindingContext.MetadataDisplayInfoProvider = new MetadataDisplayInfoProvider();
- LanguageService.Instance.BindingQueue.BindingContextMap.Add(testScriptParseInfo.ConnectionKey, bindingContext);
+ LanguageService.Instance.BindingQueue.BindingContextMap.Add(scriptParseInfo.ConnectionKey, bindingContext);
+ }
+
+ [Fact]
+ public void HandleCompletionRequestDisabled()
+ {
+ InitializeTestObjects();
+ WorkspaceService.Instance.CurrentSettings.SqlTools.IntelliSense.EnableIntellisense = false;
+ Assert.NotNull(LanguageService.HandleCompletionRequest(null, null));
+ }
+
+ [Fact]
+ public void HandleCompletionResolveRequestDisabled()
+ {
+ InitializeTestObjects();
+ WorkspaceService.Instance.CurrentSettings.SqlTools.IntelliSense.EnableIntellisense = false;
+ Assert.NotNull(LanguageService.HandleCompletionResolveRequest(null, null));
+ }
+
+ [Fact]
+ public void HandleSignatureHelpRequestDisabled()
+ {
+ InitializeTestObjects();
+ WorkspaceService.Instance.CurrentSettings.SqlTools.IntelliSense.EnableIntellisense = false;
+ Assert.NotNull(LanguageService.HandleSignatureHelpRequest(null, null));
+ }
+
+ [Fact]
+ public void AddOrUpdateScriptParseInfoNullUri()
+ {
+ InitializeTestObjects();
+ LanguageService.Instance.AddOrUpdateScriptParseInfo("abracadabra", scriptParseInfo);
+ Assert.True(LanguageService.Instance.ScriptParseInfoMap.ContainsKey("abracadabra"));
+ }
+
+ [Fact]
+ public void GetDefinitionInvalidTextDocument()
+ {
+ InitializeTestObjects();
+ textDocument.TextDocument.Uri = "invaliduri";
+ Assert.Null(LanguageService.Instance.GetDefinition(textDocument, null, null));
+ }
+
+ [Fact]
+ public void RemoveScriptParseInfoNullUri()
+ {
+ InitializeTestObjects();
+ Assert.False(LanguageService.Instance.RemoveScriptParseInfo("abc123"));
+ }
+
+ [Fact]
+ public void IsPreviewWindowNullScriptFileTest()
+ {
+ InitializeTestObjects();
+ Assert.False(LanguageService.Instance.IsPreviewWindow(null));
+ }
+
+ [Fact]
+ public void GetCompletionItemsInvalidTextDocument()
+ {
+ InitializeTestObjects();
+ textDocument.TextDocument.Uri = "somethinggoeshere";
+ Assert.True(LanguageService.Instance.GetCompletionItems(textDocument, scriptFile.Object, null).Length > 0);
+ }
+
+ [Fact]
+ public void GetDiagnosticFromMarkerTest()
+ {
+ var scriptFileMarker = new ScriptFileMarker()
+ {
+ Message = "Message",
+ Level = ScriptFileMarkerLevel.Error,
+ ScriptRegion = new ScriptRegion()
+ {
+ File = "file://nofile.sql",
+ StartLineNumber = 1,
+ StartColumnNumber = 1,
+ StartOffset = 0,
+ EndLineNumber = 1,
+ EndColumnNumber = 1,
+ EndOffset = 0
+ }
+ };
+ var diagnostic = DiagnosticsHelper.GetDiagnosticFromMarker(scriptFileMarker);
+ Assert.Equal(diagnostic.Message, scriptFileMarker.Message);
+ }
+
+ [Fact]
+ public void MapDiagnosticSeverityTest()
+ {
+ var level = ScriptFileMarkerLevel.Error;
+ Assert.Equal(DiagnosticsHelper.MapDiagnosticSeverity(level), DiagnosticSeverity.Error);
+ level = ScriptFileMarkerLevel.Warning;
+ Assert.Equal(DiagnosticsHelper.MapDiagnosticSeverity(level), DiagnosticSeverity.Warning);
+ level = ScriptFileMarkerLevel.Information;
+ Assert.Equal(DiagnosticsHelper.MapDiagnosticSeverity(level), DiagnosticSeverity.Information);
+ level = (ScriptFileMarkerLevel)100;
+ Assert.Equal(DiagnosticsHelper.MapDiagnosticSeverity(level), DiagnosticSeverity.Error);
}
///
diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/LanguageServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/LanguageServiceTests.cs
index 841196f5..326a962f 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/LanguageServiceTests.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/LanguageServiceTests.cs
@@ -3,8 +3,10 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
+using Microsoft.SqlServer.Management.SqlParser.Parser;
using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.LanguageServices;
+using Microsoft.SqlTools.ServiceLayer.LanguageServices.Completion;
using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts;
using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts;
using Microsoft.SqlTools.Test.Utility;
@@ -147,6 +149,56 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServer
Assert.Null(signatureHelp);
}
+ [Fact]
+ public void EmptyCompletionListTest()
+ {
+ Assert.Equal(AutoCompleteHelper.EmptyCompletionList.Length, 0);
+ }
+
+ [Fact]
+ public void SetWorkspaceServiceInstanceTest()
+ {
+ AutoCompleteHelper.WorkspaceServiceInstance = null;
+ // workspace will be recreated if it's set to null
+ Assert.NotNull(AutoCompleteHelper.WorkspaceServiceInstance);
+ }
+
+ internal class TestScriptDocumentInfo : ScriptDocumentInfo
+ {
+ public TestScriptDocumentInfo(TextDocumentPosition textDocumentPosition, ScriptFile scriptFile, ScriptParseInfo scriptParseInfo)
+ :base(textDocumentPosition, scriptFile, scriptParseInfo)
+ {
+
+ }
+
+ public override string TokenText
+ {
+ get
+ {
+ return "doesntmatchanythingintheintellisensedefaultlist";
+ }
+ }
+ }
+
+ [Fact]
+ public void GetDefaultCompletionListWithNoMatchesTest()
+ {
+ var scriptFile = new ScriptFile();
+ scriptFile.SetFileContents("koko wants a bananas");
+
+ ScriptParseInfo scriptInfo = new ScriptParseInfo { IsConnected = false };
+
+ var scriptDocumentInfo = new TestScriptDocumentInfo(
+ new TextDocumentPosition()
+ {
+ TextDocument = new TextDocumentIdentifier() { Uri = TestObjects.ScriptUri },
+ Position = new Position() { Line = 0, Character = 0 }
+ }, scriptFile, scriptInfo);
+
+ AutoCompleteHelper.GetDefaultCompletionItems(scriptDocumentInfo, false);
+
+ }
+
#endregion
#region "General Language Service tests"
@@ -170,11 +222,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServer
connInfo = TestObjects.InitLiveConnectionInfo(out scriptFile);
}
-
+
///
/// Test the service initialization code path and verify nothing throws
///
- // Test is causing failures in build lab..investigating to reenable
[Fact]
public void ServiceInitialization()
{
@@ -190,12 +241,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServer
Assert.True(LanguageService.ConnectionServiceInstance != null);
Assert.True(LanguageService.Instance.CurrentSettings != null);
Assert.True(LanguageService.Instance.CurrentWorkspace != null);
- }
+ }
///
/// Test the service initialization code path and verify nothing throws
///
- // Test is causing failures in build lab..investigating to reenable
[Fact]
public void PrepopulateCommonMetadata()
{
diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/PeekDefinitionTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/PeekDefinitionTests.cs
index b70c6c54..ac55d9cd 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/PeekDefinitionTests.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/PeekDefinitionTests.cs
@@ -5,22 +5,27 @@
using System;
using System.IO;
using System.Collections.Generic;
+using System.Threading;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
+using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.SqlParser.Binder;
+using Microsoft.SqlServer.Management.SqlParser.Intellisense;
using Microsoft.SqlServer.Management.SqlParser.MetadataProvider;
using Microsoft.SqlServer.Management.SqlParser.Parser;
using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol;
+using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Contracts;
using Microsoft.SqlTools.ServiceLayer.LanguageServices;
+using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts;
using Microsoft.SqlTools.ServiceLayer.SqlContext;
using Microsoft.SqlTools.ServiceLayer.Test.QueryExecution;
using Microsoft.SqlTools.ServiceLayer.Workspace;
using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts;
using Microsoft.SqlTools.Test.Utility;
-using Location = Microsoft.SqlTools.ServiceLayer.Workspace.Contracts.Location;
using Moq;
using Xunit;
+using Location = Microsoft.SqlTools.ServiceLayer.Workspace.Contracts.Location;
namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
{
@@ -89,6 +94,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
requestContext = new Mock>();
requestContext.Setup(rc => rc.SendResult(It.IsAny()))
.Returns(Task.FromResult(0));
+ requestContext.Setup(rc => rc.SendError(It.IsAny())).Returns(Task.FromResult(0));;
+ requestContext.Setup(r => r.SendEvent(It.IsAny>(), It.IsAny())).Returns(Task.FromResult(0));;
+ requestContext.Setup(r => r.SendEvent(It.IsAny>(), It.IsAny())).Returns(Task.FromResult(0));;
// setup the IBinder mock
binder = new Mock();
@@ -99,7 +107,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
var testScriptParseInfo = new ScriptParseInfo();
LanguageService.Instance.AddOrUpdateScriptParseInfo(this.testScriptUri, testScriptParseInfo);
- testScriptParseInfo.IsConnected = true;
+ testScriptParseInfo.IsConnected = false;
testScriptParseInfo.ConnectionKey = LanguageService.Instance.BindingQueue.AddConnectionContext(connectionInfo);
// setup the binding context object
@@ -111,18 +119,19 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
///
- /// Tests the definition event handler. When called with no active connection, no definition is sent
+ /// Tests the definition event handler. When called with no active connection, an error is sent
///
[Fact]
- public void DefinitionsHandlerWithNoConnectionTest()
+ public async Task DefinitionsHandlerWithNoConnectionTest()
{
+ TestObjects.InitializeTestServices();
InitializeTestObjects();
- // request the completion list
- Task handleCompletion = LanguageService.HandleDefinitionRequest(textDocument, requestContext.Object);
- handleCompletion.Wait(TaskTimeout);
-
- // verify that send result was not called
+ // request definition
+ var definitionTask = await Task.WhenAny(LanguageService.HandleDefinitionRequest(textDocument, requestContext.Object), Task.Delay(TaskTimeout));
+ await definitionTask;
+ // verify that send result was not called and send error was called
requestContext.Verify(m => m.SendResult(It.IsAny()), Times.Never());
+ requestContext.Verify(m => m.SendError(It.IsAny()), Times.Once());
}
///
@@ -132,7 +141,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
public void GetLocationFromFileForValidFilePathTest()
{
String filePath = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "C:\\test\\script.sql" : "/test/script.sql";
- PeekDefinition peekDefinition = new PeekDefinition(null);
+ PeekDefinition peekDefinition = new PeekDefinition(null, null);
Location[] locations = peekDefinition.GetLocationFromFile(filePath, 0);
String expectedFilePath = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "file:///C:/test/script.sql" : "file:/test/script.sql";
@@ -145,11 +154,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
[Fact]
public void GetSchemaFromDatabaseQualifiedNameWithValidNameTest()
{
- PeekDefinition peekDefinition = new PeekDefinition(null);
+ PeekDefinition peekDefinition = new PeekDefinition(null, null);
string validDatabaseQualifiedName = "master.test.test_table";
string objectName = "test_table";
string expectedSchemaName = "test";
-
+
string actualSchemaName = peekDefinition.GetSchemaFromDatabaseQualifiedName(validDatabaseQualifiedName, objectName);
Assert.Equal(actualSchemaName, expectedSchemaName);
}
@@ -161,11 +170,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
[Fact]
public void GetSchemaFromDatabaseQualifiedNameWithNoSchemaTest()
{
- PeekDefinition peekDefinition = new PeekDefinition(null);
+ PeekDefinition peekDefinition = new PeekDefinition(null, null);
string validDatabaseQualifiedName = "test_table";
string objectName = "test_table";
string expectedSchemaName = "dbo";
-
+
string actualSchemaName = peekDefinition.GetSchemaFromDatabaseQualifiedName(validDatabaseQualifiedName, objectName);
Assert.Equal(actualSchemaName, expectedSchemaName);
}
@@ -176,15 +185,15 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
[Fact]
public void GetSchemaFromDatabaseQualifiedNameWithInvalidNameTest()
{
- PeekDefinition peekDefinition = new PeekDefinition(null);
+ PeekDefinition peekDefinition = new PeekDefinition(null, null);
string validDatabaseQualifiedName = "x.y.z";
string objectName = "test_table";
string expectedSchemaName = "dbo";
-
+
string actualSchemaName = peekDefinition.GetSchemaFromDatabaseQualifiedName(validDatabaseQualifiedName, objectName);
Assert.Equal(actualSchemaName, expectedSchemaName);
}
-
+
#if LIVE_CONNECTION_TESTS
///
/// Test get definition for a table object with active connection
@@ -192,10 +201,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
[Fact]
public void GetValidTableDefinitionTest()
{
- // Get live connectionInfo
+ // Get live connectionInfo and serverConnection
ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfoForDefinition();
- PeekDefinition peekDefinition = new PeekDefinition(connInfo);
- string objectName = "test_table";
+ ServerConnection serverConnection = TestObjects.InitLiveServerConnectionForDefinition(connInfo);
+
+ PeekDefinition peekDefinition = new PeekDefinition(serverConnection, connInfo);
+ string objectName = "spt_monitor";
+
string schemaName = null;
string objectType = "TABLE";
@@ -211,9 +223,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
[Fact]
public void GetTableDefinitionInvalidObjectTest()
{
- // Get live connectionInfo
+ // Get live connectionInfo and serverConnection
ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfoForDefinition();
- PeekDefinition peekDefinition = new PeekDefinition(connInfo);
+ ServerConnection serverConnection = TestObjects.InitLiveServerConnectionForDefinition(connInfo);
+
+ PeekDefinition peekDefinition = new PeekDefinition(serverConnection, connInfo);
string objectName = "test_invalid";
string schemaName = null;
string objectType = "TABLE";
@@ -229,25 +243,102 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
[Fact]
public void GetTableDefinitionWithSchemaTest()
{
- // Get live connectionInfo
+ // Get live connectionInfo and serverConnection
ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfoForDefinition();
- PeekDefinition peekDefinition = new PeekDefinition(connInfo);
- string objectName = "test_table";
+ ServerConnection serverConnection = TestObjects.InitLiveServerConnectionForDefinition(connInfo);
+
+ PeekDefinition peekDefinition = new PeekDefinition(serverConnection, connInfo);
+ string objectName = "spt_monitor";
+
string schemaName = "dbo";
string objectType = "TABLE";
// Get locations for valid table object with schema name
Location[] locations = peekDefinition.GetSqlObjectDefinition(peekDefinition.GetTableScripts, objectName, schemaName, objectType);
Assert.NotNull(locations);
- Cleanup(locations);
+ Cleanup(locations);
}
///
- /// Test GetDefinition with an unsupported type(function)
+ /// Test GetDefinition with an unsupported type(schema - dbo). Expect a error result.
///
[Fact]
- public void GetUnsupportedDefinitionForFullScript()
+ public void GetUnsupportedDefinitionErrorTest()
{
+ ScriptFile scriptFile;
+ TextDocumentPosition textDocument = new TextDocumentPosition
+ {
+ TextDocument = new TextDocumentIdentifier { Uri = OwnerUri },
+ Position = new Position
+ {
+ Line = 0,
+ // test for 'dbo'
+ Character = 16
+ }
+ };
+ ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfo(out scriptFile);
+ scriptFile.Contents = "select * from dbo.func ()";
+ var languageService = new LanguageService();
+ ScriptParseInfo scriptInfo = new ScriptParseInfo { IsConnected = true };
+ languageService.ScriptParseInfoMap.Add(OwnerUri, scriptInfo);
+
+ // When I call the language service
+ var result = languageService.GetDefinition(textDocument, scriptFile, connInfo);
+
+ // Then I expect null locations and an error to be reported
+ Assert.NotNull(result);
+ Assert.True(result.IsErrorResult);
+ }
+
+ ///
+ /// Get Definition for a object with no definition. Expect a error result
+ ///
+ [Fact]
+ public void GetDefinitionWithNoResultsFoundError()
+ {
+ ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfoForDefinition();
+ ServerConnection serverConnection = TestObjects.InitLiveServerConnectionForDefinition(connInfo);
+
+ PeekDefinition peekDefinition = new PeekDefinition(serverConnection, connInfo);
+ string objectName = "from";
+
+ List declarations = new List();
+ DefinitionResult result = peekDefinition.GetScript(declarations, objectName, null);
+
+ Assert.NotNull(result);
+ Assert.True(result.IsErrorResult);
+ Assert.Equal(SR.PeekDefinitionNoResultsError, result.Message);
+ }
+
+ ///
+ /// Test GetDefinition with a forced timeout. Expect a error result.
+ ///
+ [Fact]
+ public void GetDefinitionTimeoutTest()
+ {
+ // Given a binding queue that will automatically time out
+ var languageService = new LanguageService();
+ Mock queueMock = new Mock();
+ languageService.BindingQueue = queueMock.Object;
+ ManualResetEvent mre = new ManualResetEvent(true); // Do not block
+ Mock itemMock = new Mock();
+ itemMock.Setup(i => i.ItemProcessed).Returns(mre);
+
+ DefinitionResult timeoutResult = null;
+
+ queueMock.Setup(q => q.QueueBindingOperation(
+ It.IsAny(),
+ It.IsAny>(),
+ It.IsAny>(),
+ It.IsAny(),
+ It.IsAny()))
+ .Callback, Func, int?, int?>(
+ (key, bindOperation, timeoutOperation, blah, blah2) =>
+ {
+ timeoutResult = (DefinitionResult) timeoutOperation((IBindingContext)null);
+ itemMock.Object.Result = timeoutResult;
+ })
+ .Returns(() => itemMock.Object);
ScriptFile scriptFile;
TextDocumentPosition textDocument = new TextDocumentPosition
@@ -262,12 +353,17 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfo(out scriptFile);
scriptFile.Contents = "select * from dbo.func ()";
- var languageService = LanguageService.Instance;
ScriptParseInfo scriptInfo = new ScriptParseInfo { IsConnected = true };
languageService.ScriptParseInfoMap.Add(OwnerUri, scriptInfo);
- var locations = languageService.GetDefinition(textDocument, scriptFile, connInfo);
- Assert.Null(locations);
+ // When I call the language service
+ var result = languageService.GetDefinition(textDocument, scriptFile, connInfo);
+
+ // Then I expect null locations and an error to be reported
+ Assert.NotNull(result);
+ Assert.True(result.IsErrorResult);
+ // Check timeout message
+ Assert.Equal(SR.PeekDefinitionTimedoutError, result.Message);
}
///
@@ -277,7 +373,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
public void GetValidViewDefinitionTest()
{
ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfoForDefinition();
- PeekDefinition peekDefinition = new PeekDefinition(connInfo);
+ ServerConnection serverConnection = TestObjects.InitLiveServerConnectionForDefinition(connInfo);
+
+ PeekDefinition peekDefinition = new PeekDefinition(serverConnection, connInfo);
string objectName = "objects";
string schemaName = "sys";
string objectType = "VIEW";
@@ -293,8 +391,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
[Fact]
public void GetViewDefinitionInvalidObjectTest()
{
+ // Get live connectionInfo and serverConnection
ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfoForDefinition();
- PeekDefinition peekDefinition = new PeekDefinition(connInfo);
+ ServerConnection serverConnection = TestObjects.InitLiveServerConnectionForDefinition(connInfo);
+
+ PeekDefinition peekDefinition = new PeekDefinition(serverConnection, connInfo);
string objectName = "objects";
string schemaName = null;
string objectType = "VIEW";
@@ -309,9 +410,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
[Fact]
public void GetStoredProcedureDefinitionTest()
{
+ // Get live connectionInfo and serverConnection
ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfoForDefinition();
- PeekDefinition peekDefinition = new PeekDefinition(connInfo);
- string objectName = "SP1";
+ ServerConnection serverConnection = TestObjects.InitLiveServerConnectionForDefinition(connInfo);
+
+ PeekDefinition peekDefinition = new PeekDefinition(serverConnection, connInfo);
+ string objectName = "sp_MSrepl_startup";
+
string schemaName = "dbo";
string objectType = "PROCEDURE";
@@ -326,8 +431,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
[Fact]
public void GetStoredProcedureDefinitionFailureTest()
{
+ // Get live connectionInfo and serverConnection
ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfoForDefinition();
- PeekDefinition peekDefinition = new PeekDefinition(connInfo);
+ ServerConnection serverConnection = TestObjects.InitLiveServerConnectionForDefinition(connInfo);
+
+ PeekDefinition peekDefinition = new PeekDefinition(serverConnection, connInfo);
string objectName = "SP2";
string schemaName = "dbo";
string objectType = "PROCEDURE";
@@ -342,9 +450,12 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
[Fact]
public void GetStoredProcedureDefinitionWithoutSchemaTest()
{
+ // Get live connectionInfo and serverConnection
ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfoForDefinition();
- PeekDefinition peekDefinition = new PeekDefinition(connInfo);
- string objectName = "SP1";
+ ServerConnection serverConnection = TestObjects.InitLiveServerConnectionForDefinition(connInfo);
+
+ PeekDefinition peekDefinition = new PeekDefinition(serverConnection, connInfo);
+ string objectName = "sp_MSrepl_startup";
string schemaName = null;
string objectType = "PROCEDURE";
diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/Messaging/MessageDispatcherTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/Messaging/MessageDispatcherTests.cs
new file mode 100644
index 00000000..673b0884
--- /dev/null
+++ b/test/Microsoft.SqlTools.ServiceLayer.Test/Messaging/MessageDispatcherTests.cs
@@ -0,0 +1,88 @@
+//
+// 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.Tasks;
+using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol;
+using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Channel;
+using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Contracts;
+using Moq;
+using Xunit;
+
+namespace Microsoft.SqlTools.ServiceLayer.Test.Messaging
+{
+ public class MessageDispatcherTests
+ {
+ [Fact]
+ public void SetRequestHandlerWithOverrideTest()
+ {
+ RequestType requestType = RequestType.Create("test/requestType");
+ var dispatcher = new MessageDispatcher(new Mock().Object);
+ dispatcher.SetRequestHandler(
+ requestType,
+ (i, j) =>
+ {
+ return Task.FromResult(0);
+ },
+ true);
+ Assert.True(dispatcher.requestHandlers.Count > 0);
+ }
+
+ [Fact]
+ public void SetEventHandlerTest()
+ {
+ EventType eventType = EventType.Create("test/eventType");
+ var dispatcher = new MessageDispatcher(new Mock().Object);
+ dispatcher.SetEventHandler(
+ eventType,
+ (i, j) =>
+ {
+ return Task.FromResult(0);
+ });
+ Assert.True(dispatcher.eventHandlers.Count > 0);
+ }
+
+ [Fact]
+ public void SetEventHandlerWithOverrideTest()
+ {
+ EventType eventType = EventType.Create("test/eventType");
+ var dispatcher = new MessageDispatcher(new Mock().Object);
+ dispatcher.SetEventHandler(
+ eventType,
+ (i, j) =>
+ {
+ return Task.FromResult(0);
+ },
+ true);
+ Assert.True(dispatcher.eventHandlers.Count > 0);
+ }
+
+ [Fact]
+ public void OnListenTaskCompletedFaultedTaskTest()
+ {
+ Task t = null;
+
+ try
+ {
+ t = Task.Run(() =>
+ {
+ throw new Exception();
+ });
+ t.Wait();
+ }
+ catch
+ {
+ }
+ finally
+ {
+ bool handlerCalled = false;
+ var dispatcher = new MessageDispatcher(new Mock().Object);
+ dispatcher.UnhandledException += (s, e) => handlerCalled = true;
+ dispatcher.OnListenTaskCompleted(t);
+ Assert.True(handlerCalled);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/Messaging/MessageWriterTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/Messaging/MessageWriterTests.cs
index 3c007a85..4cc99592 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.Test/Messaging/MessageWriterTests.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.Test/Messaging/MessageWriterTests.cs
@@ -7,7 +7,9 @@ using System.IO;
using System.Text;
using System.Threading.Tasks;
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol;
+using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Contracts;
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Serializers;
+using Newtonsoft.Json.Linq;
using Xunit;
namespace Microsoft.SqlTools.ServiceLayer.Test.Messaging
@@ -21,6 +23,40 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Messaging
this.messageSerializer = new V8MessageSerializer();
}
+ [Fact]
+ public void SerializeMessageTest()
+ {
+ // serialize\deserialize a request
+ var message = new Message();
+ message.MessageType = MessageType.Request;
+ message.Id = "id";
+ message.Method = "method";
+ message.Contents = null;
+ var serializedMessage = this.messageSerializer.SerializeMessage(message);
+ Assert.NotNull(serializedMessage);
+ var deserializedMessage = this.messageSerializer.DeserializeMessage(serializedMessage);
+ Assert.Equal(message.Id, deserializedMessage.Id);
+
+ // serialize\deserialize a response
+ message.MessageType = MessageType.Response;
+ serializedMessage = this.messageSerializer.SerializeMessage(message);
+ Assert.NotNull(serializedMessage);
+ deserializedMessage = this.messageSerializer.DeserializeMessage(serializedMessage);
+ Assert.Equal(message.Id, deserializedMessage.Id);
+
+ // serialize\deserialize a response with an error
+ message.Error = JToken.FromObject("error");
+ serializedMessage = this.messageSerializer.SerializeMessage(message);
+ Assert.NotNull(serializedMessage);
+ deserializedMessage = this.messageSerializer.DeserializeMessage(serializedMessage);
+ Assert.Equal(message.Error, deserializedMessage.Error);
+
+ // serialize\deserialize an unknown response type
+ serializedMessage.Remove("type");
+ serializedMessage.Add("type", JToken.FromObject("dontknowthisone"));
+ Assert.Equal(this.messageSerializer.DeserializeMessage(serializedMessage).MessageType, MessageType.Unknown);
+ }
+
[Fact]
public async Task WritesMessage()
{
diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/DataStorage/StorageDataReaderTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/DataStorage/StorageDataReaderTests.cs
index e29c8394..567e1a7a 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/DataStorage/StorageDataReaderTests.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/DataStorage/StorageDataReaderTests.cs
@@ -5,6 +5,7 @@
#if LIVE_CONNECTION_TESTS
+using System;
using System.Data.Common;
using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage;
@@ -60,8 +61,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.DataStorage
reader.Read();
Assert.False(storageReader.IsDBNull(0));
+ Assert.NotNull(storageReader.GetValue(0));
+
string shortName = storageReader.GetCharsWithMaxCapacity(0, 2);
Assert.True(shortName.Length == 2);
+
+ Assert.Throws(() => storageReader.GetBytesWithMaxCapacity(0, 0));
+ Assert.Throws(() => storageReader.GetCharsWithMaxCapacity(0, 0));
}
///
@@ -88,10 +94,15 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.DataStorage
[Fact]
public void StringWriterWithMaxCapacityTest()
{
- var writer = new StorageDataReader.StringWriterWithMaxCapacity(null, 100);
+ var writer = new StorageDataReader.StringWriterWithMaxCapacity(null, 4);
string output = "...";
writer.Write(output);
Assert.True(writer.ToString().Equals(output));
+ writer.Write('.');
+ Assert.True(writer.ToString().Equals(output + '.'));
+ writer.Write(output);
+ writer.Write('.');
+ Assert.True(writer.ToString().Equals(output + '.'));
}
}
}
diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Execution/BatchTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Execution/BatchTests.cs
index 12b99a3b..9ac1f6c2 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Execution/BatchTests.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Execution/BatchTests.cs
@@ -5,7 +5,9 @@
using System;
using System.Collections.Generic;
+using System.Data;
using System.Data.Common;
+using System.Data.SqlClient;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -388,8 +390,22 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
// Then:
// ... It should throw an exception
Assert.Throws(() => new Batch("stuff", Common.SubsectionDocument, -1, Common.GetFileStreamFactory(null)));
- }
+ }
+ [Fact]
+ public void StatementCompletedHandlerTest()
+ {
+ // If:
+ // ... I call the StatementCompletedHandler
+ // Then:
+ // ... a ResultMaessage should be logged in the resultsMessages collection
+ Batch batch = new Batch(Common.StandardQuery, Common.SubsectionDocument, Common.Ordinal, Common.GetFileStreamFactory(null));
+ batch.StatementCompletedHandler(null, new StatementCompletedEventArgs(1));
+ Assert.True(batch.ResultMessages.Count() == 1);
+ batch.StatementCompletedHandler(null, new StatementCompletedEventArgs(2));
+ Assert.True(batch.ResultMessages.Count() == 2);
+ }
+
private static DbConnection GetConnection(ConnectionInfo info)
{
return info.Factory.CreateSqlConnection(ConnectionService.BuildConnectionString(info.ConnectionDetails));
diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Execution/DbColumnWrapperTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Execution/DbColumnWrapperTests.cs
new file mode 100644
index 00000000..ca88699b
--- /dev/null
+++ b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Execution/DbColumnWrapperTests.cs
@@ -0,0 +1,114 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+using System.Data.Common;
+using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts;
+using Xunit;
+
+namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution
+{
+ ///
+ /// DbColumnWrapper tests
+ ///
+ public class DbColumnWrapperTests
+ {
+ ///
+ /// Test DbColumn derived class
+ ///
+ class TestColumn : DbColumn
+ {
+ public TestColumn(
+ string dataTypeName = null,
+ int? columnSize = null,
+ string columnName = null,
+ string udtAssemblyQualifiedName = null)
+ {
+ if (!string.IsNullOrEmpty(dataTypeName))
+ {
+ this.DataTypeName = dataTypeName;
+ }
+
+ if (columnSize.HasValue)
+ {
+ this.ColumnSize = columnSize;
+ }
+
+ if (!string.IsNullOrEmpty(columnName))
+ {
+ this.ColumnName = columnName;
+ }
+
+ if (!string.IsNullOrEmpty(udtAssemblyQualifiedName))
+ {
+ this.UdtAssemblyQualifiedName = udtAssemblyQualifiedName;
+ }
+ }
+ }
+
+ ///
+ /// Basic data type and properites test
+ ///
+ [Fact]
+ public void DataTypeAndPropertiesTest()
+ {
+ // check that data types array contains items
+ var serverDataTypes = DbColumnWrapper.AllServerDataTypes;
+ Assert.True(serverDataTypes.Count > 0);
+
+ // check default constructor doesn't throw
+ Assert.NotNull(new DbColumnWrapper());
+
+ // check various properties are either null or not null
+ var column = new TestColumn();
+ var wrapper = new DbColumnWrapper(column);
+ Assert.NotNull(wrapper.DataType);
+ Assert.Null(wrapper.AllowDBNull);
+ Assert.Null(wrapper.BaseCatalogName);
+ Assert.Null(wrapper.BaseColumnName);
+ Assert.Null(wrapper.BaseServerName);
+ Assert.Null(wrapper.BaseTableName);
+ Assert.Null(wrapper.ColumnOrdinal);
+ Assert.Null(wrapper.ColumnSize);
+ Assert.Null(wrapper.IsAliased);
+ Assert.Null(wrapper.IsAutoIncrement);
+ Assert.Null(wrapper.IsExpression);
+ Assert.Null(wrapper.IsHidden);
+ Assert.Null(wrapper.IsIdentity);
+ Assert.Null(wrapper.IsKey);
+ Assert.Null(wrapper. IsReadOnly);
+ Assert.Null(wrapper.IsUnique);
+ Assert.Null(wrapper.NumericPrecision);
+ Assert.Null(wrapper.NumericScale);
+ Assert.Null(wrapper.UdtAssemblyQualifiedName);
+ Assert.Null(wrapper.DataTypeName);
+ }
+
+ ///
+ /// constructor test
+ ///
+ [Fact]
+ public void DbColumnConstructorTests()
+ {
+ // check that various constructor parameters initial the wrapper correctly
+ var w1 = new DbColumnWrapper(new TestColumn("varchar", int.MaxValue, "Microsoft SQL Server 2005 XML Showplan"));
+ Assert.True(w1.IsXml);
+
+ var w2 = new DbColumnWrapper(new TestColumn("binary"));
+ Assert.True(w2.IsBytes);
+
+ var w3 = new DbColumnWrapper(new TestColumn("varbinary", int.MaxValue));
+ Assert.True(w3.IsBytes);
+
+ var w4 = new DbColumnWrapper(new TestColumn("sql_variant"));
+ Assert.True(w4.IsSqlVariant);
+
+ var w5 = new DbColumnWrapper(new TestColumn("my_udt"));
+ Assert.True(w5.IsUdt);
+
+ var w6 = new DbColumnWrapper(new TestColumn("my_hieracrchy", null, null, "MICROSOFT.SQLSERVER.TYPES.SQLHIERARCHYID"));
+ Assert.True(w6.IsUdt);
+ }
+ }
+}
diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/LongListTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/LongListTests.cs
index a28714bc..330214ca 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/LongListTests.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/LongListTests.cs
@@ -25,5 +25,34 @@ namespace Microsoft.SqlTools.Test.Utility
longList.RemoveAt(0);
Assert.True(longList.Count == 0);
}
+
+ ///
+ /// Add and remove and item in a LongList causing an expansion
+ ///
+ [Fact]
+ public void LongListExpandTest()
+ {
+ var longList = new LongList();
+ longList.ExpandListSize = 3;
+ for (int i = 0; i < 6; ++i)
+ {
+ longList.Add(i);
+ }
+ Assert.Equal(longList.Count, 6);
+ Assert.NotNull(longList.GetItem(4));
+
+ bool didEnum = false;
+ foreach (var j in longList)
+ {
+ didEnum = true;
+ break;
+ }
+
+ Assert.True(didEnum);
+
+ longList.RemoveAt(4);
+ Assert.Equal(longList.Count, 5);
+ }
}
}
+
diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/SrTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/SrTests.cs
new file mode 100644
index 00000000..8b15df20
--- /dev/null
+++ b/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/SrTests.cs
@@ -0,0 +1,25 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+using Microsoft.SqlTools.ServiceLayer;
+using Xunit;
+
+namespace Microsoft.SqlTools.Test.Utility
+{
+ public class SrTests
+ {
+ ///
+ /// Add and remove and item in a LongList
+ ///
+ [Fact]
+ public void SrPropertiesTest()
+ {
+ Assert.NotNull(SR.QueryServiceSubsetBatchNotCompleted);
+ Assert.NotNull(SR.QueryServiceFileWrapperWriteOnly);
+ Assert.NotNull(SR.QueryServiceFileWrapperNotInitialized);
+ Assert.NotNull(SR.QueryServiceColumnNull);
+ }
+ }
+}
diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestObjects.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestObjects.cs
index 00fc7f13..7af19715 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestObjects.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestObjects.cs
@@ -7,8 +7,10 @@ using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
+using System.Data.SqlClient;
using System.IO;
using System.Reflection;
+using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
using Microsoft.SqlTools.ServiceLayer.Credentials;
@@ -228,6 +230,12 @@ namespace Microsoft.SqlTools.Test.Utility
}
};
}
+
+ public static ServerConnection InitLiveServerConnectionForDefinition(ConnectionInfo connInfo)
+ {
+ SqlConnection sqlConn = new SqlConnection(ConnectionService.BuildConnectionString(connInfo.ConnectionDetails));
+ return new ServerConnection(sqlConn);
+ }
}
///
diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/ValidateTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/ValidateTests.cs
new file mode 100644
index 00000000..8f4f790d
--- /dev/null
+++ b/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/ValidateTests.cs
@@ -0,0 +1,38 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+using System;
+using Microsoft.SqlTools.ServiceLayer.Utility;
+using Xunit;
+
+namespace Microsoft.SqlTools.Test.Utility
+{
+ public class ValidateTests
+ {
+ [Fact]
+ public void IsWithinRangeTest()
+ {
+ Assert.Throws(() => Validate.IsWithinRange("parameterName", 1, 2, 3));
+ }
+
+ [Fact]
+ public void IsLessThanTest()
+ {
+ Assert.Throws(() => Validate.IsLessThan("parameterName", 2, 1));
+ }
+
+ [Fact]
+ public void IsNotEqualTest()
+ {
+ Assert.Throws(() => Validate.IsNotEqual("parameterName", 1, 1));
+ }
+
+ [Fact]
+ public void IsNullOrWhiteSpaceTest()
+ {
+ Assert.Throws(() => Validate.IsNotNullOrWhitespaceString("parameterName", null));
+ }
+ }
+}
diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/Workspace/WorkspaceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/Workspace/WorkspaceTests.cs
index ad5c3b3d..df63e816 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.Test/Workspace/WorkspaceTests.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.Test/Workspace/WorkspaceTests.cs
@@ -3,10 +3,12 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
+using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol;
using Microsoft.SqlTools.ServiceLayer.SqlContext;
+using Microsoft.SqlTools.ServiceLayer.Test.Utility;
using Microsoft.SqlTools.ServiceLayer.Workspace;
using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts;
using Microsoft.SqlTools.Test.Utility;
@@ -90,5 +92,58 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Workspace
Assert.Empty(workspace.GetOpenedFiles());
Assert.False(callbackCalled);
}
+
+ [Fact]
+ public void BufferRangeNoneNotNull()
+ {
+ Assert.NotNull(BufferRange.None);
+ }
+
+ [Fact]
+ public void BufferRangeStartGreaterThanEnd()
+ {
+ Assert.Throws(() =>
+ new BufferRange(new BufferPosition(2, 2), new BufferPosition(1, 1)));
+ }
+
+ [Fact]
+ public void BufferRangeEquals()
+ {
+ var range = new BufferRange(new BufferPosition(1, 1), new BufferPosition(2, 2));
+ Assert.False(range.Equals(null));
+ Assert.True(range.Equals(range));
+ Assert.NotNull(range.GetHashCode());
+ }
+
+ [Fact]
+ public void UnescapePath()
+ {
+ Assert.NotNull(Microsoft.SqlTools.ServiceLayer.Workspace.Workspace.UnescapePath("`/path/`"));
+ }
+
+ [Fact]
+ public void GetBaseFilePath()
+ {
+ TestUtils.RunIfWindows(() =>
+ {
+ using (var workspace = new ServiceLayer.Workspace.Workspace())
+ {
+ Assert.Throws(() => workspace.GetBaseFilePath("path"));
+ Assert.NotNull(workspace.GetBaseFilePath(@"c:\path\file.sql"));
+ Assert.Equal(workspace.GetBaseFilePath("tsqloutput://c:/path/file.sql"), workspace.WorkspacePath);
+ }
+ });
+ }
+
+ [Fact]
+ public void ResolveRelativeScriptPath()
+ {
+ TestUtils.RunIfWindows(() =>
+ {
+ var workspace = new ServiceLayer.Workspace.Workspace();
+ Assert.NotNull(workspace.ResolveRelativeScriptPath(null, @"c:\path\file.sql"));
+ Assert.NotNull(workspace.ResolveRelativeScriptPath(@"c:\path\", "file.sql"));
+ });
+ }
}
}
diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/project.json b/test/Microsoft.SqlTools.ServiceLayer.Test/project.json
index 977de2ab..d294d099 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.Test/project.json
+++ b/test/Microsoft.SqlTools.ServiceLayer.Test/project.json
@@ -19,7 +19,7 @@
"System.Runtime.Serialization.Primitives": "4.1.1",
"System.Data.Common": "4.1.0",
"System.Data.SqlClient": "4.4.0-sqltools-24613-04",
- "Microsoft.SqlServer.Smo": "140.1.11",
+ "Microsoft.SqlServer.Smo": "140.1.12",
"System.Security.SecureString": "4.0.0",
"System.Collections.Specialized": "4.0.1",
"System.ComponentModel.TypeConverter": "4.1.0",