Example #1
0
def test_simple_mapping(tmpdir):
    device_info = {"foo": "bar"}
    add_device_container_mapping("1", device_info, "mycontainer")
    data = yaml_load(open(tmpdir / "1" / "usbmap.yaml"))[0]

    assert data["device_info"] == device_info
    assert data["container"] == "mycontainer"
    assert data["container_type"] == "lxc"
Example #2
0
def test_share_device_setup_logger(mocker):
    check_call = mocker.patch("subprocess.check_call")
    add_device_container_mapping("1", {"serial_number": "1234567890"},
                                 "mycontainer")
    setup_logger = mocker.Mock()
    share_device_with_container(
        Namespace(device="foo", serial_number="1234567890"), setup_logger)
    setup_logger.assert_called_once_with(mocker.ANY)
Example #3
0
def test_only_adds_slash_dev_if_needed(mocker):
    share = mocker.patch(
        "lava_dispatcher_host.share_device_with_container_lxc")
    add_device_container_mapping("1", {"serial_number": "1234567890"},
                                 "mycontainer")
    share_device_with_container(
        Namespace(device="/dev/foo/bar", serial_number="1234567890"))
    share.assert_called_once_with("mycontainer", "/dev/foo/bar")
Example #4
0
def test_device_missing(mocker):
    mocker.patch("os.path.exists", return_value=False)
    check_call = mocker.patch("subprocess.check_call")
    add_device_container_mapping("1", {"serial_number": "1234567890"},
                                 "mycontainer")
    share_device_with_container(
        Namespace(device="foo/bar", serial_number="1234567890"))
    check_call.assert_not_called()
Example #5
0
def test_simple_share_device_with_container(mocker):
    check_call = mocker.patch("subprocess.check_call")
    add_device_container_mapping("1", {"serial_number": "1234567890"},
                                 "mycontainer")
    share_device_with_container(
        Namespace(device="foo/bar", serial_number="1234567890"))

    check_call.assert_called_once_with(
        ["lxc-device", "-n", "mycontainer", "add", "/dev/foo/bar"])
Example #6
0
def handle_devices_map(options):
    container = options.container
    container_type = options.container_type
    job_id = "0"  # fake map
    fields = ["serial_number", "usb_vendor_id", "usb_product_id", "fs_label"]
    device_info = {
        k: options.__dict__[k] for k in fields if k in options and options.__dict__[k]
    }
    add_device_container_mapping(job_id, device_info, container, container_type)
Example #7
0
    def run(self, connection, max_end_time):
        connection = super().run(connection, max_end_time)
        # this may be the device namespace - the lxc namespace may not be
        # accessible
        lxc_name = None
        protocols = [
            protocol for protocol in self.job.protocols
            if protocol.name == LxcProtocol.name
        ]
        if protocols:
            lxc_name = protocols[0].lxc_name
        if not lxc_name:
            self.logger.debug("No LXC device requested")
            return connection

        # If there is no device_info then this action should be idempotent.
        if "device_info" not in self.job.device:
            return connection

        device_info = self.job.device.get("device_info", [])
        logging_url = master_cert = slave_cert = socks_proxy = ipv6 = None
        job_id = self.job.job_id

        if self.logger.handler:
            logging_url = self.logger.handler.logging_url
            master_cert = self.logger.handler.master_cert
            slave_cert = self.logger.handler.slave_cert
            socks_proxy = self.logger.handler.socks_proxy
            ipv6 = self.logger.handler.ipv6
            job_id = self.logger.handler.job_id

        logging = {
            "logging_url": logging_url,
            "master_cert": master_cert,
            "slave_cert": slave_cert,
            "socks_proxy": socks_proxy,
            "ipv6": ipv6,
            "job_id": job_id,
        }

        job_prefix = self.job.parameters["dispatcher"].get("prefix", "")
        for device in device_info:
            data = {
                "serial_number": str(device.get("board_id", "")),
                "vendor_id": device.get("usb_vendor_id"),
                "product_id": device.get("usb_product_id"),
                "fs_label": device.get("fs_label"),
            }
            add_device_container_mapping(
                job_prefix + job_id,
                data,
                lxc_name,
                container_type="lxc",
                logging_info=logging,
            )
        return connection
Example #8
0
def test_second_mapping_does_not_invalidate_first(mocker):
    share = mocker.patch(
        "lava_dispatcher_host.share_device_with_container_lxc")
    add_device_container_mapping("1", {"serial_number": "1234567890"},
                                 "mycontainer1")
    add_device_container_mapping("1", {"serial_number": "badbeeb00c"},
                                 "mycontainer1")
    share_device_with_container(
        Namespace(device="/dev/foo/bar", serial_number="1234567890"))
    share.assert_called_once_with("mycontainer1", "/dev/foo/bar")
Example #9
0
def test_unknown_container_type(mocker):
    add_device_container_mapping(
        "1",
        {"serial_number": "1234567890"},
        "mycontainer",
        container_type="unsupported",
    )
    with pytest.raises(InfrastructureError):
        share_device_with_container(
            Namespace(device="foo/bar", serial_number="1234567890"))
Example #10
0
def test_two_concurrent_jobs(mocker, pass_device_lxc, device_links):
    add_device_container_mapping("1", {"serial_number": "1234567890"},
                                 "container1")
    add_device_container_mapping("2", {"serial_number": "9876543210"},
                                 "container2")
    share_device_with_container(
        Namespace(device="baz/qux", serial_number="9876543210"))

    pass_device_lxc.assert_called_once_with("container2", "/dev/baz/qux",
                                            device_links, "2")
Example #11
0
File: docker.py Project: slawr/lava
    def run(self, connection, max_end_time):
        # obtain lava overlay
        # start container
        # create USB device mapping to container
        # connect to container, and run lava-test-shell over it
        location = self.get_namespace_data(action="test",
                                           label="shared",
                                           key="location")
        overlay = self.get_namespace_data(
            action="test", label="results",
            key="lava_test_results_dir").strip("/")

        image = self.parameters["docker"]["image"]
        container = "lava-docker-test-shell-%s-%s" % (self.job.job_id,
                                                      self.level)

        board_id = self.get_board_id()
        device_info = {"board_id": board_id}
        add_device_container_mapping(
            job_id=self.job.job_id,
            device_info=device_info,
            container=container,
            container_type="docker",
            logging_info=self.get_logging_info(),
        )

        docker = DockerRun(image)
        docker.bind_mount(os.path.join(location, overlay), "/" + overlay)
        docker.interactive()
        docker.hostname("lava")
        docker.name(container)
        docker.environment("PS1", "docker-test-shell:$ ")
        if self.wait_for_device:
            devices = get_udev_devices(device_info=[device_info])
            for dev in devices:
                docker.add_device(dev)

        docker_cmd = docker.cmdline("bash", "--norc", "-i")

        cmd = " ".join([shlex.quote(s) for s in docker_cmd])
        self.logger.debug("Starting docker test shell container: %s" % cmd)
        shell = ShellCommand(cmd, self.timeout, logger=self.logger)

        shell_connection = ShellSession(self.job, shell)
        shell_connection.prompt_str = "docker-test-shell:"

        self.__set_connection__(shell_connection)
        super().run(shell_connection, max_end_time)

        # finish the container
        shell_connection.finalise()

        # return the original connection untouched
        self.__set_connection__(connection)
        return connection
Example #12
0
def test_two_concurrent_jobs(mocker):
    check_call = mocker.patch("subprocess.check_call")
    add_device_container_mapping("1", {"serial_number": "1234567890"},
                                 "container1")
    add_device_container_mapping("2", {"serial_number": "9876543210"},
                                 "container2")
    share_device_with_container(
        Namespace(device="baz/qux", serial_number="9876543210"))

    check_call.assert_called_once_with(
        ["lxc-device", "-n", "container2", "add", "/dev/baz/qux"])
Example #13
0
def test_share_device_setup_logger(mocker):
    check_call = mocker.patch("subprocess.check_call")
    add_device_container_mapping(
        "1",
        {"serial_number": "1234567890"},
        "mycontainer",
        logging_info={"logging_url": "proto://host"},
    )
    setup_logger = mocker.Mock()
    share_device_with_container(
        Namespace(device="foo", serial_number="1234567890"), setup_logger)
    setup_logger.assert_called()
Example #14
0
def test_two_devices_two_containers(mocker):
    share = mocker.patch("lava_dispatcher_host.share_device_with_container_lxc")
    add_device_container_mapping("1", {"serial_number": "1234567890"}, "mycontainer1")
    add_device_container_mapping("1", {"serial_number": "badbeeb00c"}, "mycontainer2")
    share_device_with_container(
        Namespace(device="/dev/foo/bar", serial_number="1234567890")
    )
    share.assert_called_once_with("mycontainer1", "/dev/foo/bar")
    share.reset_mock()

    share_device_with_container(
        Namespace(device="/dev/foo/bar", serial_number="badbeeb00c")
    )
    share.assert_called_once_with("mycontainer2", "/dev/foo/bar")
Example #15
0
def test_map_by_vendor_id_and_product_id(mocker, pass_device_lxc, device_links):
    add_device_container_mapping(
        "1", {"vendor_id": "aaaa", "product_id": "xxxx"}, "container1"
    )
    share_device_with_container(
        Namespace(
            device="bus/usb/001/099",
            serial_number="9876543210",
            vendor_id="aaaa",
            product_id="xxxx",
        )
    )
    pass_device_lxc.assert_called_once_with(
        "container1", "/dev/bus/usb/001/099", device_links
    )
Example #16
0
def test_map_by_vendor_id_and_product_id(mocker):
    check_call = mocker.patch("subprocess.check_call")
    add_device_container_mapping("1", {
        "vendor_id": "aaaa",
        "product_id": "xxxx"
    }, "container1")
    share_device_with_container(
        Namespace(
            device="bus/usb/001/099",
            serial_number="9876543210",
            vendor_id="aaaa",
            product_id="xxxx",
        ))
    check_call.assert_called_once_with(
        ["lxc-device", "-n", "container1", "add", "/dev/bus/usb/001/099"])
Example #17
0
 def add_device_container_mappings(self, container, container_type):
     device_info = self.job.device.get("device_info", [])
     job_id = self.job.job_id
     job_prefix = self.job.parameters["dispatcher"].get("prefix", "")
     devices = []
     for origdevice in device_info:
         device = origdevice.copy()
         if "board_id" in device:
             device["serial_number"] = device["board_id"]
             del device["board_id"]
         devices.append(device)
     for device in devices:
         add_device_container_mapping(job_prefix + job_id,
                                      device,
                                      container,
                                      container_type=container_type)
Example #18
0
 def add_device_container_mappings(self, container, container_type):
     device_info = self.job.device.get("device_info", [])
     static_info = self.job.device.get("static_info", [])
     job_id = self.job.job_id
     job_prefix = self.job.parameters["dispatcher"].get("prefix", "")
     devices = []
     for origdevice in device_info + static_info:
         device = origdevice.copy()
         if "board_id" in device:
             device["serial_number"] = device["board_id"]
             del device["board_id"]
         devices.append(device)
     for device in devices:
         add_device_container_mapping(job_prefix + job_id,
                                      device,
                                      container,
                                      container_type=container_type)
         logger = logging.getLogger("dispatcher")
         logger.info(
             f"Added mapping for {device} to {container_type} container {container}"
         )
Example #19
0
def test_mapping_with_serial_number_but_called_with_vendor_product_id_too(
        mocker, pass_device_lxc, device_links):
    add_device_container_mapping(
        "1",
        {
            "serial_number": "1234567890",
            "vendor_id": None,
            "product_id": None,
            "fs_label": None,
        },
        "mycontainer",
    )
    share_device_with_container(
        Namespace(
            device="foo/bar",
            serial_number="1234567890",
            vendor_id="0123",
            product_id="4567",
        ))

    pass_device_lxc.assert_called_once_with("mycontainer", "/dev/foo/bar",
                                            device_links, "1")
Example #20
0
def test_mapping_with_serial_number_but_called_with_vendor_product_id_too(
        mocker):
    check_call = mocker.patch("subprocess.check_call")
    add_device_container_mapping(
        "1",
        {
            "serial_number": "1234567890",
            "vendor_id": None,
            "product_id": None,
            "fs_label": None,
        },
        "mycontainer",
    )
    share_device_with_container(
        Namespace(
            device="foo/bar",
            serial_number="1234567890",
            vendor_id="0123",
            product_id="4567",
        ))

    check_call.assert_called_once_with(
        ["lxc-device", "-n", "mycontainer", "add", "/dev/foo/bar"])
Example #21
0
File: lxc.py Project: slawr/lava
    def run(self, connection, max_end_time):
        connection = super().run(connection, max_end_time)
        # this may be the device namespace - the lxc namespace may not be
        # accessible
        lxc_name = None
        protocols = [
            protocol for protocol in self.job.protocols
            if protocol.name == LxcProtocol.name
        ]
        if protocols:
            lxc_name = protocols[0].lxc_name
        if not lxc_name:
            self.logger.debug("No LXC device requested")
            return connection

        # If there is no device_info then this action should be idempotent.
        if "device_info" not in self.job.device:
            return connection

        device_info = self.job.device.get("device_info", [])
        job_id = self.job.job_id
        job_prefix = self.job.parameters["dispatcher"].get("prefix", "")
        for device in device_info:
            data = {
                "serial_number": str(device.get("board_id", "")),
                "vendor_id": device.get("usb_vendor_id"),
                "product_id": device.get("usb_product_id"),
                "fs_label": device.get("fs_label"),
            }
            add_device_container_mapping(
                job_prefix + job_id,
                data,
                lxc_name,
                container_type="lxc",
                logging_info=self.get_logging_info(),
            )
        return connection
Example #22
0
def test_mapping_for_new_container_overrides_previous_mapping(tmpdir):
    add_device_container_mapping(
        "1",
        {
            "serial_number": "1234567890",
            "vendor_id": None,
            "product_id": None,
            "fs_label": None,
        },
        "mycontainer1",
    )
    add_device_container_mapping(
        "1",
        {
            "serial_number": "1234567890",
            "vendor_id": None,
            "product_id": None,
            "fs_label": None,
        },
        "mycontainer2",
    )
    data = yaml_load(open(tmpdir / "1" / "usbmap.yaml"))
    assert len(data) == 1
    assert data[0]["container"] == "mycontainer2"
Example #23
0
def test_device_info_keys_required(mocker):
    with pytest.raises(ValueError):
        add_device_container_mapping("1", {"serial_number": None},
                                     "mycontainer")
Example #24
0
def test_device_info_required(mocker):
    with pytest.raises(ValueError):
        add_device_container_mapping("1", {}, "mycontainer")
Example #25
0
def test_add_mapping_without_job_dir(tmpdir):
    os.rmdir(tmpdir / "1")
    add_device_container_mapping("1", {"foo": "bar"}, "mycontainer")
    assert os.path.exists(tmpdir / "1" / "usbmap.yaml")
Example #26
0
def test_simple_share_device_with_container(mocker, pass_device_lxc, device_links):
    add_device_container_mapping("1", {"serial_number": "1234567890"}, "mycontainer")
    share_device_with_container(Namespace(device="foo/bar", serial_number="1234567890"))
    pass_device_lxc.assert_called_once_with("mycontainer", "/dev/foo/bar", device_links)