diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-04-13 10:07:12 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-04-13 10:24:16 +0200 |
commit | 9e7ee2687d8f0189564b9e72a2d598444a8433d2 (patch) | |
tree | 427955f68e9a72eeb2fd86aaaf48c25cc01deea3 /rtemsspec | |
parent | spec: New cases for /rtems/sem/req/obtain (diff) | |
download | rtems-central-9e7ee2687d8f0189564b9e72a2d598444a8433d2.tar.bz2 |
validation: Add get_post_conditions()
Diffstat (limited to 'rtemsspec')
-rw-r--r-- | rtemsspec/tests/spec-validation/action2.yml | 10 | ||||
-rw-r--r-- | rtemsspec/tests/test_validation.py | 19 | ||||
-rw-r--r-- | rtemsspec/validation.py | 49 |
3 files changed, 76 insertions, 2 deletions
diff --git a/rtemsspec/tests/spec-validation/action2.yml b/rtemsspec/tests/spec-validation/action2.yml index 822a4701..8c269a12 100644 --- a/rtemsspec/tests/spec-validation/action2.yml +++ b/rtemsspec/tests/spec-validation/action2.yml @@ -272,4 +272,14 @@ transition-map: - B0 C: - C0 +- enabled-by: BOOM + post-conditions: + A: N/A + B: B0 + pre-conditions: + A: N/A + B: + - B0 + C: + - C0 type: requirement diff --git a/rtemsspec/tests/test_validation.py b/rtemsspec/tests/test_validation.py index 938762c3..a35ff371 100644 --- a/rtemsspec/tests/test_validation.py +++ b/rtemsspec/tests/test_validation.py @@ -49,8 +49,13 @@ def test_validation(tmpdir): assert len(list(transition_map.get_variants([]))) == 36 assert len(list(transition_map.get_variants(["RTEMS_MULTIPROCESSING" ]))) == 36 + assert len(list(transition_map.get_post_conditions([]))) == 4 + assert len( + list(transition_map.get_post_conditions(["RTEMS_MULTIPROCESSING" + ]))) == 5 transition_map = TransitionMap(item_cache["/action2"]) assert transition_map.skip_idx_to_name(1) == "SkipReason" + assert len(list(transition_map.get_post_conditions(["BOOM"]))) == 6 generate(validation_config, item_cache) @@ -2109,14 +2114,24 @@ static const Action2_Entry Action2_Entries[] = { { 0, 1, 0, 0, Action2_Post_A_A1, Action2_Post_B_NA }, { 0, 0, 0, 0, Action2_Post_A_A2, Action2_Post_B_B0 }, - { 0, 0, 0, 0, Action2_Post_A_A1, Action2_Post_B_B0 }, { 1, 0, 0, 0, Action2_Post_A_NA, Action2_Post_B_NA }, + { 0, 0, 0, 0, Action2_Post_A_A1, Action2_Post_B_B0 }, +#if defined(BOOM) + { 0, 1, 0, 0, Action2_Post_A_NA, Action2_Post_B_B0 }, +#else + { 0, 0, 0, 0, Action2_Post_A_A1, Action2_Post_B_B0 }, +#endif +#if defined(BOOM) + { 0, 1, 0, 0, Action2_Post_A_NA, Action2_Post_B_B0 }, +#else + { 0, 0, 0, 0, Action2_Post_A_A2, Action2_Post_B_B0 }, +#endif { 0, 0, 0, 0, Action2_Post_A_A3, Action2_Post_B_B0 } }; static const uint8_t Action2_Map[] = { - 2, 2, 2, 0, 0, 0, 1, 1, 1, 1, 1, 4, 0, 0, 0, 3, 3, 3 + 4, 3, 3, 0, 0, 0, 1, 1, 1, 5, 1, 6, 0, 0, 0, 2, 2, 2 }; static size_t Action2_Scope( void *arg, char *buf, size_t n ) diff --git a/rtemsspec/validation.py b/rtemsspec/validation.py index 944764f6..baff5305 100644 --- a/rtemsspec/validation.py +++ b/rtemsspec/validation.py @@ -615,6 +615,10 @@ _POST_COND_OP = { "specified-by": _post_cond_specified_by, } +PostCond = Tuple[int, ...] + +PreCondsOfPostCond = List[Tuple[List[int], ...]] + class TransitionMap: """ Representation of an action requirement transition map. """ @@ -677,6 +681,51 @@ class TransitionMap: variant = transitions[0] yield map_idx, variant + def get_post_conditions( + self, enabled: List[str] + ) -> Iterator[Tuple[PostCond, PreCondsOfPostCond]]: + """ + Yields tuples of post-condition variants and the corresponding + pre-condition variants which are enabled by the enabled list. + + The first entry of the post-condition variant is the skip index. The + remaining entries are post-condition indices. The pre-condition + variants are a list of tuples. Each tuple entry corresponds to a + pre-condition and provides a list of corresponding pre-condition state + indices. + """ + entries = {} # type: Dict[PostCond, PreCondsOfPostCond] + for map_idx, variant in self.get_variants(enabled): + key = (variant.skip, ) + variant.post_cond + entry = entries.setdefault(key, []) + entry.append( + tuple([state] for state in self.map_idx_to_pre_co_states( + map_idx, variant.pre_cond_na))) + for post_cond, pre_conds in sorted(entries.items(), + key=lambda x: (x[0][0], len(x[1]))): + while True: + last = pre_conds[0] + combined_pre_conds = [last] + combined_count = 0 + for row in pre_conds[1:]: + if row == last: + continue + diff = [ + index for index, states in enumerate(last) + if states != row[index] + ] + if len(diff) == 1: + index = diff[0] + combined_count += 1 + last[index].extend(row[index]) + else: + combined_pre_conds.append(row) + last = row + pre_conds = combined_pre_conds + if combined_count == 0: + break + yield post_cond, pre_conds + def _post_process(self) -> None: for map_idx, transitions in enumerate(self): if not transitions or not isinstance( |