Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions .github/workflows/_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,22 @@ jobs:
needs: [docs_bzl, bazel_tests]
runs-on: ubuntu-latest
steps:
- name: Download test reports
# Both Python versions produce Bazel reports at the same paths. Download
# one version for documentation so concurrent artifact extraction cannot
# corrupt overlapping files or duplicate test cases in the documentation.
# Both versions remain available as separate artifacts for inspection.
- name: Download Bazel test reports for documentation
uses: actions/download-artifact@v8
with:
pattern: tests-report-*
name: tests-report-bazel-3.12
path: tests-report

# The docs.bzl report filenames include their Python version and suite,
# so these artifacts can be merged without overlapping paths.
- name: Download docs.bzl test reports
uses: actions/download-artifact@v8
with:
pattern: tests-report-docs-bzl-*
path: tests-report
merge-multiple: true

Expand Down
13 changes: 9 additions & 4 deletions docs/internals/requirements/requirements.rst
Original file line number Diff line number Diff line change
Expand Up @@ -631,28 +631,33 @@ Architecture Attributes
:id: tool_req__docs_arch_link_safety_to_req
:tags: Architecture
:implemented: PARTIAL
:version: 2
:version: 3
:satisfies: gd_req__arch_linkage_requirement[version==1]
:parent_covered: YES

Docs-as-Code shall enforce that architecture elements of type
:need:`tool_req__docs_arch_types` with ``safety != QM`` are linked to at least one
requirements of type :need:`tool_req__docs_req_types` with the exact same ``safety``
value.
requirement of type :need:`tool_req__docs_req_types` with ``safety != QM``.
For features and components, this shall be checked through incoming
``satisfied_by`` allocations; for architectural views and interfaces, through
``fulfils``. Additional QM requirements are permitted.

.. note:: implemented as info to enable non-breaking transition

.. tool_req:: Ensure qm architecture elements do not fulfill safety requirements
:id: tool_req__docs_arch_link_qm_to_safety_req
:tags: Architecture
:implemented: PARTIAL
:version: 2
:version: 3
:satisfies: gd_req__arch_linkage_requirement[version==1]
:parent_covered: YES

Docs-as-Code shall enforce that architecture elements of type
:need:`tool_req__docs_arch_types` with ``safety == QM`` are not linked to requirements
of type :need:`tool_req__docs_req_types` with ``safety != QM``.
This shall be checked for mandatory ``satisfied_by`` allocations of feature and
component requirements and for optional ``fulfils`` links when present.
QM requirements may be allocated to QM or safety architecture elements.


.. tool_req:: Restrict links for safety requirements
Expand Down
14 changes: 14 additions & 0 deletions src/extensions/docs/rst_filebased_testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,20 @@ You only need to match a unique substring, not the full message. For example:
For `:expect:` use as much as possible of the error message, however for `:expect_not:` use as little as possible
to catch all other issues that MIGHT occur and to avoid for typos etc.

### Informational diagnostics

Checks marked `info_only` report to the Sphinx status stream. Use
`:expect_info:` and `:expect_info_not:` to assert these diagnostics at the
need's own location. The existing `:expect:` and `:expect_not:` options continue
to check warnings, so a fixture can distinguish compatibility errors from
informational allocation-completeness diagnostics.

.. comp:: Safety component without an allocated safety requirement
:id: comp__example__missing_allocation
:safety: ASIL_B
:expect_info: must have at least one safety requirement allocated via satisfied_by.
:expect_not: must have at least one safety requirement allocated via satisfied_by.

### Setup needs

Prerequisite needs (link targets, shared fixtures) carry no `:expect:` /
Expand Down
38 changes: 32 additions & 6 deletions src/extensions/score_metamodel/metamodel.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1238,20 +1238,46 @@ graph_checks:
# req-Id: tool_req__docs_arch_link_qm_to_safety_req
tool_req__docs_arch_link_qm_to_safety_req:
needs:
include: feat_arc_sta, logic_arc_int, logic_arc_int_op, comp_arc_sta, real_arc_int, real_arc_int_op
include: feat, feat_arc_sta, feat_arc_dyn, logic_arc_int, logic_arc_int_op, comp, comp_arc_sta, comp_arc_dyn, real_arc_int, real_arc_int_op
condition: safety == QM
check_all:
fulfils: safety != QM
explanation: An QM architecture element cannot implement ASIL requirements.
fulfils: safety == QM
explanation: A QM architecture element cannot fulfil safety requirements.
info_only: true
Comment thread
AlexanderLanin marked this conversation as resolved.

# Allocation compatibility is checked from the requirement, where the
# mandatory satisfied_by link identifies every allocated feature/component.
# QM requirements impose no safety restriction on their allocation targets.
# req-Id: tool_req__docs_arch_link_qm_to_safety_req
tool_req__docs_req_allocation_safety:
needs:
include: feat_req, comp_req
condition: safety != QM
check_all:
satisfied_by: safety != QM
explanation: A safety requirement cannot be allocated to a QM architecture element.
info_only: true

# Features/components receive requirements through incoming satisfied_by
# links. Their optional fulfils links do not replace this allocation.
# req-Id: tool_req__docs_arch_link_safety_to_req
tool_req__docs_allocation_safety_to_req:
needs:
include: feat, comp
condition: safety != QM
check_one:
satisfied_by_back: safety != QM
explanation: A safety relevant feature or component must have at least one safety requirement allocated via satisfied_by.
info_only: true

# req-Id: tool_req__docs_arch_link_safety_to_req
tool_req__docs_arch_link_safety_to_req:
needs:
include: feat_arc_sta, feat_arc_dyn, logic_arc_int, comp, comp_arc_sta, comp_arc_dyn, real_arc_int
include: feat_arc_sta, feat_arc_dyn, logic_arc_int, comp_arc_sta, comp_arc_dyn, real_arc_int
condition: safety != QM
check_one:
fulfils: safety == self.safety
explanation: A safety relevant architecture element must be linked to at least one requirement with the exact same safety value via fulfils.
fulfils: safety != QM
explanation: A safety relevant architecture element must be linked to at least one safety requirement via fulfils.
info_only: true

# req-Id: tool_req__docs_req_arch_link_safety_to_arch
Expand Down
13 changes: 9 additions & 4 deletions src/extensions/score_metamodel/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ def __init__(self):
self._mock_logger = MagicMock(spec=SphinxLoggerAdapter)
self._mock_logger.warning = MagicMock()
self._mock_logger.info = MagicMock()
app_path = MagicMock()
super().__init__(self._mock_logger, app_path)
# Direct pytest uses the source-root prefix; Bazel runfiles omit it.
# A concrete root keeps both location formats meaningful to assert.
super().__init__(self._mock_logger, ".")

def assert_no_warnings(self):
if self.warnings:
Expand Down Expand Up @@ -75,7 +76,9 @@ def assert_warning(self, expected_substring: str, expect_location: bool = True):
assert kwargs["type"] == "score_metamodel"

if expect_location:
assert kwargs["location"] == "docname.rst:42", kwargs
assert kwargs["location"] in ("docname.rst:42", "./docname.rst:42"), (
kwargs
)

def assert_info(self, expected_substring: str, expect_location: bool = True):
"""
Expand All @@ -102,7 +105,9 @@ def assert_info(self, expected_substring: str, expect_location: bool = True):
assert kwargs["type"] == "score_metamodel"

if expect_location:
assert kwargs["location"] == "docname.rst:42", kwargs
assert kwargs["location"] in ("docname.rst:42", "./docname.rst:42"), (
kwargs
)

return FakeCheckLogger()

Expand Down
49 changes: 16 additions & 33 deletions src/extensions/score_metamodel/tests/rst/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,22 +41,6 @@

def setup(app: Sphinx):
add_needs_fields: dict[str, Any] = {
"expect_not": {
"description": "Partial string that is not exepcted to be in rst test warnings",
"schema": {
"type": "array",
"items": {"type": "string"},
},
"nullable": True,
},
"expect": {
"description": "String that is exepcted to be in rst test warnings",
"schema": {
"type": "array",
"items": {"type": "string"},
},
"nullable": True,
},
"test_type": {
"description": "The test type that this test has",
"schema": {
Expand All @@ -71,26 +55,25 @@ def setup(app: Sphinx):
},
"nullable": True,
},
"fully_verifies_list": {
"description": "List of requirements that this RST test fully verifies",
"schema": {
"type": "array",
"items": {"type": "string"},
},
"nullable": True,
},
"partially_verifies_list": {
"description": "List of requirements that this RST test partially verifies",
"schema": {
"type": "array",
"items": {"type": "string"},
},
"nullable": True,
},
}
for option, description in {
"expect": "Expected substrings in warning diagnostics",
"expect_not": "Forbidden substrings in warning diagnostics",
"expect_info": "Expected substrings in informational diagnostics",
"expect_info_not": "Forbidden substrings in informational diagnostics",
"fully_verifies_list": "Requirements that this RST test fully verifies",
"partially_verifies_list": "Requirements that this RST test partially verifies",
}.items():
add_needs_fields[option] = {
"description": description,
"schema": {"type": "array", "items": {"type": "string"}},
"nullable": True,
}
add_options_regex_base = {
"expect_not": "^.*$",
"expect": "^.*$",
"expect_not": "^.*$",
"expect_info": "^.*$",
"expect_info_not": "^.*$",
}
add_options_test_metadata = {
"derivation_technique": "^.*$",
Expand Down
Loading
Loading