From 6e57568e9762be8290380ff3b91afa43caa2149a Mon Sep 17 00:00:00 2001 From: silvacarloss Date: Tue, 18 Feb 2020 19:52:35 -0300 Subject: [PATCH] Remove experimental flag from share groups feature The share groups functionality will no longer be considered experimental. The existent functional tests were modified to accomplish with this feature graduation. Change-Id: Ideba68c0481345e808f185195eea68e879155cf1 Partially-Implements: bp graduate-share-groups-feature --- manila_tempest_tests/common/constants.py | 1 + manila_tempest_tests/config.py | 2 +- .../services/share/v2/json/shares_client.py | 154 ++++++++++++------ .../tests/api/admin/test_share_group_types.py | 68 +++++--- .../tests/api/admin/test_share_groups.py | 24 ++- manila_tempest_tests/tests/api/base.py | 3 +- .../tests/api/test_share_group_actions.py | 96 ++++++++--- .../tests/api/test_share_groups.py | 6 +- .../tests/api/test_share_groups_negative.py | 1 - manila_tempest_tests/utils.py | 10 ++ 10 files changed, 254 insertions(+), 111 deletions(-) diff --git a/manila_tempest_tests/common/constants.py b/manila_tempest_tests/common/constants.py index 87918379..cadab0a3 100644 --- a/manila_tempest_tests/common/constants.py +++ b/manila_tempest_tests/common/constants.py @@ -70,6 +70,7 @@ STATUS_REVERTING_ERROR = 'reverting_error' # Share groups MIN_SHARE_GROUP_MICROVERSION = '2.31' +SHARE_GROUPS_GRADUATION_VERSION = '2.55' SHARE_GROUP_SIMPLE_KEYS = { 'id', 'name', 'links', } diff --git a/manila_tempest_tests/config.py b/manila_tempest_tests/config.py index 042be5a5..6973092b 100644 --- a/manila_tempest_tests/config.py +++ b/manila_tempest_tests/config.py @@ -30,7 +30,7 @@ ShareGroup = [ help="The minimum api microversion is configured to be the " "value of the minimum microversion supported by Manila."), cfg.StrOpt("max_api_microversion", - default="2.53", + default="2.55", help="The maximum api microversion is configured to be the " "value of the latest microversion supported by Manila."), cfg.StrOpt("region", diff --git a/manila_tempest_tests/services/share/v2/json/shares_client.py b/manila_tempest_tests/services/share/v2/json/shares_client.py index d8b7ed44..09308b8f 100644 --- a/manila_tempest_tests/services/share/v2/json/shares_client.py +++ b/manila_tempest_tests/services/share/v2/json/shares_client.py @@ -1078,6 +1078,8 @@ class SharesV2Client(shares_client.SharesClient): """Create a new share group.""" uri = 'share-groups' post_body = {} + headers, extra_headers = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) if name: post_body['name'] = name if description: @@ -1095,8 +1097,8 @@ class SharesV2Client(shares_client.SharesClient): post_body['availability_zone'] = availability_zone body = json.dumps({'share_group': post_body}) - resp, body = self.post(uri, body, headers=EXPERIMENTAL, - extra_headers=True, version=version) + resp, body = self.post(uri, body, headers=headers, + extra_headers=extra_headers, version=version) self.expected_success(202, resp.status) return self._parse_resp(body) @@ -1104,8 +1106,10 @@ class SharesV2Client(shares_client.SharesClient): def delete_share_group(self, share_group_id, version=LATEST_MICROVERSION): """Delete a share group.""" uri = 'share-groups/%s' % share_group_id - resp, body = self.delete(uri, headers=EXPERIMENTAL, - extra_headers=True, version=version) + headers, extra_headers = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) + resp, body = self.delete(uri, headers=headers, + extra_headers=extra_headers, version=version) self.expected_success(202, resp.status) return self._parse_resp(body) @@ -1114,16 +1118,20 @@ class SharesV2Client(shares_client.SharesClient): """Get list of share groups w/o filters.""" uri = 'share-groups%s' % ('/detail' if detailed else '') uri += '?%s' % (parse.urlencode(params) if params else '') - resp, body = self.get(uri, headers=EXPERIMENTAL, extra_headers=True, - version=version) + headers, extra_headers = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) + resp, body = self.get(uri, headers=headers, + extra_headers=extra_headers, version=version) self.expected_success(200, resp.status) return self._parse_resp(body) def get_share_group(self, share_group_id, version=LATEST_MICROVERSION): """Get share group info.""" uri = 'share-groups/%s' % share_group_id - resp, body = self.get(uri, headers=EXPERIMENTAL, extra_headers=True, - version=version) + headers, extra_headers = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) + resp, body = self.get(uri, headers=headers, + extra_headers=extra_headers, version=version) self.expected_success(200, resp.status) return self._parse_resp(body) @@ -1131,6 +1139,8 @@ class SharesV2Client(shares_client.SharesClient): version=LATEST_MICROVERSION, **kwargs): """Update an existing share group.""" uri = 'share-groups/%s' % share_group_id + headers, extra_headers = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) post_body = {} if name: post_body['name'] = name @@ -1140,21 +1150,25 @@ class SharesV2Client(shares_client.SharesClient): post_body.update(kwargs) body = json.dumps({'share_group': post_body}) - resp, body = self.put(uri, body, headers=EXPERIMENTAL, - extra_headers=True, version=version) + resp, body = self.put(uri, body, headers=headers, + extra_headers=extra_headers, version=version) self.expected_success(200, resp.status) return self._parse_resp(body) def share_group_reset_state(self, share_group_id, status='error', version=LATEST_MICROVERSION): + headers, _junk = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) self.reset_state(share_group_id, status=status, s_type='groups', - headers=EXPERIMENTAL, version=version) + headers=headers, version=version) def share_group_force_delete(self, share_group_id, version=LATEST_MICROVERSION): + headers, _junk = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) self.force_delete(share_group_id, s_type='share-groups', - headers=EXPERIMENTAL, version=version) + headers=headers, version=version) def wait_for_share_group_status(self, share_group_id, status): """Waits for a share group to reach a given status.""" @@ -1186,6 +1200,8 @@ class SharesV2Client(shares_client.SharesClient): version=LATEST_MICROVERSION): """Create a new share group type.""" uri = 'share-group-types' + headers, extra_headers = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) post_body = {} if isinstance(share_types, (tuple, list)): share_types = list(share_types) @@ -1200,8 +1216,8 @@ class SharesV2Client(shares_client.SharesClient): if group_specs: post_body['group_specs'] = group_specs body = json.dumps({'share_group_type': post_body}) - resp, body = self.post(uri, body, headers=EXPERIMENTAL, - extra_headers=True, version=version) + resp, body = self.post(uri, body, headers=headers, + extra_headers=extra_headers, version=version) self.expected_success(200, resp.status) return self._parse_resp(body) @@ -1210,8 +1226,10 @@ class SharesV2Client(shares_client.SharesClient): """Get list of share group types.""" uri = 'share-group-types%s' % ('/detail' if detailed else '') uri += '?%s' % (parse.urlencode(params) if params else '') - resp, body = self.get(uri, headers=EXPERIMENTAL, extra_headers=True, - version=version) + headers, extra_headers = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) + resp, body = self.get(uri, headers=headers, + extra_headers=extra_headers, version=version) self.expected_success(200, resp.status) return self._parse_resp(body) @@ -1219,16 +1237,20 @@ class SharesV2Client(shares_client.SharesClient): version=LATEST_MICROVERSION): """Get share group type info.""" uri = 'share-group-types/%s' % share_group_type_id - resp, body = self.get(uri, headers=EXPERIMENTAL, extra_headers=True, - version=version) + headers, extra_headers = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) + resp, body = self.get(uri, headers=headers, + extra_headers=extra_headers, version=version) self.expected_success(200, resp.status) return self._parse_resp(body) def get_default_share_group_type(self, version=LATEST_MICROVERSION): """Get default share group type info.""" uri = 'share-group-types/default' - resp, body = self.get(uri, headers=EXPERIMENTAL, extra_headers=True, - version=version) + headers, extra_headers = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) + resp, body = self.get(uri, headers=headers, + extra_headers=extra_headers, version=version) self.expected_success(200, resp.status) return self._parse_resp(body) @@ -1236,18 +1258,22 @@ class SharesV2Client(shares_client.SharesClient): version=LATEST_MICROVERSION): """Delete an existing share group type.""" uri = 'share-group-types/%s' % share_group_type_id - resp, body = self.delete(uri, headers=EXPERIMENTAL, - extra_headers=True, version=version) + headers, extra_headers = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) + resp, body = self.delete(uri, headers=headers, + extra_headers=extra_headers, version=version) self.expected_success(204, resp.status) return self._parse_resp(body) def add_access_to_share_group_type(self, share_group_type_id, project_id, version=LATEST_MICROVERSION): uri = 'share-group-types/%s/action' % share_group_type_id + headers, extra_headers = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) post_body = {'project': project_id} post_body = json.dumps({'addProjectAccess': post_body}) - resp, body = self.post(uri, post_body, headers=EXPERIMENTAL, - extra_headers=True, version=version) + resp, body = self.post(uri, post_body, headers=headers, + extra_headers=extra_headers, version=version) self.expected_success(202, resp.status) return self._parse_resp(body) @@ -1255,18 +1281,22 @@ class SharesV2Client(shares_client.SharesClient): project_id, version=LATEST_MICROVERSION): uri = 'share-group-types/%s/action' % share_group_type_id + headers, extra_headers = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) post_body = {'project': project_id} post_body = json.dumps({'removeProjectAccess': post_body}) - resp, body = self.post(uri, post_body, headers=EXPERIMENTAL, - extra_headers=True, version=version) + resp, body = self.post(uri, post_body, headers=headers, + extra_headers=extra_headers, version=version) self.expected_success(202, resp.status) return self._parse_resp(body) def list_access_to_share_group_type(self, share_group_type_id, version=LATEST_MICROVERSION): uri = 'share-group-types/%s/access' % share_group_type_id - resp, body = self.get(uri, headers=EXPERIMENTAL, extra_headers=True, - version=version) + headers, extra_headers = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) + resp, body = self.get(uri, headers=headers, + extra_headers=extra_headers, version=version) self.expected_success(200, resp.status) return self._parse_resp(body) @@ -1276,9 +1306,11 @@ class SharesV2Client(shares_client.SharesClient): group_specs_dict, version=LATEST_MICROVERSION): url = "share-group-types/%s/group-specs" % share_group_type_id + headers, extra_headers = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) post_body = json.dumps({'group_specs': group_specs_dict}) - resp, body = self.post(url, post_body, headers=EXPERIMENTAL, - extra_headers=True, version=version) + resp, body = self.post(url, post_body, headers=headers, + extra_headers=extra_headers, version=version) self.expected_success(200, resp.status) return self._parse_resp(body) @@ -1286,18 +1318,22 @@ class SharesV2Client(shares_client.SharesClient): version=LATEST_MICROVERSION): uri = "group-types/%s/group_specs/%s" % ( share_group_type_id, group_spec_key) - resp, body = self.get(uri, headers=EXPERIMENTAL, extra_headers=True, - version=version) + headers, extra_headers = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) + resp, body = self.get(uri, headers=headers, + extra_headers=extra_headers, version=version) self.expected_success(200, resp.status) return self._parse_resp(body) def list_share_group_type_specs(self, share_group_type_id, params=None, version=LATEST_MICROVERSION): uri = "share-group-types/%s/group_specs" % share_group_type_id + headers, extra_headers = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) if params is not None: uri += '?%s' % parse.urlencode(params) - resp, body = self.get(uri, headers=EXPERIMENTAL, extra_headers=True, - version=version) + resp, body = self.get(uri, headers=headers, + extra_headers=extra_headers, version=version) self.expected_success(200, resp.status) return self._parse_resp(body) @@ -1306,10 +1342,12 @@ class SharesV2Client(shares_client.SharesClient): version=LATEST_MICROVERSION): uri = "share-group-types/%s/group-specs/%s" % ( share_group_type_id, group_spec_key) + headers, extra_headers = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) group_spec = {group_spec_key: group_spec_value} post_body = json.dumps(group_spec) - resp, body = self.put(uri, post_body, headers=EXPERIMENTAL, - extra_headers=True, version=version) + resp, body = self.put(uri, post_body, headers=headers, + extra_headers=extra_headers, version=version) self.expected_success(200, resp.status) return self._parse_resp(body) @@ -1323,8 +1361,10 @@ class SharesV2Client(shares_client.SharesClient): version=LATEST_MICROVERSION): uri = "share-group-types/%s/group-specs/%s" % ( share_type_id, group_spec_key) - resp, body = self.delete(uri, headers=EXPERIMENTAL, extra_headers=True, - version=version) + headers, extra_headers = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) + resp, body = self.delete(uri, headers=headers, + extra_headers=extra_headers, version=version) self.expected_success(204, resp.status) return body @@ -1335,14 +1375,16 @@ class SharesV2Client(shares_client.SharesClient): version=LATEST_MICROVERSION): """Create a new share group snapshot of an existing share group.""" uri = 'share-group-snapshots' + headers, extra_headers = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) post_body = {'share_group_id': share_group_id} if name: post_body['name'] = name if description: post_body['description'] = description body = json.dumps({'share_group_snapshot': post_body}) - resp, body = self.post(uri, body, headers=EXPERIMENTAL, - extra_headers=True, version=version) + resp, body = self.post(uri, body, headers=headers, + extra_headers=extra_headers, version=version) self.expected_success(202, resp.status) return self._parse_resp(body) @@ -1350,8 +1392,10 @@ class SharesV2Client(shares_client.SharesClient): version=LATEST_MICROVERSION): """Delete an existing share group snapshot.""" uri = 'share-group-snapshots/%s' % share_group_snapshot_id - resp, body = self.delete(uri, headers=EXPERIMENTAL, - extra_headers=True, version=version) + headers, extra_headers = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) + resp, body = self.delete(uri, headers=headers, + extra_headers=extra_headers, version=version) self.expected_success(202, resp.status) return body @@ -1360,8 +1404,10 @@ class SharesV2Client(shares_client.SharesClient): """Get list of share group snapshots w/o filters.""" uri = 'share-group-snapshots%s' % ('/detail' if detailed else '') uri += '?%s' % (parse.urlencode(params) if params else '') - resp, body = self.get(uri, headers=EXPERIMENTAL, extra_headers=True, - version=version) + headers, extra_headers = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) + resp, body = self.get(uri, headers=headers, + extra_headers=extra_headers, version=version) self.expected_success(200, resp.status) return self._parse_resp(body) @@ -1369,8 +1415,10 @@ class SharesV2Client(shares_client.SharesClient): version=LATEST_MICROVERSION): """Get share group snapshot info.""" uri = 'share-group-snapshots/%s' % share_group_snapshot_id - resp, body = self.get(uri, headers=EXPERIMENTAL, extra_headers=True, - version=version) + headers, extra_headers = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) + resp, body = self.get(uri, headers=headers, + extra_headers=extra_headers, version=version) self.expected_success(200, resp.status) return self._parse_resp(body) @@ -1379,29 +1427,35 @@ class SharesV2Client(shares_client.SharesClient): version=LATEST_MICROVERSION): """Update an existing share group snapshot.""" uri = 'share-group-snapshots/%s' % share_group_snapshot_id + headers, extra_headers = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) post_body = {} if name: post_body['name'] = name if description: post_body['description'] = description body = json.dumps({'share_group_snapshot': post_body}) - resp, body = self.put(uri, body, headers=EXPERIMENTAL, - extra_headers=True, version=version) + resp, body = self.put(uri, body, headers=headers, + extra_headers=extra_headers, version=version) self.expected_success(200, resp.status) return self._parse_resp(body) def share_group_snapshot_reset_state(self, share_group_snapshot_id, status='error', version=LATEST_MICROVERSION): + headers, _junk = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) self.reset_state( share_group_snapshot_id, status=status, - s_type='group-snapshots', headers=EXPERIMENTAL, version=version) + headers=headers, s_type='group-snapshots', version=version) def share_group_snapshot_force_delete(self, share_group_snapshot_id, version=LATEST_MICROVERSION): + headers, _junk = utils.get_extra_headers( + version, constants.SHARE_GROUPS_GRADUATION_VERSION) self.force_delete( share_group_snapshot_id, s_type='share-group-snapshots', - headers=EXPERIMENTAL, version=version) + headers=headers, version=version) def wait_for_share_group_snapshot_status(self, share_group_snapshot_id, status): diff --git a/manila_tempest_tests/tests/api/admin/test_share_group_types.py b/manila_tempest_tests/tests/api/admin/test_share_group_types.py index 6474f596..d05c0799 100644 --- a/manila_tempest_tests/tests/api/admin/test_share_group_types.py +++ b/manila_tempest_tests/tests/api/admin/test_share_group_types.py @@ -14,6 +14,7 @@ # under the License. import ddt +import itertools from tempest import config from tempest.lib.common.utils import data_utils from testtools import testcase as tc @@ -54,8 +55,13 @@ class ShareGroupTypesTest(base.BaseSharesAdminTest): cls.share_type2 = share_type['share_type'] @tc.attr(base.TAG_POSITIVE, base.TAG_API) - @ddt.data('id', 'name') - def test_create_get_delete_share_group_type_min(self, st_key): + @ddt.data( + *itertools.product(('id', 'name'), set( + [LATEST_MICROVERSION, constants.MIN_SHARE_GROUP_MICROVERSION, + constants.SHARE_GROUPS_GRADUATION_VERSION]))) + @ddt.unpack + def test_create_get_delete_share_group_type(self, st_key, version): + self.skip_if_microversion_not_supported(version) name = data_utils.rand_name("tempest-manila") # Create share group type @@ -63,7 +69,7 @@ class ShareGroupTypesTest(base.BaseSharesAdminTest): name=name, share_types=self.share_type[st_key], cleanup_in_class=False, - version=constants.MIN_SHARE_GROUP_MICROVERSION) + version=version) self.assertEqual( [self.share_type['id']], @@ -71,7 +77,8 @@ class ShareGroupTypesTest(base.BaseSharesAdminTest): 'Share type not applied correctly.') # Read share group type - sg_type_r = self.shares_v2_client.get_share_group_type(sg_type_c['id']) + sg_type_r = self.shares_v2_client.get_share_group_type( + sg_type_c['id'], version=version) keys = set(sg_type_r.keys()) self.assertTrue( constants.SHARE_GROUP_TYPE_REQUIRED_KEYS.issubset(keys), @@ -82,7 +89,7 @@ class ShareGroupTypesTest(base.BaseSharesAdminTest): # Delete share group type self.shares_v2_client.delete_share_group_type( - sg_type_r['id'], version=constants.MIN_SHARE_GROUP_MICROVERSION) + sg_type_r['id'], version=version) self.shares_v2_client.wait_for_resource_deletion( share_group_type_id=sg_type_r['id']) @@ -131,7 +138,11 @@ class ShareGroupTypesTest(base.BaseSharesAdminTest): self.assertDictMatch(group_specs, sg_type['group_specs']) @tc.attr(base.TAG_POSITIVE, base.TAG_API) - def test_update_single_share_group_type_spec_min(self): + @ddt.data( + *set([constants.MIN_SHARE_GROUP_MICROVERSION, + constants.SHARE_GROUPS_GRADUATION_VERSION, LATEST_MICROVERSION])) + def test_update_single_share_group_type_spec(self, version): + self.skip_if_microversion_not_supported(version) name = data_utils.rand_name("tempest-manila") group_specs = {'key1': 'value1', 'key2': 'value2'} @@ -140,14 +151,14 @@ class ShareGroupTypesTest(base.BaseSharesAdminTest): share_types=self.share_type['id'], group_specs=group_specs, cleanup_in_class=False, - version=constants.MIN_SHARE_GROUP_MICROVERSION) + version=version) self.assertDictMatch(group_specs, sg_type['group_specs']) group_specs = {'key1': 'value1', 'key2': 'value2'} self.shares_v2_client.update_share_group_type_spec( - sg_type['id'], 'key1', 'value3') + sg_type['id'], 'key1', 'value3', version=version) sg_type = self.shares_v2_client.get_share_group_type(sg_type['id']) self.assertIn('key1', sg_type['group_specs']) @@ -180,7 +191,11 @@ class ShareGroupTypesTest(base.BaseSharesAdminTest): self.assertEqual(v, sg_type['group_specs'][k]) @tc.attr(base.TAG_POSITIVE, base.TAG_API) - def test_delete_single_share_group_type_spec_min(self): + @ddt.data( + *set([constants.MIN_SHARE_GROUP_MICROVERSION, + constants.SHARE_GROUPS_GRADUATION_VERSION, LATEST_MICROVERSION])) + def test_delete_single_share_group_type_spec_min(self, version): + self.skip_if_microversion_not_supported(version) name = data_utils.rand_name("tempest-manila") group_specs = {'key1': 'value1', 'key2': 'value2'} @@ -189,7 +204,7 @@ class ShareGroupTypesTest(base.BaseSharesAdminTest): share_types=self.share_type['id'], group_specs=group_specs, cleanup_in_class=False, - version=constants.MIN_SHARE_GROUP_MICROVERSION) + version=version) self.assertDictMatch(group_specs, sg_type['group_specs']) @@ -197,14 +212,18 @@ class ShareGroupTypesTest(base.BaseSharesAdminTest): group_specs.pop(key_to_delete) self.shares_v2_client.delete_share_group_type_spec( - sg_type['id'], key_to_delete) + sg_type['id'], key_to_delete, version=version) sg_type = self.shares_v2_client.get_share_group_type( - sg_type['id']) + sg_type['id'], version=version) self.assertDictMatch(group_specs, sg_type['group_specs']) @tc.attr(base.TAG_POSITIVE, base.TAG_API) - def test_private_share_group_type_access(self): + @ddt.data( + *set([constants.MIN_SHARE_GROUP_MICROVERSION, + constants.SHARE_GROUPS_GRADUATION_VERSION, LATEST_MICROVERSION])) + def test_private_share_group_type_access(self, version): + self.skip_if_microversion_not_supported(version) name = data_utils.rand_name("tempest-manila") group_specs = {"key1": "value1", "key2": "value2"} project_id = self.shares_v2_client.tenant_id @@ -215,41 +234,48 @@ class ShareGroupTypesTest(base.BaseSharesAdminTest): share_types=[self.share_type['id']], is_public=False, group_specs=group_specs, + version=version ) self.assertEqual(name, sgt_create['name']) sgt_id = sgt_create["id"] # It should not be listed without access - sgt_list = self.shares_v2_client.list_share_group_types() + sgt_list = self.shares_v2_client.list_share_group_types( + version=version) self.assertFalse(any(sgt_id == sgt["id"] for sgt in sgt_list)) # List projects that have access for share group type - none expected - access = self.shares_v2_client.list_access_to_share_group_type(sgt_id) + access = self.shares_v2_client.list_access_to_share_group_type( + sgt_id, version=version) self.assertEmpty(access) # Add project access to share group type access = self.shares_v2_client.add_access_to_share_group_type( - sgt_id, project_id) + sgt_id, project_id, version=version) # Now it should be listed - sgt_list = self.shares_v2_client.list_share_group_types() + sgt_list = self.shares_v2_client.list_share_group_types( + version=version) self.assertTrue(any(sgt_id == sgt["id"] for sgt in sgt_list)) # List projects that have access for share group type - one expected - access = self.shares_v2_client.list_access_to_share_group_type(sgt_id) + access = self.shares_v2_client.list_access_to_share_group_type( + sgt_id, version=version) expected = [{'share_group_type_id': sgt_id, 'project_id': project_id}] self.assertEqual(expected, access) # Remove project access from share group type access = self.shares_v2_client.remove_access_from_share_group_type( - sgt_id, project_id) + sgt_id, project_id, version=version) # It should not be listed without access - sgt_list = self.shares_v2_client.list_share_group_types() + sgt_list = self.shares_v2_client.list_share_group_types( + version=version) self.assertFalse(any(sgt_id == sgt["id"] for sgt in sgt_list)) # List projects that have access for share group type - none expected - access = self.shares_v2_client.list_access_to_share_group_type(sgt_id) + access = self.shares_v2_client.list_access_to_share_group_type( + sgt_id, version=version) self.assertEmpty(access) @tc.attr(base.TAG_POSITIVE, base.TAG_API) diff --git a/manila_tempest_tests/tests/api/admin/test_share_groups.py b/manila_tempest_tests/tests/api/admin/test_share_groups.py index 39925ba2..c7b3a423 100644 --- a/manila_tempest_tests/tests/api/admin/test_share_groups.py +++ b/manila_tempest_tests/tests/api/admin/test_share_groups.py @@ -13,6 +13,7 @@ # License for the specific language governing permissions and limitations # under the License. +import ddt from tempest import config from tempest.lib.common.utils import data_utils import testtools @@ -23,8 +24,10 @@ from manila_tempest_tests.tests.api import base from manila_tempest_tests import utils CONF = config.CONF +LATEST_MICROVERSION = CONF.share.max_api_microversion +@ddt.ddt class ShareGroupsTest(base.BaseSharesAdminTest): @classmethod @@ -56,12 +59,16 @@ class ShareGroupsTest(base.BaseSharesAdminTest): cls.sg_type_id = cls.sg_type['id'] @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND) - def test_create_share_group_with_single_share_type_min(self): + @ddt.data( + *set([constants.MIN_SHARE_GROUP_MICROVERSION, + constants.SHARE_GROUPS_GRADUATION_VERSION, LATEST_MICROVERSION])) + def test_create_share_group_with_single_share_type_min(self, version): + self.skip_if_microversion_not_supported(version) share_group = self.create_share_group( share_group_type_id=self.sg_type_id, cleanup_in_class=False, share_type_ids=[self.share_type_id], - version=constants.MIN_SHARE_GROUP_MICROVERSION) + version=version) keys = set(share_group.keys()) self.assertTrue( @@ -124,14 +131,21 @@ class ShareGroupsTest(base.BaseSharesAdminTest): @testtools.skipUnless( CONF.share.default_share_type_name, "Only if defaults are defined.") @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND) - def test_default_share_group_type_applied(self): - default_type = self.shares_v2_client.get_default_share_group_type() + @ddt.data( + *set([constants.MIN_SHARE_GROUP_MICROVERSION, + constants.SHARE_GROUPS_GRADUATION_VERSION, LATEST_MICROVERSION])) + def test_default_share_group_type_applied(self, version): + self.skip_if_microversion_not_supported(version) + + default_type = self.shares_v2_client.get_default_share_group_type( + version=version + ) default_share_types = default_type['share_types'] share_group = self.create_share_group( cleanup_in_class=False, share_type_ids=default_share_types, - version=constants.MIN_SHARE_GROUP_MICROVERSION) + version=version) keys = set(share_group.keys()) self.assertTrue( diff --git a/manila_tempest_tests/tests/api/base.py b/manila_tempest_tests/tests/api/base.py index 22b1d72b..8c18a4b3 100644 --- a/manila_tempest_tests/tests/api/base.py +++ b/manila_tempest_tests/tests/api/base.py @@ -609,8 +609,7 @@ class BaseSharesTest(test.BaseTestCase): if kwargs.get('source_share_group_snapshot_id'): new_share_group_shares = client.list_shares( detailed=True, - params={'share_group_id': share_group['id']}, - experimental=True) + params={'share_group_id': share_group['id']}) for share in new_share_group_shares: resource = {"type": "share", diff --git a/manila_tempest_tests/tests/api/test_share_group_actions.py b/manila_tempest_tests/tests/api/test_share_group_actions.py index 169d7674..c1f4e6fb 100644 --- a/manila_tempest_tests/tests/api/test_share_group_actions.py +++ b/manila_tempest_tests/tests/api/test_share_group_actions.py @@ -24,6 +24,7 @@ from manila_tempest_tests.tests.api import base from manila_tempest_tests import utils CONF = config.CONF +LATEST_MICROVERSION = CONF.share.max_api_microversion @ddt.ddt @@ -81,7 +82,6 @@ class ShareGroupActionsTest(base.BaseSharesMixedTest): 'size': size, 'share_type_id': cls.share_type_id, 'share_group_id': sg_id, - 'experimental': True, }} for size, sg_id in ((cls.share_size, cls.share_group['id']), (cls.share_size2, cls.share_group['id']), (cls.share_size, cls.share_group2['id'])) @@ -104,13 +104,15 @@ class ShareGroupActionsTest(base.BaseSharesMixedTest): ) @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND) - def test_get_share_group_min_supported_sg_microversion(self): + @ddt.data( + *set([constants.MIN_SHARE_GROUP_MICROVERSION, + constants.SHARE_GROUPS_GRADUATION_VERSION, LATEST_MICROVERSION])) + def test_get_share_group(self, version): + self.skip_if_microversion_not_supported(version) # Get share group share_group = self.shares_v2_client.get_share_group( - self.share_group['id'], - version=constants.MIN_SHARE_GROUP_MICROVERSION, - ) + self.share_group['id'], version=version) # Verify keys actual_keys = set(share_group.keys()) @@ -132,8 +134,7 @@ class ShareGroupActionsTest(base.BaseSharesMixedTest): # Get share share = self.shares_v2_client.get_share( self.shares[0]['id'], - version=constants.MIN_SHARE_GROUP_MICROVERSION, - experimental=True) + version=constants.MIN_SHARE_GROUP_MICROVERSION) # Verify keys expected_keys = { @@ -155,11 +156,15 @@ class ShareGroupActionsTest(base.BaseSharesMixedTest): self.assertEqual(self.share_group["id"], share["share_group_id"]) @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND) - def test_list_share_groups_min(self): + @ddt.data( + *set([constants.MIN_SHARE_GROUP_MICROVERSION, + constants.SHARE_GROUPS_GRADUATION_VERSION, LATEST_MICROVERSION])) + def test_list_share_groups(self, version): + self.skip_if_microversion_not_supported(version) # List share groups share_groups = self.shares_v2_client.list_share_groups( - version=constants.MIN_SHARE_GROUP_MICROVERSION) + version=version) # Verify keys self.assertGreater(len(share_groups), 0) @@ -181,8 +186,11 @@ class ShareGroupActionsTest(base.BaseSharesMixedTest): self.assertEqual(1, len(gen), msg) @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND) - @ddt.data(constants.MIN_SHARE_GROUP_MICROVERSION, '2.36') + @ddt.data( + *set([constants.MIN_SHARE_GROUP_MICROVERSION, '2.36', + constants.SHARE_GROUPS_GRADUATION_VERSION, LATEST_MICROVERSION])) def test_list_share_groups_with_detail_min(self, version): + self.skip_if_microversion_not_supported(version) params = None if utils.is_microversion_ge(version, '2.36'): params = {'name~': 'tempest', 'description~': 'tempest'} @@ -218,7 +226,6 @@ class ShareGroupActionsTest(base.BaseSharesMixedTest): detailed=True, params={'share_group_id': self.share_group['id']}, version=constants.MIN_SHARE_GROUP_MICROVERSION, - experimental=True, ) share_ids = [share['id'] for share in shares] @@ -237,11 +244,16 @@ class ShareGroupActionsTest(base.BaseSharesMixedTest): self.shares[0]['id'], share_ids)) @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND) - def test_get_share_group_snapshot_min(self): + @ddt.data( + *set([constants.MIN_SHARE_GROUP_MICROVERSION, + constants.SHARE_GROUPS_GRADUATION_VERSION, LATEST_MICROVERSION])) + def test_get_share_group_snapshot(self, version): + self.skip_if_microversion_not_supported(version) + # Get share group snapshot sg_snapshot = self.shares_v2_client.get_share_group_snapshot( self.sg_snapshot['id'], - version=constants.MIN_SHARE_GROUP_MICROVERSION, + version=version, ) # Verify keys @@ -286,24 +298,29 @@ class ShareGroupActionsTest(base.BaseSharesMixedTest): self.assertEqual(share['size'], member['size']) @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND) - def test_create_share_group_from_populated_share_group_snapshot_min(self): + @ddt.data( + *set([constants.MIN_SHARE_GROUP_MICROVERSION, + constants.SHARE_GROUPS_GRADUATION_VERSION, LATEST_MICROVERSION])) + def test_create_share_group_from_populated_share_group_snapshot(self, + version): + self.skip_if_microversion_not_supported(version) sg_snapshot = self.shares_v2_client.get_share_group_snapshot( self.sg_snapshot['id'], - version=constants.MIN_SHARE_GROUP_MICROVERSION, + version=version, ) snapshot_members = sg_snapshot['members'] new_share_group = self.create_share_group( cleanup_in_class=False, source_share_group_snapshot_id=self.sg_snapshot['id'], - version=constants.MIN_SHARE_GROUP_MICROVERSION, + version=version, share_group_type_id=self.share_group_type_id, ) new_share_group = self.shares_v2_client.get_share_group( new_share_group['id'], - version=constants.MIN_SHARE_GROUP_MICROVERSION, + version=version, ) # Verify that share_network information matches source share group @@ -314,8 +331,7 @@ class ShareGroupActionsTest(base.BaseSharesMixedTest): new_shares = self.shares_v2_client.list_shares( params={'share_group_id': new_share_group['id']}, detailed=True, - version=constants.MIN_SHARE_GROUP_MICROVERSION, - experimental=True, + version=version, ) # Verify each new share is available @@ -343,6 +359,7 @@ class ShareGroupActionsTest(base.BaseSharesMixedTest): share['share_network_id']) +@ddt.ddt class ShareGroupRenameTest(base.BaseSharesMixedTest): @classmethod @@ -376,13 +393,25 @@ class ShareGroupRenameTest(base.BaseSharesMixedTest): share_type_ids=[cls.share_type_id] ) + def _rollback_share_group_update(self, version): + self.shares_v2_client.update_share_group( + self.share_group["id"], + name=self.share_group_name, + description=self.share_group_desc, + version=version, + ) + @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND) - def test_update_share_group_min(self): + @ddt.data( + *set([constants.MIN_SHARE_GROUP_MICROVERSION, + constants.SHARE_GROUPS_GRADUATION_VERSION, LATEST_MICROVERSION])) + def test_update_share_group(self, version): + self.skip_if_microversion_not_supported(version) # Get share_group share_group = self.shares_v2_client.get_share_group( self.share_group['id'], - version=constants.MIN_SHARE_GROUP_MICROVERSION + version=version ) self.assertEqual(self.share_group_name, share_group["name"]) self.assertEqual(self.share_group_desc, share_group["description"]) @@ -394,7 +423,7 @@ class ShareGroupRenameTest(base.BaseSharesMixedTest): share_group["id"], name=new_name, description=new_desc, - version=constants.MIN_SHARE_GROUP_MICROVERSION, + version=version, ) self.assertEqual(new_name, updated["name"]) self.assertEqual(new_desc, updated["description"]) @@ -402,13 +431,22 @@ class ShareGroupRenameTest(base.BaseSharesMixedTest): # Get share_group share_group = self.shares_v2_client.get_share_group( self.share_group['id'], - version=constants.MIN_SHARE_GROUP_MICROVERSION, + version=version, ) self.assertEqual(new_name, share_group["name"]) self.assertEqual(new_desc, share_group["description"]) + # Rollback the update since this is a ddt and the class resources are + # going to be reused + self._rollback_share_group_update(version) + @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND) - def test_create_update_read_share_group_with_unicode_min(self): + @ddt.data( + *set([constants.MIN_SHARE_GROUP_MICROVERSION, + constants.SHARE_GROUPS_GRADUATION_VERSION, LATEST_MICROVERSION])) + def test_create_update_read_share_group_with_unicode(self, version): + self.skip_if_microversion_not_supported(version) + value1 = u'ಠ_ಠ' value2 = u'ಠ_ರೃ' @@ -417,7 +455,7 @@ class ShareGroupRenameTest(base.BaseSharesMixedTest): cleanup_in_class=False, name=value1, description=value1, - version=constants.MIN_SHARE_GROUP_MICROVERSION, + version=version, share_group_type_id=self.share_group_type_id, share_type_ids=[self.share_type_id] ) @@ -429,13 +467,17 @@ class ShareGroupRenameTest(base.BaseSharesMixedTest): share_group["id"], name=value2, description=value2, - version=constants.MIN_SHARE_GROUP_MICROVERSION, + version=version, ) self.assertEqual(value2, updated["name"]) self.assertEqual(value2, updated["description"]) # Get share group share_group = self.shares_v2_client.get_share_group( - share_group['id'], version=constants.MIN_SHARE_GROUP_MICROVERSION) + share_group['id'], version=version) self.assertEqual(value2, share_group["name"]) self.assertEqual(value2, share_group["description"]) + + # Rollback the update since this is a ddt and the class resources are + # going to be reused + self._rollback_share_group_update(version) diff --git a/manila_tempest_tests/tests/api/test_share_groups.py b/manila_tempest_tests/tests/api/test_share_groups.py index 330c40e9..5b2ae9fc 100644 --- a/manila_tempest_tests/tests/api/test_share_groups.py +++ b/manila_tempest_tests/tests/api/test_share_groups.py @@ -72,8 +72,7 @@ class ShareGroupsTest(base.BaseSharesMixedTest): share_type_id=self.share_type_id, share_group_id=share_group['id'], cleanup_in_class=False, - version=constants.MIN_SHARE_GROUP_MICROVERSION, - experimental=True) + version=constants.MIN_SHARE_GROUP_MICROVERSION) # Delete params = {"share_group_id": share_group['id']} @@ -163,7 +162,7 @@ class ShareGroupsTest(base.BaseSharesMixedTest): new_shares = self.shares_v2_client.list_shares( params={'share_group_id': new_share_group['id']}, - version=constants.MIN_SHARE_GROUP_MICROVERSION, experimental=True) + version=constants.MIN_SHARE_GROUP_MICROVERSION) self.assertEmpty( new_shares, 'Expected 0 new shares, got %s' % len(new_shares)) @@ -236,7 +235,6 @@ class ShareGroupsTest(base.BaseSharesMixedTest): 'share_group_id': share_group['id'], 'version': '2.33', 'cleanup_in_class': False, - 'experimental': True, } if where_specify_az == 'sg_and_share': s_kwargs['availability_zone'] = azs[0] diff --git a/manila_tempest_tests/tests/api/test_share_groups_negative.py b/manila_tempest_tests/tests/api/test_share_groups_negative.py index 60e7b18b..a0a6b4b5 100644 --- a/manila_tempest_tests/tests/api/test_share_groups_negative.py +++ b/manila_tempest_tests/tests/api/test_share_groups_negative.py @@ -67,7 +67,6 @@ class ShareGroupsNegativeTest(base.BaseSharesMixedTest): size=cls.share_size, share_type_id=cls.share_type_id, share_group_id=cls.share_group['id'], - experimental=True, ) # Create a share group snapshot of the share group cls.sg_snap_name = data_utils.rand_name("tempest-sg-snap-name") diff --git a/manila_tempest_tests/utils.py b/manila_tempest_tests/utils.py index b22a5c1b..e842a332 100644 --- a/manila_tempest_tests/utils.py +++ b/manila_tempest_tests/utils.py @@ -24,6 +24,7 @@ import testtools CONF = config.CONF SHARE_NETWORK_SUBNETS_MICROVERSION = '2.51' SHARE_REPLICA_QUOTAS_MICROVERSION = "2.53" +EXPERIMENTAL = {'X-OpenStack-Manila-API-Experimental': 'True'} def get_microversion_as_tuple(microversion_str): @@ -211,3 +212,12 @@ def share_network_get_default_subnet(share_network): return next(( subnet for subnet in share_network.get('share_network_subnets', []) if subnet['availability_zone'] is None), None) + + +def get_extra_headers(request_version, graduation_version): + headers = None + extra_headers = False + if is_microversion_lt(request_version, graduation_version): + headers = EXPERIMENTAL + extra_headers = True + return headers, extra_headers