Skip to content
Merged
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
30 changes: 30 additions & 0 deletions src/extensions/score_metamodel/checks/graph_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import operator
from collections.abc import Callable
from functools import reduce
from itertools import chain
from typing import Any, cast

from score_metamodel import (
Expand Down Expand Up @@ -198,3 +199,32 @@ def check_metamodel_graph(
f" Explanation: {explanation}"
)
log.warning_for_need(need, msg)


@graph_check
def check_valid_only_links_to_valid(
app: Sphinx,
all_needs: NeedsView,
log: CheckLogger,
):
# Pre-Gather all *valid* need id's (external, & local)
valid_needs_id_all = set(
x.id for x in all_needs.values() if x.get("status") == "valid"
)
# Pre-Gather all LOCAL *valid* id's to iterate over and check
valid_needs_local = [
x
for x in all_needs.filter_is_external(False).values()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why filter out externals? Doesn't that mean it is ok to link invalid external needs?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you look at the check, what we want to do is we want to check that any LOCAL needs do not link to any invalid needs (local or external).

This way we will not check that external ones link badly.

if x.get("status") == "valid"
]

for need in valid_needs_local:
# Using set comprehension here to enable faster computation for comparisons
all_linked_needs: set[str] = set(
x.id
for x in set(chain(*need._links.values())) # type: ignore
)
invalid_needs = all_linked_needs.difference(valid_needs_id_all)
if invalid_needs:
msg = f"is valid but links to invalid need(s): {invalid_needs}"
log.warning_for_need(need, msg, is_new_check=True)
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
..
# *******************************************************************************
# 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
# *******************************************************************************

#CHECK: check_valid_only_links_to_valid

.. feat_req:: Parent requirement INVALID QM
:id: feat_req__parent__QM_invalid
:safety: QM
:status: invalid

.. We can not yet enable this test. As the check is only an 'info' and not yet a true warning
.. Therefore the test is the inverse of what we will test once it is enabled.

.. #EXPECT: comp_saf_fmea__child__16: is valid but links to invalid need(s):
#EXPECT-NOT: invalid need(s):

.. comp_saf_fmea:: Child requirement
:id: comp_saf_fmea__child__1
:safety: QM
:status: valid
:mitigated_by: feat_req__parent__QM_invalid
Loading