This change adds a new `trilio_compat_version` that can be used in templates when an option is gated on the trilio Major and Minor version. The config option cannot be used for examining atch versions as it relies on a float representation of the package version. Change-Id: I9221188b817fbb570700406b97e194aacf6ef786
689 lines
26 KiB
Python
689 lines
26 KiB
Python
import unittest.mock as mock
|
|
import os
|
|
|
|
from unit_tests.charms_openstack.charm.utils import BaseOpenStackCharmTest
|
|
from unit_tests.utils import BaseTestCase, patch_open
|
|
|
|
import charms_openstack.charm.core as co_core
|
|
import charms_openstack.plugins.trilio as trilio
|
|
|
|
|
|
class TrilioVaultFoobar(trilio.TrilioVaultCharm):
|
|
|
|
abstract_class = True
|
|
name = 'test'
|
|
all_packages = ['foo', 'bar']
|
|
os_release_pkg = 'nova-common'
|
|
|
|
@classmethod
|
|
def trilio_version_package(cls):
|
|
return "dmapi"
|
|
|
|
|
|
class TrilioVaultFoobarSubordinate(trilio.TrilioVaultSubordinateCharm):
|
|
|
|
abstract_class = True
|
|
name = 'testsubordinate'
|
|
all_packages = ['foo', 'bar', 'baz']
|
|
|
|
|
|
class TestTrilioCharmGhostAction(BaseOpenStackCharmTest):
|
|
|
|
_nfs_share = "10.20.30.40:/srv/trilioshare"
|
|
_ghost_share = "50.20.30.40:/srv/trilioghostshare"
|
|
|
|
def setUp(self):
|
|
super().setUp(trilio.TrilioVaultCharmGhostAction, {})
|
|
self.patch_object(trilio.ch_core.hookenv, "config")
|
|
self.patch_object(trilio.ch_core.host, "mounts")
|
|
self.patch_object(trilio.ch_core.host, "mount")
|
|
self.patch_object(trilio.os.path, "exists")
|
|
self.patch_object(trilio.os, "mkdir")
|
|
|
|
self.trilio_charm = trilio.TrilioVaultCharmGhostAction()
|
|
self._nfs_path = os.path.join(
|
|
trilio.TV_MOUNTS,
|
|
self.trilio_charm._encode_endpoint(self._nfs_share),
|
|
)
|
|
self._ghost_path = os.path.join(
|
|
trilio.TV_MOUNTS,
|
|
self.trilio_charm._encode_endpoint(self._ghost_share),
|
|
)
|
|
|
|
def test__ghost_nfs_share(self):
|
|
self.config.return_value = self._nfs_share
|
|
self.mounts.return_value = [
|
|
["/srv/nova", "/dev/sda"],
|
|
[self._nfs_path, self._nfs_share],
|
|
]
|
|
self.exists.return_value = False
|
|
self.trilio_charm._ghost_nfs_share(self._nfs_share,
|
|
self._ghost_share)
|
|
self.exists.assert_called_once_with(self._ghost_path)
|
|
self.mkdir.assert_called_once_with(self._ghost_path)
|
|
self.mount.assert_called_once_with(
|
|
self._nfs_path, self._ghost_path, options="bind"
|
|
)
|
|
|
|
def test__ghost_nfs_share_already_bound(self):
|
|
self.config.return_value = self._nfs_share
|
|
self.mounts.return_value = [
|
|
["/srv/nova", "/dev/sda"],
|
|
[self._nfs_path, self._nfs_share],
|
|
[self._ghost_path, self._nfs_share],
|
|
]
|
|
with self.assertRaises(trilio.GhostShareAlreadyMountedException):
|
|
self.trilio_charm._ghost_nfs_share(self._nfs_share,
|
|
self._ghost_share)
|
|
self.mount.assert_not_called()
|
|
|
|
def test__ghost_nfs_share_nfs_unmounted(self):
|
|
self.config.return_value = self._nfs_share
|
|
self.mounts.return_value = [["/srv/nova", "/dev/sda"]]
|
|
self.exists.return_value = False
|
|
with self.assertRaises(trilio.NFSShareNotMountedException):
|
|
self.trilio_charm._ghost_nfs_share(self._nfs_share,
|
|
self._ghost_share)
|
|
self.mount.assert_not_called()
|
|
|
|
def test_ghost_nfs_share(self):
|
|
self.patch_object(self.trilio_charm, "_ghost_nfs_share")
|
|
self.config.return_value = (
|
|
"10.20.30.40:/srv/trilioshare,10.20.30.40:/srv/trilioshare2"
|
|
)
|
|
self.trilio_charm.ghost_nfs_share(
|
|
"50.20.30.40:/srv/trilioshare,50.20.30.40:/srv/trilioshare2"
|
|
)
|
|
self._ghost_nfs_share.assert_has_calls([
|
|
mock.call("10.20.30.40:/srv/trilioshare",
|
|
"50.20.30.40:/srv/trilioshare"),
|
|
mock.call("10.20.30.40:/srv/trilioshare2",
|
|
"50.20.30.40:/srv/trilioshare2")
|
|
])
|
|
|
|
def test_ghost_nfs_share_mismatch(self):
|
|
self.patch_object(self.trilio_charm, "_ghost_nfs_share")
|
|
self.config.return_value = (
|
|
"10.20.30.40:/srv/trilioshare,10.20.30.40:/srv/trilioshare2"
|
|
)
|
|
with self.assertRaises(trilio.MismatchedConfigurationException):
|
|
self.trilio_charm.ghost_nfs_share(
|
|
"50.20.30.40:/srv/trilioshare"
|
|
)
|
|
|
|
|
|
class TestTrilioVault42CharmGhostAction(BaseOpenStackCharmTest):
|
|
|
|
_nfs_share = "10.20.30.40:/srv/trilioshare"
|
|
_ghost_share = "50.20.30.40:/srv/trilioghostshare"
|
|
|
|
def setUp(self):
|
|
super().setUp(trilio.TrilioVaultCharmGhostAction, {})
|
|
self.patch_object(trilio.ch_core.hookenv, "config")
|
|
self.patch_object(trilio.ch_core.host, "mounts")
|
|
self.patch_object(trilio.ch_core.host, "mount")
|
|
self.patch_object(trilio.os.path, "exists")
|
|
self.patch_object(trilio.os, "mkdir")
|
|
|
|
self.trilio_charm = trilio.TrilioVault42CharmGhostAction()
|
|
self._nfs_path = os.path.join(
|
|
trilio.TV_MOUNTS,
|
|
self.trilio_charm._encode_endpoint(self._nfs_share),
|
|
)
|
|
self._ghost_path = os.path.join(
|
|
trilio.TV_MOUNTS,
|
|
self.trilio_charm._encode_endpoint(self._ghost_share),
|
|
)
|
|
|
|
def test__ghost_nfs_share(self):
|
|
self.config.return_value = self._nfs_share
|
|
self.mounts.return_value = [
|
|
["/srv/nova", "/dev/sda"],
|
|
[self._nfs_path, self._nfs_share],
|
|
]
|
|
self.exists.return_value = False
|
|
self.trilio_charm._ghost_nfs_share(self._nfs_share,
|
|
self._ghost_share)
|
|
self.exists.assert_called_once_with(self._ghost_path)
|
|
self.mkdir.assert_called_once_with(self._ghost_path)
|
|
self.mount.assert_called_once_with(
|
|
self._nfs_path, self._ghost_path, options="bind"
|
|
)
|
|
|
|
def test__ghost_nfs_share_already_bound(self):
|
|
self.config.return_value = self._nfs_share
|
|
self.mounts.return_value = [
|
|
["/srv/nova", "/dev/sda"],
|
|
[self._nfs_path, self._nfs_share],
|
|
[self._ghost_path, self._nfs_share],
|
|
]
|
|
with self.assertRaises(trilio.GhostShareAlreadyMountedException):
|
|
self.trilio_charm._ghost_nfs_share(self._nfs_share,
|
|
self._ghost_share)
|
|
self.mount.assert_not_called()
|
|
|
|
def test__ghost_nfs_share_nfs_unmounted(self):
|
|
self.config.return_value = self._nfs_share
|
|
self.mounts.return_value = [["/srv/nova", "/dev/sda"]]
|
|
self.exists.return_value = False
|
|
with self.assertRaises(trilio.NFSShareNotMountedException):
|
|
self.trilio_charm._ghost_nfs_share(self._nfs_share,
|
|
self._ghost_share)
|
|
self.mount.assert_not_called()
|
|
|
|
def test_ghost_nfs_share(self):
|
|
self.patch_object(self.trilio_charm, "_ghost_nfs_share")
|
|
self.config.return_value = (
|
|
"10.20.30.40:/srv/trilioshare,10.20.30.40:/srv/trilioshare2"
|
|
)
|
|
self.trilio_charm.ghost_nfs_share(
|
|
"50.20.30.40:/srv/trilioshare,50.20.30.40:/srv/trilioshare2"
|
|
)
|
|
self._ghost_nfs_share.assert_has_calls([
|
|
mock.call("10.20.30.40:/srv/trilioshare",
|
|
"50.20.30.40:/srv/trilioshare"),
|
|
mock.call("10.20.30.40:/srv/trilioshare2",
|
|
"50.20.30.40:/srv/trilioshare2")
|
|
])
|
|
|
|
def test_ghost_nfs_share_mismatch(self):
|
|
self.patch_object(self.trilio_charm, "_ghost_nfs_share")
|
|
self.config.return_value = (
|
|
"10.20.30.40:/srv/trilioshare,10.20.30.40:/srv/trilioshare2"
|
|
)
|
|
with self.assertRaises(trilio.MismatchedConfigurationException):
|
|
self.trilio_charm.ghost_nfs_share(
|
|
"50.20.30.40:/srv/trilioshare"
|
|
)
|
|
|
|
|
|
class TestTrilioCommonBehaviours(BaseOpenStackCharmTest):
|
|
|
|
def setUp(self):
|
|
super().setUp(TrilioVaultFoobar, {})
|
|
self.patch_object(trilio.ch_core.hookenv, "config")
|
|
self.patch_object(trilio.ch_core.hookenv, "status_set")
|
|
self.patch_object(trilio.fetch, "filter_installed_packages")
|
|
self.patch_object(trilio.fetch, "apt_install")
|
|
self.patch_object(trilio.fetch.apt_pkg, 'version_compare')
|
|
self.patch_object(trilio.reactive, "is_flag_set")
|
|
self.patch_object(trilio.reactive, "clear_flag")
|
|
self.patch_target('update_api_ports')
|
|
self.patch_target('set_state')
|
|
self.filter_installed_packages.side_effect = lambda p: p
|
|
|
|
def test_install(self):
|
|
self.is_flag_set.return_value = False
|
|
|
|
trilio._install_triliovault(self.target)
|
|
|
|
self.is_flag_set.assert_called_with('upgrade.triliovault')
|
|
self.filter_installed_packages.assert_called_once_with(
|
|
self.target.all_packages
|
|
)
|
|
self.apt_install.assert_called_once_with(
|
|
self.target.all_packages,
|
|
fatal=True
|
|
)
|
|
self.clear_flag.assert_not_called()
|
|
self.set_state.assert_called_once_with('test-installed')
|
|
self.update_api_ports.assert_called_once()
|
|
|
|
def test_upgrade(self):
|
|
self.is_flag_set.return_value = True
|
|
|
|
trilio._install_triliovault(self.target)
|
|
|
|
self.is_flag_set.assert_called_with('upgrade.triliovault')
|
|
self.filter_installed_packages.assert_not_called()
|
|
self.apt_install.assert_called_once_with(
|
|
self.target.all_packages,
|
|
fatal=True
|
|
)
|
|
self.clear_flag.assert_called_once_with('upgrade.triliovault')
|
|
self.set_state.assert_called_once_with('test-installed')
|
|
self.update_api_ports.assert_called_once()
|
|
|
|
def test_configure_source(self):
|
|
self.config.return_value = 'testsource'
|
|
with patch_open() as (_open, _file):
|
|
trilio._configure_triliovault_source()
|
|
_open.assert_called_with(
|
|
"/etc/apt/sources.list.d/trilio-gemfury-sources.list",
|
|
"w"
|
|
)
|
|
_file.write.assert_called_once_with('testsource')
|
|
|
|
def test_trilio_properties(self):
|
|
def _version_compare(a, b):
|
|
if a > b:
|
|
return 1
|
|
if a == b:
|
|
return 0
|
|
if a < b:
|
|
return -1
|
|
cls_mock = mock.MagicMock()
|
|
cls_mock.charm_instance.release_pkg_version = lambda: '4.0'
|
|
self.version_compare.side_effect = _version_compare
|
|
self.assertEqual(
|
|
trilio.trilio_properties(cls_mock),
|
|
{
|
|
'db_type': 'legacy',
|
|
'transport_type': 'legacy',
|
|
'trilio_compat_version': 4.0})
|
|
cls_mock.charm_instance.release_pkg_version = lambda: '4.1'
|
|
self.assertEqual(
|
|
trilio.trilio_properties(cls_mock),
|
|
{
|
|
'db_type': 'dedicated',
|
|
'transport_type': 'dmapi',
|
|
'trilio_compat_version': 4.1})
|
|
cls_mock.charm_instance.release_pkg_version = lambda: 'a4.1.1'
|
|
with self.assertRaises(ValueError):
|
|
trilio.trilio_properties(cls_mock)
|
|
|
|
def test_trilio_s3_cert_config(self):
|
|
cls_mock = mock.MagicMock()
|
|
self.config.return_value = 'QSBjZXJ0Cg=='
|
|
self.assertEqual(
|
|
trilio.trilio_s3_cert_config(cls_mock),
|
|
{
|
|
'cert_file': '/usr/share/ca-certificates/charm-s3.cert',
|
|
'cert_data': 'A cert\n'})
|
|
self.config.return_value = None
|
|
self.assertEqual(
|
|
trilio.trilio_s3_cert_config(cls_mock),
|
|
{})
|
|
|
|
def test_get_trilio_codename_install_source(self):
|
|
self.assertEqual(
|
|
trilio.get_trilio_codename_install_source(
|
|
'deb [trusted=yes] https://apt.fury.io/triliodata-4-0/ /'),
|
|
'4.0')
|
|
self.assertEqual(
|
|
trilio.get_trilio_codename_install_source(
|
|
'deb [trusted=yes] https://apt.fury.io/triliodata-4-0-0/ /'),
|
|
'4.0')
|
|
with self.assertRaises(AssertionError):
|
|
trilio.get_trilio_codename_install_source(
|
|
'deb [trusted=yes] https://apt.fury.io/triliodata/ /')
|
|
|
|
def test_get_trilio_charm_instance(self):
|
|
_safe_gcif = co_core._get_charm_instance_function
|
|
co_core._get_charm_instance_function = None
|
|
|
|
class BaseClass():
|
|
def __init__(self, release, *args, **kwargs):
|
|
pass
|
|
|
|
class Pike39(BaseClass):
|
|
release = 'pike'
|
|
trilio_release = '3.9'
|
|
|
|
class Queens40(BaseClass):
|
|
release = 'queens'
|
|
trilio_release = '4.0'
|
|
|
|
class Queens41(BaseClass):
|
|
release = 'queens'
|
|
trilio_release = '4.1'
|
|
|
|
class Rocky40(BaseClass):
|
|
release = 'rocky'
|
|
trilio_release = '4.0'
|
|
|
|
def _version_compare(ver1, ver2):
|
|
if float(ver1) > float(ver2):
|
|
return 1
|
|
elif float(ver1) < float(ver2):
|
|
return -1
|
|
else:
|
|
return 0
|
|
|
|
save_releases = trilio._trilio_releases
|
|
self.version_compare.side_effect = _version_compare
|
|
trilio._trilio_releases = {
|
|
'pike': {
|
|
trilio.AptPkgVersion('3.9'): {
|
|
'deb': Pike39}},
|
|
'queens': {
|
|
trilio.AptPkgVersion('4.0'): {
|
|
'deb': Queens40},
|
|
trilio.AptPkgVersion('4.1'): {
|
|
'deb': Queens41}},
|
|
'rocky': {
|
|
trilio.AptPkgVersion('4.0'): {
|
|
'deb': Rocky40}}}
|
|
trilio.make_trilio_get_charm_instance_handler()
|
|
# Check with no release being supplied. Should return the
|
|
# highest release class.
|
|
self.assertIsInstance(
|
|
co_core.get_charm_instance(),
|
|
Rocky40)
|
|
self.assertIsInstance(
|
|
co_core.get_charm_instance(release='queens_4.0'),
|
|
Queens40)
|
|
self.assertIsInstance(
|
|
co_core.get_charm_instance(release='queens_4.1'),
|
|
Queens41)
|
|
# Ensure an error is raised if a class satisfying the trilio condition
|
|
# is not found for the highest matching OpenStack class.
|
|
with self.assertRaises(RuntimeError):
|
|
co_core.get_charm_instance(release='rocky_3.9')
|
|
# Match the openstack release and then the closest trilio releases
|
|
# within that subset.
|
|
self.assertIsInstance(
|
|
co_core.get_charm_instance(release='rocky_4.1'),
|
|
Rocky40)
|
|
with self.assertRaises(RuntimeError):
|
|
co_core.get_charm_instance(release='icehouse_4.1')
|
|
trilio._trilio_releases = save_releases
|
|
co_core._get_charm_instance_function = _safe_gcif
|
|
|
|
def test_select_trilio_release(self):
|
|
def get_charm_class(release_pkg='trilio_pkg', package_version='4.0',
|
|
os_codename_exception=None,
|
|
version_package='trilio_pkg',
|
|
package_version_exception=None,
|
|
os_release_pkg='nova_pkg',
|
|
os_codename_pkg='queens',
|
|
trilio_source='deb https://a.io/trilio-4-2-0/ /'):
|
|
|
|
class _TrilioCharm():
|
|
|
|
def __init__(self):
|
|
self.release_pkg = release_pkg
|
|
self.version_package = version_package
|
|
self.os_release_pkg = os_release_pkg
|
|
self.source_config_key = 'openstack-origin'
|
|
self.package_codenames = {}
|
|
self.package_version = package_version
|
|
self.os_codename_exception = os_codename_exception
|
|
self.os_codename_pkg = os_codename_pkg
|
|
self.trilio_source = trilio_source
|
|
|
|
@staticmethod
|
|
def get_os_codename_package(pkg, code_names,
|
|
apt_cache_sufficient=True):
|
|
if os_codename_exception:
|
|
raise os_codename_exception
|
|
else:
|
|
return os_codename_pkg
|
|
|
|
@staticmethod
|
|
def get_package_version(pkg, apt_cache_sufficient=True):
|
|
if package_version_exception:
|
|
raise package_version_exception
|
|
else:
|
|
return package_version
|
|
|
|
return _TrilioCharm()
|
|
|
|
_safe_rsf = co_core._release_selector_function
|
|
co_core._release_selector_function = None
|
|
self.patch_object(
|
|
trilio.os_utils,
|
|
"get_installed_semantic_versioned_packages")
|
|
self.patch_object(trilio.os_utils, "os_release")
|
|
self.patch_object(trilio.unitdata, "kv")
|
|
kv_mock = mock.MagicMock()
|
|
self.kv.return_value = kv_mock
|
|
kv_mock.get.return_value = None
|
|
self.patch_object(
|
|
trilio.charms_openstack.charm.core,
|
|
"get_charm_instance")
|
|
|
|
trilio.make_trilio_get_charm_instance_handler()
|
|
trilio.make_trilio_select_release_handler()
|
|
select_trilio_release = co_core._release_selector_function
|
|
self.get_charm_instance.return_value = get_charm_class()
|
|
self.assertEqual(
|
|
select_trilio_release(),
|
|
'queens_4.0')
|
|
|
|
# Check RuntimeError is raised if release_pkg is missing from charm
|
|
# class
|
|
self.get_charm_instance.return_value = get_charm_class(
|
|
release_pkg=None)
|
|
with self.assertRaises(RuntimeError):
|
|
select_trilio_release()
|
|
|
|
# Test falling back to get_installed_semantic_versioned_packages
|
|
self.os_release.return_value = 'pike'
|
|
self.get_installed_semantic_versioned_packages.reset_mock()
|
|
self.get_installed_semantic_versioned_packages.return_value = ['nova']
|
|
self.get_charm_instance.return_value = get_charm_class(
|
|
os_codename_pkg=None)
|
|
self.assertEqual(
|
|
select_trilio_release(),
|
|
'pike_4.0')
|
|
|
|
# Check RuntimeError is raised if version_package is missing from charm
|
|
# class
|
|
self.get_charm_instance.return_value = get_charm_class(
|
|
version_package=None)
|
|
with self.assertRaises(RuntimeError):
|
|
select_trilio_release()
|
|
|
|
# Test falling back to get_trilio_codename_install_source
|
|
self.get_charm_instance.return_value = get_charm_class(
|
|
package_version_exception=ValueError)
|
|
self.assertEqual(
|
|
select_trilio_release(),
|
|
'queens_4.2')
|
|
co_core._release_selector_function = _safe_rsf
|
|
|
|
|
|
class TestTrilioVaultCharm(BaseOpenStackCharmTest):
|
|
|
|
def setUp(self):
|
|
super().setUp(TrilioVaultFoobar, {})
|
|
self.patch_object(trilio.ch_core.hookenv, "log")
|
|
self.patch_object(trilio.ch_core.hookenv, "status_set")
|
|
self.patch_object(
|
|
trilio.charms_openstack.charm.core,
|
|
"get_charm_instance")
|
|
self.patch_object(trilio, "_install_triliovault")
|
|
self.patch_object(trilio, "_configure_triliovault_source")
|
|
self.patch_object(trilio.fetch, "apt_update")
|
|
self.patch_object(trilio.fetch, "apt_install")
|
|
self.patch_object(trilio.fetch.apt_pkg, "version_compare")
|
|
self.patch_target('config')
|
|
self._conf = {
|
|
'triliovault-pkg-source': 'deb https://a.io/trilio-4-2-0/ /'
|
|
}
|
|
self.config.get.side_effect = lambda x, b=None: self._conf.get(x, b)
|
|
|
|
def test_series_upgrade_complete(self):
|
|
self.patch_object(trilio.charms_openstack.charm.HAOpenStackCharm,
|
|
'series_upgrade_complete')
|
|
self.patch_target('configure_source')
|
|
self.target.series_upgrade_complete()
|
|
self.configure_source.assert_called_once_with()
|
|
|
|
def test_configure_source(self):
|
|
self.patch_object(trilio.charms_openstack.charm.HAOpenStackCharm,
|
|
'configure_source')
|
|
self.target.configure_source()
|
|
self._configure_triliovault_source.assert_called_once_with()
|
|
self.configure_source.assert_called_once_with()
|
|
|
|
def test_install(self):
|
|
self.patch_object(trilio.charms_openstack.charm.HAOpenStackCharm,
|
|
'configure_source')
|
|
self.target.install()
|
|
self._install_triliovault.assert_called_once_with(self.target)
|
|
|
|
def test_trilio_source(self):
|
|
self.assertEqual(
|
|
self.target.trilio_source,
|
|
'deb https://a.io/trilio-4-2-0/ /')
|
|
|
|
def test_do_trilio_pkg_upgrade(self):
|
|
self.target.do_trilio_pkg_upgrade()
|
|
self.apt_update.assert_called_once_with()
|
|
self.apt_install.assert_called_once_with(
|
|
packages=['foo', 'bar'],
|
|
options=[
|
|
'--option', 'Dpkg::Options::=--force-confnew',
|
|
'--option', 'Dpkg::Options::=--force-confdef'],
|
|
fatal=True)
|
|
|
|
def test_run_trilio_upgrade(self):
|
|
self.patch_target('get_os_codename_package')
|
|
self.get_os_codename_package.return_value = 'queens'
|
|
charm_cls = mock.MagicMock()
|
|
interface_mocks = [mock.MagicMock(), mock.MagicMock()]
|
|
self.get_charm_instance.return_value = charm_cls
|
|
self.target.run_trilio_upgrade(interfaces_list=interface_mocks)
|
|
self._configure_triliovault_source.assert_called_once_with()
|
|
charm_cls.do_trilio_pkg_upgrade.assert_called_once_with()
|
|
charm_cls.render_with_interfaces.assert_called_once_with(
|
|
interface_mocks)
|
|
charm_cls.do_trilio_upgrade_db_migration.assert_called_once_with()
|
|
|
|
def test_trilio_upgrade_available(self):
|
|
self.patch_target('get_package_version')
|
|
self.get_package_version.return_value = '4.1'
|
|
self.version_compare.return_value = 1
|
|
self.assertTrue(self.target.trilio_upgrade_available())
|
|
self.version_compare.assert_called_once_with('4.2', '4.1')
|
|
|
|
def test_upgrade_if_available(self):
|
|
self.patch_target('openstack_upgrade_available')
|
|
self.patch_target('trilio_upgrade_available')
|
|
self.patch_target('run_upgrade')
|
|
self.patch_target('run_trilio_upgrade')
|
|
interface_mocks = [mock.MagicMock(), mock.MagicMock()]
|
|
|
|
self._conf['action-managed-upgrade'] = False
|
|
self.openstack_upgrade_available.return_value = True
|
|
self.trilio_upgrade_available.return_value = True
|
|
self.target.upgrade_if_available(interface_mocks)
|
|
self.run_upgrade.assert_called_once_with(
|
|
interfaces_list=interface_mocks)
|
|
self.run_trilio_upgrade.assert_called_once_with(
|
|
interfaces_list=interface_mocks)
|
|
|
|
self.run_upgrade.reset_mock()
|
|
self.run_trilio_upgrade.reset_mock()
|
|
self._conf['action-managed-upgrade'] = True
|
|
self.openstack_upgrade_available.return_value = True
|
|
self.trilio_upgrade_available.return_value = True
|
|
self.target.upgrade_if_available(interface_mocks)
|
|
self.assertFalse(self.run_upgrade.called)
|
|
self.assertFalse(self.run_trilio_upgrade.called)
|
|
|
|
|
|
class TestTrilioVaultSubordinateCharm(BaseOpenStackCharmTest):
|
|
|
|
def setUp(self):
|
|
super().setUp(TrilioVaultFoobarSubordinate, {})
|
|
self.patch_object(trilio, "_install_triliovault")
|
|
self.patch_object(trilio, "_configure_triliovault_source")
|
|
self.patch_object(trilio.fetch, "apt_update")
|
|
|
|
def test_configure_source(self):
|
|
self.patch_object(trilio.charms_openstack.charm.OpenStackCharm,
|
|
'configure_source')
|
|
self.target.configure_source()
|
|
self._configure_triliovault_source.assert_called_once_with()
|
|
self.configure_source.assert_not_called()
|
|
self.apt_update.assert_called_once_with(fatal=True)
|
|
|
|
|
|
class TestBaseTrilioCharmMeta(BaseTestCase):
|
|
|
|
def setUp(self):
|
|
self.save_releases = trilio._trilio_releases
|
|
super().setUp()
|
|
self.patch_object(trilio.fetch.apt_pkg, 'version_compare')
|
|
|
|
def _version_compare(ver1, ver2):
|
|
if float(ver1) > float(ver2):
|
|
return 1
|
|
elif float(ver1) < float(ver2):
|
|
return -1
|
|
else:
|
|
return 0
|
|
self.version_compare.side_effect = _version_compare
|
|
|
|
def tearDown(self):
|
|
super().tearDown()
|
|
trilio._trilio_releases = self.save_releases
|
|
|
|
def register_classes(self):
|
|
|
|
class TrilioQueens40(metaclass=trilio.BaseTrilioCharmMeta):
|
|
|
|
release = 'queens'
|
|
trilio_release = '4.0'
|
|
|
|
class TrilioQueens41(metaclass=trilio.BaseTrilioCharmMeta):
|
|
|
|
release = 'queens'
|
|
trilio_release = '4.1'
|
|
|
|
class TrilioRocky40(metaclass=trilio.BaseTrilioCharmMeta):
|
|
|
|
release = 'rocky'
|
|
trilio_release = '4.0'
|
|
|
|
return {
|
|
'queens_4.0': TrilioQueens40,
|
|
'queens_4.1': TrilioQueens41,
|
|
'rocky_4.0': TrilioRocky40}
|
|
|
|
def register_classes_missing_key(self):
|
|
|
|
class TrilioQueens40(metaclass=trilio.BaseTrilioCharmMeta):
|
|
|
|
release = 'queens'
|
|
|
|
def register_classes_wrong_pkg_type(self):
|
|
|
|
class TrilioQueens40(metaclass=trilio.BaseTrilioCharmMeta):
|
|
|
|
release = 'queens'
|
|
trilio_release = '4.1'
|
|
package_type = 'up2date'
|
|
|
|
def register_classes_duplicate(self):
|
|
|
|
class TrilioQueens40A(metaclass=trilio.BaseTrilioCharmMeta):
|
|
|
|
release = 'queens'
|
|
trilio_release = '4.0'
|
|
|
|
class TrilioQueens40B(metaclass=trilio.BaseTrilioCharmMeta):
|
|
|
|
release = 'queens'
|
|
trilio_release = '4.0'
|
|
|
|
def test_class_register(self):
|
|
charm_classes = self.register_classes()
|
|
self.maxDiff = None
|
|
self.assertEqual(
|
|
trilio._trilio_releases,
|
|
{
|
|
'queens': {
|
|
trilio.AptPkgVersion('4.0'): {
|
|
'deb': charm_classes['queens_4.0']},
|
|
trilio.AptPkgVersion('4.1'): {
|
|
'deb': charm_classes['queens_4.1']}},
|
|
'rocky': {
|
|
trilio.AptPkgVersion('4.0'): {
|
|
'deb': charm_classes['rocky_4.0']}}})
|
|
|
|
def test_class_register_missing_key(self):
|
|
with self.assertRaises(RuntimeError):
|
|
self.register_classes_missing_key()
|
|
|
|
def test_class_register_wrong_pkg_type(self):
|
|
with self.assertRaises(RuntimeError):
|
|
self.register_classes_wrong_pkg_type()
|
|
|
|
def test_class_register_duplicate(self):
|
|
with self.assertRaises(RuntimeError):
|
|
self.register_classes_duplicate()
|