def test(q, bus, mc): params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') client = SimulatedClient(q, bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) # No Approver should be invoked at any point during this test, because the # Channel was Requested def fail_on_approval(e): raise AssertionError('Approver should not be invoked') q.add_dbus_method_impl(fail_on_approval, path=client.object_path, interface=cs.APPROVER, method='AddDispatchOperation') # wait for MC to download the properties expect_client_setup(q, [client]) test_channel_creation(q, bus, account, client, conn, False) test_channel_creation(q, bus, account, client, conn, True)
def test(q, bus, mc): params = dbus.Dictionary( { "account": "*****@*****.**", "password": "******" }, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary( { cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') client = SimulatedClient(q, bus, 'Empathy', observe=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [client]) test_channel_creation(q, bus, account, client, conn, False) test_channel_creation(q, bus, account, client, conn, True)
def test(q, bus, mc): params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) account_iface = dbus.Interface(account, cs.ACCOUNT) account_props = dbus.Interface(account, cs.PROPERTIES_IFACE) call_async(q, account_props, 'Set', cs.ACCOUNT, 'RequestedPresence', (dbus.UInt32(cs.PRESENCE_OFFLINE), 'offline', '')) q.expect('dbus-return', method='Set') call_async(q, account_props, 'Set', cs.ACCOUNT, 'Enabled', False) q.expect('dbus-return', method='Set') call_async(q, account_props, 'Set', cs.ACCOUNT, 'ConnectAutomatically', False) q.expect('dbus-return', method='Set') call_async(q, account_props, 'Set', cs.ACCOUNT, 'RequestedPresence', (dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Testing Enabled')) q.expect('dbus-return', method='Set') # Go online by setting Enabled call_async(q, account_props, 'Set', cs.ACCOUNT, 'Enabled', True) e = q.expect('dbus-method-call', method='RequestConnection', args=['fakeprotocol', params], destination=cs.tp_name_prefix + '.ConnectionManager.fakecm', path=cs.tp_path_prefix + '/ConnectionManager/fakecm', interface=cs.tp_name_prefix + '.ConnectionManager', handled=False)
def test(q, bus, mc): params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') # Emulate a handler that only wants to get outgoing channels, as a # regression test for <http://bugs.freedesktop.org/show_bug.cgi?id=23935>, # in which those didn't work text_requested = dbus.Dictionary(text_fixed_properties, signature='sv') text_requested[cs.CHANNEL + '.Requested'] = True client = SimulatedClient(q, bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_requested], bypass_approval=False) # No Approver should be invoked at any point during this test, because the # Channel was Requested def fail_on_approval(e): raise AssertionError('Approver should not be invoked') q.add_dbus_method_impl(fail_on_approval, path=client.object_path, interface=cs.APPROVER, method='AddDispatchOperation') # wait for MC to download the properties expect_client_setup(q, [client]) test_channel_creation(q, bus, account, client, conn, False) test_channel_creation(q, bus, account, client, conn, True)
def test(q, bus, mc): params = dbus.Dictionary( {"account": "*****@*****.**", "password": "******", }, signature='sv') (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) account.Properties.Set(cs.ACCOUNT, 'Enabled', True) # Set online presence presence = dbus.Struct( (dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Fixing MC bugs'), signature='uss') account.Properties.Set(cs.ACCOUNT, 'RequestedPresence', presence) e = q.expect('dbus-method-call', method='RequestConnection', args=['fakeprotocol', params], destination=tp_name_prefix + '.ConnectionManager.fakecm', path=tp_path_prefix + '/ConnectionManager/fakecm', interface=tp_name_prefix + '.ConnectionManager', handled=False) q.dbus_raise(e.message, cs.NOT_IMPLEMENTED, "CM is broken") # MC should report the connection dying. e = q.expect('dbus-signal', signal='AccountPropertyChanged', predicate=lambda e: 'ConnectionError' in e.args[0]) changed, = e.args assertEquals('/', changed['Connection']) assertEquals(cs.CONN_STATUS_DISCONNECTED, changed['ConnectionStatus']) assertEquals(cs.CSR_NONE_SPECIFIED, changed['ConnectionStatusReason']) assertEquals(cs.NOT_IMPLEMENTED, changed['ConnectionError'])
def _create_and_enable(q, bus, mc, account_name, power_saving_supported, expect_after_connect=[]): extra_interfaces = [] if power_saving_supported: extra_interfaces = [cs.CONN_IFACE_POWER_SAVING] params = dbus.Dictionary({ "account": account_name, "password": "******" }, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params, extra_interfaces=extra_interfaces, expect_after_connect=expect_after_connect) if isinstance(conn, tuple): conn = conn[0] return account, conn
def test(q, bus, mc): params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') client = SimulatedClient(q, bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [client]) channel = test_channel_creation(q, bus, account, client, conn, yours_first=True, swap_requests=False) channel.close() channel = test_channel_creation(q, bus, account, client, conn, yours_first=True, swap_requests=True) channel.close() channel = test_channel_creation(q, bus, account, client, conn, yours_first=False, swap_requests=False) channel.close() channel = test_channel_creation(q, bus, account, client, conn, yours_first=False, swap_requests=True) channel.close()
def test(q, bus, mc): params = dbus.Dictionary( { "account": "*****@*****.**", "password": "******" }, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary( { cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') client = SimulatedClient(q, bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) # This client doesn't say it can handle channels, but if it requests one # for itself, we'll at least try dispatching to it. # # A real-world use case for this is if a client wants to request channels, # and handle the channels that it, itself, requested, but not handle # anything requested by others: for instance, nautilus-sendto behaves # like this. See fd.o #23651 unsuitable = SimulatedClient(q, bus, 'Unsuitable', observe=[], approve=[], handle=[], is_handler=True, bypass_approval=False) # No Approver should be invoked at any point during this test, because the # Channel was Requested def fail_on_approval(e): raise AssertionError('Approver should not be invoked') q.add_dbus_method_impl(fail_on_approval, path=client.object_path, interface=cs.APPROVER, method='AddDispatchOperation') # wait for MC to download the properties expect_client_setup(q, [client, unsuitable]) test_channel_creation(q, bus, account, client, conn, False) test_channel_creation(q, bus, account, client, conn, True) test_channel_creation(q, bus, account, client, conn, False, unsuitable) test_channel_creation(q, bus, account, client, conn, False, unsuitable, cs.CHANNEL_TYPE_CALL)
def test(q, bus, mc): cm_bus = dbus.bus.BusConnection() cm_bus.set_exit_on_disconnect(False) # we'll disconnect later q.attach_to_bus(cm_bus) params = dbus.Dictionary( {"account": "*****@*****.**", "password": "******", }, signature='sv') (simulated_cm, account) = create_fakecm_account(q, bus, mc, params, cm_bus=cm_bus) account.Properties.Set(cs.ACCOUNT, 'Enabled', True) # Set online presence presence = dbus.Struct( (dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Fixing MC bugs'), signature='uss') account.Properties.Set(cs.ACCOUNT, 'RequestedPresence', presence) e = q.expect('dbus-method-call', method='RequestConnection', args=['fakeprotocol', params], destination=tp_name_prefix + '.ConnectionManager.fakecm', path=tp_path_prefix + '/ConnectionManager/fakecm', interface=tp_name_prefix + '.ConnectionManager', handled=False) conn = SimulatedConnection(q, cm_bus, 'fakecm', 'fakeprotocol', '_', 'myself', has_presence=True) 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) # Connect succeeds conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) # CM crashes conn.release_name() simulated_cm.release_name() cm_bus.flush() cm_bus.close() # MC should report the connection dying. e = q.expect('dbus-signal', signal='AccountPropertyChanged', predicate=lambda e: 'ConnectionError' in e.args[0]) changed, = e.args assertEquals('/', changed['Connection']) assertEquals(cs.CONN_STATUS_DISCONNECTED, changed['ConnectionStatus']) # In the absence of a better code, None will have to do. assertEquals(cs.CSR_NONE_SPECIFIED, changed['ConnectionStatusReason']) # And NoReply will do as “it crashed”. assertEquals(cs.DBUS_ERROR_NO_REPLY, changed['ConnectionError'])
def test(q, bus, mc): params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params, has_requests=False) q.expect_many( EventPattern('dbus-signal', signal='AccountPropertyChanged', predicate=lambda e: e.args[0].get('ConnectionError') == cs.SOFTWARE_UPGRADE_REQUIRED), EventPattern('dbus-method-call', method='Disconnect', handled=True), )
def _create_and_enable(q, bus, mc, account_name, power_saving_supported, expect_after_connect=[]): extra_interfaces = [] if power_saving_supported: extra_interfaces = [cs.CONN_IFACE_POWER_SAVING] params = dbus.Dictionary({"account": account_name, "password": "******"}, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params, extra_interfaces=extra_interfaces, expect_after_connect=expect_after_connect) if isinstance(conn, tuple): conn = conn[0] return account, conn
def test(q, bus, mc): params = dbus.Dictionary( { "account": "*****@*****.**", "password": "******" }, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary( { cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') # Emulate a handler that only wants to get outgoing channels, as a # regression test for <http://bugs.freedesktop.org/show_bug.cgi?id=23935>, # in which those didn't work text_requested = dbus.Dictionary(text_fixed_properties, signature='sv') text_requested[cs.CHANNEL + '.Requested'] = True client = SimulatedClient(q, bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_requested], bypass_approval=False) # No Approver should be invoked at any point during this test, because the # Channel was Requested def fail_on_approval(e): raise AssertionError('Approver should not be invoked') q.add_dbus_method_impl(fail_on_approval, path=client.object_path, interface=cs.APPROVER, method='AddDispatchOperation') # wait for MC to download the properties expect_client_setup(q, [client]) test_channel_creation(q, bus, account, client, conn, False) test_channel_creation(q, bus, account, client, conn, True)
def test(q, bus, mc): params = dbus.Dictionary( { "account": "*****@*****.**", "password": "******" }, signature='sv') (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) account_iface = dbus.Interface(account, cs.ACCOUNT) account_props = dbus.Interface(account, cs.PROPERTIES_IFACE) # Ensure that it's enabled but has offline RP call_async(q, account_props, 'Set', cs.ACCOUNT, 'RequestedPresence', (dbus.UInt32(cs.PRESENCE_OFFLINE), 'offline', '')) q.expect('dbus-return', method='Set') call_async( q, account_props, 'Set', cs.ACCOUNT, 'AutomaticPresence', (dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Testing automatic presence')) q.expect('dbus-return', method='Set') q.expect( 'dbus-signal', signal='AccountPropertyChanged', predicate=lambda e: e.args[0].get('AutomaticPresence', (None, None, None))[1] == 'busy') call_async(q, account_props, 'Set', cs.ACCOUNT, 'Enabled', True) q.expect('dbus-return', method='Set') q.expect('dbus-signal', signal='AccountPropertyChanged', predicate=lambda e: e.args[0].get('Enabled')) # Go online by telling it to connect automatically call_async(q, account_props, 'Set', cs.ACCOUNT, 'ConnectAutomatically', True) e = q.expect('dbus-method-call', method='RequestConnection', args=['fakeprotocol', params], destination=cs.tp_name_prefix + '.ConnectionManager.fakecm', path=cs.tp_path_prefix + '/ConnectionManager/fakecm', interface=cs.tp_name_prefix + '.ConnectionManager', handled=False)
def test(q, bus, mc): params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') client = SimulatedClient(q, bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [client]) cd = bus.get_object(cs.CD, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) # chat UI calls ChannelDispatcher.EnsureChannel or CreateChannel request = dbus.Dictionary({ cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.TargetID': 'juliet', }, signature='sv') call_async(q, cd, 'CreateChannel', account.object_path, request, dbus.Int64(1234), 'grr.arg', # a valid bus name, but the wrong prefix dbus_interface=cs.CD) ret = q.expect('dbus-error', method='CreateChannel') assert ret.error.get_dbus_name() == cs.INVALID_ARGUMENT call_async(q, cd, 'CreateChannel', account.object_path, request, dbus.Int64(1234), 'can has cheeseburger?', # a totally invalid bus name dbus_interface=cs.CD) ret = q.expect('dbus-error', method='CreateChannel') assert ret.error.get_dbus_name() == cs.INVALID_ARGUMENT
def test(q, bus, mc): params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') client = SimulatedClient(q, bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) # This client doesn't say it can handle channels, but if it requests one # for itself, we'll at least try dispatching to it. # # A real-world use case for this is if a client wants to request channels, # and handle the channels that it, itself, requested, but not handle # anything requested by others: for instance, nautilus-sendto behaves # like this. See fd.o #23651 unsuitable = SimulatedClient(q, bus, 'Unsuitable', observe=[], approve=[], handle=[], is_handler=True, bypass_approval=False) # No Approver should be invoked at any point during this test, because the # Channel was Requested def fail_on_approval(e): raise AssertionError('Approver should not be invoked') q.add_dbus_method_impl(fail_on_approval, path=client.object_path, interface=cs.APPROVER, method='AddDispatchOperation') # wait for MC to download the properties expect_client_setup(q, [client, unsuitable]) test_channel_creation(q, bus, account, client, conn, False) test_channel_creation(q, bus, account, client, conn, True) test_channel_creation(q, bus, account, client, conn, False, unsuitable) test_channel_creation(q, bus, account, client, conn, False, unsuitable, cs.CHANNEL_TYPE_CALL)
def test(q, bus, mc): params = dbus.Dictionary( { "account": "*****@*****.**", "password": "******" }, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params, has_requests=False) q.expect_many( EventPattern('dbus-signal', signal='AccountPropertyChanged', predicate=lambda e: e.args[0].get('ConnectionError') == cs .SOFTWARE_UPGRADE_REQUIRED), EventPattern('dbus-method-call', method='Disconnect', handled=True), )
def test(q, bus, mc): params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) account_iface = dbus.Interface(account, cs.ACCOUNT) account_props = dbus.Interface(account, cs.PROPERTIES_IFACE) # Ensure that it's enabled but has offline RP call_async(q, account_props, 'Set', cs.ACCOUNT, 'RequestedPresence', (dbus.UInt32(cs.PRESENCE_OFFLINE), 'offline', '')) q.expect('dbus-return', method='Set') call_async(q, account_props, 'Set', cs.ACCOUNT, 'AutomaticPresence', (dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Testing automatic presence')) q.expect('dbus-return', method='Set') q.expect('dbus-signal', signal='AccountPropertyChanged', predicate=lambda e: e.args[0].get('AutomaticPresence', (None, None, None))[1] == 'busy') call_async(q, account_props, 'Set', cs.ACCOUNT, 'Enabled', True) q.expect('dbus-return', method='Set') q.expect('dbus-signal', signal='AccountPropertyChanged', predicate=lambda e: e.args[0].get('Enabled')) # Go online by telling it to connect automatically call_async(q, account_props, 'Set', cs.ACCOUNT, 'ConnectAutomatically', True) e = q.expect('dbus-method-call', method='RequestConnection', args=['fakeprotocol', params], destination=cs.tp_name_prefix + '.ConnectionManager.fakecm', path=cs.tp_path_prefix + '/ConnectionManager/fakecm', interface=cs.tp_name_prefix + '.ConnectionManager', handled=False)
def test(q, bus, mc): params = dbus.Dictionary( { "account": "*****@*****.**", "password": "******" }, signature='sv') (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) account_iface = dbus.Interface(account, cs.ACCOUNT) account_props = dbus.Interface(account, cs.PROPERTIES_IFACE) call_async(q, account_props, 'Set', cs.ACCOUNT, 'RequestedPresence', (dbus.UInt32(cs.PRESENCE_OFFLINE), 'offline', '')) q.expect('dbus-return', method='Set') call_async(q, account_props, 'Set', cs.ACCOUNT, 'Enabled', False) q.expect('dbus-return', method='Set') call_async(q, account_props, 'Set', cs.ACCOUNT, 'ConnectAutomatically', False) q.expect('dbus-return', method='Set') call_async(q, account_props, 'Set', cs.ACCOUNT, 'RequestedPresence', (dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Testing Enabled')) q.expect('dbus-return', method='Set') # Go online by setting Enabled call_async(q, account_props, 'Set', cs.ACCOUNT, 'Enabled', True) e = q.expect('dbus-method-call', method='RequestConnection', args=['fakeprotocol', params], destination=cs.tp_name_prefix + '.ConnectionManager.fakecm', path=cs.tp_path_prefix + '/ConnectionManager/fakecm', interface=cs.tp_name_prefix + '.ConnectionManager', handled=False)
def test(q, bus, mc): params = dbus.Dictionary( { "account": "*****@*****.**", "password": "******", }, signature='sv') (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) account.Properties.Set(cs.ACCOUNT, 'Enabled', True) # Set online presence presence = dbus.Struct( (dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Fixing MC bugs'), signature='uss') account.Properties.Set(cs.ACCOUNT, 'RequestedPresence', presence) e = q.expect('dbus-method-call', method='RequestConnection', args=['fakeprotocol', params], destination=tp_name_prefix + '.ConnectionManager.fakecm', path=tp_path_prefix + '/ConnectionManager/fakecm', interface=tp_name_prefix + '.ConnectionManager', handled=False) q.dbus_raise(e.message, cs.NOT_IMPLEMENTED, "CM is broken") # MC should report the connection dying. e = q.expect('dbus-signal', signal='AccountPropertyChanged', predicate=lambda e: 'ConnectionError' in e.args[0]) changed, = e.args assertEquals('/', changed['Connection']) assertEquals(cs.CONN_STATUS_DISCONNECTED, changed['ConnectionStatus']) assertEquals(cs.CSR_NONE_SPECIFIED, changed['ConnectionStatusReason']) assertEquals(cs.NOT_IMPLEMENTED, changed['ConnectionError'])
def test(q, bus, mc): params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) policy_bus_name_ref = dbus.service.BusName('com.example.Policy', bus) # For the beginning of this test, we should never be asked to handle # a channel. forbidden = [ EventPattern('dbus-method-call', method='HandleChannels'), ] q.forbid_events(forbidden) # Two clients want to observe, approve and handle channels empathy = SimulatedClient(q, bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) kopete = SimulatedClient(q, bus, 'Kopete', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [empathy, kopete]) # subscribe to the OperationList interface (MC assumes that until this # property has been retrieved once, nobody cares) cd = bus.get_object(cs.CD, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] e, chan, cdo_path = signal_channel_expect_query(q, bus, account, conn, empathy, kopete) # No. q.dbus_raise(e.message, 'com.example.Errors.No', 'Denied!') # The plugin responds _, _, e = q.expect_many( EventPattern('dbus-signal', path=cdo_path, interface=cs.CDO, signal='Finished'), EventPattern('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='DispatchOperationFinished', args=[cdo_path]), EventPattern('dbus-method-call', path=chan.object_path, interface=cs.CHANNEL_IFACE_DESTROYABLE, method='Destroy', handled=False), ) q.dbus_return(e.message, signature='') chan.close() # Try again e, chan, cdo_path = signal_channel_expect_query(q, bus, account, conn, empathy, kopete) # Yes. q.dbus_return(e.message, signature='') e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), ) q.dbus_return(e.message, signature='') q.dbus_return(k.message, signature='') empathy_cdo = bus.get_object(cs.CD, cdo_path) empathy_cdo_iface = dbus.Interface(empathy_cdo, cs.CDO) call_async(q, empathy_cdo_iface, 'Claim') check_handler = q.expect('dbus-method-call', path='/com/example/Policy', interface='com.example.Policy', method='CheckHandler') q.dbus_raise(check_handler.message, 'com.example.Errors.No', "That handler doesn't have enough options") q.expect('dbus-error', method='Claim', name=cs.PERMISSION_DENIED) kopete_cdo = bus.get_object(cs.CD, cdo_path) kopete_cdo_iface = dbus.Interface(kopete_cdo, cs.CDO) call_async(q, kopete_cdo_iface, 'Claim') check_handler = q.expect('dbus-method-call', path='/com/example/Policy', interface='com.example.Policy', method='CheckHandler') q.dbus_return(check_handler.message, signature='') q.expect_many( EventPattern('dbus-signal', path=cdo_path, signal='Finished'), EventPattern('dbus-signal', path=cs.CD_PATH, signal='DispatchOperationFinished', args=[cdo_path]), EventPattern('dbus-return', method='Claim'), ) sync_dbus(bus, q, mc) # Try again; this time we'll reject a selected handler e, chan, cdo_path = signal_channel_expect_query(q, bus, account, conn, empathy, kopete) # The request is fine, continue... q.dbus_return(e.message, signature='') e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), ) q.dbus_return(e.message, signature='') q.dbus_return(k.message, signature='') kopete_cdo = bus.get_object(cs.CD, cdo_path) kopete_cdo_iface = dbus.Interface(kopete_cdo, cs.CDO) call_async(q, kopete_cdo_iface, 'HandleWith', cs.tp_name_prefix + '.Client.Kopete') check_handler = q.expect('dbus-method-call', path='/com/example/Policy', interface='com.example.Policy', method='CheckHandler') q.dbus_raise(check_handler.message, 'com.example.Errors.No', 'That handler is not good enough') q.expect('dbus-error', method='HandleWith', name=cs.PERMISSION_DENIED) # well, let's try *something*... Kopete has been marked as failed, # so this will try Empathy call_async(q, kopete_cdo_iface, 'HandleWith', '') check_handler = q.expect('dbus-method-call', path='/com/example/Policy', interface='com.example.Policy', method='CheckHandler') q.dbus_raise(check_handler.message, 'com.example.Errors.No', 'That handler is no good either') # Oops... we ran out of handlers _, _, _, e = q.expect_many( EventPattern('dbus-error', method='HandleWith', name=cs.PERMISSION_DENIED), EventPattern('dbus-signal', path=cdo_path, interface=cs.CDO, signal='Finished'), EventPattern('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='DispatchOperationFinished', args=[cdo_path]), EventPattern('dbus-method-call', path=chan.object_path, interface=cs.CHANNEL_IFACE_DESTROYABLE, method='Destroy', handled=False), ) q.dbus_return(e.message, signature='') chan.close() sync_dbus(bus, q, mc) # From now on we no longer want to forbid HandleChannels, but we do want # to forbid AddDispatchOperation q.unforbid_events(forbidden) forbidden = [ EventPattern('dbus-method-call', method='AddDispatchOperation'), ] q.forbid_events(forbidden) # Try yet again policy_request, chan, cdo_path = signal_channel_expect_query(q, bus, account, conn, empathy, kopete) # Before the policy service replies, someone requests the same channel user_action_time = dbus.Int64(1238582606) call_async(q, cd, 'EnsureChannel', account.object_path, chan.immutable, user_action_time, kopete.bus_name, dbus_interface=cs.CD) ret, add_request_call = q.expect_many( EventPattern('dbus-return', method='EnsureChannel'), EventPattern('dbus-method-call', handled=False, interface=cs.CLIENT_IFACE_REQUESTS, method='AddRequest', path=kopete.object_path), ) request_path = ret.value[0] cr = bus.get_object(cs.CD, request_path) cr.Proceed(dbus_interface=cs.CR) cm_request_call = q.expect('dbus-method-call', interface=cs.CONN_IFACE_REQUESTS, method='EnsureChannel', path=conn.object_path, args=[chan.immutable], handled=False) q.dbus_return(add_request_call.message, signature='') # Time passes. The CM returns the existing channel, and the policy # service gets round to replying q.dbus_return(cm_request_call.message, False, chan.object_path, chan.immutable, signature='boa{sv}') q.dbus_return(policy_request.message, signature='') # Now we want to pass the channel to the selected handler. # What does the policy service think about that? check_handler = q.expect('dbus-method-call', path='/com/example/Policy', interface='com.example.Policy', method='CheckHandler') # Yeah, we're OK with that. q.dbus_return(check_handler.message, signature='') e = q.expect('dbus-method-call', path=kopete.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] == chan.object_path, channels assert channels[0][1] == chan.immutable, channels assert e.args[3] == [request_path], e.args assert e.args[4] == user_action_time, (e.args[4], user_action_time) assert isinstance(e.args[5], dict) assert len(e.args) == 6 # Handler accepts the Channels q.dbus_return(e.message, signature='') q.expect_many( EventPattern('dbus-signal', interface=cs.CDO, signal='Finished'), EventPattern('dbus-signal', interface=cs.CD_IFACE_OP_LIST, signal='DispatchOperationFinished'), ) sync_dbus(bus, q, mc)
def test(q, bus, mc): params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) account_iface = dbus.Interface(account, cs.ACCOUNT) account_props = dbus.Interface(account, cs.PROPERTIES_IFACE) call_async(q, account_props, 'Set', cs.ACCOUNT, 'RequestedPresence', (dbus.UInt32(cs.PRESENCE_OFFLINE), 'offline', '')) q.expect('dbus-return', method='Set') call_async(q, account_props, 'Set', cs.ACCOUNT, 'AutomaticPresence', (dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Testing automatic presence')) q.expect('dbus-return', method='Set') q.expect('dbus-signal', signal='AccountPropertyChanged', predicate=lambda e: e.args[0].get('AutomaticPresence', (None, None, None))[1] == 'busy') call_async(q, account_props, 'Set', cs.ACCOUNT, 'Enabled', False) q.expect('dbus-return', method='Set') call_async(q, account_props, 'Set', cs.ACCOUNT, 'ConnectAutomatically', False) q.expect('dbus-return', method='Set') # Requesting a channel won't put us online, since it's disabled # make sure RequestConnection doesn't get called events = [EventPattern('dbus-method-call', method='RequestConnection')] q.forbid_events(events) user_action_time = dbus.Int64(1238582606) cd = bus.get_object(cs.CD, cs.CD_PATH) request = dbus.Dictionary({ cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.TargetID': 'juliet', }, signature='sv') call_async(q, cd, 'CreateChannel', account.object_path, request, user_action_time, "", dbus_interface=cs.CD) ret = q.expect('dbus-return', method='CreateChannel') request_path = ret.value[0] 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'] == "" assert request_props['Interfaces'] == [] sync_dbus(bus, q, mc) cr.Proceed(dbus_interface=cs.CR) # FIXME: error isn't specified (NotAvailable perhaps?) q.expect('dbus-signal', path=cr.object_path, interface=cs.CR, signal='Failed')
def test(q, bus, mc): params = dbus.Dictionary( { "account": "*****@*****.**", "password": "******" }, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) # One client (Kopete) has less specific filters than the other (Empathy), # to make sure that the dispatcher would normally prefer Empathy; this # means that when we use Kopete as the preferred handler, we know that # if Kopete is invoked, then preferring the preferred handler correctly # took precedence over the normal logic. vague_fixed_properties = dbus.Dictionary( { cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') text_fixed_properties = dbus.Dictionary( { cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') empathy_bus = dbus.bus.BusConnection() kopete_bus = dbus.bus.BusConnection() q.attach_to_bus(empathy_bus) q.attach_to_bus(kopete_bus) # Two clients want to observe, approve and handle channels empathy = SimulatedClient(q, empathy_bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) kopete = SimulatedClient(q, kopete_bus, 'Kopete', observe=[vague_fixed_properties], approve=[vague_fixed_properties], handle=[vague_fixed_properties], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [empathy, kopete]) # subscribe to the OperationList interface (MC assumes that until this # property has been retrieved once, nobody cares) cd = bus.get_object(cs.CD, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] channel_properties = dbus.Dictionary(text_fixed_properties, signature='sv') channel_properties[cs.CHANNEL + '.TargetID'] = 'juliet' channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.InitiatorID'] = 'juliet' channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.Requested'] = False channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') chan = SimulatedChannel(conn, channel_properties) chan.announce() # A channel dispatch operation is created e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') cdo_path = e.args[0] cdo_properties = e.args[1] assert cdo_properties[cs.CDO + '.Account'] == account.object_path assert cdo_properties[cs.CDO + '.Connection'] == conn.object_path assert cs.CDO + '.Interfaces' in cdo_properties handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] # Empathy has a more specific filter, so it comes first assert handlers == [ cs.tp_name_prefix + '.Client.Empathy', cs.tp_name_prefix + '.Client.Kopete' ], handlers assert cs.CD_IFACE_OP_LIST in cd_props.Get(cs.CD, 'Interfaces') assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') ==\ [(cdo_path, cdo_properties)] cdo = bus.get_object(cs.CD, cdo_path) cdo_iface = dbus.Interface(cdo, cs.CDO) cdo_props_iface = dbus.Interface(cdo, cs.PROPERTIES_IFACE) assert cdo_props_iface.Get(cs.CDO, 'Interfaces') == \ cdo_properties[cs.CDO + '.Interfaces'] assert cdo_props_iface.Get(cs.CDO, 'Connection') == conn.object_path assert cdo_props_iface.Get(cs.CDO, 'Account') == account.object_path assert cdo_props_iface.Get(cs.CDO, 'Channels') == [(chan.object_path, channel_properties)] assert cdo_props_iface.Get(cs.CDO, 'PossibleHandlers') == \ cdo_properties[cs.CDO + '.PossibleHandlers'] # Both Observers are told about the new channel e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), ) assert e.args[0] == account.object_path, e.args assert e.args[1] == conn.object_path, e.args assert e.args[3] == cdo_path, e.args assert e.args[4] == [], e.args # no requests satisfied channels = e.args[2] assert len(channels) == 1, channels assert channels[0][0] == chan.object_path, channels assert channels[0][1] == channel_properties, channels assert k.args == e.args # Both Observers indicate that they are ready to proceed q.dbus_return(k.message, bus=empathy_bus, signature='') q.dbus_return(e.message, bus=kopete_bus, signature='') # The Approvers are next e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), ) assert e.args == [[(chan.object_path, channel_properties)], cdo_path, cdo_properties] assert k.args == e.args q.dbus_return(e.message, bus=empathy_bus, signature='') q.dbus_return(k.message, bus=kopete_bus, signature='') # Both Approvers now have a flashing icon or something, trying to get the # user's attention. However, the user is busy looking through the address # book, and independently decides to talk to Juliet. The address book # is from KDE so wants Kopete to be used. user_action_time = dbus.Int64(1238582606) request = dbus.Dictionary( { cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.TargetID': 'juliet', }, signature='sv') call_async(q, cd, 'EnsureChannel', account.object_path, request, user_action_time, kopete.bus_name, dbus_interface=cs.CD) ret, add_request_call = q.expect_many( EventPattern('dbus-return', method='EnsureChannel'), EventPattern('dbus-method-call', handled=False, interface=cs.CLIENT_IFACE_REQUESTS, method='AddRequest', path=kopete.object_path), ) request_path = ret.value[0] assert add_request_call.args[0] == request_path request_props = add_request_call.args[1] assert request_props[cs.CR + '.Account'] == account.object_path assert request_props[cs.CR + '.Requests'] == [request] assert request_props[cs.CR + '.UserActionTime'] == user_action_time assert request_props[cs.CR + '.PreferredHandler'] == kopete.bus_name assert request_props[cs.CR + '.Interfaces'] == [] # 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'] == kopete.bus_name assert request_props['Interfaces'] == [] cr.Proceed(dbus_interface=cs.CR) cm_request_call = q.expect('dbus-method-call', interface=cs.CONN_IFACE_REQUESTS, method='EnsureChannel', path=conn.object_path, args=[request], handled=False) q.dbus_return(add_request_call.message, bus=kopete_bus, signature='') # Time passes. The CM returns the existing channel q.dbus_return(cm_request_call.message, False, chan.object_path, chan.immutable, signature='boa{sv}') # EnsureChannel constitutes approval, so Kopete is told to handle the # channel e = q.expect('dbus-method-call', path=kopete.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] == chan.object_path, channels assert channels[0][1] == chan.immutable, channels assert e.args[3] == [request_path], e.args assert e.args[4] == user_action_time, (e.args[4], user_action_time) assert isinstance(e.args[5], dict) assert len(e.args) == 6 q.dbus_return(e.message, bus=kopete_bus, signature='') q.expect_many( EventPattern('dbus-signal', interface=cs.CDO, signal='Finished'), EventPattern('dbus-signal', interface=cs.CD_IFACE_OP_LIST, signal='DispatchOperationFinished'), ) # Now there are no more active channel dispatch operations assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == []
def test(q, bus, mc): params = dbus.Dictionary( { "account": "*****@*****.**", "password": "******" }, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) abiword_fixed_properties = dbus.Dictionary( { cs.CHANNEL_TYPE_STREAM_TUBE + '.Service': 'x-abiword', cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_STREAM_TUBE, }, signature='sv') # subscribe to the OperationList interface (MC assumes that until this # property has been retrieved once, nobody cares) cd = bus.get_object(cs.CD, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] channel_properties = dbus.Dictionary(abiword_fixed_properties, signature='sv') channel_properties[cs.CHANNEL + '.TargetHandleType'] = cs.HT_CONTACT channel_properties[cs.CHANNEL + '.TargetID'] = 'juliet' channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.InitiatorID'] = 'juliet' channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.Requested'] = False channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') chan = SimulatedChannel(conn, channel_properties) chan.announce() # A channel dispatch operation is created e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') cdo_path = e.args[0] cdo_properties = e.args[1] assert cdo_properties[cs.CDO + '.Account'] == account.object_path assert cdo_properties[cs.CDO + '.Connection'] == conn.object_path assert cs.CDO + '.Interfaces' in cdo_properties handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] assert handlers == [cs.tp_name_prefix + '.Client.AbiWord'], handlers assert cs.CD_IFACE_OP_LIST in cd_props.Get(cs.CD, 'Interfaces') assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') ==\ [(cdo_path, cdo_properties)] cdo = bus.get_object(cs.CD, cdo_path) cdo_iface = dbus.Interface(cdo, cs.CDO) cdo_props_iface = dbus.Interface(cdo, cs.PROPERTIES_IFACE) assert cdo_props_iface.Get(cs.CDO, 'Interfaces') == \ cdo_properties[cs.CDO + '.Interfaces'] assert cdo_props_iface.Get(cs.CDO, 'Connection') == conn.object_path assert cdo_props_iface.Get(cs.CDO, 'Account') == account.object_path assert cdo_props_iface.Get(cs.CDO, 'Channels') == [(chan.object_path, channel_properties)] assert cdo_props_iface.Get(cs.CDO, 'PossibleHandlers') == \ cdo_properties[cs.CDO + '.PossibleHandlers'] abiword_object_path = cs.tp_path_prefix + '/Client/AbiWord' # There are no approvers so the only Handler is asked to handle the # channels # The fake AbiWord implementation is run e = q.expect( 'dbus-signal', path=cs.tp_path_prefix + '/RegressionTests', interface=cs.tp_name_prefix + '.RegressionTests', signal='FakeStartup', args=[cs.tp_name_prefix + '.Client.AbiWord'], ) # We take on its identity to be able to continue with the test abiword = SimulatedClient(q, bus, 'AbiWord', handle=[abiword_fixed_properties]) e = q.expect('dbus-method-call', path=abiword.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) # AbiWord accepts the channels q.dbus_return(e.message, signature='') # FIXME: this isn't currently emitted (part of the same bug as emitting # it as soon as HandleChannels is called) #q.expect('dbus-signal', path=cdo_path, signal='Finished') #q.expect('dbus-signal', path=cs.CD_PATH, # signal='DispatchOperationFinished', args=[cdo_path]) # Now there are no more active channel dispatch operations assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == []
def test(q, bus, mc): params = dbus.Dictionary( { "account": "*****@*****.**", "password": "******" }, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary( { cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') client = SimulatedClient(q, bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [client]) cd = bus.get_object(cs.CD, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) # chat UI calls ChannelDispatcher.EnsureChannel or CreateChannel request = dbus.Dictionary( { cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.TargetID': 'juliet', }, signature='sv') call_async( q, cd, 'CreateChannel', account.object_path, request, dbus.Int64(1234), 'grr.arg', # a valid bus name, but the wrong prefix dbus_interface=cs.CD) ret = q.expect('dbus-error', method='CreateChannel') assert ret.error.get_dbus_name() == cs.INVALID_ARGUMENT call_async( q, cd, 'CreateChannel', account.object_path, request, dbus.Int64(1234), 'can has cheeseburger?', # a totally invalid bus name dbus_interface=cs.CD) ret = q.expect('dbus-error', method='CreateChannel') assert ret.error.get_dbus_name() == cs.INVALID_ARGUMENT
def test(q, bus, mc, nickname): params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) account_iface = dbus.Interface(account, cs.ACCOUNT) account_props = dbus.Interface(account, cs.PROPERTIES_IFACE) call_async(q, account_props, 'Set', cs.ACCOUNT, 'Nickname', nickname) if nickname == '': q.expect('dbus-return', method='Set') else: q.expect_many( EventPattern('dbus-signal', path=account.object_path, signal='AccountPropertyChanged', interface=cs.ACCOUNT, args=[{'Nickname': nickname}]), EventPattern('dbus-return', method='Set'), ) assertEquals(nickname, account_props.Get(cs.ACCOUNT, 'Nickname')) # OK, let's go online expect_after_connect = [ EventPattern('dbus-method-call', interface=cs.CONN_IFACE_CONTACTS, predicate=(lambda e: e.method in ( 'GetContactAttributes', 'GetContactByID' ) and cs.CONN_IFACE_ALIASING in e.args[1]), handled=True), ] forbidden = [] if nickname == params['account'] or nickname == '': forbidden.append(EventPattern('dbus-method-call', method='SetAliases')) q.forbid_events(forbidden) if nickname == '': expect_after_connect.append(EventPattern('dbus-signal', path=account.object_path, signal='AccountPropertyChanged', interface=cs.ACCOUNT, predicate=(lambda e: e.args[0].get('Nickname') == params['account']))) else: expect_after_connect.append(EventPattern('dbus-method-call', interface=cs.CONN_IFACE_ALIASING, method='SetAliases', handled=False)) results = enable_fakecm_account(q, bus, mc, account, params, has_aliasing=True, expect_after_connect=expect_after_connect, self_ident=params['account']) conn = results[0] get_aliases = results[1] assert get_aliases.args[0] == [ conn.self_handle ] if nickname == params['account']: assertLength(2, results) elif nickname == '': assertLength(3, results) else: assertLength(3, results) set_aliases = results[2] assert set_aliases.args[0] == { conn.self_handle: nickname } q.dbus_return(set_aliases.message, signature='') if forbidden: sync_dbus(bus, q, mc) q.unforbid_events(forbidden) # Change alias after going online call_async(q, account_props, 'Set', cs.ACCOUNT, 'Nickname', 'Will Thomspon') e = q.expect('dbus-method-call', interface=cs.CONN_IFACE_ALIASING, method='SetAliases', args=[{ conn.self_handle: 'Will Thomspon' }], handled=False) # Set returns immediately; the change happens asynchronously q.expect('dbus-return', method='Set') q.dbus_return(e.message, signature='') someone_else = conn.ensure_handle(cs.HT_CONTACT, '*****@*****.**') # Another client changes our alias remotely q.dbus_emit(conn.object_path, cs.CONN_IFACE_ALIASING, 'AliasesChanged', dbus.Array([(conn.self_handle, 'wjt'), (someone_else, 'mardy')], signature='(us)'), signature='a(us)') q.expect('dbus-signal', path=account.object_path, signal='AccountPropertyChanged', interface=cs.ACCOUNT, args=[{'Nickname': 'wjt'}]) # If we set a trivial nickname while connected, MC does use it nickname = params['account'] call_async(q, account_props, 'Set', cs.ACCOUNT, 'Nickname', params['account']) _, _, e = q.expect_many( EventPattern('dbus-signal', path=account.object_path, signal='AccountPropertyChanged', interface=cs.ACCOUNT, args=[{'Nickname': params['account']}]), EventPattern('dbus-return', method='Set'), EventPattern('dbus-method-call', interface=cs.CONN_IFACE_ALIASING, method='SetAliases', args=[{ conn.self_handle: params['account'] }], handled=False) ) assertEquals(nickname, account_props.Get(cs.ACCOUNT, 'Nickname')) q.dbus_return(e.message, signature='') # Set the nickname back to something else nickname = 'wjt' call_async(q, account_props, 'Set', cs.ACCOUNT, 'Nickname', nickname) _, _, e = q.expect_many( EventPattern('dbus-signal', path=account.object_path, signal='AccountPropertyChanged', interface=cs.ACCOUNT, args=[{'Nickname': nickname}]), EventPattern('dbus-return', method='Set'), EventPattern('dbus-method-call', interface=cs.CONN_IFACE_ALIASING, method='SetAliases', args=[{ conn.self_handle: nickname }], handled=False) ) assertEquals(nickname, account_props.Get(cs.ACCOUNT, 'Nickname')) q.dbus_return(e.message, signature='') # If we set an empty nickname while connected, MC uses our normalized # name (identifier) instead. call_async(q, account_props, 'Set', cs.ACCOUNT, 'Nickname', '') _, _, e = q.expect_many( EventPattern('dbus-signal', path=account.object_path, signal='AccountPropertyChanged', interface=cs.ACCOUNT, args=[{'Nickname': params['account']}]), EventPattern('dbus-return', method='Set'), EventPattern('dbus-method-call', interface=cs.CONN_IFACE_ALIASING, method='SetAliases', args=[{ conn.self_handle: params['account'] }], handled=False) ) assertEquals(params['account'], account_props.Get(cs.ACCOUNT, 'Nickname')) q.dbus_return(e.message, signature='')
def test(q, bus, mc): params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') media_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_CALL, }, signature='sv') misc_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': 'com.example.Extension', }, signature='sv') # Two clients want to observe, approve and handle channels. Empathy handles # VoIP, Kopete does not. empathy = SimulatedClient(q, bus, 'org.gnome.Empathy', observe=[text_fixed_properties, media_fixed_properties], approve=[text_fixed_properties, media_fixed_properties], handle=[text_fixed_properties, media_fixed_properties], bypass_approval=False) kopete = SimulatedClient(q, bus, 'org.kde.Kopete', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [empathy, kopete]) # subscribe to the OperationList interface (MC assumes that until this # property has been retrieved once, nobody cares) cd = bus.get_object(cs.CD, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] # Part 1. A bundle that Empathy, but not Kopete, can handle text_channel_properties = dbus.Dictionary(text_fixed_properties, signature='sv') text_channel_properties[cs.CHANNEL + '.TargetID'] = 'juliet' text_channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') text_channel_properties[cs.CHANNEL + '.InitiatorID'] = 'juliet' text_channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') text_channel_properties[cs.CHANNEL + '.Requested'] = False text_channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array( [cs.CHANNEL_IFACE_DESTROYABLE], signature='s') text_chan = SimulatedChannel(conn, text_channel_properties, destroyable=True) media_channel_properties = dbus.Dictionary(media_fixed_properties, signature='sv') media_channel_properties[cs.CHANNEL + '.TargetID'] = 'juliet' media_channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') media_channel_properties[cs.CHANNEL + '.InitiatorID'] = 'juliet' media_channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') media_channel_properties[cs.CHANNEL + '.Requested'] = False media_channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array( signature='s') media_chan = SimulatedChannel(conn, media_channel_properties, destroyable=False) conn.NewChannels([text_chan, media_chan]) # A channel dispatch operation is created for the Text channel first. e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') text_cdo_path = e.args[0] text_cdo_properties = e.args[1] assert text_cdo_properties[cs.CDO + '.Account'] == account.object_path assert text_cdo_properties[cs.CDO + '.Connection'] == conn.object_path handlers = text_cdo_properties[cs.CDO + '.PossibleHandlers'][:] assert (sorted(handlers) == [cs.tp_name_prefix + '.Client.org.gnome.Empathy', cs.tp_name_prefix + '.Client.org.kde.Kopete']), handlers text_cdo = bus.get_object(cs.CD, text_cdo_path) text_cdo_iface = dbus.Interface(text_cdo, cs.CDO) # Both Observers are told about the new Text channel e_observe_text, k_observe_text = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), ) assert e_observe_text.args[0] == account.object_path, e_observe_text.args assert e_observe_text.args[1] == conn.object_path, e_observe_text.args assert e_observe_text.args[3] == text_cdo_path, e_observe_text.args assert e_observe_text.args[4] == [], e_observe_text.args channels = e_observe_text.args[2] assert len(channels) == 1, channels assert (text_chan.object_path, text_channel_properties) in channels assert k_observe_text.args[0] == e_observe_text.args[0], k_observe_text.args assert k_observe_text.args[1] == e_observe_text.args[1], k_observe_text.args assert (k_observe_text.args[2] == [(text_chan.object_path, text_channel_properties)]) # Now a separate CDO is created for the media channel. e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') media_cdo_path = e.args[0] media_cdo_properties = e.args[1] assert media_cdo_properties[cs.CDO + '.Account'] == account.object_path assert media_cdo_properties[cs.CDO + '.Connection'] == conn.object_path handlers = media_cdo_properties[cs.CDO + '.PossibleHandlers'][:] # only Empathy can handle it assert (sorted(handlers) == [cs.tp_name_prefix + '.Client.org.gnome.Empathy']), handlers assert cs.CD_IFACE_OP_LIST in cd_props.Get(cs.CD, 'Interfaces') assert (sorted(cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations')) == [(text_cdo_path, text_cdo_properties), (media_cdo_path, media_cdo_properties)]) media_cdo = bus.get_object(cs.CD, media_cdo_path) media_cdo_iface = dbus.Interface(media_cdo, cs.CDO) # Only Empathy is told about the new media channel e_observe_media = q.expect('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False) assert e_observe_media.args[0] == account.object_path, e_observe_media.args assert e_observe_media.args[1] == conn.object_path, e_observe_media.args assert e_observe_media.args[3] == media_cdo_path, e_observe_media.args assert e_observe_media.args[4] == [], e_observe_media.args channels = e_observe_media.args[2] assert len(channels) == 1, channels assert (media_chan.object_path, media_channel_properties) in channels # All Observers reply. q.dbus_return(e_observe_text.message, signature='') q.dbus_return(k_observe_text.message, signature='') q.dbus_return(e_observe_media.message, signature='') # The Approvers are next e_approve_text, k_approve_text, e_approve_media = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.APPROVER, method='AddDispatchOperation', predicate=lambda e: e.args[1] == text_cdo_path, handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.APPROVER, method='AddDispatchOperation', predicate=lambda e: e.args[1] == media_cdo_path, handled=False) ) assert len(e_approve_text.args[0]) == 1 assert ((text_chan.object_path, text_channel_properties) in e_approve_text.args[0]) assert e_approve_text.args[1:] == [text_cdo_path, text_cdo_properties] assert k_approve_text.args == e_approve_text.args assert len(e_approve_media.args[0]) == 1 assert ((media_chan.object_path, media_channel_properties) in e_approve_media.args[0]) assert e_approve_media.args[1:] == [media_cdo_path, media_cdo_properties] q.dbus_return(e_approve_text.message, signature='') q.dbus_return(k_approve_text.message, signature='') q.dbus_return(e_approve_media.message, signature='') # Both Approvers now have a flashing icon or something, trying to get the # user's attention. The user clicks on Empathy call_async(q, text_cdo_iface, 'HandleWith', cs.tp_name_prefix + '.Client.org.gnome.Empathy') # Empathy is asked to handle the channel e = q.expect('dbus-method-call', path=empathy.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) # Empathy accepts the channel q.dbus_return(e.message, signature='') q.expect_many( EventPattern('dbus-return', method='HandleWith'), EventPattern('dbus-signal', interface=cs.CDO, signal='Finished'), EventPattern('dbus-signal', interface=cs.CD_IFACE_OP_LIST, signal='DispatchOperationFinished'), ) # The user doesn't care which client will handle the channel - because # Empathy is the only possibility, it will be chosen (this is also a # regression test for the ability to leave the handler unspecified). call_async(q, media_cdo_iface, 'HandleWith', '') # Empathy is asked to handle the channel e = q.expect('dbus-method-call', path=empathy.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) # Empathy accepts the channel q.dbus_return(e.message, signature='') q.expect_many( EventPattern('dbus-return', method='HandleWith'), EventPattern('dbus-signal', interface=cs.CDO, signal='Finished'), EventPattern('dbus-signal', interface=cs.CD_IFACE_OP_LIST, signal='DispatchOperationFinished'), ) # Now there are no more active channel dispatch operations assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] text_chan.close() media_chan.close() # Part 2. A bundle that neither client can handle in its entirety respawning_channel_properties = dbus.Dictionary(misc_fixed_properties, signature='sv') respawning_channel_properties[cs.CHANNEL + '.TargetID'] = 'juliet' respawning_channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') respawning_channel_properties[cs.CHANNEL + '.InitiatorID'] = 'juliet' respawning_channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') respawning_channel_properties[cs.CHANNEL + '.Requested'] = False respawning_channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array( [cs.CHANNEL_IFACE_DESTROYABLE], signature='s') ext_channel_properties = dbus.Dictionary(misc_fixed_properties, signature='sv') ext_channel_properties[cs.CHANNEL + '.TargetID'] = 'juliet' ext_channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') ext_channel_properties[cs.CHANNEL + '.InitiatorID'] = 'juliet' ext_channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') ext_channel_properties[cs.CHANNEL + '.Requested'] = False ext_channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array( signature='s') text_chan = SimulatedChannel(conn, text_channel_properties, destroyable=True) media_chan = SimulatedChannel(conn, media_channel_properties, destroyable=False) respawning_chan = SimulatedChannel(conn, respawning_channel_properties, destroyable=True) ext_chan = SimulatedChannel(conn, ext_channel_properties, destroyable=False) conn.NewChannels([text_chan, media_chan, ext_chan, respawning_chan]) # No client can handle all four channels, so the bundle explodes into # two dispatch operations and two failures. We can only match the first # CDO here - we look at the others later. e_observe_media, e_observe_text, k_observe_text, \ e_approve_media, e_approve_text, k_approve_text, \ _, _, _ = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', predicate=(lambda e: e.args[2][0][0] == media_chan.object_path), handled=False), EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', predicate=(lambda e: e.args[2][0][0] == text_chan.object_path), handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.OBSERVER, method='ObserveChannels', predicate=(lambda e: e.args[2][0][0] == text_chan.object_path), handled=False), EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.APPROVER, method='AddDispatchOperation', predicate=(lambda e: e.args[0][0][0] == media_chan.object_path), handled=False), EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.APPROVER, method='AddDispatchOperation', predicate=(lambda e: e.args[0][0][0] == text_chan.object_path), handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.APPROVER, method='AddDispatchOperation', predicate=(lambda e: e.args[0][0][0] == text_chan.object_path), handled=False), EventPattern('dbus-method-call', interface=cs.CHANNEL_IFACE_DESTROYABLE, method='Destroy', path=respawning_chan.object_path, handled=True), EventPattern('dbus-method-call', interface=cs.CHANNEL, method='Close', path=ext_chan.object_path, handled=True), # we can't distinguish between the two NewDispatchOperation signals # since we no longer see the Channels property (it's mutable) EventPattern('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation'), ) q.dbus_return(e_observe_media.message, signature='') q.dbus_return(e_observe_text.message, signature='') q.dbus_return(k_observe_text.message, signature='') q.dbus_return(e_approve_media.message, signature='') q.dbus_return(e_approve_text.message, signature='') q.dbus_return(k_approve_text.message, signature='')
def test(q, bus, mc): policy_bus_name_ref = dbus.service.BusName('com.example.Policy', bus) params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, 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') # 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 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 fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': DELAYED_CTYPE, }, signature='sv') client = SimulatedClient(q, bus, 'Empathy', observe=[fixed_properties], approve=[fixed_properties], handle=[fixed_properties], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [client]) user_action_time = dbus.Int64(1238582606) cd = bus.get_object(cs.CD, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) 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')
def test(q, bus, mc): params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL + '.Type.RespawnObservers' }, signature='sv') # Logger is an activatable Observer who will crash logger_bus = dbus.bus.BusConnection() logger_bus.set_exit_on_disconnect(False) # we'll disconnect later # Kopete is an Approver, Handler and will not crash kopete_bus = dbus.bus.BusConnection() q.attach_to_bus(logger_bus) q.attach_to_bus(kopete_bus) kopete = SimulatedClient(q, kopete_bus, 'Kopete', observe=[], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [kopete]) # subscribe to the OperationList interface (MC assumes that until this # property has been retrieved once, nobody cares) cd = bus.get_object(cs.CD, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] channel_properties = dbus.Dictionary(text_fixed_properties, signature='sv') channel_properties[cs.CHANNEL + '.TargetID'] = 'juliet' channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.InitiatorID'] = 'juliet' channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.Requested'] = False channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') chan = SimulatedChannel(conn, channel_properties) chan.announce() # A channel dispatch operation is created e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') cdo_path = e.args[0] cdo_properties = e.args[1] assert cdo_properties[cs.CDO + '.Account'] == account.object_path assert cdo_properties[cs.CDO + '.Connection'] == conn.object_path assert cs.CDO + '.Interfaces' in cdo_properties handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] handlers.sort() assert handlers == [cs.tp_name_prefix + '.Client.Kopete'], handlers assert cs.CD_IFACE_OP_LIST in cd_props.Get(cs.CD, 'Interfaces') assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') ==\ [(cdo_path, cdo_properties)] cdo = bus.get_object(cs.CD, cdo_path) cdo_iface = dbus.Interface(cdo, cs.CDO) cdo_props_iface = dbus.Interface(cdo, cs.PROPERTIES_IFACE) assert cdo_props_iface.Get(cs.CDO, 'Interfaces') == \ cdo_properties[cs.CDO + '.Interfaces'] assert cdo_props_iface.Get(cs.CDO, 'Connection') == conn.object_path assert cdo_props_iface.Get(cs.CDO, 'Account') == account.object_path assert cdo_props_iface.Get(cs.CDO, 'Channels') == [(chan.object_path, channel_properties)] assert cdo_props_iface.Get(cs.CDO, 'PossibleHandlers') == \ cdo_properties[cs.CDO + '.PossibleHandlers'] k = q.expect('dbus-method-call', path=kopete.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False) assert k.args == [[(chan.object_path, channel_properties)], cdo_path, cdo_properties] q.dbus_return(k.message, bus=kopete_bus, signature='') # The fake Logger implementation is run e = q.expect('dbus-signal', path=cs.tp_path_prefix + '/RegressionTests', interface=cs.tp_name_prefix + '.RegressionTests', signal='FakeStartup', args=[cs.tp_name_prefix + '.Client.Logger'], ) # We take on its identity to be able to continue with the test logger = SimulatedClient(q, bus, 'Logger', observe=[text_fixed_properties]) # Logger is told about the new channel e = q.expect('dbus-method-call', path=logger.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False) assert e.args[0] == account.object_path, e.args assert e.args[1] == conn.object_path, e.args assert e.args[3] == cdo_path, e.args assert e.args[4] == [], e.args # no requests satisfied channels = e.args[2] assert len(channels) == 1, channels assert channels[0][0] == chan.object_path, channels assert channels[0][1] == channel_properties, channels # Logger indicates that it is ready to proceed q.dbus_return(e.message, bus=logger_bus, signature='') # The Approver (Kopete) is next # The user responds to Kopete call_async(q, cdo_iface, 'HandleWith', cs.tp_name_prefix + '.Client.Kopete') # Kopete is asked to handle the channels k = q.expect('dbus-method-call', path=kopete.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) # Kopete accepts the channels q.dbus_return(k.message, bus=kopete_bus, signature='') q.expect_many( EventPattern('dbus-return', method='HandleWith'), EventPattern('dbus-signal', interface=cs.CDO, signal='Finished'), EventPattern('dbus-signal', interface=cs.CD_IFACE_OP_LIST, signal='DispatchOperationFinished'), ) # Now there are no more active channel dispatch operations assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] # Logger crashes logger.release_name() e = q.expect('dbus-signal', signal='NameOwnerChanged', predicate=(lambda e: e.args[0] == logger.bus_name and e.args[2] == ''), ) logger_unique_name = e.args[1] logger_bus.flush() # Logger gets restart request e = q.expect('dbus-signal', path=cs.tp_path_prefix + '/RegressionTests', interface=cs.tp_name_prefix + '.RegressionTests', signal='FakeStartup', args=[cs.tp_name_prefix + '.Client.Logger'], ) # Logger gets restarted logger.reacquire_name() e = q.expect('dbus-signal', signal='NameOwnerChanged', predicate=(lambda e: e.args[0] == logger.bus_name and e.args[1] == ''), ) logger_unique_name = e.args[2] e = q.expect('dbus-method-call', path=logger.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False) # FIXME: assert the same things as before, except CDO (which we don't # have) and account path (which we don't know how to get); also check # that the recovering observer info key is set assert e.args[0] == account.object_path, e.args assert e.args[1] == conn.object_path, e.args assert e.args[4] == [], e.args # no requests satisfied assert e.args[5]['recovering'] == 1, e.args # due to observer recovery channels = e.args[2] assert len(channels) == 1, channels assert channels[0][0] == chan.object_path, channels assert channels[0][1] == channel_properties, channels # Logger indicates that it is ready to proceed q.dbus_return(e.message, bus=logger_bus, signature='') sync_dbus(bus, q, mc)
def test(q, bus, mc): params = dbus.Dictionary( { "account": "*****@*****.**", "password": "******" }, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) text_fixed_properties = dbus.Dictionary( { cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') # Two clients want to observe, approve and handle channels empathy = SimulatedClient(q, bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) kopete = SimulatedClient(q, bus, 'Kopete', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [empathy, kopete]) # Enable the account account.Set(cs.ACCOUNT, 'Enabled', True, dbus_interface=cs.PROPERTIES_IFACE) requested_presence = dbus.Struct( (dbus.UInt32(2L), dbus.String(u'available'), dbus.String(u''))) account.Set(cs.ACCOUNT, 'RequestedPresence', requested_presence, dbus_interface=cs.PROPERTIES_IFACE) e = q.expect('dbus-method-call', method='RequestConnection', args=['fakeprotocol', params], destination=cs.tp_name_prefix + '.ConnectionManager.fakecm', path=cs.tp_path_prefix + '/ConnectionManager/fakecm', interface=cs.tp_name_prefix + '.ConnectionManager', handled=False) # Don't allow the Connection to have its list of channels # until we want it to, by avoiding a return from GetAll(Requests). conn = SimulatedConnection(q, bus, 'fakecm', 'fakeprotocol', '_', 'myself', implement_get_channels=False) q.dbus_return(e.message, conn.bus_name, conn.object_path, signature='so') get_all_requests_call = q.expect('dbus-method-call', method='GetAll', args=[cs.CONN_IFACE_REQUESTS]) q.expect('dbus-method-call', method='Connect', path=conn.object_path, handled=True) conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) # subscribe to the OperationList interface (MC assumes that until this # property has been retrieved once, nobody cares) cd = bus.get_object(cs.CD, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] # Before returning from GetAll(Requests), make a Channel spring into # existence channel_properties = dbus.Dictionary(text_fixed_properties, signature='sv') channel_properties[cs.CHANNEL + '.TargetID'] = 'juliet' channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.InitiatorID'] = 'juliet' channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.Requested'] = False channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') chan = SimulatedChannel(conn, channel_properties) chan.announce() # Now reply to GetAll(Requests) conn.GetAll_Requests(get_all_requests_call) # A channel dispatch operation is created for the channel we already had e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') cdo_path = e.args[0] cdo_properties = e.args[1] assert cdo_properties[cs.CDO + '.Account'] == account.object_path assert cdo_properties[cs.CDO + '.Connection'] == conn.object_path handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] handlers.sort() assert handlers == [ cs.tp_name_prefix + '.Client.Empathy', cs.tp_name_prefix + '.Client.Kopete' ], handlers assert cs.CD_IFACE_OP_LIST in cd_props.Get(cs.CD, 'Interfaces') assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') ==\ [(cdo_path, cdo_properties)] cdo = bus.get_object(cs.CD, cdo_path) cdo_iface = dbus.Interface(cdo, cs.CDO) # Both Observers are told about the new channel e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), ) assert e.args[0] == account.object_path, e.args assert e.args[1] == conn.object_path, e.args assert e.args[3] == cdo_path, e.args assert e.args[4] == [], e.args # no requests satisfied channels = e.args[2] assert len(channels) == 1, channels assert channels[0][0] == chan.object_path, channels assert channels[0][1] == channel_properties, channels assert k.args == e.args # Both Observers indicate that they are ready to proceed q.dbus_return(k.message, signature='') q.dbus_return(e.message, signature='') # The Approvers are next e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), ) assert e.args == [[(chan.object_path, channel_properties)], cdo_path, cdo_properties] assert k.args == e.args q.dbus_return(e.message, signature='') q.dbus_return(k.message, signature='') # Both Approvers now have a flashing icon or something, trying to get the # user's attention # The user responds to Empathy first call_async(q, cdo_iface, 'HandleWith', cs.tp_name_prefix + '.Client.Empathy') # Empathy is asked to handle the channels e = q.expect('dbus-method-call', path=empathy.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) # Empathy accepts the channels q.dbus_return(e.message, signature='') q.expect_many( EventPattern('dbus-return', method='HandleWith'), EventPattern('dbus-signal', interface=cs.CDO, signal='Finished'), EventPattern('dbus-signal', interface=cs.CD_IFACE_OP_LIST, signal='DispatchOperationFinished'), ) # Now there are no more active channel dispatch operations assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == []
def test(q, bus, mc): params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') # Empathy is an observer for text channels with # DelayApprovers=TRUE. empathy = SimulatedClient(q, bus, 'Empathy', observe=[text_fixed_properties], approve=[], handle=[], delay_approvers=True) # Loggy is an observer for text channels with # DelayApprovers=FALSE. loggy = SimulatedClient(q, bus, 'Loggy', observe=[text_fixed_properties], approve=[], handle=[], delay_approvers=False) # Kopete is an approver and handler for text channels. kopete = SimulatedClient(q, bus, 'Kopete', observe=[], approve=[text_fixed_properties], handle=[text_fixed_properties]) expect_client_setup(q, [empathy, loggy, kopete]) # subscribe to the OperationList interface (MC assumes that until this # property has been retrieved once, nobody cares) cd = bus.get_object(cs.CD, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] # A text channel appears! channel_properties = dbus.Dictionary(text_fixed_properties, signature='sv') channel_properties[cs.CHANNEL + '.TargetID'] = 'juliet' channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.InitiatorID'] = 'juliet' channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.Requested'] = False channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') chan = SimulatedChannel(conn, channel_properties) chan.announce() e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') cdo_path = e.args[0] cdo = bus.get_object(cs.CD, cdo_path) cdo_iface = dbus.Interface(cdo, cs.CDO) cdo_props_iface = dbus.Interface(cdo, cs.PROPERTIES_IFACE) # Empathy, the observer, gets the channel to observe. Because it # has DelayApprovers=TRUE, Kopete should not have # AddDispatchOperation called on it until Empathy returns from # ObserveChannels. Because Loggy has DelayApprovers=False, # however, ADO can be called on Kopete before Loggy returns, but # again, only after Empathy returns. forbidden = [EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.APPROVER, method='AddDispatchOperation')] q.forbid_events(forbidden) e, l = q.expect_many(EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), EventPattern('dbus-method-call', path=loggy.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), ) # Waste a little time here and there. We can't call sync_dbus # here because it calls Ping and libdbus returns from Ping # synchronously and doesn't turn the main loop handle enough. call_async(q, cd_props, 'Get', cs.CD_IFACE_OP_LIST, 'DispatchOperations') event = q.expect('dbus-return', method='Get') # Finally return from ObserveChannels from Empathy, so now we # expect ADO to be called on Kopete. q.dbus_return(e.message, bus=bus, signature='') q.unforbid_events(forbidden) e = q.expect('dbus-method-call', path=kopete.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False) q.dbus_return(e.message, bus=bus, signature='') # Return from loggy's ObserveChannels. q.dbus_return(l.message, bus=bus, signature='') # The user responds to Kopete call_async(q, cdo_iface, 'HandleWith', cs.tp_name_prefix + '.Client.Kopete') # Kopete is asked to handle the channels k = q.expect('dbus-method-call', path=kopete.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) # Kopete accepts the channels q.dbus_return(k.message, bus=bus, signature='') q.expect_many( EventPattern('dbus-return', method='HandleWith'), EventPattern('dbus-signal', interface=cs.CDO, signal='Finished'), EventPattern('dbus-signal', interface=cs.CD_IFACE_OP_LIST, signal='DispatchOperationFinished'), ) # Now there are no more active channel dispatch operations assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == []
def test(q, bus, mc): # Two clients want to handle channels: MediaCall is running, and AbiWord # is activatable. # this must match the .client file abi_contact_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_STREAM_TUBE, cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL_TYPE_STREAM_TUBE + '.Service': 'x-abiword', }, signature='sv') abi_room_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_STREAM_TUBE, cs.CHANNEL + '.TargetHandleType': cs.HT_ROOM, cs.CHANNEL_TYPE_STREAM_TUBE + '.Service': 'x-abiword', }, signature='sv') media_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_CALL, }, signature='sv') media_call = SimulatedClient(q, bus, 'MediaCall', observe=[], approve=[], handle=[media_fixed_properties], cap_tokens=[cs.CHANNEL_TYPE_CALL + '/ice', cs.CHANNEL_TYPE_CALL + '/audio/speex', cs.CHANNEL_TYPE_CALL + '/video/theora'], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [media_call]) def check_contact_caps(e): structs = e.args[0] filters = {} tokens = {} assert len(structs) == 3 for struct in structs: assert struct[0] not in filters filters[struct[0]] = sorted(struct[1]) tokens[struct[0]] = sorted(struct[2]) assert media_fixed_properties in filters[cs.CLIENT + '.MediaCall'] assert len(filters[cs.CLIENT + '.MediaCall']) == 1 assert abi_room_fixed_properties in filters[cs.CLIENT + '.AbiWord'] assert abi_contact_fixed_properties in filters[cs.CLIENT + '.AbiWord'] assert len(filters[cs.CLIENT + '.AbiWord']) == 2 assert len(tokens[cs.CLIENT + '.MediaCall']) == 3 assert cs.CHANNEL_TYPE_CALL + '/ice' in \ tokens[cs.CLIENT + '.MediaCall'] assert cs.CHANNEL_TYPE_CALL + '/audio/speex' in \ tokens[cs.CLIENT + '.MediaCall'] assert cs.CHANNEL_TYPE_CALL + '/video/theora' in \ tokens[cs.CLIENT + '.MediaCall'] assert len(tokens[cs.CLIENT + '.AbiWord']) == 2 assert 'com.example.Foo' in tokens[cs.CLIENT + '.AbiWord'] assert 'com.example.Bar' in tokens[cs.CLIENT + '.AbiWord'] return True params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn, before = enable_fakecm_account(q, bus, mc, account, params, extra_interfaces=[cs.CONN_IFACE_CONTACT_CAPS], expect_before_connect=[ EventPattern('dbus-method-call', handled=False, interface=cs.CONN_IFACE_CONTACT_CAPS, method='UpdateCapabilities', predicate=check_contact_caps), ]) q.dbus_return(before.message, signature='') irssi_bus = dbus.bus.BusConnection() irssi_bus.set_exit_on_disconnect(False) # we'll disconnect later q.attach_to_bus(irssi_bus) irssi_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, cs.CHANNEL + '.TargetHandleType': cs.HT_ROOM, }, signature='sv') irssi = SimulatedClient(q, irssi_bus, 'Irssi', observe=[], approve=[], handle=[irssi_fixed_properties], cap_tokens=[], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [irssi]) e = q.expect('dbus-method-call', handled=False, interface=cs.CONN_IFACE_CONTACT_CAPS, method='UpdateCapabilities') assert len(e.args[0]) == 1 struct = e.args[0][0] assert struct[0] == cs.CLIENT + '.Irssi' assert struct[1] == [irssi_fixed_properties] assert struct[2] == [] # When Irssi exits, the CM is told it has gone irssi.release_name() del irssi irssi_bus.flush() irssi_bus.close() e = q.expect('dbus-method-call', handled=False, interface=cs.CONN_IFACE_CONTACT_CAPS, method='UpdateCapabilities') assert len(e.args[0]) == 1 struct = e.args[0][0] assert struct[0] == cs.CLIENT + '.Irssi' assert struct[1] == [] assert struct[2] == []
def test(q, bus, mc): # Because the channels are handled by another process, we should never be # asked to approve or handle them. forbidden = [ EventPattern('dbus-method-call', method='HandleChannels'), EventPattern('dbus-method-call', method='AddDispatchOperation'), ] q.forbid_events(forbidden) params = dbus.Dictionary( { "account": "*****@*****.**", "password": "******" }, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary( { cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') empathy = SimulatedClient(q, bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) kopete = SimulatedClient(q, bus, 'Kopete', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) expect_client_setup(q, [empathy, kopete]) # a non-MC-using client goes behind our back to call CreateChannel or # EnsureChannel on the Connection directly # # (This is not simulated here: we just behave as though it had happened) channel_immutable = dbus.Dictionary(text_fixed_properties) 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, 'juliet') channel_immutable[cs.CHANNEL + '.TargetID'] = 'juliet' channel = SimulatedChannel(conn, channel_immutable) channel.announce() # Observer should get told, processing waits for it e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), ) 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] == [], 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 == k.args # Observers say "OK, go" q.dbus_return(k.message, signature='') q.dbus_return(e.message, signature='') sync_dbus(bus, q, mc)
def test(q, bus, mc): params = dbus.Dictionary( { "account": "*****@*****.**", "password": "******" }, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary( { cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') # Throughout this entire test, we should never be asked to approve or # handle a channel. forbidden = [ EventPattern('dbus-method-call', method='AddDispatchOperation'), EventPattern('dbus-method-call', method='HandleChannels'), ] q.forbid_events(forbidden) # Two clients want to observe, approve and handle channels empathy = SimulatedClient(q, bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) kopete = SimulatedClient(q, bus, 'Kopete', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [empathy, kopete]) # subscribe to the OperationList interface (MC assumes that until this # property has been retrieved once, nobody cares) cd = bus.get_object(cs.CD, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] # This ID is special-cased by the mcp-plugin plugin, which rejects # channels to or from it by destroying them, without waiting for observers # to return target = '*****@*****.**' channel_properties = dbus.Dictionary(text_fixed_properties, signature='sv') channel_properties[cs.CHANNEL + '.TargetID'] = target channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, target) channel_properties[cs.CHANNEL + '.InitiatorID'] = target channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, target) channel_properties[cs.CHANNEL + '.Requested'] = False channel_properties[cs.CHANNEL + '.Interfaces'] = \ dbus.Array([cs.CHANNEL_IFACE_DESTROYABLE, cs.CHANNEL_IFACE_GROUP, ],signature='s') chan = SimulatedChannel(conn, channel_properties, group=True) chan.announce() # A channel dispatch operation is created e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') cdo_path = e.args[0] cdo_properties = e.args[1] assert cdo_properties[cs.CDO + '.Account'] == account.object_path assert cdo_properties[cs.CDO + '.Connection'] == conn.object_path assert cs.CDO + '.Interfaces' in cdo_properties handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] handlers.sort() assert handlers == [ cs.tp_name_prefix + '.Client.Empathy', cs.tp_name_prefix + '.Client.Kopete' ], handlers # The plugin realises we've been rickrolled, and responds. It calls Destroy # even though neither Empathy nor Kopete has returned from ObserveChannels # yet destruction, e, k = q.expect_many( EventPattern('dbus-method-call', path=chan.object_path, interface=cs.CHANNEL_IFACE_DESTROYABLE, method='Destroy', args=[], handled=False), EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), ) # treat the destruction like Close chan.Close(destruction) # Both Observers indicate that they are ready to proceed (somewhat late) q.dbus_return(k.message, signature='') q.dbus_return(e.message, signature='') # When the Observers have returned, the CDO finishes q.expect_many( EventPattern('dbus-signal', path=cdo_path, interface=cs.CDO, signal='Finished'), EventPattern('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='DispatchOperationFinished', args=[cdo_path]), ) # This ID is also special-cased target = '*****@*****.**' channel_properties = dbus.Dictionary(text_fixed_properties, signature='sv') channel_properties[cs.CHANNEL + '.TargetID'] = target channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, target) channel_properties[cs.CHANNEL + '.InitiatorID'] = target channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, target) channel_properties[cs.CHANNEL + '.Requested'] = False channel_properties[cs.CHANNEL + '.Interfaces'] = \ dbus.Array([cs.CHANNEL_IFACE_DESTROYABLE, cs.CHANNEL_IFACE_GROUP, ],signature='s') chan = SimulatedChannel(conn, channel_properties, group=True) chan.announce() # A channel dispatch operation is created e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') cdo_path = e.args[0] cdo_properties = e.args[1] assert cdo_properties[cs.CDO + '.Account'] == account.object_path assert cdo_properties[cs.CDO + '.Connection'] == conn.object_path assert cs.CDO + '.Interfaces' in cdo_properties handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] handlers.sort() assert handlers == [ cs.tp_name_prefix + '.Client.Empathy', cs.tp_name_prefix + '.Client.Kopete' ], handlers # The plugin realises it's MC Hammer, and responds, but its response waits # for the observers to return e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), ) sync_dbus(bus, q, account) # Both Observers indicate that they are ready to proceed q.dbus_return(k.message, signature='') q.dbus_return(e.message, signature='') _, _, e = q.expect_many( EventPattern('dbus-signal', path=cdo_path, interface=cs.CDO, signal='Finished'), EventPattern('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='DispatchOperationFinished', args=[cdo_path]), EventPattern('dbus-method-call', path=chan.object_path, interface=cs.CHANNEL_IFACE_DESTROYABLE, method='Destroy', handled=False), ) q.dbus_return(e.message, signature='') chan.close()
def test(q, bus, mc): accounts_dir = os.environ['MC_ACCOUNT_DIR'] try: os.mkdir(accounts_dir, 0700) except OSError: pass empty_key_file_name = os.path.join(os.environ['XDG_DATA_HOME'], 'telepathy', 'mission-control', 'accounts.cfg') group = 'fakecm/fakeprotocol/someguy_40example_2ecom0' account_manager, properties, interfaces = connect_to_mc(q, bus, mc) assert properties.get('ValidAccounts') == [], \ properties.get('ValidAccounts') assert properties.get('InvalidAccounts') == [], \ properties.get('InvalidAccounts') params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) account_path = account.__dbus_object_path__ # Check the account is correctly created properties = account_manager.GetAll(cs.AM, dbus_interface=cs.PROPERTIES_IFACE) assert properties is not None assert properties.get('ValidAccounts') == [account_path], properties account_path = properties['ValidAccounts'][0] assert isinstance(account_path, dbus.ObjectPath), repr(account_path) assert properties.get('InvalidAccounts') == [], properties account_iface = dbus.Interface(account, cs.ACCOUNT) account_props = dbus.Interface(account, cs.PROPERTIES_IFACE) # Alter some miscellaneous r/w properties account_props.Set(cs.ACCOUNT, 'Icon', 'im-jabber') account_props.Set(cs.ACCOUNT, 'DisplayName', 'Work account') account_props.Set(cs.ACCOUNT, 'Nickname', 'Joe Bloggs') tell_mc_to_die(q, bus) # .. let's check the diverted keyfile kf = read_account_keyfile() assert group in kf, kf assert kf[group]['manager'] == 'fakecm' assert kf[group]['protocol'] == 'fakeprotocol' assert kf[group]['param-account'] == params['account'], kf assert kf[group]['param-password'] == params['password'], kf assert kf[group]['DisplayName'] == 'Work account', kf assert kf[group]['Icon'] == 'im-jabber', kf assert kf[group]['Nickname'] == 'Joe Bloggs', kf # Reactivate MC account_manager, properties, interfaces = resuscitate_mc(q, bus, mc) account = get_fakecm_account(bus, mc, account_path) account_iface = dbus.Interface(account, cs.ACCOUNT) # Delete the account assert account_iface.Remove() is None account_event, account_manager_event = q.expect_many( EventPattern('dbus-signal', path=account_path, signal='Removed', interface=cs.ACCOUNT, args=[] ), EventPattern('dbus-signal', path=cs.AM_PATH, signal='AccountRemoved', interface=cs.AM, args=[account_path] ), ) # Check the account is correctly deleted kf = read_account_keyfile() assert group not in kf, kf
def test(q, bus, mc): params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') client = SimulatedClient(q, bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) # No Approver should be invoked at any point during this test, because the # Channel was Requested def fail_on_approval(e): raise AssertionError('Approver should not be invoked') q.add_dbus_method_impl(fail_on_approval, path=client.object_path, interface=cs.APPROVER, method='AddDispatchOperation') # wait for MC to download the properties expect_client_setup(q, [client]) user_action_time = dbus.Int64(1238582606) # chat UI calls ChannelDispatcher.CreateChannel cd = ChannelDispatcher(bus) request = dbus.Dictionary({ cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.TargetID': 'juliet', }, signature='sv') request_path = cd.CreateChannel(account.object_path, request, user_action_time, client.bus_name) add_request = q.expect('dbus-method-call', handled=False, interface=cs.CLIENT_IFACE_REQUESTS, method='AddRequest', path=client.object_path) assert add_request.args[0] == request_path q.dbus_return(add_request.message, signature='') cr = bus.get_object(cs.CD, 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 # chat UI connects to signals and calls ChannelRequest.Proceed() cr.Proceed() cm_request_call = q.expect('dbus-method-call', interface=cs.CONN_IFACE_REQUESTS, method='CreateChannel', path=conn.object_path, args=[request], handled=False) # Actually, never mind. cr.Cancel() # 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, 'juliet') channel = SimulatedChannel(conn, channel_immutable) # this order of events is guaranteed by telepathy-spec (since 0.17.14) q.dbus_return(cm_request_call.message, channel.object_path, channel.immutable, signature='oa{sv}') channel.announce() # Channel is unwanted now, MC stabs it in the face stdsig, _ = q.expect_many( EventPattern('dbus-signal', path=request_path, interface=cs.CR, signal='Failed'), EventPattern('dbus-method-call', path=channel.object_path, interface=cs.CHANNEL, method='Close', handled=True), )
def test(q, bus, mc): params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') vague_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') empathy_bus = dbus.bus.BusConnection() q.attach_to_bus(empathy_bus) empathy = SimulatedClient(q, empathy_bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) # Kopete's filter is less specific than Empathy's, so we'll prefer Empathy kopete_bus = dbus.bus.BusConnection() q.attach_to_bus(kopete_bus) kopete = SimulatedClient(q, kopete_bus, 'Kopete', observe=[], approve=[], handle=[vague_fixed_properties], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [empathy, kopete]) # subscribe to the OperationList interface (MC assumes that until this # property has been retrieved once, nobody cares) cd = bus.get_object(cs.CD, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] channel_properties = dbus.Dictionary(text_fixed_properties, signature='sv') channel_properties[cs.CHANNEL + '.TargetID'] = 'juliet' channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.InitiatorID'] = 'juliet' channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.Requested'] = False channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') chan = SimulatedChannel(conn, channel_properties) chan.announce() # A channel dispatch operation is created e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') cdo_path = e.args[0] cdo_properties = e.args[1] assert cdo_properties[cs.CDO + '.Account'] == account.object_path assert cdo_properties[cs.CDO + '.Connection'] == conn.object_path assert cs.CDO + '.Interfaces' in cdo_properties # In this test Empathy's filter has more things in it than Kopete's, so # MC will prefer Empathy handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] assert handlers == [cs.tp_name_prefix + '.Client.Empathy', cs.tp_name_prefix + '.Client.Kopete'], handlers assert cs.CD_IFACE_OP_LIST in cd_props.Get(cs.CD, 'Interfaces') assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') ==\ [(cdo_path, cdo_properties)] cdo = bus.get_object(cs.CD, cdo_path) cdo_iface = dbus.Interface(cdo, cs.CDO) cdo_props_iface = dbus.Interface(cdo, cs.PROPERTIES_IFACE) assert cdo_props_iface.Get(cs.CDO, 'Interfaces') == \ cdo_properties[cs.CDO + '.Interfaces'] assert cdo_props_iface.Get(cs.CDO, 'Connection') == conn.object_path assert cdo_props_iface.Get(cs.CDO, 'Account') == account.object_path assert cdo_props_iface.Get(cs.CDO, 'Channels') == [(chan.object_path, channel_properties)] assert cdo_props_iface.Get(cs.CDO, 'PossibleHandlers') == \ cdo_properties[cs.CDO + '.PossibleHandlers'] e = q.expect('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False) assert e.args[0] == account.object_path, e.args assert e.args[1] == conn.object_path, e.args assert e.args[3] == cdo_path, e.args assert e.args[4] == [], e.args # no requests satisfied channels = e.args[2] assert len(channels) == 1, channels assert channels[0][0] == chan.object_path, channels assert channels[0][1] == channel_properties, channels q.dbus_return(e.message, bus=empathy_bus, signature='') e = q.expect('dbus-method-call', path=empathy.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False) assert e.args == [[(chan.object_path, channel_properties)], cdo_path, cdo_properties] q.dbus_return(e.message, bus=empathy_bus, signature='') call_async(q, cdo_iface, 'HandleWith', cs.tp_name_prefix + '.Client.Empathy') # Empathy is asked to handle the channels e = q.expect('dbus-method-call', path=empathy.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) # Empathy rejects the channels q.dbus_raise(e.message, cs.NOT_AVAILABLE, 'Blind drunk', bus=empathy_bus) e = q.expect('dbus-error', method='HandleWith') assert e.error.get_dbus_name() == cs.NOT_AVAILABLE assert e.error.get_dbus_message() == 'Blind drunk' # The channels no longer count as having been approved. Check that MC # doesn't carry on regardless forbidden = [EventPattern('dbus-method-call', method='HandleChannels')] q.forbid_events(forbidden) sync_dbus(bus, q, mc) q.unforbid_events(forbidden) # I'm Feeling Lucky. It might work if I try again? Maybe? call_async(q, cdo_iface, 'HandleWith', cs.tp_name_prefix + '.Client.Empathy') # Empathy is asked to handle the channels, again e = q.expect('dbus-method-call', path=empathy.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) # Empathy rejects the channels, again q.dbus_raise(e.message, cs.NOT_CAPABLE, 'Still drunk', bus=empathy_bus) e = q.expect('dbus-error', method='HandleWith') assert e.error.get_dbus_name() == cs.NOT_CAPABLE assert e.error.get_dbus_message() == 'Still drunk' # OK, OK, is anyone else competent enough to handle them? # (Also, assert that MC doesn't offer them back to Empathy, knowing that # it already tried and failed) forbidden = [EventPattern('dbus-method-call', method='HandleChannels', path=empathy.object_path)] q.forbid_events(forbidden) call_async(q, cdo_iface, 'HandleWith', '') # Kopete is asked to handle the channels k = q.expect('dbus-method-call', path=kopete.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) # Kopete rejects the channels too q.dbus_raise(k.message, cs.NOT_AVAILABLE, 'Also blind drunk', bus=kopete_bus) e = q.expect('dbus-error', method='HandleWith') assert e.error.get_dbus_name() == cs.NOT_AVAILABLE assert e.error.get_dbus_message() == 'Also blind drunk' # MC gives up and closes the channel. This is the end of the CDO. q.expect_many( EventPattern('dbus-method-call', path=chan.object_path, interface=cs.CHANNEL, method='Close', args=[]), EventPattern('dbus-signal', interface=cs.CDO, signal='Finished'), EventPattern('dbus-signal', interface=cs.CD_IFACE_OP_LIST, signal='DispatchOperationFinished'), ) # Now there are no more active channel dispatch operations assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == []
def test(q, bus, mc): params = dbus.Dictionary( { "account": "*****@*****.**", "password": "******" }, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary( { cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') # Empathy is an Observers who will crash empathy_bus = dbus.bus.BusConnection() empathy_bus.set_exit_on_disconnect(False) # we'll disconnect later # Kopete is an Approver, Handler and will not crash kopete_bus = dbus.bus.BusConnection() q.attach_to_bus(empathy_bus) q.attach_to_bus(kopete_bus) # Two clients want to observe, approve and handle channels empathy = SimulatedClient(q, empathy_bus, 'Empathy', observe=[text_fixed_properties], approve=[], handle=[], wants_recovery=True) kopete = SimulatedClient(q, kopete_bus, 'Kopete', observe=[], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [empathy, kopete]) # subscribe to the OperationList interface (MC assumes that until this # property has been retrieved once, nobody cares) cd = bus.get_object(cs.CD, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] channel_properties = dbus.Dictionary(text_fixed_properties, signature='sv') channel_properties[cs.CHANNEL + '.TargetID'] = 'juliet' channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.InitiatorID'] = 'juliet' channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.Requested'] = False channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') chan = SimulatedChannel(conn, channel_properties) chan.announce() # A channel dispatch operation is created e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') cdo_path = e.args[0] cdo_properties = e.args[1] assert cdo_properties[cs.CDO + '.Account'] == account.object_path assert cdo_properties[cs.CDO + '.Connection'] == conn.object_path assert cs.CDO + '.Interfaces' in cdo_properties handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] handlers.sort() assert handlers == [cs.tp_name_prefix + '.Client.Kopete'], handlers assert cs.CD_IFACE_OP_LIST in cd_props.Get(cs.CD, 'Interfaces') assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') ==\ [(cdo_path, cdo_properties)] cdo = bus.get_object(cs.CD, cdo_path) cdo_iface = dbus.Interface(cdo, cs.CDO) cdo_props_iface = dbus.Interface(cdo, cs.PROPERTIES_IFACE) assert cdo_props_iface.Get(cs.CDO, 'Interfaces') == \ cdo_properties[cs.CDO + '.Interfaces'] assert cdo_props_iface.Get(cs.CDO, 'Connection') == conn.object_path assert cdo_props_iface.Get(cs.CDO, 'Account') == account.object_path assert cdo_props_iface.Get(cs.CDO, 'Channels') == [(chan.object_path, channel_properties)] assert cdo_props_iface.Get(cs.CDO, 'PossibleHandlers') == \ cdo_properties[cs.CDO + '.PossibleHandlers'] # The Observer (Empathy) is told about the new channel e = q.expect('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False) assert e.args[0] == account.object_path, e.args assert e.args[1] == conn.object_path, e.args assert e.args[3] == cdo_path, e.args assert e.args[4] == [], e.args # no requests satisfied channels = e.args[2] assert len(channels) == 1, channels assert channels[0][0] == chan.object_path, channels assert channels[0][1] == channel_properties, channels # Empathy indicates that it is ready to proceed q.dbus_return(e.message, bus=empathy_bus, signature='') # The Approver (Kopete) is next k = q.expect('dbus-method-call', path=kopete.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False) assert k.args == [[(chan.object_path, channel_properties)], cdo_path, cdo_properties] q.dbus_return(k.message, bus=kopete_bus, signature='') # The user responds to Kopete call_async(q, cdo_iface, 'HandleWith', cs.tp_name_prefix + '.Client.Kopete') # Kopete is asked to handle the channels k = q.expect('dbus-method-call', path=kopete.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) # Kopete accepts the channels q.dbus_return(k.message, bus=kopete_bus, signature='') q.expect_many( EventPattern('dbus-return', method='HandleWith'), EventPattern('dbus-signal', interface=cs.CDO, signal='Finished'), EventPattern('dbus-signal', interface=cs.CD_IFACE_OP_LIST, signal='DispatchOperationFinished'), ) # Now there are no more active channel dispatch operations assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] # Another channel: this one will remain unapproved channel2_properties = dbus.Dictionary(text_fixed_properties, signature='sv') channel2_properties[cs.CHANNEL + '.TargetID'] = 'mercutio' channel2_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'mercutio') channel2_properties[cs.CHANNEL + '.InitiatorID'] = 'mercutio' channel2_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'mercutio') channel2_properties[cs.CHANNEL + '.Requested'] = False channel2_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') chan2 = SimulatedChannel(conn, channel2_properties) chan2.announce() # A channel dispatch operation is created e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') cdo2_path = e.args[0] cdo2_properties = e.args[1] assert cdo2_properties[cs.CDO + '.Account'] == account.object_path assert cdo2_properties[cs.CDO + '.Connection'] == conn.object_path assert cs.CDO + '.Interfaces' in cdo_properties handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] handlers.sort() assert handlers == [cs.tp_name_prefix + '.Client.Kopete'], handlers assert cs.CD_IFACE_OP_LIST in cd_props.Get(cs.CD, 'Interfaces') assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') ==\ [(cdo2_path, cdo2_properties)] cdo2 = bus.get_object(cs.CD, cdo2_path) cdo2_iface = dbus.Interface(cdo2, cs.CDO) cdo2_props_iface = dbus.Interface(cdo2, cs.PROPERTIES_IFACE) assert cdo2_props_iface.Get(cs.CDO, 'Interfaces') == \ cdo2_properties[cs.CDO + '.Interfaces'] assert cdo2_props_iface.Get(cs.CDO, 'Connection') == conn.object_path assert cdo2_props_iface.Get(cs.CDO, 'Account') == account.object_path assert cdo2_props_iface.Get(cs.CDO, 'Channels') == [(chan2.object_path, channel2_properties)] assert cdo2_props_iface.Get(cs.CDO, 'PossibleHandlers') == \ cdo2_properties[cs.CDO + '.PossibleHandlers'] # The Observer (Empathy) is told about the new channel e = q.expect('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False) assert e.args[0] == account.object_path, e.args assert e.args[1] == conn.object_path, e.args assert e.args[3] == cdo2_path, e.args assert e.args[4] == [], e.args # no requests satisfied channels = e.args[2] assert len(channels) == 1, channels assert channels[0][0] == chan2.object_path, channels assert channels[0][1] == channel2_properties, channels # Empathy indicates that it is ready to proceed q.dbus_return(e.message, bus=empathy_bus, signature='') # The Approver (Kopete) is next; this time, we don't approve k = q.expect('dbus-method-call', path=kopete.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False) assert k.args == [[(chan2.object_path, channel2_properties)], cdo2_path, cdo2_properties] q.dbus_return(k.message, bus=kopete_bus, signature='') # Empathy crashes empathy.release_name() e = q.expect( 'dbus-signal', signal='NameOwnerChanged', predicate=( lambda e: e.args[0] == empathy.bus_name and e.args[2] == ''), ) empathy_unique_name = e.args[1] empathy_bus.flush() # Empathy gets restarted empathy.reacquire_name() e = q.expect( 'dbus-signal', signal='NameOwnerChanged', predicate=( lambda e: e.args[0] == empathy.bus_name and e.args[1] == ''), ) empathy_unique_name = e.args[2] e1, e2 = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', predicate=lambda e: e.args[2][0][0] == chan.object_path, handled=False), EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', predicate=lambda e: e.args[2][0][0] == chan2.object_path, handled=False), ) assert e1.args[0] == account.object_path, e1.args assert e1.args[1] == conn.object_path, e1.args assert e1.args[4] == [], e1.args # no requests satisfied assert e1.args[5]['recovering'] == 1, e1.args # due to observer recovery channels = e1.args[2] assert len(channels) == 1, channels assert channels[0][0] == chan.object_path, channels assert channels[0][1] == channel_properties, channels assert e2.args[0] == account.object_path, e2.args assert e2.args[1] == conn.object_path, e2.args assert e2.args[4] == [], e2.args # no requests satisfied assert e2.args[5]['recovering'] == 1, e2.args # due to observer recovery channels = e2.args[2] assert len(channels) == 1, channels assert channels[0][0] == chan2.object_path, channels assert channels[0][1] == channel2_properties, channels # Empathy indicates that it is ready to proceed q.dbus_return(e1.message, bus=empathy_bus, signature='') q.dbus_return(e2.message, bus=empathy_bus, signature='') sync_dbus(bus, q, mc)
def test(q, bus, mc): params = dbus.Dictionary( { "account": "*****@*****.**", "password": "******" }, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary( { cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, }, signature='sv') # subscribe to the OperationList interface (MC assumes that until this # property has been retrieved once, nobody cares) cd = bus.get_object(cs.CD, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] client = SimulatedClient(q, bus, 'Client', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [client]) channel_properties = dbus.Dictionary(text_fixed_properties, signature='sv') channel_properties[cs.CHANNEL + '.TargetID'] = 'juliet' channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.InitiatorID'] = 'juliet' channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.Requested'] = False channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') forbidden = [ EventPattern('dbus-method-call', method='AddDispatchOperation'), ] q.forbid_events(forbidden) chan = SimulatedChannel(conn, channel_properties) chan.announce() e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') cdo_path = e.args[0] cdo_properties = e.args[1] assert cdo_properties[cs.CDO + '.Account'] == account.object_path assert cdo_properties[cs.CDO + '.Connection'] == conn.object_path assert cs.CDO + '.Interfaces' in cdo_properties handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] assertEquals([], handlers) e = q.expect('dbus-method-call', path=client.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False) sync_dbus(bus, q, mc) q.dbus_return(e.message, signature='') # now (but only now) MC kills the channel q.expect_many( EventPattern('dbus-signal', path=cdo_path, signal='Finished'), EventPattern('dbus-method-call', path=chan.object_path, method='Close', handled=True), ) # There are no active channel dispatch operations assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == []
def test(q, bus, mc): params = dbus.Dictionary({ "account": "brucewayne", "password": "******" }, signature='sv') (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) account_iface = dbus.Interface(account, cs.ACCOUNT) account_props = dbus.Interface(account, cs.PROPERTIES_IFACE) call_async(q, account_props, 'Set', cs.ACCOUNT, 'Nickname', "BruceWayne") q.expect_many( EventPattern('dbus-signal', path=account.object_path, signal='AccountPropertyChanged', interface=cs.ACCOUNT, args=[{ 'Nickname': "BruceWayne" }]), EventPattern('dbus-return', method='Set'), ) assertEquals("BruceWayne", account_props.Get(cs.ACCOUNT, 'Nickname')) expect_after_connect = [ EventPattern('dbus-method-call', interface=cs.CONN_IFACE_CONTACTS, predicate=(lambda e: e.method in ('GetContactAttributes', 'GetContactByID' ) and cs.CONN_IFACE_ALIASING in e.args[1]), handled=True), EventPattern('dbus-method-call', interface=cs.CONN_IFACE_ALIASING, method='SetAliases', handled=False), EventPattern('dbus-signal', interface=cs.ACCOUNT, predicate=lambda e: e.args[0].get('CurrentPresence') == (cs.PRESENCE_UNSET, '', '')), ] conn, get_aliases, set_aliases, _ = enable_fakecm_account( q, bus, mc, account, params, has_aliasing=True, expect_after_connect=expect_after_connect, self_ident=params['account']) assert get_aliases.args[0] == [conn.self_handle] assert set_aliases.args[0] == {conn.self_handle: 'BruceWayne'} q.dbus_return(set_aliases.message, signature='') # FIXME: fd.o #55666 in telepathy-glib breaks the rest of this test. # Reinstate it when we depend on a version that has that fixed. return # Another client changes our alias remotely, but because this is IRC, # that manifests itself as a handle change conn.change_self_ident('thebatman') conn.change_self_alias('TheBatman') get_aliases, _ = q.expect_many( EventPattern('dbus-method-call', interface=cs.CONN_IFACE_CONTACTS, predicate=(lambda e: e.method in ('GetContactAttributes', 'GetContactByID' ) and cs.CONN_IFACE_ALIASING in e.args[1]), handled=True), EventPattern( 'dbus-signal', path=account.object_path, signal='AccountPropertyChanged', interface=cs.ACCOUNT, predicate=( lambda e: e.args[0].get('NormalizedName') == 'thebatman')), ) assert get_aliases.args[0] in ([conn.self_handle], conn.self_id) q.expect('dbus-signal', path=account.object_path, signal='AccountPropertyChanged', interface=cs.ACCOUNT, args=[{ 'Nickname': 'TheBatman' }]) # We change our nickname back call_async(q, account_props, 'Set', cs.ACCOUNT, 'Nickname', 'BruceWayne') _, _, e = q.expect_many( EventPattern( 'dbus-signal', path=account.object_path, signal='AccountPropertyChanged', interface=cs.ACCOUNT, predicate=(lambda e: e.args[0].get('Nickname') == 'BruceWayne')), EventPattern('dbus-return', method='Set'), EventPattern('dbus-method-call', interface=cs.CONN_IFACE_ALIASING, method='SetAliases', args=[{ conn.self_handle: 'BruceWayne', }], handled=False)) assertEquals('BruceWayne', account_props.Get(cs.ACCOUNT, 'Nickname')) conn.change_self_ident('brucewayne') conn.change_self_alias('BruceWayne') q.dbus_return(e.message, signature='') # In response to the self-handle change, we check our nickname again get_aliases, _ = q.expect_many( EventPattern('dbus-method-call', interface=cs.CONN_IFACE_CONTACTS, predicate=(lambda e: e.method in ('GetContactAttributes', 'GetContactByID' ) and cs.CONN_IFACE_ALIASING in e.args[1]), handled=True), EventPattern( 'dbus-signal', path=account.object_path, signal='AccountPropertyChanged', interface=cs.ACCOUNT, predicate=( lambda e: e.args[0].get('NormalizedName') == 'brucewayne')), ) assert get_aliases.args[0] in ([conn.self_handle], conn.self_id) forbidden = [ EventPattern('dbus-signal', signal='AccountPropertyChanged', predicate=lambda e: 'Nickname' in e.args[0]) ] q.forbid_events(forbidden) sync_dbus(bus, q, mc)
def test(q, bus, mc): params = dbus.Dictionary( { "account": "*****@*****.**", "password": "******" }, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary( { cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT, cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT, }, signature='sv') # Logger is a text observer wanting recovery logger = SimulatedClient(q, bus, 'LoggerChat', observe=[text_fixed_properties], bypass_approval=False, wants_recovery=True) # gnome-shell is a text approver and handler gs = SimulatedClient(q, bus, 'GnomeShell', approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [logger, gs]) cd = bus.get_object(cs.CD, cs.CD_PATH) # incoming text channel channel_properties = dbus.Dictionary(text_fixed_properties, signature='sv') channel_properties[cs.CHANNEL + '.TargetID'] = 'juliet' channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.InitiatorID'] = 'juliet' channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.Requested'] = False channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') chan = SimulatedChannel(conn, channel_properties) chan.announce() # gnome-shell's approver and logger's observer are notified e, k = q.expect_many( EventPattern('dbus-method-call', path=logger.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), EventPattern('dbus-method-call', path=gs.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), ) channels, cdo_path, props = k.args cdo = bus.get_object(cs.CD, cdo_path) cdo_iface = dbus.Interface(cdo, cs.CDO) q.dbus_return(e.message, signature='') q.dbus_return(k.message, signature='') # gnome-shell claims the channel call_async(q, cdo_iface, 'Claim') e = q.expect('dbus-return', method='Claim') # Logger crash logger.release_name() e = q.expect( 'dbus-signal', signal='NameOwnerChanged', predicate=(lambda e: e.args[0] == logger.bus_name and e.args[2] == ''), ) bus.flush() # Logger gets restarted logger.reacquire_name() e = q.expect( 'dbus-signal', signal='NameOwnerChanged', predicate=(lambda e: e.args[0] == logger.bus_name and e.args[1] == ''), ) # Logger recovers the channel e = q.expect('dbus-method-call', path=logger.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False) # gnome-shell which is handling the channel asks to re-ensure it cd_iface = dbus.Interface(cd, cs.CD) call_async(q, cd_iface, 'PresentChannel', chan.object_path, 0) # gnome-shell is asked to re-handle the channel e = q.expect('dbus-method-call', path=gs.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) q.dbus_return(e.message, signature='') q.expect('dbus-return', method='PresentChannel') chan.close()
def test(q, bus, mc): params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) text_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') # Two clients want to observe, approve and handle channels empathy = SimulatedClient(q, bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) kopete = SimulatedClient(q, bus, 'Kopete', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [empathy, kopete]) # Enable the account account.Set(cs.ACCOUNT, 'Enabled', True, dbus_interface=cs.PROPERTIES_IFACE) requested_presence = dbus.Struct((dbus.UInt32(2L), dbus.String(u'available'), dbus.String(u''))) account.Set(cs.ACCOUNT, 'RequestedPresence', requested_presence, dbus_interface=cs.PROPERTIES_IFACE) e = q.expect('dbus-method-call', method='RequestConnection', args=['fakeprotocol', params], destination=cs.tp_name_prefix + '.ConnectionManager.fakecm', path=cs.tp_path_prefix + '/ConnectionManager/fakecm', interface=cs.tp_name_prefix + '.ConnectionManager', handled=False) # Don't allow the Connection to have its list of channels # until we want it to, by avoiding a return from GetAll(Requests). conn = SimulatedConnection(q, bus, 'fakecm', 'fakeprotocol', '_', 'myself', implement_get_channels=False) q.dbus_return(e.message, conn.bus_name, conn.object_path, signature='so') get_all_requests_call = q.expect('dbus-method-call', method='GetAll', args=[cs.CONN_IFACE_REQUESTS]) q.expect('dbus-method-call', method='Connect', path=conn.object_path, handled=True) conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) # subscribe to the OperationList interface (MC assumes that until this # property has been retrieved once, nobody cares) cd = bus.get_object(cs.CD, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] # Before returning from GetAll(Requests), make a Channel spring into # existence channel_properties = dbus.Dictionary(text_fixed_properties, signature='sv') channel_properties[cs.CHANNEL + '.TargetID'] = 'juliet' channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.InitiatorID'] = 'juliet' channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.Requested'] = False channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') chan = SimulatedChannel(conn, channel_properties) chan.announce() # Now reply to GetAll(Requests) conn.GetAll_Requests(get_all_requests_call) # A channel dispatch operation is created for the channel we already had e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') cdo_path = e.args[0] cdo_properties = e.args[1] assert cdo_properties[cs.CDO + '.Account'] == account.object_path assert cdo_properties[cs.CDO + '.Connection'] == conn.object_path handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] handlers.sort() assert handlers == [cs.tp_name_prefix + '.Client.Empathy', cs.tp_name_prefix + '.Client.Kopete'], handlers assert cs.CD_IFACE_OP_LIST in cd_props.Get(cs.CD, 'Interfaces') assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') ==\ [(cdo_path, cdo_properties)] cdo = bus.get_object(cs.CD, cdo_path) cdo_iface = dbus.Interface(cdo, cs.CDO) # Both Observers are told about the new channel e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), ) assert e.args[0] == account.object_path, e.args assert e.args[1] == conn.object_path, e.args assert e.args[3] == cdo_path, e.args assert e.args[4] == [], e.args # no requests satisfied channels = e.args[2] assert len(channels) == 1, channels assert channels[0][0] == chan.object_path, channels assert channels[0][1] == channel_properties, channels assert k.args == e.args # Both Observers indicate that they are ready to proceed q.dbus_return(k.message, signature='') q.dbus_return(e.message, signature='') # The Approvers are next e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), ) assert e.args == [[(chan.object_path, channel_properties)], cdo_path, cdo_properties] assert k.args == e.args q.dbus_return(e.message, signature='') q.dbus_return(k.message, signature='') # Both Approvers now have a flashing icon or something, trying to get the # user's attention # The user responds to Empathy first call_async(q, cdo_iface, 'HandleWith', cs.tp_name_prefix + '.Client.Empathy') # Empathy is asked to handle the channels e = q.expect('dbus-method-call', path=empathy.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) # Empathy accepts the channels q.dbus_return(e.message, signature='') q.expect_many( EventPattern('dbus-return', method='HandleWith'), EventPattern('dbus-signal', interface=cs.CDO, signal='Finished'), EventPattern('dbus-signal', interface=cs.CD_IFACE_OP_LIST, signal='DispatchOperationFinished'), ) # Now there are no more active channel dispatch operations assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == []
def test(q, bus, mc): params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) # Two clients want to observe, approve and handle channels. Additionally, # Kopete recognises an "Urgent" flag on certain incoming channels, and # wants to bypass approval for them. empathy = SimulatedClient(q, bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) kopete = SimulatedClient(q, bus, 'Kopete', observe=[contact_text_fixed_properties], approve=[contact_text_fixed_properties], handle=[contact_text_fixed_properties], bypass_approval=False) bypass = SimulatedClient(q, bus, 'Kopete.BypassApproval', observe=[], approve=[], handle=[urgent_fixed_properties], bypass_approval=True) # wait for MC to download the properties expect_client_setup(q, [empathy, kopete, bypass]) # subscribe to the OperationList interface (MC assumes that until this # property has been retrieved once, nobody cares) cd = bus.get_object(cs.CD, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] # First, a non-urgent channel is created cdo_iface, chan, channel_properties, observe_events = announce_common(q, bus, empathy, kopete, account, conn, cd_props, False) # Both Observers indicate that they are ready to proceed for e in observe_events: q.dbus_return(e.message, signature='') expect_and_exercise_approval(q, bus, chan, channel_properties, empathy, kopete, cdo_iface, cd_props) # Now a channel that bypasses approval comes in. During this process, # we should never be asked to approve anything. approval = [ EventPattern('dbus-method-call', method='AddDispatchOperation'), ] q.forbid_events(approval) cdo_iface, chan, channel_properties, observe_events = announce_common(q, bus, empathy, kopete, account, conn, cd_props, True) # Both Observers indicate that they are ready to proceed for e in observe_events: q.dbus_return(e.message, signature='') # Kopete's BypassApproval part is asked to handle the channels e = q.expect('dbus-method-call', path=bypass.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) # Kopete accepts the channels q.dbus_return(e.message, signature='') q.unforbid_events(approval) # Regression test for fd.o #22670 closure = [ EventPattern('dbus-method-call', method='Close'), ] q.forbid_events(closure) bypass.release_name() sync_dbus(bus, q, mc) q.unforbid_events(closure) # Bring back that handler del bypass bypass = SimulatedClient(q, bus, 'Kopete.BypassApproval', observe=[], approve=[], handle=[urgent_fixed_properties], bypass_approval=True) expect_client_setup(q, [bypass]) # Another channel that bypasses approval comes in, but the handler that # bypasses approval fails. cdo_iface, chan, channel_properties, observe_events = announce_common(q, bus, empathy, kopete, account, conn, cd_props, True) # Both Observers indicate that they are ready to proceed for e in observe_events: q.dbus_return(e.message, signature='') # Kopete's BypassApproval part is asked to handle the channels e = q.expect('dbus-method-call', path=bypass.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) # Kopete's BypassApproval part fails to accept the channels q.dbus_raise(e.message, 'com.example.Broken', 'No way') # MC recovers by running the approvers and doing what they say expect_and_exercise_approval(q, bus, chan, channel_properties, empathy, kopete, cdo_iface, cd_props)
def test(q, bus, mc): params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') # Empathy is an observer for text channels with # DelayApprovers=TRUE. empathy = SimulatedClient(q, bus, 'Empathy', observe=[text_fixed_properties], approve=[], handle=[], delay_approvers=True) # Kopete is an approver and handler for text channels. kopete = SimulatedClient(q, bus, 'Kopete', observe=[], approve=[text_fixed_properties], handle=[text_fixed_properties]) expect_client_setup(q, [empathy, kopete]) # subscribe to the OperationList interface (MC assumes that until this # property has been retrieved once, nobody cares) cd = bus.get_object(cs.CD, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] # A text channel appears! channel_properties = dbus.Dictionary(text_fixed_properties, signature='sv') channel_properties[cs.CHANNEL + '.TargetID'] = 'juliet' channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.InitiatorID'] = 'juliet' channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.Requested'] = False channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') chan = SimulatedChannel(conn, channel_properties) chan.announce() e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') cdo_path = e.args[0] cdo = bus.get_object(cs.CD, cdo_path) cdo_iface = dbus.Interface(cdo, cs.CDO) cdo_props_iface = dbus.Interface(cdo, cs.PROPERTIES_IFACE) # Empathy, the observer, gets the channel to observe. Because it # has DelayApprovers=TRUE, Kopete should not have # AddDispatchOperation called on it until Empathy returns from # ObserveChannels. forbidden = [EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.APPROVER, method='AddDispatchOperation')] q.forbid_events(forbidden) o = q.expect('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False) # Waste a little time here and there. We can't call sync_dbus # here because it calls Ping and libdbus returns from Ping # synchronously and doesn't turn the main loop handle enough. call_async(q, cd_props, 'Get', cs.CD_IFACE_OP_LIST, 'DispatchOperations') event = q.expect('dbus-return', method='Get') # Finally return from ObserveChannels, so now we expect ADO to be # called on Kopete. q.dbus_return(o.message, bus=bus, signature='') q.unforbid_events(forbidden) e = q.expect('dbus-method-call', path=kopete.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False) q.dbus_return(e.message, bus=bus, signature='') # The user responds to Kopete call_async(q, cdo_iface, 'HandleWith', cs.tp_name_prefix + '.Client.Kopete') # Kopete is asked to handle the channels k = q.expect('dbus-method-call', path=kopete.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) # Kopete accepts the channels q.dbus_return(k.message, bus=bus, signature='') q.expect_many( EventPattern('dbus-return', method='HandleWith'), EventPattern('dbus-signal', interface=cs.CDO, signal='Finished'), EventPattern('dbus-signal', interface=cs.CD_IFACE_OP_LIST, signal='DispatchOperationFinished'), ) # Now there are no more active channel dispatch operations assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == []
def test(q, bus, mc): # Get the AccountManager interface account_manager = get_account_manager(bus) account_manager_iface = dbus.Interface(account_manager, cs.AM) # Introspect AccountManager for debugging purpose account_manager_introspected = account_manager.Introspect( dbus_interface=cs.INTROSPECTABLE_IFACE) #print account_manager_introspected # Check AccountManager has D-Bus property interface properties = account_manager.GetAll(cs.AM, dbus_interface=cs.PROPERTIES_IFACE) assert properties is not None assert properties.get('ValidAccounts') == [], \ properties.get('ValidAccounts') assert properties.get('InvalidAccounts') == [], \ properties.get('InvalidAccounts') interfaces = properties.get('Interfaces') params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) account_path = account.__dbus_object_path__ # Check the account is correctly created properties = account_manager.GetAll(cs.AM, dbus_interface=cs.PROPERTIES_IFACE) assert properties is not None assert properties.get('ValidAccounts') == [account_path], properties account_path = properties['ValidAccounts'][0] assert isinstance(account_path, dbus.ObjectPath), repr(account_path) assert properties.get('InvalidAccounts') == [], properties account_iface = dbus.Interface(account, cs.ACCOUNT) account_props = dbus.Interface(account, cs.PROPERTIES_IFACE) # Introspect Account for debugging purpose account_introspected = account.Introspect( dbus_interface=cs.INTROSPECTABLE_IFACE) #print account_introspected # Check Account has D-Bus property interface properties = account_props.GetAll(cs.ACCOUNT) assert properties is not None assert properties.get('DisplayName') == 'fakeaccount', \ properties.get('DisplayName') assert properties.get('Icon') == '', properties.get('Icon') assert properties.get('Valid') == True, properties.get('Valid') assert properties.get('Enabled') == False, properties.get('Enabled') #assert properties.get('Nickname') == 'fakenick', properties.get('Nickname') assert properties.get('Parameters') == params, properties.get('Parameters') assert properties.get('Connection') == '/', properties.get('Connection') assert properties.get('NormalizedName') == '', \ properties.get('NormalizedName') interfaces = properties.get('Interfaces') assert cs.ACCOUNT_IFACE_AVATAR in interfaces, interfaces # sanity check for k in properties: assert account_props.Get(cs.ACCOUNT, k) == properties[k], k # Alter some miscellaneous r/w properties call_async(q, account_props, 'Set', cs.ACCOUNT, 'DisplayName', 'Work account') q.expect_many( EventPattern('dbus-signal', path=account_path, signal='AccountPropertyChanged', interface=cs.ACCOUNT, args=[{'DisplayName': 'Work account'}]), EventPattern('dbus-signal', interface=cs.TEST_DBUS_ACCOUNT_PLUGIN_IFACE, signal='DeferringSetAttribute', args=[account_path, 'DisplayName', 'Work account']), EventPattern('dbus-signal', interface=cs.TEST_DBUS_ACCOUNT_PLUGIN_IFACE, signal='CommittingOne', args=[account_path]), EventPattern('dbus-method-call', interface=cs.TEST_DBUS_ACCOUNT_SERVICE_IFACE, method='UpdateAttributes', args=[account_path[len(cs.ACCOUNT_PATH_PREFIX):], {'DisplayName': 'Work account'}, {'DisplayName': 0}, # flags []], ), EventPattern('dbus-return', method='Set'), ) assert account_props.Get(cs.ACCOUNT, 'DisplayName') == 'Work account' call_async(q, account_props, 'Set', cs.ACCOUNT, 'Icon', 'im-jabber') q.expect_many( EventPattern('dbus-signal', path=account_path, signal='AccountPropertyChanged', interface=cs.ACCOUNT, args=[{'Icon': 'im-jabber'}]), EventPattern('dbus-signal', interface=cs.TEST_DBUS_ACCOUNT_PLUGIN_IFACE, signal='DeferringSetAttribute', args=[account_path, 'Icon', 'im-jabber']), EventPattern('dbus-signal', interface=cs.TEST_DBUS_ACCOUNT_PLUGIN_IFACE, signal='CommittingOne', args=[account_path]), EventPattern('dbus-method-call', interface=cs.TEST_DBUS_ACCOUNT_SERVICE_IFACE, method='UpdateAttributes', args=[account_path[len(cs.ACCOUNT_PATH_PREFIX):], {'Icon': 'im-jabber'}, {'Icon': 0}, # flags []], ), EventPattern('dbus-return', method='Set'), ) assert account_props.Get(cs.ACCOUNT, 'Icon') == 'im-jabber' assert account_props.Get(cs.ACCOUNT, 'HasBeenOnline') == False call_async(q, account_props, 'Set', cs.ACCOUNT, 'Nickname', 'Joe Bloggs') q.expect_many( EventPattern('dbus-signal', path=account_path, signal='AccountPropertyChanged', interface=cs.ACCOUNT, args=[{'Nickname': 'Joe Bloggs'}]), EventPattern('dbus-return', method='Set'), EventPattern('dbus-signal', interface=cs.TEST_DBUS_ACCOUNT_PLUGIN_IFACE, signal='DeferringSetAttribute', args=[account_path, 'Nickname', 'Joe Bloggs']), EventPattern('dbus-signal', interface=cs.TEST_DBUS_ACCOUNT_PLUGIN_IFACE, signal='CommittingOne', args=[account_path]), EventPattern('dbus-method-call', interface=cs.TEST_DBUS_ACCOUNT_SERVICE_IFACE, method='UpdateAttributes', args=[account_path[len(cs.ACCOUNT_PATH_PREFIX):], {'Nickname': 'Joe Bloggs'}, {'Nickname': 0}, # flags []], ), ) assert account_props.Get(cs.ACCOUNT, 'Nickname') == 'Joe Bloggs' assertEquals(dbus.Array(signature='o'), account_props.Get(cs.ACCOUNT, 'Supersedes')) call_async(q, account_props, 'Set', cs.ACCOUNT, 'Supersedes', dbus.Array([cs.ACCOUNT_PATH_PREFIX + 'x/y/z'], signature='o')) q.expect_many( EventPattern('dbus-signal', path=account_path, signal='AccountPropertyChanged', interface=cs.ACCOUNT, args=[{'Supersedes': [cs.ACCOUNT_PATH_PREFIX + 'x/y/z']}]), EventPattern('dbus-return', method='Set'), EventPattern('dbus-signal', interface=cs.TEST_DBUS_ACCOUNT_PLUGIN_IFACE, signal='DeferringSetAttribute', args=[account_path, 'Supersedes', [cs.ACCOUNT_PATH_PREFIX + 'x/y/z']]), EventPattern('dbus-signal', interface=cs.TEST_DBUS_ACCOUNT_PLUGIN_IFACE, signal='CommittingOne', args=[account_path]), EventPattern('dbus-method-call', interface=cs.TEST_DBUS_ACCOUNT_SERVICE_IFACE, method='UpdateAttributes', args=[account_path[len(cs.ACCOUNT_PATH_PREFIX):], {'Supersedes': [cs.ACCOUNT_PATH_PREFIX + 'x/y/z']}, {'Supersedes': 0}, # flags []], ), ) assertEquals(dbus.Array([cs.ACCOUNT_PATH_PREFIX + 'x/y/z'], signature='o'), account_props.Get(cs.ACCOUNT, 'Supersedes')) # Set some properties to invalidly typed values - this currently succeeds # but is a no-op, although in future it should change to raising an # exception forbidden = [ EventPattern('dbus-signal', interface=cs.TEST_DBUS_ACCOUNT_PLUGIN_IFACE, signal='DeferringSetAttribute'), EventPattern('dbus-method-call', interface=cs.TEST_DBUS_ACCOUNT_SERVICE_IFACE, method='UpdateAttributes'), ] q.forbid_events(forbidden) # this variable's D-Bus type must differ from the types of all known # properties badly_typed = dbus.Struct(('wrongly typed',), signature='s') for p in ('DisplayName', 'Icon', 'Enabled', 'Nickname', 'AutomaticPresence', 'ConnectAutomatically', 'RequestedPresence'): try: account_props.Set(cs.ACCOUNT, p, badly_typed) except dbus.DBusException, e: assert e.get_dbus_name() == cs.INVALID_ARGUMENT, \ (p, e.get_dbus_name()) else: raise AssertionError('Setting %s with wrong type should fail' % p)
def test(q, bus, mc): policy_bus_name_ref = dbus.service.BusName('com.example.Policy', bus) params = dbus.Dictionary( { "account": "*****@*****.**", "password": "******" }, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, 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') # 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 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 fixed_properties = dbus.Dictionary( { cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': DELAYED_CTYPE, }, signature='sv') client = SimulatedClient(q, bus, 'Empathy', observe=[fixed_properties], approve=[fixed_properties], handle=[fixed_properties], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [client]) user_action_time = dbus.Int64(1238582606) cd = bus.get_object(cs.CD, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) 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')
def test(q, bus, mc): params = dbus.Dictionary( {"account": "yum yum network manager", "password": "******", }, signature='sv') (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) # While we're not connected to the internet, RequestConnection should not # be called. request_connection_event = [ EventPattern('dbus-method-call', method='RequestConnection'), ] q.forbid_events(request_connection_event) account.Properties.Set(cs.ACCOUNT, 'RequestedPresence', (dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'hlaghalgh')) # Turn the account on, re-request an online presence, and even tell it to # connect automatically, to check that none of these make it sign in. call_async(q, account.Properties, 'Set', cs.ACCOUNT, 'Enabled', True) q.expect('dbus-return', method='Set') requested_presence = (dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'gtfo') call_async(q, account.Properties, 'Set', cs.ACCOUNT, 'RequestedPresence', requested_presence) q.expect('dbus-return', method='Set') call_async(q, account.Properties, 'Set', cs.ACCOUNT, 'ConnectAutomatically', True) q.expect('dbus-return', method='Set') # (but actually let's turn ConnectAutomatically off: we want to check that # MC continues to try to apply RequestedPresence if the network connection # goes away and comes back again, regardless of this setting) call_async(q, account.Properties, 'Set', cs.ACCOUNT, 'ConnectAutomatically', False) q.expect('dbus-return', method='Set') sync_dbus(bus, q, mc) q.unforbid_events(request_connection_event) # Okay, I'm satisfied. Turn the network on. mc.connectivity.go_online() expect_fakecm_connection(q, bus, mc, account, params, has_presence=True, expect_before_connect=[ EventPattern('dbus-method-call', method='SetPresence', args=list(requested_presence[1:])), ]) if config.HAVE_NM: # If NetworkManager tells us that it is going to disconnect soon, # the connection should be banished. GNetworkMonitor can't tell us # that; either it's online or it isn't. mc.connectivity.go_indeterminate() q.expect('dbus-method-call', method='Disconnect') mc.connectivity.go_offline() sync_connectivity_state(mc) # When we turn the network back on, MC should try to sign us back on. # In the process, our RequestedPresence should not have been # trampled on, as below. mc.connectivity.go_online() expect_fakecm_connection(q, bus, mc, account, params, has_presence=True, expect_before_connect=[ EventPattern('dbus-method-call', method='SetPresence', args=list(requested_presence[1:])), ]) assertEquals(requested_presence, account.Properties.Get(cs.ACCOUNT, 'RequestedPresence')) # If we turn the network off, the connection should be banished. mc.connectivity.go_offline() q.expect('dbus-method-call', method='Disconnect') # When we turn the network back on, MC should try to sign us back on. mc.connectivity.go_online() e = q.expect('dbus-method-call', method='RequestConnection') # In the process, our RequestedPresence should not have been trampled on. # (Historically, MC would replace it with the AutomaticPresence, but that # behaviour was unexpected: if the user explicitly set a status or message, # why should the network connection cutting out and coming back up cause # that to be lost?) assertEquals(requested_presence, account.Properties.Get(cs.ACCOUNT, 'RequestedPresence')) # But if we get disconnected before RequestConnection returns, MC should # clean up the new connection when it does, rather than trying to sign it # in. connect_event = [ EventPattern('dbus-method-call', method='Connect'), ] q.forbid_events(connect_event) mc.connectivity.go_offline() # Make sure that MC has noticed that the network connection has gone away. sync_connectivity_state(mc) conn = SimulatedConnection(q, bus, 'fakecm', 'fakeprotocol', account.object_path.split('/')[-1], 'myself') q.dbus_return(e.message, conn.bus_name, conn.object_path, signature='so') q.expect('dbus-method-call', method='Disconnect') # So now the user gives up and sets their RequestedPresence to offline. # Because this account does not ConnectAutomatically, if the network # connection comes back up the account should not be brought back online. q.forbid_events(request_connection_event) account.Properties.Set(cs.ACCOUNT, 'RequestedPresence', (dbus.UInt32(cs.PRESENCE_OFFLINE), 'offline', '')) mc.connectivity.go_online() # Make sure MC has noticed that the network connection has come back. sync_connectivity_state(mc)
def test(q, bus, mc): params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') empathy_bus = dbus.bus.BusConnection() q.attach_to_bus(empathy_bus) empathy = SimulatedClient(q, empathy_bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [empathy]) # subscribe to the OperationList interface (MC assumes that until this # property has been retrieved once, nobody cares) cd = bus.get_object(cs.CD, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] channel_properties = dbus.Dictionary(text_fixed_properties, signature='sv') channel_properties[cs.CHANNEL + '.TargetID'] = 'juliet' channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.InitiatorID'] = 'juliet' channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.Requested'] = False channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') chan = SimulatedChannel(conn, channel_properties) chan.announce() # A channel dispatch operation is created e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') cdo_path = e.args[0] cdo_properties = e.args[1] assert cdo_properties[cs.CDO + '.Account'] == account.object_path assert cdo_properties[cs.CDO + '.Connection'] == conn.object_path assert cs.CDO + '.Interfaces' in cdo_properties handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] assert handlers == [cs.tp_name_prefix + '.Client.Empathy'], handlers assert cs.CD_IFACE_OP_LIST in cd_props.Get(cs.CD, 'Interfaces') assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') ==\ [(cdo_path, cdo_properties)] cdo = bus.get_object(cs.CD, cdo_path) cdo_iface = dbus.Interface(cdo, cs.CDO) cdo_props_iface = dbus.Interface(cdo, cs.PROPERTIES_IFACE) assert cdo_props_iface.Get(cs.CDO, 'Interfaces') == \ cdo_properties[cs.CDO + '.Interfaces'] assert cdo_props_iface.Get(cs.CDO, 'Connection') == conn.object_path assert cdo_props_iface.Get(cs.CDO, 'Account') == account.object_path assert cdo_props_iface.Get(cs.CDO, 'Channels') == [(chan.object_path, channel_properties)] assert cdo_props_iface.Get(cs.CDO, 'PossibleHandlers') == \ cdo_properties[cs.CDO + '.PossibleHandlers'] e = q.expect('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False) assert e.args[0] == account.object_path, e.args assert e.args[1] == conn.object_path, e.args assert e.args[3] == cdo_path, e.args assert e.args[4] == [], e.args # no requests satisfied channels = e.args[2] assert len(channels) == 1, channels assert channels[0][0] == chan.object_path, channels assert channels[0][1] == channel_properties, channels q.dbus_return(e.message, bus=empathy_bus, signature='') e = q.expect('dbus-method-call', path=empathy.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False) assert e.args == [[(chan.object_path, channel_properties)], cdo_path, cdo_properties] # Empathy rejects the channels q.dbus_raise(e.message, cs.NOT_AVAILABLE, 'Blind drunk', bus=empathy_bus) # No approver works, so Empathy-the-Handler is asked to handle the channels e = q.expect('dbus-method-call', path=empathy.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) # Empathy rejects the channels q.dbus_raise(e.message, cs.NOT_AVAILABLE, 'Still drunk', bus=empathy_bus) q.expect_many( EventPattern('dbus-method-call', path=chan.object_path, interface=cs.CHANNEL, method='Close', handled=True), EventPattern('dbus-signal', path=cdo.object_path, interface=cs.CDO, signal='Finished'), EventPattern('dbus-signal', path=cd.object_path, interface=cs.CD_IFACE_OP_LIST, signal='DispatchOperationFinished'), ) # Now there are no more active channel dispatch operations assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == []
def test(q, bus, mc): params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT, cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT, }, signature='sv') # Logger is a text observer wanting recovery logger = SimulatedClient(q, bus, 'LoggerChat', observe=[text_fixed_properties], bypass_approval=False, wants_recovery=True) # gnome-shell is a text approver and handler gs = SimulatedClient(q, bus, 'GnomeShell', approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [logger, gs]) cd = bus.get_object(cs.CD, cs.CD_PATH) # incoming text channel channel_properties = dbus.Dictionary(text_fixed_properties, signature='sv') channel_properties[cs.CHANNEL + '.TargetID'] = 'juliet' channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.InitiatorID'] = 'juliet' channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.Requested'] = False channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') chan = SimulatedChannel(conn, channel_properties) chan.announce() # gnome-shell's approver and logger's observer are notified e, k = q.expect_many( EventPattern('dbus-method-call', path=logger.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), EventPattern('dbus-method-call', path=gs.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), ) channels, cdo_path, props = k.args cdo = bus.get_object(cs.CD, cdo_path) cdo_iface = dbus.Interface(cdo, cs.CDO) q.dbus_return(e.message, signature='') q.dbus_return(k.message, signature='') # gnome-shell claims the channel call_async(q, cdo_iface, 'Claim') e = q.expect('dbus-return', method='Claim') # Logger crash logger.release_name() e = q.expect('dbus-signal', signal='NameOwnerChanged', predicate=(lambda e: e.args[0] == logger.bus_name and e.args[2] == ''), ) bus.flush() # Logger gets restarted logger.reacquire_name() e = q.expect('dbus-signal', signal='NameOwnerChanged', predicate=(lambda e: e.args[0] == logger.bus_name and e.args[1] == ''), ) # Logger recovers the channel e = q.expect('dbus-method-call', path=logger.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False) # gnome-shell which is handling the channel asks to re-ensure it cd_iface = dbus.Interface(cd, cs.CD) call_async(q, cd_iface, 'PresentChannel', chan.object_path, 0) # gnome-shell is asked to re-handle the channel e = q.expect('dbus-method-call', path=gs.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) q.dbus_return(e.message, signature='') q.expect('dbus-return', method='PresentChannel') chan.close()
def test(q, bus, mc): params = dbus.Dictionary({"account": "*****@*****.**", "password": "******"}, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') empathy_bus = dbus.bus.BusConnection() empathy_bus.set_exit_on_disconnect(False) # we'll disconnect later kopete_bus = dbus.bus.BusConnection() q.attach_to_bus(empathy_bus) q.attach_to_bus(kopete_bus) # Two clients want to observe, approve and handle channels empathy = SimulatedClient(q, empathy_bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) kopete = SimulatedClient(q, kopete_bus, 'Kopete', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [empathy, kopete]) # subscribe to the OperationList interface (MC assumes that until this # property has been retrieved once, nobody cares) cd = bus.get_object(cs.CD, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] channel_properties = dbus.Dictionary(text_fixed_properties, signature='sv') channel_properties[cs.CHANNEL + '.TargetID'] = 'juliet' channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.InitiatorID'] = 'juliet' channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.Requested'] = False channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') chan = SimulatedChannel(conn, channel_properties) chan.announce() # A channel dispatch operation is created e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') cdo_path = e.args[0] cdo_properties = e.args[1] assert cdo_properties[cs.CDO + '.Account'] == account.object_path assert cdo_properties[cs.CDO + '.Connection'] == conn.object_path assert cs.CDO + '.Interfaces' in cdo_properties handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] handlers.sort() assert handlers == [cs.tp_name_prefix + '.Client.Empathy', cs.tp_name_prefix + '.Client.Kopete'], handlers assert cs.CD_IFACE_OP_LIST in cd_props.Get(cs.CD, 'Interfaces') assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') ==\ [(cdo_path, cdo_properties)] cdo = bus.get_object(cs.CD, cdo_path) cdo_iface = dbus.Interface(cdo, cs.CDO) cdo_props_iface = dbus.Interface(cdo, cs.PROPERTIES_IFACE) assert cdo_props_iface.Get(cs.CDO, 'Interfaces') == \ cdo_properties[cs.CDO + '.Interfaces'] assert cdo_props_iface.Get(cs.CDO, 'Connection') == conn.object_path assert cdo_props_iface.Get(cs.CDO, 'Account') == account.object_path assert cdo_props_iface.Get(cs.CDO, 'Channels') == [(chan.object_path, channel_properties)] assert cdo_props_iface.Get(cs.CDO, 'PossibleHandlers') == \ cdo_properties[cs.CDO + '.PossibleHandlers'] # Both Observers are told about the new channel e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), ) assert e.args[0] == account.object_path, e.args assert e.args[1] == conn.object_path, e.args assert e.args[3] == cdo_path, e.args assert e.args[4] == [], e.args # no requests satisfied channels = e.args[2] assert len(channels) == 1, channels assert channels[0][0] == chan.object_path, channels assert channels[0][1] == channel_properties, channels assert k.args == e.args # Both Observers indicate that they are ready to proceed q.dbus_return(k.message, bus=empathy_bus, signature='') q.dbus_return(e.message, bus=kopete_bus, signature='') # The Approvers are next e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), ) assert e.args == [[(chan.object_path, channel_properties)], cdo_path, cdo_properties] assert k.args == e.args q.dbus_return(e.message, bus=empathy_bus, signature='') q.dbus_return(k.message, bus=kopete_bus, signature='') # Both Approvers now have a flashing icon or something, trying to get the # user's attention # Using an invalid Handler name should fail call_async(q, cdo_iface, 'HandleWith', cs.tp_name_prefix + '.The.Moon.On.A.Stick') q.expect('dbus-error', method='HandleWith') call_async(q, cdo_iface, 'HandleWith', cs.tp_name_prefix + '.Client.the moon on a stick') q.expect('dbus-error', method='HandleWith') # The user responds to Empathy first call_async(q, cdo_iface, 'HandleWith', cs.tp_name_prefix + '.Client.Empathy') # Empathy is asked to handle the channels e = q.expect('dbus-method-call', path=empathy.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) # Empathy accepts the channels q.dbus_return(e.message, bus=empathy_bus, signature='') q.expect_many( EventPattern('dbus-return', method='HandleWith'), EventPattern('dbus-signal', interface=cs.CDO, signal='Finished'), EventPattern('dbus-signal', interface=cs.CD_IFACE_OP_LIST, signal='DispatchOperationFinished'), ) # Now there are no more active channel dispatch operations assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] # Approve another channel using HandleWithTime() channel_properties = dbus.Dictionary(text_fixed_properties, signature='sv') channel_properties[cs.CHANNEL + '.TargetID'] = 'lucien' channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'lucien') channel_properties[cs.CHANNEL + '.InitiatorID'] = 'lucien' channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'lucien') channel_properties[cs.CHANNEL + '.Requested'] = False channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') chan = SimulatedChannel(conn, channel_properties) chan.announce() # A channel dispatch operation is created e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') cdo_path = e.args[0] cdo_properties = e.args[1] assert cdo_properties[cs.CDO + '.Account'] == account.object_path assert cdo_properties[cs.CDO + '.Connection'] == conn.object_path assert cs.CDO + '.Interfaces' in cdo_properties handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] handlers.sort() assert handlers == [cs.tp_name_prefix + '.Client.Empathy', cs.tp_name_prefix + '.Client.Kopete'], handlers assert cs.CD_IFACE_OP_LIST in cd_props.Get(cs.CD, 'Interfaces') assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') ==\ [(cdo_path, cdo_properties)] cdo = bus.get_object(cs.CD, cdo_path) cdo_iface = dbus.Interface(cdo, cs.CDO) cdo_props_iface = dbus.Interface(cdo, cs.PROPERTIES_IFACE) assert cdo_props_iface.Get(cs.CDO, 'Interfaces') == \ cdo_properties[cs.CDO + '.Interfaces'] assert cdo_props_iface.Get(cs.CDO, 'Connection') == conn.object_path assert cdo_props_iface.Get(cs.CDO, 'Account') == account.object_path assert cdo_props_iface.Get(cs.CDO, 'Channels') == [(chan.object_path, channel_properties)] assert cdo_props_iface.Get(cs.CDO, 'PossibleHandlers') == \ cdo_properties[cs.CDO + '.PossibleHandlers'] # Both Observers are told about the new channel e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), ) assert e.args[0] == account.object_path, e.args assert e.args[1] == conn.object_path, e.args assert e.args[3] == cdo_path, e.args assert e.args[4] == [], e.args # no requests satisfied channels = e.args[2] assert len(channels) == 1, channels assert channels[0][0] == chan.object_path, channels assert channels[0][1] == channel_properties, channels assert k.args == e.args # Both Observers indicate that they are ready to proceed q.dbus_return(k.message, bus=empathy_bus, signature='') q.dbus_return(e.message, bus=kopete_bus, signature='') # The Approvers are next e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), ) assert e.args == [[(chan.object_path, channel_properties)], cdo_path, cdo_properties] assert k.args == e.args q.dbus_return(e.message, bus=empathy_bus, signature='') q.dbus_return(k.message, bus=kopete_bus, signature='') # Both Approvers now have a flashing icon or something, trying to get the # user's attention # The user responds to Empathy first call_async(q, cdo_iface, 'HandleWithTime', cs.tp_name_prefix + '.Client.Empathy', 13) # Empathy is asked to handle the channels e = q.expect('dbus-method-call', path=empathy.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) account_path, conn_path, channels, requests, action_time, info = e.args assert action_time == 13 # Empathy accepts the channels q.dbus_return(e.message, bus=empathy_bus, signature='') q.expect_many( EventPattern('dbus-return', method='HandleWithTime'), EventPattern('dbus-signal', interface=cs.CDO, signal='Finished'), EventPattern('dbus-signal', interface=cs.CD_IFACE_OP_LIST, signal='DispatchOperationFinished'), ) # Now there are no more active channel dispatch operations assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] # From now on, it is an error to get HandleChannels (because we're # testing Claim()) forbidden = [ EventPattern('dbus-method-call', method='HandleChannels'), ] q.forbid_events(forbidden) # Another channel channel_properties = dbus.Dictionary(text_fixed_properties, signature='sv') channel_properties[cs.CHANNEL + '.TargetID'] = 'mercutio' channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'mercutio') channel_properties[cs.CHANNEL + '.InitiatorID'] = 'mercutio' channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'mercutio') channel_properties[cs.CHANNEL + '.Requested'] = False channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') claimed_chan = SimulatedChannel(conn, channel_properties) claimed_chan.announce() # A channel dispatch operation is created e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') cdo_path = e.args[0] cdo_properties = e.args[1] assert cdo_properties[cs.CDO + '.Account'] == account.object_path assert cdo_properties[cs.CDO + '.Connection'] == conn.object_path assert cs.CDO + '.Interfaces' in cdo_properties handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] handlers.sort() assert handlers == [cs.tp_name_prefix + '.Client.Empathy', cs.tp_name_prefix + '.Client.Kopete'], handlers assert cs.CD_IFACE_OP_LIST in cd_props.Get(cs.CD, 'Interfaces') assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') ==\ [(cdo_path, cdo_properties)] cdo = bus.get_object(cs.CD, cdo_path) cdo_iface = dbus.Interface(cdo, cs.CDO) # Both Observers are told about the new channel e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), ) assert e.args[0] == account.object_path, e.args assert e.args[1] == conn.object_path, e.args assert e.args[3] == cdo_path, e.args assert e.args[4] == [], e.args # no requests satisfied channels = e.args[2] assert len(channels) == 1, channels assert channels[0][0] == claimed_chan.object_path, channels assert channels[0][1] == channel_properties, channels assert k.args == e.args # Both Observers indicate that they are ready to proceed q.dbus_return(k.message, bus=kopete_bus, signature='') q.dbus_return(e.message, bus=empathy_bus, signature='') # The Approvers are next e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), ) assert e.args == [[(claimed_chan.object_path, channel_properties)], cdo_path, cdo_properties] assert k.args == e.args q.dbus_return(e.message, bus=empathy_bus, signature='') q.dbus_return(k.message, bus=kopete_bus, signature='') # Both Approvers now have a flashing icon or something, trying to get the # user's attention # The user responds to Empathy first, and Empathy decides it wants the # channel for itself empathy_cdo = empathy_bus.get_object(cdo.bus_name, cdo.object_path) empathy_cdo_iface = dbus.Interface(empathy_cdo, cs.CDO) call_async(q, empathy_cdo_iface, 'Claim') q.expect_many( EventPattern('dbus-signal', path=cdo_path, signal='Finished'), EventPattern('dbus-signal', path=cs.CD_PATH, signal='DispatchOperationFinished', args=[cdo_path]), EventPattern('dbus-return', method='Claim'), ) # Now there are no more active channel dispatch operations assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] # A third channel channel_properties = dbus.Dictionary(text_fixed_properties, signature='sv') channel_properties[cs.CHANNEL + '.TargetID'] = 'benvolio' channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'benvolio') channel_properties[cs.CHANNEL + '.InitiatorID'] = 'benvolio' channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'benvolio') channel_properties[cs.CHANNEL + '.Requested'] = False channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') third_chan = SimulatedChannel(conn, channel_properties) third_chan.announce() # third_chan should not be closed q.unforbid_events(forbidden) forbidden.append(EventPattern('dbus-method-call', method='Close', path=third_chan.object_path)) q.forbid_events(forbidden) # A channel dispatch operation is created e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') cdo_path = e.args[0] cdo_properties = e.args[1] cdo = bus.get_object(cs.CD, cdo_path) cdo_iface = dbus.Interface(cdo, cs.CDO) e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), ) q.dbus_return(k.message, bus=kopete_bus, signature='') q.dbus_return(e.message, bus=empathy_bus, signature='') e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), ) q.dbus_return(e.message, bus=empathy_bus, signature='') q.dbus_return(k.message, bus=kopete_bus, signature='') # Kopete closes this one kopete_cdo = kopete_bus.get_object(cdo.bus_name, cdo.object_path) kopete_cdo_iface = dbus.Interface(kopete_cdo, cs.CDO) call_async(q, kopete_cdo_iface, 'Claim') q.expect_many( EventPattern('dbus-signal', path=cdo_path, signal='Finished'), EventPattern('dbus-signal', path=cs.CD_PATH, signal='DispatchOperationFinished', args=[cdo_path]), EventPattern('dbus-return', method='Claim'), ) # Empathy crashes empathy.release_name() e = q.expect('dbus-signal', signal='NameOwnerChanged', predicate=(lambda e: e.args[0] == empathy.bus_name and e.args[2] == ''), ) empathy_unique_name = e.args[1] empathy_bus.flush() empathy_bus.close() # In response, the channels that were being handled by Empathy are closed. # Kopete's channel is *not* closed. q.expect_many( EventPattern('dbus-signal', signal='NameOwnerChanged', predicate=(lambda e: e.args[0] == empathy_unique_name and e.args[2] == '')), EventPattern('dbus-method-call', path=chan.object_path, method='Close'), EventPattern('dbus-method-call', path=claimed_chan.object_path, method='Close'), ) sync_dbus(bus, q, mc) q.unforbid_events(forbidden)
def test(q, bus, mc): params = dbus.Dictionary( { "account": "*****@*****.**", "password": "******" }, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary( { cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') client = SimulatedClient(q, bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) # No Approver should be invoked at any point during this test, because the # Channel was Requested def fail_on_approval(e): raise AssertionError('Approver should not be invoked') q.add_dbus_method_impl(fail_on_approval, path=client.object_path, interface=cs.APPROVER, method='AddDispatchOperation') # wait for MC to download the properties expect_client_setup(q, [client]) user_action_time = dbus.Int64(1238582606) # chat UI calls ChannelDispatcher.CreateChannel cd = ChannelDispatcher(bus) request = dbus.Dictionary( { cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.TargetID': 'juliet', }, signature='sv') request_path = cd.CreateChannel(account.object_path, request, user_action_time, client.bus_name) add_request = q.expect('dbus-method-call', handled=False, interface=cs.CLIENT_IFACE_REQUESTS, method='AddRequest', path=client.object_path) assert add_request.args[0] == request_path q.dbus_return(add_request.message, signature='') cr = bus.get_object(cs.CD, 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 # chat UI connects to signals and calls ChannelRequest.Proceed() cr.Proceed() cm_request_call = q.expect('dbus-method-call', interface=cs.CONN_IFACE_REQUESTS, method='CreateChannel', path=conn.object_path, args=[request], handled=False) # Actually, never mind. cr.Cancel() # 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, 'juliet') channel = SimulatedChannel(conn, channel_immutable) # this order of events is guaranteed by telepathy-spec (since 0.17.14) q.dbus_return(cm_request_call.message, channel.object_path, channel.immutable, signature='oa{sv}') channel.announce() # Channel is unwanted now, MC stabs it in the face stdsig, _ = q.expect_many( EventPattern('dbus-signal', path=request_path, interface=cs.CR, signal='Failed'), EventPattern('dbus-method-call', path=channel.object_path, interface=cs.CHANNEL, method='Close', handled=True), )
def test(q, bus, mc, nickname): params = dbus.Dictionary( { "account": "*****@*****.**", "password": "******" }, signature='sv') (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) account_iface = dbus.Interface(account, cs.ACCOUNT) account_props = dbus.Interface(account, cs.PROPERTIES_IFACE) call_async(q, account_props, 'Set', cs.ACCOUNT, 'Nickname', nickname) if nickname == '': q.expect('dbus-return', method='Set') else: q.expect_many( EventPattern('dbus-signal', path=account.object_path, signal='AccountPropertyChanged', interface=cs.ACCOUNT, args=[{ 'Nickname': nickname }]), EventPattern('dbus-return', method='Set'), ) assertEquals(nickname, account_props.Get(cs.ACCOUNT, 'Nickname')) # OK, let's go online expect_after_connect = [ EventPattern('dbus-method-call', interface=cs.CONN_IFACE_CONTACTS, predicate=(lambda e: e.method in ('GetContactAttributes', 'GetContactByID' ) and cs.CONN_IFACE_ALIASING in e.args[1]), handled=True), ] forbidden = [] if nickname == params['account'] or nickname == '': forbidden.append(EventPattern('dbus-method-call', method='SetAliases')) q.forbid_events(forbidden) if nickname == '': expect_after_connect.append( EventPattern('dbus-signal', path=account.object_path, signal='AccountPropertyChanged', interface=cs.ACCOUNT, predicate=(lambda e: e.args[0].get('Nickname') == params['account']))) else: expect_after_connect.append( EventPattern('dbus-method-call', interface=cs.CONN_IFACE_ALIASING, method='SetAliases', handled=False)) results = enable_fakecm_account(q, bus, mc, account, params, has_aliasing=True, expect_after_connect=expect_after_connect, self_ident=params['account']) conn = results[0] get_aliases = results[1] assert get_aliases.args[0] == [conn.self_handle] if nickname == params['account']: assertLength(2, results) elif nickname == '': assertLength(3, results) else: assertLength(3, results) set_aliases = results[2] assert set_aliases.args[0] == {conn.self_handle: nickname} q.dbus_return(set_aliases.message, signature='') if forbidden: sync_dbus(bus, q, mc) q.unforbid_events(forbidden) # Change alias after going online call_async(q, account_props, 'Set', cs.ACCOUNT, 'Nickname', 'Will Thomspon') e = q.expect('dbus-method-call', interface=cs.CONN_IFACE_ALIASING, method='SetAliases', args=[{ conn.self_handle: 'Will Thomspon' }], handled=False) # Set returns immediately; the change happens asynchronously q.expect('dbus-return', method='Set') q.dbus_return(e.message, signature='') someone_else = conn.ensure_handle(cs.HT_CONTACT, '*****@*****.**') # Another client changes our alias remotely q.dbus_emit(conn.object_path, cs.CONN_IFACE_ALIASING, 'AliasesChanged', dbus.Array([(conn.self_handle, 'wjt'), (someone_else, 'mardy')], signature='(us)'), signature='a(us)') q.expect('dbus-signal', path=account.object_path, signal='AccountPropertyChanged', interface=cs.ACCOUNT, args=[{ 'Nickname': 'wjt' }]) # If we set a trivial nickname while connected, MC does use it nickname = params['account'] call_async(q, account_props, 'Set', cs.ACCOUNT, 'Nickname', params['account']) _, _, e = q.expect_many( EventPattern('dbus-signal', path=account.object_path, signal='AccountPropertyChanged', interface=cs.ACCOUNT, args=[{ 'Nickname': params['account'] }]), EventPattern('dbus-return', method='Set'), EventPattern('dbus-method-call', interface=cs.CONN_IFACE_ALIASING, method='SetAliases', args=[{ conn.self_handle: params['account'] }], handled=False)) assertEquals(nickname, account_props.Get(cs.ACCOUNT, 'Nickname')) q.dbus_return(e.message, signature='') # Set the nickname back to something else nickname = 'wjt' call_async(q, account_props, 'Set', cs.ACCOUNT, 'Nickname', nickname) _, _, e = q.expect_many( EventPattern('dbus-signal', path=account.object_path, signal='AccountPropertyChanged', interface=cs.ACCOUNT, args=[{ 'Nickname': nickname }]), EventPattern('dbus-return', method='Set'), EventPattern('dbus-method-call', interface=cs.CONN_IFACE_ALIASING, method='SetAliases', args=[{ conn.self_handle: nickname }], handled=False)) assertEquals(nickname, account_props.Get(cs.ACCOUNT, 'Nickname')) q.dbus_return(e.message, signature='') # If we set an empty nickname while connected, MC uses our normalized # name (identifier) instead. call_async(q, account_props, 'Set', cs.ACCOUNT, 'Nickname', '') _, _, e = q.expect_many( EventPattern('dbus-signal', path=account.object_path, signal='AccountPropertyChanged', interface=cs.ACCOUNT, args=[{ 'Nickname': params['account'] }]), EventPattern('dbus-return', method='Set'), EventPattern('dbus-method-call', interface=cs.CONN_IFACE_ALIASING, method='SetAliases', args=[{ conn.self_handle: params['account'] }], handled=False)) assertEquals(params['account'], account_props.Get(cs.ACCOUNT, 'Nickname')) q.dbus_return(e.message, signature='')
def test(q, bus, mc): # For this test, 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": "*****@*****.**", "password": "******"}, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': FORBIDDEN_CTYPE, }, signature='sv') client = SimulatedClient(q, bus, 'Empathy', observe=[fixed_properties], approve=[fixed_properties], handle=[fixed_properties], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [client]) user_action_time = dbus.Int64(1238582606) 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': FORBIDDEN_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') q.expect('dbus-signal', path=cr.object_path, interface=cs.CR, signal='Failed', args=[cs.PERMISSION_DENIED, "No, you don't"])
def test(q, bus, mc): params = dbus.Dictionary( { "account": "*****@*****.**", "password": "******" }, signature='sv') (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) account_iface = dbus.Interface(account, cs.ACCOUNT) account_props = dbus.Interface(account, cs.PROPERTIES_IFACE) # Ensure that it's enabled but has offline RP and doesn't connect # automatically call_async(q, account_props, 'Set', cs.ACCOUNT, 'RequestedPresence', (dbus.UInt32(cs.PRESENCE_OFFLINE), 'offline', '')) q.expect('dbus-return', method='Set') call_async( q, account_props, 'Set', cs.ACCOUNT, 'AutomaticPresence', (dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Testing automatic presence')) q.expect('dbus-return', method='Set') q.expect( 'dbus-signal', signal='AccountPropertyChanged', predicate=lambda e: e.args[0].get('AutomaticPresence', (None, None, None))[1] == 'busy') call_async(q, account_props, 'Set', cs.ACCOUNT, 'ConnectAutomatically', False) q.expect('dbus-return', method='Set') call_async(q, account_props, 'Set', cs.ACCOUNT, 'Enabled', True) q.expect('dbus-return', method='Set') q.expect('dbus-signal', signal='AccountPropertyChanged', predicate=lambda e: e.args[0].get('Enabled')) # Requesting a channel will put us online user_action_time = dbus.Int64(1238582606) cd = bus.get_object(cs.CD, cs.CD_PATH) request = dbus.Dictionary( { cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.TargetID': 'juliet', }, signature='sv') call_async(q, cd, 'CreateChannel', account.object_path, request, user_action_time, "", dbus_interface=cs.CD) ret = q.expect('dbus-return', method='CreateChannel') request_path = ret.value[0] 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'] == "" assert request_props['Interfaces'] == [] # make sure RequestConnection doesn't get called until we Proceed events = [EventPattern('dbus-method-call', method='RequestConnection')] q.forbid_events(events) sync_dbus(bus, q, mc) q.unforbid_events(events) cr.Proceed(dbus_interface=cs.CR) e = q.expect('dbus-method-call', method='RequestConnection', args=['fakeprotocol', params], 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', '_', 'myself', has_presence=True) 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.CSR_NONE_SPECIFIED) conn.presence = dbus.Struct((cs.PRESENCE_AVAILABLE, 'available', ''), signature='uss') _, cm_request_call = q.expect_many( EventPattern('dbus-method-call', path=conn.object_path, interface=cs.CONN_IFACE_SIMPLE_PRESENCE, method='SetPresence', args=['busy', 'Testing automatic presence'], handled=True), EventPattern('dbus-method-call', path=conn.object_path, interface=cs.CONN_IFACE_REQUESTS, method='CreateChannel', args=[request], handled=False), ) q.dbus_emit(conn.object_path, cs.CONN_IFACE_SIMPLE_PRESENCE, 'PresencesChanged', { conn.self_handle: (dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Testing automatic presence') }, signature='a{u(uss)}') # 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, 'juliet') channel = SimulatedChannel(conn, channel_immutable) # this order of events is guaranteed by telepathy-spec (since 0.17.14) q.dbus_return(cm_request_call.message, channel.object_path, channel.immutable, signature='oa{sv}') channel.announce() # there's no handler, so it gets shot down q.expect('dbus-method-call', path=channel.object_path, method='Close', handled=True)
def test(q, bus, mc): params = dbus.Dictionary( { "account": "*****@*****.**", "password": "******" }, signature='sv') simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary( { cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, }, signature='sv') empathy_bus = dbus.bus.BusConnection() empathy_bus.set_exit_on_disconnect(False) # we'll disconnect later kopete_bus = dbus.bus.BusConnection() q.attach_to_bus(empathy_bus) q.attach_to_bus(kopete_bus) # Two clients want to observe, approve and handle channels empathy = SimulatedClient(q, empathy_bus, 'Empathy', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) kopete = SimulatedClient(q, kopete_bus, 'Kopete', observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False) # wait for MC to download the properties expect_client_setup(q, [empathy, kopete]) # subscribe to the OperationList interface (MC assumes that until this # property has been retrieved once, nobody cares) cd = bus.get_object(cs.CD, cs.CD_PATH) cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] channel_properties = dbus.Dictionary(text_fixed_properties, signature='sv') channel_properties[cs.CHANNEL + '.TargetID'] = 'juliet' channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.InitiatorID'] = 'juliet' channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'juliet') channel_properties[cs.CHANNEL + '.Requested'] = False channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') chan = SimulatedChannel(conn, channel_properties) chan.announce() # A channel dispatch operation is created e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') cdo_path = e.args[0] cdo_properties = e.args[1] assert cdo_properties[cs.CDO + '.Account'] == account.object_path assert cdo_properties[cs.CDO + '.Connection'] == conn.object_path assert cs.CDO + '.Interfaces' in cdo_properties handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] handlers.sort() assert handlers == [ cs.tp_name_prefix + '.Client.Empathy', cs.tp_name_prefix + '.Client.Kopete' ], handlers assert cs.CD_IFACE_OP_LIST in cd_props.Get(cs.CD, 'Interfaces') assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') ==\ [(cdo_path, cdo_properties)] cdo = bus.get_object(cs.CD, cdo_path) cdo_iface = dbus.Interface(cdo, cs.CDO) cdo_props_iface = dbus.Interface(cdo, cs.PROPERTIES_IFACE) assert cdo_props_iface.Get(cs.CDO, 'Interfaces') == \ cdo_properties[cs.CDO + '.Interfaces'] assert cdo_props_iface.Get(cs.CDO, 'Connection') == conn.object_path assert cdo_props_iface.Get(cs.CDO, 'Account') == account.object_path assert cdo_props_iface.Get(cs.CDO, 'Channels') == [(chan.object_path, channel_properties)] assert cdo_props_iface.Get(cs.CDO, 'PossibleHandlers') == \ cdo_properties[cs.CDO + '.PossibleHandlers'] # Both Observers are told about the new channel e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), ) assert e.args[0] == account.object_path, e.args assert e.args[1] == conn.object_path, e.args assert e.args[3] == cdo_path, e.args assert e.args[4] == [], e.args # no requests satisfied channels = e.args[2] assert len(channels) == 1, channels assert channels[0][0] == chan.object_path, channels assert channels[0][1] == channel_properties, channels assert k.args == e.args # Both Observers indicate that they are ready to proceed q.dbus_return(k.message, bus=empathy_bus, signature='') q.dbus_return(e.message, bus=kopete_bus, signature='') # The Approvers are next e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), ) assert e.args == [[(chan.object_path, channel_properties)], cdo_path, cdo_properties] assert k.args == e.args q.dbus_return(e.message, bus=empathy_bus, signature='') q.dbus_return(k.message, bus=kopete_bus, signature='') # Both Approvers now have a flashing icon or something, trying to get the # user's attention # Using an invalid Handler name should fail call_async(q, cdo_iface, 'HandleWith', cs.tp_name_prefix + '.The.Moon.On.A.Stick') q.expect('dbus-error', method='HandleWith') call_async(q, cdo_iface, 'HandleWith', cs.tp_name_prefix + '.Client.the moon on a stick') q.expect('dbus-error', method='HandleWith') # The user responds to Empathy first call_async(q, cdo_iface, 'HandleWith', cs.tp_name_prefix + '.Client.Empathy') # Empathy is asked to handle the channels e = q.expect('dbus-method-call', path=empathy.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) # Empathy accepts the channels q.dbus_return(e.message, bus=empathy_bus, signature='') q.expect_many( EventPattern('dbus-return', method='HandleWith'), EventPattern('dbus-signal', interface=cs.CDO, signal='Finished'), EventPattern('dbus-signal', interface=cs.CD_IFACE_OP_LIST, signal='DispatchOperationFinished'), ) # Now there are no more active channel dispatch operations assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] # Approve another channel using HandleWithTime() channel_properties = dbus.Dictionary(text_fixed_properties, signature='sv') channel_properties[cs.CHANNEL + '.TargetID'] = 'lucien' channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'lucien') channel_properties[cs.CHANNEL + '.InitiatorID'] = 'lucien' channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'lucien') channel_properties[cs.CHANNEL + '.Requested'] = False channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') chan = SimulatedChannel(conn, channel_properties) chan.announce() # A channel dispatch operation is created e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') cdo_path = e.args[0] cdo_properties = e.args[1] assert cdo_properties[cs.CDO + '.Account'] == account.object_path assert cdo_properties[cs.CDO + '.Connection'] == conn.object_path assert cs.CDO + '.Interfaces' in cdo_properties handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] handlers.sort() assert handlers == [ cs.tp_name_prefix + '.Client.Empathy', cs.tp_name_prefix + '.Client.Kopete' ], handlers assert cs.CD_IFACE_OP_LIST in cd_props.Get(cs.CD, 'Interfaces') assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') ==\ [(cdo_path, cdo_properties)] cdo = bus.get_object(cs.CD, cdo_path) cdo_iface = dbus.Interface(cdo, cs.CDO) cdo_props_iface = dbus.Interface(cdo, cs.PROPERTIES_IFACE) assert cdo_props_iface.Get(cs.CDO, 'Interfaces') == \ cdo_properties[cs.CDO + '.Interfaces'] assert cdo_props_iface.Get(cs.CDO, 'Connection') == conn.object_path assert cdo_props_iface.Get(cs.CDO, 'Account') == account.object_path assert cdo_props_iface.Get(cs.CDO, 'Channels') == [(chan.object_path, channel_properties)] assert cdo_props_iface.Get(cs.CDO, 'PossibleHandlers') == \ cdo_properties[cs.CDO + '.PossibleHandlers'] # Both Observers are told about the new channel e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), ) assert e.args[0] == account.object_path, e.args assert e.args[1] == conn.object_path, e.args assert e.args[3] == cdo_path, e.args assert e.args[4] == [], e.args # no requests satisfied channels = e.args[2] assert len(channels) == 1, channels assert channels[0][0] == chan.object_path, channels assert channels[0][1] == channel_properties, channels assert k.args == e.args # Both Observers indicate that they are ready to proceed q.dbus_return(k.message, bus=empathy_bus, signature='') q.dbus_return(e.message, bus=kopete_bus, signature='') # The Approvers are next e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), ) assert e.args == [[(chan.object_path, channel_properties)], cdo_path, cdo_properties] assert k.args == e.args q.dbus_return(e.message, bus=empathy_bus, signature='') q.dbus_return(k.message, bus=kopete_bus, signature='') # Both Approvers now have a flashing icon or something, trying to get the # user's attention # The user responds to Empathy first call_async(q, cdo_iface, 'HandleWithTime', cs.tp_name_prefix + '.Client.Empathy', 13) # Empathy is asked to handle the channels e = q.expect('dbus-method-call', path=empathy.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) account_path, conn_path, channels, requests, action_time, info = e.args assert action_time == 13 # Empathy accepts the channels q.dbus_return(e.message, bus=empathy_bus, signature='') q.expect_many( EventPattern('dbus-return', method='HandleWithTime'), EventPattern('dbus-signal', interface=cs.CDO, signal='Finished'), EventPattern('dbus-signal', interface=cs.CD_IFACE_OP_LIST, signal='DispatchOperationFinished'), ) # Now there are no more active channel dispatch operations assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] # From now on, it is an error to get HandleChannels (because we're # testing Claim()) forbidden = [ EventPattern('dbus-method-call', method='HandleChannels'), ] q.forbid_events(forbidden) # Another channel channel_properties = dbus.Dictionary(text_fixed_properties, signature='sv') channel_properties[cs.CHANNEL + '.TargetID'] = 'mercutio' channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'mercutio') channel_properties[cs.CHANNEL + '.InitiatorID'] = 'mercutio' channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'mercutio') channel_properties[cs.CHANNEL + '.Requested'] = False channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') claimed_chan = SimulatedChannel(conn, channel_properties) claimed_chan.announce() # A channel dispatch operation is created e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') cdo_path = e.args[0] cdo_properties = e.args[1] assert cdo_properties[cs.CDO + '.Account'] == account.object_path assert cdo_properties[cs.CDO + '.Connection'] == conn.object_path assert cs.CDO + '.Interfaces' in cdo_properties handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] handlers.sort() assert handlers == [ cs.tp_name_prefix + '.Client.Empathy', cs.tp_name_prefix + '.Client.Kopete' ], handlers assert cs.CD_IFACE_OP_LIST in cd_props.Get(cs.CD, 'Interfaces') assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') ==\ [(cdo_path, cdo_properties)] cdo = bus.get_object(cs.CD, cdo_path) cdo_iface = dbus.Interface(cdo, cs.CDO) # Both Observers are told about the new channel e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), ) assert e.args[0] == account.object_path, e.args assert e.args[1] == conn.object_path, e.args assert e.args[3] == cdo_path, e.args assert e.args[4] == [], e.args # no requests satisfied channels = e.args[2] assert len(channels) == 1, channels assert channels[0][0] == claimed_chan.object_path, channels assert channels[0][1] == channel_properties, channels assert k.args == e.args # Both Observers indicate that they are ready to proceed q.dbus_return(k.message, bus=kopete_bus, signature='') q.dbus_return(e.message, bus=empathy_bus, signature='') # The Approvers are next e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), ) assert e.args == [[(claimed_chan.object_path, channel_properties)], cdo_path, cdo_properties] assert k.args == e.args q.dbus_return(e.message, bus=empathy_bus, signature='') q.dbus_return(k.message, bus=kopete_bus, signature='') # Both Approvers now have a flashing icon or something, trying to get the # user's attention # The user responds to Empathy first, and Empathy decides it wants the # channel for itself empathy_cdo = empathy_bus.get_object(cdo.bus_name, cdo.object_path) empathy_cdo_iface = dbus.Interface(empathy_cdo, cs.CDO) call_async(q, empathy_cdo_iface, 'Claim') q.expect_many( EventPattern('dbus-signal', path=cdo_path, signal='Finished'), EventPattern('dbus-signal', path=cs.CD_PATH, signal='DispatchOperationFinished', args=[cdo_path]), EventPattern('dbus-return', method='Claim'), ) # Now there are no more active channel dispatch operations assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] # A third channel channel_properties = dbus.Dictionary(text_fixed_properties, signature='sv') channel_properties[cs.CHANNEL + '.TargetID'] = 'benvolio' channel_properties[cs.CHANNEL + '.TargetHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'benvolio') channel_properties[cs.CHANNEL + '.InitiatorID'] = 'benvolio' channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ conn.ensure_handle(cs.HT_CONTACT, 'benvolio') channel_properties[cs.CHANNEL + '.Requested'] = False channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') third_chan = SimulatedChannel(conn, channel_properties) third_chan.announce() # third_chan should not be closed q.unforbid_events(forbidden) forbidden.append( EventPattern('dbus-method-call', method='Close', path=third_chan.object_path)) q.forbid_events(forbidden) # A channel dispatch operation is created e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') cdo_path = e.args[0] cdo_properties = e.args[1] cdo = bus.get_object(cs.CD, cdo_path) cdo_iface = dbus.Interface(cdo, cs.CDO) e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.OBSERVER, method='ObserveChannels', handled=False), ) q.dbus_return(k.message, bus=kopete_bus, signature='') q.dbus_return(e.message, bus=empathy_bus, signature='') e, k = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), ) q.dbus_return(e.message, bus=empathy_bus, signature='') q.dbus_return(k.message, bus=kopete_bus, signature='') # Kopete closes this one kopete_cdo = kopete_bus.get_object(cdo.bus_name, cdo.object_path) kopete_cdo_iface = dbus.Interface(kopete_cdo, cs.CDO) call_async(q, kopete_cdo_iface, 'Claim') q.expect_many( EventPattern('dbus-signal', path=cdo_path, signal='Finished'), EventPattern('dbus-signal', path=cs.CD_PATH, signal='DispatchOperationFinished', args=[cdo_path]), EventPattern('dbus-return', method='Claim'), ) # Empathy crashes empathy.release_name() e = q.expect( 'dbus-signal', signal='NameOwnerChanged', predicate=( lambda e: e.args[0] == empathy.bus_name and e.args[2] == ''), ) empathy_unique_name = e.args[1] empathy_bus.flush() empathy_bus.close() # In response, the channels that were being handled by Empathy are closed. # Kopete's channel is *not* closed. q.expect_many( EventPattern('dbus-signal', signal='NameOwnerChanged', predicate=(lambda e: e.args[0] == empathy_unique_name and e.args[2] == '')), EventPattern('dbus-method-call', path=chan.object_path, method='Close'), EventPattern('dbus-method-call', path=claimed_chan.object_path, method='Close'), ) sync_dbus(bus, q, mc) q.unforbid_events(forbidden)