Allow decorators.attr to be conditional

There are cases where we want to conditionally apply an
attribute to a test function, for example, if SSH validation
is enabled then a test may run much slower than if it is not.

This adds a 'condition' kwarg to the attr() decorator which
behaves similarly to the 'condition' kwarg on the skip_because()
decorator.

Change-Id: I83233854a217b6961e7614d7d9df1b4fc8d5a640
This commit is contained in:
Matt Riedemann 2019-02-14 14:32:20 -05:00
parent b4763ef57e
commit 2999963ff8
3 changed files with 31 additions and 3 deletions

View File

@ -0,0 +1,6 @@
---
features:
- |
The ``tempest.lib.decorators.attr`` decorator now supports a ``condition``
kwarg which can be used to conditionally apply the attr to the test
function if the condition evaluates to True.

View File

@ -136,9 +136,16 @@ def attr(**kwargs):
This decorator applies the testtools.testcase.attr if it is in the list of
attributes to testtools we want to apply.
:param condition: Optional condition which if true will apply the attr. If
a condition is specified which is false the attr will not be applied to
the test function. If not specified, the attr is always applied.
"""
def decorator(f):
# Check to see if the attr should be conditional applied.
if 'condition' in kwargs and not kwargs.get('condition'):
return f
if 'type' in kwargs and isinstance(kwargs['type'], str):
f = testtools.testcase.attr(kwargs['type'])(f)
elif 'type' in kwargs and isinstance(kwargs['type'], list):

View File

@ -32,9 +32,17 @@ class TestAttrDecorator(base.TestCase):
# By our decorators.attr decorator the attribute __testtools_attrs
# will be set only for 'type' argument, so we test it first.
if 'type' in decorator_args:
# this is what testtools sets
self.assertEqual(getattr(foo, '__testtools_attrs'),
set(expected_attrs))
if 'condition' in decorator_args:
if decorator_args['condition']:
# The expected attrs should be in the function.
self.assertEqual(set(expected_attrs),
getattr(foo, '__testtools_attrs'))
else:
# The expected attrs should not be in the function.
self.assertNotIn('__testtools_attrs', foo)
else:
self.assertEqual(set(expected_attrs),
getattr(foo, '__testtools_attrs'))
def test_attr_without_type(self):
self._test_attr_helper(expected_attrs='baz', bar='baz')
@ -50,6 +58,13 @@ class TestAttrDecorator(base.TestCase):
def test_attr_decorator_with_duplicated_type(self):
self._test_attr_helper(expected_attrs=['foo'], type=['foo', 'foo'])
def test_attr_decorator_condition_false(self):
self._test_attr_helper(None, type='slow', condition=False)
def test_attr_decorator_condition_true(self):
self._test_attr_helper(expected_attrs=['slow'], type='slow',
condition=True)
class TestSkipBecauseDecorator(base.TestCase):
def _test_skip_because_helper(self, expected_to_skip=True,