2013-11-27 11:19:24 +00:00
# -*- coding: utf-8 -*-
2012-05-05 14:09:23 +00:00
# Import python libs
2014-11-21 19:05:13 +00:00
from __future__ import absolute_import
2012-08-25 23:38:39 +00:00
import os
2012-09-28 15:04:38 +00:00
import shutil
2017-12-24 17:52:20 +00:00
import tempfile
2015-03-02 23:08:49 +00: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 11:45:28 +00:00
# Import Salt Testing libs
2017-04-03 16:04:09 +00:00
from tests . support . case import ModuleCase
2017-02-27 13:58:07 +00:00
from tests . support . unit import skipIf
2018-04-14 22:44:16 +00:00
from tests . support . paths import TMP , FILES
2017-04-02 16:09:47 +00:00
from tests . support . mixins import SaltReturnAssertsMixin
2013-06-27 11:45:28 +00:00
2012-11-18 18:57:10 +00:00
# Import salt libs
2012-11-18 19:06:17 +00:00
import salt . utils
2014-01-11 19:19:29 +00:00
from salt . modules . virtualenv_mod import KNOWN_BINARY_NAMES
2012-05-05 14:09:23 +00:00
2014-11-21 20:27:56 +00:00
# Import 3rd-party libs
import salt . ext . six as six
2012-03-29 23:18:32 +00:00
2018-04-14 22:44:16 +00:00
DEFAULT_ENDING = salt . utils . to_bytes ( os . linesep )
def trim_line_end ( line ) :
'''
Remove CRLF or LF from the end of line .
'''
if line [ - 2 : ] == salt . utils . to_bytes ( ' \r \n ' ) :
return line [ : - 2 ]
2018-04-15 00:39:29 +00:00
elif line [ - 1 : ] == salt . utils . to_bytes ( ' \n ' ) :
2018-04-14 22:44:16 +00:00
return line [ : - 1 ]
raise Exception ( " Invalid line ending " )
def reline ( source , dest , force = False , ending = DEFAULT_ENDING ) :
'''
Normalize the line endings of a file .
'''
fp , tmp = tempfile . mkstemp ( )
os . close ( fp )
with salt . utils . fopen ( tmp , ' wb ' ) as tmp_fd :
with salt . utils . fopen ( source , ' rb ' ) as fd :
lines = fd . readlines ( )
for line in lines :
line_noend = trim_line_end ( line )
tmp_fd . write ( line_noend + ending )
if os . path . exists ( dest ) and force :
os . remove ( dest )
os . rename ( tmp , dest )
2017-04-03 16:04:09 +00:00
class StateModuleTest ( ModuleCase , SaltReturnAssertsMixin ) :
2012-03-29 23:18:32 +00:00
'''
2015-03-02 23:08:49 +00:00
Validate the state module
2012-03-29 23:18:32 +00:00
'''
2012-09-01 06:49:34 +00:00
maxDiff = None
2018-04-14 22:44:16 +00:00
def setUp ( self ) :
super ( StateModuleTest , self ) . setUp ( )
destpath = os . path . join ( FILES , ' file ' , ' base ' , ' testappend ' , ' firstif ' )
reline ( destpath , destpath , force = True )
destpath = os . path . join ( FILES , ' file ' , ' base ' , ' testappend ' , ' secondif ' )
reline ( destpath , destpath , force = True )
2012-03-29 23:18:32 +00:00
def test_show_highstate ( self ) :
'''
state . show_highstate
'''
high = self . run_function ( ' state.show_highstate ' )
2017-04-03 16:04:09 +00:00
destpath = os . path . join ( TMP , ' testfile ' )
2012-03-29 23:18:32 +00: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 23:18:32 +00: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-14 03:31:46 +00: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-14 05:16:45 +00:00
self . assertIn ( ' recursive ' , err [ 0 ] )
2012-05-14 03:31:46 +00:00
2012-06-16 04:41:36 +00:00
def test_no_recurse ( self ) :
'''
2012-06-19 16:29:14 +00:00
verify that a sls structure is NOT a recursive ref
2012-06-16 04:41:36 +00:00
'''
sls = self . run_function ( ' state.show_sls ' , mods = ' recurse_ok ' )
self . assertIn ( ' snmpd ' , sls )
2012-06-19 16:29:14 +00: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 20:42:16 +00: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 21:07:03 +00: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 09:07:47 +00:00
self . assertTrue ( isinstance ( ret [ ' __sls__ ' ] , type ( None ) ) )
2016-12-05 21:07:03 +00:00
for state , ret in sls2 . items ( ) :
2016-12-08 09:07:47 +00:00
self . assertTrue ( isinstance ( ret [ ' __sls__ ' ] , str ) )
2016-12-05 21:07:03 +00:00
2015-02-17 20:10:21 +00:00
def _remove_request_cache_file ( self ) :
'''
remove minion state request file
'''
2017-04-02 15:56:17 +00:00
cache_file = os . path . join ( self . get_config ( ' minion ' ) [ ' cachedir ' ] , ' req_state.p ' )
2015-02-17 20:10:21 +00: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 23:15:26 +00:00
result = ret [ ' cmd_|-count_root_dir_contents_|-ls -a / | wc -l_|-run ' ] [ ' result ' ]
self . assertEqual ( result , None )
2015-02-17 20:10:21 +00: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 23:15:26 +00:00
self . assertEqual ( result , None )
2015-02-17 20:10:21 +00: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 ( )
2016-07-27 22:17:36 +00:00
if salt . utils . is_windows ( ) :
self . run_function ( ' state.request ' , mods = ' modules.state.requested_win ' )
else :
self . run_function ( ' state.request ' , mods = ' modules.state.requested ' )
2015-02-17 20:10:21 +00:00
ret = self . run_function ( ' state.run_request ' )
2016-07-27 22:17:36 +00:00
if salt . utils . is_windows ( ) :
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 20:10:21 +00: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 06:49:34 +00:00
def test_issue_1896_file_append_source ( self ) :
'''
Verify that we can append a file ' s contents
'''
2017-04-03 16:04:09 +00: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
2016-08-11 16:45:24 +00:00
with salt . utils . fopen ( testfile , ' r ' ) as fp_ :
2016-08-12 22:21:58 +00:00
testfile_contents = fp_ . read ( )
2016-07-27 22:17:36 +00:00
contents = textwrap . dedent ( ''' \
2015-03-02 23:08:49 +00: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 16:48:09 +00:00
fi
2016-07-28 16:33:23 +00:00
2015-03-02 23:08:49 +00:00
# enable bash completion in interactive shells
if [ - f / etc / bash_completion ] & & ! shopt - oq posix ; then
. / etc / bash_completion
fi
2016-07-27 22:17:36 +00:00
''' )
if salt . utils . is_windows ( ) :
new_contents = contents . splitlines ( )
contents = os . linesep . join ( new_contents )
contents + = os . linesep
self . assertMultiLineEqual (
2016-08-12 22:21:58 +00:00
contents , testfile_contents )
2012-09-01 06:49:34 +00: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
2016-08-11 16:45:24 +00:00
with salt . utils . fopen ( testfile , ' r ' ) as fp_ :
2016-08-12 22:21:58 +00:00
testfile_contents = fp_ . read ( )
2012-09-03 15:40:52 +00:00
2016-08-12 22:21:58 +00:00
self . assertMultiLineEqual ( contents , testfile_contents )
2012-09-01 06:49:34 +00:00
2012-08-25 13:44:07 +00: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 16:04:09 +00:00
testfile = os . path . join ( TMP , ' issue-1876 ' )
2012-08-25 13:44:07 +00:00
sls = self . run_function ( ' state.sls ' , mods = ' issue-1876 ' )
self . assertIn (
2015-08-27 04:26:08 +00:00
' ID \' {0} \' in SLS \' issue-1876 \' contains multiple state '
2014-04-22 01:07:06 +00:00
' declarations of the same type ' . format ( testfile ) ,
2012-11-06 11:20:06 +00:00
sls
2012-08-25 13:44:07 +00:00
)
2012-08-25 23:38:39 +00:00
def test_issue_1879_too_simple_contains_check ( self ) :
2016-08-11 16:45:24 +00:00
expected = textwrap . dedent ( ''' \
2015-03-02 23:08:49 +00: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 22:17:36 +00:00
if salt . utils . is_windows ( ) :
2016-08-12 23:06:27 +00:00
new_contents = expected . splitlines ( )
expected = os . linesep . join ( new_contents )
expected + = os . linesep
2016-07-27 22:17:36 +00:00
2017-04-03 16:04:09 +00: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 09:03:11 +00: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 09:03:11 +00: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 09:03:11 +00:00
# Does it match?
try :
2016-08-11 16:45:24 +00:00
with salt . utils . fopen ( testfile , ' r ' ) as fp_ :
contents = fp_ . read ( )
self . assertMultiLineEqual ( expected , contents )
2012-08-28 09:03:11 +00: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 16:45:24 +00:00
with salt . utils . fopen ( testfile , ' r ' ) as fp_ :
contents = fp_ . read ( )
self . assertMultiLineEqual ( expected , contents )
2012-08-28 09:03:11 +00:00
except Exception :
2012-11-06 11:20:06 +00:00
if os . path . exists ( testfile ) :
shutil . copy ( testfile , testfile + ' .bak ' )
2012-08-28 09:03:11 +00:00
raise
finally :
2012-11-06 11:20:06 +00:00
if os . path . exists ( testfile ) :
os . unlink ( testfile )
2012-08-25 23:38:39 +00:00
2012-09-28 00:17:37 +00:00
def test_include ( self ) :
2017-12-24 17:52:20 +00: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 00:17:37 +00:00
def test_exclude ( self ) :
2017-12-24 17:52:20 +00: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 19:06:49 +00:00
2014-01-11 19:19:29 +00:00
@skipIf ( salt . utils . which_bin ( KNOWN_BINARY_NAMES ) is None , ' virtualenv not installed ' )
2012-09-28 15:04:38 +00:00
def test_issue_2068_template_str ( self ) :
2012-11-06 12:44:53 +00:00
venv_dir = os . path . join (
2017-04-03 16:04:09 +00:00
TMP , ' issue-2068-template-str '
2012-11-06 12:44:53 +00:00
)
2012-09-28 00:17:37 +00:00
2012-09-28 15:04:38 +00: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 15:04:38 +00:00
)
2012-12-07 18:44:06 +00:00
self . assertSaltTrueReturn ( ret )
2012-09-28 15:04:38 +00: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 '
)
2016-08-11 16:45:24 +00:00
with salt . utils . fopen ( template_path , ' r ' ) as fp_ :
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 15:04:38 +00:00
2012-09-28 16:34:55 +00:00
# Now using state.template
2016-09-29 03:35:02 +00:00
ret = self . run_function (
' state.template ' , [ template_path ] , timeout = 120
)
self . assertSaltTrueReturn ( ret )
2012-09-28 16:34:55 +00:00
2012-09-28 15:04:38 +00:00
# Now the problematic #2068 including dot's
2016-09-29 03:35:02 +00:00
ret = self . run_function (
' state.sls ' , mods = ' issue-2068-template-str ' , timeout = 120
)
self . assertSaltTrueReturn ( ret )
2012-09-28 15:04:38 +00: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 '
)
2016-08-11 16:45:24 +00:00
with salt . utils . fopen ( template_path , ' r ' ) as fp_ :
template = fp_ . read ( )
2016-09-29 03:35:02 +00:00
ret = self . run_function (
' state.template_str ' , [ template ] , timeout = 120
)
self . assertSaltTrueReturn ( ret )
2012-08-25 23:38:39 +00:00
2012-09-28 16:34:55 +00:00
# Now using state.template
2016-09-29 03:35:02 +00:00
ret = self . run_function (
' state.template ' , [ template_path ] , timeout = 120
)
self . assertSaltTrueReturn ( ret )
2012-09-28 16:34:55 +00:00
2012-09-28 16:56:13 +00:00
def test_template_invalid_items ( self ) :
2015-03-02 23:08:49 +00:00
TEMPLATE = textwrap . dedent ( ''' \
{ 0 } :
- issue - 2068 - template - str
/ tmp / test - template - invalid - items :
file :
- managed
- source : salt : / / testfile
''' )
2012-09-28 16:56:13 +00: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-22 01:07:06 +00: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-22 01:36:23 +00:00
' State \' C \' in SLS \' syntax.badlist2 \' is not formed as a list '
2013-10-31 16:42:59 +00:00
] )
2013-11-24 17:28:22 +00: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 17:28:22 +00:00
' cmd_|-A_|-echo A_|-run ' : {
' __run_num__ ' : 2 ,
' comment ' : ' Command " echo A " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True } ,
2013-11-24 17:28:22 +00:00
' cmd_|-B_|-echo B_|-run ' : {
' __run_num__ ' : 1 ,
' comment ' : ' Command " echo B " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True } ,
2013-11-24 17:28:22 +00:00
' cmd_|-C_|-echo C_|-run ' : {
' __run_num__ ' : 0 ,
' comment ' : ' Command " echo C " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True }
2013-11-24 17:28:22 +00:00
}
2013-11-27 12:48:53 +00:00
expected_result = {
2013-11-24 17:28:22 +00:00
' cmd_|-A_|-echo A fifth_|-run ' : {
' __run_num__ ' : 4 ,
' comment ' : ' Command " echo A fifth " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True } ,
2013-11-24 17:28:22 +00:00
' cmd_|-B_|-echo B third_|-run ' : {
' __run_num__ ' : 2 ,
' comment ' : ' Command " echo B third " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True } ,
2013-11-24 17:28:22 +00:00
' cmd_|-C_|-echo C second_|-run ' : {
' __run_num__ ' : 1 ,
' comment ' : ' Command " echo C second " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True } ,
2013-11-24 17:28:22 +00:00
' cmd_|-D_|-echo D first_|-run ' : {
' __run_num__ ' : 0 ,
' comment ' : ' Command " echo D first " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True } ,
2013-11-24 17:28:22 +00:00
' cmd_|-E_|-echo E fourth_|-run ' : {
' __run_num__ ' : 3 ,
' comment ' : ' Command " echo E fourth " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True }
2013-11-24 17:28:22 +00:00
}
2013-11-27 12:48:53 +00:00
expected_req_use_result = {
2013-11-25 10:06:37 +00:00
' cmd_|-A_|-echo A_|-run ' : {
' __run_num__ ' : 1 ,
' comment ' : ' Command " echo A " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True } ,
2013-11-25 10:06:37 +00:00
' cmd_|-B_|-echo B_|-run ' : {
' __run_num__ ' : 4 ,
' comment ' : ' Command " echo B " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True } ,
2013-11-25 10:06:37 +00:00
' cmd_|-C_|-echo C_|-run ' : {
' __run_num__ ' : 0 ,
' comment ' : ' Command " echo C " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True } ,
2013-11-25 10:06:37 +00:00
' cmd_|-D_|-echo D_|-run ' : {
' __run_num__ ' : 5 ,
' comment ' : ' Command " echo D " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True } ,
2013-11-25 10:06:37 +00:00
' cmd_|-E_|-echo E_|-run ' : {
' __run_num__ ' : 2 ,
' comment ' : ' Command " echo E " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True } ,
2013-11-25 10:06:37 +00:00
' cmd_|-F_|-echo F_|-run ' : {
' __run_num__ ' : 3 ,
' comment ' : ' Command " echo F " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True }
2013-11-25 10:06:37 +00:00
}
2013-11-24 17:28:22 +00:00
ret = self . run_function ( ' state.sls ' , mods = ' requisites.mixed_simple ' )
2014-10-30 23:58:03 +00:00
result = self . normalize_ret ( ret )
2014-06-11 00:12:13 +00:00
self . assertReturnNonEmptySaltType ( ret )
2013-11-24 17:28:22 +00: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 23:58:03 +00:00
#result = self.normalize_ret(ret)
2013-11-24 17:28:22 +00:00
#self.assertEqual(expected_result, result)
2017-11-16 17:18:30 +00: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 16:19:25 +00: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 17:18:30 +00:00
2017-11-20 16:19:25 +00:00
self . assertEqual ( ' Watch statement fired. ' , ret [ watch ] [ ' comment ' ] )
2017-11-16 17:18:30 +00:00
self . assertEqual ( ' Something pretended to change ' ,
2017-11-20 16:19:25 +00:00
ret [ changes ] [ ' changes ' ] [ ' testing ' ] [ ' new ' ] )
2017-11-16 17:18:30 +00: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 16:32:26 +00:00
fail = ' test_|-return_changes_|-return_changes_|-fail_with_changes '
watch = ' test_|-watch_states_|-watch_states_|-succeed_without_changes '
2017-11-16 17:18:30 +00:00
2017-11-20 16:32:26 +00:00
self . assertEqual ( False , ret [ fail ] [ ' result ' ] )
2017-11-16 17:18:30 +00:00
self . assertEqual ( ' One or more requisite failed: requisites.watch_in_failure.return_changes ' ,
2017-11-20 16:32:26 +00:00
ret [ watch ] [ ' comment ' ] )
2017-11-16 17:18:30 +00:00
2014-10-30 23:58:03 +00: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 23:58:03 +00: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 15:37:57 +00: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 15:37:57 +00:00
' cmd_|-A_|-echo A fifth_|-run ' : {
' __run_num__ ' : 4 ,
' comment ' : ' Command " echo A fifth " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True ,
2013-12-06 20:44:48 +00:00
} ,
2013-11-23 15:37:57 +00:00
' cmd_|-B_|-echo B second_|-run ' : {
' __run_num__ ' : 1 ,
' comment ' : ' Command " echo B second " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True ,
2013-12-06 20:44:48 +00:00
} ,
2013-11-23 15:37:57 +00:00
' cmd_|-C_|-echo C third_|-run ' : {
' __run_num__ ' : 2 ,
' comment ' : ' Command " echo C third " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True ,
2013-12-06 20:44:48 +00:00
} ,
2013-11-23 15:37:57 +00:00
' cmd_|-D_|-echo D first_|-run ' : {
' __run_num__ ' : 0 ,
' comment ' : ' Command " echo D first " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True ,
2013-12-06 20:44:48 +00:00
} ,
2013-11-23 15:37:57 +00:00
' cmd_|-E_|-echo E fourth_|-run ' : {
' __run_num__ ' : 3 ,
' comment ' : ' Command " echo E fourth " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True ,
2013-12-06 20:44:48 +00:00
} ,
2013-11-23 15:37:57 +00: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 23:58:03 +00:00
' result ' : False ,
' changes ' : False ,
2013-12-06 20:44:48 +00:00
} ,
2013-11-23 15:37:57 +00: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 23:58:03 +00:00
' result ' : False ,
' changes ' : False ,
2013-12-06 20:44:48 +00:00
} ,
2013-11-26 10:57:09 +00:00
' cmd_|-H_|-echo H_|-run ' : {
' __run_num__ ' : 7 ,
2013-11-23 15:37:57 +00:00
' comment ' : ' The following requisites were not found: \n '
+ ' require: \n '
+ ' cmd: Z \n ' ,
2014-10-30 23:58:03 +00:00
' result ' : False ,
' changes ' : False ,
2013-12-06 20:44:48 +00:00
}
2013-11-23 15:37:57 +00:00
}
ret = self . run_function ( ' state.sls ' , mods = ' requisites.require ' )
2014-10-30 23:58:03 +00:00
result = self . normalize_ret ( ret )
2014-06-11 00:12:13 +00:00
self . assertReturnNonEmptySaltType ( ret )
2013-11-23 15:37:57 +00:00
self . assertEqual ( expected_result , result )
2013-11-25 11:58:59 +00:00
2013-11-23 15:37:57 +00:00
ret = self . run_function ( ' state.sls ' , mods = ' requisites.require_error1 ' )
self . assertEqual ( ret , [
2014-05-14 22:09:27 +00: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 15:37:57 +00:00
] )
2013-11-23 17:20:15 +00:00
2013-11-25 11:58:59 +00: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 11:58:59 +00:00
ret = self . run_function ( ' state.sls ' , mods = ' requisites.require_simple_nolist ' )
self . assertEqual ( ret , [
2014-04-22 01:07:06 +00:00
' The require statement in state \' B \' in SLS '
+ ' \' requisites.require_simple_nolist \' needs to be formed as a list '
2013-11-25 11:58:59 +00:00
] )
2013-11-23 15:37:57 +00:00
# commented until a fix is made for issue #8772
2013-11-23 17:20:15 +00:00
# TODO: this test actually fails
2013-11-23 15:37:57 +00: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 17:20:15 +00: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 " ' ]
)
2013-11-23 17:56:07 +00: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 17:56:07 +00:00
' cmd_|-A_|-echo A_|-run ' : {
' __run_num__ ' : 2 ,
' comment ' : ' Command " echo A " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True } ,
2013-11-23 17:56:07 +00:00
' cmd_|-B_|-echo B_|-run ' : {
' __run_num__ ' : 0 ,
' comment ' : ' Command " echo B " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True } ,
2013-11-23 17:56:07 +00:00
' cmd_|-C_|-echo C_|-run ' : {
' __run_num__ ' : 1 ,
' comment ' : ' Command " echo C " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True } ,
2013-11-23 17:56:07 +00:00
}
ret = self . run_function ( ' state.sls ' , mods = ' requisites.fullsls_require ' )
2014-06-11 00:12:13 +00:00
self . assertReturnNonEmptySaltType ( ret )
2014-10-30 23:58:03 +00:00
result = self . normalize_ret ( ret )
2013-11-23 17:56:07 +00:00
self . assertEqual ( expected_result , result )
2013-11-25 11:58:59 +00:00
2013-11-23 17:56:07 +00: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)
2013-11-23 15:39:19 +00: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 15:39:19 +00: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 23:58:03 +00:00
' result ' : True ,
' changes ' : True } ,
2013-11-23 15:39:19 +00:00
' cmd_|-B_|-echo B first_|-run ' : {
' __run_num__ ' : 0 ,
' comment ' : ' Command " echo B first " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True } ,
2013-11-23 15:39:19 +00:00
' cmd_|-C_|-echo C second_|-run ' : {
' __run_num__ ' : 1 ,
' comment ' : ' Command " echo C second " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True } ,
2013-11-23 15:39:19 +00: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 23:58:03 +00:00
' result ' : False ,
' changes ' : False } ,
2013-11-23 15:39:19 +00: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 23:58:03 +00:00
' result ' : False ,
' changes ' : False }
2013-11-23 15:39:19 +00:00
}
2013-11-27 12:48:53 +00:00
expected_result_simple2 = {
2013-11-24 17:30:15 +00: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 23:58:03 +00:00
' result ' : True ,
' changes ' : True } ,
2013-11-24 17:30:15 +00:00
' cmd_|-B_|-echo B_|-run ' : {
' __run_num__ ' : 2 ,
' comment ' : ' Command " echo B " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True } ,
2013-11-24 17:30:15 +00:00
' cmd_|-C_|-echo C_|-run ' : {
' __run_num__ ' : 0 ,
' comment ' : ' Command " echo C " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True } ,
2013-11-24 17:30:15 +00:00
' cmd_|-D_|-echo D_|-run ' : {
' __run_num__ ' : 3 ,
' comment ' : ' Command " echo D " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True } ,
2013-11-24 17:30:15 +00:00
' cmd_|-E_|-echo E_|-run ' : {
' __run_num__ ' : 4 ,
' comment ' : ' Command " echo E " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True }
2013-11-24 17:30:15 +00:00
}
2014-10-30 23:18:30 +00:00
expected_result_simple3 = {
' cmd_|-A_|-echo A first_|-run ' : {
' __run_num__ ' : 0 ,
' comment ' : ' Command " echo A first " run ' ,
' result ' : True ,
2014-10-30 23:58:03 +00:00
' changes ' : True ,
2014-10-30 23:18:30 +00:00
} ,
' cmd_|-B_|-echo B second_|-run ' : {
' __run_num__ ' : 1 ,
' comment ' : ' Command " echo B second " run ' ,
' result ' : True ,
2014-10-30 23:58:03 +00:00
' changes ' : True ,
2014-10-30 23:18:30 +00: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 15:59:10 +00: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 23:58:03 +00:00
' result ' : True ,
' changes ' : True } ,
2013-11-23 15:59:10 +00:00
' cmd_|-B_|-echo B first_|-run ' : {
' __run_num__ ' : 0 ,
' comment ' : ' Command " echo B first " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True } ,
2013-11-23 15:59:10 +00:00
' cmd_|-C_|-echo C second_|-run ' : {
' __run_num__ ' : 1 ,
' comment ' : ' Command " echo C second " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True } ,
2013-11-23 15:59:10 +00:00
' cmd_|-D_|-echo D third_|-run ' : {
' __run_num__ ' : 2 ,
' comment ' : ' Command " echo D third " run ' ,
2014-10-30 23:58:03 +00:00
' result ' : True ,
' changes ' : True } ,
2013-11-23 15:59:10 +00:00
}
2013-11-23 15:39:19 +00:00
ret = self . run_function ( ' state.sls ' , mods = ' requisites.prereq_simple ' )
2014-06-11 00:12:13 +00:00
self . assertReturnNonEmptySaltType ( ret )
2014-10-30 23:58:03 +00:00
result = self . normalize_ret ( ret )
2013-11-23 15:39:19 +00:00
self . assertEqual ( expected_result_simple , result )
2013-11-25 11:46:02 +00: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 23:58:03 +00:00
#result = self.normalize_ret(ret)
2013-11-25 11:46:02 +00:00
#self.assertEqual(expected_result_simple, result)
2013-11-24 17:30:15 +00:00
ret = self . run_function ( ' state.sls ' , mods = ' requisites.prereq_simple2 ' )
2014-10-30 23:58:03 +00:00
result = self . normalize_ret ( ret )
2014-06-11 00:12:13 +00:00
self . assertReturnNonEmptySaltType ( ret )
2013-11-24 17:30:15 +00:00
self . assertEqual ( expected_result_simple2 , result )
2014-10-30 23:18:30 +00:00
ret = self . run_function ( ' state.sls ' , mods = ' requisites.prereq_simple3 ' )
2014-10-30 23:58:03 +00:00
result = self . normalize_ret ( ret )
2014-10-30 23:18:30 +00:00
self . assertReturnNonEmptySaltType ( ret )
self . assertEqual ( expected_result_simple3 , result )
2013-12-19 21:27:40 +00: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 11:46:02 +00:00
2013-11-23 15:39:19 +00:00
ret = self . run_function ( ' state.sls ' , mods = ' requisites.prereq_compile_error1 ' )
2014-06-11 00:12:13 +00:00
self . assertReturnNonEmptySaltType ( ret )
2013-11-23 15:39:19 +00: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 00:12:13 +00:00
self . assertReturnNonEmptySaltType ( ret )
2013-11-23 15:39:19 +00:00
self . assertEqual (
ret [ ' cmd_|-B_|-echo B_|-run ' ] [ ' comment ' ] ,
' The following requisites were not found: \n '
+ ' prereq: \n '
+ ' foobar: C \n '
)
2015-06-18 02:01:18 +00: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 15:59:10 +00:00
2013-11-23 17:20:15 +00: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"']
#)
2015-11-20 01:14:51 +00: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 17:20:15 +00:00
2013-11-23 16:26:37 +00: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 00:12:13 +00:00
self . assertReturnNonEmptySaltType ( ret )
2014-11-21 20:27:56 +00:00
for item , descr in six . iteritems ( ret ) :
2013-11-23 16:26:37 +00:00
self . assertEqual ( descr [ ' comment ' ] , ' onlyif execution failed ' )
2013-11-25 14:35:22 +00:00
# TODO: issue #8802 : use recursions undetected
2013-11-26 09:54:32 +00: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 14:35:22 +00: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"'
#])
2013-11-01 19:36:09 +00:00
def test_get_file_from_env_in_top_match ( self ) :
2017-04-03 16:04:09 +00: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 ) )
2013-11-01 19:36:09 +00:00
with salt . utils . fopen ( tgt , ' r ' ) as cheese :
data = cheese . read ( )
self . assertIn ( ' Gromit ' , data )
self . assertIn ( ' Comte ' , data )
finally :
2018-01-10 18:16:59 +00:00
if os . path . islink ( tgt ) :
os . unlink ( tgt )
2013-11-01 19:36:09 +00:00
2015-02-19 00:16:07 +00:00
# onchanges tests
def test_onchanges_requisite ( self ) :
'''
Tests a simple state using the onchanges requisite
'''
2015-02-19 20:06:38 +00: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 14:02:11 +00: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 20:06:38 +00: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-19 00:16:07 +00:00
expected_result = ' Command " echo " Success! " " run '
2015-02-19 20:06:38 +00:00
self . assertIn ( expected_result , test_data )
2015-02-19 00:16:07 +00:00
2015-02-19 21:35:26 +00:00
# Then, test the result of the state run when changes are not expected to happen
2015-02-19 20:06:38 +00:00
test_data = state_run [ ' cmd_|-test_changes_not_expected_|-echo " Should not run " _|-run ' ] [ ' comment ' ]
2015-06-16 14:02:11 +00:00
expected_result = ' State was not run because none of the onchanges reqs changed '
2015-02-19 20:06:38 +00:00
self . assertIn ( expected_result , test_data )
2015-02-19 00:16:07 +00:00
2018-01-26 20:04:04 +00:00
def test_onchanges_requisite_with_duration ( self ) :
'''
Tests a simple state using the onchanges requisite
the state will not run but results will include duration
'''
# Only run the state once and keep the return data
state_run = self . run_function ( ' state.sls ' , mods = ' requisites.onchanges_simple ' )
# Then, test the result of the state run when changes are not expected to happen
# and ensure duration is included in the results
test_data = state_run [ ' cmd_|-test_non_changing_state_|-echo " Should not run " _|-run ' ]
self . assertIn ( ' duration ' , test_data )
2015-02-19 21:35:26 +00: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 23:13:23 +00:00
# First, test the result of the state run when a failure is expected to happen
2015-02-19 21:35:26 +00: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-09-01 02:40:36 +00: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 21:35:26 +00: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 23:13:23 +00:00
# First, test the result of the state run when a failure is expected to happen
2015-02-19 21:35:26 +00: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 )
2018-01-26 20:04:04 +00:00
def test_onfail_requisite_with_duration ( 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 ' )
# 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 ' ]
self . assertIn ( ' duration ' , test_data )
2018-03-16 00:45:42 +00:00
def test_multiple_onfail_requisite_with_required ( self ) :
'''
test to ensure multiple states are run
when specified as onfails for a single state .
This is a test for the issue :
https : / / github . com / saltstack / salt / issues / 46552
'''
state_run = self . run_function ( ' state.sls ' , mods = ' requisites.onfail_multiple_required ' )
retcode = state_run [ ' cmd_|-b_|-echo b_|-run ' ] [ ' changes ' ] [ ' retcode ' ]
self . assertEqual ( retcode , 0 )
retcode = state_run [ ' cmd_|-c_|-echo c_|-run ' ] [ ' changes ' ] [ ' retcode ' ]
self . assertEqual ( retcode , 0 )
retcode = state_run [ ' cmd_|-d_|-echo d_|-run ' ] [ ' changes ' ] [ ' retcode ' ]
self . assertEqual ( retcode , 0 )
stdout = state_run [ ' cmd_|-b_|-echo b_|-run ' ] [ ' changes ' ] [ ' stdout ' ]
self . assertEqual ( stdout , ' b ' )
stdout = state_run [ ' cmd_|-c_|-echo c_|-run ' ] [ ' changes ' ] [ ' stdout ' ]
self . assertEqual ( stdout , ' c ' )
stdout = state_run [ ' cmd_|-d_|-echo d_|-run ' ] [ ' changes ' ] [ ' stdout ' ]
self . assertEqual ( stdout , ' d ' )
def test_multiple_onfail_requisite_with_required_no_run ( self ) :
'''
test to ensure multiple states are not run
when specified as onfails for a single state
which fails .
This is a test for the issue :
https : / / github . com / saltstack / salt / issues / 46552
'''
state_run = self . run_function ( ' state.sls ' , mods = ' requisites.onfail_multiple_required_no_run ' )
expected = ' State was not run because onfail req did not change '
stdout = state_run [ ' cmd_|-b_|-echo b_|-run ' ] [ ' comment ' ]
self . assertEqual ( stdout , expected )
stdout = state_run [ ' cmd_|-c_|-echo c_|-run ' ] [ ' comment ' ]
self . assertEqual ( stdout , expected )
stdout = state_run [ ' cmd_|-d_|-echo d_|-run ' ] [ ' comment ' ]
self . assertEqual ( stdout , expected )
2015-02-19 23:13:23 +00: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 17:19:50 +00: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 06:21:01 +00:00
2018-03-05 18:36:38 +00:00
def test_listen_in_requisite_resolution_names ( self ) :
'''
Verify listen_in requisite lookups use ID declaration to check for changes
and resolves magic names state variable
'''
# Only run the state once and keep the return data
state_run = self . run_function ( ' state.sls ' , mods = ' requisites.listen_in_names ' )
self . assertIn ( ' test_|-listener_service_|-nginx_|-mod_watch ' , state_run )
self . assertIn ( ' test_|-listener_service_|-crond_|-mod_watch ' , state_run )
def test_listen_requisite_resolution_names ( self ) :
'''
Verify listen requisite lookups use ID declaration to check for changes
and resolves magic names state variable
'''
# Only run the state once and keep the return data
state_run = self . run_function ( ' state.sls ' , mods = ' requisites.listen_names ' )
self . assertIn ( ' test_|-listener_service_|-nginx_|-mod_watch ' , state_run )
self . assertIn ( ' test_|-listener_service_|-crond_|-mod_watch ' , state_run )
2016-02-02 21:34:19 +00: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 16:04:09 +00: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 16:04:09 +00:00
testfile = os . path . join ( TMP , ' retry_file ' )
2016-10-04 20:06:59 +00:00
time . sleep ( 30 )
2017-04-04 12:11:54 +00:00
open ( testfile , ' a ' ) . close ( ) # pylint: disable=resource-leakage
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 16:04:09 +00: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 19:02:14 +00:00
2017-04-03 20:41:54 +00: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 21:53:56 +00:00
2018-03-30 21:40:20 +00:00
def test_issue_46762_prereqs_on_a_state_with_unfulfilled_requirements ( self ) :
'''
2018-04-03 19:36:17 +00:00
This tests the case where state C requires state A , which fails .
State C is a pre - required state for State B .
Since state A fails , state C will not run because the requisite failed ,
therefore state B will not run because state C failed to run .
2018-03-30 21:40:20 +00:00
2018-03-30 21:47:47 +00:00
See https : / / github . com / saltstack / salt / issues / 46762 for
more information .
2018-03-30 21:40:20 +00:00
'''
state_run = self . run_function (
' state.sls ' ,
mods = ' issue-46762 '
)
state_id = ' test_|-a_|-a_|-fail_without_changes '
self . assertIn ( state_id , state_run )
self . assertEqual ( state_run [ state_id ] [ ' comment ' ] ,
' Failure! ' )
self . assertFalse ( state_run [ state_id ] [ ' result ' ] )
state_id = ' test_|-b_|-b_|-nop '
self . assertIn ( state_id , state_run )
self . assertEqual ( state_run [ state_id ] [ ' comment ' ] ,
' One or more requisite failed: issue-46762.c ' )
self . assertFalse ( state_run [ state_id ] [ ' result ' ] )
state_id = ' test_|-c_|-c_|-nop '
self . assertIn ( state_id , state_run )
self . assertEqual ( state_run [ state_id ] [ ' comment ' ] ,
' One or more requisite failed: issue-46762.a ' )
self . assertFalse ( state_run [ state_id ] [ ' result ' ] )
2017-11-20 21:53:56 +00:00
def test_state_nonbase_environment ( self ) :
'''
test state . sls with saltenv using a nonbase environment
with a salt source
'''
2018-01-10 18:16:59 +00:00
file_name = os . path . join ( TMP , ' nonbase_env ' )
2017-11-20 21:53:56 +00:00
state_run = self . run_function (
' state.sls ' ,
mods = ' non-base-env ' ,
saltenv = ' prod '
)
2018-01-10 18:16:59 +00:00
state_id = ' file_|-test_file_|- {0} _|-managed ' . format ( file_name )
self . assertEqual ( state_run [ state_id ] [ ' comment ' ] ,
' File {0} updated ' . format ( file_name ) )
self . assertTrue (
state_run [ ' file_|-test_file_|- {0} _|-managed ' . format ( file_name ) ] [ ' result ' ] )
self . assertTrue ( os . path . isfile ( file_name ) )
2017-11-20 21:53:56 +00:00
def tearDown ( self ) :
2018-01-10 18:16:59 +00:00
nonbase_file = os . path . join ( TMP , ' nonbase_env ' )
2017-11-20 21:53:56 +00:00
if os . path . isfile ( nonbase_file ) :
os . remove ( nonbase_file )