Merge "The debug configuration group is not registered"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index ec14c7e..115a2b5 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -222,7 +222,7 @@
 tenant_network_cidr = 10.100.0.0/16
 
 # The mask bits used to partition the tenant block.
-tenant_network_mask_bits = 28
+tenant_network_mask_bits = 24
 
 # If tenant networks are reachable, connectivity checks will be
 # performed directly against addresses on those networks.
diff --git a/requirements.txt b/requirements.txt
index b15fb92..3b9ec44 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -17,7 +17,7 @@
 testresources>=0.2.4
 keyring>=1.6.1
 testrepository>=0.0.17
-oslo.config>=1.1.0
+oslo.config>=1.2.0
 eventlet>=0.13.0
 six<1.4.0
 iso8601>=0.1.4
diff --git a/tempest/api/compute/admin/test_servers.py b/tempest/api/compute/admin/test_servers.py
index cb47066..0abf779 100644
--- a/tempest/api/compute/admin/test_servers.py
+++ b/tempest/api/compute/admin/test_servers.py
@@ -15,7 +15,9 @@
 #    under the License.
 
 from tempest.api.compute import base
+from tempest.common.utils.data_utils import rand_int_id
 from tempest.common.utils.data_utils import rand_name
+from tempest import exceptions
 from tempest.test import attr
 
 
@@ -31,6 +33,12 @@
     def setUpClass(cls):
         super(ServersAdminTestJSON, cls).setUpClass()
         cls.client = cls.os_adm.servers_client
+        cls.flavors_client = cls.os_adm.flavors_client
+
+        cls.admin_client = cls._get_identity_admin_client()
+        tenant = cls.admin_client.get_tenant_by_name(
+            cls.client.tenant_name)
+        cls.tenant_id = tenant['id']
 
         cls.s1_name = rand_name('server')
         resp, server = cls.create_server(name=cls.s1_name,
@@ -39,6 +47,16 @@
         resp, server = cls.create_server(name=cls.s2_name,
                                          wait_until='ACTIVE')
 
+    def _get_unused_flavor_id(self):
+        flavor_id = rand_int_id(start=1000)
+        while True:
+            try:
+                resp, body = self.flavors_client.get_flavor_details(flavor_id)
+            except exceptions.NotFound:
+                break
+            flavor_id = rand_int_id(start=1000)
+        return flavor_id
+
     @attr(type='gate')
     def test_list_servers_by_admin(self):
         # Listing servers by admin user returns empty list by default
@@ -59,6 +77,42 @@
         self.assertIn(self.s1_name, servers_name)
         self.assertIn(self.s2_name, servers_name)
 
+    @attr(type=['negative', 'gate'])
+    def test_resize_server_using_overlimit_ram(self):
+        flavor_name = rand_name("flavor-")
+        flavor_id = self._get_unused_flavor_id()
+        resp, quota_set = self.quotas_client.get_default_quota_set(
+            self.tenant_id)
+        ram = int(quota_set['ram']) + 1
+        vcpus = 8
+        disk = 10
+        resp, flavor_ref = self.flavors_client.create_flavor(flavor_name,
+                                                             ram, vcpus, disk,
+                                                             flavor_id)
+        self.addCleanup(self.flavors_client.delete_flavor, flavor_id)
+        self.assertRaises(exceptions.OverLimit,
+                          self.client.resize,
+                          self.servers[0]['id'],
+                          flavor_ref['id'])
+
+    @attr(type=['negative', 'gate'])
+    def test_resize_server_using_overlimit_vcpus(self):
+        flavor_name = rand_name("flavor-")
+        flavor_id = self._get_unused_flavor_id()
+        ram = 512
+        resp, quota_set = self.quotas_client.get_default_quota_set(
+            self.tenant_id)
+        vcpus = int(quota_set['cores']) + 1
+        disk = 10
+        resp, flavor_ref = self.flavors_client.create_flavor(flavor_name,
+                                                             ram, vcpus, disk,
+                                                             flavor_id)
+        self.addCleanup(self.flavors_client.delete_flavor, flavor_id)
+        self.assertRaises(exceptions.OverLimit,
+                          self.client.resize,
+                          self.servers[0]['id'],
+                          flavor_ref['id'])
+
 
 class ServersAdminTestXML(ServersAdminTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index d2f437b..0b527d9 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -22,6 +22,7 @@
 from tempest.common import isolated_creds
 from tempest.common.utils.data_utils import parse_image_id
 from tempest.common.utils.data_utils import rand_name
+from tempest import exceptions
 from tempest.openstack.common import log as logging
 import tempest.test
 
@@ -103,6 +104,9 @@
         for image_id in cls.images:
             try:
                 cls.images_client.delete_image(image_id)
+            except exceptions.NotFound:
+                # The image may have already been deleted which is OK.
+                pass
             except Exception as exc:
                 LOG.info('Exception raised deleting image %s', image_id)
                 LOG.exception(exc)
diff --git a/tempest/api/compute/floating_ips/test_list_floating_ips.py b/tempest/api/compute/floating_ips/test_list_floating_ips.py
index 1c72eba..3c76069 100644
--- a/tempest/api/compute/floating_ips/test_list_floating_ips.py
+++ b/tempest/api/compute/floating_ips/test_list_floating_ips.py
@@ -93,6 +93,14 @@
         self.assertRaises(exceptions.NotFound,
                           self.client.get_floating_ip_details, non_exist_id)
 
+    @attr(type='gate')
+    def test_list_floating_ip_pools(self):
+        # Positive test:Should return the list of floating IP Pools
+        resp, floating_ip_pools = self.client.list_floating_ip_pools()
+        self.assertEqual(200, resp.status)
+        self.assertNotEqual(0, len(floating_ip_pools),
+                            "Expected floating IP Pools. Got zero.")
+
 
 class FloatingIPDetailsTestXML(FloatingIPDetailsTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 77f92c9..0d5a8fa 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -196,6 +196,18 @@
                 raise exceptions.TimeoutException(message)
 
     @attr(type=['negative', 'gate'])
+    def test_resize_server_using_nonexist_flavor(self):
+        flavor_id = -1
+        self.assertRaises(exceptions.BadRequest,
+                          self.client.resize, self.server_id, flavor_id)
+
+    @attr(type=['negative', 'gate'])
+    def test_resize_server_using_null_flavor(self):
+        flavor_id = ""
+        self.assertRaises(exceptions.BadRequest,
+                          self.client.resize, self.server_id, flavor_id)
+
+    @attr(type=['negative', 'gate'])
     def test_reboot_nonexistent_server_soft(self):
         # Negative Test: The server reboot on non existent server should return
         # an error
@@ -288,6 +300,26 @@
         self.assertEqual(202, resp.status)
         self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
 
+    @attr(type='gate')
+    def test_lock_unlock_server(self):
+        # Lock the server,try server stop(exceptions throw),unlock it and retry
+        resp, server = self.servers_client.lock_server(self.server_id)
+        self.assertEqual(202, resp.status)
+        resp, server = self.servers_client.get_server(self.server_id)
+        self.assertEqual(200, resp.status)
+        self.assertEqual(server['status'], 'ACTIVE')
+        # Locked server is not allowed to be stopped by non-admin user
+        self.assertRaises(exceptions.BadRequest,
+                          self.servers_client.stop, self.server_id)
+        resp, server = self.servers_client.unlock_server(self.server_id)
+        self.assertEqual(202, resp.status)
+        resp, server = self.servers_client.stop(self.server_id)
+        self.assertEqual(202, resp.status)
+        self.servers_client.wait_for_server_status(self.server_id, 'SHUTOFF')
+        resp, server = self.servers_client.start(self.server_id)
+        self.assertEqual(202, resp.status)
+        self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
+
 
 class ServerActionsTestXML(ServerActionsTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/image/v1/test_image_members.py b/tempest/api/image/v1/test_image_members.py
index fcbde50..e9c395e 100644
--- a/tempest/api/image/v1/test_image_members.py
+++ b/tempest/api/image/v1/test_image_members.py
@@ -18,6 +18,8 @@
 
 from tempest.api.image import base
 from tempest import clients
+from tempest.common.utils.data_utils import rand_name
+from tempest import exceptions
 from tempest.test import attr
 
 
@@ -83,3 +85,25 @@
         self.assertEqual(200, resp.status)
         members = body['members']
         self.assertEqual(0, len(members))
+
+    @attr(type=['negative', 'gate'])
+    def test_add_member_with_non_existing_image(self):
+        # Add member with non existing image.
+        non_exist_image = rand_name('image_')
+        self.assertRaises(exceptions.NotFound, self.client.add_member,
+                          self.tenants[0], non_exist_image)
+
+    @attr(type=['negative', 'gate'])
+    def test_delete_member_with_non_existing_image(self):
+        # Delete member with non existing image.
+        non_exist_image = rand_name('image_')
+        self.assertRaises(exceptions.NotFound, self.client.delete_member,
+                          self.tenants[0], non_exist_image)
+
+    @attr(type=['negative', 'gate'])
+    def test_delete_member_with_non_existing_tenant(self):
+        # Delete member with non existing tenant.
+        image_id = self._create_image()
+        non_exist_tenant = rand_name('tenant_')
+        self.assertRaises(exceptions.NotFound, self.client.delete_member,
+                          non_exist_tenant, image_id)
diff --git a/tempest/api/object_storage/test_object_services.py b/tempest/api/object_storage/test_object_services.py
index 7c10138..407c3ec 100644
--- a/tempest/api/object_storage/test_object_services.py
+++ b/tempest/api/object_storage/test_object_services.py
@@ -16,7 +16,6 @@
 #    under the License.
 
 import hashlib
-import time
 
 from tempest.api.object_storage import base
 from tempest.common.utils.data_utils import arbitrary_string
@@ -225,44 +224,6 @@
         self.assertEqual(resp[actual_meta_key], meta_value)
 
     @attr(type='gate')
-    def test_get_object_using_temp_url(self):
-        # access object using temporary URL within expiration time
-
-        try:
-            # update account metadata
-            # flag to check if account metadata got updated
-            flag = False
-            key = 'Meta'
-            metadata = {'Temp-URL-Key': key}
-            resp, _ = self.account_client.create_account_metadata(
-                metadata=metadata)
-            self.assertIn(int(resp['status']), HTTP_SUCCESS)
-            flag = True
-            resp, _ = self.account_client.list_account_metadata()
-            self.assertIn('x-account-meta-temp-url-key', resp)
-            self.assertEqual(resp['x-account-meta-temp-url-key'], key)
-
-            # create object
-            object_name = rand_name(name='ObjectTemp')
-            data = arbitrary_string(size=len(object_name),
-                                    base_text=object_name)
-            self.object_client.create_object(self.container_name,
-                                             object_name, data)
-            expires = int(time.time() + 10)
-
-            # trying to get object using temp url with in expiry time
-            _, body = self.object_client.get_object_using_temp_url(
-                self.container_name, object_name,
-                expires, key)
-            self.assertEqual(body, data)
-        finally:
-            if flag:
-                resp, _ = self.account_client.delete_account_metadata(
-                    metadata=metadata)
-                resp, _ = self.account_client.list_account_metadata()
-                self.assertNotIn('x-account-meta-temp-url-key', resp)
-
-    @attr(type='gate')
     def test_object_upload_in_segments(self):
         # create object
         object_name = rand_name(name='LObject')
diff --git a/tempest/api/object_storage/test_object_temp_url.py b/tempest/api/object_storage/test_object_temp_url.py
new file mode 100644
index 0000000..0fd5499
--- /dev/null
+++ b/tempest/api/object_storage/test_object_temp_url.py
@@ -0,0 +1,157 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
+#
+# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import hashlib
+import hmac
+import time
+import urlparse
+
+from tempest.api.object_storage import base
+from tempest.common.utils.data_utils import arbitrary_string
+from tempest.common.utils.data_utils import rand_name
+from tempest import exceptions
+from tempest.test import attr
+from tempest.test import HTTP_SUCCESS
+
+
+class ObjectTempUrlTest(base.BaseObjectTest):
+
+    @classmethod
+    def setUpClass(cls):
+        super(ObjectTempUrlTest, cls).setUpClass()
+        cls.container_name = rand_name(name='TestContainer')
+        cls.container_client.create_container(cls.container_name)
+        cls.containers = [cls.container_name]
+
+        # update account metadata
+        cls.key = 'Meta'
+        cls.metadata = {'Temp-URL-Key': cls.key}
+        cls.account_client.create_account_metadata(metadata=cls.metadata)
+        cls.account_client_metadata, _ = \
+            cls.account_client.list_account_metadata()
+
+    @classmethod
+    def tearDownClass(cls):
+        resp, _ = cls.account_client.delete_account_metadata(
+            metadata=cls.metadata)
+        resp, _ = cls.account_client.list_account_metadata()
+
+        cls.delete_containers(cls.containers)
+        # delete the user setup created
+        cls.data.teardown_all()
+        super(ObjectTempUrlTest, cls).tearDownClass()
+
+    def setUp(self):
+        super(ObjectTempUrlTest, self).setUp()
+        # make sure the metadata has been set
+        self.assertIn('x-account-meta-temp-url-key',
+                      self.account_client_metadata)
+
+        self.assertEqual(
+            self.account_client_metadata['x-account-meta-temp-url-key'],
+            self.key)
+
+        # create object
+        self.object_name = rand_name(name='ObjectTemp')
+        self.data = arbitrary_string(size=len(self.object_name),
+                                     base_text=self.object_name)
+        self.object_client.create_object(self.container_name,
+                                         self.object_name, self.data)
+
+    def get_temp_url(self, container, object_name, method, expires,
+                     key):
+        """Create the temporary URL."""
+
+        path = "%s/%s/%s" % (
+            urlparse.urlparse(self.object_client.base_url).path,
+            container, object_name)
+
+        hmac_body = '%s\n%s\n%s' % (method, expires, path)
+        sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest()
+
+        url = "%s/%s?temp_url_sig=%s&temp_url_expires=%s" % (container,
+                                                             object_name,
+                                                             sig, expires)
+
+        return url
+
+    @attr(type='gate')
+    def test_get_object_using_temp_url(self):
+        EXPIRATION_TIME = 10000  # high to ensure the test finishes.
+        expires = int(time.time() + EXPIRATION_TIME)
+
+        # get a temp URL for the created object
+        url = self.get_temp_url(self.container_name,
+                                self.object_name, "GET",
+                                expires, self.key)
+
+        # trying to get object using temp url within expiry time
+        _, body = self.object_client.get_object_using_temp_url(url)
+
+        self.assertEqual(body, self.data)
+
+        # Testing a HEAD on this Temp URL
+        resp, body = self.object_client.head(url)
+        self.assertIn(int(resp['status']), HTTP_SUCCESS)
+
+    @attr(type='gate')
+    def test_put_object_using_temp_url(self):
+        # make sure the metadata has been set
+        new_data = arbitrary_string(size=len(self.object_name),
+                                    base_text=rand_name(name="random"))
+
+        EXPIRATION_TIME = 10000  # high to ensure the test finishes.
+        expires = int(time.time() + EXPIRATION_TIME)
+
+        url = self.get_temp_url(self.container_name,
+                                self.object_name, "PUT",
+                                expires, self.key)
+
+        # trying to put random data in the object using temp url
+        resp, body = self.object_client.put_object_using_temp_url(
+            url, new_data)
+
+        self.assertIn(int(resp['status']), HTTP_SUCCESS)
+
+        # Testing a HEAD on this Temp URL
+        resp, body = self.object_client.head(url)
+        self.assertIn(int(resp['status']), HTTP_SUCCESS)
+
+        # Validate that the content of the object has been modified
+        url = self.get_temp_url(self.container_name,
+                                self.object_name, "GET",
+                                expires, self.key)
+
+        _, body = self.object_client.get_object_using_temp_url(url)
+        self.assertEqual(body, new_data)
+
+    @attr(type=['gate', 'negative'])
+    def test_get_object_after_expiration_time(self):
+        EXPIRATION_TIME = 1
+        expires = int(time.time() + EXPIRATION_TIME)
+
+        # get a temp URL for the created object
+        url = self.get_temp_url(self.container_name,
+                                self.object_name, "GET",
+                                expires, self.key)
+
+        # temp URL is valid for 1 seconds, let's wait 3
+        time.sleep(EXPIRATION_TIME + 2)
+
+        self.assertRaises(exceptions.Unauthorized,
+                          self.object_client.get_object_using_temp_url,
+                          url)
diff --git a/tempest/api/volume/test_volumes_get.py b/tempest/api/volume/test_volumes_get.py
index 119e3e0..f2915f7 100644
--- a/tempest/api/volume/test_volumes_get.py
+++ b/tempest/api/volume/test_volumes_get.py
@@ -34,6 +34,15 @@
         self.assertEqual(202, resp.status)
         self.client.wait_for_resource_deletion(volume_id)
 
+    def _is_true(self, val):
+        # NOTE(jdg): Temporary conversion method to get cinder patch
+        # merged.  Then we'll make this strict again and
+        #specifically check "true" or "false"
+        if val in ['true', 'True', True]:
+            return True
+        else:
+            return False
+
     def _volume_create_get_update_delete(self, **kwargs):
         # Create a volume, Get it's details and Delete the volume
         volume = {}
@@ -69,10 +78,14 @@
                          fetched_volume['metadata'],
                          'The fetched Volume is different '
                          'from the created Volume')
+
+        # NOTE(jdg): Revert back to strict true/false checking
+        # after fix for bug #1227837 merges
+        boot_flag = self._is_true(fetched_volume['bootable'])
         if 'imageRef' in kwargs:
-            self.assertEqual(fetched_volume['bootable'], True)
+            self.assertEqual(boot_flag, True)
         if 'imageRef' not in kwargs:
-            self.assertEqual(fetched_volume['bootable'], False)
+            self.assertEqual(boot_flag, False)
 
         # Update Volume
         new_v_name = rand_name('new-Volume')
@@ -92,10 +105,14 @@
         self.assertEqual(new_v_name, updated_volume['display_name'])
         self.assertEqual(new_desc, updated_volume['display_description'])
         self.assertEqual(metadata, updated_volume['metadata'])
+
+        # NOTE(jdg): Revert back to strict true/false checking
+        # after fix for bug #1227837 merges
+        boot_flag = self._is_true(updated_volume['bootable'])
         if 'imageRef' in kwargs:
-            self.assertEqual(updated_volume['bootable'], True)
+            self.assertEqual(boot_flag, True)
         if 'imageRef' not in kwargs:
-            self.assertEqual(updated_volume['bootable'], False)
+            self.assertEqual(boot_flag, False)
 
     @attr(type='gate')
     def test_volume_get_metadata_none(self):
diff --git a/tempest/common/isolated_creds.py b/tempest/common/isolated_creds.py
index d6b4466..93dec71 100644
--- a/tempest/common/isolated_creds.py
+++ b/tempest/common/isolated_creds.py
@@ -14,7 +14,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import keystoneclient.v2_0.client
+import netaddr
+
+import keystoneclient.v2_0.client as keystoneclient
+import neutronclient.v2_0.client as neutronclient
 
 from tempest import clients
 from tempest.common.utils.data_utils import rand_name
@@ -30,50 +33,64 @@
     def __init__(self, name, tempest_client=True, interface='json',
                  password='pass'):
         self.isolated_creds = {}
+        self.isolated_net_resources = {}
+        self.ports = []
         self.name = name
         self.config = config.TempestConfig()
         self.tempest_client = tempest_client
         self.interface = interface
         self.password = password
-        self.admin_client = self._get_identity_admin_client()
+        self.identity_admin_client, self.network_admin_client = (
+            self._get_admin_clients())
 
-    def _get_keystone_client(self):
+    def _get_official_admin_clients(self):
         username = self.config.identity.admin_username
         password = self.config.identity.admin_password
         tenant_name = self.config.identity.admin_tenant_name
         auth_url = self.config.identity.uri
         dscv = self.config.identity.disable_ssl_certificate_validation
-        return keystoneclient.v2_0.client.Client(username=username,
-                                                 password=password,
-                                                 tenant_name=tenant_name,
-                                                 auth_url=auth_url,
-                                                 insecure=dscv)
+        identity_client = keystoneclient.Client(username=username,
+                                                password=password,
+                                                tenant_name=tenant_name,
+                                                auth_url=auth_url,
+                                                insecure=dscv)
+        network_client = neutronclient.Client(username=username,
+                                              password=password,
+                                              tenant_name=tenant_name,
+                                              auth_url=auth_url,
+                                              insecure=dscv)
+        return identity_client, network_client
 
-    def _get_identity_admin_client(self):
+    def _get_admin_clients(self):
         """
-        Returns an instance of the Identity Admin API client
+        Returns a tuple with instances of the following admin clients (in this
+        order):
+            identity
+            network
         """
         if self.tempest_client:
             os = clients.AdminManager(interface=self.interface)
-            admin_client = os.identity_client
+            admin_clients = (os.identity_client,
+                             os.network_client,)
         else:
-            admin_client = self._get_keystone_client()
-        return admin_client
+            admin_clients = self._get_official_admin_clients()
+        return admin_clients
 
     def _create_tenant(self, name, description):
         if self.tempest_client:
-            resp, tenant = self.admin_client.create_tenant(
+            resp, tenant = self.identity_admin_client.create_tenant(
                 name=name, description=description)
         else:
-            tenant = self.admin_client.tenants.create(name,
-                                                      description=description)
+            tenant = self.identity_admin_client.tenants.create(
+                name,
+                description=description)
         return tenant
 
     def _get_tenant_by_name(self, name):
         if self.tempest_client:
-            resp, tenant = self.admin_client.get_tenant_by_name(name)
+            resp, tenant = self.identity_admin_client.get_tenant_by_name(name)
         else:
-            tenants = self.admin_client.tenants.list()
+            tenants = self.identity_admin_client.tenants.list()
             for ten in tenants:
                 if ten['name'] == name:
                     tenant = ten
@@ -82,45 +99,50 @@
 
     def _create_user(self, username, password, tenant, email):
         if self.tempest_client:
-            resp, user = self.admin_client.create_user(username, password,
-                                                       tenant['id'], email)
+            resp, user = self.identity_admin_client.create_user(username,
+                                                                password,
+                                                                tenant['id'],
+                                                                email)
         else:
-            user = self.admin_client.users.create(username, password, email,
-                                                  tenant_id=tenant.id)
+            user = self.identity_admin_client.users.create(username, password,
+                                                           email,
+                                                           tenant_id=tenant.id)
         return user
 
     def _get_user(self, tenant, username):
         if self.tempest_client:
-            resp, user = self.admin_client.get_user_by_username(tenant['id'],
-                                                                username)
+            resp, user = self.identity_admin_client.get_user_by_username(
+                tenant['id'],
+                username)
         else:
-            user = self.admin_client.users.get(username)
+            user = self.identity_admin_client.users.get(username)
         return user
 
     def _list_roles(self):
         if self.tempest_client:
-            resp, roles = self.admin_client.list_roles()
+            resp, roles = self.identity_admin_client.list_roles()
         else:
-            roles = self.admin_client.roles.list()
+            roles = self.identity_admin_client.roles.list()
         return roles
 
     def _assign_user_role(self, tenant, user, role):
         if self.tempest_client:
-            self.admin_client.assign_user_role(tenant, user, role)
+            self.identity_admin_client.assign_user_role(tenant, user, role)
         else:
-            self.admin_client.roles.add_user_role(user, role, tenant=tenant)
+            self.identity_admin_client.roles.add_user_role(user,
+                                                           role, tenant=tenant)
 
     def _delete_user(self, user):
         if self.tempest_client:
-            self.admin_client.delete_user(user)
+            self.identity_admin_client.delete_user(user)
         else:
-            self.admin_client.users.delete(user)
+            self.identity_admin_client.users.delete(user)
 
     def _delete_tenant(self, tenant):
         if self.tempest_client:
-            self.admin_client.delete_tenant(tenant)
+            self.identity_admin_client.delete_tenant(tenant)
         else:
-            self.admin_client.tenants.delete(tenant)
+            self.identity_admin_client.tenants.delete(tenant)
 
     def _create_creds(self, suffix=None, admin=False):
         rand_name_root = rand_name(self.name)
@@ -128,7 +150,6 @@
             rand_name_root += suffix
         tenant_name = rand_name_root + "-tenant"
         tenant_desc = tenant_name + "-desc"
-        rand_name_root = rand_name(self.name)
         tenant = self._create_tenant(name=tenant_name,
                                      description=tenant_desc)
         if suffix:
@@ -164,6 +185,92 @@
             tenant_name = tenant.name
         return username, tenant_name
 
+    def _get_tenant_id(self, tenant):
+        if self.tempest_client:
+            return tenant.get('id')
+        else:
+            return tenant.id
+
+    def _create_network_resources(self, tenant_id):
+        network = None
+        subnet = None
+        router = None
+        rand_name_root = rand_name(self.name)
+        network_name = rand_name_root + "-network"
+        network = self._create_network(network_name, tenant_id)
+        try:
+            subnet_name = rand_name_root + "-subnet"
+            subnet = self._create_subnet(subnet_name, tenant_id, network['id'])
+            router_name = 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'])
+            if subnet:
+                self._clear_isolated_subnet(subnet['id'], subnet['name'])
+            if network:
+                self._clear_isolated_network(network['id'], network['name'])
+            raise
+        return network, subnet, router
+
+    def _create_network(self, name, tenant_id):
+        if self.tempest_client:
+            resp, resp_body = self.network_admin_client.create_network(
+                name, tenant_id=tenant_id)
+        else:
+            body = {'network': {'tenant_id': tenant_id, 'name': name}}
+            resp_body = self.network_admin_client.create_network(body)
+        return resp_body['network']
+
+    def _create_subnet(self, subnet_name, tenant_id, network_id):
+        if not self.tempest_client:
+            body = {'subnet': {'name': subnet_name, 'tenant_id': tenant_id,
+                               'network_id': network_id, 'ip_version': 4}}
+        base_cidr = netaddr.IPNetwork(self.config.network.tenant_network_cidr)
+        mask_bits = self.config.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)
+                else:
+                    body['subnet']['cidr'] = str(subnet_cidr)
+                    resp_body = self.network_admin_client.create_subnet(body)
+                break
+            except exceptions.BadRequest as e:
+                if 'overlaps with another subnet' not in str(e):
+                    raise
+        else:
+            e = exceptions.BuildErrorException()
+            e.message = 'Available CIDR for subnet creation could not be found'
+            raise e
+        return resp_body['subnet']
+
+    def _create_router(self, router_name, tenant_id):
+        external_net_id = dict(
+            network_id=self.config.network.public_network_id)
+        if self.tempest_client:
+            resp, resp_body = self.network_admin_client.create_router(
+                router_name,
+                external_gateway_info=external_net_id,
+                tenant_id=tenant_id)
+        else:
+            body = {'router': {'name': router_name, 'tenant_id': tenant_id,
+                               'external_gateway_info': external_net_id,
+                               'admin_state_up': True}}
+            resp_body = self.network_admin_client.create_router(body)
+        return resp_body['router']
+
+    def _add_router_interface(self, router_id, subnet_id):
+        if self.tempest_client:
+            self.network_admin_client.add_router_interface_with_subnet_id(
+                router_id, subnet_id)
+        else:
+            body = {'subnet_id': subnet_id}
+            self.network_admin_client.add_interface_router(router_id, body)
+
     def get_primary_tenant(self):
         return self.isolated_creds.get('primary')[1]
 
@@ -182,6 +289,33 @@
     def get_admin_user(self):
         return self.isolated_creds.get('admin')[0]
 
+    def get_primary_network(self):
+        return self.isolated_net_resources.get('primary')[0]
+
+    def get_primary_subnet(self):
+        return self.isolated_net_resources.get('primary')[1]
+
+    def get_primary_router(self):
+        return self.isolated_net_resources.get('primary')[2]
+
+    def get_admin_network(self):
+        return self.isolated_net_resources.get('admin')[0]
+
+    def get_admin_subnet(self):
+        return self.isolated_net_resources.get('admin')[1]
+
+    def get_admin_router(self):
+        return self.isolated_net_resources.get('admin')[2]
+
+    def get_alt_network(self):
+        return self.isolated_net_resources.get('alt')[0]
+
+    def get_alt_subnet(self):
+        return self.isolated_net_resources.get('alt')[1]
+
+    def get_alt_router(self):
+        return self.isolated_net_resources.get('alt')[2]
+
     def get_primary_creds(self):
         if self.isolated_creds.get('primary'):
             user, tenant = self.isolated_creds['primary']
@@ -190,8 +324,15 @@
             user, tenant = self._create_creds()
             username, tenant_name = self._get_cred_names(user, tenant)
             self.isolated_creds['primary'] = (user, tenant)
-            LOG.info("Aquired isolated creds:\n user: %s, tenant: %s"
+            LOG.info("Acquired isolated creds:\n user: %s, tenant: %s"
                      % (username, tenant_name))
+            if self.config.service_available.neutron:
+                network, subnet, router = self._create_network_resources(
+                    self._get_tenant_id(tenant))
+                self.isolated_net_resources['primary'] = (
+                    network, subnet, router,)
+                LOG.info("Created isolated network resources for : \n"
+                         + " user: %s, tenant: %s" % (username, tenant_name))
         return username, tenant_name, self.password
 
     def get_admin_creds(self):
@@ -202,9 +343,16 @@
             user, tenant = self._create_creds(admin=True)
             username, tenant_name = self._get_cred_names(user, tenant)
             self.isolated_creds['admin'] = (user, tenant)
-            LOG.info("Aquired admin isolated creds:\n user: %s, tenant: %s"
+            LOG.info("Acquired admin isolated creds:\n user: %s, tenant: %s"
                      % (username, tenant_name))
-            return username, tenant_name, self.password
+            if self.config.service_available.neutron:
+                network, subnet, router = self._create_network_resources(
+                    self._get_tenant_id(tenant))
+                self.isolated_net_resources['admin'] = (
+                    network, subnet, router,)
+                LOG.info("Created isolated network resources for : \n"
+                         + " user: %s, tenant: %s" % (username, tenant_name))
+        return username, tenant_name, self.password
 
     def get_alt_creds(self):
         if self.isolated_creds.get('alt'):
@@ -214,13 +362,93 @@
             user, tenant = self._create_creds()
             username, tenant_name = self._get_cred_names(user, tenant)
             self.isolated_creds['alt'] = (user, tenant)
-            LOG.info("Aquired alt isolated creds:\n user: %s, tenant: %s"
+            LOG.info("Acquired alt isolated creds:\n user: %s, tenant: %s"
                      % (username, tenant_name))
+            if self.config.service_available.neutron:
+                network, subnet, router = self._create_network_resources(
+                    self._get_tenant_id(tenant))
+                self.isolated_net_resources['alt'] = (
+                    network, subnet, router,)
+                LOG.info("Created isolated network resources for : \n"
+                         + " user: %s, tenant: %s" % (username, tenant_name))
         return username, tenant_name, self.password
 
+    def _clear_isolated_router(self, router_id, router_name):
+        net_client = self.network_admin_client
+        try:
+            net_client.delete_router(router_id)
+        except exceptions.NotFound:
+            LOG.warn('router with name: %s not found for delete' %
+                     router_name)
+            pass
+
+    def _clear_isolated_subnet(self, subnet_id, subnet_name):
+        net_client = self.network_admin_client
+        try:
+            net_client.delete_subnet(subnet_id)
+        except exceptions.NotFound:
+            LOG.warn('subnet with name: %s not found for delete' %
+                     subnet_name)
+            pass
+
+    def _clear_isolated_network(self, network_id, network_name):
+        net_client = self.network_admin_client
+        try:
+            net_client.delete_network(network_id)
+        except exceptions.NotFound:
+            LOG.warn('network with name: %s not found for delete' %
+                     network_name)
+            pass
+
+    def _cleanup_ports(self, network_id):
+        # TODO(mlavalle) This method will be removed once patch
+        # https://review.openstack.org/#/c/46563/ merges in Neutron
+        if not self.ports:
+            if self.tempest_client:
+                resp, resp_body = self.network_admin_client.list_ports()
+            else:
+                resp_body = self.network_admin_client.list_ports()
+            self.ports = resp_body['ports']
+        ports_to_delete = [
+            port for port in self.ports if port['network_id'] == network_id]
+        for port in ports_to_delete:
+            try:
+                LOG.info('Cleaning up port id %s, name %s' %
+                         (port['id'], port['name']))
+                self.network_admin_client.delete_port(port['id'])
+            except exceptions.NotFound:
+                LOG.warn('Port id: %s, name %s not found for clean-up' %
+                         (port['id'], port['name']))
+
+    def _clear_isolated_net_resources(self):
+        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']))
+
     def clear_isolated_creds(self):
         if not self.isolated_creds:
             return
+        self._clear_isolated_net_resources()
         for cred in self.isolated_creds:
             user, tenant = self.isolated_creds.get(cred)
             try:
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index a867a12..4b5127a 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -80,6 +80,21 @@
         self.http_obj = http.ClosingHttp(
             disable_ssl_certificate_validation=dscv)
 
+    def __str__(self):
+        STRING_LIMIT = 80
+        str_format = ("config:%s, user:%s, password:%s, "
+                      "auth_url:%s, tenant_name:%s, auth_version:%s, "
+                      "service:%s, base_url:%s, region:%s, "
+                      "endpoint_url:%s, build_interval:%s, build_timeout:%s"
+                      "\ntoken:%s..., \nheaders:%s...")
+        return str_format % (self.config, self.user, self.password,
+                             self.auth_url, self.tenant_name,
+                             self.auth_version, self.service,
+                             self.base_url, self.region, self.endpoint_url,
+                             self.build_interval, self.build_timeout,
+                             str(self.token)[0:STRING_LIMIT],
+                             str(self.headers)[0:STRING_LIMIT])
+
     def _set_auth(self):
         """
         Sets the token and base_url used in requests based on the strategy type
@@ -448,8 +463,8 @@
         # NOTE(mtreinish): This is for compatibility with Glance and swift
         # APIs. These are the return content types that Glance api v1
         # (and occasionally swift) are using.
-        TXT_ENC = ['text/plain; charset=UTF-8', 'text/html; charset=UTF-8',
-                   'text/plain; charset=utf-8']
+        TXT_ENC = ['text/plain', 'text/plain; charset=UTF-8',
+                   'text/html; charset=UTF-8', 'text/plain; charset=utf-8']
         XML_ENC = ['application/xml', 'application/xml; charset=UTF-8']
 
         if ctype in JSON_ENC or ctype in XML_ENC:
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 44788f2..c01de83 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -478,10 +478,13 @@
     @classmethod
     def setUpClass(cls):
         super(NetworkScenarioTest, cls).setUpClass()
-        cls.tenant_id = cls.manager._get_identity_client(
-            cls.config.identity.username,
-            cls.config.identity.password,
-            cls.config.identity.tenant_name).tenant_id
+        if cls.config.compute.allow_tenant_isolation:
+            cls.tenant_id = cls.isolated_creds.get_primary_tenant().id
+        else:
+            cls.tenant_id = cls.manager._get_identity_client(
+                cls.config.identity.username,
+                cls.config.identity.password,
+                cls.config.identity.tenant_name).tenant_id
 
     def _create_security_group(self, client=None, namestart='secgroup-smoke-'):
         if client is None:
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 7f7ba91..6cd9fe8 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -110,10 +110,6 @@
     def setUpClass(cls):
         super(TestNetworkBasicOps, cls).setUpClass()
         cls.check_preconditions()
-        cls.tenant_id = cls.manager._get_identity_client(
-            cls.config.identity.username,
-            cls.config.identity.password,
-            cls.config.identity.tenant_name).tenant_id
         # TODO(mnewby) Consider looking up entities as needed instead
         # of storing them as collections on the class.
         cls.keypairs = {}
diff --git a/tempest/services/compute/json/floating_ips_client.py b/tempest/services/compute/json/floating_ips_client.py
index 769c538..8349263 100644
--- a/tempest/services/compute/json/floating_ips_client.py
+++ b/tempest/services/compute/json/floating_ips_client.py
@@ -94,3 +94,13 @@
         except exceptions.NotFound:
             return True
         return False
+
+    def list_floating_ip_pools(self, params=None):
+        """Returns a list of all floating IP Pools."""
+        url = 'os-floating-ip-pools'
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+
+        resp, body = self.get(url)
+        body = json.loads(body)
+        return resp, body['floating_ip_pools']
diff --git a/tempest/services/compute/xml/floating_ips_client.py b/tempest/services/compute/xml/floating_ips_client.py
index 278cc88..2fffaa2 100644
--- a/tempest/services/compute/xml/floating_ips_client.py
+++ b/tempest/services/compute/xml/floating_ips_client.py
@@ -107,3 +107,13 @@
         except exceptions.NotFound:
             return True
         return False
+
+    def list_floating_ip_pools(self, params=None):
+        """Returns a list of all floating IP Pools."""
+        url = 'os-floating-ip-pools'
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+
+        resp, body = self.get(url, self.headers)
+        body = self._parse_array(etree.fromstring(body))
+        return resp, body
diff --git a/tempest/services/compute/xml/servers_client.py b/tempest/services/compute/xml/servers_client.py
index bf72bdc..9b688aa 100644
--- a/tempest/services/compute/xml/servers_client.py
+++ b/tempest/services/compute/xml/servers_client.py
@@ -193,6 +193,14 @@
         server = self._parse_server(etree.fromstring(body))
         return resp, server
 
+    def lock_server(self, server_id, **kwargs):
+        """Locks the given server."""
+        return self.action(server_id, 'lock', None, **kwargs)
+
+    def unlock_server(self, server_id, **kwargs):
+        """Unlocks the given server."""
+        return self.action(server_id, 'unlock', None, **kwargs)
+
     def suspend_server(self, server_id, **kwargs):
         """Suspends the provided server."""
         return self.action(server_id, 'suspend', None, **kwargs)
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index c2d701d..4b87b91 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -45,12 +45,9 @@
         body = json.loads(body)
         return resp, body
 
-    def create_network(self, name):
-        post_body = {
-            'network': {
-                'name': name,
-            }
-        }
+    def create_network(self, name, **kwargs):
+        post_body = {'network': kwargs}
+        post_body['network']['name'] = name
         body = json.dumps(post_body)
         uri = '%s/networks' % (self.uri_prefix)
         resp, body = self.post(uri, headers=self.headers, body=body)
@@ -79,12 +76,11 @@
         resp, body = self.delete(uri, self.headers)
         return resp, body
 
-    def create_subnet(self, net_uuid, cidr):
-        post_body = dict(
-            subnet=dict(
-                ip_version=4,
-                network_id=net_uuid,
-                cidr=cidr),)
+    def create_subnet(self, net_uuid, cidr, ip_version=4, **kwargs):
+        post_body = {'subnet': kwargs}
+        post_body['subnet']['ip_version'] = ip_version
+        post_body['subnet']['network_id'] = net_uuid
+        post_body['subnet']['cidr'] = cidr
         body = json.dumps(post_body)
         uri = '%s/subnets' % (self.uri_prefix)
         resp, body = self.post(uri, headers=self.headers, body=body)
@@ -206,16 +202,10 @@
         body = json.loads(body)
         return resp, body
 
-    def create_router(self, name, **kwargs):
-        post_body = {
-            'router': {
-                'name': name,
-            }
-        }
-        post_body['router']['admin_state_up'] = kwargs.get(
-            'admin_state_up', True)
-        post_body['router']['external_gateway_info'] = kwargs.get(
-            'external_gateway_info', None)
+    def create_router(self, name, admin_state_up=True, **kwargs):
+        post_body = {'router': kwargs}
+        post_body['router']['name'] = name
+        post_body['router']['admin_state_up'] = admin_state_up
         body = json.dumps(post_body)
         uri = '%s/routers' % (self.uri_prefix)
         resp, body = self.post(uri, headers=self.headers, body=body)
diff --git a/tempest/services/object_storage/object_client.py b/tempest/services/object_storage/object_client.py
index d338d45..2fee042 100644
--- a/tempest/services/object_storage/object_client.py
+++ b/tempest/services/object_storage/object_client.py
@@ -15,10 +15,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import hashlib
-import hmac
-import urlparse
-
 from tempest.common import http
 from tempest.common.rest_client import RestClient
 from tempest import exceptions
@@ -125,29 +121,20 @@
         resp, body = self.copy(url, headers=headers)
         return resp, body
 
-    def get_object_using_temp_url(self, container, object_name, expires, key):
-        """Retrieve object's data using temporary URL."""
-
-        self._set_auth()
-        method = 'GET'
-        path = "%s/%s/%s" % (urlparse.urlparse(self.base_url).path, container,
-                             object_name)
-        hmac_body = '%s\n%s\n%s' % (method, expires, path)
-        sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest()
-
-        url = "%s/%s?temp_url_sig=%s&temp_url_expires=%s" % (container,
-                                                             object_name,
-                                                             sig, expires)
-
-        resp, body = self.get(url)
-        return resp, body
-
     def create_object_segments(self, container, object_name, segment, data):
         """Creates object segments."""
         url = "{0}/{1}/{2}".format(container, object_name, segment)
         resp, body = self.put(url, data, self.headers)
         return resp, body
 
+    def get_object_using_temp_url(self, url):
+        """Retrieve object's data using temp URL."""
+        return self.get(url)
+
+    def put_object_using_temp_url(self, url, data):
+        """Put data in an object using temp URL."""
+        return self.put(url, data, None)
+
 
 class ObjectClientCustomizedHeader(RestClient):
 
diff --git a/tempest/stress/driver.py b/tempest/stress/driver.py
index e518d28..d959543 100644
--- a/tempest/stress/driver.py
+++ b/tempest/stress/driver.py
@@ -13,6 +13,7 @@
 #    limitations under the License.
 
 import multiprocessing
+import os
 import signal
 import time
 
@@ -87,12 +88,22 @@
     """
     Goes through the process list and terminates all child processes.
     """
+    log_check_interval = int(admin_manager.config.stress.log_check_interval)
     for process in processes:
         if process['process'].is_alive():
             try:
                 process['process'].terminate()
             except Exception:
                 pass
+    time.sleep(log_check_interval)
+    for process in processes:
+        if process['process'].is_alive():
+            try:
+                pid = process['process'].pid
+                LOG.warn("Process %d hangs. Send SIGKILL." % pid)
+                os.kill(pid, signal.SIGKILL)
+            except Exception:
+                pass
         process['process'].join()
 
 
diff --git a/tempest/stress/stressaction.py b/tempest/stress/stressaction.py
index 45a628d..61e46fa 100644
--- a/tempest/stress/stressaction.py
+++ b/tempest/stress/stressaction.py
@@ -30,7 +30,10 @@
         self.stop_on_error = stop_on_error
 
     def _shutdown_handler(self, signal, frame):
-        self.tearDown()
+        try:
+            self.tearDown()
+        except Exception:
+            self.logger.exception("Error while tearDown")
         sys.exit(0)
 
     @property
diff --git a/tox.ini b/tox.ini
index 1b8a0fd..abc9e42 100644
--- a/tox.ini
+++ b/tox.ini
@@ -86,7 +86,7 @@
 sitepackages = True
 setenv = VIRTUAL_ENV={envdir}
 commands =
-    python -m tempest/stress/run_stress -a -d 3600
+    python -m tempest/stress/run_stress -a -d 3600 -S
 
 [testenv:venv]
 commands = {posargs}