Merge branch '2017.7' into '2018.3'

Conflicts:
  - requirements/base.txt
  - salt/states/archive.py
  - salt/states/file.py
  - tests/integration/runners/test_state.py
  - tests/unit/daemons/test_masterapi.py
This commit is contained in:
rallytime 2018-06-11 11:45:37 -04:00
commit 3d2ea16c3a
No known key found for this signature in database
GPG Key ID: E8F1A4B90D0DEA19
13 changed files with 474 additions and 139 deletions

View File

@ -1,10 +1,6 @@
-r base.txt
mock>=2.0.0
apache-libcloud>=0.14.0
boto>=2.32.1
boto3>=1.2.1
moto>=0.3.6
SaltPyLint>=v2017.3.6
pytest>=3.5.0
git+https://github.com/saltstack/pytest-salt.git@master#egg=pytest-salt

36
requirements/tests.txt Normal file
View File

@ -0,0 +1,36 @@
-r zeromq.txt
-r dev.txt
-r pytest.txt
apache-libcloud>=1.0.0
boto>=2.32.1
boto3>=1.2.1
moto>=0.3.6
docker; sys.platform != 'win32'
docker==2.7.0; sys.platform == 'win32'
virtualenv
setuptools>=30
six>=1.10.0
timelib
coverage
keyring==5.7.1
python-gnupg
python-etcd==0.4.2
GitPython
supervisor; python_version < '3'
kubernetes<4.0
psutil
pyvmomi
setproctitle
cherrypy; sys.platform != 'win32' and sys.platform != 'darwin'
pyinotify; sys.platform != 'win32' and sys.platform != 'darwin'
PyMySQL; sys.platform != 'win32' and sys.platform != 'darwin'
jsonschema
strict_rfc3339
rfc3987
jinja2
pyOpenSSL
ioflo
dnspython
SaltTesting==2017.6.1
junos-eznc
jxmlease

View File

@ -66,14 +66,28 @@ def _gen_checksum(path):
def _checksum_file_path(path):
relpath = '.'.join((os.path.relpath(path, __opts__['cachedir']), 'hash'))
if re.match(r'..[/\\]', relpath):
# path is a local file
relpath = salt.utils.path.join(
'local',
os.path.splitdrive(path)[-1].lstrip('/\\'),
)
return salt.utils.path.join(__opts__['cachedir'], 'archive_hash', relpath)
try:
relpath = '.'.join((os.path.relpath(path, __opts__['cachedir']), 'hash'))
if re.match(r'..[/\\]', relpath):
# path is a local file
relpath = salt.utils.path.join(
'local',
os.path.splitdrive(path)[-1].lstrip('/\\'),
)
except ValueError as exc:
# The path is on a different drive (Windows)
if six.text_type(exc).startswith('path is on'):
drive, path = os.path.splitdrive(path)
relpath = salt.utils.path.join(
'local',
drive.rstrip(':'),
path.lstrip('/\\'),
)
else:
raise
ret = salt.utils.path.join(__opts__['cachedir'], 'archive_hash', relpath)
log.debug('Using checksum file %s for cached archive file %s', ret, path)
return ret
def _update_checksum(path):

View File

@ -673,13 +673,13 @@ def _error(ret, err_msg):
def _check_directory(name,
user,
group,
recurse,
mode,
clean,
require,
exclude_pat,
user=None,
group=None,
recurse=False,
mode=None,
clean=False,
require=False,
exclude_pat=None,
max_depth=None,
follow_symlinks=False):
'''
@ -764,7 +764,7 @@ def _check_directory(name,
def _check_directory_win(name,
win_owner,
win_owner=None,
win_perms=None,
win_deny_perms=None,
win_inheritance=None,
@ -778,9 +778,10 @@ def _check_directory_win(name,
changes = {name: {'directory': 'new'}}
else:
# Check owner
owner = salt.utils.win_dacl.get_owner(name)
if not owner.lower() == win_owner.lower():
changes['owner'] = win_owner
if win_owner is not None:
owner = salt.utils.win_dacl.get_owner(name)
if not owner.lower() == win_owner.lower():
changes['owner'] = win_owner
# Check perms
perms = salt.utils.win_dacl.get_permissions(name)
@ -956,33 +957,46 @@ def _check_touch(name, atime, mtime):
def _get_symlink_ownership(path):
return (
__salt__['file.get_user'](path, follow_symlinks=False),
__salt__['file.get_group'](path, follow_symlinks=False)
)
if salt.utils.is_windows():
owner = salt.utils.win_dacl.get_owner(path)
return owner, owner
else:
return (
__salt__['file.get_user'](path, follow_symlinks=False),
__salt__['file.get_group'](path, follow_symlinks=False)
)
def _check_symlink_ownership(path, user, group):
def _check_symlink_ownership(path, user, group, win_owner):
'''
Check if the symlink ownership matches the specified user and group
'''
cur_user, cur_group = _get_symlink_ownership(path)
return (cur_user == user) and (cur_group == group)
if salt.utils.is_windows():
return win_owner == cur_user
else:
return (cur_user == user) and (cur_group == group)
def _set_symlink_ownership(path, user, group):
def _set_symlink_ownership(path, user, group, win_owner):
'''
Set the ownership of a symlink and return a boolean indicating
success/failure
'''
try:
__salt__['file.lchown'](path, user, group)
except OSError:
pass
return _check_symlink_ownership(path, user, group)
if salt.utils.is_windows():
try:
salt.utils.win_dacl.set_owner(path, win_owner)
except CommandExecutionError:
pass
else:
try:
__salt__['file.lchown'](path, user, group)
except OSError:
pass
return _check_symlink_ownership(path, user, group, win_owner)
def _symlink_check(name, target, force, user, group):
def _symlink_check(name, target, force, user, group, win_owner):
'''
Check the symlink function
'''
@ -1001,7 +1015,7 @@ def _symlink_check(name, target, force, user, group):
else:
result = True
msg = 'The symlink {0} is present'.format(name)
if not _check_symlink_ownership(name, user, group):
if not _check_symlink_ownership(name, user, group, win_owner):
result = None
pchanges['ownership'] = '{0}:{1}'.format(*_get_symlink_ownership(name))
msg += (
@ -1225,6 +1239,57 @@ def _shortcut_check(name,
'should be. Did you mean to use force?'.format(name)), pchanges
def _makedirs(name,
user=None,
group=None,
dir_mode=None,
win_owner=None,
win_perms=None,
win_deny_perms=None,
win_inheritance=None):
'''
Helper function for creating directories when the ``makedirs`` option is set
to ``True``. Handles Unix and Windows based systems
.. versionadded:: 2017.7.7
Args:
name (str): The directory path to create
user (str): The linux user to own the directory
group (str): The linux group to own the directory
dir_mode (str): The linux mode to apply to the directory
win_owner (str): The Windows user to own the directory
win_perms (dict): A dictionary of grant permissions for Windows
win_deny_perms (dict): A dictionary of deny permissions for Windows
win_inheritance (bool): True to inherit permissions on Windows
Returns:
bool: True if successful, otherwise False on Windows
str: Error messages on failure on Linux
None: On successful creation on Linux
Raises:
CommandExecutionError: If the drive is not mounted on Windows
'''
if salt.utils.is_windows():
# Make sure the drive is mapped before trying to create the
# path in windows
drive, path = os.path.splitdrive(name)
if not os.path.isdir(drive):
raise CommandExecutionError(drive)
win_owner = win_owner if win_owner else user
return __salt__['file.makedirs'](path=name,
owner=win_owner,
grant_perms=win_perms,
deny_perms=win_deny_perms,
inheritance=win_inheritance)
else:
return __salt__['file.makedirs'](path=name,
user=user,
group=group,
mode=dir_mode)
def symlink(
name,
target,
@ -1234,6 +1299,10 @@ def symlink(
user=None,
group=None,
mode=None,
win_owner=None,
win_perms=None,
win_deny_perms=None,
win_inheritance=None,
**kwargs):
'''
Create a symbolic link (symlink, soft link)
@ -1282,6 +1351,28 @@ def symlink(
The default mode for new files and directories corresponds umask of salt
process. For existing files and directories it's not enforced.
win_owner : None
The owner of the symlink and directories if ``makedirs`` is True. If
this is not passed, ``user`` will be used. If ``user`` is not passed,
the account under which Salt is running will be used.
.. versionadded:: 2017.7.7
win_perms : None
A dictionary containing permissions to grant
.. versionadded:: 2017.7.7
win_deny_perms : None
A dictionary containing permissions to deny
.. versionadded:: 2017.7.7
win_inheritance : None
True to inherit permissions from parent, otherwise False
.. versionadded:: 2017.7.7
'''
name = os.path.expanduser(name)
@ -1310,10 +1401,16 @@ def symlink(
if not user:
user = 'SYSTEM'
# If win_owner is not passed, use user
if win_owner is None:
win_owner = user if user else None
# Group isn't relevant to Windows, use win_perms/win_deny_perms
if group is not None:
log.warning(
'The group argument for {0} has been ignored as this '
'is a Windows system.'.format(name)
'is a Windows system. Please use the `win_*` parameters to set '
'permissions in Windows.'.format(name)
)
group = user
@ -1323,14 +1420,31 @@ def symlink(
)
preflight_errors = []
uid = __salt__['file.user_to_uid'](user)
gid = __salt__['file.group_to_gid'](group)
if salt.utils.is_windows():
# Make sure the passed owner exists
if not salt.utils.win_functions.get_sid_from_name(win_owner):
preflight_errors.append('User {0} does not exist'.format(win_owner))
if uid == '':
preflight_errors.append('User {0} does not exist'.format(user))
# Make sure users passed in win_perms exist
if win_perms:
for name_check in win_perms:
if not salt.utils.win_functions.get_sid_from_name(name_check):
preflight_errors.append('User {0} does not exist'.format(name_check))
if gid == '':
preflight_errors.append('Group {0} does not exist'.format(group))
# Make sure users passed in win_deny_perms exist
if win_deny_perms:
for name_check in win_deny_perms:
if not salt.utils.win_functions.get_sid_from_name(name_check):
preflight_errors.append('User {0} does not exist'.format(name_check))
else:
uid = __salt__['file.user_to_uid'](user)
gid = __salt__['file.group_to_gid'](group)
if uid == '':
preflight_errors.append('User {0} does not exist'.format(user))
if gid == '':
preflight_errors.append('Group {0} does not exist'.format(group))
if not os.path.isabs(name):
preflight_errors.append(
@ -1347,47 +1461,77 @@ def symlink(
target,
force,
user,
group)
group,
win_owner)
if not os.path.isdir(os.path.dirname(name)):
if makedirs:
if __opts__['test']:
pcomment += '\n{0} will be created'.format(os.path.dirname(name))
else:
try:
_makedirs(name=name,
user=user,
group=group,
dir_mode=mode,
win_owner=win_owner,
win_perms=win_perms,
win_deny_perms=win_deny_perms,
win_inheritance=win_inheritance)
except CommandExecutionError as exc:
return _error(ret, 'Drive {0} is not mapped'.format(exc.message))
else:
if __opts__['test']:
pcomment += '\nDirectory {0} for symlink is not present' \
''.format(os.path.dirname(name))
else:
return _error(
ret,
'Directory {0} for symlink is not present'.format(
os.path.dirname(name)
)
)
if __opts__['test']:
ret['result'] = presult
ret['comment'] = pcomment
return ret
if not os.path.isdir(os.path.dirname(name)):
if makedirs:
__salt__['file.makedirs'](
name,
user=user,
group=group,
mode=mode)
else:
return _error(
ret,
'Directory {0} for symlink is not present'.format(
os.path.dirname(name)
)
)
if __salt__['file.is_link'](name):
# The link exists, verify that it matches the target
if os.path.normpath(__salt__['file.readlink'](name)) != os.path.normpath(target):
# The target is wrong, delete the link
os.remove(name)
else:
if _check_symlink_ownership(name, user, group):
if _check_symlink_ownership(name, user, group, win_owner):
# The link looks good!
ret['comment'] = ('Symlink {0} is present and owned by '
'{1}:{2}'.format(name, user, group))
else:
if _set_symlink_ownership(name, user, group):
ret['comment'] = ('Set ownership of symlink {0} to '
if salt.utils.is_windows():
ret['comment'] = ('Symlink {0} is present and owned by {1}'
''.format(name, win_owner))
else:
ret['comment'] = ('Symlink {0} is present and owned by '
'{1}:{2}'.format(name, user, group))
ret['changes']['ownership'] = '{0}:{1}'.format(user, group)
else:
if _set_symlink_ownership(name, user, group, win_owner):
if salt.utils.is_windows():
ret['comment'] = ('Set ownership of symlink {0} to '
'{1}'.format(name, win_owner))
ret['changes']['ownership'] = win_owner
else:
ret['comment'] = ('Set ownership of symlink {0} to '
'{1}:{2}'.format(name, user, group))
ret['changes']['ownership'] = '{0}:{1}'.format(user,
group)
else:
ret['result'] = False
ret['comment'] += (
'Failed to set ownership of symlink {0} to '
'{1}:{2}'.format(name, user, group)
)
if salt.utils.is_windows():
ret['comment'] += (
'Failed to set ownership of symlink '
'{0} to {1}'.format(name, win_owner))
else:
ret['comment'] += (
'Failed to set ownership of symlink {0} to '
'{1}:{2}'.format(name, user, group))
return ret
elif os.path.isfile(name) or os.path.isdir(name):
@ -1434,8 +1578,8 @@ def symlink(
'{1}'.format(name, target))
ret['changes']['new'] = name
if not _check_symlink_ownership(name, user, group):
if not _set_symlink_ownership(name, user, group):
if not _check_symlink_ownership(name, user, group, win_owner):
if not _set_symlink_ownership(name, user, group, win_owner):
ret['result'] = False
ret['comment'] += (', but was unable to set ownership to '
'{0}:{1}'.format(user, group))
@ -2971,23 +3115,17 @@ def directory(name,
# The parent directory does not exist, create them
if makedirs:
# Everything's good, create the parent Dirs
if salt.utils.platform.is_windows():
# Make sure the drive is mapped before trying to create the
# path in windows
drive, path = os.path.splitdrive(name)
if not os.path.isdir(drive):
return _error(
ret, 'Drive {0} is not mapped'.format(drive))
__salt__['file.makedirs'](
path=name,
owner=win_owner,
grant_perms=win_perms,
deny_perms=win_deny_perms,
inheritance=win_inheritance,
reset=win_perms_reset)
else:
__salt__['file.makedirs'](name, user=user, group=group,
mode=dir_mode)
try:
_makedirs(name=name,
user=user,
group=group,
dir_mode=dir_mode,
win_owner=win_owner,
win_perms=win_perms,
win_deny_perms=win_deny_perms,
win_inheritance=win_inheritance)
except CommandExecutionError as exc:
return _error(ret, 'Drive {0} is not mapped'.format(exc.message))
else:
return _error(
ret, 'No directory to create {0} in'.format(name))
@ -3182,6 +3320,10 @@ def recurse(name,
maxdepth=None,
keep_symlinks=False,
force_symlinks=False,
win_owner=None,
win_perms=None,
win_deny_perms=None,
win_inheritance=True,
**kwargs):
'''
Recurse through a subdirectory on the master and copy said subdirectory
@ -3341,6 +3483,28 @@ def recurse(name,
If a file or directory is obstructing symlink creation it will be
recursively removed so that symlink creation can proceed. This
option is usually not needed except in special circumstances.
win_owner : None
The owner of the symlink and directories if ``makedirs`` is True. If
this is not passed, ``user`` will be used. If ``user`` is not passed,
the account under which Salt is running will be used.
.. versionadded:: 2017.7.7
win_perms : None
A dictionary containing permissions to grant
.. versionadded:: 2017.7.7
win_deny_perms : None
A dictionary containing permissions to deny
.. versionadded:: 2017.7.7
win_inheritance : None
True to inherit permissions from parent, otherwise False
.. versionadded:: 2017.7.7
'''
if 'env' in kwargs:
# "env" is not supported; Use "saltenv".
@ -3439,7 +3603,18 @@ def recurse(name,
return _error(
ret, 'The path {0} exists and is not a directory'.format(name))
if not __opts__['test']:
__salt__['file.makedirs_perms'](name, user, group, dir_mode)
if salt.utils.is_windows():
win_owner = win_owner if win_owner else user
__salt__['file.makedirs_perms'](path=name,
owner=win_owner,
grant_perms=win_perms,
deny_perms=win_deny_perms,
inheritance=win_inheritance)
else:
__salt__['file.makedirs_perms'](name=name,
user=user,
group=group,
mode=dir_mode)
def add_comment(path, comment):
comments = ret['comment'].setdefault(path, [])
@ -4821,10 +4996,16 @@ def append(name,
if makedirs is True:
dirname = os.path.dirname(name)
if not __salt__['file.directory_exists'](dirname):
__salt__['file.makedirs'](name)
check_res, check_msg, ret['pchanges'] = _check_directory(
dirname, None, None, False, None, False, False, None
)
try:
_makedirs(name=name)
except CommandExecutionError as exc:
return _error(ret, 'Drive {0} is not mapped'.format(exc.message))
if salt.utils.is_windows():
check_res, check_msg, ret['pchanges'] = _check_directory_win(dirname)
else:
check_res, check_msg, ret['pchanges'] = _check_directory(dirname)
if not check_res:
return _error(ret, check_msg)
@ -4935,6 +5116,90 @@ def prepend(name,
The text will not be prepended again if it already exists in the file. You
may specify a single line of text or a list of lines to append.
name
The location of the file to append to.
text
The text to be appended, which can be a single string or a list
of strings.
makedirs
If the file is located in a path without a parent directory,
then the state will fail. If makedirs is set to True, then
the parent directories will be created to facilitate the
creation of the named file. Defaults to False.
source
A single source file to append. This source file can be hosted on either
the salt master server, or on an HTTP or FTP server. Both HTTPS and
HTTP are supported as well as downloading directly from Amazon S3
compatible URLs with both pre-configured and automatic IAM credentials
(see s3.get state documentation). File retrieval from Openstack Swift
object storage is supported via swift://container/object_path URLs
(see swift.get documentation).
For files hosted on the salt file server, if the file is located on
the master in the directory named spam, and is called eggs, the source
string is salt://spam/eggs.
If the file is hosted on an HTTP or FTP server, the source_hash argument
is also required.
source_hash
This can be one of the following:
1. a source hash string
2. the URI of a file that contains source hash strings
The function accepts the first encountered long unbroken alphanumeric
string of correct length as a valid hash, in order from most secure to
least secure:
.. code-block:: text
Type Length
====== ======
sha512 128
sha384 96
sha256 64
sha224 56
sha1 40
md5 32
See the ``source_hash`` parameter description for :mod:`file.managed
<salt.states.file.managed>` function for more details and examples.
template
The named templating engine will be used to render the appended-to file.
Defaults to ``jinja``. The following templates are supported:
- :mod:`cheetah<salt.renderers.cheetah>`
- :mod:`genshi<salt.renderers.genshi>`
- :mod:`jinja<salt.renderers.jinja>`
- :mod:`mako<salt.renderers.mako>`
- :mod:`py<salt.renderers.py>`
- :mod:`wempy<salt.renderers.wempy>`
sources
A list of source files to append. If the files are hosted on an HTTP or
FTP server, the source_hashes argument is also required.
source_hashes
A list of source_hashes corresponding to the sources list specified in
the sources argument.
defaults
Default context passed to the template.
context
Overrides default context variables passed to the template.
ignore_whitespace
.. versionadded:: 2015.8.4
Spaces and Tabs in text are ignored by default, when searching for the
appending content, one space or multiple tabs are the same for salt.
Set this option to ``False`` if you want to change this behavior.
Multi-line example:
.. code-block:: yaml
@ -5013,10 +5278,15 @@ def prepend(name,
if makedirs is True:
dirname = os.path.dirname(name)
if not __salt__['file.directory_exists'](dirname):
__salt__['file.makedirs'](name)
check_res, check_msg, ret['pchanges'] = _check_directory(
dirname, None, None, False, None, False, False, None
)
try:
_makedirs(name=name)
except CommandExecutionError as exc:
return _error(ret, 'Drive {0} is not mapped'.format(exc.message))
if salt.utils.is_windows():
check_res, check_msg, ret['pchanges'] = _check_directory_win(dirname)
else:
check_res, check_msg, ret['pchanges'] = _check_directory(dirname)
if not check_res:
return _error(ret, check_msg)
@ -5302,7 +5572,10 @@ def touch(name, atime=None, mtime=None, makedirs=False):
return ret
if makedirs:
__salt__['file.makedirs'](name)
try:
_makedirs(name=name)
except CommandExecutionError as exc:
return _error(ret, 'Drive {0} is not mapped'.format(exc.message))
if not os.path.isdir(os.path.dirname(name)):
return _error(
ret, 'Directory not present to touch file {0}'.format(name)
@ -5499,7 +5772,10 @@ def copy(
dname = os.path.dirname(name)
if not os.path.isdir(dname):
if makedirs:
__salt__['file.makedirs'](name)
try:
_makedirs(name=name)
except CommandExecutionError as exc:
return _error(ret, 'Drive {0} is not mapped'.format(exc.message))
else:
return _error(
ret,
@ -5596,7 +5872,10 @@ def rename(name, source, force=False, makedirs=False):
dname = os.path.dirname(name)
if not os.path.isdir(dname):
if makedirs:
__salt__['file.makedirs'](name)
try:
_makedirs(name=name)
except CommandExecutionError as exc:
return _error(ret, 'Drive {0} is not mapped'.format(exc.message))
else:
return _error(
ret,
@ -6470,9 +6749,10 @@ def shortcut(
if not os.path.isdir(os.path.dirname(name)):
if makedirs:
__salt__['file.makedirs'](
name,
user=user)
try:
_makedirs(name=name, user=user)
except CommandExecutionError as exc:
return _error(ret, 'Drive {0} is not mapped'.format(exc.message))
else:
return _error(
ret,
@ -6495,7 +6775,10 @@ def shortcut(
time.sleep(1) # wait for asynchronous deletion
if not os.path.isdir(os.path.dirname(backupname)):
if makedirs:
os.makedirs(backupname)
try:
_makedirs(name=backupname)
except CommandExecutionError as exc:
return _error(ret, 'Drive {0} is not mapped'.format(exc.message))
else:
return _error(ret, (
'Directory does not exist for'

View File

@ -239,7 +239,8 @@ class WindowsUpdateAgent(object):
# Error codes found at the following site:
# https://msdn.microsoft.com/en-us/library/windows/desktop/hh968413(v=vs.85).aspx
# https://technet.microsoft.com/en-us/library/cc720442(v=ws.10).aspx
fail_codes = {-2145124300: 'Download failed: 0x80240034',
fail_codes = {-2145107924: 'WinHTTP Send/Receive failed: 0x8024402C',
-2145124300: 'Download failed: 0x80240034',
-2145124302: 'Invalid search criteria: 0x80240032',
-2145124305: 'Cancelled by policy: 0x8024002F',
-2145124307: 'Missing source: 0x8024002D',

View File

@ -254,11 +254,13 @@ def pytest_runtest_setup(item):
if destructive_tests_marker is not None:
if item.config.getoption('--run-destructive') is False:
pytest.skip('Destructive tests are disabled')
os.environ['DESTRUCTIVE_TESTS'] = six.text_type(item.config.getoption('--run-destructive'))
expensive_tests_marker = item.get_marker('expensive_test')
if expensive_tests_marker is not None:
if item.config.getoption('--run-expensive') is False:
pytest.skip('Expensive tests are disabled')
os.environ['EXPENSIVE_TESTS'] = six.text_type(item.config.getoption('--run-expensive'))
skip_if_not_root_marker = item.get_marker('skip_if_not_root')
if skip_if_not_root_marker is not None:

View File

@ -1,6 +1,6 @@
{% set versions = {'18':['05', '03', '01'], '16':['04', '03', '02', '00'], '9':['20']} %}
Zzip:
7zip:
{% for major, subversions in versions.items() %}
{% for minor in subversions %}
'{{major}}.{{minor}}.00.0':

View File

@ -127,7 +127,11 @@ class ServiceModuleTest(ModuleCase):
# currently upstart does not have a mechanism to report if disabling a service fails if does not exist
self.assertTrue(self.run_function('service.disable', [srv_name]))
else:
self.assertFalse(self.run_function('service.disable', [srv_name]))
if salt.utils.is_windows():
disable = self.run_function('service.disable', [srv_name])
self.assertTrue('error' in disable.lower())
else:
self.assertFalse(self.run_function('service.disable', [srv_name]))
if salt.utils.platform.is_darwin():
self.assertFalse(self.run_function('service.disabled', [srv_name]))

View File

@ -270,13 +270,15 @@ class PkgTest(ModuleCase, SaltReturnAssertsMixin):
except AssertionError:
self.assertSaltTrueReturn(self.run_state('pkg.removed', name=None, pkgs=pkg_targets))
ret = self.run_state('pkg.installed',
name=None,
pkgs=pkg_targets,
refresh=False)
self.assertSaltTrueReturn(ret)
ret = self.run_state('pkg.removed', name=None, pkgs=pkg_targets)
self.assertSaltTrueReturn(ret)
try:
ret = self.run_state('pkg.installed',
name=None,
pkgs=pkg_targets,
refresh=False)
self.assertSaltTrueReturn(ret)
finally:
ret = self.run_state('pkg.removed', name=None, pkgs=pkg_targets)
self.assertSaltTrueReturn(ret)
@requires_system_grains
def test_pkg_004_installed_multipkg_with_version(self, grains=None):
@ -318,13 +320,15 @@ class PkgTest(ModuleCase, SaltReturnAssertsMixin):
pkgs = [{pkg_targets[0]: version}, pkg_targets[1]]
ret = self.run_state('pkg.installed',
name=None,
pkgs=pkgs,
refresh=False)
self.assertSaltTrueReturn(ret)
ret = self.run_state('pkg.removed', name=None, pkgs=pkg_targets)
self.assertSaltTrueReturn(ret)
try:
ret = self.run_state('pkg.installed',
name=None,
pkgs=pkgs,
refresh=False)
self.assertSaltTrueReturn(ret)
finally:
ret = self.run_state('pkg.removed', name=None, pkgs=pkg_targets)
self.assertSaltTrueReturn(ret)
@requires_system_grains
def test_pkg_005_installed_32bit(self, grains=None):

View File

@ -9,7 +9,6 @@ on a single system to test scale capabilities
# Import Python Libs
from __future__ import absolute_import, print_function
import os
import pwd
import time
import signal
import optparse
@ -29,6 +28,7 @@ import salt.utils.yaml
# Import third party libs
from salt.ext import six
from salt.ext.six.moves import range # pylint: disable=import-error,redefined-builtin
import tests.support.helpers
OSES = [
@ -148,7 +148,7 @@ def parse():
'-c', '--config-dir', default='',
help=('Pass in a configuration directory containing base configuration.')
)
parser.add_option('-u', '--user', default=pwd.getpwuid(os.getuid()).pw_name)
parser.add_option('-u', '--user', default=tests.support.helpers.this_user())
options, _args = parser.parse_args()

View File

@ -3,6 +3,7 @@
# Import Python libs
from __future__ import absolute_import, print_function, unicode_literals
from functools import wraps
import os
import io
import stat
@ -12,6 +13,7 @@ import salt.daemons.masterapi as masterapi
import salt.utils.platform
# Import Salt Testing Libs
from tests.support.paths import TMP_CONF_DIR
from tests.support.unit import TestCase, skipIf
from tests.support.mock import (
patch,
@ -568,7 +570,7 @@ class RemoteFuncsTestCase(TestCase):
'''
def setUp(self):
opts = salt.config.master_config(None)
opts = salt.config.master_config(os.path.join(TMP_CONF_DIR, 'master'))
self.funcs = masterapi.RemoteFuncs(opts)
self.funcs.cache = FakeCache()

View File

@ -59,9 +59,11 @@ class DocTestCase(TestCase):
key, val = regex.split(line, 1)
# Don't test man pages, this file,
# the page that documents to not use ":doc:", or
# the doc/conf.py file
# the tox virtualenv files, the page
# that documents to not use ":doc:",
# or the doc/conf.py file
if 'man' in key \
or '.tox/' in key \
or key.endswith('test_doc.py') \
or key.endswith(os.sep.join(['doc', 'conf.py'])) \
or key.endswith(os.sep.join(['conventions', 'documentation.rst'])) \

15
tox.ini
View File

@ -2,15 +2,6 @@
envlist = py27,py34,py35,py36
[testenv]
sitepackages = True
deps =
py27,pylint: -r{toxinidir}/requirements/dev_python27.txt
py34,py35,py36: -r{toxinidir}/requirements/dev_python34.txt
commands =
py27: python2 {toxinidir}/tests/runtests.py {posargs:-v --run-destructive}
py34,py35,py36: python3 {toxinidir}/tests/runtests.py {posargs:-v --run-destructive}
[testenv:pylint]
basepython = python2.7
commands = pylint --rcfile={toxinidir}/.testing.pylintrc --disable=W1307 {posargs:setup.py salt/}
pylint --rcfile={toxinidir}/.testing.pylintrc --disable=W0232,E1002,W1307 {posargs:tests/}
deps = -r{toxinidir}/requirements/tests.txt
commands = pytest --rootdir {toxinidir} {posargs:--no-print-logs --run-destructive}
passenv = LANG HOME