diff --git a/labgrid/remote/client.py b/labgrid/remote/client.py index 4d2eb0bfa..d9f9fbf8e 100755 --- a/labgrid/remote/client.py +++ b/labgrid/remote/client.py @@ -28,6 +28,7 @@ import attr import grpc +import yaml # TODO: drop if Python >= 3.11 guaranteed from exceptiongroup import ExceptionGroup # pylint: disable=redefined-builtin @@ -932,6 +933,19 @@ def _get_driver_or_new(self, target, cls, *, name=None, activate=True): target.activate(drv) return drv + def _parse_driver_args(self, args): + parsed = {} + for arg in args: + try: + key, value = arg.split("=", 1) + except ValueError: + raise UserError(f"invalid bootstrap argument '{arg}', expected key=value") + try: + parsed[key] = yaml.safe_load(value) + except yaml.YAMLError as e: + raise UserError(f"invalid value for bootstrap argument '{key}': {e}") from e + return parsed + def power(self): place = self.get_acquired_place() action = self.args.action @@ -1176,10 +1190,12 @@ def bootstrap(self): NetworkIMXUSBLoader, NetworkRKUSBLoader, NetworkAlteraUSBBlaster, + NetworkUSBDebugger, ) from ..driver import OpenOCDDriver drv = None + args = self._parse_driver_args(self.args.bootstrap_args) try: drv = target.get_driver("BootstrapProtocol", name=name) except NoDriverFoundError: @@ -1192,8 +1208,7 @@ def bootstrap(self): elif isinstance(resource, NetworkMXSUSBLoader): drv = self._get_driver_or_new(target, "MXSUSBDriver", activate=False, name=name) drv.loader.timeout = self.args.wait - elif isinstance(resource, NetworkAlteraUSBBlaster): - args = dict(arg.split("=", 1) for arg in self.args.bootstrap_args) + elif isinstance(resource, (NetworkAlteraUSBBlaster, NetworkUSBDebugger)): try: drv = target.get_driver("OpenOCDDriver", activate=False, name=name) except NoDriverFoundError: diff --git a/tests/test_openocd_client.py b/tests/test_openocd_client.py new file mode 100644 index 000000000..9ca6a3449 --- /dev/null +++ b/tests/test_openocd_client.py @@ -0,0 +1,81 @@ +import argparse + +import pytest + +from labgrid import Target +from labgrid.driver.openocddriver import OpenOCDDriver +from labgrid.remote.client import ClientSession, UserError +from labgrid.resource.remote import NetworkUSBDebugger + + +def test_parse_driver_args(): + session = object.__new__(ClientSession) + + args = session._parse_driver_args([ + 'search=["path"]', + 'load_commands=["init", "shutdown"]', + 'board_config=board.cfg', + ]) + + assert args == { + "search": ["path"], + "load_commands": ["init", "shutdown"], + "board_config": "board.cfg", + } + + +def test_parse_driver_args_invalid(): + session = object.__new__(ClientSession) + + with pytest.raises(UserError, match="expected key=value"): + session._parse_driver_args(["load_commands"]) + + with pytest.raises(UserError, match="invalid value for bootstrap argument 'search'"): + session._parse_driver_args(['search=["path"']) + + +def test_bootstrap_network_usb_debugger(monkeypatch): + target = Target("test") + debugger = NetworkUSBDebugger( + target, + name=None, + host="host", + busnum=1, + devnum=2, + path="1-2", + vendor_id=1, + model_id=2, + ) + monkeypatch.setattr(debugger.manager, "poll", lambda: None) + debugger.avail = True + + session = object.__new__(ClientSession) + session.args = argparse.Namespace( + wait=12.5, + name=None, + filename="dummy", + bootstrap_args=[ + 'search=["path"]', + 'load_commands=["init", "shutdown"]', + 'interface_config=interface.cfg', + ], + ) + session.get_acquired_place = lambda: argparse.Namespace(name="test") + session._get_target = lambda place: target + + load_calls = [] + + def fake_load(self, filename=None): + load_calls.append((self, filename)) + + monkeypatch.setattr(OpenOCDDriver, "load", fake_load) + + session.bootstrap() + + driver = target.get_driver(OpenOCDDriver, activate=False) + assert driver.interface is debugger + assert driver.interface.timeout == 12.5 + assert driver.search == ["path"] + assert driver.load_commands == ["init", "shutdown"] + assert driver.interface_config == "interface.cfg" + assert load_calls == [(driver, "dummy")]