From 49280d1d7b33c8404b12f6924c6a11f4a449bd9d Mon Sep 17 00:00:00 2001 From: aj Date: Wed, 20 Dec 2023 20:44:50 +0000 Subject: [PATCH] pass without exception if jinja parameter isn't found fix tests so they do not check for exception for rendering parameters remove debugging and clean up comments remove comments in params rendering code black fixes st2common tests remove unused var --- st2common/st2common/util/param.py | 25 ++++++++++---- st2common/tests/unit/test_param_utils.py | 42 ++++++++---------------- 2 files changed, 31 insertions(+), 36 deletions(-) diff --git a/st2common/st2common/util/param.py b/st2common/st2common/util/param.py index 67fb83e9acc..8061e3458fc 100644 --- a/st2common/st2common/util/param.py +++ b/st2common/st2common/util/param.py @@ -174,13 +174,22 @@ def _validate(G): """ Validates dependency graph to ensure it has no missing or cyclic dependencies """ + g_copy = G.copy() for name in G.nodes: if "value" not in G.nodes[name] and "template" not in G.nodes[name]: - msg = 'Dependency unsatisfied in variable "%s"' % name - raise ParamException(msg) - - if not nx.is_directed_acyclic_graph(G): - graph_cycles = nx.simple_cycles(G) + # this is a string not a jinja template; embedded {{sometext}} + for i in G.neighbors(name): + # remove template for neighbors; this isn't actually a variable + # it is a value + # remove template attr if it exists + g_copy.nodes[i]["value"] = g_copy.nodes[i].pop("template") + # remove edges + g_copy.remove_edge(name, i) + # remove node from graph + g_copy.remove_node(name) + + if not nx.is_directed_acyclic_graph(g_copy): + graph_cycles = nx.simple_cycles(g_copy) variable_names = [] for cycle in graph_cycles: @@ -197,6 +206,7 @@ def _validate(G): "referencing itself" % (variable_names) ) raise ParamException(msg) + return g_copy def _render(node, render_context): @@ -336,9 +346,10 @@ def render_live_params( [_process(G, name, value) for name, value in six.iteritems(params)] _process_defaults(G, [action_parameters, runner_parameters]) - _validate(G) + G = _validate(G) context = _resolve_dependencies(G) + LOG.debug("context: %s" % str(context)) live_params = _cast_params_from( params, context, [action_parameters, runner_parameters] ) @@ -359,7 +370,7 @@ def render_final_params(runner_parameters, action_parameters, params, action_con # by that point, all params should already be resolved so any template should be treated value [G.add_node(name, value=value) for name, value in six.iteritems(params)] _process_defaults(G, [action_parameters, runner_parameters]) - _validate(G) + G = _validate(G) context = _resolve_dependencies(G) context = _cast_params_from( diff --git a/st2common/tests/unit/test_param_utils.py b/st2common/tests/unit/test_param_utils.py index 8393f4aa11d..96b52f46213 100644 --- a/st2common/tests/unit/test_param_utils.py +++ b/st2common/tests/unit/test_param_utils.py @@ -59,7 +59,6 @@ class ParamsUtilsTest(DbTestCase): runnertype_db = FIXTURES["runners"]["testrunner1.yaml"] def test_process_jinja_exception(self): - action_context = {"api_user": "noob"} config = {} G = param_utils._create_graph(action_context, config) @@ -69,7 +68,6 @@ def test_process_jinja_exception(self): self.assertEquals(G.nodes.get(name, {}).get("value"), value) def test_process_jinja_template(self): - action_context = {"api_user": "noob"} config = {} G = param_utils._create_graph(action_context, config) @@ -540,28 +538,20 @@ def test_get_finalized_params_with_missing_dependency(self): params = {"r1": "{{r3}}", "r2": "{{r3}}"} runner_param_info = {"r1": {}, "r2": {}} action_param_info = {} - test_pass = True - try: - param_utils.get_finalized_params( - runner_param_info, action_param_info, params, {"user": None} - ) - test_pass = False - except ParamException as e: - test_pass = six.text_type(e).find("Dependency") == 0 - self.assertTrue(test_pass) + result = param_utils.get_finalized_params( + runner_param_info, action_param_info, params, {"user": None} + ) + self.assertEquals(result[0]["r1"], params["r1"]) + self.assertEquals(result[0]["r2"], params["r2"]) params = {} runner_param_info = {"r1": {"default": "{{r3}}"}, "r2": {"default": "{{r3}}"}} action_param_info = {} - test_pass = True - try: - param_utils.get_finalized_params( - runner_param_info, action_param_info, params, {"user": None} - ) - test_pass = False - except ParamException as e: - test_pass = six.text_type(e).find("Dependency") == 0 - self.assertTrue(test_pass) + result2 = param_utils.get_finalized_params( + runner_param_info, action_param_info, params, {"user": None} + ) + self.assertEquals(result2[0]["r1"], runner_param_info["r1"]["default"]) + self.assertEquals(result2[0]["r2"], runner_param_info["r2"]["default"]) def test_get_finalized_params_no_double_rendering(self): params = {"r1": "{{ action_context.h1 }}{{ action_context.h2 }}"} @@ -804,16 +794,10 @@ def test_unsatisfied_dependency_friendly_error_message(self): } action_context = {"user": None} - expected_msg = 'Dependency unsatisfied in variable "variable_not_defined"' - self.assertRaisesRegexp( - ParamException, - expected_msg, - param_utils.render_live_params, - runner_param_info, - action_param_info, - params, - action_context, + result = param_utils.render_live_params( + runner_param_info, action_param_info, params, action_context ) + self.assertEquals(result["r4"], params["r4"]) def test_add_default_templates_to_live_params(self): """Test addition of template values in defaults to live params"""