Complete Yocto mirror with license table for TQMa6UL (2038-compliance)
- 264 license table entries with exact download URLs (224/264 resolved) - Complete sources/ directory with all BitBake recipes - Build configuration: tqma6ul-multi-mba6ulx, spaetzle (musl) - Full traceability for Softwarefreigabeantrag - GCC 13.4.0, Linux 6.6.102, U-Boot 2023.04, musl 1.2.4 - License distribution: GPL-2.0 (24), MIT (23), GPL-2.0+ (18), BSD-3 (16)
This commit is contained in:
20
sources/poky/meta/lib/oeqa/runtime/case.py
Normal file
20
sources/poky/meta/lib/oeqa/runtime/case.py
Normal file
@@ -0,0 +1,20 @@
|
||||
#
|
||||
# Copyright (C) 2016 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
from oeqa.core.case import OETestCase
|
||||
from oeqa.utils.package_manager import install_package, uninstall_package
|
||||
|
||||
class OERuntimeTestCase(OETestCase):
|
||||
# target instance set by OERuntimeTestLoader.
|
||||
target = None
|
||||
|
||||
def setUp(self):
|
||||
super(OERuntimeTestCase, self).setUp()
|
||||
install_package(self)
|
||||
|
||||
def tearDown(self):
|
||||
super(OERuntimeTestCase, self).tearDown()
|
||||
uninstall_package(self)
|
||||
19
sources/poky/meta/lib/oeqa/runtime/cases/_qemutiny.py
Normal file
19
sources/poky/meta/lib/oeqa/runtime/cases/_qemutiny.py
Normal file
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.target.qemu import OEQemuTarget
|
||||
|
||||
class QemuTinyTest(OERuntimeTestCase):
|
||||
|
||||
def test_boot_tiny(self):
|
||||
# Until the target has explicit run_serial support, check that the
|
||||
# target is the qemu runner
|
||||
if isinstance(self.target, OEQemuTarget):
|
||||
status, output = self.target.runner.run_serial('uname -a')
|
||||
self.assertIn("Linux", output)
|
||||
else:
|
||||
self.skipTest("Target %s is not OEQemuTarget" % self.target)
|
||||
79
sources/poky/meta/lib/oeqa/runtime/cases/apt.py
Normal file
79
sources/poky/meta/lib/oeqa/runtime/cases/apt.py
Normal file
@@ -0,0 +1,79 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
import os
|
||||
from oeqa.utils.httpserver import HTTPService
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.data import skipIfNotDataVar, skipIfNotFeature
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
class AptTest(OERuntimeTestCase):
|
||||
|
||||
def pkg(self, command, expected = 0):
|
||||
command = 'apt-get %s' % command
|
||||
status, output = self.target.run(command, 1500)
|
||||
message = os.linesep.join([command, output])
|
||||
self.assertEqual(status, expected, message)
|
||||
return output
|
||||
|
||||
class AptRepoTest(AptTest):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
service_repo = os.path.join(cls.tc.td['DEPLOY_DIR_DEB'], '')
|
||||
cls.repo_server = HTTPService(service_repo,
|
||||
'0.0.0.0', port=cls.tc.target.server_port,
|
||||
logger=cls.tc.logger)
|
||||
cls.repo_server.start()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls.repo_server.stop()
|
||||
|
||||
def setup_source_config_for_package_install(self):
|
||||
apt_get_source_server = 'http://%s:%s/' % (self.tc.target.server_ip, self.repo_server.port)
|
||||
apt_get_sourceslist_dir = '/etc/apt/'
|
||||
self.target.run('cd %s; echo deb [ allow-insecure=yes ] %s/all ./ > sources.list' % (apt_get_sourceslist_dir, apt_get_source_server))
|
||||
|
||||
def setup_source_config_for_package_install_signed(self):
|
||||
apt_get_source_server = 'http://%s:%s' % (self.tc.target.server_ip, self.repo_server.port)
|
||||
apt_get_sourceslist_dir = '/etc/apt/'
|
||||
self.target.run("cd %s; 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))
|
||||
|
||||
def cleanup_source_config_for_package_install(self):
|
||||
apt_get_sourceslist_dir = '/etc/apt/'
|
||||
self.target.run('cd %s; rm sources.list' % (apt_get_sourceslist_dir))
|
||||
|
||||
def cleanup_source_config_for_package_install_signed(self):
|
||||
apt_get_sourceslist_dir = '/etc/apt/'
|
||||
self.target.run('cd %s; mv sources.list.bak sources.list' % (apt_get_sourceslist_dir))
|
||||
|
||||
def setup_key(self):
|
||||
# the key is found on the target /etc/pki/packagefeed-gpg/
|
||||
# named PACKAGEFEED-GPG-KEY-poky-branch
|
||||
self.target.run('cd %s; apt-key add P*' % ('/etc/pki/packagefeed-gpg'))
|
||||
|
||||
@skipIfNotFeature('package-management',
|
||||
'Test requires package-management to be in IMAGE_FEATURES')
|
||||
@skipIfNotDataVar('IMAGE_PKGTYPE', 'deb',
|
||||
'DEB is not the primary package manager')
|
||||
@OEHasPackage(['apt'])
|
||||
def test_apt_install_from_repo(self):
|
||||
if not self.tc.td.get('PACKAGE_FEED_GPG_NAME'):
|
||||
self.setup_source_config_for_package_install()
|
||||
self.pkg('update')
|
||||
self.pkg('remove --yes run-postinsts-dev')
|
||||
self.pkg('install --yes --allow-unauthenticated run-postinsts-dev')
|
||||
self.cleanup_source_config_for_package_install()
|
||||
else:
|
||||
# when we are here a key has been set to sign the package feed and
|
||||
# public key and gnupg installed on the image by test_testimage_apt
|
||||
self.setup_source_config_for_package_install_signed()
|
||||
self.setup_key()
|
||||
self.pkg('update')
|
||||
self.pkg('install --yes run-postinsts-dev')
|
||||
self.pkg('remove --yes run-postinsts-dev')
|
||||
self.cleanup_source_config_for_package_install_signed()
|
||||
35
sources/poky/meta/lib/oeqa/runtime/cases/boot.py
Normal file
35
sources/poky/meta/lib/oeqa/runtime/cases/boot.py
Normal file
@@ -0,0 +1,35 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
from subprocess import Popen, PIPE
|
||||
import time
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.core.decorator.oetimeout import OETimeout
|
||||
from oeqa.core.decorator.data import skipIfQemu
|
||||
|
||||
class BootTest(OERuntimeTestCase):
|
||||
|
||||
@OETimeout(120)
|
||||
@skipIfQemu()
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
def test_reboot(self):
|
||||
output = ''
|
||||
count = 0
|
||||
(status, output) = self.target.run('reboot -h')
|
||||
while count < 5:
|
||||
time.sleep(5)
|
||||
cmd = 'ping -c 1 %s' % self.target.ip
|
||||
proc = Popen(cmd, shell=True, stdout=PIPE)
|
||||
output += proc.communicate()[0].decode('utf-8')
|
||||
if proc.poll() == 0:
|
||||
count += 1
|
||||
else:
|
||||
count = 0
|
||||
msg = ('Expected 5 consecutive, got %d.\n'
|
||||
'ping output is:\n%s' % (count,output))
|
||||
self.assertEqual(count, 5, msg = msg)
|
||||
34
sources/poky/meta/lib/oeqa/runtime/cases/buildcpio.py
Normal file
34
sources/poky/meta/lib/oeqa/runtime/cases/buildcpio.py
Normal file
@@ -0,0 +1,34 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
from oeqa.runtime.utils.targetbuildproject import TargetBuildProject
|
||||
|
||||
class BuildCpioTest(OERuntimeTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
uri = 'https://downloads.yoctoproject.org/mirror/sources/cpio-2.15.tar.gz'
|
||||
cls.project = TargetBuildProject(cls.tc.target,
|
||||
uri,
|
||||
dl_dir = cls.tc.td['DL_DIR'])
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls.project.clean()
|
||||
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(['gcc'])
|
||||
@OEHasPackage(['make'])
|
||||
@OEHasPackage(['autoconf'])
|
||||
def test_cpio(self):
|
||||
self.project.download_archive()
|
||||
self.project.run_configure()
|
||||
self.project.run_make()
|
||||
self.project.run_install()
|
||||
34
sources/poky/meta/lib/oeqa/runtime/cases/buildgalculator.py
Normal file
34
sources/poky/meta/lib/oeqa/runtime/cases/buildgalculator.py
Normal file
@@ -0,0 +1,34 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
from oeqa.runtime.utils.targetbuildproject import TargetBuildProject
|
||||
|
||||
class GalculatorTest(OERuntimeTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
uri = 'http://galculator.mnim.org/downloads/galculator-2.1.4.tar.bz2'
|
||||
cls.project = TargetBuildProject(cls.tc.target,
|
||||
uri,
|
||||
dl_dir = cls.tc.td['DL_DIR'])
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls.project.clean()
|
||||
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(['gcc'])
|
||||
@OEHasPackage(['make'])
|
||||
@OEHasPackage(['autoconf'])
|
||||
@OEHasPackage(['gtk+3'])
|
||||
def test_galculator(self):
|
||||
self.project.download_archive()
|
||||
self.project.run_configure()
|
||||
self.project.run_make()
|
||||
36
sources/poky/meta/lib/oeqa/runtime/cases/buildlzip.py
Normal file
36
sources/poky/meta/lib/oeqa/runtime/cases/buildlzip.py
Normal file
@@ -0,0 +1,36 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
from oeqa.runtime.utils.targetbuildproject import TargetBuildProject
|
||||
|
||||
class BuildLzipTest(OERuntimeTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
uri = 'http://downloads.yoctoproject.org/mirror/sources'
|
||||
uri = '%s/lzip-1.19.tar.gz' % uri
|
||||
cls.project = TargetBuildProject(cls.tc.target,
|
||||
uri,
|
||||
dl_dir = cls.tc.td['DL_DIR'])
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls.project.clean()
|
||||
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(['gcc'])
|
||||
@OEHasPackage(['make'])
|
||||
@OEHasPackage(['autoconf'])
|
||||
def test_lzip(self):
|
||||
self.project.download_archive()
|
||||
self.project.run_configure()
|
||||
self.project.run_make()
|
||||
self.project.run_install()
|
||||
|
||||
33
sources/poky/meta/lib/oeqa/runtime/cases/connman.py
Normal file
33
sources/poky/meta/lib/oeqa/runtime/cases/connman.py
Normal file
@@ -0,0 +1,33 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
class ConnmanTest(OERuntimeTestCase):
|
||||
|
||||
def service_status(self, service):
|
||||
if 'systemd' in self.tc.td['DISTRO_FEATURES']:
|
||||
(_, output) = self.target.run('systemctl status -l %s' % service)
|
||||
return output
|
||||
else:
|
||||
return "Unable to get status or logs for %s" % service
|
||||
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(["connman"])
|
||||
def test_connmand_help(self):
|
||||
(status, output) = self.target.run('/usr/sbin/connmand --help')
|
||||
msg = 'Failed to get connman help. Output: %s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
@OETestDepends(['connman.ConnmanTest.test_connmand_help'])
|
||||
def test_connmand_running(self):
|
||||
cmd = '%s | grep [c]onnmand' % self.tc.target_cmds['ps']
|
||||
(status, output) = self.target.run(cmd)
|
||||
if status != 0:
|
||||
self.logger.info(self.service_status("connman"))
|
||||
self.fail("No connmand process running")
|
||||
43
sources/poky/meta/lib/oeqa/runtime/cases/date.py
Normal file
43
sources/poky/meta/lib/oeqa/runtime/cases/date.py
Normal file
@@ -0,0 +1,43 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
import re
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
class DateTest(OERuntimeTestCase):
|
||||
|
||||
def setUp(self):
|
||||
if self.tc.td.get('VIRTUAL-RUNTIME_init_manager') == 'systemd':
|
||||
self.logger.debug('Stopping systemd-timesyncd daemon')
|
||||
self.target.run('systemctl disable --now --runtime systemd-timesyncd')
|
||||
|
||||
def tearDown(self):
|
||||
if self.tc.td.get('VIRTUAL-RUNTIME_init_manager') == 'systemd':
|
||||
self.logger.debug('Starting systemd-timesyncd daemon')
|
||||
self.target.run('systemctl enable --now --runtime systemd-timesyncd')
|
||||
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(['coreutils', 'busybox'])
|
||||
def test_date(self):
|
||||
(status, output) = self.target.run('date +"%Y-%m-%d %T"')
|
||||
msg = 'Failed to get initial date, output: %s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
oldDate = output
|
||||
|
||||
sampleTimestamp = 1488800000
|
||||
(status, output) = self.target.run("date -s @%d" % sampleTimestamp)
|
||||
self.assertEqual(status, 0, msg='Date set failed, output: %s' % output)
|
||||
|
||||
(status, output) = self.target.run('date +"%s"')
|
||||
msg = 'The date was not set correctly, output: %s' % output
|
||||
self.assertTrue(int(output) - sampleTimestamp < 300, msg=msg)
|
||||
|
||||
(status, output) = self.target.run('date -s "%s"' % oldDate)
|
||||
msg = 'Failed to reset date, output: %s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
21
sources/poky/meta/lib/oeqa/runtime/cases/df.py
Normal file
21
sources/poky/meta/lib/oeqa/runtime/cases/df.py
Normal file
@@ -0,0 +1,21 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.core.decorator.data import skipIfDataVar, skipIfInDataVar
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
class DfTest(OERuntimeTestCase):
|
||||
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(['coreutils', 'busybox'])
|
||||
@skipIfInDataVar('IMAGE_FEATURES', 'read-only-rootfs', 'Test case df requires a writable rootfs')
|
||||
def test_df(self):
|
||||
cmd = "df -P / | sed -n '2p' | awk '{print $4}'"
|
||||
(status,output) = self.target.run(cmd)
|
||||
msg = 'Not enough space on image. Current size is %s' % output
|
||||
self.assertTrue(int(output)>5120, msg=msg)
|
||||
173
sources/poky/meta/lib/oeqa/runtime/cases/dnf.py
Normal file
173
sources/poky/meta/lib/oeqa/runtime/cases/dnf.py
Normal file
@@ -0,0 +1,173 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
from oeqa.utils.httpserver import HTTPService
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.core.decorator.data import skipIfNotDataVar, skipIfNotFeature, skipIfInDataVar, skipIfNotInDataVar
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
class DnfTest(OERuntimeTestCase):
|
||||
|
||||
def dnf(self, command, expected = 0):
|
||||
command = 'dnf %s' % command
|
||||
status, output = self.target.run(command, 1500)
|
||||
message = os.linesep.join([command, output])
|
||||
self.assertEqual(status, expected, message)
|
||||
return output
|
||||
|
||||
class DnfBasicTest(DnfTest):
|
||||
|
||||
@skipIfNotFeature('package-management',
|
||||
'Test requires package-management to be in IMAGE_FEATURES')
|
||||
@skipIfNotDataVar('IMAGE_PKGTYPE', 'rpm',
|
||||
'RPM is not the primary package manager')
|
||||
@OEHasPackage(['dnf'])
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
def test_dnf_help(self):
|
||||
self.dnf('--help')
|
||||
|
||||
@OETestDepends(['dnf.DnfBasicTest.test_dnf_help'])
|
||||
def test_dnf_version(self):
|
||||
self.dnf('--version')
|
||||
|
||||
@OETestDepends(['dnf.DnfBasicTest.test_dnf_help'])
|
||||
def test_dnf_info(self):
|
||||
self.dnf('info dnf')
|
||||
|
||||
@OETestDepends(['dnf.DnfBasicTest.test_dnf_help'])
|
||||
def test_dnf_search(self):
|
||||
self.dnf('search dnf')
|
||||
|
||||
@OETestDepends(['dnf.DnfBasicTest.test_dnf_help'])
|
||||
def test_dnf_history(self):
|
||||
self.dnf('history')
|
||||
|
||||
class DnfRepoTest(DnfTest):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.repo_server = HTTPService(os.path.join(cls.tc.td['WORKDIR'], 'oe-testimage-repo'),
|
||||
'0.0.0.0', port=cls.tc.target.server_port,
|
||||
logger=cls.tc.logger)
|
||||
cls.repo_server.start()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls.repo_server.stop()
|
||||
|
||||
def dnf_with_repo(self, command):
|
||||
pkgarchs = os.listdir(os.path.join(self.tc.td['WORKDIR'], 'oe-testimage-repo'))
|
||||
deploy_url = 'http://%s:%s/' %(self.target.server_ip, self.repo_server.port)
|
||||
cmdlinerepoopts = ["--repofrompath=oe-testimage-repo-%s,%s%s" %(arch, deploy_url, arch) for arch in pkgarchs]
|
||||
|
||||
output = self.dnf(" ".join(cmdlinerepoopts) + " --nogpgcheck " + command)
|
||||
return output
|
||||
|
||||
@OETestDepends(['dnf.DnfBasicTest.test_dnf_help'])
|
||||
def test_dnf_makecache(self):
|
||||
self.dnf_with_repo('makecache')
|
||||
|
||||
@OETestDepends(['dnf.DnfRepoTest.test_dnf_makecache'])
|
||||
def test_dnf_repoinfo(self):
|
||||
self.dnf_with_repo('repoinfo')
|
||||
|
||||
@OETestDepends(['dnf.DnfRepoTest.test_dnf_makecache'])
|
||||
def test_dnf_install(self):
|
||||
self.dnf_with_repo('remove -y dnf-test-*')
|
||||
self.dnf_with_repo('install -y dnf-test-dep')
|
||||
|
||||
@OETestDepends(['dnf.DnfRepoTest.test_dnf_install'])
|
||||
def test_dnf_install_dependency(self):
|
||||
self.dnf_with_repo('remove -y dnf-test-*')
|
||||
self.dnf_with_repo('install -y dnf-test-main')
|
||||
output = self.dnf('list --installed dnf-test-*')
|
||||
self.assertIn("dnf-test-main.", output)
|
||||
self.assertIn("dnf-test-dep.", output)
|
||||
|
||||
@OETestDepends(['dnf.DnfRepoTest.test_dnf_install_dependency'])
|
||||
def test_dnf_install_from_disk(self):
|
||||
self.dnf_with_repo('remove -y dnf-test-dep')
|
||||
self.dnf_with_repo('install -y --downloadonly dnf-test-dep')
|
||||
status, output = self.target.run('find /var/cache/dnf -name dnf-test-dep*rpm')
|
||||
self.assertEqual(status, 0, output)
|
||||
self.dnf_with_repo('install -y %s' % output)
|
||||
|
||||
@OETestDepends(['dnf.DnfRepoTest.test_dnf_install_from_disk'])
|
||||
def test_dnf_install_from_http(self):
|
||||
output = subprocess.check_output('%s %s -name dnf-test-dep*' % (bb.utils.which(os.getenv('PATH'), "find"),
|
||||
os.path.join(self.tc.td['WORKDIR'], 'oe-testimage-repo')), shell=True).decode("utf-8")
|
||||
rpm_path = output.split("/")[-2] + "/" + output.split("/")[-1]
|
||||
url = 'http://%s:%s/%s' %(self.target.server_ip, self.repo_server.port, rpm_path)
|
||||
self.dnf_with_repo('remove -y dnf-test-dep')
|
||||
self.dnf_with_repo('install -y %s' % url)
|
||||
|
||||
@OETestDepends(['dnf.DnfRepoTest.test_dnf_install'])
|
||||
def test_dnf_reinstall(self):
|
||||
self.dnf_with_repo('reinstall -y dnf-test-main')
|
||||
|
||||
@OETestDepends(['dnf.DnfRepoTest.test_dnf_makecache'])
|
||||
@skipIfInDataVar('DISTRO_FEATURES', 'usrmerge', 'Test run when not enable usrmerge')
|
||||
@OEHasPackage('busybox')
|
||||
def test_dnf_installroot(self):
|
||||
rootpath = '/home/root/chroot/test'
|
||||
#Copy necessary files to avoid errors with not yet installed tools on
|
||||
#installroot directory.
|
||||
self.target.run('mkdir -p %s/etc' % rootpath, 1500)
|
||||
self.target.run('mkdir -p %s/bin %s/sbin %s/usr/bin %s/usr/sbin' % (rootpath, rootpath, rootpath, rootpath), 1500)
|
||||
self.target.run('mkdir -p %s/dev' % rootpath, 1500)
|
||||
#Handle different architectures lib dirs
|
||||
self.target.run('mkdir -p %s/lib' % rootpath, 1500)
|
||||
self.target.run('mkdir -p %s/libx32' % rootpath, 1500)
|
||||
self.target.run('mkdir -p %s/lib64' % rootpath, 1500)
|
||||
self.target.run('cp /lib/libtinfo.so.5 %s/lib' % rootpath, 1500)
|
||||
self.target.run('cp /libx32/libtinfo.so.5 %s/libx32' % rootpath, 1500)
|
||||
self.target.run('cp /lib64/libtinfo.so.5 %s/lib64' % rootpath, 1500)
|
||||
self.target.run('cp -r /etc/rpm %s/etc' % rootpath, 1500)
|
||||
self.target.run('cp -r /etc/dnf %s/etc' % rootpath, 1500)
|
||||
self.target.run('cp /bin/sh %s/bin' % rootpath, 1500)
|
||||
self.target.run('mount -o bind /dev %s/dev/' % rootpath, 1500)
|
||||
self.dnf_with_repo('install --installroot=%s -v -y --rpmverbosity=debug busybox' % rootpath)
|
||||
status, output = self.target.run('test -e %s/var/cache/dnf' % rootpath, 1500)
|
||||
self.assertEqual(0, status, output)
|
||||
status, output = self.target.run('test -e %s/bin/busybox' % rootpath, 1500)
|
||||
self.assertEqual(0, status, output)
|
||||
|
||||
@OETestDepends(['dnf.DnfRepoTest.test_dnf_makecache'])
|
||||
@skipIfNotInDataVar('DISTRO_FEATURES', 'usrmerge', 'Test run when enable usrmerge')
|
||||
@OEHasPackage('busybox')
|
||||
def test_dnf_installroot_usrmerge(self):
|
||||
rootpath = '/home/root/chroot/test'
|
||||
#Copy necessary files to avoid errors with not yet installed tools on
|
||||
#installroot directory.
|
||||
self.target.run('mkdir -p %s/etc' % rootpath)
|
||||
self.target.run('mkdir -p %s/usr/bin %s/usr/sbin' % (rootpath, rootpath))
|
||||
self.target.run('ln -sf usr/bin %s/bin' % (rootpath))
|
||||
self.target.run('ln -sf usr/sbin %s/sbin' % (rootpath))
|
||||
self.target.run('mkdir -p %s/dev' % rootpath)
|
||||
#Handle different architectures lib dirs
|
||||
self.target.run("for l in /lib*; do mkdir -p %s/usr/$l; ln -s usr/$l %s/$l; done" % (rootpath, rootpath))
|
||||
self.target.run('cp -r /etc/rpm %s/etc' % rootpath)
|
||||
self.target.run('cp -r /etc/dnf %s/etc' % rootpath)
|
||||
self.target.run('cp /bin/busybox %s/bin/sh' % rootpath)
|
||||
self.target.run('mount -o bind /dev %s/dev/' % rootpath)
|
||||
self.dnf_with_repo('install --installroot=%s -v -y --rpmverbosity=debug busybox' % rootpath)
|
||||
status, output = self.target.run('test -e %s/var/cache/dnf' % rootpath)
|
||||
self.assertEqual(0, status, output)
|
||||
status, output = self.target.run('test -e %s/bin/busybox' % rootpath)
|
||||
self.assertEqual(0, status, output)
|
||||
|
||||
@OETestDepends(['dnf.DnfRepoTest.test_dnf_makecache'])
|
||||
def test_dnf_exclude(self):
|
||||
self.dnf_with_repo('remove -y dnf-test-*')
|
||||
self.dnf_with_repo('install -y --exclude=dnf-test-dep dnf-test-*')
|
||||
output = self.dnf('list --installed dnf-test-*')
|
||||
self.assertIn("dnf-test-main.", output)
|
||||
self.assertNotIn("dnf-test-dev.", output)
|
||||
@@ -0,0 +1,42 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.core.decorator.data import skipIfQemu
|
||||
|
||||
class Ethernet_Test(OERuntimeTestCase):
|
||||
|
||||
def set_ip(self, x):
|
||||
x = x.split(".")
|
||||
sample_host_address = '150'
|
||||
x[3] = sample_host_address
|
||||
x = '.'.join(x)
|
||||
return x
|
||||
|
||||
@skipIfQemu()
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
def test_set_virtual_ip(self):
|
||||
(status, output) = self.target.run("ifconfig eth0 | grep 'inet ' | awk '{print $2}'")
|
||||
self.assertEqual(status, 0, msg='Failed to get ip address. Make sure you have an ethernet connection on your device, output: %s' % output)
|
||||
original_ip = output
|
||||
virtual_ip = self.set_ip(original_ip)
|
||||
|
||||
(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))
|
||||
self.assertEqual(status, 0, msg='Failed to create virtual ip address, output: %s' % output)
|
||||
|
||||
@skipIfQemu()
|
||||
@OETestDepends(['ethernet_ip_connman.Ethernet_Test.test_set_virtual_ip'])
|
||||
def test_get_ip_from_dhcp(self):
|
||||
(status, output) = self.target.run("connmanctl services | grep -E '*AO Wired|*AR Wired' | awk '{print $3}'")
|
||||
self.assertEqual(status, 0, msg='No wired interfaces are detected, output: %s' % output)
|
||||
wired_interfaces = output
|
||||
|
||||
(status, output) = self.target.run("ip route | grep default | awk '{print $3}'")
|
||||
self.assertEqual(status, 0, msg='Failed to retrieve the default gateway, output: %s' % output)
|
||||
default_gateway = output
|
||||
|
||||
(status, output) = self.target.run("connmanctl config %s --ipv4 dhcp && sleep 2 && ping -c 5 %s" % (wired_interfaces,default_gateway))
|
||||
self.assertEqual(status, 0, msg='Failed to get dynamic IP address via DHCP in connmand, output: %s' % output)
|
||||
71
sources/poky/meta/lib/oeqa/runtime/cases/gcc.py
Normal file
71
sources/poky/meta/lib/oeqa/runtime/cases/gcc.py
Normal file
@@ -0,0 +1,71 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
import os
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
class GccCompileTest(OERuntimeTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUp(cls):
|
||||
dst = '/tmp/'
|
||||
src = os.path.join(cls.tc.files_dir, 'test.c')
|
||||
cls.tc.target.copyTo(src, dst)
|
||||
|
||||
src = os.path.join(cls.tc.runtime_files_dir, 'testmakefile')
|
||||
cls.tc.target.copyTo(src, dst)
|
||||
|
||||
src = os.path.join(cls.tc.files_dir, 'test.cpp')
|
||||
cls.tc.target.copyTo(src, dst)
|
||||
|
||||
@classmethod
|
||||
def tearDown(cls):
|
||||
files = '/tmp/test.c /tmp/test.o /tmp/test /tmp/testmakefile'
|
||||
cls.tc.target.run('rm %s' % files)
|
||||
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(['gcc'])
|
||||
def test_gcc_compile(self):
|
||||
status, output = self.target.run('gcc /tmp/test.c -o /tmp/test -lm')
|
||||
msg = 'gcc compile failed, output: %s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
status, output = self.target.run('/tmp/test')
|
||||
msg = 'running compiled file failed, output: %s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(['g++'])
|
||||
def test_gpp_compile(self):
|
||||
status, output = self.target.run('g++ /tmp/test.c -o /tmp/test -lm')
|
||||
msg = 'g++ compile failed, output: %s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
status, output = self.target.run('/tmp/test')
|
||||
msg = 'running compiled file failed, output: %s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(['g++'])
|
||||
def test_gpp2_compile(self):
|
||||
status, output = self.target.run('g++ /tmp/test.cpp -o /tmp/test -lm')
|
||||
msg = 'g++ compile failed, output: %s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
status, output = self.target.run('/tmp/test')
|
||||
msg = 'running compiled file failed, output: %s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(['gcc'])
|
||||
@OEHasPackage(['make'])
|
||||
def test_make(self):
|
||||
status, output = self.target.run('cd /tmp; make -f testmakefile')
|
||||
msg = 'running make failed, output %s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
21
sources/poky/meta/lib/oeqa/runtime/cases/gi.py
Normal file
21
sources/poky/meta/lib/oeqa/runtime/cases/gi.py
Normal file
@@ -0,0 +1,21 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
import os
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
class GObjectIntrospectionTest(OERuntimeTestCase):
|
||||
|
||||
@OETestDepends(["ssh.SSHTest.test_ssh"])
|
||||
@OEHasPackage(["python3-pygobject"])
|
||||
def test_python(self):
|
||||
script = """from gi.repository import GLib; print(GLib.markup_escape_text("<testing&testing>"))"""
|
||||
status, output = self.target.run("python3 -c '%s'" % script)
|
||||
self.assertEqual(status, 0, msg="Python failed (%s)" % (output))
|
||||
self.assertEqual(output, "<testing&testing>", msg="Unexpected output (%s)" % output)
|
||||
21
sources/poky/meta/lib/oeqa/runtime/cases/go.py
Normal file
21
sources/poky/meta/lib/oeqa/runtime/cases/go.py
Normal file
@@ -0,0 +1,21 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
class GoHelloworldTest(OERuntimeTestCase):
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(['go-helloworld'])
|
||||
def test_gohelloworld(self):
|
||||
cmd = "go-helloworld"
|
||||
status, output = self.target.run(cmd)
|
||||
msg = 'Exit status was not 0. Output: %s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
msg = 'Incorrect output: %s' % output
|
||||
self.assertEqual(output, "Hello, world!", msg=msg)
|
||||
20
sources/poky/meta/lib/oeqa/runtime/cases/gstreamer.py
Normal file
20
sources/poky/meta/lib/oeqa/runtime/cases/gstreamer.py
Normal file
@@ -0,0 +1,20 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
class GstreamerCliTest(OERuntimeTestCase):
|
||||
|
||||
@OEHasPackage(['gstreamer1.0'])
|
||||
def test_gst_inspect_can_list_all_plugins(self):
|
||||
status, output = self.target.run('gst-inspect-1.0')
|
||||
self.assertEqual(status, 0, 'gst-inspect-1.0 does not appear to be running.')
|
||||
|
||||
@OEHasPackage(['gstreamer1.0'])
|
||||
def test_gst_launch_can_create_video_pipeline(self):
|
||||
status, output = self.target.run('gst-launch-1.0 -v fakesrc silent=false num-buffers=3 ! fakesink silent=false')
|
||||
self.assertEqual(status, 0, 'gst-launch-1.0 does not appear to be running.')
|
||||
48
sources/poky/meta/lib/oeqa/runtime/cases/kernelmodule.py
Normal file
48
sources/poky/meta/lib/oeqa/runtime/cases/kernelmodule.py
Normal file
@@ -0,0 +1,48 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
import os
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.core.decorator.data import skipIfNotFeature
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
class KernelModuleTest(OERuntimeTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUp(cls):
|
||||
src = os.path.join(cls.tc.runtime_files_dir, 'hellomod.c')
|
||||
dst = '/tmp/hellomod.c'
|
||||
cls.tc.target.copyTo(src, dst)
|
||||
|
||||
src = os.path.join(cls.tc.runtime_files_dir, 'hellomod_makefile')
|
||||
dst = '/tmp/Makefile'
|
||||
cls.tc.target.copyTo(src, dst)
|
||||
|
||||
@classmethod
|
||||
def tearDown(cls):
|
||||
files = '/tmp/Makefile /tmp/hellomod.c'
|
||||
cls.tc.target.run('rm %s' % files)
|
||||
|
||||
@skipIfNotFeature('tools-sdk',
|
||||
'Test requires tools-sdk to be in IMAGE_FEATURES')
|
||||
@OETestDepends(['gcc.GccCompileTest.test_gcc_compile'])
|
||||
@OEHasPackage(['kernel-devsrc'])
|
||||
@OEHasPackage(['make'])
|
||||
@OEHasPackage(['gcc'])
|
||||
def test_kernel_module(self):
|
||||
cmds = [
|
||||
'cd /usr/src/kernel && make scripts prepare',
|
||||
'cd /tmp && make',
|
||||
'cd /tmp && insmod hellomod.ko',
|
||||
'lsmod | grep hellomod',
|
||||
'dmesg | grep Hello',
|
||||
'rmmod hellomod', 'dmesg | grep "Cleaning up hellomod"'
|
||||
]
|
||||
for cmd in cmds:
|
||||
status, output = self.target.run(cmd, 900)
|
||||
self.assertEqual(status, 0, msg='\n'.join([cmd, output]))
|
||||
233
sources/poky/meta/lib/oeqa/runtime/cases/ksample.py
Normal file
233
sources/poky/meta/lib/oeqa/runtime/cases/ksample.py
Normal file
@@ -0,0 +1,233 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
import os
|
||||
import time
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.core.decorator.data import skipIfNotFeature
|
||||
|
||||
# need some kernel fragments
|
||||
# echo "KERNEL_FEATURES:append = \" features\/kernel\-sample\/kernel\-sample.scc\"" >> local.conf
|
||||
class KSample(OERuntimeTestCase):
|
||||
def cmd_and_check(self, cmd='', match_string=''):
|
||||
status, output = self.target.run(cmd)
|
||||
if not match_string:
|
||||
# send cmd
|
||||
msg = '%s failed, %s' % (cmd, output)
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
else:
|
||||
# check result
|
||||
result = ("%s" % match_string) in output
|
||||
msg = output
|
||||
self.assertTrue(result, msg)
|
||||
self.assertEqual(status, 0, cmd)
|
||||
|
||||
def check_arch(self, archset=''):
|
||||
status, output = self.target.run("uname -m")
|
||||
result = ("%s" % output) in archset
|
||||
if not result:
|
||||
self.skipTest("This case doesn't support %s" % output)
|
||||
|
||||
def check_config(self, config_opt=''):
|
||||
cmd = "zcat /proc/config.gz | grep %s" % config_opt
|
||||
status, output = self.target.run(cmd)
|
||||
result = ("%s=y" % config_opt) in output
|
||||
if not result:
|
||||
self.skipTest("%s is not set" % config_opt)
|
||||
|
||||
def check_module_exist(self, path='', module_name=''):
|
||||
status, output = self.target.run("uname -r")
|
||||
cmd = "ls " + "/lib/modules/" + output + "/kernel/samples/" + path + module_name
|
||||
status, output = self.target.run(cmd)
|
||||
if status != 0:
|
||||
error_info = module_name + " doesn't exist"
|
||||
self.skipTest(error_info)
|
||||
|
||||
def kfifo_func(self, name=''):
|
||||
module_prename = name + "-example"
|
||||
module_name = name + "-example.ko"
|
||||
sysmbol_name = name + "_example"
|
||||
|
||||
# make sure if module exists
|
||||
self.check_module_exist("kfifo/", module_name)
|
||||
# modprobe
|
||||
self.cmd_and_check("modprobe %s" % module_prename)
|
||||
# lsmod
|
||||
self.cmd_and_check("lsmod | grep %s | cut -d\' \' -f1" % sysmbol_name, sysmbol_name)
|
||||
# check result
|
||||
self.cmd_and_check("dmesg | grep \"test passed\" ", "test passed")
|
||||
# rmmod
|
||||
self.cmd_and_check("rmmod %s" % module_prename)
|
||||
|
||||
def kprobe_func(self, name=''):
|
||||
# check config
|
||||
self.check_config("CONFIG_KPROBES")
|
||||
|
||||
module_prename = name + "_example"
|
||||
module_name = name + "_example.ko"
|
||||
sysmbol_name = module_prename
|
||||
|
||||
# make sure if module exists
|
||||
self.check_module_exist("kprobes/", module_name)
|
||||
# modprobe
|
||||
self.cmd_and_check("modprobe %s" % module_prename)
|
||||
# lsmod
|
||||
self.cmd_and_check("lsmod | grep %s | cut -d\' \' -f1" % sysmbol_name, sysmbol_name)
|
||||
# check result
|
||||
self.cmd_and_check("dmesg | grep Planted | head -n10", "Planted")
|
||||
# rmmod
|
||||
self.cmd_and_check("rmmod %s" % module_prename)
|
||||
|
||||
def kobject_func(self, name=''):
|
||||
module_prename = name + "_example"
|
||||
module_name = name + "-example.ko"
|
||||
sysmbol_name = module_prename
|
||||
|
||||
# make sure if module exists
|
||||
self.check_module_exist("kobject/", module_name)
|
||||
# modprobe
|
||||
self.cmd_and_check("modprobe %s" % module_prename)
|
||||
# lsmod
|
||||
self.cmd_and_check("lsmod | grep %s | cut -d\' \' -f1" % sysmbol_name, sysmbol_name)
|
||||
# check result
|
||||
self.cmd_and_check("ls /sys/kernel/%s/" % sysmbol_name, "bar")
|
||||
# rmmod
|
||||
self.cmd_and_check("rmmod %s" % module_prename)
|
||||
|
||||
class KSampleTest(KSample):
|
||||
# kfifo
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
def test_kfifo_test(self):
|
||||
index = ["dma", "bytestream", "inttype", "record"]
|
||||
for i in index:
|
||||
self.kfifo_func(i)
|
||||
|
||||
# kprobe
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
def test_kprobe_test(self):
|
||||
self.check_arch("x86_64 i686 ppc")
|
||||
index = ["kprobe", "kretprobe"]
|
||||
for i in index:
|
||||
self.kprobe_func(i)
|
||||
|
||||
# kobject
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
def test_kobject_test(self):
|
||||
index = ["kobject", "kset"]
|
||||
for i in index:
|
||||
self.kobject_func(i)
|
||||
|
||||
#trace
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
def test_trace_events(self):
|
||||
# check config
|
||||
self.check_config("CONFIG_TRACING_SUPPORT")
|
||||
# make sure if module exists
|
||||
self.check_module_exist("trace_events/", "trace-events-sample.ko")
|
||||
# modprobe
|
||||
self.cmd_and_check("modprobe trace-events-sample")
|
||||
# lsmod
|
||||
self.cmd_and_check("lsmod | grep trace_events_sample | cut -d\' \' -f1", "trace_events_sample")
|
||||
# check dir
|
||||
self.cmd_and_check("ls /sys/kernel/debug/tracing/events/ | grep sample-trace", "sample-trace")
|
||||
# enable trace
|
||||
self.cmd_and_check("echo 1 > /sys/kernel/debug/tracing/events/sample-trace/enable")
|
||||
self.cmd_and_check("cat /sys/kernel/debug/tracing/events/sample-trace/enable")
|
||||
# check result
|
||||
status = 1
|
||||
count = 0
|
||||
while status != 0:
|
||||
time.sleep(1)
|
||||
status, output = self.target.run('cat /sys/kernel/debug/tracing/trace | grep hello | head -n1 | cut -d\':\' -f2')
|
||||
if " foo_bar" in output:
|
||||
break
|
||||
count = count + 1
|
||||
if count > 5:
|
||||
self.assertTrue(False, "Time out when check result")
|
||||
# disable trace
|
||||
self.cmd_and_check("echo 0 > /sys/kernel/debug/tracing/events/sample-trace/enable")
|
||||
# clean up trace
|
||||
self.cmd_and_check("echo > /sys/kernel/debug/tracing/trace")
|
||||
# rmmod
|
||||
self.cmd_and_check("rmmod trace-events-sample")
|
||||
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
def test_trace_printk(self):
|
||||
# check config
|
||||
self.check_config("CONFIG_TRACING_SUPPORT")
|
||||
# make sure if module exists
|
||||
self.check_module_exist("trace_printk/", "trace-printk.ko")
|
||||
# modprobe
|
||||
self.cmd_and_check("modprobe trace-printk")
|
||||
# lsmod
|
||||
self.cmd_and_check("lsmod | grep trace_printk | cut -d\' \' -f1", "trace_printk")
|
||||
# check result
|
||||
self.cmd_and_check("cat /sys/kernel/debug/tracing/trace | grep trace_printk_irq_work | head -n1 | cut -d\':\' -f2", " trace_printk_irq_work")
|
||||
# clean up trace
|
||||
self.cmd_and_check("echo > /sys/kernel/debug/tracing/trace")
|
||||
# rmmod
|
||||
self.cmd_and_check("rmmod trace-printk")
|
||||
|
||||
# hw breakpoint
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
def test_hw_breakpoint_example(self):
|
||||
# check arch
|
||||
status, output = self.target.run("uname -m")
|
||||
result = ("x86_64" in output) or ("aarch64" in output)
|
||||
if not result:
|
||||
self.skipTest("the arch %s doesn't support hw breakpoint" % output)
|
||||
# check config
|
||||
self.check_config("CONFIG_KALLSYMS_ALL")
|
||||
# make sure if module exists
|
||||
self.check_module_exist("hw_breakpoint/", "data_breakpoint.ko")
|
||||
# modprobe
|
||||
self.cmd_and_check("modprobe data_breakpoint")
|
||||
# lsmod
|
||||
self.cmd_and_check("lsmod | grep data_breakpoint | cut -d\' \' -f1", "data_breakpoint")
|
||||
# check result
|
||||
self.cmd_and_check("cat /var/log/messages | grep sample_hbp_handler", "sample_hbp_handler")
|
||||
# rmmod
|
||||
self.cmd_and_check("rmmod data_breakpoint")
|
||||
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
def test_configfs_sample(self):
|
||||
# check config
|
||||
status, ret = self.target.run('zcat /proc/config.gz | grep CONFIG_CONFIGFS_FS')
|
||||
if not ["CONFIG_CONFIGFS_FS=m" in ret or "CONFIG_CONFIGFS_FS=y" in ret]:
|
||||
self.skipTest("CONFIG error")
|
||||
# make sure if module exists
|
||||
self.check_module_exist("configfs/", "configfs_sample.ko")
|
||||
# modprobe
|
||||
self.cmd_and_check("modprobe configfs_sample")
|
||||
# lsmod
|
||||
self.cmd_and_check("lsmod | grep configfs_sample | cut -d\' \' -f1 | head -n1", "configfs_sample")
|
||||
|
||||
status = 1
|
||||
count = 0
|
||||
while status != 0:
|
||||
time.sleep(1)
|
||||
status, ret = self.target.run('cat /sys/kernel/config/01-childless/description')
|
||||
count = count + 1
|
||||
if count > 200:
|
||||
self.skipTest("Time out for check dir")
|
||||
|
||||
# rmmod
|
||||
self.cmd_and_check("rmmod configfs_sample")
|
||||
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
def test_cn_test(self):
|
||||
# make sure if module exists
|
||||
self.check_module_exist("connector/", "cn_test.ko")
|
||||
# modprobe
|
||||
self.cmd_and_check("modprobe cn_test")
|
||||
# lsmod
|
||||
self.cmd_and_check("lsmod | grep cn_test | cut -d\' \' -f1", "cn_test")
|
||||
# check result
|
||||
self.cmd_and_check("cat /proc/net/connector | grep cn_test | head -n1 | cut -d\' \' -f1", "cn_test")
|
||||
# rmmod
|
||||
self.cmd_and_check("rmmod cn_test")
|
||||
28
sources/poky/meta/lib/oeqa/runtime/cases/ldd.py
Normal file
28
sources/poky/meta/lib/oeqa/runtime/cases/ldd.py
Normal file
@@ -0,0 +1,28 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.core.decorator.data import skipIfNotFeature
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
class LddTest(OERuntimeTestCase):
|
||||
|
||||
@OEHasPackage(["ldd"])
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
def test_ldd(self):
|
||||
status, output = self.target.run('which ldd')
|
||||
msg = 'ldd does not exist in PATH: which ldd: %s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
cmd = ('for i in $(which ldd | xargs cat | grep "^RTLDLIST"| '
|
||||
'cut -d\'=\' -f2|tr -d \'"\'); '
|
||||
'do test -f $i && echo $i && break; done')
|
||||
status, output = self.target.run(cmd)
|
||||
self.assertEqual(status, 0, msg="ldd path not correct or RTLDLIST files don't exist.")
|
||||
|
||||
status, output = self.target.run("ldd /bin/true")
|
||||
self.assertEqual(status, 0, msg="ldd failed to execute: %s" % output)
|
||||
116
sources/poky/meta/lib/oeqa/runtime/cases/login.py
Normal file
116
sources/poky/meta/lib/oeqa/runtime/cases/login.py
Normal file
@@ -0,0 +1,116 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
import time
|
||||
import os
|
||||
from datetime import datetime
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
### Status of qemu images.
|
||||
# - runqemu qemuppc64 comes up blank. (skip)
|
||||
# - qemuarmv5 comes up with multiple heads but sending "head" to screendump.
|
||||
# seems to create a png with a bad header? (skip for now, but come back to fix)
|
||||
# - qemuriscv32 and qemuloongarch64 doesn't work with testimage apparently? (skip)
|
||||
# - qemumips64 is missing mouse icon.
|
||||
# - qemumips takes forever to render and is missing mouse icon.
|
||||
# - qemuarm and qemuppc are odd as they don't resize so we need to just set width.
|
||||
# - All images have home and screen flipper icons not always rendered fully at first.
|
||||
# the sleep seems to help this out some, depending on machine load.
|
||||
###
|
||||
|
||||
class LoginTest(OERuntimeTestCase):
|
||||
@OEHasPackage(['matchbox-desktop', 'dbus-wait'])
|
||||
def test_screenshot(self):
|
||||
if self.td.get('MACHINE') in ("qemuppc64", "qemuarmv5", "qemuriscv32", "qemuriscv64", "qemuloongarch64"):
|
||||
self.skipTest("{0} is not currently supported.".format(self.td.get('MACHINE')))
|
||||
|
||||
pn = self.td.get('PN')
|
||||
|
||||
ourenv = os.environ.copy()
|
||||
origpath = self.td.get("ORIGPATH")
|
||||
if origpath:
|
||||
ourenv['PATH'] = ourenv['PATH'] + ":" + origpath
|
||||
|
||||
for cmd in ["identify.im7", "convert.im7", "compare.im7"]:
|
||||
try:
|
||||
subprocess.check_output(["which", cmd], env=ourenv)
|
||||
except subprocess.CalledProcessError:
|
||||
self.skipTest("%s (from imagemagick) not available" % cmd)
|
||||
|
||||
|
||||
# Store images so we can debug them if needed
|
||||
saved_screenshots_dir = self.td.get('T') + "/saved-screenshots/"
|
||||
|
||||
###
|
||||
# This is a really horrible way of doing this but I've not found the
|
||||
# right event to determine "The system is loaded and screen is rendered"
|
||||
#
|
||||
# Using dbus-wait for matchbox is the wrong answer because while it
|
||||
# ensures the system is up, it doesn't mean the screen is rendered.
|
||||
#
|
||||
# Checking the qmp socket doesn't work afaik either.
|
||||
#
|
||||
# One way to do this is to do compares of known good screendumps until
|
||||
# we either get expected or close to expected or we time out. Part of the
|
||||
# issue here with that is that there is a very fine difference in the
|
||||
# diff between a screendump where the icons haven't loaded yet and
|
||||
# one where they won't load. I'll look at that next, but, for now, this.
|
||||
#
|
||||
# Which is ugly and I hate it but it 'works' for various definitions of
|
||||
# 'works'.
|
||||
###
|
||||
# RP: if the signal is sent before we run this, it will never be seen and we'd timeout
|
||||
#status, output = self.target.run('dbus-wait org.matchbox_project.desktop Loaded')
|
||||
#if status != 0 or "Timeout" in output:
|
||||
# self.fail('dbus-wait failed (%s, %s). This could mean that the image never loaded the matchbox desktop.' % (status, output))
|
||||
|
||||
# Start taking screenshots every 2 seconds until diff=0 or timeout is 60 seconds
|
||||
timeout = time.time() + 60
|
||||
diff = True
|
||||
with tempfile.NamedTemporaryFile(prefix="oeqa-screenshot-login", suffix=".png") as t:
|
||||
while diff != 0 and time.time() < timeout:
|
||||
time.sleep(2)
|
||||
ret = self.target.runner.run_monitor("screendump", args={"filename": t.name, "format":"png"})
|
||||
|
||||
# Find out size of image so we can determine where to blank out clock.
|
||||
# qemuarm and qemuppc are odd as it doesn't resize the window and returns
|
||||
# incorrect widths
|
||||
if self.td.get('MACHINE') == "qemuarm" or self.td.get('MACHINE') == "qemuppc":
|
||||
width = "640"
|
||||
else:
|
||||
cmd = "identify.im7 -ping -format '%w' {0}".format(t.name)
|
||||
width = subprocess.check_output(cmd, shell=True, env=ourenv).decode()
|
||||
|
||||
rblank = int(float(width))
|
||||
lblank = rblank-80
|
||||
|
||||
# Use the meta-oe version of convert, along with it's suffix. This blanks out the clock.
|
||||
cmd = "convert.im7 {0} -fill white -draw 'rectangle {1},4 {2},28' {3}".format(t.name, str(rblank), str(lblank), t.name)
|
||||
convert_out=subprocess.check_output(cmd, shell=True, env=ourenv).decode()
|
||||
|
||||
bb.utils.mkdirhier(saved_screenshots_dir)
|
||||
savedfile = "{0}/saved-{1}-{2}-{3}.png".format(saved_screenshots_dir, \
|
||||
datetime.timestamp(datetime.now()), \
|
||||
pn, \
|
||||
self.td.get('MACHINE'))
|
||||
shutil.copy2(t.name, savedfile)
|
||||
|
||||
refimage = self.td.get('COREBASE') + "/meta/files/screenshot-tests/" + pn + "-" + self.td.get('MACHINE') +".png"
|
||||
if not os.path.exists(refimage):
|
||||
self.skipTest("No reference image for comparision (%s)" % refimage)
|
||||
|
||||
cmd = "compare.im7 -metric MSE {0} {1} /dev/null".format(t.name, refimage)
|
||||
compare_out = subprocess.run(cmd, shell=True, capture_output=True, text=True, env=ourenv)
|
||||
diff=float(compare_out.stderr.replace("(", "").replace(")","").split()[1])
|
||||
if diff > 0:
|
||||
# Keep a copy of the failed screenshot so we can see what happened.
|
||||
self.fail("Screenshot diff is {0}. Failed image stored in {1}".format(str(diff), savedfile))
|
||||
else:
|
||||
self.assertEqual(0, diff, "Screenshot diff is {0}.".format(str(diff)))
|
||||
73
sources/poky/meta/lib/oeqa/runtime/cases/logrotate.py
Normal file
73
sources/poky/meta/lib/oeqa/runtime/cases/logrotate.py
Normal file
@@ -0,0 +1,73 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
# This test should cover https://bugzilla.yoctoproject.org/tr_show_case.cgi?case_id=289 testcase
|
||||
# Note that the image under test must have logrotate installed
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
class LogrotateTest(OERuntimeTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.tc.target.run('cp /etc/logrotate.d/wtmp $HOME/wtmp.oeqabak')
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls.tc.target.run('mv -f $HOME/wtmp.oeqabak /etc/logrotate.d/wtmp && rm -rf /var/log//logrotate_dir')
|
||||
cls.tc.target.run('rm -rf /var/log/logrotate_testfile && rm -rf /etc/logrotate.d/logrotate_testfile')
|
||||
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(['logrotate'])
|
||||
def test_logrotate_wtmp(self):
|
||||
|
||||
# /var/log/wtmp may not always exist initially, so use touch to ensure it is present
|
||||
status, output = self.target.run('touch /var/log/wtmp')
|
||||
msg = ('Could not create/update /var/log/wtmp with touch')
|
||||
self.assertEqual(status, 0, msg = msg)
|
||||
|
||||
status, output = self.target.run('mkdir /var/log//logrotate_dir')
|
||||
msg = ('Could not create logrotate_dir. Output: %s' % output)
|
||||
self.assertEqual(status, 0, msg = msg)
|
||||
|
||||
status, output = self.target.run('echo "create \n olddir /var/log//logrotate_dir \n include /etc/logrotate.d/wtmp" > /tmp/logrotate-test.conf')
|
||||
msg = ('Could not write to /tmp/logrotate-test.conf')
|
||||
self.assertEqual(status, 0, msg = msg)
|
||||
|
||||
# If logrotate fails to rotate the log, view the verbose output of logrotate to see what prevented it
|
||||
_, logrotate_output = self.target.run('logrotate -vf /tmp/logrotate-test.conf')
|
||||
status, _ = self.target.run('find /var/log//logrotate_dir -type f | grep wtmp.1')
|
||||
msg = ("logrotate did not successfully rotate the wtmp log. Output from logrotate -vf: \n%s" % (logrotate_output))
|
||||
self.assertEqual(status, 0, msg = msg)
|
||||
|
||||
@OETestDepends(['logrotate.LogrotateTest.test_logrotate_wtmp'])
|
||||
def test_logrotate_newlog(self):
|
||||
|
||||
status, output = self.target.run('echo "oeqa logrotate test file" > /var/log/logrotate_testfile')
|
||||
msg = ('Could not create logrotate test file in /var/log')
|
||||
self.assertEqual(status, 0, msg = msg)
|
||||
|
||||
status, output = self.target.run('echo "/var/log/logrotate_testfile {\n missingok \n monthly \n rotate 1" > /etc/logrotate.d/logrotate_testfile')
|
||||
msg = ('Could not write to /etc/logrotate.d/logrotate_testfile')
|
||||
self.assertEqual(status, 0, msg = msg)
|
||||
|
||||
status, output = self.target.run('echo "create \n olddir /var/log//logrotate_dir \n include /etc/logrotate.d/logrotate_testfile" > /tmp/logrotate-test2.conf')
|
||||
msg = ('Could not write to /tmp/logrotate_test2.conf')
|
||||
self.assertEqual(status, 0, msg = msg)
|
||||
|
||||
status, output = self.target.run('find /var/log//logrotate_dir -type f | grep logrotate_testfile.1')
|
||||
msg = ('A rotated log for logrotate_testfile is already present in logrotate_dir')
|
||||
self.assertEqual(status, 1, msg = msg)
|
||||
|
||||
# If logrotate fails to rotate the log, view the verbose output of logrotate instead of just listing the files in olddir
|
||||
_, logrotate_output = self.target.run('logrotate -vf /tmp/logrotate-test2.conf')
|
||||
status, _ = self.target.run('find /var/log//logrotate_dir -type f | grep logrotate_testfile.1')
|
||||
msg = ('logrotate did not successfully rotate the logrotate_test log. Output from logrotate -vf: \n%s' % (logrotate_output))
|
||||
self.assertEqual(status, 0, msg = msg)
|
||||
|
||||
|
||||
129
sources/poky/meta/lib/oeqa/runtime/cases/ltp.py
Normal file
129
sources/poky/meta/lib/oeqa/runtime/cases/ltp.py
Normal file
@@ -0,0 +1,129 @@
|
||||
# LTP runtime
|
||||
#
|
||||
# Copyright (c) 2019 MontaVista Software, LLC
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
|
||||
import time
|
||||
import datetime
|
||||
import pprint
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
from oeqa.utils.logparser import LtpParser
|
||||
|
||||
class LtpTestBase(OERuntimeTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.ltp_startup()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls.ltp_finishup()
|
||||
|
||||
@classmethod
|
||||
def ltp_startup(cls):
|
||||
cls.sections = {}
|
||||
cls.failmsg = ""
|
||||
test_log_dir = os.path.join(cls.td.get('WORKDIR', ''), 'testimage')
|
||||
timestamp = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
|
||||
|
||||
cls.ltptest_log_dir_link = os.path.join(test_log_dir, 'ltp_log')
|
||||
cls.ltptest_log_dir = '%s.%s' % (cls.ltptest_log_dir_link, timestamp)
|
||||
os.makedirs(cls.ltptest_log_dir)
|
||||
|
||||
cls.tc.target.run("mkdir -p /opt/ltp/results")
|
||||
|
||||
if not hasattr(cls.tc, "extraresults"):
|
||||
cls.tc.extraresults = {}
|
||||
cls.extras = cls.tc.extraresults
|
||||
cls.extras['ltpresult.rawlogs'] = {'log': ""}
|
||||
|
||||
|
||||
@classmethod
|
||||
def ltp_finishup(cls):
|
||||
cls.extras['ltpresult.sections'] = cls.sections
|
||||
|
||||
# update symlink to ltp_log
|
||||
if os.path.exists(cls.ltptest_log_dir_link):
|
||||
os.remove(cls.ltptest_log_dir_link)
|
||||
os.symlink(os.path.basename(cls.ltptest_log_dir), cls.ltptest_log_dir_link)
|
||||
|
||||
if cls.failmsg:
|
||||
cls.fail(cls.failmsg)
|
||||
|
||||
class LtpTest(LtpTestBase):
|
||||
|
||||
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"]
|
||||
|
||||
ltp_fs = ["fs", "fs_bind"]
|
||||
# skip kernel cpuhotplug
|
||||
ltp_kernel = ["power_management_tests", "hyperthreading ", "kernel_misc", "hugetlb"]
|
||||
ltp_groups += ltp_fs
|
||||
|
||||
def runltp(self, ltp_group):
|
||||
# LTP appends to log files, so ensure we start with a clean log
|
||||
self.target.deleteFiles("/opt/ltp/results/", ltp_group)
|
||||
|
||||
cmd = '/opt/ltp/runltp -f %s -q -r /opt/ltp -l /opt/ltp/results/%s -I 1 -d /opt/ltp' % (ltp_group, ltp_group)
|
||||
|
||||
starttime = time.time()
|
||||
(status, output) = self.target.run(cmd, timeout=1200)
|
||||
endtime = time.time()
|
||||
|
||||
# status of 1 is 'just' tests failing. 255 likely was a command output timeout
|
||||
if status and status != 1:
|
||||
msg = 'Command %s returned exit code %s' % (cmd, status)
|
||||
self.target.logger.warning(msg)
|
||||
|
||||
# Write the console log to disk for convenience
|
||||
with open(os.path.join(self.ltptest_log_dir, "%s-raw.log" % ltp_group), 'w') as f:
|
||||
f.write(output)
|
||||
|
||||
# Also put the console log into the test result JSON
|
||||
self.extras['ltpresult.rawlogs']['log'] = self.extras['ltpresult.rawlogs']['log'] + output
|
||||
|
||||
# Copy the machine-readable test results locally so we can parse it
|
||||
dst = os.path.join(self.ltptest_log_dir, ltp_group)
|
||||
remote_src = "/opt/ltp/results/%s" % ltp_group
|
||||
(status, output) = self.target.copyFrom(remote_src, dst, True)
|
||||
if status:
|
||||
msg = 'File could not be copied. Output: %s' % output
|
||||
self.target.logger.warning(msg)
|
||||
|
||||
parser = LtpParser()
|
||||
results, sections = parser.parse(dst)
|
||||
|
||||
sections['duration'] = int(endtime-starttime)
|
||||
self.sections[ltp_group] = sections
|
||||
|
||||
failed_tests = {}
|
||||
for test in results:
|
||||
result = results[test]
|
||||
testname = ("ltpresult." + ltp_group + "." + test)
|
||||
self.extras[testname] = {'status': result}
|
||||
if result == 'FAILED':
|
||||
failed_tests[ltp_group] = test
|
||||
|
||||
if failed_tests:
|
||||
self.failmsg = self.failmsg + "Failed ptests:\n%s" % pprint.pformat(failed_tests)
|
||||
|
||||
# LTP runtime tests
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(["ltp"])
|
||||
def test_ltp_help(self):
|
||||
(status, output) = self.target.run('/opt/ltp/runltp --help')
|
||||
msg = 'Failed to get ltp help. Output: %s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
@OETestDepends(['ltp.LtpTest.test_ltp_help'])
|
||||
def test_ltp_groups(self):
|
||||
for ltp_group in self.ltp_groups:
|
||||
self.runltp(ltp_group)
|
||||
|
||||
@OETestDepends(['ltp.LtpTest.test_ltp_groups'])
|
||||
def test_ltp_runltp_cve(self):
|
||||
self.runltp("cve")
|
||||
97
sources/poky/meta/lib/oeqa/runtime/cases/ltp_compliance.py
Normal file
97
sources/poky/meta/lib/oeqa/runtime/cases/ltp_compliance.py
Normal file
@@ -0,0 +1,97 @@
|
||||
# LTP compliance runtime
|
||||
#
|
||||
# Copyright (c) 2019 MontaVista Software, LLC
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
|
||||
import time
|
||||
import datetime
|
||||
import pprint
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
from oeqa.utils.logparser import LtpComplianceParser
|
||||
|
||||
class LtpPosixBase(OERuntimeTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.ltp_startup()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls.ltp_finishup()
|
||||
|
||||
@classmethod
|
||||
def ltp_startup(cls):
|
||||
cls.sections = {}
|
||||
cls.failmsg = ""
|
||||
test_log_dir = os.path.join(cls.td.get('WORKDIR', ''), 'testimage')
|
||||
timestamp = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
|
||||
|
||||
cls.ltptest_log_dir_link = os.path.join(test_log_dir, 'ltpcomp_log')
|
||||
cls.ltptest_log_dir = '%s.%s' % (cls.ltptest_log_dir_link, timestamp)
|
||||
os.makedirs(cls.ltptest_log_dir)
|
||||
|
||||
cls.tc.target.run("mkdir -p /opt/ltp/results")
|
||||
|
||||
if not hasattr(cls.tc, "extraresults"):
|
||||
cls.tc.extraresults = {}
|
||||
cls.extras = cls.tc.extraresults
|
||||
cls.extras['ltpposixresult.rawlogs'] = {'log': ""}
|
||||
|
||||
|
||||
@classmethod
|
||||
def ltp_finishup(cls):
|
||||
cls.extras['ltpposixresult.sections'] = cls.sections
|
||||
|
||||
# update symlink to ltp_log
|
||||
if os.path.exists(cls.ltptest_log_dir_link):
|
||||
os.remove(cls.ltptest_log_dir_link)
|
||||
|
||||
os.symlink(os.path.basename(cls.ltptest_log_dir), cls.ltptest_log_dir_link)
|
||||
|
||||
if cls.failmsg:
|
||||
cls.fail(cls.failmsg)
|
||||
|
||||
class LtpPosixTest(LtpPosixBase):
|
||||
posix_groups = ["AIO", "MEM", "MSG", "SEM", "SIG", "THR", "TMR", "TPS"]
|
||||
|
||||
def runltp(self, posix_group):
|
||||
cmd = "/opt/ltp/bin/run-posix-option-group-test.sh %s 2>@1 | tee /opt/ltp/results/%s" % (posix_group, posix_group)
|
||||
starttime = time.time()
|
||||
(status, output) = self.target.run(cmd)
|
||||
endtime = time.time()
|
||||
|
||||
with open(os.path.join(self.ltptest_log_dir, "%s" % posix_group), 'w') as f:
|
||||
f.write(output)
|
||||
|
||||
self.extras['ltpposixresult.rawlogs']['log'] = self.extras['ltpposixresult.rawlogs']['log'] + output
|
||||
|
||||
parser = LtpComplianceParser()
|
||||
results, sections = parser.parse(os.path.join(self.ltptest_log_dir, "%s" % posix_group))
|
||||
|
||||
runtime = int(endtime-starttime)
|
||||
sections['duration'] = runtime
|
||||
self.sections[posix_group] = sections
|
||||
|
||||
failed_tests = {}
|
||||
for test in results:
|
||||
result = results[test]
|
||||
testname = ("ltpposixresult." + posix_group + "." + test)
|
||||
self.extras[testname] = {'status': result}
|
||||
if result == 'FAILED':
|
||||
failed_tests[posix_group] = test
|
||||
|
||||
if failed_tests:
|
||||
self.failmsg = self.failmsg + "Failed ptests:\n%s" % pprint.pformat(failed_tests)
|
||||
|
||||
# LTP Posix compliance runtime tests
|
||||
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(["ltp"])
|
||||
def test_posix_groups(self):
|
||||
for posix_group in self.posix_groups:
|
||||
self.runltp(posix_group)
|
||||
97
sources/poky/meta/lib/oeqa/runtime/cases/ltp_stress.py
Normal file
97
sources/poky/meta/lib/oeqa/runtime/cases/ltp_stress.py
Normal file
@@ -0,0 +1,97 @@
|
||||
# LTP Stress runtime
|
||||
#
|
||||
# Copyright (c) 2019 MontaVista Software, LLC
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
import time
|
||||
import datetime
|
||||
import pprint
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
from oeqa.core.decorator.data import skipIfQemu
|
||||
from oeqa.utils.logparser import LtpParser
|
||||
|
||||
class LtpStressBase(OERuntimeTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.ltp_startup()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls.ltp_finishup()
|
||||
|
||||
@classmethod
|
||||
def ltp_startup(cls):
|
||||
cls.sections = {}
|
||||
cls.failmsg = ""
|
||||
test_log_dir = os.path.join(cls.td.get('WORKDIR', ''), 'testimage')
|
||||
timestamp = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
|
||||
|
||||
cls.ltptest_log_dir_link = os.path.join(test_log_dir, 'ltpstress_log')
|
||||
cls.ltptest_log_dir = '%s.%s' % (cls.ltptest_log_dir_link, timestamp)
|
||||
os.makedirs(cls.ltptest_log_dir)
|
||||
|
||||
cls.tc.target.run("mkdir -p /opt/ltp/results")
|
||||
|
||||
if not hasattr(cls.tc, "extraresults"):
|
||||
cls.tc.extraresults = {}
|
||||
cls.extras = cls.tc.extraresults
|
||||
cls.extras['ltpstressresult.rawlogs'] = {'log': ""}
|
||||
|
||||
|
||||
@classmethod
|
||||
def ltp_finishup(cls):
|
||||
cls.extras['ltpstressresult.sections'] = cls.sections
|
||||
|
||||
# update symlink to ltp_log
|
||||
if os.path.exists(cls.ltptest_log_dir_link):
|
||||
os.remove(cls.ltptest_log_dir_link)
|
||||
|
||||
os.symlink(os.path.basename(cls.ltptest_log_dir), cls.ltptest_log_dir_link)
|
||||
|
||||
if cls.failmsg:
|
||||
cls.fail(cls.failmsg)
|
||||
|
||||
class LtpStressTest(LtpStressBase):
|
||||
|
||||
def runltp(self, stress_group):
|
||||
cmd = '/opt/ltp/runltp -f %s -p -q 2>@1 | tee /opt/ltp/results/%s' % (stress_group, stress_group)
|
||||
starttime = time.time()
|
||||
(status, output) = self.target.run(cmd)
|
||||
endtime = time.time()
|
||||
with open(os.path.join(self.ltptest_log_dir, "%s" % stress_group), 'w') as f:
|
||||
f.write(output)
|
||||
|
||||
self.extras['ltpstressresult.rawlogs']['log'] = self.extras['ltpstressresult.rawlogs']['log'] + output
|
||||
|
||||
parser = LtpParser()
|
||||
results, sections = parser.parse(os.path.join(self.ltptest_log_dir, "%s" % stress_group))
|
||||
|
||||
runtime = int(endtime-starttime)
|
||||
sections['duration'] = runtime
|
||||
self.sections[stress_group] = sections
|
||||
|
||||
failed_tests = {}
|
||||
for test in results:
|
||||
result = results[test]
|
||||
testname = ("ltpstressresult." + stress_group + "." + test)
|
||||
self.extras[testname] = {'status': result}
|
||||
if result == 'FAILED':
|
||||
failed_tests[stress_group] = test
|
||||
|
||||
if failed_tests:
|
||||
self.failmsg = self.failmsg + "Failed ptests:\n%s" % pprint.pformat(failed_tests)
|
||||
|
||||
# LTP stress runtime tests
|
||||
#
|
||||
@skipIfQemu()
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(["ltp"])
|
||||
def test_ltp_stress(self):
|
||||
self.tc.target.run("sed -i -r 's/^fork12.*//' /opt/ltp/runtest/crashme")
|
||||
self.runltp('crashme')
|
||||
58
sources/poky/meta/lib/oeqa/runtime/cases/maturin.py
Normal file
58
sources/poky/meta/lib/oeqa/runtime/cases/maturin.py
Normal file
@@ -0,0 +1,58 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
import os
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
|
||||
class MaturinTest(OERuntimeTestCase):
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh', 'python.PythonTest.test_python3'])
|
||||
@OEHasPackage(['python3-maturin'])
|
||||
def test_maturin_list_python(self):
|
||||
status, output = self.target.run("maturin list-python")
|
||||
self.assertEqual(status, 0)
|
||||
_, py_major = self.target.run("python3 -c 'import sys; print(sys.version_info.major)'")
|
||||
_, py_minor = self.target.run("python3 -c 'import sys; print(sys.version_info.minor)'")
|
||||
python_version = "%s.%s" % (py_major, py_minor)
|
||||
self.assertEqual(output, "🐍 1 python interpreter found:\n"
|
||||
" - CPython %s at /usr/bin/python%s" % (python_version, python_version))
|
||||
|
||||
|
||||
class MaturinDevelopTest(OERuntimeTestCase):
|
||||
@classmethod
|
||||
def setUp(cls):
|
||||
dst = '/tmp'
|
||||
src = os.path.join(cls.tc.files_dir, "maturin/guessing-game")
|
||||
cls.tc.target.copyTo(src, dst)
|
||||
|
||||
@classmethod
|
||||
def tearDown(cls):
|
||||
cls.tc.target.run('rm -rf %s' % '/tmp/guessing-game/target')
|
||||
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh', 'python.PythonTest.test_python3'])
|
||||
@OEHasPackage(['python3-maturin'])
|
||||
def test_maturin_develop(self):
|
||||
"""
|
||||
This test case requires:
|
||||
(1) that a .venv can been created.
|
||||
(2) DNS nameserver to resolve crate URIs for fetching
|
||||
(3) a functional 'rustc' and 'cargo'
|
||||
"""
|
||||
targetdir = os.path.join("/tmp", "guessing-game")
|
||||
self.target.run("cd %s; python3 -m venv .venv" % targetdir)
|
||||
self.target.run("echo 'nameserver 8.8.8.8' > /etc/resolv.conf")
|
||||
cmd = "cd %s; maturin develop" % targetdir
|
||||
status, output = self.target.run(cmd)
|
||||
self.assertRegex(output, r"🔗 Found pyo3 bindings with abi3 support for Python ≥ 3.8")
|
||||
self.assertRegex(output, r"🐍 Not using a specific python interpreter")
|
||||
self.assertRegex(output, r"📡 Using build options features from pyproject.toml")
|
||||
self.assertRegex(output, r"Compiling guessing-game v0.1.0")
|
||||
self.assertRegex(output, r"📦 Built wheel for abi3 Python ≥ 3.8")
|
||||
self.assertRegex(output, r"🛠 Installed guessing-game-0.1.0")
|
||||
self.assertEqual(status, 0)
|
||||
49
sources/poky/meta/lib/oeqa/runtime/cases/multilib.py
Normal file
49
sources/poky/meta/lib/oeqa/runtime/cases/multilib.py
Normal file
@@ -0,0 +1,49 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.core.decorator.data import skipIfNotInDataVar
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
import subprocess
|
||||
|
||||
class MultilibTest(OERuntimeTestCase):
|
||||
|
||||
def archtest(self, binary, arch):
|
||||
"""
|
||||
Check that ``binary`` has the ELF class ``arch`` (e.g. ELF32/ELF64).
|
||||
"""
|
||||
|
||||
dest = "{}/test_binary".format(self.td.get('T', ''))
|
||||
self.target.copyFrom(binary, dest)
|
||||
output = subprocess.check_output("readelf -h {}".format(dest), shell=True).decode()
|
||||
os.remove(dest)
|
||||
|
||||
l = [l.split()[1] for l in output.split('\n') if "Class:" in l]
|
||||
if l:
|
||||
theclass = l[0]
|
||||
else:
|
||||
self.fail('Cannot parse readelf. Output:\n%s' % output)
|
||||
|
||||
msg = "%s isn't %s (is %s)" % (binary, arch, theclass)
|
||||
self.assertEqual(theclass, arch, msg=msg)
|
||||
|
||||
@skipIfNotInDataVar('MULTILIBS', 'multilib:lib32',
|
||||
"This isn't a multilib:lib32 image")
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(['lib32-libc6'])
|
||||
def test_check_multilib_libc(self):
|
||||
"""
|
||||
Check that a multilib image has both 32-bit and 64-bit libc in.
|
||||
"""
|
||||
self.archtest("/lib/libc.so.6", "ELF32")
|
||||
self.archtest("/lib64/libc.so.6", "ELF64")
|
||||
|
||||
@OETestDepends(['multilib.MultilibTest.test_check_multilib_libc'])
|
||||
@OEHasPackage(['lib32-connman'])
|
||||
def test_file_connman(self):
|
||||
self.archtest("/usr/sbin/connmand", "ELF32")
|
||||
138
sources/poky/meta/lib/oeqa/runtime/cases/oe_syslog.py
Normal file
138
sources/poky/meta/lib/oeqa/runtime/cases/oe_syslog.py
Normal file
@@ -0,0 +1,138 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.core.decorator.data import skipIfDataVar
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
import time
|
||||
|
||||
class SyslogTest(OERuntimeTestCase):
|
||||
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(["busybox-syslog", "sysklogd", "rsyslog", "syslog-ng"])
|
||||
def test_syslog_running(self):
|
||||
status, output = self.target.run(self.tc.target_cmds['ps'])
|
||||
msg = "Failed to execute %s" % self.tc.target_cmds['ps']
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
msg = "No syslog daemon process; %s output:\n%s" % (self.tc.target_cmds['ps'], output)
|
||||
hasdaemon = "syslogd" in output or "syslog-ng" in output or "svlogd" in output
|
||||
self.assertTrue(hasdaemon, msg=msg)
|
||||
|
||||
class SyslogTestConfig(OERuntimeTestCase):
|
||||
|
||||
def verif_not_running(self, pids):
|
||||
for pid in pids:
|
||||
status, err_output = self.target.run('kill -0 %s' %pid)
|
||||
if not status:
|
||||
self.logger.debug("previous %s is still running" %pid)
|
||||
return 1
|
||||
|
||||
def verify_running(self, names):
|
||||
pids = []
|
||||
for name in names:
|
||||
status, pid = self.target.run('pidof %s' %name)
|
||||
if status:
|
||||
self.logger.debug("%s is not running" %name)
|
||||
return 1, pids
|
||||
pids.append(pid)
|
||||
return 0, pids
|
||||
|
||||
|
||||
def restart_sanity(self, names, restart_cmd, pidchange=True):
|
||||
status, original_pids = self.verify_running(names)
|
||||
if status:
|
||||
return False
|
||||
|
||||
status, output = self.target.run(restart_cmd)
|
||||
|
||||
msg = ('Could not restart %s service. Status and output: %s and %s' % (names, status, output))
|
||||
self.assertEqual(status, 0, msg)
|
||||
|
||||
if not pidchange:
|
||||
return True
|
||||
|
||||
# Always check for an error, most likely a race between shutting down and starting up
|
||||
timeout = time.time() + 30
|
||||
|
||||
restarted = False
|
||||
status = ""
|
||||
while time.time() < timeout:
|
||||
# Verify the previous ones are no longer running
|
||||
status = self.verif_not_running(original_pids)
|
||||
if status:
|
||||
status = "Original syslog processes still running"
|
||||
continue
|
||||
|
||||
status, pids = self.verify_running(names)
|
||||
if status:
|
||||
status = "New syslog processes not running"
|
||||
continue
|
||||
|
||||
# Everything is fine now, so exit to continue the test
|
||||
restarted = True
|
||||
break
|
||||
|
||||
msg = ('%s didn\'t appear to restart: %s' % (names, status))
|
||||
self.assertTrue(restarted, msg)
|
||||
|
||||
return True
|
||||
|
||||
@OETestDepends(['oe_syslog.SyslogTest.test_syslog_running'])
|
||||
def test_syslog_logger(self):
|
||||
status, output = self.target.run('logger foobar')
|
||||
msg = "Can't log into syslog. Output: %s " % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
# There is no way to flush the logger to disk in all cases
|
||||
time.sleep(1)
|
||||
|
||||
status, output = self.target.run('grep foobar /var/log/messages')
|
||||
if status != 0:
|
||||
if self.tc.td.get("VIRTUAL-RUNTIME_init_manager") == "systemd":
|
||||
status, output = self.target.run('journalctl -o cat | grep foobar')
|
||||
else:
|
||||
status, output = self.target.run('logread | grep foobar')
|
||||
msg = ('Test log string not found in /var/log/messages or logread.'
|
||||
' Output: %s ' % output)
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
|
||||
@OETestDepends(['oe_syslog.SyslogTest.test_syslog_running'])
|
||||
def test_syslog_restart(self):
|
||||
if self.restart_sanity(['systemd-journald'], 'systemctl restart syslog.service', pidchange=False):
|
||||
pass
|
||||
elif self.restart_sanity(['rsyslogd'], '/etc/init.d/rsyslog restart'):
|
||||
pass
|
||||
elif self.restart_sanity(['syslogd', 'klogd'], '/etc/init.d/syslog restart'):
|
||||
pass
|
||||
else:
|
||||
self.logger.info("No syslog found to restart, ignoring")
|
||||
|
||||
|
||||
@OETestDepends(['oe_syslog.SyslogTestConfig.test_syslog_logger'])
|
||||
@OEHasPackage(["busybox-syslog"])
|
||||
@skipIfDataVar('VIRTUAL-RUNTIME_init_manager', 'systemd',
|
||||
'Not appropriate for systemd image')
|
||||
def test_syslog_startup_config(self):
|
||||
cmd = 'echo "LOGFILE=/var/log/test" >> /etc/syslog-startup.conf'
|
||||
self.target.run(cmd)
|
||||
|
||||
self.test_syslog_restart()
|
||||
|
||||
cmd = 'logger foobar'
|
||||
status, output = self.target.run(cmd)
|
||||
msg = 'Logger command failed, %s. Output: %s ' % (status, output)
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
cmd = 'cat /var/log/test'
|
||||
status, output = self.target.run(cmd)
|
||||
if "foobar" not in output or status:
|
||||
self.fail("'foobar' not found in logfile, status %s, contents %s" % (status, output))
|
||||
|
||||
cmd = "sed -i 's#LOGFILE=/var/log/test##' /etc/syslog-startup.conf"
|
||||
self.target.run(cmd)
|
||||
self.test_syslog_restart()
|
||||
60
sources/poky/meta/lib/oeqa/runtime/cases/opkg.py
Normal file
60
sources/poky/meta/lib/oeqa/runtime/cases/opkg.py
Normal file
@@ -0,0 +1,60 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
import os
|
||||
from oeqa.utils.httpserver import HTTPService
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.data import skipIfNotDataVar, skipIfNotFeature, skipIfFeature
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
class OpkgTest(OERuntimeTestCase):
|
||||
|
||||
def pkg(self, command, expected = 0):
|
||||
command = 'opkg %s' % command
|
||||
status, output = self.target.run(command, 1500)
|
||||
message = os.linesep.join([command, output])
|
||||
self.assertEqual(status, expected, message)
|
||||
return output
|
||||
|
||||
class OpkgRepoTest(OpkgTest):
|
||||
|
||||
@classmethod
|
||||
def setUp(cls):
|
||||
allarchfeed = 'all'
|
||||
if cls.tc.td["MULTILIB_VARIANTS"]:
|
||||
allarchfeed = cls.tc.td["TUNE_PKGARCH"]
|
||||
service_repo = os.path.join(cls.tc.td['DEPLOY_DIR_IPK'], allarchfeed)
|
||||
cls.repo_server = HTTPService(service_repo,
|
||||
'0.0.0.0', port=cls.tc.target.server_port,
|
||||
logger=cls.tc.logger)
|
||||
cls.repo_server.start()
|
||||
|
||||
@classmethod
|
||||
def tearDown(cls):
|
||||
cls.repo_server.stop()
|
||||
|
||||
def setup_source_config_for_package_install(self):
|
||||
apt_get_source_server = 'http://%s:%s/' % (self.tc.target.server_ip, self.repo_server.port)
|
||||
apt_get_sourceslist_dir = '/etc/opkg/'
|
||||
self.target.run('cd %s; echo src/gz all %s >> opkg.conf' % (apt_get_sourceslist_dir, apt_get_source_server))
|
||||
|
||||
def cleanup_source_config_for_package_install(self):
|
||||
apt_get_sourceslist_dir = '/etc/opkg/'
|
||||
self.target.run('cd %s; sed -i "/^src/d" opkg.conf' % (apt_get_sourceslist_dir))
|
||||
|
||||
@skipIfNotFeature('package-management',
|
||||
'Test requires package-management to be in IMAGE_FEATURES')
|
||||
@skipIfNotDataVar('IMAGE_PKGTYPE', 'ipk',
|
||||
'IPK is not the primary package manager')
|
||||
@skipIfFeature('read-only-rootfs',
|
||||
'Test does not work with read-only-rootfs in IMAGE_FEATURES')
|
||||
@OEHasPackage(['opkg'])
|
||||
def test_opkg_install_from_repo(self):
|
||||
self.setup_source_config_for_package_install()
|
||||
self.pkg('update')
|
||||
self.pkg('remove run-postinsts-dev')
|
||||
self.pkg('install run-postinsts-dev')
|
||||
self.cleanup_source_config_for_package_install()
|
||||
40
sources/poky/meta/lib/oeqa/runtime/cases/pam.py
Normal file
40
sources/poky/meta/lib/oeqa/runtime/cases/pam.py
Normal file
@@ -0,0 +1,40 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
# This test should cover https://bugzilla.yoctoproject.org/tr_show_case.cgi?case_id=287 testcase
|
||||
# Note that the image under test must have "pam" in DISTRO_FEATURES
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.core.decorator.data import skipIfNotFeature
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
class PamBasicTest(OERuntimeTestCase):
|
||||
|
||||
@skipIfNotFeature('pam', 'Test requires pam to be in DISTRO_FEATURES')
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(['shadow'])
|
||||
@OEHasPackage(['shadow-base'])
|
||||
def test_pam(self):
|
||||
status, output = self.target.run('login --help')
|
||||
msg = ('login command does not work as expected. '
|
||||
'Status and output:%s and %s' % (status, output))
|
||||
self.assertEqual(status, 1, msg = msg)
|
||||
|
||||
status, output = self.target.run('passwd --help')
|
||||
msg = ('passwd command does not work as expected. '
|
||||
'Status and output:%s and %s' % (status, output))
|
||||
self.assertEqual(status, 0, msg = msg)
|
||||
|
||||
status, output = self.target.run('su --help')
|
||||
msg = ('su command does not work as expected. '
|
||||
'Status and output:%s and %s' % (status, output))
|
||||
self.assertEqual(status, 0, msg = msg)
|
||||
|
||||
status, output = self.target.run('useradd --help')
|
||||
msg = ('useradd command does not work as expected. '
|
||||
'Status and output:%s and %s' % (status, output))
|
||||
self.assertEqual(status, 0, msg = msg)
|
||||
@@ -0,0 +1,62 @@
|
||||
# Xserver explains what the short codes mean
|
||||
(WW) warning, (EE) error, (NI) not implemented, (??) unknown.
|
||||
|
||||
# Xserver warns if compiled with ACPI but no acpid running
|
||||
Open ACPI failed (/var/run/acpid.socket) (No such file or directory)
|
||||
|
||||
# Some machines (eg qemux86) don't enable PAE (they probably should though)
|
||||
NX (Execute Disable) protection cannot be enabled: non-PAE kernel!
|
||||
|
||||
# Connman's pacrunner warns if external connectivity isn't available
|
||||
Failed to find URL:http://ipv4.connman.net/online/status.html
|
||||
Failed to find URL:http://ipv6.connman.net/online/status.html
|
||||
|
||||
# x86 on 6.6+ outputs this message, it is informational, not an error
|
||||
ACPI: _OSC evaluation for CPUs failed, trying _PDC
|
||||
|
||||
# These should be reviewed to see if they are still needed
|
||||
dma timeout
|
||||
can\'t add hid device:
|
||||
usbhid: probe of
|
||||
_OSC failed (AE_ERROR)
|
||||
_OSC failed (AE_SUPPORT)
|
||||
AE_ALREADY_EXISTS
|
||||
ACPI _OSC request failed (AE_SUPPORT)
|
||||
can\'t disable ASPM
|
||||
Failed to load module "vesa"
|
||||
Failed to load module "modesetting"
|
||||
Failed to load module "glx"
|
||||
Failed to load module "fbdev"
|
||||
Failed to load module "ati"
|
||||
[drm] Cannot find any crtc or sizes
|
||||
_OSC failed (AE_NOT_FOUND); disabling ASPM
|
||||
hd.: possibly failed opcode
|
||||
NETLINK INITIALIZATION FAILED
|
||||
kernel: Cannot find map file
|
||||
omap_hwmod: debugss: _wait_target_disable failed
|
||||
VGA arbiter: cannot open kernel arbiter, no multi-card support
|
||||
Online check failed for
|
||||
netlink init failed
|
||||
Fast TSC calibration
|
||||
controller can't do DEVSLP, turning off
|
||||
stmmac_dvr_probe: warning: cannot get CSR clock
|
||||
error: couldn\'t mount because of unsupported optional features
|
||||
GPT: Use GNU Parted to correct GPT errors
|
||||
Cannot set xattr user.Librepo.DownloadInProgress
|
||||
Failed to read /var/lib/nfs/statd/state: Success
|
||||
error retry time-out =
|
||||
logind: cannot setup systemd-logind helper (-61), using legacy fallback
|
||||
Failed to rename network interface
|
||||
Failed to process device, ignoring: Device or resource busy
|
||||
Cannot find a map file
|
||||
[rdrand]: Initialization Failed
|
||||
[rndr ]: Initialization Failed
|
||||
[pulseaudio] authkey.c: Failed to open cookie file
|
||||
[pulseaudio] authkey.c: Failed to load authentication key
|
||||
was skipped because of a failed condition check
|
||||
was skipped because all trigger condition checks failed
|
||||
xf86OpenConsole: Switching VT failed
|
||||
Failed to read LoaderConfigTimeoutOneShot variable, ignoring: Operation not supported
|
||||
Failed to read LoaderEntryOneShot variable, ignoring: Operation not supported
|
||||
Direct firmware load for regulatory.db
|
||||
failed to load regulatory.db
|
||||
@@ -0,0 +1,2 @@
|
||||
# These should be reviewed to see if they are still needed
|
||||
cacheinfo: Failed to find cpu0 device node
|
||||
@@ -0,0 +1,27 @@
|
||||
# psplash
|
||||
FBIOPUT_VSCREENINFO failed, double buffering disabled
|
||||
|
||||
# PCI host bridge to bus 0000:00
|
||||
# pci_bus 0000:00: root bus resource [mem 0x10000000-0x17ffffff]
|
||||
# pci_bus 0000:00: root bus resource [io 0x1000-0x1fffff]
|
||||
# pci_bus 0000:00: No busn resource found for root bus, will use [bus 00-ff]
|
||||
# pci 0000:00:00.0: [2046:ab11] type 00 class 0x100000
|
||||
# pci 0000:00:00.0: [Firmware Bug]: reg 0x10: invalid BAR (can't size)
|
||||
# pci 0000:00:00.0: [Firmware Bug]: reg 0x14: invalid BAR (can't size)
|
||||
# pci 0000:00:00.0: [Firmware Bug]: reg 0x18: invalid BAR (can't size)
|
||||
# pci 0000:00:00.0: [Firmware Bug]: reg 0x1c: invalid BAR (can't size)
|
||||
# pci 0000:00:00.0: [Firmware Bug]: reg 0x20: invalid BAR (can't size)
|
||||
# pci 0000:00:00.0: [Firmware Bug]: reg 0x24: invalid BAR (can't size)
|
||||
invalid BAR (can't size)
|
||||
|
||||
# These should be reviewed to see if they are still needed
|
||||
wrong ELF class
|
||||
fail to add MMCONFIG information, can't access extended PCI configuration space under this bridge
|
||||
can't claim BAR
|
||||
amd_nb: Cannot enumerate AMD northbridges
|
||||
tsc: HPET/PMTIMER calibration failed
|
||||
modeset(0): Failed to initialize the DRI2 extension
|
||||
glamor initialization failed
|
||||
blk_update_request: I/O error, dev fd0, sector 0 op 0x0:(READ)
|
||||
floppy: error
|
||||
failed to IDENTIFY (I/O error, err_mask=0x4)
|
||||
@@ -0,0 +1,6 @@
|
||||
# These should be reviewed to see if they are still needed
|
||||
Fatal server error:
|
||||
(EE) Server terminated with error (1). Closing log file.
|
||||
dmi: Firmware registration failed.
|
||||
irq: type mismatch, failed to map hwirq-27 for /intc
|
||||
logind: failed to get session seat
|
||||
@@ -0,0 +1,19 @@
|
||||
# Code is 2 JENT_ECOARSETIME: Timer too coarse for RNG.
|
||||
jitterentropy: Initialization failed with host not compliant with requirements: 2
|
||||
|
||||
# These should be reviewed to see if they are still needed
|
||||
mmci-pl18x: probe of fpga:05 failed with error -22
|
||||
mmci-pl18x: probe of fpga:0b failed with error -22
|
||||
|
||||
OF: amba_device_add() failed (-19) for /amba/smc@10100000
|
||||
OF: amba_device_add() failed (-19) for /amba/mpmc@10110000
|
||||
OF: amba_device_add() failed (-19) for /amba/sctl@101e0000
|
||||
OF: amba_device_add() failed (-19) for /amba/watchdog@101e1000
|
||||
OF: amba_device_add() failed (-19) for /amba/sci@101f0000
|
||||
OF: amba_device_add() failed (-19) for /amba/spi@101f4000
|
||||
OF: amba_device_add() failed (-19) for /amba/ssp@101f4000
|
||||
OF: amba_device_add() failed (-19) for /amba/fpga/sci@a000
|
||||
Failed to initialize '/amba/timer@101e3000': -22
|
||||
|
||||
clcd-pl11x: probe of 10120000.display failed with error -2
|
||||
arm-charlcd 10008000.lcd: error -ENXIO: IRQ index 0 not found
|
||||
@@ -0,0 +1,6 @@
|
||||
# These should be reviewed to see if they are still needed
|
||||
PCI 0000:00 Cannot reserve Legacy IO [io 0x0000-0x0fff]
|
||||
host side 80-wire cable detection failed, limiting max speed
|
||||
mode "640x480" test failed
|
||||
can't handle BAR above 4GB
|
||||
Cannot reserve Legacy IO
|
||||
@@ -0,0 +1,4 @@
|
||||
# These should be reviewed to see if they are still needed
|
||||
vio vio: uevent: failed to send synthetic uevent
|
||||
synth uevent: /devices/vio: failed to send uevent
|
||||
PCI 0000:00 Cannot reserve Legacy IO [io 0x10000-0x10fff]
|
||||
@@ -0,0 +1,2 @@
|
||||
# These should be reviewed to see if they are still needed
|
||||
Failed to access perfctr msr (MSR
|
||||
@@ -0,0 +1,10 @@
|
||||
# These should be reviewed to see if they are still needed
|
||||
[drm:psb_do_init] *ERROR* Debug is
|
||||
wrong ELF class
|
||||
Could not enable PowerButton event
|
||||
probe of LNXPWRBN:00 failed with error -22
|
||||
pmd_set_huge: Cannot satisfy
|
||||
failed to setup card detect gpio
|
||||
amd_nb: Cannot enumerate AMD northbridges
|
||||
failed to retrieve link info, disabling eDP
|
||||
Direct firmware load for iwlwifi
|
||||
@@ -0,0 +1 @@
|
||||
parselogs-ignores-x86.txt
|
||||
185
sources/poky/meta/lib/oeqa/runtime/cases/parselogs.py
Normal file
185
sources/poky/meta/lib/oeqa/runtime/cases/parselogs.py
Normal file
@@ -0,0 +1,185 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
import collections
|
||||
import os
|
||||
import sys
|
||||
|
||||
from shutil import rmtree
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
|
||||
# importlib.resources.open_text in Python <3.10 doesn't search all directories
|
||||
# when a package is split across multiple directories. Until we can rely on
|
||||
# 3.10+, reimplement the searching logic.
|
||||
if sys.version_info < (3, 10):
|
||||
def _open_text(package, resource):
|
||||
import importlib, pathlib
|
||||
module = importlib.import_module(package)
|
||||
for path in module.__path__:
|
||||
candidate = pathlib.Path(path) / resource
|
||||
if candidate.exists():
|
||||
return candidate.open(encoding='utf-8')
|
||||
raise FileNotFoundError
|
||||
else:
|
||||
from importlib.resources import open_text as _open_text
|
||||
|
||||
|
||||
class ParseLogsTest(OERuntimeTestCase):
|
||||
|
||||
# Which log files should be collected
|
||||
log_locations = ["/var/log/", "/var/log/dmesg", "/tmp/dmesg_output.log"]
|
||||
|
||||
# The keywords that identify error messages in the log files
|
||||
errors = ["error", "cannot", "can't", "failed"]
|
||||
|
||||
# A list of error messages that should be ignored
|
||||
ignore_errors = []
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
# When systemd is enabled we need to notice errors on
|
||||
# circular dependencies in units.
|
||||
if 'systemd' in cls.td.get('DISTRO_FEATURES'):
|
||||
cls.errors.extend([
|
||||
'Found ordering cycle on',
|
||||
'Breaking ordering cycle by deleting job',
|
||||
'deleted to break ordering cycle',
|
||||
'Ordering cycle found, skipping',
|
||||
])
|
||||
|
||||
cls.errors = [s.casefold() for s in cls.errors]
|
||||
|
||||
cls.load_machine_ignores()
|
||||
|
||||
@classmethod
|
||||
def load_machine_ignores(cls):
|
||||
# Add TARGET_ARCH explicitly as not every machine has that in MACHINEOVERRDES (eg qemux86-64)
|
||||
for candidate in ["common", cls.td.get("TARGET_ARCH")] + cls.td.get("MACHINEOVERRIDES").split(":"):
|
||||
try:
|
||||
name = f"parselogs-ignores-{candidate}.txt"
|
||||
for line in _open_text("oeqa.runtime.cases", name):
|
||||
line = line.strip()
|
||||
if line and not line.startswith("#"):
|
||||
cls.ignore_errors.append(line.casefold())
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
# Go through the log locations provided and if it's a folder
|
||||
# create a list with all the .log files in it, if it's a file
|
||||
# just add it to that list.
|
||||
def getLogList(self, log_locations):
|
||||
logs = []
|
||||
for location in log_locations:
|
||||
status, _ = self.target.run('test -f %s' % location)
|
||||
if status == 0:
|
||||
logs.append(location)
|
||||
else:
|
||||
status, _ = self.target.run('test -d %s' % location)
|
||||
if status == 0:
|
||||
cmd = 'find %s -name \\*.log -maxdepth 1 -type f' % location
|
||||
status, output = self.target.run(cmd)
|
||||
if status == 0:
|
||||
output = output.splitlines()
|
||||
for logfile in output:
|
||||
logs.append(os.path.join(location, logfile))
|
||||
return logs
|
||||
|
||||
# Copy the log files to be parsed locally
|
||||
def transfer_logs(self, log_list):
|
||||
workdir = self.td.get('WORKDIR')
|
||||
self.target_logs = workdir + '/' + 'target_logs'
|
||||
target_logs = self.target_logs
|
||||
if os.path.exists(target_logs):
|
||||
rmtree(self.target_logs)
|
||||
os.makedirs(target_logs)
|
||||
for f in log_list:
|
||||
self.target.copyFrom(str(f), target_logs)
|
||||
|
||||
# Get the local list of logs
|
||||
def get_local_log_list(self, log_locations):
|
||||
self.transfer_logs(self.getLogList(log_locations))
|
||||
list_dir = os.listdir(self.target_logs)
|
||||
dir_files = [os.path.join(self.target_logs, f) for f in list_dir]
|
||||
logs = [f for f in dir_files if os.path.isfile(f)]
|
||||
return logs
|
||||
|
||||
def get_context(self, lines, index, before=6, after=3):
|
||||
"""
|
||||
Given a set of lines and the index of the line that is important, return
|
||||
a number of lines surrounding that line.
|
||||
"""
|
||||
last = len(lines)
|
||||
|
||||
start = index - before
|
||||
end = index + after + 1
|
||||
|
||||
if start < 0:
|
||||
end -= start
|
||||
start = 0
|
||||
if end > last:
|
||||
start -= end - last
|
||||
end = last
|
||||
|
||||
return lines[start:end]
|
||||
|
||||
def test_get_context(self):
|
||||
"""
|
||||
A test case for the test case.
|
||||
"""
|
||||
lines = list(range(0,10))
|
||||
self.assertEqual(self.get_context(lines, 0, 2, 1), [0, 1, 2, 3])
|
||||
self.assertEqual(self.get_context(lines, 5, 2, 1), [3, 4, 5, 6])
|
||||
self.assertEqual(self.get_context(lines, 9, 2, 1), [6, 7, 8, 9])
|
||||
|
||||
def parse_logs(self, logs, lines_before=10, lines_after=10):
|
||||
"""
|
||||
Search the log files @logs looking for error lines (marked by
|
||||
@self.errors), ignoring anything listed in @self.ignore_errors.
|
||||
|
||||
Returns a dictionary of log filenames to a dictionary of error lines to
|
||||
the error context (controlled by @lines_before and @lines_after).
|
||||
"""
|
||||
results = collections.defaultdict(dict)
|
||||
|
||||
for log in logs:
|
||||
with open(log) as f:
|
||||
lines = f.readlines()
|
||||
|
||||
for i, line in enumerate(lines):
|
||||
line = line.strip()
|
||||
line_lower = line.casefold()
|
||||
|
||||
if any(keyword in line_lower for keyword in self.errors):
|
||||
if not any(ignore in line_lower for ignore in self.ignore_errors):
|
||||
results[log][line] = "".join(self.get_context(lines, i, lines_before, lines_after))
|
||||
|
||||
return results
|
||||
|
||||
# Get the output of dmesg and write it in a file.
|
||||
# This file is added to log_locations.
|
||||
def write_dmesg(self):
|
||||
(status, dmesg) = self.target.run('dmesg > /tmp/dmesg_output.log')
|
||||
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
def test_parselogs(self):
|
||||
self.write_dmesg()
|
||||
log_list = self.get_local_log_list(self.log_locations)
|
||||
result = self.parse_logs(log_list)
|
||||
|
||||
errcount = 0
|
||||
self.msg = ""
|
||||
for log in result:
|
||||
self.msg += 'Log: ' + log + '\n'
|
||||
self.msg += '-----------------------\n'
|
||||
for error in result[log]:
|
||||
errcount += 1
|
||||
self.msg += 'Central error: ' + error + '\n'
|
||||
self.msg += '***********************\n'
|
||||
self.msg += result[log][error] + '\n'
|
||||
self.msg += '***********************\n'
|
||||
self.msg += '%s errors found in logs.' % errcount
|
||||
self.assertEqual(errcount, 0, msg=self.msg)
|
||||
19
sources/poky/meta/lib/oeqa/runtime/cases/perl.py
Normal file
19
sources/poky/meta/lib/oeqa/runtime/cases/perl.py
Normal file
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
import os
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
class PerlTest(OERuntimeTestCase):
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(['perl'])
|
||||
def test_perl_works(self):
|
||||
status, output = self.target.run("perl -e '$_=\"Uryyb, jbeyq\"; tr/a-zA-Z/n-za-mN-ZA-M/;print'")
|
||||
self.assertEqual(status, 0)
|
||||
self.assertEqual(output, "Hello, world")
|
||||
35
sources/poky/meta/lib/oeqa/runtime/cases/ping.py
Normal file
35
sources/poky/meta/lib/oeqa/runtime/cases/ping.py
Normal file
@@ -0,0 +1,35 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
from subprocess import Popen, PIPE
|
||||
from time import sleep
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.oetimeout import OETimeout
|
||||
from oeqa.core.exception import OEQATimeoutError
|
||||
|
||||
class PingTest(OERuntimeTestCase):
|
||||
|
||||
@OETimeout(30)
|
||||
def test_ping(self):
|
||||
output = ''
|
||||
count = 0
|
||||
self.assertNotEqual(len(self.target.ip), 0, msg="No target IP address set")
|
||||
try:
|
||||
while count < 5:
|
||||
cmd = 'ping -c 1 %s' % self.target.ip
|
||||
proc = Popen(cmd, shell=True, stdout=PIPE)
|
||||
output += proc.communicate()[0].decode('utf-8')
|
||||
if proc.poll() == 0:
|
||||
count += 1
|
||||
else:
|
||||
count = 0
|
||||
sleep(1)
|
||||
except OEQATimeoutError:
|
||||
self.fail("Ping timeout error for address %s, count %s, output: %s" % (self.target.ip, count, output))
|
||||
msg = ('Expected 5 consecutive, got %d.\n'
|
||||
'ping output is:\n%s' % (count,output))
|
||||
self.assertEqual(count, 5, msg = msg)
|
||||
120
sources/poky/meta/lib/oeqa/runtime/cases/ptest.py
Normal file
120
sources/poky/meta/lib/oeqa/runtime/cases/ptest.py
Normal file
@@ -0,0 +1,120 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
import os
|
||||
import unittest
|
||||
import pprint
|
||||
import datetime
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.core.decorator.data import skipIfNotFeature
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
from oeqa.utils.logparser import PtestParser
|
||||
|
||||
class PtestRunnerTest(OERuntimeTestCase):
|
||||
|
||||
@skipIfNotFeature('ptest', 'Test requires ptest to be in DISTRO_FEATURES')
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(['ptest-runner'])
|
||||
@unittest.expectedFailure
|
||||
def test_ptestrunner_expectfail(self):
|
||||
if not self.td.get('PTEST_EXPECT_FAILURE'):
|
||||
self.skipTest('Cannot run ptests with @expectedFailure as ptests are required to pass')
|
||||
self.do_ptestrunner()
|
||||
|
||||
@skipIfNotFeature('ptest', 'Test requires ptest to be in DISTRO_FEATURES')
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(['ptest-runner'])
|
||||
def test_ptestrunner_expectsuccess(self):
|
||||
if self.td.get('PTEST_EXPECT_FAILURE'):
|
||||
self.skipTest('Cannot run ptests without @expectedFailure as ptests are expected to fail')
|
||||
self.do_ptestrunner()
|
||||
|
||||
def do_ptestrunner(self):
|
||||
status, output = self.target.run('which ptest-runner', 0)
|
||||
if status != 0:
|
||||
self.skipTest("No -ptest packages are installed in the image")
|
||||
|
||||
test_log_dir = self.td.get('TEST_LOG_DIR', '')
|
||||
# The TEST_LOG_DIR maybe NULL when testimage is added after
|
||||
# testdata.json is generated.
|
||||
if not test_log_dir:
|
||||
test_log_dir = os.path.join(self.td.get('WORKDIR', ''), 'testimage')
|
||||
# Make the test output path absolute, otherwise the output content will be
|
||||
# created relative to current directory
|
||||
if not os.path.isabs(test_log_dir):
|
||||
test_log_dir = os.path.join(self.td.get('TOPDIR', ''), test_log_dir)
|
||||
# Don't use self.td.get('DATETIME'), it's from testdata.json, not
|
||||
# up-to-date, and may cause "File exists" when re-reun.
|
||||
timestamp = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
|
||||
ptest_log_dir_link = os.path.join(test_log_dir, 'ptest_log')
|
||||
ptest_log_dir = '%s.%s' % (ptest_log_dir_link, timestamp)
|
||||
ptest_runner_log = os.path.join(ptest_log_dir, 'ptest-runner.log')
|
||||
|
||||
libdir = self.td.get('libdir', '')
|
||||
ptest_dirs = [ '/usr/lib' ]
|
||||
if not libdir in ptest_dirs:
|
||||
ptest_dirs.append(libdir)
|
||||
status, output = self.target.run('ptest-runner -t 450 -d \"{}\"'.format(' '.join(ptest_dirs)), 0)
|
||||
os.makedirs(ptest_log_dir)
|
||||
with open(ptest_runner_log, 'w') as f:
|
||||
f.write(output)
|
||||
|
||||
# status != 0 is OK since some ptest tests may fail
|
||||
self.assertTrue(status != 127, msg="Cannot execute ptest-runner!")
|
||||
|
||||
if not hasattr(self.tc, "extraresults"):
|
||||
self.tc.extraresults = {}
|
||||
extras = self.tc.extraresults
|
||||
extras['ptestresult.rawlogs'] = {'log': output}
|
||||
|
||||
# Parse and save results
|
||||
parser = PtestParser()
|
||||
results, sections = parser.parse(ptest_runner_log)
|
||||
parser.results_as_files(ptest_log_dir)
|
||||
if os.path.exists(ptest_log_dir_link):
|
||||
# Remove the old link to create a new one
|
||||
os.remove(ptest_log_dir_link)
|
||||
os.symlink(os.path.basename(ptest_log_dir), ptest_log_dir_link)
|
||||
|
||||
extras['ptestresult.sections'] = sections
|
||||
|
||||
zerolength = []
|
||||
trans = str.maketrans("()", "__")
|
||||
for section in results:
|
||||
for test in results[section]:
|
||||
result = results[section][test]
|
||||
testname = "ptestresult." + (section or "No-section") + "." + "_".join(test.translate(trans).split())
|
||||
extras[testname] = {'status': result}
|
||||
if not results[section]:
|
||||
zerolength.append(section)
|
||||
|
||||
failed_tests = {}
|
||||
|
||||
for section in sections:
|
||||
if 'exitcode' in sections[section].keys() or 'timeout' in sections[section].keys():
|
||||
failed_tests[section] = sections[section]["log"]
|
||||
|
||||
for section in results:
|
||||
failed_testcases = [ "_".join(test.translate(trans).split()) for test in results[section] if results[section][test] == 'FAILED' ]
|
||||
if failed_testcases:
|
||||
failed_tests[section] = failed_testcases
|
||||
|
||||
failmsg = ""
|
||||
status, output = self.target.run('dmesg | grep "Killed process"', 0)
|
||||
if output:
|
||||
failmsg = "ERROR: Processes were killed by the OOM Killer:\n%s\n" % output
|
||||
|
||||
if failed_tests:
|
||||
failmsg = failmsg + "\nFailed ptests:\n%s\n" % pprint.pformat(failed_tests)
|
||||
|
||||
if zerolength:
|
||||
failmsg = failmsg + "\nptests which had no test results:\n%s" % pprint.pformat(zerolength)
|
||||
|
||||
if failmsg:
|
||||
self.logger.warning("There were failing ptests.")
|
||||
self.fail(failmsg)
|
||||
21
sources/poky/meta/lib/oeqa/runtime/cases/python.py
Normal file
21
sources/poky/meta/lib/oeqa/runtime/cases/python.py
Normal file
@@ -0,0 +1,21 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
class PythonTest(OERuntimeTestCase):
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(['python3-core'])
|
||||
def test_python3(self):
|
||||
cmd = "python3 -c \"import codecs; print(codecs.encode('Uryyb, jbeyq', 'rot13'))\""
|
||||
status, output = self.target.run(cmd)
|
||||
msg = 'Exit status was not 0. Output: %s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
msg = 'Incorrect output: %s' % output
|
||||
self.assertEqual(output, "Hello, world", msg=msg)
|
||||
149
sources/poky/meta/lib/oeqa/runtime/cases/rpm.py
Normal file
149
sources/poky/meta/lib/oeqa/runtime/cases/rpm.py
Normal file
@@ -0,0 +1,149 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
import os
|
||||
import fnmatch
|
||||
import time
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.core.decorator.data import skipIfDataVar
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
from oeqa.core.utils.path import findFile
|
||||
|
||||
class RpmBasicTest(OERuntimeTestCase):
|
||||
|
||||
@OEHasPackage(['rpm'])
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
def test_rpm_help(self):
|
||||
status, output = self.target.run('rpm --help')
|
||||
msg = 'status and output: %s and %s' % (status, output)
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
@OETestDepends(['rpm.RpmBasicTest.test_rpm_help'])
|
||||
def test_rpm_query(self):
|
||||
status, output = self.target.run('ls /var/lib/rpm/')
|
||||
if status != 0:
|
||||
self.skipTest('No /var/lib/rpm on target')
|
||||
status, output = self.target.run('rpm -q rpm')
|
||||
msg = 'status and output: %s and %s' % (status, output)
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
@OETestDepends(['rpm.RpmBasicTest.test_rpm_query'])
|
||||
def test_rpm_query_nonroot(self):
|
||||
|
||||
def set_up_test_user(u):
|
||||
status, output = self.target.run('id -u %s' % u)
|
||||
if status:
|
||||
status, output = self.target.run('useradd %s' % u)
|
||||
msg = 'Failed to create new user: %s' % output
|
||||
self.assertTrue(status == 0, msg=msg)
|
||||
|
||||
def exec_as_test_user(u):
|
||||
status, output = self.target.run('su -c id %s' % u)
|
||||
msg = 'Failed to execute as new user'
|
||||
self.assertTrue("({0})".format(u) in output, msg=msg)
|
||||
|
||||
status, output = self.target.run('su -c "rpm -qa" %s ' % u)
|
||||
msg = 'status: %s. Cannot run rpm -qa: %s' % (status, output)
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
def wait_for_no_process_for_user(u, timeout = 120):
|
||||
timeout_at = time.time() + timeout
|
||||
while time.time() < timeout_at:
|
||||
_, output = self.target.run(self.tc.target_cmds['ps'])
|
||||
if u + ' ' not in output:
|
||||
return
|
||||
time.sleep(1)
|
||||
user_pss = [ps for ps in output.split("\n") if u + ' ' in ps]
|
||||
msg = "User %s has processes still running: %s" % (u, "\n".join(user_pss))
|
||||
self.fail(msg=msg)
|
||||
|
||||
def unset_up_test_user(u):
|
||||
# ensure no test1 process in running
|
||||
wait_for_no_process_for_user(u)
|
||||
status, output = self.target.run('userdel -r %s' % u)
|
||||
msg = 'Failed to erase user: %s' % output
|
||||
self.assertTrue(status == 0, msg=msg)
|
||||
|
||||
tuser = 'test1'
|
||||
|
||||
try:
|
||||
set_up_test_user(tuser)
|
||||
exec_as_test_user(tuser)
|
||||
finally:
|
||||
unset_up_test_user(tuser)
|
||||
|
||||
|
||||
class RpmInstallRemoveTest(OERuntimeTestCase):
|
||||
|
||||
def _find_test_file(self):
|
||||
pkgarch = self.td['TUNE_PKGARCH'].replace('-', '_')
|
||||
rpmdir = os.path.join(self.tc.td['DEPLOY_DIR'], 'rpm', pkgarch)
|
||||
# Pick base-passwd-doc as a test file to get installed, because it's small
|
||||
# and it will always be built for standard targets
|
||||
rpm_doc = 'base-passwd-doc-*.%s.rpm' % pkgarch
|
||||
if not os.path.exists(rpmdir):
|
||||
self.fail("Rpm directory {} does not exist".format(rpmdir))
|
||||
for f in fnmatch.filter(os.listdir(rpmdir), rpm_doc):
|
||||
self.test_file = os.path.join(rpmdir, f)
|
||||
break
|
||||
else:
|
||||
self.fail("Couldn't find the test rpm file {} in {}".format(rpm_doc, rpmdir))
|
||||
self.dst = '/tmp/base-passwd-doc.rpm'
|
||||
|
||||
@OETestDepends(['rpm.RpmBasicTest.test_rpm_query'])
|
||||
def test_rpm_install(self):
|
||||
self._find_test_file()
|
||||
self.tc.target.copyTo(self.test_file, self.dst)
|
||||
status, output = self.target.run('rpm -ivh /tmp/base-passwd-doc.rpm')
|
||||
msg = 'Failed to install base-passwd-doc package: %s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
self.tc.target.run('rm -f %s' % self.dst)
|
||||
|
||||
@OETestDepends(['rpm.RpmInstallRemoveTest.test_rpm_install'])
|
||||
def test_rpm_remove(self):
|
||||
status,output = self.target.run('rpm -e base-passwd-doc')
|
||||
msg = 'Failed to remove base-passwd-doc package: %s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
@OETestDepends(['rpm.RpmInstallRemoveTest.test_rpm_remove'])
|
||||
def test_check_rpm_install_removal_log_file_size(self):
|
||||
"""
|
||||
Summary: Check that rpm writes into /var/log/messages
|
||||
Expected: There should be some RPM prefixed entries in the above file.
|
||||
Product: BSPs
|
||||
Author: Alexandru Georgescu <alexandru.c.georgescu@intel.com>
|
||||
Author: Alexander Kanavin <alex.kanavin@gmail.com>
|
||||
AutomatedBy: Daniel Istrate <daniel.alexandrux.istrate@intel.com>
|
||||
"""
|
||||
self._find_test_file()
|
||||
db_files_cmd = 'ls /var/lib/rpm/rpmdb.sqlite*'
|
||||
check_log_cmd = "grep RPM /var/log/messages | wc -l"
|
||||
|
||||
# Make sure that some database files are under /var/lib/rpm as 'rpmdb.sqlite'
|
||||
status, output = self.target.run(db_files_cmd)
|
||||
msg = 'Failed to find database files under /var/lib/rpm/ as rpmdb.sqlite'
|
||||
self.assertEqual(0, status, msg=msg)
|
||||
|
||||
self.tc.target.copyTo(self.test_file, self.dst)
|
||||
|
||||
# Remove the package just in case
|
||||
self.target.run('rpm -e base-passwd-doc')
|
||||
|
||||
# Install/Remove a package 10 times
|
||||
for i in range(10):
|
||||
status, output = self.target.run('rpm -ivh /tmp/base-passwd-doc.rpm')
|
||||
msg = 'Failed to install base-passwd-doc package. Reason: {}'.format(output)
|
||||
self.assertEqual(0, status, msg=msg)
|
||||
|
||||
status, output = self.target.run('rpm -e base-passwd-doc')
|
||||
msg = 'Failed to remove base-passwd-doc package. Reason: {}'.format(output)
|
||||
self.assertEqual(0, status, msg=msg)
|
||||
|
||||
self.tc.target.run('rm -f %s' % self.dst)
|
||||
|
||||
|
||||
19
sources/poky/meta/lib/oeqa/runtime/cases/rt.py
Normal file
19
sources/poky/meta/lib/oeqa/runtime/cases/rt.py
Normal file
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
|
||||
class RtTest(OERuntimeTestCase):
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
def test_is_rt(self):
|
||||
"""
|
||||
Check that the kernel has CONFIG_PREEMPT_RT enabled.
|
||||
"""
|
||||
status, output = self.target.run("uname -a")
|
||||
self.assertEqual(status, 0, msg=output)
|
||||
# Split so we don't get a substring false-positive
|
||||
self.assertIn("PREEMPT_RT", output.split())
|
||||
45
sources/poky/meta/lib/oeqa/runtime/cases/rtc.py
Normal file
45
sources/poky/meta/lib/oeqa/runtime/cases/rtc.py
Normal file
@@ -0,0 +1,45 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.core.decorator.data import skipIfFeature
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
import re
|
||||
|
||||
class RTCTest(OERuntimeTestCase):
|
||||
|
||||
def setUp(self):
|
||||
if self.tc.td.get('VIRTUAL-RUNTIME_init_manager') == 'systemd':
|
||||
self.logger.debug('Stopping systemd-timesyncd daemon')
|
||||
self.target.run('systemctl disable --now --runtime systemd-timesyncd')
|
||||
|
||||
def tearDown(self):
|
||||
if self.tc.td.get('VIRTUAL-RUNTIME_init_manager') == 'systemd':
|
||||
self.logger.debug('Starting systemd-timesyncd daemon')
|
||||
self.target.run('systemctl enable --now --runtime systemd-timesyncd')
|
||||
|
||||
@skipIfFeature('read-only-rootfs',
|
||||
'Test does not work with read-only-rootfs in IMAGE_FEATURES')
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(['coreutils', 'busybox'])
|
||||
def test_rtc(self):
|
||||
(status, output) = self.target.run('hwclock -r')
|
||||
self.assertEqual(status, 0, msg='Failed to get RTC time, output: %s' % output)
|
||||
|
||||
(status, current_datetime) = self.target.run('date +"%m%d%H%M%Y"')
|
||||
self.assertEqual(status, 0, msg='Failed to get system current date & time, output: %s' % current_datetime)
|
||||
|
||||
example_datetime = '062309452008'
|
||||
(status, output) = self.target.run('date %s ; hwclock -w ; hwclock -r' % example_datetime)
|
||||
check_hwclock = re.search('2008-06-23 09:45:..', output)
|
||||
self.assertTrue(check_hwclock, msg='The RTC time was not set correctly, output: %s' % output)
|
||||
|
||||
(status, output) = self.target.run('date %s' % current_datetime)
|
||||
self.assertEqual(status, 0, msg='Failed to reset system date & time, output: %s' % output)
|
||||
|
||||
(status, output) = self.target.run('hwclock -w')
|
||||
self.assertEqual(status, 0, msg='Failed to reset RTC time, output: %s' % output)
|
||||
27
sources/poky/meta/lib/oeqa/runtime/cases/runlevel.py
Normal file
27
sources/poky/meta/lib/oeqa/runtime/cases/runlevel.py
Normal file
@@ -0,0 +1,27 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
|
||||
import time
|
||||
|
||||
class RunLevel_Test(OERuntimeTestCase):
|
||||
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
def test_runlevel_3(self):
|
||||
(status, output) = self.target.run("init 3 && sleep 5 && runlevel")
|
||||
runlevel= '5 3'
|
||||
self.assertEqual(output, runlevel, msg='Failed to set current runlevel to runlevel 3, current runlevel : %s' % output[-1])
|
||||
(status, output) = self.target.run("uname -a")
|
||||
self.assertEqual(status, 0, msg='Failed to run uname command, output: %s' % output)
|
||||
|
||||
@OETestDepends(['runlevel.RunLevel_Test.test_runlevel_3'])
|
||||
def test_runlevel_5(self):
|
||||
(status, output) = self.target.run("init 5 && sleep 5 && runlevel")
|
||||
runlevel = '3 5'
|
||||
self.assertEqual(output, runlevel, msg='Failed to set current runlevel to runlevel 5, current runlevel : %s' % output[-1])
|
||||
(status, output) = self.target.run('export DISPLAY=:0 && x11perf -aa10text')
|
||||
self.assertEqual(status, 0, msg='Failed to run 2D graphic test, output: %s' % output)
|
||||
64
sources/poky/meta/lib/oeqa/runtime/cases/rust.py
Normal file
64
sources/poky/meta/lib/oeqa/runtime/cases/rust.py
Normal file
@@ -0,0 +1,64 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
class RustCompileTest(OERuntimeTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUp(cls):
|
||||
dst = '/tmp/'
|
||||
src = os.path.join(cls.tc.files_dir, 'test.rs')
|
||||
cls.tc.target.copyTo(src, dst)
|
||||
|
||||
@classmethod
|
||||
def tearDown(cls):
|
||||
files = '/tmp/test.rs /tmp/test'
|
||||
cls.tc.target.run('rm %s' % files)
|
||||
dirs = '/tmp/hello'
|
||||
cls.tc.target.run('rm -r %s' % dirs)
|
||||
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage('rust')
|
||||
@OEHasPackage('openssh-scp')
|
||||
def test_rust_compile(self):
|
||||
status, output = self.target.run('rustc /tmp/test.rs -o /tmp/test')
|
||||
msg = 'rust compile failed, output: %s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
status, output = self.target.run('/tmp/test')
|
||||
msg = 'running compiled file failed, output: %s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage('cargo')
|
||||
@OEHasPackage('openssh-scp')
|
||||
def test_cargo_compile(self):
|
||||
status, output = self.target.run('cargo new /tmp/hello')
|
||||
msg = 'cargo new failed, output: %s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
status, output = self.target.run('cargo build --manifest-path=/tmp/hello/Cargo.toml')
|
||||
msg = 'cargo build failed, output: %s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
status, output = self.target.run('cargo run --manifest-path=/tmp/hello/Cargo.toml')
|
||||
msg = 'running compiled file failed, output: %s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
class RustCLibExampleTest(OERuntimeTestCase):
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage('rust-c-lib-example-bin')
|
||||
def test_rust_c_lib_example(self):
|
||||
cmd = "rust-c-lib-example-bin test"
|
||||
status, output = self.target.run(cmd)
|
||||
msg = 'Exit status was not 0. Output: %s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
msg = 'Incorrect output: %s' % output
|
||||
self.assertEqual(output, "Hello world in rust from C!", msg=msg)
|
||||
39
sources/poky/meta/lib/oeqa/runtime/cases/scons.py
Normal file
39
sources/poky/meta/lib/oeqa/runtime/cases/scons.py
Normal file
@@ -0,0 +1,39 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
import os
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
class SconsCompileTest(OERuntimeTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUp(cls):
|
||||
dst = '/tmp/'
|
||||
src = os.path.join(cls.tc.runtime_files_dir, 'hello.c')
|
||||
cls.tc.target.copyTo(src, dst)
|
||||
|
||||
src = os.path.join(cls.tc.runtime_files_dir, 'SConstruct')
|
||||
cls.tc.target.copyTo(src, dst)
|
||||
|
||||
@classmethod
|
||||
def tearDown(cls):
|
||||
files = '/tmp/hello.c /tmp/hello.o /tmp/hello /tmp/SConstruct'
|
||||
cls.tc.target.run('rm %s' % files)
|
||||
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(['gcc'])
|
||||
@OEHasPackage(['python3-scons'])
|
||||
def test_scons_compile(self):
|
||||
status, output = self.target.run('cd /tmp/ && scons')
|
||||
msg = 'scons compile failed, output: %s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
status, output = self.target.run('/tmp/hello')
|
||||
msg = 'running compiled file failed, output: %s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
39
sources/poky/meta/lib/oeqa/runtime/cases/scp.py
Normal file
39
sources/poky/meta/lib/oeqa/runtime/cases/scp.py
Normal file
@@ -0,0 +1,39 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
import os
|
||||
from tempfile import mkstemp
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
class ScpTest(OERuntimeTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.tmp_fd, cls.tmp_path = mkstemp()
|
||||
with os.fdopen(cls.tmp_fd, 'w') as f:
|
||||
f.seek(2 ** 22 -1)
|
||||
f.write(os.linesep)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
os.remove(cls.tmp_path)
|
||||
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage({'openssh-scp', 'openssh-sftp-server'})
|
||||
def test_scp_file(self):
|
||||
dst = '/tmp/test_scp_file'
|
||||
|
||||
(status, output) = self.target.copyTo(self.tmp_path, dst)
|
||||
msg = 'File could not be copied. Output: %s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
(status, output) = self.target.run('ls -la %s' % dst)
|
||||
self.assertEqual(status, 0, msg = 'SCP test failed')
|
||||
|
||||
self.target.run('rm %s' % dst)
|
||||
37
sources/poky/meta/lib/oeqa/runtime/cases/skeletoninit.py
Normal file
37
sources/poky/meta/lib/oeqa/runtime/cases/skeletoninit.py
Normal file
@@ -0,0 +1,37 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
# This test should cover https://bugzilla.yoctoproject.org/tr_show_case.cgi?case_id=284
|
||||
# testcase. Image under test must have meta-skeleton layer in bblayers and
|
||||
# IMAGE_INSTALL:append = " service" in local.conf
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.core.decorator.data import skipIfDataVar
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
class SkeletonBasicTest(OERuntimeTestCase):
|
||||
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(['service'])
|
||||
@skipIfDataVar('VIRTUAL-RUNTIME_init_manager', 'systemd',
|
||||
'Not appropriate for systemd image')
|
||||
def test_skeleton_availability(self):
|
||||
status, output = self.target.run('ls /etc/init.d/skeleton')
|
||||
msg = 'skeleton init script not found. Output:\n%s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
status, output = self.target.run('ls /usr/sbin/skeleton-test')
|
||||
msg = 'skeleton-test not found. Output:\n%s' % output
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
@OETestDepends(['skeletoninit.SkeletonBasicTest.test_skeleton_availability'])
|
||||
def test_skeleton_script(self):
|
||||
output1 = self.target.run("/etc/init.d/skeleton start")[1]
|
||||
cmd = '%s | grep [s]keleton-test' % self.tc.target_cmds['ps']
|
||||
status, output2 = self.target.run(cmd)
|
||||
msg = ('Skeleton script could not be started:'
|
||||
'\n%s\n%s' % (output1, output2))
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
37
sources/poky/meta/lib/oeqa/runtime/cases/ssh.py
Normal file
37
sources/poky/meta/lib/oeqa/runtime/cases/ssh.py
Normal file
@@ -0,0 +1,37 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
import time
|
||||
import signal
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
class SSHTest(OERuntimeTestCase):
|
||||
|
||||
@OETestDepends(['ping.PingTest.test_ping'])
|
||||
@OEHasPackage(['dropbear', 'openssh-sshd'])
|
||||
def test_ssh(self):
|
||||
for i in range(5):
|
||||
status, output = self.target.run("uname -a", timeout=30)
|
||||
if status == 0:
|
||||
break
|
||||
elif status == 255 or status == -signal.SIGTERM:
|
||||
# ssh returns 255 only if a ssh error occurs. This could
|
||||
# be an issue with "Connection refused" because the port
|
||||
# isn't open yet, and this could check explicitly for that
|
||||
# here. However, let's keep it simple and just retry for
|
||||
# all errors a limited amount of times with a sleep to
|
||||
# give it time for the port to open.
|
||||
# We sometimes see -15 (SIGTERM) on slow emulation machines too, likely
|
||||
# from boot/init not being 100% complete, retry for these too.
|
||||
time.sleep(5)
|
||||
continue
|
||||
else:
|
||||
self.fail("uname failed with \"%s\" (exit code %s)" % (output, status))
|
||||
if status != 0:
|
||||
self.fail("ssh failed with \"%s\" (exit code %s)" % (output, status))
|
||||
34
sources/poky/meta/lib/oeqa/runtime/cases/stap.py
Normal file
34
sources/poky/meta/lib/oeqa/runtime/cases/stap.py
Normal file
@@ -0,0 +1,34 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
import os
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.data import skipIfNotFeature
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
class StapTest(OERuntimeTestCase):
|
||||
@skipIfNotFeature('tools-profile', 'Test requires tools-profile to be in IMAGE_FEATURES')
|
||||
@OEHasPackage(['systemtap'])
|
||||
@OEHasPackage(['gcc-symlinks'])
|
||||
@OEHasPackage(['kernel-devsrc'])
|
||||
def test_stap(self):
|
||||
try:
|
||||
cmd = 'make -j -C /usr/src/kernel scripts prepare'
|
||||
status, output = self.target.run(cmd, 900)
|
||||
self.assertEqual(status, 0, msg='\n'.join([cmd, output]))
|
||||
|
||||
cmd = 'stap -v -p4 -m stap-hello --disable-cache -DSTP_NO_VERREL_CHECK -e \'probe oneshot { print("Hello, "); println("SystemTap!") }\''
|
||||
status, output = self.target.run(cmd, 900)
|
||||
self.assertEqual(status, 0, msg='\n'.join([cmd, output]))
|
||||
|
||||
cmd = 'staprun -v -R -b1 stap-hello.ko'
|
||||
self.assertEqual(status, 0, msg='\n'.join([cmd, output]))
|
||||
self.assertIn('Hello, SystemTap!', output, msg='\n'.join([cmd, output]))
|
||||
except:
|
||||
status, dmesg = self.target.run('dmesg')
|
||||
if status == 0:
|
||||
print(dmesg)
|
||||
151
sources/poky/meta/lib/oeqa/runtime/cases/storage.py
Normal file
151
sources/poky/meta/lib/oeqa/runtime/cases/storage.py
Normal file
@@ -0,0 +1,151 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
import re
|
||||
import time
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.core.decorator.data import skipIfQemu
|
||||
|
||||
class StorageBase(OERuntimeTestCase):
|
||||
def storage_mount(cls, tmo=1):
|
||||
|
||||
(status, output) = cls.target.run('mkdir -p %s' % cls.mount_point)
|
||||
(status, output) = cls.target.run('mount %s %s' % (cls.device, cls.mount_point))
|
||||
msg = ('Mount failed: %s.' % status)
|
||||
cls.assertFalse(output, msg = msg)
|
||||
time.sleep(tmo)
|
||||
(status, output) = cls.target.run('cat /proc/mounts')
|
||||
match = re.search('%s' % cls.device, output)
|
||||
if match:
|
||||
msg = ('Device %s not mounted.' % cls.device)
|
||||
cls.assertTrue(match, msg = msg)
|
||||
|
||||
(status, output) = cls.target.run('mkdir -p %s' % cls.test_dir)
|
||||
|
||||
(status, output) = cls.target.run('rm -f %s/*' % cls.test_dir)
|
||||
msg = ('Failed to cleanup files @ %s/*' % cls.test_dir)
|
||||
cls.assertFalse(output, msg = msg)
|
||||
|
||||
|
||||
def storage_basic(cls):
|
||||
# create file on device
|
||||
(status, output) = cls.target.run('touch %s/%s' % (cls.test_dir, cls.test_file))
|
||||
msg = ('File %s not created on %s' % (cls.test_file, cls.device))
|
||||
cls.assertFalse(status, msg = msg)
|
||||
# move file
|
||||
(status, output) = cls.target.run('mv %s/%s %s/%s1' %
|
||||
(cls.test_dir, cls.test_file, cls.test_dir, cls.test_file))
|
||||
msg = ('File %s not moved to %s' % (cls.test_file, cls.device))
|
||||
cls.assertFalse(status, msg = msg)
|
||||
# remove file
|
||||
(status, output) = cls.target.run('rm %s/%s1' % (cls.test_dir, cls.test_file))
|
||||
msg = ('File %s not removed on %s' % (cls.test_file, cls.device))
|
||||
cls.assertFalse(status, msg = msg)
|
||||
|
||||
def storage_read(cls):
|
||||
# check if message is in file
|
||||
(status, output) = cls.target.run('cat %s/%s' %
|
||||
(cls.test_dir, cls.test_file))
|
||||
|
||||
match = re.search('%s' % cls.test_msg, output)
|
||||
msg = ('Test message %s not in file %s.' % (cls.test_msg, cls.test_file))
|
||||
cls.assertEqual(status, 0, msg = msg)
|
||||
|
||||
def storage_write(cls):
|
||||
# create test message in file on device
|
||||
(status, output) = cls.target.run('echo "%s" > %s/%s' %
|
||||
(cls.test_msg, cls.test_dir, cls.test_file))
|
||||
msg = ('File %s not create test message on %s' % (cls.test_file, cls.device))
|
||||
cls.assertEqual(status, 0, msg = msg)
|
||||
|
||||
def storage_umount(cls, tmo=1):
|
||||
time.sleep(tmo)
|
||||
(status, output) = cls.target.run('umount %s' % cls.mount_point)
|
||||
|
||||
if status == 32:
|
||||
# already unmounted, should it fail?
|
||||
return
|
||||
else:
|
||||
msg = ('Device not unmount %s' % cls.mount_point)
|
||||
cls.assertEqual(status, 0, msg = msg)
|
||||
|
||||
(status, output) = cls.target.run('cat /proc/mounts')
|
||||
match = re.search('%s' % cls.device, output)
|
||||
if match:
|
||||
msg = ('Device %s still mounted.' % cls.device)
|
||||
cls.assertTrue(match, msg = msg)
|
||||
|
||||
|
||||
class UsbTest(StorageBase):
|
||||
'''
|
||||
This is to mimic the usb test previously done in manual bsp-hw.json
|
||||
'''
|
||||
@classmethod
|
||||
def setUpClass(self):
|
||||
self.test_msg = "Hello World - USB"
|
||||
self.mount_point = "/media/usb"
|
||||
self.device = "/dev/sda1"
|
||||
self.test_file = "usb.tst"
|
||||
self.test_dir = os.path.join(self.mount_point, "oeqa")
|
||||
|
||||
@skipIfQemu()
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
def test_usb_mount(self):
|
||||
self.storage_umount(2)
|
||||
self.storage_mount(5)
|
||||
|
||||
@skipIfQemu()
|
||||
@OETestDepends(['storage.UsbTest.test_usb_mount'])
|
||||
def test_usb_basic_operations(self):
|
||||
self.storage_basic()
|
||||
|
||||
@skipIfQemu()
|
||||
@OETestDepends(['storage.UsbTest.test_usb_basic_operations'])
|
||||
def test_usb_basic_rw(self):
|
||||
self.storage_write()
|
||||
self.storage_read()
|
||||
|
||||
@skipIfQemu()
|
||||
@OETestDepends(['storage.UsbTest.test_usb_mount'])
|
||||
def test_usb_umount(self):
|
||||
self.storage_umount(2)
|
||||
|
||||
|
||||
class MMCTest(StorageBase):
|
||||
'''
|
||||
This is to mimic the usb test previously done in manual bsp-hw.json
|
||||
'''
|
||||
@classmethod
|
||||
def setUpClass(self):
|
||||
self.test_msg = "Hello World - MMC"
|
||||
self.mount_point = "/media/mmc"
|
||||
self.device = "/dev/mmcblk1p1"
|
||||
self.test_file = "mmc.tst"
|
||||
self.test_dir = os.path.join(self.mount_point, "oeqa")
|
||||
|
||||
@skipIfQemu()
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
def test_mmc_mount(self):
|
||||
self.storage_umount(2)
|
||||
self.storage_mount()
|
||||
|
||||
@skipIfQemu()
|
||||
@OETestDepends(['storage.MMCTest.test_mmc_mount'])
|
||||
def test_mmc_basic_operations(self):
|
||||
self.storage_basic()
|
||||
|
||||
@skipIfQemu()
|
||||
@OETestDepends(['storage.MMCTest.test_mmc_basic_operations'])
|
||||
def test_mmc_basic_rw(self):
|
||||
self.storage_write()
|
||||
self.storage_read()
|
||||
|
||||
@skipIfQemu()
|
||||
@OETestDepends(['storage.MMCTest.test_mmc_mount'])
|
||||
def test_mmc_umount(self):
|
||||
self.storage_umount(2)
|
||||
38
sources/poky/meta/lib/oeqa/runtime/cases/suspend.py
Normal file
38
sources/poky/meta/lib/oeqa/runtime/cases/suspend.py
Normal file
@@ -0,0 +1,38 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.core.decorator.data import skipIfQemu
|
||||
import threading
|
||||
import time
|
||||
|
||||
class Suspend_Test(OERuntimeTestCase):
|
||||
|
||||
def test_date(self):
|
||||
(status, output) = self.target.run('date')
|
||||
self.assertEqual(status, 0, msg = 'Failed to run date command, output : %s' % output)
|
||||
|
||||
def test_ping(self):
|
||||
t_thread = threading.Thread(target=self.target.run, args=("ping 8.8.8.8",))
|
||||
t_thread.start()
|
||||
time.sleep(2)
|
||||
|
||||
status, output = self.target.run('pidof ping')
|
||||
self.target.run('kill -9 %s' % output)
|
||||
self.assertEqual(status, 0, msg = 'Not able to find process that runs ping, output : %s' % output)
|
||||
|
||||
def set_suspend(self):
|
||||
(status, output) = self.target.run('sudo rtcwake -m mem -s 10')
|
||||
self.assertEqual(status, 0, msg = 'Failed to suspends your system to RAM, output : %s' % output)
|
||||
|
||||
@skipIfQemu()
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
def test_suspend(self):
|
||||
self.test_date()
|
||||
self.test_ping()
|
||||
self.set_suspend()
|
||||
self.test_date()
|
||||
self.test_ping()
|
||||
229
sources/poky/meta/lib/oeqa/runtime/cases/systemd.py
Normal file
229
sources/poky/meta/lib/oeqa/runtime/cases/systemd.py
Normal file
@@ -0,0 +1,229 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
import re
|
||||
import threading
|
||||
import time
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.core.decorator.data import skipIfDataVar, skipIfNotDataVar
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
from oeqa.core.decorator.data import skipIfNotFeature, skipIfFeature
|
||||
|
||||
class SystemdTest(OERuntimeTestCase):
|
||||
|
||||
def systemctl(self, action='', target='', expected=0, verbose=False):
|
||||
command = 'SYSTEMD_BUS_TIMEOUT=240s systemctl %s %s' % (action, target)
|
||||
status, output = self.target.run(command)
|
||||
message = '\n'.join([command, output])
|
||||
if status != expected and verbose:
|
||||
cmd = 'SYSTEMD_BUS_TIMEOUT=240s systemctl status --full %s' % target
|
||||
message += self.target.run(cmd)[1]
|
||||
self.assertEqual(status, expected, message)
|
||||
return output
|
||||
|
||||
#TODO: use pyjournalctl instead
|
||||
def journalctl(self, args='',l_match_units=None):
|
||||
"""
|
||||
Request for the journalctl output to the current target system
|
||||
|
||||
Arguments:
|
||||
-args, an optional argument pass through argument
|
||||
-l_match_units, an optional list of units to filter the output
|
||||
Returns:
|
||||
-string output of the journalctl command
|
||||
Raises:
|
||||
-AssertionError, on remote commands that fail
|
||||
-ValueError, on a journalctl call with filtering by l_match_units that
|
||||
returned no entries
|
||||
"""
|
||||
|
||||
query_units=''
|
||||
if l_match_units:
|
||||
query_units = ['_SYSTEMD_UNIT='+unit for unit in l_match_units]
|
||||
query_units = ' '.join(query_units)
|
||||
command = 'journalctl %s %s' %(args, query_units)
|
||||
status, output = self.target.run(command)
|
||||
if status:
|
||||
raise AssertionError("Command '%s' returned non-zero exit "
|
||||
'code %d:\n%s' % (command, status, output))
|
||||
if len(output) == 1 and "-- No entries --" in output:
|
||||
raise ValueError('List of units to match: %s, returned no entries'
|
||||
% l_match_units)
|
||||
return output
|
||||
|
||||
class SystemdBasicTests(SystemdTest):
|
||||
|
||||
def settle(self):
|
||||
"""
|
||||
Block until systemd has finished activating any units being activated,
|
||||
or until two minutes has elapsed.
|
||||
|
||||
Returns a tuple, either (True, '') if all units have finished
|
||||
activating, or (False, message string) if there are still units
|
||||
activating (generally, failing units that restart).
|
||||
"""
|
||||
endtime = time.time() + (60 * 2)
|
||||
while True:
|
||||
status, output = self.target.run('SYSTEMD_BUS_TIMEOUT=240s systemctl is-system-running')
|
||||
if "running" in output or "degraded" in output:
|
||||
return (True, '')
|
||||
if time.time() >= endtime:
|
||||
return (False, output)
|
||||
time.sleep(10)
|
||||
|
||||
@skipIfNotFeature('systemd',
|
||||
'Test requires systemd to be in DISTRO_FEATURES')
|
||||
@skipIfNotDataVar('VIRTUAL-RUNTIME_init_manager', 'systemd',
|
||||
'systemd is not the init manager for this image')
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
def test_systemd_basic(self):
|
||||
self.systemctl('--version')
|
||||
|
||||
@OETestDepends(['systemd.SystemdBasicTests.test_systemd_basic'])
|
||||
def test_systemd_list(self):
|
||||
self.systemctl('list-unit-files')
|
||||
|
||||
@OETestDepends(['systemd.SystemdBasicTests.test_systemd_basic'])
|
||||
def test_systemd_failed(self):
|
||||
settled, output = self.settle()
|
||||
msg = "Timed out waiting for systemd to settle:\n%s" % output
|
||||
self.assertTrue(settled, msg=msg)
|
||||
|
||||
output = self.systemctl('list-units', '--failed')
|
||||
match = re.search('0 loaded units listed', output)
|
||||
if not match:
|
||||
output += self.systemctl('status --full --failed')
|
||||
self.assertTrue(match, msg='Some systemd units failed:\n%s' % output)
|
||||
|
||||
|
||||
class SystemdServiceTests(SystemdTest):
|
||||
|
||||
@OEHasPackage(['avahi-daemon'])
|
||||
@OETestDepends(['systemd.SystemdBasicTests.test_systemd_basic'])
|
||||
def test_systemd_status(self):
|
||||
self.systemctl('status --full', 'avahi-daemon.service')
|
||||
|
||||
@OETestDepends(['systemd.SystemdServiceTests.test_systemd_status'])
|
||||
def test_systemd_stop_start(self):
|
||||
self.systemctl('stop', 'avahi-daemon.service')
|
||||
self.systemctl('is-active', 'avahi-daemon.service',
|
||||
expected=3, verbose=True)
|
||||
self.systemctl('start','avahi-daemon.service')
|
||||
self.systemctl('is-active', 'avahi-daemon.service', verbose=True)
|
||||
|
||||
@OETestDepends(['systemd.SystemdServiceTests.test_systemd_status'])
|
||||
@skipIfFeature('read-only-rootfs',
|
||||
'Test is only meant to run without read-only-rootfs in IMAGE_FEATURES')
|
||||
def test_systemd_disable_enable(self):
|
||||
self.systemctl('disable', 'avahi-daemon.service')
|
||||
self.systemctl('is-enabled', 'avahi-daemon.service', expected=1)
|
||||
self.systemctl('enable', 'avahi-daemon.service')
|
||||
self.systemctl('is-enabled', 'avahi-daemon.service')
|
||||
|
||||
@OETestDepends(['systemd.SystemdServiceTests.test_systemd_status'])
|
||||
@skipIfNotFeature('read-only-rootfs',
|
||||
'Test is only meant to run with read-only-rootfs in IMAGE_FEATURES')
|
||||
def test_systemd_disable_enable_ro(self):
|
||||
status = self.target.run('mount -orw,remount /')[0]
|
||||
self.assertTrue(status == 0, msg='Remounting / as r/w failed')
|
||||
try:
|
||||
self.test_systemd_disable_enable()
|
||||
finally:
|
||||
status = self.target.run('mount -oro,remount /')[0]
|
||||
self.assertTrue(status == 0, msg='Remounting / as r/o failed')
|
||||
|
||||
@OETestDepends(['systemd.SystemdBasicTests.test_systemd_basic'])
|
||||
@skipIfNotFeature('minidebuginfo', 'Test requires minidebuginfo to be in DISTRO_FEATURES')
|
||||
@OEHasPackage(['busybox'])
|
||||
def test_systemd_coredump_minidebuginfo(self):
|
||||
"""
|
||||
Verify that call-stacks generated by systemd-coredump contain symbolicated call-stacks,
|
||||
extracted from the minidebuginfo metadata (.gnu_debugdata elf section).
|
||||
"""
|
||||
# use "env sleep" instead of "sleep" to avoid calling the shell builtin function
|
||||
t_thread = threading.Thread(target=self.target.run, args=("ulimit -c unlimited && env sleep 1000",))
|
||||
t_thread.start()
|
||||
time.sleep(1)
|
||||
|
||||
status, sleep_pid = self.target.run('pidof sleep')
|
||||
# cause segfault on purpose
|
||||
self.target.run('kill -SEGV %s' % sleep_pid)
|
||||
self.assertEqual(status, 0, msg = 'Not able to find process that runs sleep, output : %s' % sleep_pid)
|
||||
|
||||
# Give some time to systemd-coredump@.service to process the coredump
|
||||
for x in range(20):
|
||||
status, output = self.target.run('coredumpctl list %s' % sleep_pid)
|
||||
if status == 0:
|
||||
break
|
||||
time.sleep(1)
|
||||
else:
|
||||
self.fail("Timed out waiting for coredump creation")
|
||||
|
||||
(status, output) = self.target.run('coredumpctl info %s' % sleep_pid)
|
||||
self.assertEqual(status, 0, msg='MiniDebugInfo Test failed: %s' % output)
|
||||
self.assertEqual('sleep_for_duration (busybox.nosuid' in output or 'xnanosleep (sleep.coreutils' in output,
|
||||
True, msg='Call stack is missing minidebuginfo symbols (functions shown as "n/a"): %s' % output)
|
||||
|
||||
class SystemdJournalTests(SystemdTest):
|
||||
|
||||
@OETestDepends(['systemd.SystemdBasicTests.test_systemd_basic'])
|
||||
def test_systemd_journal(self):
|
||||
status, output = self.target.run('journalctl')
|
||||
self.assertEqual(status, 0, output)
|
||||
|
||||
@OETestDepends(['systemd.SystemdBasicTests.test_systemd_basic'])
|
||||
def test_systemd_boot_time(self, systemd_TimeoutStartSec=90):
|
||||
"""
|
||||
Get the target boot time from journalctl and log it
|
||||
|
||||
Arguments:
|
||||
-systemd_TimeoutStartSec, an optional argument containing systemd's
|
||||
unit start timeout to compare against
|
||||
"""
|
||||
|
||||
# The expression chain that uniquely identifies the time boot message.
|
||||
expr_items=['Startup finished', 'kernel', 'userspace', r'\.$']
|
||||
try:
|
||||
output = self.journalctl(args='-o cat --reverse')
|
||||
except AssertionError:
|
||||
self.fail('Error occurred while calling journalctl')
|
||||
if not len(output):
|
||||
self.fail('Error, unable to get startup time from systemd journal')
|
||||
|
||||
# Check for the regular expression items that match the startup time.
|
||||
for line in output.split('\n'):
|
||||
check_match = ''.join(re.findall('.*'.join(expr_items), line))
|
||||
if check_match:
|
||||
break
|
||||
# Put the startup time in the test log
|
||||
if check_match:
|
||||
self.tc.logger.info('%s' % check_match)
|
||||
else:
|
||||
self.skipTest('Error at obtaining the boot time from journalctl')
|
||||
boot_time_sec = 0
|
||||
|
||||
# Get the numeric values from the string and convert them to seconds
|
||||
# same data will be placed in list and string for manipulation.
|
||||
l_boot_time = check_match.split(' ')[-2:]
|
||||
s_boot_time = ' '.join(l_boot_time)
|
||||
try:
|
||||
# Obtain the minutes it took to boot.
|
||||
if l_boot_time[0].endswith('min') and l_boot_time[0][0].isdigit():
|
||||
boot_time_min = s_boot_time.split('min')[0]
|
||||
# Convert to seconds and accumulate it.
|
||||
boot_time_sec += int(boot_time_min) * 60
|
||||
# Obtain the seconds it took to boot and accumulate.
|
||||
boot_time_sec += float(l_boot_time[1].split('s')[0])
|
||||
except ValueError:
|
||||
self.skipTest('Error when parsing time from boot string')
|
||||
|
||||
# Assert the target boot time against systemd's unit start timeout.
|
||||
if boot_time_sec > systemd_TimeoutStartSec:
|
||||
msg = ("Target boot time %s exceeds systemd's TimeoutStartSec %s"
|
||||
% (boot_time_sec, systemd_TimeoutStartSec))
|
||||
self.tc.logger.info(msg)
|
||||
26
sources/poky/meta/lib/oeqa/runtime/cases/terminal.py
Normal file
26
sources/poky/meta/lib/oeqa/runtime/cases/terminal.py
Normal file
@@ -0,0 +1,26 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
import threading
|
||||
import time
|
||||
|
||||
class TerminalTest(OERuntimeTestCase):
|
||||
|
||||
@OEHasPackage(['matchbox-terminal'])
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
def test_terminal_running(self):
|
||||
t_thread = threading.Thread(target=self.target.run, args=("export DISPLAY=:0 && matchbox-terminal -e 'sh -c \"uname -a && exec sh\"'",))
|
||||
t_thread.start()
|
||||
time.sleep(2)
|
||||
|
||||
status, output = self.target.run('pidof matchbox-terminal')
|
||||
number_of_terminal = len(output.split())
|
||||
self.assertEqual(number_of_terminal, 1, msg='There should be only one terminal being launched. Number of terminal launched : %s' % number_of_terminal)
|
||||
self.target.run('kill -9 %s' % output)
|
||||
self.assertEqual(status, 0, msg='Not able to find process that runs terminal.')
|
||||
27
sources/poky/meta/lib/oeqa/runtime/cases/usb_hid.py
Normal file
27
sources/poky/meta/lib/oeqa/runtime/cases/usb_hid.py
Normal file
@@ -0,0 +1,27 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.core.decorator.data import skipIfQemu
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
class USB_HID_Test(OERuntimeTestCase):
|
||||
|
||||
def keyboard_mouse_simulation(self):
|
||||
(status, output) = self.target.run('export DISPLAY=:0 && xdotool key F2 && xdotool mousemove 100 100')
|
||||
return self.assertEqual(status, 0, msg = 'Failed to simulate keyboard/mouse input event, output : %s' % output)
|
||||
|
||||
def set_suspend(self):
|
||||
(status, output) = self.target.run('sudo rtcwake -m mem -s 10')
|
||||
return self.assertEqual(status, 0, msg = 'Failed to suspends your system to RAM, output : %s' % output)
|
||||
|
||||
@OEHasPackage(['xdotool'])
|
||||
@skipIfQemu()
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
def test_USB_Hid_input(self):
|
||||
self.keyboard_mouse_simulation()
|
||||
self.set_suspend()
|
||||
self.keyboard_mouse_simulation()
|
||||
89
sources/poky/meta/lib/oeqa/runtime/cases/weston.py
Normal file
89
sources/poky/meta/lib/oeqa/runtime/cases/weston.py
Normal file
@@ -0,0 +1,89 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.core.decorator.data import skipIfNotFeature
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
import threading
|
||||
import time
|
||||
|
||||
class WestonTest(OERuntimeTestCase):
|
||||
weston_log_file = '/tmp/weston-2.log'
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls.tc.target.run('rm %s' % cls.weston_log_file)
|
||||
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(['weston'])
|
||||
def test_weston_running(self):
|
||||
cmd ='%s | grep [w]eston-desktop-shell' % self.tc.target_cmds['ps']
|
||||
status, output = self.target.run(cmd)
|
||||
msg = ('Weston does not appear to be running %s' %
|
||||
self.target.run(self.tc.target_cmds['ps'])[1])
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
def get_processes_of(self, target, error_msg):
|
||||
status, output = self.target.run('pidof %s' % target)
|
||||
self.assertEqual(status, 0, msg='Retrieve %s (%s) processes error: %s' % (target, error_msg, output))
|
||||
return output.split(" ")
|
||||
|
||||
def get_weston_command(self, cmd):
|
||||
return 'export XDG_RUNTIME_DIR=/run/user/`id -u weston`; export WAYLAND_DISPLAY=wayland-1; %s' % cmd
|
||||
|
||||
def run_weston_init(self):
|
||||
if 'systemd' in self.tc.td['VIRTUAL-RUNTIME_init_manager']:
|
||||
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)
|
||||
else:
|
||||
self.target.run(self.get_weston_command('openvt -- weston --socket=wayland-2 --log=%s' % self.weston_log_file))
|
||||
|
||||
def get_new_wayland_processes(self, existing_wl_processes):
|
||||
try_cnt = 0
|
||||
while try_cnt < 5:
|
||||
time.sleep(5 + 5*try_cnt)
|
||||
try_cnt += 1
|
||||
wl_processes = self.get_processes_of('weston-desktop-shell', 'existing and new')
|
||||
new_wl_processes = [x for x in wl_processes if x not in existing_wl_processes]
|
||||
if new_wl_processes:
|
||||
return new_wl_processes, try_cnt
|
||||
|
||||
return new_wl_processes, try_cnt
|
||||
|
||||
@OEHasPackage(['wayland-utils'])
|
||||
def test_wayland_info(self):
|
||||
if 'systemd' in self.tc.td['VIRTUAL-RUNTIME_init_manager']:
|
||||
command = 'XDG_RUNTIME_DIR=/run wayland-info'
|
||||
else:
|
||||
command = self.get_weston_command('wayland-info')
|
||||
status, output = self.target.run(command)
|
||||
self.assertEqual(status, 0, msg='wayland-info error: %s' % output)
|
||||
|
||||
@OEHasPackage(['weston'])
|
||||
def test_weston_can_initialize_new_wayland_compositor(self):
|
||||
existing_wl_processes = self.get_processes_of('weston-desktop-shell', 'existing')
|
||||
existing_weston_processes = self.get_processes_of('weston', 'existing')
|
||||
|
||||
weston_thread = threading.Thread(target=self.run_weston_init)
|
||||
weston_thread.start()
|
||||
new_wl_processes, try_cnt = self.get_new_wayland_processes(existing_wl_processes)
|
||||
existing_and_new_weston_processes = self.get_processes_of('weston', 'existing and new')
|
||||
new_weston_processes = [x for x in existing_and_new_weston_processes if x not in existing_weston_processes]
|
||||
if 'systemd' in self.tc.td['VIRTUAL-RUNTIME_init_manager']:
|
||||
self.target.run('systemctl stop weston-ptest.service')
|
||||
else:
|
||||
for w in new_weston_processes:
|
||||
self.target.run('kill -9 %s' % w)
|
||||
__, weston_log = self.target.run('cat %s' % self.weston_log_file)
|
||||
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))
|
||||
|
||||
@skipIfNotFeature('x11', 'Test requires x11 to be in DISTRO_FEATURES')
|
||||
@OEHasPackage(['weston'])
|
||||
def test_weston_supports_xwayland(self):
|
||||
cmd ='cat %s | grep "xserver listening on display"' % self.weston_log_file
|
||||
status, output = self.target.run(cmd)
|
||||
msg = ('xwayland does not appear to be running')
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
28
sources/poky/meta/lib/oeqa/runtime/cases/x32lib.py
Normal file
28
sources/poky/meta/lib/oeqa/runtime/cases/x32lib.py
Normal file
@@ -0,0 +1,28 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.core.decorator.data import skipIfNotInDataVar
|
||||
|
||||
import subprocess
|
||||
|
||||
class X32libTest(OERuntimeTestCase):
|
||||
|
||||
@skipIfNotInDataVar('DEFAULTTUNE', 'x86-64-x32',
|
||||
'DEFAULTTUNE is not set to x86-64-x32')
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
def test_x32_file(self):
|
||||
dest = self.td.get('T', '') + "/ls.x32test"
|
||||
self.target.copyFrom("/bin/ls", dest)
|
||||
cmd = 'readelf -h {} | grep Class | grep ELF32'.format(dest)
|
||||
status1 = subprocess.call(cmd, shell=True)
|
||||
cmd = 'readelf -h {} | grep Machine | grep X86-64'.format(dest)
|
||||
status2 = subprocess.call(cmd, shell=True)
|
||||
msg = ("/bin/ls isn't an X86-64 ELF32 binary. readelf says:\n{}".format(
|
||||
subprocess.check_output("readelf -h {}".format(dest), shell=True).decode()))
|
||||
os.remove(dest)
|
||||
self.assertTrue(status1 == 0 and status2 == 0, msg=msg)
|
||||
23
sources/poky/meta/lib/oeqa/runtime/cases/xorg.py
Normal file
23
sources/poky/meta/lib/oeqa/runtime/cases/xorg.py
Normal file
@@ -0,0 +1,23 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
from oeqa.core.decorator.depends import OETestDepends
|
||||
from oeqa.core.decorator.data import skipIfNotFeature
|
||||
from oeqa.runtime.decorator.package import OEHasPackage
|
||||
|
||||
class XorgTest(OERuntimeTestCase):
|
||||
|
||||
@skipIfNotFeature('x11-base',
|
||||
'Test requires x11 to be in IMAGE_FEATURES')
|
||||
@OETestDepends(['ssh.SSHTest.test_ssh'])
|
||||
@OEHasPackage(['xserver-nodm-init'])
|
||||
def test_xorg_running(self):
|
||||
cmd ='%s | grep -v xinit | grep [X]org' % self.tc.target_cmds['ps']
|
||||
status, output = self.target.run(cmd)
|
||||
msg = ('Xorg does not appear to be running %s' %
|
||||
self.target.run(self.tc.target_cmds['ps'])[1])
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
217
sources/poky/meta/lib/oeqa/runtime/context.py
Normal file
217
sources/poky/meta/lib/oeqa/runtime/context.py
Normal file
@@ -0,0 +1,217 @@
|
||||
#
|
||||
# Copyright (C) 2016 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from oeqa.core.context import OETestContext, OETestContextExecutor
|
||||
from oeqa.core.target.ssh import OESSHTarget
|
||||
from oeqa.core.target.qemu import OEQemuTarget
|
||||
|
||||
from oeqa.runtime.loader import OERuntimeTestLoader
|
||||
|
||||
class OERuntimeTestContext(OETestContext):
|
||||
loaderClass = OERuntimeTestLoader
|
||||
runtime_files_dir = os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)), "files")
|
||||
|
||||
def __init__(self, td, logger, target,
|
||||
image_packages, extract_dir):
|
||||
super(OERuntimeTestContext, self).__init__(td, logger)
|
||||
|
||||
self.target = target
|
||||
self.image_packages = image_packages
|
||||
self.extract_dir = extract_dir
|
||||
self._set_target_cmds()
|
||||
|
||||
def _set_target_cmds(self):
|
||||
self.target_cmds = {}
|
||||
|
||||
self.target_cmds['ps'] = 'ps'
|
||||
if 'procps' in self.image_packages:
|
||||
self.target_cmds['ps'] = self.target_cmds['ps'] + ' -ef'
|
||||
|
||||
class OERuntimeTestContextExecutor(OETestContextExecutor):
|
||||
_context_class = OERuntimeTestContext
|
||||
|
||||
name = 'runtime'
|
||||
help = 'runtime test component'
|
||||
description = 'executes runtime tests over targets'
|
||||
|
||||
default_cases = os.path.join(os.path.abspath(os.path.dirname(__file__)),
|
||||
'cases')
|
||||
default_data = None
|
||||
default_test_data = 'data/testdata.json'
|
||||
default_tests = ''
|
||||
default_json_result_dir = '%s-results' % name
|
||||
|
||||
default_target_type = 'simpleremote'
|
||||
default_manifest = 'data/manifest'
|
||||
default_server_ip = '192.168.7.1'
|
||||
default_target_ip = '192.168.7.2'
|
||||
default_extract_dir = 'packages/extracted'
|
||||
|
||||
def register_commands(self, logger, subparsers):
|
||||
super(OERuntimeTestContextExecutor, self).register_commands(logger, subparsers)
|
||||
|
||||
runtime_group = self.parser.add_argument_group('runtime options')
|
||||
|
||||
runtime_group.add_argument('--target-type', action='store',
|
||||
default=self.default_target_type, choices=['simpleremote', 'qemu'],
|
||||
help="Target type of device under test, default: %s" \
|
||||
% self.default_target_type)
|
||||
runtime_group.add_argument('--target-ip', action='store',
|
||||
default=self.default_target_ip,
|
||||
help="IP address and optionally ssh port (default 22) of device under test, for example '192.168.0.7:22'. Default: %s" \
|
||||
% self.default_target_ip)
|
||||
runtime_group.add_argument('--server-ip', action='store',
|
||||
default=self.default_target_ip,
|
||||
help="IP address of the test host from test target machine, default: %s" \
|
||||
% self.default_server_ip)
|
||||
|
||||
runtime_group.add_argument('--host-dumper-dir', action='store',
|
||||
help="Directory where host status is dumped, if tests fails")
|
||||
|
||||
runtime_group.add_argument('--packages-manifest', action='store',
|
||||
default=self.default_manifest,
|
||||
help="Package manifest of the image under test, default: %s" \
|
||||
% self.default_manifest)
|
||||
|
||||
runtime_group.add_argument('--extract-dir', action='store',
|
||||
default=self.default_extract_dir,
|
||||
help='Directory where extracted packages reside, default: %s' \
|
||||
% self.default_extract_dir)
|
||||
|
||||
runtime_group.add_argument('--qemu-boot', action='store',
|
||||
help="Qemu boot configuration, only needed when target_type is QEMU.")
|
||||
|
||||
@staticmethod
|
||||
def getTarget(target_type, logger, target_ip, server_ip, **kwargs):
|
||||
target = None
|
||||
|
||||
if target_ip:
|
||||
target_ip_port = target_ip.split(':')
|
||||
if len(target_ip_port) == 2:
|
||||
target_ip = target_ip_port[0]
|
||||
kwargs['port'] = target_ip_port[1]
|
||||
|
||||
if server_ip:
|
||||
server_ip_port = server_ip.split(':')
|
||||
if len(server_ip_port) == 2:
|
||||
server_ip = server_ip_port[0]
|
||||
kwargs['server_port'] = int(server_ip_port[1])
|
||||
|
||||
if target_type == 'simpleremote':
|
||||
target = OESSHTarget(logger, target_ip, server_ip, **kwargs)
|
||||
elif target_type == 'qemu':
|
||||
target = OEQemuTarget(logger, server_ip, **kwargs)
|
||||
else:
|
||||
# XXX: This code uses the old naming convention for controllers and
|
||||
# targets, the idea it is to leave just targets as the controller
|
||||
# most of the time was just a wrapper.
|
||||
# XXX: This code tries to import modules from lib/oeqa/controllers
|
||||
# directory and treat them as controllers, it will less error prone
|
||||
# to use introspection to load such modules.
|
||||
# XXX: Don't base your targets on this code it will be refactored
|
||||
# in the near future.
|
||||
# Custom target module loading
|
||||
controller = OERuntimeTestContextExecutor.getControllerModule(target_type)
|
||||
target = controller(logger, target_ip, server_ip, **kwargs)
|
||||
|
||||
return target
|
||||
|
||||
# Search oeqa.controllers module directory for and return a controller
|
||||
# corresponding to the given target name.
|
||||
# AttributeError raised if not found.
|
||||
# ImportError raised if a provided module can not be imported.
|
||||
@staticmethod
|
||||
def getControllerModule(target):
|
||||
controllerslist = OERuntimeTestContextExecutor._getControllerModulenames()
|
||||
controller = OERuntimeTestContextExecutor._loadControllerFromName(target, controllerslist)
|
||||
return controller
|
||||
|
||||
# Return a list of all python modules in lib/oeqa/controllers for each
|
||||
# layer in bbpath
|
||||
@staticmethod
|
||||
def _getControllerModulenames():
|
||||
|
||||
controllerslist = []
|
||||
|
||||
def add_controller_list(path):
|
||||
if not os.path.exists(os.path.join(path, '__init__.py')):
|
||||
raise OSError('Controllers directory %s exists but is missing __init__.py' % path)
|
||||
files = sorted([f for f in os.listdir(path) if f.endswith('.py') and not f.startswith('_') and not f.startswith('.#')])
|
||||
for f in files:
|
||||
module = 'oeqa.controllers.' + f[:-3]
|
||||
if module not in controllerslist:
|
||||
controllerslist.append(module)
|
||||
else:
|
||||
raise RuntimeError("Duplicate controller module found for %s. Layers should create unique controller module names" % module)
|
||||
|
||||
# sys.path can contain duplicate paths, but because of the login in
|
||||
# add_controller_list this doesn't work and causes testimage to abort.
|
||||
# Remove duplicates using an intermediate dictionary to ensure this
|
||||
# doesn't happen.
|
||||
for p in list(dict.fromkeys(sys.path)):
|
||||
controllerpath = os.path.join(p, 'oeqa', 'controllers')
|
||||
if os.path.exists(controllerpath):
|
||||
add_controller_list(controllerpath)
|
||||
return controllerslist
|
||||
|
||||
# Search for and return a controller from given target name and
|
||||
# set of module names.
|
||||
# Raise AttributeError if not found.
|
||||
# Raise ImportError if a provided module can not be imported
|
||||
@staticmethod
|
||||
def _loadControllerFromName(target, modulenames):
|
||||
for name in modulenames:
|
||||
obj = OERuntimeTestContextExecutor._loadControllerFromModule(target, name)
|
||||
if obj:
|
||||
return obj
|
||||
raise AttributeError("Unable to load {0} from available modules: {1}".format(target, str(modulenames)))
|
||||
|
||||
# Search for and return a controller or None from given module name
|
||||
@staticmethod
|
||||
def _loadControllerFromModule(target, modulename):
|
||||
try:
|
||||
import importlib
|
||||
module = importlib.import_module(modulename)
|
||||
return getattr(module, target)
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def readPackagesManifest(manifest):
|
||||
if not manifest or not os.path.exists(manifest):
|
||||
raise OSError("Manifest file not exists: %s" % manifest)
|
||||
|
||||
image_packages = set()
|
||||
with open(manifest, 'r') as f:
|
||||
for line in f.readlines():
|
||||
line = line.strip()
|
||||
if line and not line.startswith("#"):
|
||||
image_packages.add(line.split()[0])
|
||||
|
||||
return image_packages
|
||||
|
||||
def _process_args(self, logger, args):
|
||||
if not args.packages_manifest:
|
||||
raise TypeError('Manifest file not provided')
|
||||
|
||||
super(OERuntimeTestContextExecutor, self)._process_args(logger, args)
|
||||
|
||||
target_kwargs = {}
|
||||
target_kwargs['qemuboot'] = args.qemu_boot
|
||||
|
||||
self.tc_kwargs['init']['target'] = \
|
||||
OERuntimeTestContextExecutor.getTarget(args.target_type,
|
||||
None, args.target_ip, args.server_ip, **target_kwargs)
|
||||
self.tc_kwargs['init']['image_packages'] = \
|
||||
OERuntimeTestContextExecutor.readPackagesManifest(
|
||||
args.packages_manifest)
|
||||
self.tc_kwargs['init']['extract_dir'] = args.extract_dir
|
||||
|
||||
_executor_class = OERuntimeTestContextExecutor
|
||||
90
sources/poky/meta/lib/oeqa/runtime/decorator/package.py
Normal file
90
sources/poky/meta/lib/oeqa/runtime/decorator/package.py
Normal file
@@ -0,0 +1,90 @@
|
||||
#
|
||||
# Copyright (C) 2016 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
from oeqa.core.decorator import OETestDecorator, registerDecorator
|
||||
|
||||
@registerDecorator
|
||||
class OEHasPackage(OETestDecorator):
|
||||
"""
|
||||
Checks if image has packages (un)installed.
|
||||
|
||||
The argument must be a string, set, or list of packages that must be
|
||||
installed or not present in the image.
|
||||
|
||||
The way to tell a package must not be in an image is using an
|
||||
exclamation point ('!') before the name of the package.
|
||||
|
||||
If test depends on pkg1 or pkg2 you need to use:
|
||||
@OEHasPackage({'pkg1', 'pkg2'})
|
||||
|
||||
If test depends on pkg1 and pkg2 you need to use:
|
||||
@OEHasPackage('pkg1')
|
||||
@OEHasPackage('pkg2')
|
||||
|
||||
If test depends on pkg1 but pkg2 must not be present use:
|
||||
@OEHasPackage({'pkg1', '!pkg2'})
|
||||
"""
|
||||
|
||||
attrs = ('need_pkgs',)
|
||||
|
||||
def setUpDecorator(self):
|
||||
need_pkgs = set()
|
||||
unneed_pkgs = set()
|
||||
|
||||
# Turn literal strings into a list so we can just iterate over it
|
||||
if isinstance(self.need_pkgs, str):
|
||||
self.need_pkgs = [self.need_pkgs,]
|
||||
|
||||
mlprefix = self.case.td.get("MLPREFIX")
|
||||
for pkg in self.need_pkgs:
|
||||
if pkg.startswith('!'):
|
||||
unneed_pkgs.add(mlprefix + pkg[1:])
|
||||
else:
|
||||
need_pkgs.add(mlprefix + pkg)
|
||||
|
||||
if unneed_pkgs:
|
||||
msg = 'Checking if %s is not installed' % ', '.join(unneed_pkgs)
|
||||
self.logger.debug(msg)
|
||||
if not self.case.tc.image_packages.isdisjoint(unneed_pkgs):
|
||||
msg = "Test can't run with %s installed" % ', or '.join(unneed_pkgs)
|
||||
self._decorator_fail(msg)
|
||||
|
||||
if need_pkgs:
|
||||
msg = 'Checking if at least one of %s is installed' % ', '.join(need_pkgs)
|
||||
self.logger.debug(msg)
|
||||
if self.case.tc.image_packages.isdisjoint(need_pkgs):
|
||||
msg = "Test requires %s to be installed" % ', or '.join(need_pkgs)
|
||||
self._decorator_fail(msg)
|
||||
|
||||
def _decorator_fail(self, msg):
|
||||
self.case.skipTest(msg)
|
||||
|
||||
@registerDecorator
|
||||
class OERequirePackage(OEHasPackage):
|
||||
"""
|
||||
Checks if image has packages (un)installed.
|
||||
It is almost the same as OEHasPackage, but if dependencies are missing
|
||||
the test case fails.
|
||||
|
||||
The argument must be a string, set, or list of packages that must be
|
||||
installed or not present in the image.
|
||||
|
||||
The way to tell a package must not be in an image is using an
|
||||
exclamation point ('!') before the name of the package.
|
||||
|
||||
If test depends on pkg1 or pkg2 you need to use:
|
||||
@OERequirePackage({'pkg1', 'pkg2'})
|
||||
|
||||
If test depends on pkg1 and pkg2 you need to use:
|
||||
@OERequirePackage('pkg1')
|
||||
@OERequirePackage('pkg2')
|
||||
|
||||
If test depends on pkg1 but pkg2 must not be present use:
|
||||
@OERequirePackage({'pkg1', '!pkg2'})
|
||||
"""
|
||||
|
||||
def _decorator_fail(self, msg):
|
||||
self.case.fail(msg)
|
||||
1
sources/poky/meta/lib/oeqa/runtime/files/SConstruct
Normal file
1
sources/poky/meta/lib/oeqa/runtime/files/SConstruct
Normal file
@@ -0,0 +1 @@
|
||||
Program('hello.c')
|
||||
5
sources/poky/meta/lib/oeqa/runtime/files/hello.c
Normal file
5
sources/poky/meta/lib/oeqa/runtime/files/hello.c
Normal file
@@ -0,0 +1,5 @@
|
||||
int
|
||||
main()
|
||||
{
|
||||
printf("Hello, world!\n");
|
||||
}
|
||||
19
sources/poky/meta/lib/oeqa/runtime/files/hellomod.c
Normal file
19
sources/poky/meta/lib/oeqa/runtime/files/hellomod.c
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
static int __init hello_init(void)
|
||||
{
|
||||
printk(KERN_INFO "Hello world!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit hello_cleanup(void)
|
||||
{
|
||||
printk(KERN_INFO "Cleaning up hellomod.\n");
|
||||
}
|
||||
|
||||
module_init(hello_init);
|
||||
module_exit(hello_cleanup);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -0,0 +1,8 @@
|
||||
obj-m := hellomod.o
|
||||
KDIR := /usr/src/kernel
|
||||
|
||||
all:
|
||||
$(MAKE) -C $(KDIR) M=$(PWD) modules
|
||||
|
||||
clean:
|
||||
$(MAKE) -C $(KDIR) M=$(PWD) clean
|
||||
5
sources/poky/meta/lib/oeqa/runtime/files/testmakefile
Normal file
5
sources/poky/meta/lib/oeqa/runtime/files/testmakefile
Normal file
@@ -0,0 +1,5 @@
|
||||
test: test.o
|
||||
gcc -o test test.o -lm
|
||||
test.o: test.c
|
||||
gcc -c test.c
|
||||
|
||||
19
sources/poky/meta/lib/oeqa/runtime/loader.py
Normal file
19
sources/poky/meta/lib/oeqa/runtime/loader.py
Normal file
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# Copyright (C) 2016 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
from oeqa.core.loader import OETestLoader
|
||||
from oeqa.runtime.case import OERuntimeTestCase
|
||||
|
||||
class OERuntimeTestLoader(OETestLoader):
|
||||
caseClass = OERuntimeTestCase
|
||||
|
||||
def _getTestCase(self, testCaseClass, tcName):
|
||||
case = super(OERuntimeTestLoader, self)._getTestCase(testCaseClass, tcName)
|
||||
|
||||
# Adds custom attributes to the OERuntimeTestCase
|
||||
setattr(case, 'target', self.tc.target)
|
||||
|
||||
return case
|
||||
@@ -0,0 +1,44 @@
|
||||
#
|
||||
# Copyright (C) 2016 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
from oeqa.utils.buildproject import BuildProject
|
||||
|
||||
class TargetBuildProject(BuildProject):
|
||||
|
||||
def __init__(self, target, uri, foldername=None, dl_dir=None):
|
||||
self.target = target
|
||||
self.targetdir = "~/buildtest/"
|
||||
BuildProject.__init__(self, uri, foldername, dl_dir=dl_dir)
|
||||
|
||||
def download_archive(self):
|
||||
self.target.run("mkdir " + self.targetdir + " || true")
|
||||
|
||||
self._download_archive()
|
||||
|
||||
status, output = self.target.copyTo(self.localarchive, self.targetdir)
|
||||
if status:
|
||||
raise Exception('Failed to copy archive to target, '
|
||||
'output: %s' % output)
|
||||
|
||||
cmd = 'tar xf %s%s -C %s' % (self.targetdir,
|
||||
self.archive,
|
||||
self.targetdir)
|
||||
status, output = self.target.run(cmd)
|
||||
if status:
|
||||
raise Exception('Failed to extract archive, '
|
||||
'output: %s' % output)
|
||||
|
||||
# Change targetdir to project folder
|
||||
self.targetdir = self.targetdir + self.fname
|
||||
|
||||
# The timeout parameter of target.run is set to 0
|
||||
# to make the ssh command run with no timeout.
|
||||
def _run(self, cmd):
|
||||
ret = self.target.run(cmd, 0)
|
||||
msg = "Command %s failed with exit code %s: %s" % (cmd, ret[0], ret[1])
|
||||
if ret[0] != 0:
|
||||
raise Exception(msg)
|
||||
return ret[0]
|
||||
Reference in New Issue
Block a user