diff options
| -rw-r--r-- | meta/lib/oeqa/selftest/cases/spdx.py | 133 |
1 files changed, 124 insertions, 9 deletions
diff --git a/meta/lib/oeqa/selftest/cases/spdx.py b/meta/lib/oeqa/selftest/cases/spdx.py index 7685a81e7f..be595babb3 100644 --- a/meta/lib/oeqa/selftest/cases/spdx.py +++ b/meta/lib/oeqa/selftest/cases/spdx.py | |||
| @@ -6,21 +6,26 @@ | |||
| 6 | 6 | ||
| 7 | import json | 7 | import json |
| 8 | import os | 8 | import os |
| 9 | import textwrap | ||
| 10 | from pathlib import Path | ||
| 9 | from oeqa.selftest.case import OESelftestTestCase | 11 | from oeqa.selftest.case import OESelftestTestCase |
| 10 | from oeqa.utils.commands import bitbake, get_bb_var, runCmd | 12 | from oeqa.utils.commands import bitbake, get_bb_var, get_bb_vars, runCmd |
| 11 | 13 | ||
| 12 | class SPDXCheck(OESelftestTestCase): | ||
| 13 | 14 | ||
| 15 | class SPDX22Check(OESelftestTestCase): | ||
| 14 | @classmethod | 16 | @classmethod |
| 15 | def setUpClass(cls): | 17 | def setUpClass(cls): |
| 16 | super(SPDXCheck, cls).setUpClass() | 18 | super().setUpClass() |
| 17 | bitbake("python3-spdx-tools-native") | 19 | bitbake("python3-spdx-tools-native") |
| 18 | bitbake("-c addto_recipe_sysroot python3-spdx-tools-native") | 20 | bitbake("-c addto_recipe_sysroot python3-spdx-tools-native") |
| 19 | 21 | ||
| 20 | def check_recipe_spdx(self, high_level_dir, spdx_file, target_name): | 22 | def check_recipe_spdx(self, high_level_dir, spdx_file, target_name): |
| 21 | config = """ | 23 | config = textwrap.dedent( |
| 22 | INHERIT += "create-spdx" | 24 | """\ |
| 23 | """ | 25 | INHERIT:remove = "create-spdx" |
| 26 | INHERIT += "create-spdx-2.2" | ||
| 27 | """ | ||
| 28 | ) | ||
| 24 | self.write_config(config) | 29 | self.write_config(config) |
| 25 | 30 | ||
| 26 | deploy_dir = get_bb_var("DEPLOY_DIR") | 31 | deploy_dir = get_bb_var("DEPLOY_DIR") |
| @@ -29,7 +34,9 @@ INHERIT += "create-spdx" | |||
| 29 | # qemux86-64 creates the directory qemux86_64 | 34 | # qemux86-64 creates the directory qemux86_64 |
| 30 | machine_dir = machine_var.replace("-", "_") | 35 | machine_dir = machine_var.replace("-", "_") |
| 31 | 36 | ||
| 32 | full_file_path = os.path.join(deploy_dir, "spdx", spdx_version, machine_dir, high_level_dir, spdx_file) | 37 | full_file_path = os.path.join( |
| 38 | deploy_dir, "spdx", spdx_version, machine_dir, high_level_dir, spdx_file | ||
| 39 | ) | ||
| 33 | 40 | ||
| 34 | try: | 41 | try: |
| 35 | os.remove(full_file_path) | 42 | os.remove(full_file_path) |
| @@ -44,8 +51,13 @@ INHERIT += "create-spdx" | |||
| 44 | self.assertNotEqual(report, None) | 51 | self.assertNotEqual(report, None) |
| 45 | self.assertNotEqual(report["SPDXID"], None) | 52 | self.assertNotEqual(report["SPDXID"], None) |
| 46 | 53 | ||
| 47 | python = os.path.join(get_bb_var('STAGING_BINDIR', 'python3-spdx-tools-native'), 'nativepython3') | 54 | python = os.path.join( |
| 48 | validator = os.path.join(get_bb_var('STAGING_BINDIR', 'python3-spdx-tools-native'), 'pyspdxtools') | 55 | get_bb_var("STAGING_BINDIR", "python3-spdx-tools-native"), |
| 56 | "nativepython3", | ||
| 57 | ) | ||
| 58 | validator = os.path.join( | ||
| 59 | get_bb_var("STAGING_BINDIR", "python3-spdx-tools-native"), "pyspdxtools" | ||
| 60 | ) | ||
| 49 | result = runCmd("{} {} -i {}".format(python, validator, filename)) | 61 | result = runCmd("{} {} -i {}".format(python, validator, filename)) |
| 50 | 62 | ||
| 51 | self.assertExists(full_file_path) | 63 | self.assertExists(full_file_path) |
| @@ -53,3 +65,106 @@ INHERIT += "create-spdx" | |||
| 53 | 65 | ||
| 54 | def test_spdx_base_files(self): | 66 | def test_spdx_base_files(self): |
| 55 | self.check_recipe_spdx("packages", "base-files.spdx.json", "base-files") | 67 | self.check_recipe_spdx("packages", "base-files.spdx.json", "base-files") |
| 68 | |||
| 69 | |||
| 70 | class SPDX3CheckBase(object): | ||
| 71 | """ | ||
| 72 | Base class for checking SPDX 3 based tests | ||
| 73 | """ | ||
| 74 | |||
| 75 | def check_spdx_file(self, filename): | ||
| 76 | import oe.spdx30 | ||
| 77 | |||
| 78 | self.assertExists(filename) | ||
| 79 | |||
| 80 | # Read the file | ||
| 81 | objset = oe.spdx30.SHACLObjectSet() | ||
| 82 | with open(filename, "r") as f: | ||
| 83 | d = oe.spdx30.JSONLDDeserializer() | ||
| 84 | d.read(f, objset) | ||
| 85 | |||
| 86 | return objset | ||
| 87 | |||
| 88 | def check_recipe_spdx(self, target_name, spdx_path, *, task=None, extraconf=""): | ||
| 89 | config = textwrap.dedent( | ||
| 90 | f"""\ | ||
| 91 | INHERIT:remove = "create-spdx" | ||
| 92 | INHERIT += "{self.SPDX_CLASS}" | ||
| 93 | {extraconf} | ||
| 94 | """ | ||
| 95 | ) | ||
| 96 | self.write_config(config) | ||
| 97 | |||
| 98 | if task: | ||
| 99 | bitbake(f"-c {task} {target_name}") | ||
| 100 | else: | ||
| 101 | bitbake(target_name) | ||
| 102 | |||
| 103 | filename = spdx_path.format( | ||
| 104 | **get_bb_vars( | ||
| 105 | [ | ||
| 106 | "DEPLOY_DIR_IMAGE", | ||
| 107 | "DEPLOY_DIR_SPDX", | ||
| 108 | "MACHINE", | ||
| 109 | "MACHINE_ARCH", | ||
| 110 | "SDKMACHINE", | ||
| 111 | "SDK_DEPLOY", | ||
| 112 | "SPDX_VERSION", | ||
| 113 | "TOOLCHAIN_OUTPUTNAME", | ||
| 114 | ], | ||
| 115 | target_name, | ||
| 116 | ) | ||
| 117 | ) | ||
| 118 | |||
| 119 | return self.check_spdx_file(filename) | ||
| 120 | |||
| 121 | def check_objset_missing_ids(self, objset): | ||
| 122 | if objset.missing_ids: | ||
| 123 | self.assertTrue( | ||
| 124 | False, | ||
| 125 | "The following SPDXIDs are unresolved:\n " | ||
| 126 | + "\n ".join(objset.missing_ids), | ||
| 127 | ) | ||
| 128 | |||
| 129 | |||
| 130 | class SPDX30Check(SPDX3CheckBase, OESelftestTestCase): | ||
| 131 | SPDX_CLASS = "create-spdx-3.0" | ||
| 132 | |||
| 133 | def test_base_files(self): | ||
| 134 | self.check_recipe_spdx( | ||
| 135 | "base-files", | ||
| 136 | "{DEPLOY_DIR_SPDX}/{MACHINE_ARCH}/packages/base-files.spdx.json", | ||
| 137 | ) | ||
| 138 | |||
| 139 | def test_core_image_minimal(self): | ||
| 140 | objset = self.check_recipe_spdx( | ||
| 141 | "core-image-minimal", | ||
| 142 | "{DEPLOY_DIR_IMAGE}/core-image-minimal-{MACHINE}.rootfs.spdx.json", | ||
| 143 | ) | ||
| 144 | |||
| 145 | # Document should be fully linked | ||
| 146 | self.check_objset_missing_ids(objset) | ||
| 147 | |||
| 148 | def test_core_image_minimal_sdk(self): | ||
| 149 | objset = self.check_recipe_spdx( | ||
| 150 | "core-image-minimal", | ||
| 151 | "{SDK_DEPLOY}/{TOOLCHAIN_OUTPUTNAME}.spdx.json", | ||
| 152 | task="populate_sdk", | ||
| 153 | ) | ||
| 154 | |||
| 155 | # Document should be fully linked | ||
| 156 | self.check_objset_missing_ids(objset) | ||
| 157 | |||
| 158 | def test_baremetal_helloworld(self): | ||
| 159 | objset = self.check_recipe_spdx( | ||
| 160 | "baremetal-helloworld", | ||
| 161 | "{DEPLOY_DIR_IMAGE}/baremetal-helloworld-image-{MACHINE}.spdx.json", | ||
| 162 | extraconf=textwrap.dedent( | ||
| 163 | """\ | ||
| 164 | TCLIBC = "baremetal" | ||
| 165 | """ | ||
| 166 | ), | ||
| 167 | ) | ||
| 168 | |||
| 169 | # Document should be fully linked | ||
| 170 | self.check_objset_missing_ids(objset) | ||
