Merge "Migration tests in v2.6 should not repeat all migration tests."
diff --git a/.zuul.yaml b/.zuul.yaml
index ee0ae9c..17ec1fc 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -164,6 +164,16 @@
       tempest_concurrency: 2
 
 - job:
+    name: tempest-full-rocky
+    parent: tempest-full
+    override-checkout: stable/rocky
+
+- job:
+    name: tempest-full-rocky-py3
+    parent: tempest-full-py3
+    override-checkout: stable/rocky
+
+- job:
     name: tempest-full-queens
     parent: tempest-full
     override-checkout: stable/queens
@@ -314,6 +324,26 @@
               - ^setup.cfg$
               - ^tempest/hacking/.*$
               - ^tempest/tests/.*$
+        - tempest-full-rocky:
+            irrelevant-files:
+              - ^(test-|)requirements.txt$
+              - ^.*\.rst$
+              - ^doc/.*$
+              - ^etc/.*$
+              - ^releasenotes/.*$
+              - ^setup.cfg$
+              - ^tempest/hacking/.*$
+              - ^tempest/tests/.*$
+        - tempest-full-rocky-py3:
+            irrelevant-files:
+              - ^(test-|)requirements.txt$
+              - ^.*\.rst$
+              - ^doc/.*$
+              - ^etc/.*$
+              - ^releasenotes/.*$
+              - ^setup.cfg$
+              - ^tempest/hacking/.*$
+              - ^tempest/tests/.*$
         - tempest-full-queens:
             irrelevant-files:
               - ^(test-|)requirements.txt$
@@ -422,6 +452,8 @@
               - ^tempest/tests/.*$
     periodic-stable:
       jobs:
+        - tempest-full-rocky
+        - tempest-full-rocky-py3
         - tempest-full-queens
         - tempest-full-queens-py3
         - tempest-full-pike
diff --git a/README.rst b/README.rst
index c93e19f..0a130dc 100644
--- a/README.rst
+++ b/README.rst
@@ -111,15 +111,18 @@
 
     $ tempest run --workspace cloud-01
 
-   There is also the option to use testr directly, or any `testr`_ based test
-   runner, like `ostestr`_. For example, from the workspace dir run::
+   There is also the option to use `stestr`_ directly. For example, from
+   the workspace dir run::
 
-    $ ostestr --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario))'
+    $ stestr run --black-regex '\[.*\bslow\b.*\]' '^tempest\.(api|scenario)'
 
-   will run the same set of tests as the default gate jobs.
+   will run the same set of tests as the default gate jobs. Or you can
+   use `unittest`_ compatible test runners such as `testr`_, `pytest`_ etc.
 
+.. _unittest: https://docs.python.org/3/library/unittest.html
 .. _testr: https://testrepository.readthedocs.org/en/latest/MANUAL.html
-.. _ostestr: https://docs.openstack.org/os-testr/latest/
+.. _stestr: https://stestr.readthedocs.org/en/latest/MANUAL.html
+.. _pytest: https://docs.pytest.org/en/latest/
 
 Library
 -------
diff --git a/releasenotes/notes/removal-deprecated-volume-config-options-21c4412f3c600923.yaml b/releasenotes/notes/removal-deprecated-volume-config-options-21c4412f3c600923.yaml
new file mode 100644
index 0000000..32147c7
--- /dev/null
+++ b/releasenotes/notes/removal-deprecated-volume-config-options-21c4412f3c600923.yaml
@@ -0,0 +1,24 @@
+---
+upgrade:
+  - |
+    Below config option was deprecated for removal since juno release.
+    It's time to remove it as all supported stable branches and Tempest plugins
+    are good to handle it.
+
+    * ``[volume_feature_enabled].api_v1``
+
+    Also Tempest removes the below corresponding service clients alias from
+    client.py which were being set based on above removed config option.
+
+    * self.backups_client
+    * self.encryption_types_client
+    * self.snapshots_client
+    * self.volume_availability_zone_client
+    * self.volume_hosts_client
+    * self.volume_limits_client
+    * self.volume_qos_client
+    * self.volume_quotas_client
+    * self.volume_services_client
+    * self.volume_types_client
+    * self.volumes_client
+    * self.volumes_extension_client
diff --git a/tempest/api/compute/admin/test_aggregates.py b/tempest/api/compute/admin/test_aggregates.py
index c9d5733..7a3bfdf 100644
--- a/tempest/api/compute/admin/test_aggregates.py
+++ b/tempest/api/compute/admin/test_aggregates.py
@@ -209,26 +209,27 @@
         az_name = data_utils.rand_name(self.az_name_prefix)
         aggregate = self._create_test_aggregate(availability_zone=az_name)
 
-        # Find a host that has not been added to other zone,
-        # for one host can't be added to different zones.
+        # Find a host that has not been added to other availability zone,
+        # for one host can't be added to different availability zones.
         aggregates = self.client.list_aggregates()['aggregates']
         hosts_in_zone = []
-        for v in aggregates:
-            if v['availability_zone']:
-                hosts_in_zone.extend(v['hosts'])
+        for agg in aggregates:
+            if agg['availability_zone']:
+                hosts_in_zone.extend(agg['hosts'])
         hosts = [v for v in self.hosts_available if v not in hosts_in_zone]
         if not hosts:
-            raise self.skipException("All hosts are already in other zones, "
-                                     "so can't add host to aggregate.")
+            raise self.skipException("All hosts are already in other "
+                                     "availability zones, so can't add "
+                                     "host to aggregate. \nAggregates list: "
+                                     "%s" % aggregates)
         host = hosts[0]
 
         self.client.add_host(aggregate['id'], host=host)
         self.addCleanup(self.client.remove_host, aggregate['id'], host=host)
-        admin_servers_client = self.os_admin.servers_client
         server = self.create_test_server(availability_zone=az_name,
                                          wait_until='ACTIVE')
-        body = admin_servers_client.show_server(server['id'])['server']
-        self.assertEqual(host, body['OS-EXT-SRV-ATTR:host'])
+        server_host = self.get_host_for_server(server['id'])
+        self.assertEqual(host, server_host)
 
 
 class AggregatesAdminTestV241(AggregatesAdminTestBase):
diff --git a/tempest/api/compute/admin/test_migrations.py b/tempest/api/compute/admin/test_migrations.py
index e030575..83f2e61 100644
--- a/tempest/api/compute/admin/test_migrations.py
+++ b/tempest/api/compute/admin/test_migrations.py
@@ -114,8 +114,7 @@
             raise self.skipException(msg)
 
         server = self.create_test_server(wait_until="ACTIVE")
-        src_host = self.admin_servers_client.show_server(
-            server['id'])['server']['OS-EXT-SRV-ATTR:host']
+        src_host = self.get_host_for_server(server['id'])
 
         self.admin_servers_client.migrate_server(server['id'])
 
@@ -131,8 +130,7 @@
 
         waiters.wait_for_server_status(self.servers_client,
                                        server['id'], 'ACTIVE')
-        dst_host = self.admin_servers_client.show_server(
-            server['id'])['server']['OS-EXT-SRV-ATTR:host']
+        dst_host = self.get_host_for_server(server['id'])
         assert_func(src_host, dst_host)
 
     @decorators.idempotent_id('4bf0be52-3b6f-4746-9a27-3143636fe30d')
diff --git a/tempest/api/compute/admin/test_servers_on_multinodes.py b/tempest/api/compute/admin/test_servers_on_multinodes.py
index d32a5b4..5cd98f4 100644
--- a/tempest/api/compute/admin/test_servers_on_multinodes.py
+++ b/tempest/api/compute/admin/test_servers_on_multinodes.py
@@ -28,7 +28,7 @@
     def resource_setup(cls):
         super(ServersOnMultiNodesTest, cls).resource_setup()
         cls.server01 = cls.create_test_server(wait_until='ACTIVE')['id']
-        cls.host01 = cls._get_host(cls.server01)
+        cls.host01 = cls.get_host_for_server(cls.server01)
 
     @classmethod
     def skip_checks(cls):
@@ -38,11 +38,6 @@
             raise cls.skipException(
                 "Less than 2 compute nodes, skipping multi-nodes test.")
 
-    @classmethod
-    def _get_host(cls, server_id):
-        return cls.os_admin.servers_client.show_server(
-            server_id)['server']['OS-EXT-SRV-ATTR:host']
-
     def _create_servers_with_group(self, policy):
         group_id = self.create_test_server_group(policy=[policy])['id']
         hints = {'group': group_id}
@@ -61,7 +56,7 @@
         hosts = {}
         for server in servers:
             self.assertIn(server['id'], server_group['members'])
-            hosts[server['id']] = self._get_host(server['id'])
+            hosts[server['id']] = self.get_host_for_server(server['id'])
 
         return hosts
 
@@ -73,7 +68,7 @@
         hints = {'same_host': self.server01}
         server02 = self.create_test_server(scheduler_hints=hints,
                                            wait_until='ACTIVE')['id']
-        host02 = self._get_host(server02)
+        host02 = self.get_host_for_server(server02)
         self.assertEqual(self.host01, host02)
 
     @decorators.idempotent_id('cc7ca884-6e3e-42a3-a92f-c522fcf25e8e')
@@ -84,7 +79,7 @@
         hints = {'different_host': self.server01}
         server02 = self.create_test_server(scheduler_hints=hints,
                                            wait_until='ACTIVE')['id']
-        host02 = self._get_host(server02)
+        host02 = self.get_host_for_server(server02)
         self.assertNotEqual(self.host01, host02)
 
     @decorators.idempotent_id('7869cc84-d661-4e14-9f00-c18cdc89cf57')
@@ -96,7 +91,7 @@
         hints = {'different_host': [self.server01]}
         server02 = self.create_test_server(scheduler_hints=hints,
                                            wait_until='ACTIVE')['id']
-        host02 = self._get_host(server02)
+        host02 = self.get_host_for_server(server02)
         self.assertNotEqual(self.host01, host02)
 
     @decorators.idempotent_id('f8bd0867-e459-45f5-ba53-59134552fe04')
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 7fbb994..ff2f99c 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -208,19 +208,6 @@
                 raise
 
     @classmethod
-    def clear_resources(cls, resource_name, resources, resource_del_func):
-        LOG.debug('Clearing %s: %s', resource_name,
-                  ','.join(map(str, resources)))
-        for res_id in resources:
-            try:
-                test_utils.call_and_ignore_notfound_exc(
-                    resource_del_func, res_id)
-            except Exception as exc:
-                LOG.exception('Exception raised deleting %s: %s',
-                              resource_name, res_id)
-                LOG.exception(exc)
-
-    @classmethod
     def create_test_server(cls, validatable=False, volume_backed=False,
                            validation_resources=None, **kwargs):
         """Wrapper utility that returns a test server.
@@ -604,8 +591,9 @@
         self.addCleanup(client.delete_flavor, flavor['id'])
         return flavor
 
-    def get_host_for_server(self, server_id):
-        server_details = self.admin_servers_client.show_server(server_id)
+    @classmethod
+    def get_host_for_server(cls, server_id):
+        server_details = cls.admin_servers_client.show_server(server_id)
         return server_details['server']['OS-EXT-SRV-ATTR:host']
 
     def get_host_other_than(self, server_id):
diff --git a/tempest/api/network/admin/test_dhcp_agent_scheduler.py b/tempest/api/network/admin/test_dhcp_agent_scheduler.py
index 8315c5d..4631ea9 100644
--- a/tempest/api/network/admin/test_dhcp_agent_scheduler.py
+++ b/tempest/api/network/admin/test_dhcp_agent_scheduler.py
@@ -63,7 +63,6 @@
     def test_add_remove_network_from_dhcp_agent(self):
         # The agent is now bound to the network, we can free the port
         self.ports_client.delete_port(self.port['id'])
-        self.ports.remove(self.port)
         agent = dict()
         agent['agent_type'] = None
         body = self.admin_agents_client.list_agents()
diff --git a/tempest/api/network/admin/test_routers.py b/tempest/api/network/admin/test_routers.py
index 8cdb41e..a7355f3 100644
--- a/tempest/api/network/admin/test_routers.py
+++ b/tempest/api/network/admin/test_routers.py
@@ -32,7 +32,6 @@
 
     def _cleanup_router(self, router):
         self.delete_router(router)
-        self.routers.remove(router)
 
     def _create_router(self, name=None, admin_state_up=False,
                        external_network_id=None, enable_snat=None):
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index 8670165..9032fdc 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -88,9 +88,6 @@
     @classmethod
     def resource_setup(cls):
         super(BaseNetworkTest, cls).resource_setup()
-        cls.subnets = []
-        cls.ports = []
-        cls.routers = []
         cls.ethertype = "IPv" + str(cls._ip_version)
         if cls._ip_version == 4:
             cls.cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
@@ -155,7 +152,6 @@
         cls.addClassResourceCleanup(test_utils.call_and_ignore_notfound_exc,
                                     cls.subnets_client.delete_subnet,
                                     subnet['id'])
-        cls.subnets.append(subnet)
         return subnet
 
     @classmethod
@@ -166,7 +162,6 @@
         port = body['port']
         cls.addClassResourceCleanup(test_utils.call_and_ignore_notfound_exc,
                                     cls.ports_client.delete_port, port['id'])
-        cls.ports.append(port)
         return port
 
     @classmethod
@@ -194,7 +189,6 @@
         router = body['router']
         cls.addClassResourceCleanup(test_utils.call_and_ignore_notfound_exc,
                                     cls.delete_router, router)
-        cls.routers.append(router)
         return router
 
     @classmethod
diff --git a/tempest/api/network/test_dhcp_ipv6.py b/tempest/api/network/test_dhcp_ipv6.py
index 9d6d700..0730d58 100644
--- a/tempest/api/network/test_dhcp_ipv6.py
+++ b/tempest/api/network/test_dhcp_ipv6.py
@@ -56,6 +56,9 @@
     def resource_setup(cls):
         super(NetworksTestDHCPv6, cls).resource_setup()
         cls.network = cls.create_network()
+        cls.ports = []
+        cls.subnets = []
+        cls.routers = []
 
     def _remove_from_list_by_index(self, things_list, elem):
         for index, i in enumerate(things_list):
@@ -90,8 +93,10 @@
 
     def _get_ips_from_subnet(self, **kwargs):
         subnet = self.create_subnet(self.network, **kwargs)
+        self.subnets.append(subnet)
         port_mac = data_utils.rand_mac_address()
         port = self.create_port(self.network, mac_address=port_mac)
+        self.ports.append(port)
         real_ip = next(iter(port['fixed_ips']), None)['ip_address']
         eui_ip = str(netutils.get_ipv6_addr_by_EUI64(
             subnet['cidr'], port_mac))
@@ -182,16 +187,21 @@
                 kwargs_dhcp = {'ipv6_address_mode': 'dhcpv6-stateful'}
                 if order == "slaac_first":
                     subnet_slaac = self.create_subnet(self.network, **kwargs)
+                    self.subnets.append(subnet_slaac)
                     subnet_dhcp = self.create_subnet(
                         self.network, **kwargs_dhcp)
+                    self.subnets.append(subnet_dhcp)
                 else:
                     subnet_dhcp = self.create_subnet(
                         self.network, **kwargs_dhcp)
+                    self.subnets.append(subnet_dhcp)
                     subnet_slaac = self.create_subnet(self.network, **kwargs)
+                    self.subnets.append(subnet_slaac)
                 port_mac = data_utils.rand_mac_address()
                 eui_ip = str(netutils.get_ipv6_addr_by_EUI64(
                     subnet_slaac['cidr'], port_mac))
                 port = self.create_port(self.network, mac_address=port_mac)
+                self.ports.append(port)
                 real_ips = dict([(k['subnet_id'], k['ip_address'])
                                  for k in port['fixed_ips']])
                 real_dhcp_ip, real_eui_ip = [real_ips[sub['id']]
@@ -228,16 +238,21 @@
                           'ipv6_address_mode': add_mode}
                 if order == "slaac_first":
                     subnet_slaac = self.create_subnet(self.network, **kwargs)
+                    self.subnets.append(subnet_slaac)
                     subnet_dhcp = self.create_subnet(
                         self.network, ip_version=4)
+                    self.subnets.append(subnet_dhcp)
                 else:
                     subnet_dhcp = self.create_subnet(
                         self.network, ip_version=4)
+                    self.subnets.append(subnet_dhcp)
                     subnet_slaac = self.create_subnet(self.network, **kwargs)
+                    self.subnets.append(subnet_slaac)
                 port_mac = data_utils.rand_mac_address()
                 eui_ip = str(netutils.get_ipv6_addr_by_EUI64(
                     subnet_slaac['cidr'], port_mac))
                 port = self.create_port(self.network, mac_address=port_mac)
+                self.ports.append(port)
                 real_ips = dict([(k['subnet_id'], k['ip_address'])
                                  for k in port['fixed_ips']])
                 real_dhcp_ip, real_eui_ip = [real_ips[sub['id']]
@@ -267,7 +282,9 @@
                       'ipv6_address_mode': add_mode}
             kwargs = dict((k, v) for k, v in kwargs.items() if v)
             subnet = self.create_subnet(self.network, **kwargs)
+            self.subnets.append(subnet)
             port = self.create_port(self.network)
+            self.ports.append(port)
             port_ip = next(iter(port['fixed_ips']), None)['ip_address']
             self._clean_network()
             msg = ('Real IP address is {0} and it is NOT on '
@@ -289,6 +306,7 @@
                       'ipv6_address_mode': add_mode}
             kwargs = dict((k, v) for k, v in kwargs.items() if v)
             subnet = self.create_subnet(self.network, **kwargs)
+            self.subnets.append(subnet)
             ip_range = netaddr.IPRange(subnet["allocation_pools"][0]["start"],
                                        subnet["allocation_pools"][0]["end"])
             ip = netaddr.IPAddress(random.randrange(ip_range.first,
@@ -296,6 +314,7 @@
             port = self.create_port(self.network,
                                     fixed_ips=[{'subnet_id': subnet['id'],
                                                 'ip_address': ip}])
+            self.ports.append(port)
             port_ip = next(iter(port['fixed_ips']), None)['ip_address']
             self._clean_network()
             self.assertEqual(port_ip, ip,
@@ -310,6 +329,7 @@
         kwargs = {'ipv6_ra_mode': 'dhcpv6-stateful',
                   'ipv6_address_mode': 'dhcpv6-stateful'}
         subnet = self.create_subnet(self.network, **kwargs)
+        self.subnets.append(subnet)
         ip_range = netaddr.IPRange(subnet["allocation_pools"][0]["start"],
                                    subnet["allocation_pools"][0]["end"])
         ip = netaddr.IPAddress(random.randrange(
@@ -327,14 +347,16 @@
         kwargs = {'ipv6_ra_mode': 'dhcpv6-stateful',
                   'ipv6_address_mode': 'dhcpv6-stateful'}
         subnet = self.create_subnet(self.network, **kwargs)
+        self.subnets.append(subnet)
         ip_range = netaddr.IPRange(subnet["allocation_pools"][0]["start"],
                                    subnet["allocation_pools"][0]["end"])
         ip = netaddr.IPAddress(random.randrange(
             ip_range.first, ip_range.last)).format()
-        self.create_port(self.network,
-                         fixed_ips=[
-                             {'subnet_id': subnet['id'],
-                              'ip_address': ip}])
+        port = self.create_port(self.network,
+                                fixed_ips=[
+                                    {'subnet_id': subnet['id'],
+                                     'ip_address': ip}])
+        self.ports.append(port)
         self.assertRaisesRegex(lib_exc.Conflict,
                                "IpAddressAlreadyAllocated|IpAddressInUse",
                                self.create_port,
@@ -344,7 +366,9 @@
 
     def _create_subnet_router(self, kwargs):
         subnet = self.create_subnet(self.network, **kwargs)
+        self.subnets.append(subnet)
         router = self.create_router(admin_state_up=True)
+        self.routers.append(router)
         port = self.create_router_interface(router['id'],
                                             subnet['id'])
         body = self.ports_client.show_port(port['port_id'])
diff --git a/tempest/api/network/test_floating_ips.py b/tempest/api/network/test_floating_ips.py
index b4bb88e..504bfa8 100644
--- a/tempest/api/network/test_floating_ips.py
+++ b/tempest/api/network/test_floating_ips.py
@@ -64,8 +64,10 @@
         cls.router = cls.create_router(external_network_id=cls.ext_net_id)
         cls.create_router_interface(cls.router['id'], cls.subnet['id'])
         # Create two ports one each for Creation and Updating of floatingIP
+        cls.ports = []
         for i in range(2):
-            cls.create_port(cls.network)
+            port = cls.create_port(cls.network)
+            cls.ports.append(port)
 
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('62595970-ab1c-4b7f-8fcc-fddfe55e8718')
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index 3ff12e4..8b03631 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -29,7 +29,6 @@
 
     def _cleanup_router(self, router):
         self.delete_router(router)
-        self.routers.remove(router)
 
     def _create_router(self, name=None, admin_state_up=False,
                        external_network_id=None, enable_snat=None):
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index 93638b8..4b97b80 100644
--- a/tempest/api/volume/test_volumes_snapshots.py
+++ b/tempest/api/volume/test_volumes_snapshots.py
@@ -155,6 +155,30 @@
         self.assertEqual(volume['snapshot_id'], src_snap['id'])
         self.assertEqual(volume['size'], src_size + 1)
 
+    @decorators.idempotent_id('053d8870-8282-4fff-9dbb-99cb58bb5e0a')
+    def test_volume_from_snapshot_no_size(self):
+        # Creates a volume from a snapshot defaulting to original size
+        src_size = CONF.volume.volume_size
+
+        src_vol = self.create_volume(size=src_size)
+        src_snap = self.create_snapshot(src_vol['id'])
+        # Destination volume without specifying a size
+        dst_vol = self.create_volume(snapshot_id=src_snap['id'])
+
+        # NOTE(zhufl): dst_vol is created based on snapshot, so dst_vol
+        # should be deleted before deleting snapshot, otherwise deleting
+        # snapshot will end with status 'error-deleting'. This depends on
+        # the implementation mechanism of vendors, generally speaking,
+        # some verdors will use "virtual disk clone" which will promote
+        # disk clone speed, and in this situation the "disk clone"
+        # is just a relationship between volume and snapshot.
+        self.addCleanup(self.delete_volume, self.volumes_client, dst_vol['id'])
+
+        volume = self.volumes_client.show_volume(dst_vol['id'])['volume']
+        # Should allow
+        self.assertEqual(volume['snapshot_id'], src_snap['id'])
+        self.assertEqual(volume['size'], src_size)
+
     @decorators.idempotent_id('bbcfa285-af7f-479e-8c1a-8c34fc16543c')
     @testtools.skipUnless(CONF.volume_feature_enabled.backup,
                           "Cinder backup is disabled")
diff --git a/tempest/clients.py b/tempest/clients.py
index 4f2846e..204ce08 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -222,22 +222,6 @@
 
     def _set_volume_clients(self):
 
-        if CONF.volume_feature_enabled.api_v1:
-            self.backups_client = self.volume_v1.BackupsClient()
-            self.encryption_types_client = \
-                self.volume_v1.EncryptionTypesClient()
-            self.snapshots_client = self.volume_v1.SnapshotsClient()
-            self.volume_availability_zone_client = \
-                self.volume_v1.AvailabilityZoneClient()
-            self.volume_hosts_client = self.volume_v1.HostsClient()
-            self.volume_limits_client = self.volume_v1.LimitsClient()
-            self.volume_qos_client = self.volume_v1.QosSpecsClient()
-            self.volume_quotas_client = self.volume_v1.QuotasClient()
-            self.volume_services_client = self.volume_v1.ServicesClient()
-            self.volume_types_client = self.volume_v1.TypesClient()
-            self.volumes_client = self.volume_v1.VolumesClient()
-            self.volumes_extension_client = self.volume_v1.ExtensionsClient()
-
         # if only api_v3 is enabled, all these clients should be available
         if (CONF.volume_feature_enabled.api_v2 or
             CONF.volume_feature_enabled.api_v3):
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index aa333b3..6c2fee8 100644
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -205,10 +205,6 @@
 def verify_cinder_api_versions(os, update):
     # Check cinder api versions
     versions = _get_api_versions(os, 'cinder')
-    if (CONF.volume_feature_enabled.api_v1 !=
-            contains_version('v1.', versions)):
-        print_and_or_update('api_v1', 'volume-feature-enabled',
-                            not CONF.volume_feature_enabled.api_v1, update)
     if (CONF.volume_feature_enabled.api_v2 !=
             contains_version('v2.', versions)):
         print_and_or_update('api_v2', 'volume-feature-enabled',
@@ -283,6 +279,9 @@
     if not results.get(service):
         results[service] = {}
     extensions_opt = get_enabled_extensions(service)
+    if not extensions_opt:
+        LOG.info("'%s' has no api_extensions set.", service)
+        return results
     if extensions_opt[0] == 'all':
         results[service]['extensions'] = extensions
         return results
diff --git a/tempest/config.py b/tempest/config.py
index 0f3fa54..a8a3bc3 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -470,7 +470,7 @@
                      "entry 'all' indicates all filters that are included "
                      "with nova are enabled. Empty list indicates all filters "
                      "are disabled. The full list of available filters is in "
-                     "nova.conf: DEFAULT.scheduler_available_filters. If the "
+                     "nova.conf: filter_scheduler.enabled_filters. If the "
                      "default value is overridden in nova.conf by the test "
                      "environment (which means that a different set of "
                      "filters is enabled than what is included in Nova by "
@@ -836,13 +836,6 @@
                 help='A list of enabled volume extensions with a special '
                      'entry all which indicates every extension is enabled. '
                      'Empty list indicates all extensions are disabled'),
-    cfg.BoolOpt('api_v1',
-                default=False,
-                help="Is the v1 volume API enabled",
-                deprecated_for_removal=True,
-                deprecated_reason="The v1 volume API has been deprecated "
-                                  "since Juno release, and the API will be "
-                                  "removed."),
     cfg.BoolOpt('api_v2',
                 default=True,
                 help="Is the v2 volume API enabled",
diff --git a/tempest/lib/services/volume/v3/snapshots_client.py b/tempest/lib/services/volume/v3/snapshots_client.py
index 0cb5e54..cae65b2 100644
--- a/tempest/lib/services/volume/v3/snapshots_client.py
+++ b/tempest/lib/services/volume/v3/snapshots_client.py
@@ -22,7 +22,6 @@
 
 class SnapshotsClient(rest_client.RestClient):
     """Client class to send CRUD Volume Snapshot V3 API requests."""
-    create_resp = 202
 
     def list_snapshots(self, detail=False, **params):
         """List all the snapshot.
@@ -66,7 +65,7 @@
         post_body = json.dumps({'snapshot': kwargs})
         resp, body = self.post('snapshots', post_body)
         body = json.loads(body)
-        self.expected_success(self.create_resp, resp.status)
+        self.expected_success(202, resp.status)
         return rest_client.ResponseBody(resp, body)
 
     def update_snapshot(self, snapshot_id, **kwargs):
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index cdc30b9..dff50a9 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -704,6 +704,11 @@
         else:
             raise lib_exc.InvalidConfiguration()
 
+    @classmethod
+    def get_host_for_server(cls, server_id):
+        server_details = cls.os_admin.servers_client.show_server(server_id)
+        return server_details['server']['OS-EXT-SRV-ATTR:host']
+
 
 class NetworkScenarioTest(ScenarioTest):
     """Base class for network scenario tests.
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index 7452ee6..8827610 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -102,10 +102,6 @@
                                        'ACTIVE')
         self._check_network_connectivity(server, keypair, floating_ip)
 
-    def _get_host_for_server(self, server_id):
-        body = self.admin_servers_client.show_server(server_id)['server']
-        return body['OS-EXT-SRV-ATTR:host']
-
     @decorators.idempotent_id('61f1aa9a-1573-410e-9054-afa557cab021')
     @decorators.attr(type='slow')
     @utils.services('compute', 'network')
@@ -220,7 +216,7 @@
         keypair = self.create_keypair()
         server = self._setup_server(keypair)
         floating_ip = self._setup_network(server, keypair)
-        src_host = self._get_host_for_server(server['id'])
+        src_host = self.get_host_for_server(server['id'])
         self._wait_server_status_and_check_network_connectivity(
             server, keypair, floating_ip)
 
@@ -230,7 +226,7 @@
         self.servers_client.confirm_resize_server(server['id'])
         self._wait_server_status_and_check_network_connectivity(
             server, keypair, floating_ip)
-        dst_host = self._get_host_for_server(server['id'])
+        dst_host = self.get_host_for_server(server['id'])
 
         self.assertNotEqual(src_host, dst_host)
 
@@ -246,7 +242,7 @@
         keypair = self.create_keypair()
         server = self._setup_server(keypair)
         floating_ip = self._setup_network(server, keypair)
-        src_host = self._get_host_for_server(server['id'])
+        src_host = self.get_host_for_server(server['id'])
         self._wait_server_status_and_check_network_connectivity(
             server, keypair, floating_ip)
 
@@ -256,6 +252,6 @@
         self.servers_client.revert_resize_server(server['id'])
         self._wait_server_status_and_check_network_connectivity(
             server, keypair, floating_ip)
-        dst_host = self._get_host_for_server(server['id'])
+        dst_host = self.get_host_for_server(server['id'])
 
         self.assertEqual(src_host, dst_host)
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index f5805ef..28a2d64 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -282,11 +282,8 @@
 
         # Verify servers are on different compute nodes
         if self.multi_node:
-            adm_get_server = self.os_admin.servers_client.show_server
-            new_host = adm_get_server(server["id"])["server"][
-                "OS-EXT-SRV-ATTR:host"]
-            host_list = [adm_get_server(s)["server"]["OS-EXT-SRV-ATTR:host"]
-                         for s in self.servers]
+            new_host = self.get_host_for_server(server["id"])
+            host_list = [self.get_host_for_server(s) for s in self.servers]
             self.assertNotIn(new_host, host_list,
                              message="Failed to boot servers on different "
                                      "Compute nodes.")
diff --git a/tempest/tests/cmd/test_tempest_init.py b/tempest/tests/cmd/test_tempest_init.py
index 5f39ac9..9042b12 100644
--- a/tempest/tests/cmd/test_tempest_init.py
+++ b/tempest/tests/cmd/test_tempest_init.py
@@ -22,7 +22,7 @@
 
 class TestTempestInit(base.TestCase):
 
-    def test_generate_testr_conf(self):
+    def test_generate_stestr_conf(self):
         # Create fake conf dir
         conf_dir = self.useFixture(fixtures.TempDir())
 
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index 32d6224..c260343 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -343,6 +343,24 @@
         self.assertEqual(sorted(['fake1', 'fake2', 'not_fake']),
                          sorted(results['neutron']['extensions']))
 
+    def test_verify_extensions_neutron_none(self):
+        def fake_list_extensions():
+            return {'extensions': []}
+        fake_os = mock.MagicMock()
+        fake_client = mock.MagicMock()
+        fake_client.list_extensions = fake_list_extensions
+        self.useFixture(fixtures.MockPatchObject(
+            verify_tempest_config, 'get_extension_client',
+            return_value=fake_client))
+        self.useFixture(fixtures.MockPatchObject(
+            verify_tempest_config, 'get_enabled_extensions',
+            return_value=(['all'])))
+        results = verify_tempest_config.verify_extensions(fake_os,
+                                                          'neutron', {})
+        self.assertIn('neutron', results)
+        self.assertIn('extensions', results['neutron'])
+        self.assertEqual([], results['neutron']['extensions'])
+
     def test_verify_extensions_cinder(self):
         def fake_list_extensions():
             return {'extensions': [{'alias': 'fake1'},
@@ -391,6 +409,24 @@
         self.assertEqual(sorted(['fake1', 'fake2', 'not_fake']),
                          sorted(results['cinder']['extensions']))
 
+    def test_verify_extensions_cinder_none(self):
+        def fake_list_extensions():
+            return {'extensions': []}
+        fake_os = mock.MagicMock()
+        fake_client = mock.MagicMock()
+        fake_client.list_extensions = fake_list_extensions
+        self.useFixture(fixtures.MockPatchObject(
+            verify_tempest_config, 'get_extension_client',
+            return_value=fake_client))
+        self.useFixture(fixtures.MockPatchObject(
+            verify_tempest_config, 'get_enabled_extensions',
+            return_value=(['all'])))
+        results = verify_tempest_config.verify_extensions(fake_os,
+                                                          'cinder', {})
+        self.assertIn('cinder', results)
+        self.assertIn('extensions', results['cinder'])
+        self.assertEqual([], results['cinder']['extensions'])
+
     def test_verify_extensions_nova(self):
         def fake_list_extensions():
             return ([{'alias': 'fake1'}, {'alias': 'fake2'},
@@ -437,6 +473,24 @@
         self.assertEqual(sorted(['fake1', 'fake2', 'not_fake']),
                          sorted(results['nova']['extensions']))
 
+    def test_verify_extensions_nova_none(self):
+        def fake_list_extensions():
+            return ({'extensions': []})
+        fake_os = mock.MagicMock()
+        fake_client = mock.MagicMock()
+        fake_client.list_extensions = fake_list_extensions
+        self.useFixture(fixtures.MockPatchObject(
+            verify_tempest_config, 'get_extension_client',
+            return_value=fake_client))
+        self.useFixture(fixtures.MockPatchObject(
+            verify_tempest_config, 'get_enabled_extensions',
+            return_value=(['all'])))
+        results = verify_tempest_config.verify_extensions(fake_os,
+                                                          'nova', {})
+        self.assertIn('nova', results)
+        self.assertIn('extensions', results['nova'])
+        self.assertEqual([], results['nova']['extensions'])
+
     def test_verify_extensions_swift(self):
         def fake_list_extensions():
             return {'fake1': 'metadata',
@@ -485,6 +539,24 @@
         self.assertEqual(sorted(['not_fake', 'fake1', 'fake2']),
                          sorted(results['swift']['extensions']))
 
+    def test_verify_extensions_swift_none(self):
+        def fake_list_extensions():
+            return {'swift': 'metadata'}
+        fake_os = mock.MagicMock()
+        fake_client = mock.MagicMock()
+        fake_client.list_capabilities = fake_list_extensions
+        self.useFixture(fixtures.MockPatchObject(
+            verify_tempest_config, 'get_extension_client',
+            return_value=fake_client))
+        self.useFixture(fixtures.MockPatchObject(
+            verify_tempest_config, 'get_enabled_extensions',
+            return_value=(['all'])))
+        results = verify_tempest_config.verify_extensions(fake_os,
+                                                          'swift', {})
+        self.assertIn('swift', results)
+        self.assertIn('extensions', results['swift'])
+        self.assertEqual([], results['swift']['extensions'])
+
     def test_get_extension_client(self):
         creds = credentials_factory.get_credentials(
             fill_in=False, username='fake_user', project_name='fake_project',
diff --git a/tox.ini b/tox.ini
index d61a7fe..970f415 100644
--- a/tox.ini
+++ b/tox.ini
@@ -78,6 +78,7 @@
 deps = {[tempestenv]deps}
 # The regex below is used to select which tests to run and exclude the slow tag:
 # See the testrepository bug: https://bugs.launchpad.net/testrepository/+bug/1208610
+# FIXME: We can replace it with the `--black-regex` option to exclude tests now.
 commands =
     find . -type f -name "*.pyc" -delete
     tempest run --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.api)' {posargs}
@@ -100,6 +101,7 @@
 deps = {[tempestenv]deps}
 # The regex below is used to select which tests to run and exclude the slow tag:
 # See the testrepository bug: https://bugs.launchpad.net/testrepository/+bug/1208610
+# FIXME: We can replace it with the `--black-regex` option to exclude tests now.
 commands =
     find . -type f -name "*.pyc" -delete
     tempest run --serial --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario))' {posargs}