[rtems-central commit] rtems: Gather related items

Sebastian Huber sebh at rtems.org
Tue Nov 21 13:35:41 UTC 2023


Module:    rtems-central
Branch:    master
Commit:    89a0cf739104ffa63eb3db6d39344d539297ac6a
Changeset: http://git.rtems.org/rtems-central/commit/?id=89a0cf739104ffa63eb3db6d39344d539297ac6a

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Tue Nov 21 11:13:16 2023 +0100

rtems: Gather related items

---

 rtemsspec/rtems.py                   | 67 ++++++++++++++++++++++++++++++------
 rtemsspec/tests/test_packagebuild.py | 24 +++++++++++++
 rtemsspec/tests/test_rtems.py        |  5 ++-
 3 files changed, 85 insertions(+), 11 deletions(-)

diff --git a/rtemsspec/rtems.py b/rtemsspec/rtems.py
index cd68f036..9bf36b72 100644
--- a/rtemsspec/rtems.py
+++ b/rtemsspec/rtems.py
@@ -27,7 +27,7 @@
 import base64
 import hashlib
 import itertools
-from typing import Any, Dict, List, Tuple, Union
+from typing import Any, Dict, List, Set, Tuple, Union
 
 from rtemsspec.items import create_unique_link, Item, ItemCache, Link
 from rtemsspec.glossary import augment_glossary_terms
@@ -161,7 +161,8 @@ _VALIDATOR = {
 }
 
 
-def _validate_tree(item: Item) -> bool:
+def _validate_tree(item: Item, related_items: Set[Item]) -> bool:
+    related_items.add(item)
     pre_qualified = is_pre_qualified(item)
     item["_pre_qualified"] = pre_qualified
     validated = True
@@ -169,7 +170,7 @@ def _validate_tree(item: Item) -> bool:
     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
+        validated = _validate_tree(item_2, related_items) and validated
         if link.role == "validation":
             role = _VALIDATION_METHOD[item_2.type]
         elif link.role == "requirement-refinement":
@@ -229,15 +230,21 @@ def _fixup_pre_qualified(item: Item, types: List[str],
                 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,
+def validate(root: Item) -> Set[Item]:
+    """
+    Validates the item tree starting at the root item.
+
+    Returns the set of items related to the root item.
+    """
+    related_items: Set[Item] = set()
+    _validate_tree(root, related_items)
+    _validate_containers(root)
+    _fixup_pre_qualified(root,
                          ["interface/appl-config-group", "interface/group"],
                          ["interface-ingroup", "interface-ingroup-hidden"])
-    _fixup_pre_qualified(item, ["interface/header-file"],
+    _fixup_pre_qualified(root, ["interface/header-file"],
                          "interface-placement")
+    return related_items
 
 
 _API_INTERFACES = [
@@ -302,7 +309,11 @@ class RTEMSItemCache(BuildItem):
         _augment_with_interface_domains(self.item_cache)
         for glossary in ["/glossary-general", "/req/glossary"]:
             augment_glossary_terms(self.item_cache[glossary], [])
-        validate(self.item_cache[self["spec-root-uid"]])
+        self.related_items = validate(self.item_cache[self["spec-root-uid"]])
+        self.related_items_by_type: Dict[str, List[Item]] = {}
+        for item_2 in self.related_items:
+            self.related_items_by_type.setdefault(item_2.type,
+                                                  []).append(item_2)
 
         # Calculate the overall item cache hash.  Ignore QDP configuration
         # items and specification type changes.
@@ -317,3 +328,39 @@ class RTEMSItemCache(BuildItem):
 
     def refresh_link(self, link: Link) -> None:
         link["hash"] = self._hash
+
+    def get_related_items_by_type(self, types: Union[str,
+                                                     List[str]]) -> List[Item]:
+        """ Gets related items by a list of types. """
+        if isinstance(types, str):
+            types = [types]
+        items: List[Item] = []
+        for type_name in types:
+            items.extend(
+                item for item in self.related_items_by_type.get(type_name, []))
+        return sorted(items)
+
+    def get_related_types_by_prefix(
+            self, prefix: Union[str, Tuple[str, ...]]) -> List[str]:
+        """
+        Gets the types of the related items having one of the type prefixes.
+        """
+        return [
+            type_name for type_name in sorted(self.related_items_by_type)
+            if type_name.startswith(prefix)
+        ]
+
+    def get_related_interfaces(self) -> List[Item]:
+        """ Gets the related interfaces. """
+        return self.get_related_items_by_type(
+            self.get_related_types_by_prefix("interface/"))
+
+    def get_related_requirements(self) -> List[Item]:
+        """ Gets the related requirements. """
+        return self.get_related_items_by_type(
+            self.get_related_types_by_prefix("requirement/"))
+
+    def get_related_interfaces_and_requirements(self) -> List[Item]:
+        """ Gets the related interfaces and requirements. """
+        return self.get_related_items_by_type(
+            self.get_related_types_by_prefix(("interface/", "requirement/")))
diff --git a/rtemsspec/tests/test_packagebuild.py b/rtemsspec/tests/test_packagebuild.py
index fa0309d9..6ff9c8e4 100644
--- a/rtemsspec/tests/test_packagebuild.py
+++ b/rtemsspec/tests/test_packagebuild.py
@@ -38,6 +38,7 @@ from rtemsspec.items import EmptyItem, Item, ItemCache, ItemGetValueContext
 from rtemsspec.packagebuild import BuildItem, BuildItemMapper, \
     build_item_input, PackageBuildDirector
 from rtemsspec.packagebuildfactory import create_build_item_factory
+from rtemsspec.rtems import RTEMSItemCache
 from rtemsspec.specverify import verify
 import rtemsspec.testrunner
 from rtemsspec.testrunner import Executable, Report, TestRunner
@@ -144,6 +145,29 @@ def test_packagebuild(caplog, tmpdir, monkeypatch):
     assert "INFO /qdp/steps/b: is disabled" in log
     assert "INFO /qdp/steps/c: output is disabled: /qdp/output/b" in log
 
+    rtems_item_cache = director["/qdp/steps/rtems-item-cache"]
+    assert isinstance(rtems_item_cache, RTEMSItemCache)
+    related_items = rtems_item_cache.get_related_items_by_type("test-case")
+    assert [item.uid for item in related_items] == ["/rtems/test-case"]
+    related_items = rtems_item_cache.get_related_items_by_type(["test-case"])
+    assert [item.uid for item in related_items] == ["/rtems/test-case"]
+    related_types = rtems_item_cache.get_related_types_by_prefix("requirement")
+    assert related_types == [
+        "requirement/functional/function", "requirement/non-functional/design"
+    ]
+    related_items = rtems_item_cache.get_related_interfaces()
+    assert [item.uid for item in related_items] == [
+        "/rtems/domain", "/rtems/group", "/rtems/group-acfg", "/rtems/header",
+        "/rtems/if"
+    ]
+    related_items = rtems_item_cache.get_related_requirements()
+    assert [item.uid for item in related_items] == ["/req/root", "/rtems/req"]
+    related_items = rtems_item_cache.get_related_interfaces_and_requirements()
+    assert [item.uid for item in related_items] == [
+        "/req/root", "/rtems/domain", "/rtems/group", "/rtems/group-acfg",
+        "/rtems/header", "/rtems/if", "/rtems/req"
+    ]
+
     director.build_package(None, ["/qdp/steps/a"])
     log = get_and_clear_log(caplog)
     assert "INFO /qdp/steps/a: build is forced" in log
diff --git a/rtemsspec/tests/test_rtems.py b/rtemsspec/tests/test_rtems.py
index ae399f8a..28586612 100644
--- a/rtemsspec/tests/test_rtems.py
+++ b/rtemsspec/tests/test_rtems.py
@@ -124,7 +124,10 @@ 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"])
+    root = item_cache["/req/root"]
+    assert "_validated" not in root
+    validate(root)
+    assert not root["_validated"]
     api_items = {}
     gather_api_items(item_cache, api_items)
     assert [



More information about the vc mailing list