Close stringio objects at sshutils
Closes-Bug: #1956956 Change-Id: I94f597d99951459b12f0f0211ec73f2ae7fa908d
This commit is contained in:
parent
675ea00d3b
commit
2a77c63071
|
@ -17,6 +17,16 @@ Changelog
|
||||||
.. Release notes for existing releases are MUTABLE! If there is something that
|
.. Release notes for existing releases are MUTABLE! If there is something that
|
||||||
was missed or can be improved, feel free to change it!
|
was missed or can be improved, feel free to change it!
|
||||||
|
|
||||||
|
[unreleased]
|
||||||
|
------------
|
||||||
|
|
||||||
|
Fixed
|
||||||
|
~~~~~
|
||||||
|
|
||||||
|
* rally.utils.sshutils.SSH.execute leaves fifo files.
|
||||||
|
|
||||||
|
`Launchpad-bug #1956956 <https://launchpad.net/bugs/1956956>`_
|
||||||
|
|
||||||
[3.3.0] - 2021-06-16
|
[3.3.0] - 2021-06-16
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ Execute command and get output:
|
||||||
status, stdout, stderr = ssh.execute("ps ax")
|
status, stdout, stderr = ssh.execute("ps ax")
|
||||||
if status:
|
if status:
|
||||||
raise Exception("Command failed with non-zero status.")
|
raise Exception("Command failed with non-zero status.")
|
||||||
print stdout.splitlines()
|
print(stdout.splitlines())
|
||||||
|
|
||||||
Execute command with huge output:
|
Execute command with huge output:
|
||||||
|
|
||||||
|
@ -157,12 +157,18 @@ class SSH(object):
|
||||||
|
|
||||||
client = self._get_client()
|
client = self._get_client()
|
||||||
|
|
||||||
|
should_close_stdin = False
|
||||||
if isinstance(stdin, str):
|
if isinstance(stdin, str):
|
||||||
stdin = io.StringIO(stdin)
|
stdin = io.StringIO(stdin)
|
||||||
|
should_close_stdin = True
|
||||||
|
|
||||||
return self._run(client, cmd, stdin=stdin, stdout=stdout,
|
try:
|
||||||
stderr=stderr, raise_on_error=raise_on_error,
|
return self._run(client, cmd, stdin=stdin, stdout=stdout,
|
||||||
timeout=timeout)
|
stderr=stderr, raise_on_error=raise_on_error,
|
||||||
|
timeout=timeout)
|
||||||
|
finally:
|
||||||
|
if should_close_stdin:
|
||||||
|
stdin.close()
|
||||||
|
|
||||||
def _run(self, client, cmd, stdin=None, stdout=None, stderr=None,
|
def _run(self, client, cmd, stdin=None, stdout=None, stderr=None,
|
||||||
raise_on_error=True, timeout=3600):
|
raise_on_error=True, timeout=3600):
|
||||||
|
@ -246,15 +252,15 @@ class SSH(object):
|
||||||
|
|
||||||
:returns: tuple (exit_status, stdout, stderr)
|
:returns: tuple (exit_status, stdout, stderr)
|
||||||
"""
|
"""
|
||||||
stdout = io.StringIO()
|
with io.StringIO() as stdout:
|
||||||
stderr = io.StringIO()
|
with io.StringIO() as stderr:
|
||||||
|
|
||||||
exit_status, data = self.run(cmd, stderr=stderr, stdout=stdout,
|
exit_status, data = self.run(cmd, stderr=stderr, stdout=stdout,
|
||||||
stdin=stdin, timeout=timeout,
|
stdin=stdin, timeout=timeout,
|
||||||
raise_on_error=False)
|
raise_on_error=False)
|
||||||
stdout.seek(0)
|
stdout.seek(0)
|
||||||
stderr.seek(0)
|
stderr.seek(0)
|
||||||
return (exit_status, stdout.read(), stderr.read())
|
return exit_status, stdout.read(), stderr.read()
|
||||||
|
|
||||||
def wait(self, timeout=120, interval=1):
|
def wait(self, timeout=120, interval=1):
|
||||||
"""Wait for the host will be available via ssh."""
|
"""Wait for the host will be available via ssh."""
|
||||||
|
|
|
@ -128,22 +128,26 @@ class SSHTestCase(test.TestCase):
|
||||||
m_client.close.assert_called_once_with()
|
m_client.close.assert_called_once_with()
|
||||||
self.assertFalse(self.ssh._client)
|
self.assertFalse(self.ssh._client)
|
||||||
|
|
||||||
@mock.patch("rally.utils.sshutils.io.StringIO")
|
def test_execute(self):
|
||||||
def test_execute(self, mock_string_io):
|
stdout_txt = "stdout fake data"
|
||||||
mock_string_io.side_effect = stdio = [mock.Mock(), mock.Mock()]
|
stdout_io = io.StringIO(stdout_txt)
|
||||||
stdio[0].read.return_value = "stdout fake data"
|
stderr_txt = "stderr fake data"
|
||||||
stdio[1].read.return_value = "stderr fake data"
|
stderr_io = io.StringIO(stderr_txt)
|
||||||
with mock.patch.object(self.ssh, "run") as mock_run:
|
|
||||||
mock_run.return_value = (0, None)
|
with mock.patch("rally.utils.sshutils.io.StringIO") as mock_string_io:
|
||||||
status, stdout, stderr = self.ssh.execute("cmd",
|
mock_string_io.side_effect = [stdout_io, stderr_io]
|
||||||
stdin="fake_stdin",
|
with mock.patch.object(self.ssh, "run") as mock_run:
|
||||||
timeout=43)
|
mock_run.return_value = (0, None)
|
||||||
|
status, stdout, stderr = self.ssh.execute("cmd",
|
||||||
|
stdin="fake_stdin",
|
||||||
|
timeout=43)
|
||||||
|
|
||||||
mock_run.assert_called_once_with(
|
mock_run.assert_called_once_with(
|
||||||
"cmd", stdin="fake_stdin", stdout=stdio[0],
|
"cmd", stdin="fake_stdin", stdout=stdout_io, stderr=stderr_io,
|
||||||
stderr=stdio[1], timeout=43, raise_on_error=False)
|
timeout=43, raise_on_error=False)
|
||||||
self.assertEqual(0, status)
|
self.assertEqual(0, status)
|
||||||
self.assertEqual("stdout fake data", stdout)
|
self.assertEqual(stdout_txt, stdout)
|
||||||
self.assertEqual("stderr fake data", stderr)
|
self.assertEqual(stderr_txt, stderr)
|
||||||
|
|
||||||
@mock.patch("rally.utils.sshutils.time")
|
@mock.patch("rally.utils.sshutils.time")
|
||||||
def test_wait_timeout(self, mock_time):
|
def test_wait_timeout(self, mock_time):
|
||||||
|
|
Loading…
Reference in New Issue