提交 f672733e 编写于 作者: L Lukáš Doktor

avocado.core.exceptions: Update fail_on_error and rename to fail_on

This patch renames the fail_on_error decorator to fail_on and adds
support to supply list of exceptions. This way the decorator can be used
not only to make tests fail on generic exceptions but also to specify
parts of code with expected failures of given type.
Signed-off-by: NLukáš Doktor <ldoktor@redhat.com>
上级 02e8a4ce
......@@ -13,10 +13,10 @@
# Author: Lucas Meneghel Rodrigues <lmr@redhat.com>
__all__ = ['main', 'Test', 'VERSION', 'fail_on_error']
__all__ = ['main', 'Test', 'VERSION', 'fail_on']
from avocado.core.job import main
from avocado.core.test import Test
from avocado.core.version import VERSION
from avocado.core.exceptions import fail_on_error
from avocado.core.exceptions import fail_on
......@@ -15,29 +15,45 @@
"""
Exception classes, useful for tests, and other parts of the framework code.
"""
def fail_on_error(fn):
"""
Apply to any test you want to FAIL upon any exception raised.
Normally only TestFail called explicitly will mark an avocado test with the
FAIL state, but this decorator is provided as a convenience for people
that need a more relaxed behavior.
:param fn: Function that will be decorated
"""
def new_fn(*args, **kwargs):
try:
return fn(*args, **kwargs)
except TestBaseException:
raise
except Exception, e:
raise TestFail(str(e))
new_fn.__name__ = fn.__name__
new_fn.__doc__ = fn.__doc__
new_fn.__dict__.update(fn.__dict__)
return new_fn
from functools import wraps
import types
def fail_on(exceptions=None):
"""
Fail the test when decorated function produces exception of the specified
type.
(For example, our method may raise IndexError on tested software failure.
We can either try/catch it or use this decorator instead)
:param exceptions: Tuple or single exception to be assumed as
test fail [Exception]
:note: self.error and self.skip behavior remains intact
:note: To allow simple usage param "exceptions" must not be callable
"""
func = False
if exceptions is None:
exceptions = Exception
elif isinstance(exceptions, types.FunctionType): # @fail_on without ()
func = exceptions
exceptions = Exception
def decorate(func):
""" Decorator """
@wraps(func)
def wrap(*args, **kwargs):
""" Function wrapper """
try:
return func(*args, **kwargs)
except TestBaseException:
raise
except exceptions, details:
raise TestFail(str(details))
return wrap
if func:
return decorate(func)
return decorate
class JobBaseException(Exception):
......
......@@ -3,13 +3,14 @@
import avocado
class FailOnError(avocado.Test):
class FailOnException(avocado.Test):
"""
Test illustrating the behavior of the fail_on_error decorator.
Test illustrating the behavior of the fail_on decorator.
"""
@avocado.fail_on_error
# @avocado.fail_on(ValueError) also possible
@avocado.fail_on
def test(self):
"""
This should end with FAIL.
......
......@@ -126,10 +126,10 @@ class RunnerOperationTest(unittest.TestCase):
result))
self.assertIn('"status": "ERROR"', result.stdout)
def test_fail_on_error(self):
def test_fail_on_exception(self):
os.chdir(basedir)
cmd_line = ("./scripts/avocado run --sysinfo=off --job-results-dir %s "
"--json - fail_on_error" % self.tmpdir)
"--json - fail_on_exception" % self.tmpdir)
result = process.run(cmd_line, ignore_status=True)
expected_rc = 1
self.assertEqual(result.exit_status, expected_rc,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册