diff --git a/src/extensions/score_metamodel/BUILD b/src/extensions/score_metamodel/BUILD index e0d5ad80b..7b421e3f1 100644 --- a/src/extensions/score_metamodel/BUILD +++ b/src/extensions/score_metamodel/BUILD @@ -135,3 +135,27 @@ score_pytest( pytest_config = "//:pyproject.toml", deps = [":score_metamodel"], ) + +score_pytest( + name = "file_based_tests_safety", + srcs = ["tests/test_rules_file_based.py"], + data = glob(["tests/rst/safety/*.rst"]) + [ + "tests/__init__.py", + "tests/rst/conf.py", + "tests/rst/needs.json", + ], + pytest_config = "//:pyproject.toml", + deps = [":score_metamodel"], +) + +score_pytest( + name = "file_based_tests_security", + srcs = ["tests/test_rules_file_based.py"], + data = glob(["tests/rst/security/*.rst"]) + [ + "tests/__init__.py", + "tests/rst/conf.py", + "tests/rst/needs.json", + ], + pytest_config = "//:pyproject.toml", + deps = [":score_metamodel"], +) diff --git a/src/extensions/score_metamodel/tests/rst/attributes/test_std_types.rst b/src/extensions/score_metamodel/tests/rst/attributes/test_std_types.rst new file mode 100644 index 000000000..49554380c --- /dev/null +++ b/src/extensions/score_metamodel/tests/rst/attributes/test_std_types.rst @@ -0,0 +1,34 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + + +.. test_metadata:: + :id: test_metadata__std_types + :fully_verifies_list: tool_req__docs_stdreq_types[version==1], tool_req__docs_stdwp_types[version==1] + :test_type: requirements_based + :derivation_technique: requirements_based + + Tests that std_req and std_wp directives are supported by the metamodel. + + +.. std_req:: Standard requirement + :id: std_req__iso26262__test__001 + :status: valid + :expect_not: unknown directive + + +.. std_wp:: Standard workproduct + :id: std_wp__iso26262__test__001 + :status: valid + :expect_not: unknown directive diff --git a/src/extensions/score_metamodel/tests/rst/options/gd_req_comp.rst b/src/extensions/score_metamodel/tests/rst/options/gd_req_comp.rst index 0a2ae3fee..b4aebff4c 100644 --- a/src/extensions/score_metamodel/tests/rst/options/gd_req_comp.rst +++ b/src/extensions/score_metamodel/tests/rst/options/gd_req_comp.rst @@ -15,7 +15,7 @@ .. test_metadata:: :id: test_metadata__metamodel_link_checks - :partially_verifies_list: tool_req__docs_req_types + :partially_verifies_list: tool_req__docs_req_types[version==1] :test_type: requirements_based :derivation_technique: requirements_based diff --git a/src/extensions/score_metamodel/tests/rst/options/test_options_extra_option.rst b/src/extensions/score_metamodel/tests/rst/options/test_options_extra_option.rst index a7f1804c1..f3c2d7d99 100644 --- a/src/extensions/score_metamodel/tests/rst/options/test_options_extra_option.rst +++ b/src/extensions/score_metamodel/tests/rst/options/test_options_extra_option.rst @@ -15,7 +15,7 @@ .. test_metadata:: :id: test_metadata__extra_options - :partially_verifies_list: tool_req__docs_req_types, tool_req__docs_common_attr_status + :partially_verifies_list: tool_req__docs_req_types[version==1], tool_req__docs_common_attr_status[version==1] :test_type: requirements_based :derivation_technique: requirements_based diff --git a/src/extensions/score_metamodel/tests/rst/options/test_options_failure_effect.rst b/src/extensions/score_metamodel/tests/rst/options/test_options_failure_effect.rst index 9d0b9a1fc..22425e9a0 100644 --- a/src/extensions/score_metamodel/tests/rst/options/test_options_failure_effect.rst +++ b/src/extensions/score_metamodel/tests/rst/options/test_options_failure_effect.rst @@ -15,7 +15,7 @@ .. test_metadata:: :id: test_metadata__failure_effect - :partially_verifies_list: tool_req__docs_saf_attr_fmea_failure_effect + :fully_verifies_list: tool_req__docs_saf_attr_fmea_failure_effect[version==1] :test_type: requirements_based :derivation_technique: requirements_based @@ -158,7 +158,7 @@ .. feat_saf_fmea:: Empty failure_effect :id: feat_saf_fmea__test__empty_failure_effect :fault_id: FMEA_05 - :failure_effect: + :failure_effect: :sufficient: yes :status: valid :expect: feat_saf_fmea__test__empty_failure_effect: is missing required attribute: `failure_effect`. diff --git a/src/extensions/score_metamodel/tests/rst/options/test_options_options.rst b/src/extensions/score_metamodel/tests/rst/options/test_options_options.rst index 1fb3a046b..576c6e19c 100644 --- a/src/extensions/score_metamodel/tests/rst/options/test_options_options.rst +++ b/src/extensions/score_metamodel/tests/rst/options/test_options_options.rst @@ -15,7 +15,7 @@ .. test_metadata:: :id: test_metadata__mandatory_options_and_links - :partially_verifies_list: tool_req__docs_common_attr_status, tool_req__docs_req_types + :partially_verifies_list: tool_req__docs_common_attr_status[version==1], tool_req__docs_req_types[version==1] :test_type: requirements_based :derivation_technique: requirements_based diff --git a/src/extensions/score_metamodel/tests/rst/options/wp_comp.rst b/src/extensions/score_metamodel/tests/rst/options/wp_comp.rst index 3f26aaef8..fd203081b 100644 --- a/src/extensions/score_metamodel/tests/rst/options/wp_comp.rst +++ b/src/extensions/score_metamodel/tests/rst/options/wp_comp.rst @@ -15,7 +15,7 @@ .. test_metadata:: :id: test_metadata__wp_comp - :partially_verifies_list: tool_req__docs_stdwp_types, tool_req__docs_wp_types + :fully_verifies_list: tool_req__docs_stdwp_types[version==1], tool_req__docs_wp_types[version==1] :test_type: requirements_based :derivation_technique: requirements_based @@ -31,24 +31,17 @@ .. std_req:: Standard IIC requirement :id: std_req__aspice_40__iic_001 ----- - -.. Expect no warning with "complies" .. workproduct:: No Link is ok, since complies is optional :id: wp__001 :expect_not: complies ---- - -.. Expect no warning with "complies" .. workproduct:: Linking to std_wp is allowed :id: wp__002 :complies: std_wp__iso26262__001 :expect_not: complies ---- .. FIXME: this will currently be printed as an INFO, and not as a warning. Re-enable EXCPECT once we can enable that as a warning. @@ -58,9 +51,6 @@ :complies: std_req__iso26262__001 :expect: std_req__iso26262__001` does not fulfill condition `{'or': ['id contains aspice_40__iic', 'id contains std_wp']}`. Explanation: Workproducts may only link to ASPICE 40 IIC stakeholder requirements. Please ensure that the linked requirement is an ASPICE 40 IIC stakeholder requirement. ---- - - .. workproduct:: But it can refer to std_req if it is an IIC requirement :id: wp__003_two diff --git a/src/extensions/score_metamodel/tests/rst/safety/test_saf_mandatory_attrs.rst b/src/extensions/score_metamodel/tests/rst/safety/test_saf_mandatory_attrs.rst new file mode 100644 index 000000000..205d4dec8 --- /dev/null +++ b/src/extensions/score_metamodel/tests/rst/safety/test_saf_mandatory_attrs.rst @@ -0,0 +1,126 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + + +.. test_metadata:: + :id: test_metadata__saf_mandatory_attrs + :fully_verifies_list: + tool_req__docs_saf_attr_dfa_failure_id[version==2], + tool_req__docs_saf_attr_fmea_fault_id[version==2], + tool_req__docs_saf_attrs_sufficient[version==1], + tool_req__docs_saf_attrs_content[version==2] + :partially_verifies_list: tool_req__docs_saf_attrs_mandatory[version==1] + :test_type: requirements_based + :derivation_technique: requirements_based + + Tests that all safety analysis types have required mandatory attributes: + - DFA: failure_id + - FMEA: fault_id + - All: failure_effect, status, sufficient, content + + +.. feat_saf_dfa:: Missing failure_id + :id: feat_saf_dfa__test__missing_fid + :status: valid + :failure_effect: signal lost + :sufficient: yes + :expect: is missing required attribute: `failure_id` + + +.. comp_saf_dfa:: Valid failure_id + :id: comp_saf_dfa__test__good_fid + :status: valid + :failure_id: df_good_001 + :failure_effect: communication lost + :sufficient: no + :expect_not: missing required attribute: `failure_id` + + +.. feat_saf_fmea:: Missing fault_id + :id: feat_saf_fmea__test__missing_fault + :status: valid + :failure_effect: valve stuck + :sufficient: yes + :expect: is missing required attribute: `fault_id` + + +.. comp_saf_fmea:: Valid fault_id + :id: comp_saf_fmea__test__good_fault + :status: valid + :fault_id: fault_good_001 + :failure_effect: valve stuck + :sufficient: no + :expect_not: missing required attribute: `fault_id` + + +.. plat_saf_dfa:: Missing failure_effect + :id: plat_saf_dfa__test__missing_fe + :status: valid + :failure_id: df_fe_bad + :sufficient: yes + :expect: is missing required attribute: `failure_effect` + + +.. feat_saf_dfa:: Missing sufficient + :id: feat_saf_dfa__test__missing_suff + :status: valid + :failure_id: df_suff_bad + :failure_effect: output wrong + :expect: is missing required attribute: `sufficient` + + +.. feat_saf_fmea:: Valid sufficient yes + :id: feat_saf_fmea__test__suff_ok_1 + :status: valid + :fault_id: fault_suff_ok_1 + :failure_effect: system error + :sufficient: yes + :expect_not: does not follow pattern + + +.. comp_saf_dfa:: Valid sufficient no + :id: comp_saf_dfa__test__suff_ok_2 + :status: valid + :failure_id: df_suff_ok_2 + :failure_effect: signal lost + :sufficient: no + :expect_not: does not follow pattern + + +.. feat_saf_dfa:: Invalid sufficient value + :id: feat_saf_dfa__test__suff_bad + :status: valid + :failure_id: df_suff_bad_2 + :failure_effect: bad output + :sufficient: maybe + :expect: does not follow pattern + + +.. feat_saf_fmea:: Valid content + :id: feat_saf_fmea__test__content_ok + :status: valid + :fault_id: fault_content_ok + :failure_effect: crash + :sufficient: yes + + This is the content of the FMEA entry. + + +.. comp_saf_dfa:: Missing content + :id: comp_saf_dfa__test__content_bad + :status: valid + :failure_id: df_content_bad + :failure_effect: no response + :sufficient: no + :expect: is missing required attribute: `content`. diff --git a/src/extensions/score_metamodel/tests/rst/safety/test_saf_optional_attrs.rst b/src/extensions/score_metamodel/tests/rst/safety/test_saf_optional_attrs.rst new file mode 100644 index 000000000..283be5128 --- /dev/null +++ b/src/extensions/score_metamodel/tests/rst/safety/test_saf_optional_attrs.rst @@ -0,0 +1,88 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +.. test_metadata:: + :id: test_metadata__saf_optional_attrs + :fully_verifies_list: tool_req__docs_saf_attrs_mitigation_issue[version==1], tool_req__docs_saf_attrs_safety_relevant[version==1], tool_req__docs_saf_attrs_root_cause[version==1] + :test_type: requirements_based + :derivation_technique: requirements_based + + Tests optional attributes for safety analysis types: + - mitigation_issue: GitHub issue URL pattern + - safety_relevant: yes/no for all SAF types + - root_cause: non-empty content for FMEA + + +.. feat_saf_dfa:: Valid mitigation issue + :id: feat_saf_dfa__opt__001 + :failure_id: df_opt_001 + :failure_effect: comms loss + :sufficient: no + :status: valid + :mitigation_issue: https://github.com/eclipse-score/docs-as-code/issues/42 + + +.. feat_saf_fmea:: Valid mitigation issue 2 + :id: feat_saf_fmea__opt__001 + :fault_id: fault_opt_001 + :failure_effect: valve stuck + :sufficient: yes + :status: valid + :mitigation_issue: https://github.com/owner/repo/issues/123 + + +.. comp_saf_dfa:: Safety relevant yes + :id: comp_saf_dfa__opt__001 + :failure_id: df_opt_003 + :failure_effect: signal noise + :sufficient: no + :status: valid + :safety_relevant: yes + + +.. comp_saf_dfa:: Safety relevant no + :id: comp_saf_dfa__opt__002 + :failure_id: df_opt_004 + :failure_effect: power failure + :sufficient: yes + :status: valid + :safety_relevant: no + + +.. feat_saf_dfa:: Invalid safety relevant + :id: feat_saf_dfa__opt__bad_001 + :failure_id: df_opt_bad_001 + :failure_effect: bad value + :sufficient: no + :status: valid + :safety_relevant: perhaps + :expect: does not follow pattern + + +.. feat_saf_fmea:: FMEA with root cause + :id: feat_saf_fmea__opt__002 + :fault_id: fault_opt_002 + :failure_effect: component failure + :sufficient: no + :status: valid + :root_cause: manufacturing defect in solder joints + + +.. comp_saf_fmea:: Comp FMEA with root cause + :id: comp_saf_fmea__opt__001 + :fault_id: fault_opt_003 + :failure_effect: software crash + :sufficient: yes + :status: valid + :root_cause: null pointer dereference in interrupt handler diff --git a/src/extensions/score_metamodel/tests/rst/safety/test_saf_types.rst b/src/extensions/score_metamodel/tests/rst/safety/test_saf_types.rst new file mode 100644 index 000000000..d0f0f4f8c --- /dev/null +++ b/src/extensions/score_metamodel/tests/rst/safety/test_saf_types.rst @@ -0,0 +1,84 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +.. test_metadata:: + :id: test_metadata__saf_types + :fully_verifies_list: tool_req__docs_saf_types[version==2] + :partially_verifies_list: tool_req__docs_saf_attrs_mandatory[version==1] + :test_type: requirements_based + :derivation_technique: requirements_based + + Tests that all safety analysis need types are supported and that + mandatory attributes are enforced. + + +.. feat_saf_fmea:: Feature FMEA entry + :id: feat_saf_fmea__test__001 + :status: valid + :fault_id: fault_1 + :failure_effect: system hangs + :sufficient: yes + :expect_not: unknown directive + + +.. comp_saf_fmea:: Component FMEA entry + :id: comp_saf_fmea__test__001 + :status: valid + :fault_id: fault_2 + :failure_effect: valve stuck open + :sufficient: no + :expect_not: unknown directive + + +.. plat_saf_dfa:: Platform DFA entry + :id: plat_saf_dfa__test__001 + :status: valid + :failure_id: df_1 + :failure_effect: signal delay + :sufficient: yes + :expect_not: unknown directive + + +.. feat_saf_dfa:: Feature DFA entry + :id: feat_saf_dfa__test__001 + :status: valid + :failure_id: df_2 + :failure_effect: unexpected output + :sufficient: yes + :expect_not: unknown directive + + +.. comp_saf_dfa:: Component DFA entry + :id: comp_saf_dfa__test__001 + :status: valid + :failure_id: df_3 + :failure_effect: communication loss + :sufficient: no + :expect_not: unknown directive + + +.. feat_saf_fmea:: Missing failure effect + :id: feat_saf_fmea__test__bad_001 + :status: valid + :fault_id: fault_bad + :sufficient: yes + :expect: is missing required attribute: `failure_effect`. + + +.. comp_saf_dfa:: Missing status + :id: comp_saf_dfa__test__bad_001 + :failure_id: df_bad + :failure_effect: no status + :sufficient: yes + :expect: is missing required attribute: `status`. diff --git a/src/extensions/score_metamodel/tests/rst/safety/test_saf_violates.rst b/src/extensions/score_metamodel/tests/rst/safety/test_saf_violates.rst new file mode 100644 index 000000000..1bc9c1232 --- /dev/null +++ b/src/extensions/score_metamodel/tests/rst/safety/test_saf_violates.rst @@ -0,0 +1,132 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +.. test_metadata:: + :id: test_metadata__saf_violates + :partially_verifies_list: tool_req__docs_saf_attrs_violates[version==2] + :test_type: requirements_based + :derivation_technique: requirements_based + + Tests that SAF needs link `violates` to correct diagram types per the table: + + * feat_saf_dfa -> feat_arc_sta + * comp_saf_dfa -> comp_arc_sta + * feat_saf_fmea -> feat_arc_dyn, feat_arc_sta + * comp_saf_fmea -> comp_arc_dyn, comp_arc_sta + + +.. feat_arc_sta:: Stub Feature Static Architecture + :id: feat_arc_sta__001 + +.. feat_arc_dyn:: Stub Feature Dynamic Architecture + :id: feat_arc_dyn__001 + +.. comp_arc_sta:: Stub Component Static Architecture + :id: comp_arc_sta__001 + +.. comp_arc_dyn:: Stub Component Dynamic Architecture + :id: comp_arc_dyn__001 + +.. feat_arc_sta:: Stub Feature Static Architecture (bad target) + :id: feat_arc_sta__bad_001 + +.. comp_arc_sta:: Stub Component Static Architecture (bad target) + :id: comp_arc_sta__bad_001 + +.. comp_arc_dyn:: Stub Component Dynamic Architecture (bad target) + :id: comp_arc_dyn__bad_001 + + +.. feat_saf_dfa:: feat DFA violates feat arc sta + :id: feat_saf_dfa__viol__001 + :failure_id: df_001 + :failure_effect: comms loss + :sufficient: no + :status: valid + :violates: feat_arc_sta__001 + + +.. comp_saf_dfa:: comp DFA violates comp arc sta + :id: comp_saf_dfa__viol__001 + :failure_id: df_002 + :failure_effect: signal lost + :sufficient: no + :status: valid + :violates: comp_arc_sta__001 + + +.. feat_saf_fmea:: feat FMEA violates feat arc dyn + :id: feat_saf_fmea__viol__001 + :fault_id: fault_001 + :failure_effect: valve stuck + :sufficient: yes + :status: valid + :violates: feat_arc_dyn__001 + + +.. feat_saf_fmea:: feat FMEA violates feat arc sta + :id: feat_saf_fmea__viol__002 + :fault_id: fault_002 + :failure_effect: sensor drift + :sufficient: no + :status: valid + :violates: feat_arc_sta__001 + + +.. comp_saf_fmea:: comp FMEA violates comp arc dyn + :id: comp_saf_fmea__viol__001 + :fault_id: fault_003 + :failure_effect: motor failure + :sufficient: yes + :status: valid + :violates: comp_arc_dyn__001 + + +.. comp_saf_fmea:: comp FMEA violates comp arc sta + :id: comp_saf_fmea__viol__002 + :fault_id: fault_004 + :failure_effect: encoder fault + :sufficient: no + :status: valid + :violates: comp_arc_sta__001 + + +.. feat_saf_dfa:: feat DFA violates comp arc sta + :id: feat_saf_dfa__viol__bad_001 + :failure_id: df_bad_001 + :failure_effect: wrong link + :sufficient: no + :status: valid + :violates: comp_arc_sta__bad_001 + :expect: must reference Feature & Feature Package Diagram + + +.. feat_saf_fmea:: feat FMEA violates comp arc + :id: feat_saf_fmea__viol__bad_001 + :fault_id: fault_bad_001 + :failure_effect: wrong link target + :sufficient: yes + :status: valid + :violates: comp_arc_dyn__bad_001 + :expect: must reference Feature Sequence Diagram + + +.. comp_saf_dfa:: comp DFA violates feat arc + :id: comp_saf_dfa__viol__bad_001 + :failure_id: df_bad_002 + :failure_effect: wrong link target + :sufficient: no + :status: valid + :violates: feat_arc_sta__bad_001 + :expect: must reference Component Package Diagram diff --git a/src/extensions/score_metamodel/tests/rst/security/test_security_types.rst b/src/extensions/score_metamodel/tests/rst/security/test_security_types.rst new file mode 100644 index 000000000..e30547939 --- /dev/null +++ b/src/extensions/score_metamodel/tests/rst/security/test_security_types.rst @@ -0,0 +1,130 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +.. test_metadata:: + :id: test_metadata__sec_types + :fully_verifies_list: tool_req__docs_sec_types[version==2], tool_req__docs_sec_attrs_mandatory[version==1] + :partially_verifies_list: tool_req__docs_sec_attrs_optional[version==1] + :test_type: requirements_based + :derivation_technique: requirements_based + + Tests that security analysis types are supported with mandatory and optional attributes. + + +.. feat_sec_threat:: STRIDE threat feature + :id: feat_sec_threat__test__001 + :threat_id: EX_01_01 + :status: valid + + Feature STRIDE threat analysis entry. + + +.. comp_sec_threat:: STRIDE threat component + :id: comp_sec_threat__test__001 + :threat_id: MT_01_01 + :status: valid + + Component STRIDE threat analysis entry. + + +.. plat_sec_threat:: STRIDE threat platform + :id: plat_sec_threat__test__001 + :threat_id: AU_01_01 + :status: valid + + Platform STRIDE threat analysis entry. + + +.. feat_sec_ana:: Threat scenario feature + :id: feat_sec_ana__test__001 + :threat_scenario_id: AS_01_01 + :status: valid + :sufficient: no + :threat_effect: unauthorized access + + Feature threat scenario analysis. + + +.. comp_sec_ana:: Threat scenario component + :id: comp_sec_ana__test__001 + :threat_scenario_id: CO_01_01 + :status: valid + :sufficient: yes + :threat_effect: denial of service + + Component threat scenario analysis. + + +.. plat_sec_ana:: Threat scenario platform + :id: plat_sec_ana__test__001 + :threat_scenario_id: SC_01_02 + :status: valid + :sufficient: no + :threat_effect: information disclosure + + Platform threat scenario analysis. + + +.. feat_sec_ana:: Missing threat effect + :id: feat_sec_ana__test__missing_effect + :threat_scenario_id: AS_01_02 + :status: valid + :sufficient: yes + :expect: is missing required attribute: `threat_effect` + + Failing threat scenario without threat_effect. + + +.. comp_sec_ana:: Missing sufficient + :id: comp_sec_ana__test__missing_sufficient + :threat_scenario_id: CO_01_02 + :status: valid + :threat_effect: crash + :expect: is missing required attribute: `sufficient` + + Failing threat scenario without sufficient. + + +.. feat_sec_ana:: Invalid sufficient + :id: feat_sec_ana__test__bad_sufficient + :threat_scenario_id: AS_01_04 + :status: valid + :sufficient: maybe + :threat_effect: failure + :expect: does not follow pattern + + Failing threat scenario with invalid sufficient value. + + +.. feat_sec_ana:: With mitigation issue + :id: feat_sec_ana__test__mitigation + :threat_scenario_id: SI_01_02 + :status: valid + :sufficient: no + :threat_effect: data leak + :mitigation_issue: https://github.com/eclipse-score/docs-as-code/issues/42 + + Threat scenario with mitigation tracking. + + +.. comp_sec_ana:: Invalid mitigation issue URL + :id: comp_sec_ana__test__bad_mitigation + :threat_scenario_id: UI_01_01 + :status: valid + :sufficient: yes + :threat_effect: spoofing + :mitigation_issue: not-a-valid-url + :expect: does not follow pattern + + Failing threat scenario with invalid mitigation issue URL. diff --git a/src/extensions/score_source_code_linker/__init__.py b/src/extensions/score_source_code_linker/__init__.py index 644a41324..c02d83b07 100644 --- a/src/extensions/score_source_code_linker/__init__.py +++ b/src/extensions/score_source_code_linker/__init__.py @@ -359,11 +359,42 @@ def setup(app: Sphinx) -> dict[str, str | bool]: } +def _extract_version_from_id(id: str) -> tuple[str, int | None]: + """Extract base ID and version number from a potentially versioned need ID. + + Examples: + "req_id" => ("req_id", None) + "req_id[version==2]" => ("req_id", 2) + """ + import re + + match = re.search(r"\[version==(\d+)\]", id) + if match: + return re.sub(r"\[version==[^\]]+\]", "", id), int(match.group(1)) + return id, None + + def find_need(all_needs: NeedsMutable, id: str) -> NeedItem | None: """ Finds a need by ID in the needs collection. + Strips version suffixes for lookup and warns if test links to older version. """ - return all_needs.get(id) + base_id, test_version = _extract_version_from_id(id) + need = all_needs.get(base_id) + + # Check version compatibility if version was specified + # req-Id: tool_req__docs_common_attr_suspicious + if need is not None and test_version is not None: + need_version = need.get("version") + if need_version is not None and int(need_version) > test_version: + LOGGER.warning( + f"Test links to outdated version: '{id}' references " + f"version {test_version}, but need '{base_id}' is version {need_version}. " + f"Update test to reference version {need_version}.", + type="score_source_code_linker", + ) + + return need def _log_existing_links(needs: NeedsMutable) -> None: