Skip to content

Commit

Permalink
driver: bareboxdriver: add boot_expression
Browse files Browse the repository at this point in the history
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.

Signed-off-by: Jan Remmet <[email protected]>
  • Loading branch information
jremmet committed Aug 21, 2023
1 parent 1052d34 commit be38c45
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 13 deletions.
2 changes: 2 additions & 0 deletions doc/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
12 changes: 11 additions & 1 deletion labgrid/driver/bareboxdriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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))
Expand All @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down
42 changes: 30 additions & 12 deletions tests/test_bareboxdriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand All @@ -17,27 +27,35 @@ 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']
res = d.run("test")
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()

0 comments on commit be38c45

Please sign in to comment.