More on the lines of quieting pylint 2.8.x, though to make it obvious that we definitely handle the cleanup here, I elected to bolster the close() method here.
1. Check for the process having terminated early more rigorously by checking poll() directly. 2. Change the prompt read into an assertion. 3. Ensure that the final communicate() call *definitely* closes the socket, adding a timeout and a final kill just in case. Signed-off-by: John Snow <js...@redhat.com> --- tests/qemu-iotests/iotests.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index e09c991b84e..12e876fa67d 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -238,20 +238,27 @@ def qemu_io_silent_check(*args): class QemuIoInteractive: def __init__(self, *args): self.args = qemu_io_args_no_fmt + list(args) + + # Resource cleaned up via close() + # pylint: disable=consider-using-with self._p = subprocess.Popen(self.args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) + if self._p.poll(): + # Failed to start. + out = self._p.stdout.read() + raise subprocess.SubprocessError(out, self._p.poll()) + + # Eat the first prompt out = self._p.stdout.read(9) - if out != 'qemu-io> ': - # Most probably qemu-io just failed to start. - # Let's collect the whole output and exit. - out += self._p.stdout.read() - self._p.wait(timeout=1) - raise ValueError(out) + assert out == 'qemu-io> ', "Did not understand qemu-io prompt" def close(self): - self._p.communicate('q\n') + try: + self._p.communicate('q\n', timeout=5) + except subprocess.TimeoutExpired: + self._p.kill() def _read_output(self): pattern = 'qemu-io> ' -- 2.30.2