Merge "Adds more test to cover Swift tempURL middleware"
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/tempest/api/compute/admin/test_aggregates.py b/tempest/api/compute/admin/test_aggregates.py
index a5dceca..40b005d 100644
--- a/tempest/api/compute/admin/test_aggregates.py
+++ b/tempest/api/compute/admin/test_aggregates.py
@@ -15,25 +15,13 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import fixtures
-
 from tempest.api.compute import base
+from tempest.common import tempest_fixtures as fixtures
 from tempest.common.utils.data_utils import rand_name
 from tempest import exceptions
-from tempest.openstack.common import lockutils
 from tempest.test import attr
 
 
-class LockFixture(fixtures.Fixture):
-    def __init__(self, name):
-        self.mgr = lockutils.lock(name, 'tempest-', True)
-
-    def setUp(self):
-        super(LockFixture, self).setUp()
-        self.addCleanup(self.mgr.__exit__, None, None, None)
-        self.mgr.__enter__()
-
-
 class AggregatesAdminTestJSON(base.BaseComputeAdminTest):
 
     """
@@ -160,7 +148,7 @@
     @attr(type='gate')
     def test_aggregate_add_remove_host(self):
         # Add an host to the given aggregate and remove.
-        self.useFixture(LockFixture('availability_zone'))
+        self.useFixture(fixtures.LockFixture('availability_zone'))
         aggregate_name = rand_name(self.aggregate_name_prefix)
         resp, aggregate = self.client.create_aggregate(aggregate_name)
         self.addCleanup(self.client.delete_aggregate, aggregate['id'])
@@ -182,7 +170,7 @@
     @attr(type='gate')
     def test_aggregate_add_host_list(self):
         # Add an host to the given aggregate and list.
-        self.useFixture(LockFixture('availability_zone'))
+        self.useFixture(fixtures.LockFixture('availability_zone'))
         aggregate_name = rand_name(self.aggregate_name_prefix)
         resp, aggregate = self.client.create_aggregate(aggregate_name)
         self.addCleanup(self.client.delete_aggregate, aggregate['id'])
@@ -200,7 +188,7 @@
     @attr(type='gate')
     def test_aggregate_add_host_get_details(self):
         # Add an host to the given aggregate and get details.
-        self.useFixture(LockFixture('availability_zone'))
+        self.useFixture(fixtures.LockFixture('availability_zone'))
         aggregate_name = rand_name(self.aggregate_name_prefix)
         resp, aggregate = self.client.create_aggregate(aggregate_name)
         self.addCleanup(self.client.delete_aggregate, aggregate['id'])
@@ -215,7 +203,7 @@
     @attr(type='gate')
     def test_aggregate_add_host_create_server_with_az(self):
         # Add an host to the given aggregate and create a server.
-        self.useFixture(LockFixture('availability_zone'))
+        self.useFixture(fixtures.LockFixture('availability_zone'))
         aggregate_name = rand_name(self.aggregate_name_prefix)
         az_name = rand_name(self.az_name_prefix)
         resp, aggregate = self.client.create_aggregate(aggregate_name, az_name)
@@ -262,7 +250,7 @@
     @attr(type=['negative', 'gate'])
     def test_aggregate_remove_host_as_user(self):
         # Regular user is not allowed to remove a host from an aggregate.
-        self.useFixture(LockFixture('availability_zone'))
+        self.useFixture(fixtures.LockFixture('availability_zone'))
         aggregate_name = rand_name(self.aggregate_name_prefix)
         resp, aggregate = self.client.create_aggregate(aggregate_name)
         self.addCleanup(self.client.delete_aggregate, aggregate['id'])
diff --git a/tempest/api/compute/admin/test_hosts.py b/tempest/api/compute/admin/test_hosts.py
index 19d7973..bf09428 100644
--- a/tempest/api/compute/admin/test_hosts.py
+++ b/tempest/api/compute/admin/test_hosts.py
@@ -15,6 +15,7 @@
 #    under the License.
 
 from tempest.api.compute import base
+from tempest.common import tempest_fixtures as fixtures
 from tempest.common.utils.data_utils import rand_name
 from tempest import exceptions
 from tempest.test import attr
@@ -42,6 +43,7 @@
 
     @attr(type='gate')
     def test_list_hosts_with_zone(self):
+        self.useFixture(fixtures.LockFixture('availability_zone'))
         resp, hosts = self.client.list_hosts()
         host = hosts[0]
         zone_name = host['zone']
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/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 77f92c9..aec1d49 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
diff --git a/tempest/api/network/test_extensions.py b/tempest/api/network/test_extensions.py
new file mode 100644
index 0000000..1b27d1b
--- /dev/null
+++ b/tempest/api/network/test_extensions.py
@@ -0,0 +1,79 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 OpenStack, Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+
+from tempest.api.network import base
+from tempest.test import attr
+
+
+class ExtensionsTestJSON(base.BaseNetworkTest):
+    _interface = 'json'
+
+    """
+    Tests the following operations in the Neutron API using the REST client for
+    Neutron:
+
+        List all available extensions
+
+    v2.0 of the Neutron API is assumed. It is also assumed that the following
+    options are defined in the [network] section of etc/tempest.conf:
+
+    """
+
+    @classmethod
+    def setUpClass(cls):
+        super(ExtensionsTestJSON, cls).setUpClass()
+
+    @attr(type='smoke')
+    def test_list_show_extensions(self):
+        # List available extensions for the tenant
+        expected_alias = ['security-group', 'l3_agent_scheduler',
+                          'ext-gw-mode', 'binding', 'quotas',
+                          'agent', 'dhcp_agent_scheduler', 'provider',
+                          'router', 'extraroute', 'external-net',
+                          'allowed-address-pairs', 'extra_dhcp_opt']
+        actual_alias = list()
+        resp, extensions = self.client.list_extensions()
+        self.assertEqual('200', resp['status'])
+        list_extensions = extensions['extensions']
+        # Show and verify the details of the available extensions
+        for ext in list_extensions:
+            ext_name = ext['name']
+            ext_alias = ext['alias']
+            actual_alias.append(ext['alias'])
+            resp, ext_details = self.client.show_extension_details(ext_alias)
+            self.assertEqual('200', resp['status'])
+            ext_details = ext_details['extension']
+
+            self.assertIsNotNone(ext_details)
+            self.assertIn('updated', ext_details.keys())
+            self.assertIn('name', ext_details.keys())
+            self.assertIn('description', ext_details.keys())
+            self.assertIn('namespace', ext_details.keys())
+            self.assertIn('links', ext_details.keys())
+            self.assertIn('alias', ext_details.keys())
+            self.assertEqual(ext_details['name'], ext_name)
+            self.assertEqual(ext_details['alias'], ext_alias)
+            self.assertEqual(ext_details, ext)
+        # Verify if expected extensions are present in the actual list
+        # of extensions returned
+        for e in expected_alias:
+            self.assertIn(e, actual_alias)
+
+
+class ExtensionsTestXML(ExtensionsTestJSON):
+    _interface = 'xml'
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/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index 7eeb1ee..a48cea2 100644
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -15,6 +15,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import uuid
+
 from tempest.api.volume import base
 from tempest.common.utils.data_utils import rand_name
 from tempest import exceptions
@@ -29,37 +31,24 @@
         super(VolumesNegativeTest, cls).setUpClass()
         cls.client = cls.volumes_client
 
+        # Create a test shared instance and volume for attach/detach tests
+        vol_name = rand_name('Volume-')
+
+        cls.volume = cls.create_volume(size=1, display_name=vol_name)
+        cls.client.wait_for_volume_status(cls.volume['id'], 'available')
+        cls.mountpoint = "/dev/vdc"
+
     @attr(type='gate')
     def test_volume_get_nonexistant_volume_id(self):
-        # Should not be able to get a non-existent volume
-        # Creating a non-existent volume id
-        volume_id_list = []
-        resp, volumes = self.client.list_volumes()
-        for i in range(len(volumes)):
-            volume_id_list.append(volumes[i]['id'])
-        while True:
-            non_exist_id = rand_name('999')
-            if non_exist_id not in volume_id_list:
-                break
-        # Trying to Get a non-existent volume
+        # Should not be able to get a non-existant volume
         self.assertRaises(exceptions.NotFound, self.client.get_volume,
-                          non_exist_id)
+                          str(uuid.uuid4()))
 
     @attr(type='gate')
     def test_volume_delete_nonexistant_volume_id(self):
-        # Should not be able to delete a non-existent Volume
-        # Creating non-existent volume id
-        volume_id_list = []
-        resp, volumes = self.client.list_volumes()
-        for i in range(len(volumes)):
-            volume_id_list.append(volumes[i]['id'])
-        while True:
-            non_exist_id = '12345678-abcd-4321-abcd-123456789098'
-            if non_exist_id not in volume_id_list:
-                break
-        # Try to delete a non-existent volume
+        # Should not be able to delete a non-existant Volume
         self.assertRaises(exceptions.NotFound, self.client.delete_volume,
-                          non_exist_id)
+                          str(uuid.uuid4()))
 
     @attr(type='gate')
     def test_create_volume_with_invalid_size(self):
@@ -109,6 +98,26 @@
         # Should not be able to delete volume when empty ID is passed
         self.assertRaises(exceptions.NotFound, self.client.delete_volume, '')
 
+    @attr(type=['negative', 'gate'])
+    def test_attach_volumes_with_nonexistent_volume_id(self):
+        srv_name = rand_name('Instance-')
+        resp, server = self.servers_client.create_server(srv_name,
+                                                         self.image_ref,
+                                                         self.flavor_ref)
+        self.addCleanup(self.servers_client.delete_server, server['id'])
+        self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
+        self.assertRaises(exceptions.NotFound,
+                          self.client.attach_volume,
+                          str(uuid.uuid4()),
+                          server['id'],
+                          self.mountpoint)
+
+    @attr(type=['negative', 'gate'])
+    def test_detach_volumes_with_invalid_volume_id(self):
+        self.assertRaises(exceptions.NotFound,
+                          self.client.detach_volume,
+                          'xxx')
+
 
 class VolumesNegativeTestXML(VolumesNegativeTest):
     _interface = 'xml'
diff --git a/tempest/common/isolated_creds.py b/tempest/common/isolated_creds.py
index d6b4466..2fc4eb9 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)
@@ -164,6 +186,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 +290,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 +325,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 +344,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 +363,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/tempest_fixtures.py b/tempest/common/tempest_fixtures.py
new file mode 100644
index 0000000..081b271
--- /dev/null
+++ b/tempest/common/tempest_fixtures.py
@@ -0,0 +1,30 @@
+# 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.
+
+import fixtures
+
+from tempest.openstack.common import lockutils
+
+
+class LockFixture(fixtures.Fixture):
+    def __init__(self, name):
+        self.mgr = lockutils.lock(name, 'tempest-', True)
+
+    def setUp(self):
+        super(LockFixture, self).setUp()
+        self.addCleanup(self.mgr.__exit__, None, None, None)
+        self.mgr.__enter__()
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index f71ea46..c01de83 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -374,8 +374,10 @@
                                                          **ruleset)
             self.set_resource(sg_rule.id, sg_rule)
 
-    def create_server(self, client, name=None, image=None, flavor=None,
+    def create_server(self, client=None, name=None, image=None, flavor=None,
                       create_kwargs={}):
+        if client is None:
+            client = self.compute_client
         if name is None:
             name = rand_name('scenario-server-')
         if image is None:
@@ -476,12 +478,17 @@
     @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, namestart='secgroup-smoke-'):
+    def _create_security_group(self, client=None, namestart='secgroup-smoke-'):
+        if client is None:
+            client = self.compute_client
         # Create security group
         sg_name = rand_name(namestart)
         sg_desc = sg_name + " description"
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index ce4d1bd..752ff6f 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -87,8 +87,7 @@
 
     def nova_boot(self):
         create_kwargs = {'key_name': self.keypair.name}
-        self.server = self.create_server(self.compute_client,
-                                         image=self.image,
+        self.server = self.create_server(image=self.image,
                                          create_kwargs=create_kwargs)
 
     def nova_list(self):
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 2aa5de3..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 = {}
@@ -168,8 +164,7 @@
             name=rand_name('keypair-smoke-'))
 
     def _create_security_groups(self):
-        self.security_groups[self.tenant_id] = self._create_security_group(
-            self.compute_client)
+        self.security_groups[self.tenant_id] = self._create_security_group()
 
     def _create_networks(self):
         network = self._create_network(self.tenant_id)
@@ -214,8 +209,7 @@
             'key_name': keypair_name,
             'security_groups': security_groups,
         }
-        server = self.create_server(self.compute_client, name=name,
-                                    create_kwargs=create_kwargs)
+        server = self.create_server(name=name, create_kwargs=create_kwargs)
         return server
 
     def _create_servers(self):
diff --git a/tempest/scenario/test_server_advanced_ops.py b/tempest/scenario/test_server_advanced_ops.py
index 26bc95e..853b1ba 100644
--- a/tempest/scenario/test_server_advanced_ops.py
+++ b/tempest/scenario/test_server_advanced_ops.py
@@ -48,7 +48,7 @@
     @services('compute')
     def test_resize_server_confirm(self):
         # We create an instance for use in this test
-        instance = self.create_server(self.compute_client)
+        instance = self.create_server()
         instance_id = instance.id
         resize_flavor = self.config.compute.flavor_ref_alt
         LOG.debug("Resizing instance %s from flavor %s to flavor %s",
@@ -66,7 +66,7 @@
     @services('compute')
     def test_server_sequence_suspend_resume(self):
         # We create an instance for use in this test
-        instance = self.create_server(self.compute_client)
+        instance = self.create_server()
         instance_id = instance.id
         LOG.debug("Suspending instance %s. Current status: %s",
                   instance_id, instance.status)
diff --git a/tempest/scenario/test_server_basic_ops.py b/tempest/scenario/test_server_basic_ops.py
index 03e6e41..c32d49d 100644
--- a/tempest/scenario/test_server_basic_ops.py
+++ b/tempest/scenario/test_server_basic_ops.py
@@ -56,8 +56,7 @@
         create_kwargs = {
             'key_name': self.keypair.id
         }
-        instance = self.create_server(self.compute_client,
-                                      create_kwargs=create_kwargs)
+        instance = self.create_server(create_kwargs=create_kwargs)
         self.set_resource('instance', instance)
 
     def pause_server(self):
diff --git a/tempest/scenario/test_snapshot_pattern.py b/tempest/scenario/test_snapshot_pattern.py
index 8c2cc76..ba347e0 100644
--- a/tempest/scenario/test_snapshot_pattern.py
+++ b/tempest/scenario/test_snapshot_pattern.py
@@ -34,8 +34,7 @@
         create_kwargs = {
             'key_name': self.keypair.name
         }
-        return self.create_server(self.compute_client, image=image_id,
-                                  create_kwargs=create_kwargs)
+        return self.create_server(image=image_id, create_kwargs=create_kwargs)
 
     def _add_keypair(self):
         self.keypair = self.create_keypair()
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index ab464e3..4f49d65 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -58,8 +58,7 @@
         create_kwargs = {
             'key_name': self.keypair.name
         }
-        return self.create_server(self.compute_client, image=image_id,
-                                  create_kwargs=create_kwargs)
+        return self.create_server(image=image_id, create_kwargs=create_kwargs)
 
     def _add_keypair(self):
         self.keypair = self.create_keypair()
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index 3572166..d12cd56 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -49,8 +49,7 @@
             'block_device_mapping': bd_map,
             'key_name': keypair.name
         }
-        return self.create_server(self.compute_client,
-                                  create_kwargs=create_kwargs)
+        return self.create_server(create_kwargs=create_kwargs)
 
     def _create_snapshot_from_volume(self, vol_id):
         volume_snapshots = self.volume_client.volume_snapshots
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index 369dd81..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)
@@ -598,3 +588,15 @@
                                                      health_monitor_id)
         resp, body = self.delete(uri, headers=self.headers)
         return resp, body
+
+    def list_extensions(self):
+        uri = '%s/extensions' % (self.uri_prefix)
+        resp, body = self.get(uri, self.headers)
+        body = json.loads(body)
+        return resp, body
+
+    def show_extension_details(self, ext_alias):
+        uri = '%s/extensions/%s' % (self.uri_prefix, ext_alias)
+        resp, body = self.get(uri, headers=self.headers)
+        body = json.loads(body)
+        return resp, body
diff --git a/tempest/services/network/xml/network_client.py b/tempest/services/network/xml/network_client.py
index a9b5512..1523ed0 100755
--- a/tempest/services/network/xml/network_client.py
+++ b/tempest/services/network/xml/network_client.py
@@ -428,6 +428,19 @@
                                                      health_monitor_id)
         return self.delete(uri, self.headers)
 
+    def list_extensions(self):
+        url = '%s/extensions' % (self.uri_prefix)
+        resp, body = self.get(url, self.headers)
+        extensions = self._parse_array(etree.fromstring(body))
+        extensions = {"extensions": extensions}
+        return resp, extensions
+
+    def show_extension_details(self, ext_alias):
+        uri = '%s/extensions/%s' % (self.uri_prefix, str(ext_alias))
+        resp, body = self.get(uri, self.headers)
+        body = _root_tag_fetcher_and_xml_to_json_parse(body)
+        return resp, body
+
 
 def _root_tag_fetcher_and_xml_to_json_parse(xml_returned_body):
     body = ET.fromstring(xml_returned_body)
diff --git a/tempest/stress/README.rst b/tempest/stress/README.rst
index 7c180f6..ae86f6e 100644
--- a/tempest/stress/README.rst
+++ b/tempest/stress/README.rst
@@ -31,7 +31,7 @@
 
 To test installation, do the following (from the tempest/stress directory):
 
-	./run_stress.py etc/server-create-destroy-test.json -d 30
+	./run_stress.py -t etc/server-create-destroy-test.json -d 30
 
 This sample test tries to create a few VMs and kill a few VMs.
 
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/tools/install_venv_common.py b/tools/install_venv_common.py
index 0999e2c..92d66ae 100644
--- a/tools/install_venv_common.py
+++ b/tools/install_venv_common.py
@@ -119,8 +119,7 @@
         self.pip_install('setuptools')
         self.pip_install('pbr')
 
-        self.pip_install('-r', self.requirements)
-        self.pip_install('-r', self.test_requirements)
+        self.pip_install('-r', self.requirements, '-r', self.test_requirements)
 
     def post_process(self):
         self.get_distro().post_process()
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}