summaryrefslogtreecommitdiffstats
path: root/meta/lib/oeqa
diff options
context:
space:
mode:
authorStefan Stanacar <stefanx.stanacar@intel.com>2013-11-26 11:18:22 +0200
committerRichard Purdie <richard.purdie@linuxfoundation.org>2013-12-03 17:45:51 +0000
commitb4d9b4208b1c06164c4eeea2110408fb404dba1c (patch)
tree12709d6e6b26777f9a2973022a2e7b32ea0e3d2b /meta/lib/oeqa
parentfd2d16519d964ef3420cb83ac9680a4b6206cefa (diff)
downloadpoky-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.py20
-rw-r--r--meta/lib/oeqa/runtime/ping.py2
-rw-r--r--meta/lib/oeqa/runtime/smart.py4
-rw-r--r--meta/lib/oeqa/utils/qemurunner.py50
-rw-r--r--meta/lib/oeqa/utils/sshcontrol.py20
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
14from oeqa.utils.sshcontrol import SSHControl 14from oeqa.utils.sshcontrol import SSHControl
15 15
16 16
17def runTests(tc): 17def 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
31def 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
91def getmodule(pos=2): 91def 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
108def skipModuleIf(cond, reason): 108def 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
17class QemuRunner: 17class 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
14class SSHControl(object): 14class 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