Merge "Add test case for group type specs APIs"
diff --git a/releasenotes/notes/add-group-type-specs-apis-to-v3-group-types-client-10390b52dedede54.yaml b/releasenotes/notes/add-group-type-specs-apis-to-v3-group-types-client-10390b52dedede54.yaml
new file mode 100644
index 0000000..404319d
--- /dev/null
+++ b/releasenotes/notes/add-group-type-specs-apis-to-v3-group-types-client-10390b52dedede54.yaml
@@ -0,0 +1,10 @@
+---
+features:
+ - |
+ Add group type specs APIs to v3 group_types_client library.
+
+ * create_or_update_group_type_specs
+ * list_group_type_specs
+ * show_group_type_specs_item
+ * update_group_type_specs_item
+ * delete_group_type_specs_item
diff --git a/tempest/api/volume/admin/test_group_type_specs.py b/tempest/api/volume/admin/test_group_type_specs.py
new file mode 100644
index 0000000..c5e6d1a
--- /dev/null
+++ b/tempest/api/volume/admin/test_group_type_specs.py
@@ -0,0 +1,80 @@
+# Copyright 2017 FiberHome Telecommunication Technologies CO.,LTD
+# 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 import base
+from tempest.lib import decorators
+from tempest.lib import exceptions as lib_exc
+
+
+class GroupTypeSpecsTest(base.BaseVolumeAdminTest):
+ _api_version = 3
+ min_microversion = '3.11'
+ max_microversion = 'latest'
+
+ @decorators.idempotent_id('bb4e30d0-de6e-4f4d-866c-dcc48d023b4e')
+ def test_group_type_specs_create_show_update_list_delete(self):
+ # Create new group type
+ group_type = self.create_group_type()
+
+ # Create new group type specs
+ create_specs = {
+ "key1": "value1",
+ "key2": "value2"
+ }
+ body = self.admin_group_types_client.create_or_update_group_type_specs(
+ group_type['id'], create_specs)['group_specs']
+ self.assertEqual(create_specs, body)
+
+ # Create a new group type spec and update an existing group type spec
+ update_specs = {
+ "key2": "value2-updated",
+ "key3": "value3"
+ }
+ body = self.admin_group_types_client.create_or_update_group_type_specs(
+ group_type['id'], update_specs)['group_specs']
+ self.assertEqual(update_specs, body)
+
+ # Show specified item of group type specs
+ spec_keys = ['key2', 'key3']
+ for key in spec_keys:
+ body = self.admin_group_types_client.show_group_type_specs_item(
+ group_type['id'], key)
+ self.assertIn(key, body)
+ self.assertEqual(update_specs[key], body[key])
+
+ # Update specified item of group type specs
+ update_key = 'key3'
+ update_spec = {update_key: "value3-updated"}
+ body = self.admin_group_types_client.update_group_type_specs_item(
+ group_type['id'], update_key, update_spec)
+ self.assertEqual(update_spec, body)
+
+ # List all group type specs that created or updated above
+ list_specs = {}
+ list_specs.update(create_specs)
+ list_specs.update(update_specs)
+ list_specs.update(update_spec)
+ body = self.admin_group_types_client.list_group_type_specs(
+ group_type['id'])['group_specs']
+ self.assertEqual(list_specs, body)
+
+ # Delete specified item of group type specs
+ delete_key = 'key1'
+ self.admin_group_types_client.delete_group_type_specs_item(
+ group_type['id'], delete_key)
+ self.assertRaises(
+ lib_exc.NotFound,
+ self.admin_group_types_client.show_group_type_specs_item,
+ group_type['id'], delete_key)
diff --git a/tempest/lib/services/volume/v3/group_types_client.py b/tempest/lib/services/volume/v3/group_types_client.py
index 6181472..1b47201 100644
--- a/tempest/lib/services/volume/v3/group_types_client.py
+++ b/tempest/lib/services/volume/v3/group_types_client.py
@@ -88,3 +88,54 @@
self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
+
+ def create_or_update_group_type_specs(self, group_type_id, group_specs):
+ """Creates new group specs or updates existing group specs.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ https://developer.openstack.org/api-ref/block-storage/v3/#create-group-specs-for-a-group-type
+ """
+ url = "group_types/%s/group_specs" % group_type_id
+ post_body = json.dumps({'group_specs': group_specs})
+ resp, body = self.post(url, post_body)
+ body = json.loads(body)
+ self.expected_success(202, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def list_group_type_specs(self, group_type_id):
+ """Lists all group specs for a given group type."""
+ url = 'group_types/%s/group_specs' % group_type_id
+ resp, body = self.get(url)
+ body = json.loads(body)
+ self.expected_success(200, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def show_group_type_specs_item(self, group_type_id, spec_id):
+ """Shows specified item of group specs for a given group type."""
+ url = "group_types/%s/group_specs/%s" % (group_type_id, spec_id)
+ resp, body = self.get(url)
+ body = json.loads(body)
+ self.expected_success(200, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def update_group_type_specs_item(self, group_type_id, spec_id, spec):
+ """Updates specified item of group specs for a given group type.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ https://developer.openstack.org/api-ref/block-storage/v3/#update-one-specific-group-spec-for-a-group-type
+ """
+ url = "group_types/%s/group_specs/%s" % (group_type_id, spec_id)
+ put_body = json.dumps(spec)
+ resp, body = self.put(url, put_body)
+ body = json.loads(body)
+ self.expected_success(200, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
+ def delete_group_type_specs_item(self, group_type_id, spec_id):
+ """Deletes specified item of group specs for a given group type."""
+ resp, body = self.delete("group_types/%s/group_specs/%s" % (
+ group_type_id, spec_id))
+ self.expected_success(202, resp.status)
+ return rest_client.ResponseBody(resp, body)
diff --git a/tempest/tests/lib/services/volume/v3/test_group_types_client.py b/tempest/tests/lib/services/volume/v3/test_group_types_client.py
index e86594e..c60cc36 100644
--- a/tempest/tests/lib/services/volume/v3/test_group_types_client.py
+++ b/tempest/tests/lib/services/volume/v3/test_group_types_client.py
@@ -69,6 +69,28 @@
]
}
+ FAKE_CREATE_GROUP_TYPE_SPECS = {
+ "group_specs": {
+ "key1": "value1",
+ "key2": "value2"
+ }
+ }
+
+ FAKE_LIST_GROUP_TYPE_SPECS = {
+ "group_specs": {
+ "key1": "value1",
+ "key2": "value2"
+ }
+ }
+
+ FAKE_SHOW_GROUP_TYPE_SPECS_ITEM = {
+ "key1": "value1"
+ }
+
+ FAKE_UPDATE_GROUP_TYPE_SPECS_ITEM = {
+ "key2": "value2-updated"
+ }
+
def setUp(self):
super(TestGroupTypesClient, self).setUp()
fake_auth = fake_auth_provider.FakeAuthProvider()
@@ -111,6 +133,45 @@
group_type_id="3fbbcccf-d058-4502-8844-6feeffdf4cb5",
name='updated-group-type-name')
+ def _test_create_or_update_group_type_specs(self, bytes_body=False):
+ group_specs = self.FAKE_CREATE_GROUP_TYPE_SPECS['group_specs']
+ self.check_service_client_function(
+ self.client.create_or_update_group_type_specs,
+ 'tempest.lib.common.rest_client.RestClient.post',
+ self.FAKE_CREATE_GROUP_TYPE_SPECS,
+ bytes_body,
+ group_type_id="3fbbcccf-d058-4502-8844-6feeffdf4cb5",
+ group_specs=group_specs,
+ status=202)
+
+ def _test_list_group_type_specs(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_group_type_specs,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_LIST_GROUP_TYPE_SPECS,
+ bytes_body,
+ group_type_id="3fbbcccf-d058-4502-8844-6feeffdf4cb5")
+
+ def _test_show_group_type_specs_item(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.show_group_type_specs_item,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_SHOW_GROUP_TYPE_SPECS_ITEM,
+ bytes_body,
+ group_type_id="3fbbcccf-d058-4502-8844-6feeffdf4cb5",
+ spec_id="key1")
+
+ def _test_update_group_type_specs_item(self, bytes_body=False):
+ spec = self.FAKE_UPDATE_GROUP_TYPE_SPECS_ITEM
+ self.check_service_client_function(
+ self.client.update_group_type_specs_item,
+ 'tempest.lib.common.rest_client.RestClient.put',
+ self.FAKE_UPDATE_GROUP_TYPE_SPECS_ITEM,
+ bytes_body,
+ group_type_id="3fbbcccf-d058-4502-8844-6feeffdf4cb5",
+ spec_id="key2",
+ spec=spec)
+
def test_create_group_type_with_str_body(self):
self._test_create_group_type()
@@ -142,3 +203,36 @@
def test_update_group_types_with_bytes_body(self):
self._test_update_group_types(bytes_body=True)
+
+ def test_create_or_update_group_type_specs_with_str_body(self):
+ self._test_create_or_update_group_type_specs()
+
+ def test_create_or_update_group_type_specs_with_bytes_body(self):
+ self._test_create_or_update_group_type_specs(bytes_body=True)
+
+ def test_list_group_type_specs_with_str_body(self):
+ self._test_list_group_type_specs()
+
+ def test_list_group_type_specs_with_bytes_body(self):
+ self._test_list_group_type_specs(bytes_body=True)
+
+ def test_show_group_type_specs_item_with_str_body(self):
+ self._test_show_group_type_specs_item()
+
+ def test_show_group_type_specs_item_with_bytes_body(self):
+ self._test_show_group_type_specs_item(bytes_body=True)
+
+ def test_update_group_type_specs_item_with_str_body(self):
+ self._test_update_group_type_specs_item()
+
+ def test_update_group_type_specs_item_with_bytes_body(self):
+ self._test_update_group_type_specs_item(bytes_body=True)
+
+ def test_delete_group_type_specs_item(self):
+ self.check_service_client_function(
+ self.client.delete_group_type_specs_item,
+ 'tempest.lib.common.rest_client.RestClient.delete',
+ {},
+ group_type_id='0e58433f-d108-4bf3-a22c-34e6b71ef86b',
+ spec_id='key1',
+ status=202)