From 2999963ff8bdfb48d55b5c74b204fef99e4e66ec Mon Sep 17 00:00:00 2001 From: Matt Riedemann Date: Thu, 14 Feb 2019 14:32:20 -0500 Subject: [PATCH] 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 --- .../conditional-attr-a8564ec5a70ec840.yaml | 6 ++++++ tempest/lib/decorators.py | 7 +++++++ tempest/tests/lib/test_decorators.py | 21 ++++++++++++++++--- 3 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 releasenotes/notes/conditional-attr-a8564ec5a70ec840.yaml diff --git a/releasenotes/notes/conditional-attr-a8564ec5a70ec840.yaml b/releasenotes/notes/conditional-attr-a8564ec5a70ec840.yaml new file mode 100644 index 0000000000..c707f14790 --- /dev/null +++ b/releasenotes/notes/conditional-attr-a8564ec5a70ec840.yaml @@ -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. diff --git a/tempest/lib/decorators.py b/tempest/lib/decorators.py index b399aa0519..62a5d677a2 100644 --- a/tempest/lib/decorators.py +++ b/tempest/lib/decorators.py @@ -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): diff --git a/tempest/tests/lib/test_decorators.py b/tempest/tests/lib/test_decorators.py index 0b1a5991d5..3e6160eac3 100644 --- a/tempest/tests/lib/test_decorators.py +++ b/tempest/tests/lib/test_decorators.py @@ -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,