From ef5a7caf85bd6169701371da67029457abdaf47f Mon Sep 17 00:00:00 2001 From: Huanxuan Ao Date: Fri, 17 Mar 2017 13:28:49 +0800 Subject: Support to add/remove multi users for "group add/remove user" Similar delete commands in OSC, we can also support add/remove multi users for one specified group, this review implement it. Change-Id: I8ccf99d4ee83a18778fa3ff5c0a42bc7c6ff21fb Implements: bp support-multi-add-remove --- openstackclient/tests/unit/identity/v3/fakes.py | 38 ++++++ .../tests/unit/identity/v3/test_group.py | 131 +++++++++++++++------ 2 files changed, 134 insertions(+), 35 deletions(-) (limited to 'openstackclient/tests') diff --git a/openstackclient/tests/unit/identity/v3/fakes.py b/openstackclient/tests/unit/identity/v3/fakes.py index 01b5dede..139d90d5 100644 --- a/openstackclient/tests/unit/identity/v3/fakes.py +++ b/openstackclient/tests/unit/identity/v3/fakes.py @@ -770,6 +770,44 @@ class FakeUser(object): loaded=True) return user + @staticmethod + def create_users(attrs=None, count=2): + """Create multiple fake users. + + :param Dictionary attrs: + A dictionary with all attributes + :param int count: + The number of users to fake + :return: + A list of FakeResource objects faking the users + """ + users = [] + for i in range(0, count): + user = FakeUser.create_one_user(attrs) + users.append(user) + + return users + + @staticmethod + def get_users(users=None, count=2): + """Get an iterable MagicMock object with a list of faked users. + + If users list is provided, then initialize the Mock object with + the list. Otherwise create one. + + :param List users: + A list of FakeResource objects faking users + :param Integer count: + The number of users to be faked + :return + An iterable Mock object with side_effect set to a list of faked + users + """ + if users is None: + users = FakeUser.create_users(count) + + return mock.Mock(side_effect=users) + class FakeGroup(object): """Fake one or more group.""" diff --git a/openstackclient/tests/unit/identity/v3/test_group.py b/openstackclient/tests/unit/identity/v3/test_group.py index 5870e1db..81722631 100644 --- a/openstackclient/tests/unit/identity/v3/test_group.py +++ b/openstackclient/tests/unit/identity/v3/test_group.py @@ -42,47 +42,78 @@ class TestGroup(identity_fakes.TestIdentityv3): class TestGroupAddUser(TestGroup): - group = identity_fakes.FakeGroup.create_one_group() - user = identity_fakes.FakeUser.create_one_user() + _group = identity_fakes.FakeGroup.create_one_group() + users = identity_fakes.FakeUser.create_users(count=2) def setUp(self): super(TestGroupAddUser, self).setUp() - self.groups_mock.get.return_value = self.group - self.users_mock.get.return_value = self.user + self.groups_mock.get.return_value = self._group + self.users_mock.get = ( + identity_fakes.FakeUser.get_users(self.users)) self.users_mock.add_to_group.return_value = None self.cmd = group.AddUserToGroup(self.app, None) def test_group_add_user(self): arglist = [ - self.group.name, - self.user.name, + self._group.name, + self.users[0].name, ] verifylist = [ - ('group', self.group.name), - ('user', self.user.name), + ('group', self._group.name), + ('user', [self.users[0].name]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.users_mock.add_to_group.assert_called_once_with( - self.user.id, self.group.id) + self.users[0].id, self._group.id) self.assertIsNone(result) - def test_group_add_user_with_error(self): - self.users_mock.add_to_group.side_effect = exceptions.CommandError() + def test_group_add_multi_users(self): arglist = [ - self.group.name, - self.user.name, + self._group.name, + self.users[0].name, + self.users[1].name, ] verifylist = [ - ('group', self.group.name), - ('user', self.user.name), + ('group', self._group.name), + ('user', [self.users[0].name, self.users[1].name]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, parsed_args) + + result = self.cmd.take_action(parsed_args) + calls = [call(self.users[0].id, self._group.id), + call(self.users[1].id, self._group.id)] + self.users_mock.add_to_group.assert_has_calls(calls) + self.assertIsNone(result) + + @mock.patch.object(group.LOG, 'error') + def test_group_add_user_with_error(self, mock_error): + self.users_mock.add_to_group.side_effect = [ + exceptions.CommandError(), None] + arglist = [ + self._group.name, + self.users[0].name, + self.users[1].name, + ] + verifylist = [ + ('group', self._group.name), + ('user', [self.users[0].name, self.users[1].name]), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + try: + self.cmd.take_action(parsed_args) + self.fail('CommandError should be raised.') + except exceptions.CommandError as e: + msg = "1 of 2 users not added to group %s." % self._group.name + self.assertEqual(msg, str(e)) + msg = ("%(user)s not added to group %(group)s: ") % { + 'user': self.users[0].name, + 'group': self._group.name, + } + mock_error.assert_called_once_with(msg) class TestGroupCheckUser(TestGroup): @@ -463,48 +494,78 @@ class TestGroupList(TestGroup): class TestGroupRemoveUser(TestGroup): - group = identity_fakes.FakeGroup.create_one_group() - user = identity_fakes.FakeUser.create_one_user() + _group = identity_fakes.FakeGroup.create_one_group() + users = identity_fakes.FakeUser.create_users(count=2) def setUp(self): super(TestGroupRemoveUser, self).setUp() - self.groups_mock.get.return_value = self.group - self.users_mock.get.return_value = self.user + self.groups_mock.get.return_value = self._group + self.users_mock.get = ( + identity_fakes.FakeUser.get_users(self.users)) self.users_mock.remove_from_group.return_value = None self.cmd = group.RemoveUserFromGroup(self.app, None) def test_group_remove_user(self): arglist = [ - self.group.id, - self.user.id, + self._group.id, + self.users[0].id, ] verifylist = [ - ('group', self.group.id), - ('user', self.user.id), + ('group', self._group.id), + ('user', [self.users[0].id]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.users_mock.remove_from_group.assert_called_once_with( - self.user.id, self.group.id) + self.users[0].id, self._group.id) self.assertIsNone(result) - def test_group_remove_user_with_error(self): - self.users_mock.remove_from_group.side_effect = ( - exceptions.CommandError()) + def test_group_remove_multi_users(self): arglist = [ - self.group.id, - self.user.id, + self._group.name, + self.users[0].name, + self.users[1].name, ] verifylist = [ - ('group', self.group.id), - ('user', self.user.id), + ('group', self._group.name), + ('user', [self.users[0].name, self.users[1].name]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, parsed_args) + + result = self.cmd.take_action(parsed_args) + calls = [call(self.users[0].id, self._group.id), + call(self.users[1].id, self._group.id)] + self.users_mock.remove_from_group.assert_has_calls(calls) + self.assertIsNone(result) + + @mock.patch.object(group.LOG, 'error') + def test_group_remove_user_with_error(self, mock_error): + self.users_mock.remove_from_group.side_effect = [ + exceptions.CommandError(), None] + arglist = [ + self._group.id, + self.users[0].id, + self.users[1].id, + ] + verifylist = [ + ('group', self._group.id), + ('user', [self.users[0].id, self.users[1].id]), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + try: + self.cmd.take_action(parsed_args) + self.fail('CommandError should be raised.') + except exceptions.CommandError as e: + msg = "1 of 2 users not removed from group %s." % self._group.id + self.assertEqual(msg, str(e)) + msg = ("%(user)s not removed from group %(group)s: ") % { + 'user': self.users[0].id, + 'group': self._group.id, + } + mock_error.assert_called_once_with(msg) class TestGroupSet(TestGroup): -- cgit v1.2.1