Add functional tests for add multiple subnets feature
This change adds negative and positive functional tests for the new feature add multiple subnets per az. Older functional tests impacted by the feature are fixed. Finally, the new flags `run_share_server_multiple_subnets_tests` and `run_network_allocation_update_tests` are added and configured in the community jobs for Dummy DHSS=True and Container Driver. Partially-Implements: blueprint multiple-share-network-subnets Change-Id: I99547e1873646fb1494a454f67b14c7293342beb
This commit is contained in:
parent
88225a342c
commit
c1a3c0e54e
|
@ -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)
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -1953,6 +1953,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(
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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'])
|
||||
|
|
|
@ -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'])
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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'])
|
|
@ -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
|
||||
)
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue