mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 09:23:56 +00:00
Merge branch 'develop' into expand-list_pkg-attr-parameter
This commit is contained in:
commit
130c1b1c21
@ -5,7 +5,7 @@ correct cloud modules
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
# Import python libs
|
# Import python libs
|
||||||
from __future__ import absolute_import, print_function, generators
|
from __future__ import absolute_import, print_function, generators, unicode_literals
|
||||||
import os
|
import os
|
||||||
import copy
|
import copy
|
||||||
import glob
|
import glob
|
||||||
|
@ -447,8 +447,8 @@ def optional_args(proxy=None):
|
|||||||
device2:
|
device2:
|
||||||
True
|
True
|
||||||
'''
|
'''
|
||||||
opt_args = _get_device_grain('optional_args', proxy=proxy)
|
opt_args = _get_device_grain('optional_args', proxy=proxy) or {}
|
||||||
if _FORBIDDEN_OPT_ARGS:
|
if opt_args and _FORBIDDEN_OPT_ARGS:
|
||||||
for arg in _FORBIDDEN_OPT_ARGS:
|
for arg in _FORBIDDEN_OPT_ARGS:
|
||||||
opt_args.pop(arg, None)
|
opt_args.pop(arg, None)
|
||||||
return {'optional_args': opt_args}
|
return {'optional_args': opt_args}
|
||||||
|
@ -200,7 +200,7 @@ def execute(context=None, lens=None, commands=(), load_path=None):
|
|||||||
method = METHOD_MAP[cmd]
|
method = METHOD_MAP[cmd]
|
||||||
nargs = arg_map[method]
|
nargs = arg_map[method]
|
||||||
|
|
||||||
parts = salt.utils.args.shlex_split(arg, posix=False)
|
parts = salt.utils.args.shlex_split(arg)
|
||||||
|
|
||||||
if len(parts) not in nargs:
|
if len(parts) not in nargs:
|
||||||
err = '{0} takes {1} args: {2}'.format(method, nargs, parts)
|
err = '{0} takes {1} args: {2}'.format(method, nargs, parts)
|
||||||
|
@ -24,6 +24,8 @@ import salt.utils.kickstart
|
|||||||
import salt.syspaths
|
import salt.syspaths
|
||||||
from salt.exceptions import SaltInvocationError
|
from salt.exceptions import SaltInvocationError
|
||||||
|
|
||||||
|
# Import 3rd-party libs
|
||||||
|
from salt.ext import six
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -325,6 +327,8 @@ def _bootstrap_yum(
|
|||||||
'''
|
'''
|
||||||
if pkgs is None:
|
if pkgs is None:
|
||||||
pkgs = []
|
pkgs = []
|
||||||
|
elif isinstance(pkgs, six.string_types):
|
||||||
|
pkgs = pkgs.split(',')
|
||||||
|
|
||||||
default_pkgs = ('yum', 'centos-release', 'iputils')
|
default_pkgs = ('yum', 'centos-release', 'iputils')
|
||||||
for pkg in default_pkgs:
|
for pkg in default_pkgs:
|
||||||
@ -333,6 +337,8 @@ def _bootstrap_yum(
|
|||||||
|
|
||||||
if exclude_pkgs is None:
|
if exclude_pkgs is None:
|
||||||
exclude_pkgs = []
|
exclude_pkgs = []
|
||||||
|
elif isinstance(exclude_pkgs, six.string_types):
|
||||||
|
exclude_pkgs = exclude_pkgs.split(',')
|
||||||
|
|
||||||
for pkg in exclude_pkgs:
|
for pkg in exclude_pkgs:
|
||||||
pkgs.remove(pkg)
|
pkgs.remove(pkg)
|
||||||
@ -393,15 +399,27 @@ def _bootstrap_deb(
|
|||||||
if repo_url is None:
|
if repo_url is None:
|
||||||
repo_url = 'http://ftp.debian.org/debian/'
|
repo_url = 'http://ftp.debian.org/debian/'
|
||||||
|
|
||||||
|
if not salt.utils.which('debootstrap'):
|
||||||
|
log.error('Required tool debootstrap is not installed.')
|
||||||
|
return False
|
||||||
|
|
||||||
|
if isinstance(pkgs, (list, tuple)):
|
||||||
|
pkgs = ','.join(pkgs)
|
||||||
|
if isinstance(exclude_pkgs, (list, tuple)):
|
||||||
|
exclude_pkgs = ','.join(exclude_pkgs)
|
||||||
|
|
||||||
deb_args = [
|
deb_args = [
|
||||||
'debootstrap',
|
'debootstrap',
|
||||||
'--foreign',
|
'--foreign',
|
||||||
'--arch',
|
'--arch',
|
||||||
_cmd_quote(arch),
|
_cmd_quote(arch)]
|
||||||
'--include',
|
|
||||||
] + pkgs + [
|
if pkgs:
|
||||||
'--exclude',
|
deb_args += ['--include', _cmd_quote(pkgs)]
|
||||||
] + exclude_pkgs + [
|
if exclude_pkgs:
|
||||||
|
deb_args += ['--exclude', _cmd_quote(exclude_pkgs)]
|
||||||
|
|
||||||
|
deb_args += [
|
||||||
_cmd_quote(flavor),
|
_cmd_quote(flavor),
|
||||||
_cmd_quote(root),
|
_cmd_quote(root),
|
||||||
_cmd_quote(repo_url),
|
_cmd_quote(repo_url),
|
||||||
@ -469,6 +487,8 @@ def _bootstrap_pacman(
|
|||||||
|
|
||||||
if pkgs is None:
|
if pkgs is None:
|
||||||
pkgs = []
|
pkgs = []
|
||||||
|
elif isinstance(pkgs, six.string_types):
|
||||||
|
pkgs = pkgs.split(',')
|
||||||
|
|
||||||
default_pkgs = ('pacman', 'linux', 'systemd-sysvcompat', 'grub')
|
default_pkgs = ('pacman', 'linux', 'systemd-sysvcompat', 'grub')
|
||||||
for pkg in default_pkgs:
|
for pkg in default_pkgs:
|
||||||
@ -477,6 +497,8 @@ def _bootstrap_pacman(
|
|||||||
|
|
||||||
if exclude_pkgs is None:
|
if exclude_pkgs is None:
|
||||||
exclude_pkgs = []
|
exclude_pkgs = []
|
||||||
|
elif isinstance(exclude_pkgs, six.string_types):
|
||||||
|
exclude_pkgs = exclude_pkgs.split(',')
|
||||||
|
|
||||||
for pkg in exclude_pkgs:
|
for pkg in exclude_pkgs:
|
||||||
pkgs.remove(pkg)
|
pkgs.remove(pkg)
|
||||||
|
@ -31,6 +31,7 @@ from salt.modules.inspectlib.entities import (AllowedDir, IgnoredDir, Package,
|
|||||||
import salt.utils # Can be removed when reinit_crypto is moved
|
import salt.utils # Can be removed when reinit_crypto is moved
|
||||||
import salt.utils.files
|
import salt.utils.files
|
||||||
import salt.utils.fsutils
|
import salt.utils.fsutils
|
||||||
|
import salt.utils.path
|
||||||
import salt.utils.stringutils
|
import salt.utils.stringutils
|
||||||
from salt.exceptions import CommandExecutionError
|
from salt.exceptions import CommandExecutionError
|
||||||
|
|
||||||
@ -312,7 +313,7 @@ class Inspector(EnvLoader):
|
|||||||
continue
|
continue
|
||||||
if not valid or not os.path.exists(obj) or not os.access(obj, os.R_OK):
|
if not valid or not os.path.exists(obj) or not os.access(obj, os.R_OK):
|
||||||
continue
|
continue
|
||||||
if os.path.islink(obj):
|
if salt.utils.path.islink(obj):
|
||||||
links.append(obj)
|
links.append(obj)
|
||||||
elif os.path.isdir(obj):
|
elif os.path.isdir(obj):
|
||||||
dirs.append(obj)
|
dirs.append(obj)
|
||||||
|
@ -17,11 +17,14 @@
|
|||||||
# Import python libs
|
# Import python libs
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
import os
|
import os
|
||||||
import grp
|
|
||||||
import pwd
|
|
||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
import platform
|
import platform
|
||||||
import socket
|
import socket
|
||||||
|
try:
|
||||||
|
import grp
|
||||||
|
import pwd
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
# Import salt libs
|
# Import salt libs
|
||||||
import salt.utils.files
|
import salt.utils.files
|
||||||
|
602
salt/modules/saltcheck.py
Normal file
602
salt/modules/saltcheck.py
Normal file
@ -0,0 +1,602 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
A module for testing the logic of states and highstates
|
||||||
|
|
||||||
|
Saltcheck provides unittest like functionality requiring only the knowledge of salt module execution and yaml.
|
||||||
|
|
||||||
|
In order to run state and highstate saltcheck tests a sub-folder of a state must be creaed and named "saltcheck-tests".
|
||||||
|
|
||||||
|
Tests for a state should be created in files ending in *.tst and placed in the saltcheck-tests folder.
|
||||||
|
|
||||||
|
Multiple tests can be created in a file.
|
||||||
|
Multiple *.tst files can be created in the saltcheck-tests folder.
|
||||||
|
The "id" of a test works in the same manner as in salt state files.
|
||||||
|
They should be unique and descriptive.
|
||||||
|
|
||||||
|
Example file system layout:
|
||||||
|
/srv/salt/apache/
|
||||||
|
init.sls
|
||||||
|
config.sls
|
||||||
|
saltcheck-tests/
|
||||||
|
pkg_and_mods.tst
|
||||||
|
config.tst
|
||||||
|
|
||||||
|
|
||||||
|
Saltcheck Test Syntax:
|
||||||
|
|
||||||
|
Unique-ID:
|
||||||
|
module_and_function:
|
||||||
|
args:
|
||||||
|
kwargs:
|
||||||
|
assertion:
|
||||||
|
expected-return:
|
||||||
|
|
||||||
|
|
||||||
|
Example test 1:
|
||||||
|
|
||||||
|
echo-test-hello:
|
||||||
|
module_and_function: test.echo
|
||||||
|
args:
|
||||||
|
- "hello"
|
||||||
|
kwargs:
|
||||||
|
assertion: assertEqual
|
||||||
|
expected-return: 'hello'
|
||||||
|
|
||||||
|
|
||||||
|
:codeauthor: William Cannon <william.cannon@gmail.com>
|
||||||
|
:maturity: new
|
||||||
|
'''
|
||||||
|
from __future__ import absolute_import
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import yaml
|
||||||
|
try:
|
||||||
|
import salt.utils
|
||||||
|
import salt.client
|
||||||
|
import salt.exceptions
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
__virtualname__ = 'saltcheck'
|
||||||
|
|
||||||
|
|
||||||
|
def __virtual__():
|
||||||
|
'''
|
||||||
|
Check dependencies - may be useful in future
|
||||||
|
'''
|
||||||
|
return __virtualname__
|
||||||
|
|
||||||
|
|
||||||
|
def update_master_cache():
|
||||||
|
'''
|
||||||
|
Updates the master cache onto the minion - transfers all salt-check-tests
|
||||||
|
Should be done one time before running tests, and if tests are updated
|
||||||
|
Can be automated by setting "auto_update_master_cache: True" in minion config
|
||||||
|
|
||||||
|
CLI Example:
|
||||||
|
salt '*' saltcheck.update_master_cache
|
||||||
|
'''
|
||||||
|
__salt__['cp.cache_master']()
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def run_test(**kwargs):
|
||||||
|
'''
|
||||||
|
Execute one saltcheck test and return result
|
||||||
|
|
||||||
|
:param keyword arg test:
|
||||||
|
CLI Example::
|
||||||
|
salt '*' saltcheck.run_test
|
||||||
|
test='{"module_and_function": "test.echo",
|
||||||
|
"assertion": "assertEqual",
|
||||||
|
"expected-return": "This works!",
|
||||||
|
"args":["This works!"] }'
|
||||||
|
'''
|
||||||
|
# salt converts the string to a dictionary auto-magically
|
||||||
|
scheck = SaltCheck()
|
||||||
|
test = kwargs.get('test', None)
|
||||||
|
if test and isinstance(test, dict):
|
||||||
|
return scheck.run_test(test)
|
||||||
|
else:
|
||||||
|
return "Test must be a dictionary"
|
||||||
|
|
||||||
|
|
||||||
|
def run_state_tests(state):
|
||||||
|
'''
|
||||||
|
Execute all tests for a salt state and return results
|
||||||
|
Nested states will also be tested
|
||||||
|
|
||||||
|
:param str state: the name of a user defined state
|
||||||
|
|
||||||
|
CLI Example::
|
||||||
|
salt '*' saltcheck.run_state_tests postfix
|
||||||
|
'''
|
||||||
|
scheck = SaltCheck()
|
||||||
|
paths = scheck.get_state_search_path_list()
|
||||||
|
stl = StateTestLoader(search_paths=paths)
|
||||||
|
results = {}
|
||||||
|
sls_list = _get_state_sls(state)
|
||||||
|
for state_name in sls_list:
|
||||||
|
mypath = stl.convert_sls_to_path(state_name)
|
||||||
|
stl.add_test_files_for_sls(mypath)
|
||||||
|
stl.load_test_suite()
|
||||||
|
results_dict = {}
|
||||||
|
for key, value in stl.test_dict.items():
|
||||||
|
result = scheck.run_test(value)
|
||||||
|
results_dict[key] = result
|
||||||
|
results[state_name] = results_dict
|
||||||
|
passed = 0
|
||||||
|
failed = 0
|
||||||
|
missing_tests = 0
|
||||||
|
for state in results:
|
||||||
|
if len(results[state].items()) == 0:
|
||||||
|
missing_tests = missing_tests + 1
|
||||||
|
else:
|
||||||
|
for dummy, val in results[state].items():
|
||||||
|
log.info("dummy={}, val={}".format(dummy, val))
|
||||||
|
if val.startswith('Pass'):
|
||||||
|
passed = passed + 1
|
||||||
|
if val.startswith('Fail'):
|
||||||
|
failed = failed + 1
|
||||||
|
out_list = []
|
||||||
|
for key, value in results.items():
|
||||||
|
out_list.append({key: value})
|
||||||
|
out_list.sort()
|
||||||
|
out_list.append({"TEST RESULTS": {'Passed': passed, 'Failed': failed, 'Missing Tests': missing_tests}})
|
||||||
|
return out_list
|
||||||
|
|
||||||
|
|
||||||
|
def run_highstate_tests():
|
||||||
|
'''
|
||||||
|
Execute all tests for a salt highstate and return results
|
||||||
|
|
||||||
|
CLI Example::
|
||||||
|
salt '*' saltcheck.run_highstate_tests
|
||||||
|
'''
|
||||||
|
scheck = SaltCheck()
|
||||||
|
paths = scheck.get_state_search_path_list()
|
||||||
|
stl = StateTestLoader(search_paths=paths)
|
||||||
|
results = {}
|
||||||
|
sls_list = _get_top_states()
|
||||||
|
all_states = []
|
||||||
|
for top_state in sls_list:
|
||||||
|
sls_list = _get_state_sls(top_state)
|
||||||
|
for state in sls_list:
|
||||||
|
if state not in all_states:
|
||||||
|
all_states.append(state)
|
||||||
|
|
||||||
|
for state_name in all_states:
|
||||||
|
mypath = stl.convert_sls_to_path(state_name)
|
||||||
|
stl.add_test_files_for_sls(mypath)
|
||||||
|
stl.load_test_suite()
|
||||||
|
results_dict = {}
|
||||||
|
for key, value in stl.test_dict.items():
|
||||||
|
result = scheck.run_test(value)
|
||||||
|
results_dict[key] = result
|
||||||
|
results[state_name] = results_dict
|
||||||
|
passed = 0
|
||||||
|
failed = 0
|
||||||
|
missing_tests = 0
|
||||||
|
for state in results:
|
||||||
|
if len(results[state].items()) == 0:
|
||||||
|
missing_tests = missing_tests + 1
|
||||||
|
else:
|
||||||
|
for dummy, val in results[state].items():
|
||||||
|
log.info("dummy={}, val={}".format(dummy, val))
|
||||||
|
if val.startswith('Pass'):
|
||||||
|
passed = passed + 1
|
||||||
|
if val.startswith('Fail'):
|
||||||
|
failed = failed + 1
|
||||||
|
out_list = []
|
||||||
|
for key, value in results.items():
|
||||||
|
out_list.append({key: value})
|
||||||
|
out_list.sort()
|
||||||
|
out_list.append({"TEST RESULTS": {'Passed': passed, 'Failed': failed, 'Missing Tests': missing_tests}})
|
||||||
|
return out_list
|
||||||
|
|
||||||
|
|
||||||
|
def _is_valid_module(module):
|
||||||
|
'''return a list of all modules available on minion'''
|
||||||
|
modules = __salt__['sys.list_modules']()
|
||||||
|
return bool(module in modules)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_auto_update_cache_value():
|
||||||
|
'''return the config value of auto_update_master_cache'''
|
||||||
|
__salt__['config.get']('auto_update_master_cache')
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def _is_valid_function(module_name, function):
|
||||||
|
'''Determine if a function is valid for a module'''
|
||||||
|
try:
|
||||||
|
functions = __salt__['sys.list_functions'](module_name)
|
||||||
|
except salt.exceptions.SaltException:
|
||||||
|
functions = ["unable to look up functions"]
|
||||||
|
return "{0}.{1}".format(module_name, function) in functions
|
||||||
|
|
||||||
|
|
||||||
|
def _get_top_states():
|
||||||
|
''' equivalent to a salt cli: salt web state.show_top'''
|
||||||
|
alt_states = []
|
||||||
|
try:
|
||||||
|
returned = __salt__['state.show_top']()
|
||||||
|
for i in returned['base']:
|
||||||
|
alt_states.append(i)
|
||||||
|
except Exception:
|
||||||
|
raise
|
||||||
|
# log.info("top states: {}".format(alt_states))
|
||||||
|
return alt_states
|
||||||
|
|
||||||
|
|
||||||
|
def _get_state_sls(state):
|
||||||
|
''' equivalent to a salt cli: salt web state.show_low_sls STATE'''
|
||||||
|
sls_list_state = []
|
||||||
|
try:
|
||||||
|
returned = __salt__['state.show_low_sls'](state)
|
||||||
|
for i in returned:
|
||||||
|
if i['__sls__'] not in sls_list_state:
|
||||||
|
sls_list_state.append(i['__sls__'])
|
||||||
|
except Exception:
|
||||||
|
raise
|
||||||
|
return sls_list_state
|
||||||
|
|
||||||
|
|
||||||
|
class SaltCheck(object):
|
||||||
|
'''
|
||||||
|
This class implements the saltcheck
|
||||||
|
'''
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
# self.sls_list_top = []
|
||||||
|
self.sls_list_state = []
|
||||||
|
self.modules = []
|
||||||
|
self.results_dict = {}
|
||||||
|
self.results_dict_summary = {}
|
||||||
|
self.assertions_list = '''assertEqual assertNotEqual
|
||||||
|
assertTrue assertFalse
|
||||||
|
assertIn assertNotIn
|
||||||
|
assertGreater
|
||||||
|
assertGreaterEqual
|
||||||
|
assertLess assertLessEqual'''.split()
|
||||||
|
self.auto_update_master_cache = _get_auto_update_cache_value
|
||||||
|
# self.salt_lc = salt.client.Caller(mopts=__opts__)
|
||||||
|
self.salt_lc = salt.client.Caller()
|
||||||
|
if self.auto_update_master_cache:
|
||||||
|
update_master_cache()
|
||||||
|
|
||||||
|
def __is_valid_test(self, test_dict):
|
||||||
|
'''Determine if a test contains:
|
||||||
|
a test name,
|
||||||
|
a valid module and function,
|
||||||
|
a valid assertion,
|
||||||
|
an expected return value'''
|
||||||
|
tots = 0 # need total of >= 6 to be a valid test
|
||||||
|
m_and_f = test_dict.get('module_and_function', None)
|
||||||
|
assertion = test_dict.get('assertion', None)
|
||||||
|
expected_return = test_dict.get('expected-return', None)
|
||||||
|
log.info("__is_valid_test has test: {}".format(test_dict))
|
||||||
|
if m_and_f:
|
||||||
|
tots += 1
|
||||||
|
module, function = m_and_f.split('.')
|
||||||
|
if _is_valid_module(module):
|
||||||
|
tots += 1
|
||||||
|
if _is_valid_function(module, function):
|
||||||
|
tots += 1
|
||||||
|
log.info("__is_valid_test has valid m_and_f")
|
||||||
|
if assertion:
|
||||||
|
tots += 1
|
||||||
|
if assertion in self.assertions_list:
|
||||||
|
tots += 1
|
||||||
|
log.info("__is_valid_test has valid_assertion")
|
||||||
|
if expected_return:
|
||||||
|
tots += 1
|
||||||
|
log.info("__is_valid_test has valid_expected_return")
|
||||||
|
log.info("__is_valid_test score: {}".format(tots))
|
||||||
|
return tots >= 6
|
||||||
|
|
||||||
|
def call_salt_command(self,
|
||||||
|
fun,
|
||||||
|
args,
|
||||||
|
kwargs):
|
||||||
|
'''Generic call of salt Caller command'''
|
||||||
|
value = False
|
||||||
|
try:
|
||||||
|
if args and kwargs:
|
||||||
|
value = self.salt_lc.cmd(fun, *args, **kwargs)
|
||||||
|
elif args and not kwargs:
|
||||||
|
value = self.salt_lc.cmd(fun, *args)
|
||||||
|
elif not args and kwargs:
|
||||||
|
value = self.salt_lc.cmd(fun, **kwargs)
|
||||||
|
else:
|
||||||
|
value = self.salt_lc.cmd(fun)
|
||||||
|
except salt.exceptions.SaltException:
|
||||||
|
raise
|
||||||
|
except Exception:
|
||||||
|
raise
|
||||||
|
return value
|
||||||
|
|
||||||
|
def run_test(self, test_dict):
|
||||||
|
'''Run a single saltcheck test'''
|
||||||
|
if self.__is_valid_test(test_dict):
|
||||||
|
mod_and_func = test_dict['module_and_function']
|
||||||
|
args = test_dict.get('args', None)
|
||||||
|
kwargs = test_dict.get('kwargs', None)
|
||||||
|
assertion = test_dict['assertion']
|
||||||
|
expected_return = test_dict['expected-return']
|
||||||
|
actual_return = self.call_salt_command(mod_and_func, args, kwargs)
|
||||||
|
if assertion != "assertIn":
|
||||||
|
expected_return = self.cast_expected_to_returned_type(expected_return, actual_return)
|
||||||
|
if assertion == "assertEqual":
|
||||||
|
value = self.__assert_equal(expected_return, actual_return)
|
||||||
|
elif assertion == "assertNotEqual":
|
||||||
|
value = self.__assert_not_equal(expected_return, actual_return)
|
||||||
|
elif assertion == "assertTrue":
|
||||||
|
value = self.__assert_true(expected_return)
|
||||||
|
elif assertion == "assertFalse":
|
||||||
|
value = self.__assert_false(expected_return)
|
||||||
|
elif assertion == "assertIn":
|
||||||
|
value = self.__assert_in(expected_return, actual_return)
|
||||||
|
elif assertion == "assertNotIn":
|
||||||
|
value = self.__assert_not_in(expected_return, actual_return)
|
||||||
|
elif assertion == "assertGreater":
|
||||||
|
value = self.__assert_greater(expected_return, actual_return)
|
||||||
|
elif assertion == "assertGreaterEqual":
|
||||||
|
value = self.__assert_greater_equal(expected_return, actual_return)
|
||||||
|
elif assertion == "assertLess":
|
||||||
|
value = self.__assert_less(expected_return, actual_return)
|
||||||
|
elif assertion == "assertLessEqual":
|
||||||
|
value = self.__assert_less_equal(expected_return, actual_return)
|
||||||
|
else:
|
||||||
|
value = "Fail - bas assertion"
|
||||||
|
else:
|
||||||
|
return "Fail - invalid test"
|
||||||
|
return value
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def cast_expected_to_returned_type(expected, returned):
|
||||||
|
'''
|
||||||
|
Determine the type of variable returned
|
||||||
|
Cast the expected to the type of variable returned
|
||||||
|
'''
|
||||||
|
ret_type = type(returned)
|
||||||
|
new_expected = expected
|
||||||
|
if expected == "False" and ret_type == bool:
|
||||||
|
expected = False
|
||||||
|
try:
|
||||||
|
new_expected = ret_type(expected)
|
||||||
|
except ValueError:
|
||||||
|
log.info("Unable to cast expected into type of returned")
|
||||||
|
log.info("returned = {}".format(returned))
|
||||||
|
log.info("type of returned = {}".format(type(returned)))
|
||||||
|
log.info("expected = {}".format(expected))
|
||||||
|
log.info("type of expected = {}".format(type(expected)))
|
||||||
|
return new_expected
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __assert_equal(expected, returned):
|
||||||
|
'''
|
||||||
|
Test if two objects are equal
|
||||||
|
'''
|
||||||
|
result = "Pass"
|
||||||
|
|
||||||
|
try:
|
||||||
|
assert (expected == returned), "{0} is not equal to {1}".format(expected, returned)
|
||||||
|
except AssertionError as err:
|
||||||
|
result = "Fail: " + str(err)
|
||||||
|
return result
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __assert_not_equal(expected, returned):
|
||||||
|
'''
|
||||||
|
Test if two objects are not equal
|
||||||
|
'''
|
||||||
|
result = "Pass"
|
||||||
|
try:
|
||||||
|
assert (expected != returned), "{0} is equal to {1}".format(expected, returned)
|
||||||
|
except AssertionError as err:
|
||||||
|
result = "Fail: " + str(err)
|
||||||
|
return result
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __assert_true(returned):
|
||||||
|
'''
|
||||||
|
Test if an boolean is True
|
||||||
|
'''
|
||||||
|
result = "Pass"
|
||||||
|
try:
|
||||||
|
assert (returned is True), "{0} not True".format(returned)
|
||||||
|
except AssertionError as err:
|
||||||
|
result = "Fail: " + str(err)
|
||||||
|
return result
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __assert_false(returned):
|
||||||
|
'''
|
||||||
|
Test if an boolean is False
|
||||||
|
'''
|
||||||
|
result = "Pass"
|
||||||
|
if isinstance(returned, str):
|
||||||
|
try:
|
||||||
|
returned = bool(returned)
|
||||||
|
except ValueError:
|
||||||
|
raise
|
||||||
|
try:
|
||||||
|
assert (returned is False), "{0} not False".format(returned)
|
||||||
|
except AssertionError as err:
|
||||||
|
result = "Fail: " + str(err)
|
||||||
|
return result
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __assert_in(expected, returned):
|
||||||
|
'''
|
||||||
|
Test if a value is in the list of returned values
|
||||||
|
'''
|
||||||
|
result = "Pass"
|
||||||
|
try:
|
||||||
|
assert (expected in returned), "{0} not False".format(returned)
|
||||||
|
except AssertionError as err:
|
||||||
|
result = "Fail: " + str(err)
|
||||||
|
return result
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __assert_not_in(expected, returned):
|
||||||
|
'''
|
||||||
|
Test if a value is not in the list of returned values
|
||||||
|
'''
|
||||||
|
result = "Pass"
|
||||||
|
try:
|
||||||
|
assert (expected not in returned), "{0} not False".format(returned)
|
||||||
|
except AssertionError as err:
|
||||||
|
result = "Fail: " + str(err)
|
||||||
|
return result
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __assert_greater(expected, returned):
|
||||||
|
'''
|
||||||
|
Test if a value is greater than the returned value
|
||||||
|
'''
|
||||||
|
result = "Pass"
|
||||||
|
try:
|
||||||
|
assert (expected > returned), "{0} not False".format(returned)
|
||||||
|
except AssertionError as err:
|
||||||
|
result = "Fail: " + str(err)
|
||||||
|
return result
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __assert_greater_equal(expected, returned):
|
||||||
|
'''
|
||||||
|
Test if a value is greater than or equal to the returned value
|
||||||
|
'''
|
||||||
|
result = "Pass"
|
||||||
|
try:
|
||||||
|
assert (expected >= returned), "{0} not False".format(returned)
|
||||||
|
except AssertionError as err:
|
||||||
|
result = "Fail: " + str(err)
|
||||||
|
return result
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __assert_less(expected, returned):
|
||||||
|
'''
|
||||||
|
Test if a value is less than the returned value
|
||||||
|
'''
|
||||||
|
result = "Pass"
|
||||||
|
try:
|
||||||
|
assert (expected < returned), "{0} not False".format(returned)
|
||||||
|
except AssertionError as err:
|
||||||
|
result = "Fail: " + str(err)
|
||||||
|
return result
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __assert_less_equal(expected, returned):
|
||||||
|
'''
|
||||||
|
Test if a value is less than or equal to the returned value
|
||||||
|
'''
|
||||||
|
result = "Pass"
|
||||||
|
try:
|
||||||
|
assert (expected <= returned), "{0} not False".format(returned)
|
||||||
|
except AssertionError as err:
|
||||||
|
result = "Fail: " + str(err)
|
||||||
|
return result
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_state_search_path_list():
|
||||||
|
'''For the state file system, return a
|
||||||
|
list of paths to search for states'''
|
||||||
|
# state cache should be updated before running this method
|
||||||
|
search_list = []
|
||||||
|
cachedir = __opts__.get('cachedir', None)
|
||||||
|
environment = __opts__['environment']
|
||||||
|
if environment:
|
||||||
|
path = cachedir + os.sep + "files" + os.sep + environment
|
||||||
|
search_list.append(path)
|
||||||
|
path = cachedir + os.sep + "files" + os.sep + "base"
|
||||||
|
search_list.append(path)
|
||||||
|
return search_list
|
||||||
|
|
||||||
|
|
||||||
|
class StateTestLoader(object):
|
||||||
|
'''
|
||||||
|
Class loads in test files for a state
|
||||||
|
e.g. state_dir/saltcheck-tests/[1.tst, 2.tst, 3.tst]
|
||||||
|
'''
|
||||||
|
|
||||||
|
def __init__(self, search_paths):
|
||||||
|
self.search_paths = search_paths
|
||||||
|
self.path_type = None
|
||||||
|
self.test_files = [] # list of file paths
|
||||||
|
self.test_dict = {}
|
||||||
|
|
||||||
|
def load_test_suite(self):
|
||||||
|
'''load tests either from one file, or a set of files'''
|
||||||
|
self.test_dict = {}
|
||||||
|
for myfile in self.test_files:
|
||||||
|
self.load_file(myfile)
|
||||||
|
self.test_files = []
|
||||||
|
|
||||||
|
def load_file(self, filepath):
|
||||||
|
'''
|
||||||
|
loads in one test file
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
with salt.utils.files.fopen(filepath, 'r') as myfile:
|
||||||
|
# with open(filepath, 'r') as myfile:
|
||||||
|
contents_yaml = yaml.load(myfile)
|
||||||
|
for key, value in contents_yaml.items():
|
||||||
|
self.test_dict[key] = value
|
||||||
|
except:
|
||||||
|
raise
|
||||||
|
return
|
||||||
|
|
||||||
|
def gather_files(self, filepath):
|
||||||
|
'''gather files for a test suite'''
|
||||||
|
self.test_files = []
|
||||||
|
log.info("gather_files: {}".format(time.time()))
|
||||||
|
filepath = filepath + os.sep + 'saltcheck-tests'
|
||||||
|
rootdir = filepath
|
||||||
|
# for dirname, subdirlist, filelist in os.walk(rootdir):
|
||||||
|
for dirname, dummy, filelist in os.walk(rootdir):
|
||||||
|
for fname in filelist:
|
||||||
|
if fname.endswith('.tst'):
|
||||||
|
start_path = dirname + os.sep + fname
|
||||||
|
full_path = os.path.abspath(start_path)
|
||||||
|
self.test_files.append(full_path)
|
||||||
|
return
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def convert_sls_to_paths(sls_list):
|
||||||
|
'''Converting sls to paths'''
|
||||||
|
new_sls_list = []
|
||||||
|
for sls in sls_list:
|
||||||
|
sls = sls.replace(".", os.sep)
|
||||||
|
new_sls_list.append(sls)
|
||||||
|
return new_sls_list
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def convert_sls_to_path(sls):
|
||||||
|
'''Converting sls to paths'''
|
||||||
|
sls = sls.replace(".", os.sep)
|
||||||
|
return sls
|
||||||
|
|
||||||
|
def add_test_files_for_sls(self, sls_path):
|
||||||
|
'''Adding test files'''
|
||||||
|
for path in self.search_paths:
|
||||||
|
full_path = path + os.sep + sls_path
|
||||||
|
rootdir = full_path
|
||||||
|
if os.path.isdir(full_path):
|
||||||
|
log.info("searching path= {}".format(full_path))
|
||||||
|
# for dirname, subdirlist, filelist in os.walk(rootdir, topdown=True):
|
||||||
|
for dirname, subdirlist, dummy in os.walk(rootdir, topdown=True):
|
||||||
|
if "saltcheck-tests" in subdirlist:
|
||||||
|
self.gather_files(dirname)
|
||||||
|
log.info("test_files list: {}".format(self.test_files))
|
||||||
|
log.info("found subdir match in = {}".format(dirname))
|
||||||
|
else:
|
||||||
|
log.info("did not find subdir match in = {}".format(dirname))
|
||||||
|
del subdirlist[:]
|
||||||
|
else:
|
||||||
|
log.info("path is not a directory= {}".format(full_path))
|
||||||
|
return
|
@ -977,7 +977,7 @@ def install(name=None, refresh=False, pkgs=None, **kwargs):
|
|||||||
# Version is ignored
|
# Version is ignored
|
||||||
salt '*' pkg.install pkgs="['foo', 'bar']" version=1.2.3
|
salt '*' pkg.install pkgs="['foo', 'bar']" version=1.2.3
|
||||||
|
|
||||||
If passed with a comma seperated list in the ``name`` parameter, the
|
If passed with a comma separated list in the ``name`` parameter, the
|
||||||
version will apply to all packages in the list.
|
version will apply to all packages in the list.
|
||||||
|
|
||||||
CLI Example:
|
CLI Example:
|
||||||
@ -1286,7 +1286,7 @@ def install(name=None, refresh=False, pkgs=None, **kwargs):
|
|||||||
use_msiexec, msiexec = _get_msiexec(pkginfo[version_num].get('msiexec', False))
|
use_msiexec, msiexec = _get_msiexec(pkginfo[version_num].get('msiexec', False))
|
||||||
|
|
||||||
# Build cmd and arguments
|
# Build cmd and arguments
|
||||||
# cmd and arguments must be seperated for use with the task scheduler
|
# cmd and arguments must be separated for use with the task scheduler
|
||||||
if use_msiexec:
|
if use_msiexec:
|
||||||
cmd = msiexec
|
cmd = msiexec
|
||||||
arguments = ['/i', cached_pkg]
|
arguments = ['/i', cached_pkg]
|
||||||
@ -1328,7 +1328,9 @@ def install(name=None, refresh=False, pkgs=None, **kwargs):
|
|||||||
|
|
||||||
# Run Scheduled Task
|
# Run Scheduled Task
|
||||||
# Special handling for installing salt
|
# Special handling for installing salt
|
||||||
if pkg_name in ['salt-minion', 'salt-minion-py3']:
|
if re.search(r'salt[\s_.-]*minion',
|
||||||
|
pkg_name,
|
||||||
|
flags=re.IGNORECASE + re.UNICODE) is not None:
|
||||||
ret[pkg_name] = {'install status': 'task started'}
|
ret[pkg_name] = {'install status': 'task started'}
|
||||||
if not __salt__['task.run'](name='update-salt-software'):
|
if not __salt__['task.run'](name='update-salt-software'):
|
||||||
log.error('Failed to install {0}'.format(pkg_name))
|
log.error('Failed to install {0}'.format(pkg_name))
|
||||||
@ -1360,7 +1362,8 @@ def install(name=None, refresh=False, pkgs=None, **kwargs):
|
|||||||
else:
|
else:
|
||||||
|
|
||||||
# Combine cmd and arguments
|
# Combine cmd and arguments
|
||||||
cmd = [cmd].extend(arguments)
|
cmd = [cmd]
|
||||||
|
cmd.extend(arguments)
|
||||||
|
|
||||||
# Launch the command
|
# Launch the command
|
||||||
result = __salt__['cmd.run_all'](cmd,
|
result = __salt__['cmd.run_all'](cmd,
|
||||||
|
@ -108,7 +108,7 @@ import pprint
|
|||||||
import textwrap
|
import textwrap
|
||||||
|
|
||||||
# Import salt libs
|
# Import salt libs
|
||||||
import salt.utils
|
import salt.utils.color
|
||||||
import salt.utils.stringutils
|
import salt.utils.stringutils
|
||||||
import salt.output
|
import salt.output
|
||||||
from salt.utils.locales import sdecode
|
from salt.utils.locales import sdecode
|
||||||
@ -158,7 +158,7 @@ def output(data, **kwargs): # pylint: disable=unused-argument
|
|||||||
def _format_host(host, data):
|
def _format_host(host, data):
|
||||||
host = sdecode(host)
|
host = sdecode(host)
|
||||||
|
|
||||||
colors = salt.utils.get_colors(
|
colors = salt.utils.color.get_colors(
|
||||||
__opts__.get('color'),
|
__opts__.get('color'),
|
||||||
__opts__.get('color_theme'))
|
__opts__.get('color_theme'))
|
||||||
tabular = __opts__.get('state_tabular', False)
|
tabular = __opts__.get('state_tabular', False)
|
||||||
|
@ -8,9 +8,9 @@ The ``salt-key`` command makes use of this outputter to format its output.
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
# Import salt libs
|
# Import salt libs
|
||||||
import salt.utils
|
|
||||||
import salt.output
|
import salt.output
|
||||||
from salt.utils.locales import sdecode
|
from salt.utils.locales import sdecode
|
||||||
|
import salt.utils.color
|
||||||
|
|
||||||
|
|
||||||
def output(data, **kwargs): # pylint: disable=unused-argument
|
def output(data, **kwargs): # pylint: disable=unused-argument
|
||||||
@ -18,7 +18,7 @@ def output(data, **kwargs): # pylint: disable=unused-argument
|
|||||||
Read in the dict structure generated by the salt key API methods and
|
Read in the dict structure generated by the salt key API methods and
|
||||||
print the structure.
|
print the structure.
|
||||||
'''
|
'''
|
||||||
color = salt.utils.get_colors(
|
color = salt.utils.color.get_colors(
|
||||||
__opts__.get('color'),
|
__opts__.get('color'),
|
||||||
__opts__.get('color_theme'))
|
__opts__.get('color_theme'))
|
||||||
strip_colors = __opts__.get('strip_colors', True)
|
strip_colors = __opts__.get('strip_colors', True)
|
||||||
|
@ -29,9 +29,9 @@ from numbers import Number
|
|||||||
|
|
||||||
# Import salt libs
|
# Import salt libs
|
||||||
import salt.output
|
import salt.output
|
||||||
|
import salt.utils.color
|
||||||
import salt.utils.locales
|
import salt.utils.locales
|
||||||
import salt.utils.odict
|
import salt.utils.odict
|
||||||
from salt.utils import get_colors
|
|
||||||
from salt.ext.six import string_types
|
from salt.ext.six import string_types
|
||||||
|
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ class NestDisplay(object):
|
|||||||
'''
|
'''
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.__dict__.update(
|
self.__dict__.update(
|
||||||
get_colors(
|
salt.utils.color.get_colors(
|
||||||
__opts__.get('color'),
|
__opts__.get('color'),
|
||||||
__opts__.get('color_theme')
|
__opts__.get('color_theme')
|
||||||
)
|
)
|
||||||
|
@ -15,7 +15,7 @@ Example output::
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
# Import salt libs
|
# Import salt libs
|
||||||
import salt.utils
|
import salt.utils.color
|
||||||
|
|
||||||
# Import 3rd-party libs
|
# Import 3rd-party libs
|
||||||
from salt.ext import six
|
from salt.ext import six
|
||||||
@ -26,7 +26,7 @@ class NestDisplay(object):
|
|||||||
Create generator for nested output
|
Create generator for nested output
|
||||||
'''
|
'''
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.colors = salt.utils.get_colors(
|
self.colors = salt.utils.color.get_colors(
|
||||||
__opts__.get(u'color'),
|
__opts__.get(u'color'),
|
||||||
__opts__.get(u'color_theme'))
|
__opts__.get(u'color_theme'))
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ and should not be called directly.
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
# Import Salt libs
|
# Import Salt libs
|
||||||
import salt.utils
|
import salt.utils.color
|
||||||
|
|
||||||
# Import 3rd-party libs
|
# Import 3rd-party libs
|
||||||
from salt.ext import six
|
from salt.ext import six
|
||||||
@ -27,7 +27,7 @@ def output(data, **kwargs): # pylint: disable=unused-argument
|
|||||||
'''
|
'''
|
||||||
Format the data for printing stage information from the overstate system
|
Format the data for printing stage information from the overstate system
|
||||||
'''
|
'''
|
||||||
colors = salt.utils.get_colors(
|
colors = salt.utils.color.get_colors(
|
||||||
__opts__.get('color'),
|
__opts__.get('color'),
|
||||||
__opts__.get('color_theme'))
|
__opts__.get('color_theme'))
|
||||||
ostr = ''
|
ostr = ''
|
||||||
|
@ -42,12 +42,10 @@ from functools import reduce # pylint: disable=redefined-builtin
|
|||||||
|
|
||||||
# Import salt libs
|
# Import salt libs
|
||||||
import salt.output
|
import salt.output
|
||||||
import salt.utils.locales
|
|
||||||
from salt.ext.six import string_types
|
from salt.ext.six import string_types
|
||||||
from salt.utils import get_colors
|
from salt.ext.six.moves import map, zip # pylint: disable=redefined-builtin
|
||||||
from salt.ext.six.moves import map # pylint: disable=redefined-builtin
|
import salt.utils.color
|
||||||
from salt.ext.six.moves import zip # pylint: disable=redefined-builtin
|
import salt.utils.locales
|
||||||
|
|
||||||
|
|
||||||
__virtualname__ = 'table'
|
__virtualname__ = 'table'
|
||||||
|
|
||||||
@ -78,7 +76,7 @@ class TableDisplay(object):
|
|||||||
width=50, # column max width
|
width=50, # column max width
|
||||||
wrapfunc=None): # function wrapper
|
wrapfunc=None): # function wrapper
|
||||||
self.__dict__.update(
|
self.__dict__.update(
|
||||||
get_colors(
|
salt.utils.color.get_colors(
|
||||||
__opts__.get('color'),
|
__opts__.get('color'),
|
||||||
__opts__.get('color_theme')
|
__opts__.get('color_theme')
|
||||||
)
|
)
|
||||||
|
@ -1303,6 +1303,23 @@ def latest(name,
|
|||||||
'if it does not already exist).',
|
'if it does not already exist).',
|
||||||
comments
|
comments
|
||||||
)
|
)
|
||||||
|
remote_tags = set([
|
||||||
|
x.replace('refs/tags/', '') for x in __salt__['git.ls_remote'](
|
||||||
|
cwd=target,
|
||||||
|
remote=remote,
|
||||||
|
opts="--tags",
|
||||||
|
user=user,
|
||||||
|
password=password,
|
||||||
|
identity=identity,
|
||||||
|
saltenv=__env__,
|
||||||
|
ignore_retcode=True,
|
||||||
|
).keys() if '^{}' not in x
|
||||||
|
])
|
||||||
|
if set(all_local_tags) != remote_tags:
|
||||||
|
has_remote_rev = False
|
||||||
|
ret['changes']['new_tags'] = list(remote_tags.symmetric_difference(
|
||||||
|
all_local_tags
|
||||||
|
))
|
||||||
|
|
||||||
if not has_remote_rev:
|
if not has_remote_rev:
|
||||||
try:
|
try:
|
||||||
|
@ -126,7 +126,6 @@ import salt.utils.dictupdate
|
|||||||
import salt.utils.versions
|
import salt.utils.versions
|
||||||
import salt.version
|
import salt.version
|
||||||
from salt.utils.decorators.jinja import jinja_filter
|
from salt.utils.decorators.jinja import jinja_filter
|
||||||
from salt.textformat import TextFormat
|
|
||||||
from salt.exceptions import (
|
from salt.exceptions import (
|
||||||
CommandExecutionError, SaltClientError,
|
CommandExecutionError, SaltClientError,
|
||||||
CommandNotFoundError, SaltSystemExit,
|
CommandNotFoundError, SaltSystemExit,
|
||||||
@ -138,83 +137,6 @@ log = logging.getLogger(__name__)
|
|||||||
_empty = object()
|
_empty = object()
|
||||||
|
|
||||||
|
|
||||||
def get_color_theme(theme):
|
|
||||||
'''
|
|
||||||
Return the color theme to use
|
|
||||||
'''
|
|
||||||
# Keep the heavy lifting out of the module space
|
|
||||||
import yaml
|
|
||||||
if not os.path.isfile(theme):
|
|
||||||
log.warning('The named theme {0} if not available'.format(theme))
|
|
||||||
|
|
||||||
# Late import to avoid circular import.
|
|
||||||
import salt.utils.files
|
|
||||||
try:
|
|
||||||
with salt.utils.files.fopen(theme, 'rb') as fp_:
|
|
||||||
colors = yaml.safe_load(fp_.read())
|
|
||||||
ret = {}
|
|
||||||
for color in colors:
|
|
||||||
ret[color] = '\033[{0}m'.format(colors[color])
|
|
||||||
if not isinstance(colors, dict):
|
|
||||||
log.warning('The theme file {0} is not a dict'.format(theme))
|
|
||||||
return {}
|
|
||||||
return ret
|
|
||||||
except Exception:
|
|
||||||
log.warning('Failed to read the color theme {0}'.format(theme))
|
|
||||||
return {}
|
|
||||||
|
|
||||||
|
|
||||||
def get_colors(use=True, theme=None):
|
|
||||||
'''
|
|
||||||
Return the colors as an easy to use dict. Pass `False` to deactivate all
|
|
||||||
colors by setting them to empty strings. Pass a string containing only the
|
|
||||||
name of a single color to be used in place of all colors. Examples:
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
colors = get_colors() # enable all colors
|
|
||||||
no_colors = get_colors(False) # disable all colors
|
|
||||||
red_colors = get_colors('RED') # set all colors to red
|
|
||||||
'''
|
|
||||||
|
|
||||||
colors = {
|
|
||||||
'BLACK': TextFormat('black'),
|
|
||||||
'DARK_GRAY': TextFormat('bold', 'black'),
|
|
||||||
'RED': TextFormat('red'),
|
|
||||||
'LIGHT_RED': TextFormat('bold', 'red'),
|
|
||||||
'GREEN': TextFormat('green'),
|
|
||||||
'LIGHT_GREEN': TextFormat('bold', 'green'),
|
|
||||||
'YELLOW': TextFormat('yellow'),
|
|
||||||
'LIGHT_YELLOW': TextFormat('bold', 'yellow'),
|
|
||||||
'BLUE': TextFormat('blue'),
|
|
||||||
'LIGHT_BLUE': TextFormat('bold', 'blue'),
|
|
||||||
'MAGENTA': TextFormat('magenta'),
|
|
||||||
'LIGHT_MAGENTA': TextFormat('bold', 'magenta'),
|
|
||||||
'CYAN': TextFormat('cyan'),
|
|
||||||
'LIGHT_CYAN': TextFormat('bold', 'cyan'),
|
|
||||||
'LIGHT_GRAY': TextFormat('white'),
|
|
||||||
'WHITE': TextFormat('bold', 'white'),
|
|
||||||
'DEFAULT_COLOR': TextFormat('default'),
|
|
||||||
'ENDC': TextFormat('reset'),
|
|
||||||
}
|
|
||||||
if theme:
|
|
||||||
colors.update(get_color_theme(theme))
|
|
||||||
|
|
||||||
if not use:
|
|
||||||
for color in colors:
|
|
||||||
colors[color] = ''
|
|
||||||
if isinstance(use, six.string_types):
|
|
||||||
# Try to set all of the colors to the passed color
|
|
||||||
if use in colors:
|
|
||||||
for color in colors:
|
|
||||||
# except for color reset
|
|
||||||
if color == 'ENDC':
|
|
||||||
continue
|
|
||||||
colors[color] = colors[use]
|
|
||||||
|
|
||||||
return colors
|
|
||||||
|
|
||||||
|
|
||||||
def get_context(template, line, num_lines=5, marker=None):
|
def get_context(template, line, num_lines=5, marker=None):
|
||||||
'''
|
'''
|
||||||
Returns debugging context around a line in a given string
|
Returns debugging context around a line in a given string
|
||||||
@ -3435,3 +3357,49 @@ def kwargs_warn_until(kwargs,
|
|||||||
stacklevel=stacklevel,
|
stacklevel=stacklevel,
|
||||||
_version_info_=_version_info_,
|
_version_info_=_version_info_,
|
||||||
_dont_call_warnings=_dont_call_warnings)
|
_dont_call_warnings=_dont_call_warnings)
|
||||||
|
|
||||||
|
|
||||||
|
def get_color_theme(theme):
|
||||||
|
'''
|
||||||
|
Return the color theme to use
|
||||||
|
|
||||||
|
.. deprecated:: Oxygen
|
||||||
|
'''
|
||||||
|
# Late import to avoid circular import.
|
||||||
|
import salt.utils.color
|
||||||
|
import salt.utils.versions
|
||||||
|
|
||||||
|
salt.utils.versions.warn_until(
|
||||||
|
'Neon',
|
||||||
|
'Use of \'salt.utils.get_color_theme\' detected. This function has '
|
||||||
|
'been moved to \'salt.utils.color.get_color_theme\' as of Salt '
|
||||||
|
'Oxygen. This warning will be removed in Salt Neon.'
|
||||||
|
)
|
||||||
|
return salt.utils.color.get_color_theme(theme)
|
||||||
|
|
||||||
|
|
||||||
|
def get_colors(use=True, theme=None):
|
||||||
|
'''
|
||||||
|
Return the colors as an easy to use dict. Pass `False` to deactivate all
|
||||||
|
colors by setting them to empty strings. Pass a string containing only the
|
||||||
|
name of a single color to be used in place of all colors. Examples:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
colors = get_colors() # enable all colors
|
||||||
|
no_colors = get_colors(False) # disable all colors
|
||||||
|
red_colors = get_colors('RED') # set all colors to red
|
||||||
|
|
||||||
|
.. deprecated:: Oxygen
|
||||||
|
'''
|
||||||
|
# Late import to avoid circular import.
|
||||||
|
import salt.utils.color
|
||||||
|
import salt.utils.versions
|
||||||
|
|
||||||
|
salt.utils.versions.warn_until(
|
||||||
|
'Neon',
|
||||||
|
'Use of \'salt.utils.get_colors\' detected. This function has '
|
||||||
|
'been moved to \'salt.utils.color.get_colors\' as of Salt '
|
||||||
|
'Oxygen. This warning will be removed in Salt Neon.'
|
||||||
|
)
|
||||||
|
return salt.utils.color.get_colors(use=use, theme=theme)
|
||||||
|
92
salt/utils/color.py
Normal file
92
salt/utils/color.py
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
Functions used for CLI color themes.
|
||||||
|
'''
|
||||||
|
|
||||||
|
# Import Python libs
|
||||||
|
from __future__ import absolute_import
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
|
||||||
|
# Import Salt libs
|
||||||
|
from salt.ext import six
|
||||||
|
from salt.textformat import TextFormat
|
||||||
|
import salt.utils.files
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def get_color_theme(theme):
|
||||||
|
'''
|
||||||
|
Return the color theme to use
|
||||||
|
'''
|
||||||
|
# Keep the heavy lifting out of the module space
|
||||||
|
import yaml
|
||||||
|
if not os.path.isfile(theme):
|
||||||
|
log.warning('The named theme {0} if not available'.format(theme))
|
||||||
|
|
||||||
|
try:
|
||||||
|
with salt.utils.files.fopen(theme, 'rb') as fp_:
|
||||||
|
colors = yaml.safe_load(fp_.read())
|
||||||
|
ret = {}
|
||||||
|
for color in colors:
|
||||||
|
ret[color] = '\033[{0}m'.format(colors[color])
|
||||||
|
if not isinstance(colors, dict):
|
||||||
|
log.warning('The theme file {0} is not a dict'.format(theme))
|
||||||
|
return {}
|
||||||
|
return ret
|
||||||
|
except Exception:
|
||||||
|
log.warning('Failed to read the color theme {0}'.format(theme))
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
def get_colors(use=True, theme=None):
|
||||||
|
'''
|
||||||
|
Return the colors as an easy to use dict. Pass `False` to deactivate all
|
||||||
|
colors by setting them to empty strings. Pass a string containing only the
|
||||||
|
name of a single color to be used in place of all colors. Examples:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
colors = get_colors() # enable all colors
|
||||||
|
no_colors = get_colors(False) # disable all colors
|
||||||
|
red_colors = get_colors('RED') # set all colors to red
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
colors = {
|
||||||
|
'BLACK': TextFormat('black'),
|
||||||
|
'DARK_GRAY': TextFormat('bold', 'black'),
|
||||||
|
'RED': TextFormat('red'),
|
||||||
|
'LIGHT_RED': TextFormat('bold', 'red'),
|
||||||
|
'GREEN': TextFormat('green'),
|
||||||
|
'LIGHT_GREEN': TextFormat('bold', 'green'),
|
||||||
|
'YELLOW': TextFormat('yellow'),
|
||||||
|
'LIGHT_YELLOW': TextFormat('bold', 'yellow'),
|
||||||
|
'BLUE': TextFormat('blue'),
|
||||||
|
'LIGHT_BLUE': TextFormat('bold', 'blue'),
|
||||||
|
'MAGENTA': TextFormat('magenta'),
|
||||||
|
'LIGHT_MAGENTA': TextFormat('bold', 'magenta'),
|
||||||
|
'CYAN': TextFormat('cyan'),
|
||||||
|
'LIGHT_CYAN': TextFormat('bold', 'cyan'),
|
||||||
|
'LIGHT_GRAY': TextFormat('white'),
|
||||||
|
'WHITE': TextFormat('bold', 'white'),
|
||||||
|
'DEFAULT_COLOR': TextFormat('default'),
|
||||||
|
'ENDC': TextFormat('reset'),
|
||||||
|
}
|
||||||
|
if theme:
|
||||||
|
colors.update(get_color_theme(theme))
|
||||||
|
|
||||||
|
if not use:
|
||||||
|
for color in colors:
|
||||||
|
colors[color] = ''
|
||||||
|
if isinstance(use, six.string_types):
|
||||||
|
# Try to set all of the colors to the passed color
|
||||||
|
if use in colors:
|
||||||
|
for color in colors:
|
||||||
|
# except for color reset
|
||||||
|
if color == 'ENDC':
|
||||||
|
continue
|
||||||
|
colors[color] = colors[use]
|
||||||
|
|
||||||
|
return colors
|
@ -9,13 +9,13 @@ import pprint
|
|||||||
import optparse
|
import optparse
|
||||||
|
|
||||||
# Import Salt libs
|
# Import Salt libs
|
||||||
import salt.utils
|
import salt.utils.color
|
||||||
|
|
||||||
# Import 3rd-party libs
|
# Import 3rd-party libs
|
||||||
import yaml
|
import yaml
|
||||||
from salt.ext import six
|
from salt.ext import six
|
||||||
|
|
||||||
colors = salt.utils.get_colors()
|
colors = salt.utils.color.get_colors()
|
||||||
|
|
||||||
|
|
||||||
def parse():
|
def parse():
|
||||||
|
@ -49,7 +49,8 @@ import salt.minion
|
|||||||
import salt.runner
|
import salt.runner
|
||||||
import salt.output
|
import salt.output
|
||||||
import salt.version
|
import salt.version
|
||||||
import salt.utils # Can be removed once get_colors and appendproctitle are moved
|
import salt.utils # Can be removed once appendproctitle is moved
|
||||||
|
import salt.utils.color
|
||||||
import salt.utils.files
|
import salt.utils.files
|
||||||
import salt.utils.path
|
import salt.utils.path
|
||||||
import salt.utils.platform
|
import salt.utils.platform
|
||||||
@ -188,7 +189,7 @@ class TestDaemon(object):
|
|||||||
|
|
||||||
def __init__(self, parser):
|
def __init__(self, parser):
|
||||||
self.parser = parser
|
self.parser = parser
|
||||||
self.colors = salt.utils.get_colors(self.parser.options.no_colors is False)
|
self.colors = salt.utils.color.get_colors(self.parser.options.no_colors is False)
|
||||||
if salt.utils.platform.is_windows():
|
if salt.utils.platform.is_windows():
|
||||||
# There's no shell color support on windows...
|
# There's no shell color support on windows...
|
||||||
for key in self.colors:
|
for key in self.colors:
|
||||||
|
@ -9,8 +9,12 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
import tempfile
|
import tempfile
|
||||||
import textwrap
|
import textwrap
|
||||||
import pwd
|
|
||||||
import logging
|
import logging
|
||||||
|
import stat
|
||||||
|
try:
|
||||||
|
import pwd
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
# Import 3rd-party libs
|
# Import 3rd-party libs
|
||||||
import yaml
|
import yaml
|
||||||
@ -210,7 +214,6 @@ class GitFSTest(TestCase, LoaderModuleMockMixin):
|
|||||||
self.integration_base_files = os.path.join(FILES, 'file', 'base')
|
self.integration_base_files = os.path.join(FILES, 'file', 'base')
|
||||||
|
|
||||||
# Create the dir if it doesn't already exist
|
# Create the dir if it doesn't already exist
|
||||||
|
|
||||||
try:
|
try:
|
||||||
shutil.copytree(self.integration_base_files, self.tmp_repo_dir + '/')
|
shutil.copytree(self.integration_base_files, self.tmp_repo_dir + '/')
|
||||||
except OSError:
|
except OSError:
|
||||||
@ -224,6 +227,11 @@ class GitFSTest(TestCase, LoaderModuleMockMixin):
|
|||||||
|
|
||||||
if 'USERNAME' not in os.environ:
|
if 'USERNAME' not in os.environ:
|
||||||
try:
|
try:
|
||||||
|
import salt.utils
|
||||||
|
if salt.utils.is_windows():
|
||||||
|
import salt.utils.win_functions
|
||||||
|
os.environ['USERNAME'] = salt.utils.win_functions.get_current_user()
|
||||||
|
else:
|
||||||
os.environ['USERNAME'] = pwd.getpwuid(os.geteuid()).pw_name
|
os.environ['USERNAME'] = pwd.getpwuid(os.geteuid()).pw_name
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
log.error('Unable to get effective username, falling back to '
|
log.error('Unable to get effective username, falling back to '
|
||||||
@ -240,14 +248,18 @@ class GitFSTest(TestCase, LoaderModuleMockMixin):
|
|||||||
Remove the temporary git repository and gitfs cache directory to ensure
|
Remove the temporary git repository and gitfs cache directory to ensure
|
||||||
a clean environment for each test.
|
a clean environment for each test.
|
||||||
'''
|
'''
|
||||||
shutil.rmtree(self.tmp_repo_dir)
|
shutil.rmtree(self.tmp_repo_dir, onerror=self._rmtree_error)
|
||||||
shutil.rmtree(self.tmp_cachedir)
|
shutil.rmtree(self.tmp_cachedir, onerror=self._rmtree_error)
|
||||||
shutil.rmtree(self.tmp_sock_dir)
|
shutil.rmtree(self.tmp_sock_dir, onerror=self._rmtree_error)
|
||||||
del self.tmp_repo_dir
|
del self.tmp_repo_dir
|
||||||
del self.tmp_cachedir
|
del self.tmp_cachedir
|
||||||
del self.tmp_sock_dir
|
del self.tmp_sock_dir
|
||||||
del self.integration_base_files
|
del self.integration_base_files
|
||||||
|
|
||||||
|
def _rmtree_error(self, func, path, excinfo):
|
||||||
|
os.chmod(path, stat.S_IWRITE)
|
||||||
|
func(path)
|
||||||
|
|
||||||
def test_file_list(self):
|
def test_file_list(self):
|
||||||
ret = gitfs.file_list(LOAD)
|
ret = gitfs.file_list(LOAD)
|
||||||
self.assertIn('testfile', ret)
|
self.assertIn('testfile', ret)
|
||||||
|
@ -46,12 +46,57 @@ class GenesisTestCase(TestCase, LoaderModuleMockMixin):
|
|||||||
with patch.dict(genesis.__salt__, {'disk.blkid': MagicMock(return_value={})}):
|
with patch.dict(genesis.__salt__, {'disk.blkid': MagicMock(return_value={})}):
|
||||||
self.assertEqual(genesis.bootstrap('rpm', 'root', 'dir'), None)
|
self.assertEqual(genesis.bootstrap('rpm', 'root', 'dir'), None)
|
||||||
|
|
||||||
with patch.object(genesis, '_bootstrap_deb', return_value='A'):
|
common_parms = {'platform': 'deb',
|
||||||
|
'root': 'root',
|
||||||
|
'img_format': 'dir',
|
||||||
|
'arch': 'amd64',
|
||||||
|
'flavor': 'stable',
|
||||||
|
'static_qemu': 'qemu'}
|
||||||
|
|
||||||
|
param_sets = [
|
||||||
|
|
||||||
|
{'params': {},
|
||||||
|
'cmd': ['debootstrap', '--foreign', '--arch', 'amd64',
|
||||||
|
'stable', 'root', 'http://ftp.debian.org/debian/']
|
||||||
|
},
|
||||||
|
|
||||||
|
{'params': {'pkgs': 'vim'},
|
||||||
|
'cmd': ['debootstrap', '--foreign', '--arch', 'amd64',
|
||||||
|
'--include', 'vim',
|
||||||
|
'stable', 'root', 'http://ftp.debian.org/debian/']
|
||||||
|
},
|
||||||
|
|
||||||
|
{'params': {'pkgs': 'vim,emacs'},
|
||||||
|
'cmd': ['debootstrap', '--foreign', '--arch', 'amd64',
|
||||||
|
'--include', 'vim,emacs',
|
||||||
|
'stable', 'root', 'http://ftp.debian.org/debian/']
|
||||||
|
},
|
||||||
|
|
||||||
|
{'params': {'pkgs': ['vim', 'emacs']},
|
||||||
|
'cmd': ['debootstrap', '--foreign', '--arch', 'amd64',
|
||||||
|
'--include', 'vim,emacs',
|
||||||
|
'stable', 'root', 'http://ftp.debian.org/debian/']
|
||||||
|
},
|
||||||
|
|
||||||
|
{'params': {'pkgs': ['vim', 'emacs'], 'exclude_pkgs': ['vim', 'foo']},
|
||||||
|
'cmd': ['debootstrap', '--foreign', '--arch', 'amd64',
|
||||||
|
'--include', 'vim,emacs', '--exclude', 'vim,foo',
|
||||||
|
'stable', 'root', 'http://ftp.debian.org/debian/']
|
||||||
|
},
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
for param_set in param_sets:
|
||||||
|
|
||||||
with patch.dict(genesis.__salt__, {'mount.umount': MagicMock(),
|
with patch.dict(genesis.__salt__, {'mount.umount': MagicMock(),
|
||||||
'file.rmdir': MagicMock(),
|
'file.rmdir': MagicMock(),
|
||||||
'file.directory_exists': MagicMock()}):
|
'file.directory_exists': MagicMock(),
|
||||||
with patch.dict(genesis.__salt__, {'disk.blkid': MagicMock(return_value={})}):
|
'cmd.run': MagicMock(),
|
||||||
self.assertEqual(genesis.bootstrap('deb', 'root', 'dir'), None)
|
'disk.blkid': MagicMock(return_value={})}):
|
||||||
|
with patch('salt.modules.genesis.salt.utils.which', return_value=True):
|
||||||
|
param_set['params'].update(common_parms)
|
||||||
|
self.assertEqual(genesis.bootstrap(**param_set['params']), None)
|
||||||
|
genesis.__salt__['cmd.run'].assert_any_call(param_set['cmd'], python_shell=False)
|
||||||
|
|
||||||
with patch.object(genesis, '_bootstrap_pacman', return_value='A') as pacman_patch:
|
with patch.object(genesis, '_bootstrap_pacman', return_value='A') as pacman_patch:
|
||||||
with patch.dict(genesis.__salt__, {'mount.umount': MagicMock(),
|
with patch.dict(genesis.__salt__, {'mount.umount': MagicMock(),
|
||||||
|
@ -5,7 +5,10 @@
|
|||||||
|
|
||||||
# Import Python libs
|
# Import Python libs
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
try:
|
||||||
import grp
|
import grp
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
# Import Salt Testing Libs
|
# Import Salt Testing Libs
|
||||||
from tests.support.mixins import LoaderModuleMockMixin
|
from tests.support.mixins import LoaderModuleMockMixin
|
||||||
@ -13,10 +16,12 @@ from tests.support.unit import TestCase, skipIf
|
|||||||
from tests.support.mock import MagicMock, patch, NO_MOCK, NO_MOCK_REASON
|
from tests.support.mock import MagicMock, patch, NO_MOCK, NO_MOCK_REASON
|
||||||
|
|
||||||
# Import Salt Libs
|
# Import Salt Libs
|
||||||
|
import salt.utils
|
||||||
import salt.modules.groupadd as groupadd
|
import salt.modules.groupadd as groupadd
|
||||||
|
|
||||||
|
|
||||||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||||
|
@skipIf(salt.utils.is_windows(), "Module not available on Windows")
|
||||||
class GroupAddTestCase(TestCase, LoaderModuleMockMixin):
|
class GroupAddTestCase(TestCase, LoaderModuleMockMixin):
|
||||||
'''
|
'''
|
||||||
TestCase for salt.modules.groupadd
|
TestCase for salt.modules.groupadd
|
||||||
|
@ -49,9 +49,15 @@ class InspectorCollectorTestCase(TestCase):
|
|||||||
|
|
||||||
:return:
|
:return:
|
||||||
'''
|
'''
|
||||||
inspector = Inspector(cachedir='/foo/cache', piddir='/foo/pid', pidfilename='bar.pid')
|
cachedir = os.sep + os.sep.join(['foo', 'cache'])
|
||||||
self.assertEqual(inspector.dbfile, '/foo/cache/_minion_collector.db')
|
piddir = os.sep + os.sep.join(['foo', 'pid'])
|
||||||
self.assertEqual(inspector.pidfile, '/foo/pid/bar.pid')
|
inspector = Inspector(cachedir=cachedir, piddir=piddir, pidfilename='bar.pid')
|
||||||
|
self.assertEqual(
|
||||||
|
inspector.dbfile,
|
||||||
|
os.sep + os.sep.join(['foo', 'cache', '_minion_collector.db']))
|
||||||
|
self.assertEqual(
|
||||||
|
inspector.pidfile,
|
||||||
|
os.sep + os.sep.join(['foo', 'pid', 'bar.pid']))
|
||||||
|
|
||||||
def test_file_tree(self):
|
def test_file_tree(self):
|
||||||
'''
|
'''
|
||||||
@ -60,12 +66,29 @@ class InspectorCollectorTestCase(TestCase):
|
|||||||
:return:
|
:return:
|
||||||
'''
|
'''
|
||||||
|
|
||||||
inspector = Inspector(cachedir='/test', piddir='/test', pidfilename='bar.pid')
|
inspector = Inspector(cachedir=os.sep + 'test',
|
||||||
|
piddir=os.sep + 'test',
|
||||||
|
pidfilename='bar.pid')
|
||||||
tree_root = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'inspectlib', 'tree_test')
|
tree_root = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'inspectlib', 'tree_test')
|
||||||
expected_tree = (['/a/a/dummy.a', '/a/b/dummy.b', '/b/b.1', '/b/b.2', '/b/b.3'],
|
expected_tree = ([os.sep + os.sep.join(['a', 'a', 'dummy.a']),
|
||||||
['/a', '/a/a', '/a/b', '/a/c', '/b', '/c'],
|
os.sep + os.sep.join(['a', 'b', 'dummy.b']),
|
||||||
['/a/a/dummy.ln.a', '/a/b/dummy.ln.b', '/a/c/b.1', '/b/b.4',
|
os.sep + os.sep.join(['b', 'b.1']),
|
||||||
'/b/b.5', '/c/b.1', '/c/b.2', '/c/b.3'])
|
os.sep + os.sep.join(['b', 'b.2']),
|
||||||
|
os.sep + os.sep.join(['b', 'b.3'])],
|
||||||
|
[os.sep + 'a',
|
||||||
|
os.sep + os.sep.join(['a', 'a']),
|
||||||
|
os.sep + os.sep.join(['a', 'b']),
|
||||||
|
os.sep + os.sep.join(['a', 'c']),
|
||||||
|
os.sep + 'b',
|
||||||
|
os.sep + 'c'],
|
||||||
|
[os.sep + os.sep.join(['a', 'a', 'dummy.ln.a']),
|
||||||
|
os.sep + os.sep.join(['a', 'b', 'dummy.ln.b']),
|
||||||
|
os.sep + os.sep.join(['a', 'c', 'b.1']),
|
||||||
|
os.sep + os.sep.join(['b', 'b.4']),
|
||||||
|
os.sep + os.sep.join(['b', 'b.5']),
|
||||||
|
os.sep + os.sep.join(['c', 'b.1']),
|
||||||
|
os.sep + os.sep.join(['c', 'b.2']),
|
||||||
|
os.sep + os.sep.join(['c', 'b.3'])])
|
||||||
tree_result = []
|
tree_result = []
|
||||||
for chunk in inspector._get_all_files(tree_root):
|
for chunk in inspector._get_all_files(tree_root):
|
||||||
buff = []
|
buff = []
|
||||||
|
@ -5,11 +5,15 @@
|
|||||||
|
|
||||||
# Import python libs
|
# Import python libs
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
HAS_GRP = True
|
||||||
|
try:
|
||||||
import grp
|
import grp
|
||||||
|
except ImportError:
|
||||||
|
HAS_GRP = False
|
||||||
|
|
||||||
# Import Salt Testing Libs
|
# Import Salt Testing Libs
|
||||||
from tests.support.mixins import LoaderModuleMockMixin
|
from tests.support.mixins import LoaderModuleMockMixin
|
||||||
from tests.support.unit import TestCase
|
from tests.support.unit import TestCase, skipIf
|
||||||
from tests.support.mock import MagicMock, patch
|
from tests.support.mock import MagicMock, patch
|
||||||
|
|
||||||
# Import Salt Libs
|
# Import Salt Libs
|
||||||
@ -17,6 +21,7 @@ import salt.modules.mac_group as mac_group
|
|||||||
from salt.exceptions import SaltInvocationError, CommandExecutionError
|
from salt.exceptions import SaltInvocationError, CommandExecutionError
|
||||||
|
|
||||||
|
|
||||||
|
@skipIf(not HAS_GRP, "Missing required library 'grp'")
|
||||||
class MacGroupTestCase(TestCase, LoaderModuleMockMixin):
|
class MacGroupTestCase(TestCase, LoaderModuleMockMixin):
|
||||||
'''
|
'''
|
||||||
TestCase for the salt.modules.mac_group module
|
TestCase for the salt.modules.mac_group module
|
||||||
|
@ -2,10 +2,13 @@
|
|||||||
'''
|
'''
|
||||||
:codeauthor: :email:`Nicole Thomas <nicole@saltstack.com>`
|
:codeauthor: :email:`Nicole Thomas <nicole@saltstack.com>`
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# Import python libs
|
# Import python libs
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
HAS_PWD = True
|
||||||
|
try:
|
||||||
import pwd
|
import pwd
|
||||||
|
except ImportError:
|
||||||
|
HAS_PWD = False
|
||||||
|
|
||||||
# Import Salt Testing Libs
|
# Import Salt Testing Libs
|
||||||
from tests.support.mixins import LoaderModuleMockMixin
|
from tests.support.mixins import LoaderModuleMockMixin
|
||||||
@ -17,6 +20,7 @@ import salt.modules.mac_user as mac_user
|
|||||||
from salt.exceptions import SaltInvocationError, CommandExecutionError
|
from salt.exceptions import SaltInvocationError, CommandExecutionError
|
||||||
|
|
||||||
|
|
||||||
|
@skipIf(not HAS_PWD, "Missing required library 'pwd'")
|
||||||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||||
class MacUserTestCase(TestCase, LoaderModuleMockMixin):
|
class MacUserTestCase(TestCase, LoaderModuleMockMixin):
|
||||||
'''
|
'''
|
||||||
@ -26,6 +30,7 @@ class MacUserTestCase(TestCase, LoaderModuleMockMixin):
|
|||||||
def setup_loader_modules(self):
|
def setup_loader_modules(self):
|
||||||
return {mac_user: {}}
|
return {mac_user: {}}
|
||||||
|
|
||||||
|
if HAS_PWD:
|
||||||
mock_pwall = [pwd.struct_passwd(('_amavisd', '*', 83, 83, 'AMaViS Daemon',
|
mock_pwall = [pwd.struct_passwd(('_amavisd', '*', 83, 83, 'AMaViS Daemon',
|
||||||
'/var/virusmails', '/usr/bin/false')),
|
'/var/virusmails', '/usr/bin/false')),
|
||||||
pwd.struct_passwd(('_appleevents', '*', 55, 55,
|
pwd.struct_passwd(('_appleevents', '*', 55, 55,
|
||||||
|
324
tests/unit/modules/test_saltcheck.py
Normal file
324
tests/unit/modules/test_saltcheck.py
Normal file
@ -0,0 +1,324 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
'''Unit test for saltcheck execution module'''
|
||||||
|
|
||||||
|
# Import Python libs
|
||||||
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
try:
|
||||||
|
import salt.modules.saltcheck as saltcheck
|
||||||
|
except:
|
||||||
|
raise
|
||||||
|
|
||||||
|
# Import Salt Testing Libs
|
||||||
|
try:
|
||||||
|
from tests.support.mixins import LoaderModuleMockMixin
|
||||||
|
from tests.support.unit import skipIf, TestCase
|
||||||
|
from tests.support.mock import (
|
||||||
|
MagicMock,
|
||||||
|
patch,
|
||||||
|
NO_MOCK,
|
||||||
|
NO_MOCK_REASON
|
||||||
|
)
|
||||||
|
except:
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||||
|
class LinuxSysctlTestCase(TestCase, LoaderModuleMockMixin):
|
||||||
|
'''
|
||||||
|
TestCase for salt.modules.saltcheck module
|
||||||
|
'''
|
||||||
|
|
||||||
|
def setup_loader_modules(self):
|
||||||
|
return {saltcheck: {}}
|
||||||
|
|
||||||
|
def test_call_salt_command(self):
|
||||||
|
'''test simple test.echo module'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'sys.list_modules': MagicMock(return_value=['module1']),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
returned = sc_instance.call_salt_command(fun="test.echo", args=['hello'], kwargs=None)
|
||||||
|
self.assertEqual(returned, 'hello')
|
||||||
|
|
||||||
|
def test_update_master_cache(self):
|
||||||
|
'''test master cache'''
|
||||||
|
self.assertTrue(saltcheck.update_master_cache)
|
||||||
|
|
||||||
|
def test_call_salt_command2(self):
|
||||||
|
'''test simple test.echo module again'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'sys.list_modules': MagicMock(return_value=['module1']),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
returned = sc_instance.call_salt_command(fun="test.echo", args=['hello'], kwargs=None)
|
||||||
|
self.assertNotEqual(returned, 'not-hello')
|
||||||
|
|
||||||
|
def test__assert_equal1(self):
|
||||||
|
'''test'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
aaa = {'a': 1, 'b': 2}
|
||||||
|
bbb = {'a': 1, 'b': 2}
|
||||||
|
mybool = sc_instance._SaltCheck__assert_equal(aaa, bbb)
|
||||||
|
self.assertTrue(mybool)
|
||||||
|
|
||||||
|
def test__assert_equal2(self):
|
||||||
|
'''test'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
mybool = sc_instance._SaltCheck__assert_equal(False, True)
|
||||||
|
self.assertNotEqual(mybool, True)
|
||||||
|
|
||||||
|
def test__assert_not_equal1(self):
|
||||||
|
'''test'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
aaa = {'a': 1, 'b': 2}
|
||||||
|
bbb = {'a': 1, 'b': 2, 'c': 3}
|
||||||
|
mybool = sc_instance._SaltCheck__assert_not_equal(aaa, bbb)
|
||||||
|
self.assertTrue(mybool)
|
||||||
|
|
||||||
|
def test__assert_not_equal2(self):
|
||||||
|
'''test'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
aaa = {'a': 1, 'b': 2}
|
||||||
|
bbb = {'a': 1, 'b': 2}
|
||||||
|
mybool = sc_instance._SaltCheck__assert_not_equal(aaa, bbb)
|
||||||
|
self.assertNotEqual(mybool, True)
|
||||||
|
|
||||||
|
def test__assert_true1(self):
|
||||||
|
'''test'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
mybool = sc_instance._SaltCheck__assert_equal(True, True)
|
||||||
|
self.assertTrue(mybool)
|
||||||
|
|
||||||
|
def test__assert_true2(self):
|
||||||
|
'''test'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
mybool = sc_instance._SaltCheck__assert_equal(False, True)
|
||||||
|
self.assertNotEqual(mybool, True)
|
||||||
|
|
||||||
|
def test__assert_false1(self):
|
||||||
|
'''test'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
mybool = sc_instance._SaltCheck__assert_false(False)
|
||||||
|
self.assertTrue(mybool)
|
||||||
|
|
||||||
|
def test__assert_false2(self):
|
||||||
|
'''test'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
mybool = sc_instance._SaltCheck__assert_false(True)
|
||||||
|
self.assertNotEqual(mybool, True)
|
||||||
|
|
||||||
|
def test__assert_in1(self):
|
||||||
|
'''test'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
aaa = "bob"
|
||||||
|
mylist = ['alice', 'bob', 'charles', 'dana']
|
||||||
|
mybool = sc_instance._SaltCheck__assert_in(aaa, mylist)
|
||||||
|
self.assertTrue(mybool, True)
|
||||||
|
|
||||||
|
def test__assert_in2(self):
|
||||||
|
'''test'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
aaa = "elaine"
|
||||||
|
mylist = ['alice', 'bob', 'charles', 'dana']
|
||||||
|
mybool = sc_instance._SaltCheck__assert_in(aaa, mylist)
|
||||||
|
self.assertNotEqual(mybool, True)
|
||||||
|
|
||||||
|
def test__assert_not_in1(self):
|
||||||
|
'''test'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
aaa = "elaine"
|
||||||
|
mylist = ['alice', 'bob', 'charles', 'dana']
|
||||||
|
mybool = sc_instance._SaltCheck__assert_not_in(aaa, mylist)
|
||||||
|
self.assertTrue(mybool, True)
|
||||||
|
|
||||||
|
def test__assert_not_in2(self):
|
||||||
|
'''test'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
aaa = "bob"
|
||||||
|
mylist = ['alice', 'bob', 'charles', 'dana']
|
||||||
|
mybool = sc_instance._SaltCheck__assert_not_in(aaa, mylist)
|
||||||
|
self.assertNotEqual(mybool, True)
|
||||||
|
|
||||||
|
def test__assert_greater1(self):
|
||||||
|
'''test'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
aaa = 110
|
||||||
|
bbb = 100
|
||||||
|
mybool = sc_instance._SaltCheck__assert_greater(aaa, bbb)
|
||||||
|
self.assertTrue(mybool, True)
|
||||||
|
|
||||||
|
def test__assert_greater2(self):
|
||||||
|
'''test'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
aaa = 100
|
||||||
|
bbb = 110
|
||||||
|
mybool = sc_instance._SaltCheck__assert_greater(aaa, bbb)
|
||||||
|
self.assertNotEqual(mybool, True)
|
||||||
|
|
||||||
|
def test__assert_greater3(self):
|
||||||
|
'''test'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
aaa = 100
|
||||||
|
bbb = 100
|
||||||
|
mybool = sc_instance._SaltCheck__assert_greater(aaa, bbb)
|
||||||
|
self.assertNotEqual(mybool, True)
|
||||||
|
|
||||||
|
def test__assert_greater_equal1(self):
|
||||||
|
'''test'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
aaa = 110
|
||||||
|
bbb = 100
|
||||||
|
mybool = sc_instance._SaltCheck__assert_greater_equal(aaa, bbb)
|
||||||
|
self.assertTrue(mybool, True)
|
||||||
|
|
||||||
|
def test__assert_greater_equal2(self):
|
||||||
|
'''test'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
aaa = 100
|
||||||
|
bbb = 110
|
||||||
|
mybool = sc_instance._SaltCheck__assert_greater_equal(aaa, bbb)
|
||||||
|
self.assertNotEqual(mybool, True)
|
||||||
|
|
||||||
|
def test__assert_greater_equal3(self):
|
||||||
|
'''test'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
aaa = 100
|
||||||
|
bbb = 100
|
||||||
|
mybool = sc_instance._SaltCheck__assert_greater_equal(aaa, bbb)
|
||||||
|
self.assertEqual(mybool, 'Pass')
|
||||||
|
|
||||||
|
def test__assert_less1(self):
|
||||||
|
'''test'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
aaa = 99
|
||||||
|
bbb = 100
|
||||||
|
mybool = sc_instance._SaltCheck__assert_less(aaa, bbb)
|
||||||
|
self.assertTrue(mybool, True)
|
||||||
|
|
||||||
|
def test__assert_less2(self):
|
||||||
|
'''test'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
aaa = 110
|
||||||
|
bbb = 99
|
||||||
|
mybool = sc_instance._SaltCheck__assert_less(aaa, bbb)
|
||||||
|
self.assertNotEqual(mybool, True)
|
||||||
|
|
||||||
|
def test__assert_less3(self):
|
||||||
|
'''test'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
aaa = 100
|
||||||
|
bbb = 100
|
||||||
|
mybool = sc_instance._SaltCheck__assert_less(aaa, bbb)
|
||||||
|
self.assertNotEqual(mybool, True)
|
||||||
|
|
||||||
|
def test__assert_less_equal1(self):
|
||||||
|
'''test'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
aaa = 99
|
||||||
|
bbb = 100
|
||||||
|
mybool = sc_instance._SaltCheck__assert_less_equal(aaa, bbb)
|
||||||
|
self.assertTrue(mybool, True)
|
||||||
|
|
||||||
|
def test__assert_less_equal2(self):
|
||||||
|
'''test'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
aaa = 110
|
||||||
|
bbb = 99
|
||||||
|
mybool = sc_instance._SaltCheck__assert_less_equal(aaa, bbb)
|
||||||
|
self.assertNotEqual(mybool, True)
|
||||||
|
|
||||||
|
def test__assert_less_equal3(self):
|
||||||
|
'''test'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])
|
||||||
|
}):
|
||||||
|
sc_instance = saltcheck.SaltCheck()
|
||||||
|
aaa = 100
|
||||||
|
bbb = 100
|
||||||
|
mybool = sc_instance._SaltCheck__assert_less_equal(aaa, bbb)
|
||||||
|
self.assertEqual(mybool, 'Pass')
|
||||||
|
|
||||||
|
def test_run_test_1(self):
|
||||||
|
'''test'''
|
||||||
|
with patch.dict(saltcheck.__salt__, {'config.get': MagicMock(return_value=True),
|
||||||
|
'sys.list_modules': MagicMock(return_value=['test']),
|
||||||
|
'sys.list_functions': MagicMock(return_value=['test.echo']),
|
||||||
|
'cp.cache_master': MagicMock(return_value=[True])}):
|
||||||
|
returned = saltcheck.run_test(test={"module_and_function": "test.echo",
|
||||||
|
"assertion": "assertEqual",
|
||||||
|
"expected-return": "This works!",
|
||||||
|
"args": ["This works!"]
|
||||||
|
})
|
||||||
|
self.assertEqual(returned, 'Pass')
|
27
tests/unit/utils/test_color.py
Normal file
27
tests/unit/utils/test_color.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
Unit tests for salt.utils.color.py
|
||||||
|
'''
|
||||||
|
|
||||||
|
# Import python libs
|
||||||
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
# Import Salt Testing libs
|
||||||
|
from tests.support.unit import TestCase
|
||||||
|
|
||||||
|
# Import Salt libs
|
||||||
|
import salt.utils.color
|
||||||
|
|
||||||
|
|
||||||
|
class ColorUtilsTestCase(TestCase):
|
||||||
|
|
||||||
|
def test_get_colors(self):
|
||||||
|
ret = salt.utils.color.get_colors()
|
||||||
|
self.assertEqual('\x1b[0;37m', str(ret['LIGHT_GRAY']))
|
||||||
|
|
||||||
|
ret = salt.utils.color.get_colors(use=False)
|
||||||
|
self.assertDictContainsSubset({'LIGHT_GRAY': ''}, ret)
|
||||||
|
|
||||||
|
ret = salt.utils.color.get_colors(use='LIGHT_GRAY')
|
||||||
|
# LIGHT_YELLOW now == LIGHT_GRAY
|
||||||
|
self.assertEqual(str(ret['LIGHT_YELLOW']), str(ret['LIGHT_GRAY']))
|
@ -895,17 +895,6 @@ class UtilsTestCase(TestCase):
|
|||||||
ret = salt.utils.repack_dictlist(LOREM_IPSUM)
|
ret = salt.utils.repack_dictlist(LOREM_IPSUM)
|
||||||
self.assertDictEqual(ret, {})
|
self.assertDictEqual(ret, {})
|
||||||
|
|
||||||
def test_get_colors(self):
|
|
||||||
ret = salt.utils.get_colors()
|
|
||||||
self.assertEqual('\x1b[0;37m', str(ret['LIGHT_GRAY']))
|
|
||||||
|
|
||||||
ret = salt.utils.get_colors(use=False)
|
|
||||||
self.assertDictContainsSubset({'LIGHT_GRAY': ''}, ret)
|
|
||||||
|
|
||||||
ret = salt.utils.get_colors(use='LIGHT_GRAY')
|
|
||||||
# LIGHT_YELLOW now == LIGHT_GRAY
|
|
||||||
self.assertEqual(str(ret['LIGHT_YELLOW']), str(ret['LIGHT_GRAY']))
|
|
||||||
|
|
||||||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||||
def test_daemonize_if(self):
|
def test_daemonize_if(self):
|
||||||
# pylint: disable=assignment-from-none
|
# pylint: disable=assignment-from-none
|
||||||
|
Loading…
Reference in New Issue
Block a user