-
Notifications
You must be signed in to change notification settings - Fork 325
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Porting fix for Design mode clients hang for errors #1451
Changes from 2 commits
28ae70d
92a00c4
7dc6f98
a214228
da0bfcf
fb7d069
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,16 +11,22 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.Parallel | |
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities; | ||
using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces; | ||
using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel; | ||
using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.DataCollection; | ||
using Microsoft.VisualStudio.TestPlatform.ObjectModel; | ||
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; | ||
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine; | ||
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; | ||
|
||
/// <summary> | ||
/// ParallelProxyExecutionManager that manages parallel execution | ||
/// </summary> | ||
internal class ParallelProxyExecutionManager : ParallelOperationManager<IProxyExecutionManager, ITestRunEventsHandler>, IParallelProxyExecutionManager | ||
{ | ||
private IDataSerializer dataSerializer; | ||
|
||
#region TestRunSpecificData | ||
|
||
// This variable id to differentiate between implicit (abort requested by testPlatform) and explicit (test host aborted) abort. | ||
|
@@ -60,15 +66,20 @@ internal class ParallelProxyExecutionManager : ParallelOperationManager<IProxyEx | |
#endregion | ||
|
||
public ParallelProxyExecutionManager(IRequestData requestData, Func<IProxyExecutionManager> actualProxyManagerCreator, int parallelLevel) | ||
: base(actualProxyManagerCreator, parallelLevel, true) | ||
: this(requestData, actualProxyManagerCreator, JsonDataSerializer.Instance, parallelLevel, true) | ||
{ | ||
this.requestData = requestData; | ||
} | ||
|
||
public ParallelProxyExecutionManager(IRequestData requestData, Func<IProxyExecutionManager> actualProxyManagerCreator, int parallelLevel, bool sharedHosts) | ||
: this(requestData, actualProxyManagerCreator, JsonDataSerializer.Instance, parallelLevel, sharedHosts) | ||
{ | ||
} | ||
|
||
internal ParallelProxyExecutionManager(IRequestData requestData, Func<IProxyExecutionManager> actualProxyManagerCreator, IDataSerializer dataSerializer, int parallelLevel, bool sharedHosts) | ||
: base(actualProxyManagerCreator, parallelLevel, sharedHosts) | ||
{ | ||
this.requestData = requestData; | ||
this.dataSerializer = dataSerializer; | ||
} | ||
|
||
#region IProxyExecutionManager | ||
|
@@ -325,18 +336,23 @@ private void StartTestRunOnConcurrentManager(IProxyExecutionManager proxyExecuti | |
// Just in case, the actual execution couldn't start for an instance. Ensure that | ||
// we call execution complete since we have already fetched a source. Otherwise | ||
// execution will not terminate | ||
if (EqtTrace.IsWarningEnabled) | ||
if (EqtTrace.IsErrorEnabled) | ||
{ | ||
EqtTrace.Warning("ParallelProxyExecutionManager: Failed to trigger execution. Exception: " + t.Exception); | ||
EqtTrace.Error("ParallelProxyExecutionManager: Failed to trigger execution. Exception: " + t.Exception); | ||
} | ||
|
||
var handler = this.GetHandlerForGivenManager(proxyExecutionManager); | ||
var testMessagePayload = new TestMessagePayload { MessageLevel = TestMessageLevel.Error, Message = t.Exception.ToString() }; | ||
handler.HandleRawMessage(this.dataSerializer.SerializePayload(MessageType.TestMessage, testMessagePayload)); | ||
handler.HandleLogMessage(TestMessageLevel.Error, t.Exception.ToString()); | ||
|
||
// Send a run complete to caller. Similar logic is also used in ProxyExecutionManager.StartTestRun | ||
// Differences: | ||
// Aborted is sent to allow the current execution manager replaced with another instance | ||
// Ensure that the test run aggregator in parallel run events handler doesn't add these statistics | ||
// (since the test run didn't even start) | ||
var completeArgs = new TestRunCompleteEventArgs(null, false, true, null, new Collection<AttachmentSet>(), TimeSpan.Zero); | ||
this.GetHandlerForGivenManager(proxyExecutionManager).HandleTestRunComplete(completeArgs, null, null, null); | ||
handler.HandleTestRunComplete(completeArgs, null, null, null); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment as in parallel discovery |
||
}, | ||
TaskContinuationOptions.OnlyOnFaulted); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -152,13 +152,19 @@ public virtual int StartTestRun(TestRunCriteria testRunCriteria, ITestRunEventsH | |
catch (Exception exception) | ||
{ | ||
EqtTrace.Error("ProxyExecutionManager.StartTestRun: Failed to start test run: {0}", exception); | ||
|
||
// Log error message to design mode and CLI. | ||
var testMessagePayload = new TestMessagePayload { MessageLevel = TestMessageLevel.Error, Message = exception.ToString() }; | ||
this.HandleRawMessage(this.dataSerializer.SerializePayload(MessageType.TestMessage, testMessagePayload)); | ||
this.LogMessage(TestMessageLevel.Error, exception.ToString()); | ||
|
||
// Send a run complete to caller. Similar logic is also used in ParallelProxyExecutionManager.StartTestRunOnConcurrentManager | ||
// Aborted is `true`: in case of parallel run (or non shared host), an aborted message ensures another execution manager | ||
// created to replace the current one. This will help if the current execution manager is aborted due to irreparable error | ||
// and the test host is lost as well. | ||
var completeArgs = new TestRunCompleteEventArgs(null, false, true, exception, new Collection<AttachmentSet>(), TimeSpan.Zero); | ||
var completeArgs = new TestRunCompleteEventArgs(null, false, true, null, new Collection<AttachmentSet>(), TimeSpan.Zero); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We are not sending exception in TestRunCompleteEvent here to avoid duplicacy. (as we are sending error as separate message.) |
||
var testRunCompletePayload = new TestRunCompletePayload { TestRunCompleteArgs = completeArgs }; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this change is IDE behavior? What if IDE was displaying some warning if it receives Exception in TestRunComplete. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We are sending TestMessage of error which IDE will show as error. After that we don't need to send exception in TestRunComplete. This change is done for IDE only as IDE was showing error twice in this case, once because of TestMessage of error. and second because of exception in TestRunComplete. |
||
this.HandleRawMessage(this.dataSerializer.SerializePayload(MessageType.ExecutionComplete, testRunCompletePayload)); | ||
this.HandleTestRunComplete(completeArgs, null, null, null); | ||
} | ||
|
||
|
@@ -262,4 +268,4 @@ private void InitializeExtensions(IEnumerable<string> sources) | |
} | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the handler's "HandleDiscoveryComplete" calls HandRawMessage for discovery complete?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. we don't need to send handleRawMessage of complete in case of parallel as handleRawMessage is sent itself by parallel discovery manager when all managers completes discovery.