Merge "add some tests for host and seperate negative ones"
diff --git a/HACKING.rst b/HACKING.rst
index 499b436..7d995c3 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -8,16 +8,6 @@
 Tempest Specific Commandments
 ------------------------------
 
-[T101] 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")
-
 - [T102] Cannot import OpenStack python clients in tempest/api tests
 - [T103] tempest/tests is deprecated
 - [T104] Scenario tests require a services decorator
@@ -115,6 +105,32 @@
 in tempest.api.compute would require a service tag for those services, however
 they do not need to be tagged as compute.
 
+Negative Tests
+--------------
+When adding negative tests to tempest there are 2 requirements. First the tests
+must be marked with a negative attribute. For example::
+
+  @attr(type=negative)
+  def test_resource_no_uuid(self):
+    ...
+
+The second requirement is that all negative tests must be added to a negative
+test file. If such a file doesn't exist for the particular resource being
+tested a new test file should be added.
+
+Test skips because of Known Bugs
+--------------------------------
+
+If a test is broken because of a bug it is appropriate to skip the test until
+bug has been fixed. You should use the skip_because decorator so that
+Tempest's skip tracking tool can watch the bug status.
+
+Example::
+
+  @skip_because(bug="980688")
+  def test_this_and_that(self):
+    ...
+
 Guidelines
 ----------
 - Do not submit changesets with only testcases which are skipped as
diff --git a/doc/source/conf.py b/doc/source/conf.py
index cf838c0..e5444ae 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -51,17 +51,6 @@
 project = u'Tempest'
 copyright = u'2013, OpenStack QA Team'
 
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-# The short X.Y version.
-import pbr.version
-version_info = pbr.version.VersionInfo('tempest')
-version = version_info.version_string()
-# The full version, including alpha/beta/rc tags.
-release = version_info.release_string()
-
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
 #language = None
diff --git a/etc/whitelist.yaml b/etc/whitelist.yaml
new file mode 100644
index 0000000..e6d28f5
--- /dev/null
+++ b/etc/whitelist.yaml
@@ -0,0 +1,162 @@
+n-cpu:
+    - module: "nova.virt.libvirt.driver"
+      message: "During wait destroy, instance disappeared"
+    - module: "glanceclient.common.http"
+      message: "Request returned failure status"
+    - module: "nova.openstack.common.periodic_task"
+      message: "Error during ComputeManager\\.update_available_resource: \
+        'NoneType' object is not iterable"
+    - module: "nova.compute.manager"
+      message: "Possibly task preempted"
+    - module: "nova.openstack.common.rpc.amqp"
+      message: "Exception during message handling"
+    - module: "nova.network.api"
+      message: "Failed storing info cache"
+    - module: "nova.compute.manager"
+      message: "Error while trying to clean up image"
+    - module: "nova.virt.libvirt.driver"
+      message: "Error injecting data into image.*\\(Unexpected error while \
+        running command"
+    - module: "nova.compute.manager"
+      message: "Instance failed to spawn"
+    - module: "nova.compute.manager"
+      message: "Error: Unexpected error while running command"
+    - module: "nova.virt.libvirt.driver"
+      message: "Error from libvirt during destroy"
+    - module: "nova.virt.libvirt.vif"
+      message: "Failed while unplugging vif"
+    - module: "nova.openstack.common.loopingcal"
+      message: "in fixed duration looping call"
+    - module: "nova.virt.libvirt.driver"
+      message: "Getting disk size of instance"
+    - module: "nova.virt.libvirt.driver"
+      message: "No such file or directory: '/opt/stack/data/nova/instances"
+
+g-api:
+    - module: "glance.store.sheepdog"
+      message: "Error in store configuration: Unexpected error while \
+        running command"
+    - module: "swiftclient"
+      message: "Container HEAD failed: .*404 Not Found"
+
+ceilometer-acompute:
+    - module: "ceilometer.compute.pollsters.disk"
+      message: "Requested operation is not valid: domain is not running"
+    - module: "ceilometer.compute.pollsters.disk"
+      message: "Domain not found: no domain with matching uuid"
+    - module: "ceilometer.compute.pollsters.net"
+      message: "No module named libvirt"
+
+ceilometer-alarm-evaluator:
+    - module: "ceilometer.alarm.service"
+      message: "alarm evaluation cycle failed"
+
+h-api:
+    - module: "root"
+      message: "Returning 400 to user: The server could not comply with \
+        the request since it is either malformed or otherwise incorrect"
+    - module: "root"
+      message: "Unexpected error occurred serving API: Request limit \
+        exceeded: Template exceeds maximum allowed size"
+    - module: "root"
+      message: "Unexpected error occurred serving API: The Stack \
+        .*could not be found"
+
+h-eng:
+    - module: "heat.openstack.common.rpc.amqp"
+      message: "Exception during message handling"
+    - module: "heat.openstack.common.rpc.common"
+      message: "The Stack .* could not be found"
+
+n-api:
+    - module: "glanceclient.common.http"
+      message: "Request returned failure status"
+    - module: "nova.api.openstack"
+      message: "Caught error: Quota exceeded for"
+    - module: "nova.compute.api"
+      message: "ServerDiskConfigTest"
+    - module: "nova.compute.api"
+      message: "ServersTest"
+    - module: "nova.compute.api"
+      message: "\\{u'kernel_id'.*u'ramdisk_id':"
+    - module: "nova.api.openstack.wsgi"
+      message: "takes exactly 4 arguments"
+
+n-cond:
+    - module: "nova.notifications"
+      message: "Failed to send state update notification"
+
+n-sch:
+    - module: "nova.scheduler.filter_scheduler"
+      message: "Error from last host: "
+
+c-api:
+    - module: "cinder.api.middleware.fault"
+      message: "Caught error: Volume .* could not be found"
+    - module: "cinder.api.middleware.fault"
+      message: "Caught error: Snapshot .* could not be found"
+
+c-vol:
+    - module: "cinder.brick.iscsi.iscsi"
+      message: "Failed to create iscsi target for volume id"
+    - module: "cinder.brick.local_dev.lvm"
+      message: "/dev/dm-1: stat failed: No such file or directory"
+    - module: "cinder.brick.local_dev.lvm"
+      message: "Can't remove open logical volume"
+
+q-dhpc:
+    - module: "neutron.common.legacy"
+      message: "Skipping unknown group key: firewall_driver"
+    - module: "neutron.agent.dhcp_agent"
+      message: "Unable to enable dhcp"
+    - module: "neutron.agent.dhcp_agent"
+      message: " Network .* RPC info call failed"
+
+ceilometer-collector:
+    - module: "stevedore.extension"
+      message: ".*"
+    - module: "ceilometer.collector.dispatcher.database"
+      message: "duplicate key value violates unique constraint"
+    - module: "ceilometer.collector.dispatcher.database"
+      message: "Failed to record metering data: QueuePool limit"
+
+q-agt:
+    - module: "neutron.agent.linux.ovs_lib"
+      message: "Unable to execute.*Exception:"
+
+q-dhcp:
+    - module: "neutron.common.legacy"
+      message: "Skipping unknown group key: firewall_driver"
+    - module: "neutron.agent.dhcp_agent"
+      message: "Unable to enable dhcp"
+    - module: "neutron.agent.dhcp_agent"
+      message: "Network .* RPC info call failed"
+
+q-l3:
+    - module: "neutron.common.legacy"
+      message: "Skipping unknown group key: firewall_driver"
+    - module: "neutron.agent.l3_agent"
+      message: "Failed synchronizing routers"
+
+q-vpn:
+    - module: "neutron.common.legacy"
+      message: "Skipping unknown group key: firewall_driver"
+
+q-lbaas:
+    - module: "neutron.common.legacy"
+      message: "Skipping unknown group key: firewall_driver"
+    - module: "neutron.services.loadbalancer.drivers.haproxy.agent_manager"
+      message: "Error upating stats"
+    - module: "neutron.services.loadbalancer.drivers.haproxy.agent_manager"
+      message: "Unable to destroy device for pool"
+
+q-svc:
+    - module: "neutron.common.legacy"
+      message: "Skipping unknown group key: firewall_driver"
+    - module: "neutron.openstack.common.rpc.amqp"
+      message: "Exception during message handling"
+    - module: "neutron.openstack.common.rpc.common"
+      message: "(Network|Pool|Subnet|Agent|Port) .* could not be found"
+    - module: "neutron.api.v2.resource"
+      message: ".* failed"
+
diff --git a/requirements.txt b/requirements.txt
index 3b9ec44..4f6a1d3 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -5,20 +5,20 @@
 jsonschema>=1.3.0,!=1.4.0
 testtools>=0.9.32
 lxml>=2.3
-boto>=2.4.0
+boto>=2.4.0,!=2.13.0
 paramiko>=1.8.0
 netaddr
 python-glanceclient>=0.9.0
-python-keystoneclient>=0.3.0
-python-novaclient>=2.12.0
-python-neutronclient>=2.2.3,<3
-python-cinderclient>=1.0.4
+python-keystoneclient>=0.4.1
+python-novaclient>=2.15.0
+python-neutronclient>=2.3.0,<3
+python-cinderclient>=1.0.6
 python-heatclient>=0.2.3
 testresources>=0.2.4
-keyring>=1.6.1
+keyring>=1.6.1,<2.0
 testrepository>=0.0.17
 oslo.config>=1.2.0
 eventlet>=0.13.0
-six<1.4.0
+six>=1.4.1
 iso8601>=0.1.4
 fixtures>=0.3.14
diff --git a/run_tests.sh b/run_tests.sh
index acd9497..5c8ce7d 100755
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -63,7 +63,7 @@
     -l|--logging) logging=1;;
     -L|--logging-config) logging_config=$2; shift;;
     --) [ "yes" == "$first_uu" ] || testrargs="$testrargs $1"; first_uu=no  ;;
-    *) testrargs="$testrargs $1"
+    *) testrargs="$testrargs $1"; noseargs+=" $1" ;;
   esac
   shift
 done
@@ -107,12 +107,13 @@
 }
 
 function run_tests_nose {
-    NOSE_WITH_OPENSTACK=1
-    NOSE_OPENSTACK_COLOR=1
-    NOSE_OPENSTACK_RED=15.00
-    NOSE_OPENSTACK_YELLOW=3.00
-    NOSE_OPENSTACK_SHOW_ELAPSED=1
-    NOSE_OPENSTACK_STDOUT=1
+    export NOSE_WITH_OPENSTACK=1
+    export NOSE_OPENSTACK_COLOR=1
+    export NOSE_OPENSTACK_RED=15.00
+    export NOSE_OPENSTACK_YELLOW=3.00
+    export NOSE_OPENSTACK_SHOW_ELAPSED=1
+    export NOSE_OPENSTACK_STDOUT=1
+    export TEMPEST_PY26_NOSE_COMPAT=1
     if [[ "x$noseargs" =~ "tempest" ]]; then
         noseargs="$testrargs"
     else
diff --git a/setup.cfg b/setup.cfg
index a4cf118..23a97ff 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,6 +1,6 @@
 [metadata]
 name = tempest
-version = 2013.2
+version = 2014.1
 summary = OpenStack Integration Testing
 description-file =
     README.rst
@@ -17,20 +17,7 @@
     Programming Language :: Python :: 2
     Programming Language :: Python :: 2.7
 
-[global]
-setup-hooks =
-    pbr.hooks.setup_hook
-
 [build_sphinx]
 all_files = 1
 build-dir = doc/build
 source-dir = doc/source
-
-[nosetests]
-# NOTE(jkoelker) To run the test suite under nose install the following
-#                coverage http://pypi.python.org/pypi/coverage
-#                openstack-nose https://github.com/openstack-dev/openstack-nose
-verbosity=2
-
-[pbr]
-autodoc_tree_index_modules=true
diff --git a/setup.py b/setup.py
index 59a0090..70c2b3f 100755
--- a/setup.py
+++ b/setup.py
@@ -14,8 +14,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT
 import setuptools
 
 setuptools.setup(
-    setup_requires=['d2to1', 'pbr'],
-    d2to1=True)
+    setup_requires=['pbr'],
+    pbr=True)
diff --git a/tempest/api/compute/admin/test_aggregates.py b/tempest/api/compute/admin/test_aggregates.py
index 14ab236..e8acec5 100644
--- a/tempest/api/compute/admin/test_aggregates.py
+++ b/tempest/api/compute/admin/test_aggregates.py
@@ -22,7 +22,7 @@
 from tempest.test import attr
 
 
-class AggregatesAdminTestJSON(base.BaseComputeAdminTest):
+class AggregatesAdminTestJSON(base.BaseV2ComputeAdminTest):
 
     """
     Tests Aggregates API that require admin privileges
diff --git a/tempest/api/compute/admin/test_availability_zone.py b/tempest/api/compute/admin/test_availability_zone.py
index d1e1be6..d6488c4 100644
--- a/tempest/api/compute/admin/test_availability_zone.py
+++ b/tempest/api/compute/admin/test_availability_zone.py
@@ -20,7 +20,7 @@
 from tempest.test import attr
 
 
-class AvailabilityZoneAdminTestJSON(base.BaseComputeAdminTest):
+class AvailabilityZoneAdminTestJSON(base.BaseV2ComputeAdminTest):
 
     """
     Tests Availability Zone API List that require admin privileges
diff --git a/tempest/api/compute/admin/test_fixed_ips.py b/tempest/api/compute/admin/test_fixed_ips.py
index 85b03e6..766589e 100644
--- a/tempest/api/compute/admin/test_fixed_ips.py
+++ b/tempest/api/compute/admin/test_fixed_ips.py
@@ -16,16 +16,13 @@
 #    under the License.
 
 from tempest.api.compute import base
-from tempest import config
 from tempest import exceptions
 from tempest.test import attr
 
 
-class FixedIPsTestJson(base.BaseComputeAdminTest):
+class FixedIPsTestJson(base.BaseV2ComputeAdminTest):
     _interface = 'json'
 
-    CONF = config.TempestConfig()
-
     @classmethod
     def setUpClass(cls):
         super(FixedIPsTestJson, cls).setUpClass()
diff --git a/tempest/api/compute/admin/test_flavors.py b/tempest/api/compute/admin/test_flavors.py
index 3ef75ba..75b8dad 100644
--- a/tempest/api/compute/admin/test_flavors.py
+++ b/tempest/api/compute/admin/test_flavors.py
@@ -15,17 +15,16 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import testtools
-
 from tempest.api import compute
 from tempest.api.compute import base
 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.test import skip_because
 
 
-class FlavorsAdminTestJSON(base.BaseComputeAdminTest):
+class FlavorsAdminTestJSON(base.BaseV2ComputeAdminTest):
 
     """
     Tests Flavors API Create and Delete that require admin privileges
@@ -195,7 +194,7 @@
                 flag = True
         self.assertTrue(flag)
 
-    @testtools.skip("Skipped until the Bug #1209101 is resolved")
+    @skip_because(bug="1209101")
     @attr(type='gate')
     def test_list_non_public_flavor(self):
         # Create a flavor with os-flavor-access:is_public false should
diff --git a/tempest/api/compute/admin/test_flavors_access.py b/tempest/api/compute/admin/test_flavors_access.py
index 107b23d..e8ae3b4 100644
--- a/tempest/api/compute/admin/test_flavors_access.py
+++ b/tempest/api/compute/admin/test_flavors_access.py
@@ -15,6 +15,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import uuid
+
 from tempest.api import compute
 from tempest.api.compute import base
 from tempest.common.utils.data_utils import rand_int_id
@@ -23,7 +25,7 @@
 from tempest.test import attr
 
 
-class FlavorsAccessTestJSON(base.BaseComputeAdminTest):
+class FlavorsAccessTestJSON(base.BaseV2ComputeAdminTest):
 
     """
     Tests Flavor Access API extension.
@@ -123,6 +125,48 @@
                           new_flavor['id'],
                           self.tenant_id)
 
+    @attr(type=['negative', 'gate'])
+    def test_add_flavor_access_duplicate(self):
+        # Create a new flavor.
+        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)
+
+        # An exception should be raised when adding flavor access to the same
+        # tenant
+        self.assertRaises(exceptions.Conflict,
+                          self.client.add_flavor_access,
+                          new_flavor['id'],
+                          self.tenant_id)
+
+    @attr(type=['negative', 'gate'])
+    def test_remove_flavor_access_not_found(self):
+        # Create a new flavor.
+        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'])
+
+        # An exception should be raised when flavor access is not found
+        self.assertRaises(exceptions.NotFound,
+                          self.client.remove_flavor_access,
+                          new_flavor['id'],
+                          str(uuid.uuid4()))
+
 
 class FlavorsAdminTestXML(FlavorsAccessTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/admin/test_flavors_extra_specs.py b/tempest/api/compute/admin/test_flavors_extra_specs.py
index ce326a3..0fd4d11 100644
--- a/tempest/api/compute/admin/test_flavors_extra_specs.py
+++ b/tempest/api/compute/admin/test_flavors_extra_specs.py
@@ -23,7 +23,7 @@
 from tempest.test import attr
 
 
-class FlavorsExtraSpecsTestJSON(base.BaseComputeAdminTest):
+class FlavorsExtraSpecsTestJSON(base.BaseV2ComputeAdminTest):
 
     """
     Tests Flavor Extra Spec API extension.
@@ -79,6 +79,12 @@
             self.client.get_flavor_extra_spec(self.flavor['id'])
         self.assertEqual(get_resp.status, 200)
         self.assertEqual(get_body, specs)
+        # GET a key value and verify
+        get_resp, get_body = \
+            self.client.get_flavor_extra_spec_with_key(self.flavor['id'],
+                                                       "key2")
+        self.assertEqual(get_resp.status, 200)
+        self.assertEqual(get_body, specs['key2'])
         # UNSET extra specs that were set in this test
         unset_resp, _ = \
             self.client.unset_flavor_extra_spec(self.flavor['id'], "key1")
@@ -115,6 +121,14 @@
                           self.flavor['id'],
                           'key1')
 
+    @attr(type=['negative', 'gate'])
+    def test_flavor_unset_nonexistent_key(self):
+        nonexistent_key = rand_name('flavor_key')
+        self.assertRaises(exceptions.NotFound,
+                          self.client.unset_flavor_extra_spec,
+                          self.flavor['id'],
+                          nonexistent_key)
+
 
 class FlavorsExtraSpecsTestXML(FlavorsExtraSpecsTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/admin/test_hosts.py b/tempest/api/compute/admin/test_hosts.py
index c2ebb29..8e451a0 100644
--- a/tempest/api/compute/admin/test_hosts.py
+++ b/tempest/api/compute/admin/test_hosts.py
@@ -19,7 +19,7 @@
 from tempest.test import attr
 
 
-class HostsAdminTestJSON(base.BaseComputeAdminTest):
+class HostsAdminTestJSON(base.BaseV2ComputeAdminTest):
 
     """
     Tests hosts API using admin privileges.
diff --git a/tempest/api/compute/admin/test_hypervisor.py b/tempest/api/compute/admin/test_hypervisor.py
index 5ca16f4..ef4f51f 100644
--- a/tempest/api/compute/admin/test_hypervisor.py
+++ b/tempest/api/compute/admin/test_hypervisor.py
@@ -16,11 +16,10 @@
 #    under the License.
 
 from tempest.api.compute import base
-from tempest import exceptions
 from tempest.test import attr
 
 
-class HypervisorAdminTestJSON(base.BaseComputeAdminTest):
+class HypervisorAdminTestJSON(base.BaseV2ComputeAdminTest):
 
     """
     Tests Hypervisors API that require admin privileges
@@ -32,7 +31,6 @@
     def setUpClass(cls):
         super(HypervisorAdminTestJSON, cls).setUpClass()
         cls.client = cls.os_adm.hypervisor_client
-        cls.non_adm_client = cls.hypervisor_client
 
     def _list_hypervisors(self):
         # List of hypervisors
@@ -93,19 +91,14 @@
         self.assertEqual(200, resp.status)
         self.assertTrue(len(uptime) > 0)
 
-    @attr(type=['negative', 'gate'])
-    def test_get_hypervisor_list_with_non_admin_user(self):
-        # List of hypervisor and available services with non admin user
-        self.assertRaises(
-            exceptions.Unauthorized,
-            self.non_adm_client.get_hypervisor_list)
-
-    @attr(type=['negative', 'gate'])
-    def test_get_hypervisor_list_details_with_non_admin_user(self):
-        # List of hypervisor details and available services with non admin user
-        self.assertRaises(
-            exceptions.Unauthorized,
-            self.non_adm_client.get_hypervisor_list_details)
+    @attr(type='gate')
+    def test_search_hypervisor(self):
+        hypers = self._list_hypervisors()
+        self.assertTrue(len(hypers) > 0)
+        resp, hypers = self.client.search_hypervisor(
+            hypers[0]['hypervisor_hostname'])
+        self.assertEqual(200, resp.status)
+        self.assertTrue(len(hypers) > 0)
 
 
 class HypervisorAdminTestXML(HypervisorAdminTestJSON):
diff --git a/tempest/api/compute/admin/test_hypervisor_negative.py b/tempest/api/compute/admin/test_hypervisor_negative.py
new file mode 100644
index 0000000..c6455b5
--- /dev/null
+++ b/tempest/api/compute/admin/test_hypervisor_negative.py
@@ -0,0 +1,144 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 Huawei Technologies Co.,LTD.
+# 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 uuid
+
+from tempest.api.compute import base
+from tempest.common.utils import data_utils
+from tempest import exceptions
+from tempest.test import attr
+
+
+class HypervisorAdminNegativeTestJSON(base.BaseV2ComputeAdminTest):
+
+    """
+    Tests Hypervisors API that require admin privileges
+    """
+
+    _interface = 'json'
+
+    @classmethod
+    def setUpClass(cls):
+        super(HypervisorAdminNegativeTestJSON, cls).setUpClass()
+        cls.client = cls.os_adm.hypervisor_client
+        cls.non_adm_client = cls.hypervisor_client
+
+    def _list_hypervisors(self):
+        # List of hypervisors
+        resp, hypers = self.client.get_hypervisor_list()
+        self.assertEqual(200, resp.status)
+        return hypers
+
+    @attr(type=['negative', 'gate'])
+    def test_show_nonexistent_hypervisor(self):
+        nonexistent_hypervisor_id = str(uuid.uuid4())
+
+        self.assertRaises(
+            exceptions.NotFound,
+            self.client.get_hypervisor_show_details,
+            nonexistent_hypervisor_id)
+
+    @attr(type=['negative', 'gate'])
+    def test_show_hypervisor_with_non_admin_user(self):
+        hypers = self._list_hypervisors()
+        self.assertTrue(len(hypers) > 0)
+
+        self.assertRaises(
+            exceptions.Unauthorized,
+            self.non_adm_client.get_hypervisor_show_details,
+            hypers[0]['id'])
+
+    @attr(type=['negative', 'gate'])
+    def test_show_servers_with_non_admin_user(self):
+        hypers = self._list_hypervisors()
+        self.assertTrue(len(hypers) > 0)
+
+        self.assertRaises(
+            exceptions.Unauthorized,
+            self.non_adm_client.get_hypervisor_servers,
+            hypers[0]['id'])
+
+    @attr(type=['negative', 'gate'])
+    def test_show_servers_with_nonexistent_hypervisor(self):
+        nonexistent_hypervisor_id = str(uuid.uuid4())
+
+        self.assertRaises(
+            exceptions.NotFound,
+            self.client.get_hypervisor_servers,
+            nonexistent_hypervisor_id)
+
+    @attr(type=['negative', 'gate'])
+    def test_get_hypervisor_stats_with_non_admin_user(self):
+        self.assertRaises(
+            exceptions.Unauthorized,
+            self.non_adm_client.get_hypervisor_stats)
+
+    @attr(type=['negative', 'gate'])
+    def test_get_nonexistent_hypervisor_uptime(self):
+        nonexistent_hypervisor_id = str(uuid.uuid4())
+
+        self.assertRaises(
+            exceptions.NotFound,
+            self.client.get_hypervisor_uptime,
+            nonexistent_hypervisor_id)
+
+    @attr(type=['negative', 'gate'])
+    def test_get_hypervisor_uptime_with_non_admin_user(self):
+        hypers = self._list_hypervisors()
+        self.assertTrue(len(hypers) > 0)
+
+        self.assertRaises(
+            exceptions.Unauthorized,
+            self.non_adm_client.get_hypervisor_uptime,
+            hypers[0]['id'])
+
+    @attr(type=['negative', 'gate'])
+    def test_get_hypervisor_list_with_non_admin_user(self):
+        # List of hypervisor and available services with non admin user
+        self.assertRaises(
+            exceptions.Unauthorized,
+            self.non_adm_client.get_hypervisor_list)
+
+    @attr(type=['negative', 'gate'])
+    def test_get_hypervisor_list_details_with_non_admin_user(self):
+        # List of hypervisor details and available services with non admin user
+        self.assertRaises(
+            exceptions.Unauthorized,
+            self.non_adm_client.get_hypervisor_list_details)
+
+    @attr(type=['negative', 'gate'])
+    def test_search_nonexistent_hypervisor(self):
+        nonexistent_hypervisor_name = data_utils.rand_name('test_hypervisor')
+
+        self.assertRaises(
+            exceptions.NotFound,
+            self.client.search_hypervisor,
+            nonexistent_hypervisor_name)
+
+    @attr(type=['negative', 'gate'])
+    def test_search_hypervisor_with_non_admin_user(self):
+        hypers = self._list_hypervisors()
+        self.assertTrue(len(hypers) > 0)
+
+        self.assertRaises(
+            exceptions.Unauthorized,
+            self.non_adm_client.search_hypervisor,
+            hypers[0]['hypervisor_hostname'])
+
+
+class HypervisorAdminNegativeTestXML(HypervisorAdminNegativeTestJSON):
+    _interface = 'xml'
diff --git a/tempest/api/compute/admin/test_quotas.py b/tempest/api/compute/admin/test_quotas.py
index f55f152..6c4d350 100644
--- a/tempest/api/compute/admin/test_quotas.py
+++ b/tempest/api/compute/admin/test_quotas.py
@@ -17,12 +17,15 @@
 
 from tempest.api.compute import base
 from tempest.common.utils.data_utils import rand_name
+from tempest import config
 from tempest import exceptions
 from tempest.test import attr
+from tempest.test import skip_because
 
 
-class QuotasAdminTestJSON(base.BaseComputeAdminTest):
+class QuotasAdminTestJSON(base.BaseV2ComputeAdminTest):
     _interface = 'json'
+    force_tenant_isolation = True
 
     @classmethod
     def setUpClass(cls):
@@ -37,12 +40,8 @@
 
         # NOTE(afazekas): these test cases should always create and use a new
         # tenant most of them should be skipped if we can't do that
-        if cls.config.compute.allow_tenant_isolation:
-            cls.demo_tenant_id = cls.isolated_creds.get_primary_user().get(
-                'tenantId')
-        else:
-            cls.demo_tenant_id = [tnt['id'] for tnt in tenants if tnt['name']
-                                  == cls.config.identity.tenant_name][0]
+        cls.demo_tenant_id = cls.isolated_creds.get_primary_user().get(
+            'tenantId')
 
         cls.default_quota_set = set(('injected_file_content_bytes',
                                      'metadata_items', 'injected_files',
@@ -52,15 +51,6 @@
                                      'instances', 'security_group_rules',
                                      'cores', 'security_groups'))
 
-    @classmethod
-    def tearDownClass(cls):
-        for server in cls.servers:
-            try:
-                cls.servers_client.delete_server(server['id'])
-            except exceptions.NotFound:
-                continue
-        super(QuotasAdminTestJSON, cls).tearDownClass()
-
     @attr(type='smoke')
     def test_get_default_quotas(self):
         # Admin can get the default resource quota set for a tenant
@@ -167,6 +157,8 @@
                         instances=default_instances_quota)
         self.assertRaises(exceptions.OverLimit, self.create_server)
 
+    @skip_because(bug="1186354",
+                  condition=config.TempestConfig().service_available.neutron)
     @attr(type=['negative', 'gate'])
     def test_security_groups_exceed_limit(self):
         # Negative test: Creation Security Groups over limit should FAIL
@@ -189,6 +181,8 @@
                           self.sg_client.create_security_group,
                           "sg-overlimit", "sg-desc")
 
+    @skip_because(bug="1186354",
+                  condition=config.TempestConfig().service_available.neutron)
     @attr(type=['negative', 'gate'])
     def test_security_groups_rules_exceed_limit(self):
         # Negative test: Creation of Security Group Rules should FAIL
diff --git a/tempest/api/compute/admin/test_servers.py b/tempest/api/compute/admin/test_servers.py
index 741efea..ebc661c 100644
--- a/tempest/api/compute/admin/test_servers.py
+++ b/tempest/api/compute/admin/test_servers.py
@@ -19,9 +19,10 @@
 from tempest.common.utils.data_utils import rand_name
 from tempest import exceptions
 from tempest.test import attr
+from tempest.test import skip_because
 
 
-class ServersAdminTestJSON(base.BaseComputeAdminTest):
+class ServersAdminTestJSON(base.BaseV2ComputeAdminTest):
 
     """
     Tests Servers API using admin privileges
@@ -33,10 +34,10 @@
     def setUpClass(cls):
         super(ServersAdminTestJSON, cls).setUpClass()
         cls.client = cls.os_adm.servers_client
+        cls.non_adm_client = cls.servers_client
         cls.flavors_client = cls.os_adm.flavors_client
-
-        cls.admin_client = cls._get_identity_admin_client()
-        tenant = cls.admin_client.get_tenant_by_name(
+        cls.identity_client = cls._get_identity_admin_client()
+        tenant = cls.identity_client.get_tenant_by_name(
             cls.client.tenant_name)
         cls.tenant_id = tenant['id']
 
@@ -79,6 +80,14 @@
         self.assertIn(self.s1_name, servers_name)
         self.assertIn(self.s2_name, servers_name)
 
+    @attr(type='gate')
+    def test_admin_delete_servers_of_others(self):
+        # Administrator can delete servers of others
+        _, server = self.create_server()
+        resp, _ = self.client.delete_server(server['id'])
+        self.assertEqual('204', resp['status'])
+        self.servers_client.wait_for_server_termination(server['id'])
+
     @attr(type=['negative', 'gate'])
     def test_resize_server_using_overlimit_ram(self):
         flavor_name = rand_name("flavor-")
@@ -150,6 +159,25 @@
         self.assertRaises(exceptions.NotFound,
                           self.client.reset_state, '999')
 
+    @attr(type='gate')
+    @skip_because(bug="1240043")
+    def test_get_server_diagnostics_by_admin(self):
+        # Retrieve server diagnostics by admin user
+        resp, diagnostic = self.client.get_server_diagnostics(self.s1_id)
+        self.assertEqual(200, resp.status)
+        basic_attrs = ['rx_packets', 'rx_errors', 'rx_drop',
+                       'tx_packets', 'tx_errors', 'tx_drop',
+                       'read_req', 'write_req', 'cpu', 'memory']
+        for key in basic_attrs:
+            self.assertIn(key, str(diagnostic.keys()))
+
+    @attr(type=['negative', 'gate'])
+    def test_get_server_diagnostics_by_non_admin(self):
+        # Non-admin user can not view server diagnostics according to policy
+        self.assertRaises(exceptions.Unauthorized,
+                          self.non_adm_client.get_server_diagnostics,
+                          self.s1_id)
+
 
 class ServersAdminTestXML(ServersAdminTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/admin/test_services.py b/tempest/api/compute/admin/test_services.py
index 434ea2f..327d8b8 100644
--- a/tempest/api/compute/admin/test_services.py
+++ b/tempest/api/compute/admin/test_services.py
@@ -21,7 +21,7 @@
 from tempest.test import attr
 
 
-class ServicesAdminTestJSON(base.BaseComputeAdminTest):
+class ServicesAdminTestJSON(base.BaseV2ComputeAdminTest):
 
     """
     Tests Services API. List and Enable/Disable require admin privileges.
diff --git a/tempest/api/compute/admin/test_simple_tenant_usage.py b/tempest/api/compute/admin/test_simple_tenant_usage.py
index ce05899..3178ead 100644
--- a/tempest/api/compute/admin/test_simple_tenant_usage.py
+++ b/tempest/api/compute/admin/test_simple_tenant_usage.py
@@ -23,7 +23,7 @@
 import time
 
 
-class TenantUsagesTestJSON(base.BaseComputeAdminTest):
+class TenantUsagesTestJSON(base.BaseV2ComputeAdminTest):
 
     _interface = 'json'
 
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 0b527d9..37573c4 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -34,6 +34,7 @@
     """Base test case class for all Compute API tests."""
 
     conclusion = compute.generic_setup_package()
+    force_tenant_isolation = False
 
     @classmethod
     def setUpClass(cls):
@@ -43,7 +44,8 @@
             raise cls.skipException(skip_msg)
         cls.isolated_creds = isolated_creds.IsolatedCreds(cls.__name__)
 
-        if cls.config.compute.allow_tenant_isolation:
+        if (cls.config.compute.allow_tenant_isolation or
+            cls.force_tenant_isolation is True):
             creds = cls.isolated_creds.get_primary_creds()
             username, tenant_name, password = creds
             os = clients.Manager(username=username,
@@ -54,37 +56,19 @@
             os = clients.Manager(interface=cls._interface)
 
         cls.os = os
-        cls.servers_client = os.servers_client
-        cls.flavors_client = os.flavors_client
-        cls.images_client = os.images_client
-        cls.extensions_client = os.extensions_client
-        cls.floating_ips_client = os.floating_ips_client
-        cls.keypairs_client = os.keypairs_client
-        cls.security_groups_client = os.security_groups_client
-        cls.quotas_client = os.quotas_client
-        cls.limits_client = os.limits_client
-        cls.volumes_extensions_client = os.volumes_extensions_client
-        cls.volumes_client = os.volumes_client
-        cls.interfaces_client = os.interfaces_client
-        cls.fixed_ips_client = os.fixed_ips_client
-        cls.availability_zone_client = os.availability_zone_client
-        cls.aggregates_client = os.aggregates_client
-        cls.services_client = os.services_client
-        cls.hypervisor_client = os.hypervisor_client
+
         cls.build_interval = cls.config.compute.build_interval
         cls.build_timeout = cls.config.compute.build_timeout
         cls.ssh_user = cls.config.compute.ssh_user
-        cls.image_ssh_user = cls.config.compute.image_ssh_user
-        cls.image_ssh_password = cls.config.compute.image_ssh_password
         cls.image_ref = cls.config.compute.image_ref
         cls.image_ref_alt = cls.config.compute.image_ref_alt
         cls.flavor_ref = cls.config.compute.flavor_ref
         cls.flavor_ref_alt = cls.config.compute.flavor_ref_alt
+        cls.image_ssh_user = cls.config.compute.image_ssh_user
+        cls.image_ssh_password = cls.config.compute.image_ssh_password
         cls.servers = []
         cls.images = []
 
-        cls.servers_client_v3_auth = os.servers_client_v3_auth
-
     @classmethod
     def clear_servers(cls):
         for server in cls.servers:
@@ -100,6 +84,19 @@
                 pass
 
     @classmethod
+    def rebuild_server(cls, **kwargs):
+        # Destroy an existing server and creates a new one
+        try:
+            cls.servers_client.delete_server(cls.server_id)
+            cls.servers_client.wait_for_server_termination(cls.server_id)
+        except Exception as exc:
+            LOG.exception(exc)
+            pass
+        resp, server = cls.create_server(wait_until='ACTIVE', **kwargs)
+        cls.server_id = server['id']
+        cls.password = server['adminPass']
+
+    @classmethod
     def clear_images(cls):
         for image_id in cls.images:
             try:
@@ -149,7 +146,7 @@
 
     @classmethod
     def create_image_from_server(cls, server_id, **kwargs):
-        """Wrapper utility that returns a test server."""
+        """Wrapper utility that returns an image created from the server."""
         name = rand_name(cls.__name__ + "-image")
         if 'name' in kwargs:
             name = kwargs.pop('name')
@@ -182,12 +179,37 @@
             time.sleep(self.build_interval)
 
 
-class BaseComputeAdminTest(BaseComputeTest):
-    """Base test case class for all Compute Admin API tests."""
+class BaseV2ComputeTest(BaseComputeTest):
 
     @classmethod
     def setUpClass(cls):
-        super(BaseComputeAdminTest, cls).setUpClass()
+        super(BaseV2ComputeTest, cls).setUpClass()
+        cls.servers_client = cls.os.servers_client
+        cls.flavors_client = cls.os.flavors_client
+        cls.images_client = cls.os.images_client
+        cls.extensions_client = cls.os.extensions_client
+        cls.floating_ips_client = cls.os.floating_ips_client
+        cls.keypairs_client = cls.os.keypairs_client
+        cls.security_groups_client = cls.os.security_groups_client
+        cls.quotas_client = cls.os.quotas_client
+        cls.limits_client = cls.os.limits_client
+        cls.volumes_extensions_client = cls.os.volumes_extensions_client
+        cls.volumes_client = cls.os.volumes_client
+        cls.interfaces_client = cls.os.interfaces_client
+        cls.fixed_ips_client = cls.os.fixed_ips_client
+        cls.availability_zone_client = cls.os.availability_zone_client
+        cls.aggregates_client = cls.os.aggregates_client
+        cls.services_client = cls.os.services_client
+        cls.hypervisor_client = cls.os.hypervisor_client
+        cls.servers_client_v3_auth = cls.os.servers_client_v3_auth
+
+
+class BaseV2ComputeAdminTest(BaseV2ComputeTest):
+    """Base test case class for Compute Admin V2 API tests."""
+
+    @classmethod
+    def setUpClass(cls):
+        super(BaseV2ComputeAdminTest, cls).setUpClass()
         admin_username = cls.config.compute_admin.username
         admin_password = cls.config.compute_admin.password
         admin_tenant = cls.config.compute_admin.tenant_name
@@ -195,7 +217,8 @@
             msg = ("Missing Compute Admin API credentials "
                    "in configuration.")
             raise cls.skipException(msg)
-        if cls.config.compute.allow_tenant_isolation:
+        if (cls.config.compute.allow_tenant_isolation or
+            cls.force_tenant_isolation is True):
             creds = cls.isolated_creds.get_admin_creds()
             admin_username, admin_tenant_name, admin_password = creds
             cls.os_adm = clients.Manager(username=admin_username,
diff --git a/tempest/api/compute/flavors/test_flavors.py b/tempest/api/compute/flavors/test_flavors.py
index cea13a0..eac98ea 100644
--- a/tempest/api/compute/flavors/test_flavors.py
+++ b/tempest/api/compute/flavors/test_flavors.py
@@ -20,7 +20,7 @@
 from tempest.test import attr
 
 
-class FlavorsTestJSON(base.BaseComputeTest):
+class FlavorsTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @classmethod
diff --git a/tempest/api/compute/floating_ips/test_floating_ips_actions.py b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
index b747b46..ff7188b 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
@@ -15,13 +15,15 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import uuid
+
 from tempest.api.compute import base
-from tempest.common.utils.data_utils import rand_name
+from tempest.common.utils import data_utils
 from tempest import exceptions
 from tempest.test import attr
 
 
-class FloatingIPsTestJSON(base.BaseComputeTest):
+class FloatingIPsTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
     server_id = None
     floating_ip = None
@@ -46,7 +48,9 @@
         for i in range(len(body)):
             cls.floating_ip_ids.append(body[i]['id'])
         while True:
-            cls.non_exist_id = rand_name('999')
+            cls.non_exist_id = data_utils.rand_int_id(start=999)
+            if cls.config.service_available.neutron:
+                cls.non_exist_id = str(uuid.uuid4())
             if cls.non_exist_id not in cls.floating_ip_ids:
                 break
 
diff --git a/tempest/api/compute/floating_ips/test_list_floating_ips.py b/tempest/api/compute/floating_ips/test_list_floating_ips.py
index 3c76069..7fec2d1 100644
--- a/tempest/api/compute/floating_ips/test_list_floating_ips.py
+++ b/tempest/api/compute/floating_ips/test_list_floating_ips.py
@@ -15,13 +15,15 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import uuid
+
 from tempest.api.compute import base
-from tempest.common.utils.data_utils import rand_name
+from tempest.common.utils import data_utils
 from tempest import exceptions
 from tempest.test import attr
 
 
-class FloatingIPDetailsTestJSON(base.BaseComputeTest):
+class FloatingIPDetailsTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @classmethod
@@ -87,7 +89,9 @@
             floating_ip_id.append(body[i]['id'])
         # Creating a non-existent floatingIP id
         while True:
-            non_exist_id = rand_name('999')
+            non_exist_id = data_utils.rand_int_id(start=999)
+            if self.config.service_available.neutron:
+                non_exist_id = str(uuid.uuid4())
             if non_exist_id not in floating_ip_id:
                 break
         self.assertRaises(exceptions.NotFound,
diff --git a/tempest/api/compute/images/test_image_metadata.py b/tempest/api/compute/images/test_image_metadata.py
index 8f19514..df857bf 100644
--- a/tempest/api/compute/images/test_image_metadata.py
+++ b/tempest/api/compute/images/test_image_metadata.py
@@ -21,7 +21,7 @@
 from tempest.test import attr
 
 
-class ImagesMetadataTestJSON(base.BaseComputeTest):
+class ImagesMetadataTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @classmethod
diff --git a/tempest/api/compute/images/test_images.py b/tempest/api/compute/images/test_images.py
index 57f26f8..383ea1d 100644
--- a/tempest/api/compute/images/test_images.py
+++ b/tempest/api/compute/images/test_images.py
@@ -23,7 +23,7 @@
 from tempest.test import attr
 
 
-class ImagesTestJSON(base.BaseComputeTest):
+class ImagesTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @classmethod
diff --git a/tempest/api/compute/images/test_images_oneserver.py b/tempest/api/compute/images/test_images_oneserver.py
index 7df9010..bec5ea4 100644
--- a/tempest/api/compute/images/test_images_oneserver.py
+++ b/tempest/api/compute/images/test_images_oneserver.py
@@ -23,10 +23,14 @@
 from tempest.common.utils.data_utils import parse_image_id
 from tempest.common.utils.data_utils import rand_name
 from tempest import exceptions
+from tempest.openstack.common import log as logging
 from tempest.test import attr
+from tempest.test import skip_because
+
+LOG = logging.getLogger(__name__)
 
 
-class ImagesOneServerTestJSON(base.BaseComputeTest):
+class ImagesOneServerTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     def tearDown(self):
@@ -36,6 +40,20 @@
             self.image_ids.remove(image_id)
         super(ImagesOneServerTestJSON, self).tearDown()
 
+    def setUp(self):
+        # NOTE(afazekas): Normally we use the same server with all test cases,
+        # but if it has an issue, we build a new one
+        super(ImagesOneServerTestJSON, self).setUp()
+        # Check if the server is in a clean state after test
+        try:
+            self.servers_client.wait_for_server_status(self.server_id,
+                                                       'ACTIVE')
+        except Exception as exc:
+            LOG.exception(exc)
+            # Rebuild server if cannot reach the ACTIVE state
+            # Usually it means the server had a serius accident
+            self.rebuild_server()
+
     @classmethod
     def setUpClass(cls):
         super(ImagesOneServerTestJSON, cls).setUpClass()
@@ -45,7 +63,8 @@
             raise cls.skipException(skip_msg)
 
         try:
-            resp, cls.server = cls.create_server(wait_until='ACTIVE')
+            resp, server = cls.create_server(wait_until='ACTIVE')
+            cls.server_id = server['id']
         except Exception:
             cls.tearDownClass()
             raise
@@ -64,13 +83,13 @@
                 cls.alt_manager = clients.AltManager()
             cls.alt_client = cls.alt_manager.images_client
 
-    @testtools.skip("Skipped until the Bug #1006725 is resolved.")
+    @skip_because(bug="1006725")
     @attr(type=['negative', 'gate'])
     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')
         self.assertRaises(exceptions.BadRequest,
-                          self.client.create_image, self.server['id'],
+                          self.client.create_image, self.server_id,
                           snapshot_name)
 
     @attr(type=['negative', 'gate'])
@@ -79,7 +98,7 @@
         snapshot_name = rand_name('test-snap-')
         meta = {'': ''}
         self.assertRaises(exceptions.BadRequest, self.client.create_image,
-                          self.server['id'], snapshot_name, meta)
+                          self.server_id, snapshot_name, meta)
 
     @attr(type=['negative', 'gate'])
     def test_create_image_specify_metadata_over_limits(self):
@@ -87,7 +106,7 @@
         snapshot_name = rand_name('test-snap-')
         meta = {'a' * 260: 'b' * 260}
         self.assertRaises(exceptions.BadRequest, self.client.create_image,
-                          self.server['id'], snapshot_name, meta)
+                          self.server_id, snapshot_name, meta)
 
     def _get_default_flavor_disk_size(self, flavor_id):
         resp, flavor = self.flavors_client.get_flavor_details(flavor_id)
@@ -101,7 +120,7 @@
         # Create a new image
         name = rand_name('image')
         meta = {'image_type': 'test'}
-        resp, body = self.client.create_image(self.server['id'], name, meta)
+        resp, body = self.client.create_image(self.server_id, name, meta)
         self.assertEqual(202, resp.status)
         image_id = parse_image_id(resp['location'])
         self.client.wait_for_image_status(image_id, 'ACTIVE')
@@ -132,7 +151,7 @@
 
         # Create first snapshot
         snapshot_name = rand_name('test-snap-')
-        resp, body = self.client.create_image(self.server['id'],
+        resp, body = self.client.create_image(self.server_id,
                                               snapshot_name)
         self.assertEqual(202, resp.status)
         image_id = parse_image_id(resp['location'])
@@ -140,8 +159,8 @@
 
         # Create second snapshot
         alt_snapshot_name = rand_name('test-snap-')
-        self.assertRaises(exceptions.Duplicate, self.client.create_image,
-                          self.server['id'], alt_snapshot_name)
+        self.assertRaises(exceptions.Conflict, self.client.create_image,
+                          self.server_id, alt_snapshot_name)
         self.client.wait_for_image_status(image_id, 'ACTIVE')
 
     @attr(type=['negative', 'gate'])
@@ -150,14 +169,14 @@
 
         snapshot_name = rand_name('a' * 260)
         self.assertRaises(exceptions.BadRequest, self.client.create_image,
-                          self.server['id'], snapshot_name)
+                          self.server_id, snapshot_name)
 
     @attr(type=['negative', 'gate'])
     def test_delete_image_that_is_not_yet_active(self):
         # Return an error while trying to delete an image what is creating
 
         snapshot_name = rand_name('test-snap-')
-        resp, body = self.client.create_image(self.server['id'], snapshot_name)
+        resp, body = self.client.create_image(self.server_id, snapshot_name)
         self.assertEqual(202, resp.status)
         image_id = parse_image_id(resp['location'])
         self.image_ids.append(image_id)
diff --git a/tempest/api/compute/images/test_list_image_filters.py b/tempest/api/compute/images/test_list_image_filters.py
index 8a8d5bd..8d4e47b 100644
--- a/tempest/api/compute/images/test_list_image_filters.py
+++ b/tempest/api/compute/images/test_list_image_filters.py
@@ -25,7 +25,7 @@
 LOG = logging.getLogger(__name__)
 
 
-class ListImageFiltersTestJSON(base.BaseComputeTest):
+class ListImageFiltersTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @classmethod
diff --git a/tempest/api/compute/images/test_list_images.py b/tempest/api/compute/images/test_list_images.py
index 0647f86..a6726b6 100644
--- a/tempest/api/compute/images/test_list_images.py
+++ b/tempest/api/compute/images/test_list_images.py
@@ -19,7 +19,7 @@
 from tempest.test import attr
 
 
-class ListImagesTestJSON(base.BaseComputeTest):
+class ListImagesTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @classmethod
diff --git a/tempest/api/compute/keypairs/test_keypairs.py b/tempest/api/compute/keypairs/test_keypairs.py
index 807315a..d059994 100644
--- a/tempest/api/compute/keypairs/test_keypairs.py
+++ b/tempest/api/compute/keypairs/test_keypairs.py
@@ -21,7 +21,7 @@
 from tempest.test import attr
 
 
-class KeyPairsTestJSON(base.BaseComputeTest):
+class KeyPairsTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @classmethod
@@ -158,7 +158,7 @@
         resp, _ = self.client.create_keypair(k_name)
         self.assertEqual(200, resp.status)
         # Now try the same keyname to create another key
-        self.assertRaises(exceptions.Duplicate, self.client.create_keypair,
+        self.assertRaises(exceptions.Conflict, self.client.create_keypair,
                           k_name)
         resp, _ = self.client.delete_keypair(k_name)
         self.assertEqual(202, resp.status)
diff --git a/tempest/api/compute/limits/test_absolute_limits.py b/tempest/api/compute/limits/test_absolute_limits.py
index d2430df..2809244 100644
--- a/tempest/api/compute/limits/test_absolute_limits.py
+++ b/tempest/api/compute/limits/test_absolute_limits.py
@@ -20,7 +20,7 @@
 from tempest.test import attr
 
 
-class AbsoluteLimitsTestJSON(base.BaseComputeTest):
+class AbsoluteLimitsTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @classmethod
diff --git a/tempest/api/compute/security_groups/test_security_group_rules.py b/tempest/api/compute/security_groups/test_security_group_rules.py
index 61db61d..9dc164d 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules.py
@@ -15,16 +15,15 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import testtools
-
 from tempest.api.compute import base
-from tempest.common.utils.data_utils import rand_name
+from tempest.common.utils import data_utils
 from tempest import config
 from tempest import exceptions
 from tempest.test import attr
+from tempest.test import skip_because
 
 
-class SecurityGroupRulesTestJSON(base.BaseComputeTest):
+class SecurityGroupRulesTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @classmethod
@@ -37,8 +36,8 @@
         # Positive test: Creation of Security Group rule
         # should be successful
         # Creating a Security Group to add rules to it
-        s_name = rand_name('securitygroup-')
-        s_description = rand_name('description-')
+        s_name = data_utils.rand_name('securitygroup-')
+        s_description = data_utils.rand_name('description-')
         resp, securitygroup = \
             self.client.create_security_group(s_name, s_description)
         securitygroup_id = securitygroup['id']
@@ -64,15 +63,15 @@
         secgroup1 = None
         secgroup2 = None
         # Creating a Security Group to add rules to it
-        s_name = rand_name('securitygroup-')
-        s_description = rand_name('description-')
+        s_name = data_utils.rand_name('securitygroup-')
+        s_description = data_utils.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-')
+        s_name2 = data_utils.rand_name('securitygroup-')
+        s_description2 = data_utils.rand_name('description-')
         resp, securitygroup = \
             self.client.create_security_group(s_name2, s_description2)
         secgroup2 = securitygroup['id']
@@ -94,14 +93,14 @@
         self.addCleanup(self.client.delete_security_group_rule, rule['id'])
         self.assertEqual(200, resp.status)
 
-    @testtools.skipIf(config.TempestConfig().service_available.neutron,
-                      "Skipped until the Bug #1182384 is resolved")
+    @skip_because(bug="1182384",
+                  condition=config.TempestConfig().service_available.neutron)
     @attr(type=['negative', 'gate'])
     def test_security_group_rules_create_with_invalid_id(self):
         # Negative test: Creation of Security Group rule should FAIL
         # with invalid Parent group id
         # Adding rules to the invalid Security Group id
-        parent_group_id = rand_name('999')
+        parent_group_id = data_utils.rand_int_id(start=999)
         ip_protocol = 'tcp'
         from_port = 22
         to_port = 22
@@ -114,13 +113,13 @@
         # Negative test: Creation of Security Group rule should FAIL
         # with invalid ip_protocol
         # Creating a Security Group to add rule to it
-        s_name = rand_name('securitygroup-')
-        s_description = rand_name('description-')
+        s_name = data_utils.rand_name('securitygroup-')
+        s_description = data_utils.rand_name('description-')
         resp, securitygroup = self.client.create_security_group(s_name,
                                                                 s_description)
         # Adding rules to the created Security Group
         parent_group_id = securitygroup['id']
-        ip_protocol = rand_name('999')
+        ip_protocol = data_utils.rand_name('999')
         from_port = 22
         to_port = 22
 
@@ -134,14 +133,14 @@
         # Negative test: Creation of Security Group rule should FAIL
         # with invalid from_port
         # Creating a Security Group to add rule to it
-        s_name = rand_name('securitygroup-')
-        s_description = rand_name('description-')
+        s_name = data_utils.rand_name('securitygroup-')
+        s_description = data_utils.rand_name('description-')
         resp, securitygroup = self.client.create_security_group(s_name,
                                                                 s_description)
         # Adding rules to the created Security Group
         parent_group_id = securitygroup['id']
         ip_protocol = 'tcp'
-        from_port = rand_name('999')
+        from_port = data_utils.rand_int_id(start=999, end=65535)
         to_port = 22
         self.addCleanup(self.client.delete_security_group, securitygroup['id'])
         self.assertRaises(exceptions.BadRequest,
@@ -151,17 +150,17 @@
     @attr(type=['negative', 'gate'])
     def test_security_group_rules_create_with_invalid_to_port(self):
         # Negative test: Creation of Security Group rule should FAIL
-        # with invalid from_port
+        # with invalid to_port
         # Creating a Security Group to add rule to it
-        s_name = rand_name('securitygroup-')
-        s_description = rand_name('description-')
+        s_name = data_utils.rand_name('securitygroup-')
+        s_description = data_utils.rand_name('description-')
         resp, securitygroup = self.client.create_security_group(s_name,
                                                                 s_description)
         # Adding rules to the created Security Group
         parent_group_id = securitygroup['id']
         ip_protocol = 'tcp'
         from_port = 22
-        to_port = rand_name('999')
+        to_port = data_utils.rand_int_id(start=65536)
         self.addCleanup(self.client.delete_security_group, securitygroup['id'])
         self.assertRaises(exceptions.BadRequest,
                           self.client.create_security_group_rule,
@@ -172,8 +171,8 @@
         # Negative test: Creation of Security Group rule should FAIL
         # with invalid port range.
         # Creating a Security Group to add rule to it.
-        s_name = rand_name('securitygroup-')
-        s_description = rand_name('description-')
+        s_name = data_utils.rand_name('securitygroup-')
+        s_description = data_utils.rand_name('description-')
         resp, securitygroup = self.client.create_security_group(s_name,
                                                                 s_description)
         # Adding a rule to the created Security Group
@@ -186,23 +185,23 @@
                           self.client.create_security_group_rule,
                           secgroup_id, ip_protocol, from_port, to_port)
 
-    @testtools.skipIf(config.TempestConfig().service_available.neutron,
-                      "Skipped until the Bug #1182384 is resolved")
+    @skip_because(bug="1182384",
+                  condition=config.TempestConfig().service_available.neutron)
     @attr(type=['negative', 'gate'])
     def test_security_group_rules_delete_with_invalid_id(self):
         # Negative test: Deletion of Security Group rule should be FAIL
         # with invalid rule id
         self.assertRaises(exceptions.NotFound,
                           self.client.delete_security_group_rule,
-                          rand_name('999'))
+                          data_utils.rand_int_id(start=999))
 
     @attr(type='gate')
     def test_security_group_rules_list(self):
         # Positive test: Created Security Group rules should be
         # in the list of all rules
         # Creating a Security Group to add rules to it
-        s_name = rand_name('securitygroup-')
-        s_description = rand_name('description-')
+        s_name = data_utils.rand_name('securitygroup-')
+        s_description = data_utils.rand_name('description-')
         resp, securitygroup = \
             self.client.create_security_group(s_name, s_description)
         securitygroup_id = securitygroup['id']
diff --git a/tempest/api/compute/security_groups/test_security_groups.py b/tempest/api/compute/security_groups/test_security_groups.py
index 5cca3b2..6e08700 100644
--- a/tempest/api/compute/security_groups/test_security_groups.py
+++ b/tempest/api/compute/security_groups/test_security_groups.py
@@ -18,13 +18,14 @@
 import testtools
 
 from tempest.api.compute import base
-from tempest.common.utils.data_utils import rand_name
+from tempest.common.utils import data_utils
 from tempest import config
 from tempest import exceptions
 from tempest.test import attr
+from tempest.test import skip_because
 
 
-class SecurityGroupsTestJSON(base.BaseComputeTest):
+class SecurityGroupsTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @classmethod
@@ -42,8 +43,8 @@
         # Create 3 Security Groups
         security_group_list = list()
         for i in range(3):
-            s_name = rand_name('securitygroup-')
-            s_description = rand_name('description-')
+            s_name = data_utils.rand_name('securitygroup-')
+            s_description = data_utils.rand_name('description-')
             resp, securitygroup = \
                 self.client.create_security_group(s_name, s_description)
             self.assertEqual(200, resp.status)
@@ -67,8 +68,8 @@
     @attr(type='gate')
     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-')
+        s_name = data_utils.rand_name('securitygroup-')
+        s_description = data_utils.rand_name('description-')
         resp, securitygroup = \
             self.client.create_security_group(s_name, s_description)
         self.assertIn('id', securitygroup)
@@ -86,8 +87,8 @@
     @attr(type='gate')
     def test_security_group_create_get_delete(self):
         # Security Group should be created, fetched and deleted
-        s_name = rand_name('securitygroup-')
-        s_description = rand_name('description-')
+        s_name = data_utils.rand_name('securitygroup-')
+        s_description = data_utils.rand_name('description-')
         resp, securitygroup = \
             self.client.create_security_group(s_name, s_description)
         self.addCleanup(self._delete_security_group,
@@ -107,8 +108,8 @@
                          "The fetched Security Group is different "
                          "from the created Group")
 
-    @testtools.skipIf(config.TempestConfig().service_available.neutron,
-                      "Skipped until the Bug #1182384 is resolved")
+    @skip_because(bug="1182384",
+                  condition=config.TempestConfig().service_available.neutron)
     @attr(type=['negative', 'gate'])
     def test_security_group_get_nonexistant_group(self):
         # Negative test:Should not be able to GET the details
@@ -119,19 +120,19 @@
             security_group_id.append(body[i]['id'])
         # Creating a non-existent Security Group id
         while True:
-            non_exist_id = rand_name('999')
+            non_exist_id = data_utils.rand_int_id(start=999)
             if non_exist_id not in security_group_id:
                 break
         self.assertRaises(exceptions.NotFound, self.client.get_security_group,
                           non_exist_id)
 
-    @testtools.skipIf(config.TempestConfig().service_available.neutron,
-                      "Skipped until the Bug #1161411 is resolved")
+    @skip_because(bug="1161411",
+                  condition=config.TempestConfig().service_available.neutron)
     @attr(type=['negative', 'gate'])
     def test_security_group_create_with_invalid_group_name(self):
         # Negative test: Security Group should not be created with group name
         # as an empty string/with white spaces/chars more than 255
-        s_description = rand_name('description-')
+        s_description = data_utils.rand_name('description-')
         # Create Security Group with empty string as group name
         self.assertRaises(exceptions.BadRequest,
                           self.client.create_security_group, "", s_description)
@@ -145,13 +146,13 @@
                           self.client.create_security_group, s_name,
                           s_description)
 
-    @testtools.skipIf(config.TempestConfig().service_available.neutron,
-                      "Skipped until the Bug #1161411 is resolved")
+    @skip_because(bug="1161411",
+                  condition=config.TempestConfig().service_available.neutron)
     @attr(type=['negative', 'gate'])
     def test_security_group_create_with_invalid_group_description(self):
         # Negative test:Security Group should not be created with description
         # as an empty string/with white spaces/chars more than 255
-        s_name = rand_name('securitygroup-')
+        s_name = data_utils.rand_name('securitygroup-')
         # Create Security Group with empty string as description
         self.assertRaises(exceptions.BadRequest,
                           self.client.create_security_group, s_name, "")
@@ -170,8 +171,8 @@
     def test_security_group_create_with_duplicate_name(self):
         # Negative test:Security Group with duplicate name should not
         # be created
-        s_name = rand_name('securitygroup-')
-        s_description = rand_name('description-')
+        s_name = data_utils.rand_name('securitygroup-')
+        s_description = data_utils.rand_name('description-')
         resp, security_group =\
             self.client.create_security_group(s_name, s_description)
         self.assertEqual(200, resp.status)
@@ -197,8 +198,8 @@
                           self.client.delete_security_group,
                           default_security_group_id)
 
-    @testtools.skipIf(config.TempestConfig().service_available.neutron,
-                      "Skipped until the Bug #1182384 is resolved")
+    @skip_because(bug="1182384",
+                  condition=config.TempestConfig().service_available.neutron)
     @attr(type=['negative', 'gate'])
     def test_delete_nonexistant_security_group(self):
         # Negative test:Deletion of a non-existent Security Group should Fail
@@ -208,7 +209,7 @@
             security_group_id.append(body[i]['id'])
         # Creating non-existent Security Group
         while True:
-            non_exist_id = rand_name('999')
+            non_exist_id = data_utils.rand_int_id(start=999)
             if non_exist_id not in security_group_id:
                 break
         self.assertRaises(exceptions.NotFound,
@@ -227,19 +228,19 @@
         # and not deleted if the server is active.
         # Create a couple security groups that we will use
         # for the server resource this test creates
-        sg_name = rand_name('sg')
-        sg_desc = rand_name('sg-desc')
+        sg_name = data_utils.rand_name('sg')
+        sg_desc = data_utils.rand_name('sg-desc')
         resp, sg = self.client.create_security_group(sg_name, sg_desc)
         sg_id = sg['id']
 
-        sg2_name = rand_name('sg')
-        sg2_desc = rand_name('sg-desc')
+        sg2_name = data_utils.rand_name('sg')
+        sg2_desc = data_utils.rand_name('sg-desc')
         resp, sg2 = self.client.create_security_group(sg2_name, sg2_desc)
         sg2_id = sg2['id']
 
         # Create server and add the security group created
         # above to the server we just created
-        server_name = rand_name('server')
+        server_name = data_utils.rand_name('server')
         resp, server = self.servers_client.create_server(server_name,
                                                          self.image_ref,
                                                          self.flavor_ref)
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index 9f66a6c..c554dc2 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -19,7 +19,7 @@
 import time
 
 
-class AttachInterfacesTestJSON(base.BaseComputeTest):
+class AttachInterfacesTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @classmethod
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index 31ca387..adbc048 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -28,7 +28,7 @@
 from tempest.test import attr
 
 
-class ServersTestJSON(base.BaseComputeTest):
+class ServersTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
     run_ssh = tempest.config.TempestConfig().compute.run_ssh
     disk_config = 'AUTO'
diff --git a/tempest/api/compute/servers/test_disk_config.py b/tempest/api/compute/servers/test_disk_config.py
index 9abb86a..76a7117 100644
--- a/tempest/api/compute/servers/test_disk_config.py
+++ b/tempest/api/compute/servers/test_disk_config.py
@@ -22,7 +22,7 @@
 from tempest.test import attr
 
 
-class ServerDiskConfigTestJSON(base.BaseComputeTest):
+class ServerDiskConfigTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @classmethod
@@ -38,6 +38,7 @@
         # A server should be rebuilt using the manual disk config option
         resp, server = self.create_server(disk_config='AUTO',
                                           wait_until='ACTIVE')
+        self.addCleanup(self.client.delete_server, server['id'])
 
         # Verify the specified attributes are set correctly
         resp, server = self.client.get_server(server['id'])
@@ -54,14 +55,12 @@
         resp, server = self.client.get_server(server['id'])
         self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
 
-        # Delete the server
-        resp, body = self.client.delete_server(server['id'])
-
     @attr(type='gate')
     def test_rebuild_server_with_auto_disk_config(self):
         # A server should be rebuilt using the auto disk config option
         resp, server = self.create_server(disk_config='MANUAL',
                                           wait_until='ACTIVE')
+        self.addCleanup(self.client.delete_server, server['id'])
 
         # Verify the specified attributes are set correctly
         resp, server = self.client.get_server(server['id'])
@@ -78,16 +77,13 @@
         resp, server = self.client.get_server(server['id'])
         self.assertEqual('AUTO', server['OS-DCF:diskConfig'])
 
-        # Delete the server
-        resp, body = self.client.delete_server(server['id'])
-
     @testtools.skipUnless(compute.RESIZE_AVAILABLE, 'Resize not available.')
     @attr(type='gate')
     def test_resize_server_from_manual_to_auto(self):
         # A server should be resized from manual to auto disk config
         resp, server = self.create_server(disk_config='MANUAL',
                                           wait_until='ACTIVE')
-
+        self.addCleanup(self.client.delete_server, server['id'])
         # Resize with auto option
         self.client.resize(server['id'], self.flavor_ref_alt,
                            disk_config='AUTO')
@@ -98,15 +94,13 @@
         resp, server = self.client.get_server(server['id'])
         self.assertEqual('AUTO', server['OS-DCF:diskConfig'])
 
-        # Delete the server
-        resp, body = self.client.delete_server(server['id'])
-
     @testtools.skipUnless(compute.RESIZE_AVAILABLE, 'Resize not available.')
     @attr(type='gate')
     def test_resize_server_from_auto_to_manual(self):
         # A server should be resized from auto to manual disk config
         resp, server = self.create_server(disk_config='AUTO',
                                           wait_until='ACTIVE')
+        self.addCleanup(self.client.delete_server, server['id'])
 
         # Resize with manual option
         self.client.resize(server['id'], self.flavor_ref_alt,
@@ -118,8 +112,26 @@
         resp, server = self.client.get_server(server['id'])
         self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
 
-        # Delete the server
-        resp, body = self.client.delete_server(server['id'])
+    @attr(type='gate')
+    def test_update_server_from_auto_to_manual(self):
+        # A server should be updated from auto to manual disk config
+        resp, server = self.create_server(disk_config='AUTO',
+                                          wait_until='ACTIVE')
+        self.addCleanup(self.client.delete_server, server['id'])
+
+        # Verify the disk_config attribute is set correctly
+        resp, server = self.client.get_server(server['id'])
+        self.assertEqual('AUTO', server['OS-DCF:diskConfig'])
+
+        # Update the disk_config attribute to manual
+        resp, server = self.client.update_server(server['id'],
+                                                 disk_config='MANUAL')
+        self.assertEqual(200, resp.status)
+        self.client.wait_for_server_status(server['id'], 'ACTIVE')
+
+        # Verify the disk_config attribute is set correctly
+        resp, server = self.client.get_server(server['id'])
+        self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
 
 
 class ServerDiskConfigTestXML(ServerDiskConfigTestJSON):
diff --git a/tempest/api/compute/servers/test_instance_actions.py b/tempest/api/compute/servers/test_instance_actions.py
index f13e51e..61be50a 100644
--- a/tempest/api/compute/servers/test_instance_actions.py
+++ b/tempest/api/compute/servers/test_instance_actions.py
@@ -20,7 +20,7 @@
 from tempest.test import attr
 
 
-class InstanceActionsTestJSON(base.BaseComputeTest):
+class InstanceActionsTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @classmethod
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index a56bdf3..778b8ec 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -15,17 +15,16 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import testtools
-
 from tempest.api.compute import base
 from tempest.api import utils
 from tempest.common.utils.data_utils import rand_name
 from tempest import config
 from tempest import exceptions
 from tempest.test import attr
+from tempest.test import skip_because
 
 
-class ListServerFiltersTestJSON(base.BaseComputeTest):
+class ListServerFiltersTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @classmethod
@@ -58,32 +57,26 @@
             raise RuntimeError("Image %s (image_ref_alt) was not found!" %
                                cls.image_ref_alt)
 
-        cls.s1_name = rand_name('server')
-        resp, cls.s1 = cls.client.create_server(cls.s1_name, cls.image_ref,
-                                                cls.flavor_ref)
-        cls.s2_name = rand_name('server')
-        resp, cls.s2 = cls.client.create_server(cls.s2_name, cls.image_ref_alt,
-                                                cls.flavor_ref)
-        cls.s3_name = rand_name('server')
-        resp, cls.s3 = cls.client.create_server(cls.s3_name, cls.image_ref,
-                                                cls.flavor_ref_alt)
+        cls.s1_name = rand_name(cls.__name__ + '-instance')
+        resp, cls.s1 = cls.create_server(name=cls.s1_name,
+                                         image_id=cls.image_ref,
+                                         flavor=cls.flavor_ref,
+                                         wait_until='ACTIVE')
 
-        cls.client.wait_for_server_status(cls.s1['id'], 'ACTIVE')
-        resp, cls.s1 = cls.client.get_server(cls.s1['id'])
-        cls.client.wait_for_server_status(cls.s2['id'], 'ACTIVE')
-        resp, cls.s2 = cls.client.get_server(cls.s2['id'])
-        cls.client.wait_for_server_status(cls.s3['id'], 'ACTIVE')
-        resp, cls.s3 = cls.client.get_server(cls.s3['id'])
+        cls.s2_name = rand_name(cls.__name__ + '-instance')
+        resp, cls.s2 = cls.create_server(name=cls.s2_name,
+                                         image_id=cls.image_ref_alt,
+                                         flavor=cls.flavor_ref,
+                                         wait_until='ACTIVE')
+
+        cls.s3_name = rand_name(cls.__name__ + '-instance')
+        resp, cls.s3 = cls.create_server(name=cls.s3_name,
+                                         image_id=cls.image_ref,
+                                         flavor=cls.flavor_ref_alt,
+                                         wait_until='ACTIVE')
 
         cls.fixed_network_name = cls.config.compute.fixed_network_name
 
-    @classmethod
-    def tearDownClass(cls):
-        cls.client.delete_server(cls.s1['id'])
-        cls.client.delete_server(cls.s2['id'])
-        cls.client.delete_server(cls.s3['id'])
-        super(ListServerFiltersTestJSON, cls).tearDownClass()
-
     @utils.skip_unless_attr('multiple_images', 'Only one image found')
     @attr(type='gate')
     def test_list_servers_filter_by_image(self):
@@ -185,8 +178,8 @@
 
     @attr(type='gate')
     def test_list_servers_filtered_by_name_wildcard(self):
-        # List all servers that contains 'server' in name
-        params = {'name': 'server'}
+        # List all servers that contains '-instance' in name
+        params = {'name': '-instance'}
         resp, body = self.client.list_servers(params)
         servers = body['servers']
 
@@ -205,11 +198,12 @@
         self.assertNotIn(self.s2_name, map(lambda x: x['name'], servers))
         self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
 
-    @testtools.skip('Skipped until the Bug #1170718 is resolved.')
+    @skip_because(bug="1170718")
     @attr(type='gate')
     def test_list_servers_filtered_by_ip(self):
         # Filter servers by ip
         # Here should be listed 1 server
+        resp, self.s1 = self.client.get_server(self.s1['id'])
         ip = self.s1['addresses'][self.fixed_network_name][0]['addr']
         params = {'ip': ip}
         resp, body = self.client.list_servers(params)
@@ -219,13 +213,14 @@
         self.assertNotIn(self.s2_name, map(lambda x: x['name'], servers))
         self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
 
-    @testtools.skipIf(config.TempestConfig().service_available.neutron,
-                      "Skipped until the Bug #1182883 is resolved")
+    @skip_because(bug="1182883",
+                  condition=config.TempestConfig().service_available.neutron)
     @attr(type='gate')
     def test_list_servers_filtered_by_ip_regex(self):
         # Filter servers by regex ip
         # List all servers filtered by part of ip address.
         # Here should be listed all servers
+        resp, self.s1 = self.client.get_server(self.s1['id'])
         ip = self.s1['addresses'][self.fixed_network_name][0]['addr'][0:-3]
         params = {'ip': ip}
         resp, body = self.client.list_servers(params)
diff --git a/tempest/api/compute/servers/test_list_servers_negative.py b/tempest/api/compute/servers/test_list_servers_negative.py
index 1050054..bef45a7 100644
--- a/tempest/api/compute/servers/test_list_servers_negative.py
+++ b/tempest/api/compute/servers/test_list_servers_negative.py
@@ -24,10 +24,30 @@
 from tempest.test import attr
 
 
-class ListServersNegativeTestJSON(base.BaseComputeTest):
+class ListServersNegativeTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @classmethod
+    def _ensure_no_servers(cls, servers, username, tenant_name):
+        """
+        If there are servers and there is tenant isolation then a
+        skipException is raised to skip the test since it requires no servers
+        to already exist for the given user/tenant.
+        If there are servers and there is not tenant isolation then the test
+        blocks while the servers are being deleted.
+        """
+        if len(servers):
+            if not cls.config.compute.allow_tenant_isolation:
+                for srv in servers:
+                    cls.client.wait_for_server_termination(srv['id'],
+                                                           ignore_error=True)
+            else:
+                msg = ("User/tenant %(u)s/%(t)s already have "
+                       "existing server instances. Skipping test." %
+                       {'u': username, 't': tenant_name})
+                raise cls.skipException(msg)
+
+    @classmethod
     def setUpClass(cls):
         super(ListServersNegativeTestJSON, cls).setUpClass()
         cls.client = cls.servers_client
@@ -54,26 +74,14 @@
         # start of the test instead of destroying any existing
         # servers.
         resp, body = cls.client.list_servers()
-        servers = body['servers']
-        num_servers = len(servers)
-        if num_servers > 0:
-            username = cls.os.username
-            tenant_name = cls.os.tenant_name
-            msg = ("User/tenant %(u)s/%(t)s already have "
-                   "existing server instances. Skipping test." %
-                   {'u': username, 't': tenant_name})
-            raise cls.skipException(msg)
+        cls._ensure_no_servers(body['servers'],
+                               cls.os.username,
+                               cls.os.tenant_name)
 
         resp, body = cls.alt_client.list_servers()
-        servers = body['servers']
-        num_servers = len(servers)
-        if num_servers > 0:
-            username = cls.alt_manager.username
-            tenant_name = cls.alt_manager.tenant_name
-            msg = ("Alt User/tenant %(u)s/%(t)s already have "
-                   "existing server instances. Skipping test." %
-                   {'u': username, 't': tenant_name})
-            raise cls.skipException(msg)
+        cls._ensure_no_servers(body['servers'],
+                               cls.alt_manager.username,
+                               cls.alt_manager.tenant_name)
 
         # The following servers are created for use
         # by the test methods in this class. These
@@ -81,6 +89,7 @@
         # tearDownClass method of the super-class.
         cls.existing_fixtures = []
         cls.deleted_fixtures = []
+        cls.start_time = datetime.datetime.utcnow()
         for x in xrange(2):
             resp, srv = cls.create_server()
             cls.existing_fixtures.append(srv)
@@ -173,8 +182,7 @@
     @attr(type='gate')
     def test_list_servers_by_changes_since(self):
         # Servers are listed by specifying changes-since date
-        since = datetime.datetime.utcnow() - datetime.timedelta(minutes=2)
-        changes_since = {'changes-since': since.isoformat()}
+        changes_since = {'changes-since': self.start_time.isoformat()}
         resp, body = self.client.list_servers(changes_since)
         self.assertEqual('200', resp['status'])
         # changes-since returns all instances, including deleted.
diff --git a/tempest/api/compute/servers/test_multiple_create.py b/tempest/api/compute/servers/test_multiple_create.py
index 7e4a70b..d582894 100644
--- a/tempest/api/compute/servers/test_multiple_create.py
+++ b/tempest/api/compute/servers/test_multiple_create.py
@@ -21,7 +21,7 @@
 from tempest.test import attr
 
 
-class MultipleCreateTestJSON(base.BaseComputeTest):
+class MultipleCreateTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
     _name = 'multiple-create-test'
 
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 0d5a8fa..6f50a02 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -27,9 +27,10 @@
 import tempest.config
 from tempest import exceptions
 from tempest.test import attr
+from tempest.test import skip_because
 
 
-class ServerActionsTestJSON(base.BaseComputeTest):
+class ServerActionsTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
     resize_available = tempest.config.TempestConfig().compute.resize_available
     run_ssh = tempest.config.TempestConfig().compute.run_ssh
@@ -43,13 +44,13 @@
             self.client.wait_for_server_status(self.server_id, 'ACTIVE')
         except Exception:
             # Rebuild server if something happened to it during a test
-            self.rebuild_servers()
+            self.rebuild_server()
 
     @classmethod
     def setUpClass(cls):
         super(ServerActionsTestJSON, cls).setUpClass()
         cls.client = cls.servers_client
-        cls.rebuild_servers()
+        cls.rebuild_server()
 
     @testtools.skipUnless(compute.CHANGE_PASSWORD_AVAILABLE,
                           'Change password not available.')
@@ -86,7 +87,7 @@
             new_boot_time = linux_client.get_boot_time()
             self.assertGreater(new_boot_time, boot_time)
 
-    @testtools.skip('Skipped until the Bug #1014647 is resolved.')
+    @skip_because(bug="1014647")
     @attr(type='smoke')
     def test_reboot_server_soft(self):
         # The server should be signaled to reboot gracefully
@@ -117,7 +118,8 @@
         password = 'rebuildPassw0rd'
         resp, rebuilt_server = self.client.rebuild(self.server_id,
                                                    self.image_ref_alt,
-                                                   name=new_name, meta=meta,
+                                                   name=new_name,
+                                                   metadata=meta,
                                                    personality=personality,
                                                    adminPass=password)
 
@@ -195,40 +197,6 @@
                 required time (%s s).' % (self.server_id, self.build_timeout)
                 raise exceptions.TimeoutException(message)
 
-    @attr(type=['negative', 'gate'])
-    def test_resize_server_using_nonexist_flavor(self):
-        flavor_id = -1
-        self.assertRaises(exceptions.BadRequest,
-                          self.client.resize, self.server_id, flavor_id)
-
-    @attr(type=['negative', 'gate'])
-    def test_resize_server_using_null_flavor(self):
-        flavor_id = ""
-        self.assertRaises(exceptions.BadRequest,
-                          self.client.resize, self.server_id, flavor_id)
-
-    @attr(type=['negative', 'gate'])
-    def test_reboot_nonexistent_server_soft(self):
-        # Negative Test: The server reboot on non existent server should return
-        # an error
-        self.assertRaises(exceptions.NotFound, self.client.reboot, 999, 'SOFT')
-
-    @attr(type=['negative', 'gate'])
-    def test_rebuild_nonexistent_server(self):
-        # Negative test: The server rebuild for a non existing server
-        # should not be allowed
-        meta = {'rebuild': 'server'}
-        new_name = rand_name('server')
-        file_contents = 'Test server rebuild.'
-        personality = [{'path': '/etc/rebuild.txt',
-                        'contents': base64.b64encode(file_contents)}]
-        self.assertRaises(exceptions.NotFound,
-                          self.client.rebuild,
-                          999, self.image_ref_alt,
-                          name=new_name, meta=meta,
-                          personality=personality,
-                          adminPass='rebuild')
-
     @attr(type='gate')
     def test_get_console_output(self):
         # Positive test:Should be able to GET the console output
@@ -242,15 +210,7 @@
             self.assertEqual(lines, 10)
         self.wait_for(get_output)
 
-    @attr(type=['negative', 'gate'])
-    def test_get_console_output_invalid_server_id(self):
-        # Negative test: Should not be able to get the console output
-        # for an invalid server_id
-        self.assertRaises(exceptions.NotFound,
-                          self.servers_client.get_console_output,
-                          '!@#$%^&*()', 10)
-
-    @testtools.skip('Skipped until the Bug #1014683 is resolved.')
+    @skip_because(bug="1014683")
     @attr(type='gate')
     def test_get_console_output_server_id_in_reboot_status(self):
         # Positive test:Should be able to GET the console output
@@ -283,14 +243,6 @@
         self.assertEqual(202, resp.status)
         self.client.wait_for_server_status(self.server_id, 'ACTIVE')
 
-    @classmethod
-    def rebuild_servers(cls):
-        # Destroy any existing server and creates a new one
-        cls.clear_servers()
-        resp, server = cls.create_server(wait_until='ACTIVE')
-        cls.server_id = server['id']
-        cls.password = server['adminPass']
-
     @attr(type='gate')
     def test_stop_start_server(self):
         resp, server = self.servers_client.stop(self.server_id)
@@ -300,6 +252,7 @@
         self.assertEqual(202, resp.status)
         self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
 
+    @skip_because(bug="1233026")
     @attr(type='gate')
     def test_lock_unlock_server(self):
         # Lock the server,try server stop(exceptions throw),unlock it and retry
diff --git a/tempest/api/compute/servers/test_server_addresses.py b/tempest/api/compute/servers/test_server_addresses.py
index b1b9253..a594f6c 100644
--- a/tempest/api/compute/servers/test_server_addresses.py
+++ b/tempest/api/compute/servers/test_server_addresses.py
@@ -20,7 +20,7 @@
 from tempest.test import attr
 
 
-class ServerAddressesTest(base.BaseComputeTest):
+class ServerAddressesTest(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @classmethod
diff --git a/tempest/api/compute/servers/test_server_metadata.py b/tempest/api/compute/servers/test_server_metadata.py
index 5ea3cbf..4e45e4b 100644
--- a/tempest/api/compute/servers/test_server_metadata.py
+++ b/tempest/api/compute/servers/test_server_metadata.py
@@ -20,7 +20,7 @@
 from tempest.test import attr
 
 
-class ServerMetadataTestJSON(base.BaseComputeTest):
+class ServerMetadataTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @classmethod
@@ -81,14 +81,6 @@
 
         # no teardown - all creates should fail
 
-    @attr(type=['negative', 'gate'])
-    def test_create_metadata_key_error(self):
-        # Blank key should trigger an error.
-        meta = {'': 'data1'}
-        self.assertRaises(exceptions.BadRequest,
-                          self.create_server,
-                          meta=meta)
-
     @attr(type='gate')
     def test_update_server_metadata(self):
         # The server's metadata values should be updated to the
@@ -147,62 +139,48 @@
         self.assertEqual(expected, resp_metadata)
 
     @attr(type=['negative', 'gate'])
-    def test_get_nonexistant_server_metadata_item(self):
-        # Negative test: GET on a non-existent server should not succeed
+    def test_server_metadata_negative(self):
+        # Blank key should trigger an error.
+        meta = {'': 'data1'}
+        self.assertRaises(exceptions.BadRequest,
+                          self.create_server,
+                          meta=meta)
+
+        # GET on a non-existent server should not succeed
         self.assertRaises(exceptions.NotFound,
                           self.client.get_server_metadata_item, 999, 'test2')
 
-    @attr(type=['negative', 'gate'])
-    def test_list_nonexistant_server_metadata(self):
-        # Negative test:List metadata on a non-existent server should
-        # not succeed
+        # List metadata on a non-existent server should not succeed
         self.assertRaises(exceptions.NotFound,
                           self.client.list_server_metadata, 999)
 
-    @attr(type=['negative', 'gate'])
-    def test_set_server_metadata_item_incorrect_uri_key(self):
         # Raise BadRequest if key in uri does not match
         # the key passed in body.
-
         meta = {'testkey': 'testvalue'}
         self.assertRaises(exceptions.BadRequest,
                           self.client.set_server_metadata_item,
                           self.server_id, 'key', meta)
 
-    @attr(type=['negative', 'gate'])
-    def test_set_nonexistant_server_metadata(self):
-        # Negative test: Set metadata on a non-existent server should not
-        # succeed
+        # Set metadata on a non-existent server should not succeed
         meta = {'meta1': 'data1'}
         self.assertRaises(exceptions.NotFound,
                           self.client.set_server_metadata, 999, meta)
 
-    @attr(type=['negative', 'gate'])
-    def test_update_nonexistant_server_metadata(self):
-        # Negative test: An update should not happen for a non-existent image
+        # An update should not happen for a non-existent image
         meta = {'key1': 'value1', 'key2': 'value2'}
         self.assertRaises(exceptions.NotFound,
                           self.client.update_server_metadata, 999, meta)
 
-    @attr(type=['negative', 'gate'])
-    def test_update_metadata_key_error(self):
-        # Blank key should trigger an error.
+        # Blank key should trigger an error
         meta = {'': 'data1'}
         self.assertRaises(exceptions.BadRequest,
                           self.client.update_server_metadata,
                           self.server_id, meta=meta)
 
-    @attr(type=['negative', 'gate'])
-    def test_delete_nonexistant_server_metadata_item(self):
-        # Negative test: Should not be able to delete metadata item from a
-        #  non-existent server
-
-        # Delete the metadata item
+        # Should not be able to delete metadata item from a non-existent server
         self.assertRaises(exceptions.NotFound,
                           self.client.delete_server_metadata_item, 999, 'd')
 
-    @attr(type=['negative', 'gate'])
-    def test_set_server_metadata_too_long(self):
         # Raise a 413 OverLimit exception while exceeding metadata items limit
         # for tenant.
         _, quota_set = self.quotas.get_quota_set(self.tenant_id)
@@ -214,21 +192,12 @@
                           self.client.set_server_metadata,
                           self.server_id, req_metadata)
 
-    @attr(type=['negative', 'gate'])
-    def test_update_server_metadata_too_long(self):
         # Raise a 413 OverLimit exception while exceeding metadata items limit
-        # for tenant.
-        _, quota_set = self.quotas.get_quota_set(self.tenant_id)
-        quota_metadata = quota_set['metadata_items']
-        req_metadata = {}
-        for num in range(1, quota_metadata + 2):
-            req_metadata['key' + str(num)] = 'val' + str(num)
+        # for tenant (update).
         self.assertRaises(exceptions.OverLimit,
                           self.client.update_server_metadata,
                           self.server_id, req_metadata)
 
-    @attr(type=['negative', 'gate'])
-    def test_update_all_metadata_field_error(self):
         # Raise a bad request error for blank key.
         # set_server_metadata will replace all metadata with new value
         meta = {'': 'data1'}
@@ -236,6 +205,13 @@
                           self.client.set_server_metadata,
                           self.server_id, meta=meta)
 
+        # Raise a bad request error for a missing metadata field
+        # set_server_metadata will replace all metadata with new value
+        meta = {'meta1': 'data1'}
+        self.assertRaises(exceptions.BadRequest,
+                          self.client.set_server_metadata,
+                          self.server_id, meta=meta, no_metadata_field=True)
+
 
 class ServerMetadataTestXML(ServerMetadataTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/servers/test_server_personality.py b/tempest/api/compute/servers/test_server_personality.py
index 2019732..ba5c0df 100644
--- a/tempest/api/compute/servers/test_server_personality.py
+++ b/tempest/api/compute/servers/test_server_personality.py
@@ -22,7 +22,7 @@
 from tempest.test import attr
 
 
-class ServerPersonalityTestJSON(base.BaseComputeTest):
+class ServerPersonalityTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @classmethod
diff --git a/tempest/api/compute/servers/test_server_rescue.py b/tempest/api/compute/servers/test_server_rescue.py
index 82559d5..f72d36e 100644
--- a/tempest/api/compute/servers/test_server_rescue.py
+++ b/tempest/api/compute/servers/test_server_rescue.py
@@ -22,7 +22,7 @@
 from tempest.test import attr
 
 
-class ServerRescueTestJSON(base.BaseComputeTest):
+class ServerRescueTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     run_ssh = tempest.config.TempestConfig().compute.run_ssh
@@ -133,13 +133,13 @@
         self.addCleanup(self._unpause, self.server_id)
         self.assertEqual(202, resp.status)
         self.servers_client.wait_for_server_status(self.server_id, 'PAUSED')
-        self.assertRaises(exceptions.Duplicate,
+        self.assertRaises(exceptions.Conflict,
                           self.servers_client.rescue_server,
                           self.server_id)
 
     @attr(type=['negative', 'gate'])
     def test_rescued_vm_reboot(self):
-        self.assertRaises(exceptions.Duplicate, self.servers_client.reboot,
+        self.assertRaises(exceptions.Conflict, self.servers_client.reboot,
                           self.rescue_id, 'HARD')
 
     @attr(type=['negative', 'gate'])
@@ -151,7 +151,7 @@
 
     @attr(type=['negative', 'gate'])
     def test_rescued_vm_rebuild(self):
-        self.assertRaises(exceptions.Duplicate,
+        self.assertRaises(exceptions.Conflict,
                           self.servers_client.rebuild,
                           self.rescue_id,
                           self.image_ref_alt)
@@ -164,7 +164,7 @@
         self.addCleanup(self._unrescue, self.server_id)
 
         # Attach the volume to the server
-        self.assertRaises(exceptions.Duplicate,
+        self.assertRaises(exceptions.Conflict,
                           self.servers_client.attach_volume,
                           self.server_id,
                           self.volume_to_attach['id'],
@@ -188,7 +188,7 @@
         self.addCleanup(self._unrescue, self.server_id)
 
         # Detach the volume from the server expecting failure
-        self.assertRaises(exceptions.Duplicate,
+        self.assertRaises(exceptions.Conflict,
                           self.servers_client.detach_volume,
                           self.server_id,
                           self.volume_to_detach['id'])
diff --git a/tempest/api/compute/servers/test_servers.py b/tempest/api/compute/servers/test_servers.py
index 625964c..5f68201 100644
--- a/tempest/api/compute/servers/test_servers.py
+++ b/tempest/api/compute/servers/test_servers.py
@@ -20,7 +20,7 @@
 from tempest.test import attr
 
 
-class ServersTestJSON(base.BaseComputeTest):
+class ServersTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @classmethod
@@ -112,6 +112,22 @@
         resp, _ = self.client.delete_server(server['id'])
         self.assertEqual('204', resp['status'])
 
+    @attr(type='gate')
+    def test_delete_active_server(self):
+        # Delete a server while it's VM state is Active
+        resp, server = self.create_server(wait_until='ACTIVE')
+        resp, _ = self.client.delete_server(server['id'])
+        self.assertEqual('204', resp['status'])
+
+    @attr(type='gate')
+    def test_create_server_with_ipv6_addr_only(self):
+        # Create a server without an IPv4 address(only IPv6 address).
+        resp, server = self.create_server(accessIPv6='2001:2001::3')
+        self.assertEqual('202', resp['status'])
+        self.client.wait_for_server_status(server['id'], 'ACTIVE')
+        resp, server = self.client.get_server(server['id'])
+        self.assertEqual('2001:2001::3', server['accessIPv6'])
+
 
 class ServersTestXML(ServersTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index e864343..0f753a0 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -15,7 +15,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import base64
 import sys
+import uuid
 
 from tempest.api.compute import base
 from tempest import clients
@@ -24,9 +26,16 @@
 from tempest.test import attr
 
 
-class ServersNegativeTestJSON(base.BaseComputeTest):
+class ServersNegativeTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
+    def setUp(self):
+        super(ServersNegativeTestJSON, self).setUp()
+        try:
+            self.client.wait_for_server_status(self.server_id, 'ACTIVE')
+        except Exception:
+            self.rebuild_server()
+
     @classmethod
     def setUpClass(cls):
         super(ServersNegativeTestJSON, cls).setUpClass()
@@ -34,6 +43,8 @@
         cls.img_client = cls.images_client
         cls.alt_os = clients.AltManager()
         cls.alt_client = cls.alt_os.servers_client
+        resp, server = cls.create_server(wait_until='ACTIVE')
+        cls.server_id = server['id']
 
     @attr(type=['negative', 'gate'])
     def test_server_name_blank(self):
@@ -89,38 +100,65 @@
                           self.create_server, accessIPv6=IPv6)
 
     @attr(type=['negative', 'gate'])
-    def test_reboot_deleted_server(self):
-        # Reboot a deleted server
-        resp, server = self.create_server()
-        self.server_id = server['id']
-        self.client.delete_server(self.server_id)
-        self.client.wait_for_server_termination(self.server_id)
+    def test_resize_server_with_non_existent_flavor(self):
+        # Resize a server with non-existent flavor
+        nonexistent_flavor = str(uuid.uuid4())
+        self.assertRaises(exceptions.BadRequest, self.client.resize,
+                          self.server_id, flavor_ref=nonexistent_flavor)
+
+    @attr(type=['negative', 'gate'])
+    def test_resize_server_with_null_flavor(self):
+        # Resize a server with null flavor
+        self.assertRaises(exceptions.BadRequest, self.client.resize,
+                          self.server_id, flavor_ref="")
+
+    @attr(type=['negative', 'gate'])
+    def test_reboot_non_existent_server(self):
+        # Reboot a non existent server
+        nonexistent_server = str(uuid.uuid4())
         self.assertRaises(exceptions.NotFound, self.client.reboot,
-                          self.server_id, 'SOFT')
+                          nonexistent_server, 'SOFT')
 
     @attr(type=['negative', 'gate'])
     def test_pause_paused_server(self):
         # Pause a paused server.
-        resp, server = self.create_server(wait_until='ACTIVE')
-        self.server_id = server['id']
         self.client.pause_server(self.server_id)
+        self.addCleanup(self.client.unpause_server,
+                        self.server_id)
         self.client.wait_for_server_status(self.server_id, 'PAUSED')
-        self.assertRaises(exceptions.Duplicate,
+        self.assertRaises(exceptions.Conflict,
                           self.client.pause_server,
                           self.server_id)
 
     @attr(type=['negative', 'gate'])
-    def test_rebuild_deleted_server(self):
-        # Rebuild a deleted server
-
-        resp, server = self.create_server()
-        self.server_id = server['id']
-        self.client.delete_server(self.server_id)
-        self.client.wait_for_server_termination(self.server_id)
+    def test_rebuild_reboot_deleted_server(self):
+        # Rebuild and Reboot a deleted server
+        _, server = self.create_server()
+        self.client.delete_server(server['id'])
+        self.client.wait_for_server_termination(server['id'])
 
         self.assertRaises(exceptions.NotFound,
                           self.client.rebuild,
-                          self.server_id, self.image_ref_alt)
+                          server['id'], self.image_ref_alt)
+        self.assertRaises(exceptions.NotFound, self.client.reboot,
+                          server['id'], 'SOFT')
+
+    @attr(type=['negative', 'gate'])
+    def test_rebuild_non_existent_server(self):
+        # Rebuild a non existent server
+        nonexistent_server = str(uuid.uuid4())
+        meta = {'rebuild': 'server'}
+        new_name = rand_name('server')
+        file_contents = 'Test server rebuild.'
+        personality = [{'path': '/etc/rebuild.txt',
+                        'contents': base64.b64encode(file_contents)}]
+        self.assertRaises(exceptions.NotFound,
+                          self.client.rebuild,
+                          nonexistent_server,
+                          self.image_ref_alt,
+                          name=new_name, meta=meta,
+                          personality=personality,
+                          adminPass='rebuild')
 
     @attr(type=['negative', 'gate'])
     def test_create_numeric_server_name(self):
@@ -194,21 +232,19 @@
     def test_update_server_of_another_tenant(self):
         # Update name of a server that belongs to another tenant
 
-        resp, server = self.create_server(wait_until='ACTIVE')
-        new_name = server['id'] + '_new'
+        new_name = self.server_id + '_new'
         self.assertRaises(exceptions.NotFound,
-                          self.alt_client.update_server, server['id'],
+                          self.alt_client.update_server, self.server_id,
                           name=new_name)
 
     @attr(type=['negative', 'gate'])
     def test_update_server_name_length_exceeds_256(self):
         # Update name of server exceed the name length limit
 
-        resp, server = self.create_server(wait_until='ACTIVE')
         new_name = 'a' * 256
         self.assertRaises(exceptions.BadRequest,
                           self.client.update_server,
-                          server['id'],
+                          self.server_id,
                           name=new_name)
 
     @attr(type=['negative', 'gate'])
@@ -221,10 +257,9 @@
     @attr(type=['negative', 'gate'])
     def test_delete_a_server_of_another_tenant(self):
         # Delete a server that belongs to another tenant
-        resp, server = self.create_server(wait_until='ACTIVE')
         self.assertRaises(exceptions.NotFound,
                           self.alt_client.delete_server,
-                          server['id'])
+                          self.server_id)
 
     @attr(type=['negative', 'gate'])
     def test_delete_server_pass_negative_id(self):
@@ -258,16 +293,71 @@
     @attr(type=['negative', 'gate'])
     def test_stop_non_existent_server(self):
         # Stop a non existent server
-        non_exist_id = rand_name('non-existent-server')
+        nonexistent_server = str(uuid.uuid4())
         self.assertRaises(exceptions.NotFound, self.servers_client.stop,
-                          non_exist_id)
+                          nonexistent_server)
 
     @attr(type=['negative', 'gate'])
     def test_pause_non_existent_server(self):
         # pause a non existent server
-        non_exist_id = rand_name('non-existent-server')
+        nonexistent_server = str(uuid.uuid4())
         self.assertRaises(exceptions.NotFound, self.client.pause_server,
-                          non_exist_id)
+                          nonexistent_server)
+
+    @attr(type=['negative', 'gate'])
+    def test_unpause_non_existent_server(self):
+        # unpause a non existent server
+        nonexistent_server = str(uuid.uuid4())
+        self.assertRaises(exceptions.NotFound, self.client.unpause_server,
+                          nonexistent_server)
+
+    @attr(type=['negative', 'gate'])
+    def test_unpause_server_invalid_state(self):
+        # unpause an active server.
+        self.assertRaises(exceptions.Conflict,
+                          self.client.unpause_server,
+                          self.server_id)
+
+    @attr(type=['negative', 'gate'])
+    def test_suspend_non_existent_server(self):
+        # suspend a non existent server
+        nonexistent_server = str(uuid.uuid4())
+        self.assertRaises(exceptions.NotFound, self.client.suspend_server,
+                          nonexistent_server)
+
+    @attr(type=['negative', 'gate'])
+    def test_suspend_server_invalid_state(self):
+        # suspend a suspended server.
+        resp, _ = self.client.suspend_server(self.server_id)
+        self.addCleanup(self.client.resume_server,
+                        self.server_id)
+        self.assertEqual(202, resp.status)
+        self.client.wait_for_server_status(self.server_id, 'SUSPENDED')
+        self.assertRaises(exceptions.Conflict,
+                          self.client.suspend_server,
+                          self.server_id)
+
+    @attr(type=['negative', 'gate'])
+    def test_resume_non_existent_server(self):
+        # resume a non existent server
+        nonexistent_server = str(uuid.uuid4())
+        self.assertRaises(exceptions.NotFound, self.client.resume_server,
+                          nonexistent_server)
+
+    @attr(type=['negative', 'gate'])
+    def test_resume_server_invalid_state(self):
+        # resume an active server.
+        self.assertRaises(exceptions.Conflict,
+                          self.client.resume_server,
+                          self.server_id)
+
+    @attr(type=['negative', 'gate'])
+    def test_get_console_output_of_non_existent_server(self):
+        # get the console output for a non existent server
+        nonexistent_server = str(uuid.uuid4())
+        self.assertRaises(exceptions.NotFound,
+                          self.client.get_console_output,
+                          nonexistent_server, 10)
 
 
 class ServersNegativeTestXML(ServersNegativeTestJSON):
diff --git a/tempest/api/compute/servers/test_virtual_interfaces.py b/tempest/api/compute/servers/test_virtual_interfaces.py
index b743a85..a00e8ed 100644
--- a/tempest/api/compute/servers/test_virtual_interfaces.py
+++ b/tempest/api/compute/servers/test_virtual_interfaces.py
@@ -16,16 +16,16 @@
 #    under the License.
 
 import netaddr
-import testtools
 
 from tempest.api.compute import base
 from tempest.common.utils.data_utils import rand_name
 from tempest import config
 from tempest import exceptions
 from tempest.test import attr
+from tempest.test import skip_because
 
 
-class VirtualInterfacesTestJSON(base.BaseComputeTest):
+class VirtualInterfacesTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     CONF = config.TempestConfig()
@@ -37,8 +37,8 @@
         resp, server = cls.create_server(wait_until='ACTIVE')
         cls.server_id = server['id']
 
-    @testtools.skipIf(CONF.service_available.neutron, "Not implemented by " +
-                      "Neutron. Skipped until the Bug #1183436 is resolved.")
+    @skip_because(bug="1183436",
+                  condition=CONF.service_available.neutron)
     @attr(type='gate')
     def test_list_virtual_interfaces(self):
         # Positive test:Should be able to GET the virtual interfaces list
diff --git a/tempest/api/compute/test_auth_token.py b/tempest/api/compute/test_auth_token.py
index bbe92ef..ffeede8 100644
--- a/tempest/api/compute/test_auth_token.py
+++ b/tempest/api/compute/test_auth_token.py
@@ -19,7 +19,7 @@
 import tempest.config as config
 
 
-class AuthTokenTestJSON(base.BaseComputeTest):
+class AuthTokenTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @classmethod
diff --git a/tempest/api/compute/test_authorization.py b/tempest/api/compute/test_authorization.py
index 0a8595f..a7d9310 100644
--- a/tempest/api/compute/test_authorization.py
+++ b/tempest/api/compute/test_authorization.py
@@ -27,7 +27,7 @@
 LOG = logging.getLogger(__name__)
 
 
-class AuthorizationTestJSON(base.BaseComputeTest):
+class AuthorizationTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @classmethod
diff --git a/tempest/api/compute/test_extensions.py b/tempest/api/compute/test_extensions.py
index c1b7aa5..8f1e446 100644
--- a/tempest/api/compute/test_extensions.py
+++ b/tempest/api/compute/test_extensions.py
@@ -20,7 +20,7 @@
 from tempest.test import attr
 
 
-class ExtensionsTestJSON(base.BaseComputeTest):
+class ExtensionsTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @attr(type='gate')
diff --git a/tempest/api/compute/test_live_block_migration.py b/tempest/api/compute/test_live_block_migration.py
index 65daee0..bb8b372 100644
--- a/tempest/api/compute/test_live_block_migration.py
+++ b/tempest/api/compute/test_live_block_migration.py
@@ -26,7 +26,7 @@
 from tempest.test import attr
 
 
-class LiveBlockMigrationTestJSON(base.BaseComputeAdminTest):
+class LiveBlockMigrationTestJSON(base.BaseV2ComputeAdminTest):
     _host_key = 'OS-EXT-SRV-ATTR:host'
     _interface = 'json'
 
diff --git a/tempest/api/compute/test_quotas.py b/tempest/api/compute/test_quotas.py
index 6453cf4..4617bd2 100644
--- a/tempest/api/compute/test_quotas.py
+++ b/tempest/api/compute/test_quotas.py
@@ -19,7 +19,7 @@
 from tempest.test import attr
 
 
-class QuotasTestJSON(base.BaseComputeTest):
+class QuotasTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @classmethod
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index ee1ad9e..a993077 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -23,7 +23,7 @@
 from tempest.test import attr
 
 
-class AttachVolumeTestJSON(base.BaseComputeTest):
+class AttachVolumeTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
     run_ssh = tempest.config.TempestConfig().compute.run_ssh
 
diff --git a/tempest/api/compute/volumes/test_volumes_get.py b/tempest/api/compute/volumes/test_volumes_get.py
index fba8347..192d81e 100644
--- a/tempest/api/compute/volumes/test_volumes_get.py
+++ b/tempest/api/compute/volumes/test_volumes_get.py
@@ -20,7 +20,7 @@
 from tempest.test import attr
 
 
-class VolumesGetTestJSON(base.BaseComputeTest):
+class VolumesGetTestJSON(base.BaseV2ComputeTest):
 
     _interface = 'json'
 
diff --git a/tempest/api/compute/volumes/test_volumes_list.py b/tempest/api/compute/volumes/test_volumes_list.py
index 956abdf..b4e00f9 100644
--- a/tempest/api/compute/volumes/test_volumes_list.py
+++ b/tempest/api/compute/volumes/test_volumes_list.py
@@ -20,7 +20,7 @@
 from tempest.test import attr
 
 
-class VolumesTestJSON(base.BaseComputeTest):
+class VolumesTestJSON(base.BaseV2ComputeTest):
 
     """
     This test creates a number of 1G volumes. To run successfully,
diff --git a/tempest/api/compute/volumes/test_volumes_negative.py b/tempest/api/compute/volumes/test_volumes_negative.py
index 9ca1380..785902e 100644
--- a/tempest/api/compute/volumes/test_volumes_negative.py
+++ b/tempest/api/compute/volumes/test_volumes_negative.py
@@ -15,13 +15,15 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import uuid
+
 from tempest.api.compute import base
-from tempest.common.utils.data_utils import rand_name
+from tempest.common.utils import data_utils
 from tempest import exceptions
 from tempest.test import attr
 
 
-class VolumesNegativeTest(base.BaseComputeTest):
+class VolumesNegativeTest(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @classmethod
@@ -36,39 +38,23 @@
     def test_volume_get_nonexistant_volume_id(self):
         # Negative: Should not be able to get details of nonexistant volume
         # Creating a nonexistant volume id
-        volume_id_list = list()
-        resp, body = self.client.list_volumes()
-        for i in range(len(body)):
-            volume_id_list.append(body[i]['id'])
-        while True:
-            non_exist_id = rand_name('999')
-            if non_exist_id not in volume_id_list:
-                break
         # Trying to GET a non existant volume
         self.assertRaises(exceptions.NotFound, self.client.get_volume,
-                          non_exist_id)
+                          str(uuid.uuid4()))
 
     @attr(type=['negative', 'gate'])
     def test_volume_delete_nonexistant_volume_id(self):
         # Negative: Should not be able to delete nonexistant Volume
         # Creating nonexistant volume id
-        volume_id_list = list()
-        resp, body = self.client.list_volumes()
-        for i in range(len(body)):
-            volume_id_list.append(body[i]['id'])
-        while True:
-            non_exist_id = rand_name('999')
-            if non_exist_id not in volume_id_list:
-                break
         # Trying to DELETE a non existant volume
         self.assertRaises(exceptions.NotFound, self.client.delete_volume,
-                          non_exist_id)
+                          str(uuid.uuid4()))
 
     @attr(type=['negative', 'gate'])
     def test_create_volume_with_invalid_size(self):
         # Negative: Should not be able to create volume with invalid size
         # in request
-        v_name = rand_name('Volume-')
+        v_name = data_utils.rand_name('Volume-')
         metadata = {'Type': 'work'}
         self.assertRaises(exceptions.BadRequest, self.client.create_volume,
                           size='#$%', display_name=v_name, metadata=metadata)
@@ -77,7 +63,7 @@
     def test_create_volume_with_out_passing_size(self):
         # Negative: Should not be able to create volume without passing size
         # in request
-        v_name = rand_name('Volume-')
+        v_name = data_utils.rand_name('Volume-')
         metadata = {'Type': 'work'}
         self.assertRaises(exceptions.BadRequest, self.client.create_volume,
                           size='', display_name=v_name, metadata=metadata)
@@ -85,7 +71,7 @@
     @attr(type=['negative', 'gate'])
     def test_create_volume_with_size_zero(self):
         # Negative: Should not be able to create volume with size zero
-        v_name = rand_name('Volume-')
+        v_name = data_utils.rand_name('Volume-')
         metadata = {'Type': 'work'}
         self.assertRaises(exceptions.BadRequest, self.client.create_volume,
                           size='0', display_name=v_name, metadata=metadata)
diff --git a/tempest/api/identity/admin/test_roles.py b/tempest/api/identity/admin/test_roles.py
index 690d14f..543cd91 100644
--- a/tempest/api/identity/admin/test_roles.py
+++ b/tempest/api/identity/admin/test_roles.py
@@ -103,7 +103,7 @@
         self.assertIn('status', resp)
         self.assertTrue(resp['status'].startswith('2'))
         self.addCleanup(self.client.delete_role, role1_id)
-        self.assertRaises(exceptions.Duplicate, self.client.create_role,
+        self.assertRaises(exceptions.Conflict, self.client.create_role,
                           role_name)
 
     @attr(type='gate')
@@ -160,7 +160,7 @@
         # Duplicate user role should not get assigned
         (user, tenant, role) = self._get_role_params()
         self.client.assign_user_role(tenant['id'], user['id'], role['id'])
-        self.assertRaises(exceptions.Duplicate, self.client.assign_user_role,
+        self.assertRaises(exceptions.Conflict, self.client.assign_user_role,
                           tenant['id'], user['id'], role['id'])
 
     @attr(type='gate')
diff --git a/tempest/api/identity/admin/test_tenant_negative.py b/tempest/api/identity/admin/test_tenant_negative.py
new file mode 100644
index 0000000..d10080b
--- /dev/null
+++ b/tempest/api/identity/admin/test_tenant_negative.py
@@ -0,0 +1,148 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 Huawei Technologies Co.,LTD.
+# 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 uuid
+
+from tempest.api.identity import base
+from tempest.common.utils import data_utils
+from tempest import exceptions
+from tempest.test import attr
+
+
+class TenantsNegativeTestJSON(base.BaseIdentityAdminTest):
+    _interface = 'json'
+
+    @attr(type=['negative', 'gate'])
+    def test_list_tenants_by_unauthorized_user(self):
+        # Non-administrator user should not be able to list tenants
+        self.assertRaises(exceptions.Unauthorized,
+                          self.non_admin_client.list_tenants)
+
+    @attr(type=['negative', 'gate'])
+    def test_list_tenant_request_without_token(self):
+        # Request to list tenants without a valid token should fail
+        token = self.client.get_auth()
+        self.client.delete_token(token)
+        self.assertRaises(exceptions.Unauthorized, self.client.list_tenants)
+        self.client.clear_auth()
+
+    @attr(type=['negative', 'gate'])
+    def test_tenant_delete_by_unauthorized_user(self):
+        # Non-administrator user should not be able to delete a tenant
+        tenant_name = data_utils.rand_name(name='tenant-')
+        resp, tenant = self.client.create_tenant(tenant_name)
+        self.assertEqual(200, resp.status)
+        self.data.tenants.append(tenant)
+        self.assertRaises(exceptions.Unauthorized,
+                          self.non_admin_client.delete_tenant, tenant['id'])
+
+    @attr(type=['negative', 'gate'])
+    def test_tenant_delete_request_without_token(self):
+        # Request to delete a tenant without a valid token should fail
+        tenant_name = data_utils.rand_name(name='tenant-')
+        resp, tenant = self.client.create_tenant(tenant_name)
+        self.assertEqual(200, resp.status)
+        self.data.tenants.append(tenant)
+        token = self.client.get_auth()
+        self.client.delete_token(token)
+        self.assertRaises(exceptions.Unauthorized, self.client.delete_tenant,
+                          tenant['id'])
+        self.client.clear_auth()
+
+    @attr(type=['negative', 'gate'])
+    def test_delete_non_existent_tenant(self):
+        # Attempt to delete a non existent tenant should fail
+        self.assertRaises(exceptions.NotFound, self.client.delete_tenant,
+                          str(uuid.uuid4().hex))
+
+    @attr(type=['negative', 'gate'])
+    def test_tenant_create_duplicate(self):
+        # Tenant names should be unique
+        tenant_name = data_utils.rand_name(name='tenant-')
+        resp, body = self.client.create_tenant(tenant_name)
+        self.assertEqual(200, resp.status)
+        tenant = body
+        self.data.tenants.append(tenant)
+        tenant1_id = body.get('id')
+
+        self.addCleanup(self.client.delete_tenant, tenant1_id)
+        self.addCleanup(self.data.tenants.remove, tenant)
+        self.assertRaises(exceptions.Conflict, self.client.create_tenant,
+                          tenant_name)
+
+    @attr(type=['negative', 'gate'])
+    def test_create_tenant_by_unauthorized_user(self):
+        # Non-administrator user should not be authorized to create a tenant
+        tenant_name = data_utils.rand_name(name='tenant-')
+        self.assertRaises(exceptions.Unauthorized,
+                          self.non_admin_client.create_tenant, tenant_name)
+
+    @attr(type=['negative', 'gate'])
+    def test_create_tenant_request_without_token(self):
+        # Create tenant request without a token should not be authorized
+        tenant_name = data_utils.rand_name(name='tenant-')
+        token = self.client.get_auth()
+        self.client.delete_token(token)
+        self.assertRaises(exceptions.Unauthorized, self.client.create_tenant,
+                          tenant_name)
+        self.client.clear_auth()
+
+    @attr(type=['negative', 'gate'])
+    def test_create_tenant_with_empty_name(self):
+        # Tenant name should not be empty
+        self.assertRaises(exceptions.BadRequest, self.client.create_tenant,
+                          name='')
+
+    @attr(type=['negative', 'gate'])
+    def test_create_tenants_name_length_over_64(self):
+        # Tenant name length should not be greater than 64 characters
+        tenant_name = 'a' * 65
+        self.assertRaises(exceptions.BadRequest, self.client.create_tenant,
+                          tenant_name)
+
+    @attr(type=['negative', 'gate'])
+    def test_update_non_existent_tenant(self):
+        # Attempt to update a non existent tenant should fail
+        self.assertRaises(exceptions.NotFound, self.client.update_tenant,
+                          str(uuid.uuid4().hex))
+
+    @attr(type=['negative', 'gate'])
+    def test_tenant_update_by_unauthorized_user(self):
+        # Non-administrator user should not be able to update a tenant
+        tenant_name = data_utils.rand_name(name='tenant-')
+        resp, tenant = self.client.create_tenant(tenant_name)
+        self.assertEqual(200, resp.status)
+        self.data.tenants.append(tenant)
+        self.assertRaises(exceptions.Unauthorized,
+                          self.non_admin_client.update_tenant, tenant['id'])
+
+    @attr(type=['negative', 'gate'])
+    def test_tenant_update_request_without_token(self):
+        # Request to update a tenant without a valid token should fail
+        tenant_name = data_utils.rand_name(name='tenant-')
+        resp, tenant = self.client.create_tenant(tenant_name)
+        self.assertEqual(200, resp.status)
+        self.data.tenants.append(tenant)
+        token = self.client.get_auth()
+        self.client.delete_token(token)
+        self.assertRaises(exceptions.Unauthorized, self.client.update_tenant,
+                          tenant['id'])
+        self.client.clear_auth()
+
+
+class TenantsNegativeTestXML(TenantsNegativeTestJSON):
+    _interface = 'xml'
diff --git a/tempest/api/identity/admin/test_tenants.py b/tempest/api/identity/admin/test_tenants.py
index 486b739..e36b543 100644
--- a/tempest/api/identity/admin/test_tenants.py
+++ b/tempest/api/identity/admin/test_tenants.py
@@ -16,8 +16,7 @@
 #    under the License.
 
 from tempest.api.identity import base
-from tempest.common.utils.data_utils import rand_name
-from tempest import exceptions
+from tempest.common.utils import data_utils
 from tempest.test import attr
 
 
@@ -25,25 +24,13 @@
     _interface = 'json'
 
     @attr(type='gate')
-    def test_list_tenants_by_unauthorized_user(self):
-        # Non-administrator user should not be able to list tenants
-        self.assertRaises(exceptions.Unauthorized,
-                          self.non_admin_client.list_tenants)
-
-    @attr(type='gate')
-    def test_list_tenant_request_without_token(self):
-        # Request to list tenants without a valid token should fail
-        token = self.client.get_auth()
-        self.client.delete_token(token)
-        self.assertRaises(exceptions.Unauthorized, self.client.list_tenants)
-        self.client.clear_auth()
-
-    @attr(type='gate')
     def test_tenant_list_delete(self):
         # Create several tenants and delete them
         tenants = []
         for _ in xrange(3):
-            resp, tenant = self.client.create_tenant(rand_name('tenant-new'))
+            tenant_name = data_utils.rand_name(name='tenant-new')
+            resp, tenant = self.client.create_tenant(tenant_name)
+            self.assertEqual(200, resp.status)
             self.data.tenants.append(tenant)
             tenants.append(tenant)
         tenant_ids = map(lambda x: x['id'], tenants)
@@ -62,37 +49,10 @@
         self.assertFalse(any(found), 'Tenants failed to delete')
 
     @attr(type='gate')
-    def test_tenant_delete_by_unauthorized_user(self):
-        # Non-administrator user should not be able to delete a tenant
-        tenant_name = rand_name('tenant-')
-        resp, tenant = self.client.create_tenant(tenant_name)
-        self.data.tenants.append(tenant)
-        self.assertRaises(exceptions.Unauthorized,
-                          self.non_admin_client.delete_tenant, tenant['id'])
-
-    @attr(type='gate')
-    def test_tenant_delete_request_without_token(self):
-        # Request to delete a tenant without a valid token should fail
-        tenant_name = rand_name('tenant-')
-        resp, tenant = self.client.create_tenant(tenant_name)
-        self.data.tenants.append(tenant)
-        token = self.client.get_auth()
-        self.client.delete_token(token)
-        self.assertRaises(exceptions.Unauthorized, self.client.delete_tenant,
-                          tenant['id'])
-        self.client.clear_auth()
-
-    @attr(type='gate')
-    def test_delete_non_existent_tenant(self):
-        # Attempt to delete a non existent tenant should fail
-        self.assertRaises(exceptions.NotFound, self.client.delete_tenant,
-                          'junk_tenant_123456abc')
-
-    @attr(type='gate')
     def test_tenant_create_with_description(self):
         # Create tenant with a description
-        tenant_name = rand_name('tenant-')
-        tenant_desc = rand_name('desc-')
+        tenant_name = data_utils.rand_name(name='tenant-')
+        tenant_desc = data_utils.rand_name(name='desc-')
         resp, body = self.client.create_tenant(tenant_name,
                                                description=tenant_desc)
         tenant = body
@@ -113,7 +73,7 @@
     @attr(type='gate')
     def test_tenant_create_enabled(self):
         # Create a tenant that is enabled
-        tenant_name = rand_name('tenant-')
+        tenant_name = data_utils.rand_name(name='tenant-')
         resp, body = self.client.create_tenant(tenant_name, enabled=True)
         tenant = body
         self.data.tenants.append(tenant)
@@ -131,7 +91,7 @@
     @attr(type='gate')
     def test_tenant_create_not_enabled(self):
         # Create a tenant that is not enabled
-        tenant_name = rand_name('tenant-')
+        tenant_name = data_utils.rand_name(name='tenant-')
         resp, body = self.client.create_tenant(tenant_name, enabled=False)
         tenant = body
         self.data.tenants.append(tenant)
@@ -149,61 +109,18 @@
         self.data.tenants.remove(tenant)
 
     @attr(type='gate')
-    def test_tenant_create_duplicate(self):
-        # Tenant names should be unique
-        tenant_name = rand_name('tenant-dup-')
-        resp, body = self.client.create_tenant(tenant_name)
-        tenant = body
-        self.data.tenants.append(tenant)
-        tenant1_id = body.get('id')
-
-        self.addCleanup(self.client.delete_tenant, tenant1_id)
-        self.addCleanup(self.data.tenants.remove, tenant)
-        self.assertRaises(exceptions.Duplicate, self.client.create_tenant,
-                          tenant_name)
-
-    @attr(type='gate')
-    def test_create_tenant_by_unauthorized_user(self):
-        # Non-administrator user should not be authorized to create a tenant
-        tenant_name = rand_name('tenant-')
-        self.assertRaises(exceptions.Unauthorized,
-                          self.non_admin_client.create_tenant, tenant_name)
-
-    @attr(type='gate')
-    def test_create_tenant_request_without_token(self):
-        # Create tenant request without a token should not be authorized
-        tenant_name = rand_name('tenant-')
-        token = self.client.get_auth()
-        self.client.delete_token(token)
-        self.assertRaises(exceptions.Unauthorized, self.client.create_tenant,
-                          tenant_name)
-        self.client.clear_auth()
-
-    @attr(type='gate')
-    def test_create_tenant_with_empty_name(self):
-        # Tenant name should not be empty
-        self.assertRaises(exceptions.BadRequest, self.client.create_tenant,
-                          name='')
-
-    @attr(type='gate')
-    def test_create_tenants_name_length_over_64(self):
-        # Tenant name length should not be greater than 64 characters
-        tenant_name = 'a' * 65
-        self.assertRaises(exceptions.BadRequest, self.client.create_tenant,
-                          tenant_name)
-
-    @attr(type='gate')
     def test_tenant_update_name(self):
         # Update name attribute of a tenant
-        t_name1 = rand_name('tenant-')
+        t_name1 = data_utils.rand_name(name='tenant-')
         resp, body = self.client.create_tenant(t_name1)
+        self.assertEqual(200, resp.status)
         tenant = body
         self.data.tenants.append(tenant)
 
         t_id = body['id']
         resp1_name = body['name']
 
-        t_name2 = rand_name('tenant2-')
+        t_name2 = data_utils.rand_name(name='tenant2-')
         resp, body = self.client.update_tenant(t_id, name=t_name2)
         st2 = resp['status']
         resp2_name = body['name']
@@ -223,16 +140,17 @@
     @attr(type='gate')
     def test_tenant_update_desc(self):
         # Update description attribute of a tenant
-        t_name = rand_name('tenant-')
-        t_desc = rand_name('desc-')
+        t_name = data_utils.rand_name(name='tenant-')
+        t_desc = data_utils.rand_name(name='desc-')
         resp, body = self.client.create_tenant(t_name, description=t_desc)
+        self.assertEqual(200, resp.status)
         tenant = body
         self.data.tenants.append(tenant)
 
         t_id = body['id']
         resp1_desc = body['description']
 
-        t_desc2 = rand_name('desc2-')
+        t_desc2 = data_utils.rand_name(name='desc2-')
         resp, body = self.client.update_tenant(t_id, description=t_desc2)
         st2 = resp['status']
         resp2_desc = body['description']
@@ -252,9 +170,10 @@
     @attr(type='gate')
     def test_tenant_update_enable(self):
         # Update the enabled attribute of a tenant
-        t_name = rand_name('tenant-')
+        t_name = data_utils.rand_name(name='tenant-')
         t_en = False
         resp, body = self.client.create_tenant(t_name, enabled=t_en)
+        self.assertEqual(200, resp.status)
         tenant = body
         self.data.tenants.append(tenant)
 
diff --git a/tempest/api/identity/admin/test_tokens.py b/tempest/api/identity/admin/test_tokens.py
new file mode 100644
index 0000000..334a5aa
--- /dev/null
+++ b/tempest/api/identity/admin/test_tokens.py
@@ -0,0 +1,58 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 Huawei Technologies Co.,LTD.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import json
+
+from tempest.api.identity import base
+from tempest.common.utils import data_utils
+from tempest.test import attr
+
+
+class TokensTestJSON(base.BaseIdentityAdminTest):
+    _interface = 'json'
+
+    @attr(type='gate')
+    def test_create_delete_token(self):
+        # get a token by username and password
+        user_name = data_utils.rand_name(name='user-')
+        user_password = data_utils.rand_name(name='pass-')
+        # first:create a tenant
+        tenant_name = data_utils.rand_name(name='tenant-')
+        resp, tenant = self.client.create_tenant(tenant_name)
+        self.assertEqual(200, resp.status)
+        self.data.tenants.append(tenant)
+        # second:create a user
+        resp, user = self.client.create_user(user_name, user_password,
+                                             tenant['id'], '')
+        self.assertEqual(200, resp.status)
+        self.data.users.append(user)
+        # then get a token for the user
+        rsp, body = self.token_client.auth(user_name,
+                                           user_password,
+                                           tenant['name'])
+        access_data = json.loads(body)['access']
+        self.assertEqual(rsp['status'], '200')
+        self.assertEqual(access_data['token']['tenant']['name'],
+                         tenant['name'])
+        # then delete the token
+        token_id = access_data['token']['id']
+        resp, body = self.client.delete_token(token_id)
+        self.assertEqual(resp['status'], '204')
+
+
+class TokensTestXML(TokensTestJSON):
+    _interface = 'xml'
diff --git a/tempest/api/identity/admin/test_users.py b/tempest/api/identity/admin/test_users.py
index 689ab29..906fad3 100644
--- a/tempest/api/identity/admin/test_users.py
+++ b/tempest/api/identity/admin/test_users.py
@@ -18,8 +18,7 @@
 from testtools.matchers import Contains
 
 from tempest.api.identity import base
-from tempest.common.utils.data_utils import rand_name
-from tempest import exceptions
+from tempest.common.utils import data_utils
 from tempest.test import attr
 
 
@@ -29,11 +28,11 @@
     @classmethod
     def setUpClass(cls):
         super(UsersTestJSON, cls).setUpClass()
-        cls.alt_user = rand_name('test_user_')
-        cls.alt_password = rand_name('pass_')
+        cls.alt_user = data_utils.rand_name('test_user_')
+        cls.alt_password = data_utils.rand_name('pass_')
         cls.alt_email = cls.alt_user + '@testmail.tm'
-        cls.alt_tenant = rand_name('test_tenant_')
-        cls.alt_description = rand_name('desc_')
+        cls.alt_tenant = data_utils.rand_name('test_tenant_')
+        cls.alt_description = data_utils.rand_name('desc_')
 
     @attr(type='smoke')
     def test_create_user(self):
@@ -46,65 +45,24 @@
         self.assertEqual('200', resp['status'])
         self.assertEqual(self.alt_user, user['name'])
 
-    @attr(type=['negative', 'gate'])
-    def test_create_user_by_unauthorized_user(self):
-        # Non-administrator should not be authorized to create a user
+    @attr(type='smoke')
+    def test_create_user_with_enabled(self):
+        # Create a user with enabled : False
         self.data.setup_test_tenant()
-        self.assertRaises(exceptions.Unauthorized,
-                          self.non_admin_client.create_user, self.alt_user,
-                          self.alt_password, self.data.tenant['id'],
-                          self.alt_email)
-
-    @attr(type=['negative', 'gate'])
-    def test_create_user_with_empty_name(self):
-        # User with an empty name should not be created
-        self.data.setup_test_tenant()
-        self.assertRaises(exceptions.BadRequest, self.client.create_user, '',
-                          self.alt_password, self.data.tenant['id'],
-                          self.alt_email)
-
-    @attr(type=['negative', 'gate'])
-    def test_create_user_with_name_length_over_255(self):
-        # Length of user name filed should be restricted to 255 characters
-        self.data.setup_test_tenant()
-        self.assertRaises(exceptions.BadRequest, self.client.create_user,
-                          'a' * 256, self.alt_password,
-                          self.data.tenant['id'], self.alt_email)
-
-    @attr(type=['negative', 'gate'])
-    def test_create_user_with_duplicate_name(self):
-        # Duplicate user should not be created
-        self.data.setup_test_user()
-        self.assertRaises(exceptions.Duplicate, self.client.create_user,
-                          self.data.test_user, self.data.test_password,
-                          self.data.tenant['id'], self.data.test_email)
-
-    @attr(type=['negative', 'gate'])
-    def test_create_user_for_non_existant_tenant(self):
-        # Attempt to create a user in a non-existent tenant should fail
-        self.assertRaises(exceptions.NotFound, self.client.create_user,
-                          self.alt_user, self.alt_password, '49ffgg99999',
-                          self.alt_email)
-
-    @attr(type=['negative', 'gate'])
-    def test_create_user_request_without_a_token(self):
-        # Request to create a user without a valid token should fail
-        self.data.setup_test_tenant()
-        # Get the token of the current client
-        token = self.client.get_auth()
-        # Delete the token from database
-        self.client.delete_token(token)
-        self.assertRaises(exceptions.Unauthorized, self.client.create_user,
-                          self.alt_user, self.alt_password,
-                          self.data.tenant['id'], self.alt_email)
-
-        # Unset the token to allow further tests to generate a new token
-        self.client.clear_auth()
+        name = data_utils.rand_name('test_user_')
+        resp, user = self.client.create_user(name, self.alt_password,
+                                             self.data.tenant['id'],
+                                             self.alt_email, enabled=False)
+        self.data.users.append(user)
+        self.assertEqual('200', resp['status'])
+        self.assertEqual(name, user['name'])
+        self.assertEqual('false', str(user['enabled']).lower())
+        self.assertEqual(self.alt_email, user['email'])
 
     @attr(type='smoke')
     def test_update_user(self):
         # Test case to check if updating of user attributes is successful.
-        test_user = rand_name('test_user_')
+        test_user = data_utils.rand_name('test_user_')
         self.data.setup_test_tenant()
         resp, user = self.client.create_user(test_user, self.alt_password,
                                              self.data.tenant['id'],
@@ -112,7 +70,7 @@
         # Delete the User at the end of this method
         self.addCleanup(self.client.delete_user, user['id'])
         # Updating user details with new values
-        u_name2 = rand_name('user2-')
+        u_name2 = data_utils.rand_name('user2-')
         u_email2 = u_name2 + '@testmail.tm'
         resp, update_user = self.client.update_user(user['id'], name=u_name2,
                                                     email=u_email2,
@@ -132,7 +90,7 @@
     @attr(type='smoke')
     def test_delete_user(self):
         # Delete a user
-        test_user = rand_name('test_user_')
+        test_user = data_utils.rand_name('test_user_')
         self.data.setup_test_tenant()
         resp, user = self.client.create_user(test_user, self.alt_password,
                                              self.data.tenant['id'],
@@ -141,20 +99,6 @@
         resp, body = self.client.delete_user(user['id'])
         self.assertEqual('204', resp['status'])
 
-    @attr(type=['negative', 'gate'])
-    def test_delete_users_by_unauthorized_user(self):
-        # Non-administrator user should not be authorized to delete a user
-        self.data.setup_test_user()
-        self.assertRaises(exceptions.Unauthorized,
-                          self.non_admin_client.delete_user,
-                          self.data.user['id'])
-
-    @attr(type=['negative', 'gate'])
-    def test_delete_non_existant_user(self):
-        # Attempt to delete a non-existent user should fail
-        self.assertRaises(exceptions.NotFound, self.client.delete_user,
-                          'junk12345123')
-
     @attr(type='smoke')
     def test_user_authentication(self):
         # Valid user's token is authenticated
@@ -168,51 +112,6 @@
                                             self.data.test_tenant)
         self.assertEqual('200', resp['status'])
 
-    @attr(type=['negative', 'gate'])
-    def test_authentication_for_disabled_user(self):
-        # Disabled user's token should not get authenticated
-        self.data.setup_test_user()
-        self.disable_user(self.data.test_user)
-        self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
-                          self.data.test_user,
-                          self.data.test_password,
-                          self.data.test_tenant)
-
-    @attr(type=['negative', 'gate'])
-    def test_authentication_when_tenant_is_disabled(self):
-        # User's token for a disabled tenant should not be authenticated
-        self.data.setup_test_user()
-        self.disable_tenant(self.data.test_tenant)
-        self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
-                          self.data.test_user,
-                          self.data.test_password,
-                          self.data.test_tenant)
-
-    @attr(type=['negative', 'gate'])
-    def test_authentication_with_invalid_tenant(self):
-        # User's token for an invalid tenant should not be authenticated
-        self.data.setup_test_user()
-        self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
-                          self.data.test_user,
-                          self.data.test_password,
-                          'junktenant1234')
-
-    @attr(type=['negative', 'gate'])
-    def test_authentication_with_invalid_username(self):
-        # Non-existent user's token should not get authenticated
-        self.data.setup_test_user()
-        self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
-                          'junkuser123', self.data.test_password,
-                          self.data.test_tenant)
-
-    @attr(type=['negative', 'gate'])
-    def test_authentication_with_invalid_password(self):
-        # User's token with invalid password should not be authenticated
-        self.data.setup_test_user()
-        self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
-                          self.data.test_user, 'junkpass1234',
-                          self.data.test_tenant)
-
     @attr(type='gate')
     def test_authentication_request_without_token(self):
         # Request for token authentication with a valid token in header
@@ -239,28 +138,13 @@
                         Contains(self.data.test_user),
                         "Could not find %s" % self.data.test_user)
 
-    @attr(type=['negative', 'gate'])
-    def test_get_users_by_unauthorized_user(self):
-        # Non-administrator user should not be authorized to get user list
-        self.data.setup_test_user()
-        self.assertRaises(exceptions.Unauthorized,
-                          self.non_admin_client.get_users)
-
-    @attr(type=['negative', 'gate'])
-    def test_get_users_request_without_token(self):
-        # Request to get list of users without a valid token should fail
-        token = self.client.get_auth()
-        self.client.delete_token(token)
-        self.assertRaises(exceptions.Unauthorized, self.client.get_users)
-        self.client.clear_auth()
-
     @attr(type='gate')
     def test_list_users_for_tenant(self):
         # Return a list of all users for a tenant
         self.data.setup_test_tenant()
         user_ids = list()
         fetched_user_ids = list()
-        alt_tenant_user1 = rand_name('tenant_user1_')
+        alt_tenant_user1 = data_utils.rand_name('tenant_user1_')
         resp, user1 = self.client.create_user(alt_tenant_user1, 'password1',
                                               self.data.tenant['id'],
                                               'user1@123')
@@ -268,7 +152,7 @@
         user_ids.append(user1['id'])
         self.data.users.append(user1)
 
-        alt_tenant_user2 = rand_name('tenant_user2_')
+        alt_tenant_user2 = data_utils.rand_name('tenant_user2_')
         resp, user2 = self.client.create_user(alt_tenant_user2, 'password2',
                                               self.data.tenant['id'],
                                               'user2@123')
@@ -303,7 +187,7 @@
                                                   role['id'])
         self.assertEqual('200', resp['status'])
 
-        alt_user2 = rand_name('second_user_')
+        alt_user2 = data_utils.rand_name('second_user_')
         resp, second_user = self.client.create_user(alt_user2, 'password1',
                                                     self.data.tenant['id'],
                                                     'user2@123')
@@ -326,21 +210,6 @@
                          "Failed to find user %s in fetched list" %
                          ', '.join(m_user for m_user in missing_users))
 
-    @attr(type=['negative', 'gate'])
-    def test_list_users_with_invalid_tenant(self):
-        # Should not be able to return a list of all
-        # users for a non-existent tenant
-        # Assign invalid tenant ids
-        invalid_id = list()
-        invalid_id.append(rand_name('999'))
-        invalid_id.append('alpha')
-        invalid_id.append(rand_name("dddd@#%%^$"))
-        invalid_id.append('!@#()$%^&*?<>{}[]')
-        # List the users with invalid tenant id
-        for invalid in invalid_id:
-            self.assertRaises(exceptions.NotFound,
-                              self.client.list_users_for_tenant, invalid)
-
 
 class UsersTestXML(UsersTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/identity/admin/test_users_negative.py b/tempest/api/identity/admin/test_users_negative.py
new file mode 100644
index 0000000..b29d155
--- /dev/null
+++ b/tempest/api/identity/admin/test_users_negative.py
@@ -0,0 +1,236 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012 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.api.identity import base
+from tempest.common.utils.data_utils import rand_name
+from tempest import exceptions
+from tempest.test import attr
+import uuid
+
+
+class UsersNegativeTestJSON(base.BaseIdentityAdminTest):
+    _interface = 'json'
+
+    @classmethod
+    def setUpClass(cls):
+        super(UsersNegativeTestJSON, cls).setUpClass()
+        cls.alt_user = rand_name('test_user_')
+        cls.alt_password = rand_name('pass_')
+        cls.alt_email = cls.alt_user + '@testmail.tm'
+        cls.alt_tenant = rand_name('test_tenant_')
+        cls.alt_description = rand_name('desc_')
+
+    @attr(type=['negative', 'gate'])
+    def test_create_user_by_unauthorized_user(self):
+        # Non-administrator should not be authorized to create a user
+        self.data.setup_test_tenant()
+        self.assertRaises(exceptions.Unauthorized,
+                          self.non_admin_client.create_user, self.alt_user,
+                          self.alt_password, self.data.tenant['id'],
+                          self.alt_email)
+
+    @attr(type=['negative', 'gate'])
+    def test_create_user_with_empty_name(self):
+        # User with an empty name should not be created
+        self.data.setup_test_tenant()
+        self.assertRaises(exceptions.BadRequest, self.client.create_user, '',
+                          self.alt_password, self.data.tenant['id'],
+                          self.alt_email)
+
+    @attr(type=['negative', 'gate'])
+    def test_create_user_with_name_length_over_255(self):
+        # Length of user name filed should be restricted to 255 characters
+        self.data.setup_test_tenant()
+        self.assertRaises(exceptions.BadRequest, self.client.create_user,
+                          'a' * 256, self.alt_password,
+                          self.data.tenant['id'], self.alt_email)
+
+    @attr(type=['negative', 'gate'])
+    def test_create_user_with_duplicate_name(self):
+        # Duplicate user should not be created
+        self.data.setup_test_user()
+        self.assertRaises(exceptions.Conflict, self.client.create_user,
+                          self.data.test_user, self.data.test_password,
+                          self.data.tenant['id'], self.data.test_email)
+
+    @attr(type=['negative', 'gate'])
+    def test_create_user_for_non_existant_tenant(self):
+        # Attempt to create a user in a non-existent tenant should fail
+        self.assertRaises(exceptions.NotFound, self.client.create_user,
+                          self.alt_user, self.alt_password, '49ffgg99999',
+                          self.alt_email)
+
+    @attr(type=['negative', 'gate'])
+    def test_create_user_request_without_a_token(self):
+        # Request to create a user without a valid token should fail
+        self.data.setup_test_tenant()
+        # Get the token of the current client
+        token = self.client.get_auth()
+        # Delete the token from database
+        self.client.delete_token(token)
+        self.assertRaises(exceptions.Unauthorized, self.client.create_user,
+                          self.alt_user, self.alt_password,
+                          self.data.tenant['id'], self.alt_email)
+
+        # Unset the token to allow further tests to generate a new token
+        self.client.clear_auth()
+
+    @attr(type=['negative', 'gate'])
+    def test_create_user_with_enabled_non_bool(self):
+        # Attempt to create a user with valid enabled para should fail
+        self.data.setup_test_tenant()
+        name = rand_name('test_user_')
+        self.assertRaises(exceptions.BadRequest, self.client.create_user,
+                          name, self.alt_password,
+                          self.data.tenant['id'],
+                          self.alt_email, enabled=3)
+
+    @attr(type=['negative', 'gate'])
+    def test_update_user_for_non_existant_user(self):
+        # Attempt to update a user non-existent user should fail
+        user_name = rand_name('user-')
+        non_existent_id = str(uuid.uuid4())
+        self.assertRaises(exceptions.NotFound, self.client.update_user,
+                          non_existent_id, name=user_name)
+
+    @attr(type=['negative', 'gate'])
+    def test_update_user_request_without_a_token(self):
+        # Request to update a user without a valid token should fail
+
+        # Get the token of the current client
+        token = self.client.get_auth()
+        # Delete the token from database
+        self.client.delete_token(token)
+        self.assertRaises(exceptions.Unauthorized, self.client.update_user,
+                          self.alt_user)
+
+        # Unset the token to allow further tests to generate a new token
+        self.client.clear_auth()
+
+    @attr(type=['negative', 'gate'])
+    def test_update_user_by_unauthorized_user(self):
+        # Non-administrator should not be authorized to update user
+        self.data.setup_test_tenant()
+        self.assertRaises(exceptions.Unauthorized,
+                          self.non_admin_client.update_user, self.alt_user)
+
+    @attr(type=['negative', 'gate'])
+    def test_delete_users_by_unauthorized_user(self):
+        # Non-administrator user should not be authorized to delete a user
+        self.data.setup_test_user()
+        self.assertRaises(exceptions.Unauthorized,
+                          self.non_admin_client.delete_user,
+                          self.data.user['id'])
+
+    @attr(type=['negative', 'gate'])
+    def test_delete_non_existant_user(self):
+        # Attempt to delete a non-existent user should fail
+        self.assertRaises(exceptions.NotFound, self.client.delete_user,
+                          'junk12345123')
+
+    @attr(type=['negative', 'gate'])
+    def test_delete_user_request_without_a_token(self):
+        # Request to delete a user without a valid token should fail
+
+        # Get the token of the current client
+        token = self.client.get_auth()
+        # Delete the token from database
+        self.client.delete_token(token)
+        self.assertRaises(exceptions.Unauthorized, self.client.delete_user,
+                          self.alt_user)
+
+        # Unset the token to allow further tests to generate a new token
+        self.client.clear_auth()
+
+    @attr(type=['negative', 'gate'])
+    def test_authentication_for_disabled_user(self):
+        # Disabled user's token should not get authenticated
+        self.data.setup_test_user()
+        self.disable_user(self.data.test_user)
+        self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
+                          self.data.test_user,
+                          self.data.test_password,
+                          self.data.test_tenant)
+
+    @attr(type=['negative', 'gate'])
+    def test_authentication_when_tenant_is_disabled(self):
+        # User's token for a disabled tenant should not be authenticated
+        self.data.setup_test_user()
+        self.disable_tenant(self.data.test_tenant)
+        self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
+                          self.data.test_user,
+                          self.data.test_password,
+                          self.data.test_tenant)
+
+    @attr(type=['negative', 'gate'])
+    def test_authentication_with_invalid_tenant(self):
+        # User's token for an invalid tenant should not be authenticated
+        self.data.setup_test_user()
+        self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
+                          self.data.test_user,
+                          self.data.test_password,
+                          'junktenant1234')
+
+    @attr(type=['negative', 'gate'])
+    def test_authentication_with_invalid_username(self):
+        # Non-existent user's token should not get authenticated
+        self.data.setup_test_user()
+        self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
+                          'junkuser123', self.data.test_password,
+                          self.data.test_tenant)
+
+    @attr(type=['negative', 'gate'])
+    def test_authentication_with_invalid_password(self):
+        # User's token with invalid password should not be authenticated
+        self.data.setup_test_user()
+        self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
+                          self.data.test_user, 'junkpass1234',
+                          self.data.test_tenant)
+
+    @attr(type=['negative', 'gate'])
+    def test_get_users_by_unauthorized_user(self):
+        # Non-administrator user should not be authorized to get user list
+        self.data.setup_test_user()
+        self.assertRaises(exceptions.Unauthorized,
+                          self.non_admin_client.get_users)
+
+    @attr(type=['negative', 'gate'])
+    def test_get_users_request_without_token(self):
+        # Request to get list of users without a valid token should fail
+        token = self.client.get_auth()
+        self.client.delete_token(token)
+        self.assertRaises(exceptions.Unauthorized, self.client.get_users)
+        self.client.clear_auth()
+
+    @attr(type=['negative', 'gate'])
+    def test_list_users_with_invalid_tenant(self):
+        # Should not be able to return a list of all
+        # users for a non-existent tenant
+        # Assign invalid tenant ids
+        invalid_id = list()
+        invalid_id.append(rand_name('999'))
+        invalid_id.append('alpha')
+        invalid_id.append(rand_name("dddd@#%%^$"))
+        invalid_id.append('!@#()$%^&*?<>{}[]')
+        # List the users with invalid tenant id
+        for invalid in invalid_id:
+            self.assertRaises(exceptions.NotFound,
+                              self.client.list_users_for_tenant, invalid)
+
+
+class UsersNegativeTestXML(UsersNegativeTestJSON):
+    _interface = 'xml'
diff --git a/tempest/api/identity/admin/v3/test_projects.py b/tempest/api/identity/admin/v3/test_projects.py
new file mode 100644
index 0000000..ef9814a
--- /dev/null
+++ b/tempest/api/identity/admin/v3/test_projects.py
@@ -0,0 +1,256 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 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.
+
+from tempest.api.identity import base
+from tempest.common.utils.data_utils import rand_name
+from tempest import exceptions
+from tempest.test import attr
+
+
+class ProjectsTestJSON(base.BaseIdentityAdminTest):
+    _interface = 'json'
+
+    def _delete_project(self, project_id):
+        resp, _ = self.v3_client.delete_project(project_id)
+        self.assertEqual(resp['status'], '204')
+        self.assertRaises(
+            exceptions.NotFound, self.v3_client.get_project, project_id)
+
+    @attr(type='gate')
+    def test_project_list_delete(self):
+        # Create several projects and delete them
+        for _ in xrange(3):
+            resp, project = self.v3_client.create_project(
+                rand_name('project-new'))
+            self.addCleanup(self._delete_project, project['id'])
+
+        resp, list_projects = self.v3_client.list_projects()
+        self.assertEqual(resp['status'], '200')
+
+        resp, get_project = self.v3_client.get_project(project['id'])
+        self.assertIn(get_project, list_projects)
+
+    @attr(type='gate')
+    def test_project_create_with_description(self):
+        # Create project with a description
+        project_name = rand_name('project-')
+        project_desc = rand_name('desc-')
+        resp, project = self.v3_client.create_project(
+            project_name, description=project_desc)
+        self.v3data.projects.append(project)
+        st1 = resp['status']
+        project_id = project['id']
+        desc1 = project['description']
+        self.assertEqual(st1, '201')
+        self.assertEqual(desc1, project_desc, 'Description should have '
+                         'been sent in response for create')
+        resp, body = self.v3_client.get_project(project_id)
+        desc2 = body['description']
+        self.assertEqual(desc2, project_desc, 'Description does not appear'
+                         'to be set')
+
+    @attr(type='gate')
+    def test_project_create_enabled(self):
+        # Create a project that is enabled
+        project_name = rand_name('project-')
+        resp, project = self.v3_client.create_project(
+            project_name, enabled=True)
+        self.v3data.projects.append(project)
+        project_id = project['id']
+        st1 = resp['status']
+        en1 = project['enabled']
+        self.assertEqual(st1, '201')
+        self.assertTrue(en1, 'Enable should be True in response')
+        resp, body = self.v3_client.get_project(project_id)
+        en2 = body['enabled']
+        self.assertTrue(en2, 'Enable should be True in lookup')
+
+    @attr(type='gate')
+    def test_project_create_not_enabled(self):
+        # Create a project that is not enabled
+        project_name = rand_name('project-')
+        resp, project = self.v3_client.create_project(
+            project_name, enabled=False)
+        self.v3data.projects.append(project)
+        st1 = resp['status']
+        en1 = project['enabled']
+        self.assertEqual(st1, '201')
+        self.assertEqual('false', str(en1).lower(),
+                         'Enable should be False in response')
+        resp, body = self.v3_client.get_project(project['id'])
+        en2 = body['enabled']
+        self.assertEqual('false', str(en2).lower(),
+                         'Enable should be False in lookup')
+
+    @attr(type='gate')
+    def test_project_update_name(self):
+        # Update name attribute of a project
+        p_name1 = rand_name('project-')
+        resp, project = self.v3_client.create_project(p_name1)
+        self.v3data.projects.append(project)
+
+        resp1_name = project['name']
+
+        p_name2 = rand_name('project2-')
+        resp, body = self.v3_client.update_project(project['id'], name=p_name2)
+        st2 = resp['status']
+        resp2_name = body['name']
+        self.assertEqual(st2, '200')
+        self.assertNotEqual(resp1_name, resp2_name)
+
+        resp, body = self.v3_client.get_project(project['id'])
+        resp3_name = body['name']
+
+        self.assertNotEqual(resp1_name, resp3_name)
+        self.assertEqual(p_name1, resp1_name)
+        self.assertEqual(resp2_name, resp3_name)
+
+    @attr(type='gate')
+    def test_project_update_desc(self):
+        # Update description attribute of a project
+        p_name = rand_name('project-')
+        p_desc = rand_name('desc-')
+        resp, project = self.v3_client.create_project(
+            p_name, description=p_desc)
+        self.v3data.projects.append(project)
+        resp1_desc = project['description']
+
+        p_desc2 = rand_name('desc2-')
+        resp, body = self.v3_client.update_project(
+            project['id'], description=p_desc2)
+        st2 = resp['status']
+        resp2_desc = body['description']
+        self.assertEqual(st2, '200')
+        self.assertNotEqual(resp1_desc, resp2_desc)
+
+        resp, body = self.v3_client.get_project(project['id'])
+        resp3_desc = body['description']
+
+        self.assertNotEqual(resp1_desc, resp3_desc)
+        self.assertEqual(p_desc, resp1_desc)
+        self.assertEqual(resp2_desc, resp3_desc)
+
+    @attr(type='gate')
+    def test_project_update_enable(self):
+        # Update the enabled attribute of a project
+        p_name = rand_name('project-')
+        p_en = False
+        resp, project = self.v3_client.create_project(p_name, enabled=p_en)
+        self.v3data.projects.append(project)
+
+        resp1_en = project['enabled']
+
+        p_en2 = True
+        resp, body = self.v3_client.update_project(
+            project['id'], enabled=p_en2)
+        st2 = resp['status']
+        resp2_en = body['enabled']
+        self.assertEqual(st2, '200')
+        self.assertNotEqual(resp1_en, resp2_en)
+
+        resp, body = self.v3_client.get_project(project['id'])
+        resp3_en = body['enabled']
+
+        self.assertNotEqual(resp1_en, resp3_en)
+        self.assertEqual('false', str(resp1_en).lower())
+        self.assertEqual(resp2_en, resp3_en)
+
+    @attr(type='gate')
+    def test_associate_user_to_project(self):
+        #Associate a user to a project
+        #Create a Project
+        p_name = rand_name('project-')
+        resp, project = self.v3_client.create_project(p_name)
+        self.v3data.projects.append(project)
+
+        #Create a User
+        u_name = rand_name('user-')
+        u_desc = u_name + 'description'
+        u_email = u_name + '@testmail.tm'
+        u_password = rand_name('pass-')
+        resp, user = self.v3_client.create_user(
+            u_name, description=u_desc, password=u_password,
+            email=u_email, project_id=project['id'])
+        self.assertEqual(resp['status'], '201')
+        # Delete the User at the end of this method
+        self.addCleanup(self.v3_client.delete_user, user['id'])
+
+        # Get User To validate the user details
+        resp, new_user_get = self.v3_client.get_user(user['id'])
+        #Assert response body of GET
+        self.assertEqual(u_name, new_user_get['name'])
+        self.assertEqual(u_desc, new_user_get['description'])
+        self.assertEqual(project['id'],
+                         new_user_get['project_id'])
+        self.assertEqual(u_email, new_user_get['email'])
+
+    @attr(type=['negative', 'gate'])
+    def test_list_projects_by_unauthorized_user(self):
+        # Non-admin user should not be able to list projects
+        self.assertRaises(exceptions.Unauthorized,
+                          self.v3_non_admin_client.list_projects)
+
+    @attr(type=['negative', 'gate'])
+    def test_project_create_duplicate(self):
+        # Project names should be unique
+        project_name = rand_name('project-dup-')
+        resp, project = self.v3_client.create_project(project_name)
+        self.v3data.projects.append(project)
+
+        self.assertRaises(
+            exceptions.Conflict, self.v3_client.create_project, project_name)
+
+    @attr(type=['negative', 'gate'])
+    def test_create_project_by_unauthorized_user(self):
+        # Non-admin user should not be authorized to create a project
+        project_name = rand_name('project-')
+        self.assertRaises(
+            exceptions.Unauthorized, self.v3_non_admin_client.create_project,
+            project_name)
+
+    @attr(type=['negative', 'gate'])
+    def test_create_project_with_empty_name(self):
+        # Project name should not be empty
+        self.assertRaises(exceptions.BadRequest, self.v3_client.create_project,
+                          name='')
+
+    @attr(type=['negative', 'gate'])
+    def test_create_projects_name_length_over_64(self):
+        # Project name length should not be greater than 64 characters
+        project_name = 'a' * 65
+        self.assertRaises(exceptions.BadRequest, self.v3_client.create_project,
+                          project_name)
+
+    @attr(type=['negative', 'gate'])
+    def test_project_delete_by_unauthorized_user(self):
+        # Non-admin user should not be able to delete a project
+        project_name = rand_name('project-')
+        resp, project = self.v3_client.create_project(project_name)
+        self.v3data.projects.append(project)
+        self.assertRaises(
+            exceptions.Unauthorized, self.v3_non_admin_client.delete_project,
+            project['id'])
+
+    @attr(type=['negative', 'gate'])
+    def test_delete_non_existent_project(self):
+        # Attempt to delete a non existent project should fail
+        self.assertRaises(exceptions.NotFound, self.v3_client.delete_project,
+                          'junk_Project_123456abc')
+
+
+class ProjectsTestXML(ProjectsTestJSON):
+    _interface = 'xml'
diff --git a/tempest/api/identity/admin/v3/test_tokens.py b/tempest/api/identity/admin/v3/test_tokens.py
index 22d74d3..f8a62a6 100644
--- a/tempest/api/identity/admin/v3/test_tokens.py
+++ b/tempest/api/identity/admin/v3/test_tokens.py
@@ -19,13 +19,11 @@
 from tempest.common.utils.data_utils import rand_name
 from tempest import exceptions
 from tempest.test import attr
-import testtools
 
 
 class UsersTestJSON(base.BaseIdentityAdminTest):
     _interface = 'json'
 
-    @testtools.skip("Skipped until the Bug #1221889 is resolved")
     @attr(type='smoke')
     def test_tokens(self):
         # Valid user's token is authenticated
@@ -51,7 +49,7 @@
         self.assertEqual(token_details['user']['name'], u_name)
         # Perform Delete Token
         resp, _ = self.v3_client.delete_token(subject_token)
-        self.assertRaises(exceptions.Unauthorized, self.v3_client.get_token,
+        self.assertRaises(exceptions.NotFound, self.v3_client.get_token,
                           subject_token)
 
 
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index 09fdd22..ab89af4 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -40,13 +40,16 @@
             raise cls.skipException("Admin extensions disabled")
 
         cls.data = DataGenerator(cls.client)
+        cls.v3data = DataGenerator(cls.v3_client)
 
         os = clients.Manager(interface=cls._interface)
         cls.non_admin_client = os.identity_client
+        cls.v3_non_admin_client = os.identity_v3_client
 
     @classmethod
     def tearDownClass(cls):
         cls.data.teardown_all()
+        cls.v3data.teardown_all()
         super(BaseIdentityAdminTest, cls).tearDownClass()
 
     def disable_user(self, user_name):
@@ -84,6 +87,9 @@
             self.tenants = []
             self.roles = []
             self.role_name = None
+            self.v3_users = []
+            self.projects = []
+            self.v3_roles = []
 
         def setup_test_user(self):
             """Set up a test user."""
@@ -112,6 +118,33 @@
             resp, self.role = self.client.create_role(self.test_role)
             self.roles.append(self.role)
 
+        def setup_test_v3_user(self):
+            """Set up a test v3 user."""
+            self.setup_test_project()
+            self.test_user = rand_name('test_user_')
+            self.test_password = rand_name('pass_')
+            self.test_email = self.test_user + '@testmail.tm'
+            resp, self.v3_user = self.client.create_user(self.test_user,
+                                                         self.test_password,
+                                                         self.project['id'],
+                                                         self.test_email)
+            self.v3_users.append(self.v3_user)
+
+        def setup_test_project(self):
+            """Set up a test project."""
+            self.test_project = rand_name('test_project_')
+            self.test_description = rand_name('desc_')
+            resp, self.project = self.client.create_project(
+                name=self.test_project,
+                description=self.test_description)
+            self.projects.append(self.project)
+
+        def setup_test_v3_role(self):
+            """Set up a test v3 role."""
+            self.test_role = rand_name('role')
+            resp, self.v3_role = self.client.create_role(self.test_role)
+            self.v3_roles.append(self.v3_role)
+
         def teardown_all(self):
             for user in self.users:
                 self.client.delete_user(user['id'])
@@ -119,3 +152,9 @@
                 self.client.delete_tenant(tenant['id'])
             for role in self.roles:
                 self.client.delete_role(role['id'])
+            for v3_user in self.v3_users:
+                self.client.delete_user(v3_user['id'])
+            for v3_project in self.projects:
+                self.client.delete_project(v3_project['id'])
+            for v3_role in self.v3_roles:
+                self.client.delete_role(v3_role['id'])
diff --git a/tempest/api/image/v1/test_image_members.py b/tempest/api/image/v1/test_image_members.py
index e9c395e..9ea9a3d 100644
--- a/tempest/api/image/v1/test_image_members.py
+++ b/tempest/api/image/v1/test_image_members.py
@@ -28,21 +28,26 @@
     @classmethod
     def setUpClass(cls):
         super(ImageMembersTests, cls).setUpClass()
-        admin = clients.AdminManager(interface='json')
-        cls.admin_client = admin.identity_client
-        cls.tenants = cls._get_tenants()
+        if cls.config.compute.allow_tenant_isolation:
+            creds = cls.isolated_creds.get_alt_creds()
+            username, tenant_name, password = creds
+            cls.os_alt = clients.Manager(username=username,
+                                         password=password,
+                                         tenant_name=tenant_name)
+        else:
+            cls.os_alt = clients.AltManager()
 
-    @classmethod
-    def _get_tenants(cls):
-        resp, tenants = cls.admin_client.list_tenants()
-        tenants = map(lambda x: x['id'], tenants)
-        return tenants
+        alt_tenant_name = cls.os_alt.tenant_name
+        identity_client = cls._get_identity_admin_client()
+        _, tenants = identity_client.list_tenants()
+        cls.alt_tenant_id = [tnt['id'] for tnt in tenants if tnt['name'] ==
+                             alt_tenant_name][0]
 
     def _create_image(self):
         image_file = StringIO.StringIO('*' * 1024)
         resp, image = self.create_image(container_format='bare',
                                         disk_format='raw',
-                                        is_public=True,
+                                        is_public=False,
                                         data=image_file)
         self.assertEqual(201, resp.status)
         image_id = image['id']
@@ -51,23 +56,23 @@
     @attr(type='gate')
     def test_add_image_member(self):
         image = self._create_image()
-        resp = self.client.add_member(self.tenants[0], image)
+        resp = self.client.add_member(self.alt_tenant_id, image)
         self.assertEqual(204, resp.status)
         resp, body = self.client.get_image_membership(image)
         self.assertEqual(200, resp.status)
         members = body['members']
         members = map(lambda x: x['member_id'], members)
-        self.assertIn(self.tenants[0], members)
+        self.assertIn(self.alt_tenant_id, members)
 
     @attr(type='gate')
     def test_get_shared_images(self):
         image = self._create_image()
-        resp = self.client.add_member(self.tenants[0], image)
+        resp = self.client.add_member(self.alt_tenant_id, image)
         self.assertEqual(204, resp.status)
         share_image = self._create_image()
-        resp = self.client.add_member(self.tenants[0], share_image)
+        resp = self.client.add_member(self.alt_tenant_id, share_image)
         self.assertEqual(204, resp.status)
-        resp, body = self.client.get_shared_images(self.tenants[0])
+        resp, body = self.client.get_shared_images(self.alt_tenant_id)
         self.assertEqual(200, resp.status)
         images = body['shared_images']
         images = map(lambda x: x['image_id'], images)
@@ -77,28 +82,28 @@
     @attr(type='gate')
     def test_remove_member(self):
         image_id = self._create_image()
-        resp = self.client.add_member(self.tenants[0], image_id)
+        resp = self.client.add_member(self.alt_tenant_id, image_id)
         self.assertEqual(204, resp.status)
-        resp = self.client.delete_member(self.tenants[0], image_id)
+        resp = self.client.delete_member(self.alt_tenant_id, image_id)
         self.assertEqual(204, resp.status)
         resp, body = self.client.get_image_membership(image_id)
         self.assertEqual(200, resp.status)
         members = body['members']
-        self.assertEqual(0, len(members))
+        self.assertEqual(0, len(members), str(members))
 
     @attr(type=['negative', 'gate'])
     def test_add_member_with_non_existing_image(self):
         # Add member with non existing image.
         non_exist_image = rand_name('image_')
         self.assertRaises(exceptions.NotFound, self.client.add_member,
-                          self.tenants[0], non_exist_image)
+                          self.alt_tenant_id, non_exist_image)
 
     @attr(type=['negative', 'gate'])
     def test_delete_member_with_non_existing_image(self):
         # Delete member with non existing image.
         non_exist_image = rand_name('image_')
         self.assertRaises(exceptions.NotFound, self.client.delete_member,
-                          self.tenants[0], non_exist_image)
+                          self.alt_tenant_id, non_exist_image)
 
     @attr(type=['negative', 'gate'])
     def test_delete_member_with_non_existing_tenant(self):
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index cfac257..b6c2679 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -20,8 +20,11 @@
 from tempest import clients
 from tempest.common.utils.data_utils import rand_name
 from tempest import exceptions
+from tempest.openstack.common import log as logging
 import tempest.test
 
+LOG = logging.getLogger(__name__)
+
 
 class BaseNetworkTest(tempest.test.BaseTestCase):
 
@@ -56,28 +59,84 @@
         cls.networks = []
         cls.subnets = []
         cls.ports = []
+        cls.routers = []
         cls.pools = []
         cls.vips = []
         cls.members = []
         cls.health_monitors = []
+        cls.vpnservices = []
 
     @classmethod
     def tearDownClass(cls):
+        has_exception = False
+        for vpnservice in cls.vpnservices:
+            try:
+                cls.client.delete_vpn_service(vpnservice['id'])
+            except Exception as exc:
+                LOG.exception(exc)
+                has_exception = True
+
+        for router in cls.routers:
+            try:
+                resp, body = cls.client.list_router_interfaces(router['id'])
+                interfaces = body['ports']
+                for i in interfaces:
+                    cls.client.remove_router_interface_with_subnet_id(
+                        router['id'], i['fixed_ips'][0]['subnet_id'])
+            except Exception as exc:
+                LOG.exception(exc)
+                has_exception = True
+            try:
+                cls.client.delete_router(router['id'])
+            except Exception as exc:
+                LOG.exception(exc)
+                has_exception = True
+
         for health_monitor in cls.health_monitors:
-            cls.client.delete_health_monitor(health_monitor['id'])
+            try:
+                cls.client.delete_health_monitor(health_monitor['id'])
+            except Exception as exc:
+                LOG.exception(exc)
+                has_exception = True
         for member in cls.members:
-            cls.client.delete_member(member['id'])
+            try:
+                cls.client.delete_member(member['id'])
+            except Exception as exc:
+                LOG.exception(exc)
+                has_exception = True
         for vip in cls.vips:
-            cls.client.delete_vip(vip['id'])
+            try:
+                cls.client.delete_vip(vip['id'])
+            except Exception as exc:
+                LOG.exception(exc)
+                has_exception = True
         for pool in cls.pools:
-            cls.client.delete_pool(pool['id'])
+            try:
+                cls.client.delete_pool(pool['id'])
+            except Exception as exc:
+                LOG.exception(exc)
+                has_exception = True
         for port in cls.ports:
-            cls.client.delete_port(port['id'])
+            try:
+                cls.client.delete_port(port['id'])
+            except Exception as exc:
+                LOG.exception(exc)
+                has_exception = True
         for subnet in cls.subnets:
-            cls.client.delete_subnet(subnet['id'])
+            try:
+                cls.client.delete_subnet(subnet['id'])
+            except Exception as exc:
+                LOG.exception(exc)
+                has_exception = True
         for network in cls.networks:
-            cls.client.delete_network(network['id'])
+            try:
+                cls.client.delete_network(network['id'])
+            except Exception as exc:
+                LOG.exception(exc)
+                has_exception = True
         super(BaseNetworkTest, cls).tearDownClass()
+        if has_exception:
+            raise exceptions.TearDownException()
 
     @classmethod
     def create_network(cls, network_name=None):
@@ -125,6 +184,21 @@
         return port
 
     @classmethod
+    def create_router(cls, router_name=None, admin_state_up=False,
+                      external_network_id=None, enable_snat=None):
+        ext_gw_info = {}
+        if external_network_id:
+            ext_gw_info['network_id'] = external_network_id
+        if enable_snat:
+            ext_gw_info['enable_snat'] = enable_snat
+        resp, body = cls.client.create_router(
+            router_name, external_gateway_info=ext_gw_info,
+            admin_state_up=admin_state_up)
+        router = body['router']
+        cls.routers.append(router)
+        return router
+
+    @classmethod
     def create_pool(cls, name, lb_method, protocol, subnet):
         """Wrapper utility that returns a test pool."""
         resp, body = cls.client.create_pool(name, lb_method, protocol,
@@ -161,3 +235,19 @@
         health_monitor = body['health_monitor']
         cls.health_monitors.append(health_monitor)
         return health_monitor
+
+    @classmethod
+    def create_router_interface(cls, router_id, subnet_id):
+        """Wrapper utility that returns a router interface."""
+        resp, interface = cls.client.add_router_interface_with_subnet_id(
+            router_id, subnet_id)
+
+    @classmethod
+    def create_vpnservice(cls, subnet_id, router_id):
+        """Wrapper utility that returns a test vpn service."""
+        resp, body = cls.client.create_vpn_service(
+            subnet_id, router_id, admin_state_up=True,
+            name=rand_name("vpnservice-"))
+        vpnservice = body['vpnservice']
+        cls.vpnservices.append(vpnservice)
+        return vpnservice
diff --git a/tempest/api/network/common.py b/tempest/api/network/common.py
index c3fb821..43e7f68 100644
--- a/tempest/api/network/common.py
+++ b/tempest/api/network/common.py
@@ -56,7 +56,9 @@
 
 class DeletableSubnet(DeletableResource):
 
-    _router_ids = set()
+    def __init__(self, *args, **kwargs):
+        super(DeletableSubnet, self).__init__(*args, **kwargs)
+        self._router_ids = set()
 
     def add_to_router(self, router_id):
         self._router_ids.add(router_id)
diff --git a/tempest/api/network/test_floating_ips.py b/tempest/api/network/test_floating_ips.py
index 017864f..9acb6c5 100644
--- a/tempest/api/network/test_floating_ips.py
+++ b/tempest/api/network/test_floating_ips.py
@@ -20,7 +20,7 @@
 from tempest.test import attr
 
 
-class FloatingIPTest(base.BaseNetworkTest):
+class FloatingIPTestJSON(base.BaseNetworkTest):
     _interface = 'json'
 
     """
@@ -41,17 +41,15 @@
 
     @classmethod
     def setUpClass(cls):
-        super(FloatingIPTest, cls).setUpClass()
+        super(FloatingIPTestJSON, cls).setUpClass()
         cls.ext_net_id = cls.config.network.public_network_id
 
         # Create network, subnet, router and add interface
         cls.network = cls.create_network()
         cls.subnet = cls.create_subnet(cls.network)
-        resp, router = cls.client.create_router(
+        cls.router = cls.create_router(
             rand_name('router-'),
-            external_gateway_info={"network_id":
-                                   cls.network_cfg.public_network_id})
-        cls.router = router['router']
+            external_network_id=cls.network_cfg.public_network_id)
         resp, _ = cls.client.add_router_interface_with_subnet_id(
             cls.router['id'], cls.subnet['id'])
         cls.port = list()
@@ -66,8 +64,7 @@
                                                           cls.subnet['id'])
         for i in range(2):
             cls.client.delete_port(cls.port[i]['id'])
-        cls.client.delete_router(cls.router['id'])
-        super(FloatingIPTest, cls).tearDownClass()
+        super(FloatingIPTestJSON, cls).tearDownClass()
 
     def _delete_floating_ip(self, floating_ip_id):
         # Deletes a floating IP and verifies if it is deleted or not
@@ -133,3 +130,7 @@
         self.assertIsNone(update_floating_ip['port_id'])
         self.assertIsNone(update_floating_ip['fixed_ip_address'])
         self.assertIsNone(update_floating_ip['router_id'])
+
+
+class FloatingIPTestXML(FloatingIPTestJSON):
+    _interface = 'xml'
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index 8b939fe..2cfbf61 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -52,6 +52,8 @@
     @attr(type='smoke')
     def test_create_show_list_update_delete_router(self):
         # Create a router
+        # NOTE(salv-orlando): Do not invoke self.create_router
+        # as we need to check the response code
         name = rand_name('router-')
         resp, create_body = self.client.create_router(
             name, external_gateway_info={
@@ -94,41 +96,37 @@
     def test_add_remove_router_interface_with_subnet_id(self):
         network = self.create_network()
         subnet = self.create_subnet(network)
-        name = rand_name('router-')
-        resp, create_body = self.client.create_router(name)
-        self.addCleanup(self.client.delete_router, create_body['router']['id'])
+        router = self.create_router(rand_name('router-'))
         # Add router interface with subnet id
         resp, interface = self.client.add_router_interface_with_subnet_id(
-            create_body['router']['id'], subnet['id'])
+            router['id'], subnet['id'])
         self.assertEqual('200', resp['status'])
         self.addCleanup(self._remove_router_interface_with_subnet_id,
-                        create_body['router']['id'], subnet['id'])
+                        router['id'], subnet['id'])
         self.assertTrue('subnet_id' in interface.keys())
         self.assertTrue('port_id' in interface.keys())
         # Verify router id is equal to device id in port details
         resp, show_port_body = self.client.show_port(
             interface['port_id'])
         self.assertEqual(show_port_body['port']['device_id'],
-                         create_body['router']['id'])
+                         router['id'])
 
     @attr(type='smoke')
     def test_add_remove_router_interface_with_port_id(self):
         network = self.create_network()
         self.create_subnet(network)
-        name = rand_name('router-')
-        resp, create_body = self.client.create_router(name)
-        self.addCleanup(self.client.delete_router, create_body['router']['id'])
+        router = self.create_router(rand_name('router-'))
         resp, port_body = self.client.create_port(network['id'])
         # add router interface to port created above
         resp, interface = self.client.add_router_interface_with_port_id(
-            create_body['router']['id'], port_body['port']['id'])
+            router['id'], port_body['port']['id'])
         self.assertEqual('200', resp['status'])
         self.addCleanup(self._remove_router_interface_with_port_id,
-                        create_body['router']['id'], port_body['port']['id'])
+                        router['id'], port_body['port']['id'])
         self.assertTrue('subnet_id' in interface.keys())
         self.assertTrue('port_id' in interface.keys())
         # Verify router id is equal to device id in port details
         resp, show_port_body = self.client.show_port(
             interface['port_id'])
         self.assertEqual(show_port_body['port']['device_id'],
-                         create_body['router']['id'])
+                         router['id'])
diff --git a/tempest/api/network/test_security_groups.py b/tempest/api/network/test_security_groups.py
index 60ca88a..9218f0c 100644
--- a/tempest/api/network/test_security_groups.py
+++ b/tempest/api/network/test_security_groups.py
@@ -16,8 +16,7 @@
 #    under the License.
 
 from tempest.api.network import base
-from tempest.common.utils.data_utils import rand_name
-from tempest import exceptions
+from tempest.common.utils import data_utils
 from tempest.test import attr
 
 
@@ -66,9 +65,9 @@
         self.assertIsNotNone(found, msg)
 
     @attr(type='smoke')
-    def test_create_show_delete_security_group_and_rule(self):
+    def test_create_show_delete_security_group(self):
         # Create a security group
-        name = rand_name('secgroup-')
+        name = data_utils.rand_name('secgroup-')
         resp, group_create_body = self.client.create_security_group(name)
         self.assertEqual('201', resp['status'])
         self.addCleanup(self._delete_security_group,
@@ -88,14 +87,29 @@
         for secgroup in list_body['security_groups']:
             secgroup_list.append(secgroup['id'])
         self.assertIn(group_create_body['security_group']['id'], secgroup_list)
-        # No Update in security group
-        # Create rule
-        resp, rule_create_body = self.client.create_security_group_rule(
-            group_create_body['security_group']['id']
-        )
+
+    @attr(type='smoke')
+    def test_create_show_delete_security_group_rule(self):
+        # Create a security group
+        name = data_utils.rand_name('secgroup-')
+        resp, group_create_body = self.client.create_security_group(name)
         self.assertEqual('201', resp['status'])
-        self.addCleanup(self._delete_security_group_rule,
-                        rule_create_body['security_group_rule']['id'])
+        self.addCleanup(self._delete_security_group,
+                        group_create_body['security_group']['id'])
+        self.assertEqual(group_create_body['security_group']['name'], name)
+
+        # Create rules for each protocol
+        protocols = ['tcp', 'udp', 'icmp']
+        for protocol in protocols:
+            resp, rule_create_body = self.client.create_security_group_rule(
+                group_create_body['security_group']['id'],
+                protocol=protocol
+            )
+            self.assertEqual('201', resp['status'])
+            self.addCleanup(self._delete_security_group_rule,
+                            rule_create_body['security_group_rule']['id']
+                            )
+
         # Show details of the created security rule
         resp, show_rule_body = self.client.show_security_group_rule(
             rule_create_body['security_group_rule']['id']
@@ -109,19 +123,6 @@
                      for rule in rule_list_body['security_group_rules']]
         self.assertIn(rule_create_body['security_group_rule']['id'], rule_list)
 
-    @attr(type=['negative', 'smoke'])
-    def test_show_non_existent_security_group(self):
-        non_exist_id = rand_name('secgroup-')
-        self.assertRaises(exceptions.NotFound, self.client.show_security_group,
-                          non_exist_id)
-
-    @attr(type=['negative', 'smoke'])
-    def test_show_non_existent_security_group_rule(self):
-        non_exist_id = rand_name('rule-')
-        self.assertRaises(exceptions.NotFound,
-                          self.client.show_security_group_rule,
-                          non_exist_id)
-
 
 class SecGroupTestXML(SecGroupTest):
     _interface = 'xml'
diff --git a/tempest/api/network/test_security_groups_negative.py b/tempest/api/network/test_security_groups_negative.py
new file mode 100644
index 0000000..daeb89f
--- /dev/null
+++ b/tempest/api/network/test_security_groups_negative.py
@@ -0,0 +1,91 @@
+# 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.api.network import test_security_groups as base
+from tempest.common.utils import data_utils
+from tempest import exceptions
+from tempest.test import attr
+import uuid
+
+
+class NegativeSecGroupTest(base.SecGroupTest):
+    _interface = 'json'
+
+    @attr(type=['negative', 'smoke'])
+    def test_show_non_existent_security_group(self):
+        non_exist_id = str(uuid.uuid4())
+        self.assertRaises(exceptions.NotFound, self.client.show_security_group,
+                          non_exist_id)
+
+    @attr(type=['negative', 'smoke'])
+    def test_show_non_existent_security_group_rule(self):
+        non_exist_id = str(uuid.uuid4())
+        self.assertRaises(exceptions.NotFound,
+                          self.client.show_security_group_rule,
+                          non_exist_id)
+
+    @attr(type=['negative', 'smoke'])
+    def test_delete_non_existent_security_group(self):
+        non_exist_id = 'fictional-id'
+        self.assertRaises(exceptions.NotFound,
+                          self.client.delete_security_group,
+                          non_exist_id
+                          )
+
+    @attr(type=['negative', 'smoke'])
+    def test_create_security_group_rule_with_bad_protocol(self):
+        # Create a security group
+        name = data_utils.rand_name('secgroup-')
+        resp, group_create_body = self.client.create_security_group(name)
+        self.assertEqual('201', resp['status'])
+        self.addCleanup(self._delete_security_group,
+                        group_create_body['security_group']['id'])
+        self.assertEqual(group_create_body['security_group']['name'], name)
+
+        #Create rule with bad protocol name
+        pname = 'bad_protocol_name'
+        self.assertRaises(exceptions.BadRequest,
+                          self.client.create_security_group_rule,
+                          group_create_body['security_group']['id'],
+                          protocol=pname)
+
+    @attr(type=['negative', 'smoke'])
+    def test_create_security_group_rule_with_invalid_ports(self):
+        # Create a security group
+        name = data_utils.rand_name('secgroup-')
+        resp, group_create_body = self.client.create_security_group(name)
+        self.assertEqual('201', resp['status'])
+        self.addCleanup(self._delete_security_group,
+                        group_create_body['security_group']['id'])
+        self.assertEqual(group_create_body['security_group']['name'], name)
+
+        #Create rule with invalid ports
+        states = [(-16, 80, 'Invalid value for port -16'),
+                  (80, 79, 'port_range_min must be <= port_range_max'),
+                  (80, 65536, 'Invalid value for port 65536')]
+        for pmin, pmax, msg in states:
+            ex = self.assertRaises(exceptions.BadRequest,
+                                   self.client.create_security_group_rule,
+                                   group_create_body['security_group']['id'],
+                                   protocol='tcp',
+                                   port_range_min=pmin,
+                                   port_range_max=pmax)
+            self.assertIn(msg, str(ex))
+
+
+class NegativeSecGroupTestXML(NegativeSecGroupTest):
+    _interface = 'xml'
diff --git a/tempest/api/network/test_vpnaas_extensions.py b/tempest/api/network/test_vpnaas_extensions.py
new file mode 100644
index 0000000..7a8128b
--- /dev/null
+++ b/tempest/api/network/test_vpnaas_extensions.py
@@ -0,0 +1,96 @@
+# 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.api.network import base
+from tempest.common.utils.data_utils import rand_name
+from tempest.test import attr
+
+
+class VPNaaSJSON(base.BaseNetworkTest):
+    _interface = 'json'
+
+    """
+    Tests the following operations in the Neutron API using the REST client for
+    Neutron:
+
+        List VPN Services
+        Show VPN Services
+        Create VPN Services
+        Update VPN Services
+        Delete VPN Services
+    """
+
+    @classmethod
+    def setUpClass(cls):
+        super(VPNaaSJSON, cls).setUpClass()
+        cls.network = cls.create_network()
+        cls.subnet = cls.create_subnet(cls.network)
+        cls.router = cls.create_router(rand_name("router-"))
+        cls.create_router_interface(cls.router['id'], cls.subnet['id'])
+        cls.vpnservice = cls.create_vpnservice(cls.subnet['id'],
+                                               cls.router['id'])
+
+    @attr(type='smoke')
+    def test_list_vpn_services(self):
+        # Verify the VPN service exists in the list of all VPN services
+        resp, body = self.client.list_vpn_services()
+        self.assertEqual('200', resp['status'])
+        vpnservices = body['vpnservices']
+        self.assertIn(self.vpnservice['id'], [v['id'] for v in vpnservices])
+
+    @attr(type='smoke')
+    def test_create_update_delete_vpn_service(self):
+        # Creates a VPN service
+        name = rand_name('vpn-service-')
+        resp, body = self.client.create_vpn_service(self.subnet['id'],
+                                                    self.router['id'],
+                                                    name=name,
+                                                    admin_state_up=True)
+        self.assertEqual('201', resp['status'])
+        vpnservice = body['vpnservice']
+        # Assert if created vpnservices are not found in vpnservices list
+        resp, body = self.client.list_vpn_services()
+        vpn_services = [vs['id'] for vs in body['vpnservices']]
+        self.assertIsNotNone(vpnservice['id'])
+        self.assertIn(vpnservice['id'], vpn_services)
+
+        # TODO(raies): implement logic to update  vpnservice
+        # VPNaaS client function to update is implemented.
+        # But precondition is that current state of vpnservice
+        # should be "ACTIVE" not "PENDING*"
+
+        # Verification of vpn service delete
+        resp, body = self.client.delete_vpn_service(vpnservice['id'])
+        self.assertEqual('204', resp['status'])
+        # Asserting if vpn service is found in the list after deletion
+        resp, body = self.client.list_vpn_services()
+        vpn_services = [vs['id'] for vs in body['vpnservices']]
+        self.assertNotIn(vpnservice['id'], vpn_services)
+
+    @attr(type='smoke')
+    def test_show_vpn_service(self):
+        # Verifies the details of a vpn service
+        resp, body = self.client.show_vpn_service(self.vpnservice['id'])
+        self.assertEqual('200', resp['status'])
+        vpnservice = body['vpnservice']
+        self.assertEqual(self.vpnservice['id'], vpnservice['id'])
+        self.assertEqual(self.vpnservice['name'], vpnservice['name'])
+        self.assertEqual(self.vpnservice['description'],
+                         vpnservice['description'])
+        self.assertEqual(self.vpnservice['router_id'], vpnservice['router_id'])
+        self.assertEqual(self.vpnservice['subnet_id'], vpnservice['subnet_id'])
+        self.assertEqual(self.vpnservice['tenant_id'], vpnservice['tenant_id'])
diff --git a/tempest/api/object_storage/test_container_sync.py b/tempest/api/object_storage/test_container_sync.py
index a43b2b5..ff9f7bf 100644
--- a/tempest/api/object_storage/test_container_sync.py
+++ b/tempest/api/object_storage/test_container_sync.py
@@ -17,11 +17,10 @@
 
 import time
 
-import testtools
-
 from tempest.api.object_storage import base
 from tempest.common.utils.data_utils import rand_name
 from tempest.test import attr
+from tempest.test import skip_because
 
 
 class ContainerSyncTest(base.BaseObjectTest):
@@ -52,7 +51,7 @@
             cls.delete_containers(cls.containers, client[0], client[1])
         super(ContainerSyncTest, cls).tearDownClass()
 
-    @testtools.skip('Skipped until the Bug #1093743 is resolved.')
+    @skip_because(bug="1093743")
     @attr(type='gate')
     def test_container_synchronization(self):
         # container to container synchronization
diff --git a/tempest/api/object_storage/test_object_expiry.py b/tempest/api/object_storage/test_object_expiry.py
index db38401..cb52d88 100644
--- a/tempest/api/object_storage/test_object_expiry.py
+++ b/tempest/api/object_storage/test_object_expiry.py
@@ -17,13 +17,12 @@
 
 import time
 
-import testtools
-
 from tempest.api.object_storage import base
 from tempest.common.utils.data_utils import arbitrary_string
 from tempest.common.utils.data_utils import rand_name
 from tempest import exceptions
 from tempest.test import attr
+from tempest.test import skip_because
 
 
 class ObjectExpiryTest(base.BaseObjectTest):
@@ -43,7 +42,7 @@
         cls.delete_containers([cls.container_name])
         super(ObjectExpiryTest, cls).tearDownClass()
 
-    @testtools.skip('Skipped until the Bug #1069849 is resolved.')
+    @skip_because(bug="1069849")
     @attr(type='gate')
     def test_get_object_after_expiry_time(self):
         # TODO(harika-vakadi): similar test case has to be created for
diff --git a/tempest/api/orchestration/stacks/test_server_cfn_init.py b/tempest/api/orchestration/stacks/test_server_cfn_init.py
index d8334fa..ea0bff5 100644
--- a/tempest/api/orchestration/stacks/test_server_cfn_init.py
+++ b/tempest/api/orchestration/stacks/test_server_cfn_init.py
@@ -122,7 +122,7 @@
   SmokeServerIp:
     Description: IP address of server
     Value:
-      Fn::GetAtt: [SmokeServer, first_private_address]
+      Fn::GetAtt: [SmokeServer, first_address]
 """
 
     @classmethod
diff --git a/tempest/api/volume/test_volumes_actions.py b/tempest/api/volume/test_volumes_actions.py
index 19e3fc6..09131e2 100644
--- a/tempest/api/volume/test_volumes_actions.py
+++ b/tempest/api/volume/test_volumes_actions.py
@@ -32,8 +32,8 @@
         cls.image_client = cls.os.image_client
 
         # Create a test shared instance and volume for attach/detach tests
-        srv_name = rand_name('Instance-')
-        vol_name = rand_name('Volume-')
+        srv_name = rand_name(cls.__name__ + '-Instance-')
+        vol_name = rand_name(cls.__name__ + '-Volume-')
         resp, cls.server = cls.servers_client.create_server(srv_name,
                                                             cls.image_ref,
                                                             cls.flavor_ref)
diff --git a/tempest/api/volume/test_volumes_list.py b/tempest/api/volume/test_volumes_list.py
index 32eecfb..2aaa71d 100644
--- a/tempest/api/volume/test_volumes_list.py
+++ b/tempest/api/volume/test_volumes_list.py
@@ -1,6 +1,7 @@
 # vim: tabstop=4 shiftwidth=4 softtabstop=4
 
 # Copyright 2012 OpenStack Foundation
+# Copyright 2013 IBM Corp.
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -16,6 +17,7 @@
 #    under the License.
 
 from tempest.api.volume import base
+from tempest.common.utils.data_utils import rand_int_id
 from tempest.common.utils.data_utils import rand_name
 from tempest.openstack.common import log as logging
 from tempest.test import attr
@@ -103,6 +105,66 @@
         self.assertEqual(200, resp.status)
         self.assertVolumesIn(fetched_list, self.volume_list)
 
+    @attr(type='gate')
+    def test_volume_list_by_name(self):
+        volume = self.volume_list[rand_int_id(0, 2)]
+        params = {'display_name': volume['display_name']}
+        resp, fetched_vol = self.client.list_volumes(params)
+        self.assertEqual(200, resp.status)
+        self.assertEqual(1, len(fetched_vol), str(fetched_vol))
+        self.assertEqual(fetched_vol[0]['display_name'],
+                         volume['display_name'])
+
+    @attr(type='gate')
+    def test_volume_list_details_by_name(self):
+        volume = self.volume_list[rand_int_id(0, 2)]
+        params = {'display_name': volume['display_name']}
+        resp, fetched_vol = self.client.list_volumes_with_detail(params)
+        self.assertEqual(200, resp.status)
+        self.assertEqual(1, len(fetched_vol), str(fetched_vol))
+        self.assertEqual(fetched_vol[0]['display_name'],
+                         volume['display_name'])
+
+    @attr(type='gate')
+    def test_volumes_list_by_status(self):
+        params = {'status': 'available'}
+        resp, fetched_list = self.client.list_volumes(params)
+        self.assertEqual(200, resp.status)
+        for volume in fetched_list:
+            self.assertEqual('available', volume['status'])
+        self.assertVolumesIn(fetched_list, self.volume_list)
+
+    @attr(type='gate')
+    def test_volumes_list_details_by_status(self):
+        params = {'status': 'available'}
+        resp, fetched_list = self.client.list_volumes_with_detail(params)
+        self.assertEqual(200, resp.status)
+        for volume in fetched_list:
+            self.assertEqual('available', volume['status'])
+        self.assertVolumesIn(fetched_list, self.volume_list)
+
+    @attr(type='gate')
+    def test_volumes_list_by_availability_zone(self):
+        volume = self.volume_list[rand_int_id(0, 2)]
+        zone = volume['availability_zone']
+        params = {'availability_zone': zone}
+        resp, fetched_list = self.client.list_volumes(params)
+        self.assertEqual(200, resp.status)
+        for volume in fetched_list:
+            self.assertEqual(zone, volume['availability_zone'])
+        self.assertVolumesIn(fetched_list, self.volume_list)
+
+    @attr(type='gate')
+    def test_volumes_list_details_by_availability_zone(self):
+        volume = self.volume_list[rand_int_id(0, 2)]
+        zone = volume['availability_zone']
+        params = {'availability_zone': zone}
+        resp, fetched_list = self.client.list_volumes_with_detail(params)
+        self.assertEqual(200, resp.status)
+        for volume in fetched_list:
+            self.assertEqual(zone, volume['availability_zone'])
+        self.assertVolumesIn(fetched_list, self.volume_list)
+
 
 class VolumeListTestXML(VolumesListTest):
     _interface = 'xml'
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index a48cea2..02adc5d 100644
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -38,19 +38,19 @@
         cls.client.wait_for_volume_status(cls.volume['id'], 'available')
         cls.mountpoint = "/dev/vdc"
 
-    @attr(type='gate')
+    @attr(type=['negative', 'gate'])
     def test_volume_get_nonexistant_volume_id(self):
         # Should not be able to get a non-existant volume
         self.assertRaises(exceptions.NotFound, self.client.get_volume,
                           str(uuid.uuid4()))
 
-    @attr(type='gate')
+    @attr(type=['negative', 'gate'])
     def test_volume_delete_nonexistant_volume_id(self):
         # Should not be able to delete a non-existant Volume
         self.assertRaises(exceptions.NotFound, self.client.delete_volume,
                           str(uuid.uuid4()))
 
-    @attr(type='gate')
+    @attr(type=['negative', 'gate'])
     def test_create_volume_with_invalid_size(self):
         # Should not be able to create volume with invalid size
         # in request
@@ -59,7 +59,7 @@
         self.assertRaises(exceptions.BadRequest, self.client.create_volume,
                           size='#$%', display_name=v_name, metadata=metadata)
 
-    @attr(type='gate')
+    @attr(type=['negative', 'gate'])
     def test_create_volume_with_out_passing_size(self):
         # Should not be able to create volume without passing size
         # in request
@@ -68,7 +68,7 @@
         self.assertRaises(exceptions.BadRequest, self.client.create_volume,
                           size='', display_name=v_name, metadata=metadata)
 
-    @attr(type='gate')
+    @attr(type=['negative', 'gate'])
     def test_create_volume_with_size_zero(self):
         # Should not be able to create volume with size zero
         v_name = rand_name('Volume-')
@@ -76,24 +76,83 @@
         self.assertRaises(exceptions.BadRequest, self.client.create_volume,
                           size='0', display_name=v_name, metadata=metadata)
 
-    @attr(type='gate')
+    @attr(type=['negative', 'gate'])
+    def test_create_volume_with_size_negative(self):
+        # Should not be able to create volume with size negative
+        v_name = rand_name('Volume-')
+        metadata = {'Type': 'work'}
+        self.assertRaises(exceptions.BadRequest, self.client.create_volume,
+                          size='-1', display_name=v_name, metadata=metadata)
+
+    @attr(type=['negative', 'gate'])
+    def test_create_volume_with_nonexistant_volume_type(self):
+        # Should not be able to create volume with non-existant volume type
+        v_name = rand_name('Volume-')
+        metadata = {'Type': 'work'}
+        self.assertRaises(exceptions.NotFound, self.client.create_volume,
+                          size='1', volume_type=str(uuid.uuid4()),
+                          display_name=v_name, metadata=metadata)
+
+    @attr(type=['negative', 'gate'])
+    def test_create_volume_with_nonexistant_snapshot_id(self):
+        # Should not be able to create volume with non-existant snapshot
+        v_name = rand_name('Volume-')
+        metadata = {'Type': 'work'}
+        self.assertRaises(exceptions.NotFound, self.client.create_volume,
+                          size='1', snapshot_id=str(uuid.uuid4()),
+                          display_name=v_name, metadata=metadata)
+
+    @attr(type=['negative', 'gate'])
+    def test_create_volume_with_nonexistant_source_volid(self):
+        # Should not be able to create volume with non-existant source volume
+        v_name = rand_name('Volume-')
+        metadata = {'Type': 'work'}
+        self.assertRaises(exceptions.NotFound, self.client.create_volume,
+                          size='1', source_volid=str(uuid.uuid4()),
+                          display_name=v_name, metadata=metadata)
+
+    @attr(type=['negative', 'gate'])
+    def test_update_volume_with_nonexistant_volume_id(self):
+        v_name = rand_name('Volume-')
+        metadata = {'Type': 'work'}
+        self.assertRaises(exceptions.NotFound, self.client.update_volume,
+                          volume_id=str(uuid.uuid4()), display_name=v_name,
+                          metadata=metadata)
+
+    @attr(type=['negative', 'gate'])
+    def test_update_volume_with_invalid_volume_id(self):
+        v_name = rand_name('Volume-')
+        metadata = {'Type': 'work'}
+        self.assertRaises(exceptions.NotFound, self.client.update_volume,
+                          volume_id='#$%%&^&^', display_name=v_name,
+                          metadata=metadata)
+
+    @attr(type=['negative', 'gate'])
+    def test_update_volume_with_empty_volume_id(self):
+        v_name = rand_name('Volume-')
+        metadata = {'Type': 'work'}
+        self.assertRaises(exceptions.NotFound, self.client.update_volume,
+                          volume_id='', display_name=v_name,
+                          metadata=metadata)
+
+    @attr(type=['negative', 'gate'])
     def test_get_invalid_volume_id(self):
         # Should not be able to get volume with invalid id
         self.assertRaises(exceptions.NotFound, self.client.get_volume,
                           '#$%%&^&^')
 
-    @attr(type='gate')
+    @attr(type=['negative', 'gate'])
     def test_get_volume_without_passing_volume_id(self):
         # Should not be able to get volume when empty ID is passed
         self.assertRaises(exceptions.NotFound, self.client.get_volume, '')
 
-    @attr(type='gate')
+    @attr(type=['negative', 'gate'])
     def test_delete_invalid_volume_id(self):
         # Should not be able to delete volume when invalid ID is passed
         self.assertRaises(exceptions.NotFound, self.client.delete_volume,
                           '!@#$%^&*()')
 
-    @attr(type='gate')
+    @attr(type=['negative', 'gate'])
     def test_delete_volume_without_passing_volume_id(self):
         # Should not be able to delete volume when empty ID is passed
         self.assertRaises(exceptions.NotFound, self.client.delete_volume, '')
diff --git a/tempest/cli/simple_read_only/test_cinder.py b/tempest/cli/simple_read_only/test_cinder.py
index 3ff997a..25157a4 100644
--- a/tempest/cli/simple_read_only/test_cinder.py
+++ b/tempest/cli/simple_read_only/test_cinder.py
@@ -84,6 +84,24 @@
         roles = self.parser.listing(self.cinder('list-extensions'))
         self.assertTableStruct(roles, ['Name', 'Summary', 'Alias', 'Updated'])
 
+    def test_cinder_credentials(self):
+        self.cinder('credentials')
+
+    def test_cinder_availability_zone_list(self):
+        self.cinder('availability-zone-list')
+
+    def test_cinder_endpoints(self):
+        self.cinder('endpoints')
+
+    def test_cinder_service_list(self):
+        self.cinder('service-list')
+
+    def test_cinder_transfer_list(self):
+        self.cinder('transfer-list')
+
+    def test_cinder_bash_completion(self):
+        self.cinder('bash-completion')
+
     def test_admin_help(self):
         help_text = self.cinder('help')
         lines = help_text.split('\n')
diff --git a/tempest/cli/simple_read_only/test_keystone.py b/tempest/cli/simple_read_only/test_keystone.py
index 4c1c27f..a7e7147 100644
--- a/tempest/cli/simple_read_only/test_keystone.py
+++ b/tempest/cli/simple_read_only/test_keystone.py
@@ -50,7 +50,10 @@
                 self.assertTrue(svc['__label'].startswith('Service:'),
                                 msg=('Invalid beginning of service block: '
                                      '%s' % svc['__label']))
-            self.assertIn('id', svc.keys())
+            # check that region and publicURL exists. One might also
+            # check for adminURL and internalURL. id seems to be optional
+            # and is missing in the catalog backend
+            self.assertIn('publicURL', svc.keys())
             self.assertIn('region', svc.keys())
 
     def test_admin_endpoint_list(self):
diff --git a/tempest/cli/simple_read_only/test_neutron.py b/tempest/cli/simple_read_only/test_neutron.py
index ae3a1a7..9bd07d0 100644
--- a/tempest/cli/simple_read_only/test_neutron.py
+++ b/tempest/cli/simple_read_only/test_neutron.py
@@ -22,6 +22,7 @@
 
 import tempest.cli
 from tempest.openstack.common import log as logging
+from tempest import test
 
 CONF = cfg.CONF
 
@@ -67,6 +68,14 @@
     def test_neutron_floatingip_list(self):
         self.neutron('floatingip-list')
 
+    @test.skip_because(bug="1240694")
+    def test_neutron_meter_label_list(self):
+        self.neutron('meter-label-list')
+
+    @test.skip_because(bug="1240694")
+    def test_neutron_meter_label_rule_list(self):
+        self.neutron('meter-label-rule-list')
+
     def test_neutron_net_external_list(self):
         self.neutron('net-external-list')
 
diff --git a/tempest/cli/simple_read_only/test_compute.py b/tempest/cli/simple_read_only/test_nova.py
similarity index 94%
rename from tempest/cli/simple_read_only/test_compute.py
rename to tempest/cli/simple_read_only/test_nova.py
index 9b358e6..1aa8f2c 100644
--- a/tempest/cli/simple_read_only/test_compute.py
+++ b/tempest/cli/simple_read_only/test_nova.py
@@ -22,6 +22,7 @@
 
 import tempest.cli
 from tempest.openstack.common import log as logging
+import tempest.test
 
 CONF = cfg.CONF
 
@@ -73,7 +74,7 @@
     def test_admin_dns_domains(self):
         self.nova('dns-domains')
 
-    @testtools.skip("Test needs parameters, Bug #1157349")
+    @tempest.test.skip_because(bug="1157349")
     def test_admin_dns_list(self):
         self.nova('dns-list')
 
@@ -111,7 +112,7 @@
     def test_admin_image_list(self):
         self.nova('image-list')
 
-    @testtools.skip("Test needs parameters, Bug #1157349")
+    @tempest.test.skip_because(bug="1157349")
     def test_admin_interface_list(self):
         self.nova('interface-list')
 
@@ -136,7 +137,7 @@
     def test_admin_secgroup_list(self):
         self.nova('secgroup-list')
 
-    @testtools.skip("Test needs parameters, Bug #1157349")
+    @tempest.test.skip_because(bug="1157349")
     def test_admin_secgroup_list_rules(self):
         self.nova('secgroup-list-rules')
 
@@ -167,6 +168,10 @@
     def test_admin_net_list(self):
         self.nova('net-list')
 
+    def test_agent_list(self):
+        self.nova('agent-list')
+        self.nova('agent-list', flags='--debug')
+
     # Optional arguments:
 
     def test_admin_version(self):
diff --git a/tempest/cli/simple_read_only/test_compute_manage.py b/tempest/cli/simple_read_only/test_nova_manage.py
similarity index 92%
rename from tempest/cli/simple_read_only/test_compute_manage.py
rename to tempest/cli/simple_read_only/test_nova_manage.py
index 523c65f..9a33556 100644
--- a/tempest/cli/simple_read_only/test_compute_manage.py
+++ b/tempest/cli/simple_read_only/test_nova_manage.py
@@ -81,3 +81,11 @@
 
     def test_db_version(self):
         self.assertNotEqual("", self.nova_manage('db version'))
+
+    def test_cell_list(self):
+        # make sure command doesn't error out
+        self.nova_manage('cell list')
+
+    def test_host_list(self):
+        # make sure command doesn't error out
+        self.nova_manage('host list')
diff --git a/tempest/clients.py b/tempest/clients.py
index 63ce1ba..dd104a7 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -116,151 +116,6 @@
 
 LOG = logging.getLogger(__name__)
 
-IMAGES_CLIENTS = {
-    "json": ImagesClientJSON,
-    "xml": ImagesClientXML,
-}
-
-NETWORKS_CLIENTS = {
-    "json": NetworkClientJSON,
-    "xml": NetworkClientXML,
-}
-
-KEYPAIRS_CLIENTS = {
-    "json": KeyPairsClientJSON,
-    "xml": KeyPairsClientXML,
-}
-
-QUOTAS_CLIENTS = {
-    "json": QuotasClientJSON,
-    "xml": QuotasClientXML,
-}
-
-SERVERS_CLIENTS = {
-    "json": ServersClientJSON,
-    "xml": ServersClientXML,
-}
-
-LIMITS_CLIENTS = {
-    "json": LimitsClientJSON,
-    "xml": LimitsClientXML,
-}
-
-FLAVORS_CLIENTS = {
-    "json": FlavorsClientJSON,
-    "xml": FlavorsClientXML
-}
-
-EXTENSIONS_CLIENTS = {
-    "json": ExtensionsClientJSON,
-    "xml": ExtensionsClientXML
-}
-
-VOLUMES_EXTENSIONS_CLIENTS = {
-    "json": VolumesExtensionsClientJSON,
-    "xml": VolumesExtensionsClientXML,
-}
-
-FLOAT_CLIENTS = {
-    "json": FloatingIPsClientJSON,
-    "xml": FloatingIPsClientXML,
-}
-
-SNAPSHOTS_CLIENTS = {
-    "json": SnapshotsClientJSON,
-    "xml": SnapshotsClientXML,
-}
-
-VOLUMES_CLIENTS = {
-    "json": VolumesClientJSON,
-    "xml": VolumesClientXML,
-}
-
-VOLUME_TYPES_CLIENTS = {
-    "json": VolumeTypesClientJSON,
-    "xml": VolumeTypesClientXML,
-}
-
-IDENTITY_CLIENT = {
-    "json": IdentityClientJSON,
-    "xml": IdentityClientXML,
-}
-
-IDENTITY_V3_CLIENT = {
-    "json": IdentityV3ClientJSON,
-    "xml": IdentityV3ClientXML,
-}
-
-TOKEN_CLIENT = {
-    "json": TokenClientJSON,
-    "xml": TokenClientXML,
-}
-
-SECURITY_GROUPS_CLIENT = {
-    "json": SecurityGroupsClientJSON,
-    "xml": SecurityGroupsClientXML,
-}
-
-INTERFACES_CLIENT = {
-    "json": InterfacesClientJSON,
-    "xml": InterfacesClientXML,
-}
-
-ENDPOINT_CLIENT = {
-    "json": EndPointClientJSON,
-    "xml": EndPointClientXML,
-}
-
-FIXED_IPS_CLIENT = {
-    "json": FixedIPsClientJSON,
-    "xml": FixedIPsClientXML
-}
-
-AVAILABILITY_ZONE_CLIENT = {
-    "json": AvailabilityZoneClientJSON,
-    "xml": AvailabilityZoneClientXML,
-}
-
-SERVICE_CLIENT = {
-    "json": ServiceClientJSON,
-    "xml": ServiceClientXML,
-}
-
-AGGREGATES_CLIENT = {
-    "json": AggregatesClientJSON,
-    "xml": AggregatesClientXML,
-}
-
-SERVICES_CLIENT = {
-    "json": ServicesClientJSON,
-    "xml": ServicesClientXML,
-}
-
-TENANT_USAGES_CLIENT = {
-    "json": TenantUsagesClientJSON,
-    "xml": TenantUsagesClientXML,
-}
-
-POLICY_CLIENT = {
-    "json": PolicyClientJSON,
-    "xml": PolicyClientXML,
-}
-
-HYPERVISOR_CLIENT = {
-    "json": HypervisorClientJSON,
-    "xml": HypervisorClientXML,
-}
-
-V3_TOKEN_CLIENT = {
-    "json": V3TokenClientJSON,
-    "xml": V3TokenClientXML,
-}
-
-CREDENTIALS_CLIENT = {
-    "json": CredentialsClientJSON,
-    "xml": CredentialsClientXML,
-}
-
 
 class Manager(object):
 
@@ -308,55 +163,88 @@
         else:
             client_args_v3_auth = None
 
-        try:
-            self.servers_client = SERVERS_CLIENTS[interface](*client_args)
-            self.network_client = NETWORKS_CLIENTS[interface](*client_args)
-            self.limits_client = LIMITS_CLIENTS[interface](*client_args)
-            if self.config.service_available.glance:
-                self.images_client = IMAGES_CLIENTS[interface](*client_args)
-            self.keypairs_client = KEYPAIRS_CLIENTS[interface](*client_args)
-            self.quotas_client = QUOTAS_CLIENTS[interface](*client_args)
-            self.flavors_client = FLAVORS_CLIENTS[interface](*client_args)
-            ext_cli = EXTENSIONS_CLIENTS[interface](*client_args)
-            self.extensions_client = ext_cli
-            vol_ext_cli = VOLUMES_EXTENSIONS_CLIENTS[interface](*client_args)
-            self.volumes_extensions_client = vol_ext_cli
-            self.floating_ips_client = FLOAT_CLIENTS[interface](*client_args)
-            self.snapshots_client = SNAPSHOTS_CLIENTS[interface](*client_args)
-            self.volumes_client = VOLUMES_CLIENTS[interface](*client_args)
-            self.volume_types_client = \
-                VOLUME_TYPES_CLIENTS[interface](*client_args)
-            self.identity_client = IDENTITY_CLIENT[interface](*client_args)
-            self.identity_v3_client = \
-                IDENTITY_V3_CLIENT[interface](*client_args)
-            self.token_client = TOKEN_CLIENT[interface](self.config)
-            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)
-            self.fixed_ips_client = FIXED_IPS_CLIENT[interface](*client_args)
-            self.availability_zone_client = \
-                AVAILABILITY_ZONE_CLIENT[interface](*client_args)
-            self.service_client = SERVICE_CLIENT[interface](*client_args)
-            self.aggregates_client = AGGREGATES_CLIENT[interface](*client_args)
-            self.services_client = SERVICES_CLIENT[interface](*client_args)
-            self.tenant_usages_client = \
-                TENANT_USAGES_CLIENT[interface](*client_args)
-            self.policy_client = POLICY_CLIENT[interface](*client_args)
-            self.hypervisor_client = HYPERVISOR_CLIENT[interface](*client_args)
-            self.token_v3_client = V3_TOKEN_CLIENT[interface](*client_args)
-            self.credentials_client = \
-                CREDENTIALS_CLIENT[interface](*client_args)
+        self.servers_client_v3_auth = None
+
+        if interface == 'xml':
+            self.servers_client = ServersClientXML(*client_args)
+            self.limits_client = LimitsClientXML(*client_args)
+            self.images_client = ImagesClientXML(*client_args)
+            self.keypairs_client = KeyPairsClientXML(*client_args)
+            self.quotas_client = QuotasClientXML(*client_args)
+            self.flavors_client = FlavorsClientXML(*client_args)
+            self.extensions_client = ExtensionsClientXML(*client_args)
+            self.volumes_extensions_client = VolumesExtensionsClientXML(
+                *client_args)
+            self.floating_ips_client = FloatingIPsClientXML(*client_args)
+            self.snapshots_client = SnapshotsClientXML(*client_args)
+            self.volumes_client = VolumesClientXML(*client_args)
+            self.volume_types_client = VolumeTypesClientXML(*client_args)
+            self.identity_client = IdentityClientXML(*client_args)
+            self.identity_v3_client = IdentityV3ClientXML(*client_args)
+            self.token_client = TokenClientXML(self.config)
+            self.security_groups_client = SecurityGroupsClientXML(
+                *client_args)
+            self.interfaces_client = InterfacesClientXML(*client_args)
+            self.endpoints_client = EndPointClientXML(*client_args)
+            self.fixed_ips_client = FixedIPsClientXML(*client_args)
+            self.availability_zone_client = AvailabilityZoneClientXML(
+                *client_args)
+            self.service_client = ServiceClientXML(*client_args)
+            self.aggregates_client = AggregatesClientXML(*client_args)
+            self.services_client = ServicesClientXML(*client_args)
+            self.tenant_usages_client = TenantUsagesClientXML(*client_args)
+            self.policy_client = PolicyClientXML(*client_args)
+            self.hypervisor_client = HypervisorClientXML(*client_args)
+            self.token_v3_client = V3TokenClientXML(*client_args)
+            self.network_client = NetworkClientXML(*client_args)
+            self.credentials_client = CredentialsClientXML(*client_args)
 
             if client_args_v3_auth:
-                self.servers_client_v3_auth = SERVERS_CLIENTS[interface](
+                self.servers_client_v3_auth = ServersClientXML(
                     *client_args_v3_auth)
-            else:
-                self.servers_client_v3_auth = None
 
-        except KeyError:
+        elif interface == 'json':
+            self.servers_client = ServersClientJSON(*client_args)
+            self.limits_client = LimitsClientJSON(*client_args)
+            self.images_client = ImagesClientJSON(*client_args)
+            self.keypairs_client = KeyPairsClientJSON(*client_args)
+            self.quotas_client = QuotasClientJSON(*client_args)
+            self.flavors_client = FlavorsClientJSON(*client_args)
+            self.extensions_client = ExtensionsClientJSON(*client_args)
+            self.volumes_extensions_client = VolumesExtensionsClientJSON(
+                *client_args)
+            self.floating_ips_client = FloatingIPsClientJSON(*client_args)
+            self.snapshots_client = SnapshotsClientJSON(*client_args)
+            self.volumes_client = VolumesClientJSON(*client_args)
+            self.volume_types_client = VolumeTypesClientJSON(*client_args)
+            self.identity_client = IdentityClientJSON(*client_args)
+            self.identity_v3_client = IdentityV3ClientJSON(*client_args)
+            self.token_client = TokenClientJSON(self.config)
+            self.security_groups_client = SecurityGroupsClientJSON(
+                *client_args)
+            self.interfaces_client = InterfacesClientJSON(*client_args)
+            self.endpoints_client = EndPointClientJSON(*client_args)
+            self.fixed_ips_client = FixedIPsClientJSON(*client_args)
+            self.availability_zone_client = AvailabilityZoneClientJSON(
+                *client_args)
+            self.service_client = ServiceClientJSON(*client_args)
+            self.aggregates_client = AggregatesClientJSON(*client_args)
+            self.services_client = ServicesClientJSON(*client_args)
+            self.tenant_usages_client = TenantUsagesClientJSON(*client_args)
+            self.policy_client = PolicyClientJSON(*client_args)
+            self.hypervisor_client = HypervisorClientJSON(*client_args)
+            self.token_v3_client = V3TokenClientJSON(*client_args)
+            self.network_client = NetworkClientJSON(*client_args)
+            self.credentials_client = CredentialsClientJSON(*client_args)
+
+            if client_args_v3_auth:
+                self.servers_client_v3_auth = ServersClientJSON(
+                    *client_args_v3_auth)
+        else:
             msg = "Unsupported interface type `%s'" % interface
             raise exceptions.InvalidConfiguration(msg)
+
+        # common clients
         self.hosts_client = HostsClientJSON(*client_args)
         self.account_client = AccountClient(*client_args)
         if self.config.service_available.glance:
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index 4b5127a..9322f1b 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -488,7 +488,7 @@
         if resp.status == 409:
             if parse_resp:
                 resp_body = self._parse_resp(resp_body)
-            raise exceptions.Duplicate(resp_body)
+            raise exceptions.Conflict(resp_body)
 
         if resp.status == 413:
             if parse_resp:
@@ -519,7 +519,7 @@
                 elif 'message' in resp_body:
                     message = resp_body['message']
 
-            raise exceptions.ComputeFault(message)
+            raise exceptions.ServerFault(message)
 
         if resp.status >= 400:
             if parse_resp:
diff --git a/tempest/common/tempest_fixtures.py b/tempest/common/tempest_fixtures.py
index 081b271..ebc9ad3 100644
--- a/tempest/common/tempest_fixtures.py
+++ b/tempest/common/tempest_fixtures.py
@@ -15,16 +15,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import fixtures
-
 from tempest.openstack.common import lockutils
 
 
-class LockFixture(fixtures.Fixture):
+class LockFixture(lockutils.LockFixture):
     def __init__(self, name):
-        self.mgr = lockutils.lock(name, 'tempest-', True)
-
-    def setUp(self):
-        super(LockFixture, self).setUp()
-        self.addCleanup(self.mgr.__exit__, None, None, None)
-        self.mgr.__enter__()
+        super(LockFixture, self).__init__(name, 'tempest-')
diff --git a/tempest/common/utils/data_utils.py b/tempest/common/utils/data_utils.py
index bbba235..3ab8fe0 100644
--- a/tempest/common/utils/data_utils.py
+++ b/tempest/common/utils/data_utils.py
@@ -24,7 +24,7 @@
 
 
 def rand_name(name='test'):
-    return name + str(random.randint(1, 0x7fffffff))
+    return name + "-tempest-" + str(random.randint(1, 0x7fffffff))
 
 
 def rand_int_id(start=0, end=0x7fffffff):
diff --git a/tempest/config.py b/tempest/config.py
index eadbe9a..db923e9 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -27,6 +27,12 @@
 from tempest.openstack.common import log as logging
 
 
+def register_opt_group(conf, opt_group, options):
+    conf.register_group(opt_group)
+    for opt in options:
+        conf.register_opt(opt, group=opt_group.name)
+
+
 identity_group = cfg.OptGroup(name='identity',
                               title="Keystone Configuration Options")
 
@@ -87,13 +93,6 @@
                secret=True),
 ]
 
-
-def register_identity_opts(conf):
-    conf.register_group(identity_group)
-    for opt in IdentityGroup:
-        conf.register_opt(opt, group='identity')
-
-
 compute_group = cfg.OptGroup(name='compute',
                              title='Compute Service Options')
 
@@ -225,12 +224,6 @@
                     "an instance")
 ]
 
-
-def register_compute_opts(conf):
-    conf.register_group(compute_group)
-    for opt in ComputeGroup:
-        conf.register_opt(opt, group='compute')
-
 compute_admin_group = cfg.OptGroup(name='compute-admin',
                                    title="Compute Admin Options")
 
@@ -248,12 +241,6 @@
                secret=True),
 ]
 
-
-def register_compute_admin_opts(conf):
-    conf.register_group(compute_admin_group)
-    for opt in ComputeAdminGroup:
-        conf.register_opt(opt, group='compute-admin')
-
 image_group = cfg.OptGroup(name='image',
                            title="Image Service Options")
 
@@ -277,12 +264,6 @@
 ]
 
 
-def register_image_opts(conf):
-    conf.register_group(image_group)
-    for opt in ImageGroup:
-        conf.register_opt(opt, group='image')
-
-
 network_group = cfg.OptGroup(name='network',
                              title='Network Service Options')
 
@@ -316,12 +297,6 @@
                     "connectivity"),
 ]
 
-
-def register_network_opts(conf):
-    conf.register_group(network_group)
-    for opt in NetworkGroup:
-        conf.register_opt(opt, group='network')
-
 volume_group = cfg.OptGroup(name='volume',
                             title='Block Storage Options')
 
@@ -363,16 +338,10 @@
 ]
 
 
-def register_volume_opts(conf):
-    conf.register_group(volume_group)
-    for opt in VolumeGroup:
-        conf.register_opt(opt, group='volume')
-
-
 object_storage_group = cfg.OptGroup(name='object-storage',
                                     title='Object Storage Service Options')
 
-ObjectStoreConfig = [
+ObjectStoreGroup = [
     cfg.StrOpt('catalog_type',
                default='object-store',
                help="Catalog type of the Object-Storage service."),
@@ -404,12 +373,6 @@
 ]
 
 
-def register_object_storage_opts(conf):
-    conf.register_group(object_storage_group)
-    for opt in ObjectStoreConfig:
-        conf.register_opt(opt, group='object-storage')
-
-
 orchestration_group = cfg.OptGroup(name='orchestration',
                                    title='Orchestration Service Options')
 
@@ -447,17 +410,11 @@
                default=None,
                help="Name of existing keypair to launch servers with."),
     cfg.IntOpt('max_template_size',
-               default=10240,
+               default=32768,
                help="Value must match heat configuration of the same name."),
 ]
 
 
-def register_orchestration_opts(conf):
-    conf.register_group(orchestration_group)
-    for opt in OrchestrationGroup:
-        conf.register_opt(opt, group='orchestration')
-
-
 dashboard_group = cfg.OptGroup(name="dashboard",
                                title="Dashboard options")
 
@@ -471,15 +428,9 @@
 ]
 
 
-def register_dashboard_opts(conf):
-    conf.register_group(scenario_group)
-    for opt in DashboardGroup:
-        conf.register_opt(opt, group='dashboard')
-
-
 boto_group = cfg.OptGroup(name='boto',
                           title='EC2/S3 options')
-BotoConfig = [
+BotoGroup = [
     cfg.StrOpt('ec2_url',
                default="http://localhost:8773/services/Cloud",
                help="EC2 URL"),
@@ -523,12 +474,6 @@
                help="Status Change Test Interval"),
 ]
 
-
-def register_boto_opts(conf):
-    conf.register_group(boto_group)
-    for opt in BotoConfig:
-        conf.register_opt(opt, group='boto')
-
 stress_group = cfg.OptGroup(name='stress', title='Stress Test Options')
 
 StressGroup = [
@@ -563,12 +508,6 @@
 ]
 
 
-def register_stress_opts(conf):
-    conf.register_group(stress_group)
-    for opt in StressGroup:
-        conf.register_opt(opt, group='stress')
-
-
 scenario_group = cfg.OptGroup(name='scenario', title='Scenario Test Options')
 
 ScenarioGroup = [
@@ -596,12 +535,6 @@
 ]
 
 
-def register_scenario_opts(conf):
-    conf.register_group(scenario_group)
-    for opt in ScenarioGroup:
-        conf.register_opt(opt, group='scenario')
-
-
 service_available_group = cfg.OptGroup(name="service_available",
                                        title="Available OpenStack Services")
 
@@ -629,12 +562,6 @@
                 help="Whether or not Horizon is expected to be available"),
 ]
 
-
-def register_service_available_opts(conf):
-    conf.register_group(scenario_group)
-    for opt in ServiceAvailableGroup:
-        conf.register_opt(opt, group='service_available')
-
 debug_group = cfg.OptGroup(name="debug",
                            title="Debug System")
 
@@ -645,12 +572,6 @@
 ]
 
 
-def register_debug_opts(conf):
-    conf.register_group(debug_group)
-    for opt in DebugGroup:
-        conf.register_opt(opt, group='debug')
-
-
 @singleton
 class TempestConfig:
     """Provides OpenStack configuration information."""
@@ -689,20 +610,21 @@
         LOG = logging.getLogger('tempest')
         LOG.info("Using tempest config file %s" % path)
 
-        register_compute_opts(cfg.CONF)
-        register_identity_opts(cfg.CONF)
-        register_image_opts(cfg.CONF)
-        register_network_opts(cfg.CONF)
-        register_volume_opts(cfg.CONF)
-        register_object_storage_opts(cfg.CONF)
-        register_orchestration_opts(cfg.CONF)
-        register_dashboard_opts(cfg.CONF)
-        register_boto_opts(cfg.CONF)
-        register_compute_admin_opts(cfg.CONF)
-        register_stress_opts(cfg.CONF)
-        register_scenario_opts(cfg.CONF)
-        register_service_available_opts(cfg.CONF)
-        register_debug_opts(cfg.CONF)
+        register_opt_group(cfg.CONF, compute_group, ComputeGroup)
+        register_opt_group(cfg.CONF, identity_group, IdentityGroup)
+        register_opt_group(cfg.CONF, image_group, ImageGroup)
+        register_opt_group(cfg.CONF, network_group, NetworkGroup)
+        register_opt_group(cfg.CONF, volume_group, VolumeGroup)
+        register_opt_group(cfg.CONF, object_storage_group, ObjectStoreGroup)
+        register_opt_group(cfg.CONF, orchestration_group, OrchestrationGroup)
+        register_opt_group(cfg.CONF, dashboard_group, DashboardGroup)
+        register_opt_group(cfg.CONF, boto_group, BotoGroup)
+        register_opt_group(cfg.CONF, compute_admin_group, ComputeAdminGroup)
+        register_opt_group(cfg.CONF, stress_group, StressGroup)
+        register_opt_group(cfg.CONF, scenario_group, ScenarioGroup)
+        register_opt_group(cfg.CONF, service_available_group,
+                           ServiceAvailableGroup)
+        register_opt_group(cfg.CONF, debug_group, DebugGroup)
         self.compute = cfg.CONF.compute
         self.identity = cfg.CONF.identity
         self.images = cfg.CONF.image
diff --git a/tempest/exceptions.py b/tempest/exceptions.py
index 158a216..8d05fd8 100644
--- a/tempest/exceptions.py
+++ b/tempest/exceptions.py
@@ -129,8 +129,8 @@
     message = "Quota exceeded"
 
 
-class ComputeFault(TempestException):
-    message = "Got compute fault"
+class ServerFault(TempestException):
+    message = "Got server fault"
 
 
 class ImageFault(TempestException):
@@ -141,7 +141,7 @@
     message = "Got identity error"
 
 
-class Duplicate(RestClientException):
+class Conflict(RestClientException):
     message = "An object with that identifier already exists"
 
 
diff --git a/tempest/hacking/checks.py b/tempest/hacking/checks.py
index aa97211..4c1c107 100644
--- a/tempest/hacking/checks.py
+++ b/tempest/hacking/checks.py
@@ -19,28 +19,11 @@
 
 PYTHON_CLIENTS = ['cinder', 'glance', 'keystone', 'nova', 'swift', 'neutron']
 
-SKIP_DECORATOR_RE = re.compile(r'\s*@testtools.skip\((.*)\)')
-SKIP_STR_RE = re.compile(r'.*Bug #\d+.*')
 PYTHON_CLIENT_RE = re.compile('import (%s)client' % '|'.join(PYTHON_CLIENTS))
 TEST_DEFINITION = re.compile(r'^\s*def test.*')
 SCENARIO_DECORATOR = re.compile(r'\s*@.*services\(')
 
 
-def skip_bugs(physical_line):
-    """Check skip lines for proper bug entries
-
-    T101: skips must contain "Bug #<bug_number>"
-    """
-
-    res = SKIP_DECORATOR_RE.match(physical_line)
-    if res:
-        content = res.group(1)
-        res = SKIP_STR_RE.match(content)
-        if not res:
-            return (physical_line.find(content),
-                    'T101: skips must contain "Bug #<bug_number>"')
-
-
 def import_no_clients_in_api(physical_line, filename):
     """Check for client imports from tempest/api tests
 
@@ -70,6 +53,5 @@
 
 
 def factory(register):
-    register(skip_bugs)
     register(import_no_clients_in_api)
     register(scenario_tests_need_service_tags)
diff --git a/tempest/openstack/common/lockutils.py b/tempest/openstack/common/lockutils.py
index 0abd1a7..a55fd94 100644
--- a/tempest/openstack/common/lockutils.py
+++ b/tempest/openstack/common/lockutils.py
@@ -24,6 +24,7 @@
 import time
 import weakref
 
+import fixtures
 from oslo.config import cfg
 
 from tempest.openstack.common import fileutils
@@ -275,3 +276,36 @@
     """
 
     return functools.partial(synchronized, lock_file_prefix=lock_file_prefix)
+
+
+class LockFixture(fixtures.Fixture):
+    """External locking fixture.
+
+    This fixture is basically an alternative to the synchronized decorator with
+    the external flag so that tearDowns and addCleanups will be included in
+    the lock context for locking between tests. The fixture is recommended to
+    be the first line in a test method, like so::
+
+        def test_method(self):
+            self.useFixture(LockFixture)
+                ...
+
+    or the first line in setUp if all the test methods in the class are
+    required to be serialized. Something like::
+
+        class TestCase(testtools.testcase):
+            def setUp(self):
+                self.useFixture(LockFixture)
+                super(TestCase, self).setUp()
+                    ...
+
+    This is because addCleanups are put on a LIFO queue that gets run after the
+    test method exits. (either by completing or raising an exception)
+    """
+    def __init__(self, name, lock_file_prefix=None):
+        self.mgr = lock(name, lock_file_prefix, True)
+
+    def setUp(self):
+        super(LockFixture, self).setUp()
+        self.addCleanup(self.mgr.__exit__, None, None, None)
+        self.mgr.__enter__()
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index c4b98d5..8ccc899 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -280,16 +280,23 @@
         cls.os_resources.remove(thing)
         del cls.resource_keys[key]
 
-    def status_timeout(self, things, thing_id, expected_status):
+    def status_timeout(self, things, thing_id, expected_status,
+                       error_status='ERROR',
+                       not_found_exception=nova_exceptions.NotFound):
         """
         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.
         """
-        self._status_timeout(things, thing_id, expected_status=expected_status)
+        self._status_timeout(things, thing_id,
+                             expected_status=expected_status,
+                             error_status=error_status,
+                             not_found_exception=not_found_exception)
 
-    def delete_timeout(self, things, thing_id):
+    def delete_timeout(self, things, thing_id,
+                       error_status='ERROR',
+                       not_found_exception=nova_exceptions.NotFound):
         """
         Given a thing, do a loop, sleeping
         for a configurable amount of time, checking for the
@@ -298,13 +305,17 @@
         """
         self._status_timeout(things,
                              thing_id,
-                             allow_notfound=True)
+                             allow_notfound=True,
+                             error_status=error_status,
+                             not_found_exception=not_found_exception)
 
     def _status_timeout(self,
                         things,
                         thing_id,
                         expected_status=None,
-                        allow_notfound=False):
+                        allow_notfound=False,
+                        error_status='ERROR',
+                        not_found_exception=nova_exceptions.NotFound):
 
         log_status = expected_status if expected_status else ''
         if allow_notfound:
@@ -316,16 +327,16 @@
             # for the singular resource to retrieve.
             try:
                 thing = things.get(thing_id)
-            except nova_exceptions.NotFound:
+            except not_found_exception:
                 if allow_notfound:
                     return True
                 else:
                     raise
 
             new_status = thing.status
-            if new_status == 'ERROR':
+            if new_status == error_status:
                 message = "%s failed to get to expected status. \
-                          In ERROR state." % (thing)
+                          In %s state." % (thing, new_status)
                 raise exceptions.BuildErrorException(message)
             elif new_status == expected_status and expected_status is not None:
                 return True  # All good.
diff --git a/tempest/scenario/orchestration/test_autoscaling.py b/tempest/scenario/orchestration/test_autoscaling.py
index 658e9bb..e843793 100644
--- a/tempest/scenario/orchestration/test_autoscaling.py
+++ b/tempest/scenario/orchestration/test_autoscaling.py
@@ -12,6 +12,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import heatclient.exc as heat_exceptions
 import time
 
 from tempest.scenario import manager
@@ -74,7 +75,8 @@
 
         self.assertEqual('CREATE', self.stack.action)
         # wait for create to complete.
-        self.status_timeout(self.client.stacks, sid, 'COMPLETE')
+        self.status_timeout(self.client.stacks, sid, 'COMPLETE',
+                            error_status='FAILED')
 
         self.stack.get()
         self.assertEqual('CREATE_COMPLETE', self.stack.stack_status)
@@ -96,8 +98,10 @@
             call_until_true(lambda: server_count() == to_servers,
                             timeout, interval)
             self.assertEqual(to_servers, self.server_count,
-                             'Failed scaling from %d to %d servers' % (
-                                 from_servers, to_servers))
+                             'Failed scaling from %d to %d servers. '
+                             'Current server count: %s' % (
+                                 from_servers, to_servers,
+                                 self.server_count))
 
         # he marched them up to the top of the hill
         assertScale(1, 2)
@@ -106,3 +110,15 @@
         # and he marched them down again
         assertScale(3, 2)
         assertScale(2, 1)
+
+        # delete stack on completion
+        self.stack.delete()
+        self.status_timeout(self.client.stacks, sid, 'COMPLETE',
+                            error_status='FAILED',
+                            not_found_exception=heat_exceptions.NotFound)
+
+        try:
+            self.stack.get()
+            self.assertEqual('DELETE_COMPLETE', self.stack.stack_status)
+        except heat_exceptions.NotFound:
+            pass
diff --git a/tempest/scenario/test_large_ops.py b/tempest/scenario/test_large_ops.py
index 33b7adc..22c543b 100644
--- a/tempest/scenario/test_large_ops.py
+++ b/tempest/scenario/test_large_ops.py
@@ -24,7 +24,7 @@
 LOG = logging.getLogger(__name__)
 
 
-class TestLargeOpsScenario(manager.OfficialClientTest):
+class TestLargeOpsScenario(manager.NetworkScenarioTest):
 
     """
     Test large operations.
@@ -82,19 +82,19 @@
                                         properties=properties)
 
     def nova_boot(self):
-        def delete(servers):
-            [x.delete() for x in servers]
-
         name = rand_name('scenario-server-')
         client = self.compute_client
         flavor_id = self.config.compute.flavor_ref
+        secgroup = self._create_security_group()
         self.servers = client.servers.create(
             name=name, image=self.image,
             flavor=flavor_id,
-            min_count=self.config.scenario.large_ops_number)
+            min_count=self.config.scenario.large_ops_number,
+            security_groups=[secgroup.name])
         # needed because of bug 1199788
         self.servers = [x for x in client.servers.list() if name in x.name]
-        self.addCleanup(delete, self.servers)
+        for server in self.servers:
+            self.set_resource(server.name, server)
         self._wait_for_server_status('ACTIVE')
 
     @services('compute', 'image')
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index 4f49d65..6812d64 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -18,7 +18,6 @@
 import time
 
 from cinderclient import exceptions as cinder_exceptions
-import testtools
 
 from tempest.common.utils.data_utils import rand_name
 from tempest import exceptions
@@ -142,7 +141,7 @@
         got_timestamp = ssh_client.exec_command('sudo cat /mnt/timestamp')
         self.assertEqual(self.timestamp, got_timestamp)
 
-    @testtools.skip("Skipped until the Bug #1205344 is resolved.")
+    @tempest.test.skip_because(bug="1205344")
     @tempest.test.services('compute', 'network', 'volume', 'image')
     def test_stamp_pattern(self):
         # prepare for booting a instance
diff --git a/tempest/services/compute/json/flavors_client.py b/tempest/services/compute/json/flavors_client.py
index c3b568d..dc05e3e 100644
--- a/tempest/services/compute/json/flavors_client.py
+++ b/tempest/services/compute/json/flavors_client.py
@@ -102,6 +102,13 @@
         body = json.loads(body)
         return resp, body['extra_specs']
 
+    def get_flavor_extra_spec_with_key(self, flavor_id, key):
+        """Gets a specified key value for the mentioned flavor."""
+        resp, body = self.get('flavors/%s/os-extra_specs/%s' % (str(flavor_id),
+                              key))
+        body = json.loads(body)
+        return resp, body[key]
+
     def unset_flavor_extra_spec(self, flavor_id, key):
         """Unsets extra Specs from the mentioned flavor."""
         return self.delete('flavors/%s/os-extra_specs/%s' % (str(flavor_id),
diff --git a/tempest/services/compute/json/hypervisor_client.py b/tempest/services/compute/json/hypervisor_client.py
index e2e5c7b..fba5acb 100644
--- a/tempest/services/compute/json/hypervisor_client.py
+++ b/tempest/services/compute/json/hypervisor_client.py
@@ -63,3 +63,9 @@
         resp, body = self.get('os-hypervisors/%s/uptime' % hyper_id)
         body = json.loads(body)
         return resp, body['hypervisor']
+
+    def search_hypervisor(self, hyper_name):
+        """Search specified hypervisor."""
+        resp, body = self.get('os-hypervisors/%s/search' % hyper_name)
+        body = json.loads(body)
+        return resp, body['hypervisors']
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index 990c986..07bb6ce 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -89,7 +89,7 @@
         return resp, body['server']
 
     def update_server(self, server_id, name=None, meta=None, accessIPv4=None,
-                      accessIPv6=None):
+                      accessIPv6=None, disk_config=None):
         """
         Updates the properties of an existing server.
         server_id: The id of an existing server.
@@ -113,6 +113,9 @@
         if accessIPv6 is not None:
             post_body['accessIPv6'] = accessIPv6
 
+        if disk_config is not None:
+            post_body['OS-DCF:diskConfig'] = disk_config
+
         post_body = json.dumps({'server': post_body})
         resp, body = self.put("servers/%s" % str(server_id),
                               post_body, self.headers)
@@ -236,8 +239,11 @@
         body = json.loads(body)
         return resp, body['metadata']
 
-    def set_server_metadata(self, server_id, meta):
-        post_body = json.dumps({'metadata': meta})
+    def set_server_metadata(self, server_id, meta, no_metadata_field=False):
+        if no_metadata_field:
+            post_body = ""
+        else:
+            post_body = json.dumps({'metadata': meta})
         resp, body = self.put('servers/%s/metadata' % str(server_id),
                               post_body, self.headers)
         body = json.loads(body)
@@ -366,6 +372,11 @@
         """Unrescue the provided server."""
         return self.action(server_id, 'unrescue', None)
 
+    def get_server_diagnostics(self, server_id):
+        """Get the usage data for a server."""
+        resp, body = self.get("servers/%s/diagnostics" % str(server_id))
+        return resp, json.loads(body)
+
     def list_instance_actions(self, server_id):
         """List the provided server action."""
         resp, body = self.get("servers/%s/os-instance-actions" %
diff --git a/tempest/services/compute/xml/common.py b/tempest/services/compute/xml/common.py
index cb24917..ad79ed6 100644
--- a/tempest/services/compute/xml/common.py
+++ b/tempest/services/compute/xml/common.py
@@ -15,6 +15,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import collections
+
 XMLNS_11 = "http://docs.openstack.org/compute/api/v1.1"
 
 
@@ -34,7 +36,9 @@
         self._elements.append(element)
 
     def __str__(self):
-        args = " ".join(['%s="%s"' % (k, v) for k, v in self._attrs.items()])
+        args = " ".join(['%s="%s"' %
+                        (k, v if v is not None else "")
+                        for k, v in self._attrs.items()])
         string = '<%s %s' % (self.element_name, args)
         if not self._elements:
             string += '/>'
@@ -76,7 +80,9 @@
         Element.__init__(self, '?xml', *args, **kwargs)
 
     def __str__(self):
-        args = " ".join(['%s="%s"' % (k, v) for k, v in self._attrs.items()])
+        args = " ".join(['%s="%s"' %
+                        (k, v if v is not None else "")
+                        for k, v in self._attrs.items()])
         string = '<?xml %s?>\n' % args
         for element in self._elements:
             string += str(element)
@@ -110,3 +116,19 @@
             ns, tag = tag.split("}", 1)
         json[tag] = xml_to_json(child)
     return json
+
+
+def deep_dict_to_xml(dest, source):
+    """Populates the ``dest`` xml element with the ``source`` ``Mapping``
+       elements, if the source Mapping's value is also a ``Mapping``
+       they will be recursively added as a child elements.
+       :param source: A python ``Mapping`` (dict)
+       :param dest: XML child element will be added to the ``dest``
+    """
+    for element, content in source.iteritems():
+        if isinstance(content, collections.Mapping):
+            xml_element = Element(element)
+            deep_dict_to_xml(xml_element, content)
+            dest.append(xml_element)
+        else:
+            dest.append(Element(element, content))
diff --git a/tempest/services/compute/xml/flavors_client.py b/tempest/services/compute/xml/flavors_client.py
index c5886ee..c7ed044 100644
--- a/tempest/services/compute/xml/flavors_client.py
+++ b/tempest/services/compute/xml/flavors_client.py
@@ -148,6 +148,13 @@
         body = xml_to_json(etree.fromstring(body))
         return resp, body
 
+    def get_flavor_extra_spec_with_key(self, flavor_id, key):
+        """Gets a specified key detail for the mentioned flavor."""
+        resp, body = self.get('flavors/%s/os-extra_specs/%s' % (str(flavor_id),
+                              key), self.headers)
+        body = xml_to_json(etree.fromstring(body))
+        return resp, body
+
     def unset_flavor_extra_spec(self, flavor_id, key):
         """Unsets an extra spec based on the mentioned flavor and key."""
         return self.delete('flavors/%s/os-extra_specs/%s' % (str(flavor_id),
diff --git a/tempest/services/compute/xml/hypervisor_client.py b/tempest/services/compute/xml/hypervisor_client.py
index 3c4f2b8..c10fed9 100644
--- a/tempest/services/compute/xml/hypervisor_client.py
+++ b/tempest/services/compute/xml/hypervisor_client.py
@@ -70,3 +70,10 @@
                               self.headers)
         uptime = xml_to_json(etree.fromstring(body))
         return resp, uptime
+
+    def search_hypervisor(self, hyper_name):
+        """Search specified hypervisor."""
+        resp, body = self.get('os-hypervisors/%s/search' % hyper_name,
+                              self.headers)
+        hypervisors = self._parse_array(etree.fromstring(body))
+        return resp, hypervisors
diff --git a/tempest/services/compute/xml/servers_client.py b/tempest/services/compute/xml/servers_client.py
index c58c3ee..43de4ef 100644
--- a/tempest/services/compute/xml/servers_client.py
+++ b/tempest/services/compute/xml/servers_client.py
@@ -250,7 +250,7 @@
         return resp, {"servers": servers}
 
     def update_server(self, server_id, name=None, meta=None, accessIPv4=None,
-                      accessIPv6=None):
+                      accessIPv6=None, disk_config=None):
         doc = Document()
         server = Element("server")
         doc.append(server)
@@ -261,6 +261,10 @@
             server.add_attr("accessIPv4", accessIPv4)
         if accessIPv6 is not None:
             server.add_attr("accessIPv6", accessIPv6)
+        if disk_config is not None:
+            server.add_attr('xmlns:OS-DCF', "http://docs.openstack.org/"
+                            "compute/ext/disk_config/api/v1.1")
+            server.add_attr("OS-DCF:diskConfig", disk_config)
         if meta is not None:
             metadata = Element("metadata")
             server.append(metadata)
@@ -494,14 +498,15 @@
         body = self._parse_key_value(etree.fromstring(body))
         return resp, body
 
-    def set_server_metadata(self, server_id, meta):
+    def set_server_metadata(self, server_id, meta, no_metadata_field=False):
         doc = Document()
-        metadata = Element("metadata")
-        doc.append(metadata)
-        for k, v in meta.items():
-            meta_element = Element("meta", key=k)
-            meta_element.append(Text(v))
-            metadata.append(meta_element)
+        if not no_metadata_field:
+            metadata = Element("metadata")
+            doc.append(metadata)
+            for k, v in meta.items():
+                meta_element = Element("meta", key=k)
+                meta_element.append(Text(v))
+                metadata.append(meta_element)
         resp, body = self.put('servers/%s/metadata' % str(server_id),
                               str(doc), self.headers)
         return resp, xml_to_json(etree.fromstring(body))
@@ -575,6 +580,13 @@
                                  (server_id, volume_id), headers)
         return resp, body
 
+    def get_server_diagnostics(self, server_id):
+        """Get the usage data for a server."""
+        resp, body = self.get("servers/%s/diagnostics" % server_id,
+                              self.headers)
+        body = xml_to_json(etree.fromstring(body))
+        return resp, body
+
     def list_instance_actions(self, server_id):
         """List the provided server action."""
         resp, body = self.get("servers/%s/os-instance-actions" % server_id,
diff --git a/tempest/services/identity/json/identity_client.py b/tempest/services/identity/json/identity_client.py
index 18132ed..94045b8 100644
--- a/tempest/services/identity/json/identity_client.py
+++ b/tempest/services/identity/json/identity_client.py
@@ -139,7 +139,7 @@
         body = json.loads(body)
         return resp, body['tenant']
 
-    def create_user(self, name, password, tenant_id, email):
+    def create_user(self, name, password, tenant_id, email, **kwargs):
         """Create a user."""
         post_body = {
             'name': name,
@@ -147,6 +147,8 @@
             'tenantId': tenant_id,
             'email': email
         }
+        if kwargs.get('enabled') is not None:
+            post_body['enabled'] = kwargs.get('enabled')
         post_body = json.dumps({'user': post_body})
         resp, body = self.post('users', post_body, self.headers)
         body = json.loads(body)
diff --git a/tempest/services/identity/v3/json/identity_client.py b/tempest/services/identity/v3/json/identity_client.py
index 0a56e84..ec99d37 100644
--- a/tempest/services/identity/v3/json/identity_client.py
+++ b/tempest/services/identity/v3/json/identity_client.py
@@ -123,6 +123,30 @@
         body = json.loads(body)
         return resp, body['project']
 
+    def list_projects(self):
+        resp, body = self.get("projects")
+        body = json.loads(body)
+        return resp, body['projects']
+
+    def update_project(self, project_id, **kwargs):
+        resp, body = self.get_project(project_id)
+        name = kwargs.get('name', body['name'])
+        desc = kwargs.get('description', body['description'])
+        en = kwargs.get('enabled', body['enabled'])
+        domain_id = kwargs.get('domain_id', body['domain_id'])
+        post_body = {
+            'id': project_id,
+            'name': name,
+            'description': desc,
+            'enabled': en,
+            'domain_id': domain_id,
+        }
+        post_body = json.dumps({'project': post_body})
+        resp, body = self.patch('projects/%s' % project_id, post_body,
+                                self.headers)
+        body = json.loads(body)
+        return resp, body['project']
+
     def get_project(self, project_id):
         """GET a Project."""
         resp, body = self.get("projects/%s" % project_id)
diff --git a/tempest/services/identity/v3/xml/identity_client.py b/tempest/services/identity/v3/xml/identity_client.py
index 03e06dc..3fffc1f 100644
--- a/tempest/services/identity/v3/xml/identity_client.py
+++ b/tempest/services/identity/v3/xml/identity_client.py
@@ -163,6 +163,31 @@
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
+    def list_projects(self):
+        """Get the list of projects."""
+        resp, body = self.get("projects", self.headers)
+        body = self._parse_projects(etree.fromstring(body))
+        return resp, body
+
+    def update_project(self, project_id, **kwargs):
+        """Updates a Project."""
+        resp, body = self.get_project(project_id)
+        name = kwargs.get('name', body['name'])
+        desc = kwargs.get('description', body['description'])
+        en = kwargs.get('enabled', body['enabled'])
+        domain_id = kwargs.get('domain_id', body['domain_id'])
+        post_body = Element("project",
+                            xmlns=XMLNS,
+                            name=name,
+                            description=desc,
+                            enabled=str(en).lower(),
+                            domain_id=domain_id)
+        resp, body = self.patch('projects/%s' % project_id,
+                                str(Document(post_body)),
+                                self.headers)
+        body = self._parse_body(etree.fromstring(body))
+        return resp, body
+
     def get_project(self, project_id):
         """GET a Project."""
         resp, body = self.get("projects/%s" % project_id, self.headers)
diff --git a/tempest/services/identity/xml/identity_client.py b/tempest/services/identity/xml/identity_client.py
index 9d44826..9c0a72c 100644
--- a/tempest/services/identity/xml/identity_client.py
+++ b/tempest/services/identity/xml/identity_client.py
@@ -159,7 +159,7 @@
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
-    def create_user(self, name, password, tenant_id, email):
+    def create_user(self, name, password, tenant_id, email, **kwargs):
         """Create a user."""
         create_user = Element("user",
                               xmlns=XMLNS,
@@ -167,6 +167,9 @@
                               password=password,
                               tenantId=tenant_id,
                               email=email)
+        if 'enabled' in kwargs:
+            create_user.add_attr('enabled', str(kwargs['enabled']).lower())
+
         resp, body = self.post('users', str(Document(create_user)),
                                self.headers)
         body = self._parse_body(etree.fromstring(body))
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index 4b87b91..92c1faf 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -600,3 +600,53 @@
         resp, body = self.get(uri, headers=self.headers)
         body = json.loads(body)
         return resp, body
+
+    def list_vpn_services(self):
+        uri = '%s/vpn/vpnservices' % (self.uri_prefix)
+        resp, body = self.get(uri, self.headers)
+        body = json.loads(body)
+        return resp, body
+
+    def create_vpn_service(self, subnet_id, router_id, **kwargs):
+        post_body = {
+            "vpnservice": {
+                "subnet_id": subnet_id,
+                "router_id": router_id
+            }
+        }
+        for key, val in kwargs.items():
+            post_body['vpnservice'][key] = val
+        body = json.dumps(post_body)
+        uri = '%s/vpn/vpnservices' % (self.uri_prefix)
+        resp, body = self.post(uri, headers=self.headers, body=body)
+        body = json.loads(body)
+        return resp, body
+
+    def show_vpn_service(self, uuid):
+        uri = '%s/vpn/vpnservices/%s' % (self.uri_prefix, uuid)
+        resp, body = self.get(uri, self.headers)
+        body = json.loads(body)
+        return resp, body
+
+    def delete_vpn_service(self, uuid):
+        uri = '%s/vpn/vpnservices/%s' % (self.uri_prefix, uuid)
+        resp, body = self.delete(uri, self.headers)
+        return resp, body
+
+    def update_vpn_service(self, uuid, description):
+        put_body = {
+            "vpnservice": {
+                "description": description
+            }
+        }
+        body = json.dumps(put_body)
+        uri = '%s/vpn/vpnservices/%s' % (self.uri_prefix, uuid)
+        resp, body = self.put(uri, body=body, headers=self.headers)
+        body = json.loads(body)
+        return resp, body
+
+    def list_router_interfaces(self, uuid):
+        uri = '%s/ports?device_id=%s' % (self.uri_prefix, uuid)
+        resp, body = self.get(uri, self.headers)
+        body = json.loads(body)
+        return resp, body
diff --git a/tempest/services/network/xml/network_client.py b/tempest/services/network/xml/network_client.py
index 1523ed0..04ad86f 100755
--- a/tempest/services/network/xml/network_client.py
+++ b/tempest/services/network/xml/network_client.py
@@ -16,6 +16,7 @@
 import xml.etree.ElementTree as ET
 
 from tempest.common.rest_client import RestClientXML
+from tempest.services.compute.xml.common import deep_dict_to_xml
 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
@@ -441,6 +442,118 @@
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
+    def create_router(self, name, **kwargs):
+        uri = '%s/routers' % (self.uri_prefix)
+        router = Element("router")
+        router.append(Element("name", name))
+        deep_dict_to_xml(router, kwargs)
+        resp, body = self.post(uri, str(Document(router)), self.headers)
+        body = _root_tag_fetcher_and_xml_to_json_parse(body)
+        return resp, body
+
+    def delete_router(self, router_id):
+        uri = '%s/routers/%s' % (self.uri_prefix, router_id)
+        resp, body = self.delete(uri, self.headers)
+        return resp, body
+
+    def show_router(self, router_id):
+        uri = '%s/routers/%s' % (self.uri_prefix, router_id)
+        resp, body = self.get(uri, self.headers)
+        body = _root_tag_fetcher_and_xml_to_json_parse(body)
+        return resp, body
+
+    def update_router(self, router_id, **kwargs):
+        uri = '%s/routers/%s' % (self.uri_prefix, router_id)
+        router = Element("router")
+        for element, content in kwargs.iteritems():
+            router.append(Element(element, content))
+        resp, body = self.put(uri, str(Document(router)), self.headers)
+        body = _root_tag_fetcher_and_xml_to_json_parse(body)
+        return resp, body
+
+    def add_router_interface_with_subnet_id(self, router_id, subnet_id):
+        uri = '%s/routers/%s/add_router_interface' % (self.uri_prefix,
+              router_id)
+        subnet = Element("subnet_id", subnet_id)
+        resp, body = self.put(uri, str(Document(subnet)), self.headers)
+        body = _root_tag_fetcher_and_xml_to_json_parse(body)
+        return resp, body
+
+    def add_router_interface_with_port_id(self, router_id, port_id):
+        uri = '%s/routers/%s/add_router_interface' % (self.uri_prefix,
+              router_id)
+        port = Element("port_id", port_id)
+        resp, body = self.put(uri, str(Document(port)), self.headers)
+        body = _root_tag_fetcher_and_xml_to_json_parse(body)
+        return resp, body
+
+    def remove_router_interface_with_subnet_id(self, router_id, subnet_id):
+        uri = '%s/routers/%s/remove_router_interface' % (self.uri_prefix,
+              router_id)
+        subnet = Element("subnet_id", subnet_id)
+        resp, body = self.put(uri, str(Document(subnet)), self.headers)
+        body = _root_tag_fetcher_and_xml_to_json_parse(body)
+        return resp, body
+
+    def remove_router_interface_with_port_id(self, router_id, port_id):
+        uri = '%s/routers/%s/remove_router_interface' % (self.uri_prefix,
+              router_id)
+        port = Element("port_id", port_id)
+        resp, body = self.put(uri, str(Document(port)), self.headers)
+        body = _root_tag_fetcher_and_xml_to_json_parse(body)
+        return resp, body
+
+    def create_floating_ip(self, ext_network_id, **kwargs):
+        uri = '%s/floatingips' % (self.uri_prefix)
+        floatingip = Element('floatingip')
+        floatingip.append(Element("floating_network_id", ext_network_id))
+        for element, content in kwargs.iteritems():
+            floatingip.append(Element(element, content))
+        resp, body = self.post(uri, str(Document(floatingip)), self.headers)
+        body = _root_tag_fetcher_and_xml_to_json_parse(body)
+        return resp, body
+
+    def show_floating_ip(self, floating_ip_id):
+        uri = '%s/floatingips/%s' % (self.uri_prefix, floating_ip_id)
+        resp, body = self.get(uri, self.headers)
+        body = _root_tag_fetcher_and_xml_to_json_parse(body)
+        return resp, body
+
+    def list_floating_ips(self):
+        uri = '%s/floatingips' % (self.uri_prefix)
+        resp, body = self.get(uri, self.headers)
+        floatingips = self._parse_array(etree.fromstring(body))
+        floatingips = {"floatingips": floatingips}
+        return resp, floatingips
+
+    def delete_floating_ip(self, floating_ip_id):
+        uri = '%s/floatingips/%s' % (self.uri_prefix, floating_ip_id)
+        resp, body = self.delete(uri, self.headers)
+        return resp, body
+
+    def update_floating_ip(self, floating_ip_id, **kwargs):
+        uri = '%s/floatingips/%s' % (self.uri_prefix, floating_ip_id)
+        floatingip = Element('floatingip')
+        floatingip.add_attr('xmlns:xsi',
+                            'http://www.w3.org/2001/XMLSchema-instance')
+        for element, content in kwargs.iteritems():
+            if content is None:
+                xml_elem = Element(element)
+                xml_elem.add_attr("xsi:nil", "true")
+                floatingip.append(xml_elem)
+            else:
+                floatingip.append(Element(element, content))
+        resp, body = self.put(uri, str(Document(floatingip)), self.headers)
+        body = _root_tag_fetcher_and_xml_to_json_parse(body)
+        return resp, body
+
+    def list_router_interfaces(self, uuid):
+        uri = '%s/ports?device_id=%s' % (self.uri_prefix, uuid)
+        resp, body = self.get(uri, self.headers)
+        ports = self._parse_array(etree.fromstring(body))
+        ports = {"ports": ports}
+        return resp, ports
+
 
 def _root_tag_fetcher_and_xml_to_json_parse(xml_returned_body):
     body = ET.fromstring(xml_returned_body)
@@ -448,5 +561,10 @@
     if root_tag.startswith("{"):
         ns, root_tag = root_tag.split("}", 1)
     body = xml_to_json(etree.fromstring(xml_returned_body))
+    nil = '{http://www.w3.org/2001/XMLSchema-instance}nil'
+    for key, val in body.iteritems():
+        if isinstance(val, dict):
+            if (nil in val and val[nil] == 'true'):
+                body[key] = None
     body = {root_tag: body}
     return body
diff --git a/tempest/stress/driver.py b/tempest/stress/driver.py
index 8209f17..b5cab68 100644
--- a/tempest/stress/driver.py
+++ b/tempest/stress/driver.py
@@ -65,19 +65,20 @@
     return nodes
 
 
-def _error_in_logs(logfiles, nodes):
+def _has_error_in_logs(logfiles, nodes, stop_on_error=False):
     """
     Detect errors in the nova log files on the controller and compute nodes.
     """
     grep = 'egrep "ERROR|TRACE" %s' % logfiles
+    ret = False
     for node in nodes:
         errors = do_ssh(grep, node)
-        if not errors:
-            return None
         if len(errors) > 0:
             LOG.error('%s: %s' % (node, errors))
-            return errors
-    return None
+            ret = True
+            if stop_on_error:
+                break
+    return ret
 
 
 def sigchld_handler(signal, frame):
@@ -195,8 +196,7 @@
 
         if not logfiles:
             continue
-        errors = _error_in_logs(logfiles, computes)
-        if errors:
+        if _has_error_in_logs(logfiles, computes, stop_on_error):
             had_errors = True
             break
 
diff --git a/tempest/stress/run_stress.py b/tempest/stress/run_stress.py
index 886d94b..e5cc281 100755
--- a/tempest/stress/run_stress.py
+++ b/tempest/stress/run_stress.py
@@ -23,14 +23,20 @@
 from testtools.testsuite import iterate_tests
 from unittest import loader
 
+from tempest.openstack.common import log as logging
+
+LOG = logging.getLogger(__name__)
+
 
 def discover_stress_tests(path="./", filter_attr=None, call_inherited=False):
     """Discovers all tempest tests and create action out of them
     """
+    LOG.info("Start test discovery")
     tests = []
     testloader = loader.TestLoader()
     list = testloader.discover(path)
     for func in (iterate_tests(list)):
+        attrs = []
         try:
             method_name = getattr(func, '_testMethodName')
             full_name = "%s.%s.%s" % (func.__module__,
@@ -106,4 +112,8 @@
                    help="Name of the file with test description")
 
 if __name__ == "__main__":
-    sys.exit(main(parser.parse_args()))
+    try:
+        sys.exit(main(parser.parse_args()))
+    except Exception:
+        LOG.exception("Failure in the stress test framework")
+        sys.exit(1)
diff --git a/tempest/test.py b/tempest/test.py
index 6acb1c9..8ce7af8 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -16,6 +16,7 @@
 #    under the License.
 
 import atexit
+import functools
 import os
 import time
 
@@ -103,6 +104,24 @@
     return decorator
 
 
+def skip_because(*args, **kwargs):
+    """A decorator useful to skip tests hitting known bugs
+
+    @param bug: bug number causing the test to skip
+    @param condition: optional condition to be True for the skip to have place
+    """
+    def decorator(f):
+        @functools.wraps(f)
+        def wrapper(*func_args, **func_kwargs):
+            if "bug" in kwargs:
+                if "condition" not in kwargs or kwargs["condition"] is True:
+                    msg = "Skipped until Bug: %s is resolved." % kwargs["bug"]
+                    raise testtools.TestCase.skipException(msg)
+            return f(*func_args, **func_kwargs)
+        return wrapper
+    return decorator
+
+
 # there is a mis-match between nose and testtools for older pythons.
 # testtools will set skipException to be either
 # unittest.case.SkipTest, unittest2.case.SkipTest or an internal skip
diff --git a/tempest/tests/test_wrappers.py b/tempest/tests/test_wrappers.py
index 1a5af00..dbe3420 100644
--- a/tempest/tests/test_wrappers.py
+++ b/tempest/tests/test_wrappers.py
@@ -20,8 +20,6 @@
 import tempfile
 import testtools
 
-from tempest.test import attr
-
 DEVNULL = open(os.devnull, 'wb')
 
 
@@ -46,7 +44,6 @@
         shutil.copy('tempest/tests/files/setup.cfg', self.setup_cfg_file)
         shutil.copy('tempest/tests/files/__init__.py', self.init_file)
 
-    @attr(type='smoke')
     def test_pretty_tox(self):
         # Copy wrapper script and requirements:
         pretty_tox = os.path.join(self.directory, 'pretty_tox.sh')
@@ -62,7 +59,6 @@
                                     shell=True, stdout=DEVNULL, stderr=DEVNULL)
         self.assertEqual(exit_code, 0)
 
-    @attr(type='smoke')
     def test_pretty_tox_fails(self):
         # Copy wrapper script and requirements:
         pretty_tox = os.path.join(self.directory, 'pretty_tox.sh')
@@ -78,7 +74,6 @@
                                     stdout=DEVNULL, stderr=DEVNULL)
         self.assertEqual(exit_code, 1)
 
-    @attr(type='smoke')
     def test_pretty_tox_serial(self):
         # Copy wrapper script and requirements:
         pretty_tox = os.path.join(self.directory, 'pretty_tox_serial.sh')
@@ -90,7 +85,6 @@
                                     shell=True, stdout=DEVNULL, stderr=DEVNULL)
         self.assertEqual(exit_code, 0)
 
-    @attr(type='smoke')
     def test_pretty_tox_serial_fails(self):
         # Copy wrapper script and requirements:
         pretty_tox = os.path.join(self.directory, 'pretty_tox_serial.sh')
diff --git a/tempest/thirdparty/boto/test_ec2_instance_run.py b/tempest/thirdparty/boto/test_ec2_instance_run.py
index bce544a..0f455e1 100644
--- a/tempest/thirdparty/boto/test_ec2_instance_run.py
+++ b/tempest/thirdparty/boto/test_ec2_instance_run.py
@@ -16,7 +16,6 @@
 #    under the License.
 
 from boto import exception
-import testtools
 
 from tempest import clients
 from tempest.common.utils.data_utils import rand_name
@@ -24,6 +23,7 @@
 from tempest import exceptions
 from tempest.openstack.common import log as logging
 from tempest.test import attr
+from tempest.test import skip_because
 from tempest.thirdparty.boto.test import BotoTestCase
 from tempest.thirdparty.boto.utils.s3 import s3_upload_dir
 from tempest.thirdparty.boto.utils.wait import re_search_wait
@@ -206,8 +206,8 @@
             instance.terminate()
         self.cancelResourceCleanUp(rcuk)
 
+    @skip_because(bug="1098891")
     @attr(type='smoke')
-    @testtools.skip("Skipped until the Bug #1098891 is resolved")
     def test_run_terminate_instance(self):
         # EC2 run, terminate immediately
         image_ami = self.ec2_client.get_image(self.images["ami"]
@@ -233,7 +233,7 @@
 
     # NOTE(afazekas): doctored test case,
     # with normal validation it would fail
-    @testtools.skip("Skipped until the Bug #1182679 is resolved.")
+    @skip_because(bug="1182679")
     @attr(type='smoke')
     def test_integration_1(self):
         # EC2 1. integration test (not strict)
diff --git a/tempest/thirdparty/boto/test_ec2_keys.py b/tempest/thirdparty/boto/test_ec2_keys.py
index 85a99c0..5592d8c 100644
--- a/tempest/thirdparty/boto/test_ec2_keys.py
+++ b/tempest/thirdparty/boto/test_ec2_keys.py
@@ -15,11 +15,10 @@
 #    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 rand_name
 from tempest.test import attr
+from tempest.test import skip_because
 from tempest.thirdparty.boto.test import BotoTestCase
 
 
@@ -47,8 +46,8 @@
         self.assertTrue(compare_key_pairs(keypair,
                         self.client.get_key_pair(key_name)))
 
+    @skip_because(bug="1072318")
     @attr(type='smoke')
-    @testtools.skip("Skipped until the Bug #1072318 is resolved")
     def test_delete_ec2_keypair(self):
         # EC2 delete KeyPair
         key_name = rand_name("keypair-")
diff --git a/tempest/thirdparty/boto/test_ec2_network.py b/tempest/thirdparty/boto/test_ec2_network.py
index ae8c3c2..b4949c8 100644
--- a/tempest/thirdparty/boto/test_ec2_network.py
+++ b/tempest/thirdparty/boto/test_ec2_network.py
@@ -15,10 +15,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import testtools
-
 from tempest import clients
 from tempest.test import attr
+from tempest.test import skip_because
 from tempest.thirdparty.boto.test import BotoTestCase
 
 
@@ -30,8 +29,8 @@
         cls.os = clients.Manager()
         cls.client = cls.os.ec2api_client
 
-# Note(afazekas): these tests for things duable without an instance
-    @testtools.skip("Skipped until the Bug #1080406 is resolved")
+    # Note(afazekas): these tests for things duable without an instance
+    @skip_because(bug="1080406")
     @attr(type='smoke')
     def test_disassociate_not_associated_floating_ip(self):
         # EC2 disassociate not associated floating ip
diff --git a/tempest/thirdparty/boto/test_s3_buckets.py b/tempest/thirdparty/boto/test_s3_buckets.py
index e43cbaa..1a8fbe0 100644
--- a/tempest/thirdparty/boto/test_s3_buckets.py
+++ b/tempest/thirdparty/boto/test_s3_buckets.py
@@ -15,11 +15,10 @@
 #    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 rand_name
 from tempest.test import attr
+from tempest.test import skip_because
 from tempest.thirdparty.boto.test import BotoTestCase
 
 
@@ -31,7 +30,7 @@
         cls.os = clients.Manager()
         cls.client = cls.os.s3_client
 
-    @testtools.skip("Skipped until the Bug #1076965 is resolved")
+    @skip_because(bug="1076965")
     @attr(type='smoke')
     def test_create_and_get_delete_bucket(self):
         # S3 Create, get and delete bucket
diff --git a/tools/check_logs.py b/tools/check_logs.py
new file mode 100755
index 0000000..2ad4f70
--- /dev/null
+++ b/tools/check_logs.py
@@ -0,0 +1,155 @@
+#!/usr/bin/env python
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 Red Hat, Inc.
+# 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 argparse
+import gzip
+import os
+import re
+import StringIO
+import sys
+import urllib2
+import yaml
+
+
+def process_files(file_specs, url_specs, whitelists):
+    regexp = re.compile(r"^.*(ERROR|CRITICAL).*\[.*\-.*\]")
+    had_errors = False
+    for (name, filename) in file_specs:
+        whitelist = whitelists.get(name, [])
+        with open(filename) as content:
+            if scan_content(name, content, regexp, whitelist):
+                had_errors = True
+    for (name, url) in url_specs:
+        whitelist = whitelists.get(name, [])
+        req = urllib2.Request(url)
+        req.add_header('Accept-Encoding', 'gzip')
+        page = urllib2.urlopen(req)
+        buf = StringIO.StringIO(page.read())
+        f = gzip.GzipFile(fileobj=buf)
+        if scan_content(name, f.read().splitlines(), regexp, whitelist):
+            had_errors = True
+    return had_errors
+
+
+def scan_content(name, content, regexp, whitelist):
+    had_errors = False
+    for line in content:
+        if not line.startswith("Stderr:") and regexp.match(line):
+            whitelisted = False
+            for w in whitelist:
+                pat = ".*%s.*%s.*" % (w['module'].replace('.', '\\.'),
+                                      w['message'])
+                if re.match(pat, line):
+                    whitelisted = True
+                    break
+            if not whitelisted:
+                if not had_errors:
+                    print("Log File: %s" % name)
+                had_errors = True
+                print(line)
+    return had_errors
+
+
+def collect_url_logs(url):
+    page = urllib2.urlopen(url)
+    content = page.read()
+    logs = re.findall('(screen-[\w-]+\.txt\.gz)</a>', content)
+    return logs
+
+
+def main(opts):
+    if opts.directory and opts.url or not (opts.directory or opts.url):
+        print("Must provide exactly one of -d or -u")
+        exit(1)
+    print("Checking logs...")
+    WHITELIST_FILE = os.path.join(
+        os.path.abspath(os.path.dirname(os.path.dirname(__file__))),
+        "etc", "whitelist.yaml")
+
+    file_matcher = re.compile(r".*screen-([\w-]+)\.log")
+    files = []
+    if opts.directory:
+        d = opts.directory
+        for f in os.listdir(d):
+            files.append(os.path.join(d, f))
+    files_to_process = []
+    for f in files:
+        m = file_matcher.match(f)
+        if m:
+            files_to_process.append((m.group(1), f))
+
+    url_matcher = re.compile(r".*screen-([\w-]+)\.txt\.gz")
+    urls = []
+    if opts.url:
+        for logfile in collect_url_logs(opts.url):
+            urls.append("%s/%s" % (opts.url, logfile))
+    urls_to_process = []
+    for u in urls:
+        m = url_matcher.match(u)
+        if m:
+            urls_to_process.append((m.group(1), u))
+
+    whitelists = {}
+    with open(WHITELIST_FILE) as stream:
+        loaded = yaml.safe_load(stream)
+        if loaded:
+            for (name, l) in loaded.iteritems():
+                for w in l:
+                    assert 'module' in w, 'no module in %s' % name
+                    assert 'message' in w, 'no message in %s' % name
+            whitelists = loaded
+    if process_files(files_to_process, urls_to_process, whitelists):
+        print("Logs have errors")
+        # Return non-zero to start failing builds
+        return 0
+    else:
+        print("ok")
+        return 0
+
+usage = """
+Find non-white-listed log errors in log files from a devstack-gate run.
+Log files will be searched for ERROR or CRITICAL messages. If any
+error messages do not match any of the whitelist entries contained in
+etc/whitelist.yaml, those messages will be printed to the console and
+failure will be returned. A file directory containing logs or a url to the
+log files of an OpenStack gate job can be provided.
+
+The whitelist yaml looks like:
+
+log-name:
+    - module: "a.b.c"
+      message: "regexp"
+    - module: "a.b.c"
+      message: "regexp"
+
+repeated for each log file with a whitelist.
+"""
+
+parser = argparse.ArgumentParser(description=usage)
+parser.add_argument('-d', '--directory',
+                    help="Directory containing log files")
+parser.add_argument('-u', '--url',
+                    help="url containing logs from an OpenStack gate job")
+
+if __name__ == "__main__":
+    try:
+        sys.exit(main(parser.parse_args()))
+    except Exception as e:
+        print("Failure in script: %s" % e)
+        # Don't fail if there is a problem with the script.
+        sys.exit(0)
diff --git a/tools/find_stack_traces.py b/tools/find_stack_traces.py
index 0ce1500..52a5a66 100755
--- a/tools/find_stack_traces.py
+++ b/tools/find_stack_traces.py
@@ -65,7 +65,9 @@
 
 def hunt_for_stacktrace(url):
     """Return TRACE or ERROR lines out of logs."""
-    page = urllib2.urlopen(url)
+    req = urllib2.Request(url)
+    req.add_header('Accept-Encoding', 'gzip')
+    page = urllib2.urlopen(req)
     buf = StringIO.StringIO(page.read())
     f = gzip.GzipFile(fileobj=buf)
     content = f.read()
diff --git a/tools/skip_tracker.py b/tools/skip_tracker.py
index c38ccdb..ffaf134 100755
--- a/tools/skip_tracker.py
+++ b/tools/skip_tracker.py
@@ -61,8 +61,8 @@
     """
     Return the skip tuples in a test file
     """
-    BUG_RE = re.compile(r'.*skip.*bug:*\s*\#*(\d+)', re.IGNORECASE)
-    DEF_RE = re.compile(r'.*def (\w+)\(')
+    BUG_RE = re.compile(r'\s*@.*skip_because\(bug=[\'"](\d+)[\'"]')
+    DEF_RE = re.compile(r'\s*def (\w+)\(')
     bug_found = False
     results = []
     lines = open(path, 'rb').readlines()
diff --git a/tools/tempest_auto_config.py b/tools/tempest_auto_config.py
new file mode 100644
index 0000000..aef6a1f
--- /dev/null
+++ b/tools/tempest_auto_config.py
@@ -0,0 +1,234 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012 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.
+
+# Config
+import ConfigParser
+import os
+
+# Default client libs
+import keystoneclient.v2_0.client as keystone_client
+
+# Import Openstack exceptions
+import keystoneclient.exceptions as keystone_exception
+
+
+DEFAULT_CONFIG_DIR = "%s/etc" % os.path.abspath(os.path.pardir)
+DEFAULT_CONFIG_FILE = "tempest.conf"
+DEFAULT_CONFIG_SAMPLE = "tempest.conf.sample"
+
+# Environment variables override defaults
+TEMPEST_CONFIG_DIR = os.environ.get('TEMPEST_CONFIG_DIR') or DEFAULT_CONFIG_DIR
+TEMPEST_CONFIG = os.environ.get('TEMPEST_CONFIG') or "%s/%s" % \
+    (TEMPEST_CONFIG_DIR, DEFAULT_CONFIG_FILE)
+TEMPEST_CONFIG_SAMPLE = os.environ.get('TEMPEST_CONFIG_SAMPLE') or "%s/%s" % \
+    (TEMPEST_CONFIG_DIR, DEFAULT_CONFIG_SAMPLE)
+
+# Admin credentials
+OS_USERNAME = os.environ.get('OS_USERNAME')
+OS_PASSWORD = os.environ.get('OS_PASSWORD')
+OS_TENANT_NAME = os.environ.get('OS_TENANT_NAME')
+OS_AUTH_URL = os.environ.get('OS_AUTH_URL')
+
+# Image references
+IMAGE_ID = os.environ.get('IMAGE_ID')
+IMAGE_ID_ALT = os.environ.get('IMAGE_ID_ALT')
+
+
+class ClientManager(object):
+    """
+    Manager that provides access to the official python clients for
+    calling various OpenStack APIs.
+    """
+    def __init__(self):
+        self.identity_client = None
+        self.image_client = None
+        self.network_client = None
+        self.compute_client = None
+        self.volume_client = None
+
+    def get_identity_client(self, **kwargs):
+        """
+        Returns the openstack identity python client
+        :param username: a string representing the username
+        :param password: a string representing the user's password
+        :param tenant_name: a string representing the tenant name of the user
+        :param auth_url: a string representing the auth url of the identity
+        :param insecure: True if we wish to disable ssl certificate validation,
+        False otherwise
+        :returns an instance of openstack identity python client
+        """
+        if not self.identity_client:
+            self.identity_client = keystone_client.Client(**kwargs)
+
+        return self.identity_client
+
+
+def getTempestConfigSample():
+    """
+    Gets the tempest configuration file as a ConfigParser object
+    :return: the tempest configuration file
+    """
+    # get the sample config file from the sample
+    config_sample = ConfigParser.ConfigParser()
+    config_sample.readfp(open(TEMPEST_CONFIG_SAMPLE))
+
+    return config_sample
+
+
+def update_config_admin_credentials(config, config_section):
+    """
+    Updates the tempest config with the admin credentials
+    :param config: an object representing the tempest config file
+    :param config_section: the section name where the admin credentials are
+    """
+    # Check if credentials are present
+    if not (OS_AUTH_URL and
+            OS_USERNAME and
+            OS_PASSWORD and
+            OS_TENANT_NAME):
+        raise Exception("Admin environment variables not found.")
+
+    # TODO(tkammer): Add support for uri_v3
+    config_identity_params = {'uri': OS_AUTH_URL,
+                              'admin_username': OS_USERNAME,
+                              'admin_password': OS_PASSWORD,
+                              'admin_tenant_name': OS_TENANT_NAME}
+
+    update_config_section_with_params(config,
+                                      config_section,
+                                      config_identity_params)
+
+
+def update_config_section_with_params(config, section, params):
+    """
+    Updates a given config object with given params
+    :param config: the object representing the config file of tempest
+    :param section: the section we would like to update
+    :param params: the parameters we wish to update for that section
+    """
+    for option, value in params.items():
+        config.set(section, option, value)
+
+
+def get_identity_client_kwargs(config, section_name):
+    """
+    Get the required arguments for the identity python client
+    :param config: the tempest configuration file
+    :param section_name: the section name in the configuration where the
+    arguments can be found
+    :return: a dictionary representing the needed arguments for the identity
+    client
+    """
+    username = config.get(section_name, 'admin_username')
+    password = config.get(section_name, 'admin_password')
+    tenant_name = config.get(section_name, 'admin_tenant_name')
+    auth_url = config.get(section_name, 'uri')
+    dscv = config.get(section_name, 'disable_ssl_certificate_validation')
+    kwargs = {'username': username,
+              'password': password,
+              'tenant_name': tenant_name,
+              'auth_url': auth_url,
+              'insecure': dscv}
+
+    return kwargs
+
+
+def create_user_with_tenant(identity_client, username, password, tenant_name):
+    """
+    Creates a user using a given identity client
+    :param identity_client: openstack identity python client
+    :param username: a string representing the username
+    :param password: a string representing the user's password
+    :param tenant_name: a string representing the tenant name of the user
+    """
+    # Try to create the necessary tenant
+    tenant_id = None
+    try:
+        tenant_description = "Tenant for Tempest %s user" % username
+        tenant = identity_client.tenants.create(tenant_name,
+                                                tenant_description)
+        tenant_id = tenant.id
+    except keystone_exception.Conflict:
+
+        # if already exist, use existing tenant
+        tenant_list = identity_client.tenants.list()
+        for tenant in tenant_list:
+            if tenant.name == tenant_name:
+                tenant_id = tenant.id
+
+    # Try to create the user
+    try:
+        email = "%s@test.com" % username
+        identity_client.users.create(name=username,
+                                     password=password,
+                                     email=email,
+                                     tenant_id=tenant_id)
+    except keystone_exception.Conflict:
+
+        # if already exist, use existing user
+        pass
+
+
+def create_users_and_tenants(identity_client,
+                             config,
+                             identity_section):
+    """
+    Creates the two non admin users and tenants for tempest
+    :param identity_client: openstack identity python client
+    :param config: tempest configuration file
+    :param identity_section: the section name of identity in the config
+    """
+    # Get the necessary params from the config file
+    tenant_name = config.get(identity_section, 'tenant_name')
+    username = config.get(identity_section, 'username')
+    password = config.get(identity_section, 'password')
+
+    alt_tenant_name = config.get(identity_section, 'alt_tenant_name')
+    alt_username = config.get(identity_section, 'alt_username')
+    alt_password = config.get(identity_section, 'alt_password')
+
+    # Create the necessary users for the test runs
+    create_user_with_tenant(identity_client, username, password, tenant_name)
+    create_user_with_tenant(identity_client, alt_username, alt_password,
+                            alt_tenant_name)
+
+
+def main():
+    """
+    Main module to control the script
+    """
+    # TODO(tkammer): add support for existing config file
+    config_sample = getTempestConfigSample()
+    update_config_admin_credentials(config_sample, 'identity')
+
+    client_manager = ClientManager()
+
+    # Set the identity related info for tempest
+    identity_client_kwargs = get_identity_client_kwargs(config_sample,
+                                                        'identity')
+    identity_client = client_manager.get_identity_client(
+        **identity_client_kwargs)
+
+    # Create the necessary users and tenants for tempest run
+    create_users_and_tenants(identity_client,
+                             config_sample,
+                             'identity')
+
+    # TODO(tkammer): add image implementation
+
+if __name__ == "__main__":
+    main()
diff --git a/tox.ini b/tox.ini
index abc9e42..d93112c 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,11 +1,23 @@
 [tox]
 envlist = pep8
+minversion = 1.6
+skipsdist = True
 
 [testenv]
 setenv = VIRTUAL_ENV={envdir}
          LANG=en_US.UTF-8
          LANGUAGE=en_US:en
          LC_ALL=C
+usedevelop = True
+
+[testenv:py26]
+commands = python setup.py test --slowest --testr-arg='tempest\.tests {posargs}'
+
+[testenv:py33]
+commands = python setup.py test --slowest --testr-arg='tempest\.tests {posargs}'
+
+[testenv:py27]
+commands = python setup.py test --slowest --testr-arg='tempest\.tests {posargs}'
 
 [testenv:all]
 sitepackages = True
@@ -15,29 +27,25 @@
 
 [testenv:full]
 sitepackages = True
-setenv = VIRTUAL_ENV={envdir}
 # The regex below is used to select which tests to run and exclude the slow tag:
 # See the testrepostiory bug: https://bugs.launchpad.net/testrepository/+bug/1208610
 commands =
-  sh tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty|cli|tests)) {posargs}'
+  sh tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty|cli)) {posargs}'
 
 [testenv:testr-full]
 sitepackages = True
-setenv = VIRTUAL_ENV={envdir}
 commands =
-  sh tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty|cli|tests)) {posargs}'
+  sh tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty|cli)) {posargs}'
 
 [testenv:heat-slow]
 sitepackages = True
-setenv = VIRTUAL_ENV={envdir}
-         OS_TEST_TIMEOUT=1200
+setenv = OS_TEST_TIMEOUT=1200
 # The regex below is used to select heat api/scenario tests tagged as slow.
 commands =
   sh tools/pretty_tox_serial.sh '(?=.*\[.*\bslow\b.*\])(^tempest\.(api|scenario)\.orchestration) {posargs}'
 
 [testenv:large-ops]
 sitepackages = True
-setenv = VIRTUAL_ENV={envdir}
 commands =
   python setup.py testr --slowest --testr-args='tempest.scenario.test_large_ops {posargs}'
 
@@ -51,8 +59,9 @@
          NOSE_OPENSTACK_YELLOW=3
          NOSE_OPENSTACK_SHOW_ELAPSED=1
          NOSE_OPENSTACK_STDOUT=1
+         TEMPEST_PY26_NOSE_COMPAT=1
 commands =
-  nosetests --logging-format '%(asctime)-15s %(message)s' --with-xunit -sv --xunit-file=nosetests-full.xml tempest/api tempest/scenario tempest/thirdparty tempest/cli tempest/tests {posargs}
+  nosetests --logging-format '%(asctime)-15s %(message)s' --with-xunit -sv --xunit-file=nosetests-full.xml tempest/api tempest/scenario tempest/thirdparty tempest/cli {posargs}
 
 [testenv:py26-smoke]
 setenv = VIRTUAL_ENV={envdir}
@@ -62,12 +71,12 @@
          NOSE_OPENSTACK_YELLOW=3
          NOSE_OPENSTACK_SHOW_ELAPSED=1
          NOSE_OPENSTACK_STDOUT=1
+         TEMPEST_PY26_NOSE_COMPAT=1
 commands =
   nosetests --logging-format '%(asctime)-15s %(message)s' --with-xunit -sv --attr=type=smoke --xunit-file=nosetests-smoke.xml tempest {posargs}
 
 [testenv:smoke]
 sitepackages = True
-setenv = VIRTUAL_ENV={envdir}
 # This is still serial because neutron doesn't work with parallel. See:
 # https://bugs.launchpad.net/tempest/+bug/1216076 so the neutron smoke
 # job would fail if we moved it to parallel.
@@ -76,15 +85,13 @@
 
 [testenv:coverage]
 sitepackages = True
-setenv = VIRTUAL_ENV={envdir}
 commands =
    python -m tools/tempest_coverage -c start --combine
-   sh tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty|cli|tests))'
+   sh tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty|cli))'
    python -m tools/tempest_coverage -c report --html {posargs}
 
 [testenv:stress]
 sitepackages = True
-setenv = VIRTUAL_ENV={envdir}
 commands =
     python -m tempest/stress/run_stress -a -d 3600 -S