diff options
| author | Eoghan Glynn <eglynn@redhat.com> | 2013-01-22 15:44:21 +0000 |
|---|---|---|
| committer | Eoghan Glynn <eglynn@redhat.com> | 2013-01-22 15:55:47 +0000 |
| commit | d6c527bb6b0ee63fc07b91855fcf4e15f7a03821 (patch) | |
| tree | 44229a23d8cc72605717616acb09f0b4df87afcc /nova/tests | |
| parent | fab8af583bf6c363d2cebbc360ae2709325d80bd (diff) | |
Avoid stuck task_state on snapshot image failure
Fixes bug LP 1101136
Previously if the glance interaction failed prior to an
instance being snapshot'd or backed up, the task state
remained stuck at image_snapshot/backup.
The normal task state reversion logic did not kick in,
as this is limited to the compute layer, whereas the
intial glance interaction occurs within the API layer.
Now, we avoid this problem by delaying setting the task
state until the initial initial image creation/retrieval
has completed.
Change-Id: Id498ae6b3674306743013e4fe99837da8e2031b5
Diffstat (limited to 'nova/tests')
| -rw-r--r-- | nova/tests/compute/test_compute.py | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index 092fd940a..865288f95 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -4688,6 +4688,60 @@ class ComputeAPITestCase(BaseTestCase): self.assertEqual(properties['d'], 'd') self.assertFalse('spam' in properties) + def _do_test_snapshot_image_service_fails(self, method, image_id): + # Ensure task_state remains at None if image service fails. + def fake_fails(*args, **kwargs): + raise test.TestingException() + + restore = getattr(fake_image._FakeImageService, method) + self.stubs.Set(fake_image._FakeImageService, method, fake_fails) + + instance = self._create_fake_instance() + self.assertRaises(test.TestingException, + self.compute_api.snapshot, + self.context, + instance, + 'no_image_snapshot', + image_id=image_id) + + self.stubs.Set(fake_image._FakeImageService, method, restore) + db_instance = db.instance_get_all(self.context)[0] + self.assertIsNone(db_instance['task_state']) + + def test_snapshot_image_creation_fails(self): + self._do_test_snapshot_image_service_fails('create', None) + + def test_snapshot_image_show_fails(self): + self._do_test_snapshot_image_service_fails('show', 'image') + + def _do_test_backup_image_service_fails(self, method, image_id): + # Ensure task_state remains at None if image service fails. + def fake_fails(*args, **kwargs): + raise test.TestingException() + + restore = getattr(fake_image._FakeImageService, method) + self.stubs.Set(fake_image._FakeImageService, method, fake_fails) + + instance = self._create_fake_instance() + self.assertRaises(test.TestingException, + self.compute_api.backup, + self.context, + instance, + 'no_image_backup', + 'DAILY', + 0, + image_id=image_id) + + self.stubs.Set(fake_image._FakeImageService, method, restore) + db_instance = db.instance_get_all(self.context)[0] + self.assertIsNone(db_instance['task_state']) + + def test_backup_image_creation_fails(self): + self._do_test_backup_image_service_fails('create', None) + + def test_backup_image_show_fails(self): + self._do_test_backup_image_service_fails('show', 'image') + def test_backup(self): # Can't backup an instance which is already being backed up. instance = self._create_fake_instance() |
