diff options
-rw-r--r-- | meta/lib/oeqa/oetest.py | 10 | ||||
-rw-r--r-- | meta/lib/oeqa/targetcontrol.py | 9 | ||||
-rw-r--r-- | meta/lib/oeqa/utils/dump.py | 28 | ||||
-rw-r--r-- | meta/lib/oeqa/utils/qemurunner.py | 15 |
4 files changed, 35 insertions, 27 deletions
diff --git a/meta/lib/oeqa/oetest.py b/meta/lib/oeqa/oetest.py index f54113626b..4224206546 100644 --- a/meta/lib/oeqa/oetest.py +++ b/meta/lib/oeqa/oetest.py | |||
@@ -123,14 +123,14 @@ class oeRuntimeTest(oeTest): | |||
123 | # If a test fails or there is an exception | 123 | # If a test fails or there is an exception |
124 | if not exc_info() == (None, None, None): | 124 | if not exc_info() == (None, None, None): |
125 | exc_clear() | 125 | exc_clear() |
126 | self.tc.host_dumper.create_dir(self._testMethodName) | 126 | #Only dump for QemuTarget |
127 | self.tc.host_dumper.dump_host() | ||
128 | #Only QemuTarget has a serial console | ||
129 | if (isinstance(self.target, QemuTarget)): | 127 | if (isinstance(self.target, QemuTarget)): |
128 | self.tc.host_dumper.create_dir(self._testMethodName) | ||
129 | self.tc.host_dumper.dump_host() | ||
130 | self.target.target_dumper.dump_target( | 130 | self.target.target_dumper.dump_target( |
131 | self.tc.host_dumper.dump_dir) | 131 | self.tc.host_dumper.dump_dir) |
132 | print ("%s dump data stored in %s" % (self._testMethodName, | 132 | print ("%s dump data stored in %s" % (self._testMethodName, |
133 | self.tc.host_dumper.dump_dir)) | 133 | self.tc.host_dumper.dump_dir)) |
134 | 134 | ||
135 | #TODO: use package_manager.py to install packages on any type of image | 135 | #TODO: use package_manager.py to install packages on any type of image |
136 | def install_packages(self, packagelist): | 136 | def install_packages(self, packagelist): |
diff --git a/meta/lib/oeqa/targetcontrol.py b/meta/lib/oeqa/targetcontrol.py index 2d58f17ddb..542e259112 100644 --- a/meta/lib/oeqa/targetcontrol.py +++ b/meta/lib/oeqa/targetcontrol.py | |||
@@ -124,6 +124,9 @@ class QemuTarget(BaseTarget): | |||
124 | self.origrootfs = os.path.join(d.getVar("DEPLOY_DIR_IMAGE", True), d.getVar("IMAGE_LINK_NAME", True) + '.' + self.image_fstype) | 124 | self.origrootfs = os.path.join(d.getVar("DEPLOY_DIR_IMAGE", True), d.getVar("IMAGE_LINK_NAME", True) + '.' + self.image_fstype) |
125 | self.rootfs = os.path.join(self.testdir, d.getVar("IMAGE_LINK_NAME", True) + '-testimage.' + self.image_fstype) | 125 | self.rootfs = os.path.join(self.testdir, d.getVar("IMAGE_LINK_NAME", True) + '-testimage.' + self.image_fstype) |
126 | self.kernel = os.path.join(d.getVar("DEPLOY_DIR_IMAGE", True), d.getVar("KERNEL_IMAGETYPE", False) + '-' + d.getVar('MACHINE', False) + '.bin') | 126 | self.kernel = os.path.join(d.getVar("DEPLOY_DIR_IMAGE", True), d.getVar("KERNEL_IMAGETYPE", False) + '-' + d.getVar('MACHINE', False) + '.bin') |
127 | dump_target_cmds = d.getVar("testimage_dump_target", True) | ||
128 | dump_host_cmds = d.getVar("testimage_dump_host", True) | ||
129 | dump_dir = d.getVar("TESTIMAGE_DUMP_DIR", True) | ||
127 | 130 | ||
128 | # Log QemuRunner log output to a file | 131 | # Log QemuRunner log output to a file |
129 | import oe.path | 132 | import oe.path |
@@ -151,9 +154,11 @@ class QemuTarget(BaseTarget): | |||
151 | deploy_dir_image = d.getVar("DEPLOY_DIR_IMAGE", True), | 154 | deploy_dir_image = d.getVar("DEPLOY_DIR_IMAGE", True), |
152 | display = d.getVar("BB_ORIGENV", False).getVar("DISPLAY", True), | 155 | display = d.getVar("BB_ORIGENV", False).getVar("DISPLAY", True), |
153 | logfile = self.qemulog, | 156 | logfile = self.qemulog, |
154 | boottime = int(d.getVar("TEST_QEMUBOOT_TIMEOUT", True))) | 157 | boottime = int(d.getVar("TEST_QEMUBOOT_TIMEOUT", True)), |
158 | dump_dir = dump_dir, | ||
159 | dump_host_cmds = d.getVar("testimage_dump_host", True)) | ||
155 | 160 | ||
156 | self.target_dumper = TargetDumper(d, self.runner) | 161 | self.target_dumper = TargetDumper(dump_target_cmds, dump_dir, self.runner) |
157 | 162 | ||
158 | def deploy(self): | 163 | def deploy(self): |
159 | try: | 164 | try: |
diff --git a/meta/lib/oeqa/utils/dump.py b/meta/lib/oeqa/utils/dump.py index e71e1cd341..6067438e35 100644 --- a/meta/lib/oeqa/utils/dump.py +++ b/meta/lib/oeqa/utils/dump.py | |||
@@ -6,30 +6,22 @@ import itertools | |||
6 | from commands import runCmd | 6 | from commands import runCmd |
7 | 7 | ||
8 | def get_host_dumper(d): | 8 | def get_host_dumper(d): |
9 | return HostDumper(d) | 9 | cmds = d.getVar("testimage_dump_host", True) |
10 | parent_dir = d.getVar("TESTIMAGE_DUMP_DIR", True) | ||
11 | return HostDumper(cmds, parent_dir) | ||
10 | 12 | ||
11 | 13 | ||
12 | class BaseDumper(object): | 14 | class BaseDumper(object): |
13 | 15 | ||
14 | def __init__(self, d, cmds): | 16 | def __init__(self, cmds, parent_dir): |
15 | self.cmds = [] | 17 | self.cmds = [] |
16 | self.parent_dir = d.getVar("TESTIMAGE_DUMP_DIR", True) | 18 | self.parent_dir = parent_dir |
17 | if not cmds: | 19 | if not cmds: |
18 | return | 20 | return |
19 | for cmd in cmds.split('\n'): | 21 | for cmd in cmds.split('\n'): |
20 | cmd = cmd.lstrip() | 22 | cmd = cmd.lstrip() |
21 | if not cmd or cmd[0] == '#': | 23 | if not cmd or cmd[0] == '#': |
22 | continue | 24 | continue |
23 | # Replae variables from the datastore | ||
24 | while True: | ||
25 | index_start = cmd.find("${") | ||
26 | if index_start == -1: | ||
27 | break | ||
28 | index_start += 2 | ||
29 | index_end = cmd.find("}", index_start) | ||
30 | var = cmd[index_start:index_end] | ||
31 | value = d.getVar(var, True) | ||
32 | cmd = cmd.replace("${%s}" % var, value) | ||
33 | self.cmds.append(cmd) | 25 | self.cmds.append(cmd) |
34 | 26 | ||
35 | def create_dir(self, dir_suffix): | 27 | def create_dir(self, dir_suffix): |
@@ -62,9 +54,8 @@ class BaseDumper(object): | |||
62 | 54 | ||
63 | class HostDumper(BaseDumper): | 55 | class HostDumper(BaseDumper): |
64 | 56 | ||
65 | def __init__(self, d): | 57 | def __init__(self, cmds, parent_dir): |
66 | host_cmds = d.getVar("testimage_dump_host", True) | 58 | super(HostDumper, self).__init__(cmds, parent_dir) |
67 | super(HostDumper, self).__init__(d, host_cmds) | ||
68 | 59 | ||
69 | def dump_host(self, dump_dir=""): | 60 | def dump_host(self, dump_dir=""): |
70 | if dump_dir: | 61 | if dump_dir: |
@@ -76,9 +67,8 @@ class HostDumper(BaseDumper): | |||
76 | 67 | ||
77 | class TargetDumper(BaseDumper): | 68 | class TargetDumper(BaseDumper): |
78 | 69 | ||
79 | def __init__(self, d, qemurunner): | 70 | def __init__(self, cmds, parent_dir, qemurunner): |
80 | target_cmds = d.getVar("testimage_dump_target", True) | 71 | super(TargetDumper, self).__init__(cmds, parent_dir) |
81 | super(TargetDumper, self).__init__(d, target_cmds) | ||
82 | self.runner = qemurunner | 72 | self.runner = qemurunner |
83 | 73 | ||
84 | def dump_target(self, dump_dir=""): | 74 | def dump_target(self, dump_dir=""): |
diff --git a/meta/lib/oeqa/utils/qemurunner.py b/meta/lib/oeqa/utils/qemurunner.py index bcdb69b38c..4ce5d9c685 100644 --- a/meta/lib/oeqa/utils/qemurunner.py +++ b/meta/lib/oeqa/utils/qemurunner.py | |||
@@ -14,13 +14,14 @@ import socket | |||
14 | import select | 14 | import select |
15 | import errno | 15 | import errno |
16 | import threading | 16 | import threading |
17 | from oeqa.utils.dump import HostDumper | ||
17 | 18 | ||
18 | import logging | 19 | import logging |
19 | logger = logging.getLogger("BitBake.QemuRunner") | 20 | logger = logging.getLogger("BitBake.QemuRunner") |
20 | 21 | ||
21 | class QemuRunner: | 22 | class QemuRunner: |
22 | 23 | ||
23 | def __init__(self, machine, rootfs, display, tmpdir, deploy_dir_image, logfile, boottime): | 24 | def __init__(self, machine, rootfs, display, tmpdir, deploy_dir_image, logfile, boottime, dump_dir, dump_host_cmds): |
24 | 25 | ||
25 | # Popen object for runqemu | 26 | # Popen object for runqemu |
26 | self.runqemu = None | 27 | self.runqemu = None |
@@ -42,6 +43,7 @@ class QemuRunner: | |||
42 | self.thread = None | 43 | self.thread = None |
43 | 44 | ||
44 | self.runqemutime = 60 | 45 | self.runqemutime = 60 |
46 | self.host_dumper = HostDumper(dump_host_cmds, dump_dir) | ||
45 | 47 | ||
46 | def create_socket(self): | 48 | def create_socket(self): |
47 | try: | 49 | try: |
@@ -118,6 +120,7 @@ class QemuRunner: | |||
118 | if self.runqemu.returncode: | 120 | if self.runqemu.returncode: |
119 | # No point waiting any longer | 121 | # No point waiting any longer |
120 | logger.info('runqemu exited with code %d' % self.runqemu.returncode) | 122 | logger.info('runqemu exited with code %d' % self.runqemu.returncode) |
123 | self._dump_host() | ||
121 | self.stop() | 124 | self.stop() |
122 | logger.info("Output from runqemu:\n%s" % getOutput(output)) | 125 | logger.info("Output from runqemu:\n%s" % getOutput(output)) |
123 | return False | 126 | return False |
@@ -137,6 +140,7 @@ class QemuRunner: | |||
137 | self.server_ip = ips[1] | 140 | self.server_ip = ips[1] |
138 | except IndexError, ValueError: | 141 | except IndexError, ValueError: |
139 | logger.info("Couldn't get ip from qemu process arguments! Here is the qemu command line used:\n%s\nand output from runqemu:\n%s" % (cmdline, getOutput(output))) | 142 | logger.info("Couldn't get ip from qemu process arguments! Here is the qemu command line used:\n%s\nand output from runqemu:\n%s" % (cmdline, getOutput(output))) |
143 | self._dump_host() | ||
140 | self.stop() | 144 | self.stop() |
141 | return False | 145 | return False |
142 | logger.info("qemu cmdline used:\n{}".format(cmdline)) | 146 | logger.info("qemu cmdline used:\n{}".format(cmdline)) |
@@ -189,6 +193,7 @@ class QemuRunner: | |||
189 | lines = "\n".join(bootlog.splitlines()[-25:]) | 193 | lines = "\n".join(bootlog.splitlines()[-25:]) |
190 | logger.info("Last 25 lines of text:\n%s" % lines) | 194 | logger.info("Last 25 lines of text:\n%s" % lines) |
191 | logger.info("Check full boot log: %s" % self.logfile) | 195 | logger.info("Check full boot log: %s" % self.logfile) |
196 | self._dump_host() | ||
192 | self.stop() | 197 | self.stop() |
193 | return False | 198 | return False |
194 | 199 | ||
@@ -202,6 +207,7 @@ class QemuRunner: | |||
202 | 207 | ||
203 | else: | 208 | else: |
204 | logger.info("Qemu pid didn't appeared in %s seconds" % self.runqemutime) | 209 | logger.info("Qemu pid didn't appeared in %s seconds" % self.runqemutime) |
210 | self._dump_host() | ||
205 | self.stop() | 211 | self.stop() |
206 | logger.info("Output from runqemu:\n%s" % getOutput(output)) | 212 | logger.info("Output from runqemu:\n%s" % getOutput(output)) |
207 | return False | 213 | return False |
@@ -334,6 +340,13 @@ class QemuRunner: | |||
334 | status = 1 | 340 | status = 1 |
335 | return (status, str(data)) | 341 | return (status, str(data)) |
336 | 342 | ||
343 | |||
344 | def _dump_host(self): | ||
345 | self.host_dumper.create_dir("qemu") | ||
346 | logger.error("Qemu ended unexpectedly, dump data from host" | ||
347 | " is in %s" % self.host_dumper.dump_dir) | ||
348 | self.host_dumper.dump_host() | ||
349 | |||
337 | # This class is for reading data from a socket and passing it to logfunc | 350 | # This class is for reading data from a socket and passing it to logfunc |
338 | # to be processed. It's completely event driven and has a straightforward | 351 | # to be processed. It's completely event driven and has a straightforward |
339 | # event loop. The mechanism for stopping the thread is a simple pipe which | 352 | # event loop. The mechanism for stopping the thread is a simple pipe which |