Updated generic_driver and service_instance with activation

Generic driver changes to activation/deactivation of
share_networks requires changes to service instance.
Also it requires changes to tempest plugin, that should
use activation of share networks before creation of shares.

Partially-implements bp share-network-activation-api
Closes-Bug: #1294577
Closes-Bug: #1273758

Change-Id: Ide3b9a51038b532bee464e256f6e830fb93001f7
This commit is contained in:
vponomaryov 2014-03-21 07:54:28 +02:00
parent 85f02a9556
commit 69c063997c
14 changed files with 330 additions and 132 deletions

View File

@ -278,6 +278,14 @@ class BaseSharesTest(test.BaseTestCase):
client = cls.shares_client
if description is None:
description = "Tempest's share"
if (share_network_id or client.share_network_id):
share_network_id = share_network_id or client.share_network_id
__, body = client.get_share_network(share_network_id)
if body["status"].lower() == "inactive":
resp, __ = client.activate_share_network(share_network_id)
assert (int(resp["status"]) in test.HTTP_SUCCESS)
client.wait_for_share_network_status(share_network_id,
"active")
r, s = client.create_share(share_protocol=share_protocol, size=size,
name=name, snapshot_id=snapshot_id,
description=description,
@ -391,6 +399,11 @@ class BaseSharesTest(test.BaseTestCase):
client.delete_snapshot(res_id)
client.wait_for_resource_deletion(snapshot_id=res_id)
elif res["type"] is "share_network":
__, body = client.get_share_network(res_id)
if body["status"].lower() == "active":
client.deactivate_share_network(res_id)
client.wait_for_share_network_status(res_id,
"inactive")
client.delete_share_network(res_id)
client.wait_for_resource_deletion(sn_id=res_id)
elif res["type"] is "security_service":

View File

@ -42,3 +42,11 @@ class NoAvailableNetwork(base.TempestException):
class InvalidResource(base.TempestException):
message = "Provided invalid resource: %(message)s"
class ShareNetworkActivationFailed(base.TempestException):
message = "Share-network with id %(sn_id) failed to activate"
class ShareNetworkDeactivationFailed(base.TempestException):
message = "Share-network with id %(sn_id) failed to deactivate"

View File

@ -450,6 +450,47 @@ class SharesClient(rest_client.RestClient):
def delete_share_network(self, sn_id):
return self.delete("share-networks/%s" % sn_id)
def action_with_share_network(self, sn_id, action="activate"):
"""Activates or deactivates share networks.
param: sn_id: id of share-network
param: action: available values are "activate" and "deactivate"
returns: tuple with resp and body of response
"""
body = json.dumps({action: {}})
uri = "share-networks/%s/action" % sn_id
resp, body = self.post(uri, body=body)
return resp, self._parse_resp(body)
def activate_share_network(self, sn_id):
return self.action_with_share_network(sn_id, "activate")
def deactivate_share_network(self, sn_id):
return self.action_with_share_network(sn_id, "deactivate")
def wait_for_share_network_status(self, sn_id, status="active"):
"""Waits for a Share network to reach a given status."""
__, body = self.get_share_network(sn_id)
sn_name = body['name']
sn_status = body['status'].lower()
start = int(time.time())
while sn_status != status:
time.sleep(self.build_interval)
__, body = self.get_share_network(sn_id)
sn_status = body['status'].lower()
if 'error' in sn_status:
# Error can be set only on attempt to activate
raise share_exceptions.\
ShareNetworkActivationFailed(sn_id=sn_id)
if int(time.time()) - start >= self.build_timeout:
message = ('Share-network %s failed to reach %s status within '
'the required time (%s s).' %
(sn_name, status, self.build_timeout))
raise exceptions.TimeoutException(message)
###############
def _map_security_service_and_share_network(self, sn_id, ss_id,

View File

@ -208,8 +208,9 @@ class ShareController(wsgi.Controller):
except exception.ShareNetworkNotFound as e:
msg = "%s" % e
raise exc.HTTPNotFound(explanation=msg)
if share_network['status'] == constants.STATUS_ERROR:
msg = _("Share network is in 'ERROR' state.")
if share_network['status'] != constants.STATUS_ACTIVE:
msg = _("Share network '%s' is not in 'ACTIVE' state.")
msg = msg % share_network["id"]
raise exc.HTTPBadRequest(explanation=msg)
else:
kwargs['share_network_id'] = share_network_id

View File

@ -20,5 +20,7 @@ STATUS_DELETED = 'DELETED'
STATUS_ERROR = 'ERROR'
STATUS_ACTIVE = 'ACTIVE'
STATUS_INACTIVE = 'INACTIVE'
STATUS_ACTIVATING = 'ACTIVATING'
STATUS_DEACTIVATING = 'DEACTIVATING'
SECURITY_SERVICES_ALLOWED_TYPES = ['active_directory', 'ldap', 'kerberos']

View File

@ -13,12 +13,20 @@
# License for the specific language governing permissions and limitations
# under the License.
import time
from oslo.config import cfg
from manila.common import constants
from manila.db import base as db_base
from manila import exception
from manila import network as manila_network
from manila.network.neutron import api as neutron_api
from manila.network.neutron import constants as neutron_constants
from manila.openstack.common import log as logging
CONF = cfg.CONF
LOG = logging.getLogger(__name__)
class NeutronNetworkPlugin(manila_network.NetworkBaseAPI, db_base.Base):
@ -53,10 +61,7 @@ class NeutronNetworkPlugin(manila_network.NetworkBaseAPI, db_base.Base):
for _ in range(0, allocation_count):
self._create_port(context, share_network, device_owner)
return self.db.share_network_update(
context,
share_network['id'],
{'status': constants.STATUS_ACTIVE})
return self.db.share_network_get(context, share_network['id'])
def deallocate_network(self, context, share_network):
"""Deallocate neutron network resources for the given network info:
@ -72,30 +77,20 @@ class NeutronNetworkPlugin(manila_network.NetworkBaseAPI, db_base.Base):
for port in ports:
self._delete_port(context, port)
self.db.share_network_update(context,
share_network['id'],
{'status': constants.STATUS_INACTIVE})
def _create_port(self, context, share_network, device_owner):
try:
port = self.neutron_api.create_port(
share_network['project_id'],
network_id=share_network['neutron_net_id'],
subnet_id=share_network['neutron_subnet_id'],
device_owner='manila:' + device_owner)
except exception.NetworkException:
self.db.share_network_update(context,
share_network['id'],
{'status': constants.STATUS_ERROR})
raise
else:
port_dict = {'id': port['id'],
'share_network_id': share_network['id'],
'ip_address': port['fixed_ips'][0]['ip_address'],
'mac_address': port['mac_address'],
'status': constants.STATUS_ACTIVE}
self.db.network_allocation_create(context, port_dict)
return port_dict
port = self.neutron_api.create_port(share_network['project_id'],
network_id=share_network['neutron_net_id'],
subnet_id=share_network['neutron_subnet_id'],
device_owner='manila:' + device_owner)
port_dict = {
'id': port['id'],
'share_network_id': share_network['id'],
'ip_address': port['fixed_ips'][0]['ip_address'],
'mac_address': port['mac_address'],
'status': constants.STATUS_ACTIVE,
}
self.db.network_allocation_create(context, port_dict)
return port_dict
def _delete_port(self, context, port):
try:
@ -104,9 +99,6 @@ class NeutronNetworkPlugin(manila_network.NetworkBaseAPI, db_base.Base):
self.db.network_allocation_update(context,
port['id'],
{'status': constants.STATUS_ERROR})
self.db.share_network_update(context,
port['share_network_id'],
{'status': constants.STATUS_ERROR})
raise
else:
self.db.network_allocation_delete(context, port['id'])

View File

@ -23,6 +23,7 @@ import time
from oslo.config import cfg
from manila.common import constants
from manila import compute
from manila import context
from manila import exception
@ -99,7 +100,9 @@ class GenericShareDriver(driver.ExecuteMixin, driver.ShareDriver):
self.service_instance_manager = service_instance.\
ServiceInstanceManager(self.db, self._helpers)
self.get_service_instance = self.service_instance_manager.\
get_service_instance
get_service_instance
self.delete_service_instance = self.service_instance_manager.\
delete_service_instance
self.share_networks_locks = self.service_instance_manager.\
share_networks_locks
self.share_networks_servers = self.service_instance_manager.\
@ -350,11 +353,12 @@ class GenericShareDriver(driver.ExecuteMixin, driver.ShareDriver):
if not share['share_network_id']:
return
server = self.get_service_instance(self.admin_context,
share_network_id=share['share_network_id'],
create=False)
share_network_id=share['share_network_id'],
return_inactive=True)
if server:
self._get_helper(share).remove_export(server, share['name'])
self._unmount_device(context, share, server)
if server['status'] == 'ACTIVE':
self._get_helper(share).remove_export(server, share['name'])
self._unmount_device(context, share, server)
self._detach_volume(context, share, server)
self._deallocate_container(context, share)
@ -405,7 +409,7 @@ class GenericShareDriver(driver.ExecuteMixin, driver.ShareDriver):
def ensure_share(self, context, share):
"""Ensure that storage are mounted and exported."""
server = self.get_service_instance(context,
share_network_id=share['share_network_id'])
share_network_id=share['share_network_id'], create=True)
volume = self._get_volume(context, share['id'])
volume = self._attach_volume(context, share, server, volume)
self._mount_device(context, share, server, volume)
@ -428,8 +432,7 @@ class GenericShareDriver(driver.ExecuteMixin, driver.ShareDriver):
if not share['share_network_id']:
return
server = self.get_service_instance(self.admin_context,
share_network_id=share['share_network_id'],
create=False)
share_network_id=share['share_network_id'])
if server:
self._get_helper(share).deny_access(server, share['name'],
access['access_type'],
@ -444,10 +447,28 @@ class GenericShareDriver(driver.ExecuteMixin, driver.ShareDriver):
raise exception.InvalidShare(reason='Wrong share type')
def get_network_allocations_number(self):
"""Get number of network interfaces to be created."""
# NOTE(vponomaryov): Generic driver does not need allocations, because
# Nova will handle it. It is valid for all multitenant drivers, that
# use service instance provided by Nova.
return 0
def setup_network(self, network_info):
pass
def setup_network(self, share_network, metadata=None):
sn_id = share_network["id"]
msg = _("Creating share infrastructure for share network '%s'.")
LOG.debug(msg % sn_id)
self.get_service_instance(context=self.admin_context,
share_network_id=sn_id,
create=True)
def teardown_network(self, share_network):
sn_id = share_network["id"]
msg = _("Removing share infrastructure for share network '%s'.")
LOG.debug(msg % sn_id)
try:
self.delete_service_instance(self.admin_context, sn_id)
except Exception as e:
LOG.debug(e)
class NASHelperBase(object):

View File

@ -115,7 +115,14 @@ def _ssh_exec(server, command):
class ServiceInstanceManager(object):
"""Manages nova instances for various share drivers."""
"""Manages nova instances for various share drivers.
This class provides two external methods:
1. get_service_instance: creates or discovers service instance and network
infrastructure for provided share network.
2. delete_service_instance: removes service instance and network
infrastructure.
"""
def __init__(self, db, _helpers, *args, **kwargs):
"""Do initialization."""
@ -199,8 +206,6 @@ class ServiceInstanceManager(object):
def _delete_server(self, context, server):
"""Deletes the server."""
if not server:
return
self.compute_api.server_delete(context, server['id'])
t = time.time()
while time.time() - t < CONF.max_time_to_build_instance:
@ -216,43 +221,62 @@ class ServiceInstanceManager(object):
CONF.max_time_to_build_instance)
@synchronized
def get_service_instance(self, context, share_network_id, create=True):
"""Finds or creates and sets up service vm."""
def get_service_instance(self, context, share_network_id, create=False,
return_inactive=False):
"""Finds or creates and sets up service vm.
:param context: defines context, that should be used
:param share_network_id: it provides network data for service VM
:param create: allow create service VM or not
:param return_inactive: allows to return not active VM, without
raise of exception
:returns: dict with data for service VM
:raises: exception.ServiceInstanceException
"""
server = self.share_networks_servers.get(share_network_id, {})
old_server_ip = server.get('ip', None)
if self._ensure_server(context, server, update=True):
return server
else:
self._delete_server(context, server)
server = {}
service_instance_name = self._get_service_instance_name(
share_network_id)
search_opts = {'name': service_instance_name}
servers = self.compute_api.server_list(context, search_opts, True)
if len(servers) == 1:
server = servers[0]
server = self._discover_service_instance(context, share_network_id)
old_server_ip = None
is_active = False
if server:
server['ip'] = self._get_server_ip(server)
old_server_ip = server['ip']
if not self._ensure_server(context, server):
is_active = self._ensure_server(context, server)
if not is_active and create:
if server:
self._delete_server(context, server)
server.clear()
elif len(servers) > 1:
raise exception.ServiceInstanceException(
_('Error. Ambiguous service instances.'))
if not server and create:
server = self._create_service_instance(context,
service_instance_name,
share_network_id,
old_server_ip)
if server:
is_active = True
self.share_networks_servers[share_network_id] = server
if is_active:
server['share_network_id'] = share_network_id
server['ip'] = self._get_server_ip(server)
server['ssh_pool'] = self._get_ssh_pool(server)
server['ssh'] = server['ssh_pool'].create()
for helper in self._helpers.values():
helper.init_helper(server)
elif not return_inactive:
msg = _('Service instance for share network %s is not active or '
'does not exist') % share_network_id
raise exception.ServiceInstanceException(msg)
self.share_networks_servers[share_network_id] = server
return server
def _discover_service_instance(self, context, share_network_id):
server = {}
instance_name = self._get_service_instance_name(share_network_id)
search_opts = {'name': instance_name}
servers = self.compute_api.server_list(context, search_opts, True)
if len(servers) == 1:
return servers[0]
elif len(servers) > 1:
raise exception.ServiceInstanceException(
_('Error. Ambiguous service instances.'))
return server
def _get_ssh_pool(self, server):
@ -308,10 +332,11 @@ class ServiceInstanceManager(object):
raise exception.ServiceInstanceException(
_('Ambiguous image name.'))
def _create_service_instance(self, context, instance_name,
share_network_id, old_server_ip):
def _create_service_instance(self, context, share_network_id,
old_server_ip):
"""Creates service vm and sets up networking for it."""
service_image_id = self._get_service_image(context)
instance_name = self._get_service_instance_name(share_network_id)
with lock:
key_name = self._get_key(context)
@ -546,21 +571,29 @@ class ServiceInstanceManager(object):
else:
raise exception.ServiceInstanceException(_('No available cidrs.'))
def delete_share_infrastructure(self, context, share_network_id):
def delete_service_instance(self, context, share_network_id):
"""Removes share infrastructure.
Deletes service vm and subnet, associated to share network.
"""
server = self.get_service_instance(context,
share_network_id=share_network_id,
create=False)
server = self._discover_service_instance(context, share_network_id)
if server:
self._delete_server(context, server)
subnet_id = self._get_service_subnet(share_network_id)
if subnet_id:
subnet = self._get_service_subnet(share_network_id)
if subnet:
subnet_id = subnet['id']
router = self._get_private_router(share_network_id)
port = self._get_service_port()
self.neutron_api.router_remove_interface(router['id'], subnet_id)
try:
self.neutron_api.router_remove_interface(router['id'],
subnet_id)
except exception.NetworkException as e:
if e.kwargs['code'] != 404:
raise
LOG.debug(_('Subnet %(subnet_id)s is not attached to the '
'router %(router_id)s.') %
{'subnet_id': subnet_id,
'router_id': router['id']})
self._remove_fixed_ip_from_service_port(port, subnet_id)
self.neutron_api.delete_subnet(subnet_id)
self._setup_connectivity_with_service_instances()

View File

@ -110,10 +110,6 @@ class ShareManager(manager.SchedulerDependentManager):
if share_network_id:
share_network = self.db.share_network_get(context,
share_network_id)
if share_network['status'] == constants.STATUS_INACTIVE:
share_network = self._activate_share_network(
context,
share_network)
else:
share_network = {}
@ -272,7 +268,7 @@ class ShareManager(manager.SchedulerDependentManager):
def deactivate_network(self, context, share_network_id):
share_network = self.db.share_network_get(context, share_network_id)
self.driver.teardown_network(share_network)
self._deactivate_network(context, share_network)
self.network_api.deallocate_network(context, share_network)
def _activate_share_network(self, context, share_network, metadata=None):
@ -282,11 +278,29 @@ class ShareManager(manager.SchedulerDependentManager):
context,
share_network,
count=allocation_number)
try:
self.driver.setup_network(share_network, metadata=metadata)
except exception.ManilaException:
with excutils.save_and_reraise_exception():
self.network_api.deallocate_network(context,
share_network)
else:
return share_network
try:
self.db.share_network_update(context, share_network['id'],
{'status': constants.STATUS_ACTIVATING})
self.driver.setup_network(share_network, metadata=metadata)
self.db.share_network_update(context, share_network['id'],
{'status': constants.STATUS_ACTIVE})
except exception.ManilaException:
with excutils.save_and_reraise_exception():
self.db.share_network_update(context, share_network['id'],
{'status': constants.STATUS_ERROR})
self.network_api.deallocate_network(context, share_network)
else:
return share_network
def _deactivate_network(self, context, share_network):
self.db.share_network_update(context, share_network['id'],
{'status': constants.STATUS_DEACTIVATING})
try:
self.driver.teardown_network(share_network)
except Exception as e:
with excutils.save_and_reraise_exception():
self.db.share_network_update(context, share_network['id'],
{'status': constants.STATUS_ERROR})
else:
self.db.share_network_update(context, share_network['id'],
{'status': constants.STATUS_INACTIVE})

View File

@ -0,0 +1,47 @@
# Copyright 2014 Mirantis Inc.
#
# 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.
import mock
from manila.openstack.common import log as logging
from manila.tests import fake_compute
LOG = logging.getLogger(__name__)
class FakeServiceInstanceManager(object):
def __init__(self):
self.db = mock.Mock()
self._helpers = {
'CIFS': mock.Mock(),
'NFS': mock.Mock(),
}
self.share_networks_locks = {}
self.share_networks_servers = {}
self.fake_server = fake_compute.FakeServer()
self.service_instance_name_template = 'manila_fake_service_instance-%s'
def get_service_instance(self, context, share_network_id, create=True):
return self.fake_server
def _create_service_instance(self, context, instance_name,
share_network_id, old_server_ip):
return self.fake_server
def _delete_server(self, context, server):
pass
def _get_service_instance_name(self, share_network_id):
return self.service_instance_name_template % share_network_id

View File

@ -73,7 +73,7 @@ class NeutronNetworkPluginTest(unittest.TestCase):
@mock.patch.object(db_api, 'network_allocation_create',
mock.Mock(return_values=fake_network_allocation))
@mock.patch.object(db_api, 'share_network_update',
@mock.patch.object(db_api, 'share_network_get',
mock.Mock(return_value=fake_share_network))
def test_allocate_network_one_allocation(self):
has_provider_nw_ext = mock.patch.object(self.plugin,
@ -105,10 +105,6 @@ class NeutronNetworkPluginTest(unittest.TestCase):
db_api.network_allocation_create.assert_called_once_with(
self.fake_context,
fake_network_allocation)
db_api.share_network_update.assert_called_once_with(
self.fake_context,
fake_share_network['id'],
{'status': constants.STATUS_ACTIVE})
has_provider_nw_ext.stop()
save_nw_data.stop()
@ -116,7 +112,7 @@ class NeutronNetworkPluginTest(unittest.TestCase):
@mock.patch.object(db_api, 'network_allocation_create',
mock.Mock(return_values=fake_network_allocation))
@mock.patch.object(db_api, 'share_network_update',
@mock.patch.object(db_api, 'share_network_get',
mock.Mock(return_value=fake_share_network))
def test_allocate_network_two_allocation(self):
has_provider_nw_ext = mock.patch.object(self.plugin,
@ -152,10 +148,6 @@ class NeutronNetworkPluginTest(unittest.TestCase):
self.plugin.neutron_api.create_port.assert_has_calls(
neutron_api_calls)
db_api.network_allocation_create.assert_has_calls(db_api_calls)
db_api.share_network_update.assert_called_once_with(
self.fake_context,
fake_share_network['id'],
{'status': constants.STATUS_ACTIVE})
has_provider_nw_ext.stop()
save_nw_data.stop()
@ -179,10 +171,6 @@ class NeutronNetworkPluginTest(unittest.TestCase):
self.plugin.allocate_network,
self.fake_context,
fake_share_network)
db_api.share_network_update.assert_called_once_with(
self.fake_context,
fake_share_network['id'],
{'status': constants.STATUS_ERROR})
has_provider_nw_ext.stop()
save_nw_data.stop()
@ -223,11 +211,6 @@ class NeutronNetworkPluginTest(unittest.TestCase):
self.fake_context,
fake_network_allocation['id'],
{'status': constants.STATUS_ERROR})
db_api.share_network_update.assert_called_once_with(
self.fake_context,
share_nw['id'],
{'status': constants.STATUS_ERROR})
delete_port.stop()
@mock.patch.object(db_api, 'share_network_update', mock.Mock())

View File

@ -137,7 +137,8 @@ class ServiceInstanceManagerTestCase(test.TestCase):
mock.Mock(return_value=mock.Mock()))
result = self._manager.get_service_instance(self._context,
share_network_id='fake_share_network_id')
share_network_id='fake_share_network_id',
create=True)
self._manager._ensure_server.assert_called_once()
self._manager._get_ssh_pool.assert_called_once_with(fake_server)
@ -186,7 +187,8 @@ class ServiceInstanceManagerTestCase(test.TestCase):
mock.Mock(return_value=mock.Mock()))
result = self._manager.get_service_instance(self._context,
share_network_id='fake_share_network_id')
share_network_id='fake_share_network_id',
create=True)
self._manager._ensure_server.assert_has_calls(
[mock.call(self._context, old_fake_server, update=True)])
@ -356,6 +358,8 @@ class ServiceInstanceManagerTestCase(test.TestCase):
def test_create_service_instance(self):
fake_server = fake_compute.FakeServer()
fake_port = fake_network.FakePort()
fake_instance_name = 'fake_instance_name'
sn_id = 'fake_sn_id'
self.stubs.Set(self._manager, '_get_service_image',
mock.Mock(return_value='fake_image_id'))
self.stubs.Set(self._manager, '_get_key',
@ -370,9 +374,10 @@ class ServiceInstanceManagerTestCase(test.TestCase):
self.stubs.Set(self._manager, '_get_server_ip',
mock.Mock(return_value='fake_ip'))
self.stubs.Set(service_instance.socket, 'socket', mock.Mock())
self.stubs.Set(self._manager, '_get_service_instance_name',
mock.Mock(return_value=fake_instance_name))
result = self._manager._create_service_instance(self._context,
'instance_name', self.share, None)
sn_id, None)
self._manager._get_service_image.assert_called_once()
self._manager._get_key.assert_called_once()
@ -380,7 +385,7 @@ class ServiceInstanceManagerTestCase(test.TestCase):
self._manager._setup_connectivity_with_service_instances.\
assert_called_once()
self._manager.compute_api.server_create.assert_called_once_with(
self._context, 'instance_name', 'fake_image_id',
self._context, fake_instance_name, 'fake_image_id',
CONF.service_instance_flavor_id, 'fake_key_name', None, None,
nics=[{'port-id': fake_port['id']}])
service_instance.socket.socket.assert_called_once()
@ -405,8 +410,8 @@ class ServiceInstanceManagerTestCase(test.TestCase):
self.stubs.Set(service_instance.socket, 'socket', mock.Mock())
self.assertRaises(exception.ManilaException,
self._manager._create_service_instance, self._context,
'instance_name', self.share, None)
self._manager._create_service_instance,
self._context, self.share, None)
self._manager.compute_api.server_create.assert_called_once()
self.assertFalse(self._manager.compute_api.server_get.called)
@ -432,8 +437,8 @@ class ServiceInstanceManagerTestCase(test.TestCase):
self.stubs.Set(service_instance.socket, 'socket', mock.Mock())
self.assertRaises(exception.ManilaException,
self._manager._create_service_instance,
self._context, 'instance_name', self.share, None)
self._manager._create_service_instance,
self._context, self.share, None)
self._manager.neutron_api.delete_port.\
assert_called_once_with(fake_port['id'])
@ -447,8 +452,8 @@ class ServiceInstanceManagerTestCase(test.TestCase):
self.stubs.Set(self._manager, '_get_key',
mock.Mock(return_value=None))
self.assertRaises(exception.ManilaException,
self._manager._create_service_instance, self._context,
'instance_name', self.share, None)
self._manager._create_service_instance,
self._context, self.share, None)
def test_setup_network_for_instance(self):
fake_service_net = fake_network.FakeNetwork(subnets=[])

View File

@ -37,6 +37,12 @@ class FakeShareDriver(object):
def __init__(self, db, **kwargs):
self.db = db
def share_network_update(*args, **kwargs):
pass
self.db.share_network_update = mock.Mock(
side_effect=share_network_update)
def create_snapshot(self, context, snapshot):
pass
@ -366,17 +372,19 @@ class ShareTestCase(test.TestCase):
metadata=test_meta)
def test_setup_share_network(self):
network_info = {'fake': 'fake'}
share_network = {'id': 'fake_sn_id', 'share_network': 'share_network'}
allocation_number = 555
self.share.driver.get_network_allocations_number = mock.Mock(
return_value=555)
return_value=allocation_number)
self.share.network_api.allocate_network = mock.Mock(
return_value={'network_info': 'network_info'})
return_value=share_network)
self.share.driver.setup_network = mock.Mock()
self.share._activate_share_network(self.context, network_info)
self.share._activate_share_network(context=self.context,
share_network=share_network)
self.share.network_api.allocate_network.assert_called_once_with(
self.context, network_info, count=555)
self.context, share_network, count=allocation_number)
self.share.driver.setup_network.assert_called_once_with(
{'network_info': 'network_info'}, metadata=None)
share_network, metadata=None)
def test_setup_share_network_error(self):
network_info = {'fake': 'fake', 'id': 'fakeid'}
@ -403,8 +411,7 @@ class ShareTestCase(test.TestCase):
nw_api_deallocate_nw.stop()
def test_activate_network(self):
share_network_id = 'fake network id'
share_network = {}
share_network = {'id': 'fake network id'}
db_share_nw_get = mock.patch.object(self.share.db,
'share_network_get').start()
db_share_nw_get.return_value = share_network
@ -418,9 +425,9 @@ class ShareTestCase(test.TestCase):
with mock.patch.object(self.share.driver, 'setup_network',
mock.Mock()):
self.share.activate_network(self.context, share_network_id)
self.share.activate_network(self.context, share_network['id'])
db_share_nw_get.assert_called_once_with(self.context,
share_network_id)
share_network['id'])
drv_get_alloc_cnt.assert_any_call()
nw_api_allocate_nw.assert_called_once_with(self.context,
share_network,
@ -434,8 +441,7 @@ class ShareTestCase(test.TestCase):
nw_api_allocate_nw.stop()
def test_deactivate_network(self):
share_network_id = 'fake network id'
share_network = {}
share_network = {'id': 'fake network id'}
db_share_nw_get = mock.patch.object(self.share.db,
'share_network_get').start()
db_share_nw_get.return_value = share_network
@ -444,9 +450,9 @@ class ShareTestCase(test.TestCase):
with mock.patch.object(self.share.driver, 'teardown_network',
mock.Mock()):
self.share.deactivate_network(self.context, share_network_id)
self.share.deactivate_network(self.context, share_network['id'])
db_share_nw_get.assert_called_once_with(self.context,
share_network_id)
share_network['id'])
nw_api_deallocate_nw.assert_called_once_with(self.context,
share_network)
self.share.driver.teardown_network.assert_called_once_with(

View File

@ -28,6 +28,7 @@ from manila.share.drivers import generic
from manila import test
from manila.tests.db import fakes as db_fakes
from manila.tests import fake_compute
from manila.tests import fake_service_instance
from manila.tests import fake_utils
from manila.tests import fake_volume
from manila import volume
@ -97,7 +98,16 @@ class GenericShareDriverTestCase(test.TestCase):
self._driver.get_service_instance = mock.Mock()
self._driver.share_networks_servers = {}
self._driver.admin_context = self._context
self._driver.instance_manager = mock.Mock()
self.fake_sn = {"id": "fake_sn_id"}
fsim = fake_service_instance.FakeServiceInstanceManager()
sim = mock.Mock(return_value=fsim)
self._driver.instance_manager = sim
self._driver.service_instance_manager = sim
self.fake_server = sim._create_service_instance(
context="fake", instance_name="fake",
share_network_id=self.fake_sn["id"], old_server_ip="fake")
self.stubs.Set(generic, '_ssh_exec', mock.Mock())
self.stubs.Set(generic, 'synchronized', mock.Mock(side_effect=
lambda f: f))
@ -550,6 +560,28 @@ class GenericShareDriverTestCase(test.TestCase):
access['access_type'],
access['access_to'])
def test_setup_network(self):
sim = self._driver.instance_manager
self._driver.setup_network(self.fake_sn)
sim.get_service_instance.assert_called_once()
def test_setup_network_revert(self):
def raise_exception(*args, **kwargs):
raise exception.ServiceInstanceException
self.stubs.Set(self._driver, 'get_service_instance',
mock.Mock(side_effect=raise_exception))
self.assertRaises(exception.ServiceInstanceException,
self._driver.setup_network,
self.fake_sn)
def test_teardown_network(self):
sim = self._driver.instance_manager
self._driver.service_instance_manager = sim
self._driver.teardown_network(self.fake_sn)
sim.delete_service_instance.assert_called_once()
class NFSHelperTestCase(test.TestCase):
"""Test case for NFS helper of generic driver."""