def read_nonblocking(self, size=1, timeout=None): """ This reads at most size characters from the child application. It includes a timeout. If the read does not complete within the timeout period then a TIMEOUT exception is raised. If the end of file is read then an EOF exception will be raised. If a log file was set using setlog() then all data will also be written to the log file. Notice that if this method is called with timeout=None then it actually may block. This is a non-blocking wrapper around os.read(). It uses select.select() to implement a timeout. """ if self.child_fd == -1: raise ValueError('I/O operation on closed file') # Note that some systems like Solaris don't seem to ever give # an EOF when the child dies. In fact, you can still try to read # from the child_fd -- it will block forever or until TIMEOUT. # For this case, I test isalive() before doing any reading. # If isalive() is false, then I pretend that this is the same as EOF. if not self.isalive(): r, w, e = select.select([self.child_fd], [], [], 0) if not r: self.flag_eof = 1 raise pexpect.EOF( 'End Of File (EOF) in read(). Braindead platform.') timeout = 5.0 r, w, e = select.select([self.child_fd], [], [], timeout) if not r: print('Timeout (%s) exceeded in read().' % str(timeout)) raise pexpect.TIMEOUT('Timeout (%s) exceeded in read().' % str(timeout)) if self.child_fd in r: try: s = self.child_fd.recv(size) # s = os.read(self.child_fd, size) except OSError, e: self.flag_eof = 1 raise pexpect.EOF( 'End Of File (EOF) in read(). Exception style platform.') if s == '': self.flag_eof = 1 raise pexpect.EOF( 'End Of File (EOF) in read(). Empty string style platform.' ) if self.log_file != None: self.log_file.write(s) self.log_file.flush() if hasattr(self, 'console'): self.console.send(s) return s
def setUp(self): self.patchers = [] self.patchers.append( patch('pygatt.backends.gatttool.gatttool.pexpect.spawn')) self.spawn = self.patchers[0].start() self.spawn.return_value.isalive.return_value = False self.spawn.return_value.read_nonblocking.side_effect = ( pexpect.EOF(value=None)) self.patchers.append( patch('pygatt.backends.gatttool.gatttool.subprocess')) self.patchers[1].start() # Just keep saying we got the "Connected" response def rate_limited_expect(*args, **kwargs): # Sleep a little bit to stop the receive thread from spinning and # eating 100% CPU during the tests time.sleep(0.001) # This is hacky, but we sort the event list in the GATTTool receiver # and hard code where we expect the "Connected" event to be. return 4 self.spawn.return_value.expect.side_effect = rate_limited_expect self.backend = GATTToolBackend() self.backend.start()
def update_vsd_domain(vsc_host, username, password, vsd_domain): import pexpect try: ssh_newkey = 'Are you sure you want to continue connecting' child = pexpect.spawn('ssh %s@%s -o ConnectTimeout=1500' ' -o ConnectionAttempts=300' % (username, vsc_host), timeout=1500) log('ssh %s@%s' % (username, vsc_host)) i = child.expect([ssh_newkey, 'password:'******'yes') i = child.expect([ssh_newkey, 'password:', pexpect.EOF]) if i == 1: child.sendline(password) elif i == 2: child.close() raise pexpect.EOF("End of file error") elif i == 3: # timeout child.close() raise pexpect.TIMEOUT("Got a connection timeout") child.sendline("\r") child.sendline("configure vswitch-controller xmpp-server \"{}\"" .format(vsd_domain)) child.sendline("logout") child.close() except pexpect.ExceptionPexpect as e: log("Got an exception: traceback %s" % e.get_trace()) except Exception as e: log("Got a generic exception: %s" % e.strerror) else: log("Failed to update vsd domain in VSD") finally: log("Exiting update_vsd_domain")
def match_id(self): try: mid = self.expect(self.match_list, timeout=self.timeout) if mid == 4 or mid > 4: raise pexpect.EOF('metch_id Error') return mid except: return 9
def test_eof_exception(self): mocked_process = Mock() mocked_process.expect.side_effect = pexpect.EOF('') c = BaseCommand() c._build_command_string = lambda: '' self.assertRaises(LinphoneEOFException, c.execute, mocked_process)
def expect_side_effect(patterns, *args, **kwargs): nonlocal matched_prompt if isinstance(patterns, list): for pattern in patterns: if re.match(pattern, "Password:"): matched_prompt = True raise pexpect.EOF(Mock()) else: return 0 # pexpect returns 0 on a successful match
def expect_loop(self, searcher, timeout=-1, searchwindowsize=-1): ''' Using print_verbose, to get realtime output. Everything else is from pexpect.expect_loop. ''' self.searcher = searcher if timeout == -1: timeout = self.timeout if timeout is not None: end_time = time.time() + timeout if searchwindowsize == -1: searchwindowsize = self.searchwindowsize try: incoming = self.buffer freshlen = len(incoming) while True: # Keep reading until exception or return. app.print_verbose(incoming[-freshlen:], self.verbose_level, new_line=False, enable_caption=False) index = searcher.search(incoming, freshlen, searchwindowsize) if index >= 0: self.buffer = incoming[searcher.end:] self.before = incoming[:searcher.start] self.after = incoming[searcher.start:searcher.end] self.match = searcher.match self.match_index = index return self.match_index # No match at this point if timeout < 0 and timeout is not None: raise pexpect.TIMEOUT('Timeout exceeded in expect_any().') # Still have time left, so read more data c = self.read_nonblocking(self.maxread, timeout) freshlen = len(c) time.sleep(0.0001) incoming = incoming + c if timeout is not None: timeout = end_time - time.time() except pexpect.EOF, e: self.buffer = '' self.before = incoming self.after = pexpect.EOF index = searcher.eof_index if index >= 0: self.match = pexpect.EOF self.match_index = index return self.match_index else: self.match = None self.match_index = None raise pexpect.EOF(str(e) + '\n' + str(self))
def read_nonblocking(self, size=1, timeout=None): """See parent. This actually may or may not block based on timeout.""" if not self.isalive(): raise pexpect.EOF('End Of File (EOF) in read() - Not alive.') if timeout == -1: timeout = self.timeout self.channel.settimeout(timeout) try: s = self.channel.recv(size) except socket.timeout: raise pexpect.TIMEOUT('Timeout (%s) exceeded in read().' % timeout) except paramiko.SSHException as e: raise pexpect.EOF('Paramiko exception: %s' % e) except EOFError: raise pexpect.EOF('Paramiko reported End Of File (EOF) in read()') if not s: self.flag_eof = 1 raise pexpect.EOF('End Of File (EOF) in read().') return s
def read_nonblocking(self, size=-1, timeout=-1): if self.child_fd == -1: raise ValueError('I/O operation on closed file') if not self.isalive(): r, w, e = select.select([self.child_fd], [], [], 0) if not r: self.flag_eof = True raise pexpect.EOF('End Of File (EOF) in read(). ' 'Braindead platform.') if timeout == -1: timeout = self.timeout r, w, e = select.select([self.child_fd], [], [], timeout) if not r: raise pexpect.TIMEOUT('Timeout (%s) exceeded in read().' % str(timeout)) if self.child_fd in r: try: s = self.child_fd.recv(size) except OSError as e: self.flag_eof = True raise pexpect.EOF('End Of File (EOF) in read(). ' 'Exception style platform.') if s == '': self.flag_eof = True raise pexpect.EOF('End Of File (EOF) in read(). ' 'Empty string style platform.') if self.logfile is not None: self.logfile.write(s) self.logfile.flush() return s raise pexpect.ExceptionPexpect( 'Reached an unexpected state in read().')
def login(host, user, password): conn = pexpect.spawn( 'ssh -oKexAlgorithms=diffie-hellman-group1-sha1 {}@{}'.format( user, host), timeout=5) try: conn.expect('[Pp]assword:') except pexpect.EOF as e: raise pexpect.EOF( 'Connection closed while waiting for password prompt. ' 'SSH message:\n' + conn.before) except pexpect.TIMEOUT as e: raise pexpect.TIMEOUT( 'Connection timed out while waiting for password prompt! ' 'SSH message:\n' + conn.before) else: conn.sendline(password) index2 = conn.expect([ CiscoCmdline.prompt, '[Pp]assword:', ]) if index2 == 0: # Do some magic so any commands called later won't demand # pressing space or enter. conn.sendline('terminal length 0') conn.expect(CiscoCmdline.prompt) return conn elif index2 == 1: raise pexpect.EOF( 'Device refused login, probably wrong password. Giving up!')
def test_open_EOFError(self, mock_expect, mock_spawn): ''' Test pyiosxr class open - raising pexpect.EOF Should return EOFError ''' device = IOSXR(hostname='hostname', username='******', password='******', port=22, timeout=60, logfile=None, lock=True) mock_spawn.return_value = None mock_expect.side_effect = pexpect.EOF('error') self.assertRaises(EOFError, device.open)
def _start(domain, timeout): domain.logger.info("starting domain") # Do not call this when the console is functional! console = domain.console() if console: raise pexpect.EOF("console for domain %s already open" % domain) # Bring the machine up from scratch. end_time = time.time() + timeout first_attempt = True while console == None: if time.time() > end_time: raise pexpect.EOF("trying to start domain %s" % domain) status, output = domain.start() if status and first_attempt: # The first attempt at starting the domain _must_ succeed. # Failing is a sign that the domain was running. Further # attempts might fail as things get racey. raise pexpect.EOF("failed to start domain %s" % output) # give the VM time to start and then try opening the console. time.sleep(1) console = domain.console() first_attempt = False domain.logger.debug("got console") return console
def read_nonblocking(self, size=1, timeout=None): timeout = timeout if timeout is not None and timeout >= 0 else None LOGGER.debug('read_nonblocking, size=%d', size) if not self._serverprocess.is_alive(): raise pexpect.EOF('Python terminal closed') if self._raise_timeout_in_read: time.sleep(0.01) raise pexpect.TIMEOUT('Timeout') rlist = [self.child_fd] LOGGER.info('Waiting for %s in select with timeout %s', rlist, timeout) r, _, _ = select.select(rlist, [], [], timeout) if not r: raise pexpect.TIMEOUT('Timeout in read_nonblocking') LOGGER.info('Calling super read_nonblocking') ret = super(ServerTerminal, self).read_nonblocking(size, timeout=timeout) LOGGER.debug('Read %s, type=%s, first=%s', ret, type(ret), ret[0] if ret else '') return ret
def process_reader(self): while True: self._active.wait() self.start() try: r = self._process.expect([r"delay \= (\d+)", ".+"]) if r == 0: delay = self._process.match.groups()[0].decode() self.delay_changed.emit(delay) else: msg = self._process.match.string.decode() if AudioProcess.NOT_EMPTY.search(msg): self.log_message.emit(msg) if not self._process.isalive(): raise pexpect.EOF('Process died after start.') self._fails = 0 except: self._fails += 1 print("{} failed ({}) :(".format(self._command, self._fails)) sleep(self.sleepTime)
def getPrompt(self, timeout=-1, idleTimeout=60): timeoutAttemptCount = 1 notIdleRetryCount = 1 wrongPasswordCount = 1 maxNotIdleRetryCount = 15 out = '' self.idleTimerReset() username = self.myDevice.get('username') prompt = self.myDevice.get('prompt') patList = [ 'User: $', 'assword: $', '\[confirm\] $', '\[confirm yes/no\]:', '\[yes/no\]:', '\(yes/no\)\?', '\(y/n\)', '--More--', "\\%s" % (prompt), '\) #', winpexpect.TIMEOUT, winpexpect.EOF, 'Login : $', 'config\) #', '\) >', '>>>>>', 'PoE firmware \[Ok\]', '\(y\|n\)\?' ] cpl = self.connectId.compile_pattern_list(patList) while True: index = self.connectId.expect(cpl, timeout) try: out = self.connectId.before + self.connectId.after except: out = self.connectId.before self.output += out i = 0 if index == 0 + i: ## Login: $ self.connectId.sendline(self.username) try: self.connectId.expect('assword: ', 10) except winpexpect.TIMEOUT: pass else: print "PRINTING HERE" self.connectId.sendline(self.password) out = self.connectId.before + self.connectId.after self.output += out elif index == 1 + i: ## assword: $ self.connectId.sendline(self.password) out = self.connectId.before + self.connectId.after self.output += out elif index == 2 + i: ## \[confirm\] $ self.connectId.sendline() elif index == 3 + i: ## \[confirm yes/no\]: self.connectId.sendline('yes') out = self.connectId.before + self.connectId.after self.output += out elif index == 4 + i: ## \[yes/no\]: self.connectId.sendline('yes') out = self.connectId.before + self.connectId.after self.output += out elif index == 5 + i: ## \(yes/no\)\? self.connectId.sendline('yes') out = self.connectId.before + self.connectId.after self.output += out elif index == 6 + i: ## \[y/n\]: self.connectId.sendline('y') out = self.connectId.before + self.connectId.after self.output += out elif index == 7 + i: ## --More-- self.connectId.sendline(' ') out = self.connectId.before + self.connectId.after self.output += out elif index == 8 + i: return const.linuxPrompt elif index == 9 + i: #prompt return const.oniePrompt elif index == 10 + i: ## pexpect.TIMEOUT idleTimer = self.getIdleTime() if idleTimer < idleTimeout: self.connectId.before = '' self.connectId.after = '' # log.debug('idle timer %s' %idleTimer, level=const.LEVEL4) if notIdleRetryCount > maxNotIdleRetryCount: raise winpexpect.TIMEOUT('connection timed out') notIdleRetryCount += 1 else: if timeoutAttemptCount < 2: self.connectId.sendline("") timeoutAttemptCount += 1 else: raise winpexpect.TIMEOUT('connection timed out') elif index == 11 + i: ## pexpect.EOF raise winpexpect.EOF('connection terminated') elif index == 12 + i: self.connectId.sendline(self.myDevice.get("consoleUsername")) try: self.connectId.expect('assword :', 10) except winpexpect.TIMEOUT: pass else: self.connectId.sendline( self.myDevice.get('consolePassword')) self.connectId.sendline("\r") self.connectId.sendline("%s\r" % self.username) #self.connectId.sendline("test123") self.connectId.sendline("%s\r" % self.password) #if self.connectId.expect("User:"******"%s\r" % self.username) # self.connectId.sendline("test123") #self.connectId.sendline("admin\r") out = self.connectId.before + self.connectId.after self.output += out elif index == 13 + i: self.connectId.sendline("end") elif index == 14 + i: self.connectId.sendline("enable") try: self.connectId.expect('assword: ', 10) except winpexpect.TIMEOUT: pass else: self.connectId.sendline(self.myDevice.get('enable')) print "INSIDE EXCEPT BLOCK" out = self.connectId.before + self.connectId.after self.output += out
def expect_exact(foo, timeout): raise pexpect.EOF('error')
def _eval_line(self, line, allow_use_file=True, wait_for_prompt=True, restart_if_needed=True): """ Evaluate a line of commands. REMARK: By default, a long command (length exceeding ``self._eval_using_file_cutoff``) is evaluated using :meth:`_eval_line_using_file`. If the command can not be evaluated since the interface has crashed, it is automatically restarted and tried again *once*. If the optional ``wait_for_prompt`` is ``False`` then even a very long line will not be evaluated by :meth:`_eval_line_using_file`, since this does not support the ``wait_for_prompt`` option. INPUT: - ``line`` -- (string) a command. - ``allow_use_file`` (optional bool, default ``True``) -- allow to evaluate long commands using :meth:`_eval_line_using_file`. - ``wait_for_prompt`` (optional bool, default ``True``) -- wait until the prompt appears in the sub-process' output. - ``restart_if_needed`` (optional bool, default ``True``) -- If it is ``True``, the command evaluation is evaluated a second time after restarting the interface, if an ``EOFError`` occured. TESTS:: sage: singular._eval_line('def a=3;') 'def a=3;' sage: singular('a') 3 sage: singular.eval('quit;') '' sage: singular._eval_line('def a=3;') Singular crashed -- automatically restarting. 'def a=3;' sage: singular('a') 3 sage: singular.eval('kill a') 'kill a;' We are now sending a command that would run forever. But since we declare that we are not waiting for a prompt, we can interrupt it without a KeyboardInterrupt. At the same time, we test that the line is not forwarded to :meth:`_eval_line_using_file`, since that method would not support the ``wait_for_prompt`` option. For reasons which are currently not understood, the ``interrupt`` test usually returns immediately, but sometimes it takes a very long time on the same system. :: sage: cutoff = singular._eval_using_file_cutoff sage: singular._eval_using_file_cutoff = 4 sage: singular._eval_line('for(int i=1;i<=3;i++){i=1;};', wait_for_prompt=False) '' sage: singular.interrupt(timeout=3) # sometimes very slow (up to 60s on sage.math, 2012) False sage: singular._eval_using_file_cutoff = cutoff Last, we demonstrate that by default the execution of a command is tried twice if it fails the first time due to a crashed interface:: sage: singular.eval('quit;') '' sage: singular._eval_line_using_file('def a=3;', restart_if_needed=False) Traceback (most recent call last): ... RuntimeError: Singular terminated unexpectedly while reading in a large line... Since the test of the next method would fail, we re-start Singular now. :: sage: singular(2+3) Singular crashed -- automatically restarting. 5 """ if allow_use_file and wait_for_prompt and self._eval_using_file_cutoff and len(line) > self._eval_using_file_cutoff: return self._eval_line_using_file(line) try: if self._expect is None: self._start() E = self._expect try: if len(line) >= 4096: raise RuntimeError("Sending more than 4096 characters with %s on a line may cause a hang and you're sending %s characters"%(self, len(line))) E.sendline(line) if wait_for_prompt == False: return '' except OSError as msg: if restart_if_needed: # The subprocess most likely crashed. # If it's really still alive, we fall through # and raise RuntimeError. if sys.platform.startswith('sunos'): # On (Open)Solaris, we might need to wait a # while because the process might not die # immediately. See Trac #14371. for t in [0.5, 1.0, 2.0]: if E.isalive(): time.sleep(t) else: break if not E.isalive(): try: self._synchronize() except (TypeError, RuntimeError): pass return self._eval_line(line,allow_use_file=allow_use_file, wait_for_prompt=wait_for_prompt, restart_if_needed=False) raise RuntimeError, "%s\nError evaluating %s in %s"%(msg, line, self), sys.exc_info()[2] if len(line)>0: try: if isinstance(wait_for_prompt, basestring): E.expect(wait_for_prompt) else: E.expect(self._prompt) except pexpect.EOF as msg: try: if self.is_local(): tmp_to_use = self._local_tmpfile() else: tmp_to_use = self._remote_tmpfile() if self._read_in_file_command(tmp_to_use) in line: raise pexpect.EOF(msg) except NotImplementedError: pass if self._quit_string() in line: # we expect to get an EOF if we're quitting. return '' elif restart_if_needed==True: # the subprocess might have crashed try: self._synchronize() return self._eval_line(line,allow_use_file=allow_use_file, wait_for_prompt=wait_for_prompt, restart_if_needed=False) except (TypeError, RuntimeError): pass raise RuntimeError("%s\n%s crashed executing %s"%(msg,self, line)) if self._terminal_echo: out = E.before else: out = E.before.rstrip('\n\r') if out == '': # match bug with echo out = line else: if self._terminal_echo: out = '\n\r' else: out = '' except KeyboardInterrupt: self._keyboard_interrupt() raise KeyboardInterrupt("Ctrl-c pressed while running %s"%self) if self._terminal_echo: i = out.find("\n") j = out.rfind("\r") return out[i+1:j].replace('\r\n','\n') else: return out.replace('\r\n','\n')
def __init__(self): pass def expect(self, *args, **kwargs): pass @pytest.mark.parametrize( "device, conn_cmd, expect_retval, msg, exp_raises", [ ( DummyDevice(), "connect somewhere", None, "Board is in use (connection refused).", pexpect.EOF("Intentional"), ), ( DummyDevice(), "connect somewhere", 0, "Password required and not supported", None, ), ( DummyDevice(), "connect somewhere", 1, "Board is in use (connection refused).", None, ),
def getPrompt(self, timeout=-1, idleTimeout=60): timeoutAttemptCount = 1 notIdleRetryCount = 1 wrongPasswordCount = 1 maxNotIdleRetryCount = 15 out = '' self.idleTimerReset() username = self.myDevice.get('username') prompt = self.myDevice.get('prompt') patList = [ 'User: $', 'assword: $', '\[confirm\] $', '\[confirm yes/no\]:', '\[yes/no\]:', '\(yes/no\)\?', '\(y/n\)', '--More--', prompt, ':~\$', winpexpect.TIMEOUT, winpexpect.EOF ] cpl = self.connectId.compile_pattern_list(patList) while True: index = self.connectId.expect(cpl, timeout) try: out = self.connectId.before + self.connectId.after except: out = self.connectId.before self.output += out print self.output i = 0 if index == 0 + i: ## Login: $ self.connectId.sendline(self.myDevice.get('username')) out = self.connectId.before + self.connectId.after self.output += out try: self.connectId.expect('assword:', 10) except winpexpect.TIMEOUT: pass else: self.connectId.sendline(self.myDevice.get('password')) out = self.connectId.before + self.connectId.after self.output += out elif index == 1 + i: ## assword: $ self.connectId.sendline(self.myDevice.get('password')) out = self.connectId.before + self.connectId.after self.output += out try: self.connectId.expect('assword:', 10) except winpexpect.TIMEOUT: pass else: self.connectId.sendline(self.myDevice.get('password')) out = self.connectId.before + self.connectId.after self.output += out elif index == 2 + i: ## \[confirm\] $ self.connectId.sendline() elif index == 3 + i: ## \[confirm yes/no\]: self.connectId.sendline('yes') out = self.connectId.before + self.connectId.after self.output += out elif index == 4 + i: ## \[yes/no\]: self.connectId.sendline('yes') out = self.connectId.before + self.connectId.after self.output += out elif index == 5 + i: ## \(yes/no\)\? self.connectId.sendline('yes') out = self.connectId.before + self.connectId.after self.output += out elif index == 6 + i: ## \[y/n\]: self.connectId.sendline('y') out = self.connectId.before + self.connectId.after self.output += out elif index == 7 + i: ## --More-- self.connectId.sendline(' ') out = self.connectId.before + self.connectId.after self.output += out elif index == 8 + i: return const.linuxPrompt elif index == 9 + i: #prompt return const.oniePrompt elif index == 10 + i: ## pexpect.TIMEOUT idleTimer = self.getIdleTime() if idleTimer < idleTimeout: self.connectId.before = '' self.connectId.after = '' # log.debug('idle timer %s' %idleTimer, level=const.LEVEL4) if notIdleRetryCount > maxNotIdleRetryCount: raise winpexpect.TIMEOUT('connection timed out') notIdleRetryCount += 1 else: if timeoutAttemptCount < 2: self.connectId.sendline("") timeoutAttemptCount += 1 else: raise winpexpect.TIMEOUT('connection timed out') elif index == 11 + i: ## pexpect.EOF raise winpexpect.EOF('connection terminated')
def parse_error(error): if error == 0: raise pexpect.EOF('Got EOF') elif error == 1: raise pexpect.TIMEOUT('Got Timeout')
def expect_side_effect(patterns, *args, **kwargs): for idx, pattern in enumerate(patterns): if 'Are you sure you want to continue connecting' in pattern: return idx raise pexpect.EOF(None)
def getPrompt(self, prompt="#", timeout=-1, idleTimeout=60): timeoutAttemptCount = 1 notIdleRetryCount = 1 wrongPasswordCount = 1 maxNotIdleRetryCount = 15 out = '' self.idleTimerReset() username = self.myDevice.get('username') userPatList = self.myDevice.userDialogueResponse.keys() patList = [ "login as:", "assword:", username + ">", winpexpect.TIMEOUT, winpexpect.EOF ] cpl = self.connectId.compile_pattern_list(patList) while True: index = self.connectId.expect(cpl, timeout) out = self.connectId.before self.output += out for i in range(len(userPatList)): if index == i: self.connectId.sendline( self.myDevice.userDialogueResponse[userPatList[i]]) i = len(userPatList) if index == 0 + i: ## Login: $ self.connectId.sendline(self.myDevice.get('username')) out = self.connectId.after self.output += out try: self.connectId.expect('assword:', 10) except winpexpect.TIMEOUT: pass else: self.connectId.sendline(self.myDevice.get('password')) out = self.connectId.after self.output += out elif index == 1 + i: ## assword: $ self.connectId.sendline(self.myDevice.get('password')) out = self.connectId.after self.output += out elif index == 2 + i: ## > prompt self.connectId.sendline() return 1 elif index == 18 + i: ## winpexpect.TIMEOUT idleTimer = self.getIdleTime() if idleTimer < idleTimeout: self.connectId.before = '' self.connectId.after = '' log.debug('idle timer %s' % idleTimer) if notIdleRetryCount > maxNotIdleRetryCount: raise winpexpect.TIMEOUT('connection timed out') notIdleRetryCount += 1 else: if timeoutAttemptCount < 2: self.connectId.sendline() timeoutAttemptCount += 1 else: raise winpexpect.TIMEOUT('connection timed out') elif index == 19 + i: ## winpexpect.EOF raise winpexpect.EOF('connection terminated')