def test_singleton(self): # because we have two releases, we expect this to be the latter. # e.g. MyNextOpenStackCharm s = self.target.singleton self.assertEqual(s.__class__.release, 'mitaka') self.assertIsInstance(s, MyOpenStackCharm) # should also be the second one, as it's the latest self.assertIsInstance(s, MyNextOpenStackCharm) self.assertIsInstance(MyOpenStackCharm.singleton, MyOpenStackCharm) self.assertIsInstance(chm_core.BaseOpenStackCharm.singleton, MyOpenStackCharm) self.assertEqual(s, chm_core.BaseOpenStackCharm.singleton) # Note that get_charm_instance() returns NEW instance each time. self.assertNotEqual(s, chm_core.get_charm_instance()) # now clear out the singleton and make sure we get the first one using # a release function rsf_save = chm_core._release_selector_function chm_core._release_selector_function = None @chm_core.register_os_release_selector def selector(): return 'icehouse' # This should choose the icehouse version instead of the mitaka version chm_core._singleton = None s = self.target.singleton self.assertEqual(s.release, 'icehouse') self.assertEqual(s.__class__.release, 'icehouse') self.assertFalse(isinstance(s, MyNextOpenStackCharm)) chm_core._release_selector_function = rsf_save
def test_singleton(self): # because we have two releases, we expect this to be the latter. # e.g. MyNextOpenStackCharm s = self.target.singleton self.assertEqual(s.__class__.release, 'mitaka') self.assertIsInstance(s, MyOpenStackCharm) # should also be the second one, as it's the latest self.assertIsInstance(s, MyNextOpenStackCharm) self.assertIsInstance(MyOpenStackCharm.singleton, MyOpenStackCharm) self.assertIsInstance(chm_core.BaseOpenStackCharm.singleton, MyOpenStackCharm) self.assertEqual(s, chm_core.BaseOpenStackCharm.singleton) # Note that get_charm_instance() returns NEW instance each time. self.assertNotEqual(s, chm_core.get_charm_instance()) # now clear out the singleton and make sure we get the first one using # a release function rsf_save = chm_core._release_selector_function chm_core._release_selector_function = None @chm_core.register_os_release_selector def selector(): return 'icehouse' # This should choose the icehouse version instead of the mitaka version chm_core._singleton = None s = self.target.singleton self.assertEqual(s.release, 'icehouse') self.assertEqual(s.__class__.release, 'icehouse') self.assertFalse(isinstance(s, MyNextOpenStackCharm)) chm_core._release_selector_function = rsf_save
def default_select_release(): """Determine the release based on the python-keystonemiddleware that is installed. Note that this function caches the release after the first install so that it doesn't need to keep going and getting it from the package information. """ release_version = unitdata.kv().get(OPENSTACK_RELEASE_KEY, None) if release_version is None: try: # First make an attempt of determining release from a charm # instance defined package codename dictionary. singleton = get_charm_instance() if singleton.release_pkg is None: raise RuntimeError("release_pkg is not set") release_version = singleton.get_os_codename_package( singleton.release_pkg, singleton.package_codenames, apt_cache_sufficient=(not singleton.source_config_key)) if release_version is None: # Surprisingly get_os_codename_package called with # ``Fatal=True`` does not raise an error when the charm # class ``package_codenames`` map does not contain package # or major version. We'll handle it here instead of # changing the API of the method. raise ValueError except (AttributeError, ValueError): try: pkgs = os_utils.get_installed_semantic_versioned_packages() pkg = pkgs[0] except IndexError: # A non-existent package will cause os_release to try other # tactics for deriving the release. pkg = 'dummy-package' release_version = os_utils.os_release( pkg, source_key=singleton.source_config_key) unitdata.kv().set(OPENSTACK_RELEASE_KEY, release_version) return release_version
def test_get_default_release(self): # TODO this may be the wrong logic. Assume latest release if no # release is passed? self.assertIsInstance(chm_core.get_charm_instance(), self.C3)
def test_fail_too_early_series(self): with self.assertRaises(RuntimeError): chm_core.get_charm_instance(release='havana')
def test_get_inbetween(self): self.assertTrue( isinstance(chm_core.get_charm_instance(release='juno'), self.C1))
def test_get_exact(self): self.assertTrue( isinstance(chm_core.get_charm_instance(release='icehouse'), self.C1)) self.assertTrue( isinstance(chm_core.get_charm_instance(release='mitaka'), self.C3))
def test_get_default_release(self): # TODO this may be the wrong logic. Assume latest release if no # release is passed? self.assertIsInstance(chm_core.get_charm_instance(), self.C3)
def test_fail_too_early_series(self): with self.assertRaises(RuntimeError): chm_core.get_charm_instance(release='havana')
def test_get_inbetween(self): self.assertTrue( isinstance(chm_core.get_charm_instance(release='juno'), self.C1))
def test_get_exact(self): self.assertTrue( isinstance(chm_core.get_charm_instance(release='icehouse'), self.C1)) self.assertTrue( isinstance(chm_core.get_charm_instance(release='mitaka'), self.C3))
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