salt/tests/unit/utils/decorators_test.py
Nicole Thomas 216d9fdc9a [develop] Merge forward from 2016.3 to develop (#32494)
* fix sorting by latest version when called with an attribute

* remove reference to master_alive_check

* Fixes saltstack/salt#28262

* Resolve memory leak in authentication

* outputter virt_list does not exist anymore

* Update proxmox documentation

* Fix documentation on boto_asg and boto_elb modules and states

* modules.win_timezone: don't list all zones in debug log

* Correcty index glusterfs bricks

Fixes issue #32311

* Cleaner deprecation process with decorators

* Add deprecation decorator scaffold

* Capture type error and unhandled exceptions while function calls

* Aware of the current and future version of deprecation

* Implement initially is_deprecated decorator

* Add an alias for the capitalization

* Fix capitalization easier way

* Remove an extra line

* Add successor name to the deprecation decorator.

* Granulate logging and error messages.

* Implement function swapper

* Raise later the caught exception

* Clarify exception message

* Save function original name

* Remove an extra line

* Hide an alternative hidden function name in the error message, preserving the error itself

* Rename variable as private

* Add a method to detect if a function is using its previous version

* Message to the log and/or raise an exception accordingly to the status of used function

* Log an error along with the exception

* Add internal method documentation

* Add documentation and usage process for decorator "is_deprecated"

* Add documentation and process usage for the decorator "with_deprecated"

* Hide private method name

* Fix PEP8, re-word the error message

* Deprecate basic uptime function

* Add initial decorator unit test

* Rename old/new functions, mock versions

* Move frequent data to the test setup

* Add logging on EOL exception

* Rename and document high to low version test on is_deprecated

* Implement a test on low to high version of is_deprecated decorator

* Add a correction to the test description

* Remove a dead code

* Implement a test for high to low version on is_deprecated, using with_successor param

* Correct typso adn mistaeks

* Implement high to low version with successor param on is_deprecated

* Setup a virtual name for the module

* Implement test for with_deprecated should raise an exception if same deprecated function not found

* Implement test for with_deprecated an old function is picked up if configured

* Correct test description purpose

* Implement test with_deprecated when no deprecation is requested

* Add logging test to the configured deprecation request

* Add logging testing when deprecated version wasn't requested

* Implement test EOL for with_deprecated decorator

* Correct test explanation

* Rename the test

* Implement with_deprecated no EOL, deprecated other function name

* Implement with_deprecated, deprecated other function name, EOL reached

* Add test description for the with_deprecated + with_name + EOL

* Fix confusing test names

* Add logging test to the is_deprecated decorator when function as not found.

* Add more test point to each test, remove empty lines

* Bugfix: at certain conditions a wrong alias name is reported to the log

* Fix a typo in a comment

* Add test for the logging

* Disable a pylint: None will _never_ be raised

* Fix test for the deprecated "status.uptime" version

* Bugfix: Do not yank raised exceptions

* Remove unnecessary decorator

* Add test for the new uptime

* Add test for the new uptime fails when /proc/uptime does not exists

* Rename old test case

* Skip test for the UTC time, unless freeze time is used.

* Fix pylint

* Fix documentation

* Bugfix: proxy-pass the docstring of the decorated function

* Lint fix

* Fixes saltstack/salt#28262 for 2015.5 branch

* Update master config docs

* Improve git_pillar documentation/logging

* Add note about different behavior of top file in git_pillar

* Make log entry for a missing pillar SLS file more accurate for git_pillar

* FreeBSD supports packages in format java/openjdk7 so the prior commit broke that functionality. Check freebsd/pkg#1409 for more info.

* FreeBSD supports packages in format java/openjdk7 so the prior commit broke that functionality. Check freebsd/pkg#1409 for more info.

* Update glusterfs_test to be inline with #32312

* Fix salt-cloud paralell provisioning

Closes #31632

* Ignore Raspbian in service.py __virtual__ (#32421)

* Ignore Raspbian in service.py __virtual__

This prevents more than one execution module from trying to load as the
service virtual module.

Refs: #32413

* pack __salt__ before loading provider overrides

We can (and should) pack here since we're just packing a reference to the
object. __salt__ needs to be available when we're loading our provider
overrides

* Fix broken __salt__ dict in provider override

Using ret.items() here sets ``__salt__`` to its items (tuple containing
function name and reference), breaking usage of ``__salt__`` inside
overridden functions.

* Merge #32293 with test fixes (#32418)

* Fix issue #11497

* Remove check for working directory presence in tests

* Fix Domainname introspection

Default value needs to be extracted from the container itself,
because dockerd set Domainname value when network_mode=host.

* Add pgjsonb_queue to queue doc index

* Pylint fixes

* Pass parser options into batch mode

Resolves #31738

* Changed the target file in file.symlink test (#32443)

* Argument name in docs should match actual arg name (#32445)

Fixes #31851

* tests.integration: bypass MacOS TMPDIR, gettempdir (#32447)

Updates 0edd532, 8f558a5.

When logging in as root over `ssh root@host`, `$TMPDIR` and
`tempfile.gettempdir()` are both set to a variation of:
```
/private/var/folders/zz/zyxvpxvq6csfxvn_n0000000000000/T/
```
When logging in as root over `sudo -i`, `$TMPDIR` is unset and
`tempfile.gettempdir()` is set to `/tmp`.

My guess is that the second case is an unintended or uncorrected omision
by Apple as they have introduced the longer, randomized temp path in a
recent version of MacOS.

* Issue #28706: Fix state user.present behavior. (#32448)

- As mentionned in issue #28706, state user.present no longer remove
      user from groups if the keyword 'groups' with empty value '[]' is not
      explicitly set, salt will assume current groups are still wanted.

* tests.integration: fix 4230c8a

* Move the tables of virtual modules to individual documentation pages

* Add new doc pages to toctree

* Add external ref to windows package manager docs

* Improve docstrings

* Add documentation on virtual module provider overrides to the module docs

* Clarify the scope of the provider param in states.

* Add link to provider override docs to all package providers

* Add link to provider override docs to all service providers

* Add link to provider override docs to all user providers

* dd link to provider override docs to all shadow providers

* Add link to provider override docs to all group providers

* Backport 31164 and 31364 (#32474)

* Don't send REQ while another one is waiting for response.

The message has to be removed from the queue the only *after* it's
already processed to don't confuse send() functionality that expects
empty queue means: there's no active sendings.

* Fixed zeromq ReqMessageClient destroy

* Add link to provider override docs to opkg.py

This is a companion to https://github.com/saltstack/salt/pull/32458, but
this module was not added until the 2016.3 branch, so the documentation
is being updated there for this module.

* Add documentation for some master/minion configs (#32454)

Refs #32400

Adds docs for:

- cli_summary
- event_return_queue
- event_return_whitelist
- event_return_blacklist
- file_recv_max_size
- fileserver_followsymlinks
- fileserver_ignoresymlinks
- fileserver_limit_traversal

* Automatically detect correct MySQL password column for 5.7 and fix setting passwords (#32440)

* Automatically detect MySQL password column

* Fix changing password in MySQL 5.7

* Fix lint test

* Fix unit tests (?)

They will still fail if "authentication_string" is legitimately the right column name, but I don't know what to do about that.

* Additional unit test fix

* Only unsub if we have a jid

Closes #32479
2016-04-11 17:07:15 -06:00

233 lines
8.9 KiB
Python

# -*- coding: utf-8 -*-
'''
:codeauthor: :email:`Bo Maryniuk (bo@suse.de)`
unit.utils.decorators_test
'''
# Import Python libs
from __future__ import absolute_import
# Import Salt Testing libs
from salttesting import TestCase
from salttesting.helpers import ensure_in_syspath
from salt.utils import decorators
from salt.version import SaltStackVersion
from salt.exceptions import CommandExecutionError
ensure_in_syspath('../../')
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)
class DecoratorsTest(TestCase):
'''
Testing decorators.
'''
def old_function(self):
return "old"
def new_function(self):
return "new"
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__': {},
'old_function': self.old_function,
'new_function': self.new_function,
}
self.messages = list()
decorators.log = DummyLogger(self.messages)
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:
'''
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 is using its deprecated version and will expire in version "Beryllium". '
'Use its successor "new_function" instead.'])
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 is using its deprecated version and will expire in version "Beryllium". '
'Use its successor "new_function" instead.']
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_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.'])
if __name__ == '__main__':
from integration import run_tests
run_tests(DecoratorsTest, needs_daemon=False)