diff mbox series

support/testing/infra/emulator.py: fix qemu prompt detection

Message ID 20240522154616.1265769-1-brandon.maier@collins.com
State New
Headers show
Series support/testing/infra/emulator.py: fix qemu prompt detection | expand

Commit Message

Brandon Maier May 22, 2024, 3:46 p.m. UTC
The qemu.run() method can break when a command happens to output the
string "# " to stdout. This is because qemu.run() detects when a command
has completed by searching for the shell prompt, which by default is
"# ". It then captures everything before the "# " as the commands
output, causing the rest of output to be lost.

To work around the issue set the prompt to something more unique. This
makes it less likely to appear in command output.

Signed-off-by: Brandon Maier <brandon.maier@collins.com>
---
 support/testing/infra/emulator.py | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

Comments

Julien Olivain May 22, 2024, 7:04 p.m. UTC | #1
Hi Brandon, All,

On 22/05/2024 17:46, Brandon Maier via buildroot wrote:
> The qemu.run() method can break when a command happens to output the
> string "# " to stdout. This is because qemu.run() detects when a 
> command
> has completed by searching for the shell prompt, which by default is
> "# ". It then captures everything before the "# " as the commands
> output, causing the rest of output to be lost.
> 
> To work around the issue set the prompt to something more unique. This
> makes it less likely to appear in command output.

I proposed a similar patch last year:
https://patchwork.ozlabs.org/project/buildroot/list/?series=362761

Changing this prompt requires to also patch the "bash" runtime test,
which is failing if the prompt is changed in the emulator.

I think my patches were not included due to lost 3/4 and 4/4 patches
in the series from my email provider. Those patches were originally
in the v2. See:
https://patchwork.ozlabs.org/project/buildroot/list/?series=359185&state=*

> 
> Signed-off-by: Brandon Maier <brandon.maier@collins.com>
> ---
>  support/testing/infra/emulator.py | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/support/testing/infra/emulator.py 
> b/support/testing/infra/emulator.py
> index 624740fcb1..aa579443a6 100644
> --- a/support/testing/infra/emulator.py
> +++ b/support/testing/infra/emulator.py
> @@ -100,6 +100,13 @@ class Emulator(object):
>          index = self.qemu.expect(["# ", pexpect.TIMEOUT])
>          if index != 0:
>              raise SystemError("Cannot login")
> +
> +        # Set a prompt that is unlikely to appear in command output
> +        self.qemu.sendline("PS1='br-qemu-test# '")
> +        index = self.qemu.expect(["\r\nbr-qemu-test# ", 
> pexpect.TIMEOUT])
> +        if index != 0:
> +            raise SystemError("Cannot set test prompt")
> +
>          self.run("dmesg -n 1")
>          # Prevent the shell from wrapping the commands at 80 columns.
>          self.run("stty columns 29999")
> @@ -110,13 +117,13 @@ class Emulator(object):
>          self.qemu.sendline(cmd)
>          if timeout != -1:
>              timeout *= self.timeout_multiplier
> -        self.qemu.expect("# ", timeout=timeout)
> +        self.qemu.expect("br-qemu-test# ", timeout=timeout)
>          # Remove double carriage return from qemu stdout so 
> str.splitlines()
>          # works as expected.
>          output = self.qemu.before.replace("\r\r", 
> "\r").splitlines()[1:]
> 
>          self.qemu.sendline("echo $?")
> -        self.qemu.expect("# ")
> +        self.qemu.expect("br-qemu-test# ")
>          exit_code = self.qemu.before.splitlines()[2]
>          exit_code = int(exit_code)
> 
> --
> 2.45.1
> 
> _______________________________________________
> buildroot mailing list
> buildroot@buildroot.org
> https://lists.buildroot.org/mailman/listinfo/buildroot

Best regards,

Julien.
diff mbox series

Patch

diff --git a/support/testing/infra/emulator.py b/support/testing/infra/emulator.py
index 624740fcb1..aa579443a6 100644
--- a/support/testing/infra/emulator.py
+++ b/support/testing/infra/emulator.py
@@ -100,6 +100,13 @@  class Emulator(object):
         index = self.qemu.expect(["# ", pexpect.TIMEOUT])
         if index != 0:
             raise SystemError("Cannot login")
+
+        # Set a prompt that is unlikely to appear in command output
+        self.qemu.sendline("PS1='br-qemu-test# '")
+        index = self.qemu.expect(["\r\nbr-qemu-test# ", pexpect.TIMEOUT])
+        if index != 0:
+            raise SystemError("Cannot set test prompt")
+
         self.run("dmesg -n 1")
         # Prevent the shell from wrapping the commands at 80 columns.
         self.run("stty columns 29999")
@@ -110,13 +117,13 @@  class Emulator(object):
         self.qemu.sendline(cmd)
         if timeout != -1:
             timeout *= self.timeout_multiplier
-        self.qemu.expect("# ", timeout=timeout)
+        self.qemu.expect("br-qemu-test# ", timeout=timeout)
         # Remove double carriage return from qemu stdout so str.splitlines()
         # works as expected.
         output = self.qemu.before.replace("\r\r", "\r").splitlines()[1:]
 
         self.qemu.sendline("echo $?")
-        self.qemu.expect("# ")
+        self.qemu.expect("br-qemu-test# ")
         exit_code = self.qemu.before.splitlines()[2]
         exit_code = int(exit_code)