2013-11-27 11:19:24 +00:00
# -*- coding: utf-8 -*-
Use explicit unicode strings + break up salt.utils
This PR is part of what will be an ongoing effort to use explicit
unicode strings in Salt. Because Python 3 does not suport Python 2's raw
unicode string syntax (i.e. `ur'\d+'`), we must use
`salt.utils.locales.sdecode()` to ensure that the raw string is unicode.
However, because of how `salt/utils/__init__.py` has evolved into the
hulking monstrosity it is today, this means importing a large module in
places where it is not needed, which could negatively impact
performance. For this reason, this PR also breaks out some of the
functions from `salt/utils/__init__.py` into new/existing modules under
`salt/utils/`. The long term goal will be that the modules within this
directory do not depend on importing `salt.utils`.
A summary of the changes in this PR is as follows:
* Moves the following functions from `salt.utils` to new locations
(including a deprecation warning if invoked from `salt.utils`):
`to_bytes`, `to_str`, `to_unicode`, `str_to_num`, `is_quoted`,
`dequote`, `is_hex`, `is_bin_str`, `rand_string`,
`contains_whitespace`, `clean_kwargs`, `invalid_kwargs`, `which`,
`which_bin`, `path_join`, `shlex_split`, `rand_str`, `is_windows`,
`is_proxy`, `is_linux`, `is_darwin`, `is_sunos`, `is_smartos`,
`is_smartos_globalzone`, `is_smartos_zone`, `is_freebsd`, `is_netbsd`,
`is_openbsd`, `is_aix`
* Moves the functions already deprecated by @rallytime to the bottom of
`salt/utils/__init__.py` for better organization, so we can keep the
deprecated ones separate from the ones yet to be deprecated as we
continue to break up `salt.utils`
* Updates `salt/*.py` and all files under `salt/client/` to use explicit
unicode string literals.
* Gets rid of implicit imports of `salt.utils` (e.g. `from salt.utils
import foo` becomes `import salt.utils.foo as foo`).
* Renames the `test.rand_str` function to `test.random_hash` to more
accurately reflect what it does
* Modifies `salt.utils.stringutils.random()` (née `salt.utils.rand_string()`)
such that it returns a string matching the passed size. Previously
this function would get `size` bytes from `os.urandom()`,
base64-encode it, and return the result, which would in most cases not
be equal to the passed size.
2017-07-24 20:47:15 -05:00
# Import Python libs
2014-11-21 19:05:13 +00:00
from __future__ import absolute_import
2012-08-26 00:38:39 +01:00
import os
2012-09-28 16:04:38 +01:00
import shutil
2017-12-24 11:52:20 -06:00
import tempfile
2015-03-02 16:08:49 -07:00
import textwrap
2016-10-04 20:06:59 +00:00
import threading
import time
2012-11-18 18:57:10 +00:00
2013-06-27 12:45:28 +01:00
# Import Salt Testing libs
2017-04-03 17:04:09 +01:00
from tests . support . case import ModuleCase
2017-02-27 13:58:07 +00:00
from tests . support . unit import skipIf
2017-12-01 18:08:03 -05:00
from tests . support . paths import TMP , TMP_PILLAR_TREE
2017-04-02 17:09:47 +01:00
from tests . support . mixins import SaltReturnAssertsMixin
2013-06-27 12:45:28 +01:00
Use explicit unicode strings + break up salt.utils
This PR is part of what will be an ongoing effort to use explicit
unicode strings in Salt. Because Python 3 does not suport Python 2's raw
unicode string syntax (i.e. `ur'\d+'`), we must use
`salt.utils.locales.sdecode()` to ensure that the raw string is unicode.
However, because of how `salt/utils/__init__.py` has evolved into the
hulking monstrosity it is today, this means importing a large module in
places where it is not needed, which could negatively impact
performance. For this reason, this PR also breaks out some of the
functions from `salt/utils/__init__.py` into new/existing modules under
`salt/utils/`. The long term goal will be that the modules within this
directory do not depend on importing `salt.utils`.
A summary of the changes in this PR is as follows:
* Moves the following functions from `salt.utils` to new locations
(including a deprecation warning if invoked from `salt.utils`):
`to_bytes`, `to_str`, `to_unicode`, `str_to_num`, `is_quoted`,
`dequote`, `is_hex`, `is_bin_str`, `rand_string`,
`contains_whitespace`, `clean_kwargs`, `invalid_kwargs`, `which`,
`which_bin`, `path_join`, `shlex_split`, `rand_str`, `is_windows`,
`is_proxy`, `is_linux`, `is_darwin`, `is_sunos`, `is_smartos`,
`is_smartos_globalzone`, `is_smartos_zone`, `is_freebsd`, `is_netbsd`,
`is_openbsd`, `is_aix`
* Moves the functions already deprecated by @rallytime to the bottom of
`salt/utils/__init__.py` for better organization, so we can keep the
deprecated ones separate from the ones yet to be deprecated as we
continue to break up `salt.utils`
* Updates `salt/*.py` and all files under `salt/client/` to use explicit
unicode string literals.
* Gets rid of implicit imports of `salt.utils` (e.g. `from salt.utils
import foo` becomes `import salt.utils.foo as foo`).
* Renames the `test.rand_str` function to `test.random_hash` to more
accurately reflect what it does
* Modifies `salt.utils.stringutils.random()` (née `salt.utils.rand_string()`)
such that it returns a string matching the passed size. Previously
this function would get `size` bytes from `os.urandom()`,
base64-encode it, and return the result, which would in most cases not
be equal to the passed size.
2017-07-24 20:47:15 -05:00
# Import Salt libs
2017-07-18 10:31:01 -06:00
import salt . utils . files
Use explicit unicode strings + break up salt.utils
This PR is part of what will be an ongoing effort to use explicit
unicode strings in Salt. Because Python 3 does not suport Python 2's raw
unicode string syntax (i.e. `ur'\d+'`), we must use
`salt.utils.locales.sdecode()` to ensure that the raw string is unicode.
However, because of how `salt/utils/__init__.py` has evolved into the
hulking monstrosity it is today, this means importing a large module in
places where it is not needed, which could negatively impact
performance. For this reason, this PR also breaks out some of the
functions from `salt/utils/__init__.py` into new/existing modules under
`salt/utils/`. The long term goal will be that the modules within this
directory do not depend on importing `salt.utils`.
A summary of the changes in this PR is as follows:
* Moves the following functions from `salt.utils` to new locations
(including a deprecation warning if invoked from `salt.utils`):
`to_bytes`, `to_str`, `to_unicode`, `str_to_num`, `is_quoted`,
`dequote`, `is_hex`, `is_bin_str`, `rand_string`,
`contains_whitespace`, `clean_kwargs`, `invalid_kwargs`, `which`,
`which_bin`, `path_join`, `shlex_split`, `rand_str`, `is_windows`,
`is_proxy`, `is_linux`, `is_darwin`, `is_sunos`, `is_smartos`,
`is_smartos_globalzone`, `is_smartos_zone`, `is_freebsd`, `is_netbsd`,
`is_openbsd`, `is_aix`
* Moves the functions already deprecated by @rallytime to the bottom of
`salt/utils/__init__.py` for better organization, so we can keep the
deprecated ones separate from the ones yet to be deprecated as we
continue to break up `salt.utils`
* Updates `salt/*.py` and all files under `salt/client/` to use explicit
unicode string literals.
* Gets rid of implicit imports of `salt.utils` (e.g. `from salt.utils
import foo` becomes `import salt.utils.foo as foo`).
* Renames the `test.rand_str` function to `test.random_hash` to more
accurately reflect what it does
* Modifies `salt.utils.stringutils.random()` (née `salt.utils.rand_string()`)
such that it returns a string matching the passed size. Previously
this function would get `size` bytes from `os.urandom()`,
base64-encode it, and return the result, which would in most cases not
be equal to the passed size.
2017-07-24 20:47:15 -05:00
import salt . utils . path
import salt . utils . platform
2014-01-11 12:19:29 -07:00
from salt . modules . virtualenv_mod import KNOWN_BINARY_NAMES
2012-05-05 19:39:23 +05:30
2014-11-21 20:27:56 +00:00
# Import 3rd-party libs
Use explicit unicode strings + break up salt.utils
This PR is part of what will be an ongoing effort to use explicit
unicode strings in Salt. Because Python 3 does not suport Python 2's raw
unicode string syntax (i.e. `ur'\d+'`), we must use
`salt.utils.locales.sdecode()` to ensure that the raw string is unicode.
However, because of how `salt/utils/__init__.py` has evolved into the
hulking monstrosity it is today, this means importing a large module in
places where it is not needed, which could negatively impact
performance. For this reason, this PR also breaks out some of the
functions from `salt/utils/__init__.py` into new/existing modules under
`salt/utils/`. The long term goal will be that the modules within this
directory do not depend on importing `salt.utils`.
A summary of the changes in this PR is as follows:
* Moves the following functions from `salt.utils` to new locations
(including a deprecation warning if invoked from `salt.utils`):
`to_bytes`, `to_str`, `to_unicode`, `str_to_num`, `is_quoted`,
`dequote`, `is_hex`, `is_bin_str`, `rand_string`,
`contains_whitespace`, `clean_kwargs`, `invalid_kwargs`, `which`,
`which_bin`, `path_join`, `shlex_split`, `rand_str`, `is_windows`,
`is_proxy`, `is_linux`, `is_darwin`, `is_sunos`, `is_smartos`,
`is_smartos_globalzone`, `is_smartos_zone`, `is_freebsd`, `is_netbsd`,
`is_openbsd`, `is_aix`
* Moves the functions already deprecated by @rallytime to the bottom of
`salt/utils/__init__.py` for better organization, so we can keep the
deprecated ones separate from the ones yet to be deprecated as we
continue to break up `salt.utils`
* Updates `salt/*.py` and all files under `salt/client/` to use explicit
unicode string literals.
* Gets rid of implicit imports of `salt.utils` (e.g. `from salt.utils
import foo` becomes `import salt.utils.foo as foo`).
* Renames the `test.rand_str` function to `test.random_hash` to more
accurately reflect what it does
* Modifies `salt.utils.stringutils.random()` (née `salt.utils.rand_string()`)
such that it returns a string matching the passed size. Previously
this function would get `size` bytes from `os.urandom()`,
base64-encode it, and return the result, which would in most cases not
be equal to the passed size.
2017-07-24 20:47:15 -05:00
from salt . ext import six
2014-11-21 20:27:56 +00:00
2017-10-30 21:23:22 -07:00
import logging
log = logging . getLogger ( __name__ )
2012-03-29 17:18:32 -06:00
2017-04-03 17:04:09 +01:00
class StateModuleTest ( ModuleCase , SaltReturnAssertsMixin ) :
2012-03-29 17:18:32 -06:00
'''
2015-03-02 16:08:49 -07:00
Validate the state module
2012-03-29 17:18:32 -06:00
'''
2012-09-01 07:49:34 +01:00
maxDiff = None
2012-03-29 17:18:32 -06:00
def test_show_highstate ( self ) :
'''
state . show_highstate
'''
high = self . run_function ( ' state.show_highstate ' )
2017-04-03 17:04:09 +01:00
destpath = os . path . join ( TMP , ' testfile ' )
2012-03-29 17:18:32 -06:00
self . assertTrue ( isinstance ( high , dict ) )
2013-11-01 19:36:09 +00:00
self . assertTrue ( destpath in high )
self . assertEqual ( high [ destpath ] [ ' __env__ ' ] , ' base ' )
2012-03-29 17:18:32 -06:00
def test_show_lowstate ( self ) :
'''
state . show_lowstate
'''
low = self . run_function ( ' state.show_lowstate ' )
self . assertTrue ( isinstance ( low , list ) )
self . assertTrue ( isinstance ( low [ 0 ] , dict ) )
2012-05-13 21:31:46 -06:00
def test_catch_recurse ( self ) :
'''
state . show_sls used to catch a recursive ref
'''
err = self . run_function ( ' state.sls ' , mods = ' recurse_fail ' )
2012-05-13 23:16:45 -06:00
self . assertIn ( ' recursive ' , err [ 0 ] )
2012-05-13 21:31:46 -06:00
2012-06-15 22:41:36 -06:00
def test_no_recurse ( self ) :
'''
2012-06-19 10:29:14 -06:00
verify that a sls structure is NOT a recursive ref
2012-06-15 22:41:36 -06:00
'''
sls = self . run_function ( ' state.show_sls ' , mods = ' recurse_ok ' )
self . assertIn ( ' snmpd ' , sls )
2012-06-19 10:29:14 -06:00
def test_no_recurse_two ( self ) :
'''
verify that a sls structure is NOT a recursive ref
'''
sls = self . run_function ( ' state.show_sls ' , mods = ' recurse_ok_two ' )
self . assertIn ( ' /etc/nagios/nrpe.cfg ' , sls )
2016-12-05 13:42:16 -07:00
def test_running_dictionary_consistency ( self ) :
'''
Test the structure of the running dictionary so we don ' t change it
without deprecating / documenting the change
'''
running_dict_fields = [
' __id__ ' ,
' __run_num__ ' ,
' __sls__ ' ,
' changes ' ,
' comment ' ,
' duration ' ,
' name ' ,
' result ' ,
' start_time ' ,
]
sls = self . run_function ( ' state.single ' ,
fun = ' test.succeed_with_changes ' ,
name = ' gndn ' )
for state , ret in sls . items ( ) :
for field in running_dict_fields :
self . assertIn ( field , ret )
2016-12-05 14:07:03 -07:00
def test_running_dictionary_key_sls ( self ) :
'''
Ensure the __sls__ key is either null or a string
'''
sls1 = self . run_function ( ' state.single ' ,
fun = ' test.succeed_with_changes ' ,
name = ' gndn ' )
sls2 = self . run_function ( ' state.sls ' , mods = ' gndn ' )
for state , ret in sls1 . items ( ) :
2016-12-08 02:07:47 -07:00
self . assertTrue ( isinstance ( ret [ ' __sls__ ' ] , type ( None ) ) )
2016-12-05 14:07:03 -07:00
for state , ret in sls2 . items ( ) :
Use explicit unicode strings + break up salt.utils
This PR is part of what will be an ongoing effort to use explicit
unicode strings in Salt. Because Python 3 does not suport Python 2's raw
unicode string syntax (i.e. `ur'\d+'`), we must use
`salt.utils.locales.sdecode()` to ensure that the raw string is unicode.
However, because of how `salt/utils/__init__.py` has evolved into the
hulking monstrosity it is today, this means importing a large module in
places where it is not needed, which could negatively impact
performance. For this reason, this PR also breaks out some of the
functions from `salt/utils/__init__.py` into new/existing modules under
`salt/utils/`. The long term goal will be that the modules within this
directory do not depend on importing `salt.utils`.
A summary of the changes in this PR is as follows:
* Moves the following functions from `salt.utils` to new locations
(including a deprecation warning if invoked from `salt.utils`):
`to_bytes`, `to_str`, `to_unicode`, `str_to_num`, `is_quoted`,
`dequote`, `is_hex`, `is_bin_str`, `rand_string`,
`contains_whitespace`, `clean_kwargs`, `invalid_kwargs`, `which`,
`which_bin`, `path_join`, `shlex_split`, `rand_str`, `is_windows`,
`is_proxy`, `is_linux`, `is_darwin`, `is_sunos`, `is_smartos`,
`is_smartos_globalzone`, `is_smartos_zone`, `is_freebsd`, `is_netbsd`,
`is_openbsd`, `is_aix`
* Moves the functions already deprecated by @rallytime to the bottom of
`salt/utils/__init__.py` for better organization, so we can keep the
deprecated ones separate from the ones yet to be deprecated as we
continue to break up `salt.utils`
* Updates `salt/*.py` and all files under `salt/client/` to use explicit
unicode string literals.
* Gets rid of implicit imports of `salt.utils` (e.g. `from salt.utils
import foo` becomes `import salt.utils.foo as foo`).
* Renames the `test.rand_str` function to `test.random_hash` to more
accurately reflect what it does
* Modifies `salt.utils.stringutils.random()` (née `salt.utils.rand_string()`)
such that it returns a string matching the passed size. Previously
this function would get `size` bytes from `os.urandom()`,
base64-encode it, and return the result, which would in most cases not
be equal to the passed size.
2017-07-24 20:47:15 -05:00
self . assertTrue ( isinstance ( ret [ ' __sls__ ' ] , six . string_types ) )
2016-12-05 14:07:03 -07:00
2015-02-17 13:10:21 -07:00
def _remove_request_cache_file ( self ) :
'''
remove minion state request file
'''
2017-04-02 16:56:17 +01:00
cache_file = os . path . join ( self . get_config ( ' minion ' ) [ ' cachedir ' ] , ' req_state.p ' )
2015-02-17 13:10:21 -07:00
if os . path . exists ( cache_file ) :
os . remove ( cache_file )
def test_request ( self ) :
'''
verify sending a state request to the minion ( s )
'''
self . _remove_request_cache_file ( )
ret = self . run_function ( ' state.request ' , mods = ' modules.state.requested ' )
2015-02-27 16:15:26 -07:00
result = ret [ ' cmd_|-count_root_dir_contents_|-ls -a / | wc -l_|-run ' ] [ ' result ' ]
self . assertEqual ( result , None )
2015-02-17 13:10:21 -07:00
def test_check_request ( self ) :
'''
verify checking a state request sent to the minion ( s )
'''
self . _remove_request_cache_file ( )
self . run_function ( ' state.request ' , mods = ' modules.state.requested ' )
ret = self . run_function ( ' state.check_request ' )
result = ret [ ' default ' ] [ ' test_run ' ] [ ' cmd_|-count_root_dir_contents_|-ls -a / | wc -l_|-run ' ] [ ' result ' ]
2015-02-27 16:15:26 -07:00
self . assertEqual ( result , None )
2015-02-17 13:10:21 -07:00
def test_clear_request ( self ) :
'''
verify clearing a state request sent to the minion ( s )
'''
self . _remove_request_cache_file ( )
self . run_function ( ' state.request ' , mods = ' modules.state.requested ' )
ret = self . run_function ( ' state.clear_request ' )
self . assertTrue ( ret )
def test_run_request_succeeded ( self ) :
'''
verify running a state request sent to the minion ( s )
'''
self . _remove_request_cache_file ( )
Use explicit unicode strings + break up salt.utils
This PR is part of what will be an ongoing effort to use explicit
unicode strings in Salt. Because Python 3 does not suport Python 2's raw
unicode string syntax (i.e. `ur'\d+'`), we must use
`salt.utils.locales.sdecode()` to ensure that the raw string is unicode.
However, because of how `salt/utils/__init__.py` has evolved into the
hulking monstrosity it is today, this means importing a large module in
places where it is not needed, which could negatively impact
performance. For this reason, this PR also breaks out some of the
functions from `salt/utils/__init__.py` into new/existing modules under
`salt/utils/`. The long term goal will be that the modules within this
directory do not depend on importing `salt.utils`.
A summary of the changes in this PR is as follows:
* Moves the following functions from `salt.utils` to new locations
(including a deprecation warning if invoked from `salt.utils`):
`to_bytes`, `to_str`, `to_unicode`, `str_to_num`, `is_quoted`,
`dequote`, `is_hex`, `is_bin_str`, `rand_string`,
`contains_whitespace`, `clean_kwargs`, `invalid_kwargs`, `which`,
`which_bin`, `path_join`, `shlex_split`, `rand_str`, `is_windows`,
`is_proxy`, `is_linux`, `is_darwin`, `is_sunos`, `is_smartos`,
`is_smartos_globalzone`, `is_smartos_zone`, `is_freebsd`, `is_netbsd`,
`is_openbsd`, `is_aix`
* Moves the functions already deprecated by @rallytime to the bottom of
`salt/utils/__init__.py` for better organization, so we can keep the
deprecated ones separate from the ones yet to be deprecated as we
continue to break up `salt.utils`
* Updates `salt/*.py` and all files under `salt/client/` to use explicit
unicode string literals.
* Gets rid of implicit imports of `salt.utils` (e.g. `from salt.utils
import foo` becomes `import salt.utils.foo as foo`).
* Renames the `test.rand_str` function to `test.random_hash` to more
accurately reflect what it does
* Modifies `salt.utils.stringutils.random()` (née `salt.utils.rand_string()`)
such that it returns a string matching the passed size. Previously
this function would get `size` bytes from `os.urandom()`,
base64-encode it, and return the result, which would in most cases not
be equal to the passed size.
2017-07-24 20:47:15 -05:00
if salt . utils . platform . is_windows ( ) :
2016-07-27 15:17:36 -07:00
self . run_function ( ' state.request ' , mods = ' modules.state.requested_win ' )
else :
self . run_function ( ' state.request ' , mods = ' modules.state.requested ' )
2015-02-17 13:10:21 -07:00
ret = self . run_function ( ' state.run_request ' )
2016-07-27 15:17:36 -07:00
Use explicit unicode strings + break up salt.utils
This PR is part of what will be an ongoing effort to use explicit
unicode strings in Salt. Because Python 3 does not suport Python 2's raw
unicode string syntax (i.e. `ur'\d+'`), we must use
`salt.utils.locales.sdecode()` to ensure that the raw string is unicode.
However, because of how `salt/utils/__init__.py` has evolved into the
hulking monstrosity it is today, this means importing a large module in
places where it is not needed, which could negatively impact
performance. For this reason, this PR also breaks out some of the
functions from `salt/utils/__init__.py` into new/existing modules under
`salt/utils/`. The long term goal will be that the modules within this
directory do not depend on importing `salt.utils`.
A summary of the changes in this PR is as follows:
* Moves the following functions from `salt.utils` to new locations
(including a deprecation warning if invoked from `salt.utils`):
`to_bytes`, `to_str`, `to_unicode`, `str_to_num`, `is_quoted`,
`dequote`, `is_hex`, `is_bin_str`, `rand_string`,
`contains_whitespace`, `clean_kwargs`, `invalid_kwargs`, `which`,
`which_bin`, `path_join`, `shlex_split`, `rand_str`, `is_windows`,
`is_proxy`, `is_linux`, `is_darwin`, `is_sunos`, `is_smartos`,
`is_smartos_globalzone`, `is_smartos_zone`, `is_freebsd`, `is_netbsd`,
`is_openbsd`, `is_aix`
* Moves the functions already deprecated by @rallytime to the bottom of
`salt/utils/__init__.py` for better organization, so we can keep the
deprecated ones separate from the ones yet to be deprecated as we
continue to break up `salt.utils`
* Updates `salt/*.py` and all files under `salt/client/` to use explicit
unicode string literals.
* Gets rid of implicit imports of `salt.utils` (e.g. `from salt.utils
import foo` becomes `import salt.utils.foo as foo`).
* Renames the `test.rand_str` function to `test.random_hash` to more
accurately reflect what it does
* Modifies `salt.utils.stringutils.random()` (née `salt.utils.rand_string()`)
such that it returns a string matching the passed size. Previously
this function would get `size` bytes from `os.urandom()`,
base64-encode it, and return the result, which would in most cases not
be equal to the passed size.
2017-07-24 20:47:15 -05:00
if salt . utils . platform . is_windows ( ) :
2016-07-27 15:17:36 -07:00
key = ' cmd_|-count_root_dir_contents_|-Get-ChildItem C: \\ \\ | Measure-Object | % { $_.Count}_|-run '
else :
key = ' cmd_|-count_root_dir_contents_|-ls -a / | wc -l_|-run '
result = ret [ key ] [ ' result ' ]
2015-02-17 13:10:21 -07:00
self . assertTrue ( result )
def test_run_request_failed_no_request_staged ( self ) :
'''
verify not running a state request sent to the minion ( s )
'''
self . _remove_request_cache_file ( )
self . run_function ( ' state.request ' , mods = ' modules.state.requested ' )
self . run_function ( ' state.clear_request ' )
ret = self . run_function ( ' state.run_request ' )
self . assertEqual ( ret , { } )
2012-09-01 07:49:34 +01:00
def test_issue_1896_file_append_source ( self ) :
'''
Verify that we can append a file ' s contents
'''
2017-04-03 17:04:09 +01:00
testfile = os . path . join ( TMP , ' test.append ' )
2012-11-06 11:20:06 +00:00
if os . path . isfile ( testfile ) :
os . unlink ( testfile )
ret = self . run_function ( ' state.sls ' , mods = ' testappend ' )
2012-12-07 18:44:06 +00:00
self . assertSaltTrueReturn ( ret )
2012-11-06 11:20:06 +00:00
ret = self . run_function ( ' state.sls ' , mods = ' testappend.step-1 ' )
2012-12-07 18:44:06 +00:00
self . assertSaltTrueReturn ( ret )
2012-11-06 11:20:06 +00:00
ret = self . run_function ( ' state.sls ' , mods = ' testappend.step-2 ' )
2012-12-07 18:44:06 +00:00
self . assertSaltTrueReturn ( ret )
2012-11-04 11:35:23 +00:00
2017-07-18 10:31:01 -06:00
with salt . utils . files . fopen ( testfile , ' r ' ) as fp_ :
2016-08-12 16:21:58 -06:00
testfile_contents = fp_ . read ( )
2016-07-27 15:17:36 -07:00
contents = textwrap . dedent ( ''' \
2015-03-02 16:08:49 -07:00
# set variable identifying the chroot you work in (used in the prompt below)
if [ - z " $debian_chroot " ] & & [ - r / etc / debian_chroot ] ; then
debian_chroot = $ ( cat / etc / debian_chroot )
2016-07-28 09:48:09 -07:00
fi
''' )
2016-07-28 09:33:23 -07:00
Use explicit unicode strings + break up salt.utils
This PR is part of what will be an ongoing effort to use explicit
unicode strings in Salt. Because Python 3 does not suport Python 2's raw
unicode string syntax (i.e. `ur'\d+'`), we must use
`salt.utils.locales.sdecode()` to ensure that the raw string is unicode.
However, because of how `salt/utils/__init__.py` has evolved into the
hulking monstrosity it is today, this means importing a large module in
places where it is not needed, which could negatively impact
performance. For this reason, this PR also breaks out some of the
functions from `salt/utils/__init__.py` into new/existing modules under
`salt/utils/`. The long term goal will be that the modules within this
directory do not depend on importing `salt.utils`.
A summary of the changes in this PR is as follows:
* Moves the following functions from `salt.utils` to new locations
(including a deprecation warning if invoked from `salt.utils`):
`to_bytes`, `to_str`, `to_unicode`, `str_to_num`, `is_quoted`,
`dequote`, `is_hex`, `is_bin_str`, `rand_string`,
`contains_whitespace`, `clean_kwargs`, `invalid_kwargs`, `which`,
`which_bin`, `path_join`, `shlex_split`, `rand_str`, `is_windows`,
`is_proxy`, `is_linux`, `is_darwin`, `is_sunos`, `is_smartos`,
`is_smartos_globalzone`, `is_smartos_zone`, `is_freebsd`, `is_netbsd`,
`is_openbsd`, `is_aix`
* Moves the functions already deprecated by @rallytime to the bottom of
`salt/utils/__init__.py` for better organization, so we can keep the
deprecated ones separate from the ones yet to be deprecated as we
continue to break up `salt.utils`
* Updates `salt/*.py` and all files under `salt/client/` to use explicit
unicode string literals.
* Gets rid of implicit imports of `salt.utils` (e.g. `from salt.utils
import foo` becomes `import salt.utils.foo as foo`).
* Renames the `test.rand_str` function to `test.random_hash` to more
accurately reflect what it does
* Modifies `salt.utils.stringutils.random()` (née `salt.utils.rand_string()`)
such that it returns a string matching the passed size. Previously
this function would get `size` bytes from `os.urandom()`,
base64-encode it, and return the result, which would in most cases not
be equal to the passed size.
2017-07-24 20:47:15 -05:00
if not salt . utils . platform . is_windows ( ) :
2016-07-28 09:33:23 -07:00
contents + = os . linesep
contents + = textwrap . dedent ( ''' \
2015-03-02 16:08:49 -07:00
# enable bash completion in interactive shells
if [ - f / etc / bash_completion ] & & ! shopt - oq posix ; then
. / etc / bash_completion
fi
2016-07-27 15:17:36 -07:00
''' )
Use explicit unicode strings + break up salt.utils
This PR is part of what will be an ongoing effort to use explicit
unicode strings in Salt. Because Python 3 does not suport Python 2's raw
unicode string syntax (i.e. `ur'\d+'`), we must use
`salt.utils.locales.sdecode()` to ensure that the raw string is unicode.
However, because of how `salt/utils/__init__.py` has evolved into the
hulking monstrosity it is today, this means importing a large module in
places where it is not needed, which could negatively impact
performance. For this reason, this PR also breaks out some of the
functions from `salt/utils/__init__.py` into new/existing modules under
`salt/utils/`. The long term goal will be that the modules within this
directory do not depend on importing `salt.utils`.
A summary of the changes in this PR is as follows:
* Moves the following functions from `salt.utils` to new locations
(including a deprecation warning if invoked from `salt.utils`):
`to_bytes`, `to_str`, `to_unicode`, `str_to_num`, `is_quoted`,
`dequote`, `is_hex`, `is_bin_str`, `rand_string`,
`contains_whitespace`, `clean_kwargs`, `invalid_kwargs`, `which`,
`which_bin`, `path_join`, `shlex_split`, `rand_str`, `is_windows`,
`is_proxy`, `is_linux`, `is_darwin`, `is_sunos`, `is_smartos`,
`is_smartos_globalzone`, `is_smartos_zone`, `is_freebsd`, `is_netbsd`,
`is_openbsd`, `is_aix`
* Moves the functions already deprecated by @rallytime to the bottom of
`salt/utils/__init__.py` for better organization, so we can keep the
deprecated ones separate from the ones yet to be deprecated as we
continue to break up `salt.utils`
* Updates `salt/*.py` and all files under `salt/client/` to use explicit
unicode string literals.
* Gets rid of implicit imports of `salt.utils` (e.g. `from salt.utils
import foo` becomes `import salt.utils.foo as foo`).
* Renames the `test.rand_str` function to `test.random_hash` to more
accurately reflect what it does
* Modifies `salt.utils.stringutils.random()` (née `salt.utils.rand_string()`)
such that it returns a string matching the passed size. Previously
this function would get `size` bytes from `os.urandom()`,
base64-encode it, and return the result, which would in most cases not
be equal to the passed size.
2017-07-24 20:47:15 -05:00
if salt . utils . platform . is_windows ( ) :
2016-07-27 15:17:36 -07:00
new_contents = contents . splitlines ( )
contents = os . linesep . join ( new_contents )
contents + = os . linesep
self . assertMultiLineEqual (
2016-08-12 16:21:58 -06:00
contents , testfile_contents )
2012-09-01 07:49:34 +01:00
# Re-append switching order
2012-11-06 11:20:06 +00:00
ret = self . run_function ( ' state.sls ' , mods = ' testappend.step-2 ' )
2012-12-07 18:44:06 +00:00
self . assertSaltTrueReturn ( ret )
2012-11-06 11:20:06 +00:00
ret = self . run_function ( ' state.sls ' , mods = ' testappend.step-1 ' )
2012-12-07 18:44:06 +00:00
self . assertSaltTrueReturn ( ret )
2012-11-06 11:20:06 +00:00
2017-07-18 10:31:01 -06:00
with salt . utils . files . fopen ( testfile , ' r ' ) as fp_ :
2016-08-12 16:21:58 -06:00
testfile_contents = fp_ . read ( )
2012-09-03 16:40:52 +01:00
2016-08-12 16:21:58 -06:00
self . assertMultiLineEqual ( contents , testfile_contents )
2012-09-01 07:49:34 +01:00
2012-08-25 14:44:07 +01:00
def test_issue_1876_syntax_error ( self ) :
'''
verify that we catch the following syntax error : :
/ tmp / salttest / issue - 1876 :
file :
- managed
- source : salt : / / testfile
file . append :
- text : foo
'''
2017-04-03 17:04:09 +01:00
testfile = os . path . join ( TMP , ' issue-1876 ' )
2012-08-25 14:44:07 +01:00
sls = self . run_function ( ' state.sls ' , mods = ' issue-1876 ' )
self . assertIn (
2015-08-26 23:26:08 -05:00
' ID \' {0} \' in SLS \' issue-1876 \' contains multiple state '
2014-04-21 20:07:06 -05:00
' declarations of the same type ' . format ( testfile ) ,
2012-11-06 11:20:06 +00:00
sls
2012-08-25 14:44:07 +01:00
)
2012-08-26 00:38:39 +01:00
def test_issue_1879_too_simple_contains_check ( self ) :
2016-08-11 11:45:24 -05:00
expected = textwrap . dedent ( ''' \
2015-03-02 16:08:49 -07:00
# set variable identifying the chroot you work in (used in the prompt below)
if [ - z " $debian_chroot " ] & & [ - r / etc / debian_chroot ] ; then
debian_chroot = $ ( cat / etc / debian_chroot )
fi
# enable bash completion in interactive shells
if [ - f / etc / bash_completion ] & & ! shopt - oq posix ; then
. / etc / bash_completion
fi
''' )
2016-07-27 15:17:36 -07:00
Use explicit unicode strings + break up salt.utils
This PR is part of what will be an ongoing effort to use explicit
unicode strings in Salt. Because Python 3 does not suport Python 2's raw
unicode string syntax (i.e. `ur'\d+'`), we must use
`salt.utils.locales.sdecode()` to ensure that the raw string is unicode.
However, because of how `salt/utils/__init__.py` has evolved into the
hulking monstrosity it is today, this means importing a large module in
places where it is not needed, which could negatively impact
performance. For this reason, this PR also breaks out some of the
functions from `salt/utils/__init__.py` into new/existing modules under
`salt/utils/`. The long term goal will be that the modules within this
directory do not depend on importing `salt.utils`.
A summary of the changes in this PR is as follows:
* Moves the following functions from `salt.utils` to new locations
(including a deprecation warning if invoked from `salt.utils`):
`to_bytes`, `to_str`, `to_unicode`, `str_to_num`, `is_quoted`,
`dequote`, `is_hex`, `is_bin_str`, `rand_string`,
`contains_whitespace`, `clean_kwargs`, `invalid_kwargs`, `which`,
`which_bin`, `path_join`, `shlex_split`, `rand_str`, `is_windows`,
`is_proxy`, `is_linux`, `is_darwin`, `is_sunos`, `is_smartos`,
`is_smartos_globalzone`, `is_smartos_zone`, `is_freebsd`, `is_netbsd`,
`is_openbsd`, `is_aix`
* Moves the functions already deprecated by @rallytime to the bottom of
`salt/utils/__init__.py` for better organization, so we can keep the
deprecated ones separate from the ones yet to be deprecated as we
continue to break up `salt.utils`
* Updates `salt/*.py` and all files under `salt/client/` to use explicit
unicode string literals.
* Gets rid of implicit imports of `salt.utils` (e.g. `from salt.utils
import foo` becomes `import salt.utils.foo as foo`).
* Renames the `test.rand_str` function to `test.random_hash` to more
accurately reflect what it does
* Modifies `salt.utils.stringutils.random()` (née `salt.utils.rand_string()`)
such that it returns a string matching the passed size. Previously
this function would get `size` bytes from `os.urandom()`,
base64-encode it, and return the result, which would in most cases not
be equal to the passed size.
2017-07-24 20:47:15 -05:00
if salt . utils . platform . is_windows ( ) :
2016-08-12 17:06:27 -06:00
new_contents = expected . splitlines ( )
expected = os . linesep . join ( new_contents )
expected + = os . linesep
2016-07-27 15:17:36 -07:00
2017-04-03 17:04:09 +01:00
testfile = os . path . join ( TMP , ' issue-1879 ' )
2012-11-04 11:46:00 +00:00
# Delete if exiting
2012-11-06 11:20:06 +00:00
if os . path . isfile ( testfile ) :
os . unlink ( testfile )
2012-11-04 11:46:00 +00:00
2012-08-28 10:03:11 +01:00
# Create the file
2013-01-14 14:07:58 +00:00
ret = self . run_function ( ' state.sls ' , mods = ' issue-1879 ' , timeout = 120 )
2012-12-07 18:44:06 +00:00
self . assertSaltTrueReturn ( ret )
2012-11-06 11:20:06 +00:00
2012-08-28 10:03:11 +01:00
# The first append
2013-01-14 14:07:58 +00:00
ret = self . run_function (
' state.sls ' , mods = ' issue-1879.step-1 ' , timeout = 120
)
2012-12-07 18:44:06 +00:00
self . assertSaltTrueReturn ( ret )
2012-11-06 11:20:06 +00:00
# The second append
2013-01-14 14:07:58 +00:00
ret = self . run_function (
' state.sls ' , mods = ' issue-1879.step-2 ' , timeout = 120
)
2012-12-07 18:44:06 +00:00
self . assertSaltTrueReturn ( ret )
2012-11-06 11:20:06 +00:00
2012-08-28 10:03:11 +01:00
# Does it match?
try :
2017-07-18 10:31:01 -06:00
with salt . utils . files . fopen ( testfile , ' r ' ) as fp_ :
2016-08-11 11:45:24 -05:00
contents = fp_ . read ( )
self . assertMultiLineEqual ( expected , contents )
2012-08-28 10:03:11 +01:00
# Make sure we don't re-append existing text
2013-01-14 14:07:58 +00:00
ret = self . run_function (
' state.sls ' , mods = ' issue-1879.step-1 ' , timeout = 120
)
2012-12-07 18:44:06 +00:00
self . assertSaltTrueReturn ( ret )
2013-01-14 14:07:58 +00:00
ret = self . run_function (
' state.sls ' , mods = ' issue-1879.step-2 ' , timeout = 120
)
2012-12-07 18:44:06 +00:00
self . assertSaltTrueReturn ( ret )
2016-08-11 11:45:24 -05:00
2017-07-18 10:31:01 -06:00
with salt . utils . files . fopen ( testfile , ' r ' ) as fp_ :
2016-08-11 11:45:24 -05:00
contents = fp_ . read ( )
self . assertMultiLineEqual ( expected , contents )
2012-08-28 10:03:11 +01:00
except Exception :
2012-11-06 11:20:06 +00:00
if os . path . exists ( testfile ) :
shutil . copy ( testfile , testfile + ' .bak ' )
2012-08-28 10:03:11 +01:00
raise
finally :
2012-11-06 11:20:06 +00:00
if os . path . exists ( testfile ) :
os . unlink ( testfile )
2012-08-26 00:38:39 +01:00
2012-09-28 01:17:37 +01:00
def test_include ( self ) :
2017-12-24 11:52:20 -06:00
tempdir = tempfile . mkdtemp ( dir = TMP )
self . addCleanup ( shutil . rmtree , tempdir , ignore_errors = True )
pillar = { }
for path in ( ' include-test ' , ' to-include-test ' , ' exclude-test ' ) :
pillar [ path ] = os . path . join ( tempdir , path )
ret = self . run_function ( ' state.sls ' , mods = ' include-test ' , pillar = pillar )
self . assertSaltTrueReturn ( ret )
self . assertTrue ( os . path . isfile ( pillar [ ' include-test ' ] ) )
self . assertTrue ( os . path . isfile ( pillar [ ' to-include-test ' ] ) )
self . assertFalse ( os . path . isfile ( pillar [ ' exclude-test ' ] ) )
2012-09-28 01:17:37 +01:00
def test_exclude ( self ) :
2017-12-24 11:52:20 -06:00
tempdir = tempfile . mkdtemp ( dir = TMP )
self . addCleanup ( shutil . rmtree , tempdir , ignore_errors = True )
pillar = { }
for path in ( ' include-test ' , ' exclude-test ' , ' to-include-test ' ) :
pillar [ path ] = os . path . join ( tempdir , path )
ret = self . run_function ( ' state.sls ' , mods = ' exclude-test ' , pillar = pillar )
self . assertSaltTrueReturn ( ret )
self . assertTrue ( os . path . isfile ( pillar [ ' include-test ' ] ) )
self . assertTrue ( os . path . isfile ( pillar [ ' exclude-test ' ] ) )
self . assertFalse ( os . path . isfile ( pillar [ ' to-include-test ' ] ) )
2013-06-24 20:06:49 +01:00
Use explicit unicode strings + break up salt.utils
This PR is part of what will be an ongoing effort to use explicit
unicode strings in Salt. Because Python 3 does not suport Python 2's raw
unicode string syntax (i.e. `ur'\d+'`), we must use
`salt.utils.locales.sdecode()` to ensure that the raw string is unicode.
However, because of how `salt/utils/__init__.py` has evolved into the
hulking monstrosity it is today, this means importing a large module in
places where it is not needed, which could negatively impact
performance. For this reason, this PR also breaks out some of the
functions from `salt/utils/__init__.py` into new/existing modules under
`salt/utils/`. The long term goal will be that the modules within this
directory do not depend on importing `salt.utils`.
A summary of the changes in this PR is as follows:
* Moves the following functions from `salt.utils` to new locations
(including a deprecation warning if invoked from `salt.utils`):
`to_bytes`, `to_str`, `to_unicode`, `str_to_num`, `is_quoted`,
`dequote`, `is_hex`, `is_bin_str`, `rand_string`,
`contains_whitespace`, `clean_kwargs`, `invalid_kwargs`, `which`,
`which_bin`, `path_join`, `shlex_split`, `rand_str`, `is_windows`,
`is_proxy`, `is_linux`, `is_darwin`, `is_sunos`, `is_smartos`,
`is_smartos_globalzone`, `is_smartos_zone`, `is_freebsd`, `is_netbsd`,
`is_openbsd`, `is_aix`
* Moves the functions already deprecated by @rallytime to the bottom of
`salt/utils/__init__.py` for better organization, so we can keep the
deprecated ones separate from the ones yet to be deprecated as we
continue to break up `salt.utils`
* Updates `salt/*.py` and all files under `salt/client/` to use explicit
unicode string literals.
* Gets rid of implicit imports of `salt.utils` (e.g. `from salt.utils
import foo` becomes `import salt.utils.foo as foo`).
* Renames the `test.rand_str` function to `test.random_hash` to more
accurately reflect what it does
* Modifies `salt.utils.stringutils.random()` (née `salt.utils.rand_string()`)
such that it returns a string matching the passed size. Previously
this function would get `size` bytes from `os.urandom()`,
base64-encode it, and return the result, which would in most cases not
be equal to the passed size.
2017-07-24 20:47:15 -05:00
@skipIf ( salt . utils . path . which_bin ( KNOWN_BINARY_NAMES ) is None , ' virtualenv not installed ' )
2012-09-28 16:04:38 +01:00
def test_issue_2068_template_str ( self ) :
2012-11-06 12:44:53 +00:00
venv_dir = os . path . join (
2017-04-03 17:04:09 +01:00
TMP , ' issue-2068-template-str '
2012-11-06 12:44:53 +00:00
)
2012-09-28 01:17:37 +01:00
2012-09-28 16:04:38 +01:00
try :
ret = self . run_function (
2013-01-14 14:07:58 +00:00
' state.sls ' , mods = ' issue-2068-template-str-no-dot ' ,
timeout = 120
2012-09-28 16:04:38 +01:00
)
2012-12-07 18:44:06 +00:00
self . assertSaltTrueReturn ( ret )
2012-09-28 16:04:38 +01:00
finally :
if os . path . isdir ( venv_dir ) :
shutil . rmtree ( venv_dir )
# Let's load the template from the filesystem. If running this state
# with state.sls works, so should using state.template_str
template_path = os . path . join (
os . path . dirname ( os . path . dirname ( __file__ ) ) ,
' files ' , ' file ' , ' base ' , ' issue-2068-template-str-no-dot.sls '
)
2017-07-18 10:31:01 -06:00
with salt . utils . files . fopen ( template_path , ' r ' ) as fp_ :
2016-08-11 11:45:24 -05:00
template = fp_ . read ( )
2013-01-14 14:07:58 +00:00
ret = self . run_function (
' state.template_str ' , [ template ] , timeout = 120
)
2012-12-07 18:44:06 +00:00
self . assertSaltTrueReturn ( ret )
2012-09-28 16:04:38 +01:00
2012-09-28 17:34:55 +01:00
# Now using state.template
2016-09-29 12:35:02 +09:00
ret = self . run_function (
' state.template ' , [ template_path ] , timeout = 120
)
self . assertSaltTrueReturn ( ret )
2012-09-28 17:34:55 +01:00
2012-09-28 16:04:38 +01:00
# Now the problematic #2068 including dot's
2016-09-29 12:35:02 +09:00
ret = self . run_function (
' state.sls ' , mods = ' issue-2068-template-str ' , timeout = 120
)
self . assertSaltTrueReturn ( ret )
2012-09-28 16:04:38 +01:00
# Let's load the template from the filesystem. If running this state
# with state.sls works, so should using state.template_str
template_path = os . path . join (
os . path . dirname ( os . path . dirname ( __file__ ) ) ,
' files ' , ' file ' , ' base ' , ' issue-2068-template-str.sls '
)
2017-07-18 10:31:01 -06:00
with salt . utils . files . fopen ( template_path , ' r ' ) as fp_ :
2016-08-11 11:45:24 -05:00
template = fp_ . read ( )
2016-09-29 12:35:02 +09:00
ret = self . run_function (
' state.template_str ' , [ template ] , timeout = 120
)
self . assertSaltTrueReturn ( ret )
2012-08-26 00:38:39 +01:00
2012-09-28 17:34:55 +01:00
# Now using state.template
2016-09-29 12:35:02 +09:00
ret = self . run_function (
' state.template ' , [ template_path ] , timeout = 120
)
self . assertSaltTrueReturn ( ret )
2012-09-28 17:34:55 +01:00
2012-09-28 17:56:13 +01:00
def test_template_invalid_items ( self ) :
2015-03-02 16:08:49 -07:00
TEMPLATE = textwrap . dedent ( ''' \
{ 0 } :
- issue - 2068 - template - str
/ tmp / test - template - invalid - items :
file :
- managed
- source : salt : / / testfile
''' )
2012-09-28 17:56:13 +01:00
for item in ( ' include ' , ' exclude ' , ' extends ' ) :
ret = self . run_function (
' state.template_str ' , [ TEMPLATE . format ( item ) ]
)
self . assertTrue ( isinstance ( ret , list ) )
self . assertNotEqual ( ret , [ ] )
self . assertEqual (
[ ' The \' {0} \' declaration found on \' <template-str> \' is '
' invalid when rendering single templates ' . format ( item ) ] ,
ret
)
2013-05-18 22:47:14 +00:00
def test_pydsl ( self ) :
'''
Test the basics of the pydsl
'''
ret = self . run_function ( ' state.sls ' , mods = ' pydsl-1 ' )
2013-05-18 22:58:08 +00:00
self . assertSaltTrueReturn ( ret )
2013-05-18 22:47:14 +00:00
2013-10-31 16:42:59 +00:00
def test_issues_7905_and_8174_sls_syntax_error ( self ) :
'''
Call sls file with yaml syntax error .
Ensure theses errors are detected and presented to the user without
stack traces .
'''
ret = self . run_function ( ' state.sls ' , mods = ' syntax.badlist ' )
self . assertEqual ( ret , [
2014-04-21 20:07:06 -05:00
' State \' A \' in SLS \' syntax.badlist \' is not formed as a list '
2013-10-31 16:42:59 +00:00
] )
ret = self . run_function ( ' state.sls ' , mods = ' syntax.badlist2 ' )
self . assertEqual ( ret , [
2014-04-21 20:36:23 -05:00
' State \' C \' in SLS \' syntax.badlist2 \' is not formed as a list '
2013-10-31 16:42:59 +00:00
] )
2013-11-24 18:28:22 +01:00
def test_requisites_mixed_require_prereq_use ( self ) :
'''
Call sls file containing several requisites .
'''
2013-11-27 12:48:53 +00:00
expected_simple_result = {
2013-11-24 18:28:22 +01:00
' cmd_|-A_|-echo A_|-run ' : {
' __run_num__ ' : 2 ,
' comment ' : ' Command " echo A " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True } ,
2013-11-24 18:28:22 +01:00
' cmd_|-B_|-echo B_|-run ' : {
' __run_num__ ' : 1 ,
' comment ' : ' Command " echo B " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True } ,
2013-11-24 18:28:22 +01:00
' cmd_|-C_|-echo C_|-run ' : {
' __run_num__ ' : 0 ,
' comment ' : ' Command " echo C " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True }
2013-11-24 18:28:22 +01:00
}
2013-11-27 12:48:53 +00:00
expected_result = {
2013-11-24 18:28:22 +01:00
' cmd_|-A_|-echo A fifth_|-run ' : {
' __run_num__ ' : 4 ,
' comment ' : ' Command " echo A fifth " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True } ,
2013-11-24 18:28:22 +01:00
' cmd_|-B_|-echo B third_|-run ' : {
' __run_num__ ' : 2 ,
' comment ' : ' Command " echo B third " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True } ,
2013-11-24 18:28:22 +01:00
' cmd_|-C_|-echo C second_|-run ' : {
' __run_num__ ' : 1 ,
' comment ' : ' Command " echo C second " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True } ,
2013-11-24 18:28:22 +01:00
' cmd_|-D_|-echo D first_|-run ' : {
' __run_num__ ' : 0 ,
' comment ' : ' Command " echo D first " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True } ,
2013-11-24 18:28:22 +01:00
' cmd_|-E_|-echo E fourth_|-run ' : {
' __run_num__ ' : 3 ,
' comment ' : ' Command " echo E fourth " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True }
2013-11-24 18:28:22 +01:00
}
2013-11-27 12:48:53 +00:00
expected_req_use_result = {
2013-11-25 11:06:37 +01:00
' cmd_|-A_|-echo A_|-run ' : {
' __run_num__ ' : 1 ,
' comment ' : ' Command " echo A " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True } ,
2013-11-25 11:06:37 +01:00
' cmd_|-B_|-echo B_|-run ' : {
' __run_num__ ' : 4 ,
' comment ' : ' Command " echo B " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True } ,
2013-11-25 11:06:37 +01:00
' cmd_|-C_|-echo C_|-run ' : {
' __run_num__ ' : 0 ,
' comment ' : ' Command " echo C " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True } ,
2013-11-25 11:06:37 +01:00
' cmd_|-D_|-echo D_|-run ' : {
' __run_num__ ' : 5 ,
' comment ' : ' Command " echo D " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True } ,
2013-11-25 11:06:37 +01:00
' cmd_|-E_|-echo E_|-run ' : {
' __run_num__ ' : 2 ,
' comment ' : ' Command " echo E " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True } ,
2013-11-25 11:06:37 +01:00
' cmd_|-F_|-echo F_|-run ' : {
' __run_num__ ' : 3 ,
' comment ' : ' Command " echo F " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True }
2013-11-25 11:06:37 +01:00
}
2013-11-24 18:28:22 +01:00
ret = self . run_function ( ' state.sls ' , mods = ' requisites.mixed_simple ' )
2014-10-30 16:58:03 -07:00
result = self . normalize_ret ( ret )
2014-06-11 01:12:13 +01:00
self . assertReturnNonEmptySaltType ( ret )
2013-11-24 18:28:22 +01:00
self . assertEqual ( expected_simple_result , result )
# test Traceback recursion prereq+require #8785
# TODO: this is actually failing badly
#ret = self.run_function('state.sls', mods='requisites.prereq_require_recursion_error2')
#self.assertEqual(
# ret,
# ['A recursive requisite was found, SLS "requisites.prereq_require_recursion_error2" ID "B" ID "A"']
#)
# test Infinite recursion prereq+require #8785 v2
# TODO: this is actually failing badly
#ret = self.run_function('state.sls', mods='requisites.prereq_require_recursion_error3')
#self.assertEqual(
# ret,
# ['A recursive requisite was found, SLS "requisites.prereq_require_recursion_error2" ID "B" ID "A"']
#)
# test Infinite recursion prereq+require #8785 v3
# TODO: this is actually failing badly, and expected result is maybe not a recursion
#ret = self.run_function('state.sls', mods='requisites.prereq_require_recursion_error4')
#self.assertEqual(
# ret,
# ['A recursive requisite was found, SLS "requisites.prereq_require_recursion_error2" ID "B" ID "A"']
#)
# undetected infinite loopS prevents this test from running...
# TODO: this is actually failing badly
#ret = self.run_function('state.sls', mods='requisites.mixed_complex1')
2014-10-30 16:58:03 -07:00
#result = self.normalize_ret(ret)
2013-11-24 18:28:22 +01:00
#self.assertEqual(expected_result, result)
2017-11-16 12:18:30 -05:00
def test_watch_in ( self ) :
'''
test watch_in requisite when there is a success
'''
ret = self . run_function ( ' state.sls ' , mods = ' requisites.watch_in ' )
2017-11-20 11:19:25 -05:00
changes = ' test_|-return_changes_|-return_changes_|-succeed_with_changes '
watch = ' test_|-watch_states_|-watch_states_|-succeed_without_changes '
self . assertEqual ( ret [ changes ] [ ' __run_num__ ' ] , 0 )
self . assertEqual ( ret [ watch ] [ ' __run_num__ ' ] , 2 )
2017-11-16 12:18:30 -05:00
2017-11-20 11:19:25 -05:00
self . assertEqual ( ' Watch statement fired. ' , ret [ watch ] [ ' comment ' ] )
2017-11-16 12:18:30 -05:00
self . assertEqual ( ' Something pretended to change ' ,
2017-11-20 11:19:25 -05:00
ret [ changes ] [ ' changes ' ] [ ' testing ' ] [ ' new ' ] )
2017-11-16 12:18:30 -05:00
def test_watch_in_failure ( self ) :
'''
test watch_in requisite when there is a failure
'''
ret = self . run_function ( ' state.sls ' , mods = ' requisites.watch_in_failure ' )
2017-11-20 11:32:26 -05:00
fail = ' test_|-return_changes_|-return_changes_|-fail_with_changes '
watch = ' test_|-watch_states_|-watch_states_|-succeed_without_changes '
2017-11-16 12:18:30 -05:00
2017-11-20 11:32:26 -05:00
self . assertEqual ( False , ret [ fail ] [ ' result ' ] )
2017-11-16 12:18:30 -05:00
self . assertEqual ( ' One or more requisite failed: requisites.watch_in_failure.return_changes ' ,
2017-11-20 11:32:26 -05:00
ret [ watch ] [ ' comment ' ] )
2017-11-16 12:18:30 -05:00
2014-10-30 16:58:03 -07:00
def normalize_ret ( self , ret ) :
'''
Normalize the return to the format that we ' ll use for result checking
'''
result = { }
2014-11-21 20:27:56 +00:00
for item , descr in six . iteritems ( ret ) :
2014-10-30 16:58:03 -07:00
result [ item ] = {
' __run_num__ ' : descr [ ' __run_num__ ' ] ,
' comment ' : descr [ ' comment ' ] ,
' result ' : descr [ ' result ' ] ,
' changes ' : descr [ ' changes ' ] != { } # whether there where any changes
}
return result
2013-11-23 16:37:57 +01:00
def test_requisites_require_ordering_and_errors ( self ) :
'''
Call sls file containing several require_in and require .
Ensure that some of them are failing and that the order is right .
'''
2013-11-27 12:48:53 +00:00
expected_result = {
2013-11-23 16:37:57 +01:00
' cmd_|-A_|-echo A fifth_|-run ' : {
' __run_num__ ' : 4 ,
' comment ' : ' Command " echo A fifth " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True ,
2013-12-06 14:44:48 -06:00
} ,
2013-11-23 16:37:57 +01:00
' cmd_|-B_|-echo B second_|-run ' : {
' __run_num__ ' : 1 ,
' comment ' : ' Command " echo B second " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True ,
2013-12-06 14:44:48 -06:00
} ,
2013-11-23 16:37:57 +01:00
' cmd_|-C_|-echo C third_|-run ' : {
' __run_num__ ' : 2 ,
' comment ' : ' Command " echo C third " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True ,
2013-12-06 14:44:48 -06:00
} ,
2013-11-23 16:37:57 +01:00
' cmd_|-D_|-echo D first_|-run ' : {
' __run_num__ ' : 0 ,
' comment ' : ' Command " echo D first " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True ,
2013-12-06 14:44:48 -06:00
} ,
2013-11-23 16:37:57 +01:00
' cmd_|-E_|-echo E fourth_|-run ' : {
' __run_num__ ' : 3 ,
' comment ' : ' Command " echo E fourth " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True ,
2013-12-06 14:44:48 -06:00
} ,
2013-11-23 16:37:57 +01:00
' cmd_|-F_|-echo F_|-run ' : {
' __run_num__ ' : 5 ,
' comment ' : ' The following requisites were not found: \n '
+ ' require: \n '
+ ' foobar: A \n ' ,
2014-10-30 16:58:03 -07:00
' result ' : False ,
' changes ' : False ,
2013-12-06 14:44:48 -06:00
} ,
2013-11-23 16:37:57 +01:00
' cmd_|-G_|-echo G_|-run ' : {
' __run_num__ ' : 6 ,
' comment ' : ' The following requisites were not found: \n '
+ ' require: \n '
+ ' cmd: Z \n ' ,
2014-10-30 16:58:03 -07:00
' result ' : False ,
' changes ' : False ,
2013-12-06 14:44:48 -06:00
} ,
2013-11-26 11:57:09 +01:00
' cmd_|-H_|-echo H_|-run ' : {
' __run_num__ ' : 7 ,
2013-11-23 16:37:57 +01:00
' comment ' : ' The following requisites were not found: \n '
+ ' require: \n '
+ ' cmd: Z \n ' ,
2014-10-30 16:58:03 -07:00
' result ' : False ,
' changes ' : False ,
2013-12-06 14:44:48 -06:00
}
2013-11-23 16:37:57 +01:00
}
ret = self . run_function ( ' state.sls ' , mods = ' requisites.require ' )
2014-10-30 16:58:03 -07:00
result = self . normalize_ret ( ret )
2014-06-11 01:12:13 +01:00
self . assertReturnNonEmptySaltType ( ret )
2013-11-23 16:37:57 +01:00
self . assertEqual ( expected_result , result )
2013-11-25 12:58:59 +01:00
2013-11-23 16:37:57 +01:00
ret = self . run_function ( ' state.sls ' , mods = ' requisites.require_error1 ' )
self . assertEqual ( ret , [
2014-05-14 16:09:27 -06:00
" Cannot extend ID ' W ' in ' base:requisites.require_error1 ' . It is not part of the high state. \n This is likely due to a missing include statement or an incorrectly typed ID. \n Ensure that a state with an ID of ' W ' is available \n in environment ' base ' and to SLS ' requisites.require_error1 ' "
2013-11-23 16:37:57 +01:00
] )
2013-11-23 18:20:15 +01:00
2013-11-25 12:58:59 +01:00
# issue #8235
# FIXME: Why is require enforcing list syntax while require_in does not?
# And why preventing it?
# Currently this state fails, should return C/B/A
2013-11-27 12:48:53 +00:00
result = { }
2013-11-25 12:58:59 +01:00
ret = self . run_function ( ' state.sls ' , mods = ' requisites.require_simple_nolist ' )
self . assertEqual ( ret , [
2014-04-21 20:07:06 -05:00
' The require statement in state \' B \' in SLS '
+ ' \' requisites.require_simple_nolist \' needs to be formed as a list '
2013-11-25 12:58:59 +01:00
] )
2013-11-23 16:37:57 +01:00
# commented until a fix is made for issue #8772
2013-11-23 18:20:15 +01:00
# TODO: this test actually fails
2013-11-23 16:37:57 +01:00
#ret = self.run_function('state.sls', mods='requisites.require_error2')
#self.assertEqual(ret, [
# 'Cannot extend state foobar for ID A in "base:requisites.require_error2".'
# + ' It is not part of the high state.'
#])
2013-11-23 18:20:15 +01:00
ret = self . run_function ( ' state.sls ' , mods = ' requisites.require_recursion_error1 ' )
self . assertEqual (
ret ,
[ ' A recursive requisite was found, SLS " requisites.require_recursion_error1 " ID " B " ID " A " ' ]
)
2017-11-06 09:57:54 -07:00
def test_requisites_require_any ( self ) :
'''
Call sls file containing several require_in and require .
Ensure that some of them are failing and that the order is right .
'''
expected_result = {
' cmd_|-A_|-echo A_|-run ' : {
' __run_num__ ' : 3 ,
' comment ' : ' Command " echo A " run ' ,
' result ' : True ,
' changes ' : True ,
} ,
' cmd_|-B_|-echo B_|-run ' : {
' __run_num__ ' : 0 ,
' comment ' : ' Command " echo B " run ' ,
' result ' : True ,
' changes ' : True ,
} ,
' cmd_|-C_|-/bin/false_|-run ' : {
' __run_num__ ' : 1 ,
' comment ' : ' Command " /bin/false " run ' ,
' result ' : False ,
' changes ' : True ,
} ,
' cmd_|-D_|-echo D_|-run ' : {
' __run_num__ ' : 2 ,
' comment ' : ' Command " echo D " run ' ,
' result ' : True ,
' changes ' : True ,
} ,
}
ret = self . run_function ( ' state.sls ' , mods = ' requisites.require_any ' )
result = self . normalize_ret ( ret )
self . assertReturnNonEmptySaltType ( ret )
self . assertEqual ( expected_result , result )
def test_requisites_require_any_fail ( self ) :
'''
Call sls file containing several require_in and require .
Ensure that some of them are failing and that the order is right .
'''
ret = self . run_function ( ' state.sls ' , mods = ' requisites.require_any_fail ' )
result = self . normalize_ret ( ret )
self . assertReturnNonEmptySaltType ( ret )
2017-11-07 09:24:59 -07:00
self . assertIn ( ' One or more requisite failed ' ,
result [ ' cmd_|-D_|-echo D_|-run ' ] [ ' comment ' ] )
2017-11-06 09:57:54 -07:00
def test_requisites_watch_any ( self ) :
'''
Call sls file containing several require_in and require .
Ensure that some of them are failing and that the order is right .
'''
expected_result = {
' cmd_|-A_|-true_|-wait ' : {
' __run_num__ ' : 4 ,
' comment ' : ' Command " true " run ' ,
' result ' : True ,
' changes ' : True ,
} ,
' cmd_|-B_|-true_|-run ' : {
' __run_num__ ' : 0 ,
' comment ' : ' Command " true " run ' ,
' result ' : True ,
' changes ' : True ,
} ,
' cmd_|-C_|-false_|-run ' : {
' __run_num__ ' : 1 ,
' comment ' : ' Command " false " run ' ,
' result ' : False ,
' changes ' : True ,
} ,
' cmd_|-D_|-true_|-run ' : {
' __run_num__ ' : 2 ,
' comment ' : ' Command " true " run ' ,
' result ' : True ,
' changes ' : True ,
} ,
' cmd_|-E_|-true_|-wait ' : {
' __run_num__ ' : 9 ,
' comment ' : ' Command " true " run ' ,
' result ' : True ,
' changes ' : True ,
} ,
' cmd_|-F_|-true_|-run ' : {
' __run_num__ ' : 5 ,
' comment ' : ' Command " true " run ' ,
' result ' : True ,
' changes ' : True ,
} ,
' cmd_|-G_|-false_|-run ' : {
' __run_num__ ' : 6 ,
' comment ' : ' Command " false " run ' ,
' result ' : False ,
' changes ' : True ,
} ,
' cmd_|-H_|-false_|-run ' : {
' __run_num__ ' : 7 ,
' comment ' : ' Command " false " run ' ,
' result ' : False ,
' changes ' : True ,
} ,
}
ret = self . run_function ( ' state.sls ' , mods = ' requisites.watch_any ' )
result = self . normalize_ret ( ret )
self . assertReturnNonEmptySaltType ( ret )
self . assertEqual ( expected_result , result )
def test_requisites_watch_any_fail ( self ) :
'''
Call sls file containing several require_in and require .
Ensure that some of them are failing and that the order is right .
'''
ret = self . run_function ( ' state.sls ' , mods = ' requisites.watch_any_fail ' )
result = self . normalize_ret ( ret )
self . assertReturnNonEmptySaltType ( ret )
2017-11-07 09:24:59 -07:00
self . assertIn ( ' One or more requisite failed ' ,
result [ ' cmd_|-A_|-true_|-wait ' ] [ ' comment ' ] )
2017-11-06 09:57:54 -07:00
def test_requisites_onchanges_any ( self ) :
'''
Call sls file containing several require_in and require .
Ensure that some of them are failing and that the order is right .
'''
expected_result = {
' cmd_|-another_changing_state_|-echo " Changed! " _|-run ' : {
' __run_num__ ' : 1 ,
' changes ' : True ,
' comment ' : ' Command " echo " Changed! " " run ' ,
' result ' : True
} ,
' cmd_|-changing_state_|-echo " Changed! " _|-run ' : {
' __run_num__ ' : 0 ,
' changes ' : True ,
' comment ' : ' Command " echo " Changed! " " run ' ,
' result ' : True
} ,
' cmd_|-test_one_changing_states_|-echo " Success! " _|-run ' : {
' __run_num__ ' : 4 ,
' changes ' : True ,
' comment ' : ' Command " echo " Success! " " run ' ,
' result ' : True
} ,
' cmd_|-test_two_non_changing_states_|-echo " Should not run " _|-run ' : {
' __run_num__ ' : 5 ,
' changes ' : False ,
' comment ' : ' State was not run because none of the onchanges reqs changed ' ,
' result ' : True
} ,
' pip_|-another_non_changing_state_|-mock_|-installed ' : {
' __run_num__ ' : 3 ,
' changes ' : False ,
' comment ' : ' Python package mock was already installed \n All packages were successfully installed ' ,
' result ' : True
} ,
' pip_|-non_changing_state_|-mock_|-installed ' : {
' __run_num__ ' : 2 ,
' changes ' : False ,
' comment ' : ' Python package mock was already installed \n All packages were successfully installed ' ,
' result ' : True
}
}
ret = self . run_function ( ' state.sls ' , mods = ' requisites.onchanges_any ' )
result = self . normalize_ret ( ret )
self . assertReturnNonEmptySaltType ( ret )
self . assertEqual ( expected_result , result )
def test_requisites_onfail_any ( self ) :
'''
Call sls file containing several require_in and require .
Ensure that some of them are failing and that the order is right .
'''
expected_result = {
' cmd_|-a_|-exit 0_|-run ' : {
' __run_num__ ' : 0 ,
' changes ' : True ,
' comment ' : ' Command " exit 0 " run ' ,
' result ' : True
} ,
' cmd_|-b_|-exit 1_|-run ' : {
' __run_num__ ' : 1 ,
' changes ' : True ,
' comment ' : ' Command " exit 1 " run ' ,
' result ' : False
} ,
' cmd_|-c_|-exit 0_|-run ' : {
' __run_num__ ' : 2 ,
' changes ' : True ,
' comment ' : ' Command " exit 0 " run ' ,
' result ' : True
} ,
' cmd_|-d_|-echo itworked_|-run ' : {
' __run_num__ ' : 3 ,
' changes ' : True ,
' comment ' : ' Command " echo itworked " run ' ,
' result ' : True } ,
' cmd_|-e_|-exit 0_|-run ' : {
' __run_num__ ' : 4 ,
' changes ' : True ,
' comment ' : ' Command " exit 0 " run ' ,
' result ' : True
} ,
' cmd_|-f_|-exit 0_|-run ' : {
' __run_num__ ' : 5 ,
' changes ' : True ,
' comment ' : ' Command " exit 0 " run ' ,
' result ' : True
} ,
' cmd_|-g_|-exit 0_|-run ' : {
' __run_num__ ' : 6 ,
' changes ' : True ,
' comment ' : ' Command " exit 0 " run ' ,
' result ' : True
} ,
' cmd_|-h_|-echo itworked_|-run ' : {
' __run_num__ ' : 7 ,
' changes ' : False ,
' comment ' : ' State was not run because onfail req did not change ' ,
' result ' : True
}
}
ret = self . run_function ( ' state.sls ' , mods = ' requisites.onfail_any ' )
result = self . normalize_ret ( ret )
self . assertReturnNonEmptySaltType ( ret )
self . assertEqual ( expected_result , result )
2013-11-23 18:56:07 +01:00
def test_requisites_full_sls ( self ) :
'''
Teste the sls special command in requisites
'''
2013-11-27 12:48:53 +00:00
expected_result = {
2013-11-23 18:56:07 +01:00
' cmd_|-A_|-echo A_|-run ' : {
' __run_num__ ' : 2 ,
' comment ' : ' Command " echo A " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True } ,
2013-11-23 18:56:07 +01:00
' cmd_|-B_|-echo B_|-run ' : {
' __run_num__ ' : 0 ,
' comment ' : ' Command " echo B " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True } ,
2013-11-23 18:56:07 +01:00
' cmd_|-C_|-echo C_|-run ' : {
' __run_num__ ' : 1 ,
' comment ' : ' Command " echo C " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True } ,
2013-11-23 18:56:07 +01:00
}
ret = self . run_function ( ' state.sls ' , mods = ' requisites.fullsls_require ' )
2014-06-11 01:12:13 +01:00
self . assertReturnNonEmptySaltType ( ret )
2014-10-30 16:58:03 -07:00
result = self . normalize_ret ( ret )
2013-11-23 18:56:07 +01:00
self . assertEqual ( expected_result , result )
2013-11-25 12:58:59 +01:00
2013-11-23 18:56:07 +01:00
# issue #8233: traceback on prereq sls
# TODO: not done
#ret = self.run_function('state.sls', mods='requisites.fullsls_prereq')
#self.assertEqual(['sls command can only be used with require requisite'], ret)
2017-11-16 08:44:31 -08:00
def test_requisites_require_no_state_module ( self ) :
'''
Call sls file containing several require_in and require .
Ensure that some of them are failing and that the order is right .
'''
expected_result = {
' cmd_|-A_|-echo A fifth_|-run ' : {
' __run_num__ ' : 4 ,
' comment ' : ' Command " echo A fifth " run ' ,
' result ' : True ,
' changes ' : True ,
} ,
' cmd_|-B_|-echo B second_|-run ' : {
' __run_num__ ' : 1 ,
' comment ' : ' Command " echo B second " run ' ,
' result ' : True ,
' changes ' : True ,
} ,
' cmd_|-C_|-echo C third_|-run ' : {
' __run_num__ ' : 2 ,
' comment ' : ' Command " echo C third " run ' ,
' result ' : True ,
' changes ' : True ,
} ,
' cmd_|-D_|-echo D first_|-run ' : {
' __run_num__ ' : 0 ,
' comment ' : ' Command " echo D first " run ' ,
' result ' : True ,
' changes ' : True ,
} ,
' cmd_|-E_|-echo E fourth_|-run ' : {
' __run_num__ ' : 3 ,
' comment ' : ' Command " echo E fourth " run ' ,
' result ' : True ,
' changes ' : True ,
} ,
' cmd_|-G_|-echo G_|-run ' : {
' __run_num__ ' : 5 ,
' comment ' : ' The following requisites were not found: \n '
+ ' require: \n '
+ ' id: Z \n ' ,
' result ' : False ,
' changes ' : False ,
} ,
' cmd_|-H_|-echo H_|-run ' : {
' __run_num__ ' : 6 ,
' comment ' : ' The following requisites were not found: \n '
+ ' require: \n '
+ ' id: Z \n ' ,
' result ' : False ,
' changes ' : False ,
}
}
ret = self . run_function ( ' state.sls ' , mods = ' requisites.require_no_state_module ' )
result = self . normalize_ret ( ret )
self . assertReturnNonEmptySaltType ( ret )
self . assertEqual ( expected_result , result )
2013-11-23 16:39:19 +01:00
def test_requisites_prereq_simple_ordering_and_errors ( self ) :
'''
Call sls file containing several prereq_in and prereq .
Ensure that some of them are failing and that the order is right .
'''
2013-11-27 12:48:53 +00:00
expected_result_simple = {
2013-11-23 16:39:19 +01:00
' cmd_|-A_|-echo A third_|-run ' : {
' __run_num__ ' : 2 ,
2013-12-03 22:54:38 +00:00
' comment ' : ' Command " echo A third " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True } ,
2013-11-23 16:39:19 +01:00
' cmd_|-B_|-echo B first_|-run ' : {
' __run_num__ ' : 0 ,
' comment ' : ' Command " echo B first " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True } ,
2013-11-23 16:39:19 +01:00
' cmd_|-C_|-echo C second_|-run ' : {
' __run_num__ ' : 1 ,
' comment ' : ' Command " echo C second " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True } ,
2013-11-23 16:39:19 +01:00
' cmd_|-I_|-echo I_|-run ' : {
' __run_num__ ' : 3 ,
' comment ' : ' The following requisites were not found: \n '
+ ' prereq: \n '
+ ' cmd: Z \n ' ,
2014-10-30 16:58:03 -07:00
' result ' : False ,
' changes ' : False } ,
2013-11-23 16:39:19 +01:00
' cmd_|-J_|-echo J_|-run ' : {
' __run_num__ ' : 4 ,
' comment ' : ' The following requisites were not found: \n '
+ ' prereq: \n '
+ ' foobar: A \n ' ,
2014-10-30 16:58:03 -07:00
' result ' : False ,
' changes ' : False }
2013-11-23 16:39:19 +01:00
}
2017-11-16 08:44:31 -08:00
expected_result_simple_no_state_module = {
' cmd_|-A_|-echo A third_|-run ' : {
' __run_num__ ' : 2 ,
' comment ' : ' Command " echo A third " run ' ,
' result ' : True ,
' changes ' : True } ,
' cmd_|-B_|-echo B first_|-run ' : {
' __run_num__ ' : 0 ,
' comment ' : ' Command " echo B first " run ' ,
' result ' : True ,
' changes ' : True } ,
' cmd_|-C_|-echo C second_|-run ' : {
' __run_num__ ' : 1 ,
' comment ' : ' Command " echo C second " run ' ,
' result ' : True ,
' changes ' : True } ,
' cmd_|-I_|-echo I_|-run ' : {
' __run_num__ ' : 3 ,
' comment ' : ' The following requisites were not found: \n '
+ ' prereq: \n '
+ ' id: Z \n ' ,
' result ' : False ,
' changes ' : False }
}
2013-11-27 12:48:53 +00:00
expected_result_simple2 = {
2013-11-24 18:30:15 +01:00
' cmd_|-A_|-echo A_|-run ' : {
' __run_num__ ' : 1 ,
2013-12-03 22:54:38 +00:00
' comment ' : ' Command " echo A " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True } ,
2013-11-24 18:30:15 +01:00
' cmd_|-B_|-echo B_|-run ' : {
' __run_num__ ' : 2 ,
' comment ' : ' Command " echo B " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True } ,
2013-11-24 18:30:15 +01:00
' cmd_|-C_|-echo C_|-run ' : {
' __run_num__ ' : 0 ,
' comment ' : ' Command " echo C " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True } ,
2013-11-24 18:30:15 +01:00
' cmd_|-D_|-echo D_|-run ' : {
' __run_num__ ' : 3 ,
' comment ' : ' Command " echo D " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True } ,
2013-11-24 18:30:15 +01:00
' cmd_|-E_|-echo E_|-run ' : {
' __run_num__ ' : 4 ,
' comment ' : ' Command " echo E " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True }
2013-11-24 18:30:15 +01:00
}
2014-10-30 16:18:30 -07:00
expected_result_simple3 = {
' cmd_|-A_|-echo A first_|-run ' : {
' __run_num__ ' : 0 ,
' comment ' : ' Command " echo A first " run ' ,
' result ' : True ,
2014-10-30 16:58:03 -07:00
' changes ' : True ,
2014-10-30 16:18:30 -07:00
} ,
' cmd_|-B_|-echo B second_|-run ' : {
' __run_num__ ' : 1 ,
' comment ' : ' Command " echo B second " run ' ,
' result ' : True ,
2014-10-30 16:58:03 -07:00
' changes ' : True ,
2014-10-30 16:18:30 -07:00
} ,
' cmd_|-C_|-echo C third_|-wait ' : {
' __run_num__ ' : 2 ,
' comment ' : ' ' ,
' result ' : True ,
' changes ' : False ,
}
}
2013-11-27 12:48:53 +00:00
expected_result_complex = {
2013-11-23 16:59:10 +01:00
' cmd_|-A_|-echo A fourth_|-run ' : {
' __run_num__ ' : 3 ,
2013-12-03 22:54:38 +00:00
' comment ' : ' Command " echo A fourth " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True } ,
2013-11-23 16:59:10 +01:00
' cmd_|-B_|-echo B first_|-run ' : {
' __run_num__ ' : 0 ,
' comment ' : ' Command " echo B first " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True } ,
2013-11-23 16:59:10 +01:00
' cmd_|-C_|-echo C second_|-run ' : {
' __run_num__ ' : 1 ,
' comment ' : ' Command " echo C second " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True } ,
2013-11-23 16:59:10 +01:00
' cmd_|-D_|-echo D third_|-run ' : {
' __run_num__ ' : 2 ,
' comment ' : ' Command " echo D third " run ' ,
2014-10-30 16:58:03 -07:00
' result ' : True ,
' changes ' : True } ,
2013-11-23 16:59:10 +01:00
}
2013-11-23 16:39:19 +01:00
ret = self . run_function ( ' state.sls ' , mods = ' requisites.prereq_simple ' )
2014-06-11 01:12:13 +01:00
self . assertReturnNonEmptySaltType ( ret )
2014-10-30 16:58:03 -07:00
result = self . normalize_ret ( ret )
2013-11-23 16:39:19 +01:00
self . assertEqual ( expected_result_simple , result )
2013-11-25 12:46:02 +01:00
# same test, but not using lists in yaml syntax
# TODO: issue #8235, prereq ignored when not used in list syntax
# Currently fails badly with :
# TypeError encountered executing state.sls: string indices must be integers, not str.
#expected_result_simple.pop('cmd_|-I_|-echo I_|-run')
#expected_result_simple.pop('cmd_|-J_|-echo J_|-run')
#ret = self.run_function('state.sls', mods='requisites.prereq_simple_nolist')
2014-10-30 16:58:03 -07:00
#result = self.normalize_ret(ret)
2013-11-25 12:46:02 +01:00
#self.assertEqual(expected_result_simple, result)
2013-11-24 18:30:15 +01:00
ret = self . run_function ( ' state.sls ' , mods = ' requisites.prereq_simple2 ' )
2014-10-30 16:58:03 -07:00
result = self . normalize_ret ( ret )
2014-06-11 01:12:13 +01:00
self . assertReturnNonEmptySaltType ( ret )
2013-11-24 18:30:15 +01:00
self . assertEqual ( expected_result_simple2 , result )
2014-10-30 16:18:30 -07:00
ret = self . run_function ( ' state.sls ' , mods = ' requisites.prereq_simple3 ' )
2014-10-30 16:58:03 -07:00
result = self . normalize_ret ( ret )
2014-10-30 16:18:30 -07:00
self . assertReturnNonEmptySaltType ( ret )
self . assertEqual ( expected_result_simple3 , result )
2013-12-19 14:27:40 -07:00
#ret = self.run_function('state.sls', mods='requisites.prereq_error_nolist')
#self.assertEqual(
# ret,
# ['Cannot extend ID Z in "base:requisites.prereq_error_nolist".'
# + ' It is not part of the high state.']
#)
2013-11-25 12:46:02 +01:00
2013-11-23 16:39:19 +01:00
ret = self . run_function ( ' state.sls ' , mods = ' requisites.prereq_compile_error1 ' )
2014-06-11 01:12:13 +01:00
self . assertReturnNonEmptySaltType ( ret )
2013-11-23 16:39:19 +01:00
self . assertEqual (
ret [ ' cmd_|-B_|-echo B_|-run ' ] [ ' comment ' ] ,
' The following requisites were not found: \n '
+ ' prereq: \n '
+ ' foobar: A \n '
)
ret = self . run_function ( ' state.sls ' , mods = ' requisites.prereq_compile_error2 ' )
2014-06-11 01:12:13 +01:00
self . assertReturnNonEmptySaltType ( ret )
2013-11-23 16:39:19 +01:00
self . assertEqual (
ret [ ' cmd_|-B_|-echo B_|-run ' ] [ ' comment ' ] ,
' The following requisites were not found: \n '
+ ' prereq: \n '
+ ' foobar: C \n '
)
2015-06-17 19:01:18 -07:00
ret = self . run_function ( ' state.sls ' , mods = ' requisites.prereq_complex ' )
result = self . normalize_ret ( ret )
self . assertEqual ( expected_result_complex , result )
2013-11-23 16:59:10 +01:00
2013-11-23 18:20:15 +01:00
# issue #8210 : prereq recursion undetected
# TODO: this test fails
#ret = self.run_function('state.sls', mods='requisites.prereq_recursion_error')
#self.assertEqual(
# ret,
# ['A recursive requisite was found, SLS "requisites.prereq_recursion_error" ID "B" ID "A"']
#)
2017-11-16 08:44:31 -08:00
ret = self . run_function ( ' state.sls ' , mods = ' requisites.prereq_simple_no_state_module ' )
result = self . normalize_ret ( ret )
self . assertEqual ( expected_result_simple_no_state_module , result )
2015-11-19 17:14:51 -08:00
def test_infinite_recursion_sls_prereq ( self ) :
ret = self . run_function ( ' state.sls ' , mods = ' requisites.prereq_sls_infinite_recursion ' )
self . assertSaltTrueReturn ( ret )
2013-11-23 18:20:15 +01:00
2013-11-23 17:26:37 +01:00
def test_requisites_use ( self ) :
'''
Call sls file containing several use_in and use .
'''
# TODO issue #8235 & #8774 some examples are still commented in the test file
ret = self . run_function ( ' state.sls ' , mods = ' requisites.use ' )
2014-06-11 01:12:13 +01:00
self . assertReturnNonEmptySaltType ( ret )
2014-11-21 20:27:56 +00:00
for item , descr in six . iteritems ( ret ) :
2017-10-25 10:55:24 -04:00
self . assertEqual ( descr [ ' comment ' ] , ' onlyif condition is false ' )
2013-11-23 17:26:37 +01:00
2013-11-25 15:35:22 +01:00
# TODO: issue #8802 : use recursions undetected
2013-11-26 10:54:32 +01:00
# issue is closed as use does not actually inherit requisites
# if chain-use is added after #8774 resolution theses tests would maybe become useful
2013-11-25 15:35:22 +01:00
#ret = self.run_function('state.sls', mods='requisites.use_recursion')
#self.assertEqual(ret, [
# 'A recursive requisite was found, SLS "requisites.use_recursion"'
# + ' ID "B" ID "A"'
#])
#ret = self.run_function('state.sls', mods='requisites.use_recursion2')
#self.assertEqual(ret, [
# 'A recursive requisite was found, SLS "requisites.use_recursion2"'
# + ' ID "C" ID "A"'
#])
#ret = self.run_function('state.sls', mods='requisites.use_auto_recursion')
#self.assertEqual(ret, [
# 'A recursive requisite was found, SLS "requisites.use_recursion"'
# + ' ID "A" ID "A"'
#])
2017-11-16 08:44:31 -08:00
def test_requisites_use_no_state_module ( self ) :
'''
Call sls file containing several use_in and use .
'''
ret = self . run_function ( ' state.sls ' , mods = ' requisites.use_no_state_module ' )
self . assertReturnNonEmptySaltType ( ret )
for item , descr in six . iteritems ( ret ) :
2017-11-16 16:02:56 -08:00
self . assertEqual ( descr [ ' comment ' ] , ' onlyif condition is false ' )
2017-11-16 08:44:31 -08:00
2013-11-01 19:36:09 +00:00
def test_get_file_from_env_in_top_match ( self ) :
2017-04-03 17:04:09 +01:00
tgt = os . path . join ( TMP , ' prod-cheese-file ' )
2013-11-01 19:36:09 +00:00
try :
ret = self . run_function (
' state.highstate ' , minion_tgt = ' sub_minion '
)
self . assertSaltTrueReturn ( ret )
2013-11-02 18:31:14 +00:00
self . assertTrue ( os . path . isfile ( tgt ) )
2017-07-18 10:31:01 -06:00
with salt . utils . files . fopen ( tgt , ' r ' ) as cheese :
2013-11-01 19:36:09 +00:00
data = cheese . read ( )
self . assertIn ( ' Gromit ' , data )
self . assertIn ( ' Comte ' , data )
finally :
os . unlink ( tgt )
2015-02-18 17:16:07 -07:00
# onchanges tests
def test_onchanges_requisite ( self ) :
'''
Tests a simple state using the onchanges requisite
'''
2015-02-19 13:06:38 -07:00
# Only run the state once and keep the return data
state_run = self . run_function ( ' state.sls ' , mods = ' requisites.onchanges_simple ' )
# First, test the result of the state run when changes are expected to happen
test_data = state_run [ ' cmd_|-test_changing_state_|-echo " Success! " _|-run ' ] [ ' comment ' ]
expected_result = ' Command " echo " Success! " " run '
self . assertIn ( expected_result , test_data )
# Then, test the result of the state run when changes are not expected to happen
test_data = state_run [ ' cmd_|-test_non_changing_state_|-echo " Should not run " _|-run ' ] [ ' comment ' ]
2015-06-16 15:02:11 +01:00
expected_result = ' State was not run because none of the onchanges reqs changed '
self . assertIn ( expected_result , test_data )
def test_onchanges_requisite_multiple ( self ) :
'''
Tests a simple state using the onchanges requisite
'''
# Only run the state once and keep the return data
state_run = self . run_function ( ' state.sls ' ,
mods = ' requisites.onchanges_multiple ' )
# First, test the result of the state run when two changes are expected to happen
test_data = state_run [ ' cmd_|-test_two_changing_states_|-echo " Success! " _|-run ' ] [ ' comment ' ]
expected_result = ' Command " echo " Success! " " run '
self . assertIn ( expected_result , test_data )
# Then, test the result of the state run when two changes are not expected to happen
test_data = state_run [ ' cmd_|-test_two_non_changing_states_|-echo " Should not run " _|-run ' ] [ ' comment ' ]
expected_result = ' State was not run because none of the onchanges reqs changed '
self . assertIn ( expected_result , test_data )
# Finally, test the result of the state run when only one of the onchanges requisites changes.
test_data = state_run [ ' cmd_|-test_one_changing_state_|-echo " Success! " _|-run ' ] [ ' comment ' ]
expected_result = ' Command " echo " Success! " " run '
2015-02-19 13:06:38 -07:00
self . assertIn ( expected_result , test_data )
def test_onchanges_in_requisite ( self ) :
'''
Tests a simple state using the onchanges_in requisite
'''
# Only run the state once and keep the return data
state_run = self . run_function ( ' state.sls ' , mods = ' requisites.onchanges_in_simple ' )
# First, test the result of the state run of when changes are expected to happen
test_data = state_run [ ' cmd_|-test_changes_expected_|-echo " Success! " _|-run ' ] [ ' comment ' ]
2015-02-18 17:16:07 -07:00
expected_result = ' Command " echo " Success! " " run '
2015-02-19 13:06:38 -07:00
self . assertIn ( expected_result , test_data )
2015-02-18 17:16:07 -07:00
2015-02-19 14:35:26 -07:00
# Then, test the result of the state run when changes are not expected to happen
2015-02-19 13:06:38 -07:00
test_data = state_run [ ' cmd_|-test_changes_not_expected_|-echo " Should not run " _|-run ' ] [ ' comment ' ]
2015-06-16 15:02:11 +01:00
expected_result = ' State was not run because none of the onchanges reqs changed '
2015-02-19 13:06:38 -07:00
self . assertIn ( expected_result , test_data )
2015-02-18 17:16:07 -07:00
2017-11-16 08:44:31 -08:00
def test_onchanges_requisite_no_state_module ( self ) :
'''
Tests a simple state using the onchanges requisite without state modules
'''
# Only run the state once and keep the return data
state_run = self . run_function ( ' state.sls ' , mods = ' requisites.onchanges_simple_no_state_module ' )
test_data = state_run [ ' cmd_|-test_changing_state_|-echo " Success! " _|-run ' ] [ ' comment ' ]
expected_result = ' Command " echo " Success! " " run '
self . assertIn ( expected_result , test_data )
2015-02-19 14:35:26 -07:00
# onfail tests
def test_onfail_requisite ( self ) :
'''
Tests a simple state using the onfail requisite
'''
# Only run the state once and keep the return data
state_run = self . run_function ( ' state.sls ' , mods = ' requisites.onfail_simple ' )
2015-02-19 16:13:23 -07:00
# First, test the result of the state run when a failure is expected to happen
2015-02-19 14:35:26 -07:00
test_data = state_run [ ' cmd_|-test_failing_state_|-echo " Success! " _|-run ' ] [ ' comment ' ]
expected_result = ' Command " echo " Success! " " run '
self . assertIn ( expected_result , test_data )
# Then, test the result of the state run when a failure is not expected to happen
test_data = state_run [ ' cmd_|-test_non_failing_state_|-echo " Should not run " _|-run ' ] [ ' comment ' ]
expected_result = ' State was not run because onfail req did not change '
self . assertIn ( expected_result , test_data )
2016-08-31 20:40:36 -06:00
def test_multiple_onfail_requisite ( self ) :
'''
test to ensure state is run even if only one
of the onfails fails . This is a test for the issue :
https : / / github . com / saltstack / salt / issues / 22370
'''
state_run = self . run_function ( ' state.sls ' , mods = ' requisites.onfail_multiple ' )
retcode = state_run [ ' cmd_|-c_|-echo itworked_|-run ' ] [ ' changes ' ] [ ' retcode ' ]
self . assertEqual ( retcode , 0 )
stdout = state_run [ ' cmd_|-c_|-echo itworked_|-run ' ] [ ' changes ' ] [ ' stdout ' ]
self . assertEqual ( stdout , ' itworked ' )
2015-02-19 14:35:26 -07:00
def test_onfail_in_requisite ( self ) :
'''
Tests a simple state using the onfail_in requisite
'''
# Only run the state once and keep the return data
state_run = self . run_function ( ' state.sls ' , mods = ' requisites.onfail_in_simple ' )
2015-02-19 16:13:23 -07:00
# First, test the result of the state run when a failure is expected to happen
2015-02-19 14:35:26 -07:00
test_data = state_run [ ' cmd_|-test_failing_state_|-echo " Success! " _|-run ' ] [ ' comment ' ]
expected_result = ' Command " echo " Success! " " run '
self . assertIn ( expected_result , test_data )
# Then, test the result of the state run when a failure is not expected to happen
test_data = state_run [ ' cmd_|-test_non_failing_state_|-echo " Should not run " _|-run ' ] [ ' comment ' ]
expected_result = ' State was not run because onfail req did not change '
self . assertIn ( expected_result , test_data )
2017-11-16 08:44:31 -08:00
def test_onfail_requisite_no_state_module ( self ) :
'''
Tests a simple state using the onfail requisite
'''
# Only run the state once and keep the return data
state_run = self . run_function ( ' state.sls ' , mods = ' requisites.onfail_simple_no_state_module ' )
# First, test the result of the state run when a failure is expected to happen
test_data = state_run [ ' cmd_|-test_failing_state_|-echo " Success! " _|-run ' ] [ ' comment ' ]
expected_result = ' Command " echo " Success! " " run '
self . assertIn ( expected_result , test_data )
# Then, test the result of the state run when a failure is not expected to happen
test_data = state_run [ ' cmd_|-test_non_failing_state_|-echo " Should not run " _|-run ' ] [ ' comment ' ]
expected_result = ' State was not run because onfail req did not change '
self . assertIn ( expected_result , test_data )
2015-02-19 16:13:23 -07:00
# listen tests
def test_listen_requisite ( self ) :
'''
Tests a simple state using the listen requisite
'''
# Only run the state once and keep the return data
state_run = self . run_function ( ' state.sls ' , mods = ' requisites.listen_simple ' )
# First, test the result of the state run when a listener is expected to trigger
listener_state = ' cmd_|-listener_test_listening_change_state_|-echo " Listening State " _|-mod_watch '
self . assertIn ( listener_state , state_run )
# Then, test the result of the state run when a listener should not trigger
absent_state = ' cmd_|-listener_test_listening_non_changing_state_|-echo " Only run once " _|-mod_watch '
self . assertNotIn ( absent_state , state_run )
def test_listen_in_requisite ( self ) :
'''
Tests a simple state using the listen_in requisite
'''
# Only run the state once and keep the return data
state_run = self . run_function ( ' state.sls ' , mods = ' requisites.listen_in_simple ' )
# First, test the result of the state run when a listener is expected to trigger
listener_state = ' cmd_|-listener_test_listening_change_state_|-echo " Listening State " _|-mod_watch '
self . assertIn ( listener_state , state_run )
# Then, test the result of the state run when a listener should not trigger
absent_state = ' cmd_|-listener_test_listening_non_changing_state_|-echo " Only run once " _|-mod_watch '
self . assertNotIn ( absent_state , state_run )
2015-12-16 09:19:50 -08:00
def test_listen_in_requisite_resolution ( self ) :
'''
Verify listen_in requisite lookups use ID declaration to check for changes
'''
# Only run the state once and keep the return data
state_run = self . run_function ( ' state.sls ' , mods = ' requisites.listen_in_simple ' )
# Test the result of the state run when a listener is expected to trigger
listener_state = ' cmd_|-listener_test_listen_in_resolution_|-echo " Successful listen_in resolution " _|-mod_watch '
self . assertIn ( listener_state , state_run )
def test_listen_requisite_resolution ( self ) :
'''
Verify listen requisite lookups use ID declaration to check for changes
'''
# Only run the state once and keep the return data
state_run = self . run_function ( ' state.sls ' , mods = ' requisites.listen_simple ' )
# Both listeners are expected to trigger
listener_state = ' cmd_|-listener_test_listening_resolution_one_|-echo " Successful listen resolution " _|-mod_watch '
self . assertIn ( listener_state , state_run )
listener_state = ' cmd_|-listener_test_listening_resolution_two_|-echo " Successful listen resolution " _|-mod_watch '
self . assertIn ( listener_state , state_run )
2012-07-20 12:21:01 +06:00
2017-11-16 08:44:31 -08:00
def test_listen_requisite_no_state_module ( self ) :
'''
Tests a simple state using the listen requisite
'''
# Only run the state once and keep the return data
state_run = self . run_function ( ' state.sls ' , mods = ' requisites.listen_simple_no_state_module ' )
# First, test the result of the state run when a listener is expected to trigger
listener_state = ' cmd_|-listener_test_listening_change_state_|-echo " Listening State " _|-mod_watch '
self . assertIn ( listener_state , state_run )
# Then, test the result of the state run when a listener should not trigger
absent_state = ' cmd_|-listener_test_listening_non_changing_state_|-echo " Only run once " _|-mod_watch '
self . assertNotIn ( absent_state , state_run )
2016-02-02 15:34:19 -06:00
def test_issue_30820_requisite_in_match_by_name ( self ) :
'''
This tests the case where a requisite_in matches by name instead of ID
See https : / / github . com / saltstack / salt / issues / 30820 for more info
'''
state_run = self . run_function (
' state.sls ' ,
mods = ' requisites.requisite_in_match_by_name '
)
bar_state = ' cmd_|-bar state_|-echo bar_|-wait '
self . assertIn ( bar_state , state_run )
self . assertEqual ( state_run [ bar_state ] [ ' comment ' ] ,
' Command " echo bar " run ' )
2016-10-04 20:06:59 +00:00
def test_retry_option_defaults ( self ) :
'''
test the retry option on a simple state with defaults
ensure comment is as expected
ensure state duration is greater than default retry_interval ( 30 seconds )
'''
state_run = self . run_function (
' state.sls ' ,
mods = ' retry.retry_defaults '
)
retry_state = ' file_|-file_test_|-/path/to/a/non-existent/file.txt_|-exists '
expected_comment = ( ' Attempt 1: Returned a result of " False " , with the following '
' comment: " Specified path /path/to/a/non-existent/file.txt does not exist " \n '
' Specified path /path/to/a/non-existent/file.txt does not exist ' )
self . assertEqual ( state_run [ retry_state ] [ ' comment ' ] , expected_comment )
self . assertTrue ( state_run [ retry_state ] [ ' duration ' ] > 30 )
self . assertEqual ( state_run [ retry_state ] [ ' result ' ] , False )
def test_retry_option_custom ( self ) :
'''
test the retry option on a simple state with custom retry values
ensure comment is as expected
ensure state duration is greater than custom defined interval * ( retries - 1 )
'''
state_run = self . run_function (
' state.sls ' ,
mods = ' retry.retry_custom '
)
retry_state = ' file_|-file_test_|-/path/to/a/non-existent/file.txt_|-exists '
expected_comment = ( ' Attempt 1: Returned a result of " False " , with the following '
' comment: " Specified path /path/to/a/non-existent/file.txt does not exist " \n '
' Attempt 2: Returned a result of " False " , with the following comment: " Specified '
' path /path/to/a/non-existent/file.txt does not exist " \n Attempt 3: Returned '
' a result of " False " , with the following comment: " Specified path '
' /path/to/a/non-existent/file.txt does not exist " \n Attempt 4: Returned a '
' result of " False " , with the following comment: " Specified path '
' /path/to/a/non-existent/file.txt does not exist " \n Specified path '
' /path/to/a/non-existent/file.txt does not exist ' )
self . assertEqual ( state_run [ retry_state ] [ ' comment ' ] , expected_comment )
self . assertTrue ( state_run [ retry_state ] [ ' duration ' ] > 40 )
self . assertEqual ( state_run [ retry_state ] [ ' result ' ] , False )
def test_retry_option_success ( self ) :
'''
test a state with the retry option that should return True immedietly ( i . e . no retries )
'''
2017-04-03 17:04:09 +01:00
testfile = os . path . join ( TMP , ' retry_file ' )
2016-10-04 20:06:59 +00:00
state_run = self . run_function (
' state.sls ' ,
mods = ' retry.retry_success '
)
os . unlink ( testfile )
retry_state = ' file_|-file_test_|- {0} _|-exists ' . format ( testfile )
self . assertNotIn ( ' Attempt ' , state_run [ retry_state ] [ ' comment ' ] )
def run_create ( self ) :
'''
helper function to wait 30 seconds and then create the temp retry file
'''
2017-04-03 17:04:09 +01:00
testfile = os . path . join ( TMP , ' retry_file ' )
2016-10-04 20:06:59 +00:00
time . sleep ( 30 )
2017-11-08 12:36:23 -06:00
with salt . utils . files . fopen ( testfile , ' a ' ) :
pass
2016-10-04 20:06:59 +00:00
def test_retry_option_eventual_success ( self ) :
'''
test a state with the retry option that should return True after at least 4 retry attmempt
but never run 15 attempts
'''
2017-04-03 17:04:09 +01:00
testfile = os . path . join ( TMP , ' retry_file ' )
2016-10-04 20:06:59 +00:00
create_thread = threading . Thread ( target = self . run_create )
create_thread . start ( )
state_run = self . run_function (
' state.sls ' ,
mods = ' retry.retry_success2 '
)
retry_state = ' file_|-file_test_|- {0} _|-exists ' . format ( testfile )
self . assertIn ( ' Attempt 1: ' , state_run [ retry_state ] [ ' comment ' ] )
self . assertIn ( ' Attempt 2: ' , state_run [ retry_state ] [ ' comment ' ] )
self . assertIn ( ' Attempt 3: ' , state_run [ retry_state ] [ ' comment ' ] )
self . assertIn ( ' Attempt 4: ' , state_run [ retry_state ] [ ' comment ' ] )
self . assertNotIn ( ' Attempt 15: ' , state_run [ retry_state ] [ ' comment ' ] )
self . assertEqual ( state_run [ retry_state ] [ ' result ' ] , True )
2017-04-05 13:02:14 -06:00
2017-04-03 14:41:54 -06:00
def test_issue_38683_require_order_failhard_combination ( self ) :
'''
This tests the case where require , order , and failhard are all used together in a state definition .
Previously , the order option , which used in tandem with require and failhard , would cause the state
compiler to stacktrace . This exposed a logic error in the ` ` check_failhard ` ` function of the state
compiler . With the logic error resolved , this test should now pass .
See https : / / github . com / saltstack / salt / issues / 38683 for more information .
'''
state_run = self . run_function (
' state.sls ' ,
mods = ' requisites.require_order_failhard_combo '
)
state_id = ' test_|-b_|-b_|-fail_with_changes '
self . assertIn ( state_id , state_run )
self . assertEqual ( state_run [ state_id ] [ ' comment ' ] , ' Failure! ' )
self . assertFalse ( state_run [ state_id ] [ ' result ' ] )
2017-11-20 16:53:56 -05:00
def test_state_nonbase_environment ( self ) :
'''
test state . sls with saltenv using a nonbase environment
with a salt source
'''
state_run = self . run_function (
' state.sls ' ,
mods = ' non-base-env ' ,
saltenv = ' prod '
)
state_id = ' file_|-test_file_|-/tmp/nonbase_env_|-managed '
self . assertEqual ( state_run [ state_id ] [ ' comment ' ] , ' File /tmp/nonbase_env updated ' )
self . assertTrue ( state_run [ ' file_|-test_file_|-/tmp/nonbase_env_|-managed ' ] [ ' result ' ] )
self . assertTrue ( os . path . isfile ( ' /tmp/nonbase_env ' ) )
2017-12-01 18:08:03 -05:00
def _add_runtime_pillar ( self , pillar ) :
'''
helper class to add pillar data at runtime
'''
2017-12-27 22:31:50 -06:00
import salt . utils . yaml
2017-12-01 18:08:03 -05:00
with salt . utils . files . fopen ( os . path . join ( TMP_PILLAR_TREE ,
' pillar.sls ' ) , ' w ' ) as fp :
2017-12-27 22:31:50 -06:00
salt . utils . yaml . safe_dump ( pillar , fp )
2017-12-01 18:08:03 -05:00
with salt . utils . files . fopen ( os . path . join ( TMP_PILLAR_TREE , ' top.sls ' ) , ' w ' ) as fp :
fp . write ( textwrap . dedent ( ''' \
base :
' * ' :
- pillar
''' ))
self . run_function ( ' saltutil.refresh_pillar ' )
self . run_function ( ' test.sleep ' , [ 5 ] )
2017-12-04 13:37:25 -05:00
def test_state_sls_id_test ( self ) :
2017-12-01 18:08:03 -05:00
'''
2017-12-04 13:37:25 -05:00
test state . sls_id when test is set
2017-12-01 18:08:03 -05:00
to true in pillar data
'''
2017-12-04 13:37:25 -05:00
self . _add_runtime_pillar ( pillar = { ' test ' : True } )
2017-12-01 18:08:03 -05:00
ret = self . run_function ( ' state.sls ' , [ ' core ' ] )
for key , val in ret . items ( ) :
self . assertEqual ( val [ ' comment ' ] , ' The file /tmp/salt-tests-tmpdir/testfile is set to be changed ' )
self . assertEqual ( val [ ' changes ' ] , { } )
2017-12-04 13:37:25 -05:00
def test_state_sls_id_test_state_test_post_run ( self ) :
2017-12-01 18:08:03 -05:00
'''
2017-12-04 13:37:25 -05:00
test state . sls_id when test is set to
2017-12-01 18:08:03 -05:00
true post the state already being run previously
'''
ret = self . run_function ( ' state.sls ' , [ ' core ' ] )
for key , val in ret . items ( ) :
self . assertEqual ( val [ ' comment ' ] , ' File /tmp/salt-tests-tmpdir/testfile updated ' )
self . assertEqual ( val [ ' changes ' ] [ ' diff ' ] , ' New file ' )
2017-12-04 13:37:25 -05:00
self . _add_runtime_pillar ( pillar = { ' test ' : True } )
2017-12-01 18:08:03 -05:00
ret = self . run_function ( ' state.sls ' , [ ' core ' ] )
for key , val in ret . items ( ) :
2017-12-04 13:37:25 -05:00
self . assertEqual ( val [ ' comment ' ] , ' The file /tmp/salt-tests-tmpdir/testfile is in the correct state ' )
2017-12-01 18:08:03 -05:00
self . assertEqual ( val [ ' changes ' ] , { } )
def test_state_sls_id_test_true ( self ) :
'''
test state . sls_id when test = True is passed as arg
'''
ret = self . run_function ( ' state.sls ' , [ ' core ' ] , test = True )
for key , val in ret . items ( ) :
self . assertEqual ( val [ ' comment ' ] , ' The file /tmp/salt-tests-tmpdir/testfile is set to be changed ' )
self . assertEqual ( val [ ' changes ' ] , { } )
def test_state_sls_id_test_true_post_run ( self ) :
'''
test state . sls_id when test is set to true as an
arg post the state already being run previously
'''
ret = self . run_function ( ' state.sls ' , [ ' core ' ] )
for key , val in ret . items ( ) :
self . assertEqual ( val [ ' comment ' ] , ' File /tmp/salt-tests-tmpdir/testfile updated ' )
self . assertEqual ( val [ ' changes ' ] [ ' diff ' ] , ' New file ' )
ret = self . run_function ( ' state.sls ' , [ ' core ' ] , test = True )
for key , val in ret . items ( ) :
self . assertEqual ( val [ ' comment ' ] , ' The file /tmp/salt-tests-tmpdir/testfile is in the correct state ' )
self . assertEqual ( val [ ' changes ' ] , { } )
def test_state_sls_id_test_false_pillar_true ( self ) :
'''
test state . sls_id when test is set to false as an
arg and minion_state_test is set to True . Should
return test = False .
'''
2017-12-04 13:37:25 -05:00
self . _add_runtime_pillar ( pillar = { ' test ' : True } )
2017-12-01 18:08:03 -05:00
ret = self . run_function ( ' state.sls ' , [ ' core ' ] , test = False )
for key , val in ret . items ( ) :
self . assertEqual ( val [ ' comment ' ] , ' File /tmp/salt-tests-tmpdir/testfile updated ' )
self . assertEqual ( val [ ' changes ' ] [ ' diff ' ] , ' New file ' )
2017-11-20 16:53:56 -05:00
def tearDown ( self ) :
nonbase_file = ' /tmp/nonbase_env '
if os . path . isfile ( nonbase_file ) :
os . remove ( nonbase_file )
2017-12-01 18:08:03 -05:00
# remove old pillar data
for filename in os . listdir ( TMP_PILLAR_TREE ) :
os . remove ( os . path . join ( TMP_PILLAR_TREE , filename ) )
self . run_function ( ' saltutil.refresh_pillar ' )
self . run_function ( ' test.sleep ' , [ 5 ] )
# remove testfile added in core.sls state file
state_file = os . path . join ( TMP , ' testfile ' )
if os . path . isfile ( state_file ) :
os . remove ( state_file )