From patchwork Mon Oct 20 07:09:49 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kamel Bouhara X-Patchwork-Id: 72693 X-Patchwork-Delegate: steve@sakoman.com 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 42A6DCCD193 for ; Mon, 20 Oct 2025 07:11:14 +0000 (UTC) Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) by mx.groups.io with SMTP id smtpd.web10.12266.1760944271124001532 for ; Mon, 20 Oct 2025 00:11:11 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="dkim: body hash did not verify" header.i=@bootlin.com header.s=dkim header.b=ARQEFCr8; spf=pass (domain: bootlin.com, ip: 185.246.84.56, mailfrom: kamel.bouhara@bootlin.com) Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id CE5761A13A6; Mon, 20 Oct 2025 07:11:09 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id A3333606D5; Mon, 20 Oct 2025 07:11:09 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 0405F102F23A2; Mon, 20 Oct 2025 09:11:03 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1760944265; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=zVYonyeYZWqPNGgQ/QvLsQJLnE3M6Vs5W71shwYYqm0=; b=ARQEFCr8EKU1yPWj3FGHANVaCzV6SOyckp+RavhRb0BJK74z2vPl2jAmPxFeGFi+KcsFBa NN9afOf61BTCmbMn0SMmHwAUE1oXA2IDB3e5/8PSdzLJg6KIBs+0UFiNXckj+HRVQODEDA AcGvPpDL+FTz54tPknp8TFmStVGofsGnxRLJMttLR7t0HQTzH+GzE3m3y2YMJve9uextHS Q1uD9+sMDIp5Eg0Ok9JKZtPtCnRWaMGF67GWFKhQhgMeOfId5jhIn3TnqTM7Rk7Ru5HaxE FWr/zI1xWWog62vzwpXnohw3AGaYufQeZEmJanV/HsJb0ASWZvRxwTfHuP3qSQ== 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 v2 09/11] lib: oeqa: spdx: Add tests for extra options Date: Mon, 20 Oct 2025 09:09:49 +0200 Message-ID: <20251020070952.942165-10-kamel.bouhara@bootlin.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20251020070952.942165-1-kamel.bouhara@bootlin.com> References: <20251020070952.942165-1-kamel.bouhara@bootlin.com> MIME-Version: 1.0 X-Last-TLS-Session-Version: TLSv1.3 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 20 Oct 2025 07:11:14 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/225107 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 db124f4b93..c279ea162b 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): @@ -72,8 +74,6 @@ class SPDX3CheckBase(object): """ def check_spdx_file(self, filename): - import oe.spdx30 - self.assertExists(filename) # Read the file @@ -85,13 +85,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: @@ -119,11 +122,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), ) @@ -187,12 +196,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")