Merge "cleanup resources in setUpClass if exception raised"
diff --git a/tempest/api/compute/floating_ips/test_floating_ips_actions.py b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
index c0f7af0..abd8a4c 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
@@ -24,10 +24,11 @@
     floating_ip = None
 
     @classmethod
+    @test.safe_setup
     def setUpClass(cls):
         super(FloatingIPsTestJSON, cls).setUpClass()
         cls.client = cls.floating_ips_client
-        #cls.servers_client = cls.servers_client
+        cls.floating_ip_id = None
 
         # Server creation
         resp, server = cls.create_test_server(wait_until='ACTIVE')
@@ -40,7 +41,8 @@
     @classmethod
     def tearDownClass(cls):
         # Deleting the floating IP which is created in this method
-        resp, body = cls.client.delete_floating_ip(cls.floating_ip_id)
+        if cls.floating_ip_id:
+            resp, body = cls.client.delete_floating_ip(cls.floating_ip_id)
         super(FloatingIPsTestJSON, cls).tearDownClass()
 
     @test.attr(type='gate')
diff --git a/tempest/api/compute/images/test_image_metadata.py b/tempest/api/compute/images/test_image_metadata.py
index 195a018..91eb4c5 100644
--- a/tempest/api/compute/images/test_image_metadata.py
+++ b/tempest/api/compute/images/test_image_metadata.py
@@ -24,14 +24,15 @@
 class ImagesMetadataTestJSON(base.BaseV2ComputeTest):
 
     @classmethod
+    @test.safe_setup
     def setUpClass(cls):
         super(ImagesMetadataTestJSON, cls).setUpClass()
         if not CONF.service_available.glance:
             skip_msg = ("%s skipped as glance is not available" % cls.__name__)
             raise cls.skipException(skip_msg)
 
-        cls.servers_client = cls.servers_client
         cls.client = cls.images_client
+        cls.image_id = None
 
         resp, server = cls.create_test_server(wait_until='ACTIVE')
         cls.server_id = server['id']
@@ -45,7 +46,8 @@
 
     @classmethod
     def tearDownClass(cls):
-        cls.client.delete_image(cls.image_id)
+        if cls.image_id:
+            cls.client.delete_image(cls.image_id)
         super(ImagesMetadataTestJSON, cls).tearDownClass()
 
     def setUp(self):
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 837114c..f0913f1 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -26,6 +26,7 @@
 class ListServerFiltersTestJSON(base.BaseV2ComputeTest):
 
     @classmethod
+    @test.safe_setup
     def setUpClass(cls):
         super(ListServerFiltersTestJSON, cls).setUpClass()
         cls.client = cls.servers_client
diff --git a/tempest/api/compute/v3/servers/test_list_server_filters.py b/tempest/api/compute/v3/servers/test_list_server_filters.py
index ec31e8e..2cb176c 100644
--- a/tempest/api/compute/v3/servers/test_list_server_filters.py
+++ b/tempest/api/compute/v3/servers/test_list_server_filters.py
@@ -26,6 +26,7 @@
 class ListServerFiltersV3Test(base.BaseV3ComputeTest):
 
     @classmethod
+    @test.safe_setup
     def setUpClass(cls):
         super(ListServerFiltersV3Test, cls).setUpClass()
         cls.client = cls.servers_client
diff --git a/tempest/test.py b/tempest/test.py
index 804f17f..6290761 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -66,6 +66,25 @@
     return decorator
 
 
+def safe_setup(f):
+    """A decorator used to wrap the setUpClass for cleaning up resources
+       when setUpClass failed.
+    """
+
+    def decorator(cls):
+            try:
+                f(cls)
+            except Exception as se:
+                LOG.exception("setUpClass failed: %s" % se)
+                try:
+                    cls.tearDownClass()
+                except Exception as te:
+                    LOG.exception("tearDownClass failed: %s" % te)
+                raise se
+
+    return decorator
+
+
 def services(*args, **kwargs):
     """A decorator used to set an attr for each service used in a test case