From 5661055b8b138aa027b4e3f3d3d7f8a2ec928adf Mon Sep 17 00:00:00 2001 From: Gary Kotton Date: Thu, 31 Oct 2013 12:07:54 -0700 Subject: [PATCH] VMware: fix bug for exceptions thrown in _wait_for_task If the _call_method fails, for example a resource is not found, then the same call will be invoked again due to the fact that the polling task was not stopped. Closes-Bug: #1246848 Change-Id: If4818e41aed5be03395ab22afc0edf9abb3c34e1 (cherry picked from commit 1c1570ff7ac8470d7dba28c893300835b22e0966) --- nova/tests/virt/vmwareapi/test_vmwareapi.py | 26 +++++++++++++++++++++ nova/virt/vmwareapi/driver.py | 11 +++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/nova/tests/virt/vmwareapi/test_vmwareapi.py b/nova/tests/virt/vmwareapi/test_vmwareapi.py index 7058dd9170f..746a851c668 100755 --- a/nova/tests/virt/vmwareapi/test_vmwareapi.py +++ b/nova/tests/virt/vmwareapi/test_vmwareapi.py @@ -241,6 +241,32 @@ def _fake_login(_self): self.conn = driver.VMwareAPISession() self.assertEqual(self.attempts, 2) + def test_wait_for_task_exception(self): + self.flags(task_poll_interval=1, group='vmware') + self.login_session = vmwareapi_fake.FakeVim()._login() + self.stop_called = 0 + + def _fake_login(_self): + return self.login_session + + self.stubs.Set(vmwareapi_fake.FakeVim, '_login', _fake_login) + + def fake_poll_task(instance_uuid, task_ref, done): + done.send_exception(exception.NovaException('fake exception')) + + def fake_stop_loop(loop): + self.stop_called += 1 + return loop.stop() + + self.conn = driver.VMwareAPISession() + self.stubs.Set(self.conn, "_poll_task", + fake_poll_task) + self.stubs.Set(self.conn, "_stop_loop", + fake_stop_loop) + self.assertRaises(exception.NovaException, + self.conn._wait_for_task, 'fake-id', 'fake-ref') + self.assertEqual(self.stop_called, 1) + def _create_instance_in_the_db(self, node=None, set_image_ref=True, uuid=None): if not node: diff --git a/nova/virt/vmwareapi/driver.py b/nova/virt/vmwareapi/driver.py index 38e546772df..c61ab63f35f 100644 --- a/nova/virt/vmwareapi/driver.py +++ b/nova/virt/vmwareapi/driver.py @@ -910,6 +910,9 @@ def _get_vim(self): self._create_session() return self.vim + def _stop_loop(self, loop): + loop.stop() + def _wait_for_task(self, instance_uuid, task_ref): """ Return a Deferred that will give the result of the given task. @@ -920,8 +923,12 @@ def _wait_for_task(self, instance_uuid, task_ref): instance_uuid, task_ref, done) loop.start(CONF.vmware.task_poll_interval) - ret_val = done.wait() - loop.stop() + try: + ret_val = done.wait() + except Exception: + raise + finally: + self._stop_loop(loop) return ret_val def _poll_task(self, instance_uuid, task_ref, done):