summaryrefslogtreecommitdiffstats
path: root/meta/lib/oeqa/targetcontrol.py
diff options
context:
space:
mode:
Diffstat (limited to 'meta/lib/oeqa/targetcontrol.py')
-rw-r--r--meta/lib/oeqa/targetcontrol.py199
1 files changed, 199 insertions, 0 deletions
diff --git a/meta/lib/oeqa/targetcontrol.py b/meta/lib/oeqa/targetcontrol.py
new file mode 100644
index 0000000000..cc582dd1ad
--- /dev/null
+++ b/meta/lib/oeqa/targetcontrol.py
@@ -0,0 +1,199 @@
1# Copyright (C) 2013 Intel Corporation
2#
3# Released under the MIT license (see COPYING.MIT)
4
5# This module is used by testimage.bbclass for setting up and controlling a target machine.
6
7import os
8import shutil
9import subprocess
10import bb
11import traceback
12import sys
13from oeqa.utils.sshcontrol import SSHControl
14from oeqa.utils.qemurunner import QemuRunner
15from oeqa.controllers.testtargetloader import TestTargetLoader
16from abc import ABCMeta, abstractmethod
17
18def get_target_controller(d):
19 testtarget = d.getVar("TEST_TARGET", True)
20 # old, simple names
21 if testtarget == "qemu":
22 return QemuTarget(d)
23 elif testtarget == "simpleremote":
24 return SimpleRemoteTarget(d)
25 else:
26 # use the class name
27 try:
28 # is it a core class defined here?
29 controller = getattr(sys.modules[__name__], testtarget)
30 except AttributeError:
31 # nope, perhaps a layer defined one
32 try:
33 bbpath = d.getVar("BBPATH", True).split(':')
34 testtargetloader = TestTargetLoader()
35 controller = testtargetloader.get_controller_module(testtarget, bbpath)
36 except ImportError as e:
37 bb.fatal("Failed to import {0} from available controller modules:\n{1}".format(testtarget,traceback.format_exc()))
38 except AttributeError as e:
39 bb.fatal("Invalid TEST_TARGET - " + str(e))
40 return controller(d)
41
42
43class BaseTarget(object):
44
45 __metaclass__ = ABCMeta
46
47 supported_image_fstypes = []
48
49 def __init__(self, d):
50 self.connection = None
51 self.ip = None
52 self.server_ip = None
53 self.datetime = d.getVar('DATETIME', True)
54 self.testdir = d.getVar("TEST_LOG_DIR", True)
55 self.pn = d.getVar("PN", True)
56
57 @abstractmethod
58 def deploy(self):
59
60 self.sshlog = os.path.join(self.testdir, "ssh_target_log.%s" % self.datetime)
61 sshloglink = os.path.join(self.testdir, "ssh_target_log")
62 if os.path.islink(sshloglink):
63 os.unlink(sshloglink)
64 os.symlink(self.sshlog, sshloglink)
65 bb.note("SSH log file: %s" % self.sshlog)
66
67 @abstractmethod
68 def start(self, params=None):
69 pass
70
71 @abstractmethod
72 def stop(self):
73 pass
74
75 @classmethod
76 def get_extra_files(self):
77 return None
78
79 @classmethod
80 def match_image_fstype(self, d, image_fstypes=None):
81 if not image_fstypes:
82 image_fstypes = d.getVar('IMAGE_FSTYPES', True).split(' ')
83 possible_image_fstypes = [fstype for fstype in self.supported_image_fstypes if fstype in image_fstypes]
84 if possible_image_fstypes:
85 return possible_image_fstypes[0]
86 else:
87 return None
88
89 def get_image_fstype(self, d):
90 image_fstype = self.match_image_fstype(d)
91 if image_fstype:
92 return image_fstype
93 else:
94 bb.fatal("IMAGE_FSTYPES should contain a Target Controller supported image fstype: %s " % ', '.join(map(str, self.supported_image_fstypes)))
95
96 def restart(self, params=None):
97 self.stop()
98 self.start(params)
99
100 def run(self, cmd, timeout=None):
101 return self.connection.run(cmd, timeout)
102
103 def copy_to(self, localpath, remotepath):
104 return self.connection.copy_to(localpath, remotepath)
105
106 def copy_from(self, remotepath, localpath):
107 return self.connection.copy_from(remotepath, localpath)
108
109
110
111class QemuTarget(BaseTarget):
112
113 supported_image_fstypes = ['ext3']
114
115 def __init__(self, d):
116
117 super(QemuTarget, self).__init__(d)
118
119 self.image_fstype = self.get_image_fstype(d)
120 self.qemulog = os.path.join(self.testdir, "qemu_boot_log.%s" % self.datetime)
121 self.origrootfs = os.path.join(d.getVar("DEPLOY_DIR_IMAGE", True), d.getVar("IMAGE_LINK_NAME", True) + '.' + self.image_fstype)
122 self.rootfs = os.path.join(self.testdir, d.getVar("IMAGE_LINK_NAME", True) + '-testimage.' + self.image_fstype)
123
124 self.runner = QemuRunner(machine=d.getVar("MACHINE", True),
125 rootfs=self.rootfs,
126 tmpdir = d.getVar("TMPDIR", True),
127 deploy_dir_image = d.getVar("DEPLOY_DIR_IMAGE", True),
128 display = d.getVar("BB_ORIGENV", False).getVar("DISPLAY", True),
129 logfile = self.qemulog,
130 boottime = int(d.getVar("TEST_QEMUBOOT_TIMEOUT", True)))
131
132 def deploy(self):
133 try:
134 shutil.copyfile(self.origrootfs, self.rootfs)
135 except Exception as e:
136 bb.fatal("Error copying rootfs: %s" % e)
137
138 qemuloglink = os.path.join(self.testdir, "qemu_boot_log")
139 if os.path.islink(qemuloglink):
140 os.unlink(qemuloglink)
141 os.symlink(self.qemulog, qemuloglink)
142
143 bb.note("rootfs file: %s" % self.rootfs)
144 bb.note("Qemu log file: %s" % self.qemulog)
145 super(QemuTarget, self).deploy()
146
147 def start(self, params=None):
148 if self.runner.start(params):
149 self.ip = self.runner.ip
150 self.server_ip = self.runner.server_ip
151 self.connection = SSHControl(ip=self.ip, logfile=self.sshlog)
152 else:
153 self.stop()
154 raise bb.build.FuncFailed("%s - FAILED to start qemu - check the task log and the boot log" % self.pn)
155
156 def stop(self):
157 self.runner.stop()
158 self.connection = None
159 self.ip = None
160 self.server_ip = None
161
162 def restart(self, params=None):
163 if self.runner.restart(params):
164 self.ip = self.runner.ip
165 self.server_ip = self.runner.server_ip
166 self.connection = SSHControl(ip=self.ip, logfile=self.sshlog)
167 else:
168 raise bb.build.FuncFailed("%s - FAILED to re-start qemu - check the task log and the boot log" % self.pn)
169
170
171class SimpleRemoteTarget(BaseTarget):
172
173 def __init__(self, d):
174 super(SimpleRemoteTarget, self).__init__(d)
175 addr = d.getVar("TEST_TARGET_IP", True) or bb.fatal('Please set TEST_TARGET_IP with the IP address of the machine you want to run the tests on.')
176 self.ip = addr.split(":")[0]
177 try:
178 self.port = addr.split(":")[1]
179 except IndexError:
180 self.port = None
181 bb.note("Target IP: %s" % self.ip)
182 self.server_ip = d.getVar("TEST_SERVER_IP", True)
183 if not self.server_ip:
184 try:
185 self.server_ip = subprocess.check_output(['ip', 'route', 'get', self.ip ]).split("\n")[0].split()[-1]
186 except Exception as e:
187 bb.fatal("Failed to determine the host IP address (alternatively you can set TEST_SERVER_IP with the IP address of this machine): %s" % e)
188 bb.note("Server IP: %s" % self.server_ip)
189
190 def deploy(self):
191 super(SimpleRemoteTarget, self).deploy()
192
193 def start(self, params=None):
194 self.connection = SSHControl(self.ip, logfile=self.sshlog, port=self.port)
195
196 def stop(self):
197 self.connection = None
198 self.ip = None
199 self.server_ip = None