summaryrefslogtreecommitdiffstats
path: root/meta/lib/oeqa/runtime
diff options
context:
space:
mode:
authorMariano Lopez <mariano.lopez@linux.intel.com>2016-11-01 07:48:16 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2017-01-23 12:05:20 +0000
commitb569aa0e0056a97b29577f5bda611ef3dd539db3 (patch)
tree64f4d7856959435abfc7c49258688f64861f6d7c /meta/lib/oeqa/runtime
parent3857e5c91da678d7bdc07712a1df9daa14354986 (diff)
downloadpoky-b569aa0e0056a97b29577f5bda611ef3dd539db3.tar.gz
oeqa/runtime/cases: Migrate runtime tests.
This migrates current runtime test suite to be used with the new framework. [YOCTO #10234] (From OE-Core rev: b39c61f2d442c79d03b73e8ffd104996fcb2177e) Signed-off-by: Mariano Lopez <mariano.lopez@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/lib/oeqa/runtime')
-rw-r--r--meta/lib/oeqa/runtime/cases/_ptest.py125
-rw-r--r--meta/lib/oeqa/runtime/cases/_qemutiny.py9
-rw-r--r--meta/lib/oeqa/runtime/cases/buildcvs.py35
-rw-r--r--meta/lib/oeqa/runtime/cases/buildgalculator.py31
-rw-r--r--meta/lib/oeqa/runtime/cases/buildiptables.py39
-rw-r--r--meta/lib/oeqa/runtime/cases/connman.py30
-rw-r--r--meta/lib/oeqa/runtime/cases/date.py38
-rw-r--r--meta/lib/oeqa/runtime/cases/df.py13
-rw-r--r--meta/lib/oeqa/runtime/cases/gcc.py76
-rw-r--r--meta/lib/oeqa/runtime/cases/kernelmodule.py40
-rw-r--r--meta/lib/oeqa/runtime/cases/ldd.py25
-rw-r--r--meta/lib/oeqa/runtime/cases/logrotate.py42
-rw-r--r--meta/lib/oeqa/runtime/cases/multilib.py41
-rw-r--r--meta/lib/oeqa/runtime/cases/pam.py33
-rw-r--r--meta/lib/oeqa/runtime/cases/parselogs.py358
-rw-r--r--meta/lib/oeqa/runtime/cases/perl.py37
-rw-r--r--meta/lib/oeqa/runtime/cases/ping.py24
-rw-r--r--meta/lib/oeqa/runtime/cases/python.py43
-rw-r--r--meta/lib/oeqa/runtime/cases/rpm.py141
-rw-r--r--meta/lib/oeqa/runtime/cases/scanelf.py26
-rw-r--r--meta/lib/oeqa/runtime/cases/scp.py33
-rw-r--r--meta/lib/oeqa/runtime/cases/skeletoninit.py33
-rw-r--r--meta/lib/oeqa/runtime/cases/smart.py218
-rw-r--r--meta/lib/oeqa/runtime/cases/ssh.py15
-rw-r--r--meta/lib/oeqa/runtime/cases/syslog.py57
-rw-r--r--meta/lib/oeqa/runtime/cases/systemd.py181
-rw-r--r--meta/lib/oeqa/runtime/cases/x32lib.py19
-rw-r--r--meta/lib/oeqa/runtime/cases/xorg.py17
28 files changed, 1779 insertions, 0 deletions
diff --git a/meta/lib/oeqa/runtime/cases/_ptest.py b/meta/lib/oeqa/runtime/cases/_ptest.py
new file mode 100644
index 0000000000..a2432517e3
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/_ptest.py
@@ -0,0 +1,125 @@
1import unittest, os, shutil
2from oeqa.oetest import oeRuntimeTest, skipModule
3from oeqa.utils.decorators import *
4from oeqa.utils.logparser import *
5from oeqa.utils.httpserver import HTTPService
6import bb
7import glob
8from oe.package_manager import RpmPkgsList
9import subprocess
10
11def setUpModule():
12 if not oeRuntimeTest.hasFeature("package-management"):
13 skipModule("Image doesn't have package management feature")
14 if not oeRuntimeTest.hasPackage("smartpm"):
15 skipModule("Image doesn't have smart installed")
16 if "package_rpm" != oeRuntimeTest.tc.d.getVar("PACKAGE_CLASSES").split()[0]:
17 skipModule("Rpm is not the primary package manager")
18
19class PtestRunnerTest(oeRuntimeTest):
20
21 # a ptest log parser
22 def parse_ptest(self, logfile):
23 parser = Lparser(test_0_pass_regex="^PASS:(.+)", test_0_fail_regex="^FAIL:(.+)", section_0_begin_regex="^BEGIN: .*/(.+)/ptest", section_0_end_regex="^END: .*/(.+)/ptest")
24 parser.init()
25 result = Result()
26
27 with open(logfile) as f:
28 for line in f:
29 result_tuple = parser.parse_line(line)
30 if not result_tuple:
31 continue
32 result_tuple = line_type, category, status, name = parser.parse_line(line)
33
34 if line_type == 'section' and status == 'begin':
35 current_section = name
36 continue
37
38 if line_type == 'section' and status == 'end':
39 current_section = None
40 continue
41
42 if line_type == 'test' and status == 'pass':
43 result.store(current_section, name, status)
44 continue
45
46 if line_type == 'test' and status == 'fail':
47 result.store(current_section, name, status)
48 continue
49
50 result.sort_tests()
51 return result
52
53 @classmethod
54 def setUpClass(self):
55 #note the existing channels that are on the board before creating new ones
56# self.existingchannels = set()
57# (status, result) = oeRuntimeTest.tc.target.run('smart channel --show | grep "\["', 0)
58# for x in result.split("\n"):
59# self.existingchannels.add(x)
60 self.repo_server = HTTPService(oeRuntimeTest.tc.d.getVar('DEPLOY_DIR'), oeRuntimeTest.tc.target.server_ip)
61 self.repo_server.start()
62
63 @classmethod
64 def tearDownClass(self):
65 self.repo_server.stop()
66 #remove created channels to be able to repeat the tests on same image
67# (status, result) = oeRuntimeTest.tc.target.run('smart channel --show | grep "\["', 0)
68# for x in result.split("\n"):
69# if x not in self.existingchannels:
70# oeRuntimeTest.tc.target.run('smart channel --remove '+x[1:-1]+' -y', 0)
71
72 def add_smart_channel(self):
73 image_pkgtype = self.tc.d.getVar('IMAGE_PKGTYPE')
74 deploy_url = 'http://%s:%s/%s' %(self.target.server_ip, self.repo_server.port, image_pkgtype)
75 pkgarchs = self.tc.d.getVar('PACKAGE_ARCHS').replace("-","_").split()
76 for arch in os.listdir('%s/%s' % (self.repo_server.root_dir, image_pkgtype)):
77 if arch in pkgarchs:
78 self.target.run('smart channel -y --add {a} type=rpm-md baseurl={u}/{a}'.format(a=arch, u=deploy_url), 0)
79 self.target.run('smart update', 0)
80
81 def install_complementary(self, globs=None):
82 installed_pkgs_file = os.path.join(oeRuntimeTest.tc.d.getVar('WORKDIR'),
83 "installed_pkgs.txt")
84 self.pkgs_list = RpmPkgsList(oeRuntimeTest.tc.d, oeRuntimeTest.tc.d.getVar('IMAGE_ROOTFS'), oeRuntimeTest.tc.d.getVar('arch_var'), oeRuntimeTest.tc.d.getVar('os_var'))
85 with open(installed_pkgs_file, "w+") as installed_pkgs:
86 installed_pkgs.write(self.pkgs_list.list("arch"))
87
88 cmd = [bb.utils.which(os.getenv('PATH'), "oe-pkgdata-util"),
89 "-p", oeRuntimeTest.tc.d.getVar('PKGDATA_DIR'), "glob", installed_pkgs_file,
90 globs]
91 try:
92 bb.note("Installing complementary packages ...")
93 complementary_pkgs = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
94 except subprocess.CalledProcessError as e:
95 bb.fatal("Could not compute complementary packages list. Command "
96 "'%s' returned %d:\n%s" %
97 (' '.join(cmd), e.returncode, e.output))
98
99 return complementary_pkgs.split()
100
101 def setUpLocal(self):
102 self.ptest_log = os.path.join(oeRuntimeTest.tc.d.getVar("TEST_LOG_DIR"), "ptest-%s.log" % oeRuntimeTest.tc.d.getVar('DATETIME'))
103
104 @skipUnlessPassed('test_ssh')
105 def test_ptestrunner(self):
106 self.add_smart_channel()
107 (runnerstatus, result) = self.target.run('which ptest-runner', 0)
108 cond = oeRuntimeTest.hasPackage("ptest-runner") and oeRuntimeTest.hasFeature("ptest") and oeRuntimeTest.hasPackageMatch("-ptest") and (runnerstatus != 0)
109 if cond:
110 self.install_packages(self.install_complementary("*-ptest"))
111 self.install_packages(['ptest-runner'])
112
113 (runnerstatus, result) = self.target.run('/usr/bin/ptest-runner > /tmp/ptest.log 2>&1', 0)
114 #exit code is !=0 even if ptest-runner executes because some ptest tests fail.
115 self.assertTrue(runnerstatus != 127, msg="Cannot execute ptest-runner!")
116 self.target.copy_from('/tmp/ptest.log', self.ptest_log)
117 shutil.copyfile(self.ptest_log, "ptest.log")
118
119 result = self.parse_ptest("ptest.log")
120 log_results_to_location = "./results"
121 if os.path.exists(log_results_to_location):
122 shutil.rmtree(log_results_to_location)
123 os.makedirs(log_results_to_location)
124
125 result.log_as_files(log_results_to_location, test_status = ['pass','fail'])
diff --git a/meta/lib/oeqa/runtime/cases/_qemutiny.py b/meta/lib/oeqa/runtime/cases/_qemutiny.py
new file mode 100644
index 0000000000..a3c29f3572
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/_qemutiny.py
@@ -0,0 +1,9 @@
1import unittest
2from oeqa.oetest import oeRuntimeTest
3from oeqa.utils.qemutinyrunner import *
4
5class QemuTinyTest(oeRuntimeTest):
6
7 def test_boot_tiny(self):
8 (status, output) = self.target.run_serial('uname -a')
9 self.assertTrue("yocto-tiny" in output, msg="Cannot detect poky tiny boot!") \ No newline at end of file
diff --git a/meta/lib/oeqa/runtime/cases/buildcvs.py b/meta/lib/oeqa/runtime/cases/buildcvs.py
new file mode 100644
index 0000000000..341eb4959d
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/buildcvs.py
@@ -0,0 +1,35 @@
1from oeqa.runtime.case import OERuntimeTestCase
2from oeqa.core.decorator.depends import OETestDepends
3from oeqa.core.decorator.oeid import OETestID
4from oeqa.core.decorator.data import skipIfNotFeature
5
6from oeqa.runtime.utils.targetbuildproject import TargetBuildProject
7
8class BuildCvsTest(OERuntimeTestCase):
9
10 @classmethod
11 def setUpClass(cls):
12 uri = 'http://ftp.gnu.org/non-gnu/cvs/source/feature/1.12.13'
13 uri = '%s/cvs-1.12.13.tar.bz2' % uri
14 cls.project = TargetBuildProject(cls.tc.target,
15 uri,
16 dl_dir = cls.tc.td['DL_DIR'])
17 cls.project.download_archive()
18
19 @classmethod
20 def tearDownClass(cls):
21 cls.project.clean()
22
23 @OETestID(205)
24 @skipIfNotFeature('tools-sdk',
25 'Test requires tools-sdk to be in IMAGE_FEATURES')
26 @OETestDepends(['ssh.SSHTest.test_ssh'])
27 def test_cvs(self):
28 self.assertEqual(self.project.run_configure(), 0,
29 msg="Running configure failed")
30
31 self.assertEqual(self.project.run_make(), 0,
32 msg="Running make failed")
33
34 self.assertEqual(self.project.run_install(), 0,
35 msg="Running make install failed")
diff --git a/meta/lib/oeqa/runtime/cases/buildgalculator.py b/meta/lib/oeqa/runtime/cases/buildgalculator.py
new file mode 100644
index 0000000000..0bd76f9ea2
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/buildgalculator.py
@@ -0,0 +1,31 @@
1from oeqa.runtime.case import OERuntimeTestCase
2from oeqa.core.decorator.depends import OETestDepends
3from oeqa.core.decorator.oeid import OETestID
4from oeqa.core.decorator.data import skipIfNotFeature
5
6from oeqa.runtime.utils.targetbuildproject import TargetBuildProject
7
8class GalculatorTest(OERuntimeTestCase):
9
10 @classmethod
11 def setUpClass(cls):
12 uri = 'http://galculator.mnim.org/downloads/galculator-2.1.4.tar.bz2'
13 cls.project = TargetBuildProject(cls.tc.target,
14 uri,
15 dl_dir = cls.tc.td['DL_DIR'])
16 cls.project.download_archive()
17
18 @classmethod
19 def tearDownClass(cls):
20 cls.project.clean()
21
22 @OETestID(1526)
23 @skipIfNotFeature('tools-sdk',
24 'Test requires tools-sdk to be in IMAGE_FEATURES')
25 @OETestDepends(['ssh.SSHTest.test_ssh'])
26 def test_galculator(self):
27 self.assertEqual(self.project.run_configure(), 0,
28 msg="Running configure failed")
29
30 self.assertEqual(self.project.run_make(), 0,
31 msg="Running make failed")
diff --git a/meta/lib/oeqa/runtime/cases/buildiptables.py b/meta/lib/oeqa/runtime/cases/buildiptables.py
new file mode 100644
index 0000000000..bae80392d9
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/buildiptables.py
@@ -0,0 +1,39 @@
1from oeqa.runtime.case import OERuntimeTestCase
2from oeqa.core.decorator.depends import OETestDepends
3from oeqa.core.decorator.oeid import OETestID
4from oeqa.core.decorator.data import skipIfNotFeature
5
6from oeqa.runtime.utils.targetbuildproject import TargetBuildProject
7
8class BuildIptablesTest(OERuntimeTestCase):
9
10 @classmethod
11 def setUpClass(cls):
12 uri = 'http://downloads.yoctoproject.org/mirror/sources'
13 uri = '%s/iptables-1.4.13.tar.bz2' % uri
14 cls.project = TargetBuildProject(cls.tc.target,
15 uri,
16 dl_dir = cls.tc.td['DL_DIR'])
17 cls.project.download_archive()
18
19 @classmethod
20 def tearDownClass(cls):
21 cls.project.clean()
22
23 @OETestID(206)
24 @skipIfNotFeature('tools-sdk',
25 'Test requires tools-sdk to be in IMAGE_FEATURES')
26 @OETestDepends(['ssh.SSHTest.test_ssh'])
27 def test_iptables(self):
28 self.assertEqual(self.project.run_configure(), 0,
29 msg="Running configure failed")
30
31 self.assertEqual(self.project.run_make(), 0,
32 msg="Running make failed")
33
34 self.assertEqual(self.project.run_install(), 0,
35 msg="Running make install failed")
36
37 @classmethod
38 def tearDownClass(self):
39 self.project.clean()
diff --git a/meta/lib/oeqa/runtime/cases/connman.py b/meta/lib/oeqa/runtime/cases/connman.py
new file mode 100644
index 0000000000..8b47108a37
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/connman.py
@@ -0,0 +1,30 @@
1from oeqa.runtime.case import OERuntimeTestCase
2from oeqa.core.decorator.depends import OETestDepends
3from oeqa.core.decorator.oeid import OETestID
4from oeqa.runtime.decorator.package import OEHasPackage
5
6class ConnmanTest(OERuntimeTestCase):
7
8 def service_status(self, service):
9 if oeRuntimeTest.hasFeature("systemd"):
10 (_, output) = self.target.run('systemctl status -l %s' % service)
11 return output
12 else:
13 return "Unable to get status or logs for %s" % service
14
15 @OETestID(961)
16 @OETestDepends(['ssh.SSHTest.test_ssh'])
17 @OEHasPackage(["connman"])
18 def test_connmand_help(self):
19 (status, output) = self.target.run('/usr/sbin/connmand --help')
20 msg = 'Failed to get connman help. Output: %s' % output
21 self.assertEqual(status, 0, msg=msg)
22
23 @OETestID(221)
24 @OETestDepends(['connman.ConnmanTest.test_connmand_help'])
25 def test_connmand_running(self):
26 cmd = '%s | grep [c]onnmand' % self.tc.target_cmds['ps']
27 (status, output) = self.target.run(cmd)
28 if status != 0:
29 self.logger.info(self.service_status("connman"))
30 self.fail("No connmand process running")
diff --git a/meta/lib/oeqa/runtime/cases/date.py b/meta/lib/oeqa/runtime/cases/date.py
new file mode 100644
index 0000000000..ece7338de7
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/date.py
@@ -0,0 +1,38 @@
1import re
2
3from oeqa.runtime.case import OERuntimeTestCase
4from oeqa.core.decorator.depends import OETestDepends
5from oeqa.core.decorator.oeid import OETestID
6
7class DateTest(OERuntimeTestCase):
8
9 def setUp(self):
10 if self.tc.td.get('VIRTUAL-RUNTIME_init_manager') == 'systemd':
11 self.logger.debug('Stopping systemd-timesyncd daemon')
12 self.target.run('systemctl stop systemd-timesyncd')
13
14 def tearDown(self):
15 if self.tc.td.get('VIRTUAL-RUNTIME_init_manager') == 'systemd':
16 self.logger.debug('Starting systemd-timesyncd daemon')
17 self.target.run('systemctl start systemd-timesyncd')
18
19 @OETestID(211)
20 @OETestDepends(['ssh.SSHTest.test_ssh'])
21 def test_date(self):
22 (status, output) = self.target.run('date +"%Y-%m-%d %T"')
23 msg = 'Failed to get initial date, output: %s' % output
24 self.assertEqual(status, 0, msg=msg)
25 oldDate = output
26
27 sampleDate = '"2016-08-09 10:00:00"'
28 (status, output) = self.target.run("date -s %s" % sampleDate)
29 self.assertEqual(status, 0, msg='Date set failed, output: %s' % output)
30
31 (status, output) = self.target.run("date -R")
32 p = re.match('Tue, 09 Aug 2016 10:00:.. \+0000', output)
33 msg = 'The date was not set correctly, output: %s' % output
34 self.assertTrue(p, msg=msg)
35
36 (status, output) = self.target.run('date -s "%s"' % oldDate)
37 msg = 'Failed to reset date, output: %s' % output
38 self.assertEqual(status, 0, msg=msg)
diff --git a/meta/lib/oeqa/runtime/cases/df.py b/meta/lib/oeqa/runtime/cases/df.py
new file mode 100644
index 0000000000..aecc32d7ce
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/df.py
@@ -0,0 +1,13 @@
1from oeqa.runtime.case import OERuntimeTestCase
2from oeqa.core.decorator.depends import OETestDepends
3from oeqa.core.decorator.oeid import OETestID
4
5class DfTest(OERuntimeTestCase):
6
7 @OETestID(234)
8 @OETestDepends(['ssh.SSHTest.test_ssh'])
9 def test_df(self):
10 cmd = "df / | sed -n '2p' | awk '{print $4}'"
11 (status,output) = self.target.run(cmd)
12 msg = 'Not enough space on image. Current size is %s' % output
13 self.assertTrue(int(output)>5120, msg=msg)
diff --git a/meta/lib/oeqa/runtime/cases/gcc.py b/meta/lib/oeqa/runtime/cases/gcc.py
new file mode 100644
index 0000000000..064fa49af1
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/gcc.py
@@ -0,0 +1,76 @@
1import os
2
3from oeqa.runtime.case import OERuntimeTestCase
4from oeqa.core.decorator.depends import OETestDepends
5from oeqa.core.decorator.oeid import OETestID
6from oeqa.core.decorator.data import skipIfNotFeature
7
8class GccCompileTest(OERuntimeTestCase):
9
10 @classmethod
11 def setUpClass(cls):
12 dst = '/tmp/'
13 src = os.path.join(cls.tc.files_dir, 'test.c')
14 #dst = '/tmp/test.c'
15 cls.tc.target.copyTo(src, dst)
16
17 src = os.path.join(cls.tc.runtime_files_dir, 'testmakefile')
18 #dst = '/tmp/testmakefile'
19 cls.tc.target.copyTo(src, dst)
20
21 src = os.path.join(cls.tc.files_dir, 'test.cpp')
22 #dst = '/tmp/test.cpp'
23 cls.tc.target.copyTo(src, dst)
24
25 @classmethod
26 def tearDownClass(cls):
27 files = '/tmp/test.c /tmp/test.o /tmp/test /tmp/testmakefile'
28 cls.tc.target.run('rm %s' % files)
29
30 @OETestID(203)
31 @skipIfNotFeature('tools-sdk',
32 'Test requires tools-sdk to be in IMAGE_FEATURES')
33 @OETestDepends(['ssh.SSHTest.test_ssh'])
34 def test_gcc_compile(self):
35 status, output = self.target.run('gcc /tmp/test.c -o /tmp/test -lm')
36 msg = 'gcc compile failed, output: %s' % output
37 self.assertEqual(status, 0, msg=msg)
38
39 status, output = self.target.run('/tmp/test')
40 msg = 'running compiled file failed, output: %s' % output
41 self.assertEqual(status, 0, msg=msg)
42
43 @OETestID(200)
44 @skipIfNotFeature('tools-sdk',
45 'Test requires tools-sdk to be in IMAGE_FEATURES')
46 @OETestDepends(['ssh.SSHTest.test_ssh'])
47 def test_gpp_compile(self):
48 status, output = self.target.run('g++ /tmp/test.c -o /tmp/test -lm')
49 msg = 'g++ compile failed, output: %s' % output
50 self.assertEqual(status, 0, msg=msg)
51
52 status, output = self.target.run('/tmp/test')
53 msg = 'running compiled file failed, output: %s' % output
54 self.assertEqual(status, 0, msg=msg)
55
56 @OETestID(1142)
57 @skipIfNotFeature('tools-sdk',
58 'Test requires tools-sdk to be in IMAGE_FEATURES')
59 @OETestDepends(['ssh.SSHTest.test_ssh'])
60 def test_gpp2_compile(self):
61 status, output = self.target.run('g++ /tmp/test.cpp -o /tmp/test -lm')
62 msg = 'g++ compile failed, output: %s' % output
63 self.assertEqual(status, 0, msg=msg)
64
65 status, output = self.target.run('/tmp/test')
66 msg = 'running compiled file failed, output: %s' % output
67 self.assertEqual(status, 0, msg=msg)
68
69 @OETestID(204)
70 @skipIfNotFeature('tools-sdk',
71 'Test requires tools-sdk to be in IMAGE_FEATURES')
72 @OETestDepends(['ssh.SSHTest.test_ssh'])
73 def test_make(self):
74 status, output = self.target.run('cd /tmp; make -f testmakefile')
75 msg = 'running make failed, output %s' % output
76 self.assertEqual(status, 0, msg=msg)
diff --git a/meta/lib/oeqa/runtime/cases/kernelmodule.py b/meta/lib/oeqa/runtime/cases/kernelmodule.py
new file mode 100644
index 0000000000..11ad7b7f01
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/kernelmodule.py
@@ -0,0 +1,40 @@
1import os
2
3from oeqa.runtime.case import OERuntimeTestCase
4from oeqa.core.decorator.depends import OETestDepends
5from oeqa.core.decorator.oeid import OETestID
6from oeqa.core.decorator.data import skipIfNotFeature
7
8class KernelModuleTest(OERuntimeTestCase):
9
10 @classmethod
11 def setUpClass(cls):
12 src = os.path.join(cls.tc.runtime_files_dir, 'hellomod.c')
13 dst = '/tmp/hellomod.c'
14 cls.tc.target.copyTo(src, dst)
15
16 src = os.path.join(cls.tc.runtime_files_dir, 'hellomod_makefile')
17 dst = '/tmp/Makefile'
18 cls.tc.target.copyTo(src, dst)
19
20 @classmethod
21 def tearDownClass(cls):
22 files = '/tmp/Makefile /tmp/hellomod.c'
23 cls.tc.target.run('rm %s' % files)
24
25 @OETestID(1541)
26 @skipIfNotFeature('tools-sdk',
27 'Test requires tools-sdk to be in IMAGE_FEATURES')
28 @OETestDepends(['gcc.GccCompileTest.test_gcc_compile'])
29 def test_kernel_module(self):
30 cmds = [
31 'cd /usr/src/kernel && make scripts',
32 'cd /tmp && make',
33 'cd /tmp && insmod hellomod.ko',
34 'lsmod | grep hellomod',
35 'dmesg | grep Hello',
36 'rmmod hellomod', 'dmesg | grep "Cleaning up hellomod"'
37 ]
38 for cmd in cmds:
39 status, output = self.target.run(cmd, 900)
40 self.assertEqual(status, 0, msg='\n'.join([cmd, output]))
diff --git a/meta/lib/oeqa/runtime/cases/ldd.py b/meta/lib/oeqa/runtime/cases/ldd.py
new file mode 100644
index 0000000000..c6d92fd5af
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/ldd.py
@@ -0,0 +1,25 @@
1from oeqa.runtime.case import OERuntimeTestCase
2from oeqa.core.decorator.depends import OETestDepends
3from oeqa.core.decorator.oeid import OETestID
4from oeqa.core.decorator.data import skipIfNotFeature
5
6class LddTest(OERuntimeTestCase):
7
8 @OETestID(962)
9 @skipIfNotFeature('tools-sdk',
10 'Test requires tools-sdk to be in IMAGE_FEATURES')
11 @OETestDepends(['ssh.SSHTest.test_ssh'])
12 def test_ldd_exists(self):
13 status, output = self.target.run('which ldd')
14 msg = 'ldd does not exist in PATH: which ldd: %s' % output
15 self.assertEqual(status, 0, msg=msg)
16
17 @OETestID(239)
18 @OETestDepends(['ldd.LddTest.test_ldd_exists'])
19 def test_ldd_rtldlist_check(self):
20 cmd = ('for i in $(which ldd | xargs cat | grep "^RTLDLIST"| '
21 'cut -d\'=\' -f2|tr -d \'"\'); '
22 'do test -f $i && echo $i && break; done')
23 status, output = self.target.run(cmd)
24 msg = "ldd path not correct or RTLDLIST files don't exist."
25 self.assertEqual(status, 0, msg=msg)
diff --git a/meta/lib/oeqa/runtime/cases/logrotate.py b/meta/lib/oeqa/runtime/cases/logrotate.py
new file mode 100644
index 0000000000..992fef2989
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/logrotate.py
@@ -0,0 +1,42 @@
1# This test should cover https://bugzilla.yoctoproject.org/tr_show_case.cgi?case_id=289 testcase
2# Note that the image under test must have logrotate installed
3
4from oeqa.runtime.case import OERuntimeTestCase
5from oeqa.core.decorator.depends import OETestDepends
6from oeqa.core.decorator.oeid import OETestID
7from oeqa.runtime.decorator.package import OEHasPackage
8
9class LogrotateTest(OERuntimeTestCase):
10
11 @classmethod
12 def tearDownClass(cls):
13 cls.tc.target.run('rm -rf $HOME/logrotate_dir')
14
15 @OETestID(1544)
16 @OETestDepends(['ssh.SSHTest.test_ssh'])
17 @OEHasPackage(['logrotate'])
18 def test_1_logrotate_setup(self):
19 status, output = self.target.run('mkdir $HOME/logrotate_dir')
20 msg = 'Could not create logrotate_dir. Output: %s' % output
21 self.assertEqual(status, 0, msg = msg)
22
23 cmd = ('sed -i "s#wtmp {#wtmp {\\n olddir $HOME/logrotate_dir#"'
24 ' /etc/logrotate.conf')
25 status, output = self.target.run(cmd)
26 msg = ('Could not write to logrotate.conf file. Status and output: '
27 ' %s and %s' % (status, output))
28 self.assertEqual(status, 0, msg = msg)
29
30 @OETestID(1542)
31 @OETestDepends(['logrotate.LogrotateTest.test_1_logrotate_setup'])
32 def test_2_logrotate(self):
33 status, output = self.target.run('logrotate -f /etc/logrotate.conf')
34 msg = ('logrotate service could not be reloaded. Status and output: '
35 '%s and %s' % (status, output))
36 self.assertEqual(status, 0, msg = msg)
37
38 _, output = self.target.run('ls -la $HOME/logrotate_dir/ | wc -l')
39 msg = ('new logfile could not be created. List of files within log '
40 'directory: %s' % (
41 self.target.run('ls -la $HOME/logrotate_dir')[1]))
42 self.assertTrue(int(output)>=3, msg = msg)
diff --git a/meta/lib/oeqa/runtime/cases/multilib.py b/meta/lib/oeqa/runtime/cases/multilib.py
new file mode 100644
index 0000000000..8f6d2b24a6
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/multilib.py
@@ -0,0 +1,41 @@
1from oeqa.runtime.case import OERuntimeTestCase
2from oeqa.core.decorator.depends import OETestDepends
3from oeqa.core.decorator.oeid import OETestID
4from oeqa.core.decorator.data import skipIfNotInDataVar
5from oeqa.runtime.decorator.package import OEHasPackage
6
7class MultilibTest(OERuntimeTestCase):
8
9 def archtest(self, binary, arch):
10 """
11 Check that ``binary`` has the ELF class ``arch`` (e.g. ELF32/ELF64).
12 """
13
14 status, output = self.target.run('readelf -h %s' % binary)
15 self.assertEqual(status, 0, 'Failed to readelf %s' % binary)
16
17 l = [l.split()[1] for l in output.split('\n') if "Class:" in l]
18 if l:
19 theclass = l[0]
20 else:
21 self.fail('Cannot parse readelf. Output:\n%s' % output)
22
23 msg = "%s isn't %s (is %s)" % (binary, arch, theclass)
24 self.assertEqual(theclass, arch, msg=msg)
25
26 @skipIfNotInDataVar('MULTILIBS', 'multilib:lib32',
27 "This isn't a multilib:lib32 image")
28 @OETestID(201)
29 @OETestDepends(['ssh.SSHTest.test_ssh'])
30 def test_check_multilib_libc(self):
31 """
32 Check that a multilib image has both 32-bit and 64-bit libc in.
33 """
34 self.archtest("/lib/libc.so.6", "ELF32")
35 self.archtest("/lib64/libc.so.6", "ELF64")
36
37 @OETestID(279)
38 @OETestDepends(['multilib.MultilibTest.test_check_multilib_libc'])
39 @OEHasPackage(['lib32-connman'])
40 def test_file_connman(self):
41 self.archtest("/usr/sbin/connmand", "ELF32")
diff --git a/meta/lib/oeqa/runtime/cases/pam.py b/meta/lib/oeqa/runtime/cases/pam.py
new file mode 100644
index 0000000000..3654cdc946
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/pam.py
@@ -0,0 +1,33 @@
1# This test should cover https://bugzilla.yoctoproject.org/tr_show_case.cgi?case_id=287 testcase
2# Note that the image under test must have "pam" in DISTRO_FEATURES
3
4from oeqa.runtime.case import OERuntimeTestCase
5from oeqa.core.decorator.depends import OETestDepends
6from oeqa.core.decorator.oeid import OETestID
7from oeqa.core.decorator.data import skipIfNotFeature
8
9class PamBasicTest(OERuntimeTestCase):
10
11 @OETestID(1543)
12 @skipIfNotFeature('pam', 'Test requires pam to be in DISTRO_FEATURES')
13 @OETestDepends(['ssh.SSHTest.test_ssh'])
14 def test_pam(self):
15 status, output = self.target.run('login --help')
16 msg = ('login command does not work as expected. '
17 'Status and output:%s and %s' % (status, output))
18 self.assertEqual(status, 1, msg = msg)
19
20 status, output = self.target.run('passwd --help')
21 msg = ('passwd command does not work as expected. '
22 'Status and output:%s and %s' % (status, output))
23 self.assertEqual(status, 0, msg = msg)
24
25 status, output = self.target.run('su --help')
26 msg = ('su command does not work as expected. '
27 'Status and output:%s and %s' % (status, output))
28 self.assertEqual(status, 0, msg = msg)
29
30 status, output = self.target.run('useradd --help')
31 msg = ('useradd command does not work as expected. '
32 'Status and output:%s and %s' % (status, output))
33 self.assertEqual(status, 0, msg = msg)
diff --git a/meta/lib/oeqa/runtime/cases/parselogs.py b/meta/lib/oeqa/runtime/cases/parselogs.py
new file mode 100644
index 0000000000..a53a3608bd
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/parselogs.py
@@ -0,0 +1,358 @@
1import os
2
3from subprocess import check_output
4from shutil import rmtree
5from oeqa.runtime.case import OERuntimeTestCase
6from oeqa.core.decorator.depends import OETestDepends
7from oeqa.core.decorator.oeid import OETestID
8from oeqa.core.decorator.data import skipIfDataVar
9from oeqa.runtime.decorator.package import OEHasPackage
10
11#in the future these lists could be moved outside of module
12errors = ["error", "cannot", "can\'t", "failed"]
13
14common_errors = [
15 "(WW) warning, (EE) error, (NI) not implemented, (??) unknown.",
16 "dma timeout",
17 "can\'t add hid device:",
18 "usbhid: probe of ",
19 "_OSC failed (AE_ERROR)",
20 "_OSC failed (AE_SUPPORT)",
21 "AE_ALREADY_EXISTS",
22 "ACPI _OSC request failed (AE_SUPPORT)",
23 "can\'t disable ASPM",
24 "Failed to load module \"vesa\"",
25 "Failed to load module vesa",
26 "Failed to load module \"modesetting\"",
27 "Failed to load module modesetting",
28 "Failed to load module \"glx\"",
29 "Failed to load module \"fbdev\"",
30 "Failed to load module fbdev",
31 "Failed to load module glx",
32 "[drm] Cannot find any crtc or sizes - going 1024x768",
33 "_OSC failed (AE_NOT_FOUND); disabling ASPM",
34 "Open ACPI failed (/var/run/acpid.socket) (No such file or directory)",
35 "NX (Execute Disable) protection cannot be enabled: non-PAE kernel!",
36 "hd.: possibly failed opcode",
37 'NETLINK INITIALIZATION FAILED',
38 'kernel: Cannot find map file',
39 'omap_hwmod: debugss: _wait_target_disable failed',
40 'VGA arbiter: cannot open kernel arbiter, no multi-card support',
41 'Failed to find URL:http://ipv4.connman.net/online/status.html',
42 'Online check failed for',
43 'netlink init failed',
44 'Fast TSC calibration',
45 "BAR 0-9",
46 "Failed to load module \"ati\"",
47 "controller can't do DEVSLP, turning off",
48 "stmmac_dvr_probe: warning: cannot get CSR clock",
49 "error: couldn\'t mount because of unsupported optional features",
50 "GPT: Use GNU Parted to correct GPT errors",
51 ]
52
53video_related = [
54 "uvesafb",
55]
56
57x86_common = [
58 '[drm:psb_do_init] *ERROR* Debug is',
59 'wrong ELF class',
60 'Could not enable PowerButton event',
61 'probe of LNXPWRBN:00 failed with error -22',
62 'pmd_set_huge: Cannot satisfy',
63 'failed to setup card detect gpio',
64 'amd_nb: Cannot enumerate AMD northbridges',
65 'failed to retrieve link info, disabling eDP',
66 'Direct firmware load for iwlwifi',
67] + common_errors
68
69qemux86_common = [
70 'wrong ELF class',
71 "fail to add MMCONFIG information, can't access extended PCI configuration space under this bridge.",
72 "can't claim BAR ",
73 'amd_nb: Cannot enumerate AMD northbridges',
74 'uvesafb: 5000 ms task timeout, infinitely waiting',
75 'tsc: HPET/PMTIMER calibration failed',
76] + common_errors
77
78ignore_errors = {
79 'default' : common_errors,
80 'qemux86' : [
81 'Failed to access perfctr msr (MSR',
82 'pci 0000:00:00.0: [Firmware Bug]: reg 0x..: invalid BAR (can\'t size)',
83 ] + qemux86_common,
84 'qemux86-64' : qemux86_common,
85 'qemumips' : [
86 'Failed to load module "glx"',
87 'pci 0000:00:00.0: [Firmware Bug]: reg 0x..: invalid BAR (can\'t size)',
88 ] + common_errors,
89 'qemumips64' : [
90 'pci 0000:00:00.0: [Firmware Bug]: reg 0x..: invalid BAR (can\'t size)',
91 ] + common_errors,
92 'qemuppc' : [
93 'PCI 0000:00 Cannot reserve Legacy IO [io 0x0000-0x0fff]',
94 'host side 80-wire cable detection failed, limiting max speed',
95 'mode "640x480" test failed',
96 'Failed to load module "glx"',
97 'can\'t handle BAR above 4GB',
98 'Cannot reserve Legacy IO',
99 ] + common_errors,
100 'qemuarm' : [
101 'mmci-pl18x: probe of fpga:05 failed with error -22',
102 'mmci-pl18x: probe of fpga:0b failed with error -22',
103 'Failed to load module "glx"',
104 'OF: amba_device_add() failed (-19) for /amba/smc@10100000',
105 'OF: amba_device_add() failed (-19) for /amba/mpmc@10110000',
106 'OF: amba_device_add() failed (-19) for /amba/sctl@101e0000',
107 'OF: amba_device_add() failed (-19) for /amba/watchdog@101e1000',
108 'OF: amba_device_add() failed (-19) for /amba/sci@101f0000',
109 'OF: amba_device_add() failed (-19) for /amba/ssp@101f4000',
110 'OF: amba_device_add() failed (-19) for /amba/fpga/sci@a000',
111 'Failed to initialize \'/amba/timer@101e3000\': -22',
112 'jitterentropy: Initialization failed with host not compliant with requirements: 2',
113 ] + common_errors,
114 'qemuarm64' : [
115 'Fatal server error:',
116 '(EE) Server terminated with error (1). Closing log file.',
117 'dmi: Firmware registration failed.',
118 'irq: type mismatch, failed to map hwirq-27 for /intc',
119 ] + common_errors,
120 'emenlow' : [
121 '[Firmware Bug]: ACPI: No _BQC method, cannot determine initial brightness',
122 '(EE) Failed to load module "psb"',
123 '(EE) Failed to load module psb',
124 '(EE) Failed to load module "psbdrv"',
125 '(EE) Failed to load module psbdrv',
126 '(EE) open /dev/fb0: No such file or directory',
127 '(EE) AIGLX: reverting to software rendering',
128 ] + x86_common,
129 'intel-core2-32' : [
130 'ACPI: No _BQC method, cannot determine initial brightness',
131 '[Firmware Bug]: ACPI: No _BQC method, cannot determine initial brightness',
132 '(EE) Failed to load module "psb"',
133 '(EE) Failed to load module psb',
134 '(EE) Failed to load module "psbdrv"',
135 '(EE) Failed to load module psbdrv',
136 '(EE) open /dev/fb0: No such file or directory',
137 '(EE) AIGLX: reverting to software rendering',
138 'dmi: Firmware registration failed.',
139 'ioremap error for 0x78',
140 ] + x86_common,
141 'intel-corei7-64' : [
142 'can\'t set Max Payload Size to 256',
143 'intel_punit_ipc: can\'t request region for resource',
144 '[drm] parse error at position 4 in video mode \'efifb\'',
145 'ACPI Error: Could not enable RealTimeClock event',
146 'ACPI Warning: Could not enable fixed event - RealTimeClock',
147 'hci_intel INT33E1:00: Unable to retrieve gpio',
148 'hci_intel: probe of INT33E1:00 failed',
149 'can\'t derive routing for PCI INT A',
150 'failed to read out thermal zone',
151 'Bluetooth: hci0: Setting Intel event mask failed',
152 'ttyS2 - failed to request DMA',
153 ] + x86_common,
154 'crownbay' : x86_common,
155 'genericx86' : x86_common,
156 'genericx86-64' : [
157 'Direct firmware load for i915',
158 'Failed to load firmware i915',
159 'Failed to fetch GuC',
160 'Failed to initialize GuC',
161 'Failed to load DMC firmware',
162 'The driver is built-in, so to load the firmware you need to',
163 ] + x86_common,
164 'edgerouter' : [
165 'Fatal server error:',
166 ] + common_errors,
167 'jasperforest' : [
168 'Activated service \'org.bluez\' failed:',
169 'Unable to find NFC netlink family',
170 ] + common_errors,
171}
172
173log_locations = ["/var/log/","/var/log/dmesg", "/tmp/dmesg_output.log"]
174
175class ParseLogsTest(OERuntimeTestCase):
176
177 @classmethod
178 def setUpClass(cls):
179 cls.errors = errors
180
181 # When systemd is enabled we need to notice errors on
182 # circular dependencies in units.
183 if 'systemd' in cls.td.get('DISTRO_FEATURES', ''):
184 cls.errors.extend([
185 'Found ordering cycle on',
186 'Breaking ordering cycle by deleting job',
187 'deleted to break ordering cycle',
188 'Ordering cycle found, skipping',
189 ])
190
191 cls.ignore_errors = ignore_errors
192 cls.log_locations = log_locations
193 cls.msg = ''
194 is_lsb, _ = cls.tc.target.run("which LSB_Test.sh")
195 if is_lsb == 0:
196 for machine in cls.ignore_errors:
197 cls.ignore_errors[machine] = cls.ignore_errors[machine] \
198 + video_related
199
200 def getMachine(self):
201 return self.td.get('MACHINE', '')
202
203 def getWorkdir(self):
204 return self.td.get('WORKDIR', '')
205
206 # Get some information on the CPU of the machine to display at the
207 # beginning of the output. This info might be useful in some cases.
208 def getHardwareInfo(self):
209 hwi = ""
210 cmd = ('cat /proc/cpuinfo | grep "model name" | head -n1 | '
211 " awk 'BEGIN{FS=\":\"}{print $2}'")
212 _, cpu_name = self.target.run(cmd)
213
214 cmd = ('cat /proc/cpuinfo | grep "cpu cores" | head -n1 | '
215 "awk {'print $4'}")
216 _, cpu_physical_cores = self.target.run(cmd)
217
218 cmd = 'cat /proc/cpuinfo | grep "processor" | wc -l'
219 _, cpu_logical_cores = self.target.run(cmd)
220
221 _, cpu_arch = self.target.run('uname -m')
222
223 hwi += 'Machine information: \n'
224 hwi += '*******************************\n'
225 hwi += 'Machine name: ' + self.getMachine() + '\n'
226 hwi += 'CPU: ' + str(cpu_name) + '\n'
227 hwi += 'Arch: ' + str(cpu_arch)+ '\n'
228 hwi += 'Physical cores: ' + str(cpu_physical_cores) + '\n'
229 hwi += 'Logical cores: ' + str(cpu_logical_cores) + '\n'
230 hwi += '*******************************\n'
231
232 return hwi
233
234 # Go through the log locations provided and if it's a folder
235 # create a list with all the .log files in it, if it's a file
236 # just add it to that list.
237 def getLogList(self, log_locations):
238 logs = []
239 for location in log_locations:
240 status, _ = self.target.run('test -f ' + str(location))
241 if status == 0:
242 logs.append(str(location))
243 else:
244 status, _ = self.target.run('test -d ' + str(location))
245 if status == 0:
246 cmd = 'find ' + str(location) + '/*.log -maxdepth 1 -type f'
247 status, output = self.target.run(cmd)
248 if status == 0:
249 output = output.splitlines()
250 for logfile in output:
251 logs.append(os.path.join(location, str(logfile)))
252 return logs
253
254 # Copy the log files to be parsed locally
255 def transfer_logs(self, log_list):
256 workdir = self.getWorkdir()
257 self.target_logs = workdir + '/' + 'target_logs'
258 target_logs = self.target_logs
259 if os.path.exists(target_logs):
260 rmtree(self.target_logs)
261 os.makedirs(target_logs)
262 for f in log_list:
263 self.target.copyFrom(str(f), target_logs)
264
265 # Get the local list of logs
266 def get_local_log_list(self, log_locations):
267 self.transfer_logs(self.getLogList(log_locations))
268 list_dir = os.listdir(self.target_logs)
269 dir_files = [os.path.join(self.target_logs, f) for f in list_dir]
270 logs = [f for f in dir_files if os.path.isfile(f)]
271 return logs
272
273 # Build the grep command to be used with filters and exclusions
274 def build_grepcmd(self, errors, ignore_errors, log):
275 grepcmd = 'grep '
276 grepcmd += '-Ei "'
277 for error in errors:
278 grepcmd += error + '|'
279 grepcmd = grepcmd[:-1]
280 grepcmd += '" ' + str(log) + " | grep -Eiv \'"
281
282 try:
283 errorlist = ignore_errors[self.getMachine()]
284 except KeyError:
285 self.msg += 'No ignore list found for this machine, using default\n'
286 errorlist = ignore_errors['default']
287
288 for ignore_error in errorlist:
289 ignore_error = ignore_error.replace('(', '\(')
290 ignore_error = ignore_error.replace(')', '\)')
291 ignore_error = ignore_error.replace("'", '.')
292 ignore_error = ignore_error.replace('?', '\?')
293 ignore_error = ignore_error.replace('[', '\[')
294 ignore_error = ignore_error.replace(']', '\]')
295 ignore_error = ignore_error.replace('*', '\*')
296 ignore_error = ignore_error.replace('0-9', '[0-9]')
297 grepcmd += ignore_error + '|'
298 grepcmd = grepcmd[:-1]
299 grepcmd += "\'"
300
301 return grepcmd
302
303 # Grep only the errors so that their context could be collected.
304 # Default context is 10 lines before and after the error itself
305 def parse_logs(self, errors, ignore_errors, logs,
306 lines_before = 10, lines_after = 10):
307 results = {}
308 rez = []
309 grep_output = ''
310
311 for log in logs:
312 result = None
313 thegrep = self.build_grepcmd(errors, ignore_errors, log)
314
315 try:
316 result = check_output(thegrep, shell=True).decode('utf-8')
317 except:
318 pass
319
320 if result is not None:
321 results[log.replace('target_logs/','')] = {}
322 rez = result.splitlines()
323
324 for xrez in rez:
325 try:
326 cmd = ['grep', '-F', xrez, '-B', str(lines_before)]
327 cmd += ['-A', str(lines_after), log]
328 grep_output = check_output(cmd).decode('utf-8')
329 except:
330 pass
331 results[log.replace('target_logs/','')][xrez]=grep_output
332
333 return results
334
335 # Get the output of dmesg and write it in a file.
336 # This file is added to log_locations.
337 def write_dmesg(self):
338 (status, dmesg) = self.target.run('dmesg > /tmp/dmesg_output.log')
339
340 @OETestID(1059)
341 @OETestDepends(['ssh.SSHTest.test_ssh'])
342 def test_parselogs(self):
343 self.write_dmesg()
344 log_list = self.get_local_log_list(self.log_locations)
345 result = self.parse_logs(self.errors, self.ignore_errors, log_list)
346 print(self.getHardwareInfo())
347 errcount = 0
348 for log in result:
349 self.msg += 'Log: ' + log + '\n'
350 self.msg += '-----------------------\n'
351 for error in result[log]:
352 errcount += 1
353 self.msg += 'Central error: ' + str(error) + '\n'
354 self.msg += '***********************\n'
355 self.msg += result[str(log)][str(error)] + '\n'
356 self.msg += '***********************\n'
357 self.msg += '%s errors found in logs.' % errcount
358 self.assertEqual(errcount, 0, msg=self.msg)
diff --git a/meta/lib/oeqa/runtime/cases/perl.py b/meta/lib/oeqa/runtime/cases/perl.py
new file mode 100644
index 0000000000..d0b7e8ed92
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/perl.py
@@ -0,0 +1,37 @@
1import os
2
3from oeqa.runtime.case import OERuntimeTestCase
4from oeqa.core.decorator.depends import OETestDepends
5from oeqa.core.decorator.oeid import OETestID
6from oeqa.runtime.decorator.package import OEHasPackage
7
8class PerlTest(OERuntimeTestCase):
9
10 @classmethod
11 def setUpClass(cls):
12 src = os.path.join(cls.tc.files_dir, 'test.pl')
13 dst = '/tmp/test.pl'
14 cls.tc.target.copyTo(src, dst)
15
16 @classmethod
17 def tearDownClass(cls):
18 dst = '/tmp/test.pl'
19 cls.tc.target.run('rm %s' % dst)
20
21 @OETestID(1141)
22 @OETestDepends(['ssh.SSHTest.test_ssh'])
23 @OEHasPackage(['perl'])
24 def test_perl_exists(self):
25 status, output = self.target.run('which perl')
26 msg = 'Perl binary not in PATH or not on target.'
27 self.assertEqual(status, 0, msg=msg)
28
29 @OETestID(208)
30 @OETestDepends(['perl.PerlTest.test_perl_exists'])
31 def test_perl_works(self):
32 status, output = self.target.run('perl /tmp/test.pl')
33 msg = 'Exit status was not 0. Output: %s' % output
34 self.assertEqual(status, 0, msg=msg)
35
36 msg = 'Incorrect output: %s' % output
37 self.assertEqual(output, "the value of a is 0.01", msg=msg)
diff --git a/meta/lib/oeqa/runtime/cases/ping.py b/meta/lib/oeqa/runtime/cases/ping.py
new file mode 100644
index 0000000000..02f580abee
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/ping.py
@@ -0,0 +1,24 @@
1from subprocess import Popen, PIPE
2
3from oeqa.runtime.case import OERuntimeTestCase
4from oeqa.core.decorator.oeid import OETestID
5from oeqa.core.decorator.oetimeout import OETimeout
6
7class PingTest(OERuntimeTestCase):
8
9 @OETimeout(30)
10 @OETestID(964)
11 def test_ping(self):
12 output = ''
13 count = 0
14 while count < 5:
15 cmd = 'ping -c 1 %s' % self.target.ip
16 proc = Popen(cmd, shell=True, stdout=PIPE)
17 output += proc.communicate()[0].decode('utf-8')
18 if proc.poll() == 0:
19 count += 1
20 else:
21 count = 0
22 msg = ('Expected 5 consecutive, got %d.\n'
23 'ping output is:\n%s' % (count,output))
24 self.assertEqual(count, 5, msg = msg)
diff --git a/meta/lib/oeqa/runtime/cases/python.py b/meta/lib/oeqa/runtime/cases/python.py
new file mode 100644
index 0000000000..bf3e179163
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/python.py
@@ -0,0 +1,43 @@
1import os
2
3from oeqa.runtime.case import OERuntimeTestCase
4from oeqa.core.decorator.depends import OETestDepends
5from oeqa.core.decorator.oeid import OETestID
6from oeqa.runtime.decorator.package import OEHasPackage
7
8class PythonTest(OERuntimeTestCase):
9
10 @classmethod
11 def setUpClass(cls):
12 src = os.path.join(cls.tc.files_dir, 'test.py')
13 dst = '/tmp/test.py'
14 cls.tc.target.copyTo(src, dst)
15
16 @classmethod
17 def tearDownClass(cls):
18 dst = '/tmp/test.py'
19 cls.tc.target.run('rm %s' % dst)
20
21 @OETestID(1145)
22 @OETestDepends(['ssh.SSHTest.test_ssh'])
23 @OEHasPackage(['python-core'])
24 def test_python_exists(self):
25 status, output = self.target.run('which python')
26 msg = 'Python binary not in PATH or not on target.'
27 self.assertEqual(status, 0, msg=msg)
28
29 @OETestID(965)
30 @OETestDepends(['python.PythonTest.test_python_exists'])
31 def test_python_stdout(self):
32 status, output = self.target.run('python /tmp/test.py')
33 msg = 'Exit status was not 0. Output: %s' % output
34 self.assertEqual(status, 0, msg=msg)
35
36 msg = 'Incorrect output: %s' % output
37 self.assertEqual(output, "the value of a is 0.01", msg=msg)
38
39 @OETestID(1146)
40 @OETestDepends(['python.PythonTest.test_python_stdout'])
41 def test_python_testfile(self):
42 status, output = self.target.run('ls /tmp/testfile.python')
43 self.assertEqual(status, 0, msg='Python test file generate failed.')
diff --git a/meta/lib/oeqa/runtime/cases/rpm.py b/meta/lib/oeqa/runtime/cases/rpm.py
new file mode 100644
index 0000000000..532fbf82eb
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/rpm.py
@@ -0,0 +1,141 @@
1import os
2import fnmatch
3
4from oeqa.runtime.case import OERuntimeTestCase
5from oeqa.core.decorator.depends import OETestDepends
6from oeqa.core.decorator.oeid import OETestID
7from oeqa.core.decorator.data import skipIfDataVar
8from oeqa.runtime.decorator.package import OEHasPackage
9from oeqa.core.utils.path import findFile
10
11class RpmBasicTest(OERuntimeTestCase):
12
13 @classmethod
14 def setUpClass(cls):
15 if cls.tc.td['PACKAGE_CLASSES'].split()[0] != 'package_rpm':
16 cls.skipTest('Tests require image to be build from rpm')
17
18 @OETestID(960)
19 @OETestDepends(['ssh.SSHTest.test_ssh'])
20 def test_rpm_help(self):
21 status, output = self.target.run('rpm --help')
22 msg = 'status and output: %s and %s' % (status, output)
23 self.assertEqual(status, 0, msg=msg)
24
25 @OETestID(191)
26 @OETestDepends(['rpm.RpmBasicTest.test_rpm_help'])
27 def test_rpm_query(self):
28 status, output = self.target.run('rpm -q rpm')
29 msg = 'status and output: %s and %s' % (status, output)
30 self.assertEqual(status, 0, msg=msg)
31
32class RpmInstallRemoveTest(OERuntimeTestCase):
33
34 @classmethod
35 def setUpClass(cls):
36 if cls.tc.td['PACKAGE_CLASSES'].split()[0] != 'package_rpm':
37 cls.skipTest('Tests require image to be build from rpm')
38
39 pkgarch = cls.td['TUNE_PKGARCH'].replace('-', '_')
40 rpmdir = os.path.join(cls.tc.td['DEPLOY_DIR'], 'rpm', pkgarch)
41 # Pick rpm-doc as a test file to get installed, because it's small
42 # and it will always be built for standard targets
43 rpm_doc = 'rpm-doc-*.%s.rpm' % pkgarch
44 for f in fnmatch.filter(os.listdir(rpmdir), rpm_doc):
45 test_file = os.path.join(rpmdir, f)
46 dst = '/tmp/rpm-doc.rpm'
47 cls.tc.target.copyTo(test_file, dst)
48
49 @classmethod
50 def tearDownClass(cls):
51 dst = '/tmp/rpm-doc.rpm'
52 cls.tc.target.run('rm -f %s' % dst)
53
54 @OETestID(192)
55 @OETestDepends(['rpm.RpmBasicTest.test_rpm_help'])
56 def test_rpm_install(self):
57 status, output = self.target.run('rpm -ivh /tmp/rpm-doc.rpm')
58 msg = 'Failed to install rpm-doc package: %s' % output
59 self.assertEqual(status, 0, msg=msg)
60
61 @OETestID(194)
62 @OETestDepends(['rpm.RpmInstallRemoveTest.test_rpm_install'])
63 def test_rpm_remove(self):
64 status,output = self.target.run('rpm -e rpm-doc')
65 msg = 'Failed to remove rpm-doc package: %s' % output
66 self.assertEqual(status, 0, msg=msg)
67
68 @OETestID(1096)
69 @OETestDepends(['rpm.RpmBasicTest.test_rpm_query'])
70 def test_rpm_query_nonroot(self):
71
72 def set_up_test_user(u):
73 status, output = self.target.run('id -u %s' % u)
74 if status:
75 status, output = self.target.run('useradd %s' % u)
76 msg = 'Failed to create new user: %s' % output
77 self.assertTrue(status == 0, msg=msg)
78
79 def exec_as_test_user(u):
80 status, output = self.target.run('su -c id %s' % u)
81 msg = 'Failed to execute as new user'
82 self.assertTrue("({0})".format(u) in output, msg=msg)
83
84 status, output = self.target.run('su -c "rpm -qa" %s ' % u)
85 msg = 'status: %s. Cannot run rpm -qa: %s' % (status, output)
86 self.assertEqual(status, 0, msg=msg)
87
88 def unset_up_test_user(u):
89 status, output = self.target.run('userdel -r %s' % u)
90 msg = 'Failed to erase user: %s' % output
91 self.assertTrue(status == 0, msg=msg)
92
93 tuser = 'test1'
94
95 try:
96 set_up_test_user(tuser)
97 exec_as_test_user(tuser)
98 finally:
99 unset_up_test_user(tuser)
100
101 @OETestID(195)
102 @OETestDepends(['rpm.RpmInstallRemoveTest.test_rpm_remove'])
103 def test_check_rpm_install_removal_log_file_size(self):
104 """
105 Summary: Check rpm install/removal log file size
106 Expected: There should be some method to keep rpm log in a small size .
107 Product: BSPs
108 Author: Alexandru Georgescu <alexandru.c.georgescu@intel.com>
109 AutomatedBy: Daniel Istrate <daniel.alexandrux.istrate@intel.com>
110 """
111 db_files_cmd = 'ls /var/lib/rpm/__db.*'
112 get_log_size_cmd = "du /var/lib/rpm/log/log.* | awk '{print $1}'"
113
114 # Make sure that some database files are under /var/lib/rpm as '__db.xxx'
115 status, output = self.target.run(db_files_cmd)
116 msg = 'Failed to find database files under /var/lib/rpm/ as __db.xxx'
117 self.assertEqual(0, status, msg=msg)
118
119 # Remove the package just in case
120 self.target.run('rpm -e rpm-doc')
121
122 # Install/Remove a package 10 times
123 for i in range(10):
124 status, output = self.target.run('rpm -ivh /tmp/rpm-doc.rpm')
125 msg = 'Failed to install rpm-doc package. Reason: {}'.format(output)
126 self.assertEqual(0, status, msg=msg)
127
128 status, output = self.target.run('rpm -e rpm-doc')
129 msg = 'Failed to remove rpm-doc package. Reason: {}'.format(output)
130 self.assertEqual(0, status, msg=msg)
131
132 # Get the size of log file
133 status, output = self.target.run(get_log_size_cmd)
134 msg = 'Failed to get the final size of the log file.'
135 self.assertEqual(0, status, msg=msg)
136
137 # Compare each log size
138 for log_file_size in output:
139 msg = ('Log file size is greater that expected (~10MB), '
140 'found {} bytes'.format(log_file_size))
141 self.assertLessEqual(int(log_file_size), 11264, msg=msg)
diff --git a/meta/lib/oeqa/runtime/cases/scanelf.py b/meta/lib/oeqa/runtime/cases/scanelf.py
new file mode 100644
index 0000000000..3ba1f78af9
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/scanelf.py
@@ -0,0 +1,26 @@
1from oeqa.runtime.case import OERuntimeTestCase
2from oeqa.core.decorator.depends import OETestDepends
3from oeqa.core.decorator.oeid import OETestID
4from oeqa.runtime.decorator.package import OEHasPackage
5
6class ScanelfTest(OERuntimeTestCase):
7 scancmd = 'scanelf --quiet --recursive --mount --ldpath --path'
8
9 @OETestID(966)
10 @OETestDepends(['ssh.SSHTest.test_ssh'])
11 @OEHasPackage(['pax-utils'])
12 def test_scanelf_textrel(self):
13 # print TEXTREL information
14 cmd = '%s --textrel' % self.scancmd
15 status, output = self.target.run(cmd)
16 msg = '\n'.join([cmd, output])
17 self.assertEqual(output.strip(), '', msg=msg)
18
19 @OETestID(967)
20 @OETestDepends(['scanelf.ScanelfTest.test_scanelf_textrel'])
21 def test_scanelf_rpath(self):
22 # print RPATH information
23 cmd = '%s --textrel --rpath' % self.scancmd
24 status, output = self.target.run(cmd)
25 msg = '\n'.join([cmd, output])
26 self.assertEqual(output.strip(), '', msg=msg)
diff --git a/meta/lib/oeqa/runtime/cases/scp.py b/meta/lib/oeqa/runtime/cases/scp.py
new file mode 100644
index 0000000000..f488a6175b
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/scp.py
@@ -0,0 +1,33 @@
1import os
2from tempfile import mkstemp
3
4from oeqa.runtime.case import OERuntimeTestCase
5from oeqa.core.decorator.depends import OETestDepends
6from oeqa.core.decorator.oeid import OETestID
7
8class ScpTest(OERuntimeTestCase):
9
10 @classmethod
11 def setUpClass(cls):
12 cls.tmp_fd, cls.tmp_path = mkstemp()
13 with os.fdopen(cls.tmp_fd, 'w') as f:
14 f.seek(2 ** 22 -1)
15 f.write(os.linesep)
16
17 @classmethod
18 def tearDownClass(cls):
19 os.remove(cls.tmp_path)
20
21 @OETestID(220)
22 @OETestDepends(['ssh.SSHTest.test_ssh'])
23 def test_scp_file(self):
24 dst = '/tmp/test_scp_file'
25
26 (status, output) = self.target.copyTo(self.tmp_path, dst)
27 msg = 'File could not be copied. Output: %s' % output
28 self.assertEqual(status, 0, msg=msg)
29
30 (status, output) = self.target.run('ls -la %s' % dst)
31 self.assertEqual(status, 0, msg = 'SCP test failed')
32
33 self.target.run('rm %s' % dst)
diff --git a/meta/lib/oeqa/runtime/cases/skeletoninit.py b/meta/lib/oeqa/runtime/cases/skeletoninit.py
new file mode 100644
index 0000000000..4fdcf033a3
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/skeletoninit.py
@@ -0,0 +1,33 @@
1# This test should cover https://bugzilla.yoctoproject.org/tr_show_case.cgi?case_id=284
2# testcase. Image under test must have meta-skeleton layer in bblayers and
3# IMAGE_INSTALL_append = " service" in local.conf
4from oeqa.runtime.case import OERuntimeTestCase
5from oeqa.core.decorator.depends import OETestDepends
6from oeqa.core.decorator.oeid import OETestID
7from oeqa.core.decorator.data import skipIfDataVar
8from oeqa.runtime.decorator.package import OEHasPackage
9
10class SkeletonBasicTest(OERuntimeTestCase):
11
12 @OETestDepends(['ssh.SSHTest.test_ssh'])
13 @OEHasPackage(['service'])
14 @skipIfDataVar('VIRTUAL-RUNTIME_init_manager', 'systemd',
15 'Not appropiate for systemd image')
16 def test_skeleton_availability(self):
17 status, output = self.target.run('ls /etc/init.d/skeleton')
18 msg = 'skeleton init script not found. Output:\n%s' % output
19 self.assertEqual(status, 0, msg=msg)
20
21 status, output = self.target.run('ls /usr/sbin/skeleton-test')
22 msg = 'skeleton-test not found. Output:\n%s' % output
23 self.assertEqual(status, 0, msg=msg)
24
25 @OETestID(284)
26 @OETestDepends(['skeletoninit.SkeletonBasicTest.test_skeleton_availability'])
27 def test_skeleton_script(self):
28 output1 = self.target.run("/etc/init.d/skeleton start")[1]
29 cmd = '%s | grep [s]keleton-test' % self.tc.target_cmds['ps']
30 status, output2 = self.target.run(cmd)
31 msg = ('Skeleton script could not be started:'
32 '\n%s\n%s' % (output1, output2))
33 self.assertEqual(status, 0, msg=msg)
diff --git a/meta/lib/oeqa/runtime/cases/smart.py b/meta/lib/oeqa/runtime/cases/smart.py
new file mode 100644
index 0000000000..dde1c4d792
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/smart.py
@@ -0,0 +1,218 @@
1import unittest
2import re
3import oe
4import subprocess
5from oeqa.oetest import oeRuntimeTest, skipModule
6from oeqa.utils.decorators import *
7from oeqa.utils.httpserver import HTTPService
8
9def setUpModule():
10 if not oeRuntimeTest.hasFeature("package-management"):
11 skipModule("Image doesn't have package management feature")
12 if not oeRuntimeTest.hasPackage("smartpm"):
13 skipModule("Image doesn't have smart installed")
14 if "package_rpm" != oeRuntimeTest.tc.d.getVar("PACKAGE_CLASSES").split()[0]:
15 skipModule("Rpm is not the primary package manager")
16
17class SmartTest(oeRuntimeTest):
18
19 @skipUnlessPassed('test_smart_help')
20 def smart(self, command, expected = 0):
21 command = 'smart %s' % command
22 status, output = self.target.run(command, 1500)
23 message = os.linesep.join([command, output])
24 self.assertEqual(status, expected, message)
25 self.assertFalse("Cannot allocate memory" in output, message)
26 return output
27
28class SmartBasicTest(SmartTest):
29
30 @testcase(716)
31 @skipUnlessPassed('test_ssh')
32 def test_smart_help(self):
33 self.smart('--help')
34
35 @testcase(968)
36 def test_smart_version(self):
37 self.smart('--version')
38
39 @testcase(721)
40 def test_smart_info(self):
41 self.smart('info python-smartpm')
42
43 @testcase(421)
44 def test_smart_query(self):
45 self.smart('query python-smartpm')
46
47 @testcase(720)
48 def test_smart_search(self):
49 self.smart('search python-smartpm')
50
51 @testcase(722)
52 def test_smart_stats(self):
53 self.smart('stats')
54
55class SmartRepoTest(SmartTest):
56
57 @classmethod
58 def create_index(self, arg):
59 index_cmd = arg
60 try:
61 bb.note("Executing '%s' ..." % index_cmd)
62 result = subprocess.check_output(index_cmd, stderr=subprocess.STDOUT, shell=True).decode("utf-8")
63 except subprocess.CalledProcessError as e:
64 return("Index creation command '%s' failed with return code %d:\n%s" %
65 (e.cmd, e.returncode, e.output.decode("utf-8")))
66 if result:
67 bb.note(result)
68 return None
69
70 @classmethod
71 def setUpClass(self):
72 self.repolist = []
73
74 # Index RPMs
75 rpm_createrepo = bb.utils.which(os.getenv('PATH'), "createrepo")
76 index_cmds = []
77 rpm_dirs_found = False
78 archs = (oeRuntimeTest.tc.d.getVar('ALL_MULTILIB_PACKAGE_ARCHS') or "").replace('-', '_').split()
79 for arch in archs:
80 rpm_dir = os.path.join(oeRuntimeTest.tc.d.getVar('DEPLOY_DIR_RPM'), arch)
81 idx_path = os.path.join(oeRuntimeTest.tc.d.getVar('WORKDIR'), 'rpm', arch)
82 db_path = os.path.join(oeRuntimeTest.tc.d.getVar('WORKDIR'), 'rpmdb', arch)
83 if not os.path.isdir(rpm_dir):
84 continue
85 if os.path.exists(db_path):
86 bb.utils.remove(dbpath, True)
87 lockfilename = oeRuntimeTest.tc.d.getVar('DEPLOY_DIR_RPM') + "/rpm.lock"
88 lf = bb.utils.lockfile(lockfilename, False)
89 oe.path.copyhardlinktree(rpm_dir, idx_path)
90 # Full indexes overload a 256MB image so reduce the number of rpms
91 # in the feed. Filter to p* since we use the psplash packages and
92 # this leaves some allarch and machine arch packages too.
93 bb.utils.remove(idx_path + "*/[a-oq-z]*.rpm")
94 bb.utils.unlockfile(lf)
95 index_cmds.append("%s --dbpath %s --update -q %s" % (rpm_createrepo, db_path, idx_path))
96 rpm_dirs_found = True
97 # Create repodata¬
98 result = oe.utils.multiprocess_exec(index_cmds, self.create_index)
99 if result:
100 bb.fatal('%s' % ('\n'.join(result)))
101 self.repo_server = HTTPService(oeRuntimeTest.tc.d.getVar('WORKDIR'), oeRuntimeTest.tc.target.server_ip)
102 self.repo_server.start()
103
104 @classmethod
105 def tearDownClass(self):
106 self.repo_server.stop()
107 for i in self.repolist:
108 oeRuntimeTest.tc.target.run('smart channel -y --remove '+str(i))
109
110 @testcase(1143)
111 def test_smart_channel(self):
112 self.smart('channel', 1)
113
114 @testcase(719)
115 def test_smart_channel_add(self):
116 image_pkgtype = self.tc.d.getVar('IMAGE_PKGTYPE')
117 deploy_url = 'http://%s:%s/%s' %(self.target.server_ip, self.repo_server.port, image_pkgtype)
118 pkgarchs = self.tc.d.getVar('PACKAGE_ARCHS').replace("-","_").split()
119 for arch in os.listdir('%s/%s' % (self.repo_server.root_dir, image_pkgtype)):
120 if arch in pkgarchs:
121 self.smart('channel -y --add {a} type=rpm-md baseurl={u}/{a}'.format(a=arch, u=deploy_url))
122 self.repolist.append(arch)
123 self.smart('update')
124
125 @testcase(969)
126 def test_smart_channel_help(self):
127 self.smart('channel --help')
128
129 @testcase(970)
130 def test_smart_channel_list(self):
131 self.smart('channel --list')
132
133 @testcase(971)
134 def test_smart_channel_show(self):
135 self.smart('channel --show')
136
137 @testcase(717)
138 def test_smart_channel_rpmsys(self):
139 self.smart('channel --show rpmsys')
140 self.smart('channel --disable rpmsys')
141 self.smart('channel --enable rpmsys')
142
143 @testcase(1144)
144 @skipUnlessPassed('test_smart_channel_add')
145 def test_smart_install(self):
146 self.smart('remove -y psplash-default')
147 self.smart('install -y psplash-default')
148
149 @testcase(728)
150 @skipUnlessPassed('test_smart_install')
151 def test_smart_install_dependency(self):
152 self.smart('remove -y psplash')
153 self.smart('install -y psplash-default')
154
155 @testcase(723)
156 @skipUnlessPassed('test_smart_channel_add')
157 def test_smart_install_from_disk(self):
158 self.smart('remove -y psplash-default')
159 self.smart('download psplash-default')
160 self.smart('install -y ./psplash-default*')
161
162 @testcase(725)
163 @skipUnlessPassed('test_smart_channel_add')
164 def test_smart_install_from_http(self):
165 output = self.smart('download --urls psplash-default')
166 url = re.search('(http://.*/psplash-default.*\.rpm)', output)
167 self.assertTrue(url, msg="Couln't find download url in %s" % output)
168 self.smart('remove -y psplash-default')
169 self.smart('install -y %s' % url.group(0))
170
171 @testcase(729)
172 @skipUnlessPassed('test_smart_install')
173 def test_smart_reinstall(self):
174 self.smart('reinstall -y psplash-default')
175
176 @testcase(727)
177 @skipUnlessPassed('test_smart_channel_add')
178 def test_smart_remote_repo(self):
179 self.smart('update')
180 self.smart('install -y psplash')
181 self.smart('remove -y psplash')
182
183 @testcase(726)
184 def test_smart_local_dir(self):
185 self.target.run('mkdir /tmp/myrpmdir')
186 self.smart('channel --add myrpmdir type=rpm-dir path=/tmp/myrpmdir -y')
187 self.target.run('cd /tmp/myrpmdir')
188 self.smart('download psplash')
189 output = self.smart('channel --list')
190 for i in output.split("\n"):
191 if ("rpmsys" != str(i)) and ("myrpmdir" != str(i)):
192 self.smart('channel --disable '+str(i))
193 self.target.run('cd $HOME')
194 self.smart('install psplash')
195 for i in output.split("\n"):
196 if ("rpmsys" != str(i)) and ("myrpmdir" != str(i)):
197 self.smart('channel --enable '+str(i))
198 self.smart('channel --remove myrpmdir -y')
199 self.target.run("rm -rf /tmp/myrpmdir")
200
201 @testcase(718)
202 def test_smart_add_rpmdir(self):
203 self.target.run('mkdir /tmp/myrpmdir')
204 self.smart('channel --add myrpmdir type=rpm-dir path=/tmp/myrpmdir -y')
205 self.smart('channel --disable myrpmdir -y')
206 output = self.smart('channel --show myrpmdir')
207 self.assertTrue("disabled = yes" in output, msg="Failed to disable rpm dir")
208 self.smart('channel --enable myrpmdir -y')
209 output = self.smart('channel --show myrpmdir')
210 self.assertFalse("disabled = yes" in output, msg="Failed to enable rpm dir")
211 self.smart('channel --remove myrpmdir -y')
212 self.target.run("rm -rf /tmp/myrpmdir")
213
214 @testcase(731)
215 @skipUnlessPassed('test_smart_channel_add')
216 def test_smart_remove_package(self):
217 self.smart('install -y psplash')
218 self.smart('remove -y psplash')
diff --git a/meta/lib/oeqa/runtime/cases/ssh.py b/meta/lib/oeqa/runtime/cases/ssh.py
new file mode 100644
index 0000000000..eca167969a
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/ssh.py
@@ -0,0 +1,15 @@
1from oeqa.runtime.case import OERuntimeTestCase
2from oeqa.core.decorator.depends import OETestDepends
3from oeqa.core.decorator.oeid import OETestID
4
5class SSHTest(OERuntimeTestCase):
6
7 @OETestID(224)
8 @OETestDepends(['ping.PingTest.test_ping'])
9 def test_ssh(self):
10 (status, output) = self.target.run('uname -a')
11 self.assertEqual(status, 0, msg='SSH Test failed: %s' % output)
12 (status, output) = self.target.run('cat /etc/masterimage')
13 msg = "This isn't the right image - /etc/masterimage " \
14 "shouldn't be here %s" % output
15 self.assertEqual(status, 1, msg=msg)
diff --git a/meta/lib/oeqa/runtime/cases/syslog.py b/meta/lib/oeqa/runtime/cases/syslog.py
new file mode 100644
index 0000000000..1016e67e93
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/syslog.py
@@ -0,0 +1,57 @@
1from oeqa.runtime.case import OERuntimeTestCase
2from oeqa.core.decorator.depends import OETestDepends
3from oeqa.core.decorator.oeid import OETestID
4from oeqa.core.decorator.data import skipIfDataVar
5from oeqa.runtime.decorator.package import OEHasPackage
6
7class SyslogTest(OERuntimeTestCase):
8
9 @OETestID(201)
10 @OETestDepends(['ssh.SSHTest.test_ssh'])
11 @OEHasPackage(["busybox-syslog", "sysklogd"])
12 def test_syslog_running(self):
13 cmd = '%s | grep -i [s]yslogd' % self.tc.target_cmds['ps']
14 status, output = self.target.run(cmd)
15 msg = "No syslogd process; ps output: %s" % output
16 self.assertEqual(status, 0, msg=msg)
17
18class SyslogTestConfig(OERuntimeTestCase):
19
20 @OETestID(1149)
21 @OETestDepends(['syslog.SyslogTest.test_syslog_running'])
22 def test_syslog_logger(self):
23 status, output = self.target.run('logger foobar')
24 msg = "Can't log into syslog. Output: %s " % output
25 self.assertEqual(status, 0, msg=msg)
26
27 status, output = self.target.run('grep foobar /var/log/messages')
28 if status != 0:
29 if self.tc.td.get("VIRTUAL-RUNTIME_init_manager") == "systemd":
30 status, output = self.target.run('journalctl -o cat | grep foobar')
31 else:
32 status, output = self.target.run('logread | grep foobar')
33 msg = ('Test log string not found in /var/log/messages or logread.'
34 ' Output: %s ' % output)
35 self.assertEqual(status, 0, msg=msg)
36
37 @OETestID(202)
38 @OETestDepends(['syslog.SyslogTestConfig.test_syslog_logger'])
39 @OEHasPackage(["!sysklogd", "busybox"])
40 @skipIfDataVar('VIRTUAL-RUNTIME_init_manager', 'systemd',
41 'Not appropiate for systemd image')
42 def test_syslog_startup_config(self):
43 cmd = 'echo "LOGFILE=/var/log/test" >> /etc/syslog-startup.conf'
44 self.target.run(cmd)
45 status, output = self.target.run('/etc/init.d/syslog restart')
46 msg = ('Could not restart syslog service. Status and output:'
47 ' %s and %s' % (status,output))
48 self.assertEqual(status, 0, msg)
49
50 cmd = 'logger foobar && grep foobar /var/log/test'
51 status,output = self.target.run(cmd)
52 msg = 'Test log string not found. Output: %s ' % output
53 self.assertEqual(status, 0, msg=msg)
54
55 cmd = "sed -i 's#LOGFILE=/var/log/test##' /etc/syslog-startup.conf"
56 self.target.run(cmd)
57 self.target.run('/etc/init.d/syslog restart')
diff --git a/meta/lib/oeqa/runtime/cases/systemd.py b/meta/lib/oeqa/runtime/cases/systemd.py
new file mode 100644
index 0000000000..db69384c8a
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/systemd.py
@@ -0,0 +1,181 @@
1import re
2import time
3
4from oeqa.runtime.case import OERuntimeTestCase
5from oeqa.core.decorator.depends import OETestDepends
6from oeqa.core.decorator.oeid import OETestID
7from oeqa.core.decorator.data import skipIfDataVar, skipIfNotDataVar
8from oeqa.runtime.decorator.package import OEHasPackage
9from oeqa.core.decorator.data import skipIfNotFeature
10
11class SystemdTest(OERuntimeTestCase):
12
13 def systemctl(self, action='', target='', expected=0, verbose=False):
14 command = 'systemctl %s %s' % (action, target)
15 status, output = self.target.run(command)
16 message = '\n'.join([command, output])
17 if status != expected and verbose:
18 cmd = 'systemctl status --full %s' % target
19 message += self.target.run(cmd)[1]
20 self.assertEqual(status, expected, message)
21 return output
22
23 #TODO: use pyjournalctl instead
24 def journalctl(self, args='',l_match_units=None):
25 """
26 Request for the journalctl output to the current target system
27
28 Arguments:
29 -args, an optional argument pass through argument
30 -l_match_units, an optional list of units to filter the output
31 Returns:
32 -string output of the journalctl command
33 Raises:
34 -AssertionError, on remote commands that fail
35 -ValueError, on a journalctl call with filtering by l_match_units that
36 returned no entries
37 """
38
39 query_units=''
40 if l_match_units:
41 query_units = ['_SYSTEMD_UNIT='+unit for unit in l_match_units]
42 query_units = ' '.join(query_units)
43 command = 'journalctl %s %s' %(args, query_units)
44 status, output = self.target.run(command)
45 if status:
46 raise AssertionError("Command '%s' returned non-zero exit "
47 'code %d:\n%s' % (command, status, output))
48 if len(output) == 1 and "-- No entries --" in output:
49 raise ValueError('List of units to match: %s, returned no entries'
50 % l_match_units)
51 return output
52
53class SystemdBasicTests(SystemdTest):
54
55 def settle(self):
56 """
57 Block until systemd has finished activating any units being activated,
58 or until two minutes has elapsed.
59
60 Returns a tuple, either (True, '') if all units have finished
61 activating, or (False, message string) if there are still units
62 activating (generally, failing units that restart).
63 """
64 endtime = time.time() + (60 * 2)
65 while True:
66 status, output = self.target.run('systemctl --state=activating')
67 if "0 loaded units listed" in output:
68 return (True, '')
69 if time.time() >= endtime:
70 return (False, output)
71 time.sleep(10)
72
73 @skipIfNotFeature('systemd',
74 'Test requires systemd to be in DISTRO_FEATURES')
75 @skipIfNotDataVar('VIRTUAL-RUNTIME_init_manager', 'systemd',
76 'systemd is not the init manager for this image')
77 @OETestDepends(['ssh.SSHTest.test_ssh'])
78 def test_systemd_basic(self):
79 self.systemctl('--version')
80
81 @OETestID(551)
82 @OETestDepends(['systemd.SystemdBasicTests.test_systemd_basic'])
83 def test_systemd_list(self):
84 self.systemctl('list-unit-files')
85
86 @OETestID(550)
87 @OETestDepends(['systemd.SystemdBasicTests.test_systemd_basic'])
88 def test_systemd_failed(self):
89 settled, output = self.settle()
90 msg = "Timed out waiting for systemd to settle:\n%s" % output
91 self.assertTrue(settled, msg=msg)
92
93 output = self.systemctl('list-units', '--failed')
94 match = re.search('0 loaded units listed', output)
95 if not match:
96 output += self.systemctl('status --full --failed')
97 self.assertTrue(match, msg='Some systemd units failed:\n%s' % output)
98
99
100class SystemdServiceTests(SystemdTest):
101
102 @OEHasPackage(['avahi-daemon'])
103 @OETestDepends(['systemd.SystemdBasicTests.test_systemd_basic'])
104 def test_systemd_status(self):
105 self.systemctl('status --full', 'avahi-daemon.service')
106
107 @OETestID(695)
108 @OETestDepends(['systemd.SystemdServiceTests.test_systemd_status'])
109 def test_systemd_stop_start(self):
110 self.systemctl('stop', 'avahi-daemon.service')
111 self.systemctl('is-active', 'avahi-daemon.service',
112 expected=3, verbose=True)
113 self.systemctl('start','avahi-daemon.service')
114 self.systemctl('is-active', 'avahi-daemon.service', verbose=True)
115
116 @OETestID(696)
117 @OETestDepends(['systemd.SystemdServiceTests.test_systemd_status'])
118 def test_systemd_disable_enable(self):
119 self.systemctl('disable', 'avahi-daemon.service')
120 self.systemctl('is-enabled', 'avahi-daemon.service', expected=1)
121 self.systemctl('enable', 'avahi-daemon.service')
122 self.systemctl('is-enabled', 'avahi-daemon.service')
123
124class SystemdJournalTests(SystemdTest):
125
126 @OETestDepends(['systemd.SystemdBasicTests.test_systemd_basic'])
127 def test_systemd_journal(self):
128 status, output = self.target.run('journalctl')
129 self.assertEqual(status, 0, output)
130
131 @OETestDepends(['systemd.SystemdBasicTests.test_systemd_basic'])
132 def test_systemd_boot_time(self, systemd_TimeoutStartSec=90):
133 """
134 Get the target boot time from journalctl and log it
135
136 Arguments:
137 -systemd_TimeoutStartSec, an optional argument containing systemd's
138 unit start timeout to compare against
139 """
140
141 # The expression chain that uniquely identifies the time boot message.
142 expr_items=['Startup finished', 'kernel', 'userspace','\.$']
143 try:
144 output = self.journalctl(args='-o cat --reverse')
145 except AssertionError:
146 self.fail('Error occurred while calling journalctl')
147 if not len(output):
148 self.fail('Error, unable to get startup time from systemd journal')
149
150 # Check for the regular expression items that match the startup time.
151 for line in output.split('\n'):
152 check_match = ''.join(re.findall('.*'.join(expr_items), line))
153 if check_match:
154 break
155 # Put the startup time in the test log
156 if check_match:
157 self.tc.logger.info('%s' % check_match)
158 else:
159 self.skipTest('Error at obtaining the boot time from journalctl')
160 boot_time_sec = 0
161
162 # Get the numeric values from the string and convert them to seconds
163 # same data will be placed in list and string for manipulation.
164 l_boot_time = check_match.split(' ')[-2:]
165 s_boot_time = ' '.join(l_boot_time)
166 try:
167 # Obtain the minutes it took to boot.
168 if l_boot_time[0].endswith('min') and l_boot_time[0][0].isdigit():
169 boot_time_min = s_boot_time.split('min')[0]
170 # Convert to seconds and accumulate it.
171 boot_time_sec += int(boot_time_min) * 60
172 # Obtain the seconds it took to boot and accumulate.
173 boot_time_sec += float(l_boot_time[1].split('s')[0])
174 except ValueError:
175 self.skipTest('Error when parsing time from boot string')
176
177 # Assert the target boot time against systemd's unit start timeout.
178 if boot_time_sec > systemd_TimeoutStartSec:
179 msg = ("Target boot time %s exceeds systemd's TimeoutStartSec %s"
180 % (boot_time_sec, systemd_TimeoutStartSec))
181 self.tc.logger.info(msg)
diff --git a/meta/lib/oeqa/runtime/cases/x32lib.py b/meta/lib/oeqa/runtime/cases/x32lib.py
new file mode 100644
index 0000000000..8da0154e7b
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/x32lib.py
@@ -0,0 +1,19 @@
1from oeqa.runtime.case import OERuntimeTestCase
2from oeqa.core.decorator.depends import OETestDepends
3from oeqa.core.decorator.oeid import OETestID
4from oeqa.core.decorator.data import skipIfNotInDataVar
5
6class X32libTest(OERuntimeTestCase):
7
8 @skipIfNotInDataVar('DEFAULTTUNE', 'x86-64-x32',
9 'DEFAULTTUNE is not set to x86-64-x32')
10 @OETestID(281)
11 @OETestDepends(['ssh.SSHTest.test_ssh'])
12 def test_x32_file(self):
13 cmd = 'readelf -h /bin/ls | grep Class | grep ELF32'
14 status1 = self.target.run(cmd)[0]
15 cmd = 'readelf -h /bin/ls | grep Machine | grep X86-64'
16 status2 = self.target.run(cmd)[0]
17 msg = ("/bin/ls isn't an X86-64 ELF32 binary. readelf says: %s" %
18 self.target.run("readelf -h /bin/ls")[1])
19 self.assertTrue(status1 == 0 and status2 == 0, msg=msg)
diff --git a/meta/lib/oeqa/runtime/cases/xorg.py b/meta/lib/oeqa/runtime/cases/xorg.py
new file mode 100644
index 0000000000..2124813e3c
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/xorg.py
@@ -0,0 +1,17 @@
1from oeqa.runtime.case import OERuntimeTestCase
2from oeqa.core.decorator.depends import OETestDepends
3from oeqa.core.decorator.oeid import OETestID
4from oeqa.core.decorator.data import skipIfNotFeature
5
6class XorgTest(OERuntimeTestCase):
7
8 @OETestID(1151)
9 @skipIfNotFeature('x11-base',
10 'Test requires x11 to be in IMAGE_FEATURES')
11 @OETestDepends(['ssh.SSHTest.test_ssh'])
12 def test_xorg_running(self):
13 cmd ='%s | grep -v xinit | grep [X]org' % self.tc.target_cmds['ps']
14 status, output = self.target.run(cmd)
15 msg = ('Xorg does not appear to be running %s' %
16 self.target.run(self.tc.target_cmds['ps'])[1])
17 self.assertEqual(status, 0, msg=msg)