From 7370c400c4f87b6a74a151c69108216140d71fb6 Mon Sep 17 00:00:00 2001 From: Hemna Date: Wed, 5 Feb 2020 17:58:00 -0500 Subject: Ensure lease polling raises proper exception This patch adds the ability to properly translate and raise VimExceptions when polling the state of the lease. Change-Id: Ie22808471d4c72e26607e817167e0e2283630b5a --- oslo_vmware/api.py | 13 ++----------- oslo_vmware/exceptions.py | 26 ++++++++++++++++++++++++++ oslo_vmware/tests/test_exceptions.py | 29 +++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 11 deletions(-) (limited to 'oslo_vmware') diff --git a/oslo_vmware/api.py b/oslo_vmware/api.py index 81c44ef..f30fd35 100644 --- a/oslo_vmware/api.py +++ b/oslo_vmware/api.py @@ -446,16 +446,7 @@ class VMwareAPISession(object): get_completed_task()) raise loopingcall.LoopingCallDone(task_info) else: - error_msg = six.text_type(task_info.error.localizedMessage) - error = task_info.error - name = error.fault.__class__.__name__ - fault_class = exceptions.get_fault_class(name) - if fault_class: - task_ex = fault_class(error_msg) - else: - task_ex = exceptions.VimFaultException([name], - error_msg) - raise task_ex + raise exceptions.translate_fault(task_info.error) def wait_for_lease_ready(self, lease): """Waits for the given lease to be ready. @@ -506,7 +497,7 @@ class VMwareAPISession(object): "%(error_msg)s.") % {'lease': lease, 'error_msg': error_msg} LOG.error(excep_msg) - raise exceptions.VimException(excep_msg) + raise exceptions.translate_fault(error_msg, excep_msg) else: # unknown state excep_msg = _("Unknown state: %(state)s for lease: " diff --git a/oslo_vmware/exceptions.py b/oslo_vmware/exceptions.py index 4018a82..df6d676 100644 --- a/oslo_vmware/exceptions.py +++ b/oslo_vmware/exceptions.py @@ -296,6 +296,32 @@ def get_fault_class(name): return fault_class +def translate_fault(localized_method_fault, excep_msg=None): + """Produce proper VimException subclass object, + + The exception is based on a vmodl.LocalizedMethodFault. + + :param excep_msg: Message to set to the exception. Defaults to + localizedMessage of the fault. + """ + try: + if not excep_msg: + excep_msg = six.text_type(localized_method_fault.localizedMessage) + name = localized_method_fault.fault.__class__.__name__ + fault_class = get_fault_class(name) + if fault_class: + ex = fault_class(excep_msg) + else: + ex = VimFaultException([name], excep_msg) + except Exception as e: + LOG.debug("Unexpected exception thrown (%s) while translating" + " fault (%s) with message: %s.", + e, localized_method_fault, excep_msg) + ex = VimException(message=excep_msg, cause=e) + + return ex + + def register_fault_class(name, exception): fault_class = _fault_classes_registry.get(name) if not issubclass(exception, VimException): diff --git a/oslo_vmware/tests/test_exceptions.py b/oslo_vmware/tests/test_exceptions.py index 2ef24a7..d70756b 100644 --- a/oslo_vmware/tests/test_exceptions.py +++ b/oslo_vmware/tests/test_exceptions.py @@ -16,6 +16,8 @@ """ Unit tests for exceptions module. """ +import mock + from oslo_vmware._i18n import _ from oslo_vmware import exceptions from oslo_vmware.tests import base @@ -119,3 +121,30 @@ class ExceptionsTest(base.TestCase): exceptions.get_fault_class("ManagedObjectNotFound")) # Test unknown fault. self.assertIsNone(exceptions.get_fault_class("NotAFile")) + + def test_translate_fault(self): + + def fake_task(fault_class_name, error_msg=None): + task_info = mock.Mock() + task_info.localizedMessage = error_msg + if fault_class_name: + error_fault = mock.Mock() + error_fault.__class__.__name__ = fault_class_name + task_info.fault = error_fault + return task_info + + error_msg = "OUCH" + task = fake_task(exceptions.FILE_LOCKED, error_msg) + actual = exceptions.translate_fault(task) + + expected = exceptions.FileLockedException(error_msg) + self.assertEqual(expected.__class__, actual.__class__) + self.assertEqual(expected.message, actual.message) + + error_msg = "Oopsie" + task = fake_task(None, error_msg) + actual = exceptions.translate_fault(task) + expected = exceptions.VimFaultException(['Mock'], message=error_msg) + self.assertEqual(expected.__class__, actual.__class__) + self.assertEqual(expected.message, actual.message) + self.assertEqual(expected.fault_list, actual.fault_list) -- cgit v1.2.1