summaryrefslogtreecommitdiffstats
path: root/meta/lib/oeqa/selftest
diff options
context:
space:
mode:
Diffstat (limited to 'meta/lib/oeqa/selftest')
-rw-r--r--meta/lib/oeqa/selftest/cases/archiver.py6
-rw-r--r--meta/lib/oeqa/selftest/cases/bblogging.py186
-rw-r--r--meta/lib/oeqa/selftest/cases/bbtests.py81
-rw-r--r--meta/lib/oeqa/selftest/cases/buildoptions.py42
-rw-r--r--meta/lib/oeqa/selftest/cases/containerimage.py6
-rw-r--r--meta/lib/oeqa/selftest/cases/devtool.py64
-rw-r--r--meta/lib/oeqa/selftest/cases/distrodata.py8
-rw-r--r--meta/lib/oeqa/selftest/cases/eSDK.py6
-rw-r--r--meta/lib/oeqa/selftest/cases/efibootpartition.py6
-rw-r--r--meta/lib/oeqa/selftest/cases/fetch.py12
-rw-r--r--meta/lib/oeqa/selftest/cases/fitimage.py29
-rw-r--r--meta/lib/oeqa/selftest/cases/glibc.py4
-rw-r--r--meta/lib/oeqa/selftest/cases/gotoolchain.py6
-rw-r--r--meta/lib/oeqa/selftest/cases/image_typedep.py4
-rw-r--r--meta/lib/oeqa/selftest/cases/imagefeatures.py10
-rw-r--r--meta/lib/oeqa/selftest/cases/incompatible_lic.py120
-rw-r--r--meta/lib/oeqa/selftest/cases/kerneldevelopment.py2
-rw-r--r--meta/lib/oeqa/selftest/cases/layerappend.py10
-rw-r--r--meta/lib/oeqa/selftest/cases/lic_checksum.py2
-rw-r--r--meta/lib/oeqa/selftest/cases/multiconfig.py6
-rw-r--r--meta/lib/oeqa/selftest/cases/newlib.py11
-rw-r--r--meta/lib/oeqa/selftest/cases/oelib/license.py22
-rw-r--r--meta/lib/oeqa/selftest/cases/oescripts.py4
-rw-r--r--meta/lib/oeqa/selftest/cases/overlayfs.py423
-rw-r--r--meta/lib/oeqa/selftest/cases/package.py8
-rw-r--r--meta/lib/oeqa/selftest/cases/prservice.py2
-rw-r--r--meta/lib/oeqa/selftest/cases/recipetool.py278
-rw-r--r--meta/lib/oeqa/selftest/cases/recipeutils.py8
-rw-r--r--meta/lib/oeqa/selftest/cases/reproducible.py31
-rw-r--r--meta/lib/oeqa/selftest/cases/runtime_test.py40
-rw-r--r--meta/lib/oeqa/selftest/cases/signing.py12
-rw-r--r--meta/lib/oeqa/selftest/cases/sstatetests.py111
-rw-r--r--meta/lib/oeqa/selftest/cases/sysroot.py8
-rw-r--r--meta/lib/oeqa/selftest/cases/tinfoil.py10
-rw-r--r--meta/lib/oeqa/selftest/cases/wic.py148
-rw-r--r--meta/lib/oeqa/selftest/context.py2
36 files changed, 1380 insertions, 348 deletions
diff --git a/meta/lib/oeqa/selftest/cases/archiver.py b/meta/lib/oeqa/selftest/cases/archiver.py
index 0194ae9f69..75195241b7 100644
--- a/meta/lib/oeqa/selftest/cases/archiver.py
+++ b/meta/lib/oeqa/selftest/cases/archiver.py
@@ -163,21 +163,21 @@ class Archiver(OESelftestTestCase):
Test that the archiver works with `ARCHIVER_MODE[src] = "patched"`.
"""
- self._test_archiver_mode('patched', 'selftest-ed-native-1.14.1-r0-patched.tar.gz')
+ self._test_archiver_mode('patched', 'selftest-ed-native-1.14.1-r0-patched.tar.xz')
def test_archiver_mode_configured(self):
"""
Test that the archiver works with `ARCHIVER_MODE[src] = "configured"`.
"""
- self._test_archiver_mode('configured', 'selftest-ed-native-1.14.1-r0-configured.tar.gz')
+ self._test_archiver_mode('configured', 'selftest-ed-native-1.14.1-r0-configured.tar.xz')
def test_archiver_mode_recipe(self):
"""
Test that the archiver works with `ARCHIVER_MODE[recipe] = "1"`.
"""
- self._test_archiver_mode('patched', 'selftest-ed-native-1.14.1-r0-recipe.tar.gz',
+ self._test_archiver_mode('patched', 'selftest-ed-native-1.14.1-r0-recipe.tar.xz',
'ARCHIVER_MODE[recipe] = "1"\n')
def test_archiver_mode_diff(self):
diff --git a/meta/lib/oeqa/selftest/cases/bblogging.py b/meta/lib/oeqa/selftest/cases/bblogging.py
new file mode 100644
index 0000000000..317e68b82f
--- /dev/null
+++ b/meta/lib/oeqa/selftest/cases/bblogging.py
@@ -0,0 +1,186 @@
+#
+# SPDX-License-Identifier: MIT
+#
+
+
+from oeqa.selftest.case import OESelftestTestCase
+from oeqa.utils.commands import bitbake
+
+class BitBakeLogging(OESelftestTestCase):
+
+ def assertCount(self, item, entry, count):
+ self.assertEqual(item.count(entry), count, msg="Output:\n'''\n%s\n'''\ndoesn't contain %d copies of:\n'''\n%s\n'''\n" % (item, count, entry))
+
+ def test_shell_loggingA(self):
+ # no logs, no verbose
+ self.write_config('BBINCLUDELOGS = ""')
+ result = bitbake("logging-test -c shelltest -f", ignore_status = True)
+ self.assertIn("ERROR: Logfile of failure stored in:", result.output)
+ self.assertNotIn("This is shell stdout", result.output)
+ self.assertNotIn("This is shell stderr", result.output)
+
+ def test_shell_loggingB(self):
+ # logs, no verbose
+ self.write_config('BBINCLUDELOGS = "yes"')
+ result = bitbake("logging-test -c shelltest -f", ignore_status = True)
+ self.assertIn("ERROR: Logfile of failure stored in:", result.output)
+ self.assertCount(result.output, "This is shell stdout", 1)
+ self.assertCount(result.output, "This is shell stderr", 1)
+
+ def test_shell_loggingC(self):
+ # no logs, verbose
+ self.write_config('BBINCLUDELOGS = ""')
+ result = bitbake("logging-test -c shelltest -f -v", ignore_status = True)
+ self.assertIn("ERROR: Logfile of failure stored in:", result.output)
+ # two copies due to set +x
+ self.assertCount(result.output, "This is shell stdout", 2)
+ self.assertCount(result.output, "This is shell stderr", 2)
+
+ def test_shell_loggingD(self):
+ # logs, verbose
+ self.write_config('BBINCLUDELOGS = "yes"')
+ result = bitbake("logging-test -c shelltest -f -v", ignore_status = True)
+ self.assertIn("ERROR: Logfile of failure stored in:", result.output)
+ # two copies due to set +x
+ self.assertCount(result.output, "This is shell stdout", 2)
+ self.assertCount(result.output, "This is shell stderr", 2)
+
+ def test_python_exec_func_shell_loggingA(self):
+ # no logs, no verbose
+ self.write_config('BBINCLUDELOGS = ""')
+ result = bitbake("logging-test -c pythontest_exec_func_shell -f",
+ ignore_status = True)
+ self.assertIn("ERROR: Logfile of failure stored in:", result.output)
+ self.assertNotIn("This is shell stdout", result.output)
+ self.assertNotIn("This is shell stderr", result.output)
+
+ def test_python_exec_func_shell_loggingB(self):
+ # logs, no verbose
+ self.write_config('BBINCLUDELOGS = "yes"')
+ result = bitbake("logging-test -c pythontest_exec_func_shell -f",
+ ignore_status = True)
+ self.assertIn("ERROR: Logfile of failure stored in:", result.output)
+ self.assertCount(result.output, "This is shell stdout", 1)
+ self.assertCount(result.output, "This is shell stderr", 1)
+
+ def test_python_exec_func_shell_loggingC(self):
+ # no logs, verbose
+ self.write_config('BBINCLUDELOGS = ""')
+ result = bitbake("logging-test -c pythontest_exec_func_shell -f -v",
+ ignore_status = True)
+ self.assertIn("ERROR: Logfile of failure stored in:", result.output)
+ # two copies due to set +x
+ self.assertCount(result.output, "This is shell stdout", 2)
+ self.assertCount(result.output, "This is shell stderr", 2)
+
+ def test_python_exec_func_shell_loggingD(self):
+ # logs, verbose
+ self.write_config('BBINCLUDELOGS = "yes"')
+ result = bitbake("logging-test -c pythontest_exec_func_shell -f -v",
+ ignore_status = True)
+ self.assertIn("ERROR: Logfile of failure stored in:", result.output)
+ # two copies due to set +x
+ self.assertCount(result.output, "This is shell stdout", 2)
+ self.assertCount(result.output, "This is shell stderr", 2)
+
+ def test_python_exit_loggingA(self):
+ # no logs, no verbose
+ self.write_config('BBINCLUDELOGS = ""')
+ result = bitbake("logging-test -c pythontest_exit -f", ignore_status = True)
+ self.assertIn("ERROR: Logfile of failure stored in:", result.output)
+ self.assertNotIn("This is python stdout", result.output)
+
+ def test_python_exit_loggingB(self):
+ # logs, no verbose
+ self.write_config('BBINCLUDELOGS = "yes"')
+ result = bitbake("logging-test -c pythontest_exit -f", ignore_status = True)
+ self.assertIn("ERROR: Logfile of failure stored in:", result.output)
+ # A sys.exit() should include the output
+ self.assertCount(result.output, "This is python stdout", 1)
+
+ def test_python_exit_loggingC(self):
+ # no logs, verbose
+ self.write_config('BBINCLUDELOGS = ""')
+ result = bitbake("logging-test -c pythontest_exit -f -v", ignore_status = True)
+ self.assertIn("ERROR: Logfile of failure stored in:", result.output)
+ # python tasks don't log output with -v currently
+ #self.assertCount(result.output, "This is python stdout", 1)
+
+ def test_python_exit_loggingD(self):
+ # logs, verbose
+ self.write_config('BBINCLUDELOGS = "yes"')
+ result = bitbake("logging-test -c pythontest_exit -f -v", ignore_status = True)
+ self.assertIn("ERROR: Logfile of failure stored in:", result.output)
+ # python tasks don't log output with -v currently
+ #self.assertCount(result.output, "This is python stdout", 1)
+
+ def test_python_exec_func_python_loggingA(self):
+ # no logs, no verbose
+ self.write_config('BBINCLUDELOGS = ""')
+ result = bitbake("logging-test -c pythontest_exec_func_python -f",
+ ignore_status = True)
+ self.assertIn("ERROR: Logfile of failure stored in:", result.output)
+ self.assertNotIn("This is python stdout", result.output)
+
+ def test_python_exec_func_python_loggingB(self):
+ # logs, no verbose
+ self.write_config('BBINCLUDELOGS = "yes"')
+ result = bitbake("logging-test -c pythontest_exec_func_python -f",
+ ignore_status = True)
+ self.assertIn("ERROR: Logfile of failure stored in:", result.output)
+ # A sys.exit() should include the output
+ self.assertCount(result.output, "This is python stdout", 1)
+
+ def test_python_exec_func_python_loggingC(self):
+ # no logs, verbose
+ self.write_config('BBINCLUDELOGS = ""')
+ result = bitbake("logging-test -c pythontest_exec_func_python -f -v",
+ ignore_status = True)
+ self.assertIn("ERROR: Logfile of failure stored in:", result.output)
+ # python tasks don't log output with -v currently
+ #self.assertCount(result.output, "This is python stdout", 1)
+
+ def test_python_exec_func_python_loggingD(self):
+ # logs, verbose
+ self.write_config('BBINCLUDELOGS = "yes"')
+ result = bitbake("logging-test -c pythontest_exec_func_python -f -v",
+ ignore_status = True)
+ self.assertIn("ERROR: Logfile of failure stored in:", result.output)
+ # python tasks don't log output with -v currently
+ #self.assertCount(result.output, "This is python stdout", 1)
+
+ def test_python_fatal_loggingA(self):
+ # no logs, no verbose
+ self.write_config('BBINCLUDELOGS = ""')
+ result = bitbake("logging-test -c pythontest_fatal -f", ignore_status = True)
+ self.assertIn("ERROR: Logfile of failure stored in:", result.output)
+ self.assertNotIn("This is python fatal test stdout", result.output)
+ self.assertCount(result.output, "This is a fatal error", 1)
+
+ def test_python_fatal_loggingB(self):
+ # logs, no verbose
+ self.write_config('BBINCLUDELOGS = "yes"')
+ result = bitbake("logging-test -c pythontest_fatal -f", ignore_status = True)
+ self.assertIn("ERROR: Logfile of failure stored in:", result.output)
+ # A bb.fatal() should not include the output
+ self.assertNotIn("This is python fatal test stdout", result.output)
+ self.assertCount(result.output, "This is a fatal error", 1)
+
+ def test_python_fatal_loggingC(self):
+ # no logs, verbose
+ self.write_config('BBINCLUDELOGS = ""')
+ result = bitbake("logging-test -c pythontest_fatal -f -v", ignore_status = True)
+ self.assertIn("ERROR: Logfile of failure stored in:", result.output)
+ # python tasks don't log output with -v currently
+ #self.assertCount(result.output, "This is python fatal test stdout", 1)
+ self.assertCount(result.output, "This is a fatal error", 1)
+
+ def test_python_fatal_loggingD(self):
+ # logs, verbose
+ self.write_config('BBINCLUDELOGS = "yes"')
+ result = bitbake("logging-test -c pythontest_fatal -f -v", ignore_status = True)
+ self.assertIn("ERROR: Logfile of failure stored in:", result.output)
+ # python tasks don't log output with -v currently
+ #self.assertCount(result.output, "This is python fatal test stdout", 1)
+ self.assertCount(result.output, "This is a fatal error", 1)
+
diff --git a/meta/lib/oeqa/selftest/cases/bbtests.py b/meta/lib/oeqa/selftest/cases/bbtests.py
index 79390acc0d..cfac7afcf4 100644
--- a/meta/lib/oeqa/selftest/cases/bbtests.py
+++ b/meta/lib/oeqa/selftest/cases/bbtests.py
@@ -63,15 +63,15 @@ class BitbakeTests(OESelftestTestCase):
def test_warnings_errors(self):
result = bitbake('-b asdf', ignore_status=True)
- find_warnings = re.search("Summary: There w.{2,3}? [1-9][0-9]* WARNING messages* shown", result.output)
- find_errors = re.search("Summary: There w.{2,3}? [1-9][0-9]* ERROR messages* shown", result.output)
+ find_warnings = re.search("Summary: There w.{2,3}? [1-9][0-9]* WARNING messages*", result.output)
+ find_errors = re.search("Summary: There w.{2,3}? [1-9][0-9]* ERROR messages*", result.output)
self.assertTrue(find_warnings, msg="Did not find the mumber of warnings at the end of the build:\n" + result.output)
self.assertTrue(find_errors, msg="Did not find the mumber of errors at the end of the build:\n" + result.output)
def test_invalid_patch(self):
# This patch should fail to apply.
- self.write_recipeinc('man-db', 'FILESEXTRAPATHS_prepend := "${THISDIR}/files:"\nSRC_URI += "file://0001-Test-patch-here.patch"')
- self.write_config("INHERIT_remove = \"report-error\"")
+ self.write_recipeinc('man-db', 'FILESEXTRAPATHS:prepend := "${THISDIR}/files:"\nSRC_URI += "file://0001-Test-patch-here.patch"')
+ self.write_config("INHERIT:remove = \"report-error\"")
result = bitbake('man-db -c patch', ignore_status=True)
self.delete_recipeinc('man-db')
bitbake('-cclean man-db')
@@ -83,8 +83,10 @@ class BitbakeTests(OESelftestTestCase):
def test_force_task_1(self):
# test 1 from bug 5875
+ import uuid
test_recipe = 'zlib'
- test_data = "Microsoft Made No Profit From Anyone's Zunes Yo"
+ # Need to use uuid otherwise hash equivlance would change the workflow
+ test_data = "Microsoft Made No Profit From Anyone's Zunes Yo %s" % uuid.uuid1()
bb_vars = get_bb_vars(['D', 'PKGDEST', 'mandir'], test_recipe)
image_dir = bb_vars['D']
pkgsplit_dir = bb_vars['PKGDEST']
@@ -139,7 +141,7 @@ class BitbakeTests(OESelftestTestCase):
self.write_recipeinc('man-db', data)
self.write_config("""DL_DIR = \"${TOPDIR}/download-selftest\"
SSTATE_DIR = \"${TOPDIR}/download-selftest\"
-INHERIT_remove = \"report-error\"
+INHERIT:remove = \"report-error\"
""")
self.track_for_cleanup(os.path.join(self.builddir, "download-selftest"))
@@ -149,9 +151,6 @@ INHERIT_remove = \"report-error\"
self.delete_recipeinc('man-db')
self.assertEqual(result.status, 1, msg="Command succeded when it should have failed. bitbake output: %s" % result.output)
self.assertIn('Fetcher failure: Unable to find file file://invalid anywhere. The paths that were searched were:', result.output)
- line = self.getline(result, 'Fetcher failure for URL: \'file://invalid\'. Unable to fetch URL from any source.')
- self.assertTrue(line and line.startswith("ERROR:"), msg = "\"invalid\" file \
-doesn't exist, yet fetcher didn't report any error. bitbake output: %s" % result.output)
def test_rename_downloaded_file(self):
# TODO unique dldir instead of using cleanall
@@ -161,7 +160,7 @@ SSTATE_DIR = \"${TOPDIR}/download-selftest\"
""")
self.track_for_cleanup(os.path.join(self.builddir, "download-selftest"))
- data = 'SRC_URI = "${GNU_MIRROR}/aspell/aspell-${PV}.tar.gz;downloadfilename=test-aspell.tar.gz"'
+ data = 'SRC_URI = "https://downloads.yoctoproject.org/mirror/sources/aspell-${PV}.tar.gz;downloadfilename=test-aspell.tar.gz"'
self.write_recipeinc('aspell', data)
result = bitbake('-f -c fetch aspell', ignore_status=True)
self.delete_recipeinc('aspell')
@@ -213,7 +212,7 @@ SSTATE_DIR = \"${TOPDIR}/download-selftest\"
def test_continue(self):
self.write_config("""DL_DIR = \"${TOPDIR}/download-selftest\"
SSTATE_DIR = \"${TOPDIR}/download-selftest\"
-INHERIT_remove = \"report-error\"
+INHERIT:remove = \"report-error\"
""")
self.track_for_cleanup(os.path.join(self.builddir, "download-selftest"))
self.write_recipeinc('man-db',"\ndo_fail_task () {\nexit 1 \n}\n\naddtask do_fail_task before do_fetch\n" )
@@ -225,12 +224,12 @@ INHERIT_remove = \"report-error\"
self.assertLess(errorpos,continuepos, msg = "bitbake didn't pass do_fail_task. bitbake output: %s" % result.output)
def test_non_gplv3(self):
- self.write_config('INCOMPATIBLE_LICENSE = "GPLv3"')
+ self.write_config('INCOMPATIBLE_LICENSE = "GPL-3.0-or-later"')
result = bitbake('selftest-ed', ignore_status=True)
self.assertEqual(result.status, 0, "Bitbake failed, exit code %s, output %s" % (result.status, result.output))
lic_dir = get_bb_var('LICENSE_DIRECTORY')
- self.assertFalse(os.path.isfile(os.path.join(lic_dir, 'selftest-ed/generic_GPLv3')))
- self.assertTrue(os.path.isfile(os.path.join(lic_dir, 'selftest-ed/generic_GPLv2')))
+ self.assertFalse(os.path.isfile(os.path.join(lic_dir, 'selftest-ed/generic_GPL-3.0-or-later')))
+ self.assertTrue(os.path.isfile(os.path.join(lic_dir, 'selftest-ed/generic_GPL-2.0-or-later')))
def test_setscene_only(self):
""" Bitbake option to restore from sstate only within a build (i.e. execute no real tasks, only setscene)"""
@@ -298,3 +297,57 @@ INHERIT_remove = \"report-error\"
test_recipe_summary_after = get_bb_var('SUMMARY', test_recipe)
self.assertEqual(expected_recipe_summary, test_recipe_summary_after)
+
+ def test_git_patchtool(self):
+ """ PATCHTOOL=git should work with non-git sources like tarballs
+ test recipe for the test must NOT containt git:// repository in SRC_URI
+ """
+ test_recipe = "man-db"
+ self.write_recipeinc(test_recipe, 'PATCHTOOL=\"git\"')
+ src = get_bb_var("SRC_URI",test_recipe)
+ gitscm = re.search("git://", src)
+ self.assertFalse(gitscm, "test_git_patchtool pre-condition failed: {} test recipe contains git repo!".format(test_recipe))
+ result = bitbake('{} -c patch'.format(test_recipe), ignore_status=False)
+ fatal = re.search("fatal: not a git repository (or any of the parent directories)", result.output)
+ self.assertFalse(fatal, "Failed to patch using PATCHTOOL=\"git\"")
+ self.delete_recipeinc(test_recipe)
+ bitbake('-cclean {}'.format(test_recipe))
+
+ def test_git_patchtool2(self):
+ """ Test if PATCHTOOL=git works with git repo and doesn't reinitialize it
+ """
+ test_recipe = "gitrepotest"
+ src = get_bb_var("SRC_URI",test_recipe)
+ gitscm = re.search("git://", src)
+ self.assertTrue(gitscm, "test_git_patchtool pre-condition failed: {} test recipe doesn't contains git repo!".format(test_recipe))
+ result = bitbake('{} -c patch'.format(test_recipe), ignore_status=False)
+ srcdir = get_bb_var('S', test_recipe)
+ result = runCmd("git log", cwd = srcdir)
+ self.assertFalse("bitbake_patching_started" in result.output, msg = "Repository has been reinitialized. {}".format(srcdir))
+ self.delete_recipeinc(test_recipe)
+ bitbake('-cclean {}'.format(test_recipe))
+
+
+ def test_git_unpack_nonetwork(self):
+ """
+ Test that a recipe with a floating tag that needs to be resolved upstream doesn't
+ access the network in a patch task run in a separate builld invocation
+ """
+
+ # Enable the recipe to float using a distro override
+ self.write_config("DISTROOVERRIDES .= \":gitunpack-enable-recipe\"")
+
+ bitbake('gitunpackoffline -c fetch')
+ bitbake('gitunpackoffline -c patch')
+
+ def test_git_unpack_nonetwork_fail(self):
+ """
+ Test that a recipe with a floating tag which doesn't call get_srcrev() in the fetcher
+ raises an error when the fetcher is called.
+ """
+
+ # Enable the recipe to float using a distro override
+ self.write_config("DISTROOVERRIDES .= \":gitunpack-enable-recipe\"")
+
+ result = bitbake('gitunpackoffline-fail -c fetch', ignore_status=True)
+ self.assertTrue("Recipe uses a floating tag/branch without a fixed SRCREV" in result.output, msg = "Recipe without PV set to SRCPV should have failed: %s" % result.output)
diff --git a/meta/lib/oeqa/selftest/cases/buildoptions.py b/meta/lib/oeqa/selftest/cases/buildoptions.py
index 754b77defd..bfe613b847 100644
--- a/meta/lib/oeqa/selftest/cases/buildoptions.py
+++ b/meta/lib/oeqa/selftest/cases/buildoptions.py
@@ -62,9 +62,9 @@ class DiskMonTest(OESelftestTestCase):
res = bitbake("delay -c delay", ignore_status = True)
self.assertTrue('ERROR: No new tasks can be executed since the disk space monitor action is "STOPTASKS"!' in res.output, msg = "Tasks should have stopped. Disk monitor is set to STOPTASK: %s" % res.output)
self.assertEqual(res.status, 1, msg = "bitbake reported exit code %s. It should have been 1. Bitbake output: %s" % (str(res.status), res.output))
- self.write_config('BB_DISKMON_DIRS = "ABORT,${TMPDIR},100000G,100K"\nBB_HEARTBEAT_EVENT = "1"')
+ self.write_config('BB_DISKMON_DIRS = "HALT,${TMPDIR},100000G,100K"\nBB_HEARTBEAT_EVENT = "1"')
res = bitbake("delay -c delay", ignore_status = True)
- self.assertTrue('ERROR: Immediately abort since the disk space monitor action is "ABORT"!' in res.output, "Tasks should have been aborted immediatelly. Disk monitor is set to ABORT: %s" % res.output)
+ self.assertTrue('ERROR: Immediately halt since the disk space monitor action is "HALT"!' in res.output, "Tasks should have been halted immediately. Disk monitor is set to HALT: %s" % res.output)
self.assertEqual(res.status, 1, msg = "bitbake reported exit code %s. It should have been 1. Bitbake output: %s" % (str(res.status), res.output))
self.write_config('BB_DISKMON_DIRS = "WARN,${TMPDIR},100000G,100K"\nBB_HEARTBEAT_EVENT = "1"')
res = bitbake("delay -c delay")
@@ -78,9 +78,9 @@ class SanityOptionsTest(OESelftestTestCase):
def test_options_warnqa_errorqa_switch(self):
- self.write_config("INHERIT_remove = \"report-error\"")
+ self.write_config("INHERIT:remove = \"report-error\"")
if "packages-list" not in get_bb_var("ERROR_QA"):
- self.append_config("ERROR_QA_append = \" packages-list\"")
+ self.append_config("ERROR_QA:append = \" packages-list\"")
self.write_recipeinc('xcursor-transparent-theme', 'PACKAGES += \"${PN}-dbg\"')
self.add_command_to_tearDown('bitbake -c clean xcursor-transparent-theme')
@@ -90,8 +90,8 @@ class SanityOptionsTest(OESelftestTestCase):
self.assertTrue(line and line.startswith("ERROR:"), msg=res.output)
self.assertEqual(res.status, 1, msg = "bitbake reported exit code %s. It should have been 1. Bitbake output: %s" % (str(res.status), res.output))
self.write_recipeinc('xcursor-transparent-theme', 'PACKAGES += \"${PN}-dbg\"')
- self.append_config('ERROR_QA_remove = "packages-list"')
- self.append_config('WARN_QA_append = " packages-list"')
+ self.append_config('ERROR_QA:remove = "packages-list"')
+ self.append_config('WARN_QA:append = " packages-list"')
res = bitbake("xcursor-transparent-theme -f -c package")
self.delete_recipeinc('xcursor-transparent-theme')
line = self.getline(res, "QA Issue: xcursor-transparent-theme-dbg is listed in PACKAGES multiple times, this leads to packaging errors.")
@@ -148,6 +148,30 @@ class BuildhistoryTests(BuildhistoryBase):
self.run_buildhistory_operation(target, target_config="PR = \"r1\"", change_bh_location=True)
self.run_buildhistory_operation(target, target_config="PR = \"r0\"", change_bh_location=False, expect_error=True, error_regex=error)
+ def test_fileinfo(self):
+ self.config_buildhistory()
+ bitbake('hicolor-icon-theme')
+ history_dir = get_bb_var('BUILDHISTORY_DIR_PACKAGE', 'hicolor-icon-theme')
+ self.assertTrue(os.path.isdir(history_dir), 'buildhistory dir was not created.')
+
+ def load_bh(f):
+ d = {}
+ for line in open(f):
+ split = [s.strip() for s in line.split('=', 1)]
+ if len(split) > 1:
+ d[split[0]] = split[1]
+ return d
+
+ data = load_bh(os.path.join(history_dir, 'hicolor-icon-theme', 'latest'))
+ self.assertIn('FILELIST', data)
+ self.assertEqual(data['FILELIST'], '/usr/share/icons/hicolor/index.theme')
+ self.assertGreater(int(data['PKGSIZE']), 0)
+
+ data = load_bh(os.path.join(history_dir, 'hicolor-icon-theme-dev', 'latest'))
+ if 'FILELIST' in data:
+ self.assertEqual(data['FILELIST'], '')
+ self.assertEqual(int(data['PKGSIZE']), 0)
+
class ArchiverTest(OESelftestTestCase):
def test_arch_work_dir_and_export_source(self):
"""
@@ -159,8 +183,8 @@ class ArchiverTest(OESelftestTestCase):
deploy_dir_src = get_bb_var('DEPLOY_DIR_SRC')
pkgs_path = g.glob(str(deploy_dir_src) + "/allarch*/xcurs*")
src_file_glob = str(pkgs_path[0]) + "/xcursor*.src.rpm"
- tar_file_glob = str(pkgs_path[0]) + "/xcursor*.tar.gz"
- self.assertTrue((g.glob(src_file_glob) and g.glob(tar_file_glob)), "Couldn't find .src.rpm and .tar.gz files under %s/allarch*/xcursor*" % deploy_dir_src)
+ tar_file_glob = str(pkgs_path[0]) + "/xcursor*.tar.xz"
+ self.assertTrue((g.glob(src_file_glob) and g.glob(tar_file_glob)), "Couldn't find .src.rpm and .tar.xz files under %s/allarch*/xcursor*" % deploy_dir_src)
class ToolchainOptions(OESelftestTestCase):
def test_toolchain_fortran(self):
@@ -168,7 +192,7 @@ class ToolchainOptions(OESelftestTestCase):
Test that Fortran works by building a Hello, World binary.
"""
- features = 'FORTRAN_forcevariable = ",fortran"\n'
+ features = 'FORTRAN:forcevariable = ",fortran"\n'
self.write_config(features)
bitbake('fortran-helloworld')
diff --git a/meta/lib/oeqa/selftest/cases/containerimage.py b/meta/lib/oeqa/selftest/cases/containerimage.py
index 79cc8a0f2e..e0aea1a1ef 100644
--- a/meta/lib/oeqa/selftest/cases/containerimage.py
+++ b/meta/lib/oeqa/selftest/cases/containerimage.py
@@ -13,7 +13,7 @@ from oeqa.utils.commands import bitbake, get_bb_vars, runCmd
# The only package added to the image is container_image_testpkg, which
# contains one file. However, due to some other things not cleaning up during
# rootfs creation, there is some cruft. Ideally bugs will be filed and the
-# cruft removed, but for now we whitelist some known set.
+# cruft removed, but for now we ignore some known set.
#
# Also for performance reasons we're only checking the cruft when using ipk.
# When using deb, and rpm it is a bit different and we could test all
@@ -22,7 +22,7 @@ from oeqa.utils.commands import bitbake, get_bb_vars, runCmd
#
class ContainerImageTests(OESelftestTestCase):
- # Verify that when specifying a IMAGE_TYPEDEP_ of the form "foo.bar" that
+ # Verify that when specifying a IMAGE_TYPEDEP: of the form "foo.bar" that
# the conversion type bar gets added as a dep as well
def test_expected_files(self):
@@ -43,7 +43,7 @@ PACKAGE_CLASSES = "package_ipk"
IMAGE_FEATURES = ""
IMAGE_BUILDINFO_FILE = ""
INIT_MANAGER = "sysvinit"
-IMAGE_INSTALL_remove = "ssh-pregen-hostkeys"
+IMAGE_INSTALL:remove = "ssh-pregen-hostkeys"
""")
diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py
index 3385546e8e..e910672c31 100644
--- a/meta/lib/oeqa/selftest/cases/devtool.py
+++ b/meta/lib/oeqa/selftest/cases/devtool.py
@@ -80,32 +80,15 @@ def tearDownModule():
bb.utils.edit_bblayers_conf(bblayers_conf, None, None, bblayers_edit_cb)
shutil.rmtree(templayerdir)
-class DevtoolBase(OESelftestTestCase):
-
- @classmethod
- def setUpClass(cls):
- super(DevtoolBase, cls).setUpClass()
- bb_vars = get_bb_vars(['TOPDIR', 'SSTATE_DIR'])
- cls.original_sstate = bb_vars['SSTATE_DIR']
- cls.devtool_sstate = os.path.join(bb_vars['TOPDIR'], 'sstate_devtool')
- cls.sstate_conf = 'SSTATE_DIR = "%s"\n' % cls.devtool_sstate
- cls.sstate_conf += ('SSTATE_MIRRORS += "file://.* file:///%s/PATH"\n'
- % cls.original_sstate)
-
- @classmethod
- def tearDownClass(cls):
- cls.logger.debug('Deleting devtool sstate cache on %s' % cls.devtool_sstate)
- runCmd('rm -rf %s' % cls.devtool_sstate)
- super(DevtoolBase, cls).tearDownClass()
+class DevtoolTestCase(OESelftestTestCase):
def setUp(self):
"""Test case setup function"""
- super(DevtoolBase, self).setUp()
+ super(DevtoolTestCase, self).setUp()
self.workspacedir = os.path.join(self.builddir, 'workspace')
self.assertTrue(not os.path.exists(self.workspacedir),
'This test cannot be run with a workspace directory '
'under the build directory')
- self.append_config(self.sstate_conf)
def _check_src_repo(self, repo_dir):
"""Check srctree git repository"""
@@ -236,6 +219,30 @@ class DevtoolBase(OESelftestTestCase):
return filelist
+class DevtoolBase(DevtoolTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ super(DevtoolBase, cls).setUpClass()
+ bb_vars = get_bb_vars(['TOPDIR', 'SSTATE_DIR'])
+ cls.original_sstate = bb_vars['SSTATE_DIR']
+ cls.devtool_sstate = os.path.join(bb_vars['TOPDIR'], 'sstate_devtool')
+ cls.sstate_conf = 'SSTATE_DIR = "%s"\n' % cls.devtool_sstate
+ cls.sstate_conf += ('SSTATE_MIRRORS += "file://.* file:///%s/PATH"\n'
+ % cls.original_sstate)
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.logger.debug('Deleting devtool sstate cache on %s' % cls.devtool_sstate)
+ runCmd('rm -rf %s' % cls.devtool_sstate)
+ super(DevtoolBase, cls).tearDownClass()
+
+ def setUp(self):
+ """Test case setup function"""
+ super(DevtoolBase, self).setUp()
+ self.append_config(self.sstate_conf)
+
+
class DevtoolTests(DevtoolBase):
def test_create_workspace(self):
@@ -336,11 +343,11 @@ class DevtoolAddTests(DevtoolBase):
self.assertIn(srcdir, result.output)
self.assertIn(recipefile, result.output)
checkvars = {}
- checkvars['LICENSE'] = 'GPLv2'
+ checkvars['LICENSE'] = 'GPL-2.0-only'
checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263'
checkvars['S'] = '${WORKDIR}/git'
checkvars['PV'] = '0.1+git${SRCPV}'
- checkvars['SRC_URI'] = 'git://git.yoctoproject.org/git/dbus-wait;protocol=https'
+ checkvars['SRC_URI'] = 'git://git.yoctoproject.org/git/dbus-wait;protocol=https;branch=master'
checkvars['SRCREV'] = srcrev
checkvars['DEPENDS'] = set(['dbus'])
self._test_recipe_contents(recipefile, checkvars, [])
@@ -373,7 +380,7 @@ class DevtoolAddTests(DevtoolBase):
recipefile = '%s/recipes/libftdi/libftdi_%s.bb' % (self.workspacedir, version)
result = runCmd('recipetool setvar %s EXTRA_OECMAKE -- \'-DPYTHON_BINDINGS=OFF -DLIBFTDI_CMAKE_CONFIG_DIR=${datadir}/cmake/Modules\'' % recipefile)
with open(recipefile, 'a') as f:
- f.write('\nFILES_${PN}-dev += "${datadir}/cmake/Modules"\n')
+ f.write('\nFILES:${PN}-dev += "${datadir}/cmake/Modules"\n')
# We don't have the ability to pick up this dependency automatically yet...
f.write('\nDEPENDS += "libusb1"\n')
f.write('\nTESTLIBOUTPUT = "${COMPONENTS_DIR}/${TUNE_PKGARCH}/${PN}/${libdir}"\n')
@@ -442,6 +449,7 @@ class DevtoolAddTests(DevtoolBase):
tempdir = tempfile.mkdtemp(prefix='devtoolqa')
self.track_for_cleanup(tempdir)
url = 'gitsm://git.yoctoproject.org/mraa'
+ url_branch = '%s;branch=master' % url
checkrev = 'ae127b19a50aa54255e4330ccfdd9a5d058e581d'
testrecipe = 'mraa'
srcdir = os.path.join(tempdir, testrecipe)
@@ -462,7 +470,7 @@ class DevtoolAddTests(DevtoolBase):
checkvars = {}
checkvars['S'] = '${WORKDIR}/git'
checkvars['PV'] = '1.0+git${SRCPV}'
- checkvars['SRC_URI'] = url
+ checkvars['SRC_URI'] = url_branch
checkvars['SRCREV'] = '${AUTOREV}'
self._test_recipe_contents(recipefile, checkvars, [])
# Try with revision and version specified
@@ -481,7 +489,7 @@ class DevtoolAddTests(DevtoolBase):
checkvars = {}
checkvars['S'] = '${WORKDIR}/git'
checkvars['PV'] = '1.5+git${SRCPV}'
- checkvars['SRC_URI'] = url
+ checkvars['SRC_URI'] = url_branch
checkvars['SRCREV'] = checkrev
self._test_recipe_contents(recipefile, checkvars, [])
@@ -649,7 +657,7 @@ class DevtoolModifyTests(DevtoolBase):
self.track_for_cleanup(self.workspacedir)
self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
- testrecipes = 'perf kernel-devsrc package-index core-image-minimal meta-toolchain packagegroup-core-sdk meta-ide-support'.split()
+ testrecipes = 'perf kernel-devsrc package-index core-image-minimal meta-toolchain packagegroup-core-sdk'.split()
# Find actual name of gcc-source since it now includes the version - crude, but good enough for this purpose
result = runCmd('bitbake-layers show-recipes gcc-source*')
for line in result.output.splitlines():
@@ -904,7 +912,7 @@ class DevtoolUpdateTests(DevtoolBase):
self._check_repo_status(os.path.dirname(recipefile), expected_status)
result = runCmd('git diff %s' % os.path.basename(recipefile), cwd=os.path.dirname(recipefile))
- addlines = ['SRCREV = ".*"', 'SRC_URI = "git://git.infradead.org/mtd-utils.git"']
+ addlines = ['SRCREV = ".*"', 'SRC_URI = "git://git.infradead.org/mtd-utils.git;branch=master"']
srcurilines = src_uri.split()
srcurilines[0] = 'SRC_URI = "' + srcurilines[0]
srcurilines.append('"')
@@ -975,7 +983,7 @@ class DevtoolUpdateTests(DevtoolBase):
self.assertExists(patchfile, 'Patch file not created')
# Check bbappend contents
- expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
'\n',
'SRC_URI += "file://0001-Add-our-custom-version.patch"\n',
'\n']
@@ -990,7 +998,7 @@ class DevtoolUpdateTests(DevtoolBase):
result = runCmd('git reset HEAD^', cwd=tempsrcdir)
result = runCmd('devtool update-recipe %s -a %s' % (testrecipe, templayerdir))
self.assertNotExists(patchfile, 'Patch file not deleted')
- expectedlines2 = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ expectedlines2 = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
'\n']
with open(bbappendfile, 'r') as f:
self.assertEqual(expectedlines2, f.readlines())
diff --git a/meta/lib/oeqa/selftest/cases/distrodata.py b/meta/lib/oeqa/selftest/cases/distrodata.py
index 0ad6e1ef91..03f31e9fcb 100644
--- a/meta/lib/oeqa/selftest/cases/distrodata.py
+++ b/meta/lib/oeqa/selftest/cases/distrodata.py
@@ -18,7 +18,7 @@ class Distrodata(OESelftestTestCase):
Product: oe-core
Author: Alexander Kanavin <alex.kanavin@gmail.com>
"""
- feature = 'LICENSE_FLAGS_WHITELIST += " commercial"\n'
+ feature = 'LICENSE_FLAGS_ACCEPTED += " commercial"\n'
self.write_config(feature)
pkgs = oe.recipeutils.get_recipe_upgrade_status()
@@ -93,13 +93,13 @@ The following recipes do not have a DESCRIPTION. Please add an entry for DESCRIP
def is_maintainer_exception(entry):
exceptions = ["musl", "newlib", "linux-yocto", "linux-dummy", "mesa-gl", "libgfortran",
- "cve-update-db-native"]
+ "cve-update-db-native", "rust"]
for i in exceptions:
if i in entry:
return True
return False
- feature = 'require conf/distro/include/maintainers.inc\nLICENSE_FLAGS_WHITELIST += " commercial"\nPARSE_ALL_RECIPES = "1"\nPACKAGE_CLASSES = "package_ipk package_deb package_rpm"\n'
+ feature = 'require conf/distro/include/maintainers.inc\nLICENSE_FLAGS_ACCEPTED += " commercial"\nPARSE_ALL_RECIPES = "1"\nPACKAGE_CLASSES = "package_ipk package_deb package_rpm"\n'
self.write_config(feature)
with bb.tinfoil.Tinfoil() as tinfoil:
@@ -110,7 +110,7 @@ The following recipes do not have a DESCRIPTION. Please add an entry for DESCRIP
missing_recipes = []
recipes = []
- prefix = "RECIPE_MAINTAINER_pn-"
+ prefix = "RECIPE_MAINTAINER:pn-"
# We could have used all_recipes() here, but this method will find
# every recipe if we ever move to setting RECIPE_MAINTAINER in recipe files
diff --git a/meta/lib/oeqa/selftest/cases/eSDK.py b/meta/lib/oeqa/selftest/cases/eSDK.py
index 862849af35..f7279b3230 100644
--- a/meta/lib/oeqa/selftest/cases/eSDK.py
+++ b/meta/lib/oeqa/selftest/cases/eSDK.py
@@ -63,7 +63,7 @@ class oeSDKExtSelfTest(OESelftestTestCase):
cls.env_eSDK = oeSDKExtSelfTest.get_esdk_environment('', cls.tmpdir_eSDKQA)
sstate_config="""
-SDK_LOCAL_CONF_WHITELIST = "SSTATE_MIRRORS"
+ESDK_LOCALCONF_ALLOW = "SSTATE_MIRRORS"
SSTATE_MIRRORS = "file://.* file://%s/PATH"
CORE_IMAGE_EXTRA_INSTALL = "perl"
""" % sstate_dir
@@ -91,7 +91,7 @@ CORE_IMAGE_EXTRA_INSTALL = "perl"
# Configure eSDK to use sstate mirror from poky
sstate_config="""
-SDK_LOCAL_CONF_WHITELIST = "SSTATE_MIRRORS"
+ESDK_LOCALCONF_ALLOW = "SSTATE_MIRRORS"
SSTATE_MIRRORS = "file://.* file://%s/PATH"
""" % bb_vars["SSTATE_DIR"]
with open(os.path.join(cls.tmpdir_eSDKQA, 'conf', 'local.conf'), 'a+') as f:
@@ -100,7 +100,7 @@ SSTATE_MIRRORS = "file://.* file://%s/PATH"
@classmethod
def tearDownClass(cls):
for i in range(0, 10):
- if os.path.exists(os.path.join(cls.tmpdir_eSDKQA, 'bitbake.lock')):
+ if os.path.exists(os.path.join(cls.tmpdir_eSDKQA, 'bitbake.lock')) or os.path.exists(os.path.join(cls.tmpdir_eSDKQA, 'cache/hashserv.db-wal')):
time.sleep(1)
else:
break
diff --git a/meta/lib/oeqa/selftest/cases/efibootpartition.py b/meta/lib/oeqa/selftest/cases/efibootpartition.py
index a61cf9bcb3..26de3a07c9 100644
--- a/meta/lib/oeqa/selftest/cases/efibootpartition.py
+++ b/meta/lib/oeqa/selftest/cases/efibootpartition.py
@@ -26,11 +26,11 @@ class GenericEFITest(OESelftestTestCase):
self.write_config(self,
"""
EFI_PROVIDER = "%s"
-IMAGE_FSTYPES_pn-%s_append = " wic"
+IMAGE_FSTYPES:pn-%s:append = " wic"
MACHINE = "%s"
-MACHINE_FEATURES_append = " efi"
+MACHINE_FEATURES:append = " efi"
WKS_FILE = "efi-bootdisk.wks.in"
-IMAGE_INSTALL_append = " grub-efi systemd-boot kernel-image-bzimage"
+IMAGE_INSTALL:append = " grub-efi systemd-boot kernel-image-bzimage"
"""
% (self.efi_provider, self.image, self.machine))
if not self.recipes_built:
diff --git a/meta/lib/oeqa/selftest/cases/fetch.py b/meta/lib/oeqa/selftest/cases/fetch.py
index cd15f65129..be14272e63 100644
--- a/meta/lib/oeqa/selftest/cases/fetch.py
+++ b/meta/lib/oeqa/selftest/cases/fetch.py
@@ -24,8 +24,8 @@ class Fetch(OESelftestTestCase):
# No mirrors, should use git to fetch successfully
features = """
DL_DIR = "%s"
-MIRRORS_forcevariable = ""
-PREMIRRORS_forcevariable = ""
+MIRRORS:forcevariable = ""
+PREMIRRORS:forcevariable = ""
""" % dldir
self.write_config(features)
oe.path.remove(dldir, recurse=True)
@@ -35,8 +35,8 @@ PREMIRRORS_forcevariable = ""
features = """
DL_DIR = "%s"
GIT_PROXY_COMMAND = "false"
-MIRRORS_forcevariable = ""
-PREMIRRORS_forcevariable = ""
+MIRRORS:forcevariable = ""
+PREMIRRORS:forcevariable = ""
""" % dldir
self.write_config(features)
oe.path.remove(dldir, recurse=True)
@@ -47,7 +47,7 @@ PREMIRRORS_forcevariable = ""
features = """
DL_DIR = "%s"
GIT_PROXY_COMMAND = "false"
-MIRRORS_forcevariable = "git://.*/.* http://downloads.yoctoproject.org/mirror/sources/"
+MIRRORS:forcevariable = "git://.*/.* http://downloads.yoctoproject.org/mirror/sources/"
""" % dldir
self.write_config(features)
oe.path.remove(dldir, recurse=True)
@@ -99,7 +99,7 @@ class Dependencies(OESelftestTestCase):
r = """
LICENSE="CLOSED"
- SRC_URI="git://example.com/repo"
+ SRC_URI="git://example.com/repo;branch=master"
"""
f = self.write_recipe(textwrap.dedent(r), tempdir)
d = tinfoil.parse_recipe_file(f)
diff --git a/meta/lib/oeqa/selftest/cases/fitimage.py b/meta/lib/oeqa/selftest/cases/fitimage.py
index 815ee48c05..f6f6a8e795 100644
--- a/meta/lib/oeqa/selftest/cases/fitimage.py
+++ b/meta/lib/oeqa/selftest/cases/fitimage.py
@@ -114,7 +114,8 @@ KERNEL_CLASSES = " kernel-fitimage test-mkimage-wrapper "
UBOOT_SIGN_ENABLE = "1"
FIT_GENERATE_KEYS = "1"
UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys"
-UBOOT_SIGN_KEYNAME = "oe-selftest"
+UBOOT_SIGN_IMG_KEYNAME = "img-oe-selftest"
+UBOOT_SIGN_KEYNAME = "cfg-oe-selftest"
FIT_SIGN_INDIVIDUAL = "1"
UBOOT_MKIMAGE_SIGN_ARGS = "-c 'a smart comment'"
"""
@@ -173,11 +174,11 @@ UBOOT_MKIMAGE_SIGN_ARGS = "-c 'a smart comment'"
reqsigvalues_image = {
'algo': '"sha256,rsa2048"',
- 'key-name-hint': '"oe-selftest"',
+ 'key-name-hint': '"img-oe-selftest"',
}
reqsigvalues_config = {
'algo': '"sha256,rsa2048"',
- 'key-name-hint': '"oe-selftest"',
+ 'key-name-hint': '"cfg-oe-selftest"',
'sign-images': '"kernel", "fdt"',
}
@@ -215,7 +216,10 @@ UBOOT_MKIMAGE_SIGN_ARGS = "-c 'a smart comment'"
self.assertIn('conf-am335x-boneblack.dtb', signed_sections)
for signed_section, values in signed_sections.items():
value = values.get('Sign algo', None)
- self.assertEqual(value, 'sha256,rsa2048:oe-selftest', 'Signature algorithm for %s not expected value' % signed_section)
+ if signed_section.startswith("conf"):
+ self.assertEqual(value, 'sha256,rsa2048:cfg-oe-selftest', 'Signature algorithm for %s not expected value' % signed_section)
+ else:
+ self.assertEqual(value, 'sha256,rsa2048:img-oe-selftest', 'Signature algorithm for %s not expected value' % signed_section)
value = values.get('Sign value', None)
self.assertEqual(len(value), 512, 'Signature value for section %s not expected length' % signed_section)
@@ -266,7 +270,8 @@ KERNEL_CLASSES = " kernel-fitimage"
UBOOT_SIGN_ENABLE = "1"
FIT_GENERATE_KEYS = "1"
UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys"
-UBOOT_SIGN_KEYNAME = "oe-selftest"
+UBOOT_SIGN_IMG_KEYNAME = "img-oe-selftest"
+UBOOT_SIGN_KEYNAME = "cfg-oe-selftest"
FIT_SIGN_INDIVIDUAL = "1"
"""
self.write_config(config)
@@ -348,7 +353,8 @@ KERNEL_CLASSES = " kernel-fitimage test-mkimage-wrapper "
UBOOT_SIGN_ENABLE = "1"
FIT_GENERATE_KEYS = "1"
UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys"
-UBOOT_SIGN_KEYNAME = "oe-selftest"
+UBOOT_SIGN_IMG_KEYNAME = "img-oe-selftest"
+UBOOT_SIGN_KEYNAME = "cfg-oe-selftest"
FIT_SIGN_INDIVIDUAL = "1"
UBOOT_MKIMAGE_SIGN_ARGS = "-c 'a smart U-Boot comment'"
"""
@@ -592,7 +598,8 @@ KERNEL_CLASSES = " kernel-fitimage test-mkimage-wrapper "
UBOOT_SIGN_ENABLE = "1"
FIT_GENERATE_KEYS = "1"
UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys"
-UBOOT_SIGN_KEYNAME = "kernel-oe-selftest"
+UBOOT_SIGN_IMG_KEYNAME = "img-oe-selftest"
+UBOOT_SIGN_KEYNAME = "cfg-oe-selftest"
FIT_SIGN_INDIVIDUAL = "1"
"""
self.write_config(config)
@@ -735,6 +742,7 @@ UBOOT_MKIMAGE_DTCOPTS = "-I dts -O dtb -p 2000"
UBOOT_EXTLINUX = "0"
FIT_GENERATE_KEYS = "1"
KERNEL_IMAGETYPE_REPLACEMENT = "zImage"
+FIT_KERNEL_COMP_ALG = "none"
FIT_HASH_ALG = "sha256"
"""
self.write_config(config)
@@ -756,9 +764,8 @@ FIT_HASH_ALG = "sha256"
kernel_load = str(get_bb_var('UBOOT_LOADADDRESS'))
kernel_entry = str(get_bb_var('UBOOT_ENTRYPOINT'))
- initramfs_bundle_format = str(get_bb_var('KERNEL_IMAGETYPE_REPLACEMENT'))
+ kernel_compression = str(get_bb_var('FIT_KERNEL_COMP_ALG'))
uboot_arch = str(get_bb_var('UBOOT_ARCH'))
- initramfs_bundle = "arch/" + uboot_arch + "/boot/" + initramfs_bundle_format + ".initramfs"
fit_hash_alg = str(get_bb_var('FIT_HASH_ALG'))
its_file = open(fitimage_its_path)
@@ -768,11 +775,11 @@ FIT_HASH_ALG = "sha256"
exp_node_lines = [
'kernel-1 {',
'description = "Linux kernel";',
- 'data = /incbin/("' + initramfs_bundle + '");',
+ 'data = /incbin/("linux.bin");',
'type = "kernel";',
'arch = "' + uboot_arch + '";',
'os = "linux";',
- 'compression = "none";',
+ 'compression = "' + kernel_compression + '";',
'load = <' + kernel_load + '>;',
'entry = <' + kernel_entry + '>;',
'hash-1 {',
diff --git a/meta/lib/oeqa/selftest/cases/glibc.py b/meta/lib/oeqa/selftest/cases/glibc.py
index c687f6ef93..6f96281ea5 100644
--- a/meta/lib/oeqa/selftest/cases/glibc.py
+++ b/meta/lib/oeqa/selftest/cases/glibc.py
@@ -24,7 +24,7 @@ class GlibcSelfTestBase(OESelftestTestCase, OEPTestResultTestCase):
features.append('TOOLCHAIN_TEST_HOST_USER = "root"')
features.append('TOOLCHAIN_TEST_HOST_PORT = "22"')
# force single threaded test execution
- features.append('EGLIBCPARALLELISM_task-check_pn-glibc-testsuite = "PARALLELMFLAGS="-j1""')
+ features.append('EGLIBCPARALLELISM_task-check:pn-glibc-testsuite = "PARALLELMFLAGS="-j1""')
self.write_config("\n".join(features))
bitbake("glibc-testsuite -c check")
@@ -33,7 +33,7 @@ class GlibcSelfTestBase(OESelftestTestCase, OEPTestResultTestCase):
ptestsuite = "glibc-user" if ssh is None else "glibc"
self.ptest_section(ptestsuite)
- with open(os.path.join(builddir, "tests.sum"), "r") as f:
+ with open(os.path.join(builddir, "tests.sum"), "r", errors='replace') as f:
for test, result in parse_values(f):
self.ptest_result(ptestsuite, test, result)
diff --git a/meta/lib/oeqa/selftest/cases/gotoolchain.py b/meta/lib/oeqa/selftest/cases/gotoolchain.py
index 4fc3605f42..c809d7c9b1 100644
--- a/meta/lib/oeqa/selftest/cases/gotoolchain.py
+++ b/meta/lib/oeqa/selftest/cases/gotoolchain.py
@@ -43,6 +43,12 @@ class oeGoToolchainSelfTest(OESelftestTestCase):
@classmethod
def tearDownClass(cls):
+ # Go creates file which are readonly
+ for dirpath, dirnames, filenames in os.walk(cls.tmpdir_SDKQA):
+ for filename in filenames + dirnames:
+ f = os.path.join(dirpath, filename)
+ if not os.path.islink(f):
+ os.chmod(f, 0o775)
shutil.rmtree(cls.tmpdir_SDKQA, ignore_errors=True)
super(oeGoToolchainSelfTest, cls).tearDownClass()
diff --git a/meta/lib/oeqa/selftest/cases/image_typedep.py b/meta/lib/oeqa/selftest/cases/image_typedep.py
index 52e1080f13..5b182a8f94 100644
--- a/meta/lib/oeqa/selftest/cases/image_typedep.py
+++ b/meta/lib/oeqa/selftest/cases/image_typedep.py
@@ -9,7 +9,7 @@ from oeqa.utils.commands import bitbake
class ImageTypeDepTests(OESelftestTestCase):
- # Verify that when specifying a IMAGE_TYPEDEP_ of the form "foo.bar" that
+ # Verify that when specifying a IMAGE_TYPEDEP: of the form "foo.bar" that
# the conversion type bar gets added as a dep as well
def test_conversion_typedep_added(self):
@@ -22,7 +22,7 @@ LICENSE = "MIT"
IMAGE_FSTYPES = "testfstype"
IMAGE_TYPES_MASKED += "testfstype"
-IMAGE_TYPEDEP_testfstype = "tar.bz2"
+IMAGE_TYPEDEP:testfstype = "tar.bz2"
inherit image
diff --git a/meta/lib/oeqa/selftest/cases/imagefeatures.py b/meta/lib/oeqa/selftest/cases/imagefeatures.py
index 2de22d3404..d36d45c551 100644
--- a/meta/lib/oeqa/selftest/cases/imagefeatures.py
+++ b/meta/lib/oeqa/selftest/cases/imagefeatures.py
@@ -198,8 +198,8 @@ class ImageFeatures(OESelftestTestCase):
image_name = 'core-image-minimal'
all_image_types = set(get_bb_var("IMAGE_TYPES", image_name).split())
- blacklist = set(('container', 'elf', 'f2fs', 'multiubi', 'tar.zst', 'wic.zst'))
- img_types = all_image_types - blacklist
+ skip_image_types = set(('container', 'elf', 'f2fs', 'multiubi', 'tar.zst', 'wic.zst'))
+ img_types = all_image_types - skip_image_types
config = 'IMAGE_FSTYPES += "%s"\n'\
'MKUBIFS_ARGS ?= "-m 2048 -e 129024 -c 2047"\n'\
@@ -229,7 +229,7 @@ USERADD_GID_TABLES += "files/static-group"
def test_no_busybox_base_utils(self):
config = """
# Enable wayland
-DISTRO_FEATURES_append += "pam opengl wayland"
+DISTRO_FEATURES:append = " pam opengl wayland"
# Switch to systemd
DISTRO_FEATURES += "systemd"
@@ -245,8 +245,8 @@ VIRTUAL-RUNTIME_base-utils = "packagegroup-core-base-utils"
VIRTUAL-RUNTIME_base-utils-hwclock = "util-linux-hwclock"
VIRTUAL-RUNTIME_base-utils-syslog = ""
-# Blacklist busybox
-PNBLACKLIST[busybox] = "Don't build this"
+# Skip busybox
+SKIP_RECIPE[busybox] = "Don't build this"
"""
self.write_config(config)
diff --git a/meta/lib/oeqa/selftest/cases/incompatible_lic.py b/meta/lib/oeqa/selftest/cases/incompatible_lic.py
index 152da6332a..0794d46e6d 100644
--- a/meta/lib/oeqa/selftest/cases/incompatible_lic.py
+++ b/meta/lib/oeqa/selftest/cases/incompatible_lic.py
@@ -1,10 +1,11 @@
from oeqa.selftest.case import OESelftestTestCase
from oeqa.utils.commands import bitbake
-class IncompatibleLicenseTests(OESelftestTestCase):
+class IncompatibleLicenseTestObsolete(OESelftestTestCase):
- def lic_test(self, pn, pn_lic, lic):
- error_msg = 'ERROR: Nothing PROVIDES \'%s\'\n%s was skipped: it has incompatible license(s): %s' % (pn, pn, pn_lic)
+ def lic_test(self, pn, pn_lic, lic, error_msg=None):
+ if not error_msg:
+ error_msg = 'ERROR: Nothing PROVIDES \'%s\'\n%s was skipped: it has incompatible license(s): %s' % (pn, pn, pn_lic)
self.write_config("INCOMPATIBLE_LICENSE += \"%s\"" % (lic))
@@ -13,68 +14,81 @@ class IncompatibleLicenseTests(OESelftestTestCase):
raise AssertionError(result.output)
# Verify that a package with an SPDX license (from AVAILABLE_LICENSES)
- # cannot be built when INCOMPATIBLE_LICENSE contains this SPDX license
- def test_incompatible_spdx_license(self):
- self.lic_test('incompatible-license', 'GPL-3.0-only', 'GPL-3.0-only')
-
- # Verify that a package with an SPDX license (from AVAILABLE_LICENSES)
# cannot be built when INCOMPATIBLE_LICENSE contains an alias (in
# SPDXLICENSEMAP) of this SPDX license
def test_incompatible_alias_spdx_license(self):
- self.lic_test('incompatible-license', 'GPL-3.0-only', 'GPLv3')
-
- # Verify that a package with an SPDX license (from AVAILABLE_LICENSES)
- # cannot be built when INCOMPATIBLE_LICENSE contains a wildcarded license
- # matching this SPDX license
- def test_incompatible_spdx_license_wildcard(self):
- self.lic_test('incompatible-license', 'GPL-3.0-only', '*GPL-3.0-only')
+ self.lic_test('incompatible-license', 'GPL-3.0-only', 'GPLv3', "is an obsolete license, please use an SPDX reference in INCOMPATIBLE_LICENSE")
# Verify that a package with an SPDX license (from AVAILABLE_LICENSES)
# cannot be built when INCOMPATIBLE_LICENSE contains a wildcarded alias
# license matching this SPDX license
def test_incompatible_alias_spdx_license_wildcard(self):
- self.lic_test('incompatible-license', 'GPL-3.0-only', '*GPLv3')
-
- # Verify that a package with an alias (from SPDXLICENSEMAP) to an SPDX
- # license cannot be built when INCOMPATIBLE_LICENSE contains this SPDX
- # license
- def test_incompatible_spdx_license_alias(self):
- self.lic_test('incompatible-license-alias', 'GPL-3.0-only', 'GPL-3.0-only')
+ self.lic_test('incompatible-license', 'GPL-3.0-only', '*GPLv3', "*GPLv3 is an invalid license wildcard entry")
# Verify that a package with an alias (from SPDXLICENSEMAP) to an SPDX
# license cannot be built when INCOMPATIBLE_LICENSE contains this alias
def test_incompatible_alias_spdx_license_alias(self):
- self.lic_test('incompatible-license-alias', 'GPL-3.0-only', 'GPLv3')
+ self.lic_test('incompatible-license-alias', 'GPL-3.0-only', 'GPLv3', "is an obsolete license, please use an SPDX reference in INCOMPATIBLE_LICENSE")
# Verify that a package with an alias (from SPDXLICENSEMAP) to an SPDX
# license cannot be built when INCOMPATIBLE_LICENSE contains a wildcarded
# license matching this SPDX license
def test_incompatible_spdx_license_alias_wildcard(self):
- self.lic_test('incompatible-license-alias', 'GPL-3.0-only', '*GPL-3.0')
+ self.lic_test('incompatible-license-alias', 'GPL-3.0-only', '*GPL-3.0', "*GPL-3.0 is an invalid license wildcard entry")
# Verify that a package with an alias (from SPDXLICENSEMAP) to an SPDX
# license cannot be built when INCOMPATIBLE_LICENSE contains a wildcarded
# alias license matching the SPDX license
def test_incompatible_alias_spdx_license_alias_wildcard(self):
- self.lic_test('incompatible-license-alias', 'GPL-3.0-only', '*GPLv3')
+ self.lic_test('incompatible-license-alias', 'GPL-3.0-only', '*GPLv3', "*GPLv3 is an invalid license wildcard entry")
- # Verify that a package with multiple SPDX licenses (from
- # AVAILABLE_LICENSES) cannot be built when INCOMPATIBLE_LICENSE contains
- # some of them
- def test_incompatible_spdx_licenses(self):
- self.lic_test('incompatible-licenses', 'GPL-3.0-only LGPL-3.0-only', 'GPL-3.0-only LGPL-3.0-only')
# Verify that a package with multiple SPDX licenses (from
# AVAILABLE_LICENSES) cannot be built when INCOMPATIBLE_LICENSE contains a
# wildcard to some of them
def test_incompatible_spdx_licenses_wildcard(self):
- self.lic_test('incompatible-licenses', 'GPL-3.0-only LGPL-3.0-only', '*GPL-3.0-only')
+ self.lic_test('incompatible-licenses', 'GPL-3.0-only LGPL-3.0-only', '*GPL-3.0-only', "*GPL-3.0-only is an invalid license wildcard entry")
+
# Verify that a package with multiple SPDX licenses (from
# AVAILABLE_LICENSES) cannot be built when INCOMPATIBLE_LICENSE contains a
# wildcard matching all licenses
def test_incompatible_all_licenses_wildcard(self):
- self.lic_test('incompatible-licenses', 'GPL-2.0-only GPL-3.0-only LGPL-3.0-only', '*')
+ self.lic_test('incompatible-licenses', 'GPL-2.0-only GPL-3.0-only LGPL-3.0-only', '*', "* is an invalid license wildcard entry")
+
+class IncompatibleLicenseTests(OESelftestTestCase):
+
+ def lic_test(self, pn, pn_lic, lic):
+ error_msg = 'ERROR: Nothing PROVIDES \'%s\'\n%s was skipped: it has incompatible license(s): %s' % (pn, pn, pn_lic)
+
+ self.write_config("INCOMPATIBLE_LICENSE += \"%s\"" % (lic))
+
+ result = bitbake('%s --dry-run' % (pn), ignore_status=True)
+ if error_msg not in result.output:
+ raise AssertionError(result.output)
+
+ # Verify that a package with an SPDX license (from AVAILABLE_LICENSES)
+ # cannot be built when INCOMPATIBLE_LICENSE contains this SPDX license
+ def test_incompatible_spdx_license(self):
+ self.lic_test('incompatible-license', 'GPL-3.0-only', 'GPL-3.0-only')
+
+ # Verify that a package with an SPDX license (from AVAILABLE_LICENSES)
+ # cannot be built when INCOMPATIBLE_LICENSE contains a wildcarded license
+ # matching this SPDX license
+ def test_incompatible_spdx_license_wildcard(self):
+ self.lic_test('incompatible-license', 'GPL-3.0-only', 'GPL-3.0*')
+
+ # Verify that a package with an alias (from SPDXLICENSEMAP) to an SPDX
+ # license cannot be built when INCOMPATIBLE_LICENSE contains this SPDX
+ # license
+ def test_incompatible_spdx_license_alias(self):
+ self.lic_test('incompatible-license-alias', 'GPL-3.0-only', 'GPL-3.0-only')
+
+ # Verify that a package with multiple SPDX licenses (from
+ # AVAILABLE_LICENSES) cannot be built when INCOMPATIBLE_LICENSE contains
+ # some of them
+ def test_incompatible_spdx_licenses(self):
+ self.lic_test('incompatible-licenses', 'GPL-3.0-only LGPL-3.0-only', 'GPL-3.0-only LGPL-3.0-only')
# Verify that a package with a non-SPDX license (neither in
# AVAILABLE_LICENSES nor in SPDXLICENSEMAP) cannot be built when
@@ -85,8 +99,8 @@ class IncompatibleLicenseTests(OESelftestTestCase):
class IncompatibleLicensePerImageTests(OESelftestTestCase):
def default_config(self):
return """
-IMAGE_INSTALL_append = " bash"
-INCOMPATIBLE_LICENSE_pn-core-image-minimal = "GPL-3.0 LGPL-3.0"
+IMAGE_INSTALL:append = " bash"
+INCOMPATIBLE_LICENSE:pn-core-image-minimal = "GPL-3.0* LGPL-3.0*"
"""
def test_bash_default(self):
@@ -98,7 +112,7 @@ INCOMPATIBLE_LICENSE_pn-core-image-minimal = "GPL-3.0 LGPL-3.0"
raise AssertionError(result.output)
def test_bash_and_license(self):
- self.write_config(self.default_config() + '\nLICENSE_append_pn-bash = " & SomeLicense"')
+ self.write_config(self.default_config() + '\nLICENSE:append:pn-bash = " & SomeLicense"')
error_msg = "ERROR: core-image-minimal-1.0-r0 do_rootfs: Package bash cannot be installed into the image because it has incompatible license(s): GPL-3.0-or-later"
result = bitbake('core-image-minimal', ignore_status=True)
@@ -106,30 +120,42 @@ INCOMPATIBLE_LICENSE_pn-core-image-minimal = "GPL-3.0 LGPL-3.0"
raise AssertionError(result.output)
def test_bash_or_license(self):
- self.write_config(self.default_config() + '\nLICENSE_append_pn-bash = " | SomeLicense"')
+ self.write_config(self.default_config() + '\nLICENSE:append:pn-bash = " | SomeLicense"')
bitbake('core-image-minimal')
- def test_bash_whitelist(self):
- self.write_config(self.default_config() + '\nWHITELIST_GPL-3.0_pn-core-image-minimal = "bash"')
+ def test_bash_license_exceptions(self):
+ self.write_config(self.default_config() + '\nINCOMPATIBLE_LICENSE_EXCEPTIONS:pn-core-image-minimal = "bash:GPL-3.0-or-later"')
bitbake('core-image-minimal')
class NoGPL3InImagesTests(OESelftestTestCase):
def test_core_image_minimal(self):
self.write_config("""
-INCOMPATIBLE_LICENSE_pn-core-image-minimal = "GPL-3.0 LGPL-3.0"
+INCOMPATIBLE_LICENSE:pn-core-image-minimal = "GPL-3.0* LGPL-3.0*"
""")
bitbake('core-image-minimal')
- def test_core_image_full_cmdline(self):
+ def test_core_image_full_cmdline_weston(self):
self.write_config("""
-INHERIT += "testimage"\n
-INCOMPATIBLE_LICENSE_pn-core-image-full-cmdline = "GPL-3.0 LGPL-3.0"\n
-RDEPENDS_packagegroup-core-full-cmdline-utils_remove = "bash bc coreutils cpio ed findutils gawk grep mc mc-fish mc-helpers mc-helpers-perl sed tar time"\n
-RDEPENDS_packagegroup-core-full-cmdline-dev-utils_remove = "diffutils m4 make patch"\n
-RDEPENDS_packagegroup-core-full-cmdline-multiuser_remove = "gzip"\n
+INHERIT += "testimage"
+INCOMPATIBLE_LICENSE:pn-core-image-full-cmdline = "GPL-3.0* LGPL-3.0*"
+INCOMPATIBLE_LICENSE:pn-core-image-weston = "GPL-3.0* LGPL-3.0*"
+# Settings for full-cmdline
+RDEPENDS:packagegroup-core-full-cmdline-utils:remove = "bash bc coreutils cpio ed findutils gawk grep mc mc-fish mc-helpers mc-helpers-perl sed tar time"
+RDEPENDS:packagegroup-core-full-cmdline-dev-utils:remove = "diffutils m4 make patch"
+RDEPENDS:packagegroup-core-full-cmdline-multiuser:remove = "gzip"
+# Settings for weston
+# direct gpl3 dependencies
+RRECOMMENDS:packagegroup-base-vfat:remove = "dosfstools"
+PACKAGECONFIG:remove:pn-bluez5 = "readline"
+# dnf pulls in gpg which is gpl3; it also pulls in python3-rpm which pulls in rpm-build which pulls in bash
+# so install rpm but not dnf
+IMAGE_FEATURES:remove:pn-core-image-weston = "package-management"
+CORE_IMAGE_EXTRA_INSTALL:pn-core-image-weston += "rpm"
+# matchbox-terminal depends on vte, which is gpl3
+CORE_IMAGE_BASE_INSTALL:remove:pn-core-image-weston = "matchbox-terminal"
""")
- bitbake('core-image-full-cmdline')
- bitbake('-c testimage core-image-full-cmdline')
+ bitbake('core-image-full-cmdline core-image-weston')
+ bitbake('-c testimage core-image-full-cmdline core-image-weston')
diff --git a/meta/lib/oeqa/selftest/cases/kerneldevelopment.py b/meta/lib/oeqa/selftest/cases/kerneldevelopment.py
index a61876ee61..b1623a1885 100644
--- a/meta/lib/oeqa/selftest/cases/kerneldevelopment.py
+++ b/meta/lib/oeqa/selftest/cases/kerneldevelopment.py
@@ -58,7 +58,7 @@ class KernelDev(OESelftestTestCase):
recipe_append = os.path.join(self.recipeskernel_dir, 'linux-yocto_%.bbappend')
with open(recipe_append, 'w+') as fh:
fh.write('SRC_URI += "file://%s"\n' % patch_name)
- fh.write('FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"')
+ fh.write('FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"')
runCmd('bitbake virtual/kernel -c clean')
runCmd('bitbake virtual/kernel -c patch')
diff --git a/meta/lib/oeqa/selftest/cases/layerappend.py b/meta/lib/oeqa/selftest/cases/layerappend.py
index 05e9426fc6..dadc7c5d28 100644
--- a/meta/lib/oeqa/selftest/cases/layerappend.py
+++ b/meta/lib/oeqa/selftest/cases/layerappend.py
@@ -30,20 +30,20 @@ python do_build() {
addtask build
"""
append = """
-FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
-SRC_URI_append = " file://appendtest.txt"
+SRC_URI:append = " file://appendtest.txt"
-sysroot_stage_all_append() {
+sysroot_stage_all:append() {
install -m 644 ${WORKDIR}/appendtest.txt ${SYSROOT_DESTDIR}/
}
"""
append2 = """
-FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
-SRC_URI_append = " file://appendtest.txt"
+SRC_URI:append = " file://appendtest.txt"
"""
layerappend = ''
diff --git a/meta/lib/oeqa/selftest/cases/lic_checksum.py b/meta/lib/oeqa/selftest/cases/lic_checksum.py
index bae935d697..91021ac335 100644
--- a/meta/lib/oeqa/selftest/cases/lic_checksum.py
+++ b/meta/lib/oeqa/selftest/cases/lic_checksum.py
@@ -21,7 +21,7 @@ class LicenseTests(OESelftestTestCase):
os.close(lic_file)
self.track_for_cleanup(lic_path)
- self.write_config("INHERIT_remove = \"report-error\"")
+ self.write_config("INHERIT:remove = \"report-error\"")
self.write_recipeinc('emptytest', """
INHIBIT_DEFAULT_DEPS = "1"
diff --git a/meta/lib/oeqa/selftest/cases/multiconfig.py b/meta/lib/oeqa/selftest/cases/multiconfig.py
index 39b92f2439..baae9b456f 100644
--- a/meta/lib/oeqa/selftest/cases/multiconfig.py
+++ b/meta/lib/oeqa/selftest/cases/multiconfig.py
@@ -17,7 +17,7 @@ class MultiConfig(OESelftestTestCase):
"""
config = """
-IMAGE_INSTALL_append_pn-core-image-full-cmdline = " multiconfig-image-packager-tiny multiconfig-image-packager-musl"
+IMAGE_INSTALL:append:pn-core-image-full-cmdline = " multiconfig-image-packager-tiny multiconfig-image-packager-musl"
BBMULTICONFIG = "tiny musl"
"""
self.write_config(config)
@@ -52,7 +52,7 @@ TMPDIR = "${TOPDIR}/tmp-mc-tiny"
self.write_config(config)
testconfig = textwrap.dedent('''\
- MCTESTVAR_append = "1"
+ MCTESTVAR:append = "1"
''')
self.write_config(testconfig, 'test')
@@ -64,7 +64,7 @@ TMPDIR = "${TOPDIR}/tmp-mc-tiny"
self.assertIn('MCTESTVAR=test1', result.output.splitlines())
testconfig = textwrap.dedent('''\
- MCTESTVAR_append = "2"
+ MCTESTVAR:append = "2"
''')
self.write_config(testconfig, 'test')
diff --git a/meta/lib/oeqa/selftest/cases/newlib.py b/meta/lib/oeqa/selftest/cases/newlib.py
new file mode 100644
index 0000000000..999e3e78b0
--- /dev/null
+++ b/meta/lib/oeqa/selftest/cases/newlib.py
@@ -0,0 +1,11 @@
+#
+# SPDX-License-Identifier: MIT
+#
+
+from oeqa.selftest.case import OESelftestTestCase
+from oeqa.utils.commands import bitbake
+
+class NewlibTest(OESelftestTestCase):
+ def test_newlib(self):
+ self.write_config('TCLIBC = "newlib"')
+ bitbake("newlib libgloss")
diff --git a/meta/lib/oeqa/selftest/cases/oelib/license.py b/meta/lib/oeqa/selftest/cases/oelib/license.py
index 6ebbee589f..3b359396b6 100644
--- a/meta/lib/oeqa/selftest/cases/oelib/license.py
+++ b/meta/lib/oeqa/selftest/cases/oelib/license.py
@@ -15,11 +15,11 @@ class SeenVisitor(oe.license.LicenseVisitor):
class TestSingleLicense(TestCase):
licenses = [
- "GPLv2",
- "LGPL-2.0",
- "Artistic",
+ "GPL-2.0-only",
+ "LGPL-2.0-only",
+ "Artistic-1.0",
"MIT",
- "GPLv3+",
+ "GPL-3.0-or-later",
"FOO_BAR",
]
invalid_licenses = ["GPL/BSD"]
@@ -67,9 +67,9 @@ class TestComplexCombinations(TestSimpleCombinations):
"FOO & (BAR | BAZ)&MOO": ["FOO", "BAR", "MOO"],
"(ALPHA|(BETA&THETA)|OMEGA)&DELTA": ["OMEGA", "DELTA"],
"((ALPHA|BETA)&FOO)|BAZ": ["BETA", "FOO"],
- "(GPL-2.0|Proprietary)&BSD-4-clause&MIT": ["GPL-2.0", "BSD-4-clause", "MIT"],
+ "(GPL-2.0-only|Proprietary)&BSD-4-clause&MIT": ["GPL-2.0-only", "BSD-4-clause", "MIT"],
}
- preferred = ["BAR", "OMEGA", "BETA", "GPL-2.0"]
+ preferred = ["BAR", "OMEGA", "BETA", "GPL-2.0-only"]
class TestIsIncluded(TestCase):
tests = {
@@ -87,12 +87,12 @@ class TestIsIncluded(TestCase):
[True, ["BAR", "FOOBAR"]],
("(FOO | BAR) & FOOBAR | BAZ & MOO & BARFOO", None, "FOO"):
[True, ["BAZ", "MOO", "BARFOO"]],
- ("GPL-3.0 & GPL-2.0 & LGPL-2.1 | Proprietary", None, None):
- [True, ["GPL-3.0", "GPL-2.0", "LGPL-2.1"]],
- ("GPL-3.0 & GPL-2.0 & LGPL-2.1 | Proprietary", None, "GPL-3.0"):
+ ("GPL-3.0-or-later & GPL-2.0-only & LGPL-2.1-only | Proprietary", None, None):
+ [True, ["GPL-3.0-or-later", "GPL-2.0-only", "LGPL-2.1-only"]],
+ ("GPL-3.0-or-later & GPL-2.0-only & LGPL-2.1-only | Proprietary", None, "GPL-3.0-or-later"):
[True, ["Proprietary"]],
- ("GPL-3.0 & GPL-2.0 & LGPL-2.1 | Proprietary", None, "GPL-3.0 Proprietary"):
- [False, ["GPL-3.0"]]
+ ("GPL-3.0-or-later & GPL-2.0-only & LGPL-2.1-only | Proprietary", None, "GPL-3.0-or-later Proprietary"):
+ [False, ["GPL-3.0-or-later"]]
}
def test_tests(self):
diff --git a/meta/lib/oeqa/selftest/cases/oescripts.py b/meta/lib/oeqa/selftest/cases/oescripts.py
index 8a10ff357b..91abf9654a 100644
--- a/meta/lib/oeqa/selftest/cases/oescripts.py
+++ b/meta/lib/oeqa/selftest/cases/oescripts.py
@@ -150,7 +150,7 @@ class OEListPackageconfigTests(OEScriptTests):
expected_endlines = []
expected_endlines.append("RECIPE NAME PACKAGECONFIG FLAGS")
expected_endlines.append("pinentry gtk2 libcap ncurses qt secret")
- expected_endlines.append("tar acl")
+ expected_endlines.append("tar acl selinux")
self.check_endlines(results, expected_endlines)
@@ -167,7 +167,7 @@ class OEListPackageconfigTests(OEScriptTests):
def test_packageconfig_flags_option_all(self):
results = runCmd('%s/contrib/list-packageconfig-flags.py -a' % self.scripts_dir)
expected_endlines = []
- expected_endlines.append("pinentry-1.1.1")
+ expected_endlines.append("pinentry-1.2.0")
expected_endlines.append("PACKAGECONFIG ncurses libcap")
expected_endlines.append("PACKAGECONFIG[qt] --enable-pinentry-qt, --disable-pinentry-qt, qtbase-native qtbase")
expected_endlines.append("PACKAGECONFIG[gtk2] --enable-pinentry-gtk2, --disable-pinentry-gtk2, gtk+ glib-2.0")
diff --git a/meta/lib/oeqa/selftest/cases/overlayfs.py b/meta/lib/oeqa/selftest/cases/overlayfs.py
new file mode 100644
index 0000000000..56ae48ce64
--- /dev/null
+++ b/meta/lib/oeqa/selftest/cases/overlayfs.py
@@ -0,0 +1,423 @@
+#
+# SPDX-License-Identifier: MIT
+#
+
+from oeqa.selftest.case import OESelftestTestCase
+from oeqa.utils.commands import runCmd, bitbake, get_bb_var, runqemu
+
+def getline_qemu(out, line):
+ for l in out.split('\n'):
+ if line in l:
+ return l
+
+def getline(res, line):
+ return getline_qemu(res.output, line)
+
+class OverlayFSTests(OESelftestTestCase):
+ """Overlayfs class usage tests"""
+
+ def add_overlay_conf_to_machine(self):
+ machine_inc = """
+OVERLAYFS_MOUNT_POINT[mnt-overlay] = "/mnt/overlay"
+"""
+ self.set_machine_config(machine_inc)
+
+ def test_distro_features_missing(self):
+ """
+ Summary: Check that required DISTRO_FEATURES are set
+ Expected: Fail when either systemd or overlayfs are not in DISTRO_FEATURES
+ Author: Vyacheslav Yurkov <uvv.mail@gmail.com>
+ """
+
+ config = """
+IMAGE_INSTALL:append = " overlayfs-user"
+"""
+ overlayfs_recipe_append = """
+inherit overlayfs
+"""
+ self.write_config(config)
+ self.add_overlay_conf_to_machine()
+ self.write_recipeinc('overlayfs-user', overlayfs_recipe_append)
+
+ res = bitbake('core-image-minimal', ignore_status=True)
+ line = getline(res, "overlayfs-user was skipped: missing required distro features")
+ self.assertTrue("overlayfs" in res.output, msg=res.output)
+ self.assertTrue("systemd" in res.output, msg=res.output)
+ self.assertTrue("ERROR: Required build target 'core-image-minimal' has no buildable providers." in res.output, msg=res.output)
+
+ def test_not_all_units_installed(self):
+ """
+ Summary: Test QA check that we have required mount units in the image
+ Expected: Fail because mount unit for overlay partition is not installed
+ Author: Vyacheslav Yurkov <uvv.mail@gmail.com>
+ """
+
+ config = """
+IMAGE_INSTALL:append = " overlayfs-user"
+DISTRO_FEATURES += "systemd overlayfs"
+"""
+
+ self.write_config(config)
+ self.add_overlay_conf_to_machine()
+
+ res = bitbake('core-image-minimal', ignore_status=True)
+ line = getline(res, " Mount path /mnt/overlay not found in fstat and unit mnt-overlay.mount not found in systemd unit directories")
+ self.assertTrue(line and line.startswith("WARNING:"), msg=res.output)
+ line = getline(res, "Not all mount paths and units are installed in the image")
+ self.assertTrue(line and line.startswith("ERROR:"), msg=res.output)
+
+ def test_mount_unit_not_set(self):
+ """
+ Summary: Test whether mount unit was set properly
+ Expected: Fail because mount unit was not set
+ Author: Vyacheslav Yurkov <uvv.mail@gmail.com>
+ """
+
+ config = """
+IMAGE_INSTALL:append = " overlayfs-user"
+DISTRO_FEATURES += "systemd overlayfs"
+"""
+
+ self.write_config(config)
+
+ res = bitbake('core-image-minimal', ignore_status=True)
+ line = getline(res, "A recipe uses overlayfs class but there is no OVERLAYFS_MOUNT_POINT set in your MACHINE configuration")
+ self.assertTrue(line and line.startswith("Parsing recipes...ERROR:"), msg=res.output)
+
+ def test_wrong_mount_unit_set(self):
+ """
+ Summary: Test whether mount unit was set properly
+ Expected: Fail because not the correct flag used for mount unit
+ Author: Vyacheslav Yurkov <uvv.mail@gmail.com>
+ """
+
+ config = """
+IMAGE_INSTALL:append = " overlayfs-user"
+DISTRO_FEATURES += "systemd overlayfs"
+"""
+
+ wrong_machine_config = """
+OVERLAYFS_MOUNT_POINT[usr-share-overlay] = "/usr/share/overlay"
+"""
+
+ self.write_config(config)
+ self.set_machine_config(wrong_machine_config)
+
+ res = bitbake('core-image-minimal', ignore_status=True)
+ line = getline(res, "Missing required mount point for OVERLAYFS_MOUNT_POINT[mnt-overlay] in your MACHINE configuration")
+ self.assertTrue(line and line.startswith("Parsing recipes...ERROR:"), msg=res.output)
+
+ def _test_correct_image(self, recipe, data):
+ """
+ Summary: Check that we can create an image when all parameters are
+ set correctly
+ Expected: Image is created successfully
+ Author: Vyacheslav Yurkov <uvv.mail@gmail.com>
+ """
+
+ config = """
+IMAGE_INSTALL:append = " overlayfs-user systemd-machine-units"
+DISTRO_FEATURES += "systemd overlayfs"
+
+# Use systemd as init manager
+VIRTUAL-RUNTIME_init_manager = "systemd"
+
+# enable overlayfs in the kernel
+KERNEL_EXTRA_FEATURES:append = " features/overlayfs/overlayfs.scc"
+"""
+
+ overlayfs_recipe_append = """
+OVERLAYFS_WRITABLE_PATHS[mnt-overlay] += "/usr/share/another-overlay-mount"
+
+SYSTEMD_SERVICE:${PN} += " \
+ my-application.service \
+"
+
+do_install:append() {
+ install -d ${D}${systemd_system_unitdir}
+ cat <<EOT > ${D}${systemd_system_unitdir}/my-application.service
+[Unit]
+Description=Sample application start-up unit
+After=overlayfs-user-overlays.service
+Requires=overlayfs-user-overlays.service
+
+[Service]
+Type=oneshot
+ExecStart=/bin/true
+RemainAfterExit=true
+
+[Install]
+WantedBy=multi-user.target
+EOT
+}
+"""
+
+ self.write_config(config)
+ self.add_overlay_conf_to_machine()
+ self.write_recipeinc(recipe, data)
+ self.write_recipeinc('overlayfs-user', overlayfs_recipe_append)
+
+ bitbake('core-image-minimal')
+
+ with runqemu('core-image-minimal') as qemu:
+ # Check that application service started
+ status, output = qemu.run_serial("systemctl status my-application")
+ self.assertTrue("active (exited)" in output, msg=output)
+
+ # Check that overlay mounts are dependencies of our application unit
+ status, output = qemu.run_serial("systemctl list-dependencies my-application")
+ self.assertTrue("overlayfs-user-overlays.service" in output, msg=output)
+
+ status, output = qemu.run_serial("systemctl list-dependencies overlayfs-user-overlays")
+ self.assertTrue("usr-share-another\\x2doverlay\\x2dmount.mount" in output, msg=output)
+ self.assertTrue("usr-share-my\\x2dapplication.mount" in output, msg=output)
+
+ # Check that we have /mnt/overlay fs mounted as tmpfs and
+ # /usr/share/my-application as an overlay (see overlayfs-user recipe)
+ status, output = qemu.run_serial("/bin/mount -t tmpfs,overlay")
+
+ line = getline_qemu(output, "on /mnt/overlay")
+ self.assertTrue(line and line.startswith("tmpfs"), msg=output)
+
+ line = getline_qemu(output, "upperdir=/mnt/overlay/upper/usr/share/my-application")
+ self.assertTrue(line and line.startswith("overlay"), msg=output)
+
+ line = getline_qemu(output, "upperdir=/mnt/overlay/upper/usr/share/another-overlay-mount")
+ self.assertTrue(line and line.startswith("overlay"), msg=output)
+
+ def test_correct_image_fstab(self):
+ """
+ Summary: Check that we can create an image when all parameters are
+ set correctly via fstab
+ Expected: Image is created successfully
+ Author: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
+ """
+
+ base_files_append = """
+do_install:append() {
+ cat <<EOT >> ${D}${sysconfdir}/fstab
+tmpfs /mnt/overlay tmpfs mode=1777,strictatime,nosuid,nodev 0 0
+EOT
+}
+"""
+
+ self._test_correct_image('base-files', base_files_append)
+
+ def test_correct_image_unit(self):
+ """
+ Summary: Check that we can create an image when all parameters are
+ set correctly via mount unit
+ Expected: Image is created successfully
+ Author: Vyacheslav Yurkov <uvv.mail@gmail.com>
+ """
+
+ systemd_machine_unit_append = """
+SYSTEMD_SERVICE:${PN} += " \
+ mnt-overlay.mount \
+"
+
+do_install:append() {
+ install -d ${D}${systemd_system_unitdir}
+ cat <<EOT > ${D}${systemd_system_unitdir}/mnt-overlay.mount
+[Unit]
+Description=Tmpfs directory
+DefaultDependencies=no
+
+[Mount]
+What=tmpfs
+Where=/mnt/overlay
+Type=tmpfs
+Options=mode=1777,strictatime,nosuid,nodev
+
+[Install]
+WantedBy=multi-user.target
+EOT
+}
+
+"""
+
+ self._test_correct_image('systemd-machine-units', systemd_machine_unit_append)
+
+class OverlayFSEtcRunTimeTests(OESelftestTestCase):
+ """overlayfs-etc class tests"""
+
+ def test_all_required_variables_set(self):
+ """
+ Summary: Check that required variables are set
+ Expected: Fail when any of required variables is missing
+ Author: Vyacheslav Yurkov <uvv.mail@gmail.com>
+ """
+
+ configBase = """
+DISTRO_FEATURES += "systemd"
+
+# Use systemd as init manager
+VIRTUAL-RUNTIME_init_manager = "systemd"
+
+# enable overlayfs in the kernel
+KERNEL_EXTRA_FEATURES:append = " features/overlayfs/overlayfs.scc"
+
+# Image configuration for overlayfs-etc
+EXTRA_IMAGE_FEATURES += "overlayfs-etc"
+IMAGE_FEATURES:remove = "package-management"
+"""
+ configMountPoint = """
+OVERLAYFS_ETC_MOUNT_POINT = "/data"
+"""
+ configDevice = """
+OVERLAYFS_ETC_DEVICE = "/dev/mmcblk0p1"
+"""
+
+ self.write_config(configBase)
+ res = bitbake('core-image-minimal', ignore_status=True)
+ line = getline(res, "OVERLAYFS_ETC_MOUNT_POINT must be set in your MACHINE configuration")
+ self.assertTrue(line, msg=res.output)
+
+ self.append_config(configMountPoint)
+ res = bitbake('core-image-minimal', ignore_status=True)
+ line = getline(res, "OVERLAYFS_ETC_DEVICE must be set in your MACHINE configuration")
+ self.assertTrue(line, msg=res.output)
+
+ self.append_config(configDevice)
+ res = bitbake('core-image-minimal', ignore_status=True)
+ line = getline(res, "OVERLAYFS_ETC_FSTYPE should contain a valid file system type on /dev/mmcblk0p1")
+ self.assertTrue(line, msg=res.output)
+
+ def test_image_feature_conflict(self):
+ """
+ Summary: Overlayfs-etc is not allowed to be used with package-management
+ Expected: Feature conflict
+ Author: Vyacheslav Yurkov <uvv.mail@gmail.com>
+ """
+
+ config = """
+DISTRO_FEATURES += "systemd"
+
+# Use systemd as init manager
+VIRTUAL-RUNTIME_init_manager = "systemd"
+
+# enable overlayfs in the kernel
+KERNEL_EXTRA_FEATURES:append = " features/overlayfs/overlayfs.scc"
+EXTRA_IMAGE_FEATURES += "overlayfs-etc"
+EXTRA_IMAGE_FEATURES += "package-management"
+"""
+
+ self.write_config(config)
+
+ res = bitbake('core-image-minimal', ignore_status=True)
+ line = getline(res, "contains conflicting IMAGE_FEATURES")
+ self.assertTrue("overlayfs-etc" in res.output, msg=res.output)
+ self.assertTrue("package-management" in res.output, msg=res.output)
+
+ def test_image_feature_is_missing_class_included(self):
+ configAppend = """
+INHERIT += "overlayfs-etc"
+"""
+ self.run_check_image_feature(configAppend)
+
+ def test_image_feature_is_missing(self):
+ self.run_check_image_feature()
+
+ def run_check_image_feature(self, appendToConfig=""):
+ """
+ Summary: Overlayfs-etc class is not applied when image feature is not set
+ even if we inherit it directly,
+ Expected: Image is created successfully but /etc is not an overlay
+ Author: Vyacheslav Yurkov <uvv.mail@gmail.com>
+ """
+
+ config = f"""
+DISTRO_FEATURES += "systemd"
+
+# Use systemd as init manager
+VIRTUAL-RUNTIME_init_manager = "systemd"
+
+# enable overlayfs in the kernel
+KERNEL_EXTRA_FEATURES:append = " features/overlayfs/overlayfs.scc"
+
+IMAGE_FSTYPES += "wic"
+WKS_FILE = "overlayfs_etc.wks.in"
+
+EXTRA_IMAGE_FEATURES += "read-only-rootfs"
+# Image configuration for overlayfs-etc
+OVERLAYFS_ETC_MOUNT_POINT = "/data"
+OVERLAYFS_ETC_DEVICE = "/dev/sda3"
+{appendToConfig}
+"""
+
+ self.write_config(config)
+
+ bitbake('core-image-minimal')
+
+ with runqemu('core-image-minimal', image_fstype='wic') as qemu:
+ status, output = qemu.run_serial("/bin/mount")
+
+ line = getline_qemu(output, "upperdir=/data/overlay-etc/upper")
+ self.assertFalse(line, msg=output)
+
+ def test_sbin_init_preinit(self):
+ self.run_sbin_init(False)
+
+ def test_sbin_init_original(self):
+ self.run_sbin_init(True)
+
+ def run_sbin_init(self, origInit):
+ """
+ Summary: Confirm we can replace original init and mount overlay on top of /etc
+ Expected: Image is created successfully and /etc is mounted as an overlay
+ Author: Vyacheslav Yurkov <uvv.mail@gmail.com>
+ """
+
+ config = """
+DISTRO_FEATURES += "systemd"
+
+# Use systemd as init manager
+VIRTUAL-RUNTIME_init_manager = "systemd"
+
+# enable overlayfs in the kernel
+KERNEL_EXTRA_FEATURES:append = " features/overlayfs/overlayfs.scc"
+
+IMAGE_FSTYPES += "wic"
+OVERLAYFS_INIT_OPTION = "{OVERLAYFS_INIT_OPTION}"
+WKS_FILE = "overlayfs_etc.wks.in"
+
+EXTRA_IMAGE_FEATURES += "read-only-rootfs"
+# Image configuration for overlayfs-etc
+EXTRA_IMAGE_FEATURES += "overlayfs-etc"
+IMAGE_FEATURES:remove = "package-management"
+OVERLAYFS_ETC_MOUNT_POINT = "/data"
+OVERLAYFS_ETC_FSTYPE = "ext4"
+OVERLAYFS_ETC_DEVICE = "/dev/sda3"
+OVERLAYFS_ETC_USE_ORIG_INIT_NAME = "{OVERLAYFS_ETC_USE_ORIG_INIT_NAME}"
+"""
+
+ args = {
+ 'OVERLAYFS_INIT_OPTION': "" if origInit else "init=/sbin/preinit",
+ 'OVERLAYFS_ETC_USE_ORIG_INIT_NAME': int(origInit == True)
+ }
+
+ self.write_config(config.format(**args))
+
+ bitbake('core-image-minimal')
+ testFile = "/etc/my-test-data"
+
+ with runqemu('core-image-minimal', image_fstype='wic', discard_writes=False) as qemu:
+ status, output = qemu.run_serial("/bin/mount")
+
+ line = getline_qemu(output, "/dev/sda3")
+ self.assertTrue("/data" in output, msg=output)
+
+ line = getline_qemu(output, "upperdir=/data/overlay-etc/upper")
+ self.assertTrue(line and line.startswith("/data/overlay-etc/upper on /etc type overlay"), msg=output)
+
+ status, output = qemu.run_serial("touch " + testFile)
+ status, output = qemu.run_serial("sync")
+ status, output = qemu.run_serial("ls -1 " + testFile)
+ line = getline_qemu(output, testFile)
+ self.assertTrue(line and line.startswith(testFile), msg=output)
+
+ # Check that file exists in /etc after reboot
+ with runqemu('core-image-minimal', image_fstype='wic') as qemu:
+ status, output = qemu.run_serial("ls -1 " + testFile)
+ line = getline_qemu(output, testFile)
+ self.assertTrue(line and line.startswith(testFile), msg=output)
diff --git a/meta/lib/oeqa/selftest/cases/package.py b/meta/lib/oeqa/selftest/cases/package.py
index 7166c3991f..cebbb4f3f4 100644
--- a/meta/lib/oeqa/selftest/cases/package.py
+++ b/meta/lib/oeqa/selftest/cases/package.py
@@ -116,9 +116,9 @@ class PackageTests(OESelftestTestCase):
# Verify gdb to read symbols from separated debug hardlink file correctly
def test_gdb_hardlink_debug(self):
- features = 'IMAGE_INSTALL_append = " selftest-hardlink"\n'
- features += 'IMAGE_INSTALL_append = " selftest-hardlink-dbg"\n'
- features += 'IMAGE_INSTALL_append = " selftest-hardlink-gdb"\n'
+ features = 'IMAGE_INSTALL:append = " selftest-hardlink"\n'
+ features += 'IMAGE_INSTALL:append = " selftest-hardlink-dbg"\n'
+ features += 'IMAGE_INSTALL:append = " selftest-hardlink-gdb"\n'
self.write_config(features)
bitbake("core-image-minimal")
@@ -151,7 +151,7 @@ class PackageTests(OESelftestTestCase):
def test_preserve_ownership(self):
import os, stat, oe.cachedpath
- features = 'IMAGE_INSTALL_append = " selftest-chown"\n'
+ features = 'IMAGE_INSTALL:append = " selftest-chown"\n'
self.write_config(features)
bitbake("core-image-minimal")
diff --git a/meta/lib/oeqa/selftest/cases/prservice.py b/meta/lib/oeqa/selftest/cases/prservice.py
index 578b2b4dd9..10158ca7c2 100644
--- a/meta/lib/oeqa/selftest/cases/prservice.py
+++ b/meta/lib/oeqa/selftest/cases/prservice.py
@@ -40,7 +40,7 @@ class BitbakePrTests(OESelftestTestCase):
return str(stamps[0])
def increment_package_pr(self, package_name):
- inc_data = "do_package_append() {\n bb.build.exec_func('do_test_prserv', d)\n}\ndo_test_prserv() {\necho \"The current date is: %s\" > ${PKGDESTWORK}/${PN}.datestamp\n}" % datetime.datetime.now()
+ inc_data = "do_package:append() {\n bb.build.exec_func('do_test_prserv', d)\n}\ndo_test_prserv() {\necho \"The current date is: %s\" > ${PKGDESTWORK}/${PN}.datestamp\n}" % datetime.datetime.now()
self.write_recipeinc(package_name, inc_data)
res = bitbake(package_name, ignore_status=True)
self.delete_recipeinc(package_name)
diff --git a/meta/lib/oeqa/selftest/cases/recipetool.py b/meta/lib/oeqa/selftest/cases/recipetool.py
index f0685d3718..510dae6bad 100644
--- a/meta/lib/oeqa/selftest/cases/recipetool.py
+++ b/meta/lib/oeqa/selftest/cases/recipetool.py
@@ -25,7 +25,7 @@ def tearDownModule():
runCmd('rm -rf %s' % templayerdir)
-class RecipetoolBase(devtool.DevtoolBase):
+class RecipetoolBase(devtool.DevtoolTestCase):
def setUpLocal(self):
super(RecipetoolBase, self).setUpLocal()
@@ -68,17 +68,16 @@ class RecipetoolBase(devtool.DevtoolBase):
return bbappendfile, result.output
-class RecipetoolTests(RecipetoolBase):
+class RecipetoolAppendTests(RecipetoolBase):
@classmethod
def setUpClass(cls):
- super(RecipetoolTests, cls).setUpClass()
+ super(RecipetoolAppendTests, cls).setUpClass()
# Ensure we have the right data in shlibs/pkgdata
cls.logger.info('Running bitbake to generate pkgdata')
bitbake('-c packagedata base-files coreutils busybox selftest-recipetool-appendfile')
- bb_vars = get_bb_vars(['COREBASE', 'BBPATH'])
+ bb_vars = get_bb_vars(['COREBASE'])
cls.corebase = bb_vars['COREBASE']
- cls.bbpath = bb_vars['BBPATH']
def _try_recipetool_appendfile(self, testrecipe, destfile, newfile, options, expectedlines, expectedfiles):
cmd = 'recipetool appendfile %s %s %s %s' % (self.templayerdir, destfile, newfile, options)
@@ -94,7 +93,7 @@ class RecipetoolTests(RecipetoolBase):
def test_recipetool_appendfile_basic(self):
# Basic test
- expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
'\n']
_, output = self._try_recipetool_appendfile('base-files', '/etc/motd', self.testfile, '', expectedlines, ['motd'])
self.assertNotIn('WARNING: ', output)
@@ -112,11 +111,11 @@ class RecipetoolTests(RecipetoolBase):
# Need a test file - should be executable
testfile2 = os.path.join(self.corebase, 'oe-init-build-env')
testfile2name = os.path.basename(testfile2)
- expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
'\n',
'SRC_URI += "file://%s"\n' % testfile2name,
'\n',
- 'do_install_append() {\n',
+ 'do_install:append() {\n',
' install -d ${D}${base_bindir}\n',
' install -m 0755 ${WORKDIR}/%s ${D}${base_bindir}/ls\n' % testfile2name,
'}\n']
@@ -138,11 +137,11 @@ class RecipetoolTests(RecipetoolBase):
def test_recipetool_appendfile_add(self):
# Try arbitrary file add to a recipe
- expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
'\n',
'SRC_URI += "file://testfile"\n',
'\n',
- 'do_install_append() {\n',
+ 'do_install:append() {\n',
' install -d ${D}${datadir}\n',
' install -m 0644 ${WORKDIR}/testfile ${D}${datadir}/something\n',
'}\n']
@@ -151,13 +150,13 @@ class RecipetoolTests(RecipetoolBase):
# (so we're testing that, plus modifying an existing bbappend)
testfile2 = os.path.join(self.corebase, 'oe-init-build-env')
testfile2name = os.path.basename(testfile2)
- expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
'\n',
'SRC_URI += "file://testfile \\\n',
' file://%s \\\n' % testfile2name,
' "\n',
'\n',
- 'do_install_append() {\n',
+ 'do_install:append() {\n',
' install -d ${D}${datadir}\n',
' install -m 0644 ${WORKDIR}/testfile ${D}${datadir}/something\n',
' install -m 0755 ${WORKDIR}/%s ${D}${datadir}/scriptname\n' % testfile2name,
@@ -166,11 +165,11 @@ class RecipetoolTests(RecipetoolBase):
def test_recipetool_appendfile_add_bindir(self):
# Try arbitrary file add to a recipe, this time to a location such that should be installed as executable
- expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
'\n',
'SRC_URI += "file://testfile"\n',
'\n',
- 'do_install_append() {\n',
+ 'do_install:append() {\n',
' install -d ${D}${bindir}\n',
' install -m 0755 ${WORKDIR}/testfile ${D}${bindir}/selftest-recipetool-testbin\n',
'}\n']
@@ -179,13 +178,13 @@ class RecipetoolTests(RecipetoolBase):
def test_recipetool_appendfile_add_machine(self):
# Try arbitrary file add to a recipe, this time to a location such that should be installed as executable
- expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
'\n',
'PACKAGE_ARCH = "${MACHINE_ARCH}"\n',
'\n',
- 'SRC_URI_append_mymachine = " file://testfile"\n',
+ 'SRC_URI:append:mymachine = " file://testfile"\n',
'\n',
- 'do_install_append_mymachine() {\n',
+ 'do_install:append:mymachine() {\n',
' install -d ${D}${datadir}\n',
' install -m 0644 ${WORKDIR}/testfile ${D}${datadir}/something\n',
'}\n']
@@ -194,32 +193,32 @@ class RecipetoolTests(RecipetoolBase):
def test_recipetool_appendfile_orig(self):
# A file that's in SRC_URI and in do_install with the same name
- expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
'\n']
_, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/usr/share/selftest-replaceme-orig', self.testfile, '', expectedlines, ['selftest-replaceme-orig'])
self.assertNotIn('WARNING: ', output)
def test_recipetool_appendfile_todir(self):
# A file that's in SRC_URI and in do_install with destination directory rather than file
- expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
'\n']
_, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/usr/share/selftest-replaceme-todir', self.testfile, '', expectedlines, ['selftest-replaceme-todir'])
self.assertNotIn('WARNING: ', output)
def test_recipetool_appendfile_renamed(self):
# A file that's in SRC_URI with a different name to the destination file
- expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
'\n']
_, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/usr/share/selftest-replaceme-renamed', self.testfile, '', expectedlines, ['file1'])
self.assertNotIn('WARNING: ', output)
def test_recipetool_appendfile_subdir(self):
# A file that's in SRC_URI in a subdir
- expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
'\n',
'SRC_URI += "file://testfile"\n',
'\n',
- 'do_install_append() {\n',
+ 'do_install:append() {\n',
' install -d ${D}${datadir}\n',
' install -m 0644 ${WORKDIR}/testfile ${D}${datadir}/selftest-replaceme-subdir\n',
'}\n']
@@ -228,25 +227,25 @@ class RecipetoolTests(RecipetoolBase):
def test_recipetool_appendfile_inst_glob(self):
# A file that's in do_install as a glob
- expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
'\n']
_, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/usr/share/selftest-replaceme-inst-globfile', self.testfile, '', expectedlines, ['selftest-replaceme-inst-globfile'])
self.assertNotIn('WARNING: ', output)
def test_recipetool_appendfile_inst_todir_glob(self):
# A file that's in do_install as a glob with destination as a directory
- expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
'\n']
_, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/usr/share/selftest-replaceme-inst-todir-globfile', self.testfile, '', expectedlines, ['selftest-replaceme-inst-todir-globfile'])
self.assertNotIn('WARNING: ', output)
def test_recipetool_appendfile_patch(self):
# A file that's added by a patch in SRC_URI
- expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
'\n',
'SRC_URI += "file://testfile"\n',
'\n',
- 'do_install_append() {\n',
+ 'do_install:append() {\n',
' install -d ${D}${sysconfdir}\n',
' install -m 0644 ${WORKDIR}/testfile ${D}${sysconfdir}/selftest-replaceme-patched\n',
'}\n']
@@ -260,11 +259,11 @@ class RecipetoolTests(RecipetoolBase):
def test_recipetool_appendfile_script(self):
# Now, a file that's in SRC_URI but installed by a script (so no mention in do_install)
- expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
'\n',
'SRC_URI += "file://testfile"\n',
'\n',
- 'do_install_append() {\n',
+ 'do_install:append() {\n',
' install -d ${D}${datadir}\n',
' install -m 0644 ${WORKDIR}/testfile ${D}${datadir}/selftest-replaceme-scripted\n',
'}\n']
@@ -273,7 +272,7 @@ class RecipetoolTests(RecipetoolBase):
def test_recipetool_appendfile_inst_func(self):
# A file that's installed from a function called by do_install
- expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
'\n']
_, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/usr/share/selftest-replaceme-inst-func', self.testfile, '', expectedlines, ['selftest-replaceme-inst-func'])
self.assertNotIn('WARNING: ', output)
@@ -283,11 +282,11 @@ class RecipetoolTests(RecipetoolBase):
# First try without specifying recipe
self._try_recipetool_appendfile_fail('/usr/share/selftest-replaceme-postinst', self.testfile, ['File /usr/share/selftest-replaceme-postinst may be written out in a pre/postinstall script of the following recipes:', 'selftest-recipetool-appendfile'])
# Now specify recipe
- expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
'\n',
'SRC_URI += "file://testfile"\n',
'\n',
- 'do_install_append() {\n',
+ 'do_install:append() {\n',
' install -d ${D}${datadir}\n',
' install -m 0644 ${WORKDIR}/testfile ${D}${datadir}/selftest-replaceme-postinst\n',
'}\n']
@@ -332,6 +331,9 @@ class RecipetoolTests(RecipetoolBase):
filename = try_appendfile_wc('-w')
self.assertEqual(filename, recipefn.split('_')[0] + '_%.bbappend')
+
+class RecipetoolCreateTests(RecipetoolBase):
+
def test_recipetool_create(self):
# Try adding a recipe
tempsrc = os.path.join(self.tempdir, 'srctree')
@@ -341,14 +343,14 @@ class RecipetoolTests(RecipetoolBase):
result = runCmd('recipetool create -o %s %s -x %s' % (recipefile, srcuri, tempsrc))
self.assertTrue(os.path.isfile(recipefile))
checkvars = {}
- checkvars['LICENSE'] = 'GPLv2'
+ checkvars['LICENSE'] = 'GPL-2.0-only'
checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263'
checkvars['SRC_URI'] = 'https://github.com/logrotate/logrotate/releases/download/${PV}/logrotate-${PV}.tar.xz'
checkvars['SRC_URI[md5sum]'] = 'a560c57fac87c45b2fc17406cdf79288'
checkvars['SRC_URI[sha256sum]'] = '2e6a401cac9024db2288297e3be1a8ab60e7401ba8e91225218aaf4a27e82a07'
self._test_recipe_contents(recipefile, checkvars, [])
- def test_recipetool_create_git(self):
+ def test_recipetool_create_autotools(self):
if 'x11' not in get_bb_var('DISTRO_FEATURES'):
self.skipTest('Test requires x11 as distro feature')
# Ensure we have the right data in shlibs/pkgdata
@@ -361,11 +363,11 @@ class RecipetoolTests(RecipetoolBase):
result = runCmd(['recipetool', 'create', '-o', recipefile, srcuri + ";rev=9f7cf8895ae2d39c465c04cc78e918c157420269", '-x', tempsrc])
self.assertTrue(os.path.isfile(recipefile), 'recipetool did not create recipe file; output:\n%s' % result.output)
checkvars = {}
- checkvars['LICENSE'] = 'LGPLv2.1'
+ checkvars['LICENSE'] = 'LGPL-2.1-only'
checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=7fbc338309ac38fefcd64b04bb903e34'
checkvars['S'] = '${WORKDIR}/git'
checkvars['PV'] = '1.11+git${SRCPV}'
- checkvars['SRC_URI'] = srcuri
+ checkvars['SRC_URI'] = srcuri + ';branch=master'
checkvars['DEPENDS'] = set(['libcheck', 'libjpeg-turbo', 'libpng', 'libx11', 'libxext', 'pango'])
inherits = ['autotools', 'pkgconfig']
self._test_recipe_contents(recipefile, checkvars, inherits)
@@ -375,7 +377,7 @@ class RecipetoolTests(RecipetoolBase):
temprecipe = os.path.join(self.tempdir, 'recipe')
os.makedirs(temprecipe)
pv = '1.7.4.1'
- srcuri = 'http://www.dest-unreach.org/socat/download/socat-%s.tar.bz2' % pv
+ srcuri = 'http://www.dest-unreach.org/socat/download/Archive/socat-%s.tar.bz2' % pv
result = runCmd('recipetool create %s -o %s' % (srcuri, temprecipe))
dirlist = os.listdir(temprecipe)
if len(dirlist) > 1:
@@ -384,7 +386,7 @@ class RecipetoolTests(RecipetoolBase):
self.fail('recipetool did not create recipe file; output:\n%s\ndirlist:\n%s' % (result.output, str(dirlist)))
self.assertEqual(dirlist[0], 'socat_%s.bb' % pv, 'Recipe file incorrectly named')
checkvars = {}
- checkvars['LICENSE'] = set(['Unknown', 'GPLv2'])
+ checkvars['LICENSE'] = set(['Unknown', 'GPL-2.0-only'])
checkvars['LIC_FILES_CHKSUM'] = set(['file://COPYING.OpenSSL;md5=5c9bccc77f67a8328ef4ebaf468116f4', 'file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263'])
# We don't check DEPENDS since they are variable for this recipe depending on what's in the sysroot
checkvars['S'] = None
@@ -400,7 +402,7 @@ class RecipetoolTests(RecipetoolBase):
result = runCmd('recipetool create -o %s %s' % (temprecipe, srcuri))
self.assertTrue(os.path.isfile(recipefile))
checkvars = {}
- checkvars['LICENSE'] = set(['LGPLv2.1', 'MPL-1.1'])
+ checkvars['LICENSE'] = set(['LGPL-2.1-only', 'MPL-1.1-only'])
checkvars['SRC_URI'] = 'http://taglib.github.io/releases/taglib-${PV}.tar.gz'
checkvars['SRC_URI[md5sum]'] = 'cee7be0ccfc892fa433d6c837df9522a'
checkvars['SRC_URI[sha256sum]'] = 'b6d1a5a610aae6ff39d93de5efd0fdc787aa9e9dc1e7026fa4c961b26563526b'
@@ -424,16 +426,16 @@ class RecipetoolTests(RecipetoolBase):
checkvars = {}
checkvars['SUMMARY'] = 'Node Server Example'
checkvars['HOMEPAGE'] = 'https://github.com/savoirfairelinux/node-server-example#readme'
- checkvars['LICENSE'] = set(['MIT', 'ISC', 'Unknown'])
+ checkvars['LICENSE'] = 'BSD-3-Clause & ISC & MIT & Unknown'
urls = []
urls.append('npm://registry.npmjs.org/;package=@savoirfairelinux/node-server-example;version=${PV}')
urls.append('npmsw://${THISDIR}/${BPN}/npm-shrinkwrap.json')
checkvars['SRC_URI'] = set(urls)
checkvars['S'] = '${WORKDIR}/npm'
- checkvars['LICENSE_${PN}'] = 'MIT'
- checkvars['LICENSE_${PN}-base64'] = 'Unknown'
- checkvars['LICENSE_${PN}-accepts'] = 'MIT'
- checkvars['LICENSE_${PN}-inherits'] = 'ISC'
+ checkvars['LICENSE:${PN}'] = 'MIT'
+ checkvars['LICENSE:${PN}-base64'] = 'Unknown'
+ checkvars['LICENSE:${PN}-accepts'] = 'MIT'
+ checkvars['LICENSE:${PN}-inherits'] = 'ISC'
inherits = ['npm']
self._test_recipe_contents(recipefile, checkvars, inherits)
@@ -447,7 +449,7 @@ class RecipetoolTests(RecipetoolBase):
self.assertTrue(os.path.isfile(recipefile))
checkvars = {}
checkvars['LICENSE'] = set(['Apache-2.0'])
- checkvars['SRC_URI'] = 'git://github.com/mesonbuild/meson;protocol=https'
+ checkvars['SRC_URI'] = 'git://github.com/mesonbuild/meson;protocol=https;branch=master'
inherits = ['setuptools3']
self._test_recipe_contents(recipefile, checkvars, inherits)
@@ -470,25 +472,6 @@ class RecipetoolTests(RecipetoolBase):
inherits = ['setuptools3']
self._test_recipe_contents(recipefile, checkvars, inherits)
- def test_recipetool_create_python3_distutils(self):
- # Test creating python3 package from tarball (using distutils3 class)
- temprecipe = os.path.join(self.tempdir, 'recipe')
- os.makedirs(temprecipe)
- pn = 'docutils'
- pv = '0.14'
- recipefile = os.path.join(temprecipe, '%s_%s.bb' % (pn, pv))
- srcuri = 'https://files.pythonhosted.org/packages/84/f4/5771e41fdf52aabebbadecc9381d11dea0fa34e4759b4071244fa094804c/docutils-%s.tar.gz' % pv
- result = runCmd('recipetool create -o %s %s' % (temprecipe, srcuri))
- self.assertTrue(os.path.isfile(recipefile))
- checkvars = {}
- checkvars['LICENSE'] = set(['PSF', '&', 'BSD', 'GPL'])
- checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING.txt;md5=35a23d42b615470583563132872c97d6'
- checkvars['SRC_URI'] = 'https://files.pythonhosted.org/packages/84/f4/5771e41fdf52aabebbadecc9381d11dea0fa34e4759b4071244fa094804c/docutils-${PV}.tar.gz'
- checkvars['SRC_URI[md5sum]'] = 'c53768d63db3873b7d452833553469de'
- checkvars['SRC_URI[sha256sum]'] = '51e64ef2ebfb29cae1faa133b3710143496eca21c530f3f71424d77687764274'
- inherits = ['distutils3']
- self._test_recipe_contents(recipefile, checkvars, inherits)
-
def test_recipetool_create_github_tarball(self):
# Basic test to ensure github URL mangling doesn't apply to release tarballs
temprecipe = os.path.join(self.tempdir, 'recipe')
@@ -504,19 +487,48 @@ class RecipetoolTests(RecipetoolBase):
inherits = ['setuptools3']
self._test_recipe_contents(recipefile, checkvars, inherits)
- def test_recipetool_create_git_http(self):
+ def _test_recipetool_create_git(self, srcuri, branch=None):
# Basic test to check http git URL mangling works
temprecipe = os.path.join(self.tempdir, 'recipe')
os.makedirs(temprecipe)
- recipefile = os.path.join(temprecipe, 'matchbox-terminal_git.bb')
- srcuri = 'http://git.yoctoproject.org/git/matchbox-terminal'
- result = runCmd('recipetool create -o %s %s' % (temprecipe, srcuri))
+ name = srcuri.split(';')[0].split('/')[-1]
+ recipefile = os.path.join(temprecipe, name + '_git.bb')
+ options = ' -B %s' % branch if branch else ''
+ result = runCmd('recipetool create -o %s%s "%s"' % (temprecipe, options, srcuri))
self.assertTrue(os.path.isfile(recipefile))
checkvars = {}
- checkvars['LICENSE'] = set(['GPLv2'])
- checkvars['SRC_URI'] = 'git://git.yoctoproject.org/git/matchbox-terminal;protocol=http'
- inherits = ['pkgconfig', 'autotools']
- self._test_recipe_contents(recipefile, checkvars, inherits)
+ checkvars['SRC_URI'] = srcuri
+ for scheme in ['http', 'https']:
+ if srcuri.startswith(scheme + ":"):
+ checkvars['SRC_URI'] = 'git%s;protocol=%s' % (srcuri[len(scheme):], scheme)
+ if ';branch=' not in srcuri:
+ checkvars['SRC_URI'] += ';branch=' + (branch or 'master')
+ self._test_recipe_contents(recipefile, checkvars, [])
+
+ def test_recipetool_create_git_http(self):
+ self._test_recipetool_create_git('http://git.yoctoproject.org/git/matchbox-keyboard')
+
+ def test_recipetool_create_git_srcuri_master(self):
+ self._test_recipetool_create_git('git://git.yoctoproject.org/matchbox-keyboard;branch=master')
+
+ def test_recipetool_create_git_srcuri_branch(self):
+ self._test_recipetool_create_git('git://git.yoctoproject.org/matchbox-keyboard;branch=matchbox-keyboard-0-1')
+
+ def test_recipetool_create_git_srcbranch(self):
+ self._test_recipetool_create_git('git://git.yoctoproject.org/matchbox-keyboard', 'matchbox-keyboard-0-1')
+
+
+class RecipetoolTests(RecipetoolBase):
+
+ @classmethod
+ def setUpClass(cls):
+ import sys
+
+ super(RecipetoolTests, cls).setUpClass()
+ bb_vars = get_bb_vars(['BBPATH'])
+ cls.bbpath = bb_vars['BBPATH']
+ libpath = os.path.join(get_bb_var('COREBASE'), 'scripts', 'lib', 'recipetool')
+ sys.path.insert(0, libpath)
def _copy_file_with_cleanup(self, srcfile, basedstdir, *paths):
dstdir = basedstdir
@@ -561,6 +573,128 @@ class RecipetoolTests(RecipetoolBase):
with open(srcfile, 'w') as fh:
fh.writelines(plugincontent)
+ def test_recipetool_handle_license_vars(self):
+ from create import handle_license_vars
+ from unittest.mock import Mock
+
+ commonlicdir = get_bb_var('COMMON_LICENSE_DIR')
+
+ d = bb.tinfoil.TinfoilDataStoreConnector
+ d.getVar = Mock(return_value=commonlicdir)
+
+ srctree = tempfile.mkdtemp(prefix='recipetoolqa')
+ self.track_for_cleanup(srctree)
+
+ # Multiple licenses
+ licenses = ['MIT', 'ISC', 'BSD-3-Clause', 'Apache-2.0']
+ for licence in licenses:
+ shutil.copy(os.path.join(commonlicdir, licence), os.path.join(srctree, 'LICENSE.' + licence))
+ # Duplicate license
+ shutil.copy(os.path.join(commonlicdir, 'MIT'), os.path.join(srctree, 'LICENSE'))
+
+ extravalues = {
+ # Duplicate and missing licenses
+ 'LICENSE': 'Zlib & BSD-2-Clause & Zlib',
+ 'LIC_FILES_CHKSUM': [
+ 'file://README.md;md5=0123456789abcdef0123456789abcd'
+ ]
+ }
+ lines_before = []
+ handled = []
+ licvalues = handle_license_vars(srctree, lines_before, handled, extravalues, d)
+ expected_lines_before = [
+ '# WARNING: the following LICENSE and LIC_FILES_CHKSUM values are best guesses - it is',
+ '# your responsibility to verify that the values are complete and correct.',
+ '# NOTE: Original package / source metadata indicates license is: BSD-2-Clause & Zlib',
+ '#',
+ '# NOTE: multiple licenses have been detected; they have been separated with &',
+ '# in the LICENSE value for now since it is a reasonable assumption that all',
+ '# of the licenses apply. If instead there is a choice between the multiple',
+ '# licenses then you should change the value to separate the licenses with |',
+ '# instead of &. If there is any doubt, check the accompanying documentation',
+ '# to determine which situation is applicable.',
+ 'LICENSE = "Apache-2.0 & BSD-2-Clause & BSD-3-Clause & ISC & MIT & Zlib"',
+ 'LIC_FILES_CHKSUM = "file://LICENSE;md5=0835ade698e0bcf8506ecda2f7b4f302 \\\n'
+ ' file://LICENSE.Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10 \\\n'
+ ' file://LICENSE.BSD-3-Clause;md5=550794465ba0ec5312d6919e203a55f9 \\\n'
+ ' file://LICENSE.ISC;md5=f3b90e78ea0cffb20bf5cca7947a896d \\\n'
+ ' file://LICENSE.MIT;md5=0835ade698e0bcf8506ecda2f7b4f302 \\\n'
+ ' file://README.md;md5=0123456789abcdef0123456789abcd"',
+ ''
+ ]
+ self.assertEqual(lines_before, expected_lines_before)
+ expected_licvalues = [
+ ('MIT', 'LICENSE', '0835ade698e0bcf8506ecda2f7b4f302'),
+ ('Apache-2.0', 'LICENSE.Apache-2.0', '89aea4e17d99a7cacdbeed46a0096b10'),
+ ('BSD-3-Clause', 'LICENSE.BSD-3-Clause', '550794465ba0ec5312d6919e203a55f9'),
+ ('ISC', 'LICENSE.ISC', 'f3b90e78ea0cffb20bf5cca7947a896d'),
+ ('MIT', 'LICENSE.MIT', '0835ade698e0bcf8506ecda2f7b4f302')
+ ]
+ self.assertEqual(handled, [('license', expected_licvalues)])
+ self.assertEqual(extravalues, {})
+ self.assertEqual(licvalues, expected_licvalues)
+
+
+ def test_recipetool_split_pkg_licenses(self):
+ from create import split_pkg_licenses
+ licvalues = [
+ # Duplicate licenses
+ ('BSD-2-Clause', 'x/COPYING', None),
+ ('BSD-2-Clause', 'x/LICENSE', None),
+ # Multiple licenses
+ ('MIT', 'x/a/LICENSE.MIT', None),
+ ('ISC', 'x/a/LICENSE.ISC', None),
+ # Alternative licenses
+ ('(MIT | ISC)', 'x/b/LICENSE', None),
+ # Alternative licenses without brackets
+ ('MIT | BSD-2-Clause', 'x/c/LICENSE', None),
+ # Multi licenses with alternatives
+ ('MIT', 'x/d/COPYING', None),
+ ('MIT | BSD-2-Clause', 'x/d/LICENSE', None),
+ # Multi licenses with alternatives and brackets
+ ('Apache-2.0 & ((MIT | ISC) & BSD-3-Clause)', 'x/e/LICENSE', None)
+ ]
+ packages = {
+ '${PN}': '',
+ 'a': 'x/a',
+ 'b': 'x/b',
+ 'c': 'x/c',
+ 'd': 'x/d',
+ 'e': 'x/e',
+ 'f': 'x/f',
+ 'g': 'x/g',
+ }
+ fallback_licenses = {
+ # Ignored
+ 'a': 'BSD-3-Clause',
+ # Used
+ 'f': 'BSD-3-Clause'
+ }
+ outlines = []
+ outlicenses = split_pkg_licenses(licvalues, packages, outlines, fallback_licenses)
+ expected_outlicenses = {
+ '${PN}': ['BSD-2-Clause'],
+ 'a': ['ISC', 'MIT'],
+ 'b': ['(ISC | MIT)'],
+ 'c': ['(BSD-2-Clause | MIT)'],
+ 'd': ['(BSD-2-Clause | MIT)', 'MIT'],
+ 'e': ['(ISC | MIT)', 'Apache-2.0', 'BSD-3-Clause'],
+ 'f': ['BSD-3-Clause'],
+ 'g': ['Unknown']
+ }
+ self.assertEqual(outlicenses, expected_outlicenses)
+ expected_outlines = [
+ 'LICENSE:${PN} = "BSD-2-Clause"',
+ 'LICENSE:a = "ISC & MIT"',
+ 'LICENSE:b = "(ISC | MIT)"',
+ 'LICENSE:c = "(BSD-2-Clause | MIT)"',
+ 'LICENSE:d = "(BSD-2-Clause | MIT) & MIT"',
+ 'LICENSE:e = "(ISC | MIT) & Apache-2.0 & BSD-3-Clause"',
+ 'LICENSE:f = "BSD-3-Clause"',
+ 'LICENSE:g = "Unknown"'
+ ]
+ self.assertEqual(outlines, expected_outlines)
+
class RecipetoolAppendsrcBase(RecipetoolBase):
def _try_recipetool_appendsrcfile(self, testrecipe, newfile, destfile, options, expectedlines, expectedfiles):
@@ -620,7 +754,7 @@ class RecipetoolAppendsrcBase(RecipetoolBase):
else:
destpath = '.' + os.sep
- expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
'\n']
if has_src_uri:
uri = 'file://%s' % filename
diff --git a/meta/lib/oeqa/selftest/cases/recipeutils.py b/meta/lib/oeqa/selftest/cases/recipeutils.py
index 747870383b..f1dd63f65b 100644
--- a/meta/lib/oeqa/selftest/cases/recipeutils.py
+++ b/meta/lib/oeqa/selftest/cases/recipeutils.py
@@ -40,7 +40,7 @@ class RecipeUtilsTests(OESelftestTestCase):
SUMMARY = "Python framework to process interdependent tasks in a pool of workers"
HOMEPAGE = "http://github.com/gitpython-developers/async"
SECTION = "devel/python"
--LICENSE = "BSD"
+-LICENSE = "BSD-3-Clause"
+LICENSE = "something"
LIC_FILES_CHKSUM = "file://PKG-INFO;beginline=8;endline=8;md5=88df8e78b9edfd744953862179f2d14e"
@@ -52,7 +52,7 @@ class RecipeUtilsTests(OESelftestTestCase):
+SRC_URI[md5sum] = "aaaaaa"
SRC_URI[sha256sum] = "ac6894d876e45878faae493b0cf61d0e28ec417334448ac0a6ea2229d8343051"
- RDEPENDS_${PN} += "${PYTHON_PN}-threading"
+ RDEPENDS:${PN} += "${PYTHON_PN}-threading"
"""
patchlines = []
for f in patches:
@@ -80,7 +80,7 @@ class RecipeUtilsTests(OESelftestTestCase):
-SRC_URI += "file://somefile"
-
- SRC_URI_append = " file://anotherfile"
+ SRC_URI:append = " file://anotherfile"
"""
patchlines = []
for f in patches:
@@ -105,7 +105,7 @@ class RecipeUtilsTests(OESelftestTestCase):
-SRC_URI += "file://somefile"
-
--SRC_URI_append = " file://anotherfile"
+-SRC_URI:append = " file://anotherfile"
"""
patchlines = []
for f in patches:
diff --git a/meta/lib/oeqa/selftest/cases/reproducible.py b/meta/lib/oeqa/selftest/cases/reproducible.py
index a62757399b..7caf8c3e7d 100644
--- a/meta/lib/oeqa/selftest/cases/reproducible.py
+++ b/meta/lib/oeqa/selftest/cases/reproducible.py
@@ -17,23 +17,7 @@ import stat
import os
import datetime
-# For sample packages, see:
-# https://autobuilder.yocto.io/pub/repro-fail/oe-reproducible-20201127-0t7wr_oo/
-# https://autobuilder.yocto.io/pub/repro-fail/oe-reproducible-20201127-4s9ejwyp/
-# https://autobuilder.yocto.io/pub/repro-fail/oe-reproducible-20201127-haiwdlbr/
-# https://autobuilder.yocto.io/pub/repro-fail/oe-reproducible-20201127-hwds3mcl/
-# https://autobuilder.yocto.io/pub/repro-fail/oe-reproducible-20201203-sua0pzvc/
-# (both packages/ and packages-excluded/)
-
-# ruby-ri-docs, meson:
-#https://autobuilder.yocto.io/pub/repro-fail/oe-reproducible-20210215-0_td9la2/packages/diff-html/
exclude_packages = [
- 'glide',
- 'go-helloworld',
- 'go-runtime',
- 'go_',
- 'go-',
- 'ruby-ri-docs'
]
def is_excluded(package):
@@ -114,8 +98,9 @@ def compare_file(reference, test, diffutils_sysroot):
result.status = SAME
return result
-def run_diffoscope(a_dir, b_dir, html_dir, **kwargs):
- return runCmd(['diffoscope', '--no-default-limits', '--exclude-directory-metadata', 'yes', '--html-dir', html_dir, a_dir, b_dir],
+def run_diffoscope(a_dir, b_dir, html_dir, max_report_size=0, **kwargs):
+ return runCmd(['diffoscope', '--no-default-limits', '--max-report-size', str(max_report_size),
+ '--exclude-directory-metadata', 'yes', '--html-dir', html_dir, a_dir, b_dir],
**kwargs)
class DiffoscopeTests(OESelftestTestCase):
@@ -145,6 +130,9 @@ class ReproducibleTests(OESelftestTestCase):
package_classes = ['deb', 'ipk', 'rpm']
+ # Maximum report size, in bytes
+ max_report_size = 250 * 1024 * 1024
+
# targets are the things we want to test the reproducibility of
targets = ['core-image-minimal', 'core-image-sato', 'core-image-full-cmdline', 'core-image-weston', 'world']
# sstate targets are things to pull from sstate to potentially cut build/debugging time
@@ -215,12 +203,11 @@ class ReproducibleTests(OESelftestTestCase):
bb.utils.remove(tmpdir, recurse=True)
config = textwrap.dedent('''\
- INHERIT += "reproducible_build"
PACKAGE_CLASSES = "{package_classes}"
INHIBIT_PACKAGE_STRIP = "1"
TMPDIR = "{tmpdir}"
- LICENSE_FLAGS_WHITELIST = "commercial"
- DISTRO_FEATURES_append = ' systemd pam'
+ LICENSE_FLAGS_ACCEPTED = "commercial"
+ DISTRO_FEATURES:append = ' systemd pam'
USERADDEXTENSION = "useradd-staticids"
USERADD_ERROR_DYNAMIC = "skip"
USERADD_UID_TABLES += "files/static-passwd"
@@ -321,7 +308,7 @@ class ReproducibleTests(OESelftestTestCase):
# Copy jquery to improve the diffoscope output usability
self.copy_file(os.path.join(jquery_sysroot, 'usr/share/javascript/jquery/jquery.min.js'), os.path.join(package_html_dir, 'jquery.js'))
- run_diffoscope('reproducibleA', 'reproducibleB', package_html_dir,
+ run_diffoscope('reproducibleA', 'reproducibleB', package_html_dir, max_report_size=self.max_report_size,
native_sysroot=diffoscope_sysroot, ignore_status=True, cwd=package_dir)
if fails:
diff --git a/meta/lib/oeqa/selftest/cases/runtime_test.py b/meta/lib/oeqa/selftest/cases/runtime_test.py
index d0c2440722..642f0eb637 100644
--- a/meta/lib/oeqa/selftest/cases/runtime_test.py
+++ b/meta/lib/oeqa/selftest/cases/runtime_test.py
@@ -120,7 +120,7 @@ class TestImage(OESelftestTestCase):
self.skipTest('core-image-full-cmdline not buildable for poky-tiny')
features = 'INHERIT += "testimage"\n'
- features += 'IMAGE_INSTALL_append = " libssl"\n'
+ features += 'IMAGE_INSTALL:append = " libssl"\n'
features += 'TEST_SUITES = "ping ssh selftest"\n'
self.write_config(features)
@@ -186,14 +186,14 @@ class TestImage(OESelftestTestCase):
qemu_distrofeatures = get_bb_var('DISTRO_FEATURES', 'qemu-system-native')
features = 'INHERIT += "testimage"\n'
if 'gtk+' not in qemu_packageconfig:
- features += 'PACKAGECONFIG_append_pn-qemu-system-native = " gtk+"\n'
+ features += 'PACKAGECONFIG:append:pn-qemu-system-native = " gtk+"\n'
if 'sdl' not in qemu_packageconfig:
- features += 'PACKAGECONFIG_append_pn-qemu-system-native = " sdl"\n'
+ features += 'PACKAGECONFIG:append:pn-qemu-system-native = " sdl"\n'
if 'opengl' not in qemu_distrofeatures:
- features += 'DISTRO_FEATURES_append = " opengl"\n'
+ features += 'DISTRO_FEATURES:append = " opengl"\n'
features += 'TEST_SUITES = "ping ssh virgl"\n'
- features += 'IMAGE_FEATURES_append = " ssh-server-dropbear"\n'
- features += 'IMAGE_INSTALL_append = " kmscube"\n'
+ features += 'IMAGE_FEATURES:append = " ssh-server-dropbear"\n'
+ features += 'IMAGE_INSTALL:append = " kmscube"\n'
features_gtk = features + 'TEST_RUNQEMUPARAMS = "gtk gl"\n'
self.write_config(features_gtk)
bitbake('core-image-minimal')
@@ -212,23 +212,29 @@ class TestImage(OESelftestTestCase):
Author: Alexander Kanavin <alex.kanavin@gmail.com>
"""
import subprocess, os
+
+ distro = oe.lsb.distro_identifier()
+ if distro and distro in ['debian-9', 'debian-10', 'centos-7', 'centos-8', 'ubuntu-16.04', 'ubuntu-18.04', 'almalinux-8.5']:
+ self.skipTest('virgl headless cannot be tested with %s' %(distro))
+
+ render_hint = """If /dev/dri/renderD* is absent due to lack of suitable GPU, 'modprobe vgem' will create one suitable for mesa llvmpipe software renderer."""
try:
content = os.listdir("/dev/dri")
if len([i for i in content if i.startswith('render')]) == 0:
- self.skipTest("No render nodes found in /dev/dri: %s" %(content))
+ self.fail("No render nodes found in /dev/dri: %s. %s" %(content, render_hint))
except FileNotFoundError:
- self.skipTest("/dev/dri directory does not exist; no render nodes available on this machine.")
+ self.fail("/dev/dri directory does not exist; no render nodes available on this machine. %s" %(render_hint))
try:
dripath = subprocess.check_output("pkg-config --variable=dridriverdir dri", shell=True)
except subprocess.CalledProcessError as e:
- self.skipTest("Could not determine the path to dri drivers on the host via pkg-config.\nPlease install Mesa development files (particularly, dri.pc) on the host machine.")
+ self.fail("Could not determine the path to dri drivers on the host via pkg-config.\nPlease install Mesa development files (particularly, dri.pc) on the host machine.")
qemu_distrofeatures = get_bb_var('DISTRO_FEATURES', 'qemu-system-native')
features = 'INHERIT += "testimage"\n'
if 'opengl' not in qemu_distrofeatures:
- features += 'DISTRO_FEATURES_append = " opengl"\n'
+ features += 'DISTRO_FEATURES:append = " opengl"\n'
features += 'TEST_SUITES = "ping ssh virgl"\n'
- features += 'IMAGE_FEATURES_append = " ssh-server-dropbear"\n'
- features += 'IMAGE_INSTALL_append = " kmscube"\n'
+ features += 'IMAGE_FEATURES:append = " ssh-server-dropbear"\n'
+ features += 'IMAGE_INSTALL:append = " kmscube"\n'
features += 'TEST_RUNQEMUPARAMS = "egl-headless"\n'
self.write_config(features)
bitbake('core-image-minimal')
@@ -254,7 +260,7 @@ class Postinst(OESelftestTestCase):
features += 'IMAGE_FEATURES += "package-management empty-root-password"\n'
features += 'PACKAGE_CLASSES = "%s"\n' % classes
if init_manager == "systemd":
- features += 'DISTRO_FEATURES_append = " systemd"\n'
+ features += 'DISTRO_FEATURES:append = " systemd"\n'
features += 'VIRTUAL-RUNTIME_init_manager = "systemd"\n'
features += 'DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"\n'
features += 'VIRTUAL-RUNTIME_initscripts = ""\n'
@@ -371,14 +377,14 @@ TEST_SERVER_IP = "192.168.7.1"
TEST_TARGET_IP = "192.168.7.2"
EXTRA_IMAGE_FEATURES += "tools-profile dbg-pkgs"
-IMAGE_FEATURES_append = " ssh-server-dropbear"
+IMAGE_FEATURES:append = " ssh-server-dropbear"
# enables kernel debug symbols
-KERNEL_EXTRA_FEATURES_append = " features/debug/debug-kernel.scc"
-KERNEL_EXTRA_FEATURES_append = " features/systemtap/systemtap.scc"
+KERNEL_EXTRA_FEATURES:append = " features/debug/debug-kernel.scc"
+KERNEL_EXTRA_FEATURES:append = " features/systemtap/systemtap.scc"
# add systemtap run-time into target image if it is not there yet
-IMAGE_INSTALL_append = " systemtap-runtime"
+IMAGE_INSTALL:append = " systemtap-runtime"
"""
def test_crosstap_helloworld(self):
diff --git a/meta/lib/oeqa/selftest/cases/signing.py b/meta/lib/oeqa/selftest/cases/signing.py
index a28c7eb19a..6f3d4aeae9 100644
--- a/meta/lib/oeqa/selftest/cases/signing.py
+++ b/meta/lib/oeqa/selftest/cases/signing.py
@@ -145,7 +145,7 @@ class Signing(OESelftestTestCase):
feature += 'GPG_PATH = "%s"\n' % self.gpg_dir
feature += 'SSTATE_DIR = "%s"\n' % sstatedir
# Any mirror might have partial sstate without .sig files, triggering failures
- feature += 'SSTATE_MIRRORS_forcevariable = ""\n'
+ feature += 'SSTATE_MIRRORS:forcevariable = ""\n'
self.write_config(feature)
@@ -159,13 +159,13 @@ class Signing(OESelftestTestCase):
bitbake('-c clean %s' % test_recipe)
bitbake('-c populate_lic %s' % test_recipe)
- recipe_sig = glob.glob(sstatedir + '/*/*/*:ed:*_populate_lic.tgz.sig')
- recipe_tgz = glob.glob(sstatedir + '/*/*/*:ed:*_populate_lic.tgz')
+ recipe_sig = glob.glob(sstatedir + '/*/*/*:ed:*_populate_lic.tar.zst.sig')
+ recipe_archive = glob.glob(sstatedir + '/*/*/*:ed:*_populate_lic.tar.zst')
self.assertEqual(len(recipe_sig), 1, 'Failed to find .sig file.')
- self.assertEqual(len(recipe_tgz), 1, 'Failed to find .tgz file.')
+ self.assertEqual(len(recipe_archive), 1, 'Failed to find .tar.zst file.')
- ret = runCmd('gpg --homedir %s --verify %s %s' % (self.gpg_dir, recipe_sig[0], recipe_tgz[0]))
+ ret = runCmd('gpg --homedir %s --verify %s %s' % (self.gpg_dir, recipe_sig[0], recipe_archive[0]))
# gpg: Signature made Thu 22 Oct 2015 01:45:09 PM EEST using RSA key ID 61EEFB30
# gpg: Good signature from "testuser (nocomment) <testuser@email.com>"
self.assertIn('gpg: Good signature from', ret.output, 'Package signed incorrectly.')
@@ -206,7 +206,7 @@ class LockedSignatures(OESelftestTestCase):
# Use uuid so hash equivalance server isn't triggered
recipe_append_file = test_recipe + '_' + get_bb_var('PV', test_recipe) + '.bbappend'
recipe_append_path = os.path.join(templayerdir, 'recipes-test', test_recipe, recipe_append_file)
- feature = 'SUMMARY_${PN} = "test locked signature%s"\n' % uuid.uuid4()
+ feature = 'SUMMARY:${PN} = "test locked signature%s"\n' % uuid.uuid4()
os.mkdir(os.path.join(templayerdir, 'recipes-test'))
os.mkdir(os.path.join(templayerdir, 'recipes-test', test_recipe))
diff --git a/meta/lib/oeqa/selftest/cases/sstatetests.py b/meta/lib/oeqa/selftest/cases/sstatetests.py
index 9db2a0bb44..3038b40021 100644
--- a/meta/lib/oeqa/selftest/cases/sstatetests.py
+++ b/meta/lib/oeqa/selftest/cases/sstatetests.py
@@ -11,6 +11,7 @@ import tempfile
from oeqa.selftest.case import OESelftestTestCase
from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_test_layer, create_temp_layer
from oeqa.selftest.cases.sstate import SStateBase
+import oe
import bb.siggen
@@ -39,7 +40,7 @@ class SStateTests(SStateBase):
recipefile = os.path.join(tempdir, "recipes-test", "dbus-wait-test", 'dbus-wait-test_git.bb')
os.makedirs(os.path.dirname(recipefile))
- srcuri = 'git://' + srcdir + ';protocol=file'
+ srcuri = 'git://' + srcdir + ';protocol=file;branch=master'
result = runCmd(['recipetool', 'create', '-o', recipefile, srcuri])
self.assertTrue(os.path.isfile(recipefile), 'recipetool did not create recipe file; output:\n%s' % result.output)
@@ -68,7 +69,7 @@ class SStateTests(SStateBase):
results = self.search_sstate('|'.join(map(str, targets)), distro_specific, distro_nonspecific)
if distro_nonspecific:
for r in results:
- if r.endswith(("_populate_lic.tgz", "_populate_lic.tgz.siginfo", "_fetch.tgz.siginfo", "_unpack.tgz.siginfo", "_patch.tgz.siginfo")):
+ if r.endswith(("_populate_lic.tar.zst", "_populate_lic.tar.zst.siginfo", "_fetch.tar.zst.siginfo", "_unpack.tar.zst.siginfo", "_patch.tar.zst.siginfo")):
continue
file_tracker.append(r)
else:
@@ -98,15 +99,15 @@ class SStateTests(SStateBase):
bitbake(['-ccleansstate'] + targets)
bitbake(targets)
- tgz_created = self.search_sstate('|'.join(map(str, [s + r'.*?\.tgz$' for s in targets])), distro_specific, distro_nonspecific)
- self.assertTrue(tgz_created, msg="Could not find sstate .tgz files for: %s (%s)" % (', '.join(map(str, targets)), str(tgz_created)))
+ archives_created = self.search_sstate('|'.join(map(str, [s + r'.*?\.tar.zst$' for s in targets])), distro_specific, distro_nonspecific)
+ self.assertTrue(archives_created, msg="Could not find sstate .tar.zst files for: %s (%s)" % (', '.join(map(str, targets)), str(archives_created)))
siginfo_created = self.search_sstate('|'.join(map(str, [s + r'.*?\.siginfo$' for s in targets])), distro_specific, distro_nonspecific)
self.assertTrue(siginfo_created, msg="Could not find sstate .siginfo files for: %s (%s)" % (', '.join(map(str, targets)), str(siginfo_created)))
bitbake(['-ccleansstate'] + targets)
- tgz_removed = self.search_sstate('|'.join(map(str, [s + r'.*?\.tgz$' for s in targets])), distro_specific, distro_nonspecific)
- self.assertTrue(not tgz_removed, msg="do_cleansstate didn't remove .tgz sstate files for: %s (%s)" % (', '.join(map(str, targets)), str(tgz_removed)))
+ archives_removed = self.search_sstate('|'.join(map(str, [s + r'.*?\.tar.zst$' for s in targets])), distro_specific, distro_nonspecific)
+ self.assertTrue(not archives_removed, msg="do_cleansstate didn't remove .tar.zst sstate files for: %s (%s)" % (', '.join(map(str, targets)), str(archives_removed)))
def test_cleansstate_task_distro_specific_nonspecific(self):
targets = ['binutils-cross-'+ self.tune_arch, 'binutils-native']
@@ -129,15 +130,15 @@ class SStateTests(SStateBase):
bitbake(['-ccleansstate'] + targets)
bitbake(targets)
- results = self.search_sstate('|'.join(map(str, [s + r'.*?\.tgz$' for s in targets])), distro_specific=False, distro_nonspecific=True)
+ results = self.search_sstate('|'.join(map(str, [s + r'.*?\.tar.zst$' for s in targets])), distro_specific=False, distro_nonspecific=True)
filtered_results = []
for r in results:
- if r.endswith(("_populate_lic.tgz", "_populate_lic.tgz.siginfo")):
+ if r.endswith(("_populate_lic.tar.zst", "_populate_lic.tar.zst.siginfo")):
continue
filtered_results.append(r)
self.assertTrue(filtered_results == [], msg="Found distro non-specific sstate for: %s (%s)" % (', '.join(map(str, targets)), str(filtered_results)))
- file_tracker_1 = self.search_sstate('|'.join(map(str, [s + r'.*?\.tgz$' for s in targets])), distro_specific=True, distro_nonspecific=False)
- self.assertTrue(len(file_tracker_1) >= len(targets), msg = "Not all sstate files ware created for: %s" % ', '.join(map(str, targets)))
+ file_tracker_1 = self.search_sstate('|'.join(map(str, [s + r'.*?\.tar.zst$' for s in targets])), distro_specific=True, distro_nonspecific=False)
+ self.assertTrue(len(file_tracker_1) >= len(targets), msg = "Not all sstate files were created for: %s" % ', '.join(map(str, targets)))
self.track_for_cleanup(self.distro_specific_sstate + "_old")
shutil.copytree(self.distro_specific_sstate, self.distro_specific_sstate + "_old")
@@ -145,14 +146,14 @@ class SStateTests(SStateBase):
bitbake(['-cclean'] + targets)
bitbake(targets)
- file_tracker_2 = self.search_sstate('|'.join(map(str, [s + r'.*?\.tgz$' for s in targets])), distro_specific=True, distro_nonspecific=False)
- self.assertTrue(len(file_tracker_2) >= len(targets), msg = "Not all sstate files ware created for: %s" % ', '.join(map(str, targets)))
+ file_tracker_2 = self.search_sstate('|'.join(map(str, [s + r'.*?\.tar.zst$' for s in targets])), distro_specific=True, distro_nonspecific=False)
+ self.assertTrue(len(file_tracker_2) >= len(targets), msg = "Not all sstate files were created for: %s" % ', '.join(map(str, targets)))
not_recreated = [x for x in file_tracker_1 if x not in file_tracker_2]
- self.assertTrue(not_recreated == [], msg="The following sstate files ware not recreated: %s" % ', '.join(map(str, not_recreated)))
+ self.assertTrue(not_recreated == [], msg="The following sstate files were not recreated: %s" % ', '.join(map(str, not_recreated)))
created_once = [x for x in file_tracker_2 if x not in file_tracker_1]
- self.assertTrue(created_once == [], msg="The following sstate files ware created only in the second run: %s" % ', '.join(map(str, created_once)))
+ self.assertTrue(created_once == [], msg="The following sstate files were created only in the second run: %s" % ', '.join(map(str, created_once)))
def test_rebuild_distro_specific_sstate_cross_native_targets(self):
self.run_test_rebuild_distro_specific_sstate(['binutils-cross-' + self.tune_arch, 'binutils-native'], temp_sstate_location=True)
@@ -174,9 +175,9 @@ class SStateTests(SStateBase):
# If buildhistory is enabled, we need to disable version-going-backwards
# QA checks for this test. It may report errors otherwise.
- self.append_config('ERROR_QA_remove = "version-going-backwards"')
+ self.append_config('ERROR_QA:remove = "version-going-backwards"')
- # For not this only checks if random sstate tasks are handled correctly as a group.
+ # For now this only checks if random sstate tasks are handled correctly as a group.
# In the future we should add control over what tasks we check for.
sstate_archs_list = []
@@ -188,23 +189,23 @@ class SStateTests(SStateBase):
if not sstate_arch in sstate_archs_list:
sstate_archs_list.append(sstate_arch)
if target_config[idx] == target_config[-1]:
- target_sstate_before_build = self.search_sstate(target + r'.*?\.tgz$')
+ target_sstate_before_build = self.search_sstate(target + r'.*?\.tar.zst$')
bitbake("-cclean %s" % target)
result = bitbake(target, ignore_status=True)
if target_config[idx] == target_config[-1]:
- target_sstate_after_build = self.search_sstate(target + r'.*?\.tgz$')
+ target_sstate_after_build = self.search_sstate(target + r'.*?\.tar.zst$')
expected_remaining_sstate += [x for x in target_sstate_after_build if x not in target_sstate_before_build if not any(pattern in x for pattern in ignore_patterns)]
self.remove_config(global_config[idx])
self.remove_recipeinc(target, target_config[idx])
self.assertEqual(result.status, 0, msg = "build of %s failed with %s" % (target, result.output))
runCmd("sstate-cache-management.sh -y --cache-dir=%s --remove-duplicated --extra-archs=%s" % (self.sstate_path, ','.join(map(str, sstate_archs_list))))
- actual_remaining_sstate = [x for x in self.search_sstate(target + r'.*?\.tgz$') if not any(pattern in x for pattern in ignore_patterns)]
+ actual_remaining_sstate = [x for x in self.search_sstate(target + r'.*?\.tar.zst$') if not any(pattern in x for pattern in ignore_patterns)]
actual_not_expected = [x for x in actual_remaining_sstate if x not in expected_remaining_sstate]
- self.assertFalse(actual_not_expected, msg="Files should have been removed but ware not: %s" % ', '.join(map(str, actual_not_expected)))
+ self.assertFalse(actual_not_expected, msg="Files should have been removed but were not: %s" % ', '.join(map(str, actual_not_expected)))
expected_not_actual = [x for x in expected_remaining_sstate if x not in actual_remaining_sstate]
- self.assertFalse(expected_not_actual, msg="Extra files ware removed: %s" ', '.join(map(str, expected_not_actual)))
+ self.assertFalse(expected_not_actual, msg="Extra files were removed: %s" ', '.join(map(str, expected_not_actual)))
def test_sstate_cache_management_script_using_pr_1(self):
global_config = []
@@ -341,13 +342,15 @@ TCLIBCAPPEND = \"\"
MACHINE = \"qemux86-64\"
BB_SIGNATURE_HANDLER = "OEBasicHash"
"""
+ #OLDEST_KERNEL is arch specific so set to a different value here for testing
configB = """
TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
TCLIBCAPPEND = \"\"
MACHINE = \"qemuarm\"
+OLDEST_KERNEL = \"3.3.0\"
BB_SIGNATURE_HANDLER = "OEBasicHash"
"""
- self.sstate_allarch_samesigs(configA, configB)
+ self.sstate_common_samesigs(configA, configB, allarch=True)
def test_sstate_nativesdk_samesigs_multilib(self):
"""
@@ -360,7 +363,7 @@ TCLIBCAPPEND = \"\"
MACHINE = \"qemux86-64\"
require conf/multilib.conf
MULTILIBS = \"multilib:lib32\"
-DEFAULTTUNE_virtclass-multilib-lib32 = \"x86\"
+DEFAULTTUNE:virtclass-multilib-lib32 = \"x86\"
BB_SIGNATURE_HANDLER = "OEBasicHash"
"""
configB = """
@@ -371,9 +374,9 @@ require conf/multilib.conf
MULTILIBS = \"\"
BB_SIGNATURE_HANDLER = "OEBasicHash"
"""
- self.sstate_allarch_samesigs(configA, configB)
+ self.sstate_common_samesigs(configA, configB)
- def sstate_allarch_samesigs(self, configA, configB):
+ def sstate_common_samesigs(self, configA, configB, allarch=False):
self.write_config(configA)
self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
@@ -401,6 +404,13 @@ BB_SIGNATURE_HANDLER = "OEBasicHash"
self.maxDiff = None
self.assertEqual(files1, files2)
+ if allarch:
+ allarchdir = os.path.basename(glob.glob(self.topdir + "/tmp-sstatesamehash/stamps/all-*-linux")[0])
+
+ files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/" + allarchdir)
+ files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/" + allarchdir)
+ self.assertEqual(files1, files2)
+
def test_sstate_sametune_samesigs(self):
"""
The sstate checksums of two identical machines (using the same tune) should be the
@@ -414,7 +424,7 @@ TCLIBCAPPEND = \"\"
MACHINE = \"qemux86\"
require conf/multilib.conf
MULTILIBS = "multilib:lib32"
-DEFAULTTUNE_virtclass-multilib-lib32 = "x86"
+DEFAULTTUNE:virtclass-multilib-lib32 = "x86"
BB_SIGNATURE_HANDLER = "OEBasicHash"
""")
self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
@@ -425,7 +435,7 @@ TCLIBCAPPEND = \"\"
MACHINE = \"qemux86copy\"
require conf/multilib.conf
MULTILIBS = "multilib:lib32"
-DEFAULTTUNE_virtclass-multilib-lib32 = "x86"
+DEFAULTTUNE:virtclass-multilib-lib32 = "x86"
BB_SIGNATURE_HANDLER = "OEBasicHash"
""")
self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
@@ -462,7 +472,7 @@ TCLIBCAPPEND = \"\"
MACHINE = \"qemux86\"
require conf/multilib.conf
MULTILIBS = "multilib:lib32"
-DEFAULTTUNE_virtclass-multilib-lib32 = "x86"
+DEFAULTTUNE:virtclass-multilib-lib32 = "x86"
BB_SIGNATURE_HANDLER = "OEBasicHash"
""")
self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
@@ -503,7 +513,7 @@ PARALLEL_MAKE = "-j 1"
DL_DIR = "${TOPDIR}/download1"
TIME = "111111"
DATE = "20161111"
-INHERIT_remove = "buildstats-summary buildhistory uninative"
+INHERIT:remove = "buildstats-summary buildhistory uninative"
http_proxy = ""
BB_SIGNATURE_HANDLER = "OEBasicHash"
""")
@@ -519,7 +529,7 @@ DL_DIR = "${TOPDIR}/download2"
TIME = "222222"
DATE = "20161212"
# Always remove uninative as we're changing proxies
-INHERIT_remove = "uninative"
+INHERIT:remove = "uninative"
INHERIT += "buildstats-summary buildhistory"
http_proxy = "http://example.com/"
BB_SIGNATURE_HANDLER = "OEBasicHash"
@@ -573,3 +583,44 @@ BB_SIGNATURE_HANDLER = "OEBasicHash"
compare_sigfiles(rest, files1, files2, compare=False)
self.fail("sstate hashes not identical.")
+
+ def test_sstate_movelayer_samesigs(self):
+ """
+ The sstate checksums of two builds with the same oe-core layer in two
+ different locations should be the same.
+ """
+ core_layer = os.path.join(
+ self.tc.td["COREBASE"], 'meta')
+ copy_layer_1 = self.topdir + "/meta-copy1/meta"
+ copy_layer_2 = self.topdir + "/meta-copy2/meta"
+
+ oe.path.copytree(core_layer, copy_layer_1)
+ self.write_config("""
+TMPDIR = "${TOPDIR}/tmp-sstatesamehash"
+""")
+ bblayers_conf = 'BBLAYERS += "%s"\nBBLAYERS:remove = "%s"' % (copy_layer_1, core_layer)
+ self.write_bblayers_config(bblayers_conf)
+ self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
+ bitbake("bash -S none")
+
+ oe.path.copytree(core_layer, copy_layer_2)
+ self.write_config("""
+TMPDIR = "${TOPDIR}/tmp-sstatesamehash2"
+""")
+ bblayers_conf = 'BBLAYERS += "%s"\nBBLAYERS:remove = "%s"' % (copy_layer_2, core_layer)
+ self.write_bblayers_config(bblayers_conf)
+ self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
+ bitbake("bash -S none")
+
+ def get_files(d):
+ f = []
+ for root, dirs, files in os.walk(d):
+ for name in files:
+ f.append(os.path.join(root, name))
+ return f
+ files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps")
+ files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps")
+ files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash") for x in files2]
+ self.maxDiff = None
+ self.assertCountEqual(files1, files2)
+
diff --git a/meta/lib/oeqa/selftest/cases/sysroot.py b/meta/lib/oeqa/selftest/cases/sysroot.py
index 6e34927c90..79ab45235d 100644
--- a/meta/lib/oeqa/selftest/cases/sysroot.py
+++ b/meta/lib/oeqa/selftest/cases/sysroot.py
@@ -24,14 +24,14 @@ class SysrootTests(OESelftestTestCase):
self.write_config("""
PREFERRED_PROVIDER_virtual/sysroot-test = "sysroot-test-arch1"
MACHINE = "qemux86"
-TESTSTRING_pn-sysroot-test-arch1 = "%s"
-TESTSTRING_pn-sysroot-test-arch2 = "%s"
+TESTSTRING:pn-sysroot-test-arch1 = "%s"
+TESTSTRING:pn-sysroot-test-arch2 = "%s"
""" % (uuid1, uuid2))
bitbake("sysroot-test")
self.write_config("""
PREFERRED_PROVIDER_virtual/sysroot-test = "sysroot-test-arch2"
MACHINE = "qemux86copy"
-TESTSTRING_pn-sysroot-test-arch1 = "%s"
-TESTSTRING_pn-sysroot-test-arch2 = "%s"
+TESTSTRING:pn-sysroot-test-arch1 = "%s"
+TESTSTRING:pn-sysroot-test-arch2 = "%s"
""" % (uuid1, uuid2))
bitbake("sysroot-test")
diff --git a/meta/lib/oeqa/selftest/cases/tinfoil.py b/meta/lib/oeqa/selftest/cases/tinfoil.py
index a51c6048d3..8fd48bb054 100644
--- a/meta/lib/oeqa/selftest/cases/tinfoil.py
+++ b/meta/lib/oeqa/selftest/cases/tinfoil.py
@@ -94,14 +94,13 @@ class TinfoilTests(OESelftestTestCase):
pass
pattern = 'conf'
- res = tinfoil.run_command('findFilesMatchingInDir', pattern, 'conf/machine')
+ res = tinfoil.run_command('testCookerCommandEvent', pattern)
self.assertTrue(res)
eventreceived = False
commandcomplete = False
start = time.time()
# Wait for maximum 60s in total so we'd detect spurious heartbeat events for example
- # The test is IO load sensitive too
while (not (eventreceived == True and commandcomplete == True)
and (time.time() - start < 60)):
# if we received both events (on let's say a good day), we are done
@@ -111,7 +110,8 @@ class TinfoilTests(OESelftestTestCase):
commandcomplete = True
elif isinstance(event, bb.event.FilesMatchingFound):
self.assertEqual(pattern, event._pattern)
- self.assertIn('qemuarm.conf', event._matches)
+ self.assertIn('A', event._matches)
+ self.assertIn('B', event._matches)
eventreceived = True
elif isinstance(event, logging.LogRecord):
continue
@@ -173,8 +173,8 @@ class TinfoilTests(OESelftestTestCase):
self.assertEqual(value, 'origvalue', 'Variable renamed using config_data.renameVar() does not appear with new name')
# Test overrides
tinfoil.config_data.setVar('TESTVAR', 'original')
- tinfoil.config_data.setVar('TESTVAR_overrideone', 'one')
- tinfoil.config_data.setVar('TESTVAR_overridetwo', 'two')
+ tinfoil.config_data.setVar('TESTVAR:overrideone', 'one')
+ tinfoil.config_data.setVar('TESTVAR:overridetwo', 'two')
tinfoil.config_data.appendVar('OVERRIDES', ':overrideone')
value = tinfoil.config_data.getVar('TESTVAR')
self.assertEqual(value, 'one', 'Variable overrides not functioning correctly')
diff --git a/meta/lib/oeqa/selftest/cases/wic.py b/meta/lib/oeqa/selftest/cases/wic.py
index a11e2d0781..6f3dc27743 100644
--- a/meta/lib/oeqa/selftest/cases/wic.py
+++ b/meta/lib/oeqa/selftest/cases/wic.py
@@ -11,6 +11,7 @@
import os
import sys
import unittest
+import hashlib
from glob import glob
from shutil import rmtree, copy
@@ -189,8 +190,8 @@ class Wic(WicTestCase):
def test_iso_image(self):
"""Test creation of hybrid iso image with legacy and EFI boot"""
config = 'INITRAMFS_IMAGE = "core-image-minimal-initramfs"\n'\
- 'MACHINE_FEATURES_append = " efi"\n'\
- 'DEPENDS_pn-core-image-minimal += "syslinux"\n'
+ 'MACHINE_FEATURES:append = " efi"\n'\
+ 'DEPENDS:pn-core-image-minimal += "syslinux"\n'
self.append_config(config)
bitbake('core-image-minimal core-image-minimal-initramfs')
self.remove_config(config)
@@ -216,7 +217,7 @@ class Wic(WicTestCase):
@only_for_arch(['i586', 'i686', 'x86_64'])
def test_bootloader_config(self):
"""Test creation of directdisk-bootloader-config image"""
- config = 'DEPENDS_pn-core-image-minimal += "syslinux"\n'
+ config = 'DEPENDS:pn-core-image-minimal += "syslinux"\n'
self.append_config(config)
bitbake('core-image-minimal')
self.remove_config(config)
@@ -227,7 +228,7 @@ class Wic(WicTestCase):
@only_for_arch(['i586', 'i686', 'x86_64'])
def test_systemd_bootdisk(self):
"""Test creation of systemd-bootdisk image"""
- config = 'MACHINE_FEATURES_append = " efi"\n'
+ config = 'MACHINE_FEATURES:append = " efi"\n'
self.append_config(config)
bitbake('core-image-minimal')
self.remove_config(config)
@@ -259,7 +260,7 @@ class Wic(WicTestCase):
"""Test default output location"""
for fname in glob("directdisk-*.direct"):
os.remove(fname)
- config = 'DEPENDS_pn-core-image-minimal += "syslinux"\n'
+ config = 'DEPENDS:pn-core-image-minimal += "syslinux"\n'
self.append_config(config)
bitbake('core-image-minimal')
self.remove_config(config)
@@ -686,6 +687,74 @@ part /etc --source rootfs --fstype=ext4 --change-directory=etc
% (wks_file, self.resultdir), ignore_status=True).status)
os.remove(wks_file)
+ def test_no_fstab_update(self):
+ """Test --no-fstab-update wks option."""
+
+ oldpath = os.environ['PATH']
+ os.environ['PATH'] = get_bb_var("PATH", "wic-tools")
+
+ # Get stock fstab from base-files recipe
+ self.assertEqual(0, bitbake('base-files -c do_install').status)
+ bf_fstab = os.path.join(get_bb_var('D', 'base-files'), 'etc/fstab')
+ self.assertEqual(True, os.path.exists(bf_fstab))
+ bf_fstab_md5sum = runCmd('md5sum %s 2>/dev/null' % bf_fstab).output.split(" ")[0]
+
+ try:
+ no_fstab_update_path = os.path.join(self.resultdir, 'test-no-fstab-update')
+ os.makedirs(no_fstab_update_path)
+ wks_file = os.path.join(no_fstab_update_path, 'temp.wks')
+ with open(wks_file, 'w') as wks:
+ wks.writelines(['part / --source rootfs --fstype=ext4 --label rootfs\n',
+ 'part /mnt/p2 --source rootfs --rootfs-dir=core-image-minimal ',
+ '--fstype=ext4 --label p2 --no-fstab-update\n'])
+ runCmd("wic create %s -e core-image-minimal -o %s" \
+ % (wks_file, self.resultdir))
+
+ part_fstab_md5sum = []
+ for i in range(1, 3):
+ part = glob(os.path.join(self.resultdir, 'temp-*.direct.p') + str(i))[0]
+ part_fstab = runCmd("debugfs -R 'cat etc/fstab' %s 2>/dev/null" % (part))
+ part_fstab_md5sum.append(hashlib.md5((part_fstab.output + "\n\n").encode('utf-8')).hexdigest())
+
+ # '/etc/fstab' in partition 2 should contain the same stock fstab file
+ # as the one installed by the base-file recipe.
+ self.assertEqual(bf_fstab_md5sum, part_fstab_md5sum[1])
+
+ # '/etc/fstab' in partition 1 should contain an updated fstab file.
+ self.assertNotEqual(bf_fstab_md5sum, part_fstab_md5sum[0])
+
+ finally:
+ os.environ['PATH'] = oldpath
+
+ def test_no_fstab_update_errors(self):
+ """Test --no-fstab-update wks option error handling."""
+ wks_file = 'temp.wks'
+
+ # Absolute argument.
+ with open(wks_file, 'w') as wks:
+ wks.write("part / --source rootfs --fstype=ext4 --no-fstab-update /etc")
+ self.assertNotEqual(0, runCmd("wic create %s -e core-image-minimal -o %s" \
+ % (wks_file, self.resultdir), ignore_status=True).status)
+ os.remove(wks_file)
+
+ # Argument pointing to parent directory.
+ with open(wks_file, 'w') as wks:
+ wks.write("part / --source rootfs --fstype=ext4 --no-fstab-update ././..")
+ self.assertNotEqual(0, runCmd("wic create %s -e core-image-minimal -o %s" \
+ % (wks_file, self.resultdir), ignore_status=True).status)
+ os.remove(wks_file)
+
+ def test_extra_space(self):
+ """Test --extra-space wks option."""
+ extraspace = 1024**3
+ runCmd("wic create wictestdisk "
+ "--image-name core-image-minimal "
+ "--extra-space %i -o %s" % (extraspace ,self.resultdir))
+ wicout = glob(self.resultdir + "wictestdisk-*.direct")
+ self.assertEqual(1, len(wicout))
+ size = os.path.getsize(wicout[0])
+ self.assertTrue(size > extraspace)
+
class Wic2(WicTestCase):
def test_bmap_short(self):
@@ -757,7 +826,7 @@ class Wic2(WicTestCase):
def test_wic_image_type(self):
"""Test building wic images by bitbake"""
config = 'IMAGE_FSTYPES += "wic"\nWKS_FILE = "wic-image-minimal"\n'\
- 'MACHINE_FEATURES_append = " efi"\n'
+ 'MACHINE_FEATURES:append = " efi"\n'
self.append_config(config)
self.assertEqual(0, bitbake('wic-image-minimal').status)
self.remove_config(config)
@@ -777,12 +846,12 @@ class Wic2(WicTestCase):
def test_qemu(self):
"""Test wic-image-minimal under qemu"""
config = 'IMAGE_FSTYPES += "wic"\nWKS_FILE = "wic-image-minimal"\n'\
- 'MACHINE_FEATURES_append = " efi"\n'
+ 'MACHINE_FEATURES:append = " efi"\n'
self.append_config(config)
self.assertEqual(0, bitbake('wic-image-minimal').status)
self.remove_config(config)
- with runqemu('wic-image-minimal', ssh=False) as qemu:
+ with runqemu('wic-image-minimal', ssh=False, runqemuparams='nographic') as qemu:
cmd = "mount | grep '^/dev/' | cut -f1,3 -d ' ' | egrep -c -e '/dev/sda1 /boot' " \
"-e '/dev/root /|/dev/sda2 /' -e '/dev/sda3 /media' -e '/dev/sda4 /mnt'"
status, output = qemu.run_serial(cmd)
@@ -802,7 +871,7 @@ class Wic2(WicTestCase):
self.remove_config(config)
with runqemu('core-image-minimal', ssh=False,
- runqemuparams='ovmf', image_fstype='wic') as qemu:
+ runqemuparams='nographic ovmf', image_fstype='wic') as qemu:
cmd = "grep sda. /proc/partitions |wc -l"
status, output = qemu.run_serial(cmd)
self.assertEqual(1, status, 'Failed to run command "%s": %s' % (cmd, output))
@@ -990,21 +1059,21 @@ class Wic2(WicTestCase):
self.assertEqual(0, bitbake('core-image-minimal-mtdutils').status)
self.remove_config(config)
- with runqemu('core-image-minimal-mtdutils', ssh=False, image_fstype='wic') as qemu:
+ with runqemu('core-image-minimal-mtdutils', ssh=False,
+ runqemuparams='nographic', image_fstype='wic') as qemu:
cmd = "grep sda. /proc/partitions |wc -l"
status, output = qemu.run_serial(cmd)
self.assertEqual(1, status, 'Failed to run command "%s": %s' % (cmd, output))
self.assertEqual(output, '2')
- def test_rawcopy_plugin(self):
+ def _rawcopy_plugin(self, fstype):
"""Test rawcopy plugin"""
img = 'core-image-minimal'
machine = get_bb_var('MACHINE', img)
+ params = ',unpack' if fstype.endswith('.gz') else ''
with NamedTemporaryFile("w", suffix=".wks") as wks:
- wks.writelines(['part /boot --active --source bootimg-pcbios\n',
- 'part / --source rawcopy --sourceparams="file=%s-%s.ext4" --use-uuid\n'\
- % (img, machine),
- 'bootloader --timeout=0 --append="console=ttyS0,115200n8"\n'])
+ wks.write('part / --source rawcopy --sourceparams="file=%s-%s.%s%s"\n'\
+ % (img, machine, fstype, params))
wks.flush()
cmd = "wic create %s -e %s -o %s" % (wks.name, img, self.resultdir)
runCmd(cmd)
@@ -1012,6 +1081,17 @@ class Wic2(WicTestCase):
out = glob(self.resultdir + "%s-*direct" % wksname)
self.assertEqual(1, len(out))
+ def test_rawcopy_plugin(self):
+ self._rawcopy_plugin('ext4')
+
+ def test_rawcopy_plugin_unpack(self):
+ fstype = 'ext4.gz'
+ config = 'IMAGE_FSTYPES = "%s"\n' % fstype
+ self.append_config(config)
+ self.assertEqual(0, bitbake('core-image-minimal').status)
+ self.remove_config(config)
+ self._rawcopy_plugin(fstype)
+
def test_empty_plugin(self):
"""Test empty plugin"""
config = 'IMAGE_FSTYPES = "wic"\nWKS_FILE = "test_empty_plugin.wks"\n'
@@ -1035,12 +1115,13 @@ class Wic2(WicTestCase):
@only_for_arch(['i586', 'i686', 'x86_64'])
def test_biosplusefi_plugin_qemu(self):
"""Test biosplusefi plugin in qemu"""
- config = 'IMAGE_FSTYPES = "wic"\nWKS_FILE = "test_biosplusefi_plugin.wks"\nMACHINE_FEATURES_append = " efi"\n'
+ config = 'IMAGE_FSTYPES = "wic"\nWKS_FILE = "test_biosplusefi_plugin.wks"\nMACHINE_FEATURES:append = " efi"\n'
self.append_config(config)
self.assertEqual(0, bitbake('core-image-minimal').status)
self.remove_config(config)
- with runqemu('core-image-minimal', ssh=False, image_fstype='wic') as qemu:
+ with runqemu('core-image-minimal', ssh=False,
+ runqemuparams='nographic', image_fstype='wic') as qemu:
# Check that we have ONLY two /dev/sda* partitions (/boot and /)
cmd = "grep sda. /proc/partitions | wc -l"
status, output = qemu.run_serial(cmd)
@@ -1072,7 +1153,7 @@ class Wic2(WicTestCase):
# If an image hasn't been built yet, directory ${STAGING_DATADIR}/syslinux won't exists and _get_bootimg_dir()
# will raise with "Couldn't find correct bootimg_dir"
# The easiest way to work-around this issue is to make sure we already built an image here, hence the bitbake call
- config = 'IMAGE_FSTYPES = "wic"\nWKS_FILE = "test_biosplusefi_plugin.wks"\nMACHINE_FEATURES_append = " efi"\n'
+ config = 'IMAGE_FSTYPES = "wic"\nWKS_FILE = "test_biosplusefi_plugin.wks"\nMACHINE_FEATURES:append = " efi"\n'
self.append_config(config)
self.assertEqual(0, bitbake('core-image-minimal').status)
self.remove_config(config)
@@ -1089,6 +1170,35 @@ class Wic2(WicTestCase):
out = glob(self.resultdir + "%s-*.direct" % wksname)
self.assertEqual(1, len(out))
+ @only_for_arch(['i586', 'i686', 'x86_64'])
+ def test_efi_plugin_unified_kernel_image_qemu(self):
+ """Test efi plugin's Unified Kernel Image feature in qemu"""
+ config = 'IMAGE_FSTYPES = "wic"\n'\
+ 'INITRAMFS_IMAGE = "core-image-minimal-initramfs"\n'\
+ 'WKS_FILE = "test_efi_plugin.wks"\n'\
+ 'MACHINE_FEATURES:append = " efi"\n'
+ self.append_config(config)
+ self.assertEqual(0, bitbake('core-image-minimal core-image-minimal-initramfs ovmf').status)
+ self.remove_config(config)
+
+ with runqemu('core-image-minimal', ssh=False,
+ runqemuparams='nographic ovmf', image_fstype='wic') as qemu:
+ # Check that /boot has EFI bootx64.efi (required for EFI)
+ cmd = "ls /boot/EFI/BOOT/bootx64.efi | wc -l"
+ status, output = qemu.run_serial(cmd)
+ self.assertEqual(1, status, 'Failed to run command "%s": %s' % (cmd, output))
+ self.assertEqual(output, '1')
+ # Check that /boot has EFI/Linux/linux.efi (required for Unified Kernel Images auto detection)
+ cmd = "ls /boot/EFI/Linux/linux.efi | wc -l"
+ status, output = qemu.run_serial(cmd)
+ self.assertEqual(1, status, 'Failed to run command "%s": %s' % (cmd, output))
+ self.assertEqual(output, '1')
+ # Check that /boot doesn't have loader/entries/boot.conf (Unified Kernel Images are auto detected by the bootloader)
+ cmd = "ls /boot/loader/entries/boot.conf 2&>/dev/null | wc -l"
+ status, output = qemu.run_serial(cmd)
+ self.assertEqual(1, status, 'Failed to run command "%s": %s' % (cmd, output))
+ self.assertEqual(output, '0')
+
def test_fs_types(self):
"""Test filesystem types for empty and not empty partitions"""
img = 'core-image-minimal'
@@ -1310,7 +1420,7 @@ class Wic2(WicTestCase):
bb.utils.rename(new_image_path, image_path)
# Check if it boots in qemu
- with runqemu('core-image-minimal', ssh=False) as qemu:
+ with runqemu('core-image-minimal', ssh=False, runqemuparams='nographic') as qemu:
cmd = "ls /etc/"
status, output = qemu.run_serial('true')
self.assertEqual(1, status, 'Failed to run command "%s": %s' % (cmd, output))
diff --git a/meta/lib/oeqa/selftest/context.py b/meta/lib/oeqa/selftest/context.py
index 1659926975..78c7a467e2 100644
--- a/meta/lib/oeqa/selftest/context.py
+++ b/meta/lib/oeqa/selftest/context.py
@@ -39,7 +39,7 @@ class NonConcurrentTestSuite(unittest.TestSuite):
def removebuilddir(d):
delay = 5
- while delay and os.path.exists(d + "/bitbake.lock"):
+ while delay and (os.path.exists(d + "/bitbake.lock") or os.path.exists(d + "/cache/hashserv.db-wal")):
time.sleep(1)
delay = delay - 1
# Deleting these directories takes a lot of time, use autobuilder