diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2023-11-21 11:13:15 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2023-11-21 11:15:24 +0100 |
commit | 47da37564e25c1f88dfe832eecc5ec57c6784ada (patch) | |
tree | e70ff82be4cba3173c5197ec92a809046ad08a3f | |
parent | membench: Clarify wording (diff) | |
download | rtems-central-47da37564e25c1f88dfe832eecc5ec57c6784ada.tar.bz2 |
specview.py: Share validation support
30 files changed, 664 insertions, 75 deletions
diff --git a/rtemsspec/rtems.py b/rtemsspec/rtems.py index 94b2d1fb..6407de19 100644 --- a/rtemsspec/rtems.py +++ b/rtemsspec/rtems.py @@ -24,7 +24,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -from typing import Any, List +import itertools +from typing import Any, List, Tuple, Union from rtemsspec.items import create_unique_link, Item, ItemCache, Link @@ -82,3 +83,140 @@ def augment_with_test_links(item_cache: ItemCache) -> None: _add_link(item_cache, item, link) for link in actions["links"]: _add_link(item_cache, item, link) + + +_SELF_VALIDATION = { + "memory-benchmark": "memory benchmark", + "requirement/functional/action": "validation by test", + "requirement/non-functional/performance-runtime": "validation by test", + "runtime-measurement-test": "validation by test" +} + +_VALIDATION_METHOD = { + "memory-benchmark": "validation by inspection", + "requirement/functional/action": "validation by test", + "requirement/non-functional/performance-runtime": "validation by test", + "runtime-measurement-test": "validation by test", + "test-case": "validation by test", + "validation/by-analysis": "validation by analysis", + "validation/by-inspection": "validation by inspection", + "validation/by-review-of-design": "validation by review of design", +} + +_CONTAINER_TYPE = ["interface/domain", "interface/header-file"] + +# In the first pass using _validate_tree() we consider interface domains and +# header files as validated. We have to do this since a traversal to interface +# placements would lead to an infinite recursion in _validate_tree(). In the +# second pass using _validate_containers() the interface domain and header file +# validations are fixed. +_VALIDATION_LEAF = list(_VALIDATION_METHOD.keys()) + _CONTAINER_TYPE + +_CHILD_ROLES = [ + "requirement-refinement", "interface-ingroup", "interface-ingroup-hidden", + "interface-function", "glossary-member", "test-case", "validation" +] + +_PARENT_ROLES = [ + "function-implementation", "interface-enumerator", + "performance-runtime-limits" +] + + +def _validate_glossary_term(item: Item) -> bool: + for item_2 in item.parents("glossary-member"): + if item_2.type != "glossary/group": + return False + return True + + +def _validate_constraint(item: Item) -> bool: + for item_2 in item.parents("requirement-refinement"): + if item_2.uid != "/req/usage-constraints": + return False + return True + + +_VALIDATOR = { + "constraint": _validate_constraint, + "glossary/term": _validate_glossary_term +} + + +def _validate_tree(item: Item) -> bool: + pre_qualified = is_pre_qualified(item) + item["_pre_qualified"] = pre_qualified + validated = True + validation_dependencies: List[Tuple[str, str]] = [] + for link in itertools.chain(item.links_to_children(_CHILD_ROLES), + item.links_to_parents(_PARENT_ROLES)): + item_2 = link.item + validated = _validate_tree(item_2) and validated + if link.role == "validation": + role = _VALIDATION_METHOD[item_2.type] + elif link.role == "requirement-refinement": + role = "refinement" + elif link.role.startswith("interface-ingroup"): + role = "group member" + elif link.role == "performance-runtime-limits": + role = "runtime performance requirement" + else: + role = link.role.replace("-", " ") + validation_dependencies.append((item_2.uid, role)) + type_name = item.type + if type_name in _SELF_VALIDATION: + validation_dependencies.append((item.uid, _SELF_VALIDATION[type_name])) + elif not validation_dependencies: + if type_name in _VALIDATOR: + validated = _VALIDATOR[type_name](item) + else: + validated = (not pre_qualified) or (type_name in _VALIDATION_LEAF) + if type_name in _CONTAINER_TYPE: + validation_dependencies.extend( + (item_2.uid, "interface placement") + for item_2 in item.children("interface-placement")) + item["_validated"] = validated + item["_validation_dependencies"] = sorted(validation_dependencies) + return validated + + +def _validate_containers(item: Item) -> bool: + validated = item["_validated"] + if item.type in _CONTAINER_TYPE: + # If at least one not validated child exists, then the container is not + # validated + for item_2 in item.children("interface-placement"): + if not item_2["_validated"]: + validated = False + item["_validated"] = validated + break + for item_2 in itertools.chain(item.children(_CHILD_ROLES), + item.parents(_PARENT_ROLES)): + validated = _validate_containers(item_2) and validated + return validated + + +def _fixup_pre_qualified(item: Item, types: List[str], + roles: Union[str, List[str]]) -> None: + for type_name in types: + for item_2 in item.cache.items_by_type[type_name]: + # Count of not pre-qualified (index 0) and pre-qualified (index 1) + # children + count = [0, 0] + for item_3 in item_2.children(roles): + count[int(item_3["_pre_qualified"])] += 1 + # If at least one not pre-qualified child exists and no + # pre-qualified child exists, then the item is not pre-qualified. + if count[0] > 0 and count[1] == 0: + item_2["_pre_qualified"] = False + + +def validate(item: Item) -> None: + """ Validates the item tree starting at the root item. """ + _validate_tree(item) + _validate_containers(item) + _fixup_pre_qualified(item, + ["interface/appl-config-group", "interface/group"], + ["interface-ingroup", "interface-ingroup-hidden"]) + _fixup_pre_qualified(item, ["interface/header-file"], + "interface-placement") diff --git a/rtemsspec/tests/spec-rtems/constraint/bad.yml b/rtemsspec/tests/spec-rtems/constraint/bad.yml new file mode 100644 index 00000000..89210c43 --- /dev/null +++ b/rtemsspec/tests/spec-rtems/constraint/bad.yml @@ -0,0 +1,11 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2021 embedded brains GmbH & Co. KG +enabled-by: true +links: +- role: requirement-refinement + uid: ../req/usage-constraints +rationale: null +text: | + The directive may terminate the system. +type: constraint diff --git a/rtemsspec/tests/spec-rtems/constraint/constant-not-pre-qualified.yml b/rtemsspec/tests/spec-rtems/constraint/constant-not-pre-qualified.yml new file mode 100644 index 00000000..20ae5248 --- /dev/null +++ b/rtemsspec/tests/spec-rtems/constraint/constant-not-pre-qualified.yml @@ -0,0 +1,13 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2021 embedded brains GmbH & Co. KG +enabled-by: true +links: +- role: requirement-refinement + uid: ../req/usage-constraints +rationale: null +text: | + The constant is not included in the pre-qualified feature set of RTEMS. + Applications which are restricted to only use interfaces of the pre-qualified + feature set of RTEMS shall not use the constant. +type: constraint diff --git a/rtemsspec/tests/spec-rtems/constraint/terminate.yml b/rtemsspec/tests/spec-rtems/constraint/terminate.yml new file mode 100644 index 00000000..4250bb03 --- /dev/null +++ b/rtemsspec/tests/spec-rtems/constraint/terminate.yml @@ -0,0 +1,11 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2021 embedded brains GmbH & Co. KG +enabled-by: true +links: +- role: requirement-refinement + uid: ../req/root +rationale: null +text: | + The directive may terminate the system. +type: constraint diff --git a/rtemsspec/tests/spec-rtems/glossary-general.yml b/rtemsspec/tests/spec-rtems/glossary-general.yml new file mode 100644 index 00000000..b5118577 --- /dev/null +++ b/rtemsspec/tests/spec-rtems/glossary-general.yml @@ -0,0 +1,12 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 +copyrights: +- Copyright (C) 2020 embedded brains GmbH & Co. KG +enabled-by: true +glossary-type: group +links: +- role: requirement-refinement + uid: req/root +name: General +text: | + The system shall have a general glossary of terms. +type: glossary diff --git a/rtemsspec/tests/spec-rtems/glossary/api.yml b/rtemsspec/tests/spec-rtems/glossary/api.yml new file mode 100644 index 00000000..98a0ab73 --- /dev/null +++ b/rtemsspec/tests/spec-rtems/glossary/api.yml @@ -0,0 +1,12 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2017 embedded brains GmbH & Co. KG +enabled-by: true +glossary-type: term +links: +- role: glossary-member + uid: ../glossary-general +term: API +text: | + This term is an acronym for Application Programming Interface. +type: glossary diff --git a/rtemsspec/tests/spec-rtems/glossary/bad.yml b/rtemsspec/tests/spec-rtems/glossary/bad.yml new file mode 100644 index 00000000..4ef1a692 --- /dev/null +++ b/rtemsspec/tests/spec-rtems/glossary/bad.yml @@ -0,0 +1,12 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2017 embedded brains GmbH & Co. KG +enabled-by: true +glossary-type: term +links: +- role: glossary-member + uid: ../req/root +term: API +text: | + This term is an acronym for Application Programming Interface. +type: glossary diff --git a/rtemsspec/tests/spec-rtems/if/disable-newlib-reentrancy.yml b/rtemsspec/tests/spec-rtems/if/disable-newlib-reentrancy.yml new file mode 100644 index 00000000..a18e9678 --- /dev/null +++ b/rtemsspec/tests/spec-rtems/if/disable-newlib-reentrancy.yml @@ -0,0 +1,22 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +appl-config-option-type: feature-enable +copyrights: +- Copyright (C) 2020 embedded brains GmbH & Co. KG +description: | + In case this configuration option is defined, then the Newlib reentrancy + support per thread is disabled and a global reentrancy structure is used. +enabled-by: true +index-entries: [] +interface-type: appl-config-option +links: +- role: interface-placement + uid: domain +- role: interface-ingroup + uid: group-general +name: CONFIGURE_DISABLE_NEWLIB_REENTRANCY +notes: | + You can enable this option to reduce the size of the :term:`TCB`. Use this + option with care, since it can lead to race conditions and undefined system + behaviour. For example, errno is no longer a thread-local + variable if this option is enabled. +type: interface diff --git a/rtemsspec/tests/spec-rtems/if/domain.yml b/rtemsspec/tests/spec-rtems/if/domain.yml new file mode 100644 index 00000000..9d499db1 --- /dev/null +++ b/rtemsspec/tests/spec-rtems/if/domain.yml @@ -0,0 +1,13 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2021 embedded brains GmbH & Co. KG +description: | + This interface domain contains the application configuration. +enabled-by: true +index-entries: [] +interface-type: domain +links: +- role: requirement-refinement + uid: ../req/root +name: Application Configuration +type: interface diff --git a/rtemsspec/tests/spec-rtems/if/errno-header.yml b/rtemsspec/tests/spec-rtems/if/errno-header.yml new file mode 100644 index 00000000..5018bf09 --- /dev/null +++ b/rtemsspec/tests/spec-rtems/if/errno-header.yml @@ -0,0 +1,15 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +brief: This is a standard C library header file. +copyrights: +- Copyright (C) 2020 embedded brains GmbH & Co. KG +enabled-by: true +index-entries: [] +interface-type: header-file +links: +- role: interface-placement + uid: domain +- role: interface-ingroup + uid: group +path: errno.h +prefix: '' +type: interface diff --git a/rtemsspec/tests/spec-rtems/if/errno.yml b/rtemsspec/tests/spec-rtems/if/errno.yml new file mode 100644 index 00000000..09e55795 --- /dev/null +++ b/rtemsspec/tests/spec-rtems/if/errno.yml @@ -0,0 +1,14 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2020 embedded brains GmbH & Co. KG +enabled-by: true +index-entries: [] +interface-type: unspecified-define +links: +- role: interface-placement + uid: errno-header +- role: interface-ingroup + uid: group +name: errno +references: [] +type: interface diff --git a/rtemsspec/tests/spec-rtems/if/group-general.yml b/rtemsspec/tests/spec-rtems/if/group-general.yml new file mode 100644 index 00000000..0e9bb163 --- /dev/null +++ b/rtemsspec/tests/spec-rtems/if/group-general.yml @@ -0,0 +1,16 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 1988, 2008 On-Line Applications Research Corporation (OAR) +description: | + This section describes general system configuration options. +enabled-by: true +index-entries: [] +interface-type: appl-config-group +links: +- role: interface-placement + uid: domain +- role: requirement-refinement + uid: ../req/root +name: General System Configuration +text: '' +type: interface diff --git a/rtemsspec/tests/spec-rtems/if/group.yml b/rtemsspec/tests/spec-rtems/if/group.yml new file mode 100644 index 00000000..1f43773c --- /dev/null +++ b/rtemsspec/tests/spec-rtems/if/group.yml @@ -0,0 +1,17 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2021 embedded brains GmbH & Co. KG +enabled-by: true +identifier: RTEMSApplConfig +index-entries: [] +interface-type: group +links: +- role: requirement-refinement + uid: ../req/root +- role: interface-placement + uid: domain +name: Application Configuration +text: | + The API shall contain the application configuration + interface. +type: interface diff --git a/rtemsspec/tests/spec-rtems/if/header-confdefs.yml b/rtemsspec/tests/spec-rtems/if/header-confdefs.yml new file mode 100644 index 00000000..680c7c17 --- /dev/null +++ b/rtemsspec/tests/spec-rtems/if/header-confdefs.yml @@ -0,0 +1,16 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +brief: | + This header file initializes the application configuration. +copyrights: +- Copyright (C) 2021 embedded brains GmbH & Co. KG +enabled-by: true +index-entries: [] +interface-type: header-file +links: +- role: interface-placement + uid: domain +- role: interface-ingroup + uid: group +path: rtems/confdefs.h +prefix: cpukit/include +type: interface diff --git a/rtemsspec/tests/spec-rtems/if/not-pre-qualified-header.yml b/rtemsspec/tests/spec-rtems/if/not-pre-qualified-header.yml new file mode 100644 index 00000000..4fc27470 --- /dev/null +++ b/rtemsspec/tests/spec-rtems/if/not-pre-qualified-header.yml @@ -0,0 +1,15 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +brief: Not pre-qualified header. +copyrights: +- Copyright (C) 2023 embedded brains GmbH & Co. KG +enabled-by: true +index-entries: [] +interface-type: header-file +links: +- role: interface-placement + uid: domain +- role: interface-ingroup + uid: group +path: not-pre-qualified.h +prefix: '' +type: interface diff --git a/rtemsspec/tests/spec-rtems/if/not-pre-qualified.yml b/rtemsspec/tests/spec-rtems/if/not-pre-qualified.yml new file mode 100644 index 00000000..d3ccfbcc --- /dev/null +++ b/rtemsspec/tests/spec-rtems/if/not-pre-qualified.yml @@ -0,0 +1,16 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2023 embedded brains GmbH & Co. KG +enabled-by: true +index-entries: [] +interface-type: unspecified-define +links: +- role: interface-placement + uid: not-pre-qualified-header +- role: interface-ingroup + uid: group +- role: constraint + uid: ../constraint/constant-not-pre-qualified +name: NOT_PRE_QUALIFIED +references: [] +type: interface diff --git a/rtemsspec/tests/spec-rtems/req/disable-newlib-reentrancy.yml b/rtemsspec/tests/spec-rtems/req/disable-newlib-reentrancy.yml new file mode 100644 index 00000000..6a881a08 --- /dev/null +++ b/rtemsspec/tests/spec-rtems/req/disable-newlib-reentrancy.yml @@ -0,0 +1,17 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2021 embedded brains GmbH & Co. KG +enabled-by: true +functional-type: function +links: +- role: interface-function + uid: ../if/disable-newlib-reentrancy +- role: requirement-refinement + uid: group +rationale: null +references: [] +requirement-type: functional +text: | + The application configuration option shall disable the thread-specific Newlib + reentrancy support. +type: requirement diff --git a/rtemsspec/tests/spec-rtems/req/group.yml b/rtemsspec/tests/spec-rtems/req/group.yml new file mode 100644 index 00000000..e9df0e95 --- /dev/null +++ b/rtemsspec/tests/spec-rtems/req/group.yml @@ -0,0 +1,16 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2021 embedded brains GmbH & Co. KG +enabled-by: true +identifier: RTEMSImplApplConfig +links: +- role: requirement-refinement + uid: root +non-functional-type: design-group +rationale: null +references: [] +requirement-type: non-functional +text: | + The implementation software architecture component have a component + containing the application configuration implementation. +type: requirement diff --git a/rtemsspec/tests/spec-rtems/req/perf-limits.yml b/rtemsspec/tests/spec-rtems/req/perf-limits.yml new file mode 100644 index 00000000..ecad9d40 --- /dev/null +++ b/rtemsspec/tests/spec-rtems/req/perf-limits.yml @@ -0,0 +1,36 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2023 embedded brains GmbH & Co. KG +enabled-by: true +links: +- role: requirement-refinement + uid: root +- limits: + DirtyCache: + max-upper-bound: 6.36e-06 + median-lower-bound: 1.57e-06 + median-upper-bound: 6.28e-06 + min-lower-bound: 1.57e-06 + FullCache: + max-upper-bound: 5.96e-06 + median-lower-bound: 1.48e-06 + median-upper-bound: 5.92e-06 + min-lower-bound: 1.48e-06 + HotCache: + max-upper-bound: 5.88e-06 + median-lower-bound: 1.47e-06 + median-upper-bound: 5.88e-06 + min-lower-bound: 1.47e-06 + Load/1: + max-upper-bound: 1.596e-05 + median-lower-bound: 3.99e-06 + median-upper-bound: 1.596e-05 + min-lower-bound: 3.98e-06 + role: performance-runtime-limits + uid: perf-runtime +non-functional-type: performance-runtime-limits +rationale: null +references: [] +requirement-type: non-functional +text: ${.:text-template} +type: requirement diff --git a/rtemsspec/tests/spec-rtems/req/perf-runtime.yml b/rtemsspec/tests/spec-rtems/req/perf-runtime.yml new file mode 100644 index 00000000..cae4ec31 --- /dev/null +++ b/rtemsspec/tests/spec-rtems/req/perf-runtime.yml @@ -0,0 +1,59 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2021 embedded brains GmbH & Co. KG +enabled-by: true +links: +- role: requirement-refinement + uid: root +- role: runtime-measurement-request + uid: ../val/perf +non-functional-type: performance-runtime +params: {} +rationale: null +references: [] +requirement-type: non-functional +test-body: + brief: | + Automatically release the barrier. + code: | + ctx->status = rtems_barrier_wait( ctx->barrier_id, RTEMS_NO_TIMEOUT ); + description: null +test-cleanup: + brief: | + Delete the barrier and the worker. + code: | + rtems_status_code sc; + + sc = rtems_barrier_delete( ctx->barrier_id ); + T_rsc_success( sc ); + description: null +test-prepare: + brief: | + Create an automatic release barrier. + code: | + rtems_status_code sc; + + sc = rtems_barrier_create( + OBJECT_NAME, + RTEMS_BARRIER_AUTOMATIC_RELEASE, + 1, + &ctx->barrier_id + ); + T_rsc_success( sc ); + description: null +test-setup: null +test-teardown: + brief: | + Discard samples interrupted by a clock tick. + code: | + T_quiet_rsc_success( ctx->status ); + + return tic == toc; + description: null +text: | + While the execution environment is ${.:/environment}, while the barrier is an + automatic release barrier, while the measurement sample is the runtime of + exactly one successful call to ${../if/wait:/name} which automatically + releases the barrier, when exactly ${../val/perf:/params/sample-count} + samples are collected, the ${.:/limit-kind} shall be ${.:/limit-condition}. +type: requirement diff --git a/rtemsspec/tests/spec-rtems/req/root.yml b/rtemsspec/tests/spec-rtems/req/root.yml new file mode 100644 index 00000000..0cb3ba69 --- /dev/null +++ b/rtemsspec/tests/spec-rtems/req/root.yml @@ -0,0 +1,12 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2020 embedded brains GmbH & Co. KG +enabled-by: true +links: [] +non-functional-type: design +rationale: null +references: [] +requirement-type: non-functional +text: | + The software product shall be a real-time operating system. +type: requirement diff --git a/rtemsspec/tests/spec-rtems/req/usage-constraints.yml b/rtemsspec/tests/spec-rtems/req/usage-constraints.yml new file mode 100644 index 00000000..75c42c2d --- /dev/null +++ b/rtemsspec/tests/spec-rtems/req/usage-constraints.yml @@ -0,0 +1,14 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2021 embedded brains GmbH & Co. KG +enabled-by: true +links: +- role: requirement-refinement + uid: root +non-functional-type: design +rationale: null +references: [] +requirement-type: non-functional +text: | + The system shall document usage constraints of interfaces. +type: requirement diff --git a/rtemsspec/tests/spec-rtems/val/disable-newlib-reentrancy.yml b/rtemsspec/tests/spec-rtems/val/disable-newlib-reentrancy.yml new file mode 100644 index 00000000..ff29201d --- /dev/null +++ b/rtemsspec/tests/spec-rtems/val/disable-newlib-reentrancy.yml @@ -0,0 +1,25 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 +copyrights: +- Copyright (C) 2022 embedded brains GmbH & Co. KG +enabled-by: true +links: +- role: validation + uid: ../req/disable-newlib-reentrancy +method: by-inspection +references: [] +text: | + Defining ${../if/disable-newlib-reentrancy:/name} is mandatory for + applications using only the pre-qualified feature set. The reason is to get + linker errors in case such applications are linked if they depend on the + Newlib reentrancy support. Thus no validation test case can be used. + Inspection of the referenced ${/glossary/sourcecode:/term} files showed that + an initial extension set is registered, if + ${../if/disable-newlib-reentrancy:/name} is not defined. For the + pre-qualified only build of RTEMS, this would lead to an unresolved reference + linker error. If ${../if/disable-newlib-reentrancy:/name} is defined, then + the ``__getreent()`` function is not provided by RTEMS. If + ${../if/disable-newlib-reentrancy:/name} is defined, then the Newlib + reentrancy structure is not contained in the ${/glossary/tcb:/term}. This + shows that the ${../req/disable-newlib-reentrancy:/spec} requirement is implemented + as specified. +type: validation diff --git a/rtemsspec/tests/spec-rtems/val/perf.yml b/rtemsspec/tests/spec-rtems/val/perf.yml new file mode 100644 index 00000000..0fa5649e --- /dev/null +++ b/rtemsspec/tests/spec-rtems/val/perf.yml @@ -0,0 +1,58 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2021 embedded brains GmbH & Co. KG +enabled-by: true +links: +- role: validation + uid: ../req/root +params: + sample-count: 100 +test-brief: | + This test case provides a context to run ${../if/group:/name} performance + tests. +test-cleanup: null +test-context: +- brief: | + This member provides a barrier identifier. + description: null + member: | + rtems_id barrier_id +- brief: | + This member provides a worker identifier. + description: null + member: | + rtems_id worker_id +- brief: | + This member provides a status code. + description: null + member: | + rtems_status_code status +test-context-support: null +test-description: null +test-includes: +- rtems.h +test-local-includes: +- tx-support.h +test-prepare: null +test-setup: null +test-stop: null +test-support: | + typedef ${.:/test-context-type} Context; + + static void BarrierWaitWorker( rtems_task_argument arg ) + { + Context *ctx; + + ctx = (Context *) arg; + + while ( true ) { + rtems_status_code sc; + + sc = rtems_barrier_wait( ctx->barrier_id, RTEMS_NO_TIMEOUT ); + ctx->end = T_tick(); + T_quiet_rsc_success( sc ); + } + } +test-target: testsuites/validation/tc-barrier-performance.c +test-teardown: null +type: runtime-measurement-test diff --git a/rtemsspec/tests/spec/functional-more.yml b/rtemsspec/tests/spec/functional-more.yml index a7dffe19..3a1b65af 100644 --- a/rtemsspec/tests/spec/functional-more.yml +++ b/rtemsspec/tests/spec/functional-more.yml @@ -9,6 +9,10 @@ links: spec-key: functional-type spec-value: action uid: functional +- role: spec-refinement + spec-key: functional-type + spec-value: function + uid: functional spec-description: null spec-example: null spec-info: diff --git a/rtemsspec/tests/spec/non-functional-more.yml b/rtemsspec/tests/spec/non-functional-more.yml index b7535e0c..aa64a2b2 100644 --- a/rtemsspec/tests/spec/non-functional-more.yml +++ b/rtemsspec/tests/spec/non-functional-more.yml @@ -7,6 +7,10 @@ links: uid: root - role: spec-refinement spec-key: non-functional-type + spec-value: design + uid: non-functional +- role: spec-refinement + spec-key: non-functional-type spec-value: design-group uid: non-functional - role: spec-refinement @@ -15,6 +19,10 @@ links: uid: non-functional - role: spec-refinement spec-key: non-functional-type + spec-value: performance-runtime-limits + uid: non-functional +- role: spec-refinement + spec-key: non-functional-type spec-value: quality uid: non-functional spec-description: null diff --git a/rtemsspec/tests/spec/validation-more.yml b/rtemsspec/tests/spec/validation-more.yml new file mode 100644 index 00000000..1b1858c8 --- /dev/null +++ b/rtemsspec/tests/spec/validation-more.yml @@ -0,0 +1,21 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2023 embedded brains GmbH & Co. KG +enabled-by: true +links: +- role: spec-member + uid: root +- role: spec-refinement + spec-key: method + spec-value: by-inspection + uid: validation +spec-description: null +spec-example: null +spec-info: + dict: + attributes: {} + description: null + mandatory-attributes: all +spec-name: Validation More +spec-type: validation-more +type: spec diff --git a/rtemsspec/tests/spec/validation.yml b/rtemsspec/tests/spec/validation.yml new file mode 100644 index 00000000..3bc3c818 --- /dev/null +++ b/rtemsspec/tests/spec/validation.yml @@ -0,0 +1,24 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2023 embedded brains GmbH & Co. KG +enabled-by: true +links: +- role: spec-member + uid: root +- role: spec-refinement + spec-key: type + spec-value: validation + uid: root +spec-description: null +spec-example: null +spec-info: + dict: + attributes: + method: + description: null + spec-type: name + description: null + mandatory-attributes: all +spec-name: Validation +spec-type: validation +type: spec diff --git a/rtemsspec/tests/test_rtems.py b/rtemsspec/tests/test_rtems.py index cdc40667..2d0a4980 100644 --- a/rtemsspec/tests/test_rtems.py +++ b/rtemsspec/tests/test_rtems.py @@ -1,7 +1,7 @@ # SPDX-License-Identifier: BSD-2-Clause """ Unit tests for the rtemsspec.rtems module. """ -# Copyright (C) 2022 embedded brains GmbH & Co. KG +# Copyright (C) 2022, 2023 embedded brains GmbH & Co. KG # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -26,9 +26,10 @@ import pytest -from rtemsspec.items import EmptyItemCache, Item +from rtemsspec.items import EmptyItemCache, Item, ItemCache from rtemsspec.rtems import augment_with_test_links, is_pre_qualified, \ - recursive_is_enabled + recursive_is_enabled, validate +from rtemsspec.tests.util import create_item_cache_config_and_copy_spec def test_is_pre_qualified(): @@ -117,3 +118,10 @@ def test_recursive_is_enabled(): item_cache.set_enabled([], recursive_is_enabled) assert d.enabled assert not e.enabled + + +def test_validate(tmpdir): + item_cache_config = create_item_cache_config_and_copy_spec( + tmpdir, "spec-rtems", with_spec_types=True) + item_cache = ItemCache(item_cache_config) + assert not validate(item_cache["/req/root"]) diff --git a/specview.py b/specview.py index 9cef096c..3b220bd1 100755 --- a/specview.py +++ b/specview.py @@ -33,7 +33,7 @@ from typing import Any, Dict, List, Optional, Set, Tuple from rtemsspec.items import EmptyItem, Item, ItemCache, ItemMapper, \ ItemGetValueContext from rtemsspec.rtems import augment_with_test_links, is_pre_qualified, \ - recursive_is_enabled + recursive_is_enabled, validate from rtemsspec.sphinxcontent import SphinxContent from rtemsspec.transitionmap import Transition, TransitionMap from rtemsspec.util import load_config @@ -169,72 +169,6 @@ def _view(item: Item, level: int, role: Optional[str], _view(link.item, level + 1, link.role, validated_filter) -_VALIDATION_LEAF = [ - "constraint", - "glossary/group", - "glossary/term", - "interface/domain", - "interface/enum", - "interface/enumerator", - "interface/forward-declaration", - "interface/header-file", - "interface/register-block", - "interface/struct", - "interface/typedef", - "interface/union", - "interface/unspecified-define", - "interface/unspecified-enum", - "interface/unspecified-enumerator", - "interface/unspecified-function", - "interface/unspecified-group", - "interface/unspecified-macro", - "interface/unspecified-object", - "interface/unspecified-struct", - "interface/unspecified-typedef", - "interface/unspecified-union", - "memory-benchmark", - "requirement/functional/action", - "requirement/non-functional/performance-runtime", - "runtime-measurement-test", - "test-case", - "validation/by-analysis", - "validation/by-inspection", - "validation/by-review-of-design", -] - -_VALIDATION_ROLES = _CHILD_ROLES + ["validation"] - - -def _validate_tree(item: Item) -> bool: - pre_qualified = is_pre_qualified(item) - item["_pre_qualified"] = pre_qualified - validated = True - count = 0 - for link in itertools.chain(item.links_to_children(_VALIDATION_ROLES), - item.links_to_parents(_PARENT_ROLES)): - validated = _validate_tree(link.item) and validated - count += 1 - if count == 0: - validated = (not pre_qualified) or (item.type in _VALIDATION_LEAF) - item["_validated"] = validated - return validated - - -def _validate_containers(item: Item) -> None: - for item_2 in itertools.chain( - item.cache.items_by_type["interface/domain"], - item.cache.items_by_type["interface/header-file"]): - for item_3 in item_2.children("interface-placement"): - if not item_3["_validated"]: - item_2["_validated"] = False - break - - -def _validate(item: Item) -> None: - _validate_tree(item) - _validate_containers(item) - - def _validation_count(item: Item) -> int: return len(list(child for child in item.children("validation"))) @@ -466,7 +400,7 @@ def main() -> None: root = item_cache["/req/root"] if args.filter == "none": - _validate(root) + validate(root) _view(root, 0, None, args.validated) elif args.filter == "action-table": for uid in args.UIDs: @@ -475,17 +409,17 @@ def main() -> None: for uid in args.UIDs: _action_list(item_cache[uid]) elif args.filter == "orphan": - _validate(root) + validate(root) for item in item_cache.values(): if item["type"] in ["build", "spec"]: continue if item.enabled and "_validated" not in item: print(item.uid) elif args.filter == "no-validation": - _validate(root) + validate(root) _no_validation(root, []) elif args.filter == "api": - _validate(root) + validate(root) _list_api(item_cache) elif args.filter == "design": _design(item_cache) |