Multiple onchanges requisite behaviour

Change the onchanges requisite so that if you list multiple onchanges
requisites then only one must change to trigger the state. Currently all
the watched states must change to cause the trigger. This fixes #19592
This commit is contained in:
mattmb 2015-06-16 15:02:11 +01:00
parent 211bf3649e
commit a5607d5e07
4 changed files with 72 additions and 5 deletions

View file

@ -326,6 +326,9 @@ The ``onchanges`` requisite makes a state only apply if the required states
generate changes, and if the watched state's "result" is ``True``. This can be
a useful way to execute a post hook after changing aspects of a system.
If a state has multiple ``onchanges`` requisites then the state will trigger
if any of the watched states changes.
use
~~~

View file

@ -1746,7 +1746,9 @@ class State(object):
if r_state == 'onchanges':
if not run_dict[tag]['changes']:
fun_stats.add('onchanges')
continue
else:
fun_stats.add('onchangesmet')
continue
if r_state == 'watch' and run_dict[tag]['changes']:
fun_stats.add('change')
continue
@ -1768,7 +1770,7 @@ class State(object):
status = 'pre'
elif 'onfail' in fun_stats:
status = 'onfail'
elif 'onchanges' in fun_stats:
elif 'onchanges' in fun_stats and not 'onchangesmet' in fun_stats:
status = 'onchanges'
elif 'change' in fun_stats:
status = 'change'
@ -1992,7 +1994,7 @@ class State(object):
elif status == 'onchanges':
running[tag] = {'changes': {},
'result': True,
'comment': 'State was not run because onchanges req did not change',
'comment': 'State was not run because none of the onchanges reqs changed',
'__run_num__': self.__run_num,
'__sls__': low['__sls__']}
self.__run_num += 1

View file

@ -0,0 +1,38 @@
changing_state:
cmd.run:
- name: echo "Changed!"
another_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
another_non_changing_state:
pip.installed:
- name: mock
test_two_changing_states:
cmd.run:
- name: echo "Success!"
- onchanges:
- cmd: changing_state
- cmd: another_changing_state
test_two_non_changing_states:
cmd.run:
- name: echo "Should not run"
- onchanges:
- pip: non_changing_state
- pip: another_non_changing_state
test_one_changing_state:
cmd.run:
- name: echo "Success!"
- onchanges:
- cmd: changing_state
- pip: non_changing_state

View file

@ -926,7 +926,31 @@ class StateModuleTest(integration.ModuleCase,
# 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']
expected_result = 'State was not run because onchanges req did not change'
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'
self.assertIn(expected_result, test_data)
def test_onchanges_in_requisite(self):
@ -944,7 +968,7 @@ class StateModuleTest(integration.ModuleCase,
# Then, test the result of the state run when changes are not expected to happen
test_data = state_run['cmd_|-test_changes_not_expected_|-echo "Should not run"_|-run']['comment']
expected_result = 'State was not run because onchanges req did not change'
expected_result = 'State was not run because none of the onchanges reqs changed'
self.assertIn(expected_result, test_data)
# onfail tests