poky/meta/lib/oeqa/selftest/cases/spdx.py
Hongxu Jia ac8be80638 oeqa/selftest: Add SPDX 3.0 include source case for work-share
Build gcc and check gcc-14.2.0/README in objset is available

$ oe-selftest -r spdx.SPDX30Check.test_gcc_include_source
...
2024-10-26 01:24:57,063 - oe-selftest - INFO - test_gcc_include_source (spdx.SPDX30Check.test_gcc_include_source)
2024-10-26 01:28:24,204 - oe-selftest - INFO - The spdxId of gcc-14.2.0/README in gcc.spdx.json is http://spdx.org/spdxdocs/gcc-f2eaeb0d-b54b-53ba-899a-8c36c21139bf/88d5068ffd41e5ea6b4e0dd390b23bf499bb2b6674a41e09eaf2a887eced16c8/sourcefile/42
2024-10-26 01:28:26,369 - oe-selftest - INFO -  ... ok
2024-10-26 01:28:33,315 - oe-selftest - INFO - ----------------------------------------------------------------------
2024-10-26 01:28:33,316 - oe-selftest - INFO - Ran 1 test in 216.457s
2024-10-26 01:28:33,316 - oe-selftest - INFO - OK
2024-10-26 01:28:45,254 - oe-selftest - INFO - RESULTS:
2024-10-26 01:28:45,254 - oe-selftest - INFO - RESULTS - spdx.SPDX30Check.test_gcc_include_source: PASSED (209.31s)
2024-10-26 01:28:45,260 - oe-selftest - INFO - SUMMARY:
2024-10-26 01:28:45,260 - oe-selftest - INFO - oe-selftest () - Ran 1 test in 216.457s
2024-10-26 01:28:45,260 - oe-selftest - INFO - oe-selftest - OK - All required tests passed (successes=1, skipped=0, failures=0, errors=0)

(From OE-Core rev: ccd6dde301dc8c45c8f901ebd4676b488d638b08)

Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
Reviewed-by: Joshua Watt <JPEWhacker@gmail.com>
Signed-off-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2024-11-01 12:07:12 +00:00

200 lines
5.7 KiB
Python

#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: MIT
#
import json
import os
import textwrap
from pathlib import Path
from oeqa.selftest.case import OESelftestTestCase
from oeqa.utils.commands import bitbake, get_bb_var, get_bb_vars, runCmd
class SPDX22Check(OESelftestTestCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
bitbake("python3-spdx-tools-native")
bitbake("-c addto_recipe_sysroot python3-spdx-tools-native")
def check_recipe_spdx(self, high_level_dir, spdx_file, target_name):
config = textwrap.dedent(
"""\
INHERIT:remove = "create-spdx"
INHERIT += "create-spdx-2.2"
"""
)
self.write_config(config)
deploy_dir = get_bb_var("DEPLOY_DIR")
machine_var = get_bb_var("MACHINE")
spdx_version = get_bb_var("SPDX_VERSION")
# qemux86-64 creates the directory qemux86_64
machine_dir = machine_var.replace("-", "_")
full_file_path = os.path.join(
deploy_dir, "spdx", spdx_version, machine_dir, high_level_dir, spdx_file
)
try:
os.remove(full_file_path)
except FileNotFoundError:
pass
bitbake("%s -c create_spdx" % target_name)
def check_spdx_json(filename):
with open(filename) as f:
report = json.load(f)
self.assertNotEqual(report, None)
self.assertNotEqual(report["SPDXID"], None)
python = os.path.join(
get_bb_var("STAGING_BINDIR", "python3-spdx-tools-native"),
"nativepython3",
)
validator = os.path.join(
get_bb_var("STAGING_BINDIR", "python3-spdx-tools-native"), "pyspdxtools"
)
result = runCmd("{} {} -i {}".format(python, validator, filename))
self.assertExists(full_file_path)
result = check_spdx_json(full_file_path)
def test_spdx_base_files(self):
self.check_recipe_spdx("packages", "base-files.spdx.json", "base-files")
class SPDX3CheckBase(object):
"""
Base class for checking SPDX 3 based tests
"""
def check_spdx_file(self, filename):
import oe.spdx30
self.assertExists(filename)
# Read the file
objset = oe.spdx30.SHACLObjectSet()
with open(filename, "r") as f:
d = oe.spdx30.JSONLDDeserializer()
d.read(f, objset)
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}
"""
)
self.write_config(config)
if task:
bitbake(f"-c {task} {target_name}")
else:
bitbake(target_name)
filename = spdx_path.format(
**get_bb_vars(
[
"DEPLOY_DIR_IMAGE",
"DEPLOY_DIR_SPDX",
"MACHINE",
"MACHINE_ARCH",
"SDKMACHINE",
"SDK_DEPLOY",
"SPDX_VERSION",
"SSTATE_PKGARCH",
"TOOLCHAIN_OUTPUTNAME",
],
target_name,
)
)
return self.check_spdx_file(filename)
def check_objset_missing_ids(self, objset):
if objset.missing_ids:
self.assertTrue(
False,
"The following SPDXIDs are unresolved:\n "
+ "\n ".join(objset.missing_ids),
)
class SPDX30Check(SPDX3CheckBase, OESelftestTestCase):
SPDX_CLASS = "create-spdx-3.0"
def test_base_files(self):
self.check_recipe_spdx(
"base-files",
"{DEPLOY_DIR_SPDX}/{MACHINE_ARCH}/packages/base-files.spdx.json",
)
def test_gcc_include_source(self):
import oe.spdx30
objset = self.check_recipe_spdx(
"gcc",
"{DEPLOY_DIR_SPDX}/{SSTATE_PKGARCH}/recipes/gcc.spdx.json",
extraconf=textwrap.dedent(
"""\
SPDX_INCLUDE_SOURCES = "1"
"""
),
)
gcc_pv = get_bb_var("PV", "gcc")
filename = f'gcc-{gcc_pv}/README'
found = False
for software_file in objset.foreach_type(oe.spdx30.software_File):
if software_file.name == filename:
found = True
self.logger.info(f"The spdxId of {filename} in gcc.spdx.json is {software_file.spdxId}")
break
self.assertTrue(
found,
f"Not found source file {filename} in gcc.spdx.json\n"
)
def test_core_image_minimal(self):
objset = self.check_recipe_spdx(
"core-image-minimal",
"{DEPLOY_DIR_IMAGE}/core-image-minimal-{MACHINE}.rootfs.spdx.json",
)
# Document should be fully linked
self.check_objset_missing_ids(objset)
def test_core_image_minimal_sdk(self):
objset = self.check_recipe_spdx(
"core-image-minimal",
"{SDK_DEPLOY}/{TOOLCHAIN_OUTPUTNAME}.spdx.json",
task="populate_sdk",
)
# Document should be fully linked
self.check_objset_missing_ids(objset)
def test_baremetal_helloworld(self):
objset = self.check_recipe_spdx(
"baremetal-helloworld",
"{DEPLOY_DIR_IMAGE}/baremetal-helloworld-image-{MACHINE}.spdx.json",
extraconf=textwrap.dedent(
"""\
TCLIBC = "baremetal"
"""
),
)
# Document should be fully linked
self.check_objset_missing_ids(objset)