From fec8e387937717e698606689a8c013b78583e9e7 Mon Sep 17 00:00:00 2001 From: Olivier Ramonat Date: Mon, 16 Sep 2024 08:58:07 +0200 Subject: [PATCH] Detect invalid plan containing nested entry points Nested entry points are not supported. When there is an nested entry point, it is currently added to the list of entry point only after having executed the parent entry point. As a result, it is ignored by most tools and the code in the child entry point is never executed. For it/e3-core#14 --- src/e3/electrolyt/plan.py | 9 +++++++ tests/tests_e3/electrolyt/plan/main_test.py | 28 +++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/e3/electrolyt/plan.py b/src/e3/electrolyt/plan.py index 1a084b80..df75be0d 100644 --- a/src/e3/electrolyt/plan.py +++ b/src/e3/electrolyt/plan.py @@ -272,6 +272,7 @@ def execute( if entry_point_parameters is None: entry_point_parameters = {} + nb_entry_points = len(plan.entry_points) if entry_point_name in plan.entry_points: plan.entry_points[entry_point_name].execute(**entry_point_parameters) else: @@ -279,6 +280,14 @@ def execute( # used everywhere plan.mod.__dict__[entry_point_name](**entry_point_parameters) + if len(plan.entry_points) != nb_entry_points: + # The number of entry points should not change when executing the + # code in an entry point. If it does, it means that there is a + # nested entry point, this is not supported. + raise PlanError( + f"the plan contains nested entry points in {entry_point_name}" + ) + return self.action_list def _add_action(self, name: str, *args: Any, **kwargs: Any) -> None: diff --git a/tests/tests_e3/electrolyt/plan/main_test.py b/tests/tests_e3/electrolyt/plan/main_test.py index 50e5a080..26587258 100644 --- a/tests/tests_e3/electrolyt/plan/main_test.py +++ b/tests/tests_e3/electrolyt/plan/main_test.py @@ -2,6 +2,7 @@ import e3.electrolyt.host as host import e3.electrolyt.plan as plan import e3.env +import pytest def build_action(spec, build=None, host=None, target=None, board=None): @@ -145,6 +146,33 @@ def test_entry_points(): assert ep_executed[0].name == "machine2" +def test_nested_entry_points(): + """Test a plan containing nested entry points. + + Nested entry points are not supported, verify that we get an Plan Error. + """ + plan_content = [ + '@machine(name="machine1", description="Machine 1",', + ' platform="x86_64-linux", version="rhES6")', + "def machine1():", + ' build("a")', + ' @machine(description="Machine 2",', + ' platform="x86_64-linux", version="rhES6")', + " def machine2():", + ' build("b")', + ] + myplan = _get_plan({}, plan_content) + + db = myplan.entry_points + assert len(db) == 1 + assert "machine1" in db + + context = _get_new_plancontext("machine1") + with pytest.raises(plan.PlanError) as pe: + context.execute(myplan, "machine1") + assert "nested" in str(pe) + + def test_plan_disable_lines(): """Check that lines in enabled=False blocks are disabled.""" context = _get_new_plancontext("myserver")