Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLluis Sanchez <slluis.devel@gmail.com>2015-05-04 16:57:48 +0300
committerLluis Sanchez <slluis.devel@gmail.com>2015-05-04 16:57:48 +0300
commit97f3c43266a4abe2dff0a31b1afb976de897d099 (patch)
tree792d6eb40f73df1c4766f7d3ad7226ee883ec362
parentdd5da1f263f9860f1332c3ac5128b904c82b68ae (diff)
parent29e93b8586b50d688b23637c2c6e24883983af72 (diff)
Merge pull request #899 from mono/fix-29457monodevelop-5.9.0.464
[NUnit] Properly report unhandled exceptions
-rw-r--r--main/src/addins/NUnit/Gui/TestResultsPad.cs15
-rw-r--r--main/src/addins/NUnit/Services/ExternalTestRunner.cs59
-rw-r--r--main/src/addins/NUnit/Services/NUnitAssemblyTestSuite.cs25
3 files changed, 88 insertions, 11 deletions
diff --git a/main/src/addins/NUnit/Gui/TestResultsPad.cs b/main/src/addins/NUnit/Gui/TestResultsPad.cs
index e7ebaf40f4..638ed50d5f 100644
--- a/main/src/addins/NUnit/Gui/TestResultsPad.cs
+++ b/main/src/addins/NUnit/Gui/TestResultsPad.cs
@@ -44,6 +44,7 @@ using System.Text.RegularExpressions;
using MonoDevelop.Components;
using MonoDevelop.Ide.Commands;
using MonoDevelop.Ide.Fonts;
+using MonoDevelop.NUnit.External;
namespace MonoDevelop.NUnit
{
@@ -369,13 +370,19 @@ namespace MonoDevelop.NUnit
public void AddErrorMessage ()
{
- string msg = GettextCatalog.GetString ("Internal error");
- if (errorMessage != null)
- msg += ": " + Escape (errorMessage);
+ string msg;
+ if (error is RemoteUnhandledException)
+ msg = Escape (errorMessage);
+ else {
+ msg = GettextCatalog.GetString ("Internal error");
+ if (errorMessage != null)
+ msg += ": " + Escape (errorMessage);
+ }
var stock = ImageService.GetIcon (Ide.Gui.Stock.Error, Gtk.IconSize.Menu);
TreeIter testRow = failuresStore.AppendValues (stock, msg, null, null, 0);
- failuresStore.AppendValues (testRow, null, Escape (error.GetType ().Name + ": " + error.Message), null);
+ string name = error is RemoteUnhandledException ? ((RemoteUnhandledException)error).RemoteExceptionName : error.GetType ().Name;
+ failuresStore.AppendValues (testRow, null, Escape (name + ": " + error.Message), null);
TreeIter row = failuresStore.AppendValues (testRow, null, GettextCatalog.GetString ("Stack Trace"), null, null, 0);
AddStackTrace (row, error.StackTrace, null);
}
diff --git a/main/src/addins/NUnit/Services/ExternalTestRunner.cs b/main/src/addins/NUnit/Services/ExternalTestRunner.cs
index 480c845aee..ea9f51d972 100644
--- a/main/src/addins/NUnit/Services/ExternalTestRunner.cs
+++ b/main/src/addins/NUnit/Services/ExternalTestRunner.cs
@@ -75,13 +75,24 @@ namespace MonoDevelop.NUnit.External
Assembly.LoadFrom (asm);
}
- public UnitTestResult Run (IRemoteEventListener listener, ITestFilter filter, string path, string suiteName, List<string> supportAssemblies, string testRunnerType, string testRunnerAssembly)
+ public UnitTestResult Run (IRemoteEventListener listener, ITestFilter filter, string path, string suiteName, List<string> supportAssemblies, string testRunnerType, string testRunnerAssembly, string crashLogFile)
{
NUnitTestRunner runner = GetRunner (path);
EventListenerWrapper listenerWrapper = listener != null ? new EventListenerWrapper (listener) : null;
- TestResult res = runner.Run (listenerWrapper, filter, path, suiteName, supportAssemblies, testRunnerType, testRunnerAssembly);
- return listenerWrapper.GetLocalTestResult (res);
+ UnhandledExceptionEventHandler exceptionHandler = (object sender, UnhandledExceptionEventArgs e) => {
+
+ var ex = new RemoteUnhandledException ((Exception) e.ExceptionObject);
+ File.WriteAllText (crashLogFile, ex.Serialize ());
+ };
+
+ AppDomain.CurrentDomain.UnhandledException += exceptionHandler;
+ try {
+ TestResult res = runner.Run (listenerWrapper, filter, path, suiteName, supportAssemblies, testRunnerType, testRunnerAssembly);
+ return listenerWrapper.GetLocalTestResult (res);
+ } finally {
+ AppDomain.CurrentDomain.UnhandledException -= exceptionHandler;
+ }
}
public NunitTestInfo GetTestInfo (string path, List<string> supportAssemblies)
@@ -366,7 +377,47 @@ namespace MonoDevelop.NUnit.External
{
return null;
}
-
}
+
+ /// <summary>
+ /// Exception class that can be serialized
+ /// </summary>
+ class RemoteUnhandledException: Exception
+ {
+ string stack;
+
+ public RemoteUnhandledException (string exceptionName, string message, string stack): base (message)
+ {
+ RemoteExceptionName = exceptionName;
+ this.stack = stack;
+ }
+
+ public RemoteUnhandledException (Exception ex): base (ex.Message)
+ {
+ RemoteExceptionName = ex.GetType().Name;
+ this.stack = ex.StackTrace;
+ }
+
+ public string Serialize ()
+ {
+ return RemoteExceptionName + "\n" + Message.Replace ('\r',' ').Replace ('\n',' ') + "\n" + StackTrace;
+ }
+
+ public static RemoteUnhandledException Parse (string s)
+ {
+ int i = s.IndexOf ('\n');
+ string name = s.Substring (0, i++);
+ int i2 = s.IndexOf ('\n', i);
+ return new RemoteUnhandledException (name, s.Substring (i, i2 - i), s.Substring (i2 + 1));
+ }
+
+ public string RemoteExceptionName { get; set; }
+
+ public override string StackTrace {
+ get {
+ return stack;
+ }
+ }
+ }
}
diff --git a/main/src/addins/NUnit/Services/NUnitAssemblyTestSuite.cs b/main/src/addins/NUnit/Services/NUnitAssemblyTestSuite.cs
index 3e55a824be..3a50455d73 100644
--- a/main/src/addins/NUnit/Services/NUnitAssemblyTestSuite.cs
+++ b/main/src/addins/NUnit/Services/NUnitAssemblyTestSuite.cs
@@ -414,6 +414,7 @@ namespace MonoDevelop.NUnit
testContext.Monitor.CancelRequested += new TestHandler (rd.Cancel);
UnitTestResult result;
+ var crashLogFile = Path.GetTempFileName ();
try {
if (string.IsNullOrEmpty (AssemblyPath)) {
@@ -425,11 +426,17 @@ namespace MonoDevelop.NUnit
string testRunnerAssembly, testRunnerType;
GetCustomTestRunner (out testRunnerAssembly, out testRunnerType);
- result = runner.Run (localMonitor, filter, AssemblyPath, "", new List<string> (SupportAssemblies), testRunnerType, testRunnerAssembly);
+ result = runner.Run (localMonitor, filter, AssemblyPath, "", new List<string> (SupportAssemblies), testRunnerType, testRunnerAssembly, crashLogFile);
if (testName != null)
result = localMonitor.SingleTestResult;
+
+ ReportCrash (testContext, crashLogFile);
+
} catch (Exception ex) {
- if (!localMonitor.Canceled) {
+ if (ReportCrash (testContext, crashLogFile)) {
+ result = UnitTestResult.CreateFailure (GettextCatalog.GetString ("Undhandled exception"), null);
+ }
+ else if (!localMonitor.Canceled) {
LoggingService.LogError (ex.ToString ());
if (localMonitor.RunningTest != null) {
RuntimeErrorCleanup (testContext, localMonitor.RunningTest, ex);
@@ -442,6 +449,7 @@ namespace MonoDevelop.NUnit
result = UnitTestResult.CreateFailure (GettextCatalog.GetString ("Canceled"), null);
}
} finally {
+ File.Delete (crashLogFile);
testContext.Monitor.CancelRequested -= new TestHandler (rd.Cancel);
runner.Dispose ();
System.Runtime.Remoting.RemotingServices.Disconnect (localMonitor);
@@ -449,7 +457,18 @@ namespace MonoDevelop.NUnit
return result;
}
-
+
+ bool ReportCrash (TestContext testContext, string crashLogFile)
+ {
+ var crash = File.ReadAllText (crashLogFile);
+ if (crash.Length == 0)
+ return false;
+
+ var ex = RemoteUnhandledException.Parse (crash);
+ testContext.Monitor.ReportRuntimeError (GettextCatalog.GetString ("Unhandled exception"), ex);
+ return true;
+ }
+
void RuntimeErrorCleanup (TestContext testContext, UnitTest t, Exception ex)
{
UnitTestResult result = UnitTestResult.CreateFailure (ex);