Merge pull request #996 from freyes/add-tempest-magnum-support
Add tempest magnum support
This commit is contained in:
72
unit_tests/charm_tests/test_magnum.py
Normal file
72
unit_tests/charm_tests/test_magnum.py
Normal file
@@ -0,0 +1,72 @@
|
||||
# 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 os
|
||||
import unittest
|
||||
|
||||
from unittest import mock
|
||||
|
||||
import zaza.openstack.charm_tests.magnum.setup as magnum_setup
|
||||
|
||||
|
||||
class TestMagnumSetup(unittest.TestCase):
|
||||
|
||||
@mock.patch.object(magnum_setup.openstack_utils,
|
||||
'get_current_os_release_pair')
|
||||
def test_get_fedora_coreos_image_url(self, get_current_os_release_pair):
|
||||
get_current_os_release_pair.return_value = 'focal_ussuri'
|
||||
self.assertEqual(magnum_setup.FEDORA_COREOS_IMAGE['ussuri'],
|
||||
magnum_setup.get_fedora_coreos_image_url())
|
||||
|
||||
self.assertEqual(magnum_setup.FEDORA_COREOS_IMAGE['xena'],
|
||||
magnum_setup.get_fedora_coreos_image_url('xena'))
|
||||
self.assertEqual(magnum_setup.DEFAULT_FEDORA_COREOS_IMAGE_URL,
|
||||
magnum_setup.get_fedora_coreos_image_url('foobar'))
|
||||
|
||||
@mock.patch.object(magnum_setup, 'get_fedora_coreos_image_url')
|
||||
@mock.patch.object(magnum_setup.openstack_utils,
|
||||
'get_overcloud_keystone_session')
|
||||
@mock.patch.object(magnum_setup.openstack_utils,
|
||||
'get_glance_session_client')
|
||||
@mock.patch.object(magnum_setup.openstack_utils,
|
||||
'create_image')
|
||||
def test_add_image(self, create_image, get_glance_session_client,
|
||||
get_overcloud_keystone_session,
|
||||
get_fedora_coreos_image_url):
|
||||
image_url = 'http://example.com/image.qcow2'
|
||||
with mock.patch.dict(os.environ,
|
||||
{'TEST_MAGNUM_QCOW2_IMAGE_URL':
|
||||
image_url},
|
||||
clear=True) as environ: # noqa:F841
|
||||
magnum_setup.add_image()
|
||||
create_image.assert_called_with(
|
||||
get_glance_session_client(),
|
||||
image_url,
|
||||
magnum_setup.IMAGE_NAME,
|
||||
properties={'os_distro': magnum_setup.IMAGE_NAME}
|
||||
)
|
||||
get_fedora_coreos_image_url.assert_not_called()
|
||||
|
||||
image_url = 'http://example.com/fedora-coreos.qcow2'
|
||||
get_fedora_coreos_image_url.return_value = image_url
|
||||
with mock.patch.dict(os.environ, {},
|
||||
clear=True) as environ: # noqa:F841
|
||||
magnum_setup.add_image()
|
||||
create_image.assert_called_with(
|
||||
get_glance_session_client(),
|
||||
image_url,
|
||||
magnum_setup.IMAGE_NAME,
|
||||
properties={'os_distro': magnum_setup.IMAGE_NAME}
|
||||
)
|
||||
get_fedora_coreos_image_url.assert_called()
|
||||
@@ -12,9 +12,11 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import mock
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from unittest import mock
|
||||
|
||||
import zaza.openstack.charm_tests.tempest.utils as tempest_utils
|
||||
|
||||
|
||||
@@ -61,3 +63,21 @@ class TestTempestUtils(unittest.TestCase):
|
||||
('Environment variables [TEST_CIDR_EXT, TEST_FIP_RANGE] must '
|
||||
'all be set to run this test'),
|
||||
str(context.exception))
|
||||
|
||||
@mock.patch.object(tempest_utils, '_add_image_id')
|
||||
def test_add_magnum_config(self, _add_image_id):
|
||||
ctxt = {}
|
||||
keystone_session = mock.MagicMock()
|
||||
with mock.patch.dict(os.environ,
|
||||
{'TEST_REGISTRY_PREFIX': '1.2.3.4:5000'},
|
||||
clear=True) as environ: # noqa:F841
|
||||
tempest_utils._add_magnum_config(ctxt, keystone_session)
|
||||
self.assertIn('test_registry_prefix', ctxt)
|
||||
self.assertEqual(ctxt['test_registry_prefix'], '1.2.3.4:5000')
|
||||
|
||||
_add_image_id.assert_called()
|
||||
ctxt = {}
|
||||
with mock.patch.dict(os.environ, {},
|
||||
clear=True) as environ: # noqa:F841
|
||||
tempest_utils._add_magnum_config(ctxt, keystone_session)
|
||||
self.assertNotIn('test_registry_prefix', ctxt)
|
||||
|
||||
@@ -42,8 +42,8 @@ class TestBaseCharmTest(ut_utils.BaseTestCase):
|
||||
return self.get_my_tests_options('aKey', 'aDefault')
|
||||
|
||||
f = FakeTest()
|
||||
self.assertEquals(f.method({}), 'aDefault')
|
||||
self.assertEquals(f.method({
|
||||
self.assertEqual(f.method({}), 'aDefault')
|
||||
self.assertEqual(f.method({
|
||||
'tests_options': {
|
||||
'unit_tests.charm_tests.test_utils.'
|
||||
'FakeTest.method.aKey': 'aValue',
|
||||
|
||||
@@ -127,7 +127,7 @@ class TestCephUtils(ut_utils.BaseTestCase):
|
||||
'{"op": "create-pool", "name": "cinder-ceph", '
|
||||
'"compression-mode": "aggressive"}]}'),
|
||||
}
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
ceph_utils.get_pools_from_broker_req(
|
||||
'anApplication', 'aModelName'),
|
||||
['cinder-ceph'])
|
||||
|
||||
@@ -1322,7 +1322,7 @@ class TestOpenStackUtils(ut_utils.BaseTestCase):
|
||||
self.patch_object(openstack_utils.juju_utils,
|
||||
'get_machine_uuids_for_application')
|
||||
self.get_machine_uuids_for_application.return_value = 'ret'
|
||||
self.assertEquals(openstack_utils.get_gateway_uuids(), 'ret')
|
||||
self.assertEqual(openstack_utils.get_gateway_uuids(), 'ret')
|
||||
self.get_machine_uuids_for_application.assert_called_once_with(
|
||||
'neutron-gateway')
|
||||
|
||||
@@ -1330,7 +1330,7 @@ class TestOpenStackUtils(ut_utils.BaseTestCase):
|
||||
self.patch_object(openstack_utils.juju_utils,
|
||||
'get_machine_uuids_for_application')
|
||||
self.get_machine_uuids_for_application.return_value = 'ret'
|
||||
self.assertEquals(openstack_utils.get_ovs_uuids(), 'ret')
|
||||
self.assertEqual(openstack_utils.get_ovs_uuids(), 'ret')
|
||||
self.get_machine_uuids_for_application.assert_called_once_with(
|
||||
'neutron-openvswitch')
|
||||
|
||||
@@ -1338,8 +1338,8 @@ class TestOpenStackUtils(ut_utils.BaseTestCase):
|
||||
self.patch_object(openstack_utils.juju_utils,
|
||||
'get_machine_uuids_for_application')
|
||||
self.get_machine_uuids_for_application.return_value = ['ret']
|
||||
self.assertEquals(list(openstack_utils.get_ovn_uuids()),
|
||||
['ret', 'ret'])
|
||||
self.assertEqual(list(openstack_utils.get_ovn_uuids()),
|
||||
['ret', 'ret'])
|
||||
self.get_machine_uuids_for_application.assert_has_calls([
|
||||
mock.call('ovn-chassis'),
|
||||
mock.call('ovn-dedicated-chassis'),
|
||||
@@ -1387,7 +1387,7 @@ class TestOpenStackUtils(ut_utils.BaseTestCase):
|
||||
with self.assertRaises(RuntimeError):
|
||||
openstack_utils.get_charm_networking_data()
|
||||
self.ngw_present.return_value = True
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
openstack_utils.get_charm_networking_data(),
|
||||
openstack_utils.CharmedOpenStackNetworkingData(
|
||||
openstack_utils.OpenStackNetworkingTopology.ML2_OVS,
|
||||
@@ -1396,7 +1396,7 @@ class TestOpenStackUtils(ut_utils.BaseTestCase):
|
||||
'data-port',
|
||||
{}))
|
||||
self.dvr_enabled.return_value = True
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
openstack_utils.get_charm_networking_data(),
|
||||
openstack_utils.CharmedOpenStackNetworkingData(
|
||||
openstack_utils.OpenStackNetworkingTopology.ML2_OVS_DVR,
|
||||
@@ -1405,7 +1405,7 @@ class TestOpenStackUtils(ut_utils.BaseTestCase):
|
||||
'data-port',
|
||||
{}))
|
||||
self.ngw_present.return_value = False
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
openstack_utils.get_charm_networking_data(),
|
||||
openstack_utils.CharmedOpenStackNetworkingData(
|
||||
openstack_utils.OpenStackNetworkingTopology.ML2_OVS_DVR_SNAT,
|
||||
@@ -1415,7 +1415,7 @@ class TestOpenStackUtils(ut_utils.BaseTestCase):
|
||||
{}))
|
||||
self.dvr_enabled.return_value = False
|
||||
self.ovn_present.return_value = True
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
openstack_utils.get_charm_networking_data(),
|
||||
openstack_utils.CharmedOpenStackNetworkingData(
|
||||
openstack_utils.OpenStackNetworkingTopology.ML2_OVN,
|
||||
@@ -1424,7 +1424,7 @@ class TestOpenStackUtils(ut_utils.BaseTestCase):
|
||||
'bridge-interface-mappings',
|
||||
{'ovn-bridge-mappings': 'physnet1:br-ex'}))
|
||||
self.get_application.side_effect = None
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
openstack_utils.get_charm_networking_data(),
|
||||
openstack_utils.CharmedOpenStackNetworkingData(
|
||||
openstack_utils.OpenStackNetworkingTopology.ML2_OVN,
|
||||
|
||||
@@ -147,7 +147,7 @@ class CephFSTests(unittest.TestCase):
|
||||
"""
|
||||
model.set_application_config('ceph-fs', mds_config)
|
||||
results = _get_conf()
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
results['mds_cache_memory_limit'],
|
||||
mds_config['mds-cache-memory-limit'])
|
||||
self.assertAlmostEqual(
|
||||
|
||||
@@ -1323,12 +1323,12 @@ class BlueStoreCompressionCharmOperation(test_utils.BaseCharmTest):
|
||||
if pd['pool_name'] == pool:
|
||||
if 'options' in expected_properties:
|
||||
for k, v in expected_properties['options'].items():
|
||||
self.assertEquals(pd['options'][k], v)
|
||||
self.assertEqual(pd['options'][k], v)
|
||||
log_func("['options']['{}'] == {}".format(k, v))
|
||||
for k, v in expected_properties.items():
|
||||
if k == 'options':
|
||||
continue
|
||||
self.assertEquals(pd[k], v)
|
||||
self.assertEqual(pd[k], v)
|
||||
log_func("{} == {}".format(k, v))
|
||||
|
||||
def test_configure_compression(self):
|
||||
|
||||
@@ -23,8 +23,30 @@ import tenacity
|
||||
import zaza.model
|
||||
import zaza.openstack.utilities.openstack as openstack_utils
|
||||
|
||||
TEST_SWIFT_IP = os.environ.get('TEST_SWIFT_IP')
|
||||
IMAGE_NAME = 'fedora-coreos'
|
||||
|
||||
# https://docs.openstack.org/magnum/latest/user/index.html#supported-versions
|
||||
# List of published image available at:
|
||||
# https://builds.coreos.fedoraproject.org/browser?stream=stable&arch=x86_64
|
||||
#
|
||||
# Source images:
|
||||
# https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/35.20220424.3.0/x86_64/fedora-coreos-35.20220424.3.0-openstack.x86_64.qcow2.xz # noqa
|
||||
# https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/31.20200517.3.0/x86_64/fedora-coreos-31.20200517.3.0-openstack.x86_64.qcow2.xz # noqa
|
||||
# https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/32.20201104.3.0/x86_64/fedora-coreos-32.20201104.3.0-openstack.x86_64.qcow2.xz # noqa
|
||||
FEDORA_COREOS_31 = 'http://%s/magnum/images/fedora-coreos-31.qcow2' % TEST_SWIFT_IP # noqa
|
||||
FEDORA_COREOS_32 = 'http://%s/magnum/images/fedora-coreos-32.qcow2' % TEST_SWIFT_IP # noqa
|
||||
FEDORA_COREOS_35 = 'http://%s/magnum/images/fedora-coreos-35.qcow2' % TEST_SWIFT_IP # noqa
|
||||
DEFAULT_FEDORA_COREOS_IMAGE_URL = FEDORA_COREOS_35
|
||||
FEDORA_COREOS_IMAGE = {
|
||||
'ussuri': FEDORA_COREOS_32,
|
||||
'victoria': FEDORA_COREOS_31,
|
||||
'wallaby': FEDORA_COREOS_31,
|
||||
'xena': FEDORA_COREOS_31,
|
||||
'yoga': FEDORA_COREOS_35,
|
||||
'zed': FEDORA_COREOS_35,
|
||||
}
|
||||
|
||||
|
||||
def domain_setup(application_name='magnum'):
|
||||
"""Run required action for a working Magnum application."""
|
||||
@@ -37,6 +59,25 @@ def domain_setup(application_name='magnum'):
|
||||
"Unit is ready")
|
||||
|
||||
|
||||
def get_fedora_coreos_image_url(os_release: str = None) -> str:
|
||||
"""Get Fedora CoreOS image url compatible with the Magnum release deployed.
|
||||
|
||||
:param os_release: OpenStack release codename (e.g. ussuri).
|
||||
:returns: url where the image can be GET.
|
||||
"""
|
||||
if not os_release:
|
||||
pair = openstack_utils.get_current_os_release_pair('keystone')
|
||||
os_release = pair.split('_', 1)[1]
|
||||
if os_release in FEDORA_COREOS_IMAGE:
|
||||
return FEDORA_COREOS_IMAGE[os_release]
|
||||
else:
|
||||
logging.warning(
|
||||
'No image found for OpenStack %s, using default image %s',
|
||||
os_release, DEFAULT_FEDORA_COREOS_IMAGE_URL
|
||||
)
|
||||
return DEFAULT_FEDORA_COREOS_IMAGE_URL
|
||||
|
||||
|
||||
def add_image(image_url=None):
|
||||
"""Upload Magnum image.
|
||||
|
||||
@@ -47,9 +88,8 @@ def add_image(image_url=None):
|
||||
:type image_url: str
|
||||
"""
|
||||
image_url = image_url or os.environ.get(
|
||||
'TEST_MAGNUM_QCOW2_IMAGE_URL', None)
|
||||
if image_url is None:
|
||||
raise ValueError("Missing image_url")
|
||||
'TEST_MAGNUM_QCOW2_IMAGE_URL', None) or get_fedora_coreos_image_url()
|
||||
|
||||
for attempt in tenacity.Retrying(
|
||||
stop=tenacity.stop_after_attempt(3),
|
||||
reraise=True):
|
||||
|
||||
16
zaza/openstack/charm_tests/magnum/upload_fedora_coreos_images.sh
Executable file
16
zaza/openstack/charm_tests/magnum/upload_fedora_coreos_images.sh
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
wget -O - https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/31.20200517.3.0/x86_64/fedora-coreos-31.20200517.3.0-openstack.x86_64.qcow2.xz \
|
||||
| xzcat > ./fedora-coreos-31.qcow2
|
||||
|
||||
openstack object create --name images/fedora-coreos-31.qcow2 magnum ./fedora-coreos-31.qcow2
|
||||
|
||||
wget -O - https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/32.20201104.3.0/x86_64/fedora-coreos-32.20201104.3.0-openstack.x86_64.qcow2.xz \
|
||||
| xzcat > ./fedora-coreos-32.qcow2
|
||||
|
||||
openstack object create --name images/fedora-coreos-32.qcow2 magnum ./fedora-coreos-32.qcow2
|
||||
|
||||
wget -O - https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/35.20220424.3.0/x86_64/fedora-coreos-35.20220424.3.0-openstack.x86_64.qcow2.xz \
|
||||
| xzcat > ./fedora-coreos-35.qcow2
|
||||
|
||||
openstack object create --name images/fedora-coreos-35.qcow2 magnum ./fedora-coreos-35.qcow2
|
||||
@@ -122,5 +122,19 @@ test_server_path = {{ workspace_path }}/test_server.bin
|
||||
provider = amphora
|
||||
{% endif %}
|
||||
|
||||
{%- if 'magnum' in enabled_services %}
|
||||
[magnum]
|
||||
nic_id = {{ ext_net }}
|
||||
image_id = {{ fedora_coreos_id }}
|
||||
master_flavor_id = {{ flavor_ref }}
|
||||
flavor_id = {{ flavor_ref }}
|
||||
dns_nameserver = {{ test_name_server }}
|
||||
network_driver = flannel
|
||||
{%- if test_registry_prefix %}
|
||||
labels = container_infra_prefix:{{ test_registry_prefix }}
|
||||
insecure_registry = {{ test_registry_prefix }}
|
||||
{%- endif %}
|
||||
{%- endif %}
|
||||
|
||||
[dns]
|
||||
nameservers = {{ test_name_server }}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
"""Utility code for working with tempest workspaces."""
|
||||
|
||||
import jinja2
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
@@ -28,6 +29,7 @@ import zaza.utilities.deployment_env as deployment_env
|
||||
import zaza.openstack.utilities.juju as juju_utils
|
||||
import zaza.openstack.utilities.openstack as openstack_utils
|
||||
import zaza.openstack.charm_tests.glance.setup as glance_setup
|
||||
import zaza.openstack.charm_tests.magnum.setup as magnum_setup
|
||||
|
||||
SETUP_ENV_VARS = {
|
||||
'neutron': ['TEST_GATEWAY', 'TEST_CIDR_EXT', 'TEST_FIP_RANGE',
|
||||
@@ -156,7 +158,9 @@ def _get_tempest_context(workspace_path, missing_fatal=True):
|
||||
'neutron': _add_neutron_config,
|
||||
'glance': _add_glance_config,
|
||||
'cinder': _add_cinder_config,
|
||||
'keystone': _add_keystone_config}
|
||||
'keystone': _add_keystone_config,
|
||||
'magnum': _add_magnum_config,
|
||||
}
|
||||
ctxt['enabled_services'] = _get_service_list(keystone_session)
|
||||
if set(['cinderv2', 'cinderv3']) \
|
||||
.intersection(set(ctxt['enabled_services'])):
|
||||
@@ -284,16 +288,39 @@ def _add_glance_config(ctxt, keystone_session, missing_fatal=True):
|
||||
:returns: None
|
||||
:rtype: None
|
||||
"""
|
||||
_add_image_id(ctxt, keystone_session,
|
||||
glance_setup.CIRROS_IMAGE_NAME, 'image_id',
|
||||
missing_fatal)
|
||||
_add_image_id(ctxt, keystone_session,
|
||||
glance_setup.CIRROS_ALT_IMAGE_NAME, 'image_alt_id',
|
||||
missing_fatal)
|
||||
|
||||
|
||||
def _add_image_id(ctxt, keystone_session, image_name, ctxt_key,
|
||||
missing_fatal=True):
|
||||
"""Add an image id to the context.
|
||||
|
||||
:param ctxt: Context dictionary
|
||||
:type ctxt: dict
|
||||
:param keystone_session: keystoneauth1.session.Session object
|
||||
:type: keystoneauth1.session.Session
|
||||
:param image_name: Image's name to search in glance.
|
||||
:type image_name: str
|
||||
:param ctxt_key: key to use when adding the image id to the context.
|
||||
:type ctxt_key: str
|
||||
:param missing_fatal: Raise an exception if a resource is missing
|
||||
:type missing_fatal: bool
|
||||
"""
|
||||
glance_client = openstack_utils.get_glance_session_client(
|
||||
keystone_session)
|
||||
image = openstack_utils.get_images_by_name(
|
||||
glance_client, glance_setup.CIRROS_IMAGE_NAME)
|
||||
image_alt = openstack_utils.get_images_by_name(
|
||||
glance_client, glance_setup.CIRROS_ALT_IMAGE_NAME)
|
||||
image = openstack_utils.get_images_by_name(glance_client, image_name)
|
||||
if image:
|
||||
ctxt['image_id'] = image[0].id
|
||||
if image_alt:
|
||||
ctxt['image_alt_id'] = image_alt[0].id
|
||||
ctxt[ctxt_key] = image[0].id
|
||||
else:
|
||||
msg = 'Image %s not found' % image_name
|
||||
logging.warning(msg)
|
||||
if missing_fatal:
|
||||
raise Exception(msg)
|
||||
|
||||
|
||||
def _add_cinder_config(ctxt, keystone_session, missing_fatal=True):
|
||||
@@ -360,6 +387,27 @@ def _add_octavia_config(ctxt, missing_fatal=True):
|
||||
])
|
||||
|
||||
|
||||
def _add_magnum_config(ctxt, keystone_session, missing_fatal=True):
|
||||
"""Add magnum config to context.
|
||||
|
||||
:param ctxt: Context dictionary
|
||||
:type ctxt: dict
|
||||
:param missing_fatal: Raise an exception if a resource is missing
|
||||
:type missing_fatal: bool
|
||||
:returns: None
|
||||
:rtype: None
|
||||
:raises: subprocess.CalledProcessError
|
||||
"""
|
||||
_add_image_id(ctxt, keystone_session,
|
||||
magnum_setup.IMAGE_NAME, 'fedora_coreos_id',
|
||||
missing_fatal)
|
||||
test_registry_prefix = os.environ.get('TEST_REGISTRY_PREFIX')
|
||||
if test_registry_prefix:
|
||||
ctxt['test_registry_prefix'] = test_registry_prefix
|
||||
else:
|
||||
logging.warning('Environment variable TEST_REGISTRY_PREFIX not found')
|
||||
|
||||
|
||||
def _add_environment_var_config(ctxt, services, missing_fatal=True):
|
||||
"""Add environment variable config to context.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user