Merge "Add response schema validation for encryption types"
diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py
index c1ceeb7..ecc850e 100644
--- a/tempest/api/volume/admin/test_volume_types.py
+++ b/tempest/api/volume/admin/test_volume_types.py
@@ -127,7 +127,6 @@
         encryption_type = \
             self.admin_encryption_types_client.create_encryption_type(
                 volume_type_id, **create_kwargs)['encryption']
-        self.assertIn('volume_type_id', encryption_type)
         for key in create_kwargs:
             self.assertEqual(create_kwargs[key], encryption_type[key],
                              'The created encryption_type %s is different '
diff --git a/tempest/lib/api_schema/response/volume/encryption_types.py b/tempest/lib/api_schema/response/volume/encryption_types.py
new file mode 100755
index 0000000..7e7ca4a
--- /dev/null
+++ b/tempest/lib/api_schema/response/volume/encryption_types.py
@@ -0,0 +1,95 @@
+# Copyright 2019 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.
+
+from tempest.lib.api_schema.response.compute.v2_1 import parameter_types
+
+show_encryption_type = {
+    'status_code': [200],
+    'response_body': {
+        'type': ['object', 'null'],
+        'properties': {
+            'volume_type_id': {'type': 'string', 'format': 'uuid'},
+            'encryption_id': {'type': 'string', 'format': 'uuid'},
+            'key_size': {'type': ['integer', 'null']},
+            'provider': {'type': 'string'},
+            'control_location': {'enum': ['front-end', 'back-end']},
+            'cipher': {'type': ['string', 'null']},
+            'deleted': {'type': 'boolean'},
+            'created_at': parameter_types.date_time,
+            'updated_at': parameter_types.date_time_or_null,
+            'deleted_at': parameter_types.date_time_or_null
+        },
+        # result of show_encryption_type may be empty list,
+        # so no required fields.
+        'additionalProperties': False,
+    }
+}
+
+show_encryption_specs_item = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'patternProperties': {
+            '^.+$': {'type': 'string'}
+        }
+    }
+}
+
+create_encryption_type = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'encryption': {
+                'type': 'object',
+                'properties': {
+                    'volume_type_id': {'type': 'string', 'format': 'uuid'},
+                    'encryption_id': {'type': 'string', 'format': 'uuid'},
+                    'key_size': {'type': ['integer', 'null']},
+                    'provider': {'type': 'string'},
+                    'control_location': {'enum': ['front-end', 'back-end']},
+                    'cipher': {'type': ['string', 'null']},
+                },
+                'additionalProperties': False,
+                'required': ['volume_type_id', 'encryption_id']
+            }
+        },
+        'additionalProperties': False,
+        'required': ['encryption']
+    }
+}
+
+delete_encryption_type = {'status_code': [202]}
+
+update_encryption_type = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'encryption': {
+                'type': 'object',
+                'properties': {
+                    'key_size': {'type': ['integer', 'null']},
+                    'provider': {'type': 'string'},
+                    'control_location': {'enum': ['front-end', 'back-end']},
+                    'cipher': {'type': ['string', 'null']},
+                },
+                # all fields are optional
+                'additionalProperties': False,
+            }
+        },
+        'additionalProperties': False,
+        'required': ['encryption']
+    }
+}
diff --git a/tempest/lib/services/volume/v3/encryption_types_client.py b/tempest/lib/services/volume/v3/encryption_types_client.py
index bd809d6..7cced57 100644
--- a/tempest/lib/services/volume/v3/encryption_types_client.py
+++ b/tempest/lib/services/volume/v3/encryption_types_client.py
@@ -15,6 +15,7 @@
 
 from oslo_serialization import jsonutils as json
 
+from tempest.lib.api_schema.response.volume import encryption_types as schema
 from tempest.lib.common import rest_client
 from tempest.lib import exceptions as lib_exc
 
@@ -43,7 +44,7 @@
         url = "/types/%s/encryption" % volume_type_id
         resp, body = self.get(url)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(schema.show_encryption_type, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def show_encryption_specs_item(self, volume_type_id, key):
@@ -51,7 +52,7 @@
         url = "/types/%s/encryption/%s" % (volume_type_id, key)
         resp, body = self.get(url)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(schema.show_encryption_specs_item, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def create_encryption_type(self, volume_type_id, **kwargs):
@@ -65,14 +66,14 @@
         post_body = json.dumps({'encryption': kwargs})
         resp, body = self.post(url, post_body)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(schema.create_encryption_type, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def delete_encryption_type(self, volume_type_id):
         """Delete the encryption type for the specified volume-type."""
         resp, body = self.delete(
             "/types/%s/encryption/provider" % volume_type_id)
-        self.expected_success(202, resp.status)
+        self.validate_response(schema.delete_encryption_type, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def update_encryption_type(self, volume_type_id, **kwargs):
@@ -86,5 +87,5 @@
         put_body = json.dumps({'encryption': kwargs})
         resp, body = self.put(url, put_body)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(schema.update_encryption_type, resp, body)
         return rest_client.ResponseBody(resp, body)
diff --git a/tempest/tests/lib/services/volume/v3/test_encryption_types_client.py b/tempest/tests/lib/services/volume/v3/test_encryption_types_client.py
index 70a3ee5..7218224 100644
--- a/tempest/tests/lib/services/volume/v3/test_encryption_types_client.py
+++ b/tempest/tests/lib/services/volume/v3/test_encryption_types_client.py
@@ -20,11 +20,11 @@
 class TestEncryptionTypesClient(base.BaseServiceTest):
     FAKE_CREATE_ENCRYPTION_TYPE = {
         "encryption": {
-            "volume_type_id": "cbc36478b0bd8e67e89",
+            "volume_type_id": "2d29462d-76cb-417c-8a9f-fb23140f1577",
             "control_location": "front-end",
             "encryption_id": "81e069c6-7394-4856-8df7-3b237ca61f74",
             "key_size": 128,
-            "provider": "LuksEncryptor",
+            "provider": "luks",
             "cipher": "aes-xts-plain64"
         }
     }