From b44aa8823c85730ccc1b4537dab56862f8a2605c Mon Sep 17 00:00:00 2001 From: Zhang Hua Date: Mon, 12 Jul 2021 16:29:08 +0800 Subject: [PATCH 1/4] Delete hm port on unit removal This is Zaza functional test for lp:1915512. Add a unit and then remove a unit, then query the list of ports to check that the port has been deleted. Depends-On: https://review.opendev.org/c/openstack/charm-octavia/+/787700 --- zaza/openstack/charm_tests/mysql/tests.py | 29 +++--------- zaza/openstack/charm_tests/octavia/tests.py | 52 +++++++++++++++++++++ zaza/openstack/utilities/generic.py | 20 ++++++++ 3 files changed, 78 insertions(+), 23 deletions(-) diff --git a/zaza/openstack/charm_tests/mysql/tests.py b/zaza/openstack/charm_tests/mysql/tests.py index 5fbfb7e..3e47678 100644 --- a/zaza/openstack/charm_tests/mysql/tests.py +++ b/zaza/openstack/charm_tests/mysql/tests.py @@ -54,26 +54,6 @@ class MySQLBaseTest(test_utils.OpenStackBaseTest): self.application, "leader-get root-password")["Stdout"].strip() - def get_leaders_and_non_leaders(self): - """Get leader node and non-leader nodes of percona. - - Update and set on the object the leader node and list of non-leader - nodes. - - :returns: None - :rtype: None - """ - status = zaza.model.get_status().applications[self.application] - # Reset - self.leader = None - self.non_leaders = [] - for unit in status["units"]: - if status["units"][unit].get("leader"): - self.leader = unit - else: - self.non_leaders.append(unit) - return self.leader, self.non_leaders - def get_cluster_status(self): """Get cluster status. @@ -445,7 +425,8 @@ class PerconaClusterColdStartTest(PerconaClusterBaseTest): zaza.model.wait_for_application_states(states=states) # Update which node is the leader and which are not - _leader, _non_leaders = self.get_leaders_and_non_leaders() + _leader, _non_leaders = generic_utils.get_leaders_and_non_leaders( + self.application_name) # We want to test the worst possible scenario which is the # non-leader with the highest sequence number. We will use the leader # for the notify-bootstrapped after. They just need to be different @@ -818,7 +799,8 @@ class MySQLInnoDBClusterScaleTest(MySQLBaseTest): The cluster will be in waiting state. """ logging.info("Scale in test: remove leader") - leader, nons = self.get_leaders_and_non_leaders() + leader, nons = generic_utils.get_leaders_and_non_leaders( + self.application_name) leader_unit = zaza.model.get_unit_from_name(leader) # Wait until we are idle in the hopes clients are not running @@ -892,7 +874,8 @@ class MySQLInnoDBClusterScaleTest(MySQLBaseTest): We start with a four node full cluster, remove one, down to a three node full cluster. """ - leader, nons = self.get_leaders_and_non_leaders() + leader, nons = generic_utils.get_leaders_and_non_leaders( + self.application_name) non_leader_unit = zaza.model.get_unit_from_name(nons[0]) # Wait until we are idle in the hopes clients are not running diff --git a/zaza/openstack/charm_tests/octavia/tests.py b/zaza/openstack/charm_tests/octavia/tests.py index 295bd51..4ad56e7 100644 --- a/zaza/openstack/charm_tests/octavia/tests.py +++ b/zaza/openstack/charm_tests/octavia/tests.py @@ -22,9 +22,11 @@ from keystoneauth1 import exceptions as keystone_exceptions import octaviaclient.api.v2.octavia import osc_lib.exceptions +import zaza.model import zaza.openstack.charm_tests.test_utils as test_utils import zaza.openstack.utilities.openstack as openstack_utils +from zaza.openstack.utilities import generic as generic_utils from zaza.openstack.utilities import ObjectRetrierWraps LBAAS_ADMIN_ROLE = 'load-balancer_admin' @@ -104,6 +106,56 @@ class CharmOperationTest(test_utils.OpenStackBaseTest): """Run class setup for running Octavia charm operation tests.""" super(CharmOperationTest, cls).setUpClass() + def get_port_ips(self): + """Extract IP info from Neutron ports tagged with charm-octavia.""" + keystone_session = openstack_utils.get_overcloud_keystone_session() + neutron_client = openstack_utils.get_neutron_session_client( + keystone_session) + resp = neutron_client.list_ports(tags='charm-octavia') + neutron_ip_list = [] + for port in resp['ports']: + # one new DOWN port may be created when deleting one octavia unit + if port['status'] == 'DOWN': + continue + for ip_info in port['fixed_ips']: + neutron_ip_list.append(ip_info['ip_address']) + return neutron_ip_list + + def test_update_controller_ip_port_list(self): + """Test update_controller_ip_port_list. + + Add a unit and then delete a unit, then query the list of ports to + check that the port has been deleted. + """ + app = self.test_config['charm_name'] + logging.info("test_update_controller_ip_port_list: start test") + logging.info("Wait till model is idle ...") + zaza.model.block_until_all_units_idle() + ips = self.get_port_ips() + num = len(ips) + logging.info('initial hm port num is {}: {}'.format(num, ips)) + + logging.info("test_update_controller_ip_port_list: add one unit") + logging.info("Adding one unit ...") + zaza.model.add_unit(app) + logging.info("Wait until one unit is added ...") + zaza.model.block_until_unit_count(app, num+1) + zaza.model.wait_for_application_states() + ips = self.get_port_ips() + logging.info('hm ports are {} after adding one unit'.format(ips)) + self.assertTrue(len(ips) == num+1) + + logging.info("test_update_controller_ip_port_list: remove one unit") + logging.info("Removing one unit ...") + _, nons = generic_utils.get_leaders_and_non_leaders(app) + zaza.model.destroy_unit(app, nons[0]) + logging.info("Wait until one unit is deleted ...") + zaza.model.block_until_unit_count(app, num) + zaza.model.wait_for_application_states() + ips = self.get_port_ips() + logging.info('hm ports are {} after deleting one unit'.format(ips)) + self.assertTrue(len(ips) == num) + def test_pause_resume(self): """Run pause and resume tests. diff --git a/zaza/openstack/utilities/generic.py b/zaza/openstack/utilities/generic.py index fcd7989..77b5d39 100644 --- a/zaza/openstack/utilities/generic.py +++ b/zaza/openstack/utilities/generic.py @@ -706,3 +706,23 @@ def attach_file_resource(application_name, resource_name, fp.flush() model.attach_resource( application_name, resource_name, fp.name) + + +def get_leaders_and_non_leaders(application_name): + """Get leader node and non-leader nodes of percona. + + Update and set on the object the leader node and list of non-leader + nodes. + + :returns: None + :rtype: None + """ + status = model.get_status().applications[application_name] + leader = None + non_leaders = [] + for unit in status["units"]: + if status["units"][unit].get("leader"): + leader = unit + else: + non_leaders.append(unit) + return leader, non_leaders From d353f3c25b6e9cb02afea5a290de0d20381174d9 Mon Sep 17 00:00:00 2001 From: Zhang Hua Date: Tue, 27 Jul 2021 13:42:56 +0800 Subject: [PATCH 2/4] Delete hm port on unit removal This is Zaza functional test for lp:1915512. Add a unit and then remove a unit, then query the list of ports to check that the port has been deleted. Depends-On: https://review.opendev.org/c/openstack/charm-octavia/+/787700 --- zaza/openstack/utilities/generic.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/zaza/openstack/utilities/generic.py b/zaza/openstack/utilities/generic.py index 77b5d39..be19c31 100644 --- a/zaza/openstack/utilities/generic.py +++ b/zaza/openstack/utilities/generic.py @@ -709,13 +709,10 @@ def attach_file_resource(application_name, resource_name, def get_leaders_and_non_leaders(application_name): - """Get leader node and non-leader nodes of percona. + """Get leader node and non-leader nodes. - Update and set on the object the leader node and list of non-leader - nodes. - - :returns: None - :rtype: None + :returns: leader, list of non-leader + :rtype: str, list of str """ status = model.get_status().applications[application_name] leader = None From 825cc8b26693e27d06e588a3b1cb8b3ed9f7ce31 Mon Sep 17 00:00:00 2001 From: Zhang Hua Date: Tue, 12 Oct 2021 19:11:38 +0800 Subject: [PATCH 3/4] Delete hm port on unit removal - part 3 This is Zaza functional test for lp:1915512. Add a unit and then remove a unit, then query the list of ports to check that the port has been deleted. Depends-On: https://review.opendev.org/c/openstack/charm-octavia/+/787700 --- zaza/openstack/charm_tests/octavia/tests.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/zaza/openstack/charm_tests/octavia/tests.py b/zaza/openstack/charm_tests/octavia/tests.py index 4ad56e7..d58923c 100644 --- a/zaza/openstack/charm_tests/octavia/tests.py +++ b/zaza/openstack/charm_tests/octavia/tests.py @@ -114,9 +114,6 @@ class CharmOperationTest(test_utils.OpenStackBaseTest): resp = neutron_client.list_ports(tags='charm-octavia') neutron_ip_list = [] for port in resp['ports']: - # one new DOWN port may be created when deleting one octavia unit - if port['status'] == 'DOWN': - continue for ip_info in port['fixed_ips']: neutron_ip_list.append(ip_info['ip_address']) return neutron_ip_list From 4cbee5bfd2ce370385fc14820b94b39a78311e68 Mon Sep 17 00:00:00 2001 From: Zhang Hua Date: Tue, 23 Nov 2021 09:37:31 +0800 Subject: [PATCH 4/4] Delete hm port on unit removal - part 4 - disabled test --- zaza/openstack/charm_tests/octavia/tests.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/zaza/openstack/charm_tests/octavia/tests.py b/zaza/openstack/charm_tests/octavia/tests.py index d58923c..6158375 100644 --- a/zaza/openstack/charm_tests/octavia/tests.py +++ b/zaza/openstack/charm_tests/octavia/tests.py @@ -17,6 +17,7 @@ import logging import subprocess import tenacity +import unittest from keystoneauth1 import exceptions as keystone_exceptions import octaviaclient.api.v2.octavia @@ -124,6 +125,7 @@ class CharmOperationTest(test_utils.OpenStackBaseTest): Add a unit and then delete a unit, then query the list of ports to check that the port has been deleted. """ + raise unittest.SkipTest("Skipping because of lp:1951858") app = self.test_config['charm_name'] logging.info("test_update_controller_ip_port_list: start test") logging.info("Wait till model is idle ...")