Merge "Execute volume tests only when cinder is available"
diff --git a/.zuul.yaml b/.zuul.yaml
index 74ebce3..d413e88 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -1,54 +1,23 @@
 - job:
-    name: heat-functional-convg-stein
-    parent: heat-functional-convg-mysql-lbaasv2-py3
-    nodeset: openstack-single-node-bionic
-    override-checkout: stable/stein
-    vars:
-      branch_override: stable/stein
-
-- job:
-    name: heat-functional-orig-stein
-    parent: heat-functional-orig-mysql-lbaasv2
-    nodeset: openstack-single-node-bionic
-    override-checkout: stable/stein
-    vars:
-      branch_override: stable/stein
-      use_python3: 1
-
-- job:
-    name: heat-functional-convg-train
-    parent: heat-functional-convg-mysql-lbaasv2-py3
-    nodeset: openstack-single-node-bionic
-    override-checkout: stable/train
-    vars:
-      branch_override: stable/train
-
-- job:
-    name: heat-functional-orig-train
-    parent: heat-functional-orig-mysql-lbaasv2
-    nodeset: openstack-single-node-bionic
-    override-checkout: stable/train
-    vars:
-      branch_override: stable/train
-      use_python3: 1
-
-- job:
-    name: heat-functional-ussuri
+    name: heat-functional-2023-1
     parent: heat-functional
-    nodeset: openstack-single-node-bionic
-    override-checkout: stable/ussuri
+    nodeset: openstack-single-node-jammy
+    override-checkout: stable/2023.1
 
 - job:
-    name: heat-functional-victoria
+    name: heat-functional-zed
     parent: heat-functional
-    override-checkout: stable/victoria
+    nodeset: openstack-single-node-focal
+    override-checkout: stable/zed
 
 - job:
-    name: heat-functional-wallaby
+    name: heat-functional-yoga
     parent: heat-functional
-    override-checkout: stable/wallaby
+    nodeset: openstack-single-node-focal
+    override-checkout: stable/yoga
 
 - project:
+    queue: heat
     templates:
       - check-requirements
       - tempest-plugin-jobs
@@ -56,13 +25,10 @@
       jobs:
         - heat-functional
         - heat-functional-legacy
-        - heat-functional-convg-train
-        - heat-functional-orig-train
-        - heat-functional-ussuri
-        - heat-functional-victoria
-        - heat-functional-wallaby
+        - heat-functional-2023-1
+        - heat-functional-zed
+        - heat-functional-yoga
     gate:
-      queue: heat
       jobs:
         - heat-functional
         - heat-functional-legacy
diff --git a/heat_tempest_plugin/common/remote_client.py b/heat_tempest_plugin/common/remote_client.py
index f23622b..aa652be 100644
--- a/heat_tempest_plugin/common/remote_client.py
+++ b/heat_tempest_plugin/common/remote_client.py
@@ -15,9 +15,9 @@
 import socket
 import time
 
+import io
 from oslo_log import log as logging
 import paramiko
-import six
 
 from heat_tempest_plugin.common import exceptions
 
@@ -31,9 +31,9 @@
         self.host = host
         self.username = username
         self.password = password
-        if isinstance(pkey, six.string_types):
+        if isinstance(pkey, str):
             pkey = paramiko.RSAKey.from_private_key(
-                six.moves.cStringIO(str(pkey)))
+                io.cStringIO(str(pkey)))
         self.pkey = pkey
         self.look_for_keys = look_for_keys
         self.key_filename = key_filename
@@ -151,7 +151,7 @@
         network = self.conf.network_for_ssh
         ip_version = self.conf.ip_version_for_ssh
         ssh_channel_timeout = self.conf.ssh_channel_timeout
-        if isinstance(server, six.string_types):
+        if isinstance(server, str):
             ip_address = server
         else:
             addresses = server['addresses'][network]
diff --git a/heat_tempest_plugin/common/test.py b/heat_tempest_plugin/common/test.py
index 1dd2137..475d416 100644
--- a/heat_tempest_plugin/common/test.py
+++ b/heat_tempest_plugin/common/test.py
@@ -21,10 +21,9 @@
 from neutronclient.common import exceptions as network_exceptions
 from oslo_log import log as logging
 from oslo_utils import timeutils
-import six
-from six.moves import urllib
 import testscenarios
 import testtools
+import urllib
 
 from heat_tempest_plugin.common import exceptions
 from heat_tempest_plugin.common import remote_client
@@ -67,7 +66,7 @@
 
 
 def rand_name(name=''):
-    randbits = six.text_type(random.randint(1, 0x7fffffff))
+    randbits = str(random.randint(1, 0x7fffffff))
     if name:
         return name + '-' + randbits
     else:
@@ -220,7 +219,7 @@
         self.setup_clients(self.conf, True)
 
     def get_remote_client(self, server_or_ip, username, private_key=None):
-        if isinstance(server_or_ip, six.string_types):
+        if isinstance(server_or_ip, str):
             ip = server_or_ip
         else:
             network_name_for_ssh = self.conf.network_for_ssh
diff --git a/heat_tempest_plugin/tests/api/test_heat_api.py b/heat_tempest_plugin/tests/api/test_heat_api.py
index d256437..24e6059 100644
--- a/heat_tempest_plugin/tests/api/test_heat_api.py
+++ b/heat_tempest_plugin/tests/api/test_heat_api.py
@@ -20,7 +20,6 @@
 from gabbi import driver
 import keystoneauth1
 from oslo_log import log as logging
-import six
 from tempest import config
 
 from heat_tempest_plugin.common import test
@@ -63,8 +62,8 @@
                 keystoneauth1.exceptions.discovery.DiscoveryFailure,
                 keystoneauth1.exceptions.connection.UnknownConnectionError,
                 keystoneauth1.exceptions.connection.ConnectFailure):
-            LOG.warn("Keystone auth exception: %s: %s" % (sys.exc_info()[0],
-                                                          sys.exc_info()[1]))
+            LOG.warning("Keystone auth exception: %s: %s" %
+                        (sys.exc_info()[0], sys.exc_info()[1]))
             # Clear the auth_url, as there is no point in tempest trying
             # to authenticate later with mis-configured or unreachable endpoint
             conf.auth_url = None
@@ -101,7 +100,7 @@
                                        test_loader_name=__name__)
     except TypeError as ex:
         err_msg = "got an unexpected keyword argument 'cert_validate'"
-        if err_msg in six.text_type(ex):
+        if err_msg in str(ex):
             api_tests = driver.build_tests(test_dir, loader,
                                            url=endpoint, host="",
                                            fixture_module=fixtures,
diff --git a/heat_tempest_plugin/tests/functional/test_lbaasv2.py b/heat_tempest_plugin/tests/functional/test_lbaasv2.py
deleted file mode 100644
index 3439179..0000000
--- a/heat_tempest_plugin/tests/functional/test_lbaasv2.py
+++ /dev/null
@@ -1,159 +0,0 @@
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-
-from tempest.lib import decorators
-
-from heat_tempest_plugin.tests.functional import functional_base
-
-
-class LoadBalancerv2Test(functional_base.FunctionalTestsBase):
-
-    create_template = '''
-heat_template_version: 2016-04-08
-parameters:
-    subnet:
-        type: string
-resources:
-  loadbalancer:
-    type: OS::Neutron::LBaaS::LoadBalancer
-    properties:
-      description: aLoadBalancer
-      vip_subnet: { get_param: subnet }
-  listener:
-    type: OS::Neutron::LBaaS::Listener
-    properties:
-      description: aListener
-      loadbalancer: { get_resource: loadbalancer }
-      protocol: HTTP
-      protocol_port: 80
-      connection_limit: 5555
-  pool:
-    type: OS::Neutron::LBaaS::Pool
-    properties:
-      description: aPool
-      lb_algorithm: ROUND_ROBIN
-      protocol: HTTP
-      listener: { get_resource: listener }
-  poolmember:
-    type: OS::Neutron::LBaaS::PoolMember
-    properties:
-      address: 1.1.1.1
-      pool: { get_resource: pool }
-      protocol_port: 1111
-      subnet: { get_param: subnet }
-      weight: 255
-  # pm2
-  healthmonitor:
-    type: OS::Neutron::LBaaS::HealthMonitor
-    properties:
-      delay: 3
-      type: HTTP
-      timeout: 3
-      max_retries: 3
-      pool: { get_resource: pool }
-outputs:
-  loadbalancer:
-    value: { get_attr: [ loadbalancer, show ] }
-  pool:
-    value: { get_attr: [ pool, show ] }
-  poolmember:
-    value: { get_attr: [ poolmember, show ] }
-  listener:
-    value: { get_attr: [ listener, show ] }
-  healthmonitor:
-    value: { get_attr: [ healthmonitor, show ] }
-'''
-
-    add_member = '''
-  poolmember2:
-    type: OS::Neutron::LBaaS::PoolMember
-    properties:
-      address: 2.2.2.2
-      pool: { get_resource: pool }
-      protocol_port: 2222
-      subnet: { get_param: subnet }
-      weight: 222
-'''
-
-    def setUp(self):
-        super(LoadBalancerv2Test, self).setUp()
-        if not self.is_network_extension_supported('lbaasv2'):
-            self.skipTest('LBaasv2 extension not available, skipping')
-
-    @decorators.idempotent_id('2f4a476c-cba7-448b-a7c1-85f7284f0293')
-    def test_create_update_loadbalancer(self):
-        parameters = {
-            'subnet': self.conf.fixed_subnet_name,
-        }
-        stack_identifier = self.stack_create(template=self.create_template,
-                                             parameters=parameters)
-        stack = self.client.stacks.get(stack_identifier)
-        output = self._stack_output(stack, 'loadbalancer')
-        self.assertEqual('ONLINE', output['operating_status'])
-
-        template = self.create_template.replace('ROUND_ROBIN', 'SOURCE_IP')
-        template = template.replace('3', '6')
-        template = template.replace('255', '256')
-        template = template.replace('5555', '7777')
-        template = template.replace('aLoadBalancer', 'updatedLoadBalancer')
-        template = template.replace('aPool', 'updatedPool')
-        template = template.replace('aListener', 'updatedListener')
-        self.update_stack(stack_identifier, template=template,
-                          parameters=parameters)
-        stack = self.client.stacks.get(stack_identifier)
-
-        output = self._stack_output(stack, 'loadbalancer')
-        self.assertEqual('ONLINE', output['operating_status'])
-        self.assertEqual('updatedLoadBalancer', output['description'])
-        output = self._stack_output(stack, 'pool')
-        self.assertEqual('SOURCE_IP', output['lb_algorithm'])
-        self.assertEqual('updatedPool', output['description'])
-        output = self._stack_output(stack, 'poolmember')
-        self.assertEqual(256, output['weight'])
-        output = self._stack_output(stack, 'healthmonitor')
-        self.assertEqual(6, output['delay'])
-        self.assertEqual(6, output['timeout'])
-        self.assertEqual(6, output['max_retries'])
-        output = self._stack_output(stack, 'listener')
-        self.assertEqual(7777, output['connection_limit'])
-        self.assertEqual('updatedListener', output['description'])
-
-    @decorators.idempotent_id('104f59ae-a3c8-4c12-98e5-a7bc0007878d')
-    def test_add_delete_poolmember(self):
-        parameters = {
-            'subnet': self.conf.fixed_subnet_name,
-        }
-        stack_identifier = self.stack_create(template=self.create_template,
-                                             parameters=parameters)
-        stack = self.client.stacks.get(stack_identifier)
-        output = self._stack_output(stack, 'loadbalancer')
-        self.assertEqual('ONLINE', output['operating_status'])
-        output = self._stack_output(stack, 'pool')
-        self.assertEqual(1, len(output['members']))
-        # add pool member
-        template = self.create_template.replace('# pm2', self.add_member)
-        self.update_stack(stack_identifier, template=template,
-                          parameters=parameters)
-        stack = self.client.stacks.get(stack_identifier)
-        output = self._stack_output(stack, 'loadbalancer')
-        self.assertEqual('ONLINE', output['operating_status'])
-        output = self._stack_output(stack, 'pool')
-        self.assertEqual(2, len(output['members']))
-        # delete pool member
-        self.update_stack(stack_identifier, template=self.create_template,
-                          parameters=parameters)
-        stack = self.client.stacks.get(stack_identifier)
-        output = self._stack_output(stack, 'loadbalancer')
-        self.assertEqual('ONLINE', output['operating_status'])
-        output = self._stack_output(stack, 'pool')
-        self.assertEqual(1, len(output['members']))
diff --git a/heat_tempest_plugin/tests/functional/test_preview.py b/heat_tempest_plugin/tests/functional/test_preview.py
index f1a6d72..d984272 100644
--- a/heat_tempest_plugin/tests/functional/test_preview.py
+++ b/heat_tempest_plugin/tests/functional/test_preview.py
@@ -11,7 +11,6 @@
 #    under the License.
 
 from heatclient import exc
-import six
 from tempest.lib import decorators
 
 from heat_tempest_plugin.tests.functional import functional_base
@@ -133,7 +132,7 @@
 
         self.assertIn('Property error: : resources.two.properties.value: '
                       ': The Parameter (missing) was not provided.',
-                      six.text_type(excp))
+                      str(excp))
 
     @decorators.idempotent_id('0449113c-ff90-4f2b-8825-27ea35c1983f')
     def test_nested_pass(self):
diff --git a/heat_tempest_plugin/tests/functional/test_remote_stack.py b/heat_tempest_plugin/tests/functional/test_remote_stack.py
index 6c5268c..f9409d1 100644
--- a/heat_tempest_plugin/tests/functional/test_remote_stack.py
+++ b/heat_tempest_plugin/tests/functional/test_remote_stack.py
@@ -12,7 +12,6 @@
 
 
 from heatclient import exc
-import six
 from tempest.lib import decorators
 
 from heat_tempest_plugin.common import test
@@ -146,7 +145,7 @@
                      'at region "DARKHOLE" due to '
                      '"(?:public|internal|admin)(?:URL)? endpoint for '
                      'orchestration service in DARKHOLE region not found"')
-        self.assertRegex(six.text_type(ex), error_msg)
+        self.assertRegex(str(ex), error_msg)
 
     @decorators.idempotent_id('b2190dfc-d223-4595-b168-6c42b0f3a3e5')
     def test_stack_resource_validation_fail(self):
@@ -159,7 +158,7 @@
                      'endpoint at region "%s" due to '
                      '"ERROR: The template section is '
                      'invalid: resource"') % self.conf.region
-        self.assertEqual(error_msg, six.text_type(ex))
+        self.assertEqual(error_msg, str(ex))
 
     @decorators.idempotent_id('141f0478-121b-4e61-bde7-d5551bfd1fc2')
     def test_stack_update(self):
diff --git a/heat_tempest_plugin/tests/functional/test_template_validate.py b/heat_tempest_plugin/tests/functional/test_template_validate.py
index e41f952..46ad4a2 100644
--- a/heat_tempest_plugin/tests/functional/test_template_validate.py
+++ b/heat_tempest_plugin/tests/functional/test_template_validate.py
@@ -11,8 +11,6 @@
 #    under the License.
 
 
-import six
-
 from heatclient import exc
 from tempest.lib import decorators
 
@@ -169,7 +167,7 @@
         ex = self.assertRaises(exc.HTTPBadRequest,
                                self.client.stacks.validate,
                                template=fail_template)
-        self.assertIn('The template version is invalid', six.text_type(ex))
+        self.assertIn('The template version is invalid', str(ex))
 
     @decorators.idempotent_id('6a6472d2-71fa-4ebe-a2b6-20878838555b')
     def test_template_validate_parameter_groups(self):
diff --git a/heat_tempest_plugin/tests/scenario/templates/app_server_lbv2_neutron.yaml b/heat_tempest_plugin/tests/scenario/templates/app_server_lbv2_neutron.yaml
deleted file mode 100644
index ca4117b..0000000
--- a/heat_tempest_plugin/tests/scenario/templates/app_server_lbv2_neutron.yaml
+++ /dev/null
@@ -1,76 +0,0 @@
-heat_template_version: 2015-10-15
-
-description: |
-  App server that is a member of Neutron Pool.
-
-parameters:
-
-  image:
-    type: string
-
-  flavor:
-    type: string
-
-  net:
-    type: string
-
-  sec_group:
-    type: string
-
-  pool:
-    type: string
-
-  app_port:
-    type: number
-
-  timeout:
-    type: number
-
-  subnet:
-    type: string
-
-  wc_extra_args:
-    type: string
-    default: ""
-
-resources:
-
-  config:
-    type: OS::Test::WebAppConfig
-    properties:
-      app_port: { get_param: app_port }
-      wc_curl_cli:
-        list_join:
-          - " "
-          - [ get_attr: [ handle, curl_cli ], get_param: wc_extra_args ]
-
-  server:
-    type: OS::Nova::Server
-    properties:
-      image: { get_param: image }
-      flavor: { get_param: flavor }
-      networks:
-        - network: { get_param: net }
-      security_groups:
-        - { get_param: sec_group }
-      user_data_format: RAW
-      user_data: { get_resource: config }
-
-  handle:
-    type: OS::Heat::WaitConditionHandle
-
-  waiter:
-    type: OS::Heat::WaitCondition
-    depends_on: server
-    properties:
-      timeout: { get_param: timeout }
-      handle: { get_resource: handle }
-
-  pool_member:
-    type: OS::Neutron::LBaaS::PoolMember
-    depends_on: waiter
-    properties:
-      address: { get_attr: [ server, networks, { get_param: net }, 0 ] }
-      pool: { get_param: pool }
-      protocol_port: { get_param: app_port }
-      subnet: { get_param: subnet }
diff --git a/heat_tempest_plugin/tests/scenario/templates/lb_member.yaml b/heat_tempest_plugin/tests/scenario/templates/lb_member.yaml
deleted file mode 100644
index a974968..0000000
--- a/heat_tempest_plugin/tests/scenario/templates/lb_member.yaml
+++ /dev/null
@@ -1,69 +0,0 @@
-heat_template_version: pike
-parameters:
-  image:
-    type: string
-  flavor:
-    type: string
-  network:
-    type: string
-  sec_group:
-    type: string
-  pool:
-    type: string
-  app_port:
-    type: number
-  timeout:
-    type: number
-    default: 120
-  subnet:
-    type: string
-
-resources:
-  server:
-    type: OS::Nova::Server
-    properties:
-      image: {get_param: image}
-      flavor: {get_param: flavor}
-      networks:
-        - network: {get_param: network}
-      security_groups:
-        - {get_param: sec_group}
-      user_data_format: RAW
-      user_data:
-        str_replace:
-          template: |
-            #! /bin/sh -v
-            Body=$(hostname)
-            Response="HTTP/1.1 200 OK\r\nContent-Length: ${#Body}\r\n\r\n$Body"
-            while true; do
-                wc_notify --data-binary '{"status": "SUCCESS"}'
-                if [ $? -eq 0 ]; then
-                    break
-                fi
-                sleep 10
-            done
-            while true ; do
-                echo -e $Response | nc -llp PORT
-            done
-          params:
-            PORT: {get_param: app_port}
-            wc_notify: { get_attr: [handle, curl_cli]}
-
-  handle:
-    type: OS::Heat::WaitConditionHandle
-
-  waiter:
-    type: OS::Heat::WaitCondition
-    depends_on: server
-    properties:
-      timeout: {get_param: timeout}
-      handle: {get_resource: handle}
-
-  pool_member:
-    type: OS::Octavia::PoolMember
-    depends_on: waiter
-    properties:
-      address: {get_attr: [server, networks, {get_param: network}, 0]}
-      pool: {get_param: pool}
-      protocol_port: {get_param: app_port}
-      subnet: {get_param: subnet}
diff --git a/heat_tempest_plugin/tests/scenario/templates/test_autoscaling_lb_neutron.yaml b/heat_tempest_plugin/tests/scenario/templates/test_autoscaling_lb_neutron.yaml
deleted file mode 100644
index 033581a..0000000
--- a/heat_tempest_plugin/tests/scenario/templates/test_autoscaling_lb_neutron.yaml
+++ /dev/null
@@ -1,117 +0,0 @@
-heat_template_version: 2015-04-30
-
-description: |
-  Template which tests Neutron load balancing requests to members of
-  Heat AutoScalingGroup.
-  Instances must be running some webserver on a given app_port
-  producing HTTP response that is different between servers
-  but stable over time for given server.
-
-parameters:
-  flavor:
-    type: string
-  image:
-    type: string
-  net:
-    type: string
-  subnet:
-    type: string
-  public_net:
-    type: string
-  app_port:
-    type: number
-    default: 8080
-  lb_port:
-    type: number
-    default: 80
-  timeout:
-    type: number
-    default: 600
-  wc_extra_args:
-    type: string
-    default: ""
-
-resources:
-
-  sec_group:
-    type: OS::Neutron::SecurityGroup
-    properties:
-      rules:
-      - remote_ip_prefix: 0.0.0.0/0
-        protocol: tcp
-        port_range_min: { get_param: app_port }
-        port_range_max: { get_param: app_port }
-
-  asg:
-    type: OS::Heat::AutoScalingGroup
-    properties:
-      desired_capacity: 1
-      max_size: 2
-      min_size: 1
-      resource:
-        type: OS::Test::NeutronAppServer
-        properties:
-          image: { get_param: image }
-          flavor: { get_param: flavor }
-          net: { get_param: net}
-          sec_group: { get_resource: sec_group }
-          app_port: { get_param: app_port }
-          pool_id: { get_resource: pool }
-          timeout: { get_param: timeout }
-          wc_extra_args: { get_param: wc_extra_args }
-
-  scale_up:
-    type: OS::Heat::ScalingPolicy
-    properties:
-      adjustment_type: change_in_capacity
-      auto_scaling_group_id: { get_resource: asg }
-      scaling_adjustment: 1
-
-  scale_down:
-    type: OS::Heat::ScalingPolicy
-    properties:
-      adjustment_type: change_in_capacity
-      auto_scaling_group_id: { get_resource: asg }
-      scaling_adjustment: -1
-
-  health_monitor:
-    type: OS::Neutron::HealthMonitor
-    properties:
-      delay: 3
-      type: HTTP
-      timeout: 3
-      max_retries: 3
-
-  pool:
-    type: OS::Neutron::Pool
-    properties:
-      lb_method: ROUND_ROBIN
-      protocol: HTTP
-      subnet: { get_param: subnet }
-      monitors:
-      - { get_resource: health_monitor }
-      vip:
-        protocol_port: { get_param: lb_port }
-
-  floating_ip:
-     type: OS::Neutron::FloatingIP
-     properties:
-       floating_network: { get_param: public_net }
-       port_id:
-         { get_attr: [pool, vip, 'port_id'] }
-
-  loadbalancer:
-    type: OS::Neutron::LoadBalancer
-    properties:
-      pool_id: { get_resource: pool }
-      protocol_port: { get_param: app_port }
-
-outputs:
-  lburl:
-    description: URL of the loadbalanced app
-    value:
-      str_replace:
-        template: http://IP_ADDRESS:PORT
-        params:
-          IP_ADDRESS: { get_attr: [ floating_ip, floating_ip_address ] }
-          PORT: { get_param: lb_port }
diff --git a/heat_tempest_plugin/tests/scenario/templates/test_autoscaling_lbv2_neutron.yaml b/heat_tempest_plugin/tests/scenario/templates/test_autoscaling_lbv2_neutron.yaml
deleted file mode 100644
index a26f7f7..0000000
--- a/heat_tempest_plugin/tests/scenario/templates/test_autoscaling_lbv2_neutron.yaml
+++ /dev/null
@@ -1,120 +0,0 @@
-heat_template_version: 2015-04-30
-
-description: |
-  Template which tests Neutron load balancing requests to members of
-  Heat AutoScalingGroup. This uses LBaas V2.
-  Instances must be running some webserver on a given app_port
-  producing HTTP response that is different between servers
-  but stable over time for given server.
-
-parameters:
-  flavor:
-    type: string
-  image:
-    type: string
-  net:
-    type: string
-  subnet:
-    type: string
-  public_net:
-    type: string
-  app_port:
-    type: number
-    default: 8080
-  lb_port:
-    type: number
-    default: 80
-  timeout:
-    type: number
-    default: 600
-  wc_extra_args:
-    type: string
-    default: ""
-
-resources:
-
-  sec_group:
-    type: OS::Neutron::SecurityGroup
-    properties:
-      rules:
-      - remote_ip_prefix: 0.0.0.0/0
-        protocol: tcp
-        port_range_min: { get_param: app_port }
-        port_range_max: { get_param: app_port }
-
-  asg:
-    type: OS::Heat::AutoScalingGroup
-    properties:
-      desired_capacity: 1
-      max_size: 2
-      min_size: 1
-      resource:
-        type: OS::Test::NeutronAppServer
-        properties:
-          image: { get_param: image }
-          flavor: { get_param: flavor }
-          net: { get_param: net}
-          sec_group: { get_resource: sec_group }
-          app_port: { get_param: app_port }
-          pool: { get_resource: pool }
-          subnet: { get_param: subnet }
-          timeout: { get_param: timeout }
-          wc_extra_args: { get_param: wc_extra_args }
-
-  scale_up:
-    type: OS::Heat::ScalingPolicy
-    properties:
-      adjustment_type: change_in_capacity
-      auto_scaling_group_id: { get_resource: asg }
-      scaling_adjustment: 1
-
-  scale_down:
-    type: OS::Heat::ScalingPolicy
-    properties:
-      adjustment_type: change_in_capacity
-      auto_scaling_group_id: { get_resource: asg }
-      scaling_adjustment: -1
-
-  health_monitor:
-    type: OS::Neutron::LBaaS::HealthMonitor
-    properties:
-      delay: 3
-      type: HTTP
-      timeout: 3
-      max_retries: 3
-      pool: { get_resource: pool }
-
-  pool:
-    type: OS::Neutron::LBaaS::Pool
-    properties:
-      lb_algorithm: ROUND_ROBIN
-      protocol: HTTP
-      listener: { get_resource: listener }
-
-  listener:
-    type: OS::Neutron::LBaaS::Listener
-    properties:
-      loadbalancer: { get_resource: loadbalancer }
-      protocol: HTTP
-      protocol_port: { get_param: lb_port }
-
-  loadbalancer:
-    type: OS::Neutron::LBaaS::LoadBalancer
-    properties:
-      vip_subnet: { get_param: subnet }
-
-  floating_ip:
-    type: OS::Neutron::FloatingIP
-    properties:
-      floating_network: { get_param: public_net }
-      port_id: { get_attr: [loadbalancer, vip_port_id] }
-
-outputs:
-  lburl:
-    description: URL of the loadbalanced app
-    value:
-      str_replace:
-        template: http://IP_ADDRESS:PORT
-        params:
-          IP_ADDRESS: { get_attr: [ floating_ip, floating_ip_address ] }
-          PORT: { get_param: lb_port }
diff --git a/heat_tempest_plugin/tests/scenario/test_autoscaling_lb.py b/heat_tempest_plugin/tests/scenario/test_autoscaling_lb.py
deleted file mode 100644
index 3323bc5..0000000
--- a/heat_tempest_plugin/tests/scenario/test_autoscaling_lb.py
+++ /dev/null
@@ -1,114 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import time
-
-import requests
-from tempest.lib import decorators
-
-from heat_tempest_plugin.common import test
-from heat_tempest_plugin.tests.scenario import scenario_base
-
-
-class AutoscalingLoadBalancerTest(scenario_base.ScenarioTestsBase):
-    """The class is responsible for testing ASG + LBv1 scenario.
-
-    The very common use case tested is an autoscaling group
-    of some web application servers behind a loadbalancer.
-    """
-
-    def setUp(self):
-        super(AutoscalingLoadBalancerTest, self).setUp()
-        self.template_name = 'test_autoscaling_lb_neutron.yaml'
-        self.app_server_template_name = 'app_server_neutron.yaml'
-        self.webapp_template_name = 'netcat-webapp.yaml'
-        if not self.is_network_extension_supported('lbaas'):
-            self.skipTest('LBaas v1 extension not available, skipping')
-
-    def check_num_responses(self, url, expected_num, retries=10):
-        resp = set()
-        for count in range(retries):
-            time.sleep(1)
-            try:
-                r = requests.get(url, verify=self.verify_cert)
-            except requests.exceptions.ConnectionError:
-                # The LB may not be up yet, let's retry
-                continue
-            # skip unsuccessful requests
-            if r.status_code == 200:
-                resp.add(r.text)
-        self.assertEqual(expected_num, len(resp))
-
-    @decorators.idempotent_id('48ddbc45-cef6-4640-acd6-7efc281833b9')
-    def test_autoscaling_loadbalancer_neutron(self):
-        """Check work of AutoScaing and Neutron LBaaS v1 resource in Heat.
-
-        The scenario is the following:
-            1. Launch a stack with a load balancer and autoscaling group
-               of one server, wait until stack create is complete.
-            2. Check that there is only one distinctive response from
-               loadbalanced IP.
-            3. Signal the scale_up policy, wait until all resources in
-               autoscaling group are complete.
-            4. Check that now there are two distinctive responses from
-               loadbalanced IP.
-        """
-
-        parameters = {
-            'flavor': self.conf.minimal_instance_type,
-            'image': self.conf.minimal_image_ref,
-            'net': self.conf.fixed_network_name,
-            'subnet': self.conf.fixed_subnet_name,
-            'public_net': self.conf.floating_network_name,
-            'app_port': 8080,
-            'lb_port': 80,
-            'timeout': 600
-        }
-        if self.conf.vm_to_heat_api_insecure:
-            parameters['wc_extra_args'] = '--insecure'
-
-        app_server_template = self._load_template(
-            __file__, self.app_server_template_name, self.sub_dir
-        )
-        webapp_template = self._load_template(
-            __file__, self.webapp_template_name, self.sub_dir
-        )
-        files = {'appserver.yaml': app_server_template,
-                 'webapp.yaml': webapp_template}
-        env = {'resource_registry':
-               {'OS::Test::NeutronAppServer': 'appserver.yaml',
-                'OS::Test::WebAppConfig': 'webapp.yaml'}}
-        # Launch stack
-        sid = self.launch_stack(
-            template_name=self.template_name,
-            parameters=parameters,
-            files=files,
-            environment=env
-        )
-        stack = self.client.stacks.get(sid)
-        lb_url = self._stack_output(stack, 'lburl')
-        # Check number of distinctive responces, must be 1
-        self.check_num_responses(lb_url, 1)
-
-        # Signal the scaling hook
-        self.client.resources.signal(sid, 'scale_up')
-
-        # Wait for AutoScalingGroup update to finish
-        asg = self.client.resources.get(sid, 'asg')
-        test.call_until_true(self.conf.build_timeout,
-                             self.conf.build_interval,
-                             self.check_autoscale_complete,
-                             asg.physical_resource_id, 2, sid, 'asg')
-
-        # Check number of distinctive responses, must now be 2
-        self.check_num_responses(lb_url, 2)
diff --git a/heat_tempest_plugin/tests/scenario/test_autoscaling_lbv2.py b/heat_tempest_plugin/tests/scenario/test_autoscaling_lbv2.py
deleted file mode 100644
index eee1fbc..0000000
--- a/heat_tempest_plugin/tests/scenario/test_autoscaling_lbv2.py
+++ /dev/null
@@ -1,114 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import time
-
-import requests
-from tempest.lib import decorators
-
-from heat_tempest_plugin.common import test
-from heat_tempest_plugin.tests.scenario import scenario_base
-
-
-class AutoscalingLoadBalancerv2Test(scenario_base.ScenarioTestsBase):
-    """The class is responsible for testing ASG + LBv2 scenario.
-
-    The very common use case tested is an autoscaling group
-    of some web application servers behind a loadbalancer.
-    """
-
-    def setUp(self):
-        super(AutoscalingLoadBalancerv2Test, self).setUp()
-        self.template_name = 'test_autoscaling_lbv2_neutron.yaml'
-        self.app_server_template_name = 'app_server_lbv2_neutron.yaml'
-        self.webapp_template_name = 'netcat-webapp.yaml'
-        if not self.is_network_extension_supported('lbaasv2'):
-            self.skipTest('LBaasv2 extension not available, skipping')
-
-    def check_num_responses(self, url, expected_num, retries=20):
-        resp = set()
-        for count in range(retries):
-            time.sleep(2)
-            try:
-                r = requests.get(url, verify=self.verify_cert)
-            except requests.exceptions.ConnectionError:
-                # The LB may not be up yet, let's retry
-                continue
-            # skip unsuccessful requests
-            if r.status_code == 200:
-                resp.add(r.text)
-                if len(resp) == expected_num:
-                    break
-        self.assertEqual(expected_num, len(resp))
-
-    @decorators.idempotent_id('89459930-aa61-4557-989b-3429d3b3b612')
-    def test_autoscaling_loadbalancer_neutron(self):
-        """Check work of AutoScaing and Neutron LBaaS v2 resource in Heat.
-
-        The scenario is the following:
-            1. Launch a stack with a load balancer and autoscaling group
-               of one server, wait until stack create is complete.
-            2. Check that there is only one distinctive response from
-               loadbalanced IP.
-            3. Signal the scale_up policy, wait until all resources in
-               autoscaling group are complete.
-            4. Check that now there are two distinctive responses from
-               loadbalanced IP.
-        """
-
-        parameters = {
-            'flavor': self.conf.minimal_instance_type,
-            'image': self.conf.minimal_image_ref,
-            'net': self.conf.fixed_network_name,
-            'subnet': self.conf.fixed_subnet_name,
-            'public_net': self.conf.floating_network_name
-        }
-        if self.conf.vm_to_heat_api_insecure:
-            parameters['wc_extra_args'] = '--insecure'
-
-        app_server_template = self._load_template(
-            __file__, self.app_server_template_name, self.sub_dir
-        )
-        webapp_template = self._load_template(
-            __file__, self.webapp_template_name, self.sub_dir
-        )
-        files = {'appserver.yaml': app_server_template,
-                 'webapp.yaml': webapp_template}
-        env = {'resource_registry':
-               {'OS::Test::NeutronAppServer': 'appserver.yaml',
-                'OS::Test::WebAppConfig': 'webapp.yaml'}}
-
-        # Launch stack
-        sid = self.launch_stack(
-            template_name=self.template_name,
-            parameters=parameters,
-            files=files,
-            environment=env
-        )
-        stack = self.client.stacks.get(sid)
-        lb_url = self._stack_output(stack, 'lburl')
-        # Check number of distinctive responces, must be 1
-        self.check_num_responses(lb_url, 1)
-
-        # Signal the scaling hook
-        self.client.resources.signal(sid, 'scale_up')
-
-        # Wait for AutoScalingGroup update to finish
-        asg = self.client.resources.get(sid, 'asg')
-        test.call_until_true(self.conf.build_timeout,
-                             self.conf.build_interval,
-                             self.check_autoscale_complete,
-                             asg.physical_resource_id, 2, sid, 'asg')
-
-        # Check number of distinctive responses, must now be 2
-        self.check_num_responses(lb_url, 2)
diff --git a/heat_tempest_plugin/tests/scenario/test_base_resources.py b/heat_tempest_plugin/tests/scenario/test_base_resources.py
index a84df93..c9ed342 100644
--- a/heat_tempest_plugin/tests/scenario/test_base_resources.py
+++ b/heat_tempest_plugin/tests/scenario/test_base_resources.py
@@ -22,10 +22,10 @@
 
     def setUp(self):
         super(BasicResourcesTest, self).setUp()
-        if not self.conf.image_ref:
-            raise self.skipException("No image configured to test")
-        if not self.conf.instance_type:
-            raise self.skipException("No flavor configured to test")
+        if not self.conf.minimal_image_ref:
+            raise self.skipException("No minimal image configured to test")
+        if not self.conf.minimal_instance_type:
+            raise self.skipException("No minimal flavor configured to test")
 
     def check_stack(self):
         sid = self.stack_identifier
@@ -56,8 +56,8 @@
         self.private_net_name = test.rand_name('heat-net')
         parameters = {
             'key_name': test.rand_name('heat-key'),
-            'flavor': self.conf.instance_type,
-            'image': self.conf.image_ref,
+            'flavor': self.conf.minimal_instance_type,
+            'image': self.conf.minimal_image_ref,
             'vol_size': self.conf.volume_size,
             'private_net_name': self.private_net_name
         }
diff --git a/heat_tempest_plugin/tests/scenario/test_octavia_lbaas.py b/heat_tempest_plugin/tests/scenario/test_octavia_lbaas.py
index ce07262..46781d0 100644
--- a/heat_tempest_plugin/tests/scenario/test_octavia_lbaas.py
+++ b/heat_tempest_plugin/tests/scenario/test_octavia_lbaas.py
@@ -23,6 +23,10 @@
         self.template_name = 'octavia_lbaas.yaml'
         self.member_template_name = 'lb_member.yaml'
         self.sub_dir = 'templates'
+        if not self.conf.minimal_image_ref:
+            raise self.skipException("No minimal image configured to test")
+        if not self.conf.minimal_instance_type:
+            raise self.skipException("No minimal flavor configured to test")
 
     def _create_stack(self):
         self.parameters = {
diff --git a/heat_tempest_plugin/tests/scenario/test_remote_deeply_nested.py b/heat_tempest_plugin/tests/scenario/test_remote_deeply_nested.py
index ef05285..5ed428b 100644
--- a/heat_tempest_plugin/tests/scenario/test_remote_deeply_nested.py
+++ b/heat_tempest_plugin/tests/scenario/test_remote_deeply_nested.py
@@ -10,7 +10,6 @@
 # License for the specific language governing permissions and limitations
 # under the License.
 
-import six
 import uuid
 
 from heat_tempest_plugin.tests.scenario import scenario_base
@@ -33,7 +32,7 @@
 
         stack = self.client.stacks.get(stack_id)
         router_id = self._stack_output(stack, 'router')
-        self.assertIsInstance(router_id, six.string_types)
+        self.assertIsInstance(router_id, str)
         uuid.UUID(router_id)
 
         self._stack_delete(stack_id)
diff --git a/heat_tempest_plugin/tests/scenario/test_server_signal.py b/heat_tempest_plugin/tests/scenario/test_server_signal.py
index 167dfa0..c4deb3c 100644
--- a/heat_tempest_plugin/tests/scenario/test_server_signal.py
+++ b/heat_tempest_plugin/tests/scenario/test_server_signal.py
@@ -81,6 +81,10 @@
 
     @decorators.idempotent_id('8da0f6cc-60e6-4298-9e54-e1f905c5552a')
     def test_server_signal_userdata_format_raw(self):
+        if not self.conf.minimal_image_ref:
+            raise self.skipException("No minimal image configured to test")
+        if not self.conf.minimal_instance_type:
+            raise self.skipException("No minimal flavor configured to test")
         self._test_server_signal(image=self.conf.minimal_image_ref,
                                  flavor=self.conf.minimal_instance_type)
 
@@ -88,6 +92,8 @@
     def test_server_signal_userdata_format_software_config(self):
         if not self.conf.image_ref:
             raise self.skipException("No image configured to test")
+        if not self.conf.instance_type:
+            raise self.skipException("No flavor configured to test")
         self._test_server_signal(user_data_format='SOFTWARE_CONFIG',
                                  image=self.conf.image_ref,
                                  flavor=self.conf.instance_type)
diff --git a/heat_tempest_plugin/tests/scenario/test_server_software_config.py b/heat_tempest_plugin/tests/scenario/test_server_software_config.py
index 7da2853..1f2499b 100644
--- a/heat_tempest_plugin/tests/scenario/test_server_software_config.py
+++ b/heat_tempest_plugin/tests/scenario/test_server_software_config.py
@@ -11,7 +11,6 @@
 #    under the License.
 
 from heatclient.common import template_utils
-import six
 from tempest.lib import decorators
 
 from heat_tempest_plugin.tests.scenario import scenario_base
@@ -89,7 +88,7 @@
         # config isn't re-triggered
         complete_deployments = dict((d['name'], d) for d in
                                     complete_server_metadata['deployments'])
-        for k, v in six.iteritems(deployments):
+        for k, v in deployments.items():
             self.assertEqual(v, complete_deployments[k])
 
         stack = self.client.stacks.get(sid)
diff --git a/heat_tempest_plugin/tests/scenario/test_volumes.py b/heat_tempest_plugin/tests/scenario/test_volumes.py
index d99ed62..11184da 100644
--- a/heat_tempest_plugin/tests/scenario/test_volumes.py
+++ b/heat_tempest_plugin/tests/scenario/test_volumes.py
@@ -14,7 +14,6 @@
 from cinderclient import exceptions as cinder_exceptions
 import copy
 from oslo_log import log as logging
-import six
 from tempest.lib import decorators
 
 from heat_tempest_plugin.common import exceptions
@@ -45,7 +44,7 @@
     def _outputs_verify(self, stack, expected_status='available'):
         self.assertEqual(expected_status,
                          self._stack_output(stack, 'status'))
-        self.assertEqual(six.text_type(self.volume_size),
+        self.assertEqual(str(self.volume_size),
                          self._stack_output(stack, 'size'))
         self.assertEqual(self.volume_description,
                          self._stack_output(stack, 'display_description'))
diff --git a/requirements.txt b/requirements.txt
index 43abf78..ed5a98c 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,6 +1,3 @@
-# The order of packages is significant, because pip processes them in the order
-# of appearance. Changing the order has an impact on the overall integration
-# process, which may cause wedges in the gate later.
 keystoneauth1>=3.4.0 # Apache-2.0
 oslo.config>=5.2.0 # Apache-2.0
 oslo.log>=3.36.0 # Apache-2.0
diff --git a/setup.cfg b/setup.cfg
index 8776610..1b262e9 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,11 +1,12 @@
 [metadata]
 name = heat-tempest-plugin
 summary = OpenStack Orchestration Tempest Plugin
-description-file =
+description_file =
     README.rst
 author = OpenStack
-author-email = openstack-discuss@lists.openstack.org
-home-page = http://docs.openstack.org/developer/heat-tempest-plugin
+author_email = openstack-discuss@lists.openstack.org
+home_page = http://docs.openstack.org/developer/heat-tempest-plugin
+python_requires = >=3.6
 classifier =
     Environment :: OpenStack
     Intended Audience :: Information Technology
@@ -14,30 +15,20 @@
     Operating System :: POSIX :: Linux
     Programming Language :: Python
     Programming Language :: Python :: 3
-    Programming Language :: Python :: 3.5
     Programming Language :: Python :: 3.6
     Programming Language :: Python :: 3.7
+    Programming Language :: Python :: 3.8
+    Programming Language :: Python :: 3.9
+    Programming Language :: Python :: 3.10
 
 keywords =
     setup
     distutils
 
 [files]
-packages = 
+packages =
     heat_tempest_plugin
 
 [entry_points]
-tempest.test_plugins = 
+tempest.test_plugins =
     heat = heat_tempest_plugin.plugin:HeatTempestPlugin
-
-[global]
-setup-hooks =
-    pbr.hooks.setup_hook
-
-[egg_info]
-tag_build =
-tag_date = 0
-tag_svn_revision = 0
-
-[wheel]
-universal = 1
diff --git a/setup.py b/setup.py
index 566d844..cd35c3c 100644
--- a/setup.py
+++ b/setup.py
@@ -13,17 +13,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT
 import setuptools
 
-# In python < 2.7.4, a lazy loading of package `pbr` will break
-# setuptools if some other modules registered functions in `atexit`.
-# solution from: http://bugs.python.org/issue15881#msg170215
-try:
-    import multiprocessing  # noqa
-except ImportError:
-    pass
-
 setuptools.setup(
     setup_requires=['pbr>=2.0.0'],
     pbr=True)
diff --git a/test-requirements.txt b/test-requirements.txt
index 23614af..ffa8f45 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -1,7 +1,3 @@
-# The order of packages is significant, because pip processes them in the order
-# of appearance. Changing the order has an impact on the overall integration
-# process, which may cause wedges in the gate later.
-
 # Hacking already pins down pep8, pyflakes and flake8
 hacking>=2.0,<2.1.0 # Apache-2.0
 # remove this pyflakes from here once you bump the