diff options
Diffstat (limited to 'meta/lib/oeqa/utils')
-rw-r--r-- | meta/lib/oeqa/utils/dump.py | 28 | ||||
-rw-r--r-- | meta/lib/oeqa/utils/qemurunner.py | 15 |
2 files changed, 23 insertions, 20 deletions
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 |