Merge branch '2015.5' of https://github.com/saltstack/salt into 2015.5-2

This commit is contained in:
Jacob Hammons 2015-05-18 11:26:14 -06:00
commit 8664e8bc8d
10 changed files with 809 additions and 41 deletions

View file

@ -1,4 +1,200 @@
-------------------------------------------------------------------
Wed May 6 20:33:53 UTC 2015 - aboe76@gmail.com
- Major release 2015.5.0 Lithium
- update to 2015.5.0
The 2015.5.0 feature release of Salt is focused on hardening Salt
and mostly on improving existing systems. A few major additions
are present, primarily the new Beacon system. Most enhancements
have been focused around improving existing features and
interfaces.
As usual the release notes are not exhaustive and primarily
include the most notable additions and improvements. Hundreds of
bugs have been fixed and many modules have been substantially
updated and added.
See especially the warning right on the top regarding
python_shell=False.
For all details see
http://docs.saltstack.com/en/latest/topics/releases/2015.5.0.html
- RPM Package changes:
- add some versions to the buildrequires to match the 2
requirements files from the tarball
- Moved the depencencies to main salt package
except where they are specific for the package
- Changed python-request dependency,only needed on salt-cloud
- Added python-tornado dependency for http.py
- Fixed zsh_completion in tarball.
- Fixed salt-api requirements to require python-cherrypy
- Fixed salt-cloud requiments to require salt-master
-------------------------------------------------------------------
Sun Apr 19 17:48:05 UTC 2015 - aboe76@gmail.com
- New Bugfix release 2014.7.5
Changes:
+ Fixed a key error bug in salt-cloud
+ Updated man pages to better match documentation
+ Fixed bug concerning high CPU usage with salt-ssh
+ Fixed bugs with remounting cvfs and fuse filesystems
+ Fixed bug with alowing requisite tracking of entire sls files
+ Fixed bug with aptpkg.mod_repo returning OK even if apt-add-repository fails
+ Increased frequency of ssh terminal output checking
+ Fixed malformed locale string in localmod module
+ Fixed checking of available version of package when accept_keywords were changed
+ Fixed bug to make git.latest work with empty repositories
+ Added **kwargs to service.mod_watch which removes warnings about enable and __reqs__ not being supported by the function
+ Improved state comments to not grow so quickly on failed requisites
+ Added force argument to service to trigger force_reload
+ Fixed bug to andle pkgrepo keyids that have been converted to int
+ Fixed module.portage_config bug with appending accept_keywords
+ Fixed bug to correctly report disk usage on windows minion
+ Added the ability to specify key prefix for S3 ext_pillar
+ Fixed issues with batch mode operating on the incorrect number of minions
+ Fixed a bug with the proxmox cloud provider stacktracing on disk definition
+ Fixed a bug with the changes dictionary in the file state
+ Fixed the TCP keep alive settings to work better with SREQ caching
+ Fixed many bugs within the iptables state and module
+ Fixed bug with states by adding fun, state, and unless to the state runtime internal keywords listing
+ Added ability to eAuth against Active Directory
+ Fixed some salt-ssh issues when running on Fedora 21
+ Fixed grains.get_or_set_hash to work with multiple entries under same key
+ Added better explanations and more examples of how the Reactor calls functions to docs
+ Fixed bug to not pass ex_config_drive to libcloud unless it's explicitly enabled
+ Fixed bug with pip.install on windows
+ Fixed bug where puppet.run always returns a 0 retcode
+ Fixed race condition bug with minion scheduling via pillar
+ Made efficiency improvements and bug fixes to the windows installer
+ Updated environment variables to fix bug with pygit2 when running salt as non-root user
+ Fixed cas behavior on data module -- data.cas was not saving changes
+ Fixed GPG rendering error
+ Fixed strace error in virt.query
+ Fixed stacktrace when running chef-solo command
+ Fixed possible bug wherein uncaught exceptions seem to make zmq3 tip over when threading is involved
+ Fixed argument passing to the reactor
+ Fixed glibc caching to prevent bug where salt-minion getaddrinfo in dns_check() never got updated nameservers
Known Issues:
+ In multimaster mode, a minion may become temporarily unresponsive if modules or pillars are refreshed at the
same time that one or more masters are down. This can be worked around by setting 'auth_timeout' and 'auth_tries'
down to shorter periods.
-------------------------------------------------------------------
Mon Mar 30 21:41:22 UTC 2015 - aboe76@gmail.com
- New Bugfix Release 2014.7.4
- Updated patch use-forking-daemon.patch
- fix salt-zsh-completion conflicts
+ Multi-master minions mode no longer route fileclient operations asymetrically.
This fixes the source of many multi-master bugs where the minion would
become unrepsonsive from one or more masters.
+ Fix bug wherein network.iface could produce stack traces.
+ net.arp will no longer be made available unless arp is installed on the
system.
+ Major performance improvements to Saltnado
+ Allow KVM module to operate under KVM itself or VMWare Fusion
+ Various fixes to the Windows installation scripts
+ Fix issue where the syndic would not correctly propogate loads to the master
job cache.
+ Improve error handling on invalid /etc/network/interfaces file in salt
networking modules
+ Fix bug where a reponse status was not checked for in fileclient.get_url
+ Enable eauth when running salt in batch mode
+ Increase timeout in Boto Route53 module
+ Fix bugs with Salt's 'tar' module option parsing
+ Fix parsing of NTP servers on Windows
+ Fix issue with blockdev tuning not reporting changes correctly
+ Update to the latest Salt bootstrap script
+ Update Linode salt-cloud driver to use either linode-python or
apache-libcloud
+ Fix for s3.query function to return correct headers
+ Fix for s3.head returning None for files that exist
+ Fix the disable function in win_service module so that the service is
disabled correctly
+ Fix race condition between master and minion when making a directory when
both daemons are on the same host
+ Fix an issue where file.recurse would fail at the root of an svn repo
when the repo has a mountpoint
+ Fix an issue where file.recurse would fail at the root of an hgfs repo
when the repo has a mountpoint
+ Fix an issue where file.recurse would fail at the root of an gitfs repo
when the repo has a mountpoint
+ Add status.master capability for Windows.
+ Various fixes to ssh_known_hosts
+ Various fixes to states.network bonding for Debian
+ The debian_ip.get_interfaces module no longer removes nameservers.
+ Better integration between grains.virtual and systemd-detect-virt and
virt-what
+ Fix traceback in sysctl.present state output
+ Fix for issue where mount.mounted would fail when superopts were not a part
of mount.active (extended=True). Also mount.mounted various fixes for Solaris
and FreeBSD.
+ Fix error where datetimes were not correctly safeguarded before being passed
into msgpack.
+ Fix file.replace regressions. If the pattern is not found, and if dry run is False,
and if `backup` is False, and if a pre-existing file exists with extension `.bak`,
then that backup file will be overwritten. This backup behavior is a result of how `fileinput`
works. Fixing it requires either passing through the file twice (the
first time only to search for content and set a flag), or rewriting
`file.replace` so it doesn't use `fileinput`
+ VCS filreserver fixes/optimizations
+ Catch fileserver configuration errors on master start
+ Raise errors on invalid gitfs configurations
+ set_locale when locale file does not exist (Redhat family)
+ Fix to correctly count active devices when created mdadm array with spares
+ Fix to correctly target minions in batch mode
+ Support ssh:// urls using the gitfs dulwhich backend
+ New fileserver runner
+ Fix various bugs with argument parsing to the publish module.
+ Fix disk.usage for Synology OS
+ Fix issue with tags occurring twice with docker.pulled
+ Fix incorrect key error in SMTP returner
+ Fix condition which would remount loopback filesystems on every state run
+ Remove requsites from listens after they are called in the state system
+ Make system implementation of service.running aware of legacy service calls
+ Fix issue where publish.publish would not handle duplicate responses gracefully.
+ Accept Kali Linux for aptpkg salt execution module
+ Fix bug where cmd.which could not handle a dirname as an argument
+ Fix issue in ps.pgrep where exceptions were thrown on Windows.
- Known Issues:
+ In multimaster mode, a minion may become temporarily unresponsive
if modules or pillars are refreshed at the same time that one
or more masters are down. This can be worked around by setting
'auth_timeout' and 'auth_tries' down to shorter periods.
-------------------------------------------------------------------
Thu Feb 12 19:35:34 UTC 2015 - aboe76@gmail.com
- New Bugfix release 2014.7.2:
- fix package bug with fdupes.
- keep sle 11 sp3 support.
+ Fix erroneous warnings for systemd service enabled check (issue 19606)
+ Fix FreeBSD kernel module loading, listing, and persistence kmod (issue 197151, issue 19682)
+ Allow case-sensitive npm package names in the npm state. This may break behavior
for people expecting the state to lowercase their npm package names for them.
The npm module was never affected by mandatory lowercasing. (issue 20329)
+ Deprecate the activate parameter for pip.install for both the module and the state.
If bin_env is given and points to a virtualenv, there is no need to activate that virtualenv
in a shell for pip to install to the virtualenv.
+ Fix a file-locking bug in gitfs (issue 18839)
-------------------------------------------------------------------
Thu Jan 15 17:50:52 UTC 2015 - aboe76@gmail.com
- New Bugfix release 2014.7.1:
+ Fixed gitfs serving symlinks in file.recurse states (issue 17700)
+ Fixed holding of multiple packages (YUM) when combined with version pinning (issue 18468)
+ Fixed use of Jinja templates in masterless mode with non-roots fileserver backend (issue 17963)
+ Re-enabled pillar and compound matching for mine and publish calls. Note that pillar globbing is still disabled for those modes, for security reasons. (issue 17194)
+ Fix for tty: True in salt-ssh (issue 16847)
- Needed to provide zsh completion because of the tarball missing the zsh completion script.
- Removed man salt.1.gz file from salt-master because upstream removed it.
- Added man salt.7.gz to salt-master package
-------------------------------------------------------------------
>>>>>>> updated suse spec file to version 2015.5.0
Mon Nov 3 21:35:31 UTC 2014 - aboe76@gmail.com
- Updated to Major Release 2014.7.0

View file

@ -16,7 +16,7 @@
#
Name: salt
Version: 2014.7.0
Version: 2015.5.0
Release: 0
Summary: A parallel remote execution system
License: Apache-2.0
@ -35,10 +35,11 @@ BuildRequires: python-M2Crypto
BuildRequires: python-PyYAML
BuildRequires: python-apache-libcloud >= 0.14.0
BuildRequires: python-devel
BuildRequires: python-msgpack-python
BuildRequires: python-msgpack-python > 0.3
BuildRequires: python-psutil
BuildRequires: python-pycrypto
BuildRequires: python-pyzmq
BuildRequires: python-pyzmq >= 2.2.0
BuildRequires: python-tornado
BuildRequires: python-requests >= 1.0.0
BuildRequires: python-yaml
@ -67,14 +68,17 @@ BuildRequires: python-sphinx
Requires: logrotate
Requires: python-Jinja2
Requires: python-M2Crypto
Requires: python-PyYAML
Requires: python-apache-libcloud
Requires: python-msgpack-python
Requires: python-psutil
Requires: python-requests
Requires: python-tornado
Requires: python-xml
Requires: python-yaml
Requires: python-yaml
Requires: python-zypp
Requires: python-pyzmq
Requires: python-pycrypto
Requires(pre): %fillup_prereq
%if 0%{?suse_version} < 1210
Requires(pre): %insserv_prereq
@ -115,7 +119,7 @@ Summary: The api for Salt a parallel remote execution system
Group: System/Monitoring
Requires: %{name} = %{version}
Requires: %{name}-master = %{version}
Recommends: python-CherryPy
Requires: python-CherryPy
%description api
salt-api is a modular interface on top of Salt that can provide a variety of entry points into a running Salt system.
@ -124,8 +128,9 @@ salt-api is a modular interface on top of Salt that can provide a variety of ent
Summary: Salt Cloud is a generic cloud provisioning tool
Group: System/Monitoring
Requires: %{name} = %{version}
Requires: python-PyYAML
Requires: %{name}-master = %{version}
Requires: python-apache-libcloud
Requires: python-requests
Recommends: python-botocore
Recommends: python-netaddr
@ -138,10 +143,6 @@ controlled profile and mapping system.
Summary: Documentation for salt, a parallel remote execution system
Group: Documentation/HTML
Requires: %{name} = %{version}
Requires: python-M2Crypto
Requires: python-msgpack-python
Requires: python-pycrypto
Requires: python-pyzmq
%description doc
Documentation of salt, offline version of http://docs.saltstack.com.
@ -157,16 +158,11 @@ Recommends: python-pygit2
Requires: git
Requires: python-pygit2
%endif
Requires: python-M2Crypto
Requires: python-msgpack-python
Requires: python-pycrypto
Requires: python-pyzmq
%ifarch %{ix86} x86_64
%if 0%{?suse_version} && 0%{?sles_version} == 0
Requires: dmidecode
%endif
%endif
Recommends: python-halite
%if 0%{?suse_version} < 1210
Requires(pre): %insserv_prereq
%endif
@ -181,10 +177,6 @@ than serially.
Summary: Client component for salt, a parallel remote execution system
Group: System/Monitoring
Requires: %{name} = %{version}
Requires: python-M2Crypto
Requires: python-msgpack-python
Requires: python-pycrypto
Requires: python-pyzmq
%if 0%{?suse_version} < 1210
Requires(pre): %insserv_prereq
%endif
@ -239,7 +231,6 @@ Bash command line completion support for %{name}.
%package zsh-completion
Summary: Zsh Completion for %{name}
Group: System/Management
Conflicts: salt-zsh-completion
Requires: %{name} = %{version}
Requires: zsh
BuildArch: noarch
@ -322,7 +313,7 @@ install -Dpm 0644 pkg/suse/salt.SuSEfirewall2 %{buildroot}%{_sysconfdir}/syscon
## install completion scripts
%if %with_bashcomp
install -Dpm 0644 pkg/salt.bash %{buildroot}/etc/bash_completion.d/%{name}
install -Dpm 0644 scripts/completion/zsh_completion.zsh %{buildroot}/etc/zsh_completion.d/%{name}
install -Dpm 0644 pkg/zsh_completion.zsh %{buildroot}/etc/zsh_completion.d/%{name}
%endif #with_bashcomp
#%%check

View file

@ -1,6 +1,13 @@
# -*- coding: utf-8 -*-
'''
Watch files and translate the changes into salt events
:depends: - pyinotify Python module >= 0.9.5
:Caution: Using generic mask options like open, access, ignored, and
: closed_nowrite with reactors can easily cause the reactor
: to loop on itself.
'''
# Import Python libs
from __future__ import absolute_import
@ -76,24 +83,24 @@ def beacon(config):
recurse: True
auto_add: True
The mask can be a single option from:
access
attrib
close_nowrite
close_write
create
delete
delete_self
excl_unlink
ignored
modify
moved_from
moved_to
move_self
oneshot
onlydir
open
unmount
The mask list can contain options:
* access File was accessed
* attrib Metadata changed
* close_nowrite Unwrittable file closed
* close_write Writtable file was closed
* create File created
* delete File deleted
* delete_self Named file or directory deleted
* excl_unlink
* ignored
* modify File was modified
* moved_from File being watched was moved
* moved_to File moved into watched area
* move_self Named file was moved
* oneshot
* onlydir Operate only if name is directory
* open File was opened
* unmount Backing fs was unmounted
recurse:
Tell the beacon to recursively watch files in the directory
auto_add:

View file

@ -559,6 +559,8 @@ def _virtual(osdata):
grains['virtual'] = 'kvm'
if 'Vendor: Bochs' in output:
grains['virtual'] = 'kvm'
if 'Manufacturer: Bochs' in output:
grains['virtual'] = 'kvm'
if 'BHYVE BVXSDT' in output:
grains['virtual'] = 'bhyve'
# Product Name: (oVirt) www.ovirt.org

View file

@ -240,7 +240,8 @@ def returner(ret):
ret['id'],
ret.get('success', False),
json.dumps(ret)))
except salt.exceptions.SaltMasterError:
except salt.exceptions.SaltMasterError as exc:
log.critical(exc)
log.critical('Could not store return with MySQL returner. MySQL server unavailable.')

View file

@ -0,0 +1,127 @@
# -*- 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.modules import sysbench
# Globals
sysbench.__salt__ = {}
@skipIf(NO_MOCK, NO_MOCK_REASON)
class SysbenchTestCase(TestCase):
'''
Test cases to salt.modules.sysbench
'''
def test_cpu(self):
'''
Test to tests to the CPU performance of minions.
'''
with patch.dict(sysbench.__salt__,
{'cmd.run': MagicMock(return_value={'A': 'a'})}):
with patch.object(sysbench, '_parser', return_value={'A': 'a'}):
self.assertEqual(sysbench.cpu(),
{'Prime numbers limit: 500':
{'A': 'a'}, 'Prime numbers limit: 5000':
{'A': 'a'}, 'Prime numbers limit: 2500':
{'A': 'a'}, 'Prime numbers limit: 1000':
{'A': 'a'}})
def test_threads(self):
'''
Test to this tests the performance of the processor's scheduler
'''
with patch.dict(sysbench.__salt__,
{'cmd.run': MagicMock(return_value={'A': 'a'})}):
with patch.object(sysbench, '_parser', return_value={'A': 'a'}):
self.assertEqual(sysbench.threads(),
{'Yields: 500 Locks: 8': {'A': 'a'},
'Yields: 200 Locks: 4': {'A': 'a'},
'Yields: 1000 Locks: 16': {'A': 'a'},
'Yields: 100 Locks: 2': {'A': 'a'}})
def test_mutex(self):
'''
Test to tests the implementation of mutex
'''
with patch.dict(sysbench.__salt__,
{'cmd.run': MagicMock(return_value={'A': 'a'})}):
with patch.object(sysbench, '_parser', return_value={'A': 'a'}):
self.assertEqual(sysbench.mutex(),
{'Mutex: 1000 Locks: 25000 Loops: 10000':
{'A': 'a'},
'Mutex: 50 Locks: 10000 Loops: 2500':
{'A': 'a'},
'Mutex: 1000 Locks: 10000 Loops: 5000':
{'A': 'a'},
'Mutex: 500 Locks: 50000 Loops: 5000':
{'A': 'a'},
'Mutex: 500 Locks: 25000 Loops: 2500':
{'A': 'a'},
'Mutex: 500 Locks: 10000 Loops: 10000':
{'A': 'a'},
'Mutex: 50 Locks: 50000 Loops: 10000':
{'A': 'a'},
'Mutex: 1000 Locks: 50000 Loops: 2500':
{'A': 'a'},
'Mutex: 50 Locks: 25000 Loops: 5000':
{'A': 'a'}})
def test_memory(self):
'''
Test to this tests the memory for read and write operations.
'''
with patch.dict(sysbench.__salt__,
{'cmd.run': MagicMock(return_value={'A': 'a'})}):
with patch.object(sysbench, '_parser', return_value={'A': 'a'}):
self.assertEqual(sysbench.memory(),
{'Operation: read Scope: local':
{'A': 'a'},
'Operation: write Scope: local':
{'A': 'a'},
'Operation: read Scope: global':
{'A': 'a'},
'Operation: write Scope: global':
{'A': 'a'}})
def test_fileio(self):
'''
Test to this tests for the file read and write operations
'''
with patch.dict(sysbench.__salt__,
{'cmd.run': MagicMock(return_value={'A': 'a'})}):
with patch.object(sysbench, '_parser', return_value={'A': 'a'}):
self.assertEqual(sysbench.fileio(),
{'Mode: seqrd': {'A': 'a'},
'Mode: seqwr': {'A': 'a'},
'Mode: rndrd': {'A': 'a'},
'Mode: rndwr': {'A': 'a'},
'Mode: seqrewr': {'A': 'a'},
'Mode: rndrw': {'A': 'a'}})
def test_ping(self):
'''
Test to ping
'''
self.assertTrue(sysbench.ping())
if __name__ == '__main__':
from integration import run_tests
run_tests(SysbenchTestCase, needs_daemon=False)

View file

@ -0,0 +1,93 @@
# -*- coding: utf-8 -*-
'''
:codeauthor: :email:`Rahul Handay <rahulha@saltstack.com>`
'''
# Import Python Libs
from __future__ import absolute_import
# Import Salt Testing Libs
from salttesting import TestCase, skipIf
from salttesting.helpers import ensure_in_syspath
from salttesting.mock import (
MagicMock,
patch,
NO_MOCK,
NO_MOCK_REASON
)
ensure_in_syspath('../../')
# Import Salt Libs
from salt.states import sysrc
# Globals
sysrc.__salt__ = {}
sysrc.__opts__ = {}
@skipIf(NO_MOCK, NO_MOCK_REASON)
class SysrcTestCase(TestCase):
'''
Validate the sysrc state
'''
def test_managed(self):
'''
Test to ensure a sysrc variable is set to a specific value.
'''
ret = {'name': 'salt',
'changes': {},
'result': True,
'comment': ''}
mock = MagicMock(side_effect=[{'key1': {'salt': 'stack'}}, None, None])
mock1 = MagicMock(return_value=True)
with patch.dict(sysrc.__salt__, {"sysrc.get": mock,
"sysrc.set": mock1}):
ret.update({'comment': 'salt is already set to the desired'
' value.'})
self.assertDictEqual(sysrc.managed('salt', 'stack'), ret)
with patch.dict(sysrc.__opts__, {"test": True}):
ret.update({'changes': {'new': 'salt = stack will be set.',
'old': None}, 'comment': 'The value'
' of "salt" will be changed!', 'result': None})
self.assertDictEqual(sysrc.managed('salt', 'stack'), ret)
with patch.dict(sysrc.__opts__, {"test": False}):
ret.update({'changes': {'new': True, 'old': None},
'comment': 'The value of "salt" was changed!',
'result': True})
self.assertDictEqual(sysrc.managed('salt', 'stack'), ret)
def test_absent(self):
'''
Test to ensure a sysrc variable is absent.
'''
ret = {'name': 'salt',
'changes': {},
'result': True,
'comment': ''}
mock = MagicMock(side_effect=[None, True, True])
mock1 = MagicMock(return_value=True)
with patch.dict(sysrc.__salt__, {"sysrc.get": mock,
"sysrc.remove": mock1}):
ret.update({'comment': '"salt" is already absent.'})
self.assertDictEqual(sysrc.absent('salt'), ret)
with patch.dict(sysrc.__opts__, {"test": True}):
ret.update({'changes': {'new': '"salt" will be removed.',
'old': True},
'comment': '"salt" will be removed!',
'result': None})
self.assertDictEqual(sysrc.absent('salt'), ret)
with patch.dict(sysrc.__opts__, {"test": False}):
ret.update({'changes': {'new': True, 'old': True},
'comment': '"salt" was removed!',
'result': True})
self.assertDictEqual(sysrc.absent('salt'), ret)
if __name__ == '__main__':
from integration import run_tests
run_tests(SysrcTestCase, needs_daemon=False)

View file

@ -0,0 +1,120 @@
# -*- coding: utf-8 -*-
'''
:codeauthor: :email:`Rahul Handay <rahulha@saltstack.com>`
'''
# Import Python Libs
from __future__ import absolute_import
# Import Salt Testing Libs
from salttesting import TestCase, skipIf
from salttesting.helpers import ensure_in_syspath
from salttesting.mock import (
patch,
NO_MOCK,
NO_MOCK_REASON
)
ensure_in_syspath('../../')
# Import Salt Libs
from salt.states import test
# Globals
test.__salt__ = {}
test.__opts__ = {}
test.__low__ = {'__reqs__': {'watch': ''}}
@skipIf(NO_MOCK, NO_MOCK_REASON)
class TestTestCase(TestCase):
'''
Validate the test state
'''
def test_succeed_without_changes(self):
'''
Test to returns successful.
'''
ret = {'name': 'salt',
'changes': {},
'result': True,
'comment': ''}
with patch.dict(test.__opts__, {"test": False}):
ret.update({'comment': 'Success!'})
self.assertDictEqual(test.succeed_without_changes('salt'), ret)
def test_fail_without_changes(self):
'''
Test to returns failure.
'''
ret = {'name': 'salt',
'changes': {},
'result': False,
'comment': ''}
with patch.dict(test.__opts__, {"test": False}):
ret.update({'comment': 'Failure!'})
self.assertDictEqual(test.fail_without_changes('salt'), ret)
def test_succeed_with_changes(self):
'''
Test to returns successful and changes is not empty
'''
ret = {'name': 'salt',
'changes': {},
'result': False,
'comment': ''}
with patch.dict(test.__opts__, {"test": False}):
ret.update({'changes': {'testing': {'new': 'Something pretended'
' to change',
'old': 'Unchanged'}},
'comment': 'Success!', 'result': True})
self.assertDictEqual(test.succeed_with_changes('salt'), ret)
def test_fail_with_changes(self):
'''
Test to returns failure and changes is not empty.
'''
ret = {'name': 'salt',
'changes': {},
'result': False,
'comment': ''}
with patch.dict(test.__opts__, {"test": False}):
ret.update({'changes': {'testing': {'new': 'Something pretended'
' to change',
'old': 'Unchanged'}},
'comment': 'Success!',
'result': True})
self.assertDictEqual(test.succeed_with_changes('salt'), ret)
def test_configurable_test_state(self):
'''
Test of a configurable test state which
determines its output based on the inputs.
'''
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)
def test_mod_watch(self):
'''
Test to call this function via a watch statement
'''
ret = {'name': 'salt',
'changes': {},
'result': True,
'comment': ''}
ret.update({'changes': {'Requisites with changes': []},
'comment': 'Watch statement fired.'})
self.assertDictEqual(test.mod_watch('salt'), ret)
if __name__ == '__main__':
from integration import run_tests
run_tests(TestTestCase, needs_daemon=False)

View file

@ -0,0 +1,70 @@
# -*- coding: utf-8 -*-
'''
:codeauthor: :email:`Rahul Handay <rahulha@saltstack.com>`
'''
# Import Python Libs
from __future__ import absolute_import
# Import Salt Testing Libs
from salt.exceptions import CommandExecutionError
from salttesting import TestCase, skipIf
from salttesting.helpers import ensure_in_syspath
from salttesting.mock import (
MagicMock,
patch,
NO_MOCK,
NO_MOCK_REASON
)
ensure_in_syspath('../../')
# Import Salt Libs
from salt.states import timezone
# Globals
timezone.__salt__ = {}
timezone.__opts__ = {}
@skipIf(NO_MOCK, NO_MOCK_REASON)
class TimezoneTestCase(TestCase):
'''
Validate the timezone state
'''
def test_system(self):
'''
Test to set the timezone for the system.
'''
ret = {'name': 'salt',
'changes': {},
'result': True,
'comment': ''}
mock = MagicMock(side_effect=[CommandExecutionError, True, True, True])
mock1 = MagicMock(side_effect=['local', 'localtime', 'localtime'])
mock2 = MagicMock(return_value=False)
with patch.dict(timezone.__salt__, {"timezone.zone_compare": mock,
"timezone.get_hwclock": mock1,
"timezone.set_hwclock": mock2}):
ret.update({'comment': "Unable to compare desrired timezone"
" 'salt' to system timezone: ", 'result': False})
self.assertDictEqual(timezone.system('salt'), ret)
ret.update({'comment': 'Timezone salt already set,'
' UTC already set to salt', 'result': True})
self.assertDictEqual(timezone.system('salt'), ret)
with patch.dict(timezone.__opts__, {"test": True}):
ret.update({'comment': 'UTC needs to be set to True',
'result': None})
self.assertDictEqual(timezone.system('salt'), ret)
with patch.dict(timezone.__opts__, {"test": False}):
ret.update({'comment': 'Failed to set UTC to True',
'result': False})
self.assertDictEqual(timezone.system('salt'), ret)
if __name__ == '__main__':
from integration import run_tests
run_tests(TimezoneTestCase, needs_daemon=False)

View file

@ -0,0 +1,161 @@
# -*- coding: utf-8 -*-
'''
:codeauthor: :email:`Rahul Handay <rahulha@saltstack.com>`
'''
# Import Python Libs
from __future__ import absolute_import
# Import Salt Testing Libs
from salttesting import TestCase, skipIf
from salttesting.helpers import ensure_in_syspath
from salttesting.mock import (
MagicMock,
patch,
NO_MOCK,
NO_MOCK_REASON
)
ensure_in_syspath('../../')
# Import Salt Libs
from salt.states import tomcat
# Globals
tomcat.__salt__ = {}
tomcat.__opts__ = {}
tomcat.__env__ = {}
@skipIf(NO_MOCK, NO_MOCK_REASON)
class TomcatTestCase(TestCase):
'''
Validate the tomcat state
'''
def test_war_deployed(self):
'''
Test to enforce that the WAR will be deployed and
started in the context path it will make use of WAR versions
'''
ret = {'name': 'salt',
'changes': {},
'result': True,
'comment': ''}
mock1 = MagicMock(return_value='saltstack')
mock2 = MagicMock(side_effect=['FAIL', 'saltstack'])
mock3 = MagicMock(return_value='deploy')
mock = MagicMock(side_effect=[{'salt': {'version': 'jenkins-1.2.4',
'mode': 'running'}},
{'salt': {'version': 1}},
{'salt': {'version': 'jenkins-1.2.4',
'mode': 'run'}},
{'salt': {'version': 1}},
{'salt': {'version': 1}}])
with patch.dict(tomcat.__salt__, {"tomcat.ls": mock,
'tomcat.start': mock1,
'tomcat.undeploy': mock2,
'tomcat.deploy_war': mock3}):
ret.update({'comment': 'salt in version jenkins-1.2.4'
' is already deployed'})
self.assertDictEqual(tomcat.war_deployed('salt',
'salt://jenkins'
'-1.2.4.war'), ret)
with patch.dict(tomcat.__opts__, {"test": True}):
ret.update({'changes': {'deploy': 'will deploy salt'
' in version jenkins-1.2.4',
'undeploy': 'undeployed salt'
' in version 1'},
'result': None, 'comment': ''})
self.assertDictEqual(tomcat.war_deployed('salt',
'salt://jenkins'
'-1.2.4.war'), ret)
with patch.dict(tomcat.__opts__, {"test": False}):
ret.update({'changes': {'start': 'starting salt'},
'comment': 'saltstack', 'result': False})
self.assertDictEqual(tomcat.war_deployed('salt',
'salt://jenkins'
'-1.2.4.war'), ret)
ret.update({'changes': {'deploy': 'will deploy salt in'
' version jenkins-1.2.4',
'undeploy': 'undeployed salt in'
' version 1'},
'comment': 'FAIL'})
self.assertDictEqual(tomcat.war_deployed('salt',
'salt://jenkins'
'-1.2.4.war'), ret)
ret.update({'changes': {'undeploy': 'undeployed salt'
' in version 1'},
'comment': 'deploy'})
self.assertDictEqual(tomcat.war_deployed('salt',
'salt://jenkins'
'-1.2.4.war'), ret)
def test_wait(self):
'''
Test to wait for the tomcat manager to load
'''
ret = {'name': 'salt',
'changes': {},
'result': True,
'comment': 'tomcat manager is ready'}
mock = MagicMock(return_value=True)
with patch.dict(tomcat.__salt__, {"tomcat.status": mock}):
self.assertDictEqual(tomcat.wait('salt'), ret)
def test_mod_watch(self):
'''
Test to the tomcat watcher function.
'''
ret = {'name': 'salt',
'changes': {},
'result': False,
'comment': 'True'}
mock = MagicMock(return_value='True')
with patch.dict(tomcat.__salt__, {"tomcat.reload": mock}):
ret.update({'changes': {'salt': False}})
self.assertDictEqual(tomcat.mod_watch('salt'), ret)
def test_undeployed(self):
'''
Test to enforce that the WAR will be un-deployed from the server
'''
ret = {'name': 'salt',
'changes': {},
'result': False,
'comment': 'True'}
mock = MagicMock(side_effect=[False, True, True, True, True])
mock1 = MagicMock(side_effect=[{'salt': {'a': 1}},
{'salt': {'version': 1}},
{'salt': {'version': 1}},
{'salt': {'version': 1}}])
mock2 = MagicMock(side_effect=['FAIL', 'saltstack'])
with patch.dict(tomcat.__salt__, {"tomcat.status": mock,
"tomcat.ls": mock1,
"tomcat.undeploy": mock2}):
ret.update({'comment': 'Tomcat Manager does not response'})
self.assertDictEqual(tomcat.undeployed('salt'), ret)
ret.update({'comment': '', 'result': True})
self.assertDictEqual(tomcat.undeployed('salt'), ret)
with patch.dict(tomcat.__opts__, {"test": True}):
ret.update({'changes': {'undeploy': 1}, 'result': None})
self.assertDictEqual(tomcat.undeployed('salt'), ret)
with patch.dict(tomcat.__opts__, {"test": False}):
ret.update({'changes': {'undeploy': 1},
'comment': 'FAIL', 'result': False})
self.assertDictEqual(tomcat.undeployed('salt'), ret)
ret.update({'changes': {'undeploy': 1},
'comment': '', 'result': True})
self.assertDictEqual(tomcat.undeployed('salt'), ret)
if __name__ == '__main__':
from integration import run_tests
run_tests(TomcatTestCase, needs_daemon=False)