baldertest 0.1.0b8__py3-none-any.whl → 0.1.0b9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
_balder/_version.py CHANGED
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.1.0b8'
15
+ __version__ = version = '0.1.0b9'
16
16
  __version_tuple__ = version_tuple = (0, 1, 0)
_balder/balder_session.py CHANGED
@@ -21,7 +21,7 @@ if TYPE_CHECKING:
21
21
  from _balder.scenario import Scenario
22
22
  from _balder.connection import Connection
23
23
 
24
- # pylint: disable-next=too-many-instance-attributes
24
+
25
25
  class BalderSession:
26
26
  """
27
27
  This is the main balder executable object. It contains all information about the current session and executes the
_balder/collector.py CHANGED
@@ -1,5 +1,5 @@
1
1
  from __future__ import annotations
2
- from typing import List, Type, Union, Dict, Callable, Tuple, TYPE_CHECKING, Any
2
+ from typing import List, Type, Union, Dict, Callable, Tuple, TYPE_CHECKING
3
3
 
4
4
  import os
5
5
  import sys
@@ -678,7 +678,8 @@ class Collector:
678
678
  for cur_setup in self.all_setups:
679
679
  SetupController.get_for(cur_setup).validate_feature_possibility()
680
680
 
681
- def _filter_paths_after_allowed_paths(self, paths: List[pathlib.Path], filter_patterns: List[str]) -> List[pathlib.Path]:
681
+ def _filter_paths_after_allowed_paths(self, paths: List[pathlib.Path], filter_patterns: List[str]) \
682
+ -> List[pathlib.Path]:
682
683
  """
683
684
  This method filters the given list of filepaths for the given filter_patterns. It returns a list with all
684
685
  remaining paths that are mathing the filter statements in `filter_paths`.
@@ -129,6 +129,39 @@ class FeatureController(Controller):
129
129
  return [Connection()]
130
130
  return intersection
131
131
 
132
+ def _determine_all_theoretically_unordered_method_variations(
133
+ self, of_method_name: str, for_vdevice: Type[VDevice],
134
+ with_connection: Union[Connection, Tuple[Connection]]) -> Dict[Callable, Connection]:
135
+ """
136
+ This method returns all theoretically matching method variations. It returns more than one, if there are
137
+ multiple method variation for the given VDevice in this feature, where the given connection is part of the
138
+ connection described by the method variation.
139
+
140
+ :param of_method_name: the name of the method that should be returned
141
+ :param for_vdevice: the VDevice that is mapped
142
+ :param with_connection: the connection that is used between the device that uses the related feature and the
143
+ VDevice
144
+ :return: a dictionary that holds all available method variation that matches here
145
+ """
146
+ all_possible_method_variations = {}
147
+ for cur_impl_method, cur_method_impl_dict in self.get_method_based_for_vdevice()[of_method_name].items():
148
+ if for_vdevice in cur_method_impl_dict.keys():
149
+ cur_impl_method_cnns = []
150
+ for cur_cnn in cur_method_impl_dict[for_vdevice]:
151
+ cur_impl_method_cnns += cur_cnn.get_singles()
152
+ for cur_single_impl_method_cnn in cur_impl_method_cnns:
153
+ if cur_single_impl_method_cnn.contained_in(with_connection, ignore_metadata=True):
154
+ # this variation is possible
155
+ # ADD IT if it is not available yet
156
+ if cur_impl_method not in all_possible_method_variations.keys():
157
+ all_possible_method_variations[cur_impl_method] = cur_single_impl_method_cnn
158
+ # COMBINE IT if it is already available
159
+ else:
160
+ all_possible_method_variations[cur_impl_method] = Connection.based_on(
161
+ all_possible_method_variations[cur_impl_method], cur_single_impl_method_cnn)
162
+ return all_possible_method_variations
163
+
164
+
132
165
  # ---------------------------------- METHODS -----------------------------------------------------------------------
133
166
 
134
167
  def get_class_based_for_vdevice(self) -> Union[Dict[Type[VDevice], List[Connection]], None]:
@@ -321,24 +354,10 @@ class FeatureController(Controller):
321
354
  raise ValueError(f"can not find the method `{of_method_name}` in method variation data dictionary")
322
355
 
323
356
  # first determine all possible method-variations
324
- all_possible_method_variations = {}
325
- for cur_impl_method, cur_method_impl_dict in self.get_method_based_for_vdevice()[of_method_name].items():
326
- if for_vdevice in cur_method_impl_dict.keys():
327
- cur_impl_method_cnns = []
328
- for cur_cnn in cur_method_impl_dict[for_vdevice]:
329
- cur_impl_method_cnns += cur_cnn.get_singles()
330
- for cur_single_impl_method_cnn in cur_impl_method_cnns:
331
- if cur_single_impl_method_cnn.contained_in(with_connection, ignore_metadata=True):
332
- # this variation is possible
333
- # ADD IT if it is not available yet
334
- if cur_impl_method not in all_possible_method_variations.keys():
335
- all_possible_method_variations[cur_impl_method] = cur_single_impl_method_cnn
336
- # COMBINE IT if it is already available
337
- else:
338
- all_possible_method_variations[cur_impl_method] = Connection.based_on(
339
- all_possible_method_variations[cur_impl_method], cur_single_impl_method_cnn)
357
+ all_possible_method_variations = self._determine_all_theoretically_unordered_method_variations(
358
+ of_method_name=of_method_name, for_vdevice=for_vdevice, with_connection=with_connection)
340
359
 
341
- # if there are more than one possible method variation, try to sort them hierarchical
360
+ # there are no method variations in this feature directly -> check parent classes
342
361
  if len(all_possible_method_variations) == 0:
343
362
  # try to execute this method in parent classes
344
363
  for cur_base in self.related_cls.__bases__:
@@ -355,9 +374,11 @@ class FeatureController(Controller):
355
374
  f"and usable connection `{with_connection.get_tree_str()}´")
356
375
  return None
357
376
 
377
+ # we only have one -> selection is clear
358
378
  if len(all_possible_method_variations) == 1:
359
379
  return list(all_possible_method_variations.keys())[0]
360
380
 
381
+ # if there are more than one possible method variation, try to sort them hierarchical
361
382
  # we have to determine the outer one
362
383
  length_before = None
363
384
  while length_before is None or length_before != len(all_possible_method_variations):
@@ -188,7 +188,7 @@ class NormalScenarioSetupController(Controller, ABC):
188
188
 
189
189
  devices = self.get_all_inner_device_classes()
190
190
  abs_parent_devices = parent_scenario_or_setup_controller.get_all_abs_inner_device_classes()
191
- abs_parent_devices_as_names = [cur_parent.__name__ for cur_parent in abs_parent_devices]
191
+ abs_parent_devices_by_name = {cur_parent.__name__: cur_parent for cur_parent in abs_parent_devices}
192
192
 
193
193
  if len(devices) == 0:
194
194
  # ignore it because cur item has no own device definitions
@@ -197,10 +197,7 @@ class NormalScenarioSetupController(Controller, ABC):
197
197
  # check that a device is newly defined or has the same name as the parent device
198
198
  for cur_item_device in devices:
199
199
  # check if name exists in parent
200
- relevant_parent_according_naming = None
201
- if cur_item_device.__name__ in abs_parent_devices_as_names:
202
- relevant_parent_according_naming = \
203
- abs_parent_devices[abs_parent_devices_as_names.index(cur_item_device.__name__)]
200
+ relevant_parent_according_naming = abs_parent_devices_by_name.get(cur_item_device.__name__, None)
204
201
 
205
202
  # check if device is inherited from a parent
206
203
  relevant_parent_device_according_inheritance = None
@@ -236,11 +233,7 @@ class NormalScenarioSetupController(Controller, ABC):
236
233
 
237
234
  # secure that all parent devices are implemented here too
238
235
  for cur_parent in abs_parent_devices:
239
- found_parent = False
240
- for cur_item_device in devices:
241
- if issubclass(cur_item_device, cur_parent):
242
- found_parent = True
243
- break
236
+ found_parent = len([dev for dev in devices if issubclass(dev, cur_parent)]) > 0
244
237
  if not found_parent:
245
238
  raise DeviceOverwritingError(
246
239
  f"found a device `{cur_parent.__qualname__}` which is part of a parent class, but it is "
@@ -1,13 +1,13 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import time
4
- from typing import List, Dict, Union, Type, TYPE_CHECKING
4
+ from typing import List, Union, Type, TYPE_CHECKING
5
5
 
6
6
  import sys
7
7
  import types
8
8
  import traceback
9
9
  from abc import ABC, abstractmethod
10
- from _balder.testresult import FixturePartResult, ResultState
10
+ from _balder.testresult import FixturePartResult, ResultState, ResultSummary
11
11
  from _balder.previous_executor_mark import PreviousExecutorMark
12
12
  from _balder.testresult import TestcaseResult
13
13
 
@@ -207,31 +207,19 @@ class BasicExecutor(ABC):
207
207
  for cur_child_executor in self.all_child_executors:
208
208
  cur_child_executor.filter_tree_for_user_filters()
209
209
 
210
- def testsummary(self) -> Dict[ResultState, int]:
210
+ def testsummary(self) -> ResultSummary:
211
211
  """
212
212
  returns a dictionary with all possible :class:`ResultState` as keys and the number of times they have occurred
213
213
  in this branch as values
214
214
  """
215
215
 
216
- summary = {
217
- ResultState.NOT_RUN: 0,
218
- ResultState.FAILURE: 0,
219
- ResultState.ERROR: 0,
220
- ResultState.SUCCESS: 0,
221
- ResultState.SKIP: 0,
222
- ResultState.COVERED_BY: 0
223
- }
216
+ summary = ResultSummary()
224
217
 
225
218
  if isinstance(self.body_result, TestcaseResult):
226
- summary[self.executor_result] = 1
219
+ setattr(summary, self.executor_result.value, 1)
227
220
  else:
228
221
  for cur_child_exec in self.all_child_executors:
229
- cur_child_dict = cur_child_exec.testsummary()
230
- for cur_key in cur_child_dict.keys():
231
- if cur_key in summary:
232
- summary[cur_key] += cur_child_dict[cur_key]
233
- else:
234
- summary[cur_key] = cur_child_dict[cur_key]
222
+ summary += cur_child_exec.testsummary()
235
223
  return summary
236
224
 
237
225
  def execute(self, show_discarded=False):
@@ -1,10 +1,11 @@
1
1
  from __future__ import annotations
2
2
  from typing import Union, List, Type, TYPE_CHECKING
3
3
 
4
+ from dataclasses import fields
4
5
  from _balder.executor.setup_executor import SetupExecutor
5
6
  from _balder.executor.basic_executor import BasicExecutor
6
7
  from _balder.fixture_manager import FixtureManager
7
- from _balder.testresult import ResultState, BranchBodyResult
8
+ from _balder.testresult import ResultState, BranchBodyResult, ResultSummary
8
9
  from _balder.previous_executor_mark import PreviousExecutorMark
9
10
 
10
11
  if TYPE_CHECKING:
@@ -55,7 +56,8 @@ class ExecutorTree(BasicExecutor):
55
56
  # ---------------------------------- PROTECTED METHODS -------------------------------------------------------------
56
57
 
57
58
  def _prepare_execution(self, show_discarded):
58
- pass
59
+ if not show_discarded:
60
+ self.update_inner_feature_reference_in_all_setups()
59
61
 
60
62
  def _body_execution(self, show_discarded):
61
63
  for cur_setup_executor in self.get_setup_executors():
@@ -139,6 +141,16 @@ class ExecutorTree(BasicExecutor):
139
141
  for cur_setup_executor in to_remove_executor:
140
142
  self._setup_executors.remove(cur_setup_executor)
141
143
 
144
+ def update_inner_feature_reference_in_all_setups(self):
145
+ """
146
+ This method iterates over all setups and triggers the method that updates the inner feature references.
147
+
148
+ This needs to be done on ExecutorTree level, because this reference should also be accessible within session
149
+ fixtures (in case they have setup scope).
150
+ """
151
+ for cur_setup_executor in self.get_setup_executors():
152
+ cur_setup_executor.update_inner_referenced_feature_instances()
153
+
142
154
  def execute(self, show_discarded=False) -> None:
143
155
  """
144
156
  This method executes this branch of the tree
@@ -163,12 +175,12 @@ class ExecutorTree(BasicExecutor):
163
175
  print_line(end_text)
164
176
  summary = self.testsummary()
165
177
  is_first = True
166
- for cur_key, cur_val in summary.items():
178
+ for cur_field in fields(ResultSummary):
167
179
  if is_first:
168
180
  is_first = False
169
181
  else:
170
182
  print(" | ", end="")
171
- print(f"TOTAL {cur_key.value}: {cur_val}", end="")
183
+ print(f"TOTAL {cur_field.name}: {getattr(summary, cur_field.name)}", end="")
172
184
  print("")
173
185
 
174
186
  def print_tree(self, show_discarded=False) -> None:
@@ -6,6 +6,7 @@ from _balder.utils import get_class_that_defines_method
6
6
  from _balder.executor.basic_executor import BasicExecutor
7
7
  from _balder.executor.variation_executor import VariationExecutor
8
8
  from _balder.previous_executor_mark import PreviousExecutorMark
9
+ from _balder.controllers.scenario_controller import ScenarioController
9
10
 
10
11
  if TYPE_CHECKING:
11
12
  from _balder.scenario import Scenario
@@ -64,6 +65,10 @@ class ScenarioExecutor(BasicExecutor):
64
65
  """returns the :class:`Scenario` class that belongs to this executor"""
65
66
  return self._base_scenario_class
66
67
 
68
+ @property
69
+ def base_scenario_controller(self) -> ScenarioController:
70
+ return ScenarioController.get_for(self.base_scenario_class.__class__)
71
+
67
72
  @property
68
73
  def fixture_manager(self) -> FixtureManager:
69
74
  """returns the current active fixture manager that belongs to this scenario executor"""
@@ -5,6 +5,9 @@ from _balder.testresult import ResultState, BranchBodyResult
5
5
  from _balder.executor.basic_executor import BasicExecutor
6
6
  from _balder.executor.scenario_executor import ScenarioExecutor
7
7
  from _balder.previous_executor_mark import PreviousExecutorMark
8
+ from _balder.controllers.setup_controller import SetupController
9
+ from _balder.controllers.device_controller import DeviceController
10
+ from _balder.controllers.feature_controller import FeatureController
8
11
 
9
12
  if TYPE_CHECKING:
10
13
  from _balder.setup import Setup
@@ -58,6 +61,10 @@ class SetupExecutor(BasicExecutor):
58
61
  """returns the base :class:`Setup` that belongs to this executor"""
59
62
  return self._base_setup_class
60
63
 
64
+ @property
65
+ def base_setup_controller(self) -> SetupController:
66
+ return SetupController.get_for(self.base_setup_class.__class__)
67
+
61
68
  @property
62
69
  def fixture_manager(self) -> FixtureManager:
63
70
  """returns the current active fixture manager for this executor"""
@@ -84,6 +91,34 @@ class SetupExecutor(BasicExecutor):
84
91
 
85
92
  # ---------------------------------- METHODS -----------------------------------------------------------------------
86
93
 
94
+ def update_inner_referenced_feature_instances(self):
95
+ """
96
+ This method ensures that all inner referenced feature instances of all devices that are used in this setup are
97
+ set to the correct feature instance. For every existing device, this method goes trough all assigned features
98
+ and checks for a inner-referenced feature. It makes sure, that every inner-referenced feature variable has the
99
+ final assigned setup feature that belongs to it.
100
+
101
+ # TODO check where we validate that inner references feature exists in setup
102
+ """
103
+ for cur_setup_device in self.base_setup_controller.get_all_abs_inner_device_classes():
104
+ # these features are subclasses of the real defined one (because they are already the replaced ones)
105
+ all_device_features = DeviceController.get_for(cur_setup_device).get_all_instantiated_feature_objects()
106
+ all_instantiated_feature_objs_of_this_dev = [cur_feature for _, cur_feature in all_device_features.items()]
107
+ for _, cur_feature in all_device_features.items():
108
+ cur_feature_controller = FeatureController.get_for(cur_feature.__class__)
109
+ # now check the inner referenced features of this feature and check if that exists in the device
110
+ for cur_ref_feature_name, cur_ref_feature in \
111
+ cur_feature_controller.get_inner_referenced_features().items():
112
+ potential_candidates = [
113
+ candidate_feature for candidate_feature in all_instantiated_feature_objs_of_this_dev
114
+ if isinstance(candidate_feature, cur_ref_feature.__class__)]
115
+ if len(potential_candidates) != 1:
116
+ raise RuntimeError("found none or more than one potential replacing candidates")
117
+ replacing_candidate = potential_candidates[0]
118
+ # because `cur_feature` is only the object instance, the value will be overwritten only for this
119
+ # object
120
+ setattr(cur_feature, cur_ref_feature_name, replacing_candidate)
121
+
87
122
  def get_scenario_executors(self) -> List[ScenarioExecutor]:
88
123
  """returns a list with all scenario executors that belongs to this setup executor"""
89
124
  return self._scenario_executors
@@ -5,7 +5,7 @@ import inspect
5
5
  import logging
6
6
  from _balder.device import Device
7
7
  from _balder.connection import Connection
8
- from _balder.testresult import ResultState, BranchBodyResult
8
+ from _balder.testresult import ResultState, BranchBodyResult, ResultSummary
9
9
  from _balder.executor.basic_executor import BasicExecutor
10
10
  from _balder.executor.testcase_executor import TestcaseExecutor
11
11
  from _balder.previous_executor_mark import PreviousExecutorMark
@@ -150,7 +150,6 @@ class VariationExecutor(BasicExecutor):
150
150
  self.determine_abs_variation_connections()
151
151
  self.update_scenario_device_feature_instances()
152
152
  self.update_active_vdevice_device_mappings_in_all_features()
153
- self.update_inner_referenced_feature_instances()
154
153
  self.exchange_unmapped_vdevice_references()
155
154
  self.update_vdevice_referenced_feature_instances()
156
155
  self.set_conn_dependent_methods()
@@ -283,17 +282,10 @@ class VariationExecutor(BasicExecutor):
283
282
 
284
283
  # ---------------------------------- METHODS -----------------------------------------------------------------------
285
284
 
286
- def testsummary(self):
285
+ def testsummary(self) -> ResultSummary:
287
286
  if self.can_be_applied():
288
287
  return super().testsummary()
289
- return {
290
- ResultState.NOT_RUN: 0,
291
- ResultState.FAILURE: 0,
292
- ResultState.ERROR: 0,
293
- ResultState.SUCCESS: 0,
294
- ResultState.SKIP: 0,
295
- ResultState.COVERED_BY: 0
296
- }
288
+ return ResultSummary()
297
289
 
298
290
  def get_testcase_executors(self) -> List[TestcaseExecutor]:
299
291
  """returns all sub testcase executors that belongs to this variation-executor"""
@@ -570,34 +562,6 @@ class VariationExecutor(BasicExecutor):
570
562
  for cur_feature, cur_original_mapping in cur_feature_mapping_dict.items():
571
563
  cur_feature.active_vdevices = cur_original_mapping
572
564
 
573
- def update_inner_referenced_feature_instances(self):
574
- """
575
- This method ensures that all inner referenced feature instances of the used feature object, will be replaced
576
- with the related feature instances of the device object itself.
577
-
578
- .. note::
579
- Note that this method expects that the true defined scenario features are already replaced with the real
580
- setup features. So the method requires that the method `update_scenario_device_feature_instances()` was
581
- called before.
582
- """
583
- for scenario_device, _ in self._base_device_mapping.items():
584
- # these features are subclasses of the real defined one (because they are already the replaced ones)
585
- all_device_features = DeviceController.get_for(scenario_device).get_all_instantiated_feature_objects()
586
- all_instantiated_feature_objs = [cur_feature for _, cur_feature in all_device_features.items()]
587
- for _, cur_feature in all_device_features.items():
588
- cur_feature_controller = FeatureController.get_for(cur_feature.__class__)
589
- # now check the inner referenced features of this feature and check if that exists in the device
590
- for cur_ref_feature_name, cur_ref_feature in \
591
- cur_feature_controller.get_inner_referenced_features().items():
592
- potential_candidates = [candidate_feature for candidate_feature in all_instantiated_feature_objs
593
- if isinstance(candidate_feature, cur_ref_feature.__class__)]
594
- if len(potential_candidates) != 1:
595
- raise RuntimeError("found none or more than one potential replacing candidates")
596
- replacing_candidate = potential_candidates[0]
597
- # because `cur_feature` is only the object instance, the value will be overwritten only for this
598
- # object
599
- setattr(cur_feature, cur_ref_feature_name, replacing_candidate)
600
-
601
565
  def exchange_unmapped_vdevice_references(self):
602
566
  """
603
567
  This method exchanges all :class:`VDevice` references to an instance of :class:`UnmappedVDevice` if the
@@ -722,10 +686,7 @@ class VariationExecutor(BasicExecutor):
722
686
  if cur_scenario_device not in abs_var_scenario_device_cnns.keys():
723
687
  abs_var_scenario_device_cnns[cur_scenario_device] = {}
724
688
 
725
- if cur_cnn.from_device == cur_scenario_device:
726
- cur_to_device = cur_cnn.to_device
727
- else:
728
- cur_to_device = cur_cnn.from_device
689
+ cur_to_device, _ = cur_cnn.get_conn_partner_of(cur_scenario_device)
729
690
 
730
691
  if cur_to_device not in abs_var_scenario_device_cnns[cur_scenario_device].keys():
731
692
  abs_var_scenario_device_cnns[cur_scenario_device][cur_to_device] = []
_balder/testresult.py CHANGED
@@ -1,4 +1,6 @@
1
1
  from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, fields
2
4
  from typing import TYPE_CHECKING, List, Union
3
5
 
4
6
  from enum import Enum
@@ -12,21 +14,21 @@ class ResultState(Enum):
12
14
  enumeration that describes the possible results of a testcase-/fixture-executor
13
15
  """
14
16
  # this state will be assigned if the executor doesn't run yet
15
- NOT_RUN = 'NOT_RUN'
17
+ NOT_RUN = 'not_run'
16
18
  # this state will be assigned if the test fails (only assignable to :class:`TestcaseExecutor`)
17
- FAILURE = 'FAILURE'
19
+ FAILURE = 'failure'
18
20
  # this state will be assigned if the executor can not be executed because the fixture fails (only possible in
19
21
  # construction part of fixtures, if the error occurs in teardown the next higher executer get this state) - will be
20
22
  # assigned to the executor which has the fixture that fails
21
- ERROR = 'ERROR'
23
+ ERROR = 'error'
22
24
  # this state will be assigned if the executor was executed successfully (session fixture and teardown fixture; for
23
25
  # :class:`TestcaseExecutor` also the testcase itself)
24
- SUCCESS = 'SUCCESS'
26
+ SUCCESS = 'success'
25
27
  # this state will be assigned if the executor was skipped
26
- SKIP = 'SKIP'
28
+ SKIP = 'skip'
27
29
  # this state will be assigned if the executor is covered by another executor and wasn't executed (only assignable
28
30
  # to :class:`ScenarioExecutor` and :class:`TestcaseExecutor`)
29
- COVERED_BY = 'COVERED_BY'
31
+ COVERED_BY = 'covered_by'
30
32
 
31
33
  @staticmethod
32
34
  def priority_order() -> List[ResultState]:
@@ -128,3 +130,33 @@ class TestcaseResult(_SettableResult):
128
130
  #: contains the possible values that can be set for this Result type
129
131
  ALLOWED_STATES = [ResultState.NOT_RUN, ResultState.FAILURE, ResultState.SUCCESS, ResultState.SKIP,
130
132
  ResultState.COVERED_BY]
133
+
134
+ @dataclass
135
+ class ResultSummary:
136
+ """
137
+ object that holds the test results for multiple tests like on branch or global level
138
+ """
139
+ # this state will be assigned if the executor doesn't run yet
140
+ not_run: int = 0
141
+ # this state will be assigned if the test fails (only assignable to :class:`TestcaseExecutor`)
142
+ failure: int = 0
143
+ # this state will be assigned if the executor can not be executed because the fixture fails (only possible in
144
+ # construction part of fixtures, if the error occurs in teardown the next higher executer get this state) - will be
145
+ # assigned to the executor which has the fixture that fails
146
+ error: int = 0
147
+ # this state will be assigned if the executor was executed successfully (session fixture and teardown fixture; for
148
+ # :class:`TestcaseExecutor` also the testcase itself)
149
+ success: int = 0
150
+ # this state will be assigned if the executor was skipped
151
+ skip: int = 0
152
+ # this state will be assigned if the executor is covered by another executor and wasn't executed (only assignable
153
+ # to :class:`ScenarioExecutor` and :class:`TestcaseExecutor`)
154
+ covered_by: int = 0
155
+
156
+ def __add__(self, other) -> ResultSummary:
157
+ new_summary = ResultSummary()
158
+ for cur_field in fields(self.__class__):
159
+ self_val = getattr(self, cur_field.name)
160
+ other_val = getattr(other, cur_field.name)
161
+ setattr(new_summary, cur_field.name, self_val + other_val)
162
+ return new_summary
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: baldertest
3
- Version: 0.1.0b8
3
+ Version: 0.1.0b9
4
4
  Summary: balder: reusable scenario based test framework
5
5
  Home-page: https://docs.balder.dev
6
6
  Author: Max Stahlschmidt and others
@@ -1,9 +1,9 @@
1
1
  _balder/__init__.py,sha256=Qk4wkVInPlXLFV36Yco5K7PDawJoeeWQVakzj6g5pmA,195
2
- _balder/_version.py,sha256=IWxE2VF11qpQh0kbBboGimtTYBFAxLyQVgAo81Of17o,413
2
+ _balder/_version.py,sha256=xdDxoDc8nbJHb9-aJOnXPcJO9u_wtajm1m932_7HjoI,413
3
3
  _balder/balder_plugin.py,sha256=EQzJP1dwwVDydhMLJtAmTCXOczlDuXBJur05lalmK_k,3136
4
- _balder/balder_session.py,sha256=6Y2o2MR78MZHIsGCkSA9BLMu4pNhB1i8Y1HWMQOQtAc,16130
4
+ _balder/balder_session.py,sha256=WPOcarZQhTzMeAQt-hRqI8GtXN5TdMIqzyhgYD2h4rw,16079
5
5
  _balder/balder_settings.py,sha256=U96PVep7dGSaTXrMfeZMYf6oCIcEDPEqrBlFcoX476s,582
6
- _balder/collector.py,sha256=G_vrZ0nQRbIw6IjKOlGC9y7EgEn1oE7QjsJrW8t1EIs,42147
6
+ _balder/collector.py,sha256=T_7LO8ZNty8EyOmM-U-uhU9-umdAv1fbuMVNjQWUwj0,42156
7
7
  _balder/connection.py,sha256=MNazK97CIEJCA4o1krjKjtilVhOYMWD8TZT0YT5nCJs,71778
8
8
  _balder/decorator_connect.py,sha256=TvyJNIslBAYVQWhsfSeFgXKp_DP7sZF1BmcP6RhIdKo,5988
9
9
  _balder/decorator_covered_by.py,sha256=Y6WMUuyn_uvFkjGfbts8OE5Bsir_7LTRB-jxYGaYk4Y,4069
@@ -23,7 +23,7 @@ _balder/routing_path.py,sha256=6MJkhzBTHow2ESXzKQ2otwRFbPcKhLTYVy-zh7c5HeE,17172
23
23
  _balder/scenario.py,sha256=ATowBUl2HYQBmJHZ-eBpliqjPsWPnZAme9kwIeX3Tak,840
24
24
  _balder/setup.py,sha256=zSgtzNIWTVBjiZ5mn-qfpqIAnP3Im73t3Lqoaw0gWEI,763
25
25
  _balder/solver.py,sha256=qgcCRyLg3nsO2d3H0pukxmm2oe_h6t0pBGyZ-FgQYKc,11998
26
- _balder/testresult.py,sha256=6yo3EcuLlpM23vdrYzn5VDcG35qelAQudmyoLpwZoHM,5251
26
+ _balder/testresult.py,sha256=byJD3F84TNH40k30pjnxeLHXAAE-lqbVlk1JOSBtdNo,6783
27
27
  _balder/unmapped_vdevice.py,sha256=oKr01YVTLViWtZkYz8kx8ccTx-KmwgNrHuQqqD4eLQw,513
28
28
  _balder/utils.py,sha256=2kcX6bZIJW9Z8g-Hv0ue2mdOLBQYq4T2XSZpH2in1MQ,3092
29
29
  _balder/vdevice.py,sha256=fc2xuMnTuN1RyfWh9mqFgLdSO9yGA75eERobTXUQ9JA,215
@@ -33,18 +33,18 @@ _balder/controllers/__init__.py,sha256=UNb6QzMj4TqPI15OSvXyUJlA-NSai0CKkQhV5JIsb
33
33
  _balder/controllers/base_device_controller.py,sha256=g-vY2SqKFUC9yGOvHLfbdmILT3sK2YyaWKSfvTRcC0o,3174
34
34
  _balder/controllers/controller.py,sha256=XGRE5LKWxxftEf-bZODvKxXwULu09iG131wMwRoz4Fk,803
35
35
  _balder/controllers/device_controller.py,sha256=bT8c0_9UmrAmzuZ-dsleSnw2pIppfITDG4ttEZjWlC8,23477
36
- _balder/controllers/feature_controller.py,sha256=Dsjdbcs6OFQZDCJjOstqOghr3S88u-RdJkXukZHHDfU,42427
37
- _balder/controllers/normal_scenario_setup_controller.py,sha256=mJdqMP7xlhtloQgKBAmgWe5a-oyYqmruUKiL-rLOe08,22144
36
+ _balder/controllers/feature_controller.py,sha256=jaIbKbiEOdYRpYWuGdaByQBtlThK-u7OAr_xYhAfnEg,43737
37
+ _balder/controllers/normal_scenario_setup_controller.py,sha256=cF2U-tC3LEyWdZDqZP_mN3Q_7uIzg9jiY_J--Pi5kk8,21877
38
38
  _balder/controllers/scenario_controller.py,sha256=gpN_wxEYcHlh6DVk7pRbPj_x2cmM6iIAskcpLstQo2g,17973
39
39
  _balder/controllers/setup_controller.py,sha256=iNIMFjawYJWaSToUUfpmRK6ssycPyZGNlcvms8c7GKM,7135
40
40
  _balder/controllers/vdevice_controller.py,sha256=6-PidCKgvUteZVJsbGkKX69f3cYYYnolONl5Gja16W8,5777
41
41
  _balder/executor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
- _balder/executor/basic_executor.py,sha256=qINIXLSL8uO3QYRXT3kb5_sG6Ub6DOKyvw21EKYN13Y,11596
43
- _balder/executor/executor_tree.py,sha256=0vGGO2HsXRlxRB6zJJCM0vPIOPVU8VrjqLDXOqfxavw,9784
44
- _balder/executor/scenario_executor.py,sha256=PopGXe6cwkSoNLrRMCWOTO320mrXf5DVMZSmRu-TgHY,10868
45
- _balder/executor/setup_executor.py,sha256=VEU0qAy9e3A0qjKpmiV5MbAdqRkoiysMvR4zq_xvL0o,5845
42
+ _balder/executor/basic_executor.py,sha256=PYuQ1TKXKnbnQirCmayjDSyPyBmqJws1HWqkHmGKZtw,11137
43
+ _balder/executor/executor_tree.py,sha256=nEZ2bwWuayPZQrGSucFiDzuFSrYDnUVzqnVCtDLq2Ys,10439
44
+ _balder/executor/scenario_executor.py,sha256=3j5lAFCA4zCxhivjMPFGlWMi_ieZGkdwnZ_JQoAt4Rw,11094
45
+ _balder/executor/setup_executor.py,sha256=FsPTPsXZMoVB7xibEpCcwjC-BpkfGVZmx5lVbuebduw,8326
46
46
  _balder/executor/testcase_executor.py,sha256=jNfACO-AuOktIgCVcsavh0rHbUr5MmI-jML-LPMvo0w,6639
47
- _balder/executor/variation_executor.py,sha256=lwSAaDQKsXqQSbg3udLDClctxvIZSIKNj1BgR8fWNcE,55517
47
+ _balder/executor/variation_executor.py,sha256=Ms8dfZPIL5-sYzMg2c1-WANDz8ZBHqNHXgegDobm7Gg,53106
48
48
  _balder/objects/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
49
  _balder/objects/connections/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
50
  _balder/objects/connections/osi_1_physical.py,sha256=74lKWJd6ETEtvNXH0_dmTbkZlStJ_af218pQkUht0aA,2189
@@ -60,9 +60,9 @@ balder/__init__.py,sha256=BfbdkW_CZCXWGqtdg1gpAjO0AY8b4h-P-flWsIMG-X0,1003
60
60
  balder/connections.py,sha256=H6rf7UsiVY_FeZLngZXCT9WDw9cQqpiDiPbz_0J4yjM,2331
61
61
  balder/devices.py,sha256=zupHtz8yaiEjzR8CrvgZU-RzsDQcZFeN5mObfhtjwSw,173
62
62
  balder/exceptions.py,sha256=z_vlipJIsFwwJy9Ae_oGDJGPTINiAInMNZuCvEy6SUE,1884
63
- baldertest-0.1.0b8.dist-info/LICENSE,sha256=Daz9qTpqbiq-klWb2Q9lYOmn3rJ5oIQnbs62sGcqOZ4,1084
64
- baldertest-0.1.0b8.dist-info/METADATA,sha256=nMxgYubNYoSw45qZmXUlk13GJ5v93zOXCI__mlVVSs4,15783
65
- baldertest-0.1.0b8.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
66
- baldertest-0.1.0b8.dist-info/entry_points.txt,sha256=hzqu_nrMKTCi5IJqzS1fhIXWEiL7mTGZ-kgj2lUYlRU,65
67
- baldertest-0.1.0b8.dist-info/top_level.txt,sha256=RUkIBkNLqHMemx2C9aEpoS65dpqb6_jU-oagIPxGQEA,15
68
- baldertest-0.1.0b8.dist-info/RECORD,,
63
+ baldertest-0.1.0b9.dist-info/LICENSE,sha256=Daz9qTpqbiq-klWb2Q9lYOmn3rJ5oIQnbs62sGcqOZ4,1084
64
+ baldertest-0.1.0b9.dist-info/METADATA,sha256=HzdUqwAR2FIIYoAWg6RxXoFOJzUOqpkxcA7q-V3SHbM,15783
65
+ baldertest-0.1.0b9.dist-info/WHEEL,sha256=mguMlWGMX-VHnMpKOjjQidIo1ssRlCFu4a4mBpz1s2M,91
66
+ baldertest-0.1.0b9.dist-info/entry_points.txt,sha256=hzqu_nrMKTCi5IJqzS1fhIXWEiL7mTGZ-kgj2lUYlRU,65
67
+ baldertest-0.1.0b9.dist-info/top_level.txt,sha256=RUkIBkNLqHMemx2C9aEpoS65dpqb6_jU-oagIPxGQEA,15
68
+ baldertest-0.1.0b9.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (70.1.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5