Initial commit

This commit is contained in:
Your Name
2026-04-23 17:07:55 +08:00
commit b7e39e063b
16725 changed files with 1625565 additions and 0 deletions
+20
View 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)
@@ -0,0 +1,14 @@
#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: MIT
#
from oeqa.runtime.case import OERuntimeTestCase
class QemuTinyTest(OERuntimeTestCase):
def test_boot_tiny(self):
status, output = self.target.run_serial('uname -a')
msg = "Cannot detect poky tiny boot!"
self.assertTrue("yocto-tiny" in output, msg)
+79
View 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
View 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)
@@ -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.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.13.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('--disable-maintainer-mode')
# This sed is needed until
# https://git.savannah.gnu.org/cgit/cpio.git/commit/src/global.c?id=641d3f489cf6238bb916368d4ba0d9325a235afb
# is in a release.
self.project._run(r'sed -i -e "/char \*program_name/d" %s/src/global.c' % self.project.targetdir)
self.project.run_make()
self.project.run_install()
@@ -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()
@@ -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()
@@ -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
View 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
View 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
View 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
View 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
View 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, "&lt;testing&amp;testing&gt;", msg="Unexpected output (%s)" % output)
+21
View 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, Go examples!", msg=msg)
@@ -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.')
@@ -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
View 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
View 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)
@@ -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)
+124
View File
@@ -0,0 +1,124 @@
# 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", "connectors", "commands", "net.ipv6_lib", "input","fs_perms_simple"]
ltp_fs = ["fs", "fsx", "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)
endtime = time.time()
# 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")
@@ -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)
@@ -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')
@@ -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")
@@ -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 appropiate 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
View 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
View 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,393 @@
#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: MIT
#
import os
from subprocess import check_output
from shutil import rmtree
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
#in the future these lists could be moved outside of module
errors = ["error", "cannot", "can\'t", "failed"]
common_errors = [
"(WW) warning, (EE) error, (NI) not implemented, (??) unknown.",
"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 vesa",
"Failed to load module \"modesetting\"",
"Failed to load module modesetting",
"Failed to load module \"glx\"",
"Failed to load module \"fbdev\"",
"Failed to load module fbdev",
"Failed to load module glx",
"[drm] Cannot find any crtc or sizes",
"_OSC failed (AE_NOT_FOUND); disabling ASPM",
"Open ACPI failed (/var/run/acpid.socket) (No such file or directory)",
"NX (Execute Disable) protection cannot be enabled: non-PAE kernel!",
"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',
'Failed to find URL:http://ipv4.connman.net/online/status.html',
'Online check failed for',
'netlink init failed',
'Fast TSC calibration',
"BAR 0-9",
"Failed to load module \"ati\"",
"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",
]
video_related = [
]
x86_common = [
'[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',
'Direct firmware load for regulatory.db',
'failed to load regulatory.db',
] + common_errors
qemux86_common = [
'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)',
] + common_errors
ignore_errors = {
'default' : common_errors,
'qemux86' : [
'Failed to access perfctr msr (MSR',
'pci 0000:00:00.0: [Firmware Bug]: reg 0x..: invalid BAR (can\'t size)',
] + qemux86_common,
'qemux86-64' : qemux86_common,
'qemumips' : [
'Failed to load module "glx"',
'pci 0000:00:00.0: [Firmware Bug]: reg 0x..: invalid BAR (can\'t size)',
'cacheinfo: Failed to find cpu0 device node',
] + common_errors,
'qemumips64' : [
'pci 0000:00:00.0: [Firmware Bug]: reg 0x..: invalid BAR (can\'t size)',
'cacheinfo: Failed to find cpu0 device node',
] + common_errors,
'qemuppc' : [
'PCI 0000:00 Cannot reserve Legacy IO [io 0x0000-0x0fff]',
'host side 80-wire cable detection failed, limiting max speed',
'mode "640x480" test failed',
'Failed to load module "glx"',
'can\'t handle BAR above 4GB',
'Cannot reserve Legacy IO',
] + common_errors,
'qemuppc64' : [
'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]',
] + common_errors,
'qemuarmv5' : [
'mmci-pl18x: probe of fpga:05 failed with error -22',
'mmci-pl18x: probe of fpga:0b failed with error -22',
'Failed to load module "glx"',
'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',
'jitterentropy: Initialization failed with host not compliant with requirements: 2',
'clcd-pl11x: probe of 10120000.display failed with error -2',
'arm-charlcd 10008000.lcd: error -ENXIO: IRQ index 0 not found'
] + common_errors,
'qemuarm64' : [
'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',
] + common_errors,
'intel-core2-32' : [
'ACPI: No _BQC method, cannot determine initial brightness',
'[Firmware Bug]: ACPI: No _BQC method, cannot determine initial brightness',
'(EE) Failed to load module "psb"',
'(EE) Failed to load module psb',
'(EE) Failed to load module "psbdrv"',
'(EE) Failed to load module psbdrv',
'(EE) open /dev/fb0: No such file or directory',
'(EE) AIGLX: reverting to software rendering',
'dmi: Firmware registration failed.',
'ioremap error for 0x78',
] + x86_common,
'intel-corei7-64' : [
'can\'t set Max Payload Size to 256',
'intel_punit_ipc: can\'t request region for resource',
'[drm] parse error at position 4 in video mode \'efifb\'',
'ACPI Error: Could not enable RealTimeClock event',
'ACPI Warning: Could not enable fixed event - RealTimeClock',
'hci_intel INT33E1:00: Unable to retrieve gpio',
'hci_intel: probe of INT33E1:00 failed',
'can\'t derive routing for PCI INT A',
'failed to read out thermal zone',
'Bluetooth: hci0: Setting Intel event mask failed',
'ttyS2 - failed to request DMA',
'Bluetooth: hci0: Failed to send firmware data (-38)',
'atkbd serio0: Failed to enable keyboard on isa0060/serio0',
] + x86_common,
'genericx86' : x86_common,
'genericx86-64' : [
'Direct firmware load for i915',
'Failed to load firmware i915',
'Failed to fetch GuC',
'Failed to initialize GuC',
'Failed to load DMC firmware',
'The driver is built-in, so to load the firmware you need to',
] + x86_common,
'edgerouter' : [
'not creating \'/sys/firmware/fdt\'',
'Failed to find cpu0 device node',
'Fatal server error:',
'Server terminated with error',
] + common_errors,
'beaglebone-yocto' : [
'Direct firmware load for regulatory.db',
'failed to load regulatory.db',
'l4_wkup_cm',
'Failed to load module "glx"',
'Failed to make EGL context current',
'glamor initialization failed',
] + common_errors,
}
log_locations = ["/var/log/","/var/log/dmesg", "/tmp/dmesg_output.log"]
class ParseLogsTest(OERuntimeTestCase):
@classmethod
def setUpClass(cls):
cls.errors = errors
# 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.ignore_errors = ignore_errors
cls.log_locations = log_locations
cls.msg = ''
is_lsb, _ = cls.tc.target.run("which LSB_Test.sh")
if is_lsb == 0:
for machine in cls.ignore_errors:
cls.ignore_errors[machine] = cls.ignore_errors[machine] \
+ video_related
def getMachine(self):
return self.td.get('MACHINE', '')
def getWorkdir(self):
return self.td.get('WORKDIR', '')
# Get some information on the CPU of the machine to display at the
# beginning of the output. This info might be useful in some cases.
def getHardwareInfo(self):
hwi = ""
cmd = ('cat /proc/cpuinfo | grep "model name" | head -n1 | '
" awk 'BEGIN{FS=\":\"}{print $2}'")
_, cpu_name = self.target.run(cmd)
cmd = ('cat /proc/cpuinfo | grep "cpu cores" | head -n1 | '
"awk {'print $4'}")
_, cpu_physical_cores = self.target.run(cmd)
cmd = 'cat /proc/cpuinfo | grep "processor" | wc -l'
_, cpu_logical_cores = self.target.run(cmd)
_, cpu_arch = self.target.run('uname -m')
hwi += 'Machine information: \n'
hwi += '*******************************\n'
hwi += 'Machine name: ' + self.getMachine() + '\n'
hwi += 'CPU: ' + str(cpu_name) + '\n'
hwi += 'Arch: ' + str(cpu_arch)+ '\n'
hwi += 'Physical cores: ' + str(cpu_physical_cores) + '\n'
hwi += 'Logical cores: ' + str(cpu_logical_cores) + '\n'
hwi += '*******************************\n'
return hwi
# 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 ' + str(location))
if status == 0:
logs.append(str(location))
else:
status, _ = self.target.run('test -d ' + str(location))
if status == 0:
cmd = 'find ' + str(location) + '/*.log -maxdepth 1 -type f'
status, output = self.target.run(cmd)
if status == 0:
output = output.splitlines()
for logfile in output:
logs.append(os.path.join(location, str(logfile)))
return logs
# Copy the log files to be parsed locally
def transfer_logs(self, log_list):
workdir = self.getWorkdir()
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
# Build the grep command to be used with filters and exclusions
def build_grepcmd(self, errors, ignore_errors, log):
grepcmd = 'grep '
grepcmd += '-Ei "'
for error in errors:
grepcmd += r'\<' + error + r'\>' + '|'
grepcmd = grepcmd[:-1]
grepcmd += '" ' + str(log) + " | grep -Eiv \'"
try:
errorlist = ignore_errors[self.getMachine()]
except KeyError:
self.msg += 'No ignore list found for this machine, using default\n'
errorlist = ignore_errors['default']
for ignore_error in errorlist:
ignore_error = ignore_error.replace('(', r'\(')
ignore_error = ignore_error.replace(')', r'\)')
ignore_error = ignore_error.replace("'", '.')
ignore_error = ignore_error.replace('?', r'\?')
ignore_error = ignore_error.replace('[', r'\[')
ignore_error = ignore_error.replace(']', r'\]')
ignore_error = ignore_error.replace('*', r'\*')
ignore_error = ignore_error.replace('0-9', '[0-9]')
grepcmd += ignore_error + '|'
grepcmd = grepcmd[:-1]
grepcmd += "\'"
return grepcmd
# Grep only the errors so that their context could be collected.
# Default context is 10 lines before and after the error itself
def parse_logs(self, errors, ignore_errors, logs,
lines_before = 10, lines_after = 10):
results = {}
rez = []
grep_output = ''
for log in logs:
result = None
thegrep = self.build_grepcmd(errors, ignore_errors, log)
try:
result = check_output(thegrep, shell=True).decode('utf-8')
except:
pass
if result is not None:
results[log] = {}
rez = result.splitlines()
for xrez in rez:
try:
cmd = ['grep', '-F', xrez, '-B', str(lines_before)]
cmd += ['-A', str(lines_after), log]
grep_output = check_output(cmd).decode('utf-8')
except:
pass
results[log][xrez]=grep_output
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(self.errors, self.ignore_errors, log_list)
print(self.getHardwareInfo())
errcount = 0
for log in result:
self.msg += 'Log: ' + log + '\n'
self.msg += '-----------------------\n'
for error in result[log]:
errcount += 1
self.msg += 'Central error: ' + str(error) + '\n'
self.msg += '***********************\n'
self.msg += result[str(log)][str(error)] + '\n'
self.msg += '***********************\n'
self.msg += '%s errors found in logs.' % errcount
self.assertEqual(errcount, 0, msg=self.msg)
+19
View 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
View 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
View 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():
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)
@@ -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)
+145
View File
@@ -0,0 +1,145 @@
#
# 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):
@classmethod
def setUpClass(cls):
pkgarch = cls.td['TUNE_PKGARCH'].replace('-', '_')
rpmdir = os.path.join(cls.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):
return
for f in fnmatch.filter(os.listdir(rpmdir), rpm_doc):
cls.test_file = os.path.join(rpmdir, f)
cls.dst = '/tmp/base-passwd-doc.rpm'
@OETestDepends(['rpm.RpmBasicTest.test_rpm_query'])
def test_rpm_install(self):
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>
"""
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
View 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
View 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)
@@ -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)
+62
View File
@@ -0,0 +1,62 @@
#
# 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'])
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'])
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 RustHelloworldTest(OERuntimeTestCase):
@OETestDepends(['ssh.SSHTest.test_ssh'])
@OEHasPackage(['rust-hello-world'])
def test_rusthelloworld(self):
cmd = "rust-hello-world"
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)
+39
View 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
View 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'])
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)
@@ -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 appropiate 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)
+21
View 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 SSHTest(OERuntimeTestCase):
@OETestDepends(['ping.PingTest.test_ping'])
@OEHasPackage(['dropbear', 'openssh-sshd'])
def test_ssh(self):
(status, output) = self.target.run('uname -a')
self.assertEqual(status, 0, msg='SSH Test failed: %s' % output)
(status, output) = self.target.run('cat /etc/controllerimage')
msg = "This isn't the right image - /etc/controllerimage " \
"shouldn't be here %s" % output
self.assertEqual(status, 1, msg=msg)
+34
View 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
View 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)
@@ -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()
+196
View File
@@ -0,0 +1,196 @@
#
# 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 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 --state=activating')
if "0 loaded units listed" 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')
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)
@@ -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.')
@@ -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()
@@ -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)
@@ -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
View 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
View 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
@@ -0,0 +1,89 @@
#
# 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,]
for pkg in self.need_pkgs:
if pkg.startswith('!'):
unneed_pkgs.add(pkg[1:])
else:
need_pkgs.add(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)
@@ -0,0 +1 @@
Program('hello.c')
+5
View File
@@ -0,0 +1,5 @@
int
main()
{
printf("Hello, world!\n");
}
@@ -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
@@ -0,0 +1,5 @@
test: test.o
gcc -o test test.o -lm
test.o: test.c
gcc -c test.c
+19
View 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]