summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2021-09-13 15:05:11 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2021-09-14 16:00:54 +0200
commit415e8e25fc054033579c6b8db6ac4537eeb05d42 (patch)
treefd8a0042767897133a220581a809c6ab1b439bd7
parentvalidation: Fix transition variants skip (diff)
downloadrtems-central-415e8e25fc054033579c6b8db6ac4537eeb05d42.tar.bz2
validation: Fix pre-condition state handling
-rw-r--r--rtemsspec/tests/test_validation.py50
-rw-r--r--rtemsspec/transitionmap.py6
-rw-r--r--rtemsspec/validation.py51
3 files changed, 81 insertions, 26 deletions
diff --git a/rtemsspec/tests/test_validation.py b/rtemsspec/tests/test_validation.py
index a5b252b1..2bc8b934 100644
--- a/rtemsspec/tests/test_validation.py
+++ b/rtemsspec/tests/test_validation.py
@@ -1888,6 +1888,12 @@ typedef struct {
struct {
/**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 3 ];
+
+ /**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 3 ];
@@ -2247,24 +2253,33 @@ static void Action2_Skip( Action2_Context *ctx, size_t index )
switch ( index + 1 ) {
case 1:
- increment *= Action2_Pre_B_NA - ctx->Map.pcs[ 1 ];
- ctx->Map.pcs[ 1 ] = Action2_Pre_B_NA - 1;
+ increment *= Action2_Pre_B_NA - ctx->Map.pci[ 1 ];
+ ctx->Map.pci[ 1 ] = Action2_Pre_B_NA - 1;
/* Fall through */
case 2:
- increment *= Action2_Pre_C_NA - ctx->Map.pcs[ 2 ];
- ctx->Map.pcs[ 2 ] = Action2_Pre_C_NA - 1;
+ increment *= Action2_Pre_C_NA - ctx->Map.pci[ 2 ];
+ ctx->Map.pci[ 2 ] = Action2_Pre_C_NA - 1;
break;
}
ctx->Map.index += increment - 1;
}
+static void Action2_SetPreConditionStates( Action2_Context *ctx )
+{
+ if ( ctx->Map.entry.Pre_A_NA ) {
+ ctx->Map.pcs[ 0 ] = Action2_Pre_A_NA;
+ } else {
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ }
+
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+}
+
static void Action2_TestVariant( Action2_Context *ctx )
{
- Action2_Pre_A_Prepare(
- ctx,
- ctx->Map.entry.Pre_A_NA ? Action2_Pre_A_NA : ctx->Map.pcs[ 0 ]
- );
+ Action2_Pre_A_Prepare( ctx, ctx->Map.pcs[ 0 ] );
if ( ctx->Map.skip ) {
Action2_Skip( ctx, 0 );
@@ -2294,19 +2309,19 @@ void Action2_Run( int *a, int b, int *c )
ctx->Map.index = 0;
for (
- ctx->Map.pcs[ 0 ] = Action2_Pre_A_A0;
- ctx->Map.pcs[ 0 ] < Action2_Pre_A_NA;
- ++ctx->Map.pcs[ 0 ]
+ ctx->Map.pci[ 0 ] = Action2_Pre_A_A0;
+ ctx->Map.pci[ 0 ] < Action2_Pre_A_NA;
+ ++ctx->Map.pci[ 0 ]
) {
for (
- ctx->Map.pcs[ 1 ] = Action2_Pre_B_B0;
- ctx->Map.pcs[ 1 ] < Action2_Pre_B_NA;
- ++ctx->Map.pcs[ 1 ]
+ ctx->Map.pci[ 1 ] = Action2_Pre_B_B0;
+ ctx->Map.pci[ 1 ] < Action2_Pre_B_NA;
+ ++ctx->Map.pci[ 1 ]
) {
for (
- ctx->Map.pcs[ 2 ] = Action2_Pre_C_C0;
- ctx->Map.pcs[ 2 ] < Action2_Pre_C_NA;
- ++ctx->Map.pcs[ 2 ]
+ ctx->Map.pci[ 2 ] = Action2_Pre_C_C0;
+ ctx->Map.pci[ 2 ] < Action2_Pre_C_NA;
+ ++ctx->Map.pci[ 2 ]
) {
ctx->Map.entry = Action2_PopEntry( ctx );
@@ -2314,6 +2329,7 @@ void Action2_Run( int *a, int b, int *c )
continue;
}
+ Action2_SetPreConditionStates( ctx );
Action2_Prepare( ctx );
Action2_TestVariant( ctx );
Action2_Cleanup( ctx );
diff --git a/rtemsspec/transitionmap.py b/rtemsspec/transitionmap.py
index 7801ad43..9d6ab8a3 100644
--- a/rtemsspec/transitionmap.py
+++ b/rtemsspec/transitionmap.py
@@ -383,6 +383,12 @@ class TransitionMap:
map_idx //= count
return tuple(reversed(co_states))
+ def has_pre_co_not_applicable(self) -> bool:
+ """
+ Returns true, if there are N/A pre-conditions, otherwise false.
+ """
+ return sum(self.pre_co_summary[1:]) > 0
+
def pre_co_name_to_co_idx(self, co_name: str) -> int:
"""
Maps the pre-condition name to the associated pre-condition index.
diff --git a/rtemsspec/validation.py b/rtemsspec/validation.py
index a5ac6046..a4d284f5 100644
--- a/rtemsspec/validation.py
+++ b/rtemsspec/validation.py
@@ -535,6 +535,7 @@ class _ActionRequirementTestItem(_TestItem):
item["pre-conditions"])
self._post_co_idx_to_enum = _to_enum(f"{self.ident}_Post",
item["post-conditions"])
+ self._pci = "pcs"
def _add_pre_condition_descriptions(self, content: CContent) -> None:
for condition in self["pre-conditions"]:
@@ -559,6 +560,11 @@ class _ActionRequirementTestItem(_TestItem):
super().add_default_context_members(content)
content.add("struct {")
with content.indent():
+ if self._pci == "pci":
+ content.add_description_block(
+ "This member defines the pre-condition indices "
+ "for the next action.", None)
+ content.add(f"size_t pci[ {self._pre_co_count} ];")
content.add_description_block(
"This member defines the pre-condition states "
"for the next action.", None)
@@ -606,10 +612,10 @@ class _ActionRequirementTestItem(_TestItem):
for index, enum in enumerate(self._pre_co_idx_to_enum[1:], 1):
content.add(f"case {index}:")
with content.indent():
- pcs = f"ctx->Map.pcs[ {index} ]"
+ pci = f"ctx->Map.{self._pci}[ {index} ]"
content.append([
- f"increment *= {enum[-1]} - {pcs};",
- f"{pcs} = {enum[-1]} - 1;", fall_through
+ f"increment *= {enum[-1]} - {pci};",
+ f"{pci} = {enum[-1]} - 1;", fall_through
])
content.lines[-1] = content.lines[-1].replace(
fall_through, "break;")
@@ -618,13 +624,9 @@ class _ActionRequirementTestItem(_TestItem):
def _add_test_variant(self, content: CContent,
transition_map: TransitionMap) -> None:
entry = "ctx->Map.entry"
- for index, pre_co in enumerate(self._item["pre-conditions"]):
+ for index in range(self._pre_co_count):
content.gap = False
state = f"ctx->Map.pcs[ {index} ]"
- if transition_map.pre_co_summary[index + 1]:
- enum_na = self._pre_co_idx_to_enum[index][-1]
- name = pre_co["name"]
- state = f"{entry}.Pre_{name}_NA ? {enum_na} : {state}"
prepare = f"{self._pre_co_idx_to_enum[index][0]}_Prepare"
content.call_function(None, prepare, ["ctx", state])
if self._pre_co_skip.get(index, False):
@@ -648,6 +650,10 @@ class _ActionRequirementTestItem(_TestItem):
with content.condition(f"{entry}.Skip"):
content.append("continue;")
content.add_blank_line()
+ if transition_map.has_pre_co_not_applicable():
+ name = f"{self.ident}_SetPreConditionStates"
+ content.gap = False
+ content.call_function(None, name, ["ctx"])
self._add_call(content, "test-prepare", "Prepare")
content.gap = False
content.call_function(None, f"{self.ident}_TestVariant", ["ctx"])
@@ -656,7 +662,7 @@ class _ActionRequirementTestItem(_TestItem):
def _add_for_loops(self, content: CContent, transition_map: TransitionMap,
index: int) -> None:
if index < self._pre_co_count:
- var = f"ctx->Map.pcs[ {index} ]"
+ var = f"ctx->Map.{self._pci}[ {index} ]"
begin = self._pre_co_idx_to_enum[index][1]
end = self._pre_co_idx_to_enum[index][-1]
with content.for_loop(f"{var} = {begin}", f"{var} < {end}",
@@ -665,6 +671,29 @@ class _ActionRequirementTestItem(_TestItem):
else:
self._add_loop_body(content, transition_map)
+ def _add_set_pre_co_states(self, content: CContent,
+ transition_map: TransitionMap) -> None:
+ ret = "static void"
+ name = f"{self.ident}_SetPreConditionStates"
+ params = [f"{self.context} *ctx"]
+ with content.function(ret, name, params, align=True):
+ entry = "ctx->Map.entry"
+ gap = False
+ for index, pre_co in enumerate(self._item["pre-conditions"]):
+ pcs_pci = f"ctx->Map.pcs[ {index} ] = ctx->Map.pci[ {index} ];"
+ if transition_map.pre_co_summary[index + 1]:
+ is_na = f"{entry}.Pre_{pre_co['name']}_NA"
+ with content.first_condition(is_na):
+ enum_na = self._pre_co_idx_to_enum[index][-1]
+ content.add(f"ctx->Map.pcs[ {index} ] = {enum_na};")
+ with content.final_condition():
+ content.add(pcs_pci)
+ gap = True
+ else:
+ content.gap = gap
+ gap = False
+ content.add(pcs_pci)
+
def _add_test_case(self, content: CContent, transition_map: TransitionMap,
header: Dict[str, Any]) -> None:
ret = f"static inline {self.ident}_Entry"
@@ -678,6 +707,8 @@ class _ActionRequirementTestItem(_TestItem):
])
if self._pre_co_skip:
self._add_skip(content)
+ if transition_map.has_pre_co_not_applicable():
+ self._add_set_pre_co_states(content, transition_map)
with content.function("static void", f"{self.ident}_TestVariant",
[f"{self.context} *ctx"]):
self._add_test_variant(content, transition_map)
@@ -763,6 +794,8 @@ class _ActionRequirementTestItem(_TestItem):
_add_condition_enum(content, self._pre_co_idx_to_enum)
_add_condition_enum(content, self._post_co_idx_to_enum)
transition_map = TransitionMap(self.item)
+ if transition_map.has_pre_co_not_applicable():
+ self._pci = "pci"
transition_map.add_map_entry_type(content, self.ident)
instance = self.add_context(content)
self._add_pre_condition_descriptions(content)