From: "Yann E. MORIN" <yann.morin.1998@free.fr>
To: Julien Olivain <ju.o@free.fr>
Cc: Ricardo Martincoski <ricardo.martincoski@datacom.com.br>,
buildroot@buildroot.org
Subject: Re: [Buildroot] [PATCH v2 1/3] support/testing/infra/emulator.py: change the shell prompt before running tests
Date: Tue, 27 Jun 2023 23:21:16 +0200 [thread overview]
Message-ID: <20230627212116.GK646621@scaer> (raw)
In-Reply-To: <802f2f6d2163a5e097b909ac2e13c57a@free.fr>
Julien, All,
On 2023-06-27 21:43 +0200, Julien Olivain spake thusly:
> On 26/06/2023 23:06, Yann E. MORIN wrote:
> >On 2023-06-11 12:45 +0200, Julien Olivain spake thusly:
> >>If a program has the string '# ' (i.e. the default shell prompt) in
> >>its output, the test execution in the Buildroot runtime test infra is
> >>failing.
> >>
> >>This can be reproduced by adding a single line in a package test
> >>script:
> >> self.assertRunOk("echo ### this is a string with hashes ###")
[--SNIP--]
> >>an actual shell prompt. The prompt is encoded by single-quoting
> >>each character (e.g. abc -> 'a''b''c').
> >That's not really what join() will do. E.g. with your code:
> > >>> s = "#BRTEST# "
> > >>> "''".join(s)
> > "#''B''R''T''E''S''T''#'' "
> I agree doing this, we miss the first and last quote. This is exactly what
> the next line is doing:
> self.run("export PS1='{}'".format(encoded_prompt))
> Note the extra quotes. If you look in a run-test run log, there will be:
> # export PS1='#''B''R''T''E''S''T''#'' '
> #BRTEST# echo $?
> 0
Ah, yeah, so the prompt is not "encoded". Rather, the command setting
the prompt is obfuscated to that it is not itself detected as a prompt
being displayed.
OK, got it.
> This was my initial intent: setting the PS1 without the local echo
> begin caught by pexpect.
Yup.
> If you prefer any other encoding or prompt, please suggest something
> else. I initially tried by temporarily disabling the local echo with
> "stty -echo" but this was creating other issues...
Yeah, I think using a side channel to inform pexpect that a prompt is
actually being displayed, would eventually do the trick. That, combined
with your trick to obfuscate the command setting the prompt:
# \033_ is APC (Application Program Command),
# \033\ is ST (String Terminator), which terminates APC
self.prompt_esc = '\033_BR_COMMAND_FINISHED\033\\'
# Obfuscate the command setting the prompt, so that it is not
# itself detected as a prompt being displayed.
self.run("export PS1='{}# '".format("''".join(self.prompt_esc)))
And then, the emulator would be changed to expect that ANSI escape
sequence; everywhere we expect("# ") or expect(["# ",...]), we switch to
using self.prompt_esc instead or "# "
Totally untested, of course! I have a little doubt about whether the
escape ANSI sequence can be obfuscated that way, though...
[--SNIP--]
> >Anyway, your patch at least breaks tests.package.test_bash...
> The /etc/profile in Buildroot skeleton is overwriting PS1, see:
> https://git.buildroot.org/buildroot/tree/system/skeleton/etc/profile?h=2023.05#n5
>
> I was able to fix this test_bash by passing the PS1 in another exported
> variable:
>
> self.assertRunOk("export BR_PS1=\"$PS1\"")
> self.emulator.qemu.sendline("bash -il")
> self.assertRunOk("export PS1=\"${BR_PS1}\"")
>
> The "bash -il" return code is no longer tested, but I don't think it's
> an issue since the rest of the test covers that.
>
> If you agree with this workaround, I'll send an updated v3 patch series.
I think we should instead tell bash to not parse the default bashrc et
al.:
self.assertRunOk("bash -il --init-file /dev/null --rcfile /dev/null")
And this should solve the issue: PS1 is in the environment, so bash will
inherit it.
Regards,
Yann E. MORIN.
> >
> >Regards,
> >Yann E. MORIN.
> >
> >>Signed-off-by: Julien Olivain <ju.o@free.fr>
> >>---
> >>Changes v1 -> v2:
> >>- reworded commit log, to mention this issue was also seen while writing
> >> a test for the dmidecode package
> >>- the patch series also introduce the new test for dmidecode
> >>---
> >> support/testing/infra/emulator.py | 14 ++++++++++++--
> >> 1 file changed, 12 insertions(+), 2 deletions(-)
> >>
> >>diff --git a/support/testing/infra/emulator.py
> >>b/support/testing/infra/emulator.py
> >>index 02cf486128..390c582e9d 100644
> >>--- a/support/testing/infra/emulator.py
> >>+++ b/support/testing/infra/emulator.py
> >>@@ -13,6 +13,7 @@ class Emulator(object):
> >> # can take a long time to run the emulator. Use a timeout
> >>multiplier
> >> # when running the tests to avoid sporadic failures.
> >> self.timeout_multiplier = timeout_multiplier
> >>+ self.shell_prompt = "#BRTEST# "
> >>
> >> # Start Qemu to boot the system
> >> #
> >>@@ -100,6 +101,15 @@ class Emulator(object):
> >> index = self.qemu.expect(["# ", pexpect.TIMEOUT])
> >> if index != 0:
> >> raise SystemError("Cannot login")
> >>+ # Set a special shell prompt while testing. Since the standard
> >>+ # prompt '# ' is quite generic, a normal process output could
> >>+ # contain that string and confuse expect. When changing the
> >>+ # prompt, we also need to encode or escape it in some way to
> >>+ # make sure the command echo will not be seen as a prompt
> >>+ # itself. The prompt is encoded by single-quoting each
> >>+ # character (e.g. abc -> 'a''b''c').
> >>+ encoded_prompt = "''".join(self.shell_prompt)
> >>+ self.run("export PS1='{}'".format(encoded_prompt))
> >> self.run("dmesg -n 1")
> >> # Prevent the shell from wrapping the commands at 80 columns.
> >> self.run("stty columns 29999")
> >>@@ -110,13 +120,13 @@ class Emulator(object):
> >> self.qemu.sendline(cmd)
> >> if timeout != -1:
> >> timeout *= self.timeout_multiplier
> >>- self.qemu.expect("# ", timeout=timeout)
> >>+ self.qemu.expect(self.shell_prompt, 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(self.shell_prompt)
> >> exit_code = self.qemu.before.splitlines()[2]
> >> exit_code = int(exit_code)
> >>
> >>--
> >>2.41.0
> >>
> >>_______________________________________________
> >>buildroot mailing list
> >>buildroot@buildroot.org
> >>https://lists.buildroot.org/mailman/listinfo/buildroot
>
> Best regards,
>
> Julien.
--
.-----------------.--------------------.------------------.--------------------.
| Yann E. MORIN | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software Designer | \ / CAMPAIGN | ___ |
| +33 561 099 427 `------------.-------: X AGAINST | \e/ There is no |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL | v conspiracy. |
'------------------------------^-------^------------------^--------------------'
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot
prev parent reply other threads:[~2023-06-27 21:21 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-11 10:45 [Buildroot] [PATCH v2 1/3] support/testing/infra/emulator.py: change the shell prompt before running tests Julien Olivain
2023-06-26 20:00 ` [Buildroot] [PATCH v2 2/3] support/testing/tests/package/test_dieharder.py: new runtime test Julien Olivain
2023-06-26 20:01 ` [Buildroot] [PATCH v2 3/3] support/testing/tests/package/test_dmidecode.py: " Julien Olivain
2023-06-26 21:06 ` [Buildroot] [PATCH v2 1/3] support/testing/infra/emulator.py: change the shell prompt before running tests Yann E. MORIN
2023-06-27 19:43 ` Julien Olivain
2023-06-27 21:21 ` Yann E. MORIN [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230627212116.GK646621@scaer \
--to=yann.morin.1998@free.fr \
--cc=buildroot@buildroot.org \
--cc=ju.o@free.fr \
--cc=ricardo.martincoski@datacom.com.br \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox