From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id DE10143DE5; Wed, 3 Apr 2024 11:00:44 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id CAB90402CE; Wed, 3 Apr 2024 11:00:44 +0200 (CEST) Received: from mail-lf1-f44.google.com (mail-lf1-f44.google.com [209.85.167.44]) by mails.dpdk.org (Postfix) with ESMTP id A437B4025C for ; Wed, 3 Apr 2024 11:00:43 +0200 (CEST) Received: by mail-lf1-f44.google.com with SMTP id 2adb3069b0e04-513e6777af4so10075514e87.2 for ; Wed, 03 Apr 2024 02:00:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pantheon.tech; s=google; t=1712134843; x=1712739643; darn=dpdk.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=aM5McgqsvrZRBg9U2nnBzufCc54rdTb5uYA3pQhjUyI=; b=H2Dh5c+jG1tktjdl9uZJeB9BQMWbwA3ctfPLLL5yG8P4UewHIO+jQpisG4h0BiPUfL KOvjGAkfXR13uE8FSmyvp5Y1YtPlLxvfC9P1Gf4eyZc8F+x60gw19cByJpSxG3p6m3z7 F4LyJOF5G+IBNA2KYcj8L+DUxZjuKAyf39ck3R2moWeSE33OsnqCI7ToSOht2wUpphT6 AjJJy6YNXRAcDkIt+ykieEHUarZU3oV8pWSM5slj8nBk0yMzAi1Z+dPUZBZL9eRyq4aY pH9OK1eaDdrpEKmiz5fVyTUCM5bF/d4CccR/AkTZ39FB1rqzCIbeIOi870c7HZdYuGIo ZF0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1712134843; x=1712739643; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=aM5McgqsvrZRBg9U2nnBzufCc54rdTb5uYA3pQhjUyI=; b=Ew7gFmeHYMkelOD4psjICtLUaOF47JCVXxKCuJfQSnlnNiG2Yuz1fi+p1f5FoNhYGE K4FTgXZUlzySNJraX/+YeOuBQ4Ktg8cu7lHJVHPJt5Jb6Od2oFv5QGH1fGHg7110r5gF 28juzO4ojwbGCRm/xq7rLxnj+nIcUo+3e+P/ef3NYsmdPkYMzmQuCNxiSokG98UBTO96 3CTAcYcbiTzuqPL+4LqfSkLchAZfHZwgYFcSymyxznCd7po8Zz9hdMLo6eM1WoDTeFa5 yJNXKN2SAFDfchzf8Xi9iOzH9zRb/8JvQR2Wsc/LHfMSAaKgmKJUUQp/zskm9Kk/3+UU DELQ== X-Forwarded-Encrypted: i=1; AJvYcCWGYj5H5fVawSx5549GAIDqct4q+yTO2avlCx5HQvZ28Yd6xGYB+57zn05BWuUxEGn84Vl2yhgfg1hKwRA= X-Gm-Message-State: AOJu0YwzHAyC07Vy0UGYO0++IYXQAsxpx2mWVIRbJoHZQk+6mqSRo2Of rlo2bzcLgdSUuh27FGXhDZ9hU0jo2Hho9LuZF1bBZaulQiYDSx2lYVkPnnW7aHH8myxDAaW5HEr M3TFyZIMCJuy+bGYse16TVv5hg69a0MG8BIVpPA== X-Google-Smtp-Source: AGHT+IG4tvcglCO9wgi014KysiRPnE+V1kjpO3pwLTiLVI6CynbzwdJFelnRQ9nDHWUqNI6vSKRWFUTRUBfG2z3DXjk= X-Received: by 2002:a19:ad41:0:b0:515:c187:e718 with SMTP id s1-20020a19ad41000000b00515c187e718mr3194636lfd.63.1712134842881; Wed, 03 Apr 2024 02:00:42 -0700 (PDT) MIME-Version: 1.0 References: <20240312172558.11844-1-jspewock@iol.unh.edu> <20240312172558.11844-2-jspewock@iol.unh.edu> In-Reply-To: <20240312172558.11844-2-jspewock@iol.unh.edu> From: =?UTF-8?Q?Juraj_Linke=C5=A1?= Date: Wed, 3 Apr 2024 11:00:32 +0200 Message-ID: Subject: Re: [PATCH v1 1/2] dts: Improve output gathering in interactive shells To: jspewock@iol.unh.edu Cc: Honnappa.Nagarahalli@arm.com, thomas@monjalon.net, wathsala.vithanage@arm.com, probb@iol.unh.edu, paul.szczepanek@arm.com, yoan.picchi@foss.arm.com, Luca.Vizzarro@arm.com, dev@dpdk.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org On Tue, Mar 12, 2024 at 6:26=E2=80=AFPM wrote: > > From: Jeremy Spewock > > The current implementation of consuming output from interactive shells > relies on being able to find an expected prompt somewhere within the > output buffer after sending the command. This is useful in situations > where the prompt does not appear in the output itself, but in some > practical cases (such as the starting of an XML-RPC server for scapy) > the prompt exists in one of the commands sent to the shell and this can > cause the command to exit early and creates a race condition between the > server starting and the first command being sent to the server. > > This patch addresses this problem by searching for a line that strictly > ends with the provided prompt, rather than one that simply contains it, > so that the detection that a command is finished is more consistent. It > also adds a catch to detect when a command times out before finding the > prompt so that the exception can be wrapped into a more explicit one and > display the output that it did manage to gather before timing out. > This could still cause problems if the prompt appears at the end of a line in the output. Maybe we don't need to worry about that until we actually hit that problem. In any case, I'd like to test this, so please rebase the patch. :-) > Bugzilla ID: 1359 > Fixes: 88489c0501af ("dts: add smoke tests") > > Signed-off-by: Jeremy Spewock > --- > dts/framework/exception.py | 7 +++++ > .../remote_session/interactive_shell.py | 26 +++++++++++++------ > 2 files changed, 25 insertions(+), 8 deletions(-) > > diff --git a/dts/framework/exception.py b/dts/framework/exception.py > index 658eee2c38..cce1e0231a 100644 > --- a/dts/framework/exception.py > +++ b/dts/framework/exception.py > @@ -146,6 +146,13 @@ def __str__(self) -> str: > return f"Command {self.command} returned a non-zero exit code: {= self._command_return_code}" > > > +class InteractiveCommandExecutionError(DTSError): > + """An unsuccessful execution of a remote command in an interactive e= nvironment.""" > + > + #: > + severity: ClassVar[ErrorSeverity] =3D ErrorSeverity.REMOTE_CMD_EXEC_= ERR > + > + > class RemoteDirectoryExistsError(DTSError): > """A directory that exists on a remote node.""" > > diff --git a/dts/framework/remote_session/interactive_shell.py b/dts/fram= ework/remote_session/interactive_shell.py > index 5cfe202e15..2bcfdcb3c7 100644 > --- a/dts/framework/remote_session/interactive_shell.py > +++ b/dts/framework/remote_session/interactive_shell.py > @@ -20,6 +20,7 @@ > > from paramiko import Channel, SSHClient, channel # type: ignore[import] > > +from framework.exception import InteractiveCommandExecutionError > from framework.logger import DTSLogger > from framework.settings import SETTINGS > > @@ -124,6 +125,10 @@ def send_command(self, command: str, prompt: str | N= one =3D None) -> str: > > Returns: > All output in the buffer before expected string. > + > + Raises: > + InteractiveCommandExecutionError: If command was sent but pr= ompt could not be found in > + the output. > """ > self._logger.info(f"Sending: '{command}'") > if prompt is None: > @@ -131,14 +136,19 @@ def send_command(self, command: str, prompt: str | = None =3D None) -> str: > self._stdin.write(f"{command}{self._command_extra_chars}\n") > self._stdin.flush() > out: str =3D "" > - for line in self._stdout: > - out +=3D line > - if prompt in line and not line.rstrip().endswith( > - command.rstrip() > - ): # ignore line that sent command > - break > - self._logger.debug(f"Got output: {out}") > - return out > + try: > + for line in self._stdout: > + out +=3D line > + if line.rstrip().endswith(prompt): > + break > + except TimeoutError: I like this addition, but maybe we could do better. In the regular SSH session, we're expected to raise: * SSHSessionDeadError if the session is not alive, * SSHTimeoutError if the command execution times out. Can we do that here as well? > + raise InteractiveCommandExecutionError( We could just reuse the SSHTimeoutError exception. Is there a reason to distinguish between interactive and non-interactive timeouts? > + f"Failed to find the prompt ({prompt}) at the end of a l= ine in the output from the" > + f" command ({command}). Got:\n{out}" > + ) > + else: > + self._logger.debug(f"Got output: {out}") > + return out > > def close(self) -> None: > """Properly free all resources.""" > -- > 2.43.2 >