From patchwork Mon Nov 3 16:26:39 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kamel Bouhara X-Patchwork-Id: 73537 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1A8DCCCFA03 for ; Mon, 3 Nov 2025 16:27:34 +0000 (UTC) Received: from smtpout-04.galae.net (smtpout-04.galae.net [185.171.202.116]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.1643.1762187250559614956 for ; Mon, 03 Nov 2025 08:27:31 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="dkim: body hash did not verify" header.i=@bootlin.com header.s=dkim header.b=o6e4weYJ; spf=pass (domain: bootlin.com, ip: 185.171.202.116, mailfrom: kamel.bouhara@bootlin.com) Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 70756C0D7B4; Mon, 3 Nov 2025 16:27:08 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 4291D60628; Mon, 3 Nov 2025 16:27:29 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 5679610B501AA; Mon, 3 Nov 2025 17:27:27 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1762187248; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=y7gO9zk3Y8sxn1FBmbqG8J0lifZyPJSny2MakD+i0AY=; b=o6e4weYJIA0v++tY7QO/2wQigxvl7sIXO3pdWUx1qpPm7VBpO23ASOEgURs/sG0evBoqH4 I8tlPMQ+T6xr6EKWrO19HmapvF5fh18dgkoF8a3iJfuzJEtYJ5B6h7dRMrmxHfWxRqXPYd tubHzfWK3tIsAzXs6p8qy1i4eD2BDIAjb0Kby1czZ7YpvKi4toYfMDiuuDLfJvbcDXQEeP Jx16KNA+OJ4Zjt4VL+JB3NS3PNtb24L8njLsP8qOVzfSzOvb/kbBRXeV7oTZRwzaEGj0CB IMVVtsUK5LkWX2Vm4KMSLkInAK3wdv1b0x81nLNR5AQ2Jgpo7SP2vMcyYgCLSQ== From: Kamel Bouhara To: openembedded-core@lists.openembedded.org Cc: JPEWhacker@gmail.com, thomas.petazzoni@bootlin.com, Miquel Raynal , mathieu.dubois-briand@bootlin.com, antonin.godard@bootlin.com, Pascal Eberhard , Joshua Watt , Richard Purdie , "Kamel Bouhara (Schneider Electric)" Subject: [scarthgap v3 13/16] lib: oeqa: spdx: Add tests for extra options Date: Mon, 3 Nov 2025 17:26:39 +0100 Message-ID: <20251103162654.1714239-14-kamel.bouhara@bootlin.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251103162654.1714239-1-kamel.bouhara@bootlin.com> References: <20251103162654.1714239-1-kamel.bouhara@bootlin.com> MIME-Version: 1.0 X-Last-TLS-Session-Version: TLSv1.3 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 03 Nov 2025 16:27:34 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/225680 From: Joshua Watt Adds a test for several of the extra options provided by the SPDX classes. In particular, these are the options that can produce non-reproducible results, so are not enabled by default in OE core. This test takes care to configure the build so that the tests do run in a reproducible manner so that pre-built test objects can be pulled from sstate Signed-off-by: Joshua Watt Signed-off-by: Mathieu Dubois-Briand Signed-off-by: Richard Purdie (cherry picked from commit 14f534f15f7fe6362723d7f064d39783c5bd758f) Signed-off-by: Kamel Bouhara (Schneider Electric) --- meta/lib/oeqa/selftest/cases/spdx.py | 118 +++++++++++++++++++++++---- 1 file changed, 104 insertions(+), 14 deletions(-) diff --git a/meta/lib/oeqa/selftest/cases/spdx.py b/meta/lib/oeqa/selftest/cases/spdx.py index f50beb52c4..a54b74a59c 100644 --- a/meta/lib/oeqa/selftest/cases/spdx.py +++ b/meta/lib/oeqa/selftest/cases/spdx.py @@ -7,9 +7,11 @@ import json import os import textwrap +import hashlib from pathlib import Path from oeqa.selftest.case import OESelftestTestCase from oeqa.utils.commands import bitbake, get_bb_var, get_bb_vars, runCmd +import oe.spdx30 class SPDX22Check(OESelftestTestCase): @@ -73,8 +75,6 @@ class SPDX3CheckBase(object): """ def check_spdx_file(self, filename): - import oe.spdx30 - self.assertExists(filename) # Read the file @@ -86,13 +86,16 @@ class SPDX3CheckBase(object): return objset def check_recipe_spdx(self, target_name, spdx_path, *, task=None, extraconf=""): - config = textwrap.dedent( - f"""\ - INHERIT:remove = "create-spdx" - INHERIT += "{self.SPDX_CLASS}" - {extraconf} - """ + config = ( + textwrap.dedent( + f"""\ + INHERIT:remove = "create-spdx" + INHERIT += "{self.SPDX_CLASS}" + """ + ) + + textwrap.dedent(extraconf) ) + self.write_config(config) if task: @@ -120,11 +123,17 @@ class SPDX3CheckBase(object): return self.check_spdx_file(filename) def check_objset_missing_ids(self, objset): - if objset.missing_ids: + for o in objset.foreach_type(oe.spdx30.SpdxDocument): + doc = o + break + else: + self.assertTrue(False, "Unable to find SpdxDocument") + + missing_ids = objset.missing_ids - set(i.externalSpdxId for i in doc.import_) + if missing_ids: self.assertTrue( False, - "The following SPDXIDs are unresolved:\n " - + "\n ".join(objset.missing_ids), + "The following SPDXIDs are unresolved:\n " + "\n ".join(missing_ids), ) @@ -188,12 +197,93 @@ class SPDX30Check(SPDX3CheckBase, OESelftestTestCase): objset = self.check_recipe_spdx( "baremetal-helloworld", "{DEPLOY_DIR_IMAGE}/baremetal-helloworld-image-{MACHINE}.spdx.json", - extraconf=textwrap.dedent( - """\ + extraconf="""\ TCLIBC = "baremetal" + """, + ) + + # Document should be fully linked + self.check_objset_missing_ids(objset) + + def test_extra_opts(self): + HOST_SPDXID = "http://foo.bar/spdx/bar2" + + EXTRACONF = textwrap.dedent( + f"""\ + SPDX_INVOKED_BY_name = "CI Tool" + SPDX_INVOKED_BY_type = "software" + + SPDX_ON_BEHALF_OF_name = "John Doe" + SPDX_ON_BEHALF_OF_type = "person" + SPDX_ON_BEHALF_OF_id_email = "John.Doe@noreply.com" + + SPDX_PACKAGE_SUPPLIER_name = "ACME Embedded Widgets" + SPDX_PACKAGE_SUPPLIER_type = "organization" + + SPDX_AUTHORS += "authorA" + SPDX_AUTHORS_authorA_ref = "SPDX_ON_BEHALF_OF" + + SPDX_BUILD_HOST = "host" + + SPDX_IMPORTS += "host" + SPDX_IMPORTS_host_spdxid = "{HOST_SPDXID}" + + SPDX_INCLUDE_BUILD_VARIABLES = "1" + SPDX_INCLUDE_BITBAKE_PARENT_BUILD = "1" + SPDX_INCLUDE_TIMESTAMPS = "1" + + SPDX_PRETTY = "1" + """ + ) + extraconf_hash = hashlib.sha1(EXTRACONF.encode("utf-8")).hexdigest() + + objset = self.check_recipe_spdx( + "core-image-minimal", + "{DEPLOY_DIR_IMAGE}/core-image-minimal-{MACHINE}.rootfs.spdx.json", + # Many SPDX variables do not trigger a rebuild, since they are + # intended to record information at the time of the build. As such, + # the extra configuration alone may not trigger a rebuild, and even + # if it does, the task hash won't necessarily be unique. In order + # to make sure rebuilds happen, but still allow these test objects + # to be pulled from sstate (e.g. remain reproducible), change the + # namespace prefix to include the hash of the extra configuration + extraconf=textwrap.dedent( + f"""\ + SPDX_NAMESPACE_PREFIX = "http://spdx.org/spdxdocs/{extraconf_hash}" """ - ), + ) + + EXTRACONF, ) # Document should be fully linked self.check_objset_missing_ids(objset) + + for o in objset.foreach_type(oe.spdx30.SoftwareAgent): + if o.name == "CI Tool": + break + else: + self.assertTrue(False, "Unable to find software tool") + + for o in objset.foreach_type(oe.spdx30.Person): + if o.name == "John Doe": + break + else: + self.assertTrue(False, "Unable to find person") + + for o in objset.foreach_type(oe.spdx30.Organization): + if o.name == "ACME Embedded Widgets": + break + else: + self.assertTrue(False, "Unable to find organization") + + for o in objset.foreach_type(oe.spdx30.SpdxDocument): + doc = o + break + else: + self.assertTrue(False, "Unable to find SpdxDocument") + + for i in doc.import_: + if i.externalSpdxId == HOST_SPDXID: + break + else: + self.assertTrue(False, "Unable to find imported Host SpdxID")