From e973452ce0802c997872db4a1b970298441fad74 Mon Sep 17 00:00:00 2001 From: zhufl Date: Sun, 30 Sep 2018 16:07:08 +0800 Subject: [PATCH] Add response schema validation for encryption types This is to add response schema validation for encryption types. Change-Id: Ic8e1dddd4a7e7bc57cc2959f1a7991dd4be22194 partially-implements: blueprint volume-response-schema-validation --- tempest/api/volume/admin/test_volume_types.py | 1 - .../response/volume/encryption_types.py | 95 +++++++++++++++++++ .../volume/v3/encryption_types_client.py | 11 ++- .../volume/v3/test_encryption_types_client.py | 4 +- 4 files changed, 103 insertions(+), 8 deletions(-) create mode 100755 tempest/lib/api_schema/response/volume/encryption_types.py diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py index 9e2417625e..fcaace7b1a 100644 --- a/tempest/api/volume/admin/test_volume_types.py +++ b/tempest/api/volume/admin/test_volume_types.py @@ -130,7 +130,6 @@ class VolumeTypesTest(base.BaseVolumeAdminTest): 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 0000000000..7e7ca4add4 --- /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 bd809d698c..7cced57c28 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 @@ class EncryptionTypesClient(rest_client.RestClient): 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 @@ class EncryptionTypesClient(rest_client.RestClient): 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 @@ class EncryptionTypesClient(rest_client.RestClient): 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 @@ class EncryptionTypesClient(rest_client.RestClient): 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 70a3ee5a85..7218224257 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 @@ from tempest.tests.lib.services import base 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" } }