Merge "Fix share manager to save data after driver error"

This commit is contained in:
Jenkins 2014-11-13 05:18:49 +00:00 committed by Gerrit Code Review
commit a2b175719b
3 changed files with 149 additions and 3 deletions

View File

@ -71,8 +71,9 @@ class ManilaException(Exception):
headers = {}
safe = False
def __init__(self, message=None, **kwargs):
def __init__(self, message=None, detail_data={}, **kwargs):
self.kwargs = kwargs
self.detail_data = detail_data
if 'code' not in self.kwargs:
try:

View File

@ -30,6 +30,7 @@ from manila import context
from manila import exception
from manila.i18n import _LE
from manila.i18n import _LI
from manila.i18n import _LW
from manila import manager
from manila import network
from manila.openstack.common import log as logging
@ -242,9 +243,20 @@ class ShareManager(manager.SchedulerDependentManager):
context, share_ref, share_server=share_server)
self.db.share_update(context, share_id,
{'export_location': export_location})
except Exception:
except Exception as e:
with excutils.save_and_reraise_exception():
LOG.error(_LE("Share %s failed on creation."), share_id)
detail_data = getattr(e, 'detail_data', {})
if (isinstance(detail_data, dict) and
detail_data.get('export_location')):
self.db.share_update(
context, share_id,
{'export_location': detail_data['export_location']})
else:
LOG.warning(_LW('Share information in exception '
'can not be written to db because it '
'contains %s and it is not a dictionary.'),
detail_data)
self.db.share_update(context, share_id, {'status': 'error'})
else:
LOG.info(_LI("Share created successfully."))
@ -447,8 +459,23 @@ class ShareManager(manager.SchedulerDependentManager):
return self.db.share_server_update(
context, share_server['id'],
{'status': constants.STATUS_ACTIVE})
except Exception:
except Exception as e:
with excutils.save_and_reraise_exception():
detail_data = getattr(e, 'detail_data', {})
if (type(detail_data) is dict and
detail_data.get('server_details')):
server_details = detail_data['server_details']
if isinstance(server_details, dict):
self.db.share_server_backend_details_set(
context, share_server['id'], server_details)
else:
LOG.warning(_LW('Server Information in '
'exception can not be written to db '
'because it contains %s and it is not '
'a dictionary.'), server_details)
self.db.share_server_update(context, share_server['id'],
{'status': constants.STATUS_ERROR})
self.network_api.deallocate_network(context, share_network)

View File

@ -566,6 +566,25 @@ class ShareManagerTestCase(test.TestCase):
self.assertEqual(shr['status'], 'available')
self.assertEqual(shr['share_server_id'], share_srv['id'])
def test_create_share_with_error_in_driver(self):
"""Test db updates if share creation fails in driver."""
share = self._create_share()
share_id = share['id']
some_data = 'fake_location'
self.share_manager.driver = mock.Mock()
e = exception.ManilaException(
detail_data={'export_location': some_data})
self.share_manager.driver.create_share.side_effect = e
self.assertRaises(
exception.ManilaException,
self.share_manager.create_share,
self.context,
share_id
)
self.assertTrue(self.share_manager.driver.create_share.called)
shr = db.share_get(self.context, share_id)
self.assertEqual(some_data, shr['export_location'])
def test_create_share_with_server_created(self):
"""Test share can be created and share server is created."""
share_net = self._create_share_network()
@ -951,3 +970,102 @@ class ShareManagerTestCase(test.TestCase):
context, share_server['id'], {'status': constants.STATUS_ERROR})
self.share_manager.network_api.deallocate_network.\
assert_called_once_with(context, share_network)
def test_setup_server_exception_in_driver(self):
# Setup required test data
context = "fake_context"
share_server = {
'id': 'fake_id',
'share_network_id': 'fake_sn_id',
}
share_network = {'id': 'fake_sn_id'}
server_info = {'details_key': 'value'}
network_info = {'fake_network_info_key': 'fake_network_info_value'}
allocation_number = 0
# Mock required parameters
self.stubs.Set(self.share_manager.db, 'share_network_get',
mock.Mock(return_value=share_network))
self.stubs.Set(self.share_manager.driver,
'get_network_allocations_number',
mock.Mock(return_value=allocation_number))
self.stubs.Set(self.share_manager.db, 'share_server_update',
mock.Mock())
self.stubs.Set(self.share_manager.network_api, 'deallocate_network',
mock.Mock())
self.stubs.Set(self.share_manager, '_form_server_setup_info',
mock.Mock(return_value=network_info))
self.stubs.Set(self.share_manager.db,
'share_server_backend_details_set',
mock.Mock())
self.stubs.Set(self.share_manager.driver, 'setup_server',
mock.Mock(side_effect=exception.ManilaException(
detail_data={'server_details': server_info})))
# execute method _setup_server
self.assertRaises(
exception.ManilaException,
self.share_manager._setup_server,
context,
share_server,
)
self.share_manager.db.share_network_get.assert_called_once_with(
context, share_server['share_network_id'])
self.share_manager.driver.get_network_allocations_number.\
assert_called_once_with()
self.share_manager._form_server_setup_info.assert_called_once_with(
context, share_server, share_network)
self.share_manager.db.share_server_backend_details_set.\
assert_called_once_with(context, share_server['id'], server_info)
self.share_manager.db.share_server_update.assert_called_once_with(
context, share_server['id'], {'status': constants.STATUS_ERROR})
self.share_manager.network_api.deallocate_network.\
assert_called_once_with(context, share_network)
def test_setup_server_incorrect_detail_data(self):
# Setup required test data
context = "fake_context"
share_server = {
'id': 'fake_id',
'share_network_id': 'fake_sn_id',
}
share_network = {'id': 'fake_sn_id'}
network_info = {'fake_network_info_key': 'fake_network_info_value'}
allocation_number = 0
# Mock required parameters
self.stubs.Set(self.share_manager.db, 'share_network_get',
mock.Mock(return_value=share_network))
self.stubs.Set(self.share_manager.driver,
'get_network_allocations_number',
mock.Mock(return_value=allocation_number))
self.stubs.Set(self.share_manager.db, 'share_server_update',
mock.Mock())
self.stubs.Set(self.share_manager.network_api, 'deallocate_network',
mock.Mock())
self.stubs.Set(self.share_manager, '_form_server_setup_info',
mock.Mock(return_value=network_info))
self.stubs.Set(self.share_manager.db,
'share_server_backend_details_set',
mock.Mock())
self.stubs.Set(self.share_manager.driver, 'setup_server',
mock.Mock(side_effect=exception.ManilaException(
detail_data='not dictionary detail data')))
# execute method _setup_server
self.assertRaises(
exception.ManilaException,
self.share_manager._setup_server,
context,
share_server,
)
self.share_manager.db.share_network_get.assert_called_once_with(
context, share_server['share_network_id'])
self.share_manager.driver.get_network_allocations_number.\
assert_called_once_with()
self.share_manager._form_server_setup_info.assert_called_once_with(
context, share_server, share_network)
self.share_manager.db.share_server_update.assert_called_once_with(
context, share_server['id'], {'status': constants.STATUS_ERROR})
self.share_manager.network_api.deallocate_network.\
assert_called_once_with(context, share_network)