Overview#
pytest-bluezenv runs an ordinary Pytest test body on the upper tester and
the Bluetooth software under test on one or more VM hosts. Each VM host
has its own kernel and BlueZ instance. The plugin turns a declarative
host_config into VM hosts, then exposes their host
plugins through RPC proxies.
Test layout#
The Pytest process runs on host system, and is the upper tester. It collects tests, creates the required VM hosts, and drives them. It does not run the Bluetooth software under test.
A VM host is a QEMU virtual machine running the selected kernel. Its lower
tester loads host plugins and runs their code. Programs such as
bluetoothd, obexd, and bluetoothctl remain in the VM host.
A test declares one plugin list for each VM host. The
hosts fixture supplies a
HostProxy for every declared host:
from pytest_bluezenv import Bluetoothctl, Bluetoothd, host_config
@host_config([Bluetoothd(), Bluetoothctl()], [Bluetoothd()])
def test_discovery(hosts):
host0, host1 = hosts
host0.bluetoothctl.send("scan on\n")
host0.bluetoothctl.send() is an RPC call. The upper tester serialises
the call, the lower tester executes it, and the result returns to the test
body. A lower-tester exception is reported as
RemoteError. Writing tests describes host
configuration and plugins in detail.
VM-host communication#
Each VM host has control, log, console, and shared-file channels to
the upper tester. QEMU is launched using BlueZ’s
test-runner. Tests use these channels through the fixtures,
standard Python logging, and command-line tools described below.
- control
The RPC connection carries plugin calls, results, and exceptions.
--vm-timeoutbounds a call’s round trip.- log
Timestamped lower-tester log records stream to the upper tester. VM-host loggers are named
host.<run>.<index>, such ashost.0.1and service loggers ashost.<run>.<service>.- tty
A serial console with a root shell, for manual debugging. Use python3 -mpytest_bluezenv attach to attach it using Tmux.
- shared
A read-write directory mounted as
/run/sharedin the VM host and created as/tmp/pytest-bluezenv-*/shared-*on the upper tester. Core dumps andbtmoncaptures are collected from it before the VM host shuts down.
Controllers#
Each VM host has one controller, driven by its kernel over HCI. By default,
one btvirt process provides the controllers and their virtual air link.
VM hosts can therefore communicate without Bluetooth hardware.
--usb and --pcie pass named physical controllers to VM hosts. In
that configuration the VM hosts communicate over the real radio rather
than through btvirt. USB pass-through requires permission to open the
device. PCIe pass-through temporarily binds the controller to
vfio-pci and requires root privileges, an enabled IOMMU, and an
isolated IOMMU group.
Tests use btvirt unless their host_config
requests hw=True or --force-usb / --force-pcie is set. A
configuration can also omit a controller with controller=False.
Reusing VM hosts#
VM hosts are started on demand and pytest-bluezenv orders tests with matching
VM requirements together. The hosts fixture
can therefore share VM hosts between tests.
hosts_once reserves VM hosts for one test.
Host plugins are normally torn down after each test, even when the VM
host is shared. The lower tester also kills the previous process
group and powers the controller off to reset it. reuse=True retains plugins
for consecutive tests with the same host setup.
Time and log ordering#
Records from several VM hosts are interleaved and sorted by timestamp by
default. --no-log-reorder preserves arrival order. chronyd keeps
the VM-host clock close to the upper tester through the KVM PTP clock. The
paravirtualisation and PTP kernel options in Requirements are
required for this.
Timeouts#
The wait helpers, including wait_until and plugin
expect calls, use the configured default timeout. --vm-timeout
also bounds each RPC round trip. A timeout in the VM host is reported as
RemoteTimeoutError.
Failures and diagnostics#
When a process crashes, its core dump is written to the shared
directory and copied out before VM shutdown to
test-bluezenv-*.core files. Unless --no-core-backtraces is
set, a backtrace is generated and reported as
CoredumpWarning. Kernel BUG and
WARNING records produce KernelBugWarning.
Sanitizer reports, such as ASan output, produce
SanitizerWarning.
--btmon captures controller traffic for every VM host into
test-bluezenv-*.btsnoop files.
The command line options and interactive VM-host access are documented in Running tests.