Compare commits

..

2 commits

Author SHA1 Message Date
1d18cc74b7 remove subconfig 2023-04-27 11:36:07 +02:00
4b76e3314e remote storage, so session and async too 2023-04-26 15:17:28 +02:00
32 changed files with 2382 additions and 2368 deletions

View file

@ -856,31 +856,31 @@ def autocheck_reset_value_permissive(cfg, mcfg, pathread, pathwrite, confread, c
_autocheck_default_value(cfg, pathread, confread, **kwargs)
if confread != confwrite:
_autocheck_default_value(cfg, pathwrite, confwrite, **kwargs)
@autocheck
def autocheck_display(cfg, mcfg, pathread, pathwrite, confread, confwrite, **kwargs):
"""re set value
"""
if kwargs['callback']:
return
make_dict = kwargs['make_dict']
make_dict_value = kwargs['make_dict_value']
if confread is not None:
cfg_ = cfg.config(confread)
else:
cfg_ = cfg
if confwrite is not None:
cfg2_ = cfg.config(confwrite)
else:
cfg2_ = cfg
assert cfg_.value.dict() == make_dict
if confread != confwrite:
assert(cfg2_.value.dict()) == make_dict
_set_value(cfg, pathwrite, confwrite, **kwargs)
assert cfg_.value.dict() == make_dict_value
if confread != confwrite:
assert(cfg2_.value.dict()) == make_dict_value
#FIXME
#FIXME
#FIXME@autocheck
#FIXMEdef autocheck_display(cfg, mcfg, pathread, pathwrite, confread, confwrite, **kwargs):
#FIXME """re set value
#FIXME """
#FIXME if kwargs['callback']:
#FIXME return
#FIXME make_dict = kwargs['make_dict']
#FIXME make_dict_value = kwargs['make_dict_value']
#FIXME if confread is not None:
#FIXME cfg_ = cfg.config(confread)
#FIXME else:
#FIXME cfg_ = cfg
#FIXME if confwrite is not None:
#FIXME cfg2_ = cfg.config(confwrite)
#FIXME else:
#FIXME cfg2_ = cfg
#FIXME assert cfg_.value.dict() == make_dict
#FIXME if confread != confwrite:
#FIXME assert(cfg2_.value.dict()) == make_dict
#FIXME _set_value(cfg, pathwrite, confwrite, **kwargs)
#FIXME assert cfg_.value.dict() == make_dict_value
#FIXME if confread != confwrite:
#FIXME assert(cfg2_.value.dict()) == make_dict_value
@autocheck

View file

@ -38,7 +38,7 @@ def test_cache():
od1 = make_description()
cfg = Config(od1)
values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache
settings = cfg._config_bag.context.properties_cache
cfg.option('u1').value.get()
assert 'u1' in values.get_cached()
assert 'u1' in settings.get_cached()
@ -94,7 +94,7 @@ def test_cache_reset():
od1 = make_description()
cfg = Config(od1)
values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache
settings = cfg._config_bag.context.properties_cache
#when change a value
cfg.option('u1').value.get()
cfg.option('u2').value.get()
@ -156,7 +156,7 @@ def test_cache_reset_multi():
od1 = make_description()
cfg = Config(od1)
values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache
settings = cfg._config_bag.context.properties_cache
cfg.option('u1').value.get()
cfg.option('u3').value.get()
assert 'u1' in values.get_cached()
@ -209,7 +209,7 @@ def test_reset_cache():
od1 = make_description()
cfg = Config(od1)
values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache
settings = cfg._config_bag.context.properties_cache
cfg.option('u1').value.get()
assert 'u1' in values.get_cached()
assert 'u1' in settings.get_cached()
@ -234,7 +234,7 @@ def test_cache_not_cache():
od1 = make_description()
cfg = Config(od1)
values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache
settings = cfg._config_bag.context.properties_cache
cfg.property.remove('cache')
cfg.option('u1').value.get()
assert 'u1' not in values.get_cached()
@ -250,7 +250,7 @@ def test_cache_leadership():
cfg = Config(od1)
cfg.property.read_write()
values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache
settings = cfg._config_bag.context.properties_cache
assert values.get_cached() == {}
#assert settings.get_cached() == {}
#
@ -311,7 +311,7 @@ def test_cache_callback():
cfg.property.read_write()
cfg.value.dict()
values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache
settings = cfg._config_bag.context.properties_cache
compare(values.get_cached(), {'val1': {None: ('val', None)},
'val2': {None: ('val', None)},
'val3': {None: ('yes', None)},
@ -386,11 +386,11 @@ def test_cache_leader_and_followers():
#None because no value
idx_val2 = None
values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache
settings = cfg._config_bag.context.properties_cache
compare(settings.get_cached(), {None: {None: (global_props, None)},
'val1': {None: (val1_props, None)},
'val1.val1': {None: (val1_val1_props, None)},
'val1.val2': {idx_val2: (val1_val2_props, None)}})
})
# len is 0 so don't get any value
compare(values.get_cached(), {'val1.val1': {None: ([], None)}})
#
@ -437,11 +437,11 @@ def test_cache_leader_callback():
val1_val1_props = frozenset(val1_val1_props)
val1_val2_props = frozenset(val1_val2_props)
values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache
settings = cfg._config_bag.context.properties_cache
compare(settings.get_cached(), {None: {None: (global_props, None)},
'val1': {None: (val1_props, None)},
'val1.val1': {None: (val1_val1_props, None)},
'val1.val2': {None: (val1_val2_props, None)}})
})
compare(values.get_cached(), {'val1.val1': {None: ([], None)}})
cfg.option('val1.val1').value.set([undefined])
compare(settings.get_cached(), {None: {None: (set(global_props), None)},
@ -465,7 +465,7 @@ def test_cache_requires():
cfg = Config(od1)
cfg.property.read_write()
values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache
settings = cfg._config_bag.context.properties_cache
assert values.get_cached() == {}
assert cfg.option('ip_address_service').value.get() == None
compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},
@ -518,7 +518,7 @@ def test_cache_global_properties():
cfg = Config(od1)
cfg.property.read_write()
values = cfg._config_bag.context._impl_values_cache
settings = cfg._config_bag.context._impl_properties_cache
settings = cfg._config_bag.context.properties_cache
assert values.get_cached() == {}
assert cfg.option('ip_address_service').value.get() == None
compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},

View file

@ -10,7 +10,6 @@ from .config import config_type, get_config, value_list, global_owner
import pytest
from tiramisu import Config
from tiramisu.config import SubConfig
from tiramisu.i18n import _
from tiramisu import Config, IntOption, FloatOption, ChoiceOption, \
BoolOption, StrOption, SymLinkOption, OptionDescription, undefined

View file

@ -82,8 +82,6 @@ def test_make_dict(config_type):
cfg.option('s1.a').value.set(True)
d = cfg.value.dict()
assert d == {"s1.a": True, "int": 43}
d2 = cfg.value.dict(flatten=True)
assert d2 == {'a': True, 'int': 43}
if config_type == 'tiramisu':
assert cfg.forcepermissive.value.dict() == {"s1.a": True, "s1.b": False, "int": 43}
# assert not list_sessions()
@ -100,7 +98,7 @@ def test_make_dict_sub(config_type):
cfg.property.read_write()
cfg.permissive.add('hidden')
cfg = get_config(cfg, config_type)
assert cfg.option('s1').value.dict() == {'a': False}
assert cfg.option('s1').value.dict() == {'s1.a': False}
def test_make_dict_not_value(config_type):
@ -169,13 +167,7 @@ def test_make_dict_fullpath(config_type):
cfg.property.read_only()
cfg = get_config(cfg, config_type)
assert cfg.value.dict() == {"opt.s1.a": False, "opt.int": 42, "introot": 42}
if config_type == 'tiramisu':
# FIXME
assert cfg.option('opt').value.dict() == {"s1.a": False, "int": 42}
assert cfg.value.dict(fullpath=True) == {"opt.s1.a": False, "opt.int": 42, "introot": 42}
if config_type == 'tiramisu':
# FIXME
assert cfg.option('opt').value.dict(fullpath=True) == {"opt.s1.a": False, "opt.int": 42}
assert cfg.option('opt').value.dict() == {"opt.s1.a": False, "opt.int": 42}
# assert not list_sessions()

View file

@ -17,7 +17,7 @@ def test_deref_value():
b = BoolOption('b', '')
o = OptionDescription('od', '', [b])
cfg = Config(o)
w = weakref.ref(cfg._config_bag.context.cfgimpl_get_values())
w = weakref.ref(cfg._config_bag.context.get_values())
del cfg
assert w() is None
@ -26,7 +26,7 @@ def test_deref_setting():
b = BoolOption('b', '')
o = OptionDescription('od', '', [b])
cfg = Config(o)
w = weakref.ref(cfg._config_bag.context.cfgimpl_get_settings())
w = weakref.ref(cfg._config_bag.context.get_settings())
del cfg
assert w() is None

View file

@ -406,7 +406,6 @@ def test_mandatory_dyndescription():
cfg.property.read_only()
with pytest.raises(PropertiesOptionError):
cfg.option('od.dodval1.stval1').value.get()
assert list(cfg.value.mandatory()) == ['od.dodval1.stval1', 'od.dodval2.stval2']
# assert not list_sessions()
@ -582,7 +581,6 @@ def test_mandatory_dyndescription_context():
cfg.property.read_only()
with pytest.raises(PropertiesOptionError):
cfg.option('od.dodval1.stval1').value.get()
assert list(cfg.value.mandatory()) == ['od.dodval1.stval1', 'od.dodval2.stval2']
# assert not list_sessions()
@ -952,7 +950,6 @@ def test_makedict_dyndescription_context():
cfg = Config(od2)
cfg.option('od.dodval1.stval1').value.set('yes')
assert cfg.value.dict() == {'od.val1': ['val1', 'val2'], 'od.dodval1.stval1': 'yes', 'od.dodval2.stval2': None}
assert cfg.value.dict(flatten=True) == {'val1': ['val1', 'val2'], 'stval1': 'yes', 'stval2': None}
# assert not list_sessions()
@ -1102,14 +1099,14 @@ def test_leadership_dyndescription():
cfg = Config(od1)
owner = cfg.owner.get()
#
assert cfg.value.dict() == {'od.stval1.st1val1.st2val1': [], 'od.stval2.st1val2.st2val2': [], 'od.stval2.st1val2.st1val2': [], 'od.stval1.st1val1.st1val1': []}
assert cfg.value.dict() == {'od.stval2.st1val2.st1val2': [], 'od.stval1.st1val1.st1val1': []}
assert cfg.option('od.stval1.st1val1.st1val1').value.get() == []
assert cfg.option('od.stval2.st1val2.st1val2').value.get() == []
assert cfg.option('od.stval1.st1val1.st1val1').owner.isdefault()
assert cfg.option('od.stval2.st1val2.st1val2').owner.isdefault()
#
cfg.option('od.stval1.st1val1.st1val1').value.set(['yes'])
assert cfg.value.dict() == {'od.stval1.st1val1.st2val1': [None], 'od.stval2.st1val2.st2val2': [], 'od.stval2.st1val2.st1val2': [], 'od.stval1.st1val1.st1val1': ['yes']}
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': [{'od.stval1.st1val1.st1val1': 'yes', 'od.stval1.st1val1.st2val1': None}], 'od.stval2.st1val2.st1val2': []}
assert cfg.option('od.stval1.st1val1.st1val1').value.get() == ['yes']
assert cfg.option('od.stval1.st1val1.st2val1', 0).value.get() == None
assert cfg.option('od.stval2.st1val2.st1val2').value.get() == []
@ -1167,20 +1164,20 @@ def test_leadership_dyndescription_force_store_value_leader():
assert cfg.option('od.stval1.st1val1.st2val1', 1).owner.isdefault() == True
assert cfg.option('od.stval2.st1val2.st2val2', 0).owner.isdefault() == True
assert cfg.option('od.stval2.st1val2.st2val2', 1).owner.isdefault() == True
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': ['val1', 'val2'], 'od.stval1.st1val1.st2val1': ['val1', 'val2'], 'od.stval2.st1val2.st1val2': ['val1', 'val2'], 'od.stval2.st1val2.st2val2': ['val1', 'val2'], 'od.val1': ['val1', 'val2']}
assert cfg.value.dict() == {'od.val1': ['val1', 'val2'], 'od.stval1.st1val1.st1val1': [{'od.stval1.st1val1.st1val1': 'val1', 'od.stval1.st1val1.st2val1': 'val1'}, {'od.stval1.st1val1.st1val1': 'val2', 'od.stval1.st1val1.st2val1': 'val2'}], 'od.stval2.st1val2.st1val2': [{'od.stval2.st1val2.st1val2': 'val1', 'od.stval2.st1val2.st2val2': 'val1'}, {'od.stval2.st1val2.st1val2': 'val2', 'od.stval2.st1val2.st2val2': 'val2'}]}
#
cfg.option('od.val1').value.set(['val1', 'val2', 'val3'])
assert cfg.option('od.stval3.st1val3.st1val3').owner.isdefault() == False
assert cfg.option('od.stval3.st1val3.st2val3', 0).owner.isdefault() == True
assert cfg.option('od.stval3.st1val3.st2val3', 1).owner.isdefault() == True
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': ['val1', 'val2'], 'od.stval1.st1val1.st2val1': ['val1', 'val2'], 'od.stval2.st1val2.st1val2': ['val1', 'val2'], 'od.stval2.st1val2.st2val2': ['val1', 'val2'], 'od.stval3.st1val3.st1val3': ['val1', 'val2'], 'od.stval3.st1val3.st2val3': ['val1', 'val2'], 'od.val1': ['val1', 'val2', 'val3']}
assert cfg.value.dict() == {'od.val1': ['val1', 'val2', 'val3'], 'od.stval1.st1val1.st1val1': [{'od.stval1.st1val1.st1val1': 'val1', 'od.stval1.st1val1.st2val1': 'val1'}, {'od.stval1.st1val1.st1val1': 'val2', 'od.stval1.st1val1.st2val1': 'val2'}], 'od.stval2.st1val2.st1val2': [{'od.stval2.st1val2.st1val2': 'val1', 'od.stval2.st1val2.st2val2': 'val1'}, {'od.stval2.st1val2.st1val2': 'val2', 'od.stval2.st1val2.st2val2': 'val2'}], 'od.stval3.st1val3.st1val3': [{'od.stval3.st1val3.st1val3': 'val1', 'od.stval3.st1val3.st2val3': 'val1'}, {'od.stval3.st1val3.st1val3': 'val2', 'od.stval3.st1val3.st2val3': 'val2'}]}
#
cfg.option('od.stval3.st1val3.st1val3').value.set(['val1', 'val2', 'val3'])
assert cfg.option('od.stval3.st1val3.st1val3').owner.isdefault() == False
assert cfg.option('od.stval3.st1val3.st2val3', 0).owner.isdefault() == True
assert cfg.option('od.stval3.st1val3.st2val3', 1).owner.isdefault() == True
assert cfg.option('od.stval3.st1val3.st2val3', 2).owner.isdefault() == True
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': ['val1', 'val2'], 'od.stval1.st1val1.st2val1': ['val1', 'val2'], 'od.stval2.st1val2.st1val2': ['val1', 'val2'], 'od.stval2.st1val2.st2val2': ['val1', 'val2'], 'od.stval3.st1val3.st1val3': ['val1', 'val2', 'val3'], 'od.stval3.st1val3.st2val3': ['val1', 'val2', 'val3'], 'od.val1': ['val1', 'val2', 'val3']}
assert cfg.value.dict() == {'od.val1': ['val1', 'val2', 'val3'], 'od.stval1.st1val1.st1val1': [{'od.stval1.st1val1.st1val1': 'val1', 'od.stval1.st1val1.st2val1': 'val1'}, {'od.stval1.st1val1.st1val1': 'val2', 'od.stval1.st1val1.st2val1': 'val2'}], 'od.stval2.st1val2.st1val2': [{'od.stval2.st1val2.st1val2': 'val1', 'od.stval2.st1val2.st2val2': 'val1'}, {'od.stval2.st1val2.st1val2': 'val2', 'od.stval2.st1val2.st2val2': 'val2'}], 'od.stval3.st1val3.st1val3': [{'od.stval3.st1val3.st1val3': 'val1', 'od.stval3.st1val3.st2val3': 'val1'}, {'od.stval3.st1val3.st1val3': 'val2', 'od.stval3.st1val3.st2val3': 'val2'}, {'od.stval3.st1val3.st1val3': 'val3', 'od.stval3.st1val3.st2val3': 'val3'}]}
# assert not list_sessions()
@ -1200,20 +1197,20 @@ def test_leadership_dyndescription_force_store_value():
assert cfg.option('od.stval1.st1val1.st2val1', 1).owner.isdefault() == False
assert cfg.option('od.stval2.st1val2.st2val2', 0).owner.isdefault() == False
assert cfg.option('od.stval2.st1val2.st2val2', 1).owner.isdefault() == False
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': ['val1', 'val2'], 'od.stval1.st1val1.st2val1': ['val1', 'val2'], 'od.stval2.st1val2.st1val2': ['val1', 'val2'], 'od.stval2.st1val2.st2val2': ['val1', 'val2'], 'od.val1': ['val1', 'val2']}
assert cfg.value.dict() == {'od.val1': ['val1', 'val2'], 'od.stval1.st1val1.st1val1': [{'od.stval1.st1val1.st1val1': 'val1', 'od.stval1.st1val1.st2val1': 'val1'}, {'od.stval1.st1val1.st1val1': 'val2', 'od.stval1.st1val1.st2val1': 'val2'}], 'od.stval2.st1val2.st1val2': [{'od.stval2.st1val2.st1val2': 'val1', 'od.stval2.st1val2.st2val2': 'val1'}, {'od.stval2.st1val2.st1val2': 'val2', 'od.stval2.st1val2.st2val2': 'val2'}]}
#
cfg.option('od.val1').value.set(['val1', 'val2', 'val3'])
assert cfg.option('od.stval3.st1val3.st1val3').owner.isdefault() == True
assert cfg.option('od.stval3.st1val3.st2val3', 0).owner.isdefault() == False
assert cfg.option('od.stval3.st1val3.st2val3', 1).owner.isdefault() == False
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': ['val1', 'val2'], 'od.stval1.st1val1.st2val1': ['val1', 'val2'], 'od.stval2.st1val2.st1val2': ['val1', 'val2'], 'od.stval2.st1val2.st2val2': ['val1', 'val2'], 'od.stval3.st1val3.st1val3': ['val1', 'val2'], 'od.stval3.st1val3.st2val3': ['val1', 'val2'], 'od.val1': ['val1', 'val2', 'val3']}
assert cfg.value.dict() == {'od.val1': ['val1', 'val2', 'val3'], 'od.stval1.st1val1.st1val1': [{'od.stval1.st1val1.st1val1': 'val1', 'od.stval1.st1val1.st2val1': 'val1'}, {'od.stval1.st1val1.st1val1': 'val2', 'od.stval1.st1val1.st2val1': 'val2'}], 'od.stval2.st1val2.st1val2': [{'od.stval2.st1val2.st1val2': 'val1', 'od.stval2.st1val2.st2val2': 'val1'}, {'od.stval2.st1val2.st1val2': 'val2', 'od.stval2.st1val2.st2val2': 'val2'}], 'od.stval3.st1val3.st1val3': [{'od.stval3.st1val3.st1val3': 'val1', 'od.stval3.st1val3.st2val3': 'val1'}, {'od.stval3.st1val3.st1val3': 'val2', 'od.stval3.st1val3.st2val3': 'val2'}]}
#
cfg.option('od.stval3.st1val3.st1val3').value.set(['val1', 'val2', 'val3'])
assert cfg.option('od.stval3.st1val3.st1val3').owner.isdefault() == False
assert cfg.option('od.stval3.st1val3.st2val3', 0).owner.isdefault() == False
assert cfg.option('od.stval3.st1val3.st2val3', 1).owner.isdefault() == False
assert cfg.option('od.stval3.st1val3.st2val3', 2).owner.isdefault() == False
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': ['val1', 'val2'], 'od.stval1.st1val1.st2val1': ['val1', 'val2'], 'od.stval2.st1val2.st1val2': ['val1', 'val2'], 'od.stval2.st1val2.st2val2': ['val1', 'val2'], 'od.stval3.st1val3.st1val3': ['val1', 'val2', 'val3'], 'od.stval3.st1val3.st2val3': ['val1', 'val2', 'val3'], 'od.val1': ['val1', 'val2', 'val3']}
assert cfg.value.dict() == {'od.val1': ['val1', 'val2', 'val3'], 'od.stval1.st1val1.st1val1': [{'od.stval1.st1val1.st1val1': 'val1', 'od.stval1.st1val1.st2val1': 'val1'}, {'od.stval1.st1val1.st1val1': 'val2', 'od.stval1.st1val1.st2val1': 'val2'}], 'od.stval2.st1val2.st1val2': [{'od.stval2.st1val2.st1val2': 'val1', 'od.stval2.st1val2.st2val2': 'val1'}, {'od.stval2.st1val2.st1val2': 'val2', 'od.stval2.st1val2.st2val2': 'val2'}], 'od.stval3.st1val3.st1val3': [{'od.stval3.st1val3.st1val3': 'val1', 'od.stval3.st1val3.st2val3': 'val1'}, {'od.stval3.st1val3.st1val3': 'val2', 'od.stval3.st1val3.st2val3': 'val2'}, {'od.stval3.st1val3.st1val3': 'val3', 'od.stval3.st1val3.st2val3': 'val3'}]}
# assert not list_sessions()
@ -1253,14 +1250,14 @@ def test_leadership_dyndescription_param():
od1 = OptionDescription('od', '', [od])
cfg = Config(od1)
owner = cfg.owner.get()
assert cfg.value.dict() == {'od.stval1.st1val1.st2val1': [], 'od.stval2.st1val2.st2val2': [], 'od.stval2.st1val2.st1val2': [], 'od.stval1.st1val1.st1val1': [], 'od.odval1.val1': ['val1', 'val2']}
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': [], 'od.stval2.st1val2.st1val2': [], 'od.odval1.val1': ['val1', 'val2']}
assert cfg.option('od.stval1.st1val1.st1val1').value.get() == []
assert cfg.option('od.stval2.st1val2.st1val2').value.get() == []
assert cfg.option('od.stval1.st1val1.st1val1').owner.get() == owners.default
assert cfg.option('od.stval2.st1val2.st1val2').owner.get() == owners.default
#
cfg.option('od.stval1.st1val1.st1val1').value.set(['yes'])
assert cfg.value.dict() == {'od.stval1.st1val1.st2val1': [None], 'od.stval2.st1val2.st2val2': [], 'od.stval2.st1val2.st1val2': [], 'od.stval1.st1val1.st1val1': ['yes'], 'od.odval1.val1': ['val1', 'val2']}
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': [{'od.stval1.st1val1.st1val1': 'yes', 'od.stval1.st1val1.st2val1': None}], 'od.stval2.st1val2.st1val2': [], 'od.odval1.val1': ['val1', 'val2']}
assert cfg.option('od.stval1.st1val1.st1val1').value.get() == ['yes']
assert cfg.option('od.stval1.st1val1.st2val1', 0).value.get() == None
assert cfg.option('od.stval2.st1val2.st1val2').value.get() == []
@ -1333,14 +1330,14 @@ def _test_leadership(cfg):
cfg.option('od.val1.val1').value.set(['val1', 'val2'])
cfg.option('od.val1.val2', 0).value.set('val1')
cfg.option('od.val1.val2', 1).value.set('val2')
assert cfg.value.dict() == {'od.stval1.st1val1.st2val1': [], 'od.stval2.st1val2.st2val2': [], 'od.stval2.st1val2.st1val2': [], 'od.stval1.st1val1.st1val1': [], 'od.val1.val1': ['val1', 'val2'], 'od.val1.val2': ['val1', 'val2']}
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': [], 'od.stval2.st1val2.st1val2': [], 'od.val1.val1': [{'od.val1.val1': 'val1', 'od.val1.val2': 'val1'}, {'od.val1.val1': 'val2', 'od.val1.val2': 'val2'}]}
assert cfg.option('od.stval1.st1val1.st1val1').value.get() == []
assert cfg.option('od.stval2.st1val2.st1val2').value.get() == []
assert cfg.option('od.stval1.st1val1.st1val1').owner.get() == owners.default
assert cfg.option('od.stval2.st1val2.st1val2').owner.get() == owners.default
#
cfg.option('od.stval1.st1val1.st1val1').value.set(['yes'])
assert cfg.value.dict() == {'od.stval1.st1val1.st2val1': [None], 'od.stval2.st1val2.st2val2': [], 'od.stval2.st1val2.st1val2': [], 'od.stval1.st1val1.st1val1': ['yes'], 'od.val1.val1': ['val1', 'val2'], 'od.val1.val2': ['val1', 'val2']}
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': [{'od.stval1.st1val1.st1val1': 'yes', 'od.stval1.st1val1.st2val1': None}], 'od.stval2.st1val2.st1val2': [], 'od.val1.val1': [{'od.val1.val1': 'val1', 'od.val1.val2': 'val1'}, {'od.val1.val1': 'val2', 'od.val1.val2': 'val2'}]}
assert cfg.option('od.stval1.st1val1.st1val1').value.get() == ['yes']
assert cfg.option('od.stval1.st1val1.st2val1', 0).value.get() == None
assert cfg.option('od.stval2.st1val2.st1val2').value.get() == []
@ -1504,14 +1501,14 @@ def test_leadership_callback_dyndescription():
od2 = OptionDescription('od', '', [od1])
cfg = Config(od2)
owner = cfg.owner.get()
assert cfg.value.dict() == {'od.stval1.st1val1.st2val1': [], 'od.stval2.st1val2.st2val2': [], 'od.stval2.st1val2.st1val2': [], 'od.stval1.st1val1.st1val1': []}
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': [], 'od.stval2.st1val2.st1val2': []}
assert cfg.option('od.stval1.st1val1.st1val1').value.get() ==[]
assert cfg.option('od.stval2.st1val2.st1val2').value.get() == []
assert cfg.option('od.stval1.st1val1.st1val1').owner.isdefault()
assert cfg.option('od.stval2.st1val2.st1val2').owner.isdefault()
#
cfg.option('od.stval1.st1val1.st1val1').value.set(['yes'])
assert cfg.value.dict() == {'od.stval1.st1val1.st2val1': ['yes'], 'od.stval2.st1val2.st2val2': [], 'od.stval2.st1val2.st1val2': [], 'od.stval1.st1val1.st1val1': ['yes']}
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': [{'od.stval1.st1val1.st1val1': 'yes', 'od.stval1.st1val1.st2val1': 'yes'}], 'od.stval2.st1val2.st1val2': []}
assert cfg.option('od.stval1.st1val1.st1val1').value.get() == ['yes']
assert cfg.option('od.stval1.st1val1.st2val1', 0).value.get() == 'yes'
assert cfg.option('od.stval2.st1val2.st1val2').value.get() == []
@ -1599,36 +1596,21 @@ def test_leadership_callback_samegroup_dyndescription():
od2 = OptionDescription('od', '', [od1])
cfg = Config(od2)
owner = cfg.owner.get()
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': [],
'od.stval1.st1val1.st2val1': [],
'od.stval1.st1val1.st3val1': [],
'od.stval2.st1val2.st1val2': [],
'od.stval2.st1val2.st2val2': [],
'od.stval2.st1val2.st3val2': []}
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': [], 'od.stval2.st1val2.st1val2': []}
assert cfg.option('od.stval1.st1val1.st1val1').value.get() == []
assert cfg.option('od.stval2.st1val2.st1val2').value.get() == []
assert cfg.option('od.stval1.st1val1.st1val1').owner.isdefault()
assert cfg.option('od.stval2.st1val2.st1val2').owner.isdefault()
#
cfg.option('od.stval1.st1val1.st1val1').value.set(['yes'])
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': ['yes'],
'od.stval1.st1val1.st2val1': [None],
'od.stval1.st1val1.st3val1': [None],
'od.stval2.st1val2.st1val2': [],
'od.stval2.st1val2.st2val2': [],
'od.stval2.st1val2.st3val2': []}
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': [{'od.stval1.st1val1.st1val1': 'yes', 'od.stval1.st1val1.st2val1': None, 'od.stval1.st1val1.st3val1': None}], 'od.stval2.st1val2.st1val2': []}
assert cfg.option('od.stval1.st1val1.st1val1').owner.get() == owner
assert cfg.option('od.stval1.st1val1.st2val1', 0).owner.isdefault()
assert cfg.option('od.stval1.st1val1.st3val1', 0).owner.isdefault()
assert cfg.option('od.stval2.st1val2.st1val2').owner.isdefault()
#
cfg.option('od.stval1.st1val1.st2val1', 0).value.set('yes')
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': ['yes'],
'od.stval1.st1val1.st2val1': ['yes'],
'od.stval1.st1val1.st3val1': ['yes'],
'od.stval2.st1val2.st1val2': [],
'od.stval2.st1val2.st2val2': [],
'od.stval2.st1val2.st3val2': []}
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': [{'od.stval1.st1val1.st1val1': 'yes', 'od.stval1.st1val1.st2val1': 'yes', 'od.stval1.st1val1.st3val1': 'yes'}], 'od.stval2.st1val2.st1val2': []}
assert cfg.option('od.stval1.st1val1.st1val1').owner.get() == owner
assert cfg.option('od.stval1.st1val1.st2val1', 0).owner.get() == owner
assert cfg.option('od.stval1.st1val1.st3val1', 0).owner.isdefault()
@ -1712,14 +1694,14 @@ def test_leadership_dyndescription_convert():
cfg = Config(od1)
owner = cfg.owner.get()
#
assert cfg.value.dict() == {'od.stval1.st1val1.st2val1': [], 'od.stval2.st1val2.st2val2': [], 'od.stval2.st1val2.st1val2': [], 'od.stval1.st1val1.st1val1': []}
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': [], 'od.stval2.st1val2.st1val2': []}
assert cfg.option('od.stval1.st1val1.st1val1').value.get() == []
assert cfg.option('od.stval2.st1val2.st1val2').value.get() == []
assert cfg.option('od.stval1.st1val1.st1val1').owner.isdefault()
assert cfg.option('od.stval2.st1val2.st1val2').owner.isdefault()
#
cfg.option('od.stval1.st1val1.st1val1').value.set(['yes'])
assert cfg.value.dict() == {'od.stval1.st1val1.st2val1': [None], 'od.stval2.st1val2.st2val2': [], 'od.stval2.st1val2.st1val2': [], 'od.stval1.st1val1.st1val1': ['yes']}
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': [{'od.stval1.st1val1.st1val1': 'yes', 'od.stval1.st1val1.st2val1': None}], 'od.stval2.st1val2.st1val2': []}
assert cfg.option('od.stval1.st1val1.st1val1').value.get() == ['yes']
assert cfg.option('od.stval1.st1val1.st2val1', 0).value.get() == None
assert cfg.option('od.stval2.st1val2.st1val2').value.get() == []
@ -1771,36 +1753,21 @@ def test_leadership_callback_samegroup_dyndescription_convert():
od2 = OptionDescription('od', '', [od1])
cfg = Config(od2)
owner = cfg.owner.get()
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': [],
'od.stval1.st1val1.st2val1': [],
'od.stval1.st1val1.st3val1': [],
'od.stval2.st1val2.st1val2': [],
'od.stval2.st1val2.st2val2': [],
'od.stval2.st1val2.st3val2': []}
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': [], 'od.stval2.st1val2.st1val2': []}
assert cfg.option('od.stval1.st1val1.st1val1').value.get() == []
assert cfg.option('od.stval2.st1val2.st1val2').value.get() == []
assert cfg.option('od.stval1.st1val1.st1val1').owner.isdefault()
assert cfg.option('od.stval2.st1val2.st1val2').owner.isdefault()
#
cfg.option('od.stval1.st1val1.st1val1').value.set(['yes'])
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': ['yes'],
'od.stval1.st1val1.st2val1': [None],
'od.stval1.st1val1.st3val1': [None],
'od.stval2.st1val2.st1val2': [],
'od.stval2.st1val2.st2val2': [],
'od.stval2.st1val2.st3val2': []}
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': [{'od.stval1.st1val1.st1val1': 'yes', 'od.stval1.st1val1.st2val1': None, 'od.stval1.st1val1.st3val1': None}], 'od.stval2.st1val2.st1val2': []}
assert cfg.option('od.stval1.st1val1.st1val1').owner.get() == owner
assert cfg.option('od.stval1.st1val1.st2val1', 0).owner.isdefault()
assert cfg.option('od.stval1.st1val1.st3val1', 0).owner.isdefault()
assert cfg.option('od.stval2.st1val2.st1val2').owner.isdefault()
#
cfg.option('od.stval1.st1val1.st2val1', 0).value.set('yes')
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': ['yes'],
'od.stval1.st1val1.st2val1': ['yes'],
'od.stval1.st1val1.st3val1': ['yes'],
'od.stval2.st1val2.st1val2': [],
'od.stval2.st1val2.st2val2': [],
'od.stval2.st1val2.st3val2': []}
assert cfg.value.dict() == {'od.stval1.st1val1.st1val1': [{'od.stval1.st1val1.st1val1': 'yes', 'od.stval1.st1val1.st2val1': 'yes', 'od.stval1.st1val1.st3val1': 'yes'}], 'od.stval2.st1val2.st1val2': []}
assert cfg.option('od.stval1.st1val1.st1val1').owner.get() == owner
assert cfg.option('od.stval1.st1val1.st2val1', 0).owner.get() == owner
assert cfg.option('od.stval1.st1val1.st3val1', 0).owner.isdefault()
@ -1824,8 +1791,8 @@ def test_dyn_with_leader_hidden_in_config():
cfg.option('leaderval1.ip_admin_eth0val1.ip_admin_eth0val1').value.get()
with pytest.raises(PropertiesOptionError):
cfg.option('leaderval1.ip_admin_eth0val1.netmask_admin_eth0val1', 0).value.get()
cfg.value.dict(leader_to_list=True) == {'leaderval1.ip_admin_eth0val1.ip_admin_eth0val1': [{'leaderval1.ip_admin_eth0val1.ip_admin_eth0val1': '192.168.1.1'}],
'leaderval2.ip_admin_eth0val2.ip_admin_eth0val2': [{'leaderval2.ip_admin_eth0val2.ip_admin_eth0val2': '192.168.1.1'}]}
cfg.value.dict() == {'leaderval1.ip_admin_eth0val1.ip_admin_eth0val1': [{'leaderval1.ip_admin_eth0val1.ip_admin_eth0val1': '192.168.1.1'}],
'leaderval2.ip_admin_eth0val2.ip_admin_eth0val2': [{'leaderval2.ip_admin_eth0val2.ip_admin_eth0val2': '192.168.1.1'}]}
# assert not list_sessions()
@ -1858,12 +1825,7 @@ def test_dyn_leadership_requires():
assert cfg.option('leaderval1.ip_admin_eth0val1.netmask_admin_eth0val1', 1).value.get() is None
cfg.option('leaderval1.ip_admin_eth0val1.netmask_admin_eth0val1', 1).value.set('255.255.255.255')
assert cfg.option('leaderval1.ip_admin_eth0val1.netmask_admin_eth0val1', 1).value.get() == '255.255.255.255'
assert cfg.value.dict() == {'leaderval1.ip_admin_eth0val1.ip_admin_eth0val1': ['192.168.1.2', '192.168.1.2'],
'leaderval1.ip_admin_eth0val1.netmask_admin_eth0val1': [None, '255.255.255.255'],
'leaderval2.ip_admin_eth0val2.ip_admin_eth0val2': [],
'leaderval2.ip_admin_eth0val2.netmask_admin_eth0val2': []}
ret = cfg.value.dict(leader_to_list=True)
ret = cfg.value.dict()
assert ret == {'leaderval1.ip_admin_eth0val1.ip_admin_eth0val1': [{'leaderval1.ip_admin_eth0val1.ip_admin_eth0val1': '192.168.1.2', 'leaderval1.ip_admin_eth0val1.netmask_admin_eth0val1': None},
{'leaderval1.ip_admin_eth0val1.ip_admin_eth0val1': '192.168.1.2', 'leaderval1.ip_admin_eth0val1.netmask_admin_eth0val1': '255.255.255.255'}],
'leaderval2.ip_admin_eth0val2.ip_admin_eth0val2': []}
@ -1873,24 +1835,8 @@ def test_dyn_leadership_requires():
assert cfg.option('leaderval1.ip_admin_eth0val1.netmask_admin_eth0val1', 0).value.get() is None
with pytest.raises(PropertiesOptionError):
cfg.option('leaderval1.ip_admin_eth0val1.netmask_admin_eth0val1', 1).value.get()
ret = cfg.value.dict()
assert set(ret.keys()) == set(['leaderval1.ip_admin_eth0val1.ip_admin_eth0val1', 'leaderval1.ip_admin_eth0val1.netmask_admin_eth0val1', 'leaderval2.ip_admin_eth0val2.ip_admin_eth0val2', 'leaderval2.ip_admin_eth0val2.netmask_admin_eth0val2'])
assert ret['leaderval1.ip_admin_eth0val1.ip_admin_eth0val1'] == ['192.168.1.2', '192.168.1.1']
assert len(ret['leaderval1.ip_admin_eth0val1.netmask_admin_eth0val1']) == 2
assert ret['leaderval1.ip_admin_eth0val1.netmask_admin_eth0val1'][0] is None
assert isinstance(ret['leaderval1.ip_admin_eth0val1.netmask_admin_eth0val1'][1], PropertiesOptionError)
del ret['leaderval1.ip_admin_eth0val1.netmask_admin_eth0val1'][1]
del ret['leaderval1.ip_admin_eth0val1.netmask_admin_eth0val1'][0]
del ret['leaderval1.ip_admin_eth0val1.netmask_admin_eth0val1']
assert cfg.value.dict(leader_to_list=True) == {'leaderval1.ip_admin_eth0val1.ip_admin_eth0val1': [{'leaderval1.ip_admin_eth0val1.ip_admin_eth0val1': '192.168.1.2',
'leaderval1.ip_admin_eth0val1.netmask_admin_eth0val1': None},
{'leaderval1.ip_admin_eth0val1.ip_admin_eth0val1': '192.168.1.1'}],
'leaderval2.ip_admin_eth0val2.ip_admin_eth0val2': []}
assert cfg.value.dict() == {'leaderval1.ip_admin_eth0val1.ip_admin_eth0val1': [{'leaderval1.ip_admin_eth0val1.ip_admin_eth0val1': '192.168.1.2', 'leaderval1.ip_admin_eth0val1.netmask_admin_eth0val1': None}, {'leaderval1.ip_admin_eth0val1.ip_admin_eth0val1': '192.168.1.1'}], 'leaderval2.ip_admin_eth0val2.ip_admin_eth0val2': []}
#
assert cfg.value.dict(leader_to_list=True) == {'leaderval1.ip_admin_eth0val1.ip_admin_eth0val1': [{'leaderval1.ip_admin_eth0val1.ip_admin_eth0val1': '192.168.1.2',
'leaderval1.ip_admin_eth0val1.netmask_admin_eth0val1': None},
{'leaderval1.ip_admin_eth0val1.ip_admin_eth0val1': '192.168.1.1'}],
'leaderval2.ip_admin_eth0val2.ip_admin_eth0val2': []}
# assert not list_sessions()

View file

@ -62,17 +62,7 @@ def test_base_config(config_type):
if config_type != 'tiramisu-api':
ret = cfg.option.find('nom_machine', first=True)
assert ret.value.get() == "eoleng"
result = {'general.numero_etab': None, 'general.nombre_interfaces': 1,
'general.serveur_ntp': [], 'interface1.ip_admin_eth0.ip_admin_eth0': None,
'general.mode_conteneur_actif': False, 'general.time_zone': 'Paris',
'interface1.ip_admin_eth0.netmask_admin_eth0': None, 'general.nom_machine':
'eoleng', 'general.activer_proxy_client': False}
assert cfg.option('creole').value.dict() == result
result = {'serveur_ntp': [], 'mode_conteneur_actif': False,
'ip_admin_eth0': None, 'time_zone': 'Paris', 'numero_etab': None,
'netmask_admin_eth0': None, 'nom_machine': 'eoleng', 'activer_proxy_client':
False, 'nombre_interfaces': 1}
assert cfg.option('creole').value.dict(flatten=True) == result
assert cfg.option('creole').value.dict() == {'creole.general.numero_etab': None, 'creole.general.nom_machine': 'eoleng', 'creole.general.nombre_interfaces': 1, 'creole.general.activer_proxy_client': False, 'creole.general.mode_conteneur_actif': False, 'creole.general.serveur_ntp': [], 'creole.general.time_zone': 'Paris', 'creole.interface1.ip_admin_eth0.ip_admin_eth0': None, 'creole.interface1.ip_admin_eth0.netmask_admin_eth0': None}
if config_type == 'tiramisu-api':
cfg.send()
# assert not list_sessions()
@ -94,11 +84,13 @@ def test_iter_on_groups():
cfg = Config(od1)
cfg.property.read_write()
result = cfg.option('creole').list('optiondescription',
group_type=groups.family)
group_type=groups.family,
)
group_names = [res.option.name() for res in result]
assert group_names == ['general', 'interface1']
for i in cfg.option('creole').list('optiondescription',
group_type=groups.family):
group_type=groups.family,
):
#test StopIteration
break
result = cfg.option('creole').list('option',
@ -125,7 +117,7 @@ def test_list_recursive():
'netmask_admin_eth0']
result = list(cfg.option.list(recursive=True, type='optiondescription'))
group_names = [res.option.name() for res in result]
assert group_names == ['general', 'ip_admin_eth0', 'interface1', 'creole']
assert group_names == ['creole', 'general', 'interface1', 'ip_admin_eth0']
# assert not list_sessions()
@ -185,12 +177,8 @@ def test_iter_not_group():
od1 = OptionDescription("name", "descr", [])
cfg = Config(od1)
cfg.property.read_write()
try:
list(cfg.option.list(type='optiondescription', group_type='family'))
except AssertionError:
pass
else:
raise Exception('must raise')
with pytest.raises(AssertionError):
print(list(cfg.option.list(type='optiondescription', group_type='family')))
# assert not list_sessions()
@ -257,8 +245,7 @@ def test_groups_with_leader_make_dict(config_type):
od1 = OptionDescription('root', '', [interface1])
cfg = Config(od1)
cfg = get_config(cfg, config_type)
assert cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': [], 'ip_admin_eth0.netmask_admin_eth0': []}
assert cfg.value.dict(leader_to_list=True) == {'ip_admin_eth0.ip_admin_eth0': []}
assert cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': []}
if config_type != 'tiramisu-api':
# FIXME useful? already in leadership
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.len() == 0
@ -268,8 +255,7 @@ def test_groups_with_leader_make_dict(config_type):
# FIXME
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.len() == 2
assert cfg.option('ip_admin_eth0.netmask_admin_eth0').value.len() == 2
assert cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': ['ip1', 'ip2'], 'ip_admin_eth0.netmask_admin_eth0': [None, None]}
assert cfg.value.dict(leader_to_list=True) == {'ip_admin_eth0.ip_admin_eth0': [{'ip_admin_eth0.ip_admin_eth0': 'ip1', 'ip_admin_eth0.netmask_admin_eth0': None}, {'ip_admin_eth0.ip_admin_eth0': 'ip2', 'ip_admin_eth0.netmask_admin_eth0': None}]}
assert cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': [{'ip_admin_eth0.ip_admin_eth0': 'ip1', 'ip_admin_eth0.netmask_admin_eth0': None}, {'ip_admin_eth0.ip_admin_eth0': 'ip2', 'ip_admin_eth0.netmask_admin_eth0': None}]}
if config_type == 'tiramisu-api':
cfg.send()
# assert not list_sessions()
@ -292,8 +278,7 @@ def test_groups_with_leader_make_dict2(config_type):
od1 = OptionDescription('root', '', [interface1])
cfg = Config(od1)
cfg = get_config(cfg, config_type)
assert cfg.value.dict() == {'other.ip_admin_eth0': [], 'other.netmask_admin_eth0': []}
assert cfg.value.dict(leader_to_list=True) == {'other.ip_admin_eth0': []}
assert cfg.value.dict() == {'other.ip_admin_eth0': []}
if config_type != 'tiramisu-api':
# FIXME useful? already in leadership
assert cfg.option('other.ip_admin_eth0').value.len() == 0
@ -303,8 +288,7 @@ def test_groups_with_leader_make_dict2(config_type):
# FIXME
assert cfg.option('other.ip_admin_eth0').value.len() == 2
assert cfg.option('other.netmask_admin_eth0').value.len() == 2
assert cfg.value.dict() == {'other.ip_admin_eth0': ['ip1', 'ip2'], 'other.netmask_admin_eth0': [None, None]}
assert cfg.value.dict(leader_to_list=True) == {'other.ip_admin_eth0': [{'other.ip_admin_eth0': 'ip1', 'other.netmask_admin_eth0': None}, {'other.ip_admin_eth0': 'ip2', 'other.netmask_admin_eth0': None}]}
assert cfg.value.dict() == {'other.ip_admin_eth0': [{'other.ip_admin_eth0': 'ip1', 'other.netmask_admin_eth0': None}, {'other.ip_admin_eth0': 'ip2', 'other.netmask_admin_eth0': None}]}
if config_type == 'tiramisu-api':
cfg.send()
# assert not list_sessions()
@ -344,13 +328,11 @@ def test_groups_with_leader_default_value_2(config_type):
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == 'netmask1'
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.default() == 'netmask1'
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.default() == 'netmask1'
assert cfg.option('ip_admin_eth0.netmask_admin_eth0').value.default() == ['netmask1', 'netmask1']
cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.set('netmask2')
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == 'netmask1'
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == 'netmask2'
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.default() == 'netmask1'
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.default() == 'netmask1'
assert cfg.option('ip_admin_eth0.netmask_admin_eth0').value.default() == ['netmask1', 'netmask1']
if config_type == 'tiramisu-api':
cfg.send()
# assert not list_sessions()
@ -372,7 +354,6 @@ def test_groups_with_leader_hidden_in_config():
with pytest.raises(PropertiesOptionError):
cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()
assert cfg.value.dict() == {}
assert cfg.value.dict(leader_to_list=True) == {}
# assert not list_sessions()

View file

@ -5,9 +5,9 @@ do_autopath()
import pytest
from tiramisu import Config
from tiramisu import IntOption, StrOption, OptionDescription, \
from tiramisu import IntOption, StrOption, OptionDescription, DynOptionDescription, \
SymLinkOption, Leadership, undefined, Calculation, Params, \
ParamOption, ParamValue, calc_value
ParamOption, ParamValue, ParamIndex, calc_value
from tiramisu.error import PropertiesOptionError, ConfigError
from tiramisu.setting import groups
@ -36,14 +36,14 @@ def return_value(value):
def make_description2():
stroption = StrOption('str', 'Test string option', default="abc",
stroption = StrOption('str', 'str', default="abc",
properties=('mandatory', ))
stroption1 = StrOption('str1', 'Test string option',
stroption1 = StrOption('str1', 'str1',
properties=('mandatory', ))
stroption2 = SymLinkOption('unicode2', stroption1)
stroption3 = StrOption('str3', 'Test string option', multi=True,
stroption3 = StrOption('str3', 'str3', multi=True,
properties=('mandatory', ))
unicode1 = StrOption('unicode1', 'Test string option', Calculation(return_value, Params(ParamOption(stroption))), properties=('mandatory',))
unicode1 = StrOption('unicode1', 'unicode1', Calculation(return_value, Params(ParamOption(stroption))), properties=('mandatory',))
descr = OptionDescription('tiram', '', [stroption, stroption1, stroption2, stroption3, unicode1])
return descr
@ -319,6 +319,18 @@ def test_mandatory_unicode():
# assert not list_sessions()
def compare(ret, expected):
assert(len(ret) == len(expected))
for index, opt in enumerate(ret):
exp = expected[index]
if isinstance(exp, list):
assert opt.option.path() == exp[0]
assert opt.option.index() == exp[1]
else:
assert opt.option.path() == exp
assert opt.option.index() == None
def test_mandatory_warnings_ro():
od1 = make_description()
cfg = Config(od1)
@ -330,11 +342,11 @@ def test_mandatory_warnings_ro():
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
assert list(cfg.value.mandatory()) == ['str', 'str1', 'unicode2', 'str3']
compare(cfg.value.mandatory(), ['str', 'str1', 'unicode2', 'str3'])
cfg.property.read_write()
cfg.option('str').value.set('a')
cfg.property.read_only()
assert list(cfg.value.mandatory()) == ['str1', 'unicode2', 'str3']
compare(cfg.value.mandatory(), ['str1', 'unicode2', 'str3'])
# assert not list_sessions()
@ -344,9 +356,9 @@ def test_mandatory_warnings_rw():
cfg.option('str').value.set('')
cfg.property.read_write()
cfg.option('str').value.get()
assert list(cfg.value.mandatory()) == ['str', 'str1', 'unicode2', 'str3']
compare(cfg.value.mandatory(), ['str', 'str1', 'unicode2', 'str3'])
cfg.option('str').value.set('a')
assert list(cfg.value.mandatory()) == ['str1', 'unicode2', 'str3']
compare(cfg.value.mandatory(), ['str1', 'unicode2', 'str3'])
# assert not list_sessions()
@ -356,9 +368,9 @@ def test_mandatory_warnings_disabled():
cfg.option('str').value.set('')
cfg.property.read_write()
cfg.option('str').value.get()
assert set(cfg.value.mandatory()) == {'str', 'str1', 'unicode2', 'str3'}
compare(cfg.value.mandatory(), ['str', 'str1', 'unicode2', 'str3'])
cfg.option('str').property.add('disabled')
assert set(cfg.value.mandatory()) == {'str1', 'unicode2', 'str3'}
compare(cfg.value.mandatory(), ['str1', 'unicode2', 'str3'])
# assert not list_sessions()
@ -369,9 +381,9 @@ def test_mandatory_warnings_hidden():
cfg.property.read_write()
cfg.permissive.add('hidden')
cfg.option('str').value.get()
assert set(cfg.value.mandatory()) == {'str', 'str1', 'unicode2', 'str3'}
compare(cfg.value.mandatory(), ['str', 'str1', 'unicode2', 'str3'])
cfg.option('str').property.add('hidden')
assert set(cfg.value.mandatory()) == {'str', 'str1', 'unicode2', 'str3'}
compare(cfg.value.mandatory(), ['str', 'str1', 'unicode2', 'str3'])
# assert not list_sessions()
@ -381,10 +393,10 @@ def test_mandatory_warnings_frozen():
cfg.option('str').value.set('')
cfg.property.read_write()
cfg.option('str').value.get()
assert set(cfg.value.mandatory()) == {'str', 'str1', 'unicode2', 'str3'}
compare(cfg.value.mandatory(), ['str', 'str1', 'unicode2', 'str3'])
cfg.option('str').property.add('frozen')
cfg.property.read_only()
assert set(cfg.value.mandatory()) == {'str', 'str1', 'unicode2', 'str3'}
compare(cfg.value.mandatory(), ['str', 'str1', 'unicode2', 'str3'])
# assert not list_sessions()
@ -429,7 +441,7 @@ def test_mandatory_warnings_leader():
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
od1 = OptionDescription('o', '', [interface1])
cfg = Config(od1)
assert list(cfg.value.mandatory()) == ['ip_admin_eth0.ip_admin_eth0']
compare(cfg.value.mandatory(), ['ip_admin_eth0.ip_admin_eth0'])
# assert not list_sessions()
@ -492,17 +504,17 @@ def test_mandatory_warnings_leader_empty():
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set([undefined])
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == [None]
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
assert list(cfg.value.mandatory()) == ['ip_admin_eth0.ip_admin_eth0']
compare(cfg.value.mandatory(), ['ip_admin_eth0.ip_admin_eth0'])
cfg.option('ip_admin_eth0.ip_admin_eth0').value.reset()
#
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set([''])
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['']
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
assert list(cfg.value.mandatory()) == ['ip_admin_eth0.ip_admin_eth0']
compare(cfg.value.mandatory(), ['ip_admin_eth0.ip_admin_eth0'])
#
cfg.property.read_write()
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['ip'])
assert list(cfg.value.mandatory()) == []
compare(cfg.value.mandatory(), [])
# assert not list_sessions()
@ -515,8 +527,7 @@ def test_mandatory_follower():
cfg = Config(od1)
cfg.property.read_only()
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
assert cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': [],
'ip_admin_eth0.netmask_admin_eth0': []}
assert cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': []}
#
cfg.property.read_write()
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['ip'])
@ -537,8 +548,7 @@ def test_mandatory_follower():
cfg.property.read_only()
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['ip']
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == 'ip'
assert cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': ['ip'],
'ip_admin_eth0.netmask_admin_eth0': ['ip']}
assert cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': [{'ip_admin_eth0.ip_admin_eth0': 'ip', 'ip_admin_eth0.netmask_admin_eth0': 'ip'}]}
# assert not list_sessions()
@ -553,9 +563,9 @@ def test_mandatory_warnings_follower():
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
#
cfg.property.read_write()
assert list(cfg.value.mandatory()) == []
compare(cfg.value.mandatory(), [])
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['ip'])
assert list(cfg.value.mandatory()) == ['ip_admin_eth0.netmask_admin_eth0']
compare(cfg.value.mandatory(), [['ip_admin_eth0.netmask_admin_eth0', 0]])
# assert not list_sessions()
@ -565,10 +575,10 @@ def test_mandatory_warnings_symlink():
cfg.option('str').value.set('')
cfg.property.read_write()
cfg.option('str').value.get()
assert list(cfg.value.mandatory()) == ['str', 'str1', 'str3']
compare(cfg.value.mandatory(), ['str', 'str1', 'str3'])
cfg.option('str').property.add('frozen')
cfg.property.read_only()
assert list(cfg.value.mandatory()) == ['str', 'str1', 'str3']
compare(cfg.value.mandatory(), ['str', 'str1', 'str3'])
# assert not list_sessions()
@ -577,7 +587,7 @@ def test_mandatory_warnings_validate_empty():
cfg = Config(od1)
cfg.option('str').value.set('')
cfg.property.read_only()
assert list(cfg.value.mandatory()) == ['str', 'str1', 'str3']
compare(cfg.value.mandatory(), ['str', 'str1', 'str3', 'unicode1'])
# assert not list_sessions()
@ -599,12 +609,12 @@ def test_mandatory_warnings_requires():
cfg.option('str').value.set('')
cfg.property.read_write()
cfg.option('str').value.get()
assert list(cfg.value.mandatory()) == ['str', 'str1', 'unicode2']
compare(cfg.value.mandatory(), ['str', 'str1', 'unicode2'])
cfg.property.read_only()
assert list(cfg.value.mandatory()) == ['str', 'str1', 'unicode2']
compare(cfg.value.mandatory(), ['str', 'str1', 'unicode2'])
cfg.property.read_write()
cfg.option('str').value.set('yes')
assert list(cfg.value.mandatory()) == ['str1', 'unicode2', 'str3']
compare(cfg.value.mandatory(), ['str1', 'unicode2', 'str3'])
# assert not list_sessions()
@ -624,9 +634,9 @@ def test_mandatory_warnings_requires_leadership():
cfg = Config(od1)
cfg.option('str').value.set('')
cfg.option('leader.str1').value.set(['str'])
assert list(cfg.value.mandatory()) == ['str']
compare(cfg.value.mandatory(), ['str'])
cfg.option('str').value.set('yes')
assert list(cfg.value.mandatory()) == ['leader.str2']
compare(cfg.value.mandatory(), [['leader.str2', 0]])
# assert not list_sessions()
@ -644,9 +654,21 @@ def test_mandatory_warnings_requires_leadership_follower():
od1 = OptionDescription('tiram', '', [leadership])
cfg = Config(od1)
cfg.option('leader.str').value.set(['str'])
assert list(cfg.value.mandatory()) == []
compare(cfg.value.mandatory(), [])
cfg.option('leader.str1', 0).value.set('yes')
assert list(cfg.value.mandatory()) == ['leader.str2']
compare(cfg.value.mandatory(), [['leader.str2', 0]])
cfg.option('leader.str2', 0).value.set('yes')
compare(cfg.value.mandatory(), [])
#
cfg.option('leader.str').value.set(['str', 'str1'])
compare(cfg.value.mandatory(), [])
cfg.option('leader.str1', 1).value.set('yes')
compare(cfg.value.mandatory(), [['leader.str2', 1]])
cfg.option('leader.str2', 1).value.set('yes')
compare(cfg.value.mandatory(), [])
cfg.option('leader.str2', 0).value.reset()
cfg.option('leader.str2', 1).value.reset()
compare(cfg.value.mandatory(), [['leader.str2', 0], ['leader.str2', 1]])
# assert not list_sessions()
@ -655,7 +677,49 @@ def test_mandatory_od_disabled():
od1 = OptionDescription('od', '', [descr])
cfg = Config(od1)
cfg.property.read_only()
assert list(cfg.value.mandatory()) == ['tiram.str1', 'tiram.unicode2', 'tiram.str3']
compare(cfg.value.mandatory(), ['tiram.str1', 'tiram.unicode2', 'tiram.str3'])
cfg.option('tiram').property.add('disabled')
assert list(cfg.value.mandatory()) == []
compare(cfg.value.mandatory(), [])
# assert not list_sessions()
def return_list(val=None, suffix=None):
if val:
return val
else:
return ['val1', 'val2']
def test_mandatory_dyndescription():
st = StrOption('st', '', properties=('mandatory',))
dod = DynOptionDescription('dod', '', [st], suffixes=Calculation(return_list))
od = OptionDescription('od', '', [dod])
od2 = OptionDescription('od', '', [od])
cfg = Config(od2)
cfg.property.read_only()
compare(cfg.value.mandatory(), ['od.dodval1.stval1', 'od.dodval2.stval2'])
def test_mandatory_dyndescription_context():
val1 = StrOption('val1', '', ['val1', 'val2'], multi=True)
st = StrOption('st', '', properties=('mandatory',))
dod = DynOptionDescription('dod', '', [st], suffixes=Calculation(return_list, Params(ParamOption(val1))))
od = OptionDescription('od', '', [dod, val1])
od2 = OptionDescription('od', '', [od])
cfg = Config(od2)
cfg.property.read_only()
compare(cfg.value.mandatory(), ['od.dodval1.stval1', 'od.dodval2.stval2'])
def test_mandatory_callback_leader_and_followers_leader():
val1 = StrOption('val1', "", multi=True, properties=('mandatory', 'empty'))
val2 = StrOption('val2', "", multi=True, default_multi='val2', properties=('expert',))
val3 = StrOption('val3', "", Calculation(calc_value, Params(ParamOption(val2), {'index': ParamIndex()})), multi=True)
val4 = StrOption('val4', "", Calculation(calc_value, Params(ParamOption(val3), {'index': ParamIndex()})), multi=True)
interface1 = Leadership('val1', '', [val1, val2, val3, val4])
od1 = OptionDescription('rootconfig', '', [interface1])
cfg = Config(od1)
cfg.property.read_write()
# FIXME cfg = get_config(cfg, config_type)
compare(cfg.value.mandatory(), ['val1.val1'])
# assert not list_sessions()

View file

@ -88,7 +88,7 @@ def test_none():
assert meta.option('od1.i3').value.get() is conf1.option('od1.i3').value.get() is conf2.option('od1.i3').value.get() is None
assert meta.option('od1.i3').owner.get() is conf1.option('od1.i3').owner.get() is conf2.option('od1.i3').owner.get() is owners.default
#
meta.option('od1.i3').value.set(3)
assert meta.option('od1.i3').value.set(3) == []
assert meta.option('od1.i3').value.get() == conf1.option('od1.i3').value.get() == conf2.option('od1.i3').value.get() == 3
assert meta.option('od1.i3').owner.get() is conf1.option('od1.i3').owner.get() is conf2.option('od1.i3').owner.get() is owners.meta1
#
@ -870,7 +870,7 @@ def test_meta_properties_requires_mandatory():
meta.option('ip_gw').value.set('1.1.1.2')
conf1.option('eth0_method').value.set('dhcp')
conf1.property.read_only()
assert conf1.value.dict(fullpath=True) == {'probes': True, 'eth0_method': 'dhcp', 'ip_address': '1.1.1.1', 'ip_eth0': '1.1.1.1', 'ip_gw': '1.1.1.2'}
assert conf1.value.dict() == {'ip_gw': '1.1.1.2', 'probes': True, 'eth0_method': 'dhcp', 'ip_address': '1.1.1.1', 'ip_eth0': '1.1.1.1'}
def test_meta_callback():
@ -909,51 +909,51 @@ def test_meta_callback_follower():
conf1 = Config(maconfig, name='conf1')
meta = MetaConfig([conf1])
meta.property.read_write()
assert conf1.value.dict() == {'val1.val2': ['val'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'}
assert conf1.value.dict() == {'val': 'val', 'val1.val1': [{'val1.val1': 'val', 'val1.val2': 'val', 'val1.val3': 'val'}]}
#
conf1.option('val').value.set('val1')
assert conf1.value.dict() == {'val1.val2': ['val1'], 'val1.val1': ['val1'], 'val1.val3': ['val1'], 'val': 'val1'}
assert conf1.value.dict() == {'val': 'val1', 'val1.val1': [{'val1.val1': 'val1', 'val1.val2': 'val1', 'val1.val3': 'val1'}]}
#
conf1.option('val').value.reset()
meta.option('val').value.set('val1')
assert conf1.value.dict() == {'val1.val2': ['val1'], 'val1.val1': ['val1'], 'val1.val3': ['val1'], 'val': 'val1'}
assert conf1.value.dict() == {'val': 'val1', 'val1.val1': [{'val1.val1': 'val1', 'val1.val2': 'val1', 'val1.val3': 'val1'}]}
#
meta.option('val').value.reset()
conf1.option('val1.val2', 0).value.set('val2')
assert conf1.value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'}
assert conf1.value.dict() == {'val': 'val', 'val1.val1': [{'val1.val1': 'val', 'val1.val2': 'val2', 'val1.val3': 'val'}]}
#
conf1.option('val1.val2', 0).value.reset()
assert conf1.value.dict() == {'val1.val2': ['val'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'}
assert conf1.value.dict() == {'val': 'val', 'val1.val1': [{'val1.val1': 'val', 'val1.val2': 'val', 'val1.val3': 'val'}]}
#
meta.option('val1.val2', 0).value.set('val2')
assert conf1.value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'}
assert conf1.value.dict() == {'val': 'val', 'val1.val1': [{'val1.val1': 'val', 'val1.val2': 'val2', 'val1.val3': 'val'}]}
#
meta.option('val1.val1').value.set(['val'])
assert conf1.value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'}
assert conf1.value.dict() == {'val': 'val', 'val1.val1': [{'val1.val1': 'val', 'val1.val2': 'val2', 'val1.val3': 'val'}]}
#
conf1.option('val1.val3', 0).value.set('val6')
assert conf1.value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val6'], 'val': 'val'}
assert conf1.value.dict() == {'val': 'val', 'val1.val1': [{'val1.val1': 'val', 'val1.val2': 'val2', 'val1.val3': 'val6'}]}
#
meta.option('val1.val2', 0).value.reset()
conf1.option('val1.val3', 0).value.reset()
conf1.option('val1.val1').value.set(['val3'])
assert conf1.value.dict() == {'val1.val2': ['val3'], 'val1.val1': ['val3'], 'val1.val3': ['val3'], 'val': 'val'}
assert conf1.value.dict() == {'val': 'val', 'val1.val1': [{'val1.val1': 'val3', 'val1.val2': 'val3', 'val1.val3': 'val3'}]}
#
conf1.option('val1.val1').value.reset()
assert conf1.value.dict() == {'val1.val2': ['val'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'}
assert conf1.value.dict() == {'val': 'val', 'val1.val1': [{'val1.val1': 'val', 'val1.val2': 'val', 'val1.val3': 'val'}]}
#
meta.option('val1.val1').value.set(['val3'])
assert conf1.value.dict() == {'val1.val2': ['val3'], 'val1.val1': ['val3'], 'val1.val3': ['val3'], 'val': 'val'}
assert conf1.value.dict() == {'val': 'val', 'val1.val1': [{'val1.val1': 'val3', 'val1.val2': 'val3', 'val1.val3': 'val3'}]}
#
conf1.option('val1.val2', 0).value.set('val2')
assert conf1.value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val3'], 'val1.val3': ['val3'], 'val': 'val'}
assert conf1.value.dict() == {'val': 'val', 'val1.val1': [{'val1.val1': 'val3', 'val1.val2': 'val2', 'val1.val3': 'val3'}]}
#
meta.option('val1.val1').value.set(['val3', 'rah'])
assert conf1.value.dict() == {'val1.val2': ['val2', 'rah'], 'val1.val1': ['val3', 'rah'], 'val1.val3': ['val3', 'rah'], 'val': 'val'}
assert conf1.value.dict() == {'val': 'val', 'val1.val1': [{'val1.val1': 'val3', 'val1.val2': 'val2', 'val1.val3': 'val3'}, {'val1.val1': 'rah', 'val1.val2': 'rah', 'val1.val3': 'rah'}]}
#
meta.option('val1.val1').value.pop(1)
meta.option('val1.val1').value.set(['val4'])
assert conf1.value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val4'], 'val1.val3': ['val4'], 'val': 'val'}
assert conf1.value.dict() == {'val': 'val', 'val1.val1': [{'val1.val1': 'val4', 'val1.val2': 'val2', 'val1.val3': 'val4'}]}
def test_meta_reset():

View file

@ -709,51 +709,51 @@ def test_mix_callback_follower():
mix = MixConfig(maconfig, [cfg])
mix.property.read_write()
newcfg1 = mix.config('cfg1')
assert newcfg1.value.dict() == {'val1.val2': ['val'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'}
assert newcfg1.value.dict() == {'val': 'val', 'val1.val1': [{'val1.val1': 'val', 'val1.val2': 'val', 'val1.val3': 'val'}]}
#
newcfg1.option('val').value.set('val1')
assert newcfg1.value.dict() == {'val1.val2': ['val1'], 'val1.val1': ['val1'], 'val1.val3': ['val1'], 'val': 'val1'}
assert newcfg1.value.dict() == {'val': 'val1', 'val1.val1': [{'val1.val1': 'val1', 'val1.val2': 'val1', 'val1.val3': 'val1'}]}
#
newcfg1.option('val').value.reset()
mix.option('val').value.set('val1')
assert newcfg1.value.dict() == {'val1.val2': ['val1'], 'val1.val1': ['val1'], 'val1.val3': ['val1'], 'val': 'val1'}
assert newcfg1.value.dict() == {'val': 'val1', 'val1.val1': [{'val1.val1': 'val1', 'val1.val2': 'val1', 'val1.val3': 'val1'}]}
#
mix.option('val').value.reset()
newcfg1.option('val1.val2', 0).value.set('val2')
assert newcfg1.value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'}
assert newcfg1.value.dict() == {'val': 'val', 'val1.val1': [{'val1.val1': 'val', 'val1.val2': 'val2', 'val1.val3': 'val'}]}
#
newcfg1.option('val1.val2', 0).value.reset()
assert newcfg1.value.dict() == {'val1.val2': ['val'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'}
assert newcfg1.value.dict() == {'val': 'val', 'val1.val1': [{'val1.val1': 'val', 'val1.val2': 'val', 'val1.val3': 'val'}]}
#
mix.option('val1.val2', 0).value.set('val2')
assert newcfg1.value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'}
assert newcfg1.value.dict() == {'val': 'val', 'val1.val1': [{'val1.val1': 'val', 'val1.val2': 'val2', 'val1.val3': 'val'}]}
#
mix.option('val1.val1').value.set(['val'])
assert newcfg1.value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'}
assert newcfg1.value.dict() == {'val': 'val', 'val1.val1': [{'val1.val1': 'val', 'val1.val2': 'val2', 'val1.val3': 'val'}]}
#
newcfg1.option('val1.val3', 0).value.set('val6')
assert newcfg1.value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val6'], 'val': 'val'}
assert newcfg1.value.dict() == {'val': 'val', 'val1.val1': [{'val1.val1': 'val', 'val1.val2': 'val2', 'val1.val3': 'val6'}]}
#
mix.option('val1.val2', 0).value.reset()
newcfg1.option('val1.val3', 0).value.reset()
newcfg1.option('val1.val1').value.set(['val3'])
assert newcfg1.value.dict() == {'val1.val2': ['val3'], 'val1.val1': ['val3'], 'val1.val3': ['val3'], 'val': 'val'}
assert newcfg1.value.dict() == {'val': 'val', 'val1.val1': [{'val1.val1': 'val3', 'val1.val2': 'val3', 'val1.val3': 'val3'}]}
#
newcfg1.option('val1.val1').value.reset()
assert newcfg1.value.dict() == {'val1.val2': ['val'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'}
assert newcfg1.value.dict() == {'val': 'val', 'val1.val1': [{'val1.val1': 'val', 'val1.val2': 'val', 'val1.val3': 'val'}]}
#
mix.option('val1.val1').value.set(['val3'])
assert newcfg1.value.dict() == {'val1.val2': ['val3'], 'val1.val1': ['val3'], 'val1.val3': ['val3'], 'val': 'val'}
assert newcfg1.value.dict() == {'val': 'val', 'val1.val1': [{'val1.val1': 'val3', 'val1.val2': 'val3', 'val1.val3': 'val3'}]}
#
newcfg1.option('val1.val2', 0).value.set('val2')
assert newcfg1.value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val3'], 'val1.val3': ['val3'], 'val': 'val'}
assert newcfg1.value.dict() == {'val': 'val', 'val1.val1': [{'val1.val1': 'val3', 'val1.val2': 'val2', 'val1.val3': 'val3'}]}
#
mix.option('val1.val1').value.set(['val3', 'rah'])
assert newcfg1.value.dict() == {'val1.val2': ['val2', 'rah'], 'val1.val1': ['val3', 'rah'], 'val1.val3': ['val3', 'rah'], 'val': 'val'}
assert newcfg1.value.dict() == {'val': 'val', 'val1.val1': [{'val1.val1': 'val3', 'val1.val2': 'val2', 'val1.val3': 'val3'}, {'val1.val1': 'rah', 'val1.val2': 'rah', 'val1.val3': 'rah'}]}
#
mix.option('val1.val1').value.pop(1)
mix.option('val1.val1').value.set(['val4'])
assert newcfg1.value.dict() == {'val1.val2': ['val2'], 'val1.val1': ['val4'], 'val1.val3': ['val4'], 'val': 'val'}
assert newcfg1.value.dict() == {'val': 'val', 'val1.val1': [{'val1.val1': 'val4', 'val1.val2': 'val2', 'val1.val3': 'val4'}]}
def test_meta_reset():

View file

@ -776,20 +776,6 @@ def test_callback_leader_and_followers_leader_mandatory4(config_type):
# assert not list_sessions()
def test_callback_leader_and_followers_leader3():
val1 = StrOption('val1', "", multi=True, properties=('mandatory', 'empty'))
val2 = StrOption('val2', "", multi=True, default_multi='val2', properties=('expert',))
val3 = StrOption('val3', "", Calculation(calc_value, Params(ParamOption(val2), {'index': ParamIndex()})), multi=True)
val4 = StrOption('val4', "", Calculation(calc_value, Params(ParamOption(val3), {'index': ParamIndex()})), multi=True)
interface1 = Leadership('val1', '', [val1, val2, val3, val4])
od1 = OptionDescription('rootconfig', '', [interface1])
cfg = Config(od1)
cfg.property.read_write()
# FIXME cfg = get_config(cfg, config_type)
assert list(cfg.value.mandatory()) == ['val1.val1']
# assert not list_sessions()
def test_callback_leader_and_followers_leader4():
val1 = StrOption('val1', "", ['val1'], multi=True, properties=('mandatory',))
val2 = StrOption('val2', "", multi=True, default_multi='val2', properties=('expert', 'mandatory'))
@ -996,7 +982,7 @@ def test_callback_leader_and_followers_leader_callback_disabled():
with pytest.raises(ConfigError):
cfg.option('val1.val1').value.get()
with pytest.raises(ConfigError):
cfg.option('val1.val2').value.get()
cfg.option('val1.val2', 0).value.get()
cfg.property.remove('disabled')
cfg.option('val1.val1').value.set([])
cfg.property.add('disabled')

View file

@ -219,7 +219,7 @@ def test_setowner_symlinkoption(config_type):
assert not cfg.option('tiramisu.symdummy').owner.isdefault()
if config_type == 'tiramisu-api':
cfg.send()
with pytest.raises(ConfigError):
with pytest.raises(APIError):
cfg_ori.option('tiramisu.symdummy').owner.set('user')
# assert not list_sessions()

View file

@ -709,7 +709,7 @@ def test_pprint():
kwargs={'condition': ParamOption(intoption, todict=True),
'expected': ParamValue(1)}),
calc_value_property_help)
descr2 = OptionDescription("options", "", [val2], properties=(hidden_property,))
descr2 = OptionDescription("options", "options", [val2], properties=(hidden_property,))
#descr2 = OptionDescription("options", "", [val2], requires=[{'option': intoption, 'expected': 1, 'action': 'hidden'}])
hidden_property = Calculation(calc_value,
@ -721,7 +721,7 @@ def test_pprint():
val3 = StrOption('val3', "", properties=(hidden_property,))
#val3 = StrOption('val3', "", requires=[{'option': stroption, 'expected': '2', 'action': 'hidden', 'inverse': True}])
od1 = OptionDescription("options", "", [s, s2, s3, intoption, stroption, descr2, val3])
od1 = OptionDescription("options", "root option", [s, s2, s3, intoption, stroption, descr2, val3])
cfg = Config(od1)
cfg.property.read_write()
cfg.option('int').value.set(1)

View file

@ -1106,41 +1106,21 @@ def test_leadership_requires(config_type):
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() is None
cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.set('255.255.255.255')
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == '255.255.255.255'
assert cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': ['192.168.1.2', '192.168.1.2'],
'ip_admin_eth0.netmask_admin_eth0': [None, '255.255.255.255']}
assert cfg.value.dict(leader_to_list=True) == {'ip_admin_eth0.ip_admin_eth0': [{'ip_admin_eth0.ip_admin_eth0': '192.168.1.2', 'ip_admin_eth0.netmask_admin_eth0': None},
{'ip_admin_eth0.ip_admin_eth0': '192.168.1.2', 'ip_admin_eth0.netmask_admin_eth0': '255.255.255.255'}]}
assert cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': [{'ip_admin_eth0.ip_admin_eth0': '192.168.1.2', 'ip_admin_eth0.netmask_admin_eth0': None},
{'ip_admin_eth0.ip_admin_eth0': '192.168.1.2', 'ip_admin_eth0.netmask_admin_eth0': '255.255.255.255'}]}
#
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2', '192.168.1.1'])
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
with pytest.raises(PropertiesOptionError):
cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get()
ret = cfg.value.dict()
assert set(ret.keys()) == set(['ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
assert ret['ip_admin_eth0.ip_admin_eth0'] == ['192.168.1.2', '192.168.1.1']
assert len(ret['ip_admin_eth0.netmask_admin_eth0']) == 2
assert ret['ip_admin_eth0.netmask_admin_eth0'][0] is None
assert isinstance(ret['ip_admin_eth0.netmask_admin_eth0'][1], PropertiesOptionError)
del ret['ip_admin_eth0.netmask_admin_eth0'][1]
del ret['ip_admin_eth0.netmask_admin_eth0'][0]
del ret['ip_admin_eth0.netmask_admin_eth0']
assert cfg.value.dict(leader_to_list=True) == {'ip_admin_eth0.ip_admin_eth0': [{'ip_admin_eth0.ip_admin_eth0': '192.168.1.2',
'ip_admin_eth0.netmask_admin_eth0': None},
{'ip_admin_eth0.ip_admin_eth0': '192.168.1.1'}]}
assert cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': [{'ip_admin_eth0.ip_admin_eth0': '192.168.1.2',
'ip_admin_eth0.netmask_admin_eth0': None},
{'ip_admin_eth0.ip_admin_eth0': '192.168.1.1'}]}
#
cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('255.255.255.255')
ret = cfg.value.dict()
assert set(ret.keys()) == set(['ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
assert ret['ip_admin_eth0.ip_admin_eth0'] == ['192.168.1.2', '192.168.1.1']
assert len(ret['ip_admin_eth0.netmask_admin_eth0']) == 2
assert ret['ip_admin_eth0.netmask_admin_eth0'][0] == '255.255.255.255'
assert isinstance(ret['ip_admin_eth0.netmask_admin_eth0'][1], PropertiesOptionError)
del ret['ip_admin_eth0.netmask_admin_eth0'][1]
del ret['ip_admin_eth0.netmask_admin_eth0'][0]
del ret['ip_admin_eth0.netmask_admin_eth0']
assert cfg.value.dict(leader_to_list=True) == {'ip_admin_eth0.ip_admin_eth0': [{'ip_admin_eth0.ip_admin_eth0': '192.168.1.2',
'ip_admin_eth0.netmask_admin_eth0': '255.255.255.255'},
{'ip_admin_eth0.ip_admin_eth0': '192.168.1.1'}]}
assert cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': [{'ip_admin_eth0.ip_admin_eth0': '192.168.1.2',
'ip_admin_eth0.netmask_admin_eth0': '255.255.255.255'},
{'ip_admin_eth0.ip_admin_eth0': '192.168.1.1'}]}
# assert not list_sessions()
@ -1258,7 +1238,7 @@ def test_leadership_requires_no_leader(config_type):
cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()
with pytest.raises(PropertiesOptionError):
cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get()
assert cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': ['192.168.1.2', '192.168.1.1'], 'activate': False}
assert cfg.value.dict() == {'activate': False, 'ip_admin_eth0.ip_admin_eth0': [{'ip_admin_eth0.ip_admin_eth0': '192.168.1.2'}, {'ip_admin_eth0.ip_admin_eth0': '192.168.1.1'}]}
# assert not list_sessions()
@ -1319,53 +1299,10 @@ def test_leadership_requires_complet(config_type):
cfg = get_config(cfg, config_type)
cfg.option('options.unicode.unicode').value.set(['test', 'trah'])
cfg.option('options.unicode.unicode2', 0).value.set('test')
dico = cfg.value.dict()
assert dico.keys() == set(['options.unicode.unicode', 'options.unicode.unicode1', 'options.unicode.unicode2', 'options.unicode.unicode3', 'options.unicode.unicode4', 'options.unicode.unicode6', 'options.unicode.unicode7', 'options.unicodetoto'])
assert dico['options.unicode.unicode'] == ['test', 'trah']
assert dico['options.unicode.unicode1'] == [None, None]
assert dico['options.unicode.unicode2'] == ['test', None]
assert dico['options.unicode.unicode3'][0] is None
assert isinstance(dico['options.unicode.unicode3'][1], PropertiesOptionError)
assert dico['options.unicode.unicode4'][0] is None
assert isinstance(dico['options.unicode.unicode4'][1], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode6'][0], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode6'][1], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode7'][0], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode7'][1], PropertiesOptionError)
assert dico['options.unicodetoto'] is None
del dico['options.unicode.unicode3'][1]
del dico['options.unicode.unicode3']
del dico['options.unicode.unicode4'][1]
del dico['options.unicode.unicode4']
del dico['options.unicode.unicode6'][1]
del dico['options.unicode.unicode6'][0]
del dico['options.unicode.unicode7'][1]
del dico['options.unicode.unicode7'][0]
assert cfg.value.dict() == {'options.unicode.unicode': [{'options.unicode.unicode': 'test', 'options.unicode.unicode1': None, 'options.unicode.unicode2': 'test', 'options.unicode.unicode3': None, 'options.unicode.unicode4': None}, {'options.unicode.unicode': 'trah', 'options.unicode.unicode1': None, 'options.unicode.unicode2': None}], 'options.unicodetoto': None}
#
cfg.option('options.unicodetoto').value.set('test')
dico = cfg.value.dict()
assert dico.keys() == set(['options.unicode.unicode', 'options.unicode.unicode1', 'options.unicode.unicode2', 'options.unicode.unicode3', 'options.unicode.unicode4', 'options.unicode.unicode5', 'options.unicode.unicode6', 'options.unicode.unicode7', 'options.unicodetoto'])
assert dico['options.unicode.unicode'] == ['test', 'trah']
assert dico['options.unicode.unicode1'] == [None, None]
assert dico['options.unicode.unicode2'] == ['test', None]
assert dico['options.unicode.unicode3'][0] is None
assert isinstance(dico['options.unicode.unicode3'][1], PropertiesOptionError)
assert dico['options.unicode.unicode4'][0] is None
assert isinstance(dico['options.unicode.unicode4'][1], PropertiesOptionError)
assert dico['options.unicode.unicode5'] == [None, None]
assert dico['options.unicode.unicode6'][0] is None
assert isinstance(dico['options.unicode.unicode6'][1], PropertiesOptionError)
assert dico['options.unicode.unicode7'][0] is None
assert isinstance(dico['options.unicode.unicode7'][1], PropertiesOptionError)
assert dico['options.unicodetoto'] == 'test'
del dico['options.unicode.unicode3'][1]
del dico['options.unicode.unicode3']
del dico['options.unicode.unicode4'][1]
del dico['options.unicode.unicode4']
del dico['options.unicode.unicode6'][1]
del dico['options.unicode.unicode6'][0]
del dico['options.unicode.unicode7'][1]
del dico['options.unicode.unicode7'][0]
assert cfg.value.dict() == {'options.unicode.unicode': [{'options.unicode.unicode': 'test', 'options.unicode.unicode1': None, 'options.unicode.unicode2': 'test', 'options.unicode.unicode3': None, 'options.unicode.unicode4': None, 'options.unicode.unicode5': None, 'options.unicode.unicode6': None, 'options.unicode.unicode7': None}, {'options.unicode.unicode': 'trah', 'options.unicode.unicode1': None, 'options.unicode.unicode2': None, 'options.unicode.unicode5': None}], 'options.unicodetoto': 'test'}
# assert not list_sessions()
@ -1402,91 +1339,24 @@ def test_leadership_requires_transitive1(config_type):
cfg = Config(od1)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.value.dict() == {'options.unicode.unicode': [], 'options.unicode.unicode1': [], 'options.unicode.unicode3': [], 'options.unicode.unicode4': [], 'options.unicodetoto': None}
assert cfg.value.dict() == {'options.unicode.unicode': [], 'options.unicodetoto': None}
#
cfg.option('options.unicodetoto').value.set('test')
assert cfg.value.dict() == {'options.unicode.unicode': [], 'options.unicode.unicode1': [], 'options.unicode.unicode2': [], 'options.unicode.unicode3': [], 'options.unicode.unicode4': [], 'options.unicodetoto': 'test'}
assert cfg.value.dict() == {'options.unicode.unicode': [], 'options.unicodetoto': 'test'}
#
cfg.option('options.unicode.unicode').value.set(['a', 'b', 'c'])
dico = cfg.value.dict()
assert list(dico.keys()) == ['options.unicode.unicode', 'options.unicode.unicode1', 'options.unicode.unicode2', 'options.unicode.unicode3', 'options.unicode.unicode4', 'options.unicodetoto']
assert dico['options.unicodetoto'] == 'test'
assert dico['options.unicode.unicode'] == ['a', 'b', 'c']
assert dico['options.unicode.unicode1'] == [None, None, None]
assert dico['options.unicode.unicode2'] == [None, None, None]
assert isinstance(dico['options.unicode.unicode3'][0], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode3'][1], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode3'][2], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode4'][0], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode4'][1], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode4'][2], PropertiesOptionError)
del (dico['options.unicode.unicode3'][2])
del (dico['options.unicode.unicode3'][1])
del (dico['options.unicode.unicode3'][0])
del (dico['options.unicode.unicode4'][2])
del (dico['options.unicode.unicode4'][1])
del (dico['options.unicode.unicode4'][0])
assert cfg.value.dict() == {'options.unicode.unicode': [{'options.unicode.unicode': 'a', 'options.unicode.unicode1': None, 'options.unicode.unicode2': None}, {'options.unicode.unicode': 'b', 'options.unicode.unicode1': None, 'options.unicode.unicode2': None}, {'options.unicode.unicode': 'c', 'options.unicode.unicode1': None, 'options.unicode.unicode2': None}], 'options.unicodetoto': 'test'}
cfg.option('options.unicode.unicode2', 1).value.set('test')
cfg.option('options.unicode.unicode3', 1).value.set('test')
dico = cfg.value.dict()
assert list(dico.keys()) == ['options.unicode.unicode', 'options.unicode.unicode1', 'options.unicode.unicode2', 'options.unicode.unicode3', 'options.unicode.unicode4', 'options.unicodetoto']
assert dico['options.unicodetoto'] == 'test'
assert dico['options.unicode.unicode'] == ['a', 'b', 'c']
assert dico['options.unicode.unicode1'] == [None, None, None]
assert dico['options.unicode.unicode2'] == [None, 'test', None]
assert isinstance(dico['options.unicode.unicode3'][0], PropertiesOptionError)
assert dico['options.unicode.unicode3'][1] == 'test'
assert isinstance(dico['options.unicode.unicode3'][2], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode4'][0], PropertiesOptionError)
assert dico['options.unicode.unicode4'][1] == None
assert isinstance(dico['options.unicode.unicode4'][2], PropertiesOptionError)
del (dico['options.unicode.unicode3'][2])
del (dico['options.unicode.unicode3'][1])
del (dico['options.unicode.unicode3'][0])
del (dico['options.unicode.unicode4'][2])
del (dico['options.unicode.unicode4'][1])
del (dico['options.unicode.unicode4'][0])
assert cfg.value.dict() == {'options.unicode.unicode': [{'options.unicode.unicode': 'a', 'options.unicode.unicode1': None, 'options.unicode.unicode2': None}, {'options.unicode.unicode': 'b', 'options.unicode.unicode1': None, 'options.unicode.unicode2': 'test', 'options.unicode.unicode3': 'test', 'options.unicode.unicode4': None}, {'options.unicode.unicode': 'c', 'options.unicode.unicode1': None, 'options.unicode.unicode2': None}], 'options.unicodetoto': 'test'}
#
cfg.option('options.unicode.unicode2', 1).value.set('rah')
dico = cfg.value.dict()
assert list(dico.keys()) == ['options.unicode.unicode', 'options.unicode.unicode1', 'options.unicode.unicode2', 'options.unicode.unicode3', 'options.unicode.unicode4', 'options.unicodetoto']
assert dico['options.unicodetoto'] == 'test'
assert dico['options.unicode.unicode'] == ['a', 'b', 'c']
assert dico['options.unicode.unicode1'] == [None, None, None]
assert dico['options.unicode.unicode2'] == [None, 'rah', None]
assert isinstance(dico['options.unicode.unicode3'][0], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode3'][1], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode3'][2], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode4'][0], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode4'][1], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode4'][2], PropertiesOptionError)
del (dico['options.unicode.unicode3'][2])
del (dico['options.unicode.unicode3'][1])
del (dico['options.unicode.unicode3'][0])
del (dico['options.unicode.unicode4'][2])
del (dico['options.unicode.unicode4'][1])
del (dico['options.unicode.unicode4'][0])
assert cfg.value.dict() == {'options.unicode.unicode': [{'options.unicode.unicode': 'a', 'options.unicode.unicode1': None, 'options.unicode.unicode2': None}, {'options.unicode.unicode': 'b', 'options.unicode.unicode1': None, 'options.unicode.unicode2': 'rah'}, {'options.unicode.unicode': 'c', 'options.unicode.unicode1': None, 'options.unicode.unicode2': None}], 'options.unicodetoto': 'test'}
#
cfg.option('options.unicode.unicode2', 1).value.set('test')
cfg.option('options.unicodetoto').value.set('rah')
dico = cfg.value.dict()
assert list(dico.keys()) == ['options.unicode.unicode', 'options.unicode.unicode1', 'options.unicode.unicode3', 'options.unicode.unicode4', 'options.unicodetoto']
assert dico['options.unicodetoto'] == 'rah'
assert dico['options.unicode.unicode'] == ['a', 'b', 'c']
assert dico['options.unicode.unicode1'] == [None, None, None]
assert isinstance(dico['options.unicode.unicode3'][0], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode3'][1], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode3'][2], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode4'][0], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode4'][1], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode4'][2], PropertiesOptionError)
del (dico['options.unicode.unicode3'][2])
del (dico['options.unicode.unicode3'][1])
del (dico['options.unicode.unicode3'][0])
del (dico['options.unicode.unicode4'][2])
del (dico['options.unicode.unicode4'][1])
del (dico['options.unicode.unicode4'][0])
assert cfg.value.dict() == {'options.unicode.unicode': [{'options.unicode.unicode': 'a', 'options.unicode.unicode1': None}, {'options.unicode.unicode': 'b', 'options.unicode.unicode1': None}, {'options.unicode.unicode': 'c', 'options.unicode.unicode1': None}], 'options.unicodetoto': 'rah'}
# assert not list_sessions()

View file

@ -11,7 +11,6 @@ try:
except:
tiramisu_version = 2
from tiramisu import Config
from tiramisu.config import SubConfig
from tiramisu.option import ChoiceOption, BoolOption, IntOption, FloatOption,\
StrOption, SymLinkOption, StrOption, IPOption, OptionDescription, \
PortOption, NetworkOption, NetmaskOption, DomainnameOption, EmailOption, \
@ -158,32 +157,11 @@ def test_slots_option_readonly():
# assert slots == set(OptionDescription.__slots__)
def test_slots_config():
od1 = OptionDescription('a', '', [])
od2 = OptionDescription('a', '', [od1])
cfg = Config(od2)
with pytest.raises(AttributeError):
cfg._config_bag.context.x = 1
with pytest.raises(AttributeError):
cfg._config_bag.context.cfgimpl_x = 1
option_bag = OptionBag()
option_bag.set_option(od2,
'a',
ConfigBag(cfg._config_bag.context, None, None))
sc = cfg._config_bag.context.get_subconfig(option_bag)
assert isinstance(sc, SubConfig)
with pytest.raises(AttributeError):
sc.x = 1
with pytest.raises(AttributeError):
sc.cfgimpl_x = 1
# assert not list_sessions()
def test_slots_setting():
od1 = OptionDescription('a', '', [])
od2 = OptionDescription('a', '', [od1])
cfg = Config(od2)
s = cfg._config_bag.context.cfgimpl_get_settings()
s = cfg._config_bag.context.get_settings()
s
with pytest.raises(AttributeError):
s.x = 1
@ -194,7 +172,7 @@ def test_slots_value():
od1 = OptionDescription('a', '', [])
od2 = OptionDescription('a', '', [od1])
cfg = Config(od2)
v = cfg._config_bag.context.cfgimpl_get_values()
v = cfg._config_bag.context.get_values()
v
with pytest.raises(AttributeError):
v.x = 1

View file

@ -43,7 +43,7 @@ def test_symlink_assign_option(config_type):
[linkopt, OptionDescription("s1", "", [boolopt])])
cfg = Config(od1)
cfg = get_config(cfg, config_type)
with pytest.raises(ConfigError):
with pytest.raises(APIError):
cfg.option('c').value.set(True)
# assert not list_sessions()
@ -55,7 +55,7 @@ def test_symlink_del_option(config_type):
[linkopt, OptionDescription("s1", "", [boolopt])])
cfg = Config(od1)
cfg = get_config(cfg, config_type)
with pytest.raises(ConfigError):
with pytest.raises(APIError):
cfg.option('c').value.reset()
# assert not list_sessions()
@ -191,7 +191,7 @@ def test_symlink_assign(config_type):
[linkopt, OptionDescription("s1", "", [boolopt])])
cfg = Config(od1)
cfg = get_config(cfg, config_type)
with pytest.raises(ConfigError):
with pytest.raises(APIError):
cfg.option('c').value.set(True)
# assert not list_sessions()
@ -246,9 +246,9 @@ def test_symlink_with_leader(config_type):
od1 = OptionDescription('root', '', [interface1, leader])
cfg = Config(od1)
cfg = get_config(cfg, config_type)
assert cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': [], 'ip_admin_eth0.netmask_admin_eth0': [], 'leader': []}
assert cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': [], 'leader': []}
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['val1', 'val2'])
assert cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': ['val1', 'val2'], 'ip_admin_eth0.netmask_admin_eth0': [None, None], 'leader': ['val1', 'val2']}
assert cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': [{'ip_admin_eth0.ip_admin_eth0': 'val1', 'ip_admin_eth0.netmask_admin_eth0': None}, {'ip_admin_eth0.ip_admin_eth0': 'val2', 'ip_admin_eth0.netmask_admin_eth0': None}], 'leader': ['val1', 'val2']}
cfg.option('ip_admin_eth0.ip_admin_eth0').value.pop(0)
with pytest.raises(APIError):
cfg.option('leader').value.pop(0)
@ -263,36 +263,36 @@ def test_symlink_with_follower(config_type):
od1 = OptionDescription('root', '', [interface1, follower])
cfg = Config(od1)
cfg = get_config(cfg, config_type)
assert cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': [], 'ip_admin_eth0.netmask_admin_eth0': [], 'follower': []}
assert cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': [], 'follower': []}
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['val1', 'val2'])
assert cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': ['val1', 'val2'], 'ip_admin_eth0.netmask_admin_eth0': [None, None], 'follower': [None, None]}
assert cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': [{'ip_admin_eth0.ip_admin_eth0': 'val1', 'ip_admin_eth0.netmask_admin_eth0': None}, {'ip_admin_eth0.ip_admin_eth0': 'val2', 'ip_admin_eth0.netmask_admin_eth0': None}], 'follower': [None, None]}
#
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == 'default'
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).owner.get() == 'default'
assert cfg.option('follower', 0).owner.get() == 'default'
assert cfg.option('follower', 1).owner.get() == 'default'
assert cfg.option('follower').owner.get() == ['default', 'default']
with pytest.raises(APIError):
assert cfg.option('follower', 0).owner.get() == 'default'
assert cfg.option('follower').owner.get() == 'default'
#
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == None
assert cfg.option('follower', 0).value.get() == None
assert cfg.option('follower', 1).value.get() == None
with pytest.raises(APIError):
assert cfg.option('follower', 0).value.get() == None
assert cfg.option('follower').value.get() == [None, None]
#
cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.set('val3')
assert cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': ['val1', 'val2'], 'ip_admin_eth0.netmask_admin_eth0': [None, 'val3'], 'follower': [None, 'val3']}
assert cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': [{'ip_admin_eth0.ip_admin_eth0': 'val1', 'ip_admin_eth0.netmask_admin_eth0': None}, {'ip_admin_eth0.ip_admin_eth0': 'val2', 'ip_admin_eth0.netmask_admin_eth0': 'val3'}], 'follower': [None, 'val3']}
#
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == 'val3'
assert cfg.option('follower', 0).value.get() == None
assert cfg.option('follower', 1).value.get() == 'val3'
with pytest.raises(APIError):
assert cfg.option('follower', 0).value.get() == None
assert cfg.option('follower').value.get() == [None, 'val3']
#
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == 'default'
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).owner.get() == 'user'
assert cfg.option('follower', 0).owner.get() == 'default'
assert cfg.option('follower', 1).owner.get() == 'user'
assert cfg.option('follower').owner.get() == ['default', 'user']
with pytest.raises(APIError):
assert cfg.option('follower', 0).owner.get() == 'default'
assert cfg.option('follower').owner.get() == 'user'
# assert not list_sessions()

File diff suppressed because it is too large Load diff

View file

@ -176,35 +176,35 @@ class Calculation:
for_settings: bool=False,
) -> Any:
return carry_out_calculation(option_bag.option,
callback=self.function,
callback_params=self.params,
index=option_bag.index,
config_bag=option_bag.config_bag,
leadership_must_have_index=leadership_must_have_index,
orig_value=orig_value,
allow_value_error=allow_value_error,
force_value_warning=force_value_warning,
for_settings=for_settings,
)
callback=self.function,
callback_params=self.params,
index=option_bag.index,
config_bag=option_bag.config_bag,
leadership_must_have_index=leadership_must_have_index,
orig_value=orig_value,
allow_value_error=allow_value_error,
force_value_warning=force_value_warning,
for_settings=for_settings,
)
def help(self,
option_bag: OptionBag,
leadership_must_have_index: bool=False,
for_settings: bool=False,
) -> str:
option_bag: OptionBag,
leadership_must_have_index: bool=False,
for_settings: bool=False,
) -> str:
if not self.help_function:
return self.execute(option_bag,
leadership_must_have_index=leadership_must_have_index,
for_settings=for_settings,
)
leadership_must_have_index=leadership_must_have_index,
for_settings=for_settings,
)
return carry_out_calculation(option_bag.option,
callback=self.help_function,
callback_params=self.params,
index=option_bag.index,
config_bag=option_bag.config_bag,
leadership_must_have_index=leadership_must_have_index,
for_settings=for_settings,
)
callback=self.help_function,
callback_params=self.params,
index=option_bag.index,
config_bag=option_bag.config_bag,
leadership_must_have_index=leadership_must_have_index,
for_settings=for_settings,
)
def has_index(self, current_option):
if hasattr(self, '_has_index'):
@ -223,13 +223,13 @@ class Break(Exception):
def manager_callback(callbk: Param,
option,
index: Optional[int],
orig_value,
config_bag: ConfigBag,
leadership_must_have_index: bool,
for_settings: bool,
) -> Any:
option,
index: Optional[int],
orig_value,
config_bag: ConfigBag,
leadership_must_have_index: bool,
for_settings: bool,
) -> Any:
"""replace Param by true value"""
def calc_index(callbk, index, same_leadership):
if index is not None:
@ -243,7 +243,12 @@ def manager_callback(callbk: Param,
return index
return None
def calc_self(callbk, option, index, value, config_bag):
def calc_self(callbk,
option,
index,
value,
config_bag,
):
# index must be apply only if follower
is_follower = option.impl_is_follower()
apply_index = calc_index(callbk, index, is_follower)
@ -251,11 +256,40 @@ def manager_callback(callbk: Param,
if config_bag is undefined:
return undefined
path = option.impl_getpath()
option_bag = get_option_bag(config_bag,
option,
apply_index,
True)
new_value = get_value(callbk, option_bag, path)
option_bag = OptionBag(option,
None,
config_bag,
properties=None,
)
properties = config_bag.context.get_settings().getproperties(option_bag,
uncalculated=True,
)
parent_option_bag, option_bag = get_option_bag(config_bag,
option,
callbk,
apply_index,
True,
properties=properties,
)
if option.impl_is_follower() and apply_index is None:
new_value = []
for idx in range(config_bag.context.get_length_leadership(parent_option_bag)):
parent_option_bag, option_bag = get_option_bag(config_bag,
option,
callbk,
idx,
True,
properties=properties,
)
new_value.append(get_value(callbk,
option_bag,
path,
))
else:
new_value = get_value(callbk,
option_bag,
path,
)
if apply_index is None and is_follower:
new_value[index] = value
value = new_value
@ -264,13 +298,12 @@ def manager_callback(callbk: Param,
return value
def get_value(callbk,
option_bag,
path,
):
option_bag,
path,
):
try:
# get value
value = config_bag.context.getattr(path,
option_bag)
value = config_bag.context.get_value(option_bag)
except PropertiesOptionError as err:
# raise PropertiesOptionError (which is catched) because must not add value None in carry_out_calculation
if callbk.notraisepropertyerror or callbk.raisepropertyerror:
@ -284,15 +317,18 @@ def manager_callback(callbk: Param,
# cannot acces, simulate a propertyerror
raise PropertiesOptionError(option_bag,
['configerror'],
config_bag.context.cfgimpl_get_settings(),
config_bag.context.get_settings(),
)
raise ConfigError(_(f'unable to get value for calculating "{option_bag.option.impl_get_display_name()}", {err}')) from err
return value
def get_option_bag(config_bag,
opt,
index_,
self_calc):
opt,
callbk,
index_,
self_calc,
properties=undefined,
):
# don't validate if option is option that we tried to validate
config_bag = config_bag.copy()
if for_settings:
@ -300,38 +336,62 @@ def manager_callback(callbk: Param,
config_bag.set_permissive()
if not for_settings:
config_bag.properties -= {'warnings'}
option_bag = OptionBag()
option_bag.set_option(opt,
index_,
config_bag)
if not self_calc:
option_bag.properties = config_bag.context.cfgimpl_get_settings().getproperties(option_bag)
if self_calc:
config_bag.unrestraint()
config_bag.remove_validation()
root_option_bag = OptionBag(config_bag.context.get_description(),
None,
config_bag,
)
try:
options_bag = config_bag.context.get_sub_option_bag(root_option_bag,
opt.impl_getpath(),
index_,
validate_properties=not self_calc,
properties=properties,
)
except PropertiesOptionError as err:
# raise PropertiesOptionError (which is catched) because must not add value None in carry_out_calculation
if callbk.notraisepropertyerror or callbk.raisepropertyerror:
raise err from err
raise ConfigError(_('unable to carry out a calculation for "{}"'
', {}').format(option.impl_get_display_name(), err), err) from err
except ValueError as err:
raise ValueError(_('the option "{0}" is used in a calculation but is invalid ({1})').format(option.impl_get_display_name(), err)) from err
except AttributeError as err:
if isinstance(callbk, ParamDynOption) and callbk.optional:
# cannot acces, simulate a propertyerror
raise PropertiesOptionError(options_bag[-1],
['configerror'],
config_bag.context.get_settings(),
)
raise ConfigError(_(f'unable to get value for calculating "{option.impl_get_display_name()}", {err}')) from err
if self_calc:
if len(options_bag) > 1:
parent_option_bag = options_bag[-2]
else:
parent_option_bag = None
return parent_option_bag, options_bag[-1]
else:
option_bag.config_bag.unrestraint()
option_bag.config_bag.remove_validation()
# if we are in properties calculation, cannot calculated properties
option_bag.properties = config_bag.context.cfgimpl_get_settings().getproperties(option_bag,
apply_requires=False)
return option_bag
return options_bag[-1]
if isinstance(callbk, ParamValue):
return callbk.value
if isinstance(callbk, ParamInformation):
if isinstance(callbk, ParamSelfInformation):
option_bag = OptionBag()
option_bag.set_option(option,
index,
config_bag,
)
option_bag = OptionBag(option,
index,
config_bag,
)
else:
option_bag = None
try:
return config_bag.context.impl_get_information(config_bag,
option_bag,
callbk.information_name,
callbk.default_value,
)
option_bag,
callbk.information_name,
callbk.default_value,
)
except ValueError as err:
raise ConfigError(_('option "{}" cannot be calculated: {}').format(option.impl_get_display_name(),
str(err),
@ -348,11 +408,17 @@ def manager_callback(callbk: Param,
if isinstance(callbk, ParamSelfOption):
if leadership_must_have_index and option.impl_is_follower() and index is None:
raise Break()
value = calc_self(callbk, option, index, orig_value, config_bag)
value = calc_self(callbk,
option,
index,
orig_value,
config_bag,
)
if not callbk.todict:
return value
return {'name': option.impl_get_display_name(),
'value': value}
'value': value,
}
if isinstance(callbk, ParamOption):
callbk_option = callbk.option
@ -365,7 +431,8 @@ def manager_callback(callbk: Param,
suffix = callbk.suffix
callbk_option = callbk_option.to_dynoption(rootpath,
suffix,
subdyn)
subdyn,
)
found = True
elif option.impl_is_dynsymlinkoption():
rootpath = option.rootpath
@ -418,13 +485,15 @@ def manager_callback(callbk: Param,
with_index = False
path = callbk_option.impl_getpath()
option_bag = get_option_bag(config_bag,
callbk_option,
index_,
False)
callbk_option,
callbk,
index_,
False,
)
value = get_value(callbk,
option_bag,
path,
)
option_bag,
path,
)
if with_index:
value = value[index]
if values is not None:
@ -440,16 +509,16 @@ def manager_callback(callbk: Param,
def carry_out_calculation(option,
callback: Callable,
callback_params: Optional[Params],
index: Optional[int],
config_bag: Optional[ConfigBag],
orig_value=undefined,
leadership_must_have_index: bool=False,
allow_value_error: bool=False,
force_value_warning: bool=False,
for_settings: bool=False,
):
callback: Callable,
callback_params: Optional[Params],
index: Optional[int],
config_bag: Optional[ConfigBag],
orig_value=undefined,
leadership_must_have_index: bool=False,
allow_value_error: bool=False,
force_value_warning: bool=False,
for_settings: bool=False,
):
"""a function that carries out a calculation for an option's value
:param option: the option
@ -474,13 +543,13 @@ def carry_out_calculation(option,
for key, callbk in chain(fake_items(callback_params.args), callback_params.kwargs.items()):
try:
value = manager_callback(callbk,
option,
index,
orig_value,
config_bag,
leadership_must_have_index,
for_settings,
)
option,
index,
orig_value,
config_bag,
leadership_must_have_index,
for_settings,
)
if value is undefined:
return undefined
if key is None:
@ -498,11 +567,12 @@ def carry_out_calculation(option,
except Break:
continue
ret = calculate(option,
callback,
allow_value_error,
force_value_warning,
args,
kwargs)
callback,
allow_value_error,
force_value_warning,
args,
kwargs,
)
if isinstance(ret, list) and not option.impl_is_dynoptiondescription() and \
option.impl_is_follower() and not option.impl_is_submulti():
if args or kwargs:
@ -524,12 +594,12 @@ def carry_out_calculation(option,
def calculate(option,
callback: Callable,
allow_value_error: bool,
force_value_warning: bool,
args,
kwargs,
):
callback: Callable,
allow_value_error: bool,
force_value_warning: bool,
args,
kwargs,
):
"""wrapper that launches the 'callback'
:param callback: callback function

View file

@ -52,7 +52,8 @@ class Cache:
index,
props,
self_props,
type_):
type_,
):
no_cache = False, None, False
if 'cache' in props or type_ == 'context_props':
values = self._cache.get(path)

File diff suppressed because it is too large Load diff

View file

@ -128,7 +128,7 @@ class PropertiesOptionError(AttributeError):
# Exceptions for a Config
class ConfigError(Exception):
"""attempt to change an option's owner without a value
or in case of `_cfgimpl_descr` is None
or in case of `_descr` is None
or if a calculation cannot be carried out"""
def __init__(self,
exp,

View file

@ -157,8 +157,9 @@ class Base:
return getattr(self, '_properties', frozenset())
def _setsubdyn(self,
subdyn) -> None:
self._subdyn = weakref.ref(subdyn)
subdyn,
) -> None:
self._subdyn = subdyn
def issubdyn(self) -> bool:
return getattr(self, '_subdyn', None) is not None
@ -295,7 +296,7 @@ class BaseOption(Base):
config_bag: 'OptionBag',
resetted_opts: List[Base]) -> None:
context = config_bag.context
context._impl_properties_cache.delcache(path)
context.properties_cache.delcache(path)
context._impl_permissives_cache.delcache(path)
if not self.impl_is_optiondescription():
context._impl_values_cache.delcache(path)

View file

@ -19,6 +19,7 @@
# the whole pypy projet is under MIT licence
# ____________________________________________________________
import re
import weakref
from typing import List, Callable, Any
from itertools import chain
from ..autolib import ParamOption
@ -43,24 +44,18 @@ class DynOptionDescription(OptionDescription):
doc: str,
children: List[BaseOption],
suffixes: Calculation,
properties=None) -> None:
properties=None,
) -> None:
super().__init__(name,
doc,
children,
properties)
properties,
)
# check children + set relation to this dynoptiondescription
wself = weakref.ref(self)
for child in children:
if isinstance(child, OptionDescription):
if __debug__ and child.impl_get_group_type() != groups.leadership:
raise ConfigError(_('cannot set optiondescription in a '
'dynoptiondescription'))
for chld in child._children[1]:
chld._setsubdyn(self)
if __debug__ and child.impl_is_symlinkoption():
raise ConfigError(_('cannot set symlinkoption in a '
'dynoptiondescription'))
child._setsubdyn(self)
child._setsubdyn(wself)
# add suffixes
if __debug__ and not isinstance(suffixes, Calculation):
raise ConfigError(_('suffixes in dynoptiondescription has to be a calculation'))
@ -84,10 +79,11 @@ class DynOptionDescription(OptionDescription):
def get_suffixes(self,
config_bag: ConfigBag) -> List[str]:
option_bag = OptionBag()
option_bag.set_option(self,
None,
config_bag)
option_bag = OptionBag(self,
None,
config_bag,
properties=None,
)
values = self._suffixes.execute(option_bag)
if values is None:
values = []

View file

@ -96,6 +96,13 @@ class Leadership(OptionDescription):
if prop not in ALLOWED_LEADER_PROPERTIES and not isinstance(prop, Calculation):
raise LeadershipError(_('leader cannot have "{}" property').format(prop))
def _setsubdyn(self,
subdyn,
) -> None:
for chld in self._children[1]:
chld._setsubdyn(subdyn)
self._subdyn = subdyn
def is_leader(self,
opt: Option) -> bool:
leader = self.get_leader()
@ -120,11 +127,10 @@ class Leadership(OptionDescription):
config_bag = option_bag.config_bag.copy()
config_bag.remove_validation()
for follower in self.get_followers():
soption_bag = OptionBag()
soption_bag.set_option(follower,
None,
config_bag)
soption_bag.properties = config_bag.context.cfgimpl_get_settings().getproperties(soption_bag)
soption_bag = OptionBag(follower,
None,
config_bag,
)
values.reset(soption_bag)
def follower_force_store_value(self,
@ -134,37 +140,37 @@ class Leadership(OptionDescription):
owner,
dyn=None,
) -> None:
settings = option_bag.config_bag.context.cfgimpl_get_settings()
settings = option_bag.config_bag.context.get_settings()
if value:
if dyn is None:
dyn = self
for idx, follower in enumerate(dyn.get_children(option_bag.config_bag)):
foption_bag = OptionBag()
foption_bag.set_option(follower,
None,
option_bag.config_bag)
if 'force_store_value' in settings.getproperties(foption_bag):
foption_bag = OptionBag(follower,
None,
option_bag.config_bag,
)
if 'force_store_value' in foption_bag.properties:
if idx == 0:
indexes = [None]
else:
indexes = range(len(value))
for index in indexes:
foption_bag = OptionBag()
foption_bag.set_option(follower,
index,
option_bag.config_bag)
foption_bag.properties = settings.getproperties(foption_bag)
values.set_storage_value(foption_bag.path,
foption_bag_index = OptionBag(follower,
index,
option_bag.config_bag,
)
values.set_storage_value(foption_bag_index.path,
index,
values.getvalue(foption_bag),
values.getvalue(foption_bag_index),
owner,
)
def pop(self,
values: Values,
index: int,
option_bag: OptionBag,
followers: Optional[List[Option]]=undefined) -> None:
values: Values,
index: int,
option_bag: OptionBag,
followers: Optional[List[Option]]=undefined,
) -> None:
if followers is undefined:
# followers are not undefined only in SynDynLeadership
followers = self.get_followers()
@ -173,14 +179,14 @@ class Leadership(OptionDescription):
for follower in followers:
follower_path = follower.impl_getpath()
followerlen = values.get_max_length(follower_path)
soption_bag = OptionBag()
soption_bag.set_option(follower,
index,
config_bag)
# do not check force_default_on_freeze or force_metaconfig_on_freeze
soption_bag.properties = set()
soption_bag = OptionBag(follower,
index,
config_bag,
properties=set(), # do not check force_default_on_freeze or force_metaconfig_on_freeze
)
is_default = values.is_default_owner(soption_bag,
validate_meta=False)
validate_meta=False,
)
if not is_default and followerlen > index:
values.resetvalue_index(follower_path,
index,
@ -197,19 +203,22 @@ class Leadership(OptionDescription):
def reset_cache(self,
path: str,
config_bag: 'ConfigBag',
resetted_opts: List[Option]) -> None:
resetted_opts: List[Option],
) -> None:
self._reset_cache(path,
self.get_leader(),
self.get_followers(),
config_bag,
resetted_opts)
resetted_opts,
)
def _reset_cache(self,
path: str,
leader: Option,
followers: List[Option],
config_bag: 'ConfigBag',
resetted_opts: List[Option]) -> None:
resetted_opts: List[Option],
) -> None:
super().reset_cache(path,
config_bag,
resetted_opts)

View file

@ -121,10 +121,11 @@ class Option(BaseOption):
def test_multi_value(value):
if isinstance(value, Calculation):
return
option_bag = OptionBag()
option_bag.set_option(self,
None,
undefined)
option_bag = OptionBag(self,
None,
undefined,
properties=None,
)
try:
self.validate(value)
self.sync_validate_with_option(value,
@ -152,10 +153,11 @@ class Option(BaseOption):
else:
test_multi_value(default_multi)
_setattr(self, '_default_multi', default_multi)
option_bag = OptionBag()
option_bag.set_option(self,
None,
undefined)
option_bag = OptionBag(self,
None,
undefined,
properties=None,
)
self.sync_impl_validate(default,
option_bag)
self.sync_impl_validate(default,
@ -484,8 +486,8 @@ class Option(BaseOption):
pass
def validate_with_option(self,
value: Any,
option_bag: OptionBag) -> None:
value: Any,
option_bag: OptionBag) -> None:
pass
def second_level_validation(self,
@ -514,10 +516,10 @@ class Option(BaseOption):
def to_dynoption(self,
rootpath: str,
suffix: str,
ori_dyn,
dyn_parent,
) -> SynDynOption:
return SynDynOption(self,
rootpath,
suffix,
ori_dyn,
dyn_parent,
)

View file

@ -38,15 +38,15 @@ class CacheOptionDescription(BaseOption):
return self.impl_is_readonly()
def _build_cache(self,
path='',
_consistencies=None,
_consistencies_id=0,
currpath: List[str]=None,
cache_option=None,
force_store_values=None,
dependencies_information=None,
display_name=None,
) -> None:
path='',
_consistencies=None,
_consistencies_id=0,
currpath: List[str]=None,
cache_option=None,
force_store_values=None,
dependencies_information=None,
display_name=None,
) -> None:
"""validate options and set option has readonly option
"""
# _consistencies is None only when we start to build cache
@ -66,20 +66,21 @@ class CacheOptionDescription(BaseOption):
raise ConfigError(_('option description seems to be part of an other '
'config'))
for option in self.get_children(config_bag=undefined,
dyn=False):
dyn=False):
if __debug__:
cache_option.append(option)
sub_currpath = currpath + [option.impl_getname()]
subpath = '.'.join(sub_currpath)
if isinstance(option, OptionDescription):
option._build_cache(subpath,
_consistencies,
_consistencies_id,
sub_currpath,
cache_option,
force_store_values,
dependencies_information,
display_name)
_consistencies,
_consistencies_id,
sub_currpath,
cache_option,
force_store_values,
dependencies_information,
display_name,
)
else:
for information in option.get_dependencies_information():
dependencies_information.setdefault(information, []).append(option)
@ -124,21 +125,22 @@ class CacheOptionDescription(BaseOption):
suffix,
dynopt,
)
doption_bag = OptionBag()
doption_bag.set_option(doption,
None,
config_bag,
)
doption_bag = OptionBag(doption,
None,
config_bag,
properties=None,
)
yield doption_bag
else:
option_bag = OptionBag()
option_bag.set_option(option,
None,
config_bag)
option_bag = OptionBag(option,
None,
config_bag,
properties=None,
)
yield option_bag
if 'force_store_value' not in config_bag.properties:
return
values = config_bag.context.cfgimpl_get_values()
values = config_bag.context.get_values()
for option in self._cache_force_store_values:
if option.impl_is_follower():
leader = option.impl_get_leadership().get_leader()
@ -149,7 +151,7 @@ class CacheOptionDescription(BaseOption):
subpath = leader_option_bag.option.rootpath
doption = option.to_dynoption(subpath,
leader_option_bag.option.impl_getsuffix(),
leader_option_bag.option.ori_dyn,
leader_option_bag.option.dyn_parent,
)
else:
doption = option
@ -157,12 +159,11 @@ class CacheOptionDescription(BaseOption):
for index in range(follower_len):
if values.hasvalue(subpath, index):
continue
option_bag = OptionBag()
option_bag.set_option(doption,
index,
config_bag,
)
option_bag.properties = frozenset()
option_bag = OptionBag(doption,
index,
config_bag,
properties=frozenset(),
)
value = values.getvalue(option_bag)
if value is None:
continue
@ -190,10 +191,10 @@ class OptionDescriptionWalk(CacheOptionDescription):
__slots__ = ('_children',)
def get_child(self,
name: str,
config_bag: ConfigBag,
subpath: str,
) -> Union[BaseOption, SynDynOptionDescription]:
name: str,
config_bag: ConfigBag,
subpath: str,
) -> Union[BaseOption, SynDynOptionDescription]:
# if not dyn
if name in self._children[0]:
option = self._children[1][self._children[0].index(name)]
@ -204,29 +205,32 @@ class OptionDescriptionWalk(CacheOptionDescription):
return option
# if dyn
for child in self._children[1]:
if child.impl_is_dynoptiondescription():
cname = child.impl_getname()
if name.startswith(cname):
for suffix in child.get_suffixes(config_bag):
if name == cname + child.convert_suffix_to_path(suffix):
return child.to_dynoption(subpath,
suffix,
child)
if not child.impl_is_dynoptiondescription():
continue
cname = child.impl_getname()
if not name.startswith(cname):
continue
for suffix in child.get_suffixes(config_bag):
if name != cname + child.convert_suffix_to_path(suffix):
continue
return child.to_dynoption(subpath,
suffix,
child,
)
if self.impl_get_group_type() == groups.root:
raise AttributeError(_(f'unknown option "{name}" '
'in root optiondescription'
))
else:
raise AttributeError(_(f'unknown option "{name}" '
f'in optiondescription "{self.impl_get_display_name()}"'
))
raise AttributeError(_(f'unknown option "{name}" '
f'in optiondescription "{self.impl_get_display_name()}"'
))
def get_children(self,
config_bag: Union[ConfigBag, Undefined],
dyn: bool=True,
) -> Union[BaseOption, SynDynOptionDescription]:
config_bag: Union[ConfigBag, Undefined],
dyn: bool=True,
) -> Union[BaseOption, SynDynOptionDescription]:
if not dyn or config_bag is undefined or \
config_bag.context.cfgimpl_get_description() == self:
config_bag.context.get_description() == self:
subpath = ''
else:
subpath = self.impl_getpath()
@ -242,17 +246,19 @@ class OptionDescriptionWalk(CacheOptionDescription):
return children
def get_children_recursively(self,
bytype: Optional[BaseOption],
byname: Optional[str],
config_bag: ConfigBag,
self_opt: BaseOption=None) -> Iterator[Union[BaseOption, SynDynOptionDescription]]:
bytype: Optional[BaseOption],
byname: Optional[str],
config_bag: ConfigBag,
self_opt: BaseOption=None,
) -> Iterator[Union[BaseOption, SynDynOptionDescription]]:
if self_opt is None:
self_opt = self
for option in self_opt.get_children(config_bag):
if option.impl_is_optiondescription():
for subopt in option.get_children_recursively(bytype,
byname,
config_bag):
byname,
config_bag,
):
yield subopt
elif (byname is None or option.impl_getname() == byname) and \
(bytype is None or isinstance(option, bytype)):
@ -309,6 +315,12 @@ class OptionDescription(OptionDescriptionWalk):
# the group_type is useful for filtering OptionDescriptions in a config
self._group_type = groups.default
def _setsubdyn(self,
subdyn,
) -> None:
raise ConfigError(_('cannot set optiondescription in a '
'dynoptiondescription'))
def impl_is_optiondescription(self) -> bool:
return True
@ -330,7 +342,7 @@ class OptionDescription(OptionDescriptionWalk):
if self._group_type != groups.default:
raise ValueError(_('cannot change group_type if already set '
'(old {0}, new {1})').format(self._group_type,
group_type))
group_type))
if not isinstance(group_type, groups.GroupType):
raise ValueError(_('group_type: {0}'
' not allowed').format(group_type))

View file

@ -20,6 +20,7 @@
# ____________________________________________________________
from typing import Any
from .baseoption import BaseOption, valid_name
from ..error import ConfigError
from ..i18n import _
@ -47,6 +48,12 @@ class SymLinkOption(BaseOption):
) -> Any:
return getattr(self._opt, name)
def _setsubdyn(self,
subdyn,
) -> None:
raise ConfigError(_('cannot set symlinkoption in a '
'dynoptiondescription'))
def impl_has_dependency(self,
self_is_dep: bool=True) -> bool:
"""If self_is_dep is True, it has dependency (self._opt), so return True

View file

@ -29,23 +29,25 @@ class SynDynOption:
__slots__ = ('rootpath',
'opt',
'suffix',
'ori_dyn',
'dyn_parent',
'__weakref__')
def __init__(self,
opt: BaseOption,
rootpath: str,
suffix: str,
ori_dyn) -> None:
dyn_parent,
) -> None:
self.opt = opt
self.rootpath = rootpath
self.suffix = suffix
self.ori_dyn = ori_dyn
self.dyn_parent = dyn_parent
def __getattr__(self,
name: str) -> Any:
return getattr(self.opt,
name)
name,
)
def __eq__(self,
left: BaseOption) -> bool:
@ -56,18 +58,21 @@ class SynDynOption:
self.suffix == left.suffix
def impl_getname(self) -> str:
return self.opt.impl_getname() + self.ori_dyn.convert_suffix_to_path(self.suffix)
return self.opt.impl_getname() + self.dyn_parent.convert_suffix_to_path(self.suffix)
def impl_get_display_name(self) -> str:
return self.opt._get_display_name(dyn_name=self.impl_getname(),
suffix=self.ori_dyn.convert_suffix_to_path(self.suffix),
suffix=self.dyn_parent.convert_suffix_to_path(self.suffix),
)
def impl_getsuffix(self) -> str:
return self.suffix
def impl_getpath(self) -> str:
return self.rootpath + '.' + self.impl_getname()
path = self.impl_getname()
if self.rootpath:
path = f'{self.rootpath}.{path}'
return path
def impl_is_dynsymlinkoption(self) -> bool:
return True
@ -78,5 +83,5 @@ class SynDynOption:
rootpath = self.rootpath.rsplit('.', 1)[0]
return leadership.to_dynoption(rootpath,
self.suffix,
self.ori_dyn,
self.dyn_parent,
)

View file

@ -40,9 +40,6 @@ class SynDynOptionDescription:
suffix: str,
ori_dyn) -> None:
self.opt = opt
if rootpath is None:
rootpath = ''
assert isinstance(rootpath, str), 'rootpath must be a string, not {}'.format(type(rootpath))
self.rootpath = rootpath
self._suffix = suffix
# For a Leadership inside a DynOptionDescription
@ -60,9 +57,10 @@ class SynDynOptionDescription:
return self.opt
def get_child(self,
name: str,
config_bag: ConfigBag,
subpath: str) -> BaseOption:
name: str,
config_bag: ConfigBag,
subpath: str,
) -> BaseOption:
suffix = self.ori_dyn.convert_suffix_to_path(self._suffix)
if name.endswith(suffix):
oname = name[:-len(suffix)]
@ -86,9 +84,9 @@ class SynDynOptionDescription:
return True
def get_children(self,
config_bag: ConfigBag,
dyn: bool=True,
):
config_bag: ConfigBag,
dyn: bool=True,
):
subpath = self.impl_getpath()
children = []
for child in self.opt.get_children(config_bag):
@ -102,21 +100,23 @@ class SynDynOptionDescription:
return True
def get_children_recursively(self,
bytype: Optional[BaseOption],
byname: Optional[str],
config_bag: ConfigBag,
self_opt: BaseOption=None) -> BaseOption:
bytype: Optional[BaseOption],
byname: Optional[str],
config_bag: ConfigBag,
self_opt: BaseOption=None,
) -> BaseOption:
for option in self.opt.get_children_recursively(bytype,
byname,
config_bag,
self):
byname,
config_bag,
self,
):
yield option
def impl_getpath(self) -> str:
rootpath = self.rootpath
if rootpath != '':
rootpath += '.'
return rootpath + self.impl_getname()
path = self.impl_getname()
if self.rootpath:
path = f'{self.rootpath}.{path}'
return path
def impl_get_display_name(self) -> str:
return self.opt.impl_get_display_name() + str(self._suffix)
@ -126,44 +126,52 @@ class SynDynLeadership(SynDynOptionDescription):
def get_leader(self) -> SynDynOption:
return self.opt.get_leader().to_dynoption(self.impl_getpath(),
self._suffix,
self.ori_dyn)
self.ori_dyn,
)
def get_followers(self) -> Iterator[SynDynOption]:
subpath = self.impl_getpath()
for follower in self.opt.get_followers():
yield follower.to_dynoption(subpath,
self._suffix,
self.ori_dyn)
self.ori_dyn,
)
def reset_cache(self,
path: str,
config_bag: 'ConfigBag',
resetted_opts: List[str]) -> None:
resetted_opts: List[str],
) -> None:
leader = self.get_leader()
followers = self.get_followers()
self._reset_cache(path,
leader,
followers,
config_bag,
resetted_opts)
resetted_opts,
)
def pop(self,
*args,
**kwargs) -> None:
*args,
**kwargs,
) -> None:
self.opt.pop(*args,
followers=self.get_followers(),
**kwargs)
followers=self.get_followers(),
**kwargs,
)
def follower_force_store_value(self,
values,
value,
option_bag,
owner) -> None:
values,
value,
option_bag,
owner,
) -> None:
self.opt.follower_force_store_value(values,
value,
option_bag,
owner,
dyn=self)
value,
option_bag,
owner,
dyn=self,
)
def impl_getsuffix(self) -> str:
return self._suffix

View file

@ -15,6 +15,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# ____________________________________________________________
from typing import Union
from itertools import chain
from .error import PropertiesOptionError, ConstError, ConfigError, LeadershipError, display_list
from .i18n import _
@ -102,19 +103,35 @@ read_write
you can get all variables not disabled and not hidden
you can set all variables not frozen
"""
RO_APPEND = frozenset(['frozen', 'disabled', 'validator', 'everything_frozen',
'mandatory', 'empty', 'force_store_value'])
RO_REMOVE = frozenset(['permissive', 'hidden'])
RW_APPEND = frozenset(['frozen', 'disabled', 'validator', 'hidden',
'force_store_value'])
RW_REMOVE = frozenset(['permissive', 'everything_frozen', 'mandatory',
'empty'])
RO_APPEND = frozenset(['frozen',
'disabled',
'validator',
'everything_frozen',
'mandatory',
'empty',
'force_store_value',
])
RO_REMOVE = frozenset(['permissive',
'hidden',
])
RW_APPEND = frozenset(['frozen',
'disabled',
'validator',
'hidden',
'force_store_value',
])
RW_REMOVE = frozenset(['permissive',
'everything_frozen',
'mandatory',
'empty',
])
FORBIDDEN_SET_PROPERTIES = frozenset(['force_store_value'])
FORBIDDEN_SET_PERMISSIVES = frozenset(['force_default_on_freeze',
'force_metaconfig_on_freeze',
'force_store_value'])
'force_store_value',
])
ALLOWED_LEADER_PROPERTIES = frozenset(['empty',
'notempty',
'notunique',
@ -123,11 +140,23 @@ ALLOWED_LEADER_PROPERTIES = frozenset(['empty',
'mandatory',
'force_default_on_freeze',
'force_metaconfig_on_freeze',
'frozen'])
'frozen',
])
static_set = frozenset()
# ____________________________________________________________
class Undefined(object):
def __str__(self): # pragma: no cover
return 'Undefined'
__repr__ = __str__
undefined = Undefined()
class OptionBag:
__slots__ = ('option', # current option
'path',
@ -135,38 +164,42 @@ class OptionBag:
'config_bag',
'ori_option', # original option (for example useful for symlinkoption)
'properties', # properties of current option
'properties_setted',
'apply_requires', # apply requires or not for this option
)
def __init__(self):
self.option = None
def set_option(self,
option,
index,
config_bag):
if config_bag is undefined:
self.path = None
else:
self.path = option.impl_getpath()
def __init__(self,
option,
index,
config_bag,
path=None,
properties=undefined,
ori_option=None,
apply_requires=True,
):
self.index = index
self.option = option
self.config_bag = config_bag
self.option = option
if ori_option is not None:
self.ori_option = ori_option
if config_bag is undefined:
self.path = path
elif path:
self.path = path
elif option:
self.path = option.impl_getpath()
if '.' not in self.path and option == config_bag.context.get_description():
self.properties = None
elif properties is undefined:
self.properties = config_bag.context.get_settings().getproperties(self, apply_requires=apply_requires)
if properties is not undefined:
self.properties = properties
def __getattr__(self, key):
if key == 'ori_option':
return self.option
elif key == 'apply_requires':
return True
elif key == 'properties_setted':
return False
raise KeyError('unknown key "{}" for OptionBag'.format(key)) # pragma: no cover
def __setattr__(self, key, val):
super().__setattr__(key, val)
if key == 'properties':
self.properties_setted = True
return undefined
def __delattr__(self, key):
if key in ['properties', 'permissives']:
@ -178,10 +211,14 @@ class OptionBag:
raise KeyError(_('cannot delete key "{}" for OptionBag').format(key)) # pragma: no cover
def copy(self):
option_bag = OptionBag()
option_bag = OptionBag(None,
None,
None,
)
for key in self.__slots__:
if hasattr(self, key):
setattr(option_bag, key, getattr(self, key))
if not hasattr(self, key):
continue
setattr(option_bag, key, getattr(self, key))
return option_bag
@ -248,13 +285,15 @@ class _NameSpace(object):
def __setattr__(self,
name,
value):
value,
):
if name in self.__dict__:
raise ConstError(_("can't rebind {0}").format(name))
self.__dict__[name] = value
def __delattr__(self,
name):
name,
):
raise ConstError(_("can't unbind {0}").format(name))
@ -288,7 +327,7 @@ class GroupModule(_NameSpace):
class OwnerModule(_NameSpace):
"""emulates a module to manage unique owner names.
owners are living in `Config._cfgimpl_value_owners`
owners are living in `Config._value_owners`
"""
class Owner(str):
"""allowed owner names
@ -342,17 +381,6 @@ owners.forced = owners.Owner('forced')
forbidden_owners = (owners.default, owners.forced)
# ____________________________________________________________
class Undefined(object):
def __str__(self): # pragma: no cover
return 'Undefined'
__repr__ = __str__
undefined = Undefined()
# ____________________________________________________________
class Settings(object):
"``config.Config()``'s configuration options settings"
@ -387,14 +415,15 @@ class Settings(object):
# get properties and permissive methods
def get_context_properties(self,
cache,
):
cache,
):
is_cached, props, validated = cache.getcache(None,
None,
None,
{},
{},
'context_props')
'context_props',
)
if not is_cached:
props = self._properties.get(None, {}).get(None, self.default_properties)
cache.setcache(None,
@ -417,10 +446,11 @@ class Settings(object):
return ret
def getproperties(self,
option_bag,
apply_requires=True,
uncalculated=False,
help_property=False):
option_bag,
apply_requires=True,
uncalculated=False,
help_property=False,
):
"""
"""
option = option_bag.option
@ -430,13 +460,14 @@ class Settings(object):
path = option.impl_getpath()
index = option_bag.index
if apply_requires and not uncalculated and not help_property:
cache = config_bag.context._impl_properties_cache
cache = config_bag.context.properties_cache
is_cached, props, validated = cache.getcache(path,
config_bag.expiration_time,
index,
config_bag.properties,
{},
'self_props')
'self_props',
)
else:
is_cached = False
if not is_cached:
@ -459,14 +490,14 @@ class Settings(object):
elif apply_requires:
if not help_property:
new_prop = prop.execute(option_bag,
leadership_must_have_index=True,
for_settings=True,
)
leadership_must_have_index=True,
for_settings=True,
)
else:
new_prop = prop.help(option_bag,
leadership_must_have_index=True,
for_settings=True,
)
leadership_must_have_index=True,
for_settings=True,
)
if isinstance(new_prop, str):
new_prop = (new_prop, new_prop)
if new_prop is None:
@ -521,8 +552,8 @@ class Settings(object):
return ret
def getpermissives(self,
option_bag,
):
option_bag,
):
if option_bag is None:
path = None
index = None
@ -546,13 +577,12 @@ class Settings(object):
# set methods
def set_context_properties(self, properties, context):
self._properties.setdefault(None, {})[None] = properties
context.cfgimpl_reset_cache(None)
context.reset_cache(None)
def setproperties(self,
path,
properties,
option_bag,
context):
option_bag,
properties,
):
"""save properties for specified path
(never save properties if same has option properties)
"""
@ -572,22 +602,22 @@ class Settings(object):
raise LeadershipError(_('a leader ({0}) cannot have '
'"force_default_on_freeze" or "force_metaconfig_on_freeze" property without "frozen"'
'').format(opt.impl_get_display_name()))
self._properties.setdefault(path, {})[option_bag.index] = properties
self._properties.setdefault(option_bag.path, {})[option_bag.index] = properties
# values too because of follower values could have a PropertiesOptionError has value
context.cfgimpl_reset_cache(option_bag)
option_bag.config_bag.context.reset_cache(option_bag)
option_bag.properties = properties
def set_context_permissives(self,
permissives,
):
permissives,
):
self.setpermissives(None,
permissives,
)
permissives,
)
def setpermissives(self,
option_bag,
permissives,
):
option_bag,
permissives,
):
"""
enables us to put the permissives in the storage
@ -615,59 +645,66 @@ class Settings(object):
' '.join(forbidden_permissives)))
self._permissives.setdefault(path, {})[index] = permissives
if option_bag is not None:
option_bag.config_bag.context.cfgimpl_reset_cache(option_bag)
option_bag.config_bag.context.reset_cache(option_bag)
#____________________________________________________________
# reset methods
def _get_path_index_config_option(self,
bag: Union[OptionBag, ConfigBag],
msg: str,
):
if isinstance(bag, ConfigBag):
path = None
index = None
config_bag = bag
option_bag = None
else:
assert not bag.option.impl_is_symlinkoption(), \
_(msg).format(bag.option.impl_get_display_name())
path = bag.path
index = bag.index
config_bag = bag.config_bag
option_bag = bag
return path, index, config_bag, option_bag
def reset(self,
option_bag,
config_bag):
if option_bag is None:
opt = None
path = None
index = None
else:
opt = option_bag.option
assert not opt.impl_is_symlinkoption(), _("can't reset properties to "
"the symlinkoption \"{}\""
"").format(opt.impl_get_display_name())
path = option_bag.path
index = option_bag.index
bag: Union[OptionBag, ConfigBag],
):
path, index, config_bag, option_bag = \
self._get_path_index_config_option(bag,
"can't reset properties to "
"the symlinkoption \"{}\"",
)
if path in self._properties and index in self._properties[path]:
del(self._properties[path][index])
config_bag.context.cfgimpl_reset_cache(option_bag)
config_bag.context.reset_cache(option_bag)
def reset_permissives(self,
option_bag,
config_bag):
if option_bag is None:
opt = None
path = None
index = None
else:
opt = option_bag.option
assert not opt.impl_is_symlinkoption(), _("can't reset permissives to "
"the symlinkoption \"{}\""
"").format(opt.impl_get_display_name())
index = option_bag.index
path = option_bag.path
bag: Union[OptionBag, ConfigBag],
):
path, index, config_bag, option_bag = \
self._get_path_index_config_option(bag,
"can't reset permissives to "
"the symlinkoption \"{}\"",
)
if path in self._permissives and index in self._permissives[path]:
del(self._permissives[path][index])
config_bag.context.cfgimpl_reset_cache(option_bag)
config_bag.context.reset_cache(option_bag)
#____________________________________________________________
# validate properties
def calc_raises_properties(self,
option_bag,
apply_requires=True,
uncalculated=False):
if not uncalculated and apply_requires and option_bag.properties_setted:
option_bag,
apply_requires=True,
uncalculated=False,
):
if not uncalculated and apply_requires:
option_properties = option_bag.properties
else:
option_properties = self.getproperties(option_bag,
apply_requires=apply_requires,
uncalculated=uncalculated)
apply_requires=apply_requires,
uncalculated=uncalculated,
)
return self._calc_raises_properties(option_bag.config_bag.properties,
option_bag.config_bag.permissives,
option_properties)
@ -685,8 +722,9 @@ class Settings(object):
return properties
def validate_properties(self,
option_bag,
need_help=True):
option_bag,
need_help=True,
):
config_properties = option_bag.config_bag.properties
if not config_properties or config_properties == frozenset(['cache']):
# if no global property
@ -695,11 +733,13 @@ class Settings(object):
if properties != frozenset():
if need_help:
help_properties = dict(self.getproperties(option_bag,
help_property=True))
help_property=True,
))
calc_properties = []
for property_ in self._calc_raises_properties(option_bag.config_bag.properties,
option_bag.config_bag.permissives,
set(help_properties.keys())):
set(help_properties.keys()),
):
calc_properties.append(help_properties[property_])
calc_properties = frozenset(calc_properties)
else:
@ -711,9 +751,10 @@ class Settings(object):
def validate_mandatory(self,
value,
option_bag):
option_bag,
):
if 'mandatory' in option_bag.config_bag.properties:
values = option_bag.config_bag.context.cfgimpl_get_values()
values = option_bag.config_bag.context.get_values()
if option_bag.option.impl_is_follower():
force_allow_empty_list = True
else:
@ -721,19 +762,23 @@ class Settings(object):
if not ('permissive' in option_bag.config_bag.properties and
'mandatory' in option_bag.config_bag.permissives) and \
'mandatory' in option_bag.properties and values.isempty(option_bag.option,
value,
force_allow_empty_list=force_allow_empty_list,
index=option_bag.index):
value,
force_allow_empty_list=force_allow_empty_list,
index=option_bag.index,
):
raise PropertiesOptionError(option_bag,
['mandatory'],
self)
self,
)
if 'empty' in option_bag.properties and values.isempty(option_bag.option,
value,
force_allow_empty_list=True,
index=option_bag.index):
index=option_bag.index,
):
raise PropertiesOptionError(option_bag,
['empty'],
self)
self,
)
def validate_frozen(self,
option_bag):
@ -750,9 +795,10 @@ class Settings(object):
# read only/read write
def _read(self,
remove,
append,
config_bag):
remove,
append,
config_bag,
):
props = self._properties.get(None, {}).get(None, self.default_properties)
modified = False
if remove & props:
@ -763,19 +809,23 @@ class Settings(object):
modified = True
if modified:
self.set_context_properties(frozenset(props),
config_bag.context,
)
config_bag.context,
)
def read_only(self,
config_bag):
config_bag,
):
"convenience method to freeze, hide and disable"
self._read(self.ro_remove,
self.ro_append,
config_bag)
self.ro_append,
config_bag,
)
def read_write(self,
config_bag):
config_bag,
):
"convenience method to freeze, hide and disable"
self._read(self.rw_remove,
self.rw_append,
config_bag)
self.rw_append,
config_bag,
)

View file

@ -152,10 +152,11 @@ class Requires(object):
self.tiramisu_web.set_remotable(leader.option.path(), form, leader)
def manage_requires(self,
childapi,
path,
form,
current_action):
childapi,
path,
form,
current_action,
):
for requires in childapi.option.properties(uncalculated=True):
if not isinstance(requires, str):
option = requires.params.kwargs['condition'].option
@ -365,14 +366,15 @@ class TiramisuDict:
form.setdefault(leader.option.path(), {})['remote'] = True
def walk(self,
root,
subchildapi,
schema,
model,
form,
order,
updates_status,
init=False):
root,
subchildapi,
schema,
model,
form,
order,
updates_status,
init=False,
):
error = None
if init:
if form is not None:
@ -398,22 +400,26 @@ class TiramisuDict:
props_no_requires = set(childapi.option.properties())
if form is not None:
self.requires.add(path,
childapi,
form)
childapi,
form,
)
self.consistencies.add(path,
childapi,
form)
childapi,
form,
)
self.callbacks.add(path,
childapi,
schema,
'force_store_value' in props_no_requires)
childapi,
schema,
'force_store_value' in props_no_requires,
)
childapi_option = childapi.option
if model is not None and childapi.option.isoptiondescription() or not childapi_option.issymlinkoption():
self.gen_model(model,
childapi,
path,
leader_len,
updates_status)
childapi,
path,
leader_len,
updates_status,
)
if order is not None:
order.append(path)
if childapi.option.isoptiondescription():
@ -429,12 +435,13 @@ class TiramisuDict:
else:
subschema = schema
self.walk(path,
childapi,
subschema,
model,
form,
order,
updates_status)
childapi,
subschema,
model,
form,
order,
updates_status,
)
else:
child = childapi_option.get()
childtype = child.__class__.__name__
@ -461,22 +468,24 @@ class TiramisuDict:
if schema is not None:
self.gen_schema(schema,
childapi,
childapi_option,
path,
props_no_requires,
value,
defaultmulti,
is_multi,
web_type,
form)
childapi,
childapi_option,
path,
props_no_requires,
value,
defaultmulti,
is_multi,
web_type,
form,
)
if form is not None:
self.gen_form(form,
web_type,
path,
child,
childapi_option,
childtype)
web_type,
path,
child,
childapi_option,
childtype,
)
if schema is not None:
if web_type != 'symlink':
schema[path]['title'] = childapi_option.description()
@ -502,16 +511,17 @@ class TiramisuDict:
def gen_schema(self,
schema,
childapi,
childapi_option,
path,
props_no_requires,
value,
defaultmulti,
is_multi,
web_type,
form):
schema,
childapi,
childapi_option,
path,
props_no_requires,
value,
defaultmulti,
is_multi,
web_type,
form,
):
schema[path] = {'type': web_type}
if childapi_option.issymlinkoption():
sym_option = childapi_option.get()
@ -545,10 +555,11 @@ class TiramisuDict:
def get_enum(self,
childapi,
is_multi,
path,
props_no_requires):
childapi,
is_multi,
path,
props_no_requires,
):
values = childapi.value.list()
empty_is_required = not childapi.option.isfollower() and is_multi
if '' not in values and ((empty_is_required and not 'empty' in props_no_requires) or \
@ -557,12 +568,13 @@ class TiramisuDict:
return values
def gen_form(self,
form,
web_type,
path,
child,
childapi_option,
childtype):
form,
web_type,
path,
child,
childapi_option,
childtype,
):
obj_form = {}
if path in form:
obj_form.update(form[path])
@ -601,13 +613,14 @@ class TiramisuDict:
form[path] = obj_form
def calc_raises_properties(self,
obj,
childapi):
old_properties = childapi._option_bag.config_bag.properties
config = childapi._option_bag.config_bag.context
settings = config.cfgimpl_get_settings()
childapi._option_bag.config_bag.properties = self.config.property.get(default=True) # settings.get_context_properties(config._impl_properties_cache)
childapi._option_bag.config_bag.properties -= {'permissive'}
obj,
childapi,
):
old_properties = childapi._config_bag.properties
config = childapi._config_bag.context
settings = config.get_settings()
childapi._config_bag.properties = self.config.property.get(default=True) # settings.get_context_properties(config._impl_properties_cache)
childapi._config_bag.properties -= {'permissive'}
properties = childapi.property.get(only_raises=True,
uncalculated=True)
properties -= childapi.permissive.get()
@ -618,12 +631,13 @@ class TiramisuDict:
properties -= self.config.permissive.get()
if properties:
obj['hidden'] = True
childapi._option_bag.config_bag.properties = old_properties
childapi._config_bag.properties = old_properties
def _gen_model_properties(self,
childapi,
path,
index):
childapi,
path,
index,
):
isfollower = childapi.option.isfollower()
props = set(childapi.property.get())
obj = self.gen_properties(props,
@ -667,11 +681,12 @@ class TiramisuDict:
return obj
def gen_model(self,
model,
childapi,
path,
leader_len,
updates_status):
model,
childapi,
path,
leader_len,
updates_status,
):
if childapi.option.isoptiondescription():
props = set(childapi.property.get())
obj = {}
@ -686,27 +701,31 @@ class TiramisuDict:
pass
else:
obj = self._gen_model_properties(childapi,
path,
None)
path,
None,
)
if childapi.option.isfollower():
for index in range(leader_len):
follower_childapi = self.config.unrestraint.option(path, index)
sobj = self._gen_model_properties(follower_childapi,
path,
index)
path,
index,
)
self._get_model_value(follower_childapi,
path,
sobj,
index,
updates_status)
path,
sobj,
index,
updates_status,
)
if sobj:
model.setdefault(path, {})[str(index)] = sobj
else:
self._get_model_value(childapi,
path,
obj,
None,
updates_status)
path,
obj,
None,
updates_status,
)
if obj:
if not childapi.option.isoptiondescription() and childapi.option.isfollower():
model.setdefault(path, {})['null'] = obj
@ -714,11 +733,12 @@ class TiramisuDict:
model[path] = obj
def _get_model_value(self,
childapi,
path,
obj,
index,
updates_status):
childapi,
path,
obj,
index,
updates_status,
):
if path in updates_status and index in updates_status[path]:
value = childapi.value.get()
self._get_value_with_exception(obj,
@ -739,7 +759,7 @@ class TiramisuDict:
value = self.config.unrestraint.option(path, index=index).value.get()
except PropertiesOptionError as err:
config_bag = self.config._config_bag
settings = config_bag.context.cfgimpl_get_settings()
settings = config_bag.context.get_settings()
if settings._calc_raises_properties(config_bag.properties,
config_bag.permissives,
set(err.proptype)):
@ -835,9 +855,10 @@ class TiramisuDict:
childapi.value.set(multi)
def apply_updates(self,
oripath,
updates,
model_ori):
oripath,
updates,
model_ori,
):
updates_status = {}
for update in updates:
path = update['name']
@ -852,13 +873,15 @@ class TiramisuDict:
try:
if update['action'] == 'modify':
self.mod_value(childapi,
path,
index,
update.get('value', undefined))
path,
index,
update.get('value', undefined),
)
elif update['action'] == 'delete':
self.del_value(childapi,
path,
index)
path,
index,
)
elif update['action'] == 'add':
if childapi_option.ismulti():
self.add_value(childapi, path, update['value'])
@ -873,19 +896,22 @@ class TiramisuDict:
return updates_status
def set_updates(self,
body):
body,
):
root_path = self.root
updates = body.get('updates', [])
updates_status = self.apply_updates(root_path,
updates,
body.get('model'))
updates,
body.get('model'),
)
if 'model' in body:
order = []
old_model = body['model']
new_model = self.todict(order=order,
build_schema=False,
build_form=False,
updates_status=updates_status)
build_schema=False,
build_form=False,
updates_status=updates_status,
)
values = {'updates': list_keys(old_model, new_model['model'], order, updates_status),
'model': new_model['model']}
else:
@ -893,12 +919,13 @@ class TiramisuDict:
return values
def todict(self,
custom_form=[],
build_schema=True,
build_model=True,
build_form=True,
order=None,
updates_status={}):
custom_form=[],
build_schema=True,
build_model=True,
build_form=True,
order=None,
updates_status={},
):
rootpath = self.root
if build_schema:
schema = {}
@ -914,13 +941,14 @@ class TiramisuDict:
else:
form = None
self.walk(rootpath,
None,
schema,
model,
form,
order,
updates_status,
init=True)
None,
schema,
model,
form,
order,
updates_status,
init=True,
)
if build_form:
for form_ in custom_form:
if 'key' in form_:

View file

@ -101,9 +101,9 @@ class Values:
def force_to_metaconfig(self, option_bag):
# force_metaconfig_on_freeze in config => to metaconfig
# force_metaconfig_on_freeze in option + config is kernelconfig => to metaconfig
settings = option_bag.config_bag.context.cfgimpl_get_settings()
settings = option_bag.config_bag.context.get_settings()
if 'force_metaconfig_on_freeze' in option_bag.properties:
settings = option_bag.config_bag.context.cfgimpl_get_settings()
settings = option_bag.config_bag.context.get_settings()
if 'force_metaconfig_on_freeze' in option_bag.option.impl_getproperties() and \
not settings._properties.get(option_bag.path, {}).get(None, frozenset()):
# if force_metaconfig_on_freeze is only in option (not in config)
@ -113,8 +113,9 @@ class Values:
return False
def _do_value_list(self,
value: Any,
option_bag: OptionBag):
value: Any,
option_bag: OptionBag,
):
ret = []
for val in value:
if isinstance(val, (list, tuple)):
@ -126,8 +127,8 @@ class Values:
return ret
def getvalue(self,
option_bag,
):
option_bag,
):
"""actually retrieves the value
:param path: the path of the `Option`
@ -180,7 +181,7 @@ class Values:
moption_bag = self._get_modified_parent(option_bag)
if moption_bag is not None:
# retrieved value from parent config
return moption_bag.config_bag.context.cfgimpl_get_values().get_cached_value(moption_bag)
return moption_bag.config_bag.context.get_values().get_cached_value(moption_bag)
# now try to get default value:
value = self.calc_value(option_bag,
@ -226,7 +227,7 @@ class Values:
# so do not invalidate cache
return
# calculated value is a new value, so reset cache
option_bag.config_bag.context.cfgimpl_reset_cache(option_bag)
option_bag.config_bag.context.reset_cache(option_bag)
# and manage force_store_value
self._set_force_value_suffix(option_bag)
@ -246,10 +247,10 @@ class Values:
#______________________________________________________________________
# set value
def setvalue(self,
value,
option_bag,
):
def set_value(self,
option_bag,
value,
):
context = option_bag.config_bag.context
owner = self.get_context_owner()
if 'validator' in option_bag.config_bag.properties:
@ -282,30 +283,36 @@ class Values:
def setvalue_validation(self,
value,
option_bag):
settings = option_bag.config_bag.context.cfgimpl_get_settings()
option_bag,
):
settings = option_bag.config_bag.context.get_settings()
# First validate properties with this value
opt = option_bag.option
settings.validate_frozen(option_bag)
val = self.calc_value(option_bag, value, False)
val = self.calc_value(option_bag,
value,
False,)
settings.validate_mandatory(val,
option_bag)
option_bag,
)
# Value must be valid for option
opt.impl_validate(val,
option_bag,
check_error=True)
check_error=True,
)
if 'warnings' in option_bag.config_bag.properties:
# No error found so emit warnings
opt.impl_validate(value,
option_bag,
check_error=False)
check_error=False,
)
def _setvalue(self,
option_bag: OptionBag,
value: Any,
owner: str,
) -> None:
option_bag.config_bag.context.cfgimpl_reset_cache(option_bag)
option_bag.config_bag.context.reset_cache(option_bag)
self.set_storage_value(option_bag.path,
option_bag.index,
value,
@ -343,7 +350,7 @@ class Values:
if not force_store_options:
continue
rootpath = option.impl_getpath()
settings = option_bag.config_bag.context.cfgimpl_get_settings()
settings = option_bag.config_bag.context.get_settings()
for suffix in option.get_suffixes(option_bag.config_bag):
for coption in force_store_options:
subpaths = [rootpath] + coption.impl_getpath()[len(rootpath) + 1:].split('.')[:-1]
@ -355,26 +362,24 @@ class Values:
)
if coption.impl_is_follower():
leader = coption.impl_get_leadership().get_leader()
loption_bag = OptionBag()
loption_bag.set_option(leader,
None,
option_bag.config_bag,
)
loption_bag.properties = frozenset()
loption_bag = OptionBag(leader,
None,
option_bag.config_bag,
properties=frozenset(),
)
indexes = range(len(self.getvalue(loption_bag)))
else:
indexes = [None]
for index in indexes:
coption_bag = OptionBag()
coption_bag.set_option(doption,
index,
option_bag.config_bag,
)
coption_bag.properties = settings.getproperties(coption_bag)
coption_bag = OptionBag(doption,
index,
option_bag.config_bag,
)
self._values.setdefault(coption_bag.path, {})[index] = [self.getvalue(coption_bag), owners.forced]
def _get_modified_parent(self,
option_bag: OptionBag) -> Optional[OptionBag]:
option_bag: OptionBag,
) -> Optional[OptionBag]:
""" Search in differents parents a Config with a modified value
If not found, return None
For follower option, return the Config where leader is modified
@ -393,13 +398,14 @@ class Values:
# remove force_metaconfig_on_freeze only if option in metaconfig
# hasn't force_metaconfig_on_freeze properties
ori_properties = doption_bag.properties
doption_bag.properties = doption_bag.config_bag.context.cfgimpl_get_settings().getproperties(doption_bag)
doption_bag.properties = doption_bag.config_bag.context.get_settings().getproperties(doption_bag)
if not self.force_to_metaconfig(doption_bag):
doption_bag.properties = ori_properties - {'force_metaconfig_on_freeze'}
else:
doption_bag.properties = ori_properties
parent_owner = parent.cfgimpl_get_values().getowner(doption_bag,
only_default=True)
parent_owner = parent.get_values().getowner(doption_bag,
only_default=True,
)
if parent_owner != owners.default:
return doption_bag
@ -433,7 +439,8 @@ class Values:
def getowner(self,
option_bag,
validate_meta=True,
only_default=False):
only_default=False,
):
"""
retrieves the option's owner
@ -449,7 +456,7 @@ class Values:
opt = opt.impl_getopt()
option_bag.option = opt
option_bag.path = opt.impl_getpath()
settings = context.cfgimpl_get_settings()
settings = context.get_settings()
settings.validate_properties(option_bag)
if 'frozen' in option_bag.properties and \
'force_default_on_freeze' in option_bag.properties:
@ -466,16 +473,17 @@ class Values:
'frozen' in option_bag.properties and 'force_metaconfig_on_freeze' in option_bag.properties):
moption_bag = self._get_modified_parent(option_bag)
if moption_bag is not None:
owner = moption_bag.config_bag.context.cfgimpl_get_values().getowner(moption_bag,
only_default=only_default)
owner = moption_bag.config_bag.context.get_values().getowner(moption_bag,
only_default=only_default,
)
elif 'force_metaconfig_on_freeze' in option_bag.properties:
return owners.default
return owner
def setowner(self,
owner,
option_bag,
):
def set_owner(self,
option_bag,
owner,
):
"""
sets a owner to an option
@ -492,7 +500,7 @@ class Values:
if not self.hasvalue(option_bag.path, option_bag.index):
raise ConfigError(_('no value for {0} cannot change owner to {1}'
'').format(option_bag.path, owner))
option_bag.config_bag.context.cfgimpl_get_settings().validate_frozen(option_bag)
option_bag.config_bag.context.get_settings().validate_frozen(option_bag)
self._values[option_bag.path][option_bag.index][1] = owner
#______________________________________________________________________
# reset
@ -510,7 +518,7 @@ class Values:
config_bag.context = fake_context
soption_bag = option_bag.copy()
soption_bag.config_bag = config_bag
fake_value = fake_context.cfgimpl_get_values()
fake_value = fake_context.get_values()
fake_value.reset(soption_bag)
soption_bag.config_bag.properties = option_bag.config_bag.properties
value = fake_value.getdefaultvalue(soption_bag)
@ -533,7 +541,7 @@ class Values:
value = None
if option_bag.path in self._values:
del self._values[option_bag.path]
context.cfgimpl_reset_cache(option_bag)
context.reset_cache(option_bag)
if 'force_store_value' in setting_properties and option_bag.option.impl_is_leader():
if value is None:
value = self.getdefaultvalue(option_bag)
@ -556,7 +564,7 @@ class Values:
setting_properties = option_bag.config_bag.properties
if 'validator' in setting_properties:
fake_context = context._gen_fake_values()
fake_value = fake_context.cfgimpl_get_values()
fake_value = fake_context.get_values()
config_bag = option_bag.config_bag.copy()
config_bag.remove_validation()
config_bag.context = fake_context
@ -577,7 +585,7 @@ class Values:
self.resetvalue_index(option_bag.path,
option_bag.index,
)
context.cfgimpl_reset_cache(option_bag)
context.reset_cache(option_bag)
def resetvalue_index(self,
path,
@ -587,9 +595,10 @@ class Values:
del self._values[path][index]
def reset_leadership(self,
index,
option_bag,
subconfig):
option_bag: OptionBag,
leadership_option_bag: OptionBag,
index: int,
):
current_value = self.get_cached_value(option_bag)
length = len(current_value)
if index >= length:
@ -598,12 +607,13 @@ class Values:
length,
option_bag.option.impl_get_display_name()))
current_value.pop(index)
subconfig.cfgimpl_get_description().pop(self,
index,
option_bag)
self.setvalue(current_value,
option_bag,
)
leadership_option_bag.option.pop(self,
index,
option_bag,
)
self.set_value(option_bag,
current_value,
)
#______________________________________________________________________
# information
@ -626,7 +636,7 @@ class Values:
self._informations.setdefault(path, {})[key] = value
if path is not None:
for option in option_bag.option.get_dependencies_information(itself=True):
config_bag.context.cfgimpl_reset_cache(option_bag)
config_bag.context.reset_cache(option_bag)
def get_information(self,
config_bag,
@ -666,95 +676,6 @@ class Values:
):
return list(self._informations.get(path, {}).keys())
#______________________________________________________________________
# mandatory warnings
def _mandatory_warnings(self,
context,
config_bag,
description,
currpath,
subconfig,
od_config_bag):
settings = context.cfgimpl_get_settings()
for option in description.get_children(config_bag):
name = option.impl_getname()
if option.impl_is_optiondescription():
try:
option_bag = OptionBag()
option_bag.set_option(option,
None,
od_config_bag)
option_bag.properties = settings.getproperties(option_bag)
subsubconfig = subconfig.get_subconfig(option_bag)
except PropertiesOptionError as err:
pass
else:
for option in self._mandatory_warnings(context,
config_bag,
option,
currpath + [name],
subsubconfig,
od_config_bag):
yield option
elif not option.impl_is_symlinkoption():
# don't verifying symlink
try:
if not option.impl_is_follower():
option_bag = OptionBag()
option_bag.set_option(option,
None,
config_bag)
option_bag.properties = settings.getproperties(option_bag)
if 'mandatory' in option_bag.properties or 'empty' in option_bag.properties:
subconfig.getattr(name,
option_bag)
else:
for index in range(subconfig.cfgimpl_get_length()):
option_bag = OptionBag()
option_bag.set_option(option,
index,
config_bag)
option_bag.properties = settings.getproperties(option_bag)
if 'mandatory' in option_bag.properties or 'empty' in option_bag.properties:
subconfig.getattr(name,
option_bag)
except PropertiesOptionError as err:
if err.proptype in (['mandatory'], ['empty']):
yield option.impl_getpath()
except ConfigError:
pass
def mandatory_warnings(self,
config_bag):
"""convenience function to trace Options that are mandatory and
where no value has been set
:returns: generator of mandatory Option's path
"""
context = config_bag.context
# copy
od_setting_properties = config_bag.properties - {'mandatory', 'empty'}
setting_properties = set(config_bag.properties) - {'warnings'}
setting_properties.update(['mandatory', 'empty'])
nconfig_bag = ConfigBag(context=config_bag.context,
properties=frozenset(setting_properties),
permissives=config_bag.permissives)
nconfig_bag.set_permissive()
od_config_bag = ConfigBag(context=nconfig_bag.context,
properties=frozenset(od_setting_properties),
permissives=nconfig_bag.permissives)
od_config_bag.set_permissive()
descr = context.cfgimpl_get_description()
for option in self._mandatory_warnings(context,
nconfig_bag,
descr,
[],
context,
od_config_bag):
yield option
#____________________________________________________________
# default owner methods
def set_context_owner(self, owner):