From 8e2d403283f160b0dbc7d8cdbb42e7a432da0a38 Mon Sep 17 00:00:00 2001 From: Nicolas Helgeson Date: Tue, 14 Feb 2017 09:36:37 -0800 Subject: [PATCH] Identity V3-ext Oauth1 Consumers Client Adding a new client lib to handle the OAUTH consumers API testing Included unit tests for the client lib, and API tests for the OAUTH consumers API Co-Authored-By: Nishant Kumar Co-Authored-By: Avishek Dutta Change-Id: I6d0884637cfe00a5313a5d019e1e062316f76d57 Closes-Bug: #1672810 --- ...Client-tempest-tests-db1df7aae4a9fd4e.yaml | 3 + .../identity/admin/v3/test_oauth_consumers.py | 91 ++++++++++ tempest/api/identity/base.py | 1 + tempest/clients.py | 2 + tempest/lib/services/identity/v3/__init__.py | 5 +- .../identity/v3/oauth_consumers_client.py | 95 +++++++++++ .../v3/test_oauth_consumers_client.py | 160 ++++++++++++++++++ 7 files changed, 356 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/add-OAUTH-Consumer-Client-tempest-tests-db1df7aae4a9fd4e.yaml create mode 100644 tempest/api/identity/admin/v3/test_oauth_consumers.py create mode 100644 tempest/lib/services/identity/v3/oauth_consumers_client.py create mode 100644 tempest/tests/lib/services/identity/v3/test_oauth_consumers_client.py diff --git a/releasenotes/notes/add-OAUTH-Consumer-Client-tempest-tests-db1df7aae4a9fd4e.yaml b/releasenotes/notes/add-OAUTH-Consumer-Client-tempest-tests-db1df7aae4a9fd4e.yaml new file mode 100644 index 0000000000..6b4566605e --- /dev/null +++ b/releasenotes/notes/add-OAUTH-Consumer-Client-tempest-tests-db1df7aae4a9fd4e.yaml @@ -0,0 +1,3 @@ +--- +features: + - Add a new client to handle the OAUTH consumers feature from the identity API. diff --git a/tempest/api/identity/admin/v3/test_oauth_consumers.py b/tempest/api/identity/admin/v3/test_oauth_consumers.py new file mode 100644 index 0000000000..f06fb8f5f1 --- /dev/null +++ b/tempest/api/identity/admin/v3/test_oauth_consumers.py @@ -0,0 +1,91 @@ +# Copyright 2017 AT&T Corporation. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from tempest.api.identity import base +from tempest.common.utils import data_utils +from tempest.lib.common.utils import test_utils +from tempest.lib import decorators +from tempest.lib import exceptions as exceptions + + +class OAUTHConsumersV3Test(base.BaseIdentityV3AdminTest): + + def _create_consumer(self): + """Creates a consumer with a random description.""" + description = data_utils.rand_name('test_create_consumer') + consumer = self.oauth_consumers_client.create_consumer( + description)['consumer'] + # cleans up created consumers after tests + self.addCleanup(test_utils.call_and_ignore_notfound_exc, + self.oauth_consumers_client.delete_consumer, + consumer['id']) + return consumer + + @decorators.idempotent_id('c8307ea6-a86c-47fd-ae7b-5b3b2caca76d') + def test_create_and_show_consumer(self): + """Tests to make sure that a consumer with parameters is made""" + consumer = self._create_consumer() + # fetch created consumer from client + fetched_consumer = self.oauth_consumers_client.show_consumer( + consumer['id'])['consumer'] + # assert that the fetched consumer matches the created one and + # has all parameters + for key in ['description', 'id', 'links']: + self.assertEqual(consumer[key], fetched_consumer[key]) + + @decorators.idempotent_id('fdfa1b7f-2a31-4354-b2c7-f6ae20554f93') + def test_delete_consumer(self): + """Tests the delete function.""" + consumer = self._create_consumer() + # fetch consumer from client to confirm it exists + fetched_consumer = self.oauth_consumers_client.show_consumer( + consumer['id'])['consumer'] + self.assertEqual(consumer['id'], fetched_consumer['id']) + # delete existing consumer + self.oauth_consumers_client.delete_consumer(consumer['id']) + # check that consumer no longer exists + self.assertRaises(exceptions.NotFound, + self.oauth_consumers_client.show_consumer, + consumer['id']) + + @decorators.idempotent_id('080a9b1a-c009-47c0-9979-5305bf72e3dc') + def test_update_consumer(self): + """Tests the update functionality""" + # create a new consumer to update + consumer = self._create_consumer() + # create new description + new_description = data_utils.rand_name('test_update_consumer') + # update consumer + self.oauth_consumers_client.update_consumer(consumer['id'], + new_description) + # check that the same consumer now has the new description + updated_consumer = self.oauth_consumers_client.show_consumer( + consumer['id'])['consumer'] + self.assertEqual(new_description, updated_consumer['description']) + + @decorators.idempotent_id('09ca50de-78f2-4ffb-ac71-f2254036b2b8') + def test_list_consumers(self): + """Test for listing consumers""" + # create two consumers to populate list + new_consumer_one = self._create_consumer() + new_consumer_two = self._create_consumer() + # fetch the list of consumers + consumer_list = self.oauth_consumers_client \ + .list_consumers()['consumers'] + # add fetched consumer ids to a list + id_list = [consumer['id'] for consumer in consumer_list] + # check if created consumers are in the list + self.assertIn(new_consumer_one['id'], id_list) + self.assertIn(new_consumer_two['id'], id_list) diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py index 9339d3c71a..8317535c61 100644 --- a/tempest/api/identity/base.py +++ b/tempest/api/identity/base.py @@ -212,6 +212,7 @@ class BaseIdentityV3AdminTest(BaseIdentityV3Test): cls.groups_client = cls.os_adm.groups_client cls.projects_client = cls.os_adm.projects_client cls.role_assignments = cls.os_admin.role_assignments_client + cls.oauth_consumers_client = cls.os_adm.oauth_consumers_client if CONF.identity.admin_domain_scope: # NOTE(andreaf) When keystone policy requires it, the identity # admin clients for these tests shall use 'domain' scoped tokens. diff --git a/tempest/clients.py b/tempest/clients.py index e75fa7903e..2c06132212 100644 --- a/tempest/clients.py +++ b/tempest/clients.py @@ -229,6 +229,8 @@ class Manager(clients.ServiceClients): self.groups_client = self.identity_v3.GroupsClient(**params_v3) self.identity_versions_v3_client = self.identity_v3.VersionsClient( **params_v3) + self.oauth_consumers_client = self.identity_v3.OAUTHConsumerClient( + **params_v3) # Token clients do not use the catalog. They only need default_params. # They read auth_url, so they should only be set if the corresponding diff --git a/tempest/lib/services/identity/v3/__init__.py b/tempest/lib/services/identity/v3/__init__.py index 88801e7272..1489b507df 100644 --- a/tempest/lib/services/identity/v3/__init__.py +++ b/tempest/lib/services/identity/v3/__init__.py @@ -20,6 +20,8 @@ from tempest.lib.services.identity.v3.groups_client import GroupsClient from tempest.lib.services.identity.v3.identity_client import IdentityClient from tempest.lib.services.identity.v3.inherited_roles_client import \ InheritedRolesClient +from tempest.lib.services.identity.v3.oauth_consumers_client import \ + OAUTHConsumerClient from tempest.lib.services.identity.v3.policies_client import PoliciesClient from tempest.lib.services.identity.v3.projects_client import ProjectsClient from tempest.lib.services.identity.v3.regions_client import RegionsClient @@ -36,4 +38,5 @@ __all__ = ['CredentialsClient', 'DomainsClient', 'EndPointsClient', 'GroupsClient', 'IdentityClient', 'InheritedRolesClient', 'PoliciesClient', 'ProjectsClient', 'RegionsClient', 'RoleAssignmentsClient', 'RolesClient', 'ServicesClient', - 'V3TokenClient', 'TrustsClient', 'UsersClient', 'VersionsClient'] + 'V3TokenClient', 'TrustsClient', 'UsersClient', 'VersionsClient', + 'OAUTHConsumerClient'] diff --git a/tempest/lib/services/identity/v3/oauth_consumers_client.py b/tempest/lib/services/identity/v3/oauth_consumers_client.py new file mode 100644 index 0000000000..582c9e00ee --- /dev/null +++ b/tempest/lib/services/identity/v3/oauth_consumers_client.py @@ -0,0 +1,95 @@ +# Copyright 2017 AT&T Corporation. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from oslo_serialization import jsonutils as json + +from tempest.lib.common import rest_client + + +class OAUTHConsumerClient(rest_client.RestClient): + api_version = "v3" + + def create_consumer(self, description=None): + """Creates a consumer. + + :param str description: Optional field to add notes about the consumer + + For more information, please refer to the official + API reference: + http://developer.openstack.org/api-ref/identity/v3-ext/#create-consumer + """ + post_body = {"description": description} + post_body = json.dumps({'consumer': post_body}) + resp, body = self.post('OS-OAUTH1/consumers', post_body) + self.expected_success(201, resp.status) + body = json.loads(body) + return rest_client.ResponseBody(resp, body) + + def delete_consumer(self, consumer_id): + """Deletes a consumer. + + :param str consumer_id: The ID of the consumer that will be deleted + + For more information, please refer to the official + API reference: + http://developer.openstack.org/api-ref/identity/v3-ext/#delete-consumer + """ + resp, body = self.delete('OS-OAUTH1/consumers/%s' % consumer_id) + self.expected_success(204, resp.status) + return rest_client.ResponseBody(resp, body) + + def update_consumer(self, consumer_id, description=None): + """Updates a consumer. + + :param str consumer_id: The ID of the consumer that will be updated + :param str description: Optional field to add notes about the consumer + + For more information, please refer to the official + API reference: + http://developer.openstack.org/api-ref/identity/v3-ext/#update-consumers + """ + post_body = {"description": description} + post_body = json.dumps({'consumer': post_body}) + resp, body = self.patch('OS-OAUTH1/consumers/%s' % consumer_id, + post_body) + self.expected_success(200, resp.status) + body = json.loads(body) + return rest_client.ResponseBody(resp, body) + + def show_consumer(self, consumer_id): + """Show consumer details. + + :param str consumer_id: The ID of the consumer that will be shown + + For more information, please refer to the official + API reference: + http://developer.openstack.org/api-ref/identity/v3-ext/#show-consumer-details + """ + resp, body = self.get('OS-OAUTH1/consumers/%s' % consumer_id) + self.expected_success(200, resp.status) + body = json.loads(body) + return rest_client.ResponseBody(resp, body) + + def list_consumers(self): + """List all consumers. + + For more information, please refer to the official + API reference: + http://developer.openstack.org/api-ref/identity/v3-ext/#list-consumers + """ + resp, body = self.get('OS-OAUTH1/consumers') + self.expected_success(200, resp.status) + body = json.loads(body) + return rest_client.ResponseBody(resp, body) diff --git a/tempest/tests/lib/services/identity/v3/test_oauth_consumers_client.py b/tempest/tests/lib/services/identity/v3/test_oauth_consumers_client.py new file mode 100644 index 0000000000..8d5379254b --- /dev/null +++ b/tempest/tests/lib/services/identity/v3/test_oauth_consumers_client.py @@ -0,0 +1,160 @@ +# Copyright 2017 AT&T Corporation. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from tempest.lib.services.identity.v3 import oauth_consumers_client +from tempest.tests.lib import fake_auth_provider +from tempest.tests.lib.services import base + + +class TestOAUTHConsumerClient(base.BaseServiceTest): + FAKE_CREATE_CONSUMER = { + "consumer": { + 'description': 'A fake description 1' + } + + } + + FAKE_CONSUMER_INFO = { + "consumer": { + 'id': '6392c7d3b7a2062e09a07aa377', + 'links': { + 'self': 'http://example.com/identity/v3/' + + 'OS-OAUTH1/consumers/g6f2l9' + }, + 'description': 'A description that is fake' + } + + } + + FAKE_LIST_CONSUMERS = { + 'links': { + 'self': 'http://example.com/identity/v3/OS-OAUTH1/consumers/', + 'next': None, + 'previous': None + }, + 'consumers': [ + { + 'id': '6392c7d3b7a2062e09a07aa377', + 'links': { + 'self': 'http://example.com/identity/v3/' + + 'OS-OAUTH1/consumers/6b9f2g5' + }, + 'description': 'A description that is fake' + }, + { + 'id': '677a855c9e3eb3a3954b36aca6', + 'links': { + 'self': 'http://example.com/identity/v3/' + + 'OS-OAUTH1/consumers/6a9f2366' + }, + 'description': 'A very fake description 2' + }, + { + 'id': '9d3ac57b08d65e07826b5e506', + 'links': { + 'self': 'http://example.com/identity/v3/' + + 'OS-OAUTH1/consumers/626b5e506' + }, + 'description': 'A very fake description 3' + }, + { + 'id': 'b522d163b1a18e928aca9y426', + 'links': { + 'self': 'http://example.com/identity/v3/' + + 'OS-OAUTH1/consumers/g7ca9426' + }, + 'description': 'A very fake description 4' + }, + { + 'id': 'b7e47321b5ef9051f93c2049e', + 'links': { + 'self': 'http://example.com/identity/v3/' + + 'OS-OAUTH1/consumers/23d82049e' + }, + 'description': 'A very fake description 5' + } + ] + } + + def setUp(self): + super(TestOAUTHConsumerClient, self).setUp() + fake_auth = fake_auth_provider.FakeAuthProvider() + self.client = oauth_consumers_client.OAUTHConsumerClient(fake_auth, + 'identity', + 'regionOne') + + def _test_create_consumer(self, bytes_body=False): + self.check_service_client_function( + self.client.create_consumer, + 'tempest.lib.common.rest_client.RestClient.post', + self.FAKE_CREATE_CONSUMER, + bytes_body, + description=self.FAKE_CREATE_CONSUMER["consumer"]["description"], + status=201) + + def _test_show_consumer(self, bytes_body=False): + self.check_service_client_function( + self.client.show_consumer, + 'tempest.lib.common.rest_client.RestClient.get', + self.FAKE_CONSUMER_INFO, + bytes_body, + consumer_id="6392c7d3b7a2062e09a07aa377") + + def _test_list_consumers(self, bytes_body=False): + self.check_service_client_function( + self.client.list_consumers, + 'tempest.lib.common.rest_client.RestClient.get', + self.FAKE_LIST_CONSUMERS, + bytes_body) + + def _test_update_consumer(self, bytes_body=False): + self.check_service_client_function( + self.client.update_consumer, + 'tempest.lib.common.rest_client.RestClient.patch', + self.FAKE_CONSUMER_INFO, + bytes_body, + consumer_id="6392c7d3b7a2062e09a07aa377") + + def test_create_consumer_with_str_body(self): + self._test_create_consumer() + + def test_create_consumer_with_bytes_body(self): + self._test_create_consumer(bytes_body=True) + + def test_show_consumer_with_str_body(self): + self._test_show_consumer() + + def test_show_consumer_with_bytes_body(self): + self._test_show_consumer(bytes_body=True) + + def test_list_consumers_with_str_body(self): + self._test_list_consumers() + + def test_list_consumers_with_bytes_body(self): + self._test_list_consumers(bytes_body=True) + + def test_update_consumer_with_str_body(self): + self._test_update_consumer() + + def test_update_consumer_with_bytes_body(self): + self._test_update_consumer(bytes_body=True) + + def test_delete_consumer(self): + self.check_service_client_function( + self.client.delete_consumer, + 'tempest.lib.common.rest_client.RestClient.delete', + {}, + consumer_id="6392c7d3b7a2062e09a07aa377", + status=204)