Merge "Remove experimental flag from share groups feature"

This commit is contained in:
Zuul 2020-04-23 14:56:02 +00:00 committed by Gerrit Code Review
commit 32bd346f8b
10 changed files with 254 additions and 111 deletions

View File

@ -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',
}

View File

@ -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",

View File

@ -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):

View File

@ -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)

View File

@ -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(

View File

@ -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",

View File

@ -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)

View File

@ -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]

View File

@ -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")

View File

@ -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