The unit-test will test the basic functionality of `fit-image.bbclass`. Signed-off-by: Nandor Han <nandor....@vaisala.com> --- .../fit-image-test/files/dt-fake.dtb | 3 + .../fit-image-test/files/zImage-fake | 3 + .../fit-image-test/fit-image-test.bb | 17 ++ meta/lib/oeqa/selftest/cases/fit_image.py | 212 ++++++++++++++++++ 4 files changed, 235 insertions(+) create mode 100644 meta-selftest/recipes-test/fit-image-test/files/dt-fake.dtb create mode 100644 meta-selftest/recipes-test/fit-image-test/files/zImage-fake create mode 100644 meta-selftest/recipes-test/fit-image-test/fit-image-test.bb create mode 100644 meta/lib/oeqa/selftest/cases/fit_image.py
diff --git a/meta-selftest/recipes-test/fit-image-test/files/dt-fake.dtb b/meta-selftest/recipes-test/fit-image-test/files/dt-fake.dtb new file mode 100644 index 0000000000..7fa871ff00 --- /dev/null +++ b/meta-selftest/recipes-test/fit-image-test/files/dt-fake.dtb @@ -0,0 +1,3 @@ +Z�P�acn�ZWD1\�!΄�l�V +t(��H����z��jb4.���݁�W;I�ƶ����b�e���Ñ�5�x�&�9,��g +�;���!cV diff --git a/meta-selftest/recipes-test/fit-image-test/files/zImage-fake b/meta-selftest/recipes-test/fit-image-test/files/zImage-fake new file mode 100644 index 0000000000..7fa871ff00 --- /dev/null +++ b/meta-selftest/recipes-test/fit-image-test/files/zImage-fake @@ -0,0 +1,3 @@ +Z�P�acn�ZWD1\�!΄�l�V +t(��H����z��jb4.���݁�W;I�ƶ����b�e���Ñ�5�x�&�9,��g +�;���!cV diff --git a/meta-selftest/recipes-test/fit-image-test/fit-image-test.bb b/meta-selftest/recipes-test/fit-image-test/fit-image-test.bb new file mode 100644 index 0000000000..c7f325ec8a --- /dev/null +++ b/meta-selftest/recipes-test/fit-image-test/fit-image-test.bb @@ -0,0 +1,17 @@ +SUMMARY = "Recipe for testing the fit_image bbclass" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" + +DEPENDS += "\ + python3-fdt-native \ +" + +SRC_URI = "\ + file://zImage-fake \ + file://dt-fake.dtb \ +" + +inherit fit_image + +include test_recipe.inc + diff --git a/meta/lib/oeqa/selftest/cases/fit_image.py b/meta/lib/oeqa/selftest/cases/fit_image.py new file mode 100644 index 0000000000..866e48b20e --- /dev/null +++ b/meta/lib/oeqa/selftest/cases/fit_image.py @@ -0,0 +1,212 @@ +import os +from oeqa.selftest.case import OESelftestTestCase +from oeqa.utils.commands import get_bb_var, bitbake, get_bb_vars + +class FitImage(OESelftestTestCase): + + @classmethod + def setUpClass(cls): + super(FitImage, cls).setUpClass() + cls.recipe_name = 'fit-image-test' + cls.build_dir = get_bb_var('B', cls.recipe_name) + cls.fit_blob_path = os.path.join(cls.build_dir, 'image-fit.itb') + + bitbake('python3-fdt-native') + fdt_sitepackage=get_bb_var("S", "python3-fdt-native") + os.sys.path.append(fdt_sitepackage) + import fdt + + bitbake('{recipe_name} -c cleanall'.format(recipe_name=cls.recipe_name)) + + @classmethod + def tearDownClass(cls): + bitbake('{recipe_name} -c cleanall'.format(recipe_name=cls.recipe_name)) + super(FitImage, cls).tearDownClass() + + def _get_fit_configuration(self): + configuration = """ +KERNEL_IMAGE_NODE[name] = "kernel" +KERNEL_IMAGE_NODE[description] = "${PF}" +KERNEL_IMAGE_NODE[data] = '/incbin/("${WORKDIR}/zImage-fake")' +KERNEL_IMAGE_NODE[type] = "kernel" +KERNEL_IMAGE_NODE[arch] = "arm" +KERNEL_IMAGE_NODE[os] = "linux" +KERNEL_IMAGE_NODE[compression] = "none" +KERNEL_IMAGE_NODE[load] = "0x84000000" +KERNEL_IMAGE_NODE[entry] = "0x84000000" +KERNEL_IMAGE_NODE[hash] = "sha256" + +FDT_IMAGE_NODE[name] = "fdt" +FDT_IMAGE_NODE[description] = "FDT blob" +FDT_IMAGE_NODE[data] = '/incbin/("${WORKDIR}/dt-fake.dtb")' +FDT_IMAGE_NODE[type] = "flat_dt" +FDT_IMAGE_NODE[arch] = "arm" +FDT_IMAGE_NODE[compression] = "none" +FDT_IMAGE_NODE[hash] = "sha256" + +CONF1_CONF_NODE[name] = "conf" +CONF1_CONF_NODE[description] = "Linux kernel and FDT blob" +CONF1_CONF_NODE[kernel] = "kernel" +CONF1_CONF_NODE[fdt] = "fdt" + +FIT_IMAGES_NODE = "KERNEL_IMAGE_NODE FDT_IMAGE_NODE" +FIT_CONFIGURATIONS_NODE = "CONF1_CONF_NODE" +FIT_CONFIGURATIONS_NODE[default] = "${@d.getVarFlag('CONF1_CONF_NODE', 'name') or ""}" +""" + return configuration + + def setUp(self): + super(FitImage, self).setUp() + self.write_recipeinc(self.recipe_name, self._get_fit_configuration()) + + def tearDown(self): + self.delete_recipeinc(self.recipe_name) + super(FitImage, self).tearDown() + + def test_fit_source_is_generated_correctly(self): + ret = bitbake("{recipe} -D -f -c generate_fit_image".format(recipe=self.recipe_name)).output + self.logger.info('HN {log}'.format(log=ret)) + + def test_fit_blob_is_generated_successfully(self): + """ + Summary: Able to apply a single patch to the Linux kernel source + Expected: The README file should exist and the patch changes should be + displayed at the end of the file. + Product: Kernel Development + Author: Yeoh Ee Peng <ee.peng.y...@intel.com> + AutomatedBy: Mazliana Mohamad <mazliana.moha...@intel.com> + """ + + bitbake("{recipe} -c generate_fit_image".format(recipe=self.recipe_name)) + self.assertExists(self.fit_blob_path, "FIT Blob not generated") + + def test_that_fit_blob_name_is_configurable(self): + """ + Summary: Able to apply a single patch to the Linux kernel source + Expected: The README file should exist and the patch changes should be + displayed at the end of the file. + """ + fit_image_name = "custom-fit-blob-name" + fit_blob_path = os.path.join(self.build_dir, "{name}.itb".format(name=fit_image_name)) + + self.append_recipeinc(self.recipe_name, 'FIT_IMAGE_FILENAME = "{name}"'.format(name=fit_image_name)) + bitbake("{recipe} -c generate_fit_image".format(recipe=self.recipe_name)) + + self.assertExists(fit_blob_path, "FIT Blob not generated") + + def _fail_when_property_missing(self, property): + self.remove_recipeinc(self.recipe_name, property) + with self.assertRaises(AssertionError): + ret = bitbake("{recipe} -f -c generate_fit_image".format(recipe=self.recipe_name)) + + def test_fail_when_image_node_name_property_missing(self): + self._fail_when_property_missing('KERNEL_IMAGE_NODE[name] = "kernel"') + + def test_fail_when_image_node_description_property_missing(self): + self._fail_when_property_missing('KERNEL_IMAGE_NODE[description] = "${PF}"') + + def test_fail_when_image_node_data_property_missing(self): + self._fail_when_property_missing('KERNEL_IMAGE_NODE[data] = \'/incbin/("${WORKDIR}/zImage-fake")\'') + + def test_fail_when_image_node_compression_property_missing(self): + self._fail_when_property_missing('KERNEL_IMAGE_NODE[type] = "kernel"') + + def test_fail_when_conf_node_name_property_missing(self): + self._fail_when_property_missing('CONF1_CONF_NODE[name] = "conf"') + + def test_fail_when_conf_node_description_property_missing(self): + self._fail_when_property_missing('CONF1_CONF_NODE[description] = "Linux kernel and FDT blob"') + + def test_that_number_of_nodes_is_correct(self): + pass + + def _extract_fit_source(self, text): + import re + mylines = [] + copy = False + + for myline in text: + if re.match('^DEBUG:.+', myline): + copy = False + + if copy: + mylines.append(myline.rstrip('\r\n').strip()) + + if re.match('^DEBUG:.+do_generate_fit_image: Generated FIT source is:$', myline): + copy = True + + sf = ''.join(mylines) + self.logger.info('LOG: {log}\nFIT SOURCE {sf}'.format(log=text, sf=sf)) + + def _verify_node(self, var_name, path, properties): + import fdt + + # I'm creating variables in the recipe that contain the flags value. + # I wasn't able to find a better way to read a flag of a variable in the test. + for p in properties: + self.append_recipeinc( + self.recipe_name, 'FIT_IMAGE_TEST_{pu} = "${{@d.getVarFlag(\'{var}\', \'{p}\')}}"'.format( + pu=p.upper(), p=p, var=var_name)) + + ret = bitbake("{recipe} -D -c generate_fit_image".format(recipe=self.recipe_name)) + self._extract_fit_source(ret.output) + + with open(self.fit_blob_path, 'rb') as fb: + fit_blob = fb.read() + + dt = fdt.parse_dtb(fit_blob) + + try: + node = dt.get_node(path) + except ValueError: + self.assertTrue(False, '{node} node not generated'.format(node=path)) + + node_flags = get_bb_vars(['FIT_IMAGE_TEST_{p}'.format(p=p.upper()) for p in properties], + self.recipe_name) + + for p in properties: + self.assertTrue( + node.exist_property(p), + 'Missing property {p} from node {n}'.format(p=p.upper(), n=path)) + + self.assertTrue( + node_flags['FIT_IMAGE_TEST_{p}'.format(p=p.upper())], + node.get_property(p)) + + + def _verify_image_node(self, var_name, name, properties): + self._verify_node(var_name, 'images/{name}'.format(name=name), properties) + + def _verify_config_node(self, var_name, name, properties): + self._verify_node(var_name, 'configurations/{name}'.format(name=name), properties) + + def test_that_kernel_node_is_generated_successfully(self): + properties = [ + 'description', + 'data', + 'type', + 'arch', + 'os', + 'compression', + 'load', + 'entry' + ] + self._verify_image_node('KERNEL_IMAGE_NODE', 'kernel', properties) + + def test_that_fdt_node_is_generated_successfully(self): + properties = [ + 'description', + 'data', + 'type', + 'arch', + 'compression' + ] + self._verify_image_node('FDT_IMAGE_NODE', 'fdt', properties) + + def test_that_conf_node_is_generated_successfully(self): + properties = [ + 'description', + 'kernel', + 'fdt' + ] + self._verify_config_node('CONF1_CONF_NODE', 'conf', properties) -- 2.24.1
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#138731): https://lists.openembedded.org/g/openembedded-core/message/138731 Mute This Topic: https://lists.openembedded.org/mt/74483351/21656 Group Owner: openembedded-core+ow...@lists.openembedded.org Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-