Add compute microversion 2.61 schema in flavors_client

Compute microversion 2.61 adds 'extra_specs' in flavor APIs response
This commit fill the schema gap for that.

Change-Id: Id1f1e51fbae1cc3d0c9efdcd9009f384745915d6
diff --git a/doc/source/microversion_testing.rst b/doc/source/microversion_testing.rst
index ea868ae..3ae03c2 100644
--- a/doc/source/microversion_testing.rst
+++ b/doc/source/microversion_testing.rst
@@ -374,6 +374,10 @@
 
   .. _2.60: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#maximum-in-queens
 
+  * `2.61`_
+
+  .. _2.61: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id55
+
   * `2.63`_
 
   .. _2.63: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id57
diff --git a/tempest/api/compute/admin/test_flavors_microversions.py b/tempest/api/compute/admin/test_flavors_microversions.py
index 027af25..9f014e6 100644
--- a/tempest/api/compute/admin/test_flavors_microversions.py
+++ b/tempest/api/compute/admin/test_flavors_microversions.py
@@ -41,3 +41,11 @@
         self.flavors_client.list_flavors(detail=True)['flavors']
         # Checking list API response schema
         self.flavors_client.list_flavors()['flavors']
+
+
+class FlavorsV261TestJSON(FlavorsV255TestJSON):
+    min_microversion = '2.61'
+    max_microversion = 'latest'
+
+    # NOTE(gmann): This class tests the flavors APIs
+    # response schema for the 2.61 microversion.
diff --git a/tempest/lib/api_schema/response/compute/v2_61/__init__.py b/tempest/lib/api_schema/response/compute/v2_61/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/lib/api_schema/response/compute/v2_61/__init__.py
diff --git a/tempest/lib/api_schema/response/compute/v2_61/flavors.py b/tempest/lib/api_schema/response/compute/v2_61/flavors.py
new file mode 100644
index 0000000..381fb64
--- /dev/null
+++ b/tempest/lib/api_schema/response/compute/v2_61/flavors.py
@@ -0,0 +1,102 @@
+# Copyright 2018 NEC 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 parameter_types
+from tempest.lib.api_schema.response.compute.v2_55 import flavors \
+    as flavorsv255
+
+# ****** Schemas changed in microversion 2.61 *****************
+
+# Note(gmann): This is schema for microversion 2.61 which includes the
+# Flavor extra_specs in the Response body of the following APIs:
+#    - ``PUT /flavors/{flavor_id}``
+#    - ``GET /flavors/detail``
+#    - ``GET /flavors/{flavor_id}``
+#    - ``POST /flavors``
+
+flavor_description = {
+    'type': ['string', 'null'],
+    'minLength': 0, 'maxLength': 65535
+}
+
+flavor_extra_specs = {
+    'type': 'object',
+    'patternProperties': {
+        '^[a-zA-Z0-9-_:. ]{1,255}$': {'type': 'string'}
+    }
+}
+
+common_flavor_info = {
+    'type': 'object',
+    'properties': {
+        'name': {'type': 'string'},
+        'links': parameter_types.links,
+        'ram': {'type': 'integer'},
+        'vcpus': {'type': 'integer'},
+        # 'swap' attributes comes as integer value but if it is empty
+        # it comes as "". So defining type of as string and integer.
+        'swap': {'type': ['integer', 'string']},
+        'disk': {'type': 'integer'},
+        'id': {'type': 'string'},
+        'OS-FLV-DISABLED:disabled': {'type': 'boolean'},
+        'os-flavor-access:is_public': {'type': 'boolean'},
+        'rxtx_factor': {'type': 'number'},
+        'OS-FLV-EXT-DATA:ephemeral': {'type': 'integer'},
+        'description': flavor_description,
+        'extra_specs': flavor_extra_specs
+    },
+    'additionalProperties': False,
+    # 'OS-FLV-DISABLED', 'os-flavor-access', 'rxtx_factor' and
+    # 'OS-FLV-EXT-DATA' are API extensions. so they are not 'required'.
+    'required': ['name', 'links', 'ram', 'vcpus', 'swap', 'disk', 'id',
+                 'description']
+}
+
+list_flavors_details = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'flavors': {
+                'type': 'array',
+                'items': common_flavor_info
+            },
+            # NOTE(gmann): flavors_links attribute is not necessary
+            # to be present always so it is not 'required'.
+            'flavors_links': parameter_types.links
+        },
+        'additionalProperties': False,
+        'required': ['flavors']
+    }
+}
+
+create_update_get_flavor_details = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'flavor': common_flavor_info
+        },
+        'additionalProperties': False,
+        'required': ['flavor']
+    }
+}
+
+# ****** Schemas unchanged in microversion 2.61 since microversion 2.55 ***
+# Note(gmann): 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.
+list_flavors = copy.deepcopy(flavorsv255.list_flavors)
diff --git a/tempest/lib/services/compute/flavors_client.py b/tempest/lib/services/compute/flavors_client.py
index 4923d7e..a699579 100644
--- a/tempest/lib/services/compute/flavors_client.py
+++ b/tempest/lib/services/compute/flavors_client.py
@@ -23,6 +23,8 @@
     as schema_extra_specs
 from tempest.lib.api_schema.response.compute.v2_55 import flavors \
     as schemav255
+from tempest.lib.api_schema.response.compute.v2_61 import flavors \
+    as schemav261
 from tempest.lib.common import rest_client
 from tempest.lib.services.compute import base_compute_client
 
@@ -31,7 +33,8 @@
 
     schema_versions_info = [
         {'min': None, 'max': '2.54', 'schema': schema},
-        {'min': '2.55', 'max': None, 'schema': schemav255}]
+        {'min': '2.55', 'max': '2.60', 'schema': schemav255},
+        {'min': '2.61', 'max': None, 'schema': schemav261}]
 
     def list_flavors(self, detail=False, **params):
         """Lists flavors.