Merge "hyper-v: Converts all os-win exceptions"

This commit is contained in:
Zuul 2018-02-27 10:33:52 +00:00 committed by Gerrit Code Review
commit c3bb0400d0
2 changed files with 61 additions and 30 deletions

View File

@ -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):

View File

@ -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"