From 4a94b1243042bf42fc03a0a591e5ebaba0765cd7 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 11 Nov 2020 13:55:06 +0100 Subject: 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(-) create mode 100644 rtemsspec/tests/spec-validation/rtm.yml create mode 100644 rtemsspec/tests/spec/runtime-measurement-test.yml 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,11 +966,139 @@ T_TEST_CASE_FIXTURE( Tc2, &test_case_2_fixture ) #endif #include +#include +#include "v.h" #include "z.h" #include +/** + * @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 * 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, } -- cgit v1.2.3