Merge "Add functional tests for add multiple subnets feature"

This commit is contained in:
Zuul 2022-03-16 19:22:11 +00:00 committed by Gerrit Code Review
commit 822cba5b0c
14 changed files with 696 additions and 16 deletions

View File

@ -217,3 +217,31 @@ def wait_for_restore(client, share_id, version=LATEST_MICROVERSION):
'timeout': client.build_timeout,
})
raise exceptions.TimeoutException(message)
def wait_for_subnet_create_check(client, share_network_id,
neutron_net_id=None,
neutron_subnet_id=None,
availability_zone=None):
result = client.subnet_create_check(
share_network_id, neutron_net_id=neutron_net_id,
neutron_subnet_id=neutron_subnet_id,
availability_zone=availability_zone)
start = int(time.time())
while not result['compatible']:
time.sleep(client.build_interval)
result = client.subnet_create_check(
share_network_id, neutron_net_id=neutron_net_id,
neutron_subnet_id=neutron_subnet_id,
availability_zone=availability_zone)
if result['compatible']:
break
elif int(time.time()) - start >= client.build_timeout or (
result['compatible'] is False):
message = ('Subnet create check failed within the '
'required time %(timeout)s seconds for share network '
'%(share_network)s.' % {
'timeout': client.build_timeout,
'share_network': share_network_id,
})
raise exceptions.TimeoutException(message)

View File

@ -40,7 +40,7 @@ ShareGroup = [
"This value is only used to validate the versions "
"response from Manila."),
cfg.StrOpt("max_api_microversion",
default="2.69",
default="2.70",
help="The maximum api microversion is configured to be the "
"value of the latest microversion supported by Manila."),
cfg.StrOpt("region",
@ -287,6 +287,16 @@ ShareGroup = [
default=False,
help="Defines whether to run share servers migration tests. "
"Enable this option if the used driver supports it."),
cfg.BoolOpt("run_share_server_multiple_subnet_tests",
default=False,
help="Defines whether to run the share server multiple "
"subnets tests. Enable this option if the used driver "
"supports it."),
cfg.BoolOpt("run_network_allocation_update_tests",
default=False,
help="Defines whether to run the network allocation update "
"tests. Enable this option if the used driver "
"supports it."),
cfg.StrOpt("image_with_share_tools",
default="manila-service-image-master",

View File

@ -1957,6 +1957,29 @@ class SharesV2Client(shares_client.SharesClient):
self.expected_success(202, resp.status)
return rest_client.ResponseBody(resp, body)
def subnet_create_check(
self, share_network_id, neutron_net_id=None,
neutron_subnet_id=None, availability_zone=None,
reset=False, version=LATEST_MICROVERSION):
body = {
'share_network_subnet_create_check': {
'neutron_net_id': neutron_net_id,
'neutron_subnet_id': neutron_subnet_id,
'availability_zone': availability_zone,
'reset': reset,
}
}
body = json.dumps(body)
resp, body = self.post(
f'share-networks/{share_network_id}/action',
body, headers=EXPERIMENTAL, extra_headers=True,
version=version)
self.expected_success(202, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
###############
def share_server_migration_check(

View File

@ -196,8 +196,13 @@ class ShareServersAdminTest(base.BaseSharesAdminTest):
if utils.is_microversion_ge(CONF.share.max_api_microversion, "2.49"):
keys.append("is_auto_deletable")
keys.append("identifier")
if utils.is_microversion_ge(CONF.share.max_api_microversion, "2.51"):
if utils.is_microversion_ge(
CONF.share.max_api_microversion, "2.51") and (
utils.is_microversion_lt(
CONF.share.max_api_microversion, "2.70")):
keys.append("share_network_subnet_id")
if utils.is_microversion_ge(CONF.share.max_api_microversion, "2.70"):
keys.append("share_network_subnet_ids")
# all expected keys are present
for key in keys:
self.assertIn(key, server.keys())

View File

@ -66,6 +66,12 @@ class ManageShareServersTest(base.BaseSharesAdminTest):
msg = ("Manage share server with share network subnet is "
"supported starting from microversion '2.51'.")
raise self.skipException(msg)
check_multiple_subnet = utils.is_microversion_ge(
CONF.share.max_api_microversion, '2.70')
if check_multiple_subnet:
network_subnet = 'share_network_subnet_ids'
else:
network_subnet = 'share_network_subnet_id'
# create a new share network to make sure that a new share server
# will be created
original_share_network = self.shares_v2_client.get_share_network(
@ -91,7 +97,7 @@ class ManageShareServersTest(base.BaseSharesAdminTest):
neutron_subnet_id=share_network['neutron_subnet_id'],
availability_zone=az
)['share_network_subnet']
params = {'share_network_subnet_id': az_subnet['id']}
params = {network_subnet: az_subnet['id']}
# create share
share = self.create_share(
@ -119,7 +125,7 @@ class ManageShareServersTest(base.BaseSharesAdminTest):
"identifier",
]
if add_subnet_field:
keys.append('share_network_subnet_id')
keys.append(network_subnet)
# all expected keys are present
for key in keys:
self.assertIn(key, share_server)
@ -127,9 +133,10 @@ class ManageShareServersTest(base.BaseSharesAdminTest):
# check that the share server is initially auto-deletable
self.assertIs(True, share_server["is_auto_deletable"])
self.assertIsNotNone(share_server["identifier"])
if add_subnet_field:
self.assertEqual(az_subnet["id"],
share_server["share_network_subnet_id"])
if add_subnet_field and check_multiple_subnet:
self.assertIn(az_subnet["id"], share_server[network_subnet])
elif add_subnet_field and not check_multiple_subnet:
self.assertEqual(az_subnet["id"], share_server[network_subnet])
self._unmanage_share_and_wait(share)

View File

@ -187,6 +187,145 @@ class ReplicationTest(base.BaseSharesMixedTest):
# Delete subnet
self.shares_v2_client.delete_subnet(self.sn_id, subnet['id'])
@tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
@testtools.skipIf(
not CONF.share.multitenancy_enabled, "Only for multitenancy.")
@testtools.skipIf(
not CONF.share.run_share_server_multiple_subnet_tests,
"Share server multiple subnet tests are disabled.")
@testtools.skipIf(CONF.share.share_network_id != "",
"This test is not suitable for pre-existing "
"share networks.")
@utils.skip_if_microversion_not_supported("2.70")
@decorators.idempotent_id('4235e789-dbd6-47a8-8f2e-d70edf78e532')
def test_add_delete_share_replica_multiple_subnets(self):
extra_specs = {
"replication_type": self.replication_type,
"driver_handles_share_servers": CONF.share.multitenancy_enabled,
"share_server_multiple_subnet_support": True,
}
share_type = self.create_share_type(
extra_specs=extra_specs, client=self.admin_client)
default_subnet = utils.share_network_get_default_subnet(
self.share_network)
new_share_network_id = self.create_share_network(
cleanup_in_class=False)['id']
subnet_data = {
'neutron_net_id': default_subnet.get('neutron_net_id'),
'neutron_subnet_id': default_subnet.get('neutron_subnet_id'),
'share_network_id': new_share_network_id,
'availability_zone': self.replica_zone,
}
subnet1 = self.create_share_network_subnet(**subnet_data)
subnet2 = self.create_share_network_subnet(**subnet_data)
# Creating a third subnet in share replica az
subnet_data.update({'availability_zone': self.share_zone})
subnet3 = self.create_share_network_subnet(**subnet_data)
# Create the share and share replica
share = self.create_share(
share_type_id=share_type['id'], cleanup_in_class=False,
availability_zone=self.share_zone,
share_network_id=new_share_network_id)
share = self.admin_client.get_share(share['id'])['share']
replica = self.create_share_replica(share['id'], self.replica_zone)
replica = self.admin_client.get_share_replica(
replica['id'])['share_replica']
share_server = self.admin_client.show_share_server(
replica['share_server_id'])['share_server']
self.assertIn(subnet1['id'],
share_server['share_network_subnet_ids'])
self.assertIn(subnet2['id'],
share_server['share_network_subnet_ids'])
# Delete the replica
self.delete_share_replica(replica['id'])
# Delete share
self.shares_v2_client.delete_share(share['id'])
self.shares_v2_client.wait_for_resource_deletion(share_id=share['id'])
# Delete subnets
self.shares_v2_client.delete_subnet(
new_share_network_id, subnet1['id'])
self.shares_v2_client.delete_subnet(
new_share_network_id, subnet2['id'])
self.shares_v2_client.delete_subnet(
new_share_network_id, subnet3['id'])
@tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
@testtools.skipIf(
not CONF.share.multitenancy_enabled, "Only for multitenancy.")
@testtools.skipIf(
not CONF.share.run_network_allocation_update_tests,
"Share server network allocation update tests are disabled.")
@testtools.skipIf(CONF.share.share_network_id != "",
"This test is not suitable for pre-existing "
"share_network.")
@utils.skip_if_microversion_not_supported("2.70")
@decorators.idempotent_id('26694947-d4a0-46c8-99e8-2e0eca1b6a08')
def test_add_delete_share_replica_network_allocation_update(self):
extra_specs = {
"replication_type": self.replication_type,
"driver_handles_share_servers": CONF.share.multitenancy_enabled,
"network_allocation_update_support": True,
}
share_type = self.create_share_type(extra_specs=extra_specs)
default_subnet = utils.share_network_get_default_subnet(
self.share_network)
new_share_network_id = self.create_share_network(
cleanup_in_class=False)['id']
subnet_data = {
'neutron_net_id': default_subnet.get('neutron_net_id'),
'neutron_subnet_id': default_subnet.get('neutron_subnet_id'),
'share_network_id': new_share_network_id,
'availability_zone': self.share_zone,
}
subnet1 = self.create_share_network_subnet(**subnet_data)
subnet_data.update({'availability_zone': self.replica_zone})
subnet2 = self.create_share_network_subnet(**subnet_data)
# Create the share and share replica
share = self.create_share(
share_type_id=share_type['id'], cleanup_in_class=False,
availability_zone=self.share_zone,
share_network_id=new_share_network_id)
share = self.admin_client.get_share(share['id'])['share']
replica = self.create_share_replica(share['id'], self.replica_zone)
replica = self.admin_client.get_share_replica(
replica['id'])['share_replica']
# Waits until the check is completed and positive
waiters.wait_for_subnet_create_check(
self.shares_v2_client, new_share_network_id,
neutron_net_id=subnet_data['neutron_net_id'],
neutron_subnet_id=subnet_data['neutron_subnet_id'],
availability_zone=self.replica_zone)
# Creating a third subnet in replica zone to trigger the network
# allocation update
subnet3 = self.create_share_network_subnet(**subnet_data)
waiters.wait_for_resource_status(
self.admin_client, replica['share_server_id'],
constants.SERVER_STATE_ACTIVE,
resource_name="share_server",
status_attr="status")
share_server = self.admin_client.show_share_server(
replica['share_server_id']
)['share_server']
self.assertIn(subnet2['id'],
share_server['share_network_subnet_ids'])
self.assertIn(subnet3['id'],
share_server['share_network_subnet_ids'])
# Delete the replica
self.delete_share_replica(replica['id'])
# Delete share
self.shares_v2_client.delete_share(share['id'])
self.shares_v2_client.wait_for_resource_deletion(share_id=share['id'])
# Delete subnets
self.shares_v2_client.delete_subnet(
new_share_network_id, subnet1['id'])
self.shares_v2_client.delete_subnet(
new_share_network_id, subnet2['id'])
self.shares_v2_client.delete_subnet(
new_share_network_id, subnet3['id'])
@decorators.idempotent_id('00e12b41-b95d-494a-99be-e584aae10f5c')
@tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
def test_add_access_rule_create_replica_delete_rule(self):

View File

@ -15,12 +15,14 @@
import ddt
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
import testtools
from testtools import testcase as tc
from manila_tempest_tests.common import constants
from manila_tempest_tests.common import waiters
from manila_tempest_tests.tests.api import base
from manila_tempest_tests import utils
@ -263,3 +265,130 @@ class ShareGroupsTest(base.BaseSharesMixedTest):
# Verify that share always has the same AZ as share group does
self.assertEqual(
share_group['availability_zone'], share['availability_zone'])
@utils.skip_if_microversion_not_supported("2.70")
@tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
@testtools.skipUnless(CONF.share.multitenancy_enabled,
"Multitenancy is disabled.")
@testtools.skipUnless(CONF.share.run_share_server_multiple_subnet_tests,
"Share server multiple subnet tests are disabled.")
@testtools.skipIf(CONF.share.share_network_id != "",
"This test is not suitable for pre-existing "
"share networks.")
@ddt.data(False, True)
@decorators.idempotent_id('17fd1867-03a3-43d0-9be3-daf90b6c5e02')
def test_create_sg_and_share_with_multiple_subnets(
self, network_allocation_update):
if network_allocation_update and not (
CONF.share.run_network_allocation_update_tests):
raise self.skipException(
'Network allocation update tests are disabled.')
extra_specs = {
'driver_handles_share_servers': CONF.share.multitenancy_enabled,
'share_server_multiple_subnet_support': True,
}
if network_allocation_update:
extra_specs['network_allocation_update_support'] = True
share_type = self.create_share_type(extra_specs=extra_specs)
sg_type_name = data_utils.rand_name("tempest-manila")
sg_type = self.create_share_group_type(
name=sg_type_name, share_types=share_type['id'],
client=self.admin_shares_v2_client)
# Get list of existing availability zones, at least one always
# should exist
azs = self.get_availability_zones_matching_share_type(share_type)
if len(azs) == 0:
raise self.skipException(
"No AZs were found. Make sure there is at least one "
"configured.")
share_network = self.shares_v2_client.get_share_network(
self.shares_v2_client.share_network_id)['share_network']
new_share_network_id = self.create_share_network(
cleanup_in_class=False)['id']
default_subnet = utils.share_network_get_default_subnet(
share_network)
subnet_data = {
'neutron_net_id': default_subnet.get('neutron_net_id'),
'neutron_subnet_id': default_subnet.get('neutron_subnet_id'),
'share_network_id': new_share_network_id,
'availability_zone': azs[0]
}
subnet1 = self.create_share_network_subnet(**subnet_data)
if not network_allocation_update:
subnet2 = self.create_share_network_subnet(**subnet_data)
sg_kwargs = {
'share_group_type_id': sg_type['id'],
'share_type_ids': [share_type['id']],
'share_network_id': new_share_network_id,
'availability_zone': azs[0],
'version': constants.MIN_SHARE_GROUP_MICROVERSION,
'cleanup_in_class': False,
}
# Create share group
share_group = self.create_share_group(**sg_kwargs)
# Get latest share group info
share_group = self.shares_v2_client.get_share_group(
share_group['id'])['share_group']
self.assertIn('availability_zone', share_group)
self.assertEqual(azs[0], share_group['availability_zone'])
# Test 'consistent_snapshot_support' as part of 2.33 API change
self.assertIn('consistent_snapshot_support', share_group)
self.assertIn(
share_group['consistent_snapshot_support'], ('host', 'pool', None))
share_data = {
'share_type_id': share_type['id'],
'share_group_id': share_group['id'],
'share_network_id': new_share_network_id,
'availability_zone': azs[0],
'cleanup_in_class': False,
}
# Create share in share group
share = self.create_share(**share_data)
# Get latest share info
share = self.admin_shares_v2_client.get_share(share['id'])['share']
# Verify that share always has the same AZ as share group does
self.assertEqual(
share_group['availability_zone'], share['availability_zone'])
# Get share server info
share_server = self.admin_shares_v2_client.show_share_server(
share['share_server_id'])['share_server']
if network_allocation_update:
waiters.wait_for_subnet_create_check(
self.shares_v2_client, new_share_network_id,
neutron_net_id=subnet_data['neutron_net_id'],
neutron_subnet_id=subnet_data['neutron_subnet_id'],
availability_zone=azs[0])
subnet2 = self.create_share_network_subnet(**subnet_data)
waiters.wait_for_resource_status(
self.admin_shares_v2_client, share['share_server_id'],
constants.SERVER_STATE_ACTIVE,
resource_name="share_server",
status_attr="status")
share_server = self.admin_shares_v2_client.show_share_server(
share['share_server_id'])['share_server']
# Check if share server has multiple subnets
self.assertIn(subnet1['id'], share_server['share_network_subnet_ids'])
self.assertIn(subnet2['id'], share_server['share_network_subnet_ids'])
# Delete share
params = {"share_group_id": share_group['id']}
self.shares_v2_client.delete_share(
share['id'],
params=params,
version=constants.MIN_SHARE_GROUP_MICROVERSION)
self.shares_client.wait_for_resource_deletion(share_id=share['id'])
# Delete subnet
self.shares_v2_client.delete_subnet(
new_share_network_id, subnet1['id'])
self.shares_v2_client.delete_subnet(
new_share_network_id, subnet2['id'])

View File

@ -127,6 +127,8 @@ class ShareNetworkSubnetsTest(base.BaseSharesMixedTest):
msg = ("This test needs at least two compatible storage "
"availability zones.")
raise self.skipException(msg)
check_multiple_subnet = utils.is_microversion_ge(
CONF.share.max_api_microversion, '2.70')
original_share_network = self.shares_v2_client.get_share_network(
self.shares_v2_client.share_network_id
@ -173,8 +175,12 @@ class ShareNetworkSubnetsTest(base.BaseSharesMixedTest):
# Match new subnet content
self.assertDictContainsSubset(data, subnet)
# Match share server subnet
self.assertEqual(subnet['id'],
share_server['share_network_subnet_id'])
if check_multiple_subnet:
self.assertIn(subnet['id'],
share_server['share_network_subnet_ids'])
else:
self.assertIn(subnet['id'],
share_server['share_network_subnet_id'])
# Delete share
self.shares_v2_client.delete_share(share['id'])
self.shares_v2_client.wait_for_resource_deletion(share_id=share['id'])
@ -197,10 +203,11 @@ class ShareNetworkSubnetsTest(base.BaseSharesMixedTest):
msg = ("This test needs at least two compatible storage "
"availability zones.")
raise self.skipException(msg)
check_multiple_subnet = utils.is_microversion_ge(
CONF.share.max_api_microversion, '2.70')
original_share_network = self.shares_v2_client.get_share_network(
self.shares_v2_client.share_network_id
)['share_network']
self.shares_v2_client.share_network_id)['share_network']
share_net_info = (
utils.share_network_get_default_subnet(original_share_network))
share_network = self.create_share_network(
@ -254,8 +261,12 @@ class ShareNetworkSubnetsTest(base.BaseSharesMixedTest):
# Default subnet was created during share network creation
self.assertIsNone(default_subnet['availability_zone'])
# Match share server subnet
self.assertEqual(expected_subnet_id,
share_server['share_network_subnet_id'])
if not check_multiple_subnet:
self.assertEqual(
expected_subnet_id, share_server['share_network_subnet_id'])
else:
self.assertIn(
expected_subnet_id, share_server['share_network_subnet_ids'])
if create_share_with_az:
self.assertEqual(destination_az,
share['availability_zone'])

View File

@ -27,6 +27,7 @@ from manila_tempest_tests import utils
CONF = config.CONF
LATEST_MICROVERSION = CONF.share.max_api_microversion
@ddt.ddt
@ -72,6 +73,7 @@ class ShareNetworkSubnetsNegativeTest(base.BaseSharesAdminTest):
@decorators.idempotent_id('13f397bf-5e3a-42b0-b4f9-9cd2dbbb0955')
@tc.attr(base.TAG_NEGATIVE, base.TAG_API)
@ddt.data(True, False)
@utils.skip_if_is_microversion_ge(LATEST_MICROVERSION, "2.70")
def test_add_share_network_subnet_in_same_az_exists(self, is_default):
share_network = self.shares_v2_client.create_share_network(
)['share_network']
@ -231,7 +233,8 @@ class ShareNetworkSubnetsNegativeTest(base.BaseSharesAdminTest):
# Get a compatible availability zone
az = self.get_availability_zones_matching_share_type(
self.share_type)[0]
check_multiple_subnets = utils.is_microversion_ge(
CONF.share.max_api_microversion, '2.70')
original_share_network = self.shares_v2_client.get_share_network(
self.shares_v2_client.share_network_id
)['share_network']
@ -269,8 +272,12 @@ class ShareNetworkSubnetsNegativeTest(base.BaseSharesAdminTest):
share['share_server_id']
)['share_server']
# Match share server subnet
self.assertEqual(subnet['id'],
share_server['share_network_subnet_id'])
if check_multiple_subnets:
self.assertIn(subnet['id'],
share_server['share_network_subnet_ids'])
else:
self.assertEqual(subnet['id'],
share_server['share_network_subnet_id'])
# Assert that the user cannot delete a subnet that contain shares
self.assertRaises(lib_exc.Conflict,

View File

@ -195,3 +195,24 @@ class ShareNetworksNegativeTest(base.BaseSharesMixedTest):
self.shares_v2_client.create_share_network,
availability_zone='inexistent-availability-zone',
)
@utils.skip_if_microversion_not_supported("2.70")
@tc.attr(base.TAG_NEGATIVE, base.TAG_API)
@decorators.idempotent_id('f6f47c64-6821-4d4a-aa7d-3b0244158197')
def test_check_add_share_network_subnet_share_network_not_found(self):
data = self.generate_subnet_data()
self.assertRaises(lib_exc.NotFound,
self.shares_v2_client.subnet_create_check,
'fake_inexistent_id',
**data)
@utils.skip_if_microversion_not_supported("2.70")
@tc.attr(base.TAG_NEGATIVE, base.TAG_API)
@decorators.idempotent_id('d9a487fb-6638-4f93-8b69-3e1a85bfbc7d')
def test_check_add_share_network_subnet_az_not_found(self):
share_network = self.create_share_network()
data = {'availability_zone': 'non-existent-az'}
self.assertRaises(lib_exc.BadRequest,
self.shares_v2_client.subnet_create_check,
share_network['id'], **data)

View File

@ -0,0 +1,196 @@
# Copyright 2022 NetApp Inc.
# 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 import config
from tempest.lib import decorators
import testtools
from testtools import testcase as tc
from manila_tempest_tests.common import constants
from manila_tempest_tests.common import waiters
from manila_tempest_tests.tests.api import base
from manila_tempest_tests import utils
CONF = config.CONF
class ShareServerMultipleSubnetTest(base.BaseSharesMixedTest):
@classmethod
def skip_checks(cls):
super(ShareServerMultipleSubnetTest, cls).skip_checks()
if not CONF.share.multitenancy_enabled:
raise cls.skipException('Multitenancy tests are disabled.')
if not CONF.share.run_share_server_multiple_subnet_tests and not (
CONF.share.run_network_allocation_update_tests):
raise cls.skipException(
'Share server multiple subnets and network allocation '
'update tests are disabled.')
if CONF.share.share_network_id != "":
raise cls.skipException(
'These tests are not suitable for pre-existing '
'share_network.')
utils.check_skip_if_microversion_not_supported("2.70")
@classmethod
def resource_setup(cls):
super(ShareServerMultipleSubnetTest, cls).resource_setup()
cls.extra_specs = {
'driver_handles_share_servers': CONF.share.multitenancy_enabled,
}
if CONF.share.run_share_server_multiple_subnet_tests:
cls.extra_specs['share_server_multiple_subnet_support'] = True
if CONF.share.run_network_allocation_update_tests:
cls.extra_specs['network_allocation_update_support'] = True
share_type = cls.create_share_type(extra_specs=cls.extra_specs)
cls.share_type_id = share_type['id']
cls.zones = cls.get_availability_zones_matching_share_type(
share_type)
if len(cls.zones) == 0:
msg = ("These tests need at least one compatible "
"availability zone.")
raise cls.skipException(msg)
cls.share_network = cls.alt_shares_v2_client.get_share_network(
cls.alt_shares_v2_client.share_network_id)['share_network']
cls.default_subnet = utils.share_network_get_default_subnet(
cls.share_network)
@tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
@testtools.skipIf(
not CONF.share.run_share_server_multiple_subnet_tests,
"Share network multiple subnets tests are disabled.")
@decorators.idempotent_id('5600bd52-ecb4-47d3-a4e8-3e6565cb0b80')
def test_create_share_on_multiple_subnets_same_az(self):
share_network_id = self.create_share_network(
cleanup_in_class=False)["id"]
subnet_data = {
'neutron_net_id': self.default_subnet.get('neutron_net_id'),
'neutron_subnet_id': self.default_subnet.get('neutron_subnet_id'),
'share_network_id': share_network_id,
'availability_zone': self.zones[0],
}
subnet1 = self.create_share_network_subnet(**subnet_data)
subnet2 = self.create_share_network_subnet(**subnet_data)
share = self.create_share(
share_type_id=self.share_type_id,
share_network_id=share_network_id,
availability_zone=self.zones[0])
self.assertIn(share['status'], ('creating', 'available'))
share = self.admin_shares_v2_client.get_share(share['id'])['share']
share_server = self.admin_shares_v2_client.show_share_server(
share['share_server_id']
)['share_server']
self.assertIn(subnet1['id'],
share_server['share_network_subnet_ids'])
self.assertIn(subnet2['id'],
share_server['share_network_subnet_ids'])
# Delete share
self.shares_v2_client.delete_share(share['id'])
self.shares_v2_client.wait_for_resource_deletion(share_id=share['id'])
# Delete the subnets
self.shares_v2_client.delete_subnet(share_network_id, subnet1['id'])
self.shares_v2_client.delete_subnet(share_network_id, subnet2['id'])
@tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
@testtools.skipIf(
not CONF.share.run_network_allocation_update_tests,
"Share server network allocation update are disabled.")
@decorators.idempotent_id('2a9debd5-47a3-42cc-823b-2b9de435a5e4')
def test_create_share_with_network_allocation_update(self):
share_network_id = self.create_share_network(
cleanup_in_class=False)["id"]
subnet_data = {
'neutron_net_id': self.default_subnet.get('neutron_net_id'),
'neutron_subnet_id': self.default_subnet.get('neutron_subnet_id'),
'share_network_id': share_network_id,
'availability_zone': self.zones[0],
}
subnet1 = self.create_share_network_subnet(**subnet_data)
share = self.create_share(
share_type_id=self.share_type_id,
share_network_id=share_network_id,
availability_zone=self.zones[0])
self.assertIn(share['status'], ('creating', 'available'))
share = self.admin_shares_v2_client.get_share(share['id'])['share']
waiters.wait_for_subnet_create_check(
self.shares_v2_client, share_network_id,
neutron_net_id=subnet_data['neutron_net_id'],
neutron_subnet_id=subnet_data['neutron_subnet_id'],
availability_zone=self.zones[0])
subnet2 = self.create_share_network_subnet(**subnet_data)
waiters.wait_for_resource_status(
self.admin_shares_v2_client, share['share_server_id'],
constants.SERVER_STATE_ACTIVE,
resource_name="share_server",
status_attr="status")
share_server = self.admin_shares_v2_client.show_share_server(
share['share_server_id']
)['share_server']
self.assertIn(subnet1['id'],
share_server['share_network_subnet_ids'])
self.assertIn(subnet2['id'],
share_server['share_network_subnet_ids'])
# Delete share
self.shares_v2_client.delete_share(share['id'])
self.shares_v2_client.wait_for_resource_deletion(share_id=share['id'])
# Delete subnets
self.shares_v2_client.delete_subnet(share_network_id, subnet1['id'])
self.shares_v2_client.delete_subnet(share_network_id, subnet2['id'])
@tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
@testtools.skipIf(
not CONF.share.run_network_allocation_update_tests,
"Share server network allocation update are disabled.")
@decorators.idempotent_id('2624f9a7-660b-4f91-89b8-c026b3bb8d1f')
def test_share_network_subnet_create_check(self):
"""The share network subnet create check compatibility test."""
share_network_id = self.create_share_network(
cleanup_in_class=False)["id"]
subnet_data = {
'neutron_net_id': self.default_subnet.get('neutron_net_id'),
'neutron_subnet_id': self.default_subnet.get('neutron_subnet_id'),
'share_network_id': share_network_id,
'availability_zone': self.zones[0],
}
subnet1 = self.create_share_network_subnet(**subnet_data)
share = self.create_share(
share_type_id=self.share_type_id,
share_network_id=share_network_id,
availability_zone=self.zones[0]
)
self.assertIn(share['status'], ('creating', 'available'))
waiters.wait_for_subnet_create_check(
self.shares_v2_client, share_network_id,
neutron_net_id=subnet_data['neutron_net_id'],
neutron_subnet_id=subnet_data['neutron_subnet_id'],
availability_zone=self.zones[0])
# Delete share
self.shares_v2_client.delete_share(share['id'])
self.shares_v2_client.wait_for_resource_deletion(share_id=share['id'])
# Delete subnets
self.shares_v2_client.delete_subnet(share_network_id, subnet1['id'])

View File

@ -0,0 +1,90 @@
# Copyright 2022 NetApp Inc.
# 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 import config
from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
from testtools import testcase as tc
from manila_tempest_tests import share_exceptions
from manila_tempest_tests.tests.api import base
from manila_tempest_tests import utils
CONF = config.CONF
class ShareServerMultipleSubNegativeTest(base.BaseSharesMixedTest):
@classmethod
def skip_checks(cls):
super(ShareServerMultipleSubNegativeTest, cls).skip_checks()
if not CONF.share.multitenancy_enabled:
raise cls.skipException('Multitenancy tests are disabled.')
utils.check_skip_if_microversion_not_supported("2.70")
@classmethod
def resource_setup(cls):
super(ShareServerMultipleSubNegativeTest, cls).resource_setup()
cls.share_network = cls.alt_shares_v2_client.get_share_network(
cls.alt_shares_v2_client.share_network_id)['share_network']
@tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
@decorators.idempotent_id('1e2a9415-b02f-4c02-812d-bedc361f92ce')
def test_create_share_multiple_subnets_to_unsupported_backend(self):
extra_specs = {
'driver_handles_share_servers': CONF.share.multitenancy_enabled,
'share_server_multiple_subnet_support': False
}
share_type = self.create_share_type(extra_specs=extra_specs)
pools = self.get_pools_matching_share_type(
share_type, client=self.admin_shares_v2_client)
zones = self.get_availability_zones_matching_share_type(
share_type)
if not pools or not zones:
raise self.skipException("At least one backend that supports "
"adding multiple subnets into a share "
"network is needed for this test.")
extra_specs = {'pool_name': pools[0]['pool'],
'availability_zone': zones[0]}
self.admin_shares_v2_client.update_share_type_extra_specs(
share_type['id'], extra_specs)
share_network_id = self.create_share_network(
cleanup_in_class=True)["id"]
default_subnet = utils.share_network_get_default_subnet(
self.share_network)
subnet_data = {
'neutron_net_id': default_subnet.get('neutron_net_id'),
'neutron_subnet_id': default_subnet.get('neutron_subnet_id'),
'share_network_id': share_network_id,
'availability_zone': zones[0],
'cleanup_in_class': False
}
subnet1 = self.create_share_network_subnet(**subnet_data)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.shares_v2_client.delete_subnet,
share_network_id, subnet1['id'])
subnet2 = self.create_share_network_subnet(**subnet_data)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.shares_v2_client.delete_subnet,
share_network_id, subnet2['id'])
self.assertRaises(
share_exceptions.ShareBuildErrorException,
self.create_share,
share_type_id=share_type['id'],
share_network_id=share_network_id,
availability_zone=zones[0],
cleanup_in_class=False
)

View File

@ -94,6 +94,16 @@ def skip_if_microversion_not_supported(microversion):
return lambda f: f
def skip_if_is_microversion_ge(left, right):
"""Skip if version for left is greater than or equal to the right one."""
if is_microversion_ge(left, right):
reason = ("Skipped. Test requires microversion "
"< than '%s'." % right)
return testtools.skip(reason)
return lambda f: f
def check_skip_if_microversion_not_supported(microversion):
"""Callable method for tests that are microversion-specific."""
if not is_microversion_supported(microversion):

View File

@ -246,6 +246,8 @@
backend_names: LONDON,PARIS
multi_backend: true
run_share_server_migration_tests: true
run_share_server_multiple_subnet_tests: true
run_network_allocation_update_tests: true
- job:
name: manila-tempest-plugin-generic
@ -490,6 +492,8 @@
run_replication_tests: true
run_revert_to_snapshot_tests: true
run_share_server_migration_tests: true
run_share_server_multiple_subnet_tests: true
run_network_allocation_update_tests: true
- job:
name: manila-tempest-plugin-glusterfs-native