From 0df9e7725cd071b10a7148d0ea034230d7cf346f Mon Sep 17 00:00:00 2001 From: "Marco Trevisan (TreviƱo)" Date: Wed, 24 Mar 2021 20:25:55 +0100 Subject: tests: Sync tests with upstream python-dbusmock --- tests/dbusmock/accounts_service.py | 68 ++++++++++++++++------------------ tests/test-libaccountsservice.py | 76 +++++++++++++++++++++++++++++++++----- 2 files changed, 98 insertions(+), 46 deletions(-) diff --git a/tests/dbusmock/accounts_service.py b/tests/dbusmock/accounts_service.py index 0bb41b2..81692b2 100644 --- a/tests/dbusmock/accounts_service.py +++ b/tests/dbusmock/accounts_service.py @@ -11,8 +11,10 @@ __email__ = 'marco.trevisan@canonical.com' __copyright__ = '(c) 2021 Canonical Ltd.' __license__ = 'LGPL 3+' -import dbus +import sys +import time +import dbus from dbusmock import MOCK_IFACE, mockobject BUS_NAME = 'org.freedesktop.Accounts' @@ -21,6 +23,8 @@ MAIN_IFACE = 'org.freedesktop.Accounts' USER_IFACE = MAIN_IFACE + '.User' SYSTEM_BUS = True +DEFAULT_USER_PASSWORD = 'Pa$$wo0rd' + def get_user_path(uid): return '/org/freedesktop/Accounts/User{}'.format(uid) @@ -30,7 +34,7 @@ def load(mock, parameters=None): parameters = parameters if parameters else {} mock.mock_users = {} mock.cached_users = [] - mock.automatic_login_users = [] + mock.automatic_login_users = set() mock.users_auto_uids = 2000 mock.AddProperties(MAIN_IFACE, mock.GetAll(MAIN_IFACE)) @@ -47,15 +51,17 @@ def emit_properties_changed(mock, interface=MAIN_IFACE, properties=None): if isinstance(properties, (list, set)): properties = {p: mock.Get(interface, p) for p in properties} - elif isinstance(properties, dict): - pass + elif not isinstance(properties, dict): + raise TypeError('Unsupported properties type') mock.EmitSignal(dbus.PROPERTIES_IFACE, 'PropertiesChanged', 'sa{sv}as', ( interface, properties, [])) -@dbus.service.method(MOCK_IFACE, in_signature='xsa{sv}', out_signature='o') -def AddUser(self, uid, username, overrides=None): +@dbus.service.method(MOCK_IFACE, in_signature='xssa{sv}a{sv}', + out_signature='o') +def AddUser(self, uid, username, password=DEFAULT_USER_PASSWORD, + overrides=None, password_policy_overrides=None): '''Add user via uid and username and optionally overriding properties Returns the new object path. @@ -70,7 +76,7 @@ def AddUser(self, uid, username, overrides=None): 'BackgroundFile': '', 'Email': '{}@python-dbusmock.org'.format(username), 'FormatsLocale': 'C', - 'HomeDirectory': '/tmp/dbusmock-home/{}'.format(username), + 'HomeDirectory': '/nonexisting/mock-home/{}'.format(username), 'IconFile': '', 'InputSources': dbus.Array([], signature='a{ss}'), 'Language': 'C', @@ -84,47 +90,30 @@ def AddUser(self, uid, username, overrides=None): 'PasswordMode': 0, 'Session': 'mock-session', 'SessionType': 'wayland', - 'Shell': '/bin/zsh', + 'Shell': '/usr/bin/zsh', 'SystemAccount': False, 'XHasMessages': False, 'XKeyboardLayouts': dbus.Array([], signature='s'), 'XSession': 'mock-xsession', } default_props.update(overrides if overrides else {}) - self.AddObject(path, USER_IFACE, default_props, [ - ('SetRealName', 's', '', SetRealName), - ('SetEmail', 's', '', SetEmail), - ('SetLanguage', 's', '', SetLanguage), - ('SetXSession', 's', '', SetXSession), - ('SetSession', 's', '', SetSession), - ('SetSessionType', 's', '', SetSessionType), - ('SetLocation', 's', '', SetLocation), - ('SetHomeDirectory', 's', '', SetHomeDirectory), - ('SetShell', 's', '', SetShell), - ('SetIconFile', 's', '', SetIconFile), - ('SetLocked', 'b', '', SetLocked), - ('SetAccountType', 'i', '', SetAccountType), - ('SetPasswordMode', 'i', '', SetPasswordMode), - ('SetPasswordHint', 's', '', SetPasswordHint), - ('SetPassword', 'ss', '', SetPassword), - ('SetAutomaticLogin', 'b', '', SetAutomaticLogin), - ('GetPasswordExpirationPolicy', '', - 'xxxxxx', GetPasswordExpirationPolicy), - ]) + self.AddObject(path, USER_IFACE, default_props, []) had_users = len(self.mock_users) != 0 had_multiple_users = len(self.mock_users) > 1 user = mockobject.objects[path] - user.password = 'Pa$$wo0rd' + user.password = password user.properties = default_props user.pwd_expiration_policy = { - 'expiration_time': 1000, - 'last_change_time': 1615832413, + 'expiration_time': sys.maxsize, + 'last_change_time': int(time.time()), 'min_days_between_changes': 0, 'max_days_between_changes': 0, 'days_to_warn': 0, 'days_after_expiration_until_lock': 0, } + user.pwd_expiration_policy.update( + password_policy_overrides if password_policy_overrides else {}) self.mock_users[uid] = default_props self.EmitSignal(MAIN_IFACE, 'UserAdded', 'o', [path]) @@ -147,8 +136,9 @@ def ListMockUsers(self): def AddAutoLoginUser(self, username): """ Enable autologin for an user """ path = self.FindUserByName(username) - self.automatic_login_users.append(path) - mockobject.objects[path].SetAutomaticLogin(True) + self.automatic_login_users.add(path) + user = mockobject.objects[path] + set_user_property(user, 'AutomaticLogin', True) emit_properties_changed(self, MAIN_IFACE, 'AutomaticLoginUsers') return path @@ -158,7 +148,8 @@ def RemoveAutoLoginUser(self, username): """ Disables autologin for an user """ path = self.FindUserByName(username) self.automatic_login_users.remove(path) - mockobject.objects[path].SetAutomaticLogin(False) + user = mockobject.objects[path] + set_user_property(user, 'AutomaticLogin', False) emit_properties_changed(self, MAIN_IFACE, 'AutomaticLoginUsers') return path @@ -179,7 +170,7 @@ def CreateUser(self, name, fullname, account_type): self.users_auto_uids += 1 - return self.AddUser(self.users_auto_uids, name, { + return self.AddUser(self.users_auto_uids, name, DEFAULT_USER_PASSWORD, { 'RealName': fullname, 'AccountType': account_type}) @@ -191,6 +182,7 @@ def DeleteUser(self, uid, _remove_files): had_multiple_users = len(self.mock_users) > 1 self.RemoveObject(path) self.mock_users.pop(uid) + self.automatic_login_users.discard(path) self.EmitSignal(MAIN_IFACE, 'UserDeleted', 'o', [path]) @@ -367,7 +359,11 @@ def SetPassword(self, password, hint): @dbus.service.method(USER_IFACE, in_signature='b') def SetAutomaticLogin(self, automatic_login): - set_user_property(self, 'AutomaticLogin', automatic_login) + manager = mockobject.objects[MAIN_OBJ] + if automatic_login: + manager.AddAutoLoginUser(self.properties['UserName']) + else: + manager.RemoveAutoLoginUser(self.properties['UserName']) @dbus.service.method(MOCK_IFACE, in_signature='xxxxxxx') diff --git a/tests/test-libaccountsservice.py b/tests/test-libaccountsservice.py index 9e0a11a..4bfd5ee 100644 --- a/tests/test-libaccountsservice.py +++ b/tests/test-libaccountsservice.py @@ -11,8 +11,10 @@ __copyright__ = '(c) 2021 Canonical Ltd.' import os import subprocess import sys +import time import unittest +import dbus import dbusmock try: @@ -45,8 +47,12 @@ class TestAccountsService(dbusmock.DBusTestCase): self._manager = AccountsService.UserManager.get_default() while not self._manager.props.is_loaded: self.ctx.iteration(True) - self.assertFalse(self._manager.no_service()) self.assertTrue(self._manager.props.is_loaded) + self.assertFalse(self._manager.no_service()) + + def get_property(self, name): + return self._mock_obj.Get('org.freedesktop.Accounts', name, + dbus_interface=dbus.PROPERTIES_IFACE) def tearDown(self): for user in self._manager.list_users(): @@ -82,12 +88,18 @@ class TestAccountsService(dbusmock.DBusTestCase): self.assertTrue(self._manager.props.is_loaded) self.assertFalse(self._manager.list_users()) self.assertFalse(self._manager.props.has_multiple_users) + self.assertFalse(self._mock_obj.ListMockUsers()) + self.assertTrue(self.get_property('HasNoUsers')) + self.assertFalse(self.get_property('HasMultipleUsers')) + self.assertFalse(self.get_property('AutomaticLoginUsers')) + self.assertEqual(self.get_property('DaemonVersion'), 'dbus-mock-0.1') def test_create_user(self): self._manager.create_user( 'pizza', 'I Love Pizza', AccountsService.UserAccountType.ADMINISTRATOR) self.assertFalse(self._manager.props.has_multiple_users) + self.assertFalse(self.get_property('HasNoUsers')) [user] = self._manager.list_users() self.assertEqual(user.get_account_type(), AccountsService.UserAccountType.ADMINISTRATOR) @@ -105,6 +117,7 @@ class TestAccountsService(dbusmock.DBusTestCase): self.assertTrue(error.exception.matches( AccountsService.UserManagerError.quark(), AccountsService.UserManagerError.FAILED)) + self.assertFalse(self._manager.props.has_multiple_users) def test_delete_non_existent_user(self): user = self._manager.create_user('not-here-sorry', 'I am leaving...', @@ -164,6 +177,7 @@ class TestAccountsService(dbusmock.DBusTestCase): 'pizza', 'I Love Pizza!', AccountsService.UserAccountType.ADMINISTRATOR) self.assertFalse(self._manager.props.has_multiple_users) + self.assertFalse(self.get_property('HasNoUsers')) [user] = self._manager.list_users() self.assertEqual(self._manager.get_user('pizza'), user) self.assertEqual(self._manager.get_user_by_id(2001), user) @@ -181,6 +195,7 @@ class TestAccountsService(dbusmock.DBusTestCase): while not self._manager.props.has_multiple_users: self.ctx.iteration(True) + self.assertFalse(self.get_property('HasNoUsers')) self.assertTrue(self._manager.props.has_multiple_users) self.assertIn(other, self._manager.list_users()) self.assertEqual(self._manager.get_user('schiacciata'), other) @@ -195,13 +210,14 @@ class TestAccountsService(dbusmock.DBusTestCase): user = self._manager.create_user( 'pizza', 'I Love Pizza', AccountsService.UserAccountType.ADMINISTRATOR) + creation_time = int(time.time()) self.assertEqual(user.get_account_type(), AccountsService.UserAccountType.ADMINISTRATOR) self.assertFalse(self._manager.props.has_multiple_users) self.assertFalse(user.get_automatic_login()) self.assertEqual(user.get_email(), 'pizza@python-dbusmock.org') - self.assertEqual(user.get_home_dir(), '/tmp/dbusmock-home/pizza') + self.assertEqual(user.get_home_dir(), '/nonexisting/mock-home/pizza') self.assertEqual(user.get_icon_file(), '') self.assertEqual(user.get_language(), 'C') self.assertEqual(user.get_location(), '') @@ -214,7 +230,7 @@ class TestAccountsService(dbusmock.DBusTestCase): self.assertEqual(user.get_object_path(), '/org/freedesktop/Accounts/User2001') self.assertEqual(user.get_password_expiration_policy(), - (1000, 1615832413, 0, 0, 0, 0)) + (sys.maxsize, creation_time, 0, 0, 0, 0)) self.assertEqual(user.get_password_hint(), 'Remember it, come on!') self.assertEqual(user.get_password_mode(), AccountsService.UserPasswordMode.REGULAR) @@ -223,7 +239,7 @@ class TestAccountsService(dbusmock.DBusTestCase): self.assertFalse(user.get_saved()) self.assertEqual(user.get_session(), 'mock-session') self.assertEqual(user.get_session_type(), 'wayland') - self.assertEqual(user.get_shell(), '/bin/zsh') + self.assertEqual(user.get_shell(), '/usr/bin/zsh') self.assertEqual(user.get_uid(), 2001) self.assertEqual(user.get_user_name(), 'pizza') self.assertEqual(user.get_x_session(), 'mock-xsession') @@ -244,7 +260,8 @@ class TestAccountsService(dbusmock.DBusTestCase): self.assertFalse(self._manager.props.has_multiple_users) self.assertFalse(user.props.automatic_login) self.assertEqual(user.props.email, 'pizza@python-dbusmock.org') - self.assertEqual(user.props.home_directory, '/tmp/dbusmock-home/pizza') + self.assertEqual(user.props.home_directory, + '/nonexisting/mock-home/pizza') self.assertEqual(user.props.icon_file, '') self.assertEqual(user.props.language, 'C') self.assertEqual(user.props.location, '') @@ -256,7 +273,7 @@ class TestAccountsService(dbusmock.DBusTestCase): self.assertEqual(user.props.password_mode, AccountsService.UserPasswordMode.REGULAR) self.assertEqual(user.props.real_name, 'I Love Pizza') - self.assertEqual(user.props.shell, '/bin/zsh') + self.assertEqual(user.props.shell, '/usr/bin/zsh') self.assertEqual(user.props.uid, 2001) self.assertEqual(user.props.user_name, 'pizza') self.assertEqual(user.props.x_session, 'mock-xsession') @@ -289,13 +306,13 @@ class TestAccountsService(dbusmock.DBusTestCase): self.wait_changed(user) self.assertFalse(user.get_automatic_login()) - user.set_email('Test Email') + user.set_email('test@email.org') self.wait_changed(user) - self.assertEqual(user.get_email(), 'Test Email') + self.assertEqual(user.get_email(), 'test@email.org') - user.set_icon_file('Test IconFile') + user.set_icon_file('/nonexistant/home/icon.png') self.wait_changed(user) - self.assertEqual(user.get_icon_file(), 'Test IconFile') + self.assertEqual(user.get_icon_file(), '/nonexistant/home/icon.png') user.set_language('Test Language') self.wait_changed(user) @@ -389,6 +406,45 @@ class TestAccountsService(dbusmock.DBusTestCase): AccountsService.UserManagerError.quark(), AccountsService.UserManagerError.FAILED)) + def test_automatic_login_users(self): + user = self._manager.create_user( + 'test-user', 'I am a Test user', + AccountsService.UserAccountType.STANDARD) + + user.set_automatic_login(True) + self.wait_changed(user) + self.assertTrue(user.get_automatic_login()) + self.assertEqual( + [user.get_object_path()], + self.get_property('AutomaticLoginUsers')) + self.assertCountEqual(self._mock_obj.ListMockUsers(), + self.get_property('AutomaticLoginUsers')) + + user2 = self._manager.create_user( + 'another-test-user', 'I am another Test user', + AccountsService.UserAccountType.STANDARD) + self.assertNotIn(user2.get_object_path(), + self.get_property('AutomaticLoginUsers')) + + user2.set_automatic_login(True) + self.assertIn(user2.get_object_path(), + self.get_property('AutomaticLoginUsers')) + self.assertEqual(len(self.get_property('AutomaticLoginUsers')), 2) + self.assertCountEqual(self._mock_obj.ListMockUsers(), + self.get_property('AutomaticLoginUsers')) + + user.set_automatic_login(False) + self.wait_changed(user) + self.assertFalse(user.get_automatic_login()) + self.assertNotIn(user.get_object_path(), + self.get_property('AutomaticLoginUsers')) + self.assertEqual(len(self.get_property('AutomaticLoginUsers')), 1) + + self._manager.delete_user(user2, False) + while user2 in self._manager.list_users(): + self.ctx.iteration(True) + self.assertFalse(self.get_property('AutomaticLoginUsers')) + if __name__ == '__main__': # avoid writing to stderr -- cgit v1.2.3