summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2020-11-11 13:55:06 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2020-11-13 11:08:43 +0100
commit4a94b1243042bf42fc03a0a591e5ebaba0765cd7 (patch)
treedd994ee740ec6ec5d5b04dc0a3e415e89d6424df
parentvalidation: Move add function to base class (diff)
downloadrtems-central-4a94b1243042bf42fc03a0a591e5ebaba0765cd7.tar.bz2
validation: Support for runtime measurement tests
-rw-r--r--rtemsspec/tests/spec-validation/rtm.yml51
-rw-r--r--rtemsspec/tests/spec/runtime-measurement-test.yml21
-rw-r--r--rtemsspec/tests/test_validation.py129
-rw-r--r--rtemsspec/validation.py119
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 00000000..d7809840
--- /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 00000000..3da856ab
--- /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 a9e5280a..ed17189d 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 b2965785..1bef5606 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,
}