Minimize D-Bus requirements for tests (#5265)

This PR minimizes the D-Bus requirements for tests. It does this by
using dbus-daemon directly instead of dbus-launch. The latter is meant
for graphical applications and therefor has X11 dependencies. It also
leaves the D-Bus daemon running after the tests are done. This will
accumulate dbus-daemon processes over time which is not ideal.

I've also considered using dbus-run-session since it is meant to launch
processes with a private D-Bus session. For Python tests one could
launch it like so:
dbus-run-session -- python3 -m pytest ...

Then `DBUS_SESSION_BUS_ADDRESS` would be used automatically by the
`MessageBus` class. However, to keep the current behavior of the tests,
launching the D-Bus daemon manually is the better option.
This commit is contained in:
Stefan Agner 2024-08-22 19:04:34 +02:00 committed by GitHub
parent 7366673eea
commit 695a23a454
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 19 additions and 10 deletions

View File

@ -313,7 +313,7 @@ jobs:
- name: Install additional system dependencies
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends libpulse0 libudev1 dbus dbus-x11
sudo apt-get install -y --no-install-recommends libpulse0 libudev1 dbus-daemon
- name: Register Python problem matcher
run: |
echo "::add-matcher::.github/workflows/matchers/python.json"

View File

@ -1,6 +1,7 @@
"""Common test functions."""
import asyncio
from collections.abc import AsyncGenerator, Generator
from functools import partial
from inspect import unwrap
import os
@ -115,20 +116,28 @@ async def docker() -> DockerAPI:
@pytest.fixture(scope="session")
def dbus_session() -> None:
"""Start a dbus session."""
dbus_launch = subprocess.run(["dbus-launch"], stdout=subprocess.PIPE, check=False)
envs = dbus_launch.stdout.decode(encoding="utf-8").rstrip()
def dbus_session() -> Generator[str, None, None]:
"""Start a dbus session.
for env in envs.split("\n"):
name, value = env.split("=", 1)
os.environ[name] = value
Returns session address.
"""
with subprocess.Popen(
[
"dbus-daemon",
"--nofork",
"--print-address",
"--session",
],
stdout=subprocess.PIPE,
) as proc:
yield proc.stdout.readline().decode("utf-8").strip()
proc.terminate()
@pytest.fixture
async def dbus_session_bus(dbus_session) -> MessageBus:
async def dbus_session_bus(dbus_session) -> AsyncGenerator[MessageBus, None, None]:
"""Return message bus connected to session dbus."""
bus = await MessageBus(bus_type=BusType.SESSION).connect()
bus = await MessageBus(bus_type=BusType.SESSION, bus_address=dbus_session).connect()
yield bus
bus.disconnect()