Merge "make stack traces tool find individual traces"
diff --git a/HACKING.rst b/HACKING.rst
index a546f8c..eafa81b 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -153,6 +153,19 @@
                              kwarg2=dict_of_numbers)
 
 
+Test Skips
+----------
+If a test is broken because of a bug it is appropriate to skip the test until
+bug has been fixed. However, the skip message should be formatted so that
+Tempest's skip tracking tool can watch the bug status. The skip message should
+contain the string 'Bug' immediately followed by a space. Then the bug number
+should be included in the message '#' in front of the number.
+
+Example::
+
+  @testtools.skip("Skipped until the Bug #980688 is resolved")
+
+
 openstack-common
 ----------------
 
diff --git a/cli/__init__.py b/cli/__init__.py
index 6ffe229..7a92260 100644
--- a/cli/__init__.py
+++ b/cli/__init__.py
@@ -60,16 +60,22 @@
         return self.cmd_with_auth(
             'nova', action, flags, params, admin, fail_ok)
 
-    def nova_manage(self, action, flags='', params='', fail_ok=False):
+    def nova_manage(self, action, flags='', params='', fail_ok=False,
+                    merge_stderr=False):
         """Executes nova-manage command for the given action."""
         return self.cmd(
-            'nova-manage', action, flags, params, fail_ok)
+            'nova-manage', action, flags, params, fail_ok, merge_stderr)
 
     def keystone(self, action, flags='', params='', admin=True, fail_ok=False):
         """Executes keystone command for the given action."""
         return self.cmd_with_auth(
             'keystone', action, flags, params, admin, fail_ok)
 
+    def glance(self, action, flags='', params='', admin=True, fail_ok=False):
+        """Executes glance command for the given action."""
+        return self.cmd_with_auth(
+            'glance', action, flags, params, admin, fail_ok)
+
     def cmd_with_auth(self, cmd, action, flags='', params='',
                       admin=True, fail_ok=False):
         """Executes given command with auth attributes appended."""
@@ -81,14 +87,19 @@
         flags = creds + ' ' + flags
         return self.cmd(cmd, action, flags, params, fail_ok)
 
-    def cmd(self, cmd, action, flags='', params='', fail_ok=False):
+    def cmd(self, cmd, action, flags='', params='', fail_ok=False,
+            merge_stderr=False):
         """Executes specified command for the given action."""
         cmd = ' '.join([CONF.cli.cli_dir + cmd,
                         flags, action, params])
         LOG.info("running: '%s'" % cmd)
         cmd = shlex.split(cmd)
         try:
-            result = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
+            if merge_stderr:
+                result = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
+            else:
+                devnull = open('/dev/null', 'w')
+                result = subprocess.check_output(cmd, stderr=devnull)
         except subprocess.CalledProcessError, e:
             LOG.error("command output:\n%s" % e.output)
             raise
diff --git a/cli/simple_read_only/test_compute.py b/cli/simple_read_only/test_compute.py
index 43c3c45..d301d38 100644
--- a/cli/simple_read_only/test_compute.py
+++ b/cli/simple_read_only/test_compute.py
@@ -22,7 +22,6 @@
 import testtools
 
 import cli
-from tempest import config
 
 
 CONF = cfg.CONF
@@ -73,7 +72,7 @@
     def test_admin_dns_domains(self):
         self.nova('dns-domains')
 
-    @testtools.skip("Test needs parameters, Bug: 1157349")
+    @testtools.skip("Test needs parameters, Bug #1157349")
     def test_admin_dns_list(self):
         self.nova('dns-list')
 
@@ -111,7 +110,7 @@
     def test_admin_image_list(self):
         self.nova('image-list')
 
-    @testtools.skip("Test needs parameters, Bug: 1157349")
+    @testtools.skip("Test needs parameters, Bug #1157349")
     def test_admin_interface_list(self):
         self.nova('interface-list')
 
@@ -136,7 +135,7 @@
     def test_admin_secgroup_list(self):
         self.nova('secgroup-list')
 
-    @testtools.skip("Test needs parameters, Bug: 1157349")
+    @testtools.skip("Test needs parameters, Bug #1157349")
     def test_admin_secgroup_list_rules(self):
         self.nova('secgroup-list-rules')
 
diff --git a/cli/simple_read_only/test_compute_manage.py b/cli/simple_read_only/test_compute_manage.py
index 17b3bf6..bbcc5b1 100644
--- a/cli/simple_read_only/test_compute_manage.py
+++ b/cli/simple_read_only/test_compute_manage.py
@@ -18,8 +18,6 @@
 import logging
 import subprocess
 
-import testtools
-
 import cli
 
 
@@ -49,9 +47,20 @@
     def test_help_flag(self):
         self.nova_manage('', '-h')
 
-    @testtools.skip("version is empty, bug 1138844")
     def test_version_flag(self):
-        self.assertNotEqual("", self.nova_manage('', '--version'))
+        # Bug 1159957: nova-manage --version writes to stderr
+        self.assertNotEqual("", self.nova_manage('', '--version',
+                                                 merge_stderr=True))
+        self.assertEqual(self.nova_manage('version'),
+                         self.nova_manage('', '--version', merge_stderr=True))
+
+    def test_debug_flag(self):
+        self.assertNotEqual("", self.nova_manage('instance_type list',
+                            '--debug'))
+
+    def test_verbose_flag(self):
+        self.assertNotEqual("", self.nova_manage('instance_type list',
+                            '--verbose'))
 
     # test actions
     def test_version(self):
@@ -59,3 +68,16 @@
 
     def test_flavor_list(self):
         self.assertNotEqual("", self.nova_manage('flavor list'))
+        self.assertEqual(self.nova_manage('instance_type list'),
+                         self.nova_manage('flavor list'))
+
+    def test_db_archive_deleted_rows(self):
+        # make sure command doesn't error out
+        self.nova_manage('db archive_deleted_rows 50')
+
+    def test_db_sync(self):
+        # make sure command doesn't error out
+        self.nova_manage('db sync')
+
+    def test_db_version(self):
+        self.assertNotEqual("", self.nova_manage('db version'))
diff --git a/cli/simple_read_only/test_glance.py b/cli/simple_read_only/test_glance.py
new file mode 100644
index 0000000..f9822cc
--- /dev/null
+++ b/cli/simple_read_only/test_glance.py
@@ -0,0 +1,66 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 OpenStack Foundation
+# 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 logging
+import re
+import subprocess
+
+import cli
+
+
+LOG = logging.getLogger(__name__)
+
+
+class SimpleReadOnlyGlanceClientTest(cli.ClientTestBase):
+    """Basic, read-only tests for Glance CLI client.
+
+    Checks return values and output of read-only commands.
+    These tests do not presume any content, nor do they create
+    their own. They only verify the structure of output if present.
+    """
+
+    def test_glance_fake_action(self):
+        self.assertRaises(subprocess.CalledProcessError,
+                          self.glance,
+                          'this-does-not-exist')
+
+    def test_glance_image_list(self):
+        out = self.glance('image-list')
+        endpoints = self.parser.listing(out)
+        self.assertTableStruct(endpoints, [
+            'ID', 'Name', 'Disk Format', 'Container Format',
+            'Size', 'Status'])
+
+    def test_glance_help(self):
+        help_text = self.glance('help')
+        lines = help_text.split('\n')
+        self.assertTrue(lines[0].startswith('usage: glance'))
+
+        commands = []
+        cmds_start = lines.index('Positional arguments:')
+        cmds_end = lines.index('Optional arguments:')
+        command_pattern = re.compile('^ {4}([a-z0-9\-\_]+)')
+        for line in lines[cmds_start:cmds_end]:
+            match = command_pattern.match(line)
+            if match:
+                commands.append(match.group(1))
+        commands = set(commands)
+        wanted_commands = set(('image-create', 'image-delete', 'help',
+                               'image-download', 'image-show', 'image-update',
+                               'member-add', 'member-create', 'member-delete',
+                               'member-list'))
+        self.assertFalse(wanted_commands - commands)
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 02bfdcb..ac18490 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -35,9 +35,9 @@
 
 # This should be the username of a user WITH administrative privileges
 admin_username = admin
-# The above non-administrative user's password
+# The above administrative user's password
 admin_password = secret
-# The above non-administrative user's tenant name
+# The above administrative user's tenant name
 admin_tenant_name = admin
 
 [compute]
@@ -178,7 +178,7 @@
 tenant_network_cidr = 10.100.0.0/16
 
 # The mask bits used to partition the tenant block.
-tenant_network_mask_bits = 29
+tenant_network_mask_bits = 28
 
 # If tenant networks are reachable, connectivity checks will be
 # performed directly against addresses on those networks.
diff --git a/run_tests.sh b/run_tests.sh
index 93edfaf..25b9729 100755
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -33,7 +33,7 @@
 config_file=""
 update=0
 
-if ! options=$(getopt -o VNnfuswcphdsC: -l virtual-env,no-virtual-env,no-site-packages,force,update,smoke,whitebox,nova-coverage,pep8,help,debug,stdout,config: -- "$@")
+if ! options=$(getopt -o VNnfuswcphdSC: -l virtual-env,no-virtual-env,no-site-packages,force,update,smoke,whitebox,nova-coverage,pep8,help,debug,stdout,config: -- "$@")
 then
     # parse error
     usage
@@ -95,14 +95,7 @@
 
 function run_pep8 {
   echo "Running pep8 ..."
-  srcfiles="`find tempest -type f -name "*.py"`"
-  srcfiles+=" `find tools -type f -name "*.py"`"
-  srcfiles+=" `find stress -type f -name "*.py"`"
-  srcfiles+=" setup.py"
-
-  ignore='--ignore=E121,E122,E125,E126'
-
-    ${wrapper} python tools/hacking.py ${ignore} ${srcfiles}
+  ${wrapper} tools/check_source.sh
 }
 
 function run_coverage_start {
diff --git a/setup.py b/setup.py
index 1f071bb..1507797 100755
--- a/setup.py
+++ b/setup.py
@@ -25,7 +25,7 @@
 depend_links = common_setup.parse_dependency_links()
 
 setuptools.setup(name='tempest',
-                 version="2012.2",
+                 version=common_setup.get_version('tempest', "2013.2"),
                  description='Integration test tools',
                  author='OpenStack',
                  author_email='openstack-qa@lists.launchpad.net',
diff --git a/tempest/clients.py b/tempest/clients.py
index b3b5906..7d9a263 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -48,8 +48,11 @@
 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.xml.endpoints_client import EndPointClientXML
 from tempest.services.identity.xml.identity_client import IdentityClientXML
 from tempest.services.identity.xml.identity_client import TokenClientXML
 from tempest.services.image.v1.json.image_client import ImageClientJSON
@@ -157,6 +160,11 @@
     "xml": InterfacesClientXML,
 }
 
+ENDPOINT_CLIENT = {
+    "json": EndPointClientJSON,
+    "xml": EndPointClientXML,
+}
+
 
 class Manager(object):
 
@@ -219,6 +227,7 @@
             self.security_groups_client = \
                 SECURITY_GROUPS_CLIENT[interface](*client_args)
             self.interfaces_client = INTERFACES_CLIENT[interface](*client_args)
+            self.endpoints_client = ENDPOINT_CLIENT[interface](*client_args)
         except KeyError:
             msg = "Unsupported interface type `%s'" % interface
             raise exceptions.InvalidConfiguration(msg)
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index d68b9ed..fba3b0f 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -135,12 +135,14 @@
 
         headers = {'Content-Type': 'application/json'}
         body = json.dumps(creds)
-        resp, body = self.http_obj.request(auth_url, 'POST',
-                                           headers=headers, body=body)
+        self._log_request('POST', auth_url, headers, body)
+        resp, resp_body = self.http_obj.request(auth_url, 'POST',
+                                                headers=headers, body=body)
+        self._log_response(resp, resp_body)
 
         if resp.status == 200:
             try:
-                auth_data = json.loads(body)['access']
+                auth_data = json.loads(resp_body)['access']
                 token = auth_data['token']['id']
             except Exception, e:
                 print "Failed to obtain token for user: %s" % e
@@ -155,23 +157,18 @@
                             mgmt_url = _ep[self.endpoint_url]
                     if not mgmt_url:
                         mgmt_url = ep['endpoints'][0][self.endpoint_url]
-                    tenant_id = auth_data['token']['tenant']['id']
                     break
 
             if mgmt_url is None:
                 raise exceptions.EndpointNotFound(service)
 
-            if service == 'network':
-                # Keystone does not return the correct endpoint for
-                # quantum. Handle this separately.
-                mgmt_url = (mgmt_url + self.config.network.api_version +
-                            "/tenants/" + tenant_id)
-
             return token, mgmt_url
 
         elif resp.status == 401:
             raise exceptions.AuthenticationFailure(user=user,
                                                    password=password)
+        raise exceptions.IdentityError('Unexpected status code {0}'.format(
+            resp.status))
 
     def post(self, url, body, headers):
         return self.request('POST', url, headers, body)
@@ -182,6 +179,9 @@
     def delete(self, url, headers=None):
         return self.request('DELETE', url, headers)
 
+    def patch(self, url, body, headers):
+        return self.request('PATCH', url, headers, body)
+
     def put(self, url, body, headers):
         return self.request('PUT', url, headers, body)
 
@@ -236,7 +236,7 @@
 
     def response_checker(self, method, url, headers, body, resp, resp_body):
         if (resp.status in set((204, 205, 304)) or resp.status < 200 or
-            method.upper() == 'HEAD') and resp_body:
+                method.upper() == 'HEAD') and resp_body:
             raise exceptions.ResponseWithNonEmptyBody(status=resp.status)
         #NOTE(afazekas):
         # If the HTTP Status Code is 205
@@ -320,6 +320,10 @@
             except KeyError:
                 ctype = 'application/json'
 
+        # It is not an error response
+        if resp.status < 400:
+            return
+
         JSON_ENC = ['application/json; charset=UTF-8', 'application/json',
                     'application/json; charset=utf-8']
         # NOTE(mtreinish): This is for compatibility with Glance and swift
@@ -390,7 +394,7 @@
 
     def is_absolute_limit(self, resp, resp_body):
         if (not isinstance(resp_body, collections.Mapping) or
-            'retry-after' not in resp):
+                'retry-after' not in resp):
             return True
         over_limit = resp_body.get('overLimit', None)
         if not over_limit:
@@ -424,6 +428,6 @@
 
     def is_absolute_limit(self, resp, resp_body):
         if (not isinstance(resp_body, collections.Mapping) or
-            'retry-after' not in resp):
+                'retry-after' not in resp):
             return True
         return 'exceed' in resp_body.get('message', 'blabla')
diff --git a/tempest/common/utils/data_utils.py b/tempest/common/utils/data_utils.py
index 82982b8..e75b54f 100644
--- a/tempest/common/utils/data_utils.py
+++ b/tempest/common/utils/data_utils.py
@@ -24,10 +24,10 @@
 
 
 def rand_name(name='test'):
-    return name + str(random.randint(1, 999999))
+    return name + str(random.randint(1, 0x7fffffff))
 
 
-def rand_int_id(start=0, end=999999):
+def rand_int_id(start=0, end=0x7fffffff):
     return random.randint(start, end)
 
 
diff --git a/tempest/config.py b/tempest/config.py
index 3a4a8c9..9c41660 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -260,9 +260,6 @@
     cfg.StrOpt('catalog_type',
                default='network',
                help='Catalog type of the Quantum service.'),
-    cfg.StrOpt('api_version',
-               default="v1.1",
-               help="Version of Quantum API"),
     cfg.StrOpt('tenant_network_cidr',
                default="10.100.0.0/16",
                help="The cidr block to allocate tenant networks from"),
diff --git a/tempest/services/compute/json/flavors_client.py b/tempest/services/compute/json/flavors_client.py
index 955068f..1b965f3 100644
--- a/tempest/services/compute/json/flavors_client.py
+++ b/tempest/services/compute/json/flavors_client.py
@@ -106,3 +106,29 @@
         """Unsets extra Specs from the mentioned flavor."""
         return self.delete('flavors/%s/os-extra_specs/%s' % (str(flavor_id),
                            key))
+
+    def add_flavor_access(self, flavor_id, tenant_id):
+        """Add flavor access for the specified tenant."""
+        post_body = {
+            'addTenantAccess': {
+                'tenant': tenant_id
+            }
+        }
+        post_body = json.dumps(post_body)
+        resp, body = self.post('flavors/%s/action' % flavor_id,
+                               post_body, self.headers)
+        body = json.loads(body)
+        return resp, body['flavor_access']
+
+    def remove_flavor_access(self, flavor_id, tenant_id):
+        """Remove flavor access from the specified tenant."""
+        post_body = {
+            'removeTenantAccess': {
+                'tenant': tenant_id
+            }
+        }
+        post_body = json.dumps(post_body)
+        resp, body = self.post('flavors/%s/action' % flavor_id,
+                               post_body, self.headers)
+        body = json.loads(body)
+        return resp, body['flavor_access']
diff --git a/tempest/services/compute/json/floating_ips_client.py b/tempest/services/compute/json/floating_ips_client.py
index d73b8a9..27733ac 100644
--- a/tempest/services/compute/json/floating_ips_client.py
+++ b/tempest/services/compute/json/floating_ips_client.py
@@ -47,10 +47,12 @@
             raise exceptions.NotFound(body)
         return resp, body['floating_ip']
 
-    def create_floating_ip(self):
+    def create_floating_ip(self, pool_name=None):
         """Allocate a floating IP to the project."""
         url = 'os-floating-ips'
-        resp, body = self.post(url, None, None)
+        post_body = {'pool': pool_name}
+        post_body = json.dumps(post_body)
+        resp, body = self.post(url, post_body, self.headers)
         body = json.loads(body)
         return resp, body['floating_ip']
 
diff --git a/tempest/services/compute/json/quotas_client.py b/tempest/services/compute/json/quotas_client.py
index 330e80b..37d4131 100644
--- a/tempest/services/compute/json/quotas_client.py
+++ b/tempest/services/compute/json/quotas_client.py
@@ -37,7 +37,7 @@
 
     def update_quota_set(self, tenant_id, injected_file_content_bytes=None,
                          metadata_items=None, ram=None, floating_ips=None,
-                         key_pairs=None, instances=None,
+                         fixed_ips=None, key_pairs=None, instances=None,
                          security_group_rules=None, injected_files=None,
                          cores=None, injected_file_path_bytes=None,
                          security_groups=None):
@@ -59,6 +59,9 @@
         if floating_ips is not None:
             post_body['floating_ips'] = floating_ips
 
+        if fixed_ips is not None:
+            post_body['fixed_ips'] = fixed_ips
+
         if key_pairs is not None:
             post_body['key_pairs'] = key_pairs
 
diff --git a/tempest/services/compute/json/security_groups_client.py b/tempest/services/compute/json/security_groups_client.py
index 7f430d8..1dc11c4 100644
--- a/tempest/services/compute/json/security_groups_client.py
+++ b/tempest/services/compute/json/security_groups_client.py
@@ -19,6 +19,7 @@
 import urllib
 
 from tempest.common.rest_client import RestClient
+from tempest import exceptions
 
 
 class SecurityGroupsClientJSON(RestClient):
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index bc9d9bd..9e71f3d 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -52,6 +52,7 @@
         min_count: Count of minimum number of instances to launch.
         max_count: Count of maximum number of instances to launch.
         disk_config: Determines if user or admin controls disk configuration.
+        return_reservation_id: Enable/Disable the return of reservation id
         """
         post_body = {
             'name': name,
@@ -63,7 +64,8 @@
                        'security_groups', 'networks', 'user_data',
                        'availability_zone', 'accessIPv4', 'accessIPv6',
                        'min_count', 'max_count', ('metadata', 'meta'),
-                       ('OS-DCF:diskConfig', 'disk_config')]:
+                       ('OS-DCF:diskConfig', 'disk_config'),
+                       'return_reservation_id']:
             if isinstance(option, tuple):
                 post_param = option[0]
                 key = option[1]
@@ -77,6 +79,10 @@
         resp, body = self.post('servers', post_body, self.headers)
 
         body = json.loads(body)
+        # NOTE(maurosr): this deals with the case of multiple server create
+        # with return reservation id set True
+        if 'reservation_id' in body:
+            return resp, body
         return resp, body['server']
 
     def update_server(self, server_id, name=None, meta=None, accessIPv4=None,
diff --git a/tempest/services/compute/xml/common.py b/tempest/services/compute/xml/common.py
index 4b1b11a..cb24917 100644
--- a/tempest/services/compute/xml/common.py
+++ b/tempest/services/compute/xml/common.py
@@ -1,6 +1,6 @@
 # vim: tabstop=4 shiftwidth=4 softtabstop=4
 #
-# Copyright 2012 IBM
+# Copyright 2012 IBM Corp.
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/tempest/services/compute/xml/flavors_client.py b/tempest/services/compute/xml/flavors_client.py
index ece362b..a6451df 100644
--- a/tempest/services/compute/xml/flavors_client.py
+++ b/tempest/services/compute/xml/flavors_client.py
@@ -147,3 +147,28 @@
         """Unsets an extra spec based on the mentioned flavor and key."""
         return self.delete('flavors/%s/os-extra_specs/%s' % (str(flavor_id),
                            key))
+
+    def _parse_array_access(self, node):
+        return [xml_to_json(x) for x in node]
+
+    def add_flavor_access(self, flavor_id, tenant_id):
+        """Add flavor access for the specified tenant."""
+        doc = Document()
+        server = Element("addTenantAccess")
+        doc.append(server)
+        server.add_attr("tenant", tenant_id)
+        resp, body = self.post('flavors/%s/action' % str(flavor_id),
+                               str(doc), self.headers)
+        body = self._parse_array_access(etree.fromstring(body))
+        return resp, body
+
+    def remove_flavor_access(self, flavor_id, tenant_id):
+        """Remove flavor access from the specified tenant."""
+        doc = Document()
+        server = Element("removeTenantAccess")
+        doc.append(server)
+        server.add_attr("tenant", tenant_id)
+        resp, body = self.post('flavors/%s/action' % str(flavor_id),
+                               str(doc), self.headers)
+        body = self._parse_array_access(etree.fromstring(body))
+        return resp, body
diff --git a/tempest/services/compute/xml/floating_ips_client.py b/tempest/services/compute/xml/floating_ips_client.py
index 74b4be2..278cc88 100644
--- a/tempest/services/compute/xml/floating_ips_client.py
+++ b/tempest/services/compute/xml/floating_ips_client.py
@@ -1,6 +1,6 @@
 # vim: tabstop=4 shiftwidth=4 softtabstop=4
 #
-# Copyright 2012 IBM
+# Copyright 2012 IBM Corp.
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -22,6 +22,7 @@
 from tempest import exceptions
 from tempest.services.compute.xml.common import Document
 from tempest.services.compute.xml.common import Element
+from tempest.services.compute.xml.common import Text
 from tempest.services.compute.xml.common import xml_to_json
 
 
@@ -60,10 +61,17 @@
             raise exceptions.NotFound(body)
         return resp, body
 
-    def create_floating_ip(self):
+    def create_floating_ip(self, pool_name=None):
         """Allocate a floating IP to the project."""
         url = 'os-floating-ips'
-        resp, body = self.post(url, None, self.headers)
+        if pool_name:
+            doc = Document()
+            pool = Element("pool")
+            pool.append(Text(pool_name))
+            doc.append(pool)
+            resp, body = self.post(url, str(doc), self.headers)
+        else:
+            resp, body = self.post(url, None, self.headers)
         body = self._parse_floating_ip(etree.fromstring(body))
         return resp, body
 
diff --git a/tempest/services/compute/xml/images_client.py b/tempest/services/compute/xml/images_client.py
index 3b01efb..c7e337b 100644
--- a/tempest/services/compute/xml/images_client.py
+++ b/tempest/services/compute/xml/images_client.py
@@ -1,6 +1,6 @@
 # vim: tabstop=4 shiftwidth=4 softtabstop=4
 #
-# Copyright 2012 IBM
+# Copyright 2012 IBM Corp.
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -77,6 +77,19 @@
             data['images'].append(self._parse_image(image))
         return data
 
+    def _parse_key_value(self, node):
+        """Parse <foo key='key'>value</foo> data into {'key': 'value'}."""
+        data = {}
+        for node in node.getchildren():
+            data[node.get('key')] = node.text
+        return data
+
+    def _parse_metadata(self, node):
+        """Parse the response body without children."""
+        data = {}
+        data[node.get('key')] = node.text
+        return data
+
     def create_image(self, server_id, name, meta=None):
         """Creates an image of the original server."""
         post_body = Element('createImage', name=name)
@@ -153,51 +166,53 @@
             if int(time.time()) - start >= self.build_timeout:
                 raise exceptions.TimeoutException
 
+    def _metadata_body(self, meta):
+        post_body = Element('metadata')
+        for k, v in meta.items():
+            data = Element('meta', key=k)
+            data.append(Text(v))
+            post_body.append(data)
+        return post_body
+
     def list_image_metadata(self, image_id):
         """Lists all metadata items for an image."""
         resp, body = self.get("images/%s/metadata" % str(image_id),
                               self.headers)
-        body = xml_to_json(etree.fromstring(body))
-        return resp, body['metadata']
-
-    def _metadata_body(image_id, meta):
-        post_body = Document('metadata')
-        for k, v in meta:
-            text = Text(v)
-            metadata = Element('meta', text, key=k)
-            post_body.append(metadata)
-        return post_body
+        body = self._parse_key_value(etree.fromstring(body))
+        return resp, body
 
     def set_image_metadata(self, image_id, meta):
         """Sets the metadata for an image."""
-        post_body = self._metadata_body(image_id, meta)
-        resp, body = self.put('images/%s/metadata' % str(image_id),
-                              post_body, self.headers)
-        body = xml_to_json(etree.fromstring(body))
-        return resp, body['metadata']
+        post_body = self._metadata_body(meta)
+        resp, body = self.put('images/%s/metadata' % image_id,
+                              str(Document(post_body)), self.headers)
+        body = self._parse_key_value(etree.fromstring(body))
+        return resp, body
 
     def update_image_metadata(self, image_id, meta):
         """Updates the metadata for an image."""
-        post_body = self._metadata_body(image_id, meta)
+        post_body = self._metadata_body(meta)
         resp, body = self.post('images/%s/metadata' % str(image_id),
-                               post_body, self.headers)
-        body = xml_to_json(etree.fromstring(body))
-        return resp, body['metadata']
+                               str(Document(post_body)), self.headers)
+        body = self._parse_key_value(etree.fromstring(body))
+        return resp, body
 
     def get_image_metadata_item(self, image_id, key):
         """Returns the value for a specific image metadata key."""
         resp, body = self.get("images/%s/metadata/%s.xml" %
                               (str(image_id), key), self.headers)
-        body = xml_to_json(etree.fromstring(body))
-        return resp, body['meta']
+        body = self._parse_metadata(etree.fromstring(body))
+        return resp, body
 
     def set_image_metadata_item(self, image_id, key, meta):
         """Sets the value for a specific image metadata key."""
-        post_body = Document('meta', Text(meta), key=key)
-        resp, body = self.post('images/%s/metadata/%s' % (str(image_id), key),
-                               post_body, self.headers)
+        for k, v in meta.items():
+            post_body = Element('meta', key=key)
+            post_body.append(Text(v))
+        resp, body = self.put('images/%s/metadata/%s' % (str(image_id), key),
+                              str(Document(post_body)), self.headers)
         body = xml_to_json(etree.fromstring(body))
-        return resp, body['meta']
+        return resp, body
 
     def update_image_metadata_item(self, image_id, key, meta):
         """Sets the value for a specific image metadata key."""
@@ -209,6 +224,5 @@
 
     def delete_image_metadata_item(self, image_id, key):
         """Deletes a single image metadata key/value pair."""
-        resp, body = self.delete("images/%s/metadata/%s" % (str(image_id), key,
-                                 self.headers))
-        return resp, body
+        return self.delete("images/%s/metadata/%s" % (str(image_id), key),
+                           self.headers)
diff --git a/tempest/services/compute/xml/keypairs_client.py b/tempest/services/compute/xml/keypairs_client.py
index d258537..0157245 100644
--- a/tempest/services/compute/xml/keypairs_client.py
+++ b/tempest/services/compute/xml/keypairs_client.py
@@ -1,6 +1,6 @@
 # vim: tabstop=4 shiftwidth=4 softtabstop=4
 #
-# Copyright 2012 IBM
+# Copyright 2012 IBM Corp.
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/tempest/services/compute/xml/limits_client.py b/tempest/services/compute/xml/limits_client.py
index d233bba..704de52 100644
--- a/tempest/services/compute/xml/limits_client.py
+++ b/tempest/services/compute/xml/limits_client.py
@@ -1,6 +1,6 @@
 # vim: tabstop=4 shiftwidth=4 softtabstop=4
 #
-# Copyright 2012 IBM
+# Copyright 2012 IBM Corp.
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/tempest/services/compute/xml/quotas_client.py b/tempest/services/compute/xml/quotas_client.py
index 0437205..20e04b4 100644
--- a/tempest/services/compute/xml/quotas_client.py
+++ b/tempest/services/compute/xml/quotas_client.py
@@ -57,7 +57,7 @@
 
     def update_quota_set(self, tenant_id, injected_file_content_bytes=None,
                          metadata_items=None, ram=None, floating_ips=None,
-                         key_pairs=None, instances=None,
+                         fixed_ips=None, key_pairs=None, instances=None,
                          security_group_rules=None, injected_files=None,
                          cores=None, injected_file_path_bytes=None,
                          security_groups=None):
@@ -80,6 +80,9 @@
         if floating_ips is not None:
             post_body.add_attr('floating_ips', floating_ips)
 
+        if fixed_ips is not None:
+            post_body.add_attr('fixed_ips', fixed_ips)
+
         if key_pairs is not None:
             post_body.add_attr('key_pairs', key_pairs)
 
diff --git a/tempest/services/compute/xml/security_groups_client.py b/tempest/services/compute/xml/security_groups_client.py
index 7db60a1..4fccc29 100644
--- a/tempest/services/compute/xml/security_groups_client.py
+++ b/tempest/services/compute/xml/security_groups_client.py
@@ -1,6 +1,6 @@
 # vim: tabstop=4 shiftwidth=4 softtabstop=4
 #
-# Copyright 2012 IBM
+# Copyright 2012 IBM Corp.
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -19,6 +19,7 @@
 import urllib
 
 from tempest.common.rest_client import RestClientXML
+from tempest import exceptions
 from tempest.services.compute.xml.common import Document
 from tempest.services.compute.xml.common import Element
 from tempest.services.compute.xml.common import Text
diff --git a/tempest/services/compute/xml/servers_client.py b/tempest/services/compute/xml/servers_client.py
index fceeb28..f5fd4a6 100644
--- a/tempest/services/compute/xml/servers_client.py
+++ b/tempest/services/compute/xml/servers_client.py
@@ -1,6 +1,6 @@
 # vim: tabstop=4 shiftwidth=4 softtabstop=4
 #
-# Copyright 2012 IBM
+# Copyright 2012 IBM Corp.
 # Copyright 2013 Hewlett-Packard Development Company, L.P.
 # All Rights Reserved.
 #
@@ -94,6 +94,11 @@
         json['addresses'] = json_addresses
     else:
         json = xml_to_json(xml_dom)
+    diskConfig = '{http://docs.openstack.org/compute/ext/disk_config/api/v1.1'\
+                 '}diskConfig'
+    if diskConfig in json:
+        json['OS-DCF:diskConfig'] = json[diskConfig]
+        del json[diskConfig]
     return json
 
 
@@ -230,10 +235,16 @@
                          name=name)
 
         for attr in ["adminPass", "accessIPv4", "accessIPv6", "key_name",
-                     "user_data", "availability_zone"]:
+                     "user_data", "availability_zone", "min_count",
+                     "max_count", "return_reservation_id"]:
             if attr in kwargs:
                 server.add_attr(attr, kwargs[attr])
 
+        if 'disk_config' in kwargs:
+            server.add_attr('xmlns:OS-DCF', "http://docs.openstack.org/"
+                            "compute/ext/disk_config/api/v1.1")
+            server.add_attr('OS-DCF:diskConfig', kwargs['disk_config'])
+
         if 'security_groups' in kwargs:
             secgroups = Element("security_groups")
             server.append(secgroups)
@@ -357,6 +368,12 @@
 
     def rebuild(self, server_id, image_ref, **kwargs):
         kwargs['imageRef'] = image_ref
+        if 'disk_config' in kwargs:
+            kwargs['OS-DCF:diskConfig'] = kwargs['disk_config']
+            del kwargs['disk_config']
+            kwargs['xmlns:OS-DCF'] = "http://docs.openstack.org/"\
+                                     "compute/ext/disk_config/api/v1.1"
+            kwargs['xmlns:atom'] = "http://www.w3.org/2005/Atom"
         if 'xmlns' not in kwargs:
             kwargs['xmlns'] = XMLNS_11
 
@@ -381,8 +398,11 @@
 
     def resize(self, server_id, flavor_ref, **kwargs):
         if 'disk_config' in kwargs:
-            raise NotImplementedError("Sorry, disk_config not "
-                                      "supported via XML yet")
+            kwargs['OS-DCF:diskConfig'] = kwargs['disk_config']
+            del kwargs['disk_config']
+            kwargs['xmlns:OS-DCF'] = "http://docs.openstack.org/"\
+                                     "compute/ext/disk_config/api/v1.1"
+            kwargs['xmlns:atom'] = "http://www.w3.org/2005/Atom"
         kwargs['flavorRef'] = flavor_ref
         return self.action(server_id, 'resize', None, **kwargs)
 
@@ -401,6 +421,19 @@
     def remove_security_group(self, server_id, name):
         return self.action(server_id, 'removeSecurityGroup', None, name=name)
 
+    def live_migrate_server(self, server_id, dest_host, use_block_migration):
+        """This should be called with administrator privileges ."""
+
+        req_body = Element("os-migrateLive",
+                           xmlns=XMLNS_11,
+                           disk_over_commit=False,
+                           block_migration=use_block_migration,
+                           host=dest_host)
+
+        resp, body = self.post("servers/%s/action" % str(server_id),
+                               str(Document(req_body)), self.headers)
+        return resp, body
+
     def list_server_metadata(self, server_id):
         resp, body = self.get("servers/%s/metadata" % str(server_id),
                               self.headers)
diff --git a/tempest/services/compute/xml/volumes_extensions_client.py b/tempest/services/compute/xml/volumes_extensions_client.py
index 06cfcfb..4cdc4f0 100644
--- a/tempest/services/compute/xml/volumes_extensions_client.py
+++ b/tempest/services/compute/xml/volumes_extensions_client.py
@@ -1,6 +1,6 @@
 # vim: tabstop=4 shiftwidth=4 softtabstop=4
 #
-# Copyright 2012 IBM
+# Copyright 2012 IBM Corp.
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/tempest/services/identity/v3/__init__.py b/tempest/services/identity/v3/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/services/identity/v3/__init__.py
diff --git a/tempest/services/identity/v3/json/__init__.py b/tempest/services/identity/v3/json/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/services/identity/v3/json/__init__.py
diff --git a/tempest/services/identity/v3/json/endpoints_client.py b/tempest/services/identity/v3/json/endpoints_client.py
new file mode 100755
index 0000000..3cb8f90
--- /dev/null
+++ b/tempest/services/identity/v3/json/endpoints_client.py
@@ -0,0 +1,87 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+#
+# Copyright 2013 OpenStack Foundation
+# 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 urlparse import urlparse
+
+from tempest.common.rest_client import RestClient
+
+
+class EndPointClientJSON(RestClient):
+
+    def __init__(self, config, username, password, auth_url, tenant_name=None):
+        super(EndPointClientJSON, self).__init__(config,
+                                                 username, password,
+                                                 auth_url, tenant_name)
+        self.service = self.config.identity.catalog_type
+        self.endpoint_url = 'adminURL'
+
+    def request(self, method, url, headers=None, body=None, wait=None):
+        """Overriding the existing HTTP request in super class rest_client."""
+        self._set_auth()
+        self.base_url = self.base_url.replace(urlparse(self.base_url).path,
+                                              "/v3")
+        return super(EndPointClientJSON, self).request(method, url,
+                                                       headers=headers,
+                                                       body=body)
+
+    def list_endpoints(self):
+        """GET endpoints."""
+        resp, body = self.get('endpoints')
+        body = json.loads(body)
+        return resp, body['endpoints']
+
+    def create_endpoint(self, service_id, interface, url, **kwargs):
+        """Create endpoint."""
+        region = kwargs.get('region', None)
+        enabled = kwargs.get('enabled', None)
+        post_body = {
+            'service_id': service_id,
+            'interface': interface,
+            'url': url,
+            'region': region,
+            'enabled': enabled
+        }
+        post_body = json.dumps({'endpoint': post_body})
+        resp, body = self.post('endpoints', post_body, self.headers)
+        body = json.loads(body)
+        return resp, body['endpoint']
+
+    def update_endpoint(self, endpoint_id, service_id=None, interface=None,
+                        url=None, region=None, enabled=None):
+        """Updates an endpoint with given parameters."""
+        post_body = {}
+        if service_id is not None:
+            post_body['service_id'] = service_id
+        if interface is not None:
+            post_body['interface'] = interface
+        if url is not None:
+            post_body['url'] = url
+        if region is not None:
+            post_body['region'] = region
+        if enabled is not None:
+            post_body['enabled'] = enabled
+        post_body = json.dumps({'endpoint': post_body})
+        resp, body = self.patch('endpoints/%s' % endpoint_id, post_body,
+                                self.headers)
+        body = json.loads(body)
+        return resp, body['endpoint']
+
+    def delete_endpoint(self, endpoint_id):
+        """Delete endpoint."""
+        resp_header, resp_body = self.delete('endpoints/%s' % endpoint_id)
+        return resp_header, resp_body
diff --git a/tempest/services/identity/v3/xml/__init__.py b/tempest/services/identity/v3/xml/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/services/identity/v3/xml/__init__.py
diff --git a/tempest/services/identity/v3/xml/endpoints_client.py b/tempest/services/identity/v3/xml/endpoints_client.py
new file mode 100755
index 0000000..8400976
--- /dev/null
+++ b/tempest/services/identity/v3/xml/endpoints_client.py
@@ -0,0 +1,107 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+#
+# Copyright 2013 OpenStack Foundation
+# 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 urlparse import urlparse
+
+import httplib2
+from lxml import etree
+
+from tempest.common.rest_client import RestClientXML
+from tempest.services.compute.xml.common import Document
+from tempest.services.compute.xml.common import Element
+from tempest.services.compute.xml.common import xml_to_json
+
+XMLNS = "http://docs.openstack.org/identity/api/v3"
+
+
+class EndPointClientXML(RestClientXML):
+
+    def __init__(self, config, username, password, auth_url, tenant_name=None):
+        super(EndPointClientXML, self).__init__(config, username, password,
+                                                auth_url, tenant_name)
+        self.service = self.config.identity.catalog_type
+        self.endpoint_url = 'adminURL'
+
+    def _parse_array(self, node):
+        array = []
+        for child in node.getchildren():
+            tag_list = child.tag.split('}', 1)
+            if tag_list[1] == "endpoint":
+                array.append(xml_to_json(child))
+        return array
+
+    def _parse_body(self, body):
+        json = xml_to_json(body)
+        return json
+
+    def request(self, method, url, headers=None, body=None, wait=None):
+        """Overriding the existing HTTP request in super class RestClient."""
+        dscv = self.config.identity.disable_ssl_certificate_validation
+        self.http_obj = httplib2.Http(disable_ssl_certificate_validation=dscv)
+        self._set_auth()
+        self.base_url = self.base_url.replace(urlparse(self.base_url).path,
+                                              "/v3")
+        return super(EndPointClientXML, self).request(method, url,
+                                                      headers=headers,
+                                                      body=body)
+
+    def list_endpoints(self):
+        """Get the list of endpoints."""
+        resp, body = self.get("endpoints", self.headers)
+        body = self._parse_array(etree.fromstring(body))
+        return resp, body
+
+    def create_endpoint(self, service_id, interface, url, **kwargs):
+        """Create endpoint."""
+        region = kwargs.get('region', None)
+        enabled = kwargs.get('enabled', None)
+        create_endpoint = Element("endpoint",
+                                  xmlns=XMLNS,
+                                  service_id=service_id,
+                                  interface=interface,
+                                  url=url, region=region,
+                                  enabled=enabled)
+        resp, body = self.post('endpoints', str(Document(create_endpoint)),
+                               self.headers)
+        body = self._parse_body(etree.fromstring(body))
+        return resp, body
+
+    def update_endpoint(self, endpoint_id, service_id=None, interface=None,
+                        url=None, region=None, enabled=None):
+        """Updates an endpoint with given parameters."""
+        doc = Document()
+        endpoint = Element("endpoint")
+        doc.append(endpoint)
+
+        if service_id:
+            endpoint.add_attr("service_id", service_id)
+        if interface:
+            endpoint.add_attr("interface", interface)
+        if url:
+            endpoint.add_attr("url", url)
+        if region:
+            endpoint.add_attr("region", region)
+        if enabled is not None:
+            endpoint.add_attr("enabled", enabled)
+        resp, body = self.patch('endpoints/%s' % str(endpoint_id),
+                                str(doc), self.headers)
+        body = self._parse_body(etree.fromstring(body))
+        return resp, body
+
+    def delete_endpoint(self, endpoint_id):
+        """Delete endpoint."""
+        resp_header, resp_body = self.delete('endpoints/%s' % endpoint_id)
+        return resp_header, resp_body
diff --git a/tempest/services/identity/xml/identity_client.py b/tempest/services/identity/xml/identity_client.py
index 2431282..6f1b1b3 100644
--- a/tempest/services/identity/xml/identity_client.py
+++ b/tempest/services/identity/xml/identity_client.py
@@ -1,6 +1,6 @@
 # vim: tabstop=4 shiftwidth=4 softtabstop=4
 #
-# Copyright 2012 IBM
+# Copyright 2012 IBM Corp.
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/tempest/services/image/v1/json/image_client.py b/tempest/services/image/v1/json/image_client.py
index 77c9cd2..a3b3e96 100644
--- a/tempest/services/image/v1/json/image_client.py
+++ b/tempest/services/image/v1/json/image_client.py
@@ -1,6 +1,6 @@
 # vim: tabstop=4 shiftwidth=4 softtabstop=4
 #
-# Copyright 2013 IBM
+# Copyright 2013 IBM Corp.
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -18,13 +18,17 @@
 import copy
 import errno
 import json
+import logging
 import os
+import time
 import urllib
 
 from tempest.common import glance_http
 from tempest.common.rest_client import RestClient
 from tempest import exceptions
 
+LOG = logging.getLogger(__name__)
+
 
 class ImageClientJSON(RestClient):
 
@@ -59,8 +63,13 @@
     def _image_meta_to_headers(self, fields):
         headers = {}
         fields_copy = copy.deepcopy(fields)
+        copy_from = fields_copy.pop('copy_from', None)
+        if copy_from is not None:
+            headers['x-glance-api-copy-from'] = copy_from
         for key, value in fields_copy.pop('properties', {}).iteritems():
             headers['x-image-meta-property-%s' % key] = str(value)
+        for key, value in fields_copy.pop('api', {}).iteritems():
+            headers['x-glance-api-property-%s' % key] = str(value)
         for key, value in fields_copy.iteritems():
             headers['x-image-meta-%s' % key] = str(value)
         return headers
@@ -130,7 +139,7 @@
 
         headers = {}
 
-        for option in ['is_public', 'location', 'properties']:
+        for option in ['is_public', 'location', 'properties', 'copy_from']:
             if option in kwargs:
                 params[option] = kwargs.get(option)
 
@@ -187,10 +196,15 @@
         body = json.loads(body)
         return resp, body['images']
 
+    def get_image_meta(self, image_id):
+        url = 'v1/images/%s' % image_id
+        resp, __ = self.head(url)
+        body = self._image_meta_from_headers(resp)
+        return resp, body
+
     def get_image(self, image_id):
         url = 'v1/images/%s' % image_id
-        resp, __ = self.get(url)
-        body = self._image_meta_from_headers(resp)
+        resp, body = self.get(url)
         return resp, body
 
     def is_resource_deleted(self, id):
@@ -231,3 +245,34 @@
         resp, data = self.put(url, body, self.headers)
         data = json.loads(data)
         return resp, data
+
+    #NOTE(afazekas): just for the wait function
+    def _get_image_status(self, image_id):
+        resp, meta = self.get_image_meta(image_id)
+        status = meta['status']
+        return status
+
+    #NOTE(afazkas): Wait reinvented again. It is not in the correct layer
+    def wait_for_image_status(self, image_id, status):
+        """Waits for a Image to reach a given status."""
+        start_time = time.time()
+        old_value = value = self._get_image_status(image_id)
+        while True:
+            dtime = time.time() - start_time
+            time.sleep(self.build_interval)
+            if value != old_value:
+                LOG.info('Value transition from "%s" to "%s"'
+                         'in %d second(s).', old_value,
+                         value, dtime)
+            if (value == status):
+                return value
+
+            if dtime > self.build_timeout:
+                message = ('Time Limit Exceeded! (%ds)'
+                           'while waiting for %s, '
+                           'but we got %s.' %
+                           (self.build_timeout, status, value))
+                raise exceptions.TimeoutException(message)
+            time.sleep(self.build_interval)
+            old_value = value
+            value = self._get_image_status(image_id)
diff --git a/tempest/services/image/v2/json/image_client.py b/tempest/services/image/v2/json/image_client.py
index 2c50a8d..f0531ec 100644
--- a/tempest/services/image/v2/json/image_client.py
+++ b/tempest/services/image/v2/json/image_client.py
@@ -1,6 +1,6 @@
 # vim: tabstop=4 shiftwidth=4 softtabstop=4
 #
-# Copyright 2013 IBM
+# Copyright 2013 IBM Corp.
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index 34342c9..4758ddd 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -4,98 +4,112 @@
 
 class NetworkClient(RestClient):
 
+    """
+    Tempest REST client for Quantum. Uses v2 of the Quantum API, since the
+    V1 API has been removed from the code base.
+
+    Implements the following operations for each one of the basic Quantum
+    abstractions (networks, sub-networks and ports):
+
+    create
+    delete
+    list
+    show
+    """
+
     def __init__(self, config, username, password, auth_url, tenant_name=None):
         super(NetworkClient, self).__init__(config, username, password,
                                             auth_url, tenant_name)
         self.service = self.config.network.catalog_type
+        self.version = '2.0'
+        self.uri_prefix = "v%s" % (self.version)
 
     def list_networks(self):
-        resp, body = self.get('networks')
+        uri = '%s/networks' % (self.uri_prefix)
+        resp, body = self.get(uri, self.headers)
         body = json.loads(body)
         return resp, body
 
-    def create_network(self, name, key="network"):
+    def create_network(self, name):
         post_body = {
-            key: {
+            'network': {
                 'name': name,
             }
         }
-        headers = {'Content-Type': 'application/json'}
         body = json.dumps(post_body)
-        resp, body = self.post('networks', headers=headers, body=body)
+        uri = '%s/networks' % (self.uri_prefix)
+        resp, body = self.post(uri, headers=self.headers, body=body)
         body = json.loads(body)
         return resp, body
 
-    def list_networks_details(self):
-        resp, body = self.get('networks/detail')
-        body = json.loads(body)
-        return resp, body
-
-    def get_network(self, uuid):
-        resp, body = self.get('networks/%s' % uuid)
-        body = json.loads(body)
-        return resp, body
-
-    def get_network_details(self, uuid):
-        resp, body = self.get('networks/%s/detail' % uuid)
+    def show_network(self, uuid):
+        uri = '%s/networks/%s' % (self.uri_prefix, uuid)
+        resp, body = self.get(uri, self.headers)
         body = json.loads(body)
         return resp, body
 
     def delete_network(self, uuid):
-        resp, body = self.delete('networks/%s' % uuid)
+        uri = '%s/networks/%s' % (self.uri_prefix, uuid)
+        resp, body = self.delete(uri, self.headers)
         return resp, body
 
-    def create_port(self, network_id, zone, state=None, key='port'):
+    def create_subnet(self, net_uuid, cidr):
+        post_body = dict(
+            subnet=dict(
+                ip_version=4,
+                network_id=net_uuid,
+                cidr=cidr),)
+        body = json.dumps(post_body)
+        uri = '%s/subnets' % (self.uri_prefix)
+        resp, body = self.post(uri, headers=self.headers, body=body)
+        body = json.loads(body)
+        return resp, body
+
+    def delete_subnet(self, uuid):
+        uri = '%s/subnets/%s' % (self.uri_prefix, uuid)
+        resp, body = self.delete(uri, self.headers)
+        return resp, body
+
+    def list_subnets(self):
+        uri = '%s/subnets' % (self.uri_prefix)
+        resp, body = self.get(uri, self.headers)
+        body = json.loads(body)
+        return resp, body
+
+    def show_subnet(self, uuid):
+        uri = '%s/subnets/%s' % (self.uri_prefix, uuid)
+        resp, body = self.get(uri, self.headers)
+        body = json.loads(body)
+        return resp, body
+
+    def create_port(self, network_id, state=None):
         if not state:
-            state = 'ACTIVE'
+            state = True
         post_body = {
-            key: {
-                'state': state,
-                'nova_id': zone
+            'port': {
+                'network_id': network_id,
+                'admin_state_up': state,
             }
         }
-        headers = {'Content-Type': 'application/json'}
         body = json.dumps(post_body)
-        resp, body = self.post('networks/%s/ports.json' % network_id,
-                               headers=headers, body=body)
+        uri = '%s/ports' % (self.uri_prefix)
+        resp, body = self.post(uri, headers=self.headers, body=body)
         body = json.loads(body)
         return resp, body
 
-    def delete_port(self, network_id, port_id):
-        resp, body = self.delete('networks/%s/ports/%s.json' %
-                                 (network_id, port_id))
+    def delete_port(self, port_id):
+        uri = '%s/ports/%s' % (self.uri_prefix, port_id)
+        resp, body = self.delete(uri, self.headers)
         return resp, body
 
-    def list_ports(self, network_id):
-        resp, body = self.get('networks/%s/ports.json' % network_id)
+    def list_ports(self):
+        uri = '%s/ports' % (self.uri_prefix)
+        resp, body = self.get(uri, self.headers)
         body = json.loads(body)
         return resp, body
 
-    def list_port_details(self, network_id):
-        url = 'networks/%s/ports/detail.json' % network_id
-        resp, body = self.get(url)
-        body = json.loads(body)
-        return resp, body
-
-    def attach_port(self, network_id, port_id, interface_id):
-        post_body = {
-            'attachment': {
-                'id': interface_id
-            }
-        }
-        headers = {'Content-Type': 'application/json'}
-        body = json.dumps(post_body)
-        url = 'networks/%s/ports/%s/attachment.json' % (network_id, port_id)
-        resp, body = self.put(url, headers=headers, body=body)
-        return resp, body
-
-    def detach_port(self, network_id, port_id):
-        url = 'networks/%s/ports/%s/attachment.json' % (network_id, port_id)
-        resp, body = self.delete(url)
-        return resp, body
-
-    def list_port_attachment(self, network_id, port_id):
-        url = 'networks/%s/ports/%s/attachment.json' % (network_id, port_id)
-        resp, body = self.get(url)
+    def show_port(self, port_id):
+        uri = '%s/ports/%s' % (self.uri_prefix, port_id)
+        resp, body = self.get(uri, self.headers)
         body = json.loads(body)
         return resp, body
diff --git a/tempest/services/volume/json/volumes_client.py b/tempest/services/volume/json/volumes_client.py
index 6b0befd..87c0eba 100644
--- a/tempest/services/volume/json/volumes_client.py
+++ b/tempest/services/volume/json/volumes_client.py
@@ -72,6 +72,7 @@
         metadata: A dictionary of values to be used as metadata.
         volume_type: Optional Name of volume_type for the volume
         snapshot_id: When specified the volume is created from this snapshot
+        imageRef: When specified the volume is created from this image
         """
         post_body = {'size': size}
         post_body.update(kwargs)
diff --git a/tempest/services/volume/xml/admin/volume_types_client.py b/tempest/services/volume/xml/admin/volume_types_client.py
index 49cbadb..42e7b9a 100644
--- a/tempest/services/volume/xml/admin/volume_types_client.py
+++ b/tempest/services/volume/xml/admin/volume_types_client.py
@@ -1,6 +1,6 @@
 # vim: tabstop=4 shiftwidth=4 softtabstop=4
 #
-# Copyright 2012 IBM
+# Copyright 2012 IBM Corp.
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/tempest/services/volume/xml/volumes_client.py b/tempest/services/volume/xml/volumes_client.py
index 4c15256..8eda26b 100644
--- a/tempest/services/volume/xml/volumes_client.py
+++ b/tempest/services/volume/xml/volumes_client.py
@@ -1,6 +1,6 @@
 # vim: tabstop=4 shiftwidth=4 softtabstop=4
 #
-# Copyright 2012 IBM
+# Copyright 2012 IBM Corp.
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -100,6 +100,8 @@
         :param volume_type: Optional Name of volume_type for the volume
         :param snapshot_id: When specified the volume is created from
                             this snapshot
+        :param imageRef: When specified the volume is created from this
+                         image
         """
         #NOTE(afazekas): it should use a volume namespace
         volume = Element("volume", xmlns=XMLNS_11, size=size)
diff --git a/tempest/smoke.py b/tempest/smoke.py
deleted file mode 100644
index 0d4043f..0000000
--- a/tempest/smoke.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 OpenStack, LLC
-# 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 logging
-
-from tempest import test
-
-LOG = logging.getLogger(__name__)
-
-
-class SmokeTest(object):
-
-    """
-    Base test case class mixin for "smoke tests"
-
-    Smoke tests are tests that have the following characteristics:
-
-     * Test basic operations of an API, typically in an order that
-       a regular user would perform those operations
-     * Test only the correct inputs and action paths -- no fuzz or
-       random input data is sent, only valid inputs.
-     * Use only the default client tool for calling an API
-    """
-    pass
-
-
-class DefaultClientSmokeTest(test.DefaultClientTest, SmokeTest):
-
-    """
-    Base smoke test case class that provides the default clients to
-    access the various OpenStack APIs.
-    """
-
-    @classmethod
-    def tearDownClass(cls):
-        # NOTE(jaypipes): Because smoke tests are typically run in a specific
-        # order, and because test methods in smoke tests generally create
-        # resources in a particular order, we destroy resources in the reverse
-        # order in which resources are added to the smoke test class object
-        while cls.os_resources:
-            thing = cls.os_resources.pop()
-            LOG.debug("Deleting %r from shared resources of %s" %
-                      (thing, cls.__name__))
-
-            try:
-                # OpenStack resources are assumed to have a delete()
-                # method which destroys the resource...
-                thing.delete()
-            except Exception as e:
-                # If the resource is already missing, mission accomplished.
-                if e.__class__.__name__ == 'NotFound':
-                    continue
-                raise
-
-            def is_deletion_complete():
-                # Deletion testing is only required for objects whose
-                # existence cannot be checked via retrieval.
-                if isinstance(thing, dict):
-                    return True
-                try:
-                    thing.get()
-                except Exception as e:
-                    # Clients are expected to return an exception
-                    # called 'NotFound' if retrieval fails.
-                    if e.__class__.__name__ == 'NotFound':
-                        return True
-                    raise
-                return False
-
-            # Block until resource deletion has completed or timed-out
-            test.call_until_true(is_deletion_complete, 10, 1)
diff --git a/tempest/test.py b/tempest/test.py
index e0639b6..ccb2251 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -115,42 +115,91 @@
     return False
 
 
-class DefaultClientTest(TestCase):
+def status_timeout(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
+    expected status to show. At any time, if the returned
+    status of the thing is ERROR, fail out.
+    """
+    def check_status():
+        # python-novaclient has resources available to its client
+        # that all implement a get() method taking an identifier
+        # for the singular resource to retrieve.
+        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)
+        elif new_status == expected_status:
+            return True  # All good.
+        LOG.debug("Waiting for %s to get to %s status. "
+                  "Currently in %s status",
+                  thing, expected_status, new_status)
+    conf = config.TempestConfig()
+    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))
+
+
+class DefaultClientSmokeTest(TestCase):
 
     """
-    Base test case class that provides the default clients to access
-    the various OpenStack APIs.
+    Base smoke test case class that provides the default clients to
+    access the various OpenStack APIs.
+
+    Smoke tests are tests that have the following characteristics:
+
+     * Test basic operations of an API, typically in an order that
+       a regular user would perform those operations
+     * Test only the correct inputs and action paths -- no fuzz or
+       random input data is sent, only valid inputs.
+     * Use only the default client tool for calling an API
     """
 
     manager_class = manager.DefaultClientManager
 
-    def status_timeout(self, 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
-        expected status to show. At any time, if the returned
-        status of the thing is ERROR, fail out.
-        """
-        def check_status():
-            # python-novaclient has resources available to its client
-            # that all implement a get() method taking an identifier
-            # for the singular resource to retrieve.
-            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)
-            elif new_status == expected_status:
-                return True  # All good.
-            LOG.debug("Waiting for %s to get to %s status. "
-                      "Currently in %s status",
-                      thing, expected_status, new_status)
-        if not call_until_true(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))
+    @classmethod
+    def tearDownClass(cls):
+        # NOTE(jaypipes): Because smoke tests are typically run in a specific
+        # order, and because test methods in smoke tests generally create
+        # resources in a particular order, we destroy resources in the reverse
+        # order in which resources are added to the smoke test class object
+        while cls.os_resources:
+            thing = cls.os_resources.pop()
+            LOG.debug("Deleting %r from shared resources of %s" %
+                      (thing, cls.__name__))
+
+            try:
+                # OpenStack resources are assumed to have a delete()
+                # method which destroys the resource...
+                thing.delete()
+            except Exception as e:
+                # If the resource is already missing, mission accomplished.
+                if e.__class__.__name__ == 'NotFound':
+                    continue
+                raise
+
+            def is_deletion_complete():
+                # Deletion testing is only required for objects whose
+                # existence cannot be checked via retrieval.
+                if isinstance(thing, dict):
+                    return True
+                try:
+                    thing.get()
+                except Exception as e:
+                    # Clients are expected to return an exception
+                    # called 'NotFound' if retrieval fails.
+                    if e.__class__.__name__ == 'NotFound':
+                        return True
+                    raise
+                return False
+
+            # Block until resource deletion has completed or timed-out
+            call_until_true(is_deletion_complete, 10, 1)
 
 
 class ComputeFuzzClientTest(TestCase):
@@ -161,46 +210,3 @@
     """
 
     manager_class = manager.ComputeFuzzClientManager
-
-    def status_timeout(self, client_get_method, thing_id, expected_status):
-        """
-        Given a method to get a resource and an expected status, do a loop,
-        sleeping for a configurable amount of time, checking for the
-        expected status to show. At any time, if the returned
-        status of the thing is ERROR, fail out.
-
-        :param client_get_method: The callable that will retrieve the thing
-                                  with ID :param:thing_id
-        :param thing_id: The ID of the thing to get
-        :param expected_status: String value of the expected status of the
-                                thing that we are looking for.
-
-        :code ..
-
-            Usage:
-
-            def test_some_server_action(self):
-                client = self.servers_client
-                resp, server = client.create_server('random_server')
-                self.status_timeout(client.get_server, server['id'], 'ACTIVE')
-        """
-        def check_status():
-            # Tempest REST client has resources available to its client
-            # that all implement a various get_$resource() methods taking
-            # an identifier for the singular resource to retrieve.
-            thing = client_get_method(thing_id)
-            new_status = thing['status']
-            if new_status == 'ERROR':
-                self.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. "
-                      "Currently in %s status",
-                      thing, expected_status, new_status)
-        if not call_until_true(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))
diff --git a/tempest/tests/boto/test_s3_objects.py b/tempest/tests/boto/test_s3_objects.py
index c735215..dcb7c86 100644
--- a/tempest/tests/boto/test_s3_objects.py
+++ b/tempest/tests/boto/test_s3_objects.py
@@ -18,7 +18,6 @@
 from contextlib import closing
 
 from boto.s3.key import Key
-import testtools
 
 from tempest import clients
 from tempest.common.utils.data_utils import rand_name
diff --git a/tempest/tests/compute/admin/test_flavors.py b/tempest/tests/compute/admin/test_flavors.py
index 7fabf7a..7957009 100644
--- a/tempest/tests/compute/admin/test_flavors.py
+++ b/tempest/tests/compute/admin/test_flavors.py
@@ -39,6 +39,7 @@
             raise cls.skipException(msg)
 
         cls.client = cls.os_adm.flavors_client
+        cls.user_client = cls.os.flavors_client
         cls.flavor_name_prefix = 'test_flavor_'
         cls.ram = 512
         cls.vcpus = 1
@@ -47,6 +48,11 @@
         cls.swap = 1024
         cls.rxtx = 2
 
+    def flavor_clean_up(self, flavor_id):
+        resp, body = self.client.delete_flavor(flavor_id)
+        self.assertEqual(resp.status, 202)
+        self.client.wait_for_resource_deletion(flavor_id)
+
     @attr(type='positive')
     def test_create_flavor(self):
         # Create a flavor and ensure it is listed
@@ -54,43 +60,37 @@
         flavor_name = rand_name(self.flavor_name_prefix)
         new_flavor_id = rand_int_id(start=1000)
 
-        try:
-            #Create the flavor
-            resp, flavor = self.client.create_flavor(flavor_name,
-                                                     self.ram, self.vcpus,
-                                                     self.disk,
-                                                     new_flavor_id,
-                                                     ephemeral=self.ephemeral,
-                                                     swap=self.swap,
-                                                     rxtx=self.rxtx)
-            self.assertEqual(200, resp.status)
-            self.assertEqual(flavor['name'], flavor_name)
-            self.assertEqual(flavor['vcpus'], self.vcpus)
-            self.assertEqual(flavor['disk'], self.disk)
-            self.assertEqual(flavor['ram'], self.ram)
-            self.assertEqual(int(flavor['id']), new_flavor_id)
-            self.assertEqual(flavor['swap'], self.swap)
-            self.assertEqual(flavor['rxtx_factor'], self.rxtx)
-            self.assertEqual(flavor['OS-FLV-EXT-DATA:ephemeral'],
-                             self.ephemeral)
-            if self._interface == "xml":
-                XMLNS_OS_FLV_ACCESS = "http://docs.openstack.org/compute/ext/"\
-                    "flavor_access/api/v2"
-                key = "{" + XMLNS_OS_FLV_ACCESS + "}is_public"
-                self.assertEqual(flavor[key], "True")
-            if self._interface == "json":
-                self.assertEqual(flavor['os-flavor-access:is_public'], True)
+        #Create the flavor
+        resp, flavor = self.client.create_flavor(flavor_name,
+                                                 self.ram, self.vcpus,
+                                                 self.disk,
+                                                 new_flavor_id,
+                                                 ephemeral=self.ephemeral,
+                                                 swap=self.swap,
+                                                 rxtx=self.rxtx)
+        self.addCleanup(self.flavor_clean_up, flavor['id'])
+        self.assertEqual(200, resp.status)
+        self.assertEqual(flavor['name'], flavor_name)
+        self.assertEqual(flavor['vcpus'], self.vcpus)
+        self.assertEqual(flavor['disk'], self.disk)
+        self.assertEqual(flavor['ram'], self.ram)
+        self.assertEqual(int(flavor['id']), new_flavor_id)
+        self.assertEqual(flavor['swap'], self.swap)
+        self.assertEqual(flavor['rxtx_factor'], self.rxtx)
+        self.assertEqual(flavor['OS-FLV-EXT-DATA:ephemeral'],
+                         self.ephemeral)
+        if self._interface == "xml":
+            XMLNS_OS_FLV_ACCESS = "http://docs.openstack.org/compute/ext/"\
+                "flavor_access/api/v2"
+            key = "{" + XMLNS_OS_FLV_ACCESS + "}is_public"
+            self.assertEqual(flavor[key], "True")
+        if self._interface == "json":
+            self.assertEqual(flavor['os-flavor-access:is_public'], True)
 
-            #Verify flavor is retrieved
-            resp, flavor = self.client.get_flavor_details(new_flavor_id)
-            self.assertEqual(resp.status, 200)
-            self.assertEqual(flavor['name'], flavor_name)
-
-        finally:
-            #Delete the flavor
-            resp, body = self.client.delete_flavor(new_flavor_id)
-            self.assertEqual(resp.status, 202)
-            self.client.wait_for_resource_deletion(new_flavor_id)
+        #Verify flavor is retrieved
+        resp, flavor = self.client.get_flavor_details(new_flavor_id)
+        self.assertEqual(resp.status, 200)
+        self.assertEqual(flavor['name'], flavor_name)
 
     @attr(type='positive')
     def test_create_flavor_verify_entry_in_list_details(self):
@@ -99,29 +99,23 @@
         flavor_name = rand_name(self.flavor_name_prefix)
         new_flavor_id = rand_int_id(start=1000)
 
-        try:
-            #Create the flavor
-            resp, flavor = self.client.create_flavor(flavor_name,
-                                                     self.ram, self.vcpus,
-                                                     self.disk,
-                                                     new_flavor_id,
-                                                     ephemeral=self.ephemeral,
-                                                     swap=self.swap,
-                                                     rxtx=self.rxtx)
-            flag = False
-            #Verify flavor is retrieved
-            resp, flavors = self.client.list_flavors_with_detail()
-            self.assertEqual(resp.status, 200)
-            for flavor in flavors:
-                if flavor['name'] == flavor_name:
-                    flag = True
-            self.assertTrue(flag)
-
-        finally:
-            #Delete the flavor
-            resp, body = self.client.delete_flavor(new_flavor_id)
-            self.assertEqual(resp.status, 202)
-            self.client.wait_for_resource_deletion(new_flavor_id)
+        #Create the flavor
+        resp, flavor = self.client.create_flavor(flavor_name,
+                                                 self.ram, self.vcpus,
+                                                 self.disk,
+                                                 new_flavor_id,
+                                                 ephemeral=self.ephemeral,
+                                                 swap=self.swap,
+                                                 rxtx=self.rxtx)
+        self.addCleanup(self.flavor_clean_up, flavor['id'])
+        flag = False
+        #Verify flavor is retrieved
+        resp, flavors = self.client.list_flavors_with_detail()
+        self.assertEqual(resp.status, 200)
+        for flavor in flavors:
+            if flavor['name'] == flavor_name:
+                flag = True
+        self.assertTrue(flag)
 
     @attr(type='negative')
     def test_get_flavor_details_for_deleted_flavor(self):
@@ -137,11 +131,11 @@
                                                  ephemeral=self.ephemeral,
                                                  swap=self.swap,
                                                  rxtx=self.rxtx)
-        self.assertEquals(200, resp.status)
-
         # Delete the flavor
-        resp, _ = self.client.delete_flavor(new_flavor_id)
-        self.assertEqual(resp.status, 202)
+        new_flavor_id = flavor['id']
+        resp_delete, body = self.client.delete_flavor(new_flavor_id)
+        self.assertEquals(200, resp.status)
+        self.assertEquals(202, resp_delete.status)
 
         # Deleted flavors can be seen via detailed GET
         resp, flavor = self.client.get_flavor_details(new_flavor_id)
@@ -163,46 +157,40 @@
         flavor_name = rand_name(self.flavor_name_prefix)
         new_flavor_id = rand_int_id(start=1000)
 
-        try:
-            #Create the flavor
-            resp, flavor = self.client.create_flavor(flavor_name,
-                                                     self.ram, self.vcpus,
-                                                     self.disk,
-                                                     new_flavor_id)
-            self.assertEqual(200, resp.status)
-            self.assertEqual(flavor['name'], flavor_name)
-            self.assertEqual(flavor['ram'], self.ram)
-            self.assertEqual(flavor['vcpus'], self.vcpus)
-            self.assertEqual(flavor['disk'], self.disk)
-            self.assertEqual(int(flavor['id']), new_flavor_id)
-            self.assertEqual(flavor['swap'], '')
-            self.assertEqual(int(flavor['rxtx_factor']), 1)
-            self.assertEqual(int(flavor['OS-FLV-EXT-DATA:ephemeral']), 0)
-            if self._interface == "xml":
-                XMLNS_OS_FLV_ACCESS = "http://docs.openstack.org/compute/ext/"\
-                    "flavor_access/api/v2"
-                key = "{" + XMLNS_OS_FLV_ACCESS + "}is_public"
-                self.assertEqual(flavor[key], "True")
-            if self._interface == "json":
-                self.assertEqual(flavor['os-flavor-access:is_public'], True)
+        #Create the flavor
+        resp, flavor = self.client.create_flavor(flavor_name,
+                                                 self.ram, self.vcpus,
+                                                 self.disk,
+                                                 new_flavor_id)
+        self.addCleanup(self.flavor_clean_up, flavor['id'])
+        self.assertEqual(200, resp.status)
+        self.assertEqual(flavor['name'], flavor_name)
+        self.assertEqual(flavor['ram'], self.ram)
+        self.assertEqual(flavor['vcpus'], self.vcpus)
+        self.assertEqual(flavor['disk'], self.disk)
+        self.assertEqual(int(flavor['id']), new_flavor_id)
+        self.assertEqual(flavor['swap'], '')
+        self.assertEqual(int(flavor['rxtx_factor']), 1)
+        self.assertEqual(int(flavor['OS-FLV-EXT-DATA:ephemeral']), 0)
+        if self._interface == "xml":
+            XMLNS_OS_FLV_ACCESS = "http://docs.openstack.org/compute/ext/"\
+                "flavor_access/api/v2"
+            key = "{" + XMLNS_OS_FLV_ACCESS + "}is_public"
+            self.assertEqual(flavor[key], "True")
+        if self._interface == "json":
+            self.assertEqual(flavor['os-flavor-access:is_public'], True)
 
-            #Verify flavor is retrieved
-            resp, flavor = self.client.get_flavor_details(new_flavor_id)
-            self.assertEqual(resp.status, 200)
-            self.assertEqual(flavor['name'], flavor_name)
-            #Check if flavor is present in list
-            resp, flavors = self.client.list_flavors_with_detail()
-            self.assertEqual(resp.status, 200)
-            for flavor in flavors:
-                if flavor['name'] == flavor_name:
-                    flag = True
-            self.assertTrue(flag)
-
-        finally:
-            #Delete the flavor
-            resp, body = self.client.delete_flavor(new_flavor_id)
-            self.assertEqual(resp.status, 202)
-            self.client.wait_for_resource_deletion(new_flavor_id)
+        #Verify flavor is retrieved
+        resp, flavor = self.client.get_flavor_details(new_flavor_id)
+        self.assertEqual(resp.status, 200)
+        self.assertEqual(flavor['name'], flavor_name)
+        #Check if flavor is present in list
+        resp, flavors = self.client.list_flavors_with_detail()
+        self.assertEqual(resp.status, 200)
+        for flavor in flavors:
+            if flavor['name'] == flavor_name:
+                flag = True
+        self.assertTrue(flag)
 
     @attr(type='positive')
     def test_flavor_not_public_verify_entry_not_in_list_details(self):
@@ -212,25 +200,21 @@
         flavor_name = rand_name(self.flavor_name_prefix)
         new_flavor_id = rand_int_id(start=1000)
 
-        try:
-            #Create the flavor
-            resp, flavor = self.client.create_flavor(flavor_name,
-                                                     self.ram, self.vcpus,
-                                                     self.disk,
-                                                     new_flavor_id,
-                                                     is_public="False")
-            flag = False
-            #Verify flavor is retrieved
-            resp, flavors = self.client.list_flavors_with_detail()
-            self.assertEqual(resp.status, 200)
-            for flavor in flavors:
-                if flavor['name'] == flavor_name:
-                    flag = True
-            self.assertFalse(flag)
-        finally:
-            #Delete the flavor
-            resp, body = self.client.delete_flavor(new_flavor_id)
-            self.assertEqual(resp.status, 202)
+        #Create the flavor
+        resp, flavor = self.client.create_flavor(flavor_name,
+                                                 self.ram, self.vcpus,
+                                                 self.disk,
+                                                 new_flavor_id,
+                                                 is_public="False")
+        self.addCleanup(self.flavor_clean_up, flavor['id'])
+        flag = False
+        #Verify flavor is retrieved
+        resp, flavors = self.client.list_flavors_with_detail()
+        self.assertEqual(resp.status, 200)
+        for flavor in flavors:
+            if flavor['name'] == flavor_name:
+                flag = True
+        self.assertFalse(flag)
 
     def test_list_public_flavor_with_other_user(self):
         #Create a Flavor with public access.
@@ -238,76 +222,65 @@
         flavor_name = rand_name(self.flavor_name_prefix)
         new_flavor_id = rand_int_id(start=1000)
 
-        try:
             #Create the flavor
-            resp, flavor = self.client.create_flavor(flavor_name,
-                                                     self.ram, self.vcpus,
-                                                     self.disk,
-                                                     new_flavor_id,
-                                                     is_public="True")
-            flag = False
-            self.new_client = self.flavors_client
-            #Verify flavor is retrieved with new user
-            resp, flavors = self.new_client.list_flavors_with_detail()
-            self.assertEqual(resp.status, 200)
-            for flavor in flavors:
-                if flavor['name'] == flavor_name:
-                    flag = True
-            self.assertTrue(flag)
-        finally:
-            #Delete the flavor
-            resp, body = self.client.delete_flavor(new_flavor_id)
-            self.assertEqual(resp.status, 202)
-            self.client.wait_for_resource_deletion(new_flavor_id)
+        resp, flavor = self.client.create_flavor(flavor_name,
+                                                 self.ram, self.vcpus,
+                                                 self.disk,
+                                                 new_flavor_id,
+                                                 is_public="True")
+        self.addCleanup(self.flavor_clean_up, flavor['id'])
+        flag = False
+        self.new_client = self.flavors_client
+        #Verify flavor is retrieved with new user
+        resp, flavors = self.new_client.list_flavors_with_detail()
+        self.assertEqual(resp.status, 200)
+        for flavor in flavors:
+            if flavor['name'] == flavor_name:
+                flag = True
+        self.assertTrue(flag)
 
     @attr(type='positive')
     def test_is_public_string_variations(self):
-        try:
-            flavor_id_not_public = rand_int_id(start=1000)
-            flavor_name_not_public = rand_name(self.flavor_name_prefix)
-            flavor_id_public = rand_int_id(start=1000)
-            flavor_name_public = rand_name(self.flavor_name_prefix)
+        flavor_id_not_public = rand_int_id(start=1000)
+        flavor_name_not_public = rand_name(self.flavor_name_prefix)
+        flavor_id_public = rand_int_id(start=1000)
+        flavor_name_public = rand_name(self.flavor_name_prefix)
 
-            # Create a non public flavor
-            resp, flavor = self.client.create_flavor(flavor_name_not_public,
-                                                     self.ram, self.vcpus,
-                                                     self.disk,
-                                                     flavor_id_not_public,
-                                                     is_public="False")
+        # Create a non public flavor
+        resp, flavor = self.client.create_flavor(flavor_name_not_public,
+                                                 self.ram, self.vcpus,
+                                                 self.disk,
+                                                 flavor_id_not_public,
+                                                 is_public="False")
+        self.addCleanup(self.flavor_clean_up, flavor['id'])
 
-            # Create a public flavor
-            resp, flavor = self.client.create_flavor(flavor_name_public,
-                                                     self.ram, self.vcpus,
-                                                     self.disk,
-                                                     flavor_id_public,
-                                                     is_public="True")
+        # Create a public flavor
+        resp, flavor = self.client.create_flavor(flavor_name_public,
+                                                 self.ram, self.vcpus,
+                                                 self.disk,
+                                                 flavor_id_public,
+                                                 is_public="True")
+        self.addCleanup(self.flavor_clean_up, flavor['id'])
 
-            def _flavor_lookup(flavors, flavor_name):
-                for flavor in flavors:
-                    if flavor['name'] == flavor_name:
-                        return flavor
-                return None
+        def _flavor_lookup(flavors, flavor_name):
+            for flavor in flavors:
+                if flavor['name'] == flavor_name:
+                    return flavor
+            return None
 
-            def _test_string_variations(variations, flavor_name):
-                for string in variations:
-                    params = {'is_public': string}
-                    r, flavors = self.client.list_flavors_with_detail(params)
-                    self.assertEqual(r.status, 200)
-                    flavor = _flavor_lookup(flavors, flavor_name)
-                    self.assertNotEqual(flavor, None)
+        def _test_string_variations(variations, flavor_name):
+            for string in variations:
+                params = {'is_public': string}
+                r, flavors = self.client.list_flavors_with_detail(params)
+                self.assertEqual(r.status, 200)
+                flavor = _flavor_lookup(flavors, flavor_name)
+                self.assertNotEqual(flavor, None)
 
-            _test_string_variations(['f', 'false', 'no', '0'],
-                                    flavor_name_not_public)
+        _test_string_variations(['f', 'false', 'no', '0'],
+                                flavor_name_not_public)
 
-            _test_string_variations(['t', 'true', 'yes', '1'],
-                                    flavor_name_public)
-
-        finally:
-            # Delete flavors
-            for flavor_id in [flavor_id_not_public, flavor_id_public]:
-                resp, body = self.client.delete_flavor(flavor_id)
-                self.assertEqual(resp.status, 202)
-                self.client.wait_for_resource_deletion(flavor_id)
+        _test_string_variations(['t', 'true', 'yes', '1'],
+                                flavor_name_public)
 
     @attr(type='negative')
     def test_invalid_is_public_string(self):
@@ -315,7 +288,22 @@
                           self.client.list_flavors_with_detail,
                           {'is_public': 'invalid'})
 
-#TODO(afazekas): Negative tests with regular user
+    @attr(type='negative')
+    def test_create_flavor_as_user(self):
+        flavor_name = rand_name(self.flavor_name_prefix)
+        new_flavor_id = rand_int_id(start=1000)
+
+        self.assertRaises(exceptions.Unauthorized,
+                          self.user_client.create_flavor,
+                          flavor_name, self.ram, self.vcpus, self.disk,
+                          new_flavor_id, ephemeral=self.ephemeral,
+                          swap=self.swap, rxtx=self.rxtx)
+
+    @attr(type='negative')
+    def test_delete_flavor_as_user(self):
+        self.assertRaises(exceptions.Unauthorized,
+                          self.user_client.delete_flavor,
+                          self.flavor_ref_alt)
 
 
 class FlavorsAdminTestXML(FlavorsAdminTestJSON):
diff --git a/tempest/tests/compute/admin/test_flavors_access.py b/tempest/tests/compute/admin/test_flavors_access.py
new file mode 100644
index 0000000..4cc3f57
--- /dev/null
+++ b/tempest/tests/compute/admin/test_flavors_access.py
@@ -0,0 +1,128 @@
+# 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.common.utils.data_utils import rand_int_id
+from tempest.common.utils.data_utils import rand_name
+from tempest import exceptions
+from tempest.test import attr
+from tempest.tests import compute
+from tempest.tests.compute import base
+
+
+class FlavorsAccessTestJSON(base.BaseComputeAdminTest):
+
+    """
+    Tests Flavor Access API extension.
+    Add and remove Flavor Access require admin privileges.
+    """
+
+    _interface = 'json'
+
+    @classmethod
+    def setUpClass(cls):
+        super(FlavorsAccessTestJSON, cls).setUpClass()
+        if not compute.FLAVOR_EXTRA_DATA_ENABLED:
+            msg = "FlavorExtraData extension not enabled."
+            raise cls.skipException(msg)
+
+        cls.client = cls.os_adm.flavors_client
+        admin_client = cls._get_identity_admin_client()
+        resp, tenants = admin_client.list_tenants()
+        cls.tenant_id = [tnt['id'] for tnt in tenants if tnt['name'] ==
+                         cls.flavors_client.tenant_name][0]
+
+        cls.flavor_name_prefix = 'test_flavor_access_'
+        cls.ram = 512
+        cls.vcpus = 1
+        cls.disk = 10
+
+    @attr('positive')
+    def test_flavor_access_add_remove(self):
+        #Test to add and remove flavor access to a given tenant.
+        flavor_name = rand_name(self.flavor_name_prefix)
+        new_flavor_id = rand_int_id(start=1000)
+        resp, new_flavor = self.client.create_flavor(flavor_name,
+                                                     self.ram, self.vcpus,
+                                                     self.disk,
+                                                     new_flavor_id,
+                                                     is_public='False')
+        self.addCleanup(self.client.delete_flavor, new_flavor['id'])
+        #Add flavor access to a tenant.
+        resp_body = {
+            "tenant_id": str(self.tenant_id),
+            "flavor_id": str(new_flavor['id']),
+        }
+        add_resp, add_body = \
+            self.client.add_flavor_access(new_flavor['id'], self.tenant_id)
+        self.assertEqual(add_resp.status, 200)
+        self.assertIn(resp_body, add_body)
+
+        #The flavor is present in list.
+        resp, flavors = self.flavors_client.list_flavors_with_detail()
+        self.assertEqual(resp.status, 200)
+        self.assertIn(new_flavor['id'], map(lambda x: x['id'], flavors))
+
+        #Remove flavor access from a tenant.
+        remove_resp, remove_body = \
+            self.client.remove_flavor_access(new_flavor['id'], self.tenant_id)
+        self.assertEqual(remove_resp.status, 200)
+        self.assertNotIn(resp_body, remove_body)
+
+        #The flavor is not present in list.
+        resp, flavors = self.flavors_client.list_flavors_with_detail()
+        self.assertEqual(resp.status, 200)
+        self.assertNotIn(new_flavor['id'], map(lambda x: x['id'], flavors))
+
+    @attr('negative')
+    def test_flavor_non_admin_add(self):
+        #Test to add flavor access as a user without admin privileges.
+        flavor_name = rand_name(self.flavor_name_prefix)
+        new_flavor_id = rand_int_id(start=1000)
+        resp, new_flavor = self.client.create_flavor(flavor_name,
+                                                     self.ram, self.vcpus,
+                                                     self.disk,
+                                                     new_flavor_id,
+                                                     is_public='False')
+        self.addCleanup(self.client.delete_flavor, new_flavor['id'])
+        self.assertRaises(exceptions.Unauthorized,
+                          self.flavors_client.add_flavor_access,
+                          new_flavor['id'],
+                          self.tenant_id)
+
+    @attr('negative')
+    def test_flavor_non_admin_remove(self):
+        #Test to remove flavor access as a user without admin privileges.
+        flavor_name = rand_name(self.flavor_name_prefix)
+        new_flavor_id = rand_int_id(start=1000)
+        resp, new_flavor = self.client.create_flavor(flavor_name,
+                                                     self.ram, self.vcpus,
+                                                     self.disk,
+                                                     new_flavor_id,
+                                                     is_public='False')
+        self.addCleanup(self.client.delete_flavor, new_flavor['id'])
+        #Add flavor access to a tenant.
+        self.client.add_flavor_access(new_flavor['id'], self.tenant_id)
+        self.addCleanup(self.client.remove_flavor_access,
+                        new_flavor['id'], self.tenant_id)
+        self.assertRaises(exceptions.Unauthorized,
+                          self.flavors_client.remove_flavor_access,
+                          new_flavor['id'],
+                          self.tenant_id)
+
+
+class FlavorsAdminTestXML(FlavorsAccessTestJSON):
+    _interface = 'xml'
diff --git a/tempest/tests/compute/admin/test_quotas.py b/tempest/tests/compute/admin/test_quotas.py
index befcad3..5a9b6f9 100644
--- a/tempest/tests/compute/admin/test_quotas.py
+++ b/tempest/tests/compute/admin/test_quotas.py
@@ -44,7 +44,7 @@
         cls.default_quota_set = {'injected_file_content_bytes': 10240,
                                  'metadata_items': 128, 'injected_files': 5,
                                  'ram': 51200, 'floating_ips': 10,
-                                 'fixed_ips': 10, 'key_pairs': 100,
+                                 'fixed_ips': -1, 'key_pairs': 100,
                                  'injected_file_path_bytes': 255,
                                  'instances': 10, 'security_group_rules': 20,
                                  'cores': 20, 'security_groups': 10}
@@ -60,9 +60,6 @@
 
     @attr(type='smoke')
     def test_get_default_quotas(self):
-        # Tempest two step
-        self.skipTest('Skipped until the Bug 1125468 is resolved')
-
         # Admin can get the default resource quota set for a tenant
         expected_quota_set = self.default_quota_set.copy()
         expected_quota_set['id'] = self.demo_tenant_id
@@ -74,9 +71,6 @@
             self.fail("Admin could not get the default quota set for a tenant")
 
     def test_update_all_quota_resources_for_tenant(self):
-        # Tempest two step
-        self.skipTest('Skipped until the Bug 1125468 is resolved')
-
         # Admin can update all the resource quota limits for a tenant
         new_quota_set = {'injected_file_content_bytes': 20480,
                          'metadata_items': 256, 'injected_files': 10,
@@ -89,6 +83,8 @@
             resp, quota_set = self.adm_client.update_quota_set(
                 self.demo_tenant_id,
                 **new_quota_set)
+            self.addCleanup(self.adm_client.update_quota_set,
+                            self.demo_tenant_id, **self.default_quota_set)
             self.assertEqual(200, resp.status)
             self.assertEqual(new_quota_set, quota_set)
         except Exception:
@@ -103,12 +99,11 @@
 
     #TODO(afazekas): merge these test cases
     def test_get_updated_quotas(self):
-        # Tempest two step
-        self.skipTest('Skipped until the Bug 1125468 is resolved')
-
         # Verify that GET shows the updated quota set
         self.adm_client.update_quota_set(self.demo_tenant_id,
                                          ram='5120')
+        self.addCleanup(self.adm_client.update_quota_set,
+                        self.demo_tenant_id, **self.default_quota_set)
         try:
             resp, quota_set = self.client.get_quota_set(self.demo_tenant_id)
             self.assertEqual(200, resp.status)
diff --git a/tempest/tests/compute/base.py b/tempest/tests/compute/base.py
index 3b2026e..87aa889 100644
--- a/tempest/tests/compute/base.py
+++ b/tempest/tests/compute/base.py
@@ -96,47 +96,45 @@
         operate in an isolated tenant container.
         """
         admin_client = cls._get_identity_admin_client()
-        rand_name_root = rand_name(cls.__name__)
-        if cls.isolated_creds:
-            # Main user already created. Create the alt one...
-            rand_name_root += '-alt'
-        username = rand_name_root + "-user"
-        email = rand_name_root + "@example.com"
-        tenant_name = rand_name_root + "-tenant"
-        tenant_desc = tenant_name + "-desc"
         password = "pass"
 
-        try:
-            resp, tenant = admin_client.create_tenant(name=tenant_name,
-                                                      description=tenant_desc)
-        except exceptions.Duplicate:
-            if cls.config.compute.allow_tenant_reuse:
-                tenant = admin_client.get_tenant_by_name(tenant_name)
-                LOG.info('Re-using existing tenant %s' % tenant)
-            else:
-                msg = ('Unable to create isolated tenant %s because ' +
-                       'it already exists. If this is related to a ' +
-                       'previous test failure, try using ' +
-                       'allow_tenant_reuse in tempest.conf') % tenant_name
-                raise exceptions.Duplicate(msg)
+        while True:
+            try:
+                rand_name_root = rand_name(cls.__name__)
+                if cls.isolated_creds:
+                # Main user already created. Create the alt one...
+                    rand_name_root += '-alt'
+                tenant_name = rand_name_root + "-tenant"
+                tenant_desc = tenant_name + "-desc"
 
-        try:
-            resp, user = admin_client.create_user(username,
-                                                  password,
-                                                  tenant['id'],
-                                                  email)
-        except exceptions.Duplicate:
-            if cls.config.compute.allow_tenant_reuse:
-                user = admin_client.get_user_by_username(tenant['id'],
-                                                         username)
-                LOG.info('Re-using existing user %s' % user)
-            else:
-                msg = ('Unable to create isolated user %s because ' +
-                       'it already exists. If this is related to a ' +
-                       'previous test failure, try using ' +
-                       'allow_tenant_reuse in tempest.conf') % tenant_name
-                raise exceptions.Duplicate(msg)
+                resp, tenant = admin_client.create_tenant(
+                    name=tenant_name, description=tenant_desc)
+                break
+            except exceptions.Duplicate:
+                if cls.config.compute.allow_tenant_reuse:
+                    tenant = admin_client.get_tenant_by_name(tenant_name)
+                    LOG.info('Re-using existing tenant %s', tenant)
+                    break
 
+        while True:
+            try:
+                rand_name_root = rand_name(cls.__name__)
+                if cls.isolated_creds:
+                # Main user already created. Create the alt one...
+                    rand_name_root += '-alt'
+                username = rand_name_root + "-user"
+                email = rand_name_root + "@example.com"
+                resp, user = admin_client.create_user(username,
+                                                      password,
+                                                      tenant['id'],
+                                                      email)
+                break
+            except exceptions.Duplicate:
+                if cls.config.compute.allow_tenant_reuse:
+                    user = admin_client.get_user_by_username(tenant['id'],
+                                                             username)
+                    LOG.info('Re-using existing user %s', user)
+                    break
         # Store the complete creds (including UUID ids...) for later
         # but return just the username, tenant_name, password tuple
         # that the various clients will use.
@@ -184,12 +182,12 @@
 
         resp, server = cls.servers_client.create_server(
             name, image_id, flavor, **kwargs)
+        cls.servers.append(server)
 
         if 'wait_until' in kwargs:
             cls.servers_client.wait_for_server_status(
                 server['id'], kwargs['wait_until'])
 
-        cls.servers.append(server)
         return resp, server
 
     def wait_for(self, condition):
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 888481a..2b21710 100644
--- a/tempest/tests/compute/floating_ips/test_floating_ips_actions.py
+++ b/tempest/tests/compute/floating_ips/test_floating_ips_actions.py
@@ -73,6 +73,14 @@
             #Deleting the floating IP which is created in this method
             self.client.delete_floating_ip(floating_ip_id_allocated)
 
+    @attr(type='negative')
+    def test_allocate_floating_ip_from_nonexistent_pool(self):
+        # Positive test:Allocation of a new floating IP from a nonexistent_pool
+        #to a project should fail
+        self.assertRaises(exceptions.NotFound,
+                          self.client.create_floating_ip,
+                          "non_exist_pool")
+
     @attr(type='positive')
     def test_delete_floating_ip(self):
         # Positive test:Deletion of valid floating IP from project
diff --git a/tempest/tests/compute/images/test_image_metadata.py b/tempest/tests/compute/images/test_image_metadata.py
index 918075c..5d6439b 100644
--- a/tempest/tests/compute/images/test_image_metadata.py
+++ b/tempest/tests/compute/images/test_image_metadata.py
@@ -21,12 +21,12 @@
 from tempest.tests.compute import base
 
 
-class ImagesMetadataTest(base.BaseComputeTest):
+class ImagesMetadataTestJSON(base.BaseComputeTest):
     _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
-        super(ImagesMetadataTest, cls).setUpClass()
+        super(ImagesMetadataTestJSON, cls).setUpClass()
         cls.servers_client = cls.servers_client
         cls.client = cls.images_client
 
@@ -44,10 +44,10 @@
     @classmethod
     def tearDownClass(cls):
         cls.client.delete_image(cls.image_id)
-        super(ImagesMetadataTest, cls).tearDownClass()
+        super(ImagesMetadataTestJSON, cls).tearDownClass()
 
     def setUp(self):
-        super(ImagesMetadataTest, self).setUp()
+        super(ImagesMetadataTestJSON, self).setUp()
         meta = {'key1': 'value1', 'key2': 'value2'}
         resp, _ = self.client.set_image_metadata(self.image_id, meta)
         self.assertEqual(resp.status, 200)
@@ -143,3 +143,7 @@
         # item from nonexistant image
         self.assertRaises(exceptions.NotFound,
                           self.client.delete_image_metadata_item, 999, 'key1')
+
+
+class ImagesMetadataTestXML(ImagesMetadataTestJSON):
+    _interface = 'xml'
diff --git a/tempest/tests/compute/images/test_images.py b/tempest/tests/compute/images/test_images.py
index fb0364a..d9e4153 100644
--- a/tempest/tests/compute/images/test_images.py
+++ b/tempest/tests/compute/images/test_images.py
@@ -108,7 +108,7 @@
         self.assertRaises(exceptions.Duplicate, self.client.create_image,
                           server['id'], snapshot_name)
 
-    @testtools.skip("Until Bug 1039739 is fixed")
+    @testtools.skip("Until Bug #1039739 is fixed")
     @attr(type='negative')
     def test_create_image_when_server_is_rebooting(self):
         # Return error when creating an image of server that is rebooting
diff --git a/tempest/tests/compute/images/test_images_oneserver.py b/tempest/tests/compute/images/test_images_oneserver.py
index f7008f0..ca3dbb5 100644
--- a/tempest/tests/compute/images/test_images_oneserver.py
+++ b/tempest/tests/compute/images/test_images_oneserver.py
@@ -41,7 +41,12 @@
         super(ImagesOneServerTestJSON, cls).setUpClass()
         cls.client = cls.images_client
         cls.servers_client = cls.servers_client
-        resp, cls.server = cls.create_server(wait_until='ACTIVE')
+
+        try:
+            resp, cls.server = cls.create_server(wait_until='ACTIVE')
+        except Exception:
+            cls.tearDownClass()
+            raise
 
         cls.image_ids = []
 
@@ -58,7 +63,7 @@
             cls.alt_client = cls.alt_manager.images_client
 
     @attr(type='negative')
-    @testtools.skip("Until Bug 1006725 is fixed")
+    @testtools.skip("Until Bug #1006725 is fixed")
     def test_create_image_specify_multibyte_character_image_name(self):
         # Return an error if the image name has multi-byte characters
         snapshot_name = rand_name('\xef\xbb\xbf')
@@ -67,7 +72,7 @@
                           snapshot_name)
 
     @attr(type='negative')
-    @testtools.skip("Until Bug 1005423 is fixed")
+    @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-')
@@ -76,7 +81,7 @@
                           self.server['id'], snapshot_name, meta)
 
     @attr(type='negative')
-    @testtools.skip("Until Bug 1005423 is fixed")
+    @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-')
diff --git a/tempest/tests/compute/images/test_list_image_filters.py b/tempest/tests/compute/images/test_list_image_filters.py
index 472f7fb..b1a6f77 100644
--- a/tempest/tests/compute/images/test_list_image_filters.py
+++ b/tempest/tests/compute/images/test_list_image_filters.py
@@ -22,50 +22,61 @@
 from tempest.tests.compute import base
 
 
-class ListImageFiltersTest(base.BaseComputeTest):
+class ListImageFiltersTestJSON(base.BaseComputeTest):
     _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
-        super(ListImageFiltersTest, cls).setUpClass()
+        super(ListImageFiltersTestJSON, cls).setUpClass()
         cls.client = cls.images_client
 
-        resp, cls.server1 = cls.create_server()
-        resp, cls.server2 = cls.create_server(wait_until='ACTIVE')
-        # NOTE(sdague) this is faster than doing the sync wait_util on both
-        cls.servers_client.wait_for_server_status(cls.server1['id'], 'ACTIVE')
+        try:
+            resp, cls.server1 = cls.create_server()
+            resp, cls.server2 = cls.create_server(wait_until='ACTIVE')
+            # NOTE(sdague) this is faster than doing the sync wait_util on both
+            cls.servers_client.wait_for_server_status(cls.server1['id'],
+                                                      'ACTIVE')
 
-        # Create images to be used in the filter tests
-        image1_name = rand_name('image')
-        resp, body = cls.client.create_image(cls.server1['id'], image1_name)
-        cls.image1_id = parse_image_id(resp['location'])
-        cls.client.wait_for_image_resp_code(cls.image1_id, 200)
-        cls.client.wait_for_image_status(cls.image1_id, 'ACTIVE')
-        resp, cls.image1 = cls.client.get_image(cls.image1_id)
+            # Create images to be used in the filter tests
+            image1_name = rand_name('image')
+            resp, body = cls.client.create_image(cls.server1['id'],
+                                                 image1_name)
+            cls.image1_id = parse_image_id(resp['location'])
+            cls.client.wait_for_image_resp_code(cls.image1_id, 200)
+            cls.client.wait_for_image_status(cls.image1_id, 'ACTIVE')
+            resp, cls.image1 = cls.client.get_image(cls.image1_id)
 
-        # Servers have a hidden property for when they are being imaged
-        # Performing back-to-back create image calls on a single
-        # server will sometimes cause failures
-        image3_name = rand_name('image')
-        resp, body = cls.client.create_image(cls.server2['id'], image3_name)
-        cls.image3_id = parse_image_id(resp['location'])
-        cls.client.wait_for_image_resp_code(cls.image3_id, 200)
-        cls.client.wait_for_image_status(cls.image3_id, 'ACTIVE')
-        resp, cls.image3 = cls.client.get_image(cls.image3_id)
+            # Servers have a hidden property for when they are being imaged
+            # Performing back-to-back create image calls on a single
+            # server will sometimes cause failures
+            image3_name = rand_name('image')
+            resp, body = cls.client.create_image(cls.server2['id'],
+                                                 image3_name)
+            cls.image3_id = parse_image_id(resp['location'])
+            cls.client.wait_for_image_resp_code(cls.image3_id, 200)
+            cls.client.wait_for_image_status(cls.image3_id, 'ACTIVE')
+            resp, cls.image3 = cls.client.get_image(cls.image3_id)
 
-        image2_name = rand_name('image')
-        resp, body = cls.client.create_image(cls.server1['id'], image2_name)
-        cls.image2_id = parse_image_id(resp['location'])
-        cls.client.wait_for_image_resp_code(cls.image2_id, 200)
-        cls.client.wait_for_image_status(cls.image2_id, 'ACTIVE')
-        resp, cls.image2 = cls.client.get_image(cls.image2_id)
+            image2_name = rand_name('image')
+            resp, body = cls.client.create_image(cls.server1['id'],
+                                                 image2_name)
+            cls.image2_id = parse_image_id(resp['location'])
+            cls.client.wait_for_image_resp_code(cls.image2_id, 200)
+            cls.client.wait_for_image_status(cls.image2_id, 'ACTIVE')
+            resp, cls.image2 = cls.client.get_image(cls.image2_id)
+        except Exception:
+            cls.clear_servers()
+            cls.client.delete_image(cls.image1_id)
+            cls.client.delete_image(cls.image2_id)
+            cls.client.delete_image(cls.image3_id)
+            raise
 
     @classmethod
     def tearDownClass(cls):
         cls.client.delete_image(cls.image1_id)
         cls.client.delete_image(cls.image2_id)
         cls.client.delete_image(cls.image3_id)
-        super(ListImageFiltersTest, cls).tearDownClass()
+        super(ListImageFiltersTestJSON, cls).tearDownClass()
 
     @attr(type='negative')
     def test_get_image_not_existing(self):
@@ -140,7 +151,9 @@
         # Verify only the expected number of results are returned
         params = {'limit': '1'}
         resp, images = self.client.list_images(params)
-        self.assertEqual(1, len(images))
+        #when _interface='xml', one element for images_links in images
+        #ref: Question #224349
+        self.assertEqual(1, len([x for x in images if 'id' in x]))
 
     @attr(type='positive')
     def test_list_images_filter_by_changes_since(self):
@@ -226,3 +239,7 @@
     def test_get_nonexistant_image(self):
         # Negative test: GET on non existant image should fail
         self.assertRaises(exceptions.NotFound, self.client.get_image, 999)
+
+
+class ListImageFiltersTestXML(ListImageFiltersTestJSON):
+    _interface = 'xml'
diff --git a/tempest/tests/compute/images/test_list_images.py b/tempest/tests/compute/images/test_list_images.py
index d583a95..07c48fe 100644
--- a/tempest/tests/compute/images/test_list_images.py
+++ b/tempest/tests/compute/images/test_list_images.py
@@ -19,18 +19,14 @@
 from tempest.tests.compute import base
 
 
-class ListImagesTest(base.BaseComputeTest):
+class ListImagesTestJSON(base.BaseComputeTest):
     _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
-        super(ListImagesTest, cls).setUpClass()
+        super(ListImagesTestJSON, cls).setUpClass()
         cls.client = cls.images_client
 
-    @classmethod
-    def tearDownClass(cls):
-        super(ListImagesTest, cls).tearDownClass()
-
     @attr(type='smoke')
     def test_get_image(self):
         # Returns the correct details for a single image
@@ -50,3 +46,7 @@
         resp, images = self.client.list_images_with_detail()
         found = any([i for i in images if i['id'] == self.image_ref])
         self.assertTrue(found)
+
+
+class ListImagesTestXML(ListImagesTestJSON):
+    _interface = 'xml'
diff --git a/tempest/tests/compute/security_groups/test_security_group_rules.py b/tempest/tests/compute/security_groups/test_security_group_rules.py
index 99d9a5d..c2032d4 100644
--- a/tempest/tests/compute/security_groups/test_security_group_rules.py
+++ b/tempest/tests/compute/security_groups/test_security_group_rules.py
@@ -33,30 +33,24 @@
     def test_security_group_rules_create(self):
         # Positive test: Creation of Security Group rule
         # should be successfull
-        try:
-            #Creating a Security Group to add rules to it
-            s_name = rand_name('securitygroup-')
-            s_description = rand_name('description-')
-            resp, securitygroup = \
-                self.client.create_security_group(s_name, s_description)
-            securitygroup_id = securitygroup['id']
-            #Adding rules to the created Security Group
-            parent_group_id = securitygroup['id']
-            ip_protocol = 'tcp'
-            from_port = 22
-            to_port = 22
-            resp, rule = \
-                self.client.create_security_group_rule(parent_group_id,
-                                                       ip_protocol,
-                                                       from_port,
-                                                       to_port)
-            self.assertEqual(200, resp.status)
-        finally:
-            #Deleting the Security Group rule, created in this method
-            group_rule_id = rule['id']
-            self.client.delete_security_group_rule(group_rule_id)
-            #Deleting the Security Group created in this method
-            resp, _ = self.client.delete_security_group(securitygroup_id)
+        #Creating a Security Group to add rules to it
+        s_name = rand_name('securitygroup-')
+        s_description = rand_name('description-')
+        resp, securitygroup = \
+            self.client.create_security_group(s_name, s_description)
+        securitygroup_id = securitygroup['id']
+        self.addCleanup(self.client.delete_security_group, securitygroup_id)
+        #Adding rules to the created Security Group
+        ip_protocol = 'tcp'
+        from_port = 22
+        to_port = 22
+        resp, rule = \
+            self.client.create_security_group_rule(securitygroup_id,
+                                                   ip_protocol,
+                                                   from_port,
+                                                   to_port)
+        self.addCleanup(self.client.delete_security_group_rule, rule['id'])
+        self.assertEqual(200, resp.status)
 
     @attr(type='positive')
     def test_security_group_rules_create_with_optional_arguments(self):
@@ -64,75 +58,38 @@
         # with optional arguments
         # should be successfull
 
-        rule_id = None
         secgroup1 = None
         secgroup2 = None
-        try:
-            #Creating a Security Group to add rules to it
-            s_name = rand_name('securitygroup-')
-            s_description = rand_name('description-')
-            resp, securitygroup = \
-                self.client.create_security_group(s_name, s_description)
-            secgroup1 = securitygroup['id']
-            #Creating a Security Group so as to assign group_id to the rule
-            s_name2 = rand_name('securitygroup-')
-            s_description2 = rand_name('description-')
-            resp, securitygroup = \
-                self.client.create_security_group(s_name2, s_description2)
-            secgroup2 = securitygroup['id']
-            #Adding rules to the created Security Group with optional arguments
-            parent_group_id = secgroup1
-            ip_protocol = 'tcp'
-            from_port = 22
-            to_port = 22
-            cidr = '10.2.3.124/24'
-            group_id = secgroup2
-            resp, rule = \
-                self.client.create_security_group_rule(parent_group_id,
-                                                       ip_protocol,
-                                                       from_port,
-                                                       to_port,
-                                                       cidr=cidr,
-                                                       group_id=group_id)
-            rule_id = rule['id']
-            self.assertEqual(200, resp.status)
-        finally:
-            #Deleting the Security Group rule, created in this method
-            if rule_id:
-                self.client.delete_security_group_rule(rule_id)
-            #Deleting the Security Groups created in this method
-            if secgroup1:
-                self.client.delete_security_group(secgroup1)
-            if secgroup2:
-                self.client.delete_security_group(secgroup2)
-
-    @attr(type='positive')
-    def test_security_group_rules_create_delete(self):
-        # Positive test: Deletion of Security Group rule
-        # should be successfull
-        try:
-            #Creating a Security Group to add rule to it
-            s_name = rand_name('securitygroup-')
-            s_description = rand_name('description-')
-            resp, securitygroup = \
-                self.client.create_security_group(s_name, s_description)
-            securitygroup_id = securitygroup['id']
-            #Adding rules to the created Security Group
-            parent_group_id = securitygroup['id']
-            ip_protocol = 'tcp'
-            from_port = 22
-            to_port = 22
-            resp, rule = \
-                self.client.create_security_group_rule(parent_group_id,
-                                                       ip_protocol,
-                                                       from_port,
-                                                       to_port)
-        finally:
-            #Deleting the Security Group rule, created in this method
-            group_rule_id = rule['id']
-            self.client.delete_security_group_rule(group_rule_id)
-            #Deleting the Security Group created in this method
-            resp, _ = self.client.delete_security_group(securitygroup_id)
+        #Creating a Security Group to add rules to it
+        s_name = rand_name('securitygroup-')
+        s_description = rand_name('description-')
+        resp, securitygroup = \
+            self.client.create_security_group(s_name, s_description)
+        secgroup1 = securitygroup['id']
+        self.addCleanup(self.client.delete_security_group, secgroup1)
+        #Creating a Security Group so as to assign group_id to the rule
+        s_name2 = rand_name('securitygroup-')
+        s_description2 = rand_name('description-')
+        resp, securitygroup = \
+            self.client.create_security_group(s_name2, s_description2)
+        secgroup2 = securitygroup['id']
+        self.addCleanup(self.client.delete_security_group, secgroup2)
+        #Adding rules to the created Security Group with optional arguments
+        parent_group_id = secgroup1
+        ip_protocol = 'tcp'
+        from_port = 22
+        to_port = 22
+        cidr = '10.2.3.124/24'
+        group_id = secgroup2
+        resp, rule = \
+            self.client.create_security_group_rule(parent_group_id,
+                                                   ip_protocol,
+                                                   from_port,
+                                                   to_port,
+                                                   cidr=cidr,
+                                                   group_id=group_id)
+        self.addCleanup(self.client.delete_security_group_rule, rule['id'])
+        self.assertEqual(200, resp.status)
 
     @attr(type='negative')
     def test_security_group_rules_create_with_invalid_id(self):
diff --git a/tempest/tests/compute/security_groups/test_security_groups.py b/tempest/tests/compute/security_groups/test_security_groups.py
index 70a01a0..d0afde4 100644
--- a/tempest/tests/compute/security_groups/test_security_groups.py
+++ b/tempest/tests/compute/security_groups/test_security_groups.py
@@ -29,79 +29,80 @@
         super(SecurityGroupsTestJSON, cls).setUpClass()
         cls.client = cls.security_groups_client
 
+    def _delete_security_group(self, securitygroup_id):
+        resp, _ = self.client.delete_security_group(securitygroup_id)
+        self.assertEqual(202, resp.status)
+
     @attr(type='positive')
     def test_security_groups_create_list_delete(self):
         # Positive test:Should return the list of Security Groups
-        try:
-            #Create 3 Security Groups
-            security_group_list = list()
-            for i in range(3):
-                s_name = rand_name('securitygroup-')
-                s_description = rand_name('description-')
-                resp, securitygroup = \
-                    self.client.create_security_group(s_name, s_description)
-                self.assertEqual(200, resp.status)
-                security_group_list.append(securitygroup)
-            #Fetch all Security Groups and verify the list
-            #has all created Security Groups
-            resp, fetched_list = self.client.list_security_groups()
-            self.assertEqual(200, resp.status)
-            #Now check if all the created Security Groups are in fetched list
-            missing_sgs = \
-                [sg for sg in security_group_list if sg not in fetched_list]
-            self.assertFalse(missing_sgs,
-                             "Failed to find Security Group %s in fetched "
-                             "list" % ', '.join(m_group['name']
-                                                for m_group in missing_sgs))
-        finally:
-            #Delete all the Security Groups created in this method
-            for securitygroup in security_group_list:
-                resp, _ = \
-                    self.client.delete_security_group(securitygroup['id'])
-                self.assertEqual(202, resp.status)
-
-    @attr(type='positive')
-    def test_security_group_create_delete(self):
-        # Security Group should be created, verified and deleted
-        try:
+        #Create 3 Security Groups
+        security_group_list = list()
+        for i in range(3):
             s_name = rand_name('securitygroup-')
             s_description = rand_name('description-')
             resp, securitygroup = \
                 self.client.create_security_group(s_name, s_description)
             self.assertEqual(200, resp.status)
-            self.assertTrue('id' in securitygroup)
-            securitygroup_id = securitygroup['id']
-            self.assertFalse(securitygroup_id is None)
-            self.assertTrue('name' in securitygroup)
-            securitygroup_name = securitygroup['name']
-            self.assertEqual(securitygroup_name, s_name,
-                             "The created Security Group name is "
-                             "not equal to the requested name")
-        finally:
-            #Delete Security Group created in this method
-            resp, _ = self.client.delete_security_group(securitygroup['id'])
-            self.assertEqual(202, resp.status)
+            self.addCleanup(self._delete_security_group,
+                            securitygroup['id'])
+            security_group_list.append(securitygroup)
+        #Fetch all Security Groups and verify the list
+        #has all created Security Groups
+        resp, fetched_list = self.client.list_security_groups()
+        self.assertEqual(200, resp.status)
+        #Now check if all the created Security Groups are in fetched list
+        missing_sgs = \
+            [sg for sg in security_group_list if sg not in fetched_list]
+        self.assertFalse(missing_sgs,
+                         "Failed to find Security Group %s in fetched "
+                         "list" % ', '.join(m_group['name']
+                                            for m_group in missing_sgs))
+
+    #TODO(afazekas): scheduled for delete,
+    #test_security_group_create_get_delete covers it
+    @attr(type='positive')
+    def test_security_group_create_delete(self):
+        # Security Group should be created, verified and deleted
+        s_name = rand_name('securitygroup-')
+        s_description = rand_name('description-')
+        resp, securitygroup = \
+            self.client.create_security_group(s_name, s_description)
+        self.assertTrue('id' in securitygroup)
+        securitygroup_id = securitygroup['id']
+        self.addCleanup(self._delete_security_group,
+                        securitygroup_id)
+        self.assertEqual(200, resp.status)
+        self.assertFalse(securitygroup_id is None)
+        self.assertTrue('name' in securitygroup)
+        securitygroup_name = securitygroup['name']
+        self.assertEqual(securitygroup_name, s_name,
+                         "The created Security Group name is "
+                         "not equal to the requested name")
 
     @attr(type='positive')
     def test_security_group_create_get_delete(self):
         # Security Group should be created, fetched and deleted
-        try:
-            s_name = rand_name('securitygroup-')
-            s_description = rand_name('description-')
-            resp, securitygroup = \
-                self.client.create_security_group(s_name, s_description)
-            self.assertEqual(200, resp.status)
-            #Now fetch the created Security Group by its 'id'
-            resp, fetched_group = \
-                self.client.get_security_group(securitygroup['id'])
-            self.assertEqual(200, resp.status)
-            self.assertEqual(securitygroup, fetched_group,
-                             "The fetched Security Group is different "
-                             "from the created Group")
-        finally:
-            #Delete the Security Group created in this method
-            resp, _ = self.client.delete_security_group(securitygroup['id'])
-            self.assertEqual(202, resp.status)
+        s_name = rand_name('securitygroup-')
+        s_description = rand_name('description-')
+        resp, securitygroup = \
+            self.client.create_security_group(s_name, s_description)
+        self.addCleanup(self._delete_security_group,
+                        securitygroup['id'])
+
+        self.assertEqual(200, resp.status)
+        self.assertTrue('name' in securitygroup)
+        securitygroup_name = securitygroup['name']
+        self.assertEqual(securitygroup_name, s_name,
+                         "The created Security Group name is "
+                         "not equal to the requested name")
+        #Now fetch the created Security Group by its 'id'
+        resp, fetched_group = \
+            self.client.get_security_group(securitygroup['id'])
+        self.assertEqual(200, resp.status)
+        self.assertEqual(securitygroup, fetched_group,
+                         "The fetched Security Group is different "
+                         "from the created Group")
 
     @attr(type='negative')
     def test_security_group_get_nonexistant_group(self):
diff --git a/tempest/tests/compute/servers/test_create_server.py b/tempest/tests/compute/servers/test_create_server.py
index aaab9fa..b522992 100644
--- a/tempest/tests/compute/servers/test_create_server.py
+++ b/tempest/tests/compute/servers/test_create_server.py
@@ -33,7 +33,7 @@
 class ServersTestJSON(base.BaseComputeTest):
     _interface = 'json'
     run_ssh = tempest.config.TempestConfig().compute.run_ssh
-    disk_config = None
+    disk_config = 'AUTO'
 
     @classmethod
     def setUpClass(cls):
@@ -118,18 +118,6 @@
 
 
 @attr(type='positive')
-class ServersTestAutoDisk(ServersTestJSON):
-    disk_config = 'AUTO'
-
-    @classmethod
-    def setUpClass(cls):
-        if not compute.DISK_CONFIG_ENABLED:
-            msg = "DiskConfig extension not enabled."
-            raise cls.skipException(msg)
-        super(ServersTestAutoDisk, cls).setUpClass()
-
-
-@attr(type='positive')
 class ServersTestManualDisk(ServersTestJSON):
     disk_config = 'MANUAL'
 
diff --git a/tempest/tests/compute/servers/test_disk_config.py b/tempest/tests/compute/servers/test_disk_config.py
index 2fbb876..fe1c271 100644
--- a/tempest/tests/compute/servers/test_disk_config.py
+++ b/tempest/tests/compute/servers/test_disk_config.py
@@ -22,7 +22,7 @@
 from tempest.tests.compute import base
 
 
-class TestServerDiskConfig(base.BaseComputeTest):
+class ServerDiskConfigTestJSON(base.BaseComputeTest):
     _interface = 'json'
 
     @classmethod
@@ -30,7 +30,7 @@
         if not compute.DISK_CONFIG_ENABLED:
             msg = "DiskConfig extension not enabled."
             raise cls.skipException(msg)
-        super(TestServerDiskConfig, cls).setUpClass()
+        super(ServerDiskConfigTestJSON, cls).setUpClass()
         cls.client = cls.os.servers_client
 
     @attr(type='positive')
@@ -120,3 +120,7 @@
 
         #Delete the server
         resp, body = self.client.delete_server(server['id'])
+
+
+class ServerDiskConfigTestXML(ServerDiskConfigTestJSON):
+    _interface = 'xml'
diff --git a/tempest/tests/compute/servers/test_list_server_filters.py b/tempest/tests/compute/servers/test_list_server_filters.py
index ff599fe..4d2b99f 100644
--- a/tempest/tests/compute/servers/test_list_server_filters.py
+++ b/tempest/tests/compute/servers/test_list_server_filters.py
@@ -126,11 +126,12 @@
         self.assertIn(self.s3['id'], map(lambda x: x['id'], servers))
 
     @attr(type='positive')
-    def test_list_servers_detailed_filter_by_limit(self):
+    def test_list_servers_filter_by_limit(self):
         # Verify only the expected number of servers are returned
         params = {'limit': 1}
-        resp, servers = self.client.list_servers_with_detail(params)
-        self.assertEqual(1, len(servers['servers']))
+        resp, servers = self.client.list_servers(params)
+        #when _interface='xml', one element for servers_links in servers
+        self.assertEqual(1, len([x for x in servers['servers'] if 'id' in x]))
 
     @utils.skip_unless_attr('multiple_images', 'Only one image found')
     @attr(type='positive')
diff --git a/tempest/tests/compute/servers/test_list_servers_negative.py b/tempest/tests/compute/servers/test_list_servers_negative.py
index 01b11e0..0559206 100644
--- a/tempest/tests/compute/servers/test_list_servers_negative.py
+++ b/tempest/tests/compute/servers/test_list_servers_negative.py
@@ -22,12 +22,12 @@
 from tempest.tests.compute import base
 
 
-class ListServersNegativeTest(base.BaseComputeTest):
+class ListServersNegativeTestJSON(base.BaseComputeTest):
     _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
-        super(ListServersNegativeTest, cls).setUpClass()
+        super(ListServersNegativeTestJSON, cls).setUpClass()
         cls.client = cls.servers_client
         cls.servers = []
 
@@ -138,7 +138,8 @@
         # List servers by specifying limits
         resp, body = self.client.list_servers({'limit': 1})
         self.assertEqual('200', resp['status'])
-        self.assertEqual(1, len(body['servers']))
+        #when _interface='xml', one element for servers_links in servers
+        self.assertEqual(1, len([x for x in body['servers'] if 'id' in x]))
 
     def test_list_servers_by_limits_greater_than_actual_count(self):
         # List servers by specifying a greater value for limit
@@ -187,3 +188,7 @@
                   if srv['id'] in deleted_ids]
         self.assertEqual('200', resp['status'])
         self.assertEqual([], actual)
+
+
+class ListServersNegativeTestXML(ListServersNegativeTestJSON):
+    _interface = 'xml'
diff --git a/tempest/tests/compute/servers/test_multiple_create.py b/tempest/tests/compute/servers/test_multiple_create.py
new file mode 100644
index 0000000..ad5d604
--- /dev/null
+++ b/tempest/tests/compute/servers/test_multiple_create.py
@@ -0,0 +1,117 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 IBM Corp
+# 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.common.utils.data_utils import rand_name
+from tempest import exceptions
+from tempest.test import attr
+from tempest.tests.compute import base
+
+
+class MultipleCreateTestJSON(base.BaseComputeTest):
+    _interface = 'json'
+    _name = 'multiple-create-test'
+
+    def _get_created_servers(self, name):
+        """Get servers created which name match with name param."""
+        resp, body = self.servers_client.list_servers()
+        servers = body['servers']
+        servers_created = []
+        for server in servers:
+            if server['name'].startswith(name):
+                servers_created.append(server)
+        return servers_created
+
+    def _generate_name(self):
+        return rand_name(self._name)
+
+    def _create_multiple_servers(self, name=None, wait_until=None, **kwargs):
+        """
+        This is the right way to create_multiple servers and manage to get the
+        created servers into the servers list to be cleaned up after all.
+        """
+        kwargs['name'] = kwargs.get('name', self._generate_name())
+        resp, body = self.create_server(**kwargs)
+        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)
+        # 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
+        # harmful to the performance
+        if wait_until is not None:
+            for server in created_servers:
+                self.servers_client.wait_for_server_status(server['id'],
+                                                           wait_until)
+
+        return resp, body
+
+    @attr(type='positive')
+    def test_multiple_create(self):
+        resp, body = self._create_multiple_servers(wait_until='ACTIVE',
+                                                   min_count=1,
+                                                   max_count=2)
+        # NOTE(maurosr): do status response check and also make sure that
+        # reservation_id is not in the response body when the request send
+        # contains return_reservation_id=False
+        self.assertEqual('202', resp['status'])
+        self.assertFalse('reservation_id' in body)
+
+    @attr(type='negative')
+    def test_min_count_less_than_one(self):
+        invalid_min_count = 0
+        self.assertRaises(exceptions.BadRequest, self._create_multiple_servers,
+                          min_count=invalid_min_count)
+
+    @attr(type='negative')
+    def test_min_count_non_integer(self):
+        invalid_min_count = 2.5
+        self.assertRaises(exceptions.BadRequest, self._create_multiple_servers,
+                          min_count=invalid_min_count)
+
+    @attr(type='negative')
+    def test_max_count_less_than_one(self):
+        invalid_max_count = 0
+        self.assertRaises(exceptions.BadRequest, self._create_multiple_servers,
+                          max_count=invalid_max_count)
+
+    @attr(type='negative')
+    def test_max_count_non_integer(self):
+        invalid_max_count = 2.5
+        self.assertRaises(exceptions.BadRequest, self._create_multiple_servers,
+                          max_count=invalid_max_count)
+
+    @attr(type='negative')
+    def test_max_count_less_than_min_count(self):
+        min_count = 3
+        max_count = 2
+        self.assertRaises(exceptions.BadRequest, self._create_multiple_servers,
+                          min_count=min_count,
+                          max_count=max_count)
+
+    @attr(type='positive')
+    def test_multiple_create_with_reservation_return(self):
+        resp, body = self._create_multiple_servers(wait_until='ACTIVE',
+                                                   min_count=1,
+                                                   max_count=2,
+                                                   return_reservation_id=True)
+        self.assertTrue(resp['status'], 202)
+        self.assertIn('reservation_id', body)
+
+
+class MultipleCreateTestXML(MultipleCreateTestJSON):
+    _interface = 'xml'
diff --git a/tempest/tests/compute/servers/test_server_actions.py b/tempest/tests/compute/servers/test_server_actions.py
index d5b2650..5634784 100644
--- a/tempest/tests/compute/servers/test_server_actions.py
+++ b/tempest/tests/compute/servers/test_server_actions.py
@@ -87,7 +87,7 @@
             self.assertGreater(new_boot_time, boot_time)
 
     @attr(type='smoke')
-    @testtools.skip('Until bug 1014647 is dealt with.')
+    @testtools.skip('Until Bug #1014647 is dealt with.')
     def test_reboot_server_soft(self):
         # The server should be signaled to reboot gracefully
         if self.run_ssh:
@@ -239,7 +239,7 @@
                           '!@#$%^&*()', 10)
 
     @attr(type='positive')
-    @testtools.skip('Until tempest bug 1014683 is fixed.')
+    @testtools.skip('Until tempest Bug #1014683 is fixed.')
     def test_get_console_output_server_id_in_reboot_status(self):
         # Positive test:Should be able to GET the console output
         # for a given server_id in reboot status
diff --git a/tempest/tests/compute/servers/test_server_addresses.py b/tempest/tests/compute/servers/test_server_addresses.py
index cb8e85e..05fa320 100644
--- a/tempest/tests/compute/servers/test_server_addresses.py
+++ b/tempest/tests/compute/servers/test_server_addresses.py
@@ -15,7 +15,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.common.utils.data_utils import rand_name
 from tempest import exceptions
 from tempest.test import attr
 from tempest.tests.compute import base
diff --git a/tempest/tests/compute/servers/test_server_advanced_ops.py b/tempest/tests/compute/servers/test_server_advanced_ops.py
index f949f2e..ac0d7be 100644
--- a/tempest/tests/compute/servers/test_server_advanced_ops.py
+++ b/tempest/tests/compute/servers/test_server_advanced_ops.py
@@ -24,7 +24,7 @@
 LOG = logging.getLogger(__name__)
 
 
-class TestServerAdvancedOps(test.DefaultClientTest):
+class TestServerAdvancedOps(test.DefaultClientSmokeTest):
 
     """
     This test case stresses some advanced server instance operations:
@@ -66,16 +66,16 @@
 
         self.assertEqual(self.instance.status, 'BUILD')
         instance_id = self.get_resource('instance').id
-        self.status_timeout(self.compute_client.servers, instance_id, 'ACTIVE')
+        test.status_timeout(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)
-        self.status_timeout(self.compute_client.servers, instance_id,
+        test.status_timeout(self.compute_client.servers, instance_id,
                             'VERIFY_RESIZE')
 
         LOG.debug("Confirming resize of instance %s", instance_id)
         instance.confirm_resize()
-        self.status_timeout(self.compute_client.servers, instance_id, 'ACTIVE')
+        test.status_timeout(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 2183193..c7fad7a 100644
--- a/tempest/tests/compute/servers/test_server_basic_ops.py
+++ b/tempest/tests/compute/servers/test_server_basic_ops.py
@@ -18,12 +18,12 @@
 import logging
 
 from tempest.common.utils.data_utils import rand_name
-from tempest import smoke
+from tempest import test
 
 LOG = logging.getLogger(__name__)
 
 
-class TestServerBasicOps(smoke.DefaultClientSmokeTest):
+class TestServerBasicOps(test.DefaultClientSmokeTest):
 
     """
     This smoke test case follows this basic set of operations:
@@ -101,7 +101,7 @@
 
     def wait_on_active(self):
         instance_id = self.get_resource('instance').id
-        self.status_timeout(self.compute_client.servers, instance_id, 'ACTIVE')
+        test.status_timeout(self.compute_client.servers, instance_id, 'ACTIVE')
 
     def pause_server(self):
         instance = self.get_resource('instance')
@@ -109,7 +109,7 @@
         LOG.debug("Pausing instance %s. Current status: %s",
                   instance_id, instance.status)
         instance.pause()
-        self.status_timeout(self.compute_client.servers, instance_id, 'PAUSED')
+        test.status_timeout(self.compute_client.servers, instance_id, 'PAUSED')
 
     def unpause_server(self):
         instance = self.get_resource('instance')
@@ -117,7 +117,7 @@
         LOG.debug("Unpausing instance %s. Current status: %s",
                   instance_id, instance.status)
         instance.unpause()
-        self.status_timeout(self.compute_client.servers, instance_id, 'ACTIVE')
+        test.status_timeout(self.compute_client.servers, instance_id, 'ACTIVE')
 
     def suspend_server(self):
         instance = self.get_resource('instance')
@@ -125,7 +125,7 @@
         LOG.debug("Suspending instance %s. Current status: %s",
                   instance_id, instance.status)
         instance.suspend()
-        self.status_timeout(self.compute_client.servers,
+        test.status_timeout(self.compute_client.servers,
                             instance_id, 'SUSPENDED')
 
     def resume_server(self):
@@ -134,7 +134,7 @@
         LOG.debug("Resuming instance %s. Current status: %s",
                   instance_id, instance.status)
         instance.resume()
-        self.status_timeout(self.compute_client.servers, instance_id, 'ACTIVE')
+        test.status_timeout(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 9230305..91010ce 100644
--- a/tempest/tests/compute/servers/test_server_rescue.py
+++ b/tempest/tests/compute/servers/test_server_rescue.py
@@ -15,17 +15,12 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import base64
-import time
-
 import testtools
 
 from tempest.common.utils.data_utils import rand_name
-from tempest.common.utils.linux.remote_client import RemoteClient
 import tempest.config
 from tempest import exceptions
 from tempest.test import attr
-from tempest.tests import compute
 from tempest.tests.compute import base
 
 
@@ -57,16 +52,16 @@
         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.volumes_extensions_client.wait_for_volume_status(
+                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.wait_for_volume_status
-        (cls.volume_to_detach['id'], 'available')
+        cls.volumes_extensions_client.wait_for_volume_status(
+                cls.volume_to_detach['id'], 'available')
 
         # Server for positive tests
         resp, server = cls.create_server(image_id=cls.image_ref,
@@ -112,6 +107,11 @@
     def _delete(self, volume_id):
         self.volumes_extensions_client.delete_volume(volume_id)
 
+    def _unrescue(self, server_id):
+        resp, body = self.servers_client.unrescue_server(server_id)
+        self.assertEqual(202, resp.status)
+        self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
+
     @attr(type='smoke')
     def test_rescue_unrescue_instance(self):
         resp, body = self.servers_client.rescue_server(
@@ -123,9 +123,8 @@
         self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
 
     @attr(type='negative')
-    @testtools.skip("Skipped until Bug:1126163 is resolved")
     def test_rescued_vm_reboot(self):
-        self.assertRaises(exceptions.BadRequest, self.servers_client.reboot,
+        self.assertRaises(exceptions.Duplicate, self.servers_client.reboot,
                           self.rescue_id, 'HARD')
 
     @attr(type='negative')
@@ -135,61 +134,42 @@
                           self.rescue_id,
                           self.image_ref_alt)
 
-    @attr(type='positive')
-    @testtools.skip("Skipped due to Bug:1126187")
+    @attr(type='negative')
     def test_rescued_vm_attach_volume(self):
-        client = self.volumes_extensions_client
-
         # Rescue the server
         self.servers_client.rescue_server(self.server_id, self.password)
         self.servers_client.wait_for_server_status(self.server_id, 'RESCUE')
+        self.addCleanup(self._unrescue, self.server_id)
 
         # Attach the volume to the server
-        resp, body = \
-        self.servers_client.attach_volume(self.server_id,
-                                          self.volume_to_attach['id'],
-                                          device='/dev/%s' % self.device)
-        self.assertEqual(200, resp.status)
-        client.wait_for_volume_status(self.volume_to_attach['id'], 'in-use')
+        self.assertRaises(exceptions.Duplicate,
+                          self.servers_client.attach_volume,
+                          self.server_id,
+                          self.volume_to_attach['id'],
+                          device='/dev/%s' % self.device)
 
-        # Detach the volume to the server
-        resp, body = \
-        self.servers_client.detach_volume(self.server_id,
-                                          self.volume_to_attach['id'])
-        self.assertEqual(202, resp.status)
-        client.wait_for_volume_status(self.volume_to_attach['id'], 'available')
-
-        # Unrescue the server
-        resp, body = self.servers_client.unrescue_server(self.server_id)
-        self.assertEqual(202, resp.status)
-        self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
-
-    @attr(type='positive')
-    @testtools.skip("Skipped until Bug:1126187 is resolved")
+    @attr(type='negative')
     def test_rescued_vm_detach_volume(self):
         # Attach the volume to the server
         self.servers_client.attach_volume(self.server_id,
                                           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.volumes_extensions_client.wait_for_volume_status(
+                self.volume_to_detach['id'], 'in-use')
 
         # Rescue the server
         self.servers_client.rescue_server(self.server_id, self.password)
         self.servers_client.wait_for_server_status(self.server_id, 'RESCUE')
+        #addCleanup is a LIFO queue
+        self.addCleanup(self._detach, self.server_id,
+                        self.volume_to_detach['id'])
+        self.addCleanup(self._unrescue, self.server_id)
 
-        # Detach the volume to the server
-        resp, body = \
-        self.servers_client.detach_volume(self.server_id,
-                                          self.volume_to_detach['id'])
-        self.assertEqual(202, resp.status)
-        client = self.volumes_extensions_client
-        client.wait_for_volume_status(self.volume_to_detach['id'], 'available')
-
-        # Unrescue the server
-        resp, body = self.servers_client.unrescue_server(self.server_id)
-        self.assertEqual(202, resp.status)
-        self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
+        # Detach the volume from the server expecting failure
+        self.assertRaises(exceptions.Duplicate,
+                          self.servers_client.detach_volume,
+                          self.server_id,
+                          self.volume_to_detach['id'])
 
     @attr(type='positive')
     def test_rescued_vm_associate_dissociate_floating_ip(self):
@@ -197,6 +177,7 @@
         self.servers_client.rescue_server(
             self.server_id, self.password)
         self.servers_client.wait_for_server_status(self.server_id, 'RESCUE')
+        self.addCleanup(self._unrescue, self.server_id)
 
         #Association of floating IP to a rescued vm
         client = self.floating_ips_client
@@ -211,13 +192,8 @@
                                                         self.server_id)
         self.assertEqual(202, resp.status)
 
-        # Unrescue the server
-        resp, body = self.servers_client.unrescue_server(self.server_id)
-        self.assertEqual(202, resp.status)
-        self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
-
     @attr(type='positive')
-    @testtools.skip("Skipped until Bug: 1126257 is resolved")
+    @testtools.skip("Skipped until Bug #1126257 is resolved")
     def test_rescued_vm_add_remove_security_group(self):
         #Add Security group
         resp, body = self.servers_client.add_security_group(self.server_id,
diff --git a/tempest/tests/compute/test_authorization.py b/tempest/tests/compute/test_authorization.py
index 4ca197a..91cf39f 100644
--- a/tempest/tests/compute/test_authorization.py
+++ b/tempest/tests/compute/test_authorization.py
@@ -15,8 +15,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import testtools
-
 from tempest import clients
 from tempest.common.utils.data_utils import parse_image_id
 from tempest.common.utils.data_utils import rand_name
@@ -25,7 +23,7 @@
 from tempest.tests.compute import base
 
 
-class AuthorizationTest(base.BaseComputeTest):
+class AuthorizationTestJSON(base.BaseComputeTest):
     _interface = 'json'
 
     @classmethod
@@ -34,7 +32,7 @@
             msg = "Need >1 user"
             raise cls.skipException(msg)
 
-        super(AuthorizationTest, cls).setUpClass()
+        super(AuthorizationTestJSON, cls).setUpClass()
 
         cls.client = cls.os.servers_client
         cls.images_client = cls.os.images_client
@@ -73,18 +71,15 @@
 
         name = rand_name('security')
         description = rand_name('description')
-        resp, cls.security_group = \
-        cls.security_client.create_security_group(name, description)
+        resp, cls.security_group = cls.security_client.create_security_group(
+            name, description)
 
         parent_group_id = cls.security_group['id']
         ip_protocol = 'tcp'
         from_port = 22
         to_port = 22
-        resp, cls.rule =\
-        cls.security_client.create_security_group_rule(
-                                        parent_group_id,
-                                        ip_protocol, from_port,
-                                        to_port)
+        resp, cls.rule = cls.security_client.create_security_group_rule(
+            parent_group_id, ip_protocol, from_port, to_port)
 
     @classmethod
     def tearDownClass(cls):
@@ -92,7 +87,7 @@
             cls.images_client.delete_image(cls.image['id'])
             cls.keypairs_client.delete_keypair(cls.keypairname)
             cls.security_client.delete_security_group(cls.security_group['id'])
-        super(AuthorizationTest, cls).tearDownClass()
+        super(AuthorizationTestJSON, cls).tearDownClass()
 
     def test_get_server_for_alt_account_fails(self):
         # A GET request for a server on another user's account should fail
@@ -280,7 +275,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(
-                                        body['id'])  # BUG
+                    body['id'])  # BUG
                 self.fail("Create security group rule request should not "
                           "happen if the tenant id does not match the"
                           " current user")
@@ -354,3 +349,7 @@
         self.assertRaises(exceptions.NotFound,
                           self.alt_client.get_console_output,
                           self.server['id'], 10)
+
+
+class AuthorizationTestXML(AuthorizationTestJSON):
+    _interface = 'xml'
diff --git a/tempest/tests/compute/test_live_block_migration.py b/tempest/tests/compute/test_live_block_migration.py
index abaaf85..e438098 100644
--- a/tempest/tests/compute/test_live_block_migration.py
+++ b/tempest/tests/compute/test_live_block_migration.py
@@ -27,7 +27,8 @@
 
 
 @attr(category='live-migration')
-class LiveBlockMigrationTest(base.BaseComputeAdminTest):
+class LiveBlockMigrationTestJSON(base.BaseComputeAdminTest):
+    _host_key = 'OS-EXT-SRV-ATTR:host'
     _interface = 'json'
 
     live_migration_available = (
@@ -38,7 +39,7 @@
 
     @classmethod
     def setUpClass(cls):
-        super(LiveBlockMigrationTest, cls).setUpClass()
+        super(LiveBlockMigrationTestJSON, cls).setUpClass()
 
         cls.admin_hosts_client = cls.os_adm.hosts_client
         cls.admin_servers_client = cls.os_adm.servers_client
@@ -58,7 +59,7 @@
         return body
 
     def _get_host_for_server(self, server_id):
-        return self._get_server_details(server_id)['OS-EXT-SRV-ATTR:host']
+        return self._get_server_details(server_id)[self._host_key]
 
     def _migrate_server_to(self, server_id, dest_host):
         _resp, body = self.admin_servers_client.live_migrate_server(
@@ -125,4 +126,10 @@
         for server_id in cls.created_server_ids:
             cls.servers_client.delete_server(server_id)
 
-        super(LiveBlockMigrationTest, cls).tearDownClass()
+        super(LiveBlockMigrationTestJSON, cls).tearDownClass()
+
+
+class LiveBlockMigrationTestXML(LiveBlockMigrationTestJSON):
+    _host_key = (
+        '{http://docs.openstack.org/compute/ext/extended_status/api/v1.1}host')
+    _interface = 'xml'
diff --git a/tempest/tests/compute/test_quotas.py b/tempest/tests/compute/test_quotas.py
index 233d639..a84d041 100644
--- a/tempest/tests/compute/test_quotas.py
+++ b/tempest/tests/compute/test_quotas.py
@@ -33,14 +33,11 @@
 
     @attr(type='smoke')
     def test_get_default_quotas(self):
-        # Tempest two step
-        self.skipTest('Skipped until the Bug 1125468 is resolved')
-
         # User can get the default quota set for it's tenant
         expected_quota_set = {'injected_file_content_bytes': 10240,
                               'metadata_items': 128, 'injected_files': 5,
                               'ram': 51200, 'floating_ips': 10,
-                              'fixed_ips': 10, 'key_pairs': 100,
+                              'fixed_ips': -1, 'key_pairs': 100,
                               'injected_file_path_bytes': 255, 'instances': 10,
                               'security_group_rules': 20, 'cores': 20,
                               'id': self.tenant_id, 'security_groups': 10}
diff --git a/tempest/tests/compute/volumes/test_attach_volume.py b/tempest/tests/compute/volumes/test_attach_volume.py
index d9abe41..cb0a964 100644
--- a/tempest/tests/compute/volumes/test_attach_volume.py
+++ b/tempest/tests/compute/volumes/test_attach_volume.py
@@ -1,6 +1,6 @@
 # vim: tabstop=4 shiftwidth=4 softtabstop=4
 
-# Copyright 2012 IBM
+# Copyright 2012 IBM Corp.
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -17,7 +17,6 @@
 
 import testtools
 
-from tempest.common.utils.data_utils import rand_name
 from tempest.common.utils.linux.remote_client import RemoteClient
 import tempest.config
 from tempest.test import attr
@@ -92,7 +91,7 @@
             self.assertTrue(self.device in partitions)
 
             self._detach(server['id'], volume['id'])
-            attached = False
+            self.attached = False
 
             self.servers_client.stop(server['id'])
             self.servers_client.wait_for_server_status(server['id'], 'SHUTOFF')
diff --git a/tempest/tests/identity/admin/test_users.py b/tempest/tests/identity/admin/test_users.py
index 224272e..0573b21 100644
--- a/tempest/tests/identity/admin/test_users.py
+++ b/tempest/tests/identity/admin/test_users.py
@@ -77,7 +77,7 @@
                           self.data.tenant['id'], self.data.test_email)
 
     @attr(type='negative')
-    @testtools.skip("Until Bug 999084 is fixed")
+    @testtools.skip("Until Bug #999084 is fixed")
     def test_create_user_with_empty_password(self):
         # User with an empty password should not be created
         self.data.setup_test_tenant()
@@ -86,7 +86,7 @@
                           self.alt_email)
 
     @attr(type='nagative')
-    @testtools.skip("Until Bug 999084 is fixed")
+    @testtools.skip("Until Bug #999084 is fixed")
     def test_create_user_with_long_password(self):
         # User having password exceeding max length should not be created
         self.data.setup_test_tenant()
@@ -95,7 +95,7 @@
                           self.alt_email)
 
     @attr(type='negative')
-    @testtools.skip("Until Bug 999084 is fixed")
+    @testtools.skip("Until Bug #999084 is fixed")
     def test_create_user_with_invalid_email_format(self):
         # Email format should be validated while creating a user
         self.data.setup_test_tenant()
@@ -326,17 +326,9 @@
         invalid_id.append(rand_name("dddd@#%%^$"))
         invalid_id.append('!@#()$%^&*?<>{}[]')
         #List the users with invalid tenant id
-        fail = list()
         for invalid in invalid_id:
-            try:
-                resp, body = self.client.list_users_for_tenant(invalid)
-            except exceptions.NotFound:
-                pass
-            else:
-                fail.append(invalid)
-        if len(fail) != 0:
-            self.fail('Should raise Not Found when list users with invalid'
-                      'tenant ids %s' % fail)
+            self.assertRaises(exceptions.NotFound,
+                              self.client.list_users_for_tenant, invalid)
 
 
 class UsersTestXML(UsersTestJSON):
diff --git a/tempest/tests/identity/admin/v3/__init__.py b/tempest/tests/identity/admin/v3/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/tests/identity/admin/v3/__init__.py
diff --git a/tempest/tests/identity/admin/v3/test_endpoints.py b/tempest/tests/identity/admin/v3/test_endpoints.py
new file mode 100755
index 0000000..98fab57
--- /dev/null
+++ b/tempest/tests/identity/admin/v3/test_endpoints.py
@@ -0,0 +1,149 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 OpenStack Foundation
+# 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.common.utils.data_utils import rand_name
+from tempest.test import attr
+from tempest.tests.identity import base
+
+
+class EndPointsTestJSON(base.BaseIdentityAdminTest):
+    _interface = 'json'
+
+    @classmethod
+    def setUpClass(cls):
+        super(EndPointsTestJSON, cls).setUpClass()
+        cls.identity_client = cls.client
+        cls.client = cls.endpoints_client
+        cls.service_ids = list()
+        s_name = rand_name('service-')
+        s_type = rand_name('type--')
+        s_description = rand_name('description-')
+        resp, cls.service_data =\
+            cls.identity_client.create_service(s_name, s_type,
+                                               description=s_description)
+        cls.service_id = cls.service_data['id']
+        cls.service_ids.append(cls.service_id)
+        #Create endpoints so as to use for LIST and GET test cases
+        cls.setup_endpoints = list()
+        for i in range(2):
+            region = rand_name('region')
+            url = rand_name('url')
+            interface = 'public'
+            resp, endpoint = cls.client.create_endpoint(
+                cls.service_id, interface, url, region=region, enabled=True)
+            cls.setup_endpoints.append(endpoint)
+
+    @classmethod
+    def tearDownClass(cls):
+        for e in cls.setup_endpoints:
+            cls.client.delete_endpoint(e['id'])
+        for s in cls.service_ids:
+            cls.identity_client.delete_service(s)
+
+    @attr('positive')
+    def test_list_endpoints(self):
+        # Get a list of endpoints
+        resp, fetched_endpoints = self.client.list_endpoints()
+        #Asserting LIST Endpoint
+        self.assertEqual(resp['status'], '200')
+        missing_endpoints =\
+            [e for e in self.setup_endpoints if e not in fetched_endpoints]
+        self.assertEqual(0, len(missing_endpoints),
+                         "Failed to find endpoint %s in fetched list" %
+                         ', '.join(str(e) for e in missing_endpoints))
+
+    @attr('positive')
+    def test_create_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")
+
+    @attr('smoke')
+    def test_update_endpoint(self):
+        #Creating an endpoint so as to check update endpoint
+        #with new values
+        region1 = rand_name('region')
+        url1 = rand_name('url')
+        interface1 = 'public'
+        resp, endpoint_for_update =\
+            self.client.create_endpoint(self.service_id, interface1,
+                                        url1, region=region1,
+                                        enabled=True)
+        #Creating service so as update endpoint with new service ID
+        s_name = rand_name('service-')
+        s_type = rand_name('type--')
+        s_description = rand_name('description-')
+        resp, self.service2 =\
+            self.identity_client.create_service(s_name, s_type,
+                                                description=s_description)
+        self.service_ids.append(self.service2['id'])
+        #Updating endpoint with new values
+        service_id = self.service2['id']
+        region2 = rand_name('region')
+        url2 = rand_name('url')
+        interface2 = 'internal'
+        resp, endpoint = \
+            self.client.update_endpoint(endpoint_for_update['id'],
+                                        service_id=self.service2['id'],
+                                        interface=interface2, url=url2,
+                                        region=region2, enabled=False)
+        self.assertEqual(resp['status'], '200')
+        #Asserting if the attributes of endpoint are updated
+        self.assertEqual(self.service2['id'], endpoint['service_id'])
+        self.assertEqual(interface2, endpoint['interface'])
+        self.assertEqual(url2, endpoint['url'])
+        self.assertEqual(region2, endpoint['region'])
+        self.assertEqual('False', str(endpoint['enabled']))
+        self.addCleanup(self.client.delete_endpoint, endpoint_for_update['id'])
+
+
+class EndPointsTestXML(EndPointsTestJSON):
+    _interface = 'xml'
diff --git a/tempest/tests/identity/base.py b/tempest/tests/identity/base.py
index 168b2ff..64b8993 100644
--- a/tempest/tests/identity/base.py
+++ b/tempest/tests/identity/base.py
@@ -28,6 +28,7 @@
         os = clients.AdminManager(interface=cls._interface)
         cls.client = os.identity_client
         cls.token_client = os.token_client
+        cls.endpoints_client = os.endpoints_client
 
         if not cls.client.has_admin_extensions():
             raise cls.skipException("Admin extensions disabled")
diff --git a/tempest/tests/image/base.py b/tempest/tests/image/base.py
index 65d81b6..f12e957 100644
--- a/tempest/tests/image/base.py
+++ b/tempest/tests/image/base.py
@@ -15,7 +15,6 @@
 #    under the License.
 
 import logging
-import time
 
 from tempest import clients
 from tempest.common.utils.data_utils import rand_name
diff --git a/tempest/tests/image/v1/test_images.py b/tempest/tests/image/v1/test_images.py
index af09b79..1b6fa10 100644
--- a/tempest/tests/image/v1/test_images.py
+++ b/tempest/tests/image/v1/test_images.py
@@ -17,7 +17,6 @@
 
 import cStringIO as StringIO
 
-from tempest import clients
 from tempest import exceptions
 from tempest.test import attr
 from tempest.tests.image import base
@@ -68,13 +67,55 @@
                                        container_format='bare',
                                        disk_format='raw', is_public=True,
                                        location='http://example.com'
-                                                '/someimage.iso')
+                                                '/someimage.iso',
+                                       properties={'key1': 'value1',
+                                                   'key2': 'value2'})
         self.assertTrue('id' in body)
         image_id = body.get('id')
         self.created_images.append(image_id)
         self.assertEqual('New Remote Image', body.get('name'))
         self.assertTrue(body.get('is_public'))
         self.assertEqual('active', body.get('status'))
+        properties = body.get('properties')
+        self.assertEqual(properties['key1'], 'value1')
+        self.assertEqual(properties['key2'], 'value2')
+
+    def test_register_http_image(self):
+        container_client = self.os.container_client
+        object_client = self.os.object_client
+        container_name = "image_container"
+        object_name = "test_image.img"
+        container_client.create_container(container_name)
+        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='')
+        self.assertEqual(resp['status'], '204')
+
+        data = "TESTIMAGE"
+        resp, _ = object_client.create_object(container_name,
+                                              object_name, data)
+        self.addCleanup(object_client.delete_object, container_name,
+                        object_name)
+        self.assertEqual(resp['status'], '201')
+        object_url = '/'.join((object_client.base_url,
+                               container_name,
+                               object_name))
+        resp, body = self.create_image(name='New Http Image',
+                                       container_format='bare',
+                                       disk_format='raw', is_public=True,
+                                       copy_from=object_url)
+        self.assertTrue('id' in body)
+        image_id = body.get('id')
+        self.created_images.append(image_id)
+        self.assertEqual('New Http Image', body.get('name'))
+        self.assertTrue(body.get('is_public'))
+        self.client.wait_for_image_status(image_id, 'active')
+        resp, body = self.client.get_image(image_id)
+        self.assertEqual(resp['status'], '200')
+        self.assertEqual(body, data)
 
 
 class ListImagesTest(base.BaseV1ImageTest):
diff --git a/tempest/tests/image/v2/test_images.py b/tempest/tests/image/v2/test_images.py
index 19a7a95..15db519 100644
--- a/tempest/tests/image/v2/test_images.py
+++ b/tempest/tests/image/v2/test_images.py
@@ -2,7 +2,7 @@
 
 # Copyright 2013 OpenStack, LLC
 # All Rights Reserved.
-# Copyright 2013 IBM Corp
+# Copyright 2013 IBM Corp.
 #
 #    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
@@ -19,7 +19,6 @@
 import cStringIO as StringIO
 import random
 
-from tempest import clients
 from tempest import exceptions
 from tempest.test import attr
 from tempest.tests.image import base
diff --git a/tempest/tests/network/base.py b/tempest/tests/network/base.py
index 1b09513..e0e40cb 100644
--- a/tempest/tests/network/base.py
+++ b/tempest/tests/network/base.py
@@ -15,31 +15,73 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import netaddr
 
 from tempest import clients
 from tempest.common.utils.data_utils import rand_name
+from tempest import exceptions
 import tempest.test
 
 
 class BaseNetworkTest(tempest.test.BaseTestCase):
 
+    """
+    Base class for the Quantum tests that use the Tempest Quantum REST client
+
+    Per the Quantum API Guide, API v1.x was removed from the source code tree
+    (docs.openstack.org/api/openstack-network/2.0/content/Overview-d1e71.html)
+    Therefore, v2.x of the Quantum API is assumed. It is also assumed that the
+    following options are defined in the [network] section of etc/tempest.conf:
+
+        tenant_network_cidr with a block of cidr's from which smaller blocks
+        can be allocated for tenant networks
+
+        tenant_network_mask_bits with the mask bits to be used to partition the
+        block defined by tenant-network_cidr
+    """
+
     @classmethod
     def setUpClass(cls):
         os = clients.Manager()
-
-        if not os.config.network.quantum_available:
+        cls.network_cfg = os.config.network
+        if not cls.network_cfg.quantum_available:
             raise cls.skipException("Quantum support is required")
+        cls.client = os.network_client
+        cls.networks = []
+        cls.subnets = []
 
     @classmethod
     def tearDownClass(cls):
+        for subnet in cls.subnets:
+            cls.client.delete_subnet(subnet['id'])
         for network in cls.networks:
             cls.client.delete_network(network['id'])
 
-    def create_network(self, network_name=None):
+    @classmethod
+    def create_network(cls, network_name=None):
         """Wrapper utility that returns a test network."""
-        network_name = network_name or rand_name('test-network')
+        network_name = network_name or rand_name('test-network-')
 
-        resp, body = self.client.create_network(network_name)
+        resp, body = cls.client.create_network(network_name)
         network = body['network']
-        self.networks.append(network)
+        cls.networks.append(network)
         return network
+
+    @classmethod
+    def create_subnet(cls, network):
+        """Wrapper utility that returns a test subnet."""
+        cidr = netaddr.IPNetwork(cls.network_cfg.tenant_network_cidr)
+        mask_bits = cls.network_cfg.tenant_network_mask_bits
+        # Find a cidr that is not in use yet and create a subnet with it
+        for subnet_cidr in cidr.subnet(mask_bits):
+            try:
+                resp, body = cls.client.create_subnet(network['id'],
+                                                      str(subnet_cidr))
+                break
+            except exceptions.BadRequest as e:
+                is_overlapping_cidr = 'overlaps with another subnet' in str(e)
+                if not is_overlapping_cidr:
+                    raise
+        subnet = body['subnet']
+        cls.subnets.append(subnet)
+        return subnet
diff --git a/tempest/tests/network/common.py b/tempest/tests/network/common.py
new file mode 100644
index 0000000..1cff2c4
--- /dev/null
+++ b/tempest/tests/network/common.py
@@ -0,0 +1,315 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 Hewlett-Packard Development Company, L.P.
+# 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 subprocess
+
+import netaddr
+
+from quantumclient.common import exceptions as exc
+from tempest.common.utils.data_utils import rand_name
+from tempest import test
+
+
+class AttributeDict(dict):
+
+    """
+    Provide attribute access (dict.key) to dictionary values.
+    """
+
+    def __getattr__(self, name):
+        """Allow attribute access for all keys in the dict."""
+        if name in self:
+            return self[name]
+        return super(AttributeDict, self).__getattribute__(name)
+
+
+class DeletableResource(AttributeDict):
+
+    """
+    Support deletion of quantum resources (networks, subnets) via a
+    delete() method, as is supported by keystone and nova resources.
+    """
+
+    def __init__(self, *args, **kwargs):
+        self.client = kwargs.pop('client', None)
+        super(DeletableResource, self).__init__(*args, **kwargs)
+
+    def __str__(self):
+        return '<%s id="%s" name="%s">' % (self.__class__.__name__,
+                                           self.id, self.name)
+
+    def delete(self):
+        raise NotImplemented()
+
+
+class DeletableNetwork(DeletableResource):
+
+    def delete(self):
+        self.client.delete_network(self.id)
+
+
+class DeletableSubnet(DeletableResource):
+
+    _router_ids = set()
+
+    def add_to_router(self, router_id):
+        self._router_ids.add(router_id)
+        body = dict(subnet_id=self.id)
+        self.client.add_interface_router(router_id, body=body)
+
+    def delete(self):
+        for router_id in self._router_ids.copy():
+            body = dict(subnet_id=self.id)
+            self.client.remove_interface_router(router_id, body=body)
+            self._router_ids.remove(router_id)
+        self.client.delete_subnet(self.id)
+
+
+class DeletableRouter(DeletableResource):
+
+    def add_gateway(self, network_id):
+        body = dict(network_id=network_id)
+        self.client.add_gateway_router(self.id, body=body)
+
+    def delete(self):
+        self.client.remove_gateway_router(self.id)
+        self.client.delete_router(self.id)
+
+
+class DeletableFloatingIp(DeletableResource):
+
+    def delete(self):
+        self.client.delete_floatingip(self.id)
+
+
+class DeletablePort(DeletableResource):
+
+    def delete(self):
+        self.client.delete_port(self.id)
+
+
+class TestNetworkSmokeCommon(test.DefaultClientSmokeTest):
+    """
+    Base class for network smoke tests
+    """
+
+    @classmethod
+    def check_preconditions(cls):
+        if (cls.config.network.quantum_available):
+            cls.enabled = True
+            #verify that quantum_available is telling the truth
+            try:
+                cls.network_client.list_networks()
+            except exc.EndpointNotFound:
+                cls.enabled = False
+                raise
+        else:
+            cls.enabled = False
+            msg = 'Quantum not available'
+            raise cls.skipException(msg)
+
+    @classmethod
+    def setUpClass(cls):
+        super(TestNetworkSmokeCommon, cls).setUpClass()
+        cfg = cls.config.network
+        cls.tenant_id = cls.manager._get_identity_client(
+            cls.config.identity.username,
+            cls.config.identity.password,
+            cls.config.identity.tenant_name).tenant_id
+
+    def _create_keypair(self, client, namestart='keypair-smoke-'):
+        kp_name = rand_name(namestart)
+        keypair = client.keypairs.create(kp_name)
+        try:
+            self.assertEqual(keypair.id, kp_name)
+            self.set_resource(kp_name, keypair)
+        except AttributeError:
+            self.fail("Keypair object not successfully created.")
+        return keypair
+
+    def _create_security_group(self, client, namestart='secgroup-smoke-'):
+        # Create security group
+        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.")
+
+        # Add rules to the security group
+        rulesets = [
+            {
+                # ssh
+                'ip_protocol': 'tcp',
+                'from_port': 22,
+                'to_port': 22,
+                'cidr': '0.0.0.0/0',
+                'group_id': secgroup.id
+            },
+            {
+                # ping
+                'ip_protocol': 'icmp',
+                'from_port': -1,
+                'to_port': -1,
+                'cidr': '0.0.0.0/0',
+                'group_id': secgroup.id
+            }
+        ]
+        for ruleset in rulesets:
+            try:
+                client.security_group_rules.create(secgroup.id, **ruleset)
+            except Exception:
+                self.fail("Failed to create rule in security group.")
+
+        return secgroup
+
+    def _create_network(self, tenant_id, namestart='network-smoke-'):
+        name = rand_name(namestart)
+        body = dict(
+            network=dict(
+                name=name,
+                tenant_id=tenant_id,
+            ),
+        )
+        result = self.network_client.create_network(body=body)
+        network = DeletableNetwork(client=self.network_client,
+                                   **result['network'])
+        self.assertEqual(network.name, name)
+        self.set_resource(name, network)
+        return network
+
+    def _list_networks(self):
+        nets = self.network_client.list_networks()
+        return nets['networks']
+
+    def _list_subnets(self):
+        subnets = self.network_client.list_subnets()
+        return subnets['subnets']
+
+    def _list_routers(self):
+        routers = self.network_client.list_routers()
+        return routers['routers']
+
+    def _create_subnet(self, network, namestart='subnet-smoke-'):
+        """
+        Create a subnet for the given network within the cidr block
+        configured for tenant networks.
+        """
+        cfg = self.config.network
+        tenant_cidr = netaddr.IPNetwork(cfg.tenant_network_cidr)
+        result = None
+        # Repeatedly attempt subnet creation with sequential cidr
+        # blocks until an unallocated block is found.
+        for subnet_cidr in tenant_cidr.subnet(cfg.tenant_network_mask_bits):
+            body = dict(
+                subnet=dict(
+                    ip_version=4,
+                    network_id=network.id,
+                    tenant_id=network.tenant_id,
+                    cidr=str(subnet_cidr),
+                ),
+            )
+            try:
+                result = self.network_client.create_subnet(body=body)
+                break
+            except exc.QuantumClientException as e:
+                is_overlapping_cidr = 'overlaps with another subnet' in str(e)
+                if not is_overlapping_cidr:
+                    raise
+        self.assertIsNotNone(result, 'Unable to allocate tenant network')
+        subnet = DeletableSubnet(client=self.network_client,
+                                 **result['subnet'])
+        self.assertEqual(subnet.cidr, str(subnet_cidr))
+        self.set_resource(rand_name(namestart), subnet)
+        return subnet
+
+    def _create_port(self, network, namestart='port-quotatest-'):
+        name = rand_name(namestart)
+        body = dict(
+            port=dict(name=name,
+                      network_id=network.id,
+                      tenant_id=network.tenant_id))
+        try:
+            result = self.network_client.create_port(body=body)
+        except Exception as e:
+            raise
+        self.assertIsNotNone(result, 'Unable to allocate port')
+        port = DeletablePort(client=self.network_client,
+                             **result['port'])
+        self.set_resource(name, port)
+        return port
+
+    def _create_server(self, client, network, name, key_name, security_groups):
+        flavor_id = self.config.compute.flavor_ref
+        base_image_id = self.config.compute.image_ref
+        create_kwargs = {
+            'nics': [
+                {'net-id': network.id},
+            ],
+            'key_name': key_name,
+            'security_groups': security_groups,
+        }
+        server = client.servers.create(name, base_image_id, flavor_id,
+                                       **create_kwargs)
+        try:
+            self.assertEqual(server.name, name)
+            self.set_resource(name, server)
+        except AttributeError:
+            self.fail("Server not successfully created.")
+        test.status_timeout(client.servers, server.id, 'ACTIVE')
+        # The instance retrieved on creation is missing network
+        # details, necessitating retrieval after it becomes active to
+        # ensure correct details.
+        server = client.servers.get(server.id)
+        self.set_resource(name, server)
+        return server
+
+    def _create_floating_ip(self, server, external_network_id):
+        result = self.network_client.list_ports(device_id=server.id)
+        ports = result.get('ports', [])
+        self.assertEqual(len(ports), 1,
+                         "Unable to determine which port to target.")
+        port_id = ports[0]['id']
+        body = dict(
+            floatingip=dict(
+                floating_network_id=external_network_id,
+                port_id=port_id,
+                tenant_id=server.tenant_id,
+            )
+        )
+        result = self.network_client.create_floatingip(body=body)
+        floating_ip = DeletableFloatingIp(client=self.network_client,
+                                          **result['floatingip'])
+        self.set_resource(rand_name('floatingip-'), floating_ip)
+        return floating_ip
+
+    def _ping_ip_address(self, ip_address):
+        cmd = ['ping', '-c1', '-w1', ip_address]
+
+        def ping():
+            proc = subprocess.Popen(cmd,
+                                    stdout=subprocess.PIPE,
+                                    stderr=subprocess.PIPE)
+            proc.wait()
+            if proc.returncode == 0:
+                return True
+
+        # TODO(mnewby) Allow configuration of execution and sleep duration.
+        return test.call_until_true(ping, 20, 1)
diff --git a/tempest/tests/network/test_network_basic_ops.py b/tempest/tests/network/test_network_basic_ops.py
index aed368e..3afe8e3 100644
--- a/tempest/tests/network/test_network_basic_ops.py
+++ b/tempest/tests/network/test_network_basic_ops.py
@@ -1,6 +1,7 @@
 # vim: tabstop=4 shiftwidth=4 softtabstop=4
 
 # Copyright 2012 OpenStack, LLC
+# Copyright 2013 Hewlett-Packard Development Company, L.P.
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -15,94 +16,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import logging
-import subprocess
-
-import netaddr
-
-from quantumclient.common import exceptions as exc
-
 from tempest.common.utils.data_utils import rand_name
-from tempest import smoke
-from tempest import test
+import tempest.tests.network.common as net_common
 
 
-LOG = logging.getLogger(__name__)
-
-
-class AttributeDict(dict):
-
-    """
-    Provide attribute access (dict.key) to dictionary values.
-    """
-
-    def __getattr__(self, name):
-        """Allow attribute access for all keys in the dict."""
-        if name in self:
-            return self[name]
-        return super(AttributeDict, self).__getattribute__(name)
-
-
-class DeletableResource(AttributeDict):
-
-    """
-    Support deletion of quantum resources (networks, subnets) via a
-    delete() method, as is supported by keystone and nova resources.
-    """
-
-    def __init__(self, *args, **kwargs):
-        self.client = kwargs.pop('client', None)
-        super(DeletableResource, self).__init__(*args, **kwargs)
-
-    def __str__(self):
-        return '<%s id="%s" name="%s">' % (self.__class__.__name__,
-                                           self.id, self.name)
-
-    def delete(self):
-        raise NotImplemented()
-
-
-class DeletableNetwork(DeletableResource):
-
-    def delete(self):
-        self.client.delete_network(self.id)
-
-
-class DeletableSubnet(DeletableResource):
-
-    _router_ids = set()
-
-    def add_to_router(self, router_id):
-        self._router_ids.add(router_id)
-        body = dict(subnet_id=self.id)
-        self.client.add_interface_router(router_id, body=body)
-
-    def delete(self):
-        for router_id in self._router_ids.copy():
-            body = dict(subnet_id=self.id)
-            self.client.remove_interface_router(router_id, body=body)
-            self._router_ids.remove(router_id)
-        self.client.delete_subnet(self.id)
-
-
-class DeletableRouter(DeletableResource):
-
-    def add_gateway(self, network_id):
-        body = dict(network_id=network_id)
-        self.client.add_gateway_router(self.id, body=body)
-
-    def delete(self):
-        self.client.remove_gateway_router(self.id)
-        self.client.delete_router(self.id)
-
-
-class DeletableFloatingIp(DeletableResource):
-
-    def delete(self):
-        self.client.delete_floatingip(self.id)
-
-
-class TestNetworkBasicOps(smoke.DefaultClientSmokeTest):
+class TestNetworkBasicOps(net_common.TestNetworkSmokeCommon):
 
     """
     This smoke test suite assumes that Nova has been configured to
@@ -165,19 +83,12 @@
 
     @classmethod
     def check_preconditions(cls):
+        super(TestNetworkBasicOps, cls).check_preconditions()
         cfg = cls.config.network
-        msg = None
         if not (cfg.tenant_networks_reachable or cfg.public_network_id):
             msg = ('Either tenant_networks_reachable must be "true", or '
                    'public_network_id must be defined.')
-        else:
-            try:
-                cls.network_client.list_networks()
-            except exc.QuantumClientException:
-                msg = 'Unable to connect to Quantum service.'
-
-        cls.enabled = not bool(msg)
-        if msg:
+            cls.enabled = False
             raise cls.skipException(msg)
 
     @classmethod
@@ -198,55 +109,6 @@
         cls.servers = []
         cls.floating_ips = {}
 
-    def _create_keypair(self, client):
-        kp_name = rand_name('keypair-smoke-')
-        keypair = client.keypairs.create(kp_name)
-        try:
-            self.assertEqual(keypair.id, kp_name)
-            self.set_resource(kp_name, keypair)
-        except AttributeError:
-            self.fail("Keypair object not successfully created.")
-        return keypair
-
-    def _create_security_group(self, client):
-        # Create security group
-        sg_name = rand_name('secgroup-smoke-')
-        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.")
-
-        # Add rules to the security group
-        rulesets = [
-            {
-                # ssh
-                'ip_protocol': 'tcp',
-                'from_port': 22,
-                'to_port': 22,
-                'cidr': '0.0.0.0/0',
-                'group_id': secgroup.id
-            },
-            {
-                # ping
-                'ip_protocol': 'icmp',
-                'from_port': -1,
-                'to_port': -1,
-                'cidr': '0.0.0.0/0',
-                'group_id': secgroup.id
-            }
-        ]
-        for ruleset in rulesets:
-            try:
-                client.security_group_rules.create(secgroup.id, **ruleset)
-            except Exception:
-                self.fail("Failed to create rule in security group.")
-
-        return secgroup
-
     def _get_router(self, tenant_id):
         """Retrieve a router for the given tenant id.
 
@@ -261,7 +123,7 @@
         network_id = self.config.network.public_network_id
         if router_id:
             result = self.network_client.show_router(router_id)
-            return AttributeDict(**result['router'])
+            return net_common.AttributeDict(**result['router'])
         elif network_id:
             router = self._create_router(tenant_id)
             router.add_gateway(network_id)
@@ -270,8 +132,8 @@
             raise Exception("Neither of 'public_router_id' or "
                             "'public_network_id' has been defined.")
 
-    def _create_router(self, tenant_id):
-        name = rand_name('router-smoke-')
+    def _create_router(self, tenant_id, namestart='router-smoke-'):
+        name = rand_name(namestart)
         body = dict(
             router=dict(
                 name=name,
@@ -280,130 +142,12 @@
             ),
         )
         result = self.network_client.create_router(body=body)
-        router = DeletableRouter(client=self.network_client,
-                                 **result['router'])
+        router = net_common.DeletableRouter(client=self.network_client,
+                                            **result['router'])
         self.assertEqual(router.name, name)
         self.set_resource(name, router)
         return router
 
-    def _create_network(self, tenant_id):
-        name = rand_name('network-smoke-')
-        body = dict(
-            network=dict(
-                name=name,
-                tenant_id=tenant_id,
-            ),
-        )
-        result = self.network_client.create_network(body=body)
-        network = DeletableNetwork(client=self.network_client,
-                                   **result['network'])
-        self.assertEqual(network.name, name)
-        self.set_resource(name, network)
-        return network
-
-    def _list_networks(self):
-        nets = self.network_client.list_networks()
-        return nets['networks']
-
-    def _list_subnets(self):
-        subnets = self.network_client.list_subnets()
-        return subnets['subnets']
-
-    def _list_routers(self):
-        routers = self.network_client.list_routers()
-        return routers['routers']
-
-    def _create_subnet(self, network):
-        """
-        Create a subnet for the given network within the cidr block
-        configured for tenant networks.
-        """
-        cfg = self.config.network
-        tenant_cidr = netaddr.IPNetwork(cfg.tenant_network_cidr)
-        result = None
-        # Repeatedly attempt subnet creation with sequential cidr
-        # blocks until an unallocated block is found.
-        for subnet_cidr in tenant_cidr.subnet(cfg.tenant_network_mask_bits):
-            body = dict(
-                subnet=dict(
-                ip_version=4,
-                network_id=network.id,
-                tenant_id=network.tenant_id,
-                cidr=str(subnet_cidr),
-                ),
-            )
-            try:
-                result = self.network_client.create_subnet(body=body)
-                break
-            except exc.QuantumClientException as e:
-                is_overlapping_cidr = 'overlaps with another subnet' in str(e)
-                if not is_overlapping_cidr:
-                    raise
-        self.assertIsNotNone(result, 'Unable to allocate tenant network')
-        subnet = DeletableSubnet(client=self.network_client,
-                                 **result['subnet'])
-        self.assertEqual(subnet.cidr, str(subnet_cidr))
-        self.set_resource(rand_name('subnet-smoke-'), subnet)
-        return subnet
-
-    def _create_server(self, client, network, name, key_name, security_groups):
-        flavor_id = self.config.compute.flavor_ref
-        base_image_id = self.config.compute.image_ref
-        create_kwargs = {
-            'nics': [
-                {'net-id': network.id},
-            ],
-            'key_name': key_name,
-            'security_groups': security_groups,
-        }
-        server = client.servers.create(name, base_image_id, flavor_id,
-                                       **create_kwargs)
-        try:
-            self.assertEqual(server.name, name)
-            self.set_resource(name, server)
-        except AttributeError:
-            self.fail("Server not successfully created.")
-        self.status_timeout(client.servers, server.id, 'ACTIVE')
-        # The instance retrieved on creation is missing network
-        # details, necessitating retrieval after it becomes active to
-        # ensure correct details.
-        server = client.servers.get(server.id)
-        self.set_resource(name, server)
-        return server
-
-    def _create_floating_ip(self, server, external_network_id):
-        result = self.network_client.list_ports(device_id=server.id)
-        ports = result.get('ports', [])
-        self.assertEqual(len(ports), 1,
-                         "Unable to determine which port to target.")
-        port_id = ports[0]['id']
-        body = dict(
-            floatingip=dict(
-                floating_network_id=external_network_id,
-                port_id=port_id,
-                tenant_id=server.tenant_id,
-            )
-        )
-        result = self.network_client.create_floatingip(body=body)
-        floating_ip = DeletableFloatingIp(client=self.network_client,
-                                          **result['floatingip'])
-        self.set_resource(rand_name('floatingip-'), floating_ip)
-        return floating_ip
-
-    def _ping_ip_address(self, ip_address):
-        cmd = ['ping', '-c1', '-w1', ip_address]
-
-        def ping():
-            proc = subprocess.Popen(cmd,
-                                    stdout=subprocess.PIPE,
-                                    stderr=subprocess.PIPE)
-            proc.wait()
-            if proc.returncode == 0:
-                return True
-
-        # TODO(mnewby) Allow configuration of execution and sleep duration.
-        return test.call_until_true(ping, 20, 1)
-
     def test_001_create_keypairs(self):
         self.keypairs[self.tenant_id] = self._create_keypair(
             self.compute_client)
@@ -428,31 +172,21 @@
         seen_names = [n['name'] for n in seen_nets]
         seen_ids = [n['id'] for n in seen_nets]
         for mynet in self.networks:
-            assert mynet.name in seen_names, \
-            "Did not see expected network with name %s" % mynet.name
-            assert mynet.id in seen_ids, \
-            "Did not see expected network with id %s" % mynet.id
+            self.assertIn(mynet.name, seen_names)
+            self.assertIn(mynet.id, seen_ids)
         seen_subnets = self._list_subnets()
         seen_net_ids = [n['network_id'] for n in seen_subnets]
         seen_subnet_ids = [n['id'] for n in seen_subnets]
         for mynet in self.networks:
-            assert mynet.id in seen_net_ids, \
-            "Did not see subnet belonging to network %s/%s" % \
-            (mynet.name, mynet.id)
+            self.assertIn(mynet.id, seen_net_ids)
         for mysubnet in self.subnets:
-            assert mysubnet.id in seen_subnet_ids, \
-            "Did not see expected subnet with id %s" % \
-            mysubnet.id
+            self.assertIn(mysubnet.id, seen_subnet_ids)
         seen_routers = self._list_routers()
         seen_router_ids = [n['id'] for n in seen_routers]
         seen_router_names = [n['name'] for n in seen_routers]
         for myrouter in self.routers:
-            assert myrouter.name in seen_router_names, \
-            "Did not see expected router with name %s" % \
-            myrouter.name
-            assert myrouter.id in seen_router_ids, \
-            "Did not see expected router with id %s" % \
-            myrouter.id
+            self.assertIn(myrouter.name, seen_router_names)
+            self.assertIn(myrouter.id, seen_router_ids)
 
     def test_005_create_servers(self):
         if not (self.keypairs or self.security_groups or self.networks):
diff --git a/tempest/tests/network/test_network_quota_basic.py b/tempest/tests/network/test_network_quota_basic.py
new file mode 100644
index 0000000..eaec708
--- /dev/null
+++ b/tempest/tests/network/test_network_quota_basic.py
@@ -0,0 +1,92 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 Hewlett-Packard Development Company, L.P.
+# 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 quantumclient.common import exceptions as exc
+from tempest.tests.network.common import TestNetworkSmokeCommon
+
+MAX_REASONABLE_ITERATIONS = 51  # more than enough. Default for port is 50.
+
+
+class TestNetworkQuotaBasic(TestNetworkSmokeCommon):
+    """
+    This test suite contains tests that each loop trying to grab a
+    particular resource until a quota limit is hit.
+    For sanity, there is a maximum number of iterations - if this is hit
+    the test fails. Covers network, subnet, port.
+    """
+
+    @classmethod
+    def check_preconditions(cls):
+        super(TestNetworkQuotaBasic, cls).check_preconditions()
+
+    @classmethod
+    def setUpClass(cls):
+        super(TestNetworkQuotaBasic, cls).setUpClass()
+        cls.check_preconditions()
+        cls.networks = []
+        cls.subnets = []
+        cls.ports = []
+
+    def test_create_network_until_quota_hit(self):
+        hit_limit = False
+        for n in xrange(MAX_REASONABLE_ITERATIONS):
+            try:
+                self.networks.append(
+                    self._create_network(self.tenant_id,
+                                         namestart='network-quotatest-'))
+            except exc.QuantumClientException as e:
+                if (e.status_code != 409):
+                    raise
+                hit_limit = True
+                break
+        self.assertTrue(hit_limit, "Failed: Did not hit quota limit !")
+
+    def test_create_subnet_until_quota_hit(self):
+        if not self.networks:
+            self.networks.append(
+                self._create_network(self.tenant_id,
+                                     namestart='network-quotatest-'))
+        hit_limit = False
+        for n in xrange(MAX_REASONABLE_ITERATIONS):
+            try:
+                self.subnets.append(
+                    self._create_subnet(self.networks[0],
+                                        namestart='subnet-quotatest-'))
+            except exc.QuantumClientException as e:
+                if (e.status_code != 409):
+                    raise
+                hit_limit = True
+                break
+        self.assertTrue(hit_limit, "Failed: Did not hit quota limit !")
+
+    def test_create_ports_until_quota_hit(self):
+        if not self.networks:
+            self.networks.append(
+                self._create_network(self.tenant_id,
+                                     namestart='network-quotatest-'))
+        hit_limit = False
+        for n in xrange(MAX_REASONABLE_ITERATIONS):
+            try:
+                self.ports.append(
+                    self._create_port(self.networks[0],
+                                      namestart='port-quotatest-'))
+            except exc.QuantumClientException as e:
+                if (e.status_code != 409):
+                    raise
+                hit_limit = True
+                break
+        self.assertTrue(hit_limit, "Failed: Did not hit quota limit !")
diff --git a/tempest/tests/network/test_networks.py b/tempest/tests/network/test_networks.py
index 136279f..e61bc62 100644
--- a/tempest/tests/network/test_networks.py
+++ b/tempest/tests/network/test_networks.py
@@ -15,51 +15,84 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.test import attr
+import netaddr
 
 from tempest.common.utils.data_utils import rand_name
+from tempest import exceptions
+from tempest.test import attr
 from tempest.tests.network import base
 
 
 class NetworksTest(base.BaseNetworkTest):
 
+    """
+    Tests the following operations in the Quantum API using the REST client for
+    Quantum:
+
+        create a network for a tenant
+        list tenant's networks
+        show a tenant network details
+        create a subnet for a tenant
+        list tenant's subnets
+        show a tenant subnet details
+
+    v2.0 of the Quantum API is assumed. It is also assumed that the following
+    options are defined in the [network] section of etc/tempest.conf:
+
+        tenant_network_cidr with a block of cidr's from which smaller blocks
+        can be allocated for tenant networks
+
+        tenant_network_mask_bits with the mask bits to be used to partition the
+        block defined by tenant-network_cidr
+    """
+
     @classmethod
     def setUpClass(cls):
         super(NetworksTest, cls).setUpClass()
         cls.network = cls.create_network()
         cls.name = cls.network['name']
+        cls.subnet = cls.create_subnet(cls.network)
+        cls.cidr = cls.subnet['cidr']
 
     @attr(type='positive')
-    def test_create_delete_network(self):
-        # Creates and deletes a network for a tenant
-        name = rand_name('network')
+    def test_create_delete_network_subnet(self):
+        # Creates a network
+        name = rand_name('network-')
         resp, body = self.client.create_network(name)
-        self.assertEqual('202', resp['status'])
+        self.assertEqual('201', resp['status'])
         network = body['network']
         self.assertTrue(network['id'] is not None)
+        # Find a cidr that is not in use yet and create a subnet with it
+        cidr = netaddr.IPNetwork(self.network_cfg.tenant_network_cidr)
+        mask_bits = self.network_cfg.tenant_network_mask_bits
+        for subnet_cidr in cidr.subnet(mask_bits):
+            try:
+                resp, body = self.client.create_subnet(network['id'],
+                                                       str(subnet_cidr))
+                break
+            except exceptions.BadRequest as e:
+                is_overlapping_cidr = 'overlaps with another subnet' in str(e)
+                if not is_overlapping_cidr:
+                    raise
+        self.assertEqual('201', resp['status'])
+        subnet = body['subnet']
+        self.assertTrue(subnet['id'] is not None)
+        #Deletes subnet and network
+        resp, body = self.client.delete_subnet(subnet['id'])
+        self.assertEqual('204', resp['status'])
         resp, body = self.client.delete_network(network['id'])
         self.assertEqual('204', resp['status'])
 
     @attr(type='positive')
     def test_show_network(self):
         # Verifies the details of a network
-        resp, body = self.client.get_network(self.network['id'])
+        resp, body = self.client.show_network(self.network['id'])
         self.assertEqual('200', resp['status'])
         network = body['network']
         self.assertEqual(self.network['id'], network['id'])
         self.assertEqual(self.name, network['name'])
 
     @attr(type='positive')
-    def test_show_network_details(self):
-        # Verifies the full details of a network
-        resp, body = self.client.get_network_details(self.network['id'])
-        self.assertEqual('200', resp['status'])
-        network = body['network']
-        self.assertEqual(self.network['id'], network['id'])
-        self.assertEqual(self.name, network['name'])
-        self.assertEqual(len(network['ports']), 0)
-
-    @attr(type='positive')
     def test_list_networks(self):
         # Verify the network exists in the list of all networks
         resp, body = self.client.list_networks()
@@ -68,9 +101,18 @@
         self.assertTrue(found)
 
     @attr(type='positive')
-    def test_list_networks_with_detail(self):
-        # Verify the network exists in the detailed list of all networks
-        resp, body = self.client.list_networks_details()
-        networks = body['networks']
-        found = any(n for n in networks if n['id'] == self.network['id'])
+    def test_show_subnet(self):
+        # Verifies the details of a subnet
+        resp, body = self.client.show_subnet(self.subnet['id'])
+        self.assertEqual('200', resp['status'])
+        subnet = body['subnet']
+        self.assertEqual(self.subnet['id'], subnet['id'])
+        self.assertEqual(self.cidr, subnet['cidr'])
+
+    @attr(type='positive')
+    def test_list_subnets(self):
+        # Verify the subnet exists in the list of all subnets
+        resp, body = self.client.list_subnets()
+        subnets = body['subnets']
+        found = any(n for n in subnets if n['id'] == self.subnet['id'])
         self.assertTrue(found)
diff --git a/tempest/tests/object_storage/test_container_sync.py b/tempest/tests/object_storage/test_container_sync.py
index dad6309..d5fa96c 100644
--- a/tempest/tests/object_storage/test_container_sync.py
+++ b/tempest/tests/object_storage/test_container_sync.py
@@ -61,7 +61,7 @@
             #Attempt to delete the container
             resp, _ = client[0].delete_container(cont_name)
 
-    @testtools.skip('Until Bug 1093743 is resolved.')
+    @testtools.skip('Until Bug #1093743 is resolved.')
     @attr(type='positive')
     def test_container_synchronization(self):
         #Container to container synchronization
diff --git a/tempest/tests/object_storage/test_object_expiry.py b/tempest/tests/object_storage/test_object_expiry.py
index 8411ef5..c12ec3d 100644
--- a/tempest/tests/object_storage/test_object_expiry.py
+++ b/tempest/tests/object_storage/test_object_expiry.py
@@ -55,7 +55,7 @@
         #Attempt to delete the container
         resp, _ = cls.container_client.delete_container(cls.container_name)
 
-    @testtools.skip('Until bug 1069849 is resolved.')
+    @testtools.skip('Until Bug #1069849 is resolved.')
     @attr(type='regression')
     def test_get_object_after_expiry_time(self):
         # GET object after expiry time
diff --git a/tempest/tests/object_storage/test_object_services.py b/tempest/tests/object_storage/test_object_services.py
index 76fab0b..1edce92 100644
--- a/tempest/tests/object_storage/test_object_services.py
+++ b/tempest/tests/object_storage/test_object_services.py
@@ -590,7 +590,7 @@
                           self.container_name, object_name,
                           metadata=self.custom_headers)
 
-    @testtools.skip('Until bug 1097137 is resolved.')
+    @testtools.skip('Until Bug #1097137 is resolved.')
     @attr(type='positive')
     def test_get_object_using_temp_url(self):
         #Access object using temp url within expiry time
diff --git a/tempest/tests/volume/admin/test_volume_types.py b/tempest/tests/volume/admin/test_volume_types.py
index 6eb3629..38ac74a 100644
--- a/tempest/tests/volume/admin/test_volume_types.py
+++ b/tempest/tests/volume/admin/test_volume_types.py
@@ -37,10 +37,6 @@
                                                                auth_url,
                                                                adm_tenant)
 
-    @classmethod
-    def tearDownClass(cls):
-        super(VolumeTypesTest, cls).tearDownClass()
-
     def test_volume_type_list(self):
         # List Volume types.
         try:
diff --git a/tempest/tests/volume/admin/test_volume_types_extra_specs_negative.py b/tempest/tests/volume/admin/test_volume_types_extra_specs_negative.py
index f528cec..13fcbbf 100644
--- a/tempest/tests/volume/admin/test_volume_types_extra_specs_negative.py
+++ b/tempest/tests/volume/admin/test_volume_types_extra_specs_negative.py
@@ -15,7 +15,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import testtools
 import uuid
 
 from tempest.common.utils.data_utils import rand_name
diff --git a/tempest/tests/volume/admin/test_volume_types_negative.py b/tempest/tests/volume/admin/test_volume_types_negative.py
index 1b11d68..daf804d 100644
--- a/tempest/tests/volume/admin/test_volume_types_negative.py
+++ b/tempest/tests/volume/admin/test_volume_types_negative.py
@@ -15,7 +15,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import testtools
 import uuid
 
 from tempest import exceptions
diff --git a/tempest/tests/volume/test_volumes_get.py b/tempest/tests/volume/test_volumes_get.py
index a246afe..8e80e18 100644
--- a/tempest/tests/volume/test_volumes_get.py
+++ b/tempest/tests/volume/test_volumes_get.py
@@ -29,17 +29,22 @@
         super(VolumesGetTest, cls).setUpClass()
         cls.client = cls.volumes_client
 
-    @attr(type='smoke')
-    def test_volume_create_get_delete(self):
+    def _volume_create_get_delete(self, image_ref=None):
         # Create a volume, Get it's details and Delete the volume
         try:
             volume = {}
             v_name = rand_name('Volume-')
             metadata = {'Type': 'work'}
             #Create a volume
-            resp, volume = self.client.create_volume(size=1,
-                                                     display_name=v_name,
-                                                     metadata=metadata)
+            if not image_ref:
+                resp, volume = self.client.create_volume(size=1,
+                                                         display_name=v_name,
+                                                         metadata=metadata)
+            else:
+                resp, volume = self.client.create_volume(size=1,
+                                                         display_name=v_name,
+                                                         metadata=metadata,
+                                                         imageRef=image_ref)
             self.assertEqual(200, resp.status)
             self.assertTrue('id' in volume)
             self.assertTrue('display_name' in volume)
@@ -100,6 +105,14 @@
                 self.assertEqual(202, resp.status)
                 self.client.wait_for_resource_deletion(volume['id'])
 
+    @attr(type='smoke')
+    def test_volume_create_get_delete(self):
+        self._volume_create_get_delete(image_ref=None)
+
+    @attr(type='smoke')
+    def test_volume_from_image(self):
+        self._volume_create_get_delete(image_ref=self.config.compute.image_ref)
+
 
 class VolumesGetTestXML(VolumesGetTest):
     _interface = "xml"
diff --git a/tools/check_source.sh b/tools/check_source.sh
new file mode 100755
index 0000000..089ad70
--- /dev/null
+++ b/tools/check_source.sh
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+
+python tools/hacking.py --ignore=E122,E125,E126 --repeat --show-source --exclude=.venv,.tox,dist,doc,openstack,*egg .
+pep8_ret=$?
+
+pyflakes tempest stress setup.py tools cli bin | grep "imported but unused"
+unused_ret=$?
+
+ret=0
+if [ $pep8_ret != 0 ]; then
+    echo "hacking.py/pep8 test FAILED!" >&2
+    (( ret += 1  ))
+else
+    echo "hacking.py/pep8 test OK!" >&2
+fi
+
+if [ $unused_ret == 0 ]; then
+    echo "Unused import test FAILED!" >&2
+    (( ret += 2  ))
+else
+    echo "Unused import test OK!" >&2
+fi
+
+exit $ret
diff --git a/tools/hacking.py b/tools/hacking.py
index 617682d..7e46b74 100755
--- a/tools/hacking.py
+++ b/tools/hacking.py
@@ -21,7 +21,6 @@
 built on top of pep8.py
 """
 
-import fnmatch
 import inspect
 import logging
 import os
@@ -323,6 +322,30 @@
                 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
diff --git a/tools/install_venv.py b/tools/install_venv.py
index 20dcefa..ef7b0a8 100644
--- a/tools/install_venv.py
+++ b/tools/install_venv.py
@@ -21,9 +21,7 @@
 
 """Installation script for Tempest's development virtualenv."""
 
-import optparse
 import os
-import subprocess
 import sys
 
 import install_venv_common as install_venv
diff --git a/tools/pip-requires b/tools/pip-requires
index e85cced..758442c 100644
--- a/tools/pip-requires
+++ b/tools/pip-requires
@@ -14,3 +14,6 @@
 keyring
 testrepository
 oslo.config>=1.1.0
+# Needed for whitebox testing
+sqlalchemy
+MySQL-python
diff --git a/tools/tempest_coverage.py b/tools/tempest_coverage.py
index a46d0fb..9dcbd46 100755
--- a/tools/tempest_coverage.py
+++ b/tools/tempest_coverage.py
@@ -1,6 +1,6 @@
 # vim: tabstop=4 shiftwidth=4 softtabstop=4
 
-# Copyright 2012 IBM
+# Copyright 2012 IBM Corp.
 #
 #    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
@@ -16,7 +16,6 @@
 
 import json
 import os
-import re
 import shutil
 import sys
 
@@ -24,7 +23,6 @@
 
 from tempest.common.rest_client import RestClient
 from tempest import config
-from tempest.tests.compute import base
 
 CONF = config.TempestConfig()
 
diff --git a/tools/test-requires b/tools/test-requires
index 4801391..f701dab 100644
--- a/tools/test-requires
+++ b/tools/test-requires
@@ -1,6 +1,5 @@
 pep8==1.3.3
 pylint==0.19
-# Needed for whitebox testing
-sqlalchemy
-MySQL-python
+#TODO(afazekas): ensure pg_config installed
 psycopg2
+pyflakes
diff --git a/tox.ini b/tox.ini
index 92ce6bc..85a0d86 100644
--- a/tox.ini
+++ b/tox.ini
@@ -19,4 +19,4 @@
            python -m tools/tempest_coverage -c report --html
 
 [testenv:pep8]
-commands = python tools/hacking.py --ignore=E122,E125,E126 --repeat --show-source --exclude=.venv,.tox,dist,doc,openstack,*egg .
+commands = bash tools/check_source.sh