From e76cdc70c04e9a0e0a989a0fae0e16f4059b6adc Mon Sep 17 00:00:00 2001 From: matosys Date: Mon, 2 Mar 2026 08:02:56 +0100 Subject: [PATCH 1/2] tests(vdevice): modify existing test `test_1_vdevice_which_is_no_part_of_a_variation.py` and add a new `HelperDevice`, that isn't a part of the variation --- .../env/lib/features.py | 6 ++++++ .../env/setups/features_setup.py | 6 +++++- .../env/setups/setup_pythonadd.py | 13 +++++++------ ..._1_vdevice_which_is_no_part_of_a_variation.py | 16 ++-------------- 4 files changed, 20 insertions(+), 21 deletions(-) diff --git a/tests/vdevice/test_1_vdevice_which_is_no_part_of_a_variation/env/lib/features.py b/tests/vdevice/test_1_vdevice_which_is_no_part_of_a_variation/env/lib/features.py index 4dfe083b..839ef317 100644 --- a/tests/vdevice/test_1_vdevice_which_is_no_part_of_a_variation/env/lib/features.py +++ b/tests/vdevice/test_1_vdevice_which_is_no_part_of_a_variation/env/lib/features.py @@ -13,6 +13,12 @@ def add_numbers(self): raise NotImplementedError("has to be implemented in subclass") +class CalculatorHelperFeature(balder.Feature): + + def get_help_with(self, number): + return number + + class ProvidesANumberFeature(balder.Feature): the_number = 0 diff --git a/tests/vdevice/test_1_vdevice_which_is_no_part_of_a_variation/env/setups/features_setup.py b/tests/vdevice/test_1_vdevice_which_is_no_part_of_a_variation/env/setups/features_setup.py index f72a2e4d..71787f24 100644 --- a/tests/vdevice/test_1_vdevice_which_is_no_part_of_a_variation/env/setups/features_setup.py +++ b/tests/vdevice/test_1_vdevice_which_is_no_part_of_a_variation/env/setups/features_setup.py @@ -1,4 +1,5 @@ -from ..lib.features import AddCalculateFeature, ProvidesANumberFeature +import balder +from ..lib.features import AddCalculateFeature, ProvidesANumberFeature, CalculatorHelperFeature from ..lib.utils import SharedObj @@ -13,6 +14,9 @@ def sends_the_number(self): class PyAddCalculate(AddCalculateFeature): + class Helper(balder.VDevice): + helper = CalculatorHelperFeature() + def get_numbers(self): self.all_numbers = SharedObj.shared_mem_list diff --git a/tests/vdevice/test_1_vdevice_which_is_no_part_of_a_variation/env/setups/setup_pythonadd.py b/tests/vdevice/test_1_vdevice_which_is_no_part_of_a_variation/env/setups/setup_pythonadd.py index 7e2be14d..e1f64a36 100644 --- a/tests/vdevice/test_1_vdevice_which_is_no_part_of_a_variation/env/setups/setup_pythonadd.py +++ b/tests/vdevice/test_1_vdevice_which_is_no_part_of_a_variation/env/setups/setup_pythonadd.py @@ -1,24 +1,25 @@ import balder from ..lib.connections import MySimplySharedMemoryConnection from ..lib.utils import SharedObj +from ..lib.features import CalculatorHelperFeature from .features_setup import PyAddCalculate, PyAddProvideANumber class SetupPythonAdd(balder.Setup): - class Calculator1(balder.Device): - calc = PyAddCalculate() + class HelperDevice(balder.Device): + """this device is no part of the variation, but used as vdevice""" + helper = CalculatorHelperFeature() - class Calculator2(balder.Device): - calc = PyAddCalculate() + @balder.connect(HelperDevice, over_connection=balder.Connection) + class Calculator1(balder.Device): + calc = PyAddCalculate(Helper='HelperDevice') @balder.connect(Calculator1, over_connection=MySimplySharedMemoryConnection) - @balder.connect(Calculator2, over_connection=MySimplySharedMemoryConnection) class NumberProvider1(balder.Device): n = PyAddProvideANumber(Calculator="Calculator1") @balder.connect(Calculator1, over_connection=MySimplySharedMemoryConnection) - @balder.connect(Calculator2, over_connection=MySimplySharedMemoryConnection) class NumberProvider2(balder.Device): n = PyAddProvideANumber(Calculator="Calculator1") diff --git a/tests/vdevice/test_1_vdevice_which_is_no_part_of_a_variation/test_1_vdevice_which_is_no_part_of_a_variation.py b/tests/vdevice/test_1_vdevice_which_is_no_part_of_a_variation/test_1_vdevice_which_is_no_part_of_a_variation.py index 68f080cb..9153c99a 100644 --- a/tests/vdevice/test_1_vdevice_which_is_no_part_of_a_variation/test_1_vdevice_which_is_no_part_of_a_variation.py +++ b/tests/vdevice/test_1_vdevice_which_is_no_part_of_a_variation/test_1_vdevice_which_is_no_part_of_a_variation.py @@ -8,14 +8,8 @@ def test_1_vdevice_which_is_no_part_of_a_variation(balder_working_dir): """ This testcase is a modified version of the calculator environment. - The setup defines two calculator devices `Calculator1` and `Calculator2` that theoretically could map to the - scenario device `Calculator`. Normally both of these setup devices `Calculator1` and `Calculator2` should map. - - However, since we have a VDevice mapping on setup level only to the `Calculator1` device, balder should not allow - the second variation, at which the `Calculator2` would be mapped to the scenario device `Calculator`, because it - cannot be used as VDevice. - - The test secures that only the mapped `Calculator1` is a valid variation. + The setup defines two an additional helper devices `HelperDevice` that is never a part of the variation (does not + have a mapped scenario-device). It is expected, that the variation is executed and the VDevice is mapped. """ proc = Process(target=processed, args=(balder_working_dir, )) proc.start() @@ -36,9 +30,3 @@ def processed(env_dir): scenario_executors = session.executor_tree.get_setup_executors()[0].get_scenario_executors() assert len(scenario_executors) == 1 assert len(scenario_executors[0].get_variation_executors()) == 2 - for cur_variation_executor in scenario_executors[0].get_variation_executors(): - all_setup_devices = [cur_device.__name__ for cur_device in cur_variation_executor.base_device_mapping.values()] - assert "Calculator1" in all_setup_devices, \ - "can not find the expected `Calculator` setup device in mapped-devices" - assert "Calculator2" not in all_setup_devices, \ - "`Calculator2` should not be contained in mapped-devices" From e459412d3fe3ce46b739bb9fc5da5f014377e3fc Mon Sep 17 00:00:00 2001 From: matosys Date: Thu, 30 Apr 2026 15:02:03 +0200 Subject: [PATCH 2/2] fix(VariationExecutor): allow all vdevice mappings to setup devices that are no part of the variation Instead of ignoring these devices within `determine_absolute_scenario_device_connections()` (which is okay, because these devices have no influence on scenario connections), Balder raised an NotApplicableVariationException. --- src/_balder/executor/variation_executor.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/_balder/executor/variation_executor.py b/src/_balder/executor/variation_executor.py index e48e44bf..55457d18 100644 --- a/src/_balder/executor/variation_executor.py +++ b/src/_balder/executor/variation_executor.py @@ -744,10 +744,9 @@ def determine_absolute_scenario_device_connections(self): ) if vdev_mappings_of_setup_feature[0].device not in self.base_device_mapping.values(): - raise NotApplicableVariationException( - f'the mapped setup device `{vdev_mappings_of_setup_feature[0].device.__qualname__}` which is ' - f'mapped to the VDevice `{vdev_mappings_of_setup_feature[0].vdevice.__qualname__}` is no part ' - f'of this variation') + # ignore this device if it is no part of the mapping (assigned VDev, that does not have an + # mapped scenario device) + continue cur_mapped_scenario_device = self.get_scenario_device_for(vdev_mappings_of_setup_feature[0].device)