bluezoo - BlueZ D-Bus API Mock

1.0.2 · active · verified Thu Apr 16

bluezoo is a Python library that provides an in-process mock for the BlueZ D-Bus API, primarily for testing Bluetooth-related applications. It intercepts D-Bus calls to 'org.bluez' on the system bus, allowing developers to simulate Bluetooth device behavior without requiring a physical Bluetooth adapter or a running BlueZ daemon. The current version is 1.0.2, and it appears to have a stable release cadence for bug fixes and minor improvements.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to activate the `BlueZMock` context, add mock Bluetooth adapters and devices, and then verify their presence using standard `dbus-python` calls. It highlights that `bluezoo` allows your code to interact with a simulated BlueZ environment, rather than a real one.

import dbus
import dbus.mainloop.glib
from bluezoo import BlueZMock
from bluezoo.util import generate_random_address

# NOTE: dbus-python and pygobject are required in the environment to use bluezoo effectively.
#       Install them with: pip install dbus-python pygobject

# Make sure dbus-python uses the GLib main loop by default for this process.
# This is crucial for BlueZ D-Bus interactions.
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

# Use BlueZMock as a context manager to activate the mock D-Bus service.
with BlueZMock() as mock:
    print("BlueZMock is active, intercepting BlueZ D-Bus calls.")

    # 1. Add a mock Bluetooth adapter
    adapter_path = '/org/bluez/hci0'
    mock.add_adapter(adapter_path, name='MockAdapter', address=generate_random_address())
    print(f"Mock adapter '{adapter_path}' added.")

    # 2. Add a mock Bluetooth device associated with the adapter
    device_address = generate_random_address()
    device_path = f'{adapter_path}/dev_{device_address.replace(":", "_")}'
    mock.add_device(
        device_path,
        adapter_path=adapter_path,
        address=device_address,
        name='MockDevice',
        rssi=-60
    )
    print(f"Mock device '{device_address}' added to adapter '{adapter_path}'.")

    # 3. Now, client code (using dbus-python) can interact with these mock objects.
    # Get the system bus
    bus = dbus.SystemBus()

    # Get the D-Bus ObjectManager to discover objects
    obj_manager = dbus.Interface(
        bus.get_object('org.bluez', '/'),
        'org.freedesktop.DBus.ObjectManager'
    )
    
    # Get all managed objects and check for our mock adapter and device
    managed_objects = obj_manager.GetManagedObjects()
    print("\nVerifying mock objects via D-Bus ObjectManager:")

    found_adapter = False
    found_device = False

    for path, interfaces in managed_objects.items():
        if path == adapter_path and 'org.bluez.Adapter1' in interfaces:
            print(f"  Found mock adapter at {path} with name: {interfaces['org.bluez.Adapter1']['Name']}")
            found_adapter = True
        if path == device_path and 'org.bluez.Device1' in interfaces:
            print(f"  Found mock device at {path} with address: {interfaces['org.bluez.Device1']['Address']}")
            found_device = True

    if not (found_adapter and found_device):
        print("  Error: Mock adapter or device not found via D-Bus as expected!")

print("\nBlueZMock is inactive now (outside the 'with' block).")
print("D-Bus calls to 'org.bluez' would now target the real BlueZ daemon if running, or fail.")

# Optional: Demonstrate failure outside the mock context
try:
    bus = dbus.SystemBus()
    # This call would fail if no real BlueZ daemon is running
    bus.get_object('org.bluez', '/') 
except dbus.exceptions.DBusException as e:
    print(f"Attempting to access BlueZ outside mock context resulted in expected error: {e}")

view raw JSON →