summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2021-08-13 22:26:16 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2021-08-16 12:33:36 +0200
commit54e9530b503a0d5fc800c013df9263e621f5adab (patch)
treedc7fce540e772d896cbf08e07184c23a7ff3299b
parentvalidation: Simplify pre-condition N/A support (diff)
downloadrtems-central-54e9530b503a0d5fc800c013df9263e621f5adab.tar.bz2
validation: Move map index/entry to context
-rw-r--r--rtemsspec/tests/test_validation.py204
-rw-r--r--rtemsspec/transitionmap.py25
-rw-r--r--rtemsspec/validation.py67
3 files changed, 166 insertions, 130 deletions
diff --git a/rtemsspec/tests/test_validation.py b/rtemsspec/tests/test_validation.py
index 1fef4bfe..287ee3a2 100644
--- a/rtemsspec/tests/test_validation.py
+++ b/rtemsspec/tests/test_validation.py
@@ -258,6 +258,15 @@ typedef enum {
Directive_Post_Id_NA
} Directive_Post_Id;
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Name_NA : 1;
+ uint16_t Pre_Node_NA : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_Id : 3;
+} Directive_Entry;
+
/**
* @brief Test context for spec:/directive test case.
*/
@@ -281,16 +290,27 @@ typedef struct {
rtems_id id_remote_task;
- /**
- * @brief This member defines the pre-condition states for the next action.
- */
- size_t pcs[ 3 ];
-
- /**
- * @brief This member indicates if the test action loop is currently
- * executed.
- */
- bool in_action_loop;
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 3 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ Directive_Entry entry;
+ } Map;
} Directive_Context;
static Directive_Context
@@ -599,7 +619,7 @@ static void Directive_Setup_Wrap( void *arg )
Directive_Context *ctx;
ctx = arg;
- ctx->in_action_loop = false;
+ ctx->Map.in_action_loop = false;
Directive_Setup( ctx );
}
@@ -618,7 +638,7 @@ static void Directive_Teardown_Wrap( void *arg )
Directive_Context *ctx;
ctx = arg;
- ctx->in_action_loop = false;
+ ctx->Map.in_action_loop = false;
Directive_Teardown( ctx );
}
@@ -627,15 +647,6 @@ static void Directive_Action( Directive_Context *ctx )
ctx->status = rtems_task_ident( ctx->name, ctx->node, ctx->id );
}
-typedef struct {
- uint16_t Skip : 1;
- uint16_t Pre_Name_NA : 1;
- uint16_t Pre_Node_NA : 1;
- uint16_t Pre_Id_NA : 1;
- uint16_t Post_Status : 3;
- uint16_t Post_Id : 3;
-} Directive_Entry;
-
static const Directive_Entry
Directive_Entries[] = {
{ 0, 0, 0, 0, Directive_Post_Status_InvAddr, Directive_Post_Id_NullPtr },
@@ -661,8 +672,8 @@ static size_t Directive_Scope( void *arg, char *buf, size_t n )
ctx = arg;
- if ( ctx->in_action_loop ) {
- return T_get_scope( Directive_PreDesc, buf, n, ctx->pcs );
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( Directive_PreDesc, buf, n, ctx->Map.pcs );
}
return 0;
@@ -676,8 +687,12 @@ static T_fixture Directive_Fixture = {
.initial_context = &Directive_Instance
};
-static inline Directive_Entry Directive_GetEntry( size_t index )
+static inline Directive_Entry Directive_PopEntry( Directive_Context *ctx )
{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
return Directive_Entries[
Directive_Map[ index ]
];
@@ -689,38 +704,34 @@ static inline Directive_Entry Directive_GetEntry( size_t index )
T_TEST_CASE_FIXTURE( Directive, &Directive_Fixture )
{
Directive_Context *ctx;
- size_t index;
ctx = T_fixture_context();
- ctx->in_action_loop = true;
- index = 0;
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
for (
- ctx->pcs[ 0 ] = Directive_Pre_Name_Invalid;
- ctx->pcs[ 0 ] < Directive_Pre_Name_NA;
- ++ctx->pcs[ 0 ]
+ ctx->Map.pcs[ 0 ] = Directive_Pre_Name_Invalid;
+ ctx->Map.pcs[ 0 ] < Directive_Pre_Name_NA;
+ ++ctx->Map.pcs[ 0 ]
) {
for (
- ctx->pcs[ 1 ] = Directive_Pre_Node_Local;
- ctx->pcs[ 1 ] < Directive_Pre_Node_NA;
- ++ctx->pcs[ 1 ]
+ ctx->Map.pcs[ 1 ] = Directive_Pre_Node_Local;
+ ctx->Map.pcs[ 1 ] < Directive_Pre_Node_NA;
+ ++ctx->Map.pcs[ 1 ]
) {
for (
- ctx->pcs[ 2 ] = Directive_Pre_Id_NullPtr;
- ctx->pcs[ 2 ] < Directive_Pre_Id_NA;
- ++ctx->pcs[ 2 ]
+ ctx->Map.pcs[ 2 ] = Directive_Pre_Id_NullPtr;
+ ctx->Map.pcs[ 2 ] < Directive_Pre_Id_NA;
+ ++ctx->Map.pcs[ 2 ]
) {
- Directive_Entry entry;
-
- entry = Directive_GetEntry( index );
- ++index;
+ ctx->Map.entry = Directive_PopEntry( ctx );
- Directive_Pre_Name_Prepare( ctx, ctx->pcs[ 0 ] );
- Directive_Pre_Node_Prepare( ctx, ctx->pcs[ 1 ] );
- Directive_Pre_Id_Prepare( ctx, ctx->pcs[ 2 ] );
+ Directive_Pre_Name_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ Directive_Pre_Node_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ Directive_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 2 ] );
Directive_Action( ctx );
- Directive_Post_Status_Check( ctx, entry.Post_Status );
- Directive_Post_Id_Check( ctx, entry.Post_Id );
+ Directive_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ Directive_Post_Id_Check( ctx, ctx->Map.entry.Post_Id );
}
}
}
@@ -1824,6 +1835,15 @@ void Action2_Run( int *a, int b, int *c );
* @{
*/
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_A_NA : 1;
+ uint16_t Pre_B_NA : 1;
+ uint16_t Pre_C_NA : 1;
+ uint16_t Post_A : 3;
+ uint16_t Post_B : 2;
+} Action2_Entry;
+
/* Context support code */
/**
@@ -1855,16 +1875,27 @@ typedef struct {
*/
int *c;
- /**
- * @brief This member defines the pre-condition states for the next action.
- */
- size_t pcs[ 3 ];
-
- /**
- * @brief This member indicates if the test action loop is currently
- * executed.
- */
- bool in_action_loop;
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 3 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ Action2_Entry entry;
+ } Map;
} Action2_Context;
static Action2_Context
@@ -2094,7 +2125,7 @@ static void Action2_Setup_Wrap( void *arg )
Action2_Context *ctx;
ctx = arg;
- ctx->in_action_loop = false;
+ ctx->Map.in_action_loop = false;
Action2_Setup( ctx );
}
@@ -2113,7 +2144,7 @@ static void Action2_Teardown_Wrap( void *arg )
Action2_Context *ctx;
ctx = arg;
- ctx->in_action_loop = false;
+ ctx->Map.in_action_loop = false;
Action2_Teardown( ctx );
}
@@ -2132,15 +2163,6 @@ static void Action2_Cleanup( Action2_Context *ctx )
/* Cleanup */
}
-typedef struct {
- uint16_t Skip : 1;
- uint16_t Pre_A_NA : 1;
- uint16_t Pre_B_NA : 1;
- uint16_t Pre_C_NA : 1;
- uint16_t Post_A : 3;
- uint16_t Post_B : 2;
-} Action2_Entry;
-
static const Action2_Entry
Action2_Entries[] = {
{ 0, 1, 0, 0, Action2_Post_A_A1, Action2_Post_B_NA },
@@ -2171,8 +2193,8 @@ static size_t Action2_Scope( void *arg, char *buf, size_t n )
ctx = arg;
- if ( ctx->in_action_loop ) {
- return T_get_scope( Action2_PreDesc, buf, n, ctx->pcs );
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( Action2_PreDesc, buf, n, ctx->Map.pcs );
}
return 0;
@@ -2186,8 +2208,12 @@ static T_fixture Action2_Fixture = {
.initial_context = &Action2_Instance
};
-static inline Action2_Entry Action2_GetEntry( size_t index )
+static inline Action2_Entry Action2_PopEntry( Action2_Context *ctx )
{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
return Action2_Entries[
Action2_Map[ index ]
];
@@ -2198,7 +2224,6 @@ static T_fixture_node Action2_Node;
void Action2_Run( int *a, int b, int *c )
{
Action2_Context *ctx;
- size_t index;
ctx = &Action2_Instance;
ctx->a = a;
@@ -2206,43 +2231,40 @@ void Action2_Run( int *a, int b, int *c )
ctx->c = c;
ctx = T_push_fixture( &Action2_Node, &Action2_Fixture );
- ctx->in_action_loop = true;
- index = 0;
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
for (
- ctx->pcs[ 0 ] = Action2_Pre_A_A0;
- ctx->pcs[ 0 ] < Action2_Pre_A_NA;
- ++ctx->pcs[ 0 ]
+ ctx->Map.pcs[ 0 ] = Action2_Pre_A_A0;
+ ctx->Map.pcs[ 0 ] < Action2_Pre_A_NA;
+ ++ctx->Map.pcs[ 0 ]
) {
for (
- ctx->pcs[ 1 ] = Action2_Pre_B_B0;
- ctx->pcs[ 1 ] < Action2_Pre_B_NA;
- ++ctx->pcs[ 1 ]
+ ctx->Map.pcs[ 1 ] = Action2_Pre_B_B0;
+ ctx->Map.pcs[ 1 ] < Action2_Pre_B_NA;
+ ++ctx->Map.pcs[ 1 ]
) {
for (
- ctx->pcs[ 2 ] = Action2_Pre_C_C0;
- ctx->pcs[ 2 ] < Action2_Pre_C_NA;
- ++ctx->pcs[ 2 ]
+ ctx->Map.pcs[ 2 ] = Action2_Pre_C_C0;
+ ctx->Map.pcs[ 2 ] < Action2_Pre_C_NA;
+ ++ctx->Map.pcs[ 2 ]
) {
- Action2_Entry entry;
-
- entry = Action2_GetEntry( index );
- ++index;
+ ctx->Map.entry = Action2_PopEntry( ctx );
- if ( entry.Skip ) {
+ if ( ctx->Map.entry.Skip ) {
continue;
}
Action2_Prepare( ctx );
Action2_Pre_A_Prepare(
ctx,
- entry.Pre_A_NA ? Action2_Pre_A_NA : ctx->pcs[ 0 ]
+ ctx->Map.entry.Pre_A_NA ? Action2_Pre_A_NA : ctx->Map.pcs[ 0 ]
);
- Action2_Pre_B_Prepare( ctx, ctx->pcs[ 1 ] );
- Action2_Pre_C_Prepare( ctx, ctx->pcs[ 2 ] );
+ Action2_Pre_B_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ Action2_Pre_C_Prepare( ctx, ctx->Map.pcs[ 2 ] );
Action2_Action( ctx );
- Action2_Post_A_Check( ctx, entry.Post_A );
- Action2_Post_B_Check( ctx, entry.Post_B );
+ Action2_Post_A_Check( ctx, ctx->Map.entry.Post_A );
+ Action2_Post_B_Check( ctx, ctx->Map.entry.Post_B );
Action2_Cleanup( ctx );
}
}
diff --git a/rtemsspec/transitionmap.py b/rtemsspec/transitionmap.py
index c7f2193a..703395cb 100644
--- a/rtemsspec/transitionmap.py
+++ b/rtemsspec/transitionmap.py
@@ -616,6 +616,20 @@ class TransitionMap:
bits += math.ceil(math.log2(len(st_idx_to_st_name)))
return 2**max(math.ceil(math.log2(bits)), 3)
+ def add_map_entry_type(self, content: CContent, ident: str) -> None:
+ """ Adds the transition map entry type definition to the content. """
+ bits = self._get_entry_bits()
+ content.add("typedef struct {")
+ with content.indent():
+ content.append(f"uint{bits}_t Skip : 1;")
+ for condition in self["pre-conditions"]:
+ content.append(f"uint{bits}_t Pre_{condition['name']}_NA : 1;")
+ for condition in self["post-conditions"]:
+ state_bits = math.ceil(math.log2(len(condition["states"]) + 1))
+ content.append(
+ f"uint{bits}_t Post_{condition['name']} : {state_bits};")
+ content.add(f"}} {ident}_Entry;")
+
def add_map(self, content: CContent, ident: str) -> None:
""" Adds the transition map definitions to the content. """
entries = []
@@ -636,17 +650,6 @@ class TransitionMap:
enumerators.append(self._get_entry(ident, transitions[0]))
enumerators.append("#endif")
entries.append("\n".join(enumerators))
- bits = self._get_entry_bits()
- content.add("typedef struct {")
- with content.indent():
- content.append(f"uint{bits}_t Skip : 1;")
- for condition in self["pre-conditions"]:
- content.append(f"uint{bits}_t Pre_{condition['name']}_NA : 1;")
- for condition in self["post-conditions"]:
- state_bits = math.ceil(math.log2(len(condition["states"]) + 1))
- content.append(
- f"uint{bits}_t Post_{condition['name']} : {state_bits};")
- content.add(f"}} {ident}_Entry;")
content.add([f"static const {ident}_Entry", f"{ident}_Entries[] = {{"])
entries[-1] = entries[-1].replace("},", "}")
content.append(entries)
diff --git a/rtemsspec/validation.py b/rtemsspec/validation.py
index 8b76fe99..48c65077 100644
--- a/rtemsspec/validation.py
+++ b/rtemsspec/validation.py
@@ -528,23 +528,32 @@ class _ActionRequirementTestItem(_TestItem):
def add_default_context_members(self, content: CContent) -> None:
super().add_default_context_members(content)
- content.add_description_block(
- "This member defines the pre-condition states "
- "for the next action.", None)
- content.add(f"size_t pcs[ {self._pre_co_count} ];")
- content.add_description_block(
- "This member indicates if the test action loop "
- "is currently executed.", None)
- content.add("bool in_action_loop;")
+ content.add("struct {")
+ with content.indent():
+ content.add_description_block(
+ "This member defines the pre-condition states "
+ "for the next action.", None)
+ content.add(f"size_t pcs[ {self._pre_co_count} ];")
+ content.add_description_block(
+ "If this member is true, then the test action "
+ "loop is executed.", None)
+ content.add("bool in_action_loop;")
+ content.add_description_block(
+ "This member contains the next transition map index.", None)
+ content.add("size_t index;")
+ content.add_description_block(
+ "This member contains the current transition map entry.", None)
+ content.add(f"{self.ident}_Entry entry;")
+ content.append("} Map;")
def _add_fixture_scope(self, content: CContent) -> None:
params = ["void *arg", "char *buf", "size_t n"]
with content.function("static size_t", f"{self.ident}_Scope", params):
content.add([f"{self.context} *ctx;", "", "ctx = arg;"])
- with content.condition("ctx->in_action_loop"):
+ with content.condition("ctx->Map.in_action_loop"):
content.call_function(
"return", "T_get_scope",
- [f"{self.ident}_PreDesc", "buf", "n", "ctx->pcs"])
+ [f"{self.ident}_PreDesc", "buf", "n", "ctx->Map.pcs"])
content.add("return 0;")
def _add_call(self, content: CContent, key: str, name: str) -> None:
@@ -554,34 +563,34 @@ class _ActionRequirementTestItem(_TestItem):
def _add_loop_body(self, content: CContent,
transition_map: TransitionMap) -> None:
- content.add(f"{self.ident}_Entry entry;")
- content.call_function("entry =", f"{self.ident}_GetEntry", ["index"])
- content.append("++index;")
+ entry = "ctx->Map.entry"
+ content.call_function(f"{entry} =", f"{self.ident}_PopEntry", ["ctx"])
if transition_map.pre_co_summary[0]:
- with content.condition("entry.Skip"):
+ with content.condition(f"{entry}.Skip"):
content.append("continue;")
content.add_blank_line()
self._add_call(content, "test-prepare", "Prepare")
for index, pre_co in enumerate(self._item["pre-conditions"]):
content.gap = False
- state = f"ctx->pcs[ {index} ]"
+ state = f"ctx->Map.pcs[ {index} ]"
if transition_map.pre_co_summary[index + 1]:
enum_na = self._pre_co_idx_to_enum[index][-1]
- state = f"entry.Pre_{pre_co['name']}_NA ? {enum_na} : {state}"
+ 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])
self._add_call(content, "test-action", "Action")
for index, enum in enumerate(self._post_co_idx_to_enum):
content.gap = False
content.call_function(None, f"{enum[0]}_Check", [
- "ctx", f"entry.{transition_map.get_post_entry_member(index)}"
+ "ctx", f"{entry}.{transition_map.get_post_entry_member(index)}"
])
self._add_call(content, "test-cleanup", "Cleanup")
def _add_for_loops(self, content: CContent, transition_map: TransitionMap,
index: int) -> None:
if index < self._pre_co_count:
- var = f"ctx->pcs[ {index} ]"
+ var = f"ctx->Map.pcs[ {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}",
@@ -593,11 +602,12 @@ class _ActionRequirementTestItem(_TestItem):
def _add_test_case(self, content: CContent, transition_map: TransitionMap,
header: Dict[str, Any]) -> None:
ret = f"static inline {self.ident}_Entry"
- name = f"{self.ident}_GetEntry"
- params = ["size_t index"]
+ name = f"{self.ident}_PopEntry"
+ params = [f"{self.context} *ctx"]
with content.function(ret, name, params, align=True):
content.add([
- f"return {self.ident}_Entries[",
+ "size_t index;", "", "index = ctx->Map.index;",
+ "ctx->Map.index = index + 1;", f"return {self.ident}_Entries[",
f" {self.ident}_Map[ index ]", "];"
])
fixture = f"{self.ident}_Fixture"
@@ -608,11 +618,12 @@ class _ActionRequirementTestItem(_TestItem):
ret = "void"
name = f"{self.ident}_Run"
params = self._get_run_params(header)
- prologue.add([f"{self.context} *ctx;", "size_t index;"])
+ prologue.add([f"{self.context} *ctx;"])
self.assign_run_params(prologue, header)
prologue.call_function("ctx =", "T_push_fixture",
[f"&{self.ident}_Node", f"&{fixture}"])
- prologue.append(["ctx->in_action_loop = true;", "index = 0;"])
+ prologue.append(
+ ["ctx->Map.in_action_loop = true;", "ctx->Map.index = 0;"])
epilogue.add("T_pop_fixture();")
align = True
else:
@@ -624,9 +635,8 @@ class _ActionRequirementTestItem(_TestItem):
name = "T_TEST_CASE_FIXTURE"
params = [f"{self.ident}", f"&{fixture}"]
prologue.add([
- f"{self.context} *ctx;", "size_t index;", "",
- "ctx = T_fixture_context();", "ctx->in_action_loop = true;",
- "index = 0;"
+ f"{self.context} *ctx;", "", "ctx = T_fixture_context();",
+ "ctx->Map.in_action_loop = true;", "ctx->Map.index = 0;"
])
align = False
with content.function(ret, name, params, align=align):
@@ -678,6 +688,8 @@ class _ActionRequirementTestItem(_TestItem):
else:
_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)
+ transition_map.add_map_entry_type(content, self.ident)
instance = self.add_context(content)
self._add_pre_condition_descriptions(content)
content.add(self.substitute_code(self["test-support"]))
@@ -685,7 +697,7 @@ class _ActionRequirementTestItem(_TestItem):
self._pre_co_idx_to_enum, "Prepare")
self._add_handler(content, self["post-conditions"],
self._post_co_idx_to_enum, "Check")
- optional_code = "ctx->in_action_loop = false;"
+ optional_code = "ctx->Map.in_action_loop = false;"
setup = self.add_support_method(content,
"test-setup",
"Setup",
@@ -701,7 +713,6 @@ class _ActionRequirementTestItem(_TestItem):
self.add_function(content, "test-prepare", "Prepare")
self.add_function(content, "test-action", "Action")
self.add_function(content, "test-cleanup", "Cleanup")
- transition_map = TransitionMap(self.item)
transition_map.add_map(content, self.ident)
self._add_fixture_scope(content)
content.add([