Merge "Remove test_can_log_into_created_server"
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/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 068a666..8ab3505 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -128,6 +128,9 @@
 # AWS Access Key (string value)
 #aws_access=<None>
 
+# AWS Zone for EC2 tests (string value)
+#aws_zone=nova
+
 # S3 Materials Path (string value)
 #s3_materials_path=/opt/stack/devstack/files/images/s3-materials/cirros-0.3.0
 
@@ -307,14 +310,14 @@
 
 # Administrative Username to use for Nova API requests.
 # (string value)
-#username=admin
+#username=<None>
 
 # Administrative Tenant name to use for Nova API requests.
 # (string value)
-#tenant_name=admin
+#tenant_name=<None>
 
 # API key to use when authenticating as admin. (string value)
-#password=pass
+#password=<None>
 
 
 [compute-feature-enabled]
@@ -341,9 +344,6 @@
 # password? (boolean value)
 #change_password=false
 
-# Does the test environment support snapshots? (boolean value)
-#create_image=false
-
 # Does the test environment support resizing? (boolean value)
 #resize=false
 
@@ -451,16 +451,16 @@
 #endpoint_type=publicURL
 
 # Username to use for Nova API requests. (string value)
-#username=demo
+#username=<None>
 
 # Tenant name to use for Nova API requests. (string value)
-#tenant_name=demo
+#tenant_name=<None>
 
 # Role required to administrate keystone. (string value)
 #admin_role=admin
 
 # API key to use when authenticating. (string value)
-#password=pass
+#password=<None>
 
 # Username of alternate user to use for Nova API requests.
 # (string value)
@@ -476,14 +476,14 @@
 
 # Administrative Username to use for Keystone API requests.
 # (string value)
-#admin_username=admin
+#admin_username=<None>
 
 # Administrative Tenant name to use for Keystone API requests.
 # (string value)
-#admin_tenant_name=admin
+#admin_tenant_name=<None>
 
 # API key to use when authenticating as admin. (string value)
-#admin_password=pass
+#admin_password=<None>
 
 
 [identity-feature-enabled]
@@ -617,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]
 
@@ -799,9 +807,9 @@
 # value)
 #horizon=true
 
-# Whether or not Savanna is expected to be available (boolean
+# Whether or not Sahara is expected to be available (boolean
 # value)
-#savanna=false
+#sahara=false
 
 # Whether or not Ironic is expected to be available (boolean
 # value)
diff --git a/requirements.txt b/requirements.txt
index 48d1b12..434e12e 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -20,6 +20,6 @@
 testrepository>=0.0.18
 oslo.config>=1.2.0
 six>=1.5.2
-iso8601>=0.1.8
+iso8601>=0.1.9
 fixtures>=0.3.14
 testscenarios>=0.4
diff --git a/tempest/api/compute/admin/test_flavors_negative.py b/tempest/api/compute/admin/test_flavors_negative.py
index 49d49ef..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):
 
@@ -44,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
@@ -85,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)
@@ -110,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_instance_usage_audit_log.py b/tempest/api/compute/admin/test_instance_usage_audit_log.py
index 32c8656..055a177 100644
--- a/tempest/api/compute/admin/test_instance_usage_audit_log.py
+++ b/tempest/api/compute/admin/test_instance_usage_audit_log.py
@@ -14,10 +14,10 @@
 #    under the License.
 
 import datetime
+import urllib
 
 from tempest.api.compute import base
 from tempest import test
-import urllib
 
 
 class InstanceUsageAuditLogTestJSON(base.BaseV2ComputeAdminTest):
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 fe4a184..6a5fc96 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
@@ -14,11 +14,11 @@
 #    under the License.
 
 import datetime
+import urllib
 
 from tempest.api.compute import base
 from tempest import exceptions
 from tempest import test
-import urllib
 
 
 class InstanceUsageAuditLogNegativeTestJSON(base.BaseV2ComputeAdminTest):
diff --git a/tempest/api/compute/admin/test_quotas.py b/tempest/api/compute/admin/test_quotas.py
index 5af091e..09c7274 100644
--- a/tempest/api/compute/admin/test_quotas.py
+++ b/tempest/api/compute/admin/test_quotas.py
@@ -92,6 +92,29 @@
         self.assertEqual(200, resp.status)
         self.assertEqual(quota_set['ram'], 5120)
 
+    @test.attr(type='gate')
+    def test_delete_quota(self):
+        # Admin can delete the resource quota set for a tenant
+        tenant_name = data_utils.rand_name('ram_quota_tenant_')
+        tenant_desc = tenant_name + '-desc'
+        identity_client = self.os_adm.identity_client
+        _, tenant = identity_client.create_tenant(name=tenant_name,
+                                                  description=tenant_desc)
+        tenant_id = tenant['id']
+        self.addCleanup(identity_client.delete_tenant, tenant_id)
+        resp, quota_set_default = self.adm_client.get_quota_set(tenant_id)
+        ram_default = quota_set_default['ram']
+
+        resp, body = self.adm_client.update_quota_set(tenant_id, ram='5120')
+        self.assertEqual(200, resp.status)
+
+        resp, body = self.adm_client.delete_quota_set(tenant_id)
+        self.assertEqual(202, resp.status)
+
+        resp, quota_set_new = self.adm_client.get_quota_set(tenant_id)
+        self.assertEqual(200, resp.status)
+        self.assertEqual(ram_default, quota_set_new['ram'])
+
 
 class QuotasAdminTestXML(QuotasAdminTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/admin/test_services.py b/tempest/api/compute/admin/test_services.py
index 9dd429b..2feb825 100644
--- a/tempest/api/compute/admin/test_services.py
+++ b/tempest/api/compute/admin/test_services.py
@@ -14,7 +14,6 @@
 #    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 import test
 
@@ -33,7 +32,7 @@
     @test.attr(type='gate')
     def test_list_services(self):
         resp, services = self.client.list_services()
-        self.validate_response(schema.list_services, resp, services)
+        self.assertEqual(200, resp.status)
         self.assertNotEqual(0, len(services))
 
     @test.attr(type='gate')
@@ -41,7 +40,7 @@
         binary_name = 'nova-compute'
         params = {'binary': binary_name}
         resp, services = self.client.list_services(params)
-        self.validate_response(schema.list_services, resp, services)
+        self.assertEqual(200, resp.status)
         self.assertNotEqual(0, len(services))
         for service in services:
             self.assertEqual(binary_name, service['binary'])
@@ -49,14 +48,12 @@
     @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.
@@ -70,13 +67,12 @@
     @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.validate_response(schema.list_services, resp, services)
+        self.assertEqual(200, resp.status)
         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_simple_tenant_usage.py b/tempest/api/compute/admin/test_simple_tenant_usage.py
index cc8641f..33cd6f3 100644
--- a/tempest/api/compute/admin/test_simple_tenant_usage.py
+++ b/tempest/api/compute/admin/test_simple_tenant_usage.py
@@ -14,10 +14,10 @@
 #    under the License.
 
 import datetime
+import time
 
 from tempest.api.compute import base
 from tempest import test
-import time
 
 
 class TenantUsagesTestJSON(base.BaseV2ComputeAdminTest):
diff --git a/tempest/api/compute/api_schema/services.py b/tempest/api/compute/api_schema/services.py
deleted file mode 100644
index ef5868c..0000000
--- a/tempest/api/compute/api_schema/services.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# 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 e9b9efa..abd36a6 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -15,8 +15,6 @@
 
 import time
 
-import jsonschema
-
 from tempest import clients
 from tempest.common.utils import data_utils
 from tempest import config
@@ -178,25 +176,6 @@
 
         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:
-            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())
@@ -432,3 +411,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/floating_ips/test_floating_ips_actions.py b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
index c0f7af0..abd8a4c 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
@@ -24,10 +24,11 @@
     floating_ip = None
 
     @classmethod
+    @test.safe_setup
     def setUpClass(cls):
         super(FloatingIPsTestJSON, cls).setUpClass()
         cls.client = cls.floating_ips_client
-        #cls.servers_client = cls.servers_client
+        cls.floating_ip_id = None
 
         # Server creation
         resp, server = cls.create_test_server(wait_until='ACTIVE')
@@ -40,7 +41,8 @@
     @classmethod
     def tearDownClass(cls):
         # Deleting the floating IP which is created in this method
-        resp, body = cls.client.delete_floating_ip(cls.floating_ip_id)
+        if cls.floating_ip_id:
+            resp, body = cls.client.delete_floating_ip(cls.floating_ip_id)
         super(FloatingIPsTestJSON, cls).tearDownClass()
 
     @test.attr(type='gate')
diff --git a/tempest/api/compute/images/test_image_metadata.py b/tempest/api/compute/images/test_image_metadata.py
index 195a018..91eb4c5 100644
--- a/tempest/api/compute/images/test_image_metadata.py
+++ b/tempest/api/compute/images/test_image_metadata.py
@@ -24,14 +24,15 @@
 class ImagesMetadataTestJSON(base.BaseV2ComputeTest):
 
     @classmethod
+    @test.safe_setup
     def setUpClass(cls):
         super(ImagesMetadataTestJSON, 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.servers_client = cls.servers_client
         cls.client = cls.images_client
+        cls.image_id = None
 
         resp, server = cls.create_test_server(wait_until='ACTIVE')
         cls.server_id = server['id']
@@ -45,7 +46,8 @@
 
     @classmethod
     def tearDownClass(cls):
-        cls.client.delete_image(cls.image_id)
+        if cls.image_id:
+            cls.client.delete_image(cls.image_id)
         super(ImagesMetadataTestJSON, cls).tearDownClass()
 
     def setUp(self):
diff --git a/tempest/api/compute/images/test_images_oneserver.py b/tempest/api/compute/images/test_images_oneserver.py
index b152c3c..d2fd970 100644
--- a/tempest/api/compute/images/test_images_oneserver.py
+++ b/tempest/api/compute/images/test_images_oneserver.py
@@ -13,7 +13,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import testtools
 
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
@@ -61,8 +60,6 @@
         resp, flavor = self.flavors_client.get_flavor_details(flavor_id)
         return flavor['disk']
 
-    @testtools.skipUnless(CONF.compute_feature_enabled.create_image,
-                          'Environment unable to create images.')
     @test.attr(type='smoke')
     def test_create_delete_image(self):
 
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index ddf37ce..778294e 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -186,8 +186,7 @@
 
         admin_pass = self.image_ssh_password
 
-        resp, server_no_eph_disk = (self.
-                                    create_test_server(
+        resp, server_no_eph_disk = (self.create_test_server(
                                     wait_until='ACTIVE',
                                     adminPass=admin_pass,
                                     flavor=flavor_no_eph_disk_id))
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 837114c..f0913f1 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -26,6 +26,7 @@
 class ListServerFiltersTestJSON(base.BaseV2ComputeTest):
 
     @classmethod
+    @test.safe_setup
     def setUpClass(cls):
         super(ListServerFiltersTestJSON, cls).setUpClass()
         cls.client = cls.servers_client
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index bde0f57..21465d8 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -17,6 +17,7 @@
 import time
 
 import testtools
+import urlparse
 
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
@@ -382,6 +383,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}
@@ -422,6 +428,29 @@
         self.assertEqual(202, resp.status)
         self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
 
+    def _validate_url(self, url):
+        valid_scheme = ['http', 'https']
+        parsed_url = urlparse.urlparse(url)
+        self.assertNotEqual('None', parsed_url.port)
+        self.assertNotEqual('None', parsed_url.hostname)
+        self.assertIn(parsed_url.scheme, valid_scheme)
+
+    @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 of type 'novnc' and 'xvpvnc'
+        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,
+                "Failed to get Console Type: %s" % (console_types))
+            self.assertEqual(console_type, body['type'])
+            self.assertNotEqual('', body['url'])
+            self._validate_url(body['url'])
+
 
 class ServerActionsTestXML(ServerActionsTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/servers/test_server_rescue_negative.py b/tempest/api/compute/servers/test_server_rescue_negative.py
index 277f28f..e027567 100644
--- a/tempest/api/compute/servers/test_server_rescue_negative.py
+++ b/tempest/api/compute/servers/test_server_rescue_negative.py
@@ -45,6 +45,11 @@
             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,
diff --git a/tempest/api/compute/test_quotas.py b/tempest/api/compute/test_quotas.py
index 230d433..4db8c56 100644
--- a/tempest/api/compute/test_quotas.py
+++ b/tempest/api/compute/test_quotas.py
@@ -27,6 +27,9 @@
         resp, tenants = cls.admin_client.list_tenants()
         cls.tenant_id = [tnt['id'] for tnt in tenants if tnt['name'] ==
                          cls.client.tenant_name][0]
+        resp, users = cls.admin_client.list_users_for_tenant(cls.tenant_id)
+        cls.user_id = [user['id'] for user in users if user['name'] ==
+                       cls.client.user][0]
         cls.default_quota_set = set(('injected_file_content_bytes',
                                      'metadata_items', 'injected_files',
                                      'ram', 'floating_ips',
@@ -45,6 +48,14 @@
                          sorted(quota_set.keys()))
         self.assertEqual(quota_set['id'], self.tenant_id)
 
+        # get the quota set using user id
+        resp, quota_set = self.client.get_quota_set(self.tenant_id,
+                                                    self.user_id)
+        self.assertEqual(200, resp.status)
+        self.assertEqual(sorted(expected_quota_set),
+                         sorted(quota_set.keys()))
+        self.assertEqual(quota_set['id'], self.tenant_id)
+
     @test.attr(type='smoke')
     def test_get_default_quotas(self):
         # User can get the default quota set for it's tenant
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_quotas.py b/tempest/api/compute/v3/admin/test_quotas.py
index 0c138bb..917c115 100644
--- a/tempest/api/compute/v3/admin/test_quotas.py
+++ b/tempest/api/compute/v3/admin/test_quotas.py
@@ -56,7 +56,7 @@
     def test_get_quota_set_detail(self):
         # Admin can get the detail of resource quota set for a tenant
         expected_quota_set = self.default_quota_set | set(['id'])
-        expected_detail = {'reserved', 'limit', 'in_use'}
+        expected_detail = ['reserved', 'limit', 'in_use']
         resp, quota_set = self.adm_client.get_quota_set_detail(
             self.demo_tenant_id)
         self.assertEqual(200, resp.status)
@@ -109,3 +109,26 @@
         resp, quota_set = self.adm_client.get_quota_set(tenant_id)
         self.assertEqual(200, resp.status)
         self.assertEqual(quota_set['ram'], 5120)
+
+    @test.attr(type='gate')
+    def test_delete_quota(self):
+        # Admin can delete the resource quota set for a tenant
+        tenant_name = data_utils.rand_name('cpu_quota_tenant_')
+        tenant_desc = tenant_name + '-desc'
+        identity_client = self.os_adm.identity_client
+        _, tenant = identity_client.create_tenant(name=tenant_name,
+                                                  description=tenant_desc)
+        tenant_id = tenant['id']
+        self.addCleanup(identity_client.delete_tenant, tenant_id)
+        resp, quota_set_default = self.adm_client.get_quota_set(tenant_id)
+        self.assertEqual(200, resp.status)
+        ram_default = quota_set_default['ram']
+
+        self.adm_client.update_quota_set(tenant_id, ram='5120')
+        self.assertEqual(200, resp.status)
+        resp, _ = self.adm_client.delete_quota_set(tenant_id)
+        self.assertEqual(204, resp.status)
+
+        resp, quota_set_new = self.adm_client.get_quota_set(tenant_id)
+        self.assertEqual(200, resp.status)
+        self.assertEqual(ram_default, quota_set_new['ram'])
diff --git a/tempest/api/compute/v3/admin/test_services.py b/tempest/api/compute/v3/admin/test_services.py
index 0a7c7f1..b367dad 100644
--- a/tempest/api/compute/v3/admin/test_services.py
+++ b/tempest/api/compute/v3/admin/test_services.py
@@ -14,7 +14,6 @@
 #    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
 
@@ -33,7 +32,7 @@
     @attr(type='gate')
     def test_list_services(self):
         resp, services = self.client.list_services()
-        self.validate_response(schema.list_services, resp, services)
+        self.assertEqual(200, resp.status)
         self.assertNotEqual(0, len(services))
 
     @attr(type='gate')
@@ -41,7 +40,7 @@
         binary_name = 'nova-compute'
         params = {'binary': binary_name}
         resp, services = self.client.list_services(params)
-        self.validate_response(schema.list_services, resp, services)
+        self.assertEqual(200, resp.status)
         self.assertNotEqual(0, len(services))
         for service in services:
             self.assertEqual(binary_name, service['binary'])
@@ -49,14 +48,13 @@
     @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)
+        self.assertEqual(200, resp.status)
         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.
@@ -70,13 +68,12 @@
     @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.validate_response(schema.list_services, resp, services)
+        self.assertEqual(200, resp.status)
         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/images/test_images_negative.py b/tempest/api/compute/v3/images/test_images_negative.py
index c38373f..0705bdc 100644
--- a/tempest/api/compute/v3/images/test_images_negative.py
+++ b/tempest/api/compute/v3/images/test_images_negative.py
@@ -35,7 +35,7 @@
         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')
+        self.client.wait_for_image_status(image_id, 'active')
         return resp, body
 
     @test.attr(type=['negative', 'gate'])
diff --git a/tempest/api/compute/v3/images/test_images_oneserver.py b/tempest/api/compute/v3/images/test_images_oneserver.py
index 48a885e..3aab1e1 100644
--- a/tempest/api/compute/v3/images/test_images_oneserver.py
+++ b/tempest/api/compute/v3/images/test_images_oneserver.py
@@ -13,7 +13,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import testtools
 
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
@@ -61,8 +60,6 @@
         resp, flavor = self.flavors_client.get_flavor_details(flavor_id)
         return flavor['disk']
 
-    @testtools.skipUnless(CONF.compute_feature_enabled.create_image,
-                          'Environment unable to create images.')
     @test.attr(type='smoke')
     def test_create_delete_image(self):
 
@@ -73,26 +70,26 @@
                                                       name, meta)
         self.assertEqual(202, resp.status)
         image_id = data_utils.parse_image_id(resp['location'])
-        self.client.wait_for_image_status(image_id, 'ACTIVE')
+        self.client.wait_for_image_status(image_id, 'active')
 
         # Verify the image was created correctly
-        resp, image = self.client.get_image(image_id)
+        resp, image = self.client.get_image_meta(image_id)
         self.assertEqual(name, image['name'])
-        self.assertEqual('test', image['metadata']['image_type'])
+        self.assertEqual('test', image['properties']['image_type'])
 
-        resp, original_image = self.client.get_image(self.image_ref)
+        resp, original_image = self.client.get_image_meta(self.image_ref)
 
         # Verify minRAM is the same as the original image
-        self.assertEqual(image['minRam'], original_image['minRam'])
+        self.assertEqual(image['min_ram'], original_image['min_ram'])
 
         # Verify minDisk is the same as the original image or the flavor size
         flavor_disk_size = self._get_default_flavor_disk_size(self.flavor_ref)
-        self.assertIn(str(image['minDisk']),
-                      (str(original_image['minDisk']), str(flavor_disk_size)))
+        self.assertIn(str(image['min_disk']),
+                      (str(original_image['min_disk']), str(flavor_disk_size)))
 
         # Verify the image was deleted correctly
         resp, body = self.client.delete_image(image_id)
-        self.assertEqual('204', resp['status'])
+        self.assertEqual('200', resp['status'])
         self.client.wait_for_resource_deletion(image_id)
 
     @test.attr(type=['gate'])
diff --git a/tempest/api/compute/v3/servers/test_create_server.py b/tempest/api/compute/v3/servers/test_create_server.py
index 2c15784..14a4338 100644
--- a/tempest/api/compute/v3/servers/test_create_server.py
+++ b/tempest/api/compute/v3/servers/test_create_server.py
@@ -187,8 +187,7 @@
 
         admin_pass = self.image_ssh_password
 
-        resp, server_no_eph_disk = (self.
-                                    create_test_server(
+        resp, server_no_eph_disk = (self.create_test_server(
                                     wait_until='ACTIVE',
                                     adminPass=admin_pass,
                                     flavor=flavor_no_eph_disk_id))
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 ec31e8e..2cb176c 100644
--- a/tempest/api/compute/v3/servers/test_list_server_filters.py
+++ b/tempest/api/compute/v3/servers/test_list_server_filters.py
@@ -26,6 +26,7 @@
 class ListServerFiltersV3Test(base.BaseV3ComputeTest):
 
     @classmethod
+    @test.safe_setup
     def setUpClass(cls):
         super(ListServerFiltersV3Test, cls).setUpClass()
         cls.client = cls.servers_client
diff --git a/tempest/api/compute/v3/servers/test_server_actions.py b/tempest/api/compute/v3/servers/test_server_actions.py
index 406c45a..555d028 100644
--- a/tempest/api/compute/v3/servers/test_server_actions.py
+++ b/tempest/api/compute/v3/servers/test_server_actions.py
@@ -372,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)
diff --git a/tempest/api/compute/v3/test_quotas.py b/tempest/api/compute/v3/test_quotas.py
index b53d9be..3fe62e9 100644
--- a/tempest/api/compute/v3/test_quotas.py
+++ b/tempest/api/compute/v3/test_quotas.py
@@ -27,6 +27,9 @@
         resp, tenants = cls.admin_client.list_tenants()
         cls.tenant_id = [tnt['id'] for tnt in tenants if tnt['name'] ==
                          cls.client.tenant_name][0]
+        resp, users = cls.admin_client.list_users_for_tenant(cls.tenant_id)
+        cls.user_id = [user['id'] for user in users if user['name'] ==
+                       cls.client.user][0]
         cls.default_quota_set = set(('metadata_items',
                                      'ram', 'floating_ips',
                                      'fixed_ips', 'key_pairs',
@@ -43,6 +46,14 @@
                          sorted(quota_set.keys()))
         self.assertEqual(quota_set['id'], self.tenant_id)
 
+        # get the quota set using user id
+        resp, quota_set = self.client.get_quota_set(self.tenant_id,
+                                                    self.user_id)
+        self.assertEqual(200, resp.status)
+        self.assertEqual(sorted(expected_quota_set),
+                         sorted(quota_set.keys()))
+        self.assertEqual(quota_set['id'], self.tenant_id)
+
     @test.attr(type='smoke')
     def test_get_default_quotas(self):
         # User can get the default quota set for it's tenant
diff --git a/tempest/api/data_processing/base.py b/tempest/api/data_processing/base.py
index 5b272ef..73ad22b 100644
--- a/tempest/api/data_processing/base.py
+++ b/tempest/api/data_processing/base.py
@@ -27,8 +27,8 @@
     def setUpClass(cls):
         super(BaseDataProcessingTest, cls).setUpClass()
         os = cls.get_client_manager()
-        if not CONF.service_available.savanna:
-            raise cls.skipException("Savanna support is required")
+        if not CONF.service_available.sahara:
+            raise cls.skipException("Sahara support is required")
         cls.client = os.data_processing_client
 
         # set some constants
diff --git a/tempest/api/data_processing/test_node_group_templates.py b/tempest/api/data_processing/test_node_group_templates.py
index ff4fa6a..a64c345 100644
--- a/tempest/api/data_processing/test_node_group_templates.py
+++ b/tempest/api/data_processing/test_node_group_templates.py
@@ -28,7 +28,7 @@
 
         if template_name is None:
             # generate random name if it's not specified
-            template_name = data_utils.rand_name('savanna')
+            template_name = data_utils.rand_name('sahara')
 
         # create simple node group template
         resp, body, template_id = self.create_node_group_template(
diff --git a/tempest/api/identity/admin/test_tokens.py b/tempest/api/identity/admin/test_tokens.py
index 239433b..c931bcf 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,11 +43,62 @@
         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')
 
+    @attr(type='gate')
+    def test_rescope_token(self):
+        """An unscoped token can be requested, that token can be used to
+           request a scoped token.
+        """
+
+        # Create a user.
+        user_name = data_utils.rand_name(name='user-')
+        user_password = data_utils.rand_name(name='pass-')
+        tenant_id = None  # No default tenant so will get unscoped token.
+        email = ''
+        resp, user = self.client.create_user(user_name, user_password,
+                                             tenant_id, email)
+        self.assertEqual(200, resp.status)
+        self.data.users.append(user)
+
+        # Create a tenant.
+        tenant_name = data_utils.rand_name(name='tenant-')
+        resp, tenant = self.client.create_tenant(tenant_name)
+        self.assertEqual(200, resp.status)
+        self.data.tenants.append(tenant)
+
+        # Create a role
+        role_name = data_utils.rand_name(name='role-')
+        resp, role = self.client.create_role(role_name)
+        self.assertEqual(200, resp.status)
+        self.data.roles.append(role)
+
+        # Grant the user the role on the tenant.
+        resp, _ = self.client.assign_user_role(tenant['id'], user['id'],
+                                               role['id'])
+        self.assertEqual(200, resp.status)
+
+        # Get an unscoped token.
+        rsp, body = self.token_client.auth(user_name, user_password)
+        self.assertEqual(200, resp.status)
+
+        token_id = body['token']['id']
+
+        # Use the unscoped token to get a scoped token.
+        rsp, body = self.token_client.auth_token(token_id, tenant=tenant_name)
+        self.assertEqual(200, resp.status)
+
 
 class TokensTestXML(TokensTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/identity/admin/test_users_negative.py b/tempest/api/identity/admin/test_users_negative.py
index 1188325..4e8ebe5 100644
--- a/tempest/api/identity/admin/test_users_negative.py
+++ b/tempest/api/identity/admin/test_users_negative.py
@@ -13,11 +13,12 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import uuid
+
 from tempest.api.identity import base
 from tempest.common.utils import data_utils
 from tempest import exceptions
 from tempest.test import attr
-import uuid
 
 
 class UsersNegativeTestJSON(base.BaseIdentityV2AdminTest):
diff --git a/tempest/api/identity/admin/v3/test_endpoints.py b/tempest/api/identity/admin/v3/test_endpoints.py
index 05b704f..0e4d66b 100644
--- a/tempest/api/identity/admin/v3/test_endpoints.py
+++ b/tempest/api/identity/admin/v3/test_endpoints.py
@@ -102,6 +102,7 @@
             self.client.create_endpoint(self.service_id, interface1,
                                         url1, region=region1,
                                         enabled=True)
+        self.addCleanup(self.client.delete_endpoint, endpoint_for_update['id'])
         # Creating service so as update endpoint with new service ID
         s_name = data_utils.rand_name('service-')
         s_type = data_utils.rand_name('type--')
@@ -126,7 +127,6 @@
         self.assertEqual(url2, endpoint['url'])
         self.assertEqual(region2, endpoint['region'])
         self.assertEqual('false', str(endpoint['enabled']).lower())
-        self.addCleanup(self.client.delete_endpoint, endpoint_for_update['id'])
 
 
 class EndPointsTestXML(EndPointsTestJSON):
diff --git a/tempest/api/identity/admin/v3/test_endpoints_negative.py b/tempest/api/identity/admin/v3/test_endpoints_negative.py
new file mode 100644
index 0000000..28615a4
--- /dev/null
+++ b/tempest/api/identity/admin/v3/test_endpoints_negative.py
@@ -0,0 +1,94 @@
+
+# Copyright 2013 IBM Corp.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+
+from tempest.api.identity import base
+from tempest.common.utils import data_utils
+from tempest import exceptions
+from tempest.test import attr
+
+
+class EndpointsNegativeTestJSON(base.BaseIdentityV3AdminTest):
+    _interface = 'json'
+
+    @classmethod
+    def setUpClass(cls):
+        super(EndpointsNegativeTestJSON, cls).setUpClass()
+        cls.identity_client = cls.client
+        cls.client = cls.endpoints_client
+        cls.service_ids = list()
+        s_name = data_utils.rand_name('service-')
+        s_type = data_utils.rand_name('type--')
+        s_description = data_utils.rand_name('description-')
+        resp, cls.service_data = (
+            cls.service_client.create_service(s_name, s_type,
+                                              description=s_description))
+        cls.service_id = cls.service_data['id']
+        cls.service_ids.append(cls.service_id)
+
+    @classmethod
+    def tearDownClass(cls):
+        for s in cls.service_ids:
+            cls.service_client.delete_service(s)
+        super(EndpointsNegativeTestJSON, cls).tearDownClass()
+
+    @attr(type=['negative', 'gate'])
+    def test_create_with_enabled_False(self):
+        # Enabled should be a boolean, not a string like 'False'
+        interface = 'public'
+        url = data_utils.rand_name('url')
+        region = data_utils.rand_name('region')
+        self.assertRaises(exceptions.BadRequest, self.client.create_endpoint,
+                          self.service_id, interface, url, region=region,
+                          force_enabled='False')
+
+    @attr(type=['negative', 'gate'])
+    def test_create_with_enabled_True(self):
+        # Enabled should be a boolean, not a string like 'True'
+        interface = 'public'
+        url = data_utils.rand_name('url')
+        region = data_utils.rand_name('region')
+        self.assertRaises(exceptions.BadRequest, self.client.create_endpoint,
+                          self.service_id, interface, url, region=region,
+                          force_enabled='True')
+
+    def _assert_update_raises_bad_request(self, enabled):
+
+        # Create an endpoint
+        region1 = data_utils.rand_name('region')
+        url1 = data_utils.rand_name('url')
+        interface1 = 'public'
+        resp, endpoint_for_update = (
+            self.client.create_endpoint(self.service_id, interface1,
+                                        url1, region=region1, enabled=True))
+        self.addCleanup(self.client.delete_endpoint, endpoint_for_update['id'])
+
+        self.assertRaises(exceptions.BadRequest, self.client.update_endpoint,
+                          endpoint_for_update['id'], force_enabled=enabled)
+
+    @attr(type=['negative', 'gate'])
+    def test_update_with_enabled_False(self):
+        # Enabled should be a boolean, not a string like 'False'
+        self._assert_update_raises_bad_request('False')
+
+    @attr(type=['negative', 'gate'])
+    def test_update_with_enabled_True(self):
+        # Enabled should be a boolean, not a string like 'True'
+        self._assert_update_raises_bad_request('True')
+
+
+class EndpointsNegativeTestXML(EndpointsNegativeTestJSON):
+    _interface = 'xml'
diff --git a/tempest/api/image/v2/test_images.py b/tempest/api/image/v2/test_images.py
index ce11911..abde8f7 100644
--- a/tempest/api/image/v2/test_images.py
+++ b/tempest/api/image/v2/test_images.py
@@ -101,6 +101,7 @@
                                               disk_format='iso',
                                               visibility='public')
         self.assertEqual(201, resp.status)
+        self.addCleanup(self.client.delete_image, body['id'])
         self.assertEqual('queued', body['status'])
         image_id = body['id']
 
diff --git a/tempest/api/network/admin/test_l3_agent_scheduler.py b/tempest/api/network/admin/test_l3_agent_scheduler.py
index eb397ba..f4050c5 100644
--- a/tempest/api/network/admin/test_l3_agent_scheduler.py
+++ b/tempest/api/network/admin/test_l3_agent_scheduler.py
@@ -76,11 +76,8 @@
         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)
+        # NOTE(afazekas): The deletion not asserted, because neutron
+        # is not forbidden to reschedule the router to the same agent
 
 
 class L3AgentSchedulerTestXML(L3AgentSchedulerTestJSON):
diff --git a/tempest/api/network/admin/test_load_balancer_admin_actions.py b/tempest/api/network/admin/test_load_balancer_admin_actions.py
new file mode 100644
index 0000000..34a8e32
--- /dev/null
+++ b/tempest/api/network/admin/test_load_balancer_admin_actions.py
@@ -0,0 +1,94 @@
+# Copyright 2014 Mirantis.inc
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.api.network import base
+from tempest.common.utils import data_utils
+from tempest import test
+
+
+class LoadBalancerAdminTestJSON(base.BaseAdminNetworkTest):
+    _interface = 'json'
+
+    """
+    Test admin actions for load balancer.
+
+    Create VIP for another tenant
+    Create health monitor for another tenant
+    """
+
+    @classmethod
+    def setUpClass(cls):
+        super(LoadBalancerAdminTestJSON, cls).setUpClass()
+        if not test.is_extension_enabled('lbaas', 'network'):
+            msg = "lbaas extension not enabled."
+            raise cls.skipException(msg)
+        cls.force_tenant_isolation = True
+        manager = cls.get_client_manager()
+        cls.client = manager.network_client
+        username, tenant_name, passwd = cls.isolated_creds.get_primary_creds()
+        cls.tenant_id = cls.os_adm.identity_client.get_tenant_by_name(
+            tenant_name)['id']
+        cls.network = cls.create_network()
+        cls.subnet = cls.create_subnet(cls.network)
+
+    @test.attr(type='smoke')
+    def test_create_vip_as_admin_for_another_tenant(self):
+        name = data_utils.rand_name('vip-')
+        resp, body = self.admin_client.create_pool(
+            name=data_utils.rand_name('pool-'), lb_method="ROUND_ROBIN",
+            protocol="HTTP", subnet_id=self.subnet['id'],
+            tenant_id=self.tenant_id)
+        self.assertEqual('201', resp['status'])
+        pool = body['pool']
+        self.addCleanup(self.admin_client.delete_pool, pool['id'])
+        resp, body = self.admin_client.create_vip(name=name,
+                                                  protocol="HTTP",
+                                                  protocol_port=80,
+                                                  subnet_id=self.subnet['id'],
+                                                  pool_id=pool['id'],
+                                                  tenant_id=self.tenant_id)
+        self.assertEqual('201', resp['status'])
+        vip = body['vip']
+        self.addCleanup(self.admin_client.delete_vip, vip['id'])
+        self.assertIsNotNone(vip['id'])
+        self.assertEqual(self.tenant_id, vip['tenant_id'])
+        resp, body = self.client.show_vip(vip['id'])
+        self.assertEqual('200', resp['status'])
+        show_vip = body['vip']
+        self.assertEqual(vip['id'], show_vip['id'])
+        self.assertEqual(vip['name'], show_vip['name'])
+
+    @test.attr(type='smoke')
+    def test_create_health_monitor_as_admin_for_another_tenant(self):
+        resp, body = (
+            self.admin_client.create_health_monitor(delay=4,
+                                                    max_retries=3,
+                                                    type="TCP",
+                                                    timeout=1,
+                                                    tenant_id=self.tenant_id))
+        self.assertEqual('201', resp['status'])
+        health_monitor = body['health_monitor']
+        self.addCleanup(self.admin_client.delete_health_monitor,
+                        health_monitor['id'])
+        self.assertIsNotNone(health_monitor['id'])
+        self.assertEqual(self.tenant_id, health_monitor['tenant_id'])
+        resp, body = self.client.show_health_monitor(health_monitor['id'])
+        self.assertEqual('200', resp['status'])
+        show_health_monitor = body['health_monitor']
+        self.assertEqual(health_monitor['id'], show_health_monitor['id'])
+
+
+class LoadBalancerAdminTestXML(LoadBalancerAdminTestJSON):
+    _interface = 'xml'
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index 93335e7..231c4bf 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -242,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/test_load_balancer.py b/tempest/api/network/test_load_balancer.py
index 03e095d..792d61d 100644
--- a/tempest/api/network/test_load_balancer.py
+++ b/tempest/api/network/test_load_balancer.py
@@ -61,22 +61,54 @@
                                                        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-')
+        address = self.subnet['allocation_pools'][0]['end']
         resp, body = self.client.create_pool(
             name=data_utils.rand_name("pool-"),
             lb_method='ROUND_ROBIN',
@@ -87,19 +119,40 @@
                                             protocol="HTTP",
                                             protocol_port=80,
                                             subnet_id=self.subnet['id'],
-                                            pool_id=pool['id'])
+                                            pool_id=pool['id'],
+                                            address=address)
         self.assertEqual('201', resp['status'])
         vip = body['vip']
         vip_id = vip['id']
+        # Confirm VIP's address correctness with a show
+        resp, body = self.client.show_vip(vip_id)
+        self.assertEqual('200', resp['status'])
+        vip = body['vip']
+        self.assertEqual(address, vip['address'])
         # Verification of vip update
         new_name = "New_vip"
-        resp, body = self.client.update_vip(vip_id, name=new_name)
+        new_description = "New description"
+        persistence_type = "HTTP_COOKIE"
+        update_data = {"session_persistence": {
+            "type": persistence_type}}
+        resp, body = self.client.update_vip(vip_id,
+                                            name=new_name,
+                                            description=new_description,
+                                            connection_limit=10,
+                                            admin_state_up=False,
+                                            **update_data)
         self.assertEqual('200', resp['status'])
         updated_vip = body['vip']
-        self.assertEqual(updated_vip['name'], new_name)
+        self.assertEqual(new_name, updated_vip['name'])
+        self.assertEqual(new_description, updated_vip['description'])
+        self.assertEqual(10, updated_vip['connection_limit'])
+        self.assertFalse(updated_vip['admin_state_up'])
+        self.assertEqual(persistence_type,
+                         updated_vip['session_persistence']['type'])
         # 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 +170,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 +204,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 +223,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 +253,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 +268,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,
@@ -201,14 +295,49 @@
         self.assertEqual('204', resp['status'])
 
     @test.attr(type='smoke')
+    def test_create_health_monitor_http_type(self):
+        hm_type = "HTTP"
+        resp, body = self.client.create_health_monitor(delay=4,
+                                                       max_retries=3,
+                                                       type=hm_type,
+                                                       timeout=1)
+        self.assertEqual('201', resp['status'])
+        health_monitor = body['health_monitor']
+        self.addCleanup(self.client.delete_health_monitor,
+                        health_monitor['id'])
+        self.assertEqual(hm_type, health_monitor['type'])
+
+    @test.attr(type='smoke')
+    def test_update_health_monitor_http_method(self):
+        resp, body = self.client.create_health_monitor(delay=4,
+                                                       max_retries=3,
+                                                       type="HTTP",
+                                                       timeout=1)
+        self.assertEqual('201', resp['status'])
+        health_monitor = body['health_monitor']
+        self.addCleanup(self.client.delete_health_monitor,
+                        health_monitor['id'])
+        resp, body = (self.client.update_health_monitor
+                     (health_monitor['id'],
+                      http_method="POST",
+                      url_path="/home/user",
+                      expected_codes="290"))
+        self.assertEqual('200', resp['status'])
+        updated_health_monitor = body['health_monitor']
+        self.assertEqual("POST", updated_health_monitor['http_method'])
+        self.assertEqual("/home/user", updated_health_monitor['url_path'])
+        self.assertEqual("290", updated_health_monitor['expected_codes'])
+
+    @test.attr(type='smoke')
     def test_show_health_monitor(self):
         # Verifies the details of a health_monitor
         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 +345,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 1155257..70fb00a 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -67,17 +67,16 @@
         cls.name = cls.network['name']
         cls.subnet = cls.create_subnet(cls.network)
         cls.cidr = cls.subnet['cidr']
-        cls.port = cls.create_port(cls.network)
 
     @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'])
@@ -86,13 +85,12 @@
         # Find a cidr that is not in use yet and create a subnet with it
         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'])
@@ -103,191 +101,87 @@
 
     @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")
-
-    @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'])
-        self.assertEqual('201', resp['status'])
-        port = body['port']
-        self.assertTrue(port['admin_state_up'])
-        # Verification of port update
-        new_port = "New_Port"
-        resp, body = self.client.update_port(
-            port['id'],
-            name=new_port,
-            admin_state_up=False)
-        self.assertEqual('200', resp['status'])
-        updated_port = body['port']
-        self.assertEqual(updated_port['name'], new_port)
-        self.assertFalse(updated_port['admin_state_up'])
-        # Verification of port delete
-        resp, body = self.client.delete_port(port['id'])
-        self.assertEqual('204', resp['status'])
-
-    @attr(type='smoke')
-    def test_show_port(self):
-        # Verify the details of port
-        resp, body = self.client.show_port(self.port['id'])
-        self.assertEqual('200', resp['status'])
-        port = body['port']
-        self.assertEqual(self.port['id'], port['id'])
-
-    @attr(type='smoke')
-    def test_show_port_fields(self):
-        # Verifies showing fields of a port works
-        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'])
-
-    @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")
-
-    @attr(type='smoke')
-    def test_port_list_filter_by_router_id(self):
-        # Create a router
-        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'])
-        # 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
-        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'])
-
-    @attr(type='smoke')
-    def test_list_ports_fields(self):
-        # Verify listing some fields of the 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")
+        self.assertNotEmpty(subnets, "Subnet list returned is empty")
+        for subnet in subnets:
+            self.assertEqual(len(subnet), 1)
+            self.assertIn('id', subnet)
 
 
 class NetworksTestXML(NetworksTestJSON):
@@ -328,9 +222,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)
 
@@ -340,9 +232,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)
 
@@ -352,9 +242,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)
 
@@ -369,9 +257,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)
@@ -381,14 +267,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]
@@ -399,17 +281,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)
@@ -417,10 +297,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)):
@@ -437,9 +315,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)
diff --git a/tempest/api/network/test_ports.py b/tempest/api/network/test_ports.py
new file mode 100644
index 0000000..fbb25a8
--- /dev/null
+++ b/tempest/api/network/test_ports.py
@@ -0,0 +1,249 @@
+# 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.
+
+import socket
+
+from tempest.api.network import base
+from tempest.common.utils import data_utils
+from tempest import config
+from tempest import test
+
+CONF = config.CONF
+
+
+class PortsTestJSON(base.BaseNetworkTest):
+    _interface = 'json'
+
+    @classmethod
+    def setUpClass(cls):
+        super(PortsTestJSON, cls).setUpClass()
+        cls.network = cls.create_network()
+        cls.port = cls.create_port(cls.network)
+
+    def _delete_port(self, port_id):
+        resp, body = self.client.delete_port(port_id)
+        self.assertEqual('204', resp['status'])
+        resp, body = self.client.list_ports()
+        self.assertEqual('200', resp['status'])
+        ports_list = body['ports']
+        self.assertFalse(port_id in [n['id'] for n in ports_list])
+
+    @test.attr(type='smoke')
+    def test_create_update_delete_port(self):
+        # 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'])
+        # Verify port update
+        new_name = "New_Port"
+        resp, body = self.client.update_port(
+            port['id'],
+            name=new_name,
+            admin_state_up=False)
+        self.assertEqual('200', resp['status'])
+        updated_port = body['port']
+        self.assertEqual(updated_port['name'], new_name)
+        self.assertFalse(updated_port['admin_state_up'])
+        # Verify port deletion
+        resp, body = self.client.delete_port(port['id'])
+        self.assertEqual('204', resp['status'])
+
+    @test.attr(type='smoke')
+    def test_show_port(self):
+        # Verify the details of port
+        resp, body = self.client.show_port(self.port['id'])
+        self.assertEqual('200', resp['status'])
+        port = body['port']
+        self.assertIn('id', port)
+        self.assertEqual(port['id'], self.port['id'])
+        self.assertEqual(self.port['admin_state_up'], port['admin_state_up'])
+        self.assertEqual(self.port['device_id'], port['device_id'])
+        self.assertEqual(self.port['device_owner'], port['device_owner'])
+        self.assertEqual(self.port['mac_address'], port['mac_address'])
+        self.assertEqual(self.port['name'], port['name'])
+        self.assertEqual(self.port['security_groups'],
+                         port['security_groups'])
+        self.assertEqual(self.port['network_id'], port['network_id'])
+        self.assertEqual(self.port['security_groups'],
+                         port['security_groups'])
+
+    @test.attr(type='smoke')
+    def test_show_port_fields(self):
+        # 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), len(field_list))
+        for label, field_name in field_list:
+            self.assertEqual(port[field_name], self.port[field_name])
+
+    @test.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 = [port['id'] for port in body['ports']
+                 if port['id'] == self.port['id']]
+        self.assertNotEmpty(ports, "Created port not found in the list")
+
+    @test.attr(type='smoke')
+    def test_port_list_filter_by_router_id(self):
+        # Create a router
+        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'])
+        # 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
+        resp, port_list = self.client.list_ports(
+            device_id=router['id'])
+        self.assertEqual('200', resp['status'])
+        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'])
+
+    @test.attr(type='smoke')
+    def test_list_ports_fields(self):
+        # Verify specific fields of ports
+        resp, body = self.client.list_ports(fields='id')
+        self.assertEqual('200', resp['status'])
+        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 PortsTestXML(PortsTestJSON):
+    _interface = 'xml'
+
+
+class PortsAdminExtendedAttrsTestJSON(base.BaseAdminNetworkTest):
+    _interface = 'json'
+
+    @classmethod
+    def setUpClass(cls):
+        super(PortsAdminExtendedAttrsTestJSON, cls).setUpClass()
+        cls.identity_client = cls._get_identity_admin_client()
+        cls.tenant = cls.identity_client.get_tenant_by_name(
+            CONF.identity.tenant_name)
+        cls.network = cls.create_network()
+        cls.host_id = socket.gethostname()
+
+    @test.attr(type='smoke')
+    def test_create_port_binding_ext_attr(self):
+        post_body = {"network_id": self.network['id'],
+                     "binding:host_id": self.host_id}
+        resp, body = self.admin_client.create_port(**post_body)
+        self.assertEqual('201', resp['status'])
+        port = body['port']
+        self.addCleanup(self.admin_client.delete_port, port['id'])
+        host_id = port['binding:host_id']
+        self.assertIsNotNone(host_id)
+        self.assertEqual(self.host_id, host_id)
+
+    @test.attr(type='smoke')
+    def test_update_port_binding_ext_attr(self):
+        post_body = {"network_id": self.network['id']}
+        resp, body = self.admin_client.create_port(**post_body)
+        self.assertEqual('201', resp['status'])
+        port = body['port']
+        self.addCleanup(self.admin_client.delete_port, port['id'])
+        update_body = {"binding:host_id": self.host_id}
+        resp, body = self.admin_client.update_port(port['id'], **update_body)
+        self.assertEqual('200', resp['status'])
+        updated_port = body['port']
+        host_id = updated_port['binding:host_id']
+        self.assertIsNotNone(host_id)
+        self.assertEqual(self.host_id, host_id)
+
+    @test.attr(type='smoke')
+    def test_list_ports_binding_ext_attr(self):
+        resp, body = self.admin_client.list_ports(
+            **{'tenant_id': self.tenant['id']})
+        self.assertEqual('200', resp['status'])
+        ports_list = body['ports']
+        for port in ports_list:
+            vif_type = port['binding:vif_type']
+            self.assertIsNotNone(vif_type)
+            vif_details = port['binding:vif_details']['port_filter']
+            self.assertIsNotNone(vif_details)
+
+    @test.attr(type='smoke')
+    def test_show_port_binding_ext_attr(self):
+        resp, body = self.admin_client.create_port(
+            network_id=self.network['id'])
+        self.assertEqual('201', resp['status'])
+        port = body['port']
+        self.addCleanup(self.admin_client.delete_port, port['id'])
+        resp, body = self.admin_client.show_port(port['id'])
+        self.assertEqual('200', resp['status'])
+        show_port = body['port']
+        self.assertEqual(port['binding:host_id'],
+                         show_port['binding:host_id'])
+        self.assertEqual(port['binding:vif_type'],
+                         show_port['binding:vif_type'])
+        self.assertEqual(port['binding:vif_details'],
+                         show_port['binding:vif_details'])
+
+
+class PortsAdminExtendedAttrsTestXML(PortsAdminExtendedAttrsTestJSON):
+    _interface = 'xml'
+
+
+class PortsIpV6TestJSON(PortsTestJSON):
+    _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(PortsIpV6TestJSON, cls).setUpClass()
+        if not CONF.network_feature_enabled.ipv6:
+            cls.tearDownClass()
+            skip_msg = "IPv6 Tests are disabled."
+            raise cls.skipException(skip_msg)
+
+
+class PortsIpV6TestXML(PortsIpV6TestJSON):
+    _interface = 'xml'
+
+
+class PortsAdminExtendedAttrsIpV6TestJSON(PortsAdminExtendedAttrsTestJSON):
+    _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(PortsAdminExtendedAttrsIpV6TestJSON, cls).setUpClass()
+        if not CONF.network_feature_enabled.ipv6:
+            cls.tearDownClass()
+            skip_msg = "IPv6 Tests are disabled."
+            raise cls.skipException(skip_msg)
+
+
+class PortsAdminExtendedAttrsIpV6TestXML(
+    PortsAdminExtendedAttrsIpV6TestJSON):
+    _interface = 'xml'
diff --git a/tempest/api/object_storage/test_account_quotas.py b/tempest/api/object_storage/test_account_quotas.py
index b14adc0..a3098a5 100644
--- a/tempest/api/object_storage/test_account_quotas.py
+++ b/tempest/api/object_storage/test_account_quotas.py
@@ -68,7 +68,7 @@
         # Retrieve a ResellerAdmin auth data and use it to set a quota
         # on the client's account
         cls.reselleradmin_auth_data = \
-            cls.os_reselleradmin.get_auth_provider().auth_data
+            cls.os_reselleradmin.auth_provider.auth_data
 
     def setUp(self):
         super(AccountQuotasTest, self).setUp()
diff --git a/tempest/api/object_storage/test_account_quotas_negative.py b/tempest/api/object_storage/test_account_quotas_negative.py
index 402cd90..7648ea1 100644
--- a/tempest/api/object_storage/test_account_quotas_negative.py
+++ b/tempest/api/object_storage/test_account_quotas_negative.py
@@ -68,7 +68,7 @@
         # Retrieve a ResellerAdmin auth data and use it to set a quota
         # on the client's account
         cls.reselleradmin_auth_data = \
-            cls.os_reselleradmin.get_auth_provider().auth_data
+            cls.os_reselleradmin.auth_provider.auth_data
 
     def setUp(self):
         super(AccountQuotasNegativeTest, self).setUp()
diff --git a/tempest/api/object_storage/test_account_services_negative.py b/tempest/api/object_storage/test_account_services_negative.py
index ea93aa3..71eaab5 100644
--- a/tempest/api/object_storage/test_account_services_negative.py
+++ b/tempest/api/object_storage/test_account_services_negative.py
@@ -31,7 +31,7 @@
         test_os = clients.Manager(self.data.test_user,
                                   self.data.test_password,
                                   self.data.test_tenant)
-        test_auth_provider = test_os.get_auth_provider()
+        test_auth_provider = test_os.auth_provider
         # Get auth for the test user
         test_auth_provider.auth_data
 
diff --git a/tempest/api/object_storage/test_container_acl.py b/tempest/api/object_storage/test_container_acl.py
index 085ef51..c865ee1 100644
--- a/tempest/api/object_storage/test_container_acl.py
+++ b/tempest/api/object_storage/test_container_acl.py
@@ -27,7 +27,7 @@
         test_os = clients.Manager(cls.data.test_user,
                                   cls.data.test_password,
                                   cls.data.test_tenant)
-        cls.test_auth_data = test_os.get_auth_provider().auth_data
+        cls.test_auth_data = test_os.auth_provider.auth_data
 
     @classmethod
     def tearDownClass(cls):
diff --git a/tempest/api/object_storage/test_container_acl_negative.py b/tempest/api/object_storage/test_container_acl_negative.py
index a5a0950..547bf87 100644
--- a/tempest/api/object_storage/test_container_acl_negative.py
+++ b/tempest/api/object_storage/test_container_acl_negative.py
@@ -29,7 +29,7 @@
         test_os = clients.Manager(cls.data.test_user,
                                   cls.data.test_password,
                                   cls.data.test_tenant)
-        cls.test_auth_data = test_os.get_auth_provider().auth_data
+        cls.test_auth_data = test_os.auth_provider.auth_data
 
     @classmethod
     def tearDownClass(cls):
diff --git a/tempest/api/orchestration/stacks/test_server_cfn_init.py b/tempest/api/orchestration/stacks/test_server_cfn_init.py
index 7e8bc2d..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:
@@ -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/volume/admin/test_snapshots_actions.py b/tempest/api/volume/admin/test_snapshots_actions.py
index e140ad0..594c703 100644
--- a/tempest/api/volume/admin/test_snapshots_actions.py
+++ b/tempest/api/volume/admin/test_snapshots_actions.py
@@ -22,6 +22,7 @@
     _interface = "json"
 
     @classmethod
+    @test.safe_setup
     def setUpClass(cls):
         super(SnapshotsActionsTest, cls).setUpClass()
         cls.client = cls.snapshots_client
diff --git a/tempest/api/volume/admin/test_volume_quotas.py b/tempest/api/volume/admin/test_volume_quotas.py
index 31f6730..742f7e1 100644
--- a/tempest/api/volume/admin/test_volume_quotas.py
+++ b/tempest/api/volume/admin/test_volume_quotas.py
@@ -23,6 +23,7 @@
 
 class VolumeQuotasAdminTestJSON(base.BaseVolumeV1AdminTest):
     _interface = "json"
+    force_tenant_isolation = True
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py
index 8183999..ee1d09a 100644
--- a/tempest/api/volume/admin/test_volume_types.py
+++ b/tempest/api/volume/admin/test_volume_types.py
@@ -116,3 +116,35 @@
         self.assertEqual(extra_specs, fetched_volume_type['extra_specs'],
                          'The fetched Volume_type is different '
                          'from the created Volume_type')
+
+    @test.attr(type='smoke')
+    def test_volume_type_encryption_create_get(self):
+        # Create/get encryption type.
+        provider = "LuksEncryptor"
+        control_location = "front-end"
+        name = data_utils.rand_name("volume-type-")
+        resp, body = self.client.create_volume_type(name)
+        self.assertEqual(200, resp.status)
+        self.addCleanup(self._delete_volume_type, body['id'])
+        resp, encryption_type = self.client.create_encryption_type(
+            body['id'], provider=provider,
+            control_location=control_location)
+        self.assertEqual(200, resp.status)
+        self.assertIn('volume_type_id', encryption_type)
+        self.assertEqual(provider, encryption_type['provider'],
+                         "The created encryption_type provider is not equal "
+                         "to the requested provider")
+        self.assertEqual(control_location, encryption_type['control_location'],
+                         "The created encryption_type control_location is not "
+                         "equal to the requested control_location")
+        resp, fetched_encryption_type = self.client.get_encryption_type(
+            encryption_type['volume_type_id'])
+        self.assertEqual(200, resp.status)
+        self.assertEqual(provider,
+                         fetched_encryption_type['provider'],
+                         'The fetched encryption_type provider is different '
+                         'from the created encryption_type')
+        self.assertEqual(control_location,
+                         fetched_encryption_type['control_location'],
+                         'The fetched encryption_type control_location is '
+                         'different from the created encryption_type')
diff --git a/tempest/api/volume/admin/test_volumes_actions.py b/tempest/api/volume/admin/test_volumes_actions.py
index aa00700..4496f18 100644
--- a/tempest/api/volume/admin/test_volumes_actions.py
+++ b/tempest/api/volume/admin/test_volumes_actions.py
@@ -22,6 +22,7 @@
     _interface = "json"
 
     @classmethod
+    @test.safe_setup
     def setUpClass(cls):
         super(VolumesActionsTest, cls).setUpClass()
         cls.client = cls.volumes_client
diff --git a/tempest/api/volume/test_snapshot_metadata.py b/tempest/api/volume/test_snapshot_metadata.py
index 1493b37..d2c4ab7 100644
--- a/tempest/api/volume/test_snapshot_metadata.py
+++ b/tempest/api/volume/test_snapshot_metadata.py
@@ -21,6 +21,7 @@
     _interface = "json"
 
     @classmethod
+    @test.safe_setup
     def setUpClass(cls):
         super(SnapshotMetadataTest, cls).setUpClass()
         cls.client = cls.snapshots_client
diff --git a/tempest/api/volume/test_volumes_actions.py b/tempest/api/volume/test_volumes_actions.py
index a22ad32..cfab0bd 100644
--- a/tempest/api/volume/test_volumes_actions.py
+++ b/tempest/api/volume/test_volumes_actions.py
@@ -25,6 +25,7 @@
     _interface = "json"
 
     @classmethod
+    @test.safe_setup
     def setUpClass(cls):
         super(VolumesActionsTest, cls).setUpClass()
         cls.client = cls.volumes_client
@@ -44,7 +45,7 @@
     def tearDownClass(cls):
         # Delete the test instance
         cls.servers_client.delete_server(cls.server['id'])
-        cls.client.wait_for_resource_deletion(cls.server['id'])
+        cls.servers_client.wait_for_server_termination(cls.server['id'])
 
         super(VolumesActionsTest, cls).tearDownClass()
 
diff --git a/tempest/api/volume/test_volumes_get.py b/tempest/api/volume/test_volumes_get.py
index 175da01..be5d76b 100644
--- a/tempest/api/volume/test_volumes_get.py
+++ b/tempest/api/volume/test_volumes_get.py
@@ -124,8 +124,8 @@
         resp, new_volume = \
             self.client.create_volume(size=1,
                                       display_description=new_v_desc,
-                                      availability_zone=volume[
-                                      'availability_zone'])
+                                      availability_zone=
+                                      volume['availability_zone'])
         self.assertEqual(200, resp.status)
         self.assertIn('id', new_volume)
         self.addCleanup(self._delete_volume, new_volume['id'])
@@ -133,8 +133,8 @@
         resp, update_volume = \
             self.client.update_volume(new_volume['id'],
                                       display_name=volume['display_name'],
-                                      display_description=volume[
-                                      'display_description'])
+                                      display_description=
+                                      volume['display_description'])
         self.assertEqual(200, resp.status)
 
         # NOTE(jdg): Revert back to strict true/false checking
diff --git a/tempest/api/volume/v2/test_volumes_list.py b/tempest/api/volume/v2/test_volumes_list.py
index 0e91371..fff40ed 100644
--- a/tempest/api/volume/v2/test_volumes_list.py
+++ b/tempest/api/volume/v2/test_volumes_list.py
@@ -116,8 +116,8 @@
                           ('details' if with_detail else '', key)
                     if key == 'metadata':
                         self.assertThat(volume[key].items(),
-                                        matchers.ContainsAll(params[key]
-                                        .items()), msg)
+                                        matchers.ContainsAll(
+                                            params[key].items()), msg)
                     else:
                         self.assertEqual(params[key], volume[key], msg)
 
diff --git a/tempest/api/compute/api_schema/__init__.py b/tempest/api_schema/__init__.py
similarity index 100%
rename from tempest/api/compute/api_schema/__init__.py
rename to tempest/api_schema/__init__.py
diff --git a/tempest/api/compute/api_schema/__init__.py b/tempest/api_schema/compute/__init__.py
similarity index 100%
copy from tempest/api/compute/api_schema/__init__.py
copy to tempest/api_schema/compute/__init__.py
diff --git a/tempest/api_schema/compute/services.py b/tempest/api_schema/compute/services.py
new file mode 100644
index 0000000..4793f5a
--- /dev/null
+++ b/tempest/api_schema/compute/services.py
@@ -0,0 +1,44 @@
+# 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': 'object',
+        'properties': {
+            'services': {
+                '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']
+                }
+            }
+        },
+        'required': ['services']
+    }
+}
diff --git a/tempest/api/compute/api_schema/__init__.py b/tempest/api_schema/compute/v2/__init__.py
similarity index 100%
copy from tempest/api/compute/api_schema/__init__.py
copy to tempest/api_schema/compute/v2/__init__.py
diff --git a/tempest/api_schema/compute/v2/volumes.py b/tempest/api_schema/compute/v2/volumes.py
new file mode 100644
index 0000000..16ed7c2
--- /dev/null
+++ b/tempest/api_schema/compute/v2/volumes.py
@@ -0,0 +1,56 @@
+# 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.
+
+get_volume = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'volume': {
+                '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']},
+                    'status': {'type': 'string'},
+                    'displayName': {'type': ['string', 'null']},
+                    'availabilityZone': {'type': 'string'},
+                    'createdAt': {'type': 'string'},
+                    'displayDescription': {'type': ['string', 'null']},
+                    'volumeType': {'type': 'string'},
+                    'snapshotId': {'type': ['string', 'null']},
+                    'metadata': {'type': 'object'},
+                    'size': {'type': 'integer'},
+                    'attachments': {
+                        'type': 'array',
+                        'items': {
+                            'type': 'object',
+                            'properties': {
+                                'id': {'type': ['integer', 'string']},
+                                'device': {'type': 'string'},
+                                'volumeId': {'type': ['integer', 'string']},
+                                'serverId': {'type': ['integer', 'string']}
+                            }
+                        }
+                    }
+                },
+                'required': ['id', 'status', 'displayName', 'availabilityZone',
+                             'createdAt', 'displayDescription', 'volumeType',
+                             'snapshotId', 'metadata', 'size', 'attachments']
+            }
+        },
+        'required': ['volume']
+    }
+}
diff --git a/tempest/cli/__init__.py b/tempest/cli/__init__.py
index 8c4ec45..932b151 100644
--- a/tempest/cli/__init__.py
+++ b/tempest/cli/__init__.py
@@ -42,6 +42,7 @@
 
     def nova(self, action, flags='', params='', admin=True, fail_ok=False):
         """Executes nova command for the given action."""
+        flags += ' --endpoint-type %s' % CONF.compute.endpoint_type
         return self.cmd_with_auth(
             'nova', action, flags, params, admin, fail_ok)
 
@@ -58,34 +59,41 @@
 
     def glance(self, action, flags='', params='', admin=True, fail_ok=False):
         """Executes glance command for the given action."""
+        flags += ' --os-endpoint-type %s' % CONF.image.endpoint_type
         return self.cmd_with_auth(
             'glance', action, flags, params, admin, fail_ok)
 
     def ceilometer(self, action, flags='', params='', admin=True,
                    fail_ok=False):
         """Executes ceilometer command for the given action."""
+        flags += ' --os-endpoint-type %s' % CONF.telemetry.endpoint_type
         return self.cmd_with_auth(
             'ceilometer', action, flags, params, admin, fail_ok)
 
     def heat(self, action, flags='', params='', admin=True,
              fail_ok=False):
         """Executes heat command for the given action."""
+        flags += ' --os-endpoint-type %s' % CONF.orchestration.endpoint_type
         return self.cmd_with_auth(
             'heat', action, flags, params, admin, fail_ok)
 
     def cinder(self, action, flags='', params='', admin=True, fail_ok=False):
         """Executes cinder command for the given action."""
+        flags += ' --endpoint-type %s' % CONF.volume.endpoint_type
         return self.cmd_with_auth(
             'cinder', action, flags, params, admin, fail_ok)
 
     def neutron(self, action, flags='', params='', admin=True, fail_ok=False):
         """Executes neutron command for the given action."""
+        flags += ' --endpoint-type %s' % CONF.network.endpoint_type
         return self.cmd_with_auth(
             'neutron', action, flags, params, admin, fail_ok)
 
-    def savanna(self, action, flags='', params='', admin=True, fail_ok=False):
-        """Executes savanna command for the given action."""
+    def sahara(self, action, flags='', params='', admin=True, fail_ok=False):
+        """Executes sahara command for the given action."""
+        flags += ' --endpoint-type %s' % CONF.data_processing.endpoint_type
         return self.cmd_with_auth(
+            # TODO (slukjanov): replace with sahara when new client released
             'savanna', action, flags, params, admin, fail_ok)
 
     def cmd_with_auth(self, cmd, action, flags='', params='',
@@ -93,7 +101,7 @@
         """Executes given command with auth attributes appended."""
         # TODO(jogo) make admin=False work
         creds = ('--os-username %s --os-tenant-name %s --os-password %s '
-                 '--os-auth-url %s ' %
+                 '--os-auth-url %s' %
                  (CONF.identity.admin_username,
                   CONF.identity.admin_tenant_name,
                   CONF.identity.admin_password,
diff --git a/tempest/cli/simple_read_only/test_ceilometer.py b/tempest/cli/simple_read_only/test_ceilometer.py
index 0b6ae22..1d2822d 100644
--- a/tempest/cli/simple_read_only/test_ceilometer.py
+++ b/tempest/cli/simple_read_only/test_ceilometer.py
@@ -16,6 +16,7 @@
 from tempest import cli
 from tempest import config
 from tempest.openstack.common import log as logging
+from tempest import test
 
 CONF = config.CONF
 
@@ -41,6 +42,7 @@
     def test_ceilometer_meter_list(self):
         self.ceilometer('meter-list')
 
+    @test.attr(type='slow')
     def test_ceilometer_resource_list(self):
         self.ceilometer('resource-list')
 
diff --git a/tempest/cli/simple_read_only/test_savanna.py b/tempest/cli/simple_read_only/test_sahara.py
similarity index 61%
rename from tempest/cli/simple_read_only/test_savanna.py
rename to tempest/cli/simple_read_only/test_sahara.py
index 1e30978..cd819a4 100644
--- a/tempest/cli/simple_read_only/test_savanna.py
+++ b/tempest/cli/simple_read_only/test_sahara.py
@@ -25,8 +25,8 @@
 LOG = logging.getLogger(__name__)
 
 
-class SimpleReadOnlySavannaClientTest(cli.ClientTestBase):
-    """Basic, read-only tests for Savanna CLI client.
+class SimpleReadOnlySaharaClientTest(cli.ClientTestBase):
+    """Basic, read-only tests for Sahara CLI client.
 
     Checks return values and output of read-only commands.
     These tests do not presume any content, nor do they create
@@ -35,36 +35,36 @@
 
     @classmethod
     def setUpClass(cls):
-        if not CONF.service_available.savanna:
-            msg = "Skipping all Savanna cli tests because it is not available"
+        if not CONF.service_available.sahara:
+            msg = "Skipping all Sahara cli tests because it is not available"
             raise cls.skipException(msg)
-        super(SimpleReadOnlySavannaClientTest, cls).setUpClass()
+        super(SimpleReadOnlySaharaClientTest, cls).setUpClass()
 
     @test.attr(type='negative')
-    def test_savanna_fake_action(self):
+    def test_sahara_fake_action(self):
         self.assertRaises(subprocess.CalledProcessError,
-                          self.savanna,
+                          self.sahara,
                           'this-does-not-exist')
 
-    def test_savanna_plugins_list(self):
-        plugins = self.parser.listing(self.savanna('plugin-list'))
+    def test_sahara_plugins_list(self):
+        plugins = self.parser.listing(self.sahara('plugin-list'))
         self.assertTableStruct(plugins, ['name', 'versions', 'title'])
 
-    def test_savanna_plugins_show(self):
-        plugin = self.parser.listing(self.savanna('plugin-show',
-                                                  params='--name vanilla'))
+    def test_sahara_plugins_show(self):
+        plugin = self.parser.listing(self.sahara('plugin-show',
+                                                 params='--name vanilla'))
         self.assertTableStruct(plugin, ['Property', 'Value'])
 
-    def test_savanna_node_group_template_list(self):
-        plugins = self.parser.listing(self.savanna('node-group-template-list'))
+    def test_sahara_node_group_template_list(self):
+        plugins = self.parser.listing(self.sahara('node-group-template-list'))
         self.assertTableStruct(plugins, ['name', 'id', 'plugin_name',
                                          'node_processes', 'description'])
 
-    def test_savanna_cluster_template_list(self):
-        plugins = self.parser.listing(self.savanna('cluster-template-list'))
+    def test_sahara_cluster_template_list(self):
+        plugins = self.parser.listing(self.sahara('cluster-template-list'))
         self.assertTableStruct(plugins, ['name', 'id', 'plugin_name',
                                          'node_groups', 'description'])
 
-    def test_savanna_cluster_list(self):
-        plugins = self.parser.listing(self.savanna('cluster-list'))
+    def test_sahara_cluster_list(self):
+        plugins = self.parser.listing(self.sahara('cluster-list'))
         self.assertTableStruct(plugins, ['name', 'id', 'status', 'node_count'])
diff --git a/tempest/clients.py b/tempest/clients.py
index ab7deb0..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 \
@@ -315,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(
diff --git a/tempest/common/commands.py b/tempest/common/commands.py
index 6405eaa..c31a038 100644
--- a/tempest/common/commands.py
+++ b/tempest/common/commands.py
@@ -73,3 +73,7 @@
 
 def iptables_ns(ns, table):
     return ip_ns_exec(ns, "iptables -v -S -t " + table)
+
+
+def ovs_db_dump():
+    return sudo_cmd_call("ovsdb-client dump")
diff --git a/tempest/common/debug.py b/tempest/common/debug.py
index 8325d4d..6a496c2 100644
--- a/tempest/common/debug.py
+++ b/tempest/common/debug.py
@@ -38,3 +38,15 @@
         for table in ['filter', 'nat', 'mangle']:
             LOG.info('ns(%s) table(%s):\n%s', ns, table,
                      commands.iptables_ns(ns, table))
+
+
+def log_ovs_db():
+    if not CONF.debug.enable or not CONF.service_available.neutron:
+        return
+    db_dump = commands.ovs_db_dump()
+    LOG.info("OVS DB:\n" + db_dump)
+
+
+def log_net_debug():
+    log_ip_ns()
+    log_ovs_db()
diff --git a/tempest/common/generator/base_generator.py b/tempest/common/generator/base_generator.py
index 35f8158..7e7a2d6 100644
--- a/tempest/common/generator/base_generator.py
+++ b/tempest/common/generator/base_generator.py
@@ -59,7 +59,9 @@
                 "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",
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 36ddb40..88dbe58 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -21,6 +21,8 @@
 import re
 import time
 
+import jsonschema
+
 from tempest.common import http
 from tempest import config
 from tempest import exceptions
@@ -502,6 +504,31 @@
                    % self.__class__.__name__)
         raise NotImplementedError(message)
 
+    @classmethod
+    def validate_response(cls, schema, resp, body):
+        # Only check the response if the status code is a success code
+        # TODO(cyeoh): Eventually we should be able to verify that a failure
+        # code if it exists is something that we expect. This is explicitly
+        # declared in the V3 API and so we should be able to export this in
+        # the response schema. For now we'll ignore it.
+        if str(resp.status).startswith('2'):
+            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:
+                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)
+
 
 class NegativeRestClient(RestClient):
     """
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index 8420ad0..00e5e0d 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -43,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.
@@ -51,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)
 
@@ -85,27 +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.ssh_client.exec_command(cmd)
+        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.ssh_client.exec_command(cmd)
+        return self.exec_command(cmd)
 
     def turn_nic_on(self, nic):
         cmd = "sudo /bin/ip link set {nic} up".format(nic=nic)
-        return self.ssh_client.exec_command(cmd)
+        return self.exec_command(cmd)
diff --git a/tempest/config.py b/tempest/config.py
index 46dcbcc..471a0de 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -60,16 +60,16 @@
                         'publicURL', 'adminURL', 'internalURL'],
                help="The endpoint type to use for the identity service."),
     cfg.StrOpt('username',
-               default='demo',
+               default=None,
                help="Username to use for Nova API requests."),
     cfg.StrOpt('tenant_name',
-               default='demo',
+               default=None,
                help="Tenant name to use for Nova API requests."),
     cfg.StrOpt('admin_role',
                default='admin',
                help="Role required to administrate keystone."),
     cfg.StrOpt('password',
-               default='pass',
+               default=None,
                help="API key to use when authenticating.",
                secret=True),
     cfg.StrOpt('alt_username',
@@ -85,15 +85,15 @@
                help="API key to use when authenticating as alternate user.",
                secret=True),
     cfg.StrOpt('admin_username',
-               default='admin',
+               default=None,
                help="Administrative Username to use for "
                     "Keystone API requests."),
     cfg.StrOpt('admin_tenant_name',
-               default='admin',
+               default=None,
                help="Administrative Tenant name to use for Keystone API "
                     "requests."),
     cfg.StrOpt('admin_password',
-               default='pass',
+               default=None,
                help="API key to use when authenticating as admin.",
                secret=True),
 ]
@@ -246,9 +246,6 @@
                 default=False,
                 help="Does the test environment support changing the admin "
                      "password?"),
-    cfg.BoolOpt('create_image',
-                default=False,
-                help="Does the test environment support snapshots?"),
     cfg.BoolOpt('resize',
                 default=False,
                 help="Does the test environment support resizing?"),
@@ -276,14 +273,14 @@
 
 ComputeAdminGroup = [
     cfg.StrOpt('username',
-               default='admin',
+               default=None,
                help="Administrative Username to use for Nova API requests."),
     cfg.StrOpt('tenant_name',
-               default='admin',
+               default=None,
                help="Administrative Tenant name to use for Nova API "
                     "requests."),
     cfg.StrOpt('password',
-               default='pass',
+               default=None,
                help="API key to use when authenticating as admin.",
                secret=True),
 ]
@@ -366,6 +363,14 @@
                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',
@@ -621,6 +626,9 @@
     cfg.StrOpt('aws_access',
                default=None,
                help="AWS Access Key"),
+    cfg.StrOpt('aws_zone',
+               default="nova",
+               help="AWS Zone for EC2 tests"),
     cfg.StrOpt('s3_materials_path',
                default="/opt/stack/devstack/files/images/"
                        "s3-materials/cirros-0.3.0",
@@ -753,9 +761,9 @@
     cfg.BoolOpt('horizon',
                 default=True,
                 help="Whether or not Horizon is expected to be available"),
-    cfg.BoolOpt('savanna',
+    cfg.BoolOpt('sahara',
                 default=False,
-                help="Whether or not Savanna is expected to be available"),
+                help="Whether or not Sahara is expected to be available"),
     cfg.BoolOpt('ironic',
                 default=False,
                 help="Whether or not Ironic is expected to be available"),
diff --git a/tempest/exceptions/__init__.py b/tempest/exceptions/__init__.py
index 06dee71..485f532 100644
--- a/tempest/exceptions/__init__.py
+++ b/tempest/exceptions/__init__.py
@@ -20,6 +20,10 @@
     message = "Invalid Configuration"
 
 
+class InvalidCredentials(base.TempestException):
+    message = "Invalid Credentials"
+
+
 class InvalidHttpSuccessCode(base.RestClientException):
     message = "The success code is different than the expected one"
 
diff --git a/tempest/manager.py b/tempest/manager.py
index 708447e..63235db 100644
--- a/tempest/manager.py
+++ b/tempest/manager.py
@@ -75,13 +75,12 @@
             tenant_name=CONF.identity.tenant_name
         )
 
-    def get_auth_provider(self, credentials=None):
-        auth_params = dict(client_type=getattr(self, 'client_type', None),
-                           interface=getattr(self, 'interface', None))
+    def get_auth_provider(self, credentials):
+        if credentials is None:
+            raise exceptions.InvalidCredentials(
+                'Credentials must be specified')
         auth_provider_class = self.get_auth_provider_class(self.auth_version)
-        # If invalid / incomplete credentials are provided, use default ones
-        if credentials is None or \
-                not auth_provider_class.check_credentials(credentials):
-            credentials = self.credentials
-        auth_params['credentials'] = credentials
-        return auth_provider_class(**auth_params)
+        return auth_provider_class(
+            client_type=getattr(self, 'client_type', None),
+            interface=getattr(self, 'interface', None),
+            credentials=credentials)
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index 39b7760..24d2677 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -97,7 +97,7 @@
         except Exception:
             LOG.exception('ssh to server failed')
             self._log_console_output()
-            debug.log_ip_ns()
+            debug.log_net_debug()
             raise
 
     def check_partitions(self):
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 489b271..d5ab3d3 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -172,7 +172,7 @@
         except Exception:
             LOG.exception('Tenant connectivity check failed')
             self._log_console_output(servers=self.servers.keys())
-            debug.log_ip_ns()
+            debug.log_net_debug()
             raise
 
     def _create_and_associate_floating_ips(self):
@@ -204,7 +204,7 @@
                 ex_msg += ": " + msg
             LOG.exception(ex_msg)
             self._log_console_output(servers=self.servers.keys())
-            debug.log_ip_ns()
+            debug.log_net_debug()
             raise
 
     def _disassociate_floating_ips(self):
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index d404dd1..b9ee040 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -343,7 +343,7 @@
                                                             should_succeed),
                             msg)
         except Exception:
-            debug.log_ip_ns()
+            debug.log_net_debug()
             raise
 
     def _test_in_tenant_block(self, tenant):
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..e89ea70 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -53,7 +53,7 @@
             'block_device_mapping': bd_map,
             'key_name': keypair.name
         }
-        return self.create_server(create_kwargs=create_kwargs)
+        return self.create_server(image='', create_kwargs=create_kwargs)
 
     def _create_snapshot_from_volume(self, vol_id):
         volume_snapshots = self.volume_client.volume_snapshots
@@ -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')
@@ -170,3 +169,15 @@
         # deletion operations to succeed
         self._stop_instances([instance_2nd, instance_from_snapshot])
         self._detach_volumes([volume_origin, volume])
+
+
+class TestVolumeBootPatternV2(TestVolumeBootPattern):
+    def _boot_instance_from_volume(self, vol_id, keypair):
+        bdms = [{'uuid': vol_id, 'source_type': 'volume',
+                 'destination_type': 'volume', 'boot_index': 0,
+                 'delete_on_termination': False}]
+        create_kwargs = {
+            'block_device_mapping_v2': bdms,
+            'key_name': keypair.name
+        }
+        return self.create_server(image='', create_kwargs=create_kwargs)
diff --git a/tempest/services/botoclients.py b/tempest/services/botoclients.py
index b52d48c..7616a99 100644
--- a/tempest/services/botoclients.py
+++ b/tempest/services/botoclients.py
@@ -179,19 +179,6 @@
                            'revoke_security_group',
                            'revoke_security_group_egress'))
 
-    def get_good_zone(self):
-        """
-        :rtype: BaseString
-        :return: Returns with the first available zone name
-        """
-        for zone in self.get_all_zones():
-            # NOTE(afazekas): zone.region_name was None
-            if (zone.state == "available" and
-                zone.region.name == self.connection_data["region"].name):
-                return zone.name
-        else:
-            raise IndexError("Don't have a good zone")
-
 
 class ObjectClientS3(BotoClientBase):
 
diff --git a/tempest/services/compute/json/quotas_client.py b/tempest/services/compute/json/quotas_client.py
index 459ab6d..2fae927 100644
--- a/tempest/services/compute/json/quotas_client.py
+++ b/tempest/services/compute/json/quotas_client.py
@@ -27,10 +27,12 @@
         super(QuotasClientJSON, self).__init__(auth_provider)
         self.service = CONF.compute.catalog_type
 
-    def get_quota_set(self, tenant_id):
+    def get_quota_set(self, tenant_id, user_id=None):
         """List the quota set for a tenant."""
 
         url = 'os-quota-sets/%s' % str(tenant_id)
+        if user_id:
+            url += '?user_id=%s' % str(user_id)
         resp, body = self.get(url)
         body = json.loads(body)
         return resp, body['quota_set']
@@ -100,3 +102,7 @@
 
         body = json.loads(body)
         return resp, body['quota_set']
+
+    def delete_quota_set(self, tenant_id):
+        """Delete the tenant's quota set."""
+        return self.delete('os-quota-sets/%s' % str(tenant_id))
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index 623bf42..ca0f114 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -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)
@@ -436,3 +440,8 @@
     def inject_network_info(self, server_id, **kwargs):
         """Inject the Network Info into server"""
         return self.action(server_id, 'injectNetworkInfo', None, **kwargs)
+
+    def get_vnc_console(self, server_id, console_type):
+        """Get URL of VNC console."""
+        return self.action(server_id, "os-getVNCConsole",
+                           "console", type=console_type)
diff --git a/tempest/services/compute/json/services_client.py b/tempest/services/compute/json/services_client.py
index 1ab25ec..0f7d4cb 100644
--- a/tempest/services/compute/json/services_client.py
+++ b/tempest/services/compute/json/services_client.py
@@ -17,6 +17,7 @@
 import json
 import urllib
 
+from tempest.api_schema.compute import services as schema
 from tempest.common import rest_client
 from tempest import config
 
@@ -36,6 +37,7 @@
 
         resp, body = self.get(url)
         body = json.loads(body)
+        self.validate_response(schema.list_services, resp, body)
         return resp, body['services']
 
     def enable_service(self, host_name, binary):
diff --git a/tempest/services/compute/json/volumes_extensions_client.py b/tempest/services/compute/json/volumes_extensions_client.py
index 5ef11ed..451dbac 100644
--- a/tempest/services/compute/json/volumes_extensions_client.py
+++ b/tempest/services/compute/json/volumes_extensions_client.py
@@ -17,6 +17,7 @@
 import time
 import urllib
 
+from tempest.api_schema.compute.v2 import volumes as schema
 from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
@@ -58,6 +59,7 @@
         url = "os-volumes/%s" % str(volume_id)
         resp, body = self.get(url)
         body = json.loads(body)
+        self.validate_response(schema.get_volume, resp, body)
         return resp, body['volume']
 
     def create_volume(self, size, **kwargs):
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/quotas_client.py b/tempest/services/compute/v3/json/quotas_client.py
index 32e31a3..ed92aae 100644
--- a/tempest/services/compute/v3/json/quotas_client.py
+++ b/tempest/services/compute/v3/json/quotas_client.py
@@ -27,10 +27,12 @@
         super(QuotasV3ClientJSON, self).__init__(auth_provider)
         self.service = CONF.compute.catalog_v3_type
 
-    def get_quota_set(self, tenant_id):
+    def get_quota_set(self, tenant_id, user_id=None):
         """List the quota set for a tenant."""
 
         url = 'os-quota-sets/%s' % str(tenant_id)
+        if user_id:
+            url += '?user_id=%s' % str(user_id)
         resp, body = self.get(url)
         body = json.loads(body)
         return resp, body['quota_set']
@@ -96,3 +98,7 @@
 
         body = json.loads(body)
         return resp, body['quota_set']
+
+    def delete_quota_set(self, tenant_id):
+        """Delete the tenant's quota set."""
+        return self.delete('os-quota-sets/%s' % str(tenant_id))
diff --git a/tempest/services/compute/v3/json/servers_client.py b/tempest/services/compute/v3/json/servers_client.py
index 256a730..92eb09b 100644
--- a/tempest/services/compute/v3/json/servers_client.py
+++ b/tempest/services/compute/v3/json/servers_client.py
@@ -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)
diff --git a/tempest/services/compute/v3/json/services_client.py b/tempest/services/compute/v3/json/services_client.py
index b4e65a0..88c4d16 100644
--- a/tempest/services/compute/v3/json/services_client.py
+++ b/tempest/services/compute/v3/json/services_client.py
@@ -17,6 +17,7 @@
 import json
 import urllib
 
+from tempest.api_schema.compute import services as schema
 from tempest.common import rest_client
 from tempest import config
 
@@ -36,6 +37,7 @@
 
         resp, body = self.get(url)
         body = json.loads(body)
+        self.validate_response(schema.list_services, resp, body)
         return resp, body['services']
 
     def enable_service(self, host_name, binary):
diff --git a/tempest/services/compute/xml/common.py b/tempest/services/compute/xml/common.py
index b29b932..b1bf789 100644
--- a/tempest/services/compute/xml/common.py
+++ b/tempest/services/compute/xml/common.py
@@ -19,6 +19,7 @@
 XMLNS_V3 = "http://docs.openstack.org/compute/api/v1.1"
 
 NEUTRON_NAMESPACES = {
+    'binding': "http://docs.openstack.org/ext/binding/api/v1.0",
     'router': "http://docs.openstack.org/ext/neutron/router/api/v1.0",
     'provider': 'http://docs.openstack.org/ext/provider/api/v1.0',
 }
diff --git a/tempest/services/compute/xml/quotas_client.py b/tempest/services/compute/xml/quotas_client.py
index b8b759f..911c476 100644
--- a/tempest/services/compute/xml/quotas_client.py
+++ b/tempest/services/compute/xml/quotas_client.py
@@ -44,10 +44,12 @@
 
         return quota
 
-    def get_quota_set(self, tenant_id):
+    def get_quota_set(self, tenant_id, user_id=None):
         """List the quota set for a tenant."""
 
         url = 'os-quota-sets/%s' % str(tenant_id)
+        if user_id:
+            url += '?user_id=%s' % str(user_id)
         resp, body = self.get(url)
         body = xml_to_json(etree.fromstring(body))
         body = self._format_quota(body)
@@ -121,3 +123,7 @@
         body = xml_to_json(etree.fromstring(body))
         body = self._format_quota(body)
         return resp, body
+
+    def delete_quota_set(self, tenant_id):
+        """Delete the tenant's quota set."""
+        return self.delete('os-quota-sets/%s' % str(tenant_id))
diff --git a/tempest/services/compute/xml/servers_client.py b/tempest/services/compute/xml/servers_client.py
index cd2cb06..1215b80 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)
@@ -641,3 +645,8 @@
     def inject_network_info(self, server_id, **kwargs):
         """Inject the Network Info into server"""
         return self.action(server_id, 'injectNetworkInfo', None, **kwargs)
+
+    def get_vnc_console(self, server_id, console_type):
+        """Get URL of VNC console."""
+        return self.action(server_id, "os-getVNCConsole",
+                           "console", type=console_type)
diff --git a/tempest/services/database/json/flavors_client.py b/tempest/services/database/json/flavors_client.py
index 1a8a4c1..2ec0405 100644
--- a/tempest/services/database/json/flavors_client.py
+++ b/tempest/services/database/json/flavors_client.py
@@ -13,9 +13,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import urllib
+
 from tempest.common import rest_client
 from tempest import config
-import urllib
 
 CONF = config.CONF
 
diff --git a/tempest/services/identity/json/identity_client.py b/tempest/services/identity/json/identity_client.py
index 349a9e9..99b4036 100644
--- a/tempest/services/identity/json/identity_client.py
+++ b/tempest/services/identity/json/identity_client.py
@@ -134,9 +134,10 @@
         post_body = {
             'name': name,
             'password': password,
-            'tenantId': tenant_id,
             'email': email
         }
+        if tenant_id is not None:
+            post_body['tenantId'] = tenant_id
         if kwargs.get('enabled') is not None:
             post_body['enabled'] = kwargs.get('enabled')
         post_body = json.dumps({'user': post_body})
@@ -172,6 +173,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)
@@ -228,16 +234,36 @@
 
         self.auth_url = auth_url
 
-    def auth(self, user, password, tenant):
+    def auth(self, user, password, tenant=None):
         creds = {
             'auth': {
                 'passwordCredentials': {
                     'username': user,
                     'password': password,
                 },
-                'tenantName': tenant,
             }
         }
+
+        if tenant:
+            creds['auth']['tenantName'] = tenant
+
+        body = json.dumps(creds)
+        resp, body = self.post(self.auth_url, body=body)
+
+        return resp, body['access']
+
+    def auth_token(self, token_id, tenant=None):
+        creds = {
+            'auth': {
+                'token': {
+                    'id': token_id,
+                },
+            }
+        }
+
+        if tenant:
+            creds['auth']['tenantName'] = tenant
+
         body = json.dumps(creds)
         resp, body = self.post(self.auth_url, body=body)
 
diff --git a/tempest/services/identity/v3/json/endpoints_client.py b/tempest/services/identity/v3/json/endpoints_client.py
index c3c1e15..f7a894b 100644
--- a/tempest/services/identity/v3/json/endpoints_client.py
+++ b/tempest/services/identity/v3/json/endpoints_client.py
@@ -36,9 +36,17 @@
         return resp, body['endpoints']
 
     def create_endpoint(self, service_id, interface, url, **kwargs):
-        """Create endpoint."""
+        """Create endpoint.
+
+        Normally this function wouldn't allow setting values that are not
+        allowed for 'enabled'. Use `force_enabled` to set a non-boolean.
+
+        """
         region = kwargs.get('region', None)
-        enabled = kwargs.get('enabled', None)
+        if 'force_enabled' in kwargs:
+            enabled = kwargs.get('force_enabled', None)
+        else:
+            enabled = kwargs.get('enabled', None)
         post_body = {
             'service_id': service_id,
             'interface': interface,
@@ -52,8 +60,13 @@
         return resp, body['endpoint']
 
     def update_endpoint(self, endpoint_id, service_id=None, interface=None,
-                        url=None, region=None, enabled=None):
-        """Updates an endpoint with given parameters."""
+                        url=None, region=None, enabled=None, **kwargs):
+        """Updates an endpoint with given parameters.
+
+        Normally this function wouldn't allow setting values that are not
+        allowed for 'enabled'. Use `force_enabled` to set a non-boolean.
+
+        """
         post_body = {}
         if service_id is not None:
             post_body['service_id'] = service_id
@@ -63,7 +76,9 @@
             post_body['url'] = url
         if region is not None:
             post_body['region'] = region
-        if enabled is not None:
+        if 'force_enabled' in kwargs:
+            post_body['enabled'] = kwargs['force_enabled']
+        elif enabled is not None:
             post_body['enabled'] = enabled
         post_body = json.dumps({'endpoint': post_body})
         resp, body = self.patch('endpoints/%s' % endpoint_id, post_body)
diff --git a/tempest/services/identity/v3/xml/endpoints_client.py b/tempest/services/identity/v3/xml/endpoints_client.py
index cc9aa65..a1f9811 100644
--- a/tempest/services/identity/v3/xml/endpoints_client.py
+++ b/tempest/services/identity/v3/xml/endpoints_client.py
@@ -62,11 +62,19 @@
         return resp, body
 
     def create_endpoint(self, service_id, interface, url, **kwargs):
-        """Create endpoint."""
+        """Create endpoint.
+
+        Normally this function wouldn't allow setting values that are not
+        allowed for 'enabled'. Use `force_enabled` to set a non-boolean.
+
+        """
         region = kwargs.get('region', None)
-        enabled = kwargs.get('enabled', None)
-        if enabled is not None:
-            enabled = str(enabled).lower()
+        if 'force_enabled' in kwargs:
+            enabled = kwargs['force_enabled']
+        else:
+            enabled = kwargs.get('enabled', None)
+            if enabled is not None:
+                enabled = str(enabled).lower()
         create_endpoint = common.Element("endpoint",
                                          xmlns=XMLNS,
                                          service_id=service_id,
@@ -79,8 +87,13 @@
         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."""
+                        url=None, region=None, enabled=None, **kwargs):
+        """Updates an endpoint with given parameters.
+
+        Normally this function wouldn't allow setting values that are not
+        allowed for 'enabled'. Use `force_enabled` to set a non-boolean.
+
+        """
         doc = common.Document()
         endpoint = common.Element("endpoint")
         doc.append(endpoint)
@@ -93,8 +106,12 @@
             endpoint.add_attr("url", url)
         if region:
             endpoint.add_attr("region", region)
-        if enabled is not None:
+
+        if 'force_enabled' in kwargs:
+            endpoint.add_attr("enabled", kwargs['force_enabled'])
+        elif enabled is not None:
             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/xml/identity_client.py b/tempest/services/identity/xml/identity_client.py
index 50403fb..c5bf310 100644
--- a/tempest/services/identity/xml/identity_client.py
+++ b/tempest/services/identity/xml/identity_client.py
@@ -75,8 +75,9 @@
                                   xmlns=XMLNS,
                                   name=name,
                                   password=password,
-                                  tenantId=tenant_id,
                                   email=email)
+        if tenant_id:
+            create_user.add_attr('tenantId', tenant_id)
         if 'enabled' in kwargs:
             create_user.add_attr('enabled', str(kwargs['enabled']).lower())
 
@@ -116,11 +117,24 @@
 class TokenClientXML(identity_client.TokenClientJSON):
     TYPE = "xml"
 
-    def auth(self, user, password, tenant):
-        passwordCreds = xml.Element("passwordCredentials",
+    def auth(self, user, password, tenant=None):
+        passwordCreds = xml.Element('passwordCredentials',
                                     username=user,
                                     password=password)
-        auth = xml.Element("auth", tenantName=tenant)
+        auth_kwargs = {}
+        if tenant:
+            auth_kwargs['tenantName'] = tenant
+        auth = xml.Element('auth', **auth_kwargs)
         auth.append(passwordCreds)
         resp, body = self.post(self.auth_url, body=str(xml.Document(auth)))
         return resp, body['access']
+
+    def auth_token(self, token_id, tenant=None):
+        tokenCreds = xml.Element('token', id=token_id)
+        auth_kwargs = {}
+        if tenant:
+            auth_kwargs['tenantName'] = tenant
+        auth = xml.Element('auth', **auth_kwargs)
+        auth.append(tokenCreds)
+        resp, body = self.post(self.auth_url, body=str(xml.Document(auth)))
+        return resp, body['access']
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index d8c0979..a804e8e 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -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 = {
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 daa60da..2a5083c 100644
--- a/tempest/services/network/xml/network_client.py
+++ b/tempest/services/network/xml/network_client.py
@@ -23,7 +23,8 @@
 
     # 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)
@@ -92,28 +93,6 @@
             root.add_attr('xmlns:%s' % element,
                           common.NEUTRON_NAMESPACES[element])
 
-    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 associate_health_monitor_with_pool(self, health_monitor_id,
                                            pool_id):
         uri = '%s/lb/pools/%s/health_monitors' % (self.uri_prefix,
diff --git a/tempest/services/volume/json/admin/volume_types_client.py b/tempest/services/volume/json/admin/volume_types_client.py
index 5554362..c9c0582 100644
--- a/tempest/services/volume/json/admin/volume_types_client.py
+++ b/tempest/services/volume/json/admin/volume_types_client.py
@@ -122,3 +122,31 @@
         resp, body = self.put(url, put_body)
         body = json.loads(body)
         return resp, body
+
+    def get_encryption_type(self, vol_type_id):
+        """
+        Get the volume encryption type for the specified volume type.
+        vol_type_id: Id of volume_type.
+        """
+        url = "/types/%s/encryption" % str(vol_type_id)
+        resp, body = self.get(url)
+        body = json.loads(body)
+        return resp, body
+
+    def create_encryption_type(self, vol_type_id, **kwargs):
+        """
+        Create a new encryption type for the specified volume type.
+
+        vol_type_id: Id of volume_type.
+        provider: Class providing encryption support.
+        cipher: Encryption algorithm/mode to use.
+        key_size: Size of the encryption key, in bits.
+        control_location: Notional service where encryption is performed.
+        """
+        url = "/types/%s/encryption" % str(vol_type_id)
+        post_body = {}
+        post_body.update(kwargs)
+        post_body = json.dumps({'encryption': post_body})
+        resp, body = self.post(url, post_body)
+        body = json.loads(body)
+        return resp, body['encryption']
diff --git a/tempest/stress/actions/ssh_floating.py b/tempest/stress/actions/ssh_floating.py
index a34a20d..c330165 100644
--- a/tempest/stress/actions/ssh_floating.py
+++ b/tempest/stress/actions/ssh_floating.py
@@ -69,7 +69,7 @@
         servers_client = self.manager.servers_client
         self.logger.info("creating %s" % name)
         vm_args = self.vm_extra_args.copy()
-        vm_args['security_groups'] = [{'name': self.sec_grp}]
+        vm_args['security_groups'] = [self.sec_grp]
         resp, server = servers_client.create_server(name, self.image,
                                                     self.flavor,
                                                     **vm_args)
@@ -90,16 +90,15 @@
         sec_grp_cli = self.manager.security_groups_client
         s_name = data_utils.rand_name('sec_grp-')
         s_description = data_utils.rand_name('desc-')
-        _, _sec_grp = sec_grp_cli.create_security_group(s_name,
-                                                        s_description)
-        self.sec_grp = _sec_grp['id']
+        _, self.sec_grp = sec_grp_cli.create_security_group(s_name,
+                                                            s_description)
         create_rule = sec_grp_cli.create_security_group_rule
-        create_rule(self.sec_grp, 'tcp', 22, 22)
-        create_rule(self.sec_grp, 'icmp', -1, -1)
+        create_rule(self.sec_grp['id'], 'tcp', 22, 22)
+        create_rule(self.sec_grp['id'], 'icmp', -1, -1)
 
     def _destroy_sec_grp(self):
         sec_grp_cli = self.manager.security_groups_client
-        sec_grp_cli.delete_security_group(self.sec_grp)
+        sec_grp_cli.delete_security_group(self.sec_grp['id'])
 
     def _create_floating_ip(self):
         floating_cli = self.manager.floating_ips_client
diff --git a/tempest/stress/cleanup.py b/tempest/stress/cleanup.py
index b46de35..2587331 100644
--- a/tempest/stress/cleanup.py
+++ b/tempest/stress/cleanup.py
@@ -45,6 +45,16 @@
         except Exception:
             pass
 
+    secgrp_client = admin_manager.security_groups_client
+    _, secgrp = secgrp_client.list_security_groups({"all_tenants": True})
+    secgrp_del = [grp for grp in secgrp if grp['name'] != 'default']
+    LOG.info("Cleanup::remove %s Security Group" % len(secgrp_del))
+    for g in secgrp_del:
+        try:
+            secgrp_client.delete_security_group(g['id'])
+        except Exception:
+            pass
+
     _, floating_ips = admin_manager.floating_ips_client.list_floating_ips()
     LOG.info("Cleanup::remove %s floating ips" % len(floating_ips))
     for f in floating_ips:
diff --git a/tempest/test.py b/tempest/test.py
index 2125047..75eb6be 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -26,6 +26,8 @@
 import testresources
 import testtools
 
+from oslo.config import cfg
+
 from tempest import clients
 import tempest.common.generator.valid_generator as valid
 from tempest.common import isolated_creds
@@ -64,6 +66,25 @@
     return decorator
 
 
+def safe_setup(f):
+    """A decorator used to wrap the setUpClass for cleaning up resources
+       when setUpClass failed.
+    """
+
+    def decorator(cls):
+            try:
+                f(cls)
+            except Exception as se:
+                LOG.exception("setUpClass failed: %s" % se)
+                try:
+                    cls.tearDownClass()
+                except Exception as te:
+                    LOG.exception("tearDownClass failed: %s" % te)
+                raise se
+
+    return decorator
+
+
 def services(*args, **kwargs):
     """A decorator used to set an attr for each service used in a test case
 
@@ -199,13 +220,11 @@
 
 def validate_tearDownClass():
     if at_exit_set:
-        raise RuntimeError("tearDownClass does not call the super's "
-                           "tearDownClass in these classes: "
-                           + str(at_exit_set) + "\n"
-                           "If you see the exception, with another "
-                           "exception please do not report this one! "
-                           "If you are changing tempest code, make sure you "
-                           "are calling the super class's tearDownClass!")
+        LOG.error(
+            "tearDownClass does not call the super's "
+            "tearDownClass in these classes: \n"
+            + str(at_exit_set))
+
 
 atexit.register(validate_tearDownClass)
 
@@ -353,6 +372,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):
 
@@ -363,6 +388,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):
@@ -401,7 +429,17 @@
         """
         description = NegativeAutoTest.load_schema(description_file)
         LOG.debug(description)
-        generator = importutils.import_class(CONF.negative.test_generator)()
+
+        # NOTE(mkoderer): since this will be executed on import level the
+        # config doesn't have to be in place (e.g. for the pep8 job).
+        # In this case simply return.
+        try:
+            generator = importutils.import_class(
+                CONF.negative.test_generator)()
+        except cfg.ConfigFilesNotFoundError:
+            LOG.critical(
+                "Tempest config not found. Test scenarios aren't created")
+            return
         generator.validate_schema(description)
         schema = description.get("json-schema", None)
         resources = description.get("resources", [])
@@ -418,10 +456,13 @@
                                              "expected_result": expected_result
                                              }))
         if schema is not None:
-            for invalid in generator.generate(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
 
@@ -470,8 +511,12 @@
         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/api/compute/api_schema/__init__.py b/tempest/tests/common/__init__.py
similarity index 100%
copy from tempest/api/compute/api_schema/__init__.py
copy to tempest/tests/common/__init__.py
diff --git a/tempest/api/compute/api_schema/__init__.py b/tempest/tests/common/utils/__init__.py
similarity index 100%
copy from tempest/api/compute/api_schema/__init__.py
copy to tempest/tests/common/utils/__init__.py
diff --git a/tempest/tests/common/utils/test_data_utils.py b/tempest/tests/common/utils/test_data_utils.py
new file mode 100644
index 0000000..7aafdb2
--- /dev/null
+++ b/tempest/tests/common/utils/test_data_utils.py
@@ -0,0 +1,77 @@
+# 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.common.utils import data_utils
+from tempest.tests import base
+
+
+class TestDataUtils(base.TestCase):
+
+    def test_rand_uuid(self):
+        actual = data_utils.rand_uuid()
+        self.assertIsInstance(actual, str)
+        self.assertRegexpMatches(actual, "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]"
+                                         "{4}-[0-9a-f]{4}-[0-9a-f]{12}$")
+        actual2 = data_utils.rand_uuid()
+        self.assertNotEqual(actual, actual2)
+
+    def test_rand_uuid_hex(self):
+        actual = data_utils.rand_uuid_hex()
+        self.assertIsInstance(actual, str)
+        self.assertRegexpMatches(actual, "^[0-9a-f]{32}$")
+
+        actual2 = data_utils.rand_uuid_hex()
+        self.assertNotEqual(actual, actual2)
+
+    def test_rand_name(self):
+        actual = data_utils.rand_name()
+        self.assertIsInstance(actual, str)
+        actual2 = data_utils.rand_name()
+        self.assertNotEqual(actual, actual2)
+
+        actual = data_utils.rand_name('foo')
+        self.assertTrue(actual.startswith('foo'))
+        actual2 = data_utils.rand_name('foo')
+        self.assertTrue(actual.startswith('foo'))
+        self.assertNotEqual(actual, actual2)
+
+    def test_rand_int(self):
+        actual = data_utils.rand_int_id()
+        self.assertIsInstance(actual, int)
+
+        actual2 = data_utils.rand_int_id()
+        self.assertNotEqual(actual, actual2)
+
+    def test_rand_mac_address(self):
+        actual = data_utils.rand_mac_address()
+        self.assertIsInstance(actual, str)
+        self.assertRegexpMatches(actual, "^([0-9a-f][0-9a-f]:){5}"
+                                         "[0-9a-f][0-9a-f]$")
+
+        actual2 = data_utils.rand_mac_address()
+        self.assertNotEqual(actual, actual2)
+
+    def test_parse_image_id(self):
+        actual = data_utils.parse_image_id("/foo/bar/deadbeaf")
+        self.assertEqual("deadbeaf", actual)
+
+    def test_arbitrary_string(self):
+        actual = data_utils.arbitrary_string()
+        self.assertEqual(actual, "test")
+        actual = data_utils.arbitrary_string(size=30, base_text="abc")
+        self.assertEqual(actual, "abc" * (30 / len("abc")))
+        actual = data_utils.arbitrary_string(size=5, base_text="deadbeaf")
+        self.assertEqual(actual, "deadb")
diff --git a/tempest/tests/common/utils/test_misc.py b/tempest/tests/common/utils/test_misc.py
new file mode 100644
index 0000000..b8c6184
--- /dev/null
+++ b/tempest/tests/common/utils/test_misc.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.
+
+
+from tempest.common.utils import misc
+from tempest.tests import base
+
+
+@misc.singleton
+class TestFoo(object):
+
+    count = 0
+
+    def increment(self):
+        self.count += 1
+        return self.count
+
+
+@misc.singleton
+class TestBar(object):
+
+    count = 0
+
+    def increment(self):
+        self.count += 1
+        return self.count
+
+
+class TestMisc(base.TestCase):
+
+    def test_singleton(self):
+        test = TestFoo()
+        self.assertEqual(0, test.count)
+        self.assertEqual(1, test.increment())
+        test2 = TestFoo()
+        self.assertEqual(1, test.count)
+        self.assertEqual(1, test2.count)
+        self.assertEqual(test, test2)
+        test3 = TestBar()
+        self.assertNotEqual(test, test3)
diff --git a/tempest/tests/fake_config.py b/tempest/tests/fake_config.py
index e941606..8a8ebb0 100644
--- a/tempest/tests/fake_config.py
+++ b/tempest/tests/fake_config.py
@@ -12,49 +12,33 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from oslo.config import cfg
 
-class FakeConfig(object):
+from tempest import config
+from tempest.openstack.common.fixture import config as conf_fixture
 
-    class fake_compute(object):
-        build_interval = 10
-        build_timeout = 10
 
-    class fake_identity(object):
-        disable_ssl_certificate_validation = True
-        catalog_type = 'identity'
-        uri = 'http://fake_uri.com/auth'
-        uri_v3 = 'http://fake_uri_v3.com/auth'
+class ConfigFixture(conf_fixture.Config):
 
-    class fake_default_feature_enabled(object):
-        api_extensions = ['all']
+    def __init__(self):
+        config.register_opts()
+        super(ConfigFixture, self).__init__()
 
-    class fake_compute_feature_enabled(fake_default_feature_enabled):
-        api_v3_extensions = ['all']
+    def setUp(self):
+        super(ConfigFixture, self).setUp()
+        self.conf.set_default('build_interval', 10, group='compute')
+        self.conf.set_default('build_timeout', 10, group='compute')
+        self.conf.set_default('disable_ssl_certificate_validation', True,
+                              group='identity')
+        self.conf.set_default('uri', 'http://fake_uri.com/auth',
+                              group='identity')
+        self.conf.set_default('uri_v3', 'http://fake_uri_v3.com/auth',
+                              group='identity')
+        self.conf.set_default('neutron', True, group='service_available')
+        self.conf.set_default('heat', True, group='service_available')
 
-    class fake_object_storage_discoverable_apis(object):
-        discoverable_apis = ['all']
 
-    class fake_service_available(object):
-        nova = True
-        glance = True
-        cinder = True
-        heat = True
-        neutron = True
-        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()
-    object_storage_feature_enabled = fake_object_storage_discoverable_apis()
-
-    service_available = fake_service_available()
-
-    compute = fake_compute()
-    identity = fake_identity()
-
-    negative = fake_negative()
+class FakePrivate(config.TempestConfigPrivate):
+    def __init__(self):
+        cfg.CONF([], default_config_files=[])
+        self._set_attrs()
diff --git a/tempest/tests/negative/test_negative_auto_test.py b/tempest/tests/negative/test_negative_auto_test.py
index 27ddc95..7a1909a 100644
--- a/tempest/tests/negative/test_negative_auto_test.py
+++ b/tempest/tests/negative/test_negative_auto_test.py
@@ -15,6 +15,7 @@
 
 import mock
 
+from tempest import config
 import tempest.test as test
 from tempest.tests import base
 from tempest.tests import fake_config
@@ -38,7 +39,8 @@
 
     def setUp(self):
         super(TestNegativeAutoTest, self).setUp()
-        self.stubs.Set(test, 'CONF', fake_config.FakeConfig)
+        self.useFixture(fake_config.ConfigFixture())
+        self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
 
     def _check_prop_entries(self, result, entry):
         entries = [a for a in result if entry in a[0]]
diff --git a/tempest/tests/test_auth.py b/tempest/tests/test_auth.py
index df04d65..b6e15bd 100644
--- a/tempest/tests/test_auth.py
+++ b/tempest/tests/test_auth.py
@@ -42,7 +42,8 @@
 
     def setUp(self):
         super(BaseAuthTestsSetUp, self).setUp()
-        self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakeConfig)
+        self.useFixture(fake_config.ConfigFixture())
+        self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
         self.fake_http = fake_http.fake_httplib2(return_type=200)
         self.stubs.Set(http.ClosingHttp, 'request', self.fake_http.request)
         self.auth_provider = self._auth(self.credentials)
diff --git a/tempest/tests/test_decorators.py b/tempest/tests/test_decorators.py
index aa3c8fc..ebf0ca0 100644
--- a/tempest/tests/test_decorators.py
+++ b/tempest/tests/test_decorators.py
@@ -15,6 +15,9 @@
 
 import testtools
 
+from oslo.config import cfg
+
+from tempest import config
 from tempest import exceptions
 from tempest.openstack.common.fixture import mockpatch
 from tempest import test
@@ -25,7 +28,8 @@
 class BaseDecoratorsTest(base.TestCase):
     def setUp(self):
         super(BaseDecoratorsTest, self).setUp()
-        self.stubs.Set(test, 'CONF', fake_config.FakeConfig)
+        self.config_fixture = self.useFixture(fake_config.ConfigFixture())
+        self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
 
 
 class TestAttrDecorator(BaseDecoratorsTest):
@@ -191,10 +195,8 @@
 class TestRequiresExtDecorator(BaseDecoratorsTest):
     def setUp(self):
         super(TestRequiresExtDecorator, self).setUp()
-        self.fixture = self.useFixture(mockpatch.PatchObject(
-                                       test.CONF.compute_feature_enabled,
-                                       'api_extensions',
-                                       new=['enabled_ext', 'another_ext']))
+        cfg.CONF.set_default('api_extensions', ['enabled_ext', 'another_ext'],
+                             'compute-feature-enabled')
 
     def _test_requires_ext_helper(self, expected_to_skip=True,
                                   **decorator_args):
@@ -220,7 +222,7 @@
 
     def test_requires_ext_decorator_with_all_ext_enabled(self):
         # disable fixture so the default (all) is used.
-        self.fixture.cleanUp()
+        self.config_fixture.cleanUp()
         self._test_requires_ext_helper(expected_to_skip=False,
                                        extension='random_ext',
                                        service='compute')
diff --git a/tempest/tests/test_rest_client.py b/tempest/tests/test_rest_client.py
index 827b5c9..4c23fbd 100644
--- a/tempest/tests/test_rest_client.py
+++ b/tempest/tests/test_rest_client.py
@@ -35,7 +35,8 @@
 
     def setUp(self):
         super(BaseRestClientTestClass, self).setUp()
-        self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakeConfig)
+        self.useFixture(fake_config.ConfigFixture())
+        self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
         self.rest_client = rest_client.RestClient(
             fake_auth_provider.FakeAuthProvider())
         self.stubs.Set(httplib2.Http, 'request', self.fake_http.request)
@@ -254,7 +255,8 @@
 
     def setUp(self):
         super(TestRestClientErrorCheckerJSON, self).setUp()
-        self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakeConfig)
+        self.useFixture(fake_config.ConfigFixture())
+        self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
         self.rest_client = rest_client.RestClient(
             fake_auth_provider.FakeAuthProvider())
 
diff --git a/tempest/tests/test_tenant_isolation.py b/tempest/tests/test_tenant_isolation.py
new file mode 100644
index 0000000..2e50cfd
--- /dev/null
+++ b/tempest/tests/test_tenant_isolation.py
@@ -0,0 +1,336 @@
+# Copyright 2014 IBM Corp.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    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 keystoneclient.v2_0.client as keystoneclient
+from mock import patch
+import neutronclient.v2_0.client as neutronclient
+from oslo.config import cfg
+
+from tempest.common import isolated_creds
+from tempest import config
+from tempest.openstack.common.fixture import mockpatch
+from tempest.services.identity.json import identity_client as json_iden_client
+from tempest.services.identity.xml import identity_client as xml_iden_client
+from tempest.services.network.json import network_client as json_network_client
+from tempest.services.network.xml import network_client as xml_network_client
+from tempest.tests import base
+from tempest.tests import fake_config
+
+
+class TestTenantIsolation(base.TestCase):
+
+    def setUp(self):
+        super(TestTenantIsolation, self).setUp()
+        self.useFixture(fake_config.ConfigFixture())
+        self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
+
+    def test_tempest_client(self):
+        iso_creds = isolated_creds.IsolatedCreds('test class')
+        self.assertTrue(isinstance(iso_creds.identity_admin_client,
+                                   json_iden_client.IdentityClientJSON))
+        self.assertTrue(isinstance(iso_creds.network_admin_client,
+                                   json_network_client.NetworkClientJSON))
+
+    def test_official_client(self):
+        self.useFixture(mockpatch.PatchObject(keystoneclient.Client,
+                                              'authenticate'))
+        iso_creds = isolated_creds.IsolatedCreds('test class',
+                                                 tempest_client=False)
+        self.assertTrue(isinstance(iso_creds.identity_admin_client,
+                                   keystoneclient.Client))
+        self.assertTrue(isinstance(iso_creds.network_admin_client,
+                                   neutronclient.Client))
+
+    def test_tempest_client_xml(self):
+        iso_creds = isolated_creds.IsolatedCreds('test class', interface='xml')
+        self.assertEqual(iso_creds.interface, 'xml')
+        self.assertTrue(isinstance(iso_creds.identity_admin_client,
+                                   xml_iden_client.IdentityClientXML))
+        self.assertTrue(isinstance(iso_creds.network_admin_client,
+                                   xml_network_client.NetworkClientXML))
+
+    def _mock_user_create(self, id, name):
+        user_fix = self.useFixture(mockpatch.PatchObject(
+            json_iden_client.IdentityClientJSON,
+            'create_user',
+            return_value=({'status': 200},
+                          {'id': id, 'name': name})))
+        return user_fix
+
+    def _mock_tenant_create(self, id, name):
+        tenant_fix = self.useFixture(mockpatch.PatchObject(
+            json_iden_client.IdentityClientJSON,
+            'create_tenant',
+            return_value=({'status': 200},
+                          {'id': id, 'name': name})))
+        return tenant_fix
+
+    def _mock_network_create(self, iso_creds, id, name):
+        net_fix = self.useFixture(mockpatch.PatchObject(
+            iso_creds.network_admin_client,
+            'create_network',
+            return_value=({'status': 200},
+                          {'network': {'id': id, 'name': name}})))
+        return net_fix
+
+    def _mock_subnet_create(self, iso_creds, id, name):
+        subnet_fix = self.useFixture(mockpatch.PatchObject(
+            iso_creds.network_admin_client,
+            'create_subnet',
+            return_value=({'status': 200},
+                          {'subnet': {'id': id, 'name': name}})))
+        return subnet_fix
+
+    def _mock_router_create(self, id, name):
+        router_fix = self.useFixture(mockpatch.PatchObject(
+            json_network_client.NetworkClientJSON,
+            'create_router',
+            return_value=({'status': 200},
+                          {'router': {'id': id, 'name': name}})))
+        return router_fix
+
+    @patch('tempest.common.rest_client.RestClient')
+    def test_primary_creds(self, MockRestClient):
+        cfg.CONF.set_default('neutron', False, 'service_available')
+        iso_creds = isolated_creds.IsolatedCreds('test class',
+                                                 password='fake_password')
+        self._mock_tenant_create('1234', 'fake_prim_tenant')
+        self._mock_user_create('1234', 'fake_prim_user')
+        username, tenant_name, password = iso_creds.get_primary_creds()
+        self.assertEqual(username, 'fake_prim_user')
+        self.assertEqual(tenant_name, 'fake_prim_tenant')
+        # Verify helper methods
+        tenant = iso_creds.get_primary_tenant()
+        user = iso_creds.get_primary_user()
+        self.assertEqual(tenant['id'], '1234')
+        self.assertEqual(user['id'], '1234')
+
+    @patch('tempest.common.rest_client.RestClient')
+    def test_admin_creds(self, MockRestClient):
+        cfg.CONF.set_default('neutron', False, 'service_available')
+        iso_creds = isolated_creds.IsolatedCreds('test class',
+                                                 password='fake_password')
+        self._mock_user_create('1234', 'fake_admin_user')
+        self._mock_tenant_create('1234', 'fake_admin_tenant')
+        self.useFixture(mockpatch.PatchObject(
+            json_iden_client.IdentityClientJSON,
+            'list_roles',
+            return_value=({'status': 200},
+                          [{'id': '1234', 'name': 'admin'}])))
+
+        user_mock = patch.object(json_iden_client.IdentityClientJSON,
+                                 'assign_user_role')
+        user_mock.start()
+        self.addCleanup(user_mock.stop)
+        with patch.object(json_iden_client.IdentityClientJSON,
+                          'assign_user_role') as user_mock:
+            username, tenant_name, password = iso_creds.get_admin_creds()
+        user_mock.assert_called_once_with('1234', '1234', '1234')
+        self.assertEqual(username, 'fake_admin_user')
+        self.assertEqual(tenant_name, 'fake_admin_tenant')
+        # Verify helper methods
+        tenant = iso_creds.get_admin_tenant()
+        user = iso_creds.get_admin_user()
+        self.assertEqual(tenant['id'], '1234')
+        self.assertEqual(user['id'], '1234')
+
+    @patch('tempest.common.rest_client.RestClient')
+    def test_all_cred_cleanup(self, MockRestClient):
+        cfg.CONF.set_default('neutron', False, 'service_available')
+        iso_creds = isolated_creds.IsolatedCreds('test class',
+                                                 password='fake_password')
+        tenant_fix = self._mock_tenant_create('1234', 'fake_prim_tenant')
+        user_fix = self._mock_user_create('1234', 'fake_prim_user')
+        username, tenant_name, password = iso_creds.get_primary_creds()
+        tenant_fix.cleanUp()
+        user_fix.cleanUp()
+        tenant_fix = self._mock_tenant_create('12345', 'fake_alt_tenant')
+        user_fix = self._mock_user_create('12345', 'fake_alt_user')
+        alt_username, alt_tenant, alt_password = iso_creds.get_alt_creds()
+        tenant_fix.cleanUp()
+        user_fix.cleanUp()
+        tenant_fix = self._mock_tenant_create('123456', 'fake_admin_tenant')
+        user_fix = self._mock_user_create('123456', 'fake_admin_user')
+        self.useFixture(mockpatch.PatchObject(
+            json_iden_client.IdentityClientJSON,
+            'list_roles',
+            return_value=({'status': 200},
+                          [{'id': '123456', 'name': 'admin'}])))
+        with patch.object(json_iden_client.IdentityClientJSON,
+                          'assign_user_role'):
+            admin_username, admin_tenant, admin_pass = \
+                iso_creds.get_admin_creds()
+        user_mock = self.patch(
+            'tempest.services.identity.json.identity_client.'
+            'IdentityClientJSON.delete_user')
+        tenant_mock = self.patch(
+            'tempest.services.identity.json.identity_client.'
+            'IdentityClientJSON.delete_tenant')
+        iso_creds.clear_isolated_creds()
+        # Verify user delete calls
+        calls = user_mock.mock_calls
+        self.assertEqual(len(calls), 3)
+        args = map(lambda x: x[1][0], calls)
+        self.assertIn('1234', args)
+        self.assertIn('12345', args)
+        self.assertIn('123456', args)
+        # Verify tenant delete calls
+        calls = tenant_mock.mock_calls
+        self.assertEqual(len(calls), 3)
+        args = map(lambda x: x[1][0], calls)
+        self.assertIn('1234', args)
+        self.assertIn('12345', args)
+        self.assertIn('123456', args)
+
+    @patch('tempest.common.rest_client.RestClient')
+    def test_alt_creds(self, MockRestClient):
+        cfg.CONF.set_default('neutron', False, 'service_available')
+        iso_creds = isolated_creds.IsolatedCreds('test class',
+                                                 password='fake_password')
+        self._mock_user_create('1234', 'fake_alt_user')
+        self._mock_tenant_create('1234', 'fake_alt_tenant')
+        username, tenant_name, password = iso_creds.get_alt_creds()
+        self.assertEqual(username, 'fake_alt_user')
+        self.assertEqual(tenant_name, 'fake_alt_tenant')
+        # Verify helper methods
+        tenant = iso_creds.get_alt_tenant()
+        user = iso_creds.get_alt_user()
+        self.assertEqual(tenant['id'], '1234')
+        self.assertEqual(user['id'], '1234')
+
+    @patch('tempest.common.rest_client.RestClient')
+    def test_network_creation(self, MockRestClient):
+        iso_creds = isolated_creds.IsolatedCreds('test class',
+                                                 password='fake_password')
+        self._mock_user_create('1234', 'fake_prim_user')
+        self._mock_tenant_create('1234', 'fake_prim_tenant')
+        self._mock_network_create(iso_creds, '1234', 'fake_net')
+        self._mock_subnet_create(iso_creds, '1234', 'fake_subnet')
+        self._mock_router_create('1234', 'fake_router')
+        router_interface_mock = self.patch(
+            'tempest.services.network.json.network_client.NetworkClientJSON.'
+            'add_router_interface_with_subnet_id')
+        username, tenant_name, password = iso_creds.get_primary_creds()
+        router_interface_mock.called_once_with('1234', '1234')
+        network = iso_creds.get_primary_network()
+        subnet = iso_creds.get_primary_subnet()
+        router = iso_creds.get_primary_router()
+        self.assertEqual(network['id'], '1234')
+        self.assertEqual(network['name'], 'fake_net')
+        self.assertEqual(subnet['id'], '1234')
+        self.assertEqual(subnet['name'], 'fake_subnet')
+        self.assertEqual(router['id'], '1234')
+        self.assertEqual(router['name'], 'fake_router')
+
+    @patch('tempest.common.rest_client.RestClient')
+    def test_network_cleanup(self, MockRestClient):
+        iso_creds = isolated_creds.IsolatedCreds('test class',
+                                                 password='fake_password')
+        # Create primary tenant and network
+        user_fix = self._mock_user_create('1234', 'fake_prim_user')
+        tenant_fix = self._mock_tenant_create('1234', 'fake_prim_tenant')
+        net_fix = self._mock_network_create(iso_creds, '1234', 'fake_net')
+        subnet_fix = self._mock_subnet_create(iso_creds, '1234', 'fake_subnet')
+        router_fix = self._mock_router_create('1234', 'fake_router')
+        router_interface_mock = self.patch(
+            'tempest.services.network.json.network_client.NetworkClientJSON.'
+            'add_router_interface_with_subnet_id')
+        username, tenant_name, password = iso_creds.get_primary_creds()
+        router_interface_mock.called_once_with('1234', '1234')
+        router_interface_mock.reset_mock()
+        tenant_fix.cleanUp()
+        user_fix.cleanUp()
+        net_fix.cleanUp()
+        subnet_fix.cleanUp()
+        router_fix.cleanUp()
+        # Create alternate tenant and network
+        user_fix = self._mock_user_create('12345', 'fake_alt_user')
+        tenant_fix = self._mock_tenant_create('12345', 'fake_alt_tenant')
+        net_fix = self._mock_network_create(iso_creds, '12345', 'fake_alt_net')
+        subnet_fix = self._mock_subnet_create(iso_creds, '12345',
+                                              'fake_alt_subnet')
+        router_fix = self._mock_router_create('12345', 'fake_alt_router')
+        alt_username, alt_tenant_name, password = iso_creds.get_alt_creds()
+        router_interface_mock.called_once_with('12345', '12345')
+        router_interface_mock.reset_mock()
+        tenant_fix.cleanUp()
+        user_fix.cleanUp()
+        net_fix.cleanUp()
+        subnet_fix.cleanUp()
+        router_fix.cleanUp()
+        # Create admin tenant and networks
+        user_fix = self._mock_user_create('123456', 'fake_admin_user')
+        tenant_fix = self._mock_tenant_create('123456', 'fake_admin_tenant')
+        net_fix = self._mock_network_create(iso_creds, '123456',
+                                            'fake_admin_net')
+        subnet_fix = self._mock_subnet_create(iso_creds, '123456',
+                                              'fake_admin_subnet')
+        router_fix = self._mock_router_create('123456', 'fake_admin_router')
+        self.useFixture(mockpatch.PatchObject(
+            json_iden_client.IdentityClientJSON,
+            'list_roles',
+            return_value=({'status': 200},
+                          [{'id': '123456', 'name': 'admin'}])))
+        with patch.object(json_iden_client.IdentityClientJSON,
+                          'assign_user_role'):
+            admin_user, admin_tenant, password = iso_creds.get_admin_creds()
+        self.patch('tempest.services.identity.json.identity_client.'
+                   'IdentityClientJSON.delete_user')
+        self.patch('tempest.services.identity.json.identity_client.'
+                   'IdentityClientJSON.delete_tenant')
+        net = patch.object(iso_creds.network_admin_client,
+                           'delete_network')
+        net_mock = net.start()
+        subnet = patch.object(iso_creds.network_admin_client,
+                              'delete_subnet')
+        subnet_mock = subnet.start()
+        router = patch.object(iso_creds.network_admin_client,
+                              'delete_router')
+        router_mock = router.start()
+        remove_router_interface_mock = self.patch(
+            'tempest.services.network.json.network_client.NetworkClientJSON.'
+            'remove_router_interface_with_subnet_id')
+        port_list_mock = patch.object(iso_creds.network_admin_client,
+                                      'list_ports', return_value=(
+                                      {'status': 200}, {'ports': []}))
+        port_list_mock.start()
+        iso_creds.clear_isolated_creds()
+        # Verify remove router interface calls
+        calls = remove_router_interface_mock.mock_calls
+        self.assertEqual(len(calls), 3)
+        args = map(lambda x: x[1], calls)
+        self.assertIn(('1234', '1234'), args)
+        self.assertIn(('12345', '12345'), args)
+        self.assertIn(('123456', '123456'), args)
+        # Verify network delete calls
+        calls = net_mock.mock_calls
+        self.assertEqual(len(calls), 3)
+        args = map(lambda x: x[1][0], calls)
+        self.assertIn('1234', args)
+        self.assertIn('12345', args)
+        self.assertIn('123456', args)
+        # Verify subnet delete calls
+        calls = subnet_mock.mock_calls
+        self.assertEqual(len(calls), 3)
+        args = map(lambda x: x[1][0], calls)
+        self.assertIn('1234', args)
+        self.assertIn('12345', args)
+        self.assertIn('123456', args)
+        # Verify router delete calls
+        calls = router_mock.mock_calls
+        self.assertEqual(len(calls), 3)
+        args = map(lambda x: x[1][0], calls)
+        self.assertIn('1234', args)
+        self.assertIn('12345', args)
+        self.assertIn('123456', args)
diff --git a/tempest/tests/test_waiters.py b/tempest/tests/test_waiters.py
new file mode 100644
index 0000000..1f9825e
--- /dev/null
+++ b/tempest/tests/test_waiters.py
@@ -0,0 +1,49 @@
+# Copyright 2014 IBM Corp.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    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 time
+
+import mock
+
+from tempest.common import waiters
+from tempest import exceptions
+from tempest.tests import base
+
+
+class TestImageWaiters(base.TestCase):
+    def setUp(self):
+        super(TestImageWaiters, self).setUp()
+        self.client = mock.MagicMock()
+        self.client.build_timeout = 1
+        self.client.build_interval = 1
+
+    def test_wait_for_image_status(self):
+        self.client.get_image.return_value = (None, {'status': 'active'})
+        start_time = int(time.time())
+        waiters.wait_for_image_status(self.client, 'fake_image_id', 'active')
+        end_time = int(time.time())
+        # Ensure waiter returns before build_timeout
+        self.assertTrue((end_time - start_time) < 10)
+
+    def test_wait_for_image_status_timeout(self):
+        self.client.get_image.return_value = (None, {'status': 'saving'})
+        self.assertRaises(exceptions.TimeoutException,
+                          waiters.wait_for_image_status,
+                          self.client, 'fake_image_id', 'active')
+
+    def test_wait_for_image_status_error_on_image_create(self):
+        self.client.get_image.return_value = (None, {'status': 'ERROR'})
+        self.assertRaises(exceptions.AddImageException,
+                          waiters.wait_for_image_status,
+                          self.client, 'fake_image_id', 'active')
diff --git a/tempest/thirdparty/boto/test.py b/tempest/thirdparty/boto/test.py
index 10d421e..4c39f78 100644
--- a/tempest/thirdparty/boto/test.py
+++ b/tempest/thirdparty/boto/test.py
@@ -108,6 +108,9 @@
     CODE_RE = '.*'  # regexp makes sense in group match
 
     def match(self, exc):
+        """:returns: Retruns with an error string if not matches,
+               returns with None when matches.
+        """
         if not isinstance(exc, exception.BotoServerError):
             return "%r not an BotoServerError instance" % exc
         LOG.info("Status: %s , error_code: %s", exc.status, exc.error_code)
@@ -119,6 +122,7 @@
             return ("Error code (%s) does not match" +
                     "the expected re pattern \"%s\"") %\
                    (exc.error_code, self.CODE_RE)
+        return None
 
 
 class ClientError(BotoExceptionMatcher):
@@ -313,7 +317,7 @@
             except ValueError:
                 return "_GONE"
             except exception.EC2ResponseError as exc:
-                if colusure_matcher.match(exc):
+                if colusure_matcher.match(exc) is None:
                     return "_GONE"
                 else:
                     raise
@@ -449,7 +453,7 @@
                 return "_GONE"
             except exception.EC2ResponseError as exc:
                 if cls.ec2_error_code.\
-                        client.InvalidInstanceID.NotFound.match(exc):
+                        client.InvalidInstanceID.NotFound.match(exc) is None:
                     return "_GONE"
                 # NOTE(afazekas): incorrect code,
                 # but the resource must be destoreyd
diff --git a/tempest/thirdparty/boto/test_ec2_instance_run.py b/tempest/thirdparty/boto/test_ec2_instance_run.py
index bbfbb79..e6a1638 100644
--- a/tempest/thirdparty/boto/test_ec2_instance_run.py
+++ b/tempest/thirdparty/boto/test_ec2_instance_run.py
@@ -40,7 +40,7 @@
                                     ": requires ami/aki/ari manifest")))
         cls.s3_client = cls.os.s3_client
         cls.ec2_client = cls.os.ec2api_client
-        cls.zone = cls.ec2_client.get_good_zone()
+        cls.zone = CONF.boto.aws_zone
         cls.materials_path = CONF.boto.s3_materials_path
         ami_manifest = CONF.boto.ami_manifest
         aki_manifest = CONF.boto.aki_manifest
diff --git a/tempest/thirdparty/boto/test_ec2_volumes.py b/tempest/thirdparty/boto/test_ec2_volumes.py
index 6a771e5..12dea18 100644
--- a/tempest/thirdparty/boto/test_ec2_volumes.py
+++ b/tempest/thirdparty/boto/test_ec2_volumes.py
@@ -38,7 +38,7 @@
             raise cls.skipException(skip_msg)
 
         cls.client = cls.os.ec2api_client
-        cls.zone = cls.client.get_good_zone()
+        cls.zone = CONF.boto.aws_zone
 
     @test.attr(type='smoke')
     def test_create_get_delete(self):