diff options
Diffstat (limited to 'meta/lib/oeqa/runtime')
63 files changed, 897 insertions, 512 deletions
diff --git a/meta/lib/oeqa/runtime/cases/_qemutiny.py b/meta/lib/oeqa/runtime/cases/_qemutiny.py index 6886e36502..816fd4a7cb 100644 --- a/meta/lib/oeqa/runtime/cases/_qemutiny.py +++ b/meta/lib/oeqa/runtime/cases/_qemutiny.py | |||
@@ -1,12 +1,19 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
5 | from oeqa.runtime.case import OERuntimeTestCase | 7 | from oeqa.runtime.case import OERuntimeTestCase |
8 | from oeqa.core.target.qemu import OEQemuTarget | ||
6 | 9 | ||
7 | class QemuTinyTest(OERuntimeTestCase): | 10 | class QemuTinyTest(OERuntimeTestCase): |
8 | 11 | ||
9 | def test_boot_tiny(self): | 12 | def test_boot_tiny(self): |
10 | status, output = self.target.run_serial('uname -a') | 13 | # Until the target has explicit run_serial support, check that the |
11 | msg = "Cannot detect poky tiny boot!" | 14 | # target is the qemu runner |
12 | self.assertTrue("yocto-tiny" in output, msg) | 15 | if isinstance(self.target, OEQemuTarget): |
16 | status, output = self.target.runner.run_serial('uname -a') | ||
17 | self.assertIn("Linux", output) | ||
18 | else: | ||
19 | self.skipTest("Target %s is not OEQemuTarget" % self.target) | ||
diff --git a/meta/lib/oeqa/runtime/cases/apt.py b/meta/lib/oeqa/runtime/cases/apt.py index 53745df93f..8000645843 100644 --- a/meta/lib/oeqa/runtime/cases/apt.py +++ b/meta/lib/oeqa/runtime/cases/apt.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
@@ -21,7 +23,7 @@ class AptRepoTest(AptTest): | |||
21 | 23 | ||
22 | @classmethod | 24 | @classmethod |
23 | def setUpClass(cls): | 25 | def setUpClass(cls): |
24 | service_repo = os.path.join(cls.tc.td['DEPLOY_DIR_DEB'], 'all') | 26 | service_repo = os.path.join(cls.tc.td['DEPLOY_DIR_DEB'], '') |
25 | cls.repo_server = HTTPService(service_repo, | 27 | cls.repo_server = HTTPService(service_repo, |
26 | '0.0.0.0', port=cls.tc.target.server_port, | 28 | '0.0.0.0', port=cls.tc.target.server_port, |
27 | logger=cls.tc.logger) | 29 | logger=cls.tc.logger) |
@@ -34,20 +36,44 @@ class AptRepoTest(AptTest): | |||
34 | def setup_source_config_for_package_install(self): | 36 | def setup_source_config_for_package_install(self): |
35 | apt_get_source_server = 'http://%s:%s/' % (self.tc.target.server_ip, self.repo_server.port) | 37 | apt_get_source_server = 'http://%s:%s/' % (self.tc.target.server_ip, self.repo_server.port) |
36 | apt_get_sourceslist_dir = '/etc/apt/' | 38 | apt_get_sourceslist_dir = '/etc/apt/' |
37 | self.target.run('cd %s; echo deb [ allow-insecure=yes ] %s ./ > sources.list' % (apt_get_sourceslist_dir, apt_get_source_server)) | 39 | self.target.run('cd %s; echo deb [ allow-insecure=yes ] %s/all ./ > sources.list' % (apt_get_sourceslist_dir, apt_get_source_server)) |
40 | |||
41 | def setup_source_config_for_package_install_signed(self): | ||
42 | apt_get_source_server = 'http://%s:%s' % (self.tc.target.server_ip, self.repo_server.port) | ||
43 | apt_get_sourceslist_dir = '/etc/apt/' | ||
44 | self.target.run("cd %s; cp sources.list sources.list.bak; sed -i 's|\[trusted=yes\] http://bogus_ip:bogus_port|%s|g' sources.list" % (apt_get_sourceslist_dir, apt_get_source_server)) | ||
38 | 45 | ||
39 | def cleanup_source_config_for_package_install(self): | 46 | def cleanup_source_config_for_package_install(self): |
40 | apt_get_sourceslist_dir = '/etc/apt/' | 47 | apt_get_sourceslist_dir = '/etc/apt/' |
41 | self.target.run('cd %s; rm sources.list' % (apt_get_sourceslist_dir)) | 48 | self.target.run('cd %s; rm sources.list' % (apt_get_sourceslist_dir)) |
42 | 49 | ||
50 | def cleanup_source_config_for_package_install_signed(self): | ||
51 | apt_get_sourceslist_dir = '/etc/apt/' | ||
52 | self.target.run('cd %s; mv sources.list.bak sources.list' % (apt_get_sourceslist_dir)) | ||
53 | |||
54 | def setup_key(self): | ||
55 | # the key is found on the target /etc/pki/packagefeed-gpg/ | ||
56 | # named PACKAGEFEED-GPG-KEY-poky-branch | ||
57 | self.target.run('cd %s; apt-key add P*' % ('/etc/pki/packagefeed-gpg')) | ||
58 | |||
43 | @skipIfNotFeature('package-management', | 59 | @skipIfNotFeature('package-management', |
44 | 'Test requires package-management to be in IMAGE_FEATURES') | 60 | 'Test requires package-management to be in IMAGE_FEATURES') |
45 | @skipIfNotDataVar('IMAGE_PKGTYPE', 'deb', | 61 | @skipIfNotDataVar('IMAGE_PKGTYPE', 'deb', |
46 | 'DEB is not the primary package manager') | 62 | 'DEB is not the primary package manager') |
47 | @OEHasPackage(['apt']) | 63 | @OEHasPackage(['apt']) |
48 | def test_apt_install_from_repo(self): | 64 | def test_apt_install_from_repo(self): |
49 | self.setup_source_config_for_package_install() | 65 | if not self.tc.td.get('PACKAGE_FEED_GPG_NAME'): |
50 | self.pkg('update') | 66 | self.setup_source_config_for_package_install() |
51 | self.pkg('remove --yes run-postinsts-dev') | 67 | self.pkg('update') |
52 | self.pkg('install --yes --allow-unauthenticated run-postinsts-dev') | 68 | self.pkg('remove --yes run-postinsts-dev') |
53 | self.cleanup_source_config_for_package_install() | 69 | self.pkg('install --yes --allow-unauthenticated run-postinsts-dev') |
70 | self.cleanup_source_config_for_package_install() | ||
71 | else: | ||
72 | # when we are here a key has been set to sign the package feed and | ||
73 | # public key and gnupg installed on the image by test_testimage_apt | ||
74 | self.setup_source_config_for_package_install_signed() | ||
75 | self.setup_key() | ||
76 | self.pkg('update') | ||
77 | self.pkg('install --yes run-postinsts-dev') | ||
78 | self.pkg('remove --yes run-postinsts-dev') | ||
79 | self.cleanup_source_config_for_package_install_signed() | ||
diff --git a/meta/lib/oeqa/runtime/cases/boot.py b/meta/lib/oeqa/runtime/cases/boot.py index 2142f400a0..dcee3311f7 100644 --- a/meta/lib/oeqa/runtime/cases/boot.py +++ b/meta/lib/oeqa/runtime/cases/boot.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
@@ -13,7 +15,7 @@ from oeqa.core.decorator.data import skipIfQemu | |||
13 | class BootTest(OERuntimeTestCase): | 15 | class BootTest(OERuntimeTestCase): |
14 | 16 | ||
15 | @OETimeout(120) | 17 | @OETimeout(120) |
16 | @skipIfQemu('qemuall', 'Test only runs on real hardware') | 18 | @skipIfQemu() |
17 | @OETestDepends(['ssh.SSHTest.test_ssh']) | 19 | @OETestDepends(['ssh.SSHTest.test_ssh']) |
18 | def test_reboot(self): | 20 | def test_reboot(self): |
19 | output = '' | 21 | output = '' |
diff --git a/meta/lib/oeqa/runtime/cases/buildcpio.py b/meta/lib/oeqa/runtime/cases/buildcpio.py index e29bf16ccb..7be734cb4f 100644 --- a/meta/lib/oeqa/runtime/cases/buildcpio.py +++ b/meta/lib/oeqa/runtime/cases/buildcpio.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
@@ -12,7 +14,7 @@ class BuildCpioTest(OERuntimeTestCase): | |||
12 | 14 | ||
13 | @classmethod | 15 | @classmethod |
14 | def setUpClass(cls): | 16 | def setUpClass(cls): |
15 | uri = 'https://downloads.yoctoproject.org/mirror/sources/cpio-2.13.tar.gz' | 17 | uri = 'https://downloads.yoctoproject.org/mirror/sources/cpio-2.15.tar.gz' |
16 | cls.project = TargetBuildProject(cls.tc.target, | 18 | cls.project = TargetBuildProject(cls.tc.target, |
17 | uri, | 19 | uri, |
18 | dl_dir = cls.tc.td['DL_DIR']) | 20 | dl_dir = cls.tc.td['DL_DIR']) |
@@ -27,7 +29,6 @@ class BuildCpioTest(OERuntimeTestCase): | |||
27 | @OEHasPackage(['autoconf']) | 29 | @OEHasPackage(['autoconf']) |
28 | def test_cpio(self): | 30 | def test_cpio(self): |
29 | self.project.download_archive() | 31 | self.project.download_archive() |
30 | self.project.run_configure('--disable-maintainer-mode', | 32 | self.project.run_configure() |
31 | 'sed -i -e "/char \*program_name/d" src/global.c;') | ||
32 | self.project.run_make() | 33 | self.project.run_make() |
33 | self.project.run_install() | 34 | self.project.run_install() |
diff --git a/meta/lib/oeqa/runtime/cases/buildgalculator.py b/meta/lib/oeqa/runtime/cases/buildgalculator.py index e5cc3e2888..2cfb3243dc 100644 --- a/meta/lib/oeqa/runtime/cases/buildgalculator.py +++ b/meta/lib/oeqa/runtime/cases/buildgalculator.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
diff --git a/meta/lib/oeqa/runtime/cases/buildlzip.py b/meta/lib/oeqa/runtime/cases/buildlzip.py index bc70b41461..44f4f1be71 100644 --- a/meta/lib/oeqa/runtime/cases/buildlzip.py +++ b/meta/lib/oeqa/runtime/cases/buildlzip.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
diff --git a/meta/lib/oeqa/runtime/cases/connman.py b/meta/lib/oeqa/runtime/cases/connman.py index f0d15fac9b..a488752e3f 100644 --- a/meta/lib/oeqa/runtime/cases/connman.py +++ b/meta/lib/oeqa/runtime/cases/connman.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
diff --git a/meta/lib/oeqa/runtime/cases/date.py b/meta/lib/oeqa/runtime/cases/date.py index fdd2a6ae58..a2523de67a 100644 --- a/meta/lib/oeqa/runtime/cases/date.py +++ b/meta/lib/oeqa/runtime/cases/date.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
@@ -13,12 +15,12 @@ class DateTest(OERuntimeTestCase): | |||
13 | def setUp(self): | 15 | def setUp(self): |
14 | if self.tc.td.get('VIRTUAL-RUNTIME_init_manager') == 'systemd': | 16 | if self.tc.td.get('VIRTUAL-RUNTIME_init_manager') == 'systemd': |
15 | self.logger.debug('Stopping systemd-timesyncd daemon') | 17 | self.logger.debug('Stopping systemd-timesyncd daemon') |
16 | self.target.run('systemctl disable --now systemd-timesyncd') | 18 | self.target.run('systemctl disable --now --runtime systemd-timesyncd') |
17 | 19 | ||
18 | def tearDown(self): | 20 | def tearDown(self): |
19 | if self.tc.td.get('VIRTUAL-RUNTIME_init_manager') == 'systemd': | 21 | if self.tc.td.get('VIRTUAL-RUNTIME_init_manager') == 'systemd': |
20 | self.logger.debug('Starting systemd-timesyncd daemon') | 22 | self.logger.debug('Starting systemd-timesyncd daemon') |
21 | self.target.run('systemctl enable --now systemd-timesyncd') | 23 | self.target.run('systemctl enable --now --runtime systemd-timesyncd') |
22 | 24 | ||
23 | @OETestDepends(['ssh.SSHTest.test_ssh']) | 25 | @OETestDepends(['ssh.SSHTest.test_ssh']) |
24 | @OEHasPackage(['coreutils', 'busybox']) | 26 | @OEHasPackage(['coreutils', 'busybox']) |
@@ -28,14 +30,13 @@ class DateTest(OERuntimeTestCase): | |||
28 | self.assertEqual(status, 0, msg=msg) | 30 | self.assertEqual(status, 0, msg=msg) |
29 | oldDate = output | 31 | oldDate = output |
30 | 32 | ||
31 | sampleDate = '"2016-08-09 10:00:00"' | 33 | sampleTimestamp = 1488800000 |
32 | (status, output) = self.target.run("date -s %s" % sampleDate) | 34 | (status, output) = self.target.run("date -s @%d" % sampleTimestamp) |
33 | self.assertEqual(status, 0, msg='Date set failed, output: %s' % output) | 35 | self.assertEqual(status, 0, msg='Date set failed, output: %s' % output) |
34 | 36 | ||
35 | (status, output) = self.target.run("date -R") | 37 | (status, output) = self.target.run('date +"%s"') |
36 | p = re.match('Tue, 09 Aug 2016 10:00:.. \+0000', output) | ||
37 | msg = 'The date was not set correctly, output: %s' % output | 38 | msg = 'The date was not set correctly, output: %s' % output |
38 | self.assertTrue(p, msg=msg) | 39 | self.assertTrue(int(output) - sampleTimestamp < 300, msg=msg) |
39 | 40 | ||
40 | (status, output) = self.target.run('date -s "%s"' % oldDate) | 41 | (status, output) = self.target.run('date -s "%s"' % oldDate) |
41 | msg = 'Failed to reset date, output: %s' % output | 42 | msg = 'Failed to reset date, output: %s' % output |
diff --git a/meta/lib/oeqa/runtime/cases/df.py b/meta/lib/oeqa/runtime/cases/df.py index bb155c9cf9..43e0ebf9ea 100644 --- a/meta/lib/oeqa/runtime/cases/df.py +++ b/meta/lib/oeqa/runtime/cases/df.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
diff --git a/meta/lib/oeqa/runtime/cases/dnf.py b/meta/lib/oeqa/runtime/cases/dnf.py index f40c63026e..3ccb18ce83 100644 --- a/meta/lib/oeqa/runtime/cases/dnf.py +++ b/meta/lib/oeqa/runtime/cases/dnf.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
@@ -73,48 +75,43 @@ class DnfRepoTest(DnfTest): | |||
73 | def test_dnf_makecache(self): | 75 | def test_dnf_makecache(self): |
74 | self.dnf_with_repo('makecache') | 76 | self.dnf_with_repo('makecache') |
75 | 77 | ||
76 | |||
77 | # Does not work when repo is specified on the command line | ||
78 | # @OETestDepends(['dnf.DnfRepoTest.test_dnf_makecache']) | ||
79 | # def test_dnf_repolist(self): | ||
80 | # self.dnf_with_repo('repolist') | ||
81 | |||
82 | @OETestDepends(['dnf.DnfRepoTest.test_dnf_makecache']) | 78 | @OETestDepends(['dnf.DnfRepoTest.test_dnf_makecache']) |
83 | def test_dnf_repoinfo(self): | 79 | def test_dnf_repoinfo(self): |
84 | self.dnf_with_repo('repoinfo') | 80 | self.dnf_with_repo('repoinfo') |
85 | 81 | ||
86 | @OETestDepends(['dnf.DnfRepoTest.test_dnf_makecache']) | 82 | @OETestDepends(['dnf.DnfRepoTest.test_dnf_makecache']) |
87 | def test_dnf_install(self): | 83 | def test_dnf_install(self): |
88 | output = self.dnf_with_repo('list run-postinsts-dev') | 84 | self.dnf_with_repo('remove -y dnf-test-*') |
89 | if 'Installed Packages' in output: | 85 | self.dnf_with_repo('install -y dnf-test-dep') |
90 | self.dnf_with_repo('remove -y run-postinsts-dev') | ||
91 | self.dnf_with_repo('install -y run-postinsts-dev') | ||
92 | 86 | ||
93 | @OETestDepends(['dnf.DnfRepoTest.test_dnf_install']) | 87 | @OETestDepends(['dnf.DnfRepoTest.test_dnf_install']) |
94 | def test_dnf_install_dependency(self): | 88 | def test_dnf_install_dependency(self): |
95 | self.dnf_with_repo('remove -y run-postinsts') | 89 | self.dnf_with_repo('remove -y dnf-test-*') |
96 | self.dnf_with_repo('install -y run-postinsts-dev') | 90 | self.dnf_with_repo('install -y dnf-test-main') |
91 | output = self.dnf('list --installed dnf-test-*') | ||
92 | self.assertIn("dnf-test-main.", output) | ||
93 | self.assertIn("dnf-test-dep.", output) | ||
97 | 94 | ||
98 | @OETestDepends(['dnf.DnfRepoTest.test_dnf_install_dependency']) | 95 | @OETestDepends(['dnf.DnfRepoTest.test_dnf_install_dependency']) |
99 | def test_dnf_install_from_disk(self): | 96 | def test_dnf_install_from_disk(self): |
100 | self.dnf_with_repo('remove -y run-postinsts-dev') | 97 | self.dnf_with_repo('remove -y dnf-test-dep') |
101 | self.dnf_with_repo('install -y --downloadonly run-postinsts-dev') | 98 | self.dnf_with_repo('install -y --downloadonly dnf-test-dep') |
102 | status, output = self.target.run('find /var/cache/dnf -name run-postinsts-dev*rpm', 1500) | 99 | status, output = self.target.run('find /var/cache/dnf -name dnf-test-dep*rpm') |
103 | self.assertEqual(status, 0, output) | 100 | self.assertEqual(status, 0, output) |
104 | self.dnf_with_repo('install -y %s' % output) | 101 | self.dnf_with_repo('install -y %s' % output) |
105 | 102 | ||
106 | @OETestDepends(['dnf.DnfRepoTest.test_dnf_install_from_disk']) | 103 | @OETestDepends(['dnf.DnfRepoTest.test_dnf_install_from_disk']) |
107 | def test_dnf_install_from_http(self): | 104 | def test_dnf_install_from_http(self): |
108 | output = subprocess.check_output('%s %s -name run-postinsts-dev*' % (bb.utils.which(os.getenv('PATH'), "find"), | 105 | output = subprocess.check_output('%s %s -name dnf-test-dep*' % (bb.utils.which(os.getenv('PATH'), "find"), |
109 | os.path.join(self.tc.td['WORKDIR'], 'oe-testimage-repo')), shell=True).decode("utf-8") | 106 | os.path.join(self.tc.td['WORKDIR'], 'oe-testimage-repo')), shell=True).decode("utf-8") |
110 | rpm_path = output.split("/")[-2] + "/" + output.split("/")[-1] | 107 | rpm_path = output.split("/")[-2] + "/" + output.split("/")[-1] |
111 | url = 'http://%s:%s/%s' %(self.target.server_ip, self.repo_server.port, rpm_path) | 108 | url = 'http://%s:%s/%s' %(self.target.server_ip, self.repo_server.port, rpm_path) |
112 | self.dnf_with_repo('remove -y run-postinsts-dev') | 109 | self.dnf_with_repo('remove -y dnf-test-dep') |
113 | self.dnf_with_repo('install -y %s' % url) | 110 | self.dnf_with_repo('install -y %s' % url) |
114 | 111 | ||
115 | @OETestDepends(['dnf.DnfRepoTest.test_dnf_install']) | 112 | @OETestDepends(['dnf.DnfRepoTest.test_dnf_install']) |
116 | def test_dnf_reinstall(self): | 113 | def test_dnf_reinstall(self): |
117 | self.dnf_with_repo('reinstall -y run-postinsts-dev') | 114 | self.dnf_with_repo('reinstall -y dnf-test-main') |
118 | 115 | ||
119 | @OETestDepends(['dnf.DnfRepoTest.test_dnf_makecache']) | 116 | @OETestDepends(['dnf.DnfRepoTest.test_dnf_makecache']) |
120 | @skipIfInDataVar('DISTRO_FEATURES', 'usrmerge', 'Test run when not enable usrmerge') | 117 | @skipIfInDataVar('DISTRO_FEATURES', 'usrmerge', 'Test run when not enable usrmerge') |
@@ -137,55 +134,40 @@ class DnfRepoTest(DnfTest): | |||
137 | self.target.run('cp -r /etc/dnf %s/etc' % rootpath, 1500) | 134 | self.target.run('cp -r /etc/dnf %s/etc' % rootpath, 1500) |
138 | self.target.run('cp /bin/sh %s/bin' % rootpath, 1500) | 135 | self.target.run('cp /bin/sh %s/bin' % rootpath, 1500) |
139 | self.target.run('mount -o bind /dev %s/dev/' % rootpath, 1500) | 136 | self.target.run('mount -o bind /dev %s/dev/' % rootpath, 1500) |
140 | self.dnf_with_repo('install --installroot=%s -v -y --rpmverbosity=debug busybox run-postinsts' % rootpath) | 137 | self.dnf_with_repo('install --installroot=%s -v -y --rpmverbosity=debug busybox' % rootpath) |
141 | status, output = self.target.run('test -e %s/var/cache/dnf' % rootpath, 1500) | 138 | status, output = self.target.run('test -e %s/var/cache/dnf' % rootpath, 1500) |
142 | self.assertEqual(0, status, output) | 139 | self.assertEqual(0, status, output) |
143 | status, output = self.target.run('test -e %s/bin/busybox' % rootpath, 1500) | 140 | status, output = self.target.run('test -e %s/bin/busybox' % rootpath, 1500) |
144 | self.assertEqual(0, status, output) | 141 | self.assertEqual(0, status, output) |
145 | 142 | ||
146 | @OETestDepends(['dnf.DnfRepoTest.test_dnf_makecache']) | 143 | @OETestDepends(['dnf.DnfRepoTest.test_dnf_makecache']) |
147 | @skipIfNotInDataVar('DISTRO_FEATURES', 'usrmerge', 'Test run when enable usrmege') | 144 | @skipIfNotInDataVar('DISTRO_FEATURES', 'usrmerge', 'Test run when enable usrmerge') |
148 | @OEHasPackage('busybox') | 145 | @OEHasPackage('busybox') |
149 | def test_dnf_installroot_usrmerge(self): | 146 | def test_dnf_installroot_usrmerge(self): |
150 | rootpath = '/home/root/chroot/test' | 147 | rootpath = '/home/root/chroot/test' |
151 | #Copy necessary files to avoid errors with not yet installed tools on | 148 | #Copy necessary files to avoid errors with not yet installed tools on |
152 | #installroot directory. | 149 | #installroot directory. |
153 | self.target.run('mkdir -p %s/etc' % rootpath, 1500) | 150 | self.target.run('mkdir -p %s/etc' % rootpath) |
154 | self.target.run('mkdir -p %s/usr/bin %s/usr/sbin' % (rootpath, rootpath), 1500) | 151 | self.target.run('mkdir -p %s/usr/bin %s/usr/sbin' % (rootpath, rootpath)) |
155 | self.target.run('ln -sf -r %s/usr/bin %s/bin' % (rootpath, rootpath), 1500) | 152 | self.target.run('ln -sf usr/bin %s/bin' % (rootpath)) |
156 | self.target.run('ln -sf -r %s/usr/sbin %s/sbin' % (rootpath, rootpath), 1500) | 153 | self.target.run('ln -sf usr/sbin %s/sbin' % (rootpath)) |
157 | self.target.run('mkdir -p %s/dev' % rootpath, 1500) | 154 | self.target.run('mkdir -p %s/dev' % rootpath) |
158 | #Handle different architectures lib dirs | 155 | #Handle different architectures lib dirs |
159 | self.target.run('mkdir -p %s/usr/lib' % rootpath, 1500) | 156 | self.target.run("for l in /lib*; do mkdir -p %s/usr/$l; ln -s usr/$l %s/$l; done" % (rootpath, rootpath)) |
160 | self.target.run('mkdir -p %s/usr/libx32' % rootpath, 1500) | 157 | self.target.run('cp -r /etc/rpm %s/etc' % rootpath) |
161 | self.target.run('mkdir -p %s/usr/lib64' % rootpath, 1500) | 158 | self.target.run('cp -r /etc/dnf %s/etc' % rootpath) |
162 | self.target.run('cp /lib/libtinfo.so.5 %s/usr/lib' % rootpath, 1500) | 159 | self.target.run('cp /bin/busybox %s/bin/sh' % rootpath) |
163 | self.target.run('cp /libx32/libtinfo.so.5 %s/usr/libx32' % rootpath, 1500) | 160 | self.target.run('mount -o bind /dev %s/dev/' % rootpath) |
164 | self.target.run('cp /lib64/libtinfo.so.5 %s/usr/lib64' % rootpath, 1500) | 161 | self.dnf_with_repo('install --installroot=%s -v -y --rpmverbosity=debug busybox' % rootpath) |
165 | self.target.run('ln -sf -r %s/lib %s/usr/lib' % (rootpath,rootpath), 1500) | 162 | status, output = self.target.run('test -e %s/var/cache/dnf' % rootpath) |
166 | self.target.run('ln -sf -r %s/libx32 %s/usr/libx32' % (rootpath,rootpath), 1500) | ||
167 | self.target.run('ln -sf -r %s/lib64 %s/usr/lib64' % (rootpath,rootpath), 1500) | ||
168 | self.target.run('cp -r /etc/rpm %s/etc' % rootpath, 1500) | ||
169 | self.target.run('cp -r /etc/dnf %s/etc' % rootpath, 1500) | ||
170 | self.target.run('cp /bin/sh %s/bin' % rootpath, 1500) | ||
171 | self.target.run('mount -o bind /dev %s/dev/' % rootpath, 1500) | ||
172 | self.dnf_with_repo('install --installroot=%s -v -y --rpmverbosity=debug busybox run-postinsts' % rootpath) | ||
173 | status, output = self.target.run('test -e %s/var/cache/dnf' % rootpath, 1500) | ||
174 | self.assertEqual(0, status, output) | 163 | self.assertEqual(0, status, output) |
175 | status, output = self.target.run('test -e %s/bin/busybox' % rootpath, 1500) | 164 | status, output = self.target.run('test -e %s/bin/busybox' % rootpath) |
176 | self.assertEqual(0, status, output) | 165 | self.assertEqual(0, status, output) |
177 | 166 | ||
178 | @OETestDepends(['dnf.DnfRepoTest.test_dnf_makecache']) | 167 | @OETestDepends(['dnf.DnfRepoTest.test_dnf_makecache']) |
179 | def test_dnf_exclude(self): | 168 | def test_dnf_exclude(self): |
180 | excludepkg = 'curl-dev' | 169 | self.dnf_with_repo('remove -y dnf-test-*') |
181 | self.dnf_with_repo('install -y curl*') | 170 | self.dnf_with_repo('install -y --exclude=dnf-test-dep dnf-test-*') |
182 | self.dnf('list %s' % excludepkg, 0) | 171 | output = self.dnf('list --installed dnf-test-*') |
183 | #Avoid remove dependencies to skip some errors on different archs and images | 172 | self.assertIn("dnf-test-main.", output) |
184 | self.dnf_with_repo('remove --setopt=clean_requirements_on_remove=0 -y curl*') | 173 | self.assertNotIn("dnf-test-dev.", output) |
185 | #check curl-dev is not installed adter removing all curl occurrences | ||
186 | status, output = self.target.run('dnf list --installed | grep %s'% excludepkg, 1500) | ||
187 | self.assertEqual(1, status, "%s was not removed, is listed as installed"%excludepkg) | ||
188 | self.dnf_with_repo('install -y --exclude=%s --exclude=curl-staticdev curl*' % excludepkg) | ||
189 | #check curl-dev is not installed after being excluded | ||
190 | status, output = self.target.run('dnf list --installed | grep %s'% excludepkg , 1500) | ||
191 | self.assertEqual(1, status, "%s was not excluded, is listed as installed"%excludepkg) | ||
diff --git a/meta/lib/oeqa/runtime/cases/ethernet_ip_connman.py b/meta/lib/oeqa/runtime/cases/ethernet_ip_connman.py index e010612838..eac8f2d082 100644 --- a/meta/lib/oeqa/runtime/cases/ethernet_ip_connman.py +++ b/meta/lib/oeqa/runtime/cases/ethernet_ip_connman.py | |||
@@ -1,3 +1,8 @@ | |||
1 | # | ||
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
4 | # SPDX-License-Identifier: MIT | ||
5 | # | ||
1 | from oeqa.runtime.case import OERuntimeTestCase | 6 | from oeqa.runtime.case import OERuntimeTestCase |
2 | from oeqa.core.decorator.depends import OETestDepends | 7 | from oeqa.core.decorator.depends import OETestDepends |
3 | from oeqa.core.decorator.data import skipIfQemu | 8 | from oeqa.core.decorator.data import skipIfQemu |
@@ -11,7 +16,7 @@ class Ethernet_Test(OERuntimeTestCase): | |||
11 | x = '.'.join(x) | 16 | x = '.'.join(x) |
12 | return x | 17 | return x |
13 | 18 | ||
14 | @skipIfQemu('qemuall', 'Test only runs on real hardware') | 19 | @skipIfQemu() |
15 | @OETestDepends(['ssh.SSHTest.test_ssh']) | 20 | @OETestDepends(['ssh.SSHTest.test_ssh']) |
16 | def test_set_virtual_ip(self): | 21 | def test_set_virtual_ip(self): |
17 | (status, output) = self.target.run("ifconfig eth0 | grep 'inet ' | awk '{print $2}'") | 22 | (status, output) = self.target.run("ifconfig eth0 | grep 'inet ' | awk '{print $2}'") |
@@ -22,6 +27,7 @@ class Ethernet_Test(OERuntimeTestCase): | |||
22 | (status, output) = self.target.run("ifconfig eth0:1 %s netmask 255.255.255.0 && sleep 2 && ping -c 5 %s && ifconfig eth0:1 down" % (virtual_ip,virtual_ip)) | 27 | (status, output) = self.target.run("ifconfig eth0:1 %s netmask 255.255.255.0 && sleep 2 && ping -c 5 %s && ifconfig eth0:1 down" % (virtual_ip,virtual_ip)) |
23 | self.assertEqual(status, 0, msg='Failed to create virtual ip address, output: %s' % output) | 28 | self.assertEqual(status, 0, msg='Failed to create virtual ip address, output: %s' % output) |
24 | 29 | ||
30 | @skipIfQemu() | ||
25 | @OETestDepends(['ethernet_ip_connman.Ethernet_Test.test_set_virtual_ip']) | 31 | @OETestDepends(['ethernet_ip_connman.Ethernet_Test.test_set_virtual_ip']) |
26 | def test_get_ip_from_dhcp(self): | 32 | def test_get_ip_from_dhcp(self): |
27 | (status, output) = self.target.run("connmanctl services | grep -E '*AO Wired|*AR Wired' | awk '{print $3}'") | 33 | (status, output) = self.target.run("connmanctl services | grep -E '*AO Wired|*AR Wired' | awk '{print $3}'") |
diff --git a/meta/lib/oeqa/runtime/cases/gcc.py b/meta/lib/oeqa/runtime/cases/gcc.py index 1b6e431bf4..17b1483e8d 100644 --- a/meta/lib/oeqa/runtime/cases/gcc.py +++ b/meta/lib/oeqa/runtime/cases/gcc.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
diff --git a/meta/lib/oeqa/runtime/cases/gi.py b/meta/lib/oeqa/runtime/cases/gi.py index 42bd100a31..78c7ddda2c 100644 --- a/meta/lib/oeqa/runtime/cases/gi.py +++ b/meta/lib/oeqa/runtime/cases/gi.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
diff --git a/meta/lib/oeqa/runtime/cases/go.py b/meta/lib/oeqa/runtime/cases/go.py new file mode 100644 index 0000000000..39a80f4dca --- /dev/null +++ b/meta/lib/oeqa/runtime/cases/go.py | |||
@@ -0,0 +1,21 @@ | |||
1 | # | ||
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
4 | # SPDX-License-Identifier: MIT | ||
5 | # | ||
6 | |||
7 | from oeqa.runtime.case import OERuntimeTestCase | ||
8 | from oeqa.core.decorator.depends import OETestDepends | ||
9 | from oeqa.runtime.decorator.package import OEHasPackage | ||
10 | |||
11 | class GoHelloworldTest(OERuntimeTestCase): | ||
12 | @OETestDepends(['ssh.SSHTest.test_ssh']) | ||
13 | @OEHasPackage(['go-helloworld']) | ||
14 | def test_gohelloworld(self): | ||
15 | cmd = "go-helloworld" | ||
16 | status, output = self.target.run(cmd) | ||
17 | msg = 'Exit status was not 0. Output: %s' % output | ||
18 | self.assertEqual(status, 0, msg=msg) | ||
19 | |||
20 | msg = 'Incorrect output: %s' % output | ||
21 | self.assertEqual(output, "Hello, world!", msg=msg) | ||
diff --git a/meta/lib/oeqa/runtime/cases/gstreamer.py b/meta/lib/oeqa/runtime/cases/gstreamer.py index f735f82e3b..2295769cfd 100644 --- a/meta/lib/oeqa/runtime/cases/gstreamer.py +++ b/meta/lib/oeqa/runtime/cases/gstreamer.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
diff --git a/meta/lib/oeqa/runtime/cases/kernelmodule.py b/meta/lib/oeqa/runtime/cases/kernelmodule.py index 47fd2f850c..9c42fcc586 100644 --- a/meta/lib/oeqa/runtime/cases/kernelmodule.py +++ b/meta/lib/oeqa/runtime/cases/kernelmodule.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
diff --git a/meta/lib/oeqa/runtime/cases/ksample.py b/meta/lib/oeqa/runtime/cases/ksample.py index a9a1620ebd..b6848762e3 100644 --- a/meta/lib/oeqa/runtime/cases/ksample.py +++ b/meta/lib/oeqa/runtime/cases/ksample.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
@@ -10,7 +12,7 @@ from oeqa.core.decorator.depends import OETestDepends | |||
10 | from oeqa.core.decorator.data import skipIfNotFeature | 12 | from oeqa.core.decorator.data import skipIfNotFeature |
11 | 13 | ||
12 | # need some kernel fragments | 14 | # need some kernel fragments |
13 | # echo "KERNEL_FEATURES_append += \" features\/kernel\-sample\/kernel\-sample.scc\"" >> local.conf | 15 | # echo "KERNEL_FEATURES:append = \" features\/kernel\-sample\/kernel\-sample.scc\"" >> local.conf |
14 | class KSample(OERuntimeTestCase): | 16 | class KSample(OERuntimeTestCase): |
15 | def cmd_and_check(self, cmd='', match_string=''): | 17 | def cmd_and_check(self, cmd='', match_string=''): |
16 | status, output = self.target.run(cmd) | 18 | status, output = self.target.run(cmd) |
diff --git a/meta/lib/oeqa/runtime/cases/ldd.py b/meta/lib/oeqa/runtime/cases/ldd.py index 9c2caa8f65..f6841c6675 100644 --- a/meta/lib/oeqa/runtime/cases/ldd.py +++ b/meta/lib/oeqa/runtime/cases/ldd.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
diff --git a/meta/lib/oeqa/runtime/cases/login.py b/meta/lib/oeqa/runtime/cases/login.py new file mode 100644 index 0000000000..e1bc60d49b --- /dev/null +++ b/meta/lib/oeqa/runtime/cases/login.py | |||
@@ -0,0 +1,116 @@ | |||
1 | # | ||
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
4 | # SPDX-License-Identifier: MIT | ||
5 | # | ||
6 | |||
7 | import shutil | ||
8 | import subprocess | ||
9 | import tempfile | ||
10 | import time | ||
11 | import os | ||
12 | from datetime import datetime | ||
13 | from oeqa.runtime.case import OERuntimeTestCase | ||
14 | from oeqa.runtime.decorator.package import OEHasPackage | ||
15 | |||
16 | ### Status of qemu images. | ||
17 | # - runqemu qemuppc64 comes up blank. (skip) | ||
18 | # - qemuarmv5 comes up with multiple heads but sending "head" to screendump. | ||
19 | # seems to create a png with a bad header? (skip for now, but come back to fix) | ||
20 | # - qemuriscv32 and qemuloongarch64 doesn't work with testimage apparently? (skip) | ||
21 | # - qemumips64 is missing mouse icon. | ||
22 | # - qemumips takes forever to render and is missing mouse icon. | ||
23 | # - qemuarm and qemuppc are odd as they don't resize so we need to just set width. | ||
24 | # - All images have home and screen flipper icons not always rendered fully at first. | ||
25 | # the sleep seems to help this out some, depending on machine load. | ||
26 | ### | ||
27 | |||
28 | class LoginTest(OERuntimeTestCase): | ||
29 | @OEHasPackage(['matchbox-desktop', 'dbus-wait']) | ||
30 | def test_screenshot(self): | ||
31 | if self.td.get('MACHINE') in ("qemuppc64", "qemuarmv5", "qemuriscv32", "qemuriscv64", "qemuloongarch64"): | ||
32 | self.skipTest("{0} is not currently supported.".format(self.td.get('MACHINE'))) | ||
33 | |||
34 | pn = self.td.get('PN') | ||
35 | |||
36 | ourenv = os.environ.copy() | ||
37 | origpath = self.td.get("ORIGPATH") | ||
38 | if origpath: | ||
39 | ourenv['PATH'] = ourenv['PATH'] + ":" + origpath | ||
40 | |||
41 | for cmd in ["identify.im7", "convert.im7", "compare.im7"]: | ||
42 | try: | ||
43 | subprocess.check_output(["which", cmd], env=ourenv) | ||
44 | except subprocess.CalledProcessError: | ||
45 | self.skipTest("%s (from imagemagick) not available" % cmd) | ||
46 | |||
47 | |||
48 | # Store images so we can debug them if needed | ||
49 | saved_screenshots_dir = self.td.get('T') + "/saved-screenshots/" | ||
50 | |||
51 | ### | ||
52 | # This is a really horrible way of doing this but I've not found the | ||
53 | # right event to determine "The system is loaded and screen is rendered" | ||
54 | # | ||
55 | # Using dbus-wait for matchbox is the wrong answer because while it | ||
56 | # ensures the system is up, it doesn't mean the screen is rendered. | ||
57 | # | ||
58 | # Checking the qmp socket doesn't work afaik either. | ||
59 | # | ||
60 | # One way to do this is to do compares of known good screendumps until | ||
61 | # we either get expected or close to expected or we time out. Part of the | ||
62 | # issue here with that is that there is a very fine difference in the | ||
63 | # diff between a screendump where the icons haven't loaded yet and | ||
64 | # one where they won't load. I'll look at that next, but, for now, this. | ||
65 | # | ||
66 | # Which is ugly and I hate it but it 'works' for various definitions of | ||
67 | # 'works'. | ||
68 | ### | ||
69 | # RP: if the signal is sent before we run this, it will never be seen and we'd timeout | ||
70 | #status, output = self.target.run('dbus-wait org.matchbox_project.desktop Loaded') | ||
71 | #if status != 0 or "Timeout" in output: | ||
72 | # self.fail('dbus-wait failed (%s, %s). This could mean that the image never loaded the matchbox desktop.' % (status, output)) | ||
73 | |||
74 | # Start taking screenshots every 2 seconds until diff=0 or timeout is 60 seconds | ||
75 | timeout = time.time() + 60 | ||
76 | diff = True | ||
77 | with tempfile.NamedTemporaryFile(prefix="oeqa-screenshot-login", suffix=".png") as t: | ||
78 | while diff != 0 and time.time() < timeout: | ||
79 | time.sleep(2) | ||
80 | ret = self.target.runner.run_monitor("screendump", args={"filename": t.name, "format":"png"}) | ||
81 | |||
82 | # Find out size of image so we can determine where to blank out clock. | ||
83 | # qemuarm and qemuppc are odd as it doesn't resize the window and returns | ||
84 | # incorrect widths | ||
85 | if self.td.get('MACHINE') == "qemuarm" or self.td.get('MACHINE') == "qemuppc": | ||
86 | width = "640" | ||
87 | else: | ||
88 | cmd = "identify.im7 -ping -format '%w' {0}".format(t.name) | ||
89 | width = subprocess.check_output(cmd, shell=True, env=ourenv).decode() | ||
90 | |||
91 | rblank = int(float(width)) | ||
92 | lblank = rblank-80 | ||
93 | |||
94 | # Use the meta-oe version of convert, along with it's suffix. This blanks out the clock. | ||
95 | cmd = "convert.im7 {0} -fill white -draw 'rectangle {1},4 {2},28' {3}".format(t.name, str(rblank), str(lblank), t.name) | ||
96 | convert_out=subprocess.check_output(cmd, shell=True, env=ourenv).decode() | ||
97 | |||
98 | bb.utils.mkdirhier(saved_screenshots_dir) | ||
99 | savedfile = "{0}/saved-{1}-{2}-{3}.png".format(saved_screenshots_dir, \ | ||
100 | datetime.timestamp(datetime.now()), \ | ||
101 | pn, \ | ||
102 | self.td.get('MACHINE')) | ||
103 | shutil.copy2(t.name, savedfile) | ||
104 | |||
105 | refimage = self.td.get('COREBASE') + "/meta/files/screenshot-tests/" + pn + "-" + self.td.get('MACHINE') +".png" | ||
106 | if not os.path.exists(refimage): | ||
107 | self.skipTest("No reference image for comparision (%s)" % refimage) | ||
108 | |||
109 | cmd = "compare.im7 -metric MSE {0} {1} /dev/null".format(t.name, refimage) | ||
110 | compare_out = subprocess.run(cmd, shell=True, capture_output=True, text=True, env=ourenv) | ||
111 | diff=float(compare_out.stderr.replace("(", "").replace(")","").split()[1]) | ||
112 | if diff > 0: | ||
113 | # Keep a copy of the failed screenshot so we can see what happened. | ||
114 | self.fail("Screenshot diff is {0}. Failed image stored in {1}".format(str(diff), savedfile)) | ||
115 | else: | ||
116 | self.assertEqual(0, diff, "Screenshot diff is {0}.".format(str(diff))) | ||
diff --git a/meta/lib/oeqa/runtime/cases/logrotate.py b/meta/lib/oeqa/runtime/cases/logrotate.py index a4efcd07c0..6ad980cb6a 100644 --- a/meta/lib/oeqa/runtime/cases/logrotate.py +++ b/meta/lib/oeqa/runtime/cases/logrotate.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
@@ -17,7 +19,7 @@ class LogrotateTest(OERuntimeTestCase): | |||
17 | 19 | ||
18 | @classmethod | 20 | @classmethod |
19 | def tearDownClass(cls): | 21 | def tearDownClass(cls): |
20 | cls.tc.target.run('mv -f $HOME/wtmp.oeqabak /etc/logrotate.d/wtmp && rm -rf $HOME/logrotate_dir') | 22 | cls.tc.target.run('mv -f $HOME/wtmp.oeqabak /etc/logrotate.d/wtmp && rm -rf /var/log//logrotate_dir') |
21 | cls.tc.target.run('rm -rf /var/log/logrotate_testfile && rm -rf /etc/logrotate.d/logrotate_testfile') | 23 | cls.tc.target.run('rm -rf /var/log/logrotate_testfile && rm -rf /etc/logrotate.d/logrotate_testfile') |
22 | 24 | ||
23 | @OETestDepends(['ssh.SSHTest.test_ssh']) | 25 | @OETestDepends(['ssh.SSHTest.test_ssh']) |
@@ -29,17 +31,17 @@ class LogrotateTest(OERuntimeTestCase): | |||
29 | msg = ('Could not create/update /var/log/wtmp with touch') | 31 | msg = ('Could not create/update /var/log/wtmp with touch') |
30 | self.assertEqual(status, 0, msg = msg) | 32 | self.assertEqual(status, 0, msg = msg) |
31 | 33 | ||
32 | status, output = self.target.run('mkdir $HOME/logrotate_dir') | 34 | status, output = self.target.run('mkdir /var/log//logrotate_dir') |
33 | msg = ('Could not create logrotate_dir. Output: %s' % output) | 35 | msg = ('Could not create logrotate_dir. Output: %s' % output) |
34 | self.assertEqual(status, 0, msg = msg) | 36 | self.assertEqual(status, 0, msg = msg) |
35 | 37 | ||
36 | status, output = self.target.run('echo "create \n olddir $HOME/logrotate_dir \n include /etc/logrotate.d/wtmp" > /tmp/logrotate-test.conf') | 38 | status, output = self.target.run('echo "create \n olddir /var/log//logrotate_dir \n include /etc/logrotate.d/wtmp" > /tmp/logrotate-test.conf') |
37 | msg = ('Could not write to /tmp/logrotate-test.conf') | 39 | msg = ('Could not write to /tmp/logrotate-test.conf') |
38 | self.assertEqual(status, 0, msg = msg) | 40 | self.assertEqual(status, 0, msg = msg) |
39 | 41 | ||
40 | # If logrotate fails to rotate the log, view the verbose output of logrotate to see what prevented it | 42 | # If logrotate fails to rotate the log, view the verbose output of logrotate to see what prevented it |
41 | _, logrotate_output = self.target.run('logrotate -vf /tmp/logrotate-test.conf') | 43 | _, logrotate_output = self.target.run('logrotate -vf /tmp/logrotate-test.conf') |
42 | status, _ = self.target.run('find $HOME/logrotate_dir -type f | grep wtmp.1') | 44 | status, _ = self.target.run('find /var/log//logrotate_dir -type f | grep wtmp.1') |
43 | msg = ("logrotate did not successfully rotate the wtmp log. Output from logrotate -vf: \n%s" % (logrotate_output)) | 45 | msg = ("logrotate did not successfully rotate the wtmp log. Output from logrotate -vf: \n%s" % (logrotate_output)) |
44 | self.assertEqual(status, 0, msg = msg) | 46 | self.assertEqual(status, 0, msg = msg) |
45 | 47 | ||
@@ -54,17 +56,17 @@ class LogrotateTest(OERuntimeTestCase): | |||
54 | msg = ('Could not write to /etc/logrotate.d/logrotate_testfile') | 56 | msg = ('Could not write to /etc/logrotate.d/logrotate_testfile') |
55 | self.assertEqual(status, 0, msg = msg) | 57 | self.assertEqual(status, 0, msg = msg) |
56 | 58 | ||
57 | status, output = self.target.run('echo "create \n olddir $HOME/logrotate_dir \n include /etc/logrotate.d/logrotate_testfile" > /tmp/logrotate-test2.conf') | 59 | status, output = self.target.run('echo "create \n olddir /var/log//logrotate_dir \n include /etc/logrotate.d/logrotate_testfile" > /tmp/logrotate-test2.conf') |
58 | msg = ('Could not write to /tmp/logrotate_test2.conf') | 60 | msg = ('Could not write to /tmp/logrotate_test2.conf') |
59 | self.assertEqual(status, 0, msg = msg) | 61 | self.assertEqual(status, 0, msg = msg) |
60 | 62 | ||
61 | status, output = self.target.run('find $HOME/logrotate_dir -type f | grep logrotate_testfile.1') | 63 | status, output = self.target.run('find /var/log//logrotate_dir -type f | grep logrotate_testfile.1') |
62 | msg = ('A rotated log for logrotate_testfile is already present in logrotate_dir') | 64 | msg = ('A rotated log for logrotate_testfile is already present in logrotate_dir') |
63 | self.assertEqual(status, 1, msg = msg) | 65 | self.assertEqual(status, 1, msg = msg) |
64 | 66 | ||
65 | # If logrotate fails to rotate the log, view the verbose output of logrotate instead of just listing the files in olddir | 67 | # If logrotate fails to rotate the log, view the verbose output of logrotate instead of just listing the files in olddir |
66 | _, logrotate_output = self.target.run('logrotate -vf /tmp/logrotate-test2.conf') | 68 | _, logrotate_output = self.target.run('logrotate -vf /tmp/logrotate-test2.conf') |
67 | status, _ = self.target.run('find $HOME/logrotate_dir -type f | grep logrotate_testfile.1') | 69 | status, _ = self.target.run('find /var/log//logrotate_dir -type f | grep logrotate_testfile.1') |
68 | msg = ('logrotate did not successfully rotate the logrotate_test log. Output from logrotate -vf: \n%s' % (logrotate_output)) | 70 | msg = ('logrotate did not successfully rotate the logrotate_test log. Output from logrotate -vf: \n%s' % (logrotate_output)) |
69 | self.assertEqual(status, 0, msg = msg) | 71 | self.assertEqual(status, 0, msg = msg) |
70 | 72 | ||
diff --git a/meta/lib/oeqa/runtime/cases/ltp.py b/meta/lib/oeqa/runtime/cases/ltp.py index a66d5d13d7..f588a93200 100644 --- a/meta/lib/oeqa/runtime/cases/ltp.py +++ b/meta/lib/oeqa/runtime/cases/ltp.py | |||
@@ -57,37 +57,47 @@ class LtpTestBase(OERuntimeTestCase): | |||
57 | 57 | ||
58 | class LtpTest(LtpTestBase): | 58 | class LtpTest(LtpTestBase): |
59 | 59 | ||
60 | ltp_groups = ["math", "syscalls", "dio", "io", "mm", "ipc", "sched", "nptl", "pty", "containers", "controllers", "filecaps", "cap_bounds", "fcntl-locktests", "connectors", "commands", "net.ipv6_lib", "input","fs_perms_simple"] | 60 | ltp_groups = ["math", "syscalls", "dio", "io", "mm", "ipc", "sched", "nptl", "pty", "containers", "controllers", "filecaps", "cap_bounds", "fcntl-locktests", "commands", "net.ipv6_lib", "input","fs_perms_simple", "cve", "crypto", "ima", "net.nfs", "net_stress.ipsec_icmp", "net.ipv6", "numa", "uevent", "ltp-aiodio.part1", "ltp-aiodio.part2", "ltp-aiodio.part3", "ltp-aiodio.part4"] |
61 | 61 | ||
62 | ltp_fs = ["fs", "fsx", "fs_bind"] | 62 | ltp_fs = ["fs", "fs_bind"] |
63 | # skip kernel cpuhotplug | 63 | # skip kernel cpuhotplug |
64 | ltp_kernel = ["power_management_tests", "hyperthreading ", "kernel_misc", "hugetlb"] | 64 | ltp_kernel = ["power_management_tests", "hyperthreading ", "kernel_misc", "hugetlb"] |
65 | ltp_groups += ltp_fs | 65 | ltp_groups += ltp_fs |
66 | 66 | ||
67 | def runltp(self, ltp_group): | 67 | def runltp(self, ltp_group): |
68 | cmd = '/opt/ltp/runltp -f %s -p -q -r /opt/ltp -l /opt/ltp/results/%s -I 1 -d /opt/ltp' % (ltp_group, ltp_group) | 68 | # LTP appends to log files, so ensure we start with a clean log |
69 | self.target.deleteFiles("/opt/ltp/results/", ltp_group) | ||
70 | |||
71 | cmd = '/opt/ltp/runltp -f %s -q -r /opt/ltp -l /opt/ltp/results/%s -I 1 -d /opt/ltp' % (ltp_group, ltp_group) | ||
72 | |||
69 | starttime = time.time() | 73 | starttime = time.time() |
70 | (status, output) = self.target.run(cmd) | 74 | (status, output) = self.target.run(cmd, timeout=1200) |
71 | endtime = time.time() | 75 | endtime = time.time() |
72 | 76 | ||
77 | # status of 1 is 'just' tests failing. 255 likely was a command output timeout | ||
78 | if status and status != 1: | ||
79 | msg = 'Command %s returned exit code %s' % (cmd, status) | ||
80 | self.target.logger.warning(msg) | ||
81 | |||
82 | # Write the console log to disk for convenience | ||
73 | with open(os.path.join(self.ltptest_log_dir, "%s-raw.log" % ltp_group), 'w') as f: | 83 | with open(os.path.join(self.ltptest_log_dir, "%s-raw.log" % ltp_group), 'w') as f: |
74 | f.write(output) | 84 | f.write(output) |
75 | 85 | ||
86 | # Also put the console log into the test result JSON | ||
76 | self.extras['ltpresult.rawlogs']['log'] = self.extras['ltpresult.rawlogs']['log'] + output | 87 | self.extras['ltpresult.rawlogs']['log'] = self.extras['ltpresult.rawlogs']['log'] + output |
77 | 88 | ||
78 | # copy nice log from DUT | 89 | # Copy the machine-readable test results locally so we can parse it |
79 | dst = os.path.join(self.ltptest_log_dir, "%s" % ltp_group ) | 90 | dst = os.path.join(self.ltptest_log_dir, ltp_group) |
80 | remote_src = "/opt/ltp/results/%s" % ltp_group | 91 | remote_src = "/opt/ltp/results/%s" % ltp_group |
81 | (status, output) = self.target.copyFrom(remote_src, dst, True) | 92 | (status, output) = self.target.copyFrom(remote_src, dst, True) |
82 | msg = 'File could not be copied. Output: %s' % output | ||
83 | if status: | 93 | if status: |
94 | msg = 'File could not be copied. Output: %s' % output | ||
84 | self.target.logger.warning(msg) | 95 | self.target.logger.warning(msg) |
85 | 96 | ||
86 | parser = LtpParser() | 97 | parser = LtpParser() |
87 | results, sections = parser.parse(dst) | 98 | results, sections = parser.parse(dst) |
88 | 99 | ||
89 | runtime = int(endtime-starttime) | 100 | sections['duration'] = int(endtime-starttime) |
90 | sections['duration'] = runtime | ||
91 | self.sections[ltp_group] = sections | 101 | self.sections[ltp_group] = sections |
92 | 102 | ||
93 | failed_tests = {} | 103 | failed_tests = {} |
diff --git a/meta/lib/oeqa/runtime/cases/ltp_stress.py b/meta/lib/oeqa/runtime/cases/ltp_stress.py index 2445ffbc93..ce6f4bf59d 100644 --- a/meta/lib/oeqa/runtime/cases/ltp_stress.py +++ b/meta/lib/oeqa/runtime/cases/ltp_stress.py | |||
@@ -89,8 +89,7 @@ class LtpStressTest(LtpStressBase): | |||
89 | 89 | ||
90 | # LTP stress runtime tests | 90 | # LTP stress runtime tests |
91 | # | 91 | # |
92 | @skipIfQemu('qemuall', 'Test only runs on real hardware') | 92 | @skipIfQemu() |
93 | |||
94 | @OETestDepends(['ssh.SSHTest.test_ssh']) | 93 | @OETestDepends(['ssh.SSHTest.test_ssh']) |
95 | @OEHasPackage(["ltp"]) | 94 | @OEHasPackage(["ltp"]) |
96 | def test_ltp_stress(self): | 95 | def test_ltp_stress(self): |
diff --git a/meta/lib/oeqa/runtime/cases/maturin.py b/meta/lib/oeqa/runtime/cases/maturin.py new file mode 100644 index 0000000000..4e6384fe5e --- /dev/null +++ b/meta/lib/oeqa/runtime/cases/maturin.py | |||
@@ -0,0 +1,58 @@ | |||
1 | # | ||
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
4 | # SPDX-License-Identifier: MIT | ||
5 | # | ||
6 | |||
7 | import os | ||
8 | |||
9 | from oeqa.runtime.case import OERuntimeTestCase | ||
10 | from oeqa.core.decorator.depends import OETestDepends | ||
11 | from oeqa.runtime.decorator.package import OEHasPackage | ||
12 | |||
13 | |||
14 | class MaturinTest(OERuntimeTestCase): | ||
15 | @OETestDepends(['ssh.SSHTest.test_ssh', 'python.PythonTest.test_python3']) | ||
16 | @OEHasPackage(['python3-maturin']) | ||
17 | def test_maturin_list_python(self): | ||
18 | status, output = self.target.run("maturin list-python") | ||
19 | self.assertEqual(status, 0) | ||
20 | _, py_major = self.target.run("python3 -c 'import sys; print(sys.version_info.major)'") | ||
21 | _, py_minor = self.target.run("python3 -c 'import sys; print(sys.version_info.minor)'") | ||
22 | python_version = "%s.%s" % (py_major, py_minor) | ||
23 | self.assertEqual(output, "🐍 1 python interpreter found:\n" | ||
24 | " - CPython %s at /usr/bin/python%s" % (python_version, python_version)) | ||
25 | |||
26 | |||
27 | class MaturinDevelopTest(OERuntimeTestCase): | ||
28 | @classmethod | ||
29 | def setUp(cls): | ||
30 | dst = '/tmp' | ||
31 | src = os.path.join(cls.tc.files_dir, "maturin/guessing-game") | ||
32 | cls.tc.target.copyTo(src, dst) | ||
33 | |||
34 | @classmethod | ||
35 | def tearDown(cls): | ||
36 | cls.tc.target.run('rm -rf %s' % '/tmp/guessing-game/target') | ||
37 | |||
38 | @OETestDepends(['ssh.SSHTest.test_ssh', 'python.PythonTest.test_python3']) | ||
39 | @OEHasPackage(['python3-maturin']) | ||
40 | def test_maturin_develop(self): | ||
41 | """ | ||
42 | This test case requires: | ||
43 | (1) that a .venv can been created. | ||
44 | (2) DNS nameserver to resolve crate URIs for fetching | ||
45 | (3) a functional 'rustc' and 'cargo' | ||
46 | """ | ||
47 | targetdir = os.path.join("/tmp", "guessing-game") | ||
48 | self.target.run("cd %s; python3 -m venv .venv" % targetdir) | ||
49 | self.target.run("echo 'nameserver 8.8.8.8' > /etc/resolv.conf") | ||
50 | cmd = "cd %s; maturin develop" % targetdir | ||
51 | status, output = self.target.run(cmd) | ||
52 | self.assertRegex(output, r"🔗 Found pyo3 bindings with abi3 support for Python ≥ 3.8") | ||
53 | self.assertRegex(output, r"🐍 Not using a specific python interpreter") | ||
54 | self.assertRegex(output, r"📡 Using build options features from pyproject.toml") | ||
55 | self.assertRegex(output, r"Compiling guessing-game v0.1.0") | ||
56 | self.assertRegex(output, r"📦 Built wheel for abi3 Python ≥ 3.8") | ||
57 | self.assertRegex(output, r"🛠 Installed guessing-game-0.1.0") | ||
58 | self.assertEqual(status, 0) | ||
diff --git a/meta/lib/oeqa/runtime/cases/multilib.py b/meta/lib/oeqa/runtime/cases/multilib.py index 0d1b9ae2c9..68556e45c5 100644 --- a/meta/lib/oeqa/runtime/cases/multilib.py +++ b/meta/lib/oeqa/runtime/cases/multilib.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
diff --git a/meta/lib/oeqa/runtime/cases/oe_syslog.py b/meta/lib/oeqa/runtime/cases/oe_syslog.py index f3c2bedbaf..adb876160d 100644 --- a/meta/lib/oeqa/runtime/cases/oe_syslog.py +++ b/meta/lib/oeqa/runtime/cases/oe_syslog.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
@@ -114,18 +116,23 @@ class SyslogTestConfig(OERuntimeTestCase): | |||
114 | @OETestDepends(['oe_syslog.SyslogTestConfig.test_syslog_logger']) | 116 | @OETestDepends(['oe_syslog.SyslogTestConfig.test_syslog_logger']) |
115 | @OEHasPackage(["busybox-syslog"]) | 117 | @OEHasPackage(["busybox-syslog"]) |
116 | @skipIfDataVar('VIRTUAL-RUNTIME_init_manager', 'systemd', | 118 | @skipIfDataVar('VIRTUAL-RUNTIME_init_manager', 'systemd', |
117 | 'Not appropiate for systemd image') | 119 | 'Not appropriate for systemd image') |
118 | def test_syslog_startup_config(self): | 120 | def test_syslog_startup_config(self): |
119 | cmd = 'echo "LOGFILE=/var/log/test" >> /etc/syslog-startup.conf' | 121 | cmd = 'echo "LOGFILE=/var/log/test" >> /etc/syslog-startup.conf' |
120 | self.target.run(cmd) | 122 | self.target.run(cmd) |
121 | 123 | ||
122 | self.test_syslog_restart() | 124 | self.test_syslog_restart() |
123 | 125 | ||
124 | cmd = 'logger foobar && grep foobar /var/log/test' | 126 | cmd = 'logger foobar' |
125 | status,output = self.target.run(cmd) | 127 | status, output = self.target.run(cmd) |
126 | msg = 'Test log string not found. Output: %s ' % output | 128 | msg = 'Logger command failed, %s. Output: %s ' % (status, output) |
127 | self.assertEqual(status, 0, msg=msg) | 129 | self.assertEqual(status, 0, msg=msg) |
128 | 130 | ||
131 | cmd = 'cat /var/log/test' | ||
132 | status, output = self.target.run(cmd) | ||
133 | if "foobar" not in output or status: | ||
134 | self.fail("'foobar' not found in logfile, status %s, contents %s" % (status, output)) | ||
135 | |||
129 | cmd = "sed -i 's#LOGFILE=/var/log/test##' /etc/syslog-startup.conf" | 136 | cmd = "sed -i 's#LOGFILE=/var/log/test##' /etc/syslog-startup.conf" |
130 | self.target.run(cmd) | 137 | self.target.run(cmd) |
131 | self.test_syslog_restart() | 138 | self.test_syslog_restart() |
diff --git a/meta/lib/oeqa/runtime/cases/opkg.py b/meta/lib/oeqa/runtime/cases/opkg.py index 9cfee1cd88..a29c93e59a 100644 --- a/meta/lib/oeqa/runtime/cases/opkg.py +++ b/meta/lib/oeqa/runtime/cases/opkg.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
diff --git a/meta/lib/oeqa/runtime/cases/pam.py b/meta/lib/oeqa/runtime/cases/pam.py index a482ded945..b3e8b56c3c 100644 --- a/meta/lib/oeqa/runtime/cases/pam.py +++ b/meta/lib/oeqa/runtime/cases/pam.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
diff --git a/meta/lib/oeqa/runtime/cases/parselogs-ignores-common.txt b/meta/lib/oeqa/runtime/cases/parselogs-ignores-common.txt new file mode 100644 index 0000000000..f91abbc941 --- /dev/null +++ b/meta/lib/oeqa/runtime/cases/parselogs-ignores-common.txt | |||
@@ -0,0 +1,62 @@ | |||
1 | # Xserver explains what the short codes mean | ||
2 | (WW) warning, (EE) error, (NI) not implemented, (??) unknown. | ||
3 | |||
4 | # Xserver warns if compiled with ACPI but no acpid running | ||
5 | Open ACPI failed (/var/run/acpid.socket) (No such file or directory) | ||
6 | |||
7 | # Some machines (eg qemux86) don't enable PAE (they probably should though) | ||
8 | NX (Execute Disable) protection cannot be enabled: non-PAE kernel! | ||
9 | |||
10 | # Connman's pacrunner warns if external connectivity isn't available | ||
11 | Failed to find URL:http://ipv4.connman.net/online/status.html | ||
12 | Failed to find URL:http://ipv6.connman.net/online/status.html | ||
13 | |||
14 | # x86 on 6.6+ outputs this message, it is informational, not an error | ||
15 | ACPI: _OSC evaluation for CPUs failed, trying _PDC | ||
16 | |||
17 | # These should be reviewed to see if they are still needed | ||
18 | dma timeout | ||
19 | can\'t add hid device: | ||
20 | usbhid: probe of | ||
21 | _OSC failed (AE_ERROR) | ||
22 | _OSC failed (AE_SUPPORT) | ||
23 | AE_ALREADY_EXISTS | ||
24 | ACPI _OSC request failed (AE_SUPPORT) | ||
25 | can\'t disable ASPM | ||
26 | Failed to load module "vesa" | ||
27 | Failed to load module "modesetting" | ||
28 | Failed to load module "glx" | ||
29 | Failed to load module "fbdev" | ||
30 | Failed to load module "ati" | ||
31 | [drm] Cannot find any crtc or sizes | ||
32 | _OSC failed (AE_NOT_FOUND); disabling ASPM | ||
33 | hd.: possibly failed opcode | ||
34 | NETLINK INITIALIZATION FAILED | ||
35 | kernel: Cannot find map file | ||
36 | omap_hwmod: debugss: _wait_target_disable failed | ||
37 | VGA arbiter: cannot open kernel arbiter, no multi-card support | ||
38 | Online check failed for | ||
39 | netlink init failed | ||
40 | Fast TSC calibration | ||
41 | controller can't do DEVSLP, turning off | ||
42 | stmmac_dvr_probe: warning: cannot get CSR clock | ||
43 | error: couldn\'t mount because of unsupported optional features | ||
44 | GPT: Use GNU Parted to correct GPT errors | ||
45 | Cannot set xattr user.Librepo.DownloadInProgress | ||
46 | Failed to read /var/lib/nfs/statd/state: Success | ||
47 | error retry time-out = | ||
48 | logind: cannot setup systemd-logind helper (-61), using legacy fallback | ||
49 | Failed to rename network interface | ||
50 | Failed to process device, ignoring: Device or resource busy | ||
51 | Cannot find a map file | ||
52 | [rdrand]: Initialization Failed | ||
53 | [rndr ]: Initialization Failed | ||
54 | [pulseaudio] authkey.c: Failed to open cookie file | ||
55 | [pulseaudio] authkey.c: Failed to load authentication key | ||
56 | was skipped because of a failed condition check | ||
57 | was skipped because all trigger condition checks failed | ||
58 | xf86OpenConsole: Switching VT failed | ||
59 | Failed to read LoaderConfigTimeoutOneShot variable, ignoring: Operation not supported | ||
60 | Failed to read LoaderEntryOneShot variable, ignoring: Operation not supported | ||
61 | Direct firmware load for regulatory.db | ||
62 | failed to load regulatory.db | ||
diff --git a/meta/lib/oeqa/runtime/cases/parselogs-ignores-mipsarch.txt b/meta/lib/oeqa/runtime/cases/parselogs-ignores-mipsarch.txt new file mode 100644 index 0000000000..2c0bd9a247 --- /dev/null +++ b/meta/lib/oeqa/runtime/cases/parselogs-ignores-mipsarch.txt | |||
@@ -0,0 +1,2 @@ | |||
1 | # These should be reviewed to see if they are still needed | ||
2 | cacheinfo: Failed to find cpu0 device node | ||
diff --git a/meta/lib/oeqa/runtime/cases/parselogs-ignores-qemuall.txt b/meta/lib/oeqa/runtime/cases/parselogs-ignores-qemuall.txt new file mode 100644 index 0000000000..b0c0fc9ddf --- /dev/null +++ b/meta/lib/oeqa/runtime/cases/parselogs-ignores-qemuall.txt | |||
@@ -0,0 +1,27 @@ | |||
1 | # psplash | ||
2 | FBIOPUT_VSCREENINFO failed, double buffering disabled | ||
3 | |||
4 | # PCI host bridge to bus 0000:00 | ||
5 | # pci_bus 0000:00: root bus resource [mem 0x10000000-0x17ffffff] | ||
6 | # pci_bus 0000:00: root bus resource [io 0x1000-0x1fffff] | ||
7 | # pci_bus 0000:00: No busn resource found for root bus, will use [bus 00-ff] | ||
8 | # pci 0000:00:00.0: [2046:ab11] type 00 class 0x100000 | ||
9 | # pci 0000:00:00.0: [Firmware Bug]: reg 0x10: invalid BAR (can't size) | ||
10 | # pci 0000:00:00.0: [Firmware Bug]: reg 0x14: invalid BAR (can't size) | ||
11 | # pci 0000:00:00.0: [Firmware Bug]: reg 0x18: invalid BAR (can't size) | ||
12 | # pci 0000:00:00.0: [Firmware Bug]: reg 0x1c: invalid BAR (can't size) | ||
13 | # pci 0000:00:00.0: [Firmware Bug]: reg 0x20: invalid BAR (can't size) | ||
14 | # pci 0000:00:00.0: [Firmware Bug]: reg 0x24: invalid BAR (can't size) | ||
15 | invalid BAR (can't size) | ||
16 | |||
17 | # These should be reviewed to see if they are still needed | ||
18 | wrong ELF class | ||
19 | fail to add MMCONFIG information, can't access extended PCI configuration space under this bridge | ||
20 | can't claim BAR | ||
21 | amd_nb: Cannot enumerate AMD northbridges | ||
22 | tsc: HPET/PMTIMER calibration failed | ||
23 | modeset(0): Failed to initialize the DRI2 extension | ||
24 | glamor initialization failed | ||
25 | blk_update_request: I/O error, dev fd0, sector 0 op 0x0:(READ) | ||
26 | floppy: error | ||
27 | failed to IDENTIFY (I/O error, err_mask=0x4) | ||
diff --git a/meta/lib/oeqa/runtime/cases/parselogs-ignores-qemuarm64.txt b/meta/lib/oeqa/runtime/cases/parselogs-ignores-qemuarm64.txt new file mode 100644 index 0000000000..260cdde620 --- /dev/null +++ b/meta/lib/oeqa/runtime/cases/parselogs-ignores-qemuarm64.txt | |||
@@ -0,0 +1,6 @@ | |||
1 | # These should be reviewed to see if they are still needed | ||
2 | Fatal server error: | ||
3 | (EE) Server terminated with error (1). Closing log file. | ||
4 | dmi: Firmware registration failed. | ||
5 | irq: type mismatch, failed to map hwirq-27 for /intc | ||
6 | logind: failed to get session seat \ No newline at end of file | ||
diff --git a/meta/lib/oeqa/runtime/cases/parselogs-ignores-qemuarmv5.txt b/meta/lib/oeqa/runtime/cases/parselogs-ignores-qemuarmv5.txt new file mode 100644 index 0000000000..ed91107b7d --- /dev/null +++ b/meta/lib/oeqa/runtime/cases/parselogs-ignores-qemuarmv5.txt | |||
@@ -0,0 +1,19 @@ | |||
1 | # Code is 2 JENT_ECOARSETIME: Timer too coarse for RNG. | ||
2 | jitterentropy: Initialization failed with host not compliant with requirements: 2 | ||
3 | |||
4 | # These should be reviewed to see if they are still needed | ||
5 | mmci-pl18x: probe of fpga:05 failed with error -22 | ||
6 | mmci-pl18x: probe of fpga:0b failed with error -22 | ||
7 | |||
8 | OF: amba_device_add() failed (-19) for /amba/smc@10100000 | ||
9 | OF: amba_device_add() failed (-19) for /amba/mpmc@10110000 | ||
10 | OF: amba_device_add() failed (-19) for /amba/sctl@101e0000 | ||
11 | OF: amba_device_add() failed (-19) for /amba/watchdog@101e1000 | ||
12 | OF: amba_device_add() failed (-19) for /amba/sci@101f0000 | ||
13 | OF: amba_device_add() failed (-19) for /amba/spi@101f4000 | ||
14 | OF: amba_device_add() failed (-19) for /amba/ssp@101f4000 | ||
15 | OF: amba_device_add() failed (-19) for /amba/fpga/sci@a000 | ||
16 | Failed to initialize '/amba/timer@101e3000': -22 | ||
17 | |||
18 | clcd-pl11x: probe of 10120000.display failed with error -2 | ||
19 | arm-charlcd 10008000.lcd: error -ENXIO: IRQ index 0 not found | ||
diff --git a/meta/lib/oeqa/runtime/cases/parselogs-ignores-qemuppc.txt b/meta/lib/oeqa/runtime/cases/parselogs-ignores-qemuppc.txt new file mode 100644 index 0000000000..d9b58b58f1 --- /dev/null +++ b/meta/lib/oeqa/runtime/cases/parselogs-ignores-qemuppc.txt | |||
@@ -0,0 +1,6 @@ | |||
1 | # These should be reviewed to see if they are still needed | ||
2 | PCI 0000:00 Cannot reserve Legacy IO [io 0x0000-0x0fff] | ||
3 | host side 80-wire cable detection failed, limiting max speed | ||
4 | mode "640x480" test failed | ||
5 | can't handle BAR above 4GB | ||
6 | Cannot reserve Legacy IO \ No newline at end of file | ||
diff --git a/meta/lib/oeqa/runtime/cases/parselogs-ignores-qemuppc64.txt b/meta/lib/oeqa/runtime/cases/parselogs-ignores-qemuppc64.txt new file mode 100644 index 0000000000..b736a2aeb7 --- /dev/null +++ b/meta/lib/oeqa/runtime/cases/parselogs-ignores-qemuppc64.txt | |||
@@ -0,0 +1,4 @@ | |||
1 | # These should be reviewed to see if they are still needed | ||
2 | vio vio: uevent: failed to send synthetic uevent | ||
3 | synth uevent: /devices/vio: failed to send uevent | ||
4 | PCI 0000:00 Cannot reserve Legacy IO [io 0x10000-0x10fff] \ No newline at end of file | ||
diff --git a/meta/lib/oeqa/runtime/cases/parselogs-ignores-qemux86.txt b/meta/lib/oeqa/runtime/cases/parselogs-ignores-qemux86.txt new file mode 100644 index 0000000000..ebb76f1221 --- /dev/null +++ b/meta/lib/oeqa/runtime/cases/parselogs-ignores-qemux86.txt | |||
@@ -0,0 +1,2 @@ | |||
1 | # These should be reviewed to see if they are still needed | ||
2 | Failed to access perfctr msr (MSR | ||
diff --git a/meta/lib/oeqa/runtime/cases/parselogs-ignores-x86.txt b/meta/lib/oeqa/runtime/cases/parselogs-ignores-x86.txt new file mode 100644 index 0000000000..5985247daf --- /dev/null +++ b/meta/lib/oeqa/runtime/cases/parselogs-ignores-x86.txt | |||
@@ -0,0 +1,10 @@ | |||
1 | # These should be reviewed to see if they are still needed | ||
2 | [drm:psb_do_init] *ERROR* Debug is | ||
3 | wrong ELF class | ||
4 | Could not enable PowerButton event | ||
5 | probe of LNXPWRBN:00 failed with error -22 | ||
6 | pmd_set_huge: Cannot satisfy | ||
7 | failed to setup card detect gpio | ||
8 | amd_nb: Cannot enumerate AMD northbridges | ||
9 | failed to retrieve link info, disabling eDP | ||
10 | Direct firmware load for iwlwifi | ||
diff --git a/meta/lib/oeqa/runtime/cases/parselogs-ignores-x86_64.txt b/meta/lib/oeqa/runtime/cases/parselogs-ignores-x86_64.txt new file mode 120000 index 0000000000..404e384c32 --- /dev/null +++ b/meta/lib/oeqa/runtime/cases/parselogs-ignores-x86_64.txt | |||
@@ -0,0 +1 @@ | |||
parselogs-ignores-x86.txt \ No newline at end of file | |||
diff --git a/meta/lib/oeqa/runtime/cases/parselogs.py b/meta/lib/oeqa/runtime/cases/parselogs.py index a1791b5cca..6966923c94 100644 --- a/meta/lib/oeqa/runtime/cases/parselogs.py +++ b/meta/lib/oeqa/runtime/cases/parselogs.py | |||
@@ -1,204 +1,49 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
7 | import collections | ||
5 | import os | 8 | import os |
9 | import sys | ||
6 | 10 | ||
7 | from subprocess import check_output | ||
8 | from shutil import rmtree | 11 | from shutil import rmtree |
9 | from oeqa.runtime.case import OERuntimeTestCase | 12 | from oeqa.runtime.case import OERuntimeTestCase |
10 | from oeqa.core.decorator.depends import OETestDepends | 13 | from oeqa.core.decorator.depends import OETestDepends |
11 | from oeqa.core.decorator.data import skipIfDataVar | ||
12 | from oeqa.runtime.decorator.package import OEHasPackage | ||
13 | |||
14 | #in the future these lists could be moved outside of module | ||
15 | errors = ["error", "cannot", "can\'t", "failed"] | ||
16 | |||
17 | common_errors = [ | ||
18 | "(WW) warning, (EE) error, (NI) not implemented, (??) unknown.", | ||
19 | "dma timeout", | ||
20 | "can\'t add hid device:", | ||
21 | "usbhid: probe of ", | ||
22 | "_OSC failed (AE_ERROR)", | ||
23 | "_OSC failed (AE_SUPPORT)", | ||
24 | "AE_ALREADY_EXISTS", | ||
25 | "ACPI _OSC request failed (AE_SUPPORT)", | ||
26 | "can\'t disable ASPM", | ||
27 | "Failed to load module \"vesa\"", | ||
28 | "Failed to load module vesa", | ||
29 | "Failed to load module \"modesetting\"", | ||
30 | "Failed to load module modesetting", | ||
31 | "Failed to load module \"glx\"", | ||
32 | "Failed to load module \"fbdev\"", | ||
33 | "Failed to load module fbdev", | ||
34 | "Failed to load module glx", | ||
35 | "[drm] Cannot find any crtc or sizes - going 1024x768", | ||
36 | "_OSC failed (AE_NOT_FOUND); disabling ASPM", | ||
37 | "Open ACPI failed (/var/run/acpid.socket) (No such file or directory)", | ||
38 | "NX (Execute Disable) protection cannot be enabled: non-PAE kernel!", | ||
39 | "hd.: possibly failed opcode", | ||
40 | 'NETLINK INITIALIZATION FAILED', | ||
41 | 'kernel: Cannot find map file', | ||
42 | 'omap_hwmod: debugss: _wait_target_disable failed', | ||
43 | 'VGA arbiter: cannot open kernel arbiter, no multi-card support', | ||
44 | 'Failed to find URL:http://ipv4.connman.net/online/status.html', | ||
45 | 'Online check failed for', | ||
46 | 'netlink init failed', | ||
47 | 'Fast TSC calibration', | ||
48 | "BAR 0-9", | ||
49 | "Failed to load module \"ati\"", | ||
50 | "controller can't do DEVSLP, turning off", | ||
51 | "stmmac_dvr_probe: warning: cannot get CSR clock", | ||
52 | "error: couldn\'t mount because of unsupported optional features", | ||
53 | "GPT: Use GNU Parted to correct GPT errors", | ||
54 | "Cannot set xattr user.Librepo.DownloadInProgress", | ||
55 | "Failed to read /var/lib/nfs/statd/state: Success", | ||
56 | "error retry time-out =", | ||
57 | "logind: cannot setup systemd-logind helper (-61), using legacy fallback", | ||
58 | "Failed to rename network interface", | ||
59 | "Failed to process device, ignoring: Device or resource busy", | ||
60 | "Cannot find a map file", | ||
61 | "[rdrand]: Initialization Failed", | ||
62 | "[pulseaudio] authkey.c: Failed to open cookie file", | ||
63 | "[pulseaudio] authkey.c: Failed to load authentication key", | ||
64 | ] | ||
65 | 14 | ||
66 | video_related = [ | 15 | # importlib.resources.open_text in Python <3.10 doesn't search all directories |
67 | ] | 16 | # when a package is split across multiple directories. Until we can rely on |
17 | # 3.10+, reimplement the searching logic. | ||
18 | if sys.version_info < (3, 10): | ||
19 | def _open_text(package, resource): | ||
20 | import importlib, pathlib | ||
21 | module = importlib.import_module(package) | ||
22 | for path in module.__path__: | ||
23 | candidate = pathlib.Path(path) / resource | ||
24 | if candidate.exists(): | ||
25 | return candidate.open(encoding='utf-8') | ||
26 | raise FileNotFoundError | ||
27 | else: | ||
28 | from importlib.resources import open_text as _open_text | ||
68 | 29 | ||
69 | x86_common = [ | ||
70 | '[drm:psb_do_init] *ERROR* Debug is', | ||
71 | 'wrong ELF class', | ||
72 | 'Could not enable PowerButton event', | ||
73 | 'probe of LNXPWRBN:00 failed with error -22', | ||
74 | 'pmd_set_huge: Cannot satisfy', | ||
75 | 'failed to setup card detect gpio', | ||
76 | 'amd_nb: Cannot enumerate AMD northbridges', | ||
77 | 'failed to retrieve link info, disabling eDP', | ||
78 | 'Direct firmware load for iwlwifi', | ||
79 | 'Direct firmware load for regulatory.db', | ||
80 | 'failed to load regulatory.db', | ||
81 | ] + common_errors | ||
82 | 30 | ||
83 | qemux86_common = [ | 31 | class ParseLogsTest(OERuntimeTestCase): |
84 | 'wrong ELF class', | ||
85 | "fail to add MMCONFIG information, can't access extended PCI configuration space under this bridge.", | ||
86 | "can't claim BAR ", | ||
87 | 'amd_nb: Cannot enumerate AMD northbridges', | ||
88 | 'tsc: HPET/PMTIMER calibration failed', | ||
89 | "modeset(0): Failed to initialize the DRI2 extension", | ||
90 | "glamor initialization failed", | ||
91 | ] + common_errors | ||
92 | 32 | ||
93 | ignore_errors = { | 33 | # Which log files should be collected |
94 | 'default' : common_errors, | 34 | log_locations = ["/var/log/", "/var/log/dmesg", "/tmp/dmesg_output.log"] |
95 | 'qemux86' : [ | ||
96 | 'Failed to access perfctr msr (MSR', | ||
97 | 'pci 0000:00:00.0: [Firmware Bug]: reg 0x..: invalid BAR (can\'t size)', | ||
98 | ] + qemux86_common, | ||
99 | 'qemux86-64' : qemux86_common, | ||
100 | 'qemumips' : [ | ||
101 | 'Failed to load module "glx"', | ||
102 | 'pci 0000:00:00.0: [Firmware Bug]: reg 0x..: invalid BAR (can\'t size)', | ||
103 | 'cacheinfo: Failed to find cpu0 device node', | ||
104 | ] + common_errors, | ||
105 | 'qemumips64' : [ | ||
106 | 'pci 0000:00:00.0: [Firmware Bug]: reg 0x..: invalid BAR (can\'t size)', | ||
107 | 'cacheinfo: Failed to find cpu0 device node', | ||
108 | ] + common_errors, | ||
109 | 'qemuppc' : [ | ||
110 | 'PCI 0000:00 Cannot reserve Legacy IO [io 0x0000-0x0fff]', | ||
111 | 'host side 80-wire cable detection failed, limiting max speed', | ||
112 | 'mode "640x480" test failed', | ||
113 | 'Failed to load module "glx"', | ||
114 | 'can\'t handle BAR above 4GB', | ||
115 | 'Cannot reserve Legacy IO', | ||
116 | ] + common_errors, | ||
117 | 'qemuarm' : [ | ||
118 | 'mmci-pl18x: probe of fpga:05 failed with error -22', | ||
119 | 'mmci-pl18x: probe of fpga:0b failed with error -22', | ||
120 | 'Failed to load module "glx"', | ||
121 | 'OF: amba_device_add() failed (-19) for /amba/smc@10100000', | ||
122 | 'OF: amba_device_add() failed (-19) for /amba/mpmc@10110000', | ||
123 | 'OF: amba_device_add() failed (-19) for /amba/sctl@101e0000', | ||
124 | 'OF: amba_device_add() failed (-19) for /amba/watchdog@101e1000', | ||
125 | 'OF: amba_device_add() failed (-19) for /amba/sci@101f0000', | ||
126 | 'OF: amba_device_add() failed (-19) for /amba/spi@101f4000', | ||
127 | 'OF: amba_device_add() failed (-19) for /amba/ssp@101f4000', | ||
128 | 'OF: amba_device_add() failed (-19) for /amba/fpga/sci@a000', | ||
129 | 'Failed to initialize \'/amba/timer@101e3000\': -22', | ||
130 | 'jitterentropy: Initialization failed with host not compliant with requirements: 2', | ||
131 | ] + common_errors, | ||
132 | 'qemuarm64' : [ | ||
133 | 'Fatal server error:', | ||
134 | '(EE) Server terminated with error (1). Closing log file.', | ||
135 | 'dmi: Firmware registration failed.', | ||
136 | 'irq: type mismatch, failed to map hwirq-27 for /intc', | ||
137 | 'logind: failed to get session seat', | ||
138 | ] + common_errors, | ||
139 | 'intel-core2-32' : [ | ||
140 | 'ACPI: No _BQC method, cannot determine initial brightness', | ||
141 | '[Firmware Bug]: ACPI: No _BQC method, cannot determine initial brightness', | ||
142 | '(EE) Failed to load module "psb"', | ||
143 | '(EE) Failed to load module psb', | ||
144 | '(EE) Failed to load module "psbdrv"', | ||
145 | '(EE) Failed to load module psbdrv', | ||
146 | '(EE) open /dev/fb0: No such file or directory', | ||
147 | '(EE) AIGLX: reverting to software rendering', | ||
148 | 'dmi: Firmware registration failed.', | ||
149 | 'ioremap error for 0x78', | ||
150 | ] + x86_common, | ||
151 | 'intel-corei7-64' : [ | ||
152 | 'can\'t set Max Payload Size to 256', | ||
153 | 'intel_punit_ipc: can\'t request region for resource', | ||
154 | '[drm] parse error at position 4 in video mode \'efifb\'', | ||
155 | 'ACPI Error: Could not enable RealTimeClock event', | ||
156 | 'ACPI Warning: Could not enable fixed event - RealTimeClock', | ||
157 | 'hci_intel INT33E1:00: Unable to retrieve gpio', | ||
158 | 'hci_intel: probe of INT33E1:00 failed', | ||
159 | 'can\'t derive routing for PCI INT A', | ||
160 | 'failed to read out thermal zone', | ||
161 | 'Bluetooth: hci0: Setting Intel event mask failed', | ||
162 | 'ttyS2 - failed to request DMA', | ||
163 | 'Bluetooth: hci0: Failed to send firmware data (-38)', | ||
164 | 'atkbd serio0: Failed to enable keyboard on isa0060/serio0', | ||
165 | ] + x86_common, | ||
166 | 'genericx86' : x86_common, | ||
167 | 'genericx86-64' : [ | ||
168 | 'Direct firmware load for i915', | ||
169 | 'Failed to load firmware i915', | ||
170 | 'Failed to fetch GuC', | ||
171 | 'Failed to initialize GuC', | ||
172 | 'Failed to load DMC firmware', | ||
173 | 'The driver is built-in, so to load the firmware you need to', | ||
174 | ] + x86_common, | ||
175 | 'edgerouter' : [ | ||
176 | 'not creating \'/sys/firmware/fdt\'', | ||
177 | 'Failed to find cpu0 device node', | ||
178 | 'Fatal server error:', | ||
179 | 'Server terminated with error', | ||
180 | ] + common_errors, | ||
181 | 'beaglebone-yocto' : [ | ||
182 | 'Direct firmware load for regulatory.db', | ||
183 | 'failed to load regulatory.db', | ||
184 | 'l4_wkup_cm', | ||
185 | 'Failed to load module "glx"', | ||
186 | 'Failed to make EGL context current', | ||
187 | 'glamor initialization failed', | ||
188 | ] + common_errors, | ||
189 | } | ||
190 | 35 | ||
191 | log_locations = ["/var/log/","/var/log/dmesg", "/tmp/dmesg_output.log"] | 36 | # The keywords that identify error messages in the log files |
37 | errors = ["error", "cannot", "can't", "failed"] | ||
192 | 38 | ||
193 | class ParseLogsTest(OERuntimeTestCase): | 39 | # A list of error messages that should be ignored |
40 | ignore_errors = [] | ||
194 | 41 | ||
195 | @classmethod | 42 | @classmethod |
196 | def setUpClass(cls): | 43 | def setUpClass(cls): |
197 | cls.errors = errors | ||
198 | |||
199 | # When systemd is enabled we need to notice errors on | 44 | # When systemd is enabled we need to notice errors on |
200 | # circular dependencies in units. | 45 | # circular dependencies in units. |
201 | if 'systemd' in cls.td.get('DISTRO_FEATURES', ''): | 46 | if 'systemd' in cls.td.get('DISTRO_FEATURES'): |
202 | cls.errors.extend([ | 47 | cls.errors.extend([ |
203 | 'Found ordering cycle on', | 48 | 'Found ordering cycle on', |
204 | 'Breaking ordering cycle by deleting job', | 49 | 'Breaking ordering cycle by deleting job', |
@@ -206,48 +51,22 @@ class ParseLogsTest(OERuntimeTestCase): | |||
206 | 'Ordering cycle found, skipping', | 51 | 'Ordering cycle found, skipping', |
207 | ]) | 52 | ]) |
208 | 53 | ||
209 | cls.ignore_errors = ignore_errors | 54 | cls.errors = [s.casefold() for s in cls.errors] |
210 | cls.log_locations = log_locations | ||
211 | cls.msg = '' | ||
212 | is_lsb, _ = cls.tc.target.run("which LSB_Test.sh") | ||
213 | if is_lsb == 0: | ||
214 | for machine in cls.ignore_errors: | ||
215 | cls.ignore_errors[machine] = cls.ignore_errors[machine] \ | ||
216 | + video_related | ||
217 | |||
218 | def getMachine(self): | ||
219 | return self.td.get('MACHINE', '') | ||
220 | |||
221 | def getWorkdir(self): | ||
222 | return self.td.get('WORKDIR', '') | ||
223 | |||
224 | # Get some information on the CPU of the machine to display at the | ||
225 | # beginning of the output. This info might be useful in some cases. | ||
226 | def getHardwareInfo(self): | ||
227 | hwi = "" | ||
228 | cmd = ('cat /proc/cpuinfo | grep "model name" | head -n1 | ' | ||
229 | " awk 'BEGIN{FS=\":\"}{print $2}'") | ||
230 | _, cpu_name = self.target.run(cmd) | ||
231 | |||
232 | cmd = ('cat /proc/cpuinfo | grep "cpu cores" | head -n1 | ' | ||
233 | "awk {'print $4'}") | ||
234 | _, cpu_physical_cores = self.target.run(cmd) | ||
235 | |||
236 | cmd = 'cat /proc/cpuinfo | grep "processor" | wc -l' | ||
237 | _, cpu_logical_cores = self.target.run(cmd) | ||
238 | |||
239 | _, cpu_arch = self.target.run('uname -m') | ||
240 | 55 | ||
241 | hwi += 'Machine information: \n' | 56 | cls.load_machine_ignores() |
242 | hwi += '*******************************\n' | ||
243 | hwi += 'Machine name: ' + self.getMachine() + '\n' | ||
244 | hwi += 'CPU: ' + str(cpu_name) + '\n' | ||
245 | hwi += 'Arch: ' + str(cpu_arch)+ '\n' | ||
246 | hwi += 'Physical cores: ' + str(cpu_physical_cores) + '\n' | ||
247 | hwi += 'Logical cores: ' + str(cpu_logical_cores) + '\n' | ||
248 | hwi += '*******************************\n' | ||
249 | 57 | ||
250 | return hwi | 58 | @classmethod |
59 | def load_machine_ignores(cls): | ||
60 | # Add TARGET_ARCH explicitly as not every machine has that in MACHINEOVERRDES (eg qemux86-64) | ||
61 | for candidate in ["common", cls.td.get("TARGET_ARCH")] + cls.td.get("MACHINEOVERRIDES").split(":"): | ||
62 | try: | ||
63 | name = f"parselogs-ignores-{candidate}.txt" | ||
64 | for line in _open_text("oeqa.runtime.cases", name): | ||
65 | line = line.strip() | ||
66 | if line and not line.startswith("#"): | ||
67 | cls.ignore_errors.append(line.casefold()) | ||
68 | except FileNotFoundError: | ||
69 | pass | ||
251 | 70 | ||
252 | # Go through the log locations provided and if it's a folder | 71 | # Go through the log locations provided and if it's a folder |
253 | # create a list with all the .log files in it, if it's a file | 72 | # create a list with all the .log files in it, if it's a file |
@@ -255,23 +74,23 @@ class ParseLogsTest(OERuntimeTestCase): | |||
255 | def getLogList(self, log_locations): | 74 | def getLogList(self, log_locations): |
256 | logs = [] | 75 | logs = [] |
257 | for location in log_locations: | 76 | for location in log_locations: |
258 | status, _ = self.target.run('test -f ' + str(location)) | 77 | status, _ = self.target.run('test -f %s' % location) |
259 | if status == 0: | 78 | if status == 0: |
260 | logs.append(str(location)) | 79 | logs.append(location) |
261 | else: | 80 | else: |
262 | status, _ = self.target.run('test -d ' + str(location)) | 81 | status, _ = self.target.run('test -d %s' % location) |
263 | if status == 0: | 82 | if status == 0: |
264 | cmd = 'find ' + str(location) + '/*.log -maxdepth 1 -type f' | 83 | cmd = 'find %s -name \\*.log -maxdepth 1 -type f' % location |
265 | status, output = self.target.run(cmd) | 84 | status, output = self.target.run(cmd) |
266 | if status == 0: | 85 | if status == 0: |
267 | output = output.splitlines() | 86 | output = output.splitlines() |
268 | for logfile in output: | 87 | for logfile in output: |
269 | logs.append(os.path.join(location, str(logfile))) | 88 | logs.append(os.path.join(location, logfile)) |
270 | return logs | 89 | return logs |
271 | 90 | ||
272 | # Copy the log files to be parsed locally | 91 | # Copy the log files to be parsed locally |
273 | def transfer_logs(self, log_list): | 92 | def transfer_logs(self, log_list): |
274 | workdir = self.getWorkdir() | 93 | workdir = self.td.get('WORKDIR') |
275 | self.target_logs = workdir + '/' + 'target_logs' | 94 | self.target_logs = workdir + '/' + 'target_logs' |
276 | target_logs = self.target_logs | 95 | target_logs = self.target_logs |
277 | if os.path.exists(target_logs): | 96 | if os.path.exists(target_logs): |
@@ -288,65 +107,55 @@ class ParseLogsTest(OERuntimeTestCase): | |||
288 | logs = [f for f in dir_files if os.path.isfile(f)] | 107 | logs = [f for f in dir_files if os.path.isfile(f)] |
289 | return logs | 108 | return logs |
290 | 109 | ||
291 | # Build the grep command to be used with filters and exclusions | 110 | def get_context(self, lines, index, before=6, after=3): |
292 | def build_grepcmd(self, errors, ignore_errors, log): | 111 | """ |
293 | grepcmd = 'grep ' | 112 | Given a set of lines and the index of the line that is important, return |
294 | grepcmd += '-Ei "' | 113 | a number of lines surrounding that line. |
295 | for error in errors: | 114 | """ |
296 | grepcmd += '\<' + error + '\>' + '|' | 115 | last = len(lines) |
297 | grepcmd = grepcmd[:-1] | 116 | |
298 | grepcmd += '" ' + str(log) + " | grep -Eiv \'" | 117 | start = index - before |
299 | 118 | end = index + after + 1 | |
300 | try: | 119 | |
301 | errorlist = ignore_errors[self.getMachine()] | 120 | if start < 0: |
302 | except KeyError: | 121 | end -= start |
303 | self.msg += 'No ignore list found for this machine, using default\n' | 122 | start = 0 |
304 | errorlist = ignore_errors['default'] | 123 | if end > last: |
305 | 124 | start -= end - last | |
306 | for ignore_error in errorlist: | 125 | end = last |
307 | ignore_error = ignore_error.replace('(', '\(') | 126 | |
308 | ignore_error = ignore_error.replace(')', '\)') | 127 | return lines[start:end] |
309 | ignore_error = ignore_error.replace("'", '.') | 128 | |
310 | ignore_error = ignore_error.replace('?', '\?') | 129 | def test_get_context(self): |
311 | ignore_error = ignore_error.replace('[', '\[') | 130 | """ |
312 | ignore_error = ignore_error.replace(']', '\]') | 131 | A test case for the test case. |
313 | ignore_error = ignore_error.replace('*', '\*') | 132 | """ |
314 | ignore_error = ignore_error.replace('0-9', '[0-9]') | 133 | lines = list(range(0,10)) |
315 | grepcmd += ignore_error + '|' | 134 | self.assertEqual(self.get_context(lines, 0, 2, 1), [0, 1, 2, 3]) |
316 | grepcmd = grepcmd[:-1] | 135 | self.assertEqual(self.get_context(lines, 5, 2, 1), [3, 4, 5, 6]) |
317 | grepcmd += "\'" | 136 | self.assertEqual(self.get_context(lines, 9, 2, 1), [6, 7, 8, 9]) |
318 | 137 | ||
319 | return grepcmd | 138 | def parse_logs(self, logs, lines_before=10, lines_after=10): |
320 | 139 | """ | |
321 | # Grep only the errors so that their context could be collected. | 140 | Search the log files @logs looking for error lines (marked by |
322 | # Default context is 10 lines before and after the error itself | 141 | @self.errors), ignoring anything listed in @self.ignore_errors. |
323 | def parse_logs(self, errors, ignore_errors, logs, | 142 | |
324 | lines_before = 10, lines_after = 10): | 143 | Returns a dictionary of log filenames to a dictionary of error lines to |
325 | results = {} | 144 | the error context (controlled by @lines_before and @lines_after). |
326 | rez = [] | 145 | """ |
327 | grep_output = '' | 146 | results = collections.defaultdict(dict) |
328 | 147 | ||
329 | for log in logs: | 148 | for log in logs: |
330 | result = None | 149 | with open(log) as f: |
331 | thegrep = self.build_grepcmd(errors, ignore_errors, log) | 150 | lines = f.readlines() |
332 | 151 | ||
333 | try: | 152 | for i, line in enumerate(lines): |
334 | result = check_output(thegrep, shell=True).decode('utf-8') | 153 | line = line.strip() |
335 | except: | 154 | line_lower = line.casefold() |
336 | pass | ||
337 | 155 | ||
338 | if result is not None: | 156 | if any(keyword in line_lower for keyword in self.errors): |
339 | results[log] = {} | 157 | if not any(ignore in line_lower for ignore in self.ignore_errors): |
340 | rez = result.splitlines() | 158 | results[log][line] = "".join(self.get_context(lines, i, lines_before, lines_after)) |
341 | |||
342 | for xrez in rez: | ||
343 | try: | ||
344 | cmd = ['grep', '-F', xrez, '-B', str(lines_before)] | ||
345 | cmd += ['-A', str(lines_after), log] | ||
346 | grep_output = check_output(cmd).decode('utf-8') | ||
347 | except: | ||
348 | pass | ||
349 | results[log][xrez]=grep_output | ||
350 | 159 | ||
351 | return results | 160 | return results |
352 | 161 | ||
@@ -359,17 +168,18 @@ class ParseLogsTest(OERuntimeTestCase): | |||
359 | def test_parselogs(self): | 168 | def test_parselogs(self): |
360 | self.write_dmesg() | 169 | self.write_dmesg() |
361 | log_list = self.get_local_log_list(self.log_locations) | 170 | log_list = self.get_local_log_list(self.log_locations) |
362 | result = self.parse_logs(self.errors, self.ignore_errors, log_list) | 171 | result = self.parse_logs(log_list) |
363 | print(self.getHardwareInfo()) | 172 | |
364 | errcount = 0 | 173 | errcount = 0 |
174 | self.msg = "" | ||
365 | for log in result: | 175 | for log in result: |
366 | self.msg += 'Log: ' + log + '\n' | 176 | self.msg += 'Log: ' + log + '\n' |
367 | self.msg += '-----------------------\n' | 177 | self.msg += '-----------------------\n' |
368 | for error in result[log]: | 178 | for error in result[log]: |
369 | errcount += 1 | 179 | errcount += 1 |
370 | self.msg += 'Central error: ' + str(error) + '\n' | 180 | self.msg += 'Central error: ' + error + '\n' |
371 | self.msg += '***********************\n' | 181 | self.msg += '***********************\n' |
372 | self.msg += result[str(log)][str(error)] + '\n' | 182 | self.msg += result[log][error] + '\n' |
373 | self.msg += '***********************\n' | 183 | self.msg += '***********************\n' |
374 | self.msg += '%s errors found in logs.' % errcount | 184 | self.msg += '%s errors found in logs.' % errcount |
375 | self.assertEqual(errcount, 0, msg=self.msg) | 185 | self.assertEqual(errcount, 0, msg=self.msg) |
diff --git a/meta/lib/oeqa/runtime/cases/perl.py b/meta/lib/oeqa/runtime/cases/perl.py index 2c6b3b7846..f11b300836 100644 --- a/meta/lib/oeqa/runtime/cases/perl.py +++ b/meta/lib/oeqa/runtime/cases/perl.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
diff --git a/meta/lib/oeqa/runtime/cases/ping.py b/meta/lib/oeqa/runtime/cases/ping.py index f6603f75ec..f72460e7f3 100644 --- a/meta/lib/oeqa/runtime/cases/ping.py +++ b/meta/lib/oeqa/runtime/cases/ping.py | |||
@@ -1,11 +1,15 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
5 | from subprocess import Popen, PIPE | 7 | from subprocess import Popen, PIPE |
8 | from time import sleep | ||
6 | 9 | ||
7 | from oeqa.runtime.case import OERuntimeTestCase | 10 | from oeqa.runtime.case import OERuntimeTestCase |
8 | from oeqa.core.decorator.oetimeout import OETimeout | 11 | from oeqa.core.decorator.oetimeout import OETimeout |
12 | from oeqa.core.exception import OEQATimeoutError | ||
9 | 13 | ||
10 | class PingTest(OERuntimeTestCase): | 14 | class PingTest(OERuntimeTestCase): |
11 | 15 | ||
@@ -13,14 +17,19 @@ class PingTest(OERuntimeTestCase): | |||
13 | def test_ping(self): | 17 | def test_ping(self): |
14 | output = '' | 18 | output = '' |
15 | count = 0 | 19 | count = 0 |
16 | while count < 5: | 20 | self.assertNotEqual(len(self.target.ip), 0, msg="No target IP address set") |
17 | cmd = 'ping -c 1 %s' % self.target.ip | 21 | try: |
18 | proc = Popen(cmd, shell=True, stdout=PIPE) | 22 | while count < 5: |
19 | output += proc.communicate()[0].decode('utf-8') | 23 | cmd = 'ping -c 1 %s' % self.target.ip |
20 | if proc.poll() == 0: | 24 | proc = Popen(cmd, shell=True, stdout=PIPE) |
21 | count += 1 | 25 | output += proc.communicate()[0].decode('utf-8') |
22 | else: | 26 | if proc.poll() == 0: |
23 | count = 0 | 27 | count += 1 |
28 | else: | ||
29 | count = 0 | ||
30 | sleep(1) | ||
31 | except OEQATimeoutError: | ||
32 | self.fail("Ping timeout error for address %s, count %s, output: %s" % (self.target.ip, count, output)) | ||
24 | msg = ('Expected 5 consecutive, got %d.\n' | 33 | msg = ('Expected 5 consecutive, got %d.\n' |
25 | 'ping output is:\n%s' % (count,output)) | 34 | 'ping output is:\n%s' % (count,output)) |
26 | self.assertEqual(count, 5, msg = msg) | 35 | self.assertEqual(count, 5, msg = msg) |
diff --git a/meta/lib/oeqa/runtime/cases/ptest.py b/meta/lib/oeqa/runtime/cases/ptest.py index 0800f3c27f..fbaeb84d00 100644 --- a/meta/lib/oeqa/runtime/cases/ptest.py +++ b/meta/lib/oeqa/runtime/cases/ptest.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
@@ -57,7 +59,7 @@ class PtestRunnerTest(OERuntimeTestCase): | |||
57 | ptest_dirs = [ '/usr/lib' ] | 59 | ptest_dirs = [ '/usr/lib' ] |
58 | if not libdir in ptest_dirs: | 60 | if not libdir in ptest_dirs: |
59 | ptest_dirs.append(libdir) | 61 | ptest_dirs.append(libdir) |
60 | status, output = self.target.run('ptest-runner -d \"{}\"'.format(' '.join(ptest_dirs)), 0) | 62 | status, output = self.target.run('ptest-runner -t 450 -d \"{}\"'.format(' '.join(ptest_dirs)), 0) |
61 | os.makedirs(ptest_log_dir) | 63 | os.makedirs(ptest_log_dir) |
62 | with open(ptest_runner_log, 'w') as f: | 64 | with open(ptest_runner_log, 'w') as f: |
63 | f.write(output) | 65 | f.write(output) |
@@ -81,17 +83,20 @@ class PtestRunnerTest(OERuntimeTestCase): | |||
81 | 83 | ||
82 | extras['ptestresult.sections'] = sections | 84 | extras['ptestresult.sections'] = sections |
83 | 85 | ||
86 | zerolength = [] | ||
84 | trans = str.maketrans("()", "__") | 87 | trans = str.maketrans("()", "__") |
85 | for section in results: | 88 | for section in results: |
86 | for test in results[section]: | 89 | for test in results[section]: |
87 | result = results[section][test] | 90 | result = results[section][test] |
88 | testname = "ptestresult." + (section or "No-section") + "." + "_".join(test.translate(trans).split()) | 91 | testname = "ptestresult." + (section or "No-section") + "." + "_".join(test.translate(trans).split()) |
89 | extras[testname] = {'status': result} | 92 | extras[testname] = {'status': result} |
93 | if not results[section]: | ||
94 | zerolength.append(section) | ||
90 | 95 | ||
91 | failed_tests = {} | 96 | failed_tests = {} |
92 | 97 | ||
93 | for section in sections: | 98 | for section in sections: |
94 | if 'exitcode' in sections[section].keys(): | 99 | if 'exitcode' in sections[section].keys() or 'timeout' in sections[section].keys(): |
95 | failed_tests[section] = sections[section]["log"] | 100 | failed_tests[section] = sections[section]["log"] |
96 | 101 | ||
97 | for section in results: | 102 | for section in results: |
@@ -105,7 +110,10 @@ class PtestRunnerTest(OERuntimeTestCase): | |||
105 | failmsg = "ERROR: Processes were killed by the OOM Killer:\n%s\n" % output | 110 | failmsg = "ERROR: Processes were killed by the OOM Killer:\n%s\n" % output |
106 | 111 | ||
107 | if failed_tests: | 112 | if failed_tests: |
108 | failmsg = failmsg + "Failed ptests:\n%s" % pprint.pformat(failed_tests) | 113 | failmsg = failmsg + "\nFailed ptests:\n%s\n" % pprint.pformat(failed_tests) |
114 | |||
115 | if zerolength: | ||
116 | failmsg = failmsg + "\nptests which had no test results:\n%s" % pprint.pformat(zerolength) | ||
109 | 117 | ||
110 | if failmsg: | 118 | if failmsg: |
111 | self.logger.warning("There were failing ptests.") | 119 | self.logger.warning("There were failing ptests.") |
diff --git a/meta/lib/oeqa/runtime/cases/python.py b/meta/lib/oeqa/runtime/cases/python.py index ec54f1e1db..5d6d133480 100644 --- a/meta/lib/oeqa/runtime/cases/python.py +++ b/meta/lib/oeqa/runtime/cases/python.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
diff --git a/meta/lib/oeqa/runtime/cases/rpm.py b/meta/lib/oeqa/runtime/cases/rpm.py index 8e18b426f8..ea5619ffea 100644 --- a/meta/lib/oeqa/runtime/cases/rpm.py +++ b/meta/lib/oeqa/runtime/cases/rpm.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
@@ -49,21 +51,20 @@ class RpmBasicTest(OERuntimeTestCase): | |||
49 | msg = 'status: %s. Cannot run rpm -qa: %s' % (status, output) | 51 | msg = 'status: %s. Cannot run rpm -qa: %s' % (status, output) |
50 | self.assertEqual(status, 0, msg=msg) | 52 | self.assertEqual(status, 0, msg=msg) |
51 | 53 | ||
52 | def check_no_process_for_user(u): | 54 | def wait_for_no_process_for_user(u, timeout = 120): |
53 | _, output = self.target.run(self.tc.target_cmds['ps']) | 55 | timeout_at = time.time() + timeout |
54 | if u + ' ' in output: | 56 | while time.time() < timeout_at: |
55 | return False | 57 | _, output = self.target.run(self.tc.target_cmds['ps']) |
56 | else: | 58 | if u + ' ' not in output: |
57 | return True | 59 | return |
60 | time.sleep(1) | ||
61 | user_pss = [ps for ps in output.split("\n") if u + ' ' in ps] | ||
62 | msg = "User %s has processes still running: %s" % (u, "\n".join(user_pss)) | ||
63 | self.fail(msg=msg) | ||
58 | 64 | ||
59 | def unset_up_test_user(u): | 65 | def unset_up_test_user(u): |
60 | # ensure no test1 process in running | 66 | # ensure no test1 process in running |
61 | timeout = time.time() + 30 | 67 | wait_for_no_process_for_user(u) |
62 | while time.time() < timeout: | ||
63 | if check_no_process_for_user(u): | ||
64 | break | ||
65 | else: | ||
66 | time.sleep(1) | ||
67 | status, output = self.target.run('userdel -r %s' % u) | 68 | status, output = self.target.run('userdel -r %s' % u) |
68 | msg = 'Failed to erase user: %s' % output | 69 | msg = 'Failed to erase user: %s' % output |
69 | self.assertTrue(status == 0, msg=msg) | 70 | self.assertTrue(status == 0, msg=msg) |
@@ -79,21 +80,24 @@ class RpmBasicTest(OERuntimeTestCase): | |||
79 | 80 | ||
80 | class RpmInstallRemoveTest(OERuntimeTestCase): | 81 | class RpmInstallRemoveTest(OERuntimeTestCase): |
81 | 82 | ||
82 | @classmethod | 83 | def _find_test_file(self): |
83 | def setUpClass(cls): | 84 | pkgarch = self.td['TUNE_PKGARCH'].replace('-', '_') |
84 | pkgarch = cls.td['TUNE_PKGARCH'].replace('-', '_') | 85 | rpmdir = os.path.join(self.tc.td['DEPLOY_DIR'], 'rpm', pkgarch) |
85 | rpmdir = os.path.join(cls.tc.td['DEPLOY_DIR'], 'rpm', pkgarch) | ||
86 | # Pick base-passwd-doc as a test file to get installed, because it's small | 86 | # Pick base-passwd-doc as a test file to get installed, because it's small |
87 | # and it will always be built for standard targets | 87 | # and it will always be built for standard targets |
88 | rpm_doc = 'base-passwd-doc-*.%s.rpm' % pkgarch | 88 | rpm_doc = 'base-passwd-doc-*.%s.rpm' % pkgarch |
89 | if not os.path.exists(rpmdir): | 89 | if not os.path.exists(rpmdir): |
90 | return | 90 | self.fail("Rpm directory {} does not exist".format(rpmdir)) |
91 | for f in fnmatch.filter(os.listdir(rpmdir), rpm_doc): | 91 | for f in fnmatch.filter(os.listdir(rpmdir), rpm_doc): |
92 | cls.test_file = os.path.join(rpmdir, f) | 92 | self.test_file = os.path.join(rpmdir, f) |
93 | cls.dst = '/tmp/base-passwd-doc.rpm' | 93 | break |
94 | else: | ||
95 | self.fail("Couldn't find the test rpm file {} in {}".format(rpm_doc, rpmdir)) | ||
96 | self.dst = '/tmp/base-passwd-doc.rpm' | ||
94 | 97 | ||
95 | @OETestDepends(['rpm.RpmBasicTest.test_rpm_query']) | 98 | @OETestDepends(['rpm.RpmBasicTest.test_rpm_query']) |
96 | def test_rpm_install(self): | 99 | def test_rpm_install(self): |
100 | self._find_test_file() | ||
97 | self.tc.target.copyTo(self.test_file, self.dst) | 101 | self.tc.target.copyTo(self.test_file, self.dst) |
98 | status, output = self.target.run('rpm -ivh /tmp/base-passwd-doc.rpm') | 102 | status, output = self.target.run('rpm -ivh /tmp/base-passwd-doc.rpm') |
99 | msg = 'Failed to install base-passwd-doc package: %s' % output | 103 | msg = 'Failed to install base-passwd-doc package: %s' % output |
@@ -116,12 +120,13 @@ class RpmInstallRemoveTest(OERuntimeTestCase): | |||
116 | Author: Alexander Kanavin <alex.kanavin@gmail.com> | 120 | Author: Alexander Kanavin <alex.kanavin@gmail.com> |
117 | AutomatedBy: Daniel Istrate <daniel.alexandrux.istrate@intel.com> | 121 | AutomatedBy: Daniel Istrate <daniel.alexandrux.istrate@intel.com> |
118 | """ | 122 | """ |
119 | db_files_cmd = 'ls /var/lib/rpm/__db.*' | 123 | self._find_test_file() |
124 | db_files_cmd = 'ls /var/lib/rpm/rpmdb.sqlite*' | ||
120 | check_log_cmd = "grep RPM /var/log/messages | wc -l" | 125 | check_log_cmd = "grep RPM /var/log/messages | wc -l" |
121 | 126 | ||
122 | # Make sure that some database files are under /var/lib/rpm as '__db.xxx' | 127 | # Make sure that some database files are under /var/lib/rpm as 'rpmdb.sqlite' |
123 | status, output = self.target.run(db_files_cmd) | 128 | status, output = self.target.run(db_files_cmd) |
124 | msg = 'Failed to find database files under /var/lib/rpm/ as __db.xxx' | 129 | msg = 'Failed to find database files under /var/lib/rpm/ as rpmdb.sqlite' |
125 | self.assertEqual(0, status, msg=msg) | 130 | self.assertEqual(0, status, msg=msg) |
126 | 131 | ||
127 | self.tc.target.copyTo(self.test_file, self.dst) | 132 | self.tc.target.copyTo(self.test_file, self.dst) |
@@ -141,13 +146,4 @@ class RpmInstallRemoveTest(OERuntimeTestCase): | |||
141 | 146 | ||
142 | self.tc.target.run('rm -f %s' % self.dst) | 147 | self.tc.target.run('rm -f %s' % self.dst) |
143 | 148 | ||
144 | # if using systemd this should ensure all entries are flushed to /var | ||
145 | status, output = self.target.run("journalctl --sync") | ||
146 | # Get the amount of entries in the log file | ||
147 | status, output = self.target.run(check_log_cmd) | ||
148 | msg = 'Failed to get the final size of the log file.' | ||
149 | self.assertEqual(0, status, msg=msg) | ||
150 | 149 | ||
151 | # Check that there's enough of them | ||
152 | self.assertGreaterEqual(int(output), 80, | ||
153 | 'Cound not find sufficient amount of rpm entries in /var/log/messages, found {} entries'.format(output)) | ||
diff --git a/meta/lib/oeqa/runtime/cases/rt.py b/meta/lib/oeqa/runtime/cases/rt.py new file mode 100644 index 0000000000..15ab4dbbbb --- /dev/null +++ b/meta/lib/oeqa/runtime/cases/rt.py | |||
@@ -0,0 +1,19 @@ | |||
1 | # | ||
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
4 | # SPDX-License-Identifier: MIT | ||
5 | # | ||
6 | |||
7 | from oeqa.runtime.case import OERuntimeTestCase | ||
8 | from oeqa.core.decorator.depends import OETestDepends | ||
9 | |||
10 | class RtTest(OERuntimeTestCase): | ||
11 | @OETestDepends(['ssh.SSHTest.test_ssh']) | ||
12 | def test_is_rt(self): | ||
13 | """ | ||
14 | Check that the kernel has CONFIG_PREEMPT_RT enabled. | ||
15 | """ | ||
16 | status, output = self.target.run("uname -a") | ||
17 | self.assertEqual(status, 0, msg=output) | ||
18 | # Split so we don't get a substring false-positive | ||
19 | self.assertIn("PREEMPT_RT", output.split()) | ||
diff --git a/meta/lib/oeqa/runtime/cases/rtc.py b/meta/lib/oeqa/runtime/cases/rtc.py index a34c101a9d..6e45c5db4f 100644 --- a/meta/lib/oeqa/runtime/cases/rtc.py +++ b/meta/lib/oeqa/runtime/cases/rtc.py | |||
@@ -1,5 +1,11 @@ | |||
1 | # | ||
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
4 | # SPDX-License-Identifier: MIT | ||
5 | # | ||
1 | from oeqa.runtime.case import OERuntimeTestCase | 6 | from oeqa.runtime.case import OERuntimeTestCase |
2 | from oeqa.core.decorator.depends import OETestDepends | 7 | from oeqa.core.decorator.depends import OETestDepends |
8 | from oeqa.core.decorator.data import skipIfFeature | ||
3 | from oeqa.runtime.decorator.package import OEHasPackage | 9 | from oeqa.runtime.decorator.package import OEHasPackage |
4 | 10 | ||
5 | import re | 11 | import re |
@@ -9,19 +15,21 @@ class RTCTest(OERuntimeTestCase): | |||
9 | def setUp(self): | 15 | def setUp(self): |
10 | if self.tc.td.get('VIRTUAL-RUNTIME_init_manager') == 'systemd': | 16 | if self.tc.td.get('VIRTUAL-RUNTIME_init_manager') == 'systemd': |
11 | self.logger.debug('Stopping systemd-timesyncd daemon') | 17 | self.logger.debug('Stopping systemd-timesyncd daemon') |
12 | self.target.run('systemctl disable --now systemd-timesyncd') | 18 | self.target.run('systemctl disable --now --runtime systemd-timesyncd') |
13 | 19 | ||
14 | def tearDown(self): | 20 | def tearDown(self): |
15 | if self.tc.td.get('VIRTUAL-RUNTIME_init_manager') == 'systemd': | 21 | if self.tc.td.get('VIRTUAL-RUNTIME_init_manager') == 'systemd': |
16 | self.logger.debug('Starting systemd-timesyncd daemon') | 22 | self.logger.debug('Starting systemd-timesyncd daemon') |
17 | self.target.run('systemctl enable --now systemd-timesyncd') | 23 | self.target.run('systemctl enable --now --runtime systemd-timesyncd') |
18 | 24 | ||
25 | @skipIfFeature('read-only-rootfs', | ||
26 | 'Test does not work with read-only-rootfs in IMAGE_FEATURES') | ||
19 | @OETestDepends(['ssh.SSHTest.test_ssh']) | 27 | @OETestDepends(['ssh.SSHTest.test_ssh']) |
20 | @OEHasPackage(['coreutils', 'busybox']) | 28 | @OEHasPackage(['coreutils', 'busybox']) |
21 | def test_rtc(self): | 29 | def test_rtc(self): |
22 | (status, output) = self.target.run('hwclock -r') | 30 | (status, output) = self.target.run('hwclock -r') |
23 | self.assertEqual(status, 0, msg='Failed to get RTC time, output: %s' % output) | 31 | self.assertEqual(status, 0, msg='Failed to get RTC time, output: %s' % output) |
24 | 32 | ||
25 | (status, current_datetime) = self.target.run('date +"%m%d%H%M%Y"') | 33 | (status, current_datetime) = self.target.run('date +"%m%d%H%M%Y"') |
26 | self.assertEqual(status, 0, msg='Failed to get system current date & time, output: %s' % current_datetime) | 34 | self.assertEqual(status, 0, msg='Failed to get system current date & time, output: %s' % current_datetime) |
27 | 35 | ||
@@ -32,7 +40,6 @@ class RTCTest(OERuntimeTestCase): | |||
32 | 40 | ||
33 | (status, output) = self.target.run('date %s' % current_datetime) | 41 | (status, output) = self.target.run('date %s' % current_datetime) |
34 | self.assertEqual(status, 0, msg='Failed to reset system date & time, output: %s' % output) | 42 | self.assertEqual(status, 0, msg='Failed to reset system date & time, output: %s' % output) |
35 | 43 | ||
36 | (status, output) = self.target.run('hwclock -w') | 44 | (status, output) = self.target.run('hwclock -w') |
37 | self.assertEqual(status, 0, msg='Failed to reset RTC time, output: %s' % output) | 45 | self.assertEqual(status, 0, msg='Failed to reset RTC time, output: %s' % output) |
38 | |||
diff --git a/meta/lib/oeqa/runtime/cases/runlevel.py b/meta/lib/oeqa/runtime/cases/runlevel.py index 3a4df8ace1..6734b0f5ed 100644 --- a/meta/lib/oeqa/runtime/cases/runlevel.py +++ b/meta/lib/oeqa/runtime/cases/runlevel.py | |||
@@ -1,3 +1,8 @@ | |||
1 | # | ||
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
4 | # SPDX-License-Identifier: MIT | ||
5 | # | ||
1 | from oeqa.runtime.case import OERuntimeTestCase | 6 | from oeqa.runtime.case import OERuntimeTestCase |
2 | from oeqa.core.decorator.depends import OETestDepends | 7 | from oeqa.core.decorator.depends import OETestDepends |
3 | 8 | ||
diff --git a/meta/lib/oeqa/runtime/cases/rust.py b/meta/lib/oeqa/runtime/cases/rust.py new file mode 100644 index 0000000000..123c942012 --- /dev/null +++ b/meta/lib/oeqa/runtime/cases/rust.py | |||
@@ -0,0 +1,64 @@ | |||
1 | # | ||
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
4 | # SPDX-License-Identifier: MIT | ||
5 | # | ||
6 | |||
7 | from oeqa.runtime.case import OERuntimeTestCase | ||
8 | from oeqa.core.decorator.depends import OETestDepends | ||
9 | from oeqa.runtime.decorator.package import OEHasPackage | ||
10 | |||
11 | class RustCompileTest(OERuntimeTestCase): | ||
12 | |||
13 | @classmethod | ||
14 | def setUp(cls): | ||
15 | dst = '/tmp/' | ||
16 | src = os.path.join(cls.tc.files_dir, 'test.rs') | ||
17 | cls.tc.target.copyTo(src, dst) | ||
18 | |||
19 | @classmethod | ||
20 | def tearDown(cls): | ||
21 | files = '/tmp/test.rs /tmp/test' | ||
22 | cls.tc.target.run('rm %s' % files) | ||
23 | dirs = '/tmp/hello' | ||
24 | cls.tc.target.run('rm -r %s' % dirs) | ||
25 | |||
26 | @OETestDepends(['ssh.SSHTest.test_ssh']) | ||
27 | @OEHasPackage('rust') | ||
28 | @OEHasPackage('openssh-scp') | ||
29 | def test_rust_compile(self): | ||
30 | status, output = self.target.run('rustc /tmp/test.rs -o /tmp/test') | ||
31 | msg = 'rust compile failed, output: %s' % output | ||
32 | self.assertEqual(status, 0, msg=msg) | ||
33 | |||
34 | status, output = self.target.run('/tmp/test') | ||
35 | msg = 'running compiled file failed, output: %s' % output | ||
36 | self.assertEqual(status, 0, msg=msg) | ||
37 | |||
38 | @OETestDepends(['ssh.SSHTest.test_ssh']) | ||
39 | @OEHasPackage('cargo') | ||
40 | @OEHasPackage('openssh-scp') | ||
41 | def test_cargo_compile(self): | ||
42 | status, output = self.target.run('cargo new /tmp/hello') | ||
43 | msg = 'cargo new failed, output: %s' % output | ||
44 | self.assertEqual(status, 0, msg=msg) | ||
45 | |||
46 | status, output = self.target.run('cargo build --manifest-path=/tmp/hello/Cargo.toml') | ||
47 | msg = 'cargo build failed, output: %s' % output | ||
48 | self.assertEqual(status, 0, msg=msg) | ||
49 | |||
50 | status, output = self.target.run('cargo run --manifest-path=/tmp/hello/Cargo.toml') | ||
51 | msg = 'running compiled file failed, output: %s' % output | ||
52 | self.assertEqual(status, 0, msg=msg) | ||
53 | |||
54 | class RustCLibExampleTest(OERuntimeTestCase): | ||
55 | @OETestDepends(['ssh.SSHTest.test_ssh']) | ||
56 | @OEHasPackage('rust-c-lib-example-bin') | ||
57 | def test_rust_c_lib_example(self): | ||
58 | cmd = "rust-c-lib-example-bin test" | ||
59 | status, output = self.target.run(cmd) | ||
60 | msg = 'Exit status was not 0. Output: %s' % output | ||
61 | self.assertEqual(status, 0, msg=msg) | ||
62 | |||
63 | msg = 'Incorrect output: %s' % output | ||
64 | self.assertEqual(output, "Hello world in rust from C!", msg=msg) | ||
diff --git a/meta/lib/oeqa/runtime/cases/scons.py b/meta/lib/oeqa/runtime/cases/scons.py index 3c7c7f7270..4a8d4d40ba 100644 --- a/meta/lib/oeqa/runtime/cases/scons.py +++ b/meta/lib/oeqa/runtime/cases/scons.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
diff --git a/meta/lib/oeqa/runtime/cases/scp.py b/meta/lib/oeqa/runtime/cases/scp.py index 3a5f292152..ee97b8ef66 100644 --- a/meta/lib/oeqa/runtime/cases/scp.py +++ b/meta/lib/oeqa/runtime/cases/scp.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
@@ -23,7 +25,7 @@ class ScpTest(OERuntimeTestCase): | |||
23 | os.remove(cls.tmp_path) | 25 | os.remove(cls.tmp_path) |
24 | 26 | ||
25 | @OETestDepends(['ssh.SSHTest.test_ssh']) | 27 | @OETestDepends(['ssh.SSHTest.test_ssh']) |
26 | @OEHasPackage(['openssh-scp', 'dropbear']) | 28 | @OEHasPackage(['openssh-scp']) |
27 | def test_scp_file(self): | 29 | def test_scp_file(self): |
28 | dst = '/tmp/test_scp_file' | 30 | dst = '/tmp/test_scp_file' |
29 | 31 | ||
diff --git a/meta/lib/oeqa/runtime/cases/skeletoninit.py b/meta/lib/oeqa/runtime/cases/skeletoninit.py index 4779cd6bb4..d0fdcbded9 100644 --- a/meta/lib/oeqa/runtime/cases/skeletoninit.py +++ b/meta/lib/oeqa/runtime/cases/skeletoninit.py | |||
@@ -1,10 +1,12 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
5 | # This test should cover https://bugzilla.yoctoproject.org/tr_show_case.cgi?case_id=284 | 7 | # This test should cover https://bugzilla.yoctoproject.org/tr_show_case.cgi?case_id=284 |
6 | # testcase. Image under test must have meta-skeleton layer in bblayers and | 8 | # testcase. Image under test must have meta-skeleton layer in bblayers and |
7 | # IMAGE_INSTALL_append = " service" in local.conf | 9 | # IMAGE_INSTALL:append = " service" in local.conf |
8 | from oeqa.runtime.case import OERuntimeTestCase | 10 | from oeqa.runtime.case import OERuntimeTestCase |
9 | from oeqa.core.decorator.depends import OETestDepends | 11 | from oeqa.core.decorator.depends import OETestDepends |
10 | from oeqa.core.decorator.data import skipIfDataVar | 12 | from oeqa.core.decorator.data import skipIfDataVar |
@@ -15,7 +17,7 @@ class SkeletonBasicTest(OERuntimeTestCase): | |||
15 | @OETestDepends(['ssh.SSHTest.test_ssh']) | 17 | @OETestDepends(['ssh.SSHTest.test_ssh']) |
16 | @OEHasPackage(['service']) | 18 | @OEHasPackage(['service']) |
17 | @skipIfDataVar('VIRTUAL-RUNTIME_init_manager', 'systemd', | 19 | @skipIfDataVar('VIRTUAL-RUNTIME_init_manager', 'systemd', |
18 | 'Not appropiate for systemd image') | 20 | 'Not appropriate for systemd image') |
19 | def test_skeleton_availability(self): | 21 | def test_skeleton_availability(self): |
20 | status, output = self.target.run('ls /etc/init.d/skeleton') | 22 | status, output = self.target.run('ls /etc/init.d/skeleton') |
21 | msg = 'skeleton init script not found. Output:\n%s' % output | 23 | msg = 'skeleton init script not found. Output:\n%s' % output |
diff --git a/meta/lib/oeqa/runtime/cases/ssh.py b/meta/lib/oeqa/runtime/cases/ssh.py index 60a5fbbfbf..cdbef59500 100644 --- a/meta/lib/oeqa/runtime/cases/ssh.py +++ b/meta/lib/oeqa/runtime/cases/ssh.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
@@ -11,9 +13,12 @@ class SSHTest(OERuntimeTestCase): | |||
11 | @OETestDepends(['ping.PingTest.test_ping']) | 13 | @OETestDepends(['ping.PingTest.test_ping']) |
12 | @OEHasPackage(['dropbear', 'openssh-sshd']) | 14 | @OEHasPackage(['dropbear', 'openssh-sshd']) |
13 | def test_ssh(self): | 15 | def test_ssh(self): |
16 | (status, output) = self.target.run('sleep 20', timeout=2) | ||
17 | msg='run() timed out but return code was zero.' | ||
18 | self.assertNotEqual(status, 0, msg=msg) | ||
14 | (status, output) = self.target.run('uname -a') | 19 | (status, output) = self.target.run('uname -a') |
15 | self.assertEqual(status, 0, msg='SSH Test failed: %s' % output) | 20 | self.assertEqual(status, 0, msg='SSH Test failed: %s' % output) |
16 | (status, output) = self.target.run('cat /etc/masterimage') | 21 | (status, output) = self.target.run('cat /etc/controllerimage') |
17 | msg = "This isn't the right image - /etc/masterimage " \ | 22 | msg = "This isn't the right image - /etc/controllerimage " \ |
18 | "shouldn't be here %s" % output | 23 | "shouldn't be here %s" % output |
19 | self.assertEqual(status, 1, msg=msg) | 24 | self.assertEqual(status, 1, msg=msg) |
diff --git a/meta/lib/oeqa/runtime/cases/stap.py b/meta/lib/oeqa/runtime/cases/stap.py index 5342f6ac34..3be4162108 100644 --- a/meta/lib/oeqa/runtime/cases/stap.py +++ b/meta/lib/oeqa/runtime/cases/stap.py | |||
@@ -1,37 +1,34 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
5 | import os | 7 | import os |
6 | 8 | ||
7 | from oeqa.runtime.case import OERuntimeTestCase | 9 | from oeqa.runtime.case import OERuntimeTestCase |
8 | from oeqa.core.decorator.depends import OETestDepends | ||
9 | from oeqa.core.decorator.data import skipIfNotFeature | 10 | from oeqa.core.decorator.data import skipIfNotFeature |
10 | from oeqa.runtime.decorator.package import OEHasPackage | 11 | from oeqa.runtime.decorator.package import OEHasPackage |
11 | 12 | ||
12 | class StapTest(OERuntimeTestCase): | 13 | class StapTest(OERuntimeTestCase): |
13 | 14 | @skipIfNotFeature('tools-profile', 'Test requires tools-profile to be in IMAGE_FEATURES') | |
14 | @classmethod | ||
15 | def setUp(cls): | ||
16 | src = os.path.join(cls.tc.runtime_files_dir, 'hello.stp') | ||
17 | dst = '/tmp/hello.stp' | ||
18 | cls.tc.target.copyTo(src, dst) | ||
19 | |||
20 | @classmethod | ||
21 | def tearDown(cls): | ||
22 | files = '/tmp/hello.stp' | ||
23 | cls.tc.target.run('rm %s' % files) | ||
24 | |||
25 | @skipIfNotFeature('tools-profile', | ||
26 | 'Test requires tools-profile to be in IMAGE_FEATURES') | ||
27 | @OETestDepends(['kernelmodule.KernelModuleTest.test_kernel_module']) | ||
28 | @OEHasPackage(['systemtap']) | 15 | @OEHasPackage(['systemtap']) |
16 | @OEHasPackage(['gcc-symlinks']) | ||
17 | @OEHasPackage(['kernel-devsrc']) | ||
29 | def test_stap(self): | 18 | def test_stap(self): |
30 | cmds = [ | 19 | try: |
31 | 'cd /usr/src/kernel && make scripts prepare', | 20 | cmd = 'make -j -C /usr/src/kernel scripts prepare' |
32 | 'cd /lib/modules/`uname -r` && (if [ ! -e build ]; then ln -s /usr/src/kernel build; fi)', | ||
33 | 'stap --disable-cache -DSTP_NO_VERREL_CHECK /tmp/hello.stp' | ||
34 | ] | ||
35 | for cmd in cmds: | ||
36 | status, output = self.target.run(cmd, 900) | 21 | status, output = self.target.run(cmd, 900) |
37 | self.assertEqual(status, 0, msg='\n'.join([cmd, output])) | 22 | self.assertEqual(status, 0, msg='\n'.join([cmd, output])) |
23 | |||
24 | cmd = 'stap -v -p4 -m stap-hello --disable-cache -DSTP_NO_VERREL_CHECK -e \'probe oneshot { print("Hello, "); println("SystemTap!") }\'' | ||
25 | status, output = self.target.run(cmd, 900) | ||
26 | self.assertEqual(status, 0, msg='\n'.join([cmd, output])) | ||
27 | |||
28 | cmd = 'staprun -v -R -b1 stap-hello.ko' | ||
29 | self.assertEqual(status, 0, msg='\n'.join([cmd, output])) | ||
30 | self.assertIn('Hello, SystemTap!', output, msg='\n'.join([cmd, output])) | ||
31 | except: | ||
32 | status, dmesg = self.target.run('dmesg') | ||
33 | if status == 0: | ||
34 | print(dmesg) | ||
diff --git a/meta/lib/oeqa/runtime/cases/storage.py b/meta/lib/oeqa/runtime/cases/storage.py index 166d26b252..b05622fea8 100644 --- a/meta/lib/oeqa/runtime/cases/storage.py +++ b/meta/lib/oeqa/runtime/cases/storage.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
@@ -91,24 +93,24 @@ class UsbTest(StorageBase): | |||
91 | self.test_file = "usb.tst" | 93 | self.test_file = "usb.tst" |
92 | self.test_dir = os.path.join(self.mount_point, "oeqa") | 94 | self.test_dir = os.path.join(self.mount_point, "oeqa") |
93 | 95 | ||
94 | @skipIfQemu('qemuall', 'Test only runs on real hardware') | 96 | @skipIfQemu() |
95 | @OETestDepends(['ssh.SSHTest.test_ssh']) | 97 | @OETestDepends(['ssh.SSHTest.test_ssh']) |
96 | def test_usb_mount(self): | 98 | def test_usb_mount(self): |
97 | self.storage_umount(2) | 99 | self.storage_umount(2) |
98 | self.storage_mount(5) | 100 | self.storage_mount(5) |
99 | 101 | ||
100 | @skipIfQemu('qemuall', 'Test only runs on real hardware') | 102 | @skipIfQemu() |
101 | @OETestDepends(['storage.UsbTest.test_usb_mount']) | 103 | @OETestDepends(['storage.UsbTest.test_usb_mount']) |
102 | def test_usb_basic_operations(self): | 104 | def test_usb_basic_operations(self): |
103 | self.storage_basic() | 105 | self.storage_basic() |
104 | 106 | ||
105 | @skipIfQemu('qemuall', 'Test only runs on real hardware') | 107 | @skipIfQemu() |
106 | @OETestDepends(['storage.UsbTest.test_usb_basic_operations']) | 108 | @OETestDepends(['storage.UsbTest.test_usb_basic_operations']) |
107 | def test_usb_basic_rw(self): | 109 | def test_usb_basic_rw(self): |
108 | self.storage_write() | 110 | self.storage_write() |
109 | self.storage_read() | 111 | self.storage_read() |
110 | 112 | ||
111 | @skipIfQemu('qemuall', 'Test only runs on real hardware') | 113 | @skipIfQemu() |
112 | @OETestDepends(['storage.UsbTest.test_usb_mount']) | 114 | @OETestDepends(['storage.UsbTest.test_usb_mount']) |
113 | def test_usb_umount(self): | 115 | def test_usb_umount(self): |
114 | self.storage_umount(2) | 116 | self.storage_umount(2) |
@@ -126,24 +128,24 @@ class MMCTest(StorageBase): | |||
126 | self.test_file = "mmc.tst" | 128 | self.test_file = "mmc.tst" |
127 | self.test_dir = os.path.join(self.mount_point, "oeqa") | 129 | self.test_dir = os.path.join(self.mount_point, "oeqa") |
128 | 130 | ||
129 | @skipIfQemu('qemuall', 'Test only runs on real hardware') | 131 | @skipIfQemu() |
130 | @OETestDepends(['ssh.SSHTest.test_ssh']) | 132 | @OETestDepends(['ssh.SSHTest.test_ssh']) |
131 | def test_mmc_mount(self): | 133 | def test_mmc_mount(self): |
132 | self.storage_umount(2) | 134 | self.storage_umount(2) |
133 | self.storage_mount() | 135 | self.storage_mount() |
134 | 136 | ||
135 | @skipIfQemu('qemuall', 'Test only runs on real hardware') | 137 | @skipIfQemu() |
136 | @OETestDepends(['storage.MMCTest.test_mmc_mount']) | 138 | @OETestDepends(['storage.MMCTest.test_mmc_mount']) |
137 | def test_mmc_basic_operations(self): | 139 | def test_mmc_basic_operations(self): |
138 | self.storage_basic() | 140 | self.storage_basic() |
139 | 141 | ||
140 | @skipIfQemu('qemuall', 'Test only runs on real hardware') | 142 | @skipIfQemu() |
141 | @OETestDepends(['storage.MMCTest.test_mmc_basic_operations']) | 143 | @OETestDepends(['storage.MMCTest.test_mmc_basic_operations']) |
142 | def test_mmc_basic_rw(self): | 144 | def test_mmc_basic_rw(self): |
143 | self.storage_write() | 145 | self.storage_write() |
144 | self.storage_read() | 146 | self.storage_read() |
145 | 147 | ||
146 | @skipIfQemu('qemuall', 'Test only runs on real hardware') | 148 | @skipIfQemu() |
147 | @OETestDepends(['storage.MMCTest.test_mmc_mount']) | 149 | @OETestDepends(['storage.MMCTest.test_mmc_mount']) |
148 | def test_mmc_umount(self): | 150 | def test_mmc_umount(self): |
149 | self.storage_umount(2) | 151 | self.storage_umount(2) |
diff --git a/meta/lib/oeqa/runtime/cases/suspend.py b/meta/lib/oeqa/runtime/cases/suspend.py index 67b6f7e56f..a625cc5901 100644 --- a/meta/lib/oeqa/runtime/cases/suspend.py +++ b/meta/lib/oeqa/runtime/cases/suspend.py | |||
@@ -1,3 +1,8 @@ | |||
1 | # | ||
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
4 | # SPDX-License-Identifier: MIT | ||
5 | # | ||
1 | from oeqa.runtime.case import OERuntimeTestCase | 6 | from oeqa.runtime.case import OERuntimeTestCase |
2 | from oeqa.core.decorator.depends import OETestDepends | 7 | from oeqa.core.decorator.depends import OETestDepends |
3 | from oeqa.core.decorator.data import skipIfQemu | 8 | from oeqa.core.decorator.data import skipIfQemu |
@@ -23,7 +28,7 @@ class Suspend_Test(OERuntimeTestCase): | |||
23 | (status, output) = self.target.run('sudo rtcwake -m mem -s 10') | 28 | (status, output) = self.target.run('sudo rtcwake -m mem -s 10') |
24 | self.assertEqual(status, 0, msg = 'Failed to suspends your system to RAM, output : %s' % output) | 29 | self.assertEqual(status, 0, msg = 'Failed to suspends your system to RAM, output : %s' % output) |
25 | 30 | ||
26 | @skipIfQemu('qemuall', 'Test only runs on real hardware') | 31 | @skipIfQemu() |
27 | @OETestDepends(['ssh.SSHTest.test_ssh']) | 32 | @OETestDepends(['ssh.SSHTest.test_ssh']) |
28 | def test_suspend(self): | 33 | def test_suspend(self): |
29 | self.test_date() | 34 | self.test_date() |
diff --git a/meta/lib/oeqa/runtime/cases/systemd.py b/meta/lib/oeqa/runtime/cases/systemd.py index 7c44abe8ed..5481e1d840 100644 --- a/meta/lib/oeqa/runtime/cases/systemd.py +++ b/meta/lib/oeqa/runtime/cases/systemd.py | |||
@@ -1,8 +1,11 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
5 | import re | 7 | import re |
8 | import threading | ||
6 | import time | 9 | import time |
7 | 10 | ||
8 | from oeqa.runtime.case import OERuntimeTestCase | 11 | from oeqa.runtime.case import OERuntimeTestCase |
@@ -66,8 +69,8 @@ class SystemdBasicTests(SystemdTest): | |||
66 | """ | 69 | """ |
67 | endtime = time.time() + (60 * 2) | 70 | endtime = time.time() + (60 * 2) |
68 | while True: | 71 | while True: |
69 | status, output = self.target.run('SYSTEMD_BUS_TIMEOUT=240s systemctl --state=activating') | 72 | status, output = self.target.run('SYSTEMD_BUS_TIMEOUT=240s systemctl is-system-running') |
70 | if "0 loaded units listed" in output: | 73 | if "running" in output or "degraded" in output: |
71 | return (True, '') | 74 | return (True, '') |
72 | if time.time() >= endtime: | 75 | if time.time() >= endtime: |
73 | return (False, output) | 76 | return (False, output) |
@@ -134,6 +137,27 @@ class SystemdServiceTests(SystemdTest): | |||
134 | status = self.target.run('mount -oro,remount /')[0] | 137 | status = self.target.run('mount -oro,remount /')[0] |
135 | self.assertTrue(status == 0, msg='Remounting / as r/o failed') | 138 | self.assertTrue(status == 0, msg='Remounting / as r/o failed') |
136 | 139 | ||
140 | @OETestDepends(['systemd.SystemdBasicTests.test_systemd_basic']) | ||
141 | @skipIfNotFeature('minidebuginfo', 'Test requires minidebuginfo to be in DISTRO_FEATURES') | ||
142 | @OEHasPackage(['busybox']) | ||
143 | def test_systemd_coredump_minidebuginfo(self): | ||
144 | """ | ||
145 | Verify that call-stacks generated by systemd-coredump contain symbolicated call-stacks, | ||
146 | extracted from the minidebuginfo metadata (.gnu_debugdata elf section). | ||
147 | """ | ||
148 | t_thread = threading.Thread(target=self.target.run, args=("ulimit -c unlimited && sleep 1000",)) | ||
149 | t_thread.start() | ||
150 | time.sleep(1) | ||
151 | |||
152 | status, output = self.target.run('pidof sleep') | ||
153 | # cause segfault on purpose | ||
154 | self.target.run('kill -SEGV %s' % output) | ||
155 | self.assertEqual(status, 0, msg = 'Not able to find process that runs sleep, output : %s' % output) | ||
156 | |||
157 | (status, output) = self.target.run('coredumpctl info') | ||
158 | self.assertEqual(status, 0, msg='MiniDebugInfo Test failed: %s' % output) | ||
159 | self.assertEqual('sleep_for_duration (busybox.nosuid' in output, True, msg='Call stack is missing minidebuginfo symbols (functions shown as "n/a"): %s' % output) | ||
160 | |||
137 | class SystemdJournalTests(SystemdTest): | 161 | class SystemdJournalTests(SystemdTest): |
138 | 162 | ||
139 | @OETestDepends(['systemd.SystemdBasicTests.test_systemd_basic']) | 163 | @OETestDepends(['systemd.SystemdBasicTests.test_systemd_basic']) |
@@ -152,7 +176,7 @@ class SystemdJournalTests(SystemdTest): | |||
152 | """ | 176 | """ |
153 | 177 | ||
154 | # The expression chain that uniquely identifies the time boot message. | 178 | # The expression chain that uniquely identifies the time boot message. |
155 | expr_items=['Startup finished', 'kernel', 'userspace','\.$'] | 179 | expr_items=['Startup finished', 'kernel', 'userspace', r'\.$'] |
156 | try: | 180 | try: |
157 | output = self.journalctl(args='-o cat --reverse') | 181 | output = self.journalctl(args='-o cat --reverse') |
158 | except AssertionError: | 182 | except AssertionError: |
diff --git a/meta/lib/oeqa/runtime/cases/terminal.py b/meta/lib/oeqa/runtime/cases/terminal.py index 8fcca99f47..96ba3c3195 100644 --- a/meta/lib/oeqa/runtime/cases/terminal.py +++ b/meta/lib/oeqa/runtime/cases/terminal.py | |||
@@ -1,3 +1,8 @@ | |||
1 | # | ||
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
4 | # SPDX-License-Identifier: MIT | ||
5 | # | ||
1 | from oeqa.runtime.case import OERuntimeTestCase | 6 | from oeqa.runtime.case import OERuntimeTestCase |
2 | from oeqa.core.decorator.depends import OETestDepends | 7 | from oeqa.core.decorator.depends import OETestDepends |
3 | from oeqa.runtime.decorator.package import OEHasPackage | 8 | from oeqa.runtime.decorator.package import OEHasPackage |
diff --git a/meta/lib/oeqa/runtime/cases/usb_hid.py b/meta/lib/oeqa/runtime/cases/usb_hid.py index 3c292cf661..6f23d2ff51 100644 --- a/meta/lib/oeqa/runtime/cases/usb_hid.py +++ b/meta/lib/oeqa/runtime/cases/usb_hid.py | |||
@@ -1,3 +1,8 @@ | |||
1 | # | ||
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
4 | # SPDX-License-Identifier: MIT | ||
5 | # | ||
1 | from oeqa.runtime.case import OERuntimeTestCase | 6 | from oeqa.runtime.case import OERuntimeTestCase |
2 | from oeqa.core.decorator.depends import OETestDepends | 7 | from oeqa.core.decorator.depends import OETestDepends |
3 | from oeqa.core.decorator.data import skipIfQemu | 8 | from oeqa.core.decorator.data import skipIfQemu |
@@ -14,7 +19,7 @@ class USB_HID_Test(OERuntimeTestCase): | |||
14 | return self.assertEqual(status, 0, msg = 'Failed to suspends your system to RAM, output : %s' % output) | 19 | return self.assertEqual(status, 0, msg = 'Failed to suspends your system to RAM, output : %s' % output) |
15 | 20 | ||
16 | @OEHasPackage(['xdotool']) | 21 | @OEHasPackage(['xdotool']) |
17 | @skipIfQemu('qemuall', 'Test only runs on real hardware') | 22 | @skipIfQemu() |
18 | @OETestDepends(['ssh.SSHTest.test_ssh']) | 23 | @OETestDepends(['ssh.SSHTest.test_ssh']) |
19 | def test_USB_Hid_input(self): | 24 | def test_USB_Hid_input(self): |
20 | self.keyboard_mouse_simulation() | 25 | self.keyboard_mouse_simulation() |
diff --git a/meta/lib/oeqa/runtime/cases/weston.py b/meta/lib/oeqa/runtime/cases/weston.py index a1c7183213..ee4d336482 100644 --- a/meta/lib/oeqa/runtime/cases/weston.py +++ b/meta/lib/oeqa/runtime/cases/weston.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
@@ -10,7 +12,7 @@ import threading | |||
10 | import time | 12 | import time |
11 | 13 | ||
12 | class WestonTest(OERuntimeTestCase): | 14 | class WestonTest(OERuntimeTestCase): |
13 | weston_log_file = '/tmp/weston.log' | 15 | weston_log_file = '/tmp/weston-2.log' |
14 | 16 | ||
15 | @classmethod | 17 | @classmethod |
16 | def tearDownClass(cls): | 18 | def tearDownClass(cls): |
@@ -31,13 +33,13 @@ class WestonTest(OERuntimeTestCase): | |||
31 | return output.split(" ") | 33 | return output.split(" ") |
32 | 34 | ||
33 | def get_weston_command(self, cmd): | 35 | def get_weston_command(self, cmd): |
34 | return 'export XDG_RUNTIME_DIR=/run/user/0; export WAYLAND_DISPLAY=wayland-0; %s' % cmd | 36 | return 'export XDG_RUNTIME_DIR=/run/user/`id -u weston`; export WAYLAND_DISPLAY=wayland-1; %s' % cmd |
35 | 37 | ||
36 | def run_weston_init(self): | 38 | def run_weston_init(self): |
37 | if 'systemd' in self.tc.td['VIRTUAL-RUNTIME_init_manager']: | 39 | if 'systemd' in self.tc.td['VIRTUAL-RUNTIME_init_manager']: |
38 | self.target.run('systemd-run --collect --unit=weston-ptest.service --uid=0 -p PAMName=login -p TTYPath=/dev/tty6 -E XDG_RUNTIME_DIR=/tmp -E WAYLAND_DISPLAY=wayland-0 /usr/bin/weston --socket=wayland-1 --log=%s' % self.weston_log_file) | 40 | self.target.run('systemd-run --collect --unit=weston-ptest.service --uid=0 -p PAMName=login -p TTYPath=/dev/tty6 -E XDG_RUNTIME_DIR=/tmp -E WAYLAND_DISPLAY=wayland-0 /usr/bin/weston --socket=wayland-1 --log=%s' % self.weston_log_file) |
39 | else: | 41 | else: |
40 | self.target.run(self.get_weston_command('openvt -- weston --socket=wayland-1 --log=%s' % self.weston_log_file)) | 42 | self.target.run(self.get_weston_command('openvt -- weston --socket=wayland-2 --log=%s' % self.weston_log_file)) |
41 | 43 | ||
42 | def get_new_wayland_processes(self, existing_wl_processes): | 44 | def get_new_wayland_processes(self, existing_wl_processes): |
43 | try_cnt = 0 | 45 | try_cnt = 0 |
@@ -53,7 +55,11 @@ class WestonTest(OERuntimeTestCase): | |||
53 | 55 | ||
54 | @OEHasPackage(['wayland-utils']) | 56 | @OEHasPackage(['wayland-utils']) |
55 | def test_wayland_info(self): | 57 | def test_wayland_info(self): |
56 | status, output = self.target.run(self.get_weston_command('wayland-info')) | 58 | if 'systemd' in self.tc.td['VIRTUAL-RUNTIME_init_manager']: |
59 | command = 'XDG_RUNTIME_DIR=/run wayland-info' | ||
60 | else: | ||
61 | command = self.get_weston_command('wayland-info') | ||
62 | status, output = self.target.run(command) | ||
57 | self.assertEqual(status, 0, msg='wayland-info error: %s' % output) | 63 | self.assertEqual(status, 0, msg='wayland-info error: %s' % output) |
58 | 64 | ||
59 | @OEHasPackage(['weston']) | 65 | @OEHasPackage(['weston']) |
@@ -73,3 +79,11 @@ class WestonTest(OERuntimeTestCase): | |||
73 | self.target.run('kill -9 %s' % w) | 79 | self.target.run('kill -9 %s' % w) |
74 | __, weston_log = self.target.run('cat %s' % self.weston_log_file) | 80 | __, weston_log = self.target.run('cat %s' % self.weston_log_file) |
75 | self.assertTrue(new_wl_processes, msg='Could not get new weston-desktop-shell processes (%s, try_cnt:%s) weston log: %s' % (new_wl_processes, try_cnt, weston_log)) | 81 | self.assertTrue(new_wl_processes, msg='Could not get new weston-desktop-shell processes (%s, try_cnt:%s) weston log: %s' % (new_wl_processes, try_cnt, weston_log)) |
82 | |||
83 | @skipIfNotFeature('x11', 'Test requires x11 to be in DISTRO_FEATURES') | ||
84 | @OEHasPackage(['weston']) | ||
85 | def test_weston_supports_xwayland(self): | ||
86 | cmd ='cat %s | grep "xserver listening on display"' % self.weston_log_file | ||
87 | status, output = self.target.run(cmd) | ||
88 | msg = ('xwayland does not appear to be running') | ||
89 | self.assertEqual(status, 0, msg=msg) | ||
diff --git a/meta/lib/oeqa/runtime/cases/x32lib.py b/meta/lib/oeqa/runtime/cases/x32lib.py index f419c8f181..014da4b386 100644 --- a/meta/lib/oeqa/runtime/cases/x32lib.py +++ b/meta/lib/oeqa/runtime/cases/x32lib.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
diff --git a/meta/lib/oeqa/runtime/cases/xorg.py b/meta/lib/oeqa/runtime/cases/xorg.py index d6845587c2..09afb1e3d1 100644 --- a/meta/lib/oeqa/runtime/cases/xorg.py +++ b/meta/lib/oeqa/runtime/cases/xorg.py | |||
@@ -1,4 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
3 | # | 5 | # |
4 | 6 | ||
diff --git a/meta/lib/oeqa/runtime/context.py b/meta/lib/oeqa/runtime/context.py index 3826f27642..cb7227a8df 100644 --- a/meta/lib/oeqa/runtime/context.py +++ b/meta/lib/oeqa/runtime/context.py | |||
@@ -5,11 +5,11 @@ | |||
5 | # | 5 | # |
6 | 6 | ||
7 | import os | 7 | import os |
8 | import sys | ||
8 | 9 | ||
9 | from oeqa.core.context import OETestContext, OETestContextExecutor | 10 | from oeqa.core.context import OETestContext, OETestContextExecutor |
10 | from oeqa.core.target.ssh import OESSHTarget | 11 | from oeqa.core.target.ssh import OESSHTarget |
11 | from oeqa.core.target.qemu import OEQemuTarget | 12 | from oeqa.core.target.qemu import OEQemuTarget |
12 | from oeqa.utils.dump import HostDumper | ||
13 | 13 | ||
14 | from oeqa.runtime.loader import OERuntimeTestLoader | 14 | from oeqa.runtime.loader import OERuntimeTestLoader |
15 | 15 | ||
@@ -19,12 +19,11 @@ class OERuntimeTestContext(OETestContext): | |||
19 | os.path.dirname(os.path.abspath(__file__)), "files") | 19 | os.path.dirname(os.path.abspath(__file__)), "files") |
20 | 20 | ||
21 | def __init__(self, td, logger, target, | 21 | def __init__(self, td, logger, target, |
22 | host_dumper, image_packages, extract_dir): | 22 | image_packages, extract_dir): |
23 | super(OERuntimeTestContext, self).__init__(td, logger) | 23 | super(OERuntimeTestContext, self).__init__(td, logger) |
24 | 24 | ||
25 | self.target = target | 25 | self.target = target |
26 | self.image_packages = image_packages | 26 | self.image_packages = image_packages |
27 | self.host_dumper = host_dumper | ||
28 | self.extract_dir = extract_dir | 27 | self.extract_dir = extract_dir |
29 | self._set_target_cmds() | 28 | self._set_target_cmds() |
30 | 29 | ||
@@ -66,11 +65,11 @@ class OERuntimeTestContextExecutor(OETestContextExecutor): | |||
66 | % self.default_target_type) | 65 | % self.default_target_type) |
67 | runtime_group.add_argument('--target-ip', action='store', | 66 | runtime_group.add_argument('--target-ip', action='store', |
68 | default=self.default_target_ip, | 67 | default=self.default_target_ip, |
69 | help="IP address of device under test, default: %s" \ | 68 | help="IP address and optionally ssh port (default 22) of device under test, for example '192.168.0.7:22'. Default: %s" \ |
70 | % self.default_target_ip) | 69 | % self.default_target_ip) |
71 | runtime_group.add_argument('--server-ip', action='store', | 70 | runtime_group.add_argument('--server-ip', action='store', |
72 | default=self.default_target_ip, | 71 | default=self.default_target_ip, |
73 | help="IP address of device under test, default: %s" \ | 72 | help="IP address of the test host from test target machine, default: %s" \ |
74 | % self.default_server_ip) | 73 | % self.default_server_ip) |
75 | 74 | ||
76 | runtime_group.add_argument('--host-dumper-dir', action='store', | 75 | runtime_group.add_argument('--host-dumper-dir', action='store', |
@@ -119,8 +118,7 @@ class OERuntimeTestContextExecutor(OETestContextExecutor): | |||
119 | # XXX: Don't base your targets on this code it will be refactored | 118 | # XXX: Don't base your targets on this code it will be refactored |
120 | # in the near future. | 119 | # in the near future. |
121 | # Custom target module loading | 120 | # Custom target module loading |
122 | target_modules_path = kwargs.get('target_modules_path', '') | 121 | controller = OERuntimeTestContextExecutor.getControllerModule(target_type) |
123 | controller = OERuntimeTestContextExecutor.getControllerModule(target_type, target_modules_path) | ||
124 | target = controller(logger, target_ip, server_ip, **kwargs) | 122 | target = controller(logger, target_ip, server_ip, **kwargs) |
125 | 123 | ||
126 | return target | 124 | return target |
@@ -130,15 +128,15 @@ class OERuntimeTestContextExecutor(OETestContextExecutor): | |||
130 | # AttributeError raised if not found. | 128 | # AttributeError raised if not found. |
131 | # ImportError raised if a provided module can not be imported. | 129 | # ImportError raised if a provided module can not be imported. |
132 | @staticmethod | 130 | @staticmethod |
133 | def getControllerModule(target, target_modules_path): | 131 | def getControllerModule(target): |
134 | controllerslist = OERuntimeTestContextExecutor._getControllerModulenames(target_modules_path) | 132 | controllerslist = OERuntimeTestContextExecutor._getControllerModulenames() |
135 | controller = OERuntimeTestContextExecutor._loadControllerFromName(target, controllerslist) | 133 | controller = OERuntimeTestContextExecutor._loadControllerFromName(target, controllerslist) |
136 | return controller | 134 | return controller |
137 | 135 | ||
138 | # Return a list of all python modules in lib/oeqa/controllers for each | 136 | # Return a list of all python modules in lib/oeqa/controllers for each |
139 | # layer in bbpath | 137 | # layer in bbpath |
140 | @staticmethod | 138 | @staticmethod |
141 | def _getControllerModulenames(target_modules_path): | 139 | def _getControllerModulenames(): |
142 | 140 | ||
143 | controllerslist = [] | 141 | controllerslist = [] |
144 | 142 | ||
@@ -153,9 +151,12 @@ class OERuntimeTestContextExecutor(OETestContextExecutor): | |||
153 | else: | 151 | else: |
154 | raise RuntimeError("Duplicate controller module found for %s. Layers should create unique controller module names" % module) | 152 | raise RuntimeError("Duplicate controller module found for %s. Layers should create unique controller module names" % module) |
155 | 153 | ||
156 | extpath = target_modules_path.split(':') | 154 | # sys.path can contain duplicate paths, but because of the login in |
157 | for p in extpath: | 155 | # add_controller_list this doesn't work and causes testimage to abort. |
158 | controllerpath = os.path.join(p, 'lib', 'oeqa', 'controllers') | 156 | # Remove duplicates using an intermediate dictionary to ensure this |
157 | # doesn't happen. | ||
158 | for p in list(dict.fromkeys(sys.path)): | ||
159 | controllerpath = os.path.join(p, 'oeqa', 'controllers') | ||
159 | if os.path.exists(controllerpath): | 160 | if os.path.exists(controllerpath): |
160 | add_controller_list(controllerpath) | 161 | add_controller_list(controllerpath) |
161 | return controllerslist | 162 | return controllerslist |
@@ -175,16 +176,12 @@ class OERuntimeTestContextExecutor(OETestContextExecutor): | |||
175 | # Search for and return a controller or None from given module name | 176 | # Search for and return a controller or None from given module name |
176 | @staticmethod | 177 | @staticmethod |
177 | def _loadControllerFromModule(target, modulename): | 178 | def _loadControllerFromModule(target, modulename): |
178 | obj = None | ||
179 | # import module, allowing it to raise import exception | ||
180 | module = __import__(modulename, globals(), locals(), [target]) | ||
181 | # look for target class in the module, catching any exceptions as it | ||
182 | # is valid that a module may not have the target class. | ||
183 | try: | 179 | try: |
184 | obj = getattr(module, target) | 180 | import importlib |
185 | except: | 181 | module = importlib.import_module(modulename) |
186 | obj = None | 182 | return getattr(module, target) |
187 | return obj | 183 | except AttributeError: |
184 | return None | ||
188 | 185 | ||
189 | @staticmethod | 186 | @staticmethod |
190 | def readPackagesManifest(manifest): | 187 | def readPackagesManifest(manifest): |
@@ -200,10 +197,6 @@ class OERuntimeTestContextExecutor(OETestContextExecutor): | |||
200 | 197 | ||
201 | return image_packages | 198 | return image_packages |
202 | 199 | ||
203 | @staticmethod | ||
204 | def getHostDumper(cmds, directory): | ||
205 | return HostDumper(cmds, directory) | ||
206 | |||
207 | def _process_args(self, logger, args): | 200 | def _process_args(self, logger, args): |
208 | if not args.packages_manifest: | 201 | if not args.packages_manifest: |
209 | raise TypeError('Manifest file not provided') | 202 | raise TypeError('Manifest file not provided') |
@@ -216,9 +209,6 @@ class OERuntimeTestContextExecutor(OETestContextExecutor): | |||
216 | self.tc_kwargs['init']['target'] = \ | 209 | self.tc_kwargs['init']['target'] = \ |
217 | OERuntimeTestContextExecutor.getTarget(args.target_type, | 210 | OERuntimeTestContextExecutor.getTarget(args.target_type, |
218 | None, args.target_ip, args.server_ip, **target_kwargs) | 211 | None, args.target_ip, args.server_ip, **target_kwargs) |
219 | self.tc_kwargs['init']['host_dumper'] = \ | ||
220 | OERuntimeTestContextExecutor.getHostDumper(None, | ||
221 | args.host_dumper_dir) | ||
222 | self.tc_kwargs['init']['image_packages'] = \ | 212 | self.tc_kwargs['init']['image_packages'] = \ |
223 | OERuntimeTestContextExecutor.readPackagesManifest( | 213 | OERuntimeTestContextExecutor.readPackagesManifest( |
224 | args.packages_manifest) | 214 | args.packages_manifest) |
diff --git a/meta/lib/oeqa/runtime/decorator/package.py b/meta/lib/oeqa/runtime/decorator/package.py index 57178655cc..b78ac9fc38 100644 --- a/meta/lib/oeqa/runtime/decorator/package.py +++ b/meta/lib/oeqa/runtime/decorator/package.py | |||
@@ -5,7 +5,6 @@ | |||
5 | # | 5 | # |
6 | 6 | ||
7 | from oeqa.core.decorator import OETestDecorator, registerDecorator | 7 | from oeqa.core.decorator import OETestDecorator, registerDecorator |
8 | from oeqa.core.utils.misc import strToSet | ||
9 | 8 | ||
10 | @registerDecorator | 9 | @registerDecorator |
11 | class OEHasPackage(OETestDecorator): | 10 | class OEHasPackage(OETestDecorator): |
@@ -34,25 +33,30 @@ class OEHasPackage(OETestDecorator): | |||
34 | def setUpDecorator(self): | 33 | def setUpDecorator(self): |
35 | need_pkgs = set() | 34 | need_pkgs = set() |
36 | unneed_pkgs = set() | 35 | unneed_pkgs = set() |
37 | pkgs = strToSet(self.need_pkgs) | 36 | |
38 | for pkg in pkgs: | 37 | # Turn literal strings into a list so we can just iterate over it |
38 | if isinstance(self.need_pkgs, str): | ||
39 | self.need_pkgs = [self.need_pkgs,] | ||
40 | |||
41 | mlprefix = self.case.td.get("MLPREFIX") | ||
42 | for pkg in self.need_pkgs: | ||
39 | if pkg.startswith('!'): | 43 | if pkg.startswith('!'): |
40 | unneed_pkgs.add(pkg[1:]) | 44 | unneed_pkgs.add(mlprefix + pkg[1:]) |
41 | else: | 45 | else: |
42 | need_pkgs.add(pkg) | 46 | need_pkgs.add(mlprefix + pkg) |
43 | 47 | ||
44 | if unneed_pkgs: | 48 | if unneed_pkgs: |
45 | msg = 'Checking if %s is not installed' % ', '.join(unneed_pkgs) | 49 | msg = 'Checking if %s is not installed' % ', '.join(unneed_pkgs) |
46 | self.logger.debug(msg) | 50 | self.logger.debug(msg) |
47 | if not self.case.tc.image_packages.isdisjoint(unneed_pkgs): | 51 | if not self.case.tc.image_packages.isdisjoint(unneed_pkgs): |
48 | msg = "Test can't run with %s installed" % ', or'.join(unneed_pkgs) | 52 | msg = "Test can't run with %s installed" % ', or '.join(unneed_pkgs) |
49 | self._decorator_fail(msg) | 53 | self._decorator_fail(msg) |
50 | 54 | ||
51 | if need_pkgs: | 55 | if need_pkgs: |
52 | msg = 'Checking if at least one of %s is installed' % ', '.join(need_pkgs) | 56 | msg = 'Checking if at least one of %s is installed' % ', '.join(need_pkgs) |
53 | self.logger.debug(msg) | 57 | self.logger.debug(msg) |
54 | if self.case.tc.image_packages.isdisjoint(need_pkgs): | 58 | if self.case.tc.image_packages.isdisjoint(need_pkgs): |
55 | msg = "Test requires %s to be installed" % ', or'.join(need_pkgs) | 59 | msg = "Test requires %s to be installed" % ', or '.join(need_pkgs) |
56 | self._decorator_fail(msg) | 60 | self._decorator_fail(msg) |
57 | 61 | ||
58 | def _decorator_fail(self, msg): | 62 | def _decorator_fail(self, msg): |
diff --git a/meta/lib/oeqa/runtime/files/hello.stp b/meta/lib/oeqa/runtime/files/hello.stp deleted file mode 100644 index 3677147162..0000000000 --- a/meta/lib/oeqa/runtime/files/hello.stp +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | probe oneshot { println("hello world") } | ||