225
222
# We need to ensure DBUS_SESSION_BUS_ADDRESS is private here
226
223
from urllib import unquote
227
bus_address = os.environ.get('DBUS_SESSION_BUS_ADDRESS', None)
224
bus_address = yield os.environ.get('DBUS_SESSION_BUS_ADDRESS', None)
228
225
if os.path.dirname(unquote(bus_address.split(',')[0].split('=')[1])) \
229
226
!= os.path.dirname(os.getcwd()):
230
227
raise InvalidSessionBus('DBUS_SESSION_BUS_ADDRES is wrong.')
232
229
# Set up the main loop and bus connection
233
self.loop = DBusGMainLoop(set_as_default=True)
234
self.bus = dbus.bus.BusConnection(address_or_type=bus_address,
230
self.loop = yield DBusGMainLoop(set_as_default=True)
231
self.bus = yield dbus.bus.BusConnection(address_or_type=bus_address,
234
# Check that we are on the correct bus for real
235
if len(self.bus.list_names()) > 2:
236
raise InvalidSessionBus('Too many bus connections: %s' %
237
len(self.bus.list_names()))
237
239
# monkeypatch busName.__del__ to avoid errors on gc
238
240
# we take care of releasing the name in shutdown
239
241
service.BusName.__del__ = lambda _: None
240
self.bus.set_exit_on_disconnect(False)
242
yield self.bus.set_exit_on_disconnect(False)
241
243
self.signal_receivers = set()
243
245
def tearDown(self):
244
246
"""Cleanup the test."""
245
# Class 'BaseTestCase' has no 'tearDown' member
246
# pylint: disable=E1101
247
d = self.cleanup_signal_receivers(self.signal_receivers)
248
d.addBoth(self._tear_down)
249
d.addBoth(lambda _: super(DBusTestCase, self).tearDown())
252
def _tear_down(self):
257
def error_handler(self, error):
258
"""Default error handler for DBus calls."""
259
if isinstance(error, failure.Failure):
260
self.fail(error.getErrorMessage())
262
def cleanup_signal_receivers(self, signal_receivers):
263
"""Cleanup self.signal_receivers and returns a deferred."""
264
# dbus modules will be imported by the decorator
265
# pylint: disable=E0602
267
for match in signal_receivers:
271
"""Callback that accepts *args."""
274
self.bus.call_async(dbus.bus.BUS_DAEMON_NAME,
275
dbus.bus.BUS_DAEMON_PATH,
276
dbus.bus.BUS_DAEMON_IFACE, 'RemoveMatch', 's',
277
(str(match),), callback, self.error_handler)
280
return defer.DeferredList(deferreds)
282
return defer.succeed(True)
247
yield self.bus.flush()
248
yield self.bus.close()
249
yield super(DBusTestCase, self).tearDown()