Merge pull request #44573 from garethgreenaway/requisite_without_module_name

Adding the ability to specify requisites without a state module name
This commit is contained in:
Mike Place 2017-11-20 18:50:13 +00:00 committed by GitHub
commit 446e3436c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 389 additions and 2 deletions

View File

@ -1605,7 +1605,24 @@ class State(object):
for ind in items:
if not isinstance(ind, dict):
# Malformed req_in
continue
if ind in high:
_ind_high = [x for x
in high[ind]
if not x.startswith('__')]
ind = {_ind_high[0]: ind}
else:
found = False
for _id in iter(high):
for state in [state for state
in iter(high[_id])
if not state.startswith('__')]:
for j in iter(high[_id][state]):
if isinstance(j, dict) and 'name' in j:
if j['name'] == ind:
ind = {state: _id}
found = True
if not found:
continue
if len(ind) < 1:
continue
pstate = next(iter(ind))
@ -2579,7 +2596,14 @@ class State(object):
for key, val in six.iteritems(l_dict):
for listen_to in val:
if not isinstance(listen_to, dict):
continue
found = False
for chunk in chunks:
if chunk['__id__'] == listen_to or \
chunk['name'] == listen_to:
listen_to = {chunk['state']: chunk['__id__']}
found = True
if not found:
continue
for lkey, lval in six.iteritems(listen_to):
if (lkey, lval) not in crefs:
rerror = {_l_tag(lkey, lval):

View File

@ -0,0 +1,36 @@
successful_changing_state:
cmd.run:
- name: echo "Successful Change"
# mock is installed with salttesting, so it should already be
# present on the system, resulting in no changes
non_changing_state:
pip.installed:
- name: mock
test_listening_change_state:
cmd.run:
- name: echo "Listening State"
- listen:
- successful_changing_state
test_listening_non_changing_state:
cmd.run:
- name: echo "Only run once"
- listen:
- non_changing_state
# test that requisite resolution for listen uses ID declaration.
# test_listening_resolution_one and test_listening_resolution_two
# should both run.
test_listening_resolution_one:
cmd.run:
- name: echo "Successful listen resolution"
- listen:
- successful_changing_state
test_listening_resolution_two:
cmd.run:
- name: echo "Successful listen resolution"
- listen:
- successful_changing_state

View File

@ -0,0 +1,21 @@
changing_state:
cmd.run:
- name: echo "Changed!"
# mock is installed with salttesting, so it should already be
# present on the system, resulting in no changes
non_changing_state:
pip.installed:
- name: mock
test_changing_state:
cmd.run:
- name: echo "Success!"
- onchanges:
- changing_state
test_non_changing_state:
cmd.run:
- name: echo "Should not run"
- onchanges:
- non_changing_state

View File

@ -0,0 +1,19 @@
failing_state:
cmd.run:
- name: asdf
non_failing_state:
cmd.run:
- name: echo "Non-failing state"
test_failing_state:
cmd.run:
- name: echo "Success!"
- onfail:
- failing_state
test_non_failing_state:
cmd.run:
- name: echo "Should not run"
- onfail:
- non_failing_state

View File

@ -0,0 +1,33 @@
# B --+
# |
# C <-+ ----+
# |
# A <-------+
# runs after C
A:
cmd.run:
- name: echo A third
# is running in test mode before C
# C gets executed first if this states modify something
- prereq_in:
- C
# runs before C
B:
cmd.run:
- name: echo B first
# will test C and be applied only if C changes,
# and then will run before C
- prereq:
- C
C:
cmd.run:
- name: echo C second
# will fail with "The following requisites were not found"
I:
cmd.run:
- name: echo I
- prereq:
- Z

View File

@ -0,0 +1,58 @@
# Complex require/require_in graph
#
# Relative order of C>E is given by the definition order
#
# D (1) <--+
# |
# B (2) ---+ <-+ <-+ <-+
# | | |
# C (3) <--+ --|---|---+
# | | |
# E (4) ---|---|---+ <-+
# | | |
# A (5) ---+ --+ ------+
#
A:
cmd.run:
- name: echo A fifth
- require:
- C
B:
cmd.run:
- name: echo B second
- require_in:
- A
- C
C:
cmd.run:
- name: echo C third
D:
cmd.run:
- name: echo D first
- require_in:
- B
E:
cmd.run:
- name: echo E fourth
- require:
- B
- require_in:
- A
# will fail with "The following requisites were not found"
G:
cmd.run:
- name: echo G
- require:
- Z
# will fail with "The following requisites were not found"
H:
cmd.run:
- name: echo H
- require:
- Z

View File

@ -0,0 +1,55 @@
# None of theses states should run
A:
cmd.run:
- name: echo "A"
- onlyif: 'false'
# issue #8235
#B:
# cmd.run:
# - name: echo "B"
# # here used without "-"
# - use:
# cmd: A
C:
cmd.run:
- name: echo "C"
- use:
- A
D:
cmd.run:
- name: echo "D"
- onlyif: 'false'
- use_in:
- E
E:
cmd.run:
- name: echo "E"
# issue 8235
#F:
# cmd.run:
# - name: echo "F"
# - onlyif: return 0
# - use_in:
# cmd: G
#
#G:
# cmd.run:
# - name: echo "G"
# issue xxxx
#H:
# cmd.run:
# - name: echo "H"
# - use:
# - cmd: C
#I:
# cmd.run:
# - name: echo "I"
# - use:
# - cmd: E

View File

@ -964,6 +964,65 @@ class StateModuleTest(ModuleCase, SaltReturnAssertsMixin):
#ret = self.run_function('state.sls', mods='requisites.fullsls_prereq')
#self.assertEqual(['sls command can only be used with require requisite'], ret)
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)
def test_requisites_prereq_simple_ordering_and_errors(self):
'''
Call sls file containing several prereq_in and prereq.
@ -1001,6 +1060,30 @@ class StateModuleTest(ModuleCase, SaltReturnAssertsMixin):
'result': False,
'changes': False}
}
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}
}
expected_result_simple2 = {
'cmd_|-A_|-echo A_|-run': {
'__run_num__': 1,
@ -1131,6 +1214,11 @@ class StateModuleTest(ModuleCase, SaltReturnAssertsMixin):
# ret,
# ['A recursive requisite was found, SLS "requisites.prereq_recursion_error" ID "B" ID "A"']
#)
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)
def test_infinite_recursion_sls_prereq(self):
ret = self.run_function('state.sls', mods='requisites.prereq_sls_infinite_recursion')
self.assertSaltTrueReturn(ret)
@ -1167,6 +1255,16 @@ class StateModuleTest(ModuleCase, SaltReturnAssertsMixin):
# + ' ID "A" ID "A"'
#])
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):
self.assertEqual(descr['comment'], 'onlyif condition is false')
def test_get_file_from_env_in_top_match(self):
tgt = os.path.join(TMP, 'prod-cheese-file')
try:
@ -1244,6 +1342,16 @@ class StateModuleTest(ModuleCase, SaltReturnAssertsMixin):
expected_result = 'State was not run because none of the onchanges reqs changed'
self.assertIn(expected_result, test_data)
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)
# onfail tests
def test_onfail_requisite(self):
@ -1297,6 +1405,24 @@ class StateModuleTest(ModuleCase, SaltReturnAssertsMixin):
expected_result = 'State was not run because onfail req did not change'
self.assertIn(expected_result, test_data)
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)
# listen tests
def test_listen_requisite(self):
@ -1358,6 +1484,21 @@ class StateModuleTest(ModuleCase, SaltReturnAssertsMixin):
listener_state = 'cmd_|-listener_test_listening_resolution_two_|-echo "Successful listen resolution"_|-mod_watch'
self.assertIn(listener_state, state_run)
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)
def test_issue_30820_requisite_in_match_by_name(self):
'''
This tests the case where a requisite_in matches by name instead of ID