summaryrefslogtreecommitdiffstats
path: root/meta/lib/oeqa
diff options
context:
space:
mode:
Diffstat (limited to 'meta/lib/oeqa')
-rw-r--r--meta/lib/oeqa/__init__.py0
-rw-r--r--meta/lib/oeqa/oetest.py120
-rw-r--r--meta/lib/oeqa/runtime/__init__.py3
-rw-r--r--meta/lib/oeqa/runtime/buildcvs.py32
-rw-r--r--meta/lib/oeqa/runtime/buildiptables.py32
-rw-r--r--meta/lib/oeqa/runtime/buildsudoku.py29
-rw-r--r--meta/lib/oeqa/runtime/connman.py29
-rw-r--r--meta/lib/oeqa/runtime/date.py22
-rw-r--r--meta/lib/oeqa/runtime/df.py11
-rw-r--r--meta/lib/oeqa/runtime/dmesg.py11
-rw-r--r--meta/lib/oeqa/runtime/files/test.c26
-rw-r--r--meta/lib/oeqa/runtime/files/test.pl2
-rw-r--r--meta/lib/oeqa/runtime/files/testmakefile5
-rw-r--r--meta/lib/oeqa/runtime/gcc.py36
-rw-r--r--meta/lib/oeqa/runtime/ldd.py19
-rw-r--r--meta/lib/oeqa/runtime/logrotate.py27
-rw-r--r--meta/lib/oeqa/runtime/multilib.py17
-rw-r--r--meta/lib/oeqa/runtime/pam.py24
-rw-r--r--meta/lib/oeqa/runtime/perl.py28
-rw-r--r--meta/lib/oeqa/runtime/ping.py20
-rw-r--r--meta/lib/oeqa/runtime/rpm.py49
-rw-r--r--meta/lib/oeqa/runtime/scanelf.py26
-rw-r--r--meta/lib/oeqa/runtime/scp.py21
-rw-r--r--meta/lib/oeqa/runtime/skeletoninit.py28
-rw-r--r--meta/lib/oeqa/runtime/smart.py108
-rw-r--r--meta/lib/oeqa/runtime/ssh.py16
-rw-r--r--meta/lib/oeqa/runtime/syslog.py46
-rw-r--r--meta/lib/oeqa/runtime/systemd.py59
-rw-r--r--meta/lib/oeqa/runtime/vnc.py19
-rw-r--r--meta/lib/oeqa/runtime/x32lib.py17
-rw-r--r--meta/lib/oeqa/runtime/xorg.py21
-rw-r--r--meta/lib/oeqa/utils/__init__.py0
-rw-r--r--meta/lib/oeqa/utils/decorators.py50
-rw-r--r--meta/lib/oeqa/utils/httpserver.py33
-rw-r--r--meta/lib/oeqa/utils/qemurunner.py228
-rw-r--r--meta/lib/oeqa/utils/sshcontrol.py109
-rw-r--r--meta/lib/oeqa/utils/targetbuild.py63
37 files changed, 1386 insertions, 0 deletions
diff --git a/meta/lib/oeqa/__init__.py b/meta/lib/oeqa/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/meta/lib/oeqa/__init__.py
diff --git a/meta/lib/oeqa/oetest.py b/meta/lib/oeqa/oetest.py
new file mode 100644
index 0000000000..529abdc19a
--- /dev/null
+++ b/meta/lib/oeqa/oetest.py
@@ -0,0 +1,120 @@
1# Copyright (C) 2013 Intel Corporation
2#
3# Released under the MIT license (see COPYING.MIT)
4
5# Main unittest module used by testimage.bbclass
6# This provides the oeRuntimeTest base class which is inherited by all tests in meta/lib/oeqa/runtime.
7
8# It also has some helper functions and it's responsible for actually starting the tests
9
10import os, re, mmap
11import unittest
12import inspect
13import bb
14from oeqa.utils.sshcontrol import SSHControl
15
16
17def runTests(tc):
18
19 # set the context object passed from the test class
20 setattr(oeRuntimeTest, "tc", tc)
21 # set ps command to use
22 setattr(oeRuntimeTest, "pscmd", "ps -ef" if oeRuntimeTest.hasPackage("procps") else "ps")
23 # prepare test suite, loader and runner
24 suite = unittest.TestSuite()
25 testloader = unittest.TestLoader()
26 testloader.sortTestMethodsUsing = None
27 runner = unittest.TextTestRunner(verbosity=2)
28
29 bb.note("Test modules %s" % tc.testslist)
30 suite = testloader.loadTestsFromNames(tc.testslist)
31 bb.note("Found %s tests" % suite.countTestCases())
32
33 result = runner.run(suite)
34
35 return result
36
37
38
39class oeRuntimeTest(unittest.TestCase):
40
41 longMessage = True
42 testFailures = []
43 testSkipped = []
44 testErrors = []
45
46 def __init__(self, methodName='runTest'):
47 self.target = oeRuntimeTest.tc.target
48 super(oeRuntimeTest, self).__init__(methodName)
49
50
51 def run(self, result=None):
52 super(oeRuntimeTest, self).run(result)
53
54 # we add to our own lists the results, we use those for decorators
55 if len(result.failures) > len(oeRuntimeTest.testFailures):
56 oeRuntimeTest.testFailures.append(str(result.failures[-1][0]).split()[0])
57 if len(result.skipped) > len(oeRuntimeTest.testSkipped):
58 oeRuntimeTest.testSkipped.append(str(result.skipped[-1][0]).split()[0])
59 if len(result.errors) > len(oeRuntimeTest.testErrors):
60 oeRuntimeTest.testErrors.append(str(result.errors[-1][0]).split()[0])
61
62 @classmethod
63 def hasPackage(self, pkg):
64
65 pkgfile = os.path.join(oeRuntimeTest.tc.d.getVar("WORKDIR", True), "installed_pkgs.txt")
66
67 with open(pkgfile) as f:
68 data = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
69 match = re.search(pkg, data)
70 data.close()
71
72 if match:
73 return True
74
75 return False
76
77 @classmethod
78 def hasFeature(self,feature):
79
80 if feature in oeRuntimeTest.tc.d.getVar("IMAGE_FEATURES", True).split() or \
81 feature in oeRuntimeTest.tc.d.getVar("DISTRO_FEATURES", True).split():
82 return True
83 else:
84 return False
85
86 @classmethod
87 def restartTarget(self,params=None):
88
89 if oeRuntimeTest.tc.qemu.restart(params):
90 oeRuntimeTest.tc.target.host = oeRuntimeTest.tc.qemu.ip
91 else:
92 raise Exception("Restarting target failed")
93
94
95def getmodule(pos=2):
96 # stack returns a list of tuples containg frame information
97 # First element of the list the is current frame, caller is 1
98 frameinfo = inspect.stack()[pos]
99 modname = inspect.getmodulename(frameinfo[1])
100 #modname = inspect.getmodule(frameinfo[0]).__name__
101 return modname
102
103def skipModule(reason, pos=2):
104 modname = getmodule(pos)
105 if modname not in oeRuntimeTest.tc.testsrequired:
106 raise unittest.SkipTest("%s: %s" % (modname, reason))
107 else:
108 raise Exception("\nTest %s wants to be skipped.\nReason is: %s" \
109 "\nTest was required in TEST_SUITES, so either the condition for skipping is wrong" \
110 "\nor the image really doesn't have the requred feature/package when it should." % (modname, reason))
111
112def skipModuleIf(cond, reason):
113
114 if cond:
115 skipModule(reason, 3)
116
117def skipModuleUnless(cond, reason):
118
119 if not cond:
120 skipModule(reason, 3)
diff --git a/meta/lib/oeqa/runtime/__init__.py b/meta/lib/oeqa/runtime/__init__.py
new file mode 100644
index 0000000000..4cf3fa76b6
--- /dev/null
+++ b/meta/lib/oeqa/runtime/__init__.py
@@ -0,0 +1,3 @@
1# Enable other layers to have tests in the same named directory
2from pkgutil import extend_path
3__path__ = extend_path(__path__, __name__)
diff --git a/meta/lib/oeqa/runtime/buildcvs.py b/meta/lib/oeqa/runtime/buildcvs.py
new file mode 100644
index 0000000000..f024dfa99a
--- /dev/null
+++ b/meta/lib/oeqa/runtime/buildcvs.py
@@ -0,0 +1,32 @@
1from oeqa.oetest import oeRuntimeTest
2from oeqa.utils.decorators import *
3from oeqa.utils.targetbuild import TargetBuildProject
4
5def setUpModule():
6 if not oeRuntimeTest.hasFeature("tools-sdk"):
7 skipModule("Image doesn't have tools-sdk in IMAGE_FEATURES")
8
9class BuildCvsTest(oeRuntimeTest):
10
11 @classmethod
12 def setUpClass(self):
13 self.restartTarget("-m 512")
14 self.project = TargetBuildProject(oeRuntimeTest.tc.target,
15 "http://ftp.gnu.org/non-gnu/cvs/source/feature/1.12.13/cvs-1.12.13.tar.bz2")
16 self.project.download_archive()
17
18 @skipUnlessPassed("test_ssh")
19 def test_cvs(self):
20 self.assertEqual(self.project.run_configure(), 0,
21 msg="Running configure failed")
22
23 self.assertEqual(self.project.run_make(), 0,
24 msg="Running make failed")
25
26 self.assertEqual(self.project.run_install(), 0,
27 msg="Running make install failed")
28
29 @classmethod
30 def tearDownClass(self):
31 self.project.clean()
32 self.restartTarget()
diff --git a/meta/lib/oeqa/runtime/buildiptables.py b/meta/lib/oeqa/runtime/buildiptables.py
new file mode 100644
index 0000000000..88ece3bd8a
--- /dev/null
+++ b/meta/lib/oeqa/runtime/buildiptables.py
@@ -0,0 +1,32 @@
1from oeqa.oetest import oeRuntimeTest
2from oeqa.utils.decorators import *
3from oeqa.utils.targetbuild import TargetBuildProject
4
5def setUpModule():
6 if not oeRuntimeTest.hasFeature("tools-sdk"):
7 skipModule("Image doesn't have tools-sdk in IMAGE_FEATURES")
8
9class BuildIptablesTest(oeRuntimeTest):
10
11 @classmethod
12 def setUpClass(self):
13 self.restartTarget("-m 512")
14 self.project = TargetBuildProject(oeRuntimeTest.tc.target,
15 "http://netfilter.org/projects/iptables/files/iptables-1.4.13.tar.bz2")
16 self.project.download_archive()
17
18 @skipUnlessPassed("test_ssh")
19 def test_iptables(self):
20 self.assertEqual(self.project.run_configure(), 0,
21 msg="Running configure failed")
22
23 self.assertEqual(self.project.run_make(), 0,
24 msg="Running make failed")
25
26 self.assertEqual(self.project.run_install(), 0,
27 msg="Running make install failed")
28
29 @classmethod
30 def tearDownClass(self):
31 self.project.clean()
32 self.restartTarget()
diff --git a/meta/lib/oeqa/runtime/buildsudoku.py b/meta/lib/oeqa/runtime/buildsudoku.py
new file mode 100644
index 0000000000..0a7306ddc7
--- /dev/null
+++ b/meta/lib/oeqa/runtime/buildsudoku.py
@@ -0,0 +1,29 @@
1from oeqa.oetest import oeRuntimeTest
2from oeqa.utils.decorators import *
3from oeqa.utils.targetbuild import TargetBuildProject
4
5def setUpModule():
6 if not oeRuntimeTest.hasFeature("tools-sdk"):
7 skipModule("Image doesn't have tools-sdk in IMAGE_FEATURES")
8
9class SudokuTest(oeRuntimeTest):
10
11 @classmethod
12 def setUpClass(self):
13 self.restartTarget("-m 512")
14 self.project = TargetBuildProject(oeRuntimeTest.tc.target,
15 "http://downloads.sourceforge.net/project/sudoku-savant/sudoku-savant/sudoku-savant-1.3/sudoku-savant-1.3.tar.bz2")
16 self.project.download_archive()
17
18 @skipUnlessPassed("test_ssh")
19 def test_sudoku(self):
20 self.assertEqual(self.project.run_configure(), 0,
21 msg="Running configure failed")
22
23 self.assertEqual(self.project.run_make(), 0,
24 msg="Running make failed")
25
26 @classmethod
27 def tearDownClass(self):
28 self.project.clean()
29 self.restartTarget()
diff --git a/meta/lib/oeqa/runtime/connman.py b/meta/lib/oeqa/runtime/connman.py
new file mode 100644
index 0000000000..5ef96f6b06
--- /dev/null
+++ b/meta/lib/oeqa/runtime/connman.py
@@ -0,0 +1,29 @@
1import unittest
2from oeqa.oetest import oeRuntimeTest, skipModule
3from oeqa.utils.decorators import *
4
5def setUpModule():
6 if not oeRuntimeTest.hasPackage("connman"):
7 skipModule("No connman package in image")
8
9
10class ConnmanTest(oeRuntimeTest):
11
12 @skipUnlessPassed('test_ssh')
13 def test_connmand_help(self):
14 (status, output) = self.target.run('/usr/sbin/connmand --help')
15 self.assertEqual(status, 0, msg="status and output: %s and %s" % (status,output))
16
17
18 @skipUnlessPassed('test_connmand_help')
19 def test_connmand_running(self):
20 (status, output) = self.target.run(oeRuntimeTest.pscmd + ' | grep [c]onnmand')
21 self.assertEqual(status, 0, msg="no connmand process, ps output: %s" % self.target.run(oeRuntimeTest.pscmd)[1])
22
23 @skipUnlessPassed('test_connmand_running')
24 def test_connmand_unique(self):
25 self.target.run('/usr/sbin/connmand')
26 output = self.target.run(oeRuntimeTest.pscmd + ' | grep -c [c]onnmand')[1]
27 self.assertEqual(output, "1", msg="more than one connmand running in background, ps output: %s\n%s" % (output, self.target.run(oeRuntimeTest.pscmd)[1]))
28
29
diff --git a/meta/lib/oeqa/runtime/date.py b/meta/lib/oeqa/runtime/date.py
new file mode 100644
index 0000000000..a208e29ada
--- /dev/null
+++ b/meta/lib/oeqa/runtime/date.py
@@ -0,0 +1,22 @@
1from oeqa.oetest import oeRuntimeTest
2from oeqa.utils.decorators import *
3import re
4
5class DateTest(oeRuntimeTest):
6
7 @skipUnlessPassed("test_ssh")
8 def test_date(self):
9 (status, output) = self.target.run('date +"%Y-%m-%d %T"')
10 self.assertEqual(status, 0, msg="Failed to get initial date, output: %s" % output)
11 oldDate = output
12
13 sampleDate = '"2016-08-09 10:00:00"'
14 (status, output) = self.target.run("date -s %s" % sampleDate)
15 self.assertEqual(status, 0, msg="Date set failed, output: %s" % output)
16
17 (status, output) = self.target.run("date -R")
18 p = re.match('Tue, 09 Aug 2016 10:00:.. \+0000', output)
19 self.assertTrue(p, msg="The date was not set correctly, output: %s" % output)
20
21 (status, output) = self.target.run('date -s "%s"' % oldDate)
22 self.assertEqual(status, 0, msg="Failed to reset date, output: %s" % output)
diff --git a/meta/lib/oeqa/runtime/df.py b/meta/lib/oeqa/runtime/df.py
new file mode 100644
index 0000000000..b6da35027c
--- /dev/null
+++ b/meta/lib/oeqa/runtime/df.py
@@ -0,0 +1,11 @@
1import unittest
2from oeqa.oetest import oeRuntimeTest
3from oeqa.utils.decorators import *
4
5
6class DfTest(oeRuntimeTest):
7
8 @skipUnlessPassed("test_ssh")
9 def test_df(self):
10 (status,output) = self.target.run("df / | sed -n '2p' | awk '{print $4}'")
11 self.assertTrue(int(output)>5120, msg="Not enough space on image. Current size is %s" % output)
diff --git a/meta/lib/oeqa/runtime/dmesg.py b/meta/lib/oeqa/runtime/dmesg.py
new file mode 100644
index 0000000000..a53d1f0bf3
--- /dev/null
+++ b/meta/lib/oeqa/runtime/dmesg.py
@@ -0,0 +1,11 @@
1import unittest
2from oeqa.oetest import oeRuntimeTest
3from oeqa.utils.decorators import *
4
5
6class DmesgTest(oeRuntimeTest):
7
8 @skipUnlessPassed('test_ssh')
9 def test_dmesg(self):
10 (status, output) = self.target.run('dmesg | grep -v mmci-pl18x | grep -v "error changing net interface name" | grep -i error')
11 self.assertEqual(status, 1, msg = "Error messages in dmesg log: %s" % output)
diff --git a/meta/lib/oeqa/runtime/files/test.c b/meta/lib/oeqa/runtime/files/test.c
new file mode 100644
index 0000000000..2d8389c92e
--- /dev/null
+++ b/meta/lib/oeqa/runtime/files/test.c
@@ -0,0 +1,26 @@
1#include <stdio.h>
2#include <math.h>
3#include <stdlib.h>
4
5double convert(long long l)
6{
7 return (double)l;
8}
9
10int main(int argc, char * argv[]) {
11
12 long long l = 10;
13 double f;
14 double check = 10.0;
15
16 f = convert(l);
17 printf("convert: %lld => %f\n", l, f);
18 if ( f != check ) exit(1);
19
20 f = 1234.67;
21 check = 1234.0;
22 printf("floorf(%f) = %f\n", f, floorf(f));
23 if ( floorf(f) != check) exit(1);
24
25 return 0;
26}
diff --git a/meta/lib/oeqa/runtime/files/test.pl b/meta/lib/oeqa/runtime/files/test.pl
new file mode 100644
index 0000000000..689c8f1635
--- /dev/null
+++ b/meta/lib/oeqa/runtime/files/test.pl
@@ -0,0 +1,2 @@
1$a = 9.01e+21 - 9.01e+21 + 0.01;
2print ("the value of a is ", $a, "\n");
diff --git a/meta/lib/oeqa/runtime/files/testmakefile b/meta/lib/oeqa/runtime/files/testmakefile
new file mode 100644
index 0000000000..ca1844e930
--- /dev/null
+++ b/meta/lib/oeqa/runtime/files/testmakefile
@@ -0,0 +1,5 @@
1test: test.o
2 gcc -o test test.o -lm
3test.o: test.c
4 gcc -c test.c
5
diff --git a/meta/lib/oeqa/runtime/gcc.py b/meta/lib/oeqa/runtime/gcc.py
new file mode 100644
index 0000000000..b63badd3e4
--- /dev/null
+++ b/meta/lib/oeqa/runtime/gcc.py
@@ -0,0 +1,36 @@
1import unittest
2import os
3from oeqa.oetest import oeRuntimeTest, skipModule
4from oeqa.utils.decorators import *
5
6def setUpModule():
7 if not oeRuntimeTest.hasFeature("tools-sdk"):
8 skipModule("Image doesn't have tools-sdk in IMAGE_FEATURES")
9
10
11class GccCompileTest(oeRuntimeTest):
12
13 @classmethod
14 def setUpClass(self):
15 oeRuntimeTest.tc.target.copy_to(os.path.join(oeRuntimeTest.tc.filesdir, "test.c"), "/tmp/test.c")
16 oeRuntimeTest.tc.target.copy_to(os.path.join(oeRuntimeTest.tc.filesdir, "testmakefile"), "/tmp/testmakefile")
17
18 def test_gcc_compile(self):
19 (status, output) = self.target.run('gcc /tmp/test.c -o /tmp/test -lm')
20 self.assertEqual(status, 0, msg="gcc compile failed, output: %s" % output)
21 (status, output) = self.target.run('/tmp/test')
22 self.assertEqual(status, 0, msg="running compiled file failed, output %s" % output)
23
24 def test_gpp_compile(self):
25 (status, output) = self.target.run('g++ /tmp/test.c -o /tmp/test -lm')
26 self.assertEqual(status, 0, msg="g++ compile failed, output: %s" % output)
27 (status, output) = self.target.run('/tmp/test')
28 self.assertEqual(status, 0, msg="running compiled file failed, output %s" % output)
29
30 def test_make(self):
31 (status, output) = self.target.run('cd /tmp; make -f testmakefile')
32 self.assertEqual(status, 0, msg="running make failed, output %s" % output)
33
34 @classmethod
35 def tearDownClass(self):
36 oeRuntimeTest.tc.target.run("rm /tmp/test.c /tmp/test.o /tmp/test /tmp/testmakefile")
diff --git a/meta/lib/oeqa/runtime/ldd.py b/meta/lib/oeqa/runtime/ldd.py
new file mode 100644
index 0000000000..4374530fc4
--- /dev/null
+++ b/meta/lib/oeqa/runtime/ldd.py
@@ -0,0 +1,19 @@
1import unittest
2from oeqa.oetest import oeRuntimeTest
3from oeqa.utils.decorators import *
4
5def setUpModule():
6 if not oeRuntimeTest.hasFeature("tools-sdk"):
7 skipModule("Image doesn't have tools-sdk in IMAGE_FEATURES")
8
9class LddTest(oeRuntimeTest):
10
11 @skipUnlessPassed('test_ssh')
12 def test_ldd_exists(self):
13 (status, output) = self.target.run('which ldd')
14 self.assertEqual(status, 0, msg = "ldd does not exist in PATH: which ldd: %s" % output)
15
16 @skipUnlessPassed('test_ldd_exists')
17 def test_ldd_rtldlist_check(self):
18 (status, output) = self.target.run('for i in $(which ldd | xargs cat | grep "^RTLDLIST"|cut -d\'=\' -f2|tr -d \'"\'); do test -f $i && echo $i && break; done')
19 self.assertEqual(status, 0, msg = "ldd path not correct or RTLDLIST files don't exist. ")
diff --git a/meta/lib/oeqa/runtime/logrotate.py b/meta/lib/oeqa/runtime/logrotate.py
new file mode 100644
index 0000000000..80489a3267
--- /dev/null
+++ b/meta/lib/oeqa/runtime/logrotate.py
@@ -0,0 +1,27 @@
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
4import unittest
5from oeqa.oetest import oeRuntimeTest, skipModule
6from oeqa.utils.decorators import *
7
8def setUpModule():
9 if not oeRuntimeTest.hasPackage("logrotate"):
10 skipModule("No logrotate package in image")
11
12
13class LogrotateTest(oeRuntimeTest):
14
15 @skipUnlessPassed("test_ssh")
16 def test_1_logrotate_setup(self):
17 (status, output) = self.target.run('mkdir /home/root/logrotate_dir')
18 self.assertEqual(status, 0, msg = "Could not create logrotate_dir. Output: %s" % output)
19 (status, output) = self.target.run("sed -i 's#wtmp {#wtmp {\\n olddir /home/root/logrotate_dir#' /etc/logrotate.conf")
20 self.assertEqual(status, 0, msg = "Could not write to logrotate.conf file. Status and output: %s and %s)" % (status, output))
21
22 @skipUnlessPassed("test_1_logrotate_setup")
23 def test_2_logrotate(self):
24 (status, output) = self.target.run('logrotate -f /etc/logrotate.conf')
25 self.assertEqual(status, 0, msg = "logrotate service could not be reloaded. Status and output: %s and %s" % (status, output))
26 output = self.target.run('ls -la /home/root/logrotate_dir/ | wc -l')[1]
27 self.assertTrue(int(output)>=3, msg = "new logfile could not be created. List of files within log directory: %s" %(self.target.run('ls -la /home/root/logrotate_dir')[1]))
diff --git a/meta/lib/oeqa/runtime/multilib.py b/meta/lib/oeqa/runtime/multilib.py
new file mode 100644
index 0000000000..13a3b54b18
--- /dev/null
+++ b/meta/lib/oeqa/runtime/multilib.py
@@ -0,0 +1,17 @@
1import unittest
2from oeqa.oetest import oeRuntimeTest, skipModule
3from oeqa.utils.decorators import *
4
5def setUpModule():
6 multilibs = oeRuntimeTest.tc.d.getVar("MULTILIBS", True) or ""
7 if "multilib:lib32" not in multilibs:
8 skipModule("this isn't a multilib:lib32 image")
9
10
11class MultilibTest(oeRuntimeTest):
12
13 @skipUnlessPassed('test_ssh')
14 def test_file_connman(self):
15 self.assertTrue(oeRuntimeTest.hasPackage('connman-gnome'), msg="This test assumes connman-gnome is installed")
16 (status, output) = self.target.run("readelf -h /usr/bin/connman-applet | sed -n '3p' | awk '{print $2}'")
17 self.assertEqual(output, "ELF32", msg="connman-applet isn't an ELF32 binary. readelf says: %s" % self.target.run("readelf -h /usr/bin/connman-applet")[1])
diff --git a/meta/lib/oeqa/runtime/pam.py b/meta/lib/oeqa/runtime/pam.py
new file mode 100644
index 0000000000..52e1eb88e6
--- /dev/null
+++ b/meta/lib/oeqa/runtime/pam.py
@@ -0,0 +1,24 @@
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
4import unittest
5from oeqa.oetest import oeRuntimeTest
6from oeqa.utils.decorators import *
7
8def setUpModule():
9 if not oeRuntimeTest.hasFeature("pam"):
10 skipModule("target doesn't have 'pam' in DISTRO_FEATURES")
11
12
13class PamBasicTest(oeRuntimeTest):
14
15 @skipUnlessPassed('test_ssh')
16 def test_pam(self):
17 (status, output) = self.target.run('login --help')
18 self.assertEqual(status, 1, msg = "login command does not work as expected. Status and output:%s and %s" %(status, output))
19 (status, output) = self.target.run('passwd --help')
20 self.assertEqual(status, 6, msg = "passwd command does not work as expected. Status and output:%s and %s" %(status, output))
21 (status, output) = self.target.run('su --help')
22 self.assertEqual(status, 2, msg = "su command does not work as expected. Status and output:%s and %s" %(status, output))
23 (status, output) = self.target.run('useradd --help')
24 self.assertEqual(status, 2, msg = "useradd command does not work as expected. Status and output:%s and %s" %(status, output))
diff --git a/meta/lib/oeqa/runtime/perl.py b/meta/lib/oeqa/runtime/perl.py
new file mode 100644
index 0000000000..c9bb684c11
--- /dev/null
+++ b/meta/lib/oeqa/runtime/perl.py
@@ -0,0 +1,28 @@
1import unittest
2import os
3from oeqa.oetest import oeRuntimeTest, skipModule
4from oeqa.utils.decorators import *
5
6def setUpModule():
7 if not oeRuntimeTest.hasPackage("perl"):
8 skipModule("No perl package in the image")
9
10
11class PerlTest(oeRuntimeTest):
12
13 @classmethod
14 def setUpClass(self):
15 oeRuntimeTest.tc.target.copy_to(os.path.join(oeRuntimeTest.tc.filesdir, "test.pl"), "/tmp/test.pl")
16
17 def test_perl_exists(self):
18 (status, output) = self.target.run('which perl')
19 self.assertEqual(status, 0, msg="Perl binary not in PATH or not on target.")
20
21 def test_perl_works(self):
22 (status, output) = self.target.run('perl /tmp/test.pl')
23 self.assertEqual(status, 0, msg="Exit status was not 0. Output: %s" % output)
24 self.assertEqual(output, "the value of a is 0.01", msg="Incorrect output: %s" % output)
25
26 @classmethod
27 def tearDownClass(self):
28 oeRuntimeTest.tc.target.run("rm /tmp/test.pl")
diff --git a/meta/lib/oeqa/runtime/ping.py b/meta/lib/oeqa/runtime/ping.py
new file mode 100644
index 0000000000..0d028f9b22
--- /dev/null
+++ b/meta/lib/oeqa/runtime/ping.py
@@ -0,0 +1,20 @@
1import subprocess
2import unittest
3import sys
4import time
5from oeqa.oetest import oeRuntimeTest
6
7class PingTest(oeRuntimeTest):
8
9 def test_ping(self):
10 output = ''
11 count = 0
12 endtime = time.time() + 60
13 while count < 5 and time.time() < endtime:
14 proc = subprocess.Popen("ping -c 1 %s" % oeRuntimeTest.tc.qemu.ip, shell=True, stdout=subprocess.PIPE)
15 output += proc.communicate()[0]
16 if proc.poll() == 0:
17 count += 1
18 else:
19 count = 0
20 self.assertEqual(count, 5, msg = "Expected 5 consecutive replies, got %d.\nping output is:\n%s" % (count,output))
diff --git a/meta/lib/oeqa/runtime/rpm.py b/meta/lib/oeqa/runtime/rpm.py
new file mode 100644
index 0000000000..154cad5014
--- /dev/null
+++ b/meta/lib/oeqa/runtime/rpm.py
@@ -0,0 +1,49 @@
1import unittest
2import os
3from oeqa.oetest import oeRuntimeTest, skipModule
4from oeqa.utils.decorators import *
5import oe.packagedata
6
7def setUpModule():
8 if not oeRuntimeTest.hasFeature("package-management"):
9 skipModule("rpm module skipped: target doesn't have package-management in IMAGE_FEATURES")
10 if "package_rpm" != oeRuntimeTest.tc.d.getVar("PACKAGE_CLASSES", True).split()[0]:
11 skipModule("rpm module skipped: target doesn't have rpm as primary package manager")
12
13
14class RpmBasicTest(oeRuntimeTest):
15
16 @skipUnlessPassed('test_ssh')
17 def test_rpm_help(self):
18 (status, output) = self.target.run('rpm --help')
19 self.assertEqual(status, 0, msg="status and output: %s and %s" % (status,output))
20
21 @skipUnlessPassed('test_rpm_help')
22 def test_rpm_query(self):
23 (status, output) = self.target.run('rpm -q rpm')
24 self.assertEqual(status, 0, msg="status and output: %s and %s" % (status,output))
25
26class RpmInstallRemoveTest(oeRuntimeTest):
27
28 @classmethod
29 def setUpClass(self):
30 deploydir = os.path.join(oeRuntimeTest.tc.d.getVar('DEPLOY_DIR', True), "rpm", oeRuntimeTest.tc.d.getVar('TUNE_PKGARCH', True))
31 pkgdata = oe.packagedata.read_subpkgdata("rpm-doc", oeRuntimeTest.tc.d)
32 # pick rpm-doc as a test file to get installed, because it's small and it will always be built for standard targets
33 testrpmfile = "rpm-doc-%s-%s.%s.rpm" % (pkgdata["PKGV"], pkgdata["PKGR"], oeRuntimeTest.tc.d.getVar('TUNE_PKGARCH', True))
34 oeRuntimeTest.tc.target.copy_to(os.path.join(deploydir,testrpmfile), "/tmp/rpm-doc.rpm")
35
36 @skipUnlessPassed('test_rpm_help')
37 def test_rpm_install(self):
38 (status, output) = self.target.run('rpm -ivh /tmp/rpm-doc.rpm')
39 self.assertEqual(status, 0, msg="Failed to install rpm-doc package: %s" % output)
40
41 @skipUnlessPassed('test_rpm_install')
42 def test_rpm_remove(self):
43 (status,output) = self.target.run('rpm -e rpm-doc')
44 self.assertEqual(status, 0, msg="Failed to remove rpm-doc package: %s" % output)
45
46 @classmethod
47 def tearDownClass(self):
48 oeRuntimeTest.tc.target.run('rm -f /tmp/rpm-doc.rpm')
49
diff --git a/meta/lib/oeqa/runtime/scanelf.py b/meta/lib/oeqa/runtime/scanelf.py
new file mode 100644
index 0000000000..b9abf24640
--- /dev/null
+++ b/meta/lib/oeqa/runtime/scanelf.py
@@ -0,0 +1,26 @@
1import unittest
2from oeqa.oetest import oeRuntimeTest, skipModule
3from oeqa.utils.decorators import *
4
5def setUpModule():
6 if not oeRuntimeTest.hasPackage("pax-utils"):
7 skipModule("pax-utils package not installed")
8
9class ScanelfTest(oeRuntimeTest):
10
11 def setUp(self):
12 self.scancmd = 'scanelf --quiet --recursive --mount --ldpath --path'
13
14 @skipUnlessPassed('test_ssh')
15 def test_scanelf_textrel(self):
16 # print TEXTREL information
17 self.scancmd += " --textrel"
18 (status, output) = self.target.run(self.scancmd)
19 self.assertEqual(output.strip(), "", "\n".join([self.scancmd, output]))
20
21 @skipUnlessPassed('test_ssh')
22 def test_scanelf_rpath(self):
23 # print RPATH information
24 self.scancmd += " --rpath"
25 (status, output) = self.target.run(self.scancmd)
26 self.assertEqual(output.strip(), "", "\n".join([self.scancmd, output]))
diff --git a/meta/lib/oeqa/runtime/scp.py b/meta/lib/oeqa/runtime/scp.py
new file mode 100644
index 0000000000..03095bf966
--- /dev/null
+++ b/meta/lib/oeqa/runtime/scp.py
@@ -0,0 +1,21 @@
1import os
2from oeqa.oetest import oeRuntimeTest, skipModule
3from oeqa.utils.decorators import skipUnlessPassed
4
5def setUpModule():
6 if not (oeRuntimeTest.hasPackage("dropbear") or oeRuntimeTest.hasPackage("openssh-sshd")):
7 skipModule("No ssh package in image")
8
9class ScpTest(oeRuntimeTest):
10
11 @skipUnlessPassed('test_ssh')
12 def test_scp_file(self):
13 test_log_dir = oeRuntimeTest.tc.d.getVar("TEST_LOG_DIR", True)
14 test_file_path = os.path.join(test_log_dir, 'test_scp_file')
15 with open(test_file_path, 'w') as test_scp_file:
16 test_scp_file.seek(2 ** 22 - 1)
17 test_scp_file.write(os.linesep)
18 (status, output) = self.target.copy_to(test_file_path, '/tmp/test_scp_file')
19 self.assertEqual(status, 0, msg = "File could not be copied. Output: %s" % output)
20 (status, output) = self.target.run("ls -la /tmp/test_scp_file")
21 self.assertEqual(status, 0, msg = "SCP test failed")
diff --git a/meta/lib/oeqa/runtime/skeletoninit.py b/meta/lib/oeqa/runtime/skeletoninit.py
new file mode 100644
index 0000000000..557e715a3e
--- /dev/null
+++ b/meta/lib/oeqa/runtime/skeletoninit.py
@@ -0,0 +1,28 @@
1# This test should cover https://bugzilla.yoctoproject.org/tr_show_case.cgi?case_id=284 testcase
2# Note that the image under test must have meta-skeleton layer in bblayers and IMAGE_INSTALL_append = " service" in local.conf
3
4import unittest
5from oeqa.oetest import oeRuntimeTest
6from oeqa.utils.decorators import *
7
8def setUpModule():
9 if not oeRuntimeTest.hasPackage("service"):
10 skipModule("No service package in image")
11
12
13class SkeletonBasicTest(oeRuntimeTest):
14
15 @skipUnlessPassed('test_ssh')
16 @unittest.skipIf("systemd" == oeRuntimeTest.tc.d.getVar("VIRTUAL-RUNTIME_init_manager"), "Not appropiate for systemd image")
17 def test_skeleton_availability(self):
18 (status, output) = self.target.run('ls /etc/init.d/skeleton')
19 self.assertEqual(status, 0, msg = "skeleton init script not found. Output:\n%s " % output)
20 (status, output) = self.target.run('ls /usr/sbin/skeleton-test')
21 self.assertEqual(status, 0, msg = "skeleton-test not found. Output:\n%s" % output)
22
23 @skipUnlessPassed('test_skeleton_availability')
24 @unittest.skipIf("systemd" == oeRuntimeTest.tc.d.getVar("VIRTUAL-RUNTIME_init_manager"), "Not appropiate for systemd image")
25 def test_skeleton_script(self):
26 output1 = self.target.run("/etc/init.d/skeleton start")[1]
27 (status, output2) = self.target.run(oeRuntimeTest.pscmd + ' | grep [s]keleton-test')
28 self.assertEqual(status, 0, msg = "Skeleton script could not be started:\n%s\n%s" % (output1, output2))
diff --git a/meta/lib/oeqa/runtime/smart.py b/meta/lib/oeqa/runtime/smart.py
new file mode 100644
index 0000000000..c3fdf7d499
--- /dev/null
+++ b/meta/lib/oeqa/runtime/smart.py
@@ -0,0 +1,108 @@
1import unittest
2import re
3from oeqa.oetest import oeRuntimeTest
4from oeqa.utils.decorators import *
5from oeqa.utils.httpserver import HTTPService
6
7def setUpModule():
8 if not oeRuntimeTest.hasFeature("package-management"):
9 skipModule("Image doesn't have package management feature")
10 if not oeRuntimeTest.hasPackage("smart"):
11 skipModule("Image doesn't have smart installed")
12
13class SmartTest(oeRuntimeTest):
14
15 @skipUnlessPassed('test_smart_help')
16 def smart(self, command, expected = 0):
17 command = 'smart %s' % command
18 status, output = self.target.run(command, 1500)
19 message = os.linesep.join([command, output])
20 self.assertEqual(status, expected, message)
21 self.assertFalse("Cannot allocate memory" in output, message)
22 return output
23
24class SmartBasicTest(SmartTest):
25
26 @skipUnlessPassed('test_ssh')
27 def test_smart_help(self):
28 self.smart('--help')
29
30 def test_smart_version(self):
31 self.smart('--version')
32
33 def test_smart_info(self):
34 self.smart('info python-smartpm')
35
36 def test_smart_query(self):
37 self.smart('query python-smartpm')
38
39 def test_smart_search(self):
40 self.smart('search python-smartpm')
41
42 def test_smart_stats(self):
43 self.smart('stats')
44
45class SmartRepoTest(SmartTest):
46
47 @classmethod
48 def setUpClass(self):
49 self.repo_server = HTTPService(oeRuntimeTest.tc.d.getVar('DEPLOY_DIR', True), oeRuntimeTest.tc.qemu.host_ip)
50 self.repo_server.start()
51
52 @classmethod
53 def tearDownClass(self):
54 self.repo_server.stop()
55
56 def test_smart_channel(self):
57 self.smart('channel', 1)
58
59 def test_smart_channel_add(self):
60 image_pkgtype = self.tc.d.getVar('IMAGE_PKGTYPE', True)
61 deploy_url = 'http://%s:%s/%s' %(self.tc.qemu.host_ip, self.repo_server.port, image_pkgtype)
62 pkgarchs = self.tc.d.getVar('PACKAGE_ARCHS', True)
63 for arch in os.listdir('%s/%s' % (self.repo_server.root_dir, image_pkgtype)):
64 if arch in pkgarchs:
65 self.smart('channel -y --add {a} type=rpm-md baseurl={u}/{a}'.format(a=arch, u=deploy_url))
66 self.smart('update')
67
68 def test_smart_channel_help(self):
69 self.smart('channel --help')
70
71 def test_smart_channel_list(self):
72 self.smart('channel --list')
73
74 def test_smart_channel_show(self):
75 self.smart('channel --show')
76
77 def test_smart_channel_rpmsys(self):
78 self.smart('channel --show rpmsys')
79 self.smart('channel --disable rpmsys')
80 self.smart('channel --enable rpmsys')
81
82 @skipUnlessPassed('test_smart_channel_add')
83 def test_smart_install(self):
84 self.smart('remove -y psplash-default')
85 self.smart('install -y psplash-default')
86
87 @skipUnlessPassed('test_smart_install')
88 def test_smart_install_dependency(self):
89 self.smart('remove -y psplash')
90 self.smart('install -y psplash-default')
91
92 @skipUnlessPassed('test_smart_channel_add')
93 def test_smart_install_from_disk(self):
94 self.smart('remove -y psplash-default')
95 self.smart('download psplash-default')
96 self.smart('install -y ./psplash-default*')
97
98 @skipUnlessPassed('test_smart_channel_add')
99 def test_smart_install_from_http(self):
100 output = self.smart('download --urls psplash-default')
101 url = re.search('(http://.*/psplash-default.*\.rpm)', output)
102 self.assertTrue(url, msg="Couln't find download url in %s" % output)
103 self.smart('remove -y psplash-default')
104 self.smart('install -y %s' % url.group(0))
105
106 @skipUnlessPassed('test_smart_install')
107 def test_smart_reinstall(self):
108 self.smart('reinstall -y psplash-default')
diff --git a/meta/lib/oeqa/runtime/ssh.py b/meta/lib/oeqa/runtime/ssh.py
new file mode 100644
index 0000000000..8c96020e54
--- /dev/null
+++ b/meta/lib/oeqa/runtime/ssh.py
@@ -0,0 +1,16 @@
1import subprocess
2import unittest
3import sys
4from oeqa.oetest import oeRuntimeTest, skipModule
5from oeqa.utils.decorators import *
6
7def setUpModule():
8 if not (oeRuntimeTest.hasPackage("dropbear") or oeRuntimeTest.hasPackage("openssh")):
9 skipModule("No ssh package in image")
10
11class SshTest(oeRuntimeTest):
12
13 @skipUnlessPassed('test_ping')
14 def test_ssh(self):
15 (status, output) = self.target.run('uname -a')
16 self.assertEqual(status, 0, msg="SSH Test failed: %s" % output)
diff --git a/meta/lib/oeqa/runtime/syslog.py b/meta/lib/oeqa/runtime/syslog.py
new file mode 100644
index 0000000000..91d79635b7
--- /dev/null
+++ b/meta/lib/oeqa/runtime/syslog.py
@@ -0,0 +1,46 @@
1import unittest
2from oeqa.oetest import oeRuntimeTest, skipModule
3from oeqa.utils.decorators import *
4
5def setUpModule():
6 if not oeRuntimeTest.hasPackage("syslog"):
7 skipModule("No syslog package in image")
8
9class SyslogTest(oeRuntimeTest):
10
11 @skipUnlessPassed("test_ssh")
12 def test_syslog_help(self):
13 (status,output) = self.target.run('/sbin/syslogd --help')
14 self.assertEqual(status, 1, msg="status and output: %s and %s" % (status,output))
15
16 @skipUnlessPassed("test_syslog_help")
17 def test_syslog_running(self):
18 (status,output) = self.target.run(oeRuntimeTest.pscmd + ' | grep -i [s]yslogd')
19 self.assertEqual(status, 0, msg="no syslogd process, ps output: %s" % self.target.run(oeRuntimeTest.pscmd)[1])
20
21
22class SyslogTestConfig(oeRuntimeTest):
23
24 @skipUnlessPassed("test_syslog_running")
25 def test_syslog_logger(self):
26 (status,output) = self.target.run('logger foobar && test -e /var/log/messages && grep foobar /var/log/messages || logread | grep foobar')
27 self.assertEqual(status, 0, msg="Test log string not found in /var/log/messages. Output: %s " % output)
28
29 @skipUnlessPassed("test_syslog_running")
30 def test_syslog_restart(self):
31 if "systemd" != oeRuntimeTest.tc.d.getVar("VIRTUAL-RUNTIME_init_manager"):
32 (status,output) = self.target.run('/etc/init.d/syslog restart')
33 else:
34 (status,output) = self.target.run('systemctl restart syslog.service')
35
36 @skipUnlessPassed("test_syslog_restart")
37 @skipUnlessPassed("test_syslog_logger")
38 @unittest.skipIf("systemd" == oeRuntimeTest.tc.d.getVar("VIRTUAL-RUNTIME_init_manager"), "Not appropiate for systemd image")
39 def test_syslog_startup_config(self):
40 self.target.run('echo "LOGFILE=/var/log/test" >> /etc/syslog-startup.conf')
41 (status,output) = self.target.run('/etc/init.d/syslog restart')
42 self.assertEqual(status, 0, msg="Could not restart syslog service. Status and output: %s and %s" % (status,output))
43 (status,output) = self.target.run('logger foobar && grep foobar /var/log/test')
44 self.assertEqual(status, 0, msg="Test log string not found. Output: %s " % output)
45 self.target.run("sed -i 's#LOGFILE=/var/log/test##' /etc/syslog-startup.conf")
46 self.target.run('/etc/init.d/syslog restart')
diff --git a/meta/lib/oeqa/runtime/systemd.py b/meta/lib/oeqa/runtime/systemd.py
new file mode 100644
index 0000000000..e4f433632f
--- /dev/null
+++ b/meta/lib/oeqa/runtime/systemd.py
@@ -0,0 +1,59 @@
1import unittest
2from oeqa.oetest import oeRuntimeTest, skipModule
3from oeqa.utils.decorators import *
4
5def setUpModule():
6 if not oeRuntimeTest.hasFeature("systemd"):
7 skipModule("target doesn't have systemd in DISTRO_FEATURES")
8 if "systemd" != oeRuntimeTest.tc.d.getVar("VIRTUAL-RUNTIME_init_manager", True):
9 skipModule("systemd is not the init manager for this image")
10
11
12class SystemdBasicTest(oeRuntimeTest):
13
14 @skipUnlessPassed('test_ssh')
15 def test_systemd_version(self):
16 (status, output) = self.target.run('systemctl --version')
17 self.assertEqual(status, 0, msg="status and output: %s and %s" % (status,output))
18
19class SystemdTests(oeRuntimeTest):
20
21 @skipUnlessPassed('test_systemd_version')
22 def test_systemd_failed(self):
23 (status, output) = self.target.run('systemctl --failed | grep "0 loaded units listed"')
24 self.assertEqual(status, 0, msg="Failed systemd services: %s" % self.target.run('systemctl --failed')[1])
25
26 @skipUnlessPassed('test_systemd_version')
27 def test_systemd_service(self):
28 (status, output) = self.target.run('systemctl list-unit-files | grep "systemd-hostnamed.service"')
29 self.assertEqual(status, 0, msg="systemd-hostnamed.service service is not available.")
30
31 @skipUnlessPassed('test_systemd_service')
32 def test_systemd_stop(self):
33 self.target.run('systemctl stop systemd-hostnamed.service')
34 (status, output) = self.target.run('systemctl show systemd-hostnamed.service | grep "ActiveState" | grep "=inactive"')
35 self.assertEqual(status, 0, msg="systemd-hostnamed.service service could not be stopped.Status and output: %s and %s" % (status, output))
36
37 @skipUnlessPassed('test_systemd_stop')
38 @skipUnlessPassed('test_systemd_version')
39 def test_systemd_start(self):
40 self.target.run('systemctl start systemd-hostnamed.service')
41 (status, output) = self.target.run('systemctl show systemd-hostnamed.service | grep "ActiveState" | grep "=active"')
42 self.assertEqual(status, 0, msg="systemd-hostnamed.service service could not be started. Status and output: %s and %s" % (status, output))
43
44 @skipUnlessPassed('test_systemd_version')
45 def test_systemd_enable(self):
46 self.target.run('systemctl enable machineid.service')
47 (status, output) = self.target.run('systemctl is-enabled machineid.service')
48 self.assertEqual(output, 'enabled', msg="machineid.service service could not be enabled. Status and output: %s and %s" % (status, output))
49
50 @skipUnlessPassed('test_systemd_enable')
51 def test_systemd_disable(self):
52 self.target.run('systemctl disable machineid.service')
53 (status, output) = self.target.run('systemctl is-enabled machineid.service')
54 self.assertEqual(output, 'disabled', msg="machineid.service service could not be disabled. Status and output: %s and %s" % (status, output))
55
56 @skipUnlessPassed('test_systemd_version')
57 def test_systemd_list(self):
58 (status, output) = self.target.run('systemctl list-unit-files')
59 self.assertEqual(status, 0, msg="systemctl list-unit-files command failed. Status: %s" % status)
diff --git a/meta/lib/oeqa/runtime/vnc.py b/meta/lib/oeqa/runtime/vnc.py
new file mode 100644
index 0000000000..5ed10727bc
--- /dev/null
+++ b/meta/lib/oeqa/runtime/vnc.py
@@ -0,0 +1,19 @@
1from oeqa.oetest import oeRuntimeTest
2from oeqa.utils.decorators import *
3import re
4
5def setUpModule():
6 skipModuleUnless(oeRuntimeTest.hasPackage('x11vnc'), "No x11vnc package in image")
7
8class VNCTest(oeRuntimeTest):
9
10 @skipUnlessPassed('test_ssh')
11 def test_vnc(self):
12 (status, output) = self.target.run('x11vnc -display :0 -bg -o x11vnc.log')
13 self.assertEqual(status, 0, msg="x11vnc server failed to start: %s" % output)
14 port = re.search('PORT=[0-9]*', output)
15 self.assertTrue(port, msg="Listening port not specified in command output: %s" %output)
16
17 vncport = port.group(0).split('=')[1]
18 (status, output) = self.target.run('netstat -ntl | grep ":%s"' % vncport)
19 self.assertEqual(status, 0, msg="x11vnc server not running on port %s\n\n%s" % (vncport, self.target.run('netstat -ntl; cat x11vnc.log')[1]))
diff --git a/meta/lib/oeqa/runtime/x32lib.py b/meta/lib/oeqa/runtime/x32lib.py
new file mode 100644
index 0000000000..6bad201b12
--- /dev/null
+++ b/meta/lib/oeqa/runtime/x32lib.py
@@ -0,0 +1,17 @@
1import unittest
2from oeqa.oetest import oeRuntimeTest, skipModule
3from oeqa.utils.decorators import *
4
5def setUpModule():
6 #check if DEFAULTTUNE is set and it's value is: x86-64-x32
7 defaulttune = oeRuntimeTest.tc.d.getVar("DEFAULTTUNE", True)
8 if "x86-64-x32" not in defaulttune:
9 skipModule("DEFAULTTUNE is not set to x86-64-x32")
10
11class X32libTest(oeRuntimeTest):
12
13 @skipUnlessPassed("test_ssh")
14 def test_x32_file(self):
15 status1 = self.target.run("readelf -h /bin/ls | grep Class | grep ELF32")[0]
16 status2 = self.target.run("readelf -h /bin/ls | grep Machine | grep X86-64")[0]
17 self.assertTrue(status1 == 0 and status2 == 0, msg="/bin/ls isn't an X86-64 ELF32 binary. readelf says: %s" % self.target.run("readelf -h /bin/ls")[1])
diff --git a/meta/lib/oeqa/runtime/xorg.py b/meta/lib/oeqa/runtime/xorg.py
new file mode 100644
index 0000000000..12dccd8198
--- /dev/null
+++ b/meta/lib/oeqa/runtime/xorg.py
@@ -0,0 +1,21 @@
1import unittest
2from oeqa.oetest import oeRuntimeTest, skipModule
3from oeqa.utils.decorators import *
4
5def setUpModule():
6 if not oeRuntimeTest.hasFeature("x11-base"):
7 skipModule("target doesn't have x11 in IMAGE_FEATURES")
8
9
10class XorgTest(oeRuntimeTest):
11
12 @skipUnlessPassed('test_ssh')
13 def test_xorg_running(self):
14 (status, output) = self.target.run(oeRuntimeTest.pscmd + ' | grep -v xinit | grep [X]org')
15 self.assertEqual(status, 0, msg="Xorg does not appear to be running %s" % self.target.run(oeRuntimeTest.pscmd)[1])
16
17 @skipUnlessPassed('test_ssh')
18 def test_xorg_error(self):
19 (status, output) = self.target.run('cat /var/log/Xorg.0.log | grep -v "(EE) error," | grep -v "PreInit" | grep -v "evdev:" | grep -v "glx" | grep "(EE)"')
20 self.assertEqual(status, 1, msg="Errors in Xorg log: %s" % output)
21
diff --git a/meta/lib/oeqa/utils/__init__.py b/meta/lib/oeqa/utils/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/meta/lib/oeqa/utils/__init__.py
diff --git a/meta/lib/oeqa/utils/decorators.py b/meta/lib/oeqa/utils/decorators.py
new file mode 100644
index 0000000000..33fed5a10b
--- /dev/null
+++ b/meta/lib/oeqa/utils/decorators.py
@@ -0,0 +1,50 @@
1# Copyright (C) 2013 Intel Corporation
2#
3# Released under the MIT license (see COPYING.MIT)
4
5# Some custom decorators that can be used by unittests
6# Most useful is skipUnlessPassed which can be used for
7# creating dependecies between two test methods.
8
9from oeqa.oetest import *
10
11class skipIfFailure(object):
12
13 def __init__(self,testcase):
14 self.testcase = testcase
15
16 def __call__(self,f):
17 def wrapped_f(*args):
18 if self.testcase in (oeRuntimeTest.testFailures or oeRuntimeTest.testErrors):
19 raise unittest.SkipTest("Testcase dependency not met: %s" % self.testcase)
20 return f(*args)
21 wrapped_f.__name__ = f.__name__
22 return wrapped_f
23
24class skipIfSkipped(object):
25
26 def __init__(self,testcase):
27 self.testcase = testcase
28
29 def __call__(self,f):
30 def wrapped_f(*args):
31 if self.testcase in oeRuntimeTest.testSkipped:
32 raise unittest.SkipTest("Testcase dependency not met: %s" % self.testcase)
33 return f(*args)
34 wrapped_f.__name__ = f.__name__
35 return wrapped_f
36
37class skipUnlessPassed(object):
38
39 def __init__(self,testcase):
40 self.testcase = testcase
41
42 def __call__(self,f):
43 def wrapped_f(*args):
44 if self.testcase in oeRuntimeTest.testSkipped or \
45 self.testcase in oeRuntimeTest.testFailures or \
46 self.testcase in oeRuntimeTest.testErrors:
47 raise unittest.SkipTest("Testcase dependency not met: %s" % self.testcase)
48 return f(*args)
49 wrapped_f.__name__ = f.__name__
50 return wrapped_f
diff --git a/meta/lib/oeqa/utils/httpserver.py b/meta/lib/oeqa/utils/httpserver.py
new file mode 100644
index 0000000000..f161a1bddd
--- /dev/null
+++ b/meta/lib/oeqa/utils/httpserver.py
@@ -0,0 +1,33 @@
1import SimpleHTTPServer
2import multiprocessing
3import os
4
5class HTTPServer(SimpleHTTPServer.BaseHTTPServer.HTTPServer):
6
7 def server_start(self, root_dir):
8 os.chdir(root_dir)
9 self.serve_forever()
10
11class HTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
12
13 def log_message(self, format_str, *args):
14 pass
15
16class HTTPService(object):
17
18 def __init__(self, root_dir, host=''):
19 self.root_dir = root_dir
20 self.host = host
21 self.port = 0
22
23 def start(self):
24 self.server = HTTPServer((self.host, self.port), HTTPRequestHandler)
25 if self.port == 0:
26 self.port = self.server.server_port
27 self.process = multiprocessing.Process(target=self.server.server_start, args=[self.root_dir])
28 self.process.start()
29
30 def stop(self):
31 self.server.server_close()
32 self.process.terminate()
33 self.process.join()
diff --git a/meta/lib/oeqa/utils/qemurunner.py b/meta/lib/oeqa/utils/qemurunner.py
new file mode 100644
index 0000000000..256cf3c6a8
--- /dev/null
+++ b/meta/lib/oeqa/utils/qemurunner.py
@@ -0,0 +1,228 @@
1# Copyright (C) 2013 Intel Corporation
2#
3# Released under the MIT license (see COPYING.MIT)
4
5# This module provides a class for starting qemu images using runqemu.
6# It's used by testimage.bbclass.
7
8import subprocess
9import os
10import time
11import signal
12import re
13import socket
14import select
15import bb
16
17class QemuRunner:
18
19 def __init__(self, machine, rootfs, display = None, tmpdir = None, deploy_dir_image = None, logfile = None, boottime = 400, runqemutime = 60):
20 # Popen object
21 self.runqemu = None
22
23 self.machine = machine
24 self.rootfs = rootfs
25
26 self.qemupid = None
27 self.ip = None
28
29 self.display = display
30 self.tmpdir = tmpdir
31 self.deploy_dir_image = deploy_dir_image
32 self.logfile = logfile
33 self.boottime = boottime
34 self.runqemutime = runqemutime
35
36 self.create_socket()
37
38 def create_socket(self):
39
40 self.bootlog = ''
41 self.qemusock = None
42
43 try:
44 self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
45 self.server_socket.setblocking(0)
46 self.server_socket.bind(("127.0.0.1",0))
47 self.server_socket.listen(2)
48 self.serverport = self.server_socket.getsockname()[1]
49 bb.note("Created listening socket for qemu serial console on: 127.0.0.1:%s" % self.serverport)
50 except socket.error, msg:
51 self.server_socket.close()
52 bb.fatal("Failed to create listening socket: %s" %msg[1])
53
54
55 def log(self, msg):
56 if self.logfile:
57 with open(self.logfile, "a") as f:
58 f.write("%s" % msg)
59
60 def launch(self, qemuparams = None):
61
62 if self.display:
63 os.environ["DISPLAY"] = self.display
64 else:
65 bb.error("To start qemu I need a X desktop, please set DISPLAY correctly (e.g. DISPLAY=:1)")
66 return False
67 if not os.path.exists(self.rootfs):
68 bb.error("Invalid rootfs %s" % self.rootfs)
69 return False
70 if not os.path.exists(self.tmpdir):
71 bb.error("Invalid TMPDIR path %s" % self.tmpdir)
72 return False
73 else:
74 os.environ["OE_TMPDIR"] = self.tmpdir
75 if not os.path.exists(self.deploy_dir_image):
76 bb.error("Invalid DEPLOY_DIR_IMAGE path %s" % self.deploy_dir_image)
77 return False
78 else:
79 os.environ["DEPLOY_DIR_IMAGE"] = self.deploy_dir_image
80
81 # Set this flag so that Qemu doesn't do any grabs as SDL grabs interact
82 # badly with screensavers.
83 os.environ["QEMU_DONT_GRAB"] = "1"
84 self.qemuparams = 'bootparams="console=tty1 console=ttyS0,115200n8" qemuparams="-serial tcp:127.0.0.1:%s"' % self.serverport
85 if qemuparams:
86 self.qemuparams = self.qemuparams[:-1] + " " + qemuparams + " " + '\"'
87
88 launch_cmd = 'runqemu %s %s %s' % (self.machine, self.rootfs, self.qemuparams)
89 self.runqemu = subprocess.Popen(launch_cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,preexec_fn=os.setpgrp)
90
91 bb.note("runqemu started, pid is %s" % self.runqemu.pid)
92 bb.note("waiting at most %s seconds for qemu pid" % self.runqemutime)
93 endtime = time.time() + self.runqemutime
94 while not self.is_alive() and time.time() < endtime:
95 time.sleep(1)
96
97 if self.is_alive():
98 bb.note("qemu started - qemu procces pid is %s" % self.qemupid)
99 cmdline = open('/proc/%s/cmdline' % self.qemupid).read()
100 self.ip, _, self.host_ip = cmdline.split('ip=')[1].split(' ')[0].split(':')[0:3]
101 if not re.search("^((?:[0-9]{1,3}\.){3}[0-9]{1,3})$", self.ip):
102 bb.note("Couldn't get ip from qemu process arguments, I got '%s'" % self.ip)
103 bb.note("Here is the ps output:\n%s" % cmdline)
104 self.kill()
105 return False
106 bb.note("IP found: %s" % self.ip)
107 bb.note("Waiting at most %d seconds for login banner" % self.boottime )
108 endtime = time.time() + self.boottime
109 socklist = [self.server_socket]
110 reachedlogin = False
111 stopread = False
112 while time.time() < endtime and not stopread:
113 sread, swrite, serror = select.select(socklist, [], [], 5)
114 for sock in sread:
115 if sock is self.server_socket:
116 self.qemusock, addr = self.server_socket.accept()
117 self.qemusock.setblocking(0)
118 socklist.append(self.qemusock)
119 socklist.remove(self.server_socket)
120 bb.note("Connection from %s:%s" % addr)
121 else:
122 data = sock.recv(1024)
123 if data:
124 self.log(data)
125 self.bootlog += data
126 lastlines = "\n".join(self.bootlog.splitlines()[-2:])
127 if re.search("login:", lastlines):
128 stopread = True
129 reachedlogin = True
130 bb.note("Reached login banner")
131 else:
132 socklist.remove(sock)
133 sock.close()
134 stopread = True
135
136 if not reachedlogin:
137 bb.note("Target didn't reached login boot in %d seconds" % self.boottime)
138 lines = "\n".join(self.bootlog.splitlines()[-5:])
139 bb.note("Last 5 lines of text:\n%s" % lines)
140 bb.note("Check full boot log: %s" % self.logfile)
141 self.kill()
142 return False
143 else:
144 bb.note("Qemu pid didn't appeared in %s seconds" % self.runqemutime)
145 output = self.runqemu.stdout
146 self.kill()
147 bb.note("Output from runqemu:\n%s" % output.read())
148 return False
149
150 return self.is_alive()
151
152 def kill(self):
153
154 if self.runqemu:
155 bb.note("Sending SIGTERM to runqemu")
156 os.kill(-self.runqemu.pid,signal.SIGTERM)
157 endtime = time.time() + self.runqemutime
158 while self.runqemu.poll() is None and time.time() < endtime:
159 time.sleep(1)
160 if self.runqemu.poll() is None:
161 bb.note("Sending SIGKILL to runqemu")
162 os.kill(-self.runqemu.pid,signal.SIGKILL)
163 self.runqemu = None
164 if self.server_socket:
165 self.server_socket.close()
166 self.server_socket = None
167 self.qemupid = None
168 self.ip = None
169
170 def restart(self, qemuparams = None):
171 bb.note("Restarting qemu process")
172 if self.runqemu.poll() is None:
173 self.kill()
174 self.create_socket()
175 if self.launch(qemuparams):
176 return True
177 return False
178
179 def is_alive(self):
180 qemu_child = self.find_child(str(self.runqemu.pid))
181 if qemu_child:
182 self.qemupid = qemu_child[0]
183 if os.path.exists("/proc/" + str(self.qemupid)):
184 return True
185 return False
186
187 def find_child(self,parent_pid):
188 #
189 # Walk the process tree from the process specified looking for a qemu-system. Return its [pid'cmd]
190 #
191 ps = subprocess.Popen(['ps', 'axww', '-o', 'pid,ppid,command'], stdout=subprocess.PIPE).communicate()[0]
192 processes = ps.split('\n')
193 nfields = len(processes[0].split()) - 1
194 pids = {}
195 commands = {}
196 for row in processes[1:]:
197 data = row.split(None, nfields)
198 if len(data) != 3:
199 continue
200 if data[1] not in pids:
201 pids[data[1]] = []
202
203 pids[data[1]].append(data[0])
204 commands[data[0]] = data[2]
205
206 if parent_pid not in pids:
207 return []
208
209 parents = []
210 newparents = pids[parent_pid]
211 while newparents:
212 next = []
213 for p in newparents:
214 if p in pids:
215 for n in pids[p]:
216 if n not in parents and n not in next:
217 next.append(n)
218 if p not in parents:
219 parents.append(p)
220 newparents = next
221 #print "Children matching %s:" % str(parents)
222 for p in parents:
223 # Need to be careful here since runqemu-internal runs "ldd qemu-system-xxxx"
224 # Also, old versions of ldd (2.11) run "LD_XXXX qemu-system-xxxx"
225 basecmd = commands[p].split()[0]
226 basecmd = os.path.basename(basecmd)
227 if "qemu-system" in basecmd and "-serial tcp" in commands[p]:
228 return [int(p),commands[p]]
diff --git a/meta/lib/oeqa/utils/sshcontrol.py b/meta/lib/oeqa/utils/sshcontrol.py
new file mode 100644
index 0000000000..1539ff2a37
--- /dev/null
+++ b/meta/lib/oeqa/utils/sshcontrol.py
@@ -0,0 +1,109 @@
1# Copyright (C) 2013 Intel Corporation
2#
3# Released under the MIT license (see COPYING.MIT)
4
5# Provides a class for setting up ssh connections,
6# running commands and copying files to/from a target.
7# It's used by testimage.bbclass and tests in lib/oeqa/runtime.
8
9import subprocess
10import time
11import os
12
13class SSHControl(object):
14
15 def __init__(self, host=None, timeout=300, logfile=None):
16 self.host = host
17 self.timeout = timeout
18 self._starttime = None
19 self._out = ''
20 self._ret = 126
21 self.logfile = logfile
22 self.ssh_options = [
23 '-o', 'UserKnownHostsFile=/dev/null',
24 '-o', 'StrictHostKeyChecking=no',
25 '-o', 'LogLevel=ERROR'
26 ]
27 self.ssh = ['ssh', '-l', 'root'] + self.ssh_options
28
29 def log(self, msg):
30 if self.logfile:
31 with open(self.logfile, "a") as f:
32 f.write("%s\n" % msg)
33
34 def _internal_run(self, cmd):
35 # We need this for a proper PATH
36 cmd = ". /etc/profile; " + cmd
37 command = self.ssh + [self.host, cmd]
38 self.log("[Running]$ %s" % " ".join(command))
39 self._starttime = time.time()
40 # ssh hangs without os.setsid
41 proc = subprocess.Popen(command, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, preexec_fn=os.setsid)
42 return proc
43
44 def run(self, cmd, timeout=None):
45 """Run cmd and get it's return code and output.
46 Let it run for timeout seconds and then terminate/kill it,
47 if time is 0 will let cmd run until it finishes.
48 Time can be passed to here or can be set per class instance."""
49
50 if self.host:
51 sshconn = self._internal_run(cmd)
52 else:
53 raise Exception("Remote IP hasn't been set: '%s'" % actualcmd)
54
55 if timeout == 0:
56 self._out = sshconn.communicate()[0]
57 self._ret = sshconn.poll()
58 else:
59 if timeout is None:
60 tdelta = self.timeout
61 else:
62 tdelta = timeout
63 endtime = self._starttime + tdelta
64 while sshconn.poll() is None and time.time() < endtime:
65 time.sleep(1)
66 # process hasn't returned yet
67 if sshconn.poll() is None:
68 self._ret = 255
69 sshconn.terminate()
70 sshconn.kill()
71 self._out = sshconn.stdout.read()
72 sshconn.stdout.close()
73 self._out += "\n[!!! SSH command timed out after %d seconds and it was killed]" % tdelta
74 else:
75 self._out = sshconn.stdout.read()
76 self._ret = sshconn.poll()
77 # strip the last LF so we can test the output
78 self._out = self._out.rstrip()
79 self.log("%s" % self._out)
80 self.log("[SSH command returned after %d seconds]: %s" % (time.time() - self._starttime, self._ret))
81 return (self._ret, self._out)
82
83 def _internal_scp(self, cmd):
84 cmd = ['scp'] + self.ssh_options + cmd
85 self.log("[Running SCP]$ %s" % " ".join(cmd))
86 self._starttime = time.time()
87 scpconn = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, preexec_fn=os.setsid)
88 out = scpconn.communicate()[0]
89 ret = scpconn.poll()
90 self.log("%s" % out)
91 self.log("[SCP command returned after %d seconds]: %s" % (time.time() - self._starttime, ret))
92 if ret != 0:
93 # we raise an exception so that tests fail in setUp and setUpClass without a need for an assert
94 raise Exception("Error running %s, output: %s" % ( " ".join(cmd), out))
95 return (ret, out)
96
97 def copy_to(self, localpath, remotepath):
98 actualcmd = [localpath, 'root@%s:%s' % (self.host, remotepath)]
99 return self._internal_scp(actualcmd)
100
101 def copy_from(self, remotepath, localpath):
102 actualcmd = ['root@%s:%s' % (self.host, remotepath), localpath]
103 return self._internal_scp(actualcmd)
104
105 def get_status(self):
106 return self._ret
107
108 def get_output(self):
109 return self._out
diff --git a/meta/lib/oeqa/utils/targetbuild.py b/meta/lib/oeqa/utils/targetbuild.py
new file mode 100644
index 0000000000..9b2cf53773
--- /dev/null
+++ b/meta/lib/oeqa/utils/targetbuild.py
@@ -0,0 +1,63 @@
1# Copyright (C) 2013 Intel Corporation
2#
3# Released under the MIT license (see COPYING.MIT)
4
5# Provides a class for automating build tests for projects
6
7from oeqa.oetest import oeRuntimeTest
8import bb.fetch2
9import bb.data
10import os
11import re
12
13
14class TargetBuildProject():
15
16 def __init__(self, target, uri, foldername=None):
17 self.target = target
18 self.uri = uri
19 self.targetdir = "/home/root/"
20
21 self.localdata = bb.data.createCopy(oeRuntimeTest.tc.d)
22 bb.data.update_data(self.localdata)
23
24 if not foldername:
25 self.archive = os.path.basename(uri)
26 self.fname = re.sub(r'.tar.bz2|tar.gz$', '', self.archive)
27 else:
28 self.fname = foldername
29
30 def download_archive(self):
31
32 try:
33 self.localdata.delVar("BB_STRICT_CHECKSUM")
34 fetcher = bb.fetch2.Fetch([self.uri], self.localdata)
35 fetcher.download()
36 self.localarchive = fetcher.localpath(self.uri)
37 except bb.fetch2.BBFetchException:
38 raise Exception("Failed to download archive: %s" % self.uri)
39
40 (status, output) = self.target.copy_to(self.localarchive, self.targetdir)
41 if status != 0:
42 raise Exception("Failed to copy archive to target, output: %s" % output)
43
44 (status, output) = self.target.run('tar xf %s%s -C %s' % (self.targetdir, self.archive, self.targetdir))
45 if status != 0:
46 raise Exception("Failed to extract archive, output: %s" % output)
47
48 #Change targetdir to project folder
49 self.targetdir = self.targetdir + self.fname
50
51 # The timeout parameter of target.run is set to 0 to make the ssh command
52 # run with no timeout.
53 def run_configure(self):
54 return self.target.run('cd %s; ./configure' % self.targetdir, 0)[0]
55
56 def run_make(self):
57 return self.target.run('cd %s; make' % self.targetdir, 0)[0]
58
59 def run_install(self):
60 return self.target.run('cd %s; make install' % self.targetdir, 0)[0]
61
62 def clean(self):
63 self.target.run('rm -rf %s' % self.targetdir)