tests/run-tests.py
changeset 21305 d7a7825ff2cf
parent 21304 e626a67da4ba
child 21306 cbf5475827da
--- a/tests/run-tests.py	Sat Apr 19 13:29:26 2014 -0700
+++ b/tests/run-tests.py	Sat Apr 19 13:50:25 2014 -0700
@@ -563,10 +563,27 @@
         env = self._getenv()
         createhgrc(env['HGRCPATH'], self._options)
 
+        result = TestResult()
+        starttime = time.time()
+
+        def updateduration():
+            result.duration = time.time() - starttime
+
         try:
-            return self._run(self._replacements, env)
-        finally:
-            killdaemons(env['DAEMON_PIDS'])
+            ret, out = self._run(self._replacements, env)
+            updateduration()
+            result.ret = ret
+            result.out = out
+        except KeyboardInterrupt:
+            updateduration()
+            result.interrupted = True
+        except Exception, e:
+            updateduration()
+            result.exception = e
+
+        killdaemons(env['DAEMON_PIDS'])
+
+        return result
 
     def _run(self, replacements, env):
         raise NotImplemented('Subclasses must implement Test.run()')
@@ -625,6 +642,16 @@
 
         return env
 
+class TestResult(object):
+    """Holds the result of a test execution."""
+
+    def __init__(self):
+        self.ret = None
+        self.out = None
+        self.duration = None
+        self.interrupted = False
+        self.exception = None
+
 def pytest(test, wd, options, replacements, env):
     py3kswitch = options.py3k_warnings and ' -3' or ''
     cmd = '%s%s "%s"' % (PYTHON, py3kswitch, test)
@@ -1025,16 +1052,19 @@
         os.remove(err)       # Remove any previous output files
 
     t = runner(testpath, options, count)
+    res = t.run()
 
-    starttime = time.time()
-    try:
-        ret, out = t.run()
-    except KeyboardInterrupt:
-        endtime = time.time()
-        log('INTERRUPTED: %s (after %d seconds)' % (test, endtime - starttime))
-        raise
-    endtime = time.time()
-    times.append((test, endtime - starttime))
+    if res.interrupted:
+        log('INTERRUPTED: %s (after %d seconds)' % (test, res.duration))
+        raise KeyboardInterrupt()
+
+    if res.exception:
+        return fail('Exception during execution: %s' % res.exception, 255)
+
+    ret = res.ret
+    out = res.out
+
+    times.append((test, res.duration))
     vlog("# Ret was:", ret)
 
     skipped = (ret == SKIPPED_STATUS)