mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge branch '2015.8' into '2016.3'
Conflicts: - salt/cli/salt.py - salt/modules/groupadd.py - salt/states/service.py
This commit is contained in:
commit
c5b4ec0b0f
22 changed files with 1439 additions and 437 deletions
|
@ -4,7 +4,7 @@
|
|||
Debian GNU/Linux / Raspbian
|
||||
===========================
|
||||
|
||||
Debian GNU/Linux distribution and some devariatives such as Raspbian already
|
||||
Debian GNU/Linux distribution and some derivatives such as Raspbian already
|
||||
have included Salt packages to their repositories. However, current stable
|
||||
release codenamed "Jessie" contains old outdated Salt release. It is
|
||||
recommended to use SaltStack repository for Debian as described
|
||||
|
@ -23,96 +23,6 @@ Official SaltStack repository.
|
|||
|
||||
Instructions are at http://repo.saltstack.com/#debian.
|
||||
|
||||
Installation from the Community-Maintained Repository
|
||||
=====================================================
|
||||
|
||||
The SaltStack community maintains a Debian repository at debian.saltstack.com.
|
||||
Packages for Debian Old Stable, Stable, and Unstable (Wheezy, Jessie, and Sid)
|
||||
for Salt 0.16 and later are published in this repository.
|
||||
|
||||
.. note::
|
||||
Packages in this repository are community built, and it can
|
||||
take a little while until the latest SaltStack release is available
|
||||
in this repository.
|
||||
|
||||
Jessie (Stable)
|
||||
---------------
|
||||
|
||||
For Jessie, the following line is needed in either
|
||||
``/etc/apt/sources.list`` or a file in ``/etc/apt/sources.list.d``:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
deb http://debian.saltstack.com/debian jessie-saltstack main
|
||||
|
||||
Wheezy (Old Stable)
|
||||
-------------------
|
||||
|
||||
For Wheezy, the following line is needed in either
|
||||
``/etc/apt/sources.list`` or a file in ``/etc/apt/sources.list.d``:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
deb http://debian.saltstack.com/debian wheezy-saltstack main
|
||||
|
||||
Squeeze (Old Old Stable)
|
||||
------------------------
|
||||
|
||||
For Squeeze, you will need to enable the Debian backports repository
|
||||
as well as the debian.saltstack.com repository. To do so, add the
|
||||
following to ``/etc/apt/sources.list`` or a file in
|
||||
``/etc/apt/sources.list.d``:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
deb http://debian.saltstack.com/debian squeeze-saltstack main
|
||||
deb http://backports.debian.org/debian-backports squeeze-backports main
|
||||
|
||||
Stretch (Testing)
|
||||
-----------------
|
||||
|
||||
For Stretch, the following line is needed in either
|
||||
``/etc/apt/sources.list`` or a file in ``/etc/apt/sources.list.d``:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
deb http://debian.saltstack.com/debian stretch-saltstack main
|
||||
|
||||
Sid (Unstable)
|
||||
--------------
|
||||
|
||||
For Sid, the following line is needed in either
|
||||
``/etc/apt/sources.list`` or a file in ``/etc/apt/sources.list.d``:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
deb http://debian.saltstack.com/debian unstable main
|
||||
|
||||
Import the repository key
|
||||
-------------------------
|
||||
|
||||
You will need to import the key used for signing.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
wget -q -O- "http://debian.saltstack.com/debian-salt-team-joehealy.gpg.key" | apt-key add -
|
||||
|
||||
.. note::
|
||||
|
||||
You can optionally verify the key integrity with ``sha512sum`` using the
|
||||
public key signature shown here. E.g:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
echo "b702969447140d5553e31e9701be13ca11cc0a7ed5fe2b30acb8491567560ee62f834772b5095d735dfcecb2384a5c1a20045f52861c417f50b68dd5ff4660e6 debian-salt-team-joehealy.gpg.key" | sha512sum -c
|
||||
|
||||
Update the package database
|
||||
---------------------------
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
apt-get update
|
||||
|
||||
.. _installation-debian-raspbian:
|
||||
|
||||
Installation from the Debian / Raspbian Official Repository
|
||||
|
|
|
@ -213,7 +213,10 @@ class SaltCMD(parsers.SaltCMDOptionParser):
|
|||
if not self.options.batch:
|
||||
self.config['batch'] = '100%'
|
||||
|
||||
batch = salt.cli.batch.Batch(self.config, eauth=eauth, quiet=True)
|
||||
try:
|
||||
batch = salt.cli.batch.Batch(self.config, eauth=eauth, quiet=True)
|
||||
except salt.exceptions.SaltClientError as exc:
|
||||
sys.exit(2)
|
||||
|
||||
ret = {}
|
||||
|
||||
|
|
|
@ -166,10 +166,13 @@ def adduser(name, username, root=None):
|
|||
if not then adds it.
|
||||
'''
|
||||
on_redhat_5 = __grains__.get('os_family') == 'RedHat' and __grains__.get('osmajorrelease') == '5'
|
||||
on_suse_11 = __grains__.get('os_family') == 'Suse' and __grains__.get('osrelease_info')[0] == 11
|
||||
|
||||
if __grains__['kernel'] == 'Linux':
|
||||
if on_redhat_5:
|
||||
cmd = ('gpasswd', '-a', username, name)
|
||||
elif on_suse_11:
|
||||
cmd = ('usermod', '-A', name, username)
|
||||
else:
|
||||
cmd = ('gpasswd', '--add', username, name)
|
||||
if root is not None:
|
||||
|
@ -198,6 +201,7 @@ def deluser(name, username, root=None):
|
|||
then returns True.
|
||||
'''
|
||||
on_redhat_5 = __grains__.get('os_family') == 'RedHat' and __grains__.get('osmajorrelease') == '5'
|
||||
on_suse_11 = __grains__.get('os_family') == 'Suse' and __grains__.get('osrelease_info')[0] == 11
|
||||
|
||||
grp_info = __salt__['group.info'](name)
|
||||
try:
|
||||
|
@ -205,6 +209,8 @@ def deluser(name, username, root=None):
|
|||
if __grains__['kernel'] == 'Linux':
|
||||
if on_redhat_5:
|
||||
cmd = ('gpasswd', '-d', username, name)
|
||||
elif on_suse_11:
|
||||
cmd = ('usermod', '-R', name, username)
|
||||
else:
|
||||
cmd = ('gpasswd', '--del', username, name)
|
||||
if root is not None:
|
||||
|
@ -239,10 +245,15 @@ def members(name, members_list, root=None):
|
|||
foo:x:1234:user1,user2,user3,...
|
||||
'''
|
||||
on_redhat_5 = __grains__.get('os_family') == 'RedHat' and __grains__.get('osmajorrelease') == '5'
|
||||
on_suse_11 = __grains__.get('os_family') == 'Suse' and __grains__.get('osrelease_info')[0] == 11
|
||||
|
||||
if __grains__['kernel'] == 'Linux':
|
||||
if on_redhat_5:
|
||||
cmd = ('gpasswd', '-M', members_list, name)
|
||||
elif on_suse_11:
|
||||
for old_member in __salt__['group.info'](name).get('members'):
|
||||
__salt__['cmd.run']('groupmod -R {0} {1}'.format(old_member, name), python_shell=False)
|
||||
cmd = ('groupmod', '-A', members_list, name)
|
||||
else:
|
||||
cmd = ('gpasswd', '--members', members_list, name)
|
||||
if root is not None:
|
||||
|
|
|
@ -108,7 +108,7 @@ def locate(pattern, database='', limit=0, **kwargs):
|
|||
'wholename': 'w',
|
||||
}
|
||||
for option in kwargs:
|
||||
if bool(kwargs[option]) is True:
|
||||
if bool(kwargs[option]) is True and option in toggles:
|
||||
options += toggles[option]
|
||||
if options:
|
||||
options = '-{0}'.format(options)
|
||||
|
|
|
@ -1223,7 +1223,7 @@ def get_bufsize(iface):
|
|||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' network.get_bufsize
|
||||
salt '*' network.get_bufsize eth0
|
||||
'''
|
||||
if __grains__['kernel'] == 'Linux':
|
||||
if os.path.exists('/sbin/ethtool'):
|
||||
|
|
|
@ -422,6 +422,12 @@ def set_hwclock(clock):
|
|||
elif clock == 'localtime':
|
||||
__salt__['file.sed']('/etc/default/rcS', '^UTC=.*', 'UTC=no')
|
||||
elif 'Gentoo' in __grains__['os_family']:
|
||||
if clock not in ('UTC', 'localtime'):
|
||||
raise SaltInvocationError(
|
||||
'Only \'UTC\' and \'localtime\' are allowed'
|
||||
)
|
||||
if clock == 'localtime':
|
||||
clock = 'local'
|
||||
__salt__['file.sed'](
|
||||
'/etc/conf.d/hwclock', '^clock=.*', 'clock="{0}"'.format(clock))
|
||||
|
||||
|
|
|
@ -83,8 +83,9 @@ def list_available():
|
|||
salt '*' win_servermanager.list_available
|
||||
'''
|
||||
cmd = 'Import-Module ServerManager; ' \
|
||||
'Get-WindowsFeature -erroraction silentlycontinue ' \
|
||||
'-warningaction silentlycontinue'
|
||||
'Get-WindowsFeature ' \
|
||||
'-ErrorAction SilentlyContinue ' \
|
||||
'-WarningAction SilentlyContinue'
|
||||
return __salt__['cmd.shell'](cmd, shell='powershell')
|
||||
|
||||
|
||||
|
@ -102,9 +103,10 @@ def list_installed():
|
|||
|
||||
salt '*' win_servermanager.list_installed
|
||||
'''
|
||||
cmd = 'Get-WindowsFeature -erroraction silentlycontinue ' \
|
||||
'-warningaction silentlycontinue | ' \
|
||||
'Select DisplayName,Name,Installed'
|
||||
cmd = 'Get-WindowsFeature ' \
|
||||
'-ErrorAction SilentlyContinue ' \
|
||||
'-WarningAction SilentlyContinue ' \
|
||||
'| Select DisplayName,Name,Installed'
|
||||
features = _pshell_json(cmd)
|
||||
|
||||
ret = {}
|
||||
|
@ -115,7 +117,7 @@ def list_installed():
|
|||
return ret
|
||||
|
||||
|
||||
def install(feature, recurse=False):
|
||||
def install(feature, recurse=False, source=None, restart=False, exclude=None):
|
||||
'''
|
||||
Install a feature
|
||||
|
||||
|
@ -129,7 +131,21 @@ def install(feature, recurse=False):
|
|||
|
||||
:param str feature: The name of the feature to install
|
||||
|
||||
:param bool recurse: Install all sub-features
|
||||
:param bool recurse: Install all sub-features. Default is False
|
||||
|
||||
:param str source: Path to the source files if missing from the target
|
||||
system. None means that the system will use windows update services to
|
||||
find the required files. Default is None
|
||||
|
||||
:param bool restart: Restarts the computer when installation is complete, if
|
||||
required by the role/feature installed. Default is False
|
||||
|
||||
:param str exclude: The name of the feature to exclude when installing the
|
||||
named feature.
|
||||
|
||||
..note:: As there is no exclude option for the ``Add-WindowsFeature``
|
||||
command, the feature will be installed with other sub-features and
|
||||
will then be removed.
|
||||
|
||||
:return: A dictionary containing the results of the install
|
||||
:rtype: dict
|
||||
|
@ -140,16 +156,33 @@ def install(feature, recurse=False):
|
|||
|
||||
salt '*' win_servermanager.install Telnet-Client
|
||||
salt '*' win_servermanager.install SNMP-Service True
|
||||
salt '*' win_servermanager.install TFTP-Client source=d:\\side-by-side
|
||||
'''
|
||||
mgmt_tools = ''
|
||||
if salt.utils.version_cmp(__grains__['osversion'], '6.2') >= 0:
|
||||
mgmt_tools = '-IncludeManagementTools'
|
||||
|
||||
sub = ''
|
||||
if recurse:
|
||||
sub = '-IncludeAllSubFeature'
|
||||
|
||||
cmd = 'Add-WindowsFeature -Name {0} {1} ' \
|
||||
rst = ''
|
||||
if restart:
|
||||
rst = '-Restart'
|
||||
|
||||
src = ''
|
||||
if source is not None:
|
||||
src = '-Source {0}'.format(source)
|
||||
|
||||
cmd = 'Add-WindowsFeature -Name {0} {1} {2} {3} {4} ' \
|
||||
'-ErrorAction SilentlyContinue ' \
|
||||
'-WarningAction SilentlyContinue'.format(_cmd_quote(feature), sub)
|
||||
'-WarningAction SilentlyContinue'\
|
||||
.format(_cmd_quote(feature), mgmt_tools, sub, src, rst)
|
||||
out = _pshell_json(cmd)
|
||||
|
||||
if exclude is not None:
|
||||
remove(exclude, restart=restart)
|
||||
|
||||
if out['FeatureResult']:
|
||||
return {'ExitCode': out['ExitCode'],
|
||||
'DisplayName': out['FeatureResult'][0]['DisplayName'],
|
||||
|
@ -162,8 +195,8 @@ def install(feature, recurse=False):
|
|||
'Success': out['Success']}
|
||||
|
||||
|
||||
def remove(feature):
|
||||
'''
|
||||
def remove(feature, remove_payload=False, restart=False):
|
||||
r'''
|
||||
Remove an installed feature
|
||||
|
||||
.. note::
|
||||
|
@ -175,6 +208,13 @@ def remove(feature):
|
|||
|
||||
:param str feature: The name of the feature to remove
|
||||
|
||||
:param bool remove_payload: True will cause the feature to be removed from
|
||||
the side-by-side store (``%SystemDrive%:\Windows\WinSxS``). Default is
|
||||
False
|
||||
|
||||
:param bool restart: Restarts the computer when uninstall is complete, if
|
||||
required by the role/feature removed. Default is False
|
||||
|
||||
:return: A dictionary containing the results of the uninstall
|
||||
:rtype: dict
|
||||
|
||||
|
@ -184,9 +224,22 @@ def remove(feature):
|
|||
|
||||
salt -t 600 '*' win_servermanager.remove Telnet-Client
|
||||
'''
|
||||
cmd = 'Remove-WindowsFeature -Name {0} ' \
|
||||
mgmt_tools = ''
|
||||
if salt.utils.version_cmp(__grains__['osversion'], '6.2') >= 0:
|
||||
mgmt_tools = '-IncludeManagementTools'
|
||||
|
||||
rmv = ''
|
||||
if remove_payload:
|
||||
rmv = '-Remove'
|
||||
|
||||
rst = ''
|
||||
if restart:
|
||||
rst = '-Restart'
|
||||
|
||||
cmd = 'Remove-WindowsFeature -Name {0} {1} {2} {3} ' \
|
||||
'-ErrorAction SilentlyContinue ' \
|
||||
'-WarningAction SilentlyContinue'.format(_cmd_quote(feature))
|
||||
'-WarningAction SilentlyContinue'\
|
||||
.format(_cmd_quote(feature), mgmt_tools, rmv, rst)
|
||||
out = _pshell_json(cmd)
|
||||
|
||||
if out['FeatureResult']:
|
||||
|
|
|
@ -266,6 +266,11 @@ def save_minions(jid, minions, syndic_id=None):
|
|||
minions_path = os.path.join(jid_dir, MINIONS_P)
|
||||
|
||||
try:
|
||||
if not os.path.exists(jid_dir):
|
||||
try:
|
||||
os.makedirs(jid_dir)
|
||||
except OSError:
|
||||
pass
|
||||
serial.dump(minions, salt.utils.fopen(minions_path, 'w+b'))
|
||||
except IOError as exc:
|
||||
log.error(
|
||||
|
|
|
@ -2503,14 +2503,16 @@ class BaseHighState(object):
|
|||
)
|
||||
if contents:
|
||||
found = 1
|
||||
tops[self.opts['environment']] = [
|
||||
compile_template(
|
||||
contents,
|
||||
self.state.rend,
|
||||
self.state.opts['renderer'],
|
||||
saltenv=self.opts['environment']
|
||||
)
|
||||
]
|
||||
tops[self.opts['environment']] = [
|
||||
compile_template(
|
||||
contents,
|
||||
self.state.rend,
|
||||
self.state.opts['renderer'],
|
||||
saltenv=self.opts['environment']
|
||||
)
|
||||
]
|
||||
else:
|
||||
tops[self.opts['environment']] = [{}]
|
||||
elif self.opts['top_file_merging_strategy'] == 'merge':
|
||||
found = 0
|
||||
if self.opts.get('state_top_saltenv', False):
|
||||
|
@ -2521,28 +2523,6 @@ class BaseHighState(object):
|
|||
)
|
||||
if contents:
|
||||
found = found + 1
|
||||
else:
|
||||
log.debug('No contents loaded for env: {0}'.format(saltenv))
|
||||
|
||||
tops[saltenv].append(
|
||||
compile_template(
|
||||
contents,
|
||||
self.state.rend,
|
||||
self.state.opts['renderer'],
|
||||
saltenv=saltenv
|
||||
)
|
||||
)
|
||||
else:
|
||||
for saltenv in self._get_envs():
|
||||
contents = self.client.cache_file(
|
||||
self.opts['state_top'],
|
||||
saltenv
|
||||
)
|
||||
if contents:
|
||||
found = found + 1
|
||||
else:
|
||||
log.debug('No contents loaded for env: {0}'.format(saltenv))
|
||||
|
||||
tops[saltenv].append(
|
||||
compile_template(
|
||||
contents,
|
||||
|
@ -2551,6 +2531,28 @@ class BaseHighState(object):
|
|||
saltenv=saltenv
|
||||
)
|
||||
)
|
||||
else:
|
||||
tops[saltenv].append({})
|
||||
log.debug('No contents loaded for env: {0}'.format(saltenv))
|
||||
else:
|
||||
for saltenv in self._get_envs():
|
||||
contents = self.client.cache_file(
|
||||
self.opts['state_top'],
|
||||
saltenv
|
||||
)
|
||||
if contents:
|
||||
found = found + 1
|
||||
tops[saltenv].append(
|
||||
compile_template(
|
||||
contents,
|
||||
self.state.rend,
|
||||
self.state.opts['renderer'],
|
||||
saltenv=saltenv
|
||||
)
|
||||
)
|
||||
else:
|
||||
tops[saltenv].append({})
|
||||
log.debug('No contents loaded for env: {0}'.format(saltenv))
|
||||
if found > 1:
|
||||
log.warning('Top file merge strategy set to \'merge\' and multiple top files found. '
|
||||
'Top file merging order is undefined; '
|
||||
|
|
|
@ -532,8 +532,8 @@ def mod_watch(name,
|
|||
The name of the init or rc script used to manage the service
|
||||
|
||||
sfun
|
||||
The original function which triggered the mod_watch call
|
||||
(`service.running`, for example).
|
||||
Required. The original function which triggered the mod_watch call.
|
||||
Must be one of ``running`` or ``dead``.
|
||||
|
||||
sig
|
||||
The string to search for when looking for the service process with ps
|
||||
|
@ -587,7 +587,7 @@ def mod_watch(name,
|
|||
if not past_participle:
|
||||
past_participle = verb + 'ed'
|
||||
else:
|
||||
ret['comment'] = 'Unable to trigger watch for service.{0}'.format(sfun)
|
||||
ret['comment'] = 'sfun must be set to either "running" or "dead"'
|
||||
ret['result'] = False
|
||||
return ret
|
||||
|
||||
|
|
|
@ -189,6 +189,8 @@ def configurable_test_state(name, changes=True, result=True, comment=''):
|
|||
Do we return successfully or not?
|
||||
Accepts True, False, and 'Random'
|
||||
Default is True
|
||||
If test is True and changes is True, this will be None. If test is
|
||||
True and and changes is False, this will be True.
|
||||
comment:
|
||||
String to fill the comment field with.
|
||||
Default is ''
|
||||
|
@ -199,33 +201,29 @@ def configurable_test_state(name, changes=True, result=True, comment=''):
|
|||
'result': False,
|
||||
'comment': comment
|
||||
}
|
||||
change_data = {
|
||||
'testing': {
|
||||
'old': 'Unchanged',
|
||||
'new': 'Something pretended to change'
|
||||
}
|
||||
}
|
||||
|
||||
if changes == 'Random':
|
||||
if random.choice([True, False]):
|
||||
# Following the docs as written here
|
||||
# http://docs.saltstack.com/ref/states/writing.html#return-data
|
||||
ret['changes'] = {
|
||||
'testing': {
|
||||
'old': 'Unchanged',
|
||||
'new': 'Something pretended to change'
|
||||
}
|
||||
}
|
||||
ret['changes'] = change_data
|
||||
elif changes is True:
|
||||
# If changes is True we place our dummy change dictionary into it.
|
||||
# Following the docs as written here
|
||||
# http://docs.saltstack.com/ref/states/writing.html#return-data
|
||||
ret['changes'] = {
|
||||
'testing': {
|
||||
'old': 'Unchanged',
|
||||
'new': 'Something pretended to change'
|
||||
}
|
||||
}
|
||||
ret['changes'] = change_data
|
||||
elif changes is False:
|
||||
ret['changes'] = {}
|
||||
else:
|
||||
err = ('You have specified the state option \'Changes\' with'
|
||||
' invalid arguments. It must be either '
|
||||
' \'True\', \'False\', or \'Random\'')
|
||||
' invalid arguments. It must be either '
|
||||
' \'True\', \'False\', or \'Random\'')
|
||||
raise SaltInvocationError(err)
|
||||
|
||||
if result == 'Random':
|
||||
|
@ -242,8 +240,8 @@ def configurable_test_state(name, changes=True, result=True, comment=''):
|
|||
'\'Random\'')
|
||||
|
||||
if __opts__['test']:
|
||||
ret['result'] = None
|
||||
ret['comment'] = 'This is a test'
|
||||
ret['result'] = True if changes is False else None
|
||||
ret['comment'] = 'This is a test' if not comment else comment
|
||||
|
||||
return ret
|
||||
|
||||
|
|
|
@ -14,29 +14,40 @@ def __virtual__():
|
|||
return 'win_servermanager' if 'win_servermanager.install' in __salt__ else False
|
||||
|
||||
|
||||
def installed(name, recurse=False, force=False):
|
||||
def installed(name,
|
||||
recurse=False,
|
||||
force=False,
|
||||
source=None,
|
||||
restart=False,
|
||||
exclude=None):
|
||||
'''
|
||||
Install the windows feature
|
||||
|
||||
name:
|
||||
short name of the feature (the right column in win_servermanager.list_available)
|
||||
|
||||
recurse:
|
||||
install all sub-features as well
|
||||
|
||||
force:
|
||||
if the feature is installed but on of its sub-features are not installed set this to True to force
|
||||
the installation of the sub-features
|
||||
Args:
|
||||
name (str): Short name of the feature (the right column in
|
||||
win_servermanager.list_available)
|
||||
recurse (Optional[bool]): install all sub-features as well
|
||||
force (Optional[bool]): if the feature is installed but one of its
|
||||
sub-features are not installed set this to True to force the
|
||||
installation of the sub-features
|
||||
source (Optional[str]): Path to the source files if missing from the
|
||||
target system. None means that the system will use windows update
|
||||
services to find the required files. Default is None
|
||||
restart (Optional[bool]): Restarts the computer when installation is
|
||||
complete, if required by the role/feature installed. Default is
|
||||
False
|
||||
exclude (Optional[str]): The name of the feature to exclude when
|
||||
installing the named feature.
|
||||
|
||||
Note:
|
||||
Some features require reboot after un/installation. If so, until the server is restarted
|
||||
other features can not be installed!
|
||||
Some features require reboot after un/installation. If so, until the
|
||||
server is restarted other features can not be installed!
|
||||
|
||||
Example:
|
||||
|
||||
Run ``salt MinionName win_servermanager.list_available`` to get a list of available roles and features. Use
|
||||
the name in the right column. Do not use the role or feature names mentioned in the PKGMGR documentation. In
|
||||
this example for IIS-WebServerRole the name to be used is Web-Server.
|
||||
Run ``salt MinionName win_servermanager.list_available`` to get a list
|
||||
of available roles and features. Use the name in the right column. Do
|
||||
not use the role or feature names mentioned in the PKGMGR documentation.
|
||||
In this example for IIS-WebServerRole the name to be used is Web-Server.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
|
@ -73,7 +84,8 @@ def installed(name, recurse=False, force=False):
|
|||
ret['changes'] = {}
|
||||
|
||||
# Install the features
|
||||
status = __salt__['win_servermanager.install'](name, recurse)
|
||||
status = __salt__['win_servermanager.install'](
|
||||
name, recurse, source, restart, exclude)
|
||||
|
||||
ret['result'] = status['Success']
|
||||
if not ret['result']:
|
||||
|
@ -91,23 +103,27 @@ def installed(name, recurse=False, force=False):
|
|||
return ret
|
||||
|
||||
|
||||
def removed(name):
|
||||
def removed(name, remove_payload=False, restart=False):
|
||||
'''
|
||||
Remove the windows feature
|
||||
|
||||
name:
|
||||
short name of the feature (the right column in win_servermanager.list_available)
|
||||
Args:
|
||||
name (str): Short name of the feature (the right column in
|
||||
win_servermanager.list_available)
|
||||
remove_payload (Optional[bool]): True will case the feature to be
|
||||
removed from the side-by-side store
|
||||
restart (Optional[bool]): Restarts the computer when uninstall is
|
||||
complete, if required by the role/feature removed. Default is False
|
||||
|
||||
.. note::
|
||||
|
||||
Some features require a reboot after uninstallation. If so the feature will not be completely uninstalled until
|
||||
the server is restarted.
|
||||
Note:
|
||||
Some features require a reboot after uninstallation. If so the feature
|
||||
will not be completely uninstalled until the server is restarted.
|
||||
|
||||
Example:
|
||||
|
||||
Run ``salt MinionName win_servermanager.list_installed`` to get a list of all features installed. Use the top
|
||||
name listed for each feature, not the indented one. Do not use the role or feature names mentioned in the
|
||||
PKGMGR documentation.
|
||||
Run ``salt MinionName win_servermanager.list_installed`` to get a list
|
||||
of all features installed. Use the top name listed for each feature, not
|
||||
the indented one. Do not use the role or feature names mentioned in the
|
||||
PKGMGR documentation.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
|
@ -134,7 +150,7 @@ def removed(name):
|
|||
ret['changes'] = {}
|
||||
|
||||
# Remove the features
|
||||
status = __salt__['win_servermanager.remove'](name)
|
||||
status = __salt__['win_servermanager.remove'](name, remove_payload, restart)
|
||||
|
||||
ret['result'] = status['Success']
|
||||
if not ret['result']:
|
||||
|
|
|
@ -1045,11 +1045,14 @@ class Pygit2(GitProvider):
|
|||
return None
|
||||
remote_head = 'refs/remotes/origin/' + branch_name
|
||||
if remote_head not in refs:
|
||||
log.error(
|
||||
'Unable to find remote ref \'{0}\' in {1} remote '
|
||||
'\'{2}\''.format(head_ref, self.role, self.id)
|
||||
)
|
||||
return None
|
||||
# No remote ref for HEAD exists. This can happen in
|
||||
# the first-time git_pillar checkout when when the
|
||||
# remote repo does not have a master branch. Since
|
||||
# we need a HEAD reference to keep pygit2 from
|
||||
# throwing an error, and none exists in
|
||||
# refs/remotes/origin, we'll just point HEAD at the
|
||||
# remote_ref.
|
||||
remote_head = remote_ref
|
||||
self.repo.create_reference(
|
||||
head_ref,
|
||||
self.repo.lookup_reference(remote_head).target
|
||||
|
|
151
tests/integration/modules/gem.py
Normal file
151
tests/integration/modules/gem.py
Normal file
|
@ -0,0 +1,151 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Integration tests for Ruby Gem module
|
||||
'''
|
||||
|
||||
# Import Python libs
|
||||
from __future__ import absolute_import
|
||||
import platform
|
||||
|
||||
# Import Salt Testing libs
|
||||
from salttesting import skipIf
|
||||
from salttesting.helpers import ensure_in_syspath, destructiveTest
|
||||
ensure_in_syspath('../../')
|
||||
|
||||
# Import salt libs
|
||||
import integration
|
||||
import salt.utils
|
||||
import salt.utils.http
|
||||
|
||||
GEM = 'rake'
|
||||
GEM_VER = '11.1.2'
|
||||
OLD_GEM = 'thor'
|
||||
OLD_VERSION = '0.17.0'
|
||||
DEFAULT_GEMS = ['bigdecimal', 'rake', 'json', 'rdoc']
|
||||
|
||||
ON_UBUNTU = False
|
||||
if 'Ubuntu' in platform.dist():
|
||||
ON_UBUNTU = True
|
||||
|
||||
|
||||
def check_status():
|
||||
'''
|
||||
Check the status of the rubygems source
|
||||
'''
|
||||
ret = salt.utils.http.query('https://rubygems.org', status=True)
|
||||
return ret['status'] == 200
|
||||
|
||||
|
||||
@destructiveTest
|
||||
@skipIf(not salt.utils.which('gem'), 'Gem is not available')
|
||||
@skipIf(not check_status(), 'External source \'https://rubygems.org\' is not available')
|
||||
class GemModuleTest(integration.ModuleCase):
|
||||
'''
|
||||
Validate gem module
|
||||
'''
|
||||
|
||||
def test_install_uninstall(self):
|
||||
'''
|
||||
gem.install
|
||||
gem.uninstall
|
||||
'''
|
||||
# Remove gem if it is already installed
|
||||
if self.run_function('gem.list', [GEM]):
|
||||
self.run_function('gem.uninstall', [GEM])
|
||||
|
||||
self.run_function('gem.install', [GEM])
|
||||
gem_list = self.run_function('gem.list', [GEM])
|
||||
self.assertIn(GEM, gem_list)
|
||||
|
||||
self.run_function('gem.uninstall', [GEM])
|
||||
self.assertFalse(self.run_function('gem.list', [GEM]))
|
||||
|
||||
def test_install_version(self):
|
||||
'''
|
||||
gem.install rake version=11.1.2
|
||||
'''
|
||||
# Remove gem if it is already installed
|
||||
if self.run_function('gem.list', [GEM]):
|
||||
self.run_function('gem.uninstall', [GEM])
|
||||
|
||||
self.run_function('gem.install', [GEM], version=GEM_VER)
|
||||
gem_list = self.run_function('gem.list', [GEM])
|
||||
self.assertIn(GEM, gem_list)
|
||||
self.assertIn(GEM_VER, gem_list[GEM])
|
||||
|
||||
self.run_function('gem.uninstall', [GEM])
|
||||
self.assertFalse(self.run_function('gem.list', [GEM]))
|
||||
|
||||
def test_list(self):
|
||||
'''
|
||||
gem.list
|
||||
'''
|
||||
self.run_function('gem.install', [GEM])
|
||||
|
||||
all_ret = self.run_function('gem.list')
|
||||
if not ON_UBUNTU:
|
||||
for gem in DEFAULT_GEMS:
|
||||
self.assertIn(gem, all_ret)
|
||||
|
||||
single_ret = self.run_function('gem.list', [GEM])
|
||||
self.assertIn(GEM, single_ret)
|
||||
self.assertIn(GEM_VER, single_ret[GEM])
|
||||
|
||||
self.run_function('gem.uninstall', [GEM])
|
||||
|
||||
def test_list_upgrades(self):
|
||||
'''
|
||||
gem.list_upgrades
|
||||
'''
|
||||
# install outdated gem
|
||||
self.run_function('gem.install', [OLD_GEM], version=OLD_VERSION)
|
||||
|
||||
ret = self.run_function('gem.list_upgrades')
|
||||
self.assertIn(OLD_GEM, ret)
|
||||
|
||||
self.run_function('gem.uninstall', [OLD_GEM])
|
||||
|
||||
def test_sources_add_remove(self):
|
||||
'''
|
||||
gem.sources_add
|
||||
gem.sources_remove
|
||||
'''
|
||||
source = 'http://gems.github.com'
|
||||
|
||||
self.run_function('gem.sources_add', [source])
|
||||
sources_list = self.run_function('gem.sources_list')
|
||||
self.assertIn(source, sources_list)
|
||||
|
||||
self.run_function('gem.sources_remove', [source])
|
||||
sources_list = self.run_function('gem.sources_list')
|
||||
self.assertNotIn(source, sources_list)
|
||||
|
||||
def test_update(self):
|
||||
'''
|
||||
gem.update
|
||||
'''
|
||||
# Remove gem if it is already installed
|
||||
if self.run_function('gem.list', [OLD_GEM]):
|
||||
self.run_function('gem.uninstall', [OLD_GEM])
|
||||
|
||||
self.run_function('gem.install', [OLD_GEM], version=OLD_VERSION)
|
||||
gem_list = self.run_function('gem.list', [OLD_GEM])
|
||||
self.assertEqual({'thor': ['0.17.0']}, gem_list)
|
||||
|
||||
self.run_function('gem.update', [OLD_GEM])
|
||||
gem_list = self.run_function('gem.list', [OLD_GEM])
|
||||
self.assertEqual({'thor': ['0.19.1', '0.17.0']}, gem_list)
|
||||
|
||||
self.run_function('gem.uninstall', [OLD_GEM])
|
||||
self.assertFalse(self.run_function('gem.list', [OLD_GEM]))
|
||||
|
||||
def test_udpate_system(self):
|
||||
'''
|
||||
gem.udpate_system
|
||||
'''
|
||||
ret = self.run_function('gem.update_system')
|
||||
self.assertTrue(ret)
|
||||
|
||||
if __name__ == '__main__':
|
||||
from integration import run_tests
|
||||
run_tests(GemModuleTest)
|
|
@ -53,6 +53,63 @@ _PKG_TARGETS_EPOCH = {
|
|||
}
|
||||
|
||||
|
||||
def pkgmgr_avail(run_function, grains):
|
||||
'''
|
||||
Return True if the package manager is available for use
|
||||
'''
|
||||
def proc_fd_lsof(path):
|
||||
'''
|
||||
Return True if any entry in /proc/locks points to path. Example data:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# cat /proc/locks
|
||||
1: FLOCK ADVISORY WRITE 596 00:0f:10703 0 EOF
|
||||
2: FLOCK ADVISORY WRITE 14590 00:0f:11282 0 EOF
|
||||
3: POSIX ADVISORY WRITE 653 00:0f:11422 0 EOF
|
||||
'''
|
||||
import glob
|
||||
# https://www.centos.org/docs/5/html/5.2/Deployment_Guide/s2-proc-locks.html
|
||||
locks = run_function('cmd.run', ['cat /proc/locks']).splitlines()
|
||||
for line in locks:
|
||||
fields = line.split()
|
||||
try:
|
||||
major, minor, inode = fields[5].split(':')
|
||||
inode = int(inode)
|
||||
except (IndexError, ValueError):
|
||||
return False
|
||||
|
||||
for fd in glob.glob('/proc/*/fd'):
|
||||
fd_path = os.path.realpath(fd)
|
||||
# If the paths match and the inode is locked
|
||||
if fd_path == path and os.stat(fd_path).st_ino == inode:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def get_lock(path):
|
||||
'''
|
||||
Return True if any locks are found for path
|
||||
'''
|
||||
# Try lsof if it's available
|
||||
if salt.utils.which('lsof'):
|
||||
lock = run_function('cmd.run', ['lsof {0}'.format(path)])
|
||||
return True if len(lock) else False
|
||||
|
||||
# Try to find any locks on path from /proc/locks
|
||||
elif grains.get('kernel') == 'Linux':
|
||||
return proc_fd_lsof(path)
|
||||
|
||||
return False
|
||||
|
||||
if 'Debian' in grains.get('os_family', ''):
|
||||
for path in ['/var/lib/apt/lists/lock']:
|
||||
if get_lock(path):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@destructiveTest
|
||||
@requires_salt_modules('pkg.version', 'pkg.latest_version')
|
||||
class PkgTest(integration.ModuleCase,
|
||||
|
@ -66,6 +123,10 @@ class PkgTest(integration.ModuleCase,
|
|||
'''
|
||||
This is a destructive test as it installs and then removes a package
|
||||
'''
|
||||
# Skip test if package manager not available
|
||||
if not pkgmgr_avail(self.run_function, self.run_function('grains.items')):
|
||||
self.skipTest('Package manager is not available')
|
||||
|
||||
os_family = grains.get('os_family', '')
|
||||
pkg_targets = _PKG_TARGETS.get(os_family, [])
|
||||
|
||||
|
@ -93,6 +154,10 @@ class PkgTest(integration.ModuleCase,
|
|||
'''
|
||||
This is a destructive test as it installs and then removes a package
|
||||
'''
|
||||
# Skip test if package manager not available
|
||||
if not pkgmgr_avail(self.run_function, self.run_function('grains.items')):
|
||||
self.skipTest('Package manager is not available')
|
||||
|
||||
os_family = grains.get('os_family', '')
|
||||
pkg_targets = _PKG_TARGETS.get(os_family, [])
|
||||
|
||||
|
@ -134,6 +199,10 @@ class PkgTest(integration.ModuleCase,
|
|||
'''
|
||||
This is a destructive test as it installs and then removes two packages
|
||||
'''
|
||||
# Skip test if package manager not available
|
||||
if not pkgmgr_avail(self.run_function, self.run_function('grains.items')):
|
||||
self.skipTest('Package manager is not available')
|
||||
|
||||
os_family = grains.get('os_family', '')
|
||||
pkg_targets = _PKG_TARGETS.get(os_family, [])
|
||||
|
||||
|
@ -146,7 +215,7 @@ class PkgTest(integration.ModuleCase,
|
|||
# If this assert fails, we need to find new targets, this test needs to
|
||||
# be able to test successful installation of packages, so these
|
||||
# packages need to not be installed before we run the states below
|
||||
# self.assertFalse(any(version.values()))
|
||||
#self.assertFalse(any(version.values()))
|
||||
|
||||
ret = self.run_state('pkg.installed', name=None, pkgs=pkg_targets)
|
||||
self.assertSaltTrueReturn(ret)
|
||||
|
@ -159,6 +228,10 @@ class PkgTest(integration.ModuleCase,
|
|||
'''
|
||||
This is a destructive test as it installs and then removes two packages
|
||||
'''
|
||||
# Skip test if package manager not available
|
||||
if not pkgmgr_avail(self.run_function, self.run_function('grains.items')):
|
||||
self.skipTest('Package manager is not available')
|
||||
|
||||
os_family = grains.get('os_family', '')
|
||||
pkg_targets = _PKG_TARGETS.get(os_family, [])
|
||||
|
||||
|
@ -201,6 +274,10 @@ class PkgTest(integration.ModuleCase,
|
|||
'''
|
||||
This is a destructive test as it installs and then removes a package
|
||||
'''
|
||||
# Skip test if package manager not available
|
||||
if not pkgmgr_avail(self.run_function, self.run_function('grains.items')):
|
||||
self.skipTest('Package manager is not available')
|
||||
|
||||
os_name = grains.get('os', '')
|
||||
target = _PKG_TARGETS_32.get(os_name, '')
|
||||
|
||||
|
@ -232,6 +309,10 @@ class PkgTest(integration.ModuleCase,
|
|||
'''
|
||||
This is a destructive test as it installs and then removes a package
|
||||
'''
|
||||
# Skip test if package manager not available
|
||||
if not pkgmgr_avail(self.run_function, self.run_function('grains.items')):
|
||||
self.skipTest('Package manager is not available')
|
||||
|
||||
os_name = grains.get('os', '')
|
||||
target = _PKG_TARGETS_32.get(os_name, '')
|
||||
|
||||
|
@ -275,6 +356,10 @@ class PkgTest(integration.ModuleCase,
|
|||
|
||||
This is a destructive test as it installs a package
|
||||
'''
|
||||
# Skip test if package manager not available
|
||||
if not pkgmgr_avail(self.run_function, self.run_function('grains.items')):
|
||||
self.skipTest('Package manager is not available')
|
||||
|
||||
os_family = grains.get('os_family', '')
|
||||
os_version = grains.get('osmajorrelease', [''])[0]
|
||||
target = _PKG_TARGETS_DOT.get(os_family, {}).get(os_version)
|
||||
|
@ -299,6 +384,10 @@ class PkgTest(integration.ModuleCase,
|
|||
|
||||
This is a destructive test as it installs a package
|
||||
'''
|
||||
# Skip test if package manager not available
|
||||
if not pkgmgr_avail(self.run_function, self.run_function('grains.items')):
|
||||
self.skipTest('Package manager is not available')
|
||||
|
||||
os_family = grains.get('os_family', '')
|
||||
os_version = grains.get('osmajorrelease', [''])[0]
|
||||
target = _PKG_TARGETS_EPOCH.get(os_family, {}).get(os_version)
|
||||
|
@ -323,6 +412,9 @@ class PkgTest(integration.ModuleCase,
|
|||
|
||||
This is a destructive test as it installs a package
|
||||
'''
|
||||
# Skip test if package manager not available
|
||||
if not pkgmgr_avail(self.run_function, self.run_function('grains.items')):
|
||||
self.skipTest('Package manager is not available')
|
||||
|
||||
ret = self.run_function('state.sls', mods='pkg_latest_epoch')
|
||||
self.assertSaltTrueReturn(ret)
|
||||
|
@ -336,6 +428,9 @@ class PkgTest(integration.ModuleCase,
|
|||
a seperate method so I can add the requires_salt_modules
|
||||
decorator to only the pkg.info_installed command.
|
||||
'''
|
||||
# Skip test if package manager not available
|
||||
if not pkgmgr_avail(self.run_function, self.run_function('grains.items')):
|
||||
self.skipTest('Package manager is not available')
|
||||
|
||||
package = 'bash-completion'
|
||||
pkgquery = 'version'
|
||||
|
|
705
tests/integration/states/service.py
Normal file
705
tests/integration/states/service.py
Normal file
|
@ -0,0 +1,705 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Tests for the service state
|
||||
'''
|
||||
# Import python libs
|
||||
from __future__ import absolute_import
|
||||
import os
|
||||
|
||||
# Import Salt Testing libs
|
||||
from salttesting import skipIf
|
||||
from salttesting.helpers import ensure_in_syspath, destructiveTest
|
||||
ensure_in_syspath('../../')
|
||||
|
||||
# Import salt libs
|
||||
from integration import ModuleCase, SaltReturnAssertsMixIn
|
||||
|
||||
|
||||
# used to cache the status of whether the package was installed for quick test
|
||||
# skipping if it was not
|
||||
PKG_INSTALLED = None
|
||||
|
||||
|
||||
def installed(run_function, package):
|
||||
'''
|
||||
Install apache prior to running tests so that they may be skipped if the
|
||||
package fails to download
|
||||
'''
|
||||
global PKG_INSTALLED
|
||||
if not PKG_INSTALLED:
|
||||
run_function('state.single', ['pkg.installed', package])
|
||||
PKG_INSTALLED = True if run_function('pkg.version', [package]) else False
|
||||
return PKG_INSTALLED
|
||||
|
||||
|
||||
@destructiveTest
|
||||
@skipIf(os.geteuid() != 0, 'You must be logged in as root to run this test')
|
||||
class ServiceTest(ModuleCase,
|
||||
SaltReturnAssertsMixIn):
|
||||
'''
|
||||
Test service state module
|
||||
'''
|
||||
def setUp(self):
|
||||
'''
|
||||
Setup package and service names
|
||||
'''
|
||||
# Taken from https://github.com/saltstack-formulas/apache-formula/blob/master/apache/map.jinja
|
||||
os_family = self.run_function('grains.get', ['os_family'])
|
||||
|
||||
if os_family == 'Debian':
|
||||
self.package = 'apache2'
|
||||
self.service = 'apache2'
|
||||
elif os_family == 'RedHat':
|
||||
self.package = 'httpd'
|
||||
self.service = 'httpd'
|
||||
elif os_family == 'Suse':
|
||||
self.package = 'apache2'
|
||||
self.service = 'apache2'
|
||||
elif os_family == 'FreeBSD':
|
||||
self.package = 'apache22'
|
||||
self.service = 'apache22'
|
||||
elif os_family == 'MacOS':
|
||||
self.package = 'homebrew/apache/httpd24'
|
||||
self.service = 'org.apache.httpd'
|
||||
else:
|
||||
self.skipTest('This platform, {0}, has not yet been configured'
|
||||
' to run this test'.format(os_family))
|
||||
|
||||
def test_aaa_setUp_package(self):
|
||||
'''
|
||||
Install apache package
|
||||
'''
|
||||
installed(self.run_function, self.package)
|
||||
|
||||
def test_zzz_tearDown_package(self):
|
||||
'''
|
||||
Remove apache package
|
||||
'''
|
||||
# Skip if package was not installed
|
||||
if not PKG_INSTALLED:
|
||||
self.skipTest('Package containing service used by test was not installed')
|
||||
|
||||
self.run_function('state.single', ['pkg.removed', self.package])
|
||||
|
||||
def test_running(self):
|
||||
'''
|
||||
Test service.running
|
||||
'''
|
||||
# Skip test if package was not installed
|
||||
if not PKG_INSTALLED:
|
||||
self.skipTest('Package containing service used by test was not installed')
|
||||
|
||||
# Configure state parameters
|
||||
state_params = [
|
||||
'service.running',
|
||||
'name={0}'.format(self.service),
|
||||
]
|
||||
|
||||
# Setup initial state, run base test and inductive test
|
||||
self.run_function('state.single', ['service.dead', self.service])
|
||||
start_ret = self.run_function('state.single', state_params)
|
||||
already_ret = self.run_function('state.single', state_params)
|
||||
|
||||
# Validate base state
|
||||
self.assertSaltTrueReturn(start_ret)
|
||||
self.assertInSaltComment('Started Service {0}'.format(self.service), start_ret)
|
||||
self.assertSaltStateChangesEqual(start_ret, {self.service: True})
|
||||
|
||||
# Validate inductive state
|
||||
self.assertSaltTrueReturn(already_ret)
|
||||
self.assertInSaltComment('The service {0} is already running'.format(self.service), already_ret)
|
||||
self.assertSaltStateChangesEqual(already_ret, {})
|
||||
|
||||
def test_running_test(self):
|
||||
'''
|
||||
Test service.running with test=True
|
||||
'''
|
||||
# Skip test if package was not installed
|
||||
if not PKG_INSTALLED:
|
||||
self.skipTest('Package containing service used by test was not installed')
|
||||
|
||||
# Configure state parameters
|
||||
state_params = [
|
||||
'service.running',
|
||||
'name={0}'.format(self.service),
|
||||
'test=True',
|
||||
]
|
||||
|
||||
# apply the state in test mode
|
||||
self.run_function('state.single', ['service.dead', self.service])
|
||||
test_ret = self.run_function('state.single', state_params)
|
||||
# Validate test state
|
||||
self.assertSaltNoneReturn(test_ret)
|
||||
self.assertInSaltComment('Service {0} is set to start'.format(self.service), test_ret)
|
||||
self.assertSaltStateChangesEqual(test_ret, {})
|
||||
|
||||
def test_running_enabled(self):
|
||||
'''
|
||||
Test service.running with enable=True
|
||||
'''
|
||||
# Skip test if package was not installed
|
||||
if not PKG_INSTALLED:
|
||||
self.skipTest('Package containing service used by test was not installed')
|
||||
|
||||
# Skip test if functionality not present on system
|
||||
for func in 'enable', 'enabled':
|
||||
if not self.run_function('sys.doc', ['service.{0}'.format(func)]):
|
||||
self.skipTest('service.{0} function is not available on this system'.format(func))
|
||||
|
||||
# Configure state parameters
|
||||
enabled_params = [
|
||||
'service.running',
|
||||
'name={0}'.format(self.service),
|
||||
'enable=True',
|
||||
]
|
||||
|
||||
# Apply state with enable parameter True
|
||||
self.run_function('state.single', ['service.dead', self.service, 'enable=False'])
|
||||
enabled_ret = self.run_function('state.single', enabled_params)
|
||||
# Validate enabled state
|
||||
self.assertSaltTrueReturn(enabled_ret)
|
||||
self.assertInSaltComment('enabled', enabled_ret)
|
||||
self.assertSaltStateChangesEqual(enabled_ret, {self.service: True})
|
||||
|
||||
# Apply state a second time with enable parameter True
|
||||
self.run_function('state.single', ['service.dead', self.service])
|
||||
already_enabled_ret = self.run_function('state.single', enabled_params)
|
||||
# Validate enabled state
|
||||
self.assertSaltTrueReturn(already_enabled_ret)
|
||||
self.assertInSaltComment('already enabled', already_enabled_ret)
|
||||
self.assertSaltStateChangesEqual(already_enabled_ret, {self.service: True})
|
||||
|
||||
def test_running_disabled(self):
|
||||
'''
|
||||
Test service.running with enable=False
|
||||
'''
|
||||
# Skip test if package was not installed
|
||||
if not PKG_INSTALLED:
|
||||
self.skipTest('Package containing service used by test was not installed')
|
||||
|
||||
# Skip test if functionality not present on system
|
||||
for func in 'disable', 'disabled':
|
||||
if not self.run_function('sys.doc', ['service.{0}'.format(func)]):
|
||||
self.skipTest('service.{0} function is not available on this system'.format(func))
|
||||
|
||||
# Configure state parameters
|
||||
disabled_params = [
|
||||
'service.running',
|
||||
'name={0}'.format(self.service),
|
||||
'enable=False',
|
||||
]
|
||||
|
||||
# Apply state with enable parameter False
|
||||
self.run_function('state.single', ['service.dead', self.service, 'enable=True'])
|
||||
disabled_ret = self.run_function('state.single', disabled_params)
|
||||
# Validate disabled state
|
||||
self.assertSaltTrueReturn(disabled_ret)
|
||||
self.assertInSaltComment('disabled', disabled_ret)
|
||||
self.assertSaltStateChangesEqual(disabled_ret, {self.service: True})
|
||||
|
||||
# Apply state a second time with enable parameter False
|
||||
self.run_function('state.single', ['service.dead', self.service])
|
||||
already_disabled_ret = self.run_function('state.single', disabled_params)
|
||||
self.assertSaltStateChangesEqual(disabled_ret, {self.service: True})
|
||||
# Validate disabled state
|
||||
self.assertSaltTrueReturn(already_disabled_ret)
|
||||
self.assertInSaltComment('already disabled', already_disabled_ret)
|
||||
self.assertSaltStateChangesEqual(already_disabled_ret, {self.service: True})
|
||||
|
||||
def test_running_delayed(self):
|
||||
'''
|
||||
Test service.running with delay
|
||||
'''
|
||||
# Skip test if package was not installed
|
||||
if not PKG_INSTALLED:
|
||||
self.skipTest('Package containing service used by test was not installed')
|
||||
|
||||
# Configure state parameters
|
||||
init_delay = 6.2832
|
||||
delayed_params = [
|
||||
'service.running',
|
||||
'name={0}'.format(self.service),
|
||||
'init_delay={0}'.format(init_delay)
|
||||
]
|
||||
state_key = 'service_|-{0}_|-{0}_|-running'.format(self.service)
|
||||
|
||||
# Apply state with init_delay parameter
|
||||
self.run_function('state.single', ['service.dead', self.service])
|
||||
delayed_ret = self.run_function('state.single', delayed_params)
|
||||
# Validate delayed state
|
||||
self.assertSaltTrueReturn(delayed_ret)
|
||||
self.assertInSaltComment('Delayed return for {0} seconds'.format(init_delay), delayed_ret)
|
||||
self.assertSaltStateChangesEqual(delayed_ret, {self.service: True})
|
||||
self.assertTrue(delayed_ret[state_key]['duration']/1000 >= init_delay)
|
||||
|
||||
def test_dead(self):
|
||||
'''
|
||||
Test service.dead
|
||||
'''
|
||||
# Skip test if package was not installed
|
||||
if not PKG_INSTALLED:
|
||||
self.skipTest('Package containing service used by test was not installed')
|
||||
|
||||
# Configure state parameters
|
||||
state_params = [
|
||||
'service.dead',
|
||||
'name={0}'.format(self.service),
|
||||
]
|
||||
|
||||
# Setup initial state, run base test and inductive test
|
||||
self.run_function('state.single', ['service.running', self.service, 'init_delay=3'])
|
||||
kill_ret = self.run_function('state.single', state_params)
|
||||
already_ret = self.run_function('state.single', state_params)
|
||||
|
||||
# Validate base state
|
||||
self.assertSaltTrueReturn(kill_ret)
|
||||
self.assertInSaltComment('Service {0} was killed'.format(self.service), kill_ret)
|
||||
self.assertSaltStateChangesEqual(kill_ret, {self.service: True})
|
||||
|
||||
# Validate inductive state
|
||||
self.assertSaltTrueReturn(already_ret)
|
||||
self.assertInSaltComment('The service {0} is already dead'.format(self.service), already_ret)
|
||||
self.assertSaltStateChangesEqual(already_ret, {})
|
||||
|
||||
def test_dead_test(self):
|
||||
'''
|
||||
Test service.dead with test=True
|
||||
'''
|
||||
# Skip test if package was not installed
|
||||
if not PKG_INSTALLED:
|
||||
self.skipTest('Package containing service used by test was not installed')
|
||||
|
||||
# Configure state parameters
|
||||
state_params = [
|
||||
'service.dead',
|
||||
'name={0}'.format(self.service),
|
||||
'test=True',
|
||||
]
|
||||
|
||||
# apply the state in test mode
|
||||
self.run_function('state.single', ['service.running', self.service, 'init_delay=3'])
|
||||
test_ret = self.run_function('state.single', state_params)
|
||||
# Validate base state
|
||||
self.assertSaltNoneReturn(test_ret)
|
||||
self.assertInSaltComment('Service {0} is set to be killed'.format(self.service), test_ret)
|
||||
self.assertSaltStateChangesEqual(test_ret, {})
|
||||
|
||||
def test_dead_enabled(self):
|
||||
'''
|
||||
Test service.dead with enable=True
|
||||
'''
|
||||
# Skip test if package was not installed
|
||||
if not PKG_INSTALLED:
|
||||
self.skipTest('Package containing service used by test was not installed')
|
||||
|
||||
# Skip test if functionality not present on system
|
||||
for func in 'enable', 'enabled':
|
||||
if not self.run_function('sys.doc', ['service.{0}'.format(func)]):
|
||||
self.skipTest('service.{0} function is not available on this system'.format(func))
|
||||
|
||||
# Configure state parameters
|
||||
enabled_params = [
|
||||
'service.dead',
|
||||
'name={0}'.format(self.service),
|
||||
'enable=True',
|
||||
]
|
||||
|
||||
# Apply state with enable parameter True
|
||||
self.run_function('state.single', ['service.running', self.service, 'enable=False', 'init_delay=3'])
|
||||
enabled_ret = self.run_function('state.single', enabled_params)
|
||||
# Validate enabled state
|
||||
self.assertSaltTrueReturn(enabled_ret)
|
||||
self.assertInSaltComment('enabled', enabled_ret)
|
||||
self.assertSaltStateChangesEqual(enabled_ret, {self.service: True})
|
||||
|
||||
# Apply state a second time with enable parameter True
|
||||
self.run_function('state.single', ['service.running', self.service, 'init_delay=3'])
|
||||
already_enabled_ret = self.run_function('state.single', enabled_params)
|
||||
# Validate enabled state
|
||||
self.assertSaltTrueReturn(already_enabled_ret)
|
||||
self.assertInSaltComment('already enabled', already_enabled_ret)
|
||||
self.assertSaltStateChangesEqual(already_enabled_ret, {self.service: True})
|
||||
|
||||
def test_dead_disabled(self):
|
||||
'''
|
||||
Test service.dead with enable=False
|
||||
'''
|
||||
# Skip test if package was not installed
|
||||
if not PKG_INSTALLED:
|
||||
self.skipTest('Package containing service used by test was not installed')
|
||||
|
||||
# Skip test if functionality not present on system
|
||||
for func in 'disable', 'disabled':
|
||||
if not self.run_function('sys.doc', ['service.{0}'.format(func)]):
|
||||
self.skipTest('service.{0} function is not available on this system'.format(func))
|
||||
|
||||
# Configure state parameters
|
||||
disabled_params = [
|
||||
'service.dead',
|
||||
'name={0}'.format(self.service),
|
||||
'enable=False',
|
||||
]
|
||||
|
||||
# Apply state with enable parameter False
|
||||
self.run_function('state.single', ['service.running', self.service, 'enable=True', 'init_delay=3'])
|
||||
disabled_ret = self.run_function('state.single', disabled_params)
|
||||
# Validate disabled state
|
||||
self.assertSaltTrueReturn(disabled_ret)
|
||||
self.assertInSaltComment('disabled', disabled_ret)
|
||||
self.assertSaltStateChangesEqual(disabled_ret, {self.service: True})
|
||||
|
||||
# Apply state a second time with enable parameter False
|
||||
self.run_function('state.single', ['service.running', self.service, 'init_delay=3'])
|
||||
already_disabled_ret = self.run_function('state.single', disabled_params)
|
||||
self.assertSaltStateChangesEqual(disabled_ret, {self.service: True})
|
||||
# Validate disabled state
|
||||
self.assertSaltTrueReturn(already_disabled_ret)
|
||||
self.assertInSaltComment('already disabled', already_disabled_ret)
|
||||
self.assertSaltStateChangesEqual(already_disabled_ret, {self.service: True})
|
||||
|
||||
def test_enabled(self):
|
||||
'''
|
||||
Test service.enabled
|
||||
'''
|
||||
# Skip test if package was not installed
|
||||
if not PKG_INSTALLED:
|
||||
self.skipTest('Package containing service used by test was not installed')
|
||||
|
||||
# Skip test if functionality not present on system
|
||||
for func in 'enable', 'enabled':
|
||||
if not self.run_function('sys.doc', ['service.{0}'.format(func)]):
|
||||
self.skipTest('service.{0} function is not available on this system'.format(func))
|
||||
|
||||
# Configure state parameters
|
||||
state_params = [
|
||||
'service.enabled',
|
||||
'name={0}'.format(self.service),
|
||||
]
|
||||
|
||||
# Apply state
|
||||
self.run_function('state.single', ['service.disabled', self.service])
|
||||
enabled_ret = self.run_function('state.single', state_params)
|
||||
# Validate enabled state
|
||||
self.assertSaltTrueReturn(enabled_ret)
|
||||
self.assertInSaltComment('enabled', enabled_ret)
|
||||
self.assertSaltStateChangesEqual(enabled_ret, {self.service: True})
|
||||
|
||||
# Apply state a second time
|
||||
already_enabled_ret = self.run_function('state.single', state_params)
|
||||
# Validate enabled state
|
||||
self.assertSaltTrueReturn(already_enabled_ret)
|
||||
self.assertInSaltComment('already enabled', already_enabled_ret)
|
||||
self.assertSaltStateChangesEqual(already_enabled_ret, {})
|
||||
|
||||
def test_enabled_test(self):
|
||||
'''
|
||||
Test service.enabled with test=True
|
||||
'''
|
||||
# Skip test if package was not installed
|
||||
if not PKG_INSTALLED:
|
||||
self.skipTest('Package containing service used by test was not installed')
|
||||
|
||||
# Skip test if functionality not present on system
|
||||
for func in 'enable', 'enabled':
|
||||
if not self.run_function('sys.doc', ['service.{0}'.format(func)]):
|
||||
self.skipTest('service.{0} function is not available on this system'.format(func))
|
||||
|
||||
# Configure state parameters
|
||||
state_params = [
|
||||
'service.enabled',
|
||||
'name={0}'.format(self.service),
|
||||
'test=True',
|
||||
]
|
||||
|
||||
# apply the state in test mode
|
||||
self.run_function('state.single', ['service.disabled', self.service])
|
||||
test_ret = self.run_function('state.single', state_params)
|
||||
# Validate base state
|
||||
self.assertSaltNoneReturn(test_ret)
|
||||
self.assertInSaltComment('Service {0} set to be enabled'.format(self.service), test_ret)
|
||||
self.assertSaltStateChangesEqual(test_ret, {})
|
||||
|
||||
def test_disabled(self):
|
||||
'''
|
||||
Test service.disabled
|
||||
'''
|
||||
# Skip test if package was not installed
|
||||
if not PKG_INSTALLED:
|
||||
self.skipTest('Package containing service used by test was not installed')
|
||||
|
||||
# Skip test if functionality not present on system
|
||||
for func in 'disable', 'disabled':
|
||||
if not self.run_function('sys.doc', ['service.{0}'.format(func)]):
|
||||
self.skipTest('service.{0} function is not available on this system'.format(func))
|
||||
|
||||
# Configure state parameters
|
||||
state_params = [
|
||||
'service.disabled',
|
||||
'name={0}'.format(self.service),
|
||||
]
|
||||
|
||||
# Apply state
|
||||
self.run_function('state.single', ['service.enabled', self.service])
|
||||
disabled_ret = self.run_function('state.single', state_params)
|
||||
# Validate disabled state
|
||||
self.assertSaltTrueReturn(disabled_ret)
|
||||
self.assertInSaltComment('disabled', disabled_ret)
|
||||
self.assertSaltStateChangesEqual(disabled_ret, {self.service: True})
|
||||
|
||||
# Apply state a second time
|
||||
already_disabled_ret = self.run_function('state.single', state_params)
|
||||
# Validate disabled state
|
||||
self.assertSaltTrueReturn(already_disabled_ret)
|
||||
self.assertInSaltComment('already disabled', already_disabled_ret)
|
||||
self.assertSaltStateChangesEqual(already_disabled_ret, {})
|
||||
|
||||
def test_disabled_test(self):
|
||||
'''
|
||||
Test service.disabled with test=True
|
||||
'''
|
||||
# Skip test if package was not installed
|
||||
if not PKG_INSTALLED:
|
||||
self.skipTest('Package containing service used by test was not installed')
|
||||
|
||||
# Skip test if functionality not present on system
|
||||
for func in 'disable', 'disabled':
|
||||
if not self.run_function('sys.doc', ['service.{0}'.format(func)]):
|
||||
self.skipTest('service.{0} function is not available on this system'.format(func))
|
||||
|
||||
# Configure state parameters
|
||||
state_params = [
|
||||
'service.disabled',
|
||||
'name={0}'.format(self.service),
|
||||
'test=True',
|
||||
]
|
||||
|
||||
# apply the state in test mode
|
||||
self.run_function('state.single', ['service.enabled', self.service])
|
||||
test_ret = self.run_function('state.single', state_params)
|
||||
# Validate base state
|
||||
self.assertSaltNoneReturn(test_ret)
|
||||
self.assertInSaltComment('Service {0} set to be disabled'.format(self.service), test_ret)
|
||||
self.assertSaltStateChangesEqual(test_ret, {})
|
||||
|
||||
def test_mod_watch_test(self):
|
||||
'''
|
||||
Test service.mod_watch with test=True
|
||||
'''
|
||||
# Skip test if package was not installed
|
||||
if not PKG_INSTALLED:
|
||||
self.skipTest('Package containing service used by test was not installed')
|
||||
|
||||
# Configure state parameters
|
||||
state_params = [
|
||||
'service.mod_watch',
|
||||
'name={0}'.format(self.service),
|
||||
'sfun=running',
|
||||
'test=True',
|
||||
]
|
||||
|
||||
# apply the state in test mode
|
||||
self.run_function('state.single', ['service.dead', self.service])
|
||||
test_ret = self.run_function('state.single', state_params)
|
||||
# Validate base state
|
||||
self.assertSaltNoneReturn(test_ret)
|
||||
self.assertInSaltComment('Service is set to be started', test_ret)
|
||||
self.assertSaltStateChangesEqual(test_ret, {})
|
||||
|
||||
def test_mod_watch_no_sfun(self):
|
||||
'''
|
||||
Test service.mod_watch without sfun argument
|
||||
'''
|
||||
# Skip test if package was not installed
|
||||
if not PKG_INSTALLED:
|
||||
self.skipTest('Package containing service used by test was not installed')
|
||||
|
||||
# Configure state parameters
|
||||
state_params = [
|
||||
'service.mod_watch',
|
||||
'name={0}'.format(self.service),
|
||||
]
|
||||
|
||||
# Apply the state
|
||||
mod_watch_ret = self.run_function('state.single', state_params)
|
||||
# Validate state return
|
||||
self.assertSaltFalseReturn(mod_watch_ret)
|
||||
self.assertInSaltComment('sfun must be set to either "running" or "dead"', mod_watch_ret)
|
||||
self.assertSaltStateChangesEqual(mod_watch_ret, {})
|
||||
|
||||
def test_mod_watch_running(self):
|
||||
'''
|
||||
Test service.mod_watch with sfun=running
|
||||
'''
|
||||
# Skip test if package was not installed
|
||||
if not PKG_INSTALLED:
|
||||
self.skipTest('Package containing service used by test was not installed')
|
||||
|
||||
# Configure state parameters
|
||||
state_params = [
|
||||
'service.mod_watch',
|
||||
'name={0}'.format(self.service),
|
||||
'sfun=running',
|
||||
]
|
||||
|
||||
# Apply state
|
||||
self.run_function('state.single', ['service.dead', self.service])
|
||||
running_ret = self.run_function('state.single', state_params)
|
||||
# Validate state return
|
||||
self.assertSaltTrueReturn(running_ret)
|
||||
self.assertInSaltComment('Service started', running_ret)
|
||||
self.assertSaltStateChangesEqual(running_ret, {self.service: True})
|
||||
|
||||
# Apply state a second time
|
||||
already_running_ret = self.run_function('state.single', state_params)
|
||||
# Validate disabled state
|
||||
self.assertSaltTrueReturn(already_running_ret)
|
||||
self.assertInSaltComment('Service restarted', already_running_ret)
|
||||
self.assertSaltStateChangesEqual(already_running_ret, {self.service: True})
|
||||
|
||||
def test_mod_watch_running_reload(self):
|
||||
'''
|
||||
Test service.mod_watch with sfun=running and reload=True
|
||||
'''
|
||||
# Skip test if package was not installed
|
||||
if not PKG_INSTALLED:
|
||||
self.skipTest('Package containing service used by test was not installed')
|
||||
|
||||
# Skip test if functionality not present on system
|
||||
if not self.run_function('sys.doc', ['service.reload']):
|
||||
self.skipTest('service.reload function is not available on this system')
|
||||
|
||||
# Configure state parameters
|
||||
state_params = [
|
||||
'service.mod_watch',
|
||||
'name={0}'.format(self.service),
|
||||
'sfun=running',
|
||||
'reload=True',
|
||||
]
|
||||
|
||||
# Apply state
|
||||
self.run_function('state.single', ['service.running', self.service, 'init_delay=3'])
|
||||
state_ret = self.run_function('state.single', state_params)
|
||||
# Validate disabled state
|
||||
self.assertSaltTrueReturn(state_ret)
|
||||
self.assertInSaltComment('Service reloaded', state_ret)
|
||||
self.assertSaltStateChangesEqual(state_ret, {self.service: True})
|
||||
|
||||
def test_mod_watch_running_force(self):
|
||||
'''
|
||||
Test service.mod_watch with sfun=running and force=True
|
||||
'''
|
||||
# Skip test if package was not installed
|
||||
if not PKG_INSTALLED:
|
||||
self.skipTest('Package containing service used by test was not installed')
|
||||
|
||||
# Skip test if functionality not present on system
|
||||
for func in 'reload', 'force_reload':
|
||||
if not self.run_function('sys.doc', ['service.{0}'.format(func)]):
|
||||
self.skipTest('service.{0} function is not available on this system'.format(func))
|
||||
|
||||
# Configure state parameters
|
||||
state_params = [
|
||||
'service.mod_watch',
|
||||
'name={0}'.format(self.service),
|
||||
'sfun=running',
|
||||
'reload=True',
|
||||
'force=True',
|
||||
]
|
||||
|
||||
# Apply state
|
||||
self.run_function('state.single', ['service.running', self.service, 'init_delay=3'])
|
||||
state_ret = self.run_function('state.single', state_params)
|
||||
# Validate disabled state
|
||||
self.assertSaltTrueReturn(state_ret)
|
||||
self.assertInSaltComment('Service forcefully reloaded', state_ret)
|
||||
self.assertSaltStateChangesEqual(state_ret, {self.service: True})
|
||||
|
||||
def test_mod_watch_running_full_restart(self):
|
||||
'''
|
||||
Test service.mod_watch with sfun=running and full_restart=True
|
||||
'''
|
||||
# Skip test if package was not installed
|
||||
if not PKG_INSTALLED:
|
||||
self.skipTest('Package containing service used by test was not installed')
|
||||
|
||||
# Skip test if functionality not present on system
|
||||
if not self.run_function('sys.doc', ['service.full_restart']):
|
||||
self.skipTest('service.full_restart function is not available on this system')
|
||||
|
||||
# Configure state parameters
|
||||
state_params = [
|
||||
'service.mod_watch',
|
||||
'name={0}'.format(self.service),
|
||||
'sfun=running',
|
||||
'full_restart=True',
|
||||
]
|
||||
|
||||
# Apply state
|
||||
self.run_function('state.single', ['service.running', self.service, 'init_delay=3'])
|
||||
state_ret = self.run_function('state.single', state_params)
|
||||
# Validate state return
|
||||
self.assertSaltTrueReturn(state_ret)
|
||||
self.assertInSaltComment('Service fully restarted', state_ret)
|
||||
self.assertSaltStateChangesEqual(state_ret, {self.service: True})
|
||||
|
||||
def test_mod_watch_running_init_delay(self):
|
||||
'''
|
||||
Test service.mod_watch with sfun=running and init_delay
|
||||
'''
|
||||
# Skip test if package was not installed
|
||||
if not PKG_INSTALLED:
|
||||
self.skipTest('Package containing service used by test was not installed')
|
||||
|
||||
# Configure state parameters
|
||||
init_delay = 6.2832
|
||||
state_params = [
|
||||
'service.mod_watch',
|
||||
'name={0}'.format(self.service),
|
||||
'sfun=running',
|
||||
'init_delay={0}'.format(init_delay),
|
||||
]
|
||||
state_key = 'service_|-{0}_|-{0}_|-mod_watch'.format(self.service)
|
||||
|
||||
# Apply state
|
||||
self.run_function('state.single', ['service.dead', self.service])
|
||||
state_ret = self.run_function('state.single', state_params)
|
||||
# Validate state return
|
||||
self.assertSaltTrueReturn(state_ret)
|
||||
self.assertInSaltComment('Service started', state_ret)
|
||||
self.assertSaltStateChangesEqual(state_ret, {self.service: True})
|
||||
self.assertTrue(state_ret[state_key]['duration']/1000 >= init_delay)
|
||||
|
||||
def test_mod_watch_dead(self):
|
||||
'''
|
||||
Test service.mod_watch with sfun=dead
|
||||
'''
|
||||
# Skip test if package was not installed
|
||||
if not PKG_INSTALLED:
|
||||
self.skipTest('Package containing service used by test was not installed')
|
||||
|
||||
# Configure state parameters
|
||||
state_params = [
|
||||
'service.mod_watch',
|
||||
'name={0}'.format(self.service),
|
||||
'sfun=dead',
|
||||
]
|
||||
|
||||
# Apply state
|
||||
self.run_function('state.single', ['service.running', self.service, 'init_delay=3'])
|
||||
mod_watch_ret = self.run_function('state.single', state_params)
|
||||
# Validate state return
|
||||
self.assertSaltTrueReturn(mod_watch_ret)
|
||||
self.assertInSaltComment('Service stopped', mod_watch_ret)
|
||||
self.assertSaltStateChangesEqual(mod_watch_ret, {self.service: True})
|
||||
|
||||
# Apply state a second time
|
||||
already_mod_watch_ret = self.run_function('state.single', state_params)
|
||||
# Validate disabled state
|
||||
self.assertSaltTrueReturn(already_mod_watch_ret)
|
||||
self.assertInSaltComment('Service is already stopped', already_mod_watch_ret)
|
||||
self.assertSaltStateChangesEqual(already_mod_watch_ret, {})
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from integration import run_tests
|
||||
run_tests(ServiceTest)
|
|
@ -112,14 +112,26 @@ class GroupAddTestCase(TestCase):
|
|||
'''
|
||||
Tests if specified user gets added in the group.
|
||||
'''
|
||||
mock = MagicMock(return_value={'retcode': 0})
|
||||
with patch.dict(groupadd.__grains__, {'kernel': 'Linux'}):
|
||||
with patch.dict(groupadd.__salt__, {'cmd.retcode': mock}):
|
||||
self.assertFalse(groupadd.adduser('test', 'root'))
|
||||
os_version_list = [
|
||||
{'grains': {'kernel': 'Linux', 'os_family': 'RedHat', 'osmajorrelease': '5'},
|
||||
'cmd': 'gpasswd -a root test'},
|
||||
|
||||
with patch.dict(groupadd.__grains__, {'kernel': ''}):
|
||||
with patch.dict(groupadd.__salt__, {'cmd.retcode': mock}):
|
||||
self.assertFalse(groupadd.adduser('test', 'root'))
|
||||
{'grains': {'kernel': 'Linux', 'os_family': 'Suse', 'osrelease_info': [11, 2]},
|
||||
'cmd': 'usermod -A test root'},
|
||||
|
||||
{'grains': {'kernel': 'Linux'},
|
||||
'cmd': 'gpasswd --add root test'},
|
||||
|
||||
{'grains': {'kernel': 'OTHERKERNEL'},
|
||||
'cmd': 'usermod -G test root'},
|
||||
]
|
||||
|
||||
for os_version in os_version_list:
|
||||
mock = MagicMock(return_value={'retcode': 0})
|
||||
with patch.dict(groupadd.__grains__, os_version['grains']):
|
||||
with patch.dict(groupadd.__salt__, {'cmd.retcode': mock}):
|
||||
self.assertFalse(groupadd.adduser('test', 'root'))
|
||||
groupadd.__salt__['cmd.retcode'].assert_called_once_with(os_version['cmd'], python_shell=False)
|
||||
|
||||
# 'deluser' function tests: 1
|
||||
|
||||
|
@ -127,22 +139,34 @@ class GroupAddTestCase(TestCase):
|
|||
'''
|
||||
Tests if specified user gets deleted from the group.
|
||||
'''
|
||||
mock_ret = MagicMock(return_value={'retcode': 0})
|
||||
mock_info = MagicMock(return_value={'passwd': '*',
|
||||
'gid': 0,
|
||||
'name': 'test',
|
||||
'members': ['root']})
|
||||
with patch.dict(groupadd.__grains__, {'kernel': 'Linux'}):
|
||||
with patch.dict(groupadd.__salt__, {'cmd.retcode': mock_ret,
|
||||
'group.info': mock_info}):
|
||||
self.assertFalse(groupadd.deluser('test', 'root'))
|
||||
os_version_list = [
|
||||
{'grains': {'kernel': 'Linux', 'os_family': 'RedHat', 'osmajorrelease': '5'},
|
||||
'cmd': 'gpasswd -d root test'},
|
||||
|
||||
mock_stdout = MagicMock(return_value={'cmd.run_stdout': 1})
|
||||
with patch.dict(groupadd.__grains__, {'kernel': 'OpenBSD'}):
|
||||
with patch.dict(groupadd.__salt__, {'cmd.retcode': mock_ret,
|
||||
'group.info': mock_info,
|
||||
'cmd.run_stdout': mock_stdout}):
|
||||
self.assertTrue(groupadd.deluser('foo', 'root'))
|
||||
{'grains': {'kernel': 'Linux', 'os_family': 'Suse', 'osrelease_info': [11, 2]},
|
||||
'cmd': 'usermod -R test root'},
|
||||
|
||||
{'grains': {'kernel': 'Linux'},
|
||||
'cmd': 'gpasswd --del root test'},
|
||||
|
||||
{'grains': {'kernel': 'OpenBSD'},
|
||||
'cmd': 'usermod -S foo root'},
|
||||
]
|
||||
|
||||
for os_version in os_version_list:
|
||||
mock_ret = MagicMock(return_value={'retcode': 0})
|
||||
mock_stdout = MagicMock(return_value='test foo')
|
||||
mock_info = MagicMock(return_value={'passwd': '*',
|
||||
'gid': 0,
|
||||
'name': 'test',
|
||||
'members': ['root']})
|
||||
|
||||
with patch.dict(groupadd.__grains__, os_version['grains']):
|
||||
with patch.dict(groupadd.__salt__, {'cmd.retcode': mock_ret,
|
||||
'group.info': mock_info,
|
||||
'cmd.run_stdout': mock_stdout}):
|
||||
self.assertFalse(groupadd.deluser('test', 'root'))
|
||||
groupadd.__salt__['cmd.retcode'].assert_called_once_with(os_version['cmd'], python_shell=False)
|
||||
|
||||
# 'deluser' function tests: 1
|
||||
|
||||
|
@ -150,24 +174,36 @@ class GroupAddTestCase(TestCase):
|
|||
'''
|
||||
Tests if members of the group, get replaced with a provided list.
|
||||
'''
|
||||
mock_ret = MagicMock(return_value={'retcode': 0})
|
||||
mock_info = MagicMock(return_value={'passwd': '*',
|
||||
'gid': 0,
|
||||
'name': 'test',
|
||||
'members': ['root']})
|
||||
with patch.dict(groupadd.__grains__, {'kernel': 'Linux'}):
|
||||
with patch.dict(groupadd.__salt__, {'cmd.retcode': mock_ret,
|
||||
'group.info': mock_info}):
|
||||
self.assertFalse(groupadd.members('test', ['foo']))
|
||||
os_version_list = [
|
||||
{'grains': {'kernel': 'Linux', 'os_family': 'RedHat', 'osmajorrelease': '5'},
|
||||
'cmd': "gpasswd -M foo test"},
|
||||
|
||||
mock_stdout = MagicMock(return_value={'cmd.run_stdout': 1})
|
||||
mock = MagicMock()
|
||||
with patch.dict(groupadd.__grains__, {'kernel': 'OpenBSD'}):
|
||||
with patch.dict(groupadd.__salt__, {'cmd.retcode': mock_ret,
|
||||
'group.info': mock_info,
|
||||
'cmd.run_stdout': mock_stdout,
|
||||
'cmd.run': mock}):
|
||||
self.assertFalse(groupadd.members('foo', ['root']))
|
||||
{'grains': {'kernel': 'Linux', 'os_family': 'Suse', 'osrelease_info': [11, 2]},
|
||||
'cmd': 'groupmod -A foo test'},
|
||||
|
||||
{'grains': {'kernel': 'Linux'},
|
||||
'cmd': 'gpasswd --members foo test'},
|
||||
|
||||
{'grains': {'kernel': 'OpenBSD'},
|
||||
'cmd': 'usermod -G test foo'},
|
||||
]
|
||||
|
||||
for os_version in os_version_list:
|
||||
mock_ret = MagicMock(return_value={'retcode': 0})
|
||||
mock_stdout = MagicMock(return_value={'cmd.run_stdout': 1})
|
||||
mock_info = MagicMock(return_value={'passwd': '*',
|
||||
'gid': 0,
|
||||
'name': 'test',
|
||||
'members': ['root']})
|
||||
mock = MagicMock(return_value=True)
|
||||
|
||||
with patch.dict(groupadd.__grains__, os_version['grains']):
|
||||
with patch.dict(groupadd.__salt__, {'cmd.retcode': mock_ret,
|
||||
'group.info': mock_info,
|
||||
'cmd.run_stdout': mock_stdout,
|
||||
'cmd.run': mock}):
|
||||
self.assertFalse(groupadd.members('test', 'foo'))
|
||||
groupadd.__salt__['cmd.retcode'].assert_called_once_with(os_version['cmd'], python_shell=False)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -1,179 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
:codeauthor: :email:`Rupesh Tare <rupesht@saltstack.com>`
|
||||
'''
|
||||
|
||||
# Import Python Libs
|
||||
from __future__ import absolute_import
|
||||
|
||||
# Import Salt Testing Libs
|
||||
from salttesting import TestCase, skipIf
|
||||
from salttesting.mock import (
|
||||
MagicMock,
|
||||
patch,
|
||||
NO_MOCK,
|
||||
NO_MOCK_REASON
|
||||
)
|
||||
from salttesting.helpers import ensure_in_syspath
|
||||
|
||||
ensure_in_syspath('../../')
|
||||
|
||||
# Import Salt Libs
|
||||
from salt.modules import match
|
||||
import salt.ext.six.moves.builtins as __builtin__ # pylint: disable=import-error,no-name-in-module
|
||||
|
||||
# Globals
|
||||
match.__grains__ = {}
|
||||
match.__salt__ = {}
|
||||
match.__opts__ = {}
|
||||
match.__pillar__ = {}
|
||||
|
||||
|
||||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
class MatchTestCase(TestCase):
|
||||
'''
|
||||
Test cases for salt.modules.match
|
||||
'''
|
||||
@patch('salt.minion.Matcher')
|
||||
def test_compound(self, mock_matcher):
|
||||
'''
|
||||
Test for Return True if the minion ID matches the given compound target
|
||||
'''
|
||||
with patch.dict(match.__grains__, {'id': 101}):
|
||||
|
||||
mock_matcher.side_effect = MagicMock()
|
||||
with patch.object(mock_matcher, 'compound_match', MagicMock()):
|
||||
self.assertTrue(match.compound('tgt'))
|
||||
|
||||
mock_matcher.side_effect = MagicMock(return_value='B')
|
||||
self.assertFalse(match.compound('tgt'))
|
||||
|
||||
@patch('salt.minion.Matcher')
|
||||
def test_ipcidr(self, mock_matcher):
|
||||
'''
|
||||
Test for Return True if the minion matches the given ipcidr target
|
||||
'''
|
||||
with patch.dict(match.__grains__, {'id': 101}):
|
||||
|
||||
mock_matcher.side_effect = MagicMock()
|
||||
with patch.object(mock_matcher, 'ipcidr_match', MagicMock()):
|
||||
self.assertTrue(match.ipcidr('tgt'))
|
||||
|
||||
mock_matcher.side_effect = MagicMock(return_value='B')
|
||||
self.assertFalse(match.ipcidr('tgt'))
|
||||
|
||||
@patch('salt.minion.Matcher')
|
||||
def test_pillar(self, mock_matcher):
|
||||
'''
|
||||
Test for Return True if the minion matches the given pillar target.
|
||||
'''
|
||||
with patch.dict(match.__grains__, {'id': 101}):
|
||||
|
||||
mock_matcher.side_effect = MagicMock()
|
||||
with patch.object(mock_matcher, 'pillar_match', MagicMock()):
|
||||
self.assertTrue(match.pillar('tgt'))
|
||||
|
||||
mock_matcher.side_effect = MagicMock(return_value='B')
|
||||
self.assertFalse(match.pillar('tgt'))
|
||||
|
||||
@patch('salt.minion.Matcher')
|
||||
def test_data(self, mock_matcher):
|
||||
'''
|
||||
Test for Return True if the minion matches the given data target
|
||||
'''
|
||||
with patch.dict(match.__grains__, {'id': 101}):
|
||||
|
||||
mock_matcher.side_effect = MagicMock()
|
||||
with patch.object(mock_matcher, 'data_match', MagicMock()):
|
||||
self.assertTrue(match.data('tgt'))
|
||||
|
||||
mock_matcher.side_effect = MagicMock(return_value='B')
|
||||
self.assertFalse(match.data('tgt'))
|
||||
|
||||
@patch('salt.minion.Matcher')
|
||||
def test_grain_pcre(self, mock_matcher):
|
||||
'''
|
||||
Test for Return True if the minion matches the given grain_pcre target
|
||||
'''
|
||||
with patch.dict(match.__grains__, {'id': 101}):
|
||||
|
||||
mock_matcher.side_effect = MagicMock()
|
||||
with patch.object(mock_matcher, 'grain_pcre_match', MagicMock()):
|
||||
self.assertTrue(match.grain_pcre('tgt'))
|
||||
|
||||
mock_matcher.side_effect = MagicMock(return_value='B')
|
||||
self.assertFalse(match.grain_pcre('tgt'))
|
||||
|
||||
@patch('salt.minion.Matcher')
|
||||
def test_grain(self, mock_matcher):
|
||||
'''
|
||||
Test for Return True if the minion matches the given grain target
|
||||
'''
|
||||
with patch.dict(match.__grains__, {'id': 101}):
|
||||
|
||||
mock_matcher.side_effect = MagicMock()
|
||||
with patch.object(mock_matcher, 'grain_match', MagicMock()):
|
||||
self.assertTrue(match.grain('tgt'))
|
||||
|
||||
mock_matcher.side_effect = MagicMock(return_value='B')
|
||||
self.assertFalse(match.grain('tgt'))
|
||||
|
||||
@patch('salt.minion.Matcher')
|
||||
def test_list_(self, mock_matcher):
|
||||
'''
|
||||
Test for Return True if the minion ID matches the given list target
|
||||
'''
|
||||
with patch.dict(match.__grains__, {'id': 101}):
|
||||
|
||||
mock_matcher.side_effect = MagicMock()
|
||||
with patch.object(mock_matcher, 'list_match', MagicMock()):
|
||||
self.assertTrue(match.list_('tgt'))
|
||||
|
||||
mock_matcher.side_effect = MagicMock(return_value='B')
|
||||
self.assertFalse(match.list_('tgt'))
|
||||
|
||||
@patch('salt.minion.Matcher')
|
||||
def test_pcre(self, mock_matcher):
|
||||
'''
|
||||
Test for Return True if the minion ID matches the given pcre target
|
||||
'''
|
||||
mock_matcher.side_effect = MagicMock()
|
||||
with patch.dict(match.__grains__, {'id': 101}):
|
||||
with patch.object(mock_matcher, 'pcre_match', MagicMock()):
|
||||
self.assertTrue(match.pcre('tgt'))
|
||||
|
||||
mock_matcher.side_effect = MagicMock(return_value='B')
|
||||
with patch.dict(match.__grains__, {'id': 101}):
|
||||
self.assertFalse(match.pcre('tgt'))
|
||||
|
||||
@patch('salt.minion.Matcher')
|
||||
def test_glob(self, mock_matcher):
|
||||
'''
|
||||
Test for Return True if the minion ID matches the given glob target
|
||||
'''
|
||||
with patch.dict(match.__grains__, {'id': 101}):
|
||||
|
||||
mock_matcher.side_effect = MagicMock()
|
||||
with patch.object(mock_matcher, 'glob_match', MagicMock()):
|
||||
self.assertTrue(match.glob('tgt'))
|
||||
|
||||
mock_matcher.side_effect = MagicMock(return_value='B')
|
||||
self.assertFalse(match.glob('tgt'))
|
||||
|
||||
def test_filter_by(self):
|
||||
'''
|
||||
Test for Return the first match in a dictionary of target patterns
|
||||
'''
|
||||
with patch.object(__builtin__, 'dict', MagicMock()):
|
||||
|
||||
self.assertEqual(match.filter_by({'key': 'value'},
|
||||
minion_id=101), 'value')
|
||||
|
||||
self.assertEqual(match.filter_by({'key': 'value'}), 'value')
|
||||
|
||||
self.assertEqual(match.filter_by({}), None)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from integration import run_tests
|
||||
run_tests(MatchTestCase, needs_daemon=False)
|
|
@ -117,7 +117,7 @@ class PkgresTestCase(TestCase):
|
|||
'''
|
||||
Test to add a package to a dict of installed packages.
|
||||
'''
|
||||
self.assertIsNone(pkg_resource.add_pkg('pkgs', 'name', 'version'))
|
||||
self.assertIsNone(pkg_resource.add_pkg({'pkgs': []}, 'name', 'version'))
|
||||
|
||||
def test_sort_pkglist(self):
|
||||
'''
|
||||
|
|
|
@ -18,6 +18,7 @@ from salt.modules import win_servermanager
|
|||
|
||||
# Globals
|
||||
win_servermanager.__salt__ = {}
|
||||
win_servermanager.__grains__ = {}
|
||||
|
||||
|
||||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
|
@ -56,13 +57,15 @@ class WinServermanagerTestCase(TestCase):
|
|||
'FeatureResult':
|
||||
[{'DisplayName': 'Spongebob',
|
||||
'RestartNeeded': False}]})
|
||||
with patch.object(win_servermanager, '_pshell_json', mock):
|
||||
expected = {'ExitCode': 0,
|
||||
'DisplayName': 'Spongebob',
|
||||
'RestartNeeded': False,
|
||||
'Success': True}
|
||||
self.assertDictEqual(
|
||||
win_servermanager.install('Telnet-Client'), expected)
|
||||
with patch.dict(
|
||||
win_servermanager.__grains__, {'osversion': '10.0.15130'}):
|
||||
with patch.object(win_servermanager, '_pshell_json', mock):
|
||||
expected = {'ExitCode': 0,
|
||||
'DisplayName': 'Spongebob',
|
||||
'RestartNeeded': False,
|
||||
'Success': True}
|
||||
self.assertDictEqual(
|
||||
win_servermanager.install('Telnet-Client'), expected)
|
||||
|
||||
def test_remove(self):
|
||||
'''
|
||||
|
@ -73,13 +76,15 @@ class WinServermanagerTestCase(TestCase):
|
|||
'FeatureResult':
|
||||
[{'DisplayName': 'Spongebob',
|
||||
'RestartNeeded': False}]})
|
||||
with patch.object(win_servermanager, '_pshell_json', mock):
|
||||
expected = {'ExitCode': 0,
|
||||
'DisplayName': 'Spongebob',
|
||||
'RestartNeeded': False,
|
||||
'Success': True}
|
||||
self.assertDictEqual(
|
||||
win_servermanager.remove('Telnet-Client'), expected)
|
||||
with patch.dict(
|
||||
win_servermanager.__grains__, {'osversion': '10.0.15130'}):
|
||||
with patch.object(win_servermanager, '_pshell_json', mock):
|
||||
expected = {'ExitCode': 0,
|
||||
'DisplayName': 'Spongebob',
|
||||
'RestartNeeded': False,
|
||||
'Success': True}
|
||||
self.assertDictEqual(
|
||||
win_servermanager.remove('Telnet-Client'), expected)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -255,7 +255,7 @@ class ServiceTestCase(TestCase):
|
|||
'comment': 'Service is already stopped', 'name': 'salt',
|
||||
'result': True},
|
||||
{'changes': {},
|
||||
'comment': 'Unable to trigger watch for service.stack',
|
||||
'comment': 'sfun must be set to either "running" or "dead"',
|
||||
'name': 'salt', 'result': False},
|
||||
{'changes': {},
|
||||
'comment': 'Service is set to be started', 'name': 'salt',
|
||||
|
|
|
@ -18,6 +18,7 @@ from salttesting.mock import (
|
|||
ensure_in_syspath('../../')
|
||||
|
||||
# Import Salt Libs
|
||||
from salt.exceptions import SaltInvocationError
|
||||
from salt.states import test
|
||||
|
||||
# Globals
|
||||
|
@ -88,19 +89,200 @@ class TestTestCase(TestCase):
|
|||
|
||||
def test_configurable_test_state(self):
|
||||
'''
|
||||
Test of a configurable test state which
|
||||
determines its output based on the inputs.
|
||||
Test test.configurable_test_state with and without comment
|
||||
'''
|
||||
ret = {'name': 'salt',
|
||||
'changes': {},
|
||||
'result': True,
|
||||
'comment': ''}
|
||||
with patch.dict(test.__opts__, {"test": False}):
|
||||
ret.update({'changes': {'testing': {'new': 'Something pretended'
|
||||
' to change',
|
||||
'old': 'Unchanged'}},
|
||||
'comment': 'Success!'})
|
||||
self.assertDictEqual(test.succeed_with_changes('salt'), ret)
|
||||
# Configure mock parameters
|
||||
mock_name = 'cheese_shop'
|
||||
mock_comment = "I'm afraid we're fresh out of Red Leicester sir."
|
||||
mock_changes = {
|
||||
'testing': {
|
||||
'old': 'Unchanged',
|
||||
'new': 'Something pretended to change'
|
||||
}
|
||||
}
|
||||
|
||||
# Test default state with comment
|
||||
with patch.dict(test.__opts__, {'test': False}):
|
||||
mock_ret = {'name': mock_name,
|
||||
'changes': mock_changes,
|
||||
'result': True,
|
||||
'comment': ''}
|
||||
ret = test.configurable_test_state(mock_name)
|
||||
self.assertDictEqual(ret, mock_ret)
|
||||
|
||||
# Test default state without comment
|
||||
with patch.dict(test.__opts__, {'test': False}):
|
||||
mock_ret = {'name': mock_name,
|
||||
'changes': mock_changes,
|
||||
'result': True,
|
||||
'comment': mock_comment}
|
||||
ret = test.configurable_test_state(mock_name,
|
||||
comment=mock_comment)
|
||||
self.assertDictEqual(ret, mock_ret)
|
||||
|
||||
def test_configurable_test_state_changes(self):
|
||||
'''
|
||||
Test test.configurable_test_state with permutations of changes and with
|
||||
comment
|
||||
'''
|
||||
# Configure mock parameters
|
||||
mock_name = 'cheese_shop'
|
||||
mock_comment = "I'm afraid we're fresh out of Red Leicester sir."
|
||||
mock_changes = {
|
||||
'testing': {
|
||||
'old': 'Unchanged',
|
||||
'new': 'Something pretended to change'
|
||||
}
|
||||
}
|
||||
|
||||
# Test changes=Random and comment
|
||||
with patch.dict(test.__opts__, {'test': False}):
|
||||
ret = test.configurable_test_state(mock_name,
|
||||
changes='Random',
|
||||
comment=mock_comment)
|
||||
self.assertEqual(ret['name'], mock_name)
|
||||
self.assertIn(ret['changes'], [mock_changes, {}])
|
||||
self.assertEqual(ret['result'], True)
|
||||
self.assertEqual(ret['comment'], mock_comment)
|
||||
|
||||
# Test changes=True and comment
|
||||
with patch.dict(test.__opts__, {'test': False}):
|
||||
mock_ret = {'name': mock_name,
|
||||
'changes': mock_changes,
|
||||
'result': True,
|
||||
'comment': mock_comment}
|
||||
ret = test.configurable_test_state(mock_name,
|
||||
changes=True,
|
||||
comment=mock_comment)
|
||||
self.assertDictEqual(ret, mock_ret)
|
||||
|
||||
# Test changes=False and comment
|
||||
with patch.dict(test.__opts__, {'test': False}):
|
||||
mock_ret = {'name': mock_name,
|
||||
'changes': {},
|
||||
'result': True,
|
||||
'comment': mock_comment}
|
||||
ret = test.configurable_test_state(mock_name,
|
||||
changes=False,
|
||||
comment=mock_comment)
|
||||
self.assertDictEqual(ret, mock_ret)
|
||||
|
||||
# Test changes=Cheese
|
||||
with patch.dict(test.__opts__, {'test': False}):
|
||||
self.assertRaises(SaltInvocationError,
|
||||
test.configurable_test_state,
|
||||
mock_name,
|
||||
changes='Cheese')
|
||||
|
||||
def test_configurable_test_state_result(self):
|
||||
'''
|
||||
Test test.configurable_test_state with permutations of result and with
|
||||
comment
|
||||
'''
|
||||
# Configure mock parameters
|
||||
mock_name = 'cheese_shop'
|
||||
mock_comment = "I'm afraid we're fresh out of Red Leicester sir."
|
||||
mock_changes = {
|
||||
'testing': {
|
||||
'old': 'Unchanged',
|
||||
'new': 'Something pretended to change'
|
||||
}
|
||||
}
|
||||
|
||||
# Test result=Random and comment
|
||||
with patch.dict(test.__opts__, {'test': False}):
|
||||
ret = test.configurable_test_state(mock_name,
|
||||
result='Random',
|
||||
comment=mock_comment)
|
||||
self.assertEqual(ret['name'], mock_name)
|
||||
self.assertEqual(ret['changes'], mock_changes)
|
||||
self.assertIn(ret['result'], [True, False])
|
||||
self.assertEqual(ret['comment'], mock_comment)
|
||||
|
||||
# Test result=True and comment
|
||||
with patch.dict(test.__opts__, {'test': False}):
|
||||
mock_ret = {'name': mock_name,
|
||||
'changes': mock_changes,
|
||||
'result': True,
|
||||
'comment': mock_comment}
|
||||
ret = test.configurable_test_state(mock_name,
|
||||
result=True,
|
||||
comment=mock_comment)
|
||||
self.assertDictEqual(ret, mock_ret)
|
||||
|
||||
# Test result=False and comment
|
||||
with patch.dict(test.__opts__, {'test': False}):
|
||||
mock_ret = {'name': mock_name,
|
||||
'changes': mock_changes,
|
||||
'result': False,
|
||||
'comment': mock_comment}
|
||||
ret = test.configurable_test_state(mock_name,
|
||||
result=False,
|
||||
comment=mock_comment)
|
||||
self.assertDictEqual(ret, mock_ret)
|
||||
|
||||
# Test result=Cheese
|
||||
with patch.dict(test.__opts__, {'test': False}):
|
||||
self.assertRaises(SaltInvocationError,
|
||||
test.configurable_test_state,
|
||||
mock_name,
|
||||
result='Cheese')
|
||||
|
||||
def test_configurable_test_state_test(self):
|
||||
'''
|
||||
Test test.configurable_test_state with test=True with and without
|
||||
comment
|
||||
'''
|
||||
# Configure mock parameters
|
||||
mock_name = 'cheese_shop'
|
||||
mock_comment = "I'm afraid we're fresh out of Red Leicester sir."
|
||||
mock_changes = {
|
||||
'testing': {
|
||||
'old': 'Unchanged',
|
||||
'new': 'Something pretended to change'
|
||||
}
|
||||
}
|
||||
|
||||
# Test test=True without comment
|
||||
with patch.dict(test.__opts__, {'test': True}):
|
||||
mock_ret = {'name': mock_name,
|
||||
'changes': mock_changes,
|
||||
'result': None,
|
||||
'comment': 'This is a test'}
|
||||
ret = test.configurable_test_state(mock_name)
|
||||
self.assertDictEqual(ret, mock_ret)
|
||||
|
||||
# Test test=True with comment
|
||||
with patch.dict(test.__opts__, {'test': True}):
|
||||
mock_ret = {'name': mock_name,
|
||||
'changes': mock_changes,
|
||||
'result': None,
|
||||
'comment': mock_comment}
|
||||
ret = test.configurable_test_state(mock_name,
|
||||
comment=mock_comment)
|
||||
self.assertDictEqual(ret, mock_ret)
|
||||
|
||||
# Test test=True and changes=True with comment
|
||||
with patch.dict(test.__opts__, {'test': True}):
|
||||
mock_ret = {'name': mock_name,
|
||||
'changes': mock_changes,
|
||||
'result': None,
|
||||
'comment': mock_comment}
|
||||
ret = test.configurable_test_state(mock_name,
|
||||
changes=True,
|
||||
comment=mock_comment)
|
||||
self.assertDictEqual(ret, mock_ret)
|
||||
|
||||
# Test test=True and changes=False with comment
|
||||
with patch.dict(test.__opts__, {'test': True}):
|
||||
mock_ret = {'name': mock_name,
|
||||
'changes': {},
|
||||
'result': True,
|
||||
'comment': mock_comment}
|
||||
ret = test.configurable_test_state(mock_name,
|
||||
changes=False,
|
||||
comment=mock_comment)
|
||||
self.assertDictEqual(ret, mock_ret)
|
||||
|
||||
def test_mod_watch(self):
|
||||
'''
|
||||
|
|
Loading…
Add table
Reference in a new issue