diff --git a/tempest_lib/decorators.py b/tempest_lib/decorators.py index 10eda3d..e78e624 100644 --- a/tempest_lib/decorators.py +++ b/tempest_lib/decorators.py @@ -59,3 +59,22 @@ def idempotent_id(id): f.__doc__ = 'Test idempotent id: %s' % id return f return decorator + + +class skip_unless_attr(object): + """Decorator to skip tests if a specified attr does not exists or False""" + def __init__(self, attr, msg=None): + self.attr = attr + self.message = msg or ("Test case attribute %s not found " + "or False") % attr + + def __call__(self, func): + def _skipper(*args, **kw): + """Wrapped skipper function.""" + testobj = args[0] + if not getattr(testobj, self.attr, False): + raise testtools.TestCase.skipException(self.message) + func(*args, **kw) + _skipper.__name__ = func.__name__ + _skipper.__doc__ = func.__doc__ + return _skipper diff --git a/tempest_lib/tests/test_decorators.py b/tempest_lib/tests/test_decorators.py index 33fb923..252e009 100644 --- a/tempest_lib/tests/test_decorators.py +++ b/tempest_lib/tests/test_decorators.py @@ -95,3 +95,32 @@ class TestIdempotentIdDecorator(base.TestCase): def test_idempotent_id_not_valid_uuid(self): _id = '42' self.assertRaises(ValueError, self._test_helper, _id) + + +class TestSkipUnlessAttrDecorator(base.TestCase): + def _test_skip_unless_attr(self, attr, expected_to_skip=True): + class TestFoo(test.BaseTestCase): + expected_attr = not expected_to_skip + + @decorators.skip_unless_attr(attr) + def test_foo(self): + pass + + t = TestFoo('test_foo') + if expected_to_skip: + self.assertRaises(testtools.TestCase.skipException, + t.test_foo()) + else: + try: + t.test_foo() + except Exception: + raise testtools.TestCase.failureException() + + def test_skip_attr_does_not_exist(self): + self._test_skip_unless_attr('unexpected_attr') + + def test_skip_attr_false(self): + self._test_skip_unless_attr('expected_attr') + + def test_no_skip_for_attr_exist_and_true(self): + self._test_skip_unless_attr('expected_attr', expected_to_skip=False)