summaryrefslogtreecommitdiffstats
path: root/meta/lib/oeqa/utils/qemurunner.py
diff options
context:
space:
mode:
Diffstat (limited to 'meta/lib/oeqa/utils/qemurunner.py')
-rw-r--r--meta/lib/oeqa/utils/qemurunner.py40
1 files changed, 24 insertions, 16 deletions
diff --git a/meta/lib/oeqa/utils/qemurunner.py b/meta/lib/oeqa/utils/qemurunner.py
index cda43aad8c..c4db0cf038 100644
--- a/meta/lib/oeqa/utils/qemurunner.py
+++ b/meta/lib/oeqa/utils/qemurunner.py
@@ -30,6 +30,8 @@ control_range = list(range(0,32))+list(range(127,160))
30control_chars = [chr(x) for x in control_range 30control_chars = [chr(x) for x in control_range
31 if chr(x) not in string.printable] 31 if chr(x) not in string.printable]
32re_control_char = re.compile('[%s]' % re.escape("".join(control_chars))) 32re_control_char = re.compile('[%s]' % re.escape("".join(control_chars)))
33# Regex to remove the ANSI (color) control codes from console strings in order to match the text only
34re_vt100 = re.compile(r'(\x1b\[|\x9b)[^@-_a-z]*[@-_a-z]|\x1b[@-_a-z]')
33 35
34def getOutput(o): 36def getOutput(o):
35 import fcntl 37 import fcntl
@@ -101,7 +103,7 @@ class QemuRunner:
101 103
102 # Only override patterns that were set e.g. login user TESTIMAGE_BOOT_PATTERNS[send_login_user] = "webserver\n" 104 # Only override patterns that were set e.g. login user TESTIMAGE_BOOT_PATTERNS[send_login_user] = "webserver\n"
103 for pattern in accepted_patterns: 105 for pattern in accepted_patterns:
104 if not self.boot_patterns[pattern]: 106 if pattern not in self.boot_patterns or not self.boot_patterns[pattern]:
105 self.boot_patterns[pattern] = default_boot_patterns[pattern] 107 self.boot_patterns[pattern] = default_boot_patterns[pattern]
106 108
107 def create_socket(self): 109 def create_socket(self):
@@ -265,12 +267,15 @@ class QemuRunner:
265 self.monitorpipe = os.fdopen(w, "w") 267 self.monitorpipe = os.fdopen(w, "w")
266 else: 268 else:
267 # child process 269 # child process
268 os.setpgrp() 270 try:
269 os.close(w) 271 os.setpgrp()
270 r = os.fdopen(r) 272 os.close(w)
271 x = r.read() 273 r = os.fdopen(r)
272 os.killpg(os.getpgid(self.runqemu.pid), signal.SIGTERM) 274 x = r.read()
273 os._exit(0) 275 os.killpg(os.getpgid(self.runqemu.pid), signal.SIGTERM)
276 finally:
277 # We must exit under all circumstances
278 os._exit(0)
274 279
275 self.logger.debug("runqemu started, pid is %s" % self.runqemu.pid) 280 self.logger.debug("runqemu started, pid is %s" % self.runqemu.pid)
276 self.logger.debug("waiting at most %d seconds for qemu pid (%s)" % 281 self.logger.debug("waiting at most %d seconds for qemu pid (%s)" %
@@ -519,7 +524,6 @@ class QemuRunner:
519 except Exception as e: 524 except Exception as e:
520 self.logger.warning('Extra log data exception %s' % repr(e)) 525 self.logger.warning('Extra log data exception %s' % repr(e))
521 data = None 526 data = None
522 self.thread.serial_lock.release()
523 return False 527 return False
524 528
525 with self.thread.serial_lock: 529 with self.thread.serial_lock:
@@ -533,7 +537,7 @@ class QemuRunner:
533 self.logger.debug("Logged in as %s in serial console" % self.boot_patterns['send_login_user'].replace("\n", "")) 537 self.logger.debug("Logged in as %s in serial console" % self.boot_patterns['send_login_user'].replace("\n", ""))
534 if netconf: 538 if netconf:
535 # configure guest networking 539 # configure guest networking
536 cmd = "ifconfig eth0 %s netmask %s up\n" % (self.ip, self.netmask) 540 cmd = "ip addr add %s/%s dev eth0\nip link set dev eth0 up\n" % (self.ip, self.netmask)
537 output = self.run_serial(cmd, raw=True)[1] 541 output = self.run_serial(cmd, raw=True)[1]
538 if re.search(r"root@[a-zA-Z0-9\-]+:~#", output): 542 if re.search(r"root@[a-zA-Z0-9\-]+:~#", output):
539 self.logger.debug("configured ip address %s", self.ip) 543 self.logger.debug("configured ip address %s", self.ip)
@@ -681,7 +685,7 @@ class QemuRunner:
681 time.sleep(0.1) 685 time.sleep(0.1)
682 answer = self.server_socket.recv(1024) 686 answer = self.server_socket.recv(1024)
683 if answer: 687 if answer:
684 data += answer.decode('utf-8') 688 data += re_vt100.sub("", answer.decode('utf-8'))
685 # Search the prompt to stop 689 # Search the prompt to stop
686 if re.search(self.boot_patterns['search_cmd_finished'], data): 690 if re.search(self.boot_patterns['search_cmd_finished'], data):
687 break 691 break
@@ -745,8 +749,10 @@ class LoggingThread(threading.Thread):
745 def threadtarget(self): 749 def threadtarget(self):
746 try: 750 try:
747 self.eventloop() 751 self.eventloop()
748 except Exception as e: 752 except Exception:
749 self.logger.warning("Exception %s in logging thread" % traceback.format_exception(e)) 753 exc_type, exc_value, exc_traceback = sys.exc_info()
754 self.logger.warning("Exception %s in logging thread" %
755 traceback.format_exception(exc_type, exc_value, exc_traceback))
750 finally: 756 finally:
751 self.teardown() 757 self.teardown()
752 758
@@ -822,10 +828,12 @@ class LoggingThread(threading.Thread):
822 self.logfunc(data, ".stdout") 828 self.logfunc(data, ".stdout")
823 elif self.serialsock and self.serialsock.fileno() == fd: 829 elif self.serialsock and self.serialsock.fileno() == fd:
824 if self.serial_lock.acquire(blocking=False): 830 if self.serial_lock.acquire(blocking=False):
825 data = self.recv(1024, self.serialsock) 831 try:
826 self.logger.debug("Data received serial thread %s" % data.decode('utf-8', 'replace')) 832 data = self.recv(1024, self.serialsock)
827 self.logfunc(data, ".2") 833 self.logger.debug("Data received serial thread %s" % data.decode('utf-8', 'replace'))
828 self.serial_lock.release() 834 self.logfunc(data, ".2")
835 finally:
836 self.serial_lock.release()
829 else: 837 else:
830 serial_registered = False 838 serial_registered = False
831 poll.unregister(self.serialsock.fileno()) 839 poll.unregister(self.serialsock.fileno())