diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ef7454b6..962ba790 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -8,14 +8,14 @@ exclude: | repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.6.0 + rev: v5.0.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: mixed-line-ending args: ["-f=lf"] - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: "v0.6.1" + rev: "v0.8.1" hooks: - id: ruff args: ["--fix"] @@ -24,7 +24,7 @@ repos: # documentation - repo: https://github.com/sphinx-contrib/sphinx-lint - rev: v0.9.1 + rev: v1.0.0 hooks: - id: sphinx-lint args: [--enable=default-role] diff --git a/pytest-embedded-jtag/pytest_embedded_jtag/_telnetlib/telnetlib.py b/pytest-embedded-jtag/pytest_embedded_jtag/_telnetlib/telnetlib.py index bc301c8e..5db30d67 100644 --- a/pytest-embedded-jtag/pytest_embedded_jtag/_telnetlib/telnetlib.py +++ b/pytest-embedded-jtag/pytest_embedded_jtag/_telnetlib/telnetlib.py @@ -474,21 +474,21 @@ def process_rawq(self): # We can't offer automatic processing of # suboptions. Alas, we should not get any # unless we did a WILL/DO before. - self.msg('IAC %d not recognized' % ord(c)) + self.msg(f'IAC {ord(c):d} not recognized') elif len(self.iacseq) == 2: cmd = self.iacseq[1:2] self.iacseq = b'' opt = c if cmd in (DO, DONT): self.msg('IAC %s %d', - cmd == DO and 'DO' or 'DONT', ord(opt)) + (cmd == DO and 'DO') or 'DONT', ord(opt)) if self.option_callback: self.option_callback(self.sock, cmd, opt) else: self.sock.sendall(IAC + WONT + opt) elif cmd in (WILL, WONT): self.msg('IAC %s %d', - cmd == WILL and 'WILL' or 'WONT', ord(opt)) + (cmd == WILL and 'WILL') or 'WONT', ord(opt)) if self.option_callback: self.option_callback(self.sock, cmd, opt) else: diff --git a/pytest-embedded-nuttx/pytest_embedded_nuttx/__init__.py b/pytest-embedded-nuttx/pytest_embedded_nuttx/__init__.py index f207690a..a40cc890 100644 --- a/pytest-embedded-nuttx/pytest_embedded_nuttx/__init__.py +++ b/pytest-embedded-nuttx/pytest_embedded_nuttx/__init__.py @@ -4,22 +4,23 @@ from pytest_embedded.utils import lazy_load -from .dut import NuttxDut, NuttxEspDut, NuttxQemuDut, NuttxSerialDut +from .app import NuttxApp +from .dut import NuttxDut, NuttxSerialDut __getattr__ = lazy_load( importlib.import_module(__name__), { + 'NuttxApp': NuttxApp, 'NuttxDut': NuttxDut, 'NuttxSerialDut': NuttxSerialDut, - 'NuttxEspDut': NuttxEspDut, # requires 'esp' service - 'NuttxQemuDut': NuttxQemuDut, # requires 'qemu' service }, { - 'NuttxApp': '.app', # requires 'esp' service 'NuttxSerial': '.serial', # requires 'esp' service + 'NuttxEspDut': '.serial', # requires 'esp' service + 'NuttxQemuDut': '.qemu', # requires 'qemu' service }, ) -__all__ = ['NuttxApp', 'NuttxSerial', 'NuttxSerialDut', 'NuttxQemuDut', 'NuttxEspDut', 'NuttxDut'] +__all__ = ['NuttxApp', 'NuttxDut', 'NuttxEspDut', 'NuttxQemuDut', 'NuttxSerial', 'NuttxSerialDut'] __version__ = '1.12.0' diff --git a/pytest-embedded-nuttx/pytest_embedded_nuttx/app.py b/pytest-embedded-nuttx/pytest_embedded_nuttx/app.py index 7cd1b567..f7cd5cf2 100644 --- a/pytest-embedded-nuttx/pytest_embedded_nuttx/app.py +++ b/pytest-embedded-nuttx/pytest_embedded_nuttx/app.py @@ -1,4 +1,5 @@ import logging +import typing as t from pathlib import Path from pytest_embedded.app import App @@ -22,17 +23,16 @@ def __init__( super().__init__(**kwargs) self.file_extension = file_extension - files = self._get_bin_files() - self.app_file, self.bootloader_file, self.merge_file = files + self.app_file, self.bootloader_file, self.merge_file = self._get_bin_files() - def _get_bin_files(self) -> list: + def _get_bin_files(self) -> t.Tuple[t.Optional[Path], t.Optional[Path], t.Optional[Path]]: """ Get path to binary files available in the app_path. If either the application image or bootloader is not found, None is returned. Returns: - list: path to application binary file and bootloader file. + tuple: path to application binary file and bootloader file. """ search_path = Path(self.app_path) search_pattern = '*' + self.file_extension diff --git a/pytest-embedded-nuttx/pytest_embedded_nuttx/dut.py b/pytest-embedded-nuttx/pytest_embedded_nuttx/dut.py index 21a54e44..2b2baaf3 100644 --- a/pytest-embedded-nuttx/pytest_embedded_nuttx/dut.py +++ b/pytest-embedded-nuttx/pytest_embedded_nuttx/dut.py @@ -1,16 +1,11 @@ import logging import re from time import sleep -from typing import TYPE_CHECKING, AnyStr +from typing import AnyStr import pexpect from pytest_embedded.dut import Dut -from pytest_embedded_qemu.dut import QemuDut -from pytest_embedded_qemu.qemu import Qemu -from pytest_embedded_serial.dut import SerialDut - -if TYPE_CHECKING: - from .app import NuttxApp +from pytest_embedded_serial import SerialDut class NuttxDut(Dut): @@ -111,40 +106,3 @@ def reset(self) -> None: self.serial.proc.dtr = False sleep(0.2) self.serial.proc.dtr = True - - -class NuttxQemuDut(QemuDut, NuttxDut): - """ - DUT class for QEMU usage of the NuttX RTOS. - """ - - def __init__( - self, - qemu: Qemu, - **kwargs, - ) -> None: - self.qemu = qemu - - super().__init__(qemu=qemu, **kwargs) - - def reset(self) -> None: - """Hard reset the DUT.""" - self.hard_reset() - - -class NuttxEspDut(NuttxSerialDut): - """ - DUT class for serial ports connected to Espressif boards which are - flashed with NuttX RTOS. - """ - - def __init__( - self, - app: 'NuttxApp', - **kwargs, - ) -> None: - super().__init__(app=app, **kwargs) - - def reset(self) -> None: - """Resets the board.""" - self.serial.hard_reset() diff --git a/pytest-embedded-nuttx/pytest_embedded_nuttx/qemu.py b/pytest-embedded-nuttx/pytest_embedded_nuttx/qemu.py new file mode 100644 index 00000000..51d14926 --- /dev/null +++ b/pytest-embedded-nuttx/pytest_embedded_nuttx/qemu.py @@ -0,0 +1,22 @@ +from pytest_embedded_qemu import Qemu, QemuDut + +from .dut import NuttxDut + + +class NuttxQemuDut(QemuDut, NuttxDut): + """ + DUT class for QEMU usage of the NuttX RTOS. + """ + + def __init__( + self, + qemu: Qemu, + **kwargs, + ) -> None: + self.qemu = qemu + + super().__init__(qemu=qemu, **kwargs) + + def reset(self) -> None: + """Hard reset the DUT.""" + self.hard_reset() diff --git a/pytest-embedded-nuttx/pytest_embedded_nuttx/serial.py b/pytest-embedded-nuttx/pytest_embedded_nuttx/serial.py index da2193b7..6fc30733 100644 --- a/pytest-embedded-nuttx/pytest_embedded_nuttx/serial.py +++ b/pytest-embedded-nuttx/pytest_embedded_nuttx/serial.py @@ -5,6 +5,7 @@ from pytest_embedded_serial_esp.serial import EspSerial from .app import NuttxApp +from .dut import NuttxSerialDut class NuttxSerial(EspSerial): @@ -109,3 +110,22 @@ def flash(self) -> None: ], esp=self.esp, ) + + +class NuttxEspDut(NuttxSerialDut): + """ + DUT class for serial ports connected to Espressif boards which are + flashed with NuttX RTOS. + """ + + def __init__( + self, + app: NuttxApp, + **kwargs, + ) -> None: + super().__init__(app=app, **kwargs) + + def reset(self) -> None: + """Resets the board.""" + self.serial: NuttxSerial + self.serial.hard_reset() diff --git a/pytest-embedded-serial/pytest_embedded_serial/serial.py b/pytest-embedded-serial/pytest_embedded_serial/serial.py index f694673c..1bfb1d6a 100644 --- a/pytest-embedded-serial/pytest_embedded_serial/serial.py +++ b/pytest-embedded-serial/pytest_embedded_serial/serial.py @@ -198,7 +198,7 @@ def _event_loop(self): return except Exception as e: logging.warning( - 'unknown error: %s.\n' 'Recommend to close the serial process by `dut.serial.close()`', str(e) + 'unknown error: %s.\nRecommend to close the serial process by `dut.serial.close()`', str(e) ) return diff --git a/pytest-embedded/pytest_embedded/plugin.py b/pytest-embedded/pytest_embedded/plugin.py index d990ad11..8fa9c69a 100644 --- a/pytest-embedded/pytest_embedded/plugin.py +++ b/pytest-embedded/pytest_embedded/plugin.py @@ -108,12 +108,11 @@ def pytest_addoption(parser): ) base_group.addoption( '--prettify-junit-report', - help='y/yes/true for True and n/no/false for False. ' - 'Set to True to prettify XML junit report. (Default: False)', + help='y/yes/true for True and n/no/false for False. Set to True to prettify XML junit report. (Default: False)', ) parser.addoption( '--unity-test-report-mode', - choices=[UnityTestReportMode.REPLACE.value, UnityTestReportMode.MERGE.value], + choices=[mode.value for mode in UnityTestReportMode], default=UnityTestReportMode.REPLACE.value, help=( 'Specify the behavior for handling Unity test cases in the main JUnit report. ' @@ -125,7 +124,7 @@ def pytest_addoption(parser): # supports parametrization base_group.addoption('--root-logdir', help='set session-based root log dir. (Default: system temp folder)') base_group.addoption( - '--cache-dir', help='set root cache-dir for storing cache files. \n' '(Default: system temp folder)' + '--cache-dir', help='set root cache-dir for storing cache files. \n(Default: system temp folder)' ) base_group.addoption( '--embedded-services', @@ -271,8 +270,7 @@ def pytest_addoption(parser): ) qemu_group.addoption( '--encrypt', - help='y/yes/true for True and n/no/false for False. ' - 'Set to True for pre-encryption workflow (Default: False)', + help='y/yes/true for True and n/no/false for False. Set to True for pre-encryption workflow (Default: False)', ) qemu_group.addoption( '--keyfile', @@ -1194,7 +1192,7 @@ def unity_tester(dut: t.Union['IdfDut', t.Tuple['IdfDut']]) -> t.Optional['CaseT def pytest_configure(config: Config) -> None: config.stash[_junit_merger_key] = JunitMerger( - config.option.xmlpath, config.getoption('unity_test_report_mode', default='replace') + config.option.xmlpath, config.getoption('unity_test_report_mode', UnityTestReportMode.REPLACE.value) ) config.stash[_junit_report_path_key] = config.option.xmlpath diff --git a/pytest-embedded/pytest_embedded/unity.py b/pytest-embedded/pytest_embedded/unity.py index 5062eed9..76f16e2d 100644 --- a/pytest-embedded/pytest_embedded/unity.py +++ b/pytest-embedded/pytest_embedded/unity.py @@ -55,7 +55,7 @@ (0x10FFFE, 0x10FFFF), ] ILLEGAL_XML_CHAR_REGEX = re.compile( - f"[{''.join([f'{chr(lower)}-{chr(upper)}' for lower, upper in _avoid_compatibility_chars])}]" + f'[{"".join([f"{chr(lower)}-{chr(upper)}" for lower, upper in _avoid_compatibility_chars])}]' ) @@ -183,7 +183,7 @@ def add_unity_test_cases(self, s: AnyStr, additional_attrs: Optional[Dict[str, A self.attrs['tests'] += 1 if not self.testcases: - raise ValueError(f'unity test case not found, buffer:\n' f'{s}') + raise ValueError(f'unity test case not found, buffer:\n{s}') def to_xml(self) -> ET.Element: if self._xml: