Add dummy driver

Added dummy driver for ease of testing and development of REST APIs
and internal manila interfaces.
It can be enabled as backend in the same way as all other share drivers.
But, it does not provide any resources.

Also, update tempest to be able to work with share-networks when
networks are defined via config and not API.

CI hooks are configured to run tempest twice using both available
driver modes. Where DHSS=True mode uses StandAloneNetworkPlugin as
network backend.

Change-Id: I9053dddfc643cb5a6602f15235b91bbaea727dbd
Implements BluePrint dummy-driver
This commit is contained in:
Valeriy Ponomaryov 2016-06-10 18:29:24 +03:00
parent 4d4104c11f
commit 7145891ef8
7 changed files with 532 additions and 8 deletions
contrib/ci
manila/tests/share/drivers
manila_tempest_tests

@ -74,3 +74,62 @@ function manila_wait_for_drivers_init {
# its capabilities on time.
sleep 10
}
function archive_file {
# First argument is expected to be filename
local filename=$1
sudo gzip -9 $filename
sudo chown jenkins:jenkins $filename.gz
sudo chmod a+r $filename.gz
}
function save_tempest_results {
# First argument is expected to be number or tempest run
local src_dirname
local dst_dirname
src_dirname="$BASE/new/tempest"
dst_dirname="$BASE/logs/tempest_$1"
# 1. Create destination directory
sudo mkdir $dst_dirname
sudo chown jenkins:jenkins $dst_dirname
sudo chmod 755 $dst_dirname
# 2. Save tempest configuration file
sudo cp $src_dirname/etc/tempest.conf $dst_dirname/tempest_conf.txt
# 3. Save tempest log file
cp $src_dirname/tempest.log $src_dirname/tempest.txt
echo '' > $src_dirname/tempest.log
archive_file $src_dirname/tempest.txt
sudo mv $src_dirname/tempest.txt.gz $dst_dirname/tempest.txt.gz
# 4. Save tempest testr results
# Check for an interrupted run first
if [ -f $src_dirname/.testrepository/tmp* ]; then
sudo cat $src_dirname/.testrepository/tmp* >> $src_dirname/tempest.subunit
elif [ -f $src_dirname/.testrepository/0 ]; then
pushd $src_dirname
sudo testr last --subunit > $src_dirname/tempest.subunit
popd
fi
if [ -f $src_dirname/tempest.subunit ]; then
sudo /usr/os-testr-env/bin/subunit2html \
$src_dirname/tempest.subunit $src_dirname/testr_results.html
archive_file $src_dirname/tempest.subunit
sudo mv $src_dirname/tempest.subunit.gz $dst_dirname/tempest.subunit.gz
archive_file $src_dirname/testr_results.html
sudo mv $src_dirname/testr_results.html.gz $dst_dirname/testr_results.html.gz
# 5. Cleanup
sudo rm -rf $src_dirname/.testrepository
else
echo "No 'testr' results available for saving. File '$src_dirname/tempest.subunit' is absent."
fi
}

@ -43,7 +43,9 @@ TEST_TYPE=$3
POSTGRES_ENABLED=$4
POSTGRES_ENABLED=$(trueorfalse True POSTGRES_ENABLED)
if [[ "$BACK_END_TYPE" == "multibackend" ]]; then
if [[ "$DRIVER" == "dummy" ]]; then
export BACKENDS_NAMES="ALPHA,BETA"
elif [[ "$BACK_END_TYPE" == "multibackend" ]]; then
iniset $TEMPEST_CONFIG share multi_backend True
iniset $TEMPEST_CONFIG share run_migration_tests $(trueorfalse True RUN_MANILA_MIGRATION_TESTS)
@ -185,6 +187,26 @@ elif [[ "$DRIVER" == "zfsonlinux" ]]; then
iniset $TEMPEST_CONFIG share multitenancy_enabled False
iniset $TEMPEST_CONFIG share multi_backend True
iniset $TEMPEST_CONFIG share backend_replication_type 'readable'
elif [[ "$DRIVER" == "dummy" ]]; then
MANILA_TEMPEST_CONCURRENCY=24
RUN_MANILA_CG_TESTS=True
RUN_MANILA_MANAGE_TESTS=False
iniset $TEMPEST_CONFIG share run_migration_tests False
iniset $TEMPEST_CONFIG share run_quota_tests True
iniset $TEMPEST_CONFIG share run_replication_tests False
iniset $TEMPEST_CONFIG share run_shrink_tests True
iniset $TEMPEST_CONFIG share enable_ip_rules_for_protocols 'nfs'
iniset $TEMPEST_CONFIG share enable_user_rules_for_protocols 'cifs'
iniset $TEMPEST_CONFIG share enable_cert_rules_for_protocols ''
iniset $TEMPEST_CONFIG share enable_ro_access_level_for_protocols 'nfs,cifs'
iniset $TEMPEST_CONFIG share build_timeout 180
iniset $TEMPEST_CONFIG share share_creation_retry_number 0
iniset $TEMPEST_CONFIG share capability_storage_protocol 'NFS_CIFS'
iniset $TEMPEST_CONFIG share enable_protocols 'nfs,cifs'
iniset $TEMPEST_CONFIG share suppress_errors_in_cleanup False
iniset $TEMPEST_CONFIG share multitenancy_enabled True
iniset $TEMPEST_CONFIG share create_networks_when_multitenancy_enabled False
iniset $TEMPEST_CONFIG share multi_backend True
fi
# Enable consistency group tests
@ -213,3 +235,37 @@ manila_wait_for_drivers_init $MANILA_CONF
echo "Running tempest manila test suites"
sudo -H -u jenkins tox -eall-plugin $MANILA_TESTS -- --concurrency=$MANILA_TEMPEST_CONCURRENCY
RETVAL=$?
if [[ "$DRIVER" == "dummy" ]]; then
save_tempest_results 1
echo "First tempest run (DHSS=True) returned '$RETVAL'"
iniset $TEMPEST_CONFIG share backend_names "GAMMA,DELTA"
# NOTE(vponomaryov): enable migration tests when its support added to
# dummy driver.
iniset $TEMPEST_CONFIG share run_migration_tests False
iniset $TEMPEST_CONFIG share run_manage_unmanage_tests True
iniset $TEMPEST_CONFIG share run_manage_unmanage_snapshot_tests True
iniset $TEMPEST_CONFIG share run_replication_tests True
iniset $TEMPEST_CONFIG share multitenancy_enabled False
iniset $TEMPEST_CONFIG share backend_replication_type 'readable'
# Change driver mode for default share type to make tempest use
# DHSS=False backends.
source $BASE/new/devstack/openrc admin demo
manila type-key default set driver_handles_share_servers=False
echo "Running tempest manila test suites for DHSS=False mode"
sudo -H -u jenkins tox -eall-plugin $MANILA_TESTS -- --concurrency=$MANILA_TEMPEST_CONCURRENCY
RETVAL2=$?
save_tempest_results 2
# Exit with last code if first succeeded else exit with first error code
if [[ "$RETVAL" == "0" ]]; then
RETVAL=$RETVAL2
fi
echo "Second tempest run (DHSS=False) returned '$RETVAL2'"
fi
exit $RETVAL

@ -75,6 +75,55 @@ if [[ "$DRIVER" == "generic" ]]; then
elif [[ "$DRIVER" == "windows" ]]; then
MANILA_SERVICE_IMAGE_ENABLED=True
echo "SHARE_DRIVER=manila.share.drivers.windows.windows_smb_driver.WindowsSMBDriver" >> $localrc_path
elif [[ "$DRIVER" == "dummy" ]]; then
driver_path="manila.tests.share.drivers.dummy.DummyDriver"
echo "MANILA_SERVICE_IMAGE_ENABLED=False" >> $localrc_path
echo "SHARE_DRIVER=$driver_path" >> $localrc_path
echo "SUPPRESS_ERRORS_IN_CLEANUP=False" >> $localrc_path
echo "MANILA_REPLICA_STATE_UPDATE_INTERVAL=10" >> $localrc_path
echo "MANILA_ENABLED_BACKENDS=alpha,beta,gamma,delta" >> $localrc_path
echo "MANILA_CONFIGURE_GROUPS=alpha,beta,gamma,delta,membernet,adminnet" >> $localrc_path
echo "MANILA_OPTGROUP_alpha_share_driver=$driver_path" >> $localrc_path
echo "MANILA_OPTGROUP_alpha_driver_handles_share_servers=True" >> $localrc_path
echo "MANILA_OPTGROUP_alpha_share_backend_name=ALPHA" >> $localrc_path
echo "MANILA_OPTGROUP_alpha_network_config_group=membernet" >> $localrc_path
echo "MANILA_OPTGROUP_alpha_admin_network_config_group=adminnet" >> $localrc_path
echo "MANILA_OPTGROUP_beta_share_driver=$driver_path" >> $localrc_path
echo "MANILA_OPTGROUP_beta_driver_handles_share_servers=True" >> $localrc_path
echo "MANILA_OPTGROUP_beta_share_backend_name=BETA" >> $localrc_path
echo "MANILA_OPTGROUP_beta_network_config_group=membernet" >> $localrc_path
echo "MANILA_OPTGROUP_beta_admin_network_config_group=adminnet" >> $localrc_path
echo "MANILA_OPTGROUP_gamma_share_driver=$driver_path" >> $localrc_path
echo "MANILA_OPTGROUP_gamma_driver_handles_share_servers=False" >> $localrc_path
echo "MANILA_OPTGROUP_gamma_share_backend_name=GAMMA" >> $localrc_path
echo "MANILA_OPTGROUP_gamma_replication_domain=DUMMY_DOMAIN" >> $localrc_path
echo "MANILA_OPTGROUP_delta_share_driver=$driver_path" >> $localrc_path
echo "MANILA_OPTGROUP_delta_driver_handles_share_servers=False" >> $localrc_path
echo "MANILA_OPTGROUP_delta_share_backend_name=DELTA" >> $localrc_path
echo "MANILA_OPTGROUP_delta_replication_domain=DUMMY_DOMAIN" >> $localrc_path
echo "MANILA_OPTGROUP_membernet_network_api_class=manila.network.standalone_network_plugin.StandaloneNetworkPlugin" >> $localrc_path
echo "MANILA_OPTGROUP_membernet_standalone_network_plugin_gateway=10.0.0.1" >> $localrc_path
echo "MANILA_OPTGROUP_membernet_standalone_network_plugin_mask=24" >> $localrc_path
echo "MANILA_OPTGROUP_membernet_standalone_network_plugin_network_type=vlan" >> $localrc_path
echo "MANILA_OPTGROUP_membernet_standalone_network_plugin_segmentation_id=1010" >> $localrc_path
echo "MANILA_OPTGROUP_membernet_standalone_network_plugin_allowed_ip_ranges=10.0.0.10-10.0.0.209" >> $localrc_path
echo "MANILA_OPTGROUP_membernet_standalone_network_plugin_ip_version=4" >> $localrc_path
echo "MANILA_OPTGROUP_adminnet_network_api_class=manila.network.standalone_network_plugin.StandaloneNetworkPlugin" >> $localrc_path
echo "MANILA_OPTGROUP_adminnet_standalone_network_plugin_gateway=11.0.0.1" >> $localrc_path
echo "MANILA_OPTGROUP_adminnet_standalone_network_plugin_mask=24" >> $localrc_path
echo "MANILA_OPTGROUP_adminnet_standalone_network_plugin_network_type=vlan" >> $localrc_path
echo "MANILA_OPTGROUP_adminnet_standalone_network_plugin_segmentation_id=1011" >> $localrc_path
echo "MANILA_OPTGROUP_adminnet_standalone_network_plugin_allowed_ip_ranges=11.0.0.10-11.0.0.19,11.0.0.30-11.0.0.39,11.0.0.50-11.0.0.199" >> $localrc_path
echo "MANILA_OPTGROUP_adminnet_standalone_network_plugin_ip_version=4" >> $localrc_path
export MANILA_TEMPEST_CONCURRENCY=24
elif [[ "$DRIVER" == "lvm" ]]; then
echo "SHARE_DRIVER=manila.share.drivers.lvm.LVMShareDriver" >> $localrc_path
echo "SHARE_BACKING_FILE_SIZE=32000M" >> $localrc_path
@ -98,7 +147,7 @@ echo 'ENABLE_ISOLATED_METADATA=True' >> $localrc_path
echo "TEMPEST_USE_TEST_ACCOUNTS=True" >> $localrc_path
echo "TEMPEST_ALLOW_TENANT_ISOLATION=False" >> $localrc_path
echo "TEMPEST_CONCURRENCY=8" >> $localrc_path
echo "TEMPEST_CONCURRENCY=${MANILA_TEMPEST_CONCURRENCY:-8}" >> $localrc_path
# Go to Tempest dir and checkout stable commit to avoid possible
# incompatibilities for plugin stored in Manila repo.

@ -0,0 +1,330 @@
# Copyright 2016 Mirantis 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.
"""
Dummy share driver for testing Manila APIs and other interfaces.
This driver simulates support of:
- Both available driver modes: DHSS=True/False
- NFS and CIFS protocols
- IP access for NFS shares and USER access for CIFS shares
- CIFS shares in DHSS=True driver mode
- Creation and deletion of share snapshots
- Share replication (readable)
- Consistency groups
- Resize of a share (extend/shrink)
"""
from oslo_log import log
from manila.common import constants
from manila import exception
from manila.i18n import _
from manila.share import driver
from manila.share import utils as share_utils
LOG = log.getLogger(__name__)
class DummyDriver(driver.ShareDriver):
"""Dummy share driver that implements all share driver interfaces."""
def __init__(self, *args, **kwargs):
"""Do initialization."""
super(self.__class__, self).__init__([False, True], *args, **kwargs)
self.private_storage = kwargs.get('private_storage')
self.backend_name = self.configuration.safe_get(
"share_backend_name") or "DummyDriver"
def _get_share_name(self, share):
return "share_%(s_id)s_%(si_id)s" % {
"s_id": share["share_id"].replace("-", "_"),
"si_id": share["id"].replace("-", "_")}
def _get_snapshot_name(self, snapshot):
return "snapshot_%(s_id)s_%(si_id)s" % {
"s_id": snapshot["snapshot_id"].replace("-", "_"),
"si_id": snapshot["id"].replace("-", "_")}
def _generate_export_locations(self, mountpoint, share_server=None):
details = share_server["backend_details"] if share_server else {
"primary_public_ip": "10.0.0.10",
"secondary_public_ip": "10.0.0.20",
"service_ip": "11.0.0.11",
}
return [
{
"path": "%(ip)s:%(mp)s" % {"ip": ip, "mp": mountpoint},
"metadata": {
"preferred": preferred,
},
"is_admin_only": is_admin_only,
} for ip, is_admin_only, preferred in (
(details["primary_public_ip"], False, True),
(details["secondary_public_ip"], False, False),
(details["service_ip"], True, False))
]
def _create_share(self, share, share_server=None):
share_proto = share["share_proto"]
if share_proto not in ("NFS", "CIFS"):
msg = _("Unsupported share protocol provided - %s.") % share_proto
raise exception.InvalidShareAccess(reason=msg)
share_name = self._get_share_name(share)
mountpoint = "/path/to/fake/share/%s" % share_name
self.private_storage.update(
share["id"], {
"fake_provider_share_name": share_name,
"fake_provider_location": mountpoint,
}
)
return self._generate_export_locations(
mountpoint, share_server=share_server)
def create_share(self, context, share, share_server=None):
"""Is called to create share."""
return self._create_share(share, share_server=share_server)
def create_share_from_snapshot(self, context, share, snapshot,
share_server=None):
"""Is called to create share from snapshot."""
return self._create_share(share, share_server=share_server)
def _create_snapshot(self, snapshot):
snapshot_name = self._get_snapshot_name(snapshot)
self.private_storage.update(
snapshot["id"], {
"fake_provider_snapshot_name": snapshot_name,
}
)
return {"provider_location": snapshot_name}
def create_snapshot(self, context, snapshot, share_server=None):
"""Is called to create snapshot."""
return self._create_snapshot(snapshot)
def delete_share(self, context, share, share_server=None):
"""Is called to remove share."""
self.private_storage.delete(share["id"])
def delete_snapshot(self, context, snapshot, share_server=None):
"""Is called to remove snapshot."""
self.private_storage.delete(snapshot["id"])
def get_pool(self, share):
"""Return pool name where the share resides on."""
pool_name = share_utils.extract_host(share["host"], level="pool")
return pool_name
def ensure_share(self, context, share, share_server=None):
"""Invoked to ensure that share is exported."""
def update_access(self, context, share, access_rules, add_rules,
delete_rules, share_server=None):
"""Update access rules for given share."""
for rule in add_rules + access_rules:
share_proto = share["share_proto"].lower()
access_type = rule["access_type"].lower()
if not (
(share_proto == "nfs" and access_type == "ip") or
(share_proto == "cifs" and access_type == "user")):
msg = _("Unsupported '%(access_type)s' access type provided "
"for '%(share_proto)s' share protocol.") % {
"access_type": access_type, "share_proto": share_proto}
raise exception.InvalidShareAccess(reason=msg)
def do_setup(self, context):
"""Any initialization the share driver does while starting."""
def manage_existing(self, share, driver_options):
"""Brings an existing share under Manila management."""
return {"size": 1, "export_locations": self._create_share(share)}
def unmanage(self, share):
"""Removes the specified share from Manila management."""
def manage_existing_snapshot(self, snapshot, driver_options):
"""Brings an existing snapshot under Manila management."""
self._create_snapshot(snapshot)
return {"size": 1, "provider_location": snapshot["provider_location"]}
def unmanage_snapshot(self, snapshot):
"""Removes the specified snapshot from Manila management."""
def extend_share(self, share, new_size, share_server=None):
"""Extends size of existing share."""
def shrink_share(self, share, new_size, share_server=None):
"""Shrinks size of existing share."""
def get_network_allocations_number(self):
"""Returns number of network allocations for creating VIFs."""
return 2
def get_admin_network_allocations_number(self):
return 1
def _setup_server(self, network_info, metadata=None):
"""Sets up and configures share server with given network parameters.
Redefine it within share driver when it is going to handle share
servers.
"""
server_details = {
"primary_public_ip": network_info[
"network_allocations"][0]["ip_address"],
"secondary_public_ip": network_info[
"network_allocations"][1]["ip_address"],
"service_ip": network_info[
"admin_network_allocations"][0]["ip_address"],
"username": "fake_username",
}
return server_details
def _teardown_server(self, server_details, security_services=None):
"""Tears down share server."""
def _get_pools_info(self):
pools = [{
"pool_name": "fake_pool_for_%s" % self.backend_name,
"total_capacity_gb": 1230.0,
"free_capacity_gb": 1210.0,
"reserved_percentage": self.configuration.reserved_share_percentage
}]
if self.configuration.replication_domain:
pools[0]["replication_type"] = "readable"
return pools
def _update_share_stats(self, data=None):
"""Retrieve stats info from share group."""
data = {
"share_backend_name": self.backend_name,
"storage_protocol": "NFS_CIFS",
"reserved_percentage":
self.configuration.reserved_share_percentage,
"consistency_group_support": "pool",
"snapshot_support": True,
"driver_name": "Dummy",
"pools": self._get_pools_info(),
}
if self.configuration.replication_domain:
data["replication_type"] = "readable"
super(self.__class__, self)._update_share_stats(data)
def get_share_server_pools(self, share_server):
"""Return list of pools related to a particular share server."""
return []
def create_consistency_group(self, context, cg_dict, share_server=None):
"""Create a consistency group."""
LOG.debug(
"Successfully created dummy Consistency Group with ID: %s.",
cg_dict["id"])
def delete_consistency_group(self, context, cg_dict, share_server=None):
"""Delete a consistency group."""
LOG.debug(
"Successfully deleted dummy consistency group with ID %s.",
cg_dict["id"])
def create_cgsnapshot(self, context, snap_dict, share_server=None):
"""Create a consistency group snapshot."""
LOG.debug("Successfully created CG snapshot %s." % snap_dict["id"])
return None, None
def delete_cgsnapshot(self, context, snap_dict, share_server=None):
"""Delete a consistency group snapshot."""
LOG.debug("Successfully deleted CG snapshot %s." % snap_dict["id"])
return None, None
def create_consistency_group_from_cgsnapshot(
self, context, cg_dict, cgsnapshot_dict, share_server=None):
"""Create a consistency group from a cgsnapshot."""
LOG.debug(
("Successfully created dummy Consistency Group (%(cg_id)s) "
"from CG snapshot (%(cg_snap_id)s)."),
{"cg_id": cg_dict["id"], "cg_snap_id": cgsnapshot_dict["id"]})
return None, []
def create_replica(self, context, replica_list, new_replica,
access_rules, replica_snapshots, share_server=None):
"""Replicate the active replica to a new replica on this backend."""
replica_name = self._get_share_name(new_replica)
mountpoint = "/path/to/fake/share/%s" % replica_name
self.private_storage.update(
new_replica["id"], {
"fake_provider_replica_name": replica_name,
"fake_provider_location": mountpoint,
}
)
return {
"export_locations": self._generate_export_locations(
mountpoint, share_server=share_server),
"replica_state": constants.REPLICA_STATE_IN_SYNC,
"access_rules_status": constants.STATUS_ACTIVE,
}
def delete_replica(self, context, replica_list, replica_snapshots,
replica, share_server=None):
"""Delete a replica."""
self.private_storage.delete(replica["id"])
def promote_replica(self, context, replica_list, replica, access_rules,
share_server=None):
"""Promote a replica to 'active' replica state."""
return_replica_list = []
for r in replica_list:
if r["id"] == replica["id"]:
replica_state = constants.REPLICA_STATE_ACTIVE
else:
replica_state = constants.REPLICA_STATE_IN_SYNC
return_replica_list.append(
{"id": r["id"], "replica_state": replica_state})
return return_replica_list
def update_replica_state(self, context, replica_list, replica,
access_rules, replica_snapshots,
share_server=None):
"""Update the replica_state of a replica."""
return constants.REPLICA_STATE_IN_SYNC
def create_replicated_snapshot(self, context, replica_list,
replica_snapshots, share_server=None):
"""Create a snapshot on active instance and update across the replicas.
"""
return_replica_snapshots = []
for r in replica_snapshots:
return_replica_snapshots.append(
{"id": r["id"], "status": constants.STATUS_AVAILABLE})
return return_replica_snapshots
def delete_replicated_snapshot(self, context, replica_list,
replica_snapshots, share_server=None):
"""Delete a snapshot by deleting its instances across the replicas."""
return_replica_snapshots = []
for r in replica_snapshots:
return_replica_snapshots.append(
{"id": r["id"], "status": constants.STATUS_DELETED})
return return_replica_snapshots
def update_replicated_snapshot(self, context, replica_list,
share_replica, replica_snapshots,
replica_snapshot, share_server=None):
"""Update the status of a snapshot instance that lives on a replica."""
return {
"id": replica_snapshot["id"], "status": constants.STATUS_AVAILABLE}

@ -56,6 +56,15 @@ ShareGroup = [
help="This option used to determine backend driver type, "
"multitenant driver uses share-networks, but "
"single-tenant doesn't."),
cfg.BoolOpt("create_networks_when_multitenancy_enabled",
default=True,
help="This option is used only when other "
"'multitenancy_enabled' option is set to 'True'. "
"If this one is set to True, then tempest will create "
"neutron networks for each new manila share-network "
"it creates. Else it will use manila share-networks with "
"empty values (case of StandAloneNetworkPlugin and "
"NeutronSingleNetworkPlugin)."),
cfg.ListOpt("enable_protocols",
default=["nfs", "cifs"],
help="First value of list is protocol by default, "

@ -203,7 +203,8 @@ class BaseSharesTest(test.BaseTestCase):
# Provide share network
if CONF.share.multitenancy_enabled:
if not CONF.service_available.neutron:
if (not CONF.service_available.neutron and
CONF.share.create_networks_when_multitenancy_enabled):
raise cls.skipException("Neutron support is required")
nc = os.networks_client
share_network_id = cls.provide_share_network(client, nc, ic)
@ -235,7 +236,8 @@ class BaseSharesTest(test.BaseTestCase):
os.auth_provider)
cls.shares_v2_client = os.shares_v2_client
if CONF.share.multitenancy_enabled:
if not CONF.service_available.neutron:
if (not CONF.service_available.neutron and
CONF.share.create_networks_when_multitenancy_enabled):
raise cls.skipException("Neutron support is required")
share_network_id = cls.provide_share_network(
cls.shares_v2_client, os.networks_client)
@ -282,6 +284,8 @@ class BaseSharesTest(test.BaseTestCase):
"""
sc = shares_client
search_word = "reusable"
sn_name = "autogenerated_by_tempest_%s" % search_word
if not CONF.share.multitenancy_enabled:
# Assumed usage of a single-tenant driver
@ -289,13 +293,28 @@ class BaseSharesTest(test.BaseTestCase):
elif sc.share_network_id:
# Share-network already exists, use it
share_network_id = sc.share_network_id
elif not CONF.share.create_networks_when_multitenancy_enabled:
share_network_id = None
# Try get suitable share-network
share_networks = sc.list_share_networks_with_detail()
for sn in share_networks:
if (sn["neutron_net_id"] is None and
sn["neutron_subnet_id"] is None and
sn["name"] and search_word in sn["name"]):
share_network_id = sn["id"]
break
# Create new share-network if one was not found
if share_network_id is None:
sn_desc = "This share-network was created by tempest"
sn = sc.create_share_network(name=sn_name, description=sn_desc)
share_network_id = sn["id"]
else:
net_id = subnet_id = share_network_id = None
if not isolated_creds_client:
# Search for networks, created in previous runs
search_word = "reusable"
sn_name = "autogenerated_by_tempest_%s" % search_word
service_net_name = "share-service"
networks = networks_client.list_networks()
if "networks" in networks.keys():

@ -146,8 +146,10 @@ class SharesNFSTest(base.BaseSharesTest):
self.protocol, snapshot_id=snap["id"], cleanup_in_class=False)
# The 'status' of the share returned by the create API must be
# the default value - 'creating'.
self.assertEqual('creating', s2['status'])
# set and have value either 'creating' or
# 'available' (if share creation is really fast as in
# case of Dummy driver).
self.assertIn(s2['status'], ('creating', 'available'))
# verify share, created from snapshot
get = self.shares_client.get_share(s2["id"])