From ac4e44403cdff3ffc980bcf0b990a1173207f301 Mon Sep 17 00:00:00 2001 From: zhufl Date: Mon, 6 Aug 2018 15:38:59 +0800 Subject: [PATCH] Fill quota schema for microversion 2.36/2.57 Network related attributes are removed from quota set from microversion 2.36, and injected file related attributes are removed from microversion 2.57, so this is to remove them from schema of quota set according to the microversion. Because show_quota_set uses schema get_quota_set when detail is False and uses schema get_quota_set_details when detail is True, so this is also to change one get_quota_set calling to be with detail=True, so to cover the schema check of get_quota_set_details. https://developer.openstack.org/api-ref/compute/#show-a-quota Change-Id: Ib3762ac10d9fef42e4747710b35073797a36636a partially-implements: blueprint full-schema-for-all-microversions --- tempest/api/compute/admin/test_quotas.py | 100 ++++++++++++------ .../response/compute/v2_36/quotas.py | 54 ++++++++++ .../response/compute/v2_57/quotas.py | 53 ++++++++++ tempest/lib/services/compute/quotas_client.py | 11 ++ 4 files changed, 184 insertions(+), 34 deletions(-) create mode 100644 tempest/lib/api_schema/response/compute/v2_36/quotas.py create mode 100644 tempest/lib/api_schema/response/compute/v2_57/quotas.py diff --git a/tempest/api/compute/admin/test_quotas.py b/tempest/api/compute/admin/test_quotas.py index df534bc9f0..12c725569f 100644 --- a/tempest/api/compute/admin/test_quotas.py +++ b/tempest/api/compute/admin/test_quotas.py @@ -25,22 +25,57 @@ from tempest.lib import decorators LOG = logging.getLogger(__name__) -class QuotasAdminTestJSON(base.BaseV2ComputeAdminTest): +class QuotasAdminTestBase(base.BaseV2ComputeAdminTest): force_tenant_isolation = True def setUp(self): # NOTE(mriedem): Avoid conflicts with os-quota-class-sets tests. self.useFixture(fixtures.LockFixture('compute_quotas')) - super(QuotasAdminTestJSON, self).setUp() + super(QuotasAdminTestBase, self).setUp() @classmethod def setup_clients(cls): - super(QuotasAdminTestJSON, cls).setup_clients() + super(QuotasAdminTestBase, cls).setup_clients() cls.adm_client = cls.os_admin.quotas_client + def _get_updated_quotas(self): + # Verify that GET shows the updated quota set of project + project_name = data_utils.rand_name('cpu_quota_project') + project_desc = project_name + '-desc' + project = identity.identity_utils(self.os_admin).create_project( + name=project_name, description=project_desc) + project_id = project['id'] + self.addCleanup(identity.identity_utils(self.os_admin).delete_project, + project_id) + + self.adm_client.update_quota_set(project_id, ram='5120') + # Call show_quota_set with detail=true to cover the + # get_quota_set_details response schema for microversion tests + quota_set = self.adm_client.show_quota_set( + project_id, detail=True)['quota_set'] + self.assertEqual(5120, quota_set['ram']['limit']) + + # Verify that GET shows the updated quota set of user + user_name = data_utils.rand_name('cpu_quota_user') + password = data_utils.rand_password() + email = user_name + '@testmail.tm' + user = identity.identity_utils(self.os_admin).create_user( + username=user_name, password=password, project=project, + email=email) + user_id = user['id'] + self.addCleanup(identity.identity_utils(self.os_admin).delete_user, + user_id) + + self.adm_client.update_quota_set(project_id, + user_id=user_id, + ram='2048') + quota_set = self.adm_client.show_quota_set( + project_id, user_id=user_id)['quota_set'] + self.assertEqual(2048, quota_set['ram']) + @classmethod def resource_setup(cls): - super(QuotasAdminTestJSON, cls).resource_setup() + super(QuotasAdminTestBase, cls).resource_setup() # NOTE(afazekas): these test cases should always create and use a new # tenant most of them should be skipped if we can't do that @@ -60,6 +95,8 @@ class QuotasAdminTestJSON(base.BaseV2ComputeAdminTest): 'injected_file_path_bytes', 'injected_files']) + +class QuotasAdminTestJSON(QuotasAdminTestBase): @decorators.idempotent_id('3b0a7c8f-cf58-46b8-a60c-715a32a8ba7d') def test_get_default_quotas(self): # Admin can get the default resource quota set for a tenant @@ -103,36 +140,7 @@ class QuotasAdminTestJSON(base.BaseV2ComputeAdminTest): # TODO(afazekas): merge these test cases @decorators.idempotent_id('ce9e0815-8091-4abd-8345-7fe5b85faa1d') def test_get_updated_quotas(self): - # Verify that GET shows the updated quota set of project - project_name = data_utils.rand_name('cpu_quota_project') - project_desc = project_name + '-desc' - project = identity.identity_utils(self.os_admin).create_project( - name=project_name, description=project_desc) - project_id = project['id'] - self.addCleanup(identity.identity_utils(self.os_admin).delete_project, - project_id) - - self.adm_client.update_quota_set(project_id, ram='5120') - quota_set = self.adm_client.show_quota_set(project_id)['quota_set'] - self.assertEqual(5120, quota_set['ram']) - - # Verify that GET shows the updated quota set of user - user_name = data_utils.rand_name('cpu_quota_user') - password = data_utils.rand_password() - email = user_name + '@testmail.tm' - user = identity.identity_utils(self.os_admin).create_user( - username=user_name, password=password, project=project, - email=email) - user_id = user['id'] - self.addCleanup(identity.identity_utils(self.os_admin).delete_user, - user_id) - - self.adm_client.update_quota_set(project_id, - user_id=user_id, - ram='2048') - quota_set = self.adm_client.show_quota_set( - project_id, user_id=user_id)['quota_set'] - self.assertEqual(2048, quota_set['ram']) + self._get_updated_quotas() @decorators.idempotent_id('389d04f0-3a41-405f-9317-e5f86e3c44f0') def test_delete_quota(self): @@ -156,6 +164,30 @@ class QuotasAdminTestJSON(base.BaseV2ComputeAdminTest): self.assertEqual(ram_default, quota_set_new['ram']) +class QuotasAdminTestV236(QuotasAdminTestBase): + min_microversion = '2.36' + # NOTE(gmann): This test tests the Quota APIs response schema + # for 2.36 microversion. No specific assert or behaviour verification + # is needed. + + @decorators.idempotent_id('4268b5c9-92e5-4adc-acf1-3a2798f3d803') + def test_get_updated_quotas(self): + # Checking Quota update, get, get details APIs response schema + self._get_updated_quotas() + + +class QuotasAdminTestV257(QuotasAdminTestBase): + min_microversion = '2.57' + # NOTE(gmann): This test tests the Quota APIs response schema + # for 2.57 microversion. No specific assert or behaviour verification + # is needed. + + @decorators.idempotent_id('e641e6c6-e86c-41a4-9e5c-9493c0ae47ad') + def test_get_updated_quotas(self): + # Checking Quota update, get, get details APIs response schema + self._get_updated_quotas() + + class QuotaClassesAdminTestJSON(base.BaseV2ComputeAdminTest): """Tests the os-quota-class-sets API to update default quotas.""" diff --git a/tempest/lib/api_schema/response/compute/v2_36/quotas.py b/tempest/lib/api_schema/response/compute/v2_36/quotas.py new file mode 100644 index 0000000000..f191ed178d --- /dev/null +++ b/tempest/lib/api_schema/response/compute/v2_36/quotas.py @@ -0,0 +1,54 @@ +# Copyright 2018 ZTE 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. + +import copy + +from tempest.lib.api_schema.response.compute.v2_1 import quotas as quotasv21 + +# Compute microversion 2.36: +# remove attributes in quota_set: +# 'fixed_ips', +# 'floating_ips', +# 'security_group_rules', +# 'security_groups' + +remove_item_list = ['fixed_ips', 'floating_ips', + 'security_group_rules', 'security_groups'] + +update_quota_set = copy.deepcopy(quotasv21.update_quota_set) +for item in remove_item_list: + update_quota_set['response_body']['properties']['quota_set'][ + 'properties'].pop(item) + update_quota_set['response_body']['properties']['quota_set'][ + 'required'].remove(item) + +get_quota_set = copy.deepcopy(quotasv21.get_quota_set) +for item in remove_item_list: + get_quota_set['response_body']['properties']['quota_set'][ + 'properties'].pop(item) + get_quota_set['response_body']['properties']['quota_set'][ + 'required'].remove(item) + +get_quota_set_details = copy.deepcopy(quotasv21.get_quota_set_details) +for item in remove_item_list: + get_quota_set_details['response_body']['properties']['quota_set'][ + 'properties'].pop(item) + get_quota_set_details['response_body']['properties']['quota_set'][ + 'required'].remove(item) + +# NOTE(zhufl): Below are the unchanged schema in this microversion. We need +# to keep this schema in this file to have the generic way to select the +# right schema based on self.schema_versions_info mapping in service client. +# ****** Schemas unchanged since microversion 2.1 *** +delete_quota = copy.deepcopy(quotasv21.delete_quota) diff --git a/tempest/lib/api_schema/response/compute/v2_57/quotas.py b/tempest/lib/api_schema/response/compute/v2_57/quotas.py new file mode 100644 index 0000000000..4664a1af97 --- /dev/null +++ b/tempest/lib/api_schema/response/compute/v2_57/quotas.py @@ -0,0 +1,53 @@ +# Copyright 2018 ZTE 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. + +import copy + +from tempest.lib.api_schema.response.compute.v2_36 import quotas as quotasv236 + +# Compute microversion 2.57: +# remove attributes in quota_set: +# 'injected_file_content_bytes', +# 'injected_file_path_bytes', +# 'injected_files' + +remove_item_list = ['injected_file_content_bytes', 'injected_file_path_bytes', + 'injected_files'] + +update_quota_set = copy.deepcopy(quotasv236.update_quota_set) +for item in remove_item_list: + update_quota_set['response_body']['properties']['quota_set'][ + 'properties'].pop(item) + update_quota_set['response_body']['properties']['quota_set'][ + 'required'].remove(item) + +get_quota_set = copy.deepcopy(quotasv236.get_quota_set) +for item in remove_item_list: + get_quota_set['response_body']['properties']['quota_set'][ + 'properties'].pop(item) + get_quota_set['response_body']['properties']['quota_set'][ + 'required'].remove(item) + +get_quota_set_details = copy.deepcopy(quotasv236.get_quota_set_details) +for item in remove_item_list: + get_quota_set_details['response_body']['properties']['quota_set'][ + 'properties'].pop(item) + get_quota_set_details['response_body']['properties']['quota_set'][ + 'required'].remove(item) + +# NOTE(zhufl): Below are the unchanged schema in this microversion. We need +# to keep this schema in this file to have the generic way to select the +# right schema based on self.schema_versions_info mapping in service client. +# ****** Schemas unchanged since microversion 2.1 *** +delete_quota = copy.deepcopy(quotasv236.delete_quota) diff --git a/tempest/lib/services/compute/quotas_client.py b/tempest/lib/services/compute/quotas_client.py index 12df89528c..99c8d0f97d 100644 --- a/tempest/lib/services/compute/quotas_client.py +++ b/tempest/lib/services/compute/quotas_client.py @@ -17,12 +17,19 @@ from oslo_serialization import jsonutils as json from six.moves.urllib import parse as urllib from tempest.lib.api_schema.response.compute.v2_1 import quotas as schema +from tempest.lib.api_schema.response.compute.v2_36 import quotas as schemav236 +from tempest.lib.api_schema.response.compute.v2_57 import quotas as schemav257 from tempest.lib.common import rest_client from tempest.lib.services.compute import base_compute_client class QuotasClient(base_compute_client.BaseComputeClient): + schema_versions_info = [ + {'min': None, 'max': '2.35', 'schema': schema}, + {'min': '2.36', 'max': '2.56', 'schema': schemav236}, + {'min': '2.57', 'max': None, 'schema': schemav257}] + def show_quota_set(self, tenant_id, user_id=None, detail=False): """List the quota set for a tenant. @@ -42,6 +49,7 @@ class QuotasClient(base_compute_client.BaseComputeClient): url += '?%s' % urllib.urlencode(params) resp, body = self.get(url) body = json.loads(body) + schema = self.get_schema(self.schema_versions_info) if detail: self.validate_response(schema.get_quota_set_details, resp, body) else: @@ -57,6 +65,7 @@ class QuotasClient(base_compute_client.BaseComputeClient): url = 'os-quota-sets/%s/defaults' % tenant_id resp, body = self.get(url) body = json.loads(body) + schema = self.get_schema(self.schema_versions_info) self.validate_response(schema.get_quota_set, resp, body) return rest_client.ResponseBody(resp, body) @@ -78,6 +87,7 @@ class QuotasClient(base_compute_client.BaseComputeClient): post_body) body = json.loads(body) + schema = self.get_schema(self.schema_versions_info) self.validate_response(schema.update_quota_set, resp, body) return rest_client.ResponseBody(resp, body) @@ -87,5 +97,6 @@ class QuotasClient(base_compute_client.BaseComputeClient): https://developer.openstack.org/api-ref/compute/#revert-quotas-to-defaults """ resp, body = self.delete('os-quota-sets/%s' % tenant_id) + schema = self.get_schema(self.schema_versions_info) self.validate_response(schema.delete_quota, resp, body) return rest_client.ResponseBody(resp, body)