summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrian Freihofer <adrian.freihofer@siemens.com>2025-06-03 10:23:24 +0200
committerRichard Purdie <richard.purdie@linuxfoundation.org>2025-06-05 11:02:21 +0100
commit87fc5911504e6dea6e60819250ed8c6db82c9465 (patch)
tree517ad42dd5d403d3a9e46d93ca62726da2e32e8a
parent2dbbeb1d98daa3334c36dc5c15a8c3157ffc7988 (diff)
downloadpoky-87fc5911504e6dea6e60819250ed8c6db82c9465.tar.gz
oe-selftest: fitimage: add tests for fitimage.py
Having the FIT image generator code as a separate class, which is essentially independent of BitBake, also allows testing the code separately from BitBake. Take advantage of this enables testing more use cases with significantly faster tests. (From OE-Core rev: f990d95007a616bdafbe80c30877d3bdfd954c05) Signed-off-by: Adrian Freihofer <adrian.freihofer@siemens.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/lib/oeqa/selftest/cases/fitimage.py179
1 files changed, 175 insertions, 4 deletions
diff --git a/meta/lib/oeqa/selftest/cases/fitimage.py b/meta/lib/oeqa/selftest/cases/fitimage.py
index 9c353b6ed1..3d6a5a582f 100644
--- a/meta/lib/oeqa/selftest/cases/fitimage.py
+++ b/meta/lib/oeqa/selftest/cases/fitimage.py
@@ -4,13 +4,36 @@
4# SPDX-License-Identifier: MIT 4# SPDX-License-Identifier: MIT
5# 5#
6 6
7from oeqa.selftest.case import OESelftestTestCase
8from oeqa.utils.commands import runCmd, bitbake, get_bb_vars
9import os 7import os
10import re 8import re
11import shlex 9import shlex
12import logging 10import logging
13import pprint 11import pprint
12import tempfile
13
14import oe.fitimage
15
16from oeqa.selftest.case import OESelftestTestCase
17from oeqa.utils.commands import runCmd, bitbake, get_bb_vars, get_bb_var
18
19
20class BbVarsMockGenKeys:
21 def __init__(self, keydir, gen_keys="0", sign_enabled="0", keyname="", sign_ind="0", img_keyname=""):
22 self.bb_vars = {
23 'FIT_GENERATE_KEYS': gen_keys,
24 'FIT_KEY_GENRSA_ARGS': "-F4",
25 'FIT_KEY_REQ_ARGS': "-batch -new",
26 'FIT_KEY_SIGN_PKCS': "-x509",
27 'FIT_SIGN_INDIVIDUAL': sign_ind,
28 'FIT_SIGN_NUMBITS': "2048",
29 'UBOOT_SIGN_ENABLE': sign_enabled,
30 'UBOOT_SIGN_IMG_KEYNAME': img_keyname,
31 'UBOOT_SIGN_KEYDIR': keydir,
32 'UBOOT_SIGN_KEYNAME': keyname,
33 }
34
35 def getVar(self, var):
36 return self.bb_vars[var]
14 37
15class FitImageTestCase(OESelftestTestCase): 38class FitImageTestCase(OESelftestTestCase):
16 """Test functions usable for testing kernel-fitimage.bbclass and uboot-sign.bbclass 39 """Test functions usable for testing kernel-fitimage.bbclass and uboot-sign.bbclass
@@ -369,8 +392,7 @@ class FitImageTestCase(OESelftestTestCase):
369 # Verify the FIT image 392 # Verify the FIT image
370 self._check_fitimage(bb_vars, fitimage_path, uboot_tools_bindir) 393 self._check_fitimage(bb_vars, fitimage_path, uboot_tools_bindir)
371 394
372 395class KernelFitImageBase(FitImageTestCase):
373class KernelFitImageTests(FitImageTestCase):
374 """Test cases for the kernel-fitimage bbclass""" 396 """Test cases for the kernel-fitimage bbclass"""
375 397
376 def _fit_get_bb_vars(self, additional_vars=[]): 398 def _fit_get_bb_vars(self, additional_vars=[]):
@@ -696,6 +718,8 @@ class KernelFitImageTests(FitImageTestCase):
696 self.assertEqual(found_comments, num_signatures, "Expected %d signed and commented (%s) sections in the fitImage." % 718 self.assertEqual(found_comments, num_signatures, "Expected %d signed and commented (%s) sections in the fitImage." %
697 (num_signatures, a_comment)) 719 (num_signatures, a_comment))
698 720
721class KernelFitImageTests(KernelFitImageBase):
722 """Test cases for the kernel-fitimage bbclass"""
699 723
700 def test_fit_image(self): 724 def test_fit_image(self):
701 """ 725 """
@@ -732,6 +756,52 @@ FIT_CONF_PREFIX = "foo-"
732 bb_vars = self._fit_get_bb_vars() 756 bb_vars = self._fit_get_bb_vars()
733 self._test_fitimage(bb_vars) 757 self._test_fitimage(bb_vars)
734 758
759 def test_get_compatible_from_dtb(self):
760 """Test the oe.fitimage.get_compatible_from_dtb function
761
762 1. bitbake bbb-dtbs-as-ext
763 2. Check if symlink_points_below returns the path to the DTB
764 3. Check if the expected compatible string is found by get_compatible_from_dtb()
765 """
766 DTB_RECIPE = "bbb-dtbs-as-ext"
767 DTB_FILE = "am335x-bonegreen-ext.dtb"
768 DTB_SYMLINK = "am335x-bonegreen-ext-alias.dtb"
769 DTBO_FILE = "BBORG_RELAY-00A2.dtbo"
770 EXPECTED_COMP = ["ti,am335x-bone-green", "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx"]
771
772 config = """
773DISTRO="poky"
774MACHINE = "beaglebone-yocto"
775"""
776 self.write_config(config)
777
778 # Provide the fdtget command called by get_compatible_from_dtb
779 dtc_bindir = FitImageTestCase._setup_native('dtc-native')
780 fdtget_path = os.path.join(dtc_bindir, "fdtget")
781 self.assertExists(fdtget_path)
782
783 # bitbake an external DTB with a symlink to it and a DTB overlay
784 bitbake(DTB_RECIPE)
785 deploy_dir_image = get_bb_var("DEPLOY_DIR_IMAGE", DTB_RECIPE)
786 devicetree_dir = os.path.join(deploy_dir_image, "devicetree")
787 dtb_path = os.path.join(devicetree_dir, DTB_FILE)
788 dtb_alias_path = os.path.join(devicetree_dir, DTB_SYMLINK)
789 dtbo_file = os.path.join(devicetree_dir, DTBO_FILE)
790 self.assertExists(dtb_path)
791 self.assertExists(dtb_alias_path)
792 self.assertExists(dtbo_file)
793
794 # Test symlink_points_below
795 linked_dtb = oe.fitimage.symlink_points_below(dtb_alias_path, devicetree_dir)
796 self.assertEqual(linked_dtb, DTB_FILE)
797
798 # Check if get_compatible_from_dtb finds the expected compatible string in the DTBs
799 comp = oe.fitimage.get_compatible_from_dtb(dtb_path, fdtget_path)
800 self.assertEqual(comp, EXPECTED_COMP)
801 comp_alias = oe.fitimage.get_compatible_from_dtb(dtb_alias_path, fdtget_path)
802 self.assertEqual(comp_alias, EXPECTED_COMP)
803 # The alias is a symlink, therefore the compatible string is equal
804 self.assertEqual(comp_alias, comp)
735 805
736 def test_fit_image_ext_dtb_dtbo(self): 806 def test_fit_image_ext_dtb_dtbo(self):
737 """ 807 """
@@ -939,6 +1009,107 @@ FIT_HASH_ALG = "sha256"
939 self._gen_signing_key(bb_vars) 1009 self._gen_signing_key(bb_vars)
940 self._test_fitimage(bb_vars) 1010 self._test_fitimage(bb_vars)
941 1011
1012class FitImagePyTests(KernelFitImageBase):
1013 """Test cases for the fitimage.py module without calling bitbake"""
1014
1015 def _test_fitimage_py(self, bb_vars_overrides=None):
1016 topdir = os.path.join(os.environ['BUILDDIR'])
1017 fitimage_its_path = os.path.join(topdir, self._testMethodName + '.its')
1018
1019 # Provide variables without calling bitbake
1020 bb_vars = {
1021 # image-fitimage.conf
1022 'FIT_DESC': "Kernel fitImage for a dummy distro",
1023 'FIT_HASH_ALG': "sha256",
1024 'FIT_SIGN_ALG': "rsa2048",
1025 'FIT_PAD_ALG': "pkcs-1.5",
1026 'FIT_GENERATE_KEYS': "0",
1027 'FIT_SIGN_NUMBITS': "2048",
1028 'FIT_KEY_GENRSA_ARGS': "-F4",
1029 'FIT_KEY_REQ_ARGS': "-batch -new",
1030 'FIT_KEY_SIGN_PKCS': "-x509",
1031 'FIT_SIGN_INDIVIDUAL': "0",
1032 'FIT_CONF_PREFIX': "conf-",
1033 'FIT_SUPPORTED_INITRAMFS_FSTYPES': "cpio.lz4 cpio.lzo cpio.lzma cpio.xz cpio.zst cpio.gz ext2.gz cpio",
1034 'FIT_CONF_DEFAULT_DTB': "",
1035 'FIT_ADDRESS_CELLS': "1",
1036 'FIT_UBOOT_ENV': "",
1037 # kernel.bbclass
1038 'UBOOT_ENTRYPOINT': "0x20008000",
1039 'UBOOT_LOADADDRESS': "0x20008000",
1040 'INITRAMFS_IMAGE': "",
1041 'INITRAMFS_IMAGE_BUNDLE': "",
1042 # kernel-uboot.bbclass
1043 'FIT_KERNEL_COMP_ALG': "gzip",
1044 'FIT_KERNEL_COMP_ALG_EXTENSION': ".gz",
1045 'UBOOT_MKIMAGE_KERNEL_TYPE': "kernel",
1046 # uboot-config.bbclass
1047 'UBOOT_MKIMAGE_DTCOPTS': "",
1048 'UBOOT_MKIMAGE': "uboot-mkimage",
1049 'UBOOT_MKIMAGE_SIGN': "uboot-mkimage",
1050 'UBOOT_MKIMAGE_SIGN_ARGS': "",
1051 'UBOOT_SIGN_ENABLE': "0",
1052 'UBOOT_SIGN_KEYDIR': None,
1053 'UBOOT_SIGN_KEYNAME': None,
1054 'UBOOT_SIGN_IMG_KEYNAME': None,
1055 # others
1056 'MACHINE': "qemux86-64",
1057 'UBOOT_ARCH': "x86",
1058 'HOST_PREFIX': "x86_64-poky-linux-"
1059 }
1060 if bb_vars_overrides:
1061 bb_vars.update(bb_vars_overrides)
1062
1063 root_node = oe.fitimage.ItsNodeRootKernel(
1064 bb_vars["FIT_DESC"], bb_vars["FIT_ADDRESS_CELLS"],
1065 bb_vars['HOST_PREFIX'], bb_vars['UBOOT_ARCH'], bb_vars["FIT_CONF_PREFIX"],
1066 oe.types.boolean(bb_vars['UBOOT_SIGN_ENABLE']), bb_vars["UBOOT_SIGN_KEYDIR"],
1067 bb_vars["UBOOT_MKIMAGE"], bb_vars["UBOOT_MKIMAGE_DTCOPTS"],
1068 bb_vars["UBOOT_MKIMAGE_SIGN"], bb_vars["UBOOT_MKIMAGE_SIGN_ARGS"],
1069 bb_vars['FIT_HASH_ALG'], bb_vars['FIT_SIGN_ALG'], bb_vars['FIT_PAD_ALG'],
1070 bb_vars['UBOOT_SIGN_KEYNAME'],
1071 oe.types.boolean(bb_vars['FIT_SIGN_INDIVIDUAL']), bb_vars['UBOOT_SIGN_IMG_KEYNAME']
1072 )
1073
1074 root_node.fitimage_emit_section_kernel("kernel-1", "linux.bin", "none",
1075 bb_vars.get('UBOOT_LOADADDRESS'), bb_vars.get('UBOOT_ENTRYPOINT'),
1076 bb_vars.get('UBOOT_MKIMAGE_KERNEL_TYPE'), bb_vars.get("UBOOT_ENTRYSYMBOL")
1077 )
1078
1079 dtb_files, _ = FitImageTestCase._get_dtb_files(bb_vars)
1080 for dtb in dtb_files:
1081 root_node.fitimage_emit_section_dtb(dtb, os.path.join("a-dir", dtb),
1082 bb_vars.get("UBOOT_DTB_LOADADDRESS"), bb_vars.get("UBOOT_DTBO_LOADADDRESS"))
1083
1084 if bb_vars.get('FIT_UBOOT_ENV'):
1085 root_node.fitimage_emit_section_boot_script(
1086 "bootscr-" + bb_vars['FIT_UBOOT_ENV'], bb_vars['FIT_UBOOT_ENV'])
1087
1088 if bb_vars['MACHINE'] == "qemux86-64": # Not really the right if
1089 root_node.fitimage_emit_section_setup("setup-1", "setup1.bin")
1090
1091 if bb_vars.get('INITRAMFS_IMAGE') and bb_vars.get("INITRAMFS_IMAGE_BUNDLE") != "1":
1092 root_node.fitimage_emit_section_ramdisk("ramdisk-1", "a-dir/a-initramfs-1",
1093 "core-image-minimal-initramfs",
1094 bb_vars.get("UBOOT_RD_LOADADDRESS"), bb_vars.get("UBOOT_RD_ENTRYPOINT"))
1095
1096 root_node.fitimage_emit_section_config(bb_vars['FIT_CONF_DEFAULT_DTB'])
1097 root_node.write_its_file(fitimage_its_path)
1098
1099 self.assertExists(fitimage_its_path, "%s image tree source doesn't exist" % (fitimage_its_path))
1100 self.logger.debug("Checking its: %s" % fitimage_its_path)
1101 self._check_its_file(bb_vars, fitimage_its_path)
1102
1103 def test_fitimage_py_default(self):
1104 self._test_fitimage_py()
1105
1106 def test_fitimage_py_default_dtb(self):
1107 bb_vars_overrides = {
1108 'KERNEL_DEVICETREE': "one.dtb two.dtb three.dtb",
1109 'FIT_CONF_DEFAULT_DTB': "two.dtb"
1110 }
1111 self._test_fitimage_py(bb_vars_overrides)
1112
942 1113
943class UBootFitImageTests(FitImageTestCase): 1114class UBootFitImageTests(FitImageTestCase):
944 """Test cases for the uboot-sign bbclass""" 1115 """Test cases for the uboot-sign bbclass"""