From 15d1a00a57e2792d9f8ce254e133c9ddc0d364a9 Mon Sep 17 00:00:00 2001 From: whoami-rajat Date: Thu, 24 Jan 2019 16:32:14 +0530 Subject: [PATCH] Automate generation of volume actions api-ref samples This patch adds the following tests: 1) Volume actions 2) Volume manage extensions Change-Id: I7f27a336a6735f4d346cc47c983dfee55f47f55d Partially-Implements: blueprint generating-sample-files --- .../v3/samples/volume-manage-response.json | 33 ------------ .../volume-upload-to-image-request.json | 0 .../volume-upload-to-image-response.json | 16 +++--- .../volume-manage-request.json | 2 +- .../volume-manage-response.json | 17 +++++++ api-ref/source/v3/volume-manage.inc | 4 +- .../source/v3/volumes-v3-volumes-actions.inc | 4 +- cinder/test.py | 11 ++++ .../functional/api_sample_tests/fakes.py | 51 +++++++++++++++++++ .../volume-upload-to-image-request.json.tpl | 8 +++ .../volume-upload-to-image-response.json.tpl | 16 ++++++ .../volume-manage-request.json.tpl | 18 +++++++ .../volume-manage-response.json.tpl | 17 +++++++ .../api_sample_tests/test_volume_actions.py | 34 +++++++++++++ .../test_volume_manage_extensions.py | 36 +++++++++++++ .../api_sample_tests/test_volumes.py | 28 ++++++---- .../tests/functional/api_samples_test_base.py | 15 ++++-- 17 files changed, 252 insertions(+), 58 deletions(-) delete mode 100644 api-ref/source/v3/samples/volume-manage-response.json rename api-ref/source/v3/samples/{ => volume_actions}/volume-upload-to-image-request.json (100%) rename api-ref/source/v3/samples/{ => volume_actions}/volume-upload-to-image-response.json (88%) rename api-ref/source/v3/samples/{ => volume_manage_extensions}/volume-manage-request.json (99%) create mode 100644 api-ref/source/v3/samples/volume_manage_extensions/volume-manage-response.json create mode 100644 cinder/tests/functional/api_sample_tests/fakes.py create mode 100644 cinder/tests/functional/api_sample_tests/samples/volume_actions/volume-upload-to-image-request.json.tpl create mode 100644 cinder/tests/functional/api_sample_tests/samples/volume_actions/volume-upload-to-image-response.json.tpl create mode 100644 cinder/tests/functional/api_sample_tests/samples/volume_manage_extensions/volume-manage-request.json.tpl create mode 100644 cinder/tests/functional/api_sample_tests/samples/volume_manage_extensions/volume-manage-response.json.tpl create mode 100644 cinder/tests/functional/api_sample_tests/test_volume_actions.py create mode 100644 cinder/tests/functional/api_sample_tests/test_volume_manage_extensions.py diff --git a/api-ref/source/v3/samples/volume-manage-response.json b/api-ref/source/v3/samples/volume-manage-response.json deleted file mode 100644 index a53976b9cba..00000000000 --- a/api-ref/source/v3/samples/volume-manage-response.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "volume": { - "status": "creating", - "user_id": "eae1472b5fc5496998a3d06550929e7e", - "attachments": [], - "links": [ - { - "href": "http://10.0.2.15:8776/v3/87c8522052ca4eed98bc672b4c1a3ddb/volumes/23cf872b-c781-4cd4-847d-5f2ec8cbd91c", - "rel": "self" - }, - { - "href": "http://10.0.2.15:8776/87c8522052ca4eed98bc672b4c1a3ddb/volumes/23cf872b-c781-4cd4-847d-5f2ec8cbd91c", - "rel": "bookmark" - } - ], - "availability_zone": "az2", - "bootable": "false", - "encrypted": "false", - "created_at": "2014-07-18T00:12:54.000000", - "description": "Volume imported from existingLV", - "os-vol-tenant-attr:tenant_id": "87c8522052ca4eed98bc672b4c1a3ddb", - "volume_type": null, - "name": "New Volume", - "source_volid": null, - "snapshot_id": null, - "metadata": { - "key2": "value2", - "key1": "value1" - }, - "id": "23cf872b-c781-4cd4-847d-5f2ec8cbd91c", - "size": 0 - } -} diff --git a/api-ref/source/v3/samples/volume-upload-to-image-request.json b/api-ref/source/v3/samples/volume_actions/volume-upload-to-image-request.json similarity index 100% rename from api-ref/source/v3/samples/volume-upload-to-image-request.json rename to api-ref/source/v3/samples/volume_actions/volume-upload-to-image-request.json diff --git a/api-ref/source/v3/samples/volume-upload-to-image-response.json b/api-ref/source/v3/samples/volume_actions/volume-upload-to-image-response.json similarity index 88% rename from api-ref/source/v3/samples/volume-upload-to-image-response.json rename to api-ref/source/v3/samples/volume_actions/volume-upload-to-image-response.json index bed27298b15..900acbd8853 100644 --- a/api-ref/source/v3/samples/volume-upload-to-image-response.json +++ b/api-ref/source/v3/samples/volume_actions/volume-upload-to-image-response.json @@ -1,16 +1,16 @@ { "os-volume_upload_image": { - "status": "uploading", "container_format": "bare", - "image_name": "test", - "visibility": "private", - "updated_at": "2017-06-05T08:44:28.000000", - "image_id": "de75b74e-7f0d-4b59-a263-bd87bfc313bd", + "disk_format": "raw", "display_description": null, "id": "3a81fdac-e8ae-4e61-b6a2-2e14ff316f19", + "image_id": "de75b74e-7f0d-4b59-a263-bd87bfc313bd", + "image_name": "test", + "protected": false, "size": 1, - "disk_format": "raw", - "volume_type": null, - "protected": false + "status": "uploading", + "updated_at": "2017-06-05T08:44:28.000000", + "visibility": "private", + "volume_type": null } } \ No newline at end of file diff --git a/api-ref/source/v3/samples/volume-manage-request.json b/api-ref/source/v3/samples/volume_manage_extensions/volume-manage-request.json similarity index 99% rename from api-ref/source/v3/samples/volume-manage-request.json rename to api-ref/source/v3/samples/volume_manage_extensions/volume-manage-request.json index 36321478437..a78eb2e6e4b 100644 --- a/api-ref/source/v3/samples/volume-manage-request.json +++ b/api-ref/source/v3/samples/volume_manage_extensions/volume-manage-request.json @@ -15,4 +15,4 @@ "key2": "value2" } } -} +} \ No newline at end of file diff --git a/api-ref/source/v3/samples/volume_manage_extensions/volume-manage-response.json b/api-ref/source/v3/samples/volume_manage_extensions/volume-manage-response.json new file mode 100644 index 00000000000..2d1c9d5b878 --- /dev/null +++ b/api-ref/source/v3/samples/volume_manage_extensions/volume-manage-response.json @@ -0,0 +1,17 @@ +{ + "availability_zone": "az2", + "bootable": true, + "cluster": "cluster@backend", + "description": "Volume imported from existingLV", + "host": "null", + "metadata": { + "key1": "value1", + "key2": "value2" + }, + "name": "New Volume", + "ref": { + "source-id": "1234", + "source-name": "existingLV" + }, + "volume_type": "null" +} \ No newline at end of file diff --git a/api-ref/source/v3/volume-manage.inc b/api-ref/source/v3/volume-manage.inc index bddfb1a15b4..1a28e3c0108 100644 --- a/api-ref/source/v3/volume-manage.inc +++ b/api-ref/source/v3/volume-manage.inc @@ -56,7 +56,7 @@ Request Request Example --------------- -.. literalinclude:: ./samples/volume-manage-request.json +.. literalinclude:: ./samples/volume_manage_extensions/volume-manage-request.json :language: javascript .. literalinclude:: ./samples/volume-manage-request-cluster.json @@ -94,7 +94,7 @@ Response Response Example ---------------- -.. literalinclude:: ./samples/volume-manage-response.json +.. literalinclude:: ./samples/volume_manage_extensions/volume-manage-response.json :language: javascript diff --git a/api-ref/source/v3/volumes-v3-volumes-actions.inc b/api-ref/source/v3/volumes-v3-volumes-actions.inc index edc66e4c49e..e7f2640c09a 100644 --- a/api-ref/source/v3/volumes-v3-volumes-actions.inc +++ b/api-ref/source/v3/volumes-v3-volumes-actions.inc @@ -644,7 +644,7 @@ Request Request Example --------------- -.. literalinclude:: ./samples/volume-upload-to-image-request.json +.. literalinclude:: ./samples/volume_actions/volume-upload-to-image-request.json :language: javascript Response Parameters @@ -670,7 +670,7 @@ Response Parameters Response Example ---------------- -.. literalinclude:: ./samples/volume-upload-to-image-response.json +.. literalinclude:: ./samples/volume_actions/volume-upload-to-image-response.json :language: javascript diff --git a/cinder/test.py b/cinder/test.py index f5326e628f8..8f8f65434ac 100644 --- a/cinder/test.py +++ b/cinder/test.py @@ -437,6 +437,17 @@ class TestCase(testtools.TestCase): kwargs.setdefault('message', msg) self.assertIs(False, x, *args, **kwargs) + def stub_out(self, old, new): + """Replace a function for the duration of the test. + + Use the monkey patch fixture to replace a function for the + duration of a test. Useful when you want to provide fake + methods instead of mocks during testing. + This should be used instead of self.stubs.Set (which is based + on mox) going forward. + """ + self.useFixture(fixtures.MonkeyPatch(old, new)) + class ModelsObjectComparatorMixin(object): def _dict_from_object(self, obj, ignored_keys): diff --git a/cinder/tests/functional/api_sample_tests/fakes.py b/cinder/tests/functional/api_sample_tests/fakes.py new file mode 100644 index 00000000000..65b03cfac90 --- /dev/null +++ b/cinder/tests/functional/api_sample_tests/fakes.py @@ -0,0 +1,51 @@ +# 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. + + +def stub_copy_volume_to_image(self, context, volume, metadata, force): + image_metadata = { + "status": "uploading", + "container_format": "bare", + "image_name": "test", + "visibility": "private", + "updated_at": "2017-06-05T08:44:28.000000", + "image_id": "de75b74e-7f0d-4b59-a263-bd87bfc313bd", + "display_description": None, + "id": "3a81fdac-e8ae-4e61-b6a2-2e14ff316f19", + "size": 1, + "disk_format": "raw", + "volume_type": None, + "protected": False + } + return image_metadata + + +def stub_manage_existing(self, req, body): + volume = { + "host": "null", + "cluster": "cluster@backend", + "ref": { + "source-name": "existingLV", + "source-id": "1234" + }, + "name": "New Volume", + "availability_zone": "az2", + "description": "Volume imported from existingLV", + "volume_type": "null", + "bootable": True, + "metadata": { + "key1": "value1", + "key2": "value2" + } + } + + return volume diff --git a/cinder/tests/functional/api_sample_tests/samples/volume_actions/volume-upload-to-image-request.json.tpl b/cinder/tests/functional/api_sample_tests/samples/volume_actions/volume-upload-to-image-request.json.tpl new file mode 100644 index 00000000000..03f142e1f3d --- /dev/null +++ b/cinder/tests/functional/api_sample_tests/samples/volume_actions/volume-upload-to-image-request.json.tpl @@ -0,0 +1,8 @@ +{ + "os-volume_upload_image":{ + "image_name": "test", + "force": false, + "disk_format": "raw", + "container_format": "bare" + } +} \ No newline at end of file diff --git a/cinder/tests/functional/api_sample_tests/samples/volume_actions/volume-upload-to-image-response.json.tpl b/cinder/tests/functional/api_sample_tests/samples/volume_actions/volume-upload-to-image-response.json.tpl new file mode 100644 index 00000000000..900acbd8853 --- /dev/null +++ b/cinder/tests/functional/api_sample_tests/samples/volume_actions/volume-upload-to-image-response.json.tpl @@ -0,0 +1,16 @@ +{ + "os-volume_upload_image": { + "container_format": "bare", + "disk_format": "raw", + "display_description": null, + "id": "3a81fdac-e8ae-4e61-b6a2-2e14ff316f19", + "image_id": "de75b74e-7f0d-4b59-a263-bd87bfc313bd", + "image_name": "test", + "protected": false, + "size": 1, + "status": "uploading", + "updated_at": "2017-06-05T08:44:28.000000", + "visibility": "private", + "volume_type": null + } +} \ No newline at end of file diff --git a/cinder/tests/functional/api_sample_tests/samples/volume_manage_extensions/volume-manage-request.json.tpl b/cinder/tests/functional/api_sample_tests/samples/volume_manage_extensions/volume-manage-request.json.tpl new file mode 100644 index 00000000000..8d23d2f1f71 --- /dev/null +++ b/cinder/tests/functional/api_sample_tests/samples/volume_manage_extensions/volume-manage-request.json.tpl @@ -0,0 +1,18 @@ +{ + "volume": { + "host": "%(host)s", + "ref": { + "source-name": "existingLV", + "source-id": "1234" + }, + "name": "New Volume", + "availability_zone": "az2", + "description": "Volume imported from existingLV", + "volume_type": null, + "bootable": true, + "metadata": { + "key1": "value1", + "key2": "value2" + } + } +} diff --git a/cinder/tests/functional/api_sample_tests/samples/volume_manage_extensions/volume-manage-response.json.tpl b/cinder/tests/functional/api_sample_tests/samples/volume_manage_extensions/volume-manage-response.json.tpl new file mode 100644 index 00000000000..2d1c9d5b878 --- /dev/null +++ b/cinder/tests/functional/api_sample_tests/samples/volume_manage_extensions/volume-manage-response.json.tpl @@ -0,0 +1,17 @@ +{ + "availability_zone": "az2", + "bootable": true, + "cluster": "cluster@backend", + "description": "Volume imported from existingLV", + "host": "null", + "metadata": { + "key1": "value1", + "key2": "value2" + }, + "name": "New Volume", + "ref": { + "source-id": "1234", + "source-name": "existingLV" + }, + "volume_type": "null" +} \ No newline at end of file diff --git a/cinder/tests/functional/api_sample_tests/test_volume_actions.py b/cinder/tests/functional/api_sample_tests/test_volume_actions.py new file mode 100644 index 00000000000..65ba81b8814 --- /dev/null +++ b/cinder/tests/functional/api_sample_tests/test_volume_actions.py @@ -0,0 +1,34 @@ +# 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 oslo_serialization import jsonutils + +from cinder.tests.functional.api_sample_tests import fakes +from cinder.tests.functional.api_sample_tests import test_volumes + + +class VolumeActionsSampleJsonTest(test_volumes.VolumesSampleBase): + sample_dir = "volume_actions" + + def setUp(self): + super(VolumeActionsSampleJsonTest, self).setUp() + self.response = self._create_volume() + self.stub_out("cinder.volume.api.API.copy_volume_to_image", + fakes.stub_copy_volume_to_image) + + def test_volume_upload_image(self): + res = jsonutils.loads(self.response.content)['volume'] + self._poll_volume_while(res['id'], ['creating']) + response = self._do_post('volumes/%s/action' % res['id'], + 'volume-upload-to-image-request') + self._verify_response('volume-upload-to-image-response', + {}, response, 202) diff --git a/cinder/tests/functional/api_sample_tests/test_volume_manage_extensions.py b/cinder/tests/functional/api_sample_tests/test_volume_manage_extensions.py new file mode 100644 index 00000000000..51363e5b179 --- /dev/null +++ b/cinder/tests/functional/api_sample_tests/test_volume_manage_extensions.py @@ -0,0 +1,36 @@ +# 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 cinder.tests.functional.api_sample_tests import fakes +from cinder.tests.functional import api_samples_test_base + +FAKE_HOST = 'hostname@backend' + + +class VolumeActionsSampleJsonTest(api_samples_test_base.ApiSampleTestBase): + sample_dir = "volume_manage_extensions" + + def setUp(self): + super(VolumeActionsSampleJsonTest, self).setUp() + self.subs = { + 'host': FAKE_HOST + } + self.stub_out("cinder.api.contrib.volume_manage." + "VolumeManageController.create", + fakes.stub_manage_existing) + + def test_manage_existing(self): + response = self._do_post('os-volume-manage', + 'volume-manage-request', + subs=self.subs) + self._verify_response('volume-manage-response', + {}, response, 202) diff --git a/cinder/tests/functional/api_sample_tests/test_volumes.py b/cinder/tests/functional/api_sample_tests/test_volumes.py index 696a4ac10f1..8f26ad2145c 100644 --- a/cinder/tests/functional/api_sample_tests/test_volumes.py +++ b/cinder/tests/functional/api_sample_tests/test_volumes.py @@ -15,20 +15,30 @@ from oslo_serialization import jsonutils from cinder.tests.functional import api_samples_test_base -class VolumesSampleJsonTest(api_samples_test_base.ApiSampleTestBase): +class VolumesSampleBase(api_samples_test_base.ApiSampleTestBase): sample_dir = "volumes" + def _create_volume(self, _use_common_volume_api_samples=True, subs=None): + + orig_value = self.__class__._use_common_volume_api_samples + try: + self.__class__._use_common_volume_api_samples = ( + _use_common_volume_api_samples) + response = self._do_post('volumes', + 'volume-create-request', + subs) + return response + + finally: + self.__class__._use_common_volume_api_samples = orig_value + + +class VolumesSampleJsonTest(VolumesSampleBase): + def setUp(self): - super(VolumesSampleJsonTest, self).setUp() + super(VolumesSampleBase, self).setUp() self.response = self._create_volume() - def _create_volume(self, subs=None): - - response = self._do_post('volumes', - 'volume-create-request', - subs) - return response - def test_volume_list_detail(self): response = self._do_get('volumes/detail') diff --git a/cinder/tests/functional/api_samples_test_base.py b/cinder/tests/functional/api_samples_test_base.py index 14bc070e323..fed4aa32f61 100644 --- a/cinder/tests/functional/api_samples_test_base.py +++ b/cinder/tests/functional/api_samples_test_base.py @@ -67,6 +67,7 @@ class ApiSampleTestBase(functional_helpers._FunctionalTestBase): all_extensions = True sample_dir = None _project_id = True + _use_common_volume_api_samples = False def __init__(self, *args, **kwargs): super(ApiSampleTestBase, self).__init__(*args, **kwargs) @@ -100,9 +101,17 @@ class ApiSampleTestBase(functional_helpers._FunctionalTestBase): def _get_sample_path(cls, name, dirname, suffix='', api_version=None): parts = [dirname] parts.append('samples') - parts.append(cls.sample_dir) - if api_version: - parts.append('v' + api_version) + # Note: if _use_common_volume_api_samples is set to True + # then common volume sample files present in 'volumes' directory + # will be used. As of now it is being used for volume POST request + # to avoid duplicate copy of volume req and resp sample files. + # Example - VolumesSampleBase's _create_volume method. + if cls._use_common_volume_api_samples: + parts.append('volumes') + else: + parts.append(cls.sample_dir) + if api_version: + parts.append('v' + api_version) parts.append(name + ".json" + suffix) return os.path.join(*parts)