diff options
Diffstat (limited to 'tests/twisted')
97 files changed, 2747 insertions, 3022 deletions
diff --git a/tests/twisted/Makefile.am b/tests/twisted/Makefile.am index 26ac627b..7091bfa8 100644 --- a/tests/twisted/Makefile.am +++ b/tests/twisted/Makefile.am @@ -19,6 +19,7 @@ TWISTED_BASIC_TESTS = \ account-manager/recover-from-disconnect.py \ account-manager/req-conn-fails.py \ account-manager/request-online.py \ + account-manager/restricted-storage.py \ account-manager/service.py \ account-manager/update-parameters.py \ account-requests/cancel.py \ @@ -27,10 +28,8 @@ TWISTED_BASIC_TESTS = \ account/addressing.py \ capabilities/contact-caps.py \ dispatcher/already-has-channel.py \ - dispatcher/already-has-obsolete.py \ dispatcher/approver-fails.py \ dispatcher/bypass-approval.py \ - dispatcher/bypass-observers.py \ dispatcher/cancel.py \ dispatcher/capture-bundle.py \ dispatcher/cdo-claim.py \ @@ -75,9 +74,12 @@ TWISTED_BASIC_TESTS = \ # account-storage/*.py need their own instances. TWISTED_SPECIAL_BUILD_TESTS = \ account-manager/connectivity.py \ - account-manager/hidden.py \ - account-storage/default-keyring-storage.py \ - account-storage/diverted-storage.py + account-storage/diverted-storage.py \ + account-storage/5-12.py \ + account-storage/5-14.py \ + account-storage/create-new.py \ + account-storage/load-keyfiles.py \ + $(NULL) # Tests that are usually too slow to run. TWISTED_SLOW_TESTS = \ @@ -104,11 +106,10 @@ TWISTED_TESTS = \ TWISTED_OTHER_FILES = \ constants.py \ fakeaccountsservice.py \ - fakeclient.py \ - fakecm.py \ fakeconnectivity.py \ mctest.py \ servicetest.py \ + account-storage/storage_helper.py \ telepathy/clients/README \ telepathy/clients/AbiWord.client \ telepathy/clients/Logger.client \ @@ -122,6 +123,14 @@ TWISTED_OTHER_FILES = \ mc-twisted-tests.list: $(AM_V_GEN)echo $(TWISTED_BASIC_TESTS) $(TWISTED_SEPARATE_TESTS) > $@ +twisted-tests.test: Makefile + $(AM_V_GEN)( echo '[Test]'; \ + echo 'Exec=${twistedtestsdir}/run-test.sh'; \ + echo 'Type=session'; \ + echo 'Output=TAP' ) > $@.tmp + @chmod +x $@.tmp + @mv $@.tmp $@ + run-test.sh: run-test.sh.in Makefile $(AM_V_GEN)sed \ -e "s|[@]mctestsdir[@]|@mctestsdir@|g" \ @@ -130,6 +139,9 @@ run-test.sh: run-test.sh.in Makefile @chmod +x $@ if ENABLE_INSTALLED_TESTS +insttestdir = ${datadir}/installed-tests/telepathy-mission-control +nodist_insttest_DATA = twisted-tests.test + # Install files in each directory. They could be tests, pristine data files, # scripts or built source twistedtestsdir = @mctestsdir@/twisted @@ -147,13 +159,6 @@ nobase_nodist_twistedtests_DATA = \ $(NULL) endif - -if HAVE_MCE -HAVE_MCE_PYBOOL = True -else -HAVE_MCE_PYBOOL = False -endif - if HAVE_NM HAVE_NM_PYBOOL = True else @@ -162,13 +167,13 @@ endif config.py: Makefile $(AM_V_GEN) { \ - echo "HAVE_MCE = $(HAVE_MCE_PYBOOL)"; \ echo "HAVE_NM = $(HAVE_NM_PYBOOL)"; \ } > $@ BUILT_SOURCES = \ config.py \ mc-twisted-tests.list \ + twisted-tests.test \ run-test.sh \ $(NULL) @@ -177,7 +182,6 @@ AM_CFLAGS = $(ERROR_CFLAGS) plugins_list = \ mcp-plugin.la \ mcp-account-diversion.la \ - mcp-dbus-caller-permission.la \ libgiofakenetworkmonitor.la \ $(NULL) @@ -215,9 +219,6 @@ libgiofakenetworkmonitor_la_LDFLAGS = $(mcp_plugin_la_LDFLAGS) mcp_account_diversion_la_SOURCES = mcp-account-diversion.c mcp_account_diversion_la_LDFLAGS = $(mcp_plugin_la_LDFLAGS) -mcp_dbus_caller_permission_la_SOURCES = mcp-dbus-caller-permission.c -mcp_dbus_caller_permission_la_LDFLAGS = $(mcp_plugin_la_LDFLAGS) - # A debug version of the normal MC executable, which exits cleanly on # disconnection from D-Bus (so gcov info gets written out) noinst_PROGRAMS = mc-debug-server @@ -225,7 +226,7 @@ mc_debug_server_SOURCES = mc-debug-server.c mc_debug_server_LDADD = \ $(top_builddir)/src/libmcd-convenience.la -INCLUDES = \ +AM_CPPFLAGS = \ -I$(top_srcdir) -I$(top_builddir) \ -I$(top_srcdir)/src -I$(top_builddir)/src \ $(DBUS_CFLAGS) \ diff --git a/tests/twisted/account-manager/account-basics.py b/tests/twisted/account-manager/account-basics.py index 18b35cb2..4e643cc9 100644 --- a/tests/twisted/account-manager/account-basics.py +++ b/tests/twisted/account-manager/account-basics.py @@ -46,7 +46,7 @@ def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - (cm_name_ref, account) = create_fakecm_account(q, bus, mc, params) + (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) account_path = account.__dbus_object_path__ @@ -83,7 +83,6 @@ def test(q, bus, mc): interfaces = properties.get('Interfaces') assert cs.ACCOUNT_IFACE_AVATAR in interfaces, interfaces - assert cs.ACCOUNT_IFACE_NOKIA_CONDITIONS in interfaces, interfaces # sanity check for k in properties: @@ -174,32 +173,6 @@ def test(q, bus, mc): ) assert account_props.Get(cs.ACCOUNT, 'Nickname') == 'Joe Bloggs' - call_async(q, account_props, 'Set', cs.ACCOUNT_IFACE_NOKIA_CONDITIONS, - 'Condition', - dbus.Dictionary({':foo': 'bar'}, signature='ss')) - # there's no change notification for the Condition - q.expect_many( - EventPattern('dbus-return', method='Set'), - EventPattern('dbus-signal', - interface=cs.TEST_DBUS_ACCOUNT_PLUGIN_IFACE, - signal='DeferringSetAttribute', - args=[account_path, 'condition-:foo', 'bar']), - 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):], - {'condition-:foo': 'bar'}, - {'condition-:foo': 0}, # flags - []], - ), - ) - assert account_props.Get(cs.ACCOUNT_IFACE_NOKIA_CONDITIONS, - 'Condition') == {':foo': 'bar'} - assertEquals(dbus.Array(signature='o'), account_props.Get(cs.ACCOUNT, 'Supersedes')) call_async(q, account_props, 'Set', cs.ACCOUNT, 'Supersedes', @@ -271,16 +244,6 @@ def test(q, bus, mc): else: raise AssertionError('Setting %s with wrong type should fail' % p) - for p in ('Condition',): - try: - account_props.Set(cs.ACCOUNT_IFACE_NOKIA_CONDITIONS, 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) - # Make sure MC hasn't crashed yet, and make sure some properties are what # we expect them to be diff --git a/tests/twisted/account-manager/auto-connect.py b/tests/twisted/account-manager/auto-connect.py index a623902c..28cfb2ab 100644 --- a/tests/twisted/account-manager/auto-connect.py +++ b/tests/twisted/account-manager/auto-connect.py @@ -21,22 +21,20 @@ import dbus """ import os +import os.path import dbus import dbus.service from servicetest import EventPattern, tp_name_prefix, tp_path_prefix, \ call_async, assertEquals -from mctest import exec_test, SimulatedConnection, create_fakecm_account, MC +from mctest import (exec_test, SimulatedConnection, + SimulatedConnectionManager, MC) import constants as cs -cm_name_ref = dbus.service.BusName( - cs.tp_name_prefix + '.ConnectionManager.fakecm', bus=dbus.SessionBus()) - account_id = 'fakecm/fakeprotocol/jc_2edenton_40unatco_2eint' def preseed(q, bus, fake_accounts_service): - accounts_dir = os.environ['MC_ACCOUNT_DIR'] try: @@ -68,8 +66,12 @@ def preseed(q, bus, fake_accounts_service): 'password': r'\\\\ionstorm\\\\', }) - os.makedirs(accounts_dir + '/' + account_id) - avatar_bin = open(accounts_dir + '/' + account_id + '/avatar.bin', 'w') + avatar_filename = account_id + avatar_filename = avatar_filename.replace('/', '-') + '.avatar' + avatar_filename = (os.environ['XDG_DATA_HOME'] + + '/telepathy/mission-control/' + avatar_filename) + os.makedirs(os.path.dirname(avatar_filename)) + avatar_bin = open(avatar_filename, 'w') avatar_bin.write('Deus Ex') avatar_bin.close() @@ -78,6 +80,8 @@ def preseed(q, bus, fake_accounts_service): account_connections_file.close() def test(q, bus, unused, **kwargs): + simulated_cm = SimulatedConnectionManager(q, bus) + fake_accounts_service = kwargs['fake_accounts_service'] preseed(q, bus, fake_accounts_service) @@ -124,7 +128,7 @@ def test(q, bus, unused, **kwargs): assertEquals({}, prop_changed.args[0].get('ConnectionErrorDetails')) assertEquals(cs.CONN_STATUS_CONNECTING, prop_changed.args[0].get('ConnectionStatus')) - assertEquals(cs.CONN_STATUS_REASON_REQUESTED, + assertEquals(cs.CSR_REQUESTED, prop_changed.args[0].get('ConnectionStatusReason')) q.dbus_return(request_conn.message, conn.bus_name, conn.object_path, @@ -147,16 +151,16 @@ def test(q, bus, unused, **kwargs): assertEquals({}, prop_changed.args[0].get('ConnectionErrorDetails')) assertEquals(cs.CONN_STATUS_CONNECTING, prop_changed.args[0].get('ConnectionStatus')) - assertEquals(cs.CONN_STATUS_REASON_REQUESTED, + assertEquals(cs.CSR_REQUESTED, prop_changed.args[0].get('ConnectionStatusReason')) props = account.GetAll(cs.ACCOUNT, dbus_interface=cs.PROPERTIES_IFACE) assert props['Connection'] == conn.object_path assert props['ConnectionStatus'] == cs.CONN_STATUS_CONNECTING - assert props['ConnectionStatusReason'] == cs.CONN_STATUS_REASON_REQUESTED + assert props['ConnectionStatusReason'] == cs.CSR_REQUESTED print "becoming connected" - conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CONN_STATUS_REASON_NONE) + conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) set_aliases, set_presence, set_avatar, prop_changed = q.expect_many( EventPattern('dbus-method-call', @@ -183,11 +187,11 @@ def test(q, bus, unused, **kwargs): assertEquals({}, prop_changed.args[0].get('ConnectionErrorDetails')) assertEquals(cs.CONN_STATUS_CONNECTED, prop_changed.args[0].get('ConnectionStatus')) - assertEquals(cs.CONN_STATUS_REASON_REQUESTED, + assertEquals(cs.CSR_REQUESTED, prop_changed.args[0].get('ConnectionStatusReason')) assert account.Get(cs.ACCOUNT, 'CurrentPresence', - dbus_interface=cs.PROPERTIES_IFACE) == (cs.PRESENCE_TYPE_AVAILABLE, + dbus_interface=cs.PROPERTIES_IFACE) == (cs.PRESENCE_AVAILABLE, 'available', 'My vision is augmented') q.dbus_return(set_aliases.message, signature='') diff --git a/tests/twisted/account-manager/avatar-refresh.py b/tests/twisted/account-manager/avatar-refresh.py index fe75d3a3..d914c439 100644 --- a/tests/twisted/account-manager/avatar-refresh.py +++ b/tests/twisted/account-manager/avatar-refresh.py @@ -28,12 +28,10 @@ import dbus.service from servicetest import (EventPattern, tp_name_prefix, tp_path_prefix, call_async, assertEquals, sync_dbus) -from mctest import exec_test, SimulatedConnection, create_fakecm_account, MC +from mctest import (exec_test, SimulatedConnection, + SimulatedConnectionManager, MC) import constants as cs -cm_name_ref = dbus.service.BusName( - cs.tp_name_prefix + '.ConnectionManager.fakecm', bus=dbus.SessionBus()) - class Account(object): def __init__(self, fake_accounts_service, accounts_dir, avatars_persist, server_delays, local_avatar, remote_avatar): @@ -92,15 +90,6 @@ class Account(object): avatar_bin = open(avatar_filename, 'w') avatar_bin.write(local_avatar) avatar_bin.close() - elif not avatars_persist: - self.avatar_location = 'old' - # exercise migration from ~/.mission-control in a - # situation where MC should "win" - os.makedirs(accounts_dir + '/' + self.id) - avatar_bin = open( - accounts_dir + '/' + self.id + '/avatar.bin', 'w') - avatar_bin.write(local_avatar) - avatar_bin.close() else: # store it in the normal location self.avatar_location = 'home' @@ -187,23 +176,21 @@ class Account(object): q.dbus_return(e.message, conn.bus_name, conn.object_path, signature='so') - forbidden = [] - if self.winner != 'MC': - forbidden.append( - EventPattern('dbus-method-call', method='SetAvatar')) + q.forbid_events([ + EventPattern('dbus-method-call', method='SetAvatar'), + ]) if self.winner != 'service': - forbidden.append( + q.forbid_events([ EventPattern('dbus-signal', signal='AvatarChanged', - path=account_path)) - - q.forbid_events(forbidden) + path=account_path), + ]) q.expect('dbus-method-call', method='Connect', path=conn.object_path, handled=True, interface=cs.CONN) - conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CONN_STATUS_REASON_NONE) + conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) if self.winner == 'MC': # MC should upload the avatar. @@ -256,24 +243,13 @@ class Account(object): byte_arrays=True) == conn.avatar sync_dbus(bus, q, mc) - q.unforbid_events(forbidden) + q.unforbid_all() if self.local_avatar: self.test_migration(bus, q, conn, account_proxy) def test_migration(self, bus, q, conn, account_proxy): - if self.avatar_location == 'old': - # The avatar got migrated to the new location. - assert not os.path.exists(os.environ['MC_ACCOUNT_DIR'] + '/' + - self.id + '/avatar.bin') - assert not os.path.exists(os.environ['MC_ACCOUNT_DIR'] + '/fakecm') - avatar_filename = self.id - avatar_filename = avatar_filename.replace('/', '-') + '.avatar' - avatar_filename = (os.environ['XDG_DATA_HOME'] + - '/telepathy/mission-control/' + avatar_filename) - assertEquals(conn.avatar[0], ''.join(open(avatar_filename, - 'r').readlines())) - elif self.avatar_location == 'datadir' and self.winner == 'service': + if self.avatar_location == 'datadir' and self.winner == 'service': # The avatar wasn't deleted from $XDG_DATA_DIRS, but it was # overridden. assert not os.path.exists(os.environ['MC_ACCOUNT_DIR'] + '/' + @@ -359,6 +335,8 @@ def preseed(q, bus, fake_accounts_service): return accounts def test(q, bus, unused, **kwargs): + simulated_cm = SimulatedConnectionManager(q, bus) + fake_accounts_service = kwargs['fake_accounts_service'] accounts = preseed(q, bus, fake_accounts_service) diff --git a/tests/twisted/account-manager/avatar.py b/tests/twisted/account-manager/avatar.py index 9677e8a5..b31ab975 100644 --- a/tests/twisted/account-manager/avatar.py +++ b/tests/twisted/account-manager/avatar.py @@ -29,7 +29,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "me@example.com", "password": "secrecy"}, signature='sv') - (cm_name_ref, account) = create_fakecm_account(q, bus, mc, params) + (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) @@ -162,10 +162,8 @@ def test(q, bus, mc): interface=cs.TEST_DBUS_ACCOUNT_PLUGIN_IFACE, signal='DeferringSetAttribute', args=[account.object_path, 'AvatarMime', '']), - ) - q.expect('dbus-signal', path=account.object_path, - interface=cs.ACCOUNT_IFACE_AVATAR, signal='AvatarChanged') - q.expect_many( + EventPattern('dbus-signal', path=account.object_path, + interface=cs.ACCOUNT_IFACE_AVATAR, signal='AvatarChanged'), EventPattern('dbus-signal', interface=cs.TEST_DBUS_ACCOUNT_PLUGIN_IFACE, signal='CommittingOne', diff --git a/tests/twisted/account-manager/backend-makes-changes.py b/tests/twisted/account-manager/backend-makes-changes.py index 89eb4c1d..a4caeac0 100644 --- a/tests/twisted/account-manager/backend-makes-changes.py +++ b/tests/twisted/account-manager/backend-makes-changes.py @@ -34,7 +34,7 @@ def test(q, bus, mc, fake_accounts_service=None, **kwargs): {}, # attr flags {'account': 'ezio@firenze.fic', 'password': 'nothing is true'}, {}, # untyped parameters - {'password': cs.PARAM_FLAG_SECRET}) # param flags + {'password': cs.PARAM_SECRET}) # param flags q.expect_many( EventPattern('dbus-signal', path=cs.TEST_DBUS_ACCOUNT_SERVICE_PATH, @@ -47,7 +47,8 @@ def test(q, bus, mc, fake_accounts_service=None, **kwargs): {'account': 'ezio@firenze.fic', 'password': 'nothing is true'}, {}, - {'account': 0, 'password': cs.PARAM_FLAG_SECRET}]), + {'account': 0, 'password': cs.PARAM_SECRET}, + 0]), EventPattern('dbus-signal', path=cs.AM_PATH, signal='AccountValidityChanged', @@ -184,14 +185,14 @@ def test(q, bus, mc, fake_accounts_service=None, **kwargs): account.Properties.Get(cs.ACCOUNT, 'Supersedes')) fake_accounts_service.update_attributes(account_tail, - {'AutomaticPresence': (dbus.UInt32(cs.PRESENCE_TYPE_HIDDEN), 'hidden', + {'AutomaticPresence': (dbus.UInt32(cs.PRESENCE_HIDDEN), 'hidden', 'in a haystack or something')}) q.expect_many( EventPattern('dbus-signal', path=cs.TEST_DBUS_ACCOUNT_SERVICE_PATH, signal='AttributesChanged', args=[account_tail, - {'AutomaticPresence': (cs.PRESENCE_TYPE_HIDDEN, + {'AutomaticPresence': (cs.PRESENCE_HIDDEN, 'hidden', 'in a haystack or something')}, {'AutomaticPresence': 0}, @@ -201,14 +202,14 @@ def test(q, bus, mc, fake_accounts_service=None, **kwargs): signal='AccountPropertyChanged', interface=cs.ACCOUNT, args=[{'AutomaticPresence': - (cs.PRESENCE_TYPE_HIDDEN, 'hidden', + (cs.PRESENCE_HIDDEN, 'hidden', 'in a haystack or something')}]), EventPattern('dbus-signal', path=cs.TEST_DBUS_ACCOUNT_PLUGIN_PATH, signal='AttributeChanged', args=[account_path, 'AutomaticPresence']), ) - assertEquals((cs.PRESENCE_TYPE_HIDDEN, 'hidden', + assertEquals((cs.PRESENCE_HIDDEN, 'hidden', 'in a haystack or something'), account.Properties.Get(cs.ACCOUNT, 'AutomaticPresence')) @@ -276,13 +277,13 @@ def test(q, bus, mc, fake_accounts_service=None, **kwargs): account.Properties.Get(cs.ACCOUNT, 'Service')) fake_accounts_service.update_parameters(account_tail, { - 'password': 'high profile'}, flags={'password': cs.PARAM_FLAG_SECRET}) + 'password': 'high profile'}, flags={'password': cs.PARAM_SECRET}) q.expect_many( EventPattern('dbus-signal', path=cs.TEST_DBUS_ACCOUNT_SERVICE_PATH, signal='ParametersChanged', args=[account_tail, {'password': 'high profile'}, - {}, {'password': cs.PARAM_FLAG_SECRET}, []]), + {}, {'password': cs.PARAM_SECRET}, []]), EventPattern('dbus-signal', path=account_path, signal='AccountPropertyChanged', @@ -296,13 +297,13 @@ def test(q, bus, mc, fake_accounts_service=None, **kwargs): ) fake_accounts_service.update_parameters(account_tail, untyped={ - 'password': r'\\\n'}, flags={'password': cs.PARAM_FLAG_SECRET}) + 'password': r'\\\n'}, flags={'password': cs.PARAM_SECRET}) q.expect_many( EventPattern('dbus-signal', path=cs.TEST_DBUS_ACCOUNT_SERVICE_PATH, signal='ParametersChanged', args=[account_tail, {}, {'password': r'\\\n'}, - {'password': cs.PARAM_FLAG_SECRET}, []]), + {'password': cs.PARAM_SECRET}, []]), EventPattern('dbus-signal', path=account_path, signal='AccountPropertyChanged', diff --git a/tests/twisted/account-manager/bad-cm.py b/tests/twisted/account-manager/bad-cm.py index 74277b46..008ac605 100644 --- a/tests/twisted/account-manager/bad-cm.py +++ b/tests/twisted/account-manager/bad-cm.py @@ -22,11 +22,12 @@ import dbus from servicetest import call_async, assertEquals, assertContains -from mctest import exec_test, AccountManager +from mctest import (exec_test, SimulatedConnectionManager, AccountManager) import constants as cs def test(q, bus, mc): am = AccountManager(bus) + simulated_cm = SimulatedConnectionManager(q, bus) def call_create(cm='fakecm', protocol='fakeprotocol', parameters=None): if parameters is None: @@ -74,5 +75,13 @@ def test(q, bus, mc): assertEquals(cs.INVALID_ARGUMENT, e.name) assertContains("password", e.message) + # Create an account that will fail IdentifyAccount + call_create(parameters={ "account": "", + "password": "ohai", + }) + e = q.expect('dbus-error', method='CreateAccount') + assertEquals(cs.INVALID_HANDLE, e.name) + assertContains("Invalid account name", e.message) + if __name__ == '__main__': exec_test(test, {}) diff --git a/tests/twisted/account-manager/connectivity.py b/tests/twisted/account-manager/connectivity.py index 8d80c1d4..1e378dc4 100644 --- a/tests/twisted/account-manager/connectivity.py +++ b/tests/twisted/account-manager/connectivity.py @@ -46,7 +46,7 @@ def test(q, bus, mc): {"account": "yum yum network manager", "password": "boo boo connman (although your API *is* simpler)", }, signature='sv') - (cm_name_ref, account) = create_fakecm_account(q, bus, mc, params) + (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) # While we're not connected to the internet, RequestConnection should not # be called. @@ -56,13 +56,13 @@ def test(q, bus, mc): q.forbid_events(request_connection_event) account.Properties.Set(cs.ACCOUNT, 'RequestedPresence', - (dbus.UInt32(cs.PRESENCE_TYPE_BUSY), 'busy', 'hlaghalgh')) + (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_TYPE_BUSY), 'busy', 'gtfo') + 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') @@ -149,7 +149,7 @@ def test(q, bus, mc): # 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_TYPE_OFFLINE), 'offline', '')) + (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) diff --git a/tests/twisted/account-manager/crashy-cm.py b/tests/twisted/account-manager/crashy-cm.py index 2eebeb8b..ca8f0ae5 100644 --- a/tests/twisted/account-manager/crashy-cm.py +++ b/tests/twisted/account-manager/crashy-cm.py @@ -38,14 +38,14 @@ def test(q, bus, mc): {"account": "someguy@example.com", "password": "secrecy", }, signature='sv') - (cm_name_ref, account) = create_fakecm_account(q, bus, mc, params, + (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_TYPE_BUSY), 'busy', 'Fixing MC bugs'), + (dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Fixing MC bugs'), signature='uss') account.Properties.Set(cs.ACCOUNT, 'RequestedPresence', presence) @@ -65,11 +65,11 @@ def test(q, bus, mc): path=conn.object_path, handled=True) # Connect succeeds - conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CONN_STATUS_REASON_NONE) + conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) # CM crashes conn.release_name() - del cm_name_ref + simulated_cm.release_name() cm_bus.flush() cm_bus.close() @@ -80,7 +80,7 @@ def test(q, bus, mc): assertEquals('/', changed['Connection']) assertEquals(cs.CONN_STATUS_DISCONNECTED, changed['ConnectionStatus']) # In the absence of a better code, None will have to do. - assertEquals(cs.CONN_STATUS_REASON_NONE, changed['ConnectionStatusReason']) + assertEquals(cs.CSR_NONE_SPECIFIED, changed['ConnectionStatusReason']) # And NoReply will do as “it crashed”. assertEquals(cs.DBUS_ERROR_NO_REPLY, changed['ConnectionError']) diff --git a/tests/twisted/account-manager/create-auto-connect.py b/tests/twisted/account-manager/create-auto-connect.py index fa2cb470..45acda05 100644 --- a/tests/twisted/account-manager/create-auto-connect.py +++ b/tests/twisted/account-manager/create-auto-connect.py @@ -28,7 +28,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "smcv@example.com", "password": "secrecy"}, signature='sv') - (cm_name_ref, account) = create_fakecm_account(q, bus, mc, params) + (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) @@ -36,11 +36,11 @@ def test(q, bus, mc): # Ensure that it's enabled but has offline RP call_async(q, account_props, 'Set', cs.ACCOUNT, 'RequestedPresence', - (dbus.UInt32(cs.PRESENCE_TYPE_OFFLINE), 'offline', '')) + (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_TYPE_BUSY), 'busy', + (dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Testing automatic presence')) q.expect('dbus-return', method='Set') q.expect('dbus-signal', signal='AccountPropertyChanged', diff --git a/tests/twisted/account-manager/create-twice.py b/tests/twisted/account-manager/create-twice.py index 2f0c0e0c..3f1b8e20 100644 --- a/tests/twisted/account-manager/create-twice.py +++ b/tests/twisted/account-manager/create-twice.py @@ -22,7 +22,7 @@ import dbus.service from servicetest import EventPattern, tp_name_prefix, tp_path_prefix, \ call_async -from mctest import exec_test, create_fakecm_account, get_account_manager +from mctest import exec_test, SimulatedConnectionManager, get_account_manager import constants as cs def test(q, bus, mc): @@ -35,8 +35,7 @@ def test(q, bus, mc): params = dbus.Dictionary({"account": "create-twice", "password": "secrecy"}, signature='sv') - cm_name_ref = dbus.service.BusName(cs.tp_name_prefix + - '.ConnectionManager.fakecm', bus=bus) + simulated_cm = SimulatedConnectionManager(q, bus) account_manager = bus.get_object(cs.AM, cs.AM_PATH) am_iface = dbus.Interface(account_manager, cs.AM) diff --git a/tests/twisted/account-manager/create-with-properties.py b/tests/twisted/account-manager/create-with-properties.py index 6e208806..fb276c48 100644 --- a/tests/twisted/account-manager/create-with-properties.py +++ b/tests/twisted/account-manager/create-with-properties.py @@ -22,7 +22,7 @@ import dbus.service from servicetest import EventPattern, tp_name_prefix, tp_path_prefix, \ call_async, assertEquals, assertContains -from mctest import exec_test, create_fakecm_account, AccountManager +from mctest import (exec_test, SimulatedConnectionManager, AccountManager) import constants as cs def test(q, bus, mc): @@ -45,33 +45,29 @@ def test(q, bus, mc): assert (cs.ACCOUNT + '.Nickname') in supported assert (cs.ACCOUNT + '.ConnectAutomatically') in supported assert (cs.ACCOUNT_IFACE_AVATAR + '.Avatar') in supported - assert (cs.ACCOUNT_IFACE_NOKIA_CONDITIONS + '.Condition') in supported assert (cs.ACCOUNT + '.RequestedPresence') in supported assert (cs.ACCOUNT + '.Supersedes') in supported assertContains(cs.ACCOUNT + '.Service', supported) - params = dbus.Dictionary({"account": "anarki@example.com", + params = dbus.Dictionary({"account": "aNaRkI@eXaMpLe.CoM", "password": "secrecy"}, signature='sv') - cm_name_ref = dbus.service.BusName(cs.tp_name_prefix + - '.ConnectionManager.fakecm', bus=bus) + simulated_cm = SimulatedConnectionManager(q, bus) creation_properties = dbus.Dictionary({ cs.ACCOUNT + '.Enabled': True, cs.ACCOUNT + '.AutomaticPresence': dbus.Struct(( - dbus.UInt32(cs.PRESENCE_TYPE_BUSY), + dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Exploding'), signature='uss'), cs.ACCOUNT + '.RequestedPresence': dbus.Struct(( - dbus.UInt32(cs.PRESENCE_TYPE_AWAY), + dbus.UInt32(cs.PRESENCE_AWAY), 'away', 'Respawning'), signature='uss'), cs.ACCOUNT + '.Icon': 'quake3arena', cs.ACCOUNT + '.Nickname': 'AnArKi', cs.ACCOUNT + '.ConnectAutomatically': True, cs.ACCOUNT_IFACE_AVATAR + '.Avatar': (dbus.ByteArray('foo'), 'image/jpeg'), - cs.ACCOUNT_IFACE_NOKIA_CONDITIONS + '.Condition': - dbus.Dictionary({ 'has-quad-damage': ':y' }, signature='ss'), cs.ACCOUNT + '.Supersedes': dbus.Array([ cs.ACCOUNT_PATH_PREFIX + 'q1/q1/Ranger', cs.ACCOUNT_PATH_PREFIX + 'q2/q2/Grunt', @@ -98,6 +94,9 @@ def test(q, bus, mc): ) account_path = ret.value[0] assert am_signal.args == [account_path, True], am_signal.args + # We called IdentifyAccount, which normalized the silly account name. + # The _xx hex-escaping and the trailing digit are implementation details. + assert account_path.endswith('/anarki_40example_2ecom0'), account_path assert account_path is not None @@ -107,10 +106,10 @@ def test(q, bus, mc): account_props = dbus.Interface(account, cs.PROPERTIES_IFACE) properties = account_props.GetAll(cs.ACCOUNT) - assert properties.get('AutomaticPresence') == (cs.PRESENCE_TYPE_BUSY, + assert properties.get('AutomaticPresence') == (cs.PRESENCE_BUSY, 'busy', 'Exploding'), \ properties.get('AutomaticPresence') - assert properties.get('RequestedPresence') == (cs.PRESENCE_TYPE_AWAY, + assert properties.get('RequestedPresence') == (cs.PRESENCE_AWAY, 'away', 'Respawning'), \ properties.get('RequestedPresence') assert properties.get('ConnectAutomatically') == True, \ @@ -135,11 +134,6 @@ def test(q, bus, mc): assert properties.get('Avatar') == ([ord('f'), ord('o'), ord('o')], 'image/jpeg') - properties = account_props.GetAll(cs.ACCOUNT_IFACE_NOKIA_CONDITIONS) - assert properties.get('Condition') == { - 'has-quad-damage': ':y', - } - # tests for errors when creating an account creation_properties2 = creation_properties.copy() diff --git a/tests/twisted/account-manager/device-idle.py b/tests/twisted/account-manager/device-idle.py index 196b6a04..dcc76ec9 100644 --- a/tests/twisted/account-manager/device-idle.py +++ b/tests/twisted/account-manager/device-idle.py @@ -82,8 +82,8 @@ def _create_and_enable(q, bus, mc, account_name, power_saving_supported, extra_interfaces = [cs.CONN_IFACE_POWER_SAVING] params = dbus.Dictionary({"account": account_name, "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) - conn = enable_fakecm_account(q, bus, mc, account, params, has_requests=False, + 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) diff --git a/tests/twisted/account-manager/enable-auto-connect.py b/tests/twisted/account-manager/enable-auto-connect.py index 2cb91c31..d8ff3aee 100644 --- a/tests/twisted/account-manager/enable-auto-connect.py +++ b/tests/twisted/account-manager/enable-auto-connect.py @@ -28,7 +28,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "smcv@example.com", "password": "secrecy"}, signature='sv') - (cm_name_ref, account) = create_fakecm_account(q, bus, mc, params) + (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) @@ -36,11 +36,11 @@ def test(q, bus, mc): # Ensure that it's enabled but has offline RP call_async(q, account_props, 'Set', cs.ACCOUNT, 'RequestedPresence', - (dbus.UInt32(cs.PRESENCE_TYPE_OFFLINE), 'offline', '')) + (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_TYPE_BUSY), 'busy', + (dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Testing automatic presence')) q.expect('dbus-return', method='Set') q.expect('dbus-signal', signal='AccountPropertyChanged', diff --git a/tests/twisted/account-manager/enable.py b/tests/twisted/account-manager/enable.py index 50e489d1..db659f3b 100644 --- a/tests/twisted/account-manager/enable.py +++ b/tests/twisted/account-manager/enable.py @@ -28,13 +28,13 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "smcv@example.com", "password": "secrecy"}, signature='sv') - (cm_name_ref, account) = create_fakecm_account(q, bus, mc, params) + (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_TYPE_OFFLINE), 'offline', '')) + (dbus.UInt32(cs.PRESENCE_OFFLINE), 'offline', '')) q.expect('dbus-return', method='Set') call_async(q, account_props, 'Set', cs.ACCOUNT, 'Enabled', False) @@ -45,7 +45,7 @@ def test(q, bus, mc): q.expect('dbus-return', method='Set') call_async(q, account_props, 'Set', cs.ACCOUNT, 'RequestedPresence', - (dbus.UInt32(cs.PRESENCE_TYPE_BUSY), 'busy', 'Testing Enabled')) + (dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Testing Enabled')) q.expect('dbus-return', method='Set') # Go online by setting Enabled diff --git a/tests/twisted/account-manager/hidden.py b/tests/twisted/account-manager/hidden.py deleted file mode 100644 index 9e9351b0..00000000 --- a/tests/twisted/account-manager/hidden.py +++ /dev/null @@ -1,110 +0,0 @@ -# vim: set fileencoding=utf-8 : thanks python! you've been great -# Copyright © 2010 Nokia Corporation -# Copyright © 2010 Collabora Ltd. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA - -from mctest import ( - exec_test, create_fakecm_account, Account, AccountManager, - tell_mc_to_die, resuscitate_mc, - ) -from servicetest import ( - EventPattern, assertEquals, assertContains, assertDoesNotContain, - call_async, - ) -import constants as cs - -def test_unhidden_account(q, bus, mc): - """ - Check that accounts don't default to being hidden, and don't show up in the - lists of hidden accounts. - """ - am = AccountManager(bus) - - params = { "account": "oh", "password": "hai" } - (cm_name_ref, account) = create_fakecm_account(q, bus, mc, params) - - assert not account.Properties.Get(cs.ACCOUNT_IFACE_HIDDEN, 'Hidden') - - am_hidden_props = am.Properties.GetAll(cs.AM_IFACE_HIDDEN) - assertEquals([], am_hidden_props['ValidHiddenAccounts']) - assertEquals([], am_hidden_props['InvalidHiddenAccounts']) - -def test_create_hidden_account(q, bus, mc): - """ - Check that a newly-created hidden account does not show up on the main - AccountManager interface, but does show up on AM.I.Hidden, has its - Hidden property set to True, and can be removed. - """ - am = AccountManager(bus) - - call_async(q, am.Properties, 'Get', cs.AM, - 'SupportedAccountProperties') - supported = q.expect('dbus-return', method='Get').value[0] - assertContains(cs.ACCOUNT_IFACE_HIDDEN + '.Hidden', supported) - - # Make a new hidden account, and check that it really is hidden. - params = { "account": "aperture@porti.co", "password": "tollgate" } - properties = { cs.ACCOUNT_IFACE_HIDDEN + '.Hidden': True } - - q.forbid_events([ - EventPattern('dbus-signal', path=cs.AM_PATH, - signal='AccountValidityChanged', interface=cs.AM), - ]) - cm_name_ref, account = create_fakecm_account(q, bus, mc, params, properties) - - valid_accounts = am.Properties.Get(cs.AM, 'ValidAccounts') - assertDoesNotContain(account.object_path, valid_accounts) - - valid_hidden_accounts = am.Properties.Get(cs.AM_IFACE_HIDDEN, - 'ValidHiddenAccounts') - assertContains(account.object_path, valid_hidden_accounts) - - # Blow MC away, revive it, and check that the account is still hidden. - tell_mc_to_die(q, bus) - am, properties, interfaces = resuscitate_mc(q, bus, mc) - account = Account(bus, account.object_path) - - assert account.Properties.Get(cs.ACCOUNT_IFACE_HIDDEN, 'Hidden') - - assertDoesNotContain(account.object_path, properties['ValidAccounts']) - - valid_hidden_accounts = am.Properties.Get(cs.AM_IFACE_HIDDEN, - 'ValidHiddenAccounts') - assertContains(account.object_path, valid_hidden_accounts) - - # Delete the account, and check that its removal is signalled only on - # AM.I.Hidden, not on the main AM interface. - q.forbid_events([ - EventPattern('dbus-signal', path=cs.AM_PATH, - signal='AccountRemoved', interface=cs.AM, - args=[account.object_path]), - ]) - - account.Remove() - q.expect_many( - EventPattern('dbus-signal', path=cs.AM_PATH, - signal='HiddenAccountRemoved', interface=cs.AM_IFACE_HIDDEN), - EventPattern('dbus-signal', path=account.object_path, - signal='Removed', interface=cs.ACCOUNT), - ) - -def test(q, bus, mc): - test_unhidden_account(q, bus, mc) - test_create_hidden_account(q, bus, mc) - -if __name__ == '__main__': - exec_test(test, {}, timeout=10) diff --git a/tests/twisted/account-manager/irc.py b/tests/twisted/account-manager/irc.py index 2b249f19..0d0de71f 100644 --- a/tests/twisted/account-manager/irc.py +++ b/tests/twisted/account-manager/irc.py @@ -32,7 +32,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "brucewayne", "password": "secrecy"}, signature='sv') - (cm_name_ref, account) = create_fakecm_account(q, bus, mc, params) + (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) @@ -64,7 +64,7 @@ def test(q, bus, mc): interface=cs.ACCOUNT, predicate=lambda e: e.args[0].get('CurrentPresence') == - (cs.PRESENCE_TYPE_UNSET, '', '')), + (cs.PRESENCE_UNSET, '', '')), ] conn, get_aliases, set_aliases, _ = enable_fakecm_account(q, bus, mc, diff --git a/tests/twisted/account-manager/make-valid.py b/tests/twisted/account-manager/make-valid.py index 7c1df852..6e7ea34e 100644 --- a/tests/twisted/account-manager/make-valid.py +++ b/tests/twisted/account-manager/make-valid.py @@ -27,12 +27,10 @@ import dbus.service from servicetest import EventPattern, tp_name_prefix, tp_path_prefix, \ call_async, sync_dbus -from mctest import exec_test, SimulatedConnection, create_fakecm_account, MC +from mctest import (exec_test, SimulatedConnection, create_fakecm_account, MC, + SimulatedConnectionManager) import constants as cs -cm_name_ref = dbus.service.BusName( - cs.tp_name_prefix + '.ConnectionManager.fakecm', bus=dbus.SessionBus()) - account1_id = 'fakecm/fakeprotocol/jc_2edenton_40unatco_2eint' account2_id = 'fakecm/fakeprotocol/jc_2edenton_40example_2ecom' @@ -95,6 +93,7 @@ def preseed(q, bus, fake_accounts_service): account_connections_file.close() def test(q, bus, unused, **kwargs): + simulated_cm = SimulatedConnectionManager(q, bus) # make sure RequestConnection doesn't get called yet events = [EventPattern('dbus-method-call', method='RequestConnection')] @@ -169,7 +168,7 @@ def test(q, bus, unused, **kwargs): q.expect('dbus-method-call', method='Connect', path=conn.object_path, handled=True, interface=cs.CONN) - conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CONN_STATUS_REASON_NONE) + conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) set_presence, e = q.expect_many( EventPattern('dbus-method-call', path=conn.object_path, @@ -181,7 +180,7 @@ def test(q, bus, unused, **kwargs): and e.args[0]['CurrentPresence'][2] != ''), ) - assert e.args[0]['CurrentPresence'] == (cs.PRESENCE_TYPE_AVAILABLE, + assert e.args[0]['CurrentPresence'] == (cs.PRESENCE_AVAILABLE, 'available', 'My vision is augmented') # Request an online presence on account 2, then make it valid @@ -191,7 +190,7 @@ def test(q, bus, unused, **kwargs): account_path = (cs.tp_path_prefix + '/Account/' + account2_id) account = bus.get_object(cs.MC, account_path) - requested_presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_TYPE_BUSY), + requested_presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Talking to Illuminati')) account.Set(cs.ACCOUNT, 'RequestedPresence', dbus.Struct(requested_presence, variant_level=1), @@ -221,7 +220,7 @@ def test(q, bus, unused, **kwargs): q.expect('dbus-method-call', method='Connect', path=conn.object_path, handled=True, interface=cs.CONN) - conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CONN_STATUS_REASON_NONE) + conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) set_presence = q.expect('dbus-method-call', path=conn.object_path, interface=cs.CONN_IFACE_SIMPLE_PRESENCE, method='SetPresence', @@ -232,7 +231,7 @@ def test(q, bus, unused, **kwargs): predicate=lambda e: 'CurrentPresence' in e.args[0] and e.args[0]['CurrentPresence'][1] == 'busy') - assert e.args[0]['CurrentPresence'] == (cs.PRESENCE_TYPE_BUSY, + assert e.args[0]['CurrentPresence'] == (cs.PRESENCE_BUSY, 'busy', 'Talking to Illuminati') if __name__ == '__main__': diff --git a/tests/twisted/account-manager/nickname.py b/tests/twisted/account-manager/nickname.py index b128942c..e10342d3 100644 --- a/tests/twisted/account-manager/nickname.py +++ b/tests/twisted/account-manager/nickname.py @@ -28,7 +28,7 @@ import constants as cs def test(q, bus, mc, nickname): params = dbus.Dictionary({"account": "wjt@example.com", "password": "secrecy"}, signature='sv') - (cm_name_ref, account) = create_fakecm_account(q, bus, mc, params) + (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) diff --git a/tests/twisted/account-manager/param-types.py b/tests/twisted/account-manager/param-types.py index 8dafd7f1..68eff808 100644 --- a/tests/twisted/account-manager/param-types.py +++ b/tests/twisted/account-manager/param-types.py @@ -22,13 +22,13 @@ import dbus.service from servicetest import EventPattern, tp_name_prefix, tp_path_prefix, \ call_async -from mctest import exec_test, create_fakecm_account, get_account_manager +from mctest import (exec_test, create_fakecm_account, get_account_manager, + SimulatedConnectionManager) import constants as cs def test(q, bus, mc): - cm_name_ref = dbus.service.BusName( - cs.tp_name_prefix + '.ConnectionManager.onewitheverything', - bus=bus) + simulated_cm = SimulatedConnectionManager(q, bus, + cm_name='onewitheverything', protocol_names=['serializable']) # Get the AccountManager interface account_manager = get_account_manager(bus) diff --git a/tests/twisted/account-manager/presence.py b/tests/twisted/account-manager/presence.py index 5577f5a6..9f04f675 100755 --- a/tests/twisted/account-manager/presence.py +++ b/tests/twisted/account-manager/presence.py @@ -28,13 +28,13 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "jc.denton@example.com", "password": "ionstorm"}, signature='sv') - (cm_name_ref, account) = create_fakecm_account(q, bus, mc, params) + (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) - presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_TYPE_BUSY), 'busy', + presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Fighting conspiracies'), signature='uss') def mk_offline(message=''): - return dbus.Struct((dbus.UInt32(cs.PRESENCE_TYPE_OFFLINE), 'offline', + return dbus.Struct((dbus.UInt32(cs.PRESENCE_OFFLINE), 'offline', message), signature='uss') offline = mk_offline() @@ -78,10 +78,10 @@ def test(q, bus, mc): requested_presence=presence, expect_before_connect=[ EventPattern('dbus-method-call', - interface=cs.CONN, method='GetInterfaces', - args=[], + interface=cs.PROPERTIES_IFACE, method='Get', + args=[cs.CONN, 'Interfaces'], handled=True, - predicate=(lambda e: log.append('GetInterfaces') or True)), + predicate=(lambda e: log.append('Get(Interfaces)') or True)), EventPattern('dbus-method-call', interface=cs.PROPERTIES_IFACE, method='Get', args=[cs.CONN_IFACE_SIMPLE_PRESENCE, 'Statuses'], @@ -112,17 +112,17 @@ def test(q, bus, mc): e.args[0].get('CurrentPresence') == presence), ]) - # The events before Connect must happen in this order. GetInterfaces() may + # The events before Connect must happen in this order. Get(Interfaces) may # be called once or 2 times if len(log) == 5: - assert log == ['GetInterfaces', 'Get(Statuses)[1]', 'SetPresence[1]', + assert log == ['Get(Interfaces)', 'Get(Statuses)[1]', 'SetPresence[1]', 'Get(Statuses)[2]', 'SetPresence[2]'], log else: - assert log == ['GetInterfaces', 'GetInterfaces', 'Get(Statuses)[1]', 'SetPresence[1]', + assert log == ['Get(Interfaces)', 'Get(Interfaces)', 'Get(Statuses)[1]', 'SetPresence[1]', 'Get(Statuses)[2]', 'SetPresence[2]'], log # Change requested presence after going online - presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_TYPE_AWAY), 'away', + presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_AWAY), 'away', 'In Hong Kong'), signature='uss') call_async(q, account.Properties, 'Set', cs.ACCOUNT, 'RequestedPresence', presence) @@ -151,7 +151,7 @@ def test(q, bus, mc): predicate=lambda e: e.args[0].get('RequestedPresence') is not None)] q.forbid_events(events) - presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_TYPE_AWAY), 'away', + presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_AWAY), 'away', 'In Hong Kong'), signature='uss') call_async(q, account.Properties, 'Set', cs.ACCOUNT, 'RequestedPresence', presence) diff --git a/tests/twisted/account-manager/reconnect.py b/tests/twisted/account-manager/reconnect.py index 44af4100..39624a9c 100644 --- a/tests/twisted/account-manager/reconnect.py +++ b/tests/twisted/account-manager/reconnect.py @@ -27,13 +27,10 @@ from mctest import exec_test, SimulatedConnection, create_fakecm_account,\ import constants as cs def test(q, bus, mc): - cm_name_ref = dbus.service.BusName( - tp_name_prefix + '.ConnectionManager.fakecm', bus=bus) - # Create an account params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - (cm_name_ref, account) = create_fakecm_account(q, bus, mc, params) + (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) # Events that indicate that Reconnect might have done something looks_like_reconnection = [ @@ -51,7 +48,7 @@ def test(q, bus, mc): dbus_interface=cs.PROPERTIES_IFACE) q.expect('dbus-return', method='Set') - requested_presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_TYPE_AVAILABLE), + requested_presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_AVAILABLE), dbus.String(u'available'), dbus.String(u''))) call_async(q, account, 'Set', cs.ACCOUNT, 'RequestedPresence', requested_presence, @@ -65,7 +62,7 @@ def test(q, bus, mc): # While we want to be offline but the account is enabled, Reconnect is # still a no-op. - requested_presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_TYPE_OFFLINE), + requested_presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_OFFLINE), dbus.String(u'offline'), dbus.String(u''))) call_async(q, account, 'Set', cs.ACCOUNT, 'RequestedPresence', requested_presence, @@ -98,7 +95,7 @@ def test(q, bus, mc): q.unforbid_events(looks_like_reconnection) - requested_presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_TYPE_AVAILABLE), + requested_presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_AVAILABLE), dbus.String(u'brb'), dbus.String(u'Be back soon!'))) account.Set(cs.ACCOUNT, 'RequestedPresence', requested_presence, @@ -125,13 +122,13 @@ def test(q, bus, mc): path=conn.object_path, handled=True), ) - # MC calls GetStatus (maybe) and then Connect - + # MC prepares the connection, does any pre-Connect setup, then + # calls Connect q.expect('dbus-method-call', method='Connect', path=conn.object_path, handled=True) # Connect succeeds - conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CONN_STATUS_REASON_NONE) + conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) # Assert that the NormalizedName is harvested from the Connection at some # point @@ -180,10 +177,10 @@ def test(q, bus, mc): q.expect('dbus-method-call', method='Connect', path=conn.object_path, handled=True) - conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CONN_STATUS_REASON_NONE) + conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) # Put the account offline - requested_presence = (dbus.UInt32(cs.PRESENCE_TYPE_OFFLINE), 'offline', '') + requested_presence = (dbus.UInt32(cs.PRESENCE_OFFLINE), 'offline', '') account.Set(cs.ACCOUNT, 'RequestedPresence', requested_presence, dbus_interface=cs.PROPERTIES_IFACE) diff --git a/tests/twisted/account-manager/recover-from-disconnect.py b/tests/twisted/account-manager/recover-from-disconnect.py index 5cfe8686..932b4700 100644 --- a/tests/twisted/account-manager/recover-from-disconnect.py +++ b/tests/twisted/account-manager/recover-from-disconnect.py @@ -29,7 +29,7 @@ def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy", "register": True}, signature='sv') - (cm_name_ref, account) = create_fakecm_account(q, bus, mc, params) + (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) call_async(q, account.Properties, 'Set', cs.ACCOUNT, 'Enabled', False) q.expect('dbus-return', method='Set') @@ -38,7 +38,7 @@ def test(q, bus, mc): call_async(q, account.Properties, 'Set', cs.ACCOUNT, 'Enabled', True) # Set online presence - presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_TYPE_BUSY), 'busy', + presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Fixing MC bugs'), signature='uss') call_async(q, account.Properties, 'Set', cs.ACCOUNT, 'RequestedPresence', presence) @@ -55,13 +55,13 @@ def test(q, bus, mc): q.dbus_return(e.message, conn.bus_name, conn.object_path, signature='so') - # MC calls GetStatus (maybe) and then Connect - + # MC prepares the connection, does any pre-Connect setup, then + # calls Connect q.expect('dbus-method-call', method='Connect', path=conn.object_path, handled=True) # Connect succeeds - conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CONN_STATUS_REASON_NONE) + conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) q.expect('dbus-method-call', interface=cs.CONN_IFACE_SIMPLE_PRESENCE, @@ -73,7 +73,7 @@ def test(q, bus, mc): conn.ConnectionError('com.example.My.Network.Is.Full.Of.Eels', {'eels': 23, 'capacity': 23, 'debug-message': 'Too many eels'}) conn.StatusChanged(cs.CONN_STATUS_DISCONNECTED, - cs.CONN_STATUS_REASON_NETWORK_ERROR) + cs.CSR_NETWORK_ERROR) # MC reconnects. This time, we expect it to have deleted the 'register' # parameter. @@ -106,7 +106,7 @@ def test(q, bus, mc): disconnected.args[0].get('ConnectionErrorDetails')) assertEquals(cs.CONN_STATUS_DISCONNECTED, disconnected.args[0].get('ConnectionStatus')) - assertEquals(cs.CONN_STATUS_REASON_NETWORK_ERROR, + assertEquals(cs.CSR_NETWORK_ERROR, disconnected.args[0].get('ConnectionStatusReason')) assertEquals('/', connecting.args[0].get('Connection')) @@ -117,7 +117,7 @@ def test(q, bus, mc): connecting.args[0].get('ConnectionErrorDetails')) assertEquals(cs.CONN_STATUS_CONNECTING, connecting.args[0].get('ConnectionStatus')) - assertEquals(cs.CONN_STATUS_REASON_REQUESTED, + assertEquals(cs.CSR_REQUESTED, connecting.args[0].get('ConnectionStatusReason')) # The object path needs to be different from the first simulated @@ -130,8 +130,8 @@ def test(q, bus, mc): q.dbus_return(e.message, conn.bus_name, conn.object_path, signature='so') - # MC calls GetStatus (maybe) and then Connect - + # MC prepares the connection, does any pre-Connect setup, then + # calls Connect connecting, _ = q.expect_many( EventPattern('dbus-signal', signal='AccountPropertyChanged', predicate=(lambda e: @@ -150,7 +150,7 @@ def test(q, bus, mc): connecting.args[0].get('ConnectionErrorDetails')) assertEquals(cs.CONN_STATUS_CONNECTING, connecting.args[0].get('ConnectionStatus')) - assertEquals(cs.CONN_STATUS_REASON_REQUESTED, + assertEquals(cs.CSR_REQUESTED, connecting.args[0].get('ConnectionStatusReason')) assertEquals('com.example.My.Network.Is.Full.Of.Eels', @@ -160,7 +160,7 @@ def test(q, bus, mc): account.Properties.Get(cs.ACCOUNT, 'ConnectionErrorDetails')) # Connect succeeds - conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CONN_STATUS_REASON_NONE) + conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) connected, _ = q.expect_many( EventPattern('dbus-signal', signal='AccountPropertyChanged', @@ -180,7 +180,7 @@ def test(q, bus, mc): assertEquals({}, connected.args[0].get('ConnectionErrorDetails')) assertEquals(cs.CONN_STATUS_CONNECTED, connected.args[0].get('ConnectionStatus')) - assertEquals(cs.CONN_STATUS_REASON_REQUESTED, + assertEquals(cs.CSR_REQUESTED, connected.args[0].get('ConnectionStatusReason')) assertEquals('', account.Properties.Get(cs.ACCOUNT, 'ConnectionError')) diff --git a/tests/twisted/account-manager/req-conn-fails.py b/tests/twisted/account-manager/req-conn-fails.py index bc3f01a2..b9f05cba 100644 --- a/tests/twisted/account-manager/req-conn-fails.py +++ b/tests/twisted/account-manager/req-conn-fails.py @@ -31,13 +31,13 @@ def test(q, bus, mc): {"account": "someguy@example.com", "password": "secrecy", }, signature='sv') - (cm_name_ref, account) = create_fakecm_account(q, bus, mc, params) + (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_TYPE_BUSY), 'busy', 'Fixing MC bugs'), + (dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Fixing MC bugs'), signature='uss') account.Properties.Set(cs.ACCOUNT, 'RequestedPresence', presence) @@ -56,7 +56,7 @@ def test(q, bus, mc): changed, = e.args assertEquals('/', changed['Connection']) assertEquals(cs.CONN_STATUS_DISCONNECTED, changed['ConnectionStatus']) - assertEquals(cs.CONN_STATUS_REASON_NONE, changed['ConnectionStatusReason']) + assertEquals(cs.CSR_NONE_SPECIFIED, changed['ConnectionStatusReason']) assertEquals(cs.NOT_IMPLEMENTED, changed['ConnectionError']) if __name__ == '__main__': diff --git a/tests/twisted/account-manager/request-online.py b/tests/twisted/account-manager/request-online.py index 3d8a6016..18186843 100644 --- a/tests/twisted/account-manager/request-online.py +++ b/tests/twisted/account-manager/request-online.py @@ -30,9 +30,6 @@ from mctest import ( import constants as cs def test(q, bus, mc): - cm_name_ref = dbus.service.BusName( - tp_name_prefix + '.ConnectionManager.fakecm', bus=bus) - http_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': 1L, cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_STREAM_TUBE, @@ -50,7 +47,7 @@ def test(q, bus, mc): # Create an account params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - (cm_name_ref, account) = create_fakecm_account(q, bus, mc, params) + (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) # The account is initially valid but disabled, and hence offline props = account.GetAll(cs.ACCOUNT, dbus_interface=cs.PROPERTIES_IFACE) @@ -59,7 +56,7 @@ def test(q, bus, mc): # The spec says it should be (Offline, "", "") but I don't think the # strings really matter. If anything, the second one should start out at # "offline". - assertEquals(cs.PRESENCE_TYPE_OFFLINE, props['CurrentPresence'][0]) + assertEquals(cs.PRESENCE_OFFLINE, props['CurrentPresence'][0]) # Enable the account account.Set(cs.ACCOUNT, 'Enabled', True, @@ -73,7 +70,7 @@ def test(q, bus, mc): assert props['Enabled'] assert props['Valid'] # Ditto above re. string fields. - assertEquals(cs.PRESENCE_TYPE_OFFLINE, props['CurrentPresence'][0]) + assertEquals(cs.PRESENCE_OFFLINE, props['CurrentPresence'][0]) # Go online requested_presence = dbus.Struct((dbus.UInt32(2L), dbus.String(u'brb'), @@ -102,13 +99,14 @@ def test(q, bus, mc): args=[cs.CONN_IFACE_REQUESTS], path=conn.object_path, handled=True), ) - # MC calls GetStatus (maybe) and then Connect + # MC prepares the connection, does any pre-Connect setup, then + # calls Connect q.expect('dbus-method-call', method='Connect', path=conn.object_path, handled=True) # Connect succeeds - conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CONN_STATUS_REASON_NONE) + conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) # Assert that the NormalizedName is harvested from the Connection at some # point @@ -129,7 +127,7 @@ def test(q, bus, mc): # Since this Connection doesn't support SimplePresence, but it's online, # the spec says that CurrentPresence should be Unset. - assertEquals((cs.PRESENCE_TYPE_UNSET, "", ""), + assertEquals((cs.PRESENCE_UNSET, "", ""), properties.get('CurrentPresence')) new_channel = http_fixed_properties @@ -146,7 +144,7 @@ def test(q, bus, mc): q.dbus_return(e.message, signature='') # Put the account offline - requested_presence = (dbus.UInt32(cs.PRESENCE_TYPE_OFFLINE), 'offline', '') + requested_presence = (dbus.UInt32(cs.PRESENCE_OFFLINE), 'offline', '') account.Set(cs.ACCOUNT, 'RequestedPresence', requested_presence, dbus_interface=cs.PROPERTIES_IFACE) diff --git a/tests/twisted/account-manager/restricted-storage.py b/tests/twisted/account-manager/restricted-storage.py new file mode 100644 index 00000000..6724863b --- /dev/null +++ b/tests/twisted/account-manager/restricted-storage.py @@ -0,0 +1,185 @@ +# Copyright (C) 2009 Nokia Corporation +# Copyright (C) 2009-2012 Collabora Ltd. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +import dbus +import dbus.service + +from servicetest import EventPattern, call_async, assertEquals +from mctest import (exec_test, SimulatedConnection, + SimulatedConnectionManager, Account) +import constants as cs + +def test(q, bus, mc, fake_accounts_service=None, **kwargs): + simulated_cm = SimulatedConnectionManager(q, bus) + + for enabled in (True, False): + for online in (True, False): + account_tail = ('fakecm/fakeprotocol/ezio_2efirenze_40fic' + + (enabled and '_enabled' or '_disabled') + + (online and '_online' or '_offline')) + account_path = cs.ACCOUNT_PATH_PREFIX + account_tail + + try_to_connect = [ + EventPattern('dbus-method-call', method='RequestConnection', + destination=cs.tp_name_prefix + '.ConnectionManager.fakecm', + path=cs.tp_path_prefix + '/ConnectionManager/fakecm', + interface=cs.tp_name_prefix + '.ConnectionManager', + predicate=lambda e: + e.args[1]['account'] == account_tail, + handled=False) + ] + + if enabled and online: + also_expected = try_to_connect[:] + else: + also_expected = [] + q.forbid_events(try_to_connect) + + args = ( + { + 'Enabled': enabled, + 'ConnectAutomatically': online, + 'manager': 'fakecm', + 'protocol': 'fakeprotocol', + 'AutomaticPresence': + dbus.Struct((dbus.UInt32(cs.PRESENCE_HIDDEN), + 'hidden', 'press X to blend'), + signature='uss'), + }, + { + 'Enabled': 0, + 'ConnectAutomatically': 0, + 'manager': 0, + 'protocol': 0, + 'AutomaticPresence': 0, + }, + { + 'account': account_tail, + 'password': 'nothing is true' + }, + {}, # untyped parameters + { + 'account': 0, + 'password': cs.PARAM_SECRET + }, + cs.StorageRestrictionFlags.CANNOT_SET_PRESENCE | + cs.StorageRestrictionFlags.CANNOT_SET_ENABLED, + ) + + fake_accounts_service.create_account(account_tail, *args) + + events = q.expect_many( + EventPattern('dbus-signal', + path=cs.TEST_DBUS_ACCOUNT_SERVICE_PATH, + signal='AccountCreated', + args=[account_tail] + list(args)), + EventPattern('dbus-signal', + path=cs.AM_PATH, + signal='AccountValidityChanged', + args=[account_path, True]), + *also_expected) + account = Account(bus, account_path) + + if enabled and online: + conn = SimulatedConnection(q, bus, 'fakecm', 'fakeprotocol', + account_tail.replace('/', '_'), 'ezio', + has_presence=True) + q.dbus_return(events[-1].message, conn.bus_name, + conn.object_path, signature='so') + q.expect('dbus-method-call', method='SetPresence', + # the fake CM doesn't support 'hidden' by default + args=['busy', 'press X to blend']) + + requested_presence = (dbus.UInt32(cs.PRESENCE_HIDDEN), 'hidden', + 'press X to blend') + else: + requested_presence = (dbus.UInt32(cs.PRESENCE_OFFLINE), + 'offline', '') + + call_async(q, account.Properties, 'Get', cs.ACCOUNT, + 'RequestedPresence') + q.expect('dbus-return', method='Get', value=(requested_presence,)) + + # changes that are not really changes are fine + call_async(q, account.Properties, 'Set', cs.ACCOUNT, + 'Enabled', enabled) + q.expect('dbus-return', method='Set') + call_async(q, account.Properties, 'Set', cs.ACCOUNT, + 'ConnectAutomatically', online) + q.expect('dbus-return', method='Set') + + # changes that actually change the restrictive properties + # are not allowed + call_async(q, account.Properties, 'Set', cs.ACCOUNT, + 'RequestedPresence', + ((dbus.UInt32(cs.PRESENCE_AVAILABLE), 'available', + 'highly conspicuous'))) + q.expect('dbus-error', method='Set') + call_async(q, account.Properties, 'Set', cs.ACCOUNT, + 'AutomaticPresence', + ((dbus.UInt32(cs.PRESENCE_AVAILABLE), 'available', + 'highly conspicuous'))) + q.expect('dbus-error', method='Set') + call_async(q, account.Properties, 'Set', cs.ACCOUNT, + 'Enabled', not enabled) + q.expect('dbus-error', method='Set') + call_async(q, account.Properties, 'Set', cs.ACCOUNT, + 'ConnectAutomatically', not online) + q.expect('dbus-error', method='Set') + + call_async(q, account, 'Remove') + q.expect('dbus-error', method='Remove') + + # ... but the backend can still change them + if enabled and online: + q.forbid_events(try_to_connect) + fake_accounts_service.update_attributes(account_tail, + { + 'Enabled': False, + 'ConnectAutomatically': False, + }) + q.expect('dbus-method-call', method='Disconnect') + q.unforbid_events(try_to_connect) + else: + q.unforbid_events(try_to_connect) + fake_accounts_service.update_attributes(account_tail, + { + 'Enabled': True, + 'ConnectAutomatically': True, + }) + + events = q.expect_many(*try_to_connect) + conn = SimulatedConnection(q, bus, 'fakecm', 'fakeprotocol', + account_tail.replace('/', '_'), 'ezio', + has_presence=True) + q.dbus_return(events[-1].message, conn.bus_name, + conn.object_path, signature='so') + + # we are connected: deleting the account should + # disconnect us + fake_accounts_service.delete_account(account_tail) + q.expect_many( + EventPattern('dbus-signal', signal='AccountRemoved', + args=[account_path]), + EventPattern('dbus-signal', signal='Removed', + path=account_path), + EventPattern('dbus-method-call', method='Disconnect'), + ) + +if __name__ == '__main__': + exec_test(test, {}, pass_kwargs=True) diff --git a/tests/twisted/account-manager/server-drops-us.py b/tests/twisted/account-manager/server-drops-us.py index b4db423f..9a9d6ca7 100644 --- a/tests/twisted/account-manager/server-drops-us.py +++ b/tests/twisted/account-manager/server-drops-us.py @@ -30,11 +30,8 @@ params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') def test(q, bus, mc): - cm_name_ref = dbus.service.BusName( - tp_name_prefix + '.ConnectionManager.fakecm', bus=bus) - # Create an account - (cm_name_ref, account) = create_fakecm_account(q, bus, mc, params) + (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) @@ -48,7 +45,7 @@ def test(q, bus, mc): dbus_interface=cs.PROPERTIES_IFACE) # Set online presence - presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_TYPE_BUSY), 'busy', + presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Fixing MC bugs'), signature='uss') call_async(q, account, 'Set', cs.ACCOUNT, 'RequestedPresence', presence, @@ -66,13 +63,13 @@ def test(q, bus, mc): q.dbus_return(e.message, conn.bus_name, conn.object_path, signature='so') - # MC calls GetStatus (maybe) and then Connect - + # MC prepares the connection, does any pre-Connect setup, then + # calls Connect q.expect('dbus-method-call', method='Connect', path=conn.object_path, handled=True) # Connect succeeds - conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CONN_STATUS_REASON_NONE) + conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) conn = drop_and_expect_reconnect(q, bus, conn) conn = drop_and_expect_reconnect(q, bus, conn) @@ -83,7 +80,7 @@ def test(q, bus, mc): # Connection falls over for a miscellaneous reason conn.StatusChanged(cs.CONN_STATUS_DISCONNECTED, - cs.CONN_STATUS_REASON_NETWORK_ERROR) + cs.CSR_NETWORK_ERROR) # Right, that's it, I'm giving up... # This test can be considered to have succeeded if we don't @@ -98,7 +95,7 @@ def test(q, bus, mc): def drop_and_expect_reconnect(q, bus, conn): # Connection falls over for a miscellaneous reason conn.StatusChanged(cs.CONN_STATUS_DISCONNECTED, - cs.CONN_STATUS_REASON_NETWORK_ERROR) + cs.CSR_NETWORK_ERROR) # MC reconnects @@ -114,13 +111,13 @@ def drop_and_expect_reconnect(q, bus, conn): q.dbus_return(e.message, conn.bus_name, conn.object_path, signature='so') - # MC calls GetStatus (maybe) and then Connect - + # MC prepares the connection, does any pre-Connect setup, then + # calls Connect q.expect('dbus-method-call', method='Connect', path=conn.object_path, handled=True) # Connect succeeds - conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CONN_STATUS_REASON_NONE) + conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) return conn diff --git a/tests/twisted/account-manager/service.py b/tests/twisted/account-manager/service.py index f7df9903..7bed951a 100644 --- a/tests/twisted/account-manager/service.py +++ b/tests/twisted/account-manager/service.py @@ -27,7 +27,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "wjt@example.com", "password": "secrecy"}, signature='sv') - (cm_name_ref, account) = create_fakecm_account(q, bus, mc, params) + (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) srv_name = 'fu-bar-42' account_iface = dbus.Interface(account, cs.ACCOUNT) diff --git a/tests/twisted/account-manager/update-parameters.py b/tests/twisted/account-manager/update-parameters.py index a7ec6a0a..a030a01f 100644 --- a/tests/twisted/account-manager/update-parameters.py +++ b/tests/twisted/account-manager/update-parameters.py @@ -30,16 +30,13 @@ from mctest import exec_test, SimulatedConnection, create_fakecm_account,\ import constants as cs def test(q, bus, mc, **kwargs): - cm_name_ref = dbus.service.BusName( - tp_name_prefix + '.ConnectionManager.fakecm', bus=bus) - # Create an account params = dbus.Dictionary( {"account": "someguy@example.com", "password": "secrecy", "nickname": "albinoblacksheep", }, signature='sv') - (cm_name_ref, account) = create_fakecm_account(q, bus, mc, params) + (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) # Enable the account account.Set(cs.ACCOUNT, 'Enabled', True, @@ -77,13 +74,13 @@ def test(q, bus, mc, **kwargs): path=conn.object_path, handled=True), ) - # MC calls GetStatus (maybe) and then Connect - + # MC prepares the connection, does any pre-Connect setup, then + # calls Connect q.expect('dbus-method-call', method='Connect', path=conn.object_path, handled=True) # Connect succeeds - conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CONN_STATUS_REASON_NONE) + conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) # Assert that the NormalizedName is harvested from the Connection at some # point @@ -255,13 +252,11 @@ def test(q, bus, mc, **kwargs): assertEquals(r'\\', kwargs['fake_accounts_service'].accounts [account.object_path[len(cs.ACCOUNT_PATH_PREFIX):]] - [2] # parameters of known type - ['account']) + .params['account']) assertEquals(None, kwargs['fake_accounts_service'].accounts [account.object_path[len(cs.ACCOUNT_PATH_PREFIX):]] - [3] # parameters of unknown type - .get('account', None)) + .untyped_params.get('account', None)) if __name__ == '__main__': exec_test(test, {}, pass_kwargs=True) diff --git a/tests/twisted/account-requests/cancel.py b/tests/twisted/account-requests/cancel.py index f236e5b8..9effcbec 100644 --- a/tests/twisted/account-requests/cancel.py +++ b/tests/twisted/account-requests/cancel.py @@ -34,7 +34,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/account-requests/create-text.py b/tests/twisted/account-requests/create-text.py index e71aca9d..c6d5922e 100644 --- a/tests/twisted/account-requests/create-text.py +++ b/tests/twisted/account-requests/create-text.py @@ -34,7 +34,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/account-requests/delete-account-during-request.py b/tests/twisted/account-requests/delete-account-during-request.py index 348c45a7..0b448eb8 100644 --- a/tests/twisted/account-requests/delete-account-during-request.py +++ b/tests/twisted/account-requests/delete-account-during-request.py @@ -34,7 +34,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/account-storage/5-12.py b/tests/twisted/account-storage/5-12.py new file mode 100644 index 00000000..9075d767 --- /dev/null +++ b/tests/twisted/account-storage/5-12.py @@ -0,0 +1,29 @@ +# Test for a former default account storage backend: +# ~/.mission-control/accounts.cfg, as used in MC 5.0 to 5.13.1 +# +# Copyright (C) 2009-2010 Nokia Corporation +# Copyright (C) 2009-2014 Collabora Ltd. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +from storage_helper import test_keyfile +from mctest import exec_test + +def test_5_12(q, bus, mc): + test_keyfile(q, bus, mc, '5.12') + +if __name__ == '__main__': + exec_test(test_5_12, {}, preload_mc=False, use_fake_accounts_service=False) diff --git a/tests/twisted/account-storage/5-14.py b/tests/twisted/account-storage/5-14.py new file mode 100644 index 00000000..42deb3ec --- /dev/null +++ b/tests/twisted/account-storage/5-14.py @@ -0,0 +1,29 @@ +# Test for a former default account storage backend: +# XDG_DATA_HOME/telepathy/mission-control/accounts.cfg, as used in MC 5.14 +# +# Copyright (C) 2009-2010 Nokia Corporation +# Copyright (C) 2009-2014 Collabora Ltd. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +from storage_helper import test_keyfile +from mctest import exec_test + +def test_5_14(q, bus, mc): + test_keyfile(q, bus, mc, '5.14') + +if __name__ == '__main__': + exec_test(test_5_14, {}, preload_mc=False, use_fake_accounts_service=False) diff --git a/tests/twisted/account-storage/create-new.py b/tests/twisted/account-storage/create-new.py new file mode 100644 index 00000000..f77624a9 --- /dev/null +++ b/tests/twisted/account-storage/create-new.py @@ -0,0 +1,136 @@ +# Test for "stringified GVariant per account" storage backend introduced in +# Mission Control 5.16, when creating a new account stored in this default +# backend +# +# Copyright (C) 2009-2010 Nokia Corporation +# Copyright (C) 2009-2014 Collabora Ltd. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +import time +import os +import os.path +import signal + +import dbus +import dbus.service + +from servicetest import ( + EventPattern, assertEquals, + ) +from mctest import ( + exec_test, create_fakecm_account, connect_to_mc, + ) +from storage_helper import (account_store) +import constants as cs + +def test(q, bus, mc): + ctl_dir = os.environ['MC_ACCOUNT_DIR'] + old_key_file_name = os.path.join(ctl_dir, 'accounts.cfg') + newer_key_file_name = os.path.join(os.environ['XDG_DATA_HOME'], + 'telepathy', 'mission-control', 'accounts.cfg') + new_variant_file_name = os.path.join(os.environ['XDG_DATA_HOME'], + 'telepathy', 'mission-control', + 'fakecm-fakeprotocol-dontdivert_40example_2ecom0.account') + + 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": "dontdivert@example.com", + "password": "secrecy", + "snakes": dbus.UInt32(23)}, 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, 'DisplayName', 'Work account') + account_props.Set(cs.ACCOUNT, 'Icon', 'im-jabber') + account_props.Set(cs.ACCOUNT, 'Nickname', 'Joe Bloggs') + account_props.Set(cs.ACCOUNT, 'ConnectAutomatically', True) + account_props.Set(cs.ACCOUNT, 'AutomaticPresence', + (dbus.UInt32(cs.PRESENCE_EXTENDED_AWAY), 'xa', + 'never online')) + + # .. let's check the keyfile + assert not os.path.exists(old_key_file_name) + assert not os.path.exists(newer_key_file_name) + assert os.path.exists(new_variant_file_name) + assert 'Joe Bloggs' in open(new_variant_file_name).read() + assertEquals("'fakecm'", account_store('get', 'variant-file', 'manager')) + assertEquals("'fakeprotocol'", account_store('get', 'variant-file', + 'protocol')) + assertEquals("'Work account'", account_store('get', 'variant-file', + 'DisplayName')) + assertEquals("'im-jabber'", account_store('get', 'variant-file', + 'Icon')) + assertEquals("'Joe Bloggs'", account_store('get', 'variant-file', + 'Nickname')) + assertEquals('true', account_store('get', 'variant-file', + 'ConnectAutomatically')) + assertEquals("(uint32 4, 'xa', 'never online')", + account_store('get', 'variant-file', 'AutomaticPresence')) + assertEquals("'dontdivert@example.com'", + account_store('get', 'variant-file', 'param-account')) + assertEquals("uint32 23", + account_store('get', 'variant-file', 'param-snakes')) + assertEquals("'secrecy'", + account_store('get', 'variant-file', 'param-password')) + + assertEquals({'password': 'secrecy', 'account': 'dontdivert@example.com', + 'snakes': 23}, account.Properties.Get(cs.ACCOUNT, 'Parameters')) + + # 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 + assert not os.path.exists(old_key_file_name) + assert not os.path.exists(newer_key_file_name) + assert not os.path.exists(new_variant_file_name) + +if __name__ == '__main__': + exec_test(test, {}, timeout=10, use_fake_accounts_service=False) diff --git a/tests/twisted/account-storage/default-keyring-storage.py b/tests/twisted/account-storage/default-keyring-storage.py deleted file mode 100644 index 2d3b2fcf..00000000 --- a/tests/twisted/account-storage/default-keyring-storage.py +++ /dev/null @@ -1,230 +0,0 @@ -# Test for default account storage backend. -# -# Copyright (C) 2009-2010 Nokia Corporation -# Copyright (C) 2009-2010 Collabora Ltd. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA - -import time -import os -import os.path -import signal - -import dbus -import dbus.service - -from servicetest import EventPattern, tp_name_prefix, tp_path_prefix, \ - call_async, assertEquals -from mctest import ( - exec_test, create_fakecm_account, get_fakecm_account, connect_to_mc, - keyfile_read, tell_mc_to_die, resuscitate_mc - ) -import constants as cs - -# This doesn't escape its parameters before passing them to the shell, -# so be careful. -def account_store(op, backend, key=None, value=None, - account='fakecm/fakeprotocol/dontdivert_40example_2ecom0'): - cmd = [ '../account-store', op, backend, account ] - if key: - cmd.append(key) - if value: - cmd.append(value) - - lines = os.popen(' '.join(cmd)).read() - ret = [] - for line in lines.split('\n'): - if line.startswith('** '): - continue - - if line: - ret.append(line) - - if len(ret) > 0: - return ret[0] - else: - return None - -def test(q, bus, mc): - ctl_dir = os.environ['MC_ACCOUNT_DIR'] - old_key_file_name = os.path.join(ctl_dir, 'accounts.cfg') - new_key_file_name = os.path.join(os.environ['XDG_DATA_HOME'], - 'telepathy', 'mission-control', 'accounts.cfg') - group = 'fakecm/fakeprotocol/dontdivert_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": "dontdivert@example.com", - "password": "secrecy"}, signature='sv') - (cm_name_ref, 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, 'DisplayName', 'Work account') - account_props.Set(cs.ACCOUNT, 'Icon', 'im-jabber') - account_props.Set(cs.ACCOUNT, 'Nickname', 'Joe Bloggs') - - tell_mc_to_die(q, bus) - - # .. let's check the keyfile - assert not os.path.exists(old_key_file_name) - kf = keyfile_read(new_key_file_name) - 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]['DisplayName'] == 'Work account', kf - assert kf[group]['Icon'] == 'im-jabber', kf - assert kf[group]['Nickname'] == 'Joe Bloggs', kf - - # This works wherever the password is stored - pwd = account_store('get', 'default', 'param-password') - assert pwd == params['password'], pwd - - # We no longer use gnome-keyring, so the password is stored as clear-text. - assert kf[group]['param-password'] == params['password'], 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 - assert not os.path.exists(old_key_file_name) - kf = keyfile_read(new_key_file_name) - assert group not in kf, kf - - # Tell MC to die, again - tell_mc_to_die(q, bus) - - low_prio_key_file_name = os.path.join( - os.environ['XDG_DATA_DIRS'].split(':')[0], - 'telepathy', 'mission-control', 'accounts.cfg') - os.makedirs(os.path.dirname(low_prio_key_file_name), 0700) - - # This is deliberately a lower-priority location - os.remove(new_key_file_name) - open(low_prio_key_file_name, 'w').write( -r"""# Telepathy accounts -[%s] -manager=fakecm -protocol=fakeprotocol -param-account=dontdivert@example.com -param-password=password_in_keyfile -DisplayName=New and improved account -AutomaticPresence=2;available;; -""" % group) - - account_manager, properties, interfaces = resuscitate_mc(q, bus, mc) - account = get_fakecm_account(bus, mc, account_path) - account_iface = dbus.Interface(account, cs.ACCOUNT) - - # Files in lower-priority XDG locations aren't copied until something - # actually changes, and they aren't deleted. - assert not os.path.exists(new_key_file_name) - assert os.path.exists(low_prio_key_file_name) - - # Delete the password (only), like Empathy 3.0-3.4 do when migrating - account_iface.UpdateParameters({}, ['password']) - q.expect('dbus-signal', - path=account_path, - signal='AccountPropertyChanged', - interface=cs.ACCOUNT, - predicate=(lambda e: - 'Parameters' in e.args[0]), - ) - - # Tell MC to die yet again - tell_mc_to_die(q, bus) - - # Check the account has copied (not moved! XDG_DATA_DIRS are, - # conceptually, read-only) from the old to the new name - assert not os.path.exists(old_key_file_name) - assert os.path.exists(low_prio_key_file_name) - kf = keyfile_read(new_key_file_name) - assert 'param-password' not in kf[group] - pwd = account_store('get', 'default', 'param-password') - assertEquals(None, pwd) - - # Write out an account configuration in the old keyfile, to test - # migration - os.remove(new_key_file_name) - os.remove(low_prio_key_file_name) - open(old_key_file_name, 'w').write( -r"""# Telepathy accounts -[%s] -manager=fakecm -protocol=fakeprotocol -param-account=dontdivert@example.com -DisplayName=Ye olde account -AutomaticPresence=2;available;; -""" % group) - - account_manager, properties, interfaces = resuscitate_mc(q, bus, mc) - account = get_fakecm_account(bus, mc, account_path) - account_iface = dbus.Interface(account, cs.ACCOUNT) - - # This time it *does* get moved (really copied+deleted) automatically - # during MC startup - assert not os.path.exists(old_key_file_name) - assert not os.path.exists(low_prio_key_file_name) - kf = keyfile_read(new_key_file_name) - assert 'param-password' not in kf[group] - assertEquals('Ye olde account', kf[group]['DisplayName']) - -if __name__ == '__main__': - ctl_dir = os.environ['MC_ACCOUNT_DIR'] - try: - os.mkdir(ctl_dir, 0700) - except OSError: - pass - exec_test(test, {}, timeout=10, use_fake_accounts_service=False) diff --git a/tests/twisted/account-storage/diverted-storage.py b/tests/twisted/account-storage/diverted-storage.py index 8692b09b..7aa011e8 100644 --- a/tests/twisted/account-storage/diverted-storage.py +++ b/tests/twisted/account-storage/diverted-storage.py @@ -53,7 +53,7 @@ def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - (cm_name_ref, account) = create_fakecm_account(q, bus, mc, params) + (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) account_path = account.__dbus_object_path__ @@ -88,10 +88,6 @@ def test(q, bus, mc): assert kf[group]['Icon'] == 'im-jabber', kf assert kf[group]['Nickname'] == 'Joe Bloggs', kf - # default keyfile should be empty - ekf = keyfile_read(empty_key_file_name) - assert ekf == { None: {} }, ekf - # Reactivate MC account_manager, properties, interfaces = resuscitate_mc(q, bus, mc) account = get_fakecm_account(bus, mc, account_path) diff --git a/tests/twisted/account-storage/libaccounts-sso-storage.py b/tests/twisted/account-storage/libaccounts-sso-storage.py deleted file mode 100644 index a2e7b512..00000000 --- a/tests/twisted/account-storage/libaccounts-sso-storage.py +++ /dev/null @@ -1,89 +0,0 @@ -# Copyright (C) 2009-2010 Nokia Corporation -# Copyright (C) 2009-2010 Collabora Ltd. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA - -raise AssertionError('Disabled for 5.6 branch') - -import time -import os -import os.path -import signal -import sys - -import dbus -import dbus.service - -from servicetest import EventPattern, tp_name_prefix, tp_path_prefix, \ - call_async -from mctest import exec_test, create_fakecm_account, get_account_manager, \ - get_fakecm_account -import constants as cs - -if ('ACCOUNTS' not in os.environ or not os.environ['ACCOUNTS']): - print "Not testing accounts-sso storage" - sys.exit(0) - -def account_store(op, backend, key=None, value=None): - cmd = [ '../account-store', op, backend, - 'colltest42@googlemail.com' ] - if key: - cmd.append(key) - if value: - cmd.append(value) - - lines = os.popen(' '.join(cmd)).read() - ret = [] - for line in lines.split('\n'): - if line.startswith('** '): - continue - - if line: - ret.append(line) - - if len(ret) > 0: - return ret[0] - else: - return None - -def prepare_accounts_db(ctl_dir): - os.system('cp %s/../tools/example-accounts.db %s/accounts.db' % (ctl_dir, ctl_dir)) - os.system('cp %s/../tools/accounts-sso-example.service %s/google-talk.service' % (ctl_dir, ctl_dir)) - -def test(q, bus, mc): - account_manager, properties, interfaces = connect_to_mc(q, bus, mc) - - va = properties.get('ValidAccounts') - assert va == [], va - - ia = properties.get('InvalidAccounts') - assert len(ia) == 1 - - account_path = ia[0] - print repr(account_path) - - account = get_fakecm_account(bus, mc, account_path) - account_iface = dbus.Interface(account, cs.ACCOUNT) - account_props = dbus.Interface(account, cs.PROPERTIES_IFACE) - - # FIXME at this point MC crashes - properties = account_props.GetAll(cs.ACCOUNT) - - -if __name__ == '__main__': - ctl_dir = os.environ['ACCOUNTS'] - prepare_accounts_db(ctl_dir) - exec_test(test, {}, timeout=10, use_fake_accounts_service=False) diff --git a/tests/twisted/account-storage/load-keyfiles.py b/tests/twisted/account-storage/load-keyfiles.py new file mode 100644 index 00000000..b6c9d2ef --- /dev/null +++ b/tests/twisted/account-storage/load-keyfiles.py @@ -0,0 +1,283 @@ +# Test for "stringified GVariant per account" storage backend introduced in +# Mission Control 5.16, when loading pre-prepared files +# +# Copyright (C) 2009-2010 Nokia Corporation +# Copyright (C) 2009-2014 Collabora Ltd. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +import errno +import os +import os.path + +import dbus + +from servicetest import ( + assertEquals, assertContains, assertDoesNotContain, + ) +from mctest import ( + MC, exec_test, get_fakecm_account, connect_to_mc, + SimulatedConnectionManager, + ) +from storage_helper import ( + account_store, + ) +import constants as cs + +def test(q, bus, mc): + simulated_cm = SimulatedConnectionManager(q, bus) + + ctl_dir = os.environ['MC_ACCOUNT_DIR'] + old_key_file_name = os.path.join(ctl_dir, 'accounts.cfg') + newer_key_file_name = os.path.join(os.environ['XDG_DATA_HOME'], + 'telepathy', 'mission-control', 'accounts.cfg') + + # We do several scenarios in one MC run, to speed up testing a bit. + scenarios = ('low', 'priority', 'masked', 'migration', 'absentcm') + + variant_file_names = {} + low_prio_variant_file_names = {} + account_paths = {} + tails = {} + + for s in scenarios: + variant_file_names[s] = os.path.join(os.environ['XDG_DATA_HOME'], + 'telepathy', 'mission-control', + 'fakecm-fakeprotocol-dontdivert%s_40example_2ecom0.account' + % s) + tails[s] = ('fakecm/fakeprotocol/dontdivert%s_40example_2ecom0' % s) + account_paths[s] = cs.ACCOUNT_PATH_PREFIX + tails[s] + low_prio_variant_file_names[s] = os.path.join( + os.environ['XDG_DATA_DIRS'].split(':')[0], + 'telepathy', 'mission-control', + 'fakecm-fakeprotocol-dontdivert%s_40example_2ecom0.account' % + s) + + try: + os.makedirs(os.path.dirname(variant_file_names[s]), 0700) + except OSError as e: + if e.errno != errno.EEXIST: + raise + + try: + os.makedirs(os.path.dirname(low_prio_variant_file_names[s]), 0700) + except OSError as e: + if e.errno != errno.EEXIST: + raise + + # This is deliberately a lower-priority location + open(low_prio_variant_file_names['low'], 'w').write( +"""{ +'manager': <'fakecm'>, +'protocol': <'fakeprotocol'>, +'DisplayName': <'Account in a low-priority location'>, +'AutomaticPresence': <(uint32 2, 'available', '')>, +'Parameters': <{ + 'account': <'dontdivertlow@example.com'>, + 'password': <'password_in_variant_file'>, + 'snakes': <uint32 42> + }> +} +""") + + # This is in a lower-priority location and we don't know the + # parameters' types yet + open(low_prio_variant_file_names['migration'], 'w').write( +"""{ +'manager': <'fakecm'>, +'protocol': <'fakeprotocol'>, +'DisplayName': <'Account in a low-priority location with KeyFileParameters'>, +'AutomaticPresence': <(uint32 2, 'available', '')>, +'KeyFileParameters': <{ + 'account': 'dontdivertmigration@example.com', + 'password': 'password_in_variant_file', + 'snakes': '42' + }> +} +""") + + # This is in a lower-priority location, and we don't know the + # parameters' types, and we can't learn them by asking the CM + # because it isn't installed + open(low_prio_variant_file_names['absentcm'], 'w').write( +"""{ +'manager': <'absentcm'>, +'protocol': <'absentprotocol'>, +'DisplayName': <'Account in a low-priority location with absent CM'>, +'AutomaticPresence': <(uint32 2, 'available', '')>, +'KeyFileParameters': <{ + 'account': 'dontdivertabsentcm@example.com', + 'password': 'hello', + 'snakes': '42' + }> +} +""") + + # This version of this account will be used + open(variant_file_names['priority'], 'w').write("""{ +'manager': <'fakecm'>, +'protocol': <'fakeprotocol'>, +'DisplayName': <'Visible'>, +'AutomaticPresence': <(uint32 2, 'available', '')>, +'KeyFileParameters': <{'account': 'dontdivertpriority@example.com', + 'password': 'password_in_variant_file', + 'snakes': '42' + }> +} +""") + # This one won't, because it's "masked" by the higher-priority one + open(low_prio_variant_file_names['priority'], 'w').write("""{ +'manager': <'fakecm'>, +'protocol': <'fakeprotocol'>, +'DisplayName': <'Hidden'>, +'Nickname': <'Hidden'>, +'AutomaticPresence': <(uint32 2, 'available', '')>, +'KeyFileParameters': <{'account': 'dontdivertpriority@example.com', + 'password': 'password_in_variant_file', + 'snakes': '42' + }> +} +""") + + # This empty file is considered to "mask" the lower-priority one + open(variant_file_names['masked'], 'w').write('') + open(low_prio_variant_file_names['masked'], 'w').write("""{ +'manager': <'fakecm'>, +'protocol': <'fakeprotocol'>, +'AutomaticPresence': <(uint32 2, 'available', '')>, +'KeyFileParameters': <{'account': 'dontdivert@example.com', + 'password': 'password_in_variant_file', + 'snakes': '42' + }> +} +""") + + mc = MC(q, bus) + account_manager, properties, interfaces = connect_to_mc(q, bus, mc) + + for s in scenarios: + if s == 'masked': + assertDoesNotContain(account_paths[s], properties['ValidAccounts']) + assertDoesNotContain(account_paths[s], properties['InvalidAccounts']) + elif s == 'absentcm': + assertContains(account_paths[s], properties['InvalidAccounts']) + assertDoesNotContain(account_paths[s], properties['ValidAccounts']) + else: + assertContains(account_paths[s], properties['ValidAccounts']) + assertDoesNotContain(account_paths[s], properties['InvalidAccounts']) + + accounts = {} + account_ifaces = {} + + for s in scenarios: + if s != 'masked': + accounts[s] = get_fakecm_account(bus, mc, account_paths[s]) + account_ifaces[s] = dbus.Interface(accounts[s], cs.ACCOUNT) + + if s not in ('masked', 'absentcm'): + # We can't get untyped parameters if we don't know what types + # the CM gives them. + assertEquals(42, accounts[s].Properties.Get(cs.ACCOUNT, + 'Parameters')['snakes']) + assertEquals(dbus.UInt32, + type(accounts[s].Properties.Get(cs.ACCOUNT, + 'Parameters')['snakes'])) + + # Files in lower-priority XDG locations aren't copied until something + # actually changes, and they aren't deleted. + + if s == 'low': + assert os.path.exists(low_prio_variant_file_names[s]) + + # Delete the password (only), like Empathy 3.0-3.4 do when migrating. + # This results in the higher-priority file being written out. + account_ifaces['low'].UpdateParameters({}, ['password']) + q.expect('dbus-signal', + path=account_paths['low'], + signal='AccountPropertyChanged', + interface=cs.ACCOUNT, + predicate=(lambda e: + 'Parameters' in e.args[0]), + ) + # Check the account has copied (not moved! XDG_DATA_DIRS are, + # conceptually, read-only) 'low' from the old to the new name + assert not os.path.exists(old_key_file_name) + assert not os.path.exists(newer_key_file_name) + assert os.path.exists(low_prio_variant_file_names['low']) + assert os.path.exists(variant_file_names['low']) + + # test that priority works + assertContains(account_paths["priority"], properties['ValidAccounts']) + assertEquals('', + accounts['priority'].Properties.Get(cs.ACCOUNT, 'Nickname')) + assertEquals('Visible', + accounts['priority'].Properties.Get(cs.ACCOUNT, 'DisplayName')) + + # test what happens when we delete an account that has a lower-priority + # "other self": it becomes masked + assert accounts['priority'].Remove() is None + assert not os.path.exists(old_key_file_name) + assert not os.path.exists(newer_key_file_name) + assert os.path.exists(low_prio_variant_file_names['priority']) + assert os.path.exists(variant_file_names['priority']) + assert open(variant_file_names['priority'], 'r').read() == '' + assertContains('password_in_variant_file', + open(low_prio_variant_file_names['priority'], 'r').read()) + + # The masked account is still masked + assert open(variant_file_names['masked'], 'r').read() == '' + + # Because the CM exists, we can work out the correct types + # for the 'migration' account's parameters. This triggers a commit + # even though nothing has conceptually changed, so we have the type + # for later. The file is copied, not moved, because XDG_DATA_DIRS are, + # conceptually, read-only. + assert not os.path.exists(old_key_file_name) + assert not os.path.exists(newer_key_file_name) + assert os.path.exists(low_prio_variant_file_names['migration']) + assert os.path.exists(variant_file_names['migration']) + assertEquals("'password_in_variant_file'", + account_store('get', 'variant-file', 'param-password', + account=tails['migration'])) + assertEquals("uint32 42", account_store('get', 'variant-file', + 'param-snakes', account=tails['migration'])) + + # Setting the password still does the right thing. + account_ifaces['migration'].UpdateParameters({'password': 'hello'}, []) + q.expect('dbus-signal', + path=account_paths['migration'], + signal='AccountPropertyChanged', + interface=cs.ACCOUNT, + predicate=(lambda e: + 'Parameters' in e.args[0]), + ) + assert not os.path.exists(old_key_file_name) + assert not os.path.exists(newer_key_file_name) + assert os.path.exists(low_prio_variant_file_names['migration']) + assert os.path.exists(variant_file_names['migration']) + assertEquals("'hello'", + account_store('get', 'variant-file', 'param-password', + account=tails['migration'])) + + # 'absentcm' is still only in the low-priority location: we can't + # known the types of its parameters, so it doesn't get migrated. + assert not os.path.exists(old_key_file_name) + assert not os.path.exists(newer_key_file_name) + assert os.path.exists(low_prio_variant_file_names['absentcm']) + assert not os.path.exists(variant_file_names['absentcm']) + +if __name__ == '__main__': + exec_test(test, {}, preload_mc=False, use_fake_accounts_service=False) diff --git a/tests/twisted/account-storage/storage_helper.py b/tests/twisted/account-storage/storage_helper.py new file mode 100644 index 00000000..0f67df92 --- /dev/null +++ b/tests/twisted/account-storage/storage_helper.py @@ -0,0 +1,174 @@ +# Helper code for former default account storage backends +# +# Copyright (C) 2009-2010 Nokia Corporation +# Copyright (C) 2009-2014 Collabora Ltd. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +import errno +import os +import os.path + +import dbus + +from servicetest import ( + assertEquals, assertContains, assertLength, + ) +from mctest import ( + exec_test, get_fakecm_account, connect_to_mc, + MC, SimulatedConnectionManager, + ) +import constants as cs + +# This doesn't escape its parameters before passing them to the shell, +# so be careful. +def account_store(op, backend, key=None, value=None, + account='fakecm/fakeprotocol/dontdivert_40example_2ecom0'): + cmd = [ '../account-store', op, backend, account ] + if key: + cmd.append(key) + if value: + cmd.append(value) + + lines = os.popen(' '.join(cmd)).read() + ret = [] + for line in lines.split('\n'): + if line.startswith('** '): + continue + + if line: + ret.append(line) + + if len(ret) > 0: + return ret[0] + else: + return None + +def test_keyfile(q, bus, mc, how_old='5.12'): + simulated_cm = SimulatedConnectionManager(q, bus) + + if how_old == '5.12': + # This is not actually ~/.mission-control, but it uses the same + # code paths. + dot_mission_control = os.environ['MC_ACCOUNT_DIR'] + old_key_file_name = os.path.join(dot_mission_control, 'accounts.cfg') + + os.makedirs(dot_mission_control + + '/fakecm/fakeprotocol/dontdivert1_40example_2ecom0') + avatar_bin = open(dot_mission_control + + '/fakecm/fakeprotocol/dontdivert1_40example_2ecom0/avatar.bin', + 'w') + avatar_bin.write('hello, world') + avatar_bin.close() + elif how_old == '5.14': + # Same format, different location. + old_key_file_name = os.path.join(os.environ['XDG_DATA_HOME'], + 'telepathy', 'mission-control', 'accounts.cfg') + + # exercise override of an avatar in XDG_DATA_DIRS + avatar_dir = (os.environ['XDG_DATA_DIRS'].split(':')[0] + + '/telepathy/mission-control') + os.makedirs(avatar_dir) + avatar_bin = open(avatar_dir + + '/fakecm-fakeprotocol-dontdivert1_40example_2ecom0.avatar', + 'w') + avatar_bin.write('hello, world') + avatar_bin.close() + else: + raise AssertionError('Unsupported value for how_old') + + a1_new_variant_file_name = os.path.join(os.environ['XDG_DATA_HOME'], + 'telepathy', 'mission-control', + 'fakecm-fakeprotocol-dontdivert1_40example_2ecom0.account') + a1_tail = 'fakecm/fakeprotocol/dontdivert1_40example_2ecom0' + + a2_new_variant_file_name = os.path.join(os.environ['XDG_DATA_HOME'], + 'telepathy', 'mission-control', + 'fakecm-fakeprotocol-dontdivert2_40example_2ecom0.account') + a2_tail = 'fakecm/fakeprotocol/dontdivert2_40example_2ecom0' + + try: + os.makedirs(os.path.dirname(old_key_file_name), 0700) + except OSError as e: + if e.errno != errno.EEXIST: + raise + + open(old_key_file_name, 'w').write( +r"""# Telepathy accounts +[%s] +manager=fakecm +protocol=fakeprotocol +param-account=dontdivert1@example.com +param-password=1 +DisplayName=First among equals +AutomaticPresence=2;available;; +AvatarMime=text/plain +avatar_token=hello, world + +[%s] +manager=fakecm +protocol=fakeprotocol +param-account=dontdivert2@example.com +param-password=2 +DisplayName=Second to none +AutomaticPresence=2;available;; +""" % (a1_tail, a2_tail)) + + mc = MC(q, bus) + account_manager, properties, interfaces = connect_to_mc(q, bus, mc) + + # During MC startup, it moved the old keyfile's contents into + # variant-based files, and deleted the old keyfile. + assert not os.path.exists(old_key_file_name) + assert os.path.exists(a1_new_variant_file_name) + assert os.path.exists(a2_new_variant_file_name) + assertEquals("'First among equals'", + account_store('get', 'variant-file', 'DisplayName', + account=a1_tail)) + assertEquals("'Second to none'", + account_store('get', 'variant-file', 'DisplayName', + account=a2_tail)) + # Because the CM is installed, we can work out the right types + # for the parameters, too. + assertEquals("'dontdivert1@example.com'", + account_store('get', 'variant-file', 'param-account', + account=a1_tail)) + assertEquals("'dontdivert2@example.com'", + account_store('get', 'variant-file', 'param-account', + account=a2_tail)) + + # Also, MC has both accounts in memory... + assertContains(cs.ACCOUNT_PATH_PREFIX + a1_tail, + properties['ValidAccounts']) + account = get_fakecm_account(bus, mc, cs.ACCOUNT_PATH_PREFIX + a1_tail) + assertEquals('dontdivert1@example.com', + account.Properties.Get(cs.ACCOUNT, 'Parameters')['account']) + assertEquals('First among equals', + account.Properties.Get(cs.ACCOUNT, 'DisplayName')) + assertEquals((dbus.ByteArray('hello, world'), 'text/plain'), + account.Properties.Get(cs.ACCOUNT_IFACE_AVATAR, 'Avatar', + byte_arrays=True)) + + assertContains(cs.ACCOUNT_PATH_PREFIX + a2_tail, + properties['ValidAccounts']) + account = get_fakecm_account(bus, mc, cs.ACCOUNT_PATH_PREFIX + a2_tail) + assertEquals('dontdivert2@example.com', + account.Properties.Get(cs.ACCOUNT, 'Parameters')['account']) + assertEquals('Second to none', + account.Properties.Get(cs.ACCOUNT, 'DisplayName')) + + # ... and no other accounts. + assertLength(2, properties['ValidAccounts']) diff --git a/tests/twisted/account/addressing.py b/tests/twisted/account/addressing.py index e303c935..222546b0 100755 --- a/tests/twisted/account/addressing.py +++ b/tests/twisted/account/addressing.py @@ -31,7 +31,7 @@ def test(q, bus, mc): params = dbus.Dictionary ({"account": "jc.denton@example.com", "password": "ionstorm"}, signature='sv') - (cm_name_ref, account) = create_fakecm_account (q, bus, mc, params) + (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) diff --git a/tests/twisted/capabilities/contact-caps.py b/tests/twisted/capabilities/contact-caps.py index 7a348df0..320a8c5e 100644 --- a/tests/twisted/capabilities/contact-caps.py +++ b/tests/twisted/capabilities/contact-caps.py @@ -33,13 +33,6 @@ from mctest import exec_test, SimulatedConnection, SimulatedClient, \ import constants as cs def test(q, bus, mc): - forbidden = [ - EventPattern('dbus-method-call', handled=False, - interface=cs.CONN_IFACE_CAPS, - method='AdvertiseCapabilities'), - ] - q.forbid_events(forbidden) - # Two clients want to handle channels: MediaCall is running, and AbiWord # is activatable. @@ -56,13 +49,13 @@ def test(q, bus, mc): }, signature='sv') media_fixed_properties = dbus.Dictionary({ - cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_STREAMED_MEDIA, + 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_IFACE_MEDIA_SIGNALLING + '/ice-udp', - cs.CHANNEL_IFACE_MEDIA_SIGNALLING + '/audio/speex', - cs.CHANNEL_IFACE_MEDIA_SIGNALLING + '/video/theora'], + 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 @@ -89,11 +82,11 @@ def test(q, bus, mc): assert len(filters[cs.CLIENT + '.AbiWord']) == 2 assert len(tokens[cs.CLIENT + '.MediaCall']) == 3 - assert cs.CHANNEL_IFACE_MEDIA_SIGNALLING + '/ice-udp' in \ + assert cs.CHANNEL_TYPE_CALL + '/ice' in \ tokens[cs.CLIENT + '.MediaCall'] - assert cs.CHANNEL_IFACE_MEDIA_SIGNALLING + '/audio/speex' in \ + assert cs.CHANNEL_TYPE_CALL + '/audio/speex' in \ tokens[cs.CLIENT + '.MediaCall'] - assert cs.CHANNEL_IFACE_MEDIA_SIGNALLING + '/video/theora' in \ + assert cs.CHANNEL_TYPE_CALL + '/video/theora' in \ tokens[cs.CLIENT + '.MediaCall'] assert len(tokens[cs.CLIENT + '.AbiWord']) == 2 @@ -104,10 +97,9 @@ def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + 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, - cs.CONN_IFACE_CAPS], + extra_interfaces=[cs.CONN_IFACE_CONTACT_CAPS], expect_before_connect=[ EventPattern('dbus-method-call', handled=False, interface=cs.CONN_IFACE_CONTACT_CAPS, diff --git a/tests/twisted/constants.py b/tests/twisted/constants.py index 3a844d54..2a4b69b8 100644 --- a/tests/twisted/constants.py +++ b/tests/twisted/constants.py @@ -1,5 +1,5 @@ # Copyright (C) 2009 Nokia Corporation -# Copyright (C) 2009-2012 Collabora Ltd. +# Copyright (C) 2009-2013 Collabora Ltd. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -21,31 +21,59 @@ Some handy constants for other tests to share and enjoy. """ from dbus import PROPERTIES_IFACE, INTROSPECTABLE_IFACE -from servicetest import tp_name_prefix, tp_path_prefix -CM = "org.freedesktop.Telepathy.ConnectionManager" +PREFIX = "org.freedesktop.Telepathy" +PATH_PREFIX = '/' + PREFIX.replace('.', '/') -DBUS_ERROR_NO_REPLY = 'org.freedesktop.DBus.Error.NoReply' +tp_name_prefix = PREFIX +tp_path_prefix = PATH_PREFIX + +CM = PREFIX + ".ConnectionManager" +HT_NONE = 0 HT_CONTACT = 1 HT_ROOM = 2 +HT_LIST = 3 +HT_GROUP = 4 + +CHANNEL = PREFIX + ".Channel" -CHANNEL = tp_name_prefix + ".Channel" +CHANNEL_IFACE_CALL_STATE = CHANNEL + ".Interface.CallState" +CHANNEL_IFACE_CHAT_STATE = CHANNEL + '.Interface.ChatState' CHANNEL_IFACE_DESTROYABLE = CHANNEL + ".Interface.Destroyable" +CHANNEL_IFACE_DTMF = CHANNEL + ".Interface.DTMF" CHANNEL_IFACE_GROUP = CHANNEL + ".Interface.Group" CHANNEL_IFACE_HOLD = CHANNEL + ".Interface.Hold" CHANNEL_IFACE_MEDIA_SIGNALLING = CHANNEL + ".Interface.MediaSignalling" +CHANNEL_IFACE_MESSAGES = CHANNEL + ".Interface.Messages" +CHANNEL_IFACE_PASSWORD = CHANNEL + ".Interface.Password" +CHANNEL_IFACE_TUBE = CHANNEL + ".Interface.Tube" +CHANNEL_IFACE_SASL_AUTH = CHANNEL + ".Interface.SASLAuthentication" +CHANNEL_IFACE_CONFERENCE = CHANNEL + '.Interface.Conference' +CHANNEL_IFACE_ROOM = CHANNEL + '.Interface.Room2' +CHANNEL_IFACE_ROOM_CONFIG = CHANNEL + '.Interface.RoomConfig1' +CHANNEL_IFACE_SUBJECT = CHANNEL + '.Interface.Subject2' +CHANNEL_IFACE_FILE_TRANSFER_METADATA = CHANNEL + '.Interface.FileTransfer.Metadata' + +CHANNEL_TYPE_CALL = CHANNEL + ".Type.Call1" +CHANNEL_TYPE_CONTACT_LIST = CHANNEL + ".Type.ContactList" +CHANNEL_TYPE_CONTACT_SEARCH = CHANNEL + ".Type.ContactSearch" CHANNEL_TYPE_TEXT = CHANNEL + ".Type.Text" CHANNEL_TYPE_TUBES = CHANNEL + ".Type.Tubes" -CHANNEL_IFACE_TUBE = CHANNEL + ".Interface.Tube" CHANNEL_TYPE_STREAM_TUBE = CHANNEL + ".Type.StreamTube" CHANNEL_TYPE_DBUS_TUBE = CHANNEL + ".Type.DBusTube" -CHANNEL_TYPE_STREAMED_MEDIA = CHANNEL + ".Type.StreamedMedia" CHANNEL_TYPE_TEXT = CHANNEL + ".Type.Text" - -TP_AWKWARD_PROPERTIES = tp_name_prefix + ".Properties" +CHANNEL_TYPE_FILE_TRANSFER = CHANNEL + ".Type.FileTransfer" +CHANNEL_TYPE_ROOM_LIST = CHANNEL + ".Type.RoomList" +CHANNEL_TYPE_SERVER_AUTHENTICATION = \ + CHANNEL + ".Type.ServerAuthentication" +CHANNEL_TYPE_SERVER_TLS_CONNECTION = \ + CHANNEL + ".Type.ServerTLSConnection" + +TP_AWKWARD_PROPERTIES = PREFIX + ".Properties" PROPERTY_FLAG_READ = 1 PROPERTY_FLAG_WRITE = 2 +PROPERTY_FLAGS_RW = PROPERTY_FLAG_READ | PROPERTY_FLAG_WRITE CHANNEL_TYPE = CHANNEL + '.ChannelType' TARGET_HANDLE_TYPE = CHANNEL + '.TargetHandleType' @@ -56,69 +84,200 @@ INITIATOR_HANDLE = CHANNEL + '.InitiatorHandle' INITIATOR_ID = CHANNEL + '.InitiatorID' INTERFACES = CHANNEL + '.Interfaces' -CONN = tp_name_prefix + ".Connection" -CONN_IFACE_ALIASING = CONN + '.Interface.Aliasing' +CALL_CONTENTS = CHANNEL_TYPE_CALL + '.Contents' +CALL_CALL_STATE_DETAILS = CHANNEL_TYPE_CALL + '.CallStateDetails' +CALL_CALL_STATE = CHANNEL_TYPE_CALL + '.CallState' +CALL_CALL_FLAGS = CHANNEL_TYPE_CALL + '.CallFlags' +CALL_CALL_STATE_REASON = CHANNEL_TYPE_CALL + '.CallStateReason' +CALL_HARDWARE_STREAMING = CHANNEL_TYPE_CALL + '.HardwareStreaming' +CALL_CALL_MEMBERS = CHANNEL_TYPE_CALL + '.CallMembers' +CALL_MEMBER_IDENTIFIERS = CHANNEL_TYPE_CALL + '.MemberIdentifiers' +CALL_INITIAL_TRANSPORT = CHANNEL_TYPE_CALL + '.InitialTransport' +CALL_INITIAL_AUDIO = CHANNEL_TYPE_CALL + '.InitialAudio' +CALL_INITIAL_AUDIO_NAME = CHANNEL_TYPE_CALL + '.InitialAudioName' +CALL_INITIAL_VIDEO = CHANNEL_TYPE_CALL + '.InitialVideo' +CALL_INITIAL_VIDEO_NAME = CHANNEL_TYPE_CALL + '.InitialVideoName' +CALL_MUTABLE_CONTENTS = CHANNEL_TYPE_CALL + '.MutableContents' + +CALL_CONTENT = PREFIX + '.Call1.Content' +CALL_CONTENT_IFACE_MEDIA = CALL_CONTENT + '.Interface.Media' +CALL_CONTENT_IFACE_DTMF = CALL_CONTENT + '.Interface.DTMF' + +CALL_CONTENT_MEDIA_DESCRIPTION = CALL_CONTENT + '.MediaDescription' + +CALL_STREAM = PREFIX + '.Call1.Stream' +CALL_STREAM_IFACE_MEDIA = CALL_STREAM + '.Interface.Media' + +CALL_STREAM_ENDPOINT = CALL_STREAM + '.Endpoint' + +CALL_MEDIA_TYPE_AUDIO = 0 +CALL_MEDIA_TYPE_VIDEO = 1 + +CALL_CONTENT_PACKETIZATION_RTP = 0 +CALL_CONTENT_PACKETIZATION_RAW = 1 +CALL_CONTENT_PACKETIZATION_MSN_WEBCAM = 2 + +CALL_STREAM_TRANSPORT_UNKNOWN = 0 +CALL_STREAM_TRANSPORT_RAW_UDP = 1 +CALL_STREAM_TRANSPORT_ICE = 2 +CALL_STREAM_TRANSPORT_GTALK_P2P = 3 +CALL_STREAM_TRANSPORT_WLM_2009 = 4 +CALL_STREAM_TRANSPORT_SHM = 5 +CALL_STREAM_TRANSPORT_MULTICAST = 6 + +CALL_STATE_UNKNOWN = 0 +CALL_STATE_PENDING_INITIATOR = 1 +CALL_STATE_INITIALISING = 2 +CALL_STATE_INITIALISED = 3 +CALL_STATE_ACCEPTED = 4 +CALL_STATE_ACTIVE = 5 +CALL_STATE_ENDED = 6 + +CALL_FLAG_LOCALLY_HELD = 1 +CALL_FLAG_LOCALLY_RINGING = 2 +CALL_FLAG_LOCALLY_QUEUED = 4 +CALL_FLAG_FORWARDED = 8 +CALL_FLAG_CLEARING = 16 + +CALL_MEMBER_FLAG_RINGING = 1 +CALL_MEMBER_FLAG_HELD = 2 + +CALL_DISPOSITION_NONE = 0 +CALL_DISPOSITION_INITIAL = 1 + +CALL_SENDING_STATE_NONE = 0 +CALL_SENDING_STATE_PENDING_SEND = 1 +CALL_SENDING_STATE_SENDING = 2 +CALL_SENDING_STATE_PENDING_STOP_SENDING = 3 + +CALL_STREAM_FLOW_STATE_STOPPED = 0 +CALL_STREAM_FLOW_STATE_PENDING_START = 1 +CALL_STREAM_FLOW_STATE_PENDING_STOP = 2 +CALL_STREAM_FLOW_STATE_STARTED = 3 + +CALL_STREAM_ENDPOINT_STATE_CONNECTING = 0 +CALL_STREAM_ENDPOINT_STATE_PROVISIONALLY_CONNECTED = 1 +CALL_STREAM_ENDPOINT_STATE_FULLY_CONNECTED = 2 +CALL_STREAM_ENDPOINT_STATE_EXHAUSTED_CANDIDATES = 3 +CALL_STREAM_ENDPOINT_STATE_FAILED = 4 + +CALL_STREAM_CANDIDATE_TYPE_HOST = 1 +CALL_STREAM_CANDIDATE_TYPE_SERVER_REFLEXIVE = 2 +CALL_STREAM_CANDIDATE_TYPE_RELAY = 4 + +CALL_STATE_CHANGE_REASON_UNKNOWN = 0 +CALL_STATE_CHANGE_REASON_PROGRESS_MADE = 1 +CALL_STATE_CHANGE_REASON_USER_REQUESTED = 2 +CALL_STATE_CHANGE_REASON_FORWARDED = 3 +CALL_STATE_CHANGE_REASON_REJECTED = 4 +CALL_STATE_CHANGE_REASON_NO_ANSWER = 5 +CALL_STATE_CHANGE_REASON_INVALID_CONTACT = 6 +CALL_STATE_CHANGE_REASON_PERMISSION_DENIED = 7 +CALL_STATE_CHANGE_REASON_BUSY = 8 +CALL_STATE_CHANGE_REASON_INTERNAL_ERROR = 9 +CALL_STATE_CHANGE_REASON_SERVICE_ERROR = 10 +CALL_STATE_CHANGE_REASON_NETWORK_ERROR = 11 +CALL_STATE_CHANGE_REASON_MEDIA_ERROR = 12 +CALL_STATE_CHANGE_REASON_CONNECTIVITY_ERROR = 13 + +CALL_STREAM_COMPONENT_UNKNOWN = 0 +CALL_STREAM_COMPONENT_DATA = 1 +CALL_STREAM_COMPONENT_CONTROL = 2 + +SUBSCRIPTION_STATE_UNKNOWN = 0 +SUBSCRIPTION_STATE_NO = 1 +SUBSCRIPTION_STATE_REMOVED_REMOTELY = 2 +SUBSCRIPTION_STATE_ASK = 3 +SUBSCRIPTION_STATE_YES = 4 + +CONTACT_LIST_STATE_NONE = 0 +CONTACT_LIST_STATE_WAITING = 1 +CONTACT_LIST_STATE_FAILURE = 2 +CONTACT_LIST_STATE_SUCCESS = 3 + +CONN = PREFIX + ".Connection" CONN_IFACE_AVATARS = CONN + '.Interface.Avatars' +CONN_IFACE_ALIASING = CONN + '.Interface.Aliasing' CONN_IFACE_CAPS = CONN + '.Interface.Capabilities' CONN_IFACE_CONTACTS = CONN + '.Interface.Contacts' CONN_IFACE_CONTACT_CAPS = CONN + '.Interface.ContactCapabilities' -CONN_IFACE_REQUESTS = CONN + '.Interface.Requests' +CONN_IFACE_CONTACT_INFO = CONN + ".Interface.ContactInfo" +CONN_IFACE_PRESENCE = CONN + '.Interface.Presence' CONN_IFACE_SIMPLE_PRESENCE = CONN + '.Interface.SimplePresence' +CONN_IFACE_REQUESTS = CONN + '.Interface.Requests' +CONN_IFACE_LOCATION = CONN + '.Interface.Location' +CONN_IFACE_GABBLE_DECLOAK = CONN + '.Interface.Gabble.Decloak' +CONN_IFACE_MAIL_NOTIFICATION = CONN + '.Interface.MailNotification' +CONN_IFACE_CONTACT_LIST = CONN + '.Interface.ContactList' +CONN_IFACE_CONTACT_GROUPS = CONN + '.Interface.ContactGroups' +CONN_IFACE_CLIENT_TYPES = CONN + '.Interface.ClientTypes' CONN_IFACE_POWER_SAVING = CONN + '.Interface.PowerSaving' +CONN_IFACE_CONTACT_BLOCKING = CONN + '.Interface.ContactBlocking' +CONN_IFACE_ADDRESSING = CONN + '.Interface.Addressing1' CONN_IFACE_SERVICE_POINT = CONN + '.Interface.ServicePoint' -CONN_STATUS_CONNECTED = 0 -CONN_STATUS_CONNECTING = 1 -CONN_STATUS_DISCONNECTED = 2 - ATTR_CONTACT_ID = CONN + '/contact-id' ATTR_ALIAS = CONN_IFACE_ALIASING + '/alias' ATTR_AVATAR_TOKEN = CONN_IFACE_AVATARS + '/token' +ATTR_CONTACT_CAPABILITIES = CONN_IFACE_CONTACT_CAPS + '/capabilities' ATTR_PRESENCE = CONN_IFACE_SIMPLE_PRESENCE + '/presence' +ATTR_SUBSCRIBE = CONN_IFACE_CONTACT_LIST + '/subscribe' +ATTR_PUBLISH = CONN_IFACE_CONTACT_LIST + '/publish' +ATTR_GROUPS = CONN_IFACE_CONTACT_GROUPS + '/groups' + +STREAM_HANDLER = PREFIX + '.Media.StreamHandler' -CONN_STATUS_REASON_NONE = 0 -CONN_STATUS_REASON_REQUESTED = 1 -CONN_STATUS_REASON_NETWORK_ERROR = 2 - -GROUP_REASON_NONE = 0 -GROUP_REASON_OFFLINE = 1 -GROUP_REASON_KICKED = 2 -GROUP_REASON_BUSY = 3 -GROUP_REASON_INVITED = 4 -GROUP_REASON_BANNED = 5 -GROUP_REASON_ERROR = 6 -GROUP_REASON_INVALID_CONTACT = 7 -GROUP_REASON_NO_ANSWER = 8 -GROUP_REASON_RENAMED = 9 -GROUP_REASON_PERMISSION_DENIED = 10 -GROUP_REASON_SEPARATED = 11 - -PRESENCE_TYPE_UNSET = 0 -PRESENCE_TYPE_OFFLINE = 1 -PRESENCE_TYPE_AVAILABLE = 2 -PRESENCE_TYPE_AWAY = 3 -PRESENCE_TYPE_XA = 4 -PRESENCE_TYPE_HIDDEN = 5 -PRESENCE_TYPE_BUSY = 6 -PRESENCE_TYPE_UNKNOWN = 7 -PRESENCE_TYPE_ERROR = 8 - -ERROR = tp_name_prefix + '.Error' +ERROR = PREFIX + '.Error' INVALID_ARGUMENT = ERROR + '.InvalidArgument' -INVALID_HANDLE = ERROR + '.InvalidHandle' NOT_IMPLEMENTED = ERROR + '.NotImplemented' NOT_AVAILABLE = ERROR + '.NotAvailable' PERMISSION_DENIED = ERROR + '.PermissionDenied' +OFFLINE = ERROR + '.Offline' +NOT_CAPABLE = ERROR + '.NotCapable' +CONNECTION_REFUSED = ERROR + '.ConnectionRefused' +CONNECTION_FAILED = ERROR + '.ConnectionFailed' +CONNECTION_LOST = ERROR + '.ConnectionLost' CANCELLED = ERROR + '.Cancelled' NOT_YOURS = ERROR + '.NotYours' DISCONNECTED = ERROR + '.Disconnected' -NOT_CAPABLE = ERROR + '.NotCapable' +REGISTRATION_EXISTS = ERROR + '.RegistrationExists' +AUTHENTICATION_FAILED = ERROR + '.AuthenticationFailed' +CONNECTION_REPLACED = ERROR + '.ConnectionReplaced' +ALREADY_CONNECTED = ERROR + '.AlreadyConnected' +NETWORK_ERROR = ERROR + '.NetworkError' +NOT_YET = ERROR + '.NotYet' +INVALID_HANDLE = ERROR + '.InvalidHandle' +CERT_UNTRUSTED = ERROR + '.Cert.Untrusted' +SERVICE_BUSY = ERROR + '.ServiceBusy' +SERVICE_CONFUSED = ERROR + '.ServiceConfused' +SOFTWARE_UPGRADE_REQUIRED = ERROR + '.SoftwareUpgradeRequired' + +BANNED = ERROR + '.Channel.Banned' + +DBUS_ERROR_UNKNOWN_METHOD = 'org.freedesktop.DBus.Error.UnknownMethod' +DBUS_ERROR_NO_REPLY = 'org.freedesktop.DBus.Error.NoReply' TUBE_PARAMETERS = CHANNEL_IFACE_TUBE + '.Parameters' TUBE_STATE = CHANNEL_IFACE_TUBE + '.State' STREAM_TUBE_SERVICE = CHANNEL_TYPE_STREAM_TUBE + '.Service' DBUS_TUBE_SERVICE_NAME = CHANNEL_TYPE_DBUS_TUBE + '.ServiceName' DBUS_TUBE_DBUS_NAMES = CHANNEL_TYPE_DBUS_TUBE + '.DBusNames' +DBUS_TUBE_SUPPORTED_ACCESS_CONTROLS = CHANNEL_TYPE_DBUS_TUBE + '.SupportedAccessControls' +STREAM_TUBE_SUPPORTED_SOCKET_TYPES = CHANNEL_TYPE_STREAM_TUBE + '.SupportedSocketTypes' + +CONFERENCE_INITIAL_CHANNELS = CHANNEL_IFACE_CONFERENCE + '.InitialChannels' +CONFERENCE_INITIAL_INVITEE_HANDLES = CHANNEL_IFACE_CONFERENCE + '.InitialInviteeHandles' +CONFERENCE_INITIAL_INVITEE_IDS = CHANNEL_IFACE_CONFERENCE + '.InitialInviteeIDs' + +CONTACT_SEARCH_ASK = CHANNEL_TYPE_CONTACT_SEARCH + '.AvailableSearchKeys' +CONTACT_SEARCH_SERVER = CHANNEL_TYPE_CONTACT_SEARCH + '.Server' +CONTACT_SEARCH_STATE = CHANNEL_TYPE_CONTACT_SEARCH + '.SearchState' + +SEARCH_NOT_STARTED = 0 +SEARCH_IN_PROGRESS = 1 +SEARCH_MORE_AVAILABLE = 2 +SEARCH_COMPLETED = 3 +SEARCH_FAILED = 4 TUBE_CHANNEL_STATE_LOCAL_PENDING = 0 TUBE_CHANNEL_STATE_REMOTE_PENDING = 1 @@ -128,6 +287,13 @@ TUBE_CHANNEL_STATE_NOT_OFFERED = 3 MEDIA_STREAM_TYPE_AUDIO = 0 MEDIA_STREAM_TYPE_VIDEO = 1 +MEDIA_STREAM_BASE_PROTO_UDP = 0 +MEDIA_STREAM_BASE_PROTO_TCP = 1 + +MEDIA_STREAM_TRANSPORT_TYPE_LOCAL = 0 +MEDIA_STREAM_TRANSPORT_TYPE_DERIVED = 1 +MEDIA_STREAM_TRANSPORT_TYPE_RELAY = 2 + SOCKET_ADDRESS_TYPE_UNIX = 0 SOCKET_ADDRESS_TYPE_ABSTRACT_UNIX = 1 SOCKET_ADDRESS_TYPE_IPV4 = 2 @@ -166,41 +332,287 @@ MEDIA_STREAM_DIRECTION_SEND = 1 MEDIA_STREAM_DIRECTION_RECEIVE = 2 MEDIA_STREAM_DIRECTION_BIDIRECTIONAL = 3 +FT_STATE_NONE = 0 +FT_STATE_PENDING = 1 +FT_STATE_ACCEPTED = 2 +FT_STATE_OPEN = 3 +FT_STATE_COMPLETED = 4 +FT_STATE_CANCELLED = 5 + +FT_STATE_CHANGE_REASON_NONE = 0 +FT_STATE_CHANGE_REASON_REQUESTED = 1 +FT_STATE_CHANGE_REASON_LOCAL_STOPPED = 2 +FT_STATE_CHANGE_REASON_REMOTE_STOPPED = 3 +FT_STATE_CHANGE_REASON_LOCAL_ERROR = 4 +FT_STATE_CHANGE_REASON_REMOTE_ERROR = 5 + +FILE_HASH_TYPE_NONE = 0 +FILE_HASH_TYPE_MD5 = 1 +FILE_HASH_TYPE_SHA1 = 2 +FILE_HASH_TYPE_SHA256 = 3 + +FT_STATE = CHANNEL_TYPE_FILE_TRANSFER + '.State' +FT_CONTENT_TYPE = CHANNEL_TYPE_FILE_TRANSFER + '.ContentType' +FT_FILENAME = CHANNEL_TYPE_FILE_TRANSFER + '.Filename' +FT_SIZE = CHANNEL_TYPE_FILE_TRANSFER + '.Size' +FT_CONTENT_HASH_TYPE = CHANNEL_TYPE_FILE_TRANSFER + '.ContentHashType' +FT_CONTENT_HASH = CHANNEL_TYPE_FILE_TRANSFER + '.ContentHash' +FT_DESCRIPTION = CHANNEL_TYPE_FILE_TRANSFER + '.Description' +FT_DATE = CHANNEL_TYPE_FILE_TRANSFER + '.Date' +FT_AVAILABLE_SOCKET_TYPES = CHANNEL_TYPE_FILE_TRANSFER + '.AvailableSocketTypes' +FT_TRANSFERRED_BYTES = CHANNEL_TYPE_FILE_TRANSFER + '.TransferredBytes' +FT_INITIAL_OFFSET = CHANNEL_TYPE_FILE_TRANSFER + '.InitialOffset' +FT_FILE_COLLECTION = CHANNEL_TYPE_FILE_TRANSFER + '.FUTURE.FileCollection' +FT_URI = CHANNEL_TYPE_FILE_TRANSFER + '.URI' +FT_SERVICE_NAME = CHANNEL_IFACE_FILE_TRANSFER_METADATA + '.ServiceName' +FT_METADATA = CHANNEL_IFACE_FILE_TRANSFER_METADATA + '.Metadata' + +GF_CAN_ADD = 1 +GF_CAN_REMOVE = 2 +GF_CAN_RESCIND = 4 +GF_MESSAGE_ADD = 8 +GF_MESSAGE_REMOVE = 16 +GF_MESSAGE_ACCEPT = 32 +GF_MESSAGE_REJECT = 64 +GF_MESSAGE_RESCIND = 128 +GF_CHANNEL_SPECIFIC_HANDLES = 256 +GF_ONLY_ONE_GROUP = 512 +GF_HANDLE_OWNERS_NOT_AVAILABLE = 1024 +GF_PROPERTIES = 2048 +GF_MEMBERS_CHANGED_DETAILED = 4096 + +GC_REASON_NONE = 0 +GC_REASON_OFFLINE = 1 +GC_REASON_KICKED = 2 +GC_REASON_BUSY = 3 +GC_REASON_INVITED = 4 +GC_REASON_BANNED = 5 +GC_REASON_ERROR = 6 +GC_REASON_INVALID_CONTACT = 7 +GC_REASON_NO_ANSWER = 8 +GC_REASON_RENAMED = 9 +GC_REASON_PERMISSION_DENIED = 10 +GC_REASON_SEPARATED = 11 + +HS_UNHELD = 0 +HS_HELD = 1 +HS_PENDING_HOLD = 2 +HS_PENDING_UNHOLD = 3 + +HSR_NONE = 0 +HSR_REQUESTED = 1 +HSR_RESOURCE_NOT_AVAILABLE = 2 + +CONN_STATUS_CONNECTED = 0 +CONN_STATUS_CONNECTING = 1 +CONN_STATUS_DISCONNECTED = 2 + +CSR_NONE_SPECIFIED = 0 +CSR_REQUESTED = 1 +CSR_NETWORK_ERROR = 2 +CSR_AUTHENTICATION_FAILED = 3 +CSR_ENCRYPTION_ERROR = 4 +CSR_NAME_IN_USE = 5 +CSR_CERT_NOT_PROVIDED = 6 +CSR_CERT_UNTRUSTED = 7 +CSR_CERT_EXPIRED = 8 +CSR_CERT_NOT_ACTIVATED = 9 +CSR_CERT_HOSTNAME_MISMATCH = 10 +CSR_CERT_FINGERPRINT_MISMATCH = 11 +CSR_CERT_SELF_SIGNED = 12 +CSR_CERT_OTHER_ERROR = 13 + +BUDDY_INFO = 'org.laptop.Telepathy.BuddyInfo' +ACTIVITY_PROPERTIES = 'org.laptop.Telepathy.ActivityProperties' + +CHAT_STATE_GONE = 0 +CHAT_STATE_INACTIVE = 1 +CHAT_STATE_ACTIVE = 2 +CHAT_STATE_PAUSED = 3 +CHAT_STATE_COMPOSING = 4 + +# Channel_Media_Capabilities +MEDIA_CAP_AUDIO = 1 +MEDIA_CAP_VIDEO = 2 +MEDIA_CAP_STUN = 4 +MEDIA_CAP_GTALKP2P = 8 +MEDIA_CAP_ICEUDP = 16 +MEDIA_CAP_IMMUTABLE_STREAMS = 32 + +CLIENT = PREFIX + '.Client' + +PRESENCE_UNSET = 0 +PRESENCE_OFFLINE = 1 +PRESENCE_AVAILABLE = 2 +PRESENCE_AWAY = 3 +PRESENCE_EXTENDED_AWAY = 4 +PRESENCE_HIDDEN = 5 +PRESENCE_BUSY = 6 +PRESENCE_UNKNOWN = 7 +PRESENCE_ERROR = 8 + +CONTACT_INFO_FLAG_CAN_SET = 1 +CONTACT_INFO_FLAG_PUSH = 2 +CONTACT_INFO_FIELD_FLAG_PARAMETERS_EXACT = 1 +CONTACT_INFO_FIELD_FLAG_OVERWRITTEN_BY_NICKNAME = 2 + +# Channel_Interface_SaslAuthentication +SASL_STATUS_NOT_STARTED = 0 +SASL_STATUS_IN_PROGRESS = 1 +SASL_STATUS_SERVER_SUCCEEDED = 2 +SASL_STATUS_CLIENT_ACCEPTED = 3 +SASL_STATUS_SUCCEEDED = 4 +SASL_STATUS_SERVER_FAILED = 5 +SASL_STATUS_CLIENT_FAILED = 6 + +SASL_ABORT_REASON_INVALID_CHALLENGE = 0 +SASL_ABORT_REASON_USER_ABORT = 1 + +AUTH_METHOD = CHANNEL_TYPE_SERVER_AUTHENTICATION + ".AuthenticationMethod" +SASL_AVAILABLE_MECHANISMS = CHANNEL_IFACE_SASL_AUTH + ".AvailableMechanisms" +SASL_STATUS = CHANNEL_IFACE_SASL_AUTH + ".SASLStatus" +SASL_ERROR = CHANNEL_IFACE_SASL_AUTH + ".SASLError" +SASL_ERROR_DETAILS = CHANNEL_IFACE_SASL_AUTH + ".SASLErrorDetails" +SASL_CONTEXT = CHANNEL_IFACE_SASL_AUTH + ".SASLContext" +SASL_AUTHORIZATION_IDENTITY = CHANNEL_IFACE_SASL_AUTH + ".AuthorizationIdentity" +SASL_DEFAULT_REALM = CHANNEL_IFACE_SASL_AUTH + ".DefaultRealm" +SASL_DEFAULT_USERNAME = CHANNEL_IFACE_SASL_AUTH + ".DefaultUsername" + +# Channel_Type_ServerTLSConnection +TLS_CERT_PATH = CHANNEL_TYPE_SERVER_TLS_CONNECTION + ".ServerCertificate" +TLS_HOSTNAME = CHANNEL_TYPE_SERVER_TLS_CONNECTION + ".Hostname" +TLS_REFERENCE_IDENTITIES = \ + CHANNEL_TYPE_SERVER_TLS_CONNECTION + ".ReferenceIdentities" + +# Connection.Interface.Location + +LOCATION_FEATURE_CAN_SET = 1 + +# Channel.Type.Text + +MT_NORMAL = 0 +MT_ACTION = 1 +MT_NOTICE = 2 +MT_AUTO_REPLY = 3 +MT_DELIVERY_REPORT = 4 + +class MessageFlag(object): + TRUNCATED = 1 + NON_TEXT_CONTENT = 2 + SCROLLBACK = 4 + RESCUED = 8 + +class SendError(object): + UNKNOWN = 0 + OFFLINE = 1 + INVALID_CONTACT = 2 + PERMISSION_DENIED = 3 + TOO_LONG = 4 + NOT_IMPLEMENTED = 5 + +PROTOCOL = PREFIX + '.Protocol' +PROTOCOL_IFACE_PRESENCES = PROTOCOL + '.Interface.Presence' +PROTOCOL_IFACE_ADDRESSING = PROTOCOL + '.Interface.Addressing' +PROTOCOL_IFACE_AVATARS = PROTOCOL + '.Interface.Avatars' + +PARAM_REQUIRED = 1 +PARAM_REGISTER = 2 +PARAM_HAS_DEFAULT = 4 +PARAM_SECRET = 8 +PARAM_DBUS_PROPERTY = 16 + +AUTHENTICATION = PREFIX + '.Authentication' +AUTH_TLS_CERT = AUTHENTICATION + ".TLSCertificate" + +TLS_CERT_STATE_PENDING = 0 +TLS_CERT_STATE_ACCEPTED = 1 +TLS_CERT_STATE_REJECTED = 2 + +TLS_REJECT_REASON_UNKNOWN = 0 +TLS_REJECT_REASON_UNTRUSTED = 1 + +# Channel.Interface.Messages + +MESSAGE_PART_SUPPORT_FLAGS = CHANNEL_IFACE_MESSAGES + '.MessagePartSupportFlags' +DELIVERY_REPORTING_SUPPORT = CHANNEL_IFACE_MESSAGES + '.DeliveryReportingSupport' +SUPPORTED_CONTENT_TYPES = CHANNEL_IFACE_MESSAGES + '.SupportedContentTypes' + +MSG_SENDING_FLAGS_REPORT_DELIVERY = 1 +MSG_SENDING_FLAGS_REPORT_READ = 2 +MSG_SENDING_FLAGS_REPORT_DELETED = 4 + +DELIVERY_REPORTING_SUPPORT_FLAGS_RECEIVE_FAILURES = 1 +DELIVERY_REPORTING_SUPPORT_FLAGS_RECEIVE_SUCCESSES = 2 +DELIVERY_REPORTING_SUPPORT_FLAGS_RECEIVE_READ = 4 +DELIVERY_REPORTING_SUPPORT_FLAGS_RECEIVE_DELETED = 8 + +DELIVERY_STATUS_UNKNOWN = 0 +DELIVERY_STATUS_DELIVERED = 1 +DELIVERY_STATUS_TEMPORARILY_FAILED = 2 +DELIVERY_STATUS_PERMANENTLY_FAILED = 3 +DELIVERY_STATUS_ACCEPTED = 4 +DELIVERY_STATUS_READ = 5 +DELIVERY_STATUS_DELETED = 6 + +MEDIA_STREAM_ERROR_UNKNOWN = 0 +MEDIA_STREAM_ERROR_EOS = 1 +MEDIA_STREAM_ERROR_CODEC_NEGOTIATION_FAILED = 2 +MEDIA_STREAM_ERROR_CONNECTION_FAILED = 3 +MEDIA_STREAM_ERROR_NETWORK_ERROR = 4 +MEDIA_STREAM_ERROR_NO_CODECS = 5 +MEDIA_STREAM_ERROR_INVALID_CM_BEHAVIOR = 6 +MEDIA_STREAM_ERROR_MEDIA_ERROR = 7 + +PASSWORD_FLAG_PROVIDE = 8 + +# Channel.Interface.Room +ROOM_NAME = CHANNEL_IFACE_ROOM + '.RoomName' +ROOM_SERVER = CHANNEL_IFACE_ROOM + '.Server' + +# Channel.Interface.Subject +SUBJECT = CHANNEL_IFACE_ROOM + '.Subject' +SUBJECT_PRESENT = 1 +SUBJECT_CAN_SET = 2 + +DEBUG_IFACE = PREFIX + '.Debug' +DEBUG_PATH = PATH_PREFIX + '/debug' + SERVICE_POINT_TYPE_NONE = 0 SERVICE_POINT_TYPE_EMERGENCY = 1 SERVICE_POINT_TYPE_COUNSELING = 2 -CLIENT = tp_name_prefix + '.Client' -CLIENT_PATH = tp_path_prefix + '/Client' -OBSERVER = tp_name_prefix + '.Client.Observer' -APPROVER = tp_name_prefix + '.Client.Approver' -HANDLER = tp_name_prefix + '.Client.Handler' +CLIENT = PREFIX + '.Client' +CLIENT_PATH = PATH_PREFIX + '/Client' +OBSERVER = PREFIX + '.Client.Observer' +APPROVER = PREFIX + '.Client.Approver' +HANDLER = PREFIX + '.Client.Handler' CLIENT_IFACE_REQUESTS = CLIENT + '.Interface.Requests' -ACCOUNT = tp_name_prefix + '.Account' +ACCOUNT = PREFIX + '.Account' ACCOUNT_IFACE_AVATAR = ACCOUNT + '.Interface.Avatar' ACCOUNT_IFACE_ADDRESSING = ACCOUNT + '.Interface.Addressing' -ACCOUNT_IFACE_HIDDEN = ACCOUNT + '.Interface.Hidden.DRAFT1' -ACCOUNT_IFACE_NOKIA_CONDITIONS = 'com.nokia.Account.Interface.Conditions' -ACCOUNT_PATH_PREFIX = tp_path_prefix + '/Account/' +ACCOUNT_PATH_PREFIX = PATH_PREFIX + '/Account/' -AM = tp_name_prefix + '.AccountManager' -AM_IFACE_HIDDEN = AM + '.Interface.Hidden.DRAFT1' -AM_PATH = tp_path_prefix + '/AccountManager' +AM = PREFIX + '.AccountManager' +AM_PATH = PATH_PREFIX + '/AccountManager' -CR = tp_name_prefix + '.ChannelRequest' -CDO = tp_name_prefix + '.ChannelDispatchOperation' +CR = PREFIX + '.ChannelRequest' +CDO = PREFIX + '.ChannelDispatchOperation' -CD = tp_name_prefix + '.ChannelDispatcher' -CD_IFACE_OP_LIST = tp_name_prefix + '.ChannelDispatcher.Interface.OperationList' -CD_PATH = tp_path_prefix + '/ChannelDispatcher' +CD = PREFIX + '.ChannelDispatcher' +CD_IFACE_OP_LIST = PREFIX + '.ChannelDispatcher.Interface.OperationList' +CD_PATH = PATH_PREFIX + '/ChannelDispatcher' CD_REDISPATCH = CD + '.Interface.Redispatch.DRAFT' -MC = tp_name_prefix + '.MissionControl5' -MC_PATH = tp_path_prefix + '/MissionControl5' +MC = PREFIX + '.MissionControl5' +MC_PATH = PATH_PREFIX + '/MissionControl5' + +DTMF_CURRENTLY_SENDING_TONES = CHANNEL_IFACE_DTMF + '.CurrentlySendingTones' +DTMF_INITIAL_TONES = CHANNEL_IFACE_DTMF + '.InitialTones' +DTMF_DEFERRED_TONES = CHANNEL_IFACE_DTMF + '.DeferredTones' -TESTDOT = "org.freedesktop.Telepathy.MC.Test." -TESTSLASH = "/org/freedesktop/Telepathy/MC/Test/" +TESTDOT = PREFIX + ".Test." +TESTSLASH = PATH_PREFIX + "/Test/" TEST_DBUS_ACCOUNT_SERVICE = TESTDOT + "DBusAccountService" TEST_DBUS_ACCOUNT_SERVICE_PATH = TESTSLASH + "DBusAccountService" @@ -209,8 +621,8 @@ TEST_DBUS_ACCOUNT_SERVICE_IFACE = TEST_DBUS_ACCOUNT_SERVICE TEST_DBUS_ACCOUNT_PLUGIN_PATH = TESTSLASH + "DBusAccountPlugin" TEST_DBUS_ACCOUNT_PLUGIN_IFACE = TESTDOT + "DBusAccountPlugin" -PARAM_FLAG_REQUIRED = 1 -PARAM_FLAG_REGISTER = 2 -PARAM_FLAG_HAS_DEFAULT = 4 -PARAM_FLAG_SECRET = 8 -PARAM_FLAG_DBUS_PROPERTY = 16 +class StorageRestrictionFlags(object): + CANNOT_SET_PARAMETERS = 1 + CANNOT_SET_ENABLED = 2 + CANNOT_SET_PRESENCE = 4 + CANNOT_SET_SERVICE = 8 diff --git a/tests/twisted/crash-recovery/crash-recovery.py b/tests/twisted/crash-recovery/crash-recovery.py index 2bc45349..1656ab12 100644 --- a/tests/twisted/crash-recovery/crash-recovery.py +++ b/tests/twisted/crash-recovery/crash-recovery.py @@ -27,7 +27,7 @@ import dbus.service from servicetest import EventPattern, call_async from mctest import exec_test, SimulatedConnection, SimulatedClient, \ - create_fakecm_account, enable_fakecm_account, SimulatedChannel, \ + SimulatedChannel, \ expect_client_setup, MC import constants as cs diff --git a/tests/twisted/dbus-account-plugin.c b/tests/twisted/dbus-account-plugin.c index 16b1c9c0..79464ed9 100644 --- a/tests/twisted/dbus-account-plugin.c +++ b/tests/twisted/dbus-account-plugin.c @@ -23,10 +23,15 @@ #include "config.h" #include "dbus-account-plugin.h" +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> + #define DEBUG(format, ...) g_debug ("%s: " format, G_STRFUNC, ##__VA_ARGS__) +#define CRITICAL(format, ...) \ + g_critical ("%s: " format, G_STRFUNC, ##__VA_ARGS__) -#define TESTDOT "org.freedesktop.Telepathy.MC.Test." -#define TESTSLASH "/org/freedesktop/Telepathy/MC/Test/" +#define TESTDOT "org.freedesktop.Telepathy.Test." +#define TESTSLASH "/org/freedesktop/Telepathy/Test/" #define TEST_DBUS_ACCOUNT_SERVICE TESTDOT "DBusAccountService" #define TEST_DBUS_ACCOUNT_SERVICE_PATH TESTSLASH "DBusAccountService" @@ -51,7 +56,8 @@ typedef struct { GHashTable *parameter_flags; /* set of strings */ GHashTable *uncommitted_parameters; - enum { UNCOMMITTED_CREATION, UNCOMMITTED_DELETION } flags; + enum { UNCOMMITTED_CREATION = 1 } flags; + TpStorageRestrictionFlags restrictions; } Account; static void @@ -116,29 +122,6 @@ async_data_free (AsyncData *ad) g_slice_free (AsyncData, ad); } -typedef enum { - EVENT_PARAMS, - EVENT_ATTRS, - EVENT_CREATION, - EVENT_DELETION -} EventType; - -typedef struct { - EventType type; - GVariant *args; -} Event; - -static Event * -event_new (EventType type, - GVariant *args) -{ - Event *e = g_slice_new0 (Event); - - e->type = type; - e->args = g_variant_ref_sink (args); - return e; -} - static Account * lookup_account (TestDBusAccountPlugin *self, const gchar *account_name) @@ -154,7 +137,7 @@ ensure_account (TestDBusAccountPlugin *self, if (account == NULL) { - account = g_slice_new (Account); + account = g_slice_new0 (Account); account->path = g_strdup_printf ("%s%s", TP_ACCOUNT_OBJECT_PATH_BASE, account_name); @@ -179,7 +162,6 @@ ensure_account (TestDBusAccountPlugin *self, g_hash_table_insert (self->accounts, g_strdup (account_name), account); } - account->flags &= ~UNCOMMITTED_DELETION; return account; } @@ -207,18 +189,14 @@ service_vanished_cb (GDBusConnection *bus, { TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (user_data); GHashTableIter iter; - gpointer k, v; + gpointer k; self->active = FALSE; g_hash_table_iter_init (&iter, self->accounts); - while (g_hash_table_iter_next (&iter, &k, &v)) + while (g_hash_table_iter_next (&iter, &k, NULL)) { - Account *account = v; - - if ((account->flags & UNCOMMITTED_DELETION) == 0) - mcp_account_storage_emit_deleted (MCP_ACCOUNT_STORAGE (self), k); - + mcp_account_storage_emit_deleted (MCP_ACCOUNT_STORAGE (self), k); g_hash_table_iter_remove (&iter); } @@ -264,7 +242,8 @@ test_dbus_account_plugin_add_account (TestDBusAccountPlugin *self, GVariant *attribute_flags, GVariant *parameters, GVariant *untyped_parameters, - GVariant *param_flags) + GVariant *param_flags, + TpStorageRestrictionFlags restrictions) { GVariantIter iter; const gchar *k; @@ -303,13 +282,21 @@ test_dbus_account_plugin_add_account (TestDBusAccountPlugin *self, g_hash_table_insert (account->parameter_flags, g_strdup (k), GUINT_TO_POINTER (u)); + account->restrictions = restrictions; + return account; } static void -test_dbus_account_plugin_process_account_creation (TestDBusAccountPlugin *self, - GVariant *args) +account_created_cb (GDBusConnection *bus, + const gchar *sender_name, + const gchar *object_path, + const gchar *iface_name, + const gchar *signal_name, + GVariant *tuple, + gpointer user_data) { + TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (user_data); const gchar *account_name; Account *account; GVariant *attrs; @@ -317,10 +304,12 @@ test_dbus_account_plugin_process_account_creation (TestDBusAccountPlugin *self, GVariant *untyped_params; GVariant *attr_flags; GVariant *param_flags; + guint32 restrictions; - g_variant_get (args, "(&s@a{sv}@a{su}@a{sv}@a{ss}@a{su})", + g_variant_get (tuple, "(&s@a{sv}@a{su}@a{sv}@a{ss}@a{su}u)", &account_name, &attrs, &attr_flags, - ¶ms, &untyped_params, ¶m_flags); + ¶ms, &untyped_params, ¶m_flags, + &restrictions); DEBUG ("%s", account_name); account = lookup_account (self, account_name); @@ -336,7 +325,7 @@ test_dbus_account_plugin_process_account_creation (TestDBusAccountPlugin *self, * a lot of rubbish */ account = test_dbus_account_plugin_add_account (self, account_name, attrs, attr_flags, - params, untyped_params, param_flags); + params, untyped_params, param_flags, restrictions); mcp_account_storage_emit_created ( MCP_ACCOUNT_STORAGE (self), account_name); @@ -355,19 +344,25 @@ test_dbus_account_plugin_process_account_creation (TestDBusAccountPlugin *self, } static void -test_dbus_account_plugin_process_account_deletion (TestDBusAccountPlugin *self, - GVariant *args) +account_deleted_cb (GDBusConnection *bus, + const gchar *sender_name, + const gchar *object_path, + const gchar *iface_name, + const gchar *signal_name, + GVariant *tuple, + gpointer user_data) { + TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (user_data); const gchar *account_name; Account *account; - g_variant_get (args, "(&s)", &account_name); + g_variant_get (tuple, "(&s)", &account_name); DEBUG ("%s", account_name); account = lookup_account (self, account_name); if (account == NULL) { - g_warning ("accounts service deleted %s but we don't " + CRITICAL ("accounts service deleted %s but we don't " "have any record of that account", account_name); } else @@ -389,23 +384,29 @@ test_dbus_account_plugin_process_account_deletion (TestDBusAccountPlugin *self, } static void -test_dbus_account_plugin_process_attributes (TestDBusAccountPlugin *self, - GVariant *args) +attributes_changed_cb (GDBusConnection *bus, + const gchar *sender_name, + const gchar *object_path, + const gchar *iface_name, + const gchar *signal_name, + GVariant *tuple, + gpointer user_data) { + TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (user_data); const gchar *account_name; Account *account; GVariant *attrs; GVariant *attr_flags; GVariant *deleted; - g_variant_get (args, "(&s@a{sv}@a{su}@as)", + g_variant_get (tuple, "(&s@a{sv}@a{su}@as)", &account_name, &attrs, &attr_flags, &deleted); DEBUG ("%s", account_name); account = lookup_account (self, account_name); if (account == NULL) { - g_warning ("accounts service altered %s but we don't " + CRITICAL ("accounts service altered %s but we don't " "have any record of that account", account_name); } else @@ -439,8 +440,6 @@ test_dbus_account_plugin_process_attributes (TestDBusAccountPlugin *self, g_hash_table_insert (account->attributes, g_strdup (attr), g_variant_ref (value)); - mcp_account_manager_set_attribute (self->feedback, - account_name, attr, value, flags); mcp_account_storage_emit_altered_one ( MCP_ACCOUNT_STORAGE (self), account_name, attr); @@ -464,8 +463,6 @@ test_dbus_account_plugin_process_attributes (TestDBusAccountPlugin *self, DEBUG ("%s deleted", attr); g_hash_table_remove (account->attributes, attr); - mcp_account_manager_set_attribute (self->feedback, - account_name, attr, NULL, 0); mcp_account_storage_emit_altered_one ( MCP_ACCOUNT_STORAGE (self), account_name, attr); @@ -499,9 +496,15 @@ test_dbus_account_plugin_process_attributes (TestDBusAccountPlugin *self, } static void -test_dbus_account_plugin_process_parameters (TestDBusAccountPlugin *self, - GVariant *args) +parameters_changed_cb (GDBusConnection *bus, + const gchar *sender_name, + const gchar *object_path, + const gchar *iface_name, + const gchar *signal_name, + GVariant *tuple, + gpointer user_data) { + TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (user_data); const gchar *account_name; Account *account; GVariant *params; @@ -509,14 +512,14 @@ test_dbus_account_plugin_process_parameters (TestDBusAccountPlugin *self, GVariant *param_flags; GVariant *deleted; - g_variant_get (args, "(&s@a{sv}@a{ss}@a{su}@as)", + g_variant_get (tuple, "(&s@a{sv}@a{ss}@a{su}@as)", &account_name, ¶ms, &untyped_params, ¶m_flags, &deleted); DEBUG ("%s", account_name); account = lookup_account (self, account_name); if (account == NULL) { - g_warning ("accounts service altered %s but we don't " + CRITICAL ("accounts service altered %s but we don't " "have any record of that account", account_name); } else @@ -548,8 +551,6 @@ test_dbus_account_plugin_process_parameters (TestDBusAccountPlugin *self, g_hash_table_insert (account->parameters, g_strdup (param), g_variant_ref (value)); key = g_strdup_printf ("param-%s", param); - mcp_account_manager_set_parameter (self->feedback, - account_name, param, value, flags); mcp_account_storage_emit_altered_one ( MCP_ACCOUNT_STORAGE (self), account_name, key); g_free (key); @@ -577,11 +578,10 @@ test_dbus_account_plugin_process_parameters (TestDBusAccountPlugin *self, (stored == NULL || !g_variant_equal (value, stored))) { + g_hash_table_remove (account->parameters, param); g_hash_table_insert (account->untyped_parameters, g_strdup (param), g_strdup (escaped)); key = g_strdup_printf ("param-%s", param); - mcp_account_manager_set_value (self->feedback, - account_name, key, escaped); mcp_account_storage_emit_altered_one ( MCP_ACCOUNT_STORAGE (self), account_name, key); g_free (key); @@ -611,8 +611,6 @@ test_dbus_account_plugin_process_parameters (TestDBusAccountPlugin *self, g_hash_table_remove (account->untyped_parameters, param); key = g_strdup_printf ("param-%s", param); - mcp_account_manager_set_parameter (self->feedback, - account_name, param, NULL, 0); mcp_account_storage_emit_altered_one ( MCP_ACCOUNT_STORAGE (self), account_name, key); g_free (key); @@ -633,126 +631,9 @@ test_dbus_account_plugin_process_parameters (TestDBusAccountPlugin *self, g_variant_unref (deleted); } -static void -test_dbus_account_plugin_process_events (TestDBusAccountPlugin *self) -{ - Event *event; - - if (self->feedback == NULL) - return; - - while ((event = g_queue_pop_head (&self->events)) != NULL) - { - switch (event->type) - { - case EVENT_CREATION: - test_dbus_account_plugin_process_account_creation (self, - event->args); - break; - - case EVENT_DELETION: - test_dbus_account_plugin_process_account_deletion (self, - event->args); - break; - - case EVENT_ATTRS: - test_dbus_account_plugin_process_attributes (self, - event->args); - break; - - case EVENT_PARAMS: - test_dbus_account_plugin_process_parameters (self, - event->args); - break; - } - - g_variant_unref (event->args); - g_slice_free (Event, event); - } -} - -static void -account_created_cb (GDBusConnection *bus, - const gchar *sender_name, - const gchar *object_path, - const gchar *iface_name, - const gchar *signal_name, - GVariant *tuple, - gpointer user_data) -{ - TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (user_data); - const gchar *account_name; - - g_variant_get (tuple, "(&s@a{sv}@a{su}@a{sv}@a{ss}@a{su})", - &account_name, NULL, NULL, NULL, NULL, NULL); - DEBUG ("%s", account_name); - - g_queue_push_tail (&self->events, event_new (EVENT_CREATION, tuple)); - test_dbus_account_plugin_process_events (self); -} - -static void -account_deleted_cb (GDBusConnection *bus, - const gchar *sender_name, - const gchar *object_path, - const gchar *iface_name, - const gchar *signal_name, - GVariant *tuple, - gpointer user_data) -{ - TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (user_data); - const gchar *account_name; - - g_variant_get (tuple, "(&s)", &account_name); - DEBUG ("%s", account_name); - - g_queue_push_tail (&self->events, event_new (EVENT_DELETION, tuple)); - test_dbus_account_plugin_process_events (self); -} - -static void -attributes_changed_cb (GDBusConnection *bus, - const gchar *sender_name, - const gchar *object_path, - const gchar *iface_name, - const gchar *signal_name, - GVariant *tuple, - gpointer user_data) -{ - TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (user_data); - const gchar *account_name; - - g_variant_get (tuple, "(&s@a{sv}@a{su}@as)", &account_name, - NULL, NULL, NULL); - DEBUG ("%s", account_name); - - g_queue_push_tail (&self->events, event_new (EVENT_ATTRS, tuple)); - test_dbus_account_plugin_process_events (self); -} - -static void -parameters_changed_cb (GDBusConnection *bus, - const gchar *sender_name, - const gchar *object_path, - const gchar *iface_name, - const gchar *signal_name, - GVariant *tuple, - gpointer user_data) -{ - TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (user_data); - const gchar *account_name; - - g_variant_get (tuple, "(&s@a{sv}@a{ss}@a{su}@as)", &account_name, - NULL, NULL, NULL, NULL); - DEBUG ("%s", account_name); - - g_queue_push_tail (&self->events, event_new (EVENT_PARAMS, tuple)); - test_dbus_account_plugin_process_events (self); -} - static GList * -test_dbus_account_plugin_list (const McpAccountStorage *storage, - const McpAccountManager *am) +test_dbus_account_plugin_list (McpAccountStorage *storage, + McpAccountManager *am) { TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); GError *error = NULL; @@ -762,6 +643,7 @@ test_dbus_account_plugin_list (const McpAccountStorage *storage, GVariantIter account_iter; const gchar *account_name; GList *ret = NULL; + guint32 restrictions; DEBUG ("called"); @@ -820,7 +702,7 @@ test_dbus_account_plugin_list (const McpAccountStorage *storage, TEST_DBUS_ACCOUNT_SERVICE_IFACE, "GetAccounts", NULL, /* no parameters */ - G_VARIANT_TYPE ("(a{s(a{sv}a{su}a{sv}a{ss}a{su})})"), + G_VARIANT_TYPE ("(a{s(a{sv}a{su}a{sv}a{ss}a{su}u)})"), G_DBUS_CALL_FLAGS_NONE, -1, NULL, /* no cancellable */ @@ -843,13 +725,13 @@ test_dbus_account_plugin_list (const McpAccountStorage *storage, g_variant_iter_init (&account_iter, accounts); while (g_variant_iter_loop (&account_iter, - "{s(@a{sv}@a{su}@a{sv}@a{ss}@a{su})}", &account_name, + "{s(@a{sv}@a{su}@a{sv}@a{ss}@a{su}u)}", &account_name, &attributes, &attribute_flags, - ¶meters, &untyped_parameters, ¶m_flags)) + ¶meters, &untyped_parameters, ¶m_flags, &restrictions)) { test_dbus_account_plugin_add_account (self, account_name, attributes, attribute_flags, parameters, untyped_parameters, - param_flags); + param_flags, restrictions); ret = g_list_prepend (ret, g_strdup (account_name)); } @@ -859,27 +741,12 @@ test_dbus_account_plugin_list (const McpAccountStorage *storage, return ret; } -static void -test_dbus_account_plugin_ready (const McpAccountStorage *storage, - const McpAccountManager *am) -{ - TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); - - DEBUG ("called"); - g_dbus_connection_emit_signal (self->bus, NULL, - TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, - "Ready", NULL, NULL); - self->feedback = MCP_ACCOUNT_MANAGER (am); - - test_dbus_account_plugin_process_events (self); -} - static gchar * -test_dbus_account_plugin_create (const McpAccountStorage *storage, - const McpAccountManager *am, +test_dbus_account_plugin_create (McpAccountStorage *storage, + McpAccountManager *am, const gchar *manager, const gchar *protocol, - GHashTable *params, + const gchar *identifier, GError **error) { TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); @@ -890,7 +757,7 @@ test_dbus_account_plugin_create (const McpAccountStorage *storage, return FALSE; name = mcp_account_manager_get_unique_name ((McpAccountManager *) am, - manager, protocol, params); + manager, protocol, identifier); account = ensure_account (self, name); g_dbus_connection_emit_signal (self->bus, NULL, TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, @@ -898,218 +765,192 @@ test_dbus_account_plugin_create (const McpAccountStorage *storage, return name; } -static gboolean -test_dbus_account_plugin_delete (const McpAccountStorage *storage, - const McpAccountManager *am, +static void delete_account_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data); + +static void +test_dbus_account_plugin_delete_async (McpAccountStorage *storage, + McpAccountManager *am, const gchar *account_name, - const gchar *key) + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); Account *account = lookup_account (self, account_name); + GTask *task = g_task_new (self, cancellable, callback, user_data); - DEBUG ("called"); - - if (account == NULL || !self->active) - return FALSE; - - if (key == NULL) - { - account->flags |= UNCOMMITTED_DELETION; - g_hash_table_remove_all (account->attributes); - g_hash_table_remove_all (account->parameters); - g_hash_table_remove_all (account->untyped_parameters); - g_hash_table_remove_all (account->attribute_flags); - g_hash_table_remove_all (account->parameter_flags); + g_task_set_task_data (task, g_strdup (user_data), g_free); - account->flags &= ~UNCOMMITTED_CREATION; - g_hash_table_remove_all (account->uncommitted_attributes); - g_hash_table_remove_all (account->uncommitted_parameters); - - g_dbus_connection_emit_signal (self->bus, NULL, - TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, - "DeferringDelete", g_variant_new_parsed ("(%o,)", account->path), - NULL); - } - else if (g_str_has_prefix (key, "param-")) - { - g_hash_table_remove (account->parameters, key + 6); - g_hash_table_remove (account->untyped_parameters, key + 6); - g_hash_table_remove (account->parameter_flags, key + 6); - g_hash_table_add (account->uncommitted_parameters, g_strdup (key + 6)); + DEBUG ("called"); - g_dbus_connection_emit_signal (self->bus, NULL, - TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, - "DeferringDeleteParameter", - g_variant_new_parsed ("(%o, %s)", account->path, key + 6), NULL); - } - else - { - g_hash_table_remove (account->attributes, key); - g_hash_table_remove (account->attribute_flags, key); - g_hash_table_add (account->uncommitted_attributes, g_strdup (key)); + g_return_if_fail (self->active); + g_return_if_fail (account != NULL); - g_dbus_connection_emit_signal (self->bus, NULL, - TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, - "DeferringDeleteAttribute", - g_variant_new_parsed ("(%o, %s)", account->path, key), NULL); - } + /* deletion used to be delayed, so the regression tests will expect this + * to happen - leave them unmodified for now */ + g_dbus_connection_emit_signal (self->bus, NULL, + TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, + "DeferringDelete", g_variant_new_parsed ("(%o,)", account->path), + NULL); + g_dbus_connection_emit_signal (self->bus, NULL, + TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, + "CommittingOne", g_variant_new_parsed ("(%o,)", account->path), NULL); - return TRUE; + g_dbus_connection_call (self->bus, + TEST_DBUS_ACCOUNT_SERVICE, + TEST_DBUS_ACCOUNT_SERVICE_PATH, + TEST_DBUS_ACCOUNT_SERVICE_IFACE, + "DeleteAccount", + g_variant_new_parsed ("(%s,)", account_name), + G_VARIANT_TYPE_UNIT, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, /* no cancellable */ + delete_account_cb, + task); } static gboolean -test_dbus_account_plugin_get (const McpAccountStorage *storage, - const McpAccountManager *am, +test_dbus_account_plugin_delete_finish (McpAccountStorage *storage, + GAsyncResult *res, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (res), error); +} + +static GVariant * +test_dbus_account_plugin_get_attribute (McpAccountStorage *storage, + McpAccountManager *am, const gchar *account_name, - const gchar *key) + const gchar *attribute, + const GVariantType *type, + McpAttributeFlags *flags) { TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); Account *account = lookup_account (self, account_name); + GVariant *v; - if (!self->active || account == NULL || (account->flags & UNCOMMITTED_DELETION)) - return FALSE; - - if (key == NULL) - { - GHashTableIter iter; - gpointer k, v; - - /* get everything */ - g_dbus_connection_emit_signal (self->bus, NULL, - TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, - "GetAllKeys", - g_variant_new_parsed ("(%o,)", account->path), NULL); - - g_hash_table_iter_init (&iter, account->attributes); - - while (g_hash_table_iter_next (&iter, &k, &v)) - { - gchar *escaped = mcp_account_manager_escape_variant_for_keyfile (am, - v); + if (flags != NULL) + *flags = 0; - mcp_account_manager_set_value (am, account_name, k, escaped); - g_free (escaped); - } + g_return_val_if_fail (self->active, NULL); + g_return_val_if_fail (account != NULL, NULL); - g_hash_table_iter_init (&iter, account->untyped_parameters); + v = g_hash_table_lookup (account->attributes, attribute); - while (g_hash_table_iter_next (&iter, &k, &v)) - { - gchar *param_foo; - McpParameterFlags flags; - - param_foo = g_strdup_printf ("param-%s", (const gchar *) k); - mcp_account_manager_set_value (am, account_name, param_foo, v); + g_dbus_connection_emit_signal (self->bus, NULL, + TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, + "GetAttribute", + g_variant_new_parsed ("(%o, %s)", account->path, attribute), NULL); - flags = GPOINTER_TO_UINT (g_hash_table_lookup ( - account->parameter_flags, k)); + if (v != NULL) + { + return g_variant_ref (v); + } + else + { + return NULL; + } +} - if (flags & MCP_PARAMETER_FLAG_SECRET) - mcp_account_manager_parameter_make_secret (am, account_name, - param_foo); +static GVariant * +test_dbus_account_plugin_get_parameter (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account_name, + const gchar *parameter, + const GVariantType *type, + McpParameterFlags *flags) +{ + TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); + Account *account = lookup_account (self, account_name); + GVariant *v; + const gchar *s; - g_free (param_foo); - } + if (flags != NULL) + *flags = 0; - g_hash_table_iter_init (&iter, account->parameters); + g_return_val_if_fail (self->active, NULL); + g_return_val_if_fail (account != NULL, NULL); - while (g_hash_table_iter_next (&iter, &k, &v)) - { - gchar *param_foo; - guint32 flags; - gchar *escaped = mcp_account_manager_escape_variant_for_keyfile (am, - v); + g_dbus_connection_emit_signal (self->bus, NULL, + TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, + "GetParameter", + g_variant_new_parsed ("(%o, %s)", account->path, parameter), NULL); - param_foo = g_strdup_printf ("param-%s", (const gchar *) k); - mcp_account_manager_set_value (am, account_name, param_foo, escaped); - g_free (escaped); + v = g_hash_table_lookup (account->parameters, parameter); + s = g_hash_table_lookup (account->untyped_parameters, parameter); - flags = GPOINTER_TO_UINT (g_hash_table_lookup (account->parameter_flags, - k)); + if (v != NULL) + { + return g_variant_ref (v); + } + else if (s != NULL && type != NULL) + { + return mcp_account_manager_unescape_variant_from_keyfile (am, + s, type, NULL); + } + else + { + return NULL; + } +} - if (flags & MCP_PARAMETER_FLAG_SECRET) - mcp_account_manager_parameter_make_secret (am, account_name, - param_foo); +static gchar ** +test_dbus_account_plugin_list_typed_parameters (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account_name) +{ + TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); + Account *account = lookup_account (self, account_name); + GPtrArray *arr; + GHashTableIter iter; + gpointer k; - g_free (param_foo); - } + g_return_val_if_fail (self->active, NULL); + g_return_val_if_fail (account != NULL, NULL); - return TRUE; - } + arr = g_ptr_array_sized_new (g_hash_table_size (account->parameters) + 1); - /* get one parameter */ + g_hash_table_iter_init (&iter, account->parameters); - if (g_str_has_prefix (key, "param-")) - { - GVariant *v = g_hash_table_lookup (account->parameters, key + 6); - const gchar *s = g_hash_table_lookup (account->untyped_parameters, key + 6); - guint32 flags = GPOINTER_TO_UINT ( - g_hash_table_lookup (account->parameter_flags, key + 6)); + while (g_hash_table_iter_next (&iter, &k, NULL)) + g_ptr_array_add (arr, g_strdup (k)); - g_dbus_connection_emit_signal (self->bus, NULL, - TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, - "GetParameter", - g_variant_new_parsed ("(%o, %s)", account->path, key + 6), NULL); + g_ptr_array_add (arr, NULL); - if (flags & MCP_PARAMETER_FLAG_SECRET) - mcp_account_manager_parameter_make_secret (am, account_name, key); + return (gchar **) g_ptr_array_free (arr, FALSE); +} - if (v != NULL) - { - gchar *escaped = mcp_account_manager_escape_variant_for_keyfile (am, - v); +static gchar ** +test_dbus_account_plugin_list_untyped_parameters (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account_name) +{ + TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); + Account *account = lookup_account (self, account_name); + GPtrArray *arr; + GHashTableIter iter; + gpointer k; - mcp_account_manager_set_value (am, account_name, key, escaped); - g_free (escaped); - } - else if (s != NULL) - { - mcp_account_manager_set_value (am, account_name, key, s); - } - else - { - return FALSE; - } - } - else - { - GVariant *v = g_hash_table_lookup (account->attributes, key); + g_return_val_if_fail (self->active, NULL); + g_return_val_if_fail (account != NULL, NULL); - g_dbus_connection_emit_signal (self->bus, NULL, - TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, - "GetAttribute", - g_variant_new_parsed ("(%o, %s)", account->path, key), NULL); + arr = g_ptr_array_sized_new ( + g_hash_table_size (account->untyped_parameters) + 1); - if (v != NULL) - { - gchar *escaped = mcp_account_manager_escape_variant_for_keyfile (am, - v); + g_hash_table_iter_init (&iter, account->untyped_parameters); - mcp_account_manager_set_value (am, account_name, key, escaped); - g_free (escaped); - } - else - { - return FALSE; - } - } + while (g_hash_table_iter_next (&iter, &k, NULL)) + g_ptr_array_add (arr, g_strdup (k)); - return TRUE; -} + g_ptr_array_add (arr, NULL); -static gboolean -test_dbus_account_plugin_set (const McpAccountStorage *storage, - const McpAccountManager *am, - const gchar *account_name, - const gchar *key, - const gchar *value) -{ - /* Now that we implement set_attribute and set_parameter, this no longer - * needs a real implementation. */ - return FALSE; + return (gchar **) g_ptr_array_free (arr, FALSE); } -static gboolean +static McpAccountStorageSetResult test_dbus_account_plugin_set_attribute (McpAccountStorage *storage, McpAccountManager *am, const gchar *account_name, @@ -1119,17 +960,40 @@ test_dbus_account_plugin_set_attribute (McpAccountStorage *storage, { TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); Account *account = lookup_account (self, account_name); + GVariant *old; + guint old_flags; g_return_val_if_fail (account_name != NULL, FALSE); g_return_val_if_fail (attribute != NULL, FALSE); - /* for deletions, MC would call delete() instead */ - g_return_val_if_fail (value != NULL, FALSE); DEBUG ("%s of %s", attribute, account_name); - if (!self->active || account == NULL || - (account->flags & UNCOMMITTED_DELETION)) - return FALSE; + g_return_val_if_fail (self->active, MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED); + g_return_val_if_fail (account != NULL, MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED); + + if (value == NULL) + { + if (!g_hash_table_contains (account->attributes, attribute)) + return MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED; + + g_hash_table_remove (account->attributes, attribute); + g_hash_table_remove (account->attribute_flags, attribute); + g_hash_table_add (account->uncommitted_attributes, g_strdup (attribute)); + + g_dbus_connection_emit_signal (self->bus, NULL, + TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, + "DeferringDeleteAttribute", + g_variant_new_parsed ("(%o, %s)", account->path, attribute), NULL); + + return MCP_ACCOUNT_STORAGE_SET_RESULT_CHANGED; + } + + old = g_hash_table_lookup (account->attributes, attribute); + old_flags = GPOINTER_TO_UINT (g_hash_table_lookup ( + account->attribute_flags, attribute)); + + if (old != NULL && g_variant_equal (old, value) && old_flags == flags) + return MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED; g_hash_table_insert (account->attributes, g_strdup (attribute), g_variant_ref (value)); @@ -1143,10 +1007,10 @@ test_dbus_account_plugin_set_attribute (McpAccountStorage *storage, g_variant_new_parsed ("(%o, %s, %v)", account->path, attribute, value), NULL); - return TRUE; + return MCP_ACCOUNT_STORAGE_SET_RESULT_CHANGED; } -static gboolean +static McpAccountStorageSetResult test_dbus_account_plugin_set_parameter (McpAccountStorage *storage, McpAccountManager *am, const gchar *account_name, @@ -1156,17 +1020,42 @@ test_dbus_account_plugin_set_parameter (McpAccountStorage *storage, { TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); Account *account = lookup_account (self, account_name); + GVariant *old; + guint old_flags; g_return_val_if_fail (account_name != NULL, FALSE); g_return_val_if_fail (parameter != NULL, FALSE); - /* for deletions, MC would call delete() instead */ - g_return_val_if_fail (value != NULL, FALSE); DEBUG ("%s of %s", parameter, account_name); - if (!self->active || account == NULL || - (account->flags & UNCOMMITTED_DELETION)) - return FALSE; + g_return_val_if_fail (self->active, MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED); + g_return_val_if_fail (account != NULL, MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED); + + if (value == NULL) + { + if (!g_hash_table_contains (account->parameters, parameter) && + !g_hash_table_contains (account->untyped_parameters, parameter)) + return MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED; + + g_hash_table_remove (account->parameters, parameter); + g_hash_table_remove (account->untyped_parameters, parameter); + g_hash_table_remove (account->parameter_flags, parameter); + g_hash_table_add (account->uncommitted_parameters, g_strdup (parameter)); + + g_dbus_connection_emit_signal (self->bus, NULL, + TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, + "DeferringDeleteParameter", + g_variant_new_parsed ("(%o, %s)", account->path, parameter), NULL); + + return TRUE; + } + + old = g_hash_table_lookup (account->parameters, parameter); + old_flags = GPOINTER_TO_UINT (g_hash_table_lookup ( + account->parameter_flags, parameter)); + + if (old != NULL && g_variant_equal (old, value) && old_flags == flags) + return MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED; g_hash_table_remove (account->untyped_parameters, parameter); g_hash_table_insert (account->parameters, g_strdup (parameter), @@ -1181,37 +1070,7 @@ test_dbus_account_plugin_set_parameter (McpAccountStorage *storage, g_variant_new_parsed ("(%o, %s, %v)", account->path, parameter, value), NULL); - return TRUE; -} - -static gboolean -test_dbus_account_plugin_commit (const McpAccountStorage *storage, - const McpAccountManager *am) -{ - TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); - GHashTableIter iter; - gpointer k; - - DEBUG ("called"); - - if (!self->active) - return FALSE; - - g_dbus_connection_emit_signal (self->bus, NULL, - TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, - "CommittingAll", NULL, NULL); - - g_hash_table_iter_init (&iter, self->accounts); - - while (g_hash_table_iter_next (&iter, &k, NULL)) - { - if (!mcp_account_storage_commit_one (storage, am, k)) - { - g_warning ("declined to commit account %s", (const gchar *) k); - } - } - - return TRUE; + return MCP_ACCOUNT_STORAGE_SET_RESULT_CHANGED; } static void @@ -1219,27 +1078,31 @@ delete_account_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { - AsyncData *ad = user_data; + GTask *task = user_data; GVariant *tuple; GError *error = NULL; + TestDBusAccountPlugin *self = g_task_get_source_object (task); + const gchar *account_name = g_task_get_task_data (task); - tuple = g_dbus_connection_call_finish (ad->self->bus, res, &error); + tuple = g_dbus_connection_call_finish (self->bus, res, &error); if (tuple != NULL) { - g_hash_table_remove (ad->self->accounts, ad->account_name); + /* we'll emit ::deleted when we see the signal, which probably + * already happened */ + g_hash_table_remove (self->accounts, account_name); g_variant_unref (tuple); + g_task_return_boolean (task, TRUE); } else { - g_warning ("Unable to delete account %s: %s", ad->account_name, - error->message); - g_clear_error (&error); - /* FIXME: we could roll back the deletion by claiming that - * the service re-created the account? */ + g_prefix_error (&error, "Unable to delete account %s: ", + account_name); + g_warning ("%s", error->message); + g_task_return_error (task, error); } - async_data_free (ad); + g_object_unref (task); } static void @@ -1345,12 +1208,12 @@ update_parameters_cb (GObject *source_object, } static gboolean -test_dbus_account_plugin_commit_one (const McpAccountStorage *storage, - const McpAccountManager *am, +test_dbus_account_plugin_commit (McpAccountStorage *storage, + McpAccountManager *am, const gchar *account_name) { TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); - Account *account = lookup_account (self, account_name); + Account *account; GHashTableIter iter; gpointer k; GVariantBuilder a_sv_builder; @@ -1360,36 +1223,15 @@ test_dbus_account_plugin_commit_one (const McpAccountStorage *storage, DEBUG ("%s", account_name); - /* MC does not call @commit_one with parameter %NULL (meaning "all accounts") - * if we also implement commit(), which, as it happens, we do */ - g_return_val_if_fail (account_name != NULL, FALSE); + account = lookup_account (self, account_name); - if (!self->active || account == NULL) - return FALSE; + g_return_val_if_fail (self->active, FALSE); + g_return_val_if_fail (account != NULL, FALSE); g_dbus_connection_emit_signal (self->bus, NULL, TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, "CommittingOne", g_variant_new_parsed ("(%o,)", account->path), NULL); - if (account->flags & UNCOMMITTED_DELETION) - { - g_dbus_connection_call (self->bus, - TEST_DBUS_ACCOUNT_SERVICE, - TEST_DBUS_ACCOUNT_SERVICE_PATH, - TEST_DBUS_ACCOUNT_SERVICE_IFACE, - "DeleteAccount", - g_variant_new_parsed ("(%s,)", account_name), - G_VARIANT_TYPE_UNIT, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, /* no cancellable */ - delete_account_cb, - async_data_new (self, account_name)); - - /* this doesn't mean we succeeded: it means we tried */ - return TRUE; - } - if (account->flags & UNCOMMITTED_CREATION) { g_dbus_connection_call (self->bus, @@ -1516,7 +1358,7 @@ test_dbus_account_plugin_commit_one (const McpAccountStorage *storage, } static void -test_dbus_account_plugin_get_identifier (const McpAccountStorage *storage, +test_dbus_account_plugin_get_identifier (McpAccountStorage *storage, const gchar *account_name, GValue *identifier) { @@ -1525,8 +1367,8 @@ test_dbus_account_plugin_get_identifier (const McpAccountStorage *storage, DEBUG ("%s", account_name); - if (!self->active || account == NULL || (account->flags & UNCOMMITTED_DELETION)) - return; + g_return_if_fail (self->active); + g_return_if_fail (account != NULL); /* Our "library-specific unique identifier" is just the object-path * as a string. */ @@ -1535,7 +1377,7 @@ test_dbus_account_plugin_get_identifier (const McpAccountStorage *storage, } static GHashTable * -test_dbus_account_plugin_get_additional_info (const McpAccountStorage *storage, +test_dbus_account_plugin_get_additional_info (McpAccountStorage *storage, const gchar *account_name) { TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); @@ -1544,8 +1386,8 @@ test_dbus_account_plugin_get_additional_info (const McpAccountStorage *storage, DEBUG ("%s", account_name); - if (!self->active || account == NULL || (account->flags & UNCOMMITTED_DELETION)) - return NULL; + g_return_val_if_fail (self->active, NULL); + g_return_val_if_fail (account != NULL, NULL); ret = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) tp_g_value_slice_free); @@ -1556,7 +1398,7 @@ test_dbus_account_plugin_get_additional_info (const McpAccountStorage *storage, } static guint -test_dbus_account_plugin_get_restrictions (const McpAccountStorage *storage, +test_dbus_account_plugin_get_restrictions (McpAccountStorage *storage, const gchar *account_name) { TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); @@ -1564,27 +1406,17 @@ test_dbus_account_plugin_get_restrictions (const McpAccountStorage *storage, DEBUG ("%s", account_name); - if (!self->active || account == NULL || (account->flags & UNCOMMITTED_DELETION)) - return 0; + g_return_val_if_fail (self->active, 0); + g_return_val_if_fail (account != NULL, 0); - /* FIXME: actually enforce this restriction */ - return TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_SERVICE; + return account->restrictions; } -static gboolean -test_dbus_account_plugin_owns (McpAccountStorage *storage, - McpAccountManager *am, - const gchar *account_name) +static McpAccountStorageFlags +test_dbus_account_plugin_get_flags (McpAccountStorage *storage, + const gchar *account) { - TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); - Account *account = lookup_account (self, account_name); - - DEBUG ("%s", account_name); - - if (!self->active || account == NULL || (account->flags & UNCOMMITTED_DELETION)) - return FALSE; - - return TRUE; + return MCP_ACCOUNT_STORAGE_FLAG_STORES_TYPES; } static void @@ -1595,18 +1427,21 @@ account_storage_iface_init (McpAccountStorageIface *iface) /* this should be higher priority than the diverted-keyfile one */ iface->priority = MCP_ACCOUNT_STORAGE_PLUGIN_PRIO_NORMAL + 100; - iface->get = test_dbus_account_plugin_get; - iface->set = test_dbus_account_plugin_set; + iface->get_flags = test_dbus_account_plugin_get_flags; + iface->get_attribute = test_dbus_account_plugin_get_attribute; + iface->get_parameter = test_dbus_account_plugin_get_parameter; + iface->list_typed_parameters = + test_dbus_account_plugin_list_typed_parameters; + iface->list_untyped_parameters = + test_dbus_account_plugin_list_untyped_parameters; iface->set_attribute = test_dbus_account_plugin_set_attribute; iface->set_parameter = test_dbus_account_plugin_set_parameter; iface->list = test_dbus_account_plugin_list; - iface->ready = test_dbus_account_plugin_ready; - iface->delete = test_dbus_account_plugin_delete; + iface->delete_async = test_dbus_account_plugin_delete_async; + iface->delete_finish = test_dbus_account_plugin_delete_finish; iface->commit = test_dbus_account_plugin_commit; - iface->commit_one = test_dbus_account_plugin_commit_one; iface->get_identifier = test_dbus_account_plugin_get_identifier; iface->get_additional_info = test_dbus_account_plugin_get_additional_info; iface->get_restrictions = test_dbus_account_plugin_get_restrictions; iface->create = test_dbus_account_plugin_create; - iface->owns = test_dbus_account_plugin_owns; } diff --git a/tests/twisted/dispatcher/already-has-channel.py b/tests/twisted/dispatcher/already-has-channel.py index 547acdf2..6b666e12 100644 --- a/tests/twisted/dispatcher/already-has-channel.py +++ b/tests/twisted/dispatcher/already-has-channel.py @@ -33,7 +33,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) text_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, @@ -68,25 +68,19 @@ def test(q, bus, mc): interface=cs.tp_name_prefix + '.ConnectionManager', handled=False) - # Don't allow the Connection to become ready until we want it to, by - # avoiding a return from GetInterfaces + # 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_interfaces=False) - + 'myself', implement_get_channels=False) q.dbus_return(e.message, conn.bus_name, conn.object_path, signature='so') - # this is the pre-Connect one - e = q.expect('dbus-method-call', method='GetInterfaces', - path=conn.object_path, handled=False) - q.dbus_raise(e.message, cs.DISCONNECTED, 'Not connected yet') + 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.CONN_STATUS_REASON_NONE) - - get_interfaces_call = q.expect('dbus-method-call', method='GetInterfaces', - path=conn.object_path, handled=False) + 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) @@ -95,7 +89,7 @@ def test(q, bus, mc): cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] - # Before returning from GetInterfaces, make a Channel spring into + # Before returning from GetAll(Requests), make a Channel spring into # existence channel_properties = dbus.Dictionary(text_fixed_properties, @@ -112,8 +106,8 @@ def test(q, bus, mc): chan = SimulatedChannel(conn, channel_properties) chan.announce() - # Now reply to GetInterfaces and say we have Requests - conn.GetInterfaces(get_interfaces_call) + # Now reply to GetAll(Requests) + conn.GetAll_Requests(get_all_requests_call) # A channel dispatch operation is created for the channel we already had diff --git a/tests/twisted/dispatcher/already-has-obsolete.py b/tests/twisted/dispatcher/already-has-obsolete.py deleted file mode 100644 index 05dcb115..00000000 --- a/tests/twisted/dispatcher/already-has-obsolete.py +++ /dev/null @@ -1,221 +0,0 @@ -# Copyright (C) 2009 Nokia Corporation -# Copyright (C) 2009 Collabora Ltd. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA - -import dbus -"""Regression test for dispatching an incoming Text channel that was already -there before the Connection became ready. -""" - -import dbus -import dbus.service - -from servicetest import EventPattern, tp_name_prefix, tp_path_prefix, \ - call_async -from mctest import exec_test, SimulatedConnection, SimulatedClient, \ - create_fakecm_account, SimulatedChannel, expect_client_setup -import constants as cs - -def test(q, bus, mc): - params = dbus.Dictionary({"account": "someguy@example.com", - "password": "secrecy"}, signature='sv') - cm_name_ref, 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 become ready until we want it to, by - # avoiding a return from GetInterfaces - conn = SimulatedConnection(q, bus, 'fakecm', 'fakeprotocol', '_', - 'myself', implement_get_interfaces=False, has_requests=False) - - q.dbus_return(e.message, conn.bus_name, conn.object_path, signature='so') - - # this is the pre-Connect one - e = q.expect('dbus-method-call', method='GetInterfaces', - path=conn.object_path, handled=False) - q.dbus_raise(e.message, cs.DISCONNECTED, 'Not connected yet') - - q.expect('dbus-method-call', method='Connect', - path=conn.object_path, handled=True) - conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CONN_STATUS_REASON_NONE) - - get_interfaces_call = q.expect('dbus-method-call', method='GetInterfaces', - path=conn.object_path, handled=False) - - # 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 GetInterfaces, 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 GetInterfaces and say we don't have Requests - conn.GetInterfaces(get_interfaces_call) - q.expect('dbus-method-call', - interface=cs.CONN, method='ListChannels', args=[], - path=conn.object_path, handled=True) - - # 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 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 len(e.args) == 3 - assert len(e.args[0]) == 1 - assert e.args[0][0][0] == chan.object_path - assert e.args[1] == cdo_path - assert e.args[2] == 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') == [] - -if __name__ == '__main__': - exec_test(test, {}) diff --git a/tests/twisted/dispatcher/approver-fails.py b/tests/twisted/dispatcher/approver-fails.py index 67ce36a3..b8705bb7 100644 --- a/tests/twisted/dispatcher/approver-fails.py +++ b/tests/twisted/dispatcher/approver-fails.py @@ -34,7 +34,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/dispatcher/bypass-approval.py b/tests/twisted/dispatcher/bypass-approval.py index 0655a9a9..eddb3155 100644 --- a/tests/twisted/dispatcher/bypass-approval.py +++ b/tests/twisted/dispatcher/bypass-approval.py @@ -181,7 +181,7 @@ def expect_and_exercise_approval(q, bus, chan, channel_properties, def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + 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, diff --git a/tests/twisted/dispatcher/bypass-observers.py b/tests/twisted/dispatcher/bypass-observers.py deleted file mode 100644 index d8b02660..00000000 --- a/tests/twisted/dispatcher/bypass-observers.py +++ /dev/null @@ -1,291 +0,0 @@ -# Copyright (C) 2009-2010 Nokia Corporation -# Copyright (C) 2009-2010 Collabora Ltd. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA - -import dbus -"""Regression test for dispatching an incoming Text channel with bypassed -observers. -""" - -import dbus -import dbus.service - -from servicetest import EventPattern, tp_name_prefix, tp_path_prefix, \ - call_async, sync_dbus, assertEquals, assertLength, assertContains -from mctest import exec_test, SimulatedConnection, SimulatedClient, \ - create_fakecm_account, enable_fakecm_account, SimulatedChannel, \ - expect_client_setup -import constants as cs - -text_fixed_properties = dbus.Dictionary({ - cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, - }, signature='sv') -contact_text_fixed_properties = dbus.Dictionary({ - cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, - cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, - }, signature='sv') -secret_fixed_properties = dbus.Dictionary({ - cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, - cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, - 'com.example.Secrecy.Secret': True, - }, signature='sv') - -def announce_common(q, bus, empathy, kopete, account, conn, cd_props, - secret=False): - if secret: - jid = 'friar.lawrence' - else: - jid = 'juliet' - - channel_properties = dbus.Dictionary(contact_text_fixed_properties, - signature='sv') - channel_properties[cs.CHANNEL + '.TargetID'] = jid - channel_properties[cs.CHANNEL + '.TargetHandle'] = \ - conn.ensure_handle(cs.HT_CONTACT, jid) - channel_properties[cs.CHANNEL + '.InitiatorID'] = jid - channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ - conn.ensure_handle(cs.HT_CONTACT, jid) - channel_properties[cs.CHANNEL + '.Requested'] = False - channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s') - - if secret: - channel_properties['com.example.Secrecy.Secret'] = True - - 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] - - assertEquals(cdo_properties[cs.CDO + '.Account'], account.object_path) - assertEquals(cdo_properties[cs.CDO + '.Connection'], conn.object_path) - assertContains(cs.CDO + '.Interfaces', cdo_properties) - - handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] - - if secret: - # The handler with BypassApproval is first - assertEquals(cs.tp_name_prefix + '.Client.Kopete.Bypasser', - handlers[0]) - else: - handlers.sort() - assertEquals([cs.tp_name_prefix + '.Client.Empathy', - cs.tp_name_prefix + '.Client.Kopete'], handlers) - - assertContains(cs.CD_IFACE_OP_LIST, cd_props.Get(cs.CD, 'Interfaces')) - - assertEquals([(cdo_path, cdo_properties)], - cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations')) - - cdo = bus.get_object(cs.CD, cdo_path) - cdo_iface = dbus.Interface(cdo, cs.CDO) - - # Both Observers are told about the new channel - - if secret: - observe_events = [] - else: - 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), - ) - assertEquals(account.object_path, e.args[0]) - assertEquals(conn.object_path, e.args[1]) - assertEquals(cdo_path, e.args[3]) - assertEquals([], e.args[4]) # no requests satisfied - channels = e.args[2] - assertLength(1, channels) - assertEquals(chan.object_path, channels[0][0]) - assertEquals(channel_properties, channels[0][1]) - - assertEquals(k.args, e.args) - observe_events = [e, k] - - return cdo_iface, chan, channel_properties, observe_events - -def expect_and_exercise_approval(q, bus, chan, channel_properties, - empathy, kopete, cdo_iface, cd_props): - # 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), - ) - - assertEquals([(chan.object_path, channel_properties)], e.args[0]) - assertEquals(k.args, e.args) - - # Both Approvers indicate that they are ready to proceed - 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 Kopete first - call_async(q, cdo_iface, 'HandleWith', - cs.tp_name_prefix + '.Client.Kopete') - - # Kopete is asked to handle the channels - e = q.expect('dbus-method-call', - path=kopete.object_path, - interface=cs.HANDLER, method='HandleChannels', - handled=False) - - # Kopete 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 - assertEquals([], cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations')) - - -def test(q, bus, mc): - params = dbus.Dictionary({"account": "someguy@example.com", - "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) - conn = enable_fakecm_account(q, bus, mc, account, params) - - # Two clients want to observe, approve and handle channels. Additionally, - # Kopete recognises a "Secret" flag on certain incoming channels, and - # wants to bypass approval and observers for them. Also, Empathy is a - # respawnable observer, which wants to get notified of existing channels - # if it gets restarted. - empathy = SimulatedClient(q, bus, 'Empathy', - observe=[text_fixed_properties], approve=[text_fixed_properties], - handle=[text_fixed_properties], bypass_approval=False, - wants_recovery=True) - 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.Bypasser', - observe=[], approve=[], - handle=[secret_fixed_properties], - bypass_approval=True, bypass_observers=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) - assertEquals([], cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations')) - - # First, a non-secret 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) - - nonsecret_chan = chan - - # Now a channel that bypasses approval and observers comes in. - # During this process, we should never be asked to approve or - # observe 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) - - # Empathy, the observer, 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] - - 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] - - # Empathy is told to observe only the non-secret channel - e = q.expect('dbus-method-call', - path=empathy.object_path, - interface=cs.OBSERVER, method='ObserveChannels', - handled=False) - - channels = e.args[2] - assertLength(1, channels) - assertEquals(nonsecret_chan.object_path, channels[0][0]) - -if __name__ == '__main__': - exec_test(test, {}) - diff --git a/tests/twisted/dispatcher/cancel.py b/tests/twisted/dispatcher/cancel.py index 5b8d90af..fe23f005 100644 --- a/tests/twisted/dispatcher/cancel.py +++ b/tests/twisted/dispatcher/cancel.py @@ -34,7 +34,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/dispatcher/capture-bundle.py b/tests/twisted/dispatcher/capture-bundle.py index de773844..44e18e87 100644 --- a/tests/twisted/dispatcher/capture-bundle.py +++ b/tests/twisted/dispatcher/capture-bundle.py @@ -34,7 +34,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ @@ -43,7 +43,7 @@ def test(q, bus, mc): }, signature='sv') voip_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, - cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_STREAMED_MEDIA, + cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_CALL, }, signature='sv') # Two clients want to observe, approve and handle text and VoIP channels. diff --git a/tests/twisted/dispatcher/cdo-claim.py b/tests/twisted/dispatcher/cdo-claim.py index ec98b93f..89474f9b 100644 --- a/tests/twisted/dispatcher/cdo-claim.py +++ b/tests/twisted/dispatcher/cdo-claim.py @@ -30,7 +30,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/dispatcher/connect-for-request.py b/tests/twisted/dispatcher/connect-for-request.py index 1be141fe..034cd054 100644 --- a/tests/twisted/dispatcher/connect-for-request.py +++ b/tests/twisted/dispatcher/connect-for-request.py @@ -29,7 +29,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "smcv@example.com", "password": "secrecy"}, signature='sv') - (cm_name_ref, account) = create_fakecm_account(q, bus, mc, params) + (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) @@ -38,11 +38,11 @@ def test(q, bus, mc): # automatically call_async(q, account_props, 'Set', cs.ACCOUNT, 'RequestedPresence', - (dbus.UInt32(cs.PRESENCE_TYPE_OFFLINE), 'offline', '')) + (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_TYPE_BUSY), 'busy', + (dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Testing automatic presence')) q.expect('dbus-return', method='Set') q.expect('dbus-signal', signal='AccountPropertyChanged', @@ -102,14 +102,14 @@ def test(q, bus, mc): handled=False) conn = SimulatedConnection(q, bus, 'fakecm', 'fakeprotocol', '_', - 'myself', has_requests=True, has_presence=True) + '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.CONN_STATUS_REASON_NONE) - conn.presence = dbus.Struct((cs.PRESENCE_TYPE_AVAILABLE, 'available', ''), + 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( @@ -123,7 +123,7 @@ def test(q, bus, mc): q.dbus_emit(conn.object_path, cs.CONN_IFACE_SIMPLE_PRESENCE, 'PresencesChanged', - {conn.self_handle: (dbus.UInt32(cs.PRESENCE_TYPE_BUSY), 'busy', + {conn.self_handle: (dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Testing automatic presence')}, signature='a{u(uss)}') diff --git a/tests/twisted/dispatcher/create-at-startup.py b/tests/twisted/dispatcher/create-at-startup.py index e0d73722..fb515723 100644 --- a/tests/twisted/dispatcher/create-at-startup.py +++ b/tests/twisted/dispatcher/create-at-startup.py @@ -28,7 +28,7 @@ import dbus.service from servicetest import EventPattern, tp_name_prefix, tp_path_prefix, \ call_async from mctest import exec_test, SimulatedConnection, SimulatedClient, \ - create_fakecm_account, enable_fakecm_account, SimulatedChannel, \ + SimulatedConnectionManager, SimulatedChannel, \ expect_client_setup, MC import constants as cs @@ -76,8 +76,7 @@ def test(q, bus, unused, **kwargs): observe=[text_fixed_properties], approve=[text_fixed_properties], handle=[text_fixed_properties], bypass_approval=False, implement_get_interfaces=False) - cm_name_ref = dbus.service.BusName( - cs.tp_name_prefix + '.ConnectionManager.fakecm', bus=bus) + simulated_cm = SimulatedConnectionManager(q, bus) # service-activate MC; it will try to introspect the running client. mc = MC(q, bus, wait_for_names=False) @@ -133,7 +132,7 @@ def test(q, bus, unused, **kwargs): q.expect('dbus-method-call', method='Connect', path=conn.object_path, handled=True) - conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CONN_STATUS_REASON_NONE) + conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) # A channel appears spontaneously diff --git a/tests/twisted/dispatcher/create-delayed-by-mini-plugin.py b/tests/twisted/dispatcher/create-delayed-by-mini-plugin.py index 8c2925c1..fcf021b9 100644 --- a/tests/twisted/dispatcher/create-delayed-by-mini-plugin.py +++ b/tests/twisted/dispatcher/create-delayed-by-mini-plugin.py @@ -41,7 +41,7 @@ def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + 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=[ @@ -55,13 +55,6 @@ def test(q, bus, mc): q.dbus_return(e.message, points, signature='v') - # MC looks up the handles for these numbers - patterns = [EventPattern('dbus-method-call', path=conn.object_path, - interface=cs.CONN, method='RequestHandles', - args=[cs.HT_CONTACT, [num]], - handled=True) for num in e_numbers] - q.expect_many(*patterns) - # the service points change e_numbers = ['911', '112', '999'] points = dbus.Array([((cs.SERVICE_POINT_TYPE_EMERGENCY, 'urn:service:sos'), @@ -69,13 +62,6 @@ def test(q, bus, mc): q.dbus_emit(conn.object_path, cs.CONN_IFACE_SERVICE_POINT, 'ServicePointsChanged', points, signature='a((us)as)') - # MC looks up the new handles - patterns = [EventPattern('dbus-method-call', path=conn.object_path, - interface=cs.CONN, method='RequestHandles', - args=[cs.HT_CONTACT, [num]], - handled=True) for num in e_numbers] - q.expect_many(*patterns) - # 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'] @@ -89,12 +75,6 @@ def test(q, bus, mc): e_numbers = e_numbers1 + e_numbers2 - patterns = [EventPattern('dbus-method-call', path=conn.object_path, - interface=cs.CONN, method='RequestHandles', - args=[cs.HT_CONTACT, [num]], - handled=True) for num in e_numbers] - q.expect_many(*patterns) - fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, cs.CHANNEL + '.ChannelType': DELAYED_CTYPE, diff --git a/tests/twisted/dispatcher/create-handler-fails.py b/tests/twisted/dispatcher/create-handler-fails.py index ccdae2f9..13523636 100644 --- a/tests/twisted/dispatcher/create-handler-fails.py +++ b/tests/twisted/dispatcher/create-handler-fails.py @@ -34,7 +34,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/dispatcher/create-hints.py b/tests/twisted/dispatcher/create-hints.py index daf8cdcd..3b8cf94b 100644 --- a/tests/twisted/dispatcher/create-hints.py +++ b/tests/twisted/dispatcher/create-hints.py @@ -33,7 +33,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/dispatcher/create-no-preferred-handler.py b/tests/twisted/dispatcher/create-no-preferred-handler.py index 3e078415..11ac44b5 100644 --- a/tests/twisted/dispatcher/create-no-preferred-handler.py +++ b/tests/twisted/dispatcher/create-no-preferred-handler.py @@ -34,7 +34,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/dispatcher/create-rejected-by-mini-plugin.py b/tests/twisted/dispatcher/create-rejected-by-mini-plugin.py index 2f517589..ecd5f6e6 100644 --- a/tests/twisted/dispatcher/create-rejected-by-mini-plugin.py +++ b/tests/twisted/dispatcher/create-rejected-by-mini-plugin.py @@ -47,7 +47,7 @@ def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/dispatcher/create-text.py b/tests/twisted/dispatcher/create-text.py index 5a0efe1a..a0897ba4 100644 --- a/tests/twisted/dispatcher/create-text.py +++ b/tests/twisted/dispatcher/create-text.py @@ -34,7 +34,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ @@ -71,7 +71,7 @@ def test(q, bus, mc): 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_STREAMED_MEDIA) + cs.CHANNEL_TYPE_CALL) def test_channel_creation(q, bus, account, client, conn, ensure=False, prefer=None, channel_type=cs.CHANNEL_TYPE_TEXT): diff --git a/tests/twisted/dispatcher/created-behind-our-back.py b/tests/twisted/dispatcher/created-behind-our-back.py index 55d1b4b0..d87e69ac 100644 --- a/tests/twisted/dispatcher/created-behind-our-back.py +++ b/tests/twisted/dispatcher/created-behind-our-back.py @@ -39,7 +39,7 @@ def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/dispatcher/delay-approvers.py b/tests/twisted/dispatcher/delay-approvers.py index a627159d..2a7295f8 100644 --- a/tests/twisted/dispatcher/delay-approvers.py +++ b/tests/twisted/dispatcher/delay-approvers.py @@ -29,7 +29,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/dispatcher/delay-then-call-handle-with.py b/tests/twisted/dispatcher/delay-then-call-handle-with.py index 2f79b10e..28fdfb3e 100644 --- a/tests/twisted/dispatcher/delay-then-call-handle-with.py +++ b/tests/twisted/dispatcher/delay-then-call-handle-with.py @@ -29,7 +29,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/dispatcher/delay-then-dont-call-approvers.py b/tests/twisted/dispatcher/delay-then-dont-call-approvers.py index 90040228..25ebd908 100644 --- a/tests/twisted/dispatcher/delay-then-dont-call-approvers.py +++ b/tests/twisted/dispatcher/delay-then-dont-call-approvers.py @@ -29,7 +29,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/dispatcher/dispatch-activatable.py b/tests/twisted/dispatcher/dispatch-activatable.py index cb7b9cb1..6da442b2 100644 --- a/tests/twisted/dispatcher/dispatch-activatable.py +++ b/tests/twisted/dispatcher/dispatch-activatable.py @@ -33,7 +33,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) abiword_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/dispatcher/dispatch-before-connected.py b/tests/twisted/dispatcher/dispatch-before-connected.py index 9925e0fe..1037ef4c 100644 --- a/tests/twisted/dispatcher/dispatch-before-connected.py +++ b/tests/twisted/dispatcher/dispatch-before-connected.py @@ -29,17 +29,10 @@ from mctest import exec_test, SimulatedConnection, SimulatedClient, \ expect_client_setup import constants as cs -CHANNEL_TYPE_SERVER_VERIFICATION = \ - 'org.freedesktop.Telepathy.Channel.Type.ServerVerification.DRAFT' -CHANNEL_IFACE_VERIFICATION = \ - 'org.freedesktop.Telepathy.Channel.Interface.Verification.DRAFT ' -CHANNEL_IFACE_IDENT_EXCHANGE = \ - 'org.freedesktop.Telepathy.Channel.Interface.IdentityExchange.DRAFT' - def test(q, bus, mc): params = dbus.Dictionary({"account": "someone@example.com", "password": "secrecy"}, signature='sv') - (cm_name_ref, account) = create_fakecm_account(q, bus, mc, params) + (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) @@ -49,7 +42,7 @@ def test(q, bus, mc): verification_filter = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': 0, - cs.CHANNEL + '.ChannelType': CHANNEL_TYPE_SERVER_VERIFICATION, + cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_SERVER_TLS_CONNECTION, }, signature='sv') verifier_bus = dbus.bus.BusConnection() @@ -61,7 +54,7 @@ def test(q, bus, mc): expect_client_setup(q, [verifier]) account_props.Set(cs.ACCOUNT, 'RequestedPresence', - (dbus.UInt32(cs.PRESENCE_TYPE_AVAILABLE), 'available', '')) + (dbus.UInt32(cs.PRESENCE_AVAILABLE), 'available', '')) account_props.Set(cs.ACCOUNT, 'Enabled', True) @@ -73,7 +66,7 @@ def test(q, bus, mc): handled=False) conn = SimulatedConnection(q, bus, 'fakecm', 'fakeprotocol', '_', - 'myself', has_requests=True, has_presence=True) + 'myself', has_presence=True) q.dbus_return(e.message, conn.bus_name, conn.object_path, signature='so') @@ -87,10 +80,7 @@ def test(q, bus, mc): channel_properties[cs.CHANNEL + '.InitiatorID'] = '' channel_properties[cs.CHANNEL + '.InitiatorHandle'] = 0 channel_properties[cs.CHANNEL + '.Requested'] = False - channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array([ - CHANNEL_IFACE_IDENT_EXCHANGE, - CHANNEL_IFACE_VERIFICATION, - cs.CHANNEL], signature='s') + channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array([], signature='s') chan = SimulatedChannel(conn, channel_properties) chan.announce() diff --git a/tests/twisted/dispatcher/dispatch-delayed-by-mini-plugin.py b/tests/twisted/dispatcher/dispatch-delayed-by-mini-plugin.py index eeab38cb..d2c0855d 100644 --- a/tests/twisted/dispatcher/dispatch-delayed-by-mini-plugin.py +++ b/tests/twisted/dispatcher/dispatch-delayed-by-mini-plugin.py @@ -99,7 +99,7 @@ def signal_channel_expect_query(q, bus, account, conn, empathy, kopete): def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + 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) @@ -145,10 +145,8 @@ def test(q, bus, mc): args=[cdo_path]), EventPattern('dbus-method-call', path=chan.object_path, - interface=cs.CHANNEL_IFACE_GROUP, - # this error message is from the plugin - method='RemoveMembersWithReason', args=[[conn.self_handle], - "Computer says no", cs.GROUP_REASON_PERMISSION_DENIED], + interface=cs.CHANNEL_IFACE_DESTROYABLE, + method='Destroy', handled=False), ) q.dbus_return(e.message, signature='') diff --git a/tests/twisted/dispatcher/dispatch-obsolete.py b/tests/twisted/dispatcher/dispatch-obsolete.py index 4431631a..16d76517 100644 --- a/tests/twisted/dispatcher/dispatch-obsolete.py +++ b/tests/twisted/dispatcher/dispatch-obsolete.py @@ -34,158 +34,18 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params, has_requests=False) - 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]) - - # 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) - - # 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 - # the announced channel properties are some subset of what it actually has - for key in channels[0][1]: - assert channel_properties[key] == channels[0][1][key], key - assert cs.CHANNEL + '.TargetHandleType' in channels[0][1] - assert cs.CHANNEL + '.ChannelType' in channels[0][1] - assert cs.CHANNEL + '.TargetHandle' in channels[0][1] - - 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[1:] == [cdo_path, cdo_properties] - channels = e.args[0] - assert len(channels) == 1, channels - assert channels[0][0] == chan.object_path, channels - # the announced channel properties are some subset of what it actually has - for key in channels[0][1]: - assert channel_properties[key] == channels[0][1][key], key - assert cs.CHANNEL + '.TargetHandleType' in channels[0][1] - assert cs.CHANNEL + '.ChannelType' in channels[0][1] - assert cs.CHANNEL + '.TargetHandle' in channels[0][1] - 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'), + 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), ) - # Now there are no more active channel dispatch operations - assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] - if __name__ == '__main__': exec_test(test, {}) diff --git a/tests/twisted/dispatcher/dispatch-rejected-by-mini-plugin.py b/tests/twisted/dispatcher/dispatch-rejected-by-mini-plugin.py index eeb6e9ec..37a87105 100644 --- a/tests/twisted/dispatcher/dispatch-rejected-by-mini-plugin.py +++ b/tests/twisted/dispatcher/dispatch-rejected-by-mini-plugin.py @@ -33,7 +33,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ @@ -205,9 +205,8 @@ def test(q, bus, mc): args=[cdo_path]), EventPattern('dbus-method-call', path=chan.object_path, - interface=cs.CHANNEL_IFACE_GROUP, - method='RemoveMembersWithReason', args=[[conn.self_handle], - "Can't touch this", cs.GROUP_REASON_PERMISSION_DENIED], + interface=cs.CHANNEL_IFACE_DESTROYABLE, + method='Destroy', handled=False), ) q.dbus_return(e.message, signature='') diff --git a/tests/twisted/dispatcher/dispatch-text.py b/tests/twisted/dispatcher/dispatch-text.py index b1f6ce60..689639ca 100644 --- a/tests/twisted/dispatcher/dispatch-text.py +++ b/tests/twisted/dispatcher/dispatch-text.py @@ -34,7 +34,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/dispatcher/ensure-and-redispatch.py b/tests/twisted/dispatcher/ensure-and-redispatch.py index 4d526c2e..f5a77a56 100644 --- a/tests/twisted/dispatcher/ensure-and-redispatch.py +++ b/tests/twisted/dispatcher/ensure-and-redispatch.py @@ -33,7 +33,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/dispatcher/ensure-is-approval.py b/tests/twisted/dispatcher/ensure-is-approval.py index a2fb0850..63c6f8a7 100644 --- a/tests/twisted/dispatcher/ensure-is-approval.py +++ b/tests/twisted/dispatcher/ensure-is-approval.py @@ -35,7 +35,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + 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), diff --git a/tests/twisted/dispatcher/ensure-rapidly.py b/tests/twisted/dispatcher/ensure-rapidly.py index a338799b..f90a1f68 100644 --- a/tests/twisted/dispatcher/ensure-rapidly.py +++ b/tests/twisted/dispatcher/ensure-rapidly.py @@ -33,7 +33,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/dispatcher/exploding-bundles.py b/tests/twisted/dispatcher/exploding-bundles.py index 27d3be3a..27d1727e 100644 --- a/tests/twisted/dispatcher/exploding-bundles.py +++ b/tests/twisted/dispatcher/exploding-bundles.py @@ -33,7 +33,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ @@ -43,7 +43,7 @@ def test(q, bus, mc): media_fixed_properties = dbus.Dictionary({ cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, - cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_STREAMED_MEDIA, + cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_CALL, }, signature='sv') misc_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/dispatcher/fdo-21034.py b/tests/twisted/dispatcher/fdo-21034.py index 5a1ca3ca..e0ed001a 100644 --- a/tests/twisted/dispatcher/fdo-21034.py +++ b/tests/twisted/dispatcher/fdo-21034.py @@ -33,7 +33,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/dispatcher/handle-channels-fails.py b/tests/twisted/dispatcher/handle-channels-fails.py index 04b51ef7..4b3ae22e 100644 --- a/tests/twisted/dispatcher/handle-channels-fails.py +++ b/tests/twisted/dispatcher/handle-channels-fails.py @@ -34,7 +34,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/dispatcher/lose-text.py b/tests/twisted/dispatcher/lose-text.py index d652658c..42083c2c 100644 --- a/tests/twisted/dispatcher/lose-text.py +++ b/tests/twisted/dispatcher/lose-text.py @@ -34,7 +34,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/dispatcher/recover-from-disconnect.py b/tests/twisted/dispatcher/recover-from-disconnect.py index 9ae81e51..9e0d3c42 100644 --- a/tests/twisted/dispatcher/recover-from-disconnect.py +++ b/tests/twisted/dispatcher/recover-from-disconnect.py @@ -48,13 +48,10 @@ def test(q, bus, mc): # wait for MC to download the properties expect_client_setup(q, [empathy, kopete]) - cm_name_ref = dbus.service.BusName( - tp_name_prefix + '.ConnectionManager.fakecm', bus=bus) - # Create an account params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - (cm_name_ref, account) = create_fakecm_account(q, bus, mc, params) + (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) @@ -68,7 +65,7 @@ def test(q, bus, mc): dbus_interface=cs.PROPERTIES_IFACE) # Set online presence - presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_TYPE_BUSY), 'busy', + presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Fixing MC bugs'), signature='uss') call_async(q, account, 'Set', cs.ACCOUNT, 'RequestedPresence', presence, @@ -93,19 +90,19 @@ def test(q, bus, mc): path=conn.object_path, handled=True), ) - # MC calls GetStatus (maybe) and then Connect - + # MC prepares the connection, does any pre-Connect setup, then + # calls Connect q.expect('dbus-method-call', method='Connect', path=conn.object_path, handled=True) # Connect succeeds - conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CONN_STATUS_REASON_NONE) + conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) test_dispatching(q, bus, conn, account, empathy, kopete) # Connection falls over for a miscellaneous reason conn.StatusChanged(cs.CONN_STATUS_DISCONNECTED, - cs.CONN_STATUS_REASON_NETWORK_ERROR) + cs.CSR_NETWORK_ERROR) # MC reconnects @@ -128,13 +125,13 @@ def test(q, bus, mc): path=conn.object_path, handled=True), ) - # MC calls GetStatus (maybe) and then Connect - + # MC prepares the connection, does any pre-Connect setup, then + # calls Connect q.expect('dbus-method-call', method='Connect', path=conn.object_path, handled=True) # Connect succeeds - conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CONN_STATUS_REASON_NONE) + conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) test_dispatching(q, bus, conn, account, empathy, kopete) diff --git a/tests/twisted/dispatcher/redispatch-channels.py b/tests/twisted/dispatcher/redispatch-channels.py index 6178a379..41800b1c 100644 --- a/tests/twisted/dispatcher/redispatch-channels.py +++ b/tests/twisted/dispatcher/redispatch-channels.py @@ -185,7 +185,7 @@ def test_delegate_channel(q, bus, mc, account, conn, chan, empathy, empathy_bus, def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/dispatcher/request-disabled-account.py b/tests/twisted/dispatcher/request-disabled-account.py index 863f0540..c3f1640b 100644 --- a/tests/twisted/dispatcher/request-disabled-account.py +++ b/tests/twisted/dispatcher/request-disabled-account.py @@ -29,17 +29,17 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "smcv@example.com", "password": "secrecy"}, signature='sv') - (cm_name_ref, account) = create_fakecm_account(q, bus, mc, params) + (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_TYPE_OFFLINE), 'offline', '')) + (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_TYPE_BUSY), 'busy', + (dbus.UInt32(cs.PRESENCE_BUSY), 'busy', 'Testing automatic presence')) q.expect('dbus-return', method='Set') q.expect('dbus-signal', signal='AccountPropertyChanged', diff --git a/tests/twisted/dispatcher/respawn-activatable-observers.py b/tests/twisted/dispatcher/respawn-activatable-observers.py index 8f83ffbb..14727b40 100644 --- a/tests/twisted/dispatcher/respawn-activatable-observers.py +++ b/tests/twisted/dispatcher/respawn-activatable-observers.py @@ -34,7 +34,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/dispatcher/respawn-observers.py b/tests/twisted/dispatcher/respawn-observers.py index 81061ae6..bf69a794 100644 --- a/tests/twisted/dispatcher/respawn-observers.py +++ b/tests/twisted/dispatcher/respawn-observers.py @@ -34,7 +34,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/dispatcher/some-delay-approvers.py b/tests/twisted/dispatcher/some-delay-approvers.py index e06b13a6..16e0b7b0 100644 --- a/tests/twisted/dispatcher/some-delay-approvers.py +++ b/tests/twisted/dispatcher/some-delay-approvers.py @@ -29,7 +29,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/dispatcher/undispatchable.py b/tests/twisted/dispatcher/undispatchable.py index de63fbca..8a18ec03 100644 --- a/tests/twisted/dispatcher/undispatchable.py +++ b/tests/twisted/dispatcher/undispatchable.py @@ -35,7 +35,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) text_fixed_properties = dbus.Dictionary({ diff --git a/tests/twisted/dispatcher/vanishing-client.py b/tests/twisted/dispatcher/vanishing-client.py index 92a4079b..143ea4cb 100644 --- a/tests/twisted/dispatcher/vanishing-client.py +++ b/tests/twisted/dispatcher/vanishing-client.py @@ -33,7 +33,7 @@ import constants as cs def test(q, bus, mc): params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) + simulated_cm, account = create_fakecm_account(q, bus, mc, params) conn = enable_fakecm_account(q, bus, mc, account, params) bus_name = '.'.join([tp_name_prefix, 'Client.CrashMe']) diff --git a/tests/twisted/fakeaccountsservice.py b/tests/twisted/fakeaccountsservice.py index 3c10a156..d8c87a0b 100644 --- a/tests/twisted/fakeaccountsservice.py +++ b/tests/twisted/fakeaccountsservice.py @@ -25,12 +25,27 @@ from servicetest import (Event, EventPattern) import constants as cs -# indices into the tuple of dicts representing an account -ATTRS = 0 -ATTR_FLAGS = 1 -PARAMS = 2 -UNTYPED_PARAMS = 3 -PARAM_FLAGS = 4 +class FakeAccount(object): + + def __init__(self): + self.attrs = dbus.Dictionary({}, signature='sv') + self.attr_flags = dbus.Dictionary({}, signature='su') + self.params = dbus.Dictionary({}, signature='sv') + self.untyped_params = dbus.Dictionary({}, signature='ss') + self.param_flags = dbus.Dictionary({}, signature='su') + self.restrictions = 0 + + SIGNATURE = 'a{sv}a{su}a{sv}a{ss}a{su}u' + + def to_dbus(self): + return ( + self.attrs, + self.attr_flags, + self.params, + self.untyped_params, + self.param_flags, + dbus.UInt32(self.restrictions), + ) class FakeAccountsService(object): def __init__(self, q, bus): @@ -68,25 +83,28 @@ class FakeAccountsService(object): method='UpdateParameters') def create_account(self, account, attrs={}, attr_flags={}, params={}, - untyped_params={}, param_flags={}): + untyped_params={}, param_flags={}, restrictions=0): + if account in self.accounts: raise KeyError('Account %s already exists' % account) - self.accounts[account] = ({}, {}, {}, {}, {}) - self.accounts[account][ATTRS].update(attrs) + + self.accounts[account] = FakeAccount() + self.accounts[account].restrictions = restrictions + self.accounts[account].attrs.update(attrs) for attr in attrs: - self.accounts[account][ATTR_FLAGS][attr] = dbus.UInt32(0) - self.accounts[account][ATTR_FLAGS].update(attr_flags) - self.accounts[account][PARAMS].update(params) + self.accounts[account].attr_flags[attr] = dbus.UInt32(0) + self.accounts[account].attr_flags.update(attr_flags) + self.accounts[account].params.update(params) for param in params: - self.accounts[account][PARAM_FLAGS][param] = dbus.UInt32(0) - self.accounts[account][UNTYPED_PARAMS].update(untyped_params) + self.accounts[account].param_flags[param] = dbus.UInt32(0) + self.accounts[account].untyped_params.update(untyped_params) for param in untyped_params: - self.accounts[account][PARAM_FLAGS][param] = dbus.UInt32(0) - self.accounts[account][PARAM_FLAGS].update(param_flags) + self.accounts[account].param_flags[param] = dbus.UInt32(0) + self.accounts[account].param_flags.update(param_flags) self.q.dbus_emit(self.object_path, cs.TEST_DBUS_ACCOUNT_SERVICE_IFACE, 'AccountCreated', - account, *self.accounts[account], - signature='sa{sv}a{su}a{sv}a{ss}a{su}') + account, *(self.accounts[account].to_dbus()), + signature='s' + FakeAccount.SIGNATURE) def CreateAccount(self, e): try: @@ -111,28 +129,31 @@ class FakeAccountsService(object): self.q.dbus_return(e.message, signature='') def GetAccounts(self, e): - self.q.dbus_return(e.message, self.accounts, - signature='a{s(a{sv}a{su}a{sv}a{ss}a{su})}') + accounts = {} + for a in self.accounts: + accounts[a] = self.accounts[a].to_dbus() + self.q.dbus_return(e.message, accounts, + signature='a{s(' + FakeAccount.SIGNATURE + ')}') def update_attributes(self, account, changed={}, flags={}, deleted=[]): if account not in self.accounts: self.create_account(account) for (attribute, value) in changed.items(): - self.accounts[account][ATTRS][attribute] = value - self.accounts[account][ATTR_FLAGS][attribute] = flags.get( + self.accounts[account].attrs[attribute] = value + self.accounts[account].attr_flags[attribute] = flags.get( attribute, dbus.UInt32(0)) for attribute in deleted: - if attribute in self.accounts[account][ATTRS]: - del self.accounts[account][ATTRS][attribute] - if attribute in self.accounts[account][ATTR_FLAGS]: - del self.accounts[account][ATTR_FLAGS][attribute] + if attribute in self.accounts[account].attrs: + del self.accounts[account].attrs[attribute] + if attribute in self.accounts[account].attr_flags: + del self.accounts[account].attr_flags[attribute] self.q.dbus_emit(self.object_path, cs.TEST_DBUS_ACCOUNT_SERVICE_IFACE, 'AttributesChanged', account, changed, - dict([(a, self.accounts[account][ATTR_FLAGS][a]) + dict([(a, self.accounts[account].attr_flags[a]) for a in changed]), deleted, signature='sa{sv}a{su}as') @@ -150,31 +171,31 @@ class FakeAccountsService(object): self.create_account(account) for (param, value) in changed.items(): - self.accounts[account][PARAMS][param] = value - if param in self.accounts[account][UNTYPED_PARAMS]: - del self.accounts[account][UNTYPED_PARAMS][param] - self.accounts[account][PARAM_FLAGS][param] = flags.get( + self.accounts[account].params[param] = value + if param in self.accounts[account].untyped_params: + del self.accounts[account].untyped_params[param] + self.accounts[account].param_flags[param] = flags.get( param, dbus.UInt32(0)) for (param, value) in untyped.items(): - self.accounts[account][UNTYPED_PARAMS][param] = value - if param in self.accounts[account][PARAMS]: - del self.accounts[account][PARAMS][param] - self.accounts[account][PARAM_FLAGS][param] = flags.get( + self.accounts[account].untyped_params[param] = value + if param in self.accounts[account].params: + del self.accounts[account].params[param] + self.accounts[account].param_flags[param] = flags.get( param, dbus.UInt32(0)) for param in deleted: - if param in self.accounts[account][PARAMS]: - del self.accounts[account][PARAMS][param] - if param in self.accounts[account][UNTYPED_PARAMS]: - del self.accounts[account][UNTYPED_PARAMS][param] - if param in self.accounts[account][PARAM_FLAGS]: - del self.accounts[account][PARAM_FLAGS][param] + if param in self.accounts[account].params: + del self.accounts[account].params[param] + if param in self.accounts[account].untyped_params: + del self.accounts[account].untyped_params[param] + if param in self.accounts[account].param_flags: + del self.accounts[account].param_flags[param] self.q.dbus_emit(self.object_path, cs.TEST_DBUS_ACCOUNT_SERVICE_IFACE, 'ParametersChanged', account, changed, untyped, - dict([(p, self.accounts[account][PARAM_FLAGS][p]) + dict([(p, self.accounts[account].param_flags[p]) for p in (set(changed.keys()) | set(untyped.keys()))]), deleted, signature='sa{sv}a{ss}a{su}as') diff --git a/tests/twisted/fakeclient.py b/tests/twisted/fakeclient.py deleted file mode 100644 index d3c43813..00000000 --- a/tests/twisted/fakeclient.py +++ /dev/null @@ -1,99 +0,0 @@ -# Copyright (C) 2009 Nokia Corporation -# Copyright (C) 2009 Collabora Ltd. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA - -import dbus -import dbus.service -from servicetest import Event -from servicetest import EventPattern, tp_name_prefix, tp_path_prefix - -client_iface = "org.freedesktop.Telepathy.Client" -client_observer_iface = "org.freedesktop.Telepathy.Client.Observer" -client_approver_iface = "org.freedesktop.Telepathy.Client.Approver" -client_handler_iface = "org.freedesktop.Telepathy.Client.Handler" - -properties_iface = "org.freedesktop.DBus.Properties" - -empty_caps = dbus.Array([], signature='a{sv}') - -class FakeClient(dbus.service.Object): - def __init__(self, object_path, q, bus, bus_name, nameref, - caps = empty_caps): - self.object_path = object_path - self.q = q - self.bus = bus - self.bus_name = bus_name - # keep a reference on nameref, otherwise, the name will be lost! - self.nameref = nameref - self.caps = caps - dbus.service.Object.__init__(self, bus, object_path) - - @dbus.service.method(dbus_interface=properties_iface, - in_signature='ss', out_signature='v') - def Get(self, interface_name, property_name): - self.q.append(Event('dbus-method-call', name="Get", - obj=self, interface_name=interface_name, - property_name=property_name)) - if interface_name == client_iface and property_name == "Interfaces": - return dbus.Array([ - client_observer_iface, - client_approver_iface, - client_handler_iface - ], signature='s') - if interface_name == client_observer_iface and \ - property_name == "ObserverChannelFilter": - return empty_caps - if interface_name == client_approver_iface and \ - property_name == "ApproverChannelFilter": - return empty_caps - if interface_name == client_handler_iface and \ - property_name == "HandlerChannelFilter": - return self.caps - print "Error: interface_name=%s property_name=%s" % \ - (interface_name, property_name) - return None - - @dbus.service.method(dbus_interface=properties_iface, - in_signature='s', out_signature='a{sv}') - def GetAll(self, interface_name): - self.q.append(Event('dbus-method-call', name="GetAll", - obj=self, interface_name=interface_name)) - if interface_name == client_iface: - return dbus.Dictionary({ - 'Interfaces': dbus.Array([ - client_observer_iface, - client_approver_iface, - client_handler_iface - ]) - }, signature='sv') - return None - - @dbus.service.method(dbus_interface=client_handler_iface, - in_signature='ooa(oa{sv})aot', out_signature='') - def HandleChannels(self, account, connection, channels, - requests_satisfied, user_action_time): - self.q.append(Event('dbus-method-call', name="HandleChannels", - obj=self, account=account, connection=connection, - channels=channels, requests_satisfied=requests_satisfied, - user_action_time=user_action_time)) - -def start_fake_client(q, bus, bus_name, object_path, caps): - nameref = dbus.service.BusName(bus_name, bus=bus) - client = FakeClient(object_path, q, bus, bus_name, nameref, caps) - return client - - diff --git a/tests/twisted/fakecm.py b/tests/twisted/fakecm.py deleted file mode 100644 index fb534e7b..00000000 --- a/tests/twisted/fakecm.py +++ /dev/null @@ -1,292 +0,0 @@ -# Copyright (C) 2009 Nokia Corporation -# Copyright (C) 2009 Collabora Ltd. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -# 02110-1301 USA - -import dbus -import dbus.service -from servicetest import Event -from servicetest import EventPattern, tp_name_prefix, tp_path_prefix -from twisted.internet import reactor - -properties_iface = "org.freedesktop.DBus.Properties" -cm_iface = "org.freedesktop.Telepathy.ConnectionManager" -conn_iface = "org.freedesktop.Telepathy.Connection" -caps_iface = \ - "org.freedesktop.Telepathy.Connection.Interface.ContactCapabilities.DRAFT" -requests_iface = "org.freedesktop.Telepathy.Connection.Interface.Requests" -channel_iface = "org.freedesktop.Telepathy.Channel" - -class FakeChannel(dbus.service.Object): - def __init__(self, conn, object_path, q, bus, nameref, props): - self.conn = conn - self.object_path = object_path - self.q = q - self.bus = bus - # keep a reference on nameref, otherwise, the name will be lost! - self.nameref = nameref - self.props = props - - if channel_iface + '.TargetHandle' not in props: - self.props[channel_iface + '.TargetHandle'] = \ - self.conn.get_handle(props[channel_iface + '.TargetID']) - - dbus.service.Object.__init__(self, bus, object_path) - - def called(self, method): - self.q.append(Event('dbus-method-call', name=method, obj=self, - path=self.object_path)) - - @dbus.service.method(dbus_interface=channel_iface, - in_signature='', out_signature='as') - def GetInterfaces(self): - self.called('GetInterfaces') - return [self.props[channel_iface + '.ChannelType']] - - @dbus.service.method(dbus_interface=channel_iface, - in_signature='', out_signature='u') - def GetHandle(self): - return self.props[channel_iface + '.TargetHandle'] - - @dbus.service.method(dbus_interface=channel_iface, - in_signature='', out_signature='') - def Close(self): - self.Closed() - - @dbus.service.signal(dbus_interface=channel_iface, signature='') - def Closed(self): - pass - - -class FakeConn(dbus.service.Object): - def __init__(self, object_path, q, bus, nameref): - self.object_path = object_path - self.q = q - self.bus = bus - # keep a reference on nameref, otherwise, the name will be lost! - self.nameref = nameref - self.status = 2 # Connection_Status_Disconnected - self.next_channel_id = 1 - self.channels = [] - self.handles = {} - self.next_handle = 1337 # break people depending on SelfHandle == 1 - dbus.service.Object.__init__(self, bus, object_path) - - # interface Connection - - @dbus.service.method(dbus_interface=conn_iface, - in_signature='', out_signature='') - def Connect(self): - self.StatusChanged(1, 1) - self.StatusChanged(0, 1) - self.q.append(Event('dbus-method-call', name="Connect", obj=self, - path=self.object_path)) - return None - - @dbus.service.method(dbus_interface=conn_iface, - in_signature='', out_signature='as') - def GetInterfaces(self): - self.q.append(Event('dbus-method-call', name="GetInterfaces", - obj=self, path=self.object_path)) - return dbus.Array([conn_iface, caps_iface, requests_iface]) - - def get_handle(self, id): - for handle, id_ in self.handles.iteritems(): - if id_ == id: - return handle - handle = self.next_handle - self.next_handle += 1 - - self.handles[handle] = id - return handle - - @dbus.service.method(dbus_interface=conn_iface, - in_signature='', out_signature='u') - def GetSelfHandle(self): - self.q.append(Event('dbus-method-call', name="GetSelfHandle", - obj=self, path=self.object_path)) - return self.get_handle('fakeaccount') - - @dbus.service.method(dbus_interface=conn_iface, - in_signature='', out_signature='u') - def GetStatus(self): - self.q.append(Event('dbus-method-call', name="GetStatus", - obj=self, path=self.object_path)) - return self.status - - @dbus.service.method(dbus_interface=conn_iface, - in_signature='uau', out_signature='as') - def InspectHandles(self, handle_type, handles): - self.q.append(Event('dbus-method-call', name="InspectHandles", - obj=self, path=self.object_path, handle_type=handle_type, - handles=handles)) - if handle_type != 1: - raise "non-contact handles don't exist" - - ret = [] - for handle in handles: - if handle not in self.handles: - raise "%d is not a valid handle" % handle - ret.append(self.handles[handle]) - - return ret - - @dbus.service.method(dbus_interface=conn_iface, - in_signature='uas', out_signature='au') - def RequestHandles(self, type, ids): - if type != 1: - raise "non-contact handles don't exist" - - ret = [] - for id in ids: - ret.append(self.get_handle(id)) - - return ret - - @dbus.service.signal(dbus_interface=conn_iface, - signature='uu') - def StatusChanged(self, status, reason): - self.status = status - - # interface Connection.Interface.ContactCapabilities.DRAFT - - @dbus.service.method(dbus_interface=caps_iface, - in_signature='aa{sv}', out_signature='') - def SetSelfCapabilities(self, caps): - self.q.append(Event('dbus-method-call', name="SetSelfCapabilities", - obj=self, path=self.object_path, caps=caps)) - return None - - @dbus.service.signal(dbus_interface=requests_iface, - signature='a(oa{sv})') - def NewChannels(self, array): - self.channels = self.channels + array - - @dbus.service.signal(dbus_interface=conn_iface, - signature='osuub') - def NewChannel(self, object_path, channel_type, handle_type, handle, - suppress_handle): - pass - - @dbus.service.method(dbus_interface=properties_iface, - in_signature='ss', out_signature='v') - def Get(self, interface_name, property_name): - self.q.append(Event('dbus-method-call', name="Get", - obj=self, interface_name=interface_name, - property_name=property_name)) - if interface_name == requests_iface and \ - property_name == "Channels": - return dbus.Array(self.channels, signature='(oa{sv})') - print "Error: interface_name=%s property_name=%s" % \ - (interface_name, property_name) - return None - - @dbus.service.method(dbus_interface=properties_iface, - in_signature='s', out_signature='a{sv}') - def GetAll(self, interface_name): - self.q.append(Event('dbus-method-call', name="GetAll", - obj=self, interface_name=interface_name)) - if interface_name == conn_iface: - return dbus.Dictionary({ - 'SelfHandle': 0L - }, signature='sv') - if interface_name == requests_iface: - return dbus.Dictionary({ - 'Channels': dbus.Array(self.channels, - signature='(oa{sv})') - }, signature='sv') - return None - - def new_incoming_channel(self, object_path, asv): - self.NewChannels(dbus.Array([(object_path, asv)], - signature='(oa{sv})')) - self.NewChannel(object_path, - asv['org.freedesktop.Telepathy.Channel.ChannelType'], - asv['org.freedesktop.Telepathy.Channel.TargetHandleType'], - asv['org.freedesktop.Telepathy.Channel.TargetHandle'], - False) - - # interface Connection.Interface.Requests - def make_channel(self, props): - path = self.object_path + "/channel%d" % self.next_channel_id - self.next_channel_id += 1 - chan = FakeChannel(self, path, self.q, self.bus, self.nameref, props) - reactor.callLater(0, self.NewChannels, [(chan, props)]) - return chan - - @dbus.service.method(dbus_interface=requests_iface, - in_signature='a{sv}', out_signature='oa{sv}') - def CreateChannel(self, request): - self.q.append(Event('dbus-method-call', name="CreateChannel", - obj=self, interface_name=requests_iface)) - chan = self.make_channel(request) - return (chan, request) - - @dbus.service.method(dbus_interface=requests_iface, - in_signature='a{sv}', out_signature='boa{sv}') - def EnsureChannel(self, request): - self.q.append(Event('dbus-method-call', name="EnsureChannel", - obj=self, interface_name=requests_iface)) - chan = self.make_channel(request) - self.q - return (True, chan, request) - - @dbus.service.signal(dbus_interface=requests_iface, - signature="o") - def ChannelClosed(self, channel): - pass - - - -class FakeCM(dbus.service.Object): - def __init__(self, object_path, q, bus, bus_name, nameref): - self.object_path = object_path - self.q = q - self.bus = bus - self.bus_name = bus_name - # keep a reference on nameref, otherwise, the name will be lost! - self.nameref = nameref - dbus.service.Object.__init__(self, bus, object_path) - - @dbus.service.method(dbus_interface=cm_iface, - in_signature='s', out_signature='a(susv)') - def GetParameters(self, protocol): - self.q.append(Event('dbus-method-call', name="GetParameters", - protocol=protocol, obj=self)) - return [] - - @dbus.service.method(dbus_interface=cm_iface, - in_signature='', out_signature='as') - def ListProtocols(self, protocol): - self.q.append(Event('dbus-method-call', name="ListProtocols", obj=self)) - return ['fakeprotocol'] - - @dbus.service.method(dbus_interface=cm_iface, - in_signature='sa{sv}', out_signature='so') - def RequestConnection(self, protocol, parameters): - conn_path = tp_path_prefix + "/Connection/fakecm/fakeprotocol/conn1" - conn = FakeConn(conn_path, self.q, self.bus, self.nameref) - self.q.append(Event('dbus-method-call', name="RequestConnection", - protocol=protocol, parameters=parameters, - conn=conn, obj=self)) - return [self.bus_name, conn_path] - -def start_fake_connection_manager(q, bus, bus_name, object_path): - nameref = dbus.service.BusName(bus_name, bus=bus) - cm = FakeCM(object_path, q, bus, bus_name, nameref) - return cm - - diff --git a/tests/twisted/mc-debug-server.c b/tests/twisted/mc-debug-server.c index 48f02484..559f3f58 100644 --- a/tests/twisted/mc-debug-server.c +++ b/tests/twisted/mc-debug-server.c @@ -154,6 +154,7 @@ main (int argc, char **argv) { GError *error = NULL; GDBusConnection *gdbus = NULL; + GDBusConnection *gdbus_system = NULL; DBusConnection *connection = NULL; int ret = 1; GMainLoop *teardown_loop; @@ -174,26 +175,18 @@ main (int argc, char **argv) G_LOG_FATAL_MASK | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING); gdbus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); - - if (gdbus == NULL) - { - g_warning ("%s", error->message); - g_error_free (error); - error = NULL; - goto out; - } - + g_assert_no_error (error); + g_assert (gdbus != NULL); g_dbus_connection_set_exit_on_close (gdbus, FALSE); - bus_daemon = tp_dbus_daemon_dup (&error); + gdbus_system = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); + g_assert_no_error (error); + g_assert (gdbus_system != NULL); + g_dbus_connection_set_exit_on_close (gdbus_system, FALSE); - if (bus_daemon == NULL) - { - g_warning ("%s", error->message); - g_error_free (error); - error = NULL; - goto out; - } + bus_daemon = tp_dbus_daemon_dup (&error); + g_assert_no_error (error); + g_assert (bus_daemon != NULL); /* It appears that dbus-glib registers a filter that wrongly returns * DBUS_HANDLER_RESULT_HANDLED for signals, so for *our* filter to have any @@ -230,14 +223,13 @@ main (int argc, char **argv) g_main_loop_run (teardown_loop); -out: - if (connection != NULL) { dbus_connection_flush (connection); } tp_clear_object (&gdbus); + tp_clear_object (&gdbus_system); tp_clear_object (&bus_daemon); dbus_shutdown (); diff --git a/tests/twisted/mcp-account-diversion.c b/tests/twisted/mcp-account-diversion.c index a9967648..0e8bfbc8 100644 --- a/tests/twisted/mcp-account-diversion.c +++ b/tests/twisted/mcp-account-diversion.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include <config.h> #include <mission-control-plugins/mission-control-plugins.h> #define DONT_DIVERT "fakecm/fakeprotocol/dontdivert" @@ -110,109 +111,243 @@ _create_config (void) DEBUG ("created %s", file); } -static gboolean -_set (const McpAccountStorage *self, - const McpAccountManager *am, - const gchar *account, - const gchar *key, - const gchar *val) +static McpAccountStorageSetResult +_set (McpAccountStorage *self, + McpAccountManager *am, + const gchar *account, + const gchar *key, + GVariant *val, + McpParameterFlags flags) { AccountDiversionPlugin *adp = ACCOUNT_DIVERSION_PLUGIN (self); + gchar *val_str; + gboolean changed; if (g_str_has_prefix (account, DONT_DIVERT)) - return FALSE; + return MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED; - adp->save = TRUE; - g_key_file_set_value (adp->keyfile, account, key, val); - - return TRUE; -} + if (val == NULL) + { + gsize n; + GStrv keys; -static gboolean -_get (const McpAccountStorage *self, - const McpAccountManager *am, - const gchar *account, - const gchar *key) -{ - AccountDiversionPlugin *adp = ACCOUNT_DIVERSION_PLUGIN (self); + if (g_key_file_remove_key (adp->keyfile, account, key, NULL)) + { + adp->save = TRUE; + changed = TRUE; + } - if (key != NULL) - { - gchar *v = g_key_file_get_value (adp->keyfile, account, key, NULL); + keys = g_key_file_get_keys (adp->keyfile, account, &n, NULL); - if (v == NULL) - return FALSE; + if (keys == NULL || n == 0) + g_key_file_remove_group (adp->keyfile, account, NULL); - mcp_account_manager_set_value (am, account, key, v); - g_free (v); + g_strfreev (keys); } else { - gsize i; - gsize n; - GStrv keys = g_key_file_get_keys (adp->keyfile, account, &n, NULL); + gchar *old; - if (keys == NULL) - n = 0; + val_str = mcp_account_manager_escape_variant_for_keyfile (am, val); - for (i = 0; i < n; i++) - { - gchar *v = g_key_file_get_value (adp->keyfile, account, keys[i], NULL); - - if (v != NULL) - mcp_account_manager_set_value (am, account, keys[i], v); + old = g_key_file_get_value (adp->keyfile, account, key, NULL); - g_free (v); + if (tp_strdiff (old, val_str)) + { + g_key_file_set_value (adp->keyfile, account, key, val_str); + adp->save = TRUE; + changed = TRUE; } - g_strfreev (keys); + g_free (val_str); + g_free (old); } - return TRUE; + if (changed) + return MCP_ACCOUNT_STORAGE_SET_RESULT_CHANGED; + else + return MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED; } -static gboolean -_delete (const McpAccountStorage *self, - const McpAccountManager *am, +static McpAccountStorageSetResult +_set_attribute (McpAccountStorage *self, + McpAccountManager *am, + const gchar *account, + const gchar *attribute, + GVariant *val, + McpAttributeFlags flags) +{ + return _set (self, am, account, attribute, val, flags); +} + +static McpAccountStorageSetResult +_set_parameter (McpAccountStorage *self, + McpAccountManager *am, const gchar *account, - const gchar *key) + const gchar *parameter, + GVariant *val, + McpParameterFlags flags) +{ + gchar *param = g_strdup_printf ("param-%s", parameter); + gboolean ret; + + ret = _set (self, am, account, param, val, flags); + g_free (param); + + return ret; +} + +static GVariant * +_get_attribute (McpAccountStorage *self, + McpAccountManager *am, + const gchar *account, + const gchar *attribute, + const GVariantType *type, + McpAttributeFlags *flags) +{ + AccountDiversionPlugin *adp = ACCOUNT_DIVERSION_PLUGIN (self); + gchar *v; + GVariant *ret; + + if (flags != NULL) + *flags = 0; + + v = g_key_file_get_value (adp->keyfile, account, attribute, NULL); + + if (v == NULL) + return NULL; + + ret = mcp_account_manager_unescape_variant_from_keyfile (am, v, type, NULL); + g_free (v); + return ret; +} + +static GVariant * +_get_parameter (McpAccountStorage *self, + McpAccountManager *am, + const gchar *account, + const gchar *parameter, + const GVariantType *type, + McpParameterFlags *flags) { AccountDiversionPlugin *adp = ACCOUNT_DIVERSION_PLUGIN (self); + gchar *key; + gchar *v; + GVariant *ret; + + if (flags != NULL) + *flags = 0; + + /* this plugin does not store parameters' types, so we can't invent + * a sensible type from nowhere */ + if (type == NULL) + return NULL; - if (key == NULL) + key = g_strdup_printf ("param-%s", parameter); + v = g_key_file_get_value (adp->keyfile, account, key, NULL); + g_free (key); + + if (v == NULL) + return NULL; + + ret = mcp_account_manager_unescape_variant_from_keyfile (am, v, type, NULL); + g_free (v); + return ret; +} + +static gchar ** +list_typed_parameters (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account_name) +{ + /* this plugin can't store parameters' types */ + return NULL; +} + +static gchar ** +list_untyped_parameters (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account_name) +{ + AccountDiversionPlugin *adp = ACCOUNT_DIVERSION_PLUGIN (storage); + gchar **keys; + gsize i; + GPtrArray *arr; + + keys = g_key_file_get_keys (adp->keyfile, account_name, &i, NULL); + + if (keys == NULL) + return NULL; + + arr = g_ptr_array_sized_new (i); + + for (i = 0; keys[i] != NULL; i++) { - if (g_key_file_remove_group (adp->keyfile, account, NULL)) - adp->save = TRUE; + if (g_str_has_prefix (keys[i], "param-")) + g_ptr_array_add (arr, g_strdup (keys[i] + 6)); } - else - { - gsize n; - GStrv keys; - if (g_key_file_remove_key (adp->keyfile, account, key, NULL)) - adp->save = TRUE; + g_strfreev (keys); + g_ptr_array_add (arr, NULL); + return (gchar **) g_ptr_array_free (arr, FALSE); +} - keys = g_key_file_get_keys (adp->keyfile, account, &n, NULL); +static gboolean _commit (McpAccountStorage *self, + McpAccountManager *am, + const gchar *account_name); - if (keys == NULL || n == 0) - g_key_file_remove_group (adp->keyfile, account, NULL); +static void +delete_async (McpAccountStorage *self, + McpAccountManager *am, + const gchar *account, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + AccountDiversionPlugin *adp = ACCOUNT_DIVERSION_PLUGIN (self); + GTask *task = g_task_new (adp, cancellable, callback, user_data); - g_strfreev (keys); + if (g_key_file_remove_group (adp->keyfile, account, NULL)) + adp->save = TRUE; + + if (_commit (self, am, account)) + { + mcp_account_storage_emit_deleted (self, account); + g_task_return_boolean (task, TRUE); + } + else + { + g_task_return_new_error (task, TP_ERROR, TP_ERROR_NOT_AVAILABLE, + "_commit()'s error handling is not good enough to know why " + "I couldn't commit the deletion of %s", account); } - return TRUE; + g_object_unref (task); } +static gboolean +delete_finish (McpAccountStorage *storage, + GAsyncResult *res, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (res), error); +} static gboolean -_commit (const McpAccountStorage *self, - const McpAccountManager *am) +_commit (McpAccountStorage *self, + McpAccountManager *am, + const gchar *account_name G_GNUC_UNUSED) { gsize n; gchar *data; AccountDiversionPlugin *adp = ACCOUNT_DIVERSION_PLUGIN (self); gboolean rval = FALSE; + /* This simple implementation ignores account_name and commits everything: + * we're writing out the whole keyfile anyway. If MC is looping over + * accounts, the second and subsequent accounts will find that + * adp->save is false, so there's no write-amplification. */ + if (!adp->save) return TRUE; @@ -228,8 +363,8 @@ _commit (const McpAccountStorage *self, } static GList * -_list (const McpAccountStorage *self, - const McpAccountManager *am) +_list (McpAccountStorage *self, + McpAccountManager *am) { gsize i; gsize n; @@ -254,6 +389,35 @@ _list (const McpAccountStorage *self, return rval; } +static gchar * +create (McpAccountStorage *self, + McpAccountManager *am, + const gchar *manager, + const gchar *protocol, + const gchar *identification, + GError **error) +{ + gchar *unique_name; + + unique_name = mcp_account_manager_get_unique_name (MCP_ACCOUNT_MANAGER (am), + manager, protocol, + identification); + + g_return_val_if_fail (unique_name != NULL, NULL); + + if (g_str_has_prefix (unique_name, DONT_DIVERT)) + { + g_free (unique_name); + return NULL; + } + + /* No need to actually create anything: we'll happily return values + * from get(., ., ., NULL) regardless of whether we have that account + * in our list */ + + return unique_name; +} + static void account_storage_iface_init (McpAccountStorageIface *iface, gpointer unused G_GNUC_UNUSED) @@ -262,11 +426,17 @@ account_storage_iface_init (McpAccountStorageIface *iface, iface->desc = PLUGIN_DESCRIPTION; iface->priority = PLUGIN_PRIORITY; - iface->get = _get; - iface->set = _set; - iface->delete = _delete; + iface->get_attribute = _get_attribute; + iface->get_parameter = _get_parameter; + iface->list_typed_parameters = list_typed_parameters; + iface->list_untyped_parameters = list_untyped_parameters; + iface->set_attribute = _set_attribute; + iface->set_parameter = _set_parameter; + iface->delete_async = delete_async; + iface->delete_finish = delete_finish; iface->commit = _commit; iface->list = _list; + iface->create = create; } diff --git a/tests/twisted/mcp-dbus-caller-permission.c b/tests/twisted/mcp-dbus-caller-permission.c deleted file mode 100644 index 96162baf..00000000 --- a/tests/twisted/mcp-dbus-caller-permission.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * A demonstration plugin that checks a DBus caller's md5sum - * - * Copyright © 2010 Nokia Corporation - * Copyright © 2010 Collabora Ltd. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <mission-control-plugins/mission-control-plugins.h> -#include <sys/types.h> - -#define CONFFILE "mcp-dbus-caller-permissions.conf" - -#define DEBUG g_debug - -#define PLUGIN_NAME "dbus-caller-permission-checker" -#define PLUGIN_DESCRIPTION \ - "Test plugin that checks the md5 checksum of a DBus caller. " \ - "gkeyfile g_get_user_cache_dir()/" CONFFILE " holds the [paths " \ - "to] the binaries, and the permission tokens associated with each." - -/* Example conf file: -[/usr/local/bin/mc-tool] -org.freedesktop.Telepathy.AccountManager=1 -*=1 -*/ - -static void dbus_acl_iface_init (McpDBusAclIface *, - gpointer); - -typedef struct { - GObject parent; - GKeyFile *permits; - gboolean loaded; -} DBusCallerPermission; - -typedef struct { - GObjectClass parent_class; -} DBusCallerPermissionClass; - -GType dbus_caller_permission_get_type (void) G_GNUC_CONST; - -#define DBUS_CALLER_PERMISSION(o) \ - (G_TYPE_CHECK_INSTANCE_CAST ((o), dbus_caller_permission_get_type (), \ - DBusCallerPermission)) - -G_DEFINE_TYPE_WITH_CODE (DBusCallerPermission, dbus_caller_permission, - G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (MCP_TYPE_DBUS_ACL, dbus_acl_iface_init)); - -static void -dbus_caller_permission_init (DBusCallerPermission *self) -{ - const gchar *dir; - gchar *file = NULL; - - self->permits = g_key_file_new (); - - dir = g_get_user_cache_dir (); - file = g_build_path (G_DIR_SEPARATOR_S, dir, CONFFILE, NULL); - - if (!g_file_test (file, G_FILE_TEST_EXISTS)) - { - g_mkdir_with_parents (dir, 0700); - g_file_set_contents (file, "# MC DBus permissions\n", -1, NULL); - } - - DEBUG ("conf file %s", file); - g_key_file_load_from_file (self->permits, file, G_KEY_FILE_NONE, NULL); - - g_free (file); -} - -static void -dbus_caller_permission_class_init (DBusCallerPermissionClass *cls) -{ -} - -static gboolean is_filtered (const McpDBusAcl *self, - DBusAclType type, - const gchar *name) -{ - DBusCallerPermission *plugin = DBUS_CALLER_PERMISSION (self); - GKeyFile *permits = plugin->permits; - - switch (type) - { - case DBUS_ACL_TYPE_METHOD: - return g_key_file_get_boolean (permits, "methods", name, NULL); - case DBUS_ACL_TYPE_GET_PROPERTY: - return g_key_file_get_boolean (permits, "get-property", name, NULL); - case DBUS_ACL_TYPE_SET_PROPERTY: - return g_key_file_get_boolean (permits, "set-property", name, NULL); - default: - return FALSE; - } -} - -static gboolean -pid_is_permitted (const McpDBusAcl *self, const gchar *name, pid_t pid) -{ - gboolean ok = FALSE; - - if (pid != 0) - { - gchar *path = g_strdup_printf ("/proc/%d/exe", pid); - gchar *executable = g_file_read_link (path, NULL); - - if (executable != NULL) - { - DBusCallerPermission *plugin = DBUS_CALLER_PERMISSION (self); - GKeyFile *permits = plugin->permits; - - DEBUG ("executable to check for permission is %s", executable); - ok = g_key_file_get_boolean (permits, executable, name, NULL); - DEBUG ("%s:%s = %s", executable, name, ok ? "TRUE" : "FALSE"); - - g_free (executable); - } - - g_free (path); - } - - return ok; -} - -static gboolean -caller_authorised (const McpDBusAcl *self, - const TpDBusDaemon *dbus, - const DBusGMethodInvocation *call, - DBusAclType type, - const gchar *name, - const GHashTable *params) -{ - DBusGConnection *dgc = tp_proxy_get_dbus_connection ((TpDBusDaemon *)dbus); - gboolean ok = TRUE; - - if (is_filtered (self, type, name)) - { - pid_t pid = 0; - GError *error = NULL; - gchar *caller = dbus_g_method_get_sender ((DBusGMethodInvocation *) call); - DBusGProxy *proxy = dbus_g_proxy_new_for_name (dgc, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS); - - dbus_g_proxy_call (proxy, "GetConnectionUnixProcessID", &error, - G_TYPE_STRING, caller, - G_TYPE_INVALID, - G_TYPE_UINT, &pid, - G_TYPE_INVALID); - - ok = pid_is_permitted (self, name, pid); - - g_free (caller); - g_object_unref (proxy); - } - - DEBUG ("sync caller-permission ACL check [%s]", ok ? "Allowed" : "Forbidden"); - - return ok; -} - -static void -async_authorised_cb (DBusGProxy *proxy, - DBusGProxyCall *call, - gpointer data) -{ - GError *error = NULL; - DBusAclAuthData *ad = data; - pid_t pid = 0; - const McpDBusAcl *self = ad->acl; - gboolean permitted = FALSE; - - /* if this returns FALSE, there's no PID, which means something bizarre * - * and untrustowrthy is going on, which in turn means we must deny: can't * - * authorise without first authenticating */ - permitted = dbus_g_proxy_end_call (proxy, call, &error, - G_TYPE_UINT, &pid, - G_TYPE_INVALID); - - if (permitted) - permitted = pid_is_permitted (self, ad->name, pid); - else - g_error_free (error); - - DEBUG ("finished async caller-permission ACL check [%u -> %s]", - pid, permitted ? "Allowed" : "Forbidden"); - - mcp_dbus_acl_authorised_async_step (ad, permitted); -} - -static void -caller_async_authorised (const McpDBusAcl *self, - DBusAclAuthData *data) -{ - DBusGConnection *dgc = tp_proxy_get_dbus_connection (data->dbus); - DBusGProxy *proxy = dbus_g_proxy_new_for_name (dgc, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS); - - DEBUG ("starting async caller-permission ACL check"); - - if (is_filtered (self, data->type, data->name)) - { - gchar *caller = dbus_g_method_get_sender (data->context); - - dbus_g_proxy_begin_call (proxy, "GetConnectionUnixProcessID", - async_authorised_cb, - data, - NULL, - G_TYPE_STRING, caller, - G_TYPE_INVALID); - - g_free (caller); - } - else /* not filtered, so the call is allowed: */ - { - mcp_dbus_acl_authorised_async_step (data, TRUE); - } -} - - -static void -dbus_acl_iface_init (McpDBusAclIface *iface, - gpointer unused G_GNUC_UNUSED) -{ - mcp_dbus_acl_iface_set_name (iface, PLUGIN_NAME); - mcp_dbus_acl_iface_set_desc (iface, PLUGIN_DESCRIPTION); - - mcp_dbus_acl_iface_implement_authorised (iface, caller_authorised); - mcp_dbus_acl_iface_implement_authorised_async (iface, caller_async_authorised); -} - -GObject * -mcp_plugin_ref_nth_object (guint n) -{ - DEBUG ("Initializing mcp-dbus-caller-id plugin (n=%u)", n); - - switch (n) - { - case 0: - return g_object_new (dbus_caller_permission_get_type (), NULL); - - default: - return NULL; - } -} - diff --git a/tests/twisted/mcp-plugin.c b/tests/twisted/mcp-plugin.c index 7d347b11..de74134f 100644 --- a/tests/twisted/mcp-plugin.c +++ b/tests/twisted/mcp-plugin.c @@ -49,7 +49,6 @@ GType test_no_op_plugin_get_type (void) G_GNUC_CONST; G_DEFINE_TYPE_WITH_CODE (TestNoOpPlugin, test_no_op_plugin, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (MCP_TYPE_DBUS_ACL, NULL); G_IMPLEMENT_INTERFACE (MCP_TYPE_REQUEST_POLICY, NULL); G_IMPLEMENT_INTERFACE (MCP_TYPE_DISPATCH_OPERATION_POLICY, NULL)) @@ -137,11 +136,8 @@ permission_cb (DBusPendingCall *pc, } else { - G_GNUC_BEGIN_IGNORE_DEPRECATIONS - mcp_dispatch_operation_leave_channels (ctx->dispatch_operation, - TRUE, TP_CHANNEL_GROUP_CHANGE_REASON_PERMISSION_DENIED, - "Computer says no"); - G_GNUC_END_IGNORE_DEPRECATIONS + mcp_dispatch_operation_destroy_channels (ctx->dispatch_operation, + TRUE); } } else @@ -513,12 +509,8 @@ test_rejection_plugin_check_cdo (McpDispatchOperationPolicy *policy, } else if (!tp_strdiff (target_id, "mc.hammer@example.net")) { - DEBUG ("MC Hammer detected, leaving channels when observers have run"); - G_GNUC_BEGIN_IGNORE_DEPRECATIONS - mcp_dispatch_operation_leave_channels (dispatch_operation, TRUE, - TP_CHANNEL_GROUP_CHANGE_REASON_PERMISSION_DENIED, - "Can't touch this"); - G_GNUC_END_IGNORE_DEPRECATIONS + DEBUG ("MC Hammer detected, destroying channels when observers have run"); + mcp_dispatch_operation_destroy_channels (dispatch_operation, TRUE); } g_hash_table_unref (properties); diff --git a/tests/twisted/mctest.py b/tests/twisted/mctest.py index 2909acc9..549a742c 100644 --- a/tests/twisted/mctest.py +++ b/tests/twisted/mctest.py @@ -166,7 +166,7 @@ def exec_test_deferred (fun, params, protocol=None, timeout=None, try: account.Properties.Set(cs.ACCOUNT, 'RequestedPresence', - (dbus.UInt32(cs.PRESENCE_TYPE_OFFLINE), 'offline', + (dbus.UInt32(cs.PRESENCE_OFFLINE), 'offline', '')) except dbus.DBusException, e: print >> sys.stderr, "Can't set %s offline: %s" % (a, e) @@ -222,7 +222,7 @@ class SimulatedConnection(object): def __init__(self, q, bus, cmname, protocol, account_part, self_ident, self_alias=None, - implement_get_interfaces=True, has_requests=True, + implement_get_channels=True, has_requests=True, has_presence=False, has_aliasing=False, has_avatars=False, avatars_persist=True, extra_interfaces=[], has_hidden=False, implement_get_aliases=True, initial_avatar=None, @@ -292,10 +292,12 @@ class SimulatedConnection(object): interface=cs.PROPERTIES_IFACE, method='GetAll', args=[cs.CONN]) - if implement_get_interfaces: - q.add_dbus_method_impl(self.GetInterfaces, - path=self.object_path, interface=cs.CONN, - method='GetInterfaces') + q.add_dbus_method_impl(self.GetInterfaces, + path=self.object_path, interface=cs.CONN, + method='GetInterfaces') + q.add_dbus_method_impl(self.Get_Interfaces, + path=self.object_path, interface=cs.PROPERTIES_IFACE, + method='Get', args=[cs.CONN, 'Interfaces']) q.add_dbus_method_impl(self.RequestHandles, path=self.object_path, interface=cs.CONN, @@ -306,10 +308,12 @@ class SimulatedConnection(object): q.add_dbus_method_impl(self.HoldHandles, path=self.object_path, interface=cs.CONN, method='HoldHandles') - q.add_dbus_method_impl(self.GetAll_Requests, - path=self.object_path, - interface=cs.PROPERTIES_IFACE, method='GetAll', - args=[cs.CONN_IFACE_REQUESTS]) + + if implement_get_channels and has_requests: + q.add_dbus_method_impl(self.GetAll_Requests, + path=self.object_path, + interface=cs.PROPERTIES_IFACE, method='GetAll', + args=[cs.CONN_IFACE_REQUESTS]) q.add_dbus_method_impl(self.GetContactAttributes, path=self.object_path, @@ -373,22 +377,22 @@ class SimulatedConnection(object): method='SetAvatar') self.statuses = dbus.Dictionary({ - 'available': (cs.PRESENCE_TYPE_AVAILABLE, True, True), - 'away': (cs.PRESENCE_TYPE_AWAY, True, True), - 'lunch': (cs.PRESENCE_TYPE_XA, True, True), - 'busy': (cs.PRESENCE_TYPE_BUSY, True, True), - 'phone': (cs.PRESENCE_TYPE_BUSY, True, True), - 'offline': (cs.PRESENCE_TYPE_OFFLINE, False, False), - 'error': (cs.PRESENCE_TYPE_ERROR, False, False), - 'unknown': (cs.PRESENCE_TYPE_UNKNOWN, False, False), + 'available': (cs.PRESENCE_AVAILABLE, True, True), + 'away': (cs.PRESENCE_AWAY, True, True), + 'lunch': (cs.PRESENCE_EXTENDED_AWAY, True, True), + 'busy': (cs.PRESENCE_BUSY, True, True), + 'phone': (cs.PRESENCE_BUSY, True, True), + 'offline': (cs.PRESENCE_OFFLINE, False, False), + 'error': (cs.PRESENCE_ERROR, False, False), + 'unknown': (cs.PRESENCE_UNKNOWN, False, False), }, signature='s(ubb)') if has_hidden: - self.statuses['hidden'] = (cs.PRESENCE_TYPE_HIDDEN, True, True) + self.statuses['hidden'] = (cs.PRESENCE_HIDDEN, True, True) # "dbus.UInt32" to work around # https://bugs.freedesktop.org/show_bug.cgi?id=69967 - self.presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_TYPE_OFFLINE), + self.presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_OFFLINE), 'offline', ''), signature='uss') def change_self_ident(self, ident): @@ -495,7 +499,7 @@ class SimulatedConnection(object): else: # stub - MC doesn't care ret[contact] = dbus.Struct( - (cs.PRESENCE_TYPE_UNKNOWN, 'unknown', ''), + (cs.PRESENCE_UNKNOWN, 'unknown', ''), signature='uss') self.q.dbus_return(e.message, ret, signature='a{u(uss)}') @@ -530,14 +534,19 @@ class SimulatedConnection(object): def GetInterfaces(self, e): self.q.dbus_return(e.message, self.interfaces, signature='as') + def Get_Interfaces(self, e): + self.q.dbus_return(e.message, + dbus.Array(self.interfaces, signature='s'), + signature='v') + def Connect(self, e): self.StatusChanged(cs.CONN_STATUS_CONNECTING, - cs.CONN_STATUS_REASON_REQUESTED) + cs.CSR_REQUESTED) self.q.dbus_return(e.message, signature='') def Disconnect(self, e): self.StatusChanged(cs.CONN_STATUS_DISCONNECTED, - cs.CONN_STATUS_REASON_REQUESTED) + cs.CSR_REQUESTED) self.q.dbus_return(e.message, signature='') for c in self.channels: c.close() @@ -581,11 +590,10 @@ class SimulatedConnection(object): self.q.dbus_emit(self.object_path, cs.CONN, 'StatusChanged', status, reason, signature='uu') if self.status == cs.CONN_STATUS_CONNECTED and self.has_presence: - if self.presence[0] == cs.PRESENCE_TYPE_OFFLINE: + if self.presence[0] == cs.PRESENCE_OFFLINE: # "dbus.UInt32" to work around # https://bugs.freedesktop.org/show_bug.cgi?id=69967 - self.presence = dbus.Struct(( - dbus.UInt32(cs.PRESENCE_TYPE_AVAILABLE), + self.presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_AVAILABLE), 'available', ''), signature='uss') self.q.dbus_emit(self.object_path, @@ -837,7 +845,7 @@ class SimulatedClient(object): observe=[], approve=[], handle=[], cap_tokens=[], bypass_approval=False, wants_recovery=False, request_notification=True, implement_get_interfaces=True, - is_handler=None, bypass_observers=False, delay_approvers=False): + is_handler=None, delay_approvers=False): self.q = q self.bus = bus self.bus_name = '.'.join([cs.tp_name_prefix, 'Client', clientname]) @@ -847,7 +855,6 @@ class SimulatedClient(object): self.approve = aasv(approve) self.handle = aasv(handle) self.bypass_approval = bool(bypass_approval) - self.bypass_observers = bool(bypass_observers) self.delay_approvers = bool(delay_approvers) self.wants_recovery = bool(wants_recovery) self.request_notification = bool(request_notification) @@ -963,7 +970,6 @@ class SimulatedClient(object): self.q.dbus_return(e.message, { 'HandlerChannelFilter': self.handle, 'BypassApproval': self.bypass_approval, - 'BypassObservers': self.bypass_observers, 'HandledChannels': self.handled_channels, 'Capabilities': self.cap_tokens, }, @@ -987,21 +993,173 @@ class SimulatedClient(object): self.q.dbus_return(e.message, self.bypass_approval, signature='v', bus=self.bus) - def Get_BypassApproval(self, e): - assert self.handle - self.q.dbus_return(e.message, self.bypass_observers, signature='v', - bus=self.bus) - def Get_Recover(self, e): assert self.handle self.q.dbus_return(e.message, self.recover, signature='v', bus=self.bus) +class SimulatedConnectionManager(object): + def __init__(self, q, bus, cm_name='fakecm', + protocol_names=['fakeprotocol']): + self.q = q + self.bus = bus + self.cm_name = cm_name + self.bus_name = '.'.join([cs.CM, cm_name]) + self._bus_name_ref = dbus.service.BusName(self.bus_name, self.bus) + self.object_path = '/' + self.bus_name.replace('.', '/') + self.protocol_names = list(protocol_names) + + q.add_dbus_method_impl(self.GetAll_CM, + path=self.object_path, + interface=cs.PROPERTIES_IFACE, method='GetAll', + args=[cs.CM]) + + for protocol_name in protocol_names: + assert '-' not in protocol_name + + q.add_dbus_method_impl(self.IdentifyAccount, + interface=cs.PROTOCOL, method='IdentifyAccount') + q.add_dbus_method_impl(self.NormalizeContact, + interface=cs.PROTOCOL, method='NormalizeContact') + + def release_name(self): + del self._bus_name_ref + + def reacquire_name(self): + self._bus_name_ref = dbus.service.BusName(self.bus_name, self.bus) + + def get_protocols(self): + ret = dbus.Dictionary(signature='sa{sv}') + + for p in self.protocol_names: + # stub: assume all the protocols look "reasonably normal" + ret[p] = { + cs.PROTOCOL + '.Interfaces': dbus.Array(signature='s'), + cs.PROTOCOL + '.ConnectionInterfaces': + dbus.Array(signature='s'), + cs.PROTOCOL + '.RequestableChannelClasses': + dbus.Array(signature='(a{sv}as)'), + cs.PROTOCOL + '.VCardField': 'x-' + self.cm_name, + cs.PROTOCOL + '.EnglishName': self.cm_name, + cs.PROTOCOL + '.Icon': 'im-' + self.cm_name, + cs.PROTOCOL + '.AuthenticationTypes': + dbus.Array(signature='s'), + cs.PROTOCOL + '.Parameters': dbus.Array([ + ('account', cs.PARAM_REQUIRED, 's', ''), + ('password', cs.PARAM_SECRET, 's', ''), + ], signature='(susv)'), + } + + if self.cm_name == 'fakecm' and p == 'fakeprotocol': + ret[p][cs.PROTOCOL + '.Parameters'] = dbus.Array([ + ('account', cs.PARAM_REQUIRED|cs.PARAM_REGISTER, + 's', ''), + ('password', + cs.PARAM_SECRET|cs.PARAM_REQUIRED|cs.PARAM_REGISTER, + 's', ''), + ('nickname', cs.PARAM_REGISTER, 's', ''), + ('register', cs.PARAM_HAS_DEFAULT, 'b', False), + ('com.example.Badgerable.Badgered', + cs.PARAM_HAS_DEFAULT|cs.PARAM_DBUS_PROPERTY, + 'b', False), + ('secret-mushroom', cs.PARAM_SECRET, 's', ''), + ('snakes', 0, 'u', dbus.UInt32(0)), + ('contrived-example', cs.PARAM_HAS_DEFAULT, 'u', + dbus.UInt32(5)), + ], signature='(susv)') + + if self.cm_name == 'onewitheverything' and p == 'serializable': + ret[p][cs.PROTOCOL + '.Parameters'] = dbus.Array([ + ('s', cs.PARAM_REQUIRED, 's', ''), + ('o', 0, 'o', dbus.ObjectPath('/')), + ('b', 0, 'b', False), + ('q', 0, 'q', dbus.UInt16(0)), + ('u', 0, 'u', dbus.UInt32(0)), + ('t', 0, 't', dbus.UInt64(0)), + ('n', 0, 'n', dbus.Int16(0)), + ('i', 0, 'i', dbus.Int32(0)), + ('x', 0, 'x', dbus.Int64(0)), + ('d', 0, 'd', 0.0), + ('as', 0, 'as', dbus.Array(signature='s')), + ('y', 0, 'y', dbus.Byte(0)), + ], signature='(susv)') + + if self.cm_name == 'onewitheverything' and p == 'defaults': + ret[p][cs.PROTOCOL + '.Parameters'] = dbus.Array([ + ('s', cs.PARAM_HAS_DEFAULT, 's', 'foo'), + ('o', cs.PARAM_HAS_DEFAULT, 'o', dbus.ObjectPath('/foo')), + ('b', cs.PARAM_HAS_DEFAULT, 'b', True), + ('q', cs.PARAM_HAS_DEFAULT, 'q', dbus.UInt16(1)), + ('u', cs.PARAM_HAS_DEFAULT, 'u', dbus.UInt32(1)), + ('t', cs.PARAM_HAS_DEFAULT, 't', dbus.UInt64(1)), + ('n', cs.PARAM_HAS_DEFAULT, 'n', dbus.Int16(-1)), + ('i', cs.PARAM_HAS_DEFAULT, 'i', dbus.Int32(-1)), + ('x', cs.PARAM_HAS_DEFAULT, 'x', dbus.Int64(-1)), + ('d', cs.PARAM_HAS_DEFAULT, 'd', 1.5), + ('as', cs.PARAM_HAS_DEFAULT, 'as', + dbus.Array(['foo', 'bar', 'baz'], signature='s')), + ('y', cs.PARAM_HAS_DEFAULT, 'y', dbus.Byte(1)), + ], signature='(susv)') + + if self.cm_name == 'onewitheverything' and p == 'flags': + ret[p][cs.PROTOCOL + '.Parameters'] = dbus.Array([ + ('account', cs.PARAM_REQUIRED|cs.PARAM_REGISTER, 's', ''), + ('name', cs.PARAM_REGISTER, 's', ''), + ('key', + cs.PARAM_REGISTER|cs.PARAM_REQUIRED|cs.PARAM_SECRET, + 's', ''), + ('com.example.Badgerable.Badgers', cs.PARAM_DBUS_PROPERTY, + 's', ''), + ], signature='(susv)') + + return ret + + def get_interfaces(self): + return dbus.Array([], signature='s') + + def GetAll_CM(self, e): + self.q.dbus_return(e.message, { + 'Protocols': self.get_protocols(), + 'Interfaces': self.get_interfaces(), + }, signature='a{sv}', bus=self.bus) + + def IdentifyAccount(self, e): + if e.path.startswith(self.object_path + '/'): + protocol = e.path[len(self.object_path + '/'):] + + if protocol not in self.protocol_names: + self.q.dbus_raise(e.message, cs.DBUS_ERROR_UNKNOWN_METHOD, + 'Not my protocol') + return + else: + self.q.dbus_raise(e.message, cs.DBUS_ERROR_UNKNOWN_METHOD, + 'Not even my object path') + return + + if protocol in ('serializable', 'defaults') and 's' in e.args[0]: + ret = e.args[0]['s'].lower() + if ret: + self.q.dbus_return(e.message, ret, signature='s') + return + + if 'account' in e.args[0]: + ret = e.args[0]['account'].lower() + if ret: + self.q.dbus_return(e.message, ret, signature='s') + return + + self.q.dbus_raise(e.message, cs.INVALID_HANDLE, + 'Invalid account name %r' % e.args[0].get('account')) + + def NormalizeContact(self, e): + self.q.dbus_return(e.message, e.args[0].lower(), signature='s') + def take_fakecm_name(bus): return dbus.service.BusName(cs.CM + '.fakecm', bus=bus) def create_fakecm_account(q, bus, mc, params, properties={}, - cm_bus=None): + cm_bus=None, simulated_cm=None, + cm_name='fakecm', protocol_name='fakeprotocol'): """Create a fake connection manager and an account that uses it. Optional keyword arguments: @@ -1016,23 +1174,17 @@ def create_fakecm_account(q, bus, mc, params, properties={}, if cm_bus is None: cm_bus = bus - cm_name_ref = take_fakecm_name(cm_bus) + if simulated_cm is None: + simulated_cm = SimulatedConnectionManager(q, bus, + cm_name=cm_name, protocol_names=[protocol_name]) account_manager = AccountManager(bus) servicetest.call_async(q, account_manager, 'CreateAccount', - 'fakecm', 'fakeprotocol', 'fakeaccount', params, properties) - - # Check whether the account being created is to be hidden; if so, then - # expect a different signal. It annoys me that this has to be in here, but, - # eh. - if properties.get(cs.ACCOUNT_IFACE_HIDDEN + '.Hidden', False): - validity_changed_pattern = servicetest.EventPattern('dbus-signal', - path=cs.AM_PATH, signal='HiddenAccountValidityChanged', - interface=cs.AM_IFACE_HIDDEN) - else: - validity_changed_pattern = servicetest.EventPattern('dbus-signal', - path=cs.AM_PATH, signal='AccountValidityChanged', interface=cs.AM) + cm_name, protocol_name, 'fakeaccount', params, properties) + + validity_changed_pattern = servicetest.EventPattern('dbus-signal', + path=cs.AM_PATH, signal='AccountValidityChanged', interface=cs.AM) # The spec has no order guarantee here. # FIXME: MC ought to also introspect the CM and find out that the params @@ -1056,7 +1208,7 @@ def create_fakecm_account(q, bus, mc, params, properties={}, interface, prop = key.rsplit('.', 1) servicetest.assertEquals(value, account.Properties.Get(interface, prop)) - return (cm_name_ref, account) + return (simulated_cm, account) def get_fakecm_account(bus, mc, account_path): account = Account(bus, account_path) @@ -1096,19 +1248,25 @@ def expect_fakecm_connection(q, bus, mc, account, expected_params, extra_interfaces=[], expect_before_connect=(), expect_after_connect=(), has_hidden=False, - self_ident='myself'): + self_ident='myself', + cm_name='fakecm', + protocol_name='fakeprotocol'): # make (safely) mutable copies expect_before_connect = list(expect_before_connect) expect_after_connect = list(expect_after_connect) + # for simplicity we assume the sort of name that is invariant between + # Telepathy 0 and Telepathy 1 + assert '-' not in protocol_name + e = q.expect('dbus-method-call', method='RequestConnection', - args=['fakeprotocol', expected_params], - destination=cs.tp_name_prefix + '.ConnectionManager.fakecm', - path=cs.tp_path_prefix + '/ConnectionManager/fakecm', - interface=cs.tp_name_prefix + '.ConnectionManager', + args=[protocol_name, expected_params], + destination=cs.CM + '.' + cm_name, + path='/' + cs.CM.replace('.', '/') + '/' + cm_name, + interface=cs.CM, handled=False) - conn = SimulatedConnection(q, bus, 'fakecm', 'fakeprotocol', + conn = SimulatedConnection(q, bus, cm_name, protocol_name, account.object_path.split('/')[-1], self_ident, has_requests=has_requests, has_presence=has_presence, has_aliasing=has_aliasing, has_avatars=has_avatars, @@ -1133,21 +1291,12 @@ def expect_fakecm_connection(q, bus, mc, account, expected_params, q.expect('dbus-method-call', method='Connect', path=conn.object_path, handled=True) - conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CONN_STATUS_REASON_NONE) + conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CSR_NONE_SPECIFIED) expect_after_connect = list(expect_after_connect) - if not has_requests: - expect_after_connect.append( - servicetest.EventPattern('dbus-method-call', - interface=cs.CONN, method='ListChannels', args=[], - path=conn.object_path, handled=True)) - events = events + list(q.expect_many(*expect_after_connect)) - if not has_requests: - del events[-1] - if events: return (conn,) + tuple(events) diff --git a/tests/twisted/run-test.sh.in b/tests/twisted/run-test.sh.in index 56ade7b3..5f29132d 100644 --- a/tests/twisted/run-test.sh.in +++ b/tests/twisted/run-test.sh.in @@ -19,7 +19,7 @@ export MC_TEST_CURDIR if test "x$MC_TEST_UNINSTALLED" = x; then script_fullname=`readlink -e "@mctestsdir@/twisted/run-test.sh"` if [ `readlink -e "$0"` != "$script_fullname" ] ; then - echo "This script is meant to be installed at $script_fullname" >&2 + echo "Bail out! This script is meant to be installed at $script_fullname" exit 1 fi @@ -35,11 +35,11 @@ if test "x$MC_TEST_UNINSTALLED" = x; then export MC_TWISTED_PATH else if test -z "$MC_ABS_TOP_SRCDIR"; then - echo "MC_ABS_TOP_SRCDIR must be set" >&2 + echo "Bail out! MC_ABS_TOP_SRCDIR must be set" exit 1 fi if test -z "$MC_ABS_TOP_BUILDDIR"; then - echo "MC_ABS_TOP_BUILDDIR must be set" >&2 + echo "Bail out! MC_ABS_TOP_BUILDDIR must be set" exit 1 fi @@ -59,9 +59,6 @@ MC_DEBUG=all export MC_DEBUG G_DEBUG=fatal-criticals export G_DEBUG -# for ENABLE_LIBACCOUNTS_SSO -AG_DEBUG=all -export AG_DEBUG GIO_EXTRA_MODULES="${plugins}" export GIO_EXTRA_MODULES @@ -82,11 +79,20 @@ else list=$(cat "${test_build}"/twisted/mc-twisted-tests.list) fi -any_failed=0 +n=0 for i in $list ; do - echo "Testing $i ..." + n=$(( $n + 1 )) +done + +echo "1..$n" + +i=0 +n_failed=0 +for t in $list ; do + i=$(( $i + 1 )) + echo "# Testing $i/$n: $t ..." - tmp="${MC_TEST_CURDIR}/tmp-`echo $i | tr ./ __`" + tmp="${MC_TEST_CURDIR}/tmp-`echo $t | tr ./ __`" rm -fr "$tmp" mkdir "$tmp" @@ -105,12 +111,6 @@ for i in $list ; do XDG_CACHE_DIR="${tmp}/cache" export XDG_CACHE_DIR - # for ENABLE_LIBACCOUNTS_SSO - ACCOUNTS="${tmp}/libaccounts-accounts" - export ACCOUNTS - AG_SERVICES="${tmp}/libaccounts-services" - export AG_SERVICES - CHECK_TWISTED_VERBOSE=1 export CHECK_TWISTED_VERBOSE @@ -120,32 +120,38 @@ for i in $list ; do --also-for-system \ --config-file="${config_file}" \ -- \ - @TEST_PYTHON@ -u "${test_src}/twisted/$i" \ + @TEST_PYTHON@ -u "${test_src}/twisted/$t" \ > "$tmp"/test.log 2>&1 || e=$? case "$e" in (0) - echo "PASS: $i" + echo "ok $i - $t" if test -z "$MC_TEST_KEEP_TEMP"; then rm -fr "$tmp" fi ;; (77) - echo "SKIP: $i" + echo "ok $i # SKIP $t" if test -z "$MC_TEST_KEEP_TEMP"; then rm -fr "$tmp" fi ;; (*) - any_failed=1 - echo "FAIL: $i ($e)" + n_failed=$(( $n_failed + 1 )) + echo "not ok $i - $t ($e)" ( cd $tmp && for x in *.log; do - echo "===== log file: $x =====" - cat "$x" + echo "# ===== log file: $x =====" + sed 's/^/# /' "$x" done + echo "# ===== end of log files for $t =====" ) ;; esac done -exit $any_failed +if test $n_failed != 0; then + echo "# Tests run: $n; tests failed: $n_failed" + exit 1 +else + exit 0 +fi diff --git a/tests/twisted/servicetest.py b/tests/twisted/servicetest.py index 4dc604f3..821240b0 100644 --- a/tests/twisted/servicetest.py +++ b/tests/twisted/servicetest.py @@ -1,5 +1,5 @@ # Copyright (C) 2009 Nokia Corporation -# Copyright (C) 2009 Collabora Ltd. +# Copyright (C) 2009-2013 Collabora Ltd. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -17,30 +17,55 @@ # 02110-1301 USA """ -Infrastructure code for testing Mission Control +Infrastructure code for testing Telepathy services. """ from twisted.internet import glib2reactor from twisted.internet.protocol import Protocol, Factory, ClientFactory glib2reactor.install() import sys +import time +import os import pprint import unittest import dbus import dbus.lowlevel -import dbus.glib +from dbus.mainloop.glib import DBusGMainLoop +DBusGMainLoop(set_as_default=True) from twisted.internet import reactor -tp_name_prefix = 'org.freedesktop.Telepathy' -tp_path_prefix = '/org/freedesktop/Telepathy' +import constants as cs -class Event: +tp_name_prefix = cs.PREFIX +tp_path_prefix = cs.PATH_PREFIX + +class DictionarySupersetOf (object): + """Utility class for expecting "a dictionary with at least these keys".""" + def __init__(self, dictionary): + self._dictionary = dictionary + def __repr__(self): + return "DictionarySupersetOf(%s)" % self._dictionary + def __eq__(self, other): + """would like to just do: + return set(other.items()).issuperset(self._dictionary.items()) + but it turns out that this doesn't work if you have another dict + nested in the values of your dicts""" + try: + for k,v in self._dictionary.items(): + if k not in other or other[k] != v: + return False + return True + except TypeError: # other is not iterable + return False + +class Event(object): def __init__(self, type, **kw): self.__dict__.update(kw) self.type = type + (self.subqueue, self.subtype) = type.split ("-", 1) def __str__(self): return '\n'.join([ str(type(self)) ] + format_event(self)) @@ -48,7 +73,7 @@ class Event: def format_event(event): ret = ['- type %s' % event.type] - for key in dir(event): + for key in sorted(dir(event)): if key != 'type' and not key.startswith('_'): ret.append('- %s: %s' % ( key, pprint.pformat(getattr(event, key)))) @@ -61,16 +86,17 @@ def format_event(event): class EventPattern: def __init__(self, type, **properties): self.type = type - self.predicate = lambda x: True + self.predicate = None if 'predicate' in properties: self.predicate = properties['predicate'] del properties['predicate'] self.properties = properties + (self.subqueue, self.subtype) = type.split ("-", 1) def __repr__(self): properties = dict(self.properties) - if self.predicate: + if self.predicate is not None: properties['predicate'] = self.predicate return '%s(%r, **%r)' % ( @@ -87,7 +113,7 @@ class EventPattern: except AttributeError: return False - if self.predicate(event): + if self.predicate is None or self.predicate(event): return True return False @@ -112,8 +138,8 @@ class BaseEventQueue: def __init__(self, timeout=None): self.verbose = False - self.past_events = [] self.forbidden_events = set() + self.event_queues = {} if timeout is None: self.timeout = 5 @@ -124,28 +150,14 @@ class BaseEventQueue: if self.verbose: print s - def log_event(self, event): - if self.verbose: - self.log('got event:') - - if self.verbose: - map(self.log, format_event(event)) - - def flush_past_events(self): - self.past_events = [] + def log_queues(self, queues): + self.log ("Waiting for event on: %s" % ", ".join(queues)) - def expect_racy(self, type, **kw): - pattern = EventPattern(type, **kw) - - for event in self.past_events: - if pattern.match(event): - self.log('past event handled') - map(self.log, format_event(event)) - self.log('') - self.past_events.remove(event) - return event + def log_event(self, event): + self.log('got event:') - return self.expect(type, **kw) + if self.verbose: + map(self.log, format_event(event)) def forbid_events(self, patterns): """ @@ -163,34 +175,86 @@ class BaseEventQueue: """ self.forbidden_events.difference_update(set(patterns)) + def unforbid_all(self): + """ + Remove all patterns from the set of forbidden events. + """ + self.forbidden_events.clear() + def _check_forbidden(self, event): for e in self.forbidden_events: if e.match(event): raise ForbiddenEventOccurred(event) def expect(self, type, **kw): + """ + Waits for an event matching the supplied pattern to occur, and returns + it. For example, to await a D-Bus signal with particular arguments: + + e = q.expect('dbus-signal', signal='Badgers', args=["foo", 42]) + """ pattern = EventPattern(type, **kw) + t = time.time() while True: - event = self.wait() - self.log_event(event) + try: + event = self.wait([pattern.subqueue]) + except TimeoutError: + self.log('timeout') + self.log('still expecting:') + self.log(' - %r' % pattern) + raise + self._check_forbidden(event) if pattern.match(event): - self.log('handled') + self.log('handled, took %0.3f ms' + % ((time.time() - t) * 1000.0) ) self.log('') return event - self.past_events.append(event) self.log('not handled') self.log('') def expect_many(self, *patterns): + """ + Waits for events matching all of the supplied EventPattern instances to + return, and returns a list of events in the same order as the patterns + they matched. After a pattern is successfully matched, it is not + considered for future events; if more than one unsatisfied pattern + matches an event, the first "wins". + + Note that the expected events may occur in any order. If you're + expecting a series of events in a particular order, use repeated calls + to expect() instead. + + This method is useful when you're awaiting a number of events which may + happen in any order. For instance, in telepathy-gabble, calling a D-Bus + method often causes a value to be returned immediately, as well as a + query to be sent to the server. Since these events may reach the test + in either order, the following is incorrect and will fail if the IQ + happens to reach the test first: + + ret = q.expect('dbus-return', method='Foo') + query = q.expect('stream-iq', query_ns=ns.FOO) + + The following would be correct: + + ret, query = q.expect_many( + EventPattern('dbus-return', method='Foo'), + EventPattern('stream-iq', query_ns=ns.FOO), + ) + """ ret = [None] * len(patterns) + t = time.time() while None in ret: try: - event = self.wait() + queues = set() + for i, pattern in enumerate(patterns): + if ret[i] is None: + queues.add(pattern.subqueue) + event = self.wait(queues) except TimeoutError: self.log('timeout') self.log('still expecting:') @@ -198,17 +262,16 @@ class BaseEventQueue: if ret[i] is None: self.log(' - %r' % pattern) raise - self.log_event(event) self._check_forbidden(event) for i, pattern in enumerate(patterns): if ret[i] is None and pattern.match(event): - self.log('handled') + self.log('handled, took %0.3f ms' + % ((time.time() - t) * 1000.0) ) self.log('') ret[i] = event break else: - self.past_events.append(event) self.log('not handled') self.log('') @@ -217,8 +280,7 @@ class BaseEventQueue: def demand(self, type, **kw): pattern = EventPattern(type, **kw) - event = self.wait() - self.log_event(event) + event = self.wait([pattern.subqueue]) if pattern.match(event): self.log('handled') @@ -228,19 +290,39 @@ class BaseEventQueue: self.log('not handled') raise RuntimeError('expected %r, got %r' % (pattern, event)) + def queues_available(self, queues): + if queues == None: + return self.event_queues.keys() + else: + available = self.event_queues.keys() + return filter(lambda x: x in available, queues) + + + def pop_next(self, queue): + events = self.event_queues[queue] + e = events.pop(0) + if not events: + self.event_queues.pop (queue) + return e + + def append(self, event): + self.log ("Adding to queue") + self.log_event (event) + self.event_queues[event.subqueue] = \ + self.event_queues.get(event.subqueue, []) + [event] + class IteratingEventQueue(BaseEventQueue): """Event queue that works by iterating the Twisted reactor.""" def __init__(self, timeout=None): BaseEventQueue.__init__(self, timeout) - self.events = [] self._dbus_method_impls = [] self._buses = [] # a message filter which will claim we handled everything self._dbus_dev_null = \ lambda bus, message: dbus.lowlevel.HANDLER_RESULT_HANDLED - def wait(self): + def wait(self, queues=None): stop = [False] def later(): @@ -248,21 +330,21 @@ class IteratingEventQueue(BaseEventQueue): delayed_call = reactor.callLater(self.timeout, later) - while (not self.events) and (not stop[0]): - reactor.iterate(0.1) + self.log_queues(queues) + + qa = self.queues_available(queues) + while not qa and (not stop[0]): + reactor.iterate(0.01) + qa = self.queues_available(queues) - if self.events: + if qa: delayed_call.cancel() - return self.events.pop(0) + e = self.pop_next (qa[0]) + self.log_event (e) + return e else: raise TimeoutError - def append(self, event): - self.events.append(event) - - # compatibility - handle_event = append - def add_dbus_method_impl(self, cb, bus=None, **kwargs): if bus is None: bus = self._buses[0] @@ -387,50 +469,74 @@ class IteratingEventQueue(BaseEventQueue): class TestEventQueue(BaseEventQueue): def __init__(self, events): BaseEventQueue.__init__(self) - self.events = events + for e in events: + self.append (e) - def wait(self): - if self.events: - return self.events.pop(0) + def wait(self, queues = None): + qa = self.queues_available(queues) + + if qa: + return self.pop_next (qa[0]) else: raise TimeoutError class EventQueueTest(unittest.TestCase): def test_expect(self): - queue = TestEventQueue([Event('foo'), Event('bar')]) - assert queue.expect('foo').type == 'foo' - assert queue.expect('bar').type == 'bar' + queue = TestEventQueue([Event('test-foo'), Event('test-bar')]) + assert queue.expect('test-foo').type == 'test-foo' + assert queue.expect('test-bar').type == 'test-bar' def test_expect_many(self): - queue = TestEventQueue([Event('foo'), Event('bar')]) + queue = TestEventQueue([Event('test-foo'), + Event('test-bar')]) bar, foo = queue.expect_many( - EventPattern('bar'), - EventPattern('foo')) - assert bar.type == 'bar' - assert foo.type == 'foo' + EventPattern('test-bar'), + EventPattern('test-foo')) + assert bar.type == 'test-bar' + assert foo.type == 'test-foo' def test_expect_many2(self): # Test that events are only matched against patterns that haven't yet # been matched. This tests a regression. - queue = TestEventQueue([Event('foo', x=1), Event('foo', x=2)]) + queue = TestEventQueue([Event('test-foo', x=1), Event('test-foo', x=2)]) foo1, foo2 = queue.expect_many( - EventPattern('foo'), - EventPattern('foo')) - assert foo1.type == 'foo' and foo1.x == 1 - assert foo2.type == 'foo' and foo2.x == 2 + EventPattern('test-foo'), + EventPattern('test-foo')) + assert foo1.type == 'test-foo' and foo1.x == 1 + assert foo2.type == 'test-foo' and foo2.x == 2 + + def test_expect_queueing(self): + queue = TestEventQueue([Event('foo-test', x=1), + Event('foo-test', x=2)]) + + queue.append(Event('bar-test', x=1)) + queue.append(Event('bar-test', x=2)) + + queue.append(Event('baz-test', x=1)) + queue.append(Event('baz-test', x=2)) + + for x in xrange(1,2): + e = queue.expect ('baz-test') + assertEquals (x, e.x) + + e = queue.expect ('bar-test') + assertEquals (x, e.x) + + e = queue.expect ('foo-test') + assertEquals (x, e.x) def test_timeout(self): queue = TestEventQueue([]) - self.assertRaises(TimeoutError, queue.expect, 'foo') + self.assertRaises(TimeoutError, queue.expect, 'test-foo') def test_demand(self): - queue = TestEventQueue([Event('foo'), Event('bar')]) - foo = queue.demand('foo') - assert foo.type == 'foo' + queue = TestEventQueue([Event('test-foo'), Event('test-bar')]) + foo = queue.demand('test-foo') + assert foo.type == 'test-foo' def test_demand_fail(self): - queue = TestEventQueue([Event('foo'), Event('bar')]) - self.assertRaises(RuntimeError, queue.demand, 'bar') + queue = TestEventQueue([Event('test-foo'), Event('test-bar')]) + self.assertRaises(RuntimeError, queue.demand, 'test-bar') def unwrap(x): """Hack to unwrap D-Bus values, so that they're easier to read when @@ -459,11 +565,11 @@ def call_async(test, proxy, method, *args, **kw): resulting method return/error.""" def reply_func(*ret): - test.handle_event(Event('dbus-return', method=method, + test.append(Event('dbus-return', method=method, value=unwrap(ret))) def error_func(err): - test.handle_event(Event('dbus-error', method=method, error=err, + test.append(Event('dbus-error', method=method, error=err, name=err.get_dbus_name(), message=str(err))) method_proxy = getattr(proxy, method) @@ -481,7 +587,7 @@ def sync_dbus(bus, q, proxy): q.expect('dbus-error', method='DummySyncDBus') class ProxyWrapper: - def __init__(self, object, default, others): + def __init__(self, object, default, others={}): self.object = object self.default_interface = dbus.Interface(object, default) self.Properties = dbus.Interface(object, dbus.PROPERTIES_IFACE) @@ -500,6 +606,41 @@ class ProxyWrapper: return getattr(self.default_interface, name) +class ConnWrapper(ProxyWrapper): + def inspect_contact_sync(self, handle): + return self.inspect_contacts_sync([handle])[0] + + def inspect_contacts_sync(self, handles): + h2asv = self.Contacts.GetContactAttributes(handles, [], True) + ret = [] + for h in handles: + ret.append(h2asv[h][cs.ATTR_CONTACT_ID]) + return ret + + def get_contact_handle_sync(self, identifier): + return self.Contacts.GetContactByID(identifier, [])[0] + + def get_contact_handles_sync(self, ids): + return [self.get_contact_handle_sync(i) for i in ids] + +def wrap_connection(conn): + return ConnWrapper(conn, tp_name_prefix + '.Connection', + dict([ + (name, tp_name_prefix + '.Connection.Interface.' + name) + for name in ['Aliasing', 'Avatars', 'Capabilities', 'Contacts', + 'SimplePresence', 'Requests']] + + [('Peer', 'org.freedesktop.DBus.Peer'), + ('ContactCapabilities', cs.CONN_IFACE_CONTACT_CAPS), + ('ContactInfo', cs.CONN_IFACE_CONTACT_INFO), + ('Location', cs.CONN_IFACE_LOCATION), + ('Future', tp_name_prefix + '.Connection.FUTURE'), + ('MailNotification', cs.CONN_IFACE_MAIL_NOTIFICATION), + ('ContactList', cs.CONN_IFACE_CONTACT_LIST), + ('ContactGroups', cs.CONN_IFACE_CONTACT_GROUPS), + ('PowerSaving', cs.CONN_IFACE_POWER_SAVING), + ('Addressing', cs.CONN_IFACE_ADDRESSING), + ])) + def wrap_channel(chan, type_, extra=None): interfaces = { type_: tp_name_prefix + '.Channel.Type.' + type_, @@ -513,14 +654,26 @@ def wrap_channel(chan, type_, extra=None): return ProxyWrapper(chan, tp_name_prefix + '.Channel', interfaces) + +def wrap_content(chan, extra=None): + interfaces = { } + + if extra: + interfaces.update(dict([ + (name, tp_name_prefix + '.Call1.Content.Interface.' + name) + for name in extra])) + + return ProxyWrapper(chan, tp_name_prefix + '.Call1.Content', interfaces) + def make_connection(bus, event_func, name, proto, params): cm = bus.get_object( tp_name_prefix + '.ConnectionManager.%s' % name, - tp_path_prefix + '/ConnectionManager/%s' % name) + tp_path_prefix + '/ConnectionManager/%s' % name, + introspect=False) cm_iface = dbus.Interface(cm, tp_name_prefix + '.ConnectionManager') connection_name, connection_path = cm_iface.RequestConnection( - proto, params) + proto, dbus.Dictionary(params, signature='sv')) conn = wrap_connection(bus.get_object(connection_name, connection_path)) return conn @@ -540,7 +693,7 @@ class EventProtocol(Protocol): def dataReceived(self, data): if self.queue is not None: - self.queue.handle_event(Event('socket-data', protocol=self, + self.queue.append(Event('socket-data', protocol=self, data=data)) def sendData(self, data): @@ -552,7 +705,7 @@ class EventProtocol(Protocol): def connectionLost(self, reason=None): if self.queue is not None: - self.queue.handle_event(Event('socket-disconnected', protocol=self)) + self.queue.append(Event('socket-disconnected', protocol=self)) class EventProtocolFactory(Factory): def __init__(self, queue, block_reading=False): @@ -564,7 +717,7 @@ class EventProtocolFactory(Factory): def buildProtocol(self, addr): proto = self._create_protocol() - self.queue.handle_event(Event('socket-connected', protocol=proto)) + self.queue.append(Event('socket-connected', protocol=proto)) return proto class EventProtocolClientFactory(EventProtocolFactory, ClientFactory): @@ -572,7 +725,7 @@ class EventProtocolClientFactory(EventProtocolFactory, ClientFactory): def watch_tube_signals(q, tube): def got_signal_cb(*args, **kwargs): - q.handle_event(Event('tube-signal', + q.append(Event('tube-signal', path=kwargs['path'], signal=kwargs['member'], args=map(unwrap, args), @@ -590,6 +743,15 @@ def assertEquals(expected, value): raise AssertionError( "expected:\n%s\ngot:\n%s" % (pretty(expected), pretty(value))) +def assertSameSets(expected, value): + exp_set = set(expected) + val_set = set(value) + + if exp_set != val_set: + raise AssertionError( + "expected contents:\n%s\ngot:\n%s" % ( + pretty(exp_set), pretty(val_set))) + def assertNotEquals(expected, value): if expected == value: raise AssertionError( @@ -624,15 +786,11 @@ def assertFlagsUnset(flags, value): "expected none of flags %u, but %u are set in %u" % ( flags, masked, value)) -def assertSameSets(expected, value): - exp_set = set(expected) - val_set = set(value) - - if exp_set != val_set: +def assertDBusError(name, error): + if error.get_dbus_name() != name: raise AssertionError( - "expected contents:\n%s\ngot:\n%s" % ( - pretty(exp_set), pretty(val_set))) - + "expected DBus error named:\n %s\ngot:\n %s\n(with message: %s)" + % (name, error.get_dbus_name(), error.message)) def install_colourer(): def red(s): @@ -652,14 +810,26 @@ def install_colourer(): self.patterns = patterns def write(self, s): - f = self.patterns.get(s, lambda x: x) - self.fh.write(f(s)) + for p, f in self.patterns.items(): + if s.startswith(p): + self.fh.write(f(p) + s[len(p):]) + return + + self.fh.write(s) sys.stdout = Colourer(sys.stdout, patterns) return sys.stdout +# this is just to shut up unittest. +class DummyStream(object): + def write(self, s): + if 'CHECK_TWISTED_VERBOSE' in os.environ: + print s, + def flush(self): + pass if __name__ == '__main__': - unittest.main() - + stream = DummyStream() + runner = unittest.TextTestRunner(stream=stream) + unittest.main(testRunner=runner) diff --git a/tests/twisted/tools/Makefile.am b/tests/twisted/tools/Makefile.am index ffe04eff..9eb17c79 100644 --- a/tests/twisted/tools/Makefile.am +++ b/tests/twisted/tools/Makefile.am @@ -27,25 +27,25 @@ run-mc.sh: run-mc.sh.in Makefile @chmod +x $@ servicedir-uninstalled/%.conf: servicedir-uninstalled/%.conf.in Makefile - $(AM_V_at)$(mkdir_p) servicedir-uninstalled + $(AM_V_at)$(MKDIR_P) servicedir-uninstalled $(AM_V_GEN)sed -e "s|[@]abs_top_builddir[@]|@abs_top_builddir@|g" $< > $@ servicedir-installed/%.conf: servicedir-installed/%.conf.in Makefile - $(AM_V_at)$(mkdir_p) servicedir-installed + $(AM_V_at)$(MKDIR_P) servicedir-installed $(AM_V_GEN)sed -e "s|[@]mctestsdir[@]|@mctestsdir@|g" $< > $@ # We don't use the full filename for the .in because > 99 character filenames # in tarballs are non-portable (and automake 1.8 doesn't let us build # non-archaic tarballs) servicedir-uninstalled/org.freedesktop.Telepathy.%.service: servicedir-uninstalled/%.service.in Makefile - $(AM_V_at)$(mkdir_p) servicedir-uninstalled + $(AM_V_at)$(MKDIR_P) servicedir-uninstalled $(AM_V_GEN)sed \ -e "s|[@]abs_top_srcdir[@]|@abs_top_srcdir@|g" \ -e "s|[@]abs_top_builddir[@]|@abs_top_builddir@|g" \ $< > $@ servicedir-installed/org.freedesktop.Telepathy.%.service: servicedir-installed/%.service.in Makefile - $(AM_V_at)$(mkdir_p) servicedir-installed + $(AM_V_at)$(MKDIR_P) servicedir-installed $(AM_V_GEN)sed \ -e "s|[@]mctestsdir[@]|@mctestsdir@|g" \ $< > $@ |