Merge "Raise renew_delay in TestNetworkBasicOps:test_subnet_details"
diff --git a/.zuul.yaml b/.zuul.yaml
index ef9b0eb..462841c 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -272,6 +272,20 @@
       tempest_concurrency: 2
 
 - job:
+    name: tempest-slow-py3
+    parent: tempest-slow
+    vars:
+      devstack_localrc:
+        USE_PYTHON3: true
+      devstack_services:
+        s-account: false
+        s-container: false
+        s-object: false
+        s-proxy: false
+        # without Swift, c-bak cannot run (in the Gate at least)
+        c-bak: false
+
+- job:
     name: tempest-full-rocky
     parent: tempest-full
     nodeset: openstack-single-node-xenial
@@ -513,6 +527,8 @@
               # tools/ is not here since this relies on a script in tools/.
         - tempest-slow:
             irrelevant-files: *tempest-irrelevant-files
+        - tempest-slow-py3:
+            irrelevant-files: *tempest-irrelevant-files
         - nova-live-migration:
             voting: false
             irrelevant-files: *tempest-irrelevant-files
@@ -556,7 +572,7 @@
       jobs:
         - nova-multiattach:
             irrelevant-files: *tempest-irrelevant-files
-        - tempest-slow:
+        - tempest-slow-py3:
             irrelevant-files: *tempest-irrelevant-files
         - neutron-grenade-multinode:
             irrelevant-files: *tempest-irrelevant-files
diff --git a/tempest/api/compute/admin/test_servers_on_multinodes.py b/tempest/api/compute/admin/test_servers_on_multinodes.py
index 5cd98f4..bebc8c5 100644
--- a/tempest/api/compute/admin/test_servers_on_multinodes.py
+++ b/tempest/api/compute/admin/test_servers_on_multinodes.py
@@ -105,7 +105,7 @@
         asserts the servers are in the group and on different hosts.
         """
         hosts = self._create_servers_with_group('anti-affinity')
-        hostnames = hosts.values()
+        hostnames = list(hosts.values())
         self.assertNotEqual(hostnames[0], hostnames[1],
                             'Servers are on the same host: %s' % hosts)
 
@@ -120,6 +120,6 @@
         asserts the servers are in the group and on same host.
         """
         hosts = self._create_servers_with_group('affinity')
-        hostnames = hosts.values()
+        hostnames = list(hosts.values())
         self.assertEqual(hostnames[0], hostnames[1],
                          'Servers are on the different hosts: %s' % hosts)
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 09dd409..624a99e 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -457,7 +457,7 @@
             else:
                 msg = ('When validation.connect_method equals floating, '
                        'validation_resources cannot be None')
-                raise exceptions.InvalidParam(invalid_param=msg)
+                raise lib_exc.InvalidParam(invalid_param=msg)
         elif CONF.validation.connect_method == 'fixed':
             addresses = server['addresses'][CONF.validation.network_for_ssh]
             for address in addresses:
diff --git a/tempest/api/identity/admin/v3/test_domain_configuration.py b/tempest/api/identity/admin/v3/test_domain_configuration.py
index c4e0622..c0b18ca 100644
--- a/tempest/api/identity/admin/v3/test_domain_configuration.py
+++ b/tempest/api/identity/admin/v3/test_domain_configuration.py
@@ -21,6 +21,10 @@
 
 
 class DomainConfigurationTestJSON(base.BaseIdentityV3AdminTest):
+    # NOTE: force_tenant_isolation is true in the base class by default but
+    # overridden to false here to allow test execution for clouds using the
+    # pre-provisioned credentials provider.
+    force_tenant_isolation = False
 
     custom_config = {
         "identity": {
diff --git a/tempest/api/identity/admin/v3/test_tokens.py b/tempest/api/identity/admin/v3/test_tokens.py
index 8ae43d6..5f1b58d 100644
--- a/tempest/api/identity/admin/v3/test_tokens.py
+++ b/tempest/api/identity/admin/v3/test_tokens.py
@@ -42,10 +42,10 @@
         user = self.create_test_user(password=user_password)
 
         # Create a couple projects
-        project1_name = data_utils.rand_name(name='project')
+        project1_name = data_utils.rand_name(name=self.__class__.__name__)
         project1 = self.setup_test_project(name=project1_name)
 
-        project2_name = data_utils.rand_name(name='project')
+        project2_name = data_utils.rand_name(name=self.__class__.__name__)
         project2 = self.setup_test_project(name=project2_name)
         self.addCleanup(self.projects_client.delete_project, project2['id'])
 
diff --git a/tempest/api/identity/admin/v3/test_trusts.py b/tempest/api/identity/admin/v3/test_trusts.py
index 83b3c30..54a5ab7 100644
--- a/tempest/api/identity/admin/v3/test_trusts.py
+++ b/tempest/api/identity/admin/v3/test_trusts.py
@@ -49,7 +49,8 @@
 
     def create_trustor_and_roles(self):
         # create a project that trusts will be granted on
-        trustor_project_name = data_utils.rand_name(name='project')
+        trustor_project_name = data_utils.rand_name(
+            name=self.__class__.__name__)
         project = self.projects_client.create_project(
             trustor_project_name,
             domain_id=CONF.identity.default_domain_id)['project']
diff --git a/tempest/common/compute.py b/tempest/common/compute.py
index 375113d..1489e60 100644
--- a/tempest/common/compute.py
+++ b/tempest/common/compute.py
@@ -168,10 +168,19 @@
                   'imageRef': image_id,
                   'size': CONF.volume.volume_size}
         volume = volumes_client.create_volume(**params)
-        waiters.wait_for_volume_resource_status(volumes_client,
-                                                volume['volume']['id'],
-                                                'available')
-
+        try:
+            waiters.wait_for_volume_resource_status(volumes_client,
+                                                    volume['volume']['id'],
+                                                    'available')
+        except Exception:
+            with excutils.save_and_reraise_exception():
+                try:
+                    volumes_client.delete_volume(volume['volume']['id'])
+                    volumes_client.wait_for_resource_deletion(
+                        volume['volume']['id'])
+                except Exception as exc:
+                    LOG.exception("Deleting volume %s failed, exception %s",
+                                  volume['volume']['id'], exc)
         bd_map_v2 = [{
             'uuid': volume['volume']['id'],
             'source_type': 'volume',
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index 52ccfa9..49d9742 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -98,6 +98,7 @@
     def get_nic_name_by_ip(self, address):
         cmd = "ip -o addr | awk '/%s/ {print $2}'" % address
         nic = self.exec_command(cmd)
+        LOG.debug('(get_nic_name_by_ip) Command result: %s', nic)
         return nic.strip().strip(":").split('@')[0].lower()
 
     def get_dns_servers(self):
diff --git a/tempest/lib/services/clients.py b/tempest/lib/services/clients.py
index e7ac423..90debd9 100644
--- a/tempest/lib/services/clients.py
+++ b/tempest/lib/services/clients.py
@@ -18,7 +18,6 @@
 import importlib
 import inspect
 import sys
-import warnings
 
 from debtcollector import removals
 from oslo_log import log as logging
@@ -35,7 +34,6 @@
 from tempest.lib.services import placement
 from tempest.lib.services import volume
 
-warnings.simplefilter("once")
 LOG = logging.getLogger(__name__)
 
 
diff --git a/tempest/tests/cmd/test_run.py b/tempest/tests/cmd/test_run.py
index e159cdc..5091841 100644
--- a/tempest/tests/cmd/test_run.py
+++ b/tempest/tests/cmd/test_run.py
@@ -108,6 +108,27 @@
         subprocess.call(['stestr', 'init'])
         self.assertRunExit(['tempest', 'run', '--regex', 'passing'], 0)
 
+    def test_tempest_run_failing(self):
+        self.assertRunExit(['tempest', 'run', '--regex', 'failing'], 1)
+
+    def test_tempest_run_failing_with_stestr_repository(self):
+        subprocess.call(['stestr', 'init'])
+        self.assertRunExit(['tempest', 'run', '--regex', 'failing'], 1)
+
+    def test_tempest_run_blackregex_failing(self):
+        self.assertRunExit(['tempest', 'run', '--black-regex', 'failing'], 0)
+
+    def test_tempest_run_blackregex_failing_with_stestr_repository(self):
+        subprocess.call(['stestr', 'init'])
+        self.assertRunExit(['tempest', 'run', '--black-regex', 'failing'], 0)
+
+    def test_tempest_run_blackregex_passing(self):
+        self.assertRunExit(['tempest', 'run', '--black-regex', 'passing'], 1)
+
+    def test_tempest_run_blackregex_passing_with_stestr_repository(self):
+        subprocess.call(['stestr', 'init'])
+        self.assertRunExit(['tempest', 'run', '--black-regex', 'passing'], 1)
+
     def test_tempest_run_fails(self):
         self.assertRunExit(['tempest', 'run'], 1)