diff options
-rwxr-xr-x | nova/compute/manager.py | 7 | ||||
-rw-r--r-- | nova/tests/compute/test_compute.py | 35 |
2 files changed, 42 insertions, 0 deletions
diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 99b97e921..9ca00bd9b 100755 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -780,6 +780,13 @@ class ComputeManager(manager.SchedulerDependentManager): msg = _('Failed to dealloc network for deleted instance') LOG.exception(msg, instance=instance) raise + except exception.UnexpectedTaskStateError as e: + actual_task_state = e.kwargs.get('actual', None) + if actual_task_state == 'deleting': + msg = _('Instance was deleted during spawn.') + LOG.debug(msg, instance=instance) + else: + raise except Exception: exc_info = sys.exc_info() # try to re-schedule instance: diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index 5ad333c9e..98eba5570 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -7225,6 +7225,41 @@ class ComputeRescheduleOrReraiseTestCase(BaseTestCase): self.compute._reschedule_or_reraise(self.context, self.instance, exc_info, None, None, None, False, None, {}) + def test_no_reschedule_on_delete_during_spawn(self): + # instance should not be rescheduled if instance is deleted + # during the build + self.mox.StubOutWithMock(self.compute, '_spawn') + self.mox.StubOutWithMock(self.compute, '_reschedule_or_reraise') + + exc = exception.UnexpectedTaskStateError(expected=task_states.SPAWNING, + actual=task_states.DELETING) + self.compute._spawn(mox.IgnoreArg(), self.instance, mox.IgnoreArg(), + mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg(), + mox.IgnoreArg()).AndRaise(exc) + + self.mox.ReplayAll() + # test succeeds if mocked method '_reschedule_or_reraise' is not + # called. + self.compute._run_instance(self.context, None, {}, None, None, None, + False, None, self.instance) + + def test_no_reschedule_on_unexpected_task_state(self): + # instance shouldn't be rescheduled if unexpected task state arises. + # the exception should get reraised. + self.mox.StubOutWithMock(self.compute, '_spawn') + self.mox.StubOutWithMock(self.compute, '_reschedule_or_reraise') + + exc = exception.UnexpectedTaskStateError(expected=task_states.SPAWNING, + actual=task_states.SCHEDULING) + self.compute._spawn(mox.IgnoreArg(), self.instance, mox.IgnoreArg(), + mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg(), + mox.IgnoreArg()).AndRaise(exc) + + self.mox.ReplayAll() + self.assertRaises(exception.UnexpectedTaskStateError, + self.compute._run_instance, self.context, None, {}, None, None, + None, False, None, self.instance) + class ComputeRescheduleResizeOrReraiseTestCase(BaseTestCase): """Test logic and exception handling around rescheduling prep resize |