[telepathy-mission-control/master] Add a regression test for channel creation during MC startup

Simon McVittie simon.mcvittie at collabora.co.uk
Mon May 18 03:53:27 PDT 2009


* assert that channels created before the dispatching process has fully
  started can still be observed
* assert that CreateChannel isn't called until the dispatching process has
  fully started (i.e. clients have been discovered) so requested channels
  can always be observed too
---
 test/twisted/Makefile.am                     |    3 +-
 test/twisted/dispatcher/create-at-startup.py |  220 ++++++++++++++++++++++++++
 2 files changed, 222 insertions(+), 1 deletions(-)
 create mode 100644 test/twisted/dispatcher/create-at-startup.py

diff --git a/test/twisted/Makefile.am b/test/twisted/Makefile.am
index 6704e99..eadb48b 100644
--- a/test/twisted/Makefile.am
+++ b/test/twisted/Makefile.am
@@ -28,7 +28,8 @@ TWISTED_BASIC_TESTS = \
 
 TWISTED_SEPARATE_TESTS = \
 	crash-recovery/crash-recovery.py \
-	crash-recovery/client-crash-during-recovery.py
+	crash-recovery/client-crash-during-recovery.py \
+	dispatcher/create-at-startup.py
 
 # A debug version of the normal MC executable, which exits cleanly on
 # disconnection from D-Bus (so gcov info gets written out)
diff --git a/test/twisted/dispatcher/create-at-startup.py b/test/twisted/dispatcher/create-at-startup.py
new file mode 100644
index 0000000..5808665
--- /dev/null
+++ b/test/twisted/dispatcher/create-at-startup.py
@@ -0,0 +1,220 @@
+"""Regression test for activating MC due to, or immediately before, a request.
+"""
+
+import os
+
+import dbus
+import dbus.service
+
+from servicetest import EventPattern, tp_name_prefix, tp_path_prefix, \
+        call_async
+from mctest import exec_test, SimulatedConnection, SimulatedClient, \
+        create_fakecm_account, enable_fakecm_account, SimulatedChannel, \
+        expect_client_setup, make_mc
+import constants as cs
+
+def preseed():
+    accounts_dir = os.environ['MC_ACCOUNT_DIR']
+
+    accounts_cfg = open(accounts_dir + '/accounts.cfg', 'w')
+    accounts_cfg.write("""# Telepathy accounts
+[fakecm/fakeprotocol/jc_2edenton_40unatco_2eint]
+manager=fakecm
+protocol=fakeprotocol
+DisplayName=Work account
+NormalizedName=jc.denton at unatco.int
+param-account=jc.denton at unatco.int
+param-password=ionstorm
+Enabled=1
+ConnectAutomatically=0
+AutomaticPresenceType=2
+AutomaticPresenceStatus=available
+AutomaticPresenceMessage=
+""")
+    accounts_cfg.close()
+
+    account_connections_file = open(accounts_dir + '/.mc_connections', 'w')
+    account_connections_file.write("")
+    account_connections_file.close()
+
+def test(q, bus, unused):
+    text_fixed_properties = dbus.Dictionary({
+        cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT,
+        cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT,
+        }, signature='sv')
+
+    user_action_time = dbus.Int64(1238582606)
+
+    # A client and a CM are already running
+    client = SimulatedClient(q, bus, 'Empathy',
+            observe=[text_fixed_properties], approve=[text_fixed_properties],
+            handle=[text_fixed_properties], bypass_approval=False,
+            implement_get_interfaces=False)
+    cm_name_ref = dbus.service.BusName(
+            cs.tp_name_prefix + '.ConnectionManager.fakecm', bus=bus)
+
+    # service-activate MC and immediately make a request
+    mc = make_mc(bus, q.append)
+    account = bus.get_object(cs.MC,
+            cs.tp_path_prefix +
+            '/Account/fakecm/fakeprotocol/jc_2edenton_40unatco_2eint')
+    cd = bus.get_object(cs.MC, cs.CD_PATH)
+    cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE)
+
+    request = dbus.Dictionary({
+            cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT,
+            cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT,
+            cs.CHANNEL + '.TargetID': 'bob.page at versalife.com',
+            }, signature='sv')
+    call_async(q, cd, 'CreateChannel',
+            account.object_path, request, user_action_time, client.bus_name,
+            dbus_interface=cs.CD)
+
+    get_interfaces = q.expect('dbus-method-call', path=client.object_path,
+            interface=cs.PROPERTIES_IFACE, method='Get',
+            args=[cs.CLIENT, 'Interfaces'],
+            handled=False)
+    # don't reply just yet
+
+    ret = q.expect('dbus-return', method='CreateChannel')
+    request_path = ret.value[0]
+
+    # chat UI connects to signals and calls ChannelRequest.Proceed()
+    cr = bus.get_object(cs.AM, request_path)
+    request_props = cr.GetAll(cs.CR, dbus_interface=cs.PROPERTIES_IFACE)
+    assert request_props['Account'] == account.object_path
+    assert request_props['Requests'] == [request]
+    assert request_props['UserActionTime'] == user_action_time
+    assert request_props['PreferredHandler'] == client.bus_name
+    assert request_props['Interfaces'] == []
+
+    cr.Proceed(dbus_interface=cs.CR)
+
+    e = q.expect('dbus-method-call', method='RequestConnection',
+            args=['fakeprotocol', {
+                'account': 'jc.denton at unatco.int',
+                'password': 'ionstorm',
+                }],
+            destination=cs.tp_name_prefix + '.ConnectionManager.fakecm',
+            path=cs.tp_path_prefix + '/ConnectionManager/fakecm',
+            interface=cs.tp_name_prefix + '.ConnectionManager',
+            handled=False)
+    conn = SimulatedConnection(q, bus, 'fakecm', 'fakeprotocol', 'the_conn',
+            'jc.denton at unatco.int')
+    q.dbus_return(e.message, conn.bus_name, conn.object_path, signature='so')
+
+    q.expect('dbus-method-call', method='Connect',
+            path=conn.object_path, handled=True)
+    conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CONN_STATUS_REASON_NONE)
+
+    # A channel appears spontaneously
+
+    announcement_immutable = dbus.Dictionary(text_fixed_properties)
+    announcement_immutable[cs.CHANNEL + '.TargetID'] = 'gunther at unatco.int'
+    announcement_immutable[cs.CHANNEL + '.TargetHandle'] = \
+            conn.ensure_handle(cs.HT_CONTACT, 'gunther at unatco.int')
+    announcement_immutable[cs.CHANNEL + '.InitiatorHandle'] = \
+        announcement_immutable[cs.CHANNEL + '.TargetHandle']
+    announcement_immutable[cs.CHANNEL + '.InitiatorID'] = \
+        announcement_immutable[cs.CHANNEL + '.TargetID']
+    announcement_immutable[cs.CHANNEL + '.Interfaces'] = \
+            dbus.Array([], signature='s')
+    announcement_immutable[cs.CHANNEL + '.Requested'] = False
+    announcement = SimulatedChannel(conn, announcement_immutable)
+    announcement.announce()
+
+    # Now the Client returns its info
+    q.dbus_return(get_interfaces.message,
+            dbus.Array([cs.HANDLER, cs.OBSERVER, cs.APPROVER,
+                cs.CLIENT_IFACE_REQUESTS], signature='s'), signature='v')
+
+    expect_client_setup(q, [client], got_interfaces_already=True)
+
+    # Now that the dispatcher is ready to go, we start looking for channels,
+    # and also make the actual request
+    _, cm_request_call, get_handled_channels_call = q.expect_many(
+            EventPattern('dbus-method-call',
+                interface=cs.PROPERTIES_IFACE, method='GetAll',
+                args=[cs.CONN_IFACE_REQUESTS],
+                path=conn.object_path, handled=True),
+            EventPattern('dbus-method-call',
+                interface=cs.CONN_IFACE_REQUESTS, method='CreateChannel',
+                path=conn.object_path, args=[request], handled=False),
+            EventPattern('dbus-method-call',
+                path=client.object_path,
+                interface=cs.PROPERTIES_IFACE, method='Get',
+                args=[cs.HANDLER, 'HandledChannels'],
+                handled=False),
+            )
+    # FIXME: this Get(HandledChannels) could be done implicitly by the GetAll
+    # during basic Handler setup, if MC was refactored more
+    q.dbus_return(get_handled_channels_call.message, dbus.Array(signature='o'),
+            signature='v')
+
+    # Time passes. A channel is returned.
+
+    channel_immutable = dbus.Dictionary(request)
+    channel_immutable[cs.CHANNEL + '.InitiatorID'] = conn.self_ident
+    channel_immutable[cs.CHANNEL + '.InitiatorHandle'] = conn.self_handle
+    channel_immutable[cs.CHANNEL + '.Requested'] = True
+    channel_immutable[cs.CHANNEL + '.Interfaces'] = \
+        dbus.Array([], signature='s')
+    channel_immutable[cs.CHANNEL + '.TargetHandle'] = \
+        conn.ensure_handle(cs.HT_CONTACT, 'bob.page at versalife.com')
+    channel = SimulatedChannel(conn, channel_immutable)
+
+    q.dbus_return(cm_request_call.message,
+            channel.object_path, channel.immutable, signature='oa{sv}')
+    channel.announce()
+
+    # Empathy observes the channels, in the order they appeared
+    a = q.expect('dbus-method-call',
+            path=client.object_path,
+            interface=cs.OBSERVER, method='ObserveChannels',
+            handled=False)
+    e = q.expect('dbus-method-call',
+            path=client.object_path,
+            interface=cs.OBSERVER, method='ObserveChannels',
+            handled=False)
+
+    assert a.args[0] == account.object_path, a.args
+    assert a.args[1] == conn.object_path, a.args
+    assert a.args[3] != '/', a.args         # there is a dispatch operation
+    assert a.args[4] == [], a.args
+    channels = a.args[2]
+    assert len(channels) == 1, channels
+    assert channels[0][0] == announcement.object_path, channels
+    assert channels[0][1] == announcement_immutable, channels
+
+    assert e.args[0] == account.object_path, e.args
+    assert e.args[1] == conn.object_path, e.args
+    assert e.args[3] == '/', e.args         # no dispatch operation
+    assert e.args[4] == [request_path], e.args
+    channels = e.args[2]
+    assert len(channels) == 1, channels
+    assert channels[0][0] == channel.object_path, channels
+    assert channels[0][1] == channel_immutable, channels
+
+    # Observer says "OK, go"
+    q.dbus_return(a.message, signature='')
+    q.dbus_return(e.message, signature='')
+
+    # Empathy is asked to handle the channel
+    e = q.expect('dbus-method-call',
+            path=client.object_path,
+            interface=cs.HANDLER, method='HandleChannels',
+            handled=False)
+    assert e.args[0] == account.object_path, e.args
+    assert e.args[1] == conn.object_path, e.args
+    channels = e.args[2]
+    assert len(channels) == 1, channels
+    assert channels[0][0] == channel.object_path, channels
+    assert channels[0][1] == channel_immutable, channels
+    assert e.args[3] == [request_path], e.args
+    assert e.args[4] == user_action_time
+    assert isinstance(e.args[5], dict)
+    assert len(e.args) == 6
+
+if __name__ == '__main__':
+    preseed()
+    exec_test(test, {}, preload_mc=False)
-- 
1.5.6.5




More information about the telepathy-commits mailing list