From 217106adc70f91eb262211dbef41aa85c8e374a0 Mon Sep 17 00:00:00 2001 From: Medeni Baykal <433724+Haplois@users.noreply.github.com> Date: Tue, 4 May 2021 16:15:48 +0200 Subject: [PATCH] Abort when init and run messages fail to process (#2857) * Abort when init and run messages fail to process, usually on deserialization, to prevent the host from hanging * Send the message via the abort handler when we abort the run --- .../Resources/xlf/Resources.xlf.lcl | 9 + .../Resources/xlf/Resources.xlf.lcl | 9 + .../Resources/xlf/Resources.xlf.lcl | 9 + .../Resources/xlf/Resources.xlf.lcl | 9 + .../Resources/xlf/Resources.xlf.lcl | 9 + .../Resources/xlf/Resources.xlf.lcl | 9 + .../Resources/xlf/Resources.xlf.lcl | 9 + .../Resources/xlf/Resources.xlf.lcl | 9 + .../Resources/xlf/Resources.xlf.lcl | 9 + .../Resources/xlf/Resources.xlf.lcl | 9 + .../Resources/xlf/Resources.xlf.lcl | 9 + .../Resources/xlf/Resources.xlf.lcl | 9 + .../Resources/xlf/Resources.xlf.lcl | 9 + .../ExtensionFramework/TestPluginCache.cs | 2 +- .../Utilities/AssemblyResolver.cs | 11 +- .../EventHandlers/TestRequestHandler.cs | 248 ++++++++++++------ .../Resources/Resources.Designer.cs | 9 + src/vstest.console/Resources/Resources.resx | 3 + .../Resources/xlf/Resources.cs.xlf | 5 + .../Resources/xlf/Resources.de.xlf | 5 + .../Resources/xlf/Resources.es.xlf | 5 + .../Resources/xlf/Resources.fr.xlf | 5 + .../Resources/xlf/Resources.it.xlf | 5 + .../Resources/xlf/Resources.ja.xlf | 5 + .../Resources/xlf/Resources.ko.xlf | 5 + .../Resources/xlf/Resources.pl.xlf | 5 + .../Resources/xlf/Resources.pt-BR.xlf | 5 + .../Resources/xlf/Resources.ru.xlf | 5 + .../Resources/xlf/Resources.tr.xlf | 5 + .../Resources/xlf/Resources.xlf | 5 + .../Resources/xlf/Resources.zh-Hans.xlf | 5 + .../Resources/xlf/Resources.zh-Hant.xlf | 5 + 32 files changed, 379 insertions(+), 81 deletions(-) diff --git a/Localize/lcl/cs/src/vstest.console/Resources/xlf/Resources.xlf.lcl b/Localize/lcl/cs/src/vstest.console/Resources/xlf/Resources.xlf.lcl index 6d5841ec92..71b42b54f7 100644 --- a/Localize/lcl/cs/src/vstest.console/Resources/xlf/Resources.xlf.lcl +++ b/Localize/lcl/cs/src/vstest.console/Resources/xlf/Resources.xlf.lcl @@ -1447,6 +1447,15 @@ + + + + + + + + + diff --git a/Localize/lcl/de/src/vstest.console/Resources/xlf/Resources.xlf.lcl b/Localize/lcl/de/src/vstest.console/Resources/xlf/Resources.xlf.lcl index 1e3a855acc..518138e41b 100644 --- a/Localize/lcl/de/src/vstest.console/Resources/xlf/Resources.xlf.lcl +++ b/Localize/lcl/de/src/vstest.console/Resources/xlf/Resources.xlf.lcl @@ -1447,6 +1447,15 @@ + + + + + + + + + diff --git a/Localize/lcl/es/src/vstest.console/Resources/xlf/Resources.xlf.lcl b/Localize/lcl/es/src/vstest.console/Resources/xlf/Resources.xlf.lcl index 6bd006aeca..7e5b02decc 100644 --- a/Localize/lcl/es/src/vstest.console/Resources/xlf/Resources.xlf.lcl +++ b/Localize/lcl/es/src/vstest.console/Resources/xlf/Resources.xlf.lcl @@ -1447,6 +1447,15 @@ + + + + + + + + + diff --git a/Localize/lcl/fr/src/vstest.console/Resources/xlf/Resources.xlf.lcl b/Localize/lcl/fr/src/vstest.console/Resources/xlf/Resources.xlf.lcl index d91af2d4c8..28b0578882 100644 --- a/Localize/lcl/fr/src/vstest.console/Resources/xlf/Resources.xlf.lcl +++ b/Localize/lcl/fr/src/vstest.console/Resources/xlf/Resources.xlf.lcl @@ -1447,6 +1447,15 @@ + + + + + + + + + diff --git a/Localize/lcl/it/src/vstest.console/Resources/xlf/Resources.xlf.lcl b/Localize/lcl/it/src/vstest.console/Resources/xlf/Resources.xlf.lcl index b549e506af..69060108a2 100644 --- a/Localize/lcl/it/src/vstest.console/Resources/xlf/Resources.xlf.lcl +++ b/Localize/lcl/it/src/vstest.console/Resources/xlf/Resources.xlf.lcl @@ -1447,6 +1447,15 @@ + + + + + + + + + diff --git a/Localize/lcl/ja/src/vstest.console/Resources/xlf/Resources.xlf.lcl b/Localize/lcl/ja/src/vstest.console/Resources/xlf/Resources.xlf.lcl index 0da8590fb2..49a8b2fbd3 100644 --- a/Localize/lcl/ja/src/vstest.console/Resources/xlf/Resources.xlf.lcl +++ b/Localize/lcl/ja/src/vstest.console/Resources/xlf/Resources.xlf.lcl @@ -1447,6 +1447,15 @@ + + + + + + + + + diff --git a/Localize/lcl/ko/src/vstest.console/Resources/xlf/Resources.xlf.lcl b/Localize/lcl/ko/src/vstest.console/Resources/xlf/Resources.xlf.lcl index a162633776..fbba9911d2 100644 --- a/Localize/lcl/ko/src/vstest.console/Resources/xlf/Resources.xlf.lcl +++ b/Localize/lcl/ko/src/vstest.console/Resources/xlf/Resources.xlf.lcl @@ -1447,6 +1447,15 @@ + + + + + + + + + diff --git a/Localize/lcl/pl/src/vstest.console/Resources/xlf/Resources.xlf.lcl b/Localize/lcl/pl/src/vstest.console/Resources/xlf/Resources.xlf.lcl index 0fe1a5a261..393ea60af2 100644 --- a/Localize/lcl/pl/src/vstest.console/Resources/xlf/Resources.xlf.lcl +++ b/Localize/lcl/pl/src/vstest.console/Resources/xlf/Resources.xlf.lcl @@ -1447,6 +1447,15 @@ + + + + + + + + + diff --git a/Localize/lcl/pt-BR/src/vstest.console/Resources/xlf/Resources.xlf.lcl b/Localize/lcl/pt-BR/src/vstest.console/Resources/xlf/Resources.xlf.lcl index 3053291372..f8c00f0a70 100644 --- a/Localize/lcl/pt-BR/src/vstest.console/Resources/xlf/Resources.xlf.lcl +++ b/Localize/lcl/pt-BR/src/vstest.console/Resources/xlf/Resources.xlf.lcl @@ -1447,6 +1447,15 @@ + + + + + + + + + diff --git a/Localize/lcl/ru/src/vstest.console/Resources/xlf/Resources.xlf.lcl b/Localize/lcl/ru/src/vstest.console/Resources/xlf/Resources.xlf.lcl index effb3f0674..c8b92a5d09 100644 --- a/Localize/lcl/ru/src/vstest.console/Resources/xlf/Resources.xlf.lcl +++ b/Localize/lcl/ru/src/vstest.console/Resources/xlf/Resources.xlf.lcl @@ -1456,6 +1456,15 @@ + + + + + + + + + diff --git a/Localize/lcl/tr/src/vstest.console/Resources/xlf/Resources.xlf.lcl b/Localize/lcl/tr/src/vstest.console/Resources/xlf/Resources.xlf.lcl index 5c41ae9bcc..1cd6d0c92a 100644 --- a/Localize/lcl/tr/src/vstest.console/Resources/xlf/Resources.xlf.lcl +++ b/Localize/lcl/tr/src/vstest.console/Resources/xlf/Resources.xlf.lcl @@ -1447,6 +1447,15 @@ + + + + + + + + + diff --git a/Localize/lcl/zh-Hans/src/vstest.console/Resources/xlf/Resources.xlf.lcl b/Localize/lcl/zh-Hans/src/vstest.console/Resources/xlf/Resources.xlf.lcl index fbde648b43..d792ba3f6f 100644 --- a/Localize/lcl/zh-Hans/src/vstest.console/Resources/xlf/Resources.xlf.lcl +++ b/Localize/lcl/zh-Hans/src/vstest.console/Resources/xlf/Resources.xlf.lcl @@ -1447,6 +1447,15 @@ + + + + + + + + + diff --git a/Localize/lcl/zh-Hant/src/vstest.console/Resources/xlf/Resources.xlf.lcl b/Localize/lcl/zh-Hant/src/vstest.console/Resources/xlf/Resources.xlf.lcl index 6ecf0c8d61..09c580328a 100644 --- a/Localize/lcl/zh-Hant/src/vstest.console/Resources/xlf/Resources.xlf.lcl +++ b/Localize/lcl/zh-Hant/src/vstest.console/Resources/xlf/Resources.xlf.lcl @@ -1447,6 +1447,15 @@ + + + + + + + + + diff --git a/src/Microsoft.TestPlatform.Common/ExtensionFramework/TestPluginCache.cs b/src/Microsoft.TestPlatform.Common/ExtensionFramework/TestPluginCache.cs index 605c1fa8fe..5344b257ad 100644 --- a/src/Microsoft.TestPlatform.Common/ExtensionFramework/TestPluginCache.cs +++ b/src/Microsoft.TestPlatform.Common/ExtensionFramework/TestPluginCache.cs @@ -529,7 +529,7 @@ private Assembly CurrentDomainAssemblyResolve(object sender, AssemblyResolveEven { try { - EqtTrace.Verbose("CurrentDomain_AssemblyResolve: Resolving assembly '{0}'.", args.Name); + EqtTrace.Verbose("CurrentDomainAssemblyResolve: Resolving assembly '{0}'.", args.Name); if (this.resolvedAssemblies.TryGetValue(args.Name, out assembly)) { diff --git a/src/Microsoft.TestPlatform.Common/Utilities/AssemblyResolver.cs b/src/Microsoft.TestPlatform.Common/Utilities/AssemblyResolver.cs index 603312785b..4a625b0744 100644 --- a/src/Microsoft.TestPlatform.Common/Utilities/AssemblyResolver.cs +++ b/src/Microsoft.TestPlatform.Common/Utilities/AssemblyResolver.cs @@ -106,6 +106,7 @@ private Assembly OnResolve(object sender, AssemblyResolveEventArgs args) if (this.searchDirectories == null || this.searchDirectories.Count == 0) { + EqtTrace.Info("AssemblyResolver.OnResolve: {0}: There are no search directories, returning.", args.Name); return null; } @@ -146,6 +147,8 @@ private Assembly OnResolve(object sender, AssemblyResolveEventArgs args) continue; } + EqtTrace.Info("AssemblyResolver.OnResolve: {0}: Searching in: '{1}'.", args.Name, dir); + foreach (var extension in SupportedFileExtensions) { var assemblyPath = Path.Combine(dir, requestedName.Name + extension); @@ -153,6 +156,8 @@ private Assembly OnResolve(object sender, AssemblyResolveEventArgs args) { if (!File.Exists(assemblyPath)) { + EqtTrace.Info("AssemblyResolver.OnResolve: {0}: Assembly path does not exist: '{1}', returning.", args.Name, assemblyPath); + continue; } @@ -160,9 +165,13 @@ private Assembly OnResolve(object sender, AssemblyResolveEventArgs args) if (!this.RequestedAssemblyNameMatchesFound(requestedName, foundName)) { + EqtTrace.Info("AssemblyResolver.OnResolve: {0}: File exists but version/public key is wrong. Try next extension.", args.Name); + continue; // File exists but version/public key is wrong. Try next extension. } + EqtTrace.Info("AssemblyResolver.OnResolve: {0}: Loading assembly '{1}'.", args.Name, assemblyPath); + assembly = this.platformAssemblyLoadContext.LoadAssemblyFromPath(assemblyPath); this.resolvedAssemblies[args.Name] = assembly; @@ -172,7 +181,7 @@ private Assembly OnResolve(object sender, AssemblyResolveEventArgs args) } catch (FileLoadException ex) { - EqtTrace.Info("AssemblyResolver.OnResolve: {0}: Failed to load assembly. Reason:{1} ", args.Name, ex); + EqtTrace.Error("AssemblyResolver.OnResolve: {0}: Failed to load assembly. Reason:{1} ", args.Name, ex); // Re-throw FileLoadException, because this exception means that the assembly // was found, but could not be loaded. This will allow us to report a more diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs index 50137fe787..dec5071b2f 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs @@ -41,8 +41,9 @@ public class TestRequestHandler : ITestRequestHandler private ManualResetEventSlim sessionCompleted; private Action onLaunchAdapterProcessWithDebuggerAttachedAckReceived; private Action onAttachDebuggerAckRecieved; + private Exception messageProcessingUnrecoverableError; - public TestHostConnectionInfo ConnectionInfo { get; set; } + public TestHostConnectionInfo ConnectionInfo { get; set; } /// /// Initializes a new instance of the . @@ -167,6 +168,19 @@ public void SendExecutionComplete( ICollection runContextAttachments, ICollection executorUris) { + // When we abort the run we might have saved the error before we gave the handler the chance to abort + // if the handler does not return with any new error we report the original one. + if (testRunCompleteArgs.IsAborted && testRunCompleteArgs.Error == null && this.messageProcessingUnrecoverableError != null) + { + var curentArgs = testRunCompleteArgs; + testRunCompleteArgs = new TestRunCompleteEventArgs( + curentArgs.TestRunStatistics, + curentArgs.IsCanceled, + curentArgs.IsAborted, + this.messageProcessingUnrecoverableError, + curentArgs.AttachmentSets, curentArgs.ElapsedTimeInRunningTests + ); + } var data = this.dataSerializer.SerializePayload( MessageType.ExecutionComplete, new TestRunCompletePayload @@ -257,104 +271,152 @@ public void OnMessageReceived(object sender, MessageReceivedEventArgs messageRec if (EqtTrace.IsInfoEnabled) { - EqtTrace.Info("TestRequestHandler.ProcessRequests: received message: {0}", message); + EqtTrace.Info("TestRequestHandler.OnMessageReceived: received message: {0}", message); } switch (message.MessageType) { case MessageType.VersionCheck: - var version = this.dataSerializer.DeserializePayload(message); - // choose the highest version that we both support - var negotiatedVersion = Math.Min(version, highestSupportedVersion); - // BUT don't choose 3, because protocol version 3 has performance problems in 16.7.1-16.8. Those problems are caused - // by choosing payloadSerializer instead of payloadSerializer2 for protocol version 3. - // - // We cannot just update the code to choose the new serializer, because then that change would apply only to testhost. - // Testhost is is delivered by Microsoft.NET.Test.SDK nuget package, and can be used with an older vstest.console. - // An older vstest.console, that supports protocol version 3, would serialize its messages using payloadSerializer, - // but the fixed testhost would serialize it using payloadSerializer2, resulting in incompatible messages. - // - // Instead we must downgrade to protocol version 2 when 3 would be negotiated. Or higher when higher version - // would be negotiated. - if (negotiatedVersion != 3) - { - this.protocolVersion = negotiatedVersion; - } - else + try { - var flag = Environment.GetEnvironmentVariable("VSTEST_DISABLE_PROTOCOL_3_VERSION_DOWNGRADE"); - var flagIsEnabled = flag != null && flag != "0"; - var dowgradeIsDisabled = flagIsEnabled; - if (dowgradeIsDisabled) + var version = this.dataSerializer.DeserializePayload(message); + // choose the highest version that we both support + var negotiatedVersion = Math.Min(version, highestSupportedVersion); + // BUT don't choose 3, because protocol version 3 has performance problems in 16.7.1-16.8. Those problems are caused + // by choosing payloadSerializer instead of payloadSerializer2 for protocol version 3. + // + // We cannot just update the code to choose the new serializer, because then that change would apply only to testhost. + // Testhost is is delivered by Microsoft.NET.Test.SDK nuget package, and can be used with an older vstest.console. + // An older vstest.console, that supports protocol version 3, would serialize its messages using payloadSerializer, + // but the fixed testhost would serialize it using payloadSerializer2, resulting in incompatible messages. + // + // Instead we must downgrade to protocol version 2 when 3 would be negotiated. Or higher when higher version + // would be negotiated. + if (negotiatedVersion != 3) { this.protocolVersion = negotiatedVersion; } else { - this.protocolVersion = 2; + var flag = Environment.GetEnvironmentVariable("VSTEST_DISABLE_PROTOCOL_3_VERSION_DOWNGRADE"); + var flagIsEnabled = flag != null && flag != "0"; + var dowgradeIsDisabled = flagIsEnabled; + if (dowgradeIsDisabled) + { + this.protocolVersion = negotiatedVersion; + } + else + { + this.protocolVersion = 2; + } } - } - // Send the negotiated protocol to request sender - this.channel.Send(this.dataSerializer.SerializePayload(MessageType.VersionCheck, this.protocolVersion)); + // Send the negotiated protocol to request sender + this.channel.Send(this.dataSerializer.SerializePayload(MessageType.VersionCheck, this.protocolVersion)); - // Can only do this after InitializeCommunication because TestHost cannot "Send Log" unless communications are initialized - if (!string.IsNullOrEmpty(EqtTrace.LogFile)) - { - this.SendLog(TestMessageLevel.Informational, string.Format(CrossPlatResources.TesthostDiagLogOutputFile, EqtTrace.LogFile)); + // Can only do this after InitializeCommunication because TestHost cannot "Send Log" unless communications are initialized + if (!string.IsNullOrEmpty(EqtTrace.LogFile)) + { + this.SendLog(TestMessageLevel.Informational, string.Format(CrossPlatResources.TesthostDiagLogOutputFile, EqtTrace.LogFile)); + } + else if (!string.IsNullOrEmpty(EqtTrace.ErrorOnInitialization)) + { + this.SendLog(TestMessageLevel.Warning, EqtTrace.ErrorOnInitialization); + } } - else if (!string.IsNullOrEmpty(EqtTrace.ErrorOnInitialization)) + catch (Exception ex) { - this.SendLog(TestMessageLevel.Warning, EqtTrace.ErrorOnInitialization); + this.messageProcessingUnrecoverableError = ex; + EqtTrace.Error("Failed processing message {0}, aborting test run.", message.MessageType); + EqtTrace.Error(ex); + goto case MessageType.AbortTestRun; } break; case MessageType.DiscoveryInitialize: { - EqtTrace.Info("Discovery Session Initialize."); - this.testHostManagerFactoryReady.Wait(); - var discoveryEventsHandler = new TestDiscoveryEventHandler(this); - var pathToAdditionalExtensions = this.dataSerializer.DeserializePayload>(message); - jobQueue.QueueJob( - () => - testHostManagerFactory.GetDiscoveryManager().Initialize(pathToAdditionalExtensions, discoveryEventsHandler), 0); + try + { + this.testHostManagerFactoryReady.Wait(); + var discoveryEventsHandler = new TestDiscoveryEventHandler(this); + var pathToAdditionalExtensions = this.dataSerializer.DeserializePayload>(message); + Action job = () => + { + EqtTrace.Info("TestRequestHandler.OnMessageReceived: Running job '{0}'.", message.MessageType); + testHostManagerFactory.GetDiscoveryManager().Initialize(pathToAdditionalExtensions, discoveryEventsHandler); + }; + jobQueue.QueueJob(job, 0); + } + catch (Exception ex) + { + this.messageProcessingUnrecoverableError = ex; + EqtTrace.Error("Failed processing message {0}, aborting test run.", message.MessageType); + EqtTrace.Error(ex); + goto case MessageType.AbortTestRun; + } break; } case MessageType.StartDiscovery: { - EqtTrace.Info("Discovery started."); - this.testHostManagerFactoryReady.Wait(); - var discoveryEventsHandler = new TestDiscoveryEventHandler(this); - var discoveryCriteria = this.dataSerializer.DeserializePayload(message); - jobQueue.QueueJob( - () => + try + { + this.testHostManagerFactoryReady.Wait(); + var discoveryEventsHandler = new TestDiscoveryEventHandler(this); + var discoveryCriteria = this.dataSerializer.DeserializePayload(message); + Action job = () => + { + EqtTrace.Info("TestRequestHandler.OnMessageReceived: Running job '{0}'.", message.MessageType); testHostManagerFactory.GetDiscoveryManager() - .DiscoverTests(discoveryCriteria, discoveryEventsHandler), 0); + .DiscoverTests(discoveryCriteria, discoveryEventsHandler); + }; + jobQueue.QueueJob(job, 0); + } + catch (Exception ex) + { + this.messageProcessingUnrecoverableError = ex; + EqtTrace.Error("Failed processing message {0}, aborting test run.", message.MessageType); + EqtTrace.Error(ex); + goto case MessageType.AbortTestRun; + } break; } case MessageType.ExecutionInitialize: { - EqtTrace.Info("Execution Session Initialize."); - this.testHostManagerFactoryReady.Wait(); - var testInitializeEventsHandler = new TestInitializeEventsHandler(this); - var pathToAdditionalExtensions = this.dataSerializer.DeserializePayload>(message); - jobQueue.QueueJob( - () => - testHostManagerFactory.GetExecutionManager().Initialize(pathToAdditionalExtensions, testInitializeEventsHandler), 0); + try + { + this.testHostManagerFactoryReady.Wait(); + var testInitializeEventsHandler = new TestInitializeEventsHandler(this); + var pathToAdditionalExtensions = this.dataSerializer.DeserializePayload>(message); + Action job = () => + { + EqtTrace.Info("TestRequestHandler.OnMessageReceived: Running job '{0}'.", message.MessageType); + testHostManagerFactory.GetExecutionManager().Initialize(pathToAdditionalExtensions, testInitializeEventsHandler); + }; + jobQueue.QueueJob(job, 0); + } + catch (Exception ex) + { + this.messageProcessingUnrecoverableError = ex; + EqtTrace.Error("Failed processing message {0}, aborting test run.", message.MessageType); + EqtTrace.Error(ex); + goto case MessageType.AbortTestRun; + } break; } case MessageType.StartTestExecutionWithSources: { - EqtTrace.Info("Execution started."); - var testRunEventsHandler = new TestRunEventsHandler(this); - this.testHostManagerFactoryReady.Wait(); - var testRunCriteriaWithSources = this.dataSerializer.DeserializePayload(message); - jobQueue.QueueJob( - () => + try + { + var testRunEventsHandler = new TestRunEventsHandler(this); + this.testHostManagerFactoryReady.Wait(); + var testRunCriteriaWithSources = this.dataSerializer.DeserializePayload(message); + Action job = () => + { + EqtTrace.Info("TestRequestHandler.OnMessageReceived: Running job '{0}'.", message.MessageType); testHostManagerFactory.GetExecutionManager() .StartTestRun( testRunCriteriaWithSources.AdapterSourceMap, @@ -362,22 +424,32 @@ public void OnMessageReceived(object sender, MessageReceivedEventArgs messageRec testRunCriteriaWithSources.RunSettings, testRunCriteriaWithSources.TestExecutionContext, this.GetTestCaseEventsHandler(testRunCriteriaWithSources.RunSettings), - testRunEventsHandler), - 0); - + testRunEventsHandler); + }; + jobQueue.QueueJob(job, 0); + } + catch (Exception ex) + { + this.messageProcessingUnrecoverableError = ex; + EqtTrace.Error("Failed processing message {0}, aborting test run.", message.MessageType); + EqtTrace.Error(ex); + goto case MessageType.AbortTestRun; + } break; } case MessageType.StartTestExecutionWithTests: { - EqtTrace.Info("Execution started."); - var testRunEventsHandler = new TestRunEventsHandler(this); - this.testHostManagerFactoryReady.Wait(); - var testRunCriteriaWithTests = - this.dataSerializer.DeserializePayload(message); - - jobQueue.QueueJob( - () => + try + { + var testRunEventsHandler = new TestRunEventsHandler(this); + this.testHostManagerFactoryReady.Wait(); + var testRunCriteriaWithTests = + this.dataSerializer.DeserializePayload(message); + + Action job = () => + { + EqtTrace.Info("TestRequestHandler.OnMessageReceived: Running job '{0}'.", message.MessageType); testHostManagerFactory.GetExecutionManager() .StartTestRun( testRunCriteriaWithTests.Tests, @@ -385,9 +457,17 @@ public void OnMessageReceived(object sender, MessageReceivedEventArgs messageRec testRunCriteriaWithTests.RunSettings, testRunCriteriaWithTests.TestExecutionContext, this.GetTestCaseEventsHandler(testRunCriteriaWithTests.RunSettings), - testRunEventsHandler), - 0); - + testRunEventsHandler); + }; + jobQueue.QueueJob(job, 0); + } + catch (Exception ex) + { + this.messageProcessingUnrecoverableError = ex; + EqtTrace.Error("Failed processing message {0}, aborting test run.", message.MessageType); + EqtTrace.Error(ex); + goto case MessageType.AbortTestRun; + } break; } @@ -406,9 +486,19 @@ public void OnMessageReceived(object sender, MessageReceivedEventArgs messageRec break; case MessageType.AbortTestRun: - jobQueue.Pause(); - this.testHostManagerFactoryReady.Wait(); - testHostManagerFactory.GetExecutionManager().Abort(new TestRunEventsHandler(this)); + try + { + jobQueue.Pause(); + this.testHostManagerFactoryReady.Wait(); + testHostManagerFactory.GetExecutionManager().Abort(new TestRunEventsHandler(this)); + } + catch (Exception ex) + { + EqtTrace.Error("Failed processing message {0}. Stopping communication.", message.MessageType); + EqtTrace.Error(ex); + sessionCompleted.Set(); + this.Close(); + } break; case MessageType.SessionEnd: @@ -452,4 +542,4 @@ private void SendData(string data) this.channel.Send(data); } } -} +} \ No newline at end of file diff --git a/src/vstest.console/Resources/Resources.Designer.cs b/src/vstest.console/Resources/Resources.Designer.cs index 840adf11b8..9d67a7ed2f 100644 --- a/src/vstest.console/Resources/Resources.Designer.cs +++ b/src/vstest.console/Resources/Resources.Designer.cs @@ -1574,6 +1574,15 @@ internal static string TestRunAborted { } } + /// + /// Looks up a localized string similar to Test Run Aborted with error: {0}.. + /// + internal static string TestRunAbortedWithError { + get { + return ResourceManager.GetString("TestRunAbortedWithError", resourceCulture); + } + } + /// /// Looks up a localized string similar to Test Run Canceled.. /// diff --git a/src/vstest.console/Resources/Resources.resx b/src/vstest.console/Resources/Resources.resx index 2c0bb837a1..fdb826947a 100644 --- a/src/vstest.console/Resources/Resources.resx +++ b/src/vstest.console/Resources/Resources.resx @@ -763,4 +763,7 @@ Environment variable '{0}' was already defined, but it's overridden by -Environment argument. + + Test Run Aborted with error {0}. + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.cs.xlf b/src/vstest.console/Resources/xlf/Resources.cs.xlf index abe004204e..cc7859270c 100644 --- a/src/vstest.console/Resources/xlf/Resources.cs.xlf +++ b/src/vstest.console/Resources/xlf/Resources.cs.xlf @@ -1273,6 +1273,11 @@ + + Test Run Aborted with error {0}. + Testovací běh se přerušil s chybou {0}. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.de.xlf b/src/vstest.console/Resources/xlf/Resources.de.xlf index 47a348e3c3..fdd4077ae8 100644 --- a/src/vstest.console/Resources/xlf/Resources.de.xlf +++ b/src/vstest.console/Resources/xlf/Resources.de.xlf @@ -1273,6 +1273,11 @@ + + Test Run Aborted with error {0}. + Der Testlauf wurde mit dem Fehler {0} abgebrochen. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.es.xlf b/src/vstest.console/Resources/xlf/Resources.es.xlf index 889783b712..463c895fb8 100644 --- a/src/vstest.console/Resources/xlf/Resources.es.xlf +++ b/src/vstest.console/Resources/xlf/Resources.es.xlf @@ -1276,6 +1276,11 @@ + + Test Run Aborted with error {0}. + La serie de pruebas se ha anulado con el error {0}. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.fr.xlf b/src/vstest.console/Resources/xlf/Resources.fr.xlf index 0dc7e87b80..bb62e8fc1e 100644 --- a/src/vstest.console/Resources/xlf/Resources.fr.xlf +++ b/src/vstest.console/Resources/xlf/Resources.fr.xlf @@ -1273,6 +1273,11 @@ + + Test Run Aborted with error {0}. + Désolé... Nous n’avons pas pu procéder à la série de tests, car nous avons rencontré l’erreur suivante : {0}. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.it.xlf b/src/vstest.console/Resources/xlf/Resources.it.xlf index b8a99b5bd1..96284e2abf 100644 --- a/src/vstest.console/Resources/xlf/Resources.it.xlf +++ b/src/vstest.console/Resources/xlf/Resources.it.xlf @@ -1273,6 +1273,11 @@ + + Test Run Aborted with error {0}. + Esecuzione dei test interrotta con errore {0}. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.ja.xlf b/src/vstest.console/Resources/xlf/Resources.ja.xlf index cf6c790453..37bc951f0e 100644 --- a/src/vstest.console/Resources/xlf/Resources.ja.xlf +++ b/src/vstest.console/Resources/xlf/Resources.ja.xlf @@ -1273,6 +1273,11 @@ + + Test Run Aborted with error {0}. + テストの実行がエラー {0} により中止されました。 + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.ko.xlf b/src/vstest.console/Resources/xlf/Resources.ko.xlf index 66780d628d..195a1c6aa5 100644 --- a/src/vstest.console/Resources/xlf/Resources.ko.xlf +++ b/src/vstest.console/Resources/xlf/Resources.ko.xlf @@ -1273,6 +1273,11 @@ + + Test Run Aborted with error {0}. + 테스트 실행이 {0} 오류로 인해 중단되었습니다. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.pl.xlf b/src/vstest.console/Resources/xlf/Resources.pl.xlf index dda8a5a334..82996ac5d4 100644 --- a/src/vstest.console/Resources/xlf/Resources.pl.xlf +++ b/src/vstest.console/Resources/xlf/Resources.pl.xlf @@ -1273,6 +1273,11 @@ + + Test Run Aborted with error {0}. + Przebieg testowy został przerwany z powodu błędu {0}. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.pt-BR.xlf b/src/vstest.console/Resources/xlf/Resources.pt-BR.xlf index e0b9ae491c..463632dacc 100644 --- a/src/vstest.console/Resources/xlf/Resources.pt-BR.xlf +++ b/src/vstest.console/Resources/xlf/Resources.pt-BR.xlf @@ -1273,6 +1273,11 @@ Altere o prefixo de nível de diagnóstico do agente de console, como mostrado a + + Test Run Aborted with error {0}. + Execução de Teste Abortada com Erro {0}. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.ru.xlf b/src/vstest.console/Resources/xlf/Resources.ru.xlf index 25010bc261..90dea0be6e 100644 --- a/src/vstest.console/Resources/xlf/Resources.ru.xlf +++ b/src/vstest.console/Resources/xlf/Resources.ru.xlf @@ -1273,6 +1273,11 @@ + + Test Run Aborted with error {0}. + Тестовый запуск прерван с ошибкой {0}. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.tr.xlf b/src/vstest.console/Resources/xlf/Resources.tr.xlf index 0606a4e8c5..cf4a5fe37c 100644 --- a/src/vstest.console/Resources/xlf/Resources.tr.xlf +++ b/src/vstest.console/Resources/xlf/Resources.tr.xlf @@ -1273,6 +1273,11 @@ Günlükler için izleme düzeyini aşağıda gösterildiği gibi değiştirin + + Test Run Aborted with error {0}. + Test Çalıştırması {0} hatasıyla durduruldu. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.xlf b/src/vstest.console/Resources/xlf/Resources.xlf index 7c9e5c3dfb..92408fc1b3 100644 --- a/src/vstest.console/Resources/xlf/Resources.xlf +++ b/src/vstest.console/Resources/xlf/Resources.xlf @@ -896,6 +896,11 @@ Format : TestRunParameters.Parameter(name="<name>", value="<value>") Environment variable '{0}' was already defined, but it's overridden by -Environment argument. + + Test Run Aborted with error {0}. + Test Run Aborted with error {0}. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.zh-Hans.xlf b/src/vstest.console/Resources/xlf/Resources.zh-Hans.xlf index 9789434bb9..95574729b7 100644 --- a/src/vstest.console/Resources/xlf/Resources.zh-Hans.xlf +++ b/src/vstest.console/Resources/xlf/Resources.zh-Hans.xlf @@ -1273,6 +1273,11 @@ + + Test Run Aborted with error {0}. + 测试运行已中止,出现错误 {0}。 + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.zh-Hant.xlf b/src/vstest.console/Resources/xlf/Resources.zh-Hant.xlf index 29f9bb49ba..f798fda1e2 100644 --- a/src/vstest.console/Resources/xlf/Resources.zh-Hant.xlf +++ b/src/vstest.console/Resources/xlf/Resources.zh-Hant.xlf @@ -1273,6 +1273,11 @@ + + Test Run Aborted with error {0}. + 測試執行已中止,錯誤 {0}。 + + \ No newline at end of file