avocado.job: Handle setup errors

If we have an error at test setup stage, avocado will
completely crash. This happens because the setup()
method is not properly wrapped inside the avocado
execution loop.

So, trust exception handling to the job level,
putting all test executions under a single try/except
block with appropriate status and test attribute handling.
Signed-off-by: NLucas Meneghel Rodrigues <lmr@redhat.com>
上级 774b6f92
......@@ -11,6 +11,14 @@ class TestBaseException(Exception):
status = "NEVER_RAISE_THIS"
class TestSetupFail(TestBaseException):
"""
Indicates an error during a setup procedure.
"""
status = "FAIL"
class TestError(TestBaseException):
"""
......
......@@ -4,10 +4,13 @@ Class that describes a sequence of automated operations.
import imp
import logging
import os
import sys
import time
import traceback
from avocado.core import data_dir
from avocado.core import output
from avocado.core import exceptions
from avocado import test
from avocado import sysinfo
from avocado import result
......@@ -84,14 +87,36 @@ class Job(object):
:params test_instance: avocado.test.Test derived class instance.
"""
sysinfo_logger = sysinfo.SysInfo(basedir=test_instance.sysinfodir)
test_instance.start_logging()
test_instance.setup()
sysinfo_logger.start_job_hook()
test_instance.run()
test_instance.cleanup()
test_instance.report()
test_instance.stop_logging()
start_time = time.time()
try:
sysinfo_logger = sysinfo.SysInfo(basedir=test_instance.sysinfodir)
test_instance.start_logging()
sysinfo_logger.start_job_hook()
try:
test_instance.setup()
except Exception, details:
raise exceptions.TestSetupFail(details)
test_instance.action()
test_instance.cleanup()
test_instance.status = 'PASS'
except exceptions.TestBaseException, detail:
test_instance.status = detail.status
test_instance.fail_reason = detail
except Exception, detail:
exc_type, exc_value, exc_traceback = sys.exc_info()
tb_info = traceback.format_exception(exc_type, exc_value,
exc_traceback.tb_next)
tb_info = "".join(tb_info)
for e_line in tb_info.splitlines():
test_instance.log.error(e_line)
test_instance.status = 'FAIL'
test_instance.fail_reason = detail
finally:
end_time = time.time()
test_instance.time_elapsed = end_time - start_time
test_instance.report()
test_instance.stop_logging()
return test_instance
def run_test(self, url):
......
......@@ -70,6 +70,7 @@ class TestResult(object):
'Called once for a test to check status and report.'
self.start_test(test)
status_map = {'PASS': self.add_pass,
'ERROR': self.add_fail,
'FAIL': self.add_fail,
'TEST_NA': self.add_skip,
'WARN': self.add_warn}
......
......@@ -120,35 +120,6 @@ class Test(object):
raise NotImplementedError('Test subclasses must implement an action '
'method')
def run(self):
"""
Main test execution entry point.
It'll run the action payload, taking into consideration profiling
requirements. After the test is done, it reports time and status.
"""
start_time = time.time()
try:
self.action()
self.status = 'PASS'
except exceptions.TestBaseException, detail:
self.status = detail.status
self.fail_reason = detail
except Exception, detail:
exc_type, exc_value, exc_traceback = sys.exc_info()
tb_info = traceback.format_exception(exc_type, exc_value,
exc_traceback.tb_next)
tb_info = "".join(tb_info)
for e_line in tb_info.splitlines():
self.log.error(e_line)
self.status = 'FAIL'
self.fail_reason = detail
finally:
end_time = time.time()
self.time_elapsed = end_time - start_time
return self.status == 'PASS'
def cleanup(self):
"""
Cleanup stage after the action is done.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册