@@ -140,6 +140,32 @@ class CIBaseTest(CIBuilder):
self.delete_from_build_dir('ccache')
self.unconfigure()
+ def perform_sbom_test(self, targets, **kwargs):
+ """
+ Build a rootfs containing a needle package and check if that package
+ is added to the sbom.
+ """
+ import json
+
+ needle_pkg = 'cowsay'
+ self.perform_build_test(
+ targets, image_install=needle_pkg,
+ generate_sbom=True
+ )
+
+ for t in targets:
+ ds, pn, distro, machine = \
+ CIUtils.getVars('DEPLOY_DIR_SBOM', 'PN', 'DISTRO', 'MACHINE',
+ target=t)
+ for t in ["cdx", "spdx"]:
+ sbom_path = os.path.join(ds, f'{pn}-{distro}-{machine}.{t}.json')
+ self.log.info(f"Check {t} SBOM in {sbom_path}")
+ with open(sbom_path) as f:
+ sbom = json.load(f)
+ pkg_key = 'components' if t == 'cdx' else 'packages'
+ if not any(c for c in sbom[pkg_key] if c['name'] == needle_pkg):
+ self.fail(f'{needle_pkg} package not found in SBOM {sbom_path}')
+
def perform_sstate_populate(self, image_target, **kwargs):
# Use a different isar root for populating sstate cache
isar_sstate = f"{isar_root}/isar-sstate"
@@ -126,6 +126,7 @@ class CIBuilder(Test):
installer_distro=None,
installer_device=None,
customizations=None,
+ generate_sbom=False,
lines=None,
**kwargs,
):
@@ -176,6 +177,7 @@ class CIBuilder(Test):
f" image_install = {image_install}\n"
f" installer_image = {installer_image}\n"
f" customizations = {customizations}\n"
+ f" generate_sbom = {generate_sbom}\n"
f" lines = {strlines}\n"
f"==================================================="
)
@@ -275,6 +277,8 @@ class CIBuilder(Test):
'CUSTOMIZATION_FOR_IMAGES:append = " isar-image-ci"\n'
'HOSTNAME:isar-image-ci = "isar-ci"\n'
)
+ if generate_sbom is False:
+ f.write('ROOTFS_FEATURES:remove = "generate-sbom"\n')
if lines is not None:
f.writelines((line + '\n' if not line.endswith('\n') else line) for line in lines)
@@ -694,6 +694,39 @@ class CustomizationsTest(CIBaseTest):
)
+class SbomTest(CIBaseTest):
+ """
+ Test to check if sbom is generated and contains expected packages.
+ Most tests are rootfs tests to avoid costly initrd build and imaging.
+
+ :avocado: tags=sbom,fast
+ """
+
+ def test_sbom_rootfs_generate(self):
+ targets = [
+ 'mc:qemuamd64-bookworm:isar-rootfs-ci',
+ 'mc:qemuarm64-bookworm:isar-rootfs-ci',
+ 'mc:qemuamd64-trixie:isar-rootfs-ci',
+ 'mc:qemuarm64-trixie:isar-rootfs-ci',
+ 'mc:qemuamd64-noble:isar-rootfs-ci',
+ ]
+
+ self.init()
+ self.perform_sbom_test(targets)
+
+ def test_sbom_unsupported(self):
+ targets = [
+ 'mc:qemuamd64-bullseye:isar-rootfs-ci',
+ 'mc:qemuamd64-focal:isar-rootfs-ci',
+ ]
+
+ self.init()
+ self.perform_build_test(
+ targets, bitbake_cmd='do_rootfs', image_install='cowsay',
+ generate_sbom=True
+ )
+
+
class SignatureTest(CIBaseTest):
"""