diff options
author | Stefan Stanacar <stefanx.stanacar@intel.com> | 2013-11-26 11:18:22 +0200 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2013-12-03 17:45:51 +0000 |
commit | b4d9b4208b1c06164c4eeea2110408fb404dba1c (patch) | |
tree | 12709d6e6b26777f9a2973022a2e7b32ea0e3d2b /meta/lib/oeqa | |
parent | fd2d16519d964ef3420cb83ac9680a4b6206cefa (diff) | |
download | poky-b4d9b4208b1c06164c4eeea2110408fb404dba1c.tar.gz |
testimage: use the new targetcontrol.py module for running tests
This patch makes the necessary changes for using the targetcontrol.py module
so that one can run the same tests on a qemu instance or a remote machine
based on the value of TEST_TARGET variable: "qemu" or "simpleremote".
The default value is "qemu" which starts a qemu instance and it's the
with what we currently have.
With "simpleremote", the remote machine must be up with network and ssh
and you need to set TEST_TARGET_IP with the IP address of the remote machine
(it can still be a qemu instance that was manually started).
Basically testimage.bbclass now does something along the lines of:
- load tests -> deploy (prepare) / start target -> run tests.
There were a couple of changes necessary for tests and
also some cleanups/renames that were needed to adjust this change. (use
ip everywhere when refering to target and server_ip when refering to host/build machine)
Also two unnecessary and unsed methods were dropped from sshcontrol.
[ YOCTO #5554 ]
(From OE-Core rev: a7820350fa3271d78ed7476e02f4aef593be1125)
Signed-off-by: Stefan Stanacar <stefanx.stanacar@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/lib/oeqa')
-rw-r--r-- | meta/lib/oeqa/oetest.py | 20 | ||||
-rw-r--r-- | meta/lib/oeqa/runtime/ping.py | 2 | ||||
-rw-r--r-- | meta/lib/oeqa/runtime/smart.py | 4 | ||||
-rw-r--r-- | meta/lib/oeqa/utils/qemurunner.py | 50 | ||||
-rw-r--r-- | meta/lib/oeqa/utils/sshcontrol.py | 20 |
5 files changed, 50 insertions, 46 deletions
diff --git a/meta/lib/oeqa/oetest.py b/meta/lib/oeqa/oetest.py index 95661506e3..70d12a225e 100644 --- a/meta/lib/oeqa/oetest.py +++ b/meta/lib/oeqa/oetest.py | |||
@@ -14,7 +14,7 @@ import bb | |||
14 | from oeqa.utils.sshcontrol import SSHControl | 14 | from oeqa.utils.sshcontrol import SSHControl |
15 | 15 | ||
16 | 16 | ||
17 | def runTests(tc): | 17 | def loadTests(tc): |
18 | 18 | ||
19 | # set the context object passed from the test class | 19 | # set the context object passed from the test class |
20 | setattr(oeTest, "tc", tc) | 20 | setattr(oeTest, "tc", tc) |
@@ -24,12 +24,16 @@ def runTests(tc): | |||
24 | suite = unittest.TestSuite() | 24 | suite = unittest.TestSuite() |
25 | testloader = unittest.TestLoader() | 25 | testloader = unittest.TestLoader() |
26 | testloader.sortTestMethodsUsing = None | 26 | testloader.sortTestMethodsUsing = None |
27 | runner = unittest.TextTestRunner(verbosity=2) | 27 | suite = testloader.loadTestsFromNames(tc.testslist) |
28 | |||
29 | return suite | ||
30 | |||
31 | def runTests(tc): | ||
28 | 32 | ||
33 | suite = loadTests(tc) | ||
29 | bb.note("Test modules %s" % tc.testslist) | 34 | bb.note("Test modules %s" % tc.testslist) |
30 | suite = testloader.loadTestsFromNames(tc.testslist) | ||
31 | bb.note("Found %s tests" % suite.countTestCases()) | 35 | bb.note("Found %s tests" % suite.countTestCases()) |
32 | 36 | runner = unittest.TextTestRunner(verbosity=2) | |
33 | result = runner.run(suite) | 37 | result = runner.run(suite) |
34 | 38 | ||
35 | return result | 39 | return result |
@@ -81,11 +85,7 @@ class oeRuntimeTest(oeTest): | |||
81 | 85 | ||
82 | @classmethod | 86 | @classmethod |
83 | def restartTarget(self,params=None): | 87 | def restartTarget(self,params=None): |
84 | 88 | oeRuntimeTest.tc.target.restart(params) | |
85 | if oeRuntimeTest.tc.qemu.restart(params): | ||
86 | oeRuntimeTest.tc.target.host = oeRuntimeTest.tc.qemu.ip | ||
87 | else: | ||
88 | raise Exception("Restarting target failed") | ||
89 | 89 | ||
90 | 90 | ||
91 | def getmodule(pos=2): | 91 | def getmodule(pos=2): |
@@ -103,7 +103,7 @@ def skipModule(reason, pos=2): | |||
103 | else: | 103 | else: |
104 | raise Exception("\nTest %s wants to be skipped.\nReason is: %s" \ | 104 | raise Exception("\nTest %s wants to be skipped.\nReason is: %s" \ |
105 | "\nTest was required in TEST_SUITES, so either the condition for skipping is wrong" \ | 105 | "\nTest was required in TEST_SUITES, so either the condition for skipping is wrong" \ |
106 | "\nor the image really doesn't have the requred feature/package when it should." % (modname, reason)) | 106 | "\nor the image really doesn't have the required feature/package when it should." % (modname, reason)) |
107 | 107 | ||
108 | def skipModuleIf(cond, reason): | 108 | def skipModuleIf(cond, reason): |
109 | 109 | ||
diff --git a/meta/lib/oeqa/runtime/ping.py b/meta/lib/oeqa/runtime/ping.py index 0d028f9b22..a73c72402a 100644 --- a/meta/lib/oeqa/runtime/ping.py +++ b/meta/lib/oeqa/runtime/ping.py | |||
@@ -11,7 +11,7 @@ class PingTest(oeRuntimeTest): | |||
11 | count = 0 | 11 | count = 0 |
12 | endtime = time.time() + 60 | 12 | endtime = time.time() + 60 |
13 | while count < 5 and time.time() < endtime: | 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) | 14 | proc = subprocess.Popen("ping -c 1 %s" % self.target.ip, shell=True, stdout=subprocess.PIPE) |
15 | output += proc.communicate()[0] | 15 | output += proc.communicate()[0] |
16 | if proc.poll() == 0: | 16 | if proc.poll() == 0: |
17 | count += 1 | 17 | count += 1 |
diff --git a/meta/lib/oeqa/runtime/smart.py b/meta/lib/oeqa/runtime/smart.py index c3fdf7d499..7ef4b0e649 100644 --- a/meta/lib/oeqa/runtime/smart.py +++ b/meta/lib/oeqa/runtime/smart.py | |||
@@ -46,7 +46,7 @@ class SmartRepoTest(SmartTest): | |||
46 | 46 | ||
47 | @classmethod | 47 | @classmethod |
48 | def setUpClass(self): | 48 | def setUpClass(self): |
49 | self.repo_server = HTTPService(oeRuntimeTest.tc.d.getVar('DEPLOY_DIR', True), oeRuntimeTest.tc.qemu.host_ip) | 49 | self.repo_server = HTTPService(oeRuntimeTest.tc.d.getVar('DEPLOY_DIR', True), oeRuntimeTest.tc.target.server_ip) |
50 | self.repo_server.start() | 50 | self.repo_server.start() |
51 | 51 | ||
52 | @classmethod | 52 | @classmethod |
@@ -58,7 +58,7 @@ class SmartRepoTest(SmartTest): | |||
58 | 58 | ||
59 | def test_smart_channel_add(self): | 59 | def test_smart_channel_add(self): |
60 | image_pkgtype = self.tc.d.getVar('IMAGE_PKGTYPE', True) | 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) | 61 | deploy_url = 'http://%s:%s/%s' %(self.target.server_ip, self.repo_server.port, image_pkgtype) |
62 | pkgarchs = self.tc.d.getVar('PACKAGE_ARCHS', True) | 62 | pkgarchs = self.tc.d.getVar('PACKAGE_ARCHS', True) |
63 | for arch in os.listdir('%s/%s' % (self.repo_server.root_dir, image_pkgtype)): | 63 | for arch in os.listdir('%s/%s' % (self.repo_server.root_dir, image_pkgtype)): |
64 | if arch in pkgarchs: | 64 | if arch in pkgarchs: |
diff --git a/meta/lib/oeqa/utils/qemurunner.py b/meta/lib/oeqa/utils/qemurunner.py index 256cf3c6a8..5366a635fe 100644 --- a/meta/lib/oeqa/utils/qemurunner.py +++ b/meta/lib/oeqa/utils/qemurunner.py | |||
@@ -16,25 +16,30 @@ import bb | |||
16 | 16 | ||
17 | class QemuRunner: | 17 | class QemuRunner: |
18 | 18 | ||
19 | def __init__(self, machine, rootfs, display = None, tmpdir = None, deploy_dir_image = None, logfile = None, boottime = 400, runqemutime = 60): | 19 | def __init__(self, machine, rootfs, display, tmpdir, deploy_dir_image, logfile, boottime): |
20 | # Popen object | ||
21 | self.runqemu = None | ||
22 | |||
23 | self.machine = machine | ||
24 | self.rootfs = rootfs | ||
25 | 20 | ||
21 | # Popen object for runqemu | ||
22 | self.runqemu = None | ||
23 | # pid of the qemu process that runqemu will start | ||
26 | self.qemupid = None | 24 | self.qemupid = None |
25 | # target ip - from the command line | ||
27 | self.ip = None | 26 | self.ip = None |
27 | # host ip - where qemu is running | ||
28 | self.server_ip = None | ||
28 | 29 | ||
30 | self.machine = machine | ||
31 | self.rootfs = rootfs | ||
29 | self.display = display | 32 | self.display = display |
30 | self.tmpdir = tmpdir | 33 | self.tmpdir = tmpdir |
31 | self.deploy_dir_image = deploy_dir_image | 34 | self.deploy_dir_image = deploy_dir_image |
32 | self.logfile = logfile | 35 | self.logfile = logfile |
33 | self.boottime = boottime | 36 | self.boottime = boottime |
34 | self.runqemutime = runqemutime | 37 | |
38 | self.runqemutime = 60 | ||
35 | 39 | ||
36 | self.create_socket() | 40 | self.create_socket() |
37 | 41 | ||
42 | |||
38 | def create_socket(self): | 43 | def create_socket(self): |
39 | 44 | ||
40 | self.bootlog = '' | 45 | self.bootlog = '' |
@@ -57,7 +62,7 @@ class QemuRunner: | |||
57 | with open(self.logfile, "a") as f: | 62 | with open(self.logfile, "a") as f: |
58 | f.write("%s" % msg) | 63 | f.write("%s" % msg) |
59 | 64 | ||
60 | def launch(self, qemuparams = None): | 65 | def start(self, qemuparams = None): |
61 | 66 | ||
62 | if self.display: | 67 | if self.display: |
63 | os.environ["DISPLAY"] = self.display | 68 | os.environ["DISPLAY"] = self.display |
@@ -96,14 +101,19 @@ class QemuRunner: | |||
96 | 101 | ||
97 | if self.is_alive(): | 102 | if self.is_alive(): |
98 | bb.note("qemu started - qemu procces pid is %s" % self.qemupid) | 103 | bb.note("qemu started - qemu procces pid is %s" % self.qemupid) |
99 | cmdline = open('/proc/%s/cmdline' % self.qemupid).read() | 104 | cmdline = '' |
100 | self.ip, _, self.host_ip = cmdline.split('ip=')[1].split(' ')[0].split(':')[0:3] | 105 | with open('/proc/%s/cmdline' % self.qemupid) as p: |
101 | if not re.search("^((?:[0-9]{1,3}\.){3}[0-9]{1,3})$", self.ip): | 106 | cmdline = p.read() |
102 | bb.note("Couldn't get ip from qemu process arguments, I got '%s'" % self.ip) | 107 | ips = re.findall("((?:[0-9]{1,3}\.){3}[0-9]{1,3})", cmdline.split("ip=")[1]) |
103 | bb.note("Here is the ps output:\n%s" % cmdline) | 108 | if not ips or len(ips) != 3: |
104 | self.kill() | 109 | bb.note("Couldn't get ip from qemu process arguments! Here is the qemu command line used: %s" % cmdline) |
110 | self.stop() | ||
105 | return False | 111 | return False |
106 | bb.note("IP found: %s" % self.ip) | 112 | else: |
113 | self.ip = ips[0] | ||
114 | self.server_ip = ips[1] | ||
115 | bb.note("Target IP: %s" % self.ip) | ||
116 | bb.note("Server IP: %s" % self.server_ip) | ||
107 | bb.note("Waiting at most %d seconds for login banner" % self.boottime ) | 117 | bb.note("Waiting at most %d seconds for login banner" % self.boottime ) |
108 | endtime = time.time() + self.boottime | 118 | endtime = time.time() + self.boottime |
109 | socklist = [self.server_socket] | 119 | socklist = [self.server_socket] |
@@ -138,18 +148,18 @@ class QemuRunner: | |||
138 | lines = "\n".join(self.bootlog.splitlines()[-5:]) | 148 | lines = "\n".join(self.bootlog.splitlines()[-5:]) |
139 | bb.note("Last 5 lines of text:\n%s" % lines) | 149 | bb.note("Last 5 lines of text:\n%s" % lines) |
140 | bb.note("Check full boot log: %s" % self.logfile) | 150 | bb.note("Check full boot log: %s" % self.logfile) |
141 | self.kill() | 151 | self.stop() |
142 | return False | 152 | return False |
143 | else: | 153 | else: |
144 | bb.note("Qemu pid didn't appeared in %s seconds" % self.runqemutime) | 154 | bb.note("Qemu pid didn't appeared in %s seconds" % self.runqemutime) |
145 | output = self.runqemu.stdout | 155 | output = self.runqemu.stdout |
146 | self.kill() | 156 | self.stop() |
147 | bb.note("Output from runqemu:\n%s" % output.read()) | 157 | bb.note("Output from runqemu:\n%s" % output.read()) |
148 | return False | 158 | return False |
149 | 159 | ||
150 | return self.is_alive() | 160 | return self.is_alive() |
151 | 161 | ||
152 | def kill(self): | 162 | def stop(self): |
153 | 163 | ||
154 | if self.runqemu: | 164 | if self.runqemu: |
155 | bb.note("Sending SIGTERM to runqemu") | 165 | bb.note("Sending SIGTERM to runqemu") |
@@ -170,9 +180,9 @@ class QemuRunner: | |||
170 | def restart(self, qemuparams = None): | 180 | def restart(self, qemuparams = None): |
171 | bb.note("Restarting qemu process") | 181 | bb.note("Restarting qemu process") |
172 | if self.runqemu.poll() is None: | 182 | if self.runqemu.poll() is None: |
173 | self.kill() | 183 | self.stop() |
174 | self.create_socket() | 184 | self.create_socket() |
175 | if self.launch(qemuparams): | 185 | if self.start(qemuparams): |
176 | return True | 186 | return True |
177 | return False | 187 | return False |
178 | 188 | ||
diff --git a/meta/lib/oeqa/utils/sshcontrol.py b/meta/lib/oeqa/utils/sshcontrol.py index 07257b8948..a0dcf023bd 100644 --- a/meta/lib/oeqa/utils/sshcontrol.py +++ b/meta/lib/oeqa/utils/sshcontrol.py | |||
@@ -13,8 +13,8 @@ import select | |||
13 | 13 | ||
14 | class SSHControl(object): | 14 | class SSHControl(object): |
15 | 15 | ||
16 | def __init__(self, host=None, timeout=300, logfile=None): | 16 | def __init__(self, ip=None, timeout=300, logfile=None): |
17 | self.host = host | 17 | self.ip = ip |
18 | self.timeout = timeout | 18 | self.timeout = timeout |
19 | self._starttime = None | 19 | self._starttime = None |
20 | self._out = '' | 20 | self._out = '' |
@@ -35,7 +35,7 @@ class SSHControl(object): | |||
35 | def _internal_run(self, cmd): | 35 | def _internal_run(self, cmd): |
36 | # We need this for a proper PATH | 36 | # We need this for a proper PATH |
37 | cmd = ". /etc/profile; " + cmd | 37 | cmd = ". /etc/profile; " + cmd |
38 | command = self.ssh + [self.host, cmd] | 38 | command = self.ssh + [self.ip, cmd] |
39 | self.log("[Running]$ %s" % " ".join(command)) | 39 | self.log("[Running]$ %s" % " ".join(command)) |
40 | self._starttime = time.time() | 40 | self._starttime = time.time() |
41 | # ssh hangs without os.setsid | 41 | # ssh hangs without os.setsid |
@@ -48,10 +48,10 @@ class SSHControl(object): | |||
48 | if time is 0 will let cmd run until it finishes. | 48 | if time is 0 will let cmd run until it finishes. |
49 | Time can be passed to here or can be set per class instance.""" | 49 | Time can be passed to here or can be set per class instance.""" |
50 | 50 | ||
51 | if self.host: | 51 | if self.ip: |
52 | sshconn = self._internal_run(cmd) | 52 | sshconn = self._internal_run(cmd) |
53 | else: | 53 | else: |
54 | raise Exception("Remote IP/host hasn't been set, I can't run ssh without one.") | 54 | raise Exception("Remote IP hasn't been set, I can't run ssh without one.") |
55 | 55 | ||
56 | # run the command forever | 56 | # run the command forever |
57 | if timeout == 0: | 57 | if timeout == 0: |
@@ -108,15 +108,9 @@ class SSHControl(object): | |||
108 | return (ret, out) | 108 | return (ret, out) |
109 | 109 | ||
110 | def copy_to(self, localpath, remotepath): | 110 | def copy_to(self, localpath, remotepath): |
111 | actualcmd = [localpath, 'root@%s:%s' % (self.host, remotepath)] | 111 | actualcmd = [localpath, 'root@%s:%s' % (self.ip, remotepath)] |
112 | return self._internal_scp(actualcmd) | 112 | return self._internal_scp(actualcmd) |
113 | 113 | ||
114 | def copy_from(self, remotepath, localpath): | 114 | def copy_from(self, remotepath, localpath): |
115 | actualcmd = ['root@%s:%s' % (self.host, remotepath), localpath] | 115 | actualcmd = ['root@%s:%s' % (self.ip, remotepath), localpath] |
116 | return self._internal_scp(actualcmd) | 116 | return self._internal_scp(actualcmd) |
117 | |||
118 | def get_status(self): | ||
119 | return self._ret | ||
120 | |||
121 | def get_output(self): | ||
122 | return self._out | ||