mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Finished Env._finalize_core() and corresponding unit tests
This commit is contained in:
parent
8ca44bcbfa
commit
ac4efac394
@ -145,13 +145,20 @@ class Env(object):
|
||||
self.home = path.abspath(os.environ['HOME'])
|
||||
self.dot_ipa = path.join(self.home, '.ipa')
|
||||
|
||||
def __do(self, name):
|
||||
def __doing(self, name):
|
||||
if name in self.__done:
|
||||
raise StandardError(
|
||||
'%s.%s() already called' % (self.__class__.__name__, name)
|
||||
)
|
||||
self.__done.add(name)
|
||||
|
||||
def __do_if_not_done(self, name):
|
||||
if name not in self.__done:
|
||||
getattr(self, name)()
|
||||
|
||||
def _isdone(self, name):
|
||||
return name in self.__done
|
||||
|
||||
def _bootstrap(self, **overrides):
|
||||
"""
|
||||
Initialize basic environment.
|
||||
@ -159,10 +166,8 @@ class Env(object):
|
||||
This method will initialize only enough environment information to
|
||||
determine whether ipa is running in-tree, what the context is,
|
||||
and the location of the configuration file.
|
||||
|
||||
This method should be called before any plugins are loaded.
|
||||
"""
|
||||
self.__do('_bootstrap')
|
||||
self.__doing('_bootstrap')
|
||||
for (key, value) in overrides.items():
|
||||
self[key] = value
|
||||
if 'in_tree' not in self:
|
||||
@ -180,7 +185,46 @@ class Env(object):
|
||||
else:
|
||||
self.conf = path.join('/', 'etc', 'ipa', name)
|
||||
|
||||
def _load_config(self, conf_file):
|
||||
def _finalize_core(self, **defaults):
|
||||
"""
|
||||
Complete initialization of standard IPA environment.
|
||||
|
||||
After this method is called, the all environment variables
|
||||
used by all the built-in plugins will be available.
|
||||
|
||||
This method should be called before loading any plugins. It will
|
||||
automatically call `Env._bootstrap()` if it has not yet been called.
|
||||
|
||||
After this method has finished, the `Env` instance is still writable
|
||||
so that third
|
||||
"""
|
||||
self.__doing('_finalize_core')
|
||||
self.__do_if_not_done('_bootstrap')
|
||||
self._merge_config(self.conf)
|
||||
if 'in_server' not in self:
|
||||
self.in_server = (self.context == 'server')
|
||||
if 'log' not in self:
|
||||
name = '%s.log' % self.context
|
||||
if self.in_tree or self.context == 'cli':
|
||||
self.log = path.join(self.dot_ipa, 'log', name)
|
||||
else:
|
||||
self.log = path.join('/', 'var', 'log', 'ipa', name)
|
||||
for (key, value) in defaults.items():
|
||||
if key not in self:
|
||||
self[key] = value
|
||||
|
||||
def _finalize(self):
|
||||
"""
|
||||
Finalize and lock environment.
|
||||
|
||||
This method should be called after all plugins have bean loaded and
|
||||
after `plugable.API.finalize()` has been called.
|
||||
"""
|
||||
self.__doing('_finalize')
|
||||
self.__do_if_not_done('_finalize_core')
|
||||
self.__lock__()
|
||||
|
||||
def _merge_config(self, conf_file):
|
||||
"""
|
||||
Merge in values from ``conf_file`` into this `Env`.
|
||||
"""
|
||||
@ -204,14 +248,6 @@ class Env(object):
|
||||
i += 1
|
||||
return (i, len(items))
|
||||
|
||||
def _finalize(self, **defaults):
|
||||
"""
|
||||
Finalize and lock environment.
|
||||
|
||||
This method should be called after all plugins have bean loaded and
|
||||
after `plugable.API.finalize()` has been called.
|
||||
"""
|
||||
|
||||
def __lock__(self):
|
||||
"""
|
||||
Prevent further changes to environment.
|
||||
|
@ -21,5 +21,41 @@
|
||||
Constants centralized in one file.
|
||||
"""
|
||||
|
||||
# The section read in config files, i.e. [global]
|
||||
# The section to read in the config files, i.e. [global]
|
||||
CONFIG_SECTION = 'global'
|
||||
|
||||
|
||||
# The default configuration for api.env
|
||||
DEFAULT_CONFIG = (
|
||||
('lite_xmlrpc_port', 8888),
|
||||
('lite_webui_port', 9999),
|
||||
('xmlrpc_uri', 'http://localhost:8888'),
|
||||
('ldap_uri', ''),
|
||||
|
||||
('verbose', False),
|
||||
('debug', False),
|
||||
|
||||
# Env.__init__() or Env._bootstrap() or Env._finalize_core()
|
||||
# will have filled in all the keys below by the time DEFAULT_CONFIG
|
||||
# is merged in, so the values below are never actually used. They are
|
||||
# listed both to provide a big picture and so DEFAULT_CONFIG contains
|
||||
# the keys that should be present after Env._load_standard is called.
|
||||
|
||||
# Set in Env.__init__():
|
||||
('ipalib', None), # The directory containing ipalib/__init__.py
|
||||
('site_packages', None), # The directory contaning ipalib
|
||||
('script', None), # sys.argv[0]
|
||||
('bin', None), # The directory containing script
|
||||
('home', None), # The home directory of user underwhich process is running
|
||||
('dot_ipa', None), # ~/.ipa directory
|
||||
|
||||
# Set in Env._bootstrap():
|
||||
('in_tree', None), # Whether or not running in-tree (bool)
|
||||
('context', None), # Name of context, default is 'default'
|
||||
('conf', None), # Path to configuration file
|
||||
|
||||
# Set in Env._finalize_core():
|
||||
('in_server', None), # Whether or not running in-server (bool)
|
||||
('log', None), # Path to log file
|
||||
|
||||
)
|
||||
|
@ -28,7 +28,7 @@ import sys
|
||||
from tests.util import raises, setitem, delitem, ClassChecker
|
||||
from tests.util import getitem, setitem, delitem
|
||||
from tests.util import TempDir, TempHome
|
||||
from ipalib import config
|
||||
from ipalib import config, constants
|
||||
|
||||
|
||||
def test_Environment():
|
||||
@ -157,6 +157,7 @@ WfUu+/mDOAGOjsRo0UkIo+pPl6Rckl7ehuR1INGAj9u0kW2nXvK45YlQp1odukaICSAjgSQWf//Z
|
||||
# A config file that tries to override some standard vars:
|
||||
config_override = """
|
||||
[global]
|
||||
|
||||
key0 = var0
|
||||
home = /home/sweet/home
|
||||
key1 = var1
|
||||
@ -165,9 +166,10 @@ key2 = var2
|
||||
key3 = var3
|
||||
"""
|
||||
|
||||
# A config file that test the automatic type conversion
|
||||
# A config file that tests the automatic type conversion
|
||||
config_good = """
|
||||
[global]
|
||||
|
||||
yes = TRUE
|
||||
no = False
|
||||
number = 42
|
||||
@ -205,7 +207,9 @@ class test_Env(ClassChecker):
|
||||
|
||||
def bootstrap(self, **overrides):
|
||||
(o, home) = self.new()
|
||||
assert o._isdone('_bootstrap') is False
|
||||
o._bootstrap(**overrides)
|
||||
assert o._isdone('_bootstrap') is True
|
||||
e = raises(StandardError, o._bootstrap)
|
||||
assert str(e) == 'Env._bootstrap() already called'
|
||||
return (o, home)
|
||||
@ -214,7 +218,6 @@ class test_Env(ClassChecker):
|
||||
"""
|
||||
Test the `ipalib.config.Env._bootstrap` method.
|
||||
"""
|
||||
|
||||
# Test defaults created by _bootstrap():
|
||||
(o, home) = self.new()
|
||||
assert 'in_tree' not in o
|
||||
@ -253,9 +256,110 @@ class test_Env(ClassChecker):
|
||||
assert getattr(o, key) == value
|
||||
assert o[key] == value
|
||||
|
||||
def test_load_config(self):
|
||||
def finalize_core(self, **defaults):
|
||||
(o, home) = self.new()
|
||||
assert o._isdone('_finalize_core') is False
|
||||
o._finalize_core(**defaults)
|
||||
assert o._isdone('_finalize_core') is True
|
||||
e = raises(StandardError, o._finalize_core)
|
||||
assert str(e) == 'Env._finalize_core() already called'
|
||||
return (o, home)
|
||||
|
||||
def test_finalize_core(self):
|
||||
"""
|
||||
Test the `ipalib.config.Env._load_config` method.
|
||||
Test the `ipalib.config.Env._finalize_core` method.
|
||||
"""
|
||||
# Check that calls cascade up the chain:
|
||||
(o, home) = self.new()
|
||||
assert o._isdone('_bootstrap') is False
|
||||
assert o._isdone('_finalize_core') is False
|
||||
assert o._isdone('_finalize') is False
|
||||
o._finalize_core()
|
||||
assert o._isdone('_bootstrap') is True
|
||||
assert o._isdone('_finalize_core') is True
|
||||
assert o._isdone('_finalize') is False
|
||||
|
||||
# Check that it can't be called twice:
|
||||
e = raises(StandardError, o._finalize_core)
|
||||
assert str(e) == 'Env._finalize_core() already called'
|
||||
|
||||
# Check that _bootstrap() did its job:
|
||||
(o, home) = self.bootstrap()
|
||||
assert 'in_tree' in o
|
||||
assert 'conf' in o
|
||||
assert 'context' in o
|
||||
|
||||
# Check that keys _finalize_core() will set are not set yet:
|
||||
assert 'log' not in o
|
||||
assert 'in_server' not in o
|
||||
|
||||
# Check that _finalize_core() did its job:
|
||||
o._finalize_core()
|
||||
assert 'in_server' in o
|
||||
assert 'log' in o
|
||||
assert o.in_tree is False
|
||||
assert o.context == 'default'
|
||||
assert o.in_server is False
|
||||
assert o.log == '/var/log/ipa/default.log'
|
||||
|
||||
# Check log is in ~/.ipa/log when context='cli'
|
||||
(o, home) = self.bootstrap(context='cli')
|
||||
o._finalize_core()
|
||||
assert o.in_tree is False
|
||||
assert o.log == home.join('.ipa', 'log', 'cli.log')
|
||||
|
||||
# Check **defaults can't set in_server nor log:
|
||||
(o, home) = self.bootstrap(in_server='tRUE')
|
||||
o._finalize_core(in_server=False)
|
||||
assert o.in_server is True
|
||||
(o, home) = self.bootstrap(log='/some/silly/log')
|
||||
o._finalize_core(log='/a/different/log')
|
||||
assert o.log == '/some/silly/log'
|
||||
|
||||
# Test loading config file, plus test some in-tree stuff
|
||||
(o, home) = self.bootstrap(in_tree=True, context='server')
|
||||
for key in ('yes', 'no', 'number'):
|
||||
assert key not in o
|
||||
home.write(config_good, '.ipa', 'server.conf')
|
||||
o._finalize_core()
|
||||
assert o.in_tree is True
|
||||
assert o.context == 'server'
|
||||
assert o.in_server is True
|
||||
assert o.log == home.join('.ipa', 'log', 'server.log')
|
||||
assert o.yes is True
|
||||
assert o.no is False
|
||||
assert o.number == 42
|
||||
|
||||
# Test using DEFAULT_CONFIG:
|
||||
defaults = dict(constants.DEFAULT_CONFIG)
|
||||
(o, home) = self.finalize_core(**defaults)
|
||||
assert list(o) == sorted(defaults)
|
||||
for (key, value) in defaults.items():
|
||||
if value is None:
|
||||
continue
|
||||
assert o[key] is value
|
||||
|
||||
def test_finalize(self):
|
||||
"""
|
||||
Test the `ipalib.config.Env._finalize` method.
|
||||
"""
|
||||
# Check that calls cascade up the chain:
|
||||
(o, home) = self.new()
|
||||
assert o._isdone('_bootstrap') is False
|
||||
assert o._isdone('_finalize_core') is False
|
||||
assert o._isdone('_finalize') is False
|
||||
o._finalize()
|
||||
assert o._isdone('_bootstrap') is True
|
||||
assert o._isdone('_finalize_core') is True
|
||||
assert o._isdone('_finalize') is True
|
||||
|
||||
# Check that it can't be called twice:
|
||||
e = raises(StandardError, o._finalize)
|
||||
assert str(e) == 'Env._finalize() already called'
|
||||
|
||||
def test_merge_config(self):
|
||||
"""
|
||||
Test the `ipalib.config.Env._merge_config` method.
|
||||
"""
|
||||
tmp = TempDir()
|
||||
assert callable(tmp.join)
|
||||
@ -266,27 +370,27 @@ class test_Env(ClassChecker):
|
||||
o = self.cls()
|
||||
keys = tuple(o)
|
||||
orig = dict((k, o[k]) for k in o)
|
||||
assert o._load_config(no_exist) is None
|
||||
assert o._merge_config(no_exist) is None
|
||||
assert tuple(o) == keys
|
||||
|
||||
# Test an empty config file
|
||||
empty = tmp.touch('empty.conf')
|
||||
assert path.isfile(empty)
|
||||
assert o._load_config(empty) is None
|
||||
assert o._merge_config(empty) is None
|
||||
assert tuple(o) == keys
|
||||
|
||||
# Test a mal-formed config file:
|
||||
bad = tmp.join('bad.conf')
|
||||
open(bad, 'w').write(config_bad)
|
||||
assert path.isfile(bad)
|
||||
assert o._load_config(bad) is None
|
||||
assert o._merge_config(bad) is None
|
||||
assert tuple(o) == keys
|
||||
|
||||
# Test a valid config file that tries to override
|
||||
override = tmp.join('override.conf')
|
||||
open(override, 'w').write(config_override)
|
||||
assert path.isfile(override)
|
||||
assert o._load_config(override) == (4, 6)
|
||||
assert o._merge_config(override) == (4, 6)
|
||||
for (k, v) in orig.items():
|
||||
assert o[k] is v
|
||||
assert list(o) == sorted(keys + ('key0', 'key1', 'key2', 'key3'))
|
||||
@ -298,7 +402,7 @@ class test_Env(ClassChecker):
|
||||
good = tmp.join('good.conf')
|
||||
open(good, 'w').write(config_good)
|
||||
assert path.isfile(good)
|
||||
assert o._load_config(good) == (3, 3)
|
||||
assert o._merge_config(good) == (3, 3)
|
||||
assert list(o) == sorted(keys + ('yes', 'no', 'number'))
|
||||
assert o.yes is True
|
||||
assert o.no is False
|
||||
|
@ -61,6 +61,14 @@ class TempDir(object):
|
||||
assert path.isfile(f) and not path.islink(f)
|
||||
return f
|
||||
|
||||
def write(self, content, *parts):
|
||||
d = self.makedirs(*parts[:-1])
|
||||
f = path.join(d, parts[-1])
|
||||
assert not path.exists(f)
|
||||
open(f, 'w').write(content)
|
||||
assert path.isfile(f) and not path.islink(f)
|
||||
return f
|
||||
|
||||
def join(self, *parts):
|
||||
return path.join(self.path, *parts)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user