Merge "Remove generic exception catching for admin_actions API v3"
This commit is contained in:
commit
6535376c78
@ -13,7 +13,6 @@
|
||||
# under the License.
|
||||
|
||||
import os.path
|
||||
import traceback
|
||||
|
||||
import webob
|
||||
from webob import exc
|
||||
@ -44,6 +43,7 @@ class AdminActionsController(wsgi.Controller):
|
||||
super(AdminActionsController, self).__init__(*args, **kwargs)
|
||||
self.compute_api = compute.API()
|
||||
|
||||
@extensions.expected_errors((404, 409))
|
||||
@wsgi.action('pause')
|
||||
def _pause(self, req, id, body):
|
||||
"""Permit Admins to pause the server."""
|
||||
@ -55,12 +55,13 @@ class AdminActionsController(wsgi.Controller):
|
||||
except exception.InstanceInvalidState as state_error:
|
||||
common.raise_http_conflict_for_instance_invalid_state(state_error,
|
||||
'pause')
|
||||
except Exception:
|
||||
readable = traceback.format_exc()
|
||||
LOG.exception(_("Compute.api::pause %s"), readable)
|
||||
raise exc.HTTPUnprocessableEntity()
|
||||
except exception.InstanceIsLocked as e:
|
||||
raise exc.HTTPConflict(explanation=e.format_message())
|
||||
except exception.InstanceNotFound as e:
|
||||
raise exc.HTTPNotFound(explanation=e.format_message())
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@extensions.expected_errors((404, 409))
|
||||
@wsgi.action('unpause')
|
||||
def _unpause(self, req, id, body):
|
||||
"""Permit Admins to unpause the server."""
|
||||
@ -72,12 +73,13 @@ class AdminActionsController(wsgi.Controller):
|
||||
except exception.InstanceInvalidState as state_error:
|
||||
common.raise_http_conflict_for_instance_invalid_state(state_error,
|
||||
'unpause')
|
||||
except Exception:
|
||||
readable = traceback.format_exc()
|
||||
LOG.exception(_("Compute.api::unpause %s"), readable)
|
||||
raise exc.HTTPUnprocessableEntity()
|
||||
except exception.InstanceNotFound as e:
|
||||
raise exc.HTTPNotFound(explanation=e.format_message())
|
||||
except exception.InstanceIsLocked as e:
|
||||
raise exc.HTTPConflict(explanation=e.format_message())
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@extensions.expected_errors((404, 409))
|
||||
@wsgi.action('suspend')
|
||||
def _suspend(self, req, id, body):
|
||||
"""Permit admins to suspend the server."""
|
||||
@ -89,12 +91,13 @@ class AdminActionsController(wsgi.Controller):
|
||||
except exception.InstanceInvalidState as state_error:
|
||||
common.raise_http_conflict_for_instance_invalid_state(state_error,
|
||||
'suspend')
|
||||
except Exception:
|
||||
readable = traceback.format_exc()
|
||||
LOG.exception(_("compute.api::suspend %s"), readable)
|
||||
raise exc.HTTPUnprocessableEntity()
|
||||
except exception.InstanceNotFound as e:
|
||||
raise exc.HTTPNotFound(explanation=e.format_message())
|
||||
except exception.InstanceIsLocked as e:
|
||||
raise exc.HTTPConflict(explanation=e.format_message())
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@extensions.expected_errors((404, 409))
|
||||
@wsgi.action('resume')
|
||||
def _resume(self, req, id, body):
|
||||
"""Permit admins to resume the server from suspend."""
|
||||
@ -106,12 +109,13 @@ class AdminActionsController(wsgi.Controller):
|
||||
except exception.InstanceInvalidState as state_error:
|
||||
common.raise_http_conflict_for_instance_invalid_state(state_error,
|
||||
'resume')
|
||||
except Exception:
|
||||
readable = traceback.format_exc()
|
||||
LOG.exception(_("compute.api::resume %s"), readable)
|
||||
raise exc.HTTPUnprocessableEntity()
|
||||
except exception.InstanceNotFound as e:
|
||||
raise exc.HTTPNotFound(explanation=e.format_message())
|
||||
except exception.InstanceIsLocked as e:
|
||||
raise exc.HTTPConflict(explanation=e.format_message())
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@extensions.expected_errors((400, 404, 409, 413))
|
||||
@wsgi.action('migrate')
|
||||
def _migrate(self, req, id, body):
|
||||
"""Permit admins to migrate a server to a new host."""
|
||||
@ -123,11 +127,19 @@ class AdminActionsController(wsgi.Controller):
|
||||
except exception.InstanceInvalidState as state_error:
|
||||
common.raise_http_conflict_for_instance_invalid_state(state_error,
|
||||
'migrate')
|
||||
except Exception as e:
|
||||
LOG.exception(_("Error in migrate %s"), e)
|
||||
raise exc.HTTPBadRequest()
|
||||
except exception.InstanceNotFound as e:
|
||||
raise exc.HTTPNotFound(explanation=e.format_message())
|
||||
except exception.InstanceIsLocked as e:
|
||||
raise exc.HTTPConflict(explanation=e.format_message())
|
||||
except exception.FlavorNotFound as e:
|
||||
raise exc.HTTPNotFound(explanation=e.format_message())
|
||||
except exception.CannotResizeToSameFlavor as e:
|
||||
raise exc.HTTPBadRequest(explanation=e.format_message())
|
||||
except exception.TooManyInstances as e:
|
||||
raise exc.HTTPRequestEntityTooLarge(explanation=e.format_message())
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@extensions.expected_errors((404, 409))
|
||||
@wsgi.action('reset_network')
|
||||
def _reset_network(self, req, id, body):
|
||||
"""Permit admins to reset networking on a server."""
|
||||
@ -136,12 +148,13 @@ class AdminActionsController(wsgi.Controller):
|
||||
try:
|
||||
instance = self.compute_api.get(context, id)
|
||||
self.compute_api.reset_network(context, instance)
|
||||
except Exception:
|
||||
readable = traceback.format_exc()
|
||||
LOG.exception(_("Compute.api::reset_network %s"), readable)
|
||||
raise exc.HTTPUnprocessableEntity()
|
||||
except exception.InstanceNotFound as e:
|
||||
raise exc.HTTPNotFound(explanation=e.format_message())
|
||||
except exception.InstanceIsLocked as e:
|
||||
raise exc.HTTPConflict(explanation=e.format_message())
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@extensions.expected_errors((404, 409))
|
||||
@wsgi.action('inject_network_info')
|
||||
def _inject_network_info(self, req, id, body):
|
||||
"""Permit admins to inject network info into a server."""
|
||||
@ -150,14 +163,13 @@ class AdminActionsController(wsgi.Controller):
|
||||
try:
|
||||
instance = self.compute_api.get(context, id)
|
||||
self.compute_api.inject_network_info(context, instance)
|
||||
except exception.InstanceNotFound:
|
||||
raise exc.HTTPNotFound(_("Server not found"))
|
||||
except Exception:
|
||||
readable = traceback.format_exc()
|
||||
LOG.exception(_("Compute.api::inject_network_info %s"), readable)
|
||||
raise exc.HTTPUnprocessableEntity()
|
||||
except exception.InstanceNotFound as e:
|
||||
raise exc.HTTPNotFound(explanation=e.format_message())
|
||||
except exception.InstanceIsLocked as e:
|
||||
raise exc.HTTPConflict(explanation=e.format_message())
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@extensions.expected_errors(404)
|
||||
@wsgi.action('lock')
|
||||
def _lock(self, req, id, body):
|
||||
"""Permit admins to lock a server."""
|
||||
@ -166,14 +178,11 @@ class AdminActionsController(wsgi.Controller):
|
||||
try:
|
||||
instance = self.compute_api.get(context, id)
|
||||
self.compute_api.lock(context, instance)
|
||||
except exception.InstanceNotFound:
|
||||
raise exc.HTTPNotFound(_("Server not found"))
|
||||
except Exception:
|
||||
readable = traceback.format_exc()
|
||||
LOG.exception(_("Compute.api::lock %s"), readable)
|
||||
raise exc.HTTPUnprocessableEntity()
|
||||
except exception.InstanceNotFound as e:
|
||||
raise exc.HTTPNotFound(explanation=e.format_message())
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@extensions.expected_errors(404)
|
||||
@wsgi.action('unlock')
|
||||
def _unlock(self, req, id, body):
|
||||
"""Permit admins to lock a server."""
|
||||
@ -182,14 +191,11 @@ class AdminActionsController(wsgi.Controller):
|
||||
try:
|
||||
instance = self.compute_api.get(context, id)
|
||||
self.compute_api.unlock(context, instance)
|
||||
except exception.InstanceNotFound:
|
||||
raise exc.HTTPNotFound(_("Server not found"))
|
||||
except Exception:
|
||||
readable = traceback.format_exc()
|
||||
LOG.exception(_("Compute.api::unlock %s"), readable)
|
||||
raise exc.HTTPUnprocessableEntity()
|
||||
except exception.InstanceNotFound as e:
|
||||
raise exc.HTTPNotFound(explanation=e.format_message())
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@extensions.expected_errors((400, 404, 409, 413))
|
||||
@wsgi.action('create_backup')
|
||||
def _create_backup(self, req, id, body):
|
||||
"""Backup a server instance.
|
||||
@ -244,8 +250,8 @@ class AdminActionsController(wsgi.Controller):
|
||||
|
||||
try:
|
||||
instance = self.compute_api.get(context, id)
|
||||
except exception.NotFound:
|
||||
raise exc.HTTPNotFound(_("Instance not found"))
|
||||
except exception.InstanceNotFound as e:
|
||||
raise exc.HTTPNotFound(explanation=e.format_message())
|
||||
|
||||
try:
|
||||
image = self.compute_api.backup(context, instance, image_name,
|
||||
@ -264,6 +270,7 @@ class AdminActionsController(wsgi.Controller):
|
||||
|
||||
return resp
|
||||
|
||||
@extensions.expected_errors((400, 404, 409))
|
||||
@wsgi.action('migrate_live')
|
||||
def _migrate_live(self, req, id, body):
|
||||
"""Permit admins to (live) migrate a server to a new host."""
|
||||
@ -286,21 +293,20 @@ class AdminActionsController(wsgi.Controller):
|
||||
except (exception.ComputeServiceUnavailable,
|
||||
exception.InvalidHypervisorType,
|
||||
exception.UnableToMigrateToSelf,
|
||||
exception.DestinationHypervisorTooOld) as ex:
|
||||
exception.DestinationHypervisorTooOld,
|
||||
exception.NoValidHost,
|
||||
exception.InvalidLocalStorage,
|
||||
exception.InvalidSharedStorage,
|
||||
exception.MigrationPreCheckError) as ex:
|
||||
raise exc.HTTPBadRequest(explanation=ex.format_message())
|
||||
except Exception:
|
||||
if host is None:
|
||||
msg = _("Live migration of instance %s to another host "
|
||||
"failed") % id
|
||||
else:
|
||||
msg = _("Live migration of instance %(id)s to host %(host)s "
|
||||
"failed") % {'id': id, 'host': host}
|
||||
LOG.exception(msg)
|
||||
# Return messages from scheduler
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
except exception.InstanceInvalidState as state_error:
|
||||
common.raise_http_conflict_for_instance_invalid_state(state_error,
|
||||
'migrate_live')
|
||||
except exception.InstanceNotFound as e:
|
||||
raise exc.HTTPNotFound(explanation=e.format_message())
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@extensions.expected_errors((400, 404))
|
||||
@wsgi.action('reset_state')
|
||||
def _reset_state(self, req, id, body):
|
||||
"""Permit admins to reset the state of a server."""
|
||||
@ -320,12 +326,8 @@ class AdminActionsController(wsgi.Controller):
|
||||
instance.vm_state = state
|
||||
instance.task_state = None
|
||||
instance.save(admin_state_reset=True)
|
||||
except exception.InstanceNotFound:
|
||||
raise exc.HTTPNotFound(_("Server not found"))
|
||||
except Exception:
|
||||
readable = traceback.format_exc()
|
||||
LOG.exception(_("Compute.api::reset_state %s"), readable)
|
||||
raise exc.HTTPUnprocessableEntity()
|
||||
except exception.InstanceNotFound as e:
|
||||
raise exc.HTTPNotFound(explanation=e.format_message())
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
|
||||
|
@ -22,7 +22,6 @@ from nova.api.openstack.compute.plugins.v3 import admin_actions
|
||||
from nova.compute import api as compute_api
|
||||
from nova.compute import vm_states
|
||||
from nova.conductor import api as conductor_api
|
||||
from nova import context
|
||||
from nova import exception
|
||||
from nova.objects import instance as instance_obj
|
||||
from nova.openstack.common import jsonutils
|
||||
@ -73,6 +72,29 @@ def fake_compute_api_get(self, context, instance_uuid, want_objects=False):
|
||||
return instance
|
||||
|
||||
|
||||
def fake_compute_api_get_non_found(self, context, instance_id,
|
||||
want_objects=False):
|
||||
raise exception.InstanceNotFound(instance_id=instance_id)
|
||||
|
||||
|
||||
def fake_compute_api_raises_instance_is_locked(*args, **kwargs):
|
||||
raise exception.InstanceIsLocked(instance_uuid='')
|
||||
|
||||
|
||||
def fake_compute_api_resize_non_found_flavor(self, context, instance_id):
|
||||
raise exception.FlavorNotFound(flavor_id='')
|
||||
|
||||
|
||||
def fake_compute_api_can_not_resize_to_same_flavor(self, context,
|
||||
instance_id):
|
||||
raise exception.CannotResizeToSameFlavor()
|
||||
|
||||
|
||||
def fake_compute_api_too_many_instaces(self, context, instance_id):
|
||||
raise exception.TooManyInstances(overs='', req='', used=0, allowed=0,
|
||||
resource='')
|
||||
|
||||
|
||||
class AdminActionsTest(test.TestCase):
|
||||
|
||||
_actions = ('pause', 'unpause', 'suspend', 'resume', 'migrate',
|
||||
@ -89,59 +111,99 @@ class AdminActionsTest(test.TestCase):
|
||||
('resume', 'resume'),
|
||||
('migrate', 'resize'))
|
||||
|
||||
_actions_that_check_non_existed_instance = ('pause', 'unpause', 'suspend',
|
||||
'resume', 'migrate', 'reset_network', 'inject_network_info', 'lock',
|
||||
'unlock')
|
||||
|
||||
_actions_that_check_is_locked = zip(
|
||||
('pause', 'unpause', 'suspend',
|
||||
'resume', 'migrate', 'reset_network', 'inject_network_info'),
|
||||
('pause', 'unpause', 'suspend',
|
||||
'resume', 'resize', 'reset_network', 'inject_network_info'))
|
||||
|
||||
def setUp(self):
|
||||
super(AdminActionsTest, self).setUp()
|
||||
self.stubs.Set(compute_api.API, 'get', fake_compute_api_get)
|
||||
self.UUID = uuidutils.generate_uuid()
|
||||
self.app = fakes.wsgi_app_v3(init_only=('servers',
|
||||
'os-admin-actions'))
|
||||
for _method in self._methods:
|
||||
self.stubs.Set(compute_api.API, _method, fake_compute_api)
|
||||
|
||||
def _make_request(self, url, body):
|
||||
req = webob.Request.blank(url)
|
||||
req.method = 'POST'
|
||||
req.body = jsonutils.dumps(body)
|
||||
req.content_type = 'application/json'
|
||||
return req.get_response(self.app)
|
||||
|
||||
def test_admin_api_actions(self):
|
||||
app = fakes.wsgi_app_v3(init_only=('servers', 'os-admin-actions'))
|
||||
for _action in self._actions:
|
||||
req = webob.Request.blank('/v3/servers/%s/action' %
|
||||
self.UUID)
|
||||
req.method = 'POST'
|
||||
req.body = jsonutils.dumps({_action: None})
|
||||
req.content_type = 'application/json'
|
||||
res = req.get_response(app)
|
||||
res = self._make_request('/v3/servers/%s/action' % self.UUID,
|
||||
{_action: None})
|
||||
self.assertEqual(res.status_int, 202)
|
||||
|
||||
def test_admin_api_actions_raise_conflict_on_invalid_state(self):
|
||||
app = fakes.wsgi_app_v3(init_only=('servers', 'os-admin-actions'))
|
||||
|
||||
self.stubs.Set(compute_api.API, 'get', fake_compute_api_get)
|
||||
for _action, _method in self._actions_that_check_state:
|
||||
self.stubs.Set(compute_api.API, _method,
|
||||
fake_compute_api_raises_invalid_state)
|
||||
|
||||
req = webob.Request.blank('/v3/servers/%s/action' %
|
||||
self.UUID)
|
||||
req.method = 'POST'
|
||||
req.body = jsonutils.dumps({_action: None})
|
||||
req.content_type = 'application/json'
|
||||
res = req.get_response(app)
|
||||
res = self._make_request('/v3/servers/%s/action' % self.UUID,
|
||||
{_action: None})
|
||||
self.assertEqual(res.status_int, 409)
|
||||
self.assertIn("Cannot \'%(_action)s\' while instance" % locals(),
|
||||
res.body)
|
||||
|
||||
def test_migrate_live_enabled(self):
|
||||
ctxt = context.get_admin_context()
|
||||
ctxt.user_id = 'fake'
|
||||
ctxt.project_id = 'fake'
|
||||
ctxt.is_admin = True
|
||||
app = fakes.wsgi_app_v3(fake_auth_context=ctxt,
|
||||
init_only=('servers', 'os-admin-actions'))
|
||||
req = webob.Request.blank('/v3/servers/%s/action' % self.UUID)
|
||||
req.method = 'POST'
|
||||
req.body = jsonutils.dumps({
|
||||
'migrate_live': {
|
||||
'host': 'hostname',
|
||||
'block_migration': False,
|
||||
'disk_over_commit': False,
|
||||
}
|
||||
})
|
||||
req.content_type = 'application/json'
|
||||
def test_admin_api_actions_with_non_existed_instance(self):
|
||||
app = fakes.wsgi_app_v3(init_only=('servers', 'os-admin-actions'))
|
||||
self.stubs.Set(compute_api.API, 'get', fake_compute_api_get_non_found)
|
||||
for _action in self._actions_that_check_non_existed_instance:
|
||||
res = self._make_request('/v3/servers/%s/action' % self.UUID,
|
||||
{_action: None})
|
||||
self.assertEqual(res.status_int, 404)
|
||||
|
||||
def test_admin_api_actions_with_locked_instance(self):
|
||||
app = fakes.wsgi_app_v3(init_only=('servers', 'os-admin-actions'))
|
||||
for _action, _method in self._actions_that_check_is_locked:
|
||||
self.stubs.Set(compute_api.API, _method,
|
||||
fake_compute_api_raises_instance_is_locked)
|
||||
res = self._make_request('/v3/servers/%s/action' % self.UUID,
|
||||
{_action: None})
|
||||
self.assertEqual(res.status_int, 409)
|
||||
|
||||
def test_reset_state_with_non_existed_instance(self):
|
||||
app = fakes.wsgi_app_v3(init_only=('servers', 'os-admin-actions'))
|
||||
self.stubs.Set(compute_api.API, 'get', fake_compute_api_get_non_found)
|
||||
res = self._make_request('/v3/servers/%s/action' % self.UUID,
|
||||
{'reset_state': {'state': 'active'}})
|
||||
self.assertEqual(res.status_int, 404)
|
||||
|
||||
def test_migrate_with_non_existed_flavor(self):
|
||||
app = fakes.wsgi_app_v3(init_only=('servers', 'os-admin-actions'))
|
||||
self.stubs.Set(compute_api.API, 'resize',
|
||||
fake_compute_api_resize_non_found_flavor)
|
||||
res = self._make_request('/v3/servers/%s/action' % self.UUID,
|
||||
{'migrate': None})
|
||||
self.assertEqual(res.status_int, 404)
|
||||
|
||||
def test_migrate_resize_to_same_flavor(self):
|
||||
app = fakes.wsgi_app_v3(init_only=('servers', 'os-admin-actions'))
|
||||
self.stubs.Set(compute_api.API, 'resize',
|
||||
fake_compute_api_can_not_resize_to_same_flavor)
|
||||
res = self._make_request('/v3/servers/%s/action' % self.UUID,
|
||||
{'migrate': None})
|
||||
self.assertEqual(res.status_int, 400)
|
||||
|
||||
def test_migrate_too_many_instances(self):
|
||||
app = fakes.wsgi_app_v3(init_only=('servers', 'os-admin-actions'))
|
||||
self.stubs.Set(compute_api.API, 'resize',
|
||||
fake_compute_api_too_many_instaces)
|
||||
res = self._make_request('/v3/servers/%s/action' % self.UUID,
|
||||
{'migrate': None})
|
||||
self.assertEqual(res.status_int, 413)
|
||||
|
||||
def test_migrate_live_enabled(self):
|
||||
def fake_update(inst, context, instance,
|
||||
task_state, expected_task_state):
|
||||
return None
|
||||
@ -156,180 +218,99 @@ class AdminActionsTest(test.TestCase):
|
||||
'migrate_server',
|
||||
fake_migrate_server)
|
||||
|
||||
res = req.get_response(app)
|
||||
res = self._make_request('/v3/servers/%s/action' % self.UUID,
|
||||
{'migrate_live':
|
||||
{'host': 'hostname',
|
||||
'block_migration': False,
|
||||
'disk_over_commit': False}})
|
||||
self.assertEqual(res.status_int, 202)
|
||||
|
||||
def test_migrate_live_with_non_existed_instance(self):
|
||||
self.stubs.Set(compute_api.API, 'get', fake_compute_api_get_non_found)
|
||||
res = self._make_request('/v3/servers/%s/action' % self.UUID,
|
||||
{'migrate_live':
|
||||
{'host': 'hostname',
|
||||
'block_migration': False,
|
||||
'disk_over_commit': False}})
|
||||
self.assertEqual(res.status_int, 404)
|
||||
|
||||
def test_migrate_live_missing_dict_param(self):
|
||||
ctxt = context.get_admin_context()
|
||||
ctxt.user_id = 'fake'
|
||||
ctxt.project_id = 'fake'
|
||||
ctxt.is_admin = True
|
||||
app = fakes.wsgi_app_v3(fake_auth_context=ctxt,
|
||||
init_only=('servers', 'os-admin-actions'))
|
||||
req = webob.Request.blank('/v3/servers/%s/action' % self.UUID)
|
||||
req.method = 'POST'
|
||||
req.body = jsonutils.dumps({
|
||||
'migrate_live': {
|
||||
'dummy': 'hostname',
|
||||
'block_migration': False,
|
||||
'disk_over_commit': False,
|
||||
}
|
||||
})
|
||||
req.content_type = 'application/json'
|
||||
res = req.get_response(app)
|
||||
res = self._make_request('/v3/servers/%s/action' % self.UUID,
|
||||
{'migrate_live':
|
||||
{'dummy': 'hostname',
|
||||
'block_migration': False,
|
||||
'disk_over_commit': False}})
|
||||
self.assertEqual(res.status_int, 400)
|
||||
|
||||
def _test_migrate_live_failed_with_exception(self, fake_exc):
|
||||
def fake_update(inst, context, instance,
|
||||
task_state, expected_task_state):
|
||||
return None
|
||||
|
||||
def fake_migrate_server(self, context, instance,
|
||||
scheduler_hint, live, rebuild, flavor,
|
||||
block_migration, disk_over_commit):
|
||||
raise fake_exc
|
||||
|
||||
self.stubs.Set(compute_api.API, 'update', fake_update)
|
||||
self.stubs.Set(conductor_api.ComputeTaskAPI,
|
||||
'migrate_server',
|
||||
fake_migrate_server)
|
||||
|
||||
res = self._make_request('/v3/servers/%s/action' % self.UUID,
|
||||
{'migrate_live':
|
||||
{'host': 'hostname',
|
||||
'block_migration': False,
|
||||
'disk_over_commit': False}})
|
||||
self.assertEqual(res.status_int, 400)
|
||||
self.assertIn(unicode(fake_exc), res.body)
|
||||
|
||||
def test_migrate_live_compute_service_unavailable(self):
|
||||
ctxt = context.get_admin_context()
|
||||
ctxt.user_id = 'fake'
|
||||
ctxt.project_id = 'fake'
|
||||
ctxt.is_admin = True
|
||||
app = fakes.wsgi_app_v3(fake_auth_context=ctxt,
|
||||
init_only=('servers', 'os-admin-actions'))
|
||||
req = webob.Request.blank('/v3/servers/%s/action' % self.UUID)
|
||||
req.method = 'POST'
|
||||
req.body = jsonutils.dumps({
|
||||
'migrate_live': {
|
||||
'host': 'hostname',
|
||||
'block_migration': False,
|
||||
'disk_over_commit': False,
|
||||
}
|
||||
})
|
||||
req.content_type = 'application/json'
|
||||
|
||||
def fake_update(inst, context, instance,
|
||||
task_state, expected_task_state):
|
||||
return None
|
||||
|
||||
def fake_migrate_server(self, context, instance,
|
||||
scheduler_hint, live, rebuild, flavor,
|
||||
block_migration, disk_over_commit):
|
||||
raise exception.ComputeServiceUnavailable(host='host')
|
||||
|
||||
self.stubs.Set(compute_api.API, 'update', fake_update)
|
||||
self.stubs.Set(conductor_api.ComputeTaskAPI,
|
||||
'migrate_server',
|
||||
fake_migrate_server)
|
||||
|
||||
res = req.get_response(app)
|
||||
self.assertEqual(res.status_int, 400)
|
||||
self.assertIn(
|
||||
unicode(exception.ComputeServiceUnavailable(host='host')),
|
||||
res.body)
|
||||
self._test_migrate_live_failed_with_exception(
|
||||
exception.ComputeServiceUnavailable(host='host'))
|
||||
|
||||
def test_migrate_live_invalid_hypervisor_type(self):
|
||||
ctxt = context.get_admin_context()
|
||||
ctxt.user_id = 'fake'
|
||||
ctxt.project_id = 'fake'
|
||||
ctxt.is_admin = True
|
||||
app = fakes.wsgi_app_v3(fake_auth_context=ctxt,
|
||||
init_only=('servers', 'os-admin-actions'))
|
||||
req = webob.Request.blank('/v3/servers/%s/action' % self.UUID)
|
||||
req.method = 'POST'
|
||||
req.body = jsonutils.dumps({
|
||||
'migrate_live': {
|
||||
'host': 'hostname',
|
||||
'block_migration': False,
|
||||
'disk_over_commit': False,
|
||||
}
|
||||
})
|
||||
req.content_type = 'application/json'
|
||||
|
||||
def fake_update(inst, context, instance,
|
||||
task_state, expected_task_state):
|
||||
return None
|
||||
|
||||
def fake_migrate_server(self, context, instance,
|
||||
scheduler_hint, live, rebuild, flavor,
|
||||
block_migration, disk_over_commit):
|
||||
raise exception.InvalidHypervisorType()
|
||||
|
||||
self.stubs.Set(compute_api.API, 'update', fake_update)
|
||||
self.stubs.Set(conductor_api.ComputeTaskAPI,
|
||||
'migrate_server',
|
||||
fake_migrate_server)
|
||||
|
||||
res = req.get_response(app)
|
||||
self.assertEqual(res.status_int, 400)
|
||||
self.assertIn(
|
||||
unicode(exception.InvalidHypervisorType()),
|
||||
res.body)
|
||||
self._test_migrate_live_failed_with_exception(
|
||||
exception.InvalidHypervisorType())
|
||||
|
||||
def test_migrate_live_unable_to_migrate_to_self(self):
|
||||
ctxt = context.get_admin_context()
|
||||
ctxt.user_id = 'fake'
|
||||
ctxt.project_id = 'fake'
|
||||
ctxt.is_admin = True
|
||||
app = fakes.wsgi_app_v3(fake_auth_context=ctxt,
|
||||
init_only=('servers', 'os-admin-actions'))
|
||||
req = webob.Request.blank('/v3/servers/%s/action' % self.UUID)
|
||||
req.method = 'POST'
|
||||
req.body = jsonutils.dumps({
|
||||
'migrate_live': {
|
||||
'host': 'hostname',
|
||||
'block_migration': False,
|
||||
'disk_over_commit': False,
|
||||
}
|
||||
})
|
||||
req.content_type = 'application/json'
|
||||
|
||||
def fake_update(inst, context, instance,
|
||||
task_state, expected_task_state):
|
||||
return None
|
||||
|
||||
def fake_migrate_server(self, context, instance,
|
||||
scheduler_hint, live, rebuild, flavor,
|
||||
block_migration, disk_over_commit):
|
||||
raise exception.UnableToMigrateToSelf(self.UUID, host='host')
|
||||
|
||||
self.stubs.Set(compute_api.API, 'update', fake_update)
|
||||
self.stubs.Set(conductor_api.ComputeTaskAPI,
|
||||
'migrate_server',
|
||||
fake_migrate_server)
|
||||
|
||||
res = req.get_response(app)
|
||||
self.assertEqual(res.status_int, 400)
|
||||
self.assertIn(
|
||||
unicode(exception.UnableToMigrateToSelf(self.UUID, host='host')),
|
||||
res.body)
|
||||
self._test_migrate_live_failed_with_exception(
|
||||
exception.UnableToMigrateToSelf(instance_id=self.UUID,
|
||||
host='host'))
|
||||
|
||||
def test_migrate_live_destination_hypervisor_too_old(self):
|
||||
ctxt = context.get_admin_context()
|
||||
ctxt.user_id = 'fake'
|
||||
ctxt.project_id = 'fake'
|
||||
ctxt.is_admin = True
|
||||
app = fakes.wsgi_app_v3(fake_auth_context=ctxt,
|
||||
init_only=('servers', 'os-admin-actions'))
|
||||
req = webob.Request.blank('/v3/servers/%s/action' % self.UUID)
|
||||
req.method = 'POST'
|
||||
req.body = jsonutils.dumps({
|
||||
'migrate_live': {
|
||||
'host': 'hostname',
|
||||
'block_migration': False,
|
||||
'disk_over_commit': False,
|
||||
}
|
||||
})
|
||||
req.content_type = 'application/json'
|
||||
self._test_migrate_live_failed_with_exception(
|
||||
exception.DestinationHypervisorTooOld())
|
||||
|
||||
def fake_update(inst, context, instance,
|
||||
task_state, expected_task_state):
|
||||
return None
|
||||
def test_migrate_live_no_valid_host(self):
|
||||
self._test_migrate_live_failed_with_exception(
|
||||
exception.NoValidHost(reason=''))
|
||||
|
||||
def fake_migrate_server(self, context, instance,
|
||||
scheduler_hint, live, rebuild, flavor,
|
||||
block_migration, disk_over_commit):
|
||||
raise exception.DestinationHypervisorTooOld()
|
||||
def test_migrate_live_invalid_local_storage(self):
|
||||
self._test_migrate_live_failed_with_exception(
|
||||
exception.InvalidLocalStorage(path='', reason=''))
|
||||
|
||||
self.stubs.Set(compute_api.API, 'update', fake_update)
|
||||
self.stubs.Set(conductor_api.ComputeTaskAPI,
|
||||
'migrate_server',
|
||||
fake_migrate_server)
|
||||
def test_migrate_live_invalid_shared_storage(self):
|
||||
self._test_migrate_live_failed_with_exception(
|
||||
exception.InvalidSharedStorage(path='', reason=''))
|
||||
|
||||
res = req.get_response(app)
|
||||
self.assertEqual(res.status_int, 400)
|
||||
self.assertIn(
|
||||
unicode(exception.DestinationHypervisorTooOld()),
|
||||
res.body)
|
||||
def test_migrate_live_pre_check_error(self):
|
||||
self._test_migrate_live_failed_with_exception(
|
||||
exception.MigrationPreCheckError(reason=''))
|
||||
|
||||
def test_migrate_live_with_instance_invalid_state(self):
|
||||
def fake_live_migrate(self, context, instance, block_migration,
|
||||
disk_over_commit, host_name):
|
||||
raise exception.InstanceInvalidState(instance_uuid='', attr='',
|
||||
state='', method='')
|
||||
|
||||
self.stubs.Set(compute_api.API, 'live_migrate', fake_live_migrate)
|
||||
res = self._make_request('/v3/servers/%s/action' % self.UUID,
|
||||
{'migrate_live':
|
||||
{'host': 'hostname',
|
||||
'block_migration': False,
|
||||
'disk_over_commit': False}})
|
||||
self.assertEqual(res.status_int, 409)
|
||||
|
||||
|
||||
class CreateBackupTests(test.TestCase):
|
||||
@ -493,6 +474,19 @@ class CreateBackupTests(test.TestCase):
|
||||
response = request.get_response(self.app)
|
||||
self.assertEqual(response.status_int, 409)
|
||||
|
||||
def test_create_backup_with_non_existed_instance(self):
|
||||
body = {
|
||||
'create_backup': {
|
||||
'name': 'Backup 1',
|
||||
'backup_type': 'daily',
|
||||
'rotation': 1,
|
||||
},
|
||||
}
|
||||
self.stubs.Set(compute_api.API, 'get', fake_compute_api_get_non_found)
|
||||
request = self._get_request(body)
|
||||
response = request.get_response(self.app)
|
||||
self.assertEqual(response.status_int, 404)
|
||||
|
||||
|
||||
class ResetStateTests(test.TestCase):
|
||||
def setUp(self):
|
||||
|
Loading…
Reference in New Issue
Block a user