run-tests: capture execution results in a TestResult class

Some implementation details of test execution still live outside of
Test. These include determining what a result means and cleaning up
after the test.

To move to the world where more of this logic can live inside Test or a
derived object, the logic for test execution needs to be refactored.
Specifically, exception trapping and opportunities for result processing
need to be moved into Test.

This patch starts the process by establishing a TestResult class for
holding the results of a test execution. In order to actually use this
class, exception trapping and execution time recording needed to be
moved into Test.run().
This commit is contained in:
Gregory Szorc 2014-04-19 13:50:25 -07:00
parent 03c657bc26
commit ce51eb2ab0

View File

@ -563,10 +563,27 @@ class Test(object):
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 @@ class Test(object):
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 @@ def runone(options, test, count):
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)