Improve Share Migration tempest tests

Improve coverage by adding tests that validate the share-type
change while also changing the driver mode.

Closes-bug: #1620800

Change-Id: I924c34aa69591754b437d75f43db91d77e73fb07
This commit is contained in:
Rodrigo Barbieri 2016-09-06 13:16:47 -03:00
parent 7a16eb685b
commit 053acc8db1
7 changed files with 303 additions and 123 deletions

View File

@ -68,6 +68,7 @@ fi
# Set MANILA_ADMIN_NET_RANGE for admin_network and data_service IP # Set MANILA_ADMIN_NET_RANGE for admin_network and data_service IP
echo "MANILA_ADMIN_NET_RANGE=${MANILA_ADMIN_NET_RANGE:=10.2.5.0/24}" >> $localrc_path echo "MANILA_ADMIN_NET_RANGE=${MANILA_ADMIN_NET_RANGE:=10.2.5.0/24}" >> $localrc_path
echo "MANILA_DATA_NODE_IP=${MANILA_DATA_NODE_IP:=$MANILA_ADMIN_NET_RANGE}" >> $localrc_path echo "MANILA_DATA_NODE_IP=${MANILA_DATA_NODE_IP:=$MANILA_ADMIN_NET_RANGE}" >> $localrc_path
echo "MANILA_DATA_COPY_CHECK_HASH=${MANILA_DATA_COPY_CHECK_HASH:=True}" >> $localrc_path
# Share Migration CI tests migration_continue period task interval # Share Migration CI tests migration_continue period task interval
echo "MANILA_SHARE_MIGRATION_PERIOD_TASK_INTERVAL=${MANILA_SHARE_MIGRATION_PERIOD_TASK_INTERVAL:=5}" >> $localrc_path echo "MANILA_SHARE_MIGRATION_PERIOD_TASK_INTERVAL=${MANILA_SHARE_MIGRATION_PERIOD_TASK_INTERVAL:=5}" >> $localrc_path

View File

@ -186,6 +186,10 @@ function configure_manila {
iniset $MANILA_CONF DEFAULT migration_driver_continue_update_interval $MANILA_SHARE_MIGRATION_PERIOD_TASK_INTERVAL iniset $MANILA_CONF DEFAULT migration_driver_continue_update_interval $MANILA_SHARE_MIGRATION_PERIOD_TASK_INTERVAL
fi fi
if ! [[ -z $MANILA_DATA_COPY_CHECK_HASH ]]; then
iniset $MANILA_CONF DEFAULT check_hash $MANILA_DATA_COPY_CHECK_HASH
fi
iniset $MANILA_CONF DEFAULT enabled_share_protocols $MANILA_ENABLED_SHARE_PROTOCOLS iniset $MANILA_CONF DEFAULT enabled_share_protocols $MANILA_ENABLED_SHARE_PROTOCOLS
iniset $MANILA_CONF oslo_concurrency lock_path $MANILA_LOCK_PATH iniset $MANILA_CONF oslo_concurrency lock_path $MANILA_LOCK_PATH

View File

@ -176,6 +176,9 @@ MANILA_ADMIN_NET_RANGE=${MANILA_ADMIN_NET_RANGE:=10.2.5.0/24}
# Data Service IP configuration # Data Service IP configuration
MANILA_DATA_NODE_IP=${MANILA_DATA_NODE_IP:=$MANILA_ADMIN_NET_RANGE} MANILA_DATA_NODE_IP=${MANILA_DATA_NODE_IP:=$MANILA_ADMIN_NET_RANGE}
# Data Service copy validation
MANILA_DATA_COPY_CHECK_HASH=${MANILA_DATA_COPY_CHECK_HASH:=True}
# Enable manila services # Enable manila services
# ---------------------- # ----------------------
# We have to add Manila to enabled services for screen_it to work # We have to add Manila to enabled services for screen_it to work

View File

@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import six
import ddt import ddt
from tempest import config from tempest import config
@ -39,6 +38,8 @@ class MigrationNFSTest(base.BaseSharesAdminTest):
2) Host-assisted migration: force_host_assisted_migration is True, 2) Host-assisted migration: force_host_assisted_migration is True,
nondisruptive, writable and preserve-metadata are False. nondisruptive, writable and preserve-metadata are False.
3) 2-phase migration of both Host-assisted and Driver-assisted. 3) 2-phase migration of both Host-assisted and Driver-assisted.
4) Cancelling migration past first phase.
5) Changing driver modes through migration.
No need to test with writable, preserve-metadata and non-disruptive as No need to test with writable, preserve-metadata and non-disruptive as
True, values are supplied to the driver which decides what to do. Test True, values are supplied to the driver which decides what to do. Test
@ -62,17 +63,16 @@ class MigrationNFSTest(base.BaseSharesAdminTest):
CONF.share.run_driver_assisted_migration_tests): CONF.share.run_driver_assisted_migration_tests):
raise cls.skipException("Share migration tests are disabled.") raise cls.skipException("Share migration tests are disabled.")
extra_specs = {
'storage_protocol': CONF.share.capability_storage_protocol,
'driver_handles_share_servers': (
CONF.share.multitenancy_enabled),
'snapshot_support': six.text_type(
CONF.share.capability_snapshot_support),
}
cls.new_type = cls.create_share_type( cls.new_type = cls.create_share_type(
name=data_utils.rand_name('new_share_type_for_migration'), name=data_utils.rand_name('new_share_type_for_migration'),
cleanup_in_class=True, cleanup_in_class=True,
extra_specs=extra_specs) extra_specs=utils.get_configured_extra_specs())
cls.new_type_opposite = cls.create_share_type(
name=data_utils.rand_name('new_share_type_for_migration_opposite'),
cleanup_in_class=True,
extra_specs=utils.get_configured_extra_specs(
variation='opposite_driver_modes'))
@test.attr(type=[base.TAG_POSITIVE, base.TAG_BACKEND]) @test.attr(type=[base.TAG_POSITIVE, base.TAG_BACKEND])
@base.skip_if_microversion_lt("2.22") @base.skip_if_microversion_lt("2.22")
@ -83,13 +83,6 @@ class MigrationNFSTest(base.BaseSharesAdminTest):
share, dest_pool = self._setup_migration() share, dest_pool = self._setup_migration()
old_exports = self.shares_v2_client.list_share_export_locations(
share['id'])
self.assertNotEmpty(old_exports)
old_exports = [x['path'] for x in old_exports
if x['is_admin_only'] is False]
self.assertNotEmpty(old_exports)
task_state = (constants.TASK_STATE_DATA_COPYING_COMPLETED task_state = (constants.TASK_STATE_DATA_COPYING_COMPLETED
if force_host_assisted if force_host_assisted
else constants.TASK_STATE_MIGRATION_DRIVER_PHASE1_DONE) else constants.TASK_STATE_MIGRATION_DRIVER_PHASE1_DONE)
@ -101,12 +94,83 @@ class MigrationNFSTest(base.BaseSharesAdminTest):
self._validate_migration_successful( self._validate_migration_successful(
dest_pool, share, task_state, complete=False) dest_pool, share, task_state, complete=False)
progress = self.shares_v2_client.migration_get_progress(share['id'])
self.assertEqual(task_state, progress['task_state'])
self.assertEqual(100, progress['total_progress'])
share = self.migration_cancel(share['id'], dest_pool) share = self.migration_cancel(share['id'], dest_pool)
progress = self.shares_v2_client.migration_get_progress(share['id'])
self.assertEqual(
constants.TASK_STATE_MIGRATION_CANCELLED, progress['task_state'])
self.assertEqual(100, progress['total_progress'])
self._validate_migration_successful( self._validate_migration_successful(
dest_pool, share, constants.TASK_STATE_MIGRATION_CANCELLED, dest_pool, share, constants.TASK_STATE_MIGRATION_CANCELLED,
complete=False) complete=False)
@test.attr(type=[base.TAG_POSITIVE, base.TAG_BACKEND])
@base.skip_if_microversion_lt("2.22")
@ddt.data(True, False)
def test_migration_opposite_driver_modes(self, force_host_assisted):
self._check_migration_enabled(force_host_assisted)
share, dest_pool = self._setup_migration(opposite=True)
old_share_network_id = share['share_network_id']
# If currently configured is DHSS=False,
# then we need it for DHSS=True
if not CONF.share.multitenancy_enabled:
new_share_network_id = self.provide_share_network(
self.shares_v2_client, self.os_admin.networks_client,
isolated_creds_client=None, ignore_multitenancy_config=True)
# If currently configured is DHSS=True,
# then we must pass None for DHSS=False
else:
new_share_network_id = None
old_share_type_id = share['share_type']
new_share_type_id = self.new_type_opposite['share_type']['id']
task_state = (constants.TASK_STATE_DATA_COPYING_COMPLETED
if force_host_assisted
else constants.TASK_STATE_MIGRATION_DRIVER_PHASE1_DONE)
share = self.migrate_share(
share['id'], dest_pool,
force_host_assisted_migration=force_host_assisted,
wait_for_status=task_state, new_share_type_id=new_share_type_id,
new_share_network_id=new_share_network_id)
self._validate_migration_successful(
dest_pool, share, task_state, complete=False,
share_network_id=old_share_network_id,
share_type_id=old_share_type_id)
progress = self.shares_v2_client.migration_get_progress(share['id'])
self.assertEqual(task_state, progress['task_state'])
self.assertEqual(100, progress['total_progress'])
share = self.migration_complete(share['id'], dest_pool)
progress = self.shares_v2_client.migration_get_progress(share['id'])
self.assertEqual(
constants.TASK_STATE_MIGRATION_SUCCESS, progress['task_state'])
self.assertEqual(100, progress['total_progress'])
self._validate_migration_successful(
dest_pool, share, constants.TASK_STATE_MIGRATION_SUCCESS,
complete=True, share_network_id=new_share_network_id,
share_type_id=new_share_type_id)
@test.attr(type=[base.TAG_POSITIVE, base.TAG_BACKEND]) @test.attr(type=[base.TAG_POSITIVE, base.TAG_BACKEND])
@base.skip_if_microversion_lt("2.22") @base.skip_if_microversion_lt("2.22")
@ddt.data(True, False) @ddt.data(True, False)
@ -116,20 +180,18 @@ class MigrationNFSTest(base.BaseSharesAdminTest):
share, dest_pool = self._setup_migration() share, dest_pool = self._setup_migration()
old_exports = self.shares_v2_client.list_share_export_locations(
share['id'])
self.assertNotEmpty(old_exports)
old_exports = [x['path'] for x in old_exports
if x['is_admin_only'] is False]
self.assertNotEmpty(old_exports)
task_state = (constants.TASK_STATE_DATA_COPYING_COMPLETED task_state = (constants.TASK_STATE_DATA_COPYING_COMPLETED
if force_host_assisted if force_host_assisted
else constants.TASK_STATE_MIGRATION_DRIVER_PHASE1_DONE) else constants.TASK_STATE_MIGRATION_DRIVER_PHASE1_DONE)
old_share_network_id = share['share_network_id'] old_share_network_id = share['share_network_id']
if CONF.share.multitenancy_enabled:
new_share_network_id = self._create_secondary_share_network( new_share_network_id = self._create_secondary_share_network(
old_share_network_id) old_share_network_id)
else:
new_share_network_id = None
old_share_type_id = share['share_type'] old_share_type_id = share['share_type']
new_share_type_id = self.new_type['share_type']['id'] new_share_type_id = self.new_type['share_type']['id']
@ -151,12 +213,18 @@ class MigrationNFSTest(base.BaseSharesAdminTest):
share = self.migration_complete(share['id'], dest_pool) share = self.migration_complete(share['id'], dest_pool)
progress = self.shares_v2_client.migration_get_progress(share['id'])
self.assertEqual(
constants.TASK_STATE_MIGRATION_SUCCESS, progress['task_state'])
self.assertEqual(100, progress['total_progress'])
self._validate_migration_successful( self._validate_migration_successful(
dest_pool, share, constants.TASK_STATE_MIGRATION_SUCCESS, dest_pool, share, constants.TASK_STATE_MIGRATION_SUCCESS,
complete=True, share_network_id=new_share_network_id, complete=True, share_network_id=new_share_network_id,
share_type_id=new_share_type_id) share_type_id=new_share_type_id)
def _setup_migration(self): def _setup_migration(self, opposite=False):
pools = self.shares_v2_client.list_pools(detail=True)['pools'] pools = self.shares_v2_client.list_pools(detail=True)['pools']
@ -167,23 +235,40 @@ class MigrationNFSTest(base.BaseSharesAdminTest):
share = self.create_share(self.protocol) share = self.create_share(self.protocol)
share = self.shares_v2_client.get_share(share['id']) share = self.shares_v2_client.get_share(share['id'])
old_exports = self.shares_v2_client.list_share_export_locations(
share['id'])
self.assertNotEmpty(old_exports)
old_exports = [x['path'] for x in old_exports
if x['is_admin_only'] is False]
self.assertNotEmpty(old_exports)
self.shares_v2_client.create_access_rule( self.shares_v2_client.create_access_rule(
share['id'], access_to="50.50.50.50", access_level="rw") share['id'], access_to="50.50.50.50", access_level="rw")
self.shares_v2_client.wait_for_share_status( self.shares_v2_client.wait_for_share_status(
share['id'], 'active', status_attr='access_rules_status') share['id'], constants.RULE_STATE_ACTIVE,
status_attr='access_rules_status')
self.shares_v2_client.create_access_rule( self.shares_v2_client.create_access_rule(
share['id'], access_to="51.51.51.51", access_level="ro") share['id'], access_to="51.51.51.51", access_level="ro")
self.shares_v2_client.wait_for_share_status( self.shares_v2_client.wait_for_share_status(
share['id'], 'active', status_attr='access_rules_status') share['id'], constants.RULE_STATE_ACTIVE,
status_attr='access_rules_status')
default_type = self.shares_v2_client.list_share_types( if opposite:
default=True)['share_type'] dest_type = self.new_type_opposite['share_type']
else:
dest_type = self.new_type['share_type']
dest_pool = utils.choose_matching_backend(share, pools, default_type) dest_pool = utils.choose_matching_backend(share, pools, dest_type)
if opposite:
if not dest_pool:
raise self.skipException(
"This test requires two pools enabled with different "
"driver modes.")
else:
self.assertIsNotNone(dest_pool) self.assertIsNotNone(dest_pool)
self.assertIsNotNone(dest_pool.get('name')) self.assertIsNotNone(dest_pool.get('name'))
@ -216,9 +301,33 @@ class MigrationNFSTest(base.BaseSharesAdminTest):
# Share migrated # Share migrated
if complete: if complete:
self.assertEqual(dest_pool, share['host']) self.assertEqual(dest_pool, share['host'])
rules = self.shares_v2_client.list_access_rules(share['id'])
expected_rules = [{
'state': constants.RULE_STATE_ACTIVE,
'access_to': '50.50.50.50',
'access_type': 'ip',
'access_level': 'rw',
}, {
'state': constants.RULE_STATE_ACTIVE,
'access_to': '51.51.51.51',
'access_type': 'ip',
'access_level': 'ro',
}]
filtered_rules = [{'state': rule['state'],
'access_to': rule['access_to'],
'access_level': rule['access_level'],
'access_type': rule['access_type']}
for rule in rules]
for r in expected_rules:
self.assertIn(r, filtered_rules)
self.assertEqual(len(expected_rules), len(filtered_rules))
self.shares_v2_client.delete_share(share['id']) self.shares_v2_client.delete_share(share['id'])
self.shares_v2_client.wait_for_resource_deletion( self.shares_v2_client.wait_for_resource_deletion(
share_id=share['id']) share_id=share['id'])
# Share not migrated yet # Share not migrated yet
else: else:
self.assertNotEqual(dest_pool, share['host']) self.assertNotEqual(dest_pool, share['host'])
@ -235,9 +344,6 @@ class MigrationNFSTest(base.BaseSharesAdminTest):
"Driver-assisted migration tests are disabled.") "Driver-assisted migration tests are disabled.")
def _create_secondary_share_network(self, old_share_network_id): def _create_secondary_share_network(self, old_share_network_id):
if (utils.is_microversion_ge(
CONF.share.max_api_microversion, "2.22") and
CONF.share.multitenancy_enabled):
old_share_network = self.shares_v2_client.get_share_network( old_share_network = self.shares_v2_client.get_share_network(
old_share_network_id) old_share_network_id)
@ -248,5 +354,3 @@ class MigrationNFSTest(base.BaseSharesAdminTest):
neutron_subnet_id=old_share_network['neutron_subnet_id']) neutron_subnet_id=old_share_network['neutron_subnet_id'])
return new_share_network['id'] return new_share_network['id']
else:
return None

View File

@ -13,8 +13,8 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import six
import ddt
from tempest import config from tempest import config
from tempest.lib.common.utils import data_utils from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions as lib_exc from tempest.lib import exceptions as lib_exc
@ -29,6 +29,7 @@ from manila_tempest_tests import utils
CONF = config.CONF CONF = config.CONF
@ddt.ddt
class MigrationTest(base.BaseSharesAdminTest): class MigrationTest(base.BaseSharesAdminTest):
"""Tests Share Migration. """Tests Share Migration.
@ -68,17 +69,11 @@ class MigrationTest(base.BaseSharesAdminTest):
cls.dest_pool = dest_pool['name'] cls.dest_pool = dest_pool['name']
extra_specs = { cls.new_type_invalid = cls.create_share_type(
'storage_protocol': CONF.share.capability_storage_protocol,
'driver_handles_share_servers': CONF.share.multitenancy_enabled,
'snapshot_support': six.text_type(
not CONF.share.capability_snapshot_support),
}
cls.new_type = cls.create_share_type(
name=data_utils.rand_name( name=data_utils.rand_name(
'new_invalid_share_type_for_migration'), 'new_invalid_share_type_for_migration'),
cleanup_in_class=True, cleanup_in_class=True,
extra_specs=extra_specs) extra_specs=utils.get_configured_extra_specs(variation='invalid'))
@test.attr(type=[base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND]) @test.attr(type=[base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND])
@base.skip_if_microversion_lt("2.22") @base.skip_if_microversion_lt("2.22")
@ -165,9 +160,17 @@ class MigrationTest(base.BaseSharesAdminTest):
@test.attr(type=[base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND]) @test.attr(type=[base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND])
@base.skip_if_microversion_lt("2.22") @base.skip_if_microversion_lt("2.22")
def test_migrate_share_change_type_no_valid_host(self): def test_migrate_share_change_type_no_valid_host(self):
if not CONF.share.multitenancy_enabled:
new_share_network_id = self.create_share_network(
neutron_net_id='fake_net_id',
neutron_subnet_id='fake_subnet_id')['id']
else:
new_share_network_id = None
self.shares_v2_client.migrate_share( self.shares_v2_client.migrate_share(
self.share['id'], self.dest_pool, self.share['id'], self.dest_pool,
new_share_type_id=self.new_type['share_type']['id']) new_share_type_id=self.new_type_invalid['share_type']['id'],
new_share_network_id=new_share_network_id)
self.shares_v2_client.wait_for_migration_status( self.shares_v2_client.wait_for_migration_status(
self.share['id'], self.dest_pool, self.share['id'], self.dest_pool,
constants.TASK_STATE_MIGRATION_ERROR) constants.TASK_STATE_MIGRATION_ERROR)
@ -207,5 +210,30 @@ class MigrationTest(base.BaseSharesAdminTest):
def test_migrate_share_invalid_share_type(self): def test_migrate_share_invalid_share_type(self):
self.assertRaises( self.assertRaises(
lib_exc.BadRequest, self.shares_v2_client.migrate_share, lib_exc.BadRequest, self.shares_v2_client.migrate_share,
self.share['id'], self.dest_pool, True, self.share['id'], self.dest_pool,
new_share_type_id='invalid_type_id') new_share_type_id='invalid_type_id')
@test.attr(type=[base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND])
@base.skip_if_microversion_lt("2.22")
def test_migrate_share_opposite_type_share_network_invalid(self):
extra_specs = utils.get_configured_extra_specs(
variation='opposite_driver_modes')
new_type_opposite = self.create_share_type(
name=data_utils.rand_name('share_type_migration_negative'),
extra_specs=extra_specs)
new_share_network_id = None
if CONF.share.multitenancy_enabled:
new_share_network_id = self.create_share_network(
neutron_net_id='fake_net_id',
neutron_subnet_id='fake_subnet_id')['id']
self.assertRaises(
lib_exc.BadRequest, self.shares_v2_client.migrate_share,
self.share['id'], self.dest_pool,
new_share_type_id=new_type_opposite['share_type']['id'],
new_share_network_id=new_share_network_id)

View File

@ -268,7 +268,8 @@ class BaseSharesTest(test.BaseTestCase):
@classmethod @classmethod
@network_synchronized @network_synchronized
def provide_share_network(cls, shares_client, networks_client, def provide_share_network(cls, shares_client, networks_client,
isolated_creds_client=None): isolated_creds_client=None,
ignore_multitenancy_config=False):
"""Used for finding/creating share network for multitenant driver. """Used for finding/creating share network for multitenant driver.
This method creates/gets entity share-network for one tenant. This This method creates/gets entity share-network for one tenant. This
@ -279,6 +280,8 @@ class BaseSharesTest(test.BaseTestCase):
:param isolated_creds_client: DynamicCredentialProvider instance :param isolated_creds_client: DynamicCredentialProvider instance
If provided, then its networking will be used if needed. If provided, then its networking will be used if needed.
If not provided, then common network will be used if needed. If not provided, then common network will be used if needed.
:param ignore_multitenancy_config: provide a share network regardless
of 'multitenancy_enabled' configuration value.
:returns: str -- share network id for shares_client tenant :returns: str -- share network id for shares_client tenant
:returns: None -- if single-tenant driver used :returns: None -- if single-tenant driver used
""" """
@ -287,10 +290,12 @@ class BaseSharesTest(test.BaseTestCase):
search_word = "reusable" search_word = "reusable"
sn_name = "autogenerated_by_tempest_%s" % search_word sn_name = "autogenerated_by_tempest_%s" % search_word
if not CONF.share.multitenancy_enabled: if (not ignore_multitenancy_config and
not CONF.share.multitenancy_enabled):
# Assumed usage of a single-tenant driver # Assumed usage of a single-tenant driver
share_network_id = None share_network_id = None
elif sc.share_network_id: else:
if sc.share_network_id:
# Share-network already exists, use it # Share-network already exists, use it
share_network_id = sc.share_network_id share_network_id = sc.share_network_id
elif not CONF.share.create_networks_when_multitenancy_enabled: elif not CONF.share.create_networks_when_multitenancy_enabled:
@ -308,7 +313,8 @@ class BaseSharesTest(test.BaseTestCase):
# Create new share-network if one was not found # Create new share-network if one was not found
if share_network_id is None: if share_network_id is None:
sn_desc = "This share-network was created by tempest" sn_desc = "This share-network was created by tempest"
sn = sc.create_share_network(name=sn_name, description=sn_desc) sn = sc.create_share_network(name=sn_name,
description=sn_desc)
share_network_id = sn["id"] share_network_id = sn["id"]
else: else:
net_id = subnet_id = share_network_id = None net_id = subnet_id = share_network_id = None
@ -328,13 +334,14 @@ class BaseSharesTest(test.BaseTestCase):
break break
# Create suitable network # Create suitable network
if (net_id is None or subnet_id is None): if net_id is None or subnet_id is None:
ic = dynamic_creds.DynamicCredentialProvider( ic = dynamic_creds.DynamicCredentialProvider(
identity_version=CONF.identity.auth_version, identity_version=CONF.identity.auth_version,
name=service_net_name, name=service_net_name,
admin_role=CONF.identity.admin_role, admin_role=CONF.identity.admin_role,
admin_creds=( admin_creds=(
common_creds.get_configured_admin_credentials())) common_creds.
get_configured_admin_credentials()))
net_data = ic._create_network_resources(sc.tenant_id) net_data = ic._create_network_resources(sc.tenant_id)
network, subnet, router = net_data network, subnet, router = net_data
net_id = network["id"] net_id = network["id"]

View File

@ -115,3 +115,36 @@ def choose_matching_backend(share, pools, share_type):
None) None)
return selected_pool return selected_pool
def get_configured_extra_specs(variation=None):
"""Retrieve essential extra specs according to configuration in tempest.
:param variation: can assume possible values: None to be as configured in
tempest; 'opposite_driver_modes' for as configured in tempest but
inverse driver mode; 'invalid' for inverse as configured in tempest,
ideal for negative tests.
:return: dict containing essential extra specs.
"""
extra_specs = {'storage_protocol': CONF.share.capability_storage_protocol}
if variation == 'invalid':
extra_specs['driver_handles_share_servers'] = (
not CONF.share.multitenancy_enabled)
extra_specs['snapshot_support'] = (
not CONF.share.capability_snapshot_support)
elif variation == 'opposite_driver_modes':
extra_specs['driver_handles_share_servers'] = (
not CONF.share.multitenancy_enabled)
extra_specs['snapshot_support'] = (
CONF.share.capability_snapshot_support)
else:
extra_specs['driver_handles_share_servers'] = (
CONF.share.multitenancy_enabled)
extra_specs['snapshot_support'] = (
CONF.share.capability_snapshot_support)
return extra_specs