Merge "removes self.fail as suggested by HACKING.rst"
diff --git a/tempest/api/compute/keypairs/test_keypairs.py b/tempest/api/compute/keypairs/test_keypairs.py
index e4e87c0..4848cce 100644
--- a/tempest/api/compute/keypairs/test_keypairs.py
+++ b/tempest/api/compute/keypairs/test_keypairs.py
@@ -84,23 +84,17 @@
         # Keypair should be created, Got details by name and deleted
         k_name = rand_name('keypair-')
         resp, keypair = self.client.create_keypair(k_name)
-        try:
-            resp, keypair_detail = self.client.get_keypair(k_name)
-            self.assertEqual(200, resp.status)
-            self.assertIn('name', keypair_detail)
-            self.assertIn('public_key', keypair_detail)
-            self.assertEqual(keypair_detail['name'], k_name,
-                             "The created keypair name is not equal "
-                             "to requested name")
-            public_key = keypair_detail['public_key']
-            self.assertTrue(public_key is not None,
-                            "Field public_key is empty or not found.")
-        except Exception:
-            self.fail("GET keypair details requested by keypair name "
-                      "has failed")
-        finally:
-            resp, _ = self.client.delete_keypair(k_name)
-            self.assertEqual(202, resp.status)
+        resp, keypair_detail = self.client.get_keypair(k_name)
+        self.assertEqual(200, resp.status)
+        self.addCleanup(self.client.delete_keypair, k_name)
+        self.assertIn('name', keypair_detail)
+        self.assertIn('public_key', keypair_detail)
+        self.assertEqual(keypair_detail['name'], k_name,
+                         "The created keypair name is not equal "
+                         "to requested name")
+        public_key = keypair_detail['public_key']
+        self.assertTrue(public_key is not None,
+                        "Field public_key is empty or not found.")
 
     @attr(type='gate')
     def test_keypair_create_with_pub_key(self):
diff --git a/tempest/api/compute/test_authorization.py b/tempest/api/compute/test_authorization.py
index 60297a9..efdadb0 100644
--- a/tempest/api/compute/test_authorization.py
+++ b/tempest/api/compute/test_authorization.py
@@ -21,8 +21,11 @@
 from tempest.common.utils.data_utils import parse_image_id
 from tempest.common.utils.data_utils import rand_name
 from tempest import exceptions
+from tempest.openstack.common import log as logging
 from tempest.test import attr
 
+LOG = logging.getLogger(__name__)
+
 
 class AuthorizationTestJSON(base.BaseComputeTest):
     _interface = 'json'
@@ -204,7 +207,7 @@
             self.alt_keypairs_client.base_url = self.saved_base_url
             if (resp['status'] is not None):
                 resp, _ = self.alt_keypairs_client.delete_keypair(k_name)
-                self.fail("Create keypair request should not happen "
+                LOG.error("Create keypair request should not happen "
                           "if the tenant id does not match the current user")
 
     @attr(type='gate')
@@ -255,7 +258,7 @@
             self.alt_security_client.base_url = self.saved_base_url
             if resp['status'] is not None:
                 self.alt_security_client.delete_security_group(resp['id'])
-                self.fail("Create Security Group request should not happen if"
+                LOG.error("Create Security Group request should not happen if"
                           "the tenant id does not match the current user")
 
     @attr(type='gate')
@@ -297,7 +300,7 @@
             self.alt_security_client.base_url = self.saved_base_url
             if resp['status'] is not None:
                 self.alt_security_client.delete_security_group_rule(resp['id'])
-                self.fail("Create security group rule request should not "
+                LOG.error("Create security group rule request should not "
                           "happen if the tenant id does not match the"
                           " current user")
 
diff --git a/tempest/api/identity/admin/v3/test_endpoints.py b/tempest/api/identity/admin/v3/test_endpoints.py
index d98fb71..9d143ed 100644
--- a/tempest/api/identity/admin/v3/test_endpoints.py
+++ b/tempest/api/identity/admin/v3/test_endpoints.py
@@ -68,44 +68,30 @@
                          ', '.join(str(e) for e in missing_endpoints))
 
     @attr(type='gate')
-    def test_create_delete_endpoint(self):
+    def test_create_list_delete_endpoint(self):
         region = rand_name('region')
         url = rand_name('url')
         interface = 'public'
-        create_flag = False
-        matched = False
-        try:
-            resp, endpoint =\
-                self.client.create_endpoint(self.service_id, interface, url,
-                                            region=region, enabled=True)
-            create_flag = True
-            # Asserting Create Endpoint response body
-            self.assertEqual(resp['status'], '201')
-            self.assertEqual(region, endpoint['region'])
-            self.assertEqual(url, endpoint['url'])
-            # Checking if created endpoint is present in the list of endpoints
-            resp, fetched_endpoints = self.client.list_endpoints()
-            for e in fetched_endpoints:
-                if endpoint['id'] == e['id']:
-                    matched = True
-            if not matched:
-                self.fail("Created endpoint does not appear in the list"
-                          " of endpoints")
-        finally:
-            if create_flag:
-                matched = False
-                # Deleting the endpoint created in this method
-                resp_header, resp_body =\
-                    self.client.delete_endpoint(endpoint['id'])
-                self.assertEqual(resp_header['status'], '204')
-                self.assertEqual(resp_body, '')
-                # Checking whether endpoint is deleted successfully
-                resp, fetched_endpoints = self.client.list_endpoints()
-                for e in fetched_endpoints:
-                    if endpoint['id'] == e['id']:
-                        matched = True
-                if matched:
-                    self.fail("Delete endpoint is not successful")
+        resp, endpoint =\
+            self.client.create_endpoint(self.service_id, interface, url,
+                                        region=region, enabled=True)
+        # Asserting Create Endpoint response body
+        self.assertEqual(resp['status'], '201')
+        self.assertIn('id', endpoint)
+        self.assertEqual(region, endpoint['region'])
+        self.assertEqual(url, endpoint['url'])
+        # Checking if created endpoint is present in the list of endpoints
+        resp, fetched_endpoints = self.client.list_endpoints()
+        fetched_endpoints_id = [e['id'] for e in fetched_endpoints]
+        self.assertIn(endpoint['id'], fetched_endpoints_id)
+        # Deleting the endpoint created in this method
+        resp, body = self.client.delete_endpoint(endpoint['id'])
+        self.assertEqual(resp['status'], '204')
+        self.assertEqual(body, '')
+        # Checking whether endpoint is deleted successfully
+        resp, fetched_endpoints = self.client.list_endpoints()
+        fetched_endpoints_id = [e['id'] for e in fetched_endpoints]
+        self.assertNotIn(endpoint['id'], fetched_endpoints_id)
 
     @attr(type='smoke')
     def test_update_endpoint(self):
diff --git a/tempest/api/object_storage/test_object_services.py b/tempest/api/object_storage/test_object_services.py
index c599562..dd724c7 100644
--- a/tempest/api/object_storage/test_object_services.py
+++ b/tempest/api/object_storage/test_object_services.py
@@ -211,24 +211,18 @@
                                                             object_name,
                                                             orig_metadata)
         self.assertIn(int(resp['status']), HTTP_SUCCESS)
-        try:
-            # copy object from source container to destination container
-            resp, _ = self.object_client.copy_object_across_containers(
-                src_container_name, object_name, dst_container_name,
-                object_name)
-            self.assertEqual(resp['status'], '201')
-
-            # check if object is present in destination container
-            resp, body = self.object_client.get_object(dst_container_name,
-                                                       object_name)
-            self.assertEqual(body, data)
-            actual_meta_key = 'x-object-meta-' + meta_key
-            self.assertTrue(actual_meta_key in resp)
-            self.assertEqual(resp[actual_meta_key], meta_value)
-
-        except Exception as e:
-            self.fail("Got exception :%s ; while copying"
-                      " object across containers" % e)
+        # copy object from source container to destination container
+        resp, _ = self.object_client.copy_object_across_containers(
+            src_container_name, object_name, dst_container_name,
+            object_name)
+        self.assertEqual(resp['status'], '201')
+        # check if object is present in destination container
+        resp, body = self.object_client.get_object(dst_container_name,
+                                                   object_name)
+        self.assertEqual(body, data)
+        actual_meta_key = 'x-object-meta-' + meta_key
+        self.assertTrue(actual_meta_key in resp)
+        self.assertEqual(resp[actual_meta_key], meta_value)
 
     @attr(type='gate')
     def test_get_object_using_temp_url(self):
@@ -367,36 +361,32 @@
     def test_access_public_object_with_another_user_creds(self):
         # make container public-readable and access an object in it using
         # another user's credentials
-        try:
-            cont_headers = {'X-Container-Read': '.r:*,.rlistings'}
-            resp_meta, body = self.container_client.update_container_metadata(
-                self.container_name, metadata=cont_headers,
-                metadata_prefix='')
-            self.assertIn(int(resp_meta['status']), HTTP_SUCCESS)
-            # create object
-            object_name = rand_name(name='Object')
-            data = arbitrary_string(size=len(object_name) * 1,
-                                    base_text=object_name)
-            resp, _ = self.object_client.create_object(self.container_name,
-                                                       object_name, data)
-            self.assertEqual(resp['status'], '201')
+        cont_headers = {'X-Container-Read': '.r:*,.rlistings'}
+        resp_meta, body = self.container_client.update_container_metadata(
+            self.container_name, metadata=cont_headers,
+            metadata_prefix='')
+        self.assertIn(int(resp_meta['status']), HTTP_SUCCESS)
 
-            # list container metadata
-            resp, _ = self.container_client.list_container_metadata(
-                self.container_name)
-            self.assertIn(int(resp['status']), HTTP_SUCCESS)
-            self.assertIn('x-container-read', resp)
-            self.assertEqual(resp['x-container-read'], '.r:*,.rlistings')
+        # create object
+        object_name = rand_name(name='Object')
+        data = arbitrary_string(size=len(object_name) * 1,
+                                base_text=object_name)
+        resp, _ = self.object_client.create_object(self.container_name,
+                                                   object_name, data)
+        self.assertEqual(resp['status'], '201')
 
-            # get auth token of alternative user
-            token = self.identity_client_alt.get_auth()
-            headers = {'X-Auth-Token': token}
-            # access object using alternate user creds
-            resp, body = self.custom_object_client.get_object(
-                self.container_name, object_name,
-                metadata=headers)
-            self.assertEqual(body, data)
+        # list container metadata
+        resp, _ = self.container_client.list_container_metadata(
+            self.container_name)
+        self.assertIn(int(resp['status']), HTTP_SUCCESS)
+        self.assertIn('x-container-read', resp)
+        self.assertEqual(resp['x-container-read'], '.r:*,.rlistings')
 
-        except Exception as e:
-            self.fail("Failed to get public readable object with another"
-                      " user creds raised exception is %s" % e)
+        # get auth token of alternative user
+        token = self.identity_client_alt.get_auth()
+        headers = {'X-Auth-Token': token}
+        # access object using alternate user creds
+        resp, body = self.custom_object_client.get_object(
+            self.container_name, object_name,
+            metadata=headers)
+        self.assertEqual(body, data)
diff --git a/tempest/api/volume/test_volumes_actions.py b/tempest/api/volume/test_volumes_actions.py
index 5861497..2a1e2c4 100644
--- a/tempest/api/volume/test_volumes_actions.py
+++ b/tempest/api/volume/test_volumes_actions.py
@@ -55,20 +55,15 @@
     @attr(type='smoke')
     def test_attach_detach_volume_to_instance(self):
         # Volume is attached and detached successfully from an instance
-        try:
-            mountpoint = '/dev/vdc'
-            resp, body = self.client.attach_volume(self.volume['id'],
-                                                   self.server['id'],
-                                                   mountpoint)
-            self.assertEqual(202, resp.status)
-            self.client.wait_for_volume_status(self.volume['id'], 'in-use')
-        except Exception:
-            self.fail("Could not attach volume to instance")
-        finally:
-            # Detach the volume from the instance
-            resp, body = self.client.detach_volume(self.volume['id'])
-            self.assertEqual(202, resp.status)
-            self.client.wait_for_volume_status(self.volume['id'], 'available')
+        mountpoint = '/dev/vdc'
+        resp, body = self.client.attach_volume(self.volume['id'],
+                                               self.server['id'],
+                                               mountpoint)
+        self.assertEqual(202, resp.status)
+        self.client.wait_for_volume_status(self.volume['id'], 'in-use')
+        resp, body = self.client.detach_volume(self.volume['id'])
+        self.assertEqual(202, resp.status)
+        self.client.wait_for_volume_status(self.volume['id'], 'available')
 
     @attr(type='gate')
     def test_get_volume_attachment(self):
@@ -77,22 +72,22 @@
         resp, body = self.client.attach_volume(self.volume['id'],
                                                self.server['id'],
                                                mountpoint)
-        self.client.wait_for_volume_status(self.volume['id'], 'in-use')
         self.assertEqual(202, resp.status)
-        try:
-            resp, volume = self.client.get_volume(self.volume['id'])
-            self.assertEqual(200, resp.status)
-            self.assertIn('attachments', volume)
-            attachment = volume['attachments'][0]
-            self.assertEqual(mountpoint, attachment['device'])
-            self.assertEqual(self.server['id'], attachment['server_id'])
-            self.assertEqual(self.volume['id'], attachment['id'])
-            self.assertEqual(self.volume['id'], attachment['volume_id'])
-        except Exception:
-            self.fail("Could not get attachment details from volume")
-        finally:
-            self.client.detach_volume(self.volume['id'])
-            self.client.wait_for_volume_status(self.volume['id'], 'available')
+        self.client.wait_for_volume_status(self.volume['id'], 'in-use')
+        # NOTE(gfidente): added in reverse order because functions will be
+        # called in reverse order to the order they are added (LIFO)
+        self.addCleanup(self.client.wait_for_volume_status,
+                        self.volume['id'],
+                        'available')
+        self.addCleanup(self.client.detach_volume, self.volume['id'])
+        resp, volume = self.client.get_volume(self.volume['id'])
+        self.assertEqual(200, resp.status)
+        self.assertIn('attachments', volume)
+        attachment = volume['attachments'][0]
+        self.assertEqual(mountpoint, attachment['device'])
+        self.assertEqual(self.server['id'], attachment['server_id'])
+        self.assertEqual(self.volume['id'], attachment['id'])
+        self.assertEqual(self.volume['id'], attachment['volume_id'])
 
     @attr(type='gate')
     def test_volume_upload(self):
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index e93d9bc..886bf3a 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -29,12 +29,12 @@
 import neutronclient.v2_0.client
 import novaclient.client
 
-
 from tempest.api.network import common as net_common
 from tempest.common import isolated_creds
 from tempest.common import ssh
 from tempest.common.utils.data_utils import rand_name
 from tempest.common.utils.linux.remote_client import RemoteClient
+from tempest import exceptions
 import tempest.manager
 from tempest.openstack.common import log as logging
 import tempest.test
@@ -283,9 +283,9 @@
             thing = things.get(thing_id)
             new_status = thing.status
             if new_status == 'ERROR':
-                self.fail("%s failed to get to expected status. "
-                          "In ERROR state."
-                          % thing)
+                message = "%s failed to get to expected status. \
+                          In ERROR state." % (thing)
+                raise exceptions.BuildErrorException(message)
             elif new_status == expected_status:
                 return True  # All good.
             LOG.debug("Waiting for %s to get to %s status. "
@@ -295,8 +295,9 @@
             check_status,
             self.config.compute.build_timeout,
             self.config.compute.build_interval):
-            self.fail("Timed out waiting for thing %s to become %s"
-                      % (thing_id, expected_status))
+            message = "Timed out waiting for thing %s \
+                      to become %s" % (thing_id, expected_status)
+            raise exceptions.TimeoutException(message)
 
     def create_loginable_secgroup_rule(self, client=None, secgroup_id=None):
         if client is None:
@@ -343,11 +344,8 @@
         LOG.debug("Creating a server (name: %s, image: %s, flavor: %s)",
                   name, image, flavor)
         server = client.servers.create(name, image, flavor, **create_kwargs)
-        try:
-            self.assertEqual(server.name, name)
-            self.set_resource(name, server)
-        except AttributeError:
-            self.fail("Server not successfully created.")
+        self.assertEqual(server.name, name)
+        self.set_resource(name, server)
         self.status_timeout(client.servers, server.id, 'ACTIVE')
         # The instance retrieved on creation is missing network
         # details, necessitating retrieval after it becomes active to
@@ -429,12 +427,9 @@
         sg_name = rand_name(namestart)
         sg_desc = sg_name + " description"
         secgroup = client.security_groups.create(sg_name, sg_desc)
-        try:
-            self.assertEqual(secgroup.name, sg_name)
-            self.assertEqual(secgroup.description, sg_desc)
-            self.set_resource(sg_name, secgroup)
-        except AttributeError:
-            self.fail("SecurityGroup object not successfully created.")
+        self.assertEqual(secgroup.name, sg_name)
+        self.assertEqual(secgroup.description, sg_desc)
+        self.set_resource(sg_name, secgroup)
 
         # Add rules to the security group
         self.create_loginable_secgroup_rule(client, secgroup.id)
diff --git a/tempest/scenario/test_server_basic_ops.py b/tempest/scenario/test_server_basic_ops.py
index 2903687..8e14b06 100644
--- a/tempest/scenario/test_server_basic_ops.py
+++ b/tempest/scenario/test_server_basic_ops.py
@@ -44,12 +44,9 @@
         sg_desc = sg_name + " description"
         self.secgroup = self.compute_client.security_groups.create(sg_name,
                                                                    sg_desc)
-        try:
-            self.assertEqual(self.secgroup.name, sg_name)
-            self.assertEqual(self.secgroup.description, sg_desc)
-            self.set_resource('secgroup', self.secgroup)
-        except AttributeError:
-            self.fail("SecurityGroup object not successfully created.")
+        self.assertEqual(self.secgroup.name, sg_name)
+        self.assertEqual(self.secgroup.description, sg_desc)
+        self.set_resource('secgroup', self.secgroup)
 
         # Add rules to the security group
         self.create_loginable_secgroup_rule(secgroup_id=self.secgroup.id)
diff --git a/tempest/whitebox/test_images_whitebox.py b/tempest/whitebox/test_images_whitebox.py
index 0afb17e..06dcd7f 100644
--- a/tempest/whitebox/test_images_whitebox.py
+++ b/tempest/whitebox/test_images_whitebox.py
@@ -16,10 +16,13 @@
 #    under the License.
 
 from tempest.common.utils.data_utils import rand_name
+from tempest.openstack.common import log as logging
 from tempest.whitebox import manager
 
 from novaclient import exceptions
 
+LOG = logging.getLogger(__name__)
+
 
 class ImagesWhiteboxTest(manager.ComputeWhiteboxTest):
     _interface = 'json'
@@ -65,8 +68,9 @@
                               self.create_image,
                               self.shared_server.id, image_name)
         except Exception:
-            self.fail("Should not allow create image when vm_state=%s and "
+            LOG.error("Should not allow create image when vm_state=%s and "
                       "task_state=%s" % (vm_state, task_state))
+            raise
         finally:
             self.update_state(self.shared_server.id, 'active', None)
 
diff --git a/tempest/whitebox/test_servers_whitebox.py b/tempest/whitebox/test_servers_whitebox.py
index abe903c..b6c888c 100644
--- a/tempest/whitebox/test_servers_whitebox.py
+++ b/tempest/whitebox/test_servers_whitebox.py
@@ -17,8 +17,11 @@
 
 from tempest.api.identity.base import BaseIdentityAdminTest
 from tempest import exceptions
+from tempest.openstack.common import log as logging
 from tempest.whitebox import manager
 
+LOG = logging.getLogger(__name__)
+
 
 class ServersWhiteboxTest(manager.ComputeWhiteboxTest):
     _interface = 'json'
@@ -66,25 +69,21 @@
         Base method for delete server tests based on vm and task states.
         Validates for successful server termination.
         """
-        try:
-            server = self.create_server()
-            self.update_state(server['id'], vm_state, task_state)
+        server = self.create_server()
+        self.update_state(server['id'], vm_state, task_state)
 
-            resp, body = self.client.delete_server(server['id'])
-            self.assertEqual('204', resp['status'])
-            self.client.wait_for_server_termination(server['id'],
-                                                    ignore_error=True)
+        resp, body = self.client.delete_server(server['id'])
+        self.assertEqual('204', resp['status'])
+        self.client.wait_for_server_termination(server['id'],
+                                                ignore_error=True)
 
-            instances = self.meta.tables['instances']
-            stmt = instances.select().where(instances.c.uuid == server['id'])
-            result = self.connection.execute(stmt).first()
+        instances = self.meta.tables['instances']
+        stmt = instances.select().where(instances.c.uuid == server['id'])
+        result = self.connection.execute(stmt).first()
 
-            self.assertEqual(True, result.deleted > 0)
-            self.assertEqual('deleted', result.vm_state)
-            self.assertEqual(None, result.task_state)
-        except Exception:
-            self.fail("Should be able to delete a server when vm_state=%s and "
-                      "task_state=%s" % (vm_state, task_state))
+        self.assertEqual(True, result.deleted > 0)
+        self.assertEqual('deleted', result.vm_state)
+        self.assertEqual(None, result.task_state)
 
     def _test_delete_server_403_base(self, vm_state, task_state):
         """
@@ -98,8 +97,9 @@
                               self.client.delete_server,
                               self.shared_server['id'])
         except Exception:
-            self.fail("Should not allow delete server when vm_state=%s and "
+            LOG.error("Should not allow delete server when vm_state=%s and "
                       "task_state=%s" % (vm_state, task_state))
+            raise
         finally:
             self.update_state(self.shared_server['id'], 'active', None)