def expect_all(self, pattern_list: List[str], timeout: float = 10, strict: bool = True) -> None: """ Wait for all patterns appear in process output. :param pattern_list: list of string to expect :param timeout: timeout in seconds :param strict: if non strict, it allows regular expression :return: None """ pattern_list = list(pattern_list) start_time = time.time() while pattern_list: time_spent = time.time() - start_time if time_spent > timeout: raise TIMEOUT(timeout) if strict: idx = self.expect_exact(pattern_list, timeout - time_spent) else: idx = self.expect(pattern_list, timeout - time_spent) pattern_list.pop(idx)
def read_valid(self, size, timeout=1): t0 = time.time() while True: res = self.read_nonblocking(size, timeout) if res: return res elif time.time() - t0 > timeout: raise TIMEOUT("Read valid data timeout " + str(timeout)) time.sleep(0.01)
def _wait(self, timeout=5): try: self.process.expect(EOF, timeout=timeout) except TIMEOUT: raise Failure(_("timed out while waiting for program to exit")) from TIMEOUT(timeout) except UnicodeDecodeError: raise Failure(_("output not valid ASCII text")) self.kill() if self.process.signalstatus == signal.SIGSEGV: raise Failure(_("failed to execute program due to segmentation fault")) self.exitcode = self.process.exitstatus return self
def wait(self, timeout=5): try: self.child.expect(EOF, timeout=timeout) except TIMEOUT: e = Error("timed out while waiting for program to exit") e.__context__ = TIMEOUT(timeout) raise e except UnicodeDecodeError: raise Error("output not valid ASCII text") self.kill() if self.child.signalstatus == signal.SIGSEGV: raise Error("failed to execute program due to segmentation fault") self.exitstatus = self.child.exitstatus return self
def expect_all(self, pattern_list: List[str], timeout: float = 10) -> None: """ Wait for all patterns appear in process output. :param pattern_list: list of string to expect :param timeout: timeout in seconds :return: None """ pattern_list = list(pattern_list) start_time = time.time() while pattern_list: time_spent = time.time() - start_time if time_spent > timeout: raise TIMEOUT(timeout) idx = self.expect_exact(pattern_list, timeout - time_spent) pattern_list.pop(idx)
def wait(self, timeout=5): end = time.time() + timeout while time.time() <= end: if not self.child.isalive(): break try: bytes = self.child.read_nonblocking(size=1024, timeout=0) except TIMEOUT: pass except EOF: break except UnicodeDecodeError: raise Error("output not valid ASCII text") else: self.output.append(bytes) else: e = Error("timed out while waiting for program to exit") e.__context__ = TIMEOUT(timeout) raise e # Read any remaining data in pipe. while True: try: bytes = self.child.read_nonblocking(size=1024, timeout=0) except (TIMEOUT, EOF): break else: self.output.append(bytes) self.output = "".join(self.output).replace("\r\n", "\n").lstrip("\n") self.kill() if self.child.signalstatus == signal.SIGSEGV: raise Error("failed to execute program due to segmentation fault") self.exitstatus = self.child.exitstatus return self
def send(self, s, pattern=[], timeout=-1, attempt=1, regex=False, verbose=False): '''Overrides send from parent class, added ability to include expected patterns, expected timeout, retry attempts, and matching with/without regular expressions. In addition to the class variables pexpect sets, self.before self.after self.match self.match_index self.buffer this function returns additional variables, self.full_buffer - full buffer of the command including the command and the prompt self.output - output from the command excluding the command and the prompt :param - s :param - pattern (default []) :param - timeout (default -1, when set to -1, it uses class default of 30s) :param - attempt (default 1) :param - regex (default True) :return - match index from pattern list (returns None if no match) ''' self.before = None self.after = None self.match = None self.match_index = None self.buffer = bytes() if self.encoding is None else text_type() self.full_buffer = None self.output = None if attempt < 1: attempt = 1 # Create bytes and string representation of s # b = s # if type(s) == str: # b = s.encode('utf-8') # elif type(s) == bytes: # s = s.decode('utf-8') # Retry specified attempts before raising exception for i in range(attempt): if verbose: if i == 0: log.log( CONSOLE, '{}/{} attempt :\t"{}"\tpattern="{}"'.format( i + 1, attempt, s.strip(), pattern)) else: log.log( CONSOLE, '{}/{} attempts:\t"{}"\tpattern="{}"'.format( i + 1, attempt, s.strip(), pattern)) super(Connection, self).send(s) if pattern: try: if regex: super(Connection, self).expect(pattern, timeout=timeout) else: super(Connection, self).expect_exact(pattern, timeout=timeout) if isinstance(self.after, str): # For python3, the buffer read is byte type and need to be converted to string type # Reference: https://stackoverflow.com/questions/606191/convert-bytes-to-a-string/ # This implementation is backward compatible with python2 # self.full_buffer = self.before.decode('utf-8') + self.after.decode('utf-8') + self.buffer.decode('utf-8') self.full_buffer = self.before + self.after + self.buffer self.output = self.full_buffer if '\n' in self.output: self.output = self.output.rsplit( '\n', 1 )[0] # Remove the last line (contains prompt) from output self.output = self.output.replace(s.strip( ), '', 1).replace('\n', '', 1).replace( '\r', '', 1 ) # Remove the first line (contains command s) from full buffer if verbose: log.debug('s "{}"'.format(s)) log.debug( '1 match "{}"'.format(self.match if isinstance( self.match, str) else self.match.group(0))) log.debug('2 before "{}"'.format(self.before)) log.debug('3 after "{}"'.format(self.after)) log.debug('4 buffer "{}"'.format(self.buffer)) log.debug('5 output "{}"'.format(self.output)) log.debug('6 full_buffer "{}"'.format( self.full_buffer)) log.debug('7 prompt "{}"'.format(self.PROMPT)) break except TIMEOUT: if isinstance(self.buffer, str): # For python3, the buffer read is byte type and need to be converted to string type # Reference: https://stackoverflow.com/questions/606191/convert-bytes-to-a-string # This implementation is backward compatible with python2 # self.full_buffer = self.buffer.decode('utf-8') self.full_buffer = self.buffer self.output = self.full_buffer if '\n' in self.output: self.output = self.output.rsplit( '\n', 1 )[0] # Remove the last line (contains prompt) from output self.output = self.output.replace(s.strip( ), '', 1).replace('\n', '', 1).replace( '\r', '', 1 ) # Remove the first line (contains command s) from full buffer if verbose: log.debug('s "{}"'.format(s)) # log.debug('1 match "{}"'.format(self.match if isinstance(self.match, str) else self.match.group(0))) log.debug('2 before "{}"'.format(self.before)) log.debug('3 after "{}"'.format(self.after)) log.debug('4 buffer "{}"'.format(self.buffer)) log.debug('5 output "{}"'.format(self.output)) # log.debug('6 full_buffer "{}"'.format(self.full_buffer)) # log.debug('7 prompt "{}"'.format(self.PROMPT)) if i + 1 >= attempt: if self.verbose: if i == 0: log.exception( 'Raise TIMEOUT exception after {} attempt'. format(attempt)) else: log.exception( 'Raise TIMEOUT exception after {} attempts' .format(attempt)) raise TIMEOUT(ExceptionPexpect) return self.match_index