~ubuntu-branches/ubuntu/precise/telepathy-mission-control-5/precise

« back to all changes in this revision

Viewing changes to test/twisted/dispatcher/bypass-observers.py

  • Committer: Bazaar Package Importer
  • Author(s): Jonny Lamb
  • Date: 2011-01-17 15:55:24 UTC
  • mto: (0.12.1 upstream) (7.1.4 maverick)
  • mto: This revision was merged to the branch mainline in revision 8.
  • Revision ID: james.westby@ubuntu.com-20110117155524-l8ex8kr7zhs8nnm6
Tags: upstream-5.7.1
ImportĀ upstreamĀ versionĀ 5.7.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2009-2010 Nokia Corporation
 
2
# Copyright (C) 2009-2010 Collabora Ltd.
 
3
#
 
4
# This library is free software; you can redistribute it and/or
 
5
# modify it under the terms of the GNU Lesser General Public
 
6
# License as published by the Free Software Foundation; either
 
7
# version 2.1 of the License, or (at your option) any later version.
 
8
#
 
9
# This library is distributed in the hope that it will be useful, but
 
10
# WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 
12
# Lesser General Public License for more details.
 
13
#
 
14
# You should have received a copy of the GNU Lesser General Public
 
15
# License along with this library; if not, write to the Free Software
 
16
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 
17
# 02110-1301 USA
 
18
 
 
19
import dbus
 
20
"""Regression test for dispatching an incoming Text channel with bypassed
 
21
observers.
 
22
"""
 
23
 
 
24
import dbus
 
25
import dbus.service
 
26
 
 
27
from servicetest import EventPattern, tp_name_prefix, tp_path_prefix, \
 
28
        call_async, sync_dbus, assertEquals, assertLength, assertContains
 
29
from mctest import exec_test, SimulatedConnection, SimulatedClient, \
 
30
        create_fakecm_account, enable_fakecm_account, SimulatedChannel, \
 
31
        expect_client_setup
 
32
import constants as cs
 
33
 
 
34
text_fixed_properties = dbus.Dictionary({
 
35
    cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT,
 
36
    }, signature='sv')
 
37
contact_text_fixed_properties = dbus.Dictionary({
 
38
    cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT,
 
39
    cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT,
 
40
    }, signature='sv')
 
41
secret_fixed_properties = dbus.Dictionary({
 
42
    cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT,
 
43
    cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT,
 
44
    'com.example.Secrecy.Secret': True,
 
45
    }, signature='sv')
 
46
 
 
47
def announce_common(q, bus, empathy, kopete, account, conn, cd_props,
 
48
        secret=False):
 
49
    if secret:
 
50
        jid = 'friar.lawrence'
 
51
    else:
 
52
        jid = 'juliet'
 
53
 
 
54
    channel_properties = dbus.Dictionary(contact_text_fixed_properties,
 
55
            signature='sv')
 
56
    channel_properties[cs.CHANNEL + '.TargetID'] = jid
 
57
    channel_properties[cs.CHANNEL + '.TargetHandle'] = \
 
58
            conn.ensure_handle(cs.HT_CONTACT, jid)
 
59
    channel_properties[cs.CHANNEL + '.InitiatorID'] = jid
 
60
    channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \
 
61
            conn.ensure_handle(cs.HT_CONTACT, jid)
 
62
    channel_properties[cs.CHANNEL + '.Requested'] = False
 
63
    channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s')
 
64
 
 
65
    if secret:
 
66
        channel_properties['com.example.Secrecy.Secret'] = True
 
67
 
 
68
    chan = SimulatedChannel(conn, channel_properties)
 
69
    chan.announce()
 
70
 
 
71
    # A channel dispatch operation is created
 
72
 
 
73
    e = q.expect('dbus-signal',
 
74
            path=cs.CD_PATH,
 
75
            interface=cs.CD_IFACE_OP_LIST,
 
76
            signal='NewDispatchOperation')
 
77
 
 
78
    cdo_path = e.args[0]
 
79
    cdo_properties = e.args[1]
 
80
 
 
81
    assertEquals(cdo_properties[cs.CDO + '.Account'], account.object_path)
 
82
    assertEquals(cdo_properties[cs.CDO + '.Connection'], conn.object_path)
 
83
    assertContains(cs.CDO + '.Interfaces', cdo_properties)
 
84
 
 
85
    handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:]
 
86
 
 
87
    if secret:
 
88
        # The handler with BypassApproval is first
 
89
        assertEquals(cs.tp_name_prefix + '.Client.Kopete.Bypasser',
 
90
            handlers[0])
 
91
    else:
 
92
        handlers.sort()
 
93
        assertEquals([cs.tp_name_prefix + '.Client.Empathy',
 
94
            cs.tp_name_prefix + '.Client.Kopete'], handlers)
 
95
 
 
96
    assertContains(cs.CD_IFACE_OP_LIST, cd_props.Get(cs.CD, 'Interfaces'))
 
97
 
 
98
    assertEquals([(cdo_path, cdo_properties)],
 
99
        cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations'))
 
100
 
 
101
    cdo = bus.get_object(cs.CD, cdo_path)
 
102
    cdo_iface = dbus.Interface(cdo, cs.CDO)
 
103
 
 
104
    # Both Observers are told about the new channel
 
105
 
 
106
    if secret:
 
107
        observe_events = []
 
108
    else:
 
109
        e, k = q.expect_many(
 
110
                EventPattern('dbus-method-call',
 
111
                    path=empathy.object_path,
 
112
                    interface=cs.OBSERVER, method='ObserveChannels',
 
113
                    handled=False),
 
114
                EventPattern('dbus-method-call',
 
115
                    path=kopete.object_path,
 
116
                    interface=cs.OBSERVER, method='ObserveChannels',
 
117
                    handled=False),
 
118
                )
 
119
        assertEquals(account.object_path, e.args[0])
 
120
        assertEquals(conn.object_path, e.args[1])
 
121
        assertEquals(cdo_path, e.args[3])
 
122
        assertEquals([], e.args[4])      # no requests satisfied
 
123
        channels = e.args[2]
 
124
        assertLength(1, channels)
 
125
        assertEquals(chan.object_path, channels[0][0])
 
126
        assertEquals(channel_properties, channels[0][1])
 
127
 
 
128
        assertEquals(k.args, e.args)
 
129
        observe_events = [e, k]
 
130
 
 
131
    return cdo_iface, chan, channel_properties, observe_events
 
132
 
 
133
def expect_and_exercise_approval(q, bus, chan, channel_properties,
 
134
        empathy, kopete, cdo_iface, cd_props):
 
135
    # The Approvers are next
 
136
 
 
137
    e, k = q.expect_many(
 
138
            EventPattern('dbus-method-call',
 
139
                path=empathy.object_path,
 
140
                interface=cs.APPROVER, method='AddDispatchOperation',
 
141
                handled=False),
 
142
            EventPattern('dbus-method-call',
 
143
                path=kopete.object_path,
 
144
                interface=cs.APPROVER, method='AddDispatchOperation',
 
145
                handled=False),
 
146
            )
 
147
 
 
148
    assertEquals([(chan.object_path, channel_properties)], e.args[0])
 
149
    assertEquals(k.args, e.args)
 
150
 
 
151
    # Both Approvers indicate that they are ready to proceed
 
152
    q.dbus_return(e.message, signature='')
 
153
    q.dbus_return(k.message, signature='')
 
154
 
 
155
    # Both Approvers now have a flashing icon or something, trying to get the
 
156
    # user's attention
 
157
 
 
158
    # The user responds to Kopete first
 
159
    call_async(q, cdo_iface, 'HandleWith',
 
160
            cs.tp_name_prefix + '.Client.Kopete')
 
161
 
 
162
    # Kopete is asked to handle the channels
 
163
    e = q.expect('dbus-method-call',
 
164
            path=kopete.object_path,
 
165
            interface=cs.HANDLER, method='HandleChannels',
 
166
            handled=False)
 
167
 
 
168
    # Kopete accepts the channels
 
169
    q.dbus_return(e.message, signature='')
 
170
 
 
171
    q.expect_many(
 
172
            EventPattern('dbus-return', method='HandleWith'),
 
173
            EventPattern('dbus-signal', interface=cs.CDO, signal='Finished'),
 
174
            EventPattern('dbus-signal', interface=cs.CD_IFACE_OP_LIST,
 
175
                signal='DispatchOperationFinished'),
 
176
            )
 
177
 
 
178
    # Now there are no more active channel dispatch operations
 
179
    assertEquals([], cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations'))
 
180
 
 
181
 
 
182
def test(q, bus, mc):
 
183
    params = dbus.Dictionary({"account": "someguy@example.com",
 
184
        "password": "secrecy"}, signature='sv')
 
185
    cm_name_ref, account = create_fakecm_account(q, bus, mc, params)
 
186
    conn = enable_fakecm_account(q, bus, mc, account, params)
 
187
 
 
188
    # Two clients want to observe, approve and handle channels. Additionally,
 
189
    # Kopete recognises a "Secret" flag on certain incoming channels, and
 
190
    # wants to bypass approval and observers for them. Also, Empathy is a
 
191
    # respawnable observer, which wants to get notified of existing channels
 
192
    # if it gets restarted.
 
193
    empathy = SimulatedClient(q, bus, 'Empathy',
 
194
            observe=[text_fixed_properties], approve=[text_fixed_properties],
 
195
            handle=[text_fixed_properties], bypass_approval=False,
 
196
            wants_recovery=True)
 
197
    kopete = SimulatedClient(q, bus, 'Kopete',
 
198
            observe=[contact_text_fixed_properties],
 
199
            approve=[contact_text_fixed_properties],
 
200
            handle=[contact_text_fixed_properties], bypass_approval=False)
 
201
    bypass = SimulatedClient(q, bus, 'Kopete.Bypasser',
 
202
            observe=[], approve=[],
 
203
            handle=[secret_fixed_properties],
 
204
            bypass_approval=True, bypass_observers=True)
 
205
 
 
206
    # wait for MC to download the properties
 
207
    expect_client_setup(q, [empathy, kopete, bypass])
 
208
 
 
209
    # subscribe to the OperationList interface (MC assumes that until this
 
210
    # property has been retrieved once, nobody cares)
 
211
 
 
212
    cd = bus.get_object(cs.CD, cs.CD_PATH)
 
213
    cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE)
 
214
    assertEquals([], cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations'))
 
215
 
 
216
    # First, a non-secret channel is created
 
217
 
 
218
    cdo_iface, chan, channel_properties, observe_events = announce_common(q,
 
219
            bus, empathy, kopete, account, conn, cd_props, False)
 
220
 
 
221
    # Both Observers indicate that they are ready to proceed
 
222
    for e in observe_events:
 
223
        q.dbus_return(e.message, signature='')
 
224
 
 
225
    expect_and_exercise_approval(q, bus, chan, channel_properties,
 
226
            empathy, kopete, cdo_iface, cd_props)
 
227
 
 
228
    nonsecret_chan = chan
 
229
 
 
230
    # Now a channel that bypasses approval and observers comes in.
 
231
    # During this process, we should never be asked to approve or
 
232
    # observe anything.
 
233
 
 
234
    approval = [
 
235
            EventPattern('dbus-method-call', method='AddDispatchOperation'),
 
236
            ]
 
237
 
 
238
    q.forbid_events(approval)
 
239
 
 
240
    cdo_iface, chan, channel_properties, observe_events = announce_common(q,
 
241
            bus, empathy, kopete, account, conn, cd_props, True)
 
242
 
 
243
    # Both Observers indicate that they are ready to proceed
 
244
    for e in observe_events:
 
245
        q.dbus_return(e.message, signature='')
 
246
 
 
247
    # Kopete's BypassApproval part is asked to handle the channels
 
248
    e = q.expect('dbus-method-call',
 
249
            path=bypass.object_path,
 
250
            interface=cs.HANDLER, method='HandleChannels',
 
251
            handled=False)
 
252
    # Kopete accepts the channels
 
253
    q.dbus_return(e.message, signature='')
 
254
 
 
255
    q.unforbid_events(approval)
 
256
 
 
257
    # Empathy, the observer, crashes
 
258
    empathy.release_name()
 
259
 
 
260
    e = q.expect('dbus-signal',
 
261
            signal='NameOwnerChanged',
 
262
            predicate=(lambda e:
 
263
                e.args[0] == empathy.bus_name and e.args[2] == ''),
 
264
            )
 
265
    empathy_unique_name = e.args[1]
 
266
 
 
267
    bus.flush()
 
268
 
 
269
    # Empathy gets restarted
 
270
    empathy.reacquire_name()
 
271
 
 
272
    e = q.expect('dbus-signal',
 
273
            signal='NameOwnerChanged',
 
274
            predicate=(lambda e:
 
275
                e.args[0] == empathy.bus_name and e.args[1] == ''),
 
276
            )
 
277
    empathy_unique_name = e.args[2]
 
278
 
 
279
    # Empathy is told to observe only the non-secret channel
 
280
    e = q.expect('dbus-method-call',
 
281
                path=empathy.object_path,
 
282
                interface=cs.OBSERVER, method='ObserveChannels',
 
283
                handled=False)
 
284
 
 
285
    channels = e.args[2]
 
286
    assertLength(1, channels)
 
287
    assertEquals(nonsecret_chan.object_path, channels[0][0])
 
288
 
 
289
if __name__ == '__main__':
 
290
    exec_test(test, {})
 
291