Merge "Make rest_client.wait_for_resource_deletion timeout error more specific"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index dfcbaba..003a7f7 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -115,6 +115,24 @@
 # to use for running tests (string value)
 #test_accounts_file=etc/accounts.yaml
 
+# Allows test cases to create/destroy tenants and users. This
+# option requires that OpenStack Identity API admin
+# credentials are known. If false, isolated test cases and
+# parallel execution, can still be achieved configuring a list
+# of test accounts (boolean value)
+# Deprecated group/name - [compute]/allow_tenant_isolation
+# Deprecated group/name - [orchestration]/allow_tenant_isolation
+#allow_tenant_isolation=false
+
+# If set to True it enables the Accounts provider, which locks
+# credentials to allow for parallel execution with pre-
+# provisioned accounts. It can only be used to run tests that
+# ensure credentials cleanup happens. It requires at least `2
+# * CONC` distinct accounts configured in
+# `test_accounts_file`, with CONC == the number of concurrent
+# test processes. (boolean value)
+#locking_credentials_provider=false
+
 
 [baremetal]
 
@@ -229,12 +247,6 @@
 # Options defined in tempest.config
 #
 
-# Allows test cases to create/destroy tenants and users. This
-# option enables isolated test cases and better parallel
-# execution, but also requires that OpenStack Identity API
-# admin credentials are known. (boolean value)
-#allow_tenant_isolation=false
-
 # Valid primary image reference to be used in tests. This is a
 # required option (string value)
 #image_ref=<None>
@@ -356,12 +368,6 @@
 # value)
 #floating_ip_range=10.0.0.0/29
 
-# Allows test cases to create/destroy tenants and users. This
-# option enables isolated test cases and better parallel
-# execution, but also requires that OpenStack Identity API
-# admin credentials are known. (boolean value)
-#allow_tenant_isolation=false
-
 # Time in seconds between build status checks. (integer value)
 #build_interval=1
 
@@ -1100,7 +1106,7 @@
 # value)
 #build_interval=1
 
-# Timeout in seconds to wait for a volume to becomeavailable.
+# Timeout in seconds to wait for a volume to become available.
 # (integer value)
 #build_timeout=300
 
diff --git a/tempest/api/compute/admin/test_fixed_ips_negative.py b/tempest/api/compute/admin/test_fixed_ips_negative.py
index 90be820..8d6a7fc 100644
--- a/tempest/api/compute/admin/test_fixed_ips_negative.py
+++ b/tempest/api/compute/admin/test_fixed_ips_negative.py
@@ -68,7 +68,10 @@
         # NOTE(maurosr): since this exercises the same code snippet, we do it
         # only for reserve action
         body = {"reserve": "None"}
-        self.assertRaises(exceptions.NotFound,
+        # NOTE(eliqiao): in Juno, the exception is NotFound, but in master, we
+        # change the error code to BadRequest, both exceptions should be
+        # accepted by tempest
+        self.assertRaises((exceptions.NotFound, exceptions.BadRequest),
                           self.client.reserve_fixed_ip,
                           "my.invalid.ip", body)
 
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 6c93d33..6496176 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -44,9 +44,9 @@
 
         # TODO(andreaf) WE should care also for the alt_manager here
         # but only once client lazy load in the manager is done
-        os = cls.get_client_manager()
+        cls.os = cls.get_client_manager()
+        cls.multi_user = cls.check_multi_user()
 
-        cls.os = os
         cls.build_interval = CONF.compute.build_interval
         cls.build_timeout = CONF.compute.build_timeout
         cls.ssh_user = CONF.compute.ssh_user
@@ -58,7 +58,6 @@
         cls.image_ssh_password = CONF.compute.image_ssh_password
         cls.servers = []
         cls.images = []
-        cls.multi_user = cls.get_multi_user()
         cls.security_groups = []
         cls.server_groups = []
 
@@ -118,27 +117,12 @@
             raise exceptions.InvalidConfiguration(message=msg)
 
     @classmethod
-    def get_multi_user(cls):
-        multi_user = True
-        # Determine if there are two regular users that can be
-        # used in testing. If the test cases are allowed to create
-        # users (config.compute.allow_tenant_isolation is true,
-        # then we allow multi-user.
-        if not CONF.compute.allow_tenant_isolation:
-            user1 = CONF.identity.username
-            user2 = CONF.identity.alt_username
-            if not user2 or user1 == user2:
-                multi_user = False
-            else:
-                user2_password = CONF.identity.alt_password
-                user2_tenant_name = CONF.identity.alt_tenant_name
-                if not user2_password or not user2_tenant_name:
-                    msg = ("Alternate user specified but not alternate "
-                           "tenant or password: alt_tenant_name=%s "
-                           "alt_password=%s"
-                           % (user2_tenant_name, user2_password))
-                    raise exceptions.InvalidConfiguration(msg)
-        return multi_user
+    def check_multi_user(cls):
+        # We have a list of accounts now, so just checking if the list is gt 2
+        if not cls.isolated_creds.is_multi_user():
+            msg = "Not enough users available for multi-user testing"
+            raise exceptions.InvalidConfiguration(msg)
+        return True
 
     @classmethod
     def clear_servers(cls):
@@ -390,19 +374,14 @@
     @classmethod
     def resource_setup(cls):
         super(BaseComputeAdminTest, cls).resource_setup()
-        if (CONF.compute.allow_tenant_isolation or
-            cls.force_tenant_isolation is True):
+        try:
             creds = cls.isolated_creds.get_admin_creds()
-            cls.os_adm = clients.Manager(credentials=creds,
-                                         interface=cls._interface)
-        else:
-            try:
-                cls.os_adm = clients.ComputeAdminManager(
-                    interface=cls._interface)
-            except exceptions.InvalidCredentials:
-                msg = ("Missing Compute Admin API credentials "
-                       "in configuration.")
-                raise cls.skipException(msg)
+            cls.os_adm = clients.Manager(
+                credentials=creds, interface=cls._interface)
+        except NotImplementedError:
+            msg = ("Missing Compute Admin API credentials in configuration.")
+            raise cls.skipException(msg)
+
         if cls._api_version == 2:
             cls.availability_zone_admin_client = (
                 cls.os_adm.availability_zone_client)
diff --git a/tempest/api/compute/security_groups/test_security_group_rules.py b/tempest/api/compute/security_groups/test_security_group_rules.py
index 45b913a..4fd5c02 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules.py
@@ -13,6 +13,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import six
+
 from tempest.api.compute.security_groups import base
 from tempest import config
 from tempest import test
@@ -31,22 +33,54 @@
         cls.from_port = 22
         cls.to_port = 22
 
+    def setUp(cls):
+        super(SecurityGroupRulesTestJSON, cls).setUp()
+
+        from_port = cls.from_port
+        to_port = cls.to_port
+        group = {}
+        ip_range = {}
+        if cls._interface == 'xml':
+            # NOTE: An XML response is different from the one of JSON
+            # like the following.
+            from_port = six.text_type(from_port)
+            to_port = six.text_type(to_port)
+            group = {'tenant_id': 'None', 'name': 'None'}
+            ip_range = {'cidr': 'None'}
+        cls.expected = {
+            'id': None,
+            'parent_group_id': None,
+            'ip_protocol': cls.ip_protocol,
+            'from_port': from_port,
+            'to_port': to_port,
+            'ip_range': ip_range,
+            'group': group
+        }
+
+    def _check_expected_response(self, actual_rule):
+        for key in self.expected:
+            if key == 'id':
+                continue
+            self.assertEqual(self.expected[key], actual_rule[key],
+                             "Miss-matched key is %s" % key)
+
     @test.attr(type='smoke')
     @test.services('network')
     def test_security_group_rules_create(self):
         # Positive test: Creation of Security Group rule
         # should be successful
         # Creating a Security Group to add rules to it
-        resp, security_group = self.create_security_group()
+        _, security_group = self.create_security_group()
         securitygroup_id = security_group['id']
         # Adding rules to the created Security Group
-        resp, rule = \
+        _, rule = \
             self.client.create_security_group_rule(securitygroup_id,
                                                    self.ip_protocol,
                                                    self.from_port,
                                                    self.to_port)
-        self.addCleanup(self.client.delete_security_group_rule, rule['id'])
-        self.assertEqual(200, resp.status)
+        self.expected['parent_group_id'] = securitygroup_id
+        self.expected['ip_range'] = {'cidr': '0.0.0.0/0'}
+        self._check_expected_response(rule)
 
     @test.attr(type='smoke')
     @test.services('network')
@@ -56,16 +90,20 @@
         # should be successful
 
         # Creating a Security Group to add rules to it
-        resp, security_group = self.create_security_group()
+        _, security_group = self.create_security_group()
         parent_group_id = security_group['id']
 
         # Adding rules to the created Security Group with optional cidr
         cidr = '10.2.3.124/24'
-        self.client.create_security_group_rule(parent_group_id,
-                                               self.ip_protocol,
-                                               self.from_port,
-                                               self.to_port,
-                                               cidr=cidr)
+        _, rule = \
+            self.client.create_security_group_rule(parent_group_id,
+                                                   self.ip_protocol,
+                                                   self.from_port,
+                                                   self.to_port,
+                                                   cidr=cidr)
+        self.expected['parent_group_id'] = parent_group_id
+        self.expected['ip_range'] = {'cidr': cidr}
+        self._check_expected_response(rule)
 
     @test.attr(type='smoke')
     @test.services('network')
@@ -75,21 +113,25 @@
         # should be successful
 
         # Creating a Security Group to add rules to it
-        resp, security_group = self.create_security_group()
-        secgroup1 = security_group['id']
+        _, security_group = self.create_security_group()
+        parent_group_id = security_group['id']
 
         # Creating a Security Group so as to assign group_id to the rule
-        resp, security_group = self.create_security_group()
-        secgroup2 = security_group['id']
+        _, security_group = self.create_security_group()
+        group_id = security_group['id']
+        group_name = security_group['name']
 
         # Adding rules to the created Security Group with optional group_id
-        parent_group_id = secgroup1
-        group_id = secgroup2
-        self.client.create_security_group_rule(parent_group_id,
-                                               self.ip_protocol,
-                                               self.from_port,
-                                               self.to_port,
-                                               group_id=group_id)
+        _, rule = \
+            self.client.create_security_group_rule(parent_group_id,
+                                                   self.ip_protocol,
+                                                   self.from_port,
+                                                   self.to_port,
+                                                   group_id=group_id)
+        self.expected['parent_group_id'] = parent_group_id
+        self.expected['group'] = {'tenant_id': self.client.tenant_id,
+                                  'name': group_name}
+        self._check_expected_response(rule)
 
     @test.attr(type='smoke')
     @test.services('network')
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index 5df8d82..25dc87d 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -42,6 +42,7 @@
         personality = [{'path': '/test.txt',
                        'contents': base64.b64encode(file_contents)}]
         cls.client = cls.servers_client
+        cls.network_client = cls.os.network_client
         cli_resp = cls.create_test_server(name=cls.name,
                                           meta=cls.meta,
                                           accessIPv4=cls.accessIPv4,
@@ -124,6 +125,40 @@
         self.assertEqual(200, resp.status)
         self.assertIn(server['id'], server_group['members'])
 
+    @testtools.skipUnless(CONF.service_available.neutron,
+                          'Neutron service must be available.')
+    def test_verify_multiple_nics_order(self):
+        # Verify that the networks order given at the server creation is
+        # preserved within the server.
+        name_net1 = data_utils.rand_name(self.__class__.__name__)
+        _, net1 = self.network_client.create_network(name=name_net1)
+        name_net2 = data_utils.rand_name(self.__class__.__name__)
+        _, net2 = self.network_client.create_network(name=name_net2)
+
+        _, subnet1 = self.network_client.create_subnet(
+            network_id=net1['network']['id'],
+            cidr='19.80.0.0/24',
+            ip_version=4)
+        _, subnet2 = self.network_client.create_subnet(
+            network_id=net2['network']['id'],
+            cidr='19.86.0.0/24',
+            ip_version=4)
+
+        networks = [{'uuid': net1['network']['id']},
+                    {'uuid': net2['network']['id']}]
+
+        _, server_multi_nics = self.create_test_server(
+            networks=networks, wait_until='ACTIVE')
+
+        _, addresses = self.client.list_addresses(server_multi_nics['id'])
+
+        expected_addr = ['19.80.0.2', '19.86.0.2']
+
+        addr = [addresses[name_net1][0]['addr'],
+                addresses[name_net2][0]['addr']]
+
+        self.assertEqual(expected_addr, addr)
+
 
 class ServersWithSpecificFlavorTestJSON(base.BaseV2ComputeAdminTest):
     disk_config = 'AUTO'
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 98fe387..e660f00 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -69,12 +69,12 @@
         resp, cls.s3 = cls.create_test_server(name=cls.s3_name,
                                               flavor=cls.flavor_ref_alt,
                                               wait_until='ACTIVE')
-        if (CONF.service_available.neutron and
-                CONF.compute.allow_tenant_isolation):
-            network = cls.isolated_creds.get_primary_network()
-            cls.fixed_network_name = network['name']
-        else:
-            cls.fixed_network_name = CONF.compute.fixed_network_name
+
+        cls.fixed_network_name = CONF.compute.fixed_network_name
+        if CONF.service_available.neutron:
+            if hasattr(cls.isolated_creds, 'get_primary_network'):
+                network = cls.isolated_creds.get_primary_network()
+                cls.fixed_network_name = network['name']
 
     @utils.skip_unless_attr('multiple_images', 'Only one image found')
     @test.attr(type='gate')
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 3aacf2a..b51b46e 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -358,6 +358,25 @@
     @testtools.skipUnless(CONF.compute_feature_enabled.console_output,
                           'Console output not supported.')
     @test.attr(type='gate')
+    def test_get_console_output_with_unlimited_size(self):
+        _, server = self.create_test_server(wait_until='ACTIVE')
+
+        def _check_full_length_console_log():
+            _, output = self.servers_client.get_console_output(server['id'],
+                                                               None)
+            self.assertTrue(output, "Console output was empty.")
+            lines = len(output.split('\n'))
+
+            # NOTE: This test tries to get full length console log, and the
+            # length should be bigger than the one of test_get_console_output.
+            self.assertTrue(lines > 10, "Cannot get enough console log length."
+                                        " (lines: %s)" % lines)
+
+        self.wait_for(_check_full_length_console_log)
+
+    @testtools.skipUnless(CONF.compute_feature_enabled.console_output,
+                          'Console output not supported.')
+    @test.attr(type='gate')
     def test_get_console_output_server_id_in_shutoff_status(self):
         # Positive test:Should be able to GET the console output
         # for a given server_id in SHUTOFF status
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index b86ee06..0349260 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -45,10 +45,7 @@
     def resource_setup(cls):
         super(ServersNegativeTestJSON, cls).resource_setup()
         cls.client = cls.servers_client
-        if CONF.compute.allow_tenant_isolation:
-            cls.alt_os = clients.Manager(cls.isolated_creds.get_alt_creds())
-        else:
-            cls.alt_os = clients.AltManager()
+        cls.alt_os = clients.Manager(cls.isolated_creds.get_alt_creds())
         cls.alt_client = cls.alt_os.servers_client
         resp, server = cls.create_test_server(wait_until='ACTIVE')
         cls.server_id = server['id']
diff --git a/tempest/api/compute/test_authorization.py b/tempest/api/compute/test_authorization.py
index 015d9f5..175f008 100644
--- a/tempest/api/compute/test_authorization.py
+++ b/tempest/api/compute/test_authorization.py
@@ -45,12 +45,8 @@
         cls.keypairs_client = cls.os.keypairs_client
         cls.security_client = cls.os.security_groups_client
 
-        if CONF.compute.allow_tenant_isolation:
-            creds = cls.isolated_creds.get_alt_creds()
-            cls.alt_manager = clients.Manager(credentials=creds)
-        else:
-            # Use the alt_XXX credentials in the config file
-            cls.alt_manager = clients.AltManager()
+        creds = cls.isolated_creds.get_alt_creds()
+        cls.alt_manager = clients.Manager(credentials=creds)
 
         cls.alt_client = cls.alt_manager.servers_client
         cls.alt_images_client = cls.alt_manager.images_client
diff --git a/tempest/api/compute/v3/servers/test_list_server_filters.py b/tempest/api/compute/v3/servers/test_list_server_filters.py
index 209d293..73844cf 100644
--- a/tempest/api/compute/v3/servers/test_list_server_filters.py
+++ b/tempest/api/compute/v3/servers/test_list_server_filters.py
@@ -70,12 +70,11 @@
                                               flavor=cls.flavor_ref_alt,
                                               wait_until='ACTIVE')
 
-        if (CONF.service_available.neutron and
-                CONF.compute.allow_tenant_isolation):
-            network = cls.isolated_creds.get_primary_network()
-            cls.fixed_network_name = network['name']
-        else:
-            cls.fixed_network_name = CONF.compute.fixed_network_name
+        cls.fixed_network_name = CONF.compute.fixed_network_name
+        if CONF.service_available.neutron:
+            if hasattr(cls.isolated_creds, 'get_primary_network'):
+                network = cls.isolated_creds.get_primary_network()
+                cls.fixed_network_name = network['name']
 
     @utils.skip_unless_attr('multiple_images', 'Only one image found')
     @test.attr(type='gate')
diff --git a/tempest/api/compute/v3/servers/test_servers_negative.py b/tempest/api/compute/v3/servers/test_servers_negative.py
index 30ac0ac..4b1fe04 100644
--- a/tempest/api/compute/v3/servers/test_servers_negative.py
+++ b/tempest/api/compute/v3/servers/test_servers_negative.py
@@ -45,10 +45,7 @@
     def resource_setup(cls):
         super(ServersNegativeV3Test, cls).resource_setup()
         cls.client = cls.servers_client
-        if CONF.compute.allow_tenant_isolation:
-            cls.alt_os = clients.Manager(cls.isolated_creds.get_alt_creds())
-        else:
-            cls.alt_os = clients.AltManager()
+        cls.alt_os = clients.Manager(cls.isolated_creds.get_alt_creds())
         cls.alt_client = cls.alt_os.servers_v3_client
         resp, server = cls.create_test_server(wait_until='ACTIVE')
         cls.server_id = server['id']
diff --git a/tempest/api/image/base.py b/tempest/api/image/base.py
index 08767e3..74baba6 100644
--- a/tempest/api/image/base.py
+++ b/tempest/api/image/base.py
@@ -41,10 +41,7 @@
         if not CONF.service_available.glance:
             skip_msg = ("%s skipped as glance is not available" % cls.__name__)
             raise cls.skipException(skip_msg)
-        if CONF.compute.allow_tenant_isolation:
-            cls.os = clients.Manager(cls.isolated_creds.get_primary_creds())
-        else:
-            cls.os = clients.Manager()
+        cls.os = clients.Manager(cls.isolated_creds.get_primary_creds())
 
     @classmethod
     def resource_cleanup(cls):
@@ -91,10 +88,7 @@
     @classmethod
     def resource_setup(cls):
         super(BaseV1ImageMembersTest, cls).resource_setup()
-        if CONF.compute.allow_tenant_isolation:
-            cls.os_alt = clients.Manager(cls.isolated_creds.get_alt_creds())
-        else:
-            cls.os_alt = clients.AltManager()
+        cls.os_alt = clients.Manager(cls.isolated_creds.get_alt_creds())
 
         cls.alt_img_cli = cls.os_alt.image_client
         cls.alt_tenant_id = cls.alt_img_cli.tenant_id
@@ -126,11 +120,8 @@
     @classmethod
     def resource_setup(cls):
         super(BaseV2MemberImageTest, cls).resource_setup()
-        if CONF.compute.allow_tenant_isolation:
-            creds = cls.isolated_creds.get_alt_creds()
-            cls.os_alt = clients.Manager(creds)
-        else:
-            cls.os_alt = clients.AltManager()
+        creds = cls.isolated_creds.get_alt_creds()
+        cls.os_alt = clients.Manager(creds)
         cls.os_img_client = cls.os.image_client_v2
         cls.alt_img_client = cls.os_alt.image_client_v2
         cls.alt_tenant_id = cls.alt_img_client.tenant_id
diff --git a/tempest/api/messaging/test_queues.py b/tempest/api/messaging/test_queues.py
index ab099ff..8f9ac20 100644
--- a/tempest/api/messaging/test_queues.py
+++ b/tempest/api/messaging/test_queues.py
@@ -32,11 +32,10 @@
     def test_create_queue(self):
         # Create Queue
         queue_name = data_utils.rand_name('test-')
-        resp, body = self.create_queue(queue_name)
+        _, body = self.create_queue(queue_name)
 
         self.addCleanup(self.client.delete_queue, queue_name)
 
-        self.assertEqual('201', resp['status'])
         self.assertEqual('', body)
 
 
@@ -57,30 +56,27 @@
     def test_delete_queue(self):
         # Delete Queue
         queue_name = self.queues.pop()
-        resp, body = self.delete_queue(queue_name)
-        self.assertEqual('204', resp['status'])
+        _, body = self.delete_queue(queue_name)
         self.assertEqual('', body)
 
     @test.attr(type='smoke')
     def test_check_queue_existence(self):
         # Checking Queue Existence
         for queue_name in self.queues:
-            resp, body = self.check_queue_exists(queue_name)
-            self.assertEqual('204', resp['status'])
+            _, body = self.check_queue_exists(queue_name)
             self.assertEqual('', body)
 
     @test.attr(type='smoke')
     def test_check_queue_head(self):
         # Checking Queue Existence by calling HEAD
         for queue_name in self.queues:
-            resp, body = self.check_queue_exists_head(queue_name)
-            self.assertEqual('204', resp['status'])
+            _, body = self.check_queue_exists_head(queue_name)
             self.assertEqual('', body)
 
     @test.attr(type='smoke')
     def test_list_queues(self):
         # Listing queues
-        resp, body = self.list_queues()
+        _, body = self.list_queues()
         self.assertEqual(len(body['queues']), len(self.queues))
         for item in body['queues']:
             self.assertIn(item['name'], self.queues)
@@ -91,7 +87,7 @@
         queue_name = self.queues[data_utils.rand_int_id(0,
                                                         len(self.queues) - 1)]
         # Get Queue Stats for a newly created Queue
-        resp, body = self.get_queue_stats(queue_name)
+        _, body = self.get_queue_stats(queue_name)
         msgs = body['messages']
         for element in ('free', 'claimed', 'total'):
             self.assertEqual(0, msgs[element])
@@ -104,8 +100,7 @@
         queue_name = self.queues[data_utils.rand_int_id(0,
                                                         len(self.queues) - 1)]
         # Check the Queue has no metadata
-        resp, body = self.get_queue_metadata(queue_name)
-        self.assertEqual('200', resp['status'])
+        _, body = self.get_queue_metadata(queue_name)
         self.assertThat(body, matchers.HasLength(0))
         # Create metadata
         key3 = [0, 1, 2, 3, 4]
@@ -116,12 +111,10 @@
         req_body = dict()
         req_body[data_utils.rand_name('key1')] = req_body1
         # Set Queue Metadata
-        resp, body = self.set_queue_metadata(queue_name, req_body)
-        self.assertEqual('204', resp['status'])
+        _, body = self.set_queue_metadata(queue_name, req_body)
         self.assertEqual('', body)
         # Get Queue Metadata
-        resp, body = self.get_queue_metadata(queue_name)
-        self.assertEqual('200', resp['status'])
+        _, body = self.get_queue_metadata(queue_name)
         self.assertThat(body, matchers.Equals(req_body))
 
     @classmethod
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index d9b2848..91e3e14 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -366,19 +366,15 @@
     @classmethod
     def resource_setup(cls):
         super(BaseAdminNetworkTest, cls).resource_setup()
-        admin_username = CONF.compute_admin.username
-        admin_password = CONF.compute_admin.password
-        admin_tenant = CONF.compute_admin.tenant_name
-        if not (admin_username and admin_password and admin_tenant):
+
+        try:
+            creds = cls.isolated_creds.get_admin_creds()
+            cls.os_adm = clients.Manager(
+                credentials=creds, interface=cls._interface)
+        except NotImplementedError:
             msg = ("Missing Administrative Network API credentials "
                    "in configuration.")
             raise cls.skipException(msg)
-        if (CONF.compute.allow_tenant_isolation or
-            cls.force_tenant_isolation is True):
-            cls.os_adm = clients.Manager(cls.isolated_creds.get_admin_creds(),
-                                         interface=cls._interface)
-        else:
-            cls.os_adm = clients.ComputeAdminManager(interface=cls._interface)
         cls.admin_client = cls.os_adm.network_client
 
     @classmethod
diff --git a/tempest/api/object_storage/base.py b/tempest/api/object_storage/base.py
index 6a5fd3d..2e39cf9 100644
--- a/tempest/api/object_storage/base.py
+++ b/tempest/api/object_storage/base.py
@@ -36,18 +36,12 @@
             raise cls.skipException(skip_msg)
         cls.isolated_creds = isolated_creds.IsolatedCreds(
             cls.__name__, network_resources=cls.network_resources)
-        if CONF.compute.allow_tenant_isolation:
-            # Get isolated creds for normal user
-            cls.os = clients.Manager(cls.isolated_creds.get_primary_creds())
-            # Get isolated creds for admin user
-            cls.os_admin = clients.Manager(
-                cls.isolated_creds.get_admin_creds())
-            # Get isolated creds for alt user
-            cls.os_alt = clients.Manager(cls.isolated_creds.get_alt_creds())
-        else:
-            cls.os = clients.Manager()
-            cls.os_admin = clients.AdminManager()
-            cls.os_alt = clients.AltManager()
+        # Get isolated creds for normal user
+        cls.os = clients.Manager(cls.isolated_creds.get_primary_creds())
+        # Get isolated creds for admin user
+        cls.os_admin = clients.Manager(cls.isolated_creds.get_admin_creds())
+        # Get isolated creds for alt user
+        cls.os_alt = clients.Manager(cls.isolated_creds.get_alt_creds())
 
         cls.object_client = cls.os.object_client
         cls.container_client = cls.os.container_client
diff --git a/tempest/api/telemetry/test_telemetry_notification_api.py b/tempest/api/telemetry/test_telemetry_notification_api.py
index 3782b70..42e2a2d 100644
--- a/tempest/api/telemetry/test_telemetry_notification_api.py
+++ b/tempest/api/telemetry/test_telemetry_notification_api.py
@@ -32,7 +32,6 @@
     @test.attr(type="gate")
     @testtools.skipIf(not CONF.service_available.nova,
                       "Nova is not available.")
-    @test.skip_because(bug="1336755")
     def test_check_nova_notification(self):
 
         resp, body = self.create_server()
diff --git a/tempest/api/volume/admin/test_multi_backend.py b/tempest/api/volume/admin/test_multi_backend.py
index db2aab5..6f2ee06 100644
--- a/tempest/api/volume/admin/test_multi_backend.py
+++ b/tempest/api/volume/admin/test_multi_backend.py
@@ -60,7 +60,7 @@
             extra_specs = {spec_key_with_prefix: backend_name_key}
         else:
             extra_specs = {spec_key_without_prefix: backend_name_key}
-        _, self.type = self.client.create_volume_type(
+        _, self.type = self.volume_types_client.create_volume_type(
             type_name, extra_specs=extra_specs)
         self.volume_type_id_list.append(self.type['id'])
 
@@ -90,7 +90,7 @@
         # volume types deletion
         volume_type_id_list = getattr(cls, 'volume_type_id_list', [])
         for volume_type_id in volume_type_id_list:
-            cls.client.delete_volume_type(volume_type_id)
+            cls.volume_types_client.delete_volume_type(volume_type_id)
 
         super(VolumeMultiBackendTest, cls).resource_cleanup()
 
diff --git a/tempest/api/volume/admin/test_volume_quotas.py b/tempest/api/volume/admin/test_volume_quotas.py
index 7e24fa4..ece4299 100644
--- a/tempest/api/volume/admin/test_volume_quotas.py
+++ b/tempest/api/volume/admin/test_volume_quotas.py
@@ -71,7 +71,8 @@
 
     @test.attr(type='gate')
     def test_show_quota_usage(self):
-        _, quota_usage = self.quotas_client.get_quota_usage(self.adm_tenant)
+        _, quota_usage = self.quotas_client.get_quota_usage(
+            self.os_adm.credentials.tenant_name)
         for key in QUOTA_KEYS:
             self.assertIn(key, quota_usage)
             for usage_key in QUOTA_USAGE_KEYS:
diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py
index 070d38f..a0792f1 100644
--- a/tempest/api/volume/admin/test_volume_types.py
+++ b/tempest/api/volume/admin/test_volume_types.py
@@ -29,12 +29,12 @@
         self.volumes_client.wait_for_resource_deletion(volume_id)
 
     def _delete_volume_type(self, volume_type_id):
-        self.client.delete_volume_type(volume_type_id)
+        self.volume_types_client.delete_volume_type(volume_type_id)
 
     @test.attr(type='smoke')
     def test_volume_type_list(self):
         # List Volume types.
-        _, body = self.client.list_volume_types()
+        _, body = self.volume_types_client.list_volume_types()
         self.assertIsInstance(body, list)
 
     @test.attr(type='smoke')
@@ -48,7 +48,7 @@
         extra_specs = {"storage_protocol": proto,
                        "vendor_name": vendor}
         body = {}
-        _, body = self.client.create_volume_type(
+        _, body = self.volume_types_client.create_volume_type(
             vol_type_name,
             extra_specs=extra_specs)
         self.assertIn('id', body)
@@ -87,7 +87,7 @@
         vendor = CONF.volume.vendor_name
         extra_specs = {"storage_protocol": proto,
                        "vendor_name": vendor}
-        _, body = self.client.create_volume_type(
+        _, body = self.volume_types_client.create_volume_type(
             name,
             extra_specs=extra_specs)
         self.assertIn('id', body)
@@ -98,7 +98,8 @@
                          "to the requested name")
         self.assertTrue(body['id'] is not None,
                         "Field volume_type id is empty or not found.")
-        _, fetched_volume_type = self.client.get_volume_type(body['id'])
+        _, fetched_volume_type = self.volume_types_client.get_volume_type(
+            body['id'])
         self.assertEqual(name, fetched_volume_type['name'],
                          'The fetched Volume_type is different '
                          'from the created Volume_type')
@@ -115,11 +116,11 @@
         provider = "LuksEncryptor"
         control_location = "front-end"
         name = data_utils.rand_name("volume-type-")
-        _, body = self.client.create_volume_type(name)
+        _, body = self.volume_types_client.create_volume_type(name)
         self.addCleanup(self._delete_volume_type, body['id'])
 
         # Create encryption type
-        _, encryption_type = self.client.create_encryption_type(
+        _, encryption_type = self.volume_types_client.create_encryption_type(
             body['id'], provider=provider,
             control_location=control_location)
         self.assertIn('volume_type_id', encryption_type)
@@ -131,8 +132,9 @@
                          "equal to the requested control_location")
 
         # Get encryption type
-        _, fetched_encryption_type = self.client.get_encryption_type(
-            encryption_type['volume_type_id'])
+        _, fetched_encryption_type = (
+            self.volume_types_client.get_encryption_type(
+                encryption_type['volume_type_id']))
         self.assertEqual(provider,
                          fetched_encryption_type['provider'],
                          'The fetched encryption_type provider is different '
@@ -143,11 +145,12 @@
                          'different from the created encryption_type')
 
         # Delete encryption type
-        self.client.delete_encryption_type(
+        self.volume_types_client.delete_encryption_type(
             encryption_type['volume_type_id'])
         resource = {"id": encryption_type['volume_type_id'],
                     "type": "encryption-type"}
-        self.client.wait_for_resource_deletion(resource)
-        _, deleted_encryption_type = self.client.get_encryption_type(
-            encryption_type['volume_type_id'])
+        self.volume_types_client.wait_for_resource_deletion(resource)
+        _, deleted_encryption_type = (
+            self.volume_types_client.get_encryption_type(
+                encryption_type['volume_type_id']))
         self.assertEmpty(deleted_encryption_type)
diff --git a/tempest/api/volume/admin/test_volume_types_extra_specs.py b/tempest/api/volume/admin/test_volume_types_extra_specs.py
index 2d72dd2..a154821 100644
--- a/tempest/api/volume/admin/test_volume_types_extra_specs.py
+++ b/tempest/api/volume/admin/test_volume_types_extra_specs.py
@@ -25,22 +25,23 @@
     def resource_setup(cls):
         super(VolumeTypesExtraSpecsTest, cls).resource_setup()
         vol_type_name = data_utils.rand_name('Volume-type-')
-        _, cls.volume_type = cls.client.create_volume_type(vol_type_name)
+        _, cls.volume_type = cls.volume_types_client.create_volume_type(
+            vol_type_name)
 
     @classmethod
     def resource_cleanup(cls):
-        cls.client.delete_volume_type(cls.volume_type['id'])
+        cls.volume_types_client.delete_volume_type(cls.volume_type['id'])
         super(VolumeTypesExtraSpecsTest, cls).resource_cleanup()
 
     @test.attr(type='smoke')
     def test_volume_type_extra_specs_list(self):
         # List Volume types extra specs.
         extra_specs = {"spec1": "val1"}
-        _, body = self.client.create_volume_type_extra_specs(
+        _, body = self.volume_types_client.create_volume_type_extra_specs(
             self.volume_type['id'], extra_specs)
         self.assertEqual(extra_specs, body,
                          "Volume type extra spec incorrectly created")
-        _, body = self.client.list_volume_types_extra_specs(
+        _, body = self.volume_types_client.list_volume_types_extra_specs(
             self.volume_type['id'])
         self.assertIsInstance(body, dict)
         self.assertIn('spec1', body)
@@ -49,13 +50,13 @@
     def test_volume_type_extra_specs_update(self):
         # Update volume type extra specs
         extra_specs = {"spec2": "val1"}
-        _, body = self.client.create_volume_type_extra_specs(
+        _, body = self.volume_types_client.create_volume_type_extra_specs(
             self.volume_type['id'], extra_specs)
         self.assertEqual(extra_specs, body,
                          "Volume type extra spec incorrectly created")
 
         extra_spec = {"spec2": "val2"}
-        _, body = self.client.update_volume_type_extra_specs(
+        _, body = self.volume_types_client.update_volume_type_extra_specs(
             self.volume_type['id'],
             extra_spec.keys()[0],
             extra_spec)
@@ -67,18 +68,18 @@
     def test_volume_type_extra_spec_create_get_delete(self):
         # Create/Get/Delete volume type extra spec.
         extra_specs = {"spec3": "val1"}
-        _, body = self.client.create_volume_type_extra_specs(
+        _, body = self.volume_types_client.create_volume_type_extra_specs(
             self.volume_type['id'],
             extra_specs)
         self.assertEqual(extra_specs, body,
                          "Volume type extra spec incorrectly created")
 
-        self.client.get_volume_type_extra_specs(
+        self.volume_types_client.get_volume_type_extra_specs(
             self.volume_type['id'],
             extra_specs.keys()[0])
         self.assertEqual(extra_specs, body,
                          "Volume type extra spec incorrectly fetched")
 
-        self.client.delete_volume_type_extra_specs(
+        self.volume_types_client.delete_volume_type_extra_specs(
             self.volume_type['id'],
             extra_specs.keys()[0])
diff --git a/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py b/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
index f3eee00..8734b16 100644
--- a/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
+++ b/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
@@ -29,104 +29,115 @@
         super(ExtraSpecsNegativeTest, cls).resource_setup()
         vol_type_name = data_utils.rand_name('Volume-type-')
         cls.extra_specs = {"spec1": "val1"}
-        _, cls.volume_type = cls.client.create_volume_type(
+        _, cls.volume_type = cls.volume_types_client.create_volume_type(
             vol_type_name,
             extra_specs=cls.extra_specs)
 
     @classmethod
     def resource_cleanup(cls):
-        cls.client.delete_volume_type(cls.volume_type['id'])
+        cls.volume_types_client.delete_volume_type(cls.volume_type['id'])
         super(ExtraSpecsNegativeTest, cls).resource_cleanup()
 
     @test.attr(type='gate')
     def test_update_no_body(self):
         # Should not update volume type extra specs with no body
         extra_spec = {"spec1": "val2"}
-        self.assertRaises(exceptions.BadRequest,
-                          self.client.update_volume_type_extra_specs,
-                          self.volume_type['id'], extra_spec.keys()[0], None)
+        self.assertRaises(
+            exceptions.BadRequest,
+            self.volume_types_client.update_volume_type_extra_specs,
+            self.volume_type['id'], extra_spec.keys()[0], None)
 
     @test.attr(type='gate')
     def test_update_nonexistent_extra_spec_id(self):
         # Should not update volume type extra specs with nonexistent id.
         extra_spec = {"spec1": "val2"}
-        self.assertRaises(exceptions.BadRequest,
-                          self.client.update_volume_type_extra_specs,
-                          self.volume_type['id'], str(uuid.uuid4()),
-                          extra_spec)
+        self.assertRaises(
+            exceptions.BadRequest,
+            self.volume_types_client.update_volume_type_extra_specs,
+            self.volume_type['id'], str(uuid.uuid4()),
+            extra_spec)
 
     @test.attr(type='gate')
     def test_update_none_extra_spec_id(self):
         # Should not update volume type extra specs with none id.
         extra_spec = {"spec1": "val2"}
-        self.assertRaises(exceptions.BadRequest,
-                          self.client.update_volume_type_extra_specs,
-                          self.volume_type['id'], None, extra_spec)
+        self.assertRaises(
+            exceptions.BadRequest,
+            self.volume_types_client.update_volume_type_extra_specs,
+            self.volume_type['id'], None, extra_spec)
 
     @test.attr(type='gate')
     def test_update_multiple_extra_spec(self):
         # Should not update volume type extra specs with multiple specs as
             # body.
         extra_spec = {"spec1": "val2", 'spec2': 'val1'}
-        self.assertRaises(exceptions.BadRequest,
-                          self.client.update_volume_type_extra_specs,
-                          self.volume_type['id'], extra_spec.keys()[0],
-                          extra_spec)
+        self.assertRaises(
+            exceptions.BadRequest,
+            self.volume_types_client.update_volume_type_extra_specs,
+            self.volume_type['id'], extra_spec.keys()[0],
+            extra_spec)
 
     @test.attr(type='gate')
     def test_create_nonexistent_type_id(self):
         # Should not create volume type extra spec for nonexistent volume
             # type id.
         extra_specs = {"spec2": "val1"}
-        self.assertRaises(exceptions.NotFound,
-                          self.client.create_volume_type_extra_specs,
-                          str(uuid.uuid4()), extra_specs)
+        self.assertRaises(
+            exceptions.NotFound,
+            self.volume_types_client.create_volume_type_extra_specs,
+            str(uuid.uuid4()), extra_specs)
 
     @test.attr(type='gate')
     def test_create_none_body(self):
         # Should not create volume type extra spec for none POST body.
-        self.assertRaises(exceptions.BadRequest,
-                          self.client.create_volume_type_extra_specs,
-                          self.volume_type['id'], None)
+        self.assertRaises(
+            exceptions.BadRequest,
+            self.volume_types_client.create_volume_type_extra_specs,
+            self.volume_type['id'], None)
 
     @test.attr(type='gate')
     def test_create_invalid_body(self):
         # Should not create volume type extra spec for invalid POST body.
-        self.assertRaises(exceptions.BadRequest,
-                          self.client.create_volume_type_extra_specs,
-                          self.volume_type['id'], ['invalid'])
+        self.assertRaises(
+            exceptions.BadRequest,
+            self.volume_types_client.create_volume_type_extra_specs,
+            self.volume_type['id'], ['invalid'])
 
     @test.attr(type='gate')
     def test_delete_nonexistent_volume_type_id(self):
         # Should not delete volume type extra spec for nonexistent
             # type id.
         extra_specs = {"spec1": "val1"}
-        self.assertRaises(exceptions.NotFound,
-                          self.client.delete_volume_type_extra_specs,
-                          str(uuid.uuid4()), extra_specs.keys()[0])
+        self.assertRaises(
+            exceptions.NotFound,
+            self.volume_types_client.delete_volume_type_extra_specs,
+            str(uuid.uuid4()), extra_specs.keys()[0])
 
     @test.attr(type='gate')
     def test_list_nonexistent_volume_type_id(self):
         # Should not list volume type extra spec for nonexistent type id.
-        self.assertRaises(exceptions.NotFound,
-                          self.client.list_volume_types_extra_specs,
-                          str(uuid.uuid4()))
+        self.assertRaises(
+            exceptions.NotFound,
+            self.volume_types_client.list_volume_types_extra_specs,
+            str(uuid.uuid4()))
 
     @test.attr(type='gate')
     def test_get_nonexistent_volume_type_id(self):
         # Should not get volume type extra spec for nonexistent type id.
         extra_specs = {"spec1": "val1"}
-        self.assertRaises(exceptions.NotFound,
-                          self.client.get_volume_type_extra_specs,
-                          str(uuid.uuid4()), extra_specs.keys()[0])
+        self.assertRaises(
+            exceptions.NotFound,
+            self.volume_types_client.get_volume_type_extra_specs,
+            str(uuid.uuid4()), extra_specs.keys()[0])
 
     @test.attr(type='gate')
     def test_get_nonexistent_extra_spec_id(self):
         # Should not get volume type extra spec for nonexistent extra spec
             # id.
-        self.assertRaises(exceptions.NotFound,
-                          self.client.get_volume_type_extra_specs,
-                          self.volume_type['id'], str(uuid.uuid4()))
+        self.assertRaises(
+            exceptions.NotFound,
+            self.volume_types_client.get_volume_type_extra_specs,
+            self.volume_type['id'], str(uuid.uuid4()))
 
 
 class ExtraSpecsNegativeTestXML(ExtraSpecsNegativeTest):
diff --git a/tempest/api/volume/admin/test_volume_types_negative.py b/tempest/api/volume/admin/test_volume_types_negative.py
index c18e15d..a4d6431 100644
--- a/tempest/api/volume/admin/test_volume_types_negative.py
+++ b/tempest/api/volume/admin/test_volume_types_negative.py
@@ -35,18 +35,20 @@
     def test_create_with_empty_name(self):
         # Should not be able to create volume type with an empty name.
         self.assertRaises(exceptions.BadRequest,
-                          self.client.create_volume_type, '')
+                          self.volume_types_client.create_volume_type, '')
 
     @test.attr(type='gate')
     def test_get_nonexistent_type_id(self):
         # Should not be able to get volume type with nonexistent type id.
-        self.assertRaises(exceptions.NotFound, self.client.get_volume_type,
+        self.assertRaises(exceptions.NotFound,
+                          self.volume_types_client.get_volume_type,
                           str(uuid.uuid4()))
 
     @test.attr(type='gate')
     def test_delete_nonexistent_type_id(self):
         # Should not be able to delete volume type with nonexistent type id.
-        self.assertRaises(exceptions.NotFound, self.client.delete_volume_type,
+        self.assertRaises(exceptions.NotFound,
+                          self.volume_types_client.delete_volume_type,
                           str(uuid.uuid4()))
 
 
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index 7f5361d..5815f68 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -154,23 +154,17 @@
     @classmethod
     def resource_setup(cls):
         super(BaseVolumeAdminTest, cls).resource_setup()
-        cls.adm_user = CONF.identity.admin_username
-        cls.adm_pass = CONF.identity.admin_password
-        cls.adm_tenant = CONF.identity.admin_tenant_name
-        if not all((cls.adm_user, cls.adm_pass, cls.adm_tenant)):
-            msg = ("Missing Volume Admin API credentials "
-                   "in configuration.")
-            raise cls.skipException(msg)
 
-        if CONF.compute.allow_tenant_isolation:
-            cls.os_adm = clients.Manager(cls.isolated_creds.get_admin_creds(),
-                                         interface=cls._interface)
-        else:
-            cls.os_adm = clients.AdminManager(interface=cls._interface)
+        try:
+            cls.adm_creds = cls.isolated_creds.get_admin_creds()
+            cls.os_adm = clients.Manager(
+                credentials=cls.adm_creds, interface=cls._interface)
+        except NotImplementedError:
+            msg = "Missing Volume Admin API credentials in configuration."
+            raise cls.skipException(msg)
 
         cls.qos_specs = []
 
-        cls.client = cls.os_adm.volume_types_client
         cls.hosts_client = cls.os_adm.volume_hosts_client
         cls.quotas_client = cls.os_adm.volume_quotas_client
         cls.volume_types_client = cls.os_adm.volume_types_client
diff --git a/tempest/api/volume/test_volume_transfers.py b/tempest/api/volume/test_volume_transfers.py
index 90ac9c1..fe217c1 100644
--- a/tempest/api/volume/test_volume_transfers.py
+++ b/tempest/api/volume/test_volume_transfers.py
@@ -30,15 +30,16 @@
         super(VolumesV2TransfersTest, cls).resource_setup()
 
         # Add another tenant to test volume-transfer
-        if CONF.compute.allow_tenant_isolation:
-            cls.os_alt = clients.Manager(cls.isolated_creds.get_alt_creds(),
-                                         interface=cls._interface)
-            # Add admin tenant to cleanup resources
-            cls.os_adm = clients.Manager(cls.isolated_creds.get_admin_creds(),
-                                         interface=cls._interface)
-        else:
-            cls.os_alt = clients.AltManager()
-            cls.os_adm = clients.ComputeAdminManager(interface=cls._interface)
+        cls.os_alt = clients.Manager(cls.isolated_creds.get_alt_creds(),
+                                     interface=cls._interface)
+        # Add admin tenant to cleanup resources
+        try:
+            creds = cls.isolated_creds.get_admin_creds()
+            cls.os_adm = clients.Manager(
+                credentials=creds, interface=cls._interface)
+        except NotImplementedError:
+            msg = "Missing Volume Admin API credentials in configuration."
+            raise cls.skipException(msg)
 
         cls.client = cls.volumes_client
         cls.alt_client = cls.os_alt.volumes_client
diff --git a/tempest/api_schema/response/messaging/v1/queues.py b/tempest/api_schema/response/messaging/v1/queues.py
index f0b2691..09e0147 100644
--- a/tempest/api_schema/response/messaging/v1/queues.py
+++ b/tempest/api_schema/response/messaging/v1/queues.py
@@ -105,7 +105,9 @@
 
 resource_schema = {
     'type': 'array',
-    'items': 'string',
+    'items': {
+        'type': 'string'
+    },
     'minItems': 1
 }
 
diff --git a/tempest/cmd/cleanup.py b/tempest/cmd/cleanup.py
index 9ae3dfb..a305e42 100644
--- a/tempest/cmd/cleanup.py
+++ b/tempest/cmd/cleanup.py
@@ -12,7 +12,6 @@
 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 # License for the specific language governing permissions and limitations
 # under the License.
-# @author: David Paterson
 
 """
 Utility for cleaning up environment after Tempest run
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index f5f0db3..0d3c6c6 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -13,11 +13,7 @@
 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 #    License for the specific language governing permissions and limitations
 #    under the License.
-'''
-Created on Sep 3, 2014
 
-@author: David_Paterson
-'''
 from tempest import config
 from tempest.openstack.common import log as logging
 from tempest import test
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index 4e6d04a..0adc7e0 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -283,6 +283,8 @@
         If in check mode confirm that the oldest sample available is from
         before the upgrade.
         """
+        if not self.res.get('telemetry'):
+            return
         LOG.info("checking telemetry")
         for server in self.res['servers']:
             client = client_for_user(server['owner'])
diff --git a/tempest/cmd/resources.yaml b/tempest/cmd/resources.yaml
index 19ee6d5..2d5e686 100644
--- a/tempest/cmd/resources.yaml
+++ b/tempest/cmd/resources.yaml
@@ -57,3 +57,4 @@
     name: javelin1
     owner: javelin
     file: /etc/hosts
+telemetry: true
diff --git a/tempest/common/accounts.py b/tempest/common/accounts.py
index 7423c17..88e8ced 100644
--- a/tempest/common/accounts.py
+++ b/tempest/common/accounts.py
@@ -58,7 +58,12 @@
         return hash_dict
 
     def is_multi_user(self):
-        return len(self.hash_dict) > 1
+        # Default credentials is not a valid option with locking Account
+        if self.use_default_creds:
+            raise exceptions.InvalidConfiguration(
+                "Account file %s doesn't exist" % CONF.auth.test_accounts_file)
+        else:
+            return len(self.hash_dict) > 1
 
     def _create_hash_file(self, hash_string):
         path = os.path.join(os.path.join(self.accounts_dir, hash_string))
@@ -144,6 +149,21 @@
     to preserve the current behaviour of the serial tempest run.
     """
 
+    def is_multi_user(self):
+        if self.use_default_creds:
+            # Verify that the configured users are valid and distinct
+            try:
+                user = self.get_primary_creds()
+                alt_user = self.get_alt_creds()
+                return user.username != alt_user.username
+            except exceptions.InvalidCredentials as ic:
+                msg = "At least one of the configured credentials is " \
+                      "not valid: %s" % ic.message
+                raise exceptions.InvalidConfiguration(msg)
+        else:
+            # TODO(andreaf) Add a uniqueness check here
+            return len(self.hash_dict) > 1
+
     def get_creds(self, id):
         try:
             # No need to sort the dict as within the same python process
diff --git a/tempest/common/cred_provider.py b/tempest/common/cred_provider.py
index 56d34a5..b09c964 100644
--- a/tempest/common/cred_provider.py
+++ b/tempest/common/cred_provider.py
@@ -1,4 +1,5 @@
-# (c) 2014 Deutsche Telekom AG
+# Copyright (c) 2014 Deutsche Telekom AG
+# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
 #    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
@@ -43,3 +44,7 @@
     @abc.abstractmethod
     def clear_isolated_creds(self):
         return
+
+    @abc.abstractmethod
+    def is_multi_user(self):
+        return
diff --git a/tempest/common/credentials.py b/tempest/common/credentials.py
new file mode 100644
index 0000000..08b592f
--- /dev/null
+++ b/tempest/common/credentials.py
@@ -0,0 +1,39 @@
+# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
+#    Licensed under the Apache License, Version 2.0 (the "License");
+#    you may not use this file except in compliance with the License.
+#    You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+
+from tempest.common import accounts
+from tempest.common import isolated_creds
+from tempest import config
+
+CONF = config.CONF
+
+
+# Return the right implementation of CredentialProvider based on config
+# Dropping interface and password, as they are never used anyways
+# TODO(andreaf) Drop them from the CredentialsProvider interface completely
+def get_isolated_credentials(name, network_resources=None,
+                             force_tenant_isolation=False):
+    # If a test requires a new account to work, it can have it via forcing
+    # tenant isolation. A new account will be produced only for that test.
+    # In case admin credentials are not available for the account creation,
+    # the test should be skipped else it would fail.
+    if CONF.auth.allow_tenant_isolation or force_tenant_isolation:
+        return isolated_creds.IsolatedCreds(
+            name=name,
+            network_resources=network_resources)
+    else:
+        if CONF.auth.locking_credentials_provider:
+            # Most params are not relevant for pre-created accounts
+            return accounts.Accounts(name=name)
+        else:
+            return accounts.NotLockingAccounts(name=name)
diff --git a/tempest/common/isolated_creds.py b/tempest/common/isolated_creds.py
index b2edfee..2d16107 100644
--- a/tempest/common/isolated_creds.py
+++ b/tempest/common/isolated_creds.py
@@ -351,3 +351,6 @@
             except exceptions.NotFound:
                 LOG.warn("tenant with name: %s not found for delete" %
                          creds.tenant_name)
+
+    def is_multi_user(self):
+        return True
diff --git a/tempest/config.py b/tempest/config.py
index 174a895..6a41f24 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -38,9 +38,28 @@
                default='etc/accounts.yaml',
                help="Path to the yaml file that contains the list of "
                     "credentials to use for running tests"),
+    cfg.BoolOpt('allow_tenant_isolation',
+                default=False,
+                help="Allows test cases to create/destroy tenants and "
+                     "users. This option requires that OpenStack Identity "
+                     "API admin credentials are known. If false, isolated "
+                     "test cases and parallel execution, can still be "
+                     "achieved configuring a list of test accounts",
+                deprecated_opts=[cfg.DeprecatedOpt('allow_tenant_isolation',
+                                                   group='compute'),
+                                 cfg.DeprecatedOpt('allow_tenant_isolation',
+                                                   group='orchestration')]),
+    cfg.BoolOpt('locking_credentials_provider',
+                default=False,
+                help="If set to True it enables the Accounts provider, "
+                     "which locks credentials to allow for parallel execution "
+                     "with pre-provisioned accounts. It can only be used to "
+                     "run tests that ensure credentials cleanup happens. "
+                     "It requires at least `2 * CONC` distinct accounts "
+                     "configured in `test_accounts_file`, with CONC == the "
+                     "number of concurrent test processes."),
 ]
 
-
 identity_group = cfg.OptGroup(name='identity',
                               title="Keystone Configuration Options")
 
@@ -129,12 +148,6 @@
                              title='Compute Service Options')
 
 ComputeGroup = [
-    cfg.BoolOpt('allow_tenant_isolation',
-                default=False,
-                help="Allows test cases to create/destroy tenants and "
-                     "users. This option enables isolated test cases and "
-                     "better parallel execution, but also requires that "
-                     "OpenStack Identity API admin credentials are known."),
     cfg.StrOpt('image_ref',
                help="Valid primary image reference to be used in tests. "
                     "This is a required option"),
@@ -514,7 +527,7 @@
                help='Time in seconds between volume availability checks.'),
     cfg.IntOpt('build_timeout',
                default=300,
-               help='Timeout in seconds to wait for a volume to become'
+               help='Timeout in seconds to wait for a volume to become '
                     'available.'),
     cfg.StrOpt('catalog_type',
                default='volume',
@@ -666,12 +679,6 @@
                choices=['public', 'admin', 'internal',
                         'publicURL', 'adminURL', 'internalURL'],
                help="The endpoint type to use for the orchestration service."),
-    cfg.BoolOpt('allow_tenant_isolation',
-                default=False,
-                help="Allows test cases to create/destroy tenants and "
-                     "users. This option enables isolated test cases and "
-                     "better parallel execution, but also requires that "
-                     "OpenStack Identity API admin credentials are known."),
     cfg.IntOpt('build_interval',
                default=1,
                help="Time in seconds between build status checks."),
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index baa7186..928a8e1 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -23,8 +23,8 @@
 
 from tempest import auth
 from tempest import clients
+from tempest.common import credentials
 from tempest.common import debug
-from tempest.common import isolated_creds
 from tempest.common.utils import data_utils
 from tempest.common.utils.linux import remote_client
 from tempest import config
@@ -51,8 +51,9 @@
     @classmethod
     def resource_setup(cls):
         super(ScenarioTest, cls).resource_setup()
-        # Using tempest client for isolated credentials as well
-        cls.isolated_creds = isolated_creds.IsolatedCreds(
+        # TODO(andreaf) Some of the code from this resource_setup could be
+        # moved into `BaseTestCase`
+        cls.isolated_creds = credentials.get_isolated_credentials(
             cls.__name__, network_resources=cls.network_resources)
         cls.manager = clients.Manager(
             credentials=cls.credentials()
@@ -79,27 +80,19 @@
         cls.orchestration_client = cls.manager.orchestration_client
 
     @classmethod
-    def _get_credentials(cls, get_creds, ctype):
-        if CONF.compute.allow_tenant_isolation:
-            creds = get_creds()
-        else:
-            creds = auth.get_default_credentials(ctype)
-        return creds
-
-    @classmethod
     def credentials(cls):
-        return cls._get_credentials(cls.isolated_creds.get_primary_creds,
-                                    'user')
+        return cls.isolated_creds.get_primary_creds()
 
     @classmethod
     def alt_credentials(cls):
-        return cls._get_credentials(cls.isolated_creds.get_alt_creds,
-                                    'alt_user')
+        return cls.isolated_creds.get_alt_creds()
 
     @classmethod
     def admin_credentials(cls):
-        return cls._get_credentials(cls.isolated_creds.get_admin_creds,
-                                    'identity_admin')
+        try:
+            return cls.isolated_creds.get_admin_creds()
+        except NotImplementedError:
+            raise cls.skipException('Admin Credentials are not available')
 
     # ## Methods to handle sync and async deletes
 
@@ -382,9 +375,10 @@
             _, servers = self.servers_client.list_servers()
             servers = servers['servers']
         for server in servers:
-            LOG.debug('Console output for %s', server['id'])
-            LOG.debug(self.servers_client.get_console_output(server['id'],
-                                                             length=None))
+            console_output = self.servers_client.get_console_output(
+                server['id'], length=None)
+            LOG.debug('Console output for %s\nhead=%s\nbody=\n%s',
+                      server['id'], console_output[0], console_output[1])
 
     def _log_net_info(self, exc):
         # network debug is called as part of ssh init
@@ -449,7 +443,9 @@
         if wait:
             self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
 
-    def ping_ip_address(self, ip_address, should_succeed=True):
+    def ping_ip_address(self, ip_address, should_succeed=True,
+                        ping_timeout=None):
+        timeout = ping_timeout or CONF.compute.ping_timeout
         cmd = ['ping', '-c1', '-w1', ip_address]
 
         def ping():
@@ -459,8 +455,7 @@
             proc.communicate()
             return (proc.returncode == 0) == should_succeed
 
-        return tempest.test.call_until_true(
-            ping, CONF.compute.ping_timeout, 1)
+        return tempest.test.call_until_true(ping, timeout, 1)
 
 
 class NetworkScenarioTest(ScenarioTest):
@@ -628,6 +623,23 @@
         self.assertIsNone(floating_ip.port_id)
         return floating_ip
 
+    def check_floating_ip_status(self, floating_ip, status):
+        """Verifies floatingip has reached given status. without waiting
+
+        :param floating_ip: net_resources.DeletableFloatingIp floating IP to
+        to check status
+        :param status: target status
+        :raises: AssertionError if status doesn't match
+        """
+        floating_ip.refresh()
+        self.assertEqual(status, floating_ip.status,
+                         message="FloatingIP: {fp} is at status: {cst}. "
+                                 "failed  to reach status: {st}"
+                         .format(fp=floating_ip, cst=floating_ip.status,
+                                 st=status))
+        LOG.info("FloatingIP: {fp} is at status: {st}"
+                 .format(fp=floating_ip, st=status))
+
     def _check_vm_connectivity(self, ip_address,
                                username=None,
                                private_key=None,
@@ -926,8 +938,8 @@
         router_id = CONF.network.public_router_id
         network_id = CONF.network.public_network_id
         if router_id:
-            result = client.show_router(router_id)
-            return net_resources.AttributeDict(**result['router'])
+            resp, body = client.show_router(router_id)
+            return net_resources.AttributeDict(**body['router'])
         elif network_id:
             router = self._create_router(client, tenant_id)
             router.set_gateway(network_id)
diff --git a/tempest/scenario/orchestration/test_server_cfn_init.py b/tempest/scenario/orchestration/test_server_cfn_init.py
index abda1f8..791c564 100644
--- a/tempest/scenario/orchestration/test_server_cfn_init.py
+++ b/tempest/scenario/orchestration/test_server_cfn_init.py
@@ -24,7 +24,6 @@
 
 class CfnInitScenarioTest(manager.OrchestrationScenarioTest):
 
-    @test.skip_because(bug="1374175")
     def setUp(self):
         super(CfnInitScenarioTest, self).setUp()
         if not CONF.orchestration.image_ref:
@@ -84,7 +83,8 @@
         server_ip =\
             server['addresses'][CONF.compute.network_for_ssh][0]['addr']
 
-        if not self.ping_ip_address(server_ip):
+        if not self.ping_ip_address(
+            server_ip, ping_timeout=CONF.orchestration.build_timeout):
             self._log_console_output(servers=[server])
             self.fail(
                 "(CfnInitScenarioTest:test_server_cfn_init) Timed out waiting "
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index 58a028f..0c48334 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -87,6 +87,7 @@
         self._check_public_network_connectivity(floating_ip, username,
                                                 private_key, should_connect,
                                                 servers=[self.server])
+        self.check_floating_ip_status(self.floating_ip, 'ACTIVE')
 
     def _wait_server_status_and_check_network_connectivity(self):
         self.servers_client.wait_for_server_status(self.server['id'], 'ACTIVE')
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index de60745..5d75b64 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -176,16 +176,31 @@
 
     def _check_public_network_connectivity(self, should_connect=True,
                                            msg=None):
+        """Verifies connectivty to a VM via public network and floating IP,
+        and verifies floating IP has resource status is correct.
+
+        Floating IP status is verified after connectivity test in order to
+        not add extra waiting and mask racing conditions.
+
+        :param should_connect: bool. determines if connectivity check is
+        negative or positive.
+        :param msg: Failure message to add to Error message. Should describe
+        the place in the test scenario where the method was called,
+        to indicate the context of the failure
+        """
         ssh_login = CONF.compute.image_ssh_user
         floating_ip, server = self.floating_ip_tuple
         ip_address = floating_ip.floating_ip_address
         private_key = None
+        floatingip_status = 'DOWN'
         if should_connect:
             private_key = self._get_server_key(server)
+            floatingip_status = 'ACTIVE'
         # call the common method in the parent class
         super(TestNetworkBasicOps, self)._check_public_network_connectivity(
             ip_address, ssh_login, private_key, should_connect, msg,
             self.servers)
+        self.check_floating_ip_status(floating_ip, floatingip_status)
 
     def _disassociate_floating_ips(self):
         floating_ip, server = self.floating_ip_tuple
@@ -350,6 +365,8 @@
         VMs are created with unique keypair so connectivity also asserts that
         floating IP is associated with the new VM instead of the old one
 
+        Verifies that floating IP status is updated correctly after each change
+
 
         """
         self._setup_network_and_servers()
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 188dea8..6c36034 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -241,7 +241,11 @@
             'security_groups': security_groups,
             'tenant_id': tenant.creds.tenant_id
         }
-        return self.create_server(name=name, create_kwargs=create_kwargs)
+        server = self.create_server(name=name, create_kwargs=create_kwargs)
+        self.assertEqual(
+            sorted([s['name'] for s in security_groups]),
+            sorted([s['name'] for s in server['security_groups']]))
+        return server
 
     def _create_tenant_servers(self, tenant, num=1):
         for i in range(num):
diff --git a/tempest/services/compute/xml/servers_client.py b/tempest/services/compute/xml/servers_client.py
index 156d889..06f1b83 100644
--- a/tempest/services/compute/xml/servers_client.py
+++ b/tempest/services/compute/xml/servers_client.py
@@ -349,8 +349,11 @@
             networks = xml_utils.Element("networks")
             server.append(networks)
             for network in kwargs['networks']:
-                s = xml_utils.Element("network", uuid=network['uuid'],
-                                      fixed_ip=network['fixed_ip'])
+                if 'fixed_ip' in network:
+                    s = xml_utils.Element("network", uuid=network['uuid'],
+                                          fixed_ip=network['fixed_ip'])
+                else:
+                    s = xml_utils.Element("network", uuid=network['uuid'])
                 networks.append(s)
 
         if 'meta' in kwargs:
diff --git a/tempest/services/messaging/json/messaging_client.py b/tempest/services/messaging/json/messaging_client.py
index 3e82399..2794ea9 100644
--- a/tempest/services/messaging/json/messaging_client.py
+++ b/tempest/services/messaging/json/messaging_client.py
@@ -48,22 +48,26 @@
     def create_queue(self, queue_name):
         uri = '{0}/queues/{1}'.format(self.uri_prefix, queue_name)
         resp, body = self.put(uri, body=None)
+        self.expected_success(201, resp.status)
         return resp, body
 
     def get_queue(self, queue_name):
         uri = '{0}/queues/{1}'.format(self.uri_prefix, queue_name)
         resp, body = self.get(uri)
+        self.expected_success(204, resp.status)
         return resp, body
 
     def head_queue(self, queue_name):
         uri = '{0}/queues/{1}'.format(self.uri_prefix, queue_name)
         resp, body = self.head(uri)
+        self.expected_success(204, resp.status)
         return resp, body
 
     def delete_queue(self, queue_name):
         uri = '{0}/queues/{1}'.format(self.uri_prefix, queue_name)
-        resp = self.delete(uri)
-        return resp
+        resp, body = self.delete(uri)
+        self.expected_success(204, resp.status)
+        return resp, body
 
     def get_queue_stats(self, queue_name):
         uri = '{0}/queues/{1}/stats'.format(self.uri_prefix, queue_name)
@@ -75,12 +79,14 @@
     def get_queue_metadata(self, queue_name):
         uri = '{0}/queues/{1}/metadata'.format(self.uri_prefix, queue_name)
         resp, body = self.get(uri)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body
 
     def set_queue_metadata(self, queue_name, rbody):
         uri = '{0}/queues/{1}/metadata'.format(self.uri_prefix, queue_name)
         resp, body = self.put(uri, body=json.dumps(rbody))
+        self.expected_success(204, resp.status)
         return resp, body
 
     def post_messages(self, queue_name, rbody):
@@ -90,6 +96,7 @@
                                headers=self.headers)
 
         body = json.loads(body)
+        self.validate_response(queues_schema.post_messages, resp, body)
         return resp, body
 
     def list_messages(self, queue_name):
@@ -126,7 +133,7 @@
 
     def delete_messages(self, message_uri):
         resp, body = self.delete(message_uri)
-        assert(resp['status'] == '204')
+        self.expected_success(204, resp.status)
         return resp, body
 
     def post_claims(self, queue_name, rbody, url_params=False):
@@ -152,10 +159,10 @@
 
     def update_claim(self, claim_uri, rbody):
         resp, body = self.patch(claim_uri, body=json.dumps(rbody))
-        assert(resp['status'] == '204')
+        self.expected_success(204, resp.status)
         return resp, body
 
     def release_claim(self, claim_uri):
         resp, body = self.delete(claim_uri)
-        assert(resp['status'] == '204')
+        self.expected_success(204, resp.status)
         return resp, body
diff --git a/tempest/services/network/resources.py b/tempest/services/network/resources.py
index 2b182d0..a84b4d5 100644
--- a/tempest/services/network/resources.py
+++ b/tempest/services/network/resources.py
@@ -52,7 +52,7 @@
         return
 
     @abc.abstractmethod
-    def show(self):
+    def refresh(self):
         return
 
     def __hash__(self):
@@ -62,7 +62,11 @@
         if not hasattr(self, 'status'):
             return
 
-        return self.client.wait_for_resource_status(self.show, status)
+        def helper_get():
+            self.refresh()
+            return self
+
+        return self.client.wait_for_resource_status(helper_get, status)
 
 
 class DeletableNetwork(DeletableResource):
@@ -116,6 +120,12 @@
 
 class DeletableFloatingIp(DeletableResource):
 
+    def refresh(self, *args, **kwargs):
+        _, result = self.client.show_floatingip(self.id,
+                                                *args,
+                                                **kwargs)
+        super(DeletableFloatingIp, self).update(**result['floatingip'])
+
     def update(self, *args, **kwargs):
         _, result = self.client.update_floatingip(self.id,
                                                   *args,
@@ -172,7 +182,6 @@
     def delete(self):
         self.client.delete_vip(self.id)
 
-    def show(self):
+    def refresh(self):
         _, result = self.client.show_vip(self.id)
-        super(DeletableVip, self).update(**result['vip'])
-        return self
+        super(DeletableVip, self).update(**result['vip'])
\ No newline at end of file
diff --git a/tempest/test.py b/tempest/test.py
index 48e0283..1c6265d 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -29,8 +29,8 @@
 import testtools
 
 from tempest import clients
+from tempest.common import credentials
 import tempest.common.generator.valid_generator as valid
-from tempest.common import isolated_creds
 from tempest import config
 from tempest import exceptions
 from tempest.openstack.common import importutils
@@ -340,31 +340,20 @@
         """
         Returns an OpenStack client manager
         """
-        cls.isolated_creds = isolated_creds.IsolatedCreds(
-            cls.__name__, network_resources=cls.network_resources)
-
         force_tenant_isolation = getattr(cls, 'force_tenant_isolation', None)
-        if CONF.compute.allow_tenant_isolation or force_tenant_isolation:
-            creds = cls.isolated_creds.get_primary_creds()
-            if getattr(cls, '_interface', None):
-                os = clients.Manager(credentials=creds,
-                                     interface=cls._interface,
-                                     service=cls._service)
-            elif interface:
-                os = clients.Manager(credentials=creds,
-                                     interface=interface,
-                                     service=cls._service)
-            else:
-                os = clients.Manager(credentials=creds,
-                                     service=cls._service)
-        else:
-            if getattr(cls, '_interface', None):
-                os = clients.Manager(interface=cls._interface,
-                                     service=cls._service)
-            elif interface:
-                os = clients.Manager(interface=interface, service=cls._service)
-            else:
-                os = clients.Manager(service=cls._service)
+
+        cls.isolated_creds = credentials.get_isolated_credentials(
+            name=cls.__name__, network_resources=cls.network_resources,
+            force_tenant_isolation=force_tenant_isolation,
+        )
+
+        creds = cls.isolated_creds.get_primary_creds()
+        params = dict(credentials=creds, service=cls._service)
+        if getattr(cls, '_interface', None):
+            interface = cls._interface
+        if interface:
+            params['interface'] = interface
+        os = clients.Manager(**params)
         return os
 
     @classmethod
diff --git a/tempest/thirdparty/boto/test.py b/tempest/thirdparty/boto/test.py
index 3496dce..62073bd 100644
--- a/tempest/thirdparty/boto/test.py
+++ b/tempest/thirdparty/boto/test.py
@@ -498,7 +498,10 @@
         def _volume_state():
             volume.update(validate=True)
             try:
-                if volume.status != "available":
+                # NOTE(gmann): Make sure volume is attached.
+                # Checking status as 'not "available"' is not enough to make
+                # sure volume is attached as it can be in "error" state
+                if volume.status == "in-use":
                     volume.detach(force=True)
             except BaseException:
                 LOG.exception("Failed to detach volume %s" % volume)
diff --git a/tox.ini b/tox.ini
index cab59a8..262a27e 100644
--- a/tox.ini
+++ b/tox.ini
@@ -3,79 +3,78 @@
 minversion = 1.6
 skipsdist = True
 
-[testenv]
+[tempestenv]
+sitepackages = True
 setenv = VIRTUAL_ENV={envdir}
          OS_TEST_PATH=./tempest/test_discover
+deps = -r{toxinidir}/requirements.txt
+
+[testenv]
+setenv = VIRTUAL_ENV={envdir}
+         OS_TEST_PATH=./tempest/tests
 usedevelop = True
 install_command = pip install -U {opts} {packages}
-whitelist_externals = bash
-
-
-[testenv:py26]
-setenv = OS_TEST_PATH=./tempest/tests
-commands = python setup.py test --slowest --testr-arg='tempest\.tests {posargs}'
-
-[testenv:py33]
-setenv = OS_TEST_PATH=./tempest/tests
-commands = python setup.py test --slowest --testr-arg='tempest\.tests {posargs}'
-
-[testenv:py34]
-setenv = OS_TEST_PATH=./tempest/tests
-         PYTHONHASHSEED=0
-commands = python setup.py test --slowest --testr-arg='tempest\.tests {posargs}'
-
-[testenv:py27]
-setenv = OS_TEST_PATH=./tempest/tests
-commands = python setup.py test --slowest --testr-arg='tempest\.tests {posargs}'
+whitelist_externals = *
+deps = -r{toxinidir}/requirements.txt
+       -r{toxinidir}/test-requirements.txt
+commands = bash tools/pretty_tox.sh '{posargs}'
 
 [testenv:cover]
 setenv = OS_TEST_PATH=./tempest/tests
 commands = python setup.py testr --coverage --testr-arg='tempest\.tests {posargs}'
-deps = -r{toxinidir}/requirements.txt
-       -r{toxinidir}/test-requirements.txt
 
 [testenv:all]
-sitepackages = True
+sitepackages = {[tempestenv]sitepackages}
+setenv = {[tempestenv]setenv}
+deps = {[tempestenv]deps}
 commands =
   bash tools/pretty_tox.sh '{posargs}'
 
 [testenv:full]
-sitepackages = True
+sitepackages = {[tempestenv]sitepackages}
+setenv = {[tempestenv]setenv}
+deps = {[tempestenv]deps}
 # The regex below is used to select which tests to run and exclude the slow tag:
 # See the testrepostiory bug: https://bugs.launchpad.net/testrepository/+bug/1208610
 commands =
   bash tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty|cli)) {posargs}'
 
 [testenv:full-serial]
+sitepackages = {[tempestenv]sitepackages}
+setenv = {[tempestenv]setenv}
+deps = {[tempestenv]deps}
 # The regex below is used to select which tests to run and exclude the slow tag:
 # See the testrepostiory bug: https://bugs.launchpad.net/testrepository/+bug/1208610
 commands =
   bash tools/pretty_tox_serial.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty|cli)) {posargs}'
 
-[testenv:testr-full]
-sitepackages = True
-commands =
-  bash tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty|cli)) {posargs}'
-
 [testenv:heat-slow]
-sitepackages = True
-setenv = OS_TEST_TIMEOUT=1200
+sitepackages = {[tempestenv]sitepackages}
+setenv = {[tempestenv]setenv}
+         OS_TEST_TIMEOUT=1200
+deps = {[tempestenv]deps}
 # The regex below is used to select heat api/scenario tests tagged as slow.
 commands =
   bash tools/pretty_tox.sh '(?=.*\[.*\bslow\b.*\])(^tempest\.(api|scenario)\.orchestration) {posargs}'
 
 [testenv:large-ops]
-sitepackages = True
+sitepackages = {[tempestenv]sitepackages}
+setenv = {[tempestenv]setenv}
+deps = {[tempestenv]deps}
 commands =
   python setup.py testr --slowest --testr-args='tempest.scenario.test_large_ops {posargs}'
 
 [testenv:smoke]
-sitepackages = True
+sitepackages = {[tempestenv]sitepackages}
+setenv = {[tempestenv]setenv}
+deps = {[tempestenv]deps}
 commands =
    bash tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])((smoke)|(^tempest\.scenario)) {posargs}'
 
 [testenv:smoke-serial]
-sitepackages = True
+sitepackages = {[tempestenv]sitepackages}
+setenv = {[tempestenv]setenv}
+deps = {[tempestenv]deps}
 # This is still serial because neutron doesn't work with parallel. See:
 # https://bugs.launchpad.net/tempest/+bug/1216076 so the neutron smoke
 # job would fail if we moved it to parallel.
@@ -83,19 +82,17 @@
    bash tools/pretty_tox_serial.sh '(?!.*\[.*\bslow\b.*\])((smoke)|(^tempest\.scenario)) {posargs}'
 
 [testenv:stress]
-sitepackages = True
+sitepackages = {[tempestenv]sitepackages}
+setenv = {[tempestenv]setenv}
+deps = {[tempestenv]deps}
 commands =
-    run-tempest-stress -a -d 3600 -S
+    run-tempest-stress '{posargs}'
 
 [testenv:venv]
 commands = {posargs}
-deps = -r{toxinidir}/requirements.txt
-       -r{toxinidir}/test-requirements.txt
 
 [testenv:docs]
 commands = python setup.py build_sphinx {posargs}
-deps = -r{toxinidir}/requirements.txt
-       -r{toxinidir}/test-requirements.txt
 
 [testenv:pep8]
 setenv = PYTHONHASHSEED=0
@@ -103,9 +100,6 @@
    flake8 {posargs}
    {toxinidir}/tools/config/check_uptodate.sh
 
-deps = -r{toxinidir}/requirements.txt
-       -r{toxinidir}/test-requirements.txt
-
 [hacking]
 local-check-factory = tempest.hacking.checks.factory
 import_exceptions = tempest.services