debian-forge/test/run/test_devices.py
Christian Kellner a5e07cf506 devices: introduce new device manager class
Introduce a new class to manage devices, `DeviceManger` and move the
code to open devices from the `Device` here. The main insight of why
the logic should be place here is that certain information is needed
to open the devices, independently of specific type: the path to the
device node directory, `devpath`, the actual `tree` and the service
manager instance to start the actual service. Instead of passing all
this information again and again to the `Device` class, we now have
a specialized (service) manager class for devices that has all the
needed information all the time. Additionally, the special handling
of parent devices is moved from the pipeline to the service manager,
which is where it belongs.
This will make even more sense for mounts, where the `DeviceManger`
can then be passed to access the individual devices.
Port the test to use the `DeviceManager`.
2021-10-30 15:32:44 +01:00

81 lines
1.9 KiB
Python
Executable file

#!/usr/bin/python3
#
# Runtime Tests for Device Host Services
#
import os
import tempfile
import pytest
from osbuild import devices, host, loop, meta
from ..test import TestBase
@pytest.fixture(name="tmpdir")
def tmpdir_fixture():
with tempfile.TemporaryDirectory(prefix="test-devices-") as tmp:
yield tmp
@pytest.mark.skipif(not TestBase.can_bind_mount(), reason="root only")
def test_loopback_basic(tmpdir):
index = meta.Index(os.curdir)
info = index.get_module_info("Device", "org.osbuild.loopback")
tree = os.path.join(tmpdir, "tree")
os.makedirs(tree)
devpath = os.path.join(tmpdir, "dev")
os.makedirs(devpath)
size = 1024 * 1024
filename = os.path.join(tree, "image.img")
with open(filename, "wb") as f:
f.truncate(size)
sb = os.fstat(f.fileno())
testfile = os.path.join(tmpdir, "test.img")
options = {
"filename": "image.img",
"start": 0,
"size": size // 512 # size is in sectors / blocks
}
dev = devices.Device("loop", info, None, options)
with host.ServiceManager() as mgr:
devmgr = devices.DeviceManager(mgr, devpath, tree)
reply = devmgr.open(dev)
assert reply
assert reply["path"]
node = reply["path"]
assert os.path.exists(os.path.join(devpath, node))
minor = reply["node"]["minor"]
lo = loop.Loop(minor)
li = lo.get_status()
assert li.lo_offset == 0
assert li.lo_sizelimit == size
assert li.lo_inode == sb.st_ino
with pytest.raises(OSError):
with open(testfile, "wb") as f:
f.truncate(1)
lo.set_fd(f.fileno())
lo.close()
uid = f"device/{dev.name}"
client = mgr.services[uid]
client.call("close", None)
lo = loop.Loop(minor)
with open(filename, "r") as f:
assert not lo.is_bound_to(f.fileno())