From 4bf3dc4c0707aeed96a539153f109ff1a7809f49 Mon Sep 17 00:00:00 2001 From: Alex Kavanagh Date: Thu, 7 Dec 2023 10:05:06 +0000 Subject: [PATCH 1/3] Add octavia to UPGRADE_SERVICES (cherry picked from commit cabe30044a05e766aec64e6d74d79673027958b2) (cherry picked from commit de9b0cac8b54e22a4f2bb86af2b45ad5179f3d35) --- zaza/openstack/utilities/openstack.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/zaza/openstack/utilities/openstack.py b/zaza/openstack/utilities/openstack.py index 18e88d76b..65e653475 100644 --- a/zaza/openstack/utilities/openstack.py +++ b/zaza/openstack/utilities/openstack.py @@ -137,6 +137,10 @@ 'pkg': 'placement-common', 'origin_setting': 'openstack-origin' }, + 'octavia': { + 'pkg': 'octavia-common', + 'origin_setting': 'openstack-origin' + }, } # Older tests use the order the services appear in the list to imply @@ -158,6 +162,7 @@ {'name': 'ovn-central', 'type': CHARM_TYPES['ovn-central']}, {'name': 'ceph-mon', 'type': CHARM_TYPES['ceph-mon']}, {'name': 'placement', 'type': CHARM_TYPES['placement']}, + {'name': 'octavia', 'type': CHARM_TYPES['octavia']}, ] From d780c3a41b167f8f5aa2964d44c6079bf1a0c81f Mon Sep 17 00:00:00 2001 From: Felipe Reyes Date: Tue, 28 Mar 2023 15:01:56 -0300 Subject: [PATCH 2/3] Add CompareOpenStack class. The CompareOpenStack class allows the comparison of OpenStack codenames. (cherry picked from commit 7205e31753da891aa835b4d911a51c28dc019001) (cherry picked from commit f2ef3ac897c770d99f890688b541d9cbc5cf620a) --- .../test_zaza_utilities_os_versions.py | 32 +++++ zaza/openstack/utilities/os_versions.py | 120 ++++++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 unit_tests/utilities/test_zaza_utilities_os_versions.py diff --git a/unit_tests/utilities/test_zaza_utilities_os_versions.py b/unit_tests/utilities/test_zaza_utilities_os_versions.py new file mode 100644 index 000000000..86b0f6220 --- /dev/null +++ b/unit_tests/utilities/test_zaza_utilities_os_versions.py @@ -0,0 +1,32 @@ +# Copyright 2023 Canonical Ltd. +# +# 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 unit_tests.utils as ut_utils +from zaza.openstack.utilities import os_versions + + +class TestOpenStackUtils(ut_utils.BaseTestCase): + + def test_compare_openstack(self): + yoga = os_versions.CompareOpenStack('yoga') + xena = os_versions.CompareOpenStack('xena') + wallaby = os_versions.CompareOpenStack('wallaby') + self.assertGreater(yoga, xena) + self.assertLess(xena, yoga) + self.assertGreaterEqual(xena, xena) + self.assertGreaterEqual(yoga, yoga) + self.assertGreaterEqual(yoga, wallaby) + + self.assertEqual("CompareOpenStack", repr(xena)) diff --git a/zaza/openstack/utilities/os_versions.py b/zaza/openstack/utilities/os_versions.py index 2ea089e2f..9d872ceae 100644 --- a/zaza/openstack/utilities/os_versions.py +++ b/zaza/openstack/utilities/os_versions.py @@ -274,3 +274,123 @@ ('4', 'victoria'), ]), } + + +UBUNTU_RELEASES = ( + 'lucid', + 'maverick', + 'natty', + 'oneiric', + 'precise', + 'quantal', + 'raring', + 'saucy', + 'trusty', + 'utopic', + 'vivid', + 'wily', + 'xenial', + 'yakkety', + 'zesty', + 'artful', + 'bionic', + 'cosmic', + 'disco', + 'eoan', + 'focal', + 'groovy', + 'hirsute', + 'impish', + 'jammy', +) + + +class BasicStringComparator(object): + """Provides a class that will compare strings from an iterator type object. + + Used to provide > and < comparisons on strings that may not necessarily be + alphanumerically ordered. e.g. OpenStack or Ubuntu releases AFTER the + z-wrap. + """ + + _list = None + + def __init__(self, item): + """Do init.""" + if self._list is None: + raise Exception("Must define the _list in the class definition!") + try: + self.index = self._list.index(item) + except Exception: + raise KeyError("Item '{}' is not in list '{}'" + .format(item, self._list)) + + def __eq__(self, other): + """Do equals.""" + assert isinstance(other, str) or isinstance(other, self.__class__) + return self.index == self._list.index(other) + + def __ne__(self, other): + """Do not equals.""" + return not self.__eq__(other) + + def __lt__(self, other): + """Do less than.""" + assert isinstance(other, str) or isinstance(other, self.__class__) + return self.index < self._list.index(other) + + def __ge__(self, other): + """Do greater than or equal.""" + return not self.__lt__(other) + + def __gt__(self, other): + """Do greater than.""" + assert isinstance(other, str) or isinstance(other, self.__class__) + return self.index > self._list.index(other) + + def __le__(self, other): + """Do less than or equals.""" + return not self.__gt__(other) + + def __repr__(self): + """Return the representation of CompareOpenStack.""" + return "%s<%s>" % (self.__class__.__name__, self._list[self.index]) + + def __str__(self): + """Give back the item at the index. + + This is so it can be used in comparisons like: + + s_mitaka = CompareOpenStack('mitaka') + s_newton = CompareOpenstack('newton') + + assert s_newton > s_mitaka + + :returns: + """ + return self._list[self.index] + + +class CompareHostReleases(BasicStringComparator): + """Provide comparisons of Ubuntu releases. + + Use in the form of + + if CompareHostReleases(release) > 'trusty': + # do something with mitaka + """ + + _list = UBUNTU_RELEASES + + +class CompareOpenStack(BasicStringComparator): + """Provide comparisons of OpenStack releases. + + Use in the form of + + if CompareOpenStack(release) > 'yoga': + # do something + """ + + _list = list(OPENSTACK_CODENAMES.values()) + From a0e256c38043bc1420cb9cae77a185d8408ec98e Mon Sep 17 00:00:00 2001 From: Nicholas Njihia Date: Wed, 22 Sep 2021 17:15:48 +0300 Subject: [PATCH 3/3] Add Octavia volume-based Amphora test Enable Amphora to run instances booted from volume by flipping the config option `enable-volume-based-amphora` to True and checking volumes attached to the amphora instances. Depends-On: https://review.opendev.org/c/openstack/charm-octavia/+/931587 Related-Bug: https://launchpad.net/bugs/1901732 (cherry picked from commit d09609625da0f6e7ea13ea33b818ae88f347cbd7) (cherry picked from commit f0f60a5dd6dd8c0f9899d519cddea9fde28f72b5) --- .../test_zaza_utilities_os_versions.py | 10 +-- zaza/openstack/charm_tests/octavia/tests.py | 63 ++++++++++++++++--- zaza/openstack/utilities/os_versions.py | 8 ++- 3 files changed, 68 insertions(+), 13 deletions(-) diff --git a/unit_tests/utilities/test_zaza_utilities_os_versions.py b/unit_tests/utilities/test_zaza_utilities_os_versions.py index 86b0f6220..6a6742b07 100644 --- a/unit_tests/utilities/test_zaza_utilities_os_versions.py +++ b/unit_tests/utilities/test_zaza_utilities_os_versions.py @@ -20,13 +20,13 @@ class TestOpenStackUtils(ut_utils.BaseTestCase): def test_compare_openstack(self): - yoga = os_versions.CompareOpenStack('yoga') xena = os_versions.CompareOpenStack('xena') wallaby = os_versions.CompareOpenStack('wallaby') - self.assertGreater(yoga, xena) - self.assertLess(xena, yoga) + victoria = os_versions.CompareOpenStack('victoria') + self.assertGreater(xena, wallaby) + self.assertLess(wallaby, xena) self.assertGreaterEqual(xena, xena) - self.assertGreaterEqual(yoga, yoga) - self.assertGreaterEqual(yoga, wallaby) + self.assertGreaterEqual(wallaby, wallaby) + self.assertGreaterEqual(xena, victoria) self.assertEqual("CompareOpenStack", repr(xena)) diff --git a/zaza/openstack/charm_tests/octavia/tests.py b/zaza/openstack/charm_tests/octavia/tests.py index 2854867ad..c1288eec9 100644 --- a/zaza/openstack/charm_tests/octavia/tests.py +++ b/zaza/openstack/charm_tests/octavia/tests.py @@ -14,6 +14,7 @@ """Encapsulate octavia testing.""" +import json import logging import subprocess import tenacity @@ -30,6 +31,7 @@ LoadBalancerUnexpectedState, LoadBalancerUnrecoverableError, ) +from zaza.openstack.utilities.os_versions import CompareOpenStack LBAAS_ADMIN_ROLE = 'load-balancer_admin' @@ -140,12 +142,6 @@ def setUpClass(cls): cls.keystone_client = ObjectRetrierWraps( openstack_utils.get_keystone_session_client(cls.keystone_session)) - if (openstack_utils.get_os_release() >= - openstack_utils.get_os_release('focal_wallaby')): - # add role to admin user for the duration of the test - grant_role_current_user(cls.keystone_client, cls.keystone_session, - LBAAS_ADMIN_ROLE) - cls.neutron_client = ObjectRetrierWraps( openstack_utils.get_neutron_session_client(cls.keystone_session)) cls.octavia_client = ObjectRetrierWraps( @@ -163,6 +159,16 @@ def setUpClass(cls): # List of floating IPs created by this test cls.fips = [] + def setUp(self): + """Configure the octavia test environment.""" + super(LBAASv2Test, self).setUp() + if (openstack_utils.get_os_release() >= + openstack_utils.get_os_release('focal_wallaby')): + # add role to admin user for the duration of the test + grant_role_current_user(self.keystone_client, + self.keystone_session, + LBAAS_ADMIN_ROLE) + def _remove_amphorae_instances(self): """Remove amphorae instances forcefully. @@ -193,6 +199,7 @@ def resource_cleanup(self, only_local=False): :param only_local: When set to true do not call parent method :type only_local: bool """ + logging.info("deleting loadbalancer(s): {}".format(self.loadbalancers)) for lb in self.loadbalancers: try: self.octavia_client.load_balancer_delete( @@ -399,7 +406,7 @@ def _get_payload(ip): 'http://{}/'.format(ip)], universal_newlines=True) - def test_create_loadbalancer(self): + def create_loadbalancer(self, ensure_volume_backed=False): """Create load balancer.""" # Prepare payload instances # First we allow communication to port 80 by adding a security group @@ -466,5 +473,47 @@ def test_create_loadbalancer(self): .format(snippet, provider, lb_fp['floating_ip_address'])) + if ensure_volume_backed: + amphora_list = self.octavia_client.amphora_list() + self.assertTrue(len(amphora_list) > 0) + attached_volumes = [] + for amphora in amphora_list.get('amphorae', []): + server_id = amphora['compute_id'] + logging.info("Checking amphora {} server {} for attached " + "volumes".format(amphora['id'], server_id)) + volumes = self.nova_client.volumes.get_server_volumes( + server_id) + logging.info('amphora {} server {} has volumes={}'. + format(amphora['id'], + server_id, volumes)) + attached_volumes.append(json.dumps(vars(volumes))) + + self.assertTrue(len(attached_volumes) > 0) + logging.info("Amphora volumes creation successful: {}".format( + attached_volumes)) + # If we get here, it means the tests passed self.run_resource_cleanup = True + + def test_create_loadbalancer(self): + """Test creating a load balancer.""" + self.create_loadbalancer() + + +class OctaviaVolumeBackedAmphoraTest(LBAASv2Test): + """Octavia service tests.""" + + def test_volume_backed_amphora(self): + """Test volume-backed amphora load balancer.""" + os_versions = openstack_utils.get_current_os_versions(['octavia']) + if CompareOpenStack(os_versions['octavia']) < 'ussuri': + self.skipTest('Run only for Openstack Ussuri and newer releases.') + return + + """Test creating a load balancer that uses volume-based amphora.""" + default_charm_config = {'enable-volume-based-amphora': False} + alternate_charm_config = {'enable-volume-based-amphora': True} + with self.config_change(default_charm_config, + alternate_charm_config, reset_to_charm_default=True): + logging.info("Testing create volume-backed amphora loadbalancer") + self.create_loadbalancer(ensure_volume_backed=True) diff --git a/zaza/openstack/utilities/os_versions.py b/zaza/openstack/utilities/os_versions.py index 9d872ceae..746c448b0 100644 --- a/zaza/openstack/utilities/os_versions.py +++ b/zaza/openstack/utilities/os_versions.py @@ -61,6 +61,8 @@ ('2019.2', 'train'), ('2020.1', 'ussuri'), ('2020.2', 'victoria'), + ('2021.1', 'wallaby'), + ('2021.2', 'xena'), ]) OPENSTACK_RELEASES_PAIRS = [ @@ -273,6 +275,11 @@ ('3', 'ussuri'), ('4', 'victoria'), ]), + 'octavia-common': OrderedDict([ + ('5', 'train'), + ('6', 'ussuri'), + ('7', 'victoria'), + ]), } @@ -393,4 +400,3 @@ class CompareOpenStack(BasicStringComparator): """ _list = list(OPENSTACK_CODENAMES.values()) -