mirror of
https://github.com/saltstack/salt.git
synced 2025-04-16 09:40:20 +00:00
Merge remote-tracking branch 'upstream/2015.5' into merge-forward-2015.8
Conflicts: doc/ref/configuration/minion.rst salt/config.py salt/modules/sudo.py tests/integration/states/file.py
This commit is contained in:
commit
24d51fb8f1
21 changed files with 2711 additions and 83 deletions
|
@ -48,6 +48,12 @@
|
|||
# The user to run salt.
|
||||
#user: root
|
||||
|
||||
# Setting sudo_user will cause salt to run all execution modules under an sudo
|
||||
# to the user given in sudo_user. The user under which the salt minion process
|
||||
# itself runs will still be that provided in the user config above, but all
|
||||
# execution modules run by the minion will be rerouted through sudo.
|
||||
#sudo_user: saltdev
|
||||
|
||||
# Specify the location of the daemon process ID file.
|
||||
#pidfile: /var/run/salt-minion.pid
|
||||
|
||||
|
@ -626,7 +632,7 @@
|
|||
#tcp_keepalive_intvl: -1
|
||||
|
||||
|
||||
###### Windows Software settings ######
|
||||
###### Windows Software settings ######
|
||||
############################################
|
||||
# Location of the repository cache file on the master:
|
||||
#win_repo_cachefile: 'salt://win/repo/winrepo.p'
|
||||
|
|
|
@ -195,6 +195,21 @@ need to be changed to the ownership of the new user.
|
|||
|
||||
sudo_user: root
|
||||
|
||||
.. conf_minion:: sudo_user
|
||||
|
||||
``sudo_user``
|
||||
--------
|
||||
|
||||
Default: ``''``
|
||||
|
||||
Setting ``sudo_user`` will cause salt to run all execution modules under an
|
||||
sudo to the user given in ``sudo_user``. The user under which the salt minion
|
||||
process itself runs will still be that provided in :conf_minion:`user` above,
|
||||
but all execution modules run by the minion will be rerouted through sudo.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
sudo_user: saltadm
|
||||
|
||||
.. conf_minion:: pidfile
|
||||
|
||||
|
|
|
@ -20,6 +20,14 @@ minion exe>` should match the contents of the corresponding md5 file.
|
|||
|
||||
.. admonition:: Download here
|
||||
|
||||
* 2015.5.2
|
||||
* `Salt-Minion-2015.5.2-x86-Setup.exe <http://docs.saltstack.com/downloads/Salt-Minion-2015.5.2-x86-Setup.exe>`__ | `md5 <http://docs.saltstack.com/downloads/Salt-Minion-2015.5.2-x86-Setup.exe.md5>`__
|
||||
* `Salt-Minion-2015.5.2-AMD64-Setup.exe <http://docs.saltstack.com/downloads/Salt-Minion-2015.5.2-AMD64-Setup.exe>`__ | `md5 <http://docs.saltstack.com/downloads/Salt-Minion-2015.5.2-AMD64-Setup.exe.md5>`__
|
||||
|
||||
* 2015.5.1-3
|
||||
* `Salt-Minion-2015.5.1-3-x86-Setup.exe <http://docs.saltstack.com/downloads/Salt-Minion-2015.5.1-3-x86-Setup.exe>`__ | `md5 <http://docs.saltstack.com/downloads/Salt-Minion-2015.5.1-3-x86-Setup.exe.md5>`__
|
||||
* `Salt-Minion-2015.5.1-3-AMD64-Setup.exe <http://docs.saltstack.com/downloads/Salt-Minion-2015.5.1-3-AMD64-Setup.exe>`__ | `md5 <http://docs.saltstack.com/downloads/Salt-Minion-2015.5.1-3-AMD64-Setup.exe.md5>`__
|
||||
|
||||
* 2015.5.0-2
|
||||
* `Salt-Minion-2015.5.0-2-x86-Setup.exe <http://docs.saltstack.com/downloads/Salt-Minion-2015.5.0-2-x86-Setup.exe>`__ | `md5 <http://docs.saltstack.com/downloads/Salt-Minion-2015.5.0-2-x86-Setup.exe.md5>`__
|
||||
* `Salt-Minion-2015.5.0-2-AMD64-Setup.exe <http://docs.saltstack.com/downloads/Salt-Minion-2015.5.0-2-AMD64-Setup.exe>`__ | `md5 <http://docs.saltstack.com/downloads/Salt-Minion-2015.5.0-2-AMD64-Setup.exe.md5>`__
|
||||
|
|
1819
doc/topics/releases/2015.5.3.rst
Normal file
1819
doc/topics/releases/2015.5.3.rst
Normal file
File diff suppressed because it is too large
Load diff
|
@ -162,8 +162,11 @@ class Batch(object):
|
|||
continue
|
||||
if self.opts.get('raw'):
|
||||
parts.update({part['id']: part})
|
||||
minion_tracker[queue]['minions'].remove(part['id'])
|
||||
else:
|
||||
parts.update(part)
|
||||
for id in part.keys():
|
||||
minion_tracker[queue]['minions'].remove(id)
|
||||
except StopIteration:
|
||||
# if a iterator is done:
|
||||
# - set it to inactive
|
||||
|
|
|
@ -684,6 +684,8 @@ VALID_OPTS = {
|
|||
|
||||
# Used by salt-api for master requests timeout
|
||||
'rest_timeout': int,
|
||||
|
||||
'sudo_user': str,
|
||||
}
|
||||
|
||||
# default configurations
|
||||
|
@ -846,6 +848,7 @@ DEFAULT_MINION_OPTS = {
|
|||
'zmq_monitor': False,
|
||||
'cache_sreqs': True,
|
||||
'cmd_safe': True,
|
||||
'sudo_user': '',
|
||||
}
|
||||
|
||||
DEFAULT_MASTER_OPTS = {
|
||||
|
|
|
@ -1579,6 +1579,9 @@ def build_interface(iface, iface_type, enabled, **settings):
|
|||
if iface_type not in _IFACE_TYPES:
|
||||
_raise_error_iface(iface, iface_type, _IFACE_TYPES)
|
||||
|
||||
if 'proto' not in settings:
|
||||
settings['proto'] = 'static'
|
||||
|
||||
if iface_type == 'slave':
|
||||
settings['slave'] = 'yes'
|
||||
if 'master' not in settings:
|
||||
|
|
|
@ -604,10 +604,13 @@ def get_sensor_data(**kwargs):
|
|||
|
||||
salt-call ipmi.get_sensor_data api_host=127.0.0.1 api_user=admin api_pass=pass
|
||||
'''
|
||||
import ast
|
||||
with _IpmiCommand(**kwargs) as s:
|
||||
data = {}
|
||||
for reading in s.get_sensor_data():
|
||||
data[reading['name']] = reading
|
||||
if reading:
|
||||
r = ast.literal_eval(repr(reading))
|
||||
data[r.pop('name')] = r
|
||||
return data
|
||||
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ def _dscl(cmd, ctype='create'):
|
|||
|
||||
def _first_avail_uid():
|
||||
uids = set(x.pw_uid for x in pwd.getpwall())
|
||||
for idx in range(501, 2 ** 32):
|
||||
for idx in range(501, 2 ** 24):
|
||||
if idx not in uids:
|
||||
return idx
|
||||
|
||||
|
|
|
@ -1,13 +1,43 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Allow for the calling of execution modules via sudo
|
||||
Allow for the calling of execution modules via sudo.
|
||||
|
||||
This module is invoked by the minion if the ``sudo_user`` minion config is
|
||||
present.
|
||||
|
||||
Example minion config:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
sudo_user: saltdev
|
||||
|
||||
Once this setting is made, any execution module call done by the minion will be
|
||||
run under ``sudo -u <sudo_user> salt-call``. For example, with the above
|
||||
minion config,
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt sudo_minion cmd.run 'cat /etc/sudoers'
|
||||
|
||||
is equivalent to
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo -u saltdev salt-call cmd.run 'cat /etc/sudoers'
|
||||
|
||||
being run on ``sudo_minion``.
|
||||
'''
|
||||
|
||||
# Import python libs
|
||||
from __future__ import absolute_import
|
||||
import json
|
||||
try:
|
||||
from shlex import quote as _cmd_quote # pylint: disable=E0611
|
||||
except ImportError:
|
||||
from pipes import quote as _cmd_quote
|
||||
|
||||
# Import salt libs
|
||||
from salt.exceptions import SaltInvocationError
|
||||
import salt.utils
|
||||
import salt.syspaths
|
||||
|
||||
|
@ -15,7 +45,7 @@ __virtualname__ = 'sudo'
|
|||
|
||||
|
||||
def __virtual__():
|
||||
if salt.utils.which('sudo'):
|
||||
if salt.utils.which('sudo') and __opts__.get('sudo_user'):
|
||||
return __virtualname__
|
||||
return False
|
||||
|
||||
|
@ -24,23 +54,45 @@ def salt_call(runas, fun, *args, **kwargs):
|
|||
'''
|
||||
Wrap a shell execution out to salt call with sudo
|
||||
|
||||
CLI Example::
|
||||
Example:
|
||||
|
||||
salt '*' sudo.salt_call root test.ping
|
||||
/etc/salt/minion
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
sudo_user: saltdev
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' test.ping # is run as saltdev user
|
||||
'''
|
||||
if fun == 'sudo.salt_call':
|
||||
__context__['retcode'] = 1
|
||||
raise SaltInvocationError('sudo.salt_call is not designed to be run '
|
||||
'directly, but is used by the minion when '
|
||||
'the sudo_user config is set.')
|
||||
|
||||
cmd = ['sudo',
|
||||
'-u', runas,
|
||||
'salt-call',
|
||||
'--out', 'json',
|
||||
'--metadata',
|
||||
'-c', salt.syspaths.CONFIG_DIR,
|
||||
'--',
|
||||
fun]
|
||||
for arg in args:
|
||||
cmd.append(arg)
|
||||
cmd.append(_cmd_quote(arg))
|
||||
for key in kwargs:
|
||||
cmd.append('{0}={1}'.format(key, kwargs[key]))
|
||||
cmd_ret = __salt__['cmd.run_all'](cmd, python_shell=False)
|
||||
cmd_meta = json.loads(cmd_ret['stdout'])['local']
|
||||
ret = cmd_meta['return']
|
||||
__context__['retcode'] = cmd_meta.get('retcode', 0)
|
||||
cmd.append(_cmd_quote('{0}={1}'.format(key, kwargs[key])))
|
||||
|
||||
cmd_ret = __salt__['cmd.run_all'](cmd, use_vt=True, python_shell=False)
|
||||
|
||||
if cmd_ret['retcode'] == 0:
|
||||
cmd_meta = json.loads(cmd_ret['stdout'])['local']
|
||||
ret = cmd_meta['return']
|
||||
__context__['retcode'] = cmd_meta.get('retcode', 0)
|
||||
else:
|
||||
ret = cmd_ret['stderr']
|
||||
__context__['retcode'] = cmd_ret['retcode']
|
||||
|
||||
return ret
|
||||
|
|
|
@ -697,7 +697,7 @@ def _validate_str_list(arg):
|
|||
elif isinstance(arg, Iterable) and not isinstance(arg, Mapping):
|
||||
return [str(item) for item in arg]
|
||||
else:
|
||||
return False
|
||||
return [str(arg)]
|
||||
|
||||
|
||||
def symlink(
|
||||
|
@ -2066,8 +2066,6 @@ def recurse(name,
|
|||
|
||||
# expand source into source_list
|
||||
source_list = _validate_str_list(source)
|
||||
if not source_list:
|
||||
return _error(ret, '\'source\' parameter is not a string or list of strings')
|
||||
|
||||
for idx, val in enumerate(source_list):
|
||||
source_list[idx] = val.rstrip('/')
|
||||
|
@ -3181,8 +3179,6 @@ def append(name,
|
|||
text = tmpret['data']
|
||||
|
||||
text = _validate_str_list(text)
|
||||
if not text:
|
||||
return _error(ret, 'Given text is not a string or a list of strings')
|
||||
|
||||
with salt.utils.fopen(name, 'rb') as fp_:
|
||||
slines = fp_.readlines()
|
||||
|
@ -3350,8 +3346,6 @@ def prepend(name,
|
|||
text = tmpret['data']
|
||||
|
||||
text = _validate_str_list(text)
|
||||
if not text:
|
||||
return _error(ret, 'Given text is not a string or a list of strings')
|
||||
|
||||
with salt.utils.fopen(name, 'rb') as fp_:
|
||||
slines = fp_.readlines()
|
||||
|
|
|
@ -635,29 +635,29 @@ class Finder(object):
|
|||
depth = dirpath[len(path) + len(os.path.sep):].count(os.path.sep)
|
||||
if depth == self.maxdepth:
|
||||
dirs[:] = []
|
||||
else:
|
||||
if depth >= self.mindepth:
|
||||
for name in dirs + files:
|
||||
fstat = None
|
||||
matches = True
|
||||
fullpath = None
|
||||
for criterion in self.criteria:
|
||||
if fstat is None and criterion.requires() & _REQUIRES_STAT:
|
||||
fullpath = os.path.join(dirpath, name)
|
||||
fstat = os.stat(fullpath)
|
||||
if not criterion.match(dirpath, name, fstat):
|
||||
matches = False
|
||||
break
|
||||
if matches:
|
||||
if fullpath is None:
|
||||
fullpath = os.path.join(dirpath, name)
|
||||
for action in self.actions:
|
||||
if (fstat is None and
|
||||
|
||||
if depth >= self.mindepth:
|
||||
for name in dirs + files:
|
||||
fstat = None
|
||||
matches = True
|
||||
fullpath = None
|
||||
for criterion in self.criteria:
|
||||
if fstat is None and criterion.requires() & _REQUIRES_STAT:
|
||||
fullpath = os.path.join(dirpath, name)
|
||||
fstat = os.stat(fullpath)
|
||||
if not criterion.match(dirpath, name, fstat):
|
||||
matches = False
|
||||
break
|
||||
if matches:
|
||||
if fullpath is None:
|
||||
fullpath = os.path.join(dirpath, name)
|
||||
for action in self.actions:
|
||||
if (fstat is None and
|
||||
action.requires() & _REQUIRES_STAT):
|
||||
fstat = os.stat(fullpath)
|
||||
result = action.execute(fullpath, fstat, test=self.test)
|
||||
if result is not None:
|
||||
yield result
|
||||
fstat = os.stat(fullpath)
|
||||
result = action.execute(fullpath, fstat, test=self.test)
|
||||
if result is not None:
|
||||
yield result
|
||||
|
||||
|
||||
def find(path, options):
|
||||
|
|
|
@ -13,6 +13,7 @@ import pwd
|
|||
import shutil
|
||||
import stat
|
||||
import tempfile
|
||||
import textwrap
|
||||
import filecmp
|
||||
import textwrap
|
||||
|
||||
|
@ -26,8 +27,8 @@ from salttesting.helpers import (
|
|||
ensure_in_syspath,
|
||||
with_system_user_and_group
|
||||
)
|
||||
ensure_in_syspath('../../')
|
||||
|
||||
ensure_in_syspath('../../')
|
||||
|
||||
# Import salt libs
|
||||
import integration
|
||||
|
@ -36,7 +37,6 @@ import salt.utils
|
|||
# Import 3rd-party libs
|
||||
import salt.ext.six as six
|
||||
|
||||
|
||||
STATE_DIR = os.path.join(integration.FILES, 'file', 'base')
|
||||
|
||||
|
||||
|
@ -279,6 +279,65 @@ class FileTest(integration.ModuleCase, integration.SaltReturnAssertsMixIn):
|
|||
os.remove(funny_file)
|
||||
os.remove(funny_url_path)
|
||||
|
||||
def test_managed_contents(self):
|
||||
'''
|
||||
test file.managed with contents that is a boolean, string, integer,
|
||||
float, list, and dictionary
|
||||
'''
|
||||
state_name = 'file-FileTest-test_managed_contents'
|
||||
state_filename = state_name + '.sls'
|
||||
state_file = os.path.join(STATE_DIR, state_filename)
|
||||
|
||||
managed_files = {}
|
||||
state_keys = {}
|
||||
for typ in ('bool', 'str', 'int', 'float', 'list', 'dict'):
|
||||
managed_files[typ] = tempfile.mkstemp()[1]
|
||||
state_keys[typ] = 'file_|-{0} file_|-{1}_|-managed'.format(typ, managed_files[typ])
|
||||
try:
|
||||
salt.utils.fopen(state_file, 'w').write(textwrap.dedent('''\
|
||||
bool file:
|
||||
file.managed:
|
||||
- name: {bool}
|
||||
- contents: True
|
||||
|
||||
str file:
|
||||
file.managed:
|
||||
- name: {str}
|
||||
- contents: Salt was here.
|
||||
|
||||
int file:
|
||||
file.managed:
|
||||
- name: {int}
|
||||
- contents: 340282366920938463463374607431768211456
|
||||
|
||||
float file:
|
||||
file.managed:
|
||||
- name: {float}
|
||||
- contents: 1.7518e-45 # gravitational coupling constant
|
||||
|
||||
list file:
|
||||
file.managed:
|
||||
- name: {list}
|
||||
- contents: [1, 1, 2, 3, 5, 8, 13]
|
||||
|
||||
dict file:
|
||||
file.managed:
|
||||
- name: {dict}
|
||||
- contents:
|
||||
C: charge
|
||||
P: parity
|
||||
T: time
|
||||
'''.format(**managed_files)))
|
||||
|
||||
ret = self.run_function('state.sls', [state_name])
|
||||
for typ in state_keys:
|
||||
self.assertTrue(ret[state_keys[typ]]['result'])
|
||||
self.assertIn('diff', ret[state_keys[typ]]['changes'])
|
||||
finally:
|
||||
os.remove(state_file)
|
||||
for typ in managed_files:
|
||||
os.remove(managed_files[typ])
|
||||
|
||||
def test_directory(self):
|
||||
'''
|
||||
file.directory
|
||||
|
|
153
tests/unit/modules/win_groupadd_test.py
Normal file
153
tests/unit/modules/win_groupadd_test.py
Normal file
|
@ -0,0 +1,153 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
:codeauthor: :email:`Jayesh Kariya <jayeshk@saltstack.com>`
|
||||
'''
|
||||
|
||||
# Import Python Libs
|
||||
from __future__ import absolute_import
|
||||
|
||||
# Import Salt Testing Libs
|
||||
from salttesting import TestCase, skipIf
|
||||
from salttesting.mock import (
|
||||
patch,
|
||||
NO_MOCK,
|
||||
NO_MOCK_REASON
|
||||
)
|
||||
|
||||
from salttesting.helpers import ensure_in_syspath
|
||||
|
||||
ensure_in_syspath('../../')
|
||||
|
||||
# Import Salt Libs
|
||||
from salt.modules import win_groupadd
|
||||
|
||||
# Import Other Libs
|
||||
# pylint: disable=W0611
|
||||
try:
|
||||
import win32com
|
||||
import pythoncom
|
||||
import pywintypes
|
||||
HAS_WIN_LIBS = True
|
||||
except ImportError:
|
||||
HAS_WIN_LIBS = False
|
||||
# pylint: enable=W0611
|
||||
|
||||
|
||||
win_groupadd.__context__ = {}
|
||||
win_groupadd.__opts__ = {'test': False}
|
||||
|
||||
|
||||
@skipIf(not HAS_WIN_LIBS, 'win_groupadd unit tests can only be run if win32com, pythoncom, and pywintypes are installed')
|
||||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
class WinGroupTestCase(TestCase):
|
||||
'''
|
||||
Test cases for salt.modules.win_groupadd
|
||||
'''
|
||||
# 'add' function tests: 1
|
||||
|
||||
def test_add(self):
|
||||
'''
|
||||
Test if it add the specified group
|
||||
'''
|
||||
self.assertDictEqual(win_groupadd.add('foo'),
|
||||
{'changes': [], 'name': 'foo', 'result': None,
|
||||
'comment': 'The group foo already exists.'})
|
||||
|
||||
# 'delete' function tests: 1
|
||||
|
||||
def test_delete(self):
|
||||
'''
|
||||
Test if it remove the specified group
|
||||
'''
|
||||
self.assertDictEqual(win_groupadd.delete('foo'),
|
||||
{'changes': [], 'name': 'foo', 'result': None,
|
||||
'comment': 'The group foo does not exists.'})
|
||||
|
||||
# 'info' function tests: 1
|
||||
|
||||
def test_info(self):
|
||||
'''
|
||||
Test if it return information about a group.
|
||||
'''
|
||||
with patch(win_groupadd.win32.client, 'flag', None):
|
||||
self.assertDictEqual(win_groupadd.info('dc=salt'),
|
||||
{'gid': None,
|
||||
'members': ['dc=\\user1'],
|
||||
'passwd': None,
|
||||
'name': 'WinNT://./dc=salt,group'})
|
||||
|
||||
with patch(win_groupadd.win32.client, 'flag', 1):
|
||||
self.assertFalse(win_groupadd.info('dc=salt'))
|
||||
|
||||
with patch(win_groupadd.win32.client, 'flag', 2):
|
||||
self.assertFalse(win_groupadd.info('dc=salt'))
|
||||
|
||||
# 'getent' function tests: 1
|
||||
|
||||
def test_getent(self):
|
||||
'''
|
||||
Test if it return info on all groups
|
||||
'''
|
||||
with patch.dict(win_groupadd.__context__, {'group.getent': True}):
|
||||
self.assertTrue(win_groupadd.getent())
|
||||
|
||||
# 'adduser' function tests: 1
|
||||
|
||||
def test_adduser(self):
|
||||
'''
|
||||
Test if it add a user to a group
|
||||
'''
|
||||
with patch(win_groupadd.win32.client, 'flag', None):
|
||||
self.assertDictEqual(win_groupadd.adduser('dc=foo', 'dc=\\username'),
|
||||
{'changes': {'Users Added': ['dc=\\username']},
|
||||
'comment': '', 'name': 'dc=foo', 'result': True})
|
||||
|
||||
with patch(win_groupadd.win32.client, 'flag', 1):
|
||||
comt = ('Failed to add dc=\\username to group dc=foo. C')
|
||||
self.assertDictEqual(win_groupadd.adduser('dc=foo', 'dc=\\username'),
|
||||
{'changes': {'Users Added': []}, 'name': 'dc=foo',
|
||||
'comment': comt, 'result': False})
|
||||
|
||||
# 'deluser' function tests: 1
|
||||
|
||||
def test_deluser(self):
|
||||
'''
|
||||
Test if it remove a user to a group
|
||||
'''
|
||||
ret = {'changes': {'Users Removed': []},
|
||||
'comment': 'User dc=\\username is not a member of dc=foo',
|
||||
'name': 'dc=foo', 'result': None}
|
||||
|
||||
self.assertDictEqual(win_groupadd.deluser('dc=foo', 'dc=\\username'),
|
||||
ret)
|
||||
|
||||
# 'members' function tests: 1
|
||||
|
||||
def test_members(self):
|
||||
'''
|
||||
Test if it remove a user to a group
|
||||
'''
|
||||
comment = ['Failure accessing group dc=foo. C']
|
||||
ret = {'name': 'dc=foo', 'result': False, 'comment': comment,
|
||||
'changes': {'Users Added': [], 'Users Removed': []}}
|
||||
|
||||
with patch(win_groupadd.win32.client, 'flag', 2):
|
||||
self.assertDictEqual(win_groupadd.members
|
||||
('dc=foo', 'dc=\\user1,dc=\\user2,dc=\\user3'),
|
||||
ret)
|
||||
|
||||
with patch(win_groupadd.win32.client, 'flag', 1):
|
||||
comment = ['Failed to add dc=\\user2 to dc=foo. C',
|
||||
'Failed to remove dc=\\user1 from dc=foo. C']
|
||||
ret.update({'comment': comment, 'result': False})
|
||||
self.assertDictEqual(win_groupadd.members('dc=foo', 'dc=\\user2'), ret)
|
||||
|
||||
with patch(win_groupadd.win32.client, 'flag', None):
|
||||
comment = ['dc=foo membership is correct']
|
||||
ret.update({'comment': comment, 'result': None})
|
||||
self.assertDictEqual(win_groupadd.members('dc=foo', 'dc=\\user1'), ret)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from integration import run_tests
|
||||
run_tests(WinGroupTestCase, needs_daemon=False)
|
|
@ -733,7 +733,7 @@ class FileTestCase(TestCase):
|
|||
self.assertDictEqual(filestate.recurse(name, source), ret)
|
||||
|
||||
with patch.object(os.path, 'isabs', mock_t):
|
||||
comt = ("'source' parameter is not a string or list of strings")
|
||||
comt = ("Invalid source '1' (must be a salt:// URI)")
|
||||
ret.update({'comment': comt})
|
||||
self.assertDictEqual(filestate.recurse(name, 1), ret)
|
||||
|
||||
|
@ -998,10 +998,7 @@ class FileTestCase(TestCase):
|
|||
ret)
|
||||
|
||||
ret.pop('data', None)
|
||||
comt = ('Given text is not a string or a list of strings')
|
||||
ret.update({'comment': comt, 'name': name})
|
||||
self.assertDictEqual(filestate.append(name), ret)
|
||||
|
||||
ret.update({'name': name})
|
||||
with patch.object(salt.utils, 'fopen',
|
||||
MagicMock(mock_open(read_data=''))):
|
||||
comt = ('No text found to append. Nothing appended')
|
||||
|
@ -1082,10 +1079,7 @@ class FileTestCase(TestCase):
|
|||
ret)
|
||||
|
||||
ret.pop('data', None)
|
||||
comt = ('Given text is not a string or a list of strings')
|
||||
ret.update({'comment': comt, 'name': name})
|
||||
self.assertDictEqual(filestate.prepend(name), ret)
|
||||
|
||||
ret.update({'name': name})
|
||||
with patch.object(salt.utils, 'fopen',
|
||||
MagicMock(mock_open(read_data=''))):
|
||||
with patch.object(salt.utils, 'istextfile', mock_f):
|
||||
|
|
116
tests/unit/states/postgres_database_test.py
Normal file
116
tests/unit/states/postgres_database_test.py
Normal file
|
@ -0,0 +1,116 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
:codeauthor: :email:`Jayesh Kariya <jayeshk@saltstack.com>`
|
||||
'''
|
||||
# Import Python libs
|
||||
from __future__ import absolute_import
|
||||
|
||||
# Import Salt Testing Libs
|
||||
from salttesting import skipIf, TestCase
|
||||
from salttesting.mock import (
|
||||
NO_MOCK,
|
||||
NO_MOCK_REASON,
|
||||
MagicMock,
|
||||
patch
|
||||
)
|
||||
|
||||
from salttesting.helpers import ensure_in_syspath
|
||||
|
||||
ensure_in_syspath('../../')
|
||||
|
||||
# Import Salt Libs
|
||||
from salt.states import postgres_database
|
||||
|
||||
postgres_database.__opts__ = {}
|
||||
postgres_database.__salt__ = {}
|
||||
|
||||
|
||||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
class PostgresDatabaseTestCase(TestCase):
|
||||
'''
|
||||
Test cases for salt.states.postgres_database
|
||||
'''
|
||||
# 'present' function tests: 1
|
||||
|
||||
def test_present(self):
|
||||
'''
|
||||
Test to ensure that the named database is present
|
||||
with the specified properties.
|
||||
'''
|
||||
name = 'frank'
|
||||
|
||||
ret = {'name': name,
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': ''}
|
||||
|
||||
mock_t = MagicMock(return_value=True)
|
||||
mock = MagicMock(return_value={name: {}})
|
||||
with patch.dict(postgres_database.__salt__,
|
||||
{'postgres.db_list': mock,
|
||||
'postgres.db_alter': mock_t}):
|
||||
comt = ('Database {0} is already present'.format(name))
|
||||
ret.update({'comment': comt, 'result': True})
|
||||
self.assertDictEqual(postgres_database.present(name), ret)
|
||||
|
||||
comt = ("Database frank has wrong parameters "
|
||||
"which couldn't be changed on fly.")
|
||||
ret.update({'comment': comt, 'result': False})
|
||||
self.assertDictEqual(postgres_database.present(name, tablespace='A',
|
||||
lc_collate=True),
|
||||
ret)
|
||||
|
||||
with patch.dict(postgres_database.__opts__, {'test': True}):
|
||||
comt = ('Database frank exists, '
|
||||
'but parameters need to be changed')
|
||||
ret.update({'comment': comt, 'result': None})
|
||||
self.assertDictEqual(postgres_database.present(name,
|
||||
tablespace='A'),
|
||||
ret)
|
||||
|
||||
with patch.dict(postgres_database.__opts__, {'test': False}):
|
||||
comt = ('Parameters for database frank have been changed')
|
||||
ret.update({'comment': comt, 'result': True,
|
||||
'changes': {name: 'Parameters changed'}})
|
||||
self.assertDictEqual(postgres_database.present(name,
|
||||
tablespace='A'),
|
||||
ret)
|
||||
|
||||
# 'absent' function tests: 1
|
||||
|
||||
def test_absent(self):
|
||||
'''
|
||||
Test to ensure that the named database is absent.
|
||||
'''
|
||||
name = 'frank'
|
||||
|
||||
ret = {'name': name,
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': ''}
|
||||
|
||||
mock_t = MagicMock(return_value=True)
|
||||
mock = MagicMock(side_effect=[True, True, False])
|
||||
with patch.dict(postgres_database.__salt__,
|
||||
{'postgres.db_exists': mock,
|
||||
'postgres.db_remove': mock_t}):
|
||||
with patch.dict(postgres_database.__opts__, {'test': True}):
|
||||
comt = ('Database {0} is set to be removed'.format(name))
|
||||
ret.update({'comment': comt, 'result': None})
|
||||
self.assertDictEqual(postgres_database.absent(name), ret)
|
||||
|
||||
with patch.dict(postgres_database.__opts__, {'test': False}):
|
||||
comt = ('Database {0} has been removed'.format(name))
|
||||
ret.update({'comment': comt, 'result': True,
|
||||
'changes': {name: 'Absent'}})
|
||||
self.assertDictEqual(postgres_database.absent(name), ret)
|
||||
|
||||
comt = ('Database {0} is not present, so it cannot be removed'
|
||||
.format(name))
|
||||
ret.update({'comment': comt, 'result': True, 'changes': {}})
|
||||
self.assertDictEqual(postgres_database.absent(name), ret)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from integration import run_tests
|
||||
run_tests(PostgresDatabaseTestCase, needs_daemon=False)
|
101
tests/unit/states/postgres_extension_test.py
Normal file
101
tests/unit/states/postgres_extension_test.py
Normal file
|
@ -0,0 +1,101 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
:codeauthor: :email:`Jayesh Kariya <jayeshk@saltstack.com>`
|
||||
'''
|
||||
# Import Python libs
|
||||
from __future__ import absolute_import
|
||||
|
||||
# Import Salt Testing Libs
|
||||
from salttesting import skipIf, TestCase
|
||||
from salttesting.mock import (
|
||||
NO_MOCK,
|
||||
NO_MOCK_REASON,
|
||||
MagicMock,
|
||||
patch
|
||||
)
|
||||
|
||||
from salttesting.helpers import ensure_in_syspath
|
||||
|
||||
ensure_in_syspath('../../')
|
||||
|
||||
# Import Salt Libs
|
||||
from salt.states import postgres_extension
|
||||
|
||||
postgres_extension.__opts__ = {}
|
||||
postgres_extension.__salt__ = {}
|
||||
|
||||
|
||||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
class PostgresExtensionTestCase(TestCase):
|
||||
'''
|
||||
Test cases for salt.states.postgres_extension
|
||||
'''
|
||||
# 'present' function tests: 1
|
||||
|
||||
def test_present(self):
|
||||
'''
|
||||
Test to ensure that the named extension is present
|
||||
with the specified privileges.
|
||||
'''
|
||||
name = 'frank'
|
||||
|
||||
ret = {'name': name,
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': ''}
|
||||
|
||||
mock = MagicMock(return_value={})
|
||||
with patch.dict(postgres_extension.__salt__,
|
||||
{'postgres.create_metadata': mock}):
|
||||
with patch.dict(postgres_extension.__opts__, {'test': True}):
|
||||
comt = ('Extension {0} is set to be created'.format(name))
|
||||
ret.update({'comment': comt, 'result': None})
|
||||
self.assertDictEqual(postgres_extension.present(name), ret)
|
||||
|
||||
with patch.dict(postgres_extension.__opts__, {'test': False}):
|
||||
comt = ('Extension {0} is already present'.format(name))
|
||||
ret.update({'comment': comt, 'result': True})
|
||||
self.assertDictEqual(postgres_extension.present(name), ret)
|
||||
|
||||
# 'absent' function tests: 1
|
||||
|
||||
def test_absent(self):
|
||||
'''
|
||||
Test to ensure that the named extension is absent.
|
||||
'''
|
||||
name = 'frank'
|
||||
|
||||
ret = {'name': name,
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': ''}
|
||||
|
||||
mock_t = MagicMock(side_effect=[True, False])
|
||||
mock = MagicMock(side_effect=[True, True, True, False])
|
||||
with patch.dict(postgres_extension.__salt__,
|
||||
{'postgres.is_installed_extension': mock,
|
||||
'postgres.drop_extension': mock_t}):
|
||||
with patch.dict(postgres_extension.__opts__, {'test': True}):
|
||||
comt = ('Extension {0} is set to be removed'.format(name))
|
||||
ret.update({'comment': comt, 'result': None})
|
||||
self.assertDictEqual(postgres_extension.absent(name), ret)
|
||||
|
||||
with patch.dict(postgres_extension.__opts__, {'test': False}):
|
||||
comt = ('Extension {0} has been removed'.format(name))
|
||||
ret.update({'comment': comt, 'result': True,
|
||||
'changes': {name: 'Absent'}})
|
||||
self.assertDictEqual(postgres_extension.absent(name), ret)
|
||||
|
||||
comt = ('Extension {0} failed to be removed'.format(name))
|
||||
ret.update({'comment': comt, 'result': False, 'changes': {}})
|
||||
self.assertDictEqual(postgres_extension.absent(name), ret)
|
||||
|
||||
comt = ('Extension {0} is not present, so it cannot be removed'
|
||||
.format(name))
|
||||
ret.update({'comment': comt, 'result': True})
|
||||
self.assertDictEqual(postgres_extension.absent(name), ret)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from integration import run_tests
|
||||
run_tests(PostgresExtensionTestCase, needs_daemon=False)
|
99
tests/unit/states/postgres_group_test.py
Normal file
99
tests/unit/states/postgres_group_test.py
Normal file
|
@ -0,0 +1,99 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
:codeauthor: :email:`Jayesh Kariya <jayeshk@saltstack.com>`
|
||||
'''
|
||||
# Import Python libs
|
||||
from __future__ import absolute_import
|
||||
|
||||
# Import Salt Testing Libs
|
||||
from salttesting import skipIf, TestCase
|
||||
from salttesting.mock import (
|
||||
NO_MOCK,
|
||||
NO_MOCK_REASON,
|
||||
MagicMock,
|
||||
patch
|
||||
)
|
||||
|
||||
from salttesting.helpers import ensure_in_syspath
|
||||
|
||||
ensure_in_syspath('../../')
|
||||
|
||||
# Import Salt Libs
|
||||
from salt.states import postgres_group
|
||||
|
||||
postgres_group.__opts__ = {}
|
||||
postgres_group.__salt__ = {}
|
||||
|
||||
|
||||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
class PostgresGroupTestCase(TestCase):
|
||||
'''
|
||||
Test cases for salt.states.postgres_group
|
||||
'''
|
||||
# 'present' function tests: 1
|
||||
|
||||
def test_present(self):
|
||||
'''
|
||||
Test to ensure that the named group is present
|
||||
with the specified privileges.
|
||||
'''
|
||||
name = 'frank'
|
||||
|
||||
ret = {'name': name,
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': ''}
|
||||
|
||||
mock_t = MagicMock(return_value=True)
|
||||
mock = MagicMock(return_value=None)
|
||||
with patch.dict(postgres_group.__salt__,
|
||||
{'postgres.role_get': mock,
|
||||
'postgres.group_create': mock_t}):
|
||||
with patch.dict(postgres_group.__opts__, {'test': True}):
|
||||
comt = ('Group {0} is set to be created'.format(name))
|
||||
ret.update({'comment': comt, 'result': None})
|
||||
self.assertDictEqual(postgres_group.present(name), ret)
|
||||
|
||||
with patch.dict(postgres_group.__opts__, {'test': False}):
|
||||
comt = ('The group {0} has been created'.format(name))
|
||||
ret.update({'comment': comt, 'result': True})
|
||||
self.assertDictEqual(postgres_group.present(name), ret)
|
||||
|
||||
# 'absent' function tests: 1
|
||||
|
||||
def test_absent(self):
|
||||
'''
|
||||
Test to ensure that the named group is absent.
|
||||
'''
|
||||
name = 'frank'
|
||||
|
||||
ret = {'name': name,
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': ''}
|
||||
|
||||
mock_t = MagicMock(return_value=True)
|
||||
mock = MagicMock(side_effect=[True, True, False])
|
||||
with patch.dict(postgres_group.__salt__,
|
||||
{'postgres.user_exists': mock,
|
||||
'postgres.group_remove': mock_t}):
|
||||
with patch.dict(postgres_group.__opts__, {'test': True}):
|
||||
comt = ('Group {0} is set to be removed'.format(name))
|
||||
ret.update({'comment': comt, 'result': None})
|
||||
self.assertDictEqual(postgres_group.absent(name), ret)
|
||||
|
||||
with patch.dict(postgres_group.__opts__, {'test': False}):
|
||||
comt = ('Group {0} has been removed'.format(name))
|
||||
ret.update({'comment': comt, 'result': True,
|
||||
'changes': {name: 'Absent'}})
|
||||
self.assertDictEqual(postgres_group.absent(name), ret)
|
||||
|
||||
comt = ('Group {0} is not present, so it cannot be removed'
|
||||
.format(name))
|
||||
ret.update({'comment': comt, 'result': True, 'changes': {}})
|
||||
self.assertDictEqual(postgres_group.absent(name), ret)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from integration import run_tests
|
||||
run_tests(PostgresGroupTestCase, needs_daemon=False)
|
94
tests/unit/states/postgres_schema_test.py
Normal file
94
tests/unit/states/postgres_schema_test.py
Normal file
|
@ -0,0 +1,94 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
:codeauthor: :email:`Jayesh Kariya <jayeshk@saltstack.com>`
|
||||
'''
|
||||
# Import Python libs
|
||||
from __future__ import absolute_import
|
||||
|
||||
# Import Salt Testing Libs
|
||||
from salttesting import skipIf, TestCase
|
||||
from salttesting.mock import (
|
||||
NO_MOCK,
|
||||
NO_MOCK_REASON,
|
||||
MagicMock,
|
||||
patch
|
||||
)
|
||||
|
||||
from salttesting.helpers import ensure_in_syspath
|
||||
|
||||
ensure_in_syspath('../../')
|
||||
|
||||
# Import Salt Libs
|
||||
from salt.states import postgres_schema
|
||||
|
||||
postgres_schema.__opts__ = {}
|
||||
postgres_schema.__salt__ = {}
|
||||
|
||||
|
||||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
class PostgresSchemaTestCase(TestCase):
|
||||
'''
|
||||
Test cases for salt.states.postgres_schema
|
||||
'''
|
||||
# 'present' function tests: 1
|
||||
|
||||
def test_present(self):
|
||||
'''
|
||||
Test to ensure that the named schema is present in the database.
|
||||
'''
|
||||
name = 'myname'
|
||||
dbname = 'mydb'
|
||||
|
||||
ret = {'name': name,
|
||||
'dbname': dbname,
|
||||
'changes': {},
|
||||
'result': True,
|
||||
'comment': ''}
|
||||
|
||||
mock = MagicMock(return_value=name)
|
||||
with patch.dict(postgres_schema.__salt__,
|
||||
{'postgres.schema_get': mock}):
|
||||
comt = ('Schema {0} already exists in database {1}'.format(name,
|
||||
dbname))
|
||||
ret.update({'comment': comt})
|
||||
self.assertDictEqual(postgres_schema.present(dbname, name), ret)
|
||||
|
||||
# 'absent' function tests: 1
|
||||
|
||||
def test_absent(self):
|
||||
'''
|
||||
Test to ensure that the named schema is absent.
|
||||
'''
|
||||
name = 'myname'
|
||||
dbname = 'mydb'
|
||||
|
||||
ret = {'name': name,
|
||||
'dbname': dbname,
|
||||
'changes': {},
|
||||
'result': True,
|
||||
'comment': ''}
|
||||
|
||||
mock_t = MagicMock(side_effect=[True, False])
|
||||
mock = MagicMock(side_effect=[True, True, False])
|
||||
with patch.dict(postgres_schema.__salt__,
|
||||
{'postgres.schema_exists': mock,
|
||||
'postgres.schema_remove': mock_t}):
|
||||
comt = ('Schema {0} has been removed from database {1}'.
|
||||
format(name, dbname))
|
||||
ret.update({'comment': comt, 'result': True,
|
||||
'changes': {name: 'Absent'}})
|
||||
self.assertDictEqual(postgres_schema.absent(dbname, name), ret)
|
||||
|
||||
comt = ('Schema {0} failed to be removed'.format(name))
|
||||
ret.update({'comment': comt, 'result': False, 'changes': {}})
|
||||
self.assertDictEqual(postgres_schema.absent(dbname, name), ret)
|
||||
|
||||
comt = ('Schema {0} is not present in database {1},'
|
||||
' so it cannot be removed'.format(name, dbname))
|
||||
ret.update({'comment': comt, 'result': True})
|
||||
self.assertDictEqual(postgres_schema.absent(dbname, name), ret)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from integration import run_tests
|
||||
run_tests(PostgresSchemaTestCase, needs_daemon=False)
|
|
@ -33,9 +33,9 @@ MODS = (
|
|||
OPTS = {'test': False}
|
||||
|
||||
for postgres in MODS:
|
||||
postgres.__grains__ = None # in order to stub it w/patch below
|
||||
postgres.__salt__ = None # in order to stub it w/patch below
|
||||
postgres.__opts__ = OPTS # in order to stub it w/patch below
|
||||
postgres.__grains__ = {} # in order to stub it w/patch below
|
||||
postgres.__salt__ = {} # in order to stub it w/patch below
|
||||
postgres.__opts__ = {} # in order to stub it w/patch below
|
||||
|
||||
if NO_MOCK is False:
|
||||
SALT_STUB = {
|
||||
|
@ -51,7 +51,8 @@ else:
|
|||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
@patch.multiple(postgres_user,
|
||||
__grains__={'os_family': 'Linux'},
|
||||
__salt__=SALT_STUB)
|
||||
__salt__=SALT_STUB,
|
||||
__opts__={'test': False})
|
||||
@patch('salt.utils.which', Mock(return_value='/usr/bin/pgsql'))
|
||||
class PostgresUserTestCase(TestCase):
|
||||
|
||||
|
@ -61,7 +62,7 @@ class PostgresUserTestCase(TestCase):
|
|||
})
|
||||
def test_present__creation(self):
|
||||
# test=True
|
||||
with patch.dict(OPTS, {'test': True}):
|
||||
with patch.dict(postgres_user.__opts__, {'test': True}):
|
||||
ret = postgres_user.present('foo')
|
||||
self.assertEqual(
|
||||
ret,
|
||||
|
@ -111,7 +112,7 @@ class PostgresUserTestCase(TestCase):
|
|||
})
|
||||
def test_present__update(self):
|
||||
# test=True
|
||||
with patch.dict(OPTS, {'test': True}):
|
||||
with patch.dict(postgres_user.__opts__, {'test': True}):
|
||||
ret = postgres_user.present('foo', login=True, replication=False)
|
||||
self.assertEqual(
|
||||
ret,
|
||||
|
@ -183,7 +184,8 @@ class PostgresUserTestCase(TestCase):
|
|||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
@patch.multiple(postgres_group,
|
||||
__grains__={'os_family': 'Linux'},
|
||||
__salt__=SALT_STUB)
|
||||
__salt__=SALT_STUB,
|
||||
__opts__={'test': False})
|
||||
@patch('salt.utils.which', Mock(return_value='/usr/bin/pgsql'))
|
||||
class PostgresGroupTestCase(TestCase):
|
||||
|
||||
|
@ -193,7 +195,7 @@ class PostgresGroupTestCase(TestCase):
|
|||
})
|
||||
def test_present__creation(self):
|
||||
# test=True
|
||||
with patch.dict(OPTS, {'test': True}):
|
||||
with patch.dict(postgres_group.__opts__, {'test': True}):
|
||||
ret = postgres_group.present('foo')
|
||||
self.assertEqual(
|
||||
ret,
|
||||
|
@ -243,7 +245,7 @@ class PostgresGroupTestCase(TestCase):
|
|||
})
|
||||
def test_present__update(self):
|
||||
# test=True
|
||||
with patch.dict(OPTS, {'test': True}):
|
||||
with patch.dict(postgres_group.__opts__, {'test': True}):
|
||||
ret = postgres_group.present('foo', login=True, replication=False)
|
||||
self.assertEqual(
|
||||
ret,
|
||||
|
@ -315,7 +317,8 @@ class PostgresGroupTestCase(TestCase):
|
|||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
@patch.multiple(postgres_extension,
|
||||
__grains__={'os_family': 'Linux'},
|
||||
__salt__=SALT_STUB)
|
||||
__salt__=SALT_STUB,
|
||||
__opts__={'test': False})
|
||||
@patch('salt.utils.which', Mock(return_value='/usr/bin/pgsql'))
|
||||
class PostgresExtensionTestCase(TestCase):
|
||||
|
||||
|
@ -399,26 +402,27 @@ class PostgresExtensionTestCase(TestCase):
|
|||
scenario of creating upgrading extensions with possible schema and
|
||||
version specifications
|
||||
'''
|
||||
ret = postgres_extension.present('foo')
|
||||
self.assertEqual(
|
||||
ret,
|
||||
{'comment': 'Extension foo is set to be installed',
|
||||
'changes': {}, 'name': 'foo', 'result': None}
|
||||
with patch.dict(postgres_extension.__opts__, {'test': True}):
|
||||
ret = postgres_extension.present('foo')
|
||||
self.assertEqual(
|
||||
ret,
|
||||
{'comment': 'Extension foo is set to be installed',
|
||||
'changes': {}, 'name': 'foo', 'result': None}
|
||||
|
||||
)
|
||||
ret = postgres_extension.present('foo')
|
||||
self.assertEqual(
|
||||
ret,
|
||||
{'comment': "Extension foo is set to be created",
|
||||
'changes': {}, 'name': 'foo', 'result': None}
|
||||
)
|
||||
ret = postgres_extension.present('foo')
|
||||
self.assertEqual(
|
||||
ret,
|
||||
{'comment': "Extension foo is set to be created",
|
||||
'changes': {}, 'name': 'foo', 'result': None}
|
||||
|
||||
)
|
||||
ret = postgres_extension.present('foo')
|
||||
self.assertEqual(
|
||||
ret,
|
||||
{'comment': "Extension foo is set to be upgraded",
|
||||
'changes': {}, 'name': 'foo', 'result': None}
|
||||
)
|
||||
)
|
||||
ret = postgres_extension.present('foo')
|
||||
self.assertEqual(
|
||||
ret,
|
||||
{'comment': "Extension foo is set to be upgraded",
|
||||
'changes': {}, 'name': 'foo', 'result': None}
|
||||
)
|
||||
|
||||
@patch.dict(SALT_STUB, {
|
||||
'postgres.is_installed_extension': Mock(side_effect=[
|
||||
|
@ -480,7 +484,8 @@ class PostgresExtensionTestCase(TestCase):
|
|||
]),
|
||||
})
|
||||
def test_absent_failedtest(self):
|
||||
ret = postgres_extension.absent('foo')
|
||||
with patch.dict(postgres_extension.__opts__, {'test': True}):
|
||||
ret = postgres_extension.absent('foo')
|
||||
self.assertEqual(
|
||||
ret,
|
||||
{'comment': 'Extension foo is set to be removed',
|
||||
|
@ -491,7 +496,8 @@ class PostgresExtensionTestCase(TestCase):
|
|||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
@patch.multiple(postgres_schema,
|
||||
__grains__={'os_family': 'Linux'},
|
||||
__salt__=SALT_STUB)
|
||||
__salt__=SALT_STUB,
|
||||
__opts__={'test': False})
|
||||
@patch('salt.utils.which', Mock(return_value='/usr/bin/pgsql'))
|
||||
class PostgresSchemaTestCase(TestCase):
|
||||
|
||||
|
|
100
tests/unit/states/postgres_user_test.py
Normal file
100
tests/unit/states/postgres_user_test.py
Normal file
|
@ -0,0 +1,100 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
:codeauthor: :email:`Jayesh Kariya <jayeshk@saltstack.com>`
|
||||
'''
|
||||
# Import Python libs
|
||||
from __future__ import absolute_import
|
||||
|
||||
# Import Salt Testing Libs
|
||||
from salttesting import skipIf, TestCase
|
||||
from salttesting.mock import (
|
||||
NO_MOCK,
|
||||
NO_MOCK_REASON,
|
||||
MagicMock,
|
||||
patch
|
||||
)
|
||||
|
||||
from salttesting.helpers import ensure_in_syspath
|
||||
|
||||
ensure_in_syspath('../../')
|
||||
|
||||
# Import Salt Libs
|
||||
from salt.states import postgres_user
|
||||
|
||||
postgres_user.__opts__ = {}
|
||||
postgres_user.__salt__ = {}
|
||||
|
||||
|
||||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
class PostgresUserTestCase(TestCase):
|
||||
'''
|
||||
Test cases for salt.states.postgres_user
|
||||
'''
|
||||
# 'present' function tests: 1
|
||||
|
||||
def test_present(self):
|
||||
'''
|
||||
Test to ensure that the named user is present
|
||||
with the specified privileges.
|
||||
'''
|
||||
name = 'frank'
|
||||
|
||||
ret = {'name': name,
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': ''}
|
||||
|
||||
mock_t = MagicMock(return_value=True)
|
||||
mock = MagicMock(return_value=None)
|
||||
with patch.dict(postgres_user.__salt__,
|
||||
{'postgres.role_get': mock,
|
||||
'postgres.user_create': mock_t}):
|
||||
with patch.dict(postgres_user.__opts__, {'test': True}):
|
||||
comt = ('User {0} is set to be created'.format(name))
|
||||
ret.update({'comment': comt, 'result': None})
|
||||
self.assertDictEqual(postgres_user.present(name), ret)
|
||||
|
||||
with patch.dict(postgres_user.__opts__, {'test': False}):
|
||||
comt = ('The user {0} has been created'.format(name))
|
||||
ret.update({'comment': comt, 'result': True,
|
||||
'changes': {name: 'Present'}})
|
||||
self.assertDictEqual(postgres_user.present(name), ret)
|
||||
|
||||
# 'absent' function tests: 1
|
||||
|
||||
def test_absent(self):
|
||||
'''
|
||||
Test to ensure that the named user is absent.
|
||||
'''
|
||||
name = 'frank'
|
||||
|
||||
ret = {'name': name,
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': ''}
|
||||
|
||||
mock_t = MagicMock(return_value=True)
|
||||
mock = MagicMock(side_effect=[True, True, False])
|
||||
with patch.dict(postgres_user.__salt__,
|
||||
{'postgres.user_exists': mock,
|
||||
'postgres.user_remove': mock_t}):
|
||||
with patch.dict(postgres_user.__opts__, {'test': True}):
|
||||
comt = ('User {0} is set to be removed'.format(name))
|
||||
ret.update({'comment': comt, 'result': None})
|
||||
self.assertDictEqual(postgres_user.absent(name), ret)
|
||||
|
||||
with patch.dict(postgres_user.__opts__, {'test': False}):
|
||||
comt = ('User {0} has been removed'.format(name))
|
||||
ret.update({'comment': comt, 'result': True,
|
||||
'changes': {name: 'Absent'}})
|
||||
self.assertDictEqual(postgres_user.absent(name), ret)
|
||||
|
||||
comt = ('User {0} is not present, so it cannot be removed'
|
||||
.format(name))
|
||||
ret.update({'comment': comt, 'result': True, 'changes': {}})
|
||||
self.assertDictEqual(postgres_user.absent(name), ret)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from integration import run_tests
|
||||
run_tests(PostgresUserTestCase, needs_daemon=False)
|
Loading…
Add table
Reference in a new issue