From b1c1902bb7caaef84869e354a6a8d896a0eb3253 Mon Sep 17 00:00:00 2001 From: Chris Behrens Date: Tue, 30 Oct 2012 18:33:18 +0000 Subject: [PATCH] Clean up xenapi VM records on failed disk attaches Breaks the create_vm_step up so that we can clean up the VM record in case of disk attach failures. Fixes bug 1073219 Change-Id: I54e28e2cce6fe4f29a03566eff998479410f7555 --- nova/tests/test_xenapi.py | 42 ++++++++++++++++++++++++++++++++------ nova/tests/xenapi/stubs.py | 11 ++++++++-- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 11e8844c..224b7585 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -516,6 +516,13 @@ class XenAPIVMTestCase(stubs.XenAPITestBase): session = xenapi_conn.XenAPISession(url, username, password) return session.call_xenapi('VDI.get_all') + def _list_vms(self): + url = FLAGS.xenapi_connection_url + username = FLAGS.xenapi_connection_username + password = FLAGS.xenapi_connection_password + session = xenapi_conn.XenAPISession(url, username, password) + return session.call_xenapi('VM.get_all') + def _check_vdis(self, start_list, end_list): for vdi_ref in end_list: if not vdi_ref in start_list: @@ -588,30 +595,53 @@ class XenAPIVMTestCase(stubs.XenAPITestBase): def test_spawn_fail_cleanup_1(self): """Simulates an error while downloading an image. - Verifies that VDIs created are properly cleaned up. - + Verifies that the VM and VDIs created are properly cleaned up. """ vdi_recs_start = self._list_vdis() + start_vms = self._list_vms() stubs.stubout_fetch_disk_image(self.stubs, raise_failure=True) self.assertRaises(xenapi_fake.Failure, self._test_spawn, 1, 2, 3) # No additional VDI should be found. vdi_recs_end = self._list_vdis() + end_vms = self._list_vms() self._check_vdis(vdi_recs_start, vdi_recs_end) + # No additional VMs should be found. + self.assertEqual(start_vms, end_vms) def test_spawn_fail_cleanup_2(self): """Simulates an error while creating VM record. - It verifies that VDIs created are properly cleaned up. - + Verifies that the VM and VDIs created are properly cleaned up. """ vdi_recs_start = self._list_vdis() + start_vms = self._list_vms() stubs.stubout_create_vm(self.stubs) self.assertRaises(xenapi_fake.Failure, self._test_spawn, 1, 2, 3) # No additional VDI should be found. vdi_recs_end = self._list_vdis() + end_vms = self._list_vms() self._check_vdis(vdi_recs_start, vdi_recs_end) + # No additional VMs should be found. + self.assertEqual(start_vms, end_vms) + + def test_spawn_fail_cleanup_3(self): + """Simulates an error while attaching disks. + + Verifies that the VM and VDIs created are properly cleaned up. + """ + stubs.stubout_attach_disks(self.stubs) + vdi_recs_start = self._list_vdis() + start_vms = self._list_vms() + self.assertRaises(xenapi_fake.Failure, + self._test_spawn, 1, 2, 3) + # No additional VDI should be found. + vdi_recs_end = self._list_vdis() + end_vms = self._list_vms() + self._check_vdis(vdi_recs_start, vdi_recs_end) + # No additional VMs should be found. + self.assertEqual(start_vms, end_vms) @stub_vm_utils_with_vdi_attached_here def test_spawn_raw_glance(self): @@ -1362,7 +1392,7 @@ class XenAPIAutoDiskConfigTestCase(stubs.XenAPITestBase): vdis = {'root': {'uuid': vdi_uuid, 'ref': vdi_ref}} self.conn._vmops._attach_disks(instance, vm_ref, instance['name'], - disk_image_type, vdis) + vdis, disk_image_type) self.assertEqual(marker["partition_called"], called) @@ -1448,7 +1478,7 @@ class XenAPIGenerateLocal(stubs.XenAPITestBase): self.called = False self.conn._vmops._attach_disks(instance, vm_ref, instance['name'], - disk_image_type, vdis) + vdis, disk_image_type) self.assertTrue(self.called) def test_generate_swap(self): diff --git a/nova/tests/xenapi/stubs.py b/nova/tests/xenapi/stubs.py index b3b9a896..560e12d7 100644 --- a/nova/tests/xenapi/stubs.py +++ b/nova/tests/xenapi/stubs.py @@ -138,11 +138,18 @@ def stubout_create_vm(stubs): """Simulates a failure in create_vm.""" def f(*args): - raise fake.Failure("Test Exception raised by " + - "fake create_vm") + raise fake.Failure("Test Exception raised by fake create_vm") stubs.Set(vm_utils, 'create_vm', f) +def stubout_attach_disks(stubs): + """Simulates a failure in _attach_disks.""" + + def f(*args): + raise fake.Failure("Test Exception raised by fake _attach_disks") + stubs.Set(vmops.VMOps, '_attach_disks', f) + + def _make_fake_vdi(): sr_ref = fake.get_all('SR')[0] vdi_ref = fake.create_vdi('', sr_ref)