diff options
Diffstat (limited to 'meta/lib/oeqa/selftest/cases')
-rw-r--r-- | meta/lib/oeqa/selftest/cases/buildhistory.py | 61 | ||||
-rw-r--r-- | meta/lib/oeqa/selftest/cases/buildoptions.py | 38 | ||||
-rw-r--r-- | meta/lib/oeqa/selftest/cases/devtool.py | 24 | ||||
-rw-r--r-- | meta/lib/oeqa/selftest/cases/distrodata.py | 2 | ||||
-rw-r--r-- | meta/lib/oeqa/selftest/cases/esdk.py | 6 | ||||
-rw-r--r-- | meta/lib/oeqa/selftest/cases/fitimage.py | 406 | ||||
-rw-r--r-- | meta/lib/oeqa/selftest/cases/liboe.py | 37 | ||||
-rw-r--r-- | meta/lib/oeqa/selftest/cases/oescripts.py | 24 | ||||
-rw-r--r-- | meta/lib/oeqa/selftest/cases/pokybleeding.py | 32 | ||||
-rw-r--r-- | meta/lib/oeqa/selftest/cases/recipetool.py | 14 | ||||
-rw-r--r-- | meta/lib/oeqa/selftest/cases/recipeutils.py | 4 | ||||
-rw-r--r-- | meta/lib/oeqa/selftest/cases/rust.py | 2 | ||||
-rw-r--r-- | meta/lib/oeqa/selftest/cases/sstatetests.py | 99 | ||||
-rw-r--r-- | meta/lib/oeqa/selftest/cases/toolchain.py | 71 | ||||
-rw-r--r-- | meta/lib/oeqa/selftest/cases/uboot.py | 59 | ||||
-rw-r--r-- | meta/lib/oeqa/selftest/cases/wic.py | 45 |
16 files changed, 666 insertions, 258 deletions
diff --git a/meta/lib/oeqa/selftest/cases/buildhistory.py b/meta/lib/oeqa/selftest/cases/buildhistory.py index 2d55994916..511c666554 100644 --- a/meta/lib/oeqa/selftest/cases/buildhistory.py +++ b/meta/lib/oeqa/selftest/cases/buildhistory.py | |||
@@ -9,10 +9,10 @@ import re | |||
9 | import datetime | 9 | import datetime |
10 | 10 | ||
11 | from oeqa.selftest.case import OESelftestTestCase | 11 | from oeqa.selftest.case import OESelftestTestCase |
12 | from oeqa.utils.commands import bitbake, get_bb_vars | 12 | from oeqa.utils.commands import bitbake, get_bb_vars, get_bb_var, runCmd |
13 | 13 | ||
14 | 14 | ||
15 | class BuildhistoryBase(OESelftestTestCase): | 15 | class BuildhistoryTests(OESelftestTestCase): |
16 | 16 | ||
17 | def config_buildhistory(self, tmp_bh_location=False): | 17 | def config_buildhistory(self, tmp_bh_location=False): |
18 | bb_vars = get_bb_vars(['USER_CLASSES', 'INHERIT']) | 18 | bb_vars = get_bb_vars(['USER_CLASSES', 'INHERIT']) |
@@ -48,5 +48,58 @@ class BuildhistoryBase(OESelftestTestCase): | |||
48 | else: | 48 | else: |
49 | self.assertEqual(result.status, 0, msg="Command 'bitbake %s' has failed unexpectedly: %s" % (target, result.output)) | 49 | self.assertEqual(result.status, 0, msg="Command 'bitbake %s' has failed unexpectedly: %s" % (target, result.output)) |
50 | 50 | ||
51 | # No tests should be added to the base class. | 51 | |
52 | # Please create a new class that inherit this one, or use one of those already available for adding tests. | 52 | def test_buildhistory_basic(self): |
53 | self.run_buildhistory_operation('xcursor-transparent-theme') | ||
54 | self.assertTrue(os.path.isdir(get_bb_var('BUILDHISTORY_DIR')), "buildhistory dir was not created.") | ||
55 | |||
56 | def test_buildhistory_buildtime_pr_backwards(self): | ||
57 | target = 'xcursor-transparent-theme' | ||
58 | error = "ERROR:.*QA Issue: Package version for package %s went backwards which would break package feeds \(from .*-r1.* to .*-r0.*\)" % target | ||
59 | self.run_buildhistory_operation(target, target_config="PR = \"r1\"", change_bh_location=True) | ||
60 | self.run_buildhistory_operation(target, target_config="PR = \"r0\"", change_bh_location=False, expect_error=True, error_regex=error) | ||
61 | |||
62 | def test_fileinfo(self): | ||
63 | self.config_buildhistory() | ||
64 | bitbake('hicolor-icon-theme') | ||
65 | history_dir = get_bb_var('BUILDHISTORY_DIR_PACKAGE', 'hicolor-icon-theme') | ||
66 | self.assertTrue(os.path.isdir(history_dir), 'buildhistory dir was not created.') | ||
67 | |||
68 | def load_bh(f): | ||
69 | d = {} | ||
70 | for line in open(f): | ||
71 | split = [s.strip() for s in line.split('=', 1)] | ||
72 | if len(split) > 1: | ||
73 | d[split[0]] = split[1] | ||
74 | return d | ||
75 | |||
76 | data = load_bh(os.path.join(history_dir, 'hicolor-icon-theme', 'latest')) | ||
77 | self.assertIn('FILELIST', data) | ||
78 | self.assertEqual(data['FILELIST'], '/usr/share/icons/hicolor/index.theme') | ||
79 | self.assertGreater(int(data['PKGSIZE']), 0) | ||
80 | |||
81 | data = load_bh(os.path.join(history_dir, 'hicolor-icon-theme-dev', 'latest')) | ||
82 | if 'FILELIST' in data: | ||
83 | self.assertEqual(data['FILELIST'], '/usr/share/pkgconfig/default-icon-theme.pc') | ||
84 | self.assertGreater(int(data['PKGSIZE']), 0) | ||
85 | |||
86 | def test_buildhistory_diff(self): | ||
87 | target = 'xcursor-transparent-theme' | ||
88 | self.run_buildhistory_operation(target, target_config="PR = \"r1\"", change_bh_location=True) | ||
89 | self.run_buildhistory_operation(target, target_config="PR = \"r0\"", change_bh_location=False, expect_error=True) | ||
90 | result = runCmd("oe-pkgdata-util read-value PKGV %s" % target) | ||
91 | pkgv = result.output.rstrip() | ||
92 | result = runCmd("buildhistory-diff -p %s" % get_bb_var('BUILDHISTORY_DIR')) | ||
93 | expected_endlines = [ | ||
94 | "xcursor-transparent-theme-dev: RRECOMMENDS: removed \"xcursor-transparent-theme (['= %s-r1'])\", added \"xcursor-transparent-theme (['= %s-r0'])\"" % (pkgv, pkgv), | ||
95 | "xcursor-transparent-theme-staticdev: RDEPENDS: removed \"xcursor-transparent-theme-dev (['= %s-r1'])\", added \"xcursor-transparent-theme-dev (['= %s-r0'])\"" % (pkgv, pkgv) | ||
96 | ] | ||
97 | for line in result.output.splitlines(): | ||
98 | for el in expected_endlines: | ||
99 | if line.endswith(el): | ||
100 | expected_endlines.remove(el) | ||
101 | break | ||
102 | else: | ||
103 | self.fail('Unexpected line:\n%s\nExpected line endings:\n %s' % (line, '\n '.join(expected_endlines))) | ||
104 | if expected_endlines: | ||
105 | self.fail('Missing expected line endings:\n %s' % '\n '.join(expected_endlines)) \ No newline at end of file | ||
diff --git a/meta/lib/oeqa/selftest/cases/buildoptions.py b/meta/lib/oeqa/selftest/cases/buildoptions.py index b509bcf951..767e19bd88 100644 --- a/meta/lib/oeqa/selftest/cases/buildoptions.py +++ b/meta/lib/oeqa/selftest/cases/buildoptions.py | |||
@@ -10,7 +10,6 @@ import glob as g | |||
10 | import shutil | 10 | import shutil |
11 | import tempfile | 11 | import tempfile |
12 | from oeqa.selftest.case import OESelftestTestCase | 12 | from oeqa.selftest.case import OESelftestTestCase |
13 | from oeqa.selftest.cases.buildhistory import BuildhistoryBase | ||
14 | from oeqa.core.decorator.data import skipIfMachine | 13 | from oeqa.core.decorator.data import skipIfMachine |
15 | from oeqa.utils.commands import bitbake, get_bb_var, get_bb_vars | 14 | from oeqa.utils.commands import bitbake, get_bb_var, get_bb_vars |
16 | import oeqa.utils.ftools as ftools | 15 | import oeqa.utils.ftools as ftools |
@@ -139,43 +138,6 @@ class SanityOptionsTest(OESelftestTestCase): | |||
139 | 138 | ||
140 | self.assertNotIn(err, ret.output) | 139 | self.assertNotIn(err, ret.output) |
141 | 140 | ||
142 | |||
143 | class BuildhistoryTests(BuildhistoryBase): | ||
144 | |||
145 | def test_buildhistory_basic(self): | ||
146 | self.run_buildhistory_operation('xcursor-transparent-theme') | ||
147 | self.assertTrue(os.path.isdir(get_bb_var('BUILDHISTORY_DIR')), "buildhistory dir was not created.") | ||
148 | |||
149 | def test_buildhistory_buildtime_pr_backwards(self): | ||
150 | target = 'xcursor-transparent-theme' | ||
151 | error = "ERROR:.*QA Issue: Package version for package %s went backwards which would break package feeds \(from .*-r1.* to .*-r0.*\)" % target | ||
152 | self.run_buildhistory_operation(target, target_config="PR = \"r1\"", change_bh_location=True) | ||
153 | self.run_buildhistory_operation(target, target_config="PR = \"r0\"", change_bh_location=False, expect_error=True, error_regex=error) | ||
154 | |||
155 | def test_fileinfo(self): | ||
156 | self.config_buildhistory() | ||
157 | bitbake('hicolor-icon-theme') | ||
158 | history_dir = get_bb_var('BUILDHISTORY_DIR_PACKAGE', 'hicolor-icon-theme') | ||
159 | self.assertTrue(os.path.isdir(history_dir), 'buildhistory dir was not created.') | ||
160 | |||
161 | def load_bh(f): | ||
162 | d = {} | ||
163 | for line in open(f): | ||
164 | split = [s.strip() for s in line.split('=', 1)] | ||
165 | if len(split) > 1: | ||
166 | d[split[0]] = split[1] | ||
167 | return d | ||
168 | |||
169 | data = load_bh(os.path.join(history_dir, 'hicolor-icon-theme', 'latest')) | ||
170 | self.assertIn('FILELIST', data) | ||
171 | self.assertEqual(data['FILELIST'], '/usr/share/icons/hicolor/index.theme') | ||
172 | self.assertGreater(int(data['PKGSIZE']), 0) | ||
173 | |||
174 | data = load_bh(os.path.join(history_dir, 'hicolor-icon-theme-dev', 'latest')) | ||
175 | if 'FILELIST' in data: | ||
176 | self.assertEqual(data['FILELIST'], '/usr/share/pkgconfig/default-icon-theme.pc') | ||
177 | self.assertGreater(int(data['PKGSIZE']), 0) | ||
178 | |||
179 | class ArchiverTest(OESelftestTestCase): | 141 | class ArchiverTest(OESelftestTestCase): |
180 | def test_arch_work_dir_and_export_source(self): | 142 | def test_arch_work_dir_and_export_source(self): |
181 | """ | 143 | """ |
diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py index 0155ee62ee..74a7727cc0 100644 --- a/meta/lib/oeqa/selftest/cases/devtool.py +++ b/meta/lib/oeqa/selftest/cases/devtool.py | |||
@@ -469,7 +469,7 @@ class DevtoolAddTests(DevtoolBase): | |||
469 | checkvars = {} | 469 | checkvars = {} |
470 | checkvars['LICENSE'] = 'GPL-2.0-only' | 470 | checkvars['LICENSE'] = 'GPL-2.0-only' |
471 | checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263' | 471 | checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263' |
472 | checkvars['S'] = '${WORKDIR}/git' | 472 | checkvars['S'] = None |
473 | checkvars['PV'] = '0.1+git' | 473 | checkvars['PV'] = '0.1+git' |
474 | checkvars['SRC_URI'] = 'git://git.yoctoproject.org/git/dbus-wait;protocol=https;branch=master' | 474 | checkvars['SRC_URI'] = 'git://git.yoctoproject.org/git/dbus-wait;protocol=https;branch=master' |
475 | checkvars['SRCREV'] = srcrev | 475 | checkvars['SRCREV'] = srcrev |
@@ -565,7 +565,7 @@ class DevtoolAddTests(DevtoolBase): | |||
565 | recipefile = get_bb_var('FILE', testrecipe) | 565 | recipefile = get_bb_var('FILE', testrecipe) |
566 | self.assertIn('%s_%s.bb' % (testrecipe, testver), recipefile, 'Recipe file incorrectly named') | 566 | self.assertIn('%s_%s.bb' % (testrecipe, testver), recipefile, 'Recipe file incorrectly named') |
567 | checkvars = {} | 567 | checkvars = {} |
568 | checkvars['S'] = '${WORKDIR}/MarkupSafe-${PV}' | 568 | checkvars['S'] = '${UNPACKDIR}/MarkupSafe-${PV}' |
569 | checkvars['SRC_URI'] = url.replace(testver, '${PV}') | 569 | checkvars['SRC_URI'] = url.replace(testver, '${PV}') |
570 | self._test_recipe_contents(recipefile, checkvars, []) | 570 | self._test_recipe_contents(recipefile, checkvars, []) |
571 | # Try with version specified | 571 | # Try with version specified |
@@ -582,7 +582,7 @@ class DevtoolAddTests(DevtoolBase): | |||
582 | recipefile = get_bb_var('FILE', testrecipe) | 582 | recipefile = get_bb_var('FILE', testrecipe) |
583 | self.assertIn('%s_%s.bb' % (testrecipe, fakever), recipefile, 'Recipe file incorrectly named') | 583 | self.assertIn('%s_%s.bb' % (testrecipe, fakever), recipefile, 'Recipe file incorrectly named') |
584 | checkvars = {} | 584 | checkvars = {} |
585 | checkvars['S'] = '${WORKDIR}/MarkupSafe-%s' % testver | 585 | checkvars['S'] = '${UNPACKDIR}/MarkupSafe-%s' % testver |
586 | checkvars['SRC_URI'] = url | 586 | checkvars['SRC_URI'] = url |
587 | self._test_recipe_contents(recipefile, checkvars, []) | 587 | self._test_recipe_contents(recipefile, checkvars, []) |
588 | 588 | ||
@@ -609,7 +609,7 @@ class DevtoolAddTests(DevtoolBase): | |||
609 | recipefile = get_bb_var('FILE', testrecipe) | 609 | recipefile = get_bb_var('FILE', testrecipe) |
610 | self.assertIn('_git.bb', recipefile, 'Recipe file incorrectly named') | 610 | self.assertIn('_git.bb', recipefile, 'Recipe file incorrectly named') |
611 | checkvars = {} | 611 | checkvars = {} |
612 | checkvars['S'] = '${WORKDIR}/git' | 612 | checkvars['S'] = None |
613 | checkvars['PV'] = '1.0+git' | 613 | checkvars['PV'] = '1.0+git' |
614 | checkvars['SRC_URI'] = url_branch | 614 | checkvars['SRC_URI'] = url_branch |
615 | checkvars['SRCREV'] = '${AUTOREV}' | 615 | checkvars['SRCREV'] = '${AUTOREV}' |
@@ -628,7 +628,7 @@ class DevtoolAddTests(DevtoolBase): | |||
628 | recipefile = get_bb_var('FILE', testrecipe) | 628 | recipefile = get_bb_var('FILE', testrecipe) |
629 | self.assertIn('_git.bb', recipefile, 'Recipe file incorrectly named') | 629 | self.assertIn('_git.bb', recipefile, 'Recipe file incorrectly named') |
630 | checkvars = {} | 630 | checkvars = {} |
631 | checkvars['S'] = '${WORKDIR}/git' | 631 | checkvars['S'] = None |
632 | checkvars['PV'] = '1.5+git' | 632 | checkvars['PV'] = '1.5+git' |
633 | checkvars['SRC_URI'] = url_branch | 633 | checkvars['SRC_URI'] = url_branch |
634 | checkvars['SRCREV'] = checkrev | 634 | checkvars['SRCREV'] = checkrev |
@@ -1627,12 +1627,12 @@ class DevtoolUpdateTests(DevtoolBase): | |||
1627 | # Check preconditions | 1627 | # Check preconditions |
1628 | testrecipe = 'dos2unix' | 1628 | testrecipe = 'dos2unix' |
1629 | self.append_config('ERROR_QA:remove:pn-dos2unix = "patch-status"\n') | 1629 | self.append_config('ERROR_QA:remove:pn-dos2unix = "patch-status"\n') |
1630 | bb_vars = get_bb_vars(['SRC_URI', 'S', 'WORKDIR', 'FILE'], testrecipe) | 1630 | bb_vars = get_bb_vars(['SRC_URI', 'S', 'UNPACKDIR', 'FILE', 'BB_GIT_DEFAULT_DESTSUFFIX'], testrecipe) |
1631 | self.assertIn('git://', bb_vars['SRC_URI'], 'This test expects the %s recipe to be a git recipe' % testrecipe) | 1631 | self.assertIn('git://', bb_vars['SRC_URI'], 'This test expects the %s recipe to be a git recipe' % testrecipe) |
1632 | workdir_git = '%s/git/' % bb_vars['WORKDIR'] | 1632 | unpackdir_git = '%s/%s/' % (bb_vars['UNPACKDIR'], bb_vars['BB_GIT_DEFAULT_DESTSUFFIX']) |
1633 | if not bb_vars['S'].startswith(workdir_git): | 1633 | if not bb_vars['S'].startswith(unpackdir_git): |
1634 | self.fail('This test expects the %s recipe to be building from a subdirectory of the git repo' % testrecipe) | 1634 | self.fail('This test expects the %s recipe to be building from a subdirectory of the git repo' % testrecipe) |
1635 | subdir = bb_vars['S'].split(workdir_git, 1)[1] | 1635 | subdir = bb_vars['S'].split(unpackdir_git, 1)[1] |
1636 | # Clean up anything in the workdir/sysroot/sstate cache | 1636 | # Clean up anything in the workdir/sysroot/sstate cache |
1637 | bitbake('%s -c cleansstate' % testrecipe) | 1637 | bitbake('%s -c cleansstate' % testrecipe) |
1638 | # Try modifying a recipe | 1638 | # Try modifying a recipe |
@@ -2414,7 +2414,7 @@ class DevtoolUpgradeTests(DevtoolBase): | |||
2414 | newsrctree = os.path.join(self.workspacedir, 'sources', newrecipename) | 2414 | newsrctree = os.path.join(self.workspacedir, 'sources', newrecipename) |
2415 | self.assertExists(newsrctree, 'Source directory not renamed') | 2415 | self.assertExists(newsrctree, 'Source directory not renamed') |
2416 | checkvars = {} | 2416 | checkvars = {} |
2417 | checkvars['S'] = '${WORKDIR}/%s-%s' % (recipename, recipever) | 2417 | checkvars['S'] = '${UNPACKDIR}/%s-%s' % (recipename, recipever) |
2418 | checkvars['SRC_URI'] = url | 2418 | checkvars['SRC_URI'] = url |
2419 | self._test_recipe_contents(newrecipefile, checkvars, []) | 2419 | self._test_recipe_contents(newrecipefile, checkvars, []) |
2420 | # Try again - change just name this time | 2420 | # Try again - change just name this time |
@@ -2426,7 +2426,7 @@ class DevtoolUpgradeTests(DevtoolBase): | |||
2426 | self.assertNotExists(os.path.join(self.workspacedir, 'recipes', recipename), 'Old recipe directory still exists') | 2426 | self.assertNotExists(os.path.join(self.workspacedir, 'recipes', recipename), 'Old recipe directory still exists') |
2427 | self.assertExists(os.path.join(self.workspacedir, 'sources', newrecipename), 'Source directory not renamed') | 2427 | self.assertExists(os.path.join(self.workspacedir, 'sources', newrecipename), 'Source directory not renamed') |
2428 | checkvars = {} | 2428 | checkvars = {} |
2429 | checkvars['S'] = '${WORKDIR}/%s-${PV}' % recipename | 2429 | checkvars['S'] = '${UNPACKDIR}/%s-${PV}' % recipename |
2430 | checkvars['SRC_URI'] = url.replace(recipever, '${PV}') | 2430 | checkvars['SRC_URI'] = url.replace(recipever, '${PV}') |
2431 | self._test_recipe_contents(newrecipefile, checkvars, []) | 2431 | self._test_recipe_contents(newrecipefile, checkvars, []) |
2432 | # Try again - change just version this time | 2432 | # Try again - change just version this time |
@@ -2437,7 +2437,7 @@ class DevtoolUpgradeTests(DevtoolBase): | |||
2437 | self.assertExists(newrecipefile, 'Recipe file not renamed') | 2437 | self.assertExists(newrecipefile, 'Recipe file not renamed') |
2438 | self.assertExists(os.path.join(self.workspacedir, 'sources', recipename), 'Source directory no longer exists') | 2438 | self.assertExists(os.path.join(self.workspacedir, 'sources', recipename), 'Source directory no longer exists') |
2439 | checkvars = {} | 2439 | checkvars = {} |
2440 | checkvars['S'] = '${WORKDIR}/${BPN}-%s' % recipever | 2440 | checkvars['S'] = '${UNPACKDIR}/${BPN}-%s' % recipever |
2441 | checkvars['SRC_URI'] = url | 2441 | checkvars['SRC_URI'] = url |
2442 | self._test_recipe_contents(newrecipefile, checkvars, []) | 2442 | self._test_recipe_contents(newrecipefile, checkvars, []) |
2443 | 2443 | ||
diff --git a/meta/lib/oeqa/selftest/cases/distrodata.py b/meta/lib/oeqa/selftest/cases/distrodata.py index 1e88ea82e6..f2c6124d70 100644 --- a/meta/lib/oeqa/selftest/cases/distrodata.py +++ b/meta/lib/oeqa/selftest/cases/distrodata.py | |||
@@ -56,7 +56,7 @@ but their recipes claim otherwise by setting UPSTREAM_VERSION_UNKNOWN. Please re | |||
56 | 56 | ||
57 | def is_maintainer_exception(entry): | 57 | def is_maintainer_exception(entry): |
58 | exceptions = ["musl", "newlib", "picolibc", "linux-yocto", "linux-dummy", "mesa-gl", "libgfortran", "libx11-compose-data", | 58 | exceptions = ["musl", "newlib", "picolibc", "linux-yocto", "linux-dummy", "mesa-gl", "libgfortran", "libx11-compose-data", |
59 | "cve-update-nvd2-native", "barebox"] | 59 | "cve-update-nvd2-native", "barebox", "libglvnd"] |
60 | for i in exceptions: | 60 | for i in exceptions: |
61 | if i in entry: | 61 | if i in entry: |
62 | return True | 62 | return True |
diff --git a/meta/lib/oeqa/selftest/cases/esdk.py b/meta/lib/oeqa/selftest/cases/esdk.py index 9f5de2cde7..7a5fe00a08 100644 --- a/meta/lib/oeqa/selftest/cases/esdk.py +++ b/meta/lib/oeqa/selftest/cases/esdk.py | |||
@@ -27,11 +27,7 @@ class oeSDKExtSelfTest(OESelftestTestCase): | |||
27 | return glob.glob(pattern)[0] | 27 | return glob.glob(pattern)[0] |
28 | 28 | ||
29 | @staticmethod | 29 | @staticmethod |
30 | def run_esdk_cmd(env_eSDK, tmpdir_eSDKQA, cmd, postconfig=None, **options): | 30 | def run_esdk_cmd(env_eSDK, tmpdir_eSDKQA, cmd, **options): |
31 | if postconfig: | ||
32 | esdk_conf_file = os.path.join(tmpdir_eSDKQA, 'conf', 'local.conf') | ||
33 | with open(esdk_conf_file, 'a+') as f: | ||
34 | f.write(postconfig) | ||
35 | if not options: | 31 | if not options: |
36 | options = {} | 32 | options = {} |
37 | if not 'shell' in options: | 33 | if not 'shell' in options: |
diff --git a/meta/lib/oeqa/selftest/cases/fitimage.py b/meta/lib/oeqa/selftest/cases/fitimage.py index b39f2622df..3c40857747 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 | ||
7 | from oeqa.selftest.case import OESelftestTestCase | ||
8 | from oeqa.utils.commands import runCmd, bitbake, get_bb_vars | ||
9 | import os | 7 | import os |
10 | import re | 8 | import re |
11 | import shlex | 9 | import shlex |
12 | import logging | 10 | import logging |
13 | import pprint | 11 | import pprint |
12 | import tempfile | ||
13 | |||
14 | import oe.fitimage | ||
15 | |||
16 | from oeqa.selftest.case import OESelftestTestCase | ||
17 | from oeqa.utils.commands import runCmd, bitbake, get_bb_vars, get_bb_var | ||
18 | |||
19 | |||
20 | class 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 | ||
15 | class FitImageTestCase(OESelftestTestCase): | 38 | class 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 |
@@ -161,10 +184,23 @@ class FitImageTestCase(OESelftestTestCase): | |||
161 | 184 | ||
162 | @staticmethod | 185 | @staticmethod |
163 | def _get_dtb_files(bb_vars): | 186 | def _get_dtb_files(bb_vars): |
187 | """Return a list of devicetree names | ||
188 | |||
189 | The list should be used to check the dtb and conf nodes in the FIT image or its file. | ||
190 | In addition to the entries from KERNEL_DEVICETREE, the external devicetree and the | ||
191 | external devicetree overlay added by the test recipe bbb-dtbs-as-ext are handled as well. | ||
192 | """ | ||
164 | kernel_devicetree = bb_vars.get('KERNEL_DEVICETREE') | 193 | kernel_devicetree = bb_vars.get('KERNEL_DEVICETREE') |
194 | all_dtbs = [] | ||
195 | dtb_symlinks = [] | ||
165 | if kernel_devicetree: | 196 | if kernel_devicetree: |
166 | return [os.path.basename(dtb) for dtb in kernel_devicetree.split()] | 197 | all_dtbs += [os.path.basename(dtb) for dtb in kernel_devicetree.split()] |
167 | return [] | 198 | # Support only the test recipe which provides 1 devicetree and 1 devicetree overlay |
199 | pref_prov_dtb = bb_vars.get('PREFERRED_PROVIDER_virtual/dtb') | ||
200 | if pref_prov_dtb == "bbb-dtbs-as-ext": | ||
201 | all_dtbs += ["am335x-bonegreen-ext.dtb", "BBORG_RELAY-00A2.dtbo"] | ||
202 | dtb_symlinks.append("am335x-bonegreen-ext-alias.dtb") | ||
203 | return (all_dtbs, dtb_symlinks) | ||
168 | 204 | ||
169 | def _is_req_dict_in_dict(self, found_dict, req_dict): | 205 | def _is_req_dict_in_dict(self, found_dict, req_dict): |
170 | """ | 206 | """ |
@@ -243,7 +279,7 @@ class FitImageTestCase(OESelftestTestCase): | |||
243 | self.logger.debug("sigs:\n%s\n" % pprint.pformat(sigs, indent=4)) | 279 | self.logger.debug("sigs:\n%s\n" % pprint.pformat(sigs, indent=4)) |
244 | if req_sigvalues_config or req_sigvalues_image: | 280 | if req_sigvalues_config or req_sigvalues_image: |
245 | for its_path, values in sigs.items(): | 281 | for its_path, values in sigs.items(): |
246 | if 'conf-' in its_path: | 282 | if bb_vars.get('FIT_CONF_PREFIX', "conf-") in its_path: |
247 | reqsigvalues = req_sigvalues_config | 283 | reqsigvalues = req_sigvalues_config |
248 | else: | 284 | else: |
249 | reqsigvalues = req_sigvalues_image | 285 | reqsigvalues = req_sigvalues_image |
@@ -356,9 +392,8 @@ class FitImageTestCase(OESelftestTestCase): | |||
356 | # Verify the FIT image | 392 | # Verify the FIT image |
357 | self._check_fitimage(bb_vars, fitimage_path, uboot_tools_bindir) | 393 | self._check_fitimage(bb_vars, fitimage_path, uboot_tools_bindir) |
358 | 394 | ||
359 | 395 | class KernelFitImageBase(FitImageTestCase): | |
360 | class KernelFitImageTests(FitImageTestCase): | 396 | """Test cases for the linux-yocto-fitimage recipe""" |
361 | """Test cases for the kernel-fitimage bbclass""" | ||
362 | 397 | ||
363 | def _fit_get_bb_vars(self, additional_vars=[]): | 398 | def _fit_get_bb_vars(self, additional_vars=[]): |
364 | """Retrieve BitBake variables specific to the test case. | 399 | """Retrieve BitBake variables specific to the test case. |
@@ -367,6 +402,8 @@ class KernelFitImageTests(FitImageTestCase): | |||
367 | """ | 402 | """ |
368 | internal_used = { | 403 | internal_used = { |
369 | 'DEPLOY_DIR_IMAGE', | 404 | 'DEPLOY_DIR_IMAGE', |
405 | 'FIT_CONF_DEFAULT_DTB', | ||
406 | 'FIT_CONF_PREFIX', | ||
370 | 'FIT_DESC', | 407 | 'FIT_DESC', |
371 | 'FIT_HASH_ALG', | 408 | 'FIT_HASH_ALG', |
372 | 'FIT_KERNEL_COMP_ALG', | 409 | 'FIT_KERNEL_COMP_ALG', |
@@ -376,9 +413,11 @@ class KernelFitImageTests(FitImageTestCase): | |||
376 | 'INITRAMFS_IMAGE_BUNDLE', | 413 | 'INITRAMFS_IMAGE_BUNDLE', |
377 | 'INITRAMFS_IMAGE_NAME', | 414 | 'INITRAMFS_IMAGE_NAME', |
378 | 'INITRAMFS_IMAGE', | 415 | 'INITRAMFS_IMAGE', |
416 | 'KERNEL_DEPLOYSUBDIR', | ||
379 | 'KERNEL_DEVICETREE', | 417 | 'KERNEL_DEVICETREE', |
380 | 'KERNEL_FIT_LINK_NAME', | 418 | 'KERNEL_FIT_LINK_NAME', |
381 | 'MACHINE', | 419 | 'MACHINE', |
420 | 'PREFERRED_PROVIDER_virtual/dtb', | ||
382 | 'UBOOT_ARCH', | 421 | 'UBOOT_ARCH', |
383 | 'UBOOT_ENTRYPOINT', | 422 | 'UBOOT_ENTRYPOINT', |
384 | 'UBOOT_LOADADDRESS', | 423 | 'UBOOT_LOADADDRESS', |
@@ -391,10 +430,19 @@ class KernelFitImageTests(FitImageTestCase): | |||
391 | 'UBOOT_SIGN_KEYDIR', | 430 | 'UBOOT_SIGN_KEYDIR', |
392 | 'UBOOT_SIGN_KEYNAME', | 431 | 'UBOOT_SIGN_KEYNAME', |
393 | } | 432 | } |
394 | bb_vars = get_bb_vars(list(internal_used | set(additional_vars)), "virtual/kernel") | 433 | bb_vars = get_bb_vars(list(internal_used | set(additional_vars)), self.kernel_recipe) |
395 | self.logger.debug("bb_vars: %s" % pprint.pformat(bb_vars, indent=4)) | 434 | self.logger.debug("bb_vars: %s" % pprint.pformat(bb_vars, indent=4)) |
396 | return bb_vars | 435 | return bb_vars |
397 | 436 | ||
437 | def _config_add_kernel_classes(self, config): | ||
438 | config += '# Use kernel-fit-extra-artifacts.bbclass for the creation of the vmlinux artifact' + os.linesep | ||
439 | config += 'KERNEL_CLASSES = "kernel-fit-extra-artifacts"' + os.linesep | ||
440 | return config | ||
441 | |||
442 | @property | ||
443 | def kernel_recipe(self): | ||
444 | return "linux-yocto-fitimage" | ||
445 | |||
398 | def _config_add_uboot_env(self, config): | 446 | def _config_add_uboot_env(self, config): |
399 | """Generate an u-boot environment | 447 | """Generate an u-boot environment |
400 | 448 | ||
@@ -408,7 +456,7 @@ class KernelFitImageTests(FitImageTestCase): | |||
408 | config += '# Add an u-boot script to the fitImage' + os.linesep | 456 | config += '# Add an u-boot script to the fitImage' + os.linesep |
409 | config += 'FIT_UBOOT_ENV = "%s"' % fit_uenv_file + os.linesep | 457 | config += 'FIT_UBOOT_ENV = "%s"' % fit_uenv_file + os.linesep |
410 | config += 'FILESEXTRAPATHS:prepend := "${TOPDIR}/%s:"' % test_files_dir + os.linesep | 458 | config += 'FILESEXTRAPATHS:prepend := "${TOPDIR}/%s:"' % test_files_dir + os.linesep |
411 | config += 'SRC_URI:append:pn-linux-yocto = " file://${FIT_UBOOT_ENV}"' + os.linesep | 459 | config += 'SRC_URI:append:pn-%s = " file://${FIT_UBOOT_ENV}"' % self.kernel_recipe + os.linesep |
412 | 460 | ||
413 | if not os.path.isdir(test_files_dir): | 461 | if not os.path.isdir(test_files_dir): |
414 | os.makedirs(test_files_dir) | 462 | os.makedirs(test_files_dir) |
@@ -420,7 +468,7 @@ class KernelFitImageTests(FitImageTestCase): | |||
420 | 468 | ||
421 | def _bitbake_fit_image(self, bb_vars): | 469 | def _bitbake_fit_image(self, bb_vars): |
422 | """Bitbake the kernel and return the paths to the its file and the FIT image""" | 470 | """Bitbake the kernel and return the paths to the its file and the FIT image""" |
423 | bitbake("virtual/kernel") | 471 | bitbake(self.kernel_recipe) |
424 | 472 | ||
425 | # Find the right its file and the final fitImage and check if both files are available | 473 | # Find the right its file and the final fitImage and check if both files are available |
426 | deploy_dir_image = bb_vars['DEPLOY_DIR_IMAGE'] | 474 | deploy_dir_image = bb_vars['DEPLOY_DIR_IMAGE'] |
@@ -439,8 +487,13 @@ class KernelFitImageTests(FitImageTestCase): | |||
439 | fitimage_name = "fitImage" # or fitImage-${KERNEL_IMAGE_LINK_NAME}${KERNEL_IMAGE_BIN_EXT} | 487 | fitimage_name = "fitImage" # or fitImage-${KERNEL_IMAGE_LINK_NAME}${KERNEL_IMAGE_BIN_EXT} |
440 | else: | 488 | else: |
441 | self.fail('Invalid configuration: INITRAMFS_IMAGE_BUNDLE = "1" and not INITRAMFS_IMAGE') | 489 | self.fail('Invalid configuration: INITRAMFS_IMAGE_BUNDLE = "1" and not INITRAMFS_IMAGE') |
442 | fitimage_its_path = os.path.realpath(os.path.join(deploy_dir_image, fitimage_its_name)) | 490 | kernel_deploysubdir = bb_vars['KERNEL_DEPLOYSUBDIR'] |
443 | fitimage_path = os.path.realpath(os.path.join(deploy_dir_image, fitimage_name)) | 491 | if kernel_deploysubdir: |
492 | fitimage_its_path = os.path.realpath(os.path.join(deploy_dir_image, kernel_deploysubdir, fitimage_its_name)) | ||
493 | fitimage_path = os.path.realpath(os.path.join(deploy_dir_image, kernel_deploysubdir, fitimage_name)) | ||
494 | else: | ||
495 | fitimage_its_path = os.path.realpath(os.path.join(deploy_dir_image, fitimage_its_name)) | ||
496 | fitimage_path = os.path.realpath(os.path.join(deploy_dir_image, fitimage_name)) | ||
444 | return (fitimage_its_path, fitimage_path) | 497 | return (fitimage_its_path, fitimage_path) |
445 | 498 | ||
446 | def _get_req_its_paths(self, bb_vars): | 499 | def _get_req_its_paths(self, bb_vars): |
@@ -452,7 +505,7 @@ class KernelFitImageTests(FitImageTestCase): | |||
452 | ['/', 'images', 'kernel-1', 'signature-1'], | 505 | ['/', 'images', 'kernel-1', 'signature-1'], |
453 | ] | 506 | ] |
454 | """ | 507 | """ |
455 | dtb_files = FitImageTestCase._get_dtb_files(bb_vars) | 508 | dtb_files, dtb_symlinks = FitImageTestCase._get_dtb_files(bb_vars) |
456 | fit_sign_individual = bb_vars['FIT_SIGN_INDIVIDUAL'] | 509 | fit_sign_individual = bb_vars['FIT_SIGN_INDIVIDUAL'] |
457 | fit_uboot_env = bb_vars['FIT_UBOOT_ENV'] | 510 | fit_uboot_env = bb_vars['FIT_UBOOT_ENV'] |
458 | initramfs_image = bb_vars['INITRAMFS_IMAGE'] | 511 | initramfs_image = bb_vars['INITRAMFS_IMAGE'] |
@@ -470,11 +523,11 @@ class KernelFitImageTests(FitImageTestCase): | |||
470 | if initramfs_image and initramfs_image_bundle != "1": | 523 | if initramfs_image and initramfs_image_bundle != "1": |
471 | images.append('ramdisk-1') | 524 | images.append('ramdisk-1') |
472 | 525 | ||
473 | # configuration nodes | 526 | # configuration nodes (one per DTB and also one per symlink) |
474 | if dtb_files: | 527 | if dtb_files: |
475 | configurations = [ 'conf-' + conf for conf in dtb_files ] | 528 | configurations = [bb_vars['FIT_CONF_PREFIX'] + conf for conf in dtb_files + dtb_symlinks] |
476 | else: | 529 | else: |
477 | configurations = [ 'conf-1' ] | 530 | configurations = [bb_vars['FIT_CONF_PREFIX'] + '1'] |
478 | 531 | ||
479 | # Create a list of paths for all image and configuration nodes | 532 | # Create a list of paths for all image and configuration nodes |
480 | req_its_paths = [] | 533 | req_its_paths = [] |
@@ -497,11 +550,11 @@ class KernelFitImageTests(FitImageTestCase): | |||
497 | its_field_check = [ | 550 | its_field_check = [ |
498 | 'description = "%s";' % bb_vars['FIT_DESC'], | 551 | 'description = "%s";' % bb_vars['FIT_DESC'], |
499 | 'description = "Linux kernel";', | 552 | 'description = "Linux kernel";', |
500 | 'data = /incbin/("linux.bin");', | ||
501 | 'type = "' + str(bb_vars['UBOOT_MKIMAGE_KERNEL_TYPE']) + '";', | 553 | 'type = "' + str(bb_vars['UBOOT_MKIMAGE_KERNEL_TYPE']) + '";', |
554 | # 'compression = "' + str(bb_vars['FIT_KERNEL_COMP_ALG']) + '";', defined based on files in TMPDIR, not ideal... | ||
555 | 'data = /incbin/("linux.bin");', | ||
502 | 'arch = "' + str(bb_vars['UBOOT_ARCH']) + '";', | 556 | 'arch = "' + str(bb_vars['UBOOT_ARCH']) + '";', |
503 | 'os = "linux";', | 557 | 'os = "linux";', |
504 | # 'compression = "' + str(bb_vars['FIT_KERNEL_COMP_ALG']) + '";', defined based on files in TMPDIR, not ideal... | ||
505 | 'load = <' + str(bb_vars['UBOOT_LOADADDRESS']) + '>;', | 558 | 'load = <' + str(bb_vars['UBOOT_LOADADDRESS']) + '>;', |
506 | 'entry = <' + str(bb_vars['UBOOT_ENTRYPOINT']) + '>;', | 559 | 'entry = <' + str(bb_vars['UBOOT_ENTRYPOINT']) + '>;', |
507 | ] | 560 | ] |
@@ -511,10 +564,14 @@ class KernelFitImageTests(FitImageTestCase): | |||
511 | its_field_check.append("load = <%s>;" % uboot_rd_loadaddress) | 564 | its_field_check.append("load = <%s>;" % uboot_rd_loadaddress) |
512 | if uboot_rd_entrypoint: | 565 | if uboot_rd_entrypoint: |
513 | its_field_check.append("entry = <%s>;" % uboot_rd_entrypoint) | 566 | its_field_check.append("entry = <%s>;" % uboot_rd_entrypoint) |
514 | its_field_check += [ | 567 | |
515 | # 'default = "conf-1";', needs more work | 568 | fit_conf_default_dtb = bb_vars.get('FIT_CONF_DEFAULT_DTB') |
516 | 'kernel = "kernel-1";', | 569 | if fit_conf_default_dtb: |
517 | ] | 570 | fit_conf_prefix = bb_vars.get('FIT_CONF_PREFIX', "conf-") |
571 | its_field_check.append('default = "' + fit_conf_prefix + fit_conf_default_dtb + '";') | ||
572 | |||
573 | its_field_check.append('kernel = "kernel-1";') | ||
574 | |||
518 | if initramfs_image and initramfs_image_bundle != "1": | 575 | if initramfs_image and initramfs_image_bundle != "1": |
519 | its_field_check.append('ramdisk = "ramdisk-1";') | 576 | its_field_check.append('ramdisk = "ramdisk-1";') |
520 | 577 | ||
@@ -548,7 +605,7 @@ class KernelFitImageTests(FitImageTestCase): | |||
548 | 605 | ||
549 | def _get_req_sections(self, bb_vars): | 606 | def _get_req_sections(self, bb_vars): |
550 | """Generate a dictionary of expected sections in the output of dumpimage""" | 607 | """Generate a dictionary of expected sections in the output of dumpimage""" |
551 | dtb_files = FitImageTestCase._get_dtb_files(bb_vars) | 608 | dtb_files, dtb_symlinks = FitImageTestCase._get_dtb_files(bb_vars) |
552 | fit_hash_alg = bb_vars['FIT_HASH_ALG'] | 609 | fit_hash_alg = bb_vars['FIT_HASH_ALG'] |
553 | fit_sign_alg = bb_vars['FIT_SIGN_ALG'] | 610 | fit_sign_alg = bb_vars['FIT_SIGN_ALG'] |
554 | fit_sign_individual = bb_vars['FIT_SIGN_INDIVIDUAL'] | 611 | fit_sign_individual = bb_vars['FIT_SIGN_INDIVIDUAL'] |
@@ -584,25 +641,36 @@ class KernelFitImageTests(FitImageTestCase): | |||
584 | } | 641 | } |
585 | # Create a configuration section for each DTB | 642 | # Create a configuration section for each DTB |
586 | if dtb_files: | 643 | if dtb_files: |
587 | for dtb in dtb_files: | 644 | for dtb in dtb_files + dtb_symlinks: |
588 | req_sections['conf-' + dtb] = { | 645 | conf_name = bb_vars['FIT_CONF_PREFIX'] + dtb |
589 | "Kernel": "kernel-1", | 646 | # Assume that DTBs with an "-alias" in its name are symlink DTBs created e.g. by the |
590 | "FDT": 'fdt-' + dtb, | 647 | # bbb-dtbs-as-ext test recipe. Make the configuration node pointing to the real DTB. |
591 | } | 648 | real_dtb = dtb.replace("-alias", "") |
649 | # dtb overlays do not refer to a kernel (yet?) | ||
650 | if dtb.endswith('.dtbo'): | ||
651 | req_sections[conf_name] = { | ||
652 | "FDT": 'fdt-' + real_dtb, | ||
653 | } | ||
654 | else: | ||
655 | req_sections[conf_name] = { | ||
656 | "Kernel": "kernel-1", | ||
657 | "FDT": 'fdt-' + real_dtb, | ||
658 | } | ||
592 | if initramfs_image and initramfs_image_bundle != "1": | 659 | if initramfs_image and initramfs_image_bundle != "1": |
593 | req_sections['conf-' + dtb]['Init Ramdisk'] = "ramdisk-1" | 660 | req_sections[conf_name]['Init Ramdisk'] = "ramdisk-1" |
594 | else: | 661 | else: |
595 | req_sections['conf-1'] = { | 662 | conf_name = bb_vars['FIT_CONF_PREFIX'] + '1' |
663 | req_sections[conf_name] = { | ||
596 | "Kernel": "kernel-1" | 664 | "Kernel": "kernel-1" |
597 | } | 665 | } |
598 | if initramfs_image and initramfs_image_bundle != "1": | 666 | if initramfs_image and initramfs_image_bundle != "1": |
599 | req_sections['conf-1']['Init Ramdisk'] = "ramdisk-1" | 667 | req_sections[conf_name]['Init Ramdisk'] = "ramdisk-1" |
600 | 668 | ||
601 | # Add signing related properties if needed | 669 | # Add signing related properties if needed |
602 | if uboot_sign_enable == "1": | 670 | if uboot_sign_enable == "1": |
603 | for section in req_sections: | 671 | for section in req_sections: |
604 | req_sections[section]['Hash algo'] = fit_hash_alg | 672 | req_sections[section]['Hash algo'] = fit_hash_alg |
605 | if section.startswith('conf-'): | 673 | if section.startswith(bb_vars['FIT_CONF_PREFIX']): |
606 | req_sections[section]['Hash value'] = "unavailable" | 674 | req_sections[section]['Hash value'] = "unavailable" |
607 | req_sections[section]['Sign algo'] = "%s,%s:%s" % (fit_hash_alg, fit_sign_alg, uboot_sign_keyname) | 675 | req_sections[section]['Sign algo'] = "%s,%s:%s" % (fit_hash_alg, fit_sign_alg, uboot_sign_keyname) |
608 | num_signatures += 1 | 676 | num_signatures += 1 |
@@ -624,18 +692,26 @@ class KernelFitImageTests(FitImageTestCase): | |||
624 | uboot_sign_keyname = bb_vars['UBOOT_SIGN_KEYNAME'] | 692 | uboot_sign_keyname = bb_vars['UBOOT_SIGN_KEYNAME'] |
625 | uboot_sign_img_keyname = bb_vars['UBOOT_SIGN_IMG_KEYNAME'] | 693 | uboot_sign_img_keyname = bb_vars['UBOOT_SIGN_IMG_KEYNAME'] |
626 | deploy_dir_image = bb_vars['DEPLOY_DIR_IMAGE'] | 694 | deploy_dir_image = bb_vars['DEPLOY_DIR_IMAGE'] |
695 | kernel_deploysubdir = bb_vars['KERNEL_DEPLOYSUBDIR'] | ||
627 | fit_sign_individual = bb_vars['FIT_SIGN_INDIVIDUAL'] | 696 | fit_sign_individual = bb_vars['FIT_SIGN_INDIVIDUAL'] |
628 | fit_hash_alg_len = FitImageTestCase.MKIMAGE_HASH_LENGTHS[fit_hash_alg] | 697 | fit_hash_alg_len = FitImageTestCase.MKIMAGE_HASH_LENGTHS[fit_hash_alg] |
629 | fit_sign_alg_len = FitImageTestCase.MKIMAGE_SIGNATURE_LENGTHS[fit_sign_alg] | 698 | fit_sign_alg_len = FitImageTestCase.MKIMAGE_SIGNATURE_LENGTHS[fit_sign_alg] |
630 | for section, values in sections.items(): | 699 | for section, values in sections.items(): |
631 | # Configuration nodes are always signed with UBOOT_SIGN_KEYNAME (if UBOOT_SIGN_ENABLE = "1") | 700 | # Configuration nodes are always signed with UBOOT_SIGN_KEYNAME (if UBOOT_SIGN_ENABLE = "1") |
632 | if section.startswith("conf"): | 701 | if section.startswith(bb_vars['FIT_CONF_PREFIX']): |
633 | sign_algo = values.get('Sign algo', None) | 702 | sign_algo = values.get('Sign algo', None) |
634 | req_sign_algo = "%s,%s:%s" % (fit_hash_alg, fit_sign_alg, uboot_sign_keyname) | 703 | req_sign_algo = "%s,%s:%s" % (fit_hash_alg, fit_sign_alg, uboot_sign_keyname) |
635 | self.assertEqual(sign_algo, req_sign_algo, 'Signature algorithm for %s not expected value' % section) | 704 | self.assertEqual(sign_algo, req_sign_algo, 'Signature algorithm for %s not expected value' % section) |
636 | sign_value = values.get('Sign value', None) | 705 | sign_value = values.get('Sign value', None) |
637 | self.assertEqual(len(sign_value), fit_sign_alg_len, 'Signature value for section %s not expected length' % section) | 706 | self.assertEqual(len(sign_value), fit_sign_alg_len, 'Signature value for section %s not expected length' % section) |
638 | dtb_path = os.path.join(deploy_dir_image, section.replace('conf-', '')) | 707 | dtb_file_name = section.replace(bb_vars['FIT_CONF_PREFIX'], '') |
708 | dtb_path = os.path.join(deploy_dir_image, dtb_file_name) | ||
709 | if kernel_deploysubdir: | ||
710 | dtb_path = os.path.join(deploy_dir_image, kernel_deploysubdir, dtb_file_name) | ||
711 | # External devicetrees created by devicetree.bbclass are in a subfolder and have priority | ||
712 | dtb_path_ext = os.path.join(deploy_dir_image, "devicetree", dtb_file_name) | ||
713 | if os.path.exists(dtb_path_ext): | ||
714 | dtb_path = dtb_path_ext | ||
639 | self._verify_fit_image_signature(uboot_tools_bindir, fitimage_path, dtb_path, section) | 715 | self._verify_fit_image_signature(uboot_tools_bindir, fitimage_path, dtb_path, section) |
640 | else: | 716 | else: |
641 | # Image nodes always need a hash which gets indirectly signed by the config signature | 717 | # Image nodes always need a hash which gets indirectly signed by the config signature |
@@ -660,6 +736,8 @@ class KernelFitImageTests(FitImageTestCase): | |||
660 | self.assertEqual(found_comments, num_signatures, "Expected %d signed and commented (%s) sections in the fitImage." % | 736 | self.assertEqual(found_comments, num_signatures, "Expected %d signed and commented (%s) sections in the fitImage." % |
661 | (num_signatures, a_comment)) | 737 | (num_signatures, a_comment)) |
662 | 738 | ||
739 | class KernelFitImageRecipeTests(KernelFitImageBase): | ||
740 | """Test cases for the kernel-fitimage bbclass""" | ||
663 | 741 | ||
664 | def test_fit_image(self): | 742 | def test_fit_image(self): |
665 | """ | 743 | """ |
@@ -675,10 +753,7 @@ class KernelFitImageTests(FitImageTestCase): | |||
675 | Author: Usama Arif <usama.arif@arm.com> | 753 | Author: Usama Arif <usama.arif@arm.com> |
676 | """ | 754 | """ |
677 | config = """ | 755 | config = """ |
678 | # Enable creation of fitImage | ||
679 | KERNEL_IMAGETYPE = "Image" | 756 | KERNEL_IMAGETYPE = "Image" |
680 | KERNEL_IMAGETYPES += " fitImage " | ||
681 | KERNEL_CLASSES = " kernel-fitimage " | ||
682 | 757 | ||
683 | # RAM disk variables including load address and entrypoint for kernel and RAM disk | 758 | # RAM disk variables including load address and entrypoint for kernel and RAM disk |
684 | IMAGE_FSTYPES += "cpio.gz" | 759 | IMAGE_FSTYPES += "cpio.gz" |
@@ -690,8 +765,76 @@ UBOOT_RD_ENTRYPOINT = "0x88000000" | |||
690 | UBOOT_LOADADDRESS = "0x80080000" | 765 | UBOOT_LOADADDRESS = "0x80080000" |
691 | UBOOT_ENTRYPOINT = "0x80080000" | 766 | UBOOT_ENTRYPOINT = "0x80080000" |
692 | FIT_DESC = "A model description" | 767 | FIT_DESC = "A model description" |
768 | FIT_CONF_PREFIX = "foo-" | ||
769 | """ | ||
770 | config = self._config_add_kernel_classes(config) | ||
771 | self.write_config(config) | ||
772 | bb_vars = self._fit_get_bb_vars() | ||
773 | self._test_fitimage(bb_vars) | ||
774 | |||
775 | def test_get_compatible_from_dtb(self): | ||
776 | """Test the oe.fitimage.get_compatible_from_dtb function | ||
777 | |||
778 | 1. bitbake bbb-dtbs-as-ext | ||
779 | 2. Check if symlink_points_below returns the path to the DTB | ||
780 | 3. Check if the expected compatible string is found by get_compatible_from_dtb() | ||
781 | """ | ||
782 | DTB_RECIPE = "bbb-dtbs-as-ext" | ||
783 | DTB_FILE = "am335x-bonegreen-ext.dtb" | ||
784 | DTB_SYMLINK = "am335x-bonegreen-ext-alias.dtb" | ||
785 | DTBO_FILE = "BBORG_RELAY-00A2.dtbo" | ||
786 | EXPECTED_COMP = ["ti,am335x-bone-green", "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx"] | ||
787 | |||
788 | config = """ | ||
789 | DISTRO = "poky" | ||
790 | MACHINE = "beaglebone-yocto" | ||
693 | """ | 791 | """ |
694 | self.write_config(config) | 792 | self.write_config(config) |
793 | |||
794 | # Provide the fdtget command called by get_compatible_from_dtb | ||
795 | dtc_bindir = FitImageTestCase._setup_native('dtc-native') | ||
796 | fdtget_path = os.path.join(dtc_bindir, "fdtget") | ||
797 | self.assertExists(fdtget_path) | ||
798 | |||
799 | # bitbake an external DTB with a symlink to it and a DTB overlay | ||
800 | bitbake(DTB_RECIPE) | ||
801 | deploy_dir_image = get_bb_var("DEPLOY_DIR_IMAGE", DTB_RECIPE) | ||
802 | devicetree_dir = os.path.join(deploy_dir_image, "devicetree") | ||
803 | dtb_path = os.path.join(devicetree_dir, DTB_FILE) | ||
804 | dtb_alias_path = os.path.join(devicetree_dir, DTB_SYMLINK) | ||
805 | dtbo_file = os.path.join(devicetree_dir, DTBO_FILE) | ||
806 | self.assertExists(dtb_path) | ||
807 | self.assertExists(dtb_alias_path) | ||
808 | self.assertExists(dtbo_file) | ||
809 | |||
810 | # Test symlink_points_below | ||
811 | linked_dtb = oe.fitimage.symlink_points_below(dtb_alias_path, devicetree_dir) | ||
812 | self.assertEqual(linked_dtb, DTB_FILE) | ||
813 | |||
814 | # Check if get_compatible_from_dtb finds the expected compatible string in the DTBs | ||
815 | comp = oe.fitimage.get_compatible_from_dtb(dtb_path, fdtget_path) | ||
816 | self.assertEqual(comp, EXPECTED_COMP) | ||
817 | comp_alias = oe.fitimage.get_compatible_from_dtb(dtb_alias_path, fdtget_path) | ||
818 | self.assertEqual(comp_alias, EXPECTED_COMP) | ||
819 | # The alias is a symlink, therefore the compatible string is equal | ||
820 | self.assertEqual(comp_alias, comp) | ||
821 | |||
822 | def test_fit_image_ext_dtb_dtbo(self): | ||
823 | """ | ||
824 | Summary: Check if FIT image and Image Tree Source (its) are created correctly. | ||
825 | Expected: 1) its and FIT image are built successfully | ||
826 | 2) The its file contains also the external devicetree overlay | ||
827 | 3) Dumping the FIT image indicates the devicetree overlay | ||
828 | """ | ||
829 | config = """ | ||
830 | # Enable creation of fitImage | ||
831 | MACHINE = "beaglebone-yocto" | ||
832 | # Add a devicetree overlay which does not need kernel sources | ||
833 | PREFERRED_PROVIDER_virtual/dtb = "bbb-dtbs-as-ext" | ||
834 | """ | ||
835 | config = self._config_add_kernel_classes(config) | ||
836 | config = self._config_add_uboot_env(config) | ||
837 | self.write_config(config) | ||
695 | bb_vars = self._fit_get_bb_vars() | 838 | bb_vars = self._fit_get_bb_vars() |
696 | self._test_fitimage(bb_vars) | 839 | self._test_fitimage(bb_vars) |
697 | 840 | ||
@@ -702,8 +845,7 @@ FIT_DESC = "A model description" | |||
702 | and the configuration nodes are signed correctly. | 845 | and the configuration nodes are signed correctly. |
703 | Expected: 1) its and FIT image are built successfully | 846 | Expected: 1) its and FIT image are built successfully |
704 | 2) Scanning the its file indicates signing is enabled | 847 | 2) Scanning the its file indicates signing is enabled |
705 | as requested by UBOOT_SIGN_ENABLE (using 1 key | 848 | as requested by UBOOT_SIGN_ENABLE |
706 | generated by the test not via FIT_GENERATE_KEYS) | ||
707 | 3) Dumping the FIT image indicates signature values | 849 | 3) Dumping the FIT image indicates signature values |
708 | are present (only for the configuration nodes as | 850 | are present (only for the configuration nodes as |
709 | FIT_SIGN_INDIVIDUAL is disabled) | 851 | FIT_SIGN_INDIVIDUAL is disabled) |
@@ -714,13 +856,13 @@ FIT_DESC = "A model description" | |||
714 | config = """ | 856 | config = """ |
715 | # Enable creation of fitImage | 857 | # Enable creation of fitImage |
716 | MACHINE = "beaglebone-yocto" | 858 | MACHINE = "beaglebone-yocto" |
717 | KERNEL_IMAGETYPES += " fitImage " | ||
718 | KERNEL_CLASSES = " kernel-fitimage " | ||
719 | UBOOT_SIGN_ENABLE = "1" | 859 | UBOOT_SIGN_ENABLE = "1" |
720 | UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys" | 860 | UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys" |
721 | UBOOT_SIGN_KEYNAME = "dev" | 861 | UBOOT_SIGN_KEYNAME = "dev" |
722 | UBOOT_MKIMAGE_SIGN_ARGS = "-c 'a smart comment'" | 862 | UBOOT_MKIMAGE_SIGN_ARGS = "-c 'a smart comment'" |
863 | FIT_CONF_DEFAULT_DTB = "am335x-bonegreen.dtb" | ||
723 | """ | 864 | """ |
865 | config = self._config_add_kernel_classes(config) | ||
724 | config = self._config_add_uboot_env(config) | 866 | config = self._config_add_uboot_env(config) |
725 | self.write_config(config) | 867 | self.write_config(config) |
726 | 868 | ||
@@ -733,10 +875,7 @@ UBOOT_MKIMAGE_SIGN_ARGS = "-c 'a smart comment'" | |||
733 | 'UBOOT_SIGN_KEYDIR', | 875 | 'UBOOT_SIGN_KEYDIR', |
734 | ]) | 876 | ]) |
735 | 877 | ||
736 | # Do not use the random keys generated by FIT_GENERATE_KEYS. | ||
737 | # Using a static key is probably a more realistic scenario. | ||
738 | self._gen_signing_key(bb_vars) | 878 | self._gen_signing_key(bb_vars) |
739 | |||
740 | self._test_fitimage(bb_vars) | 879 | self._test_fitimage(bb_vars) |
741 | 880 | ||
742 | def test_sign_fit_image_individual(self): | 881 | def test_sign_fit_image_individual(self): |
@@ -745,11 +884,11 @@ UBOOT_MKIMAGE_SIGN_ARGS = "-c 'a smart comment'" | |||
745 | and all nodes are signed correctly. | 884 | and all nodes are signed correctly. |
746 | Expected: 1) its and FIT image are built successfully | 885 | Expected: 1) its and FIT image are built successfully |
747 | 2) Scanning the its file indicates signing is enabled | 886 | 2) Scanning the its file indicates signing is enabled |
748 | as requested by UBOOT_SIGN_ENABLE (using 2 keys | 887 | as requested by UBOOT_SIGN_ENABLE |
749 | generated via FIT_GENERATE_KEYS) | ||
750 | 3) Dumping the FIT image indicates signature values | 888 | 3) Dumping the FIT image indicates signature values |
751 | are present (including for images as enabled via | 889 | are present (including for images as enabled via |
752 | FIT_SIGN_INDIVIDUAL) | 890 | FIT_SIGN_INDIVIDUAL) |
891 | This also implies that FIT_GENERATE_KEYS = "1" works. | ||
753 | 4) Verify the FIT image contains the comments passed via | 892 | 4) Verify the FIT image contains the comments passed via |
754 | UBOOT_MKIMAGE_SIGN_ARGS once per image and per | 893 | UBOOT_MKIMAGE_SIGN_ARGS once per image and per |
755 | configuration node. | 894 | configuration node. |
@@ -765,8 +904,6 @@ UBOOT_MKIMAGE_SIGN_ARGS = "-c 'a smart comment'" | |||
765 | config = """ | 904 | config = """ |
766 | # Enable creation of fitImage | 905 | # Enable creation of fitImage |
767 | MACHINE = "beaglebone-yocto" | 906 | MACHINE = "beaglebone-yocto" |
768 | KERNEL_IMAGETYPES += " fitImage " | ||
769 | KERNEL_CLASSES = " kernel-fitimage " | ||
770 | UBOOT_SIGN_ENABLE = "1" | 907 | UBOOT_SIGN_ENABLE = "1" |
771 | FIT_GENERATE_KEYS = "1" | 908 | FIT_GENERATE_KEYS = "1" |
772 | UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys" | 909 | UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys" |
@@ -775,9 +912,14 @@ UBOOT_SIGN_KEYNAME = "cfg-oe-selftest" | |||
775 | FIT_SIGN_INDIVIDUAL = "1" | 912 | FIT_SIGN_INDIVIDUAL = "1" |
776 | UBOOT_MKIMAGE_SIGN_ARGS = "-c 'a smart comment'" | 913 | UBOOT_MKIMAGE_SIGN_ARGS = "-c 'a smart comment'" |
777 | """ | 914 | """ |
915 | config = self._config_add_kernel_classes(config) | ||
778 | config = self._config_add_uboot_env(config) | 916 | config = self._config_add_uboot_env(config) |
779 | self.write_config(config) | 917 | self.write_config(config) |
780 | bb_vars = self._fit_get_bb_vars() | 918 | bb_vars = self._fit_get_bb_vars() |
919 | |||
920 | # Ensure new keys are generated and FIT_GENERATE_KEYS = "1" is tested | ||
921 | bitbake("kernel-signing-keys-native -c compile -f") | ||
922 | |||
781 | self._test_fitimage(bb_vars) | 923 | self._test_fitimage(bb_vars) |
782 | 924 | ||
783 | def test_fit_image_sign_initramfs(self): | 925 | def test_fit_image_sign_initramfs(self): |
@@ -796,13 +938,11 @@ UBOOT_MKIMAGE_SIGN_ARGS = "-c 'a smart comment'" | |||
796 | """ | 938 | """ |
797 | 939 | ||
798 | config = """ | 940 | config = """ |
799 | DISTRO="poky" | 941 | DISTRO = "poky" |
800 | MACHINE = "beaglebone-yocto" | 942 | MACHINE = "beaglebone-yocto" |
801 | INITRAMFS_IMAGE = "core-image-minimal-initramfs" | 943 | INITRAMFS_IMAGE = "core-image-minimal-initramfs" |
802 | INITRAMFS_SCRIPTS = "" | 944 | INITRAMFS_SCRIPTS = "" |
803 | UBOOT_MACHINE = "am335x_evm_defconfig" | 945 | UBOOT_MACHINE = "am335x_evm_defconfig" |
804 | KERNEL_CLASSES = " kernel-fitimage " | ||
805 | KERNEL_IMAGETYPES = "fitImage" | ||
806 | UBOOT_SIGN_ENABLE = "1" | 946 | UBOOT_SIGN_ENABLE = "1" |
807 | UBOOT_SIGN_KEYNAME = "beaglebonekey" | 947 | UBOOT_SIGN_KEYNAME = "beaglebonekey" |
808 | UBOOT_SIGN_KEYDIR ?= "${DEPLOY_DIR_IMAGE}" | 948 | UBOOT_SIGN_KEYDIR ?= "${DEPLOY_DIR_IMAGE}" |
@@ -816,11 +956,11 @@ UBOOT_ARCH = "arm" | |||
816 | UBOOT_MKIMAGE_DTCOPTS = "-I dts -O dtb -p 2000" | 956 | UBOOT_MKIMAGE_DTCOPTS = "-I dts -O dtb -p 2000" |
817 | UBOOT_MKIMAGE_KERNEL_TYPE = "kernel" | 957 | UBOOT_MKIMAGE_KERNEL_TYPE = "kernel" |
818 | UBOOT_EXTLINUX = "0" | 958 | UBOOT_EXTLINUX = "0" |
819 | FIT_GENERATE_KEYS = "1" | ||
820 | KERNEL_IMAGETYPE_REPLACEMENT = "zImage" | 959 | KERNEL_IMAGETYPE_REPLACEMENT = "zImage" |
821 | FIT_KERNEL_COMP_ALG = "none" | 960 | FIT_KERNEL_COMP_ALG = "none" |
822 | FIT_HASH_ALG = "sha256" | 961 | FIT_HASH_ALG = "sha256" |
823 | """ | 962 | """ |
963 | config = self._config_add_kernel_classes(config) | ||
824 | config = self._config_add_uboot_env(config) | 964 | config = self._config_add_uboot_env(config) |
825 | self.write_config(config) | 965 | self.write_config(config) |
826 | 966 | ||
@@ -833,10 +973,7 @@ FIT_HASH_ALG = "sha256" | |||
833 | 'UBOOT_SIGN_KEYDIR', | 973 | 'UBOOT_SIGN_KEYDIR', |
834 | ]) | 974 | ]) |
835 | 975 | ||
836 | # Do not use the random keys generated by FIT_GENERATE_KEYS. | ||
837 | # Using a static key is probably a more realistic scenario. | ||
838 | self._gen_signing_key(bb_vars) | 976 | self._gen_signing_key(bb_vars) |
839 | |||
840 | self._test_fitimage(bb_vars) | 977 | self._test_fitimage(bb_vars) |
841 | 978 | ||
842 | def test_fit_image_sign_initramfs_bundle(self): | 979 | def test_fit_image_sign_initramfs_bundle(self): |
@@ -855,14 +992,12 @@ FIT_HASH_ALG = "sha256" | |||
855 | """ | 992 | """ |
856 | 993 | ||
857 | config = """ | 994 | config = """ |
858 | DISTRO="poky" | 995 | DISTRO = "poky" |
859 | MACHINE = "beaglebone-yocto" | 996 | MACHINE = "beaglebone-yocto" |
860 | INITRAMFS_IMAGE_BUNDLE = "1" | 997 | INITRAMFS_IMAGE_BUNDLE = "1" |
861 | INITRAMFS_IMAGE = "core-image-minimal-initramfs" | 998 | INITRAMFS_IMAGE = "core-image-minimal-initramfs" |
862 | INITRAMFS_SCRIPTS = "" | 999 | INITRAMFS_SCRIPTS = "" |
863 | UBOOT_MACHINE = "am335x_evm_defconfig" | 1000 | UBOOT_MACHINE = "am335x_evm_defconfig" |
864 | KERNEL_CLASSES = " kernel-fitimage " | ||
865 | KERNEL_IMAGETYPES = "fitImage" | ||
866 | UBOOT_SIGN_ENABLE = "1" | 1001 | UBOOT_SIGN_ENABLE = "1" |
867 | UBOOT_SIGN_KEYNAME = "beaglebonekey" | 1002 | UBOOT_SIGN_KEYNAME = "beaglebonekey" |
868 | UBOOT_SIGN_KEYDIR ?= "${DEPLOY_DIR_IMAGE}" | 1003 | UBOOT_SIGN_KEYDIR ?= "${DEPLOY_DIR_IMAGE}" |
@@ -874,20 +1009,124 @@ UBOOT_ARCH = "arm" | |||
874 | UBOOT_MKIMAGE_DTCOPTS = "-I dts -O dtb -p 2000" | 1009 | UBOOT_MKIMAGE_DTCOPTS = "-I dts -O dtb -p 2000" |
875 | UBOOT_MKIMAGE_KERNEL_TYPE = "kernel" | 1010 | UBOOT_MKIMAGE_KERNEL_TYPE = "kernel" |
876 | UBOOT_EXTLINUX = "0" | 1011 | UBOOT_EXTLINUX = "0" |
877 | FIT_GENERATE_KEYS = "1" | ||
878 | KERNEL_IMAGETYPE_REPLACEMENT = "zImage" | 1012 | KERNEL_IMAGETYPE_REPLACEMENT = "zImage" |
879 | FIT_KERNEL_COMP_ALG = "none" | 1013 | FIT_KERNEL_COMP_ALG = "none" |
880 | FIT_HASH_ALG = "sha256" | 1014 | FIT_HASH_ALG = "sha256" |
881 | """ | 1015 | """ |
1016 | config = self._config_add_kernel_classes(config) | ||
882 | config = self._config_add_uboot_env(config) | 1017 | config = self._config_add_uboot_env(config) |
883 | self.write_config(config) | 1018 | self.write_config(config) |
884 | bb_vars = self._fit_get_bb_vars() | 1019 | bb_vars = self._fit_get_bb_vars() |
1020 | self._gen_signing_key(bb_vars) | ||
885 | self._test_fitimage(bb_vars) | 1021 | self._test_fitimage(bb_vars) |
886 | 1022 | ||
1023 | class FitImagePyTests(KernelFitImageBase): | ||
1024 | """Test cases for the fitimage.py module without calling bitbake""" | ||
1025 | |||
1026 | def _test_fitimage_py(self, bb_vars_overrides=None): | ||
1027 | topdir = os.path.join(os.environ['BUILDDIR']) | ||
1028 | fitimage_its_path = os.path.join(topdir, self._testMethodName + '.its') | ||
1029 | |||
1030 | # Provide variables without calling bitbake | ||
1031 | bb_vars = { | ||
1032 | # image-fitimage.conf | ||
1033 | 'FIT_DESC': "Kernel fitImage for a dummy distro", | ||
1034 | 'FIT_HASH_ALG': "sha256", | ||
1035 | 'FIT_SIGN_ALG': "rsa2048", | ||
1036 | 'FIT_PAD_ALG': "pkcs-1.5", | ||
1037 | 'FIT_GENERATE_KEYS': "0", | ||
1038 | 'FIT_SIGN_NUMBITS': "2048", | ||
1039 | 'FIT_KEY_GENRSA_ARGS': "-F4", | ||
1040 | 'FIT_KEY_REQ_ARGS': "-batch -new", | ||
1041 | 'FIT_KEY_SIGN_PKCS': "-x509", | ||
1042 | 'FIT_SIGN_INDIVIDUAL': "0", | ||
1043 | 'FIT_CONF_PREFIX': "conf-", | ||
1044 | 'FIT_SUPPORTED_INITRAMFS_FSTYPES': "cpio.lz4 cpio.lzo cpio.lzma cpio.xz cpio.zst cpio.gz ext2.gz cpio", | ||
1045 | 'FIT_CONF_DEFAULT_DTB': "", | ||
1046 | 'FIT_ADDRESS_CELLS': "1", | ||
1047 | 'FIT_UBOOT_ENV': "", | ||
1048 | # kernel.bbclass | ||
1049 | 'UBOOT_ENTRYPOINT': "0x20008000", | ||
1050 | 'UBOOT_LOADADDRESS': "0x20008000", | ||
1051 | 'INITRAMFS_IMAGE': "", | ||
1052 | 'INITRAMFS_IMAGE_BUNDLE': "", | ||
1053 | # kernel-uboot.bbclass | ||
1054 | 'FIT_KERNEL_COMP_ALG': "gzip", | ||
1055 | 'FIT_KERNEL_COMP_ALG_EXTENSION': ".gz", | ||
1056 | 'UBOOT_MKIMAGE_KERNEL_TYPE': "kernel", | ||
1057 | # uboot-config.bbclass | ||
1058 | 'UBOOT_MKIMAGE_DTCOPTS': "", | ||
1059 | 'UBOOT_MKIMAGE': "uboot-mkimage", | ||
1060 | 'UBOOT_MKIMAGE_SIGN': "uboot-mkimage", | ||
1061 | 'UBOOT_MKIMAGE_SIGN_ARGS': "", | ||
1062 | 'UBOOT_SIGN_ENABLE': "0", | ||
1063 | 'UBOOT_SIGN_KEYDIR': None, | ||
1064 | 'UBOOT_SIGN_KEYNAME': None, | ||
1065 | 'UBOOT_SIGN_IMG_KEYNAME': None, | ||
1066 | # others | ||
1067 | 'MACHINE': "qemux86-64", | ||
1068 | 'UBOOT_ARCH': "x86", | ||
1069 | 'HOST_PREFIX': "x86_64-poky-linux-" | ||
1070 | } | ||
1071 | if bb_vars_overrides: | ||
1072 | bb_vars.update(bb_vars_overrides) | ||
1073 | |||
1074 | root_node = oe.fitimage.ItsNodeRootKernel( | ||
1075 | bb_vars["FIT_DESC"], bb_vars["FIT_ADDRESS_CELLS"], | ||
1076 | bb_vars['HOST_PREFIX'], bb_vars['UBOOT_ARCH'], bb_vars["FIT_CONF_PREFIX"], | ||
1077 | oe.types.boolean(bb_vars['UBOOT_SIGN_ENABLE']), bb_vars["UBOOT_SIGN_KEYDIR"], | ||
1078 | bb_vars["UBOOT_MKIMAGE"], bb_vars["UBOOT_MKIMAGE_DTCOPTS"], | ||
1079 | bb_vars["UBOOT_MKIMAGE_SIGN"], bb_vars["UBOOT_MKIMAGE_SIGN_ARGS"], | ||
1080 | bb_vars['FIT_HASH_ALG'], bb_vars['FIT_SIGN_ALG'], bb_vars['FIT_PAD_ALG'], | ||
1081 | bb_vars['UBOOT_SIGN_KEYNAME'], | ||
1082 | oe.types.boolean(bb_vars['FIT_SIGN_INDIVIDUAL']), bb_vars['UBOOT_SIGN_IMG_KEYNAME'] | ||
1083 | ) | ||
1084 | |||
1085 | root_node.fitimage_emit_section_kernel("kernel-1", "linux.bin", "none", | ||
1086 | bb_vars.get('UBOOT_LOADADDRESS'), bb_vars.get('UBOOT_ENTRYPOINT'), | ||
1087 | bb_vars.get('UBOOT_MKIMAGE_KERNEL_TYPE'), bb_vars.get("UBOOT_ENTRYSYMBOL") | ||
1088 | ) | ||
1089 | |||
1090 | dtb_files, _ = FitImageTestCase._get_dtb_files(bb_vars) | ||
1091 | for dtb in dtb_files: | ||
1092 | root_node.fitimage_emit_section_dtb(dtb, os.path.join("a-dir", dtb), | ||
1093 | bb_vars.get("UBOOT_DTB_LOADADDRESS"), bb_vars.get("UBOOT_DTBO_LOADADDRESS")) | ||
1094 | |||
1095 | if bb_vars.get('FIT_UBOOT_ENV'): | ||
1096 | root_node.fitimage_emit_section_boot_script( | ||
1097 | "bootscr-" + bb_vars['FIT_UBOOT_ENV'], bb_vars['FIT_UBOOT_ENV']) | ||
1098 | |||
1099 | if bb_vars['MACHINE'] == "qemux86-64": # Not really the right if | ||
1100 | root_node.fitimage_emit_section_setup("setup-1", "setup1.bin") | ||
1101 | |||
1102 | if bb_vars.get('INITRAMFS_IMAGE') and bb_vars.get("INITRAMFS_IMAGE_BUNDLE") != "1": | ||
1103 | root_node.fitimage_emit_section_ramdisk("ramdisk-1", "a-dir/a-initramfs-1", | ||
1104 | "core-image-minimal-initramfs", | ||
1105 | bb_vars.get("UBOOT_RD_LOADADDRESS"), bb_vars.get("UBOOT_RD_ENTRYPOINT")) | ||
1106 | |||
1107 | root_node.fitimage_emit_section_config(bb_vars['FIT_CONF_DEFAULT_DTB']) | ||
1108 | root_node.write_its_file(fitimage_its_path) | ||
1109 | |||
1110 | self.assertExists(fitimage_its_path, "%s image tree source doesn't exist" % (fitimage_its_path)) | ||
1111 | self.logger.debug("Checking its: %s" % fitimage_its_path) | ||
1112 | self._check_its_file(bb_vars, fitimage_its_path) | ||
1113 | |||
1114 | def test_fitimage_py_default(self): | ||
1115 | self._test_fitimage_py() | ||
1116 | |||
1117 | def test_fitimage_py_default_dtb(self): | ||
1118 | bb_vars_overrides = { | ||
1119 | 'KERNEL_DEVICETREE': "one.dtb two.dtb three.dtb", | ||
1120 | 'FIT_CONF_DEFAULT_DTB': "two.dtb" | ||
1121 | } | ||
1122 | self._test_fitimage_py(bb_vars_overrides) | ||
1123 | |||
887 | 1124 | ||
888 | class UBootFitImageTests(FitImageTestCase): | 1125 | class UBootFitImageTests(FitImageTestCase): |
889 | """Test cases for the uboot-sign bbclass""" | 1126 | """Test cases for the uboot-sign bbclass""" |
890 | 1127 | ||
1128 | BOOTLOADER_RECIPE = "virtual/bootloader" | ||
1129 | |||
891 | def _fit_get_bb_vars(self, additional_vars=[]): | 1130 | def _fit_get_bb_vars(self, additional_vars=[]): |
892 | """Get bb_vars as needed by _test_sign_fit_image | 1131 | """Get bb_vars as needed by _test_sign_fit_image |
893 | 1132 | ||
@@ -929,13 +1168,13 @@ class UBootFitImageTests(FitImageTestCase): | |||
929 | 'UBOOT_SIGN_KEYDIR', | 1168 | 'UBOOT_SIGN_KEYDIR', |
930 | 'UBOOT_SIGN_KEYNAME', | 1169 | 'UBOOT_SIGN_KEYNAME', |
931 | } | 1170 | } |
932 | bb_vars = get_bb_vars(list(internal_used | set(additional_vars)), "virtual/bootloader") | 1171 | bb_vars = get_bb_vars(list(internal_used | set(additional_vars)), UBootFitImageTests.BOOTLOADER_RECIPE) |
933 | self.logger.debug("bb_vars: %s" % pprint.pformat(bb_vars, indent=4)) | 1172 | self.logger.debug("bb_vars: %s" % pprint.pformat(bb_vars, indent=4)) |
934 | return bb_vars | 1173 | return bb_vars |
935 | 1174 | ||
936 | def _bitbake_fit_image(self, bb_vars): | 1175 | def _bitbake_fit_image(self, bb_vars): |
937 | """Bitbake the bootloader and return the paths to the its file and the FIT image""" | 1176 | """Bitbake the bootloader and return the paths to the its file and the FIT image""" |
938 | bitbake("virtual/bootloader") | 1177 | bitbake(UBootFitImageTests.BOOTLOADER_RECIPE) |
939 | 1178 | ||
940 | deploy_dir_image = bb_vars['DEPLOY_DIR_IMAGE'] | 1179 | deploy_dir_image = bb_vars['DEPLOY_DIR_IMAGE'] |
941 | machine = bb_vars['MACHINE'] | 1180 | machine = bb_vars['MACHINE'] |
@@ -1286,9 +1525,7 @@ UBOOT_SIGN_KEYNAME = "cfg-oe-selftest" | |||
1286 | self.write_config(config) | 1525 | self.write_config(config) |
1287 | bb_vars = self._fit_get_bb_vars() | 1526 | bb_vars = self._fit_get_bb_vars() |
1288 | 1527 | ||
1289 | # Using a static key. FIT_GENERATE_KEYS = "1" does not work without kernel-fitimage.bbclass | ||
1290 | self._gen_signing_key(bb_vars) | 1528 | self._gen_signing_key(bb_vars) |
1291 | |||
1292 | self._test_fitimage(bb_vars) | 1529 | self._test_fitimage(bb_vars) |
1293 | self._check_kernel_dtb(bb_vars) | 1530 | self._check_kernel_dtb(bb_vars) |
1294 | 1531 | ||
@@ -1449,11 +1686,46 @@ FIT_SIGN_INDIVIDUAL = "1" | |||
1449 | """ | 1686 | """ |
1450 | self.write_config(config) | 1687 | self.write_config(config) |
1451 | bb_vars = self._fit_get_bb_vars() | 1688 | bb_vars = self._fit_get_bb_vars() |
1452 | |||
1453 | # Using a static key. FIT_GENERATE_KEYS = "1" does not work without kernel-fitimage.bbclass | ||
1454 | self._gen_signing_key(bb_vars) | 1689 | self._gen_signing_key(bb_vars) |
1455 | 1690 | ||
1456 | bitbake("virtual/bootloader") | 1691 | bitbake(UBootFitImageTests.BOOTLOADER_RECIPE) |
1457 | 1692 | ||
1458 | # Just check the DTB of u-boot since there is no u-boot FIT image | 1693 | # Just check the DTB of u-boot since there is no u-boot FIT image |
1459 | self._check_kernel_dtb(bb_vars) | 1694 | self._check_kernel_dtb(bb_vars) |
1695 | |||
1696 | |||
1697 | def test_sign_uboot_fit_image_without_spl(self): | ||
1698 | """ | ||
1699 | Summary: Check if U-Boot FIT image and Image Tree Source (its) are | ||
1700 | created and signed correctly for the scenario where only | ||
1701 | the U-Boot proper fitImage is being created and signed | ||
1702 | (no SPL included). | ||
1703 | Expected: 1) U-Boot its and FIT image are built successfully | ||
1704 | 2) Scanning the its file indicates signing is enabled | ||
1705 | as requested by SPL_SIGN_ENABLE (using keys generated | ||
1706 | via UBOOT_FIT_GENERATE_KEYS) | ||
1707 | 3) Dumping the FIT image indicates signature values | ||
1708 | are present | ||
1709 | 4) Examination of the do_uboot_assemble_fitimage | ||
1710 | runfile/logfile indicate that UBOOT_MKIMAGE and | ||
1711 | UBOOT_MKIMAGE_SIGN are working as expected. | ||
1712 | Product: oe-core | ||
1713 | Author: Jamin Lin <jamin_lin@aspeedtech.com> | ||
1714 | """ | ||
1715 | config = """ | ||
1716 | # There's no U-boot defconfig with CONFIG_FIT_SIGNATURE yet, so we need at | ||
1717 | # least CONFIG_SPL_LOAD_FIT and CONFIG_SPL_OF_CONTROL set | ||
1718 | MACHINE = "qemuarm" | ||
1719 | UBOOT_MACHINE = "am57xx_evm_defconfig" | ||
1720 | # Enable creation and signing of the U-Boot fitImage (no SPL) | ||
1721 | UBOOT_FITIMAGE_ENABLE = "1" | ||
1722 | SPL_DTB_BINARY = "" | ||
1723 | SPL_SIGN_ENABLE = "1" | ||
1724 | SPL_SIGN_KEYNAME = "spl-oe-selftest" | ||
1725 | SPL_SIGN_KEYDIR = "${TOPDIR}/signing-keys" | ||
1726 | UBOOT_FIT_GENERATE_KEYS = "1" | ||
1727 | """ | ||
1728 | self.write_config(config) | ||
1729 | bb_vars = self._fit_get_bb_vars() | ||
1730 | self._test_fitimage(bb_vars) | ||
1731 | |||
diff --git a/meta/lib/oeqa/selftest/cases/liboe.py b/meta/lib/oeqa/selftest/cases/liboe.py index d5ffffdcb4..930354c931 100644 --- a/meta/lib/oeqa/selftest/cases/liboe.py +++ b/meta/lib/oeqa/selftest/cases/liboe.py | |||
@@ -9,11 +9,11 @@ from oeqa.utils.commands import get_bb_var, get_bb_vars, bitbake, runCmd | |||
9 | import oe.path | 9 | import oe.path |
10 | import os | 10 | import os |
11 | 11 | ||
12 | class LibOE(OESelftestTestCase): | 12 | class CopyTreeTests(OESelftestTestCase): |
13 | 13 | ||
14 | @classmethod | 14 | @classmethod |
15 | def setUpClass(cls): | 15 | def setUpClass(cls): |
16 | super(LibOE, cls).setUpClass() | 16 | super().setUpClass() |
17 | cls.tmp_dir = get_bb_var('TMPDIR') | 17 | cls.tmp_dir = get_bb_var('TMPDIR') |
18 | 18 | ||
19 | def test_copy_tree_special(self): | 19 | def test_copy_tree_special(self): |
@@ -102,3 +102,36 @@ class LibOE(OESelftestTestCase): | |||
102 | self.assertEqual(dstcnt, len(testfiles), "Number of files in dst (%s) differs from number of files in src(%s)." % (dstcnt, srccnt)) | 102 | self.assertEqual(dstcnt, len(testfiles), "Number of files in dst (%s) differs from number of files in src(%s)." % (dstcnt, srccnt)) |
103 | 103 | ||
104 | oe.path.remove(testloc) | 104 | oe.path.remove(testloc) |
105 | |||
106 | class SubprocessTests(OESelftestTestCase): | ||
107 | |||
108 | def test_subprocess_tweak(self): | ||
109 | """ | ||
110 | Test that the string representation of | ||
111 | oeqa.utils.subprocesstweak.OETestCalledProcessError includes stdout and | ||
112 | stderr, as expected. | ||
113 | """ | ||
114 | script = """ | ||
115 | #! /bin/sh | ||
116 | echo Ivn fgqbhg | tr '[a-zA-Z]' '[n-za-mN-ZA-M]' | ||
117 | echo Ivn fgqree | tr '[a-zA-Z]' '[n-za-mN-ZA-M]' >&2 | ||
118 | exit 42 | ||
119 | """ | ||
120 | |||
121 | import subprocess | ||
122 | import unittest.mock | ||
123 | from oeqa.utils.subprocesstweak import OETestCalledProcessError | ||
124 | |||
125 | with self.assertRaises(OETestCalledProcessError) as cm: | ||
126 | with unittest.mock.patch("subprocess.CalledProcessError", OETestCalledProcessError): | ||
127 | subprocess.run(["bash", "-"], input=script, text=True, capture_output=True, check=True) | ||
128 | |||
129 | e = cm.exception | ||
130 | self.assertEqual(e.returncode, 42) | ||
131 | self.assertEqual("Via stdout\n", e.stdout) | ||
132 | self.assertEqual("Via stderr\n", e.stderr) | ||
133 | |||
134 | string = str(e) | ||
135 | self.assertIn("exit status 42", string) | ||
136 | self.assertIn("Standard Output: Via stdout", string) | ||
137 | self.assertIn("Standard Error: Via stderr", string) | ||
diff --git a/meta/lib/oeqa/selftest/cases/oescripts.py b/meta/lib/oeqa/selftest/cases/oescripts.py index bfbc33b08d..3f9899b289 100644 --- a/meta/lib/oeqa/selftest/cases/oescripts.py +++ b/meta/lib/oeqa/selftest/cases/oescripts.py | |||
@@ -9,33 +9,9 @@ import shutil | |||
9 | import importlib | 9 | import importlib |
10 | import unittest | 10 | import unittest |
11 | from oeqa.selftest.case import OESelftestTestCase | 11 | from oeqa.selftest.case import OESelftestTestCase |
12 | from oeqa.selftest.cases.buildhistory import BuildhistoryBase | ||
13 | from oeqa.utils.commands import runCmd, bitbake, get_bb_var | 12 | from oeqa.utils.commands import runCmd, bitbake, get_bb_var |
14 | from oeqa.utils import CommandError | 13 | from oeqa.utils import CommandError |
15 | 14 | ||
16 | class BuildhistoryDiffTests(BuildhistoryBase): | ||
17 | |||
18 | def test_buildhistory_diff(self): | ||
19 | target = 'xcursor-transparent-theme' | ||
20 | self.run_buildhistory_operation(target, target_config="PR = \"r1\"", change_bh_location=True) | ||
21 | self.run_buildhistory_operation(target, target_config="PR = \"r0\"", change_bh_location=False, expect_error=True) | ||
22 | result = runCmd("oe-pkgdata-util read-value PKGV %s" % target) | ||
23 | pkgv = result.output.rstrip() | ||
24 | result = runCmd("buildhistory-diff -p %s" % get_bb_var('BUILDHISTORY_DIR')) | ||
25 | expected_endlines = [ | ||
26 | "xcursor-transparent-theme-dev: RRECOMMENDS: removed \"xcursor-transparent-theme (['= %s-r1'])\", added \"xcursor-transparent-theme (['= %s-r0'])\"" % (pkgv, pkgv), | ||
27 | "xcursor-transparent-theme-staticdev: RDEPENDS: removed \"xcursor-transparent-theme-dev (['= %s-r1'])\", added \"xcursor-transparent-theme-dev (['= %s-r0'])\"" % (pkgv, pkgv) | ||
28 | ] | ||
29 | for line in result.output.splitlines(): | ||
30 | for el in expected_endlines: | ||
31 | if line.endswith(el): | ||
32 | expected_endlines.remove(el) | ||
33 | break | ||
34 | else: | ||
35 | self.fail('Unexpected line:\n%s\nExpected line endings:\n %s' % (line, '\n '.join(expected_endlines))) | ||
36 | if expected_endlines: | ||
37 | self.fail('Missing expected line endings:\n %s' % '\n '.join(expected_endlines)) | ||
38 | |||
39 | @unittest.skipUnless(importlib.util.find_spec("cairo"), "Python cairo module is not present") | 15 | @unittest.skipUnless(importlib.util.find_spec("cairo"), "Python cairo module is not present") |
40 | class OEPybootchartguyTests(OESelftestTestCase): | 16 | class OEPybootchartguyTests(OESelftestTestCase): |
41 | 17 | ||
diff --git a/meta/lib/oeqa/selftest/cases/pokybleeding.py b/meta/lib/oeqa/selftest/cases/pokybleeding.py deleted file mode 100644 index d0940d680d..0000000000 --- a/meta/lib/oeqa/selftest/cases/pokybleeding.py +++ /dev/null | |||
@@ -1,32 +0,0 @@ | |||
1 | # | ||
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
4 | # SPDX-License-Identifier: MIT | ||
5 | # | ||
6 | |||
7 | from oeqa.utils.commands import bitbake, get_bb_var | ||
8 | from oeqa.selftest.case import OESelftestTestCase | ||
9 | |||
10 | class PokyBleeding(OESelftestTestCase): | ||
11 | |||
12 | def test_poky_bleeding_autorev(self): | ||
13 | """ | ||
14 | Test that poky-bleeding.bbclass sets SRCREV to "AUTOINC" for recipe | ||
15 | with a single scm in SRC_URI and for recipe with two scm's in SRC_URI. | ||
16 | """ | ||
17 | |||
18 | self.assertNotEqual( get_bb_var('SRCREV', 'pseudo'), "AUTOINC") | ||
19 | |||
20 | self.assertNotEqual( get_bb_var('SRCREV', 'hello-rs'), "AUTOINC") | ||
21 | self.assertNotEqual( get_bb_var('SRCREV_hello-lib', 'hello-rs'), "AUTOINC") | ||
22 | |||
23 | features = ''' | ||
24 | INHERIT += "poky-bleeding" | ||
25 | POKY_AUTOREV_RECIPES = "hello-rs pseudo" | ||
26 | ''' | ||
27 | self.write_config(features) | ||
28 | |||
29 | self.assertEqual( get_bb_var('SRCREV', 'pseudo'), "AUTOINC") | ||
30 | |||
31 | self.assertEqual( get_bb_var('SRCREV', 'hello-rs'), "AUTOINC") | ||
32 | self.assertEqual( get_bb_var('SRCREV_hello-lib', 'hello-rs'), "AUTOINC") | ||
diff --git a/meta/lib/oeqa/selftest/cases/recipetool.py b/meta/lib/oeqa/selftest/cases/recipetool.py index 36557f270f..2a91f6c7ae 100644 --- a/meta/lib/oeqa/selftest/cases/recipetool.py +++ b/meta/lib/oeqa/selftest/cases/recipetool.py | |||
@@ -385,7 +385,7 @@ class RecipetoolCreateTests(RecipetoolBase): | |||
385 | checkvars = {} | 385 | checkvars = {} |
386 | checkvars['LICENSE'] = 'LGPL-2.1-only' | 386 | checkvars['LICENSE'] = 'LGPL-2.1-only' |
387 | checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=7fbc338309ac38fefcd64b04bb903e34' | 387 | checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=7fbc338309ac38fefcd64b04bb903e34' |
388 | checkvars['S'] = '${WORKDIR}/git' | 388 | checkvars['S'] = None |
389 | checkvars['PV'] = '1.11+git' | 389 | checkvars['PV'] = '1.11+git' |
390 | checkvars['SRC_URI'] = srcuri + ';branch=master' | 390 | checkvars['SRC_URI'] = srcuri + ';branch=master' |
391 | checkvars['DEPENDS'] = set(['libcheck', 'libjpeg-turbo', 'libpng', 'libx11', 'libxext', 'pango']) | 391 | checkvars['DEPENDS'] = set(['libcheck', 'libjpeg-turbo', 'libpng', 'libx11', 'libxext', 'pango']) |
@@ -1144,10 +1144,10 @@ class RecipetoolAppendsrcTests(RecipetoolAppendsrcBase): | |||
1144 | 1144 | ||
1145 | def test_recipetool_appendsrcfile_srcdir_basic(self): | 1145 | def test_recipetool_appendsrcfile_srcdir_basic(self): |
1146 | testrecipe = 'bash' | 1146 | testrecipe = 'bash' |
1147 | bb_vars = get_bb_vars(['S', 'WORKDIR'], testrecipe) | 1147 | bb_vars = get_bb_vars(['S', 'UNPACKDIR'], testrecipe) |
1148 | srcdir = bb_vars['S'] | 1148 | srcdir = bb_vars['S'] |
1149 | workdir = bb_vars['WORKDIR'] | 1149 | unpackdir = bb_vars['UNPACKDIR'] |
1150 | subdir = os.path.relpath(srcdir, workdir) | 1150 | subdir = os.path.relpath(srcdir, unpackdir) |
1151 | self._test_appendsrcfile(testrecipe, 'a-file', srcdir=subdir) | 1151 | self._test_appendsrcfile(testrecipe, 'a-file', srcdir=subdir) |
1152 | 1152 | ||
1153 | def test_recipetool_appendsrcfile_existing_in_src_uri(self): | 1153 | def test_recipetool_appendsrcfile_existing_in_src_uri(self): |
@@ -1196,10 +1196,10 @@ class RecipetoolAppendsrcTests(RecipetoolAppendsrcBase): | |||
1196 | def test_recipetool_appendsrcfile_replace_file_srcdir(self): | 1196 | def test_recipetool_appendsrcfile_replace_file_srcdir(self): |
1197 | testrecipe = 'bash' | 1197 | testrecipe = 'bash' |
1198 | filepath = 'Makefile.in' | 1198 | filepath = 'Makefile.in' |
1199 | bb_vars = get_bb_vars(['S', 'WORKDIR'], testrecipe) | 1199 | bb_vars = get_bb_vars(['S', 'UNPACKDIR'], testrecipe) |
1200 | srcdir = bb_vars['S'] | 1200 | srcdir = bb_vars['S'] |
1201 | workdir = bb_vars['WORKDIR'] | 1201 | unpackdir = bb_vars['UNPACKDIR'] |
1202 | subdir = os.path.relpath(srcdir, workdir) | 1202 | subdir = os.path.relpath(srcdir, unpackdir) |
1203 | 1203 | ||
1204 | self._test_appendsrcfile(testrecipe, filepath, srcdir=subdir) | 1204 | self._test_appendsrcfile(testrecipe, filepath, srcdir=subdir) |
1205 | bitbake('%s:do_unpack' % testrecipe) | 1205 | bitbake('%s:do_unpack' % testrecipe) |
diff --git a/meta/lib/oeqa/selftest/cases/recipeutils.py b/meta/lib/oeqa/selftest/cases/recipeutils.py index 9949737172..e697fd2920 100644 --- a/meta/lib/oeqa/selftest/cases/recipeutils.py +++ b/meta/lib/oeqa/selftest/cases/recipeutils.py | |||
@@ -72,7 +72,7 @@ class RecipeUtilsTests(OESelftestTestCase): | |||
72 | expected_patch = """ | 72 | expected_patch = """ |
73 | --- a/recipes-test/recipeutils/recipeutils-test_1.2.bb | 73 | --- a/recipes-test/recipeutils/recipeutils-test_1.2.bb |
74 | +++ b/recipes-test/recipeutils/recipeutils-test_1.2.bb | 74 | +++ b/recipes-test/recipeutils/recipeutils-test_1.2.bb |
75 | @@ -11,6 +11,4 @@ | 75 | @@ -10,6 +10,4 @@ |
76 | 76 | ||
77 | BBCLASSEXTEND = "native nativesdk" | 77 | BBCLASSEXTEND = "native nativesdk" |
78 | 78 | ||
@@ -97,7 +97,7 @@ class RecipeUtilsTests(OESelftestTestCase): | |||
97 | expected_patch = """ | 97 | expected_patch = """ |
98 | --- a/recipes-test/recipeutils/recipeutils-test_1.2.bb | 98 | --- a/recipes-test/recipeutils/recipeutils-test_1.2.bb |
99 | +++ b/recipes-test/recipeutils/recipeutils-test_1.2.bb | 99 | +++ b/recipes-test/recipeutils/recipeutils-test_1.2.bb |
100 | @@ -11,6 +11,3 @@ | 100 | @@ -10,6 +10,3 @@ |
101 | 101 | ||
102 | BBCLASSEXTEND = "native nativesdk" | 102 | BBCLASSEXTEND = "native nativesdk" |
103 | 103 | ||
diff --git a/meta/lib/oeqa/selftest/cases/rust.py b/meta/lib/oeqa/selftest/cases/rust.py index 806ddf6982..d99a58d6b9 100644 --- a/meta/lib/oeqa/selftest/cases/rust.py +++ b/meta/lib/oeqa/selftest/cases/rust.py | |||
@@ -104,7 +104,7 @@ class RustSelfTestSystemEmulated(OESelftestTestCase, OEPTestResultTestCase): | |||
104 | # Copy remote-test-server to image through scp | 104 | # Copy remote-test-server to image through scp |
105 | host_sys = get_bb_var("RUST_BUILD_SYS", "rust") | 105 | host_sys = get_bb_var("RUST_BUILD_SYS", "rust") |
106 | ssh = SSHControl(ip=qemu.ip, logfile=qemu.sshlog, user="root") | 106 | ssh = SSHControl(ip=qemu.ip, logfile=qemu.sshlog, user="root") |
107 | ssh.copy_to(builddir + "/build/" + host_sys + "/stage1-tools-bin/remote-test-server","~/") | 107 | ssh.copy_to(builddir + "/build/" + host_sys + "/stage2-tools-bin/remote-test-server","~/") |
108 | # Execute remote-test-server on image through background ssh | 108 | # Execute remote-test-server on image through background ssh |
109 | command = '~/remote-test-server --bind 0.0.0.0:12345 -v' | 109 | command = '~/remote-test-server --bind 0.0.0.0:12345 -v' |
110 | sshrun=subprocess.Popen(("ssh", '-o', 'UserKnownHostsFile=/dev/null', '-o', 'StrictHostKeyChecking=no', '-f', "root@%s" % qemu.ip, command), shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | 110 | sshrun=subprocess.Popen(("ssh", '-o', 'UserKnownHostsFile=/dev/null', '-o', 'StrictHostKeyChecking=no', '-f', "root@%s" % qemu.ip, command), shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
diff --git a/meta/lib/oeqa/selftest/cases/sstatetests.py b/meta/lib/oeqa/selftest/cases/sstatetests.py index 681a57f4db..08f94b168a 100644 --- a/meta/lib/oeqa/selftest/cases/sstatetests.py +++ b/meta/lib/oeqa/selftest/cases/sstatetests.py | |||
@@ -27,17 +27,15 @@ class SStateBase(OESelftestTestCase): | |||
27 | def setUpLocal(self): | 27 | def setUpLocal(self): |
28 | super(SStateBase, self).setUpLocal() | 28 | super(SStateBase, self).setUpLocal() |
29 | self.temp_sstate_location = None | 29 | self.temp_sstate_location = None |
30 | needed_vars = ['SSTATE_DIR', 'NATIVELSBSTRING', 'TCLIBC', 'TUNE_ARCH', | 30 | needed_vars = ['SSTATE_DIR', 'TCLIBC', 'TUNE_ARCH', |
31 | 'TOPDIR', 'TARGET_VENDOR', 'TARGET_OS'] | 31 | 'TOPDIR', 'TARGET_VENDOR', 'TARGET_OS'] |
32 | bb_vars = get_bb_vars(needed_vars) | 32 | bb_vars = get_bb_vars(needed_vars) |
33 | self.sstate_path = bb_vars['SSTATE_DIR'] | 33 | self.sstate_path = bb_vars['SSTATE_DIR'] |
34 | self.hostdistro = bb_vars['NATIVELSBSTRING'] | ||
35 | self.tclibc = bb_vars['TCLIBC'] | 34 | self.tclibc = bb_vars['TCLIBC'] |
36 | self.tune_arch = bb_vars['TUNE_ARCH'] | 35 | self.tune_arch = bb_vars['TUNE_ARCH'] |
37 | self.topdir = bb_vars['TOPDIR'] | 36 | self.topdir = bb_vars['TOPDIR'] |
38 | self.target_vendor = bb_vars['TARGET_VENDOR'] | 37 | self.target_vendor = bb_vars['TARGET_VENDOR'] |
39 | self.target_os = bb_vars['TARGET_OS'] | 38 | self.target_os = bb_vars['TARGET_OS'] |
40 | self.distro_specific_sstate = os.path.join(self.sstate_path, self.hostdistro) | ||
41 | 39 | ||
42 | def track_for_cleanup(self, path): | 40 | def track_for_cleanup(self, path): |
43 | if not keep_temp_files: | 41 | if not keep_temp_files: |
@@ -52,10 +50,7 @@ class SStateBase(OESelftestTestCase): | |||
52 | config_temp_sstate = "SSTATE_DIR = \"%s\"" % temp_sstate_path | 50 | config_temp_sstate = "SSTATE_DIR = \"%s\"" % temp_sstate_path |
53 | self.append_config(config_temp_sstate) | 51 | self.append_config(config_temp_sstate) |
54 | self.track_for_cleanup(temp_sstate_path) | 52 | self.track_for_cleanup(temp_sstate_path) |
55 | bb_vars = get_bb_vars(['SSTATE_DIR', 'NATIVELSBSTRING']) | 53 | self.sstate_path = get_bb_var('SSTATE_DIR') |
56 | self.sstate_path = bb_vars['SSTATE_DIR'] | ||
57 | self.hostdistro = bb_vars['NATIVELSBSTRING'] | ||
58 | self.distro_specific_sstate = os.path.join(self.sstate_path, self.hostdistro) | ||
59 | 54 | ||
60 | if add_local_mirrors: | 55 | if add_local_mirrors: |
61 | config_set_sstate_if_not_set = 'SSTATE_MIRRORS ?= ""' | 56 | config_set_sstate_if_not_set = 'SSTATE_MIRRORS ?= ""' |
@@ -65,8 +60,16 @@ class SStateBase(OESelftestTestCase): | |||
65 | config_sstate_mirror = "SSTATE_MIRRORS += \"file://.* file:///%s/PATH\"" % local_mirror | 60 | config_sstate_mirror = "SSTATE_MIRRORS += \"file://.* file:///%s/PATH\"" % local_mirror |
66 | self.append_config(config_sstate_mirror) | 61 | self.append_config(config_sstate_mirror) |
67 | 62 | ||
63 | def set_hostdistro(self): | ||
64 | # This needs to be read after a BuildStarted event in case it gets changed by event | ||
65 | # handling in uninative.bbclass | ||
66 | self.hostdistro = get_bb_var('NATIVELSBSTRING') | ||
67 | self.distro_specific_sstate = os.path.join(self.sstate_path, self.hostdistro) | ||
68 | |||
68 | # Returns a list containing sstate files | 69 | # Returns a list containing sstate files |
69 | def search_sstate(self, filename_regex, distro_specific=True, distro_nonspecific=True): | 70 | def search_sstate(self, filename_regex, distro_specific=True, distro_nonspecific=True): |
71 | self.set_hostdistro() | ||
72 | |||
70 | result = [] | 73 | result = [] |
71 | for root, dirs, files in os.walk(self.sstate_path): | 74 | for root, dirs, files in os.walk(self.sstate_path): |
72 | if distro_specific and re.search(r"%s/%s/[a-z0-9]{2}/[a-z0-9]{2}$" % (self.sstate_path, self.hostdistro), root): | 75 | if distro_specific and re.search(r"%s/%s/[a-z0-9]{2}/[a-z0-9]{2}$" % (self.sstate_path, self.hostdistro), root): |
@@ -80,55 +83,43 @@ class SStateBase(OESelftestTestCase): | |||
80 | return result | 83 | return result |
81 | 84 | ||
82 | # Test sstate files creation and their location and directory perms | 85 | # Test sstate files creation and their location and directory perms |
83 | def run_test_sstate_creation(self, targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True, should_pass=True): | 86 | def run_test_sstate_creation(self, targets, hostdistro_specific): |
84 | self.config_sstate(temp_sstate_location, [self.sstate_path]) | 87 | self.config_sstate(True, [self.sstate_path]) |
88 | |||
89 | bitbake(['-cclean'] + targets) | ||
85 | 90 | ||
86 | if self.temp_sstate_location: | ||
87 | bitbake(['-cclean'] + targets) | ||
88 | else: | ||
89 | bitbake(['-ccleansstate'] + targets) | ||
90 | |||
91 | # We need to test that the env umask have does not effect sstate directory creation | ||
92 | # So, first, we'll get the current umask and set it to something we know incorrect | ||
93 | # See: sstate_task_postfunc for correct umask of os.umask(0o002) | ||
94 | import os | ||
95 | def current_umask(): | ||
96 | current_umask = os.umask(0) | ||
97 | os.umask(current_umask) | ||
98 | return current_umask | ||
99 | |||
100 | orig_umask = current_umask() | ||
101 | # Set it to a umask we know will be 'wrong' | 91 | # Set it to a umask we know will be 'wrong' |
102 | os.umask(0o022) | 92 | with bb.utils.umask(0o022): |
93 | bitbake(targets) | ||
103 | 94 | ||
104 | bitbake(targets) | 95 | # Distro specific files |
105 | file_tracker = [] | 96 | distro_specific_files = self.search_sstate('|'.join(map(str, targets)), True, False) |
106 | results = self.search_sstate('|'.join(map(str, targets)), distro_specific, distro_nonspecific) | 97 | |
107 | if distro_nonspecific: | 98 | # Distro non-specific |
108 | for r in results: | 99 | distro_non_specific_files = [] |
109 | if r.endswith(("_populate_lic.tar.zst", "_populate_lic.tar.zst.siginfo", "_fetch.tar.zst.siginfo", "_unpack.tar.zst.siginfo", "_patch.tar.zst.siginfo")): | 100 | results = self.search_sstate('|'.join(map(str, targets)), False, True) |
110 | continue | 101 | for r in results: |
111 | file_tracker.append(r) | 102 | if r.endswith(("_populate_lic.tar.zst", "_populate_lic.tar.zst.siginfo", "_fetch.tar.zst.siginfo", "_unpack.tar.zst.siginfo", "_patch.tar.zst.siginfo")): |
112 | else: | 103 | continue |
113 | file_tracker = results | 104 | distro_non_specific_files.append(r) |
114 | 105 | ||
115 | if should_pass: | 106 | if hostdistro_specific: |
116 | self.assertTrue(file_tracker , msg="Could not find sstate files for: %s" % ', '.join(map(str, targets))) | 107 | self.assertTrue(distro_specific_files , msg="Could not find sstate files for: %s" % ', '.join(map(str, targets))) |
108 | self.assertFalse(distro_non_specific_files, msg="Found sstate files in the wrong place for: %s (found %s)" % (', '.join(map(str, targets)), str(distro_non_specific_files))) | ||
117 | else: | 109 | else: |
118 | self.assertTrue(not file_tracker , msg="Found sstate files in the wrong place for: %s (found %s)" % (', '.join(map(str, targets)), str(file_tracker))) | 110 | self.assertTrue(distro_non_specific_files , msg="Could not find sstate files for: %s" % ', '.join(map(str, targets))) |
111 | self.assertFalse(distro_specific_files, msg="Found sstate files in the wrong place for: %s (found %s)" % (', '.join(map(str, targets)), str(distro_specific_files))) | ||
119 | 112 | ||
120 | # Now we'll walk the tree to check the mode and see if things are incorrect. | 113 | # Now we'll walk the tree to check the mode and see if things are incorrect. |
121 | badperms = [] | 114 | badperms = [] |
122 | for root, dirs, files in os.walk(self.sstate_path): | 115 | for root, dirs, files in os.walk(self.sstate_path): |
123 | for directory in dirs: | 116 | for directory in dirs: |
124 | if (os.stat(os.path.join(root, directory)).st_mode & 0o777) != 0o775: | 117 | mode = os.stat(os.path.join(root, directory)).st_mode & 0o777 |
125 | badperms.append(os.path.join(root, directory)) | 118 | if mode != 0o775: |
126 | 119 | badperms.append("%s: %s vs %s" % (os.path.join(root, directory), mode, 0o775)) | |
127 | # Return to original umask | ||
128 | os.umask(orig_umask) | ||
129 | 120 | ||
130 | if should_pass: | 121 | # Check badperms is empty |
131 | self.assertTrue(badperms , msg="Found sstate directories with the wrong permissions: %s (found %s)" % (', '.join(map(str, targets)), str(badperms))) | 122 | self.assertFalse(badperms , msg="Found sstate directories with the wrong permissions: %s (found %s)" % (', '.join(map(str, targets)), str(badperms))) |
132 | 123 | ||
133 | # Test the sstate files deletion part of the do_cleansstate task | 124 | # Test the sstate files deletion part of the do_cleansstate task |
134 | def run_test_cleansstate_task(self, targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True): | 125 | def run_test_cleansstate_task(self, targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True): |
@@ -153,6 +144,8 @@ class SStateBase(OESelftestTestCase): | |||
153 | 144 | ||
154 | bitbake(['-ccleansstate'] + targets) | 145 | bitbake(['-ccleansstate'] + targets) |
155 | 146 | ||
147 | self.set_hostdistro() | ||
148 | |||
156 | bitbake(targets) | 149 | bitbake(targets) |
157 | results = self.search_sstate('|'.join(map(str, [s + r'.*?\.tar.zst$' for s in targets])), distro_specific=False, distro_nonspecific=True) | 150 | results = self.search_sstate('|'.join(map(str, [s + r'.*?\.tar.zst$' for s in targets])), distro_specific=False, distro_nonspecific=True) |
158 | filtered_results = [] | 151 | filtered_results = [] |
@@ -251,17 +244,11 @@ class SStateTests(SStateBase): | |||
251 | bitbake("dbus-wait-test -c unpack") | 244 | bitbake("dbus-wait-test -c unpack") |
252 | 245 | ||
253 | class SStateCreation(SStateBase): | 246 | class SStateCreation(SStateBase): |
254 | def test_sstate_creation_distro_specific_pass(self): | 247 | def test_sstate_creation_distro_specific(self): |
255 | self.run_test_sstate_creation(['binutils-cross-'+ self.tune_arch, 'binutils-native'], distro_specific=True, distro_nonspecific=False, temp_sstate_location=True) | 248 | self.run_test_sstate_creation(['binutils-cross-'+ self.tune_arch, 'binutils-native'], hostdistro_specific=True) |
256 | |||
257 | def test_sstate_creation_distro_specific_fail(self): | ||
258 | self.run_test_sstate_creation(['binutils-cross-'+ self.tune_arch, 'binutils-native'], distro_specific=False, distro_nonspecific=True, temp_sstate_location=True, should_pass=False) | ||
259 | |||
260 | def test_sstate_creation_distro_nonspecific_pass(self): | ||
261 | self.run_test_sstate_creation(['linux-libc-headers'], distro_specific=False, distro_nonspecific=True, temp_sstate_location=True) | ||
262 | 249 | ||
263 | def test_sstate_creation_distro_nonspecific_fail(self): | 250 | def test_sstate_creation_distro_nonspecific(self): |
264 | self.run_test_sstate_creation(['linux-libc-headers'], distro_specific=True, distro_nonspecific=False, temp_sstate_location=True, should_pass=False) | 251 | self.run_test_sstate_creation(['linux-libc-headers'], hostdistro_specific=False) |
265 | 252 | ||
266 | class SStateCleanup(SStateBase): | 253 | class SStateCleanup(SStateBase): |
267 | def test_cleansstate_task_distro_specific_nonspecific(self): | 254 | def test_cleansstate_task_distro_specific_nonspecific(self): |
@@ -972,7 +959,7 @@ class SStateMirrors(SStateCheckObjectPresence): | |||
972 | self.append_config(""" | 959 | self.append_config(""" |
973 | MACHINE = "{}" | 960 | MACHINE = "{}" |
974 | BB_HASHSERVE_UPSTREAM = "hashserv.yoctoproject.org:8686" | 961 | BB_HASHSERVE_UPSTREAM = "hashserv.yoctoproject.org:8686" |
975 | SSTATE_MIRRORS ?= "file://.* http://cdn.jsdelivr.net/yocto/sstate/all/PATH;downloadfilename=PATH" | 962 | SSTATE_MIRRORS ?= "file://.* http://sstate.yoctoproject.org/all/PATH;downloadfilename=PATH" |
976 | """.format(machine)) | 963 | """.format(machine)) |
977 | else: | 964 | else: |
978 | self.append_config(""" | 965 | self.append_config(""" |
diff --git a/meta/lib/oeqa/selftest/cases/toolchain.py b/meta/lib/oeqa/selftest/cases/toolchain.py new file mode 100644 index 0000000000..b4b280d037 --- /dev/null +++ b/meta/lib/oeqa/selftest/cases/toolchain.py | |||
@@ -0,0 +1,71 @@ | |||
1 | # | ||
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
4 | # SPDX-License-Identifier: MIT | ||
5 | # | ||
6 | |||
7 | import shutil | ||
8 | import subprocess | ||
9 | import tempfile | ||
10 | from types import SimpleNamespace | ||
11 | |||
12 | import oe.path | ||
13 | from oeqa.selftest.case import OESelftestTestCase | ||
14 | from oeqa.utils.commands import bitbake, get_bb_var, get_bb_vars | ||
15 | |||
16 | class ToolchainTests(OESelftestTestCase): | ||
17 | |||
18 | def test_toolchain_switching(self): | ||
19 | """ | ||
20 | Test that a configuration that uses GCC by default but clang for one | ||
21 | specific recipe does infact do that. | ||
22 | """ | ||
23 | |||
24 | def extract_comment(objcopy, filename): | ||
25 | """ | ||
26 | Using the specified `objcopy`, return the .comment segment from | ||
27 | `filename` as a bytes(). | ||
28 | """ | ||
29 | with tempfile.NamedTemporaryFile(prefix="comment-") as f: | ||
30 | cmd = [objcopy, "--dump-section", ".comment=" + f.name, filename] | ||
31 | subprocess.run(cmd, check=True) | ||
32 | # clang's objcopy writes to a temporary file and renames, so we need to re-open. | ||
33 | with open(f.name, "rb") as f2: | ||
34 | return f2.read() | ||
35 | |||
36 | def check_recipe(recipe, filename, override, comment_present, comment_absent=None): | ||
37 | """ | ||
38 | Check that `filename` in `recipe`'s bindir contains `comment`, and | ||
39 | the overrides contain `override`. | ||
40 | """ | ||
41 | d = SimpleNamespace(**get_bb_vars(("D", "bindir", "OBJCOPY", "OVERRIDES", "PATH"), target=recipe)) | ||
42 | |||
43 | self.assertIn(override, d.OVERRIDES) | ||
44 | |||
45 | binary = oe.path.join(d.D, d.bindir, filename) | ||
46 | |||
47 | objcopy = shutil.which(d.OBJCOPY, path=d.PATH) | ||
48 | self.assertIsNotNone(objcopy) | ||
49 | |||
50 | comment = extract_comment(objcopy, binary) | ||
51 | self.assertIn(comment_present, comment) | ||
52 | if comment_absent: | ||
53 | self.assertNotIn(comment_absent, comment) | ||
54 | |||
55 | |||
56 | # GCC by default, clang for selftest-hello. | ||
57 | self.write_config(""" | ||
58 | TOOLCHAIN = "gcc" | ||
59 | TOOLCHAIN:pn-selftest-hello = "clang" | ||
60 | """) | ||
61 | |||
62 | # Force these recipes to re-install so we can extract the .comments from | ||
63 | # the install directory, as they're stripped out of the final packages. | ||
64 | bitbake("m4 selftest-hello -C install") | ||
65 | |||
66 | # m4 should be built with GCC and only GCC | ||
67 | check_recipe("m4", "m4", "toolchain-gcc", b"GCC: (GNU)", b"clang") | ||
68 | |||
69 | # helloworld should be built with clang. We can't assert that GCC is not | ||
70 | # present as it will be linked against glibc which is built with GCC. | ||
71 | check_recipe("selftest-hello", "helloworld", "toolchain-clang", b"clang version") | ||
diff --git a/meta/lib/oeqa/selftest/cases/uboot.py b/meta/lib/oeqa/selftest/cases/uboot.py index 96da4efb06..980ea327f0 100644 --- a/meta/lib/oeqa/selftest/cases/uboot.py +++ b/meta/lib/oeqa/selftest/cases/uboot.py | |||
@@ -6,8 +6,8 @@ | |||
6 | # | 6 | # |
7 | 7 | ||
8 | from oeqa.selftest.case import OESelftestTestCase | 8 | from oeqa.selftest.case import OESelftestTestCase |
9 | from oeqa.utils.commands import bitbake, runqemu | 9 | from oeqa.utils.commands import bitbake, runqemu, get_bb_var, get_bb_vars, runCmd |
10 | from oeqa.core.decorator.data import skipIfNotArch | 10 | from oeqa.core.decorator.data import skipIfNotArch, skipIfNotBuildArch |
11 | from oeqa.core.decorator import OETestTag | 11 | from oeqa.core.decorator import OETestTag |
12 | 12 | ||
13 | uboot_boot_patterns = { | 13 | uboot_boot_patterns = { |
@@ -41,3 +41,58 @@ QEMU_USE_KVM = "False" | |||
41 | status, output = qemu.run_serial(cmd) | 41 | status, output = qemu.run_serial(cmd) |
42 | self.assertEqual(status, 1, msg=output) | 42 | self.assertEqual(status, 1, msg=output) |
43 | self.assertTrue("U-Boot" in output, msg=output) | 43 | self.assertTrue("U-Boot" in output, msg=output) |
44 | |||
45 | @skipIfNotArch(['aarch64']) | ||
46 | @skipIfNotBuildArch(['aarch64']) | ||
47 | @OETestTag("runqemu") | ||
48 | def test_boot_uboot_kvm_to_full_target(self): | ||
49 | """ | ||
50 | Tests building u-boot and booting it with QEMU and KVM. | ||
51 | Requires working KVM on build host. See "kvm-ok" output. | ||
52 | """ | ||
53 | |||
54 | runCmd("kvm-ok") | ||
55 | |||
56 | image = "core-image-minimal" | ||
57 | vars = get_bb_vars(['HOST_ARCH', 'BUILD_ARCH'], image) | ||
58 | host_arch = vars['HOST_ARCH'] | ||
59 | build_arch = vars['BUILD_ARCH'] | ||
60 | |||
61 | self.assertEqual(host_arch, build_arch, 'HOST_ARCH %s and BUILD_ARCH %s must match for KVM' % (host_arch, build_arch)) | ||
62 | |||
63 | self.write_config(""" | ||
64 | QEMU_USE_KVM = "1" | ||
65 | |||
66 | # Using u-boot in EFI mode, need ESP partition for grub/systemd-boot/kernel etc | ||
67 | IMAGE_FSTYPES:pn-core-image-minimal:append = " wic" | ||
68 | |||
69 | # easiest to follow genericarm64 setup with wks file, initrd and EFI loader | ||
70 | INITRAMFS_IMAGE = "core-image-initramfs-boot" | ||
71 | EFI_PROVIDER = "${@bb.utils.contains("DISTRO_FEATURES", "systemd", "systemd-boot", "grub-efi", d)}" | ||
72 | WKS_FILE = "genericarm64.wks.in" | ||
73 | |||
74 | # use wic image with ESP for u-boot, not ext4 | ||
75 | QB_DEFAULT_FSTYPE = "wic" | ||
76 | |||
77 | PREFERRED_PROVIDER_virtual/bootloader = "u-boot" | ||
78 | QB_DEFAULT_BIOS = "u-boot.bin" | ||
79 | |||
80 | # let u-boot or EFI loader load kernel from ESP | ||
81 | QB_DEFAULT_KERNEL = "none" | ||
82 | |||
83 | # virt pci, not scsi because support not in u-boot to find ESP | ||
84 | QB_DRIVE_TYPE = "/dev/vd" | ||
85 | """) | ||
86 | bitbake("virtual/bootloader %s" % image) | ||
87 | |||
88 | runqemu_params = get_bb_var('TEST_RUNQEMUPARAMS', image) or "" | ||
89 | with runqemu(image, ssh=False, runqemuparams='nographic kvm %s' % runqemu_params) as qemu: | ||
90 | |||
91 | # boot to target and login worked, should have been fast with kvm | ||
92 | cmd = "dmesg" | ||
93 | status, output = qemu.run_serial(cmd) | ||
94 | self.assertEqual(status, 1, msg=output) | ||
95 | # Machine is qemu | ||
96 | self.assertTrue("Machine model: linux,dummy-virt" in output, msg=output) | ||
97 | # with KVM enabled | ||
98 | self.assertTrue("KVM: hypervisor services detected" in output, msg=output) | ||
diff --git a/meta/lib/oeqa/selftest/cases/wic.py b/meta/lib/oeqa/selftest/cases/wic.py index 1a67b6df51..680f99d381 100644 --- a/meta/lib/oeqa/selftest/cases/wic.py +++ b/meta/lib/oeqa/selftest/cases/wic.py | |||
@@ -153,7 +153,7 @@ class Wic(WicTestCase): | |||
153 | # create a temporary file for the WKS content | 153 | # create a temporary file for the WKS content |
154 | with NamedTemporaryFile("w", suffix=".wks") as wks: | 154 | with NamedTemporaryFile("w", suffix=".wks") as wks: |
155 | wks.write( | 155 | wks.write( |
156 | 'part --source bootimg-efi ' | 156 | 'part --source bootimg_efi ' |
157 | '--sourceparams="loader=grub-efi,install-kernel-into-boot-dir=false" ' | 157 | '--sourceparams="loader=grub-efi,install-kernel-into-boot-dir=false" ' |
158 | '--label boot --active\n' | 158 | '--label boot --active\n' |
159 | ) | 159 | ) |
@@ -186,7 +186,7 @@ class Wic(WicTestCase): | |||
186 | # create a temporary file for the WKS content | 186 | # create a temporary file for the WKS content |
187 | with NamedTemporaryFile("w", suffix=".wks") as wks: | 187 | with NamedTemporaryFile("w", suffix=".wks") as wks: |
188 | wks.write( | 188 | wks.write( |
189 | 'part --source bootimg-efi ' | 189 | 'part --source bootimg_efi ' |
190 | '--sourceparams="loader=grub-efi,install-kernel-into-boot-dir=true" ' | 190 | '--sourceparams="loader=grub-efi,install-kernel-into-boot-dir=true" ' |
191 | '--label boot --active\n' | 191 | '--label boot --active\n' |
192 | ) | 192 | ) |
@@ -1021,6 +1021,18 @@ class Wic2(WicTestCase): | |||
1021 | """Test building wic images by bitbake""" | 1021 | """Test building wic images by bitbake""" |
1022 | config = 'IMAGE_FSTYPES += "wic"\nWKS_FILE = "wic-image-minimal"\n'\ | 1022 | config = 'IMAGE_FSTYPES += "wic"\nWKS_FILE = "wic-image-minimal"\n'\ |
1023 | 'MACHINE_FEATURES:append = " efi"\n' | 1023 | 'MACHINE_FEATURES:append = " efi"\n' |
1024 | image_recipe_append = """ | ||
1025 | do_image_wic[postfuncs] += "run_wic_cmd" | ||
1026 | run_wic_cmd() { | ||
1027 | echo "test" >> ${WORKDIR}/test.wic-cp | ||
1028 | wic cp --vars "${STAGING_DIR}/${MACHINE}/imgdata/" -e "${IMAGE_BASENAME}" ${WORKDIR}/test.wic-cp ${IMGDEPLOYDIR}/${IMAGE_NAME}.wic:1/ | ||
1029 | wic ls --vars "${STAGING_DIR}/${MACHINE}/imgdata/" -e "${IMAGE_BASENAME}" ${IMGDEPLOYDIR}/${IMAGE_NAME}.wic:1/ | ||
1030 | wic rm --vars "${STAGING_DIR}/${MACHINE}/imgdata/" -e "${IMAGE_BASENAME}" ${IMGDEPLOYDIR}/${IMAGE_NAME}.wic:1/test.wic-cp | ||
1031 | wic cp --vars "${STAGING_DIR}/${MACHINE}/imgdata/" -e "${IMAGE_BASENAME}" ${WORKDIR}/test.wic-cp ${IMGDEPLOYDIR}/${IMAGE_NAME}.wic:1/ | ||
1032 | } | ||
1033 | """ | ||
1034 | self.write_recipeinc('images', image_recipe_append) | ||
1035 | |||
1024 | self.append_config(config) | 1036 | self.append_config(config) |
1025 | image = 'wic-image-minimal' | 1037 | image = 'wic-image-minimal' |
1026 | bitbake(image) | 1038 | bitbake(image) |
@@ -1029,6 +1041,11 @@ class Wic2(WicTestCase): | |||
1029 | bb_vars = get_bb_vars(['DEPLOY_DIR_IMAGE', 'IMAGE_LINK_NAME'], image) | 1041 | bb_vars = get_bb_vars(['DEPLOY_DIR_IMAGE', 'IMAGE_LINK_NAME'], image) |
1030 | prefix = os.path.join(bb_vars['DEPLOY_DIR_IMAGE'], '%s.' % bb_vars['IMAGE_LINK_NAME']) | 1042 | prefix = os.path.join(bb_vars['DEPLOY_DIR_IMAGE'], '%s.' % bb_vars['IMAGE_LINK_NAME']) |
1031 | 1043 | ||
1044 | sysroot = get_bb_var('RECIPE_SYSROOT_NATIVE', 'wic-tools') | ||
1045 | # check if file is there | ||
1046 | result = runCmd("wic ls %s:1/ -n %s" % (prefix+"wic", sysroot)) | ||
1047 | self.assertIn("test.wic-cp", result.output) | ||
1048 | |||
1032 | # check if we have result image and manifests symlinks | 1049 | # check if we have result image and manifests symlinks |
1033 | # pointing to existing files | 1050 | # pointing to existing files |
1034 | for suffix in ('wic', 'manifest'): | 1051 | for suffix in ('wic', 'manifest'): |
@@ -1044,7 +1061,25 @@ class Wic2(WicTestCase): | |||
1044 | config = 'IMAGE_FSTYPES += "wic"\nWKS_FILE = "wic-image-minimal"\n'\ | 1061 | config = 'IMAGE_FSTYPES += "wic"\nWKS_FILE = "wic-image-minimal"\n'\ |
1045 | 'MACHINE_FEATURES:append = " efi"\n' | 1062 | 'MACHINE_FEATURES:append = " efi"\n' |
1046 | self.append_config(config) | 1063 | self.append_config(config) |
1064 | image_recipe_append = """ | ||
1065 | do_image_wic[postfuncs] += "run_wic_cmd" | ||
1066 | run_wic_cmd() { | ||
1067 | echo "test" >> ${WORKDIR}/test.wic-cp | ||
1068 | wic cp --vars "${STAGING_DIR}/${MACHINE}/imgdata/" -e "${IMAGE_BASENAME}" ${WORKDIR}/test.wic-cp ${IMGDEPLOYDIR}/${IMAGE_NAME}.wic:1/ | ||
1069 | wic ls --vars "${STAGING_DIR}/${MACHINE}/imgdata/" -e "${IMAGE_BASENAME}" ${IMGDEPLOYDIR}/${IMAGE_NAME}.wic:1/ | ||
1070 | wic rm --vars "${STAGING_DIR}/${MACHINE}/imgdata/" -e "${IMAGE_BASENAME}" ${IMGDEPLOYDIR}/${IMAGE_NAME}.wic:1/test.wic-cp | ||
1071 | wic cp --vars "${STAGING_DIR}/${MACHINE}/imgdata/" -e "${IMAGE_BASENAME}" ${WORKDIR}/test.wic-cp ${IMGDEPLOYDIR}/${IMAGE_NAME}.wic:1/ | ||
1072 | } | ||
1073 | """ | ||
1074 | self.write_recipeinc('images', image_recipe_append) | ||
1047 | bitbake('wic-image-minimal') | 1075 | bitbake('wic-image-minimal') |
1076 | |||
1077 | sysroot = get_bb_var('RECIPE_SYSROOT_NATIVE', 'wic-tools') | ||
1078 | bb_vars = get_bb_vars(['DEPLOY_DIR_IMAGE', 'IMAGE_LINK_NAME'], "wic-image-minimal") | ||
1079 | image_path = os.path.join(bb_vars['DEPLOY_DIR_IMAGE'], bb_vars['IMAGE_LINK_NAME']) | ||
1080 | # check if file is there | ||
1081 | result = runCmd("wic ls %s:1/ -n %s" % (image_path+".wic", sysroot)) | ||
1082 | self.assertIn("test.wic-cp", result.output) | ||
1048 | self.remove_config(config) | 1083 | self.remove_config(config) |
1049 | 1084 | ||
1050 | runqemu_params = get_bb_var('TEST_RUNQEMUPARAMS', 'wic-image-minimal') or "" | 1085 | runqemu_params = get_bb_var('TEST_RUNQEMUPARAMS', 'wic-image-minimal') or "" |
@@ -1358,7 +1393,7 @@ class Wic2(WicTestCase): | |||
1358 | def test_biosplusefi_plugin(self): | 1393 | def test_biosplusefi_plugin(self): |
1359 | """Test biosplusefi plugin""" | 1394 | """Test biosplusefi plugin""" |
1360 | # Wic generation below may fail depending on the order of the unittests | 1395 | # Wic generation below may fail depending on the order of the unittests |
1361 | # This is because bootimg-pcbios (that bootimg-biosplusefi uses) generate its MBR inside STAGING_DATADIR directory | 1396 | # This is because bootimg_pcbios (that bootimg_biosplusefi uses) generate its MBR inside STAGING_DATADIR directory |
1362 | # which may or may not exists depending on what was built already | 1397 | # which may or may not exists depending on what was built already |
1363 | # If an image hasn't been built yet, directory ${STAGING_DATADIR}/syslinux won't exists and _get_bootimg_dir() | 1398 | # If an image hasn't been built yet, directory ${STAGING_DATADIR}/syslinux won't exists and _get_bootimg_dir() |
1364 | # will raise with "Couldn't find correct bootimg_dir" | 1399 | # will raise with "Couldn't find correct bootimg_dir" |
@@ -1370,7 +1405,7 @@ class Wic2(WicTestCase): | |||
1370 | 1405 | ||
1371 | img = 'core-image-minimal' | 1406 | img = 'core-image-minimal' |
1372 | with NamedTemporaryFile("w", suffix=".wks") as wks: | 1407 | with NamedTemporaryFile("w", suffix=".wks") as wks: |
1373 | wks.writelines(['part /boot --active --source bootimg-biosplusefi --sourceparams="loader=grub-efi"\n', | 1408 | wks.writelines(['part /boot --active --source bootimg_biosplusefi --sourceparams="loader=grub-efi"\n', |
1374 | 'part / --source rootfs --fstype=ext4 --align 1024 --use-uuid\n'\ | 1409 | 'part / --source rootfs --fstype=ext4 --align 1024 --use-uuid\n'\ |
1375 | 'bootloader --timeout=0 --append="console=ttyS0,115200n8"\n']) | 1410 | 'bootloader --timeout=0 --append="console=ttyS0,115200n8"\n']) |
1376 | wks.flush() | 1411 | wks.flush() |
@@ -1390,7 +1425,7 @@ class Wic2(WicTestCase): | |||
1390 | 1425 | ||
1391 | img = 'core-image-minimal' | 1426 | img = 'core-image-minimal' |
1392 | with NamedTemporaryFile("w", suffix=".wks") as wks: | 1427 | with NamedTemporaryFile("w", suffix=".wks") as wks: |
1393 | wks.writelines(['part /boot --source bootimg-efi --sourceparams="loader=uefi-kernel"\n' | 1428 | wks.writelines(['part /boot --source bootimg_efi --sourceparams="loader=uefi-kernel"\n' |
1394 | 'part / --source rootfs --fstype=ext4 --align 1024 --use-uuid\n'\ | 1429 | 'part / --source rootfs --fstype=ext4 --align 1024 --use-uuid\n'\ |
1395 | 'bootloader --timeout=0 --append="console=ttyS0,115200n8"\n']) | 1430 | 'bootloader --timeout=0 --append="console=ttyS0,115200n8"\n']) |
1396 | wks.flush() | 1431 | wks.flush() |