Merge "Forbid admin_password None in rescue Nova API"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 7c604be..bb9a68e 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -427,7 +427,7 @@
 # (string value)
 #alt_password=<None>
 
-# Administrative Username to use forKeystone API requests.
+# Administrative Username to use for Keystone API requests.
 # (string value)
 #admin_username=admin
 
@@ -439,6 +439,17 @@
 #admin_password=pass
 
 
+[identity-feature-enabled]
+
+#
+# Options defined in tempest.config
+#
+
+# Does the identity service have delegation and impersonation
+# enabled (boolean value)
+#trust=true
+
+
 [image]
 
 #
diff --git a/etc/whitelist.yaml b/etc/whitelist.yaml
index a8c5276..1c12b6c 100644
--- a/etc/whitelist.yaml
+++ b/etc/whitelist.yaml
@@ -39,6 +39,8 @@
       message: "Instance failed network setup after 1 attempt"
     - module: "nova.compute.manager"
       message: "Periodic sync_power_state task had an error"
+    - module: "nova.virt.driver"
+      message: "Info cache for instance .* could not be found"
 
 g-api:
     - module: "glance.store.sheepdog"
@@ -73,6 +75,10 @@
     - module: "ceilometer.compute.pollsters.disk"
       message: ".*"
 
+ceilometer-acentral:
+    - module: "ceilometer.central.manager"
+      message: "403 Forbidden"
+
 ceilometer-alarm-evaluator:
     - module: "ceilometer.alarm.service"
       message: "alarm evaluation cycle failed"
diff --git a/run_tests.sh b/run_tests.sh
index 285b372..3f00453 100755
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -126,7 +126,7 @@
     exit
 fi
 
-if [$coverage -eq 1] ; then
+if [ $coverage -eq 1 ]; then
     $testrargs = "--coverage $testrargs"
 fi
 
diff --git a/tempest/api/compute/admin/test_hosts_negative.py b/tempest/api/compute/admin/test_hosts_negative.py
index dbf7967..a1afe0e 100644
--- a/tempest/api/compute/admin/test_hosts_negative.py
+++ b/tempest/api/compute/admin/test_hosts_negative.py
@@ -66,7 +66,9 @@
 
         self.assertRaises(exceptions.Unauthorized,
                           self.non_admin_client.update_host,
-                          hostname)
+                          hostname,
+                          status='enable',
+                          maintenance_mode='enable')
 
     @test.skip_because(bug="1261964", interface="xml")
     @test.attr(type=['negative', 'gate'])
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 311e158..5f13c09 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -169,6 +169,8 @@
 
     @classmethod
     def setUpClass(cls):
+        # By default compute tests do not create network resources
+        cls.set_network_resources()
         super(BaseV2ComputeTest, cls).setUpClass()
         cls.servers_client = cls.os.servers_client
         cls.flavors_client = cls.os.flavors_client
@@ -274,6 +276,8 @@
         cls.extensions_client = cls.os.extensions_v3_client
         cls.availability_zone_client = cls.os.availability_zone_v3_client
         cls.interfaces_client = cls.os.interfaces_v3_client
+        cls.instance_usages_audit_log_client = \
+            cls.os.instance_usages_audit_log_v3_client
         cls.hypervisor_client = cls.os.hypervisor_v3_client
         cls.keypairs_client = cls.os.keypairs_v3_client
         cls.tenant_usages_client = cls.os.tenant_usages_v3_client
@@ -342,6 +346,8 @@
 
         cls.os_adm = os_adm
         cls.servers_admin_client = cls.os_adm.servers_v3_client
+        cls.instance_usages_audit_log_admin_client = \
+            cls.os_adm.instance_usages_audit_log_v3_client
         cls.services_admin_client = cls.os_adm.services_v3_client
         cls.availability_zone_admin_client = \
             cls.os_adm.availability_zone_v3_client
diff --git a/tempest/api/compute/floating_ips/base.py b/tempest/api/compute/floating_ips/base.py
new file mode 100644
index 0000000..e2c9b04
--- /dev/null
+++ b/tempest/api/compute/floating_ips/base.py
@@ -0,0 +1,28 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2014 OpenStack Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.api.compute import base
+
+
+class BaseFloatingIPsTest(base.BaseV2ComputeTest):
+
+    @classmethod
+    def setUpClass(cls):
+        # Floating IP actions might need a full network configuration
+        cls.set_network_resources(network=True, subnet=True,
+                                  router=True, dhcp=True)
+        super(BaseFloatingIPsTest, cls).setUpClass()
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 32e7b39..cd5f4a8 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
@@ -15,13 +15,13 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api.compute import base
+from tempest.api.compute.floating_ips import base
 from tempest.common.utils.data_utils import rand_name
 from tempest import exceptions
 from tempest.test import attr
 
 
-class FloatingIPsTestJSON(base.BaseV2ComputeTest):
+class FloatingIPsTestJSON(base.BaseFloatingIPsTest):
     _interface = 'json'
     server_id = None
     floating_ip = None
diff --git a/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py b/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
index 89315bb..674669c 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
@@ -17,13 +17,13 @@
 
 import uuid
 
-from tempest.api.compute import base
+from tempest.api.compute.floating_ips import base
 from tempest.common.utils import data_utils
 from tempest import exceptions
 from tempest.test import attr
 
 
-class FloatingIPsNegativeTestJSON(base.BaseV2ComputeTest):
+class FloatingIPsNegativeTestJSON(base.BaseFloatingIPsTest):
     _interface = 'json'
     server_id = None
 
diff --git a/tempest/api/compute/security_groups/base.py b/tempest/api/compute/security_groups/base.py
new file mode 100644
index 0000000..66f2600
--- /dev/null
+++ b/tempest/api/compute/security_groups/base.py
@@ -0,0 +1,27 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012 OpenStack Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.api.compute import base
+
+
+class BaseSecurityGroupsTest(base.BaseV2ComputeTest):
+
+    @classmethod
+    def setUpClass(cls):
+        # A network and a subnet will be created for these tests
+        cls.set_network_resources(network=True, subnet=True)
+        super(BaseSecurityGroupsTest, cls).setUpClass()
diff --git a/tempest/api/compute/security_groups/test_security_group_rules.py b/tempest/api/compute/security_groups/test_security_group_rules.py
index 2ccc3a8..eddccc1 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules.py
@@ -15,12 +15,12 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api.compute import base
+from tempest.api.compute.security_groups import base
 from tempest.common.utils import data_utils
 from tempest.test import attr
 
 
-class SecurityGroupRulesTestJSON(base.BaseV2ComputeTest):
+class SecurityGroupRulesTestJSON(base.BaseSecurityGroupsTest):
     _interface = 'json'
 
     @classmethod
diff --git a/tempest/api/compute/security_groups/test_security_group_rules_negative.py b/tempest/api/compute/security_groups/test_security_group_rules_negative.py
index c0b202d..bec95ad 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules_negative.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules_negative.py
@@ -17,7 +17,7 @@
 
 import testtools
 
-from tempest.api.compute import base
+from tempest.api.compute.security_groups import base
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest import exceptions
@@ -27,7 +27,7 @@
 CONF = config.CONF
 
 
-class SecurityGroupRulesNegativeTestJSON(base.BaseV2ComputeTest):
+class SecurityGroupRulesNegativeTestJSON(base.BaseSecurityGroupsTest):
     _interface = 'json'
 
     @classmethod
diff --git a/tempest/api/compute/security_groups/test_security_groups.py b/tempest/api/compute/security_groups/test_security_groups.py
index 4ae65be..ffd9fd2 100644
--- a/tempest/api/compute/security_groups/test_security_groups.py
+++ b/tempest/api/compute/security_groups/test_security_groups.py
@@ -15,13 +15,13 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api.compute import base
+from tempest.api.compute.security_groups import base
 from tempest.common.utils import data_utils
 from tempest import exceptions
 from tempest import test
 
 
-class SecurityGroupsTestJSON(base.BaseV2ComputeTest):
+class SecurityGroupsTestJSON(base.BaseSecurityGroupsTest):
     _interface = 'json'
 
     @classmethod
diff --git a/tempest/api/compute/security_groups/test_security_groups_negative.py b/tempest/api/compute/security_groups/test_security_groups_negative.py
index 6a8e604..cf78089 100644
--- a/tempest/api/compute/security_groups/test_security_groups_negative.py
+++ b/tempest/api/compute/security_groups/test_security_groups_negative.py
@@ -17,7 +17,7 @@
 
 import testtools
 
-from tempest.api.compute import base
+from tempest.api.compute.security_groups import base
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest import exceptions
@@ -26,7 +26,7 @@
 CONF = config.CONF
 
 
-class SecurityGroupsNegativeTestJSON(base.BaseV2ComputeTest):
+class SecurityGroupsNegativeTestJSON(base.BaseSecurityGroupsTest):
     _interface = 'json'
 
     @classmethod
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index dbb7d75..738e4a8 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -26,6 +26,8 @@
     def setUpClass(cls):
         if not cls.config.service_available.neutron:
             raise cls.skipException("Neutron is required")
+        # This test class requires network and subnet
+        cls.set_network_resources(network=True, subnet=True)
         super(AttachInterfacesTestJSON, cls).setUpClass()
         cls.client = cls.os.interfaces_client
 
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index 5d62e1b..e45161b 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -109,6 +109,104 @@
         self.assertTrue(linux_client.hostname_equals_servername(self.name))
 
 
+class ServersWithSpecificFlavorTestJSON(base.BaseV2ComputeAdminTest):
+    _interface = 'json'
+    run_ssh = CONF.compute.run_ssh
+    disk_config = 'AUTO'
+
+    @classmethod
+    def setUpClass(cls):
+        super(ServersWithSpecificFlavorTestJSON, cls).setUpClass()
+        cls.meta = {'hello': 'world'}
+        cls.accessIPv4 = '1.1.1.1'
+        cls.accessIPv6 = '0000:0000:0000:0000:0000:babe:220.12.22.2'
+        cls.name = data_utils.rand_name('server')
+        file_contents = 'This is a test file.'
+        personality = [{'path': '/test.txt',
+                       'contents': base64.b64encode(file_contents)}]
+        cls.client = cls.servers_client
+        cls.flavor_client = cls.os_adm.flavors_client
+        cli_resp = cls.create_test_server(name=cls.name,
+                                          meta=cls.meta,
+                                          accessIPv4=cls.accessIPv4,
+                                          accessIPv6=cls.accessIPv6,
+                                          personality=personality,
+                                          disk_config=cls.disk_config)
+        cls.resp, cls.server_initial = cli_resp
+        cls.password = cls.server_initial['adminPass']
+        cls.client.wait_for_server_status(cls.server_initial['id'], 'ACTIVE')
+        resp, cls.server = cls.client.get_server(cls.server_initial['id'])
+
+    @testtools.skipIf(not run_ssh, 'Instance validation tests are disabled.')
+    @attr(type='gate')
+    def test_verify_created_server_ephemeral_disk(self):
+        # Verify that the ephemeral disk is created when creating server
+
+        def create_flavor_with_extra_specs(self):
+            flavor_with_eph_disk_name = data_utils.rand_name('eph_flavor')
+            flavor_with_eph_disk_id = data_utils.rand_int_id(start=1000)
+            ram = 64
+            vcpus = 1
+            disk = 0
+
+            # Create a flavor with extra specs
+            resp, flavor = (self.flavor_client.
+                            create_flavor(flavor_with_eph_disk_name,
+                                          ram, vcpus, disk,
+                                          flavor_with_eph_disk_id,
+                                          ephemeral=1))
+            self.addCleanup(self.flavor_clean_up, flavor['id'])
+            self.assertEqual(200, resp.status)
+
+            return flavor['id']
+
+        def create_flavor_without_extra_specs(self):
+            flavor_no_eph_disk_name = data_utils.rand_name('no_eph_flavor')
+            flavor_no_eph_disk_id = data_utils.rand_int_id(start=1000)
+
+            ram = 64
+            vcpus = 1
+            disk = 0
+
+            # Create a flavor without extra specs
+            resp, flavor = (self.flavor_client.
+                            create_flavor(flavor_no_eph_disk_name,
+                                          ram, vcpus, disk,
+                                          flavor_no_eph_disk_id))
+            self.addCleanup(self.flavor_clean_up, flavor['id'])
+            self.assertEqual(200, resp.status)
+
+            return flavor['id']
+
+        def flavor_clean_up(self, flavor_id):
+            resp, body = self.flavor_client.delete_flavor(flavor_id)
+            self.assertEqual(resp.status, 202)
+            self.flavor_client.wait_for_resource_deletion(flavor_id)
+
+        flavor_with_eph_disk_id = self.create_flavor_with_extra_specs()
+        flavor_no_eph_disk_id = self.create_flavor_without_extra_specs()
+
+        admin_pass = self.image_ssh_password
+
+        resp, server_no_eph_disk = (self.
+                                    create_test_server(
+                                    wait_until='ACTIVE',
+                                    adminPass=admin_pass,
+                                    flavor=flavor_no_eph_disk_id))
+        resp, server_with_eph_disk = (self.create_test_server(
+                                      wait_until='ACTIVE',
+                                      adminPass=admin_pass,
+                                      flavor=flavor_with_eph_disk_id))
+        # Get partition number of server without extra specs.
+        linux_client = RemoteClient(server_no_eph_disk,
+                                    self.ssh_user, self.password)
+        partition_num = len(linux_client.get_partitions())
+
+        linux_client = RemoteClient(server_with_eph_disk,
+                                    self.ssh_user, self.password)
+        self.assertEqual(partition_num + 1, linux_client.get_partitions())
+
+
 class ServersTestManualDisk(ServersTestJSON):
     disk_config = 'MANUAL'
 
@@ -122,3 +220,7 @@
 
 class ServersTestXML(ServersTestJSON):
     _interface = 'xml'
+
+
+class ServersWithSpecificFlavorTestXML(ServersWithSpecificFlavorTestJSON):
+    _interface = 'xml'
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index f195562..e4af2e1 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -174,7 +174,7 @@
 
     def _detect_server_image_flavor(self, server_id):
         # Detects the current server image flavor ref.
-        resp, server = self.client.get_server(self.server_id)
+        resp, server = self.client.get_server(server_id)
         current_flavor = server['flavor']['id']
         new_flavor_ref = self.flavor_ref_alt \
             if current_flavor == self.flavor_ref else self.flavor_ref
diff --git a/tempest/api/compute/servers/test_server_addresses.py b/tempest/api/compute/servers/test_server_addresses.py
index 1e55afb..39d9580 100644
--- a/tempest/api/compute/servers/test_server_addresses.py
+++ b/tempest/api/compute/servers/test_server_addresses.py
@@ -24,6 +24,8 @@
 
     @classmethod
     def setUpClass(cls):
+        # This test module might use a network and a subnet
+        cls.set_network_resources(network=True, subnet=True)
         super(ServerAddressesTestJSON, cls).setUpClass()
         cls.client = cls.servers_client
 
diff --git a/tempest/api/compute/servers/test_server_addresses_negative.py b/tempest/api/compute/servers/test_server_addresses_negative.py
index 30aa7d1..0343538 100644
--- a/tempest/api/compute/servers/test_server_addresses_negative.py
+++ b/tempest/api/compute/servers/test_server_addresses_negative.py
@@ -25,6 +25,7 @@
 
     @classmethod
     def setUpClass(cls):
+        cls.set_network_resources(network=True, subnet=True)
         super(ServerAddressesNegativeTestJSON, cls).setUpClass()
         cls.client = cls.servers_client
 
diff --git a/tempest/api/compute/servers/test_virtual_interfaces.py b/tempest/api/compute/servers/test_virtual_interfaces.py
index 968ae47..7bbe30b 100644
--- a/tempest/api/compute/servers/test_virtual_interfaces.py
+++ b/tempest/api/compute/servers/test_virtual_interfaces.py
@@ -29,6 +29,8 @@
 
     @classmethod
     def setUpClass(cls):
+        # This test needs a network and a subnet
+        cls.set_network_resources(network=True, subnet=True)
         super(VirtualInterfacesTestJSON, cls).setUpClass()
         cls.client = cls.servers_client
         resp, server = cls.create_test_server(wait_until='ACTIVE')
diff --git a/tempest/api/compute/servers/test_virtual_interfaces_negative.py b/tempest/api/compute/servers/test_virtual_interfaces_negative.py
index a2a6c11..d67e13a 100644
--- a/tempest/api/compute/servers/test_virtual_interfaces_negative.py
+++ b/tempest/api/compute/servers/test_virtual_interfaces_negative.py
@@ -27,6 +27,8 @@
 
     @classmethod
     def setUpClass(cls):
+        # For this test no network resources are needed
+        cls.set_network_resources()
         super(VirtualInterfacesNegativeTestJSON, cls).setUpClass()
         cls.client = cls.servers_client
 
diff --git a/tempest/api/compute/test_authorization.py b/tempest/api/compute/test_authorization.py
index 327c7d1..03075df 100644
--- a/tempest/api/compute/test_authorization.py
+++ b/tempest/api/compute/test_authorization.py
@@ -30,6 +30,8 @@
 
     @classmethod
     def setUpClass(cls):
+        # No network resources required for this test
+        cls.set_network_resources()
         super(AuthorizationTestJSON, cls).setUpClass()
         if not cls.multi_user:
             msg = "Need >1 user"
diff --git a/tempest/api/compute/v3/admin/test_hosts_negative.py b/tempest/api/compute/v3/admin/test_hosts_negative.py
index 755fa2b..598a1d3 100644
--- a/tempest/api/compute/v3/admin/test_hosts_negative.py
+++ b/tempest/api/compute/v3/admin/test_hosts_negative.py
@@ -66,7 +66,9 @@
 
         self.assertRaises(exceptions.Unauthorized,
                           self.non_admin_client.update_host,
-                          hostname)
+                          hostname,
+                          status='enable',
+                          maintenance_mode='enable')
 
     @test.attr(type=['negative', 'gate'])
     def test_update_host_with_extra_param(self):
diff --git a/tempest/api/compute/v3/admin/test_instance_usage_audit_log.py b/tempest/api/compute/v3/admin/test_instance_usage_audit_log.py
index cea6e92..d0cfc63 100644
--- a/tempest/api/compute/v3/admin/test_instance_usage_audit_log.py
+++ b/tempest/api/compute/v3/admin/test_instance_usage_audit_log.py
@@ -16,22 +16,22 @@
 #    under the License.
 
 import datetime
-
-from tempest.api.compute import base
-from tempest.test import attr
 import urllib
 
+from tempest.api.compute import base
+from tempest import test
 
-class InstanceUsageAuditLogTestJSON(base.BaseV2ComputeAdminTest):
+
+class InstanceUsageAuditLogV3TestJSON(base.BaseV3ComputeAdminTest):
 
     _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
-        super(InstanceUsageAuditLogTestJSON, cls).setUpClass()
-        cls.adm_client = cls.os_adm.instance_usages_audit_log_client
+        super(InstanceUsageAuditLogV3TestJSON, cls).setUpClass()
+        cls.adm_client = cls.instance_usages_audit_log_admin_client
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_instance_usage_audit_logs(self):
         # list instance usage audit logs
         resp, body = self.adm_client.list_instance_usage_audit_logs()
@@ -44,12 +44,12 @@
         for item in expected_items:
             self.assertIn(item, body)
 
-    @attr(type='gate')
-    def test_get_instance_usage_audit_log(self):
+    @test.attr(type='gate')
+    def test_list_instance_usage_audit_logs_with_filter_before(self):
         # Get instance usage audit log before specified time
-        now = datetime.datetime.now()
-        resp, body = self.adm_client.get_instance_usage_audit_log(
-            urllib.quote(now.strftime("%Y-%m-%d %H:%M:%S")))
+        ending_time = datetime.datetime(2012, 12, 24)
+        resp, body = self.adm_client.list_instance_usage_audit_logs(
+            urllib.quote(ending_time.strftime("%Y-%m-%d %H:%M:%S")))
 
         self.assertEqual(200, resp.status)
         expected_items = ['total_errors', 'total_instances', 'log',
@@ -58,7 +58,8 @@
                           'period_beginning', 'num_hosts_not_run']
         for item in expected_items:
             self.assertIn(item, body)
+        self.assertEqual(body['period_ending'], "2012-12-23 23:00:00")
 
 
-class InstanceUsageAuditLogTestXML(InstanceUsageAuditLogTestJSON):
+class InstanceUsageAuditLogV3TestXML(InstanceUsageAuditLogV3TestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/v3/admin/test_instance_usage_audit_log_negative.py b/tempest/api/compute/v3/admin/test_instance_usage_audit_log_negative.py
index dcf41c5..6e919c9 100644
--- a/tempest/api/compute/v3/admin/test_instance_usage_audit_log_negative.py
+++ b/tempest/api/compute/v3/admin/test_instance_usage_audit_log_negative.py
@@ -15,42 +15,34 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import datetime
-
 from tempest.api.compute import base
 from tempest import exceptions
-from tempest.test import attr
-import urllib
+from tempest import test
 
 
-class InstanceUsageAuditLogNegativeTestJSON(base.BaseV2ComputeAdminTest):
+class InstanceUsageLogNegativeV3TestJSON(base.BaseV3ComputeAdminTest):
 
     _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
-        super(InstanceUsageAuditLogNegativeTestJSON, cls).setUpClass()
-        cls.adm_client = cls.os_adm.instance_usages_audit_log_client
+        super(InstanceUsageLogNegativeV3TestJSON, cls).setUpClass()
+        cls.adm_client = cls.instance_usages_audit_log_admin_client
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_instance_usage_audit_logs_with_nonadmin_user(self):
         # the instance_usage_audit_logs API just can be accessed by admin user
         self.assertRaises(exceptions.Unauthorized,
                           self.instance_usages_audit_log_client.
                           list_instance_usage_audit_logs)
-        now = datetime.datetime.now()
-        self.assertRaises(exceptions.Unauthorized,
-                          self.instance_usages_audit_log_client.
-                          get_instance_usage_audit_log,
-                          urllib.quote(now.strftime("%Y-%m-%d %H:%M:%S")))
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_get_instance_usage_audit_logs_with_invalid_time(self):
         self.assertRaises(exceptions.BadRequest,
-                          self.adm_client.get_instance_usage_audit_log,
+                          self.adm_client.list_instance_usage_audit_logs,
                           "invalid_time")
 
 
-class InstanceUsageAuditLogNegativeTestXML(
-    InstanceUsageAuditLogNegativeTestJSON):
+class InstanceUsageLogNegativeV3TestXML(
+    InstanceUsageLogNegativeV3TestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/v3/servers/test_create_server.py b/tempest/api/compute/v3/servers/test_create_server.py
index e1bb160..1555442 100644
--- a/tempest/api/compute/v3/servers/test_create_server.py
+++ b/tempest/api/compute/v3/servers/test_create_server.py
@@ -117,6 +117,104 @@
         self.assertTrue(linux_client.hostname_equals_servername(self.name))
 
 
+class ServersWithSpecificFlavorV3TestJSON(base.BaseV3ComputeAdminTest):
+    _interface = 'json'
+    run_ssh = CONF.compute.run_ssh
+    disk_config = 'AUTO'
+
+    @classmethod
+    def setUpClass(cls):
+        super(ServersWithSpecificFlavorV3TestJSON, cls).setUpClass()
+        cls.meta = {'hello': 'world'}
+        cls.accessIPv4 = '1.1.1.1'
+        cls.accessIPv6 = '0000:0000:0000:0000:0000:babe:220.12.22.2'
+        cls.name = data_utils.rand_name('server')
+        file_contents = 'This is a test file.'
+        personality = [{'path': '/test.txt',
+                       'contents': base64.b64encode(file_contents)}]
+        cls.client = cls.servers_client
+        cls.flavor_client = cls.flavors_admin_client
+        cli_resp = cls.create_test_server(name=cls.name,
+                                          meta=cls.meta,
+                                          access_ip_v4=cls.accessIPv4,
+                                          access_ip_v6=cls.accessIPv6,
+                                          personality=personality,
+                                          disk_config=cls.disk_config)
+        cls.resp, cls.server_initial = cli_resp
+        cls.password = cls.server_initial['admin_password']
+        cls.client.wait_for_server_status(cls.server_initial['id'], 'ACTIVE')
+        resp, cls.server = cls.client.get_server(cls.server_initial['id'])
+
+    @testtools.skipIf(not run_ssh, 'Instance validation tests are disabled.')
+    @test.attr(type='gate')
+    def test_verify_created_server_ephemeral_disk(self):
+        # Verify that the ephemeral disk is created when creating server
+
+        def create_flavor_with_extra_specs(self):
+            flavor_with_eph_disk_name = data_utils.rand_name('eph_flavor')
+            flavor_with_eph_disk_id = data_utils.rand_int_id(start=1000)
+            ram = 512
+            vcpus = 1
+            disk = 10
+
+            # Create a flavor with extra specs
+            resp, flavor = (self.flavor_client.
+                            create_flavor(flavor_with_eph_disk_name,
+                                          ram, vcpus, disk,
+                                          flavor_with_eph_disk_id,
+                                          ephemeral=1, swap=1024, rxtx=1))
+            self.addCleanup(self.flavor_clean_up, flavor['id'])
+            self.assertEqual(200, resp.status)
+
+            return flavor['id']
+
+        def create_flavor_without_extra_specs(self):
+            flavor_no_eph_disk_name = data_utils.rand_name('no_eph_flavor')
+            flavor_no_eph_disk_id = data_utils.rand_int_id(start=1000)
+
+            ram = 512
+            vcpus = 1
+            disk = 10
+
+            # Create a flavor without extra specs
+            resp, flavor = (self.flavor_client.
+                            create_flavor(flavor_no_eph_disk_name,
+                                          ram, vcpus, disk,
+                                          flavor_no_eph_disk_id))
+            self.addCleanup(self.flavor_clean_up, flavor['id'])
+            self.assertEqual(200, resp.status)
+
+            return flavor['id']
+
+        def flavor_clean_up(self, flavor_id):
+            resp, body = self.flavor_client.delete_flavor(flavor_id)
+            self.assertEqual(resp.status, 202)
+            self.flavor_client.wait_for_resource_deletion(flavor_id)
+
+        flavor_with_eph_disk_id = self.create_flavor_with_extra_specs()
+        flavor_no_eph_disk_id = self.create_flavor_without_extra_specs()
+
+        admin_pass = self.image_ssh_password
+
+        resp, server_no_eph_disk = (self.
+                                    create_test_server(
+                                    wait_until='ACTIVE',
+                                    adminPass=admin_pass,
+                                    flavor=flavor_no_eph_disk_id))
+        resp, server_with_eph_disk = (self.create_test_server(
+                                      wait_until='ACTIVE',
+                                      adminPass=admin_pass,
+                                      flavor=flavor_with_eph_disk_id))
+        # Get partition number of server without extra specs.
+        linux_client = RemoteClient(server_no_eph_disk,
+                                    self.ssh_user, self.password)
+        partition_num = len(linux_client.get_partitions())
+
+        linux_client = RemoteClient(server_with_eph_disk,
+                                    self.ssh_user, self.password)
+        self.assertEqual(partition_num + 1, linux_client.get_partitions())
+
+
 class ServersV3TestManualDisk(ServersV3TestJSON):
     disk_config = 'MANUAL'
 
@@ -130,3 +228,7 @@
 
 class ServersV3TestXML(ServersV3TestJSON):
     _interface = 'xml'
+
+
+class ServersWithSpecificFlavorV3TestXML(ServersWithSpecificFlavorV3TestJSON):
+    _interface = 'xml'
diff --git a/tempest/api/compute/v3/servers/test_server_actions.py b/tempest/api/compute/v3/servers/test_server_actions.py
index ad9dbe1..f462cc2 100644
--- a/tempest/api/compute/v3/servers/test_server_actions.py
+++ b/tempest/api/compute/v3/servers/test_server_actions.py
@@ -15,7 +15,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import base64
 import time
 
 import testtools
@@ -113,15 +112,11 @@
         # The server should be rebuilt using the provided image and data
         meta = {'rebuild': 'server'}
         new_name = data_utils.rand_name('server')
-        file_contents = 'Test server rebuild.'
-        personality = [{'path': 'rebuild.txt',
-                       'contents': base64.b64encode(file_contents)}]
         password = 'rebuildPassw0rd'
         resp, rebuilt_server = self.client.rebuild(self.server_id,
                                                    self.image_ref_alt,
                                                    name=new_name,
                                                    metadata=meta,
-                                                   personality=personality,
                                                    admin_password=password)
         self.addCleanup(self.client.rebuild, self.server_id, self.image_ref)
 
@@ -174,7 +169,7 @@
 
     def _detect_server_image_flavor(self, server_id):
         # Detects the current server image flavor ref.
-        resp, server = self.client.get_server(self.server_id)
+        resp, server = self.client.get_server(server_id)
         current_flavor = server['flavor']['id']
         new_flavor_ref = self.flavor_ref_alt \
             if current_flavor == self.flavor_ref else self.flavor_ref
diff --git a/tempest/api/compute/v3/servers/test_server_metadata.py b/tempest/api/compute/v3/servers/test_server_metadata.py
index ee0f4a9..f36feb3 100644
--- a/tempest/api/compute/v3/servers/test_server_metadata.py
+++ b/tempest/api/compute/v3/servers/test_server_metadata.py
@@ -20,12 +20,12 @@
 from tempest.test import attr
 
 
-class ServerMetadataTestJSON(base.BaseV2ComputeTest):
+class ServerMetadataV3TestJSON(base.BaseV3ComputeTest):
     _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
-        super(ServerMetadataTestJSON, cls).setUpClass()
+        super(ServerMetadataV3TestJSON, cls).setUpClass()
         cls.client = cls.servers_client
         cls.quotas = cls.quotas_client
         cls.admin_client = cls._get_identity_admin_client()
@@ -37,7 +37,7 @@
         cls.server_id = server['id']
 
     def setUp(self):
-        super(ServerMetadataTestJSON, self).setUp()
+        super(ServerMetadataV3TestJSON, self).setUp()
         meta = {'key1': 'value1', 'key2': 'value2'}
         resp, _ = self.client.set_server_metadata(self.server_id, meta)
         self.assertEqual(resp.status, 200)
@@ -88,7 +88,7 @@
         meta = {'key1': 'alt1', 'key3': 'value3'}
         resp, metadata = self.client.update_server_metadata(self.server_id,
                                                             meta)
-        self.assertEqual(200, resp.status)
+        self.assertEqual(201, resp.status)
 
         # Verify the values have been updated to the proper values
         resp, resp_metadata = self.client.list_server_metadata(self.server_id)
@@ -213,5 +213,5 @@
                           self.server_id, meta=meta, no_metadata_field=True)
 
 
-class ServerMetadataTestXML(ServerMetadataTestJSON):
+class ServerMetadataV3TestXML(ServerMetadataV3TestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/v3/servers/test_server_personality.py b/tempest/api/compute/v3/servers/test_server_personality.py
deleted file mode 100644
index c6d2e44..0000000
--- a/tempest/api/compute/v3/servers/test_server_personality.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import base64
-
-from tempest.api.compute import base
-from tempest import exceptions
-from tempest.test import attr
-
-
-class ServerPersonalityTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
-
-    @classmethod
-    def setUpClass(cls):
-        super(ServerPersonalityTestJSON, cls).setUpClass()
-        cls.client = cls.servers_client
-        cls.user_client = cls.limits_client
-
-    @attr(type='gate')
-    def test_personality_files_exceed_limit(self):
-        # Server creation should fail if greater than the maximum allowed
-        # number of files are injected into the server.
-        file_contents = 'This is a test file.'
-        personality = []
-        max_file_limit = \
-            self.user_client.get_specific_absolute_limit("maxPersonality")
-        for i in range(0, int(max_file_limit) + 1):
-            path = 'etc/test' + str(i) + '.txt'
-            personality.append({'path': path,
-                                'contents': base64.b64encode(file_contents)})
-        self.assertRaises(exceptions.OverLimit, self.create_test_server,
-                          personality=personality)
-
-    @attr(type='gate')
-    def test_can_create_server_with_max_number_personality_files(self):
-        # Server should be created successfully if maximum allowed number of
-        # files is injected into the server during creation.
-        file_contents = 'This is a test file.'
-        max_file_limit = \
-            self.user_client.get_specific_absolute_limit("maxPersonality")
-        person = []
-        for i in range(0, int(max_file_limit)):
-            path = 'etc/test' + str(i) + '.txt'
-            person.append({
-                'path': path,
-                'contents': base64.b64encode(file_contents),
-            })
-        resp, server = self.create_test_server(personality=person)
-        self.assertEqual('202', resp['status'])
-
-
-class ServerPersonalityTestXML(ServerPersonalityTestJSON):
-    _interface = "xml"
diff --git a/tempest/api/identity/admin/v3/test_trusts.py b/tempest/api/identity/admin/v3/test_trusts.py
index d316ae1..98b298e 100644
--- a/tempest/api/identity/admin/v3/test_trusts.py
+++ b/tempest/api/identity/admin/v3/test_trusts.py
@@ -17,16 +17,22 @@
 from tempest.api.identity import base
 from tempest import clients
 from tempest.common.utils.data_utils import rand_name
+from tempest import config
 from tempest import exceptions
 from tempest.openstack.common import timeutils
 from tempest.test import attr
 
+CONF = config.CONF
+
 
 class BaseTrustsV3Test(base.BaseIdentityAdminTest):
 
     def setUp(self):
         super(BaseTrustsV3Test, self).setUp()
         # Use alt_username as the trustee
+        if not CONF.identity_feature_enabled.trust:
+            raise self.skipException("Trusts aren't enabled")
+
         self.trustee_username = self.config.identity.alt_username
         self.trust_id = None
 
diff --git a/tempest/api/image/base.py b/tempest/api/image/base.py
index 28ed5b6..b521bce 100644
--- a/tempest/api/image/base.py
+++ b/tempest/api/image/base.py
@@ -34,7 +34,8 @@
         super(BaseImageTest, cls).setUpClass()
         cls.created_images = []
         cls._interface = 'json'
-        cls.isolated_creds = isolated_creds.IsolatedCreds(cls.__name__)
+        cls.isolated_creds = isolated_creds.IsolatedCreds(
+            cls.__name__, network_resources=cls.network_resources)
         if not cls.config.service_available.glance:
             skip_msg = ("%s skipped as glance is not available" % cls.__name__)
             raise cls.skipException(skip_msg)
@@ -129,7 +130,7 @@
             raise cls.skipException(msg)
 
 
-class BaseV2MemeberImageTest(BaseImageTest):
+class BaseV2MemeberImageTest(BaseV2ImageTest):
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index dcad101..fd3dc9f 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -50,6 +50,8 @@
 
     @classmethod
     def setUpClass(cls):
+        # Create no network resources for these test.
+        cls.set_network_resources()
         super(BaseNetworkTest, cls).setUpClass()
         os = clients.Manager(interface=cls._interface)
         cls.network_cfg = os.config.network
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index 68ca66a..849d62e 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -127,6 +127,21 @@
         self.assertIsNotNone(found, msg)
 
     @attr(type='smoke')
+    def test_list_networks_fields(self):
+        # Verify listing some 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")
+
+    @attr(type='smoke')
     def test_show_subnet(self):
         # Verifies the details of a subnet
         resp, body = self.client.show_subnet(self.subnet['id'])
@@ -149,6 +164,21 @@
         self.assertIsNotNone(found, msg)
 
     @attr(type='smoke')
+    def test_list_subnets_fields(self):
+        # Verify listing some fields of the 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(self.network['id'])
@@ -184,6 +214,21 @@
                 found = n['id']
         self.assertIsNotNone(found, "Port list doesn't contain created port")
 
+    @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")
+
 
 class NetworksTestXML(NetworksTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/network/test_security_groups.py b/tempest/api/network/test_security_groups.py
index 9b0a3de..37b1f2c 100644
--- a/tempest/api/network/test_security_groups.py
+++ b/tempest/api/network/test_security_groups.py
@@ -82,6 +82,36 @@
                      for rule in rule_list_body['security_group_rules']]
         self.assertIn(rule_create_body['security_group_rule']['id'], rule_list)
 
+    @attr(type='smoke')
+    def test_create_security_group_rule_with_additional_args(self):
+        # Verify creating security group rule with the following
+        # arguments works: "protocol": "tcp", "port_range_max": 77,
+        # "port_range_min": 77, "direction":"ingress".
+        group_create_body, _ = self._create_security_group()
+
+        direction = 'ingress'
+        protocol = 'tcp'
+        port_range_min = 77
+        port_range_max = 77
+        resp, rule_create_body = self.client.create_security_group_rule(
+            group_create_body['security_group']['id'],
+            direction=direction,
+            protocol=protocol,
+            port_range_min=port_range_min,
+            port_range_max=port_range_max
+        )
+
+        self.assertEqual('201', resp['status'])
+        sec_group_rule = rule_create_body['security_group_rule']
+        self.addCleanup(self._delete_security_group_rule,
+                        sec_group_rule['id']
+                        )
+
+        self.assertEqual(sec_group_rule['direction'], direction)
+        self.assertEqual(sec_group_rule['protocol'], protocol)
+        self.assertEqual(int(sec_group_rule['port_range_min']), port_range_min)
+        self.assertEqual(int(sec_group_rule['port_range_max']), port_range_max)
+
 
 class SecGroupTestXML(SecGroupTest):
     _interface = 'xml'
diff --git a/tempest/api/object_storage/base.py b/tempest/api/object_storage/base.py
index 47d8cca..b4928dd 100644
--- a/tempest/api/object_storage/base.py
+++ b/tempest/api/object_storage/base.py
@@ -32,7 +32,8 @@
         if not cls.config.service_available.swift:
             skip_msg = ("%s skipped as swift is not available" % cls.__name__)
             raise cls.skipException(skip_msg)
-        cls.isolated_creds = isolated_creds.IsolatedCreds(cls.__name__)
+        cls.isolated_creds = isolated_creds.IsolatedCreds(
+            cls.__name__, network_resources=cls.network_resources)
         if cls.config.compute.allow_tenant_isolation:
             # Get isolated creds for normal user
             creds = cls.isolated_creds.get_primary_creds()
diff --git a/tempest/clients.py b/tempest/clients.py
index 519d191..75f8838 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -64,6 +64,8 @@
 from tempest.services.compute.v3.json.hosts_client import HostsV3ClientJSON
 from tempest.services.compute.v3.json.hypervisor_client import \
     HypervisorV3ClientJSON
+from tempest.services.compute.v3.json.instance_usage_audit_log_client import \
+    InstanceUsagesAuditLogV3ClientJSON
 from tempest.services.compute.v3.json.interfaces_client import \
     InterfacesV3ClientJSON
 from tempest.services.compute.v3.json.keypairs_client import \
@@ -88,6 +90,8 @@
 from tempest.services.compute.v3.xml.hosts_client import HostsV3ClientXML
 from tempest.services.compute.v3.xml.hypervisor_client import \
     HypervisorV3ClientXML
+from tempest.services.compute.v3.xml.instance_usage_audit_log_client import \
+    InstanceUsagesAuditLogV3ClientXML
 from tempest.services.compute.v3.xml.interfaces_client import \
     InterfacesV3ClientXML
 from tempest.services.compute.v3.xml.keypairs_client import KeyPairsV3ClientXML
@@ -284,6 +288,8 @@
             self.credentials_client = CredentialsClientXML(*client_args)
             self.instance_usages_audit_log_client = \
                 InstanceUsagesAuditLogClientXML(*client_args)
+            self.instance_usages_audit_log_v3_client = \
+                InstanceUsagesAuditLogV3ClientXML(*client_args)
             self.volume_hosts_client = VolumeHostsClientXML(*client_args)
             self.volumes_extension_client = VolumeExtensionClientXML(
                 *client_args)
@@ -347,6 +353,8 @@
             self.credentials_client = CredentialsClientJSON(*client_args)
             self.instance_usages_audit_log_client = \
                 InstanceUsagesAuditLogClientJSON(*client_args)
+            self.instance_usages_audit_log_v3_client = \
+                InstanceUsagesAuditLogV3ClientJSON(*client_args)
             self.volume_hosts_client = VolumeHostsClientJSON(*client_args)
             self.volumes_extension_client = VolumeExtensionClientJSON(
                 *client_args)
diff --git a/tempest/common/isolated_creds.py b/tempest/common/isolated_creds.py
index da60318..9c0d7f6 100644
--- a/tempest/common/isolated_creds.py
+++ b/tempest/common/isolated_creds.py
@@ -32,7 +32,8 @@
 class IsolatedCreds(object):
 
     def __init__(self, name, tempest_client=True, interface='json',
-                 password='pass'):
+                 password='pass', network_resources=None):
+        self.network_resources = network_resources
         self.isolated_creds = {}
         self.isolated_net_resources = {}
         self.ports = []
@@ -198,15 +199,33 @@
         network = None
         subnet = None
         router = None
+        # Make sure settings
+        if self.network_resources:
+            if self.network_resources['router']:
+                if (not self.network_resources['subnet'] or
+                    not self.network_resources['network']):
+                    raise exceptions.InvalidConfiguration(
+                        'A router requires a subnet and network')
+            elif self.network_resources['subnet']:
+                if not self.network_resources['network']:
+                    raise exceptions.InvalidConfiguration(
+                        'A subnet requires a network')
+            elif self.network_resources['dhcp']:
+                raise exceptions.InvalidConfiguration('DHCP requires a subnet')
+
         data_utils.rand_name_root = data_utils.rand_name(self.name)
-        network_name = data_utils.rand_name_root + "-network"
-        network = self._create_network(network_name, tenant_id)
+        if not self.network_resources or self.network_resources['network']:
+            network_name = data_utils.rand_name_root + "-network"
+            network = self._create_network(network_name, tenant_id)
         try:
-            subnet_name = data_utils.rand_name_root + "-subnet"
-            subnet = self._create_subnet(subnet_name, tenant_id, network['id'])
-            router_name = data_utils.rand_name_root + "-router"
-            router = self._create_router(router_name, tenant_id)
-            self._add_router_interface(router['id'], subnet['id'])
+            if not self.network_resources or self.network_resources['subnet']:
+                subnet_name = data_utils.rand_name_root + "-subnet"
+                subnet = self._create_subnet(subnet_name, tenant_id,
+                                             network['id'])
+            if not self.network_resources or self.network_resources['router']:
+                router_name = data_utils.rand_name_root + "-router"
+                router = self._create_router(router_name, tenant_id)
+                self._add_router_interface(router['id'], subnet['id'])
         except Exception:
             if router:
                 self._clear_isolated_router(router['id'], router['name'])
@@ -230,14 +249,25 @@
         if not self.tempest_client:
             body = {'subnet': {'name': subnet_name, 'tenant_id': tenant_id,
                                'network_id': network_id, 'ip_version': 4}}
+            if self.network_resources:
+                body['enable_dhcp'] = self.network_resources['dhcp']
         base_cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
         mask_bits = CONF.network.tenant_network_mask_bits
         for subnet_cidr in base_cidr.subnet(mask_bits):
             try:
                 if self.tempest_client:
-                    resp, resp_body = self.network_admin_client.create_subnet(
-                        network_id, str(subnet_cidr), name=subnet_name,
-                        tenant_id=tenant_id)
+                    if self.network_resources:
+                        resp, resp_body = self.network_admin_client.\
+                            create_subnet(
+                                network_id, str(subnet_cidr),
+                                name=subnet_name,
+                                tenant_id=tenant_id,
+                                enable_dhcp=self.network_resources['dhcp'])
+                    else:
+                        resp, resp_body = self.network_admin_client.\
+                            create_subnet(network_id, str(subnet_cidr),
+                                          name=subnet_name,
+                                          tenant_id=tenant_id)
                 else:
                     body['subnet']['cidr'] = str(subnet_cidr)
                     resp_body = self.network_admin_client.create_subnet(body)
@@ -431,26 +461,27 @@
         net_client = self.network_admin_client
         for cred in self.isolated_net_resources:
             network, subnet, router = self.isolated_net_resources.get(cred)
-            try:
-                if self.tempest_client:
-                    net_client.remove_router_interface_with_subnet_id(
-                        router['id'], subnet['id'])
-                else:
-                    body = {'subnet_id': subnet['id']}
-                    net_client.remove_interface_router(router['id'], body)
-            except exceptions.NotFound:
-                LOG.warn('router with name: %s not found for delete' %
-                         router['name'])
-                pass
-            self._clear_isolated_router(router['id'], router['name'])
-            # TODO(mlavalle) This method call will be removed once patch
-            # https://review.openstack.org/#/c/46563/ merges in Neutron
-            self._cleanup_ports(network['id'])
-            self._clear_isolated_subnet(subnet['id'], subnet['name'])
-            self._clear_isolated_network(network['id'], network['name'])
-            LOG.info("Cleared isolated network resources: \n"
-                     + " network: %s, subnet: %s, router: %s"
-                     % (network['name'], subnet['name'], router['name']))
+            if self.network_resources.get('router'):
+                try:
+                    if self.tempest_client:
+                        net_client.remove_router_interface_with_subnet_id(
+                            router['id'], subnet['id'])
+                    else:
+                        body = {'subnet_id': subnet['id']}
+                        net_client.remove_interface_router(router['id'], body)
+                except exceptions.NotFound:
+                    LOG.warn('router with name: %s not found for delete' %
+                             router['name'])
+                    pass
+                self._clear_isolated_router(router['id'], router['name'])
+            if self.network_resources.get('network'):
+                # TODO(mlavalle) This method call will be removed once patch
+                # https://review.openstack.org/#/c/46563/ merges in Neutron
+                self._cleanup_ports(network['id'])
+            if self.network_resources.get('subnet'):
+                self._clear_isolated_subnet(subnet['id'], subnet['name'])
+            if self.network_resources.get('network'):
+                self._clear_isolated_network(network['id'], network['name'])
 
     def clear_isolated_creds(self):
         if not self.isolated_creds:
diff --git a/tempest/config.py b/tempest/config.py
index 0342380..3c7241a 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -78,7 +78,7 @@
                secret=True),
     cfg.StrOpt('admin_username',
                default='admin',
-               help="Administrative Username to use for"
+               help="Administrative Username to use for "
                     "Keystone API requests."),
     cfg.StrOpt('admin_tenant_name',
                default='admin',
@@ -90,6 +90,16 @@
                secret=True),
 ]
 
+identity_feature_group = cfg.OptGroup(name='identity-feature-enabled',
+                                      title='Enabled Identity Features')
+
+IdentityFeatureGroup = [
+    cfg.BoolOpt('trust',
+                default=True,
+                help='Does the identity service have delegation and '
+                     'impersonation enabled')
+]
+
 compute_group = cfg.OptGroup(name='compute',
                              title='Compute Service Options')
 
@@ -724,6 +734,8 @@
         register_opt_group(cfg.CONF, compute_features_group,
                            ComputeFeaturesGroup)
         register_opt_group(cfg.CONF, identity_group, IdentityGroup)
+        register_opt_group(cfg.CONF, identity_feature_group,
+                           IdentityFeatureGroup)
         register_opt_group(cfg.CONF, image_group, ImageGroup)
         register_opt_group(cfg.CONF, image_feature_group, ImageFeaturesGroup)
         register_opt_group(cfg.CONF, network_group, NetworkGroup)
@@ -752,6 +764,7 @@
         self.compute = cfg.CONF.compute
         self.compute_feature_enabled = cfg.CONF['compute-feature-enabled']
         self.identity = cfg.CONF.identity
+        self.identity_feature_enabled = cfg.CONF['identity-feature-enabled']
         self.images = cfg.CONF.image
         self.image_feature_enabled = cfg.CONF['image-feature-enabled']
         self.network = cfg.CONF.network
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 409fcc2..ecb55f9 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -235,7 +235,8 @@
     def setUpClass(cls):
         super(OfficialClientTest, cls).setUpClass()
         cls.isolated_creds = isolated_creds.IsolatedCreds(
-            __name__, tempest_client=False)
+            __name__, tempest_client=False,
+            network_resources=cls.network_resources)
 
         username, password, tenant_name = cls.credentials()
 
@@ -527,6 +528,13 @@
             private_key = self.keypair.private_key
         return RemoteClient(ip, username, pkey=private_key)
 
+    def _log_console_output(self, servers=None):
+        if not servers:
+            servers = self.compute_client.servers.list()
+        for server in servers:
+            LOG.debug('Console output for %s', server.id)
+            LOG.debug(server.get_console_output())
+
 
 class NetworkScenarioTest(OfficialClientTest):
     """
diff --git a/tempest/scenario/test_aggregates_basic_ops.py b/tempest/scenario/test_aggregates_basic_ops.py
new file mode 100644
index 0000000..3ae9567
--- /dev/null
+++ b/tempest/scenario/test_aggregates_basic_ops.py
@@ -0,0 +1,133 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 IBM Corp.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.common import tempest_fixtures as fixtures
+from tempest.common.utils.data_utils import rand_name
+from tempest.openstack.common import log as logging
+from tempest.scenario import manager
+from tempest import test
+
+
+LOG = logging.getLogger(__name__)
+
+
+class TestAggregatesBasicOps(manager.OfficialClientTest):
+    """
+    Creates an aggregate within an availability zone
+    Adds a host to the aggregate
+    Checks aggregate details
+    Updates aggregate's name
+    Removes host from aggregate
+    Deletes aggregate
+    """
+    @classmethod
+    def credentials(cls):
+        return cls.admin_credentials()
+
+    def _create_aggregate(self, aggregate_name, availability_zone=None):
+        aggregate = self.compute_client.aggregates.create(aggregate_name,
+                                                          availability_zone)
+        self.assertEqual(aggregate.name, aggregate_name)
+        self.assertEqual(aggregate.availability_zone, availability_zone)
+        self.set_resource(aggregate.id, aggregate)
+        LOG.debug("Aggregate %s created." % (aggregate.name))
+        return aggregate
+
+    def _delete_aggregate(self, aggregate):
+        self.compute_client.aggregates.delete(aggregate.id)
+        self.remove_resource(aggregate.id)
+        LOG.debug("Aggregate %s deleted. " % (aggregate.name))
+
+    def _get_host_name(self):
+        hosts = self.compute_client.hosts.list()
+        self.assertTrue(len(hosts) >= 1)
+        hostname = hosts[0].host_name
+        return hostname
+
+    def _add_host(self, aggregate_name, host):
+        aggregate = self.compute_client.aggregates.add_host(aggregate_name,
+                                                            host)
+        self.assertIn(host, aggregate.hosts)
+        LOG.debug("Host %s added to Aggregate %s." % (host, aggregate.name))
+
+    def _remove_host(self, aggregate_name, host):
+        aggregate = self.compute_client.aggregates.remove_host(aggregate_name,
+                                                               host)
+        self.assertNotIn(host, aggregate.hosts)
+        LOG.debug("Host %s removed to Aggregate %s." % (host, aggregate.name))
+
+    def _check_aggregate_details(self, aggregate, aggregate_name, azone,
+                                 hosts, metadata):
+        aggregate = self.compute_client.aggregates.get(aggregate.id)
+        self.assertEqual(aggregate_name, aggregate.name)
+        self.assertEqual(azone, aggregate.availability_zone)
+        self.assertEqual(aggregate.hosts, hosts)
+        for meta_key in metadata.keys():
+            self.assertIn(meta_key, aggregate.metadata)
+            self.assertEqual(metadata[meta_key], aggregate.metadata[meta_key])
+        LOG.debug("Aggregate %s details match." % aggregate.name)
+
+    def _set_aggregate_metadata(self, aggregate, meta):
+        aggregate = self.compute_client.aggregates.set_metadata(aggregate.id,
+                                                                meta)
+
+        for key, value in meta.items():
+            self.assertEqual(meta[key], aggregate.metadata[key])
+        LOG.debug("Aggregate %s metadata updated successfully." %
+                  aggregate.name)
+
+    def _update_aggregate(self, aggregate, aggregate_name,
+                          availability_zone):
+        values = {}
+        if aggregate_name:
+            values.update({'name': aggregate_name})
+        if availability_zone:
+            values.update({'availability_zone': availability_zone})
+        if values.keys():
+            aggregate = self.compute_client.aggregates.update(aggregate.id,
+                                                              values)
+            for key, values in values.items():
+                self.assertEqual(getattr(aggregate, key), values)
+        return aggregate
+
+    @test.services('compute')
+    def test_aggregate_basic_ops(self):
+        self.useFixture(fixtures.LockFixture('availability_zone'))
+        az = 'foo_zone'
+        aggregate_name = rand_name('aggregate-scenario')
+        aggregate = self._create_aggregate(aggregate_name, az)
+
+        metadata = {'meta_key': 'meta_value'}
+        self._set_aggregate_metadata(aggregate, metadata)
+
+        host = self._get_host_name()
+        self._add_host(aggregate, host)
+        self._check_aggregate_details(aggregate, aggregate_name, az, [host],
+                                      metadata)
+
+        aggregate_name = rand_name('renamed-aggregate-scenario')
+        aggregate = self._update_aggregate(aggregate, aggregate_name, None)
+
+        additional_metadata = {'foo': 'bar'}
+        self._set_aggregate_metadata(aggregate, additional_metadata)
+
+        metadata.update(additional_metadata)
+        self._check_aggregate_details(aggregate, aggregate.name, az, [host],
+                                      metadata)
+
+        self._remove_host(aggregate, host)
+        self._delete_aggregate(aggregate)
diff --git a/tempest/scenario/test_cross_tenant_connectivity.py b/tempest/scenario/test_cross_tenant_connectivity.py
index faba987..a269017 100644
--- a/tempest/scenario/test_cross_tenant_connectivity.py
+++ b/tempest/scenario/test_cross_tenant_connectivity.py
@@ -371,6 +371,7 @@
                             msg)
         except Exception:
             debug.log_ip_ns()
+            self._log_console_output(servers=self.servers)
             raise
 
     def _test_in_tenant_block(self, tenant):
diff --git a/tempest/scenario/test_dashboard_basic_ops.py b/tempest/scenario/test_dashboard_basic_ops.py
index 1081a3e..9e08bb6 100644
--- a/tempest/scenario/test_dashboard_basic_ops.py
+++ b/tempest/scenario/test_dashboard_basic_ops.py
@@ -34,6 +34,7 @@
 
     @classmethod
     def setUpClass(cls):
+        cls.set_network_resources()
         super(TestDashboardBasicOps, cls).setUpClass()
 
         if not cls.config.service_available.horizon:
diff --git a/tempest/scenario/test_large_ops.py b/tempest/scenario/test_large_ops.py
index 7f8d3e4..30468fa 100644
--- a/tempest/scenario/test_large_ops.py
+++ b/tempest/scenario/test_large_ops.py
@@ -36,6 +36,11 @@
 
     """
 
+    @classmethod
+    def setUpClass(cls):
+        cls.set_network_resources()
+        super(TestLargeOpsScenario, cls).setUpClass()
+
     def _wait_for_server_status(self, status):
         for server in self.servers:
             self.status_timeout(
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index 8a51cd1..890d00f 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -131,7 +131,12 @@
         self.server.add_floating_ip(self.floating_ip)
 
     def ssh_to_server(self):
-        self.linux_client = self.get_remote_client(self.floating_ip.ip)
+        try:
+            self.linux_client = self.get_remote_client(self.floating_ip.ip)
+        except Exception:
+            LOG.exception('ssh to server failed')
+            self._log_console_output()
+            raise
 
     def check_partitions(self):
         partitions = self.linux_client.get_partitions()
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 52a36e6..414aae6 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -19,11 +19,9 @@
 from tempest.common import debug
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest.openstack.common import jsonutils
 from tempest.openstack.common import log as logging
 from tempest.scenario import manager
 
-import tempest.test
 from tempest.test import attr
 from tempest.test import services
 
@@ -31,45 +29,6 @@
 LOG = logging.getLogger(__name__)
 
 
-class FloatingIPCheckTracker(object):
-    """
-    Checking VM connectivity through floating IP addresses is bound to fail
-    if the floating IP has not actually been associated with the VM yet.
-    This helper class facilitates checking for floating IP assignments on
-    VMs. It only checks for a given IP address once.
-    """
-
-    def __init__(self, compute_client, floating_ip_map):
-        self.compute_client = compute_client
-        self.unchecked = floating_ip_map.copy()
-
-    def run_checks(self):
-        """Check for any remaining unverified floating IPs
-
-        Gets VM details from nova and checks for floating IPs
-        within the returned information. Returns true when all
-        checks are complete and is suitable for use with
-        tempest.test.call_until_true()
-        """
-        to_delete = []
-        loggable_map = {}
-        for check_addr, server in self.unchecked.iteritems():
-            serverdata = self.compute_client.servers.get(server.id)
-            ip_addr = [addr for sublist in serverdata.networks.values() for
-                       addr in sublist]
-            if check_addr.floating_ip_address in ip_addr:
-                to_delete.append(check_addr)
-            else:
-                loggable_map[server.id] = check_addr
-
-        for to_del in to_delete:
-            del self.unchecked[to_del]
-
-        LOG.debug('Unchecked floating IPs: %s',
-                  jsonutils.dumps(loggable_map))
-        return len(self.unchecked) == 0
-
-
 class TestNetworkBasicOps(manager.NetworkScenarioTest):
 
     """
@@ -213,11 +172,6 @@
             name = data_utils.rand_name('server-smoke-%d-' % i)
             self._create_server(name, network)
 
-    def _log_console_output(self):
-        for server, key in self.servers.items():
-            LOG.debug('Console output for %s', server.id)
-            LOG.debug(server.get_console_output())
-
     def _check_tenant_network_connectivity(self):
         if not CONF.network.tenant_networks_reachable:
             msg = 'Tenant networks not configured to be reachable.'
@@ -234,21 +188,11 @@
                                                     key.private_key)
         except Exception:
             LOG.exception('Tenant connectivity check failed')
-            self._log_console_output()
+            self._log_console_output(
+                servers=[server for server, _key in self.servers])
             debug.log_ip_ns()
             raise
 
-    def _wait_for_floating_ip_association(self):
-        ip_tracker = FloatingIPCheckTracker(self.compute_client,
-                                            self.floating_ips)
-
-        self.assertTrue(
-            tempest.test.call_until_true(
-                ip_tracker.run_checks, CONF.compute.build_timeout,
-                CONF.compute.build_interval),
-            "Timed out while waiting for the floating IP assignments "
-            "to propagate")
-
     def _create_and_associate_floating_ips(self):
         public_network_id = CONF.network.public_network_id
         for server in self.servers.keys():
@@ -272,7 +216,8 @@
                                             should_connect=should_connect)
         except Exception:
             LOG.exception('Public network connectivity check failed')
-            self._log_console_output()
+            self._log_console_output(
+                servers=[server for server, _key in self.servers])
             debug.log_ip_ns()
             raise
 
@@ -298,11 +243,9 @@
         self._check_networks()
         self._create_servers()
         self._create_and_associate_floating_ips()
-        self._wait_for_floating_ip_association()
         self._check_tenant_network_connectivity()
         self._check_public_network_connectivity(should_connect=True)
         self._disassociate_floating_ips()
         self._check_public_network_connectivity(should_connect=False)
         self._reassociate_floating_ips()
-        self._wait_for_floating_ip_association()
         self._check_public_network_connectivity(should_connect=True)
diff --git a/tempest/scenario/test_network_quotas.py b/tempest/scenario/test_network_quotas.py
deleted file mode 100644
index cb7aa0b..0000000
--- a/tempest/scenario/test_network_quotas.py
+++ /dev/null
@@ -1,131 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 Hewlett-Packard Development Company, L.P.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-from neutronclient.common import exceptions as exc
-
-from tempest.scenario.manager import NetworkScenarioTest
-from tempest.test import services
-
-
-class TestNetworkQuotaBasic(NetworkScenarioTest):
-    """
-    This test suite contains tests that each loop trying to grab a
-    particular resource until a quota limit is hit.
-    For sanity, there is a maximum number of iterations - if this is hit
-    the test fails. Covers network, subnet, port.
-    """
-
-    @classmethod
-    def check_preconditions(cls):
-        super(TestNetworkQuotaBasic, cls).check_preconditions()
-
-    @classmethod
-    def setUpClass(cls):
-        super(TestNetworkQuotaBasic, cls).setUpClass()
-        cls.check_preconditions()
-        cls.networks = []
-        cls.subnets = []
-        cls.ports = []
-
-    @services('network')
-    def test_create_network_until_quota_hit(self):
-        hit_limit = False
-        networknum = self._get_tenant_own_network_num(self.tenant_id)
-        max = self._show_quota_network(self.tenant_id) - networknum
-        for n in xrange(max):
-            try:
-                self.networks.append(
-                    self._create_network(self.tenant_id,
-                                         namestart='network-quotatest-'))
-            except exc.NeutronClientException as e:
-                if (e.status_code != 409):
-                    raise
-                hit_limit = True
-                break
-        self.assertFalse(hit_limit, "Failed: Hit quota limit !")
-
-        try:
-            self.networks.append(
-                self._create_network(self.tenant_id,
-                                     namestart='network-quotatest-'))
-        except exc.NeutronClientException as e:
-            if (e.status_code != 409):
-                raise
-            hit_limit = True
-        self.assertTrue(hit_limit, "Failed: Did not hit quota limit !")
-
-    @services('network')
-    def test_create_subnet_until_quota_hit(self):
-        if not self.networks:
-            self.networks.append(
-                self._create_network(self.tenant_id,
-                                     namestart='network-quotatest-'))
-        hit_limit = False
-        subnetnum = self._get_tenant_own_subnet_num(self.tenant_id)
-        max = self._show_quota_subnet(self.tenant_id) - subnetnum
-        for n in xrange(max):
-            try:
-                self.subnets.append(
-                    self._create_subnet(self.networks[0],
-                                        namestart='subnet-quotatest-'))
-            except exc.NeutronClientException as e:
-                if (e.status_code != 409):
-                    raise
-                hit_limit = True
-                break
-        self.assertFalse(hit_limit, "Failed: Hit quota limit !")
-
-        try:
-            self.subnets.append(
-                self._create_subnet(self.networks[0],
-                                    namestart='subnet-quotatest-'))
-        except exc.NeutronClientException as e:
-            if (e.status_code != 409):
-                raise
-            hit_limit = True
-        self.assertTrue(hit_limit, "Failed: Did not hit quota limit !")
-
-    @services('network')
-    def test_create_ports_until_quota_hit(self):
-        if not self.networks:
-            self.networks.append(
-                self._create_network(self.tenant_id,
-                                     namestart='network-quotatest-'))
-        hit_limit = False
-        portnum = self._get_tenant_own_port_num(self.tenant_id)
-        max = self._show_quota_port(self.tenant_id) - portnum
-        for n in xrange(max):
-            try:
-                self.ports.append(
-                    self._create_port(self.networks[0],
-                                      namestart='port-quotatest-'))
-            except exc.NeutronClientException as e:
-                if (e.status_code != 409):
-                    raise
-                hit_limit = True
-                break
-        self.assertFalse(hit_limit, "Failed: Hit quota limit !")
-
-        try:
-            self.ports.append(
-                self._create_port(self.networks[0],
-                                  namestart='port-quotatest-'))
-        except exc.NeutronClientException as e:
-            if (e.status_code != 409):
-                raise
-            hit_limit = True
-        self.assertTrue(hit_limit, "Failed: Did not hit quota limit !")
diff --git a/tempest/scenario/test_server_advanced_ops.py b/tempest/scenario/test_server_advanced_ops.py
index 112c8a2..2c9446f 100644
--- a/tempest/scenario/test_server_advanced_ops.py
+++ b/tempest/scenario/test_server_advanced_ops.py
@@ -33,6 +33,7 @@
 
     @classmethod
     def setUpClass(cls):
+        cls.set_network_resources()
         super(TestServerAdvancedOps, cls).setUpClass()
 
         if not cls.config.compute_feature_enabled.resize:
diff --git a/tempest/scenario/test_server_basic_ops.py b/tempest/scenario/test_server_basic_ops.py
index ca3035d..279b80e 100644
--- a/tempest/scenario/test_server_basic_ops.py
+++ b/tempest/scenario/test_server_basic_ops.py
@@ -151,10 +151,15 @@
             instance = self.get_resource('instance')
             instance.add_floating_ip(floating_ip)
             # Check ssh
-            self.get_remote_client(
-                server_or_ip=floating_ip.ip,
-                username=self.image_utils.ssh_user(self.image_ref),
-                private_key=self.keypair.private)
+            try:
+                self.get_remote_client(
+                    server_or_ip=floating_ip.ip,
+                    username=self.image_utils.ssh_user(self.image_ref),
+                    private_key=self.keypair.private)
+            except Exception:
+                LOG.exception('ssh to server failed')
+                self._log_console_output()
+                raise
 
     @services('compute', 'network')
     def test_server_basicops(self):
diff --git a/tempest/scenario/test_snapshot_pattern.py b/tempest/scenario/test_snapshot_pattern.py
index 00139f0..874bc60 100644
--- a/tempest/scenario/test_snapshot_pattern.py
+++ b/tempest/scenario/test_snapshot_pattern.py
@@ -15,10 +15,14 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest.openstack.common import log
 from tempest.scenario import manager
 from tempest.test import services
 
 
+LOG = log.getLogger(__name__)
+
+
 class TestSnapshotPattern(manager.OfficialClientTest):
     """
     This test is for snapshotting an instance and booting with it.
@@ -40,7 +44,11 @@
         self.keypair = self.create_keypair()
 
     def _ssh_to_server(self, server_or_ip):
-        linux_client = self.get_remote_client(server_or_ip)
+        try:
+            linux_client = 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):
diff --git a/tempest/scenario/test_swift_basic_ops.py b/tempest/scenario/test_swift_basic_ops.py
index 6763503..4ef2aca 100644
--- a/tempest/scenario/test_swift_basic_ops.py
+++ b/tempest/scenario/test_swift_basic_ops.py
@@ -39,6 +39,7 @@
 
     @classmethod
     def setUpClass(cls):
+        cls.set_network_resources()
         super(TestSwiftBasicOps, cls).setUpClass()
         if not cls.config.service_available.swift:
             skip_msg = ("%s skipped as swift is not available" %
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index fa9a228..2a2b527 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -13,10 +13,14 @@
 #    under the License.
 
 from tempest.common.utils import data_utils
+from tempest.openstack.common import log
 from tempest.scenario import manager
 from tempest.test import services
 
 
+LOG = log.getLogger(__name__)
+
+
 class TestVolumeBootPattern(manager.OfficialClientTest):
 
     """
@@ -96,8 +100,14 @@
             network_name_for_ssh = self.config.compute.network_for_ssh
             ip = server.networks[network_name_for_ssh][0]
 
-        client = self.get_remote_client(ip,
-                                        private_key=keypair.private_key)
+        try:
+            client = 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):
diff --git a/tempest/services/compute/v3/json/flavors_client.py b/tempest/services/compute/v3/json/flavors_client.py
index e99ac91..a790c40 100644
--- a/tempest/services/compute/v3/json/flavors_client.py
+++ b/tempest/services/compute/v3/json/flavors_client.py
@@ -61,7 +61,7 @@
             'id': flavor_id,
         }
         if kwargs.get('ephemeral'):
-            post_body['OS-FLV-EXT-DATA:ephemeral'] = kwargs.get('ephemeral')
+            post_body['ephemeral'] = kwargs.get('ephemeral')
         if kwargs.get('swap'):
             post_body['swap'] = kwargs.get('swap')
         if kwargs.get('rxtx'):
diff --git a/tempest/services/compute/v3/json/instance_usage_audit_log_client.py b/tempest/services/compute/v3/json/instance_usage_audit_log_client.py
index 07ce1bb..bd73c13 100644
--- a/tempest/services/compute/v3/json/instance_usage_audit_log_client.py
+++ b/tempest/services/compute/v3/json/instance_usage_audit_log_client.py
@@ -20,21 +20,18 @@
 from tempest.common.rest_client import RestClient
 
 
-class InstanceUsagesAuditLogClientJSON(RestClient):
+class InstanceUsagesAuditLogV3ClientJSON(RestClient):
 
     def __init__(self, config, username, password, auth_url, tenant_name=None):
-        super(InstanceUsagesAuditLogClientJSON, self).__init__(
+        super(InstanceUsagesAuditLogV3ClientJSON, self).__init__(
             config, username, password, auth_url, tenant_name)
-        self.service = self.config.compute.catalog_type
+        self.service = self.config.compute.catalog_v3_type
 
-    def list_instance_usage_audit_logs(self):
-        url = 'os-instance_usage_audit_log'
-        resp, body = self.get(url)
-        body = json.loads(body)
-        return resp, body["instance_usage_audit_logs"]
-
-    def get_instance_usage_audit_log(self, time_before):
-        url = 'os-instance_usage_audit_log/%s' % time_before
+    def list_instance_usage_audit_logs(self, time_before=None):
+        if time_before:
+            url = 'os-instance-usage-audit-log?before=%s' % time_before
+        else:
+            url = 'os-instance-usage-audit-log'
         resp, body = self.get(url)
         body = json.loads(body)
         return resp, body["instance_usage_audit_log"]
diff --git a/tempest/services/compute/v3/json/limits_client.py b/tempest/services/compute/v3/json/limits_client.py
deleted file mode 100644
index 3e53e3e..0000000
--- a/tempest/services/compute/v3/json/limits_client.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import json
-from tempest.common.rest_client import RestClient
-
-
-class LimitsClientJSON(RestClient):
-
-    def __init__(self, config, username, password, auth_url, tenant_name=None):
-        super(LimitsClientJSON, self).__init__(config, username, password,
-                                               auth_url, tenant_name)
-        self.service = self.config.compute.catalog_type
-
-    def get_absolute_limits(self):
-        resp, body = self.get("limits")
-        body = json.loads(body)
-        return resp, body['limits']['absolute']
-
-    def get_specific_absolute_limit(self, absolute_limit):
-        resp, body = self.get("limits")
-        body = json.loads(body)
-        if absolute_limit not in body['limits']['absolute']:
-            return None
-        else:
-            return body['limits']['absolute'][absolute_limit]
diff --git a/tempest/services/compute/v3/json/servers_client.py b/tempest/services/compute/v3/json/servers_client.py
index 3e361a1..eba3be5 100644
--- a/tempest/services/compute/v3/json/servers_client.py
+++ b/tempest/services/compute/v3/json/servers_client.py
@@ -45,8 +45,6 @@
         admin_password: Sets the initial root password.
         key_name: Key name of keypair that was created earlier.
         meta: A dictionary of values to be used as metadata.
-        personality: A list of dictionaries for files to be injected into
-        the server.
         security_groups: A list of security group dicts.
         networks: A list of network dicts with UUID and fixed_ip.
         user_data: User data for instance.
@@ -64,7 +62,7 @@
             'flavor_ref': flavor_ref
         }
 
-        for option in ['personality', 'admin_password', 'key_name', 'networks',
+        for option in ['admin_password', 'key_name', 'networks',
                        ('os-security-groups:security_groups',
                         'security_groups'),
                        ('os-user-data:user_data', 'user_data'),
@@ -103,7 +101,6 @@
         Updates the properties of an existing server.
         server_id: The id of an existing server.
         name: The name of the server.
-        personality: A list of files to be injected into the server.
         access_ip_v4: The IPv4 access address for the server.
         access_ip_v6: The IPv6 access address for the server.
         """
diff --git a/tempest/services/compute/v3/xml/instance_usage_audit_log_client.py b/tempest/services/compute/v3/xml/instance_usage_audit_log_client.py
index 175997b..b8429b2 100644
--- a/tempest/services/compute/v3/xml/instance_usage_audit_log_client.py
+++ b/tempest/services/compute/v3/xml/instance_usage_audit_log_client.py
@@ -21,21 +21,18 @@
 from tempest.services.compute.xml.common import xml_to_json
 
 
-class InstanceUsagesAuditLogClientXML(RestClientXML):
+class InstanceUsagesAuditLogV3ClientXML(RestClientXML):
 
     def __init__(self, config, username, password, auth_url, tenant_name=None):
-        super(InstanceUsagesAuditLogClientXML, self).__init__(
+        super(InstanceUsagesAuditLogV3ClientXML, self).__init__(
             config, username, password, auth_url, tenant_name)
-        self.service = self.config.compute.catalog_type
+        self.service = self.config.compute.catalog_v3_type
 
-    def list_instance_usage_audit_logs(self):
-        url = 'os-instance_usage_audit_log'
+    def list_instance_usage_audit_logs(self, time_before=None):
+        if time_before:
+            url = 'os-instance-usage-audit-log?before=%s' % time_before
+        else:
+            url = 'os-instance-usage-audit-log'
         resp, body = self.get(url, self.headers)
         instance_usage_audit_logs = xml_to_json(etree.fromstring(body))
         return resp, instance_usage_audit_logs
-
-    def get_instance_usage_audit_log(self, time_before):
-        url = 'os-instance_usage_audit_log/%s' % time_before
-        resp, body = self.get(url, self.headers)
-        instance_usage_audit_log = xml_to_json(etree.fromstring(body))
-        return resp, instance_usage_audit_log
diff --git a/tempest/services/compute/v3/xml/limits_client.py b/tempest/services/compute/v3/xml/limits_client.py
deleted file mode 100644
index 704de52..0000000
--- a/tempest/services/compute/v3/xml/limits_client.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Copyright 2012 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 lxml import objectify
-
-from tempest.common.rest_client import RestClientXML
-
-NS = "{http://docs.openstack.org/common/api/v1.0}"
-
-
-class LimitsClientXML(RestClientXML):
-
-    def __init__(self, config, username, password, auth_url, tenant_name=None):
-        super(LimitsClientXML, self).__init__(config, username, password,
-                                              auth_url, tenant_name)
-        self.service = self.config.compute.catalog_type
-
-    def get_absolute_limits(self):
-        resp, body = self.get("limits", self.headers)
-        body = objectify.fromstring(body)
-        lim = NS + 'absolute'
-        ret = {}
-
-        for el in body[lim].iterchildren():
-            attributes = el.attrib
-            ret[attributes['name']] = attributes['value']
-        return resp, ret
-
-    def get_specific_absolute_limit(self, absolute_limit):
-        resp, body = self.get("limits", self.headers)
-        body = objectify.fromstring(body)
-        lim = NS + 'absolute'
-        ret = {}
-
-        for el in body[lim].iterchildren():
-            attributes = el.attrib
-            ret[attributes['name']] = attributes['value']
-        if absolute_limit not in ret:
-            return None
-        else:
-            return ret[absolute_limit]
diff --git a/tempest/services/compute/v3/xml/servers_client.py b/tempest/services/compute/v3/xml/servers_client.py
index 7405fc9..68831cd 100644
--- a/tempest/services/compute/v3/xml/servers_client.py
+++ b/tempest/services/compute/v3/xml/servers_client.py
@@ -304,8 +304,6 @@
         admin_password: Sets the initial root password.
         key_name: Key name of keypair that was created earlier.
         meta: A dictionary of values to be used as metadata.
-        personality: A list of dictionaries for files to be injected into
-        the server.
         security_groups: A list of security group dicts.
         networks: A list of network dicts with UUID and fixed_ip.
         user_data: User data for instance.
@@ -404,14 +402,6 @@
                 meta.append(Text(v))
                 metadata.append(meta)
 
-        if 'personality' in kwargs:
-            personality = Element('personality')
-            server.append(personality)
-            for k in kwargs['personality']:
-                temp = Element('file', path=k['path'])
-                temp.append(Text(k['contents']))
-                personality.append(temp)
-
         resp, body = self.post('servers', str(Document(server)), self.headers)
         server = self._parse_server(etree.fromstring(body))
         return resp, server
@@ -614,7 +604,7 @@
     def set_server_metadata_item(self, server_id, key, meta):
         doc = Document()
         for k, v in meta.items():
-            meta_element = Element("meta", key=k)
+            meta_element = Element("metadata", key=k)
             meta_element.append(Text(v))
             doc.append(meta_element)
         resp, body = self.put('servers/%s/metadata/%s' % (str(server_id), key),
diff --git a/tempest/test.py b/tempest/test.py
index d57ed83..931aa5d 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -230,6 +230,8 @@
 
     setUpClassCalled = False
 
+    network_resources = {}
+
     @classmethod
     def setUpClass(cls):
         if hasattr(super(BaseTestCase, cls), 'setUpClass'):
@@ -277,7 +279,8 @@
         """
         Returns an Openstack client manager
         """
-        cls.isolated_creds = isolated_creds.IsolatedCreds(cls.__name__)
+        cls.isolated_creds = isolated_creds.IsolatedCreds(
+            cls.__name__, network_resources=cls.network_resources)
 
         force_tenant_isolation = getattr(cls, 'force_tenant_isolation', None)
         if (cls.config.compute.allow_tenant_isolation or
@@ -319,6 +322,27 @@
             cls.config.identity.uri
         )
 
+    @classmethod
+    def set_network_resources(self, network=False, router=False, subnet=False,
+                              dhcp=False):
+        """Specify which network resources should be created
+
+        @param network
+        @param router
+        @param subnet
+        @param dhcp
+        """
+        # network resources should be set only once from callers
+        # in order to ensure that even if it's called multiple times in
+        # a chain of overloaded methods, the attribute is set only
+        # in the leaf class
+        if not self.network_resources:
+            self.network_resources = {
+                'network': network,
+                'router': router,
+                'subnet': subnet,
+                'dhcp': dhcp}
+
 
 def call_until_true(func, duration, sleep_for):
     """
diff --git a/test-requirements.txt b/test-requirements.txt
index 9486244..d7340f3 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -6,3 +6,4 @@
 oslo.sphinx
 mox>=0.5.3
 mock>=1.0
+coverage>=3.6
diff --git a/tox.ini b/tox.ini
index 6d596e3..88f2537 100644
--- a/tox.ini
+++ b/tox.ini
@@ -25,6 +25,10 @@
 setenv = OS_TEST_PATH=./tempest/tests
 commands = python setup.py test --slowest --testr-arg='tempest\.tests {posargs}'
 
+[testenv:cover]
+setenv = OS_TEST_PATH=./tempest/tests
+commands = python setup.py testr --coverage --testr-arg='tempest\.tests {posargs}'
+
 [testenv:all]
 setenv = VIRTUAL_ENV={envdir}
 commands =