From 4adae2fff6e78c306ddf28999589ef388464f4e8 Mon Sep 17 00:00:00 2001 From: Ken'ichi Ohmichi Date: Wed, 15 Mar 2017 15:47:44 -0700 Subject: [PATCH] Add "list Cinder API versions" Many projects provides multiple API versions and the version information is very important for users, because users can know what features are available on clouds. However, Tempest didn't test the Cinder API versions in long-term. So this patch adds the corresponding test. NOTE: This patch adds the response status code validation also for 300 but Cinder api-ref currently shows 200 and 202 also. These status codes are never returned actually and the patch Id28e26fca0adbdcfb0d905f52ca697a74db3be75 will fix it on Cinder side. Change-Id: Id5791665d8435fac7552733b0c1126cee4359d00 --- ...ion-to-volume-client-4769dd1bd4ab9c5e.yaml | 6 ++ tempest/api/volume/v3/base.py | 1 + tempest/api/volume/v3/test_versions.py | 28 ++++++ tempest/clients.py | 1 + .../api_schema/response/volume/__init__.py | 0 .../api_schema/response/volume/versions.py | 60 ++++++++++++ tempest/lib/services/volume/v3/__init__.py | 3 +- .../lib/services/volume/v3/versions_client.py | 47 ++++++++++ .../volume/v3/test_versions_client.py | 91 +++++++++++++++++++ 9 files changed, 236 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/add-list-version-to-volume-client-4769dd1bd4ab9c5e.yaml create mode 100644 tempest/api/volume/v3/test_versions.py create mode 100644 tempest/lib/api_schema/response/volume/__init__.py create mode 100644 tempest/lib/api_schema/response/volume/versions.py create mode 100644 tempest/lib/services/volume/v3/versions_client.py create mode 100644 tempest/tests/lib/services/volume/v3/test_versions_client.py diff --git a/releasenotes/notes/add-list-version-to-volume-client-4769dd1bd4ab9c5e.yaml b/releasenotes/notes/add-list-version-to-volume-client-4769dd1bd4ab9c5e.yaml new file mode 100644 index 0000000000..233cc287e8 --- /dev/null +++ b/releasenotes/notes/add-list-version-to-volume-client-4769dd1bd4ab9c5e.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + Add versions_client module for volume service. + This new module provides list_versions() method which shows API versions + from Volume service. diff --git a/tempest/api/volume/v3/base.py b/tempest/api/volume/v3/base.py index 31fc1ebfc2..7f76e6f526 100644 --- a/tempest/api/volume/v3/base.py +++ b/tempest/api/volume/v3/base.py @@ -45,6 +45,7 @@ class VolumesV3Test(api_version_utils.BaseMicroversionTest, def setup_clients(cls): super(VolumesV3Test, cls).setup_clients() cls.messages_client = cls.os.volume_v3_messages_client + cls.versions_client = cls.os.volume_v3_versions_client def setUp(self): super(VolumesV3Test, self).setUp() diff --git a/tempest/api/volume/v3/test_versions.py b/tempest/api/volume/v3/test_versions.py new file mode 100644 index 0000000000..20f16574ea --- /dev/null +++ b/tempest/api/volume/v3/test_versions.py @@ -0,0 +1,28 @@ +# Copyright 2017 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. + +from tempest.api.volume.v3 import base +from tempest.lib import decorators +from tempest import test + + +class VersionsTest(base.VolumesV3Test): + + @decorators.idempotent_id('77838fc4-b49b-4c64-9533-166762517369') + @test.attr(type='smoke') + def test_list_versions(self): + # NOTE: The version data is checked on service client side + # with JSON-Schema validation. It is enough to just call + # the API here. + self.versions_client.list_versions()['versions'] diff --git a/tempest/clients.py b/tempest/clients.py index e75fa7903e..06541105ed 100644 --- a/tempest/clients.py +++ b/tempest/clients.py @@ -265,6 +265,7 @@ class Manager(clients.ServiceClients): self.volumes_client = self.volume_v1.VolumesClient() self.volumes_v2_client = self.volume_v2.VolumesClient() self.volume_v3_messages_client = self.volume_v3.MessagesClient() + self.volume_v3_versions_client = self.volume_v3.VersionsClient() self.volume_types_client = self.volume_v1.TypesClient() self.volume_types_v2_client = self.volume_v2.TypesClient() self.volume_hosts_client = self.volume_v1.HostsClient() diff --git a/tempest/lib/api_schema/response/volume/__init__.py b/tempest/lib/api_schema/response/volume/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tempest/lib/api_schema/response/volume/versions.py b/tempest/lib/api_schema/response/volume/versions.py new file mode 100644 index 0000000000..2391a8c86e --- /dev/null +++ b/tempest/lib/api_schema/response/volume/versions.py @@ -0,0 +1,60 @@ +# Copyright 2015 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. + + +list_versions = { + 'status_code': [300], + 'response_body': { + 'type': 'object', + 'properties': { + 'versions': { + 'type': 'array', + 'items': { + 'type': 'object', + 'properties': { + 'status': {'type': 'string'}, + 'updated': {'type': 'string'}, + 'id': {'type': 'string'}, + 'links': { + 'type': 'array', + 'items': { + 'type': 'object', + 'properties': { + 'href': {'type': 'string', + 'format': 'uri'}, + 'rel': {'type': 'string'}, + 'type': {'type': 'string'}, + }, + 'required': ['href', 'rel'] + } + }, + 'min_version': {'type': 'string'}, + 'version': {'type': 'string'}, + 'media-types': { + 'type': 'array', + 'properties': { + 'base': {'type': 'string'}, + 'type': {'type': 'string'} + }, + 'required': ['base', 'type'] + } + }, + 'required': ['status', 'updated', 'id', 'links', + 'min_version', 'version', 'media-types'] + } + } + }, + 'required': ['versions'], + } +} diff --git a/tempest/lib/services/volume/v3/__init__.py b/tempest/lib/services/volume/v3/__init__.py index a4600a8b65..72ab785d43 100644 --- a/tempest/lib/services/volume/v3/__init__.py +++ b/tempest/lib/services/volume/v3/__init__.py @@ -14,5 +14,6 @@ from tempest.lib.services.volume.v3.base_client import BaseClient from tempest.lib.services.volume.v3.messages_client import MessagesClient +from tempest.lib.services.volume.v3.versions_client import VersionsClient -__all__ = ['MessagesClient', 'BaseClient'] +__all__ = ['MessagesClient', 'BaseClient', 'VersionsClient'] diff --git a/tempest/lib/services/volume/v3/versions_client.py b/tempest/lib/services/volume/v3/versions_client.py new file mode 100644 index 0000000000..e2941c4b9b --- /dev/null +++ b/tempest/lib/services/volume/v3/versions_client.py @@ -0,0 +1,47 @@ +# Copyright 2017 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 time + +from oslo_serialization import jsonutils as json + +from tempest.lib.api_schema.response.volume import versions as schema +from tempest.lib.common import rest_client +from tempest.lib.services.volume.v3 import base_client + + +class VersionsClient(base_client.BaseClient): + + def list_versions(self): + """List API versions + + For a full list of available parameters, please refer to the official + API reference: + https://developer.openstack.org/api-ref/block-storage/v3/#list-all-api-versions + """ + version_url = self._get_base_version_url() + + start = time.time() + resp, body = self.raw_request(version_url, 'GET') + end = time.time() + # NOTE: We need a raw_request() here instead of request() call because + # "list API versions" API doesn't require an authentication and we can + # skip it with raw_request() call. + self._log_request('GET', version_url, resp, secs=(end - start), + resp_body=body) + self._error_checker(resp, body) + + body = json.loads(body) + self.validate_response(schema.list_versions, resp, body) + return rest_client.ResponseBody(resp, body) diff --git a/tempest/tests/lib/services/volume/v3/test_versions_client.py b/tempest/tests/lib/services/volume/v3/test_versions_client.py new file mode 100644 index 0000000000..9627b9a2be --- /dev/null +++ b/tempest/tests/lib/services/volume/v3/test_versions_client.py @@ -0,0 +1,91 @@ +# Copyright 2017 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. + +from tempest.lib.services.volume.v3 import versions_client +from tempest.tests.lib import fake_auth_provider +from tempest.tests.lib.services import base + + +class TestVersionsClient(base.BaseServiceTest): + + FAKE_VERSIONS_INFO = { + "versions": [ + { + "status": "DEPRECATED", "updated": "2016-05-02T20:25:19Z", + "links": [ + {"href": "http://docs.openstack.org/", "type": "text/html", + "rel": "describedby"}, + {"href": "https://10.30.197.39:8776/v1/", "rel": "self"} + ], + "min_version": "", + "version": "", + "media-types": [ + {"base": "application/json", + "type": "application/vnd.openstack.volume+json;version=1"} + ], + "id": "v1.0" + }, + { + "status": "DEPRECATED", "updated": "2017-02-25T12:00:00Z", + "links": [ + {"href": "http://docs.openstack.org/", "type": "text/html", + "rel": "describedby"}, + {"href": "https://10.30.197.39:8776/v2/", "rel": "self"} + ], + "min_version": "", + "version": "", + "media-types": [ + {"base": "application/json", + "type": "application/vnd.openstack.volume+json;version=1"} + ], + "id": "v2.0" + }, + { + "status": "CURRENT", "updated": "2016-02-08T12:20:21Z", + "links": [ + {"href": "http://docs.openstack.org/", "type": "text/html", + "rel": "describedby"}, + {"href": "https://10.30.197.39:8776/v3/", "rel": "self"} + ], + "min_version": "3.0", + "version": "3.28", + "media-types": [ + {"base": "application/json", + "type": "application/vnd.openstack.volume+json;version=1"} + ], + "id": "v3.0" + } + ] + } + + def setUp(self): + super(TestVersionsClient, self).setUp() + fake_auth = fake_auth_provider.FakeAuthProvider() + self.client = versions_client.VersionsClient(fake_auth, + 'volume', + 'regionOne') + + def _test_list_versions(self, bytes_body=False): + self.check_service_client_function( + self.client.list_versions, + 'tempest.lib.common.rest_client.RestClient.raw_request', + self.FAKE_VERSIONS_INFO, + bytes_body, + 300) + + def test_list_versions_with_str_body(self): + self._test_list_versions() + + def test_list_versions_with_bytes_body(self): + self._test_list_versions(bytes_body=True)