57 lines
2.2 KiB
Python
57 lines
2.2 KiB
Python
import importlib.util
|
|
from pathlib import Path
|
|
import unittest
|
|
|
|
spec = importlib.util.spec_from_file_location("usb_qmp", Path(__file__).parents[1] / "usb-device-qmp.py")
|
|
usb = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(usb)
|
|
|
|
|
|
class FakeQmp:
|
|
def __init__(self, occupied=False, fail_add=False):
|
|
self.calls = []
|
|
self.occupied = occupied
|
|
self.fail_add = fail_add
|
|
|
|
def call(self, name, args=None):
|
|
self.calls.append((name, args))
|
|
if name == "query-chardev":
|
|
return [{"label": "vdi_usb_box_100"}] if self.occupied else []
|
|
if name == "qom-list":
|
|
return [{"name": "tablet"}, {"name": "hostpci0"}]
|
|
if name == "device_add" and self.fail_add:
|
|
raise RuntimeError("bad USB bus")
|
|
return {}
|
|
|
|
|
|
class UsbQmpTests(unittest.TestCase):
|
|
def test_only_loopback_tunnel_and_approved_storage_are_attached(self):
|
|
q = FakeQmp()
|
|
usb.attach(q, 100, 40001, "ehci-2.0", "0951", "1666")
|
|
channel = next(a for n, a in q.calls if n == "chardev-add")
|
|
self.assertEqual(channel["backend"]["data"]["addr"]["data"]["host"], "127.0.0.1")
|
|
device = next(a for n, a in q.calls if n == "device_add")
|
|
self.assertEqual(device["filter"], "0x08:0x0951:0x1666:-1:1|-1:-1:-1:-1:0")
|
|
|
|
def test_any_storage_filter_keeps_hid_and_hub_out(self):
|
|
q = FakeQmp()
|
|
usb.attach(q, 100, 40001, "ehci-2.0")
|
|
device = next(a for n, a in q.calls if n == "device_add")
|
|
self.assertEqual(device["filter"], "0x08:-1:-1:-1:1|-1:-1:-1:-1:0")
|
|
|
|
def test_busy_endpoint_is_never_replaced(self):
|
|
q = FakeQmp(occupied=True)
|
|
with self.assertRaisesRegex(RuntimeError, "already exists"):
|
|
usb.attach(q, 100, 40001, "ehci-2.0", "0951", "1666")
|
|
self.assertFalse(any(n in ("chardev-add", "chardev-remove", "device_del") for n, _ in q.calls))
|
|
|
|
def test_failed_device_add_rolls_back_only_its_new_channel(self):
|
|
q = FakeQmp(fail_add=True)
|
|
with self.assertRaisesRegex(RuntimeError, "bad USB bus"):
|
|
usb.attach(q, 100, 40001, "ehci-2.0", "0951", "1666")
|
|
self.assertEqual(q.calls[-1], ("chardev-remove", {"id": "vdi_usb_box_100"}))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|