diff options
author | Brad Bishop <bradleyb@fuzziesquirrel.com> | 2018-06-25 19:45:53 +0300 |
---|---|---|
committer | Brad Bishop <bradleyb@fuzziesquirrel.com> | 2018-06-27 21:38:15 +0300 |
commit | 316dfdd917bec6a218f431211d28bf8df6b6fb0f (patch) | |
tree | 5541073f9851f44c2bd67b4959dc776ee3c3810f /import-layers/yocto-poky/meta/lib/oeqa | |
parent | 36acd3e888044dea2ac0b2946f15616f968388c9 (diff) | |
download | openbmc-316dfdd917bec6a218f431211d28bf8df6b6fb0f.tar.xz |
Yocto 2.5
Move OpenBMC to Yocto 2.5(sumo)
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
Change-Id: I5c5ad6904a16e14c1c397f0baf10c9d465594a78
Diffstat (limited to 'import-layers/yocto-poky/meta/lib/oeqa')
29 files changed, 638 insertions, 120 deletions
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/buildperf/base.py b/import-layers/yocto-poky/meta/lib/oeqa/buildperf/base.py index 7b2b4aa2a..ac6ee15d0 100644 --- a/import-layers/yocto-poky/meta/lib/oeqa/buildperf/base.py +++ b/import-layers/yocto-poky/meta/lib/oeqa/buildperf/base.py @@ -282,7 +282,7 @@ class BuildPerfTestCase(unittest.TestCase): if not os.path.isdir(self.tmp_dir): os.mkdir(self.tmp_dir) if self.build_target: - self.run_cmd(['bitbake', self.build_target, '-c', 'fetchall']) + self.run_cmd(['bitbake', self.build_target, '--runall=fetch']) def tearDown(self): """Tear-down fixture for each test""" diff --git a/import-layers/yocto-poky/meta/lib/oeqa/buildperf/test_basic.py b/import-layers/yocto-poky/meta/lib/oeqa/buildperf/test_basic.py index a19089a6e..6d6b01b04 100644 --- a/import-layers/yocto-poky/meta/lib/oeqa/buildperf/test_basic.py +++ b/import-layers/yocto-poky/meta/lib/oeqa/buildperf/test_basic.py @@ -15,8 +15,7 @@ import shutil import oe.path from oeqa.buildperf import BuildPerfTestCase -from oeqa.utils.commands import get_bb_vars - +from oeqa.utils.commands import get_bb_var, get_bb_vars class Test1P1(BuildPerfTestCase): build_target = 'core-image-sato' @@ -30,6 +29,7 @@ class Test1P1(BuildPerfTestCase): self.measure_cmd_resources(['bitbake', self.build_target], 'build', 'bitbake ' + self.build_target, save_bs=True) self.measure_disk_usage(self.bb_vars['TMPDIR'], 'tmpdir', 'tmpdir') + self.measure_disk_usage(get_bb_var("IMAGE_ROOTFS", self.build_target), 'rootfs', 'rootfs', True) class Test1P2(BuildPerfTestCase): diff --git a/import-layers/yocto-poky/meta/lib/oeqa/core/loader.py b/import-layers/yocto-poky/meta/lib/oeqa/core/loader.py index 975a081ba..a4744dee0 100644 --- a/import-layers/yocto-poky/meta/lib/oeqa/core/loader.py +++ b/import-layers/yocto-poky/meta/lib/oeqa/core/loader.py @@ -43,7 +43,7 @@ def _built_modules_dict(modules): for module in modules: # Assumption: package and module names do not contain upper case # characters, whereas class names do - m = re.match(r'^([^A-Z]+)(?:\.([A-Z][^.]*)(?:\.([^.]+))?)?$', module) + m = re.match(r'^(\w+)(?:\.(\w[^.]*)(?:\.([^.]+))?)?$', module, flags=re.ASCII) module_name, class_name, test_name = m.groups() diff --git a/import-layers/yocto-poky/meta/lib/oeqa/core/target/qemu.py b/import-layers/yocto-poky/meta/lib/oeqa/core/target/qemu.py index d359bf9fe..bf3b633f0 100644 --- a/import-layers/yocto-poky/meta/lib/oeqa/core/target/qemu.py +++ b/import-layers/yocto-poky/meta/lib/oeqa/core/target/qemu.py @@ -9,7 +9,7 @@ import time from .ssh import OESSHTarget from oeqa.utils.qemurunner import QemuRunner -supported_fstypes = ['ext3', 'ext4', 'cpio.gz', 'wic', 'elf'] +supported_fstypes = ['ext3', 'ext4', 'cpio.gz', 'wic'] class OEQemuTarget(OESSHTarget): def __init__(self, logger, ip, server_ip, timeout=300, user='root', diff --git a/import-layers/yocto-poky/meta/lib/oeqa/runtime/cases/apt.py b/import-layers/yocto-poky/meta/lib/oeqa/runtime/cases/apt.py new file mode 100644 index 000000000..8d4dd35c5 --- /dev/null +++ b/import-layers/yocto-poky/meta/lib/oeqa/runtime/cases/apt.py @@ -0,0 +1,47 @@ +import os +from oeqa.utils.httpserver import HTTPService +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.core.decorator.data import skipIfNotDataVar, skipIfNotFeature +from oeqa.runtime.decorator.package import OEHasPackage + +class AptTest(OERuntimeTestCase): + + def pkg(self, command, expected = 0): + command = 'apt-get %s' % command + status, output = self.target.run(command, 1500) + message = os.linesep.join([command, output]) + self.assertEqual(status, expected, message) + return output + +class AptRepoTest(AptTest): + + @classmethod + def setUpClass(cls): + service_repo = os.path.join(cls.tc.td['DEPLOY_DIR_DEB'], 'all') + cls.repo_server = HTTPService(service_repo, cls.tc.target.server_ip) + cls.repo_server.start() + + @classmethod + def tearDownClass(cls): + cls.repo_server.stop() + + def setup_source_config_for_package_install(self): + apt_get_source_server = 'http://%s:%s/' % (self.tc.target.server_ip, self.repo_server.port) + apt_get_sourceslist_dir = '/etc/apt/' + self.target.run('cd %s; echo deb %s ./ > sources.list' % (apt_get_sourceslist_dir, apt_get_source_server)) + + def cleanup_source_config_for_package_install(self): + apt_get_sourceslist_dir = '/etc/apt/' + self.target.run('cd %s; rm sources.list' % (apt_get_sourceslist_dir)) + + @skipIfNotFeature('package-management', + 'Test requires package-management to be in IMAGE_FEATURES') + @skipIfNotDataVar('IMAGE_PKGTYPE', 'deb', + 'DEB is not the primary package manager') + @OEHasPackage(['apt']) + def test_apt_install_from_repo(self): + self.setup_source_config_for_package_install() + self.pkg('update') + self.pkg('remove --yes run-postinsts-dev') + self.pkg('install --yes --allow-unauthenticated run-postinsts-dev') + self.cleanup_source_config_for_package_install() diff --git a/import-layers/yocto-poky/meta/lib/oeqa/runtime/cases/gi.py b/import-layers/yocto-poky/meta/lib/oeqa/runtime/cases/gi.py new file mode 100644 index 000000000..19073e52c --- /dev/null +++ b/import-layers/yocto-poky/meta/lib/oeqa/runtime/cases/gi.py @@ -0,0 +1,15 @@ +import os + +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.core.decorator.depends import OETestDepends +from oeqa.runtime.decorator.package import OEHasPackage + +class GObjectIntrospectionTest(OERuntimeTestCase): + + @OETestDepends(["ssh.SSHTest.test_ssh"]) + @OEHasPackage(["python3-pygobject"]) + def test_python(self): + script = """from gi.repository import GObject; print(GObject.markup_escape_text("<testing&testing>"))""" + status, output = self.target.run("python3 -c '%s'" % script) + self.assertEqual(status, 0, msg="Python failed (%s)" % (output)) + self.assertEqual(output, "<testing&testing>", msg="Unexpected output (%s)" % output) diff --git a/import-layers/yocto-poky/meta/lib/oeqa/runtime/cases/kernelmodule.py b/import-layers/yocto-poky/meta/lib/oeqa/runtime/cases/kernelmodule.py index 11ad7b7f0..de1a5aa44 100644 --- a/import-layers/yocto-poky/meta/lib/oeqa/runtime/cases/kernelmodule.py +++ b/import-layers/yocto-poky/meta/lib/oeqa/runtime/cases/kernelmodule.py @@ -28,7 +28,7 @@ class KernelModuleTest(OERuntimeTestCase): @OETestDepends(['gcc.GccCompileTest.test_gcc_compile']) def test_kernel_module(self): cmds = [ - 'cd /usr/src/kernel && make scripts', + 'cd /usr/src/kernel && make scripts prepare', 'cd /tmp && make', 'cd /tmp && insmod hellomod.ko', 'lsmod | grep hellomod', diff --git a/import-layers/yocto-poky/meta/lib/oeqa/runtime/cases/opkg.py b/import-layers/yocto-poky/meta/lib/oeqa/runtime/cases/opkg.py new file mode 100644 index 000000000..671ee06c7 --- /dev/null +++ b/import-layers/yocto-poky/meta/lib/oeqa/runtime/cases/opkg.py @@ -0,0 +1,47 @@ +import os +from oeqa.utils.httpserver import HTTPService +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.core.decorator.data import skipIfNotDataVar, skipIfNotFeature +from oeqa.runtime.decorator.package import OEHasPackage + +class OpkgTest(OERuntimeTestCase): + + def pkg(self, command, expected = 0): + command = 'opkg %s' % command + status, output = self.target.run(command, 1500) + message = os.linesep.join([command, output]) + self.assertEqual(status, expected, message) + return output + +class OpkgRepoTest(OpkgTest): + + @classmethod + def setUpClass(cls): + service_repo = os.path.join(cls.tc.td['DEPLOY_DIR_IPK'], 'all') + cls.repo_server = HTTPService(service_repo, cls.tc.target.server_ip) + cls.repo_server.start() + + @classmethod + def tearDownClass(cls): + cls.repo_server.stop() + + def setup_source_config_for_package_install(self): + apt_get_source_server = 'http://%s:%s/' % (self.tc.target.server_ip, self.repo_server.port) + apt_get_sourceslist_dir = '/etc/opkg/' + self.target.run('cd %s; echo src/gz all %s >> opkg.conf' % (apt_get_sourceslist_dir, apt_get_source_server)) + + def cleanup_source_config_for_package_install(self): + apt_get_sourceslist_dir = '/etc/opkg/' + self.target.run('cd %s; sed -i "/^src/d" opkg.conf' % (apt_get_sourceslist_dir)) + + @skipIfNotFeature('package-management', + 'Test requires package-management to be in IMAGE_FEATURES') + @skipIfNotDataVar('IMAGE_PKGTYPE', 'ipk', + 'IPK is not the primary package manager') + @OEHasPackage(['opkg']) + def test_opkg_install_from_repo(self): + self.setup_source_config_for_package_install() + self.pkg('update') + self.pkg('remove run-postinsts-dev') + self.pkg('install run-postinsts-dev') + self.cleanup_source_config_for_package_install() diff --git a/import-layers/yocto-poky/meta/lib/oeqa/runtime/cases/ptest.py b/import-layers/yocto-poky/meta/lib/oeqa/runtime/cases/ptest.py index ec8c038a5..f60a433d5 100644 --- a/import-layers/yocto-poky/meta/lib/oeqa/runtime/cases/ptest.py +++ b/import-layers/yocto-poky/meta/lib/oeqa/runtime/cases/ptest.py @@ -48,9 +48,12 @@ class PtestRunnerTest(OERuntimeTestCase): @OETestID(1600) @skipIfNotFeature('ptest', 'Test requires ptest to be in DISTRO_FEATURES') - @skipIfNotFeature('ptest-pkgs', 'Test requires ptest-pkgs to be in IMAGE_FEATURES') @OETestDepends(['ssh.SSHTest.test_ssh']) def test_ptestrunner(self): + status, output = self.target.run('which ptest-runner', 0) + if status != 0: + self.skipTest("No -ptest packages are installed in the image") + import datetime test_log_dir = self.td.get('TEST_LOG_DIR', '') @@ -80,3 +83,11 @@ class PtestRunnerTest(OERuntimeTestCase): # Remove the old link to create a new one os.remove(ptest_log_dir_link) os.symlink(os.path.basename(ptest_log_dir), ptest_log_dir_link) + + failed_tests = {} + for section in parse_result.result_dict: + failed_testcases = [ test for test, result in parse_result.result_dict[section] if result == 'fail' ] + if failed_testcases: + failed_tests[section] = failed_testcases + + self.assertFalse(failed_tests, msg = "Failed ptests: %s" %(str(failed_tests))) diff --git a/import-layers/yocto-poky/meta/lib/oeqa/runtime/cases/stap.py b/import-layers/yocto-poky/meta/lib/oeqa/runtime/cases/stap.py new file mode 100644 index 000000000..fc728bfc5 --- /dev/null +++ b/import-layers/yocto-poky/meta/lib/oeqa/runtime/cases/stap.py @@ -0,0 +1,33 @@ +import os + +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.core.decorator.depends import OETestDepends +from oeqa.core.decorator.oeid import OETestID +from oeqa.core.decorator.data import skipIfNotFeature + +class StapTest(OERuntimeTestCase): + + @classmethod + def setUpClass(cls): + src = os.path.join(cls.tc.runtime_files_dir, 'hello.stp') + dst = '/tmp/hello.stp' + cls.tc.target.copyTo(src, dst) + + @classmethod + def tearDownClass(cls): + files = '/tmp/hello.stp' + cls.tc.target.run('rm %s' % files) + + @OETestID(1652) + @skipIfNotFeature('tools-profile', + 'Test requires tools-profile to be in IMAGE_FEATURES') + @OETestDepends(['kernelmodule.KernelModuleTest.test_kernel_module']) + def test_stap(self): + cmds = [ + 'cd /usr/src/kernel && make scripts prepare', + 'cd /lib/modules/`uname -r` && (if [ ! -L build ]; then ln -s /usr/src/kernel build; fi)', + 'stap --disable-cache -DSTP_NO_VERREL_CHECK /tmp/hello.stp' + ] + for cmd in cmds: + status, output = self.target.run(cmd, 900) + self.assertEqual(status, 0, msg='\n'.join([cmd, output])) diff --git a/import-layers/yocto-poky/meta/lib/oeqa/runtime/files/hello.stp b/import-layers/yocto-poky/meta/lib/oeqa/runtime/files/hello.stp new file mode 100644 index 000000000..367714716 --- /dev/null +++ b/import-layers/yocto-poky/meta/lib/oeqa/runtime/files/hello.stp @@ -0,0 +1 @@ +probe oneshot { println("hello world") } diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/archiver.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/archiver.py index f61a52201..0a6d4e325 100644 --- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/archiver.py +++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/archiver.py @@ -116,3 +116,16 @@ class Archiver(OESelftestTestCase): excluded_present = len(glob.glob(src_path_target + '/%s-*' % target_recipes[1])) self.assertFalse(excluded_present, 'Recipe %s was not excluded.' % target_recipes[1]) + + + + def test_archiver_srpm_mode(self): + """ + Test that in srpm mode, the added recipe dependencies at least exist/work [YOCTO #11121] + """ + + features = 'INHERIT += "archiver"\n' + features += 'ARCHIVER_MODE[srpm] = "1"\n' + self.write_config(features) + + bitbake('-n core-image-sato') diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/bbtests.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/bbtests.py index 4c8204903..350614967 100644 --- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/bbtests.py +++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/bbtests.py @@ -64,15 +64,14 @@ class BitbakeTests(OESelftestTestCase): @OETestID(108) def test_invalid_patch(self): - # This patch already exists in SRC_URI so adding it again will cause the - # patch to fail. - self.write_recipeinc('man', 'SRC_URI += "file://man-1.5h1-make.patch"') + # 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\"") - result = bitbake('man -c patch', ignore_status=True) - self.delete_recipeinc('man') - bitbake('-cclean man') + result = bitbake('man-db -c patch', ignore_status=True) + self.delete_recipeinc('man-db') + bitbake('-cclean man-db') line = self.getline(result, "Function failed: patch_do_patch") - self.assertTrue(line and line.startswith("ERROR:"), msg = "Repeated patch application didn't fail. bitbake output: %s" % result.output) + self.assertTrue(line and line.startswith("ERROR:"), msg = "Incorrectly formed patch application didn't fail. bitbake output: %s" % result.output) @OETestID(1354) def test_force_task_1(self): @@ -132,17 +131,17 @@ class BitbakeTests(OESelftestTestCase): @OETestID(168) def test_invalid_recipe_src_uri(self): data = 'SRC_URI = "file://invalid"' - self.write_recipeinc('man', data) + self.write_recipeinc('man-db', data) self.write_config("""DL_DIR = \"${TOPDIR}/download-selftest\" SSTATE_DIR = \"${TOPDIR}/download-selftest\" INHERIT_remove = \"report-error\" """) self.track_for_cleanup(os.path.join(self.builddir, "download-selftest")) - bitbake('-ccleanall man') - result = bitbake('-c fetch man', ignore_status=True) - bitbake('-ccleanall man') - self.delete_recipeinc('man') + bitbake('-ccleanall man-db') + result = bitbake('-c fetch man-db', ignore_status=True) + bitbake('-ccleanall man-db') + self.delete_recipeinc('man-db') self.assertEqual(result.status, 1, msg="Command succeded when it should have failed. bitbake output: %s" % result.output) self.assertTrue('Fetcher failure: Unable to find file file://invalid anywhere. The paths that were searched were:' in result.output, msg = "\"invalid\" file \ doesn't exist, yet no error message encountered. bitbake output: %s" % result.output) @@ -222,9 +221,9 @@ SSTATE_DIR = \"${TOPDIR}/download-selftest\" INHERIT_remove = \"report-error\" """) self.track_for_cleanup(os.path.join(self.builddir, "download-selftest")) - self.write_recipeinc('man',"\ndo_fail_task () {\nexit 1 \n}\n\naddtask do_fail_task before do_fetch\n" ) - runCmd('bitbake -c cleanall man xcursor-transparent-theme') - result = runCmd('bitbake -c unpack -k man xcursor-transparent-theme', ignore_status=True) + self.write_recipeinc('man-db',"\ndo_fail_task () {\nexit 1 \n}\n\naddtask do_fail_task before do_fetch\n" ) + runCmd('bitbake -c cleanall man-db xcursor-transparent-theme') + result = runCmd('bitbake -c unpack -k man-db xcursor-transparent-theme', ignore_status=True) errorpos = result.output.find('ERROR: Function failed: do_fail_task') manver = re.search("NOTE: recipe xcursor-transparent-theme-(.*?): task do_unpack: Started", result.output) continuepos = result.output.find('NOTE: recipe xcursor-transparent-theme-%s: task do_unpack: Started' % manver.group(1)) diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/buildoptions.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/buildoptions.py index cf221c33a..e60e32dad 100644 --- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/buildoptions.py +++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/buildoptions.py @@ -164,3 +164,17 @@ class ArchiverTest(OESelftestTestCase): 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) + +class ToolchainOptions(OESelftestTestCase): + + def test_toolchain_fortran(self): + """ + Test whether we can enable and build fortran and its supporting libraries + """ + + features = 'FORTRAN_forcevariable = ",fortran"\n' + features += 'RUNTIMETARGET_append_pn-gcc-runtime = " libquadmath"\n' + self.write_config(features) + + bitbake('gcc-runtime libgfortran') + diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/devtool.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/devtool.py index 43280cdc0..d5b6a46d4 100644 --- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/devtool.py +++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/devtool.py @@ -174,7 +174,7 @@ class DevtoolTests(DevtoolBase): def test_create_workspace(self): # Check preconditions result = runCmd('bitbake-layers show-layers') - self.assertTrue('/workspace' not in result.output, 'This test cannot be run with a workspace layer in bblayers.conf') + self.assertTrue('\nworkspace' not in result.output, 'This test cannot be run with a workspace layer in bblayers.conf') # Try creating a workspace layer with a specific path tempdir = tempfile.mkdtemp(prefix='devtoolqa') self.track_for_cleanup(tempdir) @@ -611,7 +611,7 @@ class DevtoolTests(DevtoolBase): @OETestID(1165) def test_devtool_modify_git(self): # Check preconditions - testrecipe = 'mkelfimage' + testrecipe = 'psplash' src_uri = get_bb_var('SRC_URI', testrecipe) self.assertIn('git://', src_uri, 'This test expects the %s recipe to be a git recipe' % testrecipe) # Clean up anything in the workdir/sysroot/sstate cache @@ -623,9 +623,9 @@ class DevtoolTests(DevtoolBase): self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') self.add_command_to_tearDown('bitbake -c clean %s' % testrecipe) result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir)) - self.assertExists(os.path.join(tempdir, 'Makefile'), 'Extracted source could not be found') + self.assertExists(os.path.join(tempdir, 'Makefile.am'), 'Extracted source could not be found') self.assertExists(os.path.join(self.workspacedir, 'conf', 'layer.conf'), 'Workspace directory not created. devtool output: %s' % result.output) - matches = glob.glob(os.path.join(self.workspacedir, 'appends', 'mkelfimage_*.bbappend')) + matches = glob.glob(os.path.join(self.workspacedir, 'appends', 'psplash_*.bbappend')) self.assertTrue(matches, 'bbappend not created') # Test devtool status result = runCmd('devtool status') @@ -899,6 +899,7 @@ class DevtoolTests(DevtoolBase): f.write('BBFILE_PATTERN_oeselftesttemplayer = "^${LAYERDIR}/"\n') f.write('BBFILE_PRIORITY_oeselftesttemplayer = "999"\n') f.write('BBFILE_PATTERN_IGNORE_EMPTY_oeselftesttemplayer = "1"\n') + f.write('LAYERSERIES_COMPAT_oeselftesttemplayer = "${LAYERSERIES_COMPAT_core}"\n') self.add_command_to_tearDown('bitbake-layers remove-layer %s || true' % templayerdir) result = runCmd('bitbake-layers add-layer %s' % templayerdir, cwd=self.builddir) # Create the bbappend @@ -987,8 +988,12 @@ class DevtoolTests(DevtoolBase): @OETestID(1371) def test_devtool_update_recipe_local_files_2(self): """Check local source files support when oe-local-files is in Git""" - testrecipe = 'lzo' + testrecipe = 'devtool-test-local' recipefile = get_bb_var('FILE', testrecipe) + recipedir = os.path.dirname(recipefile) + result = runCmd('git status --porcelain .', cwd=recipedir) + if result.output.strip(): + self.fail('Recipe directory for %s contains uncommitted changes' % testrecipe) # Setup srctree for modifying the recipe tempdir = tempfile.mkdtemp(prefix='devtoolqa') self.track_for_cleanup(tempdir) @@ -1002,9 +1007,9 @@ class DevtoolTests(DevtoolBase): runCmd('git add oe-local-files', cwd=tempdir) runCmd('git commit -m "Add local sources"', cwd=tempdir) # Edit / commit local sources - runCmd('echo "# Foobar" >> oe-local-files/acinclude.m4', cwd=tempdir) + runCmd('echo "# Foobar" >> oe-local-files/file1', cwd=tempdir) runCmd('git commit -am "Edit existing file"', cwd=tempdir) - runCmd('git rm oe-local-files/run-ptest', cwd=tempdir) + runCmd('git rm oe-local-files/file2', cwd=tempdir) runCmd('git commit -m"Remove file"', cwd=tempdir) runCmd('echo "Foo" > oe-local-files/new-local', cwd=tempdir) runCmd('git add oe-local-files/new-local', cwd=tempdir) @@ -1016,11 +1021,11 @@ class DevtoolTests(DevtoolBase): os.path.dirname(recipefile)) # Checkout unmodified file to working copy -> devtool should still pick # the modified version from HEAD - runCmd('git checkout HEAD^ -- oe-local-files/acinclude.m4', cwd=tempdir) + runCmd('git checkout HEAD^ -- oe-local-files/file1', cwd=tempdir) runCmd('devtool update-recipe %s' % testrecipe) expected_status = [(' M', '.*/%s$' % os.path.basename(recipefile)), - (' M', '.*/acinclude.m4$'), - (' D', '.*/run-ptest$'), + (' M', '.*/file1$'), + (' D', '.*/file2$'), ('??', '.*/new-local$'), ('??', '.*/0001-Add-new-file.patch$')] self._check_repo_status(os.path.dirname(recipefile), expected_status) diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/distrodata.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/distrodata.py index 12540adc7..7b2800464 100644 --- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/distrodata.py +++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/distrodata.py @@ -9,6 +9,11 @@ class Distrodata(OESelftestTestCase): @classmethod def setUpClass(cls): super(Distrodata, cls).setUpClass() + feature = 'INHERIT += "distrodata"\n' + feature += 'LICENSE_FLAGS_WHITELIST += " commercial"\n' + + cls.write_config(cls, feature) + bitbake('-c checkpkg world') @OETestID(1902) def test_checkpkg(self): @@ -18,11 +23,6 @@ class Distrodata(OESelftestTestCase): Product: oe-core Author: Alexander Kanavin <alexander.kanavin@intel.com> """ - feature = 'INHERIT += "distrodata"\n' - feature += 'LICENSE_FLAGS_WHITELIST += " commercial"\n' - - self.write_config(feature) - bitbake('-c checkpkg world') checkpkg_result = open(os.path.join(get_bb_var("LOG_DIR"), "checkpkg.csv")).readlines()[1:] regressed_failures = [pkg_data[0] for pkg_data in [pkg_line.split('\t') for pkg_line in checkpkg_result] if pkg_data[11] == 'UNKNOWN_BROKEN'] regressed_successes = [pkg_data[0] for pkg_data in [pkg_line.split('\t') for pkg_line in checkpkg_result] if pkg_data[11] == 'KNOWN_BROKEN'] @@ -40,3 +40,60 @@ The following packages have been checked successfully for upstream versions, but their recipes claim otherwise by setting UPSTREAM_VERSION_UNKNOWN. Please remove that line from the recipes. """ + "\n".join(regressed_successes) self.assertTrue(len(regressed_failures) == 0 and len(regressed_successes) == 0, msg) + + def test_maintainers(self): + """ + Summary: Test that oe-core recipes have a maintainer + Expected: All oe-core recipes (except a few special static/testing ones) should have a maintainer listed in maintainers.inc file. + Product: oe-core + Author: Alexander Kanavin <alexander.kanavin@intel.com> + """ + def is_exception(pkg): + exceptions = ["packagegroup-", "initramfs-", "systemd-machine-units", "target-sdk-provides-dummy"] + for i in exceptions: + if i in pkg: + return True + return False + + def is_in_oe_core(recipe, recipes): + self.assertTrue(recipe in recipes.keys(), "Recipe %s was not in 'bitbake-layers show-recipes' output" %(recipe)) + self.assertTrue(len(recipes[recipe]) > 0, "'bitbake-layers show-recipes' could not determine what layer(s) a recipe %s is in" %(recipe)) + try: + recipes[recipe].index('meta') + return True + except ValueError: + return False + + def get_recipe_layers(): + import re + + recipes = {} + recipe_regex = re.compile('^(?P<name>.*):$') + layer_regex = re.compile('^ (?P<name>\S*) +') + output = runCmd('bitbake-layers show-recipes').output + for line in output.split('\n'): + recipe_name_obj = recipe_regex.search(line) + if recipe_name_obj: + recipe_name = recipe_name_obj.group('name') + recipes[recipe_name] = [] + recipe_layer_obj = layer_regex.search(line) + if recipe_layer_obj: + layer_name = recipe_layer_obj.group('name') + recipes[recipe_name].append(layer_name) + return recipes + + checkpkg_result = open(os.path.join(get_bb_var("LOG_DIR"), "checkpkg.csv")).readlines()[1:] + recipes_layers = get_recipe_layers() + no_maintainer_list = [pkg_data[0] for pkg_data in [pkg_line.split('\t') for pkg_line in checkpkg_result] \ + if pkg_data[14] == '' and is_in_oe_core(pkg_data[0], recipes_layers) and not is_exception(pkg_data[0])] + msg = """ +The following packages do not have a maintainer assigned to them. Please add an entry to meta/conf/distro/include/maintainers.inc file. +""" + "\n".join(no_maintainer_list) + self.assertTrue(len(no_maintainer_list) == 0, msg) + + with_maintainer_list = [pkg_data[0] for pkg_data in [pkg_line.split('\t') for pkg_line in checkpkg_result] \ + if pkg_data[14] != '' and is_in_oe_core(pkg_data[0], recipes_layers) and not is_exception(pkg_data[0])] + msg = """ +The list of oe-core packages with maintainers is empty. This may indicate that the test has regressed and needs fixing. +""" + self.assertTrue(len(with_maintainer_list) > 0, msg) diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/efibootpartition.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/efibootpartition.py new file mode 100644 index 000000000..0c8325669 --- /dev/null +++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/efibootpartition.py @@ -0,0 +1,45 @@ +# Based on runqemu.py test file +# +# Copyright (c) 2017 Wind River Systems, Inc. +# + +import re + +from oeqa.selftest.case import OESelftestTestCase +from oeqa.utils.commands import bitbake, runqemu, get_bb_var + +class GenericEFITest(OESelftestTestCase): + """EFI booting test class""" + + buffer = True + cmd_common = "runqemu nographic serial wic ovmf" + efi_provider = "systemd-boot" + image = "core-image-minimal" + machine = "qemux86-64" + recipes_built = False + + @classmethod + def setUpLocal(self): + super(GenericEFITest, self).setUpLocal(self) + + self.write_config(self, +""" +EFI_PROVIDER = "%s" +IMAGE_FSTYPES_pn-%s_append = " wic" +MACHINE = "%s" +MACHINE_FEATURES_append = " efi" +WKS_FILE = "efi-bootdisk.wks.in" +IMAGE_INSTALL_append = " grub-efi systemd-boot kernel-image-bzimage" +""" +% (self.efi_provider, self.image, self.machine)) + if not self.recipes_built: + bitbake("ovmf") + bitbake(self.image) + self.recipes_built = True + + @classmethod + def test_boot_efi(self): + """Test generic boot partition with qemu""" + cmd = "%s %s" % (self.cmd_common, self.machine) + with runqemu(self.image, ssh=False, launch_cmd=cmd) as qemu: + self.assertTrue(qemu.runner.logged, "Failed: %s" % cmd) diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/gotoolchain.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/gotoolchain.py new file mode 100644 index 000000000..1e23257f4 --- /dev/null +++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/gotoolchain.py @@ -0,0 +1,67 @@ +import glob +import os +import shutil +import tempfile +from oeqa.selftest.case import OESelftestTestCase +from oeqa.utils.commands import runCmd, bitbake, get_bb_vars + + +class oeGoToolchainSelfTest(OESelftestTestCase): + """ + Test cases for OE's Go toolchain + """ + + @staticmethod + def get_sdk_environment(tmpdir_SDKQA): + pattern = os.path.join(tmpdir_SDKQA, "environment-setup-*") + # FIXME: this is a very naive implementation + return glob.glob(pattern)[0] + + @staticmethod + def get_sdk_toolchain(): + bb_vars = get_bb_vars(['SDK_DEPLOY', 'TOOLCHAIN_OUTPUTNAME'], + "meta-go-toolchain") + sdk_deploy = bb_vars['SDK_DEPLOY'] + toolchain_name = bb_vars['TOOLCHAIN_OUTPUTNAME'] + return os.path.join(sdk_deploy, toolchain_name + ".sh") + + @classmethod + def setUpClass(cls): + super(oeGoToolchainSelfTest, cls).setUpClass() + cls.tmpdir_SDKQA = tempfile.mkdtemp(prefix='SDKQA') + cls.go_path = os.path.join(cls.tmpdir_SDKQA, "go") + # Build the SDK and locate it in DEPLOYDIR + bitbake("meta-go-toolchain") + cls.sdk_path = oeGoToolchainSelfTest.get_sdk_toolchain() + # Install the SDK into the tmpdir + runCmd("sh %s -y -d \"%s\"" % (cls.sdk_path, cls.tmpdir_SDKQA)) + cls.env_SDK = oeGoToolchainSelfTest.get_sdk_environment(cls.tmpdir_SDKQA) + + @classmethod + def tearDownClass(cls): + shutil.rmtree(cls.tmpdir_SDKQA, ignore_errors=True) + super(oeGoToolchainSelfTest, cls).tearDownClass() + + def run_sdk_go_command(self, gocmd): + cmd = "cd %s; " % self.tmpdir_SDKQA + cmd = cmd + ". %s; " % self.env_SDK + cmd = cmd + "export GOPATH=%s; " % self.go_path + cmd = cmd + "${CROSS_COMPILE}go %s" % gocmd + return runCmd(cmd).status + + def test_go_dep_build(self): + proj = "github.com/golang" + name = "dep" + ver = "v0.3.1" + archive = ".tar.gz" + url = "https://%s/%s/archive/%s%s" % (proj, name, ver, archive) + + runCmd("cd %s; wget %s" % (self.tmpdir_SDKQA, url)) + runCmd("cd %s; tar -xf %s" % (self.tmpdir_SDKQA, ver+archive)) + runCmd("mkdir -p %s/src/%s" % (self.go_path, proj)) + runCmd("mv %s/dep-0.3.1 %s/src/%s/%s" + % (self.tmpdir_SDKQA, self.go_path, proj, name)) + retv = self.run_sdk_go_command('build %s/%s/cmd/dep' + % (proj, name)) + self.assertEqual(retv, 0, + msg="Running go build failed for %s" % name) diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/imagefeatures.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/imagefeatures.py index 0ffb68692..09e0b2062 100644 --- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/imagefeatures.py +++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/imagefeatures.py @@ -211,7 +211,7 @@ class ImageFeatures(OESelftestTestCase): image_name = 'core-image-minimal' img_types = [itype for itype in get_bb_var("IMAGE_TYPES", image_name).split() \ - if itype not in ('container', 'elf', 'multiubi')] + if itype not in ('container', 'elf', 'f2fs', 'multiubi')] config = 'IMAGE_FSTYPES += "%s"\n'\ 'MKUBIFS_ARGS ?= "-m 2048 -e 129024 -c 2047"\n'\ diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/meta_ide.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/meta_ide.py new file mode 100644 index 000000000..5df9d3ed9 --- /dev/null +++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/meta_ide.py @@ -0,0 +1,49 @@ +from oeqa.selftest.case import OESelftestTestCase +from oeqa.sdk.utils.sdkbuildproject import SDKBuildProject +from oeqa.utils.commands import bitbake, get_bb_vars, runCmd +from oeqa.core.decorator.oeid import OETestID +import tempfile +import shutil + +class MetaIDE(OESelftestTestCase): + + @classmethod + def setUpClass(cls): + super(MetaIDE, cls).setUpClass() + bitbake('meta-ide-support') + bb_vars = get_bb_vars(['MULTIMACH_TARGET_SYS', 'TMPDIR', 'COREBASE']) + cls.environment_script = 'environment-setup-%s' % bb_vars['MULTIMACH_TARGET_SYS'] + cls.tmpdir = bb_vars['TMPDIR'] + cls.environment_script_path = '%s/%s' % (cls.tmpdir, cls.environment_script) + cls.corebasedir = bb_vars['COREBASE'] + cls.tmpdir_metaideQA = tempfile.mkdtemp(prefix='metaide') + + @classmethod + def tearDownClass(cls): + shutil.rmtree(cls.tmpdir_metaideQA, ignore_errors=True) + super(MetaIDE, cls).tearDownClass() + + @OETestID(1982) + def test_meta_ide_had_installed_meta_ide_support(self): + self.assertExists(self.environment_script_path) + + @OETestID(1983) + def test_meta_ide_can_compile_c_program(self): + runCmd('cp %s/test.c %s' % (self.tc.files_dir, self.tmpdir_metaideQA)) + runCmd("cd %s; . %s; $CC test.c -lm" % (self.tmpdir_metaideQA, self.environment_script_path)) + compiled_file = '%s/a.out' % self.tmpdir_metaideQA + self.assertExists(compiled_file) + + @OETestID(1984) + def test_meta_ide_can_build_cpio_project(self): + dl_dir = self.td.get('DL_DIR', None) + self.project = SDKBuildProject(self.tmpdir_metaideQA + "/cpio/", self.environment_script_path, + "https://ftp.gnu.org/gnu/cpio/cpio-2.12.tar.gz", + self.tmpdir_metaideQA, self.td['DATETIME'], dl_dir=dl_dir) + self.project.download_archive() + self.assertEqual(self.project.run_configure(), 0, + msg="Running configure failed") + self.assertEqual(self.project.run_make(), 0, + msg="Running make failed") + self.assertEqual(self.project.run_install(), 0, + msg="Running make install failed") diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/runqemu.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/runqemu.py index 47d41f521..5ebdd57a4 100644 --- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/runqemu.py +++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/runqemu.py @@ -3,9 +3,10 @@ # import re - +import tempfile +import time from oeqa.selftest.case import OESelftestTestCase -from oeqa.utils.commands import bitbake, runqemu, get_bb_var +from oeqa.utils.commands import bitbake, runqemu, get_bb_var, runCmd from oeqa.core.decorator.oeid import OETestID class RunqemuTests(OESelftestTestCase): @@ -136,3 +137,70 @@ SYSLINUX_TIMEOUT = "10" cmd = "%s %s" % (self.cmd_common, rootfs) with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: self.assertTrue(qemu.runner.logged, "Failed: %s" % cmd) + +# This test was designed as a separate class to test that shutdown +# command will shutdown qemu as expected on each qemu architecture +# based on the MACHINE configuration inside the config file +# (eg. local.conf). +# +# This was different compared to RunqemuTests, where RunqemuTests was +# dedicated for MACHINE=qemux86-64 where it test that qemux86-64 will +# bootup various filesystem types, including live image(iso and hddimg) +# where live image was not supported on all qemu architecture. +class QemuTest(OESelftestTestCase): + + @classmethod + def setUpClass(cls): + super(QemuTest, cls).setUpClass() + cls.recipe = 'core-image-minimal' + cls.machine = get_bb_var('MACHINE') + cls.deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE') + cls.cmd_common = "runqemu nographic" + cls.qemuboot_conf = "%s-%s.qemuboot.conf" % (cls.recipe, cls.machine) + cls.qemuboot_conf = os.path.join(cls.deploy_dir_image, cls.qemuboot_conf) + bitbake(cls.recipe) + + def _start_qemu_shutdown_check_if_shutdown_succeeded(self, qemu, timeout): + qemu.run_serial("shutdown -h now") + # Stop thread will stop the LoggingThread instance used for logging + # qemu through serial console, stop thread will prevent this code + # from facing exception (Console connection closed unexpectedly) + # when qemu was shutdown by the above shutdown command + qemu.runner.stop_thread() + time_track = 0 + while True: + is_alive = qemu.check() + if not is_alive: + return True + if time_track > timeout: + return False + time.sleep(1) + time_track += 1 + + def test_qemu_can_shutdown(self): + self.assertExists(self.qemuboot_conf) + cmd = "%s %s" % (self.cmd_common, self.qemuboot_conf) + shutdown_timeout = 120 + with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: + qemu_shutdown_succeeded = self._start_qemu_shutdown_check_if_shutdown_succeeded(qemu, shutdown_timeout) + self.assertTrue(qemu_shutdown_succeeded, 'Failed: %s does not shutdown within timeout(%s)' % (self.machine, shutdown_timeout)) + + # Need to have portmap/rpcbind running to allow this test to work and + # current autobuilder setup does not have this. + def disabled_test_qemu_can_boot_nfs_and_shutdown(self): + self.assertExists(self.qemuboot_conf) + bitbake('meta-ide-support') + rootfs_tar = "%s-%s.tar.bz2" % (self.recipe, self.machine) + rootfs_tar = os.path.join(self.deploy_dir_image, rootfs_tar) + self.assertExists(rootfs_tar) + tmpdir = tempfile.mkdtemp(prefix='qemu_nfs') + tmpdir_nfs = os.path.join(tmpdir, 'nfs') + cmd_extract_nfs = 'runqemu-extract-sdk %s %s' % (rootfs_tar, tmpdir_nfs) + result = runCmd(cmd_extract_nfs) + self.assertEqual(0, result.status, "runqemu-extract-sdk didn't run as expected. %s" % result.output) + cmd = "%s nfs %s %s" % (self.cmd_common, self.qemuboot_conf, tmpdir_nfs) + shutdown_timeout = 120 + with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: + qemu_shutdown_succeeded = self._start_qemu_shutdown_check_if_shutdown_succeeded(qemu, shutdown_timeout) + self.assertTrue(qemu_shutdown_succeeded, 'Failed: %s does not shutdown within timeout(%s)' % (self.machine, shutdown_timeout)) + runCmd('rm -rf %s' % tmpdir) diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/runtime_test.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/runtime_test.py index 25270b753..9c9b4b341 100644 --- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/runtime_test.py +++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/runtime_test.py @@ -167,55 +167,6 @@ class TestImage(OESelftestTestCase): class Postinst(OESelftestTestCase): @OETestID(1540) - def test_verify_postinst(self): - """ - Summary: The purpose of this test is to verify the execution order of postinst Bugzilla ID: [5319] - Expected : - 1. Compile a minimal image. - 2. The compiled image will add the created layer with the recipes postinst[ abdpt] - 3. Run qemux86 - 4. Validate the task execution order - Author: Francisco Pedraza <francisco.j.pedraza.gonzalez@intel.com> - """ - features = 'INHERIT += "testimage"\n' - features += 'CORE_IMAGE_EXTRA_INSTALL += "postinst-at-rootfs \ -postinst-delayed-a \ -postinst-delayed-b \ -postinst-delayed-d \ -postinst-delayed-p \ -postinst-delayed-t \ -"\n' - self.write_config(features) - - bitbake('core-image-minimal -f ') - - postinst_list = ['100-postinst-at-rootfs', - '101-postinst-delayed-a', - '102-postinst-delayed-b', - '103-postinst-delayed-d', - '104-postinst-delayed-p', - '105-postinst-delayed-t'] - path_workdir = get_bb_var('WORKDIR','core-image-minimal') - workspacedir = 'testimage/qemu_boot_log' - workspacedir = os.path.join(path_workdir, workspacedir) - rexp = re.compile("^Running postinst .*/(?P<postinst>.*)\.\.\.$") - with runqemu('core-image-minimal') as qemu: - with open(workspacedir) as f: - found = False - idx = 0 - for line in f.readlines(): - line = line.strip().replace("^M","") - if not line: # To avoid empty lines - continue - m = rexp.search(line) - if m: - self.assertEqual(postinst_list[idx], m.group('postinst'), "Fail") - idx = idx+1 - found = True - elif found: - self.assertEqual(idx, len(postinst_list), "Not found all postinsts") - break - @OETestID(1545) def test_postinst_rootfs_and_boot(self): """ @@ -234,16 +185,22 @@ postinst-delayed-t \ for initialization managers: sysvinit and systemd. """ - file_rootfs_name = "this-was-created-at-rootfstime" - fileboot_name = "this-was-created-at-first-boot" - rootfs_pkg = 'postinst-at-rootfs' - boot_pkg = 'postinst-delayed-a' + + import oe.path + + vars = get_bb_vars(("IMAGE_ROOTFS", "sysconfdir"), "core-image-minimal") + rootfs = vars["IMAGE_ROOTFS"] + self.assertIsNotNone(rootfs) + sysconfdir = vars["sysconfdir"] + self.assertIsNotNone(sysconfdir) + # Need to use oe.path here as sysconfdir starts with / + hosttestdir = oe.path.join(rootfs, sysconfdir, "postinst-test") + targettestdir = os.path.join(sysconfdir, "postinst-test") for init_manager in ("sysvinit", "systemd"): for classes in ("package_rpm", "package_deb", "package_ipk"): with self.subTest(init_manager=init_manager, package_class=classes): - features = 'MACHINE = "qemux86"\n' - features += 'CORE_IMAGE_EXTRA_INSTALL += "%s %s "\n'% (rootfs_pkg, boot_pkg) + features = 'CORE_IMAGE_EXTRA_INSTALL = "postinst-delayed-b"\n' features += 'IMAGE_FEATURES += "package-management empty-root-password"\n' features += 'PACKAGE_CLASSES = "%s"\n' % classes if init_manager == "systemd": @@ -255,13 +212,49 @@ postinst-delayed-t \ bitbake('core-image-minimal') - file_rootfs_created = os.path.join(get_bb_var('IMAGE_ROOTFS', "core-image-minimal"), - file_rootfs_name) - found = os.path.isfile(file_rootfs_created) - self.assertTrue(found, "File %s was not created at rootfs time by %s" % \ - (file_rootfs_name, rootfs_pkg)) + self.assertTrue(os.path.isfile(os.path.join(hosttestdir, "rootfs")), + "rootfs state file was not created") - testcommand = 'ls /etc/' + fileboot_name with runqemu('core-image-minimal') as qemu: - status, output = qemu.run_serial("-f /etc/" + fileboot_name) - self.assertEqual(status, 0, 'File %s was not created at first boot (%s)' % (fileboot_name, output)) + # Make the test echo a string and search for that as + # run_serial()'s status code is useless.' + for filename in ("rootfs", "delayed-a", "delayed-b"): + status, output = qemu.run_serial("test -f %s && echo found" % os.path.join(targettestdir, filename)) + self.assertEqual(output, "found", "%s was not present on boot" % filename) + + + + def test_failing_postinst(self): + """ + Summary: The purpose of this test case is to verify that post-installation + scripts that contain errors are properly reported. + Expected: The scriptlet failure is properly reported. + The file that is created after the error in the scriptlet is not present. + Product: oe-core + Author: Alexander Kanavin <alexander.kanavin@intel.com> + """ + + import oe.path + + vars = get_bb_vars(("IMAGE_ROOTFS", "sysconfdir"), "core-image-minimal") + rootfs = vars["IMAGE_ROOTFS"] + self.assertIsNotNone(rootfs) + sysconfdir = vars["sysconfdir"] + self.assertIsNotNone(sysconfdir) + # Need to use oe.path here as sysconfdir starts with / + hosttestdir = oe.path.join(rootfs, sysconfdir, "postinst-test") + + for classes in ("package_rpm", "package_deb", "package_ipk"): + with self.subTest(package_class=classes): + features = 'CORE_IMAGE_EXTRA_INSTALL = "postinst-rootfs-failing"\n' + features += 'PACKAGE_CLASSES = "%s"\n' % classes + self.write_config(features) + bb_result = bitbake('core-image-minimal') + self.assertGreaterEqual(bb_result.output.find("Intentionally failing postinstall scriptlets of ['postinst-rootfs-failing'] to defer them to first boot is deprecated."), 0, + "Warning about a failed scriptlet not found in bitbake output: %s" %(bb_result.output)) + + self.assertTrue(os.path.isfile(os.path.join(hosttestdir, "rootfs-before-failure")), + "rootfs-before-failure file was not created") + self.assertFalse(os.path.isfile(os.path.join(hosttestdir, "rootfs-after-failure")), + "rootfs-after-failure file was created") + diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/signing.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/signing.py index b3d1a8292..a750cfc7b 100644 --- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/signing.py +++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/signing.py @@ -87,7 +87,7 @@ class Signing(OESelftestTestCase): ret = runCmd('%s/rpmkeys --define "_dbpath %s" --checksig %s' % (staging_bindir_native, rpmdb, pkg_deploy)) # tmp/deploy/rpm/i586/ed-1.9-r0.i586.rpm: rsa sha1 md5 OK - self.assertIn('rsa sha1 (md5) pgp md5 OK', ret.output, 'Package signed incorrectly.') + self.assertIn('digests signatures OK', ret.output, 'Package signed incorrectly.') shutil.rmtree(rpmdb) #Check that an image can be built from signed packages diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/sstatetests.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/sstatetests.py index 47900886a..7b008e409 100644 --- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/sstatetests.py +++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/sstatetests.py @@ -2,15 +2,51 @@ import os import shutil import glob import subprocess +import tempfile from oeqa.selftest.case import OESelftestTestCase -from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_test_layer +from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_test_layer, create_temp_layer from oeqa.selftest.cases.sstate import SStateBase from oeqa.core.decorator.oeid import OETestID import bb.siggen class SStateTests(SStateBase): + def test_autorev_sstate_works(self): + # Test that a git repository which changes is correctly handled by SRCREV = ${AUTOREV} + # when PV does not contain SRCPV + + tempdir = tempfile.mkdtemp(prefix='oeqa') + self.track_for_cleanup(tempdir) + create_temp_layer(tempdir, 'selftestrecipetool') + self.add_command_to_tearDown('bitbake-layers remove-layer %s' % tempdir) + runCmd('bitbake-layers add-layer %s' % tempdir) + + # Use dbus-wait as a local git repo we can add a commit between two builds in + pn = 'dbus-wait' + srcrev = '6cc6077a36fe2648a5f993fe7c16c9632f946517' + url = 'git://git.yoctoproject.org/dbus-wait' + result = runCmd('git clone %s noname' % url, cwd=tempdir) + srcdir = os.path.join(tempdir, 'noname') + result = runCmd('git reset --hard %s' % srcrev, cwd=srcdir) + self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure.ac')), 'Unable to find configure script in source directory') + + 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' + result = runCmd(['recipetool', 'create', '-o', recipefile, srcuri]) + self.assertTrue(os.path.isfile(recipefile), 'recipetool did not create recipe file; output:\n%s' % result.output) + + with open(recipefile, 'a') as f: + f.write('SRCREV = "${AUTOREV}"\n') + f.write('PV = "1.0"\n') + + bitbake("dbus-wait-test -c fetch") + with open(os.path.join(srcdir, "bar.txt"), "w") as f: + f.write("foo") + result = runCmd('git add bar.txt; git commit -asm "add bar"', cwd=srcdir) + bitbake("dbus-wait-test -c unpack") + # Test sstate files creation and their location def run_test_sstate_creation(self, targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True, should_pass=True): @@ -490,7 +526,7 @@ http_proxy = "http://example.com/" # this is an expensive computation, thus just compare the first 'max_sigfiles_to_compare' k files max_sigfiles_to_compare = 20 first, rest = files[:max_sigfiles_to_compare], files[max_sigfiles_to_compare:] - compare_sigfiles(first, files1.keys(), files2.keys(), compare=True) - compare_sigfiles(rest, files1.keys(), files2.keys(), compare=False) + compare_sigfiles(first, files1, files2, compare=True) + compare_sigfiles(rest, files1, files2, compare=False) self.fail("sstate hashes not identical.") diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/wic.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/wic.py index 651d575dc..b84466d9a 100644 --- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/wic.py +++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/cases/wic.py @@ -623,7 +623,7 @@ part /etc --source rootfs --ondisk mmcblk0 --fstype=ext4 --exclude-path bin/ --r self.assertTrue(os.path.islink(path)) self.assertTrue(os.path.isfile(os.path.realpath(path))) - @OETestID(1422) + @OETestID(1424) @only_for_arch(['i586', 'i686', 'x86_64']) def test_qemu(self): """Test wic-image-minimal under qemu""" @@ -634,10 +634,13 @@ part /etc --source rootfs --ondisk mmcblk0 --fstype=ext4 --exclude-path bin/ --r self.remove_config(config) with runqemu('wic-image-minimal', ssh=False) as qemu: - cmd = "mount |grep '^/dev/' | cut -f1,3 -d ' '" + cmd = "mount |grep '^/dev/' | cut -f1,3 -d ' ' | sort" + status, output = qemu.run_serial(cmd) + self.assertEqual(output, '/dev/root /\r\n/dev/sda1 /boot\r\n/dev/sda3 /media\r\n/dev/sda4 /mnt') + cmd = "grep UUID= /etc/fstab" status, output = qemu.run_serial(cmd) self.assertEqual(1, status, 'Failed to run command "%s": %s' % (cmd, output)) - self.assertEqual(output, '/dev/root /\r\n/dev/sda1 /boot\r\n/dev/sda3 /mnt') + self.assertEqual(output, 'UUID=2c71ef06-a81d-4735-9d3a-379b69c6bdba\t/media\text4\tdefaults\t0\t0') @only_for_arch(['i586', 'i686', 'x86_64']) @OETestID(1852) diff --git a/import-layers/yocto-poky/meta/lib/oeqa/targetcontrol.py b/import-layers/yocto-poky/meta/lib/oeqa/targetcontrol.py index f63936c3e..59a9c35a0 100644 --- a/import-layers/yocto-poky/meta/lib/oeqa/targetcontrol.py +++ b/import-layers/yocto-poky/meta/lib/oeqa/targetcontrol.py @@ -91,6 +91,8 @@ class QemuTarget(BaseTarget): def __init__(self, d, logger, image_fstype=None): + import oe.types + super(QemuTarget, self).__init__(d, logger) self.rootfs = '' @@ -107,7 +109,7 @@ class QemuTarget(BaseTarget): dump_dir = d.getVar("TESTIMAGE_DUMP_DIR") qemu_use_kvm = d.getVar("QEMU_USE_KVM") if qemu_use_kvm and \ - (qemu_use_kvm == "True" and "x86" in d.getVar("MACHINE") or \ + (oe.types.boolean(qemu_use_kvm) and "x86" in d.getVar("MACHINE") or \ d.getVar("MACHINE") in qemu_use_kvm.split()): use_kvm = True else: diff --git a/import-layers/yocto-poky/meta/lib/oeqa/utils/commands.py b/import-layers/yocto-poky/meta/lib/oeqa/utils/commands.py index 0bb90028d..0d9cf23fe 100644 --- a/import-layers/yocto-poky/meta/lib/oeqa/utils/commands.py +++ b/import-layers/yocto-poky/meta/lib/oeqa/utils/commands.py @@ -227,7 +227,7 @@ def get_bb_vars(variables=None, target=None, postconfig=None): bbenv = get_bb_env(target, postconfig=postconfig) if variables is not None: - variables = variables.copy() + variables = list(variables) var_re = re.compile(r'^(export )?(?P<var>\w+(_.*)?)="(?P<value>.*)"$') unset_re = re.compile(r'^unset (?P<var>\w+)$') lastline = None @@ -285,7 +285,7 @@ def create_temp_layer(templayerdir, templayername, priority=999, recipepathspec= f.write('BBFILE_PATTERN_%s = "^${LAYERDIR}/"\n' % templayername) f.write('BBFILE_PRIORITY_%s = "%d"\n' % (templayername, priority)) f.write('BBFILE_PATTERN_IGNORE_EMPTY_%s = "1"\n' % templayername) - + f.write('LAYERSERIES_COMPAT_%s = "${LAYERSERIES_COMPAT_core}"\n' % templayername) @contextlib.contextmanager def runqemu(pn, ssh=True, runqemuparams='', image_fstype=None, launch_cmd=None, qemuparams=None, overrides={}, discard_writes=True): diff --git a/import-layers/yocto-poky/meta/lib/oeqa/utils/package_manager.py b/import-layers/yocto-poky/meta/lib/oeqa/utils/package_manager.py index 724afb2b5..afd5b8e75 100644 --- a/import-layers/yocto-poky/meta/lib/oeqa/utils/package_manager.py +++ b/import-layers/yocto-poky/meta/lib/oeqa/utils/package_manager.py @@ -14,7 +14,8 @@ def get_package_manager(d, root_path): if pkg_class == "rpm": pm = RpmPM(d, root_path, - d.getVar('TARGET_VENDOR')) + d.getVar('TARGET_VENDOR'), + filterbydependencies=False) pm.create_configs() elif pkg_class == "ipk": diff --git a/import-layers/yocto-poky/meta/lib/oeqa/utils/qemurunner.py b/import-layers/yocto-poky/meta/lib/oeqa/utils/qemurunner.py index 0631d4321..c962602a6 100644 --- a/import-layers/yocto-poky/meta/lib/oeqa/utils/qemurunner.py +++ b/import-layers/yocto-poky/meta/lib/oeqa/utils/qemurunner.py @@ -194,7 +194,8 @@ class QemuRunner: sys.exit(0) self.logger.debug("runqemu started, pid is %s" % self.runqemu.pid) - self.logger.debug("waiting at most %s seconds for qemu pid" % self.runqemutime) + self.logger.debug("waiting at most %s seconds for qemu pid (%s)" % + (self.runqemutime, time.strftime("%D %H:%M:%S"))) endtime = time.time() + self.runqemutime while not self.is_alive() and time.time() < endtime: if self.runqemu.poll(): @@ -208,7 +209,8 @@ class QemuRunner: time.sleep(0.5) if not self.is_alive(): - self.logger.error("Qemu pid didn't appear in %s seconds" % self.runqemutime) + self.logger.error("Qemu pid didn't appear in %s seconds (%s)" % + (self.runqemutime, time.strftime("%D %H:%M:%S"))) # Dump all processes to help us to figure out what is going on... ps = subprocess.Popen(['ps', 'axww', '-o', 'pid,ppid,command '], stdout=subprocess.PIPE).communicate()[0] processes = ps.decode("utf-8") @@ -225,7 +227,9 @@ class QemuRunner: # We are alive: qemu is running out = self.getOutput(output) netconf = False # network configuration is not required by default - self.logger.debug("qemu started in %s seconds - qemu procces pid is %s" % (time.time() - (endtime - self.runqemutime), self.qemupid)) + self.logger.debug("qemu started in %s seconds - qemu procces pid is %s (%s)" % + (time.time() - (endtime - self.runqemutime), + self.qemupid, time.strftime("%D %H:%M:%S"))) if get_ip: cmdline = '' with open('/proc/%s/cmdline' % self.qemupid) as p: @@ -269,7 +273,8 @@ class QemuRunner: return False self.logger.debug("Output from runqemu:\n%s", out) - self.logger.debug("Waiting at most %d seconds for login banner" % self.boottime) + self.logger.debug("Waiting at most %d seconds for login banner (%s)" % + (self.boottime, time.strftime("%D %H:%M:%S"))) endtime = time.time() + self.boottime socklist = [self.server_socket] reachedlogin = False @@ -298,15 +303,22 @@ class QemuRunner: self.server_socket = qemusock stopread = True reachedlogin = True - self.logger.debug("Reached login banner") + self.logger.debug("Reached login banner in %s seconds (%s)" % + (time.time() - (endtime - self.boottime), + time.strftime("%D %H:%M:%S"))) else: + # no need to check if reachedlogin unless we support multiple connections + self.logger.debug("QEMU socket disconnected before login banner reached. (%s)" % + time.strftime("%D %H:%M:%S")) socklist.remove(sock) sock.close() stopread = True if not reachedlogin: - self.logger.debug("Target didn't reached login boot in %d seconds" % self.boottime) + if time.time() >= endtime: + self.logger.debug("Target didn't reach login banner in %d seconds (%s)" % + (self.boottime, time.strftime("%D %H:%M:%S"))) tail = lambda l: "\n".join(l.splitlines()[-25:]) # in case bootlog is empty, use tail qemu log store at self.msg lines = tail(bootlog if bootlog else self.msg) |