From 83853a9d963661838db82ba5ddb6348a7a4e83f2 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Mon, 8 Oct 2012 19:34:22 +0100 Subject: [PATCH 3/3] Add a regression test for service-points (matched by identifier) The side-effect they have within MC is that plugins aren't allowed to delay or reject channel requests; we ought to test that, really. --- tests/twisted/constants.py | 5 + .../dispatcher/create-delayed-by-mini-plugin.py | 183 ++++++++++++++------ tests/twisted/mctest.py | 9 + 3 files changed, 143 insertions(+), 54 deletions(-) diff --git a/tests/twisted/constants.py b/tests/twisted/constants.py index c3de47c..b2bb5af 100644 --- a/tests/twisted/constants.py +++ b/tests/twisted/constants.py @@ -65,6 +65,7 @@ CONN_IFACE_CONTACT_CAPS = CONN + '.Interface.ContactCapabilities' CONN_IFACE_REQUESTS = CONN + '.Interface.Requests' CONN_IFACE_SIMPLE_PRESENCE = CONN + '.Interface.SimplePresence' CONN_IFACE_POWER_SAVING = CONN + '.Interface.PowerSaving' +CONN_IFACE_SERVICE_POINT = CONN + '.Interface.ServicePoint' CONN_STATUS_CONNECTED = 0 CONN_STATUS_CONNECTING = 1 @@ -160,6 +161,10 @@ MEDIA_STREAM_DIRECTION_SEND = 1 MEDIA_STREAM_DIRECTION_RECEIVE = 2 MEDIA_STREAM_DIRECTION_BIDIRECTIONAL = 3 +SERVICE_POINT_TYPE_NONE = 0 +SERVICE_POINT_TYPE_EMERGENCY = 1 +SERVICE_POINT_TYPE_COUNSELING = 2 + CLIENT = tp_name_prefix + '.Client' CLIENT_PATH = tp_path_prefix + '/Client' OBSERVER = tp_name_prefix + '.Client.Observer' diff --git a/tests/twisted/dispatcher/create-delayed-by-mini-plugin.py b/tests/twisted/dispatcher/create-delayed-by-mini-plugin.py index b99e29f..38b776e 100644 --- a/tests/twisted/dispatcher/create-delayed-by-mini-plugin.py +++ b/tests/twisted/dispatcher/create-delayed-by-mini-plugin.py @@ -39,20 +39,63 @@ DELAYED_CTYPE = 'com.example.QuestionableChannel' def test(q, bus, mc): policy_bus_name_ref = dbus.service.BusName('com.example.Policy', bus) - # For now, we should never actually be asked to make a channel. - forbidden = [ - EventPattern('dbus-method-call', method='CreateChannel'), - EventPattern('dbus-method-call', method='EnsureChannel'), - EventPattern('dbus-method-call', method='ObserveChannels'), - EventPattern('dbus-method-call', method='AddDispatchOperation'), - EventPattern('dbus-method-call', method='HandleChannels'), - ] - q.forbid_events(forbidden) - params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') cm_name_ref, account = create_fakecm_account(q, bus, mc, params) - conn = enable_fakecm_account(q, bus, mc, account, params) + conn, e = enable_fakecm_account(q, bus, mc, account, params, + extra_interfaces=[cs.CONN_IFACE_SERVICE_POINT], + expect_after_connect=[ + EventPattern('dbus-method-call', method='Get', + args=[cs.CONN_IFACE_SERVICE_POINT, 'KnownServicePoints']), + ]) + + e_numbers = ['911', '112'] + points = dbus.Array([((cs.SERVICE_POINT_TYPE_EMERGENCY, 'urn:service:sos'), + e_numbers)], signature='((us)as)') + + q.dbus_return(e.message, points, signature='v') + + # MC looks up the handles for these numbers + e = q.expect('dbus-method-call', path=conn.object_path, + interface=cs.CONN, method='RequestHandles', + args=[cs.HT_CONTACT, e_numbers], + handled=True) + + # the service points change + e_numbers = ['911', '112', '999'] + points = dbus.Array([((cs.SERVICE_POINT_TYPE_EMERGENCY, 'urn:service:sos'), + e_numbers)], signature='((us)as)') + q.dbus_emit(conn.object_path, cs.CONN_IFACE_SERVICE_POINT, + 'ServicePointsChanged', points, signature='a((us)as)') + + # MC looks up the new handles + e = q.expect('dbus-method-call', path=conn.object_path, + interface=cs.CONN, method='RequestHandles', + args=[cs.HT_CONTACT, e_numbers], + handled=True) + + # MC used to critical if more than one emergency service point was + # given by the CM. That's silly, so let's test it. + e_numbers1 = ['911'] + e_numbers2 = ['999'] + points = dbus.Array([((cs.SERVICE_POINT_TYPE_EMERGENCY, 'urn:service:sos'), + e_numbers1), + ((cs.SERVICE_POINT_TYPE_EMERGENCY, 'urn:service:sos'), + e_numbers2)], signature='((us)as)') + q.dbus_emit(conn.object_path, cs.CONN_IFACE_SERVICE_POINT, + 'ServicePointsChanged', points, signature='a((us)as)') + + e_numbers = e_numbers1 + e_numbers2 + + q.expect_many(EventPattern('dbus-method-call', path=conn.object_path, + interface=cs.CONN, method='RequestHandles', + args=[cs.HT_CONTACT, e_numbers1], + handled=True), + EventPattern('dbus-method-call', path=conn.object_path, + interface=cs.CONN, method='RequestHandles', + args=[cs.HT_CONTACT, e_numbers2], + handled=True), + ) fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, @@ -71,49 +114,81 @@ def test(q, bus, mc): cd = bus.get_object(cs.CD, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) - # UI calls ChannelDispatcher.CreateChannel - request = dbus.Dictionary({ - cs.CHANNEL + '.ChannelType': DELAYED_CTYPE, - cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, - cs.CHANNEL + '.TargetID': 'juliet', - }, signature='sv') - call_async(q, cd, 'CreateChannel', - account.object_path, request, user_action_time, client.bus_name, - dbus_interface=cs.CD) - - ret = q.expect('dbus-return', - method='CreateChannel') - request_path = ret.value[0] - - # 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'] == [] - - call_async(q, cr, 'Proceed', dbus_interface=cs.CR) - - q.expect('dbus-return', method='Proceed') - - # What does the policy service think? - permission = q.expect('dbus-method-call', path='/com/example/Policy', - interface='com.example.Policy', method='RequestRequest') - - # Think about it for a bit, then allow dispatching to continue - sync_dbus(bus, q, account) - q.unforbid_events(forbidden) - q.dbus_return(permission.message, signature='') - - # Only now does the CM's CreateChannel method get called - cm_request_call = q.expect('dbus-method-call', - interface=cs.CONN_IFACE_REQUESTS, - method='CreateChannel', - path=conn.object_path, args=[request], handled=False) - q.dbus_raise(cm_request_call.message, cs.INVALID_ARGUMENT, 'No') + for emergency in False, True: + if emergency: + target_id = '112' + forbidden = [ + EventPattern('dbus-method-call', method='RequestRequest'), + ] + + else: + target_id = 'juliet' + # For now, we should never actually be asked to make a channel. + forbidden = [ + EventPattern('dbus-method-call', method='CreateChannel'), + EventPattern('dbus-method-call', method='EnsureChannel'), + EventPattern('dbus-method-call', method='ObserveChannels'), + EventPattern('dbus-method-call', method='AddDispatchOperation'), + EventPattern('dbus-method-call', method='HandleChannels'), + ] + + q.forbid_events(forbidden) + + # UI calls ChannelDispatcher.CreateChannel + request = dbus.Dictionary({ + cs.CHANNEL + '.ChannelType': DELAYED_CTYPE, + cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, + cs.CHANNEL + '.TargetID': target_id, + }, signature='sv') + call_async(q, cd, 'CreateChannel', + account.object_path, request, user_action_time, client.bus_name, + dbus_interface=cs.CD) + + ret = q.expect('dbus-return', + method='CreateChannel') + request_path = ret.value[0] + + # 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'] == [] + + call_async(q, cr, 'Proceed', dbus_interface=cs.CR) + + q.expect('dbus-return', method='Proceed') + + if emergency: + # The CM is asked to create the channel anyway, because this + # looks a bit like an emergency call + cm_request_call = q.expect('dbus-method-call', + interface=cs.CONN_IFACE_REQUESTS, + method='CreateChannel', + path=conn.object_path, args=[request], handled=False) + q.dbus_raise(cm_request_call.message, cs.INVALID_ARGUMENT, 'No') + + sync_dbus(bus, q, account) + q.unforbid_events(forbidden) + else: + # What does the policy service think? + permission = q.expect('dbus-method-call', path='/com/example/Policy', + interface='com.example.Policy', method='RequestRequest') + + # Think about it for a bit, then allow dispatching to continue + sync_dbus(bus, q, account) + q.unforbid_events(forbidden) + q.dbus_return(permission.message, signature='') + + # Only now does the CM's CreateChannel method get called + cm_request_call = q.expect('dbus-method-call', + interface=cs.CONN_IFACE_REQUESTS, + method='CreateChannel', + path=conn.object_path, args=[request], handled=False) + q.dbus_raise(cm_request_call.message, cs.INVALID_ARGUMENT, 'No') if __name__ == '__main__': exec_test(test, {}) diff --git a/tests/twisted/mctest.py b/tests/twisted/mctest.py index c1577cc..2c67b2c 100644 --- a/tests/twisted/mctest.py +++ b/tests/twisted/mctest.py @@ -273,6 +273,9 @@ class SimulatedConnection(object): path=self.object_path, interface=cs.CONN, method='GetInterfaces') + q.add_dbus_method_impl(self.RequestHandles, + path=self.object_path, interface=cs.CONN, + method='RequestHandles') q.add_dbus_method_impl(self.InspectHandles, path=self.object_path, interface=cs.CONN, method='InspectHandles') @@ -505,6 +508,12 @@ class SimulatedConnection(object): except e: self.q.dbus_raise(e.message, INVALID_HANDLE, str(e.args[0])) + def RequestHandles(self, e): + htype, idents = e.args + self.q.dbus_return(e.message, + [self.ensure_handle(htype, i) for i in idents], + signature='au') + def GetStatus(self, e): self.q.dbus_return(e.message, self.status, signature='u') -- 1.7.10.4