| Message ID | 20260312153845.164369-6-stondo@gmail.com |
|---|---|
| State | Under Review |
| Headers | show |
| Series | SPDX 3.0 SBOM enrichment and compliance improvements | expand |
On Thu Mar 12, 2026 at 4:38 PM CET, Stefano Tondo via lists.openembedded.org wrote: > From: Stefano Tondo <stefano.tondo.ext@siemens.com> > > Add two new SPDX 3.0 selftest cases: > > test_download_location_defensive_handling: > Verifies SPDX generation succeeds for recipes with tarball sources > and that external references are properly structured (ExternalRef > locator is a list of strings per SPDX 3.0 spec). > > test_version_extraction_patterns: > Verifies that version extraction works correctly and all source > packages have proper version strings containing digits. > > These tests validate the source download enrichment added in the > previous commit. > > Signed-off-by: Stefano Tondo <stefano.tondo.ext@siemens.com> > --- Hi Stefano, Thanks for the new version. Builds look correct so far, except for these 3 selftest errors: 2026-03-12 22:29:04,908 - oe-selftest - INFO - spdx.SPDX30Check.test_download_location_defensive_handling (subunit.RemotedTestCase) 2026-03-12 22:29:04,909 - oe-selftest - INFO - ... FAIL ... 2026-03-12 22:29:04,910 - oe-selftest - INFO - 6: 39/53 444/679 (18.85s) (0 failed) (spdx.SPDX30Check.test_download_location_defensive_handling) 2026-03-12 22:29:04,911 - oe-selftest - INFO - testtools.testresult.real._StringException: Traceback (most recent call last): File "/srv/pokybuild/yocto-worker/oe-selftest-armhost/build/layers/openembedded-core/meta/lib/oeqa/selftest/cases/spdx.py", line 424, in test_download_location_defensive_handling objset = self.check_recipe_spdx( ^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/pokybuild/yocto-worker/oe-selftest-armhost/build/layers/openembedded-core/meta/lib/oeqa/selftest/cases/spdx.py", line 123, in check_recipe_spdx return self.check_spdx_file(filename) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/pokybuild/yocto-worker/oe-selftest-armhost/build/layers/openembedded-core/meta/lib/oeqa/selftest/cases/spdx.py", line 81, in check_spdx_file self.assertExists(filename) File "/srv/pokybuild/yocto-worker/oe-selftest-armhost/build/layers/openembedded-core/meta/lib/oeqa/selftest/case.py", line 249, in assertExists raise self.failureException(msg) AssertionError: '/srv/pokybuild/yocto-worker/oe-selftest-armhost/build/build-st-3170645/tmp/deploy/spdx/3.0.1/cortexa57/recipes/build-m4.spdx.json' does not exist ... 2026-03-12 23:32:02,849 - oe-selftest - INFO - spdx.SPDX30Check.test_packageconfig_spdx (subunit.RemotedTestCase) 2026-03-12 23:32:02,849 - oe-selftest - INFO - ... FAIL ... 2026-03-12 23:32:02,850 - oe-selftest - INFO - 6: 43/53 634/679 (70.33s) (2 failed) (spdx.SPDX30Check.test_packageconfig_spdx) 2026-03-12 23:32:02,850 - oe-selftest - INFO - testtools.testresult.real._StringException: Traceback (most recent call last): File "/srv/pokybuild/yocto-worker/oe-selftest-armhost/build/layers/openembedded-core/meta/lib/oeqa/selftest/cases/spdx.py", line 393, in test_packageconfig_spdx objset = self.check_recipe_spdx( ^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/pokybuild/yocto-worker/oe-selftest-armhost/build/layers/openembedded-core/meta/lib/oeqa/selftest/cases/spdx.py", line 123, in check_recipe_spdx return self.check_spdx_file(filename) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/pokybuild/yocto-worker/oe-selftest-armhost/build/layers/openembedded-core/meta/lib/oeqa/selftest/cases/spdx.py", line 81, in check_spdx_file self.assertExists(filename) File "/srv/pokybuild/yocto-worker/oe-selftest-armhost/build/layers/openembedded-core/meta/lib/oeqa/selftest/case.py", line 249, in assertExists raise self.failureException(msg) AssertionError: '/srv/pokybuild/yocto-worker/oe-selftest-armhost/build/build-st-3170645/tmp/deploy/spdx/3.0.1/cortexa57/recipes/build-tar.spdx.json' does not exist ... 2026-03-12 23:32:16,627 - oe-selftest - INFO - spdx.SPDX30Check.test_version_extraction_patterns (subunit.RemotedTestCase) 2026-03-12 23:32:16,628 - oe-selftest - INFO - ... FAIL ... 2026-03-12 23:32:16,628 - oe-selftest - INFO - 6: 44/53 635/679 (13.78s) (4 failed) (spdx.SPDX30Check.test_version_extraction_patterns) 2026-03-12 23:32:16,628 - oe-selftest - INFO - testtools.testresult.real._StringException: Traceback (most recent call last): File "/srv/pokybuild/yocto-worker/oe-selftest-armhost/build/layers/openembedded-core/meta/lib/oeqa/selftest/cases/spdx.py", line 452, in test_version_extraction_patterns objset = self.check_recipe_spdx( ^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/pokybuild/yocto-worker/oe-selftest-armhost/build/layers/openembedded-core/meta/lib/oeqa/selftest/cases/spdx.py", line 123, in check_recipe_spdx return self.check_spdx_file(filename) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/pokybuild/yocto-worker/oe-selftest-armhost/build/layers/openembedded-core/meta/lib/oeqa/selftest/cases/spdx.py", line 81, in check_spdx_file self.assertExists(filename) File "/srv/pokybuild/yocto-worker/oe-selftest-armhost/build/layers/openembedded-core/meta/lib/oeqa/selftest/case.py", line 249, in assertExists raise self.failureException(msg) AssertionError: '/srv/pokybuild/yocto-worker/oe-selftest-armhost/build/build-st-3170645/tmp/deploy/spdx/3.0.1/cortexa57/recipes/build-tar.spdx.json' does not exist https://autobuilder.yoctoproject.org/valkyrie/#/builders/23/builds/3513 https://autobuilder.yoctoproject.org/valkyrie/#/builders/35/builds/3395 https://autobuilder.yoctoproject.org/valkyrie/#/builders/48/builds/3286 Looking at the error, I suspect this is to address changes from the Joshua series, but I didn't had this series in my branch. Is that right? I will keep these changes in my branch, so we can go further, but please confirm everything is correct. Thanks, Mathieu
Hi Mathieu, Yes, that's correct, the build-m4/build-tar naming depends on Joshua's series which renames recipe-* to build-* in the SPDX output. My series is intended to be applied on top of his. Once his series lands, these tests should pass. Thanks, Stefano
diff --git a/meta/lib/oeqa/selftest/cases/spdx.py b/meta/lib/oeqa/selftest/cases/spdx.py index 41ef52fce1..859667dd6b 100644 --- a/meta/lib/oeqa/selftest/cases/spdx.py +++ b/meta/lib/oeqa/selftest/cases/spdx.py @@ -392,7 +392,7 @@ class SPDX30Check(SPDX3CheckBase, OESelftestTestCase): def test_packageconfig_spdx(self): objset = self.check_recipe_spdx( "tar", - "{DEPLOY_DIR_SPDX}/{SSTATE_PKGARCH}/recipes/recipe-tar.spdx.json", + "{DEPLOY_DIR_SPDX}/{SSTATE_PKGARCH}/recipes/build-tar.spdx.json", extraconf="""\ SPDX_INCLUDE_PACKAGECONFIG = "1" """, @@ -414,3 +414,72 @@ class SPDX30Check(SPDX3CheckBase, OESelftestTestCase): value, ["enabled", "disabled"], f"Unexpected PACKAGECONFIG value '{value}' for {key}" ) + + def test_download_location_defensive_handling(self): + """Test that download_location handling is defensive. + + Verifies SPDX generation succeeds and external references are + properly structured when download_location retrieval works. + """ + objset = self.check_recipe_spdx( + "m4", + "{DEPLOY_DIR_SPDX}/{SSTATE_PKGARCH}/recipes/build-m4.spdx.json", + ) + + found_external_refs = False + for pkg in objset.foreach_type(oe.spdx30.software_Package): + if pkg.externalRef: + found_external_refs = True + for ref in pkg.externalRef: + self.assertIsNotNone(ref.externalRefType) + self.assertIsNotNone(ref.locator) + self.assertGreater(len(ref.locator), 0, "Locator should have at least one entry") + for loc in ref.locator: + self.assertIsInstance(loc, str) + break + + self.logger.info( + f"External references {'found' if found_external_refs else 'not found'} " + f"in SPDX output (defensive handling verified)" + ) + + def test_version_extraction_patterns(self): + """Test that version extraction works for various package formats. + + Verifies that version patterns correctly extract versions from + tarball sources and that all packages have proper version strings. + """ + objset = self.check_recipe_spdx( + "tar", + "{DEPLOY_DIR_SPDX}/{SSTATE_PKGARCH}/recipes/build-tar.spdx.json", + ) + + # Collect all packages with versions + packages_with_versions = [] + for pkg in objset.foreach_type(oe.spdx30.software_Package): + if pkg.software_packageVersion: + packages_with_versions.append((pkg.name, pkg.software_packageVersion)) + + self.assertGreater( + len(packages_with_versions), 0, + "Should find packages with extracted versions" + ) + + self.logger.info(f"Found {len(packages_with_versions)} packages with versions") + + # Log some examples for debugging + for name, version in packages_with_versions[:5]: + self.logger.info(f" {name}: {version}") + + # Verify that versions follow expected patterns + for name, version in packages_with_versions: + # Version should not be empty + self.assertIsNotNone(version) + self.assertNotEqual(version, "") + + # Version should contain digits + self.assertRegex( + version, + r'\d', + f"Version '{version}' for package '{name}' should contain digits" + )