public inbox for openembedded-core@lists.openembedded.org
 help / color / mirror / Atom feed
From: stondo@gmail.com
To: openembedded-core@lists.openembedded.org
Cc: JPEWhacker@gmail.com, richard.purdie@linuxfoundation.org,
	ross.burton@arm.com, marta.rybczynska@syslinbit.com,
	benjamin.robin@bootlin.com, peter.marko@siemens.com,
	adrian.freihofer@siemens.com, mathieu.dubois-briand@bootlin.com,
	stefano.tondo.ext@siemens.com
Subject: [RFC PATCH 2/2] oeqa/selftest: Add tests for OpenVEX integration
Date: Tue, 31 Mar 2026 16:19:56 +0200	[thread overview]
Message-ID: <20260331141956.608976-3-stondo@gmail.com> (raw)
In-Reply-To: <20260331141956.608976-1-stondo@gmail.com>

From: Stefano Tondo <stefano.tondo.ext@siemens.com>

Add two test methods to SPDX30Check:
- test_openvex_integration: Verifies VEX relationships exist in SPDX
  output and packages have PURLs for VEX product identification
- test_openvex_standalone_files: Verifies standalone .vex.json files
  are created with proper metadata when OPENVEX_GENERATE_STANDALONE=1

Signed-off-by: Stefano Tondo <stefano.tondo.ext@siemens.com>
---
 meta/lib/oeqa/selftest/cases/spdx.py | 90 ++++++++++++++++++++++++++++
 1 file changed, 90 insertions(+)

diff --git a/meta/lib/oeqa/selftest/cases/spdx.py b/meta/lib/oeqa/selftest/cases/spdx.py
index 8285189382..661daa17d8 100644
--- a/meta/lib/oeqa/selftest/cases/spdx.py
+++ b/meta/lib/oeqa/selftest/cases/spdx.py
@@ -443,3 +443,93 @@ class SPDX30Check(SPDX3CheckBase, OESelftestTestCase):
                 r'\d',
                 f"Version '{version}' for package '{name}' should contain digits"
             )
+
+    def test_openvex_integration(self):
+        """
+        Test that OpenVEX generation is integrated into SPDX workflow.
+
+        Verifies VEX relationships are created for vulnerabilities and
+        packages have PURLs suitable for VEX product identification.
+        """
+        objset = self.check_recipe_spdx(
+            "busybox",
+            "{DEPLOY_DIR_SPDX}/{SSTATE_PKGARCH}/static/static-busybox.spdx.json",
+            task="create_recipe_spdx",
+            extraconf="""                OPENVEX_AUTHOR = "Test Author"
+                OPENVEX_ROLE = "securityAdvisor"
+                """,
+        )
+
+        # Check for VEX relationships (any type: Fixed, Affected, NotAffected, etc.)
+        vex_count = 0
+        for rel in objset.foreach_type(oe.spdx30.security_VexVulnAssessmentRelationship):
+            vex_count += 1
+            self.assertIsNotNone(rel.from_, "VEX relationship missing 'from' field")
+            self.assertIsNotNone(rel.to, "VEX relationship missing 'to' field")
+
+        if vex_count:
+            self.logger.info(f"Found {vex_count} VEX relationships in SPDX")
+        else:
+            self.logger.info("No VEX relationships found (expected if no CVEs)")
+
+        # Verify packages have PURLs for VEX product identification
+        packages_with_purls = []
+        for pkg in objset.foreach_type(oe.spdx30.software_Package):
+            if hasattr(pkg, "externalIdentifier") and pkg.externalIdentifier:
+                for ext_id in pkg.externalIdentifier:
+                    if hasattr(ext_id, "externalIdentifierType"):
+                        if "packageurl" in str(ext_id.externalIdentifierType).lower():
+                            packages_with_purls.append(pkg.name)
+                            break
+
+        self.assertGreater(
+            len(packages_with_purls), 0,
+            "Should have packages with PURLs for VEX product identification"
+        )
+        self.logger.info(f"Found {len(packages_with_purls)} packages with PURLs")
+
+    def test_openvex_standalone_files(self):
+        """
+        Test that standalone OpenVEX files are generated when enabled.
+
+        Verifies OpenVEX JSON files are created with required metadata
+        for a recipe with known CVEs (busybox).
+        """
+        import json
+        from pathlib import Path
+
+        self.check_recipe_spdx(
+            "busybox",
+            "{DEPLOY_DIR_SPDX}/{SSTATE_PKGARCH}/static/static-busybox.spdx.json",
+            task="create_recipe_spdx",
+            extraconf="""                OPENVEX_GENERATE_STANDALONE = "1"
+                OPENVEX_AUTHOR = "Test Security Team"
+                OPENVEX_ROLE = "securityAdvisor"
+                """,
+        )
+
+        deploy_dir_spdx = get_bb_var("DEPLOY_DIR_SPDX")
+        sstate_pkgarch = get_bb_var("SSTATE_PKGARCH", "busybox")
+
+        vex_file = Path(deploy_dir_spdx) / sstate_pkgarch / "recipes" / "busybox.vex.json"
+
+        self.assertExists(str(vex_file), "busybox.vex.json should exist (busybox has known CVEs)")
+
+        with open(vex_file, "r") as f:
+            vex_data = json.load(f)
+
+        self.assertIn("@context", vex_data, "VEX missing @context")
+        self.assertIn("statements", vex_data, "VEX missing statements")
+        self.assertGreater(len(vex_data["statements"]), 0, "VEX should have at least one statement")
+
+        self.assertEqual(
+            vex_data["author"],
+            "Test Security Team",
+            "VEX author not set correctly"
+        )
+
+        self.logger.info(
+            f"Validated OpenVEX file: busybox.vex.json "
+            f"({len(vex_data['statements'])} statements)"
+        )
+
-- 
2.53.0



  parent reply	other threads:[~2026-03-31 14:20 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-31 14:19 [RFC PATCH 0/2] spdx30: Add OpenVEX standalone document generation stondo
2026-03-31 14:19 ` [RFC PATCH 1/2] " stondo
2026-03-31 14:19 ` stondo [this message]
2026-03-31 14:23 ` [RFC PATCH 0/2] " Richard Purdie
2026-03-31 14:46   ` [OE-core] " Marta Rybczynska
2026-03-31 15:04   ` Joshua Watt
2026-03-31 22:05     ` Freihofer, Adrian
2026-04-01  7:43       ` Benjamin Robin
2026-04-01  9:58         ` Freihofer, Adrian
2026-04-01 11:34           ` Benjamin Robin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260331141956.608976-3-stondo@gmail.com \
    --to=stondo@gmail.com \
    --cc=JPEWhacker@gmail.com \
    --cc=adrian.freihofer@siemens.com \
    --cc=benjamin.robin@bootlin.com \
    --cc=marta.rybczynska@syslinbit.com \
    --cc=mathieu.dubois-briand@bootlin.com \
    --cc=openembedded-core@lists.openembedded.org \
    --cc=peter.marko@siemens.com \
    --cc=richard.purdie@linuxfoundation.org \
    --cc=ross.burton@arm.com \
    --cc=stefano.tondo.ext@siemens.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox