Merge "Fill quota schema for microversion 2.36/2.57"
diff --git a/tempest/api/compute/admin/test_quotas.py b/tempest/api/compute/admin/test_quotas.py
index df534bc..12c7255 100644
--- a/tempest/api/compute/admin/test_quotas.py
+++ b/tempest/api/compute/admin/test_quotas.py
@@ -25,22 +25,57 @@
 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 @@
                                              '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 @@
     # 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 @@
         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 0000000..f191ed1
--- /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 0000000..4664a1a
--- /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 12df895..99c8d0f 100644
--- a/tempest/lib/services/compute/quotas_client.py
+++ b/tempest/lib/services/compute/quotas_client.py
@@ -17,12 +17,19 @@
 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 @@
             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 @@
         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 @@
                                   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 @@
         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)