diff --git a/doc/configuration.rst b/doc/configuration.rst index 553418d03..c9bacfa5a 100644 --- a/doc/configuration.rst +++ b/doc/configuration.rst @@ -1681,6 +1681,8 @@ Arguments: - interrupt (str, default="\\n"): string to interrupt autoboot (use "\\x03" for CTRL-C) - bootstring (regex, default="Linux version \\d"): regex that indicating that the Linux Kernel is booting + - boot_expression (regex, default="[\n]barebox 20\d+"): string that indicates that Barebox is + starting - password (str): optional, password to use for access to the shell - login_timeout (int, default=60): timeout for access to the shell diff --git a/labgrid/driver/bareboxdriver.py b/labgrid/driver/bareboxdriver.py index 910f25300..fa2cd4f39 100644 --- a/labgrid/driver/bareboxdriver.py +++ b/labgrid/driver/bareboxdriver.py @@ -26,6 +26,7 @@ class BareboxDriver(CommandMixin, Driver, CommandProtocol, LinuxBootProtocol): prompt (str): barebox prompt to match autoboot (regex): optional, autoboot message to match interrupt (str): optional, string to interrupt autoboot (use "\x03" for CTRL-C) + boot_expression (regex): optional, string to search for on barebox start bootstring (regex): optional, regex indicating that the Linux Kernel is booting password (str): optional, password to use for access to the shell login_timeout (int): optional, timeout for access to the shell @@ -34,6 +35,7 @@ class BareboxDriver(CommandMixin, Driver, CommandProtocol, LinuxBootProtocol): prompt = attr.ib(default="", validator=attr.validators.instance_of(str)) autoboot = attr.ib(default="stop autoboot", validator=attr.validators.instance_of(str)) interrupt = attr.ib(default="\n", validator=attr.validators.instance_of(str)) + boot_expression = attr.ib(default=r"[\n]barebox 20\d+", validator=attr.validators.instance_of(str)) bootstring = attr.ib(default=r"Linux version \d", validator=attr.validators.instance_of(str)) password = attr.ib(default="", validator=attr.validators.instance_of(str)) login_timeout = attr.ib(default=60, validator=attr.validators.instance_of(int)) @@ -42,6 +44,7 @@ def __attrs_post_init__(self): super().__attrs_post_init__() self.logger = logging.getLogger(f"{self}:{self.target}") self._status = 0 + self.boot_detected = False # barebox' default log level, used as fallback if no log level can be saved self.saved_log_level = 7 @@ -110,6 +113,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}") def get_status(self): """Retrieve status of the BareboxDriver @@ -150,8 +155,9 @@ def _await_prompt(self): # occours, we can't lose any data this way. last_before = None password_entered = False + self.boot_detected = False - expectations = [self.prompt, self.autoboot, "Password: ", TIMEOUT] + expectations = [self.prompt, self.autoboot, "Password: ", self.boot_expression, TIMEOUT] while True: index, before, _, _ = self.console.expect( expectations, @@ -179,6 +185,10 @@ def _await_prompt(self): password_entered = True 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_bareboxdriver.py b/tests/test_bareboxdriver.py index 9842a17c8..fad3b74a3 100644 --- a/tests/test_bareboxdriver.py +++ b/tests/test_bareboxdriver.py @@ -7,6 +7,16 @@ from labgrid.driver import ExecutionError +def _get_active_barebox(target_with_fakeconsole, mocker): + t = target_with_fakeconsole + d = BareboxDriver(t, "barebox") + d = t.get_driver(BareboxDriver, activate=False) + # mock for d._run('echo $global.loglevel') + d._run = mocker.MagicMock(return_value=(['7'], [], 0)) + t.activate(d) + return d + + class TestBareboxDriver: def test_create(self): t = Target('dummy') @@ -17,12 +27,7 @@ def test_create(self): assert (isinstance(d, LinuxBootProtocol)) def test_barebox_run(self, target_with_fakeconsole, mocker): - t = target_with_fakeconsole - d = BareboxDriver(t, "barebox") - d = t.get_driver(BareboxDriver, activate=False) - # mock for d._run('echo $global.loglevel') - d._run = mocker.MagicMock(return_value=(['7'], [], 0)) - t.activate(d) + d = _get_active_barebox(target_with_fakeconsole, mocker) d._run = mocker.MagicMock(return_value=(['success'], [], 0)) res = d.run_check("test") assert res == ['success'] @@ -30,14 +35,27 @@ def test_barebox_run(self, target_with_fakeconsole, mocker): assert res == (['success'], [], 0) def test_barebox_run_error(self, target_with_fakeconsole, mocker): - t = target_with_fakeconsole - d = BareboxDriver(t, "barebox") - d = t.get_driver(BareboxDriver, activate=False) - # mock for d._run('echo $global.loglevel') - d._run = mocker.MagicMock(return_value=(['7'], [], 0)) - t.activate(d) + d = _get_active_barebox(target_with_fakeconsole, mocker) d._run = mocker.MagicMock(return_value=(['error'], [], 1)) with pytest.raises(ExecutionError): res = d.run_check("test") res = d.run("test") assert res == (['error'], [], 1) + + def test_barebox_reset(self, target_with_fakeconsole, mocker): + d = _get_active_barebox(target_with_fakeconsole, mocker) + + d.boot_expression = "[\n]barebox 2345" + d.prompt = prompt = ">=" + d._check_prompt = mocker.MagicMock() + d.console.rxq.extend([prompt.encode(), b"\nbarebox 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() +