Sfoglia il codice sorgente

Improved test case exception handling

nuwan_ag 10 anni fa
parent
commit
44300727f2

+ 1 - 1
cloudbridge/providers/aws/resources.py

@@ -400,4 +400,4 @@ class AWSSnapshot(BaseSnapshot):
         self._snapshot.delete()
 
     def __repr__(self):
-        return "<CB-AWSVolume: {0} ({1}>".format(self.snapshot_id, self.name)
+        return "<CB-AWSSnapshot: {0} ({1}>".format(self.snapshot_id, self.name)

+ 4 - 2
cloudbridge/providers/aws/services.py

@@ -97,7 +97,7 @@ class AWSVolumeService(VolumeService):
         Creates a new volume.
         """
         zone_name = zone.name if isinstance(zone, PlacementZone) else zone
-        snapshot_id = snapshot.id if isinstance(
+        snapshot_id = snapshot.snapshot_id if isinstance(
             zone, AWSSnapshot) and snapshot else snapshot
 
         ec2_vol = self.provider.ec2_conn.create_volume(
@@ -143,7 +143,9 @@ class AWSSnapshotService(SnapshotService):
         """
         Creates a new snapshot of a given volume.
         """
-        volume_id = volume.id if isinstance(volume, AWSVolume) else volume
+        volume_id = volume.volume_id if isinstance(
+            volume,
+            AWSVolume) else volume
 
         ec2_snap = self.provider.ec2_conn.create_snapshot(
             volume_id,

+ 31 - 0
test/helpers.py

@@ -1,8 +1,39 @@
+from contextlib import contextmanager
 import os
+import sys
 import unittest
+
 from cloudbridge.providers.factory import CloudProviderFactory
 
 
+@contextmanager
+def exception_action(cleanup_func):
+    """
+    Context manager to carry out a given
+    cleanup action when an exception occurs.
+    If any errors occur during the cleanup
+    action, those are ignored, and the original
+    traceback is preserved.
+
+    :params func: This function is called only
+        if an exception occurs. Any exceptions raised
+        by func are ignored.
+    Usage:
+        with exception_action(lambda e: print("Oops!")):
+            do_something()
+    """
+    try:
+        yield
+    except:
+        exc_info = sys.exc_info()
+        try:
+            cleanup_func()
+        except:
+            pass
+        # raise the original exception
+        raise exc_info[0], exc_info[1], exc_info[2]
+
+
 def create_test_instance(provider):
     instance_name = "HelloCloudBridge-{0}".format(provider.name)
     if "AWSCloudProvider" in provider.name:

+ 0 - 1
test/test_compute_service.py

@@ -1,4 +1,3 @@
-from cloudbridge.providers import interfaces
 from test.helpers import ProviderTestBase
 import test.helpers
 

+ 14 - 14
test/test_provider_block_store_service.py

@@ -3,7 +3,7 @@ import uuid
 from cloudbridge.providers.interfaces import SnapshotState
 from cloudbridge.providers.interfaces import VolumeState
 from test.helpers import ProviderTestBase
-import test.helpers
+import test.helpers as helpers
 
 
 class ProviderBlockStoreServiceTestCase(ProviderTestBase):
@@ -13,7 +13,7 @@ class ProviderBlockStoreServiceTestCase(ProviderTestBase):
             methodName=methodName, provider=provider)
 
     def setUp(self):
-        self.instance = test.helpers.get_test_instance(self.provider)
+        self.instance = helpers.get_test_instance(self.provider)
 
     def tearDown(self):
         self.instance.terminate()
@@ -28,7 +28,7 @@ class ProviderBlockStoreServiceTestCase(ProviderTestBase):
             name,
             1,
             self.instance.placement_zone)
-        try:
+        with helpers.exception_action(lambda x: test_vol.delete()):
             test_vol.wait_till_ready()
             volumes = self.provider.block_store.volumes.list_volumes()
             found_volumes = [vol for vol in volumes if vol.name == name]
@@ -36,7 +36,6 @@ class ProviderBlockStoreServiceTestCase(ProviderTestBase):
                 len(found_volumes) == 1,
                 "List volumes does not return the expected volume %s" %
                 name)
-        finally:
             test_vol.delete()
 
     def test_attach_detach_volume(self):
@@ -46,7 +45,7 @@ class ProviderBlockStoreServiceTestCase(ProviderTestBase):
         name = "CBUnitTestAttachVol-{0}".format(uuid.uuid4())
         test_vol = self.provider.block_store.volumes.create_volume(
             name, 1, self.instance.placement_zone)
-        try:
+        with helpers.exception_action(lambda x: test_vol.delete()):
             test_vol.wait_till_ready()
             test_vol.attach(self.instance, '/dev/sda2')
             test_vol.wait_for(
@@ -56,7 +55,6 @@ class ProviderBlockStoreServiceTestCase(ProviderTestBase):
             test_vol.wait_for(
                 [VolumeState.AVAILABLE], terminal_states=[VolumeState.ERROR,
                                                           VolumeState.DELETED])
-        finally:
             test_vol.delete()
 
     def test_crud_snapshot(self):
@@ -70,15 +68,20 @@ class ProviderBlockStoreServiceTestCase(ProviderTestBase):
             name,
             1,
             self.instance.placement_zone)
-        try:
+        with helpers.exception_action(lambda x: test_vol.delete()):
             test_vol.wait_till_ready()
             snap_name = "CBSnapshot-{0}".format(name)
             test_snap = test_vol.create_snapshot(name=snap_name,
                                                  description=snap_name)
-            try:
-                test_snap.wait_for(
-                    [SnapshotState.AVAILABLE],
+
+            def cleanup_snap(snap):
+                snap.delete()
+                snap.wait_for(
+                    [SnapshotState.UNKNOWN],
                     terminal_states=[SnapshotState.ERROR])
+
+            with helpers.exception_action(lambda x: cleanup_snap(test_snap)):
+                test_snap.wait_till_ready()
                 snaps = self.provider.block_store.snapshots.list_snapshots()
                 found_snaps = [snap for snap in snaps
                                if snap.name == snap_name]
@@ -86,7 +89,4 @@ class ProviderBlockStoreServiceTestCase(ProviderTestBase):
                     len(found_snaps) == 1,
                     "List snapshots does not return the expected volume %s" %
                     name)
-            finally:
-                test_snap.delete()
-        finally:
-            test_vol.delete()
+                cleanup_snap(test_snap)

+ 3 - 4
test/test_provider_image_service.py

@@ -1,7 +1,7 @@
 import uuid
 
 from test.helpers import ProviderTestBase
-import test.helpers
+import test.helpers as helpers
 
 
 class ProviderImageServiceTestCase(ProviderTestBase):
@@ -11,7 +11,7 @@ class ProviderImageServiceTestCase(ProviderTestBase):
             methodName=methodName, provider=provider)
 
     def setUp(self):
-        self.instance = test.helpers.get_test_instance(self.provider)
+        self.instance = helpers.get_test_instance(self.provider)
 
     def tearDown(self):
         self.instance.terminate()
@@ -24,7 +24,7 @@ class ProviderImageServiceTestCase(ProviderTestBase):
         """
         name = "CBUnitTestListImg-{0}".format(uuid.uuid4())
         test_image = self.instance.create_image(name)
-        try:
+        with helpers.exception_action(lambda x: test_image.delete()):
             test_image.wait_till_ready()
             images = self.provider.images.list_images()
             images = [image for image in images if image.name == name]
@@ -32,5 +32,4 @@ class ProviderImageServiceTestCase(ProviderTestBase):
                 len(images) == 1,
                 "List images does not return the expected image %s" %
                 name)
-        finally:
             test_image.delete()