From 4af2c82068d1188a03c1c3ed422f85f512997b73 Mon Sep 17 00:00:00 2001 From: zhufl Date: Mon, 6 Aug 2018 14:38:53 +0800 Subject: [PATCH] Fill aggregate schema for microversion 2.41 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ‘uuid’ attribute of an aggregate is returned from calls to the /os-aggregates endpoint from microversion 2.41, so this is to add 'uuid' in schema of aggregate. https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id37 Change-Id: I90e53056ceae5ad6b6ea2995f3f8c6eceea4739a partially-implements: blueprint full-schema-for-all-microversions --- doc/source/microversion_testing.rst | 4 ++ tempest/api/compute/admin/test_aggregates.py | 34 ++++++++++-- .../response/compute/v2_41/__init__.py | 0 .../response/compute/v2_41/aggregates.py | 54 +++++++++++++++++++ .../lib/services/compute/aggregates_client.py | 17 +++++- 5 files changed, 105 insertions(+), 4 deletions(-) create mode 100644 tempest/lib/api_schema/response/compute/v2_41/__init__.py create mode 100644 tempest/lib/api_schema/response/compute/v2_41/aggregates.py diff --git a/doc/source/microversion_testing.rst b/doc/source/microversion_testing.rst index ce9bbb52a4..6677d0a24d 100644 --- a/doc/source/microversion_testing.rst +++ b/doc/source/microversion_testing.rst @@ -350,6 +350,10 @@ Microversion tests implemented in Tempest .. _2.39: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id35 + * `2.41`_ + + .. _2.41: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id37 + * `2.42`_ .. _2.42: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#maximum-in-ocata diff --git a/tempest/api/compute/admin/test_aggregates.py b/tempest/api/compute/admin/test_aggregates.py index d8faa33693..c9d5733ef1 100644 --- a/tempest/api/compute/admin/test_aggregates.py +++ b/tempest/api/compute/admin/test_aggregates.py @@ -25,17 +25,17 @@ from tempest.lib import decorators CONF = config.CONF -class AggregatesAdminTestJSON(base.BaseV2ComputeAdminTest): +class AggregatesAdminTestBase(base.BaseV2ComputeAdminTest): """Tests Aggregates API that require admin privileges""" @classmethod def setup_clients(cls): - super(AggregatesAdminTestJSON, cls).setup_clients() + super(AggregatesAdminTestBase, cls).setup_clients() cls.client = cls.os_admin.aggregates_client @classmethod def resource_setup(cls): - super(AggregatesAdminTestJSON, cls).resource_setup() + super(AggregatesAdminTestBase, cls).resource_setup() cls.aggregate_name_prefix = 'test_aggregate' cls.az_name_prefix = 'test_az' @@ -69,6 +69,9 @@ class AggregatesAdminTestJSON(base.BaseV2ComputeAdminTest): return aggregate + +class AggregatesAdminTestJSON(AggregatesAdminTestBase): + @decorators.idempotent_id('0d148aa3-d54c-4317-aa8d-42040a475e20') def test_aggregate_create_delete(self): # Create and delete an aggregate. @@ -226,3 +229,28 @@ class AggregatesAdminTestJSON(base.BaseV2ComputeAdminTest): wait_until='ACTIVE') body = admin_servers_client.show_server(server['id'])['server'] self.assertEqual(host, body['OS-EXT-SRV-ATTR:host']) + + +class AggregatesAdminTestV241(AggregatesAdminTestBase): + min_microversion = '2.41' + + # NOTE(gmann): This test tests the Aggregate APIs response schema + # for 2.41 microversion. No specific assert or behaviour verification + # is needed. + + @decorators.idempotent_id('fdf24d9e-8afa-4700-b6aa-9c498351504f') + def test_create_update_show_aggregate_add_remove_host(self): + # Update and add a host to the given aggregate and get details. + self.useFixture(fixtures.LockFixture('availability_zone')) + # Checking create aggregate API response schema + aggregate = self._create_test_aggregate() + + new_aggregate_name = data_utils.rand_name(self.aggregate_name_prefix) + # Checking update aggregate API response schema + self.client.update_aggregate(aggregate['id'], name=new_aggregate_name) + # Checking show aggregate API response schema + self.client.show_aggregate(aggregate['id'])['aggregate'] + # Checking add host to aggregate API response schema + self.client.add_host(aggregate['id'], host=self.host) + # Checking rempve host from aggregate API response schema + self.client.remove_host(aggregate['id'], host=self.host) diff --git a/tempest/lib/api_schema/response/compute/v2_41/__init__.py b/tempest/lib/api_schema/response/compute/v2_41/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tempest/lib/api_schema/response/compute/v2_41/aggregates.py b/tempest/lib/api_schema/response/compute/v2_41/aggregates.py new file mode 100644 index 0000000000..036bd83ca5 --- /dev/null +++ b/tempest/lib/api_schema/response/compute/v2_41/aggregates.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 aggregates + +# 'uuid' of an aggregate is returned in microversion 2.41 +aggregate_for_create = copy.deepcopy(aggregates.aggregate_for_create) +aggregate_for_create['properties'].update({'uuid': {'type': 'string', + 'format': 'uuid'}}) +aggregate_for_create['required'].append('uuid') + +common_aggregate_info = copy.deepcopy(aggregates.common_aggregate_info) +common_aggregate_info['properties'].update({'uuid': {'type': 'string', + 'format': 'uuid'}}) +common_aggregate_info['required'].append('uuid') + +list_aggregates = copy.deepcopy(aggregates.list_aggregates) +list_aggregates['response_body']['properties']['aggregates'].update( + {'items': common_aggregate_info}) + +get_aggregate = copy.deepcopy(aggregates.get_aggregate) +get_aggregate['response_body']['properties'].update( + {'aggregate': common_aggregate_info}) + +aggregate_set_metadata = get_aggregate + +update_aggregate = copy.deepcopy(aggregates.update_aggregate) +update_aggregate['response_body']['properties'].update( + {'aggregate': common_aggregate_info}) + +create_aggregate = copy.deepcopy(aggregates.create_aggregate) +create_aggregate['response_body']['properties'].update( + {'aggregate': aggregate_for_create}) + +aggregate_add_remove_host = get_aggregate + +# 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_aggregate = copy.deepcopy(aggregates.delete_aggregate) diff --git a/tempest/lib/services/compute/aggregates_client.py b/tempest/lib/services/compute/aggregates_client.py index 713d7a30bf..57f5e4e79a 100644 --- a/tempest/lib/services/compute/aggregates_client.py +++ b/tempest/lib/services/compute/aggregates_client.py @@ -15,7 +15,10 @@ from oslo_serialization import jsonutils as json -from tempest.lib.api_schema.response.compute.v2_1 import aggregates as schema +from tempest.lib.api_schema.response.compute.v2_1 \ + import aggregates as schema +from tempest.lib.api_schema.response.compute.v2_41 \ + import aggregates as schemav241 from tempest.lib.common import rest_client from tempest.lib import exceptions as lib_exc from tempest.lib.services.compute import base_compute_client @@ -23,10 +26,15 @@ from tempest.lib.services.compute import base_compute_client class AggregatesClient(base_compute_client.BaseComputeClient): + schema_versions_info = [ + {'min': None, 'max': '2.40', 'schema': schema}, + {'min': '2.41', 'max': None, 'schema': schemav241}] + def list_aggregates(self): """Get aggregate list.""" resp, body = self.get("os-aggregates") body = json.loads(body) + schema = self.get_schema(self.schema_versions_info) self.validate_response(schema.list_aggregates, resp, body) return rest_client.ResponseBody(resp, body) @@ -34,6 +42,7 @@ class AggregatesClient(base_compute_client.BaseComputeClient): """Get details of the given aggregate.""" resp, body = self.get("os-aggregates/%s" % aggregate_id) body = json.loads(body) + schema = self.get_schema(self.schema_versions_info) self.validate_response(schema.get_aggregate, resp, body) return rest_client.ResponseBody(resp, body) @@ -48,6 +57,7 @@ class AggregatesClient(base_compute_client.BaseComputeClient): resp, body = self.post('os-aggregates', post_body) body = json.loads(body) + schema = self.get_schema(self.schema_versions_info) self.validate_response(schema.create_aggregate, resp, body) return rest_client.ResponseBody(resp, body) @@ -62,12 +72,14 @@ class AggregatesClient(base_compute_client.BaseComputeClient): resp, body = self.put('os-aggregates/%s' % aggregate_id, put_body) body = json.loads(body) + schema = self.get_schema(self.schema_versions_info) self.validate_response(schema.update_aggregate, resp, body) return rest_client.ResponseBody(resp, body) def delete_aggregate(self, aggregate_id): """Delete the given aggregate.""" resp, body = self.delete("os-aggregates/%s" % aggregate_id) + schema = self.get_schema(self.schema_versions_info) self.validate_response(schema.delete_aggregate, resp, body) return rest_client.ResponseBody(resp, body) @@ -94,6 +106,7 @@ class AggregatesClient(base_compute_client.BaseComputeClient): resp, body = self.post('os-aggregates/%s/action' % aggregate_id, post_body) body = json.loads(body) + schema = self.get_schema(self.schema_versions_info) self.validate_response(schema.aggregate_add_remove_host, resp, body) return rest_client.ResponseBody(resp, body) @@ -108,6 +121,7 @@ class AggregatesClient(base_compute_client.BaseComputeClient): resp, body = self.post('os-aggregates/%s/action' % aggregate_id, post_body) body = json.loads(body) + schema = self.get_schema(self.schema_versions_info) self.validate_response(schema.aggregate_add_remove_host, resp, body) return rest_client.ResponseBody(resp, body) @@ -122,5 +136,6 @@ class AggregatesClient(base_compute_client.BaseComputeClient): resp, body = self.post('os-aggregates/%s/action' % aggregate_id, post_body) body = json.loads(body) + schema = self.get_schema(self.schema_versions_info) self.validate_response(schema.aggregate_set_metadata, resp, body) return rest_client.ResponseBody(resp, body)