diff --git a/doc/configuration.rst b/doc/configuration.rst index d1fbf210c..7fd20884c 100644 --- a/doc/configuration.rst +++ b/doc/configuration.rst @@ -1656,6 +1656,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 cc1cd0d4b..a8293794d 100644 --- a/labgrid/driver/ubootdriver.py +++ b/labgrid/driver/ubootdriver.py @@ -23,8 +23,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 @@ -37,7 +37,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)) @@ -47,10 +47,7 @@ class UBootDriver(CommandMixin, Driver, CommandProtocol, LinuxBootProtocol): def __attrs_post_init__(self): super().__attrs_post_init__() 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 @@ -137,6 +134,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): @@ -151,8 +150,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, @@ -171,6 +171,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()