Tests might want to look at the whole output from a command execution,
as well as just logging it. Add support for this.
Signed-off-by: John Levon <john.levon@nutanix.com>
---
tests/functional/qemu_test/cmd.py | 38 +++++++++++++++++++++++++++----
1 file changed, 33 insertions(+), 5 deletions(-)
diff --git a/tests/functional/qemu_test/cmd.py b/tests/functional/qemu_test/cmd.py
index dc5f422b77..6355b1a683 100644
--- a/tests/functional/qemu_test/cmd.py
+++ b/tests/functional/qemu_test/cmd.py
@@ -45,6 +45,9 @@ def is_readable_executable_file(path):
# If end of line is seen, with neither @success or @failure
# return False
#
+# In both cases, also return the contents of the line (in bytes)
+# up to that point.
+#
# If @failure is seen, then mark @test as failed
def _console_read_line_until_match(test, vm, success, failure):
msg = bytes([])
@@ -76,10 +79,23 @@ def _console_read_line_until_match(test, vm, success, failure):
except:
console_logger.debug(msg)
- return done
+ return done, msg
def _console_interaction(test, success_message, failure_message,
send_string, keep_sending=False, vm=None):
+ """
+ Interact with the console until either message is seen.
+
+ :param success_message: if this message appears, finish interaction
+ :param failure_message: if this message appears, test fails
+ :param send_string: a string to send to the console before trying
+ to read a new line
+ :param keep_sending: keep sending the send string each time
+ :param vm: the VM to interact with
+
+ :return: The collected output (in bytes form).
+ """
+
assert not keep_sending or send_string
assert success_message or send_string
@@ -101,6 +117,8 @@ def _console_interaction(test, success_message, failure_message,
if failure_message is not None:
failure_message_b = failure_message.encode()
+ out = bytes([])
+
while True:
if send_string:
vm.console_socket.sendall(send_string.encode())
@@ -113,11 +131,17 @@ def _console_interaction(test, success_message, failure_message,
break
continue
- if _console_read_line_until_match(test, vm,
- success_message_b,
- failure_message_b):
+ done, line = _console_read_line_until_match(test, vm,
+ success_message_b,
+ failure_message_b)
+
+ out += line
+
+ if done:
break
+ return out
+
def interrupt_interactive_console_until_pattern(test, success_message,
failure_message=None,
interrupt_string='\r'):
@@ -184,9 +208,13 @@ def exec_command_and_wait_for_pattern(test, command,
:param command: the command to send
:param success_message: if this message appears, test succeeds
:param failure_message: if this message appears, test fails
+
+ :return: The collected output (in bytes form).
"""
assert success_message
- _console_interaction(test, success_message, failure_message, command + '\r')
+
+ return _console_interaction(test, success_message, failure_message,
+ command + '\r')
def get_qemu_img(test):
test.log.debug('Looking for and selecting a qemu-img binary')
--
2.43.0
On Mon, Aug 18, 2025 at 12:05:44PM +0100, John Levon wrote: > Tests might want to look at the whole output from a command execution, > as well as just logging it. Add support for this. > > Signed-off-by: John Levon <john.levon@nutanix.com> > --- > tests/functional/qemu_test/cmd.py | 38 +++++++++++++++++++++++++++---- > 1 file changed, 33 insertions(+), 5 deletions(-) > > diff --git a/tests/functional/qemu_test/cmd.py b/tests/functional/qemu_test/cmd.py > index dc5f422b77..6355b1a683 100644 > --- a/tests/functional/qemu_test/cmd.py > +++ b/tests/functional/qemu_test/cmd.py > @@ -45,6 +45,9 @@ def is_readable_executable_file(path): > # If end of line is seen, with neither @success or @failure > # return False > # > +# In both cases, also return the contents of the line (in bytes) > +# up to that point. > +# > # If @failure is seen, then mark @test as failed > def _console_read_line_until_match(test, vm, success, failure): > msg = bytes([]) > @@ -76,10 +79,23 @@ def _console_read_line_until_match(test, vm, success, failure): > except: > console_logger.debug(msg) > > - return done > + return done, msg > > def _console_interaction(test, success_message, failure_message, > send_string, keep_sending=False, vm=None): > + """ > + Interact with the console until either message is seen. > + > + :param success_message: if this message appears, finish interaction > + :param failure_message: if this message appears, test fails > + :param send_string: a string to send to the console before trying > + to read a new line > + :param keep_sending: keep sending the send string each time > + :param vm: the VM to interact with > + > + :return: The collected output (in bytes form). > + """ > + > assert not keep_sending or send_string > assert success_message or send_string > > @@ -101,6 +117,8 @@ def _console_interaction(test, success_message, failure_message, > if failure_message is not None: > failure_message_b = failure_message.encode() > > + out = bytes([]) > + > while True: > if send_string: > vm.console_socket.sendall(send_string.encode()) > @@ -113,11 +131,17 @@ def _console_interaction(test, success_message, failure_message, > break > continue > > - if _console_read_line_until_match(test, vm, > - success_message_b, > - failure_message_b): > + done, line = _console_read_line_until_match(test, vm, > + success_message_b, > + failure_message_b) > + > + out += line > + > + if done: > break > > + return out > + > def interrupt_interactive_console_until_pattern(test, success_message, > failure_message=None, > interrupt_string='\r'): > @@ -184,9 +208,13 @@ def exec_command_and_wait_for_pattern(test, command, > :param command: the command to send > :param success_message: if this message appears, test succeeds > :param failure_message: if this message appears, test fails > + > + :return: The collected output (in bytes form). > """ > assert success_message > - _console_interaction(test, success_message, failure_message, command + '\r') > + > + return _console_interaction(test, success_message, failure_message, > + command + '\r') Looks reasonable, but there are a few other methods whjich call _console_interaction() - can you make them also return the matched bytes for consistency. With regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
© 2016 - 2025 Red Hat, Inc.