def __init__( self, name, msg, args, log_dir, generate_tox_log, command_log, popen, python, suicide_timeout, interrupt_timeout, terminate_timeout, ): self.name = name self.args = args self.msg = msg self.activity = self.msg.split(" ", 1)[0] self.log_dir = log_dir self.generate_tox_log = generate_tox_log self.via_popen = popen self.command_log = command_log self._timed_report = None self.python = python self.suicide_timeout = suicide_timeout self.interrupt_timeout = interrupt_timeout self.terminate_timeout = terminate_timeout if is_main_thread(): # python allows only main thread to install signal handlers # see https://docs.python.org/3/library/signal.html#signals-and-threads self._install_sigterm_handler()
def evaluate_cmd(self, input_file_handler, process, redirect): try: if self.generate_tox_log and not redirect: if process.stderr is not None: # prevent deadlock raise ValueError("stderr must not be piped here") # we read binary from the process and must write using a binary stream buf = getattr(sys.stdout, "buffer", sys.stdout) last_time = time.time() while True: # we have to read one byte at a time, otherwise there # might be no output for a long time with slow tests data = input_file_handler.read(1) if data: buf.write(data) if b"\n" in data or (time.time() - last_time) > 1: # we flush on newlines or after 1 second to # provide quick enough feedback to the user # when printing a dot per test buf.flush() last_time = time.time() elif process.poll() is not None: if process.stdout is not None: process.stdout.close() break else: time.sleep(0.1) # the seek updates internal read buffers input_file_handler.seek(0, 1) input_file_handler.close() out, _ = process.communicate() # wait to finish except KeyboardInterrupt as exception: reporter.error("got KeyboardInterrupt signal") main_thread = is_main_thread() while True: try: if main_thread: # spin up a new thread to disable further interrupt on main thread stopper = Thread(target=self.handle_interrupt, args=(process, )) stopper.start() stopper.join() else: self.handle_interrupt(process) except KeyboardInterrupt: continue break raise exception return out