[rtems-central commit] validation: Support for runtime measurement tests

Sebastian Huber sebh at rtems.org
Fri Nov 13 10:09:47 UTC 2020


Module:    rtems-central
Branch:    master
Commit:    4a94b1243042bf42fc03a0a591e5ebaba0765cd7
Changeset: http://git.rtems.org/rtems-central/commit/?id=4a94b1243042bf42fc03a0a591e5ebaba0765cd7

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Wed Nov 11 13:55:06 2020 +0100

validation: Support for runtime measurement tests

---

 rtemsspec/tests/spec-validation/rtm.yml           |  51 +++++++++
 rtemsspec/tests/spec/runtime-measurement-test.yml |  21 ++++
 rtemsspec/tests/test_validation.py                | 129 ++++++++++++++++++++++
 rtemsspec/validation.py                           | 119 ++++++++++++++++++--
 4 files changed, 309 insertions(+), 11 deletions(-)

diff --git a/rtemsspec/tests/spec-validation/rtm.yml b/rtemsspec/tests/spec-validation/rtm.yml
new file mode 100644
index 0000000..d780984
--- /dev/null
+++ b/rtemsspec/tests/spec-validation/rtm.yml
@@ -0,0 +1,51 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+copyrights:
+- Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links: []
+params:
+  sample-count: 100
+test-brief: |
+  Test brief.
+test-cleanup:
+  brief: |
+    Cleanup brief.
+  code: |
+    /* Cleanup code */
+  description: |
+    Cleanup description.
+test-context:
+- brief: |
+    Context member brief.
+  description: |
+    Context member description.
+  member: |
+    int member
+test-context-support: |
+  /* Context support code */
+test-description: |
+  Test description.
+test-includes:
+- u.h
+test-local-includes:
+- v.h
+test-prepare: null
+test-setup: null
+test-stop:
+  brief: |
+    Stop brief.
+  code: |
+    /* Stop code */
+  description: |
+    Stop description.
+test-support: |
+  /* Support code */
+test-target: tc34.c
+test-teardown:
+  brief: |
+    Teardown brief.
+  code: |
+    /* Teardown code */
+  description: |
+    Teardown description.
+type: runtime-measurement-test
diff --git a/rtemsspec/tests/spec/runtime-measurement-test.yml b/rtemsspec/tests/spec/runtime-measurement-test.yml
new file mode 100644
index 0000000..3da856a
--- /dev/null
+++ b/rtemsspec/tests/spec/runtime-measurement-test.yml
@@ -0,0 +1,21 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+copyrights:
+- Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: spec-member
+  uid: root
+- role: spec-refinement
+  spec-key: type
+  spec-value: runtime-measurement-test
+  uid: root
+spec-description: null
+spec-example: null
+spec-info:
+  dict:
+    attributes: {}
+    description: null
+    mandatory-attributes: all
+spec-name: Runtime Measurement Test
+spec-type: runtime-measurement-test
+type: spec
diff --git a/rtemsspec/tests/test_validation.py b/rtemsspec/tests/test_validation.py
index a9e5280..ed17189 100644
--- a/rtemsspec/tests/test_validation.py
+++ b/rtemsspec/tests/test_validation.py
@@ -916,6 +916,7 @@ T_TEST_CASE_FIXTURE( Tc2, &test_case_2_fixture )
 /**
  * @file
  *
+ * @ingroup RTEMSTestCaseRtm
  * @ingroup RTEMSTestCaseTc3
  * @ingroup RTEMSTestCaseTc4
  * @ingroup RTEMSTestCaseTc5
@@ -965,12 +966,140 @@ T_TEST_CASE_FIXTURE( Tc2, &test_case_2_fixture )
 #endif
 
 #include <c.h>
+#include <u.h>
 
+#include "v.h"
 #include "z.h"
 
 #include <rtems/test.h>
 
 /**
+ * @defgroup RTEMSTestCaseRtm spec:/rtm
+ *
+ * @ingroup RTEMSTestSuiteTs
+ *
+ * @brief Test brief.
+ *
+ * Test description.
+ *
+ * @{
+ */
+
+/* Context support code */
+
+/**
+ * @brief Test context for spec:/rtm test case.
+ */
+typedef struct {
+  /**
+   * @brief Context member brief.
+   *
+   * Context member description.
+   */
+  int member;
+
+  /**
+   * @brief This member references the measure runtime context.
+   */
+  T_measure_runtime_context *context;
+
+  /**
+   * @brief This member provides the measure runtime request.
+   */
+  T_measure_runtime_request request;
+} Rtm_Context;
+
+static Rtm_Context
+  Rtm_Instance;
+
+/* Support code */
+
+static void Rtm_Setup_Context( Rtm_Context *ctx )
+{
+  T_measure_runtime_config config;
+
+  memset( &config, 0, sizeof( config ) );
+  config.sample_count = 100;
+  ctx->request.arg = ctx;
+  ctx->context = T_measure_runtime_create( &config );
+  T_assert_not_null( ctx->context );
+}
+
+static void Rtm_Setup_Wrap( void *arg )
+{
+  Rtm_Context *ctx;
+
+  ctx = arg;
+  Rtm_Setup_Context( ctx );
+}
+
+/**
+ * @brief Stop brief.
+ *
+ * Stop description.
+ */
+static void Rtm_Stop( Rtm_Context *ctx )
+{
+  /* Stop code */
+}
+
+static void Rtm_Stop_Wrap( void *arg )
+{
+  Rtm_Context *ctx;
+
+  ctx = arg;
+  Rtm_Stop( ctx );
+}
+
+/**
+ * @brief Teardown brief.
+ *
+ * Teardown description.
+ */
+static void Rtm_Teardown( Rtm_Context *ctx )
+{
+  /* Teardown code */
+}
+
+static void Rtm_Teardown_Wrap( void *arg )
+{
+  Rtm_Context *ctx;
+
+  ctx = arg;
+  Rtm_Teardown( ctx );
+}
+
+static T_fixture Rtm_Fixture = {
+  .setup = Rtm_Setup_Wrap,
+  .stop = Rtm_Stop_Wrap,
+  .teardown = Rtm_Teardown_Wrap,
+  .scope = NULL,
+  .initial_context = &Rtm_Instance
+};
+
+/**
+ * @brief Cleanup brief.
+ *
+ * Cleanup description.
+ */
+static void Rtm_Cleanup( Rtm_Context *ctx )
+{
+  /* Cleanup code */
+}
+
+/**
+ * @fn void T_case_body_Rtm( void )
+ */
+T_TEST_CASE_FIXTURE( Rtm, &Rtm_Fixture )
+{
+  Rtm_Context *ctx;
+
+  ctx = T_fixture_context();
+}
+
+/** @} */
+
+/**
  * @defgroup RTEMSTestCaseTc3 spec:/tc3
  *
  * @ingroup RTEMSTestSuiteTs
diff --git a/rtemsspec/validation.py b/rtemsspec/validation.py
index b296578..1bef560 100644
--- a/rtemsspec/validation.py
+++ b/rtemsspec/validation.py
@@ -205,36 +205,56 @@ class _TestItem:
         content.declare_function("void", f"{self.ident}_Run",
                                  self._get_run_params(header))
 
-    def add_support_method(
-            self,
-            content: CContent,
-            key: str,
-            name: str,
-            mandatory_code: Optional[GenericContent] = None,
-            optional_code: Optional[GenericContent] = None) -> str:
+    def add_support_method(self,
+                           content: CContent,
+                           key: str,
+                           name: str,
+                           mandatory_code: Optional[GenericContent] = None,
+                           optional_code: Optional[GenericContent] = None,
+                           ret: str = "void",
+                           extra_params: Optional[List[str]] = None,
+                           extra_args: Optional[List[str]] = None,
+                           do_wrap: bool = True) -> str:
         """ Adds a support method to the content. """
 
         # pylint: disable=too-many-arguments
+        # pylint: disable=too-many-locals
         info = self[key]
         if not info and not mandatory_code:
             return "NULL"
+        if extra_params is None:
+            extra_params = []
+        if extra_args is None:
+            extra_args = []
         method = f"{self.ident}_{name}"
         wrap = f"{method}_Wrap"
         if info:
             content.add_description_block(
                 self.substitute_text(info["brief"]),
                 self.substitute_text(info["description"]))
-            with content.function("static void", method,
-                                  [f"{self.context} *ctx"]):
+            params = [f"{self.context} *ctx"] + extra_params
+            with content.function(f"static {ret}", method, params):
+                if not do_wrap:
+                    content.gap = False
+                    content.add(mandatory_code)
+                    content.gap = False
+                    content.add(optional_code)
                 content.add(self.substitute_code(info["code"]))
-        with content.function("static void", wrap, ["void *arg"]):
+        if not do_wrap:
+            assert info
+            return method
+        params = ["void *arg"] + extra_params
+        with content.function(f"static {ret}", wrap, params):
             content.add([f"{self.context} *ctx;", "", "ctx = arg;"])
             content.gap = False
             content.add(mandatory_code)
             content.gap = False
             content.add(optional_code)
             if info:
-                content.append(f"{method}( ctx );")
+                content.gap = False
+                ret_2 = None if ret == "void" else "return"
+                args = ["ctx"] + extra_args
+                content.call_function(ret_2, f"{method}", args)
         return wrap
 
     def add_function(self, content: CContent, key: str, name: str) -> None:
@@ -737,6 +757,71 @@ class _ActionRequirementTestItem(_TestItem):
         content.add("/** @} */")
 
 
+class _RuntimeMeasurementTestItem(_TestItem):
+    """ A runtime measurement test item. """
+    def add_test_case_action_description(self, _content: CContent) -> None:
+        pass
+
+    def add_default_context_members(self, content: CContent) -> None:
+        content.add_description_block(
+            "This member references the measure runtime context.", None)
+        content.add("T_measure_runtime_context *context;")
+        content.add_description_block(
+            "This member provides the measure runtime request.", None)
+        content.add("T_measure_runtime_request request;")
+
+    def generate(self, content: CContent, base_directory: str,
+                 test_case_to_suites: Dict[str, List[_TestItem]]) -> None:
+        self.add_test_case_description(content, test_case_to_suites)
+        self.add_context(content)
+        content.add(self.substitute_code(self["test-support"]))
+        setup = f"{self.ident}_Setup_Context"
+        with content.function("static void", setup, [f"{self.context} *ctx"]):
+            content.add([
+                "T_measure_runtime_config config;",
+                "",
+                "memset( &config, 0, sizeof( config ) );",
+                f"config.sample_count = {self['params']['sample-count']};",
+                "ctx->request.arg = ctx;",
+                "ctx->context = T_measure_runtime_create( &config );",
+                "T_assert_not_null( ctx->context );",
+            ])
+        setup = self.add_support_method(content,
+                                        "test-setup",
+                                        "Setup",
+                                        mandatory_code=f"{setup}( ctx );")
+        stop = self.add_support_method(content, "test-stop", "Stop")
+        teardown = self.add_support_method(content, "test-teardown",
+                                           "Teardown")
+        content.add([
+            f"static T_fixture {self.ident}_Fixture = {{",
+            f"  .setup = {setup},", f"  .stop = {stop},",
+            f"  .teardown = {teardown},", "  .scope = NULL,",
+            f"  .initial_context = &{self.ident}_Instance", "};"
+        ])
+        self.add_support_method(content,
+                                "test-prepare",
+                                "Prepare",
+                                do_wrap=False)
+        self.add_support_method(content,
+                                "test-cleanup",
+                                "Cleanup",
+                                do_wrap=False)
+        with content.function_block(f"void T_case_body_{self.ident}( void )"):
+            pass
+        content.gap = False
+        ret = ""
+        name = "T_TEST_CASE_FIXTURE"
+        params = [f"{self.ident}", f"&{self.ident}_Fixture"]
+        with content.function(ret, name, params, align=False):
+            content.add([
+                f"{self.context} *ctx;",
+                "",
+                "ctx = T_fixture_context();",
+            ])
+        content.add("/** @} */")
+
+
 class _SourceFile:
     """ A test source file. """
     def __init__(self, filename: str):
@@ -767,6 +852,10 @@ class _SourceFile:
         """ Adds an action requirement test to the source file. """
         self._test_cases.append(_ActionRequirementTestItem(item))
 
+    def add_runtime_measurement_test(self, item: Item) -> None:
+        """ Adds a runtime measurement test to the source file. """
+        self._test_cases.append(_RuntimeMeasurementTestItem(item))
+
     def generate(self, base_directory: str,
                  test_case_to_suites: Dict[str, List[_TestItem]]) -> None:
         """
@@ -831,6 +920,13 @@ def _gather_action_requirement_test(
     src.add_action_requirement_test(item)
 
 
+def _gather_runtime_measurement_test(
+        item: Item, source_files: Dict[str, _SourceFile],
+        _test_programs: List[_TestProgram]) -> None:
+    src = _get_source_file(item["test-target"], source_files)
+    src.add_runtime_measurement_test(item)
+
+
 def _gather_test_case(item: Item, source_files: Dict[str, _SourceFile],
                       _test_programs: List[_TestProgram]) -> None:
     src = _get_source_file(item["test-target"], source_files)
@@ -856,6 +952,7 @@ def _gather_default(_item: Item, _source_files: Dict[str, _SourceFile],
 _GATHER = {
     "build/test-program": _gather_test_program,
     "requirement/functional/action": _gather_action_requirement_test,
+    "runtime-measurement-test": _gather_runtime_measurement_test,
     "test-case": _gather_test_case,
     "test-suite": _gather_test_suite,
 }



More information about the vc mailing list