From: Stefano Tondo <[email protected]>
Fix incorrect function call when processing SPDX_CUSTOM_ANNOTATION_VARS.
The code was calling new_annotation() as a standalone function, but it
should be called as a method on the build_objset object.
Error:
new_annotation(d, build_objset, build, ...)
Corrected to:
build_objset.new_annotation(d, build_objset, build, ...)
This bug would cause a NameError at runtime if SPDX_CUSTOM_ANNOTATION_VARS
was set to a non-empty value, preventing SPDX document generation.
The fix aligns with how new_annotation() is called elsewhere in the
codebase and matches the SBOMObjset class method signature.
Signed-off-by: Stefano Tondo <[email protected]>
Signed-off-by: Mathieu Dubois-Briand <[email protected]>
(cherry picked from commit 52ab3b640c6bb7ece34cb4ea6026fd6375f17af4)
Signed-off-by: Steve Sakoman <[email protected]>
---
meta/lib/oe/spdx30_tasks.py | 4 +-
meta/lib/oeqa/selftest/cases/spdx.py | 85 +++++++++++++++++++++++++---
2 files changed, 79 insertions(+), 10 deletions(-)
diff --git a/meta/lib/oe/spdx30_tasks.py b/meta/lib/oe/spdx30_tasks.py
index f2f133005d..4d11b3c289 100644
--- a/meta/lib/oe/spdx30_tasks.py
+++ b/meta/lib/oe/spdx30_tasks.py
@@ -498,9 +498,7 @@ def create_spdx(d):
build_objset.set_is_native(is_native)
for var in (d.getVar("SPDX_CUSTOM_ANNOTATION_VARS") or "").split():
- new_annotation(
- d,
- build_objset,
+ build_objset.new_annotation(
build,
"%s=%s" % (var, d.getVar(var)),
oe.spdx30.AnnotationType.other,
diff --git a/meta/lib/oeqa/selftest/cases/spdx.py
b/meta/lib/oeqa/selftest/cases/spdx.py
index 8cd4e83ca2..f548dd4be7 100644
--- a/meta/lib/oeqa/selftest/cases/spdx.py
+++ b/meta/lib/oeqa/selftest/cases/spdx.py
@@ -34,7 +34,7 @@ class SPDX22Check(OESelftestTestCase):
arch_dir = get_bb_var("PACKAGE_ARCH", target_name)
spdx_version = get_bb_var("SPDX_VERSION")
# qemux86-64 creates the directory qemux86_64
- #arch_dir = arch_var.replace("-", "_")
+ # arch_dir = arch_var.replace("-", "_")
full_file_path = os.path.join(
deploy_dir, "spdx", spdx_version, arch_dir, high_level_dir,
spdx_file
@@ -89,15 +89,12 @@ class SPDX3CheckBase(object):
return objset
def check_recipe_spdx(self, target_name, spdx_path, *, task=None,
extraconf=""):
- config = (
- textwrap.dedent(
- f"""\
+ config = textwrap.dedent(
+ f"""\
INHERIT:remove = "create-spdx"
INHERIT += "{self.SPDX_CLASS}"
"""
- )
- + textwrap.dedent(extraconf)
- )
+ ) + textwrap.dedent(extraconf)
self.write_config(config)
@@ -286,3 +283,77 @@ class SPDX30Check(SPDX3CheckBase, OESelftestTestCase):
break
else:
self.assertTrue(False, "Unable to find imported Host SpdxID")
+
+ def test_custom_annotation_vars(self):
+ """
+ Test that SPDX_CUSTOM_ANNOTATION_VARS properly creates annotations
+ without runtime errors. This is a regression test for the bug where
+ new_annotation() was called as a standalone function instead of as
+ a method on build_objset, causing a NameError.
+
+ The test verifies:
+ 1. The build completes successfully (no NameError)
+ 2. Each configured annotation variable appears exactly once
+ 3. The annotation values match the configured variables
+
+ We check for exact equality (not >=) to prevent regressions where
+ one annotation might appear multiple times while another is missing.
+ """
+ ANNOTATION_VAR1 = "TestAnnotation1"
+ ANNOTATION_VAR2 = "TestAnnotation2"
+
+ # This will fail with NameError if new_annotation() is called
incorrectly
+ objset = self.check_recipe_spdx(
+ "base-files",
+
"{DEPLOY_DIR_SPDX}/{MACHINE_ARCH}/recipes/recipe-base-files.spdx.json",
+ extraconf=textwrap.dedent(
+ f"""\
+ ANNOTATION1 = "{ANNOTATION_VAR1}"
+ ANNOTATION2 = "{ANNOTATION_VAR2}"
+ SPDX_CUSTOM_ANNOTATION_VARS = "ANNOTATION1 ANNOTATION2"
+ """
+ ),
+ )
+
+ # If we got here, the build succeeded (no NameError)
+ # Now verify the annotations were actually created
+
+ # Find the build element
+ build = None
+ for o in objset.foreach_type(oe.spdx30.build_Build):
+ build = o
+ break
+
+ self.assertIsNotNone(build, "Unable to find Build element")
+
+ # Find annotation objects that reference our build
+ found_annotations = []
+ for obj in objset.objects: # <-- Remove parentheses
+ if isinstance(obj, oe.spdx30.Annotation):
+ if hasattr(obj, "subject") and build._id == obj.subject._id:
+ found_annotations.append(obj)
+
+ # Check each annotation separately to ensure exactly one occurrence of
each
+ annotation1_count = 0
+ annotation2_count = 0
+
+ for annotation in found_annotations:
+ if hasattr(annotation, "statement"):
+ if f"ANNOTATION1={ANNOTATION_VAR1}" in annotation.statement:
+ annotation1_count += 1
+ self.logger.info(f"Found ANNOTATION1:
{annotation.statement}")
+ if f"ANNOTATION2={ANNOTATION_VAR2}" in annotation.statement:
+ annotation2_count += 1
+ self.logger.info(f"Found ANNOTATION2:
{annotation.statement}")
+
+ # Each annotation should appear exactly once
+ self.assertEqual(
+ annotation1_count,
+ 1,
+ f"Expected exactly 1 occurrence of ANNOTATION1, found
{annotation1_count}",
+ )
+ self.assertEqual(
+ annotation2_count,
+ 1,
+ f"Expected exactly 1 occurrence of ANNOTATION2, found
{annotation2_count}",
+ )
--
2.43.0
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#228270):
https://lists.openembedded.org/g/openembedded-core/message/228270
Mute This Topic: https://lists.openembedded.org/mt/116893595/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-