Merge "Fix compute quota classes schema for v2.50 and v2.57"
diff --git a/doc/source/microversion_testing.rst b/doc/source/microversion_testing.rst
index ff6237e..f5da6f9 100644
--- a/doc/source/microversion_testing.rst
+++ b/doc/source/microversion_testing.rst
@@ -386,6 +386,10 @@
 
   .. _2.49: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id45
 
+  * `2.50`_
+
+  .. _2.50: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id46
+
   * `2.53`_
 
   .. _2.53: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#maximum-in-pike
diff --git a/tempest/api/compute/admin/test_quotas.py b/tempest/api/compute/admin/test_quotas.py
index 9d5e0c9..6a79a2f 100644
--- a/tempest/api/compute/admin/test_quotas.py
+++ b/tempest/api/compute/admin/test_quotas.py
@@ -253,3 +253,14 @@
             'default')['quota_class_set']
         self.assertThat(show_body.items(),
                         matchers.ContainsAll(body.items()))
+
+
+class QuotaClassesAdmin257Test(QuotaClassesAdminTestJSON):
+    """Test compute quotas with microversion greater than 2.56
+
+    # NOTE(gmann): This test tests the Quota class APIs response schema
+    # for 2.57 microversion. No specific assert or behaviour verification
+    # is needed.
+    """
+
+    min_microversion = '2.57'
diff --git a/tempest/lib/api_schema/response/compute/v2_50/__init__.py b/tempest/lib/api_schema/response/compute/v2_50/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/lib/api_schema/response/compute/v2_50/__init__.py
diff --git a/tempest/lib/api_schema/response/compute/v2_50/quota_classes.py b/tempest/lib/api_schema/response/compute/v2_50/quota_classes.py
new file mode 100644
index 0000000..4ee845f
--- /dev/null
+++ b/tempest/lib/api_schema/response/compute/v2_50/quota_classes.py
@@ -0,0 +1,48 @@
+# 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 quota_classes \
+    as quota_classesv21
+
+# Compute microversion 2.50:
+# 1. fixed_ips, floating_ips, security_group_rules and security_groups
+#    are removed from:
+#      * GET /os-quota-class-sets/{id}
+#      * PUT /os-quota-class-sets/{id}
+# 2. server_groups and server_group_members are added to:
+#      * GET /os-quota-class-sets/{id}
+#      * PUT /os-quota-class-sets/{id}
+
+get_quota_class_set = copy.deepcopy(quota_classesv21.get_quota_class_set)
+update_quota_class_set = copy.deepcopy(quota_classesv21.update_quota_class_set)
+for field in ['fixed_ips', 'floating_ips', 'security_group_rules',
+              'security_groups']:
+    get_quota_class_set['response_body']['properties']['quota_class_set'][
+        'properties'].pop(field, None)
+    get_quota_class_set['response_body']['properties']['quota_class_set'][
+        'required'].remove(field)
+    update_quota_class_set['response_body']['properties']['quota_class_set'][
+        'properties'].pop(field, None)
+    update_quota_class_set['response_body']['properties'][
+        'quota_class_set']['required'].remove(field)
+for field in ['server_groups', 'server_group_members']:
+    get_quota_class_set['response_body']['properties']['quota_class_set'][
+        'properties'].update({field: {'type': 'integer'}})
+    get_quota_class_set['response_body']['properties']['quota_class_set'][
+        'required'].append(field)
+    update_quota_class_set['response_body']['properties']['quota_class_set'][
+        'properties'].update({field: {'type': 'integer'}})
+    update_quota_class_set['response_body']['properties']['quota_class_set'][
+        'required'].append(field)
diff --git a/tempest/lib/api_schema/response/compute/v2_57/quota_classes.py b/tempest/lib/api_schema/response/compute/v2_57/quota_classes.py
new file mode 100644
index 0000000..396ed66
--- /dev/null
+++ b/tempest/lib/api_schema/response/compute/v2_57/quota_classes.py
@@ -0,0 +1,37 @@
+# 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_50 import quota_classes \
+    as quota_classesv250
+
+# Compute microversion 2.57:
+# 1. injected_file_content_bytes, injected_file_path_bytes, injected_files
+#    are removed from:
+#      * GET /os-quota-class-sets/{id}
+#      * PUT /os-quota-class-sets/{id}
+
+get_quota_class_set = copy.deepcopy(quota_classesv250.get_quota_class_set)
+update_quota_class_set = copy.deepcopy(
+    quota_classesv250.update_quota_class_set)
+for field in ['injected_file_content_bytes', 'injected_file_path_bytes',
+              'injected_files']:
+    get_quota_class_set['response_body']['properties']['quota_class_set'][
+        'properties'].pop(field, None)
+    get_quota_class_set['response_body']['properties']['quota_class_set'][
+        'required'].remove(field)
+    update_quota_class_set['response_body']['properties']['quota_class_set'][
+        'properties'].pop(field, None)
+    update_quota_class_set['response_body']['properties'][
+        'quota_class_set']['required'].remove(field)
diff --git a/tempest/lib/services/compute/quota_classes_client.py b/tempest/lib/services/compute/quota_classes_client.py
index 9b64099..5f220a7 100644
--- a/tempest/lib/services/compute/quota_classes_client.py
+++ b/tempest/lib/services/compute/quota_classes_client.py
@@ -16,20 +16,30 @@
 from oslo_serialization import jsonutils as json
 
 from tempest.lib.api_schema.response.compute.v2_1\
-    import quota_classes as classes_schema
+    import quota_classes as schema
+from tempest.lib.api_schema.response.compute.v2_50 import quota_classes \
+    as schemav250
+from tempest.lib.api_schema.response.compute.v2_57 import quota_classes \
+    as schemav257
 from tempest.lib.common import rest_client
 from tempest.lib.services.compute import base_compute_client
 
 
 class QuotaClassesClient(base_compute_client.BaseComputeClient):
 
+    schema_versions_info = [
+        {'min': None, 'max': '2.49', 'schema': schema},
+        {'min': '2.50', 'max': '2.56', 'schema': schemav250},
+        {'min': '2.57', 'max': None, 'schema': schemav257}]
+
     def show_quota_class_set(self, quota_class_id):
         """List the quota class set for a quota class."""
 
         url = 'os-quota-class-sets/%s' % quota_class_id
         resp, body = self.get(url)
         body = json.loads(body)
-        self.validate_response(classes_schema.get_quota_class_set, resp, body)
+        _schema = self.get_schema(self.schema_versions_info)
+        self.validate_response(_schema.get_quota_class_set, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def update_quota_class_set(self, quota_class_id, **kwargs):
@@ -45,6 +55,7 @@
                               post_body)
 
         body = json.loads(body)
-        self.validate_response(classes_schema.update_quota_class_set,
+        _schema = self.get_schema(self.schema_versions_info)
+        self.validate_response(_schema.update_quota_class_set,
                                resp, body)
         return rest_client.ResponseBody(resp, body)