diff --git a/core/_tests/helpers/test_setup_teardown.py b/core/_tests/helpers/test_setup_teardown.py new file mode 100644 index 000000000..cb5d03801 --- /dev/null +++ b/core/_tests/helpers/test_setup_teardown.py @@ -0,0 +1,240 @@ +from __future__ import absolute_import +from __future__ import print_function + +import unittest + +from mock import call +from mock import patch + +from core.helpers import setup_teardown + + +# Get helpers names (python will try to mangle it inside classes) +get_arg_names = setup_teardown.__get_arg_names +getcallargs = setup_teardown.__getcallargs +call_in_context = setup_teardown.__call_in_context + + +class TestWrappers(unittest.TestCase): + def test_get_arg_names(self): + def func_no_args(): + pass + + def func_arg(single): + pass + + def func_args(first, last): + pass + + self.assertEqual( + get_arg_names(func_no_args), + [] + ) + + self.assertEqual( + get_arg_names(func_arg), + ['single'] + ) + + self.assertEqual( + get_arg_names(func_args), + ['first', 'last'] + ) + + def test_getcallargs(self): + def func_no_def(arg1, arg2): + pass + + def func_def(arg1, arg2='arg2'): + pass + + self.assertEqual( + dict(getcallargs(func_no_def, *['arg1', 'arg2'], **{})), + {'arg1': 'arg1', 'arg2': 'arg2'} + ) + + self.assertEqual( + dict(getcallargs(func_no_def, *['arg1'], **{'arg2': 'arg2'})), + {'arg1': 'arg1', 'arg2': 'arg2'} + ) + + self.assertEqual( + dict(getcallargs( + func_no_def, *[], **{'arg1': 'arg1', 'arg2': 'arg2'})), + {'arg1': 'arg1', 'arg2': 'arg2'} + ) + + self.assertEqual( + dict(getcallargs(func_def, *['arg1'], **{})), + {'arg1': 'arg1', 'arg2': 'arg2'} + ) + + self.assertEqual( + dict(getcallargs(func_def, *[], **{'arg1': 'arg1'})), + {'arg1': 'arg1', 'arg2': 'arg2'} + ) + + self.assertEqual( + dict(getcallargs( + func_def, *[], **{'arg1': 'arg1', 'arg2': 2})), + {'arg1': 'arg1', 'arg2': 2} + ) + + def test_call_in_context(self): + def func_no_args(): + return None + + def func_args(first='first', last='last'): + return first, last + + def func_self_arg(self): + return self + + def func_cls_arg(cls): + return cls + + class Tst(object): + @classmethod + def tst(cls): + return cls + + self.assertIsNone( + call_in_context( + func=func_no_args, + context_args={} + ) + ) + + self.assertIsNone( + call_in_context( + func=func_no_args, + context_args={'test': 'val'} + ) + ) + + self.assertEqual( + call_in_context( + func=func_args, + context_args={'first': 0, 'last': -1} + ), + (0, -1) + ) + + with self.assertRaises(ValueError): + call_in_context( + func=func_args, + context_args={} + ) + + self.assertEqual( + call_in_context( + func=func_self_arg, + context_args={'self': self} + ), + self + ) + + self.assertEqual( + call_in_context( + func=func_cls_arg, + context_args={'cls': self.__class__} + ), + self.__class__ + ) + + self.assertEqual( + call_in_context( + func=func_cls_arg, + context_args={'self': self} + ), + self.__class__ + ) + + self.assertEqual( + call_in_context( + func=Tst.tst, + context_args={'cls': self.__class__} + ), + Tst, + 'cls was not filtered from @classmethod!' + ) + + +@patch('core.helpers.setup_teardown.__getcallargs', return_value={'arg': True}) +@patch('core.helpers.setup_teardown.__call_in_context') +class TestSetupTeardown(unittest.TestCase): + def test_basic(self, call_in, getargs): + arg = True + + def setup_func(): + pass + + def teardown_func(): + pass + + @setup_teardown.setup_teardown() + def positive_example(arg): + return arg + + self.assertEqual(positive_example(arg), arg) + + # Real function is under decorator, so we could not make full check + getargs.assert_called_once() + + call_in.assert_has_calls(( + call(None, {'arg': arg}), + call(None, {'arg': arg}), + )) + + def test_applied(self, call_in, getargs): + arg = True + + def setup_func(): + pass + + def teardown_func(): + pass + + @setup_teardown.setup_teardown( + setup=setup_func, + teardown=teardown_func + ) + def positive_example(arg): + return arg + + self.assertEqual(positive_example(arg), arg) + + # Real function is under decorator, so we could not make full check + getargs.assert_called_once() + + call_in.assert_has_calls(( + call(setup_func, {'arg': arg}), + call(teardown_func, {'arg': arg}), + )) + + def test_exception_applied(self, call_in, getargs): + arg = True + + def setup_func(): + pass + + def teardown_func(): + pass + + @setup_teardown.setup_teardown( + setup=setup_func, + teardown=teardown_func + ) + def positive_example(arg): + raise ValueError(arg) + + with self.assertRaises(ValueError): + positive_example(arg) + + # Real function is under decorator, so we could not make full check + getargs.assert_called_once() + + call_in.assert_has_calls(( + call(setup_func, {'arg': arg}), + call(teardown_func, {'arg': arg}), + )) diff --git a/core/helpers/setup_teardown.py b/core/helpers/setup_teardown.py new file mode 100644 index 000000000..1ea6780be --- /dev/null +++ b/core/helpers/setup_teardown.py @@ -0,0 +1,337 @@ +# Copyright 2016 Mirantis, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from __future__ import unicode_literals + +import functools +import inspect + +import six + +# Setup/Teardown decorators, which is missing in Proboscis. +# Usage: like in Nose. + + +# pylint: disable=no-member +def __getcallargs(func, *positional, **named): + """get real function call arguments without calling function + + :rtype: dict + """ + # noinspection PyUnresolvedReferences + if six.PY2: + return inspect.getcallargs(func, *positional, **named) + sig = inspect.signature(func).bind(*positional, **named) + sig.apply_defaults() # after bind we doesn't have defaults + return sig.arguments + + +def __get_arg_names(func): + """get argument names for function + + :param func: func + :return: list of function argnames + :rtype: list + + >>> def tst_1(): + ... pass + + >>> __get_arg_names(tst_1) + [] + + >>> def tst_2(arg): + ... pass + + >>> __get_arg_names(tst_2) + ['arg'] + """ + # noinspection PyUnresolvedReferences + return ( + [arg for arg in inspect.getargspec(func=func).args] if six.PY2 else + list(inspect.signature(obj=func).parameters.keys()) + ) +# pylint:enable=no-member + + +def __call_in_context(func, context_args): + """call function with substitute arguments from dict + + :param func: function or None + :param context_args: dict + :type context_args: dict + :return: function call results + + >>> __call_in_context(None, {}) + + >>> def print_print(): + ... print ('print') + + >>> __call_in_context(print_print, {}) + print + + >>> __call_in_context(print_print, {'val': 1}) + print + + >>> def print_val(val): + ... print(val) + + >>> __call_in_context(print_val, {'val': 1}) + 1 + """ + if func is None: + return + + func_args = __get_arg_names(func) + if not func_args: + return func() + + if inspect.ismethod(func) and 'cls' in func_args: + func_args.remove('cls') + # cls if used in @classmethod and could not be posted + # via args or kwargs, so classmethod decorators always has access + # to it's own class only, except direct class argument + elif 'self' in context_args: + context_args.setdefault('cls', context_args['self'].__class__) + try: + arg_values = [context_args[k] for k in func_args] + except KeyError as e: + raise ValueError("Argument '{}' is missing".format(str(e))) + + return func(*arg_values) + + +def setup_teardown(setup=None, teardown=None): + """Add setup and teardown for functions and methods. + + :param setup: function + :param teardown: function + :return: + + >>> def setup_func(): + ... print('setup_func called') + + >>> def teardown_func(): + ... print('teardown_func called') + + >>> @setup_teardown(setup=setup_func, teardown=teardown_func) + ... def positive_example(arg): + ... print(arg) + + >>> positive_example(arg=1) + setup_func called + 1 + teardown_func called + + >>> def print_call(text): + ... print (text) + + >>> @setup_teardown( + ... setup=lambda: print_call('setup lambda'), + ... teardown=lambda: print_call('teardown lambda')) + ... def positive_example_lambda(arg): + ... print(arg) + + >>> positive_example_lambda(arg=1) + setup lambda + 1 + teardown lambda + + >>> def setup_with_self(self): + ... print( + ... 'setup_with_self: ' + ... 'self.cls_val = {cls_val!s}, self.val = {val!s}'.format( + ... cls_val=self.cls_val, val=self.val)) + + >>> def teardown_with_self(self): + ... print( + ... 'teardown_with_self: ' + ... 'self.cls_val = {cls_val!s}, self.val = {val!s}'.format( + ... cls_val=self.cls_val, val=self.val)) + + >>> def setup_with_cls(cls): + ... print( + ... 'setup_with_cls: cls.cls_val = {cls_val!s}'.format( + ... cls_val=cls.cls_val)) + + >>> def teardown_with_cls(cls): + ... print('teardown_with_cls: cls.cls_val = {cls_val!s}'.format( + ... cls_val=cls.cls_val)) + + >>> class HelpersBase(object): + ... cls_val = None + ... def __init__(self): + ... self.val = None + ... @classmethod + ... def cls_setup(cls): + ... print( + ... 'cls_setup: cls.cls_val = {cls_val!s}'.format( + ... cls_val=cls.cls_val)) + ... @classmethod + ... def cls_teardown(cls): + ... print( + ... 'cls_teardown: cls.cls_val = {cls_val!s}'.format( + ... cls_val=cls.cls_val)) + ... def self_setup(self): + ... print( + ... 'self_setup: ' + ... 'self.cls_val = {cls_val!s}, self.val = {val!s}'.format( + ... cls_val=self.cls_val, val=self.val)) + ... def self_teardown(self): + ... print( + ... 'self_teardown: ' + ... 'self.cls_val = {cls_val!s}, self.val = {val!s}'.format( + ... cls_val=self.cls_val, val=self.val)) + + >>> class Test(HelpersBase): + ... @setup_teardown( + ... setup=HelpersBase.self_setup, + ... teardown=HelpersBase.self_teardown) + ... def test_self_self(self, cls_val=0, val=0): + ... print( + ... 'test_self_self: ' + ... 'self.cls_val = {cls_val!s}, self.val = {val!s}'.format( + ... cls_val=cls_val, val=val)) + ... self.val = val + ... self.cls_val = cls_val + ... @setup_teardown( + ... setup=HelpersBase.cls_setup, + ... teardown=HelpersBase.cls_teardown) + ... def test_self_cls(self, cls_val=1, val=1): + ... print( + ... 'test_self_cls: ' + ... 'self.cls_val = {cls_val!s}, self.val = {val!s}'.format( + ... cls_val=cls_val, val=val)) + ... self.val = val + ... self.cls_val = cls_val + ... @setup_teardown( + ... setup=setup_func, + ... teardown=teardown_func) + ... def test_self_none(self, cls_val=2, val=2): + ... print( + ... 'test_self_cls: ' + ... 'self.cls_val = {cls_val!s}, self.val = {val!s}'.format( + ... cls_val=cls_val, val=val)) + ... self.val = val + ... self.cls_val = cls_val + ... @setup_teardown( + ... setup=setup_with_self, + ... teardown=teardown_with_self) + ... def test_self_ext_self(self, cls_val=-1, val=-1): + ... print( + ... 'test_self_ext_self: ' + ... 'self.cls_val = {cls_val!s}, self.val = {val!s}'.format( + ... cls_val=cls_val, val=val)) + ... self.val = val + ... self.cls_val = cls_val + ... @setup_teardown( + ... setup=setup_with_cls, + ... teardown=teardown_with_cls) + ... def test_self_ext_cls(self, cls_val=-2, val=-2): + ... print( + ... 'test_self_ext_cls: ' + ... 'self.cls_val = {cls_val!s}, self.val = {val!s}'.format( + ... cls_val=cls_val, val=val)) + ... self.val = val + ... self.cls_val = cls_val + ... @classmethod + ... @setup_teardown( + ... setup=HelpersBase.cls_setup, + ... teardown=HelpersBase.cls_teardown) + ... def test_cls_cls(cls, cls_val=3): + ... print( + ... 'test_cls_cls: cls.cls_val = {cls_val!s}'.format( + ... cls_val=cls_val)) + ... cls.cls_val = cls_val + ... @classmethod + ... @setup_teardown( + ... setup=setup_func, + ... teardown=teardown_func) + ... def test_cls_none(cls, cls_val=4): + ... print( + ... 'test_cls_none: cls.cls_val = {cls_val!s}'.format( + ... cls_val=cls_val)) + ... cls.cls_val = cls_val + ... @classmethod + ... @setup_teardown( + ... setup=setup_with_cls, + ... teardown=teardown_with_cls) + ... def test_cls_ext_cls(cls, cls_val=-3): + ... print( + ... 'test_self_ext_cls: cls.cls_val = {cls_val!s}'.format( + ... cls_val=cls_val)) + ... cls.cls_val = cls_val + ... @staticmethod + ... @setup_teardown(setup=setup_func, teardown=teardown_func) + ... def test_none_none(): + ... print('test') + + >>> test = Test() + + >>> test.test_self_self() + self_setup: self.cls_val = None, self.val = None + test_self_self: self.cls_val = 0, self.val = 0 + self_teardown: self.cls_val = 0, self.val = 0 + + >>> test.test_self_cls() + cls_setup: cls.cls_val = None + test_self_cls: self.cls_val = 1, self.val = 1 + cls_teardown: cls.cls_val = None + + >>> test.test_self_none() + setup_func called + test_self_cls: self.cls_val = 2, self.val = 2 + teardown_func called + + >>> test.test_self_ext_self() + setup_with_self: self.cls_val = 2, self.val = 2 + test_self_ext_self: self.cls_val = -1, self.val = -1 + teardown_with_self: self.cls_val = -1, self.val = -1 + + >>> test.test_self_ext_cls() + setup_with_cls: cls.cls_val = None + test_self_ext_cls: self.cls_val = -2, self.val = -2 + teardown_with_cls: cls.cls_val = None + + >>> test.test_cls_cls() + cls_setup: cls.cls_val = None + test_cls_cls: cls.cls_val = 3 + cls_teardown: cls.cls_val = None + + >>> test.test_cls_none() + setup_func called + test_cls_none: cls.cls_val = 4 + teardown_func called + + >>> test.test_cls_ext_cls() + setup_with_cls: cls.cls_val = 4 + test_self_ext_cls: cls.cls_val = -3 + teardown_with_cls: cls.cls_val = -3 + + >>> test.test_none_none() + setup_func called + test + teardown_func called + """ + def real_decorator(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + real_args = __getcallargs(func, *args, **kwargs) + __call_in_context(setup, real_args) + try: + result = func(*args, **kwargs) + finally: + __call_in_context(teardown, real_args) + return result + return wrapper + return real_decorator diff --git a/fuelweb_test/helpers/decorators.py b/fuelweb_test/helpers/decorators.py index 42e3b1519..4bd18389c 100644 --- a/fuelweb_test/helpers/decorators.py +++ b/fuelweb_test/helpers/decorators.py @@ -29,6 +29,10 @@ from proboscis.asserts import assert_true from six.moves import urllib # pylint: enable=import-error +# pylint: disable=unused-import +from core.helpers.setup_teardown import setup_teardown # noqa +# pylint: enable=unused-import + from fuelweb_test import logger from fuelweb_test import settings from fuelweb_test.helpers.checkers import check_action_logs @@ -514,317 +518,6 @@ def check_repos_management(func): return result return wrapper -# Setup/Teardown decorators, which is missing in Proboscis. -# Usage: like in Nose. -# Python.six is less smart - - -# pylint: disable=no-member -def __getcallargs(func, *positional, **named): - if sys.version_info.major < 3: - return inspect.getcallargs(func, *positional, **named) - else: - # noinspection PyUnresolvedReferences - return inspect.signature(func).bind(*positional, **named).arguments - - -def __get_arg_names(func): - """get argument names for function - - :param func: func - :return: list of function argnames - - >>> def tst_1(): - ... pass - - >>> __get_arg_names(tst_1) - [] - - >>> def tst_2(arg): - ... pass - - >>> __get_arg_names(tst_2) - ['arg'] - """ - if sys.version_info.major < 3: - return [arg for arg in inspect.getargspec(func=func).args] - else: - # noinspection PyUnresolvedReferences - return list(inspect.signature(obj=func).parameters.keys()) -# pylint:enable=no-member - - -def __call_in_context(func, context_args): - """call function with substitute arguments from dict - - :param func: function or None - :param context_args: dict - :return: function call results - - >>> __call_in_context(None, {}) - - >>> def print_print(): - ... print ('print') - - >>> __call_in_context(print_print, {}) - print - - >>> __call_in_context(print_print, {'val': 1}) - print - - >>> def print_val(val): - ... print(val) - - >>> __call_in_context(print_val, {'val': 1}) - 1 - """ - if func is None: - return - - func_args = __get_arg_names(func) - if not func_args: - return func() - - if inspect.ismethod(func) and 'cls' in func_args: - func_args.remove('cls') - # cls if used in @classmethod and could not be posted - # via args or kwargs, so classmethod decorators always has access - # to it's own class only, except direct class argument - elif 'self' in context_args: - context_args.setdefault('cls', context_args['self'].__class__) - try: - arg_values = [context_args[k] for k in func_args] - except KeyError as e: - raise ValueError("Argument '{}' is missing".format(str(e))) - - return func(*arg_values) - - -def setup_teardown(setup=None, teardown=None): - """Add setup and teardown for functions and methods. - - :param setup: function - :param teardown: function - :return: - - >>> def setup_func(): - ... print('setup_func called') - - >>> def teardown_func(): - ... print('teardown_func called') - - >>> @setup_teardown(setup=setup_func, teardown=teardown_func) - ... def positive_example(arg): - ... print(arg) - - >>> positive_example(arg=1) - setup_func called - 1 - teardown_func called - - >>> def print_call(text): - ... print (text) - - >>> @setup_teardown( - ... setup=lambda: print_call('setup lambda'), - ... teardown=lambda: print_call('teardown lambda')) - ... def positive_example_lambda(arg): - ... print(arg) - - >>> positive_example_lambda(arg=1) - setup lambda - 1 - teardown lambda - - >>> def setup_with_self(self): - ... print( - ... 'setup_with_self: ' - ... 'self.cls_val = {cls_val!s}, self.val = {val!s}'.format( - ... cls_val=self.cls_val, val=self.val)) - - >>> def teardown_with_self(self): - ... print( - ... 'teardown_with_self: ' - ... 'self.cls_val = {cls_val!s}, self.val = {val!s}'.format( - ... cls_val=self.cls_val, val=self.val)) - - >>> def setup_with_cls(cls): - ... print( - ... 'setup_with_cls: cls.cls_val = {cls_val!s}'.format( - ... cls_val=cls.cls_val)) - - >>> def teardown_with_cls(cls): - ... print('teardown_with_cls: cls.cls_val = {cls_val!s}'.format( - ... cls_val=cls.cls_val)) - - >>> class HelpersBase(object): - ... cls_val = None - ... def __init__(self): - ... self.val = None - ... @classmethod - ... def cls_setup(cls): - ... print( - ... 'cls_setup: cls.cls_val = {cls_val!s}'.format( - ... cls_val=cls.cls_val)) - ... @classmethod - ... def cls_teardown(cls): - ... print( - ... 'cls_teardown: cls.cls_val = {cls_val!s}'.format( - ... cls_val=cls.cls_val)) - ... def self_setup(self): - ... print( - ... 'self_setup: ' - ... 'self.cls_val = {cls_val!s}, self.val = {val!s}'.format( - ... cls_val=self.cls_val, val=self.val)) - ... def self_teardown(self): - ... print( - ... 'self_teardown: ' - ... 'self.cls_val = {cls_val!s}, self.val = {val!s}'.format( - ... cls_val=self.cls_val, val=self.val)) - - >>> class Test(HelpersBase): - ... @setup_teardown( - ... setup=HelpersBase.self_setup, - ... teardown=HelpersBase.self_teardown) - ... def test_self_self(self, cls_val=0, val=0): - ... print( - ... 'test_self_self: ' - ... 'self.cls_val = {cls_val!s}, self.val = {val!s}'.format( - ... cls_val=cls_val, val=val)) - ... self.val = val - ... self.cls_val = cls_val - ... @setup_teardown( - ... setup=HelpersBase.cls_setup, - ... teardown=HelpersBase.cls_teardown) - ... def test_self_cls(self, cls_val=1, val=1): - ... print( - ... 'test_self_cls: ' - ... 'self.cls_val = {cls_val!s}, self.val = {val!s}'.format( - ... cls_val=cls_val, val=val)) - ... self.val = val - ... self.cls_val = cls_val - ... @setup_teardown( - ... setup=setup_func, - ... teardown=teardown_func) - ... def test_self_none(self, cls_val=2, val=2): - ... print( - ... 'test_self_cls: ' - ... 'self.cls_val = {cls_val!s}, self.val = {val!s}'.format( - ... cls_val=cls_val, val=val)) - ... self.val = val - ... self.cls_val = cls_val - ... @setup_teardown( - ... setup=setup_with_self, - ... teardown=teardown_with_self) - ... def test_self_ext_self(self, cls_val=-1, val=-1): - ... print( - ... 'test_self_ext_self: ' - ... 'self.cls_val = {cls_val!s}, self.val = {val!s}'.format( - ... cls_val=cls_val, val=val)) - ... self.val = val - ... self.cls_val = cls_val - ... @setup_teardown( - ... setup=setup_with_cls, - ... teardown=teardown_with_cls) - ... def test_self_ext_cls(self, cls_val=-2, val=-2): - ... print( - ... 'test_self_ext_cls: ' - ... 'self.cls_val = {cls_val!s}, self.val = {val!s}'.format( - ... cls_val=cls_val, val=val)) - ... self.val = val - ... self.cls_val = cls_val - ... @classmethod - ... @setup_teardown( - ... setup=HelpersBase.cls_setup, - ... teardown=HelpersBase.cls_teardown) - ... def test_cls_cls(cls, cls_val=3): - ... print( - ... 'test_cls_cls: cls.cls_val = {cls_val!s}'.format( - ... cls_val=cls_val)) - ... cls.cls_val = cls_val - ... @classmethod - ... @setup_teardown( - ... setup=setup_func, - ... teardown=teardown_func) - ... def test_cls_none(cls, cls_val=4): - ... print( - ... 'test_cls_none: cls.cls_val = {cls_val!s}'.format( - ... cls_val=cls_val)) - ... cls.cls_val = cls_val - ... @classmethod - ... @setup_teardown( - ... setup=setup_with_cls, - ... teardown=teardown_with_cls) - ... def test_cls_ext_cls(cls, cls_val=-3): - ... print( - ... 'test_self_ext_cls: cls.cls_val = {cls_val!s}'.format( - ... cls_val=cls_val)) - ... cls.cls_val = cls_val - ... @staticmethod - ... @setup_teardown(setup=setup_func, teardown=teardown_func) - ... def test_none_none(): - ... print('test') - - >>> test = Test() - - >>> test.test_self_self() - self_setup: self.cls_val = None, self.val = None - test_self_self: self.cls_val = 0, self.val = 0 - self_teardown: self.cls_val = 0, self.val = 0 - - >>> test.test_self_cls() - cls_setup: cls.cls_val = None - test_self_cls: self.cls_val = 1, self.val = 1 - cls_teardown: cls.cls_val = None - - >>> test.test_self_none() - setup_func called - test_self_cls: self.cls_val = 2, self.val = 2 - teardown_func called - - >>> test.test_self_ext_self() - setup_with_self: self.cls_val = 2, self.val = 2 - test_self_ext_self: self.cls_val = -1, self.val = -1 - teardown_with_self: self.cls_val = -1, self.val = -1 - - >>> test.test_self_ext_cls() - setup_with_cls: cls.cls_val = None - test_self_ext_cls: self.cls_val = -2, self.val = -2 - teardown_with_cls: cls.cls_val = None - - >>> test.test_cls_cls() - cls_setup: cls.cls_val = None - test_cls_cls: cls.cls_val = 3 - cls_teardown: cls.cls_val = None - - >>> test.test_cls_none() - setup_func called - test_cls_none: cls.cls_val = 4 - teardown_func called - - >>> test.test_cls_ext_cls() - setup_with_cls: cls.cls_val = 4 - test_self_ext_cls: cls.cls_val = -3 - teardown_with_cls: cls.cls_val = -3 - - >>> test.test_none_none() - setup_func called - test - teardown_func called - """ - def real_decorator(func): - @functools.wraps(func) - def wrapper(*args, **kwargs): - real_args = __getcallargs(func, *args, **kwargs) - __call_in_context(setup, real_args) - try: - result = func(*args, **kwargs) - finally: - __call_in_context(teardown, real_args) - return result - return wrapper - return real_decorator - def token(func): @functools.wraps(func) diff --git a/fuelweb_test/tests/plugins/plugin_example/test_fuel_plugin_example_postdeploy.py b/fuelweb_test/tests/plugins/plugin_example/test_fuel_plugin_example_postdeploy.py index 32146b77c..ef783f20b 100644 --- a/fuelweb_test/tests/plugins/plugin_example/test_fuel_plugin_example_postdeploy.py +++ b/fuelweb_test/tests/plugins/plugin_example/test_fuel_plugin_example_postdeploy.py @@ -16,10 +16,11 @@ from os.path import basename from proboscis.asserts import assert_true from proboscis import test +from core.helpers.setup_teardown import setup_teardown + from fuelweb_test import logger from fuelweb_test.helpers.decorators import log_snapshot_after_test from fuelweb_test.helpers.decorators import upload_manifests -from fuelweb_test.helpers.decorators import setup_teardown from fuelweb_test.helpers.utils import get_node_hiera_roles from fuelweb_test.helpers import checkers from fuelweb_test.settings import DEPLOYMENT_MODE diff --git a/fuelweb_test/tests/test_reduced_footprint.py b/fuelweb_test/tests/test_reduced_footprint.py index 403c4e369..00d94c395 100644 --- a/fuelweb_test/tests/test_reduced_footprint.py +++ b/fuelweb_test/tests/test_reduced_footprint.py @@ -21,9 +21,10 @@ from paramiko.ssh_exception import ChannelException from proboscis import asserts from proboscis import test +from core.helpers.setup_teardown import setup_teardown + from fuelweb_test.helpers import checkers from fuelweb_test.helpers.decorators import log_snapshot_after_test -from fuelweb_test.helpers.decorators import setup_teardown from fuelweb_test.helpers.utils import get_network_template from fuelweb_test.helpers.utils import preserve_partition from fuelweb_test import settings diff --git a/fuelweb_test/tests/tests_strength/test_load.py b/fuelweb_test/tests/tests_strength/test_load.py index 3ba014b7e..df0055519 100644 --- a/fuelweb_test/tests/tests_strength/test_load.py +++ b/fuelweb_test/tests/tests_strength/test_load.py @@ -17,11 +17,12 @@ import time from proboscis import test from proboscis.asserts import assert_true +from core.helpers.setup_teardown import setup_teardown + from fuelweb_test import logger from fuelweb_test import ostf_test_mapping from fuelweb_test import settings from fuelweb_test.helpers.decorators import log_snapshot_after_test -from fuelweb_test.helpers.decorators import setup_teardown from fuelweb_test.helpers.rally import RallyBenchmarkTest from fuelweb_test.helpers.utils import fill_space from fuelweb_test.tests.base_test_case import SetupEnvironment diff --git a/fuelweb_test/tests/tests_strength/test_repetitive_restart.py b/fuelweb_test/tests/tests_strength/test_repetitive_restart.py index 5125c77b8..72adbf33d 100644 --- a/fuelweb_test/tests/tests_strength/test_repetitive_restart.py +++ b/fuelweb_test/tests/tests_strength/test_repetitive_restart.py @@ -17,15 +17,17 @@ import time from proboscis import test from proboscis.asserts import assert_true # pylint: disable=redefined-builtin +# noinspection PyUnresolvedReferences from six.moves import xrange # pylint: enable=redefined-builtin +from core.helpers.setup_teardown import setup_teardown + from fuelweb_test import logger from fuelweb_test import ostf_test_mapping from fuelweb_test import settings from fuelweb_test.helpers.cic_maintenance_mode import change_config from fuelweb_test.helpers.decorators import log_snapshot_after_test -from fuelweb_test.helpers.decorators import setup_teardown from fuelweb_test.helpers.rally import RallyBenchmarkTest from fuelweb_test.helpers.utils import fill_space from fuelweb_test.tests.base_test_case import SetupEnvironment