Merge "Add support for compute API v2.70 - os-volume_attachments"
diff --git a/.zuul.yaml b/.zuul.yaml
index e3210fe..0d2005b 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -363,6 +363,7 @@
       - opendev.org/openstack/cinder-tempest-plugin
       - opendev.org/openstack/cloudkitty-tempest-plugin
       - opendev.org/openstack/congress-tempest-plugin
+      - opendev.org/openstack/cyborg-tempest-plugin
       - opendev.org/openstack/designate-tempest-plugin
       - opendev.org/openstack/ec2api-tempest-plugin
       - opendev.org/openstack/freezer
@@ -405,7 +406,6 @@
       - opendev.org/openstack/neutron-vpnaas
       - opendev.org/x/nova-lxd
       - opendev.org/x/novajoin-tempest-plugin
-      - opendev.org/openstack/octavia
       - opendev.org/openstack/octavia-tempest-plugin
       - opendev.org/openstack/oswin-tempest-plugin
       - opendev.org/openstack/panko
@@ -634,7 +634,6 @@
         - tempest-full-queens
         - tempest-full-queens-py3
         - tempest-full-pike
-        - legacy-periodic-tempest-dsvm-neutron-full-ocata
     periodic:
       jobs:
         - tempest-all
diff --git a/HACKING.rst b/HACKING.rst
index 1559fc6..204b3c7 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -457,7 +457,7 @@
 by modifying Tempest's `lib installation script`_ for previous branches
 (because DevStack is branched).
 
-.. _lib installation script: https://git.openstack.org/cgit/openstack-dev/devstack/tree/lib/tempest
+.. _lib installation script: https://opendev.org/openstack/devstack/src/branch/master/lib/tempest
 
 2. Bug fix on core project needing Tempest changes
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/README.rst b/README.rst
index 73930f1..e8206ee 100644
--- a/README.rst
+++ b/README.rst
@@ -61,7 +61,7 @@
 #. You first need to install Tempest. This is done with pip after you check out
    the Tempest repo::
 
-    $ git clone https://git.openstack.org/openstack/tempest
+    $ git clone https://opendev.org/openstack/tempest
     $ pip install tempest/
 
    This can be done within a venv, but the assumption for this guide is that
diff --git a/REVIEWING.rst b/REVIEWING.rst
index 31fedce..498ce66 100644
--- a/REVIEWING.rst
+++ b/REVIEWING.rst
@@ -187,4 +187,4 @@
   Note that such a policy should be used judiciously, as we should strive to
   have two +2's on each patch set, prior to approval.
 
-.. _example: https://review.openstack.org/#/c/611032/
+.. _example: https://review.opendev.org/#/c/611032/
diff --git a/doc/source/plugin.rst b/doc/source/plugin.rst
index dc0e94c..a9e2059 100644
--- a/doc/source/plugin.rst
+++ b/doc/source/plugin.rst
@@ -43,7 +43,7 @@
 In order to create the basic structure with base classes and test directories
 you can use the tempest-plugin-cookiecutter project::
 
-  > pip install -U cookiecutter && cookiecutter https://git.openstack.org/openstack/tempest-plugin-cookiecutter
+  > pip install -U cookiecutter && cookiecutter https://opendev.org/openstack/tempest-plugin-cookiecutter
 
   Cloning into 'tempest-plugin-cookiecutter'...
   remote: Counting objects: 17, done.
diff --git a/releasenotes/notes/add-migrate-volume-and-list-hosts-to-v3-volume-client-library-ad3529260db58f00.yaml b/releasenotes/notes/add-migrate-volume-and-list-hosts-to-v3-volume-client-library-ad3529260db58f00.yaml
new file mode 100644
index 0000000..ca6a78d
--- /dev/null
+++ b/releasenotes/notes/add-migrate-volume-and-list-hosts-to-v3-volume-client-library-ad3529260db58f00.yaml
@@ -0,0 +1,8 @@
+---
+features:
+  - |
+    Add list host API support to the volume v3 client library.
+    This feature enables callers to list all hosts for a given project.
+  - |
+    Add migrate volume API support to the volume v3 client library.
+    This features allows callers to migrate volumes between backends.
diff --git a/releasenotes/notes/correct-port-profile-config-option-d67f5cb31f1bc34c.yaml b/releasenotes/notes/correct-port-profile-config-option-d67f5cb31f1bc34c.yaml
index 7510d47..2830aa2 100644
--- a/releasenotes/notes/correct-port-profile-config-option-d67f5cb31f1bc34c.yaml
+++ b/releasenotes/notes/correct-port-profile-config-option-d67f5cb31f1bc34c.yaml
@@ -1,7 +1,7 @@
 ---
 fixes:
   - |
-    Patch https://review.openstack.org/#/c/499575/ introduced
+    Patch https://review.opendev.org/#/c/499575/ introduced
     support creating Neutron port with certain capabilities.
     Currently capabilities list interpreted as string this change
     fix it.
diff --git a/releasenotes/notes/deprecate-dns_servers-option-0xf2f297ee47a5ff.yaml b/releasenotes/notes/deprecate-dns_servers-option-0xf2f297ee47a5ff.yaml
new file mode 100644
index 0000000..30551cb
--- /dev/null
+++ b/releasenotes/notes/deprecate-dns_servers-option-0xf2f297ee47a5ff.yaml
@@ -0,0 +1,6 @@
+---
+deprecations:
+  - |
+    The config option ``CONF.network.dns_servers`` is no longer used
+    anywhere, so it is deprecated and will be removed in the future.
+
diff --git a/tempest/api/compute/admin/test_quotas.py b/tempest/api/compute/admin/test_quotas.py
index 12c7255..0060ffe 100644
--- a/tempest/api/compute/admin/test_quotas.py
+++ b/tempest/api/compute/admin/test_quotas.py
@@ -212,7 +212,7 @@
     # 'danger' flag.
     @decorators.idempotent_id('7932ab0f-5136-4075-b201-c0e2338df51a')
     def test_update_default_quotas(self):
-        LOG.debug("get the current 'default' quota class values")
+        # get the current 'default' quota class values
         body = (self.adm_client.show_quota_class_set('default')
                 ['quota_class_set'])
         self.assertEqual('default', body.pop('id'))
@@ -224,9 +224,14 @@
             # there is a real chance that we go from -1 (unlimited)
             # to a very small number which causes issues.
             body[quota] = default + 100
-        LOG.debug("update limits for the default quota class set")
+        # update limits for the default quota class set
         update_body = self.adm_client.update_quota_class_set(
             'default', **body)['quota_class_set']
-        LOG.debug("assert that the response has all of the changed values")
+        # assert that the response has all of the changed values
         self.assertThat(update_body.items(),
                         matchers.ContainsAll(body.items()))
+        # check quota values are changed
+        show_body = self.adm_client.show_quota_class_set(
+            'default')['quota_class_set']
+        self.assertThat(show_body.items(),
+                        matchers.ContainsAll(body.items()))
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 93bd817..f6c3e73 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -92,6 +92,7 @@
             validatable=True,
             validation_resources=validation_resources,
             wait_until='ACTIVE')
+        self.addCleanup(self.delete_server, newserver['id'])
         # The server's password should be set to the provided password
         new_password = 'Newpass1234'
         self.client.change_password(newserver['id'], adminPass=new_password)
diff --git a/tempest/api/compute/test_extensions.py b/tempest/api/compute/test_extensions.py
index 34faf5f..12e7fea 100644
--- a/tempest/api/compute/test_extensions.py
+++ b/tempest/api/compute/test_extensions.py
@@ -37,7 +37,7 @@
         ext = CONF.compute_feature_enabled.api_extensions[0]
 
         # Log extensions list
-        extension_list = map(lambda x: x['alias'], extensions)
+        extension_list = [x['alias'] for x in extensions]
         LOG.debug("Nova extensions: %s", ','.join(extension_list))
 
         if ext == 'all':
diff --git a/tempest/api/identity/admin/v3/test_endpoint_groups.py b/tempest/api/identity/admin/v3/test_endpoint_groups.py
index 625568d..7d85dc9 100644
--- a/tempest/api/identity/admin/v3/test_endpoint_groups.py
+++ b/tempest/api/identity/admin/v3/test_endpoint_groups.py
@@ -69,6 +69,7 @@
     @decorators.idempotent_id('7c69e7a1-f865-402d-a2ea-44493017315a')
     def test_create_list_show_check_delete_endpoint_group(self):
         service_id = self._create_service()
+        self.addCleanup(self.services_client.delete_service, service_id)
         name = data_utils.rand_name('service_group')
         description = data_utils.rand_name('description')
         filters = {'service_id': service_id}
@@ -129,6 +130,7 @@
         # Creating an endpoint group so as to check update endpoint group
         # with new values
         service1_id = self._create_service()
+        self.addCleanup(self.services_client.delete_service, service1_id)
         name = data_utils.rand_name('service_group')
         description = data_utils.rand_name('description')
         filters = {'service_id': service1_id}
diff --git a/tempest/api/identity/v3/test_catalog.py b/tempest/api/identity/v3/test_catalog.py
index deec2dc..bc95f0d 100644
--- a/tempest/api/identity/v3/test_catalog.py
+++ b/tempest/api/identity/v3/test_catalog.py
@@ -22,8 +22,8 @@
 
     @decorators.idempotent_id('56b57ced-22b8-4127-9b8a-565dfb0207e2')
     def test_catalog_standardization(self):
-        # http://git.openstack.org/cgit/openstack/service-types-authority
-        # /tree/service-types.yaml
+        # https://opendev.org/openstack/service-types-authority
+        # /src/branch/master/service-types.yaml
         standard_service_values = [{'name': 'keystone', 'type': 'identity'},
                                    {'name': 'nova', 'type': 'compute'},
                                    {'name': 'glance', 'type': 'image'},
diff --git a/tempest/api/network/admin/test_external_network_extension.py b/tempest/api/network/admin/test_external_network_extension.py
index 7e8cc8e..5bd3fce 100644
--- a/tempest/api/network/admin/test_external_network_extension.py
+++ b/tempest/api/network/admin/test_external_network_extension.py
@@ -36,6 +36,7 @@
         body = self.admin_networks_client.create_network(**post_body)
         network = body['network']
         self.addCleanup(
+            test_utils.call_and_ignore_notfound_exc,
             self.admin_networks_client.delete_network, network['id'])
         return network
 
diff --git a/tempest/api/network/admin/test_floating_ips_admin_actions.py b/tempest/api/network/admin/test_floating_ips_admin_actions.py
index be0c4c6..adc4dda 100644
--- a/tempest/api/network/admin/test_floating_ips_admin_actions.py
+++ b/tempest/api/network/admin/test_floating_ips_admin_actions.py
@@ -16,6 +16,7 @@
 from tempest.api.network import base
 from tempest.common import utils
 from tempest import config
+from tempest.lib.common.utils import test_utils
 from tempest.lib import decorators
 
 CONF = config.CONF
@@ -57,14 +58,18 @@
         # Create floating ip from admin user
         floating_ip_admin = self.admin_floating_ips_client.create_floatingip(
             floating_network_id=self.ext_net_id)
-        self.addCleanup(self.admin_floating_ips_client.delete_floatingip,
-                        floating_ip_admin['floatingip']['id'])
+        self.addCleanup(
+            test_utils.call_and_ignore_notfound_exc,
+            self.admin_floating_ips_client.delete_floatingip,
+            floating_ip_admin['floatingip']['id'])
         # Create floating ip from alt user
         body = self.alt_floating_ips_client.create_floatingip(
             floating_network_id=self.ext_net_id)
         floating_ip_alt = body['floatingip']
-        self.addCleanup(self.alt_floating_ips_client.delete_floatingip,
-                        floating_ip_alt['id'])
+        self.addCleanup(
+            test_utils.call_and_ignore_notfound_exc,
+            self.alt_floating_ips_client.delete_floatingip,
+            floating_ip_alt['id'])
         # List floating ips from admin
         body = self.admin_floating_ips_client.list_floatingips()
         floating_ip_ids_admin = [f['id'] for f in body['floatingips']]
@@ -91,8 +96,10 @@
             tenant_id=self.network['tenant_id'],
             port_id=self.port['id'])
         created_floating_ip = body['floatingip']
-        self.addCleanup(self.floating_ips_client.delete_floatingip,
-                        created_floating_ip['id'])
+        self.addCleanup(
+            test_utils.call_and_ignore_notfound_exc,
+            self.floating_ips_client.delete_floatingip,
+            created_floating_ip['id'])
         self.assertIsNotNone(created_floating_ip['id'])
         self.assertIsNotNone(created_floating_ip['tenant_id'])
         self.assertIsNotNone(created_floating_ip['floating_ip_address'])
diff --git a/tempest/api/network/admin/test_negative_quotas.py b/tempest/api/network/admin/test_negative_quotas.py
index 9d1e2a7..0db038d 100644
--- a/tempest/api/network/admin/test_negative_quotas.py
+++ b/tempest/api/network/admin/test_negative_quotas.py
@@ -17,6 +17,7 @@
 from tempest.common import identity
 from tempest.common import utils
 from tempest.lib.common.utils import data_utils
+from tempest.lib.common.utils import test_utils
 from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
 
@@ -58,11 +59,13 @@
         # Create two networks
         n1 = self.admin_networks_client.create_network(
             tenant_id=self.project['id'])
-        self.addCleanup(self.admin_networks_client.delete_network,
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.admin_networks_client.delete_network,
                         n1['network']['id'])
         n2 = self.admin_networks_client.create_network(
             tenant_id=self.project['id'])
-        self.addCleanup(self.admin_networks_client.delete_network,
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.admin_networks_client.delete_network,
                         n2['network']['id'])
 
         # Try to create a third network while the quota is two
@@ -71,5 +74,6 @@
                 r"Quota exceeded for resources: \['network'\].*"):
             n3 = self.admin_networks_client.create_network(
                 tenant_id=self.project['id'])
-            self.addCleanup(self.admin_networks_client.delete_network,
+            self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                            self.admin_networks_client.delete_network,
                             n3['network']['id'])
diff --git a/tempest/api/network/admin/test_ports.py b/tempest/api/network/admin/test_ports.py
index 05363db..edfda6e 100644
--- a/tempest/api/network/admin/test_ports.py
+++ b/tempest/api/network/admin/test_ports.py
@@ -14,6 +14,7 @@
 #    under the License.
 
 from tempest.api.network import base
+from tempest.lib.common.utils import test_utils
 from tempest.lib import decorators
 
 
@@ -37,7 +38,9 @@
                      "binding:host_id": self.host_id}
         body = self.admin_ports_client.create_port(**post_body)
         port = body['port']
-        self.addCleanup(self.admin_ports_client.delete_port, port['id'])
+        self.addCleanup(
+            test_utils.call_and_ignore_notfound_exc,
+            self.admin_ports_client.delete_port, port['id'])
         host_id = port['binding:host_id']
         self.assertIsNotNone(host_id)
         self.assertEqual(self.host_id, host_id)
@@ -47,7 +50,9 @@
         post_body = {"network_id": self.network['id']}
         body = self.admin_ports_client.create_port(**post_body)
         port = body['port']
-        self.addCleanup(self.admin_ports_client.delete_port, port['id'])
+        self.addCleanup(
+            test_utils.call_and_ignore_notfound_exc,
+            self.admin_ports_client.delete_port, port['id'])
         update_body = {"binding:host_id": self.host_id}
         body = self.admin_ports_client.update_port(port['id'], **update_body)
         updated_port = body['port']
@@ -61,7 +66,9 @@
         post_body = {"network_id": self.network['id']}
         body = self.admin_ports_client.create_port(**post_body)
         port = body['port']
-        self.addCleanup(self.admin_ports_client.delete_port, port['id'])
+        self.addCleanup(
+            test_utils.call_and_ignore_notfound_exc,
+            self.admin_ports_client.delete_port, port['id'])
 
         # Update the port's binding attributes so that is now 'bound'
         # to a host
@@ -85,7 +92,8 @@
         body = self.admin_ports_client.create_port(
             network_id=self.network['id'])
         port = body['port']
-        self.addCleanup(self.admin_ports_client.delete_port, port['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.admin_ports_client.delete_port, port['id'])
         body = self.admin_ports_client.show_port(port['id'])
         show_port = body['port']
         self.assertEqual(port['binding:host_id'],
diff --git a/tempest/api/network/admin/test_routers.py b/tempest/api/network/admin/test_routers.py
index 6ce86fb..a4a057c 100644
--- a/tempest/api/network/admin/test_routers.py
+++ b/tempest/api/network/admin/test_routers.py
@@ -20,6 +20,7 @@
 from tempest.common import utils
 from tempest import config
 from tempest.lib.common.utils import data_utils
+from tempest.lib.common.utils import test_utils
 from tempest.lib import decorators
 
 CONF = config.CONF
@@ -38,7 +39,8 @@
         # associate a cleanup with created routers to avoid quota limits
         router = self.create_router(name, admin_state_up,
                                     external_network_id, enable_snat)
-        self.addCleanup(self._cleanup_router, router)
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self._cleanup_router, router)
         return router
 
     @classmethod
@@ -62,7 +64,8 @@
         name = data_utils.rand_name('router-')
         create_body = self.admin_routers_client.create_router(
             name=name, tenant_id=project_id)
-        self.addCleanup(self.admin_routers_client.delete_router,
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.admin_routers_client.delete_router,
                         create_body['router']['id'])
         self.assertEqual(project_id, create_body['router']['tenant_id'])
 
@@ -92,7 +95,8 @@
                 'enable_snat': enable_snat}
             create_body = self.admin_routers_client.create_router(
                 name=name, external_gateway_info=external_gateway_info)
-            self.addCleanup(self.admin_routers_client.delete_router,
+            self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                            self.admin_routers_client.delete_router,
                             create_body['router']['id'])
             # Verify snat attributes after router creation
             self._verify_router_gateway(create_body['router']['id'],
diff --git a/tempest/api/network/admin/test_routers_dvr.py b/tempest/api/network/admin/test_routers_dvr.py
index 93478e6..270f802 100644
--- a/tempest/api/network/admin/test_routers_dvr.py
+++ b/tempest/api/network/admin/test_routers_dvr.py
@@ -18,6 +18,7 @@
 from tempest.api.network import base
 from tempest.common import utils
 from tempest.lib.common.utils import data_utils
+from tempest.lib.common.utils import test_utils
 from tempest.lib import decorators
 
 
@@ -62,7 +63,8 @@
         name = data_utils.rand_name('router')
         router = self.admin_routers_client.create_router(name=name,
                                                          distributed=True)
-        self.addCleanup(self.admin_routers_client.delete_router,
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.admin_routers_client.delete_router,
                         router['router']['id'])
         self.assertTrue(router['router']['distributed'])
 
@@ -82,7 +84,8 @@
         name = data_utils.rand_name('router')
         router = self.admin_routers_client.create_router(name=name,
                                                          distributed=False)
-        self.addCleanup(self.admin_routers_client.delete_router,
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.admin_routers_client.delete_router,
                         router['router']['id'])
         self.assertFalse(router['router']['distributed'])
 
@@ -112,8 +115,8 @@
                                                          ha=False,
                                                          tenant_id=tenant_id)
         router_id = router['router']['id']
-        self.addCleanup(self.admin_routers_client.delete_router,
-                        router_id)
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.admin_routers_client.delete_router, router_id)
         self.assertFalse(router['router']['distributed'])
         router = self.admin_routers_client.update_router(
             router_id, distributed=True)
diff --git a/tempest/api/network/admin/test_routers_negative.py b/tempest/api/network/admin/test_routers_negative.py
index 9356bcc..fdcc977 100644
--- a/tempest/api/network/admin/test_routers_negative.py
+++ b/tempest/api/network/admin/test_routers_negative.py
@@ -18,6 +18,7 @@
 from tempest.api.network import base
 from tempest.common import utils
 from tempest import config
+from tempest.lib.common.utils import test_utils
 from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
 
@@ -42,7 +43,8 @@
         # At first create a address from public_network_id
         port = self.admin_ports_client.create_port(
             network_id=CONF.network.public_network_id)['port']
-        self.addCleanup(self.admin_ports_client.delete_port,
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.admin_ports_client.delete_port,
                         port_id=port['id'])
         # Add used ip and subnet_id in external_fixed_ips
         fixed_ip = {
diff --git a/tempest/api/network/base_security_groups.py b/tempest/api/network/base_security_groups.py
index b8d677a..32f2cdd 100644
--- a/tempest/api/network/base_security_groups.py
+++ b/tempest/api/network/base_security_groups.py
@@ -15,6 +15,7 @@
 
 from tempest.api.network import base
 from tempest.lib.common.utils import data_utils
+from tempest.lib.common.utils import test_utils
 
 
 class BaseSecGroupTest(base.BaseNetworkTest):
@@ -24,7 +25,8 @@
         name = data_utils.rand_name('secgroup-')
         group_create_body = (
             self.security_groups_client.create_security_group(name=name))
-        self.addCleanup(self._delete_security_group,
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self._delete_security_group,
                         group_create_body['security_group']['id'])
         self.assertEqual(group_create_body['security_group']['name'], name)
         return group_create_body, name
diff --git a/tempest/api/network/test_allowed_address_pair.py b/tempest/api/network/test_allowed_address_pair.py
index dec3413..d393207 100644
--- a/tempest/api/network/test_allowed_address_pair.py
+++ b/tempest/api/network/test_allowed_address_pair.py
@@ -17,6 +17,7 @@
 
 from tempest.api.network import base
 from tempest.common import utils
+from tempest.lib.common.utils import test_utils
 from tempest.lib import decorators
 
 
@@ -62,7 +63,8 @@
             network_id=self.network['id'],
             allowed_address_pairs=allowed_address_pairs)
         port_id = body['port']['id']
-        self.addCleanup(self.ports_client.delete_port, port_id)
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.ports_client.delete_port, port_id)
 
         # Confirm port was created with allowed address pair attribute
         body = self.ports_client.list_ports()
@@ -76,7 +78,8 @@
         # Create a port without allowed address pair
         body = self.ports_client.create_port(network_id=self.network['id'])
         port_id = body['port']['id']
-        self.addCleanup(self.ports_client.delete_port, port_id)
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.ports_client.delete_port, port_id)
         if mac_address is None:
             mac_address = self.mac_address
 
@@ -106,7 +109,8 @@
         # Create an ip _address and mac_address through port create
         resp = self.ports_client.create_port(network_id=self.network['id'])
         newportid = resp['port']['id']
-        self.addCleanup(self.ports_client.delete_port, newportid)
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.ports_client.delete_port, newportid)
         ipaddress = resp['port']['fixed_ips'][0]['ip_address']
         macaddress = resp['port']['mac_address']
 
diff --git a/tempest/api/network/test_extra_dhcp_options.py b/tempest/api/network/test_extra_dhcp_options.py
index 0d42033..8e94429 100644
--- a/tempest/api/network/test_extra_dhcp_options.py
+++ b/tempest/api/network/test_extra_dhcp_options.py
@@ -16,6 +16,7 @@
 from tempest.api.network import base
 from tempest.common import utils
 from tempest.lib.common.utils import data_utils
+from tempest.lib.common.utils import test_utils
 from tempest.lib import decorators
 
 
@@ -62,7 +63,8 @@
             network_id=self.network['id'],
             extra_dhcp_opts=self.extra_dhcp_opts)
         port_id = body['port']['id']
-        self.addCleanup(self.ports_client.delete_port, port_id)
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.ports_client.delete_port, port_id)
 
         # Confirm port created has Extra DHCP Options
         body = self.ports_client.list_ports()
diff --git a/tempest/api/network/test_floating_ips.py b/tempest/api/network/test_floating_ips.py
index 504bfa8..9704c73 100644
--- a/tempest/api/network/test_floating_ips.py
+++ b/tempest/api/network/test_floating_ips.py
@@ -18,6 +18,7 @@
 from tempest.common.utils import data_utils
 from tempest.common.utils import net_utils
 from tempest import config
+from tempest.lib.common.utils import test_utils
 from tempest.lib import decorators
 
 CONF = config.CONF
@@ -77,8 +78,10 @@
             floating_network_id=self.ext_net_id,
             port_id=self.ports[0]['id'])
         created_floating_ip = body['floatingip']
-        self.addCleanup(self.floating_ips_client.delete_floatingip,
-                        created_floating_ip['id'])
+        self.addCleanup(
+            test_utils.call_and_ignore_notfound_exc,
+            self.floating_ips_client.delete_floatingip,
+            created_floating_ip['id'])
         self.assertIsNotNone(created_floating_ip['id'])
         self.assertIsNotNone(created_floating_ip['tenant_id'])
         self.assertIsNotNone(created_floating_ip['floating_ip_address'])
@@ -125,14 +128,19 @@
         self.assertIsNone(updated_floating_ip['fixed_ip_address'])
         self.assertIsNone(updated_floating_ip['router_id'])
 
+        # Explicity test deletion of floating IP
+        self.floating_ips_client.delete_floatingip(created_floating_ip['id'])
+
     @decorators.idempotent_id('e1f6bffd-442f-4668-b30e-df13f2705e77')
     def test_floating_ip_delete_port(self):
         # Create a floating IP
         body = self.floating_ips_client.create_floatingip(
             floating_network_id=self.ext_net_id)
         created_floating_ip = body['floatingip']
-        self.addCleanup(self.floating_ips_client.delete_floatingip,
-                        created_floating_ip['id'])
+        self.addCleanup(
+            test_utils.call_and_ignore_notfound_exc,
+            self.floating_ips_client.delete_floatingip,
+            created_floating_ip['id'])
         # Create a port
         port = self.ports_client.create_port(network_id=self.network['id'])
         created_port = port['port']
@@ -158,24 +166,36 @@
             floating_network_id=self.ext_net_id,
             port_id=self.ports[1]['id'])
         created_floating_ip = body['floatingip']
-        self.addCleanup(self.floating_ips_client.delete_floatingip,
-                        created_floating_ip['id'])
+        self.addCleanup(
+            test_utils.call_and_ignore_notfound_exc,
+            self.floating_ips_client.delete_floatingip,
+            created_floating_ip['id'])
         self.assertEqual(created_floating_ip['router_id'], self.router['id'])
         network_name = data_utils.rand_name(self.__class__.__name__)
         network2 = self.networks_client.create_network(
             name=network_name)['network']
-        self.addCleanup(self.networks_client.delete_network,
-                        network2['id'])
+        self.addCleanup(
+            test_utils.call_and_ignore_notfound_exc,
+            self.networks_client.delete_network,
+            network2['id'])
         subnet2 = self.create_subnet(network2)
-        self.addCleanup(self.subnets_client.delete_subnet, subnet2['id'])
+        self.addCleanup(
+            test_utils.call_and_ignore_notfound_exc,
+            self.subnets_client.delete_subnet, subnet2['id'])
         router2 = self.create_router(external_network_id=self.ext_net_id)
-        self.addCleanup(self.routers_client.delete_router, router2['id'])
+        self.addCleanup(
+            test_utils.call_and_ignore_notfound_exc,
+            self.routers_client.delete_router, router2['id'])
         self.create_router_interface(router2['id'], subnet2['id'])
-        self.addCleanup(self.routers_client.remove_router_interface,
-                        router2['id'], subnet_id=subnet2['id'])
+        self.addCleanup(
+            test_utils.call_and_ignore_notfound_exc,
+            self.routers_client.remove_router_interface,
+            router2['id'], subnet_id=subnet2['id'])
         port_other_router = self.create_port(network2)
-        self.addCleanup(self.ports_client.delete_port,
-                        port_other_router['id'])
+        self.addCleanup(
+            test_utils.call_and_ignore_notfound_exc,
+            self.ports_client.delete_port,
+            port_other_router['id'])
         # Associate floating IP to the other port on another router
         floating_ip = self.floating_ips_client.update_floatingip(
             created_floating_ip['id'],
@@ -194,8 +214,10 @@
             port_id=self.ports[1]['id'],
             fixed_ip_address=self.ports[1]['fixed_ips'][0]['ip_address'])
         created_floating_ip = body['floatingip']
-        self.addCleanup(self.floating_ips_client.delete_floatingip,
-                        created_floating_ip['id'])
+        self.addCleanup(
+            test_utils.call_and_ignore_notfound_exc,
+            self.floating_ips_client.delete_floatingip,
+            created_floating_ip['id'])
         self.assertIsNotNone(created_floating_ip['id'])
         self.assertEqual(created_floating_ip['fixed_ip_address'],
                          self.ports[1]['fixed_ips'][0]['ip_address'])
@@ -218,14 +240,16 @@
         body = self.ports_client.create_port(network_id=self.network['id'],
                                              fixed_ips=fixed_ips)
         port = body['port']
-        self.addCleanup(self.ports_client.delete_port, port['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.ports_client.delete_port, port['id'])
         # Create floating ip
         body = self.floating_ips_client.create_floatingip(
             floating_network_id=self.ext_net_id,
             port_id=port['id'],
             fixed_ip_address=list_ips[0])
         floating_ip = body['floatingip']
-        self.addCleanup(self.floating_ips_client.delete_floatingip,
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.floating_ips_client.delete_floatingip,
                         floating_ip['id'])
         self.assertIsNotNone(floating_ip['id'])
         self.assertEqual(floating_ip['fixed_ip_address'], list_ips[0])
diff --git a/tempest/api/network/test_floating_ips_negative.py b/tempest/api/network/test_floating_ips_negative.py
index e904a81..1688c9d 100644
--- a/tempest/api/network/test_floating_ips_negative.py
+++ b/tempest/api/network/test_floating_ips_negative.py
@@ -17,6 +17,7 @@
 from tempest.api.network import base
 from tempest.common import utils
 from tempest import config
+from tempest.lib.common.utils import test_utils
 from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
 
@@ -81,6 +82,7 @@
             floating_network_id=self.ext_net_id)
         floating_ip = body['floatingip']
         self.addCleanup(
+            test_utils.call_and_ignore_notfound_exc,
             self.floating_ips_client.delete_floatingip, floating_ip['id'])
         # Associate floating IP to the other port
         self.assertRaises(
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index ed8eb52..eba1f6c 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -160,7 +160,8 @@
     def test_create_update_delete_network_subnet(self):
         # Create a network
         network = self.create_network()
-        self.addCleanup(self.networks_client.delete_network, network['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.networks_client.delete_network, network['id'])
         net_id = network['id']
         self.assertEqual('ACTIVE', network['status'])
         # Verify network update
@@ -176,6 +177,8 @@
         body = self.subnets_client.update_subnet(subnet_id, name=new_name)
         updated_subnet = body['subnet']
         self.assertEqual(updated_subnet['name'], new_name)
+        # Verify network delete
+        self.networks_client.delete_network(network['id'])
 
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('2bf13842-c93f-4a69-83ed-717d2ec3b44e')
@@ -313,7 +316,8 @@
     @decorators.idempotent_id('3d3852eb-3009-49ec-97ac-5ce83b73010a')
     def test_update_subnet_gw_dns_host_routes_dhcp(self):
         network = self.create_network()
-        self.addCleanup(self.networks_client.delete_network, network['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.networks_client.delete_network, network['id'])
 
         subnet = self.create_subnet(
             network, **self.subnet_dict(['gateway', 'host_routes',
diff --git a/tempest/api/network/test_ports.py b/tempest/api/network/test_ports.py
index 25976ce..93a4631 100644
--- a/tempest/api/network/test_ports.py
+++ b/tempest/api/network/test_ports.py
@@ -23,6 +23,7 @@
 from tempest.common import custom_matchers
 from tempest.common import utils
 from tempest.lib.common.utils import data_utils
+from tempest.lib.common.utils import test_utils
 from tempest.lib import decorators
 from tempest.lib import exceptions
 
@@ -52,7 +53,8 @@
     def _create_subnet(self, network, gateway='',
                        cidr=None, mask_bits=None, **kwargs):
         subnet = self.create_subnet(network, gateway, cidr, mask_bits)
-        self.addCleanup(self.subnets_client.delete_subnet, subnet['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.subnets_client.delete_subnet, subnet['id'])
         return subnet
 
     def _create_network(self, network_name=None, **kwargs):
@@ -60,7 +62,8 @@
             self.__class__.__name__)
         network = self.networks_client.create_network(
             name=network_name, **kwargs)['network']
-        self.addCleanup(self.networks_client.delete_network,
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.networks_client.delete_network,
                         network['id'])
         return network
 
@@ -116,13 +119,15 @@
                             mask_bits=address.prefixlen,
                             **allocation_pools)
         body = self.ports_client.create_port(network_id=net_id)
-        self.addCleanup(self.ports_client.delete_port, body['port']['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.ports_client.delete_port, body['port']['id'])
         port = body['port']
         ip_address = port['fixed_ips'][0]['ip_address']
         start_ip_address = allocation_pools['allocation_pools'][0]['start']
         end_ip_address = allocation_pools['allocation_pools'][0]['end']
         ip_range = netaddr.IPRange(start_ip_address, end_ip_address)
         self.assertIn(ip_address, ip_range)
+        self.ports_client.delete_port(port['id'])
 
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('c9a685bd-e83f-499c-939f-9f7863ca259f')
@@ -168,9 +173,11 @@
         self._create_subnet(network)
         # Create two ports
         port_1 = self.ports_client.create_port(network_id=network['id'])
-        self.addCleanup(self.ports_client.delete_port, port_1['port']['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.ports_client.delete_port, port_1['port']['id'])
         port_2 = self.ports_client.create_port(network_id=network['id'])
-        self.addCleanup(self.ports_client.delete_port, port_2['port']['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.ports_client.delete_port, port_2['port']['id'])
         # List ports filtered by fixed_ips
         port_1_fixed_ip = port_1['port']['fixed_ips'][0]['ip_address']
         fixed_ips = 'ip_address=' + port_1_fixed_ip
@@ -219,11 +226,13 @@
         fixed_ips = [{'subnet_id': subnet['id'], 'ip_address': ip_address_1}]
         port_1 = self.ports_client.create_port(network_id=network['id'],
                                                fixed_ips=fixed_ips)
-        self.addCleanup(self.ports_client.delete_port, port_1['port']['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.ports_client.delete_port, port_1['port']['id'])
         fixed_ips = [{'subnet_id': subnet['id'], 'ip_address': ip_address_2}]
         port_2 = self.ports_client.create_port(network_id=network['id'],
                                                fixed_ips=fixed_ips)
-        self.addCleanup(self.ports_client.delete_port, port_2['port']['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.ports_client.delete_port, port_2['port']['id'])
 
         # Scenario 1: List port1 (port2 is filtered out)
         if ip_address_1[:-1] != ip_address_2[:-1]:
@@ -272,12 +281,14 @@
         network = self._create_network()
         self._create_subnet(network)
         router = self.create_router()
-        self.addCleanup(self.routers_client.delete_router, router['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.routers_client.delete_router, router['id'])
         port = self.ports_client.create_port(network_id=network['id'])
         # Add router interface to port created above
         self.routers_client.add_router_interface(router['id'],
                                                  port_id=port['port']['id'])
-        self.addCleanup(self.routers_client.remove_router_interface,
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.routers_client.remove_router_interface,
                         router['id'], port_id=port['port']['id'])
         # List ports filtered by router_id
         port_list = self.ports_client.list_ports(device_id=router['id'])
@@ -311,7 +322,8 @@
         # Create a port with multiple IP addresses
         port = self.create_port(network,
                                 fixed_ips=fixed_ips)
-        self.addCleanup(self.ports_client.delete_port, port['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.ports_client.delete_port, port['id'])
         self.assertEqual(2, len(port['fixed_ips']))
         check_fixed_ips = [subnet_1['id'], subnet_2['id']]
         for item in port['fixed_ips']:
@@ -334,7 +346,8 @@
         for name in security_groups_names:
             group_create_body = sec_grps_client.create_security_group(
                 name=name)
-            self.addCleanup(self.security_groups_client.delete_security_group,
+            self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                            self.security_groups_client.delete_security_group,
                             group_create_body['security_group']['id'])
             security_groups_list.append(group_create_body['security_group']
                                         ['id'])
@@ -342,7 +355,8 @@
         sec_grp_name = data_utils.rand_name('secgroup')
         security_group = sec_grps_client.create_security_group(
             name=sec_grp_name)
-        self.addCleanup(self.security_groups_client.delete_security_group,
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.security_groups_client.delete_security_group,
                         security_group['security_group']['id'])
         post_body = {
             "name": data_utils.rand_name('port-'),
@@ -351,7 +365,8 @@
             "admin_state_up": True,
             "fixed_ips": fixed_ip_1}
         body = self.ports_client.create_port(**post_body)
-        self.addCleanup(self.ports_client.delete_port, body['port']['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.ports_client.delete_port, body['port']['id'])
         port = body['port']
 
         # Update the port with security groups
@@ -402,7 +417,8 @@
         # Create a new port with user defined mac
         body = self.ports_client.create_port(network_id=self.network['id'],
                                              mac_address=free_mac_address)
-        self.addCleanup(self.ports_client.delete_port, body['port']['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.ports_client.delete_port, body['port']['id'])
         port = body['port']
         body = self.ports_client.show_port(port['id'])
         show_port = body['port']
@@ -418,7 +434,8 @@
         network = self._create_network()
         self._create_subnet(network)
         port = self.create_port(network, security_groups=[])
-        self.addCleanup(self.ports_client.delete_port, port['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.ports_client.delete_port, port['id'])
         self.assertIsNotNone(port['security_groups'])
         self.assertEmpty(port['security_groups'])
 
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index be3cf65..f223fa4 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -20,6 +20,7 @@
 from tempest.common import utils
 from tempest import config
 from tempest.lib.common.utils import data_utils
+from tempest.lib.common.utils import test_utils
 from tempest.lib import decorators
 
 CONF = config.CONF
@@ -89,10 +90,11 @@
         network_name = data_utils.rand_name(self.__class__.__name__)
         network = self.networks_client.create_network(
             name=network_name)['network']
-        self.addCleanup(self.networks_client.delete_network,
-                        network['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.networks_client.delete_network, network['id'])
         subnet = self.create_subnet(network)
-        self.addCleanup(self.subnets_client.delete_subnet, subnet['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.subnets_client.delete_subnet, subnet['id'])
         router = self.create_router()
         self.addCleanup(self.delete_router, router)
         # Add router interface with subnet id
@@ -114,8 +116,8 @@
         network_name = data_utils.rand_name(self.__class__.__name__)
         network = self.networks_client.create_network(
             name=network_name)['network']
-        self.addCleanup(self.networks_client.delete_network,
-                        network['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.networks_client.delete_network, network['id'])
         subnet = self.create_subnet(network)
         self.addCleanup(self.subnets_client.delete_subnet, subnet['id'])
         router = self.create_router()
@@ -126,7 +128,8 @@
         interface = self.routers_client.add_router_interface(
             router['id'],
             port_id=port_body['port']['id'])
-        self.addCleanup(self.routers_client.remove_router_interface,
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.routers_client.remove_router_interface,
                         router['id'], port_id=port_body['port']['id'])
         self.assertIn('subnet_id', interface.keys())
         self.assertIn('port_id', interface.keys())
@@ -135,6 +138,8 @@
             interface['port_id'])
         self.assertEqual(show_port_body['port']['device_id'],
                          router['id'])
+        self.routers_client.remove_router_interface(
+            router['id'], port_id=port_body['port']['id'])
 
     @decorators.idempotent_id('cbe42f84-04c2-11e7-8adb-fa163e4fa634')
     @utils.requires_ext(extension='ext-gw-mode', service='network')
@@ -160,7 +165,8 @@
         # Create a router and set gateway to fixed_ip
         router = self.admin_routers_client.create_router(
             external_gateway_info=external_gateway_info)['router']
-        self.addCleanup(self.admin_routers_client.delete_router,
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.admin_routers_client.delete_router,
                         router_id=router['id'])
         # Examine router's gateway is equal to fixed_ip
         self.assertEqual(router['external_gateway_info'][
@@ -188,10 +194,12 @@
             network_name = data_utils.rand_name(self.__class__.__name__)
             network = self.networks_client.create_network(
                 name=network_name)['network']
-            self.addCleanup(self.networks_client.delete_network,
+            self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                            self.networks_client.delete_network,
                             network['id'])
             subnet = self.create_subnet(network, cidr=next_cidr)
-            self.addCleanup(self.subnets_client.delete_subnet, subnet['id'])
+            self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                            self.subnets_client.delete_subnet, subnet['id'])
             next_cidr = next_cidr.next()
 
             # Add router interface with subnet id
@@ -254,18 +262,20 @@
         network_name = data_utils.rand_name(self.__class__.__name__)
         network01 = self.networks_client.create_network(
             name=network_name)['network']
-        self.addCleanup(self.networks_client.delete_network,
-                        network01['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.networks_client.delete_network, network01['id'])
         network_name = data_utils.rand_name(self.__class__.__name__)
         network02 = self.networks_client.create_network(
             name=network_name)['network']
-        self.addCleanup(self.networks_client.delete_network,
-                        network02['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.networks_client.delete_network, network02['id'])
         subnet01 = self.create_subnet(network01)
-        self.addCleanup(self.subnets_client.delete_subnet, subnet01['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.subnets_client.delete_subnet, subnet01['id'])
         sub02_cidr = self.cidr.next()
         subnet02 = self.create_subnet(network02, cidr=sub02_cidr)
-        self.addCleanup(self.subnets_client.delete_subnet, subnet02['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.subnets_client.delete_subnet, subnet02['id'])
         router = self.create_router()
         self.addCleanup(self.delete_router, router)
         interface01 = self._add_router_interface_with_subnet_id(router['id'],
@@ -282,10 +292,11 @@
         network_name = data_utils.rand_name(self.__class__.__name__)
         network = self.networks_client.create_network(
             name=network_name)['network']
-        self.addCleanup(self.networks_client.delete_network,
-                        network['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.networks_client.delete_network, network['id'])
         subnet = self.create_subnet(network)
-        self.addCleanup(self.subnets_client.delete_subnet, subnet['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.subnets_client.delete_subnet, subnet['id'])
         router = self.create_router()
         self.addCleanup(self.delete_router, router)
         fixed_ip = [{'subnet_id': subnet['id']}]
diff --git a/tempest/api/network/test_security_groups.py b/tempest/api/network/test_security_groups.py
index ffc1fca..ea68005 100644
--- a/tempest/api/network/test_security_groups.py
+++ b/tempest/api/network/test_security_groups.py
@@ -16,6 +16,7 @@
 from tempest.api.network import base_security_groups as base
 from tempest.common import utils
 from tempest.lib.common.utils import data_utils
+from tempest.lib.common.utils import test_utils
 from tempest.lib import decorators
 
 
@@ -49,8 +50,8 @@
         )
 
         sec_group_rule = rule_create_body['security_group_rule']
-        self.addCleanup(self._delete_security_group_rule,
-                        sec_group_rule['id'])
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self._delete_security_group_rule, sec_group_rule['id'])
 
         expected = {'direction': direction, 'protocol': protocol,
                     'ethertype': ethertype, 'port_range_min': port_range_min,
@@ -104,6 +105,8 @@
         self.assertEqual(show_body['security_group']['name'], new_name)
         self.assertEqual(show_body['security_group']['description'],
                          new_description)
+        # Delete security group
+        self._delete_security_group(group_create_body['security_group']['id'])
 
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('cfb99e0e-7410-4a3d-8a0c-959a63ee77e9')
@@ -138,6 +141,8 @@
                          for rule in rule_list_body['security_group_rules']]
             self.assertIn(rule_create_body['security_group_rule']['id'],
                           rule_list)
+            self._delete_security_group_rule(
+                rule_create_body['security_group_rule']['id'])
 
     @decorators.idempotent_id('87dfbcf9-1849-43ea-b1e4-efa3eeae9f71')
     def test_create_security_group_rule_with_additional_args(self):
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index 0e86f05..77ec0f8 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -104,8 +104,8 @@
         body = client.show_server(server_id)['server']
     except lib_exc.NotFound:
         return
-    old_status = server_status = body['status']
-    old_task_state = task_state = _get_task_state(body)
+    old_status = body['status']
+    old_task_state = _get_task_state(body)
     start_time = int(time.time())
     while True:
         time.sleep(client.build_interval)
@@ -213,6 +213,31 @@
              resource_name, resource_id, status, time.time() - start)
 
 
+def wait_for_volume_migration(client, volume_id, new_host):
+    """Waits for a Volume to move to a new host."""
+    body = client.show_volume(volume_id)['volume']
+    host = body['os-vol-host-attr:host']
+    migration_status = body['migration_status']
+    start = int(time.time())
+
+    # new_host is hostname@backend while current_host is hostname@backend#type
+    while migration_status != 'success' or new_host not in host:
+        time.sleep(client.build_interval)
+        body = client.show_volume(volume_id)['volume']
+        host = body['os-vol-host-attr:host']
+        migration_status = body['migration_status']
+
+        if migration_status == 'error':
+            message = ('volume %s failed to migrate.' % (volume_id))
+            raise lib_exc.TempestException(message)
+
+        if int(time.time()) - start >= client.build_timeout:
+            message = ('Volume %s failed to migrate to %s (current %s) '
+                       'within the required time (%s s).' %
+                       (volume_id, new_host, host, client.build_timeout))
+            raise lib_exc.TimeoutException(message)
+
+
 def wait_for_volume_retype(client, volume_id, new_volume_type):
     """Waits for a Volume to have a new volume type."""
     body = client.show_volume(volume_id)['volume']
diff --git a/tempest/config.py b/tempest/config.py
index 24ae3ae..f692a4b 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -685,7 +685,10 @@
     cfg.ListOpt('dns_servers',
                 default=["8.8.8.8", "8.8.4.4"],
                 help="List of dns servers which should be used"
-                     " for subnet creation"),
+                     " for subnet creation",
+                deprecated_for_removal=True,
+                deprecated_reason="This config option is no longer "
+                                  "used anywhere, so it can be removed."),
     cfg.StrOpt('port_vnic_type',
                choices=[None, 'normal', 'direct', 'macvtap'],
                help="vnic_type to use when launching instances"
diff --git a/tempest/lib/api_schema/response/compute/v2_1/volumes.py b/tempest/lib/api_schema/response/compute/v2_1/volumes.py
index c35dae9..d367f2a 100644
--- a/tempest/lib/api_schema/response/compute/v2_1/volumes.py
+++ b/tempest/lib/api_schema/response/compute/v2_1/volumes.py
@@ -50,7 +50,8 @@
                             # If it would come as empty array "[]" then,
                             # those elements can be defined as 'required'.
                         }
-                    }
+                    },
+                    'os-vol-host-attr:host': {'type': 'string'},
                 },
                 'additionalProperties': False,
                 'required': ['id', 'status', 'displayName', 'availabilityZone',
diff --git a/tempest/lib/services/volume/v3/volumes_client.py b/tempest/lib/services/volume/v3/volumes_client.py
index fec2950..2dbdd11 100644
--- a/tempest/lib/services/volume/v3/volumes_client.py
+++ b/tempest/lib/services/volume/v3/volumes_client.py
@@ -35,6 +35,16 @@
             return params
         return urllib.urlencode(params)
 
+    def list_hosts(self):
+        """Lists all hosts summary info that is not disabled.
+
+        https://developer.openstack.org/api-ref/block-storage/v3/index.html#list-all-hosts-for-a-project
+        """
+        resp, body = self.get('os-hosts')
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
     def list_volumes(self, detail=False, params=None):
         """List all the volumes created.
 
@@ -55,6 +65,19 @@
         self.expected_success(200, resp.status)
         return rest_client.ResponseBody(resp, body)
 
+    def migrate_volume(self, volume_id, **kwargs):
+        """Migrate a volume to a new backend
+
+        For a full list of available parameters please refer to the offical
+        API reference:
+
+        https://developer.openstack.org/api-ref/block-storage/v3/index.html#migrate-a-volume
+        """
+        post_body = json.dumps({'os-migrate_volume': kwargs})
+        resp, body = self.post('volumes/%s/action' % volume_id, post_body)
+        self.expected_success(202, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
     def show_volume(self, volume_id):
         """Returns the details of a single volume."""
         url = "volumes/%s" % volume_id
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index d09f20c..86d37f1 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -346,8 +346,10 @@
     def create_volume_type(self, client=None, name=None, backend_name=None):
         if not client:
             client = self.os_admin.volume_types_client_latest
-        randomized_name = name or data_utils.rand_name(
-            'volume-type-' + self.__class__.__name__)
+        if not name:
+            class_name = self.__class__.__name__
+            name = data_utils.rand_name(class_name + '-volume-type')
+        randomized_name = data_utils.rand_name('scenario-type-' + name)
 
         LOG.debug("Creating a volume type: %s on backend %s",
                   randomized_name, backend_name)
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 7992585..f46c7e8 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -292,11 +292,14 @@
                                               % CONF.network.build_timeout)
 
         _, new_nic = self.diff_list[0]
-        ssh_client.exec_command("sudo ip addr add %s/%s dev %s" % (
-                                new_port['fixed_ips'][0]['ip_address'],
-                                CONF.network.project_network_mask_bits,
-                                new_nic))
-        ssh_client.exec_command("sudo ip link set %s up" % new_nic)
+        ip_output = ssh_client.exec_command('ip a')
+        ip_address = new_port['fixed_ips'][0]['ip_address']
+        ip_mask = CONF.network.project_network_mask_bits
+        # check if the address is not already in use, if not, set it
+        if ' ' + ip_address + '/' + str(ip_mask) not in ip_output:
+            ssh_client.exec_command("sudo ip addr add %s/%s dev %s" % (
+                                    ip_address, ip_mask, new_nic))
+            ssh_client.exec_command("sudo ip link set %s up" % new_nic)
 
     def _get_server_nics(self, ssh_client):
         reg = re.compile(r'(?P<num>\d+): (?P<nic_name>\w+)[@]?.*:')
diff --git a/tempest/scenario/test_volume_migrate_attached.py b/tempest/scenario/test_volume_migrate_attached.py
index c54bb38..106500e 100644
--- a/tempest/scenario/test_volume_migrate_attached.py
+++ b/tempest/scenario/test_volume_migrate_attached.py
@@ -33,6 +33,9 @@
      * Write to the volume
      * Perform a cinder retype --on-demand of the volume to type of backend #2
      * Check written content of migrated volume
+     * Check the type of the volume has been updated.
+     * Check the volume is still in-use and the migration was successful.
+     * Check that the same volume is attached to the instance.
     """
 
     credentials = ['primary', 'admin']
@@ -78,7 +81,8 @@
                                         'src_backend': backend_source,
                                         'dst': dest_body['name'],
                                         'dst_backend': backend_dest})
-        return source_body['name'], dest_body['name']
+        return ({'name': source_body['name'], 'host': backend_source},
+                {'name': dest_body['name'], 'host': backend_dest})
 
     def _volume_retype_with_migration(self, volume_id, new_volume_type):
         # NOTE: The 'on-demand' migration requires admin operation, so
@@ -93,7 +97,7 @@
     @decorators.attr(type='slow')
     @decorators.idempotent_id('deadd2c2-beef-4dce-98be-f86765ff311b')
     @utils.services('compute', 'volume')
-    def test_volume_migrate_attached(self):
+    def test_volume_retype_attached(self):
         LOG.info("Creating keypair and security group")
         keypair = self.create_keypair()
         security_group = self._create_security_group()
@@ -104,11 +108,11 @@
 
         # create an instance from volume
         LOG.info("Booting instance from volume")
-        volume_origin = self.create_volume(imageRef=CONF.compute.image_ref,
-                                           volume_type=source_type)
+        volume_id = self.create_volume(imageRef=CONF.compute.image_ref,
+                                       volume_type=source_type['name'])['id']
 
-        instance = self._boot_instance_from_volume(volume_origin['id'],
-                                                   keypair, security_group)
+        instance = self._boot_instance_from_volume(volume_id, keypair,
+                                                   security_group)
 
         # write content to volume on instance
         LOG.info("Setting timestamp in instance %s", instance['id'])
@@ -118,9 +122,11 @@
                                           server=instance)
 
         # retype volume with migration from backend #1 to backend #2
-        LOG.info("Retyping Volume %s to new type %s", volume_origin['id'],
-                 dest_type)
-        self._volume_retype_with_migration(volume_origin['id'], dest_type)
+        LOG.info("Retyping Volume %s to new type %s", volume_id,
+                 dest_type['name'])
+        # This method calls for the retype of the volume before calling a
+        # waiter that asserts that the volume type has changed successfully.
+        self._volume_retype_with_migration(volume_id, dest_type['name'])
 
         # check the content of written file
         LOG.info("Getting timestamp in postmigrated instance %s",
@@ -129,3 +135,82 @@
                                         private_key=keypair['private_key'],
                                         server=instance)
         self.assertEqual(timestamp, timestamp2)
+
+        # Assert that the volume is on the new host, is still in-use and has a
+        # migration_status of success
+        volume = self.admin_volumes_client.show_volume(volume_id)['volume']
+        # dest_type is host@backend, os-vol-host-attr:host is host@backend#type
+        self.assertIn(dest_type['host'], volume['os-vol-host-attr:host'])
+        self.assertEqual('in-use', volume['status'])
+        self.assertEqual('success', volume['migration_status'])
+
+        # Assert that the same volume id is attached to the instance, ensuring
+        # the os-migrate_volume_completion Cinder API has been called.
+        attached_volumes = self.servers_client.list_volume_attachments(
+            instance['id'])['volumeAttachments']
+        self.assertEqual(volume_id, attached_volumes[0]['id'])
+
+    @decorators.attr(type='slow')
+    @decorators.idempotent_id('fe47b1ed-640e-4e3b-a090-200e25607362')
+    @utils.services('compute', 'volume')
+    def test_volume_migrate_attached(self):
+        LOG.info("Creating keypair and security group")
+        keypair = self.create_keypair()
+        security_group = self._create_security_group()
+
+        LOG.info("Creating volume")
+        # Create a unique volume type to avoid using the backend default
+        migratable_type = self.create_volume_type()['name']
+        volume_id = self.create_volume(imageRef=CONF.compute.image_ref,
+                                       volume_type=migratable_type)['id']
+        volume = self.admin_volumes_client.show_volume(volume_id)
+
+        LOG.info("Booting instance from volume")
+        instance = self._boot_instance_from_volume(volume_id, keypair,
+                                                   security_group)
+
+        # Identify the source and destination hosts for the migration
+        src_host = volume['volume']['os-vol-host-attr:host']
+
+        # Select the first c-vol host that isn't hosting the volume as the dest
+        # host['host_name'] should take the format of host@backend.
+        # src_host should take the format of host@backend#type
+        hosts = self.admin_volumes_client.list_hosts()['hosts']
+        for host in hosts:
+            if (host['service'] == 'cinder-volume' and
+                not src_host.startswith(host['host_name'])):
+                dest_host = host['host_name']
+                break
+
+        ip_instance = self.get_server_ip(instance)
+        timestamp = self.create_timestamp(ip_instance,
+                                          private_key=keypair['private_key'],
+                                          server=instance)
+
+        LOG.info("Migrating Volume %s from host %s to host %s",
+                 volume_id, src_host, dest_host)
+        self.admin_volumes_client.migrate_volume(volume_id, host=dest_host)
+
+        # This waiter asserts that the migration_status is success and that
+        # the volume has moved to the dest_host
+        waiters.wait_for_volume_migration(self.admin_volumes_client, volume_id,
+                                          dest_host)
+
+        # check the content of written file
+        LOG.info("Getting timestamp in postmigrated instance %s",
+                 instance['id'])
+        timestamp2 = self.get_timestamp(ip_instance,
+                                        private_key=keypair['private_key'],
+                                        server=instance)
+        self.assertEqual(timestamp, timestamp2)
+
+        # Assert that the volume is in-use
+        volume = self.admin_volumes_client.show_volume(volume_id)['volume']
+        self.assertEqual('in-use', volume['status'])
+
+        # Assert that the same volume id is attached to the instance, ensuring
+        # the os-migrate_volume_completion Cinder API has been called
+        attached_volumes = self.servers_client.list_volume_attachments(
+            instance['id'])['volumeAttachments']
+        attached_volume_id = attached_volumes[0]['id']
+        self.assertEqual(volume_id, attached_volume_id)
diff --git a/tempest/tests/common/test_waiters.py b/tempest/tests/common/test_waiters.py
index 938d226..d56e8a4 100644
--- a/tempest/tests/common/test_waiters.py
+++ b/tempest/tests/common/test_waiters.py
@@ -148,3 +148,68 @@
         list_interfaces.assert_has_calls([mock.call('server_id'),
                                           mock.call('server_id')])
         sleep.assert_called_once_with(client.build_interval)
+
+
+class TestVolumeWaiters(base.TestCase):
+    vol_migrating_src_host = {
+        'volume': {'migration_status': 'migrating',
+                   'os-vol-host-attr:host': 'src_host@backend#type'}}
+    vol_migrating_dst_host = {
+        'volume': {'migration_status': 'migrating',
+                   'os-vol-host-attr:host': 'dst_host@backend#type'}}
+    vol_migration_success = {
+        'volume': {'migration_status': 'success',
+                   'os-vol-host-attr:host': 'dst_host@backend#type'}}
+    vol_migration_error = {
+        'volume': {'migration_status': 'error',
+                   'os-vol-host-attr:host': 'src_host@backend#type'}}
+
+    def test_wait_for_volume_migration_timeout(self):
+        show_volume = mock.MagicMock(return_value=self.vol_migrating_src_host)
+        client = mock.Mock(spec=volumes_client.VolumesClient,
+                           resource_type="volume",
+                           build_interval=1,
+                           build_timeout=1,
+                           show_volume=show_volume)
+        self.patch('time.time', side_effect=[0., client.build_timeout + 1.])
+        self.patch('time.sleep')
+        self.assertRaises(lib_exc.TimeoutException,
+                          waiters.wait_for_volume_migration,
+                          client, mock.sentinel.volume_id, 'dst_host')
+
+    def test_wait_for_volume_migration_error(self):
+        show_volume = mock.MagicMock(side_effect=[
+            self.vol_migrating_src_host,
+            self.vol_migrating_src_host,
+            self.vol_migration_error])
+        client = mock.Mock(spec=volumes_client.VolumesClient,
+                           resource_type="volume",
+                           build_interval=1,
+                           build_timeout=1,
+                           show_volume=show_volume)
+        self.patch('time.time', return_value=0.)
+        self.patch('time.sleep')
+        self.assertRaises(lib_exc.TempestException,
+                          waiters.wait_for_volume_migration,
+                          client, mock.sentinel.volume_id, 'dst_host')
+
+    def test_wait_for_volume_migration_success_and_dst(self):
+        show_volume = mock.MagicMock(side_effect=[
+            self.vol_migrating_src_host,
+            self.vol_migrating_dst_host,
+            self.vol_migration_success])
+        client = mock.Mock(spec=volumes_client.VolumesClient,
+                           resource_type="volume",
+                           build_interval=1,
+                           build_timeout=1,
+                           show_volume=show_volume)
+        self.patch('time.time', return_value=0.)
+        self.patch('time.sleep')
+        waiters.wait_for_volume_migration(
+            client, mock.sentinel.volume_id, 'dst_host')
+
+        # Assert that we wait until migration_status is success and dst_host is
+        # part of the returned os-vol-host-attr:host.
+        show_volume.assert_has_calls([mock.call(mock.sentinel.volume_id),
+                                      mock.call(mock.sentinel.volume_id),
+                                      mock.call(mock.sentinel.volume_id)])
diff --git a/tools/generate-tempest-plugins-list.py b/tools/generate-tempest-plugins-list.py
index 3772774..746cb34 100644
--- a/tools/generate-tempest-plugins-list.py
+++ b/tools/generate-tempest-plugins-list.py
@@ -19,9 +19,9 @@
 #
 # In order to function correctly, the environment in which the
 # script runs must have
-#   * network access to the review.openstack.org Gerrit API
+#   * network access to the review.opendev.org Gerrit API
 #     working directory
-#   * network access to https://git.openstack.org/cgit
+#   * network access to https://opendev.org/openstack
 
 import json
 import re
@@ -36,7 +36,7 @@
     from urllib2 import HTTPError
 
 
-url = 'https://review.openstack.org/projects/'
+url = 'https://review.opendev.org/projects/'
 
 # This is what a project looks like
 '''
@@ -59,7 +59,8 @@
 def has_tempest_plugin(proj):
     try:
         r = urllib.urlopen(
-            "https://git.openstack.org/cgit/%s/plain/setup.cfg" % proj)
+            "https://opendev.org/%s/raw/branch/"
+            "master/setup.cfg" % proj)
     except HTTPError as err:
         if err.code == 404:
             return False
diff --git a/tools/generate-tempest-plugins-list.sh b/tools/generate-tempest-plugins-list.sh
index 17a4059..b4e5430 100755
--- a/tools/generate-tempest-plugins-list.sh
+++ b/tools/generate-tempest-plugins-list.sh
@@ -28,9 +28,9 @@
 #   * the environment variable git_dir pointing to the location
 #   * of said git repositories
 #   ) OR (
-#   * network access to the review.openstack.org Gerrit API
+#   * network access to the review.opendev.org Gerrit API
 #     working directory
-#   * network access to https://git.openstack.org/cgit
+#   * network access to https://opendev.org/openstack
 #   ))
 #
 # If a file named doc/source/data/tempest-plugins-registry.header or
@@ -69,8 +69,8 @@
 i=0
 for plugin in ${sorted_plugins}; do
     i=$((i+1))
-    giturl="https://git.openstack.org/openstack/${plugin}"
-    gitlink="https://git.openstack.org/cgit/openstack/${plugin}"
+    giturl="https://opendev.org/openstack/${plugin}"
+    gitlink="https://opendev.org/openstack/${plugin}"
     printf "%-3s %-${name_col_len}s %s\n" "$i" "${plugin}" "\`${giturl} <${gitlink}>\`__"
 done
 
diff --git a/tools/tempest-plugin-sanity.sh b/tools/tempest-plugin-sanity.sh
index 703dce2..b291fcc 100644
--- a/tools/tempest-plugin-sanity.sh
+++ b/tools/tempest-plugin-sanity.sh
@@ -46,23 +46,23 @@
 # List of projects having tempest plugin stale or unmaintained for a long time
 # (6 months or more)
 # TODO(masayukig): Some of these can be removed from BLACKLIST in the future.
-# airship-tempest-plugin: https://review.openstack.org/#/c/634387/
-# barbican-tempest-plugin: https://review.openstack.org/#/c/634631/
-# intel-nfv-ci-tests: https://review.openstack.org/#/c/634640/
-# networking-ansible: https://review.openstack.org/#/c/634647/
-# networking-generic-switch: https://review.openstack.org/#/c/634846/
-# networking-l2gw-tempest-plugin: https://review.openstack.org/#/c/635093/
-# networking-midonet: https://review.openstack.org/#/c/635096/
-# networking-plumgrid: https://review.openstack.org/#/c/635096/
-# networking-spp: https://review.openstack.org/#/c/635098/
-# neutron-dynamic-routing: https://review.openstack.org/#/c/637718/
-# neutron-vpnaas: https://review.openstack.org/#/c/637719/
-# nova-lxd: https://review.openstack.org/#/c/638334/
-# valet: https://review.openstack.org/#/c/638339/
-# vitrage-tempest-plugin: https://review.openstack.org/#/c/639003/
+# barbican-tempest-plugin: https://review.opendev.org/#/c/634631/
+# cyborg-tempest-plugin: https://review.opendev.org/659687
+# intel-nfv-ci-tests: https://review.opendev.org/#/c/634640/
+# networking-ansible: https://review.opendev.org/#/c/634647/
+# networking-generic-switch: https://review.opendev.org/#/c/634846/
+# networking-l2gw-tempest-plugin: https://review.opendev.org/#/c/635093/
+# networking-midonet: https://review.opendev.org/#/c/635096/
+# networking-plumgrid: https://review.opendev.org/#/c/635096/
+# networking-spp: https://review.opendev.org/#/c/635098/
+# neutron-dynamic-routing: https://review.opendev.org/#/c/637718/
+# neutron-vpnaas: https://review.opendev.org/#/c/637719/
+# nova-lxd: https://review.opendev.org/#/c/638334/
+# valet: https://review.opendev.org/#/c/638339/
+
 BLACKLIST="
-airship-tempest-plugin
 barbican-tempest-plugin
+cyborg-tempest-plugin
 intel-nfv-ci-tests
 networking-ansible
 networking-generic-switch
@@ -74,18 +74,17 @@
 neutron-vpnaas
 nova-lxd
 valet
-vitrage-tempest-plugin
 "
 
 # Function to clone project using zuul-cloner or from git
 function clone_project() {
     if [ -e /usr/zuul-env/bin/zuul-cloner ]; then
         /usr/zuul-env/bin/zuul-cloner --cache-dir /opt/git \
-        https://git.openstack.org \
+        https://opendev.org \
         openstack/"$1"
 
     elif [ -e /usr/bin/git ]; then
-        /usr/bin/git clone https://git.openstack.org/openstack/"$1" \
+        /usr/bin/git clone https://opendev.org/openstack/"$1" \
         openstack/"$1"
 
     fi
@@ -94,7 +93,7 @@
 # function to create virtualenv to perform sanity operation
 function prepare_workspace() {
     SANITY_DIR=$(pwd)
-    virtualenv --clear "$SANITY_DIR"/.venv
+    virtualenv -p python3 --clear "$SANITY_DIR"/.venv
     export TVENV="$SANITY_DIR/tools/with_venv.sh"
     cd "$SANITY_DIR"
 
diff --git a/tox.ini b/tox.ini
index 230249f..48a2baa 100644
--- a/tox.ini
+++ b/tox.ini
@@ -9,7 +9,7 @@
     VIRTUAL_ENV={envdir}
     OS_TEST_PATH=./tempest/test_discover
 deps =
-    -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
+    -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
     -r{toxinidir}/requirements.txt
 
 [testenv]
@@ -25,7 +25,7 @@
 install_command = pip install {opts} {packages}
 whitelist_externals = *
 deps =
-    -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
+    -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
     -r{toxinidir}/requirements.txt
     -r{toxinidir}/test-requirements.txt
 commands =
@@ -173,7 +173,7 @@
 
 [testenv:venv]
 deps =
-  -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
+  -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
   -r{toxinidir}/requirements.txt
   -r{toxinidir}/doc/requirements.txt
 commands = {posargs}
@@ -188,7 +188,7 @@
 [testenv:docs]
 basepython = python3
 deps =
-  -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
+  -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
   -r{toxinidir}/requirements.txt
   -r{toxinidir}/doc/requirements.txt
 commands =
@@ -221,7 +221,7 @@
 import_exceptions = tempest.services
 
 [flake8]
-# E125 is a won't fix until https://github.com/jcrocholl/pep8/issues/126 is resolved.  For further detail see https://review.openstack.org/#/c/36788/
+# E125 is a won't fix until https://github.com/jcrocholl/pep8/issues/126 is resolved.  For further detail see https://review.opendev.org/#/c/36788/
 # E123 skipped because it is ignored by default in the default pep8
 # E129 skipped because it is too limiting when combined with other rules
 # W504 skipped because it is overeager and unnecessary
@@ -234,7 +234,7 @@
 [testenv:releasenotes]
 basepython = python3
 deps =
-  -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
+  -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
   -r{toxinidir}/requirements.txt
   -r{toxinidir}/doc/requirements.txt
 commands =
@@ -265,6 +265,7 @@
 
 [testenv:plugin-sanity-check]
 # perform tempest plugin sanity
+basepython = python3
 whitelist_externals = bash
 commands =
   bash tools/tempest-plugin-sanity.sh