summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/twisted/Makefile.am9
-rw-r--r--tests/twisted/account-manager/auto-connect.py9
-rw-r--r--tests/twisted/account-manager/avatar-refresh.py22
-rw-r--r--tests/twisted/account-manager/bad-cm.py11
-rw-r--r--tests/twisted/account-storage/5-12.py29
-rw-r--r--tests/twisted/account-storage/5-14.py29
-rw-r--r--tests/twisted/account-storage/create-new.py136
-rw-r--r--tests/twisted/account-storage/default-keyring-storage.py317
-rw-r--r--tests/twisted/account-storage/load-keyfiles.py274
-rw-r--r--tests/twisted/account-storage/storage_helper.py174
-rw-r--r--tests/twisted/dbus-account-plugin.c521
-rw-r--r--tests/twisted/mc-debug-server.c30
-rw-r--r--tests/twisted/mcp-account-diversion.c259
-rw-r--r--tests/twisted/mctest.py38
14 files changed, 1106 insertions, 752 deletions
diff --git a/tests/twisted/Makefile.am b/tests/twisted/Makefile.am
index 587d6b0c..2a96647f 100644
--- a/tests/twisted/Makefile.am
+++ b/tests/twisted/Makefile.am
@@ -74,8 +74,12 @@ TWISTED_BASIC_TESTS = \
# account-storage/*.py need their own instances.
TWISTED_SPECIAL_BUILD_TESTS = \
account-manager/connectivity.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 = \
@@ -105,6 +109,7 @@ TWISTED_OTHER_FILES = \
fakeconnectivity.py \
mctest.py \
servicetest.py \
+ account-storage/storage_helper.py \
telepathy/clients/README \
telepathy/clients/AbiWord.client \
telepathy/clients/Logger.client \
diff --git a/tests/twisted/account-manager/auto-connect.py b/tests/twisted/account-manager/auto-connect.py
index 46b13364..28cfb2ab 100644
--- a/tests/twisted/account-manager/auto-connect.py
+++ b/tests/twisted/account-manager/auto-connect.py
@@ -21,6 +21,7 @@ import dbus
"""
import os
+import os.path
import dbus
import dbus.service
@@ -65,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()
diff --git a/tests/twisted/account-manager/avatar-refresh.py b/tests/twisted/account-manager/avatar-refresh.py
index f76d7fb6..d914c439 100644
--- a/tests/twisted/account-manager/avatar-refresh.py
+++ b/tests/twisted/account-manager/avatar-refresh.py
@@ -90,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'
@@ -258,18 +249,7 @@ class Account(object):
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'] + '/' +
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-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 27b45e51..00000000
--- a/tests/twisted/account-storage/default-keyring-storage.py
+++ /dev/null
@@ -1,317 +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, assertContains, assertDoesNotContain
-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')
- 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')
- 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",
- "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'))
-
- tell_mc_to_die(q, bus)
-
- # .. let's check the keyfile
- assert not os.path.exists(old_key_file_name)
- assert not os.path.exists(newer_key_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'))
-
- # 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)
-
- 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)
-
- # Tell MC to die, again
- tell_mc_to_die(q, bus)
-
- low_prio_variant_file_name = os.path.join(
- os.environ['XDG_DATA_DIRS'].split(':')[0],
- 'telepathy', 'mission-control',
- 'fakecm-fakeprotocol-dontdivert_40example_2ecom0.account')
- os.makedirs(os.path.dirname(low_prio_variant_file_name), 0700)
-
- # This is deliberately a lower-priority location
- open(low_prio_variant_file_name, 'w').write(
-"""{
-'manager': <'fakecm'>,
-'protocol': <'fakeprotocol'>,
-'DisplayName': <'New and improved account'>,
-'AutomaticPresence': <(uint32 2, 'available', '')>,
-'KeyFileParameters': <{
- 'account': 'dontdivert@example.com',
- 'password': 'password_in_variant_file',
- 'snakes': '42'
- }>
-}
-""")
-
- # This version of this account will be used
- open(new_variant_file_name.replace('.account', 'priority.account'),
- 'w').write("""{
-'manager': <'fakecm'>,
-'protocol': <'fakeprotocol'>,
-'DisplayName': <'Visible'>,
-'AutomaticPresence': <(uint32 2, 'available', '')>,
-'KeyFileParameters': <{'account': 'dontdivert@example.com',
- 'password': 'password_in_variant_file'}>
-}
-""")
- # This one won't, because it's "masked" by the higher-priority one
- open(low_prio_variant_file_name.replace('.account', 'priority.account'),
- 'w').write("""{
-'manager': <'fakecm'>,
-'protocol': <'fakeprotocol'>,
-'DisplayName': <'Hidden'>,
-'Nickname': <'Hidden'>,
-'AutomaticPresence': <(uint32 2, 'available', '')>,
-'KeyFileParameters': <{'account': 'dontdivert@example.com',
- 'password': 'password_in_variant_file'}>
-}
-""")
-
- # This empty file is considered to "mask" the lower-priority one
- open(new_variant_file_name.replace('.account', 'masked.account'),
- 'w').write('')
- open(low_prio_variant_file_name.replace('.account', 'masked.account'),
- 'w').write("""{
-'manager': <'fakecm'>,
-'protocol': <'fakeprotocol'>,
-'AutomaticPresence': <(uint32 2, 'available', '')>,
-'KeyFileParameters': <{'account': 'dontdivert@example.com',
- 'password': 'password_in_variant_file'}>
-}
-""")
-
- account_manager, properties, interfaces = resuscitate_mc(q, bus, mc)
- assertContains(account_path, properties['ValidAccounts'])
- account = get_fakecm_account(bus, mc, account_path)
- account_iface = dbus.Interface(account, cs.ACCOUNT)
-
- assertEquals(42,
- account.Properties.Get(cs.ACCOUNT, 'Parameters')['snakes'])
- assertEquals(dbus.UInt32,
- type(account.Properties.Get(cs.ACCOUNT, 'Parameters')['snakes']))
-
- # Files in lower-priority XDG locations aren't copied until something
- # actually changes, and they aren't deleted.
- assert not os.path.exists(new_variant_file_name)
- assert os.path.exists(low_prio_variant_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]),
- )
-
- # test that "masking" works
- assertDoesNotContain(account_path + "masked", properties['ValidAccounts'])
- assertDoesNotContain(account_path + "masked",
- properties['InvalidAccounts'])
-
- # test that priority works
- assertContains(account_path + "priority", properties['ValidAccounts'])
- priority_account = get_fakecm_account(bus, mc, account_path + "priority")
- assertEquals('', priority_account.Properties.Get(cs.ACCOUNT, 'Nickname'))
- assertEquals('Visible',
- priority_account.Properties.Get(cs.ACCOUNT, 'DisplayName'))
-
- # test what happens when we delete an account that has a lower-priority
- # "other self"
- assert priority_account.Remove() is None
-
- # 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 not os.path.exists(newer_key_file_name)
- assert os.path.exists(low_prio_variant_file_name)
- assert os.path.exists(new_variant_file_name)
- assert open(new_variant_file_name.replace('.account', 'masked.account'),
- 'r').read() == ''
- assert open(new_variant_file_name.replace('.account', 'priority.account'),
- 'r').read() == ''
-
- pwd = account_store('get', 'variant-file', 'param-password')
- assertEquals(None, pwd)
-
- # Write out an account configuration in the old keyfile, to test
- # migration from there
- os.remove(new_variant_file_name)
- os.remove(new_variant_file_name.replace('.account', 'masked.account'))
- os.remove(new_variant_file_name.replace('.account', 'priority.account'))
- os.remove(low_prio_variant_file_name)
- os.remove(low_prio_variant_file_name.replace('.account', 'masked.account'))
- os.remove(low_prio_variant_file_name.replace('.account', 'priority.account'))
- 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 deleted automatically during MC startup,
- # after copying its contents to the new name/format
- assert not os.path.exists(old_key_file_name)
- assert not os.path.exists(low_prio_variant_file_name)
- assertEquals("'Ye olde account'",
- account_store('get', 'variant-file', '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/load-keyfiles.py b/tests/twisted/account-storage/load-keyfiles.py
new file mode 100644
index 00000000..dfba53b4
--- /dev/null
+++ b/tests/twisted/account-storage/load-keyfiles.py
@@ -0,0 +1,274 @@
+# 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() == ''
+
+ # Teach the one that knows its CM that the 'password' is a string.
+ # This results in the higher-priority file being written out.
+ 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]),
+ )
+ # Check the account has copied (not moved! XDG_DATA_DIRS are,
+ # conceptually, read-only) 'migration' 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['migration'])
+ assert os.path.exists(variant_file_names['migration'])
+ assertEquals("'hello'", account_store('get', 'variant-file',
+ 'param-password', account=tails['migration']))
+ # Parameters whose types are still unknown are copied too, but their
+ # types are still unknown
+ assertEquals("keyfile-escaped '42'", account_store('get', 'variant-file',
+ 'param-snakes', account=tails['migration']))
+
+ # 'absentcm' is still only in the low-priority location: we can't
+ # known the types of its parameters
+ 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..ebbe78e6
--- /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))
+ # MC doesn't currently ensure that parameters are stored with their
+ # proper types.
+ assertEquals("keyfile-escaped 'dontdivert1@example.com'",
+ account_store('get', 'variant-file', 'param-account',
+ account=a1_tail))
+ assertEquals("keyfile-escaped '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/dbus-account-plugin.c b/tests/twisted/dbus-account-plugin.c
index a8a2e4df..446a2ad7 100644
--- a/tests/twisted/dbus-account-plugin.c
+++ b/tests/twisted/dbus-account-plugin.c
@@ -27,6 +27,8 @@
#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.Test."
#define TESTSLASH "/org/freedesktop/Telepathy/Test/"
@@ -54,7 +56,7 @@ 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;
@@ -183,7 +185,6 @@ ensure_account (TestDBusAccountPlugin *self,
g_hash_table_insert (self->accounts, g_strdup (account_name), account);
}
- account->flags &= ~UNCOMMITTED_DELETION;
return account;
}
@@ -211,18 +212,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);
}
@@ -376,7 +373,7 @@ test_dbus_account_plugin_process_account_deletion (TestDBusAccountPlugin *self,
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
@@ -414,7 +411,7 @@ test_dbus_account_plugin_process_attributes (TestDBusAccountPlugin *self,
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
@@ -448,8 +445,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);
@@ -473,8 +468,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);
@@ -525,7 +518,7 @@ test_dbus_account_plugin_process_parameters (TestDBusAccountPlugin *self,
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
@@ -557,8 +550,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);
@@ -586,11 +577,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);
@@ -620,8 +610,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);
@@ -760,8 +748,8 @@ parameters_changed_cb (GDBusConnection *bus,
}
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;
@@ -870,8 +858,8 @@ test_dbus_account_plugin_list (const McpAccountStorage *storage,
}
static void
-test_dbus_account_plugin_ready (const McpAccountStorage *storage,
- const McpAccountManager *am)
+test_dbus_account_plugin_ready (McpAccountStorage *storage,
+ McpAccountManager *am)
{
TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage);
@@ -885,8 +873,8 @@ test_dbus_account_plugin_ready (const McpAccountStorage *storage,
}
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,
const gchar *identifier,
@@ -908,218 +896,139 @@ 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);
-
- account->flags &= ~UNCOMMITTED_CREATION;
- g_hash_table_remove_all (account->uncommitted_attributes);
- g_hash_table_remove_all (account->uncommitted_parameters);
+ g_task_set_task_data (task, g_strdup (user_data), g_free);
- 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);
-
- mcp_account_manager_set_value (am, account_name, k, escaped);
- g_free (escaped);
- }
-
- g_hash_table_iter_init (&iter, account->untyped_parameters);
-
- 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);
+ if (flags != NULL)
+ *flags = 0;
- flags = GPOINTER_TO_UINT (g_hash_table_lookup (
- account->parameter_flags, k));
+ g_return_val_if_fail (self->active, NULL);
+ g_return_val_if_fail (account != NULL, NULL);
- if (flags & MCP_PARAMETER_FLAG_SECRET)
- mcp_account_manager_parameter_make_secret (am, account_name,
- param_foo);
+ v = g_hash_table_lookup (account->attributes, attribute);
- g_free (param_foo);
- }
+ 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);
- g_hash_table_iter_init (&iter, account->parameters);
+ if (v != NULL)
+ {
+ return g_variant_ref (v);
+ }
+ else
+ {
+ return 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);
+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;
- param_foo = g_strdup_printf ("param-%s", (const gchar *) k);
- mcp_account_manager_set_value (am, account_name, param_foo, escaped);
- g_free (escaped);
+ if (flags != NULL)
+ *flags = 0;
- flags = GPOINTER_TO_UINT (g_hash_table_lookup (account->parameter_flags,
- k));
+ g_return_val_if_fail (self->active, NULL);
+ g_return_val_if_fail (account != NULL, NULL);
- if (flags & MCP_PARAMETER_FLAG_SECRET)
- mcp_account_manager_parameter_make_secret (am, account_name,
- param_foo);
+ 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);
- g_free (param_foo);
- }
+ v = g_hash_table_lookup (account->parameters, parameter);
+ s = g_hash_table_lookup (account->untyped_parameters, parameter);
- return TRUE;
+ if (v != NULL)
+ {
+ return g_variant_ref (v);
}
-
- /* get one parameter */
-
- if (g_str_has_prefix (key, "param-"))
+ else if (s != NULL)
{
- 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));
-
- 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);
-
- if (flags & MCP_PARAMETER_FLAG_SECRET)
- mcp_account_manager_parameter_make_secret (am, account_name, key);
-
- if (v != NULL)
- {
- gchar *escaped = mcp_account_manager_escape_variant_for_keyfile (am,
- v);
-
- 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;
- }
+ return mcp_account_manager_unescape_variant_from_keyfile (am,
+ s, type, NULL);
}
else
{
- GVariant *v = g_hash_table_lookup (account->attributes, key);
-
- 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);
-
- if (v != NULL)
- {
- gchar *escaped = mcp_account_manager_escape_variant_for_keyfile (am,
- v);
-
- mcp_account_manager_set_value (am, account_name, key, escaped);
- g_free (escaped);
- }
- else
- {
- return FALSE;
- }
+ return NULL;
}
-
- return TRUE;
-}
-
-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;
}
-static gboolean
+static McpAccountStorageSetResult
test_dbus_account_plugin_set_attribute (McpAccountStorage *storage,
McpAccountManager *am,
const gchar *account_name,
@@ -1129,17 +1038,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));
@@ -1153,10 +1085,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,
@@ -1166,17 +1098,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),
@@ -1191,37 +1148,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
@@ -1229,27 +1156,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
@@ -1355,12 +1286,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;
@@ -1370,36 +1301,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,
@@ -1526,7 +1436,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)
{
@@ -1535,8 +1445,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. */
@@ -1545,7 +1455,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);
@@ -1554,8 +1464,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);
@@ -1566,7 +1476,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);
@@ -1574,28 +1484,12 @@ 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);
return account->restrictions;
}
-static gboolean
-test_dbus_account_plugin_owns (McpAccountStorage *storage,
- McpAccountManager *am,
- const gchar *account_name)
-{
- 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;
-}
-
static void
account_storage_iface_init (McpAccountStorageIface *iface)
{
@@ -1604,18 +1498,17 @@ 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_attribute = test_dbus_account_plugin_get_attribute;
+ iface->get_parameter = test_dbus_account_plugin_get_parameter;
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/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 923f51b4..466d3ee3 100644
--- a/tests/twisted/mcp-account-diversion.c
+++ b/tests/twisted/mcp-account-diversion.c
@@ -111,109 +111,201 @@ _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);
+ old = g_key_file_get_value (adp->keyfile, account, key, NULL);
- if (v != NULL)
- mcp_account_manager_set_value (am, account, keys[i], v);
-
- 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 *key)
+ 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 *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 (key == NULL)
- {
- if (g_key_file_remove_group (adp->keyfile, account, NULL))
- adp->save = TRUE;
- }
- else
- {
- gsize n;
- GStrv keys;
+ if (flags != NULL)
+ *flags = 0;
- if (g_key_file_remove_key (adp->keyfile, account, key, NULL))
- adp->save = TRUE;
+ v = g_key_file_get_value (adp->keyfile, account, attribute, NULL);
- keys = g_key_file_get_keys (adp->keyfile, account, &n, NULL);
+ if (v == NULL)
+ return NULL;
- if (keys == NULL || n == 0)
- g_key_file_remove_group (adp->keyfile, account, NULL);
+ ret = mcp_account_manager_unescape_variant_from_keyfile (am, v, type, NULL);
+ g_free (v);
+ return ret;
+}
- g_strfreev (keys);
+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;
+
+ 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 gboolean _commit (McpAccountStorage *self,
+ McpAccountManager *am,
+ const gchar *account_name);
+
+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);
+
+ 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;
@@ -229,8 +321,8 @@ _commit (const McpAccountStorage *self,
}
static GList *
-_list (const McpAccountStorage *self,
- const McpAccountManager *am)
+_list (McpAccountStorage *self,
+ McpAccountManager *am)
{
gsize i;
gsize n;
@@ -255,6 +347,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)
@@ -263,11 +384,15 @@ 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->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/mctest.py b/tests/twisted/mctest.py
index 35ccec97..2229525b 100644
--- a/tests/twisted/mctest.py
+++ b/tests/twisted/mctest.py
@@ -1018,12 +1018,11 @@ class SimulatedConnectionManager(object):
for protocol_name in protocol_names:
assert '-' not in protocol_name
- q.add_dbus_method_impl(self.IdentifyAccount,
- path=self.object_path + '/' + protocol_name,
- interface=cs.PROTOCOL, method='IdentifyAccount')
- q.add_dbus_method_impl(self.NormalizeContact,
- path=self.object_path + '/' + protocol_name,
- interface=cs.PROTOCOL, method='NormalizeContact')
+
+ 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
@@ -1132,11 +1131,32 @@ class SimulatedConnectionManager(object):
}, 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()
- else:
- ret = 'account'
- self.q.dbus_return(e.message, ret, signature='s')
+ 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')