D-Bus testing: need common '/' object for ConnMan and Bluez

Adding the always-on '/' object for ConnMan broke Bluez testing,
because adding a second '/' object for the Bluez calls fails with:
  KeyError: "Can't register the object-path handler for '/': there is already a handler"

This makes sense, because at the D-Bus message might be sent directly,
without including the well-known bus name, and thus finding the right
right object cannot be done by bus name.

Solved by registering a unified ConnMan/Bluez root object which provides
both interfaces.
This commit is contained in:
Patrick Ohly 2012-01-16 14:17:29 +01:00
parent ef237ff52e
commit a2c5935920
1 changed files with 54 additions and 52 deletions

View File

@ -100,6 +100,59 @@ atexit.register(os.kill, child, 9)
bus = dbus.SessionBus()
loop = gobject.MainLoop()
# Bluez default adapter
bt_adaptor = "/org/bluez/1036/hci0"
# handles D-Bus messages for '/' object in both net.connman and
# org.bluez; must be the same object because D-Bus cannot switch based
# on the bus name (not necessarily included in message)
class RootObject (dbus.service.Object):
# ConnMan state
state = "online"
getPropertiesCalled = False
waitingForGetProperties = False
def __init__(self):
self.bluez_name = dbus.service.BusName('org.bluez', bus)
self.conn_name = dbus.service.BusName("net.connman", bus);
dbus.service.Object.__init__(self, bus, '/')
@dbus.service.method(dbus_interface='org.bluez.Manager', in_signature='', out_signature='o')
def DefaultAdapter(self):
return bt_adaptor
@dbus.service.signal(dbus_interface='org.bluez.Manager', signature='o')
def DefaultAdapterChanged(self, obj):
return bt_adaptor
@dbus.service.method(dbus_interface='net.connman.Manager', in_signature='', out_signature='a{sv}')
def GetProperties(self):
# notify TestDBusServerPresence.setUp()?
if self.waitingForGetProperties:
loop.quit()
self.getPropertiesCalled = True
return { "State" : self.state }
@dbus.service.signal(dbus_interface='net.connman.Manager', signature='sv')
def PropertyChanged(self, key, value):
pass
def setState(self, state):
if self.state != state:
self.state = state
self.PropertyChanged("State", state)
# race condition: it happened that method calls
# reached syncevo-dbus-server before the state change,
# thus breaking the test
time.sleep(1)
def reset(self):
self.state = "online"
self.getPropertiesCalled = False
self.waitingForGetProperties = False
root = RootObject()
def property(key, value):
"""Function decorator which sets an arbitrary property of a test.
Use like this:
@ -1054,38 +1107,6 @@ class TestNamedConfig(unittest.TestCase, DBusUtil):
self.assertEqual(fooConfig, self.session.GetNamedConfig("foo", False))
self.assertEqual(barConfig, self.session.GetNamedConfig("bar", False))
class Connman (dbus.service.Object):
state = "online"
getPropertiesCalled = False
waitingForGetProperties = False
@dbus.service.method(dbus_interface='net.connman.Manager', in_signature='', out_signature='a{sv}')
def GetProperties(self):
# notify TestDBusServerPresence.setUp()?
if self.waitingForGetProperties:
loop.quit()
self.getPropertiesCalled = True
return { "State" : self.state }
@dbus.service.signal(dbus_interface='net.connman.Manager', signature='sv')
def PropertyChanged(self, key, value):
pass
def setState(self, state):
if self.state != state:
self.state = state
self.PropertyChanged("State", state)
# race condition: it happened that method calls
# reached syncevo-dbus-server before the state change,
# thus breaking the test
time.sleep(1)
def reset(self):
self.state = "online"
self.getPropertiesCalled = False
self.waitingForGetProperties = False
class TestDBusServerPresence(unittest.TestCase, DBusUtil):
"""Tests Presence signal and checkPresence API"""
@ -1094,8 +1115,7 @@ class TestDBusServerPresence(unittest.TestCase, DBusUtil):
# will try to call it before setUp(). The implementation's
# initialization and tearDown() below ensures that the state
# is "online" outside of tests.
name = dbus.service.BusName ("net.connman", bus);
conn = Connman (bus, "/")
conn = root
def setUp(self):
self.setUpServer()
@ -3210,22 +3230,8 @@ bt_mac = "D4:5D:42:73:E4:6C"
bt_fingerprint = "Nokia 5230"
bt_name = "My Nokia 5230"
bt_template = "Bluetooth_%s_1" % (bt_mac)
bt_adaptor = "/org/bluez/1036/hci0"
bt_device = "%s/dev_%s" % (bt_adaptor, string.replace(bt_mac, ':', '_'))
class BluezManager (dbus.service.Object):
def __init__(self):
bus_name = dbus.service.BusName('org.bluez', bus)
dbus.service.Object.__init__(self, bus_name, '/')
@dbus.service.method(dbus_interface='org.bluez.Manager', in_signature='', out_signature='o')
def DefaultAdapter(self):
return bt_adaptor
@dbus.service.signal(dbus_interface='org.bluez.Manager', signature='o')
def DefaultAdapterChanged(self, obj):
return bt_adaptor
class BluezAdapter (dbus.service.Object):
def __init__(self):
self.SUPPORTS_MULTIPLE_OBJECT_PATHS = True
@ -3292,17 +3298,13 @@ class BluezDevice (dbus.service.Object):
class TestBluetooth(unittest.TestCase, DBusUtil):
"""Tests that Bluetooth works properly."""
name = dbus.service.BusName ("org.bluez", bus);
def setUp(self):
self.man_conn = BluezManager()
self.adp_conn = BluezAdapter()
self.dev_conn = BluezDevice()
loop.run()
self.setUpServer()
def tearDown(self):
self.man_conn.remove_from_connection()
self.adp_conn.remove_from_connection()
self.dev_conn.remove_from_connection()