diff --git a/manila/exception.py b/manila/exception.py
index 319637ac71..4836e92be0 100644
--- a/manila/exception.py
+++ b/manila/exception.py
@@ -498,12 +498,32 @@ class ServiceInstanceUnavailable(ServiceInstanceException):
message = _("Service instance is not available.")
+class StorageResourceException(ManilaException):
+ message = _("Storage resource exception.")
+
+
+class StorageResourceNotFound(StorageResourceException):
+ message = _("Storage resource %(name)s not found.")
+
+
+class SnapshotNotFound(StorageResourceNotFound):
+ message = _("Snapshot %(name)s not found.")
+
+
+class SnapshotUnavailable(StorageResourceException):
+ message = _("Snapshot %(name)s info not available.")
+
+
class NetAppException(ManilaException):
message = _("Exception due to NetApp failure.")
-class VserverUnavailable(NetAppException):
- message = _("Vserver %(vserver)s is not available.")
+class VserverNotFound(NetAppException):
+ message = _("Vserver %(vserver)s not found.")
+
+
+class VserverNotSpecified(NetAppException):
+ message = _("Vserver not specified.")
class EMCVnxXMLAPIError(Invalid):
diff --git a/manila/share/drivers/netapp/dataontap/client/api.py b/manila/share/drivers/netapp/dataontap/client/api.py
index 28ad080c09..c617aea0e5 100644
--- a/manila/share/drivers/netapp/dataontap/client/api.py
+++ b/manila/share/drivers/netapp/dataontap/client/api.py
@@ -33,10 +33,12 @@ LOG = log.getLogger(__name__)
EONTAPI_EINVAL = '22'
EAPINOTFOUND = '13005'
+ESNAPSHOTNOTALLOWED = '13023'
EVOLUMEOFFLINE = '13042'
EINTERNALERROR = '13114'
EDUPLICATEENTRY = '13130'
EVOLNOTCLONE = '13170'
+EVOL_NOT_MOUNTED = '14716'
ESIS_CLONE_NOT_LICENSED = '14956'
EOBJECTNOTFOUND = '15661'
diff --git a/manila/share/drivers/netapp/dataontap/client/client_cmode.py b/manila/share/drivers/netapp/dataontap/client/client_cmode.py
index f00fc98dd2..7af4e9f157 100644
--- a/manila/share/drivers/netapp/dataontap/client/client_cmode.py
+++ b/manila/share/drivers/netapp/dataontap/client/client_cmode.py
@@ -899,7 +899,12 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
@na_utils.trace
def offline_volume(self, volume_name):
"""Offlines a volume."""
- self.send_request('volume-offline', {'name': volume_name})
+ try:
+ self.send_request('volume-offline', {'name': volume_name})
+ except netapp_api.NaApiError as e:
+ if e.code == netapp_api.EVOLUMEOFFLINE:
+ return
+ raise
@na_utils.trace
def unmount_volume(self, volume_name, force=False):
@@ -908,7 +913,12 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
'volume-name': volume_name,
'force': six.text_type(force).lower(),
}
- self.send_request('volume-unmount', api_args)
+ try:
+ self.send_request('volume-unmount', api_args)
+ except netapp_api.NaApiError as e:
+ if e.code == netapp_api.EVOL_NOT_MOUNTED:
+ return
+ raise
@na_utils.trace
def delete_volume(self, volume_name):
@@ -944,11 +954,33 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
}
result = self.send_request('snapshot-get-iter', api_args)
+ error_record_list = result.get_child_by_name(
+ 'volume-errors') or netapp_api.NaElement('none')
+ errors = error_record_list.get_children()
+
+ if errors:
+ error = errors[0]
+ error_code = error.get_child_content('errno')
+ error_reason = error.get_child_content('reason')
+ msg = _('Could not read information for snapshot %(name)s. '
+ 'Code: %(code)s. Reason: %(reason)s')
+ msg_args = {
+ 'name': snapshot_name,
+ 'code': error_code,
+ 'reason': error_reason
+ }
+ if error_code == netapp_api.ESNAPSHOTNOTALLOWED:
+ raise exception.SnapshotUnavailable(msg % msg_args)
+ else:
+ raise exception.NetAppException(msg % msg_args)
+
attributes_list = result.get_child_by_name(
'attributes-list') or netapp_api.NaElement('none')
snapshot_info_list = attributes_list.get_children()
- if not self._has_records(result) or len(snapshot_info_list) != 1:
+ if not self._has_records(result):
+ raise exception.SnapshotNotFound(name=snapshot_name)
+ elif len(snapshot_info_list) > 1:
msg = _('Could not find unique snapshot %(snap)s on '
'volume %(vol)s.')
msg_args = {'snap': snapshot_name, 'vol': volume_name}
diff --git a/manila/share/drivers/netapp/dataontap/cluster_mode/lib_base.py b/manila/share/drivers/netapp/dataontap/cluster_mode/lib_base.py
index b9d27322be..9dc09ede73 100644
--- a/manila/share/drivers/netapp/dataontap/cluster_mode/lib_base.py
+++ b/manila/share/drivers/netapp/dataontap/cluster_mode/lib_base.py
@@ -28,7 +28,7 @@ from oslo_utils import units
import six
from manila import exception
-from manila.i18n import _, _LE, _LI
+from manila.i18n import _, _LE, _LI, _LW
from manila.openstack.common import loopingcall
from manila.share.drivers.netapp.dataontap.client import client_cmode
from manila.share.drivers.netapp.dataontap.protocols import cifs_cmode
@@ -459,8 +459,19 @@ class NetAppCmodeFileStorageLibrary(object):
@na_utils.trace
def delete_share(self, context, share, share_server=None):
"""Deletes share."""
+ try:
+ vserver, vserver_client = self._get_vserver(
+ share_server=share_server)
+ except (exception.InvalidInput,
+ exception.VserverNotSpecified,
+ exception.VserverNotFound) as error:
+ LOG.warning(_LW("Could not determine share server for share being "
+ "deleted: %(share)s. Deletion of share record "
+ "will proceed anyway. Error: %(error)s"),
+ {'share': share['id'], 'error': error})
+ return
+
share_name = self._get_valid_share_name(share['id'])
- vserver, vserver_client = self._get_vserver(share_server=share_server)
if self._share_exists(share_name, vserver_client):
self._remove_export(share, vserver_client)
self._deallocate_container(share_name, vserver_client)
@@ -516,11 +527,27 @@ class NetAppCmodeFileStorageLibrary(object):
@na_utils.trace
def delete_snapshot(self, context, snapshot, share_server=None):
"""Deletes a snapshot of a share."""
- vserver, vserver_client = self._get_vserver(share_server=share_server)
+ try:
+ vserver, vserver_client = self._get_vserver(
+ share_server=share_server)
+ except (exception.InvalidInput,
+ exception.VserverNotSpecified,
+ exception.VserverNotFound) as error:
+ LOG.warning(_LW("Could not determine share server for snapshot "
+ "being deleted: %(snap)s. Deletion of snapshot "
+ "record will proceed anyway. Error: %(error)s"),
+ {'snap': snapshot['id'], 'error': error})
+ return
+
share_name = self._get_valid_share_name(snapshot['share_id'])
snapshot_name = self._get_valid_snapshot_name(snapshot['id'])
- self._handle_busy_snapshot(vserver_client, share_name, snapshot_name)
+ try:
+ self._handle_busy_snapshot(vserver_client, share_name,
+ snapshot_name)
+ except exception.SnapshotNotFound:
+ LOG.info(_LI("Snapshot %s does not exist."), snapshot_name)
+ return
LOG.debug('Deleting snapshot %(snap)s for share %(share)s.',
{'snap': snapshot_name, 'share': share_name})
diff --git a/manila/share/drivers/netapp/dataontap/cluster_mode/lib_multi_svm.py b/manila/share/drivers/netapp/dataontap/cluster_mode/lib_multi_svm.py
index ca93b68559..fb7e99618a 100644
--- a/manila/share/drivers/netapp/dataontap/cluster_mode/lib_multi_svm.py
+++ b/manila/share/drivers/netapp/dataontap/cluster_mode/lib_multi_svm.py
@@ -80,7 +80,8 @@ class NetAppCmodeMultiSVMFileStorageLibrary(
def _get_vserver(self, share_server=None):
if not share_server:
- raise exception.NetAppException(_('Share server not provided.'))
+ msg = _('Share server not provided')
+ raise exception.InvalidInput(reason=msg)
backend_details = share_server.get('backend_details')
vserver = backend_details.get(
@@ -89,10 +90,10 @@ class NetAppCmodeMultiSVMFileStorageLibrary(
if not vserver:
msg = _('Vserver name is absent in backend details. Please '
'check whether Vserver was created properly.')
- raise exception.NetAppException(msg)
+ raise exception.VserverNotSpecified(msg)
if not self._client.vserver_exists(vserver):
- raise exception.VserverUnavailable(vserver=vserver)
+ raise exception.VserverNotFound(vserver=vserver)
vserver_client = self._get_api_client(vserver)
return vserver, vserver_client
@@ -205,8 +206,23 @@ class NetAppCmodeMultiSVMFileStorageLibrary(
@na_utils.trace
def teardown_server(self, server_details, security_services=None):
- """Teardown share network."""
- vserver = server_details['vserver_name']
+ """Teardown share server."""
+ vserver = server_details.get(
+ 'vserver_name') if server_details else None
+
+ if not vserver:
+ LOG.warning(_LW("Vserver not specified for share server being "
+ "deleted. Deletion of share server record will "
+ "proceed anyway."))
+ return
+
+ elif not self._client.vserver_exists(vserver):
+ LOG.warning(_LW("Could not find Vserver for share server being "
+ "deleted: %s. Deletion of share server "
+ "record will proceed anyway."), vserver)
+ return
+
vserver_client = self._get_api_client(vserver=vserver)
- self._client.delete_vserver(vserver, vserver_client,
+ self._client.delete_vserver(vserver,
+ vserver_client,
security_services=security_services)
diff --git a/manila/share/drivers/netapp/dataontap/cluster_mode/lib_single_svm.py b/manila/share/drivers/netapp/dataontap/cluster_mode/lib_single_svm.py
index c38975be82..6346afe253 100644
--- a/manila/share/drivers/netapp/dataontap/cluster_mode/lib_single_svm.py
+++ b/manila/share/drivers/netapp/dataontap/cluster_mode/lib_single_svm.py
@@ -53,7 +53,7 @@ class NetAppCmodeSingleSVMFileStorageLibrary(
# Ensure vserver exists.
if not self._client.vserver_exists(self._vserver):
- raise exception.VserverUnavailable(vserver=self._vserver)
+ raise exception.VserverNotFound(vserver=self._vserver)
# If we have vserver credentials, ensure the vserver they connect
# to matches the vserver specified in the configuration.
@@ -95,7 +95,7 @@ class NetAppCmodeSingleSVMFileStorageLibrary(
raise exception.InvalidInput(reason=msg)
if not self._client.vserver_exists(self._vserver):
- raise exception.VserverUnavailable(vserver=self._vserver)
+ raise exception.VserverNotFound(vserver=self._vserver)
vserver_client = self._get_api_client(self._vserver)
return self._vserver, vserver_client
diff --git a/manila/tests/share/drivers/netapp/dataontap/client/fakes.py b/manila/tests/share/drivers/netapp/dataontap/client/fakes.py
index 10208cd8ed..6b850d0c82 100644
--- a/manila/tests/share/drivers/netapp/dataontap/client/fakes.py
+++ b/manila/tests/share/drivers/netapp/dataontap/client/fakes.py
@@ -1019,6 +1019,62 @@ SNAPSHOT_GET_ITER_BUSY_RESPONSE = etree.XML("""
""" % {'snap': SNAPSHOT_NAME, 'volume': SHARE_NAME, 'vserver': VSERVER_NAME})
+SNAPSHOT_GET_ITER_NOT_UNIQUE_RESPONSE = etree.XML("""
+
+
+
+ false
+ %(snap)s
+ %(volume)s
+ %(vserver)s
+
+
+ false
+ %(snap)s
+ %(root_volume)s
+ %(admin_vserver)s
+
+
+ 1
+
+""" % {
+ 'snap': SNAPSHOT_NAME,
+ 'volume': SHARE_NAME,
+ 'vserver': VSERVER_NAME,
+ 'root_volume': ROOT_VOLUME_NAME,
+ 'admin_vserver': ADMIN_VSERVER_NAME,
+})
+
+SNAPSHOT_GET_ITER_UNAVAILABLE_RESPONSE = etree.XML("""
+
+ 0
+
+
+ 13023
+ %(volume)s
+ Unable to get information for Snapshot copies of volume \
+"%(volume)s" on Vserver "%(vserver)s". Reason: Volume not online.
+ %(vserver)s
+
+
+
+""" % {'volume': SHARE_NAME, 'vserver': VSERVER_NAME})
+
+SNAPSHOT_GET_ITER_OTHER_ERROR_RESPONSE = etree.XML("""
+
+ 0
+
+
+ 99999
+ %(volume)s
+ Unable to get information for Snapshot copies of volume \
+"%(volume)s" on Vserver "%(vserver)s".
+ %(vserver)s
+
+
+
+""" % {'volume': SHARE_NAME, 'vserver': VSERVER_NAME})
+
NFS_EXPORT_RULES = ('10.10.10.10', '10.10.10.20')
NFS_EXPORTFS_LIST_RULES_2_NO_RULES_RESPONSE = etree.XML("""
diff --git a/manila/tests/share/drivers/netapp/dataontap/client/test_client_cmode.py b/manila/tests/share/drivers/netapp/dataontap/client/test_client_cmode.py
index 0b914d90a0..fa7d99e397 100644
--- a/manila/tests/share/drivers/netapp/dataontap/client/test_client_cmode.py
+++ b/manila/tests/share/drivers/netapp/dataontap/client/test_client_cmode.py
@@ -1594,6 +1594,30 @@ class NetAppClientCmodeTestCase(test.TestCase):
self.client.send_request.assert_has_calls([
mock.call('volume-offline', volume_offline_args)])
+ def test_offline_volume_already_offline(self):
+
+ self.mock_object(self.client,
+ 'send_request',
+ mock.Mock(side_effect=self._mock_api_error(
+ netapp_api.EVOLUMEOFFLINE)))
+
+ self.client.offline_volume(fake.SHARE_NAME)
+
+ volume_offline_args = {'name': fake.SHARE_NAME}
+
+ self.client.send_request.assert_has_calls([
+ mock.call('volume-offline', volume_offline_args)])
+
+ def test_offline_volume_api_error(self):
+
+ self.mock_object(self.client,
+ 'send_request',
+ mock.Mock(side_effect=self._mock_api_error()))
+
+ self.assertRaises(netapp_api.NaApiError,
+ self.client.offline_volume,
+ fake.SHARE_NAME)
+
def test_unmount_volume(self):
self.mock_object(self.client, 'send_request')
@@ -1614,14 +1638,36 @@ class NetAppClientCmodeTestCase(test.TestCase):
self.client.unmount_volume(fake.SHARE_NAME, force=True)
- volume_unmount_args = {
- 'volume-name': fake.SHARE_NAME,
- 'force': 'true'
- }
+ volume_unmount_args = {'volume-name': fake.SHARE_NAME, 'force': 'true'}
self.client.send_request.assert_has_calls([
mock.call('volume-unmount', volume_unmount_args)])
+ def test_unmount_volume_already_unmounted(self):
+
+ self.mock_object(self.client,
+ 'send_request',
+ mock.Mock(side_effect=self._mock_api_error(
+ netapp_api.EVOL_NOT_MOUNTED)))
+
+ self.client.unmount_volume(fake.SHARE_NAME, force=True)
+
+ volume_unmount_args = {'volume-name': fake.SHARE_NAME, 'force': 'true'}
+
+ self.client.send_request.assert_has_calls([
+ mock.call('volume-unmount', volume_unmount_args)])
+
+ def test_unmount_volume_api_error(self):
+
+ self.mock_object(self.client,
+ 'send_request',
+ mock.Mock(side_effect=self._mock_api_error()))
+
+ self.assertRaises(netapp_api.NaApiError,
+ self.client.unmount_volume,
+ fake.SHARE_NAME,
+ force=True)
+
def test_delete_volume(self):
self.mock_object(self.client, 'send_request')
@@ -1696,14 +1742,28 @@ class NetAppClientCmodeTestCase(test.TestCase):
mock.call('snapshot-get-iter', snapshot_get_iter_args)])
self.assertDictEqual(expected, result)
- def test_get_snapshot_not_found(self):
+ @ddt.data({
+ 'api_response_xml': fake.NO_RECORDS_RESPONSE,
+ 'raised_exception': exception.SnapshotNotFound,
+ }, {
+ 'api_response_xml': fake.SNAPSHOT_GET_ITER_NOT_UNIQUE_RESPONSE,
+ 'raised_exception': exception.NetAppException,
+ }, {
+ 'api_response_xml': fake.SNAPSHOT_GET_ITER_UNAVAILABLE_RESPONSE,
+ 'raised_exception': exception.SnapshotUnavailable,
+ }, {
+ 'api_response_xml': fake.SNAPSHOT_GET_ITER_OTHER_ERROR_RESPONSE,
+ 'raised_exception': exception.NetAppException,
+ })
+ @ddt.unpack
+ def test_get_snapshot_error(self, api_response_xml, raised_exception):
- api_response = netapp_api.NaElement(fake.NO_RECORDS_RESPONSE)
+ api_response = netapp_api.NaElement(api_response_xml)
self.mock_object(self.client,
'send_request',
mock.Mock(return_value=api_response))
- self.assertRaises(exception.NetAppException,
+ self.assertRaises(raised_exception,
self.client.get_snapshot,
fake.SHARE_NAME,
fake.SNAPSHOT_NAME)
diff --git a/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_base.py b/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_base.py
index 5e266867d9..274671b19a 100644
--- a/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_base.py
+++ b/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_base.py
@@ -20,6 +20,7 @@ import copy
import socket
import time
+import ddt
import mock
from oslo_log import log
@@ -36,6 +37,7 @@ from manila import test
from manila.tests.share.drivers.netapp.dataontap import fakes as fake
+@ddt.ddt
class NetAppFileStorageLibraryTestCase(test.TestCase):
def setUp(self):
@@ -49,6 +51,9 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
self.mock_object(lib_base.LOG,
'info',
mock.Mock(side_effect=mock_logger.info))
+ self.mock_object(lib_base.LOG,
+ 'warning',
+ mock.Mock(side_effect=mock_logger.warning))
self.mock_object(lib_base.LOG,
'error',
mock.Mock(side_effect=mock_logger.error))
@@ -754,6 +759,30 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
vserver_client)
self.assertEqual(0, lib_base.LOG.info.call_count)
+ @ddt.data(exception.InvalidInput(reason='fake_reason'),
+ exception.VserverNotSpecified(),
+ exception.VserverNotFound(vserver='fake_vserver'))
+ def test_delete_share_no_share_server(self, get_vserver_exception):
+
+ self.mock_object(self.library,
+ '_get_vserver',
+ mock.Mock(side_effect=get_vserver_exception))
+ mock_share_exists = self.mock_object(self.library,
+ '_share_exists',
+ mock.Mock(return_value=False))
+ mock_remove_export = self.mock_object(self.library, '_remove_export')
+ mock_deallocate_container = self.mock_object(self.library,
+ '_deallocate_container')
+
+ self.library.delete_share(self.context,
+ fake.SHARE,
+ share_server=fake.SHARE_SERVER)
+
+ self.assertFalse(mock_share_exists.called)
+ self.assertFalse(mock_remove_export.called)
+ self.assertFalse(mock_deallocate_container.called)
+ self.assertEqual(1, lib_base.LOG.warning.call_count)
+
def test_delete_share_not_found(self):
vserver_client = mock.Mock()
@@ -891,6 +920,64 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
vserver_client.delete_snapshot.assert_called_once_with(share_name,
snapshot_name)
+ @ddt.data(exception.InvalidInput(reason='fake_reason'),
+ exception.VserverNotSpecified(),
+ exception.VserverNotFound(vserver='fake_vserver'))
+ def test_delete_snapshot_no_share_server(self, get_vserver_exception):
+
+ self.mock_object(self.library,
+ '_get_vserver',
+ mock.Mock(side_effect=get_vserver_exception))
+ mock_handle_busy_snapshot = self.mock_object(self.library,
+ '_handle_busy_snapshot')
+
+ self.library.delete_snapshot(self.context,
+ fake.SNAPSHOT,
+ share_server=fake.SHARE_SERVER)
+
+ self.assertFalse(mock_handle_busy_snapshot.called)
+ self.assertEqual(1, lib_base.LOG.warning.call_count)
+
+ def test_delete_snapshot_not_found(self):
+
+ vserver_client = mock.Mock()
+ self.mock_object(self.library,
+ '_get_vserver',
+ mock.Mock(return_value=(fake.VSERVER1,
+ vserver_client)))
+ mock_handle_busy_snapshot = self.mock_object(
+ self.library, '_handle_busy_snapshot',
+ mock.Mock(side_effect=exception.SnapshotNotFound(
+ name=fake.SNAPSHOT_NAME)))
+
+ self.library.delete_snapshot(self.context,
+ fake.SNAPSHOT,
+ share_server=fake.SHARE_SERVER)
+
+ self.assertTrue(mock_handle_busy_snapshot.called)
+ self.assertFalse(vserver_client.delete_snapshot.called)
+
+ def test_delete_snapshot_busy(self):
+
+ vserver_client = mock.Mock()
+ self.mock_object(self.library,
+ '_get_vserver',
+ mock.Mock(return_value=(fake.VSERVER1,
+ vserver_client)))
+ mock_handle_busy_snapshot = self.mock_object(
+ self.library, '_handle_busy_snapshot',
+ mock.Mock(side_effect=exception.ShareSnapshotIsBusy(
+ snapshot_name=fake.SNAPSHOT_NAME)))
+
+ self.assertRaises(exception.ShareSnapshotIsBusy,
+ self.library.delete_snapshot,
+ self.context,
+ fake.SNAPSHOT,
+ share_server=fake.SHARE_SERVER)
+
+ self.assertTrue(mock_handle_busy_snapshot.called)
+ self.assertFalse(vserver_client.delete_snapshot.called)
+
def test_handle_busy_snapshot_not_busy(self):
vserver_client = mock.Mock()
@@ -904,6 +991,18 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
self.assertEqual(1, vserver_client.get_snapshot.call_count)
self.assertEqual(0, lib_base.LOG.debug.call_count)
+ def test_handle_busy_snapshot_not_found(self):
+
+ vserver_client = mock.Mock()
+ vserver_client.get_snapshot.side_effect = exception.SnapshotNotFound(
+ name=fake.SNAPSHOT_NAME)
+
+ self.assertRaises(exception.SnapshotNotFound,
+ self.library._handle_busy_snapshot,
+ vserver_client,
+ fake.SHARE_NAME,
+ fake.SNAPSHOT_NAME)
+
def test_handle_busy_snapshot_not_clone_dependency(self):
snapshot = copy.deepcopy(fake.CDOT_SNAPSHOT_BUSY_VOLUME_CLONE)
diff --git a/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_multi_svm.py b/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_multi_svm.py
index 0e6ace13a2..304ebb5e6f 100644
--- a/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_multi_svm.py
+++ b/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_multi_svm.py
@@ -121,7 +121,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
def test_get_vserver_no_share_server(self):
- self.assertRaises(exception.NetAppException,
+ self.assertRaises(exception.InvalidInput,
self.library._get_vserver)
def test_get_vserver_no_backend_details(self):
@@ -130,7 +130,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
fake_share_server.pop('backend_details')
kwargs = {'share_server': fake_share_server}
- self.assertRaises(exception.NetAppException,
+ self.assertRaises(exception.VserverNotSpecified,
self.library._get_vserver,
**kwargs)
@@ -140,7 +140,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
fake_share_server['backend_details'] = None
kwargs = {'share_server': fake_share_server}
- self.assertRaises(exception.NetAppException,
+ self.assertRaises(exception.VserverNotSpecified,
self.library._get_vserver,
**kwargs)
@@ -150,7 +150,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
fake_share_server['backend_details'].pop('vserver_name')
kwargs = {'share_server': fake_share_server}
- self.assertRaises(exception.NetAppException,
+ self.assertRaises(exception.VserverNotSpecified,
self.library._get_vserver,
**kwargs)
@@ -160,7 +160,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
fake_share_server['backend_details']['vserver_name'] = None
kwargs = {'share_server': fake_share_server}
- self.assertRaises(exception.NetAppException,
+ self.assertRaises(exception.VserverNotSpecified,
self.library._get_vserver,
**kwargs)
@@ -169,7 +169,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
self.library._client.vserver_exists.return_value = False
kwargs = {'share_server': fake.SHARE_SERVER}
- self.assertRaises(exception.VserverUnavailable,
+ self.assertRaises(exception.VserverNotFound,
self.library._get_vserver,
**kwargs)
@@ -432,12 +432,36 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
self.mock_object(self.library,
'_get_api_client',
mock.Mock(return_value=vserver_client))
+ self.library._client.vserver_exists.return_value = True
self.library.teardown_server(
fake.SHARE_SERVER['backend_details'],
security_services=fake.NETWORK_INFO['security_services'])
+ self.library._client.vserver_exists.assert_called_once_with(
+ fake.VSERVER1)
self.library._client.delete_vserver.assert_called_once_with(
fake.VSERVER1,
vserver_client,
security_services=fake.NETWORK_INFO['security_services'])
+
+ @ddt.data(None, {}, {'vserver_name': None})
+ def test_teardown_server_no_share_server(self, server_details):
+
+ self.library.teardown_server(server_details)
+
+ self.assertFalse(self.library._client.delete_vserver.called)
+ self.assertTrue(lib_multi_svm.LOG.warning.called)
+
+ def test_teardown_server_no_vserver(self):
+
+ self.library._client.vserver_exists.return_value = False
+
+ self.library.teardown_server(
+ fake.SHARE_SERVER['backend_details'],
+ security_services=fake.NETWORK_INFO['security_services'])
+
+ self.library._client.vserver_exists.assert_called_once_with(
+ fake.VSERVER1)
+ self.assertFalse(self.library._client.delete_vserver.called)
+ self.assertTrue(lib_multi_svm.LOG.warning.called)
diff --git a/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_single_svm.py b/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_single_svm.py
index f222c3147c..fa152308dd 100644
--- a/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_single_svm.py
+++ b/manila/tests/share/drivers/netapp/dataontap/cluster_mode/test_lib_single_svm.py
@@ -83,7 +83,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
def test_check_for_setup_error_vserver_not_found(self):
self.library._client.vserver_exists.return_value = False
- self.assertRaises(exception.VserverUnavailable,
+ self.assertRaises(exception.VserverNotFound,
self.library.check_for_setup_error)
def test_check_for_setup_error_cluster_creds_vserver_match(self):
@@ -145,7 +145,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
def test_get_vserver_vserver_not_found(self):
self.library._client.vserver_exists.return_value = False
- self.assertRaises(exception.VserverUnavailable,
+ self.assertRaises(exception.VserverNotFound,
self.library._get_vserver)
def test_find_matching_aggregates(self):
diff --git a/manila/tests/share/drivers/netapp/dataontap/fakes.py b/manila/tests/share/drivers/netapp/dataontap/fakes.py
index ef166f3ca1..a80a776943 100644
--- a/manila/tests/share/drivers/netapp/dataontap/fakes.py
+++ b/manila/tests/share/drivers/netapp/dataontap/fakes.py
@@ -179,6 +179,7 @@ NETWORK_INFO = {
NETWORK_INFO_NETMASK = '255.255.255.0'
SHARE_SERVER = {
+ 'share_network_id': 'c5b3a865-56d0-4d88-abe5-879965e099c9',
'backend_details': {
'vserver_name': VSERVER1
}