Workaround paramiko timeout problem

Change-Id: I5fda968011465171866f86e11bf4ca98a7215c24
This commit is contained in:
Federico Ressi 2019-10-16 09:47:37 +02:00
parent 17ef6dcb32
commit ac8b04b78c
4 changed files with 23 additions and 42 deletions

View File

@ -33,7 +33,7 @@ class ShellExecuteResult(object):
def __init__(self, command=None, exit_status=None, stdin=None, stdout=None,
stderr=None):
self.command = str(command)
self.exit_status = int(exit_status)
self.exit_status = exit_status
self.stdin = stdin and str(stdin) or None
self.stdout = stdout and str(stdout) or None
self.stderr = stderr and str(stderr) or None
@ -83,7 +83,7 @@ def execute_process(process, stdin, expect_exit_status):
process.check_exit_status(expect_exit_status)
return ShellExecuteResult(command=str(process.command),
exit_status=int(process.exit_status),
exit_status=process.exit_status,
stdin=_process.str_from_stream(process.stdin),
stdout=_process.str_from_stream(process.stdout),
stderr=_process.str_from_stream(process.stderr))

View File

@ -191,23 +191,20 @@ class ShellProcessFixture(tobiko.SharedFixture):
# Drain all incoming data from STDOUT and STDERR
self.wait(timeout=timeout)
finally:
try:
self._terminate()
except Exception:
LOG.debug('Exception terminating process: %r',
self.command, exc_info=1)
self._terminate()
def _terminate(self):
self.close_stdout()
self.close_stderr()
exit_status = None
try:
exit_status = self.poll_exit_status()
except Exception:
LOG.exception('Error getting exit status')
exit_status = None
exit_status = self.get_exit_status()
finally:
if exit_status is None:
self.kill()
try:
self.kill()
except Exception:
LOG.exception('Error killing process: %r', self.command)
def __getattr__(self, name):
try:
@ -281,13 +278,10 @@ class ShellProcessFixture(tobiko.SharedFixture):
def receive_all(self, **kwargs):
self.communicate(receive_all=True, **kwargs)
def wait(self, timeout=None, receive_all=True, **kwargs):
timeout = shell_process_timeout(timeout=timeout)
try:
self.communicate(timeout=timeout, receive_all=receive_all,
**kwargs)
finally:
self.get_exit_status(timeout=timeout)
def wait(self, timeout=None, receive_all=True,
**kwargs):
self.communicate(timeout=timeout, receive_all=receive_all,
**kwargs)
def communicate(self, stdin=None, stdout=True, stderr=True, timeout=None,
receive_all=False, buffer_size=None):

View File

@ -117,16 +117,18 @@ class SSHShellProcessFixture(_process.ShellProcessFixture):
def _get_exit_status(self, time_left=None):
process = self.process
if not process.exit_status_ready():
LOG.debug('Waiting for command (%s) exit status', self.command)
# workaround for paramiko timeout problem
time_left = min(time_left, 120.0)
# recv_exit_status method doesn't accept timeout parameter
if process.status_event.wait(timeout=time_left):
assert process.exit_status_ready()
else:
assert not process.exit_status_ready()
return None
LOG.debug('Waiting for command (%s) exit status (time_left=%r)',
self.command, time_left)
if not process.status_event.wait(timeout=time_left):
LOG.debug('Timed out before status event being set')
assert process.exit_status is not None
return process.exit_status
if process.exit_status >= 0:
return process.exit_status
else:
return None
def kill(self):
process = self.process

View File

@ -172,18 +172,3 @@ class SSHExecuteTest(ExecuteTest):
def execute(self, **kwargs):
kwargs.setdefault('shell', self.shell)
return sh.ssh_execute(ssh_client=self.ssh_client, **kwargs)
class ExecuteWithSSHCommandTest(ExecuteTest):
server_stack = tobiko.required_setup_fixture(
stacks.CirrosServerStackFixture)
@property
def shell(self):
return self.server_stack.ssh_command
@testtools.skip('This is producing strange failures :-(')
def test_timeout_expires(self, command='sleep 10', timeout=5., stdin=None,
stdout=None, stderr=None, **kwargs):
pass