Merge "Fix Manager exceptions rendering for end-users"

This commit is contained in:
Jenkins 2014-01-20 12:55:13 +00:00 committed by Gerrit Code Review
commit 88dc709ef5
8 changed files with 166 additions and 122 deletions

View File

@ -20,9 +20,11 @@ from werkzeug import datastructures
from climate.api import context
from climate import exceptions as ex
from climate.manager import exceptions as manager_exceptions
from climate.openstack.common.deprecated import wsgi
from climate.openstack.common.gettextutils import _ # noqa
from climate.openstack.common import log as logging
from climate.openstack.common.rpc import common as rpc_common
LOG = logging.getLogger(__name__)
@ -73,6 +75,18 @@ class Rest(flask.Blueprint):
return func(**kwargs)
except ex.ClimateException as e:
return bad_request(e)
except rpc_common.RemoteError as e:
try:
# NOTE(sbauza): All Manager Exceptions should be
# defined in climate.manager.exceptions
cls = getattr(manager_exceptions, e.exc_type)
except AttributeError:
# We obfuscate all Exceptions but Climate ones for
# security reasons
return internal_error(500, 'Internal Server Error',
e)
return render_error_message(cls.code, e.value,
cls.code)
except Exception as e:
return internal_error(500, 'Internal Server Error', e)

View File

@ -0,0 +1,73 @@
# Copyright (c) 2013 Bull.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from climate import exceptions
from climate.openstack.common.gettextutils import _ # noqa
class NoFreePool(exceptions.NotFound):
msg_fmt = _("No Freepool found")
class HostNotInFreePool(exceptions.NotFound):
msg_fmt = _("Host %(host)s not in freepool '%(freepool_name)s'")
class CantRemoveHost(exceptions.ClimateException):
code = 409
msg_fmt = _("Can't remove host(s) %(host)s from Aggregate %(pool)s")
class CantAddHost(exceptions.ClimateException):
code = 409
msg_fmt = _("Can't add host(s) %(host)s to Aggregate %(pool)s")
class AggregateHaveHost(exceptions.ClimateException):
code = 409
msg_fmt = _("Can't delete Aggregate '%(name)s', "
"host(s) attached to it : %(hosts)s")
class AggregateAlreadyHasHost(exceptions.ClimateException):
code = 409
msg_fmt = _("Aggregate %(pool)s already has host(s) %(host)s ")
class AggregateNotFound(exceptions.NotFound):
msg_fmt = _("Aggregate '%(pool)s' not found!")
class HostNotFound(exceptions.NotFound):
msg_fmt = _("Host '%(host)s' not found!")
class InvalidHost(exceptions.NotAuthorized):
msg_fmt = _("Invalid values for host %(host)s")
class MultipleHostsFound(exceptions.ClimateException):
code = 409
msg_fmt = _("Multiple Hosts found for pattern '%(host)s'")
class HostHavingServers(exceptions.ClimateException):
code = 409
msg_fmt = _("Servers [%(servers)s] found for host %(host)s")
class CantAddExtraCapability(exceptions.ClimateException):
code = 409
msg_fmt = _("Can't add extracapabilities %(keys)s to Host %(host)s")

View File

@ -18,24 +18,7 @@ from novaclient import exceptions as nova_exceptions
from oslo.config import cfg
from climate import context
from climate import exceptions
from climate.openstack.common.gettextutils import _ # noqa
class HostNotFound(exceptions.ClimateException):
msg_fmt = _("Host '%(host)s' not found!")
class InvalidHost(exceptions.ClimateException):
msg_fmt = _("Invalid values for host %(host)s")
class MultipleHostsFound(exceptions.ClimateException):
msg_fmt = _("Multiple Hosts found for pattern '%(host)s'")
class HostHavingServers(exceptions.ClimateException):
msg_fmt = _("Servers [%(servers)s] found for host %(host)s")
from climate.manager import exceptions as manager_exceptions
class NovaInventory(object):
@ -64,9 +47,9 @@ class NovaInventory(object):
try:
hypervisors_list = self.nova.hypervisors.search(host)
except nova_exceptions.NotFound:
raise HostNotFound(host=host)
raise manager_exceptions.HostNotFound(host=host)
if len(hypervisors_list) > 1:
raise MultipleHostsFound(host)
raise manager_exceptions.MultipleHostsFound(host)
else:
hypervisor_id = hypervisors_list[0].id
# NOTE(sbauza): No need to catch the exception as we're sure
@ -82,7 +65,7 @@ class NovaInventory(object):
'memory_mb': hypervisor.memory_mb,
'local_gb': hypervisor.local_gb}
except AttributeError:
raise InvalidHost(host=host)
raise manager_exceptions.InvalidHost(host=host)
def get_servers_per_host(self, host):
"""List all servers of a nova-compute host
@ -93,9 +76,9 @@ class NovaInventory(object):
try:
hypervisors_list = self.nova.hypervisors.search(host, servers=True)
except nova_exceptions.NotFound:
raise HostNotFound(host=host)
raise manager_exceptions.HostNotFound(host=host)
if len(hypervisors_list) > 1:
raise MultipleHostsFound(host)
raise manager_exceptions.MultipleHostsFound(host)
else:
try:
return hypervisors_list[0].servers

View File

@ -21,8 +21,7 @@ from novaclient import exceptions as nova_exceptions
from oslo.config import cfg
from climate import context
from climate import exceptions
from climate.openstack.common.gettextutils import _ # noqa
from climate.manager import exceptions as manager_exceptions
from climate.openstack.common import log as logging
@ -47,35 +46,6 @@ opts = [
cfg.CONF.register_opts(opts, 'physical:host')
class NoFreePool(exceptions.ClimateException):
pass
class HostNotInFreePool(exceptions.ClimateException):
msg_fmt = _("Host %(host)s not in freepool '%(freepool_name)s'")
class CantRemoveHost(exceptions.ClimateException):
msg_fmt = _("Can't remove host(s) %(host)s from Aggregate %(pool)s")
class CantAddHost(exceptions.ClimateException):
msg_fmt = _("Can't add host(s) %(host)s to Aggregate %(pool)s")
class AggregateHaveHost(exceptions.ClimateException):
msg_fmt = _("Can't delete Aggregate '%(name)s', "
"host(s) attached to it : %(hosts)s")
class AggregateNotFound(exceptions.ClimateException):
msg_fmt = _("Aggregate '%(pool)s' not found!")
class HostNotFound(exceptions.ClimateException):
msg_fmt = _("Host '%(host)s' not found!")
class ReservationPool(object):
def __init__(self):
self.ctx = context.current()
@ -118,7 +88,7 @@ class ReservationPool(object):
if aggregate:
return aggregate
else:
raise AggregateNotFound(pool=aggregate_obj)
raise manager_exceptions.AggregateNotFound(pool=aggregate_obj)
@staticmethod
def _generate_aggregate_name():
@ -164,12 +134,12 @@ class ReservationPool(object):
hosts = agg.hosts
if len(hosts) > 0 and not force:
raise AggregateHaveHost(name=agg.name, hosts=agg.hosts)
raise manager_exceptions.AggregateHaveHost(name=agg.name,
hosts=agg.hosts)
try:
freepool_agg = self.get(self.freepool_name)
except AggregateNotFound:
raise NoFreePool()
except manager_exceptions.AggregateNotFound:
raise manager_exceptions.NoFreePool()
for host in hosts:
LOG.debug("Removing host '%s' from aggregate "
"'%s')" % (host, agg.id))
@ -196,7 +166,7 @@ class ReservationPool(object):
try:
agg = self.get_aggregate_from_name_or_id(pool)
return agg.hosts
except AggregateNotFound:
except manager_exceptions.AggregateNotFound:
return []
def add_computehost(self, pool, host):
@ -213,25 +183,28 @@ class ReservationPool(object):
try:
freepool_agg = self.get(self.freepool_name)
except AggregateNotFound:
raise NoFreePool()
except manager_exceptions.AggregateNotFound:
raise manager_exceptions.NoFreePool()
if freepool_agg.id != agg.id:
if host not in freepool_agg.hosts:
raise HostNotInFreePool(host=host,
freepool_name=freepool_agg.name)
raise manager_exceptions.HostNotInFreePool(
host=host, freepool_name=freepool_agg.name)
LOG.info("removing host '%s' "
"from aggregate freepool %s" % (host, freepool_agg.name))
try:
self.remove_computehost(freepool_agg.id, host)
except nova_exceptions.NotFound:
raise HostNotFound(host=host)
raise manager_exceptions.HostNotFound(host=host)
LOG.info("adding host '%s' to aggregate %s" % (host, agg.id))
try:
return self.nova.aggregates.add_host(agg.id, host)
except nova_exceptions.NotFound:
raise HostNotFound(host=host)
raise manager_exceptions.HostNotFound(host=host)
except nova_exceptions.Conflict:
raise manager_exceptions.AggregateAlreadyHasHost(pool=pool,
host=host)
def remove_all_computehosts(self, pool):
"""Remove all compute hosts attached to an aggregate."""
@ -249,8 +222,8 @@ class ReservationPool(object):
try:
freepool_agg = self.get(self.freepool_name)
except AggregateNotFound:
raise NoFreePool()
except manager_exceptions.AggregateNotFound:
raise manager_exceptions.NoFreePool()
hosts_failing_to_remove = []
hosts_failing_to_add = []
@ -273,12 +246,14 @@ class ReservationPool(object):
hosts_failing_to_add.append(host)
if hosts_failing_to_remove:
raise CantRemoveHost(host=hosts_failing_to_remove, pool=agg)
raise manager_exceptions.CantRemoveHost(
host=hosts_failing_to_remove, pool=agg)
if hosts_failing_to_add:
raise CantAddHost(host=hosts_failing_to_add, pool=freepool_agg)
raise manager_exceptions.CantAddHost(host=hosts_failing_to_add,
pool=freepool_agg)
if hosts_not_in_freepool:
raise HostNotInFreePool(host=hosts_not_in_freepool,
freepool_name=freepool_agg.name)
raise manager_exceptions.HostNotInFreePool(
host=hosts_not_in_freepool, freepool_name=freepool_agg.name)
def add_project(self, pool, project_id):
"""Add a project to an aggregate."""

View File

@ -18,18 +18,13 @@ from oslo.config import cfg
from climate import context
from climate.db import api as db_api
from climate import exceptions
from climate.openstack.common.gettextutils import _ # noqa
from climate.manager import exceptions as manager_exceptions
from climate.plugins import base
from climate.plugins.oshosts import nova_inventory
from climate.plugins.oshosts import reservation_pool as rp
from climate.utils import service as service_utils
class CantAddExtraCapability(exceptions.ClimateException):
msg_fmt = _("Can't add extracapabilities %(keys)s to Host %(host)s")
class PhysicalHostPlugin(base.BasePlugin):
"""Plugin for physical host resource."""
resource_type = 'physical:host'
@ -62,7 +57,7 @@ class PhysicalHostPlugin(base.BasePlugin):
try:
self.pool.get_aggregate_from_name_or_id(self.freepool_name)
return True
except rp.AggregateNotFound:
except manager_exceptions.AggregateNotFound:
return False
def _get_extra_capabilities(self, host_id):
@ -102,11 +97,11 @@ class PhysicalHostPlugin(base.BasePlugin):
host_ref = host_id or host_name
if host_ref is None:
raise nova_inventory.InvalidHost(host=host_values)
raise manager_exceptions.InvalidHost(host=host_values)
servers = self.inventory.get_servers_per_host(host_ref)
if servers:
raise nova_inventory.HostHavingServers(host=host_ref,
servers=servers)
raise manager_exceptions.HostHavingServers(host=host_ref,
servers=servers)
host_details = self.inventory.get_host_details(host_ref)
# NOTE(sbauza): Only last duplicate name for same extra capability will
# be stored
@ -134,8 +129,8 @@ class PhysicalHostPlugin(base.BasePlugin):
except RuntimeError:
cantaddextracapability.append(key)
if cantaddextracapability:
raise CantAddExtraCapability(keys=cantaddextracapability,
host=host['id'])
raise manager_exceptions.CantAddExtraCapability(
keys=cantaddextracapability, host=host['id'])
if host:
return self.get_computehost(host['id'])
else:
@ -161,8 +156,8 @@ class PhysicalHostPlugin(base.BasePlugin):
cantupdateextracapability.append(
raw_capability['capability_name'])
if cantupdateextracapability:
raise CantAddExtraCapability(host=host_id,
keys=cantupdateextracapability)
raise manager_exceptions.CantAddExtraCapability(
host=host_id, keys=cantupdateextracapability)
return self.get_computehost(host_id)
@service_utils.export_context
@ -171,11 +166,11 @@ class PhysicalHostPlugin(base.BasePlugin):
# - Check if no leases having this host scheduled
servers = self.inventory.get_servers_per_host(host_id)
if servers:
raise nova_inventory.HostHavingServers(host=host_id,
servers=servers)
raise manager_exceptions.HostHavingServers(host=host_id,
servers=servers)
host = db_api.host_get(host_id)
if not host:
raise rp.HostNotFound(host=host_id)
raise manager_exceptions.HostNotFound(host=host_id)
try:
self.pool.remove_computehost(self.freepool_name,
host['hypervisor_hostname'])
@ -184,4 +179,5 @@ class PhysicalHostPlugin(base.BasePlugin):
db_api.host_destroy(host_id)
except RuntimeError:
# Nothing so bad, but we need to advert the admin he has to rerun
raise rp.CantRemoveHost(host=host_id, pool=self.freepool_name)
raise manager_exceptions.CantRemoveHost(host=host_id,
pool=self.freepool_name)

View File

@ -17,6 +17,7 @@ from novaclient import client
from novaclient import exceptions as nova_exceptions
from climate import context
from climate.manager import exceptions as manager_exceptions
from climate.plugins.oshosts import nova_inventory
from climate import tests
@ -94,22 +95,22 @@ class NovaInventoryTestCase(tests.TestCase):
self.assertEqual(expected, host)
def test_get_host_details_with_host_name_having_multiple_results(self):
self.assertRaises(nova_inventory.MultipleHostsFound,
self.assertRaises(manager_exceptions.MultipleHostsFound,
self.inventory.get_host_details, 'multiple')
def test_get_host_details_with_host_id_not_found(self):
self.assertRaises(nova_inventory.HostNotFound,
self.assertRaises(manager_exceptions.HostNotFound,
self.inventory.get_host_details, '2')
def test_get_host_details_with_host_name_not_found(self):
self.assertRaises(nova_inventory.HostNotFound,
self.assertRaises(manager_exceptions.HostNotFound,
self.inventory.get_host_details, 'wrong_name')
def test_get_host_details_with_invalid_host(self):
invalid_host = FakeNovaHypervisors.FakeHost
del invalid_host.vcpus
self.hypervisors_get.return_value = invalid_host
self.assertRaises(nova_inventory.InvalidHost,
self.assertRaises(manager_exceptions.InvalidHost,
self.inventory.get_host_details, '1')
def test_get_servers_per_host(self):
@ -117,15 +118,15 @@ class NovaInventoryTestCase(tests.TestCase):
self.assertEqual(FakeNovaHypervisors.FakeHost.servers, servers)
def test_get_servers_per_host_with_host_id(self):
self.assertRaises(nova_inventory.HostNotFound,
self.assertRaises(manager_exceptions.HostNotFound,
self.inventory.get_servers_per_host, '1')
def test_get_servers_per_host_with_host_not_found(self):
self.assertRaises(nova_inventory.HostNotFound,
self.assertRaises(manager_exceptions.HostNotFound,
self.inventory.get_servers_per_host, 'wrong_name')
def test_get_servers_per_host_having_multiple_results(self):
self.assertRaises(nova_inventory.MultipleHostsFound,
self.assertRaises(manager_exceptions.MultipleHostsFound,
self.inventory.get_servers_per_host, 'multiple')
def test_get_servers_per_host_with_host_having_no_servers(self):

View File

@ -19,6 +19,7 @@ from oslo.config import cfg
from climate import config
from climate import context
from climate.manager import exceptions as manager_exceptions
from climate.plugins.oshosts import reservation_pool as rp
from climate import tests
from novaclient import client as nova_client
@ -85,9 +86,9 @@ class ReservationPoolTestCase(tests.TestCase):
self.nova.aggregates.list.return_value = [self.fake_aggregate]
self.nova.aggregates.get.side_effect = fake_aggregate_get
self.assertRaises(rp.AggregateNotFound,
self.assertRaises(manager_exceptions.AggregateNotFound,
self.pool.get_aggregate_from_name_or_id, 'none')
self.assertRaises(rp.AggregateNotFound,
self.assertRaises(manager_exceptions.AggregateNotFound,
self.pool.get_aggregate_from_name_or_id, '3000')
self.assertEqual(self.pool.get_aggregate_from_name_or_id('fooname'),
self.fake_aggregate)
@ -138,7 +139,7 @@ class ReservationPoolTestCase(tests.TestCase):
)
# can't delete aggregate with hosts
self.assertRaises(rp.AggregateHaveHost,
self.assertRaises(manager_exceptions.AggregateHaveHost,
self.pool.delete, 'bar',
force=False)
@ -152,14 +153,14 @@ class ReservationPoolTestCase(tests.TestCase):
def test_delete_with_no_freepool(self):
def get_fake_aggregate_but_no_freepool(*args):
if self.freepool_name in args:
raise rp.AggregateNotFound
raise manager_exceptions.AggregateNotFound
else:
return self.fake_aggregate
self.patch(self.pool, 'get_aggregate_from_name_or_id')\
.side_effect = get_fake_aggregate_but_no_freepool
agg = self.pool.get('foo')
agg.hosts = []
self.assertRaises(rp.NoFreePool,
self.assertRaises(manager_exceptions.NoFreePool,
self.pool.delete, 'bar',
force=False)
@ -183,7 +184,7 @@ class ReservationPoolTestCase(tests.TestCase):
def test_add_computehost_not_in_freepool(self):
self._patch_get_agg_from_whatever()
self.assertRaises(rp.HostNotInFreePool,
self.assertRaises(manager_exceptions.HostNotInFreePool,
self.pool.add_computehost,
'foopool',
'ghost-host')
@ -191,14 +192,14 @@ class ReservationPoolTestCase(tests.TestCase):
def test_add_computehost_with_no_freepool(self):
def get_fake_aggregate_but_no_freepool(*args):
if self.freepool_name in args:
raise rp.AggregateNotFound
raise manager_exceptions.AggregateNotFound
else:
return self.fake_aggregate
self.patch(self.pool, 'get_aggregate_from_name_or_id')\
.side_effect = get_fake_aggregate_but_no_freepool
self.assertRaises(rp.NoFreePool,
self.assertRaises(manager_exceptions.NoFreePool,
self.pool.add_computehost,
'pool',
'host3')
@ -208,10 +209,10 @@ class ReservationPoolTestCase(tests.TestCase):
if self.freepool_name in args:
return self.freepool_name
else:
raise rp.AggregateNotFound
raise manager_exceptions.AggregateNotFound
self.patch(self.pool, 'get_aggregate_from_name_or_id')\
.side_effect = get_no_aggregate_but_freepool
self.assertRaises(rp.AggregateNotFound,
self.assertRaises(manager_exceptions.AggregateNotFound,
self.pool.add_computehost,
'wrong_pool',
'host3')
@ -231,7 +232,7 @@ class ReservationPoolTestCase(tests.TestCase):
def test_remove_computehost_not_existing_from_freepool(self):
self._patch_get_agg_from_whatever()
self.assertRaises(rp.HostNotInFreePool,
self.assertRaises(manager_exceptions.HostNotInFreePool,
self.pool.remove_computehost,
self.freepool_name,
'hostXX')
@ -246,14 +247,14 @@ class ReservationPoolTestCase(tests.TestCase):
def test_remove_computehost_with_no_freepool(self):
def get_fake_aggregate_but_no_freepool(*args):
if self.freepool_name in args:
raise rp.AggregateNotFound
raise manager_exceptions.AggregateNotFound
else:
return self.fake_aggregate
self.patch(self.pool, 'get_aggregate_from_name_or_id')\
.side_effect = get_fake_aggregate_but_no_freepool
self.assertRaises(rp.NoFreePool,
self.assertRaises(manager_exceptions.NoFreePool,
self.pool.remove_computehost,
'pool',
'host3')
@ -263,10 +264,10 @@ class ReservationPoolTestCase(tests.TestCase):
if self.freepool_name in args:
return self.freepool_name
else:
raise rp.AggregateNotFound
raise manager_exceptions.AggregateNotFound
self.patch(self.pool, 'get_aggregate_from_name_or_id')\
.side_effect = get_no_aggregate_but_freepool
self.assertRaises(rp.AggregateNotFound,
self.assertRaises(manager_exceptions.AggregateNotFound,
self.pool.remove_computehost,
'wrong_pool',
'host3')
@ -275,7 +276,7 @@ class ReservationPoolTestCase(tests.TestCase):
self._patch_get_agg_from_whatever()
self.nova.aggregates.remove_host.side_effect = \
nova_exceptions.NotFound(404)
self.assertRaises(rp.CantRemoveHost,
self.assertRaises(manager_exceptions.CantRemoveHost,
self.pool.remove_computehost,
'pool',
'host3')
@ -284,7 +285,7 @@ class ReservationPoolTestCase(tests.TestCase):
self._patch_get_agg_from_whatever()
self.nova.aggregates.add_host.side_effect = \
nova_exceptions.Conflict(409)
self.assertRaises(rp.CantAddHost,
self.assertRaises(manager_exceptions.CantAddHost,
self.pool.remove_computehost,
'pool',
'host3')

View File

@ -17,6 +17,7 @@ import testtools
from climate import context
from climate.db import api as db_api
from climate.manager import exceptions as manager_exceptions
from climate.manager import service
from climate.plugins.oshosts import nova_inventory
from climate.plugins.oshosts import reservation_pool as rp
@ -60,7 +61,7 @@ class PhysicalHostPlugingSetupOnlyTestCase(tests.TestCase):
def test__freepool_exists_with_freepool_missing(self):
def fake_get_aggregate_from_name_or_id(*args, **kwargs):
raise rp.AggregateNotFound
raise manager_exceptions.AggregateNotFound
mock = self.patch(self.rp.ReservationPool,
'get_aggregate_from_name_or_id')
mock.side_effect = fake_get_aggregate_from_name_or_id
@ -187,12 +188,12 @@ class PhysicalHostPluginTestCase(tests.TestCase):
self.assertEqual(host, fake_host)
def test_create_host_with_invalid_values(self):
self.assertRaises(nova_inventory.InvalidHost,
self.assertRaises(manager_exceptions.InvalidHost,
self.fake_phys_plugin.create_computehost, {})
def test_create_host_with_existing_vms(self):
self.get_servers_per_host.return_value = ['server1', 'server2']
self.assertRaises(nova_inventory.HostHavingServers,
self.assertRaises(manager_exceptions.HostHavingServers,
self.fake_phys_plugin.create_computehost,
self.fake_host)
@ -213,7 +214,7 @@ class PhysicalHostPluginTestCase(tests.TestCase):
self.db_host_create.return_value = self.fake_host
self.db_host_extra_capability_create.side_effect = \
fake_db_host_extra_capability_create
self.assertRaises(physical_host_plugin.CantAddExtraCapability,
self.assertRaises(manager_exceptions.CantAddExtraCapability,
self.fake_phys_plugin.create_computehost,
fake_request)
@ -239,7 +240,7 @@ class PhysicalHostPluginTestCase(tests.TestCase):
'capability_value': 'bar'}]
self.db_host_extra_capability_update.side_effect = \
fake_db_host_extra_capability_update
self.assertRaises(physical_host_plugin.CantAddExtraCapability,
self.assertRaises(manager_exceptions.CantAddExtraCapability,
self.fake_phys_plugin.update_computehost,
self.fake_host_id, host_values)
@ -250,13 +251,13 @@ class PhysicalHostPluginTestCase(tests.TestCase):
def test_delete_host_having_vms(self):
self.get_servers_per_host.return_value = ['server1', 'server2']
self.assertRaises(nova_inventory.HostHavingServers,
self.assertRaises(manager_exceptions.HostHavingServers,
self.fake_phys_plugin.delete_computehost,
self.fake_host_id)
def test_delete_host_not_existing_in_db(self):
self.db_host_get.return_value = None
self.assertRaises(rp.HostNotFound,
self.assertRaises(manager_exceptions.HostNotFound,
self.fake_phys_plugin.delete_computehost,
self.fake_host_id)
@ -264,6 +265,6 @@ class PhysicalHostPluginTestCase(tests.TestCase):
def fake_db_host_destroy(*args, **kwargs):
raise RuntimeError
self.db_host_destroy.side_effect = fake_db_host_destroy
self.assertRaises(rp.CantRemoveHost,
self.assertRaises(manager_exceptions.CantRemoveHost,
self.fake_phys_plugin.delete_computehost,
self.fake_host_id)