From 3d3affc752613f0f12cd25109b1d5be05bfe0c6f Mon Sep 17 00:00:00 2001 From: Peter Feiner Date: Wed, 15 May 2013 14:03:56 -0500 Subject: Ignore lifecycle events for non-existent instances Since event delivery is asynchronous, there's an inherent yet benign race in the event handler querying the database for a deleted instance. Fixes bug #1180501. Change-Id: I8e478fb13bedfc86730018ba849ecc71d4286f0d --- nova/tests/compute/test_compute.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'nova/tests') diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index e2783641c..bba8bbcb2 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -73,6 +73,11 @@ from nova.tests import fake_network_cache_model from nova.tests.image import fake as fake_image from nova.tests import matchers from nova import utils +from nova.virt.event import EVENT_LIFECYCLE_PAUSED +from nova.virt.event import EVENT_LIFECYCLE_RESUMED +from nova.virt.event import EVENT_LIFECYCLE_STARTED +from nova.virt.event import EVENT_LIFECYCLE_STOPPED +from nova.virt.event import LifecycleEvent from nova.virt import fake from nova.volume import cinder @@ -5315,6 +5320,38 @@ class ComputeTestCase(BaseTestCase): self._test_sync_to_stop(power_state.RUNNING, vs, ps, stop=False) + def _test_lifecycle_event(self, lifecycle_event, power_state): + instance = self._create_fake_instance() + uuid = instance['uuid'] + + self.mox.StubOutWithMock(self.compute, '_sync_instance_power_state') + if power_state != None: + self.compute._sync_instance_power_state( + mox.IgnoreArg(), + mox.ContainsKeyValue('uuid', uuid), + power_state) + self.mox.ReplayAll() + self.compute.handle_events(LifecycleEvent(uuid, lifecycle_event)) + self.mox.VerifyAll() + self.mox.UnsetStubs() + + def test_lifecycle_events(self): + self._test_lifecycle_event(EVENT_LIFECYCLE_STOPPED, + power_state.SHUTDOWN) + self._test_lifecycle_event(EVENT_LIFECYCLE_STARTED, + power_state.RUNNING) + self._test_lifecycle_event(EVENT_LIFECYCLE_PAUSED, + power_state.PAUSED) + self._test_lifecycle_event(EVENT_LIFECYCLE_RESUMED, + power_state.RUNNING) + self._test_lifecycle_event(-1, None) + + def test_lifecycle_event_non_existent_instance(self): + # No error raised for non-existent instance because of inherent race + # between database updates and hypervisor events. See bug #1180501. + event = LifecycleEvent('does-not-exist', EVENT_LIFECYCLE_STOPPED) + self.compute.handle_events(event) + class ComputeAPITestCase(BaseTestCase): -- cgit