Merge pull request #222 from openstack-charmers/issue/221
octavia: tear down resources created during LBaasV2 test
This commit is contained in:
@@ -13,5 +13,8 @@ matrix:
|
||||
- name: "Python 3.7"
|
||||
python: 3.7
|
||||
env: ENV=pep8,py3
|
||||
- name: "Python 3.8"
|
||||
python: 3.7
|
||||
env: ENV=pep8,py3
|
||||
script:
|
||||
- tox -c tox.ini -e $ENV
|
||||
|
||||
@@ -4,7 +4,7 @@ boto3
|
||||
juju
|
||||
juju_wait
|
||||
PyYAML<=4.2,>=3.0
|
||||
flake8>=2.2.4,<=3.5.0
|
||||
flake8>=2.2.4
|
||||
flake8-docstrings
|
||||
flake8-per-file-ignores
|
||||
pydocstyle<4.0.0
|
||||
|
||||
2
tox.ini
2
tox.ini
@@ -25,7 +25,7 @@ deps = -r{toxinidir}/requirements.txt
|
||||
commands = /bin/true
|
||||
|
||||
[flake8]
|
||||
ignore = E402,E226,W503
|
||||
ignore = E402,E226,W504
|
||||
per-file-ignores =
|
||||
unit_tests/**: D
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ import logging
|
||||
import subprocess
|
||||
import tenacity
|
||||
|
||||
import osc_lib.exceptions
|
||||
|
||||
import zaza.openstack.charm_tests.test_utils as test_utils
|
||||
import zaza.openstack.utilities.openstack as openstack_utils
|
||||
|
||||
@@ -47,15 +49,54 @@ class LBAASv2Test(test_utils.OpenStackBaseTest):
|
||||
"""Run class setup for running LBaaSv2 service tests."""
|
||||
super(LBAASv2Test, cls).setUpClass()
|
||||
|
||||
cls.keystone_session = openstack_utils.get_overcloud_keystone_session()
|
||||
cls.neutron_client = openstack_utils.get_neutron_session_client(
|
||||
cls.keystone_session)
|
||||
cls.octavia_client = openstack_utils.get_octavia_session_client(
|
||||
cls.keystone_session)
|
||||
|
||||
# NOTE(fnordahl): in the event of a test failure we do not want to run
|
||||
# tear down code as it will make debugging a problem virtually
|
||||
# impossible. To alleviate each test method will set the
|
||||
# `run_tearDown` instance variable at the end which will let us run
|
||||
# tear down only when there were no failure.
|
||||
cls.run_tearDown = False
|
||||
# List of load balancers created by this test
|
||||
cls.loadbalancers = []
|
||||
# LIst of floating IPs created by this test
|
||||
cls.fips = []
|
||||
|
||||
@classmethod
|
||||
def tearDown(cls):
|
||||
"""Remove resources created during test execution.
|
||||
|
||||
Note that resources created in the configure step prior to executing
|
||||
the test should not be touched here.
|
||||
"""
|
||||
if not cls.run_tearDown:
|
||||
return
|
||||
for lb in cls.loadbalancers:
|
||||
cls.octavia_client.load_balancer_delete(lb['id'], cascade=True)
|
||||
try:
|
||||
cls.wait_for_lb_resource(
|
||||
cls.octavia_client.load_balancer_show, lb['id'],
|
||||
provisioning_status='DELETED')
|
||||
except osc_lib.exceptions.NotFound:
|
||||
pass
|
||||
for fip in cls.fips:
|
||||
cls.neutron_client.delete_floatingip(fip)
|
||||
|
||||
@staticmethod
|
||||
@tenacity.retry(wait=tenacity.wait_fixed(1),
|
||||
reraise=True, stop=tenacity.stop_after_delay(900))
|
||||
@tenacity.retry(retry=tenacity.retry_if_exception_type(AssertionError),
|
||||
wait=tenacity.wait_fixed(1), reraise=True,
|
||||
stop=tenacity.stop_after_delay(900))
|
||||
def wait_for_lb_resource(octavia_show_func, resource_id,
|
||||
operating_status=None):
|
||||
provisioning_status=None, operating_status=None):
|
||||
"""Wait for loadbalancer resource to reach expected status."""
|
||||
provisioning_status = provisioning_status or 'ACTIVE'
|
||||
resp = octavia_show_func(resource_id)
|
||||
logging.info(resp['provisioning_status'])
|
||||
assert resp['provisioning_status'] == 'ACTIVE', (
|
||||
assert resp['provisioning_status'] == provisioning_status, (
|
||||
'load balancer resource has not reached '
|
||||
'expected provisioning status: {}'
|
||||
.format(resp))
|
||||
@@ -197,11 +238,8 @@ class LBAASv2Test(test_utils.OpenStackBaseTest):
|
||||
|
||||
def test_create_loadbalancer(self):
|
||||
"""Create load balancer."""
|
||||
keystone_session = openstack_utils.get_overcloud_keystone_session()
|
||||
neutron_client = openstack_utils.get_neutron_session_client(
|
||||
keystone_session)
|
||||
nova_client = openstack_utils.get_nova_session_client(
|
||||
keystone_session)
|
||||
self.keystone_session)
|
||||
|
||||
# Get IP of the prepared payload instances
|
||||
payload_ips = []
|
||||
@@ -209,24 +247,24 @@ class LBAASv2Test(test_utils.OpenStackBaseTest):
|
||||
payload_ips.append(server.networks['private'][0])
|
||||
self.assertTrue(len(payload_ips) > 0)
|
||||
|
||||
resp = neutron_client.list_networks(name='private')
|
||||
resp = self.neutron_client.list_networks(name='private')
|
||||
subnet_id = resp['networks'][0]['subnets'][0]
|
||||
if openstack_utils.dvr_enabled():
|
||||
resp = neutron_client.list_networks(name='private_lb_fip_network')
|
||||
resp = self.neutron_client.list_networks(
|
||||
name='private_lb_fip_network')
|
||||
vip_subnet_id = resp['networks'][0]['subnets'][0]
|
||||
else:
|
||||
vip_subnet_id = subnet_id
|
||||
octavia_client = openstack_utils.get_octavia_session_client(
|
||||
keystone_session)
|
||||
for provider in self.get_lb_providers(octavia_client).keys():
|
||||
for provider in self.get_lb_providers(self.octavia_client).keys():
|
||||
logging.info('Creating loadbalancer with provider {}'
|
||||
.format(provider))
|
||||
lb = self._create_lb_resources(octavia_client, provider,
|
||||
lb = self._create_lb_resources(self.octavia_client, provider,
|
||||
vip_subnet_id, subnet_id,
|
||||
payload_ips)
|
||||
self.loadbalancers.append(lb)
|
||||
|
||||
lb_fp = openstack_utils.create_floating_ip(
|
||||
neutron_client, 'ext_net', port={'id': lb['vip_port_id']})
|
||||
self.neutron_client, 'ext_net', port={'id': lb['vip_port_id']})
|
||||
|
||||
snippet = 'This is the default welcome page'
|
||||
assert snippet in self._get_payload(lb_fp['floating_ip_address'])
|
||||
@@ -234,3 +272,6 @@ class LBAASv2Test(test_utils.OpenStackBaseTest):
|
||||
' (provider="{}") at "http://{}/"'
|
||||
.format(snippet, provider,
|
||||
lb_fp['floating_ip_address']))
|
||||
|
||||
# If we get here, it means the tests passed
|
||||
self.run_tearDown = True
|
||||
|
||||
@@ -105,12 +105,12 @@ def _login(dashboard_ip, domain, username, password):
|
||||
# services/information missing that horizon wants to display data
|
||||
# for.
|
||||
# Redirect to /horizon/identity/ instead.
|
||||
if (openstack_utils.get_os_release()
|
||||
>= openstack_utils.get_os_release('xenial_queens')):
|
||||
if (openstack_utils.get_os_release() >=
|
||||
openstack_utils.get_os_release('xenial_queens')):
|
||||
auth['next'] = '/horizon/identity/'
|
||||
|
||||
if (openstack_utils.get_os_release()
|
||||
>= openstack_utils.get_os_release('bionic_stein')):
|
||||
if (openstack_utils.get_os_release() >=
|
||||
openstack_utils.get_os_release('bionic_stein')):
|
||||
auth['region'] = 'default'
|
||||
|
||||
if api_version == 2:
|
||||
@@ -122,8 +122,8 @@ def _login(dashboard_ip, domain, username, password):
|
||||
# NOTE(ajkavanagh) there used to be a trusty/icehouse test in the
|
||||
# amulet test, but as the zaza tests only test from trusty/mitaka
|
||||
# onwards, the test has been dropped
|
||||
if (openstack_utils.get_os_release()
|
||||
>= openstack_utils.get_os_release('bionic_stein')):
|
||||
if (openstack_utils.get_os_release() >=
|
||||
openstack_utils.get_os_release('bionic_stein')):
|
||||
expect = "Sign Out"
|
||||
# update the in dashboard seems to require region to be default in
|
||||
# this test configuration
|
||||
|
||||
@@ -214,8 +214,8 @@ class GenericPolicydTest(PolicydTest, test_utils.OpenStackBaseTest):
|
||||
def setUpClass(cls, application_name=None):
|
||||
"""Run class setup for running KeystonePolicydTest tests."""
|
||||
super(GenericPolicydTest, cls).setUpClass(application_name)
|
||||
if (openstack_utils.get_os_release()
|
||||
< openstack_utils.get_os_release('xenial_queens')):
|
||||
if (openstack_utils.get_os_release() <
|
||||
openstack_utils.get_os_release('xenial_queens')):
|
||||
raise unittest.SkipTest(
|
||||
"zaza.openstack.charm_tests.policyd.tests.GenericPolicydTest "
|
||||
"not valid before xenial_queens")
|
||||
@@ -276,8 +276,8 @@ class BasePolicydSpecialization(PolicydTest,
|
||||
def setUpClass(cls, application_name=None):
|
||||
"""Run class setup for running KeystonePolicydTest tests."""
|
||||
super(BasePolicydSpecialization, cls).setUpClass(application_name)
|
||||
if (openstack_utils.get_os_release()
|
||||
< openstack_utils.get_os_release('xenial_queens')):
|
||||
if (openstack_utils.get_os_release() <
|
||||
openstack_utils.get_os_release('xenial_queens')):
|
||||
raise unittest.SkipTest(
|
||||
"zaza.openstack.charm_tests.policyd.tests.* "
|
||||
"not valid before xenial_queens")
|
||||
|
||||
@@ -38,26 +38,26 @@ class QuaggaTest(unittest.TestCase):
|
||||
'tor2', 'peer0', 'peer1']
|
||||
if app in status.applications.keys())
|
||||
for application in applications:
|
||||
for unit in zaza.model.get_units(application):
|
||||
bgp_sum = zaza.model.run_on_unit(
|
||||
unit.entity_id,
|
||||
'echo "sh bgp ipv4 unicast summary" | vtysh')['Stdout']
|
||||
r = re.compile('^(\d+\.\d+\.\d+\.\d+)')
|
||||
ip_list = []
|
||||
for line in bgp_sum.splitlines():
|
||||
m = r.match(line)
|
||||
if m:
|
||||
ip_list.append(m.group(1))
|
||||
logging.info('unit {} neighbours {}'
|
||||
.format(unit.entity_id, ip_list))
|
||||
for unit in zaza.model.get_units(application):
|
||||
bgp_sum = zaza.model.run_on_unit(
|
||||
unit.entity_id,
|
||||
'echo "sh bgp ipv4 unicast summary" | vtysh')['Stdout']
|
||||
r = re.compile(r'^(\d+\.\d+\.\d+\.\d+)')
|
||||
ip_list = []
|
||||
for line in bgp_sum.splitlines():
|
||||
m = r.match(line)
|
||||
if m:
|
||||
ip_list.append(m.group(1))
|
||||
logging.info('unit {} neighbours {}'
|
||||
.format(unit.entity_id, ip_list))
|
||||
|
||||
if not ip_list:
|
||||
raise Exception('FAILED: Unit {} has no BGP peers.'
|
||||
.format(unit.entity_id))
|
||||
for ip in ip_list:
|
||||
result = zaza.model.run_on_unit(
|
||||
unit.entity_id,
|
||||
'ping -c 3 {}'.format(ip))
|
||||
logging.info(result['Stdout'])
|
||||
if result['Code'] == '1':
|
||||
raise Exception('FAILED')
|
||||
if not ip_list:
|
||||
raise Exception('FAILED: Unit {} has no BGP peers.'
|
||||
.format(unit.entity_id))
|
||||
for ip in ip_list:
|
||||
result = zaza.model.run_on_unit(
|
||||
unit.entity_id,
|
||||
'ping -c 3 {}'.format(ip))
|
||||
logging.info(result['Stdout'])
|
||||
if result['Code'] == '1':
|
||||
raise Exception('FAILED')
|
||||
|
||||
@@ -50,7 +50,7 @@ def skipUntilVersion(service, package, release):
|
||||
stderr=subprocess.STDOUT,
|
||||
universal_newlines=True)
|
||||
return f(*args, **kwargs)
|
||||
except subprocess.CalledProcessError as cp:
|
||||
except subprocess.CalledProcessError:
|
||||
logging.warn("Skipping test for older ({})"
|
||||
"service {}, requested {}".format(
|
||||
package_version, service, release))
|
||||
|
||||
@@ -579,28 +579,28 @@ def get_file_contents(unit, f):
|
||||
|
||||
|
||||
def is_port_open(port, address):
|
||||
"""Determine if TCP port is accessible.
|
||||
"""Determine if TCP port is accessible.
|
||||
|
||||
Connect to the MySQL port on the VIP.
|
||||
Connect to the MySQL port on the VIP.
|
||||
|
||||
:param port: Port number
|
||||
:type port: str
|
||||
:param address: IP address
|
||||
:type port: str
|
||||
:returns: True if port is reachable
|
||||
:rtype: boolean
|
||||
"""
|
||||
try:
|
||||
telnetlib.Telnet(address, port)
|
||||
return True
|
||||
except socket.error as e:
|
||||
if e.errno == 113:
|
||||
logging.error("could not connect to {}:{}"
|
||||
.format(address, port))
|
||||
if e.errno == 111:
|
||||
logging.error("connection refused connecting"
|
||||
" to {}:{}".format(address, port))
|
||||
return False
|
||||
:param port: Port number
|
||||
:type port: str
|
||||
:param address: IP address
|
||||
:type port: str
|
||||
:returns: True if port is reachable
|
||||
:rtype: boolean
|
||||
"""
|
||||
try:
|
||||
telnetlib.Telnet(address, port)
|
||||
return True
|
||||
except socket.error as e:
|
||||
if e.errno == 113:
|
||||
logging.error("could not connect to {}:{}"
|
||||
.format(address, port))
|
||||
if e.errno == 111:
|
||||
logging.error("connection refused connecting"
|
||||
" to {}:{}".format(address, port))
|
||||
return False
|
||||
|
||||
|
||||
def port_knock_units(units, port=22, expect_success=True):
|
||||
|
||||
@@ -1411,11 +1411,11 @@ def get_os_code_info(package, pkg_version):
|
||||
pkg_version = pkg_version.split(':')[1:][0]
|
||||
if 'swift' in package:
|
||||
# Fully x.y.z match for swift versions
|
||||
match = re.match('^(\d+)\.(\d+)\.(\d+)', pkg_version)
|
||||
match = re.match(r'^(\d+)\.(\d+)\.(\d+)', pkg_version)
|
||||
else:
|
||||
# x.y match only for 20XX.X
|
||||
# and ignore patch level for other packages
|
||||
match = re.match('^(\d+)\.(\d+)', pkg_version)
|
||||
match = re.match(r'^(\d+)\.(\d+)', pkg_version)
|
||||
|
||||
if match:
|
||||
vers = match.group(0)
|
||||
|
||||
Reference in New Issue
Block a user