Merge "Fail manage operations if service is down"
This commit is contained in:
commit
8c847e677b
@ -112,7 +112,7 @@ class SnapshotManageTest(test.TestCase):
|
||||
@mock.patch('cinder.db.service_get')
|
||||
def test_manage_snapshot_ok(self, mock_db,
|
||||
mock_create_snapshot, mock_rpcapi):
|
||||
"""Test successful manage volume execution.
|
||||
"""Test successful manage snapshot execution.
|
||||
|
||||
Tests for correct operation when valid arguments are passed in the
|
||||
request body. We ensure that cinder.volume.api.API.manage_existing got
|
||||
@ -144,6 +144,41 @@ class SnapshotManageTest(test.TestCase):
|
||||
args = mock_rpcapi.call_args[0]
|
||||
self.assertEqual('fake_ref', args[2])
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up', return_value=True)
|
||||
@mock.patch('cinder.volume.rpcapi.VolumeAPI.manage_existing_snapshot')
|
||||
@mock.patch('cinder.volume.api.API.create_snapshot_in_db')
|
||||
@mock.patch('cinder.db.service_get')
|
||||
def test_manage_snapshot_disabled(self, mock_db, mock_create_snapshot,
|
||||
mock_rpcapi, mock_is_up):
|
||||
"""Test manage snapshot failure due to disabled service."""
|
||||
mock_db.return_value = fake_service.fake_service_obj(self._admin_ctxt,
|
||||
disabled=True)
|
||||
body = {'snapshot': {'volume_id': fake.VOLUME_ID, 'ref': 'fake_ref'}}
|
||||
res = self._get_resp_post(body)
|
||||
self.assertEqual(400, res.status_int, res)
|
||||
self.assertEqual(exception.ServiceUnavailable.message,
|
||||
res.json['badRequest']['message'])
|
||||
mock_create_snapshot.assert_not_called()
|
||||
mock_rpcapi.assert_not_called()
|
||||
mock_is_up.assert_not_called()
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up', return_value=False)
|
||||
@mock.patch('cinder.volume.rpcapi.VolumeAPI.manage_existing_snapshot')
|
||||
@mock.patch('cinder.volume.api.API.create_snapshot_in_db')
|
||||
@mock.patch('cinder.db.service_get')
|
||||
def test_manage_snapshot_is_down(self, mock_db, mock_create_snapshot,
|
||||
mock_rpcapi, mock_is_up):
|
||||
"""Test manage snapshot failure due to down service."""
|
||||
mock_db.return_value = fake_service.fake_service_obj(self._admin_ctxt)
|
||||
body = {'snapshot': {'volume_id': fake.VOLUME_ID, 'ref': 'fake_ref'}}
|
||||
res = self._get_resp_post(body)
|
||||
self.assertEqual(400, res.status_int, res)
|
||||
self.assertEqual(exception.ServiceUnavailable.message,
|
||||
res.json['badRequest']['message'])
|
||||
mock_create_snapshot.assert_not_called()
|
||||
mock_rpcapi.assert_not_called()
|
||||
self.assertTrue(mock_is_up.called)
|
||||
|
||||
def test_manage_snapshot_missing_volume_id(self):
|
||||
"""Test correct failure when volume_id is not specified."""
|
||||
body = {'snapshot': {'ref': 'fake_ref'}}
|
||||
@ -240,3 +275,24 @@ class SnapshotManageTest(test.TestCase):
|
||||
mock_api_manageable.assert_called_once_with(
|
||||
self._admin_ctxt, 'fakehost', limit=10, marker='1234', offset=4,
|
||||
sort_dirs=['asc'], sort_keys=['reference'])
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up', return_value=True)
|
||||
@mock.patch('cinder.db.service_get')
|
||||
def test_get_manageable_snapshots_disabled(self, mock_db, mock_is_up):
|
||||
mock_db.return_value = fake_service.fake_service_obj(self._admin_ctxt,
|
||||
disabled=True)
|
||||
res = self._get_resp_get('host_ok', False, True)
|
||||
self.assertEqual(400, res.status_int, res)
|
||||
self.assertEqual(exception.ServiceUnavailable.message,
|
||||
res.json['badRequest']['message'])
|
||||
mock_is_up.assert_not_called()
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up', return_value=False)
|
||||
@mock.patch('cinder.db.service_get')
|
||||
def test_get_manageable_snapshots_is_down(self, mock_db, mock_is_up):
|
||||
mock_db.return_value = fake_service.fake_service_obj(self._admin_ctxt)
|
||||
res = self._get_resp_get('host_ok', False, True)
|
||||
self.assertEqual(400, res.status_int, res)
|
||||
self.assertEqual(exception.ServiceUnavailable.message,
|
||||
res.json['badRequest']['message'])
|
||||
self.assertTrue(mock_is_up.called)
|
||||
|
@ -41,7 +41,7 @@ def app():
|
||||
return mapper
|
||||
|
||||
|
||||
def service_get_by_host_and_topic(context, host, topic):
|
||||
def service_get(context, host, binary):
|
||||
"""Replacement for Service.service_get_by_host_and_topic.
|
||||
|
||||
We mock the Service.service_get_by_host_and_topic method to return
|
||||
@ -50,7 +50,9 @@ def service_get_by_host_and_topic(context, host, topic):
|
||||
check for existence of a host, so the content returned doesn't matter.
|
||||
"""
|
||||
if host == 'host_ok':
|
||||
return {}
|
||||
return {'disabled': False}
|
||||
if host == 'host_disabled':
|
||||
return {'disabled': True}
|
||||
raise exception.ServiceNotFound(service_id=host)
|
||||
|
||||
# Some of the tests check that volume types are correctly validated during a
|
||||
@ -128,8 +130,7 @@ def api_get_manageable_volumes(*args, **kwargs):
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@mock.patch('cinder.objects.service.Service.get_by_host_and_topic',
|
||||
service_get_by_host_and_topic)
|
||||
@mock.patch('cinder.db.service_get', service_get)
|
||||
@mock.patch('cinder.volume.volume_types.get_volume_type_by_name',
|
||||
vt_get_volume_type_by_name)
|
||||
@mock.patch('cinder.volume.volume_types.get_volume_type',
|
||||
@ -210,6 +211,26 @@ class VolumeManageTest(test.TestCase):
|
||||
res = self._get_resp_post(body)
|
||||
self.assertEqual(400, res.status_int)
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up', return_value=True)
|
||||
def test_manage_volume_disabled(self, mock_is_up):
|
||||
"""Test manage volume failure due to disabled service."""
|
||||
body = {'volume': {'host': 'host_disabled', 'ref': 'fake_ref'}}
|
||||
res = self._get_resp_post(body)
|
||||
self.assertEqual(400, res.status_int, res)
|
||||
self.assertEqual(exception.ServiceUnavailable.message,
|
||||
res.json['badRequest']['message'])
|
||||
mock_is_up.assert_not_called()
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up', return_value=False)
|
||||
def test_manage_volume_is_down(self, mock_is_up):
|
||||
"""Test manage volume failure due to down service."""
|
||||
body = {'volume': {'host': 'host_ok', 'ref': 'fake_ref'}}
|
||||
res = self._get_resp_post(body)
|
||||
self.assertEqual(400, res.status_int, res)
|
||||
self.assertEqual(exception.ServiceUnavailable.message,
|
||||
res.json['badRequest']['message'])
|
||||
self.assertTrue(mock_is_up.called)
|
||||
|
||||
@mock.patch('cinder.volume.api.API.manage_existing', api_manage)
|
||||
@mock.patch(
|
||||
'cinder.api.openstack.wsgi.Controller.validate_name_and_description')
|
||||
@ -335,3 +356,19 @@ class VolumeManageTest(test.TestCase):
|
||||
"metadata": value}}
|
||||
res = self._get_resp_post(body)
|
||||
self.assertEqual(400, res.status_int)
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up', return_value=True)
|
||||
def test_get_manageable_volumes_disabled(self, mock_is_up):
|
||||
res = self._get_resp_get('host_disabled', False, True)
|
||||
self.assertEqual(400, res.status_int, res)
|
||||
self.assertEqual(exception.ServiceUnavailable.message,
|
||||
res.json['badRequest']['message'])
|
||||
mock_is_up.assert_not_called()
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up', return_value=False)
|
||||
def test_get_manageable_volumes_is_down(self, mock_is_up):
|
||||
res = self._get_resp_get('host_ok', False, True)
|
||||
self.assertEqual(400, res.status_int, res)
|
||||
self.assertEqual(exception.ServiceUnavailable.message,
|
||||
res.json['badRequest']['message'])
|
||||
self.assertTrue(mock_is_up.called)
|
||||
|
@ -37,7 +37,7 @@ def app():
|
||||
|
||||
|
||||
@mock.patch('cinder.objects.service.Service.get_by_host_and_topic',
|
||||
test_contrib.service_get_by_host_and_topic)
|
||||
test_contrib.service_get)
|
||||
@mock.patch('cinder.volume.volume_types.get_volume_type_by_name',
|
||||
test_contrib.vt_get_volume_type_by_name)
|
||||
@mock.patch('cinder.volume.volume_types.get_volume_type',
|
||||
|
@ -1485,6 +1485,11 @@ class API(base.Base):
|
||||
'service.'), resource)
|
||||
raise exception.ServiceUnavailable()
|
||||
|
||||
if not utils.service_is_up(service):
|
||||
LOG.error(_LE('Unable to manage existing %s on a service that is '
|
||||
'down.'), resource)
|
||||
raise exception.ServiceUnavailable()
|
||||
|
||||
return service
|
||||
|
||||
def manage_existing(self, context, host, ref, name=None, description=None,
|
||||
|
Loading…
x
Reference in New Issue
Block a user