diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyOperationManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyOperationManager.cs index c0933108cf..02f6d439f9 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyOperationManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyOperationManager.cs @@ -167,6 +167,7 @@ public virtual bool SetupChannel(IEnumerable sources, string runSettings if (!this.testHostLaunched || !this.RequestSender.WaitForRequestHandlerConnection(connTimeout * 1000, this.CancellationTokenSource.Token)) { + EqtTrace.Verbose($"Test host failed to start Test host launched:{testHostLaunched} test host exited: {testHostExited.IsSet}"); // Throw a test platform exception with the appropriate message if user requested cancellation this.CancellationTokenSource.Token.ThrowTestPlatformExceptionIfCancellationRequested(); @@ -209,7 +210,9 @@ public virtual void Close() // We want to give test host a chance to safely close. // The upper bound for wait should be 100ms. - this.testHostExited.Wait(100); + var timeout = 100; + EqtTrace.Verbose("ProxyOperationManager.Close: waiting for test host to exit for {0} ms", timeout); + this.testHostExited.Wait(timeout); } } catch (Exception ex) @@ -315,16 +318,24 @@ private void TestHostManagerHostLaunched(object sender, HostProviderEventArgs e) private void TestHostManagerHostExited(object sender, HostProviderEventArgs e) { + EqtTrace.Verbose("CrossPlatEngine.TestHostManagerHostExited: calling on client process exit callback."); this.testHostProcessStdError = e.Data; - this.RequestSender.OnClientProcessExit(this.testHostProcessStdError); + // this needs to be set before we call the OnClientProcess exit + // because the OnClientProcess will short-circuit WaitForRequestHandlerConnection in SetupChannel + // that then continues to throw an exception and checks if the testhost process exited + // if not it reports timeout, if we don't set this before OnClientProcessExit we will report timeout + // even though we exited the test host before even attempting the connect this.testHostExited.Set(); + this.RequestSender.OnClientProcessExit(this.testHostProcessStdError); } private void ThrowOnTestHostExited(bool testHostExited) - { + { if (testHostExited) { + // we might consider passing standard output here in case standard error is not available because some + // errors don't end up in the standard error output throw new TestPlatformException(string.Format(CrossPlatEngineResources.TestHostExitedWithError, this.testHostProcessStdError)); } } diff --git a/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DotnetTestHostManager.cs b/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DotnetTestHostManager.cs index 8d55c50e5a..f2a974ccec 100644 --- a/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DotnetTestHostManager.cs +++ b/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DotnetTestHostManager.cs @@ -376,8 +376,13 @@ private void OnHostExited(HostProviderEventArgs e) if (!this.hostExitedEventRaised) { this.hostExitedEventRaised = true; + EqtTrace.Verbose("DotnetTestHostManager.OnHostExited: invoking OnHostExited callback"); this.HostExited.SafeInvoke(this, e, "HostProviderEvents.OnHostExited"); } + else + { + EqtTrace.Verbose("DotnetTestHostManager.OnHostExited: exit event was already raised, skipping"); + } } private bool LaunchHost(TestProcessStartInfo testHostStartInfo, CancellationToken cancellationToken) diff --git a/src/Microsoft.TestPlatform.TestHostProvider/Hosting/TestHostManagerCallbacks.cs b/src/Microsoft.TestPlatform.TestHostProvider/Hosting/TestHostManagerCallbacks.cs index 33c09bd210..3edb5873de 100644 --- a/src/Microsoft.TestPlatform.TestHostProvider/Hosting/TestHostManagerCallbacks.cs +++ b/src/Microsoft.TestPlatform.TestHostProvider/Hosting/TestHostManagerCallbacks.cs @@ -28,6 +28,7 @@ public static void ExitCallBack( StringBuilder testHostProcessStdError, Action onHostExited) { + EqtTrace.Verbose("TestHostProvider.ExitCallBack: Host exited starting callback."); var exitCode = 0; var testHostProcessStdErrorStr = testHostProcessStdError.ToString(); @@ -38,8 +39,9 @@ public static void ExitCallBack( { procId = (process as Process).Id; } - catch (InvalidOperationException) + catch (InvalidOperationException ex) { + EqtTrace.Error("TestHostProvider.ExitCallBack: could not get proccess id from process, error: {0}.", ex); } if (exitCode != 0)