From: "Alex Bennée" <alex.bennee@linaro.org>
To: "Cédric Le Goater" <clg@kaod.org>
Cc: qemu-devel@nongnu.org, fam@euphon.net, berrange@redhat.com,
f4bug@amsat.org, aurelien@aurel32.net, pbonzini@redhat.com,
stefanha@redhat.com, crosa@redhat.com,
"Philippe Mathieu-Daudé" <philmd@linaro.org>,
"Wainer dos Santos Moschetta" <wainersm@redhat.com>,
"Beraldo Leal" <bleal@redhat.com>
Subject: Re: [PATCH v2 02/12] tests/avocado: improve behaviour waiting for login prompts
Date: Thu, 17 Nov 2022 14:04:29 +0000 [thread overview]
Message-ID: <87edu18xw5.fsf@linaro.org> (raw)
In-Reply-To: <33e63f5c-8a32-8093-6ce8-2641d0d8e325@kaod.org>
Cédric Le Goater <clg@kaod.org> writes:
> Hello Alex,
>
> On 11/11/22 15:55, Alex Bennée wrote:
>> This attempts to deal with the problem of login prompts not being
>> guaranteed to be terminated with a newline. The solution to this is to
>> peek at the incoming data looking to see if we see an up-coming match
>> before we fall back to the old readline() logic. The reason to mostly
>> rely on readline is because I am occasionally seeing the peek stalling
>> despite data being there.
>> This seems kinda hacky and gross so I'm open to alternative
>> approaches
>> and cleaner python code.
>> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
>> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
>
> I have pulled this patch in the aspeed tree hoping it would improve tests:
>
> AST2x00MachineSDK.test_arm_ast2500_evb_sdk
> AST2x00MachineSDK.test_arm_ast2600_evb_sdk
>
> but the failure rate has increased :/ I have seen failures in these also :
>
> AST2x00Machine.test_arm_ast2500_evb_buildroot
> AST2x00Machine.test_arm_ast2600_evb_buildroot
>
> which used to be quite stable.
>
> Sorry, this is not of much help. the issue might be elsewhere.
Do you see what is happening in the logs? I've made a couple of tweaks
since and it gets through the negotiation but then timesout:
console: looking for 22:(ast2600-default login:), sending None (always=False)
/console: [ 0.939039] aspeed-pcie 1e7700c0.pcie: [1] : tx idle timeout [0]
-console: [ 1.385144] spi-nor spi0.1: unrecognized JEDEC id bytes: 00 00 00 00 00 00
console: [ 1.413028] spi-nor spi2.0: unrecognized JEDEC id bytes: 00 00 00 00 00 00
console: [ 1.617539] aspeed-rtc 1e781000.rtc: hctosys: unable to read the hardware clock
-console: rofs = mtd4 squashfs rwfs = mtd5 jffs2
/console: [ 14.563495] systemd[1]: Failed to find module 'autofs4'
-console: [ 18.034371] systemd[176]: /lib/systemd/system-generators/systemd-gpt-auto-generator failed with exit status 1.
|console: [FAILED] Failed to start Intel Power Control for the Host 0.
/console: [FAILED] Failed to start Phosphor C…istening on device /dev/ttyS2.
console: [DEPEND] Dependency failed for Host logger for ttyS2.
-console: Phosphor OpenBMC (Phosphor OpenBMC Project Reference Distro) nodistro.0 ast2600-default ttyS4
console: ast2600-default login:
(always=False)g for 9:(Password:), sending root
console: root
|console: Password:
(always=False)g for 23:(root@ast2600-default:~#), sending 0penBmc
console: Login timed out after 60 seconds.
|console: Phosphor OpenBMC (Phosphor OpenBMC Project Reference Distro) nodistro.0 ast2600-default ttyS4
/avocado.test:
>
> Thanks for the time you spend on this.
>
> C.
>
>
>> ---
>> v2
>> - remove superfluous /r/n
>> ---
>> tests/avocado/avocado_qemu/__init__.py | 89 +++++++++++++++++++++++++-
>> 1 file changed, 88 insertions(+), 1 deletion(-)
>> diff --git a/tests/avocado/avocado_qemu/__init__.py
>> b/tests/avocado/avocado_qemu/__init__.py
>> index 910f3ba1ea..20cba57161 100644
>> --- a/tests/avocado/avocado_qemu/__init__.py
>> +++ b/tests/avocado/avocado_qemu/__init__.py
>> @@ -131,6 +131,58 @@ def pick_default_qemu_bin(bin_prefix='qemu-system-', arch=None):
>> return path
>> return None
>> +def _peek_ahead(console, min_match, success_message):
>> + """
>> + peek ahead in the console stream keeping an eye out for the
>> + success message.
>> +
>> + Returns some message to process or None, indicating the normal
>> + readline should occur.
>> + """
>> + console_logger = logging.getLogger('console')
>> + peek_len = 0
>> + retries = 0
>> +
>> + while True:
>> + try:
>> + old_peek_len = peek_len
>> + peek_ahead = console.peek(min_match).decode()
>> + peek_len = len(peek_ahead)
>> +
>> + # if we get stuck too long lets just fallback to readline
>> + if peek_len <= old_peek_len:
>> + retries += 1
>> + if retries > 10:
>> + return None
>> +
>> + # if we see a newline in the peek we can let safely bail
>> + # and let the normal readline() deal with it
>> + if peek_ahead.endswith(('\n', '\r')):
>> + return None
>> +
>> + # if we haven't seen enough for the whole message but the
>> + # first part matches lets just loop again
>> + if len(peek_ahead) < min_match and \
>> + success_message[:peek_len] in peek_ahead:
>> + continue
>> +
>> + # if we see the whole success_message we are done, consume
>> + # it and pass back so we can exit to the user
>> + if success_message in peek_ahead:
>> + return console.read(peek_len).decode()
>> +
>> + # of course if we've seen enough then this line probably
>> + # doesn't contain what we are looking for, fallback
>> + if peek_len > min_match:
>> + return None
>> +
>> + except UnicodeDecodeError:
>> + console_logger.log("error in decode of peek")
>> + return None
>> +
>> + # we should never get here
>> + return None
>> +
>> def _console_interaction(test, success_message, failure_message,
>> send_string, keep_sending=False, vm=None):
>> @@ -139,17 +191,52 @@ def _console_interaction(test, success_message, failure_message,
>> vm = test.vm
>> console = vm.console_socket.makefile(mode='rb', encoding='utf-8')
>> console_logger = logging.getLogger('console')
>> +
>> + # Establish the minimum number of bytes we would need to
>> + # potentially match against success_message
>> + if success_message is not None:
>> + min_match = len(success_message)
>> + else:
>> + min_match = 0
>> +
>> + console_logger.debug("looking for %d:(%s), sending %s (always=%s)",
>> + min_match, success_message, send_string, keep_sending)
>> +
>> while True:
>> + msg = None
>> +
>> + # First send our string, optionally repeating the send next
>> + # cycle.
>> if send_string:
>> vm.console_socket.sendall(send_string.encode())
>> if not keep_sending:
>> send_string = None # send only once
>> +
>> + # If the console has no data to read we briefly
>> + # sleep before continuing.
>> + if not console.readable():
>> + time.sleep(0.1)
>> + continue
>> +
>> try:
>> - msg = console.readline().decode().strip()
>> +
>> + # First we shall peek ahead for a potential match to cover waiting
>> + # for lines without any newlines.
>> + if min_match > 0:
>> + msg = _peek_ahead(console, min_match, success_message)
>> +
>> + # otherwise we block here for a full line
>> + if not msg:
>> + msg = console.readline().decode().strip()
>> +
>> except UnicodeDecodeError:
>> + console_logger.debug("skipped unicode error")
>> msg = None
>> +
>> + # if nothing came out we continue and try again
>> if not msg:
>> continue
>> +
>> console_logger.debug(msg)
>> if success_message is None or success_message in msg:
>> break
--
Alex Bennée
next prev parent reply other threads:[~2022-11-17 14:22 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-11-11 14:55 [PATCH for 7.2-rc1 v2 00/12] testing, docs, plugins, arm pre-PR Alex Bennée
2022-11-11 14:55 ` [PATCH v2 01/12] Run docker probe only if docker or podman are available Alex Bennée
2022-11-11 16:50 ` Thomas Huth
2022-11-11 14:55 ` [PATCH v2 02/12] tests/avocado: improve behaviour waiting for login prompts Alex Bennée
2022-11-14 16:28 ` Peter Maydell
2022-11-14 22:15 ` Philippe Mathieu-Daudé
2022-11-17 13:38 ` Cédric Le Goater
2022-11-17 13:50 ` Peter Maydell
2022-11-17 14:04 ` Alex Bennée [this message]
2022-11-17 17:14 ` Cédric Le Goater
2022-11-11 14:55 ` [PATCH v2 03/12] tests/avocado/machine_aspeed.py: Reduce noise on the console for SDK tests Alex Bennée
2022-11-11 14:55 ` [PATCH v2 04/12] tests/docker: allow user to override check target Alex Bennée
2022-11-11 17:12 ` Philippe Mathieu-Daudé
2022-11-11 14:55 ` [PATCH v2 05/12] docs/devel: add a maintainers section to development process Alex Bennée
2022-11-11 14:55 ` [PATCH v2 06/12] docs/devel: make language a little less code centric Alex Bennée
2022-11-11 14:55 ` [PATCH v2 07/12] docs/devel: simplify the minimal checklist Alex Bennée
2022-11-11 14:55 ` [PATCH v2 08/12] docs/devel: try and improve the language around patch review Alex Bennée
2022-11-11 14:55 ` [PATCH v2 09/12] tests/plugins: add a new vcpu state tracking plugin Alex Bennée
2022-11-11 14:55 ` [PATCH v2 10/12] tests/avocado: Raise timeout for boot_linux.py:BootLinuxPPC64.test_pseries_tcg Alex Bennée
2022-11-11 14:55 ` [PATCH v2 11/12] gitlab: integrate coverage report Alex Bennée
2022-11-11 19:35 ` Philippe Mathieu-Daudé
2022-11-11 14:55 ` [PATCH v2 12/12] hw/intc: add implementation of GICD_IIDR to Arm GIC Alex Bennée
2022-11-11 14:55 ` Alex Bennée
2022-11-14 13:18 ` Peter Maydell
2022-11-14 12:47 ` [PATCH for 7.2-rc1 v2 00/12] testing, docs, plugins, arm pre-PR Alex Bennée
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=87edu18xw5.fsf@linaro.org \
--to=alex.bennee@linaro.org \
--cc=aurelien@aurel32.net \
--cc=berrange@redhat.com \
--cc=bleal@redhat.com \
--cc=clg@kaod.org \
--cc=crosa@redhat.com \
--cc=f4bug@amsat.org \
--cc=fam@euphon.net \
--cc=pbonzini@redhat.com \
--cc=philmd@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
--cc=wainersm@redhat.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.