Changed section/parameter reference schema in Configuration class, added template substitution
This commit is contained in:
parent
841264e185
commit
4ceec12865
@ -1,3 +1,5 @@
|
||||
import string
|
||||
|
||||
from ostack_validator.common import Mark
|
||||
|
||||
class ConfigurationSection(object):
|
||||
@ -6,29 +8,35 @@ class ConfigurationSection(object):
|
||||
self.config = config
|
||||
self.section = section
|
||||
|
||||
def get(self, *args, **kwargs):
|
||||
return self.config.get(self.section, *args, **kwargs)
|
||||
def _combine_names(self, section, param):
|
||||
if section == 'DEFAULT':
|
||||
return param
|
||||
|
||||
def set(self, *args, **kwargs):
|
||||
self.config.set(self.section, *args, **kwargs)
|
||||
return '%s.%s' % (section, param)
|
||||
|
||||
def set_default(self, *args, **kwargs):
|
||||
self.config.set_default(self.section, *args, **kwargs)
|
||||
def get(self, name, *args, **kwargs):
|
||||
return self.config.get(self._combine_names(self.section, name), *args, **kwargs)
|
||||
|
||||
def contains(self, *args, **kwargs):
|
||||
return self.config.contains(self.section, *args, **kwargs)
|
||||
def set(self, name, *args, **kwargs):
|
||||
self.config.set(self._combine_names(self.section, name), *args, **kwargs)
|
||||
|
||||
def is_default(self, *args, **kwargs):
|
||||
return self.config.is_default(self.section, *args, **kwargs)
|
||||
def set_default(self, name, *args, **kwargs):
|
||||
self.config.set_default(self._combine_names(self.section, name), *args, **kwargs)
|
||||
|
||||
def contains(self, name, *args, **kwargs):
|
||||
return self.config.contains(self._combine_names(self.section, name), *args, **kwargs)
|
||||
|
||||
def is_default(self, name, *args, **kwargs):
|
||||
return self.config.is_default(self._combine_names(self.section, name), *args, **kwargs)
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self.config.get(self.section, key)
|
||||
return self.config.get(self._combine_names(self.section, key))
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
return self.config.set(self.section, key, value)
|
||||
return self.config.set(self._combine_names(self.section, key), value)
|
||||
|
||||
def __contains__(self, key):
|
||||
return self.config.contains(self.section, key)
|
||||
return self.config.contains(self._combine_names(self.section, key))
|
||||
|
||||
def keys(self):
|
||||
return self.config.keys(self.section)
|
||||
@ -36,6 +44,18 @@ class ConfigurationSection(object):
|
||||
def items(self, *args, **kwargs):
|
||||
return self.config.items(self.section, *args, **kwargs)
|
||||
|
||||
class ConfigurationWrapper(object):
|
||||
def __init__(self, config, state):
|
||||
super(ConfigurationWrapper, self).__init__()
|
||||
self.config = config
|
||||
self.state = state
|
||||
|
||||
def __getitem__(self, key):
|
||||
if key in self.state:
|
||||
return ''
|
||||
|
||||
return self.config.get(key, _state=self.state)
|
||||
|
||||
|
||||
class Configuration(object):
|
||||
def __init__(self):
|
||||
@ -43,16 +63,39 @@ class Configuration(object):
|
||||
self._defaults = dict()
|
||||
self._normal = dict()
|
||||
|
||||
def get(self, section, name, default=None):
|
||||
def _normalize_name(self, name):
|
||||
if name.find('.') == -1:
|
||||
section = 'DEFAULT'
|
||||
else:
|
||||
section, name = name.split('.', 1)
|
||||
|
||||
return (section, name)
|
||||
|
||||
def _combine_names(self, section, param):
|
||||
if section == 'DEFAULT':
|
||||
return param
|
||||
|
||||
return '%s.%s' % (section, param)
|
||||
|
||||
def get(self, name, default=None, _state=[]):
|
||||
section, name = self._normalize_name(name)
|
||||
|
||||
if section in self._normal and name in self._normal[section]:
|
||||
return self._normal[section][name]
|
||||
value = self._normal[section][name]
|
||||
elif section in self._defaults and name in self._defaults[section]:
|
||||
value = self._defaults[section][name]
|
||||
else:
|
||||
value = default
|
||||
|
||||
if section in self._defaults and name in self._defaults[section]:
|
||||
return self._defaults[section][name]
|
||||
if not isinstance(value, str):
|
||||
return value
|
||||
|
||||
return default
|
||||
tmpl = string.Template(value)
|
||||
return tmpl.safe_substitute(ConfigurationWrapper(self, _state + [name]))
|
||||
|
||||
def contains(self, name, ignoreDefault=False):
|
||||
section, name = self._normalize_name(name)
|
||||
|
||||
def contains(self, section, name, ignoreDefault=False):
|
||||
if section in self._normal and name in self._normal[section]:
|
||||
return True
|
||||
|
||||
@ -61,16 +104,22 @@ class Configuration(object):
|
||||
|
||||
return False
|
||||
|
||||
def is_default(self, section, name):
|
||||
def is_default(self, name):
|
||||
section, name = self._normalize_name(name)
|
||||
|
||||
return not (section in self._normal and name in self._normal[section]) and (section in self._defaults and name in self._defaults[section])
|
||||
|
||||
def set_default(self, section, name, value):
|
||||
def set_default(self, name, value):
|
||||
section, name = self._normalize_name(name)
|
||||
|
||||
if not section in self._defaults:
|
||||
self._defaults[section] = dict()
|
||||
|
||||
self._defaults[section][name] = value
|
||||
|
||||
def set(self, section, name, value):
|
||||
def set(self, name, value):
|
||||
section, name = self._normalize_name(name)
|
||||
|
||||
if not section in self._normal:
|
||||
self._normal[section] = dict()
|
||||
|
||||
@ -80,18 +129,10 @@ class Configuration(object):
|
||||
return ConfigurationSection(self, section)
|
||||
|
||||
def __getitem__(self, key):
|
||||
if not isinstance(key, tuple) == 1:
|
||||
return self.section(key)
|
||||
elif isinstance(key, tuple) and len(key) == 2:
|
||||
return self.get(key[0], key[1])
|
||||
else:
|
||||
raise TypeError, "expectes 1 or 2 arguments, %d given" % len(key)
|
||||
return self.get(key)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
if isinstance(key, tuple) and len(key) == 2:
|
||||
self.set(key[0], key[1], value)
|
||||
else:
|
||||
raise TypeError, "key expected to be section + parameter names, got %s" % key
|
||||
self.set(key, value)
|
||||
|
||||
def __contains__(self, section):
|
||||
return (section in self._defaults) or (section in self._normal)
|
||||
@ -119,7 +160,7 @@ class Configuration(object):
|
||||
|
||||
def items(self, section=None):
|
||||
if section:
|
||||
return [(name, self.get(section, name)) for name in self.keys(section)]
|
||||
return [(name, self.get(self._combine_names(section, name))) for name in self.keys(section)]
|
||||
else:
|
||||
return [(name, ConfigurationSection(self, name)) for name in self.keys()]
|
||||
|
||||
|
@ -204,11 +204,11 @@ class OpenstackDiscovery(object):
|
||||
keystone.version = self._find_python_package_version(client, 'keystone')
|
||||
keystone.config_file = self._collect_file(client, config_path)
|
||||
|
||||
token = keystone.config['DEFAULT']['admin_token']
|
||||
host = keystone.config['DEFAULT']['bind_host']
|
||||
token = keystone.config['admin_token']
|
||||
host = keystone.config['bind_host']
|
||||
if host == '0.0.0.0':
|
||||
host = '127.0.0.1'
|
||||
port = int(keystone.config['DEFAULT']['admin_port'])
|
||||
port = int(keystone.config['admin_port'])
|
||||
|
||||
keystone_env = {
|
||||
'OS_SERVICE_TOKEN': token,
|
||||
@ -238,7 +238,7 @@ class OpenstackDiscovery(object):
|
||||
nova_api.version = self._find_python_package_version(client, 'nova')
|
||||
nova_api.config_file = self._collect_file(client, config_path)
|
||||
|
||||
paste_config_path = path_relative_to(nova_api.config['DEFAULT']['api_paste_config'], os.path.dirname(config_path))
|
||||
paste_config_path = path_relative_to(nova_api.config['api_paste_config'], os.path.dirname(config_path))
|
||||
nova_api.paste_config_file = self._collect_file(client, paste_config_path)
|
||||
|
||||
return nova_api
|
||||
@ -326,7 +326,7 @@ class OpenstackDiscovery(object):
|
||||
cinder_api.version = self._find_python_package_version(client, 'cinder')
|
||||
cinder_api.config_file = self._collect_file(client, config_path)
|
||||
|
||||
paste_config_path = path_relative_to(cinder_api.config['DEFAULT']['api_paste_config'], os.path.dirname(config_path))
|
||||
paste_config_path = path_relative_to(cinder_api.config['api_paste_config'], os.path.dirname(config_path))
|
||||
cinder_api.paste_config_file = self._collect_file(client, paste_config_path)
|
||||
|
||||
return cinder_api
|
||||
@ -346,7 +346,7 @@ class OpenstackDiscovery(object):
|
||||
cinder_volume.version = self._find_python_package_version(client, 'cinder')
|
||||
cinder_volume.config_file = self._collect_file(client, config_path)
|
||||
|
||||
rootwrap_config_path = path_relative_to(cinder_volume.config['DEFAULT']['rootwrap_config'], os.path.dirname(config_path))
|
||||
rootwrap_config_path = path_relative_to(cinder_volume.config['rootwrap_config'], os.path.dirname(config_path))
|
||||
cinder_volume.rootwrap_config = self._collect_file(client, rootwrap_config_path)
|
||||
|
||||
return cinder_volume
|
||||
@ -400,3 +400,4 @@ class OpenstackDiscovery(object):
|
||||
return None
|
||||
|
||||
return None
|
||||
|
||||
|
@ -18,12 +18,12 @@ class KeystoneAuthtokenSettingsInspection(Inspection):
|
||||
return
|
||||
|
||||
keystone = keystones[0]
|
||||
keystone_addresses = [keystone.config['DEFAULT']['bind_host']]
|
||||
keystone_addresses = [keystone.config['bind_host']]
|
||||
if keystone_addresses == ['0.0.0.0']:
|
||||
keystone_addresses = keystone.host.network_addresses
|
||||
|
||||
for nova in [c for c in components if c.name == 'nova-api']:
|
||||
if nova.config['DEFAULT']['auth_strategy'] != 'keystone':
|
||||
if nova.config['auth_strategy'] != 'keystone':
|
||||
continue
|
||||
|
||||
(authtoken_section,_) = find(
|
||||
@ -33,11 +33,11 @@ class KeystoneAuthtokenSettingsInspection(Inspection):
|
||||
|
||||
if not authtoken_section: continue
|
||||
|
||||
authtoken_settings = nova.paste_config[authtoken_section]
|
||||
authtoken_settings = nova.paste_config.section(authtoken_section)
|
||||
|
||||
|
||||
def get_value(name):
|
||||
return authtoken_settings[name] or nova.config['keystone_authtoken', name]
|
||||
return authtoken_settings[name] or nova.config['keystone_authtoken.%s' % name]
|
||||
|
||||
auth_host = get_value('auth_host')
|
||||
auth_port = get_value('auth_port')
|
||||
@ -56,7 +56,7 @@ class KeystoneAuthtokenSettingsInspection(Inspection):
|
||||
|
||||
if not auth_port:
|
||||
nova.report_issue(Issue(Issue.ERROR, msg_prefix + ' miss "auth_port" setting in keystone authtoken config'))
|
||||
elif auth_port != keystone.config['DEFAULT']['admin_port']:
|
||||
elif auth_port != keystone.config['admin_port']:
|
||||
nova.report_issue(Issue(Issue.ERROR, msg_prefix + ' has incorrect "auth_port" setting in keystone authtoken config'))
|
||||
|
||||
if not auth_protocol:
|
||||
|
@ -31,7 +31,7 @@ class KeystoneEndpointsInspection(Inspection):
|
||||
for c in host.components:
|
||||
if c.name != 'nova-compute': continue
|
||||
|
||||
if c.config['DEFAULT', 'osapi_compute_listen'] in ['0.0.0.0', url.hostname] and c.config['DEFAULT', 'osapi_compute_listen_port'] == url.port:
|
||||
if c.config['osapi_compute_listen'] in ['0.0.0.0', url.hostname] and c.config['osapi_compute_listen_port'] == url.port:
|
||||
nova_compute = c
|
||||
break
|
||||
|
||||
|
@ -139,7 +139,10 @@ class OpenstackComponent(Service):
|
||||
# Apply defaults
|
||||
if schema:
|
||||
for parameter in filter(lambda p: p.default, schema.parameters):
|
||||
_config.set_default(parameter.section, parameter.name, parameter.default)
|
||||
if parameter.section == 'DEFAULT':
|
||||
_config.set_default(parameter.name, parameter.default)
|
||||
else:
|
||||
_config.set_default('%s.%s' % (parameter.section, parameter.name), parameter.default)
|
||||
|
||||
# Parse config file
|
||||
|
||||
@ -182,6 +185,10 @@ class OpenstackComponent(Service):
|
||||
else:
|
||||
seen_parameters.add(parameter.name.text)
|
||||
|
||||
parameter_fullname = parameter.name.text
|
||||
if section_name != 'DEFAULT':
|
||||
parameter_fullname = section_name + '.' + parameter_fullname
|
||||
|
||||
if parameter_schema:
|
||||
type_validator = TypeValidatorRegistry.get_validator(parameter_schema.type)
|
||||
type_validation_result = type_validator.validate(parameter.value.text)
|
||||
@ -193,14 +200,14 @@ class OpenstackComponent(Service):
|
||||
else:
|
||||
value = type_validation_result
|
||||
|
||||
_config.set(section_name, parameter.name.text, value)
|
||||
_config.set(parameter_fullname, value)
|
||||
|
||||
# if value == parameter_schema.default:
|
||||
# report_issue(MarkedIssue(Issue.INFO, 'Explicit value equals default: section "%s" parameter "%s"' % (section_name, parameter.name.text), parameter.start_mark))
|
||||
if parameter_schema.deprecation_message:
|
||||
report_issue(MarkedIssue(Issue.WARNING, 'Deprecated parameter: section "%s" name "%s". %s' % (section_name, parameter.name.text, parameter_schema.deprecation_message), parameter.start_mark))
|
||||
else:
|
||||
_config.set(section_name, parameter.name.text, parameter.value.text)
|
||||
_config.set(parameter_fullname, parameter.value.text)
|
||||
|
||||
return _config
|
||||
|
||||
|
@ -5,173 +5,193 @@ from ostack_validator.config_model import Configuration
|
||||
class ConfigurationTests(unittest.TestCase):
|
||||
section = 'section1'
|
||||
param = 'param1'
|
||||
fullparam = '%s.%s' % (section, param)
|
||||
value = 'foobar'
|
||||
default_value = 'bar123'
|
||||
|
||||
def test_empty(self):
|
||||
c = Configuration()
|
||||
self.assertIsNone(c.get('section1', 'param1'))
|
||||
self.assertIsNone(c.get('section1.param1'))
|
||||
|
||||
def test_storage(self):
|
||||
|
||||
c = Configuration()
|
||||
c.set(self.section, self.param, self.value)
|
||||
c.set(self.fullparam, self.value)
|
||||
|
||||
self.assertEqual(self.value, c.get(self.section, self.param))
|
||||
self.assertEqual(self.value, c.get(self.fullparam))
|
||||
|
||||
def test_parameter_names_containing_sections(self):
|
||||
c = Configuration()
|
||||
c.set(self.fullparam, self.value)
|
||||
|
||||
self.assertEqual(self.value, c.get('%s.%s' % (self.section, self.param)))
|
||||
|
||||
def test_parameter_with_default_section(self):
|
||||
c = Configuration()
|
||||
c.set(self.param, self.value)
|
||||
|
||||
self.assertEqual(self.value, c.get(self.param))
|
||||
|
||||
def test_explicit_default_on_get(self):
|
||||
c = Configuration()
|
||||
override_value = '12345'
|
||||
|
||||
self.assertEqual(override_value, c.get(self.section, self.param, default=override_value))
|
||||
self.assertEqual(override_value, c.get(self.fullparam, default=override_value))
|
||||
|
||||
def test_default(self):
|
||||
c = Configuration()
|
||||
c.set_default(self.section, self.param, self.default_value)
|
||||
c.set_default(self.fullparam, self.default_value)
|
||||
|
||||
self.assertEqual(self.default_value, c.get(self.section, self.param))
|
||||
self.assertEqual(self.default_value, c.get(self.fullparam))
|
||||
|
||||
def test_normal_overrides_default(self):
|
||||
c = Configuration()
|
||||
c.set(self.section, self.param, self.value)
|
||||
c.set_default(self.section, self.param, self.default_value)
|
||||
c.set(self.fullparam, self.value)
|
||||
c.set_default(self.fullparam, self.default_value)
|
||||
|
||||
self.assertEqual(self.value, c.get(self.section, self.param))
|
||||
self.assertEqual(self.value, c.get(self.fullparam))
|
||||
|
||||
def test_contains(self):
|
||||
c = Configuration()
|
||||
self.assertFalse(c.contains(self.section, self.param))
|
||||
self.assertFalse(c.contains(self.fullparam))
|
||||
|
||||
def test_contains_default(self):
|
||||
c = Configuration()
|
||||
c.set_default(self.section, self.param, self.default_value)
|
||||
c.set_default(self.fullparam, self.default_value)
|
||||
|
||||
self.assertTrue(c.contains(self.section, self.param))
|
||||
self.assertFalse(c.contains(self.section, self.param, ignoreDefault=True))
|
||||
self.assertTrue(c.contains(self.fullparam))
|
||||
self.assertFalse(c.contains(self.fullparam, ignoreDefault=True))
|
||||
|
||||
def test_contains_normal(self):
|
||||
c = Configuration()
|
||||
c.set(self.section, self.param, self.value)
|
||||
c.set(self.fullparam, self.value)
|
||||
|
||||
self.assertTrue(c.contains(self.section, self.param))
|
||||
self.assertTrue(c.contains(self.section, self.param, ignoreDefault=True))
|
||||
self.assertTrue(c.contains(self.fullparam))
|
||||
self.assertTrue(c.contains(self.fullparam, ignoreDefault=True))
|
||||
|
||||
|
||||
def test_is_default_returns_false_if_param_missing(self):
|
||||
c = Configuration()
|
||||
self.assertFalse(c.is_default(self.section, self.param))
|
||||
self.assertFalse(c.is_default(self.fullparam))
|
||||
|
||||
def test_is_default_returns_true_if_only_default_value_set(self):
|
||||
c = Configuration()
|
||||
c.set_default(self.section, self.param, self.default_value)
|
||||
c.set_default(self.fullparam, self.default_value)
|
||||
|
||||
self.assertTrue(c.is_default(self.section, self.param))
|
||||
self.assertTrue(c.is_default(self.fullparam))
|
||||
|
||||
def test_is_default_returns_false_if_normal_value_set(self):
|
||||
c = Configuration()
|
||||
c.set(self.section, self.param, self.value)
|
||||
c.set(self.fullparam, self.value)
|
||||
|
||||
self.assertFalse(c.is_default(self.section, self.param))
|
||||
self.assertFalse(c.is_default(self.fullparam))
|
||||
|
||||
def test_is_default_returns_false_if_both_values_set(self):
|
||||
c = Configuration()
|
||||
c.set_default(self.section, self.param, self.default_value)
|
||||
c.set(self.section, self.param, self.value)
|
||||
c.set_default(self.fullparam, self.default_value)
|
||||
c.set(self.fullparam, self.value)
|
||||
|
||||
self.assertFalse(c.is_default(self.section, self.param))
|
||||
self.assertFalse(c.is_default(self.fullparam))
|
||||
|
||||
def test_subsection_set(self):
|
||||
c = Configuration()
|
||||
c[self.section].set(self.param, self.value)
|
||||
c.section(self.section).set(self.param, self.value)
|
||||
|
||||
self.assertEqual(self.value, c.get(self.section, self.param))
|
||||
self.assertEqual(self.value, c.get(self.fullparam))
|
||||
|
||||
def test_keys(self):
|
||||
c = Configuration()
|
||||
c.set_default('section1', 'param1', '123')
|
||||
c.set('section2', 'param1', '456')
|
||||
c.set_default('section1.param1', '123')
|
||||
c.set('section2.param1', '456')
|
||||
|
||||
self.assertEqual(['section1', 'section2'], sorted(c.keys()))
|
||||
|
||||
def test_subsection_keys(self):
|
||||
c = Configuration()
|
||||
c.set_default(self.section, 'param1', '123')
|
||||
c.set(self.section, 'param2', '456')
|
||||
c.set_default('%s.param1' % self.section, '123')
|
||||
c.set('%s.param2' % self.section, '456')
|
||||
|
||||
self.assertEqual(['param1', 'param2'], sorted(c[self.section].keys()))
|
||||
self.assertEqual(['param1', 'param2'], sorted(c.section(self.section).keys()))
|
||||
|
||||
def test_subsection_items(self):
|
||||
c = Configuration()
|
||||
c.set(self.section, 'param1', 'value1')
|
||||
c.set_default(self.section, 'param2', 'value2')
|
||||
c.set('%s.param1' % self.section, 'value1')
|
||||
c.set_default('%s.param2' % self.section, 'value2')
|
||||
|
||||
self.assertEqual([('param1', 'value1'), ('param2', 'value2')], sorted(c[self.section].items()))
|
||||
self.assertEqual([('param1', 'value1'), ('param2', 'value2')], sorted(c.section(self.section).items()))
|
||||
|
||||
def test_subsection_get(self):
|
||||
c = Configuration()
|
||||
|
||||
c.set(self.section, self.param, self.value)
|
||||
c.set(self.fullparam, self.value)
|
||||
|
||||
cs = c.section(self.section)
|
||||
self.assertEqual(self.value, cs.get(self.param))
|
||||
|
||||
def test_subsection_through_indexer(self):
|
||||
c = Configuration()
|
||||
|
||||
c.set(self.section, self.param, self.value)
|
||||
|
||||
cs = c[self.section]
|
||||
self.assertEqual(self.value, cs.get(self.param))
|
||||
|
||||
def test_getitem(self):
|
||||
c = Configuration()
|
||||
c.set(self.section, self.param, self.value)
|
||||
c.set(self.fullparam, self.value)
|
||||
|
||||
self.assertEqual(self.value, c[self.section, self.param])
|
||||
self.assertEqual(self.value, c[self.fullparam])
|
||||
|
||||
def test_subsection_getitem(self):
|
||||
c = Configuration()
|
||||
c.set(self.section, self.param, self.value)
|
||||
c.set(self.fullparam, self.value)
|
||||
|
||||
cs = c[self.section]
|
||||
cs = c.section(self.section)
|
||||
|
||||
self.assertEqual(self.value, cs[self.param])
|
||||
|
||||
def test_setitem(self):
|
||||
c = Configuration()
|
||||
|
||||
c[self.section, self.param] = self.value
|
||||
c[self.fullparam] = self.value
|
||||
|
||||
self.assertEqual(self.value, c.get(self.section, self.param))
|
||||
self.assertEqual(self.value, c.get(self.fullparam))
|
||||
|
||||
def test_subsection_setitem(self):
|
||||
c = Configuration()
|
||||
|
||||
cs = c[self.section]
|
||||
cs = c.section(self.section)
|
||||
|
||||
cs[self.param] = self.value
|
||||
|
||||
self.assertEqual(self.value, c.get(self.section, self.param))
|
||||
self.assertEqual(self.value, c.get(self.fullparam))
|
||||
|
||||
def test_contains(self):
|
||||
c = Configuration()
|
||||
|
||||
self.assertFalse(self.section in c)
|
||||
|
||||
c.set(self.section, self.param, self.value)
|
||||
c.set(self.fullparam, self.value)
|
||||
self.assertTrue(self.section in c)
|
||||
|
||||
def test_subsection_contains(self):
|
||||
c = Configuration()
|
||||
|
||||
c.set('section1', 'param1', '123')
|
||||
c.set_default('section2', 'param2', '234')
|
||||
c.set('section1.param1', '123')
|
||||
c.set_default('section2.param2', '234')
|
||||
|
||||
self.assertTrue('param1' in c['section1'])
|
||||
self.assertTrue('param2' in c['section2'])
|
||||
self.assertFalse('param1' in c['section2'])
|
||||
self.assertTrue('param1' in c.section('section1'))
|
||||
self.assertTrue('param2' in c.section('section2'))
|
||||
self.assertFalse('param1' in c.section('section2'))
|
||||
|
||||
def test_returns_section_object_even_if_section_doesnot_exist(self):
|
||||
c = Configuration()
|
||||
self.assertIsNotNone(c['foo'])
|
||||
self.assertIsNotNone(c.section('foo'))
|
||||
|
||||
def test_template_substitution(self):
|
||||
c = Configuration()
|
||||
c.set('a', 'x')
|
||||
c.set('b', '$a')
|
||||
c.set('c', '$b')
|
||||
|
||||
self.assertEqual('x', c.get('c'))
|
||||
|
||||
def test_cycle_template_substitution_resolves_in_empty_string(self):
|
||||
c = Configuration()
|
||||
c.set('a', 'a$c')
|
||||
c.set('b', 'b$a')
|
||||
c.set('c', 'c$b')
|
||||
|
||||
self.assertEqual('cba', c.get('c'))
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user