Extend usage of user messages
Instead of creating a user message only from scheduler during resource creation, a message is created directly by share manager which allows more detailed error reporting. Partially-implements: blueprint user-messages Change-Id: Ic7d25a144905a39c56ababe8bd666b01bc0d0aef
This commit is contained in:
parent
dd630c3929
commit
360474974d
|
@ -16,24 +16,57 @@ from manila.i18n import _
|
|||
class Resource(object):
|
||||
|
||||
SHARE = 'SHARE'
|
||||
SHARE_GROUP = 'SHARE_GROUP'
|
||||
SHARE_REPLICA = 'SHARE_REPLICA'
|
||||
SHARE_SNAPSHOT = 'SHARE_SNAPSHOT'
|
||||
|
||||
|
||||
class Action(object):
|
||||
|
||||
ALLOCATE_HOST = ('001', _('allocate host'))
|
||||
|
||||
ALL = (ALLOCATE_HOST,)
|
||||
CREATE = ('002', _('create'))
|
||||
DELETE_ACCESS_RULES = ('003', _('delete access rules'))
|
||||
PROMOTE = ('004', _('promote'))
|
||||
UPDATE = ('005', _('update'))
|
||||
REVERT_TO_SNAPSHOT = ('006', _('revert to snapshot'))
|
||||
DELETE = ('007', _('delete'))
|
||||
ALL = (ALLOCATE_HOST,
|
||||
CREATE,
|
||||
DELETE_ACCESS_RULES,
|
||||
PROMOTE,
|
||||
UPDATE,
|
||||
REVERT_TO_SNAPSHOT,
|
||||
DELETE)
|
||||
|
||||
|
||||
class Detail(object):
|
||||
|
||||
UNKNOWN_ERROR = ('001', _('An unknown error occurred.'))
|
||||
NO_VALID_HOST = ('002', _("No storage could be allocated for this share "
|
||||
"request. Trying again with a different size "
|
||||
"or share type may succeed."))
|
||||
NO_VALID_HOST = (
|
||||
'002', _("No storage could be allocated for this share request. "
|
||||
"Trying again with a different size or share type may "
|
||||
"succeed."))
|
||||
UNEXPECTED_NETWORK = (
|
||||
'003', _("Driver does not expect share-network to be provided with "
|
||||
"current configuration."))
|
||||
NO_SHARE_SERVER = (
|
||||
'004', _("Could not find an existing share server or allocate one on "
|
||||
"the share network provided. You may use a different share "
|
||||
"network, or verify the network details in the share network "
|
||||
"and retry your request. If this doesn't work, contact your "
|
||||
"administrator to troubleshoot issues with your network."))
|
||||
NO_ACTIVE_AVAILABLE_REPLICA = (
|
||||
'005', _("An 'active' replica must exist in 'available' state to "
|
||||
"create a new replica for share."))
|
||||
NO_ACTIVE_REPLICA = (
|
||||
'006', _("Share has no replica with 'replica_state' set to 'active'."))
|
||||
|
||||
ALL = (UNKNOWN_ERROR,
|
||||
NO_VALID_HOST)
|
||||
NO_VALID_HOST,
|
||||
UNEXPECTED_NETWORK,
|
||||
NO_SHARE_SERVER,
|
||||
NO_ACTIVE_AVAILABLE_REPLICA,
|
||||
NO_ACTIVE_REPLICA,)
|
||||
|
||||
# Exception and detail mappings
|
||||
EXCEPTION_DETAIL_MAPPINGS = {
|
||||
|
|
|
@ -221,7 +221,8 @@ class SchedulerManager(manager.Manager):
|
|||
def request_service_capabilities(self, context):
|
||||
share_rpcapi.ShareAPI().publish_service_capabilities(context)
|
||||
|
||||
def _set_share_group_error_state(self, method, context, ex, request_spec):
|
||||
def _set_share_group_error_state(self, method, context, ex,
|
||||
request_spec, action=None):
|
||||
LOG.warning("Failed to schedule_%(method)s: %(ex)s",
|
||||
{"method": method, "ex": ex})
|
||||
|
||||
|
@ -232,6 +233,12 @@ class SchedulerManager(manager.Manager):
|
|||
if share_group_id:
|
||||
db.share_group_update(context, share_group_id, share_group_state)
|
||||
|
||||
if action:
|
||||
self.message_api.create(
|
||||
context, action, context.project_id,
|
||||
resource_type=message_field.Resource.SHARE_GROUP,
|
||||
resource_id=share_group_id, exception=ex)
|
||||
|
||||
@periodic_task.periodic_task(spacing=600, run_immediately=True)
|
||||
def _expire_reservations(self, context):
|
||||
quota.QUOTAS.expire(context)
|
||||
|
@ -243,14 +250,15 @@ class SchedulerManager(manager.Manager):
|
|||
context, share_group_id, request_spec, filter_properties)
|
||||
except exception.NoValidHost as ex:
|
||||
self._set_share_group_error_state(
|
||||
'create_share_group', context, ex, request_spec)
|
||||
'create_share_group', context, ex, request_spec,
|
||||
message_field.Action.ALLOCATE_HOST)
|
||||
except Exception as ex:
|
||||
with excutils.save_and_reraise_exception():
|
||||
self._set_share_group_error_state(
|
||||
'create_share_group', context, ex, request_spec)
|
||||
|
||||
def _set_share_replica_error_state(self, context, method, exc,
|
||||
request_spec):
|
||||
request_spec, action=None):
|
||||
|
||||
LOG.warning("Failed to schedule_%(method)s: %(exc)s",
|
||||
{'method': method, 'exc': exc})
|
||||
|
@ -271,6 +279,12 @@ class SchedulerManager(manager.Manager):
|
|||
|
||||
db.share_replica_update(context, share_replica_id, status_updates)
|
||||
|
||||
if action:
|
||||
self.message_api.create(
|
||||
context, action, context.project_id,
|
||||
resource_type=message_field.Resource.SHARE_REPLICA,
|
||||
resource_id=share_replica_id, exception=exc)
|
||||
|
||||
def create_share_replica(self, context, request_spec=None,
|
||||
filter_properties=None):
|
||||
try:
|
||||
|
@ -279,7 +293,8 @@ class SchedulerManager(manager.Manager):
|
|||
|
||||
except exception.NoValidHost as exc:
|
||||
self._set_share_replica_error_state(
|
||||
context, 'create_share_replica', exc, request_spec)
|
||||
context, 'create_share_replica', exc, request_spec,
|
||||
message_field.Action.ALLOCATE_HOST)
|
||||
|
||||
except Exception as exc:
|
||||
with excutils.save_and_reraise_exception():
|
||||
|
|
|
@ -40,6 +40,8 @@ from manila.data import rpcapi as data_rpcapi
|
|||
from manila import exception
|
||||
from manila.i18n import _
|
||||
from manila import manager
|
||||
from manila.message import api as message_api
|
||||
from manila.message import message_field
|
||||
from manila import quota
|
||||
from manila.share import access
|
||||
from manila.share import api
|
||||
|
@ -227,6 +229,7 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
self.migration_wait_access_rules_timeout = (
|
||||
CONF.migration_wait_access_rules_timeout)
|
||||
|
||||
self.message_api = message_api.API()
|
||||
self.hooks = []
|
||||
self._init_hook_drivers()
|
||||
|
||||
|
@ -423,7 +426,6 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
|
||||
def error(msg, *args):
|
||||
LOG.error(msg, *args)
|
||||
|
||||
self.db.share_instance_update(context, share_instance['id'],
|
||||
{'status': constants.STATUS_ERROR})
|
||||
|
||||
|
@ -1566,6 +1568,13 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
if share_network_id and not self.driver.driver_handles_share_servers:
|
||||
self.db.share_instance_update(
|
||||
context, share_instance_id, {'status': constants.STATUS_ERROR})
|
||||
self.message_api.create(
|
||||
context,
|
||||
message_field.Action.CREATE,
|
||||
share['project_id'],
|
||||
resource_type=message_field.Resource.SHARE,
|
||||
resource_id=share_id,
|
||||
detail=message_field.Detail.UNEXPECTED_NETWORK)
|
||||
raise exception.ManilaException(_(
|
||||
"Creation of share instance %s failed: driver does not expect "
|
||||
"share-network to be provided with current "
|
||||
|
@ -1602,6 +1611,14 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
context, share_instance_id,
|
||||
{'status': constants.STATUS_ERROR}
|
||||
)
|
||||
self.message_api.create(
|
||||
context,
|
||||
message_field.Action.CREATE,
|
||||
share['project_id'],
|
||||
resource_type=message_field.Resource.SHARE,
|
||||
resource_id=share_id,
|
||||
detail=message_field.Detail.NO_SHARE_SERVER)
|
||||
|
||||
else:
|
||||
share_server = None
|
||||
|
||||
|
@ -1643,6 +1660,13 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
context, share_instance_id,
|
||||
{'status': constants.STATUS_ERROR}
|
||||
)
|
||||
self.message_api.create(
|
||||
context,
|
||||
message_field.Action.CREATE,
|
||||
share['project_id'],
|
||||
resource_type=message_field.Resource.SHARE,
|
||||
resource_id=share_id,
|
||||
exception=e)
|
||||
else:
|
||||
LOG.info("Share instance %s created successfully.",
|
||||
share_instance_id)
|
||||
|
@ -1726,6 +1750,13 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
context, share_replica['id'],
|
||||
{'status': constants.STATUS_ERROR,
|
||||
'replica_state': constants.STATUS_ERROR})
|
||||
self.message_api.create(
|
||||
context,
|
||||
message_field.Action.CREATE,
|
||||
share_replica['project_id'],
|
||||
resource_type=message_field.Resource.SHARE_REPLICA,
|
||||
resource_id=share_replica['id'],
|
||||
detail=message_field.Detail.NO_ACTIVE_REPLICA)
|
||||
msg = _("An 'active' replica must exist in 'available' "
|
||||
"state to create a new replica for share %s.")
|
||||
raise exception.ReplicationException(
|
||||
|
@ -1741,6 +1772,13 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
context, share_replica['id'],
|
||||
{'status': constants.STATUS_ERROR,
|
||||
'replica_state': constants.STATUS_ERROR})
|
||||
self.message_api.create(
|
||||
context,
|
||||
message_field.Action.CREATE,
|
||||
share_replica['project_id'],
|
||||
resource_type=message_field.Resource.SHARE_REPLICA,
|
||||
resource_id=share_replica['id'],
|
||||
detail=message_field.Detail.UNEXPECTED_NETWORK)
|
||||
raise exception.InvalidDriverMode(
|
||||
"Driver does not expect share-network to be provided "
|
||||
"with current configuration.")
|
||||
|
@ -1759,6 +1797,13 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
context, share_replica['id'],
|
||||
{'status': constants.STATUS_ERROR,
|
||||
'replica_state': constants.STATUS_ERROR})
|
||||
self.message_api.create(
|
||||
context,
|
||||
message_field.Action.CREATE,
|
||||
share_replica['project_id'],
|
||||
resource_type=message_field.Resource.SHARE_REPLICA,
|
||||
resource_id=share_replica['id'],
|
||||
detail=message_field.Detail.NO_SHARE_SERVER)
|
||||
else:
|
||||
share_server = None
|
||||
|
||||
|
@ -1794,7 +1839,7 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
share_access_rules, available_share_snapshots,
|
||||
share_server=share_server) or {}
|
||||
|
||||
except Exception:
|
||||
except Exception as excep:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error("Share replica %s failed on creation.",
|
||||
share_replica['id'])
|
||||
|
@ -1804,6 +1849,13 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
'replica_state': constants.STATUS_ERROR})
|
||||
self._update_share_replica_access_rules_state(
|
||||
context, share_replica['id'], constants.STATUS_ERROR)
|
||||
self.message_api.create(
|
||||
context,
|
||||
message_field.Action.CREATE,
|
||||
share_replica['project_id'],
|
||||
resource_type=message_field.Resource.SHARE_REPLICA,
|
||||
resource_id=share_replica['id'],
|
||||
exception=excep)
|
||||
|
||||
if replica_ref.get('export_locations'):
|
||||
if isinstance(replica_ref.get('export_locations'), list):
|
||||
|
@ -1871,13 +1923,20 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
delete_all_rules=True,
|
||||
share_server=share_server
|
||||
)
|
||||
except Exception:
|
||||
except Exception as excep:
|
||||
with excutils.save_and_reraise_exception() as exc_context:
|
||||
# Set status to 'error' from 'deleting' since
|
||||
# access_rules_status has been set to 'error'.
|
||||
self.db.share_replica_update(
|
||||
context, share_replica['id'],
|
||||
{'status': constants.STATUS_ERROR})
|
||||
self.message_api.create(
|
||||
context,
|
||||
message_field.Action.DELETE_ACCESS_RULES,
|
||||
share_replica['project_id'],
|
||||
resource_type=message_field.Resource.SHARE_REPLICA,
|
||||
resource_id=share_replica['id'],
|
||||
exception=excep)
|
||||
if force:
|
||||
msg = _("The driver was unable to delete access rules "
|
||||
"for the replica: %s. Will attempt to delete "
|
||||
|
@ -1889,7 +1948,7 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
self.driver.delete_replica(
|
||||
context, replica_list, replica_snapshots, share_replica,
|
||||
share_server=share_server)
|
||||
except Exception:
|
||||
except Exception as excep:
|
||||
with excutils.save_and_reraise_exception() as exc_context:
|
||||
if force:
|
||||
msg = _("The driver was unable to delete the share "
|
||||
|
@ -1904,6 +1963,13 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
context, share_replica['id'],
|
||||
{'status': constants.STATUS_ERROR_DELETING,
|
||||
'replica_state': constants.STATUS_ERROR})
|
||||
self.message_api.create(
|
||||
context,
|
||||
message_field.Action.DELETE,
|
||||
share_replica['project_id'],
|
||||
resource_type=message_field.Resource.SHARE_REPLICA,
|
||||
resource_id=share_replica['id'],
|
||||
exception=excep)
|
||||
|
||||
for replica_snapshot in replica_snapshots:
|
||||
self.db.share_snapshot_instance_delete(
|
||||
|
@ -1948,6 +2014,13 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
msg = _("Share %(share)s has no replica with 'replica_state' "
|
||||
"set to %(state)s. Promoting %(replica)s is not "
|
||||
"possible.")
|
||||
self.message_api.create(
|
||||
context,
|
||||
message_field.Action.PROMOTE,
|
||||
share_replica['project_id'],
|
||||
resource_type=message_field.Resource.SHARE_REPLICA,
|
||||
resource_id=share_replica['id'],
|
||||
detail=message_field.Detail.NO_ACTIVE_REPLICA)
|
||||
raise exception.ReplicationException(
|
||||
reason=msg % {'share': share_replica['share_id'],
|
||||
'state': constants.REPLICA_STATE_ACTIVE,
|
||||
|
@ -1966,7 +2039,7 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
context, replica_list, share_replica, access_rules,
|
||||
share_server=share_server)
|
||||
)
|
||||
except Exception:
|
||||
except Exception as excep:
|
||||
with excutils.save_and_reraise_exception():
|
||||
# (NOTE) gouthamr: If the driver throws an exception at
|
||||
# this stage, there is a good chance that the replicas are
|
||||
|
@ -1981,6 +2054,13 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
for replica_ref in replica_list:
|
||||
self.db.share_replica_update(
|
||||
context, replica_ref['id'], updates)
|
||||
self.message_api.create(
|
||||
context,
|
||||
message_field.Action.PROMOTE,
|
||||
replica_ref['project_id'],
|
||||
resource_type=message_field.Resource.SHARE_REPLICA,
|
||||
resource_id=replica_ref['id'],
|
||||
exception=excep)
|
||||
|
||||
# Set any 'creating' snapshots on the currently active replica to
|
||||
# 'error' since we cannot guarantee they will finish 'creating'.
|
||||
|
@ -2145,7 +2225,7 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
replica_state = self.driver.update_replica_state(
|
||||
context, replica_list, share_replica, access_rules,
|
||||
available_share_snapshots, share_server=share_server)
|
||||
except Exception:
|
||||
except Exception as excep:
|
||||
msg = ("Driver error when updating replica "
|
||||
"state for replica %s.")
|
||||
LOG.exception(msg, share_replica['id'])
|
||||
|
@ -2153,6 +2233,13 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
context, share_replica['id'],
|
||||
{'replica_state': constants.STATUS_ERROR,
|
||||
'status': constants.STATUS_ERROR})
|
||||
self.message_api.create(
|
||||
context,
|
||||
message_field.Action.UPDATE,
|
||||
share_replica['project_id'],
|
||||
resource_type=message_field.Resource.SHARE_REPLICA,
|
||||
resource_id=share_replica['id'],
|
||||
exception=excep)
|
||||
return
|
||||
|
||||
if replica_state in (constants.REPLICA_STATE_IN_SYNC,
|
||||
|
@ -2510,7 +2597,7 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
snapshot_instance_dict,
|
||||
access_rules,
|
||||
share_server=share_server)
|
||||
except Exception:
|
||||
except Exception as excep:
|
||||
with excutils.save_and_reraise_exception():
|
||||
|
||||
msg = ('Share %(share)s could not be reverted '
|
||||
|
@ -2529,6 +2616,13 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
self.db.share_snapshot_update(
|
||||
context, snapshot_id,
|
||||
{'status': constants.STATUS_AVAILABLE})
|
||||
self.message_api.create(
|
||||
context,
|
||||
message_field.Action.REVERT_TO_SNAPSHOT,
|
||||
share['project_id'],
|
||||
resource_type=message_field.Resource.SHARE,
|
||||
resource_id=share_id,
|
||||
exception=excep)
|
||||
|
||||
if reservations:
|
||||
QUOTAS.commit(
|
||||
|
@ -2568,7 +2662,7 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
except exception.ShareResourceNotFound:
|
||||
LOG.warning("Share instance %s does not exist in the "
|
||||
"backend.", share_instance_id)
|
||||
except Exception:
|
||||
except Exception as excep:
|
||||
with excutils.save_and_reraise_exception() as exc_context:
|
||||
if force:
|
||||
msg = ("The driver was unable to delete access rules "
|
||||
|
@ -2581,6 +2675,13 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
context,
|
||||
share_instance_id,
|
||||
{'status': constants.STATUS_ERROR_DELETING})
|
||||
self.message_api.create(
|
||||
context,
|
||||
message_field.Action.DELETE_ACCESS_RULES,
|
||||
share_instance['project_id'],
|
||||
resource_type=message_field.Resource.SHARE,
|
||||
resource_id=share_instance_id,
|
||||
exception=excep)
|
||||
|
||||
try:
|
||||
self.driver.delete_share(context, share_instance,
|
||||
|
@ -2588,7 +2689,7 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
except exception.ShareResourceNotFound:
|
||||
LOG.warning("Share instance %s does not exist in the "
|
||||
"backend.", share_instance_id)
|
||||
except Exception:
|
||||
except Exception as excep:
|
||||
with excutils.save_and_reraise_exception() as exc_context:
|
||||
if force:
|
||||
msg = ("The driver was unable to delete the share "
|
||||
|
@ -2603,6 +2704,13 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
context,
|
||||
share_instance_id,
|
||||
{'status': constants.STATUS_ERROR_DELETING})
|
||||
self.message_api.create(
|
||||
context,
|
||||
message_field.Action.DELETE,
|
||||
share_instance['project_id'],
|
||||
resource_type=message_field.Resource.SHARE,
|
||||
resource_id=share_instance_id,
|
||||
exception=excep)
|
||||
|
||||
self.db.share_instance_delete(context, share_instance_id)
|
||||
LOG.info("Share instance %s: deleted successfully.",
|
||||
|
@ -2658,12 +2766,19 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
model_update = self.driver.create_snapshot(
|
||||
context, snapshot_instance, share_server=share_server) or {}
|
||||
|
||||
except Exception:
|
||||
except Exception as excep:
|
||||
with excutils.save_and_reraise_exception():
|
||||
self.db.share_snapshot_instance_update(
|
||||
context,
|
||||
snapshot_instance_id,
|
||||
{'status': constants.STATUS_ERROR})
|
||||
self.message_api.create(
|
||||
context,
|
||||
message_field.Action.CREATE,
|
||||
snapshot_ref['project_id'],
|
||||
resource_type=message_field.Resource.SHARE_SNAPSHOT,
|
||||
resource_id=snapshot_instance_id,
|
||||
exception=excep)
|
||||
|
||||
snapshot_export_locations = model_update.pop('export_locations', [])
|
||||
|
||||
|
@ -2725,7 +2840,7 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
try:
|
||||
self.driver.delete_snapshot(context, snapshot_instance,
|
||||
share_server=share_server)
|
||||
except Exception:
|
||||
except Exception as excep:
|
||||
with excutils.save_and_reraise_exception() as exc:
|
||||
if force:
|
||||
msg = _("The driver was unable to delete the "
|
||||
|
@ -2740,6 +2855,13 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
context,
|
||||
snapshot_instance_id,
|
||||
{'status': constants.STATUS_ERROR_DELETING})
|
||||
self.message_api.create(
|
||||
context,
|
||||
message_field.Action.DELETE,
|
||||
snapshot_ref['project_id'],
|
||||
resource_type=message_field.Resource.SHARE_SNAPSHOT,
|
||||
resource_id=snapshot_instance_id,
|
||||
exception=excep)
|
||||
|
||||
self.db.share_snapshot_instance_delete(context, snapshot_instance_id)
|
||||
|
||||
|
@ -3514,6 +3636,13 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
self.db.share_group_update(
|
||||
context, share_group_id,
|
||||
{'status': constants.STATUS_ERROR})
|
||||
self.message_api.create(
|
||||
context,
|
||||
message_field.Action.CREATE,
|
||||
share_group_ref['project_id'],
|
||||
resource_type=message_field.Resource.SHARE_GROUP,
|
||||
resource_id=share_group_id,
|
||||
detail=message_field.Detail.NO_SHARE_SERVER)
|
||||
|
||||
try:
|
||||
# TODO(ameade): Add notification for create.start
|
||||
|
|
|
@ -32,6 +32,7 @@ from manila.data import rpcapi as data_rpc
|
|||
from manila import db
|
||||
from manila.db.sqlalchemy import models
|
||||
from manila import exception
|
||||
from manila.message import message_field
|
||||
from manila import quota
|
||||
from manila.share import api
|
||||
from manila.share import drivers_private_data
|
||||
|
@ -96,6 +97,7 @@ class ShareManagerTestCase(test.TestCase):
|
|||
self.share_manager.driver._stats = {
|
||||
'share_group_stats': {'consistent_snapshot_support': None},
|
||||
}
|
||||
self.mock_object(self.share_manager.message_api, 'create')
|
||||
self.context = context.get_admin_context()
|
||||
self.share_manager.driver.initialized = True
|
||||
mock.patch.object(
|
||||
|
@ -584,6 +586,13 @@ class ShareManagerTestCase(test.TestCase):
|
|||
mock.ANY, replica['id'], {'status': constants.STATUS_ERROR,
|
||||
'replica_state': constants.STATUS_ERROR})
|
||||
self.assertFalse(mock_driver_replica_call.called)
|
||||
self.share_manager.message_api.create.assert_called_once_with(
|
||||
utils.IsAMatcher(context.RequestContext),
|
||||
message_field.Action.CREATE,
|
||||
replica['project_id'],
|
||||
resource_type=message_field.Resource.SHARE_REPLICA,
|
||||
resource_id=replica['id'],
|
||||
detail=message_field.Detail.NO_ACTIVE_REPLICA)
|
||||
|
||||
def test_create_share_replica_with_share_network_id_and_not_dhss(self):
|
||||
replica = fake_replica()
|
||||
|
@ -605,6 +614,13 @@ class ShareManagerTestCase(test.TestCase):
|
|||
mock.ANY, replica['id'], {'status': constants.STATUS_ERROR,
|
||||
'replica_state': constants.STATUS_ERROR})
|
||||
self.assertFalse(mock_driver_replica_call.called)
|
||||
self.share_manager.message_api.create.assert_called_once_with(
|
||||
utils.IsAMatcher(context.RequestContext),
|
||||
message_field.Action.CREATE,
|
||||
replica['project_id'],
|
||||
resource_type=message_field.Resource.SHARE_REPLICA,
|
||||
resource_id=replica['id'],
|
||||
detail=message_field.Detail.UNEXPECTED_NETWORK)
|
||||
|
||||
def test_create_share_replica_with_share_server_exception(self):
|
||||
replica = fake_replica()
|
||||
|
@ -626,6 +642,13 @@ class ShareManagerTestCase(test.TestCase):
|
|||
mock.ANY, replica['id'], {'status': constants.STATUS_ERROR,
|
||||
'replica_state': constants.STATUS_ERROR})
|
||||
self.assertFalse(mock_driver_replica_call.called)
|
||||
self.share_manager.message_api.create.assert_called_once_with(
|
||||
utils.IsAMatcher(context.RequestContext),
|
||||
message_field.Action.CREATE,
|
||||
replica['project_id'],
|
||||
resource_type=message_field.Resource.SHARE_REPLICA,
|
||||
resource_id=replica['id'],
|
||||
detail=message_field.Detail.NO_SHARE_SERVER)
|
||||
|
||||
def test_create_share_replica_driver_error_on_creation(self):
|
||||
fake_access_rules = [{'id': '1'}, {'id': '2'}, {'id': '3'}]
|
||||
|
@ -676,6 +699,13 @@ class ShareManagerTestCase(test.TestCase):
|
|||
self.assertTrue(mock_log_error.called)
|
||||
self.assertFalse(mock_log_info.called)
|
||||
self.assertTrue(driver_call.called)
|
||||
self.share_manager.message_api.create.assert_called_once_with(
|
||||
utils.IsAMatcher(context.RequestContext),
|
||||
message_field.Action.CREATE,
|
||||
replica['project_id'],
|
||||
resource_type=message_field.Resource.SHARE_REPLICA,
|
||||
resource_id=replica['id'],
|
||||
exception=mock.ANY)
|
||||
|
||||
def test_create_share_replica_invalid_locations_state(self):
|
||||
driver_retval = {
|
||||
|
@ -896,6 +926,13 @@ class ShareManagerTestCase(test.TestCase):
|
|||
self.assertFalse(mock_drv_delete_replica_call.called)
|
||||
self.assertFalse(mock_replica_delete_call.called)
|
||||
self.assertFalse(mock_exception_log.called)
|
||||
self.share_manager.message_api.create.assert_called_once_with(
|
||||
utils.IsAMatcher(context.RequestContext),
|
||||
message_field.Action.DELETE_ACCESS_RULES,
|
||||
replica['project_id'],
|
||||
resource_type=message_field.Resource.SHARE_REPLICA,
|
||||
resource_id=replica['id'],
|
||||
exception=mock.ANY)
|
||||
|
||||
def test_delete_share_replica_drv_misbehavior_ignored_with_the_force(self):
|
||||
replica = fake_replica()
|
||||
|
@ -1097,6 +1134,18 @@ class ShareManagerTestCase(test.TestCase):
|
|||
mock_replica_update.assert_has_calls(expected_update_calls)
|
||||
self.assertFalse(mock_info_log.called)
|
||||
|
||||
expected_message_calls = [
|
||||
mock.call(
|
||||
utils.IsAMatcher(context.RequestContext),
|
||||
message_field.Action.PROMOTE,
|
||||
r['project_id'],
|
||||
resource_type=message_field.Resource.SHARE_REPLICA,
|
||||
resource_id=r['id'],
|
||||
exception=mock.ANY)
|
||||
for r in (replica, active_replica)]
|
||||
self.share_manager.message_api.create.assert_has_calls(
|
||||
expected_message_calls)
|
||||
|
||||
@ddt.data([], None)
|
||||
def test_promote_share_replica_driver_update_nothing_has_snaps(self,
|
||||
retval):
|
||||
|
@ -1288,6 +1337,13 @@ class ShareManagerTestCase(test.TestCase):
|
|||
'status': constants.STATUS_ERROR}
|
||||
)
|
||||
self.assertEqual(1, mock_debug_log.call_count)
|
||||
self.share_manager.message_api.create.assert_called_once_with(
|
||||
utils.IsAMatcher(context.RequestContext),
|
||||
message_field.Action.UPDATE,
|
||||
replica['project_id'],
|
||||
resource_type=message_field.Resource.SHARE_REPLICA,
|
||||
resource_id=replica['id'],
|
||||
exception=mock.ANY)
|
||||
|
||||
def test__share_replica_update_driver_exception_ignored(self):
|
||||
mock_debug_log = self.mock_object(manager.LOG, 'debug')
|
||||
|
@ -1314,6 +1370,13 @@ class ShareManagerTestCase(test.TestCase):
|
|||
'status': constants.STATUS_ERROR}
|
||||
)
|
||||
self.assertEqual(1, mock_debug_log.call_count)
|
||||
self.share_manager.message_api.create.assert_called_once_with(
|
||||
utils.IsAMatcher(context.RequestContext),
|
||||
message_field.Action.UPDATE,
|
||||
replica['project_id'],
|
||||
resource_type=message_field.Resource.SHARE_REPLICA,
|
||||
resource_id=replica['id'],
|
||||
exception=mock.ANY)
|
||||
|
||||
@ddt.data({'status': constants.STATUS_AVAILABLE,
|
||||
'replica_state': constants.REPLICA_STATE_ACTIVE, },
|
||||
|
@ -1487,6 +1550,13 @@ class ShareManagerTestCase(test.TestCase):
|
|||
|
||||
self.share_manager.driver.create_snapshot.assert_called_once_with(
|
||||
self.context, expected_snapshot_instance_dict, share_server=None)
|
||||
self.share_manager.message_api.create.assert_called_once_with(
|
||||
utils.IsAMatcher(context.RequestContext),
|
||||
message_field.Action.CREATE,
|
||||
snapshot['project_id'],
|
||||
resource_type=message_field.Resource.SHARE_SNAPSHOT,
|
||||
resource_id=snapshot_instance['id'],
|
||||
exception=mock.ANY)
|
||||
|
||||
@ddt.data({'model_update': {}, 'mount_snapshot_support': True},
|
||||
{'model_update': {}, 'mount_snapshot_support': False},
|
||||
|
@ -1601,6 +1671,13 @@ class ShareManagerTestCase(test.TestCase):
|
|||
snapshot_instance['id'], delete_all_rules=True, share_server=None)
|
||||
self.assertFalse(db_destroy_call.called)
|
||||
self.assertFalse(mock_exception_log.called)
|
||||
self.share_manager.message_api.create.assert_called_once_with(
|
||||
utils.IsAMatcher(context.RequestContext),
|
||||
message_field.Action.DELETE,
|
||||
snapshot['project_id'],
|
||||
resource_type=message_field.Resource.SHARE_SNAPSHOT,
|
||||
resource_id=snapshot_instance['id'],
|
||||
exception=mock.ANY)
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_delete_snapshot_with_quota_error(self, quota_error):
|
||||
|
@ -1695,6 +1772,13 @@ class ShareManagerTestCase(test.TestCase):
|
|||
mock.ANY, snapshot_instance['id'])
|
||||
self.assertFalse(quota_commit_call.called)
|
||||
self.assertFalse(db_update_call.called)
|
||||
self.share_manager.message_api.create.assert_called_once_with(
|
||||
utils.IsAMatcher(context.RequestContext),
|
||||
message_field.Action.DELETE,
|
||||
snapshot['project_id'],
|
||||
resource_type=message_field.Resource.SHARE_SNAPSHOT,
|
||||
resource_id=snapshot_instance['id'],
|
||||
exception=mock.ANY)
|
||||
|
||||
def test_create_share_instance_with_share_network_dhss_false(self):
|
||||
manager.CONF.set_default('driver_handles_share_servers', False)
|
||||
|
@ -1702,8 +1786,8 @@ class ShareManagerTestCase(test.TestCase):
|
|||
self.share_manager.driver.configuration, 'safe_get',
|
||||
mock.Mock(return_value=False))
|
||||
share_network_id = 'fake_sn'
|
||||
share_instance = db_utils.create_share(
|
||||
share_network_id=share_network_id).instance
|
||||
share = db_utils.create_share(share_network_id=share_network_id)
|
||||
share_instance = share.instance
|
||||
self.mock_object(
|
||||
self.share_manager.db, 'share_instance_get',
|
||||
mock.Mock(return_value=share_instance))
|
||||
|
@ -1722,6 +1806,13 @@ class ShareManagerTestCase(test.TestCase):
|
|||
self.share_manager.db.share_instance_update.assert_called_once_with(
|
||||
utils.IsAMatcher(context.RequestContext), share_instance['id'],
|
||||
{'status': constants.STATUS_ERROR})
|
||||
self.share_manager.message_api.create.assert_called_once_with(
|
||||
utils.IsAMatcher(context.RequestContext),
|
||||
message_field.Action.CREATE,
|
||||
six.text_type(share.project_id),
|
||||
resource_type=message_field.Resource.SHARE,
|
||||
resource_id=share['id'],
|
||||
detail=mock.ANY)
|
||||
|
||||
def test_create_share_instance_with_share_network_server_not_exists(self):
|
||||
"""Test share can be created without share server."""
|
||||
|
@ -1800,6 +1891,13 @@ class ShareManagerTestCase(test.TestCase):
|
|||
metadata={'request_host': 'fake_host'})
|
||||
manager.LOG.error.assert_called_with(mock.ANY,
|
||||
fake_share.instance['id'])
|
||||
self.share_manager.message_api.create.assert_called_once_with(
|
||||
utils.IsAMatcher(context.RequestContext),
|
||||
message_field.Action.CREATE,
|
||||
six.text_type(fake_share.project_id),
|
||||
resource_type=message_field.Resource.SHARE,
|
||||
resource_id=fake_share['id'],
|
||||
detail=message_field.Detail.NO_SHARE_SERVER)
|
||||
|
||||
def test_create_share_instance_with_share_network_not_found(self):
|
||||
"""Test creation fails if share network not found."""
|
||||
|
@ -1817,6 +1915,13 @@ class ShareManagerTestCase(test.TestCase):
|
|||
manager.LOG.error.assert_called_with(mock.ANY, share.instance['id'])
|
||||
shr = db.share_get(self.context, share_id)
|
||||
self.assertEqual(constants.STATUS_ERROR, shr['status'])
|
||||
self.share_manager.message_api.create.assert_called_once_with(
|
||||
utils.IsAMatcher(context.RequestContext),
|
||||
message_field.Action.CREATE,
|
||||
six.text_type(shr.project_id),
|
||||
resource_type=message_field.Resource.SHARE,
|
||||
resource_id=shr['id'],
|
||||
detail=message_field.Detail.NO_SHARE_SERVER)
|
||||
|
||||
def test_create_share_instance_with_share_network_server_exists(self):
|
||||
"""Test share can be created with existing share server."""
|
||||
|
@ -1865,6 +1970,13 @@ class ShareManagerTestCase(test.TestCase):
|
|||
self.assertTrue(self.share_manager.driver.create_share.called)
|
||||
shr = db.share_get(self.context, share_id)
|
||||
self.assertEqual(some_data, shr['export_location'])
|
||||
self.share_manager.message_api.create.assert_called_once_with(
|
||||
utils.IsAMatcher(context.RequestContext),
|
||||
message_field.Action.CREATE,
|
||||
six.text_type(share.project_id),
|
||||
resource_type=message_field.Resource.SHARE,
|
||||
resource_id=share['id'],
|
||||
exception=mock.ANY)
|
||||
|
||||
def test_create_share_instance_with_server_created(self):
|
||||
"""Test share can be created and share server is created."""
|
||||
|
|
Loading…
Reference in New Issue