Add fix for SendEvent causing test to fail (#195)

Add flag in ServiceHost to ignore SendEvent errors
This commit is contained in:
Connor Quagliana
2016-12-19 14:01:03 -08:00
committed by GitHub
parent 1a2e802a5d
commit ba12a80fbf
2 changed files with 58 additions and 31 deletions

View File

@@ -9,6 +9,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Channel; using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Channel;
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Contracts; using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Contracts;
using Microsoft.SqlTools.ServiceLayer.Utility;
namespace Microsoft.SqlTools.ServiceLayer.Hosting.Protocol namespace Microsoft.SqlTools.ServiceLayer.Hosting.Protocol
{ {
@@ -28,6 +29,14 @@ namespace Microsoft.SqlTools.ServiceLayer.Hosting.Protocol
private Dictionary<string, TaskCompletionSource<Message>> pendingRequests = private Dictionary<string, TaskCompletionSource<Message>> pendingRequests =
new Dictionary<string, TaskCompletionSource<Message>>(); new Dictionary<string, TaskCompletionSource<Message>>();
/// <summary>
/// When true, SendEvent will ignore exceptions and write them
/// to the log instead. Intended to be used for test scenarios
/// where SendEvent throws exceptions unrelated to what is
/// being tested.
/// </summary>
internal static bool SendEventIgnoreExceptions = false;
/// <summary> /// <summary>
/// Gets the MessageDispatcher which allows registration of /// Gets the MessageDispatcher which allows registration of
/// handlers for requests, responses, and events that are /// handlers for requests, responses, and events that are
@@ -194,37 +203,52 @@ namespace Microsoft.SqlTools.ServiceLayer.Hosting.Protocol
EventType<TParams> eventType, EventType<TParams> eventType,
TParams eventParams) TParams eventParams)
{ {
if (!this.protocolChannel.IsConnected) try
{ {
throw new InvalidOperationException("SendEvent called when ProtocolChannel was not yet connected"); if (!this.protocolChannel.IsConnected)
{
throw new InvalidOperationException("SendEvent called when ProtocolChannel was not yet connected");
}
// Some events could be raised from a different thread.
// To ensure that messages are written serially, dispatch
// dispatch the SendEvent call to the message loop thread.
if (!this.MessageDispatcher.InMessageLoopThread)
{
TaskCompletionSource<bool> writeTask = new TaskCompletionSource<bool>();
this.MessageDispatcher.SynchronizationContext.Post(
async (obj) =>
{
await this.protocolChannel.MessageWriter.WriteEvent(
eventType,
eventParams);
writeTask.SetResult(true);
}, null);
return writeTask.Task;
}
else
{
return this.protocolChannel.MessageWriter.WriteEvent(
eventType,
eventParams);
}
} }
catch (Exception ex)
// Some events could be raised from a different thread.
// To ensure that messages are written serially, dispatch
// dispatch the SendEvent call to the message loop thread.
if (!this.MessageDispatcher.InMessageLoopThread)
{ {
TaskCompletionSource<bool> writeTask = new TaskCompletionSource<bool>(); if (SendEventIgnoreExceptions)
{
this.MessageDispatcher.SynchronizationContext.Post( Logger.Write(LogLevel.Verbose, "Exception in SendEvent " + ex.ToString());
async (obj) => }
{ else
await this.protocolChannel.MessageWriter.WriteEvent( {
eventType, throw;
eventParams); }
writeTask.SetResult(true);
}, null);
return writeTask.Task;
}
else
{
return this.protocolChannel.MessageWriter.WriteEvent(
eventType,
eventParams);
} }
return Task.FromResult(false);
} }
#endregion #endregion

View File

@@ -3,7 +3,6 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
// //
using Microsoft.SqlServer.Management.SqlParser.Parser;
using Microsoft.SqlTools.ServiceLayer.Connection; using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.LanguageServices; using Microsoft.SqlTools.ServiceLayer.LanguageServices;
using Microsoft.SqlTools.ServiceLayer.LanguageServices.Completion; using Microsoft.SqlTools.ServiceLayer.LanguageServices.Completion;
@@ -290,6 +289,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServer
{ {
// When we make a connection to a live database // When we make a connection to a live database
ScriptFile scriptFile; ScriptFile scriptFile;
Hosting.ServiceHost.SendEventIgnoreExceptions = true;
ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfo(out scriptFile); ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfo(out scriptFile);
// And we place the cursor after a function that should prompt for signature help // And we place the cursor after a function that should prompt for signature help
@@ -308,12 +308,15 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServer
} }
}; };
// If we have a valid ScriptParseInfo and the SQL has already been parsed // If the SQL has already been parsed
var service = LanguageService.Instance; var service = LanguageService.Instance;
ScriptParseInfo parseInfo = service.GetScriptParseInfo(scriptFile.ClientFilePath);
await service.UpdateLanguageServiceOnConnection(connInfo); await service.UpdateLanguageServiceOnConnection(connInfo);
// We should get back a non-null SignatureHelp // We should get back a non-null ScriptParseInfo
ScriptParseInfo parseInfo = service.GetScriptParseInfo(scriptFile.ClientFilePath);
Assert.NotNull(parseInfo);
// And we should get back a non-null SignatureHelp
SignatureHelp signatureHelp = service.GetSignatureHelp(textDocument, scriptFile); SignatureHelp signatureHelp = service.GetSignatureHelp(textDocument, scriptFile);
Assert.NotNull(signatureHelp); Assert.NotNull(signatureHelp);
} }