Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:tulip
salt
fix-onlyif-unless-when-multiple-conditions-bsc-...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File fix-onlyif-unless-when-multiple-conditions-bsc-11808.patch of Package salt
From 828ca76e2083d87ace12b488277e51d4e30c8c9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?= <psuarezhernandez@suse.com> Date: Thu, 21 Jan 2021 11:19:07 +0000 Subject: [PATCH] Fix onlyif/unless when multiple conditions (bsc#1180818) Add unit tests to ensure right onlyif/unless behavior Add extra unit test to cover valid cases Add unit tests cases to ensure proper onlyif/unless behavior Change tests to use 'exit' cmd and work outside Linux --- salt/state.py | 20 ++++-- tests/unit/test_state.py | 148 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 163 insertions(+), 5 deletions(-) diff --git a/salt/state.py b/salt/state.py index cc6db7e1b2..070a914636 100644 --- a/salt/state.py +++ b/salt/state.py @@ -947,8 +947,10 @@ class State: "result": True, } ) + return False elif cmd == 0: ret.update({"comment": "onlyif condition is true", "result": False}) + return True for entry in low_data_onlyif: if isinstance(entry, str): @@ -960,7 +962,8 @@ class State: # Command failed, notify onlyif to skip running the item cmd = 100 log.debug("Last command return code: %s", cmd) - _check_cmd(cmd) + if not _check_cmd(cmd): + return ret elif isinstance(entry, dict): if "fun" not in entry: ret["comment"] = "no `fun` argument in onlyif: {}".format(entry) @@ -972,7 +975,8 @@ class State: if get_return: result = salt.utils.data.traverse_dict_and_list(result, get_return) if self.state_con.get("retcode", 0): - _check_cmd(self.state_con["retcode"]) + if not _check_cmd(self.state_con["retcode"]): + return ret elif not result: ret.update( { @@ -981,6 +985,7 @@ class State: "result": True, } ) + return ret else: ret.update({"comment": "onlyif condition is true", "result": False}) @@ -991,6 +996,7 @@ class State: "result": False, } ) + return ret return ret def _run_check_unless(self, low_data, cmd_opts): @@ -1013,8 +1019,10 @@ class State: "result": True, } ) + return False elif cmd != 0: ret.update({"comment": "unless condition is false", "result": False}) + return True for entry in low_data_unless: if isinstance(entry, str): @@ -1026,7 +1034,8 @@ class State: except CommandExecutionError: # Command failed, so notify unless to skip the item cmd = 0 - _check_cmd(cmd) + if not _check_cmd(cmd): + return ret elif isinstance(entry, dict): if "fun" not in entry: ret["comment"] = "no `fun` argument in unless: {}".format(entry) @@ -1038,7 +1047,8 @@ class State: if get_return: result = salt.utils.data.traverse_dict_and_list(result, get_return) if self.state_con.get("retcode", 0): - _check_cmd(self.state_con["retcode"]) + if not _check_cmd(self.state_con["retcode"]): + return ret elif result: ret.update( { @@ -1047,6 +1057,7 @@ class State: "result": True, } ) + return ret else: ret.update( {"comment": "unless condition is false", "result": False} @@ -1058,6 +1069,7 @@ class State: "result": False, } ) + return ret # No reason to stop, return ret return ret diff --git a/tests/unit/test_state.py b/tests/unit/test_state.py index b1bcf8fe83..95018a9cf3 100644 --- a/tests/unit/test_state.py +++ b/tests/unit/test_state.py @@ -205,6 +205,152 @@ class StateCompilerTestCase(TestCase, AdaptedConfigurationTestCaseMixin): ) self.assertEqual(expected_result, return_result) + def test_verify_unless_list_cmd(self): + low_data = { + "state": "cmd", + "name": 'echo "something"', + "__sls__": "tests.cmd", + "__env__": "base", + "__id__": "check unless", + "unless": ["exit 0", "exit 1"], + "order": 10001, + "fun": "run", + } + expected_result = { + "comment": "unless condition is true", + "result": True, + "skip_watch": True, + } + with patch("salt.state.State._gather_pillar") as state_patch: + minion_opts = self.get_temp_config("minion") + state_obj = salt.state.State(minion_opts) + return_result = state_obj._run_check_unless(low_data, {}) + self.assertEqual(expected_result, return_result) + + def test_verify_unless_list_cmd_different_order(self): + low_data = { + "state": "cmd", + "name": 'echo "something"', + "__sls__": "tests.cmd", + "__env__": "base", + "__id__": "check unless", + "unless": ["exit 1", "exit 0"], + "order": 10001, + "fun": "run", + } + expected_result = { + "comment": "unless condition is true", + "result": True, + "skip_watch": True, + } + with patch("salt.state.State._gather_pillar") as state_patch: + minion_opts = self.get_temp_config("minion") + state_obj = salt.state.State(minion_opts) + return_result = state_obj._run_check_unless(low_data, {}) + self.assertEqual(expected_result, return_result) + + def test_verify_onlyif_list_cmd_different_order(self): + low_data = { + "state": "cmd", + "name": 'echo "something"', + "__sls__": "tests.cmd", + "__env__": "base", + "__id__": "check onlyif", + "onlyif": ["exit 1", "exit 0"], + "order": 10001, + "fun": "run", + } + expected_result = { + "comment": "onlyif condition is false", + "result": True, + "skip_watch": True, + } + with patch("salt.state.State._gather_pillar") as state_patch: + minion_opts = self.get_temp_config("minion") + state_obj = salt.state.State(minion_opts) + return_result = state_obj._run_check_onlyif(low_data, {}) + self.assertEqual(expected_result, return_result) + + def test_verify_unless_list_cmd_valid(self): + low_data = { + "state": "cmd", + "name": 'echo "something"', + "__sls__": "tests.cmd", + "__env__": "base", + "__id__": "check unless", + "unless": ["exit 1", "exit 1"], + "order": 10001, + "fun": "run", + } + expected_result = {"comment": "unless condition is false", "result": False} + with patch("salt.state.State._gather_pillar") as state_patch: + minion_opts = self.get_temp_config("minion") + state_obj = salt.state.State(minion_opts) + return_result = state_obj._run_check_unless(low_data, {}) + self.assertEqual(expected_result, return_result) + + def test_verify_onlyif_list_cmd_valid(self): + low_data = { + "state": "cmd", + "name": 'echo "something"', + "__sls__": "tests.cmd", + "__env__": "base", + "__id__": "check onlyif", + "onlyif": ["exit 0", "exit 0"], + "order": 10001, + "fun": "run", + } + expected_result = {"comment": "onlyif condition is true", "result": False} + with patch("salt.state.State._gather_pillar") as state_patch: + minion_opts = self.get_temp_config("minion") + state_obj = salt.state.State(minion_opts) + return_result = state_obj._run_check_onlyif(low_data, {}) + self.assertEqual(expected_result, return_result) + + def test_verify_unless_list_cmd_invalid(self): + low_data = { + "state": "cmd", + "name": 'echo "something"', + "__sls__": "tests.cmd", + "__env__": "base", + "__id__": "check unless", + "unless": ["exit 0", "exit 0"], + "order": 10001, + "fun": "run", + } + expected_result = { + "comment": "unless condition is true", + "result": True, + "skip_watch": True, + } + with patch("salt.state.State._gather_pillar") as state_patch: + minion_opts = self.get_temp_config("minion") + state_obj = salt.state.State(minion_opts) + return_result = state_obj._run_check_unless(low_data, {}) + self.assertEqual(expected_result, return_result) + + def test_verify_onlyif_list_cmd_invalid(self): + low_data = { + "state": "cmd", + "name": 'echo "something"', + "__sls__": "tests.cmd", + "__env__": "base", + "__id__": "check onlyif", + "onlyif": ["exit 1", "exit 1"], + "order": 10001, + "fun": "run", + } + expected_result = { + "comment": "onlyif condition is false", + "result": True, + "skip_watch": True, + } + with patch("salt.state.State._gather_pillar") as state_patch: + minion_opts = self.get_temp_config("minion") + state_obj = salt.state.State(minion_opts) + return_result = state_obj._run_check_onlyif(low_data, {}) + self.assertEqual(expected_result, return_result) + def test_verify_unless_parse(self): low_data = { "unless": [{"fun": "test.arg", "args": ["arg1", "arg2"]}], @@ -376,7 +522,7 @@ class StateCompilerTestCase(TestCase, AdaptedConfigurationTestCaseMixin): "__sls__": "tests.cmd", "__env__": "base", "__id__": "check onlyif", - "onlyif": ["/bin/true", "/bin/false"], + "onlyif": ["exit 0", "exit 1"], "order": 10001, "fun": "run", } -- 2.29.2
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor