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 @@
+
+
+ Testovací běh se přerušil s chybou {0}.
+
+