[telepathy-mission-control/master] servicetest, mctest: add support for Clients being on more than one bus

Simon McVittie simon.mcvittie at collabora.co.uk
Tue May 26 05:02:30 PDT 2009


---
 test/twisted/mctest.py      |   38 ++++++++++++++--------
 test/twisted/servicetest.py |   75 +++++++++++++++++++++++++++++++++---------
 2 files changed, 83 insertions(+), 30 deletions(-)

diff --git a/test/twisted/mctest.py b/test/twisted/mctest.py
index 5978e8e..c91f6d3 100644
--- a/test/twisted/mctest.py
+++ b/test/twisted/mctest.py
@@ -450,21 +450,24 @@ class SimulatedClient(object):
             q.add_dbus_method_impl(self.Get_Interfaces,
                     path=self.object_path, interface=cs.PROPERTIES_IFACE,
                     method='Get', args=[cs.CLIENT, 'Interfaces'])
-            q.add_dbus_method_impl(self.GetAll_Client, path=self.object_path,
+            q.add_dbus_method_impl(self.GetAll_Client,
+                    path=self.object_path,
                     interface=cs.PROPERTIES_IFACE, method='GetAll',
                     args=[cs.CLIENT])
 
         q.add_dbus_method_impl(self.Get_ObserverChannelFilter,
                 path=self.object_path, interface=cs.PROPERTIES_IFACE,
                 method='Get', args=[cs.OBSERVER, 'ObserverChannelFilter'])
-        q.add_dbus_method_impl(self.GetAll_Observer, path=self.object_path,
+        q.add_dbus_method_impl(self.GetAll_Observer,
+                path=self.object_path,
                 interface=cs.PROPERTIES_IFACE, method='GetAll',
                 args=[cs.OBSERVER])
 
         q.add_dbus_method_impl(self.Get_ApproverChannelFilter,
                 path=self.object_path, interface=cs.PROPERTIES_IFACE,
                 method='Get', args=[cs.APPROVER, 'ApproverChannelFilter'])
-        q.add_dbus_method_impl(self.GetAll_Approver, path=self.object_path,
+        q.add_dbus_method_impl(self.GetAll_Approver,
+                path=self.object_path,
                 interface=cs.PROPERTIES_IFACE, method='GetAll',
                 args=[cs.APPROVER])
 
@@ -477,7 +480,8 @@ class SimulatedClient(object):
         q.add_dbus_method_impl(self.Get_BypassApproval,
                 path=self.object_path, interface=cs.PROPERTIES_IFACE,
                 method='Get', args=[cs.HANDLER, 'BypassApproval'])
-        q.add_dbus_method_impl(self.GetAll_Handler, path=self.object_path,
+        q.add_dbus_method_impl(self.GetAll_Handler,
+                path=self.object_path,
                 interface=cs.PROPERTIES_IFACE, method='GetAll',
                 args=[cs.HANDLER])
 
@@ -499,29 +503,32 @@ class SimulatedClient(object):
         return ret
 
     def Get_Interfaces(self, e):
-        self.q.dbus_return(e.message, self.get_interfaces(), signature='v')
+        self.q.dbus_return(e.message, self.get_interfaces(), signature='v',
+                bus=self.bus)
 
     def GetAll_Client(self, e):
         self.q.dbus_return(e.message, {'Interfaces': self.get_interfaces()},
-                signature='a{sv}')
+                signature='a{sv}', bus=self.bus)
 
     def GetAll_Observer(self, e):
         assert self.observe
         self.q.dbus_return(e.message, {'ObserverChannelFilter': self.observe},
-                signature='a{sv}')
+                signature='a{sv}', bus=self.bus)
 
     def Get_ObserverChannelFilter(self, e):
         assert self.observe
-        self.q.dbus_return(e.message, self.observe, signature='v')
+        self.q.dbus_return(e.message, self.observe, signature='v',
+                bus=self.bus)
 
     def GetAll_Approver(self, e):
         assert self.approve
         self.q.dbus_return(e.message, {'ApproverChannelFilter': self.approve},
-                signature='a{sv}')
+                signature='a{sv}', bus=self.bus)
 
     def Get_ApproverChannelFilter(self, e):
         assert self.approve
-        self.q.dbus_return(e.message, self.approve, signature='v')
+        self.q.dbus_return(e.message, self.approve, signature='v',
+                bus=self.bus)
 
     def GetAll_Handler(self, e):
         assert self.handle
@@ -530,18 +537,21 @@ class SimulatedClient(object):
             'BypassApproval': self.bypass_approval,
             'HandledChannels': self.handled_channels,
             },
-                signature='a{sv}')
+                signature='a{sv}', bus=self.bus)
 
     def Get_HandledChannels(self, e):
-        self.q.dbus_return(e.message, self.handled_channels, signature='v')
+        self.q.dbus_return(e.message, self.handled_channels, signature='v',
+                bus=self.bus)
 
     def Get_HandlerChannelFilter(self, e):
         assert self.handle
-        self.q.dbus_return(e.message, self.handle, signature='v')
+        self.q.dbus_return(e.message, self.handle, signature='v',
+                bus=self.bus)
 
     def Get_BypassApproval(self, e):
         assert self.handle
-        self.q.dbus_return(e.message, self.bypass_approval, signature='v')
+        self.q.dbus_return(e.message, self.bypass_approval, signature='v',
+                bus=self.bus)
 
 def create_fakecm_account(q, bus, mc, params):
     """Create a fake connection manager and an account that uses it.
diff --git a/test/twisted/servicetest.py b/test/twisted/servicetest.py
index 92d6634..7438b49 100644
--- a/test/twisted/servicetest.py
+++ b/test/twisted/servicetest.py
@@ -190,7 +190,10 @@ class IteratingEventQueue(BaseEventQueue):
         BaseEventQueue.__init__(self, timeout)
         self.events = []
         self._dbus_method_impls = []
-        self._bus = None
+        self._buses = []
+        # a message filter which will claim we handled everything
+        self._dbus_dev_null = \
+                lambda bus, message: dbus.lowlevel.HANDLER_RESULT_HANDLED
 
     def wait(self):
         stop = [False]
@@ -215,33 +218,62 @@ class IteratingEventQueue(BaseEventQueue):
     # compatibility
     handle_event = append
 
-    def add_dbus_method_impl(self, cb, **kwargs):
+    def add_dbus_method_impl(self, cb, bus=None, **kwargs):
+        if bus is None:
+            bus = self._buses[0]
+
         self._dbus_method_impls.append(
                 (EventPattern('dbus-method-call', **kwargs), cb))
 
     def dbus_emit(self, path, iface, name, *a, **k):
+        bus = k.pop('bus', self._buses[0])
         assert 'signature' in k, k
         message = dbus.lowlevel.SignalMessage(path, iface, name)
         message.append(*a, **k)
-        self._bus.send_message(message)
+        bus.send_message(message)
 
     def dbus_return(self, in_reply_to, *a, **k):
+        bus = k.pop('bus', self._buses[0])
         assert 'signature' in k, k
         reply = dbus.lowlevel.MethodReturnMessage(in_reply_to)
         reply.append(*a, **k)
-        self._bus.send_message(reply)
+        bus.send_message(reply)
+
+    def dbus_raise(self, in_reply_to, name, message=None, bus=None):
+        if bus is None:
+            bus = self._buses[0]
 
-    def dbus_raise(self, in_reply_to, name, message=None):
         reply = dbus.lowlevel.ErrorMessage(in_reply_to, name, message)
-        self._bus.send_message(reply)
+        bus.send_message(reply)
 
     def attach_to_bus(self, bus):
-        assert self._bus is None, self._bus
-        self._bus = bus
-        self._dbus_filter_bound_method = self._dbus_filter
-        self._bus.add_message_filter(self._dbus_filter_bound_method)
-
-        self._bus.add_signal_receiver(
+        if not self._buses:
+            # first-time setup
+            self._dbus_filter_bound_method = self._dbus_filter
+
+        self._buses.append(bus)
+
+        # Only subscribe to messages on the first bus connection (assumed to
+        # be the shared session bus connection used by the simulated connection
+        # manager and most of the test suite), not on subsequent bus
+        # connections (assumed to represent extra clients).
+        #
+        # When we receive a method call on the other bus connections, ignore
+        # it - the eavesdropping filter installed on the first bus connection
+        # will see it too.
+        #
+        # This is highly counter-intuitive, but it means our messages are in
+        # a guaranteed order (we don't have races between messages arriving on
+        # various connections).
+        if len(self._buses) > 1:
+            bus.add_message_filter(self._dbus_dev_null)
+            return
+
+        bus.add_match_string("")    # eavesdrop, like dbus-monitor does
+
+        bus.add_message_filter(self._dbus_filter_bound_method)
+
+        bus.add_signal_receiver(
                 lambda *args, **kw:
                     self.append(
                         Event('dbus-signal',
@@ -259,18 +291,29 @@ class IteratingEventQueue(BaseEventQueue):
                 )
 
     def cleanup(self):
-        if self._bus is not None:
-            self._bus.remove_message_filter(self._dbus_filter_bound_method)
-            self._bus = None
+        if self._buses:
+            self._buses[0].remove_message_filter(self._dbus_filter_bound_method)
+        for bus in self._buses[1:]:
+            bus.remove_message_filter(self._dbus_dev_null)
+
+        self._buses = []
         self._dbus_method_impls = []
 
     def _dbus_filter(self, bus, message):
         if isinstance(message, dbus.lowlevel.MethodCallMessage):
 
+            destination = message.get_destination()
+            sender = message.get_sender()
+
+            if (destination == 'org.freedesktop.DBus' or
+                    sender == self._buses[0].get_unique_name()):
+                # suppress reply and don't make an Event
+                return dbus.lowlevel.HANDLER_RESULT_HANDLED
+
             e = Event('dbus-method-call', message=message,
                 interface=message.get_interface(), path=message.get_path(),
                 args=map(unwrap, message.get_args_list(byte_arrays=True)),
-                destination=message.get_destination(),
+                destination=str(destination),
                 method=message.get_member(),
                 sender=message.get_sender(),
                 handled=False)
-- 
1.5.6.5




More information about the telepathy-commits mailing list