From efb5f35de9607c889fa0787ec000771d3af313fb Mon Sep 17 00:00:00 2001 From: Jan Remmet Date: Tue, 30 May 2023 13:46:55 +0200 Subject: [PATCH] driver: ubootdriver: check for the boot_expression Sets self.boot_detected in _await_prompt. This is used in reset to check if a reboot has occurred. Can also be used in strategies. Direct checking was deprecated with: 7b55a19 ("driver/ubootdriver: deprecate boot_expression attribute") Signed-off-by: Jan Remmet --- doc/configuration.rst | 1 + labgrid/driver/ubootdriver.py | 20 ++++++++++++-------- tests/test_ubootdriver.py | 35 +++++++++++++++++++++++++++-------- 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/doc/configuration.rst b/doc/configuration.rst index c9bacfa5a..4d6bf4c3b 100644 --- a/doc/configuration.rst +++ b/doc/configuration.rst @@ -1601,6 +1601,7 @@ Arguments: - init_commands (tuple): optional, tuple of commands to execute after matching the prompt - password_prompt (str, default="enter Password: "): regex to match the U-Boot password prompt + - boot_expression (regex, default="[\n]U-Boot 20\\d+"): regex to match the U-Boot start string - bootstring (str): optional, regex to match on Linux Kernel boot - boot_command (str, default="run bootcmd"): boot command for booting target - boot_commands (dict, default={}): boot commands by name for LinuxBootProtocol boot command diff --git a/labgrid/driver/ubootdriver.py b/labgrid/driver/ubootdriver.py index d721f598c..c51aa9f1d 100644 --- a/labgrid/driver/ubootdriver.py +++ b/labgrid/driver/ubootdriver.py @@ -25,8 +25,8 @@ class UBootDriver(CommandMixin, Driver, CommandProtocol, LinuxBootProtocol): autoboot (str): optional, string to search for to interrupt autoboot interrupt (str): optional, character to interrupt autoboot and go to prompt password_prompt (str): optional, string to detect the password prompt - boot_expression (str): optional, deprecated - bootstring (str): optional, string that indicates that the Kernel is booting + boot_expression (regex): optional, string to search for on U-Boot start + bootstring (regex): optional, string that indicates that the Kernel is booting boot_command (str): optional boot command to boot target login_timeout (int): optional, timeout for login prompt detection boot_timeout (int): optional, timeout for initial Linux Kernel version detection @@ -39,7 +39,7 @@ class UBootDriver(CommandMixin, Driver, CommandProtocol, LinuxBootProtocol): interrupt = attr.ib(default="\n", validator=attr.validators.instance_of(str)) init_commands = attr.ib(default=attr.Factory(tuple), converter=tuple) password_prompt = attr.ib(default="enter Password:", validator=attr.validators.instance_of(str)) - boot_expression = attr.ib(default="", validator=attr.validators.instance_of(str)) + boot_expression = attr.ib(default=r"[\n]U-Boot 20\d+", validator=attr.validators.instance_of(str)) bootstring = attr.ib(default=r"Linux version \d", validator=attr.validators.instance_of(str)) boot_command = attr.ib(default="run bootcmd", validator=attr.validators.instance_of(str)) boot_commands = attr.ib(default=attr.Factory(dict), validator=attr.validators.instance_of(dict)) @@ -50,10 +50,7 @@ def __attrs_post_init__(self): super().__attrs_post_init__() self.logger = logging.getLogger(f"{self}:{self.target}") self._status = 0 - - if self.boot_expression: - import warnings - warnings.warn("boot_expression is deprecated and will be ignored", DeprecationWarning) + self.boot_detected = False def on_activate(self): """Activate the UBootDriver @@ -140,6 +137,8 @@ def reset(self): self._status = 0 self.console.sendline("reset") self._await_prompt() + if not self.boot_detected: + raise Exception(f"No reboot message detected: {self.boot_expression}") @step() def _await_prompt(self): @@ -154,8 +153,9 @@ def _await_prompt(self): # Because pexpect keeps any read data in it's buffer when a timeout # occours, we can't lose any data this way. last_before = None + self.boot_detected = False - expectations = [self.prompt, self.autoboot, self.password_prompt, TIMEOUT] + expectations = [self.prompt, self.autoboot, self.password_prompt, self.boot_expression, TIMEOUT] while True: index, before, _, _ = self.console.expect( expectations, @@ -174,6 +174,10 @@ def _await_prompt(self): self.console.sendline(self.password) elif index == 3: + # we detect a boot + self.boot_detected = True + + elif index == 4: # expect hit a timeout while waiting for a match if before == last_before: # we did not receive anything during the previous expect cycle diff --git a/tests/test_ubootdriver.py b/tests/test_ubootdriver.py index aa796ed1a..17c90591d 100644 --- a/tests/test_ubootdriver.py +++ b/tests/test_ubootdriver.py @@ -7,6 +7,14 @@ from labgrid.driver import ExecutionError +def _get_active_uboot(target_with_fakeconsole, mocker): + t = target_with_fakeconsole + d = UBootDriver(t, "uboot") + d.console.rxq.append(b"U-Boot 2019\n") + d = t.get_driver(UBootDriver) + return d + + class TestUBootDriver: def test_create(self): t = Target('dummy') @@ -17,10 +25,7 @@ def test_create(self): assert (isinstance(d, LinuxBootProtocol)) def test_uboot_run(self, target_with_fakeconsole, mocker): - t = target_with_fakeconsole - d = UBootDriver(t, "uboot") - d.console.rxq.append(b"U-Boot 2019\n") - d = t.get_driver(UBootDriver) + d = _get_active_uboot(target_with_fakeconsole, mocker) d._run = mocker.MagicMock(return_value=(['success'], [], 0)) res = d.run_check("test") assert res == ['success'] @@ -31,10 +36,7 @@ def test_uboot_run(self, target_with_fakeconsole, mocker): d._run.assert_called_once_with("test", timeout=30) def test_uboot_run_error(self, target_with_fakeconsole, mocker): - t = target_with_fakeconsole - d = UBootDriver(t, "uboot") - d.console.rxq.append(b"U-Boot 2019\n") - d = t.get_driver(UBootDriver) + d = _get_active_uboot(target_with_fakeconsole, mocker) d._run = mocker.MagicMock(return_value=(['error'], [], 1)) with pytest.raises(ExecutionError): res = d.run_check("test") @@ -54,3 +56,20 @@ def test_uboot_boot(self, target_with_fakeconsole): assert d.console.txq.pop() == b"bar\n" with pytest.raises(Exception): d.boot('nop') + + def test_uboot_reset(self, target_with_fakeconsole, mocker): + d = _get_active_uboot(target_with_fakeconsole, mocker) + + d.boot_expression = "[\n]U-Boot 2345" + d.prompt = prompt = "u-boot=>" + d._check_prompt = mocker.MagicMock() + d.console.rxq.extend([prompt.encode(), b"\nU-Boot 2345"]) + d.reset() + + assert d.console.txq.pop() == b"reset\n" + assert d._status == 1 + assert d.boot_detected + + d.console.rxq.append(prompt.encode()) + with pytest.raises(Exception): + d.reset()