From 20409ca2cc373bdd5af7d845a6f31cb2cef8618c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=BCnther?= Date: Wed, 10 Jul 2024 17:41:33 +0200 Subject: [PATCH] doc: add get_filtered_output method documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add documentation for the get_filtered_output method in both the Python implementation and the Integration with pytest chapter. The method is used to filter command outputs by removing prompts and log messages, making it easier to process shell command results. Signed-off-by: Thomas Günther removed traling whitespace --- doc/develop/test/pytest.rst | 2 + .../src/twister_harness/helpers/shell.py | 49 ++++++++++++++----- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/doc/develop/test/pytest.rst b/doc/develop/test/pytest.rst index 9bf95c030989..88137a691747 100644 --- a/doc/develop/test/pytest.rst +++ b/doc/develop/test/pytest.rst @@ -219,6 +219,8 @@ Shell .. automethod:: wait_for_prompt + .. automethod:: get_filtered_output + Examples of pytest tests in the Zephyr project ********************************************** diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py index 7782617538c7..0960db7743ae 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py @@ -22,7 +22,9 @@ class Shell: Helper class that provides methods used to interact with shell application. """ - def __init__(self, device: DeviceAdapter, prompt: str = 'uart:~$', timeout: float | None = None) -> None: + def __init__( + self, device: DeviceAdapter, prompt: str = 'uart:~$', timeout: float | None = None + ) -> None: self._device: DeviceAdapter = device self.prompt: str = prompt self.base_timeout: float = timeout or device.base_timeout @@ -48,7 +50,9 @@ def wait_for_prompt(self, timeout: float | None = None) -> bool: return True return False - def exec_command(self, command: str, timeout: float | None = None, print_output: bool = True) -> list[str]: + def exec_command( + self, command: str, timeout: float | None = None, print_output: bool = True + ) -> list[str]: """ Send shell command to a device and return response. Passed command is extended by double enter sings - first one to execute this command @@ -63,20 +67,42 @@ def exec_command(self, command: str, timeout: float | None = None, print_output: self._device.write(command_ext.encode()) lines: list[str] = [] # wait for device command print - it should be done immediately after sending command to device - lines.extend(self._device.readlines_until(regex=regex_command, timeout=1.0, print_output=print_output)) + lines.extend( + self._device.readlines_until( + regex=regex_command, timeout=1.0, print_output=print_output + ) + ) # wait for device command execution - lines.extend(self._device.readlines_until(regex=regex_prompt, timeout=timeout, print_output=print_output)) + lines.extend( + self._device.readlines_until( + regex=regex_prompt, timeout=timeout, print_output=print_output + ) + ) return lines def get_filtered_output(self, command_lines: list[str]) -> list[str]: + """ + Filter out prompts and log messages + + Take the output of exec_command, which can contain log messages and command prompts, + and filter them to obtain only the command output. + + Example: + >>> # equivalent to `lines = shell.exec_command("kernel version")` + >>> lines = [ + >>> 'uart:~$', # filter prompts + >>> 'Zephyr version 3.6.0', # keep this line + >>> 'uart:~$ debug message' # filter log messages + >>> ] + >>> filtered_output = shell.get_filtered_output(output) + >>> filtered_output + ['Zephyr version 3.6.0'] + + :param command_lines: List of strings i.e. the output of `exec_command`. + :return: A list of strings containing, excluding prompts and log messages. + """ regex_filter = re.compile( - '|'.join([ - re.escape(self.prompt), - '', - '', - '', - '' - ]) + '|'.join([re.escape(self.prompt), '', '', '', '']) ) return list(filter(lambda l: not regex_filter.search(l), command_lines)) @@ -106,6 +132,7 @@ class ShellMCUbootCommandParsed: """ Helper class to keep data from `mcuboot` shell command. """ + areas: list[ShellMCUbootArea] = field(default_factory=list) @classmethod