Merge "Extend network debug infos on network failures"
diff --git a/.gitignore b/.gitignore
index 0f4880f..8d2b281 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,3 +15,5 @@
 dist
 build
 .testrepository
+.coverage
+cover/
diff --git a/etc/logging.conf.sample b/etc/logging.conf.sample
index 3b468f1..cdeedef 100644
--- a/etc/logging.conf.sample
+++ b/etc/logging.conf.sample
@@ -1,46 +1,40 @@
 [loggers]
-keys=root,tempest,tempest_stress
+keys=root,tempest_stress
 
 [handlers]
-keys=file,syslog,devel
+keys=file,devel,syslog
 
 [formatters]
-keys=default,tests
+keys=simple,tests
 
 [logger_root]
-level=NOTSET
-handlers=syslog
-
-[logger_tempest]
 level=DEBUG
 handlers=file
-qualname=tempest
 
 [logger_tempest_stress]
-level=INFO
+level=DEBUG
 handlers=file,devel
 qualname=tempest.stress
 
 [handler_file]
 class=FileHandler
 level=DEBUG
+args=('tempest.log', 'w+')
 formatter=tests
-args=('tempest.log', 'w')
 
 [handler_syslog]
 class=handlers.SysLogHandler
 level=ERROR
-formatter = default
 args = ('/dev/log', handlers.SysLogHandler.LOG_USER)
 
 [handler_devel]
 class=StreamHandler
 level=DEBUG
-formatter=default
 args=(sys.stdout,)
-
-[formatter_default]
-format=%(name)s: %(levelname)s: %(message)s
+formatter=simple
 
 [formatter_tests]
-class = tempest.common.log.TestsFormatter
+class = tempest.openstack.common.log.ContextFormatter
+
+[formatter_simple]
+format=%(asctime)s.%(msecs)03d %(process)d %(levelname)s: %(message)s
diff --git a/etc/schemas/compute/admin/flavor_create.json b/etc/schemas/compute/admin/flavor_create.json
new file mode 100644
index 0000000..0a3e7b3
--- /dev/null
+++ b/etc/schemas/compute/admin/flavor_create.json
@@ -0,0 +1,20 @@
+{
+    "name": "flavor-create",
+    "http-method": "POST",
+    "admin_client": true,
+    "url": "flavors",
+    "default_result_code": 400,
+    "json-schema": {
+        "type": "object",
+        "properties": {
+            "name": { "type": "string"},
+            "ram": { "type": "integer", "minimum": 1},
+            "vcpus": { "type": "integer", "minimum": 1},
+            "disk": { "type": "integer"},
+            "id": { "type": "integer"},
+            "swap": { "type": "integer"},
+            "rxtx_factor": { "type": "integer"},
+            "OS-FLV-EXT-DATA:ephemeral": { "type": "integer"}
+        }
+    }
+}
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 0f18f5e..d75de90 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -105,6 +105,10 @@
 # value)
 #catalog_type=baremetal
 
+# The endpoint type to use for the baremetal provisioning
+# service. (string value)
+#endpoint_type=publicURL
+
 
 [boto]
 
@@ -165,6 +169,11 @@
 # value)
 #cli_dir=/usr/local/bin
 
+# Whether the tempest run location has access to the *-manage
+# commands. In a pure blackbox environment it will not.
+# (boolean value)
+#has_manage=true
+
 # Number of seconds to wait on a CLI timeout (integer value)
 #timeout=15
 
@@ -350,6 +359,10 @@
 # iSCSI volumes (boolean value)
 #block_migrate_cinder_iscsi=false
 
+# Enable VNC console. This configuration value should be same
+# as [nova.vnc]->vnc_enabled in nova.conf (boolean value)
+#vnc_console=false
+
 
 [dashboard]
 
@@ -373,6 +386,24 @@
 # Catalog type of the data processing service. (string value)
 #catalog_type=data_processing
 
+# The endpoint type to use for the data processing service.
+# (string value)
+#endpoint_type=publicURL
+
+
+[database]
+
+#
+# Options defined in tempest.config
+#
+
+# Catalog type of the Database service. (string value)
+#catalog_type=database
+
+# Valid primary flavor to use in database tests. (string
+# value)
+#db_flavor_ref=1
+
 
 [debug]
 
@@ -531,6 +562,16 @@
 #ssh_user_regex=[["^.*[Cc]irros.*$", "root"]]
 
 
+[negative]
+
+#
+# Options defined in tempest.config
+#
+
+# Test generator class for all negative tests (string value)
+#test_generator=tempest.common.generator.negative_generator.NegativeTestGenerator
+
+
 [network]
 
 #
@@ -557,9 +598,6 @@
 # The mask bits for tenant ipv4 subnets (integer value)
 #tenant_network_mask_bits=28
 
-# Allow the execution of IPv6 tests (boolean value)
-#ipv6_enabled=true
-
 # The cidr block to allocate tenant ipv6 subnets from (string
 # value)
 #tenant_network_v6_cidr=2003::/64
@@ -579,6 +617,14 @@
 # (string value)
 #public_router_id=
 
+# Timeout in seconds to wait for network operation to
+# complete. (integer value)
+#build_timeout=300
+
+# Time in seconds between network operation status checks.
+# (integer value)
+#build_interval=10
+
 
 [network-feature-enabled]
 
@@ -586,6 +632,9 @@
 # Options defined in tempest.config
 #
 
+# Allow the execution of IPv6 tests (boolean value)
+#ipv6=true
+
 # A list of enabled network extensions with a special entry
 # all which indicates every extension is enabled (list value)
 #api_extensions=all
@@ -622,6 +671,9 @@
 # creating containers (string value)
 #operator_role=Member
 
+# User role that has reseller admin (string value)
+#reseller_admin_role=ResellerAdmin
+
 
 [object-storage-feature-enabled]
 
@@ -659,7 +711,7 @@
 
 # Timeout in seconds to wait for a stack to build. (integer
 # value)
-#build_timeout=300
+#build_timeout=600
 
 # Instance type for tests. Needs to be big enough for a full
 # OS plus the test workload (string value)
@@ -678,6 +730,16 @@
 #max_template_size=524288
 
 
+[queuing]
+
+#
+# Options defined in tempest.config
+#
+
+# Catalog type of the Queuing service. (string value)
+#catalog_type=queuing
+
+
 [scenario]
 
 #
@@ -753,6 +815,14 @@
 # value)
 #ironic=false
 
+# Whether or not Trove is expected to be available (boolean
+# value)
+#trove=false
+
+# Whether or not Marconi is expected to be available (boolean
+# value)
+#marconi=false
+
 
 [stress]
 
@@ -811,6 +881,10 @@
 # Catalog type of the Telemetry service. (string value)
 #catalog_type=metering
 
+# The endpoint type to use for the telemetry service. (string
+# value)
+#endpoint_type=publicURL
+
 
 [volume]
 
diff --git a/requirements.txt b/requirements.txt
index 8573a2e..48d1b12 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,6 +1,5 @@
-pbr>=0.5.21,<1.0
+pbr>=0.6,<1.0
 anyjson>=0.3.3
-nose
 httplib2>=0.7.5
 jsonschema>=2.0.0,<3.0.0
 testtools>=0.9.34
@@ -9,18 +8,18 @@
 paramiko>=1.9.0
 netaddr>=0.7.6
 python-glanceclient>=0.9.0
-python-keystoneclient>=0.4.2
-python-novaclient>=2.15.0
-python-neutronclient>=2.3.3,<3
+python-keystoneclient>=0.6.0
+python-novaclient>=2.17.0
+python-neutronclient>=2.3.4,<3
 python-cinderclient>=1.0.6
 python-heatclient>=0.2.3
-python-savannaclient>=0.4.1
-python-swiftclient>=1.5
+python-savannaclient>=0.5.0
+python-swiftclient>=1.6
 testresources>=0.2.4
 keyring>=1.6.1,<2.0,>=2.1
-testrepository>=0.0.17
+testrepository>=0.0.18
 oslo.config>=1.2.0
-six>=1.4.1
+six>=1.5.2
 iso8601>=0.1.8
 fixtures>=0.3.14
 testscenarios>=0.4
diff --git a/run_tempest.sh b/run_tempest.sh
index f6c330d..bdd1f69 100755
--- a/run_tempest.sh
+++ b/run_tempest.sh
@@ -53,12 +53,12 @@
     -u|--update) update=1;;
     -d|--debug) debug=1;;
     -C|--config) config_file=$2; shift;;
-    -s|--smoke) testrargs+="smoke"; noseargs+="--attr=type=smoke";;
+    -s|--smoke) testrargs+="smoke";;
     -t|--serial) serial=1;;
     -l|--logging) logging=1;;
     -L|--logging-config) logging_config=$2; shift;;
     --) [ "yes" == "$first_uu" ] || testrargs="$testrargs $1"; first_uu=no  ;;
-    *) testrargs="$testrargs $1"; noseargs+=" $1" ;;
+    *) testrargs+="$testrargs $1";;
   esac
   shift
 done
@@ -110,22 +110,6 @@
   fi
 }
 
-function run_tests_nose {
-    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
-        noseargs="$noseargs tempest"
-    fi
-    ${wrapper} nosetests $noseargs
-}
-
 if [ $never_venv -eq 0 ]
 then
   # Remove the virtual environment if --force used
@@ -156,12 +140,7 @@
   fi
 fi
 
-py_version=`${wrapper} python --version 2>&1`
-if [[ $py_version =~ "2.6" ]] ; then
-    run_tests_nose
-else
-    run_tests
-fi
+run_tests
 retval=$?
 
 exit $retval
diff --git a/run_tests.sh b/run_tests.sh
index c807f79..a12bf46 100755
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -54,7 +54,7 @@
     -c|--coverage) coverage=1;;
     -t|--serial) serial=1;;
     --) [ "yes" == "$first_uu" ] || testrargs="$testrargs $1"; first_uu=no  ;;
-    *) testrargs="$testrargs $1"; noseargs+=" $1" ;;
+    *) testrargs="$testrargs $1";;
   esac
   shift
 done
diff --git a/tempest/api/compute/admin/test_aggregates.py b/tempest/api/compute/admin/test_aggregates.py
index 08d8a0d..fb249e5 100644
--- a/tempest/api/compute/admin/test_aggregates.py
+++ b/tempest/api/compute/admin/test_aggregates.py
@@ -16,7 +16,7 @@
 from tempest.api.compute import base
 from tempest.common import tempest_fixtures as fixtures
 from tempest.common.utils import data_utils
-from tempest.test import attr
+from tempest import test
 
 
 class AggregatesAdminTestJSON(base.BaseV2ComputeAdminTest):
@@ -26,7 +26,6 @@
     """
 
     _host_key = 'OS-EXT-SRV-ATTR:host'
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -40,20 +39,20 @@
                     filter(lambda y: y['service'] == 'compute', hosts_all))
         cls.host = hosts[0]
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_aggregate_create_delete(self):
         # Create and delete an aggregate.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
         resp, aggregate = self.client.create_aggregate(name=aggregate_name)
         self.assertEqual(200, resp.status)
         self.assertEqual(aggregate_name, aggregate['name'])
-        self.assertEqual(None, aggregate['availability_zone'])
+        self.assertIsNone(aggregate['availability_zone'])
 
         resp, _ = self.client.delete_aggregate(aggregate['id'])
         self.assertEqual(200, resp.status)
         self.client.wait_for_resource_deletion(aggregate['id'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_aggregate_create_delete_with_az(self):
         # Create and delete an aggregate.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -68,7 +67,7 @@
         self.assertEqual(200, resp.status)
         self.client.wait_for_resource_deletion(aggregate['id'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_aggregate_create_verify_entry_in_list(self):
         # Create an aggregate and ensure it is listed.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -81,7 +80,7 @@
                       map(lambda x: (x['id'], x['availability_zone']),
                           aggregates))
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_aggregate_create_update_metadata_get_details(self):
         # Create an aggregate and ensure its details are returned.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -106,7 +105,7 @@
         self.assertEqual(200, resp.status)
         self.assertEqual(meta, body["metadata"])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_aggregate_create_update_with_az(self):
         # Update an aggregate and ensure properties are updated correctly
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -138,7 +137,7 @@
                          (x['id'], x['name'], x['availability_zone']),
                           aggregates))
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_aggregate_add_remove_host(self):
         # Add an host to the given aggregate and remove.
         self.useFixture(fixtures.LockFixture('availability_zone'))
@@ -160,7 +159,7 @@
                          body['availability_zone'])
         self.assertNotIn(self.host, body['hosts'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_aggregate_add_host_list(self):
         # Add an host to the given aggregate and list.
         self.useFixture(fixtures.LockFixture('availability_zone'))
@@ -175,10 +174,10 @@
         self.assertEqual(1, len(aggs))
         agg = aggs[0]
         self.assertEqual(aggregate_name, agg['name'])
-        self.assertEqual(None, agg['availability_zone'])
+        self.assertIsNone(agg['availability_zone'])
         self.assertIn(self.host, agg['hosts'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_aggregate_add_host_get_details(self):
         # Add an host to the given aggregate and get details.
         self.useFixture(fixtures.LockFixture('availability_zone'))
@@ -190,10 +189,10 @@
 
         resp, body = self.client.get_aggregate(aggregate['id'])
         self.assertEqual(aggregate_name, body['name'])
-        self.assertEqual(None, body['availability_zone'])
+        self.assertIsNone(body['availability_zone'])
         self.assertIn(self.host, body['hosts'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_aggregate_add_host_create_server_with_az(self):
         # Add an host to the given aggregate and create a server.
         self.useFixture(fixtures.LockFixture('availability_zone'))
diff --git a/tempest/api/compute/admin/test_aggregates_negative.py b/tempest/api/compute/admin/test_aggregates_negative.py
index 7d92532..690f2ab 100644
--- a/tempest/api/compute/admin/test_aggregates_negative.py
+++ b/tempest/api/compute/admin/test_aggregates_negative.py
@@ -17,7 +17,7 @@
 from tempest.common import tempest_fixtures as fixtures
 from tempest.common.utils import data_utils
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class AggregatesAdminNegativeTestJSON(base.BaseV2ComputeAdminTest):
@@ -26,8 +26,6 @@
     Tests Aggregates API that require admin privileges
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(AggregatesAdminNegativeTestJSON, cls).setUpClass()
@@ -41,7 +39,7 @@
                     filter(lambda y: y['service'] == 'compute', hosts_all))
         cls.host = hosts[0]
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_create_as_user(self):
         # Regular user is not allowed to create an aggregate.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -49,14 +47,14 @@
                           self.user_client.create_aggregate,
                           name=aggregate_name)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_create_aggregate_name_length_less_than_1(self):
         # the length of aggregate name should >= 1 and <=255
         self.assertRaises(exceptions.BadRequest,
                           self.client.create_aggregate,
                           name='')
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_create_aggregate_name_length_exceeds_255(self):
         # the length of aggregate name should >= 1 and <=255
         aggregate_name = 'a' * 256
@@ -64,7 +62,7 @@
                           self.client.create_aggregate,
                           name=aggregate_name)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_create_with_existent_aggregate_name(self):
         # creating an aggregate with existent aggregate name is forbidden
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -76,7 +74,7 @@
                           self.client.create_aggregate,
                           name=aggregate_name)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_delete_as_user(self):
         # Regular user is not allowed to delete an aggregate.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -88,13 +86,13 @@
                           self.user_client.delete_aggregate,
                           aggregate['id'])
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_list_as_user(self):
         # Regular user is not allowed to list aggregates.
         self.assertRaises(exceptions.Unauthorized,
                           self.user_client.list_aggregates)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_get_details_as_user(self):
         # Regular user is not allowed to get aggregate details.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -106,19 +104,19 @@
                           self.user_client.get_aggregate,
                           aggregate['id'])
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_delete_with_invalid_id(self):
         # Delete an aggregate with invalid id should raise exceptions.
         self.assertRaises(exceptions.NotFound,
                           self.client.delete_aggregate, -1)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_get_details_with_invalid_id(self):
         # Get aggregate details with invalid id should raise exceptions.
         self.assertRaises(exceptions.NotFound,
                           self.client.get_aggregate, -1)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_add_non_exist_host(self):
         # Adding a non-exist host to an aggregate should raise exceptions.
         resp, hosts_all = self.os_adm.hosts_client.list_hosts()
@@ -135,7 +133,7 @@
         self.assertRaises(exceptions.NotFound, self.client.add_host,
                           aggregate['id'], non_exist_host)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_add_host_as_user(self):
         # Regular user is not allowed to add a host to an aggregate.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -147,7 +145,7 @@
                           self.user_client.add_host,
                           aggregate['id'], self.host)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_add_existent_host(self):
         self.useFixture(fixtures.LockFixture('availability_zone'))
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -162,7 +160,7 @@
         self.assertRaises(exceptions.Conflict, self.client.add_host,
                           aggregate['id'], self.host)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_remove_host_as_user(self):
         # Regular user is not allowed to remove a host from an aggregate.
         self.useFixture(fixtures.LockFixture('availability_zone'))
@@ -178,7 +176,7 @@
                           self.user_client.remove_host,
                           aggregate['id'], self.host)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_aggregate_remove_nonexistent_host(self):
         non_exist_host = data_utils.rand_name('nonexist_host_')
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
diff --git a/tempest/api/compute/admin/test_availability_zone.py b/tempest/api/compute/admin/test_availability_zone.py
index 283a45a..3c06624 100644
--- a/tempest/api/compute/admin/test_availability_zone.py
+++ b/tempest/api/compute/admin/test_availability_zone.py
@@ -14,7 +14,7 @@
 #    under the License.
 
 from tempest.api.compute import base
-from tempest.test import attr
+from tempest import test
 
 
 class AZAdminTestJSON(base.BaseV2ComputeAdminTest):
@@ -23,21 +23,19 @@
     Tests Availability Zone API List
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(AZAdminTestJSON, cls).setUpClass()
         cls.client = cls.os_adm.availability_zone_client
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_availability_zone_list(self):
         # List of availability zone
         resp, availability_zone = self.client.get_availability_zone_list()
         self.assertEqual(200, resp.status)
         self.assertTrue(len(availability_zone) > 0)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_availability_zone_list_detail(self):
         # List of availability zones and available services
         resp, availability_zone = \
diff --git a/tempest/api/compute/admin/test_availability_zone_negative.py b/tempest/api/compute/admin/test_availability_zone_negative.py
index d13618c..ce97491 100644
--- a/tempest/api/compute/admin/test_availability_zone_negative.py
+++ b/tempest/api/compute/admin/test_availability_zone_negative.py
@@ -14,7 +14,7 @@
 
 from tempest.api.compute import base
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class AZAdminNegativeTestJSON(base.BaseV2ComputeAdminTest):
@@ -23,14 +23,12 @@
     Tests Availability Zone API List
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(AZAdminNegativeTestJSON, cls).setUpClass()
         cls.non_adm_client = cls.availability_zone_client
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_get_availability_zone_list_detail_with_non_admin_user(self):
         # List of availability zones and available services with
         # non-administrator user
diff --git a/tempest/api/compute/admin/test_fixed_ips.py b/tempest/api/compute/admin/test_fixed_ips.py
index cfb2f0e..b0692b1 100644
--- a/tempest/api/compute/admin/test_fixed_ips.py
+++ b/tempest/api/compute/admin/test_fixed_ips.py
@@ -15,13 +15,12 @@
 
 from tempest.api.compute import base
 from tempest import config
-from tempest.test import attr
+from tempest import test
 
 CONF = config.CONF
 
 
 class FixedIPsTestJson(base.BaseV2ComputeAdminTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -40,18 +39,18 @@
             if cls.ip:
                 break
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_fixed_ip_details(self):
         resp, fixed_ip = self.client.get_fixed_ip_details(self.ip)
         self.assertEqual(fixed_ip['address'], self.ip)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_set_reserve(self):
         body = {"reserve": "None"}
         resp, body = self.client.reserve_fixed_ip(self.ip, body)
         self.assertEqual(resp.status, 202)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_set_unreserve(self):
         body = {"unreserve": "None"}
         resp, body = self.client.reserve_fixed_ip(self.ip, body)
diff --git a/tempest/api/compute/admin/test_fixed_ips_negative.py b/tempest/api/compute/admin/test_fixed_ips_negative.py
index def9810..3fb3829 100644
--- a/tempest/api/compute/admin/test_fixed_ips_negative.py
+++ b/tempest/api/compute/admin/test_fixed_ips_negative.py
@@ -15,13 +15,12 @@
 from tempest.api.compute import base
 from tempest import config
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 CONF = config.CONF
 
 
 class FixedIPsNegativeTestJson(base.BaseV2ComputeAdminTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -41,26 +40,26 @@
             if cls.ip:
                 break
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_list_fixed_ip_details_with_non_admin_user(self):
         self.assertRaises(exceptions.Unauthorized,
                           self.non_admin_client.get_fixed_ip_details, self.ip)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_set_reserve_with_non_admin_user(self):
         body = {"reserve": "None"}
         self.assertRaises(exceptions.Unauthorized,
                           self.non_admin_client.reserve_fixed_ip,
                           self.ip, body)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_set_unreserve_with_non_admin_user(self):
         body = {"unreserve": "None"}
         self.assertRaises(exceptions.Unauthorized,
                           self.non_admin_client.reserve_fixed_ip,
                           self.ip, body)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_set_reserve_with_invalid_ip(self):
         # NOTE(maurosr): since this exercises the same code snippet, we do it
         # only for reserve action
@@ -69,7 +68,7 @@
                           self.client.reserve_fixed_ip,
                           "my.invalid.ip", body)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_fixed_ip_with_invalid_action(self):
         body = {"invalid_action": "None"}
         self.assertRaises(exceptions.BadRequest,
diff --git a/tempest/api/compute/admin/test_flavors.py b/tempest/api/compute/admin/test_flavors.py
index 3e13bf8..05b763a 100644
--- a/tempest/api/compute/admin/test_flavors.py
+++ b/tempest/api/compute/admin/test_flavors.py
@@ -27,8 +27,6 @@
     Tests Flavors API Create and Delete that require admin privileges
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(FlavorsAdminTestJSON, cls).setUpClass()
diff --git a/tempest/api/compute/admin/test_flavors_access.py b/tempest/api/compute/admin/test_flavors_access.py
index da11ab5..4804ce4 100644
--- a/tempest/api/compute/admin/test_flavors_access.py
+++ b/tempest/api/compute/admin/test_flavors_access.py
@@ -25,8 +25,6 @@
     Add and remove Flavor Access require admin privileges.
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(FlavorsAccessTestJSON, cls).setUpClass()
diff --git a/tempest/api/compute/admin/test_flavors_access_negative.py b/tempest/api/compute/admin/test_flavors_access_negative.py
index c4d54b6..8fe3331 100644
--- a/tempest/api/compute/admin/test_flavors_access_negative.py
+++ b/tempest/api/compute/admin/test_flavors_access_negative.py
@@ -28,8 +28,6 @@
     Add and remove Flavor Access require admin privileges.
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(FlavorsAccessNegativeTestJSON, cls).setUpClass()
diff --git a/tempest/api/compute/admin/test_flavors_extra_specs.py b/tempest/api/compute/admin/test_flavors_extra_specs.py
index 1afa693..91145ec 100644
--- a/tempest/api/compute/admin/test_flavors_extra_specs.py
+++ b/tempest/api/compute/admin/test_flavors_extra_specs.py
@@ -26,8 +26,6 @@
     GET Flavor Extra specs can be performed even by without admin privileges.
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(FlavorsExtraSpecsTestJSON, cls).setUpClass()
diff --git a/tempest/api/compute/admin/test_flavors_extra_specs_negative.py b/tempest/api/compute/admin/test_flavors_extra_specs_negative.py
index cdf97cc..a139c2f 100644
--- a/tempest/api/compute/admin/test_flavors_extra_specs_negative.py
+++ b/tempest/api/compute/admin/test_flavors_extra_specs_negative.py
@@ -27,8 +27,6 @@
     SET, UNSET, UPDATE Flavor Extra specs require admin privileges.
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(FlavorsExtraSpecsNegativeTestJSON, cls).setUpClass()
diff --git a/tempest/api/compute/admin/test_flavors_negative.py b/tempest/api/compute/admin/test_flavors_negative.py
index ad4ceeb..b882ff4 100644
--- a/tempest/api/compute/admin/test_flavors_negative.py
+++ b/tempest/api/compute/admin/test_flavors_negative.py
@@ -13,6 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import testscenarios
 import uuid
 
 from tempest.api.compute import base
@@ -20,6 +21,8 @@
 from tempest import exceptions
 from tempest import test
 
+load_tests = testscenarios.load_tests_apply_scenarios
+
 
 class FlavorsAdminNegativeTestJSON(base.BaseV2ComputeAdminTest):
 
@@ -27,8 +30,6 @@
     Tests Flavors API Create and Delete that require admin privileges
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(FlavorsAdminNegativeTestJSON, cls).setUpClass()
@@ -46,11 +47,6 @@
         cls.swap = 1024
         cls.rxtx = 2
 
-    def flavor_clean_up(self, flavor_id):
-        resp, body = self.client.delete_flavor(flavor_id)
-        self.assertEqual(resp.status, 202)
-        self.client.wait_for_resource_deletion(flavor_id)
-
     @test.attr(type=['negative', 'gate'])
     def test_get_flavor_details_for_deleted_flavor(self):
         # Delete a flavor and ensure it is not listed
@@ -87,13 +83,6 @@
         self.assertTrue(flag)
 
     @test.attr(type=['negative', 'gate'])
-    def test_invalid_is_public_string(self):
-        # the 'is_public' parameter can be 'none/true/false' if it exists
-        self.assertRaises(exceptions.BadRequest,
-                          self.client.list_flavors_with_detail,
-                          {'is_public': 'invalid'})
-
-    @test.attr(type=['negative', 'gate'])
     def test_create_flavor_as_user(self):
         # only admin user can create a flavor
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@@ -112,231 +101,16 @@
                           self.user_client.delete_flavor,
                           self.flavor_ref_alt)
 
-    @test.attr(type=['negative', 'gate'])
-    def test_create_flavor_using_invalid_ram(self):
-        # the 'ram' attribute must be positive integer
-        flavor_name = data_utils.rand_name(self.flavor_name_prefix)
-        new_flavor_id = str(uuid.uuid4())
 
-        self.assertRaises(exceptions.BadRequest,
-                          self.client.create_flavor,
-                          flavor_name, -1, self.vcpus,
-                          self.disk, new_flavor_id)
+class FlavorCreateNegativeTestJSON(base.BaseV2ComputeAdminTest,
+                                   test.NegativeAutoTest):
+    _interface = 'json'
+    _service = 'compute'
+    _schema_file = 'compute/admin/flavor_create.json'
+
+    scenarios = test.NegativeAutoTest.generate_scenario(_schema_file)
 
     @test.attr(type=['negative', 'gate'])
-    def test_create_flavor_using_invalid_vcpus(self):
-        # the 'vcpu' attribute must be positive integer
-        flavor_name = data_utils.rand_name(self.flavor_name_prefix)
-        new_flavor_id = str(uuid.uuid4())
-
-        self.assertRaises(exceptions.BadRequest,
-                          self.client.create_flavor,
-                          flavor_name, self.ram, -1,
-                          self.disk, new_flavor_id)
-
-    @test.attr(type=['negative', 'gate'])
-    def test_create_flavor_with_name_length_less_than_1(self):
-        # ensure name length >= 1
-        new_flavor_id = str(uuid.uuid4())
-
-        self.assertRaises(exceptions.BadRequest,
-                          self.client.create_flavor,
-                          '',
-                          self.ram, self.vcpus,
-                          self.disk,
-                          new_flavor_id,
-                          ephemeral=self.ephemeral,
-                          swap=self.swap,
-                          rxtx=self.rxtx,
-                          is_public='False')
-
-    @test.attr(type=['negative', 'gate'])
-    def test_create_flavor_with_name_length_exceeds_255(self):
-        # ensure name do not exceed 255 characters
-        new_flavor_name = 'a' * 256
-        new_flavor_id = str(uuid.uuid4())
-
-        self.assertRaises(exceptions.BadRequest,
-                          self.client.create_flavor,
-                          new_flavor_name,
-                          self.ram, self.vcpus,
-                          self.disk,
-                          new_flavor_id,
-                          ephemeral=self.ephemeral,
-                          swap=self.swap,
-                          rxtx=self.rxtx,
-                          is_public='False')
-
-    @test.attr(type=['negative', 'gate'])
-    def test_create_flavor_with_invalid_name(self):
-        # the regex of flavor_name is '^[\w\.\- ]*$'
-        invalid_flavor_name = data_utils.rand_name('invalid-!@#$%-')
-        new_flavor_id = str(uuid.uuid4())
-
-        self.assertRaises(exceptions.BadRequest,
-                          self.client.create_flavor,
-                          invalid_flavor_name,
-                          self.ram, self.vcpus,
-                          self.disk,
-                          new_flavor_id,
-                          ephemeral=self.ephemeral,
-                          swap=self.swap,
-                          rxtx=self.rxtx,
-                          is_public='False')
-
-    @test.attr(type=['negative', 'gate'])
-    def test_create_flavor_with_invalid_flavor_id(self):
-        # the regex of flavor_id is '^[\w\.\- ]*$', and it cannot contain
-        # leading and/or trailing whitespace
-        new_flavor_name = data_utils.rand_name(self.flavor_name_prefix)
-        invalid_flavor_id = '!@#$%'
-
-        self.assertRaises(exceptions.BadRequest,
-                          self.client.create_flavor,
-                          new_flavor_name,
-                          self.ram, self.vcpus,
-                          self.disk,
-                          invalid_flavor_id,
-                          ephemeral=self.ephemeral,
-                          swap=self.swap,
-                          rxtx=self.rxtx,
-                          is_public='False')
-
-    @test.attr(type=['negative', 'gate'])
-    def test_create_flavor_with_id_length_exceeds_255(self):
-        # the length of flavor_id should not exceed 255 characters
-        new_flavor_name = data_utils.rand_name(self.flavor_name_prefix)
-        invalid_flavor_id = 'a' * 256
-
-        self.assertRaises(exceptions.BadRequest,
-                          self.client.create_flavor,
-                          new_flavor_name,
-                          self.ram, self.vcpus,
-                          self.disk,
-                          invalid_flavor_id,
-                          ephemeral=self.ephemeral,
-                          swap=self.swap,
-                          rxtx=self.rxtx,
-                          is_public='False')
-
-    @test.attr(type=['negative', 'gate'])
-    def test_create_flavor_with_invalid_root_gb(self):
-        # root_gb attribute should be non-negative ( >= 0) integer
-        new_flavor_name = data_utils.rand_name(self.flavor_name_prefix)
-        new_flavor_id = str(uuid.uuid4())
-
-        self.assertRaises(exceptions.BadRequest,
-                          self.client.create_flavor,
-                          new_flavor_name,
-                          self.ram, self.vcpus,
-                          -1,
-                          new_flavor_id,
-                          ephemeral=self.ephemeral,
-                          swap=self.swap,
-                          rxtx=self.rxtx,
-                          is_public='False')
-
-    @test.attr(type=['negative', 'gate'])
-    def test_create_flavor_with_invalid_ephemeral_gb(self):
-        # ephemeral_gb attribute should be non-negative ( >= 0) integer
-        new_flavor_name = data_utils.rand_name(self.flavor_name_prefix)
-        new_flavor_id = str(uuid.uuid4())
-
-        self.assertRaises(exceptions.BadRequest,
-                          self.client.create_flavor,
-                          new_flavor_name,
-                          self.ram, self.vcpus,
-                          self.disk,
-                          new_flavor_id,
-                          ephemeral=-1,
-                          swap=self.swap,
-                          rxtx=self.rxtx,
-                          is_public='False')
-
-    @test.attr(type=['negative', 'gate'])
-    def test_create_flavor_with_invalid_swap(self):
-        # swap attribute should be non-negative ( >= 0) integer
-        new_flavor_name = data_utils.rand_name(self.flavor_name_prefix)
-        new_flavor_id = str(uuid.uuid4())
-
-        self.assertRaises(exceptions.BadRequest,
-                          self.client.create_flavor,
-                          new_flavor_name,
-                          self.ram, self.vcpus,
-                          self.disk,
-                          new_flavor_id,
-                          ephemeral=self.ephemeral,
-                          swap=-1,
-                          rxtx=self.rxtx,
-                          is_public='False')
-
-    @test.attr(type=['negative', 'gate'])
-    def test_create_flavor_with_invalid_rxtx_factor(self):
-        # rxtx_factor attribute should be a positive float
-        new_flavor_name = data_utils.rand_name(self.flavor_name_prefix)
-        new_flavor_id = str(uuid.uuid4())
-
-        self.assertRaises(exceptions.BadRequest,
-                          self.client.create_flavor,
-                          new_flavor_name,
-                          self.ram, self.vcpus,
-                          self.disk,
-                          new_flavor_id,
-                          ephemeral=self.ephemeral,
-                          swap=self.swap,
-                          rxtx=-1.5,
-                          is_public='False')
-
-    @test.attr(type=['negative', 'gate'])
-    def test_create_flavor_with_invalid_is_public(self):
-        # is_public attribute should be boolean
-        new_flavor_name = data_utils.rand_name(self.flavor_name_prefix)
-        new_flavor_id = str(uuid.uuid4())
-
-        self.assertRaises(exceptions.BadRequest,
-                          self.client.create_flavor,
-                          new_flavor_name,
-                          self.ram, self.vcpus,
-                          self.disk,
-                          new_flavor_id,
-                          ephemeral=self.ephemeral,
-                          swap=self.swap,
-                          rxtx=self.rxtx,
-                          is_public='Invalid')
-
-    @test.attr(type=['negative', 'gate'])
-    def test_create_flavor_already_exists(self):
-        flavor_name = data_utils.rand_name(self.flavor_name_prefix)
-        new_flavor_id = str(uuid.uuid4())
-
-        resp, flavor = self.client.create_flavor(flavor_name,
-                                                 self.ram, self.vcpus,
-                                                 self.disk,
-                                                 new_flavor_id,
-                                                 ephemeral=self.ephemeral,
-                                                 swap=self.swap,
-                                                 rxtx=self.rxtx)
-        self.assertEqual(200, resp.status)
-        self.addCleanup(self.flavor_clean_up, flavor['id'])
-
-        self.assertRaises(exceptions.Conflict,
-                          self.client.create_flavor,
-                          flavor_name,
-                          self.ram, self.vcpus,
-                          self.disk,
-                          new_flavor_id,
-                          ephemeral=self.ephemeral,
-                          swap=self.swap,
-                          rxtx=self.rxtx)
-
-    @test.attr(type=['negative', 'gate'])
-    def test_delete_nonexistent_flavor(self):
-        nonexistent_flavor_id = str(uuid.uuid4())
-
-        self.assertRaises(exceptions.NotFound,
-                          self.client.delete_flavor,
-                          nonexistent_flavor_id)
-
-
-class FlavorsAdminNegativeTestXML(FlavorsAdminNegativeTestJSON):
-    _interface = 'xml'
+    def test_create_flavor(self):
+        # flavor details are not returned for non-existent flavors
+        self.execute(self._schema_file)
diff --git a/tempest/api/compute/admin/test_flavors_negative_xml.py b/tempest/api/compute/admin/test_flavors_negative_xml.py
new file mode 100644
index 0000000..a06b0e6
--- /dev/null
+++ b/tempest/api/compute/admin/test_flavors_negative_xml.py
@@ -0,0 +1,268 @@
+# 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.
+
+import uuid
+
+from tempest.api.compute.admin import test_flavors_negative
+from tempest.common.utils import data_utils
+from tempest import exceptions
+from tempest import test
+
+
+class FlavorsAdminNegativeTestXML(test_flavors_negative.
+                                  FlavorsAdminNegativeTestJSON):
+
+    """
+    Tests Flavors API Create and Delete that require admin privileges
+    """
+
+    _interface = 'xml'
+
+    def flavor_clean_up(self, flavor_id):
+        resp, body = self.client.delete_flavor(flavor_id)
+        self.assertEqual(resp.status, 202)
+        self.client.wait_for_resource_deletion(flavor_id)
+
+    @test.attr(type=['negative', 'gate'])
+    def test_invalid_is_public_string(self):
+        # the 'is_public' parameter can be 'none/true/false' if it exists
+        self.assertRaises(exceptions.BadRequest,
+                          self.client.list_flavors_with_detail,
+                          {'is_public': 'invalid'})
+
+    @test.attr(type=['negative', 'gate'])
+    def test_create_flavor_using_invalid_ram(self):
+        # the 'ram' attribute must be positive integer
+        flavor_name = data_utils.rand_name(self.flavor_name_prefix)
+        new_flavor_id = str(uuid.uuid4())
+
+        self.assertRaises(exceptions.BadRequest,
+                          self.client.create_flavor,
+                          flavor_name, -1, self.vcpus,
+                          self.disk, new_flavor_id)
+
+    @test.attr(type=['negative', 'gate'])
+    def test_create_flavor_using_invalid_vcpus(self):
+        # the 'vcpu' attribute must be positive integer
+        flavor_name = data_utils.rand_name(self.flavor_name_prefix)
+        new_flavor_id = str(uuid.uuid4())
+
+        self.assertRaises(exceptions.BadRequest,
+                          self.client.create_flavor,
+                          flavor_name, self.ram, -1,
+                          self.disk, new_flavor_id)
+
+    @test.attr(type=['negative', 'gate'])
+    def test_create_flavor_with_name_length_less_than_1(self):
+        # ensure name length >= 1
+        new_flavor_id = str(uuid.uuid4())
+
+        self.assertRaises(exceptions.BadRequest,
+                          self.client.create_flavor,
+                          '',
+                          self.ram, self.vcpus,
+                          self.disk,
+                          new_flavor_id,
+                          ephemeral=self.ephemeral,
+                          swap=self.swap,
+                          rxtx=self.rxtx,
+                          is_public='False')
+
+    @test.attr(type=['negative', 'gate'])
+    def test_create_flavor_with_name_length_exceeds_255(self):
+        # ensure name do not exceed 255 characters
+        new_flavor_name = 'a' * 256
+        new_flavor_id = str(uuid.uuid4())
+
+        self.assertRaises(exceptions.BadRequest,
+                          self.client.create_flavor,
+                          new_flavor_name,
+                          self.ram, self.vcpus,
+                          self.disk,
+                          new_flavor_id,
+                          ephemeral=self.ephemeral,
+                          swap=self.swap,
+                          rxtx=self.rxtx,
+                          is_public='False')
+
+    @test.attr(type=['negative', 'gate'])
+    def test_create_flavor_with_invalid_name(self):
+        # the regex of flavor_name is '^[\w\.\- ]*$'
+        invalid_flavor_name = data_utils.rand_name('invalid-!@#$%-')
+        new_flavor_id = str(uuid.uuid4())
+
+        self.assertRaises(exceptions.BadRequest,
+                          self.client.create_flavor,
+                          invalid_flavor_name,
+                          self.ram, self.vcpus,
+                          self.disk,
+                          new_flavor_id,
+                          ephemeral=self.ephemeral,
+                          swap=self.swap,
+                          rxtx=self.rxtx,
+                          is_public='False')
+
+    @test.attr(type=['negative', 'gate'])
+    def test_create_flavor_with_invalid_flavor_id(self):
+        # the regex of flavor_id is '^[\w\.\- ]*$', and it cannot contain
+        # leading and/or trailing whitespace
+        new_flavor_name = data_utils.rand_name(self.flavor_name_prefix)
+        invalid_flavor_id = '!@#$%'
+
+        self.assertRaises(exceptions.BadRequest,
+                          self.client.create_flavor,
+                          new_flavor_name,
+                          self.ram, self.vcpus,
+                          self.disk,
+                          invalid_flavor_id,
+                          ephemeral=self.ephemeral,
+                          swap=self.swap,
+                          rxtx=self.rxtx,
+                          is_public='False')
+
+    @test.attr(type=['negative', 'gate'])
+    def test_create_flavor_with_id_length_exceeds_255(self):
+        # the length of flavor_id should not exceed 255 characters
+        new_flavor_name = data_utils.rand_name(self.flavor_name_prefix)
+        invalid_flavor_id = 'a' * 256
+
+        self.assertRaises(exceptions.BadRequest,
+                          self.client.create_flavor,
+                          new_flavor_name,
+                          self.ram, self.vcpus,
+                          self.disk,
+                          invalid_flavor_id,
+                          ephemeral=self.ephemeral,
+                          swap=self.swap,
+                          rxtx=self.rxtx,
+                          is_public='False')
+
+    @test.attr(type=['negative', 'gate'])
+    def test_create_flavor_with_invalid_root_gb(self):
+        # root_gb attribute should be non-negative ( >= 0) integer
+        new_flavor_name = data_utils.rand_name(self.flavor_name_prefix)
+        new_flavor_id = str(uuid.uuid4())
+
+        self.assertRaises(exceptions.BadRequest,
+                          self.client.create_flavor,
+                          new_flavor_name,
+                          self.ram, self.vcpus,
+                          -1,
+                          new_flavor_id,
+                          ephemeral=self.ephemeral,
+                          swap=self.swap,
+                          rxtx=self.rxtx,
+                          is_public='False')
+
+    @test.attr(type=['negative', 'gate'])
+    def test_create_flavor_with_invalid_ephemeral_gb(self):
+        # ephemeral_gb attribute should be non-negative ( >= 0) integer
+        new_flavor_name = data_utils.rand_name(self.flavor_name_prefix)
+        new_flavor_id = str(uuid.uuid4())
+
+        self.assertRaises(exceptions.BadRequest,
+                          self.client.create_flavor,
+                          new_flavor_name,
+                          self.ram, self.vcpus,
+                          self.disk,
+                          new_flavor_id,
+                          ephemeral=-1,
+                          swap=self.swap,
+                          rxtx=self.rxtx,
+                          is_public='False')
+
+    @test.attr(type=['negative', 'gate'])
+    def test_create_flavor_with_invalid_swap(self):
+        # swap attribute should be non-negative ( >= 0) integer
+        new_flavor_name = data_utils.rand_name(self.flavor_name_prefix)
+        new_flavor_id = str(uuid.uuid4())
+
+        self.assertRaises(exceptions.BadRequest,
+                          self.client.create_flavor,
+                          new_flavor_name,
+                          self.ram, self.vcpus,
+                          self.disk,
+                          new_flavor_id,
+                          ephemeral=self.ephemeral,
+                          swap=-1,
+                          rxtx=self.rxtx,
+                          is_public='False')
+
+    @test.attr(type=['negative', 'gate'])
+    def test_create_flavor_with_invalid_rxtx_factor(self):
+        # rxtx_factor attribute should be a positive float
+        new_flavor_name = data_utils.rand_name(self.flavor_name_prefix)
+        new_flavor_id = str(uuid.uuid4())
+
+        self.assertRaises(exceptions.BadRequest,
+                          self.client.create_flavor,
+                          new_flavor_name,
+                          self.ram, self.vcpus,
+                          self.disk,
+                          new_flavor_id,
+                          ephemeral=self.ephemeral,
+                          swap=self.swap,
+                          rxtx=-1.5,
+                          is_public='False')
+
+    @test.attr(type=['negative', 'gate'])
+    def test_create_flavor_with_invalid_is_public(self):
+        # is_public attribute should be boolean
+        new_flavor_name = data_utils.rand_name(self.flavor_name_prefix)
+        new_flavor_id = str(uuid.uuid4())
+
+        self.assertRaises(exceptions.BadRequest,
+                          self.client.create_flavor,
+                          new_flavor_name,
+                          self.ram, self.vcpus,
+                          self.disk,
+                          new_flavor_id,
+                          ephemeral=self.ephemeral,
+                          swap=self.swap,
+                          rxtx=self.rxtx,
+                          is_public='Invalid')
+
+    @test.attr(type=['negative', 'gate'])
+    def test_create_flavor_already_exists(self):
+        flavor_name = data_utils.rand_name(self.flavor_name_prefix)
+        new_flavor_id = str(uuid.uuid4())
+
+        resp, flavor = self.client.create_flavor(flavor_name,
+                                                 self.ram, self.vcpus,
+                                                 self.disk,
+                                                 new_flavor_id,
+                                                 ephemeral=self.ephemeral,
+                                                 swap=self.swap,
+                                                 rxtx=self.rxtx)
+        self.assertEqual(200, resp.status)
+        self.addCleanup(self.flavor_clean_up, flavor['id'])
+
+        self.assertRaises(exceptions.Conflict,
+                          self.client.create_flavor,
+                          flavor_name,
+                          self.ram, self.vcpus,
+                          self.disk,
+                          new_flavor_id,
+                          ephemeral=self.ephemeral,
+                          swap=self.swap,
+                          rxtx=self.rxtx)
+
+    @test.attr(type=['negative', 'gate'])
+    def test_delete_nonexistent_flavor(self):
+        nonexistent_flavor_id = str(uuid.uuid4())
+
+        self.assertRaises(exceptions.NotFound,
+                          self.client.delete_flavor,
+                          nonexistent_flavor_id)
diff --git a/tempest/api/compute/admin/test_hosts.py b/tempest/api/compute/admin/test_hosts.py
index a3b4b47..e612566 100644
--- a/tempest/api/compute/admin/test_hosts.py
+++ b/tempest/api/compute/admin/test_hosts.py
@@ -14,7 +14,7 @@
 
 from tempest.api.compute import base
 from tempest.common import tempest_fixtures as fixtures
-from tempest.test import attr
+from tempest import test
 
 
 class HostsAdminTestJSON(base.BaseV2ComputeAdminTest):
@@ -23,20 +23,18 @@
     Tests hosts API using admin privileges.
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(HostsAdminTestJSON, cls).setUpClass()
         cls.client = cls.os_adm.hosts_client
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_hosts(self):
         resp, hosts = self.client.list_hosts()
         self.assertEqual(200, resp.status)
         self.assertTrue(len(hosts) >= 2, str(hosts))
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_hosts_with_zone(self):
         self.useFixture(fixtures.LockFixture('availability_zone'))
         resp, hosts = self.client.list_hosts()
@@ -48,7 +46,7 @@
         self.assertTrue(len(hosts) >= 1)
         self.assertIn(host, hosts)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_hosts_with_a_blank_zone(self):
         # If send the request with a blank zone, the request will be successful
         # and it will return all the hosts list
@@ -57,7 +55,7 @@
         self.assertNotEqual(0, len(hosts))
         self.assertEqual(200, resp.status)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_hosts_with_nonexistent_zone(self):
         # If send the request with a nonexistent zone, the request will be
         # successful and no hosts will be retured
@@ -66,7 +64,7 @@
         self.assertEqual(0, len(hosts))
         self.assertEqual(200, resp.status)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_show_host_detail(self):
         resp, hosts = self.client.list_hosts()
         self.assertEqual(200, resp.status)
diff --git a/tempest/api/compute/admin/test_hosts_negative.py b/tempest/api/compute/admin/test_hosts_negative.py
index cb034c9..0f26e84 100644
--- a/tempest/api/compute/admin/test_hosts_negative.py
+++ b/tempest/api/compute/admin/test_hosts_negative.py
@@ -24,8 +24,6 @@
     Tests hosts API using admin privileges.
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(HostsAdminNegativeTestJSON, cls).setUpClass()
diff --git a/tempest/api/compute/admin/test_hypervisor.py b/tempest/api/compute/admin/test_hypervisor.py
index 989c0d8..48f9ffb 100644
--- a/tempest/api/compute/admin/test_hypervisor.py
+++ b/tempest/api/compute/admin/test_hypervisor.py
@@ -14,7 +14,7 @@
 #    under the License.
 
 from tempest.api.compute import base
-from tempest.test import attr
+from tempest import test
 
 
 class HypervisorAdminTestJSON(base.BaseV2ComputeAdminTest):
@@ -23,8 +23,6 @@
     Tests Hypervisors API that require admin privileges
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(HypervisorAdminTestJSON, cls).setUpClass()
@@ -39,20 +37,20 @@
     def assertHypervisors(self, hypers):
         self.assertTrue(len(hypers) > 0, "No hypervisors found: %s" % hypers)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_hypervisor_list(self):
         # List of hypervisor and available hypervisors hostname
         hypers = self._list_hypervisors()
         self.assertHypervisors(hypers)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_hypervisor_list_details(self):
         # Display the details of the all hypervisor
         resp, hypers = self.client.get_hypervisor_list_details()
         self.assertEqual(200, resp.status)
         self.assertHypervisors(hypers)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_hypervisor_show_details(self):
         # Display the details of the specified hypervisor
         hypers = self._list_hypervisors()
@@ -65,7 +63,7 @@
         self.assertEqual(details['hypervisor_hostname'],
                          hypers[0]['hypervisor_hostname'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_hypervisor_show_servers(self):
         # Show instances about the specific hypervisors
         hypers = self._list_hypervisors()
@@ -76,14 +74,14 @@
         self.assertEqual(200, resp.status)
         self.assertTrue(len(hypervisors) > 0)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_hypervisor_stats(self):
         # Verify the stats of the all hypervisor
         resp, stats = self.client.get_hypervisor_stats()
         self.assertEqual(200, resp.status)
         self.assertTrue(len(stats) > 0)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_hypervisor_uptime(self):
         # Verify that GET shows the specified hypervisor uptime
         hypers = self._list_hypervisors()
@@ -103,7 +101,7 @@
             has_valid_uptime,
             "None of the hypervisors had a valid uptime: %s" % hypers)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_search_hypervisor(self):
         hypers = self._list_hypervisors()
         self.assertHypervisors(hypers)
diff --git a/tempest/api/compute/admin/test_hypervisor_negative.py b/tempest/api/compute/admin/test_hypervisor_negative.py
index e41bd18..4ba8d30 100644
--- a/tempest/api/compute/admin/test_hypervisor_negative.py
+++ b/tempest/api/compute/admin/test_hypervisor_negative.py
@@ -18,7 +18,7 @@
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class HypervisorAdminNegativeTestJSON(base.BaseV2ComputeAdminTest):
@@ -27,8 +27,6 @@
     Tests Hypervisors API that require admin privileges
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(HypervisorAdminNegativeTestJSON, cls).setUpClass()
@@ -41,7 +39,7 @@
         self.assertEqual(200, resp.status)
         return hypers
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_show_nonexistent_hypervisor(self):
         nonexistent_hypervisor_id = str(uuid.uuid4())
 
@@ -50,7 +48,7 @@
             self.client.get_hypervisor_show_details,
             nonexistent_hypervisor_id)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_show_hypervisor_with_non_admin_user(self):
         hypers = self._list_hypervisors()
         self.assertTrue(len(hypers) > 0)
@@ -60,7 +58,7 @@
             self.non_adm_client.get_hypervisor_show_details,
             hypers[0]['id'])
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_show_servers_with_non_admin_user(self):
         hypers = self._list_hypervisors()
         self.assertTrue(len(hypers) > 0)
@@ -70,7 +68,7 @@
             self.non_adm_client.get_hypervisor_servers,
             hypers[0]['id'])
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_show_servers_with_nonexistent_hypervisor(self):
         nonexistent_hypervisor_id = str(uuid.uuid4())
 
@@ -79,13 +77,13 @@
             self.client.get_hypervisor_servers,
             nonexistent_hypervisor_id)
 
-    @attr(type=['negative', 'gate'])
+    @test.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'])
+    @test.attr(type=['negative', 'gate'])
     def test_get_nonexistent_hypervisor_uptime(self):
         nonexistent_hypervisor_id = str(uuid.uuid4())
 
@@ -94,7 +92,7 @@
             self.client.get_hypervisor_uptime,
             nonexistent_hypervisor_id)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_get_hypervisor_uptime_with_non_admin_user(self):
         hypers = self._list_hypervisors()
         self.assertTrue(len(hypers) > 0)
@@ -104,21 +102,21 @@
             self.non_adm_client.get_hypervisor_uptime,
             hypers[0]['id'])
 
-    @attr(type=['negative', 'gate'])
+    @test.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'])
+    @test.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'])
+    @test.attr(type=['negative', 'gate'])
     def test_search_nonexistent_hypervisor(self):
         nonexistent_hypervisor_name = data_utils.rand_name('test_hypervisor')
 
@@ -127,7 +125,7 @@
             self.client.search_hypervisor,
             nonexistent_hypervisor_name)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_search_hypervisor_with_non_admin_user(self):
         hypers = self._list_hypervisors()
         self.assertTrue(len(hypers) > 0)
diff --git a/tempest/api/compute/admin/test_instance_usage_audit_log.py b/tempest/api/compute/admin/test_instance_usage_audit_log.py
index c617178..32c8656 100644
--- a/tempest/api/compute/admin/test_instance_usage_audit_log.py
+++ b/tempest/api/compute/admin/test_instance_usage_audit_log.py
@@ -16,20 +16,18 @@
 import datetime
 
 from tempest.api.compute import base
-from tempest.test import attr
+from tempest import test
 import urllib
 
 
 class InstanceUsageAuditLogTestJSON(base.BaseV2ComputeAdminTest):
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(InstanceUsageAuditLogTestJSON, cls).setUpClass()
         cls.adm_client = cls.os_adm.instance_usages_audit_log_client
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_instance_usage_audit_logs(self):
         # list instance usage audit logs
         resp, body = self.adm_client.list_instance_usage_audit_logs()
@@ -42,7 +40,7 @@
         for item in expected_items:
             self.assertIn(item, body)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_instance_usage_audit_log(self):
         # Get instance usage audit log before specified time
         now = datetime.datetime.now()
diff --git a/tempest/api/compute/admin/test_instance_usage_audit_log_negative.py b/tempest/api/compute/admin/test_instance_usage_audit_log_negative.py
index 10bb1aa..fe4a184 100644
--- a/tempest/api/compute/admin/test_instance_usage_audit_log_negative.py
+++ b/tempest/api/compute/admin/test_instance_usage_audit_log_negative.py
@@ -17,20 +17,18 @@
 
 from tempest.api.compute import base
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 import urllib
 
 
 class InstanceUsageAuditLogNegativeTestJSON(base.BaseV2ComputeAdminTest):
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(InstanceUsageAuditLogNegativeTestJSON, cls).setUpClass()
         cls.adm_client = cls.os_adm.instance_usages_audit_log_client
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_instance_usage_audit_logs_with_nonadmin_user(self):
         # the instance_usage_audit_logs API just can be accessed by admin user
         self.assertRaises(exceptions.Unauthorized,
@@ -42,7 +40,7 @@
                           get_instance_usage_audit_log,
                           urllib.quote(now.strftime("%Y-%m-%d %H:%M:%S")))
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_get_instance_usage_audit_logs_with_invalid_time(self):
         self.assertRaises(exceptions.BadRequest,
                           self.adm_client.get_instance_usage_audit_log,
diff --git a/tempest/api/compute/admin/test_quotas.py b/tempest/api/compute/admin/test_quotas.py
index 81b0328..5af091e 100644
--- a/tempest/api/compute/admin/test_quotas.py
+++ b/tempest/api/compute/admin/test_quotas.py
@@ -19,7 +19,6 @@
 
 
 class QuotasAdminTestJSON(base.BaseV2ComputeAdminTest):
-    _interface = 'json'
     force_tenant_isolation = True
 
     @classmethod
diff --git a/tempest/api/compute/admin/test_quotas_negative.py b/tempest/api/compute/admin/test_quotas_negative.py
index 4c4acd4..5b2b5fd 100644
--- a/tempest/api/compute/admin/test_quotas_negative.py
+++ b/tempest/api/compute/admin/test_quotas_negative.py
@@ -22,7 +22,6 @@
 
 
 class QuotasAdminNegativeTestJSON(base.BaseV2ComputeAdminTest):
-    _interface = 'json'
     force_tenant_isolation = True
 
     @classmethod
diff --git a/tempest/api/compute/admin/test_security_groups.py b/tempest/api/compute/admin/test_security_groups.py
index 0cfa344..f728d68 100644
--- a/tempest/api/compute/admin/test_security_groups.py
+++ b/tempest/api/compute/admin/test_security_groups.py
@@ -18,13 +18,12 @@
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest.test import attr
+from tempest import test
 
 CONF = config.CONF
 
 
 class SecurityGroupsTestAdminJSON(base.BaseV2ComputeAdminTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -43,7 +42,7 @@
     @testtools.skipIf(CONF.service_available.neutron,
                       "Skipped because neutron do not support all_tenants"
                       "search filter.")
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_list_security_groups_list_all_tenants_filter(self):
         # Admin can list security groups of all tenants
         # List of all security groups created
diff --git a/tempest/api/compute/admin/test_servers.py b/tempest/api/compute/admin/test_servers.py
index 8a5f1a5..40a4df7 100644
--- a/tempest/api/compute/admin/test_servers.py
+++ b/tempest/api/compute/admin/test_servers.py
@@ -25,7 +25,6 @@
     """
 
     _host_key = 'OS-EXT-SRV-ATTR:host'
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -175,6 +174,16 @@
         rebuilt_image_id = server['image']['id']
         self.assertEqual(self.image_ref_alt, rebuilt_image_id)
 
+    @test.attr(type='gate')
+    def test_reset_network_inject_network_info(self):
+        # Reset Network of a Server
+        resp, server = self.create_test_server(wait_until='ACTIVE')
+        resp, server_body = self.client.reset_network(server['id'])
+        self.assertEqual(202, resp.status)
+        # Inject the Network Info into Server
+        resp, server_body = self.client.inject_network_info(server['id'])
+        self.assertEqual(202, resp.status)
+
 
 class ServersAdminTestXML(ServersAdminTestJSON):
     _host_key = (
diff --git a/tempest/api/compute/admin/test_servers_negative.py b/tempest/api/compute/admin/test_servers_negative.py
index 9580a06..797b780 100644
--- a/tempest/api/compute/admin/test_servers_negative.py
+++ b/tempest/api/compute/admin/test_servers_negative.py
@@ -17,7 +17,7 @@
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class ServersAdminNegativeTestJSON(base.BaseV2ComputeAdminTest):
@@ -26,8 +26,6 @@
     Tests Servers API using admin privileges
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(ServersAdminNegativeTestJSON, cls).setUpClass()
@@ -54,7 +52,7 @@
             flavor_id = data_utils.rand_int_id(start=1000)
         return flavor_id
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_resize_server_using_overlimit_ram(self):
         flavor_name = data_utils.rand_name("flavor-")
         flavor_id = self._get_unused_flavor_id()
@@ -72,7 +70,7 @@
                           self.servers[0]['id'],
                           flavor_ref['id'])
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_resize_server_using_overlimit_vcpus(self):
         flavor_name = data_utils.rand_name("flavor-")
         flavor_id = self._get_unused_flavor_id()
@@ -90,38 +88,38 @@
                           self.servers[0]['id'],
                           flavor_ref['id'])
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_reset_state_server_invalid_state(self):
         self.assertRaises(exceptions.BadRequest,
                           self.client.reset_state, self.s1_id,
                           state='invalid')
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_reset_state_server_invalid_type(self):
         self.assertRaises(exceptions.BadRequest,
                           self.client.reset_state, self.s1_id,
                           state=1)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_reset_state_server_nonexistent_server(self):
         self.assertRaises(exceptions.NotFound,
                           self.client.reset_state, '999')
 
-    @attr(type=['negative', 'gate'])
+    @test.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)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_migrate_non_existent_server(self):
         # migrate a non existent server
         self.assertRaises(exceptions.NotFound,
                           self.client.migrate_server,
                           str(uuid.uuid4()))
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_migrate_server_invalid_state(self):
         # create server.
         resp, server = self.create_test_server(wait_until='ACTIVE')
diff --git a/tempest/api/compute/admin/test_services.py b/tempest/api/compute/admin/test_services.py
index ac800fb..9dd429b 100644
--- a/tempest/api/compute/admin/test_services.py
+++ b/tempest/api/compute/admin/test_services.py
@@ -14,8 +14,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest.api.compute.api_schema import services as schema
 from tempest.api.compute import base
-from tempest.test import attr
+from tempest import test
 
 
 class ServicesAdminTestJSON(base.BaseV2ComputeAdminTest):
@@ -24,37 +25,38 @@
     Tests Services API. List and Enable/Disable require admin privileges.
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(ServicesAdminTestJSON, cls).setUpClass()
         cls.client = cls.os_adm.services_client
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_services(self):
         resp, services = self.client.list_services()
-        self.assertEqual(200, resp.status)
+        self.validate_response(schema.list_services, resp, services)
         self.assertNotEqual(0, len(services))
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_service_by_service_binary_name(self):
         binary_name = 'nova-compute'
         params = {'binary': binary_name}
         resp, services = self.client.list_services(params)
-        self.assertEqual(200, resp.status)
+        self.validate_response(schema.list_services, resp, services)
         self.assertNotEqual(0, len(services))
         for service in services:
             self.assertEqual(binary_name, service['binary'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_service_by_host_name(self):
         resp, services = self.client.list_services()
+        self.validate_response(schema.list_services, resp, services)
         host_name = services[0]['host']
         services_on_host = [service for service in services if
                             service['host'] == host_name]
         params = {'host': host_name}
+
         resp, services = self.client.list_services(params)
+        self.validate_response(schema.list_services, resp, services)
 
         # we could have a periodic job checkin between the 2 service
         # lookups, so only compare binary lists.
@@ -65,14 +67,16 @@
         # on order.
         self.assertEqual(sorted(s1), sorted(s2))
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_service_by_service_and_host_name(self):
         resp, services = self.client.list_services()
+        self.validate_response(schema.list_services, resp, services)
         host_name = services[0]['host']
         binary_name = services[0]['binary']
         params = {'host': host_name, 'binary': binary_name}
+
         resp, services = self.client.list_services(params)
-        self.assertEqual(200, resp.status)
+        self.validate_response(schema.list_services, resp, services)
         self.assertEqual(1, len(services))
         self.assertEqual(host_name, services[0]['host'])
         self.assertEqual(binary_name, services[0]['binary'])
diff --git a/tempest/api/compute/admin/test_services_negative.py b/tempest/api/compute/admin/test_services_negative.py
index a1809c4..c78d70d 100644
--- a/tempest/api/compute/admin/test_services_negative.py
+++ b/tempest/api/compute/admin/test_services_negative.py
@@ -14,7 +14,7 @@
 
 from tempest.api.compute import base
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class ServicesAdminNegativeTestJSON(base.BaseV2ComputeAdminTest):
@@ -23,20 +23,18 @@
     Tests Services API. List and Enable/Disable require admin privileges.
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(ServicesAdminNegativeTestJSON, cls).setUpClass()
         cls.client = cls.os_adm.services_client
         cls.non_admin_client = cls.services_client
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_list_services_with_non_admin_user(self):
         self.assertRaises(exceptions.Unauthorized,
                           self.non_admin_client.list_services)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_get_service_by_invalid_params(self):
         # return all services if send the request with invalid parameter
         resp, services = self.client.list_services()
@@ -45,7 +43,7 @@
         self.assertEqual(200, resp.status)
         self.assertEqual(len(services), len(services_xxx))
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_get_service_by_invalid_service_and_valid_host(self):
         resp, services = self.client.list_services()
         host_name = services[0]['host']
@@ -54,7 +52,7 @@
         self.assertEqual(200, resp.status)
         self.assertEqual(0, len(services))
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_get_service_with_valid_service_and_invalid_host(self):
         resp, services = self.client.list_services()
         binary_name = services[0]['binary']
diff --git a/tempest/api/compute/admin/test_simple_tenant_usage.py b/tempest/api/compute/admin/test_simple_tenant_usage.py
index dcb9aed..cc8641f 100644
--- a/tempest/api/compute/admin/test_simple_tenant_usage.py
+++ b/tempest/api/compute/admin/test_simple_tenant_usage.py
@@ -16,14 +16,12 @@
 import datetime
 
 from tempest.api.compute import base
-from tempest.test import attr
+from tempest import test
 import time
 
 
 class TenantUsagesTestJSON(base.BaseV2ComputeAdminTest):
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(TenantUsagesTestJSON, cls).setUpClass()
@@ -48,7 +46,7 @@
         # Returns formatted datetime
         return at.strftime('%Y-%m-%dT%H:%M:%S.%f')
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_usage_all_tenants(self):
         # Get usage for all tenants
         params = {'start': self.start,
@@ -58,7 +56,7 @@
         self.assertEqual(200, resp.status)
         self.assertEqual(len(tenant_usage), 8)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_usage_tenant(self):
         # Get usage for a specific tenant
         params = {'start': self.start,
@@ -69,7 +67,7 @@
         self.assertEqual(200, resp.status)
         self.assertEqual(len(tenant_usage), 8)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_usage_tenant_with_non_admin_user(self):
         # Get usage for a specific tenant with non admin user
         params = {'start': self.start,
diff --git a/tempest/api/compute/admin/test_simple_tenant_usage_negative.py b/tempest/api/compute/admin/test_simple_tenant_usage_negative.py
index 2a30348..a080f2e 100644
--- a/tempest/api/compute/admin/test_simple_tenant_usage_negative.py
+++ b/tempest/api/compute/admin/test_simple_tenant_usage_negative.py
@@ -17,13 +17,11 @@
 
 from tempest.api.compute import base
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class TenantUsagesNegativeTestJSON(base.BaseV2ComputeAdminTest):
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(TenantUsagesNegativeTestJSON, cls).setUpClass()
@@ -39,7 +37,7 @@
         # Returns formatted datetime
         return at.strftime('%Y-%m-%dT%H:%M:%S.%f')
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_get_usage_tenant_with_empty_tenant_id(self):
         # Get usage for a specific tenant empty
         params = {'start': self.start,
@@ -48,7 +46,7 @@
                           self.adm_client.get_tenant_usage,
                           '', params)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_get_usage_tenant_with_invalid_date(self):
         # Get usage for tenant with invalid date
         params = {'start': self.end,
@@ -60,7 +58,7 @@
                           self.adm_client.get_tenant_usage,
                           tenant_id, params)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_list_usage_all_tenants_with_non_admin_user(self):
         # Get usage for all tenants with non admin user
         params = {'start': self.start,
diff --git a/tempest/api/compute/api_schema/__init__.py b/tempest/api/compute/api_schema/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/api/compute/api_schema/__init__.py
diff --git a/tempest/api/compute/api_schema/services.py b/tempest/api/compute/api_schema/services.py
new file mode 100644
index 0000000..ef5868c
--- /dev/null
+++ b/tempest/api/compute/api_schema/services.py
@@ -0,0 +1,38 @@
+# Copyright 2014 NEC Corporation.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+list_services = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'array',
+        'items': {
+            'type': 'object',
+            'properties': {
+                # NOTE: Now the type of 'id' is integer, but here allows
+                # 'string' also because we will be able to change it to
+                # 'uuid' in the future.
+                'id': {'type': ['integer', 'string']},
+                'zone': {'type': 'string'},
+                'host': {'type': 'string'},
+                'state': {'type': 'string'},
+                'binary': {'type': 'string'},
+                'status': {'type': 'string'},
+                'updated_at': {'type': 'string'},
+                'disabled_reason': {'type': ['string', 'null']},
+            },
+            'required': ['id', 'zone', 'host', 'state', 'binary', 'status',
+                         'updated_at', 'disabled_reason'],
+        },
+    }
+}
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 72bb723..b2f3117 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -15,6 +15,8 @@
 
 import time
 
+import jsonschema
+
 from tempest import clients
 from tempest.common.utils import data_utils
 from tempest import config
@@ -176,6 +178,32 @@
 
         return resp, body
 
+    @classmethod
+    def validate_response(cls, schema, resp, body):
+        response_code = schema['status_code']
+        if resp.status not in response_code:
+            msg = ("The status code(%s) is different than the expected "
+                   "one(%s)") % (resp.status, response_code)
+            raise exceptions.InvalidHttpSuccessCode(msg)
+        response_schema = schema.get('response_body')
+        if response_schema:
+            if cls._interface == 'xml':
+                # NOTE: xml client of Tempest is broken and cannot get some
+                # keys. The best way is to fix it, but now xml format has been
+                # marked as "deprecated" in Nova API and xml client will be
+                # removed from Tempest.
+                # So now this test does not check attributes if xml.
+                return
+            try:
+                jsonschema.validate(body, response_schema)
+            except jsonschema.ValidationError as ex:
+                msg = ("HTTP response body is invalid (%s)") % ex
+                raise exceptions.InvalidHTTPResponseBody(msg)
+        else:
+            if body:
+                msg = ("HTTP response body should not exist (%s)") % body
+                raise exceptions.InvalidHTTPResponseBody(msg)
+
     def wait_for(self, condition):
         """Repeatedly calls condition() until a timeout."""
         start_time = int(time.time())
@@ -206,6 +234,8 @@
 
 class BaseV2ComputeTest(BaseComputeTest):
 
+    _interface = "json"
+
     @classmethod
     def setUpClass(cls):
         # By default compute tests do not create network resources
@@ -303,6 +333,8 @@
 
 class BaseV3ComputeTest(BaseComputeTest):
 
+    _interface = "json"
+
     @classmethod
     def setUpClass(cls):
         # By default compute tests do not create network resources
@@ -311,14 +343,14 @@
                         "%s will be removed shortly" % cls.__name__)
             raise cls.skipException(skip_msg)
 
-        cls.set_network_resources()
-        super(BaseV3ComputeTest, cls).setUpClass()
         if not CONF.compute_feature_enabled.api_v3:
-            cls.tearDownClass()
             skip_msg = ("%s skipped as nova v3 api is not available" %
                         cls.__name__)
             raise cls.skipException(skip_msg)
 
+        cls.set_network_resources()
+        super(BaseV3ComputeTest, cls).setUpClass()
+
         cls.servers_client = cls.os.servers_v3_client
         cls.images_client = cls.os.image_client
         cls.flavors_client = cls.os.flavors_v3_client
@@ -407,3 +439,4 @@
         cls.aggregates_admin_client = cls.os_adm.aggregates_v3_client
         cls.hosts_admin_client = cls.os_adm.hosts_v3_client
         cls.quotas_admin_client = cls.os_adm.quotas_v3_client
+        cls.agents_admin_client = cls.os_adm.agents_v3_client
diff --git a/tempest/api/compute/certificates/test_certificates.py b/tempest/api/compute/certificates/test_certificates.py
index 79619bc..5299d13 100644
--- a/tempest/api/compute/certificates/test_certificates.py
+++ b/tempest/api/compute/certificates/test_certificates.py
@@ -14,13 +14,12 @@
 #    under the License.
 
 from tempest.api.compute import base
-from tempest.test import attr
+from tempest import test
 
 
 class CertificatesTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_create_and_get_root_certificate(self):
         # create certificates
         resp, create_body = self.certificates_client.create_certificate()
diff --git a/tempest/api/compute/flavors/test_flavors.py b/tempest/api/compute/flavors/test_flavors.py
index b0a7fed..6e202f6 100644
--- a/tempest/api/compute/flavors/test_flavors.py
+++ b/tempest/api/compute/flavors/test_flavors.py
@@ -14,18 +14,17 @@
 #    under the License.
 
 from tempest.api.compute import base
-from tempest.test import attr
+from tempest import test
 
 
 class FlavorsTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
         super(FlavorsTestJSON, cls).setUpClass()
         cls.client = cls.flavors_client
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_list_flavors(self):
         # List of all flavors should contain the expected flavor
         resp, flavors = self.client.list_flavors()
@@ -34,34 +33,34 @@
                              'name': flavor['name']}
         self.assertIn(flavor_min_detail, flavors)
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_list_flavors_with_detail(self):
         # Detailed list of all flavors should contain the expected flavor
         resp, flavors = self.client.list_flavors_with_detail()
         resp, flavor = self.client.get_flavor_details(self.flavor_ref)
         self.assertIn(flavor, flavors)
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_get_flavor(self):
         # The expected flavor details should be returned
         resp, flavor = self.client.get_flavor_details(self.flavor_ref)
         self.assertEqual(self.flavor_ref, flavor['id'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_flavors_limit_results(self):
         # Only the expected number of flavors should be returned
         params = {'limit': 1}
         resp, flavors = self.client.list_flavors(params)
         self.assertEqual(1, len(flavors))
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_flavors_detailed_limit_results(self):
         # Only the expected number of flavors (detailed) should be returned
         params = {'limit': 1}
         resp, flavors = self.client.list_flavors_with_detail(params)
         self.assertEqual(1, len(flavors))
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_flavors_using_marker(self):
         # The list of flavors should start from the provided marker
         resp, flavors = self.client.list_flavors()
@@ -72,7 +71,7 @@
         self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]),
                          'The list of flavors did not start after the marker.')
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_flavors_detailed_using_marker(self):
         # The list of flavors should start from the provided marker
         resp, flavors = self.client.list_flavors_with_detail()
@@ -83,7 +82,7 @@
         self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]),
                          'The list of flavors did not start after the marker.')
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_flavors_detailed_filter_by_min_disk(self):
         # The detailed list of flavors should be filtered by disk space
         resp, flavors = self.client.list_flavors_with_detail()
@@ -94,7 +93,7 @@
         resp, flavors = self.client.list_flavors_with_detail(params)
         self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_flavors_detailed_filter_by_min_ram(self):
         # The detailed list of flavors should be filtered by RAM
         resp, flavors = self.client.list_flavors_with_detail()
@@ -105,7 +104,7 @@
         resp, flavors = self.client.list_flavors_with_detail(params)
         self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_flavors_filter_by_min_disk(self):
         # The list of flavors should be filtered by disk space
         resp, flavors = self.client.list_flavors_with_detail()
@@ -116,7 +115,7 @@
         resp, flavors = self.client.list_flavors(params)
         self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_flavors_filter_by_min_ram(self):
         # The list of flavors should be filtered by RAM
         resp, flavors = self.client.list_flavors_with_detail()
diff --git a/tempest/api/compute/flavors/test_flavors_negative.py b/tempest/api/compute/flavors/test_flavors_negative.py
index 8ac6182..4ba5023 100644
--- a/tempest/api/compute/flavors/test_flavors_negative.py
+++ b/tempest/api/compute/flavors/test_flavors_negative.py
@@ -24,7 +24,6 @@
 
 class FlavorsListNegativeTestJSON(base.BaseV2ComputeTest,
                                   test.NegativeAutoTest):
-    _interface = 'json'
     _service = 'compute'
     _schema_file = 'compute/flavors/flavors_list.json'
 
@@ -37,7 +36,6 @@
 
 class FlavorDetailsNegativeTestJSON(base.BaseV2ComputeTest,
                                     test.NegativeAutoTest):
-    _interface = 'json'
     _service = 'compute'
     _schema_file = 'compute/flavors/flavor_details.json'
 
diff --git a/tempest/api/compute/flavors/test_flavors_negative_xml.py b/tempest/api/compute/flavors/test_flavors_negative_xml.py
index c93c7c9..bf73c0e 100644
--- a/tempest/api/compute/flavors/test_flavors_negative_xml.py
+++ b/tempest/api/compute/flavors/test_flavors_negative_xml.py
@@ -17,7 +17,7 @@
 
 from tempest.api.compute import base
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class FlavorsNegativeTestXML(base.BaseV2ComputeTest):
@@ -28,19 +28,19 @@
         super(FlavorsNegativeTestXML, cls).setUpClass()
         cls.client = cls.flavors_client
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_invalid_minRam_filter(self):
         self.assertRaises(exceptions.BadRequest,
                           self.client.list_flavors_with_detail,
                           {'minRam': 'invalid'})
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_invalid_minDisk_filter(self):
         self.assertRaises(exceptions.BadRequest,
                           self.client.list_flavors_with_detail,
                           {'minDisk': 'invalid'})
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_non_existent_flavor_id(self):
         # flavor details are not returned for non-existent flavors
         nonexistent_flavor_id = str(uuid.uuid4())
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 ea785b3..c0f7af0 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
@@ -20,7 +20,6 @@
 
 
 class FloatingIPsTestJSON(base.BaseFloatingIPsTest):
-    _interface = 'json'
     server_id = None
     floating_ip = None
 
diff --git a/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py b/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
index f24343b..9fc43e2 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
@@ -19,13 +19,12 @@
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 CONF = config.CONF
 
 
 class FloatingIPsNegativeTestJSON(base.BaseFloatingIPsTest):
-    _interface = 'json'
     server_id = None
 
     @classmethod
@@ -48,7 +47,7 @@
             if cls.non_exist_id not in cls.floating_ip_ids:
                 break
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_allocate_floating_ip_from_nonexistent_pool(self):
         # Negative test:Allocation of a new floating IP from a nonexistent_pool
         # to a project should fail
@@ -56,7 +55,7 @@
                           self.client.create_floating_ip,
                           "non_exist_pool")
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_delete_nonexistent_floating_ip(self):
         # Negative test:Deletion of a nonexistent floating IP
         # from project should fail
@@ -65,7 +64,7 @@
         self.assertRaises(exceptions.NotFound, self.client.delete_floating_ip,
                           self.non_exist_id)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_associate_nonexistent_floating_ip(self):
         # Negative test:Association of a non existent floating IP
         # to specific server should fail
@@ -74,7 +73,7 @@
                           self.client.associate_floating_ip_to_server,
                           "0.0.0.0", self.server_id)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_dissociate_nonexistent_floating_ip(self):
         # Negative test:Dissociation of a non existent floating IP should fail
         # Dissociating non existent floating IP
@@ -82,7 +81,7 @@
                           self.client.disassociate_floating_ip_from_server,
                           "0.0.0.0", self.server_id)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_associate_ip_to_server_without_passing_floating_ip(self):
         # Negative test:Association of empty floating IP to specific server
         # should raise NotFound exception
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 fa2d558..94dcf61 100644
--- a/tempest/api/compute/floating_ips/test_list_floating_ips.py
+++ b/tempest/api/compute/floating_ips/test_list_floating_ips.py
@@ -14,11 +14,10 @@
 #    under the License.
 
 from tempest.api.compute import base
-from tempest.test import attr
+from tempest import test
 
 
 class FloatingIPDetailsTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -37,7 +36,7 @@
             cls.client.delete_floating_ip(cls.floating_ip_id[i])
         super(FloatingIPDetailsTestJSON, cls).tearDownClass()
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_floating_ips(self):
         # Positive test:Should return the list of floating IPs
         resp, body = self.client.list_floating_ips()
@@ -48,7 +47,7 @@
         for i in range(3):
             self.assertIn(self.floating_ip[i], floating_ips)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_floating_ip_details(self):
         # Positive test:Should be able to GET the details of floatingIP
         # Creating a floating IP for which details are to be checked
@@ -70,7 +69,7 @@
                          body['fixed_ip'])
         self.assertEqual(floating_ip_id, body['id'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_floating_ip_pools(self):
         # Positive test:Should return the list of floating IP Pools
         resp, floating_ip_pools = self.client.list_floating_ip_pools()
diff --git a/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py b/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py
index 8d60e7d..8cb2f08 100644
--- a/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py
+++ b/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py
@@ -19,20 +19,19 @@
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 CONF = config.CONF
 
 
 class FloatingIPDetailsNegativeTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
         super(FloatingIPDetailsNegativeTestJSON, cls).setUpClass()
         cls.client = cls.floating_ips_client
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_get_nonexistent_floating_ip_details(self):
         # Negative test:Should not be able to GET the details
         # of non-existent floating IP
diff --git a/tempest/api/compute/images/test_image_metadata.py b/tempest/api/compute/images/test_image_metadata.py
index 4115d65..195a018 100644
--- a/tempest/api/compute/images/test_image_metadata.py
+++ b/tempest/api/compute/images/test_image_metadata.py
@@ -16,13 +16,12 @@
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest.test import attr
+from tempest import test
 
 CONF = config.CONF
 
 
 class ImagesMetadataTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -55,14 +54,14 @@
         resp, _ = self.client.set_image_metadata(self.image_id, meta)
         self.assertEqual(resp.status, 200)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_image_metadata(self):
         # All metadata key/value pairs for an image should be returned
         resp, resp_metadata = self.client.list_image_metadata(self.image_id)
         expected = {'key1': 'value1', 'key2': 'value2'}
         self.assertEqual(expected, resp_metadata)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_set_image_metadata(self):
         # The metadata for the image should match the new values
         req_metadata = {'meta2': 'value2', 'meta3': 'value3'}
@@ -72,7 +71,7 @@
         resp, resp_metadata = self.client.list_image_metadata(self.image_id)
         self.assertEqual(req_metadata, resp_metadata)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_update_image_metadata(self):
         # The metadata for the image should match the updated values
         req_metadata = {'key1': 'alt1', 'key3': 'value3'}
@@ -83,14 +82,14 @@
         expected = {'key1': 'alt1', 'key2': 'value2', 'key3': 'value3'}
         self.assertEqual(expected, resp_metadata)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_image_metadata_item(self):
         # The value for a specific metadata key should be returned
         resp, meta = self.client.get_image_metadata_item(self.image_id,
                                                          'key2')
         self.assertEqual('value2', meta['key2'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_set_image_metadata_item(self):
         # The value provided for the given meta item should be set for
         # the image
@@ -101,7 +100,7 @@
         expected = {'key1': 'alt', 'key2': 'value2'}
         self.assertEqual(expected, resp_metadata)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_delete_image_metadata_item(self):
         # The metadata value/key pair should be deleted from the image
         resp, body = self.client.delete_image_metadata_item(self.image_id,
diff --git a/tempest/api/compute/images/test_image_metadata_negative.py b/tempest/api/compute/images/test_image_metadata_negative.py
index 4878936..15bb66a 100644
--- a/tempest/api/compute/images/test_image_metadata_negative.py
+++ b/tempest/api/compute/images/test_image_metadata_negative.py
@@ -16,25 +16,24 @@
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class ImagesMetadataTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
         super(ImagesMetadataTestJSON, cls).setUpClass()
         cls.client = cls.images_client
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_list_nonexistent_image_metadata(self):
         # Negative test: List on nonexistent image
         # metadata should not happen
         self.assertRaises(exceptions.NotFound, self.client.list_image_metadata,
                           data_utils.rand_uuid())
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_update_nonexistent_image_metadata(self):
         # Negative test:An update should not happen for a non-existent image
         meta = {'key1': 'alt1', 'key2': 'alt2'}
@@ -42,21 +41,21 @@
                           self.client.update_image_metadata,
                           data_utils.rand_uuid(), meta)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_get_nonexistent_image_metadata_item(self):
         # Negative test: Get on non-existent image should not happen
         self.assertRaises(exceptions.NotFound,
                           self.client.get_image_metadata_item,
                           data_utils.rand_uuid(), 'key2')
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_set_nonexistent_image_metadata(self):
         # Negative test: Metadata should not be set to a non-existent image
         meta = {'key1': 'alt1', 'key2': 'alt2'}
         self.assertRaises(exceptions.NotFound, self.client.set_image_metadata,
                           data_utils.rand_uuid(), meta)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_set_nonexistent_image_metadata_item(self):
         # Negative test: Metadata item should not be set to a
         # nonexistent image
@@ -66,7 +65,7 @@
                           data_utils.rand_uuid(), 'key1',
                           meta)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_delete_nonexistent_image_metadata_item(self):
         # Negative test: Shouldn't be able to delete metadata
         # item from non-existent image
diff --git a/tempest/api/compute/images/test_images.py b/tempest/api/compute/images/test_images.py
index 8964dcf..5de2436 100644
--- a/tempest/api/compute/images/test_images.py
+++ b/tempest/api/compute/images/test_images.py
@@ -22,7 +22,6 @@
 
 
 class ImagesTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -33,22 +32,6 @@
         cls.client = cls.images_client
         cls.servers_client = cls.servers_client
 
-        cls.image_ids = []
-
-    def tearDown(self):
-        """Terminate test instances created after a test is executed."""
-        for image_id in self.image_ids:
-            self.client.delete_image(image_id)
-            self.image_ids.remove(image_id)
-        super(ImagesTestJSON, self).tearDown()
-
-    def __create_image__(self, server_id, name, meta=None):
-        resp, body = self.client.create_image(server_id, name, meta)
-        image_id = data_utils.parse_image_id(resp['location'])
-        self.client.wait_for_image_status(image_id, 'ACTIVE')
-        self.image_ids.append(image_id)
-        return resp, body
-
     @test.attr(type=['negative', 'gate'])
     def test_create_image_from_deleted_server(self):
         # An image should not be created if the server instance is removed
@@ -61,8 +44,8 @@
         name = data_utils.rand_name('image')
         meta = {'image_type': 'test'}
         self.assertRaises(exceptions.NotFound,
-                          self.__create_image__,
-                          server['id'], name, meta)
+                          self.create_image_from_server,
+                          server['id'], name=name, meta=meta)
 
     @test.attr(type=['negative', 'gate'])
     def test_create_image_from_invalid_server(self):
@@ -72,8 +55,9 @@
         meta = {'image_type': 'test'}
         resp = {}
         resp['status'] = None
-        self.assertRaises(exceptions.NotFound, self.__create_image__,
-                          '!@#$%^&*()', name, meta)
+        self.assertRaises(exceptions.NotFound,
+                          self.create_image_from_server,
+                          '!@#$%^&*()', name=name, meta=meta)
 
     @test.attr(type=['negative', 'gate'])
     def test_create_image_from_stopped_server(self):
diff --git a/tempest/api/compute/images/test_images_oneserver.py b/tempest/api/compute/images/test_images_oneserver.py
index 7d5593d..b152c3c 100644
--- a/tempest/api/compute/images/test_images_oneserver.py
+++ b/tempest/api/compute/images/test_images_oneserver.py
@@ -26,7 +26,6 @@
 
 
 class ImagesOneServerTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     def setUp(self):
         # NOTE(afazekas): Normally we use the same server with all test cases,
diff --git a/tempest/api/compute/images/test_images_oneserver_negative.py b/tempest/api/compute/images/test_images_oneserver_negative.py
index 82955d8..41a0590 100644
--- a/tempest/api/compute/images/test_images_oneserver_negative.py
+++ b/tempest/api/compute/images/test_images_oneserver_negative.py
@@ -27,7 +27,6 @@
 
 
 class ImagesOneServerNegativeTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     def tearDown(self):
         """Terminate test instances created after a test is executed."""
diff --git a/tempest/api/compute/images/test_list_image_filters.py b/tempest/api/compute/images/test_list_image_filters.py
index 9cff3a8..86ee4a4 100644
--- a/tempest/api/compute/images/test_list_image_filters.py
+++ b/tempest/api/compute/images/test_list_image_filters.py
@@ -24,7 +24,6 @@
 
 
 class ListImageFiltersTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/images/test_list_image_filters_negative.py b/tempest/api/compute/images/test_list_image_filters_negative.py
index 3b19d3c..80d59a7 100644
--- a/tempest/api/compute/images/test_list_image_filters_negative.py
+++ b/tempest/api/compute/images/test_list_image_filters_negative.py
@@ -22,7 +22,6 @@
 
 
 class ListImageFiltersNegativeTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/images/test_list_images.py b/tempest/api/compute/images/test_list_images.py
index ed38442..eba331f 100644
--- a/tempest/api/compute/images/test_list_images.py
+++ b/tempest/api/compute/images/test_list_images.py
@@ -15,13 +15,12 @@
 
 from tempest.api.compute import base
 from tempest import config
-from tempest.test import attr
+from tempest import test
 
 CONF = config.CONF
 
 
 class ListImagesTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -31,20 +30,20 @@
             raise cls.skipException(skip_msg)
         cls.client = cls.images_client
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_get_image(self):
         # Returns the correct details for a single image
         resp, image = self.client.get_image(self.image_ref)
         self.assertEqual(self.image_ref, image['id'])
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_list_images(self):
         # The list of all images should contain the image
         resp, images = self.client.list_images()
         found = any([i for i in images if i['id'] == self.image_ref])
         self.assertTrue(found)
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_list_images_with_detail(self):
         # Detailed list of all images should contain the expected images
         resp, images = self.client.list_images_with_detail()
diff --git a/tempest/api/compute/keypairs/test_keypairs.py b/tempest/api/compute/keypairs/test_keypairs.py
index d4554bc..67fafed 100644
--- a/tempest/api/compute/keypairs/test_keypairs.py
+++ b/tempest/api/compute/keypairs/test_keypairs.py
@@ -19,7 +19,6 @@
 
 
 class KeyPairsTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/keypairs/test_keypairs_negative.py b/tempest/api/compute/keypairs/test_keypairs_negative.py
index 93b0692..a91a9c2 100644
--- a/tempest/api/compute/keypairs/test_keypairs_negative.py
+++ b/tempest/api/compute/keypairs/test_keypairs_negative.py
@@ -21,7 +21,6 @@
 
 
 class KeyPairsNegativeTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/limits/test_absolute_limits.py b/tempest/api/compute/limits/test_absolute_limits.py
index 0e234fb..d64fd57 100644
--- a/tempest/api/compute/limits/test_absolute_limits.py
+++ b/tempest/api/compute/limits/test_absolute_limits.py
@@ -18,7 +18,6 @@
 
 
 class AbsoluteLimitsTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/limits/test_absolute_limits_negative.py b/tempest/api/compute/limits/test_absolute_limits_negative.py
index ac8af3b..f88699b 100644
--- a/tempest/api/compute/limits/test_absolute_limits_negative.py
+++ b/tempest/api/compute/limits/test_absolute_limits_negative.py
@@ -19,7 +19,6 @@
 
 
 class AbsoluteLimitsNegativeTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
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 17bb489..b04ab8a 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules.py
@@ -21,7 +21,6 @@
 
 
 class SecurityGroupRulesTestJSON(base.BaseSecurityGroupsTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/security_groups/test_security_group_rules_negative.py b/tempest/api/compute/security_groups/test_security_group_rules_negative.py
index 680bc2f..0b53037 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules_negative.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules_negative.py
@@ -13,8 +13,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import testtools
-
 from tempest.api.compute.security_groups import base
 from tempest.common.utils import data_utils
 from tempest import config
@@ -24,22 +22,26 @@
 CONF = config.CONF
 
 
+def not_existing_id():
+    if CONF.service_available.neutron:
+        return data_utils.rand_uuid()
+    else:
+        return data_utils.rand_int_id(start=999)
+
+
 class SecurityGroupRulesNegativeTestJSON(base.BaseSecurityGroupsTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
         super(SecurityGroupRulesNegativeTestJSON, cls).setUpClass()
         cls.client = cls.security_groups_client
 
-    @test.skip_because(bug="1182384",
-                       condition=CONF.service_available.neutron)
     @test.attr(type=['negative', 'smoke'])
     def test_create_security_group_rule_with_non_existent_id(self):
         # Negative test: Creation of Security Group rule should FAIL
         # with non existent Parent group id
         # Adding rules to the non existent Security Group id
-        parent_group_id = data_utils.rand_int_id(start=999)
+        parent_group_id = not_existing_id()
         ip_protocol = 'tcp'
         from_port = 22
         to_port = 22
@@ -47,8 +49,6 @@
                           self.client.create_security_group_rule,
                           parent_group_id, ip_protocol, from_port, to_port)
 
-    @testtools.skipIf(CONF.service_available.neutron,
-                      "Neutron not check the security_group_id")
     @test.attr(type=['negative', 'smoke'])
     def test_create_security_group_rule_with_invalid_id(self):
         # Negative test: Creation of Security Group rule should FAIL
@@ -146,13 +146,11 @@
                           self.client.create_security_group_rule,
                           secgroup_id, ip_protocol, from_port, to_port)
 
-    @test.skip_because(bug="1182384",
-                       condition=CONF.service_available.neutron)
     @test.attr(type=['negative', 'smoke'])
     def test_delete_security_group_rule_with_non_existent_id(self):
         # Negative test: Deletion of Security Group rule should be FAIL
         # with non existent id
-        non_existent_rule_id = data_utils.rand_int_id(start=999)
+        non_existent_rule_id = not_existing_id()
         self.assertRaises(exceptions.NotFound,
                           self.client.delete_security_group_rule,
                           non_existent_rule_id)
diff --git a/tempest/api/compute/security_groups/test_security_groups.py b/tempest/api/compute/security_groups/test_security_groups.py
index b376edc..538ebc6 100644
--- a/tempest/api/compute/security_groups/test_security_groups.py
+++ b/tempest/api/compute/security_groups/test_security_groups.py
@@ -20,14 +20,13 @@
 
 
 class SecurityGroupsTestJSON(base.BaseSecurityGroupsTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
         super(SecurityGroupsTestJSON, cls).setUpClass()
         cls.client = cls.security_groups_client
 
-    @test.attr(type='gate')
+    @test.attr(type='smoke')
     def test_security_groups_create_list_delete(self):
         # Positive test:Should return the list of Security Groups
         # Create 3 Security Groups
@@ -59,7 +58,7 @@
                          "list" % ', '.join(m_group['name']
                                             for m_group in deleted_sgs))
 
-    @test.attr(type='gate')
+    @test.attr(type='smoke')
     def test_security_group_create_get_delete(self):
         # Security Group should be created, fetched and deleted
         s_name = data_utils.rand_name('securitygroup-')
@@ -77,7 +76,7 @@
                          "The fetched Security Group is different "
                          "from the created Group")
 
-    @test.attr(type='gate')
+    @test.attr(type='smoke')
     def test_server_security_groups(self):
         # Checks that security groups may be added and linked to a server
         # and not deleted if the server is active.
@@ -123,7 +122,7 @@
         self.client.delete_security_group(sg2['id'])
         self.assertEqual(202, resp.status)
 
-    @test.attr(type='gate')
+    @test.attr(type='smoke')
     def test_update_security_groups(self):
         # Update security group name and description
         # Create a security group
diff --git a/tempest/api/compute/security_groups/test_security_groups_negative.py b/tempest/api/compute/security_groups/test_security_groups_negative.py
index edf38e9..aa2d32e 100644
--- a/tempest/api/compute/security_groups/test_security_groups_negative.py
+++ b/tempest/api/compute/security_groups/test_security_groups_negative.py
@@ -25,7 +25,6 @@
 
 
 class SecurityGroupsNegativeTestJSON(base.BaseSecurityGroupsTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -57,7 +56,7 @@
 
     @test.skip_because(bug="1161411",
                        condition=CONF.service_available.neutron)
-    @test.attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'smoke'])
     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
@@ -77,7 +76,7 @@
 
     @test.skip_because(bug="1161411",
                        condition=CONF.service_available.neutron)
-    @test.attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'smoke'])
     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
@@ -96,7 +95,7 @@
 
     @testtools.skipIf(CONF.service_available.neutron,
                       "Neutron allows duplicate names for security groups")
-    @test.attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'smoke'])
     def test_security_group_create_with_duplicate_name(self):
         # Negative test:Security Group with duplicate name should not
         # be created
@@ -110,7 +109,7 @@
                           self.client.create_security_group, s_name,
                           s_description)
 
-    @test.attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'smoke'])
     def test_delete_the_default_security_group(self):
         # Negative test:Deletion of the "default" Security Group should Fail
         default_security_group_id = None
@@ -131,7 +130,7 @@
         self.assertRaises(exceptions.NotFound,
                           self.client.delete_security_group, non_exist_id)
 
-    @test.attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'smoke'])
     def test_delete_security_group_without_passing_id(self):
         # Negative test:Deletion of a Security Group with out passing ID
         # should Fail
@@ -140,7 +139,7 @@
 
     @testtools.skipIf(CONF.service_available.neutron,
                       "Neutron not check the security_group_id")
-    @test.attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'smoke'])
     def test_update_security_group_with_invalid_sg_id(self):
         # Update security_group with invalid sg_id should fail
         s_name = data_utils.rand_name('sg-')
@@ -153,7 +152,7 @@
 
     @testtools.skipIf(CONF.service_available.neutron,
                       "Neutron not check the security_group_name")
-    @test.attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'smoke'])
     def test_update_security_group_with_invalid_sg_name(self):
         # Update security_group with invalid sg_name should fail
         resp, securitygroup = self.create_security_group()
@@ -168,7 +167,7 @@
 
     @testtools.skipIf(CONF.service_available.neutron,
                       "Neutron not check the security_group_description")
-    @test.attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'smoke'])
     def test_update_security_group_with_invalid_sg_des(self):
         # Update security_group with invalid sg_des should fail
         resp, securitygroup = self.create_security_group()
@@ -181,7 +180,7 @@
                           self.client.update_security_group,
                           securitygroup_id, description=s_new_des)
 
-    @test.attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'smoke'])
     def test_update_non_existent_security_group(self):
         # Update a non-existent Security Group should Fail
         non_exist_id = self._generate_a_non_existent_security_group_id()
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index 9cdac55..f6eed00 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -16,7 +16,7 @@
 from tempest.api.compute import base
 from tempest import config
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 import time
 
@@ -24,7 +24,6 @@
 
 
 class AttachInterfacesTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -48,6 +47,7 @@
     def _create_server_get_interfaces(self):
         resp, server = self.create_test_server(wait_until='ACTIVE')
         resp, ifs = self.client.list_interfaces(server['id'])
+        self.assertEqual(200, resp.status)
         resp, body = self.client.wait_for_interface_status(
             server['id'], ifs[0]['port_id'], 'ACTIVE')
         ifs[0]['port_state'] = body['port_state']
@@ -55,6 +55,7 @@
 
     def _test_create_interface(self, server):
         resp, iface = self.client.create_interface(server['id'])
+        self.assertEqual(200, resp.status)
         resp, iface = self.client.wait_for_interface_status(
             server['id'], iface['port_id'], 'ACTIVE')
         self._check_interface(iface)
@@ -64,6 +65,7 @@
         network_id = ifs[0]['net_id']
         resp, iface = self.client.create_interface(server['id'],
                                                    network_id=network_id)
+        self.assertEqual(200, resp.status)
         resp, iface = self.client.wait_for_interface_status(
             server['id'], iface['port_id'], 'ACTIVE')
         self._check_interface(iface, network_id=network_id)
@@ -73,12 +75,14 @@
         iface = ifs[0]
         resp, _iface = self.client.show_interface(server['id'],
                                                   iface['port_id'])
+        self.assertEqual(200, resp.status)
         self.assertEqual(iface, _iface)
 
     def _test_delete_interface(self, server, ifs):
         # NOTE(danms): delete not the first or last, but one in the middle
         iface = ifs[1]
-        self.client.delete_interface(server['id'], iface['port_id'])
+        resp, _ = self.client.delete_interface(server['id'], iface['port_id'])
+        self.assertEqual(202, resp.status)
         _ifs = self.client.list_interfaces(server['id'])[1]
         start = int(time.time())
 
@@ -102,7 +106,7 @@
 
         self.assertEqual(sorted(list1), sorted(list2))
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_create_list_show_delete_interfaces(self):
         server, ifs = self._create_server_get_interfaces()
         interface_count = len(ifs)
@@ -123,6 +127,33 @@
         _ifs = self._test_delete_interface(server, ifs)
         self.assertEqual(len(ifs) - 1, len(_ifs))
 
+    @test.attr(type='gate')
+    def test_add_remove_fixed_ip(self):
+        # Add and Remove the fixed IP to server.
+        server, ifs = self._create_server_get_interfaces()
+        interface_count = len(ifs)
+        self.assertTrue(interface_count > 0)
+        self._check_interface(ifs[0])
+        network_id = ifs[0]['net_id']
+        resp, body = self.client.add_fixed_ip(server['id'],
+                                              network_id)
+        self.assertEqual(202, resp.status)
+        # Remove the fixed IP from server.
+        server_resp, server_detail = self.os.servers_client.get_server(
+            server['id'])
+        # Get the Fixed IP from server.
+        fixed_ip = None
+        for ip_set in server_detail['addresses']:
+            for ip in server_detail['addresses'][ip_set]:
+                if ip['OS-EXT-IPS:type'] == 'fixed':
+                    fixed_ip = ip['addr']
+                    break
+            if fixed_ip is not None:
+                break
+        resp, body = self.client.remove_fixed_ip(server['id'],
+                                                 fixed_ip)
+        self.assertEqual(202, resp.status)
+
 
 class AttachInterfacesTestXML(AttachInterfacesTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/servers/test_availability_zone.py b/tempest/api/compute/servers/test_availability_zone.py
index 748ba41..7b12555 100644
--- a/tempest/api/compute/servers/test_availability_zone.py
+++ b/tempest/api/compute/servers/test_availability_zone.py
@@ -23,8 +23,6 @@
     Tests Availability Zone API List
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(AZTestJSON, cls).setUpClass()
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index f705308..ddf37ce 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -28,7 +28,6 @@
 
 
 class ServersTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
     run_ssh = CONF.compute.run_ssh
     disk_config = 'AUTO'
 
@@ -110,7 +109,6 @@
 
 
 class ServersWithSpecificFlavorTestJSON(base.BaseV2ComputeAdminTest):
-    _interface = 'json'
     run_ssh = CONF.compute.run_ssh
     disk_config = 'AUTO'
 
diff --git a/tempest/api/compute/servers/test_delete_server.py b/tempest/api/compute/servers/test_delete_server.py
index ec40ce0..5e011dd 100644
--- a/tempest/api/compute/servers/test_delete_server.py
+++ b/tempest/api/compute/servers/test_delete_server.py
@@ -13,6 +13,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import testtools
+
 from tempest.api.compute import base
 from tempest import config
 from tempest import test
@@ -23,7 +25,6 @@
 class DeleteServersTestJSON(base.BaseV2ComputeTest):
     # NOTE: Server creations of each test class should be under 10
     # for preventing "Quota exceeded for instances"
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -36,6 +37,7 @@
         resp, server = self.create_test_server(wait_until='BUILD')
         resp, _ = self.client.delete_server(server['id'])
         self.assertEqual('204', resp['status'])
+        self.client.wait_for_server_termination(server['id'])
 
     @test.attr(type='gate')
     def test_delete_active_server(self):
@@ -43,6 +45,7 @@
         resp, server = self.create_test_server(wait_until='ACTIVE')
         resp, _ = self.client.delete_server(server['id'])
         self.assertEqual('204', resp['status'])
+        self.client.wait_for_server_termination(server['id'])
 
     @test.attr(type='gate')
     def test_delete_server_while_in_shutoff_state(self):
@@ -52,6 +55,7 @@
         self.client.wait_for_server_status(server['id'], 'SHUTOFF')
         resp, _ = self.client.delete_server(server['id'])
         self.assertEqual('204', resp['status'])
+        self.client.wait_for_server_termination(server['id'])
 
     @test.attr(type='gate')
     def test_delete_server_while_in_pause_state(self):
@@ -61,6 +65,7 @@
         self.client.wait_for_server_status(server['id'], 'PAUSED')
         resp, _ = self.client.delete_server(server['id'])
         self.assertEqual('204', resp['status'])
+        self.client.wait_for_server_termination(server['id'])
 
     @test.attr(type='gate')
     def test_delete_server_while_in_shelved_state(self):
@@ -79,12 +84,25 @@
                                                'SHELVED')
         resp, _ = self.client.delete_server(server['id'])
         self.assertEqual('204', resp['status'])
+        self.client.wait_for_server_termination(server['id'])
+
+    @testtools.skipIf(not CONF.compute_feature_enabled.resize,
+                      'Resize not available.')
+    @test.attr(type='gate')
+    def test_delete_server_while_in_verify_resize_state(self):
+        # Delete a server while it's VM state is VERIFY_RESIZE
+        resp, server = self.create_test_server(wait_until='ACTIVE')
+        resp, body = self.client.resize(server['id'], self.flavor_ref_alt)
+        self.assertEqual(202, resp.status)
+        self.client.wait_for_server_status(server['id'], 'VERIFY_RESIZE')
+        resp, _ = self.client.delete_server(server['id'])
+        self.assertEqual('204', resp['status'])
+        self.client.wait_for_server_termination(server['id'])
 
 
 class DeleteServersAdminTestJSON(base.BaseV2ComputeAdminTest):
     # NOTE: Server creations of each test class should be under 10
     # for preventing "Quota exceeded for instances".
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -103,6 +121,8 @@
         self.assertEqual(server['status'], 'ERROR')
         resp, _ = self.non_admin_client.delete_server(server['id'])
         self.assertEqual('204', resp['status'])
+        self.servers_client.wait_for_server_termination(server['id'],
+                                                        ignore_error=True)
 
     @test.attr(type='gate')
     def test_admin_delete_servers_of_others(self):
diff --git a/tempest/api/compute/servers/test_disk_config.py b/tempest/api/compute/servers/test_disk_config.py
index 0d79161..332358c 100644
--- a/tempest/api/compute/servers/test_disk_config.py
+++ b/tempest/api/compute/servers/test_disk_config.py
@@ -17,13 +17,12 @@
 
 from tempest.api.compute import base
 from tempest import config
-from tempest.test import attr
+from tempest import test
 
 CONF = config.CONF
 
 
 class ServerDiskConfigTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -45,7 +44,7 @@
             resp, server = self.client.get_server(server['id'])
             self.assertEqual(disk_config, server['OS-DCF:diskConfig'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_rebuild_server_with_manual_disk_config(self):
         # A server should be rebuilt using the manual disk config option
         self._update_server_with_disk_config(disk_config='AUTO')
@@ -61,7 +60,7 @@
         resp, server = self.client.get_server(server['id'])
         self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_rebuild_server_with_auto_disk_config(self):
         # A server should be rebuilt using the auto disk config option
         self._update_server_with_disk_config(disk_config='MANUAL')
@@ -87,7 +86,7 @@
 
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_resize_server_from_manual_to_auto(self):
         # A server should be resized from manual to auto disk config
         self._update_server_with_disk_config(disk_config='MANUAL')
@@ -104,7 +103,7 @@
 
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_resize_server_from_auto_to_manual(self):
         # A server should be resized from auto to manual disk config
         self._update_server_with_disk_config(disk_config='AUTO')
@@ -119,7 +118,7 @@
         resp, server = self.client.get_server(self.server_id)
         self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_update_server_from_auto_to_manual(self):
         # A server should be updated from auto to manual disk config
         self._update_server_with_disk_config(disk_config='AUTO')
diff --git a/tempest/api/compute/servers/test_instance_actions.py b/tempest/api/compute/servers/test_instance_actions.py
index 667b84f..dd31165 100644
--- a/tempest/api/compute/servers/test_instance_actions.py
+++ b/tempest/api/compute/servers/test_instance_actions.py
@@ -18,7 +18,6 @@
 
 
 class InstanceActionsTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/servers/test_instance_actions_negative.py b/tempest/api/compute/servers/test_instance_actions_negative.py
index 2503eb2..e67b69d 100644
--- a/tempest/api/compute/servers/test_instance_actions_negative.py
+++ b/tempest/api/compute/servers/test_instance_actions_negative.py
@@ -20,7 +20,6 @@
 
 
 class InstanceActionsNegativeTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index fc0bb9f..837114c 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -24,7 +24,6 @@
 
 
 class ListServerFiltersTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/servers/test_list_servers_negative.py b/tempest/api/compute/servers/test_list_servers_negative.py
index a0aefd8..c825fb9 100644
--- a/tempest/api/compute/servers/test_list_servers_negative.py
+++ b/tempest/api/compute/servers/test_list_servers_negative.py
@@ -15,13 +15,14 @@
 
 import datetime
 
+from six import moves
+
 from tempest.api.compute import base
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class ListServersNegativeTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
     force_tenant_isolation = True
 
     @classmethod
@@ -36,7 +37,7 @@
         cls.existing_fixtures = []
         cls.deleted_fixtures = []
         cls.start_time = datetime.datetime.utcnow()
-        for x in xrange(2):
+        for x in moves.xrange(2):
             resp, srv = cls.create_test_server()
             cls.existing_fixtures.append(srv)
 
@@ -50,7 +51,7 @@
                                                ignore_error=True)
         cls.deleted_fixtures.append(srv)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_list_servers_with_a_deleted_server(self):
         # Verify deleted servers do not show by default in list servers
         # List servers and verify server not returned
@@ -62,7 +63,7 @@
         self.assertEqual('200', resp['status'])
         self.assertEqual([], actual)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_list_servers_by_non_existing_image(self):
         # Listing servers for a non existing image returns empty list
         non_existing_image = '1234abcd-zzz0-aaa9-ppp3-0987654abcde'
@@ -71,7 +72,7 @@
         self.assertEqual('200', resp['status'])
         self.assertEqual([], servers)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_list_servers_by_non_existing_flavor(self):
         # Listing servers by non existing flavor returns empty list
         non_existing_flavor = 1234
@@ -80,7 +81,7 @@
         self.assertEqual('200', resp['status'])
         self.assertEqual([], servers)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_list_servers_by_non_existing_server_name(self):
         # Listing servers for a non existent server name returns empty list
         non_existing_name = 'junk_server_1234'
@@ -89,7 +90,7 @@
         self.assertEqual('200', resp['status'])
         self.assertEqual([], servers)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_list_servers_status_non_existing(self):
         # Return an empty list when invalid status is specified
         non_existing_status = 'BALONEY'
@@ -98,7 +99,7 @@
         self.assertEqual('200', resp['status'])
         self.assertEqual([], servers)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_servers_by_limits(self):
         # List servers by specifying limits
         resp, body = self.client.list_servers({'limit': 1})
@@ -106,26 +107,26 @@
         # when _interface='xml', one element for servers_links in servers
         self.assertEqual(1, len([x for x in body['servers'] if 'id' in x]))
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_list_servers_by_limits_greater_than_actual_count(self):
         # List servers by specifying a greater value for limit
         resp, body = self.client.list_servers({'limit': 100})
         self.assertEqual('200', resp['status'])
         self.assertEqual(len(self.existing_fixtures), len(body['servers']))
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_list_servers_by_limits_pass_string(self):
         # Return an error if a string value is passed for limit
         self.assertRaises(exceptions.BadRequest, self.client.list_servers,
                           {'limit': 'testing'})
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_list_servers_by_limits_pass_negative_value(self):
         # Return an error if a negative value for limit is passed
         self.assertRaises(exceptions.BadRequest, self.client.list_servers,
                           {'limit': -1})
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_servers_by_changes_since(self):
         # Servers are listed by specifying changes-since date
         changes_since = {'changes-since': self.start_time.isoformat()}
@@ -138,13 +139,13 @@
                          "Number of servers %d is wrong in %s" %
                          (num_expected, body['servers']))
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_list_servers_by_changes_since_invalid_date(self):
         # Return an error when invalid date format is passed
         self.assertRaises(exceptions.BadRequest, self.client.list_servers,
                           {'changes-since': '2011/01/01'})
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_list_servers_by_changes_since_future_date(self):
         # Return an empty list when a date in the future is passed
         changes_since = {'changes-since': '2051-01-01T12:34:00Z'}
@@ -152,7 +153,7 @@
         self.assertEqual('200', resp['status'])
         self.assertEqual(0, len(body['servers']))
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_list_servers_detail_server_is_deleted(self):
         # Server details are not listed for a deleted server
         deleted_ids = [s['id'] for s in self.deleted_fixtures]
diff --git a/tempest/api/compute/servers/test_multiple_create.py b/tempest/api/compute/servers/test_multiple_create.py
index cf4d646..40b9c16 100644
--- a/tempest/api/compute/servers/test_multiple_create.py
+++ b/tempest/api/compute/servers/test_multiple_create.py
@@ -19,7 +19,6 @@
 
 
 class MultipleCreateTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
     _name = 'multiple-create-test'
 
     def _generate_name(self):
diff --git a/tempest/api/compute/servers/test_multiple_create_negative.py b/tempest/api/compute/servers/test_multiple_create_negative.py
index e289717..3dea521 100644
--- a/tempest/api/compute/servers/test_multiple_create_negative.py
+++ b/tempest/api/compute/servers/test_multiple_create_negative.py
@@ -20,7 +20,6 @@
 
 
 class MultipleCreateNegativeTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
     _name = 'multiple-create-test'
 
     def _generate_name(self):
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index adf522b..71d6018 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -29,7 +29,6 @@
 
 
 class ServerActionsTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
     resize_available = CONF.compute_feature_enabled.resize
     run_ssh = CONF.compute.run_ssh
 
@@ -383,6 +382,11 @@
             self.client.wait_for_server_status(self.server_id,
                                                'SHELVED')
 
+            resp, server = self.client.shelve_offload_server(self.server_id)
+            self.assertEqual(202, resp.status)
+            self.client.wait_for_server_status(self.server_id,
+                                               'SHELVED_OFFLOADED')
+
         resp, server = self.client.get_server(self.server_id)
         image_name = server['name'] + '-shelved'
         params = {'name': image_name}
diff --git a/tempest/api/compute/servers/test_server_addresses.py b/tempest/api/compute/servers/test_server_addresses.py
index d5528c4..0c14dc2 100644
--- a/tempest/api/compute/servers/test_server_addresses.py
+++ b/tempest/api/compute/servers/test_server_addresses.py
@@ -21,7 +21,6 @@
 
 
 class ServerAddressesTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/servers/test_server_addresses_negative.py b/tempest/api/compute/servers/test_server_addresses_negative.py
index c69c5eb..d37f7fa 100644
--- a/tempest/api/compute/servers/test_server_addresses_negative.py
+++ b/tempest/api/compute/servers/test_server_addresses_negative.py
@@ -19,7 +19,6 @@
 
 
 class ServerAddressesNegativeTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/servers/test_server_metadata.py b/tempest/api/compute/servers/test_server_metadata.py
index ad4931c..448b8ff 100644
--- a/tempest/api/compute/servers/test_server_metadata.py
+++ b/tempest/api/compute/servers/test_server_metadata.py
@@ -18,7 +18,6 @@
 
 
 class ServerMetadataTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/servers/test_server_metadata_negative.py b/tempest/api/compute/servers/test_server_metadata_negative.py
index e52ea4a..8b69c78 100644
--- a/tempest/api/compute/servers/test_server_metadata_negative.py
+++ b/tempest/api/compute/servers/test_server_metadata_negative.py
@@ -20,7 +20,6 @@
 
 
 class ServerMetadataNegativeTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/servers/test_server_password.py b/tempest/api/compute/servers/test_server_password.py
index 06697a5..50c881a 100644
--- a/tempest/api/compute/servers/test_server_password.py
+++ b/tempest/api/compute/servers/test_server_password.py
@@ -15,11 +15,10 @@
 
 
 from tempest.api.compute import base
-from tempest.test import attr
+from tempest import test
 
 
 class ServerPasswordTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -27,12 +26,12 @@
         cls.client = cls.servers_client
         resp, cls.server = cls.create_test_server(wait_until="ACTIVE")
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_server_password(self):
         resp, body = self.client.get_password(self.server['id'])
         self.assertEqual(200, resp.status)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_delete_server_password(self):
         resp, body = self.client.delete_password(self.server['id'])
         self.assertEqual(204, resp.status)
diff --git a/tempest/api/compute/servers/test_server_personality.py b/tempest/api/compute/servers/test_server_personality.py
index bb14a4c..b7e4e38 100644
--- a/tempest/api/compute/servers/test_server_personality.py
+++ b/tempest/api/compute/servers/test_server_personality.py
@@ -17,11 +17,10 @@
 
 from tempest.api.compute import base
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class ServerPersonalityTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -29,7 +28,7 @@
         cls.client = cls.servers_client
         cls.user_client = cls.limits_client
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_personality_files_exceed_limit(self):
         # Server creation should fail if greater than the maximum allowed
         # number of files are injected into the server.
@@ -44,7 +43,7 @@
         self.assertRaises(exceptions.OverLimit, self.create_test_server,
                           personality=personality)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_can_create_server_with_max_number_personality_files(self):
         # Server should be created successfully if maximum allowed number of
         # files is injected into the server during creation.
diff --git a/tempest/api/compute/servers/test_server_rescue.py b/tempest/api/compute/servers/test_server_rescue.py
index 0bf604c..48f2e14 100644
--- a/tempest/api/compute/servers/test_server_rescue.py
+++ b/tempest/api/compute/servers/test_server_rescue.py
@@ -15,18 +15,15 @@
 
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class ServerRescueTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
         cls.set_network_resources(network=True, subnet=True, router=True)
         super(ServerRescueTestJSON, cls).setUpClass()
-        cls.device = 'vdf'
 
         # Floating IP creation
         resp, body = cls.floating_ips_client.create_floating_ip()
@@ -54,14 +51,6 @@
         cls.password = server['adminPass']
         cls.servers_client.wait_for_server_status(cls.server_id, 'ACTIVE')
 
-        # Server for negative tests
-        cls.rescue_id = resc_server['id']
-        cls.rescue_password = resc_server['adminPass']
-
-        cls.servers_client.rescue_server(
-            cls.rescue_id, adminPass=cls.rescue_password)
-        cls.servers_client.wait_for_server_status(cls.rescue_id, 'RESCUE')
-
     def setUp(self):
         super(ServerRescueTestJSON, self).setUp()
 
@@ -77,22 +66,12 @@
     def tearDown(self):
         super(ServerRescueTestJSON, self).tearDown()
 
-    def _detach(self, server_id, volume_id):
-        self.servers_client.detach_volume(server_id, volume_id)
-        self.volumes_extensions_client.wait_for_volume_status(volume_id,
-                                                              'available')
-
     def _unrescue(self, server_id):
         resp, body = self.servers_client.unrescue_server(server_id)
         self.assertEqual(202, resp.status)
         self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
 
-    def _unpause(self, server_id):
-        resp, body = self.servers_client.unpause_server(server_id)
-        self.assertEqual(202, resp.status)
-        self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
-
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_rescue_unrescue_instance(self):
         resp, body = self.servers_client.rescue_server(
             self.server_id, adminPass=self.password)
@@ -102,76 +81,7 @@
         self.assertEqual(202, resp.status)
         self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
 
-    @attr(type=['negative', 'gate'])
-    def test_rescue_paused_instance(self):
-        # Rescue a paused server
-        resp, body = self.servers_client.pause_server(
-            self.server_id)
-        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.Conflict,
-                          self.servers_client.rescue_server,
-                          self.server_id)
-
-    @attr(type=['negative', 'gate'])
-    def test_rescued_vm_reboot(self):
-        self.assertRaises(exceptions.Conflict, self.servers_client.reboot,
-                          self.rescue_id, 'HARD')
-
-    @attr(type=['negative', 'gate'])
-    def test_rescue_non_existent_server(self):
-        # Rescue a non-existing server
-        self.assertRaises(exceptions.NotFound,
-                          self.servers_client.rescue_server,
-                          '999erra43')
-
-    @attr(type=['negative', 'gate'])
-    def test_rescued_vm_rebuild(self):
-        self.assertRaises(exceptions.Conflict,
-                          self.servers_client.rebuild,
-                          self.rescue_id,
-                          self.image_ref_alt)
-
-    @attr(type=['negative', 'gate'])
-    def test_rescued_vm_attach_volume(self):
-        # Rescue the server
-        self.servers_client.rescue_server(self.server_id,
-                                          adminPass=self.password)
-        self.servers_client.wait_for_server_status(self.server_id, 'RESCUE')
-        self.addCleanup(self._unrescue, self.server_id)
-
-        # Attach the volume to the server
-        self.assertRaises(exceptions.Conflict,
-                          self.servers_client.attach_volume,
-                          self.server_id,
-                          self.volume['id'],
-                          device='/dev/%s' % self.device)
-
-    @attr(type=['negative', 'gate'])
-    def test_rescued_vm_detach_volume(self):
-        # Attach the volume to the server
-        self.servers_client.attach_volume(self.server_id,
-                                          self.volume['id'],
-                                          device='/dev/%s' % self.device)
-        self.volumes_extensions_client.wait_for_volume_status(
-            self.volume['id'], 'in-use')
-
-        # Rescue the server
-        self.servers_client.rescue_server(self.server_id,
-                                          adminPass=self.password)
-        self.servers_client.wait_for_server_status(self.server_id, 'RESCUE')
-        # addCleanup is a LIFO queue
-        self.addCleanup(self._detach, self.server_id, self.volume['id'])
-        self.addCleanup(self._unrescue, self.server_id)
-
-        # Detach the volume from the server expecting failure
-        self.assertRaises(exceptions.Conflict,
-                          self.servers_client.detach_volume,
-                          self.server_id,
-                          self.volume['id'])
-
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_rescued_vm_associate_dissociate_floating_ip(self):
         # Rescue the server
         self.servers_client.rescue_server(
@@ -191,7 +101,7 @@
                                                         self.server_id)
         self.assertEqual(202, resp.status)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_rescued_vm_add_remove_security_group(self):
         # Rescue the server
         self.servers_client.rescue_server(
diff --git a/tempest/api/compute/servers/test_server_rescue_negative.py b/tempest/api/compute/servers/test_server_rescue_negative.py
new file mode 100644
index 0000000..e027567
--- /dev/null
+++ b/tempest/api/compute/servers/test_server_rescue_negative.py
@@ -0,0 +1,139 @@
+# Copyright 2013 Hewlett-Packard Development Company, L.P.
+# Copyright 2014 NEC Corporation.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.api.compute import base
+from tempest.common.utils import data_utils
+from tempest import exceptions
+from tempest import test
+
+
+class ServerRescueNegativeTestJSON(base.BaseV2ComputeTest):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.set_network_resources(network=True, subnet=True, router=True)
+        super(ServerRescueNegativeTestJSON, cls).setUpClass()
+        cls.device = 'vdf'
+
+        # Create a volume and wait for it to become ready for attach
+        resp, cls.volume = cls.volumes_extensions_client.create_volume(
+            1, display_name=data_utils.rand_name(cls.__name__ + '_volume'))
+        cls.volumes_extensions_client.wait_for_volume_status(
+            cls.volume['id'], 'available')
+
+        # Server for negative tests
+        resp, server = cls.create_test_server(wait_until='BUILD')
+        resp, resc_server = cls.create_test_server(wait_until='ACTIVE')
+        cls.server_id = server['id']
+        cls.password = server['adminPass']
+        cls.rescue_id = resc_server['id']
+        rescue_password = resc_server['adminPass']
+
+        cls.servers_client.rescue_server(
+            cls.rescue_id, adminPass=rescue_password)
+        cls.servers_client.wait_for_server_status(cls.rescue_id, 'RESCUE')
+
+    @classmethod
+    def tearDownClass(cls):
+        cls.delete_volume(cls.volume['id'])
+        super(ServerRescueNegativeTestJSON, cls).tearDownClass()
+
+    def _detach(self, server_id, volume_id):
+        self.servers_client.detach_volume(server_id, volume_id)
+        self.volumes_extensions_client.wait_for_volume_status(volume_id,
+                                                              'available')
+
+    def _unrescue(self, server_id):
+        resp, body = self.servers_client.unrescue_server(server_id)
+        self.assertEqual(202, resp.status)
+        self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
+
+    def _unpause(self, server_id):
+        resp, body = self.servers_client.unpause_server(server_id)
+        self.assertEqual(202, resp.status)
+        self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
+
+    @test.attr(type=['negative', 'gate'])
+    def test_rescue_paused_instance(self):
+        # Rescue a paused server
+        resp, body = self.servers_client.pause_server(self.server_id)
+        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.Conflict,
+                          self.servers_client.rescue_server,
+                          self.server_id)
+
+    @test.attr(type=['negative', 'gate'])
+    def test_rescued_vm_reboot(self):
+        self.assertRaises(exceptions.Conflict, self.servers_client.reboot,
+                          self.rescue_id, 'HARD')
+
+    @test.attr(type=['negative', 'gate'])
+    def test_rescue_non_existent_server(self):
+        # Rescue a non-existing server
+        non_existent_server = data_utils.rand_uuid()
+        self.assertRaises(exceptions.NotFound,
+                          self.servers_client.rescue_server,
+                          non_existent_server)
+
+    @test.attr(type=['negative', 'gate'])
+    def test_rescued_vm_rebuild(self):
+        self.assertRaises(exceptions.Conflict,
+                          self.servers_client.rebuild,
+                          self.rescue_id,
+                          self.image_ref_alt)
+
+    @test.attr(type=['negative', 'gate'])
+    def test_rescued_vm_attach_volume(self):
+        # Rescue the server
+        self.servers_client.rescue_server(self.server_id,
+                                          adminPass=self.password)
+        self.servers_client.wait_for_server_status(self.server_id, 'RESCUE')
+        self.addCleanup(self._unrescue, self.server_id)
+
+        # Attach the volume to the server
+        self.assertRaises(exceptions.Conflict,
+                          self.servers_client.attach_volume,
+                          self.server_id,
+                          self.volume['id'],
+                          device='/dev/%s' % self.device)
+
+    @test.attr(type=['negative', 'gate'])
+    def test_rescued_vm_detach_volume(self):
+        # Attach the volume to the server
+        self.servers_client.attach_volume(self.server_id,
+                                          self.volume['id'],
+                                          device='/dev/%s' % self.device)
+        self.volumes_extensions_client.wait_for_volume_status(
+            self.volume['id'], 'in-use')
+
+        # Rescue the server
+        self.servers_client.rescue_server(self.server_id,
+                                          adminPass=self.password)
+        self.servers_client.wait_for_server_status(self.server_id, 'RESCUE')
+        # addCleanup is a LIFO queue
+        self.addCleanup(self._detach, self.server_id, self.volume['id'])
+        self.addCleanup(self._unrescue, self.server_id)
+
+        # Detach the volume from the server expecting failure
+        self.assertRaises(exceptions.Conflict,
+                          self.servers_client.detach_volume,
+                          self.server_id,
+                          self.volume['id'])
+
+
+class ServerRescueNegativeTestXML(ServerRescueNegativeTestJSON):
+    _interface = 'xml'
diff --git a/tempest/api/compute/servers/test_servers.py b/tempest/api/compute/servers/test_servers.py
index 7167a8b..40b97d7 100644
--- a/tempest/api/compute/servers/test_servers.py
+++ b/tempest/api/compute/servers/test_servers.py
@@ -15,11 +15,10 @@
 
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
-from tempest.test import attr
+from tempest import test
 
 
 class ServersTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -30,7 +29,7 @@
         self.clear_servers()
         super(ServersTestJSON, self).tearDown()
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_create_server_with_admin_password(self):
         # If an admin password is provided on server creation, the server's
         # root password should be set to that password.
@@ -39,7 +38,7 @@
         # Verify the password is set correctly in the response
         self.assertEqual('testpassword', server['adminPass'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_create_with_existing_server_name(self):
         # Creating a server with a name that already exists is allowed
 
@@ -58,7 +57,7 @@
         name2 = server['name']
         self.assertEqual(name1, name2)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_create_specify_keypair(self):
         # Specify a keypair while creating a server
 
@@ -71,7 +70,7 @@
         resp, server = self.client.get_server(server['id'])
         self.assertEqual(key_name, server['key_name'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_update_server_name(self):
         # The server name should be changed to the the provided value
         resp, server = self.create_test_server(wait_until='ACTIVE')
@@ -86,7 +85,7 @@
         resp, server = self.client.get_server(server['id'])
         self.assertEqual('newname', server['name'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_update_access_server_address(self):
         # The server's access addresses should reflect the provided values
         resp, server = self.create_test_server(wait_until='ACTIVE')
@@ -103,7 +102,7 @@
         self.assertEqual('1.1.1.1', server['accessIPv4'])
         self.assertEqual('::babe:202:202', server['accessIPv6'])
 
-    @attr(type='gate')
+    @test.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_test_server(accessIPv6='2001:2001::3')
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index e0181b9..4cccbd6 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -27,7 +27,6 @@
 
 
 class ServersNegativeTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     def setUp(self):
         super(ServersNegativeTestJSON, self).setUp()
diff --git a/tempest/api/compute/servers/test_servers_negative_new.py b/tempest/api/compute/servers/test_servers_negative_new.py
index 2b2fcf1..42ace76 100644
--- a/tempest/api/compute/servers/test_servers_negative_new.py
+++ b/tempest/api/compute/servers/test_servers_negative_new.py
@@ -24,7 +24,6 @@
 
 class GetConsoleOutputNegativeTestJSON(base.BaseV2ComputeTest,
                                        test.NegativeAutoTest):
-    _interface = 'json'
     _service = 'compute'
     _schema_file = 'compute/servers/get_console_output.json'
 
diff --git a/tempest/api/compute/servers/test_virtual_interfaces.py b/tempest/api/compute/servers/test_virtual_interfaces.py
index 95703d4..6354996 100644
--- a/tempest/api/compute/servers/test_virtual_interfaces.py
+++ b/tempest/api/compute/servers/test_virtual_interfaces.py
@@ -23,7 +23,6 @@
 
 
 class VirtualInterfacesTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/servers/test_virtual_interfaces_negative.py b/tempest/api/compute/servers/test_virtual_interfaces_negative.py
index f73218c..87289d8 100644
--- a/tempest/api/compute/servers/test_virtual_interfaces_negative.py
+++ b/tempest/api/compute/servers/test_virtual_interfaces_negative.py
@@ -21,7 +21,6 @@
 
 
 class VirtualInterfacesNegativeTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/test_authorization.py b/tempest/api/compute/test_authorization.py
index ed72061..7f909d7 100644
--- a/tempest/api/compute/test_authorization.py
+++ b/tempest/api/compute/test_authorization.py
@@ -19,7 +19,7 @@
 from tempest import config
 from tempest import exceptions
 from tempest.openstack.common import log as logging
-from tempest.test import attr
+from tempest import test
 
 CONF = config.CONF
 
@@ -27,7 +27,6 @@
 
 
 class AuthorizationTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -90,31 +89,31 @@
             cls.security_client.delete_security_group(cls.security_group['id'])
         super(AuthorizationTestJSON, cls).tearDownClass()
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_server_for_alt_account_fails(self):
         # A GET request for a server on another user's account should fail
         self.assertRaises(exceptions.NotFound, self.alt_client.get_server,
                           self.server['id'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_delete_server_for_alt_account_fails(self):
         # A DELETE request for another user's server should fail
         self.assertRaises(exceptions.NotFound, self.alt_client.delete_server,
                           self.server['id'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_update_server_for_alt_account_fails(self):
         # An update server request for another user's server should fail
         self.assertRaises(exceptions.NotFound, self.alt_client.update_server,
                           self.server['id'], name='test')
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_server_addresses_for_alt_account_fails(self):
         # A list addresses request for another user's server should fail
         self.assertRaises(exceptions.NotFound, self.alt_client.list_addresses,
                           self.server['id'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_server_addresses_by_network_for_alt_account_fails(self):
         # A list address/network request for another user's server should fail
         server_id = self.server['id']
@@ -122,7 +121,7 @@
                           self.alt_client.list_addresses_by_network, server_id,
                           'public')
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_servers_with_alternate_tenant(self):
         # A list on servers from one tenant should not
         # show on alternate tenant
@@ -132,44 +131,44 @@
         alt_server_ids = [s['id'] for s in body['servers']]
         self.assertNotIn(self.server['id'], alt_server_ids)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_change_password_for_alt_account_fails(self):
         # A change password request for another user's server should fail
         self.assertRaises(exceptions.NotFound, self.alt_client.change_password,
                           self.server['id'], 'newpass')
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_reboot_server_for_alt_account_fails(self):
         # A reboot request for another user's server should fail
         self.assertRaises(exceptions.NotFound, self.alt_client.reboot,
                           self.server['id'], 'HARD')
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_rebuild_server_for_alt_account_fails(self):
         # A rebuild request for another user's server should fail
         self.assertRaises(exceptions.NotFound, self.alt_client.rebuild,
                           self.server['id'], self.image_ref_alt)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_resize_server_for_alt_account_fails(self):
         # A resize request for another user's server should fail
         self.assertRaises(exceptions.NotFound, self.alt_client.resize,
                           self.server['id'], self.flavor_ref_alt)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_create_image_for_alt_account_fails(self):
         # A create image request for another user's server should fail
         self.assertRaises(exceptions.NotFound,
                           self.alt_images_client.create_image,
                           self.server['id'], 'testImage')
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_create_server_with_unauthorized_image(self):
         # Server creation with another user's image should fail
         self.assertRaises(exceptions.BadRequest, self.alt_client.create_server,
                           'test', self.image['id'], self.flavor_ref)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_create_server_fails_when_tenant_incorrect(self):
         # A create server request should fail if the tenant id does not match
         # the current user
@@ -182,7 +181,7 @@
                           self.alt_client.create_server, 'test',
                           self.image['id'], self.flavor_ref)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_create_keypair_in_analt_user_tenant(self):
         # A create keypair request should fail if the tenant id does not match
         # the current user
@@ -205,34 +204,34 @@
                 LOG.error("Create keypair request should not happen "
                           "if the tenant id does not match the current user")
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_keypair_of_alt_account_fails(self):
         # A GET request for another user's keypair should fail
         self.assertRaises(exceptions.NotFound,
                           self.alt_keypairs_client.get_keypair,
                           self.keypairname)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_delete_keypair_of_alt_account_fails(self):
         # A DELETE request for another user's keypair should fail
         self.assertRaises(exceptions.NotFound,
                           self.alt_keypairs_client.delete_keypair,
                           self.keypairname)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_image_for_alt_account_fails(self):
         # A GET request for an image on another user's account should fail
         self.assertRaises(exceptions.NotFound,
                           self.alt_images_client.get_image, self.image['id'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_delete_image_for_alt_account_fails(self):
         # A DELETE request for another user's image should fail
         self.assertRaises(exceptions.NotFound,
                           self.alt_images_client.delete_image,
                           self.image['id'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_create_security_group_in_analt_user_tenant(self):
         # A create security group request should fail if the tenant id does not
         # match the current user
@@ -257,21 +256,21 @@
                 LOG.error("Create Security Group request should not happen if"
                           "the tenant id does not match the current user")
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_security_group_of_alt_account_fails(self):
         # A GET request for another user's security group should fail
         self.assertRaises(exceptions.NotFound,
                           self.alt_security_client.get_security_group,
                           self.security_group['id'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_delete_security_group_of_alt_account_fails(self):
         # A DELETE request for another user's security group should fail
         self.assertRaises(exceptions.NotFound,
                           self.alt_security_client.delete_security_group,
                           self.security_group['id'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_create_security_group_rule_in_analt_user_tenant(self):
         # A create security group rule request should fail if the tenant id
         # does not match the current user
@@ -301,7 +300,7 @@
                           "happen if the tenant id does not match the"
                           " current user")
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_delete_security_group_rule_of_alt_account_fails(self):
         # A DELETE request for another user's security group rule
         # should fail
@@ -309,7 +308,7 @@
                           self.alt_security_client.delete_security_group_rule,
                           self.rule['id'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_set_metadata_of_alt_account_server_fails(self):
         # A set metadata for another user's server should fail
         req_metadata = {'meta1': 'data1', 'meta2': 'data2'}
@@ -318,7 +317,7 @@
                           self.server['id'],
                           req_metadata)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_set_metadata_of_alt_account_image_fails(self):
         # A set metadata for another user's image should fail
         req_metadata = {'meta1': 'value1', 'meta2': 'value2'}
@@ -326,7 +325,7 @@
                           self.alt_images_client.set_image_metadata,
                           self.image['id'], req_metadata)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_metadata_of_alt_account_server_fails(self):
         # A get metadata for another user's server should fail
         req_metadata = {'meta1': 'data1'}
@@ -337,7 +336,7 @@
                           self.alt_client.get_server_metadata_item,
                           self.server['id'], 'meta1')
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_metadata_of_alt_account_image_fails(self):
         # A get metadata for another user's image should fail
         req_metadata = {'meta1': 'value1'}
@@ -349,7 +348,7 @@
                           self.alt_images_client.get_image_metadata_item,
                           self.image['id'], 'meta1')
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_delete_metadata_of_alt_account_server_fails(self):
         # A delete metadata for another user's server should fail
         req_metadata = {'meta1': 'data1'}
@@ -360,7 +359,7 @@
                           self.alt_client.delete_server_metadata_item,
                           self.server['id'], 'meta1')
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_delete_metadata_of_alt_account_image_fails(self):
         # A delete metadata for another user's image should fail
         req_metadata = {'meta1': 'data1'}
@@ -372,7 +371,7 @@
                           self.alt_images_client.delete_image_metadata_item,
                           self.image['id'], 'meta1')
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_console_output_of_alt_account_server_fails(self):
         # A Get Console Output for another user's server should fail
         self.assertRaises(exceptions.NotFound,
diff --git a/tempest/api/compute/test_extensions.py b/tempest/api/compute/test_extensions.py
index 55146e5..674ca9a 100644
--- a/tempest/api/compute/test_extensions.py
+++ b/tempest/api/compute/test_extensions.py
@@ -26,7 +26,6 @@
 
 
 class ExtensionsTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @test.attr(type='gate')
     def test_list_extensions(self):
diff --git a/tempest/api/compute/test_live_block_migration.py b/tempest/api/compute/test_live_block_migration.py
index 1df4159..93ff4b0 100644
--- a/tempest/api/compute/test_live_block_migration.py
+++ b/tempest/api/compute/test_live_block_migration.py
@@ -18,14 +18,13 @@
 
 from tempest.api.compute import base
 from tempest import config
-from tempest.test import attr
+from tempest import test
 
 CONF = config.CONF
 
 
 class LiveBlockMigrationTestJSON(base.BaseV2ComputeAdminTest):
     _host_key = 'OS-EXT-SRV-ATTR:host'
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -86,7 +85,7 @@
 
     @testtools.skipIf(not CONF.compute_feature_enabled.live_migration,
                       'Live migration not available')
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_live_block_migration(self):
         # Live block migrate an instance to another host
         if len(self._get_compute_hostnames()) < 2:
@@ -106,7 +105,7 @@
     @testtools.skipIf(not CONF.compute_feature_enabled.
                       block_migrate_cinder_iscsi,
                       'Block Live migration not configured for iSCSI')
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_iscsi_volume(self):
         # Live block migrate an instance to another host
         if len(self._get_compute_hostnames()) < 2:
diff --git a/tempest/api/compute/test_live_block_migration_negative.py b/tempest/api/compute/test_live_block_migration_negative.py
index da0e4c4..c10818e 100644
--- a/tempest/api/compute/test_live_block_migration_negative.py
+++ b/tempest/api/compute/test_live_block_migration_negative.py
@@ -25,7 +25,6 @@
 
 class LiveBlockMigrationNegativeTestJSON(base.BaseV2ComputeAdminTest):
     _host_key = 'OS-EXT-SRV-ATTR:host'
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -38,7 +37,7 @@
     def _migrate_server_to(self, server_id, dest_host):
         _resp, body = self.admin_servers_client.live_migrate_server(
             server_id, dest_host,
-            self.config.compute_feature_enabled.
+            CONF.compute_feature_enabled.
             block_migration_for_live_migration)
         return body
 
diff --git a/tempest/api/compute/test_quotas.py b/tempest/api/compute/test_quotas.py
index 112e4fb..230d433 100644
--- a/tempest/api/compute/test_quotas.py
+++ b/tempest/api/compute/test_quotas.py
@@ -14,11 +14,10 @@
 #    under the License.
 
 from tempest.api.compute import base
-from tempest.test import attr
+from tempest import test
 
 
 class QuotasTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -36,7 +35,7 @@
                                      'instances', 'security_group_rules',
                                      'cores', 'security_groups'))
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_get_quotas(self):
         # User can get the quota set for it's tenant
         expected_quota_set = self.default_quota_set | set(['id'])
@@ -46,7 +45,7 @@
                          sorted(quota_set.keys()))
         self.assertEqual(quota_set['id'], self.tenant_id)
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_get_default_quotas(self):
         # User can get the default quota set for it's tenant
         expected_quota_set = self.default_quota_set | set(['id'])
@@ -56,7 +55,7 @@
                          sorted(quota_set.keys()))
         self.assertEqual(quota_set['id'], self.tenant_id)
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_compare_tenant_quotas_with_default_quotas(self):
         # Tenants are created with the default quota values
         resp, defualt_quota_set = \
diff --git a/tempest/api/compute/v3/admin/test_agents.py b/tempest/api/compute/v3/admin/test_agents.py
new file mode 100644
index 0000000..9d01b71
--- /dev/null
+++ b/tempest/api/compute/v3/admin/test_agents.py
@@ -0,0 +1,91 @@
+# Copyright 2014 NEC Corporation.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.api.compute import base
+from tempest import test
+
+
+class AgentsAdminV3Test(base.BaseV3ComputeAdminTest):
+
+    """
+    Tests Agents API that require admin privileges
+    """
+
+    @classmethod
+    def setUpClass(cls):
+        super(AgentsAdminV3Test, cls).setUpClass()
+        cls.client = cls.agents_admin_client
+
+    @test.attr(type='gate')
+    def test_create_update_list_delete_agents(self):
+
+        """
+        1. Create 2 agents.
+        2. Update one of the agents.
+        3. List all agent builds.
+        4. List the agent builds by the filter.
+        5. Delete agents.
+        """
+        params_kvm = expected_kvm = {'hypervisor': 'kvm',
+                                     'os': 'win',
+                                     'architecture': 'x86',
+                                     'version': '7.0',
+                                     'url': 'xxx://xxxx/xxx/xxx',
+                                     'md5hash': ("""add6bb58e139be103324d04d"""
+                                                 """82d8f545""")}
+
+        resp, agent_kvm = self.client.create_agent(**params_kvm)
+        self.assertEqual(201, resp.status)
+        for expected_item, value in expected_kvm.items():
+            self.assertEqual(value, agent_kvm[expected_item])
+
+        params_xen = expected_xen = {'hypervisor': 'xen',
+                                     'os': 'linux',
+                                     'architecture': 'x86',
+                                     'version': '7.0',
+                                     'url': 'xxx://xxxx/xxx/xxx1',
+                                     'md5hash': """add6bb58e139be103324d04d8"""
+                                                """2d8f546"""}
+
+        resp, agent_xen = self.client.create_agent(**params_xen)
+        self.assertEqual(201, resp.status)
+
+        for expected_item, value in expected_xen.items():
+            self.assertEqual(value, agent_xen[expected_item])
+
+        params_kvm_new = expected_kvm_new = {'version': '8.0',
+                                             'url': 'xxx://xxxx/xxx/xxx2',
+                                             'md5hash': """add6bb58e139be103"""
+                                                        """324d04d82d8f547"""}
+
+        resp, resp_agent_kvm = self.client.update_agent(agent_kvm['agent_id'],
+                                                        **params_kvm_new)
+        self.assertEqual(200, resp.status)
+        for expected_item, value in expected_kvm_new.items():
+            self.assertEqual(value, resp_agent_kvm[expected_item])
+
+        resp, agents = self.client.list_agents()
+        self.assertEqual(200, resp.status)
+        self.assertTrue(len(agents) > 1)
+
+        params_filter = {'hypervisor': 'kvm'}
+        resp, agent = self.client.list_agents(params_filter)
+        self.assertEqual(200, resp.status)
+        self.assertTrue(len(agent) > 0)
+        self.assertEqual('kvm', agent[0]['hypervisor'])
+
+        resp, _ = self.client.delete_agent(agent_kvm['agent_id'])
+        self.assertEqual(204, resp.status)
+        resp, _ = self.client.delete_agent(agent_xen['agent_id'])
+        self.assertEqual(204, resp.status)
diff --git a/tempest/api/compute/v3/admin/test_aggregates.py b/tempest/api/compute/v3/admin/test_aggregates.py
index 20093e4..e5ec08b 100644
--- a/tempest/api/compute/v3/admin/test_aggregates.py
+++ b/tempest/api/compute/v3/admin/test_aggregates.py
@@ -26,7 +26,6 @@
     """
 
     _host_key = 'os-extended-server-attributes:host'
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -47,7 +46,7 @@
         resp, aggregate = self.client.create_aggregate(name=aggregate_name)
         self.assertEqual(201, resp.status)
         self.assertEqual(aggregate_name, aggregate['name'])
-        self.assertEqual(None, aggregate['availability_zone'])
+        self.assertIsNone(aggregate['availability_zone'])
 
         resp, _ = self.client.delete_aggregate(aggregate['id'])
         self.assertEqual(204, resp.status)
@@ -176,7 +175,7 @@
         self.assertEqual(1, len(aggs))
         agg = aggs[0]
         self.assertEqual(aggregate_name, agg['name'])
-        self.assertEqual(None, agg['availability_zone'])
+        self.assertIsNone(agg['availability_zone'])
         self.assertIn(self.host, agg['hosts'])
 
     @test.attr(type='gate')
@@ -191,7 +190,7 @@
 
         resp, body = self.client.get_aggregate(aggregate['id'])
         self.assertEqual(aggregate_name, body['name'])
-        self.assertEqual(None, body['availability_zone'])
+        self.assertIsNone(body['availability_zone'])
         self.assertIn(self.host, body['hosts'])
 
     @test.attr(type='gate')
diff --git a/tempest/api/compute/v3/admin/test_aggregates_negative.py b/tempest/api/compute/v3/admin/test_aggregates_negative.py
index 5700460..1505f74 100644
--- a/tempest/api/compute/v3/admin/test_aggregates_negative.py
+++ b/tempest/api/compute/v3/admin/test_aggregates_negative.py
@@ -26,8 +26,6 @@
     Tests Aggregates API that require admin privileges
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(AggregatesAdminNegativeV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/admin/test_availability_zone.py b/tempest/api/compute/v3/admin/test_availability_zone.py
index 176751f..9ca8953 100644
--- a/tempest/api/compute/v3/admin/test_availability_zone.py
+++ b/tempest/api/compute/v3/admin/test_availability_zone.py
@@ -23,8 +23,6 @@
     Tests Availability Zone API List
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(AZAdminV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/admin/test_availability_zone_negative.py b/tempest/api/compute/v3/admin/test_availability_zone_negative.py
index 180f298..f3af6df 100644
--- a/tempest/api/compute/v3/admin/test_availability_zone_negative.py
+++ b/tempest/api/compute/v3/admin/test_availability_zone_negative.py
@@ -24,8 +24,6 @@
     Tests Availability Zone API List
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(AZAdminNegativeV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/admin/test_flavors.py b/tempest/api/compute/v3/admin/test_flavors.py
index 597c99b..401eb85 100644
--- a/tempest/api/compute/v3/admin/test_flavors.py
+++ b/tempest/api/compute/v3/admin/test_flavors.py
@@ -27,8 +27,6 @@
     Tests Flavors API Create and Delete that require admin privileges
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(FlavorsAdminV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/admin/test_flavors_access.py b/tempest/api/compute/v3/admin/test_flavors_access.py
index 43dc726..03305ff 100644
--- a/tempest/api/compute/v3/admin/test_flavors_access.py
+++ b/tempest/api/compute/v3/admin/test_flavors_access.py
@@ -25,8 +25,6 @@
     Add and remove Flavor Access require admin privileges.
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(FlavorsAccessV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/admin/test_flavors_access_negative.py b/tempest/api/compute/v3/admin/test_flavors_access_negative.py
index 6a2e826..334d124 100644
--- a/tempest/api/compute/v3/admin/test_flavors_access_negative.py
+++ b/tempest/api/compute/v3/admin/test_flavors_access_negative.py
@@ -28,8 +28,6 @@
     Add and remove Flavor Access require admin privileges.
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(FlavorsAccessNegativeV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/admin/test_flavors_extra_specs.py b/tempest/api/compute/v3/admin/test_flavors_extra_specs.py
index 4d22027..29cd8db 100644
--- a/tempest/api/compute/v3/admin/test_flavors_extra_specs.py
+++ b/tempest/api/compute/v3/admin/test_flavors_extra_specs.py
@@ -26,8 +26,6 @@
     GET Flavor Extra specs can be performed even by without admin privileges.
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(FlavorsExtraSpecsV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/admin/test_flavors_extra_specs_negative.py b/tempest/api/compute/v3/admin/test_flavors_extra_specs_negative.py
index 98e6e3d..e9c04a3 100644
--- a/tempest/api/compute/v3/admin/test_flavors_extra_specs_negative.py
+++ b/tempest/api/compute/v3/admin/test_flavors_extra_specs_negative.py
@@ -27,8 +27,6 @@
     SET, UNSET, UPDATE Flavor Extra specs require admin privileges.
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(FlavorsExtraSpecsNegativeV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/admin/test_flavors_negative.py b/tempest/api/compute/v3/admin/test_flavors_negative.py
index f54de79..3f8a2da 100644
--- a/tempest/api/compute/v3/admin/test_flavors_negative.py
+++ b/tempest/api/compute/v3/admin/test_flavors_negative.py
@@ -27,8 +27,6 @@
     Tests Flavors API Create and Delete that require admin privileges
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(FlavorsAdminNegativeV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/admin/test_hosts.py b/tempest/api/compute/v3/admin/test_hosts.py
index 2c9369f..8cb1f23 100644
--- a/tempest/api/compute/v3/admin/test_hosts.py
+++ b/tempest/api/compute/v3/admin/test_hosts.py
@@ -23,8 +23,6 @@
     Tests hosts API using admin privileges.
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(HostsAdminV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/admin/test_hosts_negative.py b/tempest/api/compute/v3/admin/test_hosts_negative.py
index ac5d7de..79cd97f 100644
--- a/tempest/api/compute/v3/admin/test_hosts_negative.py
+++ b/tempest/api/compute/v3/admin/test_hosts_negative.py
@@ -24,8 +24,6 @@
     Tests hosts API using admin privileges.
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(HostsAdminNegativeV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/admin/test_hypervisor.py b/tempest/api/compute/v3/admin/test_hypervisor.py
index 0f96bba..93d4441 100644
--- a/tempest/api/compute/v3/admin/test_hypervisor.py
+++ b/tempest/api/compute/v3/admin/test_hypervisor.py
@@ -23,8 +23,6 @@
     Tests Hypervisors API that require admin privileges
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(HypervisorAdminV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/admin/test_hypervisor_negative.py b/tempest/api/compute/v3/admin/test_hypervisor_negative.py
index aee354a..45642b7 100644
--- a/tempest/api/compute/v3/admin/test_hypervisor_negative.py
+++ b/tempest/api/compute/v3/admin/test_hypervisor_negative.py
@@ -27,8 +27,6 @@
     Tests Hypervisors API that require admin privileges
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(HypervisorAdminNegativeV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/admin/test_quotas.py b/tempest/api/compute/v3/admin/test_quotas.py
index b388b70..0c138bb 100644
--- a/tempest/api/compute/v3/admin/test_quotas.py
+++ b/tempest/api/compute/v3/admin/test_quotas.py
@@ -22,7 +22,6 @@
 
 
 class QuotasAdminV3Test(base.BaseV3ComputeAdminTest):
-    _interface = 'json'
     force_tenant_isolation = True
 
     @classmethod
diff --git a/tempest/api/compute/v3/admin/test_quotas_negative.py b/tempest/api/compute/v3/admin/test_quotas_negative.py
index c9f14f8..d138e80 100644
--- a/tempest/api/compute/v3/admin/test_quotas_negative.py
+++ b/tempest/api/compute/v3/admin/test_quotas_negative.py
@@ -20,7 +20,6 @@
 
 
 class QuotasAdminNegativeV3Test(base.BaseV3ComputeAdminTest):
-    _interface = 'json'
     force_tenant_isolation = True
 
     @classmethod
diff --git a/tempest/api/compute/v3/admin/test_servers.py b/tempest/api/compute/v3/admin/test_servers.py
index 0dc3dbc..fb8afe4 100644
--- a/tempest/api/compute/v3/admin/test_servers.py
+++ b/tempest/api/compute/v3/admin/test_servers.py
@@ -25,7 +25,6 @@
     """
 
     _host_key = 'os-extended-server-attributes:host'
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -175,3 +174,13 @@
         resp, server = self.non_admin_client.get_server(rebuilt_server['id'])
         rebuilt_image_id = server['image']['id']
         self.assertEqual(self.image_ref_alt, rebuilt_image_id)
+
+    @test.attr(type='gate')
+    def test_reset_network_inject_network_info(self):
+        resp, server = self.create_test_server(wait_until='ACTIVE')
+        # Reset Network of a Server
+        resp, server_body = self.client.reset_network(server['id'])
+        self.assertEqual(202, resp.status)
+        # Inject the Network Info into Server
+        resp, server = self.client.inject_network_info(server['id'])
+        self.assertEqual(202, resp.status)
diff --git a/tempest/api/compute/v3/admin/test_servers_negative.py b/tempest/api/compute/v3/admin/test_servers_negative.py
index a6a5736..cc1be4e 100644
--- a/tempest/api/compute/v3/admin/test_servers_negative.py
+++ b/tempest/api/compute/v3/admin/test_servers_negative.py
@@ -26,8 +26,6 @@
     Tests Servers API using admin privileges
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(ServersAdminNegativeV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/admin/test_services.py b/tempest/api/compute/v3/admin/test_services.py
index 8d6e549..0a7c7f1 100644
--- a/tempest/api/compute/v3/admin/test_services.py
+++ b/tempest/api/compute/v3/admin/test_services.py
@@ -14,6 +14,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest.api.compute.api_schema import services as schema
 from tempest.api.compute import base
 from tempest.test import attr
 
@@ -24,8 +25,6 @@
     Tests Services API. List and Enable/Disable require admin privileges.
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(ServicesAdminV3Test, cls).setUpClass()
@@ -34,7 +33,7 @@
     @attr(type='gate')
     def test_list_services(self):
         resp, services = self.client.list_services()
-        self.assertEqual(200, resp.status)
+        self.validate_response(schema.list_services, resp, services)
         self.assertNotEqual(0, len(services))
 
     @attr(type='gate')
@@ -42,7 +41,7 @@
         binary_name = 'nova-compute'
         params = {'binary': binary_name}
         resp, services = self.client.list_services(params)
-        self.assertEqual(200, resp.status)
+        self.validate_response(schema.list_services, resp, services)
         self.assertNotEqual(0, len(services))
         for service in services:
             self.assertEqual(binary_name, service['binary'])
@@ -50,11 +49,14 @@
     @attr(type='gate')
     def test_get_service_by_host_name(self):
         resp, services = self.client.list_services()
+        self.validate_response(schema.list_services, resp, services)
         host_name = services[0]['host']
         services_on_host = [service for service in services if
                             service['host'] == host_name]
         params = {'host': host_name}
+
         resp, services = self.client.list_services(params)
+        self.validate_response(schema.list_services, resp, services)
 
         # we could have a periodic job checkin between the 2 service
         # lookups, so only compare binary lists.
@@ -68,11 +70,13 @@
     @attr(type='gate')
     def test_get_service_by_service_and_host_name(self):
         resp, services = self.client.list_services()
+        self.validate_response(schema.list_services, resp, services)
         host_name = services[0]['host']
         binary_name = services[0]['binary']
         params = {'host': host_name, 'binary': binary_name}
+
         resp, services = self.client.list_services(params)
-        self.assertEqual(200, resp.status)
+        self.validate_response(schema.list_services, resp, services)
         self.assertEqual(1, len(services))
         self.assertEqual(host_name, services[0]['host'])
         self.assertEqual(binary_name, services[0]['binary'])
diff --git a/tempest/api/compute/v3/admin/test_services_negative.py b/tempest/api/compute/v3/admin/test_services_negative.py
index c270842..3168af2 100644
--- a/tempest/api/compute/v3/admin/test_services_negative.py
+++ b/tempest/api/compute/v3/admin/test_services_negative.py
@@ -25,8 +25,6 @@
     Tests Services API. List and Enable/Disable require admin privileges.
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(ServicesAdminNegativeV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/certificates/test_certificates.py b/tempest/api/compute/v3/certificates/test_certificates.py
index 5c980c0..ce025fc 100644
--- a/tempest/api/compute/v3/certificates/test_certificates.py
+++ b/tempest/api/compute/v3/certificates/test_certificates.py
@@ -18,7 +18,6 @@
 
 
 class CertificatesV3Test(base.BaseV3ComputeTest):
-    _interface = 'json'
 
     @attr(type='gate')
     def test_create_and_get_root_certificate(self):
diff --git a/tempest/api/compute/v3/flavors/test_flavors.py b/tempest/api/compute/v3/flavors/test_flavors.py
index 812358f..a0bbba6 100644
--- a/tempest/api/compute/v3/flavors/test_flavors.py
+++ b/tempest/api/compute/v3/flavors/test_flavors.py
@@ -18,7 +18,6 @@
 
 
 class FlavorsV3Test(base.BaseV3ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/v3/flavors/test_flavors_negative.py b/tempest/api/compute/v3/flavors/test_flavors_negative.py
index 3d4100a..346f6d6 100644
--- a/tempest/api/compute/v3/flavors/test_flavors_negative.py
+++ b/tempest/api/compute/v3/flavors/test_flavors_negative.py
@@ -24,7 +24,6 @@
 
 class FlavorsListNegativeV3Test(base.BaseV3ComputeTest,
                                 test.NegativeAutoTest):
-    _interface = 'json'
     _service = 'computev3'
     _schema_file = 'compute/flavors/flavors_list_v3.json'
 
@@ -37,7 +36,6 @@
 
 class FlavorDetailsNegativeV3Test(base.BaseV3ComputeTest,
                                   test.NegativeAutoTest):
-    _interface = 'json'
     _service = 'computev3'
     _schema_file = 'compute/flavors/flavor_details_v3.json'
 
diff --git a/tempest/api/compute/v3/images/test_images.py b/tempest/api/compute/v3/images/test_images.py
index b045630..bb81626 100644
--- a/tempest/api/compute/v3/images/test_images.py
+++ b/tempest/api/compute/v3/images/test_images.py
@@ -15,14 +15,12 @@
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
 
 
 class ImagesV3Test(base.BaseV3ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -31,42 +29,8 @@
             skip_msg = ("%s skipped as glance is not available" % cls.__name__)
             raise cls.skipException(skip_msg)
         cls.client = cls.images_client
-        cls.servers_client = cls.servers_client
 
-    def __create_image__(self, server_id, name, meta=None):
-        resp, body = self.servers_client.create_image(server_id, name, meta)
-        image_id = data_utils.parse_image_id(resp['location'])
-        self.addCleanup(self.client.delete_image, image_id)
-        self.client.wait_for_image_status(image_id, 'ACTIVE')
-        return resp, body
-
-    @test.attr(type=['negative', 'gate'])
-    def test_create_image_from_deleted_server(self):
-        # An image should not be created if the server instance is removed
-        resp, server = self.create_test_server(wait_until='ACTIVE')
-
-        # Delete server before trying to create server
-        self.servers_client.delete_server(server['id'])
-        self.servers_client.wait_for_server_termination(server['id'])
-        # Create a new image after server is deleted
-        name = data_utils.rand_name('image')
-        meta = {'image_type': 'test'}
-        self.assertRaises(exceptions.NotFound,
-                          self.__create_image__,
-                          server['id'], name, meta)
-
-    @test.attr(type=['negative', 'gate'])
-    def test_create_image_from_invalid_server(self):
-        # An image should not be created with invalid server id
-        # Create a new image with invalid server id
-        name = data_utils.rand_name('image')
-        meta = {'image_type': 'test'}
-        resp = {}
-        resp['status'] = None
-        self.assertRaises(exceptions.NotFound, self.__create_image__,
-                          '!@#$%^&*()', name, meta)
-
-    @test.attr(type=['negative', 'gate'])
+    @test.attr(type='gate')
     def test_create_image_from_stopped_server(self):
         resp, server = self.create_test_server(wait_until='ACTIVE')
         self.servers_client.stop(server['id'])
@@ -90,21 +54,3 @@
                                                     wait_until='queued')
         resp, body = self.client.delete_image(image['id'])
         self.assertEqual('200', resp['status'])
-
-    @test.attr(type=['negative', 'gate'])
-    def test_create_image_specify_uuid_35_characters_or_less(self):
-        # Return an error if Image ID passed is 35 characters or less
-        snapshot_name = data_utils.rand_name('test-snap-')
-        test_uuid = ('a' * 35)
-        self.assertRaises(exceptions.NotFound,
-                          self.servers_client.create_image,
-                          test_uuid, snapshot_name)
-
-    @test.attr(type=['negative', 'gate'])
-    def test_create_image_specify_uuid_37_characters_or_more(self):
-        # Return an error if Image ID passed is 37 characters or more
-        snapshot_name = data_utils.rand_name('test-snap-')
-        test_uuid = ('a' * 37)
-        self.assertRaises(exceptions.NotFound,
-                          self.servers_client.create_image,
-                          test_uuid, snapshot_name)
diff --git a/tempest/api/compute/v3/images/test_images_negative.py b/tempest/api/compute/v3/images/test_images_negative.py
new file mode 100644
index 0000000..c38373f
--- /dev/null
+++ b/tempest/api/compute/v3/images/test_images_negative.py
@@ -0,0 +1,82 @@
+# Copyright 2014 NEC Corporation.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.api.compute import base
+from tempest.common.utils import data_utils
+from tempest import config
+from tempest import exceptions
+from tempest import test
+
+CONF = config.CONF
+
+
+class ImagesNegativeV3Test(base.BaseV3ComputeTest):
+
+    @classmethod
+    def setUpClass(cls):
+        super(ImagesNegativeV3Test, cls).setUpClass()
+        if not CONF.service_available.glance:
+            skip_msg = ("%s skipped as glance is not available" % cls.__name__)
+            raise cls.skipException(skip_msg)
+        cls.client = cls.images_client
+
+    def __create_image__(self, server_id, name, meta=None):
+        resp, body = self.servers_client.create_image(server_id, name, meta)
+        image_id = data_utils.parse_image_id(resp['location'])
+        self.addCleanup(self.client.delete_image, image_id)
+        self.client.wait_for_image_status(image_id, 'ACTIVE')
+        return resp, body
+
+    @test.attr(type=['negative', 'gate'])
+    def test_create_image_from_deleted_server(self):
+        # An image should not be created if the server instance is removed
+        resp, server = self.create_test_server(wait_until='ACTIVE')
+
+        # Delete server before trying to create server
+        self.servers_client.delete_server(server['id'])
+        self.servers_client.wait_for_server_termination(server['id'])
+        # Create a new image after server is deleted
+        name = data_utils.rand_name('image')
+        meta = {'image_type': 'test'}
+        self.assertRaises(exceptions.NotFound,
+                          self.__create_image__,
+                          server['id'], name, meta)
+
+    @test.attr(type=['negative', 'gate'])
+    def test_create_image_from_nonexistent_server(self):
+        # An image should not be created with invalid server id
+        # Create a new image with invalid server id
+        nonexistent_server_id = data_utils.rand_uuid()
+        name = data_utils.rand_name('image')
+        meta = {'image_type': 'test'}
+        self.assertRaises(exceptions.NotFound, self.__create_image__,
+                          nonexistent_server_id, name, meta)
+
+    @test.attr(type=['negative', 'gate'])
+    def test_create_image_specify_uuid_35_characters_or_less(self):
+        # Return an error if Image ID passed is 35 characters or less
+        snapshot_name = data_utils.rand_name('test-snap-')
+        test_uuid = ('a' * 35)
+        self.assertRaises(exceptions.NotFound,
+                          self.servers_client.create_image,
+                          test_uuid, snapshot_name)
+
+    @test.attr(type=['negative', 'gate'])
+    def test_create_image_specify_uuid_37_characters_or_more(self):
+        # Return an error if Image ID passed is 37 characters or more
+        snapshot_name = data_utils.rand_name('test-snap-')
+        test_uuid = ('a' * 37)
+        self.assertRaises(exceptions.NotFound,
+                          self.servers_client.create_image,
+                          test_uuid, snapshot_name)
diff --git a/tempest/api/compute/v3/images/test_images_oneserver.py b/tempest/api/compute/v3/images/test_images_oneserver.py
index 1ded4e4..48a885e 100644
--- a/tempest/api/compute/v3/images/test_images_oneserver.py
+++ b/tempest/api/compute/v3/images/test_images_oneserver.py
@@ -26,7 +26,6 @@
 
 
 class ImagesOneServerV3Test(base.BaseV3ComputeTest):
-    _interface = 'json'
 
     def setUp(self):
         # NOTE(afazekas): Normally we use the same server with all test cases,
diff --git a/tempest/api/compute/v3/images/test_images_oneserver_negative.py b/tempest/api/compute/v3/images/test_images_oneserver_negative.py
index 8d2517e..7679eee 100644
--- a/tempest/api/compute/v3/images/test_images_oneserver_negative.py
+++ b/tempest/api/compute/v3/images/test_images_oneserver_negative.py
@@ -27,7 +27,6 @@
 
 
 class ImagesOneServerNegativeV3Test(base.BaseV3ComputeTest):
-    _interface = 'json'
 
     def tearDown(self):
         """Terminate test instances created after a test is executed."""
diff --git a/tempest/api/compute/v3/keypairs/test_keypairs.py b/tempest/api/compute/v3/keypairs/test_keypairs.py
index 8eef811..668a295 100644
--- a/tempest/api/compute/v3/keypairs/test_keypairs.py
+++ b/tempest/api/compute/v3/keypairs/test_keypairs.py
@@ -19,7 +19,6 @@
 
 
 class KeyPairsV3Test(base.BaseV3ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/v3/keypairs/test_keypairs_negative.py b/tempest/api/compute/v3/keypairs/test_keypairs_negative.py
index ae22ccc..e426b85 100644
--- a/tempest/api/compute/v3/keypairs/test_keypairs_negative.py
+++ b/tempest/api/compute/v3/keypairs/test_keypairs_negative.py
@@ -21,7 +21,6 @@
 
 
 class KeyPairsNegativeV3Test(base.BaseV3ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/v3/servers/test_attach_interfaces.py b/tempest/api/compute/v3/servers/test_attach_interfaces.py
index 272cb53..e1c69d9 100644
--- a/tempest/api/compute/v3/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/v3/servers/test_attach_interfaces.py
@@ -24,7 +24,6 @@
 
 
 class AttachInterfacesV3Test(base.BaseV3ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -48,6 +47,7 @@
     def _create_server_get_interfaces(self):
         resp, server = self.create_test_server(wait_until='ACTIVE')
         resp, ifs = self.client.list_interfaces(server['id'])
+        self.assertEqual(200, resp.status)
         resp, body = self.client.wait_for_interface_status(
             server['id'], ifs[0]['port_id'], 'ACTIVE')
         ifs[0]['port_state'] = body['port_state']
@@ -55,6 +55,7 @@
 
     def _test_create_interface(self, server):
         resp, iface = self.client.create_interface(server['id'])
+        self.assertEqual(200, resp.status)
         resp, iface = self.client.wait_for_interface_status(
             server['id'], iface['port_id'], 'ACTIVE')
         self._check_interface(iface)
@@ -64,6 +65,7 @@
         network_id = ifs[0]['net_id']
         resp, iface = self.client.create_interface(server['id'],
                                                    network_id=network_id)
+        self.assertEqual(200, resp.status)
         resp, iface = self.client.wait_for_interface_status(
             server['id'], iface['port_id'], 'ACTIVE')
         self._check_interface(iface, network_id=network_id)
@@ -73,12 +75,14 @@
         iface = ifs[0]
         resp, _iface = self.client.show_interface(server['id'],
                                                   iface['port_id'])
+        self.assertEqual(200, resp.status)
         self.assertEqual(iface, _iface)
 
     def _test_delete_interface(self, server, ifs):
         # NOTE(danms): delete not the first or last, but one in the middle
         iface = ifs[1]
-        self.client.delete_interface(server['id'], iface['port_id'])
+        resp, _ = self.client.delete_interface(server['id'], iface['port_id'])
+        self.assertEqual(202, resp.status)
         _ifs = self.client.list_interfaces(server['id'])[1]
         start = int(time.time())
 
@@ -122,3 +126,30 @@
 
         _ifs = self._test_delete_interface(server, ifs)
         self.assertEqual(len(ifs) - 1, len(_ifs))
+
+    @attr(type='gate')
+    def test_add_remove_fixed_ip(self):
+        # Add and Remove the fixed IP to server.
+        server, ifs = self._create_server_get_interfaces()
+        interface_count = len(ifs)
+        self.assertGreater(interface_count, 0)
+        self._check_interface(ifs[0])
+        network_id = ifs[0]['net_id']
+        resp, body = self.client.add_fixed_ip(server['id'],
+                                              network_id)
+        self.assertEqual(202, resp.status)
+        server_resp, server_detail = self.servers_client.get_server(
+            server['id'])
+        # Get the Fixed IP from server.
+        fixed_ip = None
+        for ip_set in server_detail['addresses']:
+            for ip in server_detail['addresses'][ip_set]:
+                if ip['type'] == 'fixed':
+                    fixed_ip = ip['addr']
+                    break
+            if fixed_ip is not None:
+                break
+        # Remove the fixed IP from server.
+        resp, body = self.client.remove_fixed_ip(server['id'],
+                                                 fixed_ip)
+        self.assertEqual(202, resp.status)
diff --git a/tempest/api/compute/v3/servers/test_attach_volume.py b/tempest/api/compute/v3/servers/test_attach_volume.py
index 2edf934..8577aab 100644
--- a/tempest/api/compute/v3/servers/test_attach_volume.py
+++ b/tempest/api/compute/v3/servers/test_attach_volume.py
@@ -24,7 +24,6 @@
 
 
 class AttachVolumeV3Test(base.BaseV3ComputeTest):
-    _interface = 'json'
     run_ssh = CONF.compute.run_ssh
 
     def __init__(self, *args, **kwargs):
diff --git a/tempest/api/compute/v3/servers/test_availability_zone.py b/tempest/api/compute/v3/servers/test_availability_zone.py
index feac9a1..5a1e07e 100644
--- a/tempest/api/compute/v3/servers/test_availability_zone.py
+++ b/tempest/api/compute/v3/servers/test_availability_zone.py
@@ -23,8 +23,6 @@
     Tests Availability Zone API List
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(AZV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/servers/test_create_server.py b/tempest/api/compute/v3/servers/test_create_server.py
index 0825381..a212ca5 100644
--- a/tempest/api/compute/v3/servers/test_create_server.py
+++ b/tempest/api/compute/v3/servers/test_create_server.py
@@ -28,7 +28,6 @@
 
 
 class ServersV3Test(base.BaseV3ComputeTest):
-    _interface = 'json'
     run_ssh = CONF.compute.run_ssh
     disk_config = 'AUTO'
 
@@ -119,7 +118,6 @@
 
 
 class ServersWithSpecificFlavorV3Test(base.BaseV3ComputeAdminTest):
-    _interface = 'json'
     run_ssh = CONF.compute.run_ssh
     disk_config = 'AUTO'
 
diff --git a/tempest/api/compute/v3/servers/test_delete_server.py b/tempest/api/compute/v3/servers/test_delete_server.py
index f53ab6e..d694a33 100644
--- a/tempest/api/compute/v3/servers/test_delete_server.py
+++ b/tempest/api/compute/v3/servers/test_delete_server.py
@@ -12,6 +12,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import testtools
+
 from tempest.api.compute import base
 from tempest import config
 from tempest import test
@@ -22,7 +24,6 @@
 class DeleteServersV3Test(base.BaseV3ComputeTest):
     # NOTE: Server creations of each test class should be under 10
     # for preventing "Quota exceeded for instances".
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -35,6 +36,7 @@
         resp, server = self.create_test_server(wait_until='BUILD')
         resp, _ = self.client.delete_server(server['id'])
         self.assertEqual('204', resp['status'])
+        self.client.wait_for_server_termination(server['id'])
 
     @test.attr(type='gate')
     def test_delete_active_server(self):
@@ -42,6 +44,7 @@
         resp, server = self.create_test_server(wait_until='ACTIVE')
         resp, _ = self.client.delete_server(server['id'])
         self.assertEqual('204', resp['status'])
+        self.client.wait_for_server_termination(server['id'])
 
     @test.attr(type='gate')
     def test_delete_server_while_in_shutoff_state(self):
@@ -51,6 +54,7 @@
         self.client.wait_for_server_status(server['id'], 'SHUTOFF')
         resp, _ = self.client.delete_server(server['id'])
         self.assertEqual('204', resp['status'])
+        self.client.wait_for_server_termination(server['id'])
 
     @test.attr(type='gate')
     def test_delete_server_while_in_pause_state(self):
@@ -60,6 +64,7 @@
         self.client.wait_for_server_status(server['id'], 'PAUSED')
         resp, _ = self.client.delete_server(server['id'])
         self.assertEqual('204', resp['status'])
+        self.client.wait_for_server_termination(server['id'])
 
     @test.attr(type='gate')
     def test_delete_server_while_in_shelved_state(self):
@@ -79,12 +84,25 @@
 
         resp, _ = self.client.delete_server(server['id'])
         self.assertEqual('204', resp['status'])
+        self.client.wait_for_server_termination(server['id'])
+
+    @testtools.skipIf(not CONF.compute_feature_enabled.resize,
+                      'Resize not available.')
+    @test.attr(type='gate')
+    def test_delete_server_while_in_verify_resize_state(self):
+        # Delete a server while it's VM state is VERIFY_RESIZE
+        resp, server = self.create_test_server(wait_until='ACTIVE')
+        resp, body = self.client.resize(server['id'], self.flavor_ref_alt)
+        self.assertEqual(202, resp.status)
+        self.client.wait_for_server_status(server['id'], 'VERIFY_RESIZE')
+        resp, _ = self.client.delete_server(server['id'])
+        self.assertEqual('204', resp['status'])
+        self.client.wait_for_server_termination(server['id'])
 
 
 class DeleteServersAdminV3Test(base.BaseV3ComputeAdminTest):
     # NOTE: Server creations of each test class should be under 10
     # for preventing "Quota exceeded for instances".
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -103,6 +121,8 @@
         self.assertEqual(server['status'], 'ERROR')
         resp, _ = self.non_admin_client.delete_server(server['id'])
         self.assertEqual('204', resp['status'])
+        self.servers_client.wait_for_server_termination(server['id'],
+                                                        ignore_error=True)
 
     @test.attr(type='gate')
     def test_admin_delete_servers_of_others(self):
diff --git a/tempest/api/compute/v3/servers/test_instance_actions.py b/tempest/api/compute/v3/servers/test_instance_actions.py
index c4f6e14..7d25100 100644
--- a/tempest/api/compute/v3/servers/test_instance_actions.py
+++ b/tempest/api/compute/v3/servers/test_instance_actions.py
@@ -18,14 +18,13 @@
 
 
 class InstanceActionsV3Test(base.BaseV3ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
         super(InstanceActionsV3Test, cls).setUpClass()
         cls.client = cls.servers_client
         resp, server = cls.create_test_server(wait_until='ACTIVE')
-        cls.request_id = resp['x-compute-request-id']
+        cls.resp = resp
         cls.server_id = server['id']
 
     @test.attr(type='gate')
@@ -41,10 +40,12 @@
         self.assertTrue(any([i for i in body if i['action'] == 'reboot']))
 
     @test.attr(type='gate')
+    @test.skip_because(bug="1281915")
     def test_get_instance_action(self):
         # Get the action details of the provided server
+        request_id = self.resp['x-compute-request-id']
         resp, body = self.client.get_instance_action(self.server_id,
-                                                     self.request_id)
+                                                     request_id)
         self.assertEqual(200, resp.status)
         self.assertEqual(self.server_id, body['instance_uuid'])
         self.assertEqual('create', body['action'])
diff --git a/tempest/api/compute/v3/servers/test_instance_actions_negative.py b/tempest/api/compute/v3/servers/test_instance_actions_negative.py
index bd741e0..b0a7050 100644
--- a/tempest/api/compute/v3/servers/test_instance_actions_negative.py
+++ b/tempest/api/compute/v3/servers/test_instance_actions_negative.py
@@ -20,7 +20,6 @@
 
 
 class InstanceActionsNegativeV3Test(base.BaseV3ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/v3/servers/test_list_server_filters.py b/tempest/api/compute/v3/servers/test_list_server_filters.py
index e08125b..ec31e8e 100644
--- a/tempest/api/compute/v3/servers/test_list_server_filters.py
+++ b/tempest/api/compute/v3/servers/test_list_server_filters.py
@@ -24,7 +24,6 @@
 
 
 class ListServerFiltersV3Test(base.BaseV3ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/v3/servers/test_list_servers_negative.py b/tempest/api/compute/v3/servers/test_list_servers_negative.py
index 09e1bb6..92f44fe 100644
--- a/tempest/api/compute/v3/servers/test_list_servers_negative.py
+++ b/tempest/api/compute/v3/servers/test_list_servers_negative.py
@@ -15,13 +15,14 @@
 
 import datetime
 
+from six import moves
+
 from tempest.api.compute import base
 from tempest import exceptions
 from tempest.test import attr
 
 
 class ListServersNegativeV3Test(base.BaseV3ComputeTest):
-    _interface = 'json'
     force_tenant_isolation = True
 
     @classmethod
@@ -36,7 +37,7 @@
         cls.existing_fixtures = []
         cls.deleted_fixtures = []
         cls.start_time = datetime.datetime.utcnow()
-        for x in xrange(2):
+        for x in moves.xrange(2):
             resp, srv = cls.create_test_server()
             cls.existing_fixtures.append(srv)
 
diff --git a/tempest/api/compute/v3/servers/test_multiple_create.py b/tempest/api/compute/v3/servers/test_multiple_create.py
index dee4407..23e0854 100644
--- a/tempest/api/compute/v3/servers/test_multiple_create.py
+++ b/tempest/api/compute/v3/servers/test_multiple_create.py
@@ -19,7 +19,6 @@
 
 
 class MultipleCreateV3Test(base.BaseV3ComputeTest):
-    _interface = 'json'
     _name = 'multiple-create-test'
 
     def _generate_name(self):
diff --git a/tempest/api/compute/v3/servers/test_multiple_create_negative.py b/tempest/api/compute/v3/servers/test_multiple_create_negative.py
index 57bb807..f208bc0 100644
--- a/tempest/api/compute/v3/servers/test_multiple_create_negative.py
+++ b/tempest/api/compute/v3/servers/test_multiple_create_negative.py
@@ -20,7 +20,6 @@
 
 
 class MultipleCreateV3NegativeTest(base.BaseV3ComputeTest):
-    _interface = 'json'
     _name = 'multiple-create-negative-test'
 
     def _generate_name(self):
diff --git a/tempest/api/compute/v3/servers/test_server_actions.py b/tempest/api/compute/v3/servers/test_server_actions.py
index 6584b93..555d028 100644
--- a/tempest/api/compute/v3/servers/test_server_actions.py
+++ b/tempest/api/compute/v3/servers/test_server_actions.py
@@ -28,7 +28,6 @@
 
 
 class ServerActionsV3Test(base.BaseV3ComputeTest):
-    _interface = 'json'
     resize_available = CONF.compute_feature_enabled.resize
     run_ssh = CONF.compute.run_ssh
 
@@ -373,6 +372,11 @@
             self.client.wait_for_server_status(self.server_id,
                                                'SHELVED')
 
+            resp, server = self.client.shelve_offload_server(self.server_id)
+            self.assertEqual(202, resp.status)
+            self.client.wait_for_server_status(self.server_id,
+                                               'SHELVED_OFFLOADED')
+
         resp, server = self.client.get_server(self.server_id)
         image_name = server['name'] + '-shelved'
         resp, images = self.images_client.image_list(name=image_name)
@@ -411,3 +415,16 @@
         resp, server = self.servers_client.start(self.server_id)
         self.assertEqual(202, resp.status)
         self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
+
+    @testtools.skipUnless(CONF.compute_feature_enabled.vnc_console,
+                          'VNC Console feature is disabled')
+    @test.attr(type='gate')
+    def test_get_vnc_console(self):
+        # Get the VNC console
+        console_types = ['novnc', 'xvpvnc']
+        for console_type in console_types:
+            resp, body = self.servers_client.get_vnc_console(self.server_id,
+                                                             console_type)
+            self.assertEqual(200, resp.status)
+            self.assertEqual(console_type, body['type'])
+            self.assertNotEqual('', body['url'])
diff --git a/tempest/api/compute/v3/servers/test_server_addresses.py b/tempest/api/compute/v3/servers/test_server_addresses.py
index 038e254..efd7500 100644
--- a/tempest/api/compute/v3/servers/test_server_addresses.py
+++ b/tempest/api/compute/v3/servers/test_server_addresses.py
@@ -15,14 +15,12 @@
 
 from tempest.api.compute import base
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
 
 
 class ServerAddressesV3Test(base.BaseV3ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -33,19 +31,6 @@
 
         resp, cls.server = cls.create_test_server(wait_until='ACTIVE')
 
-    @test.attr(type=['negative', 'gate'])
-    def test_list_server_addresses_invalid_server_id(self):
-        # List addresses request should fail if server id not in system
-        self.assertRaises(exceptions.NotFound, self.client.list_addresses,
-                          '999')
-
-    @test.attr(type=['negative', 'gate'])
-    def test_list_server_addresses_by_network_neg(self):
-        # List addresses by network should fail if network name not valid
-        self.assertRaises(exceptions.NotFound,
-                          self.client.list_addresses_by_network,
-                          self.server['id'], 'invalid')
-
     @test.skip_because(bug="1210483",
                        condition=CONF.service_available.neutron)
     @test.attr(type='smoke')
diff --git a/tempest/api/compute/v3/servers/test_server_addresses_negative.py b/tempest/api/compute/v3/servers/test_server_addresses_negative.py
new file mode 100644
index 0000000..8a9877b
--- /dev/null
+++ b/tempest/api/compute/v3/servers/test_server_addresses_negative.py
@@ -0,0 +1,46 @@
+# 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.compute import base
+from tempest.common.utils import data_utils
+from tempest import exceptions
+from tempest import test
+
+
+class ServerAddressesV3NegativeTest(base.BaseV3ComputeTest):
+    _interface = 'json'
+
+    @classmethod
+    def setUpClass(cls):
+        # This test module might use a network and a subnet
+        cls.set_network_resources(network=True, subnet=True)
+        super(ServerAddressesV3NegativeTest, cls).setUpClass()
+        cls.client = cls.servers_client
+
+        resp, cls.server = cls.create_test_server(wait_until='ACTIVE')
+
+    @test.attr(type=['negative', 'gate'])
+    def test_list_server_addresses_nonexistent_server_id(self):
+        # List addresses request should fail if server id not in system
+        non_existent_server_id = data_utils.rand_uuid()
+        self.assertRaises(exceptions.NotFound, self.client.list_addresses,
+                          non_existent_server_id)
+
+    @test.attr(type=['negative', 'gate'])
+    def test_list_server_addresses_by_network_neg(self):
+        # List addresses by network should fail if network name not valid
+        self.assertRaises(exceptions.NotFound,
+                          self.client.list_addresses_by_network,
+                          self.server['id'], 'invalid')
diff --git a/tempest/api/compute/v3/servers/test_server_metadata.py b/tempest/api/compute/v3/servers/test_server_metadata.py
index 13c82dd..0e4ef07 100644
--- a/tempest/api/compute/v3/servers/test_server_metadata.py
+++ b/tempest/api/compute/v3/servers/test_server_metadata.py
@@ -18,7 +18,6 @@
 
 
 class ServerMetadataV3Test(base.BaseV3ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/v3/servers/test_server_metadata_negative.py b/tempest/api/compute/v3/servers/test_server_metadata_negative.py
index ce6c340..ec2bc8c 100644
--- a/tempest/api/compute/v3/servers/test_server_metadata_negative.py
+++ b/tempest/api/compute/v3/servers/test_server_metadata_negative.py
@@ -19,7 +19,6 @@
 
 
 class ServerMetadataV3NegativeTest(base.BaseV3ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/v3/servers/test_server_password.py b/tempest/api/compute/v3/servers/test_server_password.py
index 579a8a5..fc0b145 100644
--- a/tempest/api/compute/v3/servers/test_server_password.py
+++ b/tempest/api/compute/v3/servers/test_server_password.py
@@ -19,7 +19,6 @@
 
 
 class ServerPasswordV3Test(base.BaseV3ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/v3/servers/test_server_rescue.py b/tempest/api/compute/v3/servers/test_server_rescue.py
index fa7def0..b3dcb51 100644
--- a/tempest/api/compute/v3/servers/test_server_rescue.py
+++ b/tempest/api/compute/v3/servers/test_server_rescue.py
@@ -14,67 +14,22 @@
 #    under the License.
 
 from tempest.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class ServerRescueV3Test(base.BaseV3ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
         super(ServerRescueV3Test, cls).setUpClass()
-        cls.device = 'vdf'
-
-        # Create a volume and wait for it to become ready for attach
-        resp, cls.volume = cls.volumes_client.create_volume(
-            1, display_name=data_utils.rand_name(cls.__name__ + '_volume'))
-        cls.volumes_client.wait_for_volume_status(
-            cls.volume['id'], 'available')
 
         # Server for positive tests
         resp, server = cls.create_test_server(wait_until='BUILD')
-        resp, resc_server = cls.create_test_server(wait_until='ACTIVE')
         cls.server_id = server['id']
         cls.password = server['admin_password']
         cls.servers_client.wait_for_server_status(cls.server_id, 'ACTIVE')
 
-        # Server for negative tests
-        cls.rescue_id = resc_server['id']
-        cls.rescue_password = resc_server['admin_password']
-
-        cls.servers_client.rescue_server(
-            cls.rescue_id, admin_password=cls.rescue_password)
-        cls.servers_client.wait_for_server_status(cls.rescue_id, 'RESCUE')
-
-    def setUp(self):
-        super(ServerRescueV3Test, self).setUp()
-
-    @classmethod
-    def tearDownClass(cls):
-        cls.delete_volume(cls.volume['id'])
-        super(ServerRescueV3Test, cls).tearDownClass()
-
-    def tearDown(self):
-        super(ServerRescueV3Test, self).tearDown()
-
-    def _detach(self, server_id, volume_id):
-        self.servers_client.detach_volume(server_id, volume_id)
-        self.volumes_client.wait_for_volume_status(volume_id,
-                                                   'available')
-
-    def _unrescue(self, server_id):
-        resp, body = self.servers_client.unrescue_server(server_id)
-        self.assertEqual(202, resp.status)
-        self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
-
-    def _unpause(self, server_id):
-        resp, body = self.servers_client.unpause_server(server_id)
-        self.assertEqual(202, resp.status)
-        self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
-
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_rescue_unrescue_instance(self):
         resp, body = self.servers_client.rescue_server(
             self.server_id, admin_password=self.password)
@@ -83,71 +38,3 @@
         resp, body = self.servers_client.unrescue_server(self.server_id)
         self.assertEqual(202, resp.status)
         self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
-
-    @attr(type=['negative', 'gate'])
-    def test_rescue_paused_instance(self):
-        # Rescue a paused server
-        resp, body = self.servers_client.pause_server(
-            self.server_id)
-        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.Conflict,
-                          self.servers_client.rescue_server,
-                          self.server_id)
-
-    @attr(type=['negative', 'gate'])
-    def test_rescued_vm_reboot(self):
-        self.assertRaises(exceptions.Conflict, self.servers_client.reboot,
-                          self.rescue_id, 'HARD')
-
-    @attr(type=['negative', 'gate'])
-    def test_rescue_non_existent_server(self):
-        # Rescue a non-existing server
-        self.assertRaises(exceptions.NotFound,
-                          self.servers_client.rescue_server,
-                          '999erra43')
-
-    @attr(type=['negative', 'gate'])
-    def test_rescued_vm_rebuild(self):
-        self.assertRaises(exceptions.Conflict,
-                          self.servers_client.rebuild,
-                          self.rescue_id,
-                          self.image_ref_alt)
-
-    @attr(type=['negative', 'gate'])
-    def test_rescued_vm_attach_volume(self):
-        # Rescue the server
-        self.servers_client.rescue_server(self.server_id,
-                                          admin_password=self.password)
-        self.servers_client.wait_for_server_status(self.server_id, 'RESCUE')
-        self.addCleanup(self._unrescue, self.server_id)
-
-        # Attach the volume to the server
-        self.assertRaises(exceptions.Conflict,
-                          self.servers_client.attach_volume,
-                          self.server_id,
-                          self.volume['id'],
-                          device='/dev/%s' % self.device)
-
-    @attr(type=['negative', 'gate'])
-    def test_rescued_vm_detach_volume(self):
-        # Attach the volume to the server
-        self.servers_client.attach_volume(self.server_id,
-                                          self.volume['id'],
-                                          device='/dev/%s' % self.device)
-        self.volumes_client.wait_for_volume_status(self.volume['id'], 'in-use')
-
-        # Rescue the server
-        self.servers_client.rescue_server(self.server_id,
-                                          admin_password=self.password)
-        self.servers_client.wait_for_server_status(self.server_id, 'RESCUE')
-        # addCleanup is a LIFO queue
-        self.addCleanup(self._detach, self.server_id, self.volume['id'])
-        self.addCleanup(self._unrescue, self.server_id)
-
-        # Detach the volume from the server expecting failure
-        self.assertRaises(exceptions.Conflict,
-                          self.servers_client.detach_volume,
-                          self.server_id,
-                          self.volume['id'])
diff --git a/tempest/api/compute/v3/servers/test_server_rescue_negative.py b/tempest/api/compute/v3/servers/test_server_rescue_negative.py
new file mode 100644
index 0000000..6e09376
--- /dev/null
+++ b/tempest/api/compute/v3/servers/test_server_rescue_negative.py
@@ -0,0 +1,133 @@
+# Copyright 2013 Hewlett-Packard Development Company, L.P.
+# Copyright 2014 NEC Corporation.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.api.compute import base
+from tempest.common.utils import data_utils
+from tempest import exceptions
+from tempest import test
+
+
+class ServerRescueNegativeV3Test(base.BaseV3ComputeTest):
+
+    @classmethod
+    def setUpClass(cls):
+        super(ServerRescueNegativeV3Test, cls).setUpClass()
+        cls.device = 'vdf'
+
+        # Create a volume and wait for it to become ready for attach
+        resp, cls.volume = cls.volumes_client.create_volume(
+            1, display_name=data_utils.rand_name(cls.__name__ + '_volume'))
+        cls.volumes_client.wait_for_volume_status(
+            cls.volume['id'], 'available')
+
+        # Server for negative tests
+        resp, server = cls.create_test_server(wait_until='BUILD')
+        resp, resc_server = cls.create_test_server(wait_until='ACTIVE')
+        cls.server_id = server['id']
+        cls.password = server['admin_password']
+        cls.rescue_id = resc_server['id']
+        cls.rescue_password = resc_server['admin_password']
+
+        cls.servers_client.rescue_server(
+            cls.rescue_id, admin_password=cls.rescue_password)
+        cls.servers_client.wait_for_server_status(cls.rescue_id, 'RESCUE')
+
+    @classmethod
+    def tearDownClass(cls):
+        cls.delete_volume(cls.volume['id'])
+        super(ServerRescueNegativeV3Test, cls).tearDownClass()
+
+    def _detach(self, server_id, volume_id):
+        self.servers_client.detach_volume(server_id, volume_id)
+        self.volumes_client.wait_for_volume_status(volume_id,
+                                                   'available')
+
+    def _unrescue(self, server_id):
+        resp, body = self.servers_client.unrescue_server(server_id)
+        self.assertEqual(202, resp.status)
+        self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
+
+    def _unpause(self, server_id):
+        resp, body = self.servers_client.unpause_server(server_id)
+        self.assertEqual(202, resp.status)
+        self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
+
+    @test.attr(type=['negative', 'gate'])
+    def test_rescue_paused_instance(self):
+        # Rescue a paused server
+        resp, body = self.servers_client.pause_server(
+            self.server_id)
+        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.Conflict,
+                          self.servers_client.rescue_server,
+                          self.server_id)
+
+    @test.attr(type=['negative', 'gate'])
+    def test_rescued_vm_reboot(self):
+        self.assertRaises(exceptions.Conflict, self.servers_client.reboot,
+                          self.rescue_id, 'HARD')
+
+    @test.attr(type=['negative', 'gate'])
+    def test_rescue_non_existent_server(self):
+        # Rescue a non-existing server
+        self.assertRaises(exceptions.NotFound,
+                          self.servers_client.rescue_server,
+                          data_utils.rand_uuid())
+
+    @test.attr(type=['negative', 'gate'])
+    def test_rescued_vm_rebuild(self):
+        self.assertRaises(exceptions.Conflict,
+                          self.servers_client.rebuild,
+                          self.rescue_id,
+                          self.image_ref_alt)
+
+    @test.attr(type=['negative', 'gate'])
+    def test_rescued_vm_attach_volume(self):
+        # Rescue the server
+        self.servers_client.rescue_server(self.server_id,
+                                          admin_password=self.password)
+        self.servers_client.wait_for_server_status(self.server_id, 'RESCUE')
+        self.addCleanup(self._unrescue, self.server_id)
+
+        # Attach the volume to the server
+        self.assertRaises(exceptions.Conflict,
+                          self.servers_client.attach_volume,
+                          self.server_id,
+                          self.volume['id'],
+                          device='/dev/%s' % self.device)
+
+    @test.attr(type=['negative', 'gate'])
+    def test_rescued_vm_detach_volume(self):
+        # Attach the volume to the server
+        self.servers_client.attach_volume(self.server_id,
+                                          self.volume['id'],
+                                          device='/dev/%s' % self.device)
+        self.volumes_client.wait_for_volume_status(self.volume['id'], 'in-use')
+
+        # Rescue the server
+        self.servers_client.rescue_server(self.server_id,
+                                          admin_password=self.password)
+        self.servers_client.wait_for_server_status(self.server_id, 'RESCUE')
+        # addCleanup is a LIFO queue
+        self.addCleanup(self._detach, self.server_id, self.volume['id'])
+        self.addCleanup(self._unrescue, self.server_id)
+
+        # Detach the volume from the server expecting failure
+        self.assertRaises(exceptions.Conflict,
+                          self.servers_client.detach_volume,
+                          self.server_id,
+                          self.volume['id'])
diff --git a/tempest/api/compute/v3/servers/test_servers.py b/tempest/api/compute/v3/servers/test_servers.py
index 5480e31..426ee8d 100644
--- a/tempest/api/compute/v3/servers/test_servers.py
+++ b/tempest/api/compute/v3/servers/test_servers.py
@@ -19,7 +19,6 @@
 
 
 class ServersV3Test(base.BaseV3ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/v3/servers/test_servers_negative.py b/tempest/api/compute/v3/servers/test_servers_negative.py
index 12e0ad8..cb5e93d 100644
--- a/tempest/api/compute/v3/servers/test_servers_negative.py
+++ b/tempest/api/compute/v3/servers/test_servers_negative.py
@@ -27,7 +27,6 @@
 
 
 class ServersNegativeV3Test(base.BaseV3ComputeTest):
-    _interface = 'json'
 
     def setUp(self):
         super(ServersNegativeV3Test, self).setUp()
diff --git a/tempest/api/compute/v3/test_extensions.py b/tempest/api/compute/v3/test_extensions.py
index 09f5ab4..3c612df 100644
--- a/tempest/api/compute/v3/test_extensions.py
+++ b/tempest/api/compute/v3/test_extensions.py
@@ -25,7 +25,6 @@
 
 
 class ExtensionsV3Test(base.BaseV3ComputeTest):
-    _interface = 'json'
 
     @test.attr(type='gate')
     def test_list_extensions(self):
diff --git a/tempest/api/compute/v3/test_live_block_migration.py b/tempest/api/compute/v3/test_live_block_migration.py
index 43b4e2b..33d2bd9 100644
--- a/tempest/api/compute/v3/test_live_block_migration.py
+++ b/tempest/api/compute/v3/test_live_block_migration.py
@@ -24,7 +24,6 @@
 
 class LiveBlockMigrationV3Test(base.BaseV3ComputeAdminTest):
     _host_key = 'os-extended-server-attributes:host'
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/v3/test_live_block_migration_negative.py b/tempest/api/compute/v3/test_live_block_migration_negative.py
index 4d820d8..b4ec505 100644
--- a/tempest/api/compute/v3/test_live_block_migration_negative.py
+++ b/tempest/api/compute/v3/test_live_block_migration_negative.py
@@ -25,7 +25,6 @@
 
 class LiveBlockMigrationV3NegativeTest(base.BaseV3ComputeAdminTest):
     _host_key = 'os-extended-server-attributes:host'
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
@@ -39,7 +38,7 @@
     def _migrate_server_to(self, server_id, dest_host):
         _resp, body = self.admin_servers_client.live_migrate_server(
             server_id, dest_host,
-            self.config.compute_feature_enabled.
+            CONF.compute_feature_enabled.
             block_migration_for_live_migration)
         return body
 
diff --git a/tempest/api/compute/v3/test_quotas.py b/tempest/api/compute/v3/test_quotas.py
index 33b90ff..b53d9be 100644
--- a/tempest/api/compute/v3/test_quotas.py
+++ b/tempest/api/compute/v3/test_quotas.py
@@ -18,7 +18,6 @@
 
 
 class QuotasV3Test(base.BaseV3ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/v3/test_version.py b/tempest/api/compute/v3/test_version.py
index 9161d4d..1a74e35 100644
--- a/tempest/api/compute/v3/test_version.py
+++ b/tempest/api/compute/v3/test_version.py
@@ -19,7 +19,6 @@
 
 
 class VersionV3Test(base.BaseV3ComputeTest):
-    _interface = 'json'
 
     @test.attr(type='gate')
     def test_version(self):
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index 7a60196..3c5feed 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -24,7 +24,6 @@
 
 
 class AttachVolumeTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
     run_ssh = CONF.compute.run_ssh
 
     def __init__(self, *args, **kwargs):
diff --git a/tempest/api/compute/volumes/test_volumes_get.py b/tempest/api/compute/volumes/test_volumes_get.py
index 73e3b3a..c3d6ba6 100644
--- a/tempest/api/compute/volumes/test_volumes_get.py
+++ b/tempest/api/compute/volumes/test_volumes_get.py
@@ -24,8 +24,6 @@
 
 class VolumesGetTestJSON(base.BaseV2ComputeTest):
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(VolumesGetTestJSON, cls).setUpClass()
diff --git a/tempest/api/compute/volumes/test_volumes_list.py b/tempest/api/compute/volumes/test_volumes_list.py
index 48b1b7e..9867c64 100644
--- a/tempest/api/compute/volumes/test_volumes_list.py
+++ b/tempest/api/compute/volumes/test_volumes_list.py
@@ -31,8 +31,6 @@
     VOLUME_BACKING_FILE_SIZE is atleast 4G in your localrc
     """
 
-    _interface = 'json'
-
     @classmethod
     def setUpClass(cls):
         super(VolumesTestJSON, cls).setUpClass()
diff --git a/tempest/api/compute/volumes/test_volumes_negative.py b/tempest/api/compute/volumes/test_volumes_negative.py
index 85b30e2..cecaf62 100644
--- a/tempest/api/compute/volumes/test_volumes_negative.py
+++ b/tempest/api/compute/volumes/test_volumes_negative.py
@@ -25,7 +25,6 @@
 
 
 class VolumesNegativeTest(base.BaseV2ComputeTest):
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/database/__init__.py b/tempest/api/database/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/api/database/__init__.py
diff --git a/tempest/api/database/base.py b/tempest/api/database/base.py
new file mode 100644
index 0000000..8add9ba
--- /dev/null
+++ b/tempest/api/database/base.py
@@ -0,0 +1,42 @@
+# Copyright 2014 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 import config
+from tempest.openstack.common import log as logging
+import tempest.test
+
+CONF = config.CONF
+LOG = logging.getLogger(__name__)
+
+
+class BaseDatabaseTest(tempest.test.BaseTestCase):
+    """Base test case class for all Database API tests."""
+
+    _interface = 'json'
+    force_tenant_isolation = False
+
+    @classmethod
+    def setUpClass(cls):
+        super(BaseDatabaseTest, cls).setUpClass()
+        if not CONF.service_available.trove:
+            skip_msg = ("%s skipped as trove is not available" % cls.__name__)
+            raise cls.skipException(skip_msg)
+
+        cls.catalog_type = CONF.database.catalog_type
+        cls.db_flavor_ref = CONF.database.db_flavor_ref
+
+        os = cls.get_client_manager()
+        cls.os = os
+        cls.database_flavors_client = cls.os.database_flavors_client
diff --git a/tempest/api/database/flavors/__init__.py b/tempest/api/database/flavors/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/api/database/flavors/__init__.py
diff --git a/tempest/api/database/flavors/test_flavors.py b/tempest/api/database/flavors/test_flavors.py
new file mode 100644
index 0000000..a591e8e
--- /dev/null
+++ b/tempest/api/database/flavors/test_flavors.py
@@ -0,0 +1,41 @@
+# Copyright 2014 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.database import base
+from tempest import test
+
+
+class DatabaseFlavorsTest(base.BaseDatabaseTest):
+
+    @classmethod
+    def setUpClass(cls):
+        super(DatabaseFlavorsTest, cls).setUpClass()
+        cls.client = cls.database_flavors_client
+
+    @test.attr(type='smoke')
+    def test_get_db_flavor(self):
+        # The expected flavor details should be returned
+        resp, flavor = self.client.get_db_flavor_details(self.db_flavor_ref)
+        self.assertEqual(self.db_flavor_ref, str(flavor['id']))
+        self.assertIn('ram', flavor)
+        self.assertIn('links', flavor)
+        self.assertIn('name', flavor)
+
+    @test.attr(type='smoke')
+    def test_list_db_flavors(self):
+        resp, flavor = self.client.get_db_flavor_details(self.db_flavor_ref)
+        # List of all flavors should contain the expected flavor
+        resp, flavors = self.client.list_db_flavors()
+        self.assertIn(flavor, flavors)
diff --git a/tempest/api/database/flavors/test_flavors_negative.py b/tempest/api/database/flavors/test_flavors_negative.py
new file mode 100644
index 0000000..202dc48
--- /dev/null
+++ b/tempest/api/database/flavors/test_flavors_negative.py
@@ -0,0 +1,32 @@
+# Copyright 2014 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.database import base
+from tempest import exceptions
+from tempest import test
+
+
+class DatabaseFlavorsNegativeTest(base.BaseDatabaseTest):
+
+    @classmethod
+    def setUpClass(cls):
+        super(DatabaseFlavorsNegativeTest, cls).setUpClass()
+        cls.client = cls.database_flavors_client
+
+    @test.attr(type=['negative', 'gate'])
+    def test_get_non_existent_db_flavor(self):
+        # flavor details are not returned for non-existent flavors
+        self.assertRaises(exceptions.NotFound,
+                          self.client.get_db_flavor_details, -1)
diff --git a/tempest/api/identity/admin/test_roles.py b/tempest/api/identity/admin/test_roles.py
index aa64969..5e78cce 100644
--- a/tempest/api/identity/admin/test_roles.py
+++ b/tempest/api/identity/admin/test_roles.py
@@ -13,6 +13,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from six import moves
+
 from tempest.api.identity import base
 from tempest.common.utils import data_utils
 from tempest.test import attr
@@ -24,7 +26,7 @@
     @classmethod
     def setUpClass(cls):
         super(RolesTestJSON, cls).setUpClass()
-        for _ in xrange(5):
+        for _ in moves.xrange(5):
             role_name = data_utils.rand_name(name='role-')
             resp, role = cls.client.create_role(role_name)
             cls.data.roles.append(role)
diff --git a/tempest/api/identity/admin/test_services.py b/tempest/api/identity/admin/test_services.py
index cbf6b58..459c44c 100644
--- a/tempest/api/identity/admin/test_services.py
+++ b/tempest/api/identity/admin/test_services.py
@@ -13,6 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from six import moves
 
 from tempest.api.identity import base
 from tempest.common.utils import data_utils
@@ -69,7 +70,7 @@
     def test_list_services(self):
         # Create, List, Verify and Delete Services
         services = []
-        for _ in xrange(3):
+        for _ in moves.xrange(3):
             name = data_utils.rand_name('service-')
             type = data_utils.rand_name('type--')
             description = data_utils.rand_name('description-')
diff --git a/tempest/api/identity/admin/test_tenants.py b/tempest/api/identity/admin/test_tenants.py
index c7cacb4..257a6d7 100644
--- a/tempest/api/identity/admin/test_tenants.py
+++ b/tempest/api/identity/admin/test_tenants.py
@@ -13,6 +13,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from six import moves
+
 from tempest.api.identity import base
 from tempest.common.utils import data_utils
 from tempest.test import attr
@@ -25,7 +27,7 @@
     def test_tenant_list_delete(self):
         # Create several tenants and delete them
         tenants = []
-        for _ in xrange(3):
+        for _ in moves.xrange(3):
             tenant_name = data_utils.rand_name(name='tenant-new')
             resp, tenant = self.client.create_tenant(tenant_name)
             self.assertEqual(200, resp.status)
diff --git a/tempest/api/identity/admin/test_tokens.py b/tempest/api/identity/admin/test_tokens.py
index 239433b..533f374 100644
--- a/tempest/api/identity/admin/test_tokens.py
+++ b/tempest/api/identity/admin/test_tokens.py
@@ -22,7 +22,7 @@
     _interface = 'json'
 
     @attr(type='gate')
-    def test_create_delete_token(self):
+    def test_create_get_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-')
@@ -43,8 +43,16 @@
         self.assertEqual(rsp['status'], '200')
         self.assertEqual(body['token']['tenant']['name'],
                          tenant['name'])
-        # then delete the token
+        # Perform GET Token
         token_id = body['token']['id']
+        resp, token_details = self.client.get_token(token_id)
+        self.assertEqual(resp['status'], '200')
+        self.assertEqual(token_id, token_details['token']['id'])
+        self.assertEqual(user['id'], token_details['user']['id'])
+        self.assertEqual(user_name, token_details['user']['name'])
+        self.assertEqual(tenant['name'],
+                         token_details['token']['tenant']['name'])
+        # then delete the token
         resp, body = self.client.delete_token(token_id)
         self.assertEqual(resp['status'], '204')
 
diff --git a/tempest/api/identity/admin/v3/test_endpoints.py b/tempest/api/identity/admin/v3/test_endpoints.py
index 78ecf93..05b704f 100644
--- a/tempest/api/identity/admin/v3/test_endpoints.py
+++ b/tempest/api/identity/admin/v3/test_endpoints.py
@@ -125,7 +125,7 @@
         self.assertEqual(interface2, endpoint['interface'])
         self.assertEqual(url2, endpoint['url'])
         self.assertEqual(region2, endpoint['region'])
-        self.assertEqual('False', str(endpoint['enabled']))
+        self.assertEqual('false', str(endpoint['enabled']).lower())
         self.addCleanup(self.client.delete_endpoint, endpoint_for_update['id'])
 
 
diff --git a/tempest/api/identity/admin/v3/test_projects.py b/tempest/api/identity/admin/v3/test_projects.py
index be03a03..31a0ddd 100644
--- a/tempest/api/identity/admin/v3/test_projects.py
+++ b/tempest/api/identity/admin/v3/test_projects.py
@@ -13,6 +13,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from six import moves
+
 from tempest.api.identity import base
 from tempest.common.utils import data_utils
 from tempest import exceptions
@@ -31,7 +33,7 @@
     @test.attr(type='gate')
     def test_project_list_delete(self):
         # Create several projects and delete them
-        for _ in xrange(3):
+        for _ in moves.xrange(3):
             resp, project = self.client.create_project(
                 data_utils.rand_name('project-new'))
             self.addCleanup(self._delete_project, project['id'])
diff --git a/tempest/api/identity/admin/v3/test_users.py b/tempest/api/identity/admin/v3/test_users.py
index a78d542..e1d1543 100644
--- a/tempest/api/identity/admin/v3/test_users.py
+++ b/tempest/api/identity/admin/v3/test_users.py
@@ -120,6 +120,13 @@
                          ', '.join(m_project for m_project
                                    in missing_projects))
 
+    @attr(type='gate')
+    def test_get_user(self):
+        # Get a user detail
+        self.data.setup_test_v3_user()
+        resp, user = self.client.get_user(self.data.v3_user['id'])
+        self.assertEqual(self.data.v3_user['id'], user['id'])
+
 
 class UsersV3TestXML(UsersV3TestJSON):
     _interface = 'xml'
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index 10f5217..a5bf248 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -153,10 +153,11 @@
             self.test_user = data_utils.rand_name('test_user_')
             self.test_password = data_utils.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)
+            resp, self.v3_user = self.client.create_user(
+                self.test_user,
+                password=self.test_password,
+                project_id=self.project['id'],
+                email=self.test_email)
             self.v3_users.append(self.v3_user)
 
         def setup_test_project(self):
diff --git a/tempest/api/image/v1/test_image_members.py b/tempest/api/image/v1/test_image_members.py
index e6a078e..4cbb62f 100644
--- a/tempest/api/image/v1/test_image_members.py
+++ b/tempest/api/image/v1/test_image_members.py
@@ -14,12 +14,12 @@
 
 
 from tempest.api.image import base
-from tempest.test import attr
+from tempest import test
 
 
 class ImageMembersTest(base.BaseV1ImageMembersTest):
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_add_image_member(self):
         image = self._create_image()
         resp = self.client.add_member(self.alt_tenant_id, image)
@@ -33,7 +33,7 @@
         resp, body = self.alt_img_cli.get_image(image)
         self.assertEqual(200, resp.status)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_shared_images(self):
         image = self._create_image()
         resp = self.client.add_member(self.alt_tenant_id, image)
@@ -48,7 +48,7 @@
         self.assertIn(share_image, images)
         self.assertIn(image, images)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_remove_member(self):
         image_id = self._create_image()
         resp = self.client.add_member(self.alt_tenant_id, image_id)
diff --git a/tempest/api/image/v1/test_image_members_negative.py b/tempest/api/image/v1/test_image_members_negative.py
index d68ef03..aac63b4 100644
--- a/tempest/api/image/v1/test_image_members_negative.py
+++ b/tempest/api/image/v1/test_image_members_negative.py
@@ -16,26 +16,26 @@
 from tempest.api.image import base
 from tempest.common.utils import data_utils
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class ImageMembersNegativeTest(base.BaseV1ImageMembersTest):
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_add_member_with_non_existing_image(self):
         # Add member with non existing image.
         non_exist_image = data_utils.rand_uuid()
         self.assertRaises(exceptions.NotFound, self.client.add_member,
                           self.alt_tenant_id, non_exist_image)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_delete_member_with_non_existing_image(self):
         # Delete member with non existing image.
         non_exist_image = data_utils.rand_uuid()
         self.assertRaises(exceptions.NotFound, self.client.delete_member,
                           self.alt_tenant_id, non_exist_image)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_delete_member_with_non_existing_tenant(self):
         # Delete member with non existing tenant.
         image_id = self._create_image()
@@ -43,7 +43,7 @@
         self.assertRaises(exceptions.NotFound, self.client.delete_member,
                           non_exist_tenant, image_id)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_get_image_without_membership(self):
         # Image is hidden from another tenants.
         image_id = self._create_image()
diff --git a/tempest/api/image/v1/test_images_negative.py b/tempest/api/image/v1/test_images_negative.py
index 5695884..66556e0 100644
--- a/tempest/api/image/v1/test_images_negative.py
+++ b/tempest/api/image/v1/test_images_negative.py
@@ -15,30 +15,30 @@
 
 from tempest.api.image import base
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class CreateDeleteImagesNegativeTest(base.BaseV1ImageTest):
     """Here are negative tests for the deletion and creation of images."""
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_register_with_invalid_container_format(self):
         # Negative tests for invalid data supplied to POST /images
         self.assertRaises(exceptions.BadRequest, self.client.create_image,
                           'test', 'wrong', 'vhd')
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_register_with_invalid_disk_format(self):
         self.assertRaises(exceptions.BadRequest, self.client.create_image,
                           'test', 'bare', 'wrong')
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_delete_image_with_invalid_image_id(self):
         # An image should not be deleted with invalid image id
         self.assertRaises(exceptions.NotFound, self.client.delete_image,
                           '!@$%^&*()')
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_delete_non_existent_image(self):
         # Return an error while trying to delete a non-existent image
 
@@ -46,24 +46,24 @@
         self.assertRaises(exceptions.NotFound, self.client.delete_image,
                           non_existent_image_id)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_delete_image_blank_id(self):
         # Return an error while trying to delete an image with blank Id
         self.assertRaises(exceptions.NotFound, self.client.delete_image, '')
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_delete_image_non_hex_string_id(self):
         # Return an error while trying to delete an image with non hex id
         image_id = '11a22b9-120q-5555-cc11-00ab112223gj'
         self.assertRaises(exceptions.NotFound, self.client.delete_image,
                           image_id)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_delete_image_negative_image_id(self):
         # Return an error while trying to delete an image with negative id
         self.assertRaises(exceptions.NotFound, self.client.delete_image, -1)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_delete_image_id_is_over_35_character_limit(self):
         # Return an error while trying to delete image with id over limit
         self.assertRaises(exceptions.NotFound, self.client.delete_image,
diff --git a/tempest/api/image/v2/test_images.py b/tempest/api/image/v2/test_images.py
index 2a5401f..ce11911 100644
--- a/tempest/api/image/v2/test_images.py
+++ b/tempest/api/image/v2/test_images.py
@@ -19,7 +19,7 @@
 
 from tempest.api.image import base
 from tempest.common.utils import data_utils
-from tempest.test import attr
+from tempest import test
 
 
 class BasicOperationsImagesTest(base.BaseV2ImageTest):
@@ -27,7 +27,7 @@
     Here we test the basic operations of images
     """
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_register_upload_get_image_file(self):
 
         """
@@ -68,9 +68,9 @@
         self.assertEqual(200, resp.status)
         self.assertEqual(file_content, body)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_delete_image(self):
-        # Deletes a image by image_id
+        # Deletes an image by image_id
 
         # Create image
         image_name = data_utils.rand_name('image')
@@ -90,6 +90,43 @@
         self.assertEqual(resp.status, 200)
         self.assertNotIn(image_id, images)
 
+    @test.attr(type='gate')
+    def test_update_image(self):
+        # Updates an image by image_id
+
+        # Create image
+        image_name = data_utils.rand_name('image')
+        resp, body = self.client.create_image(name=image_name,
+                                              container_format='bare',
+                                              disk_format='iso',
+                                              visibility='public')
+        self.assertEqual(201, resp.status)
+        self.assertEqual('queued', body['status'])
+        image_id = body['id']
+
+        # Now try uploading an image file
+        file_content = '*' * 1024
+        image_file = StringIO.StringIO(file_content)
+        resp, body = self.client.store_image(image_id, image_file)
+        self.assertEqual(204, resp.status)
+
+        # Update Image
+        new_image_name = data_utils.rand_name('new-image')
+        new_visibility = 'private'
+        resp, body = self.client.update_image(image_id, [
+            dict(replace='/name', value=new_image_name),
+            dict(replace='/visibility', value=new_visibility)])
+
+        self.assertEqual(200, resp.status)
+
+        # Verifying updating
+
+        resp, body = self.client.get_image(image_id)
+        self.assertEqual(200, resp.status)
+        self.assertEqual(image_id, body['id'])
+        self.assertEqual(new_image_name, body['name'])
+        self.assertEqual(new_visibility, body['visibility'])
+
 
 class ListImagesTest(base.BaseV2ImageTest):
     """
@@ -139,7 +176,7 @@
                 msg = "Failed to list images by %s" % key
                 self.assertEqual(params[key], image[key], msg)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_index_no_params(self):
         # Simple test to see all fixture images returned
         resp, images_list = self.client.image_list()
@@ -149,25 +186,25 @@
         for image in self.created_images:
             self.assertIn(image, image_list)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_images_param_container_format(self):
         # Test to get all images with container_format='bare'
         params = {"container_format": "bare"}
         self._list_by_param_value_and_assert(params)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_images_param_disk_format(self):
         # Test to get all images with disk_format = raw
         params = {"disk_format": "raw"}
         self._list_by_param_value_and_assert(params)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_images_param_visibility(self):
         # Test to get all images with visibility = public
         params = {"visibility": "public"}
         self._list_by_param_value_and_assert(params)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_images_param_size(self):
         # Test to get all images by size
         image_id = self.created_images[1]
@@ -178,7 +215,7 @@
         params = {"size": image['size']}
         self._list_by_param_value_and_assert(params)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_images_param_min_max_size(self):
         # Test to get all images with size between 2000 to 3000
         image_id = self.created_images[1]
@@ -197,13 +234,13 @@
                             image_size <= params['size_max'],
                             "Failed to get images by size_min and size_max")
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_images_param_status(self):
         # Test to get all active images
         params = {"status": "active"}
         self._list_by_param_value_and_assert(params)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_images_param_limit(self):
         # Test to get images by limit
         params = {"limit": 2}
@@ -212,3 +249,19 @@
 
         self.assertEqual(len(images_list), params['limit'],
                          "Failed to get images by limit")
+
+    @test.attr(type='gate')
+    def test_get_image_schema(self):
+        # Test to get image schema
+        schema = "image"
+        resp, body = self.client.get_schema(schema)
+        self.assertEqual(200, resp.status)
+        self.assertEqual("image", body['name'])
+
+    @test.attr(type='gate')
+    def test_get_images_schema(self):
+        # Test to get images schema
+        schema = "images"
+        resp, body = self.client.get_schema(schema)
+        self.assertEqual(200, resp.status)
+        self.assertEqual("images", body['name'])
diff --git a/tempest/api/image/v2/test_images_member.py b/tempest/api/image/v2/test_images_member.py
index 41fc49d..f80c818 100644
--- a/tempest/api/image/v2/test_images_member.py
+++ b/tempest/api/image/v2/test_images_member.py
@@ -11,17 +11,18 @@
 #    under the License.
 
 from tempest.api.image import base
-from tempest.test import attr
+from tempest import test
 
 
 class ImagesMemberTest(base.BaseV2MemberImageTest):
     _interface = 'json'
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_image_share_accept(self):
         image_id = self._create_image()
         resp, member = self.os_img_client.add_member(image_id,
                                                      self.alt_tenant_id)
+        self.assertEqual(200, resp.status)
         self.assertEqual(member['member_id'], self.alt_tenant_id)
         self.assertEqual(member['image_id'], image_id)
         self.assertEqual(member['status'], 'pending')
@@ -30,7 +31,8 @@
                                                  self.alt_tenant_id,
                                                  'accepted')
         self.assertIn(image_id, self._list_image_ids_as_alt())
-        _, body = self.os_img_client.get_image_membership(image_id)
+        resp, body = self.os_img_client.get_image_membership(image_id)
+        self.assertEqual(200, resp.status)
         members = body['members']
         member = members[0]
         self.assertEqual(len(members), 1, str(members))
@@ -38,16 +40,61 @@
         self.assertEqual(member['image_id'], image_id)
         self.assertEqual(member['status'], 'accepted')
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_image_share_reject(self):
         image_id = self._create_image()
         resp, member = self.os_img_client.add_member(image_id,
                                                      self.alt_tenant_id)
+        self.assertEqual(200, resp.status)
         self.assertEqual(member['member_id'], self.alt_tenant_id)
         self.assertEqual(member['image_id'], image_id)
         self.assertEqual(member['status'], 'pending')
         self.assertNotIn(image_id, self._list_image_ids_as_alt())
+        resp, _ = self.alt_img_client.update_member_status(image_id,
+                                                           self.alt_tenant_id,
+                                                           'rejected')
+        self.assertEqual(200, resp.status)
+        self.assertNotIn(image_id, self._list_image_ids_as_alt())
+
+    @test.attr(type='gate')
+    def test_get_image_member(self):
+        image_id = self._create_image()
+        self.os_img_client.add_member(image_id,
+                                      self.alt_tenant_id)
         self.alt_img_client.update_member_status(image_id,
                                                  self.alt_tenant_id,
-                                                 'rejected')
+                                                 'accepted')
+
+        self.assertIn(image_id, self._list_image_ids_as_alt())
+        resp, member = self.os_img_client.get_member(image_id,
+                                                     self.alt_tenant_id)
+        self.assertEqual(200, resp.status)
+        self.assertEqual(self.alt_tenant_id, member['member_id'])
+        self.assertEqual(image_id, member['image_id'])
+        self.assertEqual('accepted', member['status'])
+
+    @test.attr(type='gate')
+    def test_remove_image_member(self):
+        image_id = self._create_image()
+        self.os_img_client.add_member(image_id,
+                                      self.alt_tenant_id)
+        self.alt_img_client.update_member_status(image_id,
+                                                 self.alt_tenant_id,
+                                                 'accepted')
+
+        self.assertIn(image_id, self._list_image_ids_as_alt())
+        resp = self.os_img_client.remove_member(image_id, self.alt_tenant_id)
+        self.assertEqual(204, resp.status)
         self.assertNotIn(image_id, self._list_image_ids_as_alt())
+
+    @test.attr(type='gate')
+    def test_get_image_member_schema(self):
+        resp, body = self.os_img_client.get_schema("member")
+        self.assertEqual(200, resp.status)
+        self.assertEqual("member", body['name'])
+
+    @test.attr(type='gate')
+    def test_get_image_members_schema(self):
+        resp, body = self.os_img_client.get_schema("members")
+        self.assertEqual(200, resp.status)
+        self.assertEqual("members", body['name'])
diff --git a/tempest/api/image/v2/test_images_member_negative.py b/tempest/api/image/v2/test_images_member_negative.py
index 4c7cc5a..98ef649 100644
--- a/tempest/api/image/v2/test_images_member_negative.py
+++ b/tempest/api/image/v2/test_images_member_negative.py
@@ -12,13 +12,13 @@
 
 from tempest.api.image import base
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class ImagesMemberNegativeTest(base.BaseV2MemberImageTest):
     _interface = 'json'
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_image_share_invalid_status(self):
         image_id = self._create_image()
         resp, member = self.os_img_client.add_member(image_id,
@@ -28,7 +28,7 @@
                           self.alt_img_client.update_member_status,
                           image_id, self.alt_tenant_id, 'notavalidstatus')
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_image_share_owner_cannot_accept(self):
         image_id = self._create_image()
         resp, member = self.os_img_client.add_member(image_id,
diff --git a/tempest/api/image/v2/test_images_negative.py b/tempest/api/image/v2/test_images_negative.py
index b8ba868..27ba39c 100644
--- a/tempest/api/image/v2/test_images_negative.py
+++ b/tempest/api/image/v2/test_images_negative.py
@@ -18,7 +18,7 @@
 
 from tempest.api.image import base
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class ImagesNegativeTest(base.BaseV2ImageTest):
@@ -35,20 +35,20 @@
         ** delete the deleted image
      """
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_get_non_existent_image(self):
         # get the non-existent image
         non_existent_id = str(uuid.uuid4())
         self.assertRaises(exceptions.NotFound, self.client.get_image,
                           non_existent_id)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_get_image_null_id(self):
         # get image with image_id = NULL
         image_id = ""
         self.assertRaises(exceptions.NotFound, self.client.get_image, image_id)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_get_delete_deleted_image(self):
         # get and delete the deleted image
         # create and delete image
@@ -67,27 +67,27 @@
         self.assertRaises(exceptions.NotFound, self.client.delete_image,
                           image_id)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_delete_non_existing_image(self):
         # delete non-existent image
         non_existent_image_id = str(uuid.uuid4())
         self.assertRaises(exceptions.NotFound, self.client.delete_image,
                           non_existent_image_id)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_delete_image_null_id(self):
         # delete image with image_id=NULL
         image_id = ""
         self.assertRaises(exceptions.NotFound, self.client.delete_image,
                           image_id)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_register_with_invalid_container_format(self):
         # Negative tests for invalid data supplied to POST /images
         self.assertRaises(exceptions.BadRequest, self.client.create_image,
                           'test', 'wrong', 'vhd')
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_register_with_invalid_disk_format(self):
         self.assertRaises(exceptions.BadRequest, self.client.create_image,
                           'test', 'bare', 'wrong')
diff --git a/tempest/api/image/v2/test_images_tags.py b/tempest/api/image/v2/test_images_tags.py
index f0e343d..504c0e8 100644
--- a/tempest/api/image/v2/test_images_tags.py
+++ b/tempest/api/image/v2/test_images_tags.py
@@ -14,12 +14,12 @@
 
 from tempest.api.image import base
 from tempest.common.utils import data_utils
-from tempest.test import attr
+from tempest import test
 
 
 class ImagesTagsTest(base.BaseV2ImageTest):
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_update_delete_tags_for_image(self):
         resp, body = self.create_image(container_format='bare',
                                        disk_format='raw',
diff --git a/tempest/api/image/v2/test_images_tags_negative.py b/tempest/api/image/v2/test_images_tags_negative.py
index 0628d29..3233db7 100644
--- a/tempest/api/image/v2/test_images_tags_negative.py
+++ b/tempest/api/image/v2/test_images_tags_negative.py
@@ -17,12 +17,12 @@
 from tempest.api.image import base
 from tempest.common.utils import data_utils
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class ImagesTagsNegativeTest(base.BaseV2ImageTest):
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_update_tags_for_non_existing_image(self):
         # Update tag with non existing image.
         tag = data_utils.rand_name('tag-')
@@ -30,7 +30,7 @@
         self.assertRaises(exceptions.NotFound, self.client.add_image_tag,
                           non_exist_image, tag)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_delete_non_existing_tag(self):
         # Delete non existing tag.
         resp, body = self.create_image(container_format='bare',
diff --git a/tempest/api/network/admin/test_l3_agent_scheduler.py b/tempest/api/network/admin/test_l3_agent_scheduler.py
index 7c02787..eb397ba 100644
--- a/tempest/api/network/admin/test_l3_agent_scheduler.py
+++ b/tempest/api/network/admin/test_l3_agent_scheduler.py
@@ -26,6 +26,7 @@
 
         List routers that the given L3 agent is hosting.
         List L3 agents hosting the given router.
+        Add and Remove Router to L3 agent
 
     v2.0 of the Neutron API is assumed. It is also assumed that the following
     options are defined in the [network] section of etc/tempest.conf:
@@ -37,28 +38,49 @@
         if not test.is_extension_enabled('l3_agent_scheduler', 'network'):
             msg = "L3 Agent Scheduler Extension not enabled."
             raise cls.skipException(msg)
+        # Trying to get agent details for L3 Agent
+        resp, body = cls.admin_client.list_agents()
+        agents = body['agents']
+        for agent in agents:
+            if agent['agent_type'] == 'L3 agent':
+                cls.agent = agent
+                break
+        else:
+            msg = "L3 Agent not found"
+            raise cls.skipException(msg)
 
     @test.attr(type='smoke')
     def test_list_routers_on_l3_agent(self):
-        resp, body = self.admin_client.list_agents()
-        agents = body['agents']
-        for a in agents:
-            if a['agent_type'] == 'L3 agent':
-                agent = a
         resp, body = self.admin_client.list_routers_on_l3_agent(
-            agent['id'])
+            self.agent['id'])
         self.assertEqual('200', resp['status'])
 
     @test.attr(type='smoke')
-    def test_list_l3_agents_hosting_router(self):
-        name = data_utils.rand_name('router-')
+    def test_add_list_remove_router_on_l3_agent(self):
+        l3_agent_ids = list()
+        name = data_utils.rand_name('router1-')
         resp, router = self.client.create_router(name)
+        self.addCleanup(self.client.delete_router, router['router']['id'])
+        resp, body = self.admin_client.add_router_to_l3_agent(
+            self.agent['id'], router['router']['id'])
         self.assertEqual('201', resp['status'])
         resp, body = self.admin_client.list_l3_agents_hosting_router(
             router['router']['id'])
         self.assertEqual('200', resp['status'])
-        resp, _ = self.client.delete_router(router['router']['id'])
-        self.assertEqual(204, resp.status)
+        for agent in body['agents']:
+            l3_agent_ids.append(agent['id'])
+            self.assertIn('agent_type', agent)
+            self.assertEqual('L3 agent', agent['agent_type'])
+        self.assertIn(self.agent['id'], l3_agent_ids)
+        del l3_agent_ids[:]
+        resp, body = self.admin_client.remove_router_from_l3_agent(
+            self.agent['id'], router['router']['id'])
+        self.assertEqual('204', resp['status'])
+        resp, body = self.admin_client.list_l3_agents_hosting_router(
+            router['router']['id'])
+        for agent in body['agents']:
+            l3_agent_ids.append(agent['id'])
+        self.assertNotIn(self.agent['id'], l3_agent_ids)
 
 
 class L3AgentSchedulerTestXML(L3AgentSchedulerTestJSON):
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index dd888a6..231c4bf 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -53,15 +53,12 @@
 
     # Default to ipv4.
     _ip_version = 4
-    _tenant_network_cidr = CONF.network.tenant_network_cidr
-    _tenant_network_mask_bits = CONF.network.tenant_network_mask_bits
 
     @classmethod
     def setUpClass(cls):
         # Create no network resources for these test.
         cls.set_network_resources()
         super(BaseNetworkTest, cls).setUpClass()
-        os = clients.Manager(interface=cls._interface)
         if not CONF.service_available.neutron:
             raise cls.skipException("Neutron support is required")
 
@@ -147,11 +144,13 @@
     def create_subnet(cls, network):
         """Wrapper utility that returns a test subnet."""
         # The cidr and mask_bits depend on the ip version.
-        cidr = netaddr.IPNetwork(cls._tenant_network_cidr)
-        mask_bits = cls._tenant_network_mask_bits
+        if cls._ip_version == 4:
+            cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
+            mask_bits = CONF.network.tenant_network_mask_bits
+        elif cls._ip_version == 6:
+            cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
+            mask_bits = CONF.network.tenant_network_v6_mask_bits
         # Find a cidr that is not in use yet and create a subnet with it
-        body = None
-        failure = None
         for subnet_cidr in cidr.subnet(mask_bits):
             try:
                 resp, body = cls.client.create_subnet(
@@ -163,12 +162,9 @@
                 is_overlapping_cidr = 'overlaps with another subnet' in str(e)
                 if not is_overlapping_cidr:
                     raise
-                # save the failure in case all of the CIDRs are overlapping
-                failure = e
-
-        if not body and failure:
-            raise failure
-
+        else:
+            message = 'Available CIDR for subnet creation could not be found'
+            raise exceptions.BuildErrorException(message)
         subnet = body['subnet']
         cls.subnets.append(subnet)
         return subnet
@@ -246,14 +242,20 @@
     @classmethod
     def create_member(cls, protocol_port, pool):
         """Wrapper utility that returns a test member."""
-        resp, body = cls.client.create_member("10.0.9.46",
-                                              protocol_port,
-                                              pool['id'])
+        resp, body = cls.client.create_member(address="10.0.9.46",
+                                              protocol_port=protocol_port,
+                                              pool_id=pool['id'])
         member = body['member']
         cls.members.append(member)
         return member
 
     @classmethod
+    def update_member(cls, admin_state_up):
+        resp, body = cls.client.update_member(admin_state_up=admin_state_up)
+        member = body['member']
+        return member
+
+    @classmethod
     def create_health_monitor(cls, delay, max_retries, Type, timeout):
         """Wrapper utility that returns a test health monitor."""
         resp, body = cls.client.create_health_monitor(delay=delay,
diff --git a/tempest/api/network/base_routers.py b/tempest/api/network/base_routers.py
index 304b2ca..b278002 100644
--- a/tempest/api/network/base_routers.py
+++ b/tempest/api/network/base_routers.py
@@ -38,11 +38,13 @@
         self.assertNotIn(router_id, routers_list)
 
     def _remove_router_interface_with_subnet_id(self, router_id, subnet_id):
-        resp, _ = self.client.remove_router_interface_with_subnet_id(
+        resp, body = self.client.remove_router_interface_with_subnet_id(
             router_id, subnet_id)
         self.assertEqual('200', resp['status'])
+        self.assertEqual(subnet_id, body['subnet_id'])
 
     def _remove_router_interface_with_port_id(self, router_id, port_id):
-        resp, _ = self.client.remove_router_interface_with_port_id(
+        resp, body = self.client.remove_router_interface_with_port_id(
             router_id, port_id)
         self.assertEqual('200', resp['status'])
+        self.assertEqual(port_id, body['port_id'])
diff --git a/tempest/api/network/common.py b/tempest/api/network/common.py
index d68ff1a..97e120f 100644
--- a/tempest/api/network/common.py
+++ b/tempest/api/network/common.py
@@ -61,6 +61,11 @@
         super(DeletableSubnet, self).__init__(*args, **kwargs)
         self._router_ids = set()
 
+    def update(self, *args, **kwargs):
+        body = dict(subnet=dict(*args, **kwargs))
+        result = self.client.update_subnet(subnet=self.id, body=body)
+        super(DeletableSubnet, self).update(**result['subnet'])
+
     def add_to_router(self, router_id):
         self._router_ids.add(router_id)
         body = dict(subnet_id=self.id)
diff --git a/tempest/api/network/test_load_balancer.py b/tempest/api/network/test_load_balancer.py
index 03e095d..695dbf8 100644
--- a/tempest/api/network/test_load_balancer.py
+++ b/tempest/api/network/test_load_balancer.py
@@ -61,19 +61,50 @@
                                                        Type="TCP",
                                                        timeout=1)
 
+    def _check_list_with_filter(self, obj_name, attr_exceptions, **kwargs):
+        create_obj = getattr(self.client, 'create_' + obj_name)
+        delete_obj = getattr(self.client, 'delete_' + obj_name)
+        list_objs = getattr(self.client, 'list_' + obj_name + 's')
+
+        resp, body = create_obj(**kwargs)
+        self.assertEqual('201', resp['status'])
+        obj = body[obj_name]
+        self.addCleanup(delete_obj, obj['id'])
+        for key, value in obj.iteritems():
+            # It is not relevant to filter by all arguments. That is why
+            # there is a list of attr to except
+            if key not in attr_exceptions:
+                resp, body = list_objs(**{key: value})
+                self.assertEqual('200', resp['status'])
+                objs = [v[key] for v in body[obj_name + 's']]
+                self.assertIn(value, objs)
+
     @test.attr(type='smoke')
     def test_list_vips(self):
         # Verify the vIP exists in the list of all vIPs
         resp, body = self.client.list_vips()
         self.assertEqual('200', resp['status'])
         vips = body['vips']
-        found = None
-        for n in vips:
-            if (n['id'] == self.vip['id']):
-                found = n['id']
-        msg = "vIPs list doesn't contain created vip"
-        self.assertIsNotNone(found, msg)
+        self.assertIn(self.vip['id'], [v['id'] for v in vips])
 
+    @test.attr(type='smoke')
+    def test_list_vips_with_filter(self):
+        name = data_utils.rand_name('vip-')
+        resp, body = self.client.create_pool(
+            name=data_utils.rand_name("pool-"), lb_method="ROUND_ROBIN",
+            protocol="HTTPS", subnet_id=self.subnet['id'])
+        self.assertEqual('201', resp['status'])
+        pool = body['pool']
+        self.addCleanup(self.client.delete_pool, pool['id'])
+        attr_exceptions = ['status', 'session_persistence',
+                           'status_description']
+        self._check_list_with_filter(
+            'vip', attr_exceptions, name=name, protocol="HTTPS",
+            protocol_port=81, subnet_id=self.subnet['id'], pool_id=pool['id'],
+            description=data_utils.rand_name('description-'),
+            admin_state_up=False)
+
+    @test.attr(type='smoke')
     def test_create_update_delete_pool_vip(self):
         # Creates a vip
         name = data_utils.rand_name('vip-')
@@ -100,6 +131,7 @@
         # Verification of vip delete
         resp, body = self.client.delete_vip(vip['id'])
         self.assertEqual('204', resp['status'])
+        self.client.wait_for_resource_deletion('vip', vip['id'])
         # Verification of pool update
         new_name = "New_pool"
         resp, body = self.client.update_pool(pool['id'],
@@ -117,17 +149,30 @@
         resp, body = self.client.show_vip(self.vip['id'])
         self.assertEqual('200', resp['status'])
         vip = body['vip']
-        self.assertEqual(self.vip['id'], vip['id'])
-        self.assertEqual(self.vip['name'], vip['name'])
+        for key, value in vip.iteritems():
+            # 'status' should not be confirmed in api tests
+            if key != 'status':
+                self.assertEqual(self.vip[key], value)
 
     @test.attr(type='smoke')
     def test_show_pool(self):
-        # Verifies the details of a pool
-        resp, body = self.client.show_pool(self.pool['id'])
-        self.assertEqual('200', resp['status'])
+        # Here we need to new pool without any dependence with vips
+        resp, body = self.client.create_pool(
+            name=data_utils.rand_name("pool-"),
+            lb_method='ROUND_ROBIN',
+            protocol='HTTP',
+            subnet_id=self.subnet['id'])
+        self.assertEqual('201', resp['status'])
         pool = body['pool']
-        self.assertEqual(self.pool['id'], pool['id'])
-        self.assertEqual(self.pool['name'], pool['name'])
+        self.addCleanup(self.client.delete_pool, pool['id'])
+        # Verifies the details of a pool
+        resp, body = self.client.show_pool(pool['id'])
+        self.assertEqual('200', resp['status'])
+        shown_pool = body['pool']
+        for key, value in pool.iteritems():
+            # 'status' should not be confirmed in api tests
+            if key != 'status':
+                self.assertEqual(value, shown_pool[key])
 
     @test.attr(type='smoke')
     def test_list_pools(self):
@@ -138,6 +183,17 @@
         self.assertIn(self.pool['id'], [p['id'] for p in pools])
 
     @test.attr(type='smoke')
+    def test_list_pools_with_filters(self):
+        attr_exceptions = ['status', 'vip_id', 'members', 'provider',
+                           'status_description']
+        self._check_list_with_filter(
+            'pool', attr_exceptions, name=data_utils.rand_name("pool-"),
+            lb_method="ROUND_ROBIN", protocol="HTTPS",
+            subnet_id=self.subnet['id'],
+            description=data_utils.rand_name('description-'),
+            admin_state_up=False)
+
+    @test.attr(type='smoke')
     def test_list_members(self):
         # Verify the member exists in the list of all members
         resp, body = self.client.list_members()
@@ -146,14 +202,23 @@
         self.assertIn(self.member['id'], [m['id'] for m in members])
 
     @test.attr(type='smoke')
+    def test_list_members_with_filters(self):
+        attr_exceptions = ['status', 'status_description']
+        self._check_list_with_filter('member', attr_exceptions,
+                                     address="10.0.9.47", protocol_port=80,
+                                     pool_id=self.pool['id'])
+
+    @test.attr(type='smoke')
     def test_create_update_delete_member(self):
         # Creates a member
-        resp, body = self.client.create_member("10.0.9.47", 80,
-                                               self.pool['id'])
+        resp, body = self.client.create_member(address="10.0.9.47",
+                                               protocol_port=80,
+                                               pool_id=self.pool['id'])
         self.assertEqual('201', resp['status'])
         member = body['member']
         # Verification of member update
-        resp, body = self.client.update_member(False, member['id'])
+        resp, body = self.client.update_member(member['id'],
+                                               admin_state_up=False)
         self.assertEqual('200', resp['status'])
         updated_member = body['member']
         self.assertFalse(updated_member['admin_state_up'])
@@ -167,9 +232,10 @@
         resp, body = self.client.show_member(self.member['id'])
         self.assertEqual('200', resp['status'])
         member = body['member']
-        self.assertEqual(self.member['id'], member['id'])
-        self.assertEqual(self.member['admin_state_up'],
-                         member['admin_state_up'])
+        for key, value in member.iteritems():
+             # 'status' should not be confirmed in api tests
+            if key != 'status':
+                self.assertEqual(self.member[key], value)
 
     @test.attr(type='smoke')
     def test_list_health_monitors(self):
@@ -181,6 +247,13 @@
                       [h['id'] for h in health_monitors])
 
     @test.attr(type='smoke')
+    def test_list_health_monitors_with_filters(self):
+        attr_exceptions = ['status', 'status_description', 'pools']
+        self._check_list_with_filter('health_monitor', attr_exceptions,
+                                     delay=5, max_retries=4, type="TCP",
+                                     timeout=2)
+
+    @test.attr(type='smoke')
     def test_create_update_delete_health_monitor(self):
         # Creates a health_monitor
         resp, body = self.client.create_health_monitor(delay=4,
@@ -206,9 +279,10 @@
         resp, body = self.client.show_health_monitor(self.health_monitor['id'])
         self.assertEqual('200', resp['status'])
         health_monitor = body['health_monitor']
-        self.assertEqual(self.health_monitor['id'], health_monitor['id'])
-        self.assertEqual(self.health_monitor['admin_state_up'],
-                         health_monitor['admin_state_up'])
+        for key, value in health_monitor.iteritems():
+             # 'status' should not be confirmed in api tests
+            if key != 'status':
+                self.assertEqual(self.health_monitor[key], value)
 
     @test.attr(type='smoke')
     def test_associate_disassociate_health_monitor_with_pool(self):
@@ -216,10 +290,26 @@
         resp, body = (self.client.associate_health_monitor_with_pool
                      (self.health_monitor['id'], self.pool['id']))
         self.assertEqual('201', resp['status'])
+        resp, body = self.client.show_health_monitor(
+            self.health_monitor['id'])
+        health_monitor = body['health_monitor']
+        resp, body = self.client.show_pool(self.pool['id'])
+        pool = body['pool']
+        self.assertIn(pool['id'],
+                      [p['pool_id'] for p in health_monitor['pools']])
+        self.assertIn(health_monitor['id'], pool['health_monitors'])
         # Verify that a health monitor can be disassociated from a pool
         resp, body = (self.client.disassociate_health_monitor_with_pool
                      (self.health_monitor['id'], self.pool['id']))
         self.assertEqual('204', resp['status'])
+        resp, body = self.client.show_pool(self.pool['id'])
+        pool = body['pool']
+        resp, body = self.client.show_health_monitor(
+            self.health_monitor['id'])
+        health_monitor = body['health_monitor']
+        self.assertNotIn(health_monitor['id'], pool['health_monitors'])
+        self.assertNotIn(pool['id'],
+                         [p['pool_id'] for p in health_monitor['pools']])
 
     @test.attr(type='smoke')
     def test_get_lb_pool_stats(self):
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index aba2c8e..88e7238 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -18,7 +18,6 @@
 from tempest.api.network import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest.test import attr
 
 CONF = config.CONF
@@ -72,165 +71,137 @@
 
     @attr(type='smoke')
     def test_create_update_delete_network_subnet(self):
-        # Creates a network
+        # Create a network
         name = data_utils.rand_name('network-')
         resp, body = self.client.create_network(name=name)
         self.assertEqual('201', resp['status'])
         network = body['network']
         net_id = network['id']
-        # Verification of network update
+        # Verify network update
         new_name = "New_network"
         resp, body = self.client.update_network(net_id, name=new_name)
         self.assertEqual('200', resp['status'])
         updated_net = body['network']
         self.assertEqual(updated_net['name'], new_name)
         # Find a cidr that is not in use yet and create a subnet with it
-        cidr = netaddr.IPNetwork(self._tenant_network_cidr)
-        mask_bits = self._tenant_network_mask_bits
-        for subnet_cidr in cidr.subnet(mask_bits):
-            try:
-                resp, body = self.client.create_subnet(
-                    network_id=net_id,
-                    cidr=str(subnet_cidr),
-                    ip_version=self._ip_version)
-                break
-            except exceptions.BadRequest as e:
-                is_overlapping_cidr = 'overlaps with another subnet' in str(e)
-                if not is_overlapping_cidr:
-                    raise
-        self.assertEqual('201', resp['status'])
-        subnet = body['subnet']
+        subnet = self.create_subnet(network)
         subnet_id = subnet['id']
-        # Verification of subnet update
-        new_subnet = "New_subnet"
-        resp, body = self.client.update_subnet(subnet_id,
-                                               name=new_subnet)
+        # Verify subnet update
+        new_name = "New_subnet"
+        resp, body = self.client.update_subnet(subnet_id, name=new_name)
         self.assertEqual('200', resp['status'])
         updated_subnet = body['subnet']
-        self.assertEqual(updated_subnet['name'], new_subnet)
+        self.assertEqual(updated_subnet['name'], new_name)
         # Delete subnet and network
         resp, body = self.client.delete_subnet(subnet_id)
         self.assertEqual('204', resp['status'])
+        # Remove subnet from cleanup list
+        self.subnets.pop()
         resp, body = self.client.delete_network(net_id)
         self.assertEqual('204', resp['status'])
 
     @attr(type='smoke')
     def test_show_network(self):
-        # Verifies the details of a network
+        # Verify the details of a network
         resp, body = self.client.show_network(self.network['id'])
         self.assertEqual('200', resp['status'])
         network = body['network']
-        self.assertEqual(self.network['id'], network['id'])
-        self.assertEqual(self.name, network['name'])
+        for key in ['id', 'name']:
+            self.assertEqual(network[key], self.network[key])
 
     @attr(type='smoke')
     def test_show_network_fields(self):
-        # Verifies showing some fields of a network works
+        # Verify specific fields of a network
         field_list = [('fields', 'id'), ('fields', 'name'), ]
         resp, body = self.client.show_network(self.network['id'],
                                               field_list=field_list)
         self.assertEqual('200', resp['status'])
         network = body['network']
-        self.assertEqual(len(network), 2)
-        self.assertEqual(self.network['id'], network['id'])
-        self.assertEqual(self.name, network['name'])
+        self.assertEqual(len(network), len(field_list))
+        for label, field_name in field_list:
+            self.assertEqual(network[field_name], self.network[field_name])
 
     @attr(type='smoke')
     def test_list_networks(self):
         # Verify the network exists in the list of all networks
         resp, body = self.client.list_networks()
         self.assertEqual('200', resp['status'])
-        networks = body['networks']
-        found = None
-        for n in networks:
-            if (n['id'] == self.network['id']):
-                found = n['id']
-        msg = "Network list doesn't contain created network"
-        self.assertIsNotNone(found, msg)
+        networks = [network['id'] for network in body['networks']
+                    if network['id'] == self.network['id']]
+        self.assertNotEmpty(networks, "Created network not found in the list")
 
     @attr(type='smoke')
     def test_list_networks_fields(self):
-        # Verify listing some fields of the networks
+        # Verify specific fields of the networks
         resp, body = self.client.list_networks(fields='id')
         self.assertEqual('200', resp['status'])
         networks = body['networks']
-        found = None
-        for n in networks:
-            self.assertEqual(len(n), 1)
-            self.assertIn('id', n)
-            if (n['id'] == self.network['id']):
-                found = n['id']
-        self.assertIsNotNone(found,
-                             "Created network id not found in the list")
+        self.assertNotEmpty(networks, "Network list returned is empty")
+        for network in networks:
+            self.assertEqual(len(network), 1)
+            self.assertIn('id', network)
 
     @attr(type='smoke')
     def test_show_subnet(self):
-        # Verifies the details of a subnet
+        # Verify the details of a subnet
         resp, body = self.client.show_subnet(self.subnet['id'])
         self.assertEqual('200', resp['status'])
         subnet = body['subnet']
-        self.assertEqual(self.subnet['id'], subnet['id'])
-        self.assertEqual(self.cidr, subnet['cidr'])
+        self.assertNotEmpty(subnet, "Subnet returned has no fields")
+        for key in ['id', 'cidr']:
+            self.assertIn(key, subnet)
+            self.assertEqual(subnet[key], self.subnet[key])
 
     @attr(type='smoke')
     def test_show_subnet_fields(self):
-        # Verifies showing some fields of a subnet works
+        # Verify specific fields of a subnet
         field_list = [('fields', 'id'), ('fields', 'cidr'), ]
         resp, body = self.client.show_subnet(self.subnet['id'],
                                              field_list=field_list)
         self.assertEqual('200', resp['status'])
         subnet = body['subnet']
-        self.assertEqual(len(subnet), 2)
-        self.assertEqual(self.subnet['id'], subnet['id'])
-        self.assertEqual(self.cidr, subnet['cidr'])
+        self.assertEqual(len(subnet), len(field_list))
+        for label, field_name in field_list:
+            self.assertEqual(subnet[field_name], self.subnet[field_name])
 
     @attr(type='smoke')
     def test_list_subnets(self):
         # Verify the subnet exists in the list of all subnets
         resp, body = self.client.list_subnets()
         self.assertEqual('200', resp['status'])
-        subnets = body['subnets']
-        found = None
-        for n in subnets:
-            if (n['id'] == self.subnet['id']):
-                found = n['id']
-        msg = "Subnet list doesn't contain created subnet"
-        self.assertIsNotNone(found, msg)
+        subnets = [subnet['id'] for subnet in body['subnets']
+                   if subnet['id'] == self.subnet['id']]
+        self.assertNotEmpty(subnets, "Created subnet not found in the list")
 
     @attr(type='smoke')
     def test_list_subnets_fields(self):
-        # Verify listing some fields of the subnets
+        # Verify specific fields of subnets
         resp, body = self.client.list_subnets(fields='id')
         self.assertEqual('200', resp['status'])
         subnets = body['subnets']
-        found = None
-        for n in subnets:
-            self.assertEqual(len(n), 1)
-            self.assertIn('id', n)
-            if (n['id'] == self.subnet['id']):
-                found = n['id']
-        self.assertIsNotNone(found,
-                             "Created subnet id not found in the list")
+        self.assertNotEmpty(subnets, "Subnet list returned is empty")
+        for subnet in subnets:
+            self.assertEqual(len(subnet), 1)
+            self.assertIn('id', subnet)
 
     @attr(type='smoke')
     def test_create_update_delete_port(self):
-        # Verify that successful port creation, update & deletion
-        resp, body = self.client.create_port(
-            network_id=self.network['id'])
+        # Verify port creation
+        resp, body = self.client.create_port(network_id=self.network['id'])
         self.assertEqual('201', resp['status'])
         port = body['port']
         self.assertTrue(port['admin_state_up'])
-        # Verification of port update
-        new_port = "New_Port"
+        # Verify port update
+        new_name = "New_Port"
         resp, body = self.client.update_port(
             port['id'],
-            name=new_port,
+            name=new_name,
             admin_state_up=False)
         self.assertEqual('200', resp['status'])
         updated_port = body['port']
-        self.assertEqual(updated_port['name'], new_port)
+        self.assertEqual(updated_port['name'], new_name)
         self.assertFalse(updated_port['admin_state_up'])
-        # Verification of port delete
+        # Verify port deletion
         resp, body = self.client.delete_port(port['id'])
         self.assertEqual('204', resp['status'])
 
@@ -240,30 +211,29 @@
         resp, body = self.client.show_port(self.port['id'])
         self.assertEqual('200', resp['status'])
         port = body['port']
-        self.assertEqual(self.port['id'], port['id'])
+        self.assertIn('id', port)
+        self.assertEqual(port['id'], self.port['id'])
 
     @attr(type='smoke')
     def test_show_port_fields(self):
-        # Verifies showing fields of a port works
+        # Verify specific fields of a port
         field_list = [('fields', 'id'), ]
         resp, body = self.client.show_port(self.port['id'],
                                            field_list=field_list)
         self.assertEqual('200', resp['status'])
         port = body['port']
-        self.assertEqual(len(port), 1)
-        self.assertEqual(self.port['id'], port['id'])
+        self.assertEqual(len(port), len(field_list))
+        for label, field_name in field_list:
+            self.assertEqual(port[field_name], self.port[field_name])
 
     @attr(type='smoke')
     def test_list_ports(self):
         # Verify the port exists in the list of all ports
         resp, body = self.client.list_ports()
         self.assertEqual('200', resp['status'])
-        ports_list = body['ports']
-        found = None
-        for n in ports_list:
-            if (n['id'] == self.port['id']):
-                found = n['id']
-        self.assertIsNotNone(found, "Port list doesn't contain created port")
+        ports = [port['id'] for port in body['ports']
+                 if port['id'] == self.port['id']]
+        self.assertNotEmpty(ports, "Created port not found in the list")
 
     @attr(type='smoke')
     def test_port_list_filter_by_router_id(self):
@@ -271,36 +241,32 @@
         network = self.create_network()
         self.create_subnet(network)
         router = self.create_router(data_utils.rand_name('router-'))
-        resp, port = self.client.create_port(
-            network_id=network['id'])
+        resp, port = self.client.create_port(network_id=network['id'])
         # Add router interface to port created above
         resp, interface = self.client.add_router_interface_with_port_id(
             router['id'], port['port']['id'])
         self.addCleanup(self.client.remove_router_interface_with_port_id,
                         router['id'], port['port']['id'])
-        # list ports filtered by router_id
+        # List ports filtered by router_id
         resp, port_list = self.client.list_ports(
             device_id=router['id'])
         self.assertEqual('200', resp['status'])
-        # Verify if only corresponding port is listed and assert router_id
-        self.assertEqual(len(port_list['ports']), 1)
-        self.assertEqual(port['port']['id'], port_list['ports'][0]['id'])
-        self.assertEqual(router['id'], port_list['ports'][0]['device_id'])
+        ports = port_list['ports']
+        self.assertEqual(len(ports), 1)
+        self.assertEqual(ports[0]['id'], port['port']['id'])
+        self.assertEqual(ports[0]['device_id'], router['id'])
 
     @attr(type='smoke')
     def test_list_ports_fields(self):
-        # Verify listing some fields of the ports
+        # Verify specific fields of ports
         resp, body = self.client.list_ports(fields='id')
         self.assertEqual('200', resp['status'])
-        ports_list = body['ports']
-        found = None
-        for n in ports_list:
-            self.assertEqual(len(n), 1)
-            self.assertIn('id', n)
-            if (n['id'] == self.port['id']):
-                found = n['id']
-        self.assertIsNotNone(found,
-                             "Created port id not found in the list")
+        ports = body['ports']
+        self.assertNotEmpty(ports, "Port list returned is empty")
+        # Asserting the fields returned are correct
+        for port in ports:
+            self.assertEqual(len(port), 1)
+            self.assertIn('id', port)
 
 
 class NetworksTestXML(NetworksTestJSON):
@@ -341,9 +307,7 @@
             self.assertEqual(204, resp.status)
         # Asserting that the networks are not found in the list after deletion
         resp, body = self.client.list_networks()
-        networks_list = list()
-        for network in body['networks']:
-            networks_list.append(network['id'])
+        networks_list = [network['id'] for network in body['networks']]
         for n in created_networks:
             self.assertNotIn(n['id'], networks_list)
 
@@ -353,9 +317,7 @@
             self.assertEqual(204, resp.status)
         # Asserting that the subnets are not found in the list after deletion
         resp, body = self.client.list_subnets()
-        subnets_list = list()
-        for subnet in body['subnets']:
-            subnets_list.append(subnet['id'])
+        subnets_list = [subnet['id'] for subnet in body['subnets']]
         for n in created_subnets:
             self.assertNotIn(n['id'], subnets_list)
 
@@ -365,9 +327,7 @@
             self.assertEqual(204, resp.status)
         # Asserting that the ports are not found in the list after deletion
         resp, body = self.client.list_ports()
-        ports_list = list()
-        for port in body['ports']:
-            ports_list.append(port['id'])
+        ports_list = [port['id'] for port in body['ports']]
         for n in created_ports:
             self.assertNotIn(n['id'], ports_list)
 
@@ -382,9 +342,7 @@
         self.addCleanup(self._delete_networks, created_networks)
         # Asserting that the networks are found in the list after creation
         resp, body = self.client.list_networks()
-        networks_list = list()
-        for network in body['networks']:
-            networks_list.append(network['id'])
+        networks_list = [network['id'] for network in body['networks']]
         for n in created_networks:
             self.assertIsNotNone(n['id'])
             self.assertIn(n['id'], networks_list)
@@ -394,14 +352,10 @@
         # Creates 2 subnets in one request
         cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
         mask_bits = CONF.network.tenant_network_mask_bits
-        cidrs = []
-        for subnet_cidr in cidr.subnet(mask_bits):
-            cidrs.append(subnet_cidr)
-        names = []
+        cidrs = [subnet_cidr for subnet_cidr in cidr.subnet(mask_bits)]
         networks = [self.network1['id'], self.network2['id']]
-        for i in range(len(networks)):
-            names.append(data_utils.rand_name('subnet-'))
-        subnet_list = []
+        names = [data_utils.rand_name('subnet-') for i in range(len(networks))]
+        subnets_list = []
         # TODO(raies): "for IPv6, version list [4, 6] will be used.
         # and cidr for IPv6 will be of IPv6"
         ip_version = [4, 4]
@@ -412,17 +366,15 @@
                 'name': names[i],
                 'ip_version': ip_version[i]
             }
-            subnet_list.append(p1)
-        del subnet_list[1]['name']
-        resp, body = self.client.create_bulk_subnet(subnet_list)
+            subnets_list.append(p1)
+        del subnets_list[1]['name']
+        resp, body = self.client.create_bulk_subnet(subnets_list)
         created_subnets = body['subnets']
         self.addCleanup(self._delete_subnets, created_subnets)
         self.assertEqual('201', resp['status'])
         # Asserting that the subnets are found in the list after creation
         resp, body = self.client.list_subnets()
-        subnets_list = list()
-        for subnet in body['subnets']:
-            subnets_list.append(subnet['id'])
+        subnets_list = [subnet['id'] for subnet in body['subnets']]
         for n in created_subnets:
             self.assertIsNotNone(n['id'])
             self.assertIn(n['id'], subnets_list)
@@ -430,10 +382,8 @@
     @attr(type='smoke')
     def test_bulk_create_delete_port(self):
         # Creates 2 ports in one request
-        names = []
         networks = [self.network1['id'], self.network2['id']]
-        for i in range(len(networks)):
-            names.append(data_utils.rand_name('port-'))
+        names = [data_utils.rand_name('port-') for i in range(len(networks))]
         port_list = []
         state = [True, False]
         for i in range(len(names)):
@@ -450,9 +400,7 @@
         self.assertEqual('201', resp['status'])
         # Asserting that the ports are found in the list after creation
         resp, body = self.client.list_ports()
-        ports_list = list()
-        for port in body['ports']:
-            ports_list.append(port['id'])
+        ports_list = [port['id'] for port in body['ports']]
         for n in created_ports:
             self.assertIsNotNone(n['id'])
             self.assertIn(n['id'], ports_list)
@@ -464,13 +412,11 @@
 
 class NetworksIpV6TestJSON(NetworksTestJSON):
     _ip_version = 6
-    _tenant_network_cidr = CONF.network.tenant_network_v6_cidr
-    _tenant_network_mask_bits = CONF.network.tenant_network_v6_mask_bits
 
     @classmethod
     def setUpClass(cls):
         super(NetworksIpV6TestJSON, cls).setUpClass()
-        if not CONF.network.ipv6_enabled:
+        if not CONF.network_feature_enabled.ipv6:
             cls.tearDownClass()
             skip_msg = "IPv6 Tests are disabled."
             raise cls.skipException(skip_msg)
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index d552c70..2657031 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -16,6 +16,7 @@
 import netaddr
 
 from tempest.api.network import base_routers as base
+from tempest import clients
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest import test
@@ -32,6 +33,8 @@
         if not test.is_extension_enabled('router', 'network'):
             msg = "router extension not enabled."
             raise cls.skipException(msg)
+        admin_manager = clients.AdminManager()
+        cls.identity_admin_client = admin_manager.identity_client
 
     @test.attr(type='smoke')
     def test_create_show_list_update_delete_router(self):
@@ -77,6 +80,25 @@
         self.assertEqual(show_body['router']['name'], updated_name)
 
     @test.attr(type='smoke')
+    def test_create_router_setting_tenant_id(self):
+        # Test creating router from admin user setting tenant_id.
+        test_tenant = data_utils.rand_name('test_tenant_')
+        test_description = data_utils.rand_name('desc_')
+        _, tenant = self.identity_admin_client.create_tenant(
+            name=test_tenant,
+            description=test_description)
+        tenant_id = tenant['id']
+        self.addCleanup(self.identity_admin_client.delete_tenant, tenant_id)
+
+        name = data_utils.rand_name('router-')
+        resp, create_body = self.admin_client.create_router(
+            name, tenant_id=tenant_id)
+        self.assertEqual('201', resp['status'])
+        self.addCleanup(self.admin_client.delete_router,
+                        create_body['router']['id'])
+        self.assertEqual(tenant_id, create_body['router']['tenant_id'])
+
+    @test.attr(type='smoke')
     def test_add_remove_router_interface_with_subnet_id(self):
         network = self.create_network()
         subnet = self.create_subnet(network)
@@ -234,3 +256,48 @@
 
     def _delete_extra_routes(self, router_id):
         resp, _ = self.client.delete_extra_routes(router_id)
+
+    @test.attr(type='smoke')
+    def test_update_router_admin_state(self):
+        self.router = self.create_router(data_utils.rand_name('router-'))
+        self.assertFalse(self.router['admin_state_up'])
+        # Update router admin state
+        resp, update_body = self.client.update_router(self.router['id'],
+                                                      admin_state_up=True)
+        self.assertEqual('200', resp['status'])
+        self.assertTrue(update_body['router']['admin_state_up'])
+        resp, show_body = self.client.show_router(self.router['id'])
+        self.assertEqual('200', resp['status'])
+        self.assertTrue(show_body['router']['admin_state_up'])
+
+    @test.attr(type='smoke')
+    def test_add_multiple_router_interfaces(self):
+        network = self.create_network()
+        subnet01 = self.create_subnet(network)
+        subnet02 = self.create_subnet(network)
+        router = self.create_router(data_utils.rand_name('router-'))
+        interface01 = self._add_router_interface_with_subnet_id(router['id'],
+                                                                subnet01['id'])
+        self._verify_router_interface(router['id'], subnet01['id'],
+                                      interface01['port_id'])
+        interface02 = self._add_router_interface_with_subnet_id(router['id'],
+                                                                subnet02['id'])
+        self._verify_router_interface(router['id'], subnet02['id'],
+                                      interface02['port_id'])
+
+    def _add_router_interface_with_subnet_id(self, router_id, subnet_id):
+        resp, interface = self.client.add_router_interface_with_subnet_id(
+            router_id, subnet_id)
+        self.assertEqual('200', resp['status'])
+        self.addCleanup(self._remove_router_interface_with_subnet_id,
+                        router_id, subnet_id)
+        self.assertEqual(subnet_id, interface['subnet_id'])
+        return interface
+
+    def _verify_router_interface(self, router_id, subnet_id, port_id):
+        resp, show_port_body = self.client.show_port(port_id)
+        self.assertEqual('200', resp['status'])
+        interface_port = show_port_body['port']
+        self.assertEqual(router_id, interface_port['device_id'])
+        self.assertEqual(subnet_id,
+                         interface_port['fixed_ips'][0]['subnet_id'])
diff --git a/tempest/api/network/test_security_groups.py b/tempest/api/network/test_security_groups.py
index 1d41cc9..3e26f46 100644
--- a/tempest/api/network/test_security_groups.py
+++ b/tempest/api/network/test_security_groups.py
@@ -14,6 +14,7 @@
 #    under the License.
 
 from tempest.api.network import base_security_groups as base
+from tempest.common.utils import data_utils
 from tempest import test
 
 
@@ -41,15 +42,9 @@
         self.assertIsNotNone(found, msg)
 
     @test.attr(type='smoke')
-    def test_create_show_delete_security_group(self):
+    def test_create_list_update_show_delete_security_group(self):
         group_create_body, name = self._create_security_group()
 
-        # Show details of the created security group
-        resp, show_body = self.client.show_security_group(
-            group_create_body['security_group']['id'])
-        self.assertEqual('200', resp['status'])
-        self.assertEqual(show_body['security_group']['name'], name)
-
         # List security groups and verify if created group is there in response
         resp, list_body = self.client.list_security_groups()
         self.assertEqual('200', resp['status'])
@@ -57,6 +52,24 @@
         for secgroup in list_body['security_groups']:
             secgroup_list.append(secgroup['id'])
         self.assertIn(group_create_body['security_group']['id'], secgroup_list)
+        # Update the security group
+        new_name = data_utils.rand_name('security-')
+        new_description = data_utils.rand_name('security-description')
+        resp, update_body = self.client.update_security_group(
+            group_create_body['security_group']['id'],
+            name=new_name,
+            description=new_description)
+        # Verify if security group is updated
+        self.assertEqual('200', resp['status'])
+        self.assertEqual(update_body['security_group']['name'], new_name)
+        self.assertEqual(update_body['security_group']['description'],
+                         new_description)
+        # Show details of the updated security group
+        resp, show_body = self.client.show_security_group(
+            group_create_body['security_group']['id'])
+        self.assertEqual(show_body['security_group']['name'], new_name)
+        self.assertEqual(show_body['security_group']['description'],
+                         new_description)
 
     @test.attr(type='smoke')
     def test_create_show_delete_security_group_rule(self):
diff --git a/tempest/api/object_storage/test_account_quotas.py b/tempest/api/object_storage/test_account_quotas.py
index 788292d..b14adc0 100644
--- a/tempest/api/object_storage/test_account_quotas.py
+++ b/tempest/api/object_storage/test_account_quotas.py
@@ -17,9 +17,12 @@
 from tempest.api.object_storage import base
 from tempest import clients
 from tempest.common.utils import data_utils
+from tempest import config
 from tempest import exceptions
 from tempest import test
 
+CONF = config.CONF
+
 
 class AccountQuotasTest(base.BaseObjectTest):
 
@@ -41,7 +44,7 @@
         try:
             _, roles = cls.os_admin.identity_client.list_roles()
             reseller_role_id = next(r['id'] for r in roles if r['name']
-                                    == 'ResellerAdmin')
+                                    == CONF.object_storage.reseller_admin_role)
         except StopIteration:
             msg = "No ResellerAdmin role found"
             raise exceptions.NotFound(msg)
diff --git a/tempest/api/object_storage/test_account_quotas_negative.py b/tempest/api/object_storage/test_account_quotas_negative.py
index cab307d..402cd90 100644
--- a/tempest/api/object_storage/test_account_quotas_negative.py
+++ b/tempest/api/object_storage/test_account_quotas_negative.py
@@ -17,9 +17,12 @@
 from tempest.api.object_storage import base
 from tempest import clients
 from tempest.common.utils import data_utils
+from tempest import config
 from tempest import exceptions
 from tempest import test
 
+CONF = config.CONF
+
 
 class AccountQuotasNegativeTest(base.BaseObjectTest):
 
@@ -41,7 +44,7 @@
         try:
             _, roles = cls.os_admin.identity_client.list_roles()
             reseller_role_id = next(r['id'] for r in roles if r['name']
-                                    == 'ResellerAdmin')
+                                    == CONF.object_storage.reseller_admin_role)
         except StopIteration:
             msg = "No ResellerAdmin role found"
             raise exceptions.NotFound(msg)
diff --git a/tempest/api/object_storage/test_account_services.py b/tempest/api/object_storage/test_account_services.py
index 5456768..4b895d8 100644
--- a/tempest/api/object_storage/test_account_services.py
+++ b/tempest/api/object_storage/test_account_services.py
@@ -15,18 +15,25 @@
 
 import random
 
+from six import moves
+
 from tempest.api.object_storage import base
+from tempest import clients
 from tempest.common import custom_matchers
 from tempest.common.utils import data_utils
+from tempest import config
+from tempest import exceptions
 from tempest import test
 
+CONF = config.CONF
+
 
 class AccountTest(base.BaseObjectTest):
     @classmethod
     def setUpClass(cls):
         super(AccountTest, cls).setUpClass()
         cls.containers = []
-        for i in xrange(ord('a'), ord('f') + 1):
+        for i in moves.xrange(ord('a'), ord('f') + 1):
             name = data_utils.rand_name(name='%s-' % chr(i))
             cls.container_client.create_container(name)
             cls.containers.append(name)
@@ -35,20 +42,109 @@
     @classmethod
     def tearDownClass(cls):
         cls.delete_containers(cls.containers)
+        cls.data.teardown_all()
         super(AccountTest, cls).tearDownClass()
 
     @test.attr(type='smoke')
     def test_list_containers(self):
         # list of all containers should not be empty
-        params = {'format': 'json'}
-        resp, container_list = \
-            self.account_client.list_account_containers(params=params)
+        resp, container_list = self.account_client.list_account_containers()
         self.assertHeaders(resp, 'Account', 'GET')
 
         self.assertIsNotNone(container_list)
-        container_names = [c['name'] for c in container_list]
         for container_name in self.containers:
-            self.assertIn(container_name, container_names)
+            self.assertIn(container_name, container_list)
+
+    @test.attr(type='smoke')
+    def test_list_no_containers(self):
+        # List request to empty account
+
+        # To test listing no containers, create new user other than
+        # the base user of this instance.
+        self.data.setup_test_user()
+
+        os_test_user = clients.Manager(
+            self.data.test_user,
+            self.data.test_password,
+            self.data.test_tenant)
+
+        # Retrieve the id of an operator role of object storage
+        test_role_id = None
+        swift_role = CONF.object_storage.operator_role
+        try:
+            _, roles = self.os_admin.identity_client.list_roles()
+            test_role_id = next(r['id'] for r in roles if r['name']
+                                == swift_role)
+        except StopIteration:
+            msg = "%s role found" % swift_role
+            raise exceptions.NotFound(msg)
+
+        # Retrieve the test_user id
+        _, users = self.os_admin.identity_client.get_users()
+        test_user_id = next(usr['id'] for usr in users if usr['name']
+                            == self.data.test_user)
+
+        # Retrieve the test_tenant id
+        _, tenants = self.os_admin.identity_client.list_tenants()
+        test_tenant_id = next(tnt['id'] for tnt in tenants if tnt['name']
+                              == self.data.test_tenant)
+
+        # Assign the newly created user the appropriate operator role
+        self.os_admin.identity_client.assign_user_role(
+            test_tenant_id,
+            test_user_id,
+            test_role_id)
+
+        resp, container_list = \
+            os_test_user.account_client.list_account_containers()
+        self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
+
+        # When sending a request to an account which has not received a PUT
+        # container request, the response does not contain 'accept-ranges'
+        # header. This is a special case, therefore the existence of response
+        # headers is checked without custom matcher.
+        self.assertIn('content-length', resp)
+        self.assertIn('x-timestamp', resp)
+        self.assertIn('x-account-bytes-used', resp)
+        self.assertIn('x-account-container-count', resp)
+        self.assertIn('x-account-object-count', resp)
+        self.assertIn('content-type', resp)
+        self.assertIn('x-trans-id', resp)
+        self.assertIn('date', resp)
+
+        # Check only the format of common headers with custom matcher
+        self.assertThat(resp, custom_matchers.AreAllWellFormatted())
+
+        self.assertEqual(len(container_list), 0)
+
+    @test.attr(type='smoke')
+    def test_list_containers_with_format_json(self):
+        # list containers setting format parameter to 'json'
+        params = {'format': 'json'}
+        resp, container_list = self.account_client.list_account_containers(
+            params=params)
+        self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
+        self.assertHeaders(resp, 'Account', 'GET')
+        self.assertIsNotNone(container_list)
+        self.assertTrue([c['name'] for c in container_list])
+        self.assertTrue([c['count'] for c in container_list])
+        self.assertTrue([c['bytes'] for c in container_list])
+
+    @test.attr(type='smoke')
+    def test_list_containers_with_format_xml(self):
+        # list containers setting format parameter to 'xml'
+        params = {'format': 'xml'}
+        resp, container_list = self.account_client.list_account_containers(
+            params=params)
+        self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
+        self.assertHeaders(resp, 'Account', 'GET')
+        self.assertIsNotNone(container_list)
+        self.assertEqual(container_list.tag, 'account')
+        self.assertTrue('name' in container_list.keys())
+        self.assertEqual(container_list.find(".//container").tag, 'container')
+        self.assertEqual(container_list.find(".//name").tag, 'name')
+        self.assertEqual(container_list.find(".//count").tag, 'count')
+        self.assertEqual(container_list.find(".//bytes").tag, 'bytes')
 
     @test.attr(type='smoke')
     def test_list_extensions(self):
@@ -107,6 +203,17 @@
         self.assertEqual(len(container_list), self.containers_count / 2)
 
     @test.attr(type='smoke')
+    def test_list_containers_with_marker_and_end_marker(self):
+        # list containers combining marker and end_marker param
+        params = {'marker': self.containers[0],
+                  'end_marker': self.containers[self.containers_count - 1]}
+        resp, container_list = self.account_client.list_account_containers(
+            params=params)
+        self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
+        self.assertHeaders(resp, 'Account', 'GET')
+        self.assertEqual(len(container_list), self.containers_count - 2)
+
+    @test.attr(type='smoke')
     def test_list_containers_with_limit_and_marker(self):
         # list containers combining marker and limit param
         # result are always limitated by the limit whatever the marker
@@ -121,34 +228,125 @@
             self.assertTrue(len(container_list) <= limit, str(container_list))
 
     @test.attr(type='smoke')
-    def test_list_account_metadata(self):
-        # list all account metadata
-        resp, metadata = self.account_client.list_account_metadata()
+    def test_list_containers_with_limit_and_end_marker(self):
+        # list containers combining limit and end_marker param
+        limit = random.randint(1, self.containers_count)
+        params = {'limit': limit,
+                  'end_marker': self.containers[self.containers_count / 2]}
+        resp, container_list = self.account_client.list_account_containers(
+            params=params)
         self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
-        self.assertHeaders(resp, 'Account', 'HEAD')
+        self.assertHeaders(resp, 'Account', 'GET')
+        self.assertEqual(len(container_list),
+                         min(limit, self.containers_count / 2))
 
     @test.attr(type='smoke')
-    def test_create_and_delete_account_metadata(self):
-        header = 'test-account-meta'
-        data = 'Meta!'
+    def test_list_containers_with_limit_and_marker_and_end_marker(self):
+        # list containers combining limit, marker and end_marker param
+        limit = random.randint(1, self.containers_count)
+        params = {'limit': limit,
+                  'marker': self.containers[0],
+                  'end_marker': self.containers[self.containers_count - 1]}
+        resp, container_list = self.account_client.list_account_containers(
+            params=params)
+        self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
+        self.assertHeaders(resp, 'Account', 'GET')
+        self.assertEqual(len(container_list),
+                         min(limit, self.containers_count - 2))
+
+    @test.attr(type='smoke')
+    def test_list_account_metadata(self):
+        # list all account metadata
+
+        # set metadata to account
+        metadata = {'test-account-meta1': 'Meta1',
+                    'test-account-meta2': 'Meta2'}
+        resp, _ = self.account_client.create_account_metadata(metadata)
+
+        resp, _ = self.account_client.list_account_metadata()
+        self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
+        self.assertHeaders(resp, 'Account', 'HEAD')
+        self.assertIn('x-account-meta-test-account-meta1', resp)
+        self.assertIn('x-account-meta-test-account-meta2', resp)
+        self.account_client.delete_account_metadata(metadata)
+
+    @test.attr(type='smoke')
+    def test_list_no_account_metadata(self):
+        # list no account metadata
+        resp, _ = self.account_client.list_account_metadata()
+        self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
+        self.assertHeaders(resp, 'Account', 'HEAD')
+        self.assertNotIn('x-account-meta-', str(resp))
+
+    @test.attr(type='smoke')
+    def test_update_account_metadata_with_create_metadata(self):
         # add metadata to account
-        resp, _ = self.account_client.create_account_metadata(
-            metadata={header: data})
+        metadata = {'test-account-meta1': 'Meta1'}
+        resp, _ = self.account_client.create_account_metadata(metadata)
         self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
         self.assertHeaders(resp, 'Account', 'POST')
 
-        resp, _ = self.account_client.list_account_metadata()
-        self.assertHeaders(resp, 'Account', 'HEAD')
+        resp, body = self.account_client.list_account_metadata()
+        self.assertIn('x-account-meta-test-account-meta1', resp)
+        self.assertEqual(resp['x-account-meta-test-account-meta1'],
+                         metadata['test-account-meta1'])
 
-        self.assertIn('x-account-meta-' + header, resp)
-        self.assertEqual(resp['x-account-meta-' + header], data)
+        self.account_client.delete_account_metadata(metadata)
 
+    @test.attr(type='smoke')
+    def test_update_account_metadata_with_delete_matadata(self):
         # delete metadata from account
-        resp, _ = \
-            self.account_client.delete_account_metadata(metadata=[header])
+        metadata = {'test-account-meta1': 'Meta1'}
+        self.account_client.create_account_metadata(metadata)
+        resp, _ = self.account_client.delete_account_metadata(metadata)
         self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
         self.assertHeaders(resp, 'Account', 'POST')
 
         resp, _ = self.account_client.list_account_metadata()
-        self.assertHeaders(resp, 'Account', 'HEAD')
-        self.assertNotIn('x-account-meta-' + header, resp)
+        self.assertNotIn('x-account-meta-test-account-meta1', resp)
+
+    @test.attr(type='smoke')
+    def test_update_account_metadata_with_create_matadata_key(self):
+        # if the value of metadata is not set, the metadata is not
+        # registered at a server
+        metadata = {'test-account-meta1': ''}
+        resp, _ = self.account_client.create_account_metadata(metadata)
+        self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
+        self.assertHeaders(resp, 'Account', 'POST')
+
+        resp, _ = self.account_client.list_account_metadata()
+        self.assertNotIn('x-account-meta-test-account-meta1', resp)
+
+    @test.attr(type='smoke')
+    def test_update_account_metadata_with_delete_matadata_key(self):
+        # Although the value of metadata is not set, the feature of
+        # deleting metadata is valid
+        metadata_1 = {'test-account-meta1': 'Meta1'}
+        self.account_client.create_account_metadata(metadata_1)
+        metadata_2 = {'test-account-meta1': ''}
+        resp, _ = self.account_client.delete_account_metadata(metadata_2)
+        self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
+        self.assertHeaders(resp, 'Account', 'POST')
+
+        resp, _ = self.account_client.list_account_metadata()
+        self.assertNotIn('x-account-meta-test-account-meta1', resp)
+
+    @test.attr(type='smoke')
+    def test_update_account_metadata_with_create_and_delete_metadata(self):
+        # Send a request adding and deleting metadata requests simultaneously
+        metadata_1 = {'test-account-meta1': 'Meta1'}
+        self.account_client.create_account_metadata(metadata_1)
+        metadata_2 = {'test-account-meta2': 'Meta2'}
+        resp, body = self.account_client.create_and_delete_account_metadata(
+            metadata_2,
+            metadata_1)
+        self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
+        self.assertHeaders(resp, 'Account', 'POST')
+
+        resp, _ = self.account_client.list_account_metadata()
+        self.assertNotIn('x-account-meta-test-account-meta1', resp)
+        self.assertIn('x-account-meta-test-account-meta2', resp)
+        self.assertEqual(resp['x-account-meta-test-account-meta2'],
+                         metadata_2['test-account-meta2'])
+
+        self.account_client.delete_account_metadata(metadata_2)
diff --git a/tempest/api/object_storage/test_object_services.py b/tempest/api/object_storage/test_object_services.py
index 33f3299..91df292 100644
--- a/tempest/api/object_storage/test_object_services.py
+++ b/tempest/api/object_storage/test_object_services.py
@@ -14,6 +14,7 @@
 #    under the License.
 
 import hashlib
+from six import moves
 
 from tempest.api.object_storage import base
 from tempest.common import custom_matchers
@@ -242,9 +243,9 @@
         object_name = data_utils.rand_name(name='LObject')
         data = data_utils.arbitrary_string()
         segments = 10
-        data_segments = [data + str(i) for i in xrange(segments)]
+        data_segments = [data + str(i) for i in moves.xrange(segments)]
         # uploading segments
-        for i in xrange(segments):
+        for i in moves.xrange(segments):
             resp, _ = self.object_client.create_object_segments(
                 self.container_name, object_name, i, data_segments[i])
             self.assertEqual(resp['status'], '201')
diff --git a/tempest/api/object_storage/test_object_temp_url.py b/tempest/api/object_storage/test_object_temp_url.py
index 47c270e..c597255 100644
--- a/tempest/api/object_storage/test_object_temp_url.py
+++ b/tempest/api/object_storage/test_object_temp_url.py
@@ -40,9 +40,9 @@
         # update account metadata
         cls.key = 'Meta'
         cls.metadatas = []
-        cls.metadata = {'Temp-URL-Key': cls.key}
-        cls.metadatas.append(cls.metadata)
-        cls.account_client.create_account_metadata(metadata=cls.metadata)
+        metadata = {'Temp-URL-Key': cls.key}
+        cls.metadatas.append(metadata)
+        cls.account_client.create_account_metadata(metadata=metadata)
 
         # create an object
         cls.object_name = data_utils.rand_name(name='ObjectTemp')
@@ -53,7 +53,7 @@
 
     @classmethod
     def tearDownClass(cls):
-        for metadata in cls.metadata:
+        for metadata in cls.metadatas:
             cls.account_client.delete_account_metadata(
                 metadata=metadata)
 
diff --git a/tempest/api/orchestration/stacks/test_neutron_resources.py b/tempest/api/orchestration/stacks/test_neutron_resources.py
index 3e621f4..18ba37b 100644
--- a/tempest/api/orchestration/stacks/test_neutron_resources.py
+++ b/tempest/api/orchestration/stacks/test_neutron_resources.py
@@ -73,7 +73,7 @@
       subnet_id: {get_resource: Subnet}
   Server:
     type: AWS::EC2::Instance
-    Metadata:
+    metadata:
       Name: SmokeServerNeutron
     properties:
       ImageId: {get_param: ImageId}
@@ -93,7 +93,7 @@
     type: AWS::CloudFormation::WaitConditionHandle
   WaitCondition:
     type: AWS::CloudFormation::WaitCondition
-    DependsOn: Server
+    depends_on: Server
     properties:
       Handle: {get_resource: WaitHandleNeutron}
       Timeout: '600'
@@ -135,7 +135,7 @@
             # the cause of the server not signalling the waitcondition
             # to heat.
             resp, body = cls.client.get_resource(cls.stack_identifier,
-                                                 'SmokeServerNeutron')
+                                                 'Server')
             server_id = body['physical_resource_id']
             LOG.debug('Console output for %s', server_id)
             resp, output = cls.servers_client.get_console_output(
diff --git a/tempest/api/orchestration/stacks/test_nova_keypair_resources.py b/tempest/api/orchestration/stacks/test_nova_keypair_resources.py
new file mode 100644
index 0000000..9d3bf13
--- /dev/null
+++ b/tempest/api/orchestration/stacks/test_nova_keypair_resources.py
@@ -0,0 +1,181 @@
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+
+import logging
+
+from tempest.api.orchestration import base
+from tempest.common.utils import data_utils
+from tempest.test import attr
+
+
+LOG = logging.getLogger(__name__)
+
+
+class NovaKeyPairResourcesYAMLTest(base.BaseOrchestrationTest):
+    _interface = 'json'
+    template = """
+heat_template_version: 2013-05-23
+
+description: >
+  Template which creates two key pairs.
+
+parameters:
+  KeyPairName1:
+    type: string
+    default: testkey
+
+  KeyPairName2:
+    type: string
+    default: testkey2
+
+resources:
+  KeyPairSavePrivate:
+    type: OS::Nova::KeyPair
+    properties:
+      name: { get_param: KeyPairName1 }
+      save_private_key: true
+
+  KeyPairDontSavePrivate:
+    type: OS::Nova::KeyPair
+    properties:
+      name: { get_param: KeyPairName2 }
+      save_private_key: false
+
+outputs:
+  KeyPair_PublicKey:
+    description: Public Key of generated keypair
+    value: { get_attr: [KeyPairSavePrivate, public_key] }
+
+  KeyPair_PrivateKey:
+    description: Private Key of generated keypair
+    value: { get_attr: [KeyPairSavePrivate, private_key] }
+
+  KeyPairDontSavePrivate_PublicKey:
+    description: Public Key of generated keypair
+    value: { get_attr: [KeyPairDontSavePrivate, public_key] }
+
+  KeyPairDontSavePrivate_PrivateKey:
+    description: Private Key of generated keypair
+    value: { get_attr: [KeyPairDontSavePrivate, private_key] }
+"""
+
+    @classmethod
+    def setUpClass(cls):
+        super(NovaKeyPairResourcesYAMLTest, cls).setUpClass()
+        cls.client = cls.orchestration_client
+        cls.stack_name = data_utils.rand_name('heat')
+
+        # create the stack, avoid any duplicated key.
+        cls.stack_identifier = cls.create_stack(
+            cls.stack_name,
+            cls.template,
+            parameters={
+                'KeyPairName1': cls.stack_name + '_1',
+                'KeyPairName2': cls.stack_name + '_2'
+            })
+
+        cls.stack_id = cls.stack_identifier.split('/')[1]
+        cls.client.wait_for_stack_status(cls.stack_id, 'CREATE_COMPLETE')
+        _, resources = cls.client.list_resources(cls.stack_identifier)
+        cls.test_resources = {}
+        for resource in resources:
+            cls.test_resources[resource['logical_resource_id']] = resource
+
+    @attr(type='slow')
+    def test_created_resources(self):
+        """Verifies created keypair resource."""
+        resources = [('KeyPairSavePrivate', 'OS::Nova::KeyPair'),
+                     ('KeyPairDontSavePrivate', 'OS::Nova::KeyPair')]
+
+        for resource_name, resource_type in resources:
+            resource = self.test_resources.get(resource_name, None)
+            self.assertIsInstance(resource, dict)
+            self.assertEqual(resource_name, resource['logical_resource_id'])
+            self.assertEqual(resource_type, resource['resource_type'])
+            self.assertEqual('CREATE_COMPLETE', resource['resource_status'])
+
+    @attr(type='slow')
+    def test_stack_keypairs_output(self):
+        resp, stack = self.client.get_stack(self.stack_name)
+        self.assertEqual('200', resp['status'])
+        self.assertIsInstance(stack, dict)
+
+        output_map = {}
+        for outputs in stack['outputs']:
+            output_map[outputs['output_key']] = outputs['output_value']
+        #Test that first key generated public and private keys
+        self.assertTrue('KeyPair_PublicKey' in output_map)
+        self.assertTrue("Generated by" in output_map['KeyPair_PublicKey'])
+        self.assertTrue('KeyPair_PrivateKey' in output_map)
+        self.assertTrue('-----BEGIN' in output_map['KeyPair_PrivateKey'])
+        #Test that second key generated public key, and private key is not
+        #in the output due to save_private_key = false
+        self.assertTrue('KeyPairDontSavePrivate_PublicKey' in output_map)
+        self.assertTrue('Generated by' in
+                        output_map['KeyPairDontSavePrivate_PublicKey'])
+        self.assertTrue(u'KeyPairDontSavePrivate_PrivateKey' in output_map)
+        private_key = output_map['KeyPairDontSavePrivate_PrivateKey']
+        self.assertTrue(len(private_key) == 0)
+
+
+class NovaKeyPairResourcesAWSTest(NovaKeyPairResourcesYAMLTest):
+    template = """
+{
+  "AWSTemplateFormatVersion" : "2010-09-09",
+  "Description" : "Template which create two key pairs.",
+  "Parameters" : {
+    "KeyPairName1": {
+      "Type": "String",
+      "Default": "testkey1"
+      },
+    "KeyPairName2": {
+      "Type": "String",
+      "Default": "testkey2"
+      }
+   },
+   "Resources" : {
+     "KeyPairSavePrivate": {
+       "Type": "OS::Nova::KeyPair",
+       "Properties": {
+         "name" : { "Ref" : "KeyPairName1" },
+         "save_private_key": true
+       }
+     },
+     "KeyPairDontSavePrivate": {
+       "Type": "OS::Nova::KeyPair",
+       "Properties": {
+         "name" : { "Ref" : "KeyPairName2" },
+         "save_private_key": false
+      }
+     }
+  },
+ "Outputs": {
+   "KeyPair_PublicKey": {
+     "Description": "Public Key of generated keypair.",
+     "Value": { "Fn::GetAtt" : ["KeyPairSavePrivate", "public_key"] }
+    },
+   "KeyPair_PrivateKey": {
+     "Description": "Private Key of generated keypair.",
+     "Value": { "Fn::GetAtt" : ["KeyPairSavePrivate", "private_key"] }
+   },
+   "KeyPairDontSavePrivate_PublicKey": {
+     "Description": "Public Key of generated keypair.",
+     "Value": { "Fn::GetAtt" : ["KeyPairDontSavePrivate", "public_key"] }
+   },
+  "KeyPairDontSavePrivate_PrivateKey": {
+     "Description": "Private Key of generated keypair.",
+     "Value": { "Fn::GetAtt" : ["KeyPairDontSavePrivate", "private_key"] }
+   }
+  }
+}
+"""
diff --git a/tempest/api/orchestration/stacks/test_server_cfn_init.py b/tempest/api/orchestration/stacks/test_server_cfn_init.py
index 5130f87..95deaf5 100644
--- a/tempest/api/orchestration/stacks/test_server_cfn_init.py
+++ b/tempest/api/orchestration/stacks/test_server_cfn_init.py
@@ -17,6 +17,7 @@
 from tempest.common.utils import data_utils
 from tempest.common.utils.linux import remote_client
 from tempest import config
+from tempest import exceptions
 from tempest.openstack.common import log as logging
 from tempest import test
 
@@ -66,18 +67,13 @@
               content: smoke test complete
             /etc/cfn/cfn-credentials:
               content:
-                Fn::Join:
-                - ''
-                - - AWSAccessKeyId=
-                  - {Ref: SmokeKeys}
-                  - '
-
-                    '
-                  - AWSSecretKey=
-                  - Fn::GetAtt: [SmokeKeys, SecretAccessKey]
-                  - '
-
-                    '
+                Fn::Replace:
+                - SmokeKeys: {Ref: SmokeKeys}
+                  SecretAccessKey:
+                    'Fn::GetAtt': [SmokeKeys, SecretAccessKey]
+                - |
+                  AWSAccessKeyId=SmokeKeys
+                  AWSSecretKey=SecretAccessKey
               mode: '000400'
               owner: root
               group: root
@@ -90,19 +86,13 @@
       networks:
       - uuid: {Ref: network}
       user_data:
-        Fn::Base64:
-          Fn::Join:
-          - ''
-          - - |-
-                #!/bin/bash -v
-                /opt/aws/bin/cfn-init
-            - |-
-                || error_exit ''Failed to run cfn-init''
-                /opt/aws/bin/cfn-signal -e 0 --data "`cat /tmp/smoke-status`" '
-            - {Ref: WaitHandle}
-            - '''
-
-              '
+        Fn::Replace:
+        - WaitHandle: {Ref: WaitHandle}
+        - |
+          #!/bin/bash -v
+          /opt/aws/bin/cfn-init
+          /opt/aws/bin/cfn-signal -e 0 --data "`cat /tmp/smoke-status`" \
+              "WaitHandle"
   WaitHandle:
     Type: AWS::CloudFormation::WaitConditionHandle
   WaitCondition:
@@ -154,8 +144,8 @@
         sid = self.stack_identifier
         rid = 'SmokeServer'
 
-        # wait for server resource create to complete.
-        self.client.wait_for_resource_status(sid, rid, 'CREATE_COMPLETE')
+        # wait for create to complete.
+        self.client.wait_for_stack_status(sid, 'CREATE_COMPLETE')
 
         resp, body = self.client.get_resource(sid, rid)
         self.assertEqual('CREATE_COMPLETE', body['resource_status'])
@@ -172,9 +162,32 @@
         linux_client.validate_authentication()
 
     @test.attr(type='slow')
-    def test_stack_wait_condition_data(self):
-
+    def test_all_resources_created(self):
         sid = self.stack_identifier
+        self.client.wait_for_resource_status(
+            sid, 'WaitHandle', 'CREATE_COMPLETE')
+        self.client.wait_for_resource_status(
+            sid, 'SmokeSecurityGroup', 'CREATE_COMPLETE')
+        self.client.wait_for_resource_status(
+            sid, 'SmokeKeys', 'CREATE_COMPLETE')
+        self.client.wait_for_resource_status(
+            sid, 'CfnUser', 'CREATE_COMPLETE')
+        self.client.wait_for_resource_status(
+            sid, 'SmokeServer', 'CREATE_COMPLETE')
+        try:
+            self.client.wait_for_resource_status(
+                sid, 'WaitCondition', 'CREATE_COMPLETE')
+        except exceptions.TimeoutException as e:
+            # attempt to log the server console to help with debugging
+            # the cause of the server not signalling the waitcondition
+            # to heat.
+            resp, body = self.client.get_resource(sid, 'SmokeServer')
+            server_id = body['physical_resource_id']
+            LOG.debug('Console output for %s', server_id)
+            resp, output = self.servers_client.get_console_output(
+                server_id, None)
+            LOG.debug(output)
+            raise e
 
         # wait for create to complete.
         self.client.wait_for_stack_status(sid, 'CREATE_COMPLETE')
diff --git a/tempest/api/orchestration/stacks/test_swift_resources.py b/tempest/api/orchestration/stacks/test_swift_resources.py
new file mode 100644
index 0000000..713cfd4
--- /dev/null
+++ b/tempest/api/orchestration/stacks/test_swift_resources.py
@@ -0,0 +1,125 @@
+# -*- coding: utf-8 -*-
+# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
+#
+# Author: Chmouel Boudjnah <chmouel@enovance.com>
+#
+# 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.orchestration import base
+from tempest import clients
+from tempest.common.utils import data_utils
+from tempest import config
+
+
+CONF = config.CONF
+
+
+class SwiftResourcesTestJSON(base.BaseOrchestrationTest):
+    _interface = 'json'
+    template = """
+heat_template_version: 2013-05-23
+description: Template which creates a Swift container resource
+
+resources:
+  SwiftContainerWebsite:
+    deletion_policy: "Delete"
+    type: OS::Swift::Container
+    properties:
+      X-Container-Read: ".r:*"
+      X-Container-Meta:
+        web-index: "index.html"
+        web-error: "error.html"
+
+  SwiftContainer:
+    type: OS::Swift::Container
+
+outputs:
+  WebsiteURL:
+    description: "URL for website hosted on S3"
+    value: { get_attr: [SwiftContainer, WebsiteURL] }
+  DomainName:
+    description: "Domain of Swift host"
+    value: { get_attr: [SwiftContainer, DomainName] }
+
+"""
+
+    @classmethod
+    def setUpClass(cls):
+        super(SwiftResourcesTestJSON, cls).setUpClass()
+        cls.client = cls.orchestration_client
+        cls.stack_name = data_utils.rand_name('heat')
+        os = clients.Manager()
+        if not CONF.service_available.swift:
+            raise cls.skipException("Swift support is required")
+        cls.account_client = os.account_client
+        cls.container_client = os.container_client
+        # create the stack
+        cls.stack_identifier = cls.create_stack(
+            cls.stack_name,
+            cls.template)
+        cls.stack_id = cls.stack_identifier.split('/')[1]
+        cls.client.wait_for_stack_status(cls.stack_id, 'CREATE_COMPLETE')
+        cls.test_resources = {}
+        _, resources = cls.client.list_resources(cls.stack_identifier)
+        for resource in resources:
+            cls.test_resources[resource['logical_resource_id']] = resource
+
+    def test_created_resources(self):
+        """Created stack should be on the list of existing stacks."""
+        resources = [('SwiftContainer', 'OS::Swift::Container'),
+                     ('SwiftContainerWebsite', 'OS::Swift::Container')]
+        for resource_name, resource_type in resources:
+            resource = self.test_resources.get(resource_name)
+            self.assertIsInstance(resource, dict)
+            self.assertEqual(resource_type, resource['resource_type'])
+            self.assertEqual(resource_name, resource['logical_resource_id'])
+            self.assertEqual('CREATE_COMPLETE', resource['resource_status'])
+
+    def test_created_containers(self):
+        params = {'format': 'json'}
+        resp, container_list = \
+            self.account_client.list_account_containers(params=params)
+        self.assertEqual('200', resp['status'])
+        self.assertEqual(2, len(container_list))
+        for cont in container_list:
+            self.assertTrue(cont['name'].startswith(self.stack_name))
+
+    def test_acl(self):
+        acl_headers = ('x-container-meta-web-index', 'x-container-read')
+
+        swcont = self.test_resources.get(
+            'SwiftContainer')['physical_resource_id']
+        swcont_website = self.test_resources.get(
+            'SwiftContainerWebsite')['physical_resource_id']
+
+        headers, _ = self.container_client.list_container_metadata(swcont)
+        for h in acl_headers:
+            self.assertNotIn(h, headers)
+        headers, _ = self.container_client.list_container_metadata(
+            swcont_website)
+        for h in acl_headers:
+            self.assertIn(h, headers)
+
+    def test_metadata(self):
+        metadatas = {
+            "web-index": "index.html",
+            "web-error": "error.html"
+        }
+        swcont_website = self.test_resources.get(
+            'SwiftContainerWebsite')['physical_resource_id']
+        headers, _ = self.container_client.list_container_metadata(
+            swcont_website)
+
+        for meta in metadatas:
+            header_meta = "x-container-meta-%s" % meta
+            self.assertIn(header_meta, headers)
+            self.assertEqual(headers[header_meta], metadatas[meta])
diff --git a/tempest/api/queuing/__init__.py b/tempest/api/queuing/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/api/queuing/__init__.py
diff --git a/tempest/api/queuing/base.py b/tempest/api/queuing/base.py
new file mode 100644
index 0000000..5656850
--- /dev/null
+++ b/tempest/api/queuing/base.py
@@ -0,0 +1,49 @@
+# Copyright (c) 2014 Rackspace, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from tempest import config
+from tempest.openstack.common import log as logging
+from tempest import test
+
+CONF = config.CONF
+
+LOG = logging.getLogger(__name__)
+
+
+class BaseQueuingTest(test.BaseTestCase):
+
+    """
+    Base class for the Queuing tests that use the Tempest Marconi REST client
+
+    It is assumed that the following option is defined in the
+    [service_available] section of etc/tempest.conf
+
+        queuing as True
+    """
+
+    @classmethod
+    def setUpClass(cls):
+        super(BaseQueuingTest, cls).setUpClass()
+        if not CONF.service_available.marconi:
+            raise cls.skipException("Marconi support is required")
+        os = cls.get_client_manager()
+        cls.queuing_cfg = CONF.queuing
+        cls.client = os.queuing_client
+
+    @classmethod
+    def create_queue(cls, queue_name):
+        """Wrapper utility that returns a test queue."""
+        resp, body = cls.client.create_queue(queue_name)
+        return resp, body
diff --git a/tempest/api/queuing/test_queues.py b/tempest/api/queuing/test_queues.py
new file mode 100644
index 0000000..6934b46
--- /dev/null
+++ b/tempest/api/queuing/test_queues.py
@@ -0,0 +1,37 @@
+# Copyright (c) 2014 Rackspace, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging
+
+from tempest.api.queuing import base
+from tempest.common.utils import data_utils
+from tempest import test
+
+
+LOG = logging.getLogger(__name__)
+
+
+class TestQueues(base.BaseQueuingTest):
+
+    @test.attr(type='smoke')
+    def test_create_queue(self):
+        # Create Queue
+        queue_name = data_utils.rand_name('test-')
+        resp, body = self.create_queue(queue_name)
+
+        self.addCleanup(self.client.delete_queue, queue_name)
+
+        self.assertEqual('201', resp['status'])
+        self.assertEqual('', body)
diff --git a/tempest/api/volume/admin/test_multi_backend.py b/tempest/api/volume/admin/test_multi_backend.py
index b0c878b..6178a1c 100644
--- a/tempest/api/volume/admin/test_multi_backend.py
+++ b/tempest/api/volume/admin/test_multi_backend.py
@@ -14,7 +14,7 @@
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest.openstack.common import log as logging
-from tempest.test import attr
+from tempest import test
 
 CONF = config.CONF
 
@@ -86,7 +86,7 @@
 
         super(VolumeMultiBackendTest, cls).tearDownClass()
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_backend_name_reporting(self):
         # this test checks if os-vol-attr:host is populated correctly after
         # the multi backend feature has been enabled
@@ -100,7 +100,7 @@
                self.volume1['id'])
         self.assertTrue(len(volume1_host.split("@")) > 1, msg)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_backend_name_distinction(self):
         # this test checks that the two volumes created at setUp don't
         # belong to the same backend (if they are, than the
diff --git a/tempest/api/volume/admin/test_snapshots_actions.py b/tempest/api/volume/admin/test_snapshots_actions.py
index 12fda92..e140ad0 100644
--- a/tempest/api/volume/admin/test_snapshots_actions.py
+++ b/tempest/api/volume/admin/test_snapshots_actions.py
@@ -15,7 +15,7 @@
 
 from tempest.api.volume import base
 from tempest.common.utils import data_utils
-from tempest.test import attr
+from tempest import test
 
 
 class SnapshotsActionsTest(base.BaseVolumeV1AdminTest):
@@ -80,7 +80,7 @@
     def _get_progress_alias(self):
         return 'os-extended-snapshot-attributes:progress'
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_reset_snapshot_status(self):
         # Reset snapshot status to creating
         status = 'creating'
@@ -92,7 +92,7 @@
         self.assertEqual(200, resp_get.status)
         self.assertEqual(status, snapshot_get['status'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_update_snapshot_status(self):
         # Reset snapshot status to creating
         status = 'creating'
@@ -112,22 +112,22 @@
         self.assertEqual(status, snapshot_get['status'])
         self.assertEqual(progress, snapshot_get[progress_alias])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_snapshot_force_delete_when_snapshot_is_creating(self):
         # test force delete when status of snapshot is creating
         self._create_reset_and_force_delete_temp_snapshot('creating')
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_snapshot_force_delete_when_snapshot_is_deleting(self):
         # test force delete when status of snapshot is deleting
         self._create_reset_and_force_delete_temp_snapshot('deleting')
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_snapshot_force_delete_when_snapshot_is_error(self):
         # test force delete when status of snapshot is error
         self._create_reset_and_force_delete_temp_snapshot('error')
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_snapshot_force_delete_when_snapshot_is_error_deleting(self):
         # test force delete when status of snapshot is error_deleting
         self._create_reset_and_force_delete_temp_snapshot('error_deleting')
diff --git a/tempest/api/volume/admin/test_volume_hosts.py b/tempest/api/volume/admin/test_volume_hosts.py
index 5c311e1..01ba915 100644
--- a/tempest/api/volume/admin/test_volume_hosts.py
+++ b/tempest/api/volume/admin/test_volume_hosts.py
@@ -14,13 +14,13 @@
 #    under the License.
 
 from tempest.api.volume import base
-from tempest.test import attr
+from tempest import test
 
 
 class VolumeHostsAdminTestsJSON(base.BaseVolumeV1AdminTest):
     _interface = "json"
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_hosts(self):
         resp, hosts = self.hosts_client.list_hosts()
         self.assertEqual(200, resp.status)
diff --git a/tempest/api/volume/admin/test_volume_quotas.py b/tempest/api/volume/admin/test_volume_quotas.py
new file mode 100644
index 0000000..31f6730
--- /dev/null
+++ b/tempest/api/volume/admin/test_volume_quotas.py
@@ -0,0 +1,99 @@
+# Copyright (C) 2014 eNovance SAS <licensing@enovance.com>
+#
+# Author: Sylvain Baubeau <sylvain.baubeau@enovance.com>
+#
+#    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.volume import base
+from tempest import test
+
+QUOTA_KEYS = ['gigabytes', 'snapshots', 'volumes']
+QUOTA_USAGE_KEYS = ['reserved', 'limit', 'in_use']
+
+
+class VolumeQuotasAdminTestJSON(base.BaseVolumeV1AdminTest):
+    _interface = "json"
+
+    @classmethod
+    def setUpClass(cls):
+        super(VolumeQuotasAdminTestJSON, cls).setUpClass()
+        cls.admin_volume_client = cls.os_adm.volumes_client
+        cls.demo_tenant_id = cls.isolated_creds.get_primary_user().get(
+            'tenantId')
+
+    @test.attr(type='gate')
+    def test_list_quotas(self):
+        resp, quotas = self.quotas_client.get_quota_set(self.demo_tenant_id)
+        self.assertEqual(200, resp.status)
+        for key in QUOTA_KEYS:
+            self.assertIn(key, quotas)
+
+    @test.attr(type='gate')
+    def test_list_default_quotas(self):
+        resp, quotas = self.quotas_client.get_default_quota_set(
+            self.demo_tenant_id)
+        self.assertEqual(200, resp.status)
+        for key in QUOTA_KEYS:
+            self.assertIn(key, quotas)
+
+    @test.attr(type='gate')
+    def test_update_all_quota_resources_for_tenant(self):
+        # Admin can update all the resource quota limits for a tenant
+        resp, default_quota_set = self.quotas_client.get_default_quota_set(
+            self.demo_tenant_id)
+        new_quota_set = {'gigabytes': 1009,
+                         'volumes': 11,
+                         'snapshots': 11}
+
+        # Update limits for all quota resources
+        resp, quota_set = self.quotas_client.update_quota_set(
+            self.demo_tenant_id,
+            **new_quota_set)
+
+        default_quota_set.pop('id')
+        self.addCleanup(self.quotas_client.update_quota_set,
+                        self.demo_tenant_id, **default_quota_set)
+        self.assertEqual(200, resp.status)
+        self.assertEqual(new_quota_set, quota_set)
+
+    @test.attr(type='gate')
+    def test_show_quota_usage(self):
+        resp, quota_usage = self.quotas_client.get_quota_usage(self.adm_tenant)
+        self.assertEqual(200, resp.status)
+        for key in QUOTA_KEYS:
+            self.assertIn(key, quota_usage)
+            for usage_key in QUOTA_USAGE_KEYS:
+                self.assertIn(usage_key, quota_usage[key])
+
+    @test.attr(type='gate')
+    def test_quota_usage(self):
+        resp, quota_usage = self.quotas_client.get_quota_usage(
+            self.demo_tenant_id)
+
+        volume = self.create_volume(size=1)
+        self.addCleanup(self.admin_volume_client.delete_volume,
+                        volume['id'])
+
+        resp, new_quota_usage = self.quotas_client.get_quota_usage(
+            self.demo_tenant_id)
+
+        self.assertEqual(200, resp.status)
+        self.assertEqual(quota_usage['volumes']['in_use'] + 1,
+                         new_quota_usage['volumes']['in_use'])
+
+        self.assertEqual(quota_usage['gigabytes']['in_use'] + 1,
+                         new_quota_usage['gigabytes']['in_use'])
+
+
+class VolumeQuotasAdminTestXML(VolumeQuotasAdminTestJSON):
+    _interface = "xml"
diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py
index d481251..8183999 100644
--- a/tempest/api/volume/admin/test_volume_types.py
+++ b/tempest/api/volume/admin/test_volume_types.py
@@ -16,7 +16,7 @@
 from tempest.api.volume import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest.test import attr
+from tempest import test
 
 CONF = config.CONF
 
@@ -33,14 +33,14 @@
         resp, _ = self.client.delete_volume_type(volume_type_id)
         self.assertEqual(202, resp.status)
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_volume_type_list(self):
         # List Volume types.
         resp, body = self.client.list_volume_types()
         self.assertEqual(200, resp.status)
         self.assertIsInstance(body, list)
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_create_get_delete_volume_with_volume_type_and_extra_specs(self):
         # Create/get/delete volume with volume_type and extra spec.
         volume = {}
@@ -84,7 +84,7 @@
                          'The fetched Volume is different '
                          'from the created Volume')
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_volume_type_create_get_delete(self):
         # Create/get volume type.
         body = {}
diff --git a/tempest/api/volume/admin/test_volume_types_extra_specs.py b/tempest/api/volume/admin/test_volume_types_extra_specs.py
index 99a0826..06a0b34 100644
--- a/tempest/api/volume/admin/test_volume_types_extra_specs.py
+++ b/tempest/api/volume/admin/test_volume_types_extra_specs.py
@@ -15,7 +15,7 @@
 
 from tempest.api.volume import base
 from tempest.common.utils import data_utils
-from tempest.test import attr
+from tempest import test
 
 
 class VolumeTypesExtraSpecsTest(base.BaseVolumeV1AdminTest):
@@ -32,7 +32,7 @@
         cls.client.delete_volume_type(cls.volume_type['id'])
         super(VolumeTypesExtraSpecsTest, cls).tearDownClass()
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_volume_type_extra_specs_list(self):
         # List Volume types extra specs.
         extra_specs = {"spec1": "val1"}
@@ -47,7 +47,7 @@
         self.assertIsInstance(body, dict)
         self.assertIn('spec1', body)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_type_extra_specs_update(self):
         # Update volume type extra specs
         extra_specs = {"spec2": "val1"}
@@ -67,7 +67,7 @@
         self.assertEqual(extra_spec['spec2'], body['spec2'],
                          "Volume type extra spec incorrectly updated")
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_volume_type_extra_spec_create_get_delete(self):
         # Create/Get/Delete volume type extra spec.
         extra_specs = {"spec3": "val1"}
diff --git a/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py b/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
index 5a1a2cd..d3a052e 100644
--- a/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
+++ b/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
@@ -18,7 +18,7 @@
 from tempest.api.volume import base
 from tempest.common.utils import data_utils
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class ExtraSpecsNegativeTest(base.BaseVolumeV1AdminTest):
@@ -38,7 +38,7 @@
         cls.client.delete_volume_type(cls.volume_type['id'])
         super(ExtraSpecsNegativeTest, cls).tearDownClass()
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_update_no_body(self):
         # Should not update volume type extra specs with no body
         extra_spec = {"spec1": "val2"}
@@ -46,7 +46,7 @@
                           self.client.update_volume_type_extra_specs,
                           self.volume_type['id'], extra_spec.keys()[0], None)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_update_nonexistent_extra_spec_id(self):
         # Should not update volume type extra specs with nonexistent id.
         extra_spec = {"spec1": "val2"}
@@ -55,7 +55,7 @@
                           self.volume_type['id'], str(uuid.uuid4()),
                           extra_spec)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_update_none_extra_spec_id(self):
         # Should not update volume type extra specs with none id.
         extra_spec = {"spec1": "val2"}
@@ -63,7 +63,7 @@
                           self.client.update_volume_type_extra_specs,
                           self.volume_type['id'], None, extra_spec)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_update_multiple_extra_spec(self):
         # Should not update volume type extra specs with multiple specs as
             # body.
@@ -73,7 +73,7 @@
                           self.volume_type['id'], extra_spec.keys()[0],
                           extra_spec)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_create_nonexistent_type_id(self):
         # Should not create volume type extra spec for nonexistent volume
             # type id.
@@ -82,21 +82,21 @@
                           self.client.create_volume_type_extra_specs,
                           str(uuid.uuid4()), extra_specs)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_create_none_body(self):
         # Should not create volume type extra spec for none POST body.
         self.assertRaises(exceptions.BadRequest,
                           self.client.create_volume_type_extra_specs,
                           self.volume_type['id'], None)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_create_invalid_body(self):
         # Should not create volume type extra spec for invalid POST body.
         self.assertRaises(exceptions.BadRequest,
                           self.client.create_volume_type_extra_specs,
                           self.volume_type['id'], ['invalid'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_delete_nonexistent_volume_type_id(self):
         # Should not delete volume type extra spec for nonexistent
             # type id.
@@ -105,14 +105,14 @@
                           self.client.delete_volume_type_extra_specs,
                           str(uuid.uuid4()), extra_specs.keys()[0])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_nonexistent_volume_type_id(self):
         # Should not list volume type extra spec for nonexistent type id.
         self.assertRaises(exceptions.NotFound,
                           self.client.list_volume_types_extra_specs,
                           str(uuid.uuid4()))
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_nonexistent_volume_type_id(self):
         # Should not get volume type extra spec for nonexistent type id.
         extra_specs = {"spec1": "val1"}
@@ -120,7 +120,7 @@
                           self.client.get_volume_type_extra_specs,
                           str(uuid.uuid4()), extra_specs.keys()[0])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_nonexistent_extra_spec_id(self):
         # Should not get volume type extra spec for nonexistent extra spec
             # id.
diff --git a/tempest/api/volume/admin/test_volume_types_negative.py b/tempest/api/volume/admin/test_volume_types_negative.py
index 56ad227..c18e15d 100644
--- a/tempest/api/volume/admin/test_volume_types_negative.py
+++ b/tempest/api/volume/admin/test_volume_types_negative.py
@@ -17,13 +17,13 @@
 
 from tempest.api.volume import base
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class VolumeTypesNegativeTest(base.BaseVolumeV1AdminTest):
     _interface = 'json'
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_create_with_nonexistent_volume_type(self):
         # Should not be able to create volume with nonexistent volume_type.
         self.assertRaises(exceptions.NotFound,
@@ -31,19 +31,19 @@
                           display_name=str(uuid.uuid4()),
                           volume_type=str(uuid.uuid4()))
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_create_with_empty_name(self):
         # Should not be able to create volume type with an empty name.
         self.assertRaises(exceptions.BadRequest,
                           self.client.create_volume_type, '')
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_nonexistent_type_id(self):
         # Should not be able to get volume type with nonexistent type id.
         self.assertRaises(exceptions.NotFound, self.client.get_volume_type,
                           str(uuid.uuid4()))
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_delete_nonexistent_type_id(self):
         # Should not be able to delete volume type with nonexistent type id.
         self.assertRaises(exceptions.NotFound, self.client.delete_volume_type,
diff --git a/tempest/api/volume/admin/test_volumes_actions.py b/tempest/api/volume/admin/test_volumes_actions.py
index 9274fce..aa00700 100644
--- a/tempest/api/volume/admin/test_volumes_actions.py
+++ b/tempest/api/volume/admin/test_volumes_actions.py
@@ -15,7 +15,7 @@
 
 from tempest.api.volume import base
 from tempest.common.utils import data_utils as utils
-from tempest.test import attr
+from tempest import test
 
 
 class VolumesActionsTest(base.BaseVolumeV1AdminTest):
@@ -75,7 +75,7 @@
         self.assertEqual(202, resp_delete.status)
         self.client.wait_for_resource_deletion(temp_volume['id'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_reset_status(self):
         # test volume reset status : available->error->available
         resp, body = self._reset_volume_status(self.volume['id'], 'error')
@@ -84,7 +84,7 @@
             self.volume['id'])
         self.assertEqual('error', volume_get['status'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_begin_detaching(self):
         # test volume begin detaching : available -> detaching -> available
         resp, body = self.client.volume_begin_detaching(self.volume['id'])
@@ -92,7 +92,7 @@
         resp_get, volume_get = self.client.get_volume(self.volume['id'])
         self.assertEqual('detaching', volume_get['status'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_roll_detaching(self):
         # test volume roll detaching : detaching -> in-use -> available
         resp, body = self.client.volume_begin_detaching(self.volume['id'])
@@ -110,7 +110,7 @@
         # test force delete when status of volume is attaching
         self._create_reset_and_force_delete_temp_volume('attaching')
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_force_delete_when_volume_is_error(self):
         # test force delete when status of volume is error
         self._create_reset_and_force_delete_temp_volume('error')
diff --git a/tempest/api/volume/admin/test_volumes_backup.py b/tempest/api/volume/admin/test_volumes_backup.py
index 47094f0..cd6d7a8 100644
--- a/tempest/api/volume/admin/test_volumes_backup.py
+++ b/tempest/api/volume/admin/test_volumes_backup.py
@@ -13,7 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api.volume.base import BaseVolumeV1AdminTest
+from tempest.api.volume import base
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest.openstack.common import log as logging
@@ -23,7 +23,7 @@
 LOG = logging.getLogger(__name__)
 
 
-class VolumesBackupsTest(BaseVolumeV1AdminTest):
+class VolumesBackupsTest(base.BaseVolumeV1AdminTest):
     _interface = "json"
 
     @classmethod
@@ -38,7 +38,8 @@
         cls.volume = cls.create_volume()
 
     @test.attr(type='smoke')
-    def test_volume_backup_create_get_restore_delete(self):
+    def test_volume_backup_create_get_detailed_list_restore_delete(self):
+        # Create backup
         backup_name = data_utils.rand_name('Backup')
         create_backup = self.backups_adm_client.create_backup
         resp, backup = create_backup(self.volume['id'],
@@ -46,21 +47,31 @@
         self.assertEqual(202, resp.status)
         self.addCleanup(self.backups_adm_client.delete_backup,
                         backup['id'])
-        self.assertEqual(backup['name'], backup_name)
+        self.assertEqual(backup_name, backup['name'])
         self.volumes_adm_client.wait_for_volume_status(self.volume['id'],
                                                        'available')
         self.backups_adm_client.wait_for_backup_status(backup['id'],
                                                        'available')
 
+        # Get a given backup
         resp, backup = self.backups_adm_client.get_backup(backup['id'])
         self.assertEqual(200, resp.status)
-        self.assertEqual(backup['name'], backup_name)
+        self.assertEqual(backup_name, backup['name'])
 
+        # Get all backups with detail
+        resp, backups = self.backups_adm_client.list_backups_with_detail()
+        self.assertEqual(200, resp.status)
+        self.assertIn((backup['name'], backup['id']),
+                      [(m['name'], m['id']) for m in backups])
+
+        # Restore backup
         resp, restore = self.backups_adm_client.restore_backup(backup['id'])
         self.assertEqual(202, resp.status)
+
+        # Delete backup
         self.addCleanup(self.volumes_adm_client.delete_volume,
                         restore['volume_id'])
-        self.assertEqual(restore['backup_id'], backup['id'])
+        self.assertEqual(backup['id'], restore['backup_id'])
         self.backups_adm_client.wait_for_backup_status(backup['id'],
                                                        'available')
         self.volumes_adm_client.wait_for_volume_status(restore['volume_id'],
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index 8824977..2c6050c 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -145,6 +145,7 @@
             cls.os_adm = clients.AdminManager(interface=cls._interface)
         cls.client = cls.os_adm.volume_types_client
         cls.hosts_client = cls.os_adm.volume_hosts_client
+        cls.quotas_client = cls.os_adm.volume_quotas_client
 
 
 class BaseVolumeV2Test(BaseVolumeTest):
diff --git a/tempest/api/volume/test_extensions.py b/tempest/api/volume/test_extensions.py
index cceffd6..ce019a2 100644
--- a/tempest/api/volume/test_extensions.py
+++ b/tempest/api/volume/test_extensions.py
@@ -17,7 +17,7 @@
 from tempest.api.volume import base
 from tempest import config
 from tempest.openstack.common import log as logging
-from tempest.test import attr
+from tempest import test
 
 CONF = config.CONF
 
@@ -28,7 +28,7 @@
 class ExtensionsTestJSON(base.BaseVolumeV1Test):
     _interface = 'json'
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_extensions(self):
         # List of all extensions
         resp, extensions = self.volumes_extension_client.list_extensions()
diff --git a/tempest/api/volume/test_volume_transfers.py b/tempest/api/volume/test_volume_transfers.py
index f4b2d4c..55a72c1 100644
--- a/tempest/api/volume/test_volume_transfers.py
+++ b/tempest/api/volume/test_volume_transfers.py
@@ -18,7 +18,7 @@
 from tempest.api.volume import base
 from tempest import clients
 from tempest import config
-from tempest.test import attr
+from tempest import test
 
 CONF = config.CONF
 
@@ -66,7 +66,7 @@
         self.assertEqual(202, resp.status)
         self.adm_client.wait_for_resource_deletion(volume_id)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_create_get_list_accept_volume_transfer(self):
         # Create a volume first
         volume = self.create_volume()
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index 284c321..82924a5 100644
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -18,7 +18,7 @@
 from tempest.api.volume import base
 from tempest.common.utils import data_utils
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class VolumesNegativeTest(base.BaseVolumeV1Test):
@@ -33,19 +33,19 @@
         cls.volume = cls.create_volume()
         cls.mountpoint = "/dev/vdc"
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_volume_get_nonexistent_volume_id(self):
         # Should not be able to get a non-existent volume
         self.assertRaises(exceptions.NotFound, self.client.get_volume,
                           str(uuid.uuid4()))
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_volume_delete_nonexistent_volume_id(self):
         # Should not be able to delete a non-existent Volume
         self.assertRaises(exceptions.NotFound, self.client.delete_volume,
                           str(uuid.uuid4()))
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_create_volume_with_invalid_size(self):
         # Should not be able to create volume with invalid size
         # in request
@@ -54,7 +54,7 @@
         self.assertRaises(exceptions.BadRequest, self.client.create_volume,
                           size='#$%', display_name=v_name, metadata=metadata)
 
-    @attr(type=['negative', 'gate'])
+    @test.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
@@ -63,7 +63,7 @@
         self.assertRaises(exceptions.BadRequest, self.client.create_volume,
                           size='', display_name=v_name, metadata=metadata)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_create_volume_with_size_zero(self):
         # Should not be able to create volume with size zero
         v_name = data_utils.rand_name('Volume-')
@@ -71,7 +71,7 @@
         self.assertRaises(exceptions.BadRequest, self.client.create_volume,
                           size='0', display_name=v_name, metadata=metadata)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_create_volume_with_size_negative(self):
         # Should not be able to create volume with size negative
         v_name = data_utils.rand_name('Volume-')
@@ -79,7 +79,7 @@
         self.assertRaises(exceptions.BadRequest, self.client.create_volume,
                           size='-1', display_name=v_name, metadata=metadata)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_create_volume_with_nonexistent_volume_type(self):
         # Should not be able to create volume with non-existent volume type
         v_name = data_utils.rand_name('Volume-')
@@ -88,7 +88,7 @@
                           size='1', volume_type=str(uuid.uuid4()),
                           display_name=v_name, metadata=metadata)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_create_volume_with_nonexistent_snapshot_id(self):
         # Should not be able to create volume with non-existent snapshot
         v_name = data_utils.rand_name('Volume-')
@@ -97,7 +97,7 @@
                           size='1', snapshot_id=str(uuid.uuid4()),
                           display_name=v_name, metadata=metadata)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_create_volume_with_nonexistent_source_volid(self):
         # Should not be able to create volume with non-existent source volume
         v_name = data_utils.rand_name('Volume-')
@@ -106,7 +106,7 @@
                           size='1', source_volid=str(uuid.uuid4()),
                           display_name=v_name, metadata=metadata)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_update_volume_with_nonexistent_volume_id(self):
         v_name = data_utils.rand_name('Volume-')
         metadata = {'Type': 'work'}
@@ -114,7 +114,7 @@
                           volume_id=str(uuid.uuid4()), display_name=v_name,
                           metadata=metadata)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_update_volume_with_invalid_volume_id(self):
         v_name = data_utils.rand_name('Volume-')
         metadata = {'Type': 'work'}
@@ -122,7 +122,7 @@
                           volume_id='#$%%&^&^', display_name=v_name,
                           metadata=metadata)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_update_volume_with_empty_volume_id(self):
         v_name = data_utils.rand_name('Volume-')
         metadata = {'Type': 'work'}
@@ -130,29 +130,29 @@
                           volume_id='', display_name=v_name,
                           metadata=metadata)
 
-    @attr(type=['negative', 'gate'])
+    @test.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=['negative', 'gate'])
+    @test.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=['negative', 'gate'])
+    @test.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=['negative', 'gate'])
+    @test.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, '')
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_attach_volumes_with_nonexistent_volume_id(self):
         srv_name = data_utils.rand_name('Instance-')
         resp, server = self.servers_client.create_server(srv_name,
@@ -166,60 +166,60 @@
                           server['id'],
                           self.mountpoint)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_detach_volumes_with_invalid_volume_id(self):
         self.assertRaises(exceptions.NotFound,
                           self.client.detach_volume,
                           'xxx')
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_volume_extend_with_size_smaller_than_original_size(self):
         # Extend volume with smaller size than original size.
         extend_size = 0
         self.assertRaises(exceptions.BadRequest, self.client.extend_volume,
                           self.volume['id'], extend_size)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_volume_extend_with_non_number_size(self):
         # Extend volume when size is non number.
         extend_size = 'abc'
         self.assertRaises(exceptions.BadRequest, self.client.extend_volume,
                           self.volume['id'], extend_size)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_volume_extend_with_None_size(self):
         # Extend volume with None size.
         extend_size = None
         self.assertRaises(exceptions.BadRequest, self.client.extend_volume,
                           self.volume['id'], extend_size)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_volume_extend_with_nonexistent_volume_id(self):
         # Extend volume size when volume is nonexistent.
         extend_size = int(self.volume['size']) + 1
         self.assertRaises(exceptions.NotFound, self.client.extend_volume,
                           str(uuid.uuid4()), extend_size)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_volume_extend_without_passing_volume_id(self):
         # Extend volume size when passing volume id is None.
         extend_size = int(self.volume['size']) + 1
         self.assertRaises(exceptions.NotFound, self.client.extend_volume,
                           None, extend_size)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_reserve_volume_with_nonexistent_volume_id(self):
         self.assertRaises(exceptions.NotFound,
                           self.client.reserve_volume,
                           str(uuid.uuid4()))
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_unreserve_volume_with_nonexistent_volume_id(self):
         self.assertRaises(exceptions.NotFound,
                           self.client.unreserve_volume,
                           str(uuid.uuid4()))
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_reserve_volume_with_negative_volume_status(self):
         # Mark volume as reserved.
         resp, body = self.client.reserve_volume(self.volume['id'])
@@ -232,7 +232,7 @@
         resp, body = self.client.unreserve_volume(self.volume['id'])
         self.assertEqual(202, resp.status)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_list_volumes_with_nonexistent_name(self):
         v_name = data_utils.rand_name('Volume-')
         params = {'display_name': v_name}
@@ -240,7 +240,7 @@
         self.assertEqual(200, resp.status)
         self.assertEqual(0, len(fetched_volume))
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_list_volumes_detail_with_nonexistent_name(self):
         v_name = data_utils.rand_name('Volume-')
         params = {'display_name': v_name}
@@ -248,14 +248,14 @@
         self.assertEqual(200, resp.status)
         self.assertEqual(0, len(fetched_volume))
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_list_volumes_with_invalid_status(self):
         params = {'status': 'null'}
         resp, fetched_volume = self.client.list_volumes(params)
         self.assertEqual(200, resp.status)
         self.assertEqual(0, len(fetched_volume))
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_list_volumes_detail_with_invalid_status(self):
         params = {'status': 'null'}
         resp, fetched_volume = self.client.list_volumes_with_detail(params)
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index 56915e6..2701e84 100644
--- a/tempest/api/volume/test_volumes_snapshots.py
+++ b/tempest/api/volume/test_volumes_snapshots.py
@@ -14,7 +14,7 @@
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest.openstack.common import log as logging
-from tempest.test import attr
+from tempest import test
 
 LOG = logging.getLogger(__name__)
 CONF = config.CONF
@@ -63,7 +63,7 @@
                       ('details' if with_detail else '', key)
                 self.assertEqual(params[key], snap[key], msg)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_snapshot_create_with_volume_in_use(self):
         # Create a snapshot when volume status is in-use
         # Create a test instance
@@ -89,7 +89,7 @@
         self.snapshots_client.wait_for_resource_deletion(snapshot['id'])
         self.snapshots.remove(snapshot)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_snapshot_create_get_list_update_delete(self):
         # Create a snapshot
         s_name = data_utils.rand_name('snap')
@@ -134,7 +134,7 @@
         self.snapshots_client.wait_for_resource_deletion(snapshot['id'])
         self.snapshots.remove(snapshot)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_snapshots_list_with_params(self):
         """list snapshots with params."""
         # Create a snapshot
@@ -155,7 +155,7 @@
                   'display_name': snapshot['display_name']}
         self._list_by_param_values_and_assert(params)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_snapshots_list_details_with_params(self):
         """list snapshot details with params."""
         # Create a snapshot
@@ -174,7 +174,7 @@
                   'display_name': snapshot['display_name']}
         self._list_by_param_values_and_assert(params, with_detail=True)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_from_snapshot(self):
         # Create a temporary snap using wrapper method from base, then
         # create a snap based volume, check resp code and deletes it
diff --git a/tempest/api/volume/test_volumes_snapshots_negative.py b/tempest/api/volume/test_volumes_snapshots_negative.py
index b24b597..9e47c03 100644
--- a/tempest/api/volume/test_volumes_snapshots_negative.py
+++ b/tempest/api/volume/test_volumes_snapshots_negative.py
@@ -15,13 +15,13 @@
 from tempest.api.volume import base
 from tempest.common.utils import data_utils
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class VolumesSnapshotNegativeTest(base.BaseVolumeV1Test):
     _interface = "json"
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_create_snapshot_with_nonexistent_volume_id(self):
         # Create a snapshot with nonexistent volume id
         s_name = data_utils.rand_name('snap')
@@ -29,7 +29,7 @@
                           self.snapshots_client.create_snapshot,
                           str(uuid.uuid4()), display_name=s_name)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_create_snapshot_without_passing_volume_id(self):
         # Create a snapshot without passing volume id
         s_name = data_utils.rand_name('snap')
diff --git a/tempest/api/volume/v2/test_volumes_list.py b/tempest/api/volume/v2/test_volumes_list.py
index d0e8b99..0e91371 100644
--- a/tempest/api/volume/v2/test_volumes_list.py
+++ b/tempest/api/volume/v2/test_volumes_list.py
@@ -18,8 +18,8 @@
 from tempest.api.volume import base
 from tempest.common.utils import data_utils
 from tempest.openstack.common import log as logging
-from tempest.test import attr
-from testtools.matchers import ContainsAll
+from tempest import test
+from testtools import matchers
 
 LOG = logging.getLogger(__name__)
 
@@ -116,12 +116,12 @@
                           ('details' if with_detail else '', key)
                     if key == 'metadata':
                         self.assertThat(volume[key].items(),
-                                        ContainsAll(params[key].items()),
-                                        msg)
+                                        matchers.ContainsAll(params[key]
+                                        .items()), msg)
                     else:
                         self.assertEqual(params[key], volume[key], msg)
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_volume_list(self):
         # Get a list of Volumes
         # Fetch all volumes
@@ -130,7 +130,7 @@
         self.assertVolumesIn(fetched_list, self.volume_list,
                              fields=VOLUME_FIELDS)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_list_with_details(self):
         # Get a list of Volumes with details
         # Fetch all Volumes
@@ -138,7 +138,7 @@
         self.assertEqual(200, resp.status)
         self.assertVolumesIn(fetched_list, self.volume_list)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_list_by_name(self):
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         params = {'name': volume['name']}
@@ -147,7 +147,7 @@
         self.assertEqual(1, len(fetched_vol), str(fetched_vol))
         self.assertEqual(fetched_vol[0]['name'], volume['name'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_list_details_by_name(self):
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         params = {'name': volume['name']}
@@ -156,43 +156,43 @@
         self.assertEqual(1, len(fetched_vol), str(fetched_vol))
         self.assertEqual(fetched_vol[0]['name'], volume['name'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volumes_list_by_status(self):
         params = {'status': 'available'}
         self._list_by_param_value_and_assert(params)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volumes_list_details_by_status(self):
         params = {'status': 'available'}
         self._list_by_param_value_and_assert(params, with_detail=True)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volumes_list_by_availability_zone(self):
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         zone = volume['availability_zone']
         params = {'availability_zone': zone}
         self._list_by_param_value_and_assert(params)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volumes_list_details_by_availability_zone(self):
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         zone = volume['availability_zone']
         params = {'availability_zone': zone}
         self._list_by_param_value_and_assert(params, with_detail=True)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_list_with_param_metadata(self):
         # Test to list volumes when metadata param is given
         params = {'metadata': self.metadata}
         self._list_by_param_value_and_assert(params)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_list_with_detail_param_metadata(self):
         # Test to list volumes details when metadata param is given
         params = {'metadata': self.metadata}
         self._list_by_param_value_and_assert(params, with_detail=True)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_list_param_display_name_and_status(self):
         # Test to list volume when display name and status param is given
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
@@ -200,7 +200,7 @@
                   'status': 'available'}
         self._list_by_param_value_and_assert(params, expected_list=[volume])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_list_with_detail_param_display_name_and_status(self):
         # Test to list volume when name and status param is given
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
diff --git a/tempest/auth.py b/tempest/auth.py
index e1ba13b..0e45161 100644
--- a/tempest/auth.py
+++ b/tempest/auth.py
@@ -14,11 +14,11 @@
 #    under the License.
 
 import copy
+import datetime
 import exceptions
 import re
 import urlparse
 
-from datetime import datetime
 from tempest import config
 from tempest.services.identity.json import identity_client as json_id
 from tempest.services.identity.v3.json import identity_client as json_v3id
@@ -291,9 +291,9 @@
 
     def is_expired(self, auth_data):
         _, access = auth_data
-        expiry = datetime.strptime(access['token']['expires'],
-                                   self.EXPIRY_DATE_FORMAT)
-        return expiry <= datetime.now()
+        expiry = datetime.datetime.strptime(access['token']['expires'],
+                                            self.EXPIRY_DATE_FORMAT)
+        return expiry <= datetime.datetime.now()
 
 
 class KeystoneV3AuthProvider(KeystoneAuthProvider):
@@ -382,7 +382,7 @@
             path = "/" + filters['api_version']
             noversion_path = "/".join(parts.path.split("/")[2:])
             if noversion_path != "":
-                path += noversion_path
+                path += "/" + noversion_path
             _base_url = _base_url.replace(parts.path, path)
         if filters.get('skip_path', None) is not None:
             _base_url = _base_url.replace(parts.path, "/")
@@ -391,6 +391,6 @@
 
     def is_expired(self, auth_data):
         _, access = auth_data
-        expiry = datetime.strptime(access['expires_at'],
-                                   self.EXPIRY_DATE_FORMAT)
-        return expiry <= datetime.now()
+        expiry = datetime.datetime.strptime(access['expires_at'],
+                                            self.EXPIRY_DATE_FORMAT)
+        return expiry <= datetime.datetime.now()
diff --git a/tempest/cli/simple_read_only/test_nova.py b/tempest/cli/simple_read_only/test_nova.py
index b0264d0..d0b6028 100644
--- a/tempest/cli/simple_read_only/test_nova.py
+++ b/tempest/cli/simple_read_only/test_nova.py
@@ -154,12 +154,18 @@
     def test_admin_usage_list(self):
         self.nova('usage-list')
 
+    @testtools.skipIf(not CONF.service_available.cinder,
+                      "Skipped as Cinder is not available")
     def test_admin_volume_list(self):
         self.nova('volume-list')
 
+    @testtools.skipIf(not CONF.service_available.cinder,
+                      "Skipped as Cinder is not available")
     def test_admin_volume_snapshot_list(self):
         self.nova('volume-snapshot-list')
 
+    @testtools.skipIf(not CONF.service_available.cinder,
+                      "Skipped as Cinder is not available")
     def test_admin_volume_type_list(self):
         self.nova('volume-type-list')
 
diff --git a/tempest/cli/simple_read_only/test_nova_manage.py b/tempest/cli/simple_read_only/test_nova_manage.py
index 13a1589..f1fee2e 100644
--- a/tempest/cli/simple_read_only/test_nova_manage.py
+++ b/tempest/cli/simple_read_only/test_nova_manage.py
@@ -41,6 +41,10 @@
         if not CONF.service_available.nova:
             msg = ("%s skipped as Nova is not available" % cls.__name__)
             raise cls.skipException(msg)
+        if not CONF.cli.has_manage:
+            msg = ("%s skipped as *-manage commands not available"
+                   % cls.__name__)
+            raise cls.skipException(msg)
         super(SimpleReadOnlyNovaManageTest, cls).setUpClass()
 
     def test_admin_fake_action(self):
diff --git a/tempest/clients.py b/tempest/clients.py
index 8db399a..7ebd983 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -61,6 +61,7 @@
     TenantUsagesClientJSON
 from tempest.services.compute.json.volumes_extensions_client import \
     VolumesExtensionsClientJSON
+from tempest.services.compute.v3.json.agents_client import AgentsV3ClientJSON
 from tempest.services.compute.v3.json.aggregates_client import \
     AggregatesV3ClientJSON
 from tempest.services.compute.v3.json.availability_zone_client import \
@@ -114,6 +115,8 @@
 from tempest.services.compute.xml.volumes_extensions_client import \
     VolumesExtensionsClientXML
 from tempest.services.data_processing.v1_1.client import DataProcessingClient
+from tempest.services.database.json.flavors_client import \
+    DatabaseFlavorsClientJSON
 from tempest.services.identity.json.identity_client import IdentityClientJSON
 from tempest.services.identity.json.identity_client import TokenClientJSON
 from tempest.services.identity.v3.json.credentials_client import \
@@ -150,12 +153,15 @@
     ObjectClientCustomizedHeader
 from tempest.services.orchestration.json.orchestration_client import \
     OrchestrationClient
+from tempest.services.queuing.json.queuing_client import QueuingClientJSON
 from tempest.services.telemetry.json.telemetry_client import \
     TelemetryClientJSON
 from tempest.services.telemetry.xml.telemetry_client import \
     TelemetryClientXML
 from tempest.services.volume.json.admin.volume_hosts_client import \
     VolumeHostsClientJSON
+from tempest.services.volume.json.admin.volume_quotas_client import \
+    VolumeQuotasClientJSON
 from tempest.services.volume.json.admin.volume_types_client import \
     VolumeTypesClientJSON
 from tempest.services.volume.json.backups_client import BackupsClientJSON
@@ -167,6 +173,8 @@
 from tempest.services.volume.v2.xml.volumes_client import VolumesV2ClientXML
 from tempest.services.volume.xml.admin.volume_hosts_client import \
     VolumeHostsClientXML
+from tempest.services.volume.xml.admin.volume_quotas_client import \
+    VolumeQuotasClientXML
 from tempest.services.volume.xml.admin.volume_types_client import \
     VolumeTypesClientXML
 from tempest.services.volume.xml.backups_client import BackupsClientXML
@@ -247,6 +255,8 @@
                 InstanceUsagesAuditLogClientXML(self.auth_provider)
             self.volume_hosts_client = VolumeHostsClientXML(
                 self.auth_provider)
+            self.volume_quotas_client = VolumeQuotasClientXML(
+                self.auth_provider)
             self.volumes_extension_client = VolumeExtensionClientXML(
                 self.auth_provider)
             if CONF.service_available.ceilometer:
@@ -306,6 +316,7 @@
             self.services_v3_client = ServicesV3ClientJSON(
                 self.auth_provider)
             self.service_client = ServiceClientJSON(self.auth_provider)
+            self.agents_v3_client = AgentsV3ClientJSON(self.auth_provider)
             self.aggregates_v3_client = AggregatesV3ClientJSON(
                 self.auth_provider)
             self.aggregates_client = AggregatesClientJSON(
@@ -327,9 +338,14 @@
                 InstanceUsagesAuditLogClientJSON(self.auth_provider)
             self.volume_hosts_client = VolumeHostsClientJSON(
                 self.auth_provider)
+            self.volume_quotas_client = VolumeQuotasClientJSON(
+                self.auth_provider)
             self.volumes_extension_client = VolumeExtensionClientJSON(
                 self.auth_provider)
             self.hosts_v3_client = HostsV3ClientJSON(self.auth_provider)
+            self.database_flavors_client = DatabaseFlavorsClientJSON(
+                self.auth_provider)
+            self.queuing_client = QueuingClientJSON(self.auth_provider)
             if CONF.service_available.ceilometer:
                 self.telemetry_client = TelemetryClientJSON(
                     self.auth_provider)
diff --git a/tempest/common/generate_json.py b/tempest/common/generate_json.py
deleted file mode 100644
index c8e86dc..0000000
--- a/tempest/common/generate_json.py
+++ /dev/null
@@ -1,265 +0,0 @@
-# Copyright 2014 Red Hat, Inc. & Deutsche Telekom AG
-# 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 copy
-import jsonschema
-
-from tempest.openstack.common import log as logging
-
-LOG = logging.getLogger(__name__)
-
-
-def generate_valid(schema):
-    """
-    Create a valid dictionary based on the types in a json schema.
-    """
-    LOG.debug("generate_valid: %s" % schema)
-    schema_type = schema["type"]
-    if isinstance(schema_type, list):
-        # Just choose the first one since all are valid.
-        schema_type = schema_type[0]
-    return type_map_valid[schema_type](schema)
-
-
-def generate_valid_string(schema):
-    size = schema.get("minLength", 0)
-    # TODO(dkr mko): handle format and pattern
-    return "x" * size
-
-
-def generate_valid_integer(schema):
-    # TODO(dkr mko): handle multipleOf
-    if "minimum" in schema:
-        minimum = schema["minimum"]
-        if "exclusiveMinimum" not in schema:
-            return minimum
-        else:
-            return minimum + 1
-    if "maximum" in schema:
-        maximum = schema["maximum"]
-        if "exclusiveMaximum" not in schema:
-            return maximum
-        else:
-            return maximum - 1
-    return 0
-
-
-def generate_valid_object(schema):
-    obj = {}
-    for k, v in schema["properties"].iteritems():
-        obj[k] = generate_valid(v)
-    return obj
-
-
-def generate_invalid(schema):
-    """
-    Generate an invalid json dictionary based on a schema.
-    Only one value is mis-generated for each dictionary created.
-
-    Any generator must return a list of tuples or a single tuple.
-    The values of this tuple are:
-      result[0]: Name of the test
-      result[1]: json schema for the test
-      result[2]: expected result of the test (can be None)
-    """
-    LOG.debug("generate_invalid: %s" % schema)
-    schema_type = schema["type"]
-    if isinstance(schema_type, list):
-        if "integer" in schema_type:
-            schema_type = "integer"
-        else:
-            raise Exception("non-integer list types not supported")
-    result = []
-    for generator in type_map_invalid[schema_type]:
-        ret = generator(schema)
-        if ret is not None:
-            if isinstance(ret, list):
-                result.extend(ret)
-            elif isinstance(ret, tuple):
-                result.append(ret)
-            else:
-                raise Exception("generator (%s) returns invalid result"
-                                % generator)
-    LOG.debug("result: %s" % result)
-    return result
-
-
-def _check_for_expected_result(name, schema):
-    expected_result = None
-    if "results" in schema:
-        if name in schema["results"]:
-            expected_result = schema["results"][name]
-    return expected_result
-
-
-def generator(fn):
-    """
-    Decorator for simple generators that simply return one value
-    """
-    def wrapped(schema):
-        result = fn(schema)
-        if result is not None:
-            expected_result = _check_for_expected_result(fn.__name__, schema)
-            return (fn.__name__, result, expected_result)
-        return
-    return wrapped
-
-
-@generator
-def gen_int(_):
-    return 4
-
-
-@generator
-def gen_string(_):
-    return "XXXXXX"
-
-
-def gen_none(schema):
-    # Note(mkoderer): it's not using the decorator otherwise it'd be filtered
-    expected_result = _check_for_expected_result('gen_none', schema)
-    return ('gen_none', None, expected_result)
-
-
-@generator
-def gen_str_min_length(schema):
-    min_length = schema.get("minLength", 0)
-    if min_length > 0:
-        return "x" * (min_length - 1)
-
-
-@generator
-def gen_str_max_length(schema):
-    max_length = schema.get("maxLength", -1)
-    if max_length > -1:
-        return "x" * (max_length + 1)
-
-
-@generator
-def gen_int_min(schema):
-    if "minimum" in schema:
-        minimum = schema["minimum"]
-        if "exclusiveMinimum" not in schema:
-            minimum -= 1
-        return minimum
-
-
-@generator
-def gen_int_max(schema):
-    if "maximum" in schema:
-        maximum = schema["maximum"]
-        if "exclusiveMaximum" not in schema:
-            maximum += 1
-        return maximum
-
-
-def gen_obj_remove_attr(schema):
-    invalids = []
-    valid = generate_valid(schema)
-    required = schema.get("required", [])
-    for r in required:
-        new_valid = copy.deepcopy(valid)
-        del new_valid[r]
-        invalids.append(("gen_obj_remove_attr", new_valid, None))
-    return invalids
-
-
-@generator
-def gen_obj_add_attr(schema):
-    valid = generate_valid(schema)
-    if not schema.get("additionalProperties", True):
-        new_valid = copy.deepcopy(valid)
-        new_valid["$$$$$$$$$$"] = "xxx"
-        return new_valid
-
-
-def gen_inv_prop_obj(schema):
-    LOG.debug("generate_invalid_object: %s" % schema)
-    valid = generate_valid(schema)
-    invalids = []
-    properties = schema["properties"]
-
-    for k, v in properties.iteritems():
-        for invalid in generate_invalid(v):
-            LOG.debug(v)
-            new_valid = copy.deepcopy(valid)
-            new_valid[k] = invalid[1]
-            name = "prop_%s_%s" % (k, invalid[0])
-            invalids.append((name, new_valid, invalid[2]))
-
-    LOG.debug("generate_invalid_object return: %s" % invalids)
-    return invalids
-
-
-type_map_valid = {
-    "string": generate_valid_string,
-    "integer": generate_valid_integer,
-    "object": generate_valid_object
-}
-
-type_map_invalid = {
-    "string": [
-        gen_int,
-        gen_none,
-        gen_str_min_length,
-        gen_str_max_length],
-    "integer": [
-        gen_string,
-        gen_none,
-        gen_int_min,
-        gen_int_max],
-    "object": [
-        gen_obj_remove_attr,
-        gen_obj_add_attr,
-        gen_inv_prop_obj]
-}
-
-schema = {
-    "type": "object",
-    "properties": {
-        "name": {"type": "string"},
-        "http-method": {
-            "enum": ["GET", "PUT", "HEAD",
-                     "POST", "PATCH", "DELETE", 'COPY']
-        },
-        "url": {"type": "string"},
-        "json-schema": jsonschema._utils.load_schema("draft4"),
-        "resources": {
-            "type": "array",
-            "items": {
-                "oneOf": [
-                    {"type": "string"},
-                    {
-                        "type": "object",
-                        "properties": {
-                            "name": {"type": "string"},
-                            "expected_result": {"type": "integer"}
-                        }
-                    }
-                ]
-            }
-        },
-        "results": {
-            "type": "object",
-            "properties": {}
-        }
-    },
-    "required": ["name", "http-method", "url"],
-    "additionalProperties": False,
-}
-
-
-def validate_negative_test_schema(nts):
-    jsonschema.validate(nts, schema)
diff --git a/tempest/common/generate_sample_tempest.py b/tempest/common/generate_sample_tempest.py
index e1213db..ceb3394 100644
--- a/tempest/common/generate_sample_tempest.py
+++ b/tempest/common/generate_sample_tempest.py
@@ -31,5 +31,5 @@
 
 
 if __name__ == "__main__":
-    CONF = tempest.config.TempestConfigPrivate(False)
+    tempest.config.register_opts()
     generator.generate(sys.argv[1:])
diff --git a/tempest/common/generator/__init__.py b/tempest/common/generator/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/common/generator/__init__.py
diff --git a/tempest/common/generator/base_generator.py b/tempest/common/generator/base_generator.py
new file mode 100644
index 0000000..7e7a2d6
--- /dev/null
+++ b/tempest/common/generator/base_generator.py
@@ -0,0 +1,143 @@
+# Copyright 2014 Deutsche Telekom AG
+# 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 jsonschema
+
+from tempest.openstack.common import log as logging
+
+LOG = logging.getLogger(__name__)
+
+
+def _check_for_expected_result(name, schema):
+    expected_result = None
+    if "results" in schema:
+        if name in schema["results"]:
+            expected_result = schema["results"][name]
+    return expected_result
+
+
+def generator_type(*args):
+    def wrapper(func):
+        func.types = args
+        return func
+    return wrapper
+
+
+def simple_generator(fn):
+    """
+    Decorator for simple generators that return one value
+    """
+    def wrapped(self, schema):
+        result = fn(self, schema)
+        if result is not None:
+            expected_result = _check_for_expected_result(fn.__name__, schema)
+            return (fn.__name__, result, expected_result)
+        return
+    return wrapped
+
+
+class BasicGeneratorSet(object):
+    _instance = None
+
+    schema = {
+        "type": "object",
+        "properties": {
+            "name": {"type": "string"},
+            "http-method": {
+                "enum": ["GET", "PUT", "HEAD",
+                         "POST", "PATCH", "DELETE", 'COPY']
+            },
+            "admin_client": {"type": "boolean"},
+            "url": {"type": "string"},
+            "default_result_code": {"type": "integer"},
+            "json-schema": jsonschema._utils.load_schema("draft4"),
+            "resources": {
+                "type": "array",
+                "items": {
+                    "oneOf": [
+                        {"type": "string"},
+                        {
+                            "type": "object",
+                            "properties": {
+                                "name": {"type": "string"},
+                                "expected_result": {"type": "integer"}
+                            }
+                        }
+                    ]
+                }
+            },
+            "results": {
+                "type": "object",
+                "properties": {}
+            }
+        },
+        "required": ["name", "http-method", "url"],
+        "additionalProperties": False,
+    }
+
+    def __new__(cls, *args, **kwargs):
+        if not cls._instance:
+            cls._instance = super(BasicGeneratorSet, cls).__new__(cls, *args,
+                                                                  **kwargs)
+        return cls._instance
+
+    def __init__(self):
+        self.types_dict = {}
+        for m in dir(self):
+            if callable(getattr(self, m)) and not'__' in m:
+                method = getattr(self, m)
+                if hasattr(method, "types"):
+                    for type in method.types:
+                        if type not in self.types_dict:
+                            self.types_dict[type] = []
+                        self.types_dict[type].append(method)
+
+    def validate_schema(self, schema):
+        jsonschema.validate(schema, self.schema)
+
+    def generate(self, schema):
+        """
+        Generate an json dictionary based on a schema.
+        Only one value is mis-generated for each dictionary created.
+
+        Any generator must return a list of tuples or a single tuple.
+        The values of this tuple are:
+          result[0]: Name of the test
+          result[1]: json schema for the test
+          result[2]: expected result of the test (can be None)
+        """
+        LOG.debug("generate_invalid: %s" % schema)
+        schema_type = schema["type"]
+        if isinstance(schema_type, list):
+            if "integer" in schema_type:
+                schema_type = "integer"
+            else:
+                raise Exception("non-integer list types not supported")
+        result = []
+        if schema_type not in self.types_dict:
+            raise Exception("generator (%s) doesn't support type: %s"
+                            % (self.__class__.__name__, schema_type))
+        for generator in self.types_dict[schema_type]:
+            ret = generator(schema)
+            if ret is not None:
+                if isinstance(ret, list):
+                    result.extend(ret)
+                elif isinstance(ret, tuple):
+                    result.append(ret)
+                else:
+                    raise Exception("generator (%s) returns invalid result: %s"
+                                    % (generator, ret))
+        LOG.debug("result: %s" % result)
+        return result
diff --git a/tempest/common/generator/negative_generator.py b/tempest/common/generator/negative_generator.py
new file mode 100644
index 0000000..4f3d2cd
--- /dev/null
+++ b/tempest/common/generator/negative_generator.py
@@ -0,0 +1,111 @@
+# Copyright 2014 Deutsche Telekom AG
+# 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 copy
+
+import tempest.common.generator.base_generator as base
+import tempest.common.generator.valid_generator as valid
+from tempest.openstack.common import log as logging
+
+LOG = logging.getLogger(__name__)
+
+
+class NegativeTestGenerator(base.BasicGeneratorSet):
+    @base.generator_type("string")
+    @base.simple_generator
+    def gen_int(self, _):
+        return 4
+
+    @base.generator_type("integer")
+    @base.simple_generator
+    def gen_string(self, _):
+        return "XXXXXX"
+
+    @base.generator_type("integer", "string")
+    def gen_none(self, schema):
+        # Note(mkoderer): it's not using the decorator otherwise it'd be
+        # filtered
+        expected_result = base._check_for_expected_result('gen_none', schema)
+        return ('gen_none', None, expected_result)
+
+    @base.generator_type("string")
+    @base.simple_generator
+    def gen_str_min_length(self, schema):
+        min_length = schema.get("minLength", 0)
+        if min_length > 0:
+            return "x" * (min_length - 1)
+
+    @base.generator_type("string")
+    @base.simple_generator
+    def gen_str_max_length(self, schema):
+        max_length = schema.get("maxLength", -1)
+        if max_length > -1:
+            return "x" * (max_length + 1)
+
+    @base.generator_type("integer")
+    @base.simple_generator
+    def gen_int_min(self, schema):
+        if "minimum" in schema:
+            minimum = schema["minimum"]
+            if "exclusiveMinimum" not in schema:
+                minimum -= 1
+            return minimum
+
+    @base.generator_type("integer")
+    @base.simple_generator
+    def gen_int_max(self, schema):
+        if "maximum" in schema:
+            maximum = schema["maximum"]
+            if "exclusiveMaximum" not in schema:
+                maximum += 1
+            return maximum
+
+    @base.generator_type("object")
+    def gen_obj_remove_attr(self, schema):
+        invalids = []
+        valid_schema = valid.ValidTestGenerator().generate_valid(schema)
+        required = schema.get("required", [])
+        for r in required:
+            new_valid = copy.deepcopy(valid_schema)
+            del new_valid[r]
+            invalids.append(("gen_obj_remove_attr", new_valid, None))
+        return invalids
+
+    @base.generator_type("object")
+    @base.simple_generator
+    def gen_obj_add_attr(self, schema):
+        valid_schema = valid.ValidTestGenerator().generate_valid(schema)
+        if not schema.get("additionalProperties", True):
+            new_valid = copy.deepcopy(valid_schema)
+            new_valid["$$$$$$$$$$"] = "xxx"
+            return new_valid
+
+    @base.generator_type("object")
+    def gen_inv_prop_obj(self, schema):
+        LOG.debug("generate_invalid_object: %s" % schema)
+        valid_schema = valid.ValidTestGenerator().generate_valid(schema)
+        invalids = []
+        properties = schema["properties"]
+
+        for k, v in properties.iteritems():
+            for invalid in self.generate(v):
+                LOG.debug(v)
+                new_valid = copy.deepcopy(valid_schema)
+                new_valid[k] = invalid[1]
+                name = "prop_%s_%s" % (k, invalid[0])
+                invalids.append((name, new_valid, invalid[2]))
+
+        LOG.debug("generate_invalid_object return: %s" % invalids)
+        return invalids
diff --git a/tempest/common/generator/valid_generator.py b/tempest/common/generator/valid_generator.py
new file mode 100644
index 0000000..a99bbc0
--- /dev/null
+++ b/tempest/common/generator/valid_generator.py
@@ -0,0 +1,58 @@
+# Copyright 2014 Deutsche Telekom AG
+# 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 tempest.common.generator.base_generator as base
+from tempest.openstack.common import log as logging
+
+
+LOG = logging.getLogger(__name__)
+
+
+class ValidTestGenerator(base.BasicGeneratorSet):
+    @base.generator_type("string")
+    @base.simple_generator
+    def generate_valid_string(self, schema):
+        size = schema.get("minLength", 0)
+        # TODO(dkr mko): handle format and pattern
+        return "x" * size
+
+    @base.generator_type("integer")
+    @base.simple_generator
+    def generate_valid_integer(self, schema):
+        # TODO(dkr mko): handle multipleOf
+        if "minimum" in schema:
+            minimum = schema["minimum"]
+            if "exclusiveMinimum" not in schema:
+                return minimum
+            else:
+                return minimum + 1
+        if "maximum" in schema:
+            maximum = schema["maximum"]
+            if "exclusiveMaximum" not in schema:
+                return maximum
+            else:
+                return maximum - 1
+        return 0
+
+    @base.generator_type("object")
+    @base.simple_generator
+    def generate_valid_object(self, schema):
+        obj = {}
+        for k, v in schema["properties"].iteritems():
+            obj[k] = self.generate_valid(v)
+        return obj
+
+    def generate_valid(self, schema):
+        return self.generate(schema)[0][1]
diff --git a/tempest/common/glance_http.py b/tempest/common/glance_http.py
index 4503f13..b4ba933 100644
--- a/tempest/common/glance_http.py
+++ b/tempest/common/glance_http.py
@@ -21,6 +21,7 @@
 import json
 import posixpath
 import re
+from six import moves
 import socket
 import StringIO
 import struct
@@ -264,7 +265,7 @@
 
         # Also try Subject Alternative Names for a match
         san_list = None
-        for i in xrange(x509.get_extension_count()):
+        for i in moves.xrange(x509.get_extension_count()):
             ext = x509.get_extension(i)
             if ext.get_short_name() == 'subjectAltName':
                 san_list = str(ext)
diff --git a/tempest/common/isolated_creds.py b/tempest/common/isolated_creds.py
index ac8b14f..c54a8e8 100644
--- a/tempest/common/isolated_creds.py
+++ b/tempest/common/isolated_creds.py
@@ -456,7 +456,8 @@
             port
             for port in self.ports
             if (port['network_id'] == network_id and
-                port['device_owner'] != 'network:router_interface')
+                port['device_owner'] != 'network:router_interface' and
+                port['device_owner'] != 'network:dhcp')
         ]
         for port in ports_to_delete:
             try:
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index 03dccd4..36ddb40 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -25,7 +25,7 @@
 from tempest import config
 from tempest import exceptions
 from tempest.openstack.common import log as logging
-from tempest.services.compute.xml.common import xml_to_json
+from tempest.services.compute.xml import common
 
 CONF = config.CONF
 
@@ -299,11 +299,11 @@
                 # Parse list-like xmls (users, roles, etc)
                 array = []
                 for child in element.getchildren():
-                    array.append(xml_to_json(child))
+                    array.append(common.xml_to_json(child))
                 return array
 
             # Parse one-item-like xmls (user, role, etc)
-            return xml_to_json(element)
+            return common.xml_to_json(element)
 
     def response_checker(self, method, url, headers, body, resp, resp_body):
         if (resp.status in set((204, 205, 304)) or resp.status < 200 or
@@ -409,7 +409,7 @@
         elif ctype.lower() in TXT_ENC:
             parse_resp = False
         else:
-            raise exceptions.RestClientException(str(resp.status))
+            raise exceptions.InvalidContentType(str(resp.status))
 
         if resp.status == 401 or resp.status == 403:
             raise exceptions.Unauthorized()
@@ -451,25 +451,26 @@
                     # exception.
                     raise exceptions.InvalidHTTPResponseBody(message)
                 else:
-                    # I'm seeing both computeFault
-                    # and cloudServersFault come back.
-                    # Will file a bug to fix, but leave as is for now.
-                    if 'cloudServersFault' in resp_body:
-                        message = resp_body['cloudServersFault']['message']
-                    elif 'computeFault' in resp_body:
-                        message = resp_body['computeFault']['message']
-                    elif 'error' in resp_body:  # Keystone errors
-                        message = resp_body['error']['message']
-                        raise exceptions.IdentityError(message)
-                    elif 'message' in resp_body:
-                        message = resp_body['message']
+                    if isinstance(resp_body, dict):
+                        # I'm seeing both computeFault
+                        # and cloudServersFault come back.
+                        # Will file a bug to fix, but leave as is for now.
+                        if 'cloudServersFault' in resp_body:
+                            message = resp_body['cloudServersFault']['message']
+                        elif 'computeFault' in resp_body:
+                            message = resp_body['computeFault']['message']
+                        elif 'error' in resp_body:  # Keystone errors
+                            message = resp_body['error']['message']
+                            raise exceptions.IdentityError(message)
+                        elif 'message' in resp_body:
+                            message = resp_body['message']
+                    else:
+                        message = resp_body
 
             raise exceptions.ServerFault(message)
 
         if resp.status >= 400:
-            if parse_resp:
-                resp_body = self._parse_resp(resp_body)
-            raise exceptions.RestClientException(str(resp.status))
+            raise exceptions.UnexpectedResponseCode(str(resp.status))
 
     def is_absolute_limit(self, resp, resp_body):
         if (not isinstance(resp_body, collections.Mapping) or
diff --git a/tempest/common/ssh.py b/tempest/common/ssh.py
index b6fa0a0..531887c 100644
--- a/tempest/common/ssh.py
+++ b/tempest/common/ssh.py
@@ -16,6 +16,7 @@
 
 import cStringIO
 import select
+import six
 import socket
 import time
 import warnings
@@ -39,7 +40,7 @@
         self.host = host
         self.username = username
         self.password = password
-        if isinstance(pkey, basestring):
+        if isinstance(pkey, six.string_types):
             pkey = paramiko.RSAKey.from_private_key(
                 cStringIO.StringIO(str(pkey)))
         self.pkey = pkey
diff --git a/tempest/common/utils/data_utils.py b/tempest/common/utils/data_utils.py
index cd32720..a0a88dd 100644
--- a/tempest/common/utils/data_utils.py
+++ b/tempest/common/utils/data_utils.py
@@ -15,12 +15,8 @@
 
 import itertools
 import random
-import re
-import urllib
 import uuid
 
-from tempest import exceptions
-
 
 def rand_uuid():
     return str(uuid.uuid4())
@@ -57,37 +53,6 @@
     return ':'.join(["%02x" % x for x in mac])
 
 
-def build_url(host, port, api_version=None, path=None,
-              params=None, use_ssl=False):
-    """Build the request URL from given host, port, path and parameters."""
-
-    pattern = 'v\d\.\d'
-    if re.match(pattern, path):
-        message = 'Version should not be included in path.'
-        raise exceptions.InvalidConfiguration(message=message)
-
-    if use_ssl:
-        url = "https://" + host
-    else:
-        url = "http://" + host
-
-    if port is not None:
-        url += ":" + port
-    url += "/"
-
-    if api_version is not None:
-        url += api_version + "/"
-
-    if path is not None:
-        url += path
-
-    if params is not None:
-        url += "?"
-        url += urllib.urlencode(params)
-
-    return url
-
-
 def parse_image_id(image_ref):
     """Return the image id from a given image ref."""
     return image_ref.rsplit('/')[-1]
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index 94fc23c..00e5e0d 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -11,6 +11,7 @@
 #    under the License.
 
 import re
+import six
 import time
 
 from tempest.common import ssh
@@ -28,7 +29,7 @@
         network = CONF.compute.network_for_ssh
         ip_version = CONF.compute.ip_version_for_ssh
         ssh_channel_timeout = CONF.compute.ssh_channel_timeout
-        if isinstance(server, basestring):
+        if isinstance(server, six.string_types):
             ip_address = server
         else:
             addresses = server['addresses'][network]
@@ -42,6 +43,9 @@
                                      ssh_timeout, pkey=pkey,
                                      channel_timeout=ssh_channel_timeout)
 
+    def exec_command(self, cmd):
+        return self.ssh_client.exec_command(cmd)
+
     def validate_authentication(self):
         """Validate ssh connection and authentication
            This method raises an Exception when the validation fails.
@@ -50,33 +54,33 @@
 
     def hostname_equals_servername(self, expected_hostname):
         # Get host name using command "hostname"
-        actual_hostname = self.ssh_client.exec_command("hostname").rstrip()
+        actual_hostname = self.exec_command("hostname").rstrip()
         return expected_hostname == actual_hostname
 
     def get_files(self, path):
         # Return a list of comma separated files
         command = "ls -m " + path
-        return self.ssh_client.exec_command(command).rstrip('\n').split(', ')
+        return self.exec_command(command).rstrip('\n').split(', ')
 
     def get_ram_size_in_mb(self):
-        output = self.ssh_client.exec_command('free -m | grep Mem')
+        output = self.exec_command('free -m | grep Mem')
         if output:
             return output.split()[1]
 
     def get_number_of_vcpus(self):
         command = 'cat /proc/cpuinfo | grep processor | wc -l'
-        output = self.ssh_client.exec_command(command)
+        output = self.exec_command(command)
         return int(output)
 
     def get_partitions(self):
         # Return the contents of /proc/partitions
         command = 'cat /proc/partitions'
-        output = self.ssh_client.exec_command(command)
+        output = self.exec_command(command)
         return output
 
     def get_boot_time(self):
         cmd = 'cut -f1 -d. /proc/uptime'
-        boot_secs = self.ssh_client.exec_command(cmd)
+        boot_secs = self.exec_command(cmd)
         boot_time = time.time() - int(boot_secs)
         return time.localtime(boot_time)
 
@@ -84,12 +88,27 @@
         message = re.sub("([$\\`])", "\\\\\\\\\\1", message)
         # usually to /dev/ttyS0
         cmd = 'sudo sh -c "echo \\"%s\\" >/dev/console"' % message
-        return self.ssh_client.exec_command(cmd)
+        return self.exec_command(cmd)
 
     def ping_host(self, host):
         cmd = 'ping -c1 -w1 %s' % host
-        return self.ssh_client.exec_command(cmd)
+        return self.exec_command(cmd)
 
     def get_mac_address(self):
         cmd = "/sbin/ifconfig | awk '/HWaddr/ {print $5}'"
-        return self.ssh_client.exec_command(cmd)
+        return self.exec_command(cmd)
+
+    def get_ip_list(self):
+        cmd = "/bin/ip address"
+        return self.exec_command(cmd)
+
+    def assign_static_ip(self, nic, addr):
+        cmd = "sudo /bin/ip addr add {ip}/{mask} dev {nic}".format(
+            ip=addr, mask=CONF.network.tenant_network_mask_bits,
+            nic=nic
+        )
+        return self.exec_command(cmd)
+
+    def turn_nic_on(self, nic):
+        cmd = "sudo /bin/ip link set {nic} up".format(nic=nic)
+        return self.exec_command(cmd)
diff --git a/tempest/config.py b/tempest/config.py
index 4380608..212ee8a 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -263,7 +263,11 @@
     cfg.BoolOpt('block_migrate_cinder_iscsi',
                 default=False,
                 help="Does the test environment block migration support "
-                     "cinder iSCSI volumes")
+                     "cinder iSCSI volumes"),
+    cfg.BoolOpt('vnc_console',
+                default=False,
+                help='Enable VNC console. This configuration value should '
+                     'be same as [nova.vnc]->vnc_enabled in nova.conf')
 ]
 
 
@@ -344,9 +348,6 @@
     cfg.IntOpt('tenant_network_mask_bits',
                default=28,
                help="The mask bits for tenant ipv4 subnets"),
-    cfg.BoolOpt('ipv6_enabled',
-                default=True,
-                help="Allow the execution of IPv6 tests"),
     cfg.StrOpt('tenant_network_v6_cidr',
                default="2003::/64",
                help="The cidr block to allocate tenant ipv6 subnets from"),
@@ -365,18 +366,38 @@
                default="",
                help="Id of the public router that provides external "
                     "connectivity"),
+    cfg.IntOpt('build_timeout',
+               default=300,
+               help="Timeout in seconds to wait for network operation to "
+                    "complete."),
+    cfg.IntOpt('build_interval',
+               default=10,
+               help="Time in seconds between network operation status "
+                    "checks."),
 ]
 
 network_feature_group = cfg.OptGroup(name='network-feature-enabled',
                                      title='Enabled network service features')
 
 NetworkFeaturesGroup = [
+    cfg.BoolOpt('ipv6',
+                default=True,
+                help="Allow the execution of IPv6 tests"),
     cfg.ListOpt('api_extensions',
                 default=['all'],
                 help='A list of enabled network extensions with a special '
                      'entry all which indicates every extension is enabled'),
 ]
 
+queuing_group = cfg.OptGroup(name='queuing',
+                             title='Queuing Service')
+
+QueuingGroup = [
+    cfg.StrOpt('catalog_type',
+               default='queuing',
+               help='Catalog type of the Queuing service.'),
+]
+
 volume_group = cfg.OptGroup(name='volume',
                             title='Block Storage Options')
 
@@ -472,6 +493,9 @@
                default='Member',
                help="Role to add to users created for swift tests to "
                     "enable creating containers"),
+    cfg.StrOpt('reseller_admin_role',
+               default='ResellerAdmin',
+               help="User role that has reseller admin"),
 ]
 
 object_storage_feature_group = cfg.OptGroup(
@@ -486,6 +510,17 @@
                      "features are expected to be enabled"),
 ]
 
+database_group = cfg.OptGroup(name='database',
+                              title='Database Service Options')
+
+DatabaseGroup = [
+    cfg.StrOpt('catalog_type',
+               default='database',
+               help="Catalog type of the Database service."),
+    cfg.StrOpt('db_flavor_ref',
+               default="1",
+               help="Valid primary flavor to use in database tests."),
+]
 
 orchestration_group = cfg.OptGroup(name='orchestration',
                                    title='Orchestration Service Options')
@@ -515,7 +550,7 @@
                default=1,
                help="Time in seconds between build status checks."),
     cfg.IntOpt('build_timeout',
-               default=300,
+               default=600,
                help="Timeout in seconds to wait for a stack to build."),
     cfg.StrOpt('instance_type',
                default='m1.micro',
@@ -541,6 +576,11 @@
     cfg.StrOpt('catalog_type',
                default='metering',
                help="Catalog type of the Telemetry service."),
+    cfg.StrOpt('endpoint_type',
+               default='publicURL',
+               choices=['public', 'admin', 'internal',
+                        'publicURL', 'adminURL', 'internalURL'],
+               help="The endpoint type to use for the telemetry service."),
 ]
 
 
@@ -563,7 +603,13 @@
 DataProcessingGroup = [
     cfg.StrOpt('catalog_type',
                default='data_processing',
-               help="Catalog type of the data processing service.")
+               help="Catalog type of the data processing service."),
+    cfg.StrOpt('endpoint_type',
+               default='publicURL',
+               choices=['public', 'admin', 'internal',
+                        'publicURL', 'adminURL', 'internalURL'],
+               help="The endpoint type to use for the data processing "
+                    "service."),
 ]
 
 
@@ -721,6 +767,12 @@
     cfg.BoolOpt('ironic',
                 default=False,
                 help="Whether or not Ironic is expected to be available"),
+    cfg.BoolOpt('trove',
+                default=False,
+                help="Whether or not Trove is expected to be available"),
+    cfg.BoolOpt('marconi',
+                default=False,
+                help="Whether or not Marconi is expected to be available"),
 ]
 
 debug_group = cfg.OptGroup(name="debug",
@@ -761,6 +813,12 @@
     cfg.StrOpt('catalog_type',
                default='baremetal',
                help="Catalog type of the baremetal provisioning service."),
+    cfg.StrOpt('endpoint_type',
+               default='publicURL',
+               choices=['public', 'admin', 'internal',
+                        'publicURL', 'adminURL', 'internalURL'],
+               help="The endpoint type to use for the baremetal provisioning "
+                    "service."),
 ]
 
 cli_group = cfg.OptGroup(name='cli', title="cli Configuration Options")
@@ -772,11 +830,63 @@
     cfg.StrOpt('cli_dir',
                default='/usr/local/bin',
                help="directory where python client binaries are located"),
+    cfg.BoolOpt('has_manage',
+                default=True,
+                help=("Whether the tempest run location has access to the "
+                      "*-manage commands. In a pure blackbox environment "
+                      "it will not.")),
     cfg.IntOpt('timeout',
                default=15,
                help="Number of seconds to wait on a CLI timeout"),
 ]
 
+negative_group = cfg.OptGroup(name='negative', title="Negative Test Options")
+
+NegativeGroup = [
+    cfg.StrOpt('test_generator',
+               default='tempest.common.' +
+               'generator.negative_generator.NegativeTestGenerator',
+               help="Test generator class for all negative tests"),
+]
+
+
+def register_opts():
+    register_opt_group(cfg.CONF, compute_group, ComputeGroup)
+    register_opt_group(cfg.CONF, compute_features_group,
+                       ComputeFeaturesGroup)
+    register_opt_group(cfg.CONF, identity_group, IdentityGroup)
+    register_opt_group(cfg.CONF, identity_feature_group,
+                       IdentityFeatureGroup)
+    register_opt_group(cfg.CONF, image_group, ImageGroup)
+    register_opt_group(cfg.CONF, image_feature_group, ImageFeaturesGroup)
+    register_opt_group(cfg.CONF, network_group, NetworkGroup)
+    register_opt_group(cfg.CONF, network_feature_group,
+                       NetworkFeaturesGroup)
+    register_opt_group(cfg.CONF, queuing_group, QueuingGroup)
+    register_opt_group(cfg.CONF, volume_group, VolumeGroup)
+    register_opt_group(cfg.CONF, volume_feature_group,
+                       VolumeFeaturesGroup)
+    register_opt_group(cfg.CONF, object_storage_group, ObjectStoreGroup)
+    register_opt_group(cfg.CONF, object_storage_feature_group,
+                       ObjectStoreFeaturesGroup)
+    register_opt_group(cfg.CONF, database_group, DatabaseGroup)
+    register_opt_group(cfg.CONF, orchestration_group, OrchestrationGroup)
+    register_opt_group(cfg.CONF, telemetry_group, TelemetryGroup)
+    register_opt_group(cfg.CONF, dashboard_group, DashboardGroup)
+    register_opt_group(cfg.CONF, data_processing_group,
+                       DataProcessingGroup)
+    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)
+    register_opt_group(cfg.CONF, baremetal_group, BaremetalGroup)
+    register_opt_group(cfg.CONF, input_scenario_group, InputScenarioGroup)
+    register_opt_group(cfg.CONF, cli_group, CLIGroup)
+    register_opt_group(cfg.CONF, negative_group, NegativeGroup)
+
 
 # this should never be called outside of this class
 class TempestConfigPrivate(object):
@@ -788,6 +898,41 @@
 
     DEFAULT_CONFIG_FILE = "tempest.conf"
 
+    def _set_attrs(self):
+        self.compute = cfg.CONF.compute
+        self.compute_feature_enabled = cfg.CONF['compute-feature-enabled']
+        self.identity = cfg.CONF.identity
+        self.identity_feature_enabled = cfg.CONF['identity-feature-enabled']
+        self.image = cfg.CONF.image
+        self.image_feature_enabled = cfg.CONF['image-feature-enabled']
+        self.network = cfg.CONF.network
+        self.network_feature_enabled = cfg.CONF['network-feature-enabled']
+        self.volume = cfg.CONF.volume
+        self.volume_feature_enabled = cfg.CONF['volume-feature-enabled']
+        self.object_storage = cfg.CONF['object-storage']
+        self.object_storage_feature_enabled = cfg.CONF[
+            'object-storage-feature-enabled']
+        self.database = cfg.CONF.database
+        self.orchestration = cfg.CONF.orchestration
+        self.queuing = cfg.CONF.queuing
+        self.telemetry = cfg.CONF.telemetry
+        self.dashboard = cfg.CONF.dashboard
+        self.data_processing = cfg.CONF.data_processing
+        self.boto = cfg.CONF.boto
+        self.compute_admin = cfg.CONF['compute-admin']
+        self.stress = cfg.CONF.stress
+        self.scenario = cfg.CONF.scenario
+        self.service_available = cfg.CONF.service_available
+        self.debug = cfg.CONF.debug
+        self.baremetal = cfg.CONF.baremetal
+        self.input_scenario = cfg.CONF['input-scenario']
+        self.cli = cfg.CONF.cli
+        self.negative = cfg.CONF.negative
+        if not self.compute_admin.username:
+            self.compute_admin.username = self.identity.admin_username
+            self.compute_admin.password = self.identity.admin_password
+            self.compute_admin.tenant_name = self.identity.admin_tenant_name
+
     def __init__(self, parse_conf=True):
         """Initialize a configuration from a conf directory and conf file."""
         super(TempestConfigPrivate, self).__init__()
@@ -813,70 +958,8 @@
         logging.setup('tempest')
         LOG = logging.getLogger('tempest')
         LOG.info("Using tempest config file %s" % path)
-
-        register_opt_group(cfg.CONF, compute_group, ComputeGroup)
-        register_opt_group(cfg.CONF, compute_features_group,
-                           ComputeFeaturesGroup)
-        register_opt_group(cfg.CONF, identity_group, IdentityGroup)
-        register_opt_group(cfg.CONF, identity_feature_group,
-                           IdentityFeatureGroup)
-        register_opt_group(cfg.CONF, image_group, ImageGroup)
-        register_opt_group(cfg.CONF, image_feature_group, ImageFeaturesGroup)
-        register_opt_group(cfg.CONF, network_group, NetworkGroup)
-        register_opt_group(cfg.CONF, network_feature_group,
-                           NetworkFeaturesGroup)
-        register_opt_group(cfg.CONF, volume_group, VolumeGroup)
-        register_opt_group(cfg.CONF, volume_feature_group,
-                           VolumeFeaturesGroup)
-        register_opt_group(cfg.CONF, object_storage_group, ObjectStoreGroup)
-        register_opt_group(cfg.CONF, object_storage_feature_group,
-                           ObjectStoreFeaturesGroup)
-        register_opt_group(cfg.CONF, orchestration_group, OrchestrationGroup)
-        register_opt_group(cfg.CONF, telemetry_group, TelemetryGroup)
-        register_opt_group(cfg.CONF, dashboard_group, DashboardGroup)
-        register_opt_group(cfg.CONF, data_processing_group,
-                           DataProcessingGroup)
-        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)
-        register_opt_group(cfg.CONF, baremetal_group, BaremetalGroup)
-        register_opt_group(cfg.CONF, input_scenario_group, InputScenarioGroup)
-        register_opt_group(cfg.CONF, cli_group, CLIGroup)
-        self.compute = cfg.CONF.compute
-        self.compute_feature_enabled = cfg.CONF['compute-feature-enabled']
-        self.identity = cfg.CONF.identity
-        self.identity_feature_enabled = cfg.CONF['identity-feature-enabled']
-        self.image = cfg.CONF.image
-        self.image_feature_enabled = cfg.CONF['image-feature-enabled']
-        self.network = cfg.CONF.network
-        self.network_feature_enabled = cfg.CONF['network-feature-enabled']
-        self.volume = cfg.CONF.volume
-        self.volume_feature_enabled = cfg.CONF['volume-feature-enabled']
-        self.object_storage = cfg.CONF['object-storage']
-        self.object_storage_feature_enabled = cfg.CONF[
-            'object-storage-feature-enabled']
-        self.orchestration = cfg.CONF.orchestration
-        self.telemetry = cfg.CONF.telemetry
-        self.dashboard = cfg.CONF.dashboard
-        self.data_processing = cfg.CONF.data_processing
-        self.boto = cfg.CONF.boto
-        self.compute_admin = cfg.CONF['compute-admin']
-        self.stress = cfg.CONF.stress
-        self.scenario = cfg.CONF.scenario
-        self.service_available = cfg.CONF.service_available
-        self.debug = cfg.CONF.debug
-        self.baremetal = cfg.CONF.baremetal
-        self.input_scenario = cfg.CONF['input-scenario']
-        self.cli = cfg.CONF.cli
-        if not self.compute_admin.username:
-            self.compute_admin.username = self.identity.admin_username
-            self.compute_admin.password = self.identity.admin_password
-            self.compute_admin.tenant_name = self.identity.admin_tenant_name
-
+        register_opts()
+        self._set_attrs()
         if parse_conf:
             cfg.CONF.log_opt_values(LOG, std_logging.DEBUG)
 
diff --git a/tempest/exceptions.py b/tempest/exceptions.py
deleted file mode 100644
index ac88faa..0000000
--- a/tempest/exceptions.py
+++ /dev/null
@@ -1,187 +0,0 @@
-# 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.
-
-import testtools
-
-
-class TempestException(Exception):
-    """
-    Base Tempest Exception
-
-    To correctly use this class, inherit from it and define
-    a 'message' property. That message will get printf'd
-    with the keyword arguments provided to the constructor.
-    """
-    message = "An unknown exception occurred"
-
-    def __init__(self, *args, **kwargs):
-        super(TempestException, self).__init__()
-        try:
-            self._error_string = self.message % kwargs
-        except Exception:
-            # at least get the core message out if something happened
-            self._error_string = self.message
-        if len(args) > 0:
-            # If there is a non-kwarg parameter, assume it's the error
-            # message or reason description and tack it on to the end
-            # of the exception message
-            # Convert all arguments into their string representations...
-            args = ["%s" % arg for arg in args]
-            self._error_string = (self._error_string +
-                                  "\nDetails: %s" % '\n'.join(args))
-
-    def __str__(self):
-        return self._error_string
-
-
-class InvalidConfiguration(TempestException):
-    message = "Invalid Configuration"
-
-
-class RestClientException(TempestException,
-                          testtools.TestCase.failureException):
-    pass
-
-
-class InvalidHttpSuccessCode(RestClientException):
-    message = "The success code is different than the expected one"
-
-
-class NotFound(RestClientException):
-    message = "Object not found"
-
-
-class Unauthorized(RestClientException):
-    message = 'Unauthorized'
-
-
-class InvalidServiceTag(RestClientException):
-    message = "Invalid service tag"
-
-
-class TimeoutException(TempestException):
-    message = "Request timed out"
-
-
-class BuildErrorException(TempestException):
-    message = "Server %(server_id)s failed to build and is in ERROR status"
-
-
-class ImageKilledException(TempestException):
-    message = "Image %(image_id)s 'killed' while waiting for '%(status)s'"
-
-
-class AddImageException(TempestException):
-    message = "Image %(image_id)s failed to become ACTIVE in the allotted time"
-
-
-class EC2RegisterImageException(TempestException):
-    message = ("Image %(image_id)s failed to become 'available' "
-               "in the allotted time")
-
-
-class VolumeBuildErrorException(TempestException):
-    message = "Volume %(volume_id)s failed to build and is in ERROR status"
-
-
-class SnapshotBuildErrorException(TempestException):
-    message = "Snapshot %(snapshot_id)s failed to build and is in ERROR status"
-
-
-class VolumeBackupException(TempestException):
-    message = "Volume backup %(backup_id)s failed and is in ERROR status"
-
-
-class StackBuildErrorException(TempestException):
-    message = ("Stack %(stack_identifier)s is in %(stack_status)s status "
-               "due to '%(stack_status_reason)s'")
-
-
-class BadRequest(RestClientException):
-    message = "Bad request"
-
-
-class UnprocessableEntity(RestClientException):
-    message = "Unprocessable entity"
-
-
-class AuthenticationFailure(RestClientException):
-    message = ("Authentication with user %(user)s and password "
-               "%(password)s failed auth using tenant %(tenant)s.")
-
-
-class EndpointNotFound(TempestException):
-    message = "Endpoint not found"
-
-
-class RateLimitExceeded(TempestException):
-    message = "Rate limit exceeded"
-
-
-class OverLimit(TempestException):
-    message = "Quota exceeded"
-
-
-class ServerFault(TempestException):
-    message = "Got server fault"
-
-
-class ImageFault(TempestException):
-    message = "Got image fault"
-
-
-class IdentityError(TempestException):
-    message = "Got identity error"
-
-
-class Conflict(RestClientException):
-    message = "An object with that identifier already exists"
-
-
-class SSHTimeout(TempestException):
-    message = ("Connection to the %(host)s via SSH timed out.\n"
-               "User: %(user)s, Password: %(password)s")
-
-
-class SSHExecCommandFailed(TempestException):
-    """Raised when remotely executed command returns nonzero status."""
-    message = ("Command '%(command)s', exit status: %(exit_status)d, "
-               "Error:\n%(strerror)s")
-
-
-class ServerUnreachable(TempestException):
-    message = "The server is not reachable via the configured network"
-
-
-class TearDownException(TempestException):
-    message = "%(num)d cleanUp operation failed"
-
-
-class RFCViolation(RestClientException):
-    message = "RFC Violation"
-
-
-class ResponseWithNonEmptyBody(RFCViolation):
-    message = ("RFC Violation! Response with %(status)d HTTP Status Code "
-               "MUST NOT have a body")
-
-
-class ResponseWithEntity(RFCViolation):
-    message = ("RFC Violation! Response with 205 HTTP Status Code "
-               "MUST NOT have an entity")
-
-
-class InvalidHTTPResponseBody(RestClientException):
-    message = "HTTP response body is invalid json or xml"
diff --git a/tempest/exceptions/README.rst b/tempest/exceptions/README.rst
new file mode 100644
index 0000000..dbe42b2
--- /dev/null
+++ b/tempest/exceptions/README.rst
@@ -0,0 +1,27 @@
+Tempest Field Guide to Exceptions
+=================================
+
+
+What are these exceptions?
+--------------------------
+
+These exceptions are used by Tempest for covering OpenStack specific exceptional
+cases.
+
+How to add new exceptions?
+--------------------------
+
+Each exception-template for inheritance purposes should be added into 'base'
+submodule.
+All other exceptions can be added in two ways:
+- in main module
+- in submodule
+But only in one of the ways. Need to make sure, that new exception is not
+present already.
+
+How to use exceptions?
+----------------------
+
+Any exceptions from this module or its submodules should be used in appropriate
+places to handle exceptional cases.
+Classes from 'base' module should be used only for inheritance.
diff --git a/tempest/exceptions/__init__.py b/tempest/exceptions/__init__.py
new file mode 100644
index 0000000..06dee71
--- /dev/null
+++ b/tempest/exceptions/__init__.py
@@ -0,0 +1,156 @@
+# 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.exceptions import base
+
+
+class InvalidConfiguration(base.TempestException):
+    message = "Invalid Configuration"
+
+
+class InvalidHttpSuccessCode(base.RestClientException):
+    message = "The success code is different than the expected one"
+
+
+class NotFound(base.RestClientException):
+    message = "Object not found"
+
+
+class Unauthorized(base.RestClientException):
+    message = 'Unauthorized'
+
+
+class InvalidServiceTag(base.RestClientException):
+    message = "Invalid service tag"
+
+
+class TimeoutException(base.TempestException):
+    message = "Request timed out"
+
+
+class BuildErrorException(base.TempestException):
+    message = "Server %(server_id)s failed to build and is in ERROR status"
+
+
+class ImageKilledException(base.TempestException):
+    message = "Image %(image_id)s 'killed' while waiting for '%(status)s'"
+
+
+class AddImageException(base.TempestException):
+    message = "Image %(image_id)s failed to become ACTIVE in the allotted time"
+
+
+class EC2RegisterImageException(base.TempestException):
+    message = ("Image %(image_id)s failed to become 'available' "
+               "in the allotted time")
+
+
+class VolumeBuildErrorException(base.TempestException):
+    message = "Volume %(volume_id)s failed to build and is in ERROR status"
+
+
+class SnapshotBuildErrorException(base.TempestException):
+    message = "Snapshot %(snapshot_id)s failed to build and is in ERROR status"
+
+
+class VolumeBackupException(base.TempestException):
+    message = "Volume backup %(backup_id)s failed and is in ERROR status"
+
+
+class StackBuildErrorException(base.TempestException):
+    message = ("Stack %(stack_identifier)s is in %(stack_status)s status "
+               "due to '%(stack_status_reason)s'")
+
+
+class BadRequest(base.RestClientException):
+    message = "Bad request"
+
+
+class UnprocessableEntity(base.RestClientException):
+    message = "Unprocessable entity"
+
+
+class AuthenticationFailure(base.RestClientException):
+    message = ("Authentication with user %(user)s and password "
+               "%(password)s failed auth using tenant %(tenant)s.")
+
+
+class EndpointNotFound(base.TempestException):
+    message = "Endpoint not found"
+
+
+class RateLimitExceeded(base.TempestException):
+    message = "Rate limit exceeded"
+
+
+class OverLimit(base.TempestException):
+    message = "Quota exceeded"
+
+
+class ServerFault(base.TempestException):
+    message = "Got server fault"
+
+
+class ImageFault(base.TempestException):
+    message = "Got image fault"
+
+
+class IdentityError(base.TempestException):
+    message = "Got identity error"
+
+
+class Conflict(base.RestClientException):
+    message = "An object with that identifier already exists"
+
+
+class SSHTimeout(base.TempestException):
+    message = ("Connection to the %(host)s via SSH timed out.\n"
+               "User: %(user)s, Password: %(password)s")
+
+
+class SSHExecCommandFailed(base.TempestException):
+    """Raised when remotely executed command returns nonzero status."""
+    message = ("Command '%(command)s', exit status: %(exit_status)d, "
+               "Error:\n%(strerror)s")
+
+
+class ServerUnreachable(base.TempestException):
+    message = "The server is not reachable via the configured network"
+
+
+class TearDownException(base.TempestException):
+    message = "%(num)d cleanUp operation failed"
+
+
+class ResponseWithNonEmptyBody(base.RFCViolation):
+    message = ("RFC Violation! Response with %(status)d HTTP Status Code "
+               "MUST NOT have a body")
+
+
+class ResponseWithEntity(base.RFCViolation):
+    message = ("RFC Violation! Response with 205 HTTP Status Code "
+               "MUST NOT have an entity")
+
+
+class InvalidHTTPResponseBody(base.RestClientException):
+    message = "HTTP response body is invalid json or xml"
+
+
+class InvalidContentType(base.RestClientException):
+    message = "Invalid content type provided"
+
+
+class UnexpectedResponseCode(base.RestClientException):
+    message = "Unexpected response code received"
diff --git a/tempest/exceptions/base.py b/tempest/exceptions/base.py
new file mode 100644
index 0000000..b8e470e
--- /dev/null
+++ b/tempest/exceptions/base.py
@@ -0,0 +1,55 @@
+# 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.
+
+import testtools
+
+
+class TempestException(Exception):
+    """
+    Base Tempest Exception
+
+    To correctly use this class, inherit from it and define
+    a 'message' property. That message will get printf'd
+    with the keyword arguments provided to the constructor.
+    """
+    message = "An unknown exception occurred"
+
+    def __init__(self, *args, **kwargs):
+        super(TempestException, self).__init__()
+        try:
+            self._error_string = self.message % kwargs
+        except Exception:
+            # at least get the core message out if something happened
+            self._error_string = self.message
+        if len(args) > 0:
+            # If there is a non-kwarg parameter, assume it's the error
+            # message or reason description and tack it on to the end
+            # of the exception message
+            # Convert all arguments into their string representations...
+            args = ["%s" % arg for arg in args]
+            self._error_string = (self._error_string +
+                                  "\nDetails: %s" % '\n'.join(args))
+
+    def __str__(self):
+        return self._error_string
+
+
+class RestClientException(TempestException,
+                          testtools.TestCase.failureException):
+    pass
+
+
+class RFCViolation(RestClientException):
+    message = "RFC Violation"
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 56fdcc8..f06a850 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -16,6 +16,7 @@
 
 import logging
 import os
+import six
 import subprocess
 
 import netaddr
@@ -225,8 +226,9 @@
             # so case sensitive comparisons can really mess things
             # up.
             if new_status.lower() == error_status.lower():
-                message = ("%s failed to get to expected status. "
-                           "In %s state.") % (thing, new_status)
+                message = ("%s failed to get to expected status (%s). "
+                           "In %s state.") % (thing, expected_status,
+                                              new_status)
                 raise exceptions.BuildErrorException(message,
                                                      server_id=thing_id)
             elif new_status == expected_status and expected_status is not None:
@@ -370,7 +372,7 @@
         return keypair
 
     def get_remote_client(self, server_or_ip, username=None, private_key=None):
-        if isinstance(server_or_ip, basestring):
+        if isinstance(server_or_ip, six.string_types):
             ip = server_or_ip
         else:
             network_name_for_ssh = CONF.compute.network_for_ssh
@@ -511,7 +513,7 @@
         ports = self._list_ports(tenant_id=tenant_id)
         return len(ports)
 
-    def _create_subnet(self, network, namestart='subnet-smoke-'):
+    def _create_subnet(self, network, namestart='subnet-smoke-', **kwargs):
         """
         Create a subnet for the given network within the cidr block
         configured for tenant networks.
@@ -544,6 +546,7 @@
                     cidr=str_cidr,
                 ),
             )
+            body['subnet'].update(kwargs)
             try:
                 result = self.network_client.create_subnet(body=body)
                 break
@@ -605,7 +608,7 @@
         :param floating_ip: type DeletableFloatingIp
         """
         floating_ip.update(port_id=None)
-        self.assertEqual(None, floating_ip.port_id)
+        self.assertIsNone(floating_ip.port_id)
         return floating_ip
 
     def _ping_ip_address(self, ip_address, should_succeed=True):
@@ -701,6 +704,28 @@
                                                   private_key)
             linux_client.validate_authentication()
 
+    def _check_remote_connectivity(self, source, dest, should_succeed=True):
+        """
+        check ping server via source ssh connection
+
+        :param source: RemoteClient: an ssh connection from which to ping
+        :param dest: and IP to ping against
+        :param should_succeed: boolean should ping succeed or not
+        :returns: boolean -- should_succeed == ping
+        :returns: ping is false if ping failed
+        """
+        def ping_remote():
+            try:
+                source.ping_host(dest)
+            except exceptions.SSHExecCommandFailed:
+                LOG.exception('Failed to ping host via ssh connection')
+                return not should_succeed
+            return should_succeed
+
+        return tempest.test.call_until_true(ping_remote,
+                                            CONF.compute.ping_timeout,
+                                            1)
+
     def _create_security_group_nova(self, client=None,
                                     namestart='secgroup-smoke-',
                                     tenant_id=None):
diff --git a/tempest/scenario/test_load_balancer_basic.py b/tempest/scenario/test_load_balancer_basic.py
index 5bcdacd..ce2c66f 100644
--- a/tempest/scenario/test_load_balancer_basic.py
+++ b/tempest/scenario/test_load_balancer_basic.py
@@ -17,7 +17,6 @@
 import urllib
 
 from tempest.api.network import common as net_common
-from tempest.common import ssh
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest import exceptions
@@ -64,6 +63,8 @@
         cls.servers_keypairs = {}
         cls.members = []
         cls.floating_ips = {}
+        cls.server_ip = None
+        cls.vip_ip = None
         cls.port1 = 80
         cls.port2 = 88
 
@@ -76,12 +77,10 @@
         name = data_utils.rand_name("smoke_server-")
         keypair = self.create_keypair(name='keypair-%s' % name)
         security_groups = [self.security_groups[tenant_id].name]
-        net = self.list_networks(tenant_id=self.tenant_id)[0]
-        self.network = net_common.DeletableNetwork(client=self.network_client,
-                                                   **net['network'])
+        net = self._list_networks(tenant_id=self.tenant_id)[0]
         create_kwargs = {
             'nics': [
-                {'net-id': self.network.id},
+                {'net-id': net['id']},
             ],
             'key_name': keypair.name,
             'security_groups': security_groups,
@@ -89,30 +88,36 @@
         server = self.create_server(name=name,
                                     create_kwargs=create_kwargs)
         self.servers_keypairs[server] = keypair
+        if (config.network.public_network_id and not
+                config.network.tenant_networks_reachable):
+            public_network_id = config.network.public_network_id
+            floating_ip = self._create_floating_ip(
+                server, public_network_id)
+            self.floating_ips[floating_ip] = server
+            self.server_ip = floating_ip.floating_ip_address
+        else:
+            self.server_ip = server.networks[net['name']][0]
         self.assertTrue(self.servers_keypairs)
+        return server
 
-    def _start_servers(self):
+    def _start_servers(self, server):
         """
         1. SSH to the instance
-        2. Start two servers listening on ports 80 and 88 respectively
+        2. Start two http backends listening on ports 80 and 88 respectively
         """
-        for server in self.servers_keypairs.keys():
-            ssh_login = config.compute.image_ssh_user
-            private_key = self.servers_keypairs[server].private_key
-            network_name = self.network.name
 
-            ip_address = server.networks[network_name][0]
-            ssh_client = ssh.Client(ip_address, ssh_login,
-                                    pkey=private_key,
-                                    timeout=100)
-            start_server = "while true; do echo -e 'HTTP/1.0 200 OK\r\n\r\n" \
-                           "%(server)s' | sudo nc -l -p %(port)s ; done &"
-            cmd = start_server % {'server': 'server1',
-                                  'port': self.port1}
-            ssh_client.exec_command(cmd)
-            cmd = start_server % {'server': 'server2',
-                                  'port': self.port2}
-            ssh_client.exec_command(cmd)
+        private_key = self.servers_keypairs[server].private_key
+        ssh_client = self.get_remote_client(
+            server_or_ip=self.server_ip,
+            private_key=private_key).ssh_client
+        start_server = "while true; do echo -e 'HTTP/1.0 200 OK\r\n\r\n" \
+                       "%(server)s' | sudo nc -l -p %(port)s ; done &"
+        cmd = start_server % {'server': 'server1',
+                              'port': self.port1}
+        ssh_client.exec_command(cmd)
+        cmd = start_server % {'server': 'server2',
+                              'port': self.port2}
+        ssh_client.exec_command(cmd)
 
     def _check_connection(self, check_ip):
         def try_connect(ip):
@@ -135,14 +140,14 @@
         # get tenant subnet and verify there's only one
         subnet = self._list_subnets(tenant_id=self.tenant_id)[0]
         self.subnet = net_common.DeletableSubnet(client=self.network_client,
-                                                 **subnet['subnet'])
+                                                 **subnet)
         self.pool = super(TestLoadBalancerBasic, self)._create_pool(
             'ROUND_ROBIN',
             'HTTP',
             self.subnet.id)
         self.assertTrue(self.pool)
 
-    def _create_members(self, network_name, server_ids):
+    def _create_members(self, server_ids):
         """
         Create two members.
 
@@ -152,7 +157,7 @@
         servers = self.compute_client.servers.list()
         for server in servers:
             if server.id in server_ids:
-                ip = server.networks[network_name][0]
+                ip = self.server_ip
                 pool_id = self.pool.id
                 if len(set(server_ids)) == 1 or len(servers) == 1:
                     member1 = self._create_member(ip, self.port1, pool_id)
@@ -173,8 +178,7 @@
 
     def _create_load_balancer(self):
         self._create_pool()
-        self._create_members(self.network.name,
-                             [self.servers_keypairs.keys()[0].id])
+        self._create_members([self.servers_keypairs.keys()[0].id])
         subnet_id = self.subnet.id
         pool_id = self.pool.id
         self.vip = super(TestLoadBalancerBasic, self)._create_vip('HTTP', 80,
@@ -185,7 +189,13 @@
                                               net_common.DeletableVip),
                              self.vip.id,
                              expected_status='ACTIVE')
-        self._assign_floating_ip_to_vip(self.vip)
+        if (config.network.public_network_id and not
+                config.network.tenant_networks_reachable):
+            self._assign_floating_ip_to_vip(self.vip)
+            self.vip_ip = self.floating_ips[
+                self.vip.id][0]['floating_ip_address']
+        else:
+            self.vip_ip = self.vip.address
 
     def _check_load_balancing(self):
         """
@@ -195,25 +205,22 @@
            of the requests
         """
 
-        vip = self.vip
-        floating_ip_vip = self.floating_ips[vip.id][0]['floating_ip_address']
-        self._check_connection(floating_ip_vip)
+        self._check_connection(self.vip_ip)
         resp = []
         for count in range(10):
             resp.append(
                 urllib.urlopen(
-                    "http://{0}/".format(floating_ip_vip)).read())
+                    "http://{0}/".format(self.vip_ip)).read())
         self.assertEqual(set(["server1\n", "server2\n"]), set(resp))
         self.assertEqual(5, resp.count("server1\n"))
         self.assertEqual(5, resp.count("server2\n"))
 
-    @test.skip_because(bug="1277381")
     @test.attr(type='smoke')
     @test.services('compute', 'network')
     def test_load_balancer_basic(self):
         self._create_security_groups()
-        self._create_server()
-        self._start_servers()
+        server = self._create_server()
+        self._start_servers(server)
         self._create_load_balancer()
         self._check_load_balancing()
 
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 450d85e..d5ab3d3 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -15,6 +15,9 @@
 #    under the License.
 import collections
 
+import re
+
+from tempest.api.network import common as net_common
 from tempest.common import debug
 from tempest.common.utils import data_utils
 from tempest import config
@@ -36,36 +39,6 @@
     boot VM's with Neutron-managed networking, and attempts to
     verify network connectivity as follows:
 
-     * For a freshly-booted VM with an IP address ("port") on a given network:
-
-       - the Tempest host can ping the IP address.  This implies, but
-         does not guarantee (see the ssh check that follows), that the
-         VM has been assigned the correct IP address and has
-         connectivity to the Tempest host.
-
-       - the Tempest host can perform key-based authentication to an
-         ssh server hosted at the IP address.  This check guarantees
-         that the IP address is associated with the target VM.
-
-       - detach the floating-ip from the VM and verify that it becomes
-       unreachable
-
-       - associate detached floating ip to a new VM and verify connectivity.
-       VMs are created with unique keypair so connectivity also asserts that
-       floating IP is associated with the new VM instead of the old one
-
-       # TODO(mnewby) - Need to implement the following:
-       - the Tempest host can ssh into the VM via the IP address and
-         successfully execute the following:
-
-         - ping an external IP address, implying external connectivity.
-
-         - ping an external hostname, implying that dns is correctly
-           configured.
-
-         - ping an internal IP address, implying connectivity to another
-           VM on the same network.
-
      There are presumed to be two types of networks: tenant and
      public.  A tenant network may or may not be reachable from the
      Tempest host.  A public network is assumed to be reachable from
@@ -250,10 +223,150 @@
         self.floating_ip_tuple = Floating_IP_tuple(
             floating_ip, serv_dict['server'])
 
+    def _create_new_network(self):
+        self.new_net = self._create_network(self.tenant_id)
+        self.addCleanup(self.cleanup_wrapper, self.new_net)
+        self.new_subnet = self._create_subnet(
+            network=self.new_net,
+            gateway_ip=None)
+        self.addCleanup(self.cleanup_wrapper, self.new_subnet)
+
+    def _hotplug_server(self):
+        old_floating_ip, server = self.floating_ip_tuple
+        ip_address = old_floating_ip.floating_ip_address
+        private_key = self.servers[server].private_key
+        ssh_client = self.get_remote_client(ip_address,
+                                            private_key=private_key)
+        old_nic_list = self._get_server_nics(ssh_client)
+        # get a port from a list of one item
+        port_list = self._list_ports(device_id=server.id)
+        self.assertEqual(1, len(port_list))
+        old_port = port_list[0]
+        self.compute_client.servers.interface_attach(server=server,
+                                                     net_id=self.new_net.id,
+                                                     port_id=None,
+                                                     fixed_ip=None)
+        # move server to the head of the cleanup list
+        self.addCleanup(self.cleanup_wrapper, server)
+
+        def check_ports():
+            port_list = [port for port in
+                         self._list_ports(device_id=server.id)
+                         if port != old_port]
+            return len(port_list) == 1
+
+        test.call_until_true(check_ports, 60, 1)
+        new_port_list = [p for p in
+                         self._list_ports(device_id=server.id)
+                         if p != old_port]
+        self.assertEqual(1, len(new_port_list))
+        new_port = new_port_list[0]
+        new_port = net_common.DeletablePort(client=self.network_client,
+                                            **new_port)
+        new_nic_list = self._get_server_nics(ssh_client)
+        diff_list = [n for n in new_nic_list if n not in old_nic_list]
+        self.assertEqual(1, len(diff_list))
+        num, new_nic = diff_list[0]
+        ssh_client.assign_static_ip(nic=new_nic,
+                                    addr=new_port.fixed_ips[0]['ip_address'])
+        ssh_client.turn_nic_on(nic=new_nic)
+
+    def _get_server_nics(self, ssh_client):
+        reg = re.compile(r'(?P<num>\d+): (?P<nic_name>\w+):')
+        ipatxt = ssh_client.get_ip_list()
+        return reg.findall(ipatxt)
+
+    def _check_network_internal_connectivity(self, network):
+        """
+        via ssh check VM internal connectivity:
+        - ping internal gateway and DHCP port, implying in-tenant connectivity
+        pinging both, because L3 and DHCP agents might be on different nodes
+        """
+        floating_ip, server = self.floating_ip_tuple
+        # get internal ports' ips:
+        # get all network ports in the new network
+        internal_ips = (p['fixed_ips'][0]['ip_address'] for p in
+                        self._list_ports(tenant_id=server.tenant_id,
+                                         network_id=network.id)
+                        if p['device_owner'].startswith('network'))
+
+        self._check_server_connectivity(floating_ip, internal_ips)
+
+    def _check_network_external_connectivity(self):
+        """
+        ping public network default gateway to imply external connectivity
+
+        """
+        if not CONF.network.public_network_id:
+            msg = 'public network not defined.'
+            LOG.info(msg)
+            return
+
+        subnet = self.network_client.list_subnets(
+            network_id=CONF.network.public_network_id)['subnets']
+        self.assertEqual(1, len(subnet), "Found %d subnets" % len(subnet))
+
+        external_ips = [subnet[0]['gateway_ip']]
+        self._check_server_connectivity(self.floating_ip_tuple.floating_ip,
+                                        external_ips)
+
+    def _check_server_connectivity(self, floating_ip, address_list):
+        ip_address = floating_ip.floating_ip_address
+        private_key = self.servers[self.floating_ip_tuple.server].private_key
+        ssh_source = self._ssh_to_server(ip_address, private_key)
+
+        for remote_ip in address_list:
+            try:
+                self.assertTrue(self._check_remote_connectivity(ssh_source,
+                                                                remote_ip),
+                                "Timed out waiting for %s to become "
+                                "reachable" % remote_ip)
+            except Exception:
+                LOG.exception("Unable to access {dest} via ssh to "
+                              "floating-ip {src}".format(dest=remote_ip,
+                                                         src=floating_ip))
+                debug.log_ip_ns()
+                raise
+
     @test.attr(type='smoke')
     @test.services('compute', 'network')
     def test_network_basic_ops(self):
+        """
+        For a freshly-booted VM with an IP address ("port") on a given
+            network:
+
+        - the Tempest host can ping the IP address.  This implies, but
+         does not guarantee (see the ssh check that follows), that the
+         VM has been assigned the correct IP address and has
+         connectivity to the Tempest host.
+
+        - the Tempest host can perform key-based authentication to an
+         ssh server hosted at the IP address.  This check guarantees
+         that the IP address is associated with the target VM.
+
+        - the Tempest host can ssh into the VM via the IP address and
+         successfully execute the following:
+
+         - ping an external IP address, implying external connectivity.
+
+         - ping an external hostname, implying that dns is correctly
+           configured.
+
+         - ping an internal IP address, implying connectivity to another
+           VM on the same network.
+
+        - detach the floating-ip from the VM and verify that it becomes
+        unreachable
+
+        - associate detached floating ip to a new VM and verify connectivity.
+        VMs are created with unique keypair so connectivity also asserts that
+        floating IP is associated with the new VM instead of the old one
+
+
+        """
         self._check_public_network_connectivity(should_connect=True)
+        self._check_network_internal_connectivity(network=self.network)
+        self._check_network_external_connectivity()
         self._disassociate_floating_ips()
         self._check_public_network_connectivity(should_connect=False,
                                                 msg="after disassociate "
@@ -262,3 +375,20 @@
         self._check_public_network_connectivity(should_connect=True,
                                                 msg="after re-associate "
                                                     "floating ip")
+
+    @test.attr(type='smoke')
+    @test.services('compute', 'network')
+    def test_hotplug_nic(self):
+        """
+        1. create a new network, with no gateway (to prevent overwriting VM's
+            gateway)
+        2. connect VM to new network
+        3. set static ip and bring new nic up
+        4. check VM can ping new network dhcp port
+
+        """
+
+        self._check_public_network_connectivity(should_connect=True)
+        self._create_new_network()
+        self._hotplug_server()
+        self._check_network_internal_connectivity(network=self.new_net)
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 0d13108..b9ee040 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -17,7 +17,6 @@
 from tempest.common import debug
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest.openstack.common import log as logging
 from tempest.scenario import manager
 from tempest import test
@@ -332,28 +331,6 @@
                                                private_key=private_key)
         return access_point_ssh
 
-    def _test_remote_connectivity(self, source, dest, should_succeed=True):
-        """
-        check ping server via source ssh connection
-
-        :param source: RemoteClient: an ssh connection from which to ping
-        :param dest: and IP to ping against
-        :param should_succeed: boolean should ping succeed or not
-        :returns: boolean -- should_succeed == ping
-        :returns: ping is false if ping failed
-        """
-        def ping_remote():
-            try:
-                source.ping_host(dest)
-            except exceptions.SSHExecCommandFailed as ex:
-                LOG.debug(ex)
-                return not should_succeed
-            return should_succeed
-
-        return test.call_until_true(ping_remote,
-                                    CONF.compute.ping_timeout,
-                                    1)
-
     def _check_connectivity(self, access_point, ip, should_succeed=True):
         if should_succeed:
             msg = "Timed out waiting for %s to become reachable" % ip
@@ -362,8 +339,8 @@
             return True
             msg = "%s is reachable" % ip
         try:
-            self.assertTrue(self._test_remote_connectivity(access_point, ip,
-                                                           should_succeed),
+            self.assertTrue(self._check_remote_connectivity(access_point, ip,
+                                                            should_succeed),
                             msg)
         except Exception:
             debug.log_net_debug()
diff --git a/tempest/scenario/test_server_basic_ops.py b/tempest/scenario/test_server_basic_ops.py
index 1144414..d369f12 100644
--- a/tempest/scenario/test_server_basic_ops.py
+++ b/tempest/scenario/test_server_basic_ops.py
@@ -26,10 +26,6 @@
 
 LOG = logging.getLogger(__name__)
 
-# NOTE(andreaf) - nose does not honour the load_tests protocol
-# however it's test discovery regex will match anything
-# which includes _tests. So nose would require some further
-# investigation to be supported with this
 load_tests = testscenarios.load_tests_apply_scenarios
 
 
diff --git a/tempest/scenario/test_snapshot_pattern.py b/tempest/scenario/test_snapshot_pattern.py
index 37beb07..562020a 100644
--- a/tempest/scenario/test_snapshot_pattern.py
+++ b/tempest/scenario/test_snapshot_pattern.py
@@ -45,11 +45,10 @@
 
     def _ssh_to_server(self, server_or_ip):
         try:
-            linux_client = self.get_remote_client(server_or_ip)
+            return self.get_remote_client(server_or_ip)
         except Exception:
             LOG.exception()
             self._log_console_output()
-        return linux_client.ssh_client
 
     def _write_timestamp(self, server_or_ip):
         ssh_client = self._ssh_to_server(server_or_ip)
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index 841f9e1..128ec17 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -72,8 +72,7 @@
         server.add_floating_ip(floating_ip)
 
     def _ssh_to_server(self, server_or_ip):
-        linux_client = self.get_remote_client(server_or_ip)
-        return linux_client.ssh_client
+        return self.get_remote_client(server_or_ip)
 
     def _create_volume_snapshot(self, volume):
         snapshot_name = data_utils.rand_name('scenario-snapshot-')
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index 9a250d7..9803664 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -101,14 +101,13 @@
             ip = server.networks[network_name_for_ssh][0]
 
         try:
-            client = self.get_remote_client(
+            return self.get_remote_client(
                 ip,
                 private_key=keypair.private_key)
         except Exception:
             LOG.exception('ssh to server failed')
             self._log_console_output()
             raise
-        return client.ssh_client
 
     def _get_content(self, ssh_client):
         return ssh_client.exec_command('cat /tmp/text')
diff --git a/tempest/services/compute/json/aggregates_client.py b/tempest/services/compute/json/aggregates_client.py
index e26f570..700a29b 100644
--- a/tempest/services/compute/json/aggregates_client.py
+++ b/tempest/services/compute/json/aggregates_client.py
@@ -15,14 +15,14 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
 
 CONF = config.CONF
 
 
-class AggregatesClientJSON(RestClient):
+class AggregatesClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(AggregatesClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/availability_zone_client.py b/tempest/services/compute/json/availability_zone_client.py
index ea4e95e..9278d5b 100644
--- a/tempest/services/compute/json/availability_zone_client.py
+++ b/tempest/services/compute/json/availability_zone_client.py
@@ -15,13 +15,13 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class AvailabilityZoneClientJSON(RestClient):
+class AvailabilityZoneClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(AvailabilityZoneClientJSON, self).__init__(
diff --git a/tempest/services/compute/json/certificates_client.py b/tempest/services/compute/json/certificates_client.py
index de0f1a8..c05e352 100644
--- a/tempest/services/compute/json/certificates_client.py
+++ b/tempest/services/compute/json/certificates_client.py
@@ -15,13 +15,13 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class CertificatesClientJSON(RestClient):
+class CertificatesClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(CertificatesClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/extensions_client.py b/tempest/services/compute/json/extensions_client.py
index f7e2737..5ad8b98 100644
--- a/tempest/services/compute/json/extensions_client.py
+++ b/tempest/services/compute/json/extensions_client.py
@@ -15,13 +15,13 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class ExtensionsClientJSON(RestClient):
+class ExtensionsClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(ExtensionsClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/fixed_ips_client.py b/tempest/services/compute/json/fixed_ips_client.py
index af750a3..8b2c6c9 100644
--- a/tempest/services/compute/json/fixed_ips_client.py
+++ b/tempest/services/compute/json/fixed_ips_client.py
@@ -15,13 +15,13 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class FixedIPsClientJSON(RestClient):
+class FixedIPsClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(FixedIPsClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/flavors_client.py b/tempest/services/compute/json/flavors_client.py
index 289b09e..a8111af 100644
--- a/tempest/services/compute/json/flavors_client.py
+++ b/tempest/services/compute/json/flavors_client.py
@@ -16,13 +16,13 @@
 import json
 import urllib
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class FlavorsClientJSON(RestClient):
+class FlavorsClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(FlavorsClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/floating_ips_client.py b/tempest/services/compute/json/floating_ips_client.py
index 0385160..42487c3 100644
--- a/tempest/services/compute/json/floating_ips_client.py
+++ b/tempest/services/compute/json/floating_ips_client.py
@@ -16,14 +16,14 @@
 import json
 import urllib
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
 
 CONF = config.CONF
 
 
-class FloatingIPsClientJSON(RestClient):
+class FloatingIPsClientJSON(rest_client.RestClient):
     def __init__(self, auth_provider):
         super(FloatingIPsClientJSON, self).__init__(auth_provider)
         self.service = CONF.compute.catalog_type
diff --git a/tempest/services/compute/json/hosts_client.py b/tempest/services/compute/json/hosts_client.py
index d826a78..fb45997 100644
--- a/tempest/services/compute/json/hosts_client.py
+++ b/tempest/services/compute/json/hosts_client.py
@@ -15,13 +15,13 @@
 import json
 import urllib
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class HostsClientJSON(RestClient):
+class HostsClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(HostsClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/hypervisor_client.py b/tempest/services/compute/json/hypervisor_client.py
index 74844dc..c6b13b0 100644
--- a/tempest/services/compute/json/hypervisor_client.py
+++ b/tempest/services/compute/json/hypervisor_client.py
@@ -15,13 +15,13 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class HypervisorClientJSON(RestClient):
+class HypervisorClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(HypervisorClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/images_client.py b/tempest/services/compute/json/images_client.py
index b3d8c35..5a79a29 100644
--- a/tempest/services/compute/json/images_client.py
+++ b/tempest/services/compute/json/images_client.py
@@ -16,7 +16,7 @@
 import json
 import urllib
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest.common import waiters
 from tempest import config
 from tempest import exceptions
@@ -24,7 +24,7 @@
 CONF = config.CONF
 
 
-class ImagesClientJSON(RestClient):
+class ImagesClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(ImagesClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/instance_usage_audit_log_client.py b/tempest/services/compute/json/instance_usage_audit_log_client.py
index 27930f2..1f6e988 100644
--- a/tempest/services/compute/json/instance_usage_audit_log_client.py
+++ b/tempest/services/compute/json/instance_usage_audit_log_client.py
@@ -15,13 +15,13 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class InstanceUsagesAuditLogClientJSON(RestClient):
+class InstanceUsagesAuditLogClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(InstanceUsagesAuditLogClientJSON, self).__init__(
diff --git a/tempest/services/compute/json/interfaces_client.py b/tempest/services/compute/json/interfaces_client.py
index f4c4c64..9928b94 100644
--- a/tempest/services/compute/json/interfaces_client.py
+++ b/tempest/services/compute/json/interfaces_client.py
@@ -16,14 +16,14 @@
 import json
 import time
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
 
 CONF = config.CONF
 
 
-class InterfacesClientJSON(RestClient):
+class InterfacesClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(InterfacesClientJSON, self).__init__(auth_provider)
@@ -80,3 +80,25 @@
                 raise exceptions.TimeoutException(message)
 
         return resp, body
+
+    def add_fixed_ip(self, server_id, network_id):
+        """Add a fixed IP to input server instance."""
+        post_body = json.dumps({
+            'addFixedIp': {
+                'networkId': network_id
+            }
+        })
+        resp, body = self.post('servers/%s/action' % str(server_id),
+                               post_body)
+        return resp, body
+
+    def remove_fixed_ip(self, server_id, ip_address):
+        """Remove input fixed IP from input server instance."""
+        post_body = json.dumps({
+            'removeFixedIp': {
+                'address': ip_address
+            }
+        })
+        resp, body = self.post('servers/%s/action' % str(server_id),
+                               post_body)
+        return resp, body
diff --git a/tempest/services/compute/json/keypairs_client.py b/tempest/services/compute/json/keypairs_client.py
index 356c2e6..28f3c31 100644
--- a/tempest/services/compute/json/keypairs_client.py
+++ b/tempest/services/compute/json/keypairs_client.py
@@ -15,13 +15,13 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class KeyPairsClientJSON(RestClient):
+class KeyPairsClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(KeyPairsClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/limits_client.py b/tempest/services/compute/json/limits_client.py
index 765ba79..1493718 100644
--- a/tempest/services/compute/json/limits_client.py
+++ b/tempest/services/compute/json/limits_client.py
@@ -15,13 +15,13 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class LimitsClientJSON(RestClient):
+class LimitsClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(LimitsClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/quotas_client.py b/tempest/services/compute/json/quotas_client.py
index 7607cc0..459ab6d 100644
--- a/tempest/services/compute/json/quotas_client.py
+++ b/tempest/services/compute/json/quotas_client.py
@@ -15,13 +15,13 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class QuotasClientJSON(RestClient):
+class QuotasClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(QuotasClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/security_groups_client.py b/tempest/services/compute/json/security_groups_client.py
index 2cd2d2e..899d4ef 100644
--- a/tempest/services/compute/json/security_groups_client.py
+++ b/tempest/services/compute/json/security_groups_client.py
@@ -16,14 +16,14 @@
 import json
 import urllib
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
 
 CONF = config.CONF
 
 
-class SecurityGroupsClientJSON(RestClient):
+class SecurityGroupsClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(SecurityGroupsClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index 025c4e5..70d075a 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -18,7 +18,7 @@
 import time
 import urllib
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest.common import waiters
 from tempest import config
 from tempest import exceptions
@@ -26,7 +26,7 @@
 CONF = config.CONF
 
 
-class ServersClientJSON(RestClient):
+class ServersClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(ServersClientJSON, self).__init__(auth_provider)
@@ -382,6 +382,10 @@
         """Un-shelves the provided server."""
         return self.action(server_id, 'unshelve', None, **kwargs)
 
+    def shelve_offload_server(self, server_id, **kwargs):
+        """Shelve-offload the provided server."""
+        return self.action(server_id, 'shelveOffload', None, **kwargs)
+
     def get_console_output(self, server_id, length):
         return self.action(server_id, 'os-getConsoleOutput', 'output',
                            length=length)
@@ -428,3 +432,11 @@
     def restore_soft_deleted_server(self, server_id, **kwargs):
         """Restore a soft-deleted server."""
         return self.action(server_id, 'restore', None, **kwargs)
+
+    def reset_network(self, server_id, **kwargs):
+        """Resets the Network of a server"""
+        return self.action(server_id, 'resetNetwork', None, **kwargs)
+
+    def inject_network_info(self, server_id, **kwargs):
+        """Inject the Network Info into server"""
+        return self.action(server_id, 'injectNetworkInfo', None, **kwargs)
diff --git a/tempest/services/compute/json/services_client.py b/tempest/services/compute/json/services_client.py
index 8380dc2..1ab25ec 100644
--- a/tempest/services/compute/json/services_client.py
+++ b/tempest/services/compute/json/services_client.py
@@ -17,13 +17,13 @@
 import json
 import urllib
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class ServicesClientJSON(RestClient):
+class ServicesClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(ServicesClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/tenant_usages_client.py b/tempest/services/compute/json/tenant_usages_client.py
index b14fa9b..f3a67dd 100644
--- a/tempest/services/compute/json/tenant_usages_client.py
+++ b/tempest/services/compute/json/tenant_usages_client.py
@@ -16,13 +16,13 @@
 import json
 import urllib
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class TenantUsagesClientJSON(RestClient):
+class TenantUsagesClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(TenantUsagesClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/json/volumes_extensions_client.py b/tempest/services/compute/json/volumes_extensions_client.py
index 4b9dc0b..5ef11ed 100644
--- a/tempest/services/compute/json/volumes_extensions_client.py
+++ b/tempest/services/compute/json/volumes_extensions_client.py
@@ -17,14 +17,14 @@
 import time
 import urllib
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
 
 CONF = config.CONF
 
 
-class VolumesExtensionsClientJSON(RestClient):
+class VolumesExtensionsClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(VolumesExtensionsClientJSON, self).__init__(
diff --git a/tempest/services/compute/v3/json/agents_client.py b/tempest/services/compute/v3/json/agents_client.py
new file mode 100644
index 0000000..6893af2
--- /dev/null
+++ b/tempest/services/compute/v3/json/agents_client.py
@@ -0,0 +1,52 @@
+# Copyright 2014 NEC Corporation.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import json
+import urllib
+
+from tempest.common import rest_client
+from tempest import config
+
+CONF = config.CONF
+
+
+class AgentsV3ClientJSON(rest_client.RestClient):
+
+    def __init__(self, auth_provider):
+        super(AgentsV3ClientJSON, self).__init__(auth_provider)
+        self.service = CONF.compute.catalog_v3_type
+
+    def list_agents(self, params=None):
+        """List all agent builds."""
+        url = 'os-agents'
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+        resp, body = self.get(url)
+        return resp, self._parse_resp(body)
+
+    def create_agent(self, **kwargs):
+        """Create an agent build."""
+        post_body = json.dumps({'agent': kwargs})
+        resp, body = self.post('os-agents', post_body)
+        return resp, self._parse_resp(body)
+
+    def delete_agent(self, agent_id):
+        """Delete an existing agent build."""
+        return self.delete('os-agents/%s' % str(agent_id))
+
+    def update_agent(self, agent_id, **kwargs):
+        """Update an agent build."""
+        put_body = json.dumps({'agent': kwargs})
+        resp, body = self.put('os-agents/%s' % str(agent_id), put_body)
+        return resp, self._parse_resp(body)
diff --git a/tempest/services/compute/v3/json/aggregates_client.py b/tempest/services/compute/v3/json/aggregates_client.py
index 20ce87b..fddf5df 100644
--- a/tempest/services/compute/v3/json/aggregates_client.py
+++ b/tempest/services/compute/v3/json/aggregates_client.py
@@ -15,14 +15,14 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
 
 CONF = config.CONF
 
 
-class AggregatesV3ClientJSON(RestClient):
+class AggregatesV3ClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(AggregatesV3ClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/v3/json/availability_zone_client.py b/tempest/services/compute/v3/json/availability_zone_client.py
index 4a6db55..bad2de9 100644
--- a/tempest/services/compute/v3/json/availability_zone_client.py
+++ b/tempest/services/compute/v3/json/availability_zone_client.py
@@ -15,13 +15,13 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class AvailabilityZoneV3ClientJSON(RestClient):
+class AvailabilityZoneV3ClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(AvailabilityZoneV3ClientJSON, self).__init__(
diff --git a/tempest/services/compute/v3/json/certificates_client.py b/tempest/services/compute/v3/json/certificates_client.py
index 620eedf..f8beeb9 100644
--- a/tempest/services/compute/v3/json/certificates_client.py
+++ b/tempest/services/compute/v3/json/certificates_client.py
@@ -15,13 +15,13 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class CertificatesV3ClientJSON(RestClient):
+class CertificatesV3ClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(CertificatesV3ClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/v3/json/extensions_client.py b/tempest/services/compute/v3/json/extensions_client.py
index 54f0aba..46f17a4 100644
--- a/tempest/services/compute/v3/json/extensions_client.py
+++ b/tempest/services/compute/v3/json/extensions_client.py
@@ -15,13 +15,13 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class ExtensionsV3ClientJSON(RestClient):
+class ExtensionsV3ClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(ExtensionsV3ClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/v3/json/flavors_client.py b/tempest/services/compute/v3/json/flavors_client.py
index f9df2b8..656bd84 100644
--- a/tempest/services/compute/v3/json/flavors_client.py
+++ b/tempest/services/compute/v3/json/flavors_client.py
@@ -16,13 +16,13 @@
 import json
 import urllib
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class FlavorsV3ClientJSON(RestClient):
+class FlavorsV3ClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(FlavorsV3ClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/v3/json/hosts_client.py b/tempest/services/compute/v3/json/hosts_client.py
index 76af626..e27c7c6 100644
--- a/tempest/services/compute/v3/json/hosts_client.py
+++ b/tempest/services/compute/v3/json/hosts_client.py
@@ -15,13 +15,13 @@
 import json
 import urllib
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class HostsV3ClientJSON(RestClient):
+class HostsV3ClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(HostsV3ClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/v3/json/hypervisor_client.py b/tempest/services/compute/v3/json/hypervisor_client.py
index e07a1fb..30e391f 100644
--- a/tempest/services/compute/v3/json/hypervisor_client.py
+++ b/tempest/services/compute/v3/json/hypervisor_client.py
@@ -15,13 +15,13 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class HypervisorV3ClientJSON(RestClient):
+class HypervisorV3ClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(HypervisorV3ClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/v3/json/interfaces_client.py b/tempest/services/compute/v3/json/interfaces_client.py
index c167520..b45426c 100644
--- a/tempest/services/compute/v3/json/interfaces_client.py
+++ b/tempest/services/compute/v3/json/interfaces_client.py
@@ -16,14 +16,14 @@
 import json
 import time
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
 
 CONF = config.CONF
 
 
-class InterfacesV3ClientJSON(RestClient):
+class InterfacesV3ClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(InterfacesV3ClientJSON, self).__init__(auth_provider)
@@ -81,3 +81,25 @@
                 raise exceptions.TimeoutException(message)
 
         return resp, body
+
+    def add_fixed_ip(self, server_id, network_id):
+        """Add a fixed IP to input server instance."""
+        post_body = json.dumps({
+            'add_fixed_ip': {
+                'network_id': network_id
+            }
+        })
+        resp, body = self.post('servers/%s/action' % str(server_id),
+                               post_body)
+        return resp, body
+
+    def remove_fixed_ip(self, server_id, ip_address):
+        """Remove input fixed IP from input server instance."""
+        post_body = json.dumps({
+            'remove_fixed_ip': {
+                'address': ip_address
+            }
+        })
+        resp, body = self.post('servers/%s/action' % str(server_id),
+                               post_body)
+        return resp, body
diff --git a/tempest/services/compute/v3/json/keypairs_client.py b/tempest/services/compute/v3/json/keypairs_client.py
index 821b86f..9ca4885 100644
--- a/tempest/services/compute/v3/json/keypairs_client.py
+++ b/tempest/services/compute/v3/json/keypairs_client.py
@@ -15,13 +15,13 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class KeyPairsV3ClientJSON(RestClient):
+class KeyPairsV3ClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(KeyPairsV3ClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/v3/json/quotas_client.py b/tempest/services/compute/v3/json/quotas_client.py
index aa8bfaf..32e31a3 100644
--- a/tempest/services/compute/v3/json/quotas_client.py
+++ b/tempest/services/compute/v3/json/quotas_client.py
@@ -15,13 +15,13 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class QuotasV3ClientJSON(RestClient):
+class QuotasV3ClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(QuotasV3ClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/v3/json/servers_client.py b/tempest/services/compute/v3/json/servers_client.py
index 840e914..92eb09b 100644
--- a/tempest/services/compute/v3/json/servers_client.py
+++ b/tempest/services/compute/v3/json/servers_client.py
@@ -19,7 +19,7 @@
 import time
 import urllib
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest.common import waiters
 from tempest import config
 from tempest import exceptions
@@ -27,7 +27,7 @@
 CONF = config.CONF
 
 
-class ServersV3ClientJSON(RestClient):
+class ServersV3ClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(ServersV3ClientJSON, self).__init__(auth_provider)
@@ -384,6 +384,10 @@
         """Un-shelves the provided server."""
         return self.action(server_id, 'unshelve', None, **kwargs)
 
+    def shelve_offload_server(self, server_id, **kwargs):
+        """Shelve-offload the provided server."""
+        return self.action(server_id, 'shelve_offload', None, **kwargs)
+
     def get_console_output(self, server_id, length):
         return self.action(server_id, 'get_console_output', 'output',
                            length=length)
@@ -423,3 +427,23 @@
     def restore_soft_deleted_server(self, server_id, **kwargs):
         """Restore a soft-deleted server."""
         return self.action(server_id, 'restore', None, **kwargs)
+
+    def get_vnc_console(self, server_id, type):
+        """Get URL of VNC console."""
+        post_body = json.dumps({
+            "get_vnc_console": {
+                "type": type
+            }
+        })
+        resp, body = self.post('servers/%s/action' % str(server_id),
+                               post_body)
+        body = json.loads(body)
+        return resp, body['console']
+
+    def reset_network(self, server_id, **kwargs):
+        """Resets the Network of a server"""
+        return self.action(server_id, 'reset_network', None, **kwargs)
+
+    def inject_network_info(self, server_id, **kwargs):
+        """Inject the Network Info into server"""
+        return self.action(server_id, 'inject_network_info', None, **kwargs)
diff --git a/tempest/services/compute/v3/json/services_client.py b/tempest/services/compute/v3/json/services_client.py
index e20dfde..b4e65a0 100644
--- a/tempest/services/compute/v3/json/services_client.py
+++ b/tempest/services/compute/v3/json/services_client.py
@@ -17,13 +17,13 @@
 import json
 import urllib
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class ServicesV3ClientJSON(RestClient):
+class ServicesV3ClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(ServicesV3ClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/compute/xml/common.py b/tempest/services/compute/xml/common.py
index 4def19f..b29b932 100644
--- a/tempest/services/compute/xml/common.py
+++ b/tempest/services/compute/xml/common.py
@@ -18,6 +18,11 @@
 XMLNS_11 = "http://docs.openstack.org/compute/api/v1.1"
 XMLNS_V3 = "http://docs.openstack.org/compute/api/v1.1"
 
+NEUTRON_NAMESPACES = {
+    'router': "http://docs.openstack.org/ext/neutron/router/api/v1.0",
+    'provider': 'http://docs.openstack.org/ext/provider/api/v1.0',
+}
+
 
 # NOTE(danms): This is just a silly implementation to help make generating
 # XML faster for prototyping. Could be replaced with proper etree gorp
@@ -137,6 +142,9 @@
         tag = child.tag
         if tag.startswith("{"):
             ns, tag = tag.split("}", 1)
+            for key, uri in NEUTRON_NAMESPACES.iteritems():
+                if uri == ns[1:]:
+                    tag = key + ":" + tag
         if plurals is not None and tag in plurals:
                 json[tag] = parse_array(child, plurals)
         else:
diff --git a/tempest/services/compute/xml/interfaces_client.py b/tempest/services/compute/xml/interfaces_client.py
index 5df6187..8d4bfcc 100644
--- a/tempest/services/compute/xml/interfaces_client.py
+++ b/tempest/services/compute/xml/interfaces_client.py
@@ -24,6 +24,7 @@
 from tempest.services.compute.xml.common import Element
 from tempest.services.compute.xml.common import Text
 from tempest.services.compute.xml.common import xml_to_json
+from tempest.services.compute.xml.common import XMLNS_11
 
 CONF = config.CONF
 
@@ -104,3 +105,21 @@
                            (port_id, status, self.build_timeout))
                 raise exceptions.TimeoutException(message)
         return resp, body
+
+    def add_fixed_ip(self, server_id, network_id):
+        """Add a fixed IP to input server instance."""
+        post_body = Element("addFixedIp",
+                            xmlns=XMLNS_11,
+                            networkId=network_id)
+        resp, body = self.post('servers/%s/action' % str(server_id),
+                               str(Document(post_body)))
+        return resp, body
+
+    def remove_fixed_ip(self, server_id, ip_address):
+        """Remove input fixed IP from input server instance."""
+        post_body = Element("removeFixedIp",
+                            xmlns=XMLNS_11,
+                            address=ip_address)
+        resp, body = self.post('servers/%s/action' % str(server_id),
+                               str(Document(post_body)))
+        return resp, body
diff --git a/tempest/services/compute/xml/quotas_client.py b/tempest/services/compute/xml/quotas_client.py
index eb287c2..b8b759f 100644
--- a/tempest/services/compute/xml/quotas_client.py
+++ b/tempest/services/compute/xml/quotas_client.py
@@ -44,9 +44,6 @@
 
         return quota
 
-    def _parse_array(self, node):
-        return [self._format_quota(xml_to_json(x)) for x in node]
-
     def get_quota_set(self, tenant_id):
         """List the quota set for a tenant."""
 
diff --git a/tempest/services/compute/xml/servers_client.py b/tempest/services/compute/xml/servers_client.py
index da01b83..4d3646c 100644
--- a/tempest/services/compute/xml/servers_client.py
+++ b/tempest/services/compute/xml/servers_client.py
@@ -227,6 +227,10 @@
         """Un-shelves the provided server."""
         return self.action(server_id, 'unshelve', None, **kwargs)
 
+    def shelve_offload_server(self, server_id, **kwargs):
+        """Shelve-offload the provided server."""
+        return self.action(server_id, 'shelveOffload', None, **kwargs)
+
     def reset_state(self, server_id, state='error'):
         """Resets the state of a server to active/error."""
         return self.action(server_id, 'os-resetState', None, state=state)
@@ -633,3 +637,11 @@
     def restore_soft_deleted_server(self, server_id, **kwargs):
         """Restore a soft-deleted server."""
         return self.action(server_id, 'restore', None, **kwargs)
+
+    def reset_network(self, server_id, **kwargs):
+        """Resets the Network of a server"""
+        return self.action(server_id, 'resetNetwork', None, **kwargs)
+
+    def inject_network_info(self, server_id, **kwargs):
+        """Inject the Network Info into server"""
+        return self.action(server_id, 'injectNetworkInfo', None, **kwargs)
diff --git a/tempest/services/database/__init__.py b/tempest/services/database/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/services/database/__init__.py
diff --git a/tempest/services/database/json/__init__.py b/tempest/services/database/json/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/services/database/json/__init__.py
diff --git a/tempest/services/database/json/flavors_client.py b/tempest/services/database/json/flavors_client.py
new file mode 100644
index 0000000..1a8a4c1
--- /dev/null
+++ b/tempest/services/database/json/flavors_client.py
@@ -0,0 +1,39 @@
+# Copyright 2014 OpenStack Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.common import rest_client
+from tempest import config
+import urllib
+
+CONF = config.CONF
+
+
+class DatabaseFlavorsClientJSON(rest_client.RestClient):
+
+    def __init__(self, auth_provider):
+        super(DatabaseFlavorsClientJSON, self).__init__(auth_provider)
+        self.service = CONF.database.catalog_type
+
+    def list_db_flavors(self, params=None):
+        url = 'flavors'
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+
+        resp, body = self.get(url)
+        return resp, self._parse_resp(body)
+
+    def get_db_flavor_details(self, db_flavor_id):
+        resp, body = self.get("flavors/%s" % str(db_flavor_id))
+        return resp, self._parse_resp(body)
diff --git a/tempest/services/identity/json/identity_client.py b/tempest/services/identity/json/identity_client.py
index 349a9e9..9a31540 100644
--- a/tempest/services/identity/json/identity_client.py
+++ b/tempest/services/identity/json/identity_client.py
@@ -172,6 +172,11 @@
         resp, body = self.put('users/%s/enabled' % user_id, put_body)
         return resp, self._parse_resp(body)
 
+    def get_token(self, token_id):
+        """Get token details."""
+        resp, body = self.get("tokens/%s" % token_id)
+        return resp, self._parse_resp(body)
+
     def delete_token(self, token_id):
         """Delete a token."""
         return self.delete("tokens/%s" % token_id)
diff --git a/tempest/services/identity/v3/json/credentials_client.py b/tempest/services/identity/v3/json/credentials_client.py
index 5d6632a..f795c7b 100644
--- a/tempest/services/identity/v3/json/credentials_client.py
+++ b/tempest/services/identity/v3/json/credentials_client.py
@@ -15,13 +15,13 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class CredentialsClientJSON(RestClient):
+class CredentialsClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(CredentialsClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/identity/v3/json/endpoints_client.py b/tempest/services/identity/v3/json/endpoints_client.py
index 652c345..c3c1e15 100644
--- a/tempest/services/identity/v3/json/endpoints_client.py
+++ b/tempest/services/identity/v3/json/endpoints_client.py
@@ -15,13 +15,13 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class EndPointClientJSON(RestClient):
+class EndPointClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(EndPointClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/identity/v3/json/identity_client.py b/tempest/services/identity/v3/json/identity_client.py
index b044e4d..65f3355 100644
--- a/tempest/services/identity/v3/json/identity_client.py
+++ b/tempest/services/identity/v3/json/identity_client.py
@@ -15,14 +15,14 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
 
 CONF = config.CONF
 
 
-class IdentityV3ClientJSON(RestClient):
+class IdentityV3ClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(IdentityV3ClientJSON, self).__init__(auth_provider)
@@ -439,7 +439,7 @@
         return resp, body
 
 
-class V3TokenClientJSON(RestClient):
+class V3TokenClientJSON(rest_client.RestClient):
 
     def __init__(self):
         super(V3TokenClientJSON, self).__init__(None)
diff --git a/tempest/services/identity/v3/json/policy_client.py b/tempest/services/identity/v3/json/policy_client.py
index 5a3f891..3c90fa1 100644
--- a/tempest/services/identity/v3/json/policy_client.py
+++ b/tempest/services/identity/v3/json/policy_client.py
@@ -15,13 +15,13 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class PolicyClientJSON(RestClient):
+class PolicyClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(PolicyClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/identity/v3/json/service_client.py b/tempest/services/identity/v3/json/service_client.py
index c1faebb..b66fb4a 100644
--- a/tempest/services/identity/v3/json/service_client.py
+++ b/tempest/services/identity/v3/json/service_client.py
@@ -15,13 +15,13 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class ServiceClientJSON(RestClient):
+class ServiceClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(ServiceClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/identity/v3/xml/credentials_client.py b/tempest/services/identity/v3/xml/credentials_client.py
index 22ed44d..70f85a1 100644
--- a/tempest/services/identity/v3/xml/credentials_client.py
+++ b/tempest/services/identity/v3/xml/credentials_client.py
@@ -19,10 +19,7 @@
 
 from tempest.common import rest_client
 from tempest import config
-from tempest.services.compute.xml.common import Document
-from tempest.services.compute.xml.common import Element
-from tempest.services.compute.xml.common import Text
-from tempest.services.compute.xml.common import xml_to_json
+from tempest.services.compute.xml import common
 
 CONF = config.CONF
 
@@ -39,7 +36,7 @@
         self.api_version = "v3"
 
     def _parse_body(self, body):
-        data = xml_to_json(body)
+        data = common.xml_to_json(body)
         return data
 
     def _parse_creds(self, node):
@@ -47,7 +44,7 @@
         for child in node.getchildren():
             tag_list = child.tag.split('}', 1)
             if tag_list[1] == "credential":
-                array.append(xml_to_json(child))
+                array.append(common.xml_to_json(child))
         return array
 
     def create_credential(self, access_key, secret_key, user_id, project_id):
@@ -55,14 +52,14 @@
         cred_type = 'ec2'
         access = "&quot;access&quot;: &quot;%s&quot;" % access_key
         secret = "&quot;secret&quot;: &quot;%s&quot;" % secret_key
-        blob = Element('blob',
-                       xmlns=XMLNS)
-        blob.append(Text("{%s , %s}"
-                         % (access, secret)))
-        credential = Element('credential', project_id=project_id,
-                             type=cred_type, user_id=user_id)
+        blob = common.Element('blob',
+                              xmlns=XMLNS)
+        blob.append(common.Text("{%s , %s}"
+                                % (access, secret)))
+        credential = common.Element('credential', project_id=project_id,
+                                    type=cred_type, user_id=user_id)
         credential.append(blob)
-        resp, body = self.post('credentials', str(Document(credential)))
+        resp, body = self.post('credentials', str(common.Document(credential)))
         body = self._parse_body(etree.fromstring(body))
         body['blob'] = json.loads(body['blob'])
         return resp, body
@@ -77,15 +74,15 @@
         user_id = kwargs.get('user_id', body['user_id'])
         access = "&quot;access&quot;: &quot;%s&quot;" % access_key
         secret = "&quot;secret&quot;: &quot;%s&quot;" % secret_key
-        blob = Element('blob',
-                       xmlns=XMLNS)
-        blob.append(Text("{%s , %s}"
-                         % (access, secret)))
-        credential = Element('credential', project_id=project_id,
-                             type=cred_type, user_id=user_id)
+        blob = common.Element('blob',
+                              xmlns=XMLNS)
+        blob.append(common.Text("{%s , %s}"
+                                % (access, secret)))
+        credential = common.Element('credential', project_id=project_id,
+                                    type=cred_type, user_id=user_id)
         credential.append(blob)
         resp, body = self.patch('credentials/%s' % credential_id,
-                                str(Document(credential)))
+                                str(common.Document(credential)))
         body = self._parse_body(etree.fromstring(body))
         body['blob'] = json.loads(body['blob'])
         return resp, body
diff --git a/tempest/services/identity/v3/xml/endpoints_client.py b/tempest/services/identity/v3/xml/endpoints_client.py
index a32eede..cc9aa65 100644
--- a/tempest/services/identity/v3/xml/endpoints_client.py
+++ b/tempest/services/identity/v3/xml/endpoints_client.py
@@ -18,9 +18,7 @@
 from tempest.common import http
 from tempest.common import rest_client
 from tempest import config
-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
+from tempest.services.compute.xml import common
 
 CONF = config.CONF
 
@@ -41,11 +39,11 @@
         for child in node.getchildren():
             tag_list = child.tag.split('}', 1)
             if tag_list[1] == "endpoint":
-                array.append(xml_to_json(child))
+                array.append(common.xml_to_json(child))
         return array
 
     def _parse_body(self, body):
-        json = xml_to_json(body)
+        json = common.xml_to_json(body)
         return json
 
     def request(self, method, url, headers=None, body=None, wait=None):
@@ -67,21 +65,24 @@
         """Create endpoint."""
         region = kwargs.get('region', None)
         enabled = kwargs.get('enabled', None)
-        create_endpoint = Element("endpoint",
-                                  xmlns=XMLNS,
-                                  service_id=service_id,
-                                  interface=interface,
-                                  url=url, region=region,
-                                  enabled=enabled)
-        resp, body = self.post('endpoints', str(Document(create_endpoint)))
+        if enabled is not None:
+            enabled = str(enabled).lower()
+        create_endpoint = common.Element("endpoint",
+                                         xmlns=XMLNS,
+                                         service_id=service_id,
+                                         interface=interface,
+                                         url=url, region=region,
+                                         enabled=enabled)
+        resp, body = self.post('endpoints',
+                               str(common.Document(create_endpoint)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
     def update_endpoint(self, endpoint_id, service_id=None, interface=None,
                         url=None, region=None, enabled=None):
         """Updates an endpoint with given parameters."""
-        doc = Document()
-        endpoint = Element("endpoint")
+        doc = common.Document()
+        endpoint = common.Element("endpoint")
         doc.append(endpoint)
 
         if service_id:
@@ -93,7 +94,7 @@
         if region:
             endpoint.add_attr("region", region)
         if enabled is not None:
-            endpoint.add_attr("enabled", enabled)
+            endpoint.add_attr("enabled", str(enabled).lower())
         resp, body = self.patch('endpoints/%s' % str(endpoint_id), str(doc))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
diff --git a/tempest/services/identity/v3/xml/identity_client.py b/tempest/services/identity/v3/xml/identity_client.py
index e8e70d8..6ff6d56 100644
--- a/tempest/services/identity/v3/xml/identity_client.py
+++ b/tempest/services/identity/v3/xml/identity_client.py
@@ -20,10 +20,7 @@
 from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
-from tempest.services.compute.xml.common import Document
-from tempest.services.compute.xml.common import Element
-from tempest.services.compute.xml.common import Text
-from tempest.services.compute.xml.common import xml_to_json
+from tempest.services.compute.xml import common
 
 CONF = config.CONF
 
@@ -44,7 +41,7 @@
         for child in node.getchildren():
             tag_list = child.tag.split('}', 1)
             if tag_list[1] == "project":
-                array.append(xml_to_json(child))
+                array.append(common.xml_to_json(child))
         return array
 
     def _parse_domains(self, node):
@@ -52,7 +49,7 @@
         for child in node.getchildren():
             tag_list = child.tag.split('}', 1)
             if tag_list[1] == "domain":
-                array.append(xml_to_json(child))
+                array.append(common.xml_to_json(child))
         return array
 
     def _parse_group_users(self, node):
@@ -60,7 +57,7 @@
         for child in node.getchildren():
             tag_list = child.tag.split('}', 1)
             if tag_list[1] == "user":
-                array.append(xml_to_json(child))
+                array.append(common.xml_to_json(child))
         return array
 
     def _parse_roles(self, node):
@@ -68,17 +65,17 @@
         for child in node.getchildren():
             tag_list = child.tag.split('}', 1)
             if tag_list[1] == "role":
-                array.append(xml_to_json(child))
+                array.append(common.xml_to_json(child))
         return array
 
     def _parse_array(self, node):
         array = []
         for child in node.getchildren():
-            array.append(xml_to_json(child))
+            array.append(common.xml_to_json(child))
         return array
 
     def _parse_body(self, body):
-        _json = xml_to_json(body)
+        _json = common.xml_to_json(body)
         return _json
 
     def create_user(self, user_name, **kwargs):
@@ -89,16 +86,16 @@
         project_id = kwargs.get('project_id', None)
         description = kwargs.get('description', None)
         domain_id = kwargs.get('domain_id', 'default')
-        post_body = Element("user",
-                            xmlns=XMLNS,
-                            name=user_name,
-                            password=password,
-                            description=description,
-                            email=email,
-                            enabled=str(en).lower(),
-                            project_id=project_id,
-                            domain_id=domain_id)
-        resp, body = self.post('users', str(Document(post_body)))
+        post_body = common.Element("user",
+                                   xmlns=XMLNS,
+                                   name=user_name,
+                                   password=password,
+                                   description=description,
+                                   email=email,
+                                   enabled=str(en).lower(),
+                                   project_id=project_id,
+                                   domain_id=domain_id)
+        resp, body = self.post('users', str(common.Document(post_body)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -110,16 +107,16 @@
         project_id = kwargs.get('project_id', body['project_id'])
         description = kwargs.get('description', body['description'])
         domain_id = kwargs.get('domain_id', body['domain_id'])
-        update_user = Element("user",
-                              xmlns=XMLNS,
-                              name=name,
-                              email=email,
-                              project_id=project_id,
-                              domain_id=domain_id,
-                              description=description,
-                              enabled=str(en).lower())
+        update_user = common.Element("user",
+                                     xmlns=XMLNS,
+                                     name=name,
+                                     email=email,
+                                     project_id=project_id,
+                                     domain_id=domain_id,
+                                     description=description,
+                                     enabled=str(en).lower())
         resp, body = self.patch('users/%s' % user_id,
-                                str(Document(update_user)))
+                                str(common.Document(update_user)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -151,14 +148,14 @@
         description = kwargs.get('description', None)
         en = kwargs.get('enabled', 'true')
         domain_id = kwargs.get('domain_id', 'default')
-        post_body = Element("project",
-                            xmlns=XMLNS,
-                            description=description,
-                            domain_id=domain_id,
-                            enabled=str(en).lower(),
-                            name=name)
+        post_body = common.Element("project",
+                                   xmlns=XMLNS,
+                                   description=description,
+                                   domain_id=domain_id,
+                                   enabled=str(en).lower(),
+                                   name=name)
         resp, body = self.post('projects',
-                               str(Document(post_body)))
+                               str(common.Document(post_body)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -175,14 +172,14 @@
         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)
+        post_body = common.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)))
+                                str(common.Document(post_body)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -199,10 +196,10 @@
 
     def create_role(self, name):
         """Create a Role."""
-        post_body = Element("role",
-                            xmlns=XMLNS,
-                            name=name)
-        resp, body = self.post('roles', str(Document(post_body)))
+        post_body = common.Element("role",
+                                   xmlns=XMLNS,
+                                   name=name)
+        resp, body = self.post('roles', str(common.Document(post_body)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -214,11 +211,11 @@
 
     def update_role(self, name, role_id):
         """Updates a Role."""
-        post_body = Element("role",
-                            xmlns=XMLNS,
-                            name=name)
+        post_body = common.Element("role",
+                                   xmlns=XMLNS,
+                                   name=name)
         resp, body = self.patch('roles/%s' % str(role_id),
-                                str(Document(post_body)))
+                                str(common.Document(post_body)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -237,12 +234,12 @@
         """Creates a domain."""
         description = kwargs.get('description', None)
         en = kwargs.get('enabled', True)
-        post_body = Element("domain",
-                            xmlns=XMLNS,
-                            name=name,
-                            description=description,
-                            enabled=str(en).lower())
-        resp, body = self.post('domains', str(Document(post_body)))
+        post_body = common.Element("domain",
+                                   xmlns=XMLNS,
+                                   name=name,
+                                   description=description,
+                                   enabled=str(en).lower())
+        resp, body = self.post('domains', str(common.Document(post_body)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -263,13 +260,13 @@
         description = kwargs.get('description', body['description'])
         en = kwargs.get('enabled', body['enabled'])
         name = kwargs.get('name', body['name'])
-        post_body = Element("domain",
-                            xmlns=XMLNS,
-                            name=name,
-                            description=description,
-                            enabled=str(en).lower())
+        post_body = common.Element("domain",
+                                   xmlns=XMLNS,
+                                   name=name,
+                                   description=description,
+                                   enabled=str(en).lower())
         resp, body = self.patch('domains/%s' % domain_id,
-                                str(Document(post_body)))
+                                str(common.Document(post_body)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -299,13 +296,13 @@
         description = kwargs.get('description', None)
         domain_id = kwargs.get('domain_id', 'default')
         project_id = kwargs.get('project_id', None)
-        post_body = Element("group",
-                            xmlns=XMLNS,
-                            name=name,
-                            description=description,
-                            domain_id=domain_id,
-                            project_id=project_id)
-        resp, body = self.post('groups', str(Document(post_body)))
+        post_body = common.Element("group",
+                                   xmlns=XMLNS,
+                                   name=name,
+                                   description=description,
+                                   domain_id=domain_id,
+                                   project_id=project_id)
+        resp, body = self.post('groups', str(common.Document(post_body)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -320,12 +317,12 @@
         resp, body = self.get_group(group_id)
         name = kwargs.get('name', body['name'])
         description = kwargs.get('description', body['description'])
-        post_body = Element("group",
-                            xmlns=XMLNS,
-                            name=name,
-                            description=description)
+        post_body = common.Element("group",
+                                   xmlns=XMLNS,
+                                   name=name,
+                                   description=description)
         resp, body = self.patch('groups/%s' % group_id,
-                                str(Document(post_body)))
+                                str(common.Document(post_body)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -456,35 +453,35 @@
         Validation is left to the server side.
         """
         if user_type == 'id':
-            _user = Element('user', id=user, password=password)
+            _user = common.Element('user', id=user, password=password)
         else:
-            _user = Element('user', name=user, password=password)
+            _user = common.Element('user', name=user, password=password)
         if domain is not None:
-            _domain = Element('domain', name=domain)
+            _domain = common.Element('domain', name=domain)
             _user.append(_domain)
 
-        password = Element('password')
+        password = common.Element('password')
         password.append(_user)
 
-        method = Element('method')
-        method.append(Text('password'))
-        methods = Element('methods')
+        method = common.Element('method')
+        method.append(common.Text('password'))
+        methods = common.Element('methods')
         methods.append(method)
-        identity = Element('identity')
+        identity = common.Element('identity')
         identity.append(methods)
         identity.append(password)
 
-        auth = Element('auth')
+        auth = common.Element('auth')
         auth.append(identity)
 
         if tenant is not None:
-            project = Element('project', name=tenant)
+            project = common.Element('project', name=tenant)
             project.append(_domain)
-            scope = Element('scope')
+            scope = common.Element('scope')
             scope.append(project)
             auth.append(scope)
 
-        resp, body = self.post(self.auth_url, body=str(Document(auth)))
+        resp, body = self.post(self.auth_url, body=str(common.Document(auth)))
         return resp, body
 
     def request(self, method, url, headers=None, body=None):
diff --git a/tempest/services/identity/v3/xml/policy_client.py b/tempest/services/identity/v3/xml/policy_client.py
index c12018a..bf4cce7 100644
--- a/tempest/services/identity/v3/xml/policy_client.py
+++ b/tempest/services/identity/v3/xml/policy_client.py
@@ -18,9 +18,7 @@
 from tempest.common import http
 from tempest.common import rest_client
 from tempest import config
-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
+from tempest.services.compute.xml import common
 
 CONF = config.CONF
 
@@ -41,11 +39,11 @@
         for child in node.getchildren():
             tag_list = child.tag.split('}', 1)
             if tag_list[1] == "policy":
-                array.append(xml_to_json(child))
+                array.append(common.xml_to_json(child))
         return array
 
     def _parse_body(self, body):
-        json = xml_to_json(body)
+        json = common.xml_to_json(body)
         return json
 
     def request(self, method, url, headers=None, body=None, wait=None):
@@ -59,8 +57,9 @@
 
     def create_policy(self, blob, type):
         """Creates a Policy."""
-        create_policy = Element("policy", xmlns=XMLNS, blob=blob, type=type)
-        resp, body = self.post('policies', str(Document(create_policy)))
+        create_policy = common.Element("policy", xmlns=XMLNS,
+                                       blob=blob, type=type)
+        resp, body = self.post('policies', str(common.Document(create_policy)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -81,9 +80,9 @@
         """Updates a policy."""
         resp, body = self.get_policy(policy_id)
         type = kwargs.get('type')
-        update_policy = Element("policy", xmlns=XMLNS, type=type)
+        update_policy = common.Element("policy", xmlns=XMLNS, type=type)
         url = 'policies/%s' % policy_id
-        resp, body = self.patch(url, str(Document(update_policy)))
+        resp, body = self.patch(url, str(common.Document(update_policy)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
diff --git a/tempest/services/identity/v3/xml/service_client.py b/tempest/services/identity/v3/xml/service_client.py
index d5476c4..966d7f7 100644
--- a/tempest/services/identity/v3/xml/service_client.py
+++ b/tempest/services/identity/v3/xml/service_client.py
@@ -17,9 +17,7 @@
 
 from tempest.common import rest_client
 from tempest import config
-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
+from tempest.services.compute.xml import common
 
 CONF = config.CONF
 
@@ -35,14 +33,8 @@
         self.endpoint_url = 'adminURL'
         self.api_version = "v3"
 
-    def _parse_array(self, node):
-        array = []
-        for child in node.getchildren():
-            array.append(xml_to_json(child))
-        return array
-
     def _parse_body(self, body):
-        data = xml_to_json(body)
+        data = common.xml_to_json(body)
         return data
 
     def update_service(self, service_id, **kwargs):
@@ -51,14 +43,14 @@
         name = kwargs.get('name', body['name'])
         description = kwargs.get('description', body['description'])
         type = kwargs.get('type', body['type'])
-        update_service = Element("service",
-                                 xmlns=XMLNS,
-                                 id=service_id,
-                                 name=name,
-                                 description=description,
-                                 type=type)
+        update_service = common.Element("service",
+                                        xmlns=XMLNS,
+                                        id=service_id,
+                                        name=name,
+                                        description=description,
+                                        type=type)
         resp, body = self.patch('services/%s' % service_id,
-                                str(Document(update_service)))
+                                str(common.Document(update_service)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -70,12 +62,12 @@
         return resp, body
 
     def create_service(self, serv_type, name=None, description=None):
-        post_body = Element("service",
-                            xmlns=XMLNS,
-                            name=name,
-                            description=description,
-                            type=serv_type)
-        resp, body = self.post("services", str(Document(post_body)))
+        post_body = common.Element("service",
+                                   xmlns=XMLNS,
+                                   name=name,
+                                   description=description,
+                                   type=serv_type)
+        resp, body = self.post("services", str(common.Document(post_body)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
diff --git a/tempest/services/image/v1/json/image_client.py b/tempest/services/image/v1/json/image_client.py
index 932fa14..e22cd9c 100644
--- a/tempest/services/image/v1/json/image_client.py
+++ b/tempest/services/image/v1/json/image_client.py
@@ -21,7 +21,7 @@
 import urllib
 
 from tempest.common import glance_http
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
 from tempest.openstack.common import log as logging
@@ -31,7 +31,7 @@
 LOG = logging.getLogger(__name__)
 
 
-class ImageClientJSON(RestClient):
+class ImageClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(ImageClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/image/v2/json/image_client.py b/tempest/services/image/v2/json/image_client.py
index 58819d0..b3014fc 100644
--- a/tempest/services/image/v2/json/image_client.py
+++ b/tempest/services/image/v2/json/image_client.py
@@ -39,23 +39,9 @@
                                       filters=self.filters,
                                       insecure=dscv)
 
-    def get_images_schema(self):
-        url = 'v2/schemas/images'
-        resp, body = self.get(url)
-        body = json.loads(body)
-        return resp, body
-
-    def get_image_schema(self):
-        url = 'v2/schemas/image'
-        resp, body = self.get(url)
-        body = json.loads(body)
-        return resp, body
-
     def _validate_schema(self, body, type='image'):
-        if type == 'image':
-            resp, schema = self.get_image_schema()
-        elif type == 'images':
-            resp, schema = self.get_images_schema()
+        if type in ['image', 'images']:
+            resp, schema = self.get_schema(type)
         else:
             raise ValueError("%s is not a valid schema type" % type)
 
@@ -68,6 +54,15 @@
                 self._http = self._get_http()
         return self._http
 
+    def update_image(self, image_id, patch):
+        data = json.dumps(patch)
+        self._validate_schema(data)
+
+        headers = {"Content-Type": "application/openstack-images-v2.0"
+                                   "-json-patch"}
+        resp, body = self.patch('v2/images/%s' % image_id, data, headers)
+        return resp, self._parse_resp(body)
+
     def create_image(self, name, container_format, disk_format, **kwargs):
         params = {
             "name": name,
@@ -163,3 +158,21 @@
         body = json.loads(body)
         self.expected_success(200, resp)
         return resp, body
+
+    def get_member(self, image_id, member_id):
+        url = 'v2/images/%s/members/%s' % (image_id, member_id)
+        resp, body = self.get(url)
+        self.expected_success(200, resp)
+        return resp, json.loads(body)
+
+    def remove_member(self, image_id, member_id):
+        url = 'v2/images/%s/members/%s' % (image_id, member_id)
+        resp, _ = self.delete(url)
+        self.expected_success(204, resp)
+        return resp
+
+    def get_schema(self, schema):
+        url = 'v2/schemas/%s' % schema
+        resp, body = self.get(url)
+        body = json.loads(body)
+        return resp, body
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index 366ccee..a804e8e 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -12,7 +12,7 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest.services.network import network_client_base
 
 
@@ -32,7 +32,7 @@
     """
 
     def get_rest_client(self, auth_provider):
-        return RestClient(auth_provider)
+        return rest_client.RestClient(auth_provider)
 
     def deserialize_single(self, body):
         return json.loads(body)
@@ -163,32 +163,6 @@
         body = json.loads(body)
         return resp, body
 
-    def create_member(self, address, protocol_port, pool_id):
-        post_body = {
-            "member": {
-                "protocol_port": protocol_port,
-                "pool_id": pool_id,
-                "address": address
-            }
-        }
-        body = json.dumps(post_body)
-        uri = '%s/lb/members' % (self.uri_prefix)
-        resp, body = self.post(uri, body)
-        body = json.loads(body)
-        return resp, body
-
-    def update_member(self, admin_state_up, member_id):
-        put_body = {
-            "member": {
-                "admin_state_up": admin_state_up
-            }
-        }
-        body = json.dumps(put_body)
-        uri = '%s/lb/members/%s' % (self.uri_prefix, member_id)
-        resp, body = self.put(uri, body)
-        body = json.loads(body)
-        return resp, body
-
     def associate_health_monitor_with_pool(self, health_monitor_id,
                                            pool_id):
         post_body = {
@@ -280,6 +254,20 @@
         body = json.loads(body)
         return resp, body
 
+    def add_router_to_l3_agent(self, agent_id, router_id):
+        uri = '%s/agents/%s/l3-routers' % (self.uri_prefix, agent_id)
+        post_body = {"router_id": router_id}
+        body = json.dumps(post_body)
+        resp, body = self.post(uri, body)
+        body = json.loads(body)
+        return resp, body
+
+    def remove_router_from_l3_agent(self, agent_id, router_id):
+        uri = '%s/agents/%s/l3-routers/%s' % (
+            self.uri_prefix, agent_id, router_id)
+        resp, body = self.delete(uri)
+        return resp, body
+
     def list_dhcp_agent_hosting_network(self, network_id):
         uri = '%s/networks/%s/dhcp-agents' % (self.uri_prefix, network_id)
         resp, body = self.get(uri)
diff --git a/tempest/services/network/network_client_base.py b/tempest/services/network/network_client_base.py
index f1bf548..41a7aa4 100644
--- a/tempest/services/network/network_client_base.py
+++ b/tempest/services/network/network_client_base.py
@@ -10,9 +10,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import time
 import urllib
 
 from tempest import config
+from tempest import exceptions
 
 CONF = config.CONF
 
@@ -54,6 +56,8 @@
         self.rest_client.service = CONF.network.catalog_type
         self.version = '2.0'
         self.uri_prefix = "v%s" % (self.version)
+        self.build_timeout = CONF.network.build_timeout
+        self.build_interval = CONF.network.build_interval
 
     def get_rest_client(self, auth_provider):
         raise NotImplementedError
@@ -189,3 +193,23 @@
         resp, body = self.post(uri, body)
         body = {'ports': self.deserialize_list(body)}
         return resp, body
+
+    def wait_for_resource_deletion(self, resource_type, id):
+        """Waits for a resource to be deleted."""
+        start_time = int(time.time())
+        while True:
+            if self.is_resource_deleted(resource_type, id):
+                return
+            if int(time.time()) - start_time >= self.build_timeout:
+                raise exceptions.TimeoutException
+            time.sleep(self.build_interval)
+
+    def is_resource_deleted(self, resource_type, id):
+        method = 'show_' + resource_type
+        try:
+            getattr(self, method)(id)
+        except AttributeError:
+            raise Exception("Unknown resource type %s " % resource_type)
+        except exceptions.NotFound:
+            return True
+        return False
diff --git a/tempest/services/network/xml/network_client.py b/tempest/services/network/xml/network_client.py
index 97d514f..2a5083c 100644
--- a/tempest/services/network/xml/network_client.py
+++ b/tempest/services/network/xml/network_client.py
@@ -23,19 +23,14 @@
 
     # list of plurals used for xml serialization
     PLURALS = ['dns_nameservers', 'host_routes', 'allocation_pools',
-               'fixed_ips', 'extensions', 'extra_dhcp_opts']
+               'fixed_ips', 'extensions', 'extra_dhcp_opts', 'pools',
+               'health_monitors', 'vips']
 
     def get_rest_client(self, auth_provider):
         rc = rest_client.RestClient(auth_provider)
         rc.TYPE = self.TYPE
         return rc
 
-    def _parse_array(self, node):
-        array = []
-        for child in node.getchildren():
-            array.append(common.xml_to_json(child))
-        return array
-
     def deserialize_list(self, body):
         return common.parse_array(etree.fromstring(body), self.PLURALS)
 
@@ -49,9 +44,14 @@
         post_body = common.Element(root)
         post_body.add_attr('xmlns:xsi',
                            'http://www.w3.org/2001/XMLSchema-instance')
+        elements = set()
         for name, attr in body[root].items():
             elt = self._get_element(name, attr)
             post_body.append(elt)
+            if ":" in name:
+                elements.add(name.split(":")[0])
+        if elements:
+            self._add_namespaces(post_body, elements)
         return str(common.Document(post_body))
 
     def serialize_list(self, body, root_name=None, item_name=None):
@@ -88,27 +88,10 @@
         else:
             return common.Element(name, value)
 
-    def create_member(self, address, protocol_port, pool_id):
-        uri = '%s/lb/members' % (self.uri_prefix)
-        post_body = common.Element("member")
-        p1 = common.Element("address", address)
-        p2 = common.Element("protocol_port", protocol_port)
-        p3 = common.Element("pool_id", pool_id)
-        post_body.append(p1)
-        post_body.append(p2)
-        post_body.append(p3)
-        resp, body = self.post(uri, str(common.Document(post_body)))
-        body = _root_tag_fetcher_and_xml_to_json_parse(body)
-        return resp, body
-
-    def update_member(self, admin_state_up, member_id):
-        uri = '%s/lb/members/%s' % (self.uri_prefix, str(member_id))
-        put_body = common.Element("member")
-        p2 = common.Element("admin_state_up", admin_state_up)
-        put_body.append(p2)
-        resp, body = self.put(uri, str(common.Document(put_body)))
-        body = _root_tag_fetcher_and_xml_to_json_parse(body)
-        return resp, body
+    def _add_namespaces(self, root, elements):
+        for element in elements:
+            root.add_attr('xmlns:%s' % element,
+                          common.NEUTRON_NAMESPACES[element])
 
     def associate_health_monitor_with_pool(self, health_monitor_id,
                                            pool_id):
@@ -244,15 +227,30 @@
     def list_routers_on_l3_agent(self, agent_id):
         uri = '%s/agents/%s/l3-routers' % (self.uri_prefix, agent_id)
         resp, body = self.get(uri)
-        body = _root_tag_fetcher_and_xml_to_json_parse(body)
+        routers = common.parse_array(etree.fromstring(body))
+        body = {'routers': routers}
         return resp, body
 
     def list_l3_agents_hosting_router(self, router_id):
         uri = '%s/routers/%s/l3-agents' % (self.uri_prefix, router_id)
         resp, body = self.get(uri)
+        agents = common.parse_array(etree.fromstring(body))
+        body = {'agents': agents}
+        return resp, body
+
+    def add_router_to_l3_agent(self, agent_id, router_id):
+        uri = '%s/agents/%s/l3-routers' % (self.uri_prefix, agent_id)
+        router = (common.Element("router_id", router_id))
+        resp, body = self.post(uri, str(common.Document(router)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
+    def remove_router_from_l3_agent(self, agent_id, router_id):
+        uri = '%s/agents/%s/l3-routers/%s' % (
+            self.uri_prefix, agent_id, router_id)
+        resp, body = self.delete(uri)
+        return resp, body
+
     def list_dhcp_agent_hosting_network(self, network_id):
         uri = '%s/networks/%s/dhcp-agents' % (self.uri_prefix, network_id)
         resp, body = self.get(uri)
diff --git a/tempest/services/object_storage/account_client.py b/tempest/services/object_storage/account_client.py
index efac5f5..7c3fa85 100644
--- a/tempest/services/object_storage/account_client.py
+++ b/tempest/services/object_storage/account_client.py
@@ -17,18 +17,18 @@
 import urllib
 
 from tempest.common import http
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
+from xml.etree import ElementTree as etree
 
 CONF = config.CONF
 
 
-class AccountClient(RestClient):
+class AccountClient(rest_client.RestClient):
     def __init__(self, auth_provider):
         super(AccountClient, self).__init__(auth_provider)
         self.service = CONF.object_storage.catalog_type
-        self.format = 'json'
 
     def create_account(self, data=None,
                        params=None,
@@ -87,7 +87,25 @@
 
         headers = {}
         for item in metadata:
-            headers[metadata_prefix + item] = 'x'
+            headers[metadata_prefix + item] = metadata[item]
+        resp, body = self.post('', headers=headers, body=None)
+        return resp, body
+
+    def create_and_delete_account_metadata(
+            self,
+            create_metadata=None,
+            delete_metadata=None,
+            create_metadata_prefix='X-Account-Meta-',
+            delete_metadata_prefix='X-Remove-Account-Meta-'):
+        """
+        Creates and deletes an account metadata entry.
+        """
+        headers = {}
+        for key in create_metadata:
+            headers[create_metadata_prefix + key] = create_metadata[key]
+        for key in delete_metadata:
+            headers[delete_metadata_prefix + key] = delete_metadata[key]
+
         resp, body = self.post('', headers=headers, body=None)
         return resp, body
 
@@ -112,36 +130,35 @@
             response.
             DEFAULT:  Python-List returned in response body
         """
+        url = '?%s' % urllib.urlencode(params) if params else ''
 
-        if params:
-            if 'format' not in params:
-                params['format'] = self.format
-        else:
-            params = {'format': self.format}
-
-        url = '?' + urllib.urlencode(params)
-        resp, body = self.get(url)
-
+        resp, body = self.get(url, headers={})
         if params and params.get('format') == 'json':
             body = json.loads(body)
+        elif params and params.get('format') == 'xml':
+            body = etree.fromstring(body)
+        else:
+            body = body.strip().splitlines()
         return resp, body
 
     def list_extensions(self):
         self.skip_path()
-        resp, body = self.get('info')
-        self.reset_path()
+        try:
+            resp, body = self.get('info')
+        finally:
+            self.reset_path()
         body = json.loads(body)
         return resp, body
 
 
-class AccountClientCustomizedHeader(RestClient):
+class AccountClientCustomizedHeader(rest_client.RestClient):
 
     # TODO(andreaf) This class is now redundant, to be removed in next patch
 
     def __init__(self, auth_provider):
         super(AccountClientCustomizedHeader, self).__init__(
             auth_provider)
-        # Overwrites json-specific header encoding in RestClient
+        # Overwrites json-specific header encoding in rest_client.RestClient
         self.service = CONF.object_storage.catalog_type
         self.format = 'json'
 
diff --git a/tempest/services/object_storage/container_client.py b/tempest/services/object_storage/container_client.py
index f224407..546b557 100644
--- a/tempest/services/object_storage/container_client.py
+++ b/tempest/services/object_storage/container_client.py
@@ -16,18 +16,18 @@
 import json
 import urllib
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 from xml.etree import ElementTree as etree
 
 CONF = config.CONF
 
 
-class ContainerClient(RestClient):
+class ContainerClient(rest_client.RestClient):
     def __init__(self, auth_provider):
         super(ContainerClient, self).__init__(auth_provider)
 
-        # Overwrites json-specific header encoding in RestClient
+        # Overwrites json-specific header encoding in rest_client.RestClient
         self.headers = {}
         self.service = CONF.object_storage.catalog_type
         self.format = 'json'
diff --git a/tempest/services/object_storage/object_client.py b/tempest/services/object_storage/object_client.py
index 09e484e..77d29a5 100644
--- a/tempest/services/object_storage/object_client.py
+++ b/tempest/services/object_storage/object_client.py
@@ -16,14 +16,14 @@
 import urllib
 
 from tempest.common import http
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
 
 CONF = config.CONF
 
 
-class ObjectClient(RestClient):
+class ObjectClient(rest_client.RestClient):
     def __init__(self, auth_provider):
         super(ObjectClient, self).__init__(auth_provider)
 
@@ -135,14 +135,14 @@
         return resp, body
 
 
-class ObjectClientCustomizedHeader(RestClient):
+class ObjectClientCustomizedHeader(rest_client.RestClient):
 
     # TODO(andreaf) This class is now redundant, to be removed in next patch
 
     def __init__(self, auth_provider):
         super(ObjectClientCustomizedHeader, self).__init__(
             auth_provider)
-        # Overwrites json-specific header encoding in RestClient
+        # Overwrites json-specific header encoding in rest_client.RestClient
         self.service = CONF.object_storage.catalog_type
         self.format = 'json'
 
diff --git a/tempest/services/queuing/__init__.py b/tempest/services/queuing/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/services/queuing/__init__.py
diff --git a/tempest/services/queuing/json/__init__.py b/tempest/services/queuing/json/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/services/queuing/json/__init__.py
diff --git a/tempest/services/queuing/json/queuing_client.py b/tempest/services/queuing/json/queuing_client.py
new file mode 100644
index 0000000..4a0c495
--- /dev/null
+++ b/tempest/services/queuing/json/queuing_client.py
@@ -0,0 +1,58 @@
+# Copyright (c) 2014 Rackspace, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json
+
+from tempest.common import rest_client
+from tempest import config
+
+CONF = config.CONF
+
+
+class QueuingClientJSON(rest_client.RestClient):
+
+    def __init__(self, auth_provider):
+        super(QueuingClientJSON, self).__init__(auth_provider)
+        self.service = CONF.queuing.catalog_type
+        self.version = '1'
+        self.uri_prefix = 'v{0}'.format(self.version)
+
+    def list_queues(self):
+        uri = '{0}/queues'.format(self.uri_prefix)
+        resp, body = self.get(uri)
+        body = json.loads(body)
+        return resp, body
+
+    def create_queue(self, queue_name):
+        uri = '{0}/queues/{1}'.format(self.uri_prefix, queue_name)
+        resp, body = self.put(uri, body=None)
+        return resp, body
+
+    def get_queue(self, queue_name):
+        uri = '{0}/queues/{1}'.format(self.uri_prefix, queue_name)
+        resp, body = self.get(uri)
+        body = json.loads(body)
+        return resp, body
+
+    def head_queue(self, queue_name):
+        uri = '{0}/queues/{1}'.format(self.uri_prefix, queue_name)
+        resp, body = self.head(uri)
+        body = json.loads(body)
+        return resp, body
+
+    def delete_queue(self, queue_name):
+        uri = '{0}/queues/{1}'.format(self.uri_prefix, queue_name)
+        resp = self.delete(uri)
+        return resp
diff --git a/tempest/services/telemetry/json/telemetry_client.py b/tempest/services/telemetry/json/telemetry_client.py
index e666475..996aceb 100644
--- a/tempest/services/telemetry/json/telemetry_client.py
+++ b/tempest/services/telemetry/json/telemetry_client.py
@@ -13,7 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest.openstack.common import jsonutils as json
 import tempest.services.telemetry.telemetry_client_base as client
 
@@ -21,7 +21,7 @@
 class TelemetryClientJSON(client.TelemetryClientBase):
 
     def get_rest_client(self, auth_provider):
-        return RestClient(auth_provider)
+        return rest_client.RestClient(auth_provider)
 
     def deserialize(self, body):
         return json.loads(body.replace("\n", ""))
diff --git a/tempest/services/telemetry/xml/telemetry_client.py b/tempest/services/telemetry/xml/telemetry_client.py
index 165f29a..673f98e 100644
--- a/tempest/services/telemetry/xml/telemetry_client.py
+++ b/tempest/services/telemetry/xml/telemetry_client.py
@@ -16,8 +16,7 @@
 from lxml import etree
 
 from tempest.common import rest_client
-from tempest.services.compute.xml.common import Document
-from tempest.services.compute.xml.common import xml_to_json
+from tempest.services.compute.xml import common
 import tempest.services.telemetry.telemetry_client_base as client
 
 
@@ -32,11 +31,11 @@
     def _parse_array(self, body):
         array = []
         for child in body.getchildren():
-            array.append(xml_to_json(child))
+            array.append(common.xml_to_json(child))
         return array
 
     def serialize(self, body):
-        return str(Document(body))
+        return str(common.Document(body))
 
     def deserialize(self, body):
         return self._parse_array(etree.fromstring(body))
diff --git a/tempest/services/volume/json/admin/volume_hosts_client.py b/tempest/services/volume/json/admin/volume_hosts_client.py
index 6efb258..84e4705 100644
--- a/tempest/services/volume/json/admin/volume_hosts_client.py
+++ b/tempest/services/volume/json/admin/volume_hosts_client.py
@@ -16,13 +16,13 @@
 import json
 import urllib
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class VolumeHostsClientJSON(RestClient):
+class VolumeHostsClientJSON(rest_client.RestClient):
     """
     Client class to send CRUD Volume Hosts API requests to a Cinder endpoint
     """
diff --git a/tempest/services/volume/json/admin/volume_quotas_client.py b/tempest/services/volume/json/admin/volume_quotas_client.py
new file mode 100644
index 0000000..ea9c92e
--- /dev/null
+++ b/tempest/services/volume/json/admin/volume_quotas_client.py
@@ -0,0 +1,79 @@
+# Copyright (C) 2014 eNovance SAS <licensing@enovance.com>
+#
+# Author: Sylvain Baubeau <sylvain.baubeau@enovance.com>
+#
+#    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 urllib
+
+from tempest.openstack.common import jsonutils
+
+from tempest.common import rest_client
+from tempest import config
+
+CONF = config.CONF
+
+
+class VolumeQuotasClientJSON(rest_client.RestClient):
+    """
+    Client class to send CRUD Volume Quotas API requests to a Cinder endpoint
+    """
+
+    TYPE = "json"
+
+    def __init__(self, auth_provider):
+        super(VolumeQuotasClientJSON, self).__init__(auth_provider)
+
+        self.service = CONF.volume.catalog_type
+        self.build_interval = CONF.volume.build_interval
+        self.build_timeout = CONF.volume.build_timeout
+
+    def get_default_quota_set(self, tenant_id):
+        """List the default volume quota set for a tenant."""
+
+        url = 'os-quota-sets/%s/defaults' % tenant_id
+        resp, body = self.get(url)
+        return resp, self._parse_resp(body)
+
+    def get_quota_set(self, tenant_id, params=None):
+        """List the quota set for a tenant."""
+
+        url = 'os-quota-sets/%s' % tenant_id
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+
+        resp, body = self.get(url)
+        return resp, self._parse_resp(body)
+
+    def get_quota_usage(self, tenant_id):
+        """List the quota set for a tenant."""
+
+        resp, body = self.get_quota_set(tenant_id, params={'usage': True})
+        return resp, body
+
+    def update_quota_set(self, tenant_id, gigabytes=None, volumes=None,
+                         snapshots=None):
+        post_body = {}
+
+        if gigabytes is not None:
+            post_body['gigabytes'] = gigabytes
+
+        if volumes is not None:
+            post_body['volumes'] = volumes
+
+        if snapshots is not None:
+            post_body['snapshots'] = snapshots
+
+        post_body = jsonutils.dumps({'quota_set': post_body})
+        resp, body = self.put('os-quota-sets/%s' % tenant_id, post_body)
+        return resp, self._parse_resp(body)
diff --git a/tempest/services/volume/json/admin/volume_types_client.py b/tempest/services/volume/json/admin/volume_types_client.py
index 0d50524..5554362 100644
--- a/tempest/services/volume/json/admin/volume_types_client.py
+++ b/tempest/services/volume/json/admin/volume_types_client.py
@@ -16,13 +16,13 @@
 import json
 import urllib
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class VolumeTypesClientJSON(RestClient):
+class VolumeTypesClientJSON(rest_client.RestClient):
     """
     Client class to send CRUD Volume Types API requests to a Cinder endpoint
     """
diff --git a/tempest/services/volume/json/backups_client.py b/tempest/services/volume/json/backups_client.py
index baaf5a0..183d06b 100644
--- a/tempest/services/volume/json/backups_client.py
+++ b/tempest/services/volume/json/backups_client.py
@@ -69,6 +69,13 @@
         body = json.loads(body)
         return resp, body['backup']
 
+    def list_backups_with_detail(self):
+        """Information for all the tenant's backups."""
+        url = "backups/detail"
+        resp, body = self.get(url)
+        body = json.loads(body)
+        return resp, body['backups']
+
     def wait_for_backup_status(self, backup_id, status):
         """Waits for a Backup to reach a given status."""
         resp, body = self.get_backup(backup_id)
diff --git a/tempest/services/volume/json/extensions_client.py b/tempest/services/volume/json/extensions_client.py
index 257b7c8..9e182ea 100644
--- a/tempest/services/volume/json/extensions_client.py
+++ b/tempest/services/volume/json/extensions_client.py
@@ -15,13 +15,13 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class ExtensionsClientJSON(RestClient):
+class ExtensionsClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(ExtensionsClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/volume/json/snapshots_client.py b/tempest/services/volume/json/snapshots_client.py
index ba33c49..2dff63d 100644
--- a/tempest/services/volume/json/snapshots_client.py
+++ b/tempest/services/volume/json/snapshots_client.py
@@ -14,7 +14,7 @@
 import time
 import urllib
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
 from tempest.openstack.common import log as logging
@@ -24,7 +24,7 @@
 LOG = logging.getLogger(__name__)
 
 
-class SnapshotsClientJSON(RestClient):
+class SnapshotsClientJSON(rest_client.RestClient):
     """Client class to send CRUD Volume API requests."""
 
     def __init__(self, auth_provider):
diff --git a/tempest/services/volume/json/volumes_client.py b/tempest/services/volume/json/volumes_client.py
index 2183c56..e4d2e8d 100644
--- a/tempest/services/volume/json/volumes_client.py
+++ b/tempest/services/volume/json/volumes_client.py
@@ -17,14 +17,14 @@
 import time
 import urllib
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
 
 CONF = config.CONF
 
 
-class VolumesClientJSON(RestClient):
+class VolumesClientJSON(rest_client.RestClient):
     """
     Client class to send CRUD Volume API requests to a Cinder endpoint
     """
diff --git a/tempest/services/volume/v2/json/volumes_client.py b/tempest/services/volume/v2/json/volumes_client.py
index bd98402..5bfa75f 100644
--- a/tempest/services/volume/v2/json/volumes_client.py
+++ b/tempest/services/volume/v2/json/volumes_client.py
@@ -17,14 +17,14 @@
 import time
 import urllib
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
 
 CONF = config.CONF
 
 
-class VolumesV2ClientJSON(RestClient):
+class VolumesV2ClientJSON(rest_client.RestClient):
     """
     Client class to send CRUD Volume V2 API requests to a Cinder endpoint
     """
diff --git a/tempest/services/volume/v2/xml/volumes_client.py b/tempest/services/volume/v2/xml/volumes_client.py
index bc57842..0b8f47c 100644
--- a/tempest/services/volume/v2/xml/volumes_client.py
+++ b/tempest/services/volume/v2/xml/volumes_client.py
@@ -21,11 +21,7 @@
 from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
-from tempest.services.compute.xml.common import Document
-from tempest.services.compute.xml.common import Element
-from tempest.services.compute.xml.common import Text
-from tempest.services.compute.xml.common import xml_to_json
-from tempest.services.compute.xml.common import XMLNS_11
+from tempest.services.compute.xml import common
 
 CONF = config.CONF
 
@@ -56,7 +52,7 @@
                                        meta.text) for meta in
                                        child.getchildren())
             else:
-                vol[tag] = xml_to_json(child)
+                vol[tag] = common.xml_to_json(child)
         return vol
 
     def get_attachment_from_volume(self, volume):
@@ -134,15 +130,15 @@
                          image
         """
         # NOTE(afazekas): it should use a volume namespace
-        volume = Element("volume", xmlns=XMLNS_11, size=size)
+        volume = common.Element("volume", xmlns=common.XMLNS_11, size=size)
 
         if 'metadata' in kwargs:
-            _metadata = Element('metadata')
+            _metadata = common.Element('metadata')
             volume.append(_metadata)
             for key, value in kwargs['metadata'].items():
-                meta = Element('meta')
+                meta = common.Element('meta')
                 meta.add_attr('key', key)
-                meta.append(Text(value))
+                meta.append(common.Text(value))
                 _metadata.append(meta)
             attr_to_add = kwargs.copy()
             del attr_to_add['metadata']
@@ -152,17 +148,17 @@
         for key, value in attr_to_add.items():
             volume.add_attr(key, value)
 
-        resp, body = self.post('volumes', str(Document(volume)))
-        body = xml_to_json(etree.fromstring(body))
+        resp, body = self.post('volumes', str(common.Document(volume)))
+        body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def update_volume(self, volume_id, **kwargs):
         """Updates the Specified Volume."""
-        put_body = Element("volume", xmlns=XMLNS_11, **kwargs)
+        put_body = common.Element("volume", xmlns=common.XMLNS_11, **kwargs)
 
         resp, body = self.put('volumes/%s' % volume_id,
-                              str(Document(put_body)))
-        body = xml_to_json(etree.fromstring(body))
+                              str(common.Document(put_body)))
+        body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def delete_volume(self, volume_id):
@@ -198,108 +194,107 @@
 
     def attach_volume(self, volume_id, instance_uuid, mountpoint):
         """Attaches a volume to a given instance on a given mountpoint."""
-        post_body = Element("os-attach",
-                            instance_uuid=instance_uuid,
-                            mountpoint=mountpoint
-                            )
+        post_body = common.Element("os-attach",
+                                   instance_uuid=instance_uuid,
+                                   mountpoint=mountpoint
+                                   )
         url = 'volumes/%s/action' % str(volume_id)
-        resp, body = self.post(url, str(Document(post_body)))
+        resp, body = self.post(url, str(common.Document(post_body)))
         if body:
-            body = xml_to_json(etree.fromstring(body))
+            body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def detach_volume(self, volume_id):
         """Detaches a volume from an instance."""
-        post_body = Element("os-detach")
+        post_body = common.Element("os-detach")
         url = 'volumes/%s/action' % str(volume_id)
-        resp, body = self.post(url, str(Document(post_body)))
+        resp, body = self.post(url, str(common.Document(post_body)))
         if body:
-            body = xml_to_json(etree.fromstring(body))
+            body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def upload_volume(self, volume_id, image_name, disk_format):
         """Uploads a volume in Glance."""
-        post_body = Element("os-volume_upload_image",
-                            image_name=image_name,
-                            disk_format=disk_format)
+        post_body = common.Element("os-volume_upload_image",
+                                   image_name=image_name,
+                                   disk_format=disk_format)
         url = 'volumes/%s/action' % str(volume_id)
-        resp, body = self.post(url, str(Document(post_body)))
-        volume = xml_to_json(etree.fromstring(body))
+        resp, body = self.post(url, str(common.Document(post_body)))
+        volume = common.xml_to_json(etree.fromstring(body))
         return resp, volume
 
     def extend_volume(self, volume_id, extend_size):
         """Extend a volume."""
-        post_body = Element("os-extend",
-                            new_size=extend_size)
+        post_body = common.Element("os-extend",
+                                   new_size=extend_size)
         url = 'volumes/%s/action' % str(volume_id)
-        resp, body = self.post(url, str(Document(post_body)))
+        resp, body = self.post(url, str(common.Document(post_body)))
         if body:
-            body = xml_to_json(etree.fromstring(body))
+            body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def reset_volume_status(self, volume_id, status):
         """Reset the Specified Volume's Status."""
-        post_body = Element("os-reset_status",
-                            status=status
-                            )
+        post_body = common.Element("os-reset_status",
+                                   status=status
+                                   )
         url = 'volumes/%s/action' % str(volume_id)
-        resp, body = self.post(url, str(Document(post_body)))
+        resp, body = self.post(url, str(common.Document(post_body)))
         if body:
-            body = xml_to_json(etree.fromstring(body))
+            body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def volume_begin_detaching(self, volume_id):
         """Volume Begin Detaching."""
-        post_body = Element("os-begin_detaching")
+        post_body = common.Element("os-begin_detaching")
         url = 'volumes/%s/action' % str(volume_id)
-        resp, body = self.post(url, str(Document(post_body)))
+        resp, body = self.post(url, str(common.Document(post_body)))
         if body:
-            body = xml_to_json(etree.fromstring(body))
+            body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def volume_roll_detaching(self, volume_id):
         """Volume Roll Detaching."""
-        post_body = Element("os-roll_detaching")
+        post_body = common.Element("os-roll_detaching")
         url = 'volumes/%s/action' % str(volume_id)
-        resp, body = self.post(url, str(Document(post_body)))
+        resp, body = self.post(url, str(common.Document(post_body)))
         if body:
-            body = xml_to_json(etree.fromstring(body))
+            body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def reserve_volume(self, volume_id):
         """Reserves a volume."""
-        post_body = Element("os-reserve")
+        post_body = common.Element("os-reserve")
         url = 'volumes/%s/action' % str(volume_id)
-        resp, body = self.post(url, str(Document(post_body)))
+        resp, body = self.post(url, str(common.Document(post_body)))
         if body:
-            body = xml_to_json(etree.fromstring(body))
+            body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def unreserve_volume(self, volume_id):
         """Restore a reserved volume ."""
-        post_body = Element("os-unreserve")
+        post_body = common.Element("os-unreserve")
         url = 'volumes/%s/action' % str(volume_id)
-        resp, body = self.post(url, str(Document(post_body)))
+        resp, body = self.post(url, str(common.Document(post_body)))
         if body:
-            body = xml_to_json(etree.fromstring(body))
+            body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def create_volume_transfer(self, vol_id, name=None):
         """Create a volume transfer."""
-        post_body = Element("transfer",
-                            volume_id=vol_id)
+        post_body = common.Element("transfer", volume_id=vol_id)
         if name:
             post_body.add_attr('name', name)
         resp, body = self.post('os-volume-transfer',
-                               str(Document(post_body)))
-        volume = xml_to_json(etree.fromstring(body))
+                               str(common.Document(post_body)))
+        volume = common.xml_to_json(etree.fromstring(body))
         return resp, volume
 
     def get_volume_transfer(self, transfer_id):
         """Returns the details of a volume transfer."""
         url = "os-volume-transfer/%s" % str(transfer_id)
         resp, body = self.get(url)
-        volume = xml_to_json(etree.fromstring(body))
+        volume = common.xml_to_json(etree.fromstring(body))
         return resp, volume
 
     def list_volume_transfers(self, params=None):
@@ -321,7 +316,7 @@
             tag = child.tag
             if tag.startswith("{"):
                 tag = tag.split("}", 1)
-            vol[tag] = xml_to_json(child)
+            vol[tag] = common.xml_to_json(child)
         return vol
 
     def delete_volume_transfer(self, transfer_id):
@@ -330,36 +325,36 @@
 
     def accept_volume_transfer(self, transfer_id, transfer_auth_key):
         """Accept a volume transfer."""
-        post_body = Element("accept", auth_key=transfer_auth_key)
+        post_body = common.Element("accept", auth_key=transfer_auth_key)
         url = 'os-volume-transfer/%s/accept' % transfer_id
-        resp, body = self.post(url, str(Document(post_body)))
-        volume = xml_to_json(etree.fromstring(body))
+        resp, body = self.post(url, str(common.Document(post_body)))
+        volume = common.xml_to_json(etree.fromstring(body))
         return resp, volume
 
     def update_volume_readonly(self, volume_id, readonly):
         """Update the Specified Volume readonly."""
-        post_body = Element("os-update_readonly_flag",
-                            readonly=readonly)
+        post_body = common.Element("os-update_readonly_flag",
+                                   readonly=readonly)
         url = 'volumes/%s/action' % str(volume_id)
-        resp, body = self.post(url, str(Document(post_body)))
+        resp, body = self.post(url, str(common.Document(post_body)))
         if body:
-            body = xml_to_json(etree.fromstring(body))
+            body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def force_delete_volume(self, volume_id):
         """Force Delete Volume."""
-        post_body = Element("os-force_delete")
+        post_body = common.Element("os-force_delete")
         url = 'volumes/%s/action' % str(volume_id)
-        resp, body = self.post(url, str(Document(post_body)))
+        resp, body = self.post(url, str(common.Document(post_body)))
         if body:
-            body = xml_to_json(etree.fromstring(body))
+            body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def _metadata_body(self, meta):
-        post_body = Element('metadata')
+        post_body = common.Element('metadata')
         for k, v in meta.items():
-            data = Element('meta', key=k)
-            data.append(Text(v))
+            data = common.Element('meta', key=k)
+            data.append(common.Text(v))
             post_body.append(data)
         return post_body
 
@@ -374,7 +369,7 @@
         """Create metadata for the volume."""
         post_body = self._metadata_body(metadata)
         resp, body = self.post('volumes/%s/metadata' % volume_id,
-                               str(Document(post_body)))
+                               str(common.Document(post_body)))
         body = self._parse_key_value(etree.fromstring(body))
         return resp, body
 
@@ -389,18 +384,18 @@
         """Update metadata for the volume."""
         put_body = self._metadata_body(metadata)
         url = "volumes/%s/metadata" % str(volume_id)
-        resp, body = self.put(url, str(Document(put_body)))
+        resp, body = self.put(url, str(common.Document(put_body)))
         body = self._parse_key_value(etree.fromstring(body))
         return resp, body
 
     def update_volume_metadata_item(self, volume_id, id, meta_item):
         """Update metadata item for the volume."""
         for k, v in meta_item.items():
-            put_body = Element('meta', key=k)
-            put_body.append(Text(v))
+            put_body = common.Element('meta', key=k)
+            put_body.append(common.Text(v))
         url = "volumes/%s/metadata/%s" % (str(volume_id), str(id))
-        resp, body = self.put(url, str(Document(put_body)))
-        body = xml_to_json(etree.fromstring(body))
+        resp, body = self.put(url, str(common.Document(put_body)))
+        body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def delete_volume_metadata_item(self, volume_id, id):
diff --git a/tempest/services/volume/xml/admin/volume_hosts_client.py b/tempest/services/volume/xml/admin/volume_hosts_client.py
index fb84c83..e34b9f0 100644
--- a/tempest/services/volume/xml/admin/volume_hosts_client.py
+++ b/tempest/services/volume/xml/admin/volume_hosts_client.py
@@ -19,7 +19,7 @@
 
 from tempest.common import rest_client
 from tempest import config
-from tempest.services.compute.xml.common import xml_to_json
+from tempest.services.compute.xml import common
 
 CONF = config.CONF
 
@@ -58,7 +58,7 @@
         for child in node.getchildren():
             tag_list = child.tag.split('}', 1)
             if tag_list[0] == "host":
-                array.append(xml_to_json(child))
+                array.append(common.xml_to_json(child))
         return array
 
     def list_hosts(self, params=None):
diff --git a/tempest/services/volume/xml/admin/volume_quotas_client.py b/tempest/services/volume/xml/admin/volume_quotas_client.py
new file mode 100644
index 0000000..d2eac34
--- /dev/null
+++ b/tempest/services/volume/xml/admin/volume_quotas_client.py
@@ -0,0 +1,70 @@
+# Copyright (C) 2014 eNovance SAS <licensing@enovance.com>
+#
+# Author: Sylvain Baubeau <sylvain.baubeau@enovance.com>
+#
+#    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 ast import literal_eval
+from lxml import etree
+
+from tempest import config
+from tempest.services.compute.xml import common as xml
+from tempest.services.volume.json.admin import volume_quotas_client
+
+CONF = config.CONF
+
+
+class VolumeQuotasClientXML(volume_quotas_client.VolumeQuotasClientJSON):
+    """
+    Client class to send CRUD Volume Quotas API requests to a Cinder endpoint
+    """
+
+    TYPE = "xml"
+
+    def _format_quota(self, q):
+        quota = {}
+        for k, v in q.items():
+            try:
+                v = literal_eval(v)
+            except (ValueError, SyntaxError):
+                pass
+
+            quota[k] = v
+
+        return quota
+
+    def get_quota_usage(self, tenant_id):
+        """List the quota set for a tenant."""
+
+        resp, body = self.get_quota_set(tenant_id, params={'usage': True})
+        return resp, self._format_quota(body)
+
+    def update_quota_set(self, tenant_id, gigabytes=None, volumes=None,
+                         snapshots=None):
+        post_body = {}
+        element = xml.Element("quota_set")
+
+        if gigabytes is not None:
+            post_body['gigabytes'] = gigabytes
+
+        if volumes is not None:
+            post_body['volumes'] = volumes
+
+        if snapshots is not None:
+            post_body['snapshots'] = snapshots
+
+        xml.deep_dict_to_xml(element, post_body)
+        resp, body = self.put('os-quota-sets/%s' % tenant_id,
+                              str(xml.Document(element)))
+        body = xml.xml_to_json(etree.fromstring(body))
+        return resp, self._format_quota(body)
diff --git a/tempest/services/volume/xml/admin/volume_types_client.py b/tempest/services/volume/xml/admin/volume_types_client.py
index 77bafec..1fa3e73 100644
--- a/tempest/services/volume/xml/admin/volume_types_client.py
+++ b/tempest/services/volume/xml/admin/volume_types_client.py
@@ -20,11 +20,7 @@
 from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
-from tempest.services.compute.xml.common import Document
-from tempest.services.compute.xml.common import Element
-from tempest.services.compute.xml.common import Text
-from tempest.services.compute.xml.common import xml_to_json
-from tempest.services.compute.xml.common import XMLNS_11
+from tempest.services.compute.xml import common
 
 CONF = config.CONF
 
@@ -53,7 +49,7 @@
                                                 meta.text)
                                                for meta in list(child))
             else:
-                vol_type[tag] = xml_to_json(child)
+                vol_type[tag] = common.xml_to_json(child)
             return vol_type
 
     def _parse_volume_type_extra_specs(self, body):
@@ -64,7 +60,7 @@
             if tag.startswith("{"):
                 ns, tag = tag.split("}", 1)
             else:
-                extra_spec[tag] = xml_to_json(child)
+                extra_spec[tag] = common.xml_to_json(child)
             return extra_spec
 
     def list_volume_types(self, params=None):
@@ -95,22 +91,22 @@
         Following optional keyword arguments are accepted:
         extra_specs: A dictionary of values to be used as extra_specs.
         """
-        vol_type = Element("volume_type", xmlns=XMLNS_11)
+        vol_type = common.Element("volume_type", xmlns=common.XMLNS_11)
         if name:
             vol_type.add_attr('name', name)
 
         extra_specs = kwargs.get('extra_specs')
         if extra_specs:
-            _extra_specs = Element('extra_specs')
+            _extra_specs = common.Element('extra_specs')
             vol_type.append(_extra_specs)
             for key, value in extra_specs.items():
-                spec = Element('extra_spec')
+                spec = common.Element('extra_spec')
                 spec.add_attr('key', key)
-                spec.append(Text(value))
+                spec.append(common.Text(value))
                 _extra_specs.append(spec)
 
-        resp, body = self.post('types', str(Document(vol_type)))
-        body = xml_to_json(etree.fromstring(body))
+        resp, body = self.post('types', str(common.Document(vol_type)))
+        body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def delete_volume_type(self, type_id):
@@ -147,21 +143,21 @@
         extra_specs: A dictionary of values to be used as extra_specs.
         """
         url = "types/%s/extra_specs" % str(vol_type_id)
-        extra_specs = Element("extra_specs", xmlns=XMLNS_11)
+        extra_specs = common.Element("extra_specs", xmlns=common.XMLNS_11)
         if extra_spec:
             if isinstance(extra_spec, list):
                 extra_specs.append(extra_spec)
             else:
                 for key, value in extra_spec.items():
-                    spec = Element('extra_spec')
+                    spec = common.Element('extra_spec')
                     spec.add_attr('key', key)
-                    spec.append(Text(value))
+                    spec.append(common.Text(value))
                     extra_specs.append(spec)
         else:
             extra_specs = None
 
-        resp, body = self.post(url, str(Document(extra_specs)))
-        body = xml_to_json(etree.fromstring(body))
+        resp, body = self.post(url, str(common.Document(extra_specs)))
+        body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def delete_volume_type_extra_specs(self, vol_id, extra_spec_name):
@@ -180,17 +176,17 @@
         """
         url = "types/%s/extra_specs/%s" % (str(vol_type_id),
                                            str(extra_spec_name))
-        extra_specs = Element("extra_specs", xmlns=XMLNS_11)
+        extra_specs = common.Element("extra_specs", xmlns=common.XMLNS_11)
 
         if extra_spec is not None:
             for key, value in extra_spec.items():
-                spec = Element('extra_spec')
+                spec = common.Element('extra_spec')
                 spec.add_attr('key', key)
-                spec.append(Text(value))
+                spec.append(common.Text(value))
                 extra_specs.append(spec)
 
-        resp, body = self.put(url, str(Document(extra_specs)))
-        body = xml_to_json(etree.fromstring(body))
+        resp, body = self.put(url, str(common.Document(extra_specs)))
+        body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def is_resource_deleted(self, id):
diff --git a/tempest/services/volume/xml/extensions_client.py b/tempest/services/volume/xml/extensions_client.py
index 1ea974f..4861733 100644
--- a/tempest/services/volume/xml/extensions_client.py
+++ b/tempest/services/volume/xml/extensions_client.py
@@ -17,7 +17,7 @@
 
 from tempest.common import rest_client
 from tempest import config
-from tempest.services.compute.xml.common import xml_to_json
+from tempest.services.compute.xml import common
 
 CONF = config.CONF
 
@@ -32,7 +32,7 @@
     def _parse_array(self, node):
         array = []
         for child in node:
-            array.append(xml_to_json(child))
+            array.append(common.xml_to_json(child))
         return array
 
     def list_extensions(self):
diff --git a/tempest/services/volume/xml/snapshots_client.py b/tempest/services/volume/xml/snapshots_client.py
index 458001b..9ad86d2 100644
--- a/tempest/services/volume/xml/snapshots_client.py
+++ b/tempest/services/volume/xml/snapshots_client.py
@@ -19,11 +19,7 @@
 from tempest import config
 from tempest import exceptions
 from tempest.openstack.common import log as logging
-from tempest.services.compute.xml.common import Document
-from tempest.services.compute.xml.common import Element
-from tempest.services.compute.xml.common import Text
-from tempest.services.compute.xml.common import xml_to_json
-from tempest.services.compute.xml.common import XMLNS_11
+from tempest.services.compute.xml import common
 
 CONF = config.CONF
 
@@ -52,7 +48,7 @@
         body = etree.fromstring(body)
         snapshots = []
         for snap in body:
-            snapshots.append(xml_to_json(snap))
+            snapshots.append(common.xml_to_json(snap))
         return resp, snapshots
 
     def list_snapshots_with_detail(self, params=None):
@@ -66,7 +62,7 @@
         body = etree.fromstring(body)
         snapshots = []
         for snap in body:
-            snapshots.append(xml_to_json(snap))
+            snapshots.append(common.xml_to_json(snap))
         return resp, snapshots
 
     def get_snapshot(self, snapshot_id):
@@ -74,7 +70,7 @@
         url = "snapshots/%s" % str(snapshot_id)
         resp, body = self.get(url)
         body = etree.fromstring(body)
-        return resp, xml_to_json(body)
+        return resp, common.xml_to_json(body)
 
     def create_snapshot(self, volume_id, **kwargs):
         """Creates a new snapshot.
@@ -84,20 +80,22 @@
         display_description: User friendly snapshot description.
         """
         # NOTE(afazekas): it should use the volume namespace
-        snapshot = Element("snapshot", xmlns=XMLNS_11, volume_id=volume_id)
+        snapshot = common.Element("snapshot", xmlns=common.XMLNS_11,
+                                  volume_id=volume_id)
         for key, value in kwargs.items():
             snapshot.add_attr(key, value)
-        resp, body = self.post('snapshots', str(Document(snapshot)))
-        body = xml_to_json(etree.fromstring(body))
+        resp, body = self.post('snapshots',
+                               str(common.Document(snapshot)))
+        body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def update_snapshot(self, snapshot_id, **kwargs):
         """Updates a snapshot."""
-        put_body = Element("snapshot", xmlns=XMLNS_11, **kwargs)
+        put_body = common.Element("snapshot", xmlns=common.XMLNS_11, **kwargs)
 
         resp, body = self.put('snapshots/%s' % snapshot_id,
-                              str(Document(put_body)))
-        body = xml_to_json(etree.fromstring(body))
+                              str(common.Document(put_body)))
+        body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     # NOTE(afazekas): just for the wait function
@@ -150,32 +148,30 @@
 
     def reset_snapshot_status(self, snapshot_id, status):
         """Reset the specified snapshot's status."""
-        post_body = Element("os-reset_status",
-                            status=status
-                            )
+        post_body = common.Element("os-reset_status", status=status)
         url = 'snapshots/%s/action' % str(snapshot_id)
-        resp, body = self.post(url, str(Document(post_body)))
+        resp, body = self.post(url, str(common.Document(post_body)))
         if body:
-            body = xml_to_json(etree.fromstring(body))
+            body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def update_snapshot_status(self, snapshot_id, status, progress):
         """Update the specified snapshot's status."""
-        post_body = Element("os-update_snapshot_status",
-                            status=status,
-                            progress=progress
-                            )
+        post_body = common.Element("os-update_snapshot_status",
+                                   status=status,
+                                   progress=progress
+                                   )
         url = 'snapshots/%s/action' % str(snapshot_id)
-        resp, body = self.post(url, str(Document(post_body)))
+        resp, body = self.post(url, str(common.Document(post_body)))
         if body:
-            body = xml_to_json(etree.fromstring(body))
+            body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def _metadata_body(self, meta):
-        post_body = Element('metadata')
+        post_body = common.Element('metadata')
         for k, v in meta.items():
-            data = Element('meta', key=k)
-            data.append(Text(v))
+            data = common.Element('meta', key=k)
+            data.append(common.Text(v))
             post_body.append(data)
         return post_body
 
@@ -190,7 +186,7 @@
         """Create metadata for the snapshot."""
         post_body = self._metadata_body(metadata)
         resp, body = self.post('snapshots/%s/metadata' % snapshot_id,
-                               str(Document(post_body)))
+                               str(common.Document(post_body)))
         body = self._parse_key_value(etree.fromstring(body))
         return resp, body
 
@@ -205,18 +201,18 @@
         """Update metadata for the snapshot."""
         put_body = self._metadata_body(metadata)
         url = "snapshots/%s/metadata" % str(snapshot_id)
-        resp, body = self.put(url, str(Document(put_body)))
+        resp, body = self.put(url, str(common.Document(put_body)))
         body = self._parse_key_value(etree.fromstring(body))
         return resp, body
 
     def update_snapshot_metadata_item(self, snapshot_id, id, meta_item):
         """Update metadata item for the snapshot."""
         for k, v in meta_item.items():
-            put_body = Element('meta', key=k)
-            put_body.append(Text(v))
+            put_body = common.Element('meta', key=k)
+            put_body.append(common.Text(v))
         url = "snapshots/%s/metadata/%s" % (str(snapshot_id), str(id))
-        resp, body = self.put(url, str(Document(put_body)))
-        body = xml_to_json(etree.fromstring(body))
+        resp, body = self.put(url, str(common.Document(put_body)))
+        body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def delete_snapshot_metadata_item(self, snapshot_id, id):
@@ -226,9 +222,9 @@
 
     def force_delete_snapshot(self, snapshot_id):
         """Force Delete Snapshot."""
-        post_body = Element("os-force_delete")
+        post_body = common.Element("os-force_delete")
         url = 'snapshots/%s/action' % str(snapshot_id)
-        resp, body = self.post(url, str(Document(post_body)))
+        resp, body = self.post(url, str(common.Document(post_body)))
         if body:
-            body = xml_to_json(etree.fromstring(body))
+            body = common.xml_to_json(etree.fromstring(body))
         return resp, body
diff --git a/tempest/services/volume/xml/volumes_client.py b/tempest/services/volume/xml/volumes_client.py
index aef1e3c..8e886ce 100644
--- a/tempest/services/volume/xml/volumes_client.py
+++ b/tempest/services/volume/xml/volumes_client.py
@@ -17,16 +17,12 @@
 import urllib
 
 from lxml import etree
-from xml.sax.saxutils import escape
+from xml.sax import saxutils
 
 from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
-from tempest.services.compute.xml.common import Document
-from tempest.services.compute.xml.common import Element
-from tempest.services.compute.xml.common import Text
-from tempest.services.compute.xml.common import xml_to_json
-from tempest.services.compute.xml.common import XMLNS_11
+from tempest.services.compute.xml import common
 
 CONF = config.CONF
 
@@ -55,7 +51,7 @@
                                        meta.text) for meta in
                                        child.getchildren())
             else:
-                vol[tag] = xml_to_json(child)
+                vol[tag] = common.xml_to_json(child)
         return vol
 
     def get_attachment_from_volume(self, volume):
@@ -135,15 +131,15 @@
                          image
         """
         # NOTE(afazekas): it should use a volume namespace
-        volume = Element("volume", xmlns=XMLNS_11, size=size)
+        volume = common.Element("volume", xmlns=common.XMLNS_11, size=size)
 
         if 'metadata' in kwargs:
-            _metadata = Element('metadata')
+            _metadata = common.Element('metadata')
             volume.append(_metadata)
             for key, value in kwargs['metadata'].items():
-                meta = Element('meta')
+                meta = common.Element('meta')
                 meta.add_attr('key', key)
-                meta.append(Text(value))
+                meta.append(common.Text(value))
                 _metadata.append(meta)
             attr_to_add = kwargs.copy()
             del attr_to_add['metadata']
@@ -153,17 +149,17 @@
         for key, value in attr_to_add.items():
             volume.add_attr(key, value)
 
-        resp, body = self.post('volumes', str(Document(volume)))
-        body = xml_to_json(etree.fromstring(body))
+        resp, body = self.post('volumes', str(common.Document(volume)))
+        body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def update_volume(self, volume_id, **kwargs):
         """Updates the Specified Volume."""
-        put_body = Element("volume", xmlns=XMLNS_11, **kwargs)
+        put_body = common.Element("volume", xmlns=common.XMLNS_11, **kwargs)
 
         resp, body = self.put('volumes/%s' % volume_id,
-                              str(Document(put_body)))
-        body = xml_to_json(etree.fromstring(body))
+                              str(common.Document(put_body)))
+        body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def delete_volume(self, volume_id):
@@ -199,108 +195,108 @@
 
     def attach_volume(self, volume_id, instance_uuid, mountpoint):
         """Attaches a volume to a given instance on a given mountpoint."""
-        post_body = Element("os-attach",
-                            instance_uuid=instance_uuid,
-                            mountpoint=mountpoint
-                            )
+        post_body = common.Element("os-attach",
+                                   instance_uuid=instance_uuid,
+                                   mountpoint=mountpoint
+                                   )
         url = 'volumes/%s/action' % str(volume_id)
-        resp, body = self.post(url, str(Document(post_body)))
+        resp, body = self.post(url, str(common.Document(post_body)))
         if body:
-            body = xml_to_json(etree.fromstring(body))
+            body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def detach_volume(self, volume_id):
         """Detaches a volume from an instance."""
-        post_body = Element("os-detach")
+        post_body = common.Element("os-detach")
         url = 'volumes/%s/action' % str(volume_id)
-        resp, body = self.post(url, str(Document(post_body)))
+        resp, body = self.post(url, str(common.Document(post_body)))
         if body:
-            body = xml_to_json(etree.fromstring(body))
+            body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def upload_volume(self, volume_id, image_name, disk_format):
         """Uploads a volume in Glance."""
-        post_body = Element("os-volume_upload_image",
-                            image_name=image_name,
-                            disk_format=disk_format)
+        post_body = common.Element("os-volume_upload_image",
+                                   image_name=image_name,
+                                   disk_format=disk_format)
         url = 'volumes/%s/action' % str(volume_id)
-        resp, body = self.post(url, str(Document(post_body)))
-        volume = xml_to_json(etree.fromstring(body))
+        resp, body = self.post(url, str(common.Document(post_body)))
+        volume = common.xml_to_json(etree.fromstring(body))
         return resp, volume
 
     def extend_volume(self, volume_id, extend_size):
         """Extend a volume."""
-        post_body = Element("os-extend",
-                            new_size=extend_size)
+        post_body = common.Element("os-extend",
+                                   new_size=extend_size)
         url = 'volumes/%s/action' % str(volume_id)
-        resp, body = self.post(url, str(Document(post_body)))
+        resp, body = self.post(url, str(common.Document(post_body)))
         if body:
-            body = xml_to_json(etree.fromstring(body))
+            body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def reset_volume_status(self, volume_id, status):
         """Reset the Specified Volume's Status."""
-        post_body = Element("os-reset_status",
-                            status=status
-                            )
+        post_body = common.Element("os-reset_status",
+                                   status=status
+                                   )
         url = 'volumes/%s/action' % str(volume_id)
-        resp, body = self.post(url, str(Document(post_body)))
+        resp, body = self.post(url, str(common.Document(post_body)))
         if body:
-            body = xml_to_json(etree.fromstring(body))
+            body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def volume_begin_detaching(self, volume_id):
         """Volume Begin Detaching."""
-        post_body = Element("os-begin_detaching")
+        post_body = common.Element("os-begin_detaching")
         url = 'volumes/%s/action' % str(volume_id)
-        resp, body = self.post(url, str(Document(post_body)))
+        resp, body = self.post(url, str(common.Document(post_body)))
         if body:
-            body = xml_to_json(etree.fromstring(body))
+            body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def volume_roll_detaching(self, volume_id):
         """Volume Roll Detaching."""
-        post_body = Element("os-roll_detaching")
+        post_body = common.Element("os-roll_detaching")
         url = 'volumes/%s/action' % str(volume_id)
-        resp, body = self.post(url, str(Document(post_body)))
+        resp, body = self.post(url, str(common.Document(post_body)))
         if body:
-            body = xml_to_json(etree.fromstring(body))
+            body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def reserve_volume(self, volume_id):
         """Reserves a volume."""
-        post_body = Element("os-reserve")
+        post_body = common.Element("os-reserve")
         url = 'volumes/%s/action' % str(volume_id)
-        resp, body = self.post(url, str(Document(post_body)))
+        resp, body = self.post(url, str(common.Document(post_body)))
         if body:
-            body = xml_to_json(etree.fromstring(body))
+            body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def unreserve_volume(self, volume_id):
         """Restore a reserved volume ."""
-        post_body = Element("os-unreserve")
+        post_body = common.Element("os-unreserve")
         url = 'volumes/%s/action' % str(volume_id)
-        resp, body = self.post(url, str(Document(post_body)))
+        resp, body = self.post(url, str(common.Document(post_body)))
         if body:
-            body = xml_to_json(etree.fromstring(body))
+            body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def create_volume_transfer(self, vol_id, display_name=None):
         """Create a volume transfer."""
-        post_body = Element("transfer",
-                            volume_id=vol_id)
+        post_body = common.Element("transfer",
+                                   volume_id=vol_id)
         if display_name:
             post_body.add_attr('name', display_name)
         resp, body = self.post('os-volume-transfer',
-                               str(Document(post_body)))
-        volume = xml_to_json(etree.fromstring(body))
+                               str(common.Document(post_body)))
+        volume = common.xml_to_json(etree.fromstring(body))
         return resp, volume
 
     def get_volume_transfer(self, transfer_id):
         """Returns the details of a volume transfer."""
         url = "os-volume-transfer/%s" % str(transfer_id)
         resp, body = self.get(url)
-        volume = xml_to_json(etree.fromstring(body))
+        volume = common.xml_to_json(etree.fromstring(body))
         return resp, volume
 
     def list_volume_transfers(self, params=None):
@@ -322,7 +318,7 @@
             tag = child.tag
             if tag.startswith("{"):
                 tag = tag.split("}", 1)
-            vol[tag] = xml_to_json(child)
+            vol[tag] = common.xml_to_json(child)
         return vol
 
     def delete_volume_transfer(self, transfer_id):
@@ -331,37 +327,37 @@
 
     def accept_volume_transfer(self, transfer_id, transfer_auth_key):
         """Accept a volume transfer."""
-        post_body = Element("accept", auth_key=transfer_auth_key)
+        post_body = common.Element("accept", auth_key=transfer_auth_key)
         url = 'os-volume-transfer/%s/accept' % transfer_id
-        resp, body = self.post(url, str(Document(post_body)))
-        volume = xml_to_json(etree.fromstring(body))
+        resp, body = self.post(url, str(common.Document(post_body)))
+        volume = common.xml_to_json(etree.fromstring(body))
         return resp, volume
 
     def update_volume_readonly(self, volume_id, readonly):
         """Update the Specified Volume readonly."""
-        post_body = Element("os-update_readonly_flag",
-                            readonly=readonly)
+        post_body = common.Element("os-update_readonly_flag",
+                                   readonly=readonly)
         url = 'volumes/%s/action' % str(volume_id)
-        resp, body = self.post(url, str(Document(post_body)))
+        resp, body = self.post(url, str(common.Document(post_body)))
         if body:
-            body = xml_to_json(etree.fromstring(body))
+            body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def force_delete_volume(self, volume_id):
         """Force Delete Volume."""
-        post_body = Element("os-force_delete")
+        post_body = common.Element("os-force_delete")
         url = 'volumes/%s/action' % str(volume_id)
-        resp, body = self.post(url, str(Document(post_body)))
+        resp, body = self.post(url, str(common.Document(post_body)))
         if body:
-            body = xml_to_json(etree.fromstring(body))
+            body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def _metadata_body(self, meta):
-        post_body = Element('metadata')
+        post_body = common.Element('metadata')
         for k, v in meta.items():
-            data = Element('meta', key=k)
+            data = common.Element('meta', key=k)
             # Escape value to allow for special XML chars
-            data.append(Text(escape(v)))
+            data.append(common.Text(saxutils.escape(v)))
             post_body.append(data)
         return post_body
 
@@ -376,7 +372,7 @@
         """Create metadata for the volume."""
         post_body = self._metadata_body(metadata)
         resp, body = self.post('volumes/%s/metadata' % volume_id,
-                               str(Document(post_body)))
+                               str(common.Document(post_body)))
         body = self._parse_key_value(etree.fromstring(body))
         return resp, body
 
@@ -391,18 +387,18 @@
         """Update metadata for the volume."""
         put_body = self._metadata_body(metadata)
         url = "volumes/%s/metadata" % str(volume_id)
-        resp, body = self.put(url, str(Document(put_body)))
+        resp, body = self.put(url, str(common.Document(put_body)))
         body = self._parse_key_value(etree.fromstring(body))
         return resp, body
 
     def update_volume_metadata_item(self, volume_id, id, meta_item):
         """Update metadata item for the volume."""
         for k, v in meta_item.items():
-            put_body = Element('meta', key=k)
-            put_body.append(Text(v))
+            put_body = common.Element('meta', key=k)
+            put_body.append(common.Text(v))
         url = "volumes/%s/metadata/%s" % (str(volume_id), str(id))
-        resp, body = self.put(url, str(Document(put_body)))
-        body = xml_to_json(etree.fromstring(body))
+        resp, body = self.put(url, str(common.Document(put_body)))
+        body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def delete_volume_metadata_item(self, volume_id, id):
diff --git a/tempest/stress/driver.py b/tempest/stress/driver.py
index 3715636..9660081 100644
--- a/tempest/stress/driver.py
+++ b/tempest/stress/driver.py
@@ -17,6 +17,8 @@
 import signal
 import time
 
+from six import moves
+
 from tempest import clients
 from tempest.common import ssh
 from tempest.common.utils import data_utils
@@ -128,7 +130,7 @@
             manager = admin_manager
         else:
             manager = clients.Manager()
-        for p_number in xrange(test.get('threads', default_thread_num)):
+        for p_number in moves.xrange(test.get('threads', default_thread_num)):
             if test.get('use_isolated_tenants', False):
                 username = data_utils.rand_name("stress_user")
                 tenant_name = data_utils.rand_name("stress_tenant")
diff --git a/tempest/test.py b/tempest/test.py
index 22aa3f2..d358510 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -23,15 +23,15 @@
 import uuid
 
 import fixtures
-import nose.plugins.attrib
 import testresources
 import testtools
 
 from tempest import clients
-from tempest.common import generate_json
+import tempest.common.generator.valid_generator as valid
 from tempest.common import isolated_creds
 from tempest import config
 from tempest import exceptions
+from tempest.openstack.common import importutils
 from tempest.openstack.common import log as logging
 
 LOG = logging.getLogger(__name__)
@@ -43,11 +43,10 @@
 
 
 def attr(*args, **kwargs):
-    """A decorator which applies the nose and testtools attr decorator
+    """A decorator which applies the  testtools attr decorator
 
-    This decorator applies the nose attr decorator as well as the
-    the testtools.testcase.attr if it is in the list of attributes
-    to testtools we want to apply.
+    This decorator applies the testtools.testcase.attr if it is in the list of
+    attributes to testtools we want to apply.
     """
 
     def decorator(f):
@@ -60,7 +59,7 @@
                 f = testtools.testcase.attr(attr)(f)
                 if attr == 'smoke':
                     f = testtools.testcase.attr('gate')(f)
-        return nose.plugins.attrib.attr(*args, **kwargs)(f)
+        return f
 
     return decorator
 
@@ -194,40 +193,6 @@
         return True
     return False
 
-# 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
-# exception, depending on what it can find. Python <2.7 doesn't have
-# unittest.case.SkipTest; so if unittest2 is not installed it falls
-# back to the internal class.
-#
-# The current nose skip plugin will decide to raise either
-# unittest.case.SkipTest or its own internal exception; it does not
-# look for unittest2 or the internal unittest exception.  Thus we must
-# monkey-patch testtools.TestCase.skipException to be the exception
-# the nose skip plugin expects.
-#
-# However, with the switch to testr nose may not be available, so we
-# require you to opt-in to this fix with an environment variable.
-#
-# This is temporary until upstream nose starts looking for unittest2
-# as testtools does; we can then remove this and ensure unittest2 is
-# available for older pythons; then nose and testtools will agree
-# unittest2.case.SkipTest is the one-true skip test exception.
-#
-#   https://review.openstack.org/#/c/33056
-#   https://github.com/nose-devs/nose/pull/699
-if 'TEMPEST_PY26_NOSE_COMPAT' in os.environ:
-    try:
-        import unittest.case.SkipTest
-        # convince pep8 we're using the import...
-        if unittest.case.SkipTest:
-            pass
-        raise RuntimeError("You have unittest.case.SkipTest; "
-                           "no need to override")
-    except ImportError:
-        LOG.info("Overriding skipException to nose SkipTest")
-        testtools.TestCase.skipException = nose.plugins.skip.SkipTest
 
 at_exit_set = set()
 
@@ -388,6 +353,12 @@
                 'subnet': subnet,
                 'dhcp': dhcp}
 
+    def assertEmpty(self, list, msg=None):
+        self.assertTrue(len(list) == 0, msg)
+
+    def assertNotEmpty(self, list, msg=None):
+        self.assertTrue(len(list) > 0, msg)
+
 
 class NegativeAutoTest(BaseTestCase):
 
@@ -398,6 +369,9 @@
         super(NegativeAutoTest, cls).setUpClass()
         os = cls.get_client_manager()
         cls.client = os.negative_client
+        os_admin = clients.AdminManager(interface=cls._interface,
+                                        service=cls._service)
+        cls.admin_client = os_admin.negative_client
 
     @staticmethod
     def load_schema(file):
@@ -436,7 +410,8 @@
         """
         description = NegativeAutoTest.load_schema(description_file)
         LOG.debug(description)
-        generate_json.validate_negative_test_schema(description)
+        generator = importutils.import_class(CONF.negative.test_generator)()
+        generator.validate_schema(description)
         schema = description.get("json-schema", None)
         resources = description.get("resources", [])
         scenario_list = []
@@ -452,10 +427,13 @@
                                              "expected_result": expected_result
                                              }))
         if schema is not None:
-            for invalid in generate_json.generate_invalid(schema):
-                scenario_list.append((invalid[0],
-                                      {"schema": invalid[1],
-                                       "expected_result": invalid[2]}))
+            for name, schema, expected_result in generator.generate(schema):
+                if (expected_result is None and
+                    "default_result_code" in description):
+                    expected_result = description["default_result_code"]
+                scenario_list.append((name,
+                                      {"schema": schema,
+                                       "expected_result": expected_result}))
         LOG.debug(scenario_list)
         return scenario_list
 
@@ -495,16 +473,21 @@
             # Note(mkoderer): The resources list already contains an invalid
             # entry (see get_resource).
             # We just send a valid json-schema with it
-            valid = None
+            valid_schema = None
             schema = description.get("json-schema", None)
             if schema:
-                valid = generate_json.generate_valid(schema)
-            new_url, body = self._http_arguments(valid, url, method)
+                valid_schema = \
+                    valid.ValidTestGenerator().generate_valid(schema)
+            new_url, body = self._http_arguments(valid_schema, url, method)
         elif hasattr(self, "schema"):
             new_url, body = self._http_arguments(self.schema, url, method)
 
-        resp, resp_body = self.client.send_request(method, new_url,
-                                                   resources, body=body)
+        if "admin_client" in description and description["admin_client"]:
+            client = self.admin_client
+        else:
+            client = self.client
+        resp, resp_body = client.send_request(method, new_url,
+                                              resources, body=body)
         self._check_negative_response(resp.status, resp_body)
 
     def _http_arguments(self, json_dict, url, method):
diff --git a/tempest/tests/fake_config.py b/tempest/tests/fake_config.py
index 41b0558..e941606 100644
--- a/tempest/tests/fake_config.py
+++ b/tempest/tests/fake_config.py
@@ -43,6 +43,10 @@
         swift = True
         horizon = True
 
+    class fake_negative(object):
+        test_generator = 'tempest.common.' \
+            'generator.negative_generator.NegativeTestGenerator'
+
     compute_feature_enabled = fake_compute_feature_enabled()
     volume_feature_enabled = fake_default_feature_enabled()
     network_feature_enabled = fake_default_feature_enabled()
@@ -52,3 +56,5 @@
 
     compute = fake_compute()
     identity = fake_identity()
+
+    negative = fake_negative()
diff --git a/tempest/tests/fake_identity.py b/tempest/tests/fake_identity.py
index ea2bd44..058c9c2 100644
--- a/tempest/tests/fake_identity.py
+++ b/tempest/tests/fake_identity.py
@@ -25,16 +25,16 @@
 COMPUTE_ENDPOINTS_V2 = {
     "endpoints": [
         {
-            "adminURL": "http://fake_url/api/admin",
+            "adminURL": "http://fake_url/v2/first_endpoint/admin",
             "region": "NoMatchRegion",
-            "internalURL": "http://fake_url/api/internal",
-            "publicURL": "http://fake_url/api/public"
+            "internalURL": "http://fake_url/v2/first_endpoint/internal",
+            "publicURL": "http://fake_url/v2/first_endpoint/public"
         },
         {
-            "adminURL": "http://fake_url/api/admin",
+            "adminURL": "http://fake_url/v2/second_endpoint/admin",
             "region": "FakeRegion",
-            "internalURL": "http://fake_url/api/internal",
-            "publicURL": "http://fake_url/api/public"
+            "internalURL": "http://fake_url/v2/second_endpoint/internal",
+            "publicURL": "http://fake_url/v2/second_endpoint/public"
         },
     ],
     "type": "compute",
@@ -79,17 +79,24 @@
 COMPUTE_ENDPOINTS_V3 = {
     "endpoints": [
         {
-            "id": "fake_service",
+            "id": "first_compute_fake_service",
             "interface": "public",
             "region": "NoMatchRegion",
-            "url": "http://fake_url/v3"
+            "url": "http://fake_url/v3/first_endpoint/api"
         },
         {
-            "id": "another_fake_service",
+            "id": "second_fake_service",
             "interface": "public",
             "region": "FakeRegion",
-            "url": "http://fake_url/v3"
+            "url": "http://fake_url/v3/second_endpoint/api"
+        },
+        {
+            "id": "third_fake_service",
+            "interface": "admin",
+            "region": "MiddleEarthRegion",
+            "url": "http://fake_url/v3/third_endpoint/api"
         }
+
     ],
     "type": "compute",
     "id": "fake_compute_endpoint"
diff --git a/tempest/tests/negative/test_generate_json.py b/tempest/tests/negative/test_generate_json.py
index a0aa088..e09fcdf 100644
--- a/tempest/tests/negative/test_generate_json.py
+++ b/tempest/tests/negative/test_generate_json.py
@@ -13,11 +13,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.common import generate_json as gen
+from tempest.common.generator import negative_generator
 import tempest.test
 
 
-class TestGenerateJson(tempest.test.BaseTestCase):
+class TestNegativeGenerator(tempest.test.BaseTestCase):
 
     fake_input_str = {"type": "string",
                       "minLength": 2,
@@ -35,19 +35,23 @@
                                      }
                       }
 
+    def setUp(self):
+        super(TestNegativeGenerator, self).setUp()
+        self.negative = negative_generator.NegativeTestGenerator()
+
     def _validate_result(self, data):
         self.assertTrue(isinstance(data, list))
         for t in data:
             self.assertTrue(isinstance(t, tuple))
 
     def test_generate_invalid_string(self):
-        result = gen.generate_invalid(self.fake_input_str)
+        result = self.negative.generate(self.fake_input_str)
         self._validate_result(result)
 
     def test_generate_invalid_integer(self):
-        result = gen.generate_invalid(self.fake_input_int)
+        result = self.negative.generate(self.fake_input_int)
         self._validate_result(result)
 
     def test_generate_invalid_obj(self):
-        result = gen.generate_invalid(self.fake_input_obj)
+        result = self.negative.generate(self.fake_input_obj)
         self._validate_result(result)
diff --git a/tempest/tests/negative/test_negative_auto_test.py b/tempest/tests/negative/test_negative_auto_test.py
index 4c59383..27ddc95 100644
--- a/tempest/tests/negative/test_negative_auto_test.py
+++ b/tempest/tests/negative/test_negative_auto_test.py
@@ -16,9 +16,11 @@
 import mock
 
 import tempest.test as test
+from tempest.tests import base
+from tempest.tests import fake_config
 
 
-class TestNegativeAutoTest(test.BaseTestCase):
+class TestNegativeAutoTest(base.TestCase):
     # Fake entries
     _interface = 'json'
     _service = 'compute'
@@ -34,6 +36,10 @@
                        "resources": ["flavor", "volume", "image"]
                        }
 
+    def setUp(self):
+        super(TestNegativeAutoTest, self).setUp()
+        self.stubs.Set(test, 'CONF', fake_config.FakeConfig)
+
     def _check_prop_entries(self, result, entry):
         entries = [a for a in result if entry in a[0]]
         self.assertIsNotNone(entries)
diff --git a/tempest/tests/test_auth.py b/tempest/tests/test_auth.py
index 5346052..df04d65 100644
--- a/tempest/tests/test_auth.py
+++ b/tempest/tests/test_auth.py
@@ -100,6 +100,7 @@
 
 
 class TestKeystoneV2AuthProvider(BaseAuthTestsSetUp):
+    _endpoints = fake_identity.IDENTITY_V2_RESPONSE['access']['serviceCatalog']
     _auth_provider_class = auth.KeystoneV2AuthProvider
 
     def setUp(self):
@@ -111,41 +112,71 @@
     def _get_fake_alt_identity(self):
         return fake_identity.ALT_IDENTITY_V2_RESPONSE['access']
 
-    def _get_result_url_from_fake_identity(self):
-        return fake_identity.COMPUTE_ENDPOINTS_V2['endpoints'][1]['publicURL']
+    def _get_result_url_from_endpoint(self, ep, endpoint_type='publicURL',
+                                      replacement=None):
+        if replacement:
+            return ep[endpoint_type].replace('v2', replacement)
+        return ep[endpoint_type]
 
     def _get_token_from_fake_identity(self):
         return fake_identity.TOKEN
 
-    def _test_request_helper(self):
+    def _test_request_helper(self, filters, expected):
+        url, headers, body = self.auth_provider.auth_request('GET',
+                                                             self.target_url,
+                                                             filters=filters)
+
+        self.assertEqual(expected['url'], url)
+        self.assertEqual(expected['token'], headers['X-Auth-Token'])
+        self.assertEqual(expected['body'], body)
+
+    def test_request(self):
+        filters = {
+            'service': 'compute',
+            'endpoint_type': 'publicURL',
+            'region': 'FakeRegion'
+        }
+
+        url = self._get_result_url_from_endpoint(
+            self._endpoints[0]['endpoints'][1]) + '/' + self.target_url
+
+        expected = {
+            'body': None,
+            'url': url,
+            'token': self._get_token_from_fake_identity(),
+        }
+        self._test_request_helper(filters, expected)
+
+    def test_request_with_alt_auth_cleans_alt(self):
+        self.auth_provider.set_alt_auth_data(
+            'body',
+            (fake_identity.ALT_TOKEN, self._get_fake_alt_identity()))
+        self.test_request()
+        # Assert alt auth data is clear after it
+        self.assertIsNone(self.auth_provider.alt_part)
+        self.assertIsNone(self.auth_provider.alt_auth_data)
+
+    def test_request_with_alt_part_without_alt_data(self):
+        """
+        Assert that when alt_part is defined, the corresponding original
+        request element is kept the same.
+        """
         filters = {
             'service': 'compute',
             'endpoint_type': 'publicURL',
             'region': 'fakeRegion'
         }
+        self.auth_provider.set_alt_auth_data('url', None)
 
         url, headers, body = self.auth_provider.auth_request('GET',
                                                              self.target_url,
                                                              filters=filters)
 
-        result_url = self._get_result_url_from_fake_identity()
-        self.assertEqual(url, result_url + '/' + self.target_url)
+        self.assertEqual(url, self.target_url)
         self.assertEqual(self._get_token_from_fake_identity(),
                          headers['X-Auth-Token'])
         self.assertEqual(body, None)
 
-    def test_request(self):
-        self._test_request_helper()
-
-    def test_request_with_alt_auth(self):
-        self.auth_provider.set_alt_auth_data(
-            'body',
-            (fake_identity.ALT_TOKEN, self._get_fake_alt_identity()))
-        self._test_request_helper()
-        # Assert alt auth data is clear after it
-        self.assertIsNone(self.auth_provider.alt_part)
-        self.assertIsNone(self.auth_provider.alt_auth_data)
-
     def test_request_with_bad_service(self):
         filters = {
             'service': 'BAD_SERVICE',
@@ -154,7 +185,7 @@
         }
         self.assertRaises(exceptions.EndpointNotFound,
                           self.auth_provider.auth_request, 'GET',
-                          'http://fakeurl.com/fake_api', filters=filters)
+                          self.target_url, filters=filters)
 
     def test_request_without_service(self):
         filters = {
@@ -164,7 +195,7 @@
         }
         self.assertRaises(exceptions.EndpointNotFound,
                           self.auth_provider.auth_request, 'GET',
-                          'http://fakeurl.com/fake_api', filters=filters)
+                          self.target_url, filters=filters)
 
     def test_check_credentials_missing_attribute(self):
         for attr in ['username', 'password']:
@@ -183,8 +214,86 @@
         del cred['tenant_name']
         self.assertFalse(self.auth_provider.check_credentials(cred))
 
+    def _test_base_url_helper(self, expected_url, filters,
+                              auth_data=None):
+
+        url = self.auth_provider.base_url(filters, auth_data)
+        self.assertEqual(url, expected_url)
+
+    def test_base_url(self):
+        self.filters = {
+            'service': 'compute',
+            'endpoint_type': 'publicURL',
+            'region': 'FakeRegion'
+        }
+        expected = self._get_result_url_from_endpoint(
+            self._endpoints[0]['endpoints'][1])
+        self._test_base_url_helper(expected, self.filters)
+
+    def test_base_url_to_get_admin_endpoint(self):
+        self.filters = {
+            'service': 'compute',
+            'endpoint_type': 'adminURL',
+            'region': 'FakeRegion'
+        }
+        expected = self._get_result_url_from_endpoint(
+            self._endpoints[0]['endpoints'][1], endpoint_type='adminURL')
+        self._test_base_url_helper(expected, self.filters)
+
+    def test_base_url_unknown_region(self):
+        """
+        Assure that if the region is unknow the first endpoint is returned.
+        """
+        self.filters = {
+            'service': 'compute',
+            'endpoint_type': 'publicURL',
+            'region': 'AintNoBodyKnowThisRegion'
+        }
+        expected = self._get_result_url_from_endpoint(
+            self._endpoints[0]['endpoints'][0])
+        self._test_base_url_helper(expected, self.filters)
+
+    def test_base_url_with_non_existent_service(self):
+        self.filters = {
+            'service': 'BAD_SERVICE',
+            'endpoint_type': 'publicURL',
+            'region': 'FakeRegion'
+        }
+        self.assertRaises(exceptions.EndpointNotFound,
+                          self._test_base_url_helper, None, self.filters)
+
+    def test_base_url_without_service(self):
+        self.filters = {
+            'endpoint_type': 'publicURL',
+            'region': 'FakeRegion'
+        }
+        self.assertRaises(exceptions.EndpointNotFound,
+                          self._test_base_url_helper, None, self.filters)
+
+    def test_base_url_with_api_version_filter(self):
+        self.filters = {
+            'service': 'compute',
+            'endpoint_type': 'publicURL',
+            'region': 'FakeRegion',
+            'api_version': 'v12'
+        }
+        expected = self._get_result_url_from_endpoint(
+            self._endpoints[0]['endpoints'][1], replacement='v12')
+        self._test_base_url_helper(expected, self.filters)
+
+    def test_base_url_with_skip_path_filter(self):
+        self.filters = {
+            'service': 'compute',
+            'endpoint_type': 'publicURL',
+            'region': 'FakeRegion',
+            'skip_path': True
+        }
+        expected = 'http://fake_url/'
+        self._test_base_url_helper(expected, self.filters)
+
 
 class TestKeystoneV3AuthProvider(TestKeystoneV2AuthProvider):
+    _endpoints = fake_identity.IDENTITY_V3_RESPONSE['token']['catalog']
     _auth_provider_class = auth.KeystoneV3AuthProvider
     credentials = {
         'username': 'fake_user',
@@ -201,10 +310,23 @@
     def _get_fake_alt_identity(self):
         return fake_identity.ALT_IDENTITY_V3['token']
 
-    def _get_result_url_from_fake_identity(self):
-        return fake_identity.COMPUTE_ENDPOINTS_V3['endpoints'][1]['url']
+    def _get_result_url_from_endpoint(self, ep, replacement=None):
+        if replacement:
+            return ep['url'].replace('v3', replacement)
+        return ep['url']
 
     def test_check_credentials_missing_tenant_name(self):
         cred = copy.copy(self.credentials)
         del cred['domain_name']
         self.assertFalse(self.auth_provider.check_credentials(cred))
+
+    # Overwrites v2 test
+    def test_base_url_to_get_admin_endpoint(self):
+        self.filters = {
+            'service': 'compute',
+            'endpoint_type': 'admin',
+            'region': 'MiddleEarthRegion'
+        }
+        expected = self._get_result_url_from_endpoint(
+            self._endpoints[0]['endpoints'][2])
+        self._test_base_url_helper(expected, self.filters)
diff --git a/tempest/tests/test_decorators.py b/tempest/tests/test_decorators.py
index 88920dc..aa3c8fc 100644
--- a/tempest/tests/test_decorators.py
+++ b/tempest/tests/test_decorators.py
@@ -41,10 +41,6 @@
             self.assertEqual(getattr(foo, '__testtools_attrs'),
                              set(expected_attrs))
 
-        # nose sets it anyway
-        for arg, value in decorator_args.items():
-            self.assertEqual(getattr(foo, arg), value)
-
     def test_attr_without_type(self):
         self._test_attr_helper(expected_attrs='baz', bar='baz')
 
@@ -74,7 +70,6 @@
         t = TestFoo('test_bar')
         self.assertEqual(set(decorator_args), getattr(t.test_bar,
                                                       '__testtools_attrs'))
-        self.assertEqual(list(decorator_args), t.test_bar.type)
         self.assertEqual(t.test_bar(), 0)
 
     def test_services_decorator_with_single_service(self):
@@ -110,7 +105,6 @@
                          expected_frequency)
         self.assertEqual(getattr(foo, 'st_allow_inheritance'),
                          expected_inheritance)
-        self.assertEqual(foo.type, 'stress')
         self.assertEqual(set(['stress']), getattr(foo, '__testtools_attrs'))
 
     def test_stresstest_decorator_default(self):
diff --git a/tempest/tests/test_rest_client.py b/tempest/tests/test_rest_client.py
index ba43daf..827b5c9 100644
--- a/tempest/tests/test_rest_client.py
+++ b/tempest/tests/test_rest_client.py
@@ -164,7 +164,7 @@
 
     keys = ["fake_key1", "fake_key2"]
     values = ["fake_value1", "fake_value2"]
-    item_expected = {key: value for key, value in zip(keys, values)}
+    item_expected = dict((key, value) for (key, value) in zip(keys, values))
     list_expected = {"body_list": [
         {keys[0]: values[0]},
         {keys[1]: values[1]},
@@ -230,3 +230,114 @@
         data = {"one_top_key": "not_list_or_dict_value"}
         body = self.rest_client._parse_resp(json.dumps(data))
         self.assertEqual(data, body)
+
+
+class TestRestClientErrorCheckerJSON(base.TestCase):
+    c_type = "application/json"
+
+    def set_data(self, r_code, enc=None, r_body=None):
+        if enc is None:
+            enc = self.c_type
+        resp_dict = {'status': r_code, 'content-type': enc}
+        resp = httplib2.Response(resp_dict)
+        data = {
+            "method": "fake_method",
+            "url": "fake_url",
+            "headers": "fake_headers",
+            "body": "fake_body",
+            "resp": resp,
+            "resp_body": '{"resp_body": "fake_resp_body"}',
+        }
+        if r_body is not None:
+            data.update({"resp_body": r_body})
+        return data
+
+    def setUp(self):
+        super(TestRestClientErrorCheckerJSON, self).setUp()
+        self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakeConfig)
+        self.rest_client = rest_client.RestClient(
+            fake_auth_provider.FakeAuthProvider())
+
+    def test_response_less_than_400(self):
+        self.rest_client._error_checker(**self.set_data("399"))
+
+    def test_response_400(self):
+        self.assertRaises(exceptions.BadRequest,
+                          self.rest_client._error_checker,
+                          **self.set_data("400"))
+
+    def test_response_401(self):
+        self.assertRaises(exceptions.Unauthorized,
+                          self.rest_client._error_checker,
+                          **self.set_data("401"))
+
+    def test_response_403(self):
+        self.assertRaises(exceptions.Unauthorized,
+                          self.rest_client._error_checker,
+                          **self.set_data("403"))
+
+    def test_response_404(self):
+        self.assertRaises(exceptions.NotFound,
+                          self.rest_client._error_checker,
+                          **self.set_data("404"))
+
+    def test_response_409(self):
+        self.assertRaises(exceptions.Conflict,
+                          self.rest_client._error_checker,
+                          **self.set_data("409"))
+
+    def test_response_413(self):
+        self.assertRaises(exceptions.OverLimit,
+                          self.rest_client._error_checker,
+                          **self.set_data("413"))
+
+    def test_response_422(self):
+        self.assertRaises(exceptions.UnprocessableEntity,
+                          self.rest_client._error_checker,
+                          **self.set_data("422"))
+
+    def test_response_500_with_text(self):
+        # _parse_resp is expected to return 'str'
+        self.assertRaises(exceptions.ServerFault,
+                          self.rest_client._error_checker,
+                          **self.set_data("500"))
+
+    def test_response_501_with_text(self):
+        self.assertRaises(exceptions.ServerFault,
+                          self.rest_client._error_checker,
+                          **self.set_data("501"))
+
+    def test_response_500_with_dict(self):
+        r_body = '{"resp_body": {"err": "fake_resp_body"}}'
+        self.assertRaises(exceptions.ServerFault,
+                          self.rest_client._error_checker,
+                          **self.set_data("500", r_body=r_body))
+
+    def test_response_501_with_dict(self):
+        r_body = '{"resp_body": {"err": "fake_resp_body"}}'
+        self.assertRaises(exceptions.ServerFault,
+                          self.rest_client._error_checker,
+                          **self.set_data("501", r_body=r_body))
+
+    def test_response_bigger_than_400(self):
+        # Any response code, that bigger than 400, and not in
+        # (401, 403, 404, 409, 413, 422, 500, 501)
+        self.assertRaises(exceptions.UnexpectedResponseCode,
+                          self.rest_client._error_checker,
+                          **self.set_data("402"))
+
+
+class TestRestClientErrorCheckerXML(TestRestClientErrorCheckerJSON):
+    c_type = "application/xml"
+
+
+class TestRestClientErrorCheckerTEXT(TestRestClientErrorCheckerJSON):
+    c_type = "text/plain"
+
+    def test_fake_content_type(self):
+        # This test is required only in one exemplar
+        # Any response code, that bigger than 400, and not in
+        # (401, 403, 404, 409, 413, 422, 500, 501)
+        self.assertRaises(exceptions.InvalidContentType,
+                          self.rest_client._error_checker,
+                          **self.set_data("405", enc="fake_enc"))
diff --git a/tempest/thirdparty/boto/test.py b/tempest/thirdparty/boto/test.py
index b36e8c7..10d421e 100644
--- a/tempest/thirdparty/boto/test.py
+++ b/tempest/thirdparty/boto/test.py
@@ -17,6 +17,7 @@
 import logging as orig_logging
 import os
 import re
+import six
 import urlparse
 
 import boto
@@ -26,14 +27,12 @@
 import keystoneclient.exceptions
 
 import tempest.clients
-from tempest.common.utils.file_utils import have_effective_read_access
+from tempest.common.utils import file_utils
 from tempest import config
 from tempest import exceptions
 from tempest.openstack.common import log as logging
 import tempest.test
-from tempest.thirdparty.boto.utils.wait import re_search_wait
-from tempest.thirdparty.boto.utils.wait import state_wait
-from tempest.thirdparty.boto.utils.wait import wait_exception
+from tempest.thirdparty.boto.utils import wait
 
 CONF = config.CONF
 LOG = logging.getLogger(__name__)
@@ -47,7 +46,7 @@
     id_matcher = re.compile("[A-Za-z0-9]{20,}")
 
     def all_read(*args):
-        return all(map(have_effective_read_access, args))
+        return all(map(file_utils.have_effective_read_access, args))
 
     materials_path = CONF.boto.s3_materials_path
     ami_path = materials_path + os.sep + CONF.boto.ami_manifest
@@ -136,7 +135,7 @@
         The not leaf elements does wildcard match
     """
     # in error_code just literal and '.' characters expected
-    if not isinstance(error_data, basestring):
+    if not isinstance(error_data, six.string_types):
         (error_code, status_code) = map(str, error_data)
     else:
         status_code = None
@@ -146,7 +145,7 @@
     num_parts = len(parts)
     max_index = num_parts - 1
     add_cls = error_cls
-    for i_part in xrange(num_parts):
+    for i_part in six.moves.xrange(num_parts):
         part = parts[i_part]
         leaf = i_part == max_index
         if not leaf:
@@ -327,7 +326,7 @@
             final_set = set((final_set,))
         final_set |= self.gone_set
         lfunction = self.get_lfunction_gone(lfunction)
-        state = state_wait(lfunction, final_set, valid_set)
+        state = wait.state_wait(lfunction, final_set, valid_set)
         self.assertIn(state, valid_set | self.gone_set)
         return state
 
@@ -377,8 +376,8 @@
                 return "ASSOCIATED"
             return "DISASSOCIATED"
 
-        state = state_wait(_disassociate, "DISASSOCIATED",
-                           set(("ASSOCIATED", "DISASSOCIATED")))
+        state = wait.state_wait(_disassociate, "DISASSOCIATED",
+                                set(("ASSOCIATED", "DISASSOCIATED")))
         self.assertEqual(state, "DISASSOCIATED")
 
     def assertAddressReleasedWait(self, address):
@@ -391,7 +390,7 @@
                     return "DELETED"
             return "NOTDELETED"
 
-        state = state_wait(_address_delete, "DELETED")
+        state = wait.state_wait(_address_delete, "DELETED")
         self.assertEqual(state, "DELETED")
 
     def assertReSearch(self, regexp, string):
@@ -462,7 +461,7 @@
         for instance in reservation.instances:
             try:
                 instance.terminate()
-                re_search_wait(_instance_state, "_GONE")
+                wait.re_search_wait(_instance_state, "_GONE")
             except BaseException:
                 LOG.exception("Failed to terminate instance %s " % instance)
                 exc_num += 1
@@ -503,7 +502,8 @@
             return volume.status
 
         try:
-            re_search_wait(_volume_state, "available")  # not validates status
+            wait.re_search_wait(_volume_state, "available")
+            # not validates status
             LOG.info(_volume_state())
             volume.delete()
         except BaseException:
@@ -520,7 +520,7 @@
         def _update():
             snapshot.update(validate=True)
 
-        wait_exception(_update)
+        wait.wait_exception(_update)
 
 
 # you can specify tuples if you want to specify the status pattern
diff --git a/tempest/thirdparty/boto/test_ec2_instance_run.py b/tempest/thirdparty/boto/test_ec2_instance_run.py
index 54861be..bbfbb79 100644
--- a/tempest/thirdparty/boto/test_ec2_instance_run.py
+++ b/tempest/thirdparty/boto/test_ec2_instance_run.py
@@ -16,23 +16,21 @@
 from boto import exception
 
 from tempest.common.utils import data_utils
-from tempest.common.utils.linux.remote_client import RemoteClient
+from tempest.common.utils.linux import remote_client
 from tempest import config
 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
-from tempest.thirdparty.boto.utils.wait import state_wait
+from tempest import test
+from tempest.thirdparty.boto import test as boto_test
+from tempest.thirdparty.boto.utils import s3
+from tempest.thirdparty.boto.utils import wait
 
 CONF = config.CONF
 
 LOG = logging.getLogger(__name__)
 
 
-class InstanceRunTest(BotoTestCase):
+class InstanceRunTest(boto_test.BotoTestCase):
 
     @classmethod
     def setUpClass(cls):
@@ -57,7 +55,7 @@
         cls.addResourceCleanUp(cls.destroy_bucket,
                                cls.s3_client.connection_data,
                                cls.bucket_name)
-        s3_upload_dir(bucket, cls.materials_path)
+        s3.s3_upload_dir(bucket, cls.materials_path)
         cls.images = {"ami":
                       {"name": data_utils.rand_name("ami-name-"),
                        "location": cls.bucket_name + "/" + ami_manifest},
@@ -78,14 +76,14 @@
             def _state():
                 retr = cls.ec2_client.get_image(image["image_id"])
                 return retr.state
-            state = state_wait(_state, "available")
+            state = wait.state_wait(_state, "available")
             if state != "available":
                 for _image in cls.images.itervalues():
                     cls.ec2_client.deregister_image(_image["image_id"])
                 raise exceptions.EC2RegisterImageException(image_id=
                                                            image["image_id"])
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_run_idempotent_instances(self):
         # EC2 run instances idempotently
 
@@ -123,7 +121,7 @@
         _terminate_reservation(reservation_1, rcuk_1)
         _terminate_reservation(reservation_2, rcuk_2)
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_run_stop_terminate_instance(self):
         # EC2 run, stop and terminate instance
         image_ami = self.ec2_client.get_image(self.images["ami"]
@@ -148,7 +146,7 @@
             instance.terminate()
         self.cancelResourceCleanUp(rcuk)
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_run_stop_terminate_instance_with_tags(self):
         # EC2 run, stop and terminate instance with tags
         image_ami = self.ec2_client.get_image(self.images["ami"]
@@ -195,8 +193,8 @@
             instance.terminate()
         self.cancelResourceCleanUp(rcuk)
 
-    @skip_because(bug="1098891")
-    @attr(type='smoke')
+    @test.skip_because(bug="1098891")
+    @test.attr(type='smoke')
     def test_run_terminate_instance(self):
         # EC2 run, terminate immediately
         image_ami = self.ec2_client.get_image(self.images["ami"]
@@ -222,8 +220,8 @@
 
     # NOTE(afazekas): doctored test case,
     # with normal validation it would fail
-    @skip_because(bug="1182679")
-    @attr(type='smoke')
+    @test.skip_because(bug="1182679")
+    @test.attr(type='smoke')
     def test_integration_1(self):
         # EC2 1. integration test (not strict)
         image_ami = self.ec2_client.get_image(self.images["ami"]["image_id"])
@@ -271,9 +269,9 @@
         self.assertVolumeStatusWait(volume, "available")
         # NOTE(afazekas): it may be reports available before it is available
 
-        ssh = RemoteClient(address.public_ip,
-                           CONF.compute.ssh_user,
-                           pkey=self.keypair.material)
+        ssh = remote_client.RemoteClient(address.public_ip,
+                                         CONF.compute.ssh_user,
+                                         pkey=self.keypair.material)
         text = data_utils.rand_name("Pattern text for console output -")
         resp = ssh.write_to_console(text)
         self.assertFalse(resp)
@@ -282,7 +280,7 @@
             output = instance.get_console_output()
             return output.output
 
-        re_search_wait(_output, text)
+        wait.re_search_wait(_output, text)
         part_lines = ssh.get_partitions().split('\n')
         volume.attach(instance.id, "/dev/vdh")
 
@@ -291,7 +289,7 @@
             return volume.status
 
         self.assertVolumeStatusWait(_volume_state, "in-use")
-        re_search_wait(_volume_state, "in-use")
+        wait.re_search_wait(_volume_state, "in-use")
 
         # NOTE(afazekas):  Different Hypervisor backends names
         # differently the devices,
@@ -305,7 +303,7 @@
                 return 'DECREASE'
             return 'EQUAL'
 
-        state_wait(_part_state, 'INCREASE')
+        wait.state_wait(_part_state, 'INCREASE')
         part_lines = ssh.get_partitions().split('\n')
 
         # TODO(afazekas): Resource compare to the flavor settings
@@ -313,10 +311,10 @@
         volume.detach()
 
         self.assertVolumeStatusWait(_volume_state, "available")
-        re_search_wait(_volume_state, "available")
+        wait.re_search_wait(_volume_state, "available")
         LOG.info("Volume %s state: %s", volume.id, volume.status)
 
-        state_wait(_part_state, 'DECREASE')
+        wait.state_wait(_part_state, 'DECREASE')
 
         instance.stop()
         address.disassociate()
diff --git a/tempest/thirdparty/boto/test_ec2_keys.py b/tempest/thirdparty/boto/test_ec2_keys.py
index 329ace3..dec0170 100644
--- a/tempest/thirdparty/boto/test_ec2_keys.py
+++ b/tempest/thirdparty/boto/test_ec2_keys.py
@@ -14,9 +14,8 @@
 #    under the License.
 
 from tempest.common.utils import data_utils
-from tempest.test import attr
-from tempest.test import skip_because
-from tempest.thirdparty.boto.test import BotoTestCase
+from tempest import test
+from tempest.thirdparty.boto import test as boto_test
 
 
 def compare_key_pairs(a, b):
@@ -24,7 +23,7 @@
             a.fingerprint == b.fingerprint)
 
 
-class EC2KeysTest(BotoTestCase):
+class EC2KeysTest(boto_test.BotoTestCase):
 
     @classmethod
     def setUpClass(cls):
@@ -33,7 +32,7 @@
         cls.ec = cls.ec2_error_code
 
 # TODO(afazekas): merge create, delete, get test cases
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_create_ec2_keypair(self):
         # EC2 create KeyPair
         key_name = data_utils.rand_name("keypair-")
@@ -42,16 +41,16 @@
         self.assertTrue(compare_key_pairs(keypair,
                         self.client.get_key_pair(key_name)))
 
-    @skip_because(bug="1072318")
-    @attr(type='smoke')
+    @test.skip_because(bug="1072318")
+    @test.attr(type='smoke')
     def test_delete_ec2_keypair(self):
         # EC2 delete KeyPair
         key_name = data_utils.rand_name("keypair-")
         self.client.create_key_pair(key_name)
         self.client.delete_key_pair(key_name)
-        self.assertEqual(None, self.client.get_key_pair(key_name))
+        self.assertIsNone(self.client.get_key_pair(key_name))
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_get_ec2_keypair(self):
         # EC2 get KeyPair
         key_name = data_utils.rand_name("keypair-")
@@ -60,7 +59,7 @@
         self.assertTrue(compare_key_pairs(keypair,
                         self.client.get_key_pair(key_name)))
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_duplicate_ec2_keypair(self):
         # EC2 duplicate KeyPair
         key_name = data_utils.rand_name("keypair-")
diff --git a/tempest/thirdparty/boto/test_ec2_network.py b/tempest/thirdparty/boto/test_ec2_network.py
index 4b2f01f..d508c07 100644
--- a/tempest/thirdparty/boto/test_ec2_network.py
+++ b/tempest/thirdparty/boto/test_ec2_network.py
@@ -13,12 +13,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.test import attr
-from tempest.test import skip_because
-from tempest.thirdparty.boto.test import BotoTestCase
+from tempest import test
+from tempest.thirdparty.boto import test as boto_test
 
 
-class EC2NetworkTest(BotoTestCase):
+class EC2NetworkTest(boto_test.BotoTestCase):
 
     @classmethod
     def setUpClass(cls):
@@ -26,8 +25,8 @@
         cls.client = cls.os.ec2api_client
 
     # Note(afazekas): these tests for things duable without an instance
-    @skip_because(bug="1080406")
-    @attr(type='smoke')
+    @test.skip_because(bug="1080406")
+    @test.attr(type='smoke')
     def test_disassociate_not_associated_floating_ip(self):
         # EC2 disassociate not associated floating ip
         ec2_codes = self.ec2_error_code
diff --git a/tempest/thirdparty/boto/test_ec2_security_groups.py b/tempest/thirdparty/boto/test_ec2_security_groups.py
index 9b58603..86140ec 100644
--- a/tempest/thirdparty/boto/test_ec2_security_groups.py
+++ b/tempest/thirdparty/boto/test_ec2_security_groups.py
@@ -14,18 +14,18 @@
 #    under the License.
 
 from tempest.common.utils import data_utils
-from tempest.test import attr
-from tempest.thirdparty.boto.test import BotoTestCase
+from tempest import test
+from tempest.thirdparty.boto import test as boto_test
 
 
-class EC2SecurityGroupTest(BotoTestCase):
+class EC2SecurityGroupTest(boto_test.BotoTestCase):
 
     @classmethod
     def setUpClass(cls):
         super(EC2SecurityGroupTest, cls).setUpClass()
         cls.client = cls.os.ec2api_client
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_create_authorize_security_group(self):
         # EC2 Create, authorize/revoke security group
         group_name = data_utils.rand_name("securty_group-")
diff --git a/tempest/thirdparty/boto/test_ec2_volumes.py b/tempest/thirdparty/boto/test_ec2_volumes.py
index 04671c5..6a771e5 100644
--- a/tempest/thirdparty/boto/test_ec2_volumes.py
+++ b/tempest/thirdparty/boto/test_ec2_volumes.py
@@ -13,10 +13,12 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest import config
 from tempest.openstack.common import log as logging
-from tempest.test import attr
-from tempest.thirdparty.boto.test import BotoTestCase
+from tempest import test
+from tempest.thirdparty.boto import test as boto_test
 
+CONF = config.CONF
 LOG = logging.getLogger(__name__)
 
 
@@ -25,15 +27,20 @@
             a.size == b.size)
 
 
-class EC2VolumesTest(BotoTestCase):
+class EC2VolumesTest(boto_test.BotoTestCase):
 
     @classmethod
     def setUpClass(cls):
         super(EC2VolumesTest, cls).setUpClass()
+
+        if not CONF.service_available.cinder:
+            skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
+            raise cls.skipException(skip_msg)
+
         cls.client = cls.os.ec2api_client
         cls.zone = cls.client.get_good_zone()
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_create_get_delete(self):
         # EC2 Create, get, delete Volume
         volume = self.client.create_volume(1, self.zone)
@@ -46,7 +53,7 @@
         self.client.delete_volume(volume.id)
         self.cancelResourceCleanUp(cuk)
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_create_volume_from_snapshot(self):
         # EC2 Create volume from snapshot
         volume = self.client.create_volume(1, self.zone)
diff --git a/tempest/thirdparty/boto/test_s3_buckets.py b/tempest/thirdparty/boto/test_s3_buckets.py
index f34faac..af6aa8b 100644
--- a/tempest/thirdparty/boto/test_s3_buckets.py
+++ b/tempest/thirdparty/boto/test_s3_buckets.py
@@ -14,20 +14,19 @@
 #    under the License.
 
 from tempest.common.utils import data_utils
-from tempest.test import attr
-from tempest.test import skip_because
-from tempest.thirdparty.boto.test import BotoTestCase
+from tempest import test
+from tempest.thirdparty.boto import test as boto_test
 
 
-class S3BucketsTest(BotoTestCase):
+class S3BucketsTest(boto_test.BotoTestCase):
 
     @classmethod
     def setUpClass(cls):
         super(S3BucketsTest, cls).setUpClass()
         cls.client = cls.os.s3_client
 
-    @skip_because(bug="1076965")
-    @attr(type='smoke')
+    @test.skip_because(bug="1076965")
+    @test.attr(type='smoke')
     def test_create_and_get_delete_bucket(self):
         # S3 Create, get and delete bucket
         bucket_name = data_utils.rand_name("s3bucket-")
diff --git a/tempest/thirdparty/boto/test_s3_ec2_images.py b/tempest/thirdparty/boto/test_s3_ec2_images.py
index 9607a92..d2300ee 100644
--- a/tempest/thirdparty/boto/test_s3_ec2_images.py
+++ b/tempest/thirdparty/boto/test_s3_ec2_images.py
@@ -17,14 +17,14 @@
 
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest.test import attr
-from tempest.thirdparty.boto.test import BotoTestCase
-from tempest.thirdparty.boto.utils.s3 import s3_upload_dir
+from tempest import test
+from tempest.thirdparty.boto import test as boto_test
+from tempest.thirdparty.boto.utils import s3
 
 CONF = config.CONF
 
 
-class S3ImagesTest(BotoTestCase):
+class S3ImagesTest(boto_test.BotoTestCase):
 
     @classmethod
     def setUpClass(cls):
@@ -46,9 +46,9 @@
         cls.addResourceCleanUp(cls.destroy_bucket,
                                cls.s3_client.connection_data,
                                cls.bucket_name)
-        s3_upload_dir(bucket, cls.materials_path)
+        s3.s3_upload_dir(bucket, cls.materials_path)
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_register_get_deregister_ami_image(self):
         # Register and deregister ami image
         image = {"name": data_utils.rand_name("ami-name-"),
diff --git a/tempest/thirdparty/boto/test_s3_objects.py b/tempest/thirdparty/boto/test_s3_objects.py
index a102a22..1ae46de 100644
--- a/tempest/thirdparty/boto/test_s3_objects.py
+++ b/tempest/thirdparty/boto/test_s3_objects.py
@@ -18,18 +18,18 @@
 import boto.s3.key
 
 from tempest.common.utils import data_utils
-from tempest.test import attr
-from tempest.thirdparty.boto.test import BotoTestCase
+from tempest import test
+from tempest.thirdparty.boto import test as boto_test
 
 
-class S3BucketsTest(BotoTestCase):
+class S3BucketsTest(boto_test.BotoTestCase):
 
     @classmethod
     def setUpClass(cls):
         super(S3BucketsTest, cls).setUpClass()
         cls.client = cls.os.s3_client
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_create_get_delete_object(self):
         # S3 Create, get and delete object
         bucket_name = data_utils.rand_name("s3bucket-")
diff --git a/tempest/thirdparty/boto/utils/wait.py b/tempest/thirdparty/boto/utils/wait.py
index eed0a92..752ed0f 100644
--- a/tempest/thirdparty/boto/utils/wait.py
+++ b/tempest/thirdparty/boto/utils/wait.py
@@ -17,7 +17,7 @@
 import time
 
 import boto.exception
-from testtools import TestCase
+import testtools
 
 from tempest import config
 from tempest.openstack.common import log as logging
@@ -44,10 +44,11 @@
             return status
         dtime = time.time() - start_time
         if dtime > CONF.boto.build_timeout:
-            raise TestCase.failureException("State change timeout exceeded!"
-                                            '(%ds) While waiting'
-                                            'for %s at "%s"' %
-                                            (dtime, final_set, status))
+            raise testtools.TestCase\
+                .failureException("State change timeout exceeded!"
+                                  '(%ds) While waiting'
+                                  'for %s at "%s"' %
+                                  (dtime, final_set, status))
         time.sleep(CONF.boto.build_interval)
         old_status = status
         status = lfunction()
@@ -67,10 +68,11 @@
             return result
         dtime = time.time() - start_time
         if dtime > CONF.boto.build_timeout:
-            raise TestCase.failureException('Pattern find timeout exceeded!'
-                                            '(%ds) While waiting for'
-                                            '"%s" pattern in "%s"' %
-                                            (dtime, regexp, text))
+            raise testtools.TestCase\
+                .failureException('Pattern find timeout exceeded!'
+                                  '(%ds) While waiting for'
+                                  '"%s" pattern in "%s"' %
+                                  (dtime, regexp, text))
         time.sleep(CONF.boto.build_interval)
 
 
@@ -98,8 +100,8 @@
         # Let the other exceptions propagate
         dtime = time.time() - start_time
         if dtime > CONF.boto.build_timeout:
-            raise TestCase.failureException("Wait timeout exceeded! (%ds)" %
-                                            dtime)
+            raise testtools.TestCase\
+                .failureException("Wait timeout exceeded! (%ds)" % dtime)
         time.sleep(CONF.boto.build_interval)
 
 
@@ -116,8 +118,8 @@
             return exc
         dtime = time.time() - start_time
         if dtime > CONF.boto.build_timeout:
-            raise TestCase.failureException("Wait timeout exceeded! (%ds)" %
-                                            dtime)
+            raise testtools.TestCase\
+                .failureException("Wait timeout exceeded! (%ds)" % dtime)
         time.sleep(CONF.boto.build_interval)
 
 # TODO(afazekas): consider strategy design pattern..
diff --git a/tools/check_logs.py b/tools/check_logs.py
index 15988a6..edf95a1 100755
--- a/tools/check_logs.py
+++ b/tools/check_logs.py
@@ -25,20 +25,24 @@
 import yaml
 
 
-is_neutron = os.environ.get('DEVSTACK_GATE_NEUTRON', "0") == "1"
 is_grenade = (os.environ.get('DEVSTACK_GATE_GRENADE', "0") == "1" or
               os.environ.get('DEVSTACK_GATE_GRENADE_FORWARD', "0") == "1")
 dump_all_errors = True
 
+# As logs are made clean, add to this set
+must_be_clean = set(['c-sch', 'g-reg', 'ceilometer-alarm-notifier',
+                     'ceilometer-collector', 'horizon', 'n-crt', 'n-obj',
+                     'q-vpn'])
+
 
 def process_files(file_specs, url_specs, whitelists):
-    regexp = re.compile(r"^.* (ERROR|CRITICAL) .*\[.*\-.*\]")
-    had_errors = False
+    regexp = re.compile(r"^.* (ERROR|CRITICAL|TRACE) .*\[.*\-.*\]")
+    logs_with_errors = []
     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
+                logs_with_errors.append(name)
     for (name, url) in url_specs:
         whitelist = whitelists.get(name, [])
         req = urllib2.Request(url)
@@ -47,8 +51,8 @@
         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
+            logs_with_errors.append(name)
+    return logs_with_errors
 
 
 def scan_content(name, content, regexp, whitelist):
@@ -122,19 +126,22 @@
                     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):
+    logs_with_errors = process_files(files_to_process, urls_to_process,
+                                     whitelists)
+    if logs_with_errors:
         print("Logs have errors")
-        if is_neutron:
-            print("Currently not failing neutron builds with errors")
-            return 0
-        if is_grenade:
-            print("Currently not failing grenade runs with errors")
-            return 0
-        print("FAILED")
-        return 1
-    else:
-        print("ok")
+    if is_grenade:
+        print("Currently not failing grenade runs with errors")
         return 0
+    failed = False
+    for log in logs_with_errors:
+        if log in must_be_clean:
+            print("FAILED: %s" % log)
+            failed = True
+    if failed:
+        return 1
+    print("ok")
+    return 0
 
 usage = """
 Find non-white-listed log errors in log files from a devstack-gate run.
diff --git a/tox.ini b/tox.ini
index 1580b14..4a625f8 100644
--- a/tox.ini
+++ b/tox.ini
@@ -4,11 +4,10 @@
 skipsdist = True
 
 [testenv]
-sitepackages = True
 setenv = VIRTUAL_ENV={envdir}
          OS_TEST_PATH=./tempest/test_discover
 usedevelop = True
-install_command = pip install {opts} {packages}
+install_command = pip install -U {opts} {packages}
 
 [testenv:py26]
 setenv = OS_TEST_PATH=./tempest/tests
@@ -27,11 +26,13 @@
 commands = python setup.py testr --coverage --testr-arg='tempest\.tests {posargs}'
 
 [testenv:all]
+sitepackages = True
 setenv = VIRTUAL_ENV={envdir}
 commands =
-  python setup.py testr --slowest --testr-args='{posargs}'
+  bash tools/pretty_tox.sh '{posargs}'
 
 [testenv:full]
+sitepackages = True
 # 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 =
@@ -44,49 +45,29 @@
   bash tools/pretty_tox_serial.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty|cli)) {posargs}'
 
 [testenv:testr-full]
+sitepackages = True
 commands =
   bash tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty|cli)) {posargs}'
 
 [testenv:heat-slow]
+sitepackages = True
 setenv = OS_TEST_TIMEOUT=1200
 # The regex below is used to select heat api/scenario tests tagged as slow.
 commands =
   bash tools/pretty_tox_serial.sh '(?=.*\[.*\bslow\b.*\])(^tempest\.(api|scenario)\.orchestration) {posargs}'
 
 [testenv:large-ops]
+sitepackages = True
 commands =
   python setup.py testr --slowest --testr-args='tempest.scenario.test_large_ops {posargs}'
 
-
-[testenv:py26-full]
-setenv = VIRTUAL_ENV={envdir}
-         NOSE_WITH_OPENSTACK=1
-         NOSE_OPENSTACK_COLOR=1
-         NOSE_OPENSTACK_RED=15
-         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 {posargs}
-
-[testenv:py26-smoke]
-setenv = VIRTUAL_ENV={envdir}
-NOSE_WITH_OPENSTACK=1
-         NOSE_OPENSTACK_COLOR=1
-         NOSE_OPENSTACK_RED=15
-         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
 commands =
    bash tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])((smoke)|(^tempest\.scenario)) {posargs}'
 
 [testenv:smoke-serial]
+sitepackages = True
 # 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.
@@ -94,6 +75,7 @@
    bash tools/pretty_tox_serial.sh '(?!.*\[.*\bslow\b.*\])((smoke)|(^tempest\.scenario)) {posargs}'
 
 [testenv:stress]
+sitepackages = True
 commands =
     python -m tempest/stress/run_stress -a -d 3600 -S