class IUTCtl: '''IUT Control Class''' def __init__(self, btpclient_path): """Constructor.""" log("%s.%s btpclient_path=%s", self.__class__, self.__init__.__name__, btpclient_path) self.btpclient_path = btpclient_path self.btp_socket = None self.iut_process = None def start(self): """Starts the IUT""" log("%s.%s", self.__class__, self.start.__name__) self.btp_socket = BTPWorker() self.btp_socket.open() iut_cmd = get_iut_cmd(self.btpclient_path) log("Starting IUT process: %s", iut_cmd) self.iut_process = subprocess.Popen(shlex.split(iut_cmd), shell=False, stdout=IUT_LOG_FO, stderr=IUT_LOG_FO) try: self.btp_socket.accept() except socket.timeout: log("IUT didn't connect!") self.stop() # self.wait_iut_ready_event() def wait_iut_ready_event(self): """Wait until IUT sends ready event after power up""" tuple_hdr, tuple_data = self.btp_socket.read() try: if (tuple_hdr.svc_id != defs.BTP_SERVICE_ID_CORE or tuple_hdr.op != defs.CORE_EV_IUT_READY): raise BTPError("Failed to get ready event") except BTPError as err: log("Unexpected event received (%s), expected IUT ready!", err) self.stop() else: log("IUT ready event received OK") def reset(self): """Reset IUT like removing all paired devices""" def stop(self): """Powers off the IUT""" log("%s.%s", self.__class__, self.stop.__name__) if self.btp_socket: self.btp_socket.close() self.btp_socket = None if self.iut_process and self.iut_process.poll() is None: self.iut_process.terminate() self.iut_process.wait() # do not let zombies take over self.iut_process = None
class MynewtCtl: """Mynewt OS Control Class""" def __init__(self, tty_file, board_name, use_rtt2pty=None): """Constructor.""" log("%s.%s tty_file=%s board_name=%s", self.__class__, self.__init__.__name__, tty_file, board_name) assert tty_file and board_name self.tty_file = tty_file self.board = Board(board_name, self) self.socat_process = None self.btp_socket = None self.test_case = None self.rtt2pty_process = None self.iut_log_file = None if use_rtt2pty: self.rtt2pty = RTT2PTY() else: self.rtt2pty = None def start(self, test_case): """Starts the Mynewt OS""" log("%s.%s", self.__class__, self.start.__name__) self.test_case = test_case self.iut_log_file = open(os.path.join(test_case.log_dir, "autopts-iutctl-mynewt.log"), "a") self.flush_serial() self.btp_socket = BTPWorker() self.btp_socket.open() socat_cmd = ("socat -x -v %s,rawer,b115200 UNIX-CONNECT:%s" % (self.tty_file, BTP_ADDRESS)) log("Starting socat process: %s", socat_cmd) # socat dies after socket is closed, so no need to kill it self.socat_process = subprocess.Popen(shlex.split(socat_cmd), shell=False, stdout=self.iut_log_file, stderr=self.iut_log_file) self.btp_socket.accept() def flush_serial(self): log("%s.%s", self.__class__, self.flush_serial.__name__) # Try to read data or timeout ser = serial.Serial(port=self.tty_file, baudrate=SERIAL_BAUDRATE, timeout=1) ser.read(99999) ser.close() def rtt2pty_start(self): if self.rtt2pty: self.rtt2pty.start(os.path.join(self.test_case.log_dir, 'iut-mynewt.log')) def rtt2pty_stop(self): if self.rtt2pty: self.rtt2pty.stop() def reset(self): """Restart IUT related processes and reset the IUT""" log("%s.%s", self.__class__, self.reset.__name__) self.stop() self.start(self.test_case) self.flush_serial() self.rtt2pty_stop() self.board.reset() def wait_iut_ready_event(self): """Wait until IUT sends ready event after power up""" self.reset() tuple_hdr, tuple_data = self.btp_socket.read() try: if (tuple_hdr.svc_id != defs.BTP_SERVICE_ID_CORE or tuple_hdr.op != defs.CORE_EV_IUT_READY): raise BTPError("Failed to get ready event") except BTPError as err: log("Unexpected event received (%s), expected IUT ready!", err) self.stop() raise err else: log("IUT ready event received OK") self.rtt2pty_start() def stop(self): """Powers off the Mynewt OS""" log("%s.%s", self.__class__, self.stop.__name__) if self.btp_socket: self.btp_socket.close() self.btp_socket = None if self.socat_process and self.socat_process.poll() is None: self.socat_process.terminate() self.socat_process.wait() if self.iut_log_file: self.iut_log_file.close() self.iut_log_file = None if self.rtt2pty: self.rtt2pty.stop() if self.socat_process: self.socat_process.terminate() self.socat_process.wait() self.socat_process = None
class ZephyrCtl: '''Zephyr OS Control Class''' def __init__(self, kernel_image, tty_file, board_name=None, use_rtt2pty=None): """Constructor.""" log("%s.%s kernel_image=%s tty_file=%s board_name=%s", self.__class__, self.__init__.__name__, kernel_image, tty_file, board_name) self.debugger_snr = None self.kernel_image = kernel_image self.tty_file = tty_file if self.tty_file and board_name: # DUT is a hardware board, not QEMU self.get_debugger_snr() self.board = Board(board_name, kernel_image, self) else: # DUT is QEMU or a board that won't be reset self.board = None self.qemu_process = None self.socat_process = None self.btp_socket = None self.test_case = None self.rtt2pty_process = None self.iut_log_file = None self.btp_address = BTP_ADDRESS + self.debugger_snr if use_rtt2pty: self.rtt2pty = RTT2PTY() self.btmon = BTMON() else: self.rtt2pty = None self.btmon = None def get_debugger_snr(self): debuggers = subprocess.Popen( 'nrfjprog --com', shell=True, stdout=subprocess.PIPE).stdout.read().decode() if sys.platform == "win32": COM = "COM" + str(int(self.tty_file["/dev/ttyS".__len__():]) + 1) reg = "[0-9]+(?=\s+" + COM + ".+)" else: reg = "[0-9]+(?=\s+" + self.tty_file + ".+)" try: self.debugger_snr = re.findall(reg, debuggers)[0] except: sys.exit("No debuggers associated with the device found") def start(self, test_case): """Starts the Zephyr OS""" log("%s.%s", self.__class__, self.start.__name__) self.test_case = test_case self.iut_log_file = open( os.path.join(test_case.log_dir, "autopts-iutctl-zephyr.log"), "a") self.flush_serial() self.btp_socket = BTPWorker() self.btp_socket.open(self.btp_address) if self.tty_file: if sys.platform == "win32": # On windows socat.exe does not support setting serial baud rate. # Set it with 'mode' from cmd.exe COM = "COM" + str( int(self.tty_file["/dev/ttyS".__len__():]) + 1) mode_cmd = (">nul 2>nul cmd.exe /c \"mode " + COM + "BAUD=115200 PARITY=n DATA=8 STOP=1\"") os.system(mode_cmd) socat_cmd = ( "socat.exe -x -v tcp:" + socket.gethostbyname(socket.gethostname()) + ":%s,retry=100,interval=1 %s,raw,b115200" % (self.btp_socket.sock.getsockname()[1], self.tty_file)) else: socat_cmd = ("socat -x -v %s,rawer,b115200 UNIX-CONNECT:%s" % (self.tty_file, self.btp_address)) log("Starting socat process: %s", socat_cmd) # socat dies after socket is closed, so no need to kill it self.socat_process = subprocess.Popen(shlex.split(socat_cmd), shell=False, stdout=self.iut_log_file, stderr=self.iut_log_file) else: qemu_cmd = get_qemu_cmd(self.kernel_image) log("Starting QEMU zephyr process: %s", qemu_cmd) # TODO check if zephyr process has started correctly self.qemu_process = subprocess.Popen(shlex.split(qemu_cmd), shell=False, stdout=self.iut_log_file, stderr=self.iut_log_file) self.btp_socket.accept() def flush_serial(self): log("%s.%s", self.__class__, self.flush_serial.__name__) # Try to read data or timeout try: ser = serial.Serial(port=self.tty_file, baudrate=SERIAL_BAUDRATE, timeout=1) ser.read(99999) ser.close() except serial.SerialException: pass def rtt2pty_start(self): if self.rtt2pty: self.rtt2pty.start( os.path.join(self.test_case.log_dir, 'iut-zephyr.log'), self.debugger_snr) def rtt2pty_stop(self): if self.rtt2pty: self.rtt2pty.stop() def btmon_start(self): if self.btmon: log_file = os.path.join( self.test_case.log_dir, self.test_case.name.replace('/', '_') + '_btmon.log') self.btmon.start(log_file, self.debugger_snr) def btmon_stop(self): if self.btmon: self.btmon.stop() def reset(self): """Restart IUT related processes and reset the IUT""" log("%s.%s", self.__class__, self.reset.__name__) self.stop() self.start(self.test_case) self.flush_serial() if not self.board: return self.btmon_stop() self.rtt2pty_stop() self.board.reset() def wait_iut_ready_event(self): """Wait until IUT sends ready event after power up""" self.reset() tuple_hdr, tuple_data = self.btp_socket.read() try: if (tuple_hdr.svc_id != defs.BTP_SERVICE_ID_CORE or tuple_hdr.op != defs.CORE_EV_IUT_READY): raise BTPError("Failed to get ready event") except BTPError as err: log("Unexpected event received (%s), expected IUT ready!", err) self.stop() else: log("IUT ready event received OK") self.rtt2pty_start() self.btmon_start() def stop(self): """Powers off the Zephyr OS""" log("%s.%s", self.__class__, self.stop.__name__) if self.btp_socket: self.btp_socket.close() self.btp_socket = None if self.qemu_process and self.qemu_process.poll() is None: self.qemu_process.terminate() self.qemu_process.wait() # do not let zombies take over self.qemu_process = None if self.iut_log_file: self.iut_log_file.close() self.iut_log_file = None if self.rtt2pty: self.rtt2pty.stop()
class MynewtCtl: '''Mynewt OS Control Class''' def __init__(self, kernel_image, tty_file, board_name=None): """Constructor.""" log("%s.%s kernel_image=%s tty_file=%s board_name=%s", self.__class__, self.__init__.__name__, kernel_image, tty_file, board_name) self.kernel_image = kernel_image self.tty_file = tty_file if self.tty_file and board_name: # DUT is a hardware board, not QEMU self.board = Board(board_name, kernel_image, tty_file) else: # DUT is QEMU or a board that won't be reset self.board = None self.qemu_process = None self.socat_process = None self.btp_socket = None def start(self): """Starts the Mynewt OS""" log("%s.%s", self.__class__, self.start.__name__) self.flush_serial() self.btp_socket = BTPWorker() self.btp_socket.open() socat_cmd = ("socat -x -v %s,rawer,b115200 UNIX-CONNECT:%s" % (self.tty_file, BTP_ADDRESS)) log("Starting socat process: %s", socat_cmd) # socat dies after socket is closed, so no need to kill it self.socat_process = subprocess.Popen(shlex.split(socat_cmd), shell=False, stdout=IUT_LOG_FO, stderr=IUT_LOG_FO) self.btp_socket.accept() def flush_serial(self): log("%s.%s", self.__class__, self.flush_serial.__name__) # Try to read data or timeout ser = serial.Serial(port=self.tty_file, baudrate=SERIAL_BAUDRATE, timeout=1) ser.read(99999) ser.close() def reset(self): """Restart IUT related processes and reset the IUT""" log("%s.%s", self.__class__, self.reset.__name__) self.stop() self.start() self.flush_serial() if not self.board: return self.board.reset() def wait_iut_ready_event(self): """Wait until IUT sends ready event after power up""" self.reset() tuple_hdr, tuple_data = self.btp_socket.read() try: if (tuple_hdr.svc_id != defs.BTP_SERVICE_ID_CORE or tuple_hdr.op != defs.CORE_EV_IUT_READY): raise BTPError("Failed to get ready event") except BTPError as err: log("Unexpected event received (%s), expected IUT ready!", err) self.stop() else: log("IUT ready event received OK") def stop(self): """Powers off the Mynewt OS""" log("%s.%s", self.__class__, self.stop.__name__) if self.btp_socket: self.btp_socket.close() self.btp_socket = None if self.socat_process and self.socat_process.poll() is None: self.socat_process.terminate() self.socat_process.wait()
class ZephyrCtl: '''Zephyr OS Control Class''' def __init__(self, kernel_image, tty_file, board_name=None): """Constructor.""" log("%s.%s kernel_image=%s tty_file=%s board_name=%s", self.__class__, self.__init__.__name__, kernel_image, tty_file, board_name) self.kernel_image = kernel_image self.tty_file = tty_file if self.tty_file and board_name: # DUT is a hardware board, not QEMU self.board = Board(board_name, kernel_image, tty_file) else: # DUT is QEMU or a board that won't be reset self.board = None self.qemu_process = None self.socat_process = None self.btp_socket = None def start(self): """Starts the Zephyr OS""" log("%s.%s", self.__class__, self.start.__name__) self.btp_socket = BTPWorker() self.btp_socket.open() if self.tty_file: socat_cmd = ("socat -x -v %s,rawer,b115200 UNIX-CONNECT:%s" % (self.tty_file, BTP_ADDRESS)) log("Starting socat process: %s", socat_cmd) # socat dies after socket is closed, so no need to kill it self.socat_process = subprocess.Popen(shlex.split(socat_cmd), shell=False, stdout=IUT_LOG_FO, stderr=IUT_LOG_FO) else: qemu_cmd = get_qemu_cmd(self.kernel_image) log("Starting QEMU zephyr process: %s", qemu_cmd) # TODO check if zephyr process has started correctly self.qemu_process = subprocess.Popen(shlex.split(qemu_cmd), shell=False, stdout=IUT_LOG_FO, stderr=IUT_LOG_FO) self.btp_socket.accept() def wait_iut_ready_event(self): """Wait until IUT sends ready event after power up""" if self.board: self.board.reset() tuple_hdr, tuple_data = self.btp_socket.read() try: if (tuple_hdr.svc_id != defs.BTP_SERVICE_ID_CORE or tuple_hdr.op != defs.CORE_EV_IUT_READY): raise BTPError("Failed to get ready event") except BTPError as err: log("Unexpected event received (%s), expected IUT ready!", err) self.stop() else: log("IUT ready event received OK") def stop(self): """Powers off the Zephyr OS""" log("%s.%s", self.__class__, self.stop.__name__) if self.btp_socket: self.btp_socket.close() self.btp_socket = None if self.qemu_process and self.qemu_process.poll() is None: self.qemu_process.terminate() self.qemu_process.wait() # do not let zombies take over self.qemu_process = None
class ZephyrCtl: '''Zephyr OS Control Class''' def __init__(self, kernel_image, tty_file, board_name=None, use_rtt2pty=None): """Constructor.""" log("%s.%s kernel_image=%s tty_file=%s board_name=%s", self.__class__, self.__init__.__name__, kernel_image, tty_file, board_name) self.kernel_image = kernel_image self.tty_file = tty_file if self.tty_file and board_name: # DUT is a hardware board, not QEMU self.board = Board(board_name, kernel_image, self) else: # DUT is QEMU or a board that won't be reset self.board = None self.qemu_process = None self.socat_process = None self.btp_socket = None self.test_case = None self.rtt2pty_process = None self.iut_log_file = None if use_rtt2pty: self.rtt2pty = RTT2PTY() else: self.rtt2pty = None def start(self, test_case): """Starts the Zephyr OS""" log("%s.%s", self.__class__, self.start.__name__) self.test_case = test_case self.iut_log_file = open( os.path.join(test_case.log_dir, "autopts-iutctl-zephyr.log"), "a") self.flush_serial() self.btp_socket = BTPWorker() self.btp_socket.open() if self.tty_file: socat_cmd = ("socat -x -v %s,rawer,b115200 UNIX-CONNECT:%s" % (self.tty_file, BTP_ADDRESS)) log("Starting socat process: %s", socat_cmd) # socat dies after socket is closed, so no need to kill it self.socat_process = subprocess.Popen(shlex.split(socat_cmd), shell=False, stdout=self.iut_log_file, stderr=self.iut_log_file) else: qemu_cmd = get_qemu_cmd(self.kernel_image) log("Starting QEMU zephyr process: %s", qemu_cmd) # TODO check if zephyr process has started correctly self.qemu_process = subprocess.Popen(shlex.split(qemu_cmd), shell=False, stdout=self.iut_log_file, stderr=self.iut_log_file) self.btp_socket.accept() def flush_serial(self): log("%s.%s", self.__class__, self.flush_serial.__name__) # Try to read data or timeout try: ser = serial.Serial(port=self.tty_file, baudrate=SERIAL_BAUDRATE, timeout=1) ser.read(99999) ser.close() except serial.SerialException: pass def rtt2pty_start(self): if self.rtt2pty: self.rtt2pty.start( os.path.join(self.test_case.log_dir, 'iut-zephyr.log')) def rtt2pty_stop(self): if self.rtt2pty: self.rtt2pty.stop() def reset(self): """Restart IUT related processes and reset the IUT""" log("%s.%s", self.__class__, self.reset.__name__) self.stop() self.start(self.test_case) self.flush_serial() if not self.board: return self.rtt2pty_stop() self.board.reset() def wait_iut_ready_event(self): """Wait until IUT sends ready event after power up""" self.reset() tuple_hdr, tuple_data = self.btp_socket.read() try: if (tuple_hdr.svc_id != defs.BTP_SERVICE_ID_CORE or tuple_hdr.op != defs.CORE_EV_IUT_READY): raise BTPError("Failed to get ready event") except BTPError as err: log("Unexpected event received (%s), expected IUT ready!", err) self.stop() else: log("IUT ready event received OK") self.rtt2pty_start() def stop(self): """Powers off the Zephyr OS""" log("%s.%s", self.__class__, self.stop.__name__) if self.btp_socket: self.btp_socket.close() self.btp_socket = None if self.qemu_process and self.qemu_process.poll() is None: self.qemu_process.terminate() self.qemu_process.wait() # do not let zombies take over self.qemu_process = None if self.iut_log_file: self.iut_log_file.close() self.iut_log_file = None if self.rtt2pty: self.rtt2pty.stop()
class ZephyrCtl: """Zephyr OS Control Class""" def __init__(self, args): """Constructor.""" log("%s.%s kernel_image=%s tty_file=%s board_name=%s", self.__class__, self.__init__.__name__, args.kernel_image, args.tty_file, args.board_name) self.debugger_snr = args.debugger_snr self.kernel_image = args.kernel_image self.tty_file = args.tty_file self.hci = args.hci self.native = None if self.tty_file and args.board_name: # DUT is a hardware board, not QEMU if self.debugger_snr is None: self.debugger_snr = get_debugger_snr(self.tty_file) self.board = Board(args.board_name, self) else: # DUT is QEMU or a board that won't be reset self.board = None self.qemu_process = None self.native_process = None self.socat_process = None self.btp_socket = None self.test_case = None self.iut_log_file = None self.rtt_logger = None self.btmon = None if self.debugger_snr: self.btp_address = BTP_ADDRESS + self.debugger_snr self.rtt_logger = RTT() if args.rtt_log else None self.btmon = BTMON() if args.btmon else None else: self.btp_address = BTP_ADDRESS def start(self, test_case): """Starts the Zephyr OS""" log("%s.%s", self.__class__, self.start.__name__) self.test_case = test_case self.iut_log_file = open( os.path.join(test_case.log_dir, "autopts-iutctl-zephyr.log"), "a") self.flush_serial() self.btp_socket = BTPWorker() self.btp_socket.open(self.btp_address) if self.tty_file: if sys.platform == "win32": # On windows socat.exe does not support setting serial baud rate. # Set it with 'mode' from cmd.exe com = tty_to_com(self.tty_file) mode_cmd = (">nul 2>nul cmd.exe /c \"mode " + com + "BAUD=115200 PARITY=n DATA=8 STOP=1\"") os.system(mode_cmd) socat_cmd = ( "socat.exe -x -v tcp:" + socket.gethostbyname(socket.gethostname()) + ":%s,retry=100,interval=1 %s,raw,b115200" % (self.btp_socket.sock.getsockname()[1], self.tty_file)) else: socat_cmd = ("socat -x -v %s,rawer,b115200 UNIX-CONNECT:%s" % (self.tty_file, self.btp_address)) log("Starting socat process: %s", socat_cmd) # socat dies after socket is closed, so no need to kill it self.socat_process = subprocess.Popen(shlex.split(socat_cmd), shell=False, stdout=self.iut_log_file, stderr=self.iut_log_file) elif self.hci is not None: socat_cmd = ("socat -x -v %%s,rawer,b115200 UNIX-CONNECT:%s &" % self.btp_address) native_cmd = ("%s --bt-dev=hci%d --attach_uart_cmd=\"%s\"" % (self.kernel_image, self.hci, socat_cmd)) log("Starting native zephyr process: %s", native_cmd) # TODO check if zephyr process has started correctly self.native_process = subprocess.Popen(shlex.split(native_cmd), shell=False, stdout=self.iut_log_file, stderr=self.iut_log_file) else: qemu_cmd = get_qemu_cmd(self.kernel_image) log("Starting QEMU zephyr process: %s", qemu_cmd) # TODO check if zephyr process has started correctly self.qemu_process = subprocess.Popen(shlex.split(qemu_cmd), shell=False, stdout=self.iut_log_file, stderr=self.iut_log_file) self.btp_socket.accept() def flush_serial(self): log("%s.%s", self.__class__, self.flush_serial.__name__) # Try to read data or timeout try: if sys.platform == 'win32': tty = tty_to_com(self.tty_file) else: tty = self.tty_file ser = serial.Serial(port=tty, baudrate=SERIAL_BAUDRATE, timeout=1) ser.read(99999) ser.close() except serial.SerialException: pass def btmon_start(self): if self.btmon: log_file = os.path.join( self.test_case.log_dir, self.test_case.name.replace('/', '_') + '_btmon.log') self.btmon.start(log_file, self.debugger_snr) def btmon_stop(self): if self.btmon: self.btmon.stop() def rtt_logger_start(self): if self.rtt_logger: log_file = os.path.join( self.test_case.log_dir, self.test_case.name.replace('/', '_') + '_iutctl.log') self.rtt_logger.start('Logger', log_file, self.debugger_snr) def rtt_logger_stop(self): if self.rtt_logger: self.rtt_logger.stop() def reset(self): """Restart IUT related processes and reset the IUT""" log("%s.%s", self.__class__, self.reset.__name__) self.stop() self.start(self.test_case) self.flush_serial() if not self.board: return self.rtt_logger_stop() self.btmon_stop() self.board.reset() def wait_iut_ready_event(self): """Wait until IUT sends ready event after power up""" self.reset() tuple_hdr, tuple_data = self.btp_socket.read() try: if (tuple_hdr.svc_id != defs.BTP_SERVICE_ID_CORE or tuple_hdr.op != defs.CORE_EV_IUT_READY): raise BTPError("Failed to get ready event") except BTPError as err: log("Unexpected event received (%s), expected IUT ready!", err) self.stop() else: log("IUT ready event received OK") self.rtt_logger_start() self.btmon_start() def stop(self): """Powers off the Zephyr OS""" log("%s.%s", self.__class__, self.stop.__name__) if self.btp_socket: self.btp_socket.close() self.btp_socket = None if self.native_process and self.native_process.poll() is None: self.native_process.terminate() self.native_process.wait() # do not let zombies take over self.native_process = None if self.qemu_process and self.qemu_process.poll() is None: time.sleep(1) self.qemu_process.terminate() self.qemu_process.wait() # do not let zombies take over self.qemu_process = None if self.iut_log_file: self.iut_log_file.close() self.iut_log_file = None self.rtt_logger_stop() self.btmon_stop() if self.socat_process: self.socat_process.terminate() self.socat_process.wait() self.socat_process = None