mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 00:55:19 +00:00
379 lines
16 KiB
Python
379 lines
16 KiB
Python
# -*- coding: utf-8 -*-
|
|
'''
|
|
:codeauthor: Bo Maryniuk (bo@suse.de)
|
|
unit.utils.decorators_test
|
|
'''
|
|
|
|
# Import Python libs
|
|
from __future__ import absolute_import, print_function, unicode_literals
|
|
|
|
# Import Salt libs
|
|
import salt.utils.decorators as decorators
|
|
from salt.version import SaltStackVersion
|
|
from salt.exceptions import CommandExecutionError, SaltConfigurationError
|
|
from tests.support.unit import skipIf, TestCase
|
|
from tests.support.mock import NO_MOCK, NO_MOCK_REASON, patch
|
|
|
|
|
|
class DummyLogger(object):
|
|
'''
|
|
Dummy logger accepts everything and simply logs
|
|
'''
|
|
def __init__(self, messages):
|
|
self._messages = messages
|
|
|
|
def __getattr__(self, item):
|
|
return self._log
|
|
|
|
def _log(self, msg):
|
|
self._messages.append(msg)
|
|
|
|
|
|
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
|
class DecoratorsTest(TestCase):
|
|
'''
|
|
Testing decorators.
|
|
'''
|
|
def old_function(self):
|
|
return "old"
|
|
|
|
def new_function(self):
|
|
return "new"
|
|
|
|
def _new_function(self):
|
|
return "old"
|
|
|
|
def _mk_version(self, name):
|
|
'''
|
|
Make a version
|
|
|
|
:return:
|
|
'''
|
|
return name, SaltStackVersion.from_name(name)
|
|
|
|
def setUp(self):
|
|
'''
|
|
Setup a test
|
|
:return:
|
|
'''
|
|
self.globs = {
|
|
'__virtualname__': 'test',
|
|
'__opts__': {},
|
|
'__pillar__': {},
|
|
'old_function': self.old_function,
|
|
'new_function': self.new_function,
|
|
'_new_function': self._new_function,
|
|
}
|
|
self.addCleanup(delattr, self, 'globs')
|
|
self.messages = list()
|
|
self.addCleanup(delattr, self, 'messages')
|
|
patcher = patch.object(decorators, 'log', DummyLogger(self.messages))
|
|
patcher.start()
|
|
self.addCleanup(patcher.stop)
|
|
|
|
def test_is_deprecated_version_eol(self):
|
|
'''
|
|
Use of is_deprecated will result to the exception,
|
|
if the expiration version is lower than the current version.
|
|
A successor function is not pointed out.
|
|
|
|
:return:
|
|
'''
|
|
depr = decorators.is_deprecated(self.globs, "Helium")
|
|
depr._curr_version = self._mk_version("Beryllium")[1]
|
|
with self.assertRaises(CommandExecutionError):
|
|
depr(self.old_function)()
|
|
self.assertEqual(self.messages,
|
|
['The lifetime of the function "old_function" expired.'])
|
|
|
|
def test_is_deprecated_with_successor_eol(self):
|
|
'''
|
|
Use of is_deprecated will result to the exception,
|
|
if the expiration version is lower than the current version.
|
|
A successor function is pointed out.
|
|
|
|
:return:
|
|
'''
|
|
depr = decorators.is_deprecated(self.globs, "Helium", with_successor="new_function")
|
|
depr._curr_version = self._mk_version("Beryllium")[1]
|
|
with self.assertRaises(CommandExecutionError):
|
|
depr(self.old_function)()
|
|
self.assertEqual(self.messages,
|
|
['The lifetime of the function "old_function" expired. '
|
|
'Please use its successor "new_function" instead.'])
|
|
|
|
def test_is_deprecated(self):
|
|
'''
|
|
Use of is_deprecated will result to the log message,
|
|
if the expiration version is higher than the current version.
|
|
A successor function is not pointed out.
|
|
|
|
:return:
|
|
'''
|
|
depr = decorators.is_deprecated(self.globs, "Beryllium")
|
|
depr._curr_version = self._mk_version("Helium")[1]
|
|
self.assertEqual(depr(self.old_function)(), self.old_function())
|
|
self.assertEqual(self.messages,
|
|
['The function "old_function" is deprecated '
|
|
'and will expire in version "Beryllium".'])
|
|
|
|
def test_is_deprecated_with_successor(self):
|
|
'''
|
|
Use of is_deprecated will result to the log message,
|
|
if the expiration version is higher than the current version.
|
|
A successor function is pointed out.
|
|
|
|
:return:
|
|
'''
|
|
depr = decorators.is_deprecated(self.globs, "Beryllium", with_successor="old_function")
|
|
depr._curr_version = self._mk_version("Helium")[1]
|
|
self.assertEqual(depr(self.old_function)(), self.old_function())
|
|
self.assertEqual(self.messages,
|
|
['The function "old_function" is deprecated '
|
|
'and will expire in version "Beryllium". '
|
|
'Use successor "old_function" instead.'])
|
|
|
|
def test_with_deprecated_notfound(self):
|
|
'''
|
|
Test with_deprecated should raise an exception, if a same name
|
|
function with the "_" prefix not implemented.
|
|
|
|
:return:
|
|
'''
|
|
del self.globs['_new_function']
|
|
self.globs['__opts__']['use_deprecated'] = ['test.new_function']
|
|
depr = decorators.with_deprecated(self.globs, "Beryllium")
|
|
depr._curr_version = self._mk_version("Helium")[1]
|
|
with self.assertRaises(CommandExecutionError):
|
|
depr(self.new_function)()
|
|
self.assertEqual(self.messages,
|
|
['The function "test.new_function" is using its deprecated '
|
|
'version and will expire in version "Beryllium".'])
|
|
|
|
def test_with_deprecated_notfound_in_pillar(self):
|
|
'''
|
|
Test with_deprecated should raise an exception, if a same name
|
|
function with the "_" prefix not implemented.
|
|
|
|
:return:
|
|
'''
|
|
del self.globs['_new_function']
|
|
self.globs['__pillar__']['use_deprecated'] = ['test.new_function']
|
|
depr = decorators.with_deprecated(self.globs, "Beryllium")
|
|
depr._curr_version = self._mk_version("Helium")[1]
|
|
with self.assertRaises(CommandExecutionError):
|
|
depr(self.new_function)()
|
|
self.assertEqual(self.messages,
|
|
['The function "test.new_function" is using its deprecated '
|
|
'version and will expire in version "Beryllium".'])
|
|
|
|
def test_with_deprecated_found(self):
|
|
'''
|
|
Test with_deprecated should not raise an exception, if a same name
|
|
function with the "_" prefix is implemented, but should use
|
|
an old version instead, if "use_deprecated" is requested.
|
|
|
|
:return:
|
|
'''
|
|
self.globs['__opts__']['use_deprecated'] = ['test.new_function']
|
|
self.globs['_new_function'] = self.old_function
|
|
depr = decorators.with_deprecated(self.globs, "Beryllium")
|
|
depr._curr_version = self._mk_version("Helium")[1]
|
|
self.assertEqual(depr(self.new_function)(), self.old_function())
|
|
log_msg = ['The function "test.new_function" is using its deprecated version '
|
|
'and will expire in version "Beryllium".']
|
|
self.assertEqual(self.messages, log_msg)
|
|
|
|
def test_with_deprecated_found_in_pillar(self):
|
|
'''
|
|
Test with_deprecated should not raise an exception, if a same name
|
|
function with the "_" prefix is implemented, but should use
|
|
an old version instead, if "use_deprecated" is requested.
|
|
|
|
:return:
|
|
'''
|
|
self.globs['__pillar__']['use_deprecated'] = ['test.new_function']
|
|
self.globs['_new_function'] = self.old_function
|
|
depr = decorators.with_deprecated(self.globs, "Beryllium")
|
|
depr._curr_version = self._mk_version("Helium")[1]
|
|
self.assertEqual(depr(self.new_function)(), self.old_function())
|
|
log_msg = ['The function "test.new_function" is using its deprecated version '
|
|
'and will expire in version "Beryllium".']
|
|
self.assertEqual(self.messages, log_msg)
|
|
|
|
def test_with_deprecated_found_eol(self):
|
|
'''
|
|
Test with_deprecated should raise an exception, if a same name
|
|
function with the "_" prefix is implemented, "use_deprecated" is requested
|
|
and EOL is reached.
|
|
|
|
:return:
|
|
'''
|
|
self.globs['__opts__']['use_deprecated'] = ['test.new_function']
|
|
self.globs['_new_function'] = self.old_function
|
|
depr = decorators.with_deprecated(self.globs, "Helium")
|
|
depr._curr_version = self._mk_version("Beryllium")[1]
|
|
with self.assertRaises(CommandExecutionError):
|
|
depr(self.new_function)()
|
|
self.assertEqual(self.messages,
|
|
['Although function "new_function" is called, an alias "new_function" '
|
|
'is configured as its deprecated version. The lifetime of the function '
|
|
'"new_function" expired. Please use its successor "new_function" instead.'])
|
|
|
|
def test_with_deprecated_found_eol_in_pillar(self):
|
|
'''
|
|
Test with_deprecated should raise an exception, if a same name
|
|
function with the "_" prefix is implemented, "use_deprecated" is requested
|
|
and EOL is reached.
|
|
|
|
:return:
|
|
'''
|
|
self.globs['__pillar__']['use_deprecated'] = ['test.new_function']
|
|
self.globs['_new_function'] = self.old_function
|
|
depr = decorators.with_deprecated(self.globs, "Helium")
|
|
depr._curr_version = self._mk_version("Beryllium")[1]
|
|
with self.assertRaises(CommandExecutionError):
|
|
depr(self.new_function)()
|
|
self.assertEqual(self.messages,
|
|
['Although function "new_function" is called, an alias "new_function" '
|
|
'is configured as its deprecated version. The lifetime of the function '
|
|
'"new_function" expired. Please use its successor "new_function" instead.'])
|
|
|
|
def test_with_deprecated_no_conf(self):
|
|
'''
|
|
Test with_deprecated should not raise an exception, if a same name
|
|
function with the "_" prefix is implemented, but should use
|
|
a new version instead, if "use_deprecated" is not requested.
|
|
|
|
:return:
|
|
'''
|
|
self.globs['_new_function'] = self.old_function
|
|
depr = decorators.with_deprecated(self.globs, "Beryllium")
|
|
depr._curr_version = self._mk_version("Helium")[1]
|
|
self.assertEqual(depr(self.new_function)(), self.new_function())
|
|
self.assertFalse(self.messages)
|
|
|
|
def test_with_deprecated_with_name(self):
|
|
'''
|
|
Test with_deprecated should not raise an exception, if a different name
|
|
function is implemented and specified with the "with_name" parameter,
|
|
but should use an old version instead and log a warning log message.
|
|
|
|
:return:
|
|
'''
|
|
self.globs['__opts__']['use_deprecated'] = ['test.new_function']
|
|
depr = decorators.with_deprecated(self.globs, "Beryllium", with_name="old_function")
|
|
depr._curr_version = self._mk_version("Helium")[1]
|
|
self.assertEqual(depr(self.new_function)(), self.old_function())
|
|
self.assertEqual(self.messages,
|
|
['The function "old_function" is deprecated and will expire in version "Beryllium". '
|
|
'Use its successor "new_function" instead.'])
|
|
|
|
def test_with_deprecated_with_name_eol(self):
|
|
'''
|
|
Test with_deprecated should raise an exception, if a different name
|
|
function is implemented and specified with the "with_name" parameter
|
|
and EOL is reached.
|
|
|
|
:return:
|
|
'''
|
|
self.globs['__opts__']['use_deprecated'] = ['test.new_function']
|
|
depr = decorators.with_deprecated(self.globs, "Helium", with_name="old_function")
|
|
depr._curr_version = self._mk_version("Beryllium")[1]
|
|
with self.assertRaises(CommandExecutionError):
|
|
depr(self.new_function)()
|
|
self.assertEqual(self.messages,
|
|
['Although function "new_function" is called, '
|
|
'an alias "old_function" is configured as its deprecated version. '
|
|
'The lifetime of the function "old_function" expired. '
|
|
'Please use its successor "new_function" instead.'])
|
|
|
|
def test_with_deprecated_opt_in_default(self):
|
|
'''
|
|
Test with_deprecated using opt-in policy,
|
|
where newer function is not used, unless configured.
|
|
|
|
:return:
|
|
'''
|
|
depr = decorators.with_deprecated(self.globs, "Beryllium", policy=decorators._DeprecationDecorator.OPT_IN)
|
|
depr._curr_version = self._mk_version("Helium")[1]
|
|
assert depr(self.new_function)() == self.old_function()
|
|
assert self.messages == ['The function "test.new_function" is using its '
|
|
'deprecated version and will expire in version "Beryllium".']
|
|
|
|
def test_with_deprecated_opt_in_use_superseded(self):
|
|
'''
|
|
Test with_deprecated using opt-in policy,
|
|
where newer function is used as per configuration.
|
|
|
|
:return:
|
|
'''
|
|
self.globs['__opts__']['use_superseded'] = ['test.new_function']
|
|
depr = decorators.with_deprecated(self.globs, "Beryllium", policy=decorators._DeprecationDecorator.OPT_IN)
|
|
depr._curr_version = self._mk_version("Helium")[1]
|
|
assert depr(self.new_function)() == self.new_function()
|
|
assert not self.messages
|
|
|
|
def test_with_deprecated_opt_in_use_superseded_in_pillar(self):
|
|
'''
|
|
Test with_deprecated using opt-in policy,
|
|
where newer function is used as per configuration.
|
|
|
|
:return:
|
|
'''
|
|
self.globs['__pillar__']['use_superseded'] = ['test.new_function']
|
|
depr = decorators.with_deprecated(self.globs, "Beryllium", policy=decorators._DeprecationDecorator.OPT_IN)
|
|
depr._curr_version = self._mk_version("Helium")[1]
|
|
assert depr(self.new_function)() == self.new_function()
|
|
assert not self.messages
|
|
|
|
def test_with_deprecated_opt_in_use_superseded_and_deprecated(self):
|
|
'''
|
|
Test with_deprecated misconfiguration.
|
|
|
|
:return:
|
|
'''
|
|
self.globs['__opts__']['use_deprecated'] = ['test.new_function']
|
|
self.globs['__opts__']['use_superseded'] = ['test.new_function']
|
|
depr = decorators.with_deprecated(self.globs, "Beryllium")
|
|
depr._curr_version = self._mk_version("Helium")[1]
|
|
with self.assertRaises(SaltConfigurationError):
|
|
assert depr(self.new_function)() == self.new_function()
|
|
|
|
def test_with_deprecated_opt_in_use_superseded_and_deprecated_in_pillar(self):
|
|
'''
|
|
Test with_deprecated misconfiguration.
|
|
|
|
:return:
|
|
'''
|
|
self.globs['__pillar__']['use_deprecated'] = ['test.new_function']
|
|
self.globs['__pillar__']['use_superseded'] = ['test.new_function']
|
|
depr = decorators.with_deprecated(self.globs, "Beryllium")
|
|
depr._curr_version = self._mk_version("Helium")[1]
|
|
with self.assertRaises(SaltConfigurationError):
|
|
assert depr(self.new_function)() == self.new_function()
|
|
|
|
def test_with_depreciated_should_wrap_function(self):
|
|
wrapped = decorators.with_deprecated({}, "Beryllium")(self.old_function)
|
|
assert wrapped.__module__ == self.old_function.__module__
|
|
|
|
def test_is_deprecated_should_wrap_function(self):
|
|
wrapped = decorators.is_deprecated({}, "Beryllium")(self.old_function)
|
|
assert wrapped.__module__ == self.old_function.__module__
|
|
|
|
def test_ensure_unicode_args_should_wrap_function(self):
|
|
wrapped = decorators.ensure_unicode_args(self.old_function)
|
|
assert wrapped.__module__ == self.old_function.__module__
|
|
|
|
def test_ignores_kwargs_should_wrap_function(self):
|
|
wrapped = decorators.ignores_kwargs('foo', 'bar')(self.old_function)
|
|
assert wrapped.__module__ == self.old_function.__module__
|
|
|
|
def test_memoize_should_wrap_function(self):
|
|
wrapped = decorators.memoize(self.old_function)
|
|
assert wrapped.__module__ == self.old_function.__module__
|
|
|
|
def timing_should_wrap_function(self):
|
|
wrapped = decorators.timing(self.old_function)
|
|
assert wrapped.__module__ == self.old_function.__module__
|