Merge "hyper-v: Converts all os-win exceptions"
This commit is contained in:
commit
c3bb0400d0
@ -26,39 +26,45 @@ from ceilometer.compute.pollsters import util
|
||||
from ceilometer.compute.virt import inspector as virt_inspector
|
||||
|
||||
|
||||
def convert_exceptions(function, exception_map):
|
||||
def convert_exceptions(exception_map, yields=True):
|
||||
expected_exceptions = tuple(exception_map.keys())
|
||||
|
||||
@functools.wraps(function)
|
||||
def wrapper(*args, **kwargs):
|
||||
try:
|
||||
return function(*args, **kwargs)
|
||||
except expected_exceptions as ex:
|
||||
# exception might be a subclass of an expected exception.
|
||||
for expected in expected_exceptions:
|
||||
if isinstance(ex, expected):
|
||||
raised_exception = exception_map[expected]
|
||||
break
|
||||
def _reraise_exception(exc):
|
||||
# exception might be a subclass of an expected exception.
|
||||
for expected in expected_exceptions:
|
||||
if isinstance(exc, expected):
|
||||
raised_exception = exception_map[expected]
|
||||
break
|
||||
|
||||
exc_info = sys.exc_info()
|
||||
# NOTE(claudiub): Python 3 raises the exception object given as
|
||||
# the second argument in six.reraise.
|
||||
# The original message will be maintained by passing the original
|
||||
# exception.
|
||||
exc = raised_exception(six.text_type(exc_info[1]))
|
||||
six.reraise(raised_exception, exc, exc_info[2])
|
||||
return wrapper
|
||||
exc_info = sys.exc_info()
|
||||
# NOTE(claudiub): Python 3 raises the exception object given as
|
||||
# the second argument in six.reraise.
|
||||
# The original message will be maintained by passing the
|
||||
# original exception.
|
||||
exc = raised_exception(six.text_type(exc_info[1]))
|
||||
six.reraise(raised_exception, exc, exc_info[2])
|
||||
|
||||
def decorator(function):
|
||||
if yields:
|
||||
@functools.wraps(function)
|
||||
def wrapper(*args, **kwargs):
|
||||
try:
|
||||
# NOTE(claudiub): We're consuming the function's yield in
|
||||
# order to avoid yielding a generator.
|
||||
for item in function(*args, **kwargs):
|
||||
yield item
|
||||
except expected_exceptions as ex:
|
||||
_reraise_exception(ex)
|
||||
else:
|
||||
@functools.wraps(function)
|
||||
def wrapper(*args, **kwargs):
|
||||
try:
|
||||
return function(*args, **kwargs)
|
||||
except expected_exceptions as ex:
|
||||
_reraise_exception(ex)
|
||||
|
||||
def decorate_all_methods(decorator, *args, **kwargs):
|
||||
def decorate(cls):
|
||||
for attr in cls.__dict__:
|
||||
class_member = getattr(cls, attr)
|
||||
if callable(class_member):
|
||||
setattr(cls, attr, decorator(class_member, *args, **kwargs))
|
||||
return cls
|
||||
|
||||
return decorate
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
|
||||
exception_conversion_map = collections.OrderedDict([
|
||||
@ -69,12 +75,11 @@ exception_conversion_map = collections.OrderedDict([
|
||||
(os_win_exc.OSWinException, virt_inspector.InspectorException),
|
||||
])
|
||||
|
||||
# NOTE(claudiub): the purpose of the decorator below is to prevent any
|
||||
# NOTE(claudiub): the purpose of the decorators below is to prevent any
|
||||
# os_win exceptions (subclasses of OSWinException) to leak outside of the
|
||||
# HyperVInspector.
|
||||
|
||||
|
||||
@decorate_all_methods(convert_exceptions, exception_conversion_map)
|
||||
class HyperVInspector(virt_inspector.Inspector):
|
||||
|
||||
def __init__(self, conf):
|
||||
@ -91,6 +96,7 @@ class HyperVInspector(virt_inspector.Inspector):
|
||||
|
||||
return float(host_cpu_clock * host_cpu_count)
|
||||
|
||||
@convert_exceptions(exception_conversion_map, yields=False)
|
||||
def inspect_instance(self, instance, duration):
|
||||
instance_name = util.instance_name(instance)
|
||||
(cpu_clock_used,
|
||||
@ -105,6 +111,7 @@ class HyperVInspector(virt_inspector.Inspector):
|
||||
cpu_time=cpu_time,
|
||||
memory_usage=memory_usage)
|
||||
|
||||
@convert_exceptions(exception_conversion_map)
|
||||
def inspect_vnics(self, instance, duration):
|
||||
instance_name = util.instance_name(instance)
|
||||
for vnic_metrics in self._utils.get_vnic_metrics(instance_name):
|
||||
@ -122,6 +129,7 @@ class HyperVInspector(virt_inspector.Inspector):
|
||||
tx_drop=0,
|
||||
tx_errors=0)
|
||||
|
||||
@convert_exceptions(exception_conversion_map)
|
||||
def inspect_disks(self, instance, duration):
|
||||
instance_name = util.instance_name(instance)
|
||||
for disk_metrics in self._utils.get_disk_metrics(instance_name):
|
||||
@ -134,6 +142,7 @@ class HyperVInspector(virt_inspector.Inspector):
|
||||
write_bytes=disk_metrics['write_mb'] * units.Mi,
|
||||
errors=0, wr_total_times=0, rd_total_times=0)
|
||||
|
||||
@convert_exceptions(exception_conversion_map)
|
||||
def inspect_disk_latency(self, instance, duration):
|
||||
instance_name = util.instance_name(instance)
|
||||
for disk_metrics in self._utils.get_disk_latency_metrics(
|
||||
@ -142,6 +151,7 @@ class HyperVInspector(virt_inspector.Inspector):
|
||||
device=disk_metrics['instance_id'],
|
||||
disk_latency=disk_metrics['disk_latency'] / 1000)
|
||||
|
||||
@convert_exceptions(exception_conversion_map)
|
||||
def inspect_disk_iops(self, instance, duration):
|
||||
instance_name = util.instance_name(instance)
|
||||
for disk_metrics in self._utils.get_disk_iops_count(instance_name):
|
||||
|
@ -58,6 +58,27 @@ class TestHyperVInspection(base.BaseTestCase):
|
||||
self._inspector.inspect_instance,
|
||||
mock.sentinel.instance, None)
|
||||
|
||||
def _yield_consumer(generator_method, *args, **kwargs):
|
||||
list(generator_method(*args, **kwargs))
|
||||
|
||||
self._inspector._utils.get_vnic_metrics.side_effect = (
|
||||
os_win_exc.OSWinException)
|
||||
self.assertRaises(virt_inspector.InspectorException,
|
||||
_yield_consumer, self._inspector.inspect_vnics,
|
||||
mock.sentinel.instance, None)
|
||||
|
||||
self._inspector._utils.get_vnic_metrics.side_effect = (
|
||||
os_win_exc.HyperVException)
|
||||
self.assertRaises(virt_inspector.InspectorException,
|
||||
_yield_consumer, self._inspector.inspect_vnics,
|
||||
mock.sentinel.instance, None)
|
||||
|
||||
self._inspector._utils.get_vnic_metrics.side_effect = (
|
||||
os_win_exc.NotFound(resource='foofoo'))
|
||||
self.assertRaises(virt_inspector.InstanceNotFoundException,
|
||||
_yield_consumer, self._inspector.inspect_vnics,
|
||||
mock.sentinel.instance, None)
|
||||
|
||||
def test_assert_original_traceback_maintained(self):
|
||||
def bar(self):
|
||||
foo = "foofoo"
|
||||
|
Loading…
Reference in New Issue
Block a user