From bca4571ab67b55b1a6d5c4ac09fe71dc687e4296 Mon Sep 17 00:00:00 2001 From: Huanxuan Ao Date: Wed, 20 Jul 2016 17:26:45 +0800 Subject: [PATCH] Unit test of credential in identityv3 Add missing unit tests and refactor the older tests with fake classeds for credential in identity v3 Change-Id: I94d4f80a86806c6115178421bd481b7622065956 --- openstackclient/tests/identity/v3/fakes.py | 103 +++++- .../tests/identity/v3/test_credential.py | 292 ++++++++++++++++-- 2 files changed, 367 insertions(+), 28 deletions(-) diff --git a/openstackclient/tests/identity/v3/fakes.py b/openstackclient/tests/identity/v3/fakes.py index df532df401..bad15b6cde 100644 --- a/openstackclient/tests/identity/v3/fakes.py +++ b/openstackclient/tests/identity/v3/fakes.py @@ -198,8 +198,6 @@ SERVICE_WITHOUT_NAME = { 'links': base_url + 'services/' + service_id, } -credential_id = 'c-123' - endpoint_id = 'e-123' endpoint_url = 'http://127.0.0.1:35357' endpoint_region = 'RegionOne' @@ -639,3 +637,104 @@ class FakeDomain(object): domain = fakes.FakeResource(info=copy.deepcopy(domain_info), loaded=True) return domain + + +class FakeCredential(object): + """Fake one or more credential.""" + + @staticmethod + def create_one_credential(attrs=None): + """Create a fake credential. + + :param Dictionary attrs: + A dictionary with all attributes + :return: + A FakeResource object, with id, type, and so on + """ + + attrs = attrs or {} + + # set default attributes. + credential_info = { + 'id': 'credential-id-' + uuid.uuid4().hex, + 'type': 'cert', + 'user_id': 'user-id-' + uuid.uuid4().hex, + 'blob': 'credential-data-' + uuid.uuid4().hex, + 'project_id': 'project-id-' + uuid.uuid4().hex, + 'links': 'links-' + uuid.uuid4().hex, + } + credential_info.update(attrs) + + credential = fakes.FakeResource( + info=copy.deepcopy(credential_info), loaded=True) + return credential + + @staticmethod + def create_credentials(attrs=None, count=2): + """Create multiple fake credentials. + + :param Dictionary attrs: + A dictionary with all attributes + :param int count: + The number of credentials to fake + :return: + A list of FakeResource objects faking the credentials + """ + credentials = [] + for i in range(0, count): + credential = FakeCredential.create_one_credential(attrs) + credentials.append(credential) + + return credentials + + @staticmethod + def get_credentials(credentials=None, count=2): + """Get an iterable MagicMock object with a list of faked credentials. + + If credentials list is provided, then initialize the Mock object with + the list. Otherwise create one. + + :param List credentials: + A list of FakeResource objects faking credentials + :param Integer count: + The number of credentials to be faked + :return + An iterable Mock object with side_effect set to a list of faked + credentials + """ + if credentials is None: + credentials = FakeCredential.create_credentials(count) + + return mock.MagicMock(side_effect=credentials) + + +class FakeUser(object): + """Fake one or more user.""" + + @staticmethod + def create_one_user(attrs=None): + """Create a fake user. + + :param Dictionary attrs: + A dictionary with all attributes + :return: + A FakeResource object, with id, name, and so on + """ + + attrs = attrs or {} + + # set default attributes. + user_info = { + 'id': 'user-id-' + uuid.uuid4().hex, + 'name': 'user-name-' + uuid.uuid4().hex, + 'default_project_id': 'project-' + uuid.uuid4().hex, + 'email': 'user-email-' + uuid.uuid4().hex, + 'enabled': True, + 'domain_id': 'domain-id' + uuid.uuid4().hex, + 'links': 'links-' + uuid.uuid4().hex, + } + user_info.update(attrs) + + user = fakes.FakeResource(info=copy.deepcopy(user_info), + loaded=True) + return user diff --git a/openstackclient/tests/identity/v3/test_credential.py b/openstackclient/tests/identity/v3/test_credential.py index d8866124f9..b272087d10 100644 --- a/openstackclient/tests/identity/v3/test_credential.py +++ b/openstackclient/tests/identity/v3/test_credential.py @@ -10,7 +10,10 @@ # License for the specific language governing permissions and limitations # under the License. -import json +import mock +from mock import call + +from osc_lib import exceptions from openstackclient.identity.v3 import credential from openstackclient.tests.identity.v3 import fakes as identity_fakes @@ -18,16 +21,6 @@ from openstackclient.tests import utils class TestCredential(identity_fakes.TestIdentityv3): - data = { - "access": "abc123", - "secret": "hidden-message", - "trust_id": None - } - - def __init__(self, *args): - super(TestCredential, self).__init__(*args) - - self.json_data = json.dumps(self.data) def setUp(self): super(TestCredential, self).setUp() @@ -45,15 +38,221 @@ class TestCredential(identity_fakes.TestIdentityv3): self.projects_mock.reset_mock() +class TestCredentialCreate(TestCredential): + + user = identity_fakes.FakeUser.create_one_user() + project = identity_fakes.FakeProject.create_one_project() + columns = ( + 'blob', + 'id', + 'project_id', + 'type', + 'user_id', + ) + + def setUp(self): + super(TestCredentialCreate, self).setUp() + + self.credential = identity_fakes.FakeCredential.create_one_credential( + attrs={'user_id': self.user.id, 'project_id': self.project.id}) + self.credentials_mock.create.return_value = self.credential + self.users_mock.get.return_value = self.user + self.projects_mock.get.return_value = self.project + self.data = ( + self.credential.blob, + self.credential.id, + self.credential.project_id, + self.credential.type, + self.credential.user_id, + ) + + self.cmd = credential.CreateCredential(self.app, None) + + def test_credential_create_no_options(self): + arglist = [ + self.credential.user_id, + self.credential.blob, + ] + verifylist = [ + ('user', self.credential.user_id), + ('data', self.credential.blob), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + kwargs = { + 'user': self.credential.user_id, + 'type': self.credential.type, + 'blob': self.credential.blob, + 'project': None, + } + self.credentials_mock.create.assert_called_once_with( + **kwargs + ) + + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) + + def test_credential_create_with_options(self): + arglist = [ + self.credential.user_id, + self.credential.blob, + '--type', self.credential.type, + '--project', self.credential.project_id, + ] + verifylist = [ + ('user', self.credential.user_id), + ('data', self.credential.blob), + ('type', self.credential.type), + ('project', self.credential.project_id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + kwargs = { + 'user': self.credential.user_id, + 'type': self.credential.type, + 'blob': self.credential.blob, + 'project': self.credential.project_id, + } + self.credentials_mock.create.assert_called_once_with( + **kwargs + ) + + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) + + def test_credential_create_with_invalid_type(self): + arglist = [ + self.credential.user_id, + self.credential.blob, + '--type', 'invalid_type', + ] + verifylist = [ + ('user', self.credential.user_id), + ('data', self.credential.blob), + ('type', 'invalid_type'), + ] + self.assertRaises(utils.ParserException, self.check_parser, + self.cmd, arglist, verifylist) + + +class TestCredentialDelete(TestCredential): + + credentials = identity_fakes.FakeCredential.create_credentials(count=2) + + def setUp(self): + super(TestCredentialDelete, self).setUp() + + self.credentials_mock.delete.return_value = None + + # Get the command object to test + self.cmd = credential.DeleteCredential(self.app, None) + + def test_credential_delete(self): + arglist = [ + self.credentials[0].id, + ] + verifylist = [ + ('credential', [self.credentials[0].id]), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + + self.credentials_mock.delete.assert_called_with( + self.credentials[0].id, + ) + self.assertIsNone(result) + + def test_credential_multi_delete(self): + arglist = [] + for c in self.credentials: + arglist.append(c.id) + verifylist = [ + ('credential', arglist), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + calls = [] + for c in self.credentials: + calls.append(call(c.id)) + self.credentials_mock.delete.assert_has_calls(calls) + self.assertIsNone(result) + + def test_credential_multi_delete_with_exception(self): + arglist = [ + self.credentials[0].id, + 'unexist_credential', + ] + verifylist = [ + ('credential', [self.credentials[0].id, 'unexist_credential']) + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + delete_mock_result = [None, exceptions.CommandError] + self.credentials_mock.delete = ( + mock.MagicMock(side_effect=delete_mock_result) + ) + + try: + self.cmd.take_action(parsed_args) + self.fail('CommandError should be raised.') + except exceptions.CommandError as e: + self.assertEqual('1 of 2 credential failed to delete.', str(e)) + + self.credentials_mock.delete.assert_any_call(self.credentials[0].id) + self.credentials_mock.delete.assert_any_call('unexist_credential') + + +class TestCredentialList(TestCredential): + + credential = identity_fakes.FakeCredential.create_one_credential() + + columns = ('ID', 'Type', 'User ID', 'Data', 'Project ID') + data = (( + credential.id, + credential.type, + credential.user_id, + credential.blob, + credential.project_id, + ), ) + + def setUp(self): + super(TestCredentialList, self).setUp() + + self.credentials_mock.list.return_value = [self.credential] + + # Get the command object to test + self.cmd = credential.ListCredential(self.app, None) + + def test_domain_list_no_options(self): + arglist = [] + verifylist = [] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.credentials_mock.list.assert_called_with() + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, tuple(data)) + + class TestCredentialSet(TestCredential): + credential = identity_fakes.FakeCredential.create_one_credential() + def setUp(self): super(TestCredentialSet, self).setUp() self.cmd = credential.SetCredential(self.app, None) def test_credential_set_no_options(self): arglist = [ - identity_fakes.credential_id, + self.credential.id, ] self.assertRaises(utils.ParserException, @@ -62,8 +261,8 @@ class TestCredentialSet(TestCredential): def test_credential_set_missing_user(self): arglist = [ '--type', 'ec2', - '--data', self.json_data, - identity_fakes.credential_id, + '--data', self.credential.blob, + self.credential.id, ] self.assertRaises(utils.ParserException, @@ -71,9 +270,9 @@ class TestCredentialSet(TestCredential): def test_credential_set_missing_type(self): arglist = [ - '--user', identity_fakes.user_name, - '--data', self.json_data, - identity_fakes.credential_id, + '--user', self.credential.user_id, + '--data', self.credential.blob, + self.credential.id, ] self.assertRaises(utils.ParserException, @@ -81,9 +280,9 @@ class TestCredentialSet(TestCredential): def test_credential_set_missing_data(self): arglist = [ - '--user', identity_fakes.user_name, + '--user', self.credential.user_id, '--type', 'ec2', - identity_fakes.credential_id, + self.credential.id, ] self.assertRaises(utils.ParserException, @@ -91,10 +290,10 @@ class TestCredentialSet(TestCredential): def test_credential_set_valid(self): arglist = [ - '--user', identity_fakes.user_name, + '--user', self.credential.user_id, '--type', 'ec2', - '--data', self.json_data, - identity_fakes.credential_id, + '--data', self.credential.blob, + self.credential.id, ] parsed_args = self.check_parser(self.cmd, arglist, []) @@ -104,14 +303,55 @@ class TestCredentialSet(TestCredential): def test_credential_set_valid_with_project(self): arglist = [ - '--user', identity_fakes.user_name, + '--user', self.credential.user_id, '--type', 'ec2', - '--data', self.json_data, - '--project', identity_fakes.project_name, - identity_fakes.credential_id, + '--data', self.credential.blob, + '--project', self.credential.project_id, + self.credential.id, ] parsed_args = self.check_parser(self.cmd, arglist, []) result = self.cmd.take_action(parsed_args) self.assertIsNone(result) + + +class TestCredentialShow(TestCredential): + + columns = ( + 'blob', + 'id', + 'project_id', + 'type', + 'user_id', + ) + + def setUp(self): + super(TestCredentialShow, self).setUp() + + self.credential = identity_fakes.FakeCredential.create_one_credential() + self.credentials_mock.get.return_value = self.credential + self.data = ( + self.credential.blob, + self.credential.id, + self.credential.project_id, + self.credential.type, + self.credential.user_id, + ) + + self.cmd = credential.ShowCredential(self.app, None) + + def test_credential_show(self): + arglist = [ + self.credential.id, + ] + verifylist = [ + ('credential', self.credential.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.credentials_mock.get.assert_called_once_with(self.credential.id) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data)