Merge "Added tests to list instances by regexp"
diff --git a/.gitignore b/.gitignore
index c154603..f5f51ab 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
 ChangeLog
 *.pyc
 etc/tempest.conf
+etc/logging.conf
 include/swift_objects/swift_small
 include/swift_objects/swift_medium
 include/swift_objects/swift_large
diff --git a/cli/__init__.py b/cli/__init__.py
index 7a92260..a3038d2 100644
--- a/cli/__init__.py
+++ b/cli/__init__.py
@@ -87,6 +87,15 @@
         flags = creds + ' ' + flags
         return self.cmd(cmd, action, flags, params, fail_ok)
 
+    def check_output(self, cmd, **kwargs):
+        # substitutes subprocess.check_output which is not in python2.6
+        kwargs['stdout'] = subprocess.PIPE
+        proc = subprocess.Popen(cmd, **kwargs)
+        output = proc.communicate()[0]
+        if proc.returncode != 0:
+            raise CommandFailed(proc.returncode, cmd, output)
+        return output
+
     def cmd(self, cmd, action, flags='', params='', fail_ok=False,
             merge_stderr=False):
         """Executes specified command for the given action."""
@@ -96,10 +105,10 @@
         cmd = shlex.split(cmd)
         try:
             if merge_stderr:
-                result = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
+                result = self.check_output(cmd, stderr=subprocess.STDOUT)
             else:
-                devnull = open('/dev/null', 'w')
-                result = subprocess.check_output(cmd, stderr=devnull)
+                with open('/dev/null', 'w') as devnull:
+                    result = self.check_output(cmd, stderr=devnull)
         except subprocess.CalledProcessError, e:
             LOG.error("command output:\n%s" % e.output)
             raise
@@ -110,3 +119,10 @@
         for item in items:
             for field in field_names:
                 self.assertIn(field, item)
+
+
+class CommandFailed(subprocess.CalledProcessError):
+    # adds output attribute for python2.6
+    def __init__(self, returncode, cmd, output):
+        super(CommandFailed, self).__init__(returncode, cmd)
+        self.output = output
diff --git a/stress/driver.py b/stress/driver.py
index f80e765..9604318 100644
--- a/stress/driver.py
+++ b/stress/driver.py
@@ -261,7 +261,7 @@
         state.delete_instance_state(kill_id)
     for floating_ip_state in state.get_floating_ips():
         manager.floating_ips_client.delete_floating_ip(
-                                            floating_ip_state.resource_id)
+            floating_ip_state.resource_id)
     for keypair_state in state.get_keypairs():
         manager.keypairs_client.delete_keypair(keypair_state.name)
     for volume_state in state.get_volumes():
diff --git a/tempest/clients.py b/tempest/clients.py
index 642f009..732a982 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -22,13 +22,18 @@
 from tempest.services import botoclients
 from tempest.services.compute.json.aggregates_client import \
     AggregatesClientJSON
+from tempest.services.compute.json.availability_zone_client import \
+    AvailabilityZoneClientJSON
 from tempest.services.compute.json.extensions_client import \
     ExtensionsClientJSON
+from tempest.services.compute.json.fixed_ips_client import FixedIPsClientJSON
 from tempest.services.compute.json.flavors_client import FlavorsClientJSON
 from tempest.services.compute.json.floating_ips_client import \
     FloatingIPsClientJSON
 from tempest.services.compute.json.hosts_client import HostsClientJSON
 from tempest.services.compute.json.images_client import ImagesClientJSON
+from tempest.services.compute.json.interfaces_client import \
+    InterfacesClientJSON
 from tempest.services.compute.json.keypairs_client import KeyPairsClientJSON
 from tempest.services.compute.json.limits_client import LimitsClientJSON
 from tempest.services.compute.json.quotas_client import QuotasClientJSON
@@ -37,11 +42,16 @@
 from tempest.services.compute.json.servers_client import ServersClientJSON
 from tempest.services.compute.json.volumes_extensions_client import \
     VolumesExtensionsClientJSON
+from tempest.services.compute.xml.availability_zone_client import \
+    AvailabilityZoneClientXML
 from tempest.services.compute.xml.extensions_client import ExtensionsClientXML
+from tempest.services.compute.xml.fixed_ips_client import FixedIPsClientXML
 from tempest.services.compute.xml.flavors_client import FlavorsClientXML
 from tempest.services.compute.xml.floating_ips_client import \
     FloatingIPsClientXML
 from tempest.services.compute.xml.images_client import ImagesClientXML
+from tempest.services.compute.xml.interfaces_client import \
+    InterfacesClientXML
 from tempest.services.compute.xml.keypairs_client import KeyPairsClientXML
 from tempest.services.compute.xml.limits_client import LimitsClientXML
 from tempest.services.compute.xml.quotas_client import QuotasClientXML
@@ -50,10 +60,10 @@
 from tempest.services.compute.xml.servers_client import ServersClientXML
 from tempest.services.compute.xml.volumes_extensions_client import \
     VolumesExtensionsClientXML
-from tempest.services.identity.v3.json.endpoints_client import \
-    EndPointClientJSON
 from tempest.services.identity.json.identity_client import IdentityClientJSON
 from tempest.services.identity.json.identity_client import TokenClientJSON
+from tempest.services.identity.v3.json.endpoints_client import \
+    EndPointClientJSON
 from tempest.services.identity.v3.xml.endpoints_client import EndPointClientXML
 from tempest.services.identity.xml.identity_client import IdentityClientXML
 from tempest.services.identity.xml.identity_client import TokenClientXML
@@ -75,12 +85,6 @@
     VolumeTypesClientXML
 from tempest.services.volume.xml.snapshots_client import SnapshotsClientXML
 from tempest.services.volume.xml.volumes_client import VolumesClientXML
-from tempest.services.compute.json.interfaces_client import \
-    InterfacesClientJSON
-from tempest.services.compute.xml.interfaces_client import \
-    InterfacesClientXML
-from tempest.services.compute.json.fixed_ips_client import FixedIPsClientJSON
-from tempest.services.compute.xml.fixed_ips_client import FixedIPsClientXML
 
 LOG = logging.getLogger(__name__)
 
@@ -174,6 +178,11 @@
     "xml": FixedIPsClientXML
 }
 
+AVAILABILITY_ZONE_CLIENT = {
+    "json": AvailabilityZoneClientJSON,
+    "xml": AvailabilityZoneClientXML,
+}
+
 
 class Manager(object):
 
@@ -238,6 +247,8 @@
             self.interfaces_client = INTERFACES_CLIENT[interface](*client_args)
             self.endpoints_client = ENDPOINT_CLIENT[interface](*client_args)
             self.fixed_ips_client = FIXED_IPS_CLIENT[interface](*client_args)
+            self.availability_zone_client = \
+                AVAILABILITY_ZONE_CLIENT[interface](*client_args)
         except KeyError:
             msg = "Unsupported interface type `%s'" % interface
             raise exceptions.InvalidConfiguration(msg)
diff --git a/tempest/common/ssh.py b/tempest/common/ssh.py
index be6fe27..263cf3f 100644
--- a/tempest/common/ssh.py
+++ b/tempest/common/ssh.py
@@ -117,8 +117,8 @@
             ready = select.select(*select_params)
             if not any(ready):
                 raise exceptions.TimeoutException(
-                        "Command: '{0}' executed on host '{1}'.".format(
-                            cmd, self.host))
+                    "Command: '{0}' executed on host '{1}'.".format(
+                        cmd, self.host))
             if not ready[0]:        # If there is nothing to read.
                 continue
             out_chunk = err_chunk = None
@@ -133,8 +133,8 @@
         exit_status = channel.recv_exit_status()
         if 0 != exit_status:
             raise exceptions.SSHExecCommandFailed(
-                    command=cmd, exit_status=exit_status,
-                    strerror=''.join(err_data))
+                command=cmd, exit_status=exit_status,
+                strerror=''.join(err_data))
         return ''.join(out_data)
 
     def test_connection_auth(self):
diff --git a/tempest/config.py b/tempest/config.py
index 9c41660..556e2a7 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -420,6 +420,9 @@
 
     def __init__(self):
         """Initialize a configuration from a conf directory and conf file."""
+        config_files = []
+
+        failsafe_path = "/etc/tempest/" + self.DEFAULT_CONFIG_FILE
 
         # Environment variables override defaults...
         conf_dir = os.environ.get('TEMPEST_CONFIG_DIR',
@@ -431,16 +434,17 @@
         if not (os.path.isfile(path) or
                 'TEMPEST_CONFIG_DIR' in os.environ or
                 'TEMPEST_CONFIG' in os.environ):
-            path = "/etc/tempest/" + self.DEFAULT_CONFIG_FILE
+            path = failsafe_path
 
         LOG.info("Using tempest config file %s" % path)
 
         if not os.path.exists(path):
             msg = "Config file %(path)s not found" % locals()
             print >> sys.stderr, RuntimeError(msg)
-            sys.exit(os.EX_NOINPUT)
+        else:
+            config_files.append(path)
 
-        cfg.CONF([], project='tempest', default_config_files=[path])
+        cfg.CONF([], project='tempest', default_config_files=config_files)
 
         register_compute_opts(cfg.CONF)
         register_identity_opts(cfg.CONF)
diff --git a/tempest/services/botoclients.py b/tempest/services/botoclients.py
index 0870c96..628151a 100644
--- a/tempest/services/botoclients.py
+++ b/tempest/services/botoclients.py
@@ -96,7 +96,7 @@
                     ec2_cred.secret
             else:
                 raise exceptions.InvalidConfiguration(
-                                    "Unable to get access and secret keys")
+                    "Unable to get access and secret keys")
         return self.connect_method(**self.connection_data)
 
 
diff --git a/tempest/services/compute/json/availability_zone_client.py b/tempest/services/compute/json/availability_zone_client.py
new file mode 100644
index 0000000..b11871b
--- /dev/null
+++ b/tempest/services/compute/json/availability_zone_client.py
@@ -0,0 +1,39 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 NEC Corporation.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import json
+
+from tempest.common.rest_client import RestClient
+
+
+class AvailabilityZoneClientJSON(RestClient):
+
+    def __init__(self, config, username, password, auth_url, tenant_name=None):
+        super(AvailabilityZoneClientJSON, self).__init__(config, username,
+                                                         password, auth_url,
+                                                         tenant_name)
+        self.service = self.config.compute.catalog_type
+
+    def get_availability_zone_list(self):
+        resp, body = self.get('os-availability-zone')
+        body = json.loads(body)
+        return resp, body['availabilityZoneInfo']
+
+    def get_availability_zone_list_detail(self):
+        resp, body = self.get('os-availability-zone/detail')
+        body = json.loads(body)
+        return resp, body['availabilityZoneInfo']
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index 9e71f3d..3569b50 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -390,3 +390,17 @@
     def unrescue_server(self, server_id):
         """Unrescue the provided server."""
         return self.action(server_id, 'unrescue', None)
+
+    def list_instance_actions(self, server_id):
+        """List the provided server action."""
+        resp, body = self.get("servers/%s/os-instance-actions" %
+                              str(server_id))
+        body = json.loads(body)
+        return resp, body['instanceActions']
+
+    def get_instance_action(self, server_id, request_id):
+        """Returns the action details of the provided server."""
+        resp, body = self.get("servers/%s/os-instance-actions/%s" %
+                              (str(server_id), str(request_id)))
+        body = json.loads(body)
+        return resp, body['instanceAction']
diff --git a/tempest/services/compute/xml/availability_zone_client.py b/tempest/services/compute/xml/availability_zone_client.py
new file mode 100644
index 0000000..ae93774
--- /dev/null
+++ b/tempest/services/compute/xml/availability_zone_client.py
@@ -0,0 +1,43 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 NEC Corporation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from lxml import etree
+
+from tempest.common.rest_client import RestClientXML
+from tempest.services.compute.xml.common import xml_to_json
+
+
+class AvailabilityZoneClientXML(RestClientXML):
+
+    def __init__(self, config, username, password, auth_url, tenant_name=None):
+        super(AvailabilityZoneClientXML, self).__init__(config, username,
+                                                        password, auth_url,
+                                                        tenant_name)
+        self.service = self.config.compute.catalog_type
+
+    def _parse_array(self, node):
+        return [xml_to_json(x) for x in node]
+
+    def get_availability_zone_list(self):
+        resp, body = self.get('os-availability-zone', self.headers)
+        availability_zone = self._parse_array(etree.fromstring(body))
+        return resp, availability_zone
+
+    def get_availability_zone_list_detail(self):
+        resp, body = self.get('os-availability-zone/detail', self.headers)
+        availability_zone = self._parse_array(etree.fromstring(body))
+        return resp, availability_zone
diff --git a/tempest/services/compute/xml/security_groups_client.py b/tempest/services/compute/xml/security_groups_client.py
index 4fccc29..08b381c 100644
--- a/tempest/services/compute/xml/security_groups_client.py
+++ b/tempest/services/compute/xml/security_groups_client.py
@@ -31,8 +31,8 @@
 
     def __init__(self, config, username, password, auth_url, tenant_name=None):
         super(SecurityGroupsClientXML, self).__init__(
-                                        config, username, password,
-                                        auth_url, tenant_name)
+            config, username, password,
+            auth_url, tenant_name)
         self.service = self.config.compute.catalog_type
 
     def _parse_array(self, node):
diff --git a/tempest/services/compute/xml/servers_client.py b/tempest/services/compute/xml/servers_client.py
index 331d560..f7e8915 100644
--- a/tempest/services/compute/xml/servers_client.py
+++ b/tempest/services/compute/xml/servers_client.py
@@ -527,3 +527,17 @@
         resp, body = self.delete('servers/%s/os-volume_attachments/%s' %
                                  (server_id, volume_id), headers)
         return resp, body
+
+    def list_instance_actions(self, server_id):
+        """List the provided server action."""
+        resp, body = self.get("servers/%s/os-instance-actions" % server_id,
+                              self.headers)
+        body = self._parse_array(etree.fromstring(body))
+        return resp, body
+
+    def get_instance_action(self, server_id, request_id):
+        """Returns the action details of the provided server."""
+        resp, body = self.get("servers/%s/os-instance-actions/%s" %
+                              (server_id, request_id), self.headers)
+        body = xml_to_json(etree.fromstring(body))
+        return resp, body
diff --git a/tempest/services/identity/json/identity_client.py b/tempest/services/identity/json/identity_client.py
index 5b6eaa0..c806949 100644
--- a/tempest/services/identity/json/identity_client.py
+++ b/tempest/services/identity/json/identity_client.py
@@ -152,7 +152,7 @@
     def enable_disable_user(self, user_id, enabled):
         """Enables or disables a user."""
         put_body = {
-                'enabled': enabled
+            'enabled': enabled
         }
         put_body = json.dumps({'user': put_body})
         resp, body = self.put('users/%s/enabled' % user_id,
diff --git a/tempest/services/volume/json/snapshots_client.py b/tempest/services/volume/json/snapshots_client.py
index 9545d0b..db614f1 100644
--- a/tempest/services/volume/json/snapshots_client.py
+++ b/tempest/services/volume/json/snapshots_client.py
@@ -84,7 +84,7 @@
         # state in a "normal" lifecycle
         if (status == 'error'):
             raise exceptions.SnapshotBuildErrorException(
-                    snapshot_id=snapshot_id)
+                snapshot_id=snapshot_id)
 
         return status
 
diff --git a/tempest/services/volume/xml/snapshots_client.py b/tempest/services/volume/xml/snapshots_client.py
index 89ea89f..2209fc7 100644
--- a/tempest/services/volume/xml/snapshots_client.py
+++ b/tempest/services/volume/xml/snapshots_client.py
@@ -93,7 +93,7 @@
         # state in a "normal" lifecycle
         if (status == 'error'):
             raise exceptions.SnapshotBuildErrorException(
-                    snapshot_id=snapshot_id)
+                snapshot_id=snapshot_id)
 
         return status
 
diff --git a/tempest/test.py b/tempest/test.py
index ccb2251..4db9827 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -56,6 +56,11 @@
         #NOTE(afazekas): inspection workaround
         BaseTestCase.config = config.TempestConfig()
 
+    @classmethod
+    def setUpClass(cls):
+        if hasattr(super(BaseTestCase, cls), 'setUpClass'):
+            super(BaseTestCase, cls).setUpClass()
+
 
 class TestCase(BaseTestCase):
     """Base test case class for all Tempest tests
@@ -115,7 +120,7 @@
     return False
 
 
-def status_timeout(things, thing_id, expected_status):
+def status_timeout(testcase, things, thing_id, expected_status):
     """
     Given a thing and an expected status, do a loop, sleeping
     for a configurable amount of time, checking for the
@@ -129,9 +134,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)
+            testcase.fail("%s failed to get to expected status."
+                          "In ERROR state."
+                          % thing)
         elif new_status == expected_status:
             return True  # All good.
         LOG.debug("Waiting for %s to get to %s status. "
@@ -141,8 +146,8 @@
     if not call_until_true(check_status,
                            conf.compute.build_timeout,
                            conf.compute.build_interval):
-        self.fail("Timed out waiting for thing %s to become %s"
-                  % (thing_id, expected_status))
+        testcase.fail("Timed out waiting for thing %s to become %s"
+                      % (thing_id, expected_status))
 
 
 class DefaultClientSmokeTest(TestCase):
diff --git a/tempest/testboto.py b/tempest/testboto.py
index cee8843..8b819d9 100644
--- a/tempest/testboto.py
+++ b/tempest/testboto.py
@@ -282,9 +282,10 @@
 
     @classmethod
     def get_lfunction_gone(cls, obj):
-        """ If the object is instance of a well know type returns back with
+        """If the object is instance of a well know type returns back with
             with the correspoding function otherwise it assumes the obj itself
-            is the function"""
+            is the function.
+            """
         ec = cls.ec2_error_code
         if isinstance(obj, ec2.instance.Instance):
             colusure_matcher = ec.client.InvalidInstanceID.NotFound
@@ -442,7 +443,7 @@
                 return "_GONE"
             except exception.EC2ResponseError as exc:
                 if cls.ec2_error_code.\
-                client.InvalidInstanceID.NotFound.match(exc):
+                        client.InvalidInstanceID.NotFound.match(exc):
                     return "_GONE"
                 #NOTE(afazekas): incorrect code,
                 # but the resource must be destoreyd
diff --git a/tempest/tests/boto/test_ec2_instance_run.py b/tempest/tests/boto/test_ec2_instance_run.py
index 3293dea..08dc330 100644
--- a/tempest/tests/boto/test_ec2_instance_run.py
+++ b/tempest/tests/boto/test_ec2_instance_run.py
@@ -73,8 +73,8 @@
                        "location": cls.bucket_name + "/" + ari_manifest}}
         for image in cls.images.itervalues():
             image["image_id"] = cls.ec2_client.register_image(
-                                name=image["name"],
-                                image_location=image["location"])
+                name=image["name"],
+                image_location=image["location"])
             cls.addResourceCleanUp(cls.ec2_client.deregister_image,
                                    image["image_id"])
 
@@ -151,13 +151,15 @@
                                                                group_desc)
         self.addResourceCleanUp(self.destroy_security_group_wait,
                                 security_group)
-        self.assertTrue(self.ec2_client.authorize_security_group(
+        self.assertTrue(
+            self.ec2_client.authorize_security_group(
                 sec_group_name,
                 ip_protocol="icmp",
                 cidr_ip="0.0.0.0/0",
                 from_port=-1,
                 to_port=-1))
-        self.assertTrue(self.ec2_client.authorize_security_group(
+        self.assertTrue(
+            self.ec2_client.authorize_security_group(
                 sec_group_name,
                 ip_protocol="tcp",
                 cidr_ip="0.0.0.0/0",
diff --git a/tempest/tests/boto/test_s3_ec2_images.py b/tempest/tests/boto/test_s3_ec2_images.py
index 4068aba..f77743e 100644
--- a/tempest/tests/boto/test_s3_ec2_images.py
+++ b/tempest/tests/boto/test_s3_ec2_images.py
@@ -63,12 +63,12 @@
                  "location": self.bucket_name + "/" + self.ami_manifest,
                  "type": "ami"}
         image["image_id"] = self.images_client.register_image(
-                            name=image["name"],
-                            image_location=image["location"])
+            name=image["name"],
+            image_location=image["location"])
         #Note(afazekas): delete_snapshot=True might trigger boto lib? bug
         image["cleanUp"] = self.addResourceCleanUp(
-                                self.images_client.deregister_image,
-                                image["image_id"])
+            self.images_client.deregister_image,
+            image["image_id"])
         self.assertEqual(image["image_id"][0:3], image["type"])
         retrieved_image = self.images_client.get_image(image["image_id"])
         self.assertTrue(retrieved_image.name == image["name"])
@@ -90,11 +90,11 @@
                  "location": self.bucket_name + "/" + self.ari_manifest,
                  "type": "aki"}
         image["image_id"] = self.images_client.register_image(
-                            name=image["name"],
-                            image_location=image["location"])
+            name=image["name"],
+            image_location=image["location"])
         image["cleanUp"] = self.addResourceCleanUp(
-                                self.images_client.deregister_image,
-                                image["image_id"])
+            self.images_client.deregister_image,
+            image["image_id"])
         self.assertEqual(image["image_id"][0:3], image["type"])
         retrieved_image = self.images_client.get_image(image["image_id"])
         self.assertTrue(retrieved_image.name == image["name"])
@@ -115,11 +115,11 @@
                  "location": "/" + self.bucket_name + "/" + self.ari_manifest,
                  "type": "ari"}
         image["image_id"] = self.images_client.register_image(
-                            name=image["name"],
-                            image_location=image["location"])
+            name=image["name"],
+            image_location=image["location"])
         image["cleanUp"] = self.addResourceCleanUp(
-                                self.images_client.deregister_image,
-                                image["image_id"])
+            self.images_client.deregister_image,
+            image["image_id"])
         self.assertEqual(image["image_id"][0:3], image["type"])
         retrieved_image = self.images_client.get_image(image["image_id"])
         self.assertIn(retrieved_image.state, self.valid_image_state)
diff --git a/tempest/tests/compute/admin/test_availability_zone.py b/tempest/tests/compute/admin/test_availability_zone.py
new file mode 100644
index 0000000..98ad49c
--- /dev/null
+++ b/tempest/tests/compute/admin/test_availability_zone.py
@@ -0,0 +1,69 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 NEC Corporation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest import exceptions
+from tempest.test import attr
+from tempest.tests.compute import base
+
+
+class AvailabilityZoneAdminTestJSON(base.BaseComputeAdminTest):
+
+    """
+    Tests Availability Zone API List that require admin privileges
+    """
+
+    _interface = 'json'
+
+    @classmethod
+    def setUpClass(cls):
+        super(AvailabilityZoneAdminTestJSON, cls).setUpClass()
+        cls.client = cls.os_adm.availability_zone_client
+        cls.non_adm_client = cls.availability_zone_client
+
+    @attr('positive')
+    def test_get_availability_zone_list(self):
+        # List of availability zone
+        resp, availability_zone = self.client.get_availability_zone_list()
+        self.assertEqual(200, resp.status)
+        self.assertTrue(len(availability_zone) > 0)
+
+    @attr('positive')
+    def test_get_availability_zone_list_detail(self):
+        # List of availability zones and available services
+        resp, availability_zone = \
+            self.client.get_availability_zone_list_detail()
+        self.assertEqual(200, resp.status)
+        self.assertTrue(len(availability_zone) > 0)
+
+    @attr('positive')
+    def test_get_availability_zone_list_with_non_admin_user(self):
+        # List of availability zone with non admin user
+        resp, availability_zone = \
+            self.non_adm_client.get_availability_zone_list()
+        self.assertEqual(200, resp.status)
+        self.assertTrue(len(availability_zone) > 0)
+
+    @attr('negative')
+    def test_get_availability_zone_list_detail_with_non_admin_user(self):
+        # List of availability zones and available services with non admin user
+        self.assertRaises(
+            exceptions.Unauthorized,
+            self.non_adm_client.get_availability_zone_list_detail)
+
+
+class AvailabilityZoneAdminTestXML(AvailabilityZoneAdminTestJSON):
+    _interface = 'xml'
diff --git a/tempest/tests/compute/admin/test_flavors_extra_specs.py b/tempest/tests/compute/admin/test_flavors_extra_specs.py
index 01bff98..31a2511 100644
--- a/tempest/tests/compute/admin/test_flavors_extra_specs.py
+++ b/tempest/tests/compute/admin/test_flavors_extra_specs.py
@@ -92,9 +92,9 @@
     def test_flavor_non_admin_get_keys(self):
         specs = {"key1": "value1", "key2": "value2"}
         set_resp, set_body = self.client.set_flavor_extra_spec(
-                                                self.flavor['id'], specs)
+            self.flavor['id'], specs)
         resp, body = self.flavors_client.get_flavor_extra_spec(
-                                                            self.flavor['id'])
+            self.flavor['id'])
         self.assertEqual(resp.status, 200)
         for key in specs:
             self.assertEquals(body[key], specs[key])
@@ -103,7 +103,7 @@
     def test_flavor_non_admin_unset_keys(self):
         specs = {"key1": "value1", "key2": "value2"}
         set_resp, set_body = self.client.set_flavor_extra_spec(
-                                                self.flavor['id'], specs)
+            self.flavor['id'], specs)
 
         self.assertRaises(exceptions.Unauthorized,
                           self.flavors_client.unset_flavor_extra_spec,
diff --git a/tempest/tests/compute/base.py b/tempest/tests/compute/base.py
index 7716922..221cfb6 100644
--- a/tempest/tests/compute/base.py
+++ b/tempest/tests/compute/base.py
@@ -61,6 +61,7 @@
         cls.volumes_client = os.volumes_client
         cls.interfaces_client = os.interfaces_client
         cls.fixed_ips_client = os.fixed_ips_client
+        cls.availability_zone_client = os.availability_zone_client
         cls.build_interval = cls.config.compute.build_interval
         cls.build_timeout = cls.config.compute.build_timeout
         cls.ssh_user = cls.config.compute.ssh_user
diff --git a/tempest/tests/compute/floating_ips/test_floating_ips_actions.py b/tempest/tests/compute/floating_ips/test_floating_ips_actions.py
index 2b21710..d800fb5 100644
--- a/tempest/tests/compute/floating_ips/test_floating_ips_actions.py
+++ b/tempest/tests/compute/floating_ips/test_floating_ips_actions.py
@@ -102,14 +102,14 @@
         # to a specific server should be successful
 
         #Association of floating IP to fixed IP address
-        resp, body =\
-        self.client.associate_floating_ip_to_server(self.floating_ip,
-                                                    self.server_id)
+        resp, body = self.client.associate_floating_ip_to_server(
+            self.floating_ip,
+            self.server_id)
         self.assertEqual(202, resp.status)
         #Disassociation of floating IP that was associated in this method
-        resp, body = \
-            self.client.disassociate_floating_ip_from_server(self.floating_ip,
-                                                             self.server_id)
+        resp, body = self.client.disassociate_floating_ip_from_server(
+            self.floating_ip,
+            self.server_id)
         self.assertEqual(202, resp.status)
 
     @attr(type='negative')
@@ -150,13 +150,13 @@
         self.new_server_id = body['id']
 
         #Associating floating IP for the first time
-        resp, _ = \
-        self.client.associate_floating_ip_to_server(self.floating_ip,
-                                                    self.server_id)
+        resp, _ = self.client.associate_floating_ip_to_server(
+            self.floating_ip,
+            self.server_id)
         #Associating floating IP for the second time
-        resp, body = \
-        self.client.associate_floating_ip_to_server(self.floating_ip,
-                                                    self.new_server_id)
+        resp, body = self.client.associate_floating_ip_to_server(
+            self.floating_ip,
+            self.new_server_id)
 
         self.addCleanup(self.servers_client.delete_server, self.new_server_id)
         if (resp['status'] is not None):
diff --git a/tempest/tests/compute/images/test_images_oneserver.py b/tempest/tests/compute/images/test_images_oneserver.py
index ca3dbb5..dfc16f4 100644
--- a/tempest/tests/compute/images/test_images_oneserver.py
+++ b/tempest/tests/compute/images/test_images_oneserver.py
@@ -72,7 +72,6 @@
                           snapshot_name)
 
     @attr(type='negative')
-    @testtools.skip("Until Bug #1005423 is fixed")
     def test_create_image_specify_invalid_metadata(self):
         # Return an error when creating image with invalid metadata
         snapshot_name = rand_name('test-snap-')
@@ -81,12 +80,11 @@
                           self.server['id'], snapshot_name, meta)
 
     @attr(type='negative')
-    @testtools.skip("Until Bug #1005423 is fixed")
     def test_create_image_specify_metadata_over_limits(self):
         # Return an error when creating image with meta data over 256 chars
         snapshot_name = rand_name('test-snap-')
         meta = {'a' * 260: 'b' * 260}
-        self.assertRaises(exceptions.OverLimit, self.client.create_image,
+        self.assertRaises(exceptions.BadRequest, self.client.create_image,
                           self.server['id'], snapshot_name, meta)
 
     @attr(type='negative')
@@ -130,6 +128,11 @@
         self.assertEqual(original_image['minRam'], image['minRam'])
         self.assertEqual(original_image['minDisk'], image['minDisk'])
 
+        # Verify the image was deleted correctly
+        resp, body = self.client.delete_image(image_id)
+        self.assertEqual('204', resp['status'])
+        self.assertRaises(exceptions.NotFound, self.client.get_image, image_id)
+
     @attr(type='negative')
     @testtools.skipUnless(compute.MULTI_USER,
                           'Need multiple users for this test.')
diff --git a/tempest/tests/compute/limits/test_absolute_limits.py b/tempest/tests/compute/limits/test_absolute_limits.py
index 2b31680..6933fd7 100644
--- a/tempest/tests/compute/limits/test_absolute_limits.py
+++ b/tempest/tests/compute/limits/test_absolute_limits.py
@@ -15,6 +15,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest import exceptions
+from tempest.test import attr
 from tempest.tests.compute import base
 
 
@@ -25,6 +27,7 @@
     def setUpClass(cls):
         super(AbsoluteLimitsTestJSON, cls).setUpClass()
         cls.client = cls.limits_client
+        cls.server_client = cls.servers_client
 
     def test_absLimits_get(self):
         # To check if all limits are present in the response
@@ -45,6 +48,24 @@
                          "Failed to find element %s in absolute limits list"
                          % ', '.join(ele for ele in missing_elements))
 
+    @attr(type='negative')
+    def test_max_image_meta_exceed_limit(self):
+        #We should not create vm with image meta over maxImageMeta limit
+        # Get max limit value
+        max_meta = self.client.get_specific_absolute_limit('maxImageMeta')
+
+        #Create server should fail, since we are passing > metadata Limit!
+        max_meta_data = int(max_meta) + 1
+
+        meta_data = {}
+        for xx in range(max_meta_data):
+            meta_data[str(xx)] = str(xx)
+
+        self.assertRaises(exceptions.OverLimit,
+                          self.server_client.create_server,
+                          name='test', meta=meta_data, flavor_ref='84',
+                          image_ref='9e6a2e3b-1601-42a5-985f-c3a2f93a5ec3')
+
 
 class AbsoluteLimitsTestXML(AbsoluteLimitsTestJSON):
     _interface = 'xml'
diff --git a/tempest/tests/compute/servers/test_instance_actions.py b/tempest/tests/compute/servers/test_instance_actions.py
new file mode 100644
index 0000000..e7e31e8
--- /dev/null
+++ b/tempest/tests/compute/servers/test_instance_actions.py
@@ -0,0 +1,69 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 NEC Corporation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest import exceptions
+from tempest.test import attr
+from tempest.tests.compute import base
+
+
+class InstanceActionsTestJSON(base.BaseComputeTest):
+    _interface = 'json'
+
+    @classmethod
+    def setUpClass(cls):
+        super(InstanceActionsTestJSON, cls).setUpClass()
+        cls.client = cls.servers_client
+        resp, server = cls.create_server(wait_until='ACTIVE')
+        cls.request_id = resp['x-compute-request-id']
+        cls.server_id = server['id']
+
+    @attr(type='positive')
+    def test_list_instance_actions(self):
+        # List actions of the provided server
+        resp, body = self.client.reboot(self.server_id, 'HARD')
+        self.client.wait_for_server_status(self.server_id, 'ACTIVE')
+
+        resp, body = self.client.list_instance_actions(self.server_id)
+        self.assertEqual(200, resp.status)
+        self.assertTrue(len(body) == 2)
+        self.assertTrue(any([i for i in body if i['action'] == 'create']))
+        self.assertTrue(any([i for i in body if i['action'] == 'reboot']))
+
+    @attr(type='positive')
+    def test_get_instance_action(self):
+        # Get the action details of the provided server
+        resp, body = self.client.get_instance_action(self.server_id,
+                                                     self.request_id)
+        self.assertEqual(200, resp.status)
+        self.assertEqual(self.server_id, body['instance_uuid'])
+        self.assertEqual('create', body['action'])
+
+    @attr(type='negative')
+    def test_list_instance_actions_invalid_server(self):
+        # List actions of the invalid server id
+        self.assertRaises(exceptions.NotFound,
+                          self.client.list_instance_actions, 'server-999')
+
+    @attr(type='negative')
+    def test_get_instance_action_invalid_request(self):
+        # Get the action details of the provided server with invalid request
+        self.assertRaises(exceptions.NotFound, self.client.get_instance_action,
+                          self.server_id, '999')
+
+
+class InstanceActionsTestXML(InstanceActionsTestJSON):
+    _interface = 'xml'
diff --git a/tempest/tests/compute/servers/test_multiple_create.py b/tempest/tests/compute/servers/test_multiple_create.py
index ad5d604..47a38b1 100644
--- a/tempest/tests/compute/servers/test_multiple_create.py
+++ b/tempest/tests/compute/servers/test_multiple_create.py
@@ -48,7 +48,7 @@
         created_servers = self._get_created_servers(kwargs['name'])
         # NOTE(maurosr): append it to cls.servers list from base.BaseCompute
         # class.
-        self.servers.append(created_servers)
+        self.servers.extend(created_servers)
         # NOTE(maurosr): get a server list, check status of the ones with names
         # that match and wait for them become active. At a first look, since
         # they are building in parallel, wait inside the for doesn't seem be
diff --git a/tempest/tests/compute/servers/test_server_advanced_ops.py b/tempest/tests/compute/servers/test_server_advanced_ops.py
index ac0d7be..8be9c54 100644
--- a/tempest/tests/compute/servers/test_server_advanced_ops.py
+++ b/tempest/tests/compute/servers/test_server_advanced_ops.py
@@ -57,7 +57,7 @@
         flavor_id = self.config.compute.flavor_ref
         base_image_id = self.config.compute.image_ref
         self.instance = self.compute_client.servers.create(
-                i_name, base_image_id, flavor_id)
+            i_name, base_image_id, flavor_id)
         try:
             self.assertEqual(self.instance.name, i_name)
             self.set_resource('instance', self.instance)
@@ -66,16 +66,18 @@
 
         self.assertEqual(self.instance.status, 'BUILD')
         instance_id = self.get_resource('instance').id
-        test.status_timeout(self.compute_client.servers, instance_id, 'ACTIVE')
+        test.status_timeout(
+            self, self.compute_client.servers, instance_id, 'ACTIVE')
         instance = self.get_resource('instance')
         instance_id = instance.id
         resize_flavor = self.config.compute.flavor_ref_alt
         LOG.debug("Resizing instance %s from flavor %s to flavor %s",
                   instance.id, instance.flavor, resize_flavor)
         instance.resize(resize_flavor)
-        test.status_timeout(self.compute_client.servers, instance_id,
+        test.status_timeout(self, self.compute_client.servers, instance_id,
                             'VERIFY_RESIZE')
 
         LOG.debug("Confirming resize of instance %s", instance_id)
         instance.confirm_resize()
-        test.status_timeout(self.compute_client.servers, instance_id, 'ACTIVE')
+        test.status_timeout(
+            self, self.compute_client.servers, instance_id, 'ACTIVE')
diff --git a/tempest/tests/compute/servers/test_server_basic_ops.py b/tempest/tests/compute/servers/test_server_basic_ops.py
index c7fad7a..e4e246a 100644
--- a/tempest/tests/compute/servers/test_server_basic_ops.py
+++ b/tempest/tests/compute/servers/test_server_basic_ops.py
@@ -78,7 +78,7 @@
         for ruleset in rulesets:
             try:
                 self.compute_client.security_group_rules.create(
-                        self.secgroup.id, **ruleset)
+                    self.secgroup.id, **ruleset)
             except Exception:
                 self.fail("Failed to create rule in security group.")
 
@@ -90,7 +90,7 @@
             'key_name': self.get_resource('keypair').id
         }
         self.instance = self.compute_client.servers.create(
-                i_name, base_image_id, flavor_id, **create_kwargs)
+            i_name, base_image_id, flavor_id, **create_kwargs)
         try:
             self.assertEqual(self.instance.name, i_name)
             self.set_resource('instance', self.instance)
@@ -101,7 +101,8 @@
 
     def wait_on_active(self):
         instance_id = self.get_resource('instance').id
-        test.status_timeout(self.compute_client.servers, instance_id, 'ACTIVE')
+        test.status_timeout(
+            self, self.compute_client.servers, instance_id, 'ACTIVE')
 
     def pause_server(self):
         instance = self.get_resource('instance')
@@ -109,7 +110,8 @@
         LOG.debug("Pausing instance %s. Current status: %s",
                   instance_id, instance.status)
         instance.pause()
-        test.status_timeout(self.compute_client.servers, instance_id, 'PAUSED')
+        test.status_timeout(
+            self, self.compute_client.servers, instance_id, 'PAUSED')
 
     def unpause_server(self):
         instance = self.get_resource('instance')
@@ -117,7 +119,8 @@
         LOG.debug("Unpausing instance %s. Current status: %s",
                   instance_id, instance.status)
         instance.unpause()
-        test.status_timeout(self.compute_client.servers, instance_id, 'ACTIVE')
+        test.status_timeout(
+            self, self.compute_client.servers, instance_id, 'ACTIVE')
 
     def suspend_server(self):
         instance = self.get_resource('instance')
@@ -125,7 +128,7 @@
         LOG.debug("Suspending instance %s. Current status: %s",
                   instance_id, instance.status)
         instance.suspend()
-        test.status_timeout(self.compute_client.servers,
+        test.status_timeout(self, self.compute_client.servers,
                             instance_id, 'SUSPENDED')
 
     def resume_server(self):
@@ -134,7 +137,8 @@
         LOG.debug("Resuming instance %s. Current status: %s",
                   instance_id, instance.status)
         instance.resume()
-        test.status_timeout(self.compute_client.servers, instance_id, 'ACTIVE')
+        test.status_timeout(
+            self, self.compute_client.servers, instance_id, 'ACTIVE')
 
     def terminate_instance(self):
         instance = self.get_resource('instance')
diff --git a/tempest/tests/compute/servers/test_server_rescue.py b/tempest/tests/compute/servers/test_server_rescue.py
index 91010ce..04c5b27 100644
--- a/tempest/tests/compute/servers/test_server_rescue.py
+++ b/tempest/tests/compute/servers/test_server_rescue.py
@@ -15,8 +15,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import testtools
-
 from tempest.common.utils.data_utils import rand_name
 import tempest.config
 from tempest import exceptions
@@ -43,25 +41,25 @@
         cls.sg_name = rand_name('sg')
         cls.sg_desc = rand_name('sg-desc')
         resp, cls.sg = \
-        cls.security_groups_client.create_security_group(cls.sg_name,
-                                                         cls.sg_desc)
+            cls.security_groups_client.create_security_group(cls.sg_name,
+                                                             cls.sg_desc)
         cls.sg_id = cls.sg['id']
 
         # Create a volume and wait for it to become ready for attach
         resp, cls.volume_to_attach = \
-        cls.volumes_extensions_client.create_volume(1,
-                                                    display_name=
-                                                    'test_attach')
+            cls.volumes_extensions_client.create_volume(1,
+                                                        display_name=
+                                                        'test_attach')
         cls.volumes_extensions_client.wait_for_volume_status(
-                cls.volume_to_attach['id'], 'available')
+            cls.volume_to_attach['id'], 'available')
 
         # Create a volume and wait for it to become ready for attach
         resp, cls.volume_to_detach = \
-        cls.volumes_extensions_client.create_volume(1,
-                                                    display_name=
-                                                    'test_detach')
+            cls.volumes_extensions_client.create_volume(1,
+                                                        display_name=
+                                                        'test_detach')
         cls.volumes_extensions_client.wait_for_volume_status(
-                cls.volume_to_detach['id'], 'available')
+            cls.volume_to_detach['id'], 'available')
 
         # Server for positive tests
         resp, server = cls.create_server(image_id=cls.image_ref,
@@ -93,8 +91,8 @@
         client = cls.volumes_extensions_client
         client.delete_volume(str(cls.volume_to_attach['id']).strip())
         client.delete_volume(str(cls.volume_to_detach['id']).strip())
-        resp, cls.sg = \
-        cls.security_groups_client.delete_security_group(cls.sg_id)
+        resp, cls.sg = cls.security_groups_client.delete_security_group(
+            cls.sg_id)
 
     def tearDown(self):
         super(ServerRescueTestJSON, self).tearDown()
@@ -155,7 +153,7 @@
                                           self.volume_to_detach['id'],
                                           device='/dev/%s' % self.device)
         self.volumes_extensions_client.wait_for_volume_status(
-                self.volume_to_detach['id'], 'in-use')
+            self.volume_to_detach['id'], 'in-use')
 
         # Rescue the server
         self.servers_client.rescue_server(self.server_id, self.password)
@@ -181,9 +179,8 @@
 
         #Association of floating IP to a rescued vm
         client = self.floating_ips_client
-        resp, body =\
-        client.associate_floating_ip_to_server(self.floating_ip,
-                                               self.server_id)
+        resp, body = client.associate_floating_ip_to_server(self.floating_ip,
+                                                            self.server_id)
         self.assertEqual(202, resp.status)
 
         #Disassociation of floating IP that was associated in this method
@@ -193,8 +190,12 @@
         self.assertEqual(202, resp.status)
 
     @attr(type='positive')
-    @testtools.skip("Skipped until Bug #1126257 is resolved")
     def test_rescued_vm_add_remove_security_group(self):
+        # Rescue the server
+        self.servers_client.rescue_server(
+            self.server_id, self.password)
+        self.servers_client.wait_for_server_status(self.server_id, 'RESCUE')
+
         #Add Security group
         resp, body = self.servers_client.add_security_group(self.server_id,
                                                             self.sg_name)
@@ -202,7 +203,7 @@
 
         #Delete Security group
         resp, body = self.servers_client.remove_security_group(self.server_id,
-                                                               self.sg_id)
+                                                               self.sg_name)
         self.assertEqual(202, resp.status)
 
         # Unrescue the server
diff --git a/tempest/tests/compute/servers/test_servers_whitebox.py b/tempest/tests/compute/servers/test_servers_whitebox.py
index 9b75cd5..6b192dd 100644
--- a/tempest/tests/compute/servers/test_servers_whitebox.py
+++ b/tempest/tests/compute/servers/test_servers_whitebox.py
@@ -55,9 +55,9 @@
     def test_create_server_vcpu_quota_full(self):
         # Disallow server creation when tenant's vcpu quota is full
         quotas = self.meta.tables['quotas']
-        stmt = quotas.select().where(
-            quotas.c.project_id == self.tenant_id).where(
-            quotas.c.resource == 'cores')
+        stmt = (quotas.select().
+                where(quotas.c.project_id == self.tenant_id).
+                where(quotas.c.resource == 'cores'))
         result = self.connection.execute(stmt).first()
 
         # Set vcpu quota for tenant if not already set
@@ -87,9 +87,9 @@
     def test_create_server_memory_quota_full(self):
         # Disallow server creation when tenant's memory quota is full
         quotas = self.meta.tables['quotas']
-        stmt = quotas.select().where(
-            quotas.c.project_id == self.tenant_id).where(
-            quotas.c.resource == 'ram')
+        stmt = (quotas.select().
+                where(quotas.c.project_id == self.tenant_id).
+                where(quotas.c.resource == 'ram'))
         result = self.connection.execute(stmt).first()
 
         # Set memory quota for tenant if not already set
diff --git a/tempest/tests/image/v1/test_images.py b/tempest/tests/image/v1/test_images.py
index 0065d27..c01aeaf 100644
--- a/tempest/tests/image/v1/test_images.py
+++ b/tempest/tests/image/v1/test_images.py
@@ -89,9 +89,9 @@
         self.addCleanup(container_client.delete_container, container_name)
         cont_headers = {'X-Container-Read': '.r:*'}
         resp, _ = container_client.update_container_metadata(
-                    container_name,
-                    metadata=cont_headers,
-                    metadata_prefix='')
+            container_name,
+            metadata=cont_headers,
+            metadata_prefix='')
         self.assertEqual(resp['status'], '204')
 
         data = "TESTIMAGE"
@@ -270,7 +270,7 @@
     @attr(type='image')
     def test_index_name(self):
         resp, images_list = self.client.image_list_detail(
-                                                name='New Remote Image dup')
+            name='New Remote Image dup')
         self.assertEqual(resp['status'], '200')
         result_set = set(map(lambda x: x['id'], images_list))
         for image in images_list:
diff --git a/tempest/tests/network/common.py b/tempest/tests/network/common.py
index 1cff2c4..8c8d518 100644
--- a/tempest/tests/network/common.py
+++ b/tempest/tests/network/common.py
@@ -273,7 +273,7 @@
             self.set_resource(name, server)
         except AttributeError:
             self.fail("Server not successfully created.")
-        test.status_timeout(client.servers, server.id, 'ACTIVE')
+        test.status_timeout(self, client.servers, server.id, 'ACTIVE')
         # The instance retrieved on creation is missing network
         # details, necessitating retrieval after it becomes active to
         # ensure correct details.
diff --git a/tempest/tests/object_storage/test_container_services.py b/tempest/tests/object_storage/test_container_services.py
index 2c5b1ff..223744c 100644
--- a/tempest/tests/object_storage/test_container_services.py
+++ b/tempest/tests/object_storage/test_container_services.py
@@ -124,7 +124,7 @@
 
         # List container metadata
         resp, _ = self.container_client.list_container_metadata(
-                                                            container_name)
+            container_name)
         self.assertEqual(resp['status'], '204')
         self.assertIn('x-container-meta-name', resp)
         self.assertIn('x-container-meta-description', resp)
@@ -132,10 +132,9 @@
         self.assertEqual(resp['x-container-meta-description'], 'Travel')
 
         # Delete container metadata
-        resp, _ = \
-            self.container_client.delete_container_metadata(
-                                                    container_name,
-                                                    metadata=metadata.keys())
+        resp, _ = self.container_client.delete_container_metadata(
+            container_name,
+            metadata=metadata.keys())
         self.assertEqual(resp['status'], '204')
 
         resp, _ = self.container_client.list_container_metadata(container_name)
diff --git a/tempest/tests/object_storage/test_object_version.py b/tempest/tests/object_storage/test_object_version.py
index bc1c045..80cfc27 100644
--- a/tempest/tests/object_storage/test_object_version.py
+++ b/tempest/tests/object_storage/test_object_version.py
@@ -59,7 +59,7 @@
         # Create a containers
         vers_container_name = rand_name(name='TestVersionContainer')
         resp, body = self.container_client.create_container(
-                                                        vers_container_name)
+            vers_container_name)
         self.containers.append(vers_container_name)
         self.assertIn(resp['status'], ('202', '201'))
         self.assertContainer(vers_container_name, '0', '0',
@@ -68,9 +68,9 @@
         base_container_name = rand_name(name='TestBaseContainer')
         headers = {'X-versions-Location': vers_container_name}
         resp, body = self.container_client.create_container(
-                                                        base_container_name,
-                                                        metadata=headers,
-                                                        metadata_prefix='')
+            base_container_name,
+            metadata=headers,
+            metadata_prefix='')
         self.containers.append(base_container_name)
         self.assertIn(resp['status'], ('202', '201'))
         self.assertContainer(base_container_name, '0', '0',
diff --git a/tempest/tests/volume/admin/test_volume_types.py b/tempest/tests/volume/admin/test_volume_types.py
index 38ac74a..13efca7 100644
--- a/tempest/tests/volume/admin/test_volume_types.py
+++ b/tempest/tests/volume/admin/test_volume_types.py
@@ -55,15 +55,15 @@
             extra_specs = {"storage_protocol": "iSCSI",
                            "vendor_name": "Open Source"}
             body = {}
-            resp, body = self.client.create_volume_type(vol_type_name,
-                                                        extra_specs=
-                                                        extra_specs)
+            resp, body = self.client.create_volume_type(
+                vol_type_name,
+                extra_specs=extra_specs)
             self.assertEqual(200, resp.status)
             self.assertTrue('id' in body)
             self.assertTrue('name' in body)
-            resp, volume = self.volumes_client.\
-            create_volume(size=1, display_name=vol_name,
-                          volume_type=vol_type_name)
+            resp, volume = self.volumes_client.create_volume(
+                size=1, display_name=vol_name,
+                volume_type=vol_type_name)
             self.assertEqual(200, resp.status)
             self.assertTrue('id' in volume)
             self.assertTrue('display_name' in volume)
@@ -74,8 +74,7 @@
                             "Field volume id is empty or not found.")
             self.volumes_client.wait_for_volume_status(volume['id'],
                                                        'available')
-            resp, fetched_volume = self.volumes_client.\
-            get_volume(volume['id'])
+            resp, fetched_volume = self.volumes_client.get_volume(volume['id'])
             self.assertEqual(200, resp.status)
             self.assertEqual(vol_name, fetched_volume['display_name'],
                              'The fetched Volume is different '
@@ -104,8 +103,9 @@
             name = rand_name("volume-type-")
             extra_specs = {"storage_protocol": "iSCSI",
                            "vendor_name": "Open Source"}
-            resp, body = self.client.\
-            create_volume_type(name, extra_specs=extra_specs)
+            resp, body = self.client.create_volume_type(
+                name,
+                extra_specs=extra_specs)
             self.assertEqual(200, resp.status)
             self.assertTrue('id' in body)
             self.assertTrue('name' in body)
@@ -114,8 +114,7 @@
                              "to the requested name")
             self.assertTrue(body['id'] is not None,
                             "Field volume_type id is empty or not found.")
-            resp, fetched_volume_type = self.client.\
-            delete_volume_type(body['id'])
+            resp, _ = self.client.delete_volume_type(body['id'])
             self.assertEqual(202, resp.status)
         except Exception:
             self.fail("Could not create a volume_type")
@@ -127,8 +126,9 @@
             name = rand_name("volume-type-")
             extra_specs = {"storage_protocol": "iSCSI",
                            "vendor_name": "Open Source"}
-            resp, body = self.client.\
-            create_volume_type(name, extra_specs=extra_specs)
+            resp, body = self.client.create_volume_type(
+                name,
+                extra_specs=extra_specs)
             self.assertEqual(200, resp.status)
             self.assertTrue('id' in body)
             self.assertTrue('name' in body)
diff --git a/tempest/tests/volume/admin/test_volume_types_extra_specs.py b/tempest/tests/volume/admin/test_volume_types_extra_specs.py
index 31e2879..c8cf8d9 100644
--- a/tempest/tests/volume/admin/test_volume_types_extra_specs.py
+++ b/tempest/tests/volume/admin/test_volume_types_extra_specs.py
@@ -37,13 +37,13 @@
         # List Volume types extra specs.
         try:
             extra_specs = {"spec1": "val1"}
-            resp, body = self.client.\
-            create_volume_type_extra_specs(self.volume_type['id'], extra_specs)
+            resp, body = self.client.create_volume_type_extra_specs(
+                self.volume_type['id'], extra_specs)
             self.assertEqual(200, resp.status)
             self.assertEqual(extra_specs, body,
                              "Volume type extra spec incorrectly created")
-            resp, body = self.client.\
-            list_volume_types_extra_specs(self.volume_type['id'])
+            resp, body = self.client.list_volume_types_extra_specs(
+                self.volume_type['id'])
             self.assertEqual(200, resp.status)
             self.assertTrue(type(body), dict)
             self.assertTrue('spec1' in body, "Incorrect volume type extra"
@@ -55,17 +55,17 @@
         # Update volume type extra specs
         try:
             extra_specs = {"spec2": "val1"}
-            resp, body = self.client.\
-            create_volume_type_extra_specs(self.volume_type['id'], extra_specs)
+            resp, body = self.client.create_volume_type_extra_specs(
+                self.volume_type['id'], extra_specs)
             self.assertEqual(200, resp.status)
             self.assertEqual(extra_specs, body,
                              "Volume type extra spec incorrectly created")
 
             extra_spec = {"spec2": "val2"}
-            resp, body = self.client.\
-            update_volume_type_extra_specs(self.volume_type['id'],
-                                           extra_spec.keys()[0],
-                                           extra_spec)
+            resp, body = self.client.update_volume_type_extra_specs(
+                self.volume_type['id'],
+                extra_spec.keys()[0],
+                extra_spec)
             self.assertEqual(200, resp.status)
             self.assertTrue('spec2' in body,
                             "Volume type extra spec incorrectly updated")
@@ -78,22 +78,23 @@
         # Create/Get/Delete volume type extra spec.
         try:
             extra_specs = {"spec3": "val1"}
-            resp, body = self.client.\
-            create_volume_type_extra_specs(self.volume_type['id'], extra_specs)
+            resp, body = self.client.create_volume_type_extra_specs(
+                self.volume_type['id'],
+                extra_specs)
             self.assertEqual(200, resp.status)
             self.assertEqual(extra_specs, body,
                              "Volume type extra spec incorrectly created")
 
-            resp, fetched_vol_type_extra_spec = self.client.\
-            get_volume_type_extra_specs(self.volume_type['id'],
-                                        extra_specs.keys()[0])
+            resp, _ = self.client.get_volume_type_extra_specs(
+                self.volume_type['id'],
+                extra_specs.keys()[0])
             self.assertEqual(200, resp.status)
             self.assertEqual(extra_specs, body,
                              "Volume type extra spec incorrectly fetched")
 
-            resp, _ = self.client.\
-            delete_volume_type_extra_specs(self.volume_type['id'],
-                                           extra_specs.keys()[0])
+            resp, _ = self.client.delete_volume_type_extra_specs(
+                self.volume_type['id'],
+                extra_specs.keys()[0])
             self.assertEqual(202, resp.status)
         except Exception:
             self.fail("Could not create a volume_type extra spec")
diff --git a/tempest/tests/volume/base.py b/tempest/tests/volume/base.py
index 00e8668..978ec53 100644
--- a/tempest/tests/volume/base.py
+++ b/tempest/tests/volume/base.py
@@ -149,13 +149,13 @@
     def clear_volumes(cls):
         for volume in cls.volumes:
             try:
-                cls.volume_client.delete_volume(volume['id'])
+                cls.volumes_client.delete_volume(volume['id'])
             except Exception:
                 pass
 
         for volume in cls.volumes:
             try:
-                cls.servers_client.wait_for_resource_deletion(volume['id'])
+                cls.volumes_client.wait_for_resource_deletion(volume['id'])
             except Exception:
                 pass
 
diff --git a/tempest/whitebox.py b/tempest/whitebox.py
index bfcc373..cf9fff0 100644
--- a/tempest/whitebox.py
+++ b/tempest/whitebox.py
@@ -111,7 +111,7 @@
             image_id = cls.image_ref
 
         resp, server = cls.servers_client.create_server(
-                                                server_name, image_id, flavor)
+            server_name, image_id, flavor)
         cls.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
         cls.servers.append(server)
         return server
diff --git a/tools/check_source.sh b/tools/check_source.sh
index 089ad70..01724fa 100755
--- a/tools/check_source.sh
+++ b/tools/check_source.sh
@@ -1,6 +1,6 @@
 #!/usr/bin/env bash
 
-python tools/hacking.py --ignore=E122,E125,E126 --repeat --show-source --exclude=.venv,.tox,dist,doc,openstack,*egg .
+flake8 --ignore=E125,H302,H304,H404,F --show-source --exclude=.git,.venv,.tox,dist,doc,openstack,*egg .
 pep8_ret=$?
 
 pyflakes tempest stress setup.py tools cli bin | grep "imported but unused"
diff --git a/tools/hacking.py b/tools/hacking.py
deleted file mode 100755
index 7e46b74..0000000
--- a/tools/hacking.py
+++ /dev/null
@@ -1,525 +0,0 @@
-#!/usr/bin/env python
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright (c) 2012, Cloudscaling
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-"""tempest HACKING file compliance testing
-
-built on top of pep8.py
-"""
-
-import inspect
-import logging
-import os
-import re
-import subprocess
-import sys
-import tokenize
-import warnings
-
-import pep8
-
-# Don't need this for testing
-logging.disable('LOG')
-
-#T1xx comments
-#T2xx except
-#T3xx imports
-#T4xx docstrings
-#T5xx dictionaries/lists
-#T6xx calling methods
-#T7xx localization
-#N8xx git commit messages
-
-IMPORT_EXCEPTIONS = ['sqlalchemy', 'migrate']
-DOCSTRING_TRIPLE = ['"""', "'''"]
-VERBOSE_MISSING_IMPORT = os.getenv('HACKING_VERBOSE_MISSING_IMPORT', 'False')
-
-
-# Monkey patch broken excluded filter in pep8
-# See https://github.com/jcrocholl/pep8/pull/111
-def excluded(self, filename):
-    """
-    Check if options.exclude contains a pattern that matches filename.
-    """
-    basename = os.path.basename(filename)
-    return any((pep8.filename_match(filename, self.options.exclude,
-                                    default=False),
-                pep8.filename_match(basename, self.options.exclude,
-                                    default=False)))
-
-
-def input_dir(self, dirname):
-    """Check all files in this directory and all subdirectories."""
-    dirname = dirname.rstrip('/')
-    if self.excluded(dirname):
-        return 0
-    counters = self.options.report.counters
-    verbose = self.options.verbose
-    filepatterns = self.options.filename
-    runner = self.runner
-    for root, dirs, files in os.walk(dirname):
-        if verbose:
-            print('directory ' + root)
-        counters['directories'] += 1
-        for subdir in sorted(dirs):
-            if self.excluded(os.path.join(root, subdir)):
-                dirs.remove(subdir)
-        for filename in sorted(files):
-            # contain a pattern that matches?
-            if ((pep8.filename_match(filename, filepatterns) and
-                 not self.excluded(filename))):
-                runner(os.path.join(root, filename))
-
-
-def is_import_exception(mod):
-    return (mod in IMPORT_EXCEPTIONS or
-            any(mod.startswith(m + '.') for m in IMPORT_EXCEPTIONS))
-
-
-def import_normalize(line):
-    # convert "from x import y" to "import x.y"
-    # handle "from x import y as z" to "import x.y as z"
-    split_line = line.split()
-    if ("import" in line and line.startswith("from ") and "," not in line and
-        split_line[2] == "import" and split_line[3] != "*" and
-        split_line[1] != "__future__" and
-       (len(split_line) == 4 or
-       (len(split_line) == 6 and split_line[4] == "as"))):
-        return "import %s.%s" % (split_line[1], split_line[3])
-    else:
-        return line
-
-
-def tempest_todo_format(physical_line):
-    """Check for 'TODO()'.
-
-    tempest HACKING guide recommendation for TODO:
-    Include your name with TODOs as in "#TODO(termie)"
-    T101
-    """
-    pos = physical_line.find('TODO')
-    pos1 = physical_line.find('TODO(')
-    pos2 = physical_line.find('#')  # make sure it's a comment
-    if (pos != pos1 and pos2 >= 0 and pos2 < pos):
-        return pos, "T101: Use TODO(NAME)"
-
-
-def tempest_except_format(logical_line):
-    """Check for 'except:'.
-
-    tempest HACKING guide recommends not using except:
-    Do not write "except:", use "except Exception:" at the very least
-    T201
-    """
-    if logical_line.startswith("except:"):
-        yield 6, "T201: no 'except:' at least use 'except Exception:'"
-
-
-def tempest_except_format_assert(logical_line):
-    """Check for 'assertRaises(Exception'.
-
-    tempest HACKING guide recommends not using assertRaises(Exception...):
-    Do not use overly broad Exception type
-    T202
-    """
-    if logical_line.startswith("self.assertRaises(Exception"):
-        yield 1, "T202: assertRaises Exception too broad"
-
-
-def tempest_one_import_per_line(logical_line):
-    """Check for import format.
-
-    tempest HACKING guide recommends one import per line:
-    Do not import more than one module per line
-
-    Examples:
-    BAD: from tempest.common.rest_client import RestClient, RestClientXML
-    T301
-    """
-    pos = logical_line.find(',')
-    parts = logical_line.split()
-    if (pos > -1 and (parts[0] == "import" or
-                      parts[0] == "from" and parts[2] == "import") and
-        not is_import_exception(parts[1])):
-        yield pos, "T301: one import per line"
-
-_missingImport = set([])
-
-
-def tempest_import_module_only(logical_line):
-    """Check for import module only.
-
-    tempest HACKING guide recommends importing only modules:
-    Do not import objects, only modules
-    T302 import only modules
-    T303 Invalid Import
-    T304 Relative Import
-    """
-    def importModuleCheck(mod, parent=None, added=False):
-        """
-        If can't find module on first try, recursively check for relative
-        imports
-        """
-        current_path = os.path.dirname(pep8.current_file)
-        try:
-            with warnings.catch_warnings():
-                warnings.simplefilter('ignore', DeprecationWarning)
-                valid = True
-                if parent:
-                    if is_import_exception(parent):
-                        return
-                    parent_mod = __import__(parent, globals(), locals(),
-                                            [mod], -1)
-                    valid = inspect.ismodule(getattr(parent_mod, mod))
-                else:
-                    __import__(mod, globals(), locals(), [], -1)
-                    valid = inspect.ismodule(sys.modules[mod])
-                if not valid:
-                    if added:
-                        sys.path.pop()
-                        added = False
-                        return logical_line.find(mod), ("T304: No "
-                                                        "relative  imports. "
-                                                        "'%s' is a relative "
-                                                        "import"
-                                                        % logical_line)
-                    return logical_line.find(mod), ("T302: import only"
-                                                    " modules. '%s' does not "
-                                                    "import a module"
-                                                    % logical_line)
-
-        except (ImportError, NameError) as exc:
-            if not added:
-                added = True
-                sys.path.append(current_path)
-                return importModuleCheck(mod, parent, added)
-            else:
-                name = logical_line.split()[1]
-                if name not in _missingImport:
-                    if VERBOSE_MISSING_IMPORT != 'False':
-                        print >> sys.stderr, ("ERROR: import '%s' in %s "
-                                              "failed: %s" %
-                                              (name, pep8.current_file, exc))
-                    _missingImport.add(name)
-                added = False
-                sys.path.pop()
-                return
-
-        except AttributeError:
-            # Invalid import
-            return logical_line.find(mod), ("T303: Invalid import, "
-                                            "AttributeError raised")
-
-    # convert "from x import y" to " import x.y"
-    # convert "from x import y as z" to " import x.y"
-    import_normalize(logical_line)
-    split_line = logical_line.split()
-
-    if (logical_line.startswith("import ") and "," not in logical_line and
-            (len(split_line) == 2 or
-            (len(split_line) == 4 and split_line[2] == "as"))):
-        mod = split_line[1]
-        rval = importModuleCheck(mod)
-        if rval is not None:
-            yield rval
-
-    # TODO(jogo) handle "from x import *"
-
-#TODO(jogo): import template: T305
-
-
-def tempest_import_alphabetical(logical_line, line_number, lines):
-    """Check for imports in alphabetical order.
-
-    Tempest HACKING guide recommendation for imports:
-    imports in human alphabetical order
-    T306
-    """
-    # handle import x
-    # use .lower since capitalization shouldn't dictate order
-    split_line = import_normalize(logical_line.strip()).lower().split()
-    split_previous = import_normalize(lines[
-                                      line_number - 2]).strip().lower().split()
-    # with or without "as y"
-    length = [2, 4]
-    if (len(split_line) in length and len(split_previous) in length and
-        split_line[0] == "import" and split_previous[0] == "import"):
-        if split_line[1] < split_previous[1]:
-            yield (0, "T306: imports not in alphabetical order"
-                      " (%s, %s)"
-                      % (split_previous[1], split_line[1]))
-
-
-def tempest_docstring_start_space(physical_line):
-    """Check for docstring not start with space.
-
-    tempest HACKING guide recommendation for docstring:
-    Docstring should not start with space
-    T401
-    """
-    pos = max([physical_line.find(i) for i in DOCSTRING_TRIPLE])  # start
-    end = max([physical_line[-4:-1] == i for i in DOCSTRING_TRIPLE])  # end
-    if (pos != -1 and end and len(physical_line) > pos + 4):
-        if (physical_line[pos + 3] == ' '):
-            return (pos, "T401: one line docstring should not start"
-                         " with a space")
-
-
-def tempest_docstring_one_line(physical_line):
-    """Check one line docstring end.
-
-    tempest HACKING guide recommendation for one line docstring:
-    A one line docstring looks like this and ends in a period.
-    T402
-    """
-    pos = max([physical_line.find(i) for i in DOCSTRING_TRIPLE])  # start
-    end = max([physical_line[-4:-1] == i for i in DOCSTRING_TRIPLE])  # end
-    if (pos != -1 and end and len(physical_line) > pos + 4):
-        if (physical_line[-5] != '.'):
-            return pos, "T402: one line docstring needs a period"
-
-
-def tempest_docstring_multiline_end(physical_line):
-    """Check multi line docstring end.
-
-    Tempest HACKING guide recommendation for docstring:
-    Docstring should end on a new line
-    T403
-    """
-    pos = max([physical_line.find(i) for i in DOCSTRING_TRIPLE])  # start
-    if (pos != -1 and len(physical_line) == pos):
-        if (physical_line[pos + 3] == ' '):
-            return (pos, "T403: multi line docstring end on new line")
-
-
-def tempest_no_test_docstring(physical_line, previous_logical, filename):
-    """Check that test_ functions don't have docstrings
-
-    This ensure we get better results out of tempest, instead
-    of them being hidden behind generic descriptions of the
-    functions.
-
-    T404
-    """
-    if "tempest/test" in filename:
-        pos = max([physical_line.find(i) for i in DOCSTRING_TRIPLE])
-        if pos != -1:
-            if previous_logical.startswith("def test_"):
-                return (pos, "T404: test functions must "
-                        "not have doc strings")
-
-SKIP_DECORATOR = '@testtools.skip('
-
-
-def tempest_skip_bugs(physical_line):
-    """Check skip lines for proper bug entries
-
-    T601: Bug not in skip line
-    T602: Bug in message formatted incorrectly
-    """
-
-    pos = physical_line.find(SKIP_DECORATOR)
-
-    skip_re = re.compile(r'^\s*@testtools.skip.*')
-
-    if pos != -1 and skip_re.match(physical_line):
-        bug = re.compile(r'^.*\bbug\b.*', re.IGNORECASE)
-        if bug.match(physical_line) is None:
-            return (pos, 'T601: skips must have an associated bug')
-
-        bug_re = re.compile(r'.*skip\(.*Bug\s\#\d+', re.IGNORECASE)
-
-        if bug_re.match(physical_line) is None:
-            return (pos, 'T602: Bug number formatted incorrectly')
-
-
-FORMAT_RE = re.compile("%(?:"
-                       "%|"           # Ignore plain percents
-                       "(\(\w+\))?"   # mapping key
-                       "([#0 +-]?"    # flag
-                       "(?:\d+|\*)?"  # width
-                       "(?:\.\d+)?"   # precision
-                       "[hlL]?"       # length mod
-                       "\w))")        # type
-
-
-class LocalizationError(Exception):
-    pass
-
-
-def check_i18n():
-    """Generator that checks token stream for localization errors.
-
-    Expects tokens to be ``send``ed one by one.
-    Raises LocalizationError if some error is found.
-    """
-    while True:
-        try:
-            token_type, text, _, _, line = yield
-        except GeneratorExit:
-            return
-        if (token_type == tokenize.NAME and text == "_" and
-            not line.startswith('def _(msg):')):
-
-            while True:
-                token_type, text, start, _, _ = yield
-                if token_type != tokenize.NL:
-                    break
-            if token_type != tokenize.OP or text != "(":
-                continue  # not a localization call
-
-            format_string = ''
-            while True:
-                token_type, text, start, _, _ = yield
-                if token_type == tokenize.STRING:
-                    format_string += eval(text)
-                elif token_type == tokenize.NL:
-                    pass
-                else:
-                    break
-
-            if not format_string:
-                raise LocalizationError(start,
-                                        "T701: Empty localization "
-                                        "string")
-            if token_type != tokenize.OP:
-                raise LocalizationError(start,
-                                        "T701: Invalid localization "
-                                        "call")
-            if text != ")":
-                if text == "%":
-                    raise LocalizationError(start,
-                                            "T702: Formatting "
-                                            "operation should be outside"
-                                            " of localization method call")
-                elif text == "+":
-                    raise LocalizationError(start,
-                                            "T702: Use bare string "
-                                            "concatenation instead of +")
-                else:
-                    raise LocalizationError(start,
-                                            "T702: Argument to _ must"
-                                            " be just a string")
-
-            format_specs = FORMAT_RE.findall(format_string)
-            positional_specs = [(key, spec) for key, spec in format_specs
-                                if not key and spec]
-            # not spec means %%, key means %(smth)s
-            if len(positional_specs) > 1:
-                raise LocalizationError(start,
-                                        "T703: Multiple positional "
-                                        "placeholders")
-
-
-def tempest_localization_strings(logical_line, tokens):
-    """Check localization in line.
-
-    T701: bad localization call
-    T702: complex expression instead of string as argument to _()
-    T703: multiple positional placeholders
-    """
-
-    gen = check_i18n()
-    next(gen)
-    try:
-        map(gen.send, tokens)
-        gen.close()
-    except LocalizationError as e:
-        yield e.args
-
-#TODO(jogo) Dict and list objects
-
-current_file = ""
-
-
-def readlines(filename):
-    """Record the current file being tested."""
-    pep8.current_file = filename
-    return open(filename).readlines()
-
-
-def add_tempest():
-    """Monkey patch in tempest guidelines.
-
-    Look for functions that start with tempest_  and have arguments
-    and add them to pep8 module
-    Assumes you know how to write pep8.py checks
-    """
-    for name, function in globals().items():
-        if not inspect.isfunction(function):
-            continue
-        args = inspect.getargspec(function)[0]
-        if args and name.startswith("tempest"):
-            exec("pep8.%s = %s" % (name, name))
-
-
-def once_git_check_commit_title():
-    """Check git commit messages.
-
-    tempest HACKING recommends not referencing a bug or blueprint
-    in first line, it should provide an accurate description of the change
-    T801
-    T802 Title limited to 50 chars
-    """
-    #Get title of most recent commit
-
-    subp = subprocess.Popen(['git', 'log', '--no-merges', '--pretty=%s', '-1'],
-                            stdout=subprocess.PIPE)
-    title = subp.communicate()[0]
-    if subp.returncode:
-        raise Exception("git log failed with code %s" % subp.returncode)
-
-    #From https://github.com/openstack/openstack-ci-puppet
-    #       /blob/master/modules/gerrit/manifests/init.pp#L74
-    #Changeid|bug|blueprint
-    git_keywords = (r'(I[0-9a-f]{8,40})|'
-                    '([Bb]ug|[Ll][Pp])[\s\#:]*(\d+)|'
-                    '([Bb]lue[Pp]rint|[Bb][Pp])[\s\#:]*([A-Za-z0-9\\-]+)')
-    GIT_REGEX = re.compile(git_keywords)
-
-    error = False
-    #NOTE(jogo) if match regex but over 3 words, acceptable title
-    if GIT_REGEX.search(title) is not None and len(title.split()) <= 3:
-        print ("T801: git commit title ('%s') should provide an accurate "
-               "description of the change, not just a reference to a bug "
-               "or blueprint" % title.strip())
-        error = True
-    if len(title.decode('utf-8')) > 72:
-        print ("T802: git commit title ('%s') should be under 50 chars"
-               % title.strip())
-        error = True
-    return error
-
-if __name__ == "__main__":
-    #include tempest path
-    sys.path.append(os.getcwd())
-    #Run once tests (not per line)
-    once_error = once_git_check_commit_title()
-    #TEMPEST error codes start with a T
-    pep8.ERRORCODE_REGEX = re.compile(r'[EWT]\d{3}')
-    add_tempest()
-    pep8.current_file = current_file
-    pep8.readlines = readlines
-    pep8.StyleGuide.excluded = excluded
-    pep8.StyleGuide.input_dir = input_dir
-    try:
-        pep8._main()
-        sys.exit(once_error)
-    finally:
-        if len(_missingImport) > 0:
-            print >> sys.stderr, ("%i imports missing in this test environment"
-                                  % len(_missingImport))
diff --git a/tools/tempest_coverage.py b/tools/tempest_coverage.py
index 9dcbd46..5b926f9 100755
--- a/tools/tempest_coverage.py
+++ b/tools/tempest_coverage.py
@@ -165,7 +165,7 @@
             resp, body = coverage_client.report_coverage_xml(file=CLI.filename)
         elif CLI.html:
             resp, body = coverage_client.report_coverage_html(
-                                                            file=CLI.filename)
+                file=CLI.filename)
         else:
             resp, body = coverage_client.report_coverage(file=CLI.filename)
         if not resp['status'] == '200':
diff --git a/tools/test-requires b/tools/test-requires
index f701dab..3d4c2d6 100644
--- a/tools/test-requires
+++ b/tools/test-requires
@@ -1,5 +1,4 @@
-pep8==1.3.3
-pylint==0.19
+flake8
+hacking
 #TODO(afazekas): ensure pg_config installed
 psycopg2
-pyflakes