consistency is now simple validation

This commit is contained in:
Emmanuel Garette 2019-10-27 11:09:15 +01:00
parent e62268c46a
commit 5c3a133928
37 changed files with 1163 additions and 6135 deletions

View File

@ -5,11 +5,9 @@ from .autopath import do_autopath
do_autopath() do_autopath()
from .config import config_type, get_config, value_list, global_owner from .config import config_type, get_config, value_list, global_owner
from tiramisu.setting import owners from tiramisu import ChoiceOption, StrOption, OptionDescription, Config, owners, Calculation, \
from tiramisu import ChoiceOption, StrOption, OptionDescription, Config undefined, Params, ParamValue, ParamOption, list_sessions
from tiramisu.error import ConfigError from tiramisu.error import ConfigError
from tiramisu import undefined, Params, ParamValue, ParamOption
from tiramisu.storage import list_sessions
def teardown_function(function): def teardown_function(function):
@ -58,7 +56,7 @@ def test_choiceoption(config_type):
def test_choiceoption_function(config_type): def test_choiceoption_function(config_type):
choice = ChoiceOption('choice', '', values=return_list) choice = ChoiceOption('choice', '', values=Calculation(return_list))
odesc = OptionDescription('od', '', [choice]) odesc = OptionDescription('od', '', [choice])
cfg = Config(odesc) cfg = Config(odesc)
cfg.property.read_write() cfg.property.read_write()
@ -79,7 +77,7 @@ def test_choiceoption_function(config_type):
def test_choiceoption_function_error(): def test_choiceoption_function_error():
choice = ChoiceOption('choice', '', values=return_error) choice = ChoiceOption('choice', '', values=Calculation(return_error))
odesc = OptionDescription('od', '', [choice]) odesc = OptionDescription('od', '', [choice])
cfg = Config(odesc) cfg = Config(odesc)
cfg.property.read_write() cfg.property.read_write()
@ -87,7 +85,7 @@ def test_choiceoption_function_error():
def test_choiceoption_function_error_args(): def test_choiceoption_function_error_args():
choice = ChoiceOption('choice', '', values=return_error, values_params=Params((ParamValue('val1'),))) choice = ChoiceOption('choice', '', values=Calculation(return_error, Params(ParamValue('val1'))))
odesc = OptionDescription('od', '', [choice]) odesc = OptionDescription('od', '', [choice])
cfg = Config(odesc) cfg = Config(odesc)
cfg.property.read_write() cfg.property.read_write()
@ -95,7 +93,7 @@ def test_choiceoption_function_error_args():
def test_choiceoption_function_error_kwargs(): def test_choiceoption_function_error_kwargs():
choice = ChoiceOption('choice', '', values=return_error, values_params=Params(kwargs={'kwargs': ParamValue('val1')})) choice = ChoiceOption('choice', '', values=Calculation(return_error, Params(kwargs={'kwargs': ParamValue('val1')})))
odesc = OptionDescription('od', '', [choice]) odesc = OptionDescription('od', '', [choice])
cfg = Config(odesc) cfg = Config(odesc)
cfg.property.read_write() cfg.property.read_write()
@ -103,7 +101,7 @@ def test_choiceoption_function_error_kwargs():
def test_choiceoption_calc_function(config_type): def test_choiceoption_calc_function(config_type):
choice = ChoiceOption('choice', "", values=return_calc_list, values_params=Params((ParamValue('val1'),))) choice = ChoiceOption('choice', "", values=Calculation(return_calc_list, Params(ParamValue('val1'))))
odesc = OptionDescription('od', '', [choice]) odesc = OptionDescription('od', '', [choice])
cfg = Config(odesc) cfg = Config(odesc)
cfg.property.read_write() cfg.property.read_write()
@ -125,8 +123,7 @@ def test_choiceoption_calc_opt_function(config_type):
str_ = StrOption('str', '', 'val1') str_ = StrOption('str', '', 'val1')
choice = ChoiceOption('choice', choice = ChoiceOption('choice',
"", "",
values=return_calc_list, values=Calculation(return_calc_list, Params(ParamOption(str_))))
values_params=Params((ParamOption(str_),)))
odesc = OptionDescription('od', '', [str_, choice]) odesc = OptionDescription('od', '', [str_, choice])
cfg = Config(odesc) cfg = Config(odesc)
cfg.property.read_write() cfg.property.read_write()
@ -148,8 +145,7 @@ def test_choiceoption_calc_opt_function_propertyerror():
str_ = StrOption('str', '', 'val1', properties=('disabled',)) str_ = StrOption('str', '', 'val1', properties=('disabled',))
choice = ChoiceOption('choice', choice = ChoiceOption('choice',
"", "",
values=return_calc_list, values=Calculation(return_calc_list, Params(ParamOption(str_))))
values_params=Params((ParamOption(str_),)))
odesc = OptionDescription('od', '', [str_, choice]) odesc = OptionDescription('od', '', [str_, choice])
cfg = Config(odesc) cfg = Config(odesc)
cfg.property.read_write() cfg.property.read_write()
@ -164,14 +160,12 @@ def test_choiceoption_calc_opt_multi_function():
choice = ChoiceOption('choice', choice = ChoiceOption('choice',
"", "",
default_multi='val2', default_multi='val2',
values=return_val, values=Calculation(return_val, Params(ParamOption(str_))),
values_params=Params((ParamOption(str_),)),
multi=True) multi=True)
ch2 = ChoiceOption('ch2', ch2 = ChoiceOption('ch2',
"", "",
default=['val2'], default=['val2'],
values=return_val, values=Calculation(return_val, Params(ParamOption(str_))),
values_params=Params((ParamOption(str_),)),
multi=True) multi=True)
odesc = OptionDescription('od', '', [str_, choice, ch2]) odesc = OptionDescription('od', '', [str_, choice, ch2])
cfg = Config(odesc) cfg = Config(odesc)
@ -203,14 +197,12 @@ def test_choiceoption_calc_opt_multi_function_kwargs(config_type):
choice = ChoiceOption('choice', choice = ChoiceOption('choice',
"", "",
default_multi='val2', default_multi='val2',
values=return_val, values=Calculation(return_val, Params(kwargs={'val': ParamOption(str_)})),
values_params=Params(kwargs={'val': ParamOption(str_)}),
multi=True) multi=True)
ch2 = ChoiceOption('ch2', ch2 = ChoiceOption('ch2',
"", "",
default=['val2'], default=['val2'],
values=return_val, values=Calculation(return_val, Params(kwargs={'val': ParamOption(str_)})),
values_params=Params(kwargs={'val': ParamOption(str_)}),
multi=True) multi=True)
odesc = OptionDescription('od', '', [str_, choice, ch2]) odesc = OptionDescription('od', '', [str_, choice, ch2])
cfg = Config(odesc) cfg = Config(odesc)
@ -237,21 +229,12 @@ def test_choiceoption_calc_opt_multi_function_kwargs(config_type):
raises(ValueError, "cfg.option('ch2').value.get()") raises(ValueError, "cfg.option('ch2').value.get()")
def test_choiceoption_calc_invalid():
str_ = StrOption('str', '', ['val1'], multi=True)
str_
raises(ValueError,
"choice = ChoiceOption('choice', '', default_multi='val2', values=[1, 2, 3], \
values_params=Params((ParamOption(str_),)), multi=True)")
def test_choiceoption_calc_not_list(): def test_choiceoption_calc_not_list():
str_ = StrOption('str', '', 'val1') str_ = StrOption('str', '', 'val1')
choice = ChoiceOption('choice', choice = ChoiceOption('choice',
"", "",
default_multi='val2', default_multi='val2',
values=return_val, values=Calculation(return_val, Params(ParamOption(str_))),
values_params=Params((ParamOption(str_),)),
multi=True) multi=True)
odesc = OptionDescription('od', '', [str_, choice]) odesc = OptionDescription('od', '', [str_, choice])
cfg = Config(odesc) cfg = Config(odesc)

View File

@ -139,77 +139,11 @@ def test_deref_optiondescription_config():
assert w() is None assert w() is None
#def test_deref_groupconfig():
# if not IS_DEREFABLE:
# return
# i1 = IntOption('i1', '')
# od1 = OptionDescription('od1', '', [i1])
# od2 = OptionDescription('od2', '', [od1])
# conf1 = Config(od2, 'conf1')
# conf2 = Config(od2, 'conf2')
# meta = GroupConfig([conf1, conf2])
# w = weakref.ref(conf1)
# del(conf1)
# assert w() is not None
# del(meta)
# assert w() is None
#def test_deref_metaconfig():
# if not IS_DEREFABLE:
# return
# i1 = IntOption('i1', '')
# od1 = OptionDescription('od1', '', [i1])
# od2 = OptionDescription('od2', '', [od1])
# conf1 = Config(od2, 'conf1')
# conf2 = Config(od2, 'conf2')
# meta = MetaConfig([conf1, conf2])
# w = weakref.ref(conf1)
# del(conf1)
# assert w() is not None
# del(meta)
# assert w() is None
def test_deref_consistency():
if not IS_DEREFABLE:
return
a = IPOption('a', '')
b = NetmaskOption('b', '')
od = OptionDescription('od', '', [a, b])
b.impl_add_consistency('ip_netmask', a)
cfg = Config(od)
w = weakref.ref(a)
x = weakref.ref(b)
y = weakref.ref(od)
z = weakref.ref(cfg)
assert w() is not None
assert x() is not None
assert y() is not None
assert z() is not None
del(a)
del(b)
assert w() is not None
assert x() is not None
assert y() is not None
assert z() is not None
del(od)
assert w() is not None
assert x() is not None
assert y() is not None
assert z() is not None
del(cfg)
assert y() is None
assert z() is None
#assert w() is None
#assert x() is None
def test_deref_validator(): def test_deref_validator():
if not IS_DEREFABLE: if not IS_DEREFABLE:
return return
a = StrOption('a', '', default='yes') a = StrOption('a', '', default='yes')
b = StrOption('b', '', validator=funcname, validator_params=Params((ParamOption(a),)), default='val') b = StrOption('b', '', validators=[Calculation(funcname, Params(ParamOption(a)))], default='val')
od = OptionDescription('root', '', [a, b]) od = OptionDescription('root', '', [a, b])
cfg = Config(od) cfg = Config(od)
w = weakref.ref(a) w = weakref.ref(a)
@ -234,8 +168,6 @@ def test_deref_validator():
del(cfg) del(cfg)
assert y() is None assert y() is None
assert z() is None assert z() is None
#assert w() is None
#assert x() is None
def test_deref_callback(): def test_deref_callback():
@ -267,8 +199,6 @@ def test_deref_callback():
del(cfg) del(cfg)
assert y() is None assert y() is None
assert z() is None assert z() is None
#assert w() is None
#assert x() is None
def test_deref_symlink(): def test_deref_symlink():
@ -298,8 +228,6 @@ def test_deref_symlink():
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
del(cfg) del(cfg)
#assert w() is None
#assert x() is None
assert y() is None assert y() is None
assert z() is None assert z() is None
@ -333,7 +261,5 @@ def test_deref_dyn():
assert w() is not None assert w() is not None
assert x() is not None assert x() is not None
del(cfg) del(cfg)
#assert w() is None
#assert x() is None
assert y() is None assert y() is None
assert z() is None assert z() is None

View File

@ -9,7 +9,7 @@ from tiramisu import BoolOption, StrOption, ChoiceOption, IPOption, \
UnicodeOption, PortOption, BroadcastOption, DomainnameOption, \ UnicodeOption, PortOption, BroadcastOption, DomainnameOption, \
EmailOption, URLOption, UsernameOption, FilenameOption, SymLinkOption, \ EmailOption, URLOption, UsernameOption, FilenameOption, SymLinkOption, \
OptionDescription, DynOptionDescription, SynDynOption, submulti, Leadership, \ OptionDescription, DynOptionDescription, SynDynOption, submulti, Leadership, \
Config, Params, ParamOption, ParamValue, Calculation, calc_value Config, Params, ParamOption, ParamValue, ParamSuffix, ParamSelfOption, Calculation, calc_value
from tiramisu.error import PropertiesOptionError, ConfigError, ConflictError from tiramisu.error import PropertiesOptionError, ConfigError, ConflictError
from tiramisu.storage import list_sessions from tiramisu.storage import list_sessions
@ -28,7 +28,7 @@ def return_dynval(value='val', suffix=None):
return value return value
def return_list2(suffix=None): def return_list2(suffix):
return [str(suffix), 'val2'] return [str(suffix), 'val2']
@ -249,7 +249,7 @@ def test_callback_dyndescription():
def test_callback_list_dyndescription(): def test_callback_list_dyndescription():
st = StrOption('st', '', Calculation(return_list2), multi=True) st = StrOption('st', '', Calculation(return_list2, Params(ParamSuffix())), multi=True)
dod = DynOptionDescription('dod', '', [st], suffixes=Calculation(return_list)) dod = DynOptionDescription('dod', '', [st], suffixes=Calculation(return_list))
od = OptionDescription('od', '', [dod]) od = OptionDescription('od', '', [dod])
od2 = OptionDescription('od', '', [od]) od2 = OptionDescription('od', '', [od])
@ -675,7 +675,7 @@ def test_requires_dyndescription2():
def test_validator_dyndescription(): def test_validator_dyndescription():
val1 = StrOption('val1', '', ['val1', 'val2'], multi=True) val1 = StrOption('val1', '', ['val1', 'val2'], multi=True)
st = StrOption('st', '', validator=return_true, validator_params=Params((ParamValue('yes'),)), default='val') st = StrOption('st', '', validators=[Calculation(return_true, Params((ParamSelfOption(), ParamValue('yes'))))], default='val')
dod = DynOptionDescription('dod', '', [st], suffixes=Calculation(return_list)) dod = DynOptionDescription('dod', '', [st], suffixes=Calculation(return_list))
od = OptionDescription('od', '', [dod, val1]) od = OptionDescription('od', '', [dod, val1])
od2 = OptionDescription('od', '', [od]) od2 = OptionDescription('od', '', [od])
@ -735,108 +735,13 @@ def test_information_dyndescription_context():
assert api.information.get('testcfgod') == 'val3' assert api.information.get('testcfgod') == 'val3'
def test_consistency_dyndescription():
st1 = StrOption('st', '')
st2 = StrOption('st2', '')
dod = DynOptionDescription('dod', '', [st1, st2], suffixes=Calculation(return_list))
od1 = OptionDescription('od', '', [dod])
st1.impl_add_consistency('not_equal', st2)
od2 = OptionDescription('od', '', [od1])
api = Config(od2)
api.option('od.dodval1.stval1').value.set('yes')
raises(ValueError, "api.option('od.dodval1.st2val1').value.set('yes')")
api.option('od.dodval2.stval2').value.set('yes')
raises(ValueError, "api.option('od.dodval2.st2val2').value.set('yes')")
raises(ValueError, "api.option('od.dodval1.st2val1').value.set('yes')")
api.option('od.dodval2.stval2').value.reset()
raises(ValueError, "api.option('od.dodval1.st2val1').value.set('yes')")
api.option('od.dodval2.st2val2').value.set('yes')
raises(ValueError, "api.option('od.dodval2.stval2').value.set('yes')")
#
api.option('od.dodval1.stval1').value.reset()
api.option('od.dodval2.st2val2').value.reset()
api.option('od.dodval1.st2val1').value.set('yes')
raises(ValueError, "api.option('od.dodval1.stval1').value.set('yes')")
def test_consistency_dyndescription_default():
st = StrOption('st', '', 'yes')
st2 = StrOption('st2', '')
dod = DynOptionDescription('dod', '', [st, st2], suffixes=Calculation(return_list))
od = OptionDescription('od', '', [dod])
st.impl_add_consistency('not_equal', st2)
od2 = OptionDescription('od', '', [od])
api = Config(od2)
raises(ValueError, "api.option('od.dodval1.st2val1').value.set('yes')")
raises(ValueError, "api.option('od.dodval2.st2val2').value.set('yes')")
def test_consistency_dyndescription_default_multi2():
st = StrOption('st', '', ['yes'], multi=True)
st2 = StrOption('st2', '', ['yes'], multi=True)
dod = DynOptionDescription('dod', '', [st, st2], suffixes=Calculation(return_list))
dod
# FIXME raises(ValueError, "st.impl_add_consistency('not_equal', st2)")
def test_consistency_only_one_dyndescription():
st = StrOption('st', '')
st
st2 = StrOption('st2', '')
dod = DynOptionDescription('dod', '', [st2], suffixes=Calculation(return_list))
raises(ConfigError, "st.impl_add_consistency('not_equal', st2)")
raises(ConfigError, "st2.impl_add_consistency('not_equal', st)")
def test_consistency_became_dyndescription():
st = StrOption('st', '')
st2 = StrOption('st2', '')
st2.impl_add_consistency('not_equal', st)
od = DynOptionDescription('dod', '', [st2], suffixes=Calculation(return_list))
od2 = OptionDescription('od', '', [od, st])
od2
raises(ConfigError, "c = Config(od2)")
def test_consistency_became_dyndescription2():
st = StrOption('st', '')
st2 = StrOption('st2', '')
st.impl_add_consistency('not_equal', st2)
od = DynOptionDescription('dod', '', [st2], suffixes=Calculation(return_list))
od2 = OptionDescription('od', '', [od, st])
od2
raises(ConfigError, "c = Config(od2)")
def test_consistency_external_dyndescription():
st = StrOption('st', '')
st1 = StrOption('st1', '')
st2 = StrOption('st2', '')
dod = DynOptionDescription('dod', '', [st1, st2], suffixes=Calculation(return_list))
od = OptionDescription('od', '', [dod, st])
od
raises(ConfigError, "st.impl_add_consistency('not_equal', st2)")
def test_consistency_notsame_dyndescription():
st1 = StrOption('st1', '')
st2 = StrOption('st2', '')
dod = DynOptionDescription('dod', '', [st1, st2], suffixes=Calculation(return_list))
tst1 = StrOption('tst1', '')
tst2 = StrOption('tst2', '')
tdod = DynOptionDescription('tdod', '', [tst1, tst2], suffixes=Calculation(return_list))
od = OptionDescription('od', '', [dod, tdod])
od
raises(ConfigError, "st1.impl_add_consistency('not_equal', tst1)")
def test_all_dyndescription(): def test_all_dyndescription():
st = StrOption('st', '') st = StrOption('st', '')
ip = IPOption('ip', '') ip = IPOption('ip', '')
network = NetworkOption('network', '') network = NetworkOption('network', '')
netmask = NetmaskOption('netmask', '') netmask = NetmaskOption('netmask', '')
ch = ChoiceOption('ch', '', ('val1', 'val2', 'val3')) ch = ChoiceOption('ch', '', ('val1', 'val2', 'val3'))
ch1 = ChoiceOption('ch1', '', return_list) ch1 = ChoiceOption('ch1', '', Calculation(return_list))
boo = BoolOption('boo', '') boo = BoolOption('boo', '')
intr = IntOption('intr', '') intr = IntOption('intr', '')
floa = FloatOption('floa', '') floa = FloatOption('floa', '')
@ -925,34 +830,6 @@ def test_all_dyndescription():
assert api.option('dodval2.filenameval2').value.get() is None assert api.option('dodval2.filenameval2').value.get() is None
def test_consistency_ip_netmask_dyndescription():
ipa = IPOption('a', '')
netb = NetmaskOption('b', '')
dod = DynOptionDescription('dod', '', [ipa, netb], suffixes=Calculation(return_list))
netb.impl_add_consistency('ip_netmask', ipa)
od1 = OptionDescription('od', '', [dod])
cfg = Config(od1)
cfg.option('dodval1.aval1').value.set('192.168.1.1')
cfg.option('dodval1.bval1').value.set('255.255.255.0')
cfg.option('dodval2.aval2').value.set('192.168.1.2')
cfg.option('dodval2.bval2').value.set('255.255.255.128')
cfg.option('dodval2.bval2').value.set('255.255.255.0')
raises(ValueError, "cfg.option('dodval2.bval2').value.set('255.255.255.255')")
def test_consistency_ip_in_network_dyndescription():
neta = NetworkOption('a', '')
netb = NetmaskOption('b', '')
ipc = IPOption('c', '')
dod = DynOptionDescription('dod', '', [neta, netb, ipc], suffixes=Calculation(return_list))
ipc.impl_add_consistency('in_network', neta, netb)
od1 = OptionDescription('od', '', [dod])
cfg = Config(od1)
cfg.option('dodval1.aval1').value.set('192.168.1.0')
cfg.option('dodval1.bval1').value.set('255.255.255.0')
cfg.option('dodval1.cval1').value.set('192.168.1.1')
def test_leadership_dyndescription(): def test_leadership_dyndescription():
st1 = StrOption('st1', "", multi=True) st1 = StrOption('st1', "", multi=True)
st2 = StrOption('st2', "", multi=True) st2 = StrOption('st2', "", multi=True)

View File

@ -178,15 +178,6 @@ def test_force_store_value():
compare(conf.value.exportation(), (('wantref', 'wantref2', 'wantref3'), (None, None, None), (False, False, (False,)), ('forced', 'forced', 'forced'))) compare(conf.value.exportation(), (('wantref', 'wantref2', 'wantref3'), (None, None, None), (False, False, (False,)), ('forced', 'forced', 'forced')))
def test_force_store_value_no_requirement():
booloption = BoolOption('bool', 'Test boolean option', default=True)
try:
BoolOption('wantref', 'Test requires', default=False,
requires=({'option': booloption, 'expected': True, 'action': 'force_store_value'},))
except ValueError:
pass
def test_force_store_value_leadership_follower(): def test_force_store_value_leadership_follower():
b = IntOption('int', 'Test int option', multi=True) b = IntOption('int', 'Test int option', multi=True)
c = StrOption('str', 'Test string option', multi=True, properties=('force_store_value',)) c = StrOption('str', 'Test string option', multi=True, properties=('force_store_value',))

View File

@ -330,9 +330,9 @@ def test_groups_with_leader_default_value_2(config_type):
def test_groups_with_leader_hidden_in_config(): def test_groups_with_leader_hidden_in_config():
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True, properties=('hidden',)) ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True, properties=('hidden',)) netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True, properties=('hidden',))
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0], properties=('hidden',))
od = OptionDescription('root', '', [interface1]) od = OptionDescription('root', '', [interface1])
cfg = Config(od) cfg = Config(od)
cfg.property.read_write() cfg.property.read_write()
@ -412,22 +412,6 @@ def test_groups_with_leader_reset_out_of_range(config_type):
cfg.send() cfg.send()
def test_groups_with_leader_hidden_in_config3():
#if leader is hidden, follower are hidden too
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True, properties=('hidden',))
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
od = OptionDescription('root', '', [interface1])
cfg = Config(od)
cfg.property.read_write()
cfg.permissive.set(frozenset(['hidden']))
assert cfg.forcepermissive.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
cfg.forcepermissive.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1'])
assert cfg.forcepermissive.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()")
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
def test_allowed_groups(): def test_allowed_groups():
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True) ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True) netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
@ -449,7 +433,8 @@ def test_values_with_leader_disabled_leader(config_type):
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.230.145']) cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.230.145'])
cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set("192.168.230.145") cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set("192.168.230.145")
cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.reset() cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.reset()
cfg_ori.option('ip_admin_eth0.ip_admin_eth0').property.add('disabled') raises(LeadershipError, "cfg_ori.option('ip_admin_eth0.ip_admin_eth0').property.add('disabled')")
cfg_ori.option('ip_admin_eth0').property.add('disabled')
cfg = get_config(cfg_ori, config_type) cfg = get_config(cfg_ori, config_type)
if config_type != 'tiramisu-api': if config_type != 'tiramisu-api':
# FIXME # FIXME
@ -847,49 +832,7 @@ def test_follower_not_multi():
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True) ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau") netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau")
raises(ValueError, "Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])") raises(ValueError, "Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])")
#
def test_follower_not_same():
ip_admin_eth0 = IPOption('ip_admin_eth0', "ip réseau autorisé", multi=True, default=['1.1.1.1'])
netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
interface0 = Leadership('interface0', '', [ip_admin_eth0, netmask_admin_eth0])
ip_admin_eth1 = IPOption('ip_admin_eth1', "ip réseau autorisé", multi=True, default=['1.1.1.1'])
netmask_admin_eth1 = NetmaskOption('netmask_admin_eth1', "masque du sous-réseau", multi=True)
netmask_admin_eth1.impl_add_consistency('ip_netmask', ip_admin_eth0)
interface1 = Leadership('interface1', '', [ip_admin_eth1, netmask_admin_eth1])
od1 = OptionDescription('od', '', [interface0, interface1])
maconfig = OptionDescription('toto', '', [od1])
raises(ConfigError, "Config(maconfig)")
def test_follower_not_same_not_equal():
ip_admin_eth0 = IPOption('ip_admin_eth0', "ip réseau autorisé", multi=True, default=['1.1.1.1'])
netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
interface0 = Leadership('interface0', '', [ip_admin_eth0, netmask_admin_eth0])
ip_admin_eth1 = IPOption('ip_admin_eth1', "ip réseau autorisé", multi=True, default=['1.1.1.1'])
netmask_admin_eth1 = NetmaskOption('netmask_admin_eth1', "masque du sous-réseau", multi=True)
netmask_admin_eth1.impl_add_consistency('not_equal', netmask_admin_eth0)
interface1 = Leadership('interface1', '', [ip_admin_eth1, netmask_admin_eth1])
od1 = OptionDescription('od', '', [interface0, interface1])
maconfig = OptionDescription('toto', '', [od1])
cfg = Config(maconfig)
cfg.property.read_write()
def test_follower_consistency():
network_admin_eth1 = NetworkOption('network_admin_eth1', "ip réseau autorisé", multi=True, default=['1.1.1.1'])
netmask_admin_eth1 = NetmaskOption('netmask_admin_eth1', "masque du sous-réseau", multi=True)
netmask_admin_eth1.impl_add_consistency('network_netmask', network_admin_eth1)
interface1 = Leadership('interface1', '', [network_admin_eth1, netmask_admin_eth1])
od1 = OptionDescription('od', '', [interface1])
maconfig = OptionDescription('toto', '', [od1])
cfg = Config(maconfig)
cfg.property.read_write()
cfg.option('od.interface1.network_admin_eth1').value.set(['192.168.1.128', '192.168.2.0', '192.168.3.128'])
cfg.option('od.interface1.netmask_admin_eth1', 0).value.set('255.255.255.128')
cfg.option('od.interface1.netmask_admin_eth1', 1).value.set('255.255.255.0')
cfg.option('od.interface1.netmask_admin_eth1', 2).value.set('255.255.255.128')
cfg.option('od.interface1.network_admin_eth1').value.pop(0)
def test_follower_force_store_value(): def test_follower_force_store_value():

View File

@ -5,7 +5,8 @@ do_autopath()
from tiramisu.setting import groups, owners from tiramisu.setting import groups, owners
from tiramisu import IntOption, StrOption, NetworkOption, NetmaskOption, BoolOption, ChoiceOption, \ from tiramisu import IntOption, StrOption, NetworkOption, NetmaskOption, BoolOption, ChoiceOption, \
IPOption, OptionDescription, Leadership, Config, GroupConfig, MetaConfig, \ IPOption, OptionDescription, Leadership, Config, GroupConfig, MetaConfig, \
Calculation, Params, ParamOption, ParamValue, calc_value Calculation, Params, ParamOption, ParamValue, calc_value, ParamSelfOption, \
valid_network_netmask, valid_not_equal
from tiramisu.error import ConfigError, ConflictError, PropertiesOptionError, LeadershipError, APIError from tiramisu.error import ConfigError, ConflictError, PropertiesOptionError, LeadershipError, APIError
from tiramisu.storage import list_sessions from tiramisu.storage import list_sessions
from .config import config_type, get_config from .config import config_type, get_config
@ -719,9 +720,8 @@ def test_meta_force_default_and_dont_change():
def test_meta_properties_meta(): def test_meta_properties_meta():
ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1']) ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1'])
netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask", multi=True, properties=('disabled',)) netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask", multi=True, validators=[Calculation(valid_network_netmask, Params((ParamOption(ip_admin_eth0), ParamSelfOption())))])
netmask_admin_eth0.impl_add_consistency('network_netmask', ip_admin_eth0) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0], properties=('disabled',))
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
od = OptionDescription('root', '', [interface1]) od = OptionDescription('root', '', [interface1])
conf1 = Config(od, session_id='conf1') conf1 = Config(od, session_id='conf1')
conf2 = Config(od, session_id='conf2') conf2 = Config(od, session_id='conf2')
@ -734,8 +734,7 @@ def test_meta_properties_meta():
def test_meta_exception_meta(): def test_meta_exception_meta():
ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1']) ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1'])
netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask", Calculation(raise_exception), multi=True) netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask", Calculation(raise_exception), multi=True, validators=[Calculation(valid_network_netmask, Params((ParamOption(ip_admin_eth0), ParamSelfOption())))])
netmask_admin_eth0.impl_add_consistency('network_netmask', ip_admin_eth0)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
od = OptionDescription('root', '', [interface1]) od = OptionDescription('root', '', [interface1])
conf1 = Config(od, session_id='conf1') conf1 = Config(od, session_id='conf1')
@ -753,8 +752,7 @@ def test_meta_properties_requires1():
kwargs={'condition': ParamOption(opt1, todict=True), kwargs={'condition': ParamOption(opt1, todict=True),
'expected': ParamValue(False)})) 'expected': ParamValue(False)}))
od2 = OptionDescription('od2', "", [opt2], properties=(disabled_property,)) od2 = OptionDescription('od2', "", [opt2], properties=(disabled_property,))
opt3 = BoolOption('opt3', '') opt3 = BoolOption('opt3', '', validators=[Calculation(valid_not_equal, Params((ParamOption(opt2), ParamSelfOption())))])
opt2.impl_add_consistency('not_equal', opt3)
od = OptionDescription('root', '', [opt1, od2, opt3]) od = OptionDescription('root', '', [opt1, od2, opt3])
conf1 = Config(od, session_id='conf1') conf1 = Config(od, session_id='conf1')
conf1.property.read_write() conf1.property.read_write()
@ -775,8 +773,7 @@ def test_meta_properties_requires_mandatory():
'expected': ParamValue('yes'), 'expected': ParamValue('yes'),
'default': ParamValue(None)})) 'default': ParamValue(None)}))
ip_eth0 = IPOption('ip_eth0', "ip", Calculation(return_condition, Params(kwargs={'val': ParamOption(ip_address), 'condition': ParamOption(eth0_method), 'expected': ParamValue('dhcp')})), properties=(mandatory_property,)) ip_eth0 = IPOption('ip_eth0', "ip", Calculation(return_condition, Params(kwargs={'val': ParamOption(ip_address), 'condition': ParamOption(eth0_method), 'expected': ParamValue('dhcp')})), properties=(mandatory_property,))
ip_gw = IPOption('ip_gw', 'gw') ip_gw = IPOption('ip_gw', 'gw', validators=[Calculation(valid_not_equal, Params((ParamOption(ip_eth0), ParamSelfOption())))])
ip_gw.impl_add_consistency('not_equal', ip_eth0)
od = OptionDescription('root', '', [ip_gw, probes, eth0_method, ip_address, ip_eth0]) od = OptionDescription('root', '', [ip_gw, probes, eth0_method, ip_address, ip_eth0])
conf1 = Config(od, session_id='conf1') conf1 = Config(od, session_id='conf1')
conf1.property.read_write() conf1.property.read_write()

View File

@ -6,7 +6,8 @@ from py.test import raises
from tiramisu.setting import groups, owners from tiramisu.setting import groups, owners
from tiramisu import IntOption, StrOption, NetworkOption, NetmaskOption, \ from tiramisu import IntOption, StrOption, NetworkOption, NetmaskOption, \
OptionDescription, Leadership, Config, GroupConfig, MixConfig, \ OptionDescription, Leadership, Config, GroupConfig, MixConfig, \
MetaConfig, Params, ParamOption, ParamValue, Calculation MetaConfig, Params, ParamOption, ParamValue, ParamSelfOption, Calculation, \
valid_network_netmask
from tiramisu.error import ConfigError, ConflictError, PropertiesOptionError, LeadershipError, APIError from tiramisu.error import ConfigError, ConflictError, PropertiesOptionError, LeadershipError, APIError
from tiramisu.storage import list_sessions from tiramisu.storage import list_sessions
@ -589,9 +590,8 @@ def test_mix_force_default_and_dont_change():
def test_mix_properties_mix(): def test_mix_properties_mix():
ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1']) ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1'])
netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask", multi=True, properties=('disabled',)) netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask", multi=True, validators=[Calculation(valid_network_netmask, Params((ParamOption(ip_admin_eth0), ParamSelfOption())))])
netmask_admin_eth0.impl_add_consistency('network_netmask', ip_admin_eth0) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0], properties=('disabled',))
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
od = OptionDescription('root', '', [interface1]) od = OptionDescription('root', '', [interface1])
conf1 = Config(od, session_id='conf1') conf1 = Config(od, session_id='conf1')
conf2 = Config(od, session_id='conf2') conf2 = Config(od, session_id='conf2')
@ -604,8 +604,7 @@ def test_mix_properties_mix():
def test_mix_exception_mix(): def test_mix_exception_mix():
ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1']) ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1'])
netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask", Calculation(raise_exception), multi=True) netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask", Calculation(raise_exception), multi=True, validators=[Calculation(valid_network_netmask, Params((ParamOption(ip_admin_eth0), ParamSelfOption())))])
netmask_admin_eth0.impl_add_consistency('network_netmask', ip_admin_eth0)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
od = OptionDescription('root', '', [interface1]) od = OptionDescription('root', '', [interface1])
conf1 = Config(od, session_id='conf1') conf1 = Config(od, session_id='conf1')

View File

@ -10,7 +10,8 @@ from tiramisu.config import KernelConfig
from tiramisu.setting import groups, owners from tiramisu.setting import groups, owners
from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \ from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \
StrOption, OptionDescription, SymLinkOption, IPOption, NetmaskOption, Leadership, \ StrOption, OptionDescription, SymLinkOption, IPOption, NetmaskOption, Leadership, \
undefined, Calculation, Params, ParamOption, ParamValue, ParamContext, ParamIndex, calc_value undefined, Calculation, Params, ParamOption, ParamValue, ParamContext, ParamIndex, calc_value, \
valid_ip_netmask, ParamSelfOption
from tiramisu.error import PropertiesOptionError, ConflictError, LeadershipError, ConfigError from tiramisu.error import PropertiesOptionError, ConflictError, LeadershipError, ConfigError
from tiramisu.i18n import _ from tiramisu.i18n import _
from tiramisu.storage import list_sessions from tiramisu.storage import list_sessions
@ -252,23 +253,6 @@ def test_freeze_and_has_callback():
raises(PropertiesOptionError, "cfg.option('gc.dummy').value.set(True)") raises(PropertiesOptionError, "cfg.option('gc.dummy').value.set(True)")
def test_callback_legacy(config_type):
val1 = StrOption('val1', "", callback=return_val)
val2 = StrOption('val2', "")
maconfig = OptionDescription('rootconfig', '', [val1, val2])
cfg = Config(maconfig)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
if config_type != 'tiramisu-api':
assert cfg.option('val1').option.callbacks() != (None, None)
assert cfg.option('val2').option.callbacks() == (None, None)
assert cfg.option('val1').value.get() == 'val'
cfg.option('val1').value.set('new-val')
assert cfg.option('val1').value.get() == 'new-val'
cfg.option('val1').value.reset()
assert cfg.option('val1').value.get() == 'val'
def test_callback(config_type): def test_callback(config_type):
val1 = StrOption('val1', "", Calculation(return_val)) val1 = StrOption('val1', "", Calculation(return_val))
val2 = StrOption('val2', "") val2 = StrOption('val2', "")
@ -283,10 +267,6 @@ def test_callback(config_type):
assert cfg.option('val1').value.get() == 'val' assert cfg.option('val1').value.get() == 'val'
def test_callback_params_without_callback():
raises(ValueError, "StrOption('val2', '', callback_params=Params(ParamValue('yes')))")
def test_params(): def test_params():
raises(ValueError, "Params([ParamContext()])") raises(ValueError, "Params([ParamContext()])")
raises(ValueError, "Params('str')") raises(ValueError, "Params('str')")
@ -301,28 +281,6 @@ def test_param_option():
raises(AssertionError, "ParamOption(val1, 'str')") raises(AssertionError, "ParamOption(val1, 'str')")
def test_callback_invalid_legacy():
raises(AssertionError, 'val1 = StrOption("val1", "", callback="string")')
raises(AssertionError, 'val1 = StrOption("val1", "", callback=return_val, callback_params="string")')
val1 = StrOption('val1', "", 'val')
val1
raises(AssertionError, "StrOption('val2', '', callback=return_value, callback_params={'': 'string'})")
raises(AssertionError, "StrOption('val4', '', callback=return_value, callback_params={'value': (('string', False),)})")
raises(AssertionError, "StrOption('val4', '', callback=return_value, callback_params={'value': ((val1, 'string'),)})")
raises(AssertionError, "StrOption('val4', '', callback=return_value, callback_params={'value': ((val1, False, 'unknown'),)})")
raises(AssertionError, "StrOption('val4', '', callback=return_value, callback_params={'value': ((val1,),)})")
def test_callback_with_context_legacy():
context = ParamContext()
value = ParamValue('string')
params = Params((context,), {'value': value})
val1 = StrOption("val1", "", callback=is_config, callback_params=params)
maconfig = OptionDescription('rootconfig', '', [val1])
cfg = Config(maconfig)
assert cfg.option('val1').value.get() == 'yes'
def test_callback_with_context(): def test_callback_with_context():
context = ParamContext() context = ParamContext()
value = ParamValue('string') value = ParamValue('string')
@ -333,15 +291,6 @@ def test_callback_with_context():
assert cfg.option('val1').value.get() == 'yes' assert cfg.option('val1').value.get() == 'yes'
def test_callback_with_context_named_legacy():
context = ParamContext()
params = Params(kwargs={'config': context})
val1 = StrOption("val1", "", callback=is_config, callback_params=params)
maconfig = OptionDescription('rootconfig', '', [val1])
cfg = Config(maconfig)
assert cfg.option('val1').value.get() == 'yes'
def test_callback_with_context_named(): def test_callback_with_context_named():
context = ParamContext() context = ParamContext()
params = Params(kwargs={'config': context}) params = Params(kwargs={'config': context})
@ -351,14 +300,6 @@ def test_callback_with_context_named():
assert cfg.option('val1').value.get() == 'yes' assert cfg.option('val1').value.get() == 'yes'
def test_callback_with_error_legacy(config_type):
val1 = StrOption("val1", "", callback=is_config, callback_params=Params(ParamValue('string'), kwargs={'value': ParamValue('string')}))
maconfig = OptionDescription('rootconfig', '', [val1])
cfg = Config(maconfig)
cfg = get_config(cfg, config_type)
assert cfg.option('val1').value.get() == 'no'
def test_callback_with_error(config_type): def test_callback_with_error(config_type):
val1 = StrOption("val1", "", Calculation(is_config, Params(ParamValue('string'), kwargs={'value': ParamValue('string')}))) val1 = StrOption("val1", "", Calculation(is_config, Params(ParamValue('string'), kwargs={'value': ParamValue('string')})))
maconfig = OptionDescription('rootconfig', '', [val1]) maconfig = OptionDescription('rootconfig', '', [val1])
@ -367,21 +308,6 @@ def test_callback_with_error(config_type):
assert cfg.option('val1').value.get() == 'no' assert cfg.option('val1').value.get() == 'no'
def test_callback_with_context_value_legacy():
context = ParamContext()
params = Params((context,))
val1 = StrOption("val1", "")
val2 = StrOption("val2", "", callback=ret_from_config, callback_params=params)
maconfig = OptionDescription('rootconfig', '', [val1, val2])
cfg = Config(maconfig)
cfg.option('val1').value.set('yes')
assert cfg.option('val1').value.get() == 'yes'
assert cfg.option('val2').value.get() == 'yes'
cfg.option('val1').value.set('no')
assert cfg.option('val1').value.get() == 'no'
assert cfg.option('val2').value.get() == 'no'
def test_callback_with_context_value(): def test_callback_with_context_value():
context = ParamContext() context = ParamContext()
params = Params((context,)) params = Params((context,))
@ -397,31 +323,6 @@ def test_callback_with_context_value():
assert cfg.option('val2').value.get() == 'no' assert cfg.option('val2').value.get() == 'no'
def test_callback_value_legacy(config_type):
val1 = StrOption('val1', "", 'val')
val2 = StrOption('val2', "", callback=return_value, callback_params=Params(ParamOption(val1)))
val3 = StrOption('val3', "", callback=return_value, callback_params=Params(ParamValue('yes')))
val4 = StrOption('val4', "", callback=return_value, callback_params=Params(kwargs={'value': ParamOption(val1)}))
val5 = StrOption('val5', "", callback=return_value, callback_params=Params(ParamValue('yes')))
maconfig = OptionDescription('rootconfig', '', [val1, val2, val3, val4, val5])
cfg = Config(maconfig)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('val1').value.get() == 'val'
assert cfg.option('val2').value.get() == 'val'
assert cfg.option('val4').value.get() == 'val'
cfg.option('val1').value.set('new-val')
assert cfg.option('val1').value.get() == 'new-val'
assert cfg.option('val2').value.get() == 'new-val'
assert cfg.option('val4').value.get() == 'new-val'
cfg.option('val1').value.reset()
assert cfg.option('val1').value.get() == 'val'
assert cfg.option('val2').value.get() == 'val'
assert cfg.option('val3').value.get() == 'yes'
assert cfg.option('val4').value.get() == 'val'
assert cfg.option('val5').value.get() == 'yes'
def test_callback_value(config_type): def test_callback_value(config_type):
val1 = StrOption('val1', "", 'val') val1 = StrOption('val1', "", 'val')
val2 = StrOption('val2', "", Calculation(return_value, Params(ParamOption(val1)))) val2 = StrOption('val2', "", Calculation(return_value, Params(ParamOption(val1))))
@ -447,25 +348,6 @@ def test_callback_value(config_type):
assert cfg.option('val5').value.get() == 'yes' assert cfg.option('val5').value.get() == 'yes'
def test_callback_value_tuple_legacy(config_type):
val1 = StrOption('val1', "", 'val1')
val2 = StrOption('val2', "", 'val2')
val3 = StrOption('val3', "", callback=return_concat, callback_params=Params((ParamOption(val1), ParamOption(val2))))
val4 = StrOption('val4', "", callback=return_concat, callback_params=Params((ParamValue('yes'), ParamValue('no'))))
maconfig = OptionDescription('rootconfig', '', [val1, val2, val3, val4])
cfg = Config(maconfig)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('val1').value.get() == 'val1'
assert cfg.option('val2').value.get() == 'val2'
assert cfg.option('val3').value.get() == 'val1.val2'
assert cfg.option('val4').value.get() == 'yes.no'
cfg.option('val1').value.set('new-val')
assert cfg.option('val3').value.get() == 'new-val.val2'
cfg.option('val1').value.reset()
assert cfg.option('val3').value.get() == 'val1.val2'
def test_callback_value_tuple(config_type): def test_callback_value_tuple(config_type):
val1 = StrOption('val1', "", 'val1') val1 = StrOption('val1', "", 'val1')
val2 = StrOption('val2', "", 'val2') val2 = StrOption('val2', "", 'val2')
@ -485,20 +367,6 @@ def test_callback_value_tuple(config_type):
assert cfg.option('val3').value.get() == 'val1.val2' assert cfg.option('val3').value.get() == 'val1.val2'
def test_callback_value_force_permissive2_legacy(config_type):
val1 = StrOption('val1', "", 'val', properties=('disabled',))
val2 = StrOption('val2', "", callback=return_value, callback_params=Params(ParamOption(val1)))
val3 = StrOption('val3', "", callback=return_value, callback_params=Params(ParamOption(val1, True)))
maconfig = OptionDescription('rootconfig', '', [val1, val2, val3])
cfg = Config(maconfig)
cfg.property.read_only()
if config_type != 'tiramisu-api':
raises(ConfigError, "cfg.option('val2').value.get()")
cfg.option('val3').value.get() is None
else:
raises(ConfigError, "get_config(cfg, config_type)")
def test_callback_value_force_permissive2(config_type): def test_callback_value_force_permissive2(config_type):
val1 = StrOption('val1', "", 'val', properties=('disabled',)) val1 = StrOption('val1', "", 'val', properties=('disabled',))
val2 = StrOption('val2', "", Calculation(return_value, Params(ParamOption(val1)))) val2 = StrOption('val2', "", Calculation(return_value, Params(ParamOption(val1))))
@ -513,17 +381,6 @@ def test_callback_value_force_permissive2(config_type):
raises(ConfigError, "get_config(cfg, config_type)") raises(ConfigError, "get_config(cfg, config_type)")
def test_callback_value_force_permissive_kwargs_legacy():
val1 = StrOption('val1', "", 'val', properties=('disabled',))
val2 = StrOption('val2', "", callback=return_value, callback_params=Params(value=ParamOption(val1)))
val3 = StrOption('val3', "", callback=return_value, callback_params=Params(value=ParamOption(val1, True)))
maconfig = OptionDescription('rootconfig', '', [val1, val2, val3])
cfg = Config(maconfig)
cfg.property.read_only()
raises(ConfigError, "cfg.option('val2').value.get()")
cfg.option('val3').value.get() is None
def test_callback_value_force_permissive_kwargs(): def test_callback_value_force_permissive_kwargs():
val1 = StrOption('val1', "", 'val', properties=('disabled',)) val1 = StrOption('val1', "", 'val', properties=('disabled',))
val2 = StrOption('val2', "", Calculation(return_value, Params(value=ParamOption(val1)))) val2 = StrOption('val2', "", Calculation(return_value, Params(value=ParamOption(val1))))
@ -535,25 +392,6 @@ def test_callback_value_force_permissive_kwargs():
cfg.option('val3').value.get() is None cfg.option('val3').value.get() is None
def test_callback_symlink_legacy(config_type):
val1 = StrOption('val1', "", 'val')
val2 = SymLinkOption('val2', val1)
val3 = StrOption('val3', "", callback=return_value, callback_params=Params(ParamOption(val2)))
maconfig = OptionDescription('rootconfig', '', [val1, val2, val3])
cfg = Config(maconfig)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('val1').value.get() == 'val'
assert cfg.option('val2').value.get() == 'val'
assert cfg.option('val3').value.get() == 'val'
cfg.option('val1').value.set('new-val')
assert cfg.option('val1').value.get() == 'new-val'
assert cfg.option('val3').value.get() == 'new-val'
cfg.option('val1').value.reset()
assert cfg.option('val1').value.get() == 'val'
assert cfg.option('val3').value.get() == 'val'
def test_callback_symlink(config_type): def test_callback_symlink(config_type):
val1 = StrOption('val1', "", 'val') val1 = StrOption('val1', "", 'val')
val2 = SymLinkOption('val2', val1) val2 = SymLinkOption('val2', val1)
@ -573,14 +411,6 @@ def test_callback_symlink(config_type):
assert cfg.option('val3').value.get() == 'val' assert cfg.option('val3').value.get() == 'val'
def test_callback_list_legacy():
val1 = StrOption('val1', "", callback=return_list)
maconfig = OptionDescription('rootconfig', '', [val1])
cfg = Config(maconfig)
cfg.property.read_write()
raises(ValueError, "cfg.option('val1').value.get()")
def test_callback_list(): def test_callback_list():
val1 = StrOption('val1', "", Calculation(return_list)) val1 = StrOption('val1', "", Calculation(return_list))
maconfig = OptionDescription('rootconfig', '', [val1]) maconfig = OptionDescription('rootconfig', '', [val1])
@ -589,18 +419,6 @@ def test_callback_list():
raises(ValueError, "cfg.option('val1').value.get()") raises(ValueError, "cfg.option('val1').value.get()")
def test_callback_list2_legacy():
val1 = StrOption('val1', "", callback=return_list)
#val2 = StrOption('val2', "", callback=return_value, callback_params=Params(ParamOption(val1)))
val2 = StrOption('val2', "", callback=return_value, callback_params=Params(ParamOption(val1))) # , 'forcepermissive': False}]})
maconfig = OptionDescription('rootconfig', '', [val1, val2])
cfg = Config(maconfig)
cfg.property.read_write()
raises(ValueError, "cfg.option('val1').value.get()")
#cfg.val2
raises(ValueError, "cfg.option('val2').value.get()")
def test_callback_list2(): def test_callback_list2():
val1 = StrOption('val1', "", Calculation(return_list)) val1 = StrOption('val1', "", Calculation(return_list))
val2 = StrOption('val2', "", Calculation(return_value, Params(ParamOption(val1)))) val2 = StrOption('val2', "", Calculation(return_value, Params(ParamOption(val1))))
@ -612,21 +430,6 @@ def test_callback_list2():
raises(ValueError, "cfg.option('val2').value.get()") raises(ValueError, "cfg.option('val2').value.get()")
def test_callback_multi_legacy(config_type):
val1 = StrOption('val1', "", callback=return_val, multi=True)
maconfig = OptionDescription('rootconfig', '', [val1])
cfg = Config(maconfig)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('val1').value.get() == ['val']
cfg.option('val1').value.set(['new-val'])
assert cfg.option('val1').value.get() == ['new-val']
cfg.option('val1').value.set(['new-val', 'new-val2'])
assert cfg.option('val1').value.get() == ['new-val', 'new-val2']
cfg.option('val1').value.reset()
assert cfg.option('val1').value.get() == ['val']
def test_callback_multi(config_type): def test_callback_multi(config_type):
val1 = StrOption('val1', "", [Calculation(return_val)], multi=True) val1 = StrOption('val1', "", [Calculation(return_val)], multi=True)
maconfig = OptionDescription('rootconfig', '', [val1]) maconfig = OptionDescription('rootconfig', '', [val1])
@ -642,41 +445,6 @@ def test_callback_multi(config_type):
assert cfg.option('val1').value.get() == ['val'] assert cfg.option('val1').value.get() == ['val']
def test_callback_multi_value_legacy(config_type):
val1 = StrOption('val1', "", ['val'], multi=True)
option = ParamOption(val1)
params1 = Params((option,))
value = ParamValue('yes')
params2 = Params((value,))
params3 = Params((option, value))
val2 = StrOption('val2', "", multi=True, callback=return_value, callback_params=params1)
val3 = StrOption('val3', "", multi=True, callback=return_value, callback_params=params2)
val4 = StrOption('val4', "", multi=True, callback=return_list2, callback_params=params3)
maconfig = OptionDescription('rootconfig', '', [val1, val2, val3, val4])
cfg = Config(maconfig)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('val1').value.get() == ['val']
assert cfg.option('val2').value.get() == ['val']
assert cfg.option('val4').value.get() == ['val', 'yes']
cfg.option('val1').value.set(['new-val'])
assert cfg.option('val1').value.get() == ['new-val']
assert cfg.option('val2').value.get() == ['new-val']
assert cfg.option('val4').value.get() == ['new-val', 'yes']
cfg.option('val1').value.set(['new-val', 'new-val2'])
assert cfg.option('val1').value.get() == ['new-val', 'new-val2']
assert cfg.option('val2').value.get() == ['new-val', 'new-val2']
assert cfg.option('val4').value.get() == ['new-val', 'new-val2', 'yes']
cfg.option('val1').value.reset()
assert cfg.option('val1').value.get() == ['val']
assert cfg.option('val2').value.get() == ['val']
assert cfg.option('val3').value.get() == ['yes']
assert cfg.option('val4').value.get() == ['val', 'yes']
cfg.option('val2').value.set(['val', 'new'])
assert cfg.option('val1').value.get() == ['val']
assert cfg.option('val2').value.get() == ['val', 'new']
def test_callback_multi_value(config_type): def test_callback_multi_value(config_type):
val1 = StrOption('val1', "", ['val'], multi=True) val1 = StrOption('val1', "", ['val'], multi=True)
option = ParamOption(val1) option = ParamOption(val1)
@ -712,21 +480,6 @@ def test_callback_multi_value(config_type):
assert cfg.option('val2').value.get() == ['val', 'new'] assert cfg.option('val2').value.get() == ['val', 'new']
def test_callback_multi_list_legacy(config_type):
val1 = StrOption('val1', "", callback=return_list, multi=True)
maconfig = OptionDescription('rootconfig', '', [val1])
cfg = Config(maconfig)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('val1').value.get() == ['val', 'val']
cfg.option('val1').value.set(['new-val'])
assert cfg.option('val1').value.get() == ['new-val']
cfg.option('val1').value.set(['new-val', 'new-val2'])
assert cfg.option('val1').value.get() == ['new-val', 'new-val2']
cfg.option('val1').value.reset()
assert cfg.option('val1').value.get() == ['val', 'val']
def test_callback_multi_list(config_type): def test_callback_multi_list(config_type):
val1 = StrOption('val1', "", Calculation(return_list), multi=True) val1 = StrOption('val1', "", Calculation(return_list), multi=True)
maconfig = OptionDescription('rootconfig', '', [val1]) maconfig = OptionDescription('rootconfig', '', [val1])
@ -742,15 +495,6 @@ def test_callback_multi_list(config_type):
assert cfg.option('val1').value.get() == ['val', 'val'] assert cfg.option('val1').value.get() == ['val', 'val']
def test_callback_multi_list_extend_legacy(config_type):
val1 = StrOption('val1', "", callback=return_list2, callback_params=Params((ParamValue(['1', '2', '3']), ParamValue(['4', '5']))), multi=True)
maconfig = OptionDescription('rootconfig', '', [val1])
cfg = Config(maconfig)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('val1').value.get() == ['1', '2', '3', '4', '5']
def test_callback_multi_list_extend(config_type): def test_callback_multi_list_extend(config_type):
val1 = StrOption('val1', "", Calculation(return_list2, Params((ParamValue(['1', '2', '3']), ParamValue(['4', '5'])))), multi=True) val1 = StrOption('val1', "", Calculation(return_list2, Params((ParamValue(['1', '2', '3']), ParamValue(['4', '5'])))), multi=True)
maconfig = OptionDescription('rootconfig', '', [val1]) maconfig = OptionDescription('rootconfig', '', [val1])
@ -760,18 +504,6 @@ def test_callback_multi_list_extend(config_type):
assert cfg.option('val1').value.get() == ['1', '2', '3', '4', '5'] assert cfg.option('val1').value.get() == ['1', '2', '3', '4', '5']
def test_callback_multi_callback_legacy(config_type):
val1 = StrOption('val1', "", multi=True, callback=return_val)
interface1 = OptionDescription('val1', '', [val1])
maconfig = OptionDescription('rootconfig', '', [interface1])
cfg = Config(maconfig)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('val1.val1').value.get() == ['val']
cfg.option('val1.val1').value.set(['val1', undefined])
assert cfg.option('val1.val1').value.get() == ['val1', 'val']
def test_callback_multi_callback(config_type): def test_callback_multi_callback(config_type):
val1 = StrOption('val1', "", [Calculation(return_val)], multi=True) val1 = StrOption('val1', "", [Calculation(return_val)], multi=True)
interface1 = OptionDescription('val1', '', [val1]) interface1 = OptionDescription('val1', '', [val1])
@ -796,21 +528,6 @@ def test_callback_multi_callback_default(config_type):
assert cfg.option('val1.val1').value.get() == ['val1', 'val'] assert cfg.option('val1.val1').value.get() == ['val1', 'val']
def test_callback_leader_and_followers_leader_legacy(config_type):
val1 = StrOption('val1', "", multi=True, callback=return_val)
val2 = StrOption('val2', "", multi=True)
interface1 = Leadership('val1', '', [val1, val2])
maconfig = OptionDescription('rootconfig', '', [interface1])
cfg = Config(maconfig)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('val1.val1').value.get() == ['val']
cfg.option('val1.val1').value.set([undefined, undefined])
assert cfg.option('val1.val1').value.get() == ['val', 'val']
assert cfg.option('val1.val2', 0).value.get() == None
assert cfg.option('val1.val2', 1).value.get() == None
def test_callback_leader_and_followers_leader(config_type): def test_callback_leader_and_followers_leader(config_type):
val1 = StrOption('val1', "", default=[Calculation(return_val)], default_multi=Calculation(return_val), multi=True) val1 = StrOption('val1', "", default=[Calculation(return_val)], default_multi=Calculation(return_val), multi=True)
val2 = StrOption('val2', "", multi=True) val2 = StrOption('val2', "", multi=True)
@ -826,30 +543,6 @@ def test_callback_leader_and_followers_leader(config_type):
assert cfg.option('val1.val2', 1).value.get() == None assert cfg.option('val1.val2', 1).value.get() == None
def test_callback_follower_legacy(config_type):
val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", multi=True, callback=return_value3, callback_params=Params(ParamValue(['string', 'new'])))
interface1 = Leadership('val1', '', [val1, val2])
maconfig = OptionDescription('rootconfig', '', [interface1])
cfg = Config(maconfig)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('val1.val1').value.set(['val'])
assert cfg.option('val1.val2', 0).value.get() == 'string'
cfg.option('val1.val1').value.set(['val', 'val1'])
assert cfg.option('val1.val2', 0).value.get() == 'string'
assert cfg.option('val1.val2', 1).value.get() == 'new'
cfg.option('val1.val1').value.set(['val', 'val1', 'val2'])
assert cfg.option('val1.val2', 0).value.get() == 'string'
assert cfg.option('val1.val2', 1).value.get() == 'new'
assert cfg.option('val1.val2', 2).value.get() == None
cfg.option('val1.val1').value.set(['val', 'val1', 'val2', 'val3'])
assert cfg.option('val1.val2', 0).value.get() == 'string'
assert cfg.option('val1.val2', 1).value.get() == 'new'
assert cfg.option('val1.val2', 2).value.get() == None
assert cfg.option('val1.val2', 3).value.get() == None
def test_callback_follower(config_type): def test_callback_follower(config_type):
val1 = StrOption('val1', "", multi=True) val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", Calculation(return_value3, Params(ParamValue(['string', 'new']), {'index': ParamIndex()})), multi=True) val2 = StrOption('val2', "", Calculation(return_value3, Params(ParamValue(['string', 'new']), {'index': ParamIndex()})), multi=True)
@ -874,22 +567,6 @@ def test_callback_follower(config_type):
assert cfg.option('val1.val2', 3).value.get() == None assert cfg.option('val1.val2', 3).value.get() == None
def test_callback_leader_and_followers_leader2_legacy(config_type):
val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", multi=True, default_multi='val2')
val3 = StrOption('val3', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val2)))
val4 = StrOption('val4', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val3)))
interface1 = Leadership('val1', '', [val1, val2, val3, val4])
maconfig = OptionDescription('rootconfig', '', [interface1])
cfg = Config(maconfig)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('val1.val1').value.set(['val'])
assert cfg.option('val1.val4', 0).value.get() == 'val2'
assert cfg.option('val1.val3', 0).value.get() == 'val2'
assert cfg.option('val1.val2', 0).value.get() == 'val2'
def test_callback_leader_and_followers_leader2(config_type): def test_callback_leader_and_followers_leader2(config_type):
val1 = StrOption('val1', "", multi=True) val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", multi=True, default_multi='val2') val2 = StrOption('val2', "", multi=True, default_multi='val2')
@ -906,36 +583,6 @@ def test_callback_leader_and_followers_leader2(config_type):
assert cfg.option('val1.val2', 0).value.get() == 'val2' assert cfg.option('val1.val2', 0).value.get() == 'val2'
def test_callback_leader_and_followers_leader_mandatory1_legacy(config_type):
val = StrOption('val', "", default='val')
val1 = StrOption('val1', "", multi=True, callback=return_value2, callback_params=Params(ParamOption(val)), properties=('mandatory',))
val3 = StrOption('val3', "", multi=True, callback=return_index, callback_params=Params(ParamOption(val1)), properties=('mandatory',))
val4 = StrOption('val4', "", multi=True, callback=return_index, callback_params=Params(ParamOption(val1)), properties=('mandatory',))
interface1 = Leadership('val1', '', [val1, val3, val4])
maconfig = OptionDescription('rootconfig', '', [val, interface1])
cfg_ori = Config(maconfig)
cfg_ori.property.read_only()
cfg = get_config(cfg_ori, config_type)
assert cfg.option('val1.val3', 0).value.get() == 'val'
assert cfg.option('val1.val4', 0).value.get() == 'val'
assert cfg.option('val1.val1').value.get() == ['val']
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.read_write()
cfg = get_config(cfg_ori, config_type)
cfg.option('val1.val1').value.set([undefined, 'val3'])
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.read_only()
cfg = get_config(cfg_ori, config_type)
assert cfg.option('val1.val1').value.get() == ['val', 'val3']
assert cfg.option('val1.val3', 0).value.get() == 'val'
if config_type != 'tiramisu-api':
# FIXME
raises(PropertiesOptionError, "cfg.option('val1.val3', 1).value.get()")
raises(PropertiesOptionError, "cfg.option('val1.val4', 1).value.get()")
def test_callback_leader_and_followers_leader_mandatory1(config_type): def test_callback_leader_and_followers_leader_mandatory1(config_type):
val = StrOption('val', "", default='val') val = StrOption('val', "", default='val')
val1 = StrOption('val1', "", Calculation(return_value2, Params(ParamOption(val))), properties=('mandatory',), multi=True) val1 = StrOption('val1', "", Calculation(return_value2, Params(ParamOption(val))), properties=('mandatory',), multi=True)
@ -966,39 +613,6 @@ def test_callback_leader_and_followers_leader_mandatory1(config_type):
raises(PropertiesOptionError, "cfg.option('val1.val4', 1).value.get()") raises(PropertiesOptionError, "cfg.option('val1.val4', 1).value.get()")
def test_callback_leader_and_followers_leader_mandatory2_legacy(config_type):
val = StrOption('val', "", default='val')
val_ = StrOption('val_', "", default='val_')
val1 = StrOption('val1', "", multi=True, callback=return_index, callback_params=Params(ParamOption(val), {'val2': ParamOption(val_)}), properties=('mandatory',))
val3 = StrOption('val3', "", multi=True, callback=return_index, callback_params=Params(ParamOption(val1), {'val2': ParamOption(val_)}), properties=('mandatory',))
val4 = StrOption('val4', "", multi=True, callback=return_index, callback_params=Params(ParamOption(val1), {'val2': ParamOption(val_)}), properties=('mandatory',))
interface1 = Leadership('val1', '', [val1, val3, val4])
maconfig = OptionDescription('rootconfig', '', [val, val_, interface1])
cfg_ori = Config(maconfig)
cfg_ori.property.read_only()
cfg = get_config(cfg_ori, config_type)
assert cfg.option('val1.val3', 0).value.get() == 'val'
assert cfg.option('val1.val3', 1).value.get() == 'val_'
assert cfg.option('val1.val4', 0).value.get() == 'val'
assert cfg.option('val1.val4', 1).value.get() == 'val_'
assert cfg.option('val1.val1').value.get() == ['val', 'val_']
cfg_ori.property.read_write()
cfg = get_config(cfg_ori, config_type)
cfg.option('val1.val1').value.set(['val', 'val_', 'val3'])
assert cfg.option('val1.val1').value.get() == ['val', 'val_', 'val3']
cfg_ori.property.read_only()
cfg = get_config(cfg_ori, config_type)
assert cfg.option('val1.val3', 0).value.get() == 'val'
assert cfg.option('val1.val3', 1).value.get() == 'val_'
assert cfg.option('val1.val4', 0).value.get() == 'val'
assert cfg.option('val1.val4', 1).value.get() == 'val_'
if config_type != 'tiramisu-api':
# FIXME
raises(PropertiesOptionError, "cfg.option('val1.val3', 2).value.get()")
raises(PropertiesOptionError, "cfg.option('val1.val4', 2).value.get()")
assert cfg.option('val1.val1').value.get() == ['val', 'val_', 'val3']
def test_callback_leader_and_followers_leader_mandatory2(config_type): def test_callback_leader_and_followers_leader_mandatory2(config_type):
val = StrOption('val', "", default='val') val = StrOption('val', "", default='val')
val_ = StrOption('val_', "", default='val_') val_ = StrOption('val_', "", default='val_')
@ -1032,36 +646,6 @@ def test_callback_leader_and_followers_leader_mandatory2(config_type):
assert cfg.option('val1.val1').value.get() == ['val', 'val_', 'val3'] assert cfg.option('val1.val1').value.get() == ['val', 'val_', 'val3']
def test_callback_leader_and_followers_leader_mandatory3_legacy(config_type):
val = StrOption('val', "", default='val')
val_ = StrOption('val_', "", default='val_')
val1 = StrOption('val1', "", multi=True, callback=return_value2, callback_params=Params(ParamOption(val), {'val': ParamOption(val_)}), properties=('mandatory',))
val3 = StrOption('val3', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val1)), properties=('mandatory',))
val4 = StrOption('val4', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val1)), properties=('mandatory',))
interface1 = Leadership('val1', '', [val1, val3, val4])
maconfig = OptionDescription('rootconfig', '', [val, val_, interface1])
cfg_ori = Config(maconfig)
cfg_ori.property.read_only()
cfg = get_config(cfg_ori, config_type)
assert cfg.option('val1.val3', 0).value.get() == 'val'
assert cfg.option('val1.val3', 1).value.get() == 'val_'
assert cfg.option('val1.val4', 0).value.get() == 'val'
assert cfg.option('val1.val4', 1).value.get() == 'val_'
assert cfg.option('val1.val1').value.get() == ['val', 'val_']
cfg_ori.property.read_write()
cfg = get_config(cfg_ori, config_type)
cfg.option('val1.val1').value.set(['val', 'val_', 'val3'])
cfg_ori.property.read_only()
cfg = get_config(cfg_ori, config_type)
assert cfg.option('val1.val3', 0).value.get() == 'val'
assert cfg.option('val1.val3', 1).value.get() == 'val_'
assert cfg.option('val1.val3', 2).value.get() == 'val3'
assert cfg.option('val1.val4', 0).value.get() == 'val'
assert cfg.option('val1.val4', 1).value.get() == 'val_'
assert cfg.option('val1.val4', 2).value.get() == 'val3'
assert cfg.option('val1.val1').value.get() == ['val', 'val_', 'val3']
def test_callback_leader_and_followers_leader_mandatory3(config_type): def test_callback_leader_and_followers_leader_mandatory3(config_type):
val = StrOption('val', "", default='val') val = StrOption('val', "", default='val')
val_ = StrOption('val_', "", default='val_') val_ = StrOption('val_', "", default='val_')
@ -1092,32 +676,6 @@ def test_callback_leader_and_followers_leader_mandatory3(config_type):
assert cfg.option('val1.val1').value.get() == ['val', 'val_', 'val3'] assert cfg.option('val1.val1').value.get() == ['val', 'val_', 'val3']
def test_callback_leader_and_followers_leader_mandatory4_legacy(config_type):
val = StrOption('val', "", default='val')
val1 = StrOption('val1', "", multi=True, callback=return_value2, callback_params=Params(ParamOption(val)), properties=('mandatory',))
val3 = StrOption('val3', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val1)), properties=('mandatory',))
val4 = StrOption('val4', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val1)), properties=('mandatory',))
interface1 = Leadership('val1', '', [val1, val3, val4])
maconfig = OptionDescription('rootconfig', '', [val, interface1])
cfg_ori = Config(maconfig)
cfg_ori.property.read_only()
cfg = get_config(cfg_ori, config_type)
#raises(IndexError, "cfg.option('val1.val3').value.get()")
assert cfg.option('val1.val3', 0).value.get() == 'val'
assert cfg.option('val1.val4', 0).value.get() == 'val'
assert cfg.option('val1.val1').value.get() == ['val']
cfg_ori.property.read_write()
cfg = get_config(cfg_ori, config_type)
cfg.option('val1.val1').value.set(['val', 'val3'])
cfg_ori.property.read_only()
cfg = get_config(cfg_ori, config_type)
assert cfg.option('val1.val1').value.get() == ['val', 'val3']
assert cfg.option('val1.val3', 0).value.get() == 'val'
assert cfg.option('val1.val3', 1).value.get() == 'val3'
assert cfg.option('val1.val4', 0).value.get() == 'val'
assert cfg.option('val1.val4', 1).value.get() == 'val3'
def test_callback_leader_and_followers_leader_mandatory4(config_type): def test_callback_leader_and_followers_leader_mandatory4(config_type):
val = StrOption('val', "", default='val') val = StrOption('val', "", default='val')
val1 = StrOption('val1', "", Calculation(return_value2, Params(ParamOption(val))), properties=('mandatory',), multi=True) val1 = StrOption('val1', "", Calculation(return_value2, Params(ParamOption(val))), properties=('mandatory',), multi=True)
@ -1144,19 +702,6 @@ def test_callback_leader_and_followers_leader_mandatory4(config_type):
assert cfg.option('val1.val4', 1).value.get() == 'val3' assert cfg.option('val1.val4', 1).value.get() == 'val3'
def test_callback_leader_and_followers_leader3_legacy():
val1 = StrOption('val1', "", multi=True, properties=('mandatory', 'empty'))
val2 = StrOption('val2', "", multi=True, default_multi='val2', properties=('expert',))
val3 = StrOption('val3', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val2)))
val4 = StrOption('val4', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val3)))
interface1 = Leadership('val1', '', [val1, val2, val3, val4])
maconfig = OptionDescription('rootconfig', '', [interface1])
cfg = Config(maconfig)
cfg.property.read_write()
# FIXME cfg = get_config(cfg, config_type)
assert list(cfg.value.mandatory()) == ['val1.val1']
def test_callback_leader_and_followers_leader3(): def test_callback_leader_and_followers_leader3():
val1 = StrOption('val1', "", multi=True, properties=('mandatory', 'empty')) val1 = StrOption('val1', "", multi=True, properties=('mandatory', 'empty'))
val2 = StrOption('val2', "", multi=True, default_multi='val2', properties=('expert',)) val2 = StrOption('val2', "", multi=True, default_multi='val2', properties=('expert',))
@ -1170,21 +715,6 @@ def test_callback_leader_and_followers_leader3():
assert list(cfg.value.mandatory()) == ['val1.val1'] assert list(cfg.value.mandatory()) == ['val1.val1']
def test_callback_leader_and_followers_leader4_legacy():
val1 = StrOption('val1', "", ['val1'], multi=True, properties=('mandatory',))
val2 = StrOption('val2', "", multi=True, default_multi='val2', properties=('expert', 'mandatory'))
val3 = StrOption('val3', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val2)))
val4 = StrOption('val4', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val3)))
interface1 = Leadership('val1', '', [val1, val2, val3, val4])
maconfig = OptionDescription('rootconfig', '', [interface1])
cfg = Config(maconfig)
cfg.property.read_write()
# FIXME cfg = get_config(cfg, config_type)
cfg.property.add('expert')
cfg.permissive.set(frozenset(['expert']))
assert list(cfg.value.mandatory()) == []
def test_callback_leader_and_followers_leader4(): def test_callback_leader_and_followers_leader4():
val1 = StrOption('val1', "", ['val1'], multi=True, properties=('mandatory',)) val1 = StrOption('val1', "", ['val1'], multi=True, properties=('mandatory',))
val2 = StrOption('val2', "", multi=True, default_multi='val2', properties=('expert', 'mandatory')) val2 = StrOption('val2', "", multi=True, default_multi='val2', properties=('expert', 'mandatory'))
@ -1203,69 +733,19 @@ def test_callback_leader_and_followers_leader4():
def test_consistency_leader_and_followers_leader_mandatory_transitive(): def test_consistency_leader_and_followers_leader_mandatory_transitive():
#default value #default value
val1 = IPOption('val1', "", ['192.168.0.1'], multi=True, properties=('mandatory',)) val1 = IPOption('val1', "", ['192.168.0.1'], multi=True, properties=('mandatory',))
val2 = NetmaskOption('val2', "", multi=True, default_multi='255.255.255.0', properties=('disabled', 'mandatory')) val2 = NetmaskOption('val2', "", multi=True, default_multi='255.255.255.0', properties=('disabled', 'mandatory'), validators=[Calculation(valid_ip_netmask, Params((ParamOption(val1), ParamSelfOption())))])
val2.impl_add_consistency('ip_netmask', val1)
#no value
val3 = IPOption('val3', "", multi=True, properties=('mandatory',))
val4 = NetmaskOption('val4', "", multi=True, default_multi='255.255.255.0', properties=('disabled', 'mandatory'))
val4.impl_add_consistency('ip_netmask', val3)
interface1 = Leadership('val1', '', [val1, val2])
interface2 = Leadership('val3', '', [val3, val4])
maconfig = OptionDescription('rootconfig', '', [interface1, interface2])
cfg = Config(maconfig)
cfg.property.read_write()
# FIXME cfg = get_config(cfg, config_type)
try:
cfg.option('val1.val1').value.get()
except PropertiesOptionError as error:
assert str(error) == str(_('cannot access to {0} "{1}" because "{2}" has {3} {4}').format('option', 'val1', 'val2', _('property'), '"disabled"'))
else:
raise Exception('must raises')
raises(PropertiesOptionError, "cfg.option('val3.val3').value.get()")
assert list(cfg.value.mandatory()) == []
def test_consistency_leader_and_followers_leader_mandatory_non_transitive():
#no value
val1 = IPOption('val1', "", multi=True, properties=('mandatory',))
val2 = NetmaskOption('val2', "", multi=True, default_multi='255.255.255.0', properties=('disabled', 'mandatory'))
val2.impl_add_consistency('ip_netmask', val1, transitive=False)
#default value
val3 = IPOption('val3', "", ['192.168.0.1'], multi=True, properties=('mandatory',))
val4 = NetmaskOption('val4', "", multi=True, default_multi='255.255.255.0', properties=('disabled', 'mandatory'))
val4.impl_add_consistency('ip_netmask', val3, transitive=False)
interface1 = Leadership('val1', '', [val1, val2])
interface2 = Leadership('val3', '', [val3, val4])
maconfig = OptionDescription('rootconfig', '', [interface1, interface2])
cfg = Config(maconfig)
cfg.property.read_write()
# FIXME cfg = get_config(cfg, config_type)
assert list(cfg.value.mandatory()) == ["val1.val1"]
def test_callback_leader_and_followers_leader_list_legacy(config_type):
val1 = StrOption('val1', "", multi=True, callback=return_list)
val2 = StrOption('val2', "", multi=True)
interface1 = Leadership('val1', '', [val1, val2]) interface1 = Leadership('val1', '', [val1, val2])
maconfig = OptionDescription('rootconfig', '', [interface1]) maconfig = OptionDescription('rootconfig', '', [interface1])
cfg = Config(maconfig) cfg = Config(maconfig)
cfg.property.read_write() cfg.property.read_write()
cfg = get_config(cfg, config_type) # FIXME cfg = get_config(cfg, config_type)
assert cfg.option('val1.val1').value.get() == ['val', 'val'] try:
assert cfg.option('val1.val2', 0).value.get() == None cfg.option('val1.val2', 0).value.get()
assert cfg.option('val1.val2', 1).value.get() == None except PropertiesOptionError as error:
cfg.option('val1.val1').value.set(['val', 'val', undefined]) assert str(error) == str(_('cannot access to {0} "{1}" because has {2} {3}').format('option', 'val2', _('property'), '"disabled"'))
assert cfg.option('val1.val1').value.get() == ['val', 'val', None] else:
assert cfg.option('val1.val2', 0).value.get() == None raise Exception('must raises')
assert cfg.option('val1.val2', 1).value.get() == None assert list(cfg.value.mandatory()) == []
assert cfg.option('val1.val2', 2).value.get() == None
cfg.option('val1.val1').value.reset()
assert cfg.option('val1.val1').value.get() == ['val', 'val']
assert cfg.option('val1.val2', 0).value.get() == None
assert cfg.option('val1.val2', 1).value.get() == None
cfg.option('val1.val1').value.pop(1)
assert cfg.option('val1.val1').value.get() == ['val']
assert cfg.option('val1.val2', 0).value.get() == None
def test_callback_leader_and_followers_leader_list(config_type): def test_callback_leader_and_followers_leader_list(config_type):
@ -1293,23 +773,6 @@ def test_callback_leader_and_followers_leader_list(config_type):
assert cfg.option('val1.val2', 0).value.get() == None assert cfg.option('val1.val2', 0).value.get() == None
def test_callback_leader_and_followers_leader_follower_list_legacy(config_type):
val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", multi=True, callback=return_list)
interface1 = Leadership('val1', '', [val1, val2])
maconfig = OptionDescription('rootconfig', '', [interface1])
cfg = Config(maconfig)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('val1.val1').value.get() == []
if config_type == 'tiramisu-api':
# when "tiramisu-api", raise when set and not in get function
raises(ConfigError, "cfg.option('val1.val1').value.set(['val1'])")
else:
cfg.option('val1.val1').value.set(['val1'])
raises(LeadershipError, "cfg.option('val1.val2', 0).value.get()")
def test_callback_leader_and_followers_leader_follower_list(config_type): def test_callback_leader_and_followers_leader_follower_list(config_type):
val1 = StrOption('val1', "", multi=True) val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", Calculation(return_list), multi=True) val2 = StrOption('val2', "", Calculation(return_list), multi=True)
@ -1327,47 +790,6 @@ def test_callback_leader_and_followers_leader_follower_list(config_type):
raises(LeadershipError, "cfg.option('val1.val2', 0).value.get()") raises(LeadershipError, "cfg.option('val1.val2', 0).value.get()")
def test_callback_leader_and_followers_follower_legacy(config_type):
val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", multi=True, callback=return_val)
interface1 = Leadership('val1', '', [val1, val2])
maconfig = OptionDescription('rootconfig', '', [interface1])
cfg = Config(maconfig)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('val1.val1').value.get() == []
#
cfg.option('val1.val1').value.set(['val1'])
assert cfg.option('val1.val1').value.get() == ['val1']
assert cfg.option('val1.val2', 0).value.get() == 'val'
#
cfg.option('val1.val1').value.set(['val1', 'val2'])
assert cfg.option('val1.val1').value.get() == ['val1', 'val2']
assert cfg.option('val1.val2', 0).value.get() == 'val'
assert cfg.option('val1.val2', 1).value.get() == 'val'
#
cfg.option('val1.val1').value.set(['val1', 'val2', 'val3'])
assert cfg.option('val1.val1').value.get() == ['val1', 'val2', 'val3']
assert cfg.option('val1.val2', 0).value.get() == 'val'
assert cfg.option('val1.val2', 1).value.get() == 'val'
assert cfg.option('val1.val2', 2).value.get() == 'val'
#
cfg.option('val1.val1').value.pop(2)
assert cfg.option('val1.val1').value.get() == ['val1', 'val2']
assert cfg.option('val1.val2', 0).value.get() == 'val'
assert cfg.option('val1.val2', 1).value.get() == 'val'
#
cfg.option('val1.val2', 0).value.set('val2')
cfg.option('val1.val2', 1).value.set('val2')
assert cfg.option('val1.val2', 0).value.get() == 'val2'
assert cfg.option('val1.val2', 1).value.get() == 'val2'
#
cfg.option('val1.val1').value.set(['val1', 'val2', 'val3'])
assert cfg.option('val1.val2', 0).value.get() == 'val2'
assert cfg.option('val1.val2', 1).value.get() == 'val2'
assert cfg.option('val1.val2', 2).value.get() == 'val'
def test_callback_leader_and_followers_follower(config_type): def test_callback_leader_and_followers_follower(config_type):
val1 = StrOption('val1', "", multi=True) val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", Calculation(return_val), multi=True) val2 = StrOption('val2', "", Calculation(return_val), multi=True)
@ -1409,15 +831,6 @@ def test_callback_leader_and_followers_follower(config_type):
assert cfg.option('val1.val2', 2).value.get() == 'val' assert cfg.option('val1.val2', 2).value.get() == 'val'
def test_callback_leader_and_followers_legacy():
val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", multi=True, callback=return_val)
interface1 = Leadership('val1', '', [val1, val2])
maconfig = OptionDescription('rootconfig', '', [interface1])
cfg = Config(maconfig)
cfg.property.read_write()
def test_callback_leader_and_followers(): def test_callback_leader_and_followers():
val1 = StrOption('val1', "", multi=True) val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", Calculation(return_val), multi=True) val2 = StrOption('val2', "", Calculation(return_val), multi=True)
@ -1427,48 +840,6 @@ def test_callback_leader_and_followers():
cfg.property.read_write() cfg.property.read_write()
def test_callback_leader_and_followers_follower_cal_legacy(config_type):
val3 = StrOption('val3', "", multi=True)
val1 = StrOption('val1', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val3)))
val2 = StrOption('val2', "", multi=True, callback=return_val)
interface1 = Leadership('val1', '', [val1, val2])
maconfig = OptionDescription('rootconfig', '', [interface1, val3])
cfg = Config(maconfig)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
#
assert cfg.option('val3').value.get() == []
assert cfg.option('val1.val1').value.get() == []
#
cfg.option('val1.val1').value.set(['val1'])
cfg.option('val3').value.set(['val1'])
assert cfg.option('val1.val1').value.get() == ['val1']
assert cfg.option('val1.val2', 0).value.get() == 'val'
#
cfg.option('val1.val1').value.reset()
cfg.option('val1.val2', 0).value.set('val')
#
cfg.option('val3').value.set(['val1', 'val2'])
assert cfg.option('val1.val2', 0).value.get() == 'val'
assert cfg.option('val1.val2', 1).value.get() == 'val'
assert cfg.option('val1.val1').value.get() == ['val1', 'val2']
# len of follower is higher than leader's one
cfg.option('val1.val2', 0).value.set('val1')
cfg.option('val1.val2', 1).value.set('val2')
if config_type == 'tiramisu-api':
# when "tiramisu-api", raise when set and not in get function
raises(ConfigError, "cfg.option('val3').value.set(['val1'])")
else:
cfg.option('val3').value.set(['val1'])
assert cfg.option('val1.val1').value.get() == ['val1']
raises(LeadershipError, "cfg.option('val1.val2', 0).value.get()")
#
cfg.option('val3').value.set(['val1', 'val2', 'val3'])
assert cfg.option('val1.val2', 0).value.get() == 'val1'
assert cfg.option('val1.val2', 1).value.get() == 'val2'
assert cfg.option('val1.val2', 2).value.get() == 'val'
def test_callback_leader_and_followers_follower_cal(config_type): def test_callback_leader_and_followers_follower_cal(config_type):
val3 = StrOption('val3', "", multi=True) val3 = StrOption('val3', "", multi=True)
val1 = StrOption('val1', "", Calculation(return_value, Params(ParamOption(val3))), multi=True) val1 = StrOption('val1', "", Calculation(return_value, Params(ParamOption(val3))), multi=True)
@ -1513,9 +884,9 @@ def test_callback_leader_and_followers_follower_cal(config_type):
def test_callback_leader_and_followers_leader_disabled(): def test_callback_leader_and_followers_leader_disabled():
#properties must be transitive #properties must be transitive
val1 = StrOption('val1', "", ['val1'], multi=True, properties=('disabled',)) val1 = StrOption('val1', "", ['val1'], multi=True)
val2 = StrOption('val2', "", multi=True) val2 = StrOption('val2', "", multi=True)
interface1 = Leadership('val1', '', [val1, val2]) interface1 = Leadership('val1', '', [val1, val2], properties=('disabled',))
maconfig = OptionDescription('rootconfig', '', [interface1]) maconfig = OptionDescription('rootconfig', '', [interface1])
cfg = Config(maconfig) cfg = Config(maconfig)
cfg.property.read_write() cfg.property.read_write()
@ -1524,22 +895,6 @@ def test_callback_leader_and_followers_leader_disabled():
raises(PropertiesOptionError, "cfg.option('val1.val2', 0).value.get()") raises(PropertiesOptionError, "cfg.option('val1.val2', 0).value.get()")
def test_callback_leader_and_followers_leader_callback_disabled_legacy():
val0 = StrOption('val0', "", multi=True, properties=('disabled',))
val1 = StrOption('val1', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val0)))
val2 = StrOption('val2', "", multi=True)
interface1 = Leadership('val1', '', [val1, val2])
maconfig = OptionDescription('rootconfig', '', [interface1, val0])
cfg = Config(maconfig)
cfg.property.read_write()
raises(ConfigError, "cfg.option('val1.val1').value.get()")
raises(ConfigError, "cfg.option('val1.val2').value.get()")
cfg.property.pop('disabled')
cfg.option('val1.val1').value.set([])
cfg.property.add('disabled')
assert cfg.option('val1.val1').value.get() == []
def test_callback_leader_and_followers_leader_callback_disabled(): def test_callback_leader_and_followers_leader_callback_disabled():
val0 = StrOption('val0', "", multi=True, properties=('disabled',)) val0 = StrOption('val0', "", multi=True, properties=('disabled',))
val1 = StrOption('val1', "", Calculation(return_value, Params(ParamOption(val0))), multi=True) val1 = StrOption('val1', "", Calculation(return_value, Params(ParamOption(val0))), multi=True)
@ -1582,25 +937,6 @@ def test_callback_leader_and_followers_follower_disabled():
assert cfg.option('val1.val2', 1).value.get() == 'no1' assert cfg.option('val1.val2', 1).value.get() == 'no1'
def test_callback_leader_and_followers_follower_callback_disabled_legacy():
val0 = StrOption('val0', "", multi=True, properties=('disabled',))
val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val0)))
interface1 = Leadership('val1', '', [val1, val2])
maconfig = OptionDescription('rootconfig', '', [interface1, val0])
cfg = Config(maconfig)
cfg.property.read_write()
assert cfg.option('val1.val1').value.get() == []
cfg.option('val1.val1').value.set(['yes'])
assert cfg.option('val1.val1').value.get() == ['yes']
cfg.property.pop('disabled')
cfg.option('val1.val2', 0).value.set('no')
cfg.option('val1.val1').value.set(['yes', 'yes1'])
assert cfg.option('val1.val2', 0).value.get() == 'no'
cfg.property.add('disabled')
cfg.option('val1.val1').value.pop(1)
def test_callback_leader_and_followers_follower_callback_disabled(): def test_callback_leader_and_followers_follower_callback_disabled():
val0 = StrOption('val0', "", multi=True, properties=('disabled',)) val0 = StrOption('val0', "", multi=True, properties=('disabled',))
val1 = StrOption('val1', "", multi=True) val1 = StrOption('val1', "", multi=True)
@ -1620,77 +956,6 @@ def test_callback_leader_and_followers_follower_callback_disabled():
cfg.option('val1.val1').value.pop(1) cfg.option('val1.val1').value.pop(1)
def test_callback_leader_and_followers_value_legacy():
val4 = StrOption('val4', '', multi=True, default=['val10', 'val11'])
val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val1)))
val3 = StrOption('val3', "", multi=True, callback=return_value, callback_params=Params(ParamValue('yes')))
val5 = StrOption('val5', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val4)))
val6 = StrOption('val6', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val5)))
interface1 = Leadership('val1', '', [val1, val2, val3, val5, val6])
maconfig = OptionDescription('rootconfig', '', [interface1, val4])
cfg = Config(maconfig)
cfg.property.read_write()
cfg.option('val4').value.get() == ['val10', 'val11']
assert cfg.option('val1.val1').value.get() == []
#raises(LeadershipError, "cfg.val1.val1")
#raises(LeadershipError, "cfg.val1.val2")
#raises(LeadershipError, "cfg.val1.val3")
#raises(LeadershipError, "cfg.val1.val5")
#raises(LeadershipError, "cfg.val1.val6")
#
#default calculation has greater length
#raises(LeadershipError, "cfg.option('val1.val1').value.set(['val1']")
#
cfg.option('val1.val1').value.set(['val1', 'val2'])
assert cfg.option('val1.val1').value.get() == ['val1', 'val2']
assert cfg.option('val1.val2', 0).value.get() == 'val1'
assert cfg.option('val1.val2', 1).value.get() == 'val2'
assert cfg.option('val1.val3', 0).value.get() == 'yes'
assert cfg.option('val1.val3', 1).value.get() == 'yes'
raises(LeadershipError, "cfg.option('val1.val5', 0).value.get()")
raises(LeadershipError, "cfg.option('val1.val5', 1).value.get()")
raises(LeadershipError, "cfg.option('val1.val6', 0).value.get()")
raises(LeadershipError, "cfg.option('val1.val6', 1).value.get()")
#
cfg.option('val1.val1').value.set(['val1', 'val2', 'val3'])
assert cfg.option('val1.val1').value.get() == ['val1', 'val2', 'val3']
assert cfg.option('val1.val2', 0).value.get() == 'val1'
assert cfg.option('val1.val2', 1).value.get() == 'val2'
assert cfg.option('val1.val2', 2).value.get() == 'val3'
assert cfg.option('val1.val3', 0).value.get() == 'yes'
assert cfg.option('val1.val3', 1).value.get() == 'yes'
assert cfg.option('val1.val3', 2).value.get() == 'yes'
raises(LeadershipError, "cfg.option('val1.val5', 2).value.get()")
raises(LeadershipError, "cfg.option('val1.val6', 2).value.get()")
#
cfg.option('val1.val1').value.pop(2)
assert cfg.option('val1.val1').value.get() == ['val1', 'val2']
assert cfg.option('val1.val2', 0).value.get() == 'val1'
assert cfg.option('val1.val2', 1).value.get() == 'val2'
assert cfg.option('val1.val3', 0).value.get() == 'yes'
assert cfg.option('val1.val3', 1).value.get() == 'yes'
#
cfg.option('val1.val2', 0).value.set('val2')
cfg.option('val1.val2', 1).value.set('val2')
cfg.option('val1.val3', 0).value.set('val2')
cfg.option('val1.val3', 1).value.set('val2')
cfg.option('val1.val5', 0).value.set('val2')
cfg.option('val1.val5', 1).value.set('val2')
assert cfg.option('val1.val2', 0).value.get() == 'val2'
assert cfg.option('val1.val2', 1).value.get() == 'val2'
assert cfg.option('val1.val3', 0).value.get() == 'val2'
assert cfg.option('val1.val3', 1).value.get() == 'val2'
assert cfg.option('val1.val5', 0).value.get() == 'val2'
assert cfg.option('val1.val5', 1).value.get() == 'val2'
assert cfg.option('val1.val6', 0).value.get() == 'val2'
assert cfg.option('val1.val6', 1).value.get() == 'val2'
#
cfg.option('val1.val1').value.set(['val1', 'val2', 'val3'])
assert cfg.option('val1.val2', 2).value.get() == 'val3'
assert cfg.option('val1.val3', 2).value.get() == 'yes'
def test_callback_leader_and_followers_value(): def test_callback_leader_and_followers_value():
val4 = StrOption('val4', '', multi=True, default=['val10', 'val11']) val4 = StrOption('val4', '', multi=True, default=['val10', 'val11'])
val1 = StrOption('val1', "", multi=True) val1 = StrOption('val1', "", multi=True)
@ -1762,37 +1027,6 @@ def test_callback_leader_and_followers_value():
assert cfg.option('val1.val3', 2).value.get() == 'yes' assert cfg.option('val1.val3', 2).value.get() == 'yes'
def test_callback_leader_legacy():
val2 = StrOption('val2', "", callback=return_value, multi=True)
val1 = StrOption('val1', "", callback=return_value, callback_params=Params(ParamOption(val2)), multi=True)
raises(ValueError, "Leadership('val1', '', [val1, val2])")
def test_callback_different_type_legacy(config_type):
val = IntOption('val', "", default=2)
val_ = IntOption('val_', "", default=3)
val1 = IntOption('val1', "", multi=True)
val2 = IntOption('val2', "", multi=True, callback=return_calc, callback_params=Params((ParamOption(val), ParamOption(val1)), {'k': ParamOption(val_)}))
interface1 = Leadership('val1', '', [val1, val2])
maconfig = OptionDescription('rootconfig', '', [interface1, val, val_])
cfg = Config(maconfig)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('val1.val1').value.get() == []
cfg.option('val1.val1').value.set([1])
assert cfg.option('val1.val1').value.get() == [1]
assert cfg.option('val1.val2', 0).value.get() == 6
cfg.option('val1.val1').value.set([1, 3])
assert cfg.option('val1.val1').value.get() == [1, 3]
assert cfg.option('val1.val2', 0).value.get() == 6
assert cfg.option('val1.val2', 1).value.get() == 8
cfg.option('val1.val1').value.set([1, 3, 5])
assert cfg.option('val1.val1').value.get() == [1, 3, 5]
assert cfg.option('val1.val2', 0).value.get() == 6
assert cfg.option('val1.val2', 1).value.get() == 8
assert cfg.option('val1.val2', 2).value.get() == 10
def test_callback_different_type(config_type): def test_callback_different_type(config_type):
val = IntOption('val', "", default=2) val = IntOption('val', "", default=2)
val_ = IntOption('val_', "", default=3) val_ = IntOption('val_', "", default=3)
@ -1818,19 +1052,6 @@ def test_callback_different_type(config_type):
assert cfg.option('val1.val2', 2).value.get() == 10 assert cfg.option('val1.val2', 2).value.get() == 10
def test_callback_hidden_legacy():
opt1 = BoolOption('opt1', '')
opt2 = BoolOption('opt2', '', callback=return_value, callback_params=Params(ParamOption(opt1)))
od1 = OptionDescription('od1', '', [opt1], properties=('hidden',))
od2 = OptionDescription('od2', '', [opt2])
maconfig = OptionDescription('rootconfig', '', [od1, od2])
cfg = Config(maconfig)
cfg.property.read_write()
raises(PropertiesOptionError, "cfg.option('od1.opt1').value.get()")
# do not raise, forcepermissive
cfg.option('od2.opt2').value.get()
def test_callback_hidden(): def test_callback_hidden():
opt1 = BoolOption('opt1', '') opt1 = BoolOption('opt1', '')
opt2 = BoolOption('opt2', '', Calculation(return_value, Params(ParamOption(opt1)))) opt2 = BoolOption('opt2', '', Calculation(return_value, Params(ParamOption(opt1))))
@ -1844,19 +1065,6 @@ def test_callback_hidden():
cfg.option('od2.opt2').value.get() cfg.option('od2.opt2').value.get()
def test_callback_hidden_permissive_legacy():
opt1 = BoolOption('opt1', '')
opt2 = BoolOption('opt2', '', callback=return_value, callback_params=Params(ParamOption(opt1)))
od1 = OptionDescription('od1', '', [opt1], properties=('hidden',))
od2 = OptionDescription('od2', '', [opt2])
maconfig = OptionDescription('rootconfig', '', [od1, od2])
cfg = Config(maconfig)
cfg.permissive.set(frozenset(['hidden']))
cfg.property.read_write()
raises(PropertiesOptionError, "cfg.option('od1.opt1').value.get()")
cfg.option('od2.opt2').value.get()
def test_callback_hidden_permissive(): def test_callback_hidden_permissive():
opt1 = BoolOption('opt1', '') opt1 = BoolOption('opt1', '')
opt2 = BoolOption('opt2', '', Calculation(return_value, Params(ParamOption(opt1)))) opt2 = BoolOption('opt2', '', Calculation(return_value, Params(ParamOption(opt1))))
@ -1870,18 +1078,6 @@ def test_callback_hidden_permissive():
cfg.option('od2.opt2').value.get() cfg.option('od2.opt2').value.get()
def test_callback_hidden_permissive_callback_legacy():
opt1 = BoolOption('opt1', '')
opt2 = BoolOption('opt2', '', callback=return_value, callback_params=Params(ParamOption(opt1, True)))
od1 = OptionDescription('od1', '', [opt1], properties=('hidden',))
od2 = OptionDescription('od2', '', [opt2])
maconfig = OptionDescription('rootconfig', '', [od1, od2])
cfg = Config(maconfig)
cfg.property.read_write()
raises(PropertiesOptionError, "cfg.option('od1.opt1').value.get()")
cfg.option('od2.opt2').value.get()
def test_callback_hidden_permissive_callback(): def test_callback_hidden_permissive_callback():
opt1 = BoolOption('opt1', '') opt1 = BoolOption('opt1', '')
opt2 = BoolOption('opt2', '', Calculation(return_value, Params(ParamOption(opt1, True)))) opt2 = BoolOption('opt2', '', Calculation(return_value, Params(ParamOption(opt1, True))))
@ -1894,17 +1090,6 @@ def test_callback_hidden_permissive_callback():
cfg.option('od2.opt2').value.get() cfg.option('od2.opt2').value.get()
def test_callback_two_disabled_legacy():
opt1 = BoolOption('opt1', '', properties=('disabled',))
opt2 = BoolOption('opt2', '', callback=return_value, callback_params=Params(ParamOption(opt1)), properties=('disabled',))
od1 = OptionDescription('od1', '', [opt1])
od2 = OptionDescription('od2', '', [opt2])
maconfig = OptionDescription('rootconfig', '', [od1, od2])
cfg = Config(maconfig)
cfg.property.read_write()
raises(PropertiesOptionError, "cfg.option('od2.opt2').value.get()")
def test_callback_two_disabled(): def test_callback_two_disabled():
opt1 = BoolOption('opt1', '', properties=('disabled',)) opt1 = BoolOption('opt1', '', properties=('disabled',))
opt2 = BoolOption('opt2', '', Calculation(return_value, Params(ParamOption(opt1))), properties=('disabled',)) opt2 = BoolOption('opt2', '', Calculation(return_value, Params(ParamOption(opt1))), properties=('disabled',))
@ -1916,19 +1101,6 @@ def test_callback_two_disabled():
raises(PropertiesOptionError, "cfg.option('od2.opt2').value.get()") raises(PropertiesOptionError, "cfg.option('od2.opt2').value.get()")
def test_callback_two_disabled2_legacy():
opt1 = BoolOption('opt1', '', properties=('hidden',))
opt2 = BoolOption('opt2', '', callback=return_value, callback_params=Params(ParamOption(opt1)), properties=('hidden',))
od1 = OptionDescription('od1', '', [opt1])
od2 = OptionDescription('od2', '', [opt2])
maconfig = OptionDescription('rootconfig', '', [od1, od2])
cfg = Config(maconfig)
cfg.property.read_write()
cfg.permissive.set(frozenset(['hidden']))
raises(PropertiesOptionError, "cfg.option('od2.opt2').value.get()")
assert cfg.forcepermissive.option('od2.opt2').owner.isdefault()
def test_callback_two_disabled2(): def test_callback_two_disabled2():
opt1 = BoolOption('opt1', '', properties=('hidden',)) opt1 = BoolOption('opt1', '', properties=('hidden',))
opt2 = BoolOption('opt2', '', Calculation(return_value, Params(ParamOption(opt1))), properties=('hidden',)) opt2 = BoolOption('opt2', '', Calculation(return_value, Params(ParamOption(opt1))), properties=('hidden',))
@ -1942,19 +1114,6 @@ def test_callback_two_disabled2():
assert cfg.forcepermissive.option('od2.opt2').owner.isdefault() assert cfg.forcepermissive.option('od2.opt2').owner.isdefault()
def test_callback_calculating_invalid_legacy():
opt1 = IntOption('opt1', '', 1)
opt2 = BoolOption('opt2', '', callback=return_value, callback_params=Params(ParamOption(opt1)))
od1 = OptionDescription('od1', '', [opt1])
od2 = OptionDescription('od2', '', [opt2])
maconfig = OptionDescription('rootconfig', '', [od1, od2])
cfg = Config(maconfig)
cfg.property.read_write()
raises(ValueError, "cfg.option('od2.opt2').value.get()")
cfg.unrestraint.option('od2.opt2').property.add('disabled')
raises(PropertiesOptionError, "cfg.option('od2.opt2').value.get()")
def test_callback_calculating_invalid(): def test_callback_calculating_invalid():
opt1 = IntOption('opt1', '', 1) opt1 = IntOption('opt1', '', 1)
opt2 = BoolOption('opt2', '', Calculation(return_value, Params(ParamOption(opt1)))) opt2 = BoolOption('opt2', '', Calculation(return_value, Params(ParamOption(opt1))))
@ -1968,17 +1127,6 @@ def test_callback_calculating_invalid():
raises(PropertiesOptionError, "cfg.option('od2.opt2').value.get()") raises(PropertiesOptionError, "cfg.option('od2.opt2').value.get()")
def test_callback_calculating_disabled_legacy():
opt1 = BoolOption('opt1', '', properties=('disabled',))
opt2 = BoolOption('opt2', '', callback=return_value, callback_params=Params(ParamOption(opt1)))
od1 = OptionDescription('od1', '', [opt1])
od2 = OptionDescription('od2', '', [opt2])
maconfig = OptionDescription('rootconfig', '', [od1, od2])
cfg = Config(maconfig)
cfg.property.read_write()
raises(ConfigError, "cfg.option('od2.opt2').value.get()")
def test_callback_calculating_disabled(): def test_callback_calculating_disabled():
opt1 = BoolOption('opt1', '', properties=('disabled',)) opt1 = BoolOption('opt1', '', properties=('disabled',))
opt2 = BoolOption('opt2', '', Calculation(return_value, Params(ParamOption(opt1)))) opt2 = BoolOption('opt2', '', Calculation(return_value, Params(ParamOption(opt1))))
@ -1990,17 +1138,6 @@ def test_callback_calculating_disabled():
raises(ConfigError, "cfg.option('od2.opt2').value.get()") raises(ConfigError, "cfg.option('od2.opt2').value.get()")
def test_callback_calculating_mandatory_legacy():
opt1 = BoolOption('opt1', '', properties=('disabled',))
opt2 = BoolOption('opt2', '', callback=return_value, callback_params=Params(ParamOption(opt1)), properties=('mandatory',))
od1 = OptionDescription('od1', '', [opt1])
od2 = OptionDescription('od2', '', [opt2])
maconfig = OptionDescription('rootconfig', '', [od1, od2])
cfg = Config(maconfig)
cfg.property.read_only()
raises(ConfigError, "cfg.option('od2.opt2').value.get()")
def test_callback_calculating_mandatory(): def test_callback_calculating_mandatory():
opt1 = BoolOption('opt1', '', properties=('disabled',)) opt1 = BoolOption('opt1', '', properties=('disabled',))
opt2 = BoolOption('opt2', '', Calculation(return_value, Params(ParamOption(opt1))), properties=('mandatory',)) opt2 = BoolOption('opt2', '', Calculation(return_value, Params(ParamOption(opt1))), properties=('mandatory',))
@ -2012,17 +1149,6 @@ def test_callback_calculating_mandatory():
raises(ConfigError, "cfg.option('od2.opt2').value.get()") raises(ConfigError, "cfg.option('od2.opt2').value.get()")
def test_callback_calculating_mandatory_multi_legacy():
opt1 = BoolOption('opt1', '', multi=True, properties=('disabled',))
opt2 = BoolOption('opt2', '', multi=True, callback=return_value, callback_params=Params(ParamOption(opt1)), properties=('mandatory',))
od1 = OptionDescription('od1', '', [opt1])
od2 = OptionDescription('od2', '', [opt2])
maconfig = OptionDescription('rootconfig', '', [od1, od2])
cfg = Config(maconfig)
cfg.property.read_only()
raises(ConfigError, "cfg.option('od2.opt2').value.get()")
def test_callback_calculating_mandatory_multi(): def test_callback_calculating_mandatory_multi():
opt1 = BoolOption('opt1', '', multi=True, properties=('disabled',)) opt1 = BoolOption('opt1', '', multi=True, properties=('disabled',))
opt2 = BoolOption('opt2', '', Calculation(return_value, Params(ParamOption(opt1))), properties=('mandatory',), multi=True) opt2 = BoolOption('opt2', '', Calculation(return_value, Params(ParamOption(opt1))), properties=('mandatory',), multi=True)
@ -2034,17 +1160,6 @@ def test_callback_calculating_mandatory_multi():
raises(ConfigError, "cfg.option('od2.opt2').value.get()") raises(ConfigError, "cfg.option('od2.opt2').value.get()")
def test_callback_two_disabled_multi_legacy():
opt1 = BoolOption('opt1', '', properties=('disabled',))
opt2 = BoolOption('opt2', '', callback=return_value, callback_params=Params(ParamOption(opt1)), properties=('disabled',), multi=True)
od1 = OptionDescription('od1', '', [opt1])
od2 = OptionDescription('od2', '', [opt2])
maconfig = OptionDescription('rootconfig', '', [od1, od2])
cfg = Config(maconfig)
cfg.property.read_write()
raises(PropertiesOptionError, "cfg.option('od2.opt2').value.get()")
def test_callback_two_disabled_multi(): def test_callback_two_disabled_multi():
opt1 = BoolOption('opt1', '', properties=('disabled',)) opt1 = BoolOption('opt1', '', properties=('disabled',))
opt2 = BoolOption('opt2', '', Calculation(return_value, Params(ParamOption(opt1))), properties=('disabled',), multi=True) opt2 = BoolOption('opt2', '', Calculation(return_value, Params(ParamOption(opt1))), properties=('disabled',), multi=True)
@ -2056,17 +1171,6 @@ def test_callback_two_disabled_multi():
raises(PropertiesOptionError, "cfg.option('od2.opt2').value.get()") raises(PropertiesOptionError, "cfg.option('od2.opt2').value.get()")
def test_callback_multi_list_params_legacy(config_type):
val1 = StrOption('val1', "", multi=True, default=['val1', 'val2'])
val2 = StrOption('val2', "", multi=True, callback=return_list, callback_params=Params(ParamOption(val1)))
oval2 = OptionDescription('val2', '', [val2])
maconfig = OptionDescription('rootconfig', '', [val1, oval2])
cfg = Config(maconfig)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('val2.val2').value.get() == ['val', 'val']
def test_callback_multi_list_params(config_type): def test_callback_multi_list_params(config_type):
val1 = StrOption('val1', "", multi=True, default=['val1', 'val2']) val1 = StrOption('val1', "", multi=True, default=['val1', 'val2'])
val2 = StrOption('val2', "", Calculation(return_list, Params(ParamOption(val1))), multi=True) val2 = StrOption('val2', "", Calculation(return_list, Params(ParamOption(val1))), multi=True)
@ -2078,17 +1182,6 @@ def test_callback_multi_list_params(config_type):
assert cfg.option('val2.val2').value.get() == ['val', 'val'] assert cfg.option('val2.val2').value.get() == ['val', 'val']
def test_callback_multi_list_params_key_legacy(config_type):
val1 = StrOption('val1', "", multi=True, default=['val1', 'val2'])
val2 = StrOption('val2', "", multi=True, callback=return_list, callback_params=Params(kwargs={'value': ParamOption(val1)}))
oval2 = OptionDescription('val2', '', [val2])
maconfig = OptionDescription('rootconfig', '', [val1, oval2])
cfg = Config(maconfig)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('val2.val2').value.get() == ['val', 'val']
def test_callback_multi_list_params_key(config_type): def test_callback_multi_list_params_key(config_type):
val1 = StrOption('val1', "", multi=True, default=['val1', 'val2']) val1 = StrOption('val1', "", multi=True, default=['val1', 'val2'])
val2 = StrOption('val2', "", Calculation(return_list, Params(kwargs={'value': ParamOption(val1)})), multi=True) val2 = StrOption('val2', "", Calculation(return_list, Params(kwargs={'value': ParamOption(val1)})), multi=True)
@ -2100,25 +1193,6 @@ def test_callback_multi_list_params_key(config_type):
assert cfg.option('val2.val2').value.get() == ['val', 'val'] assert cfg.option('val2.val2').value.get() == ['val', 'val']
def test_leadership_callback_description_legacy(config_type):
st1 = StrOption('st1', "", multi=True)
st2 = StrOption('st2', "", multi=True, callback=return_value, callback_params=Params(ParamOption(st1)))
stm = Leadership('st1', '', [st1, st2])
st = OptionDescription('st', '', [stm])
od = OptionDescription('od', '', [st])
od2 = OptionDescription('od', '', [od])
cfg = Config(od2)
cfg = get_config(cfg, config_type)
owner = cfg.owner.get()
assert cfg.option('od.st.st1.st1').value.get() == []
assert cfg.option('od.st.st1.st1').owner.isdefault()
##
cfg.option('od.st.st1.st1').value.set(['yes'])
cfg.option('od.st.st1.st2', 0).value.set('yes')
assert cfg.option('od.st.st1.st1').owner.get() == owner
assert cfg.option('od.st.st1.st2', 0).owner.get() == owner
def test_leadership_callback_description(config_type): def test_leadership_callback_description(config_type):
st1 = StrOption('st1', "", multi=True) st1 = StrOption('st1', "", multi=True)
st2 = StrOption('st2', "", Calculation(return_value, Params(ParamOption(st1))), multi=True) st2 = StrOption('st2', "", Calculation(return_value, Params(ParamOption(st1))), multi=True)
@ -2138,24 +1212,6 @@ def test_leadership_callback_description(config_type):
assert cfg.option('od.st.st1.st2', 0).owner.get() == owner assert cfg.option('od.st.st1.st2', 0).owner.get() == owner
def test_callback_raise_legacy():
opt1 = BoolOption('opt1', 'Option 1', callback=return_raise)
opt2 = BoolOption('opt2', 'Option 2', callback=return_valueerror)
od1 = OptionDescription('od1', '', [opt1])
od2 = OptionDescription('od2', '', [opt2])
maconfig = OptionDescription('rootconfig', '', [od1, od2])
cfg = Config(maconfig)
cfg.property.read_write()
try:
cfg.option('od1.opt1').value.get()
except ConfigError as err:
assert '"Option 1"' in str(err)
try:
cfg.option('od2.opt2').value.get()
except ConfigError as err:
assert '"Option 2"' in str(err)
def test_callback_raise(): def test_callback_raise():
opt1 = BoolOption('opt1', 'Option 1', Calculation(return_raise)) opt1 = BoolOption('opt1', 'Option 1', Calculation(return_raise))
opt2 = BoolOption('opt2', 'Option 2', Calculation(return_valueerror)) opt2 = BoolOption('opt2', 'Option 2', Calculation(return_valueerror))
@ -2174,15 +1230,6 @@ def test_callback_raise():
assert '"Option 2"' in str(err) assert '"Option 2"' in str(err)
def test_calc_value_simple_legacy(config_type):
val1 = StrOption('val1', '', 'val1')
val2 = StrOption('val2', '', callback=calc_value, callback_params=Params(ParamOption(val1)))
od = OptionDescription('root', '', [val1, val2])
cfg = Config(od)
cfg = get_config(cfg, config_type)
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val1'}
def test_calc_value_simple(config_type): def test_calc_value_simple(config_type):
val1 = StrOption('val1', '', 'val1') val1 = StrOption('val1', '', 'val1')
val2 = StrOption('val2', '', Calculation(calc_value, Params(ParamOption(val1)))) val2 = StrOption('val2', '', Calculation(calc_value, Params(ParamOption(val1))))
@ -2192,16 +1239,6 @@ def test_calc_value_simple(config_type):
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val1'} assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val1'}
def test_calc_value_multi_legacy(config_type):
val1 = StrOption('val1', "", 'val1')
val2 = StrOption('val2', "", 'val2')
val3 = StrOption('val3', "", multi=True, callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), multi=ParamValue(True)))
od = OptionDescription('root', '', [val1, val2, val3])
cfg = Config(od)
cfg = get_config(cfg, config_type)
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val2', 'val3': ['val1', 'val2']}
def test_calc_value_multi(config_type): def test_calc_value_multi(config_type):
val1 = StrOption('val1', "", 'val1') val1 = StrOption('val1', "", 'val1')
val2 = StrOption('val2', "", 'val2') val2 = StrOption('val2', "", 'val2')
@ -2212,17 +1249,6 @@ def test_calc_value_multi(config_type):
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val2', 'val3': ['val1', 'val2']} assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val2', 'val3': ['val1', 'val2']}
def test_calc_value_disabled_legacy():
val1 = StrOption('val1', '', 'val1')
val2 = StrOption('val2', '', callback=calc_value, callback_params=Params(ParamOption(val1, True), default=ParamValue('default_value')))
od = OptionDescription('root', '', [val1, val2])
cfg = Config(od)
cfg.property.read_write()
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val1'}
cfg.option('val1').property.add('disabled')
assert cfg.value.dict() == {'val2': 'default_value'}
def test_calc_value_disabled(): def test_calc_value_disabled():
val1 = StrOption('val1', '', 'val1') val1 = StrOption('val1', '', 'val1')
val2 = StrOption('val2', '', Calculation(calc_value, Params(ParamOption(val1, True), default=ParamValue('default_value')))) val2 = StrOption('val2', '', Calculation(calc_value, Params(ParamOption(val1, True), default=ParamValue('default_value'))))
@ -2234,22 +1260,6 @@ def test_calc_value_disabled():
assert cfg.value.dict() == {'val2': 'default_value'} assert cfg.value.dict() == {'val2': 'default_value'}
def test_calc_value_condition_legacy(config_type):
boolean = BoolOption('boolean', '', True)
val1 = StrOption('val1', '', 'val1')
val2 = StrOption('val2', '', callback=calc_value, callback_params=Params(ParamOption(val1, True),
default=ParamValue('default_value'),
condition=ParamOption(boolean),
expected=ParamValue(True)))
od = OptionDescription('root', '', [boolean, val1, val2])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.value.dict() == {'boolean': True, 'val1': 'val1', 'val2': 'val1'}
cfg.option('boolean').value.set(False)
assert cfg.value.dict() == {'boolean': False, 'val1': 'val1', 'val2': 'default_value'}
def test_calc_value_condition(config_type): def test_calc_value_condition(config_type):
boolean = BoolOption('boolean', '', True) boolean = BoolOption('boolean', '', True)
val1 = StrOption('val1', '', 'val1') val1 = StrOption('val1', '', 'val1')
@ -2266,16 +1276,6 @@ def test_calc_value_condition(config_type):
assert cfg.value.dict() == {'boolean': False, 'val1': 'val1', 'val2': 'default_value'} assert cfg.value.dict() == {'boolean': False, 'val1': 'val1', 'val2': 'default_value'}
def test_calc_value_allow_none_legacy(config_type):
val1 = StrOption('val1', "", 'val1')
val2 = StrOption('val2', "")
val3 = StrOption('val3', "", multi=True, callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), multi=ParamValue(True), allow_none=ParamValue(True)))
od = OptionDescription('root', '', [val1, val2, val3])
cfg = Config(od)
cfg = get_config(cfg, config_type)
assert cfg.value.dict() == {'val1': 'val1', 'val2': None, 'val3': ['val1', None]}
def test_calc_value_allow_none(config_type): def test_calc_value_allow_none(config_type):
val1 = StrOption('val1', "", 'val1') val1 = StrOption('val1', "", 'val1')
val2 = StrOption('val2', "") val2 = StrOption('val2', "")
@ -2286,16 +1286,6 @@ def test_calc_value_allow_none(config_type):
assert cfg.value.dict() == {'val1': 'val1', 'val2': None, 'val3': ['val1', None]} assert cfg.value.dict() == {'val1': 'val1', 'val2': None, 'val3': ['val1', None]}
def test_calc_value_remove_duplicate_legacy(config_type):
val1 = StrOption('val1', "", 'val1')
val2 = StrOption('val2', "", 'val1')
val3 = StrOption('val3', "", multi=True, callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), multi=ParamValue(True), remove_duplicate_value=ParamValue(True)))
od = OptionDescription('root', '', [val1, val2, val3])
cfg = Config(od)
cfg = get_config(cfg, config_type)
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val1', 'val3': ['val1']}
def test_calc_value_remove_duplicate(config_type): def test_calc_value_remove_duplicate(config_type):
val1 = StrOption('val1', "", 'val1') val1 = StrOption('val1', "", 'val1')
val2 = StrOption('val2', "", 'val1') val2 = StrOption('val2', "", 'val1')
@ -2306,16 +1296,6 @@ def test_calc_value_remove_duplicate(config_type):
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val1', 'val3': ['val1']} assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val1', 'val3': ['val1']}
def test_calc_value_join_legacy(config_type):
val1 = StrOption('val1', "", 'val1')
val2 = StrOption('val2', "", 'val2')
val3 = StrOption('val3', "", callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), join=ParamValue('.')))
od = OptionDescription('root', '', [val1, val2, val3])
cfg = Config(od)
cfg = get_config(cfg, config_type)
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val2', 'val3': 'val1.val2'}
def test_calc_value_join(config_type): def test_calc_value_join(config_type):
val1 = StrOption('val1', "", 'val1') val1 = StrOption('val1', "", 'val1')
val2 = StrOption('val2', "", 'val2') val2 = StrOption('val2', "", 'val2')
@ -2326,19 +1306,6 @@ def test_calc_value_join(config_type):
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val2', 'val3': 'val1.val2'} assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val2', 'val3': 'val1.val2'}
def test_calc_value_min_legacy():
val1 = StrOption('val1', "", 'val1')
val2 = StrOption('val2', "", 'val2')
val3 = StrOption('val3', "", 'val3')
val4 = StrOption('val4', "", callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2), ParamOption(val3, True)), join=ParamValue('.'), min_args_len=ParamValue(3)))
od = OptionDescription('root', '', [val1, val2, val3, val4])
cfg = Config(od)
cfg.property.read_write()
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val2', 'val3': 'val3', 'val4': 'val1.val2.val3'}
cfg.option('val3').property.add('disabled')
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val2', 'val4': ''}
def test_calc_value_min(): def test_calc_value_min():
val1 = StrOption('val1', "", 'val1') val1 = StrOption('val1', "", 'val1')
val2 = StrOption('val2', "", 'val2') val2 = StrOption('val2', "", 'val2')
@ -2351,16 +1318,6 @@ def test_calc_value_min():
cfg.option('val3').property.add('disabled') cfg.option('val3').property.add('disabled')
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val2', 'val4': ''} assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val2', 'val4': ''}
def test_calc_value_add_legacy(config_type):
val1 = IntOption('val1', "", 1)
val2 = IntOption('val2', "", 2)
val3 = IntOption('val3', "", callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), operator=ParamValue('add')))
od = OptionDescription('root', '', [val1, val2, val3])
cfg = Config(od)
cfg = get_config(cfg, config_type)
assert cfg.value.dict() == {'val1': 1, 'val2': 2, 'val3': 3}
def test_calc_value_add(config_type): def test_calc_value_add(config_type):
val1 = IntOption('val1', "", 1) val1 = IntOption('val1', "", 1)
val2 = IntOption('val2', "", 2) val2 = IntOption('val2', "", 2)

View File

@ -1,1175 +0,0 @@
from .autopath import do_autopath
do_autopath()
from .config import config_type, get_config
from py.test import raises
from tiramisu.setting import owners, groups
from tiramisu import IPOption, NetworkOption, NetmaskOption, IntOption,\
BroadcastOption, StrOption, SymLinkOption, OptionDescription, submulti, Leadership,\
Config, undefined, Params, ParamOption, Calculation, ParamIndex
from tiramisu.error import ConfigError, ValueWarning, PropertiesOptionError
import warnings
from tiramisu.storage import list_sessions
from tiramisu.i18n import _
def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def test_consistency():
a = IntOption('a', '')
b = IntOption('b', '')
a.impl_add_consistency('not_equal', b)
#consistency to itself
raises(ConfigError, "a.impl_add_consistency('not_equal', a)")
def test_consistency_not_exists():
a = IntOption('a', '')
b = IntOption('b', '')
a, b
raises(ConfigError, "a.impl_add_consistency('not_exists', b)")
def test_consistency_unknown_params():
a = IntOption('a', '')
b = IntOption('b', '')
a, b
raises(ValueError, "a.impl_add_consistency('not_equal', b, unknown=False)")
def test_consistency_warnings_only_default():
a = IntOption('a', '', 1)
b = IntOption('b', '', 1)
warnings.simplefilter("always", ValueWarning)
with warnings.catch_warnings(record=True) as w:
a.impl_add_consistency('not_equal', b, warnings_only=True)
assert w != []
def test_consistency_warnings_only(config_type):
a = IntOption('a', '')
b = IntOption('b', '')
c = IntOption('c', '')
od = OptionDescription('od', '', [a, b, c])
a.impl_add_consistency('not_equal', b, warnings_only=True)
cfg = Config(od)
assert cfg.option('a').option.consistencies()
assert not cfg.option('b').option.consistencies()
assert not cfg.option('c').option.consistencies()
cfg = get_config(cfg, config_type)
cfg.option('a').value.set(1)
warnings.simplefilter("always", ValueWarning)
with warnings.catch_warnings(record=True) as w:
cfg.option('b').value.set(1)
assert w != []
def test_consistency_warnings_only_more_option(config_type):
a = IntOption('a', '')
b = IntOption('b', '')
d = IntOption('d', '')
od = OptionDescription('od', '', [a, b, d])
a.impl_add_consistency('not_equal', b, d, warnings_only=True)
cfg = Config(od)
cfg = get_config(cfg, config_type)
cfg.option('a').value.set(1)
warnings.simplefilter("always", ValueWarning)
with warnings.catch_warnings(record=True) as w:
cfg.option('b').value.set(1)
assert w != []
assert len(w) == 1
with warnings.catch_warnings(record=True) as w:
cfg.option('d').value.get()
assert w != []
assert len(w) == 1
with warnings.catch_warnings(record=True) as w:
cfg.option('d').value.set(1)
assert w != []
assert len(w) == 1
def test_consistency_error_prefix():
a = IntOption('a', '')
b = IntOption('b', '')
od = OptionDescription('od', '', [a, b])
a.impl_add_consistency('not_equal', b)
cfg = Config(od)
cfg.option('a').value.set(1)
try:
cfg.option('b').value.set(1)
except Exception as err:
assert str(err) == _('"{0}" is an invalid {1} for "{2}"').format('1', _('integer'), 'b') + ', ' + _('must be different from the value of {}').format('"a"')
try:
cfg.option('b').value.set(1)
except Exception as err:
err.prefix = ''
assert str(err) == _('must be different from the value of {}').format('"a"')
def test_consistency_warnings_only_option(config_type):
a = IntOption('a', '')
b = IntOption('b', '', warnings_only=True)
od = OptionDescription('od', '', [a, b])
a.impl_add_consistency('not_equal', b)
cfg_ori = Config(od)
cfg = get_config(cfg_ori, config_type)
cfg.option('a').value.set(1)
warnings.simplefilter("always", ValueWarning)
with warnings.catch_warnings(record=True) as w:
cfg.option('b').value.set(1)
assert w != []
cfg.option('a').value.reset()
cfg.option('b').value.set(1)
raises(ValueError, "cfg.option('a').value.set(1)")
#
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.add('demoting_error_warning')
cfg = get_config(cfg_ori, config_type)
warnings.simplefilter("always", ValueWarning)
with warnings.catch_warnings(record=True) as w:
cfg.option('a').value.set(1)
assert len(w) == 1
def test_consistency_not_equal(config_type):
a = IntOption('a', '')
b = IntOption('b', '')
od = OptionDescription('od', '', [a, b])
a.impl_add_consistency('not_equal', b)
cfg_ori = Config(od)
cfg = get_config(cfg_ori, config_type)
assert cfg.option('a').value.get() is None
assert cfg.option('b').value.get() is None
cfg.option('a').value.set(1)
cfg.option('a').value.reset()
cfg.option('a').value.set(1)
raises(ValueError, "cfg.option('b').value.set(1)")
cfg.option('b').value.set(2)
#
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.add('demoting_error_warning')
cfg = get_config(cfg_ori, config_type)
warnings.simplefilter("always", ValueWarning)
with warnings.catch_warnings(record=True) as w:
cfg.option('b').value.set(1)
assert len(w) == 1
def test_consistency_not_equal_many_opts(config_type):
a = IntOption('a', '')
b = IntOption('b', '')
c = IntOption('c', '')
d = IntOption('d', '')
e = IntOption('e', '')
f = IntOption('f', '')
od = OptionDescription('od', '', [a, b, c, d, e, f])
a.impl_add_consistency('not_equal', b, c, d, e, f)
cfg_ori = Config(od)
cfg = get_config(cfg_ori, config_type)
assert cfg.option('a').value.get() is None
assert cfg.option('b').value.get() is None
#
cfg.option('a').value.set(1)
cfg.option('a').value.reset()
#
cfg.option('a').value.set(1)
raises(ValueError, "cfg.option('b').value.set(1)")
assert cfg.option('b').value.get() == None
#
cfg.option('b').value.set(2)
raises(ValueError, "cfg.option('f').value.set(2)")
assert cfg.option('f').value.get() is None
assert cfg.option('a').value.get() == 1
assert cfg.option('b').value.get() == 2
raises(ValueError, "cfg.option('f').value.set(1)")
assert cfg.option('f').value.get() is None
assert cfg.option('a').value.get() == 1
assert cfg.option('b').value.get() == 2
#
cfg.option('d').value.set(3)
raises(ValueError, "cfg.option('f').value.set(3)")
raises(ValueError, "cfg.option('a').value.set(3)")
cfg.option('d').value.set(3)
raises(ValueError, "cfg.option('c').value.set(3)")
raises(ValueError, "cfg.option('e').value.set(3)")
#
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.add('demoting_error_warning')
cfg = get_config(cfg_ori, config_type)
warnings.simplefilter("always", ValueWarning)
with warnings.catch_warnings(record=True) as w:
cfg.option('c').value.set(3)
assert len(w) == 1
with warnings.catch_warnings(record=True) as w:
cfg.option('e').value.set(3)
assert len(w) == 1
def test_consistency_not_equal_many_opts_one_disabled(config_type):
a = IntOption('a', '')
b = IntOption('b', '')
c = IntOption('c', '')
d = IntOption('d', '')
e = IntOption('e', '')
f = IntOption('f', '')
g = IntOption('g', '', properties=('disabled',))
od = OptionDescription('od', '', [a, b, c, d, e, f, g])
a.impl_add_consistency('not_equal', b, c, d, e, f, g, transitive=False)
cfg_ori = Config(od)
cfg_ori.property.read_write()
cfg = get_config(cfg_ori, config_type)
assert cfg.option('a').value.get() is None
assert cfg.option('b').value.get() is None
#
cfg.option('a').value.set(1)
cfg.option('a').value.reset()
#
cfg.option('a').value.set(1)
raises(ValueError, "cfg.option('b').value.set(1)")
#
cfg.option('b').value.set(2)
raises(ValueError, "cfg.option('f').value.set(2)")
raises(ValueError, "cfg.option('f').value.set(1)")
#
cfg.option('d').value.set(3)
raises(ValueError, "cfg.option('f').value.set(3)")
raises(ValueError, "cfg.option('a').value.set(3)")
raises(ValueError, "cfg.option('c').value.set(3)")
raises(ValueError, "cfg.option('e').value.set(3)")
#
if config_type == 'tiramisu-api':
cfg.send()
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.add('demoting_error_warning')
cfg = get_config(cfg_ori, config_type)
with warnings.catch_warnings(record=True) as w:
cfg.option('c').value.set(3)
assert len(w) == 1
def test_consistency_not_in_config_1():
a = IntOption('a', '')
b = IntOption('b', '')
a.impl_add_consistency('not_equal', b)
od1 = OptionDescription('od1', '', [a])
od = OptionDescription('root', '', [od1])
od
raises(ConfigError, "Config(od)")
def test_consistency_not_in_config_2():
a = IntOption('a', '')
b = IntOption('b', '')
a.impl_add_consistency('not_equal', b)
od1 = OptionDescription('od1', '', [a])
od2 = OptionDescription('od2', '', [b])
od = OptionDescription('root', '', [od1, od2])
Config(od)
def test_consistency_not_in_config_3():
a = IntOption('a', '')
b = IntOption('b', '')
a.impl_add_consistency('not_equal', b)
od1 = OptionDescription('od1', '', [a])
od2 = OptionDescription('od2', '', [b])
od = OptionDescription('root', '', [od1, od2])
od
#with subconfig
raises(ConfigError, "Config(od1)")
def test_consistency_after_config():
a = IntOption('a', '')
b = IntOption('b', '')
od1 = OptionDescription('od1', '', [a])
od2 = OptionDescription('od2', '', [b])
od = OptionDescription('root', '', [od1, od2])
Config(od)
raises(AttributeError, "a.impl_add_consistency('not_equal', b)")
def test_consistency_not_equal_symlink():
a = IntOption('a', '')
b = IntOption('b', '')
c = SymLinkOption('c', a)
od = OptionDescription('od', '', [a, b, c])
a.impl_add_consistency('not_equal', b)
cfg = Config(od)
assert set(od._cache_consistencies.keys()) == set([a, b])
def test_consistency_mix(config_type):
b = IntOption('b', '', multi=True)
c = IntOption('c', '', multi=True)
d = IntOption('d', '', multi=True)
od = Leadership('c', '', [c, d])
od2 = OptionDescription('a', '', [b, od])
c.impl_add_consistency('not_equal', b, d)
cfg_ori = Config(od2)
cfg = get_config(cfg_ori, config_type)
cfg.option('b').value.set([1, 2, 3])
cfg.option('c.c').value.set([4, 5])
raises(ValueError, "cfg.option('c.c').value.set([1, 2])")
raises(ValueError, "cfg.option('c.d', 0).value.set(1)")
raises(ValueError, "cfg.option('c.d', 1).value.set(4)")
#
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.add('demoting_error_warning')
cfg = get_config(cfg_ori, config_type)
with warnings.catch_warnings(record=True) as w:
cfg.option('c.d', 1).value.set(4)
assert len(w) == 1
def test_consistency_not_equal_submulti():
a = IntOption('a', '', multi=submulti)
b = IntOption('b', '', multi=submulti)
od = OptionDescription('a', '', [a, b])
raises(ConfigError, 'a.impl_add_consistency("not_equal", b)')
def test_consistency_not_equal_default_submulti():
a = IntOption('a', '', [[1, 2]], multi=submulti)
b = IntOption('b', '', [[1]], multi=submulti)
od = OptionDescription('od', '', [a, b])
od
raises(ConfigError, "a.impl_add_consistency('not_equal', b)")
def test_consistency_not_equal_leadership(config_type):
a = IntOption('a', '', multi=True)
b = IntOption('b', '', multi=True)
od = Leadership('a', '', [a, b])
od2 = OptionDescription('b', '', [od])
a.impl_add_consistency('not_equal', b)
cfg = Config(od2)
cfg = get_config(cfg, config_type)
assert cfg.option('a.a').value.get() == []
cfg.option('a.a').value.set([1])
cfg.option('a.a').value.reset()
cfg.option('a.a').value.set([1])
raises(ValueError, "cfg.option('a.b', 0).value.set(1)")
cfg.option('a.b', 0).value.set(2)
cfg.option('a.a').value.reset()
cfg.option('a.a').value.set([1])
cfg.value.dict()
def test_consistency_not_equal_leadership_error_multi1():
a = IPOption('a', '', multi=True)
b = NetmaskOption('b', '', multi=True)
c = NetmaskOption('c', '', multi=True)
od = Leadership('a', '', [a, b])
od2 = OptionDescription('b', '', [od, c])
c.impl_add_consistency('ip_netmask', a)
raises(ConfigError, "Config(od2)")
def test_consistency_not_equal_leadership_error_multi2():
a = IPOption('a', '', multi=True)
b = NetmaskOption('b', '', multi=True)
c = IPOption('c', '', multi=True)
od = Leadership('a', '', [a, b])
od2 = OptionDescription('b', '', [od, c])
b.impl_add_consistency('ip_netmask', c)
raises(ConfigError, "Config(od2)")
def test_consistency_ip_netmask_leadership_error_not_leader():
a = IPOption('a', '', multi=True)
b = NetmaskOption('b', '', multi=True)
od = OptionDescription('a', '', [a, b])
od2 = OptionDescription('b', '', [od])
b.impl_add_consistency('ip_netmask', a)
raises(ConfigError, "Config(od2)")
def test_consistency_ip_netmask_leadership_error_leader_and_not():
a = IPOption('a', '', multi=True)
b = NetmaskOption('b', '', multi=True)
c = IPOption('c', '', multi=True)
d = NetmaskOption('d', '', multi=True)
od = Leadership('a', '', [a, b])
od2 = OptionDescription('c', '', [c, d])
od3 = OptionDescription('b', '', [od, od2])
d.impl_add_consistency('ip_netmask', a)
raises(ConfigError, "Config(od3)")
def test_consistency_ip_netmask_leadership_error_otherleader():
a = IPOption('a', '', multi=True)
b = NetmaskOption('b', '', multi=True)
c = IPOption('c', '', multi=True)
d = NetmaskOption('d', '', multi=True)
od = Leadership('a', '', [a, b])
od2 = Leadership('c', '', [c, d])
od3 = OptionDescription('b', '', [od, od2])
d.impl_add_consistency('ip_netmask', a)
raises(ConfigError, "Config(od2)")
def test_consistency_not_equal_leadership_default():
a = IntOption('a', '', multi=True)
b = IntOption('b', '', multi=True, default_multi=1)
od = Leadership('a', '', [a, b])
od2 = OptionDescription('a', '', [od])
a.impl_add_consistency('not_equal', b)
cfg = Config(od2)
# FIXME cfg = get_config(cfg, config_type)
assert cfg.option('a.a').value.get() == []
raises(ValueError, "cfg.option('a.a').value.set([1])")
cfg.option('a.a').value.set([2])
cfg.option('a.a').value.reset()
#
cfg.property.add('demoting_error_warning')
with warnings.catch_warnings(record=True) as w:
cfg.option('a.a').value.set([1])
assert len(w) == 1
def test_consistency_not_equal_multi(config_type):
a = IntOption('a', '', multi=True)
b = IntOption('b', '', multi=True)
od = OptionDescription('a', '', [a, b])
a.impl_add_consistency('not_equal', b)
cfg_ori = Config(od)
cfg = get_config(cfg_ori, config_type)
assert cfg.option('a').value.get() == []
assert cfg.option('b').value.get() == []
cfg.option('a').value.set([1])
cfg.option('a').value.reset()
cfg.option('a').value.set([1])
raises(ValueError, "cfg.option('b').value.set([1])")
cfg.option('a').value.set([2])
raises(ValueError, "cfg.option('b').value.set([2, 1])")
cfg.option('a').value.set([2, 3])
raises(ValueError, "cfg.option('a').value.set([2, 3, 3])")
raises(ValueError, "cfg.option('b').value.set([2, 3])")
#
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.add('demoting_error_warning')
cfg = get_config(cfg_ori, config_type)
with warnings.catch_warnings(record=True) as w:
cfg.option('b').value.set([2, 3])
assert len(w) == 1
def test_consistency_not_equal_multi_default1():
a = IntOption('a', '', multi=True, default=[1])
b = IntOption('b', '', multi=True, default=[3, 1])
od = OptionDescription('a', '', [a, b])
# FIXME raises(ValueError, "b.impl_add_consistency('not_equal', a)")
def test_consistency_not_equal_multi_default2():
a = IntOption('a', '', multi=True, default=[1])
b = IntOption('b', '', multi=True, default_multi=1)
od = OptionDescription('a', '', [a, b])
#default_multi not tested now
a.impl_add_consistency('not_equal', b)
def test_consistency_not_equal_leader_default(config_type):
a = IntOption('a', '', multi=True, default=[2, 1])
b = IntOption('b', '', multi=True, default_multi=1)
od = Leadership('a', '', [a, b])
a.impl_add_consistency('not_equal', b)
od2 = OptionDescription('a', '', [od])
cfg = Config(od2)
cfg = get_config(cfg, config_type)
# default_multi not tested
raises(ValueError, "cfg.option('a.b', 0).value.get()")
cfg.option('a.b', 0).value.set(3)
cfg.option('a.b', 1).value.set(3)
assert cfg.option('a.b', 1).value.get() == 3
def test_consistency_not_equal_multi_default_modif(config_type):
a = IntOption('a', '', multi=True)
b = IntOption('b', '', multi=True, default=[1, 2])
od = OptionDescription('a', '', [a, b])
a.impl_add_consistency('not_equal', b)
cfg_ori = Config(od)
cfg = get_config(cfg_ori, config_type)
assert cfg.option('a').value.get() == []
assert cfg.option('b').value.get() == [1, 2]
raises(ValueError, "cfg.option('a').value.set([1])")
raises(ValueError, "cfg.option('b').value.set([1, 2, 1])")
#
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.add('demoting_error_warning')
cfg = get_config(cfg_ori, config_type)
with warnings.catch_warnings(record=True) as w:
cfg.option('b').value.set([1, 2, 1])
assert len(w) == 1
def test_consistency_default():
a = IntOption('a', '', 1)
b = IntOption('b', '', 1)
a, b
raises(ValueError, "a.impl_add_consistency('not_equal', b)")
def test_consistency_default_multi():
a = IntOption('a', '', [2, 1], multi=True)
b = IntOption('b', '', [1, 1], multi=True)
c = IntOption('c', '', [1, 2], multi=True)
b
# FIXME raises(ValueError, "a.impl_add_consistency('not_equal', b)")
# FIXME raises(ValueError, "a.impl_add_consistency('not_equal', c)")
def test_consistency_default_diff():
a = IntOption('a', '', 3)
b = IntOption('b', '', 1)
od = OptionDescription('od', '', [a, b])
a.impl_add_consistency('not_equal', b)
cfg = Config(od)
# FIXME cfg = get_config(cfg, config_type)
raises(ValueError, "cfg.option('a').value.set(1)")
cfg.option('a').value.set(2)
cfg.option('b').value.set(3)
owner = cfg.owner.get()
assert cfg.option('a').owner.get() == owner
raises(ValueError, "cfg.option('a').value.reset()")
assert cfg.option('a').owner.get() == owner
#
cfg.property.add('demoting_error_warning')
with warnings.catch_warnings(record=True) as w:
cfg.option('a').value.reset()
assert len(w) == 1
def test_consistency_ip_netmask(config_type):
a = IPOption('a', '')
b = NetmaskOption('b', '')
od = OptionDescription('od', '', [a, b])
b.impl_add_consistency('ip_netmask', a)
cfg_ori = Config(od)
cfg = cfg_ori
cfg = get_config(cfg_ori, config_type)
cfg.option('a').value.set('192.168.1.1')
cfg.option('b').value.set('255.255.255.0')
cfg.option('a').value.set('192.168.1.2')
cfg.option('b').value.set('255.255.255.128')
cfg.option('b').value.set('255.255.255.0')
raises(ValueError, "cfg.option('a').value.set('192.168.1.0')")
raises(ValueError, "cfg.option('a').value.set('192.168.1.255')")
cfg.option('a').value.reset()
cfg.option('b').value.reset()
cfg.option('a').value.set('192.168.1.255')
raises(ValueError, "cfg.option('b').value.set('255.255.255.0')")
#
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.add('demoting_error_warning')
cfg = get_config(cfg_ori, config_type)
with warnings.catch_warnings(record=True) as w:
cfg.option('b').value.set('255.255.255.0')
assert len(w) == 1
def test_consistency_ip_netmask_invalid():
b = NetmaskOption('b', '')
od = OptionDescription('od', '', [b])
raises(ConfigError, "b.impl_add_consistency('ip_netmask')")
def test_consistency_network_netmask(config_type):
a = NetworkOption('a', '')
b = NetmaskOption('b', '')
od = OptionDescription('od', '', [a, b])
b.impl_add_consistency('network_netmask', a)
cfg_ori = Config(od)
cfg = get_config(cfg_ori, config_type)
cfg.option('a').value.set('192.168.1.1')
cfg.option('b').value.set('255.255.255.255')
cfg.option('b').value.reset()
cfg.option('a').value.set('192.168.1.0')
cfg.option('b').value.set('255.255.255.0')
raises(ValueError, "cfg.option('a').value.set('192.168.1.1')")
#
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.add('demoting_error_warning')
cfg = get_config(cfg_ori, config_type)
with warnings.catch_warnings(record=True) as w:
cfg.option('a').value.set('192.168.1.1')
assert len(w) == 1
def test_consistency_network_netmask_invalid():
b = NetmaskOption('b', '')
od = OptionDescription('od', '', [b])
raises(ConfigError, "b.impl_add_consistency('network_netmask')")
def test_consistency_ip_in_network(config_type):
a = NetworkOption('a', '')
b = NetmaskOption('b', '')
c = IPOption('c', '')
d = IPOption('d', '')
od = OptionDescription('od', '', [a, b, c, d])
c.impl_add_consistency('in_network', a, b)
d.impl_add_consistency('in_network', a, b, warnings_only=True)
warnings.simplefilter("always", ValueWarning)
cfg = Config(od)
cfg = get_config(cfg, config_type)
cfg.option('a').value.set('192.168.1.0')
cfg.option('b').value.set('255.255.255.0')
cfg.option('c').value.set('192.168.1.1')
raises(ValueError, "cfg.option('c').value.set('192.168.2.1')")
raises(ValueError, "cfg.option('c').value.set('192.168.1.0')")
raises(ValueError, "cfg.option('c').value.set('192.168.1.255')")
with warnings.catch_warnings(record=True) as w:
cfg.option('d').value.set('192.168.2.1')
assert len(w) == 1
def test_consistency_ip_in_network_cidr(config_type):
a = NetworkOption('a', '', cidr=True)
c = IPOption('c', '')
d = IPOption('d', '')
od = OptionDescription('od', '', [a, c, d])
c.impl_add_consistency('in_network', a)
d.impl_add_consistency('in_network', a, warnings_only=True)
warnings.simplefilter("always", ValueWarning)
cfg = Config(od)
cfg = get_config(cfg, config_type)
cfg.option('a').value.set('192.168.1.0/24')
cfg.option('c').value.set('192.168.1.1')
raises(ValueError, "cfg.option('c').value.set('192.168.2.1')")
raises(ValueError, "cfg.option('c').value.set('192.168.1.0')")
raises(ValueError, "cfg.option('c').value.set('192.168.1.255')")
with warnings.catch_warnings(record=True) as w:
cfg.option('d').value.set('192.168.2.1')
assert len(w) == 1
def test_consistency_ip_in_network_invalid():
a = NetworkOption('a', '')
b = NetmaskOption('b', '')
c = IPOption('c', '')
d = IPOption('d', '')
od = OptionDescription('od', '', [a, b, c, d])
raises(ConfigError, "c.impl_add_consistency('in_network', a)")
def test_consistency_ip_netmask_error_multi():
a = IPOption('a', '', multi=True)
b = NetmaskOption('b', '')
OptionDescription('od', '', [a, b])
raises(ConfigError, "b.impl_add_consistency('ip_netmask', a)")
def test_consistency_ip_netmask_multi(config_type):
a = IPOption('a', '', multi=True)
b = NetmaskOption('b', '', multi=True)
od = Leadership('a', '', [a, b])
b.impl_add_consistency('ip_netmask', a)
od2 = OptionDescription('od2', '', [od])
cfg_ori = Config(od2)
cfg = get_config(cfg_ori, config_type)
cfg.option('a.a').value.set(['192.168.1.1'])
cfg.option('a.b', 0).value.set('255.255.255.0')
cfg.option('a.a').value.set(['192.168.1.2'])
cfg.option('a.b', 0).value.set('255.255.255.128')
cfg.option('a.b', 0).value.set('255.255.255.0')
raises(ValueError, "cfg.option('a.a').value.set(['192.168.1.0'])")
#
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.add('demoting_error_warning')
cfg = get_config(cfg_ori, config_type)
with warnings.catch_warnings(record=True) as w:
cfg.option('a.a').value.set(['192.168.1.0'])
assert len(w) == 1
def test_consistency_network_netmask_multi(config_type):
a = NetworkOption('a', '', multi=True)
b = NetmaskOption('b', '', multi=True)
od = Leadership('a', '', [a, b])
b.impl_add_consistency('network_netmask', a)
od2 = OptionDescription('od', '', [od])
cfg = Config(od2)
cfg = get_config(cfg, config_type)
cfg.option('a.a').value.set(['192.168.1.1'])
cfg.option('a.b', 0).value.set('255.255.255.255')
cfg.option('a.b', 0).value.reset()
cfg.option('a.a').value.set(['192.168.1.0'])
cfg.option('a.b', 0).value.set('255.255.255.0')
raises(ValueError, "cfg.option('a.a').value.set(['192.168.1.1'])")
def test_consistency_network_netmask_multi_follower_default_multi(config_type):
a = NetworkOption('a', '', default_multi=u'192.168.1.0', multi=True, properties=('mandatory',))
b = NetmaskOption('b', '', default_multi=u'255.255.255.0', multi=True, properties=('mandatory',))
od = Leadership('a', '', [a, b])
od2 = OptionDescription('od2', '', [od])
b.impl_add_consistency('network_netmask', a)
cfg = Config(od2)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('a.a').value.set([undefined])
assert cfg.option('a.a').value.get() == ['192.168.1.0']
assert cfg.option('a.b', 0).value.get() == '255.255.255.0'
def test_consistency_network_netmask_multi_follower_default(config_type):
a = NetworkOption('a', '', multi=True, properties=('mandatory',))
b = NetmaskOption('b', '', default_multi=u'255.255.255.0', multi=True, properties=('mandatory',))
od = Leadership('a', '', [a, b])
b.impl_add_consistency('network_netmask', a)
od2 = OptionDescription('od2', '', [od])
cfg_ori = Config(od2)
cfg_ori.property.read_write()
cfg_ori.property.pop('cache')
cfg = get_config(cfg_ori, config_type)
assert cfg.option('a.a').value.get() == []
cfg.option('a.a').value.set(['192.168.1.0'])
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.read_only()
cfg = get_config(cfg_ori, config_type)
assert cfg.option('a.a').value.get() == [u'192.168.1.0']
assert cfg.option('a.b', 0).value.get() == u'255.255.255.0'
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.read_write()
cfg = get_config(cfg_ori, config_type)
raises(ValueError, "cfg.option('a.a').value.set([u'192.168.1.0', u'192.168.1.1'])")
cfg.option('a.a').value.set(['192.168.1.0', undefined])
cfg.option('a.b', 0).value.set('255.255.255.0')
cfg.option('a.b', 1).value.set('255.255.255.255')
cfg.option('a.a').value.set([u'192.168.1.0', u'192.168.1.1'])
def return_netmask(*args, **kwargs):
return u'255.255.255.0'
def return_netmask2(leader):
if leader is not None:
if leader.endswith('2.1'):
return u'255.255.255.0'
if not leader.endswith('.0'):
return u'255.255.255.255'
return u'255.255.255.0'
def test_consistency_network_netmask_multi_follower_callback(config_type):
a = NetworkOption('a', '', multi=True, properties=('mandatory',))
b = NetmaskOption('b', '', Calculation(return_netmask, Params(kwargs={'index': ParamIndex()})), multi=True, properties=('mandatory',))
od = Leadership('a', '', [a, b])
b.impl_add_consistency('network_netmask', a)
od2 = OptionDescription('od2', '', [od])
cfg_ori = Config(od2)
cfg_ori.property.read_write()
cfg_ori.property.pop('cache')
cfg = get_config(cfg_ori, config_type)
assert cfg.option('a.a').value.get() == []
cfg.option('a.a').value.set(['192.168.1.0'])
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.read_only()
cfg = get_config(cfg_ori, config_type)
assert cfg.option('a.a').value.get() == [u'192.168.1.0']
assert cfg.option('a.b', 0).value.get() == '255.255.255.0'
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.read_write()
cfg = get_config(cfg_ori, config_type)
raises(ValueError, "assert cfg.option('a.a').value.set([u'192.168.1.0', u'192.168.1.1'])")
cfg.option('a.a').value.set(['192.168.1.0', undefined])
cfg.option('a.b', 0).value.set('255.255.255.0')
cfg.option('a.b', 1).value.set('255.255.255.255')
cfg.option('a.a').value.set(['192.168.1.0', '192.168.1.1'])
def test_consistency_network_netmask_multi_follower_callback_value(config_type):
a = NetworkOption('a', '', multi=True, properties=('mandatory',))
b = NetmaskOption('b', '', Calculation(return_netmask2, Params(ParamOption(a))), multi=True, properties=('mandatory',))
od = Leadership('a', '', [a, b])
b.impl_add_consistency('network_netmask', a)
od2 = OptionDescription('od2', '', [od])
cfg = Config(od2)
cfg.property.read_write()
cfg.property.pop('cache')
cfg = get_config(cfg, config_type)
assert cfg.option('a.a').value.get() == []
cfg.option('a.a').value.set(['192.168.1.0'])
assert cfg.option('a.a').value.get() == ['192.168.1.0']
assert cfg.option('a.b', 0).value.get() == '255.255.255.0'
raises(ValueError, "cfg.option('a.a').value.set(['192.168.1.0', '192.168.2.1'])")
assert cfg.option('a.a').value.get() == [u'192.168.1.0']
assert cfg.option('a.b', 0).value.get() == '255.255.255.0'
raises(ValueError, "cfg.option('a.a').value.set(['192.168.2.1'])")
assert cfg.option('a.a').value.get() == [u'192.168.1.0']
assert cfg.option('a.b', 0).value.get() == '255.255.255.0'
cfg.option('a.a').value.set(['192.168.1.0', '192.168.1.1'])
cfg.option('a.b', 0).value.set('255.255.255.0')
cfg.option('a.b', 1).value.set('255.255.255.255')
def test_consistency_ip_netmask_multi_leader(config_type):
a = IPOption('a', '', multi=True)
b = NetmaskOption('b', '', multi=True)
od = Leadership('a', '', [a, b])
b.impl_add_consistency('ip_netmask', a)
od2 = OptionDescription('od2', '', [od])
cfg = Config(od2)
cfg = get_config(cfg, config_type)
cfg.option('a.a').value.set(['192.168.1.1'])
cfg.option('a.b', 0).value.set('255.255.255.0')
cfg.option('a.a').value.set(['192.168.1.2'])
cfg.option('a.b', 0).value.set('255.255.255.128')
cfg.option('a.b', 0).value.set('255.255.255.0')
raises(ValueError, "cfg.option('a.a').value.set(['192.168.1.0'])")
cfg.option('a.a').value.set(['192.168.1.128'])
raises(ValueError, "cfg.option('a.b', 0).value.set('255.255.255.128')")
cfg.option('a.a').value.set(['192.168.1.2', '192.168.1.3'])
def test_consistency_network_netmask_multi_leader(config_type):
a = NetworkOption('a', '', multi=True)
b = NetmaskOption('b', '', multi=True)
od = Leadership('a', '', [a, b])
b.impl_add_consistency('network_netmask', a)
od2 = OptionDescription('od2', '', [od])
cfg = Config(od2)
cfg = get_config(cfg, config_type)
cfg.option('a.a').value.set(['192.168.1.1'])
cfg.option('a.b', 0).value.set('255.255.255.255')
cfg.option('a.b', 0).value.reset()
cfg.option('a.a').value.set(['192.168.1.0'])
cfg.option('a.b', 0).value.set('255.255.255.0')
raises(ValueError, "cfg.option('a.a').value.set(['192.168.1.1'])")
def test_consistency_broadcast(config_type):
a = NetworkOption('a', '', multi=True)
b = NetmaskOption('b', '', multi=True)
c = BroadcastOption('c', '', multi=True)
od = Leadership('a', '', [a, b, c])
b.impl_add_consistency('network_netmask', a)
c.impl_add_consistency('broadcast', a, b)
od2 = OptionDescription('od2', '', [od])
cfg = Config(od2)
cfg = get_config(cfg, config_type)
#first, test network_netmask
cfg.option('a.a').value.set(['192.168.1.128'])
raises(ValueError, "cfg.option('a.a').value.set(['255.255.255.0'])")
#
cfg.option('a.a').value.set(['192.168.1.0'])
cfg.option('a.b', 0).value.set('255.255.255.0')
cfg.option('a.c', 0).value.set('192.168.1.255')
raises(ValueError, "cfg.option('a.a').value.set(['192.168.1.1'])")
#
cfg.option('a.a').value.set(['192.168.1.0', '192.168.2.128'])
cfg.option('a.b', 0).value.set('255.255.255.0')
cfg.option('a.b', 1).value.set('255.255.255.128')
cfg.option('a.c', 0).value.set('192.168.1.255')
cfg.option('a.c', 1).value.set('192.168.2.255')
raises(ValueError, "cfg.option('a.c', 1).value.set('192.168.2.128')")
cfg.option('a.c', 1).value.set('192.168.2.255')
def test_consistency_broadcast_error(config_type):
a = NetworkOption('a', '', multi=True)
b = NetmaskOption('b', '', multi=True)
c = BroadcastOption('c', '', multi=True)
od = Leadership('a', '', [a, b, c])
od2 = OptionDescription('od2', '', [od])
b.impl_add_consistency('network_netmask', a)
c.impl_add_consistency('broadcast', a)
cfg = Config(od2)
cfg = get_config(cfg, config_type)
raises(ConfigError, "cfg.option('a.a').value.set(['192.168.1.0'])")
def test_consistency_broadcast_warnings(config_type):
warnings.simplefilter("always", ValueWarning)
a = NetworkOption('a', '', properties=('mandatory', 'disabled'))
b = NetmaskOption('b', '', properties=('mandatory', 'disabled'))
c = NetmaskOption('c', '', properties=('mandatory', 'disabled'))
od = OptionDescription('a', '', [a, b, c])
b.impl_add_consistency('network_netmask', a, warnings_only=True)
cfg_ori = Config(od)
cfg = get_config(cfg_ori, config_type)
with warnings.catch_warnings(record=True) as w:
cfg.option('a').value.set('192.168.1.4')
cfg.option('b').value.set('255.255.255.0')
assert len(w) == 1
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.read_write()
cfg = get_config(cfg_ori, config_type)
with warnings.catch_warnings(record=True) as w:
list(cfg.value.mandatory())
assert len(w) == 0
def test_consistency_broadcast_default_1():
a = NetworkOption('a', '', '192.168.1.0')
b = NetmaskOption('b', '', '255.255.255.128')
c = BroadcastOption('c', '', '192.168.2.127')
od = OptionDescription('a', '', [a, b, c])
od
raises(ValueError, "c.impl_add_consistency('broadcast', a, b)")
def test_consistency_broadcast_default_2():
a = NetworkOption('a', '', '192.168.1.0')
b = NetmaskOption('b', '', '255.255.255.128')
d = BroadcastOption('d', '', '192.168.1.127')
od2 = OptionDescription('a', '', [a, b, d])
od2
d.impl_add_consistency('broadcast', a, b)
def test_consistency_not_all(config_type):
#_cache_consistencies is not None by not options has consistencies
a = NetworkOption('a', '', multi=True)
b = NetmaskOption('b', '', multi=True)
c = BroadcastOption('c', '', multi=True)
od = Leadership('a', '', [a, b, c])
b.impl_add_consistency('network_netmask', a)
od2 = OptionDescription('od2', '', [od])
cfg = Config(od2)
cfg = get_config(cfg, config_type)
cfg.option('a.a').value.set(['192.168.1.0'])
cfg.option('a.b', 0).value.set('255.255.255.0')
cfg.option('a.c', 0).value.set('192.168.1.255')
def test_consistency_permissive(config_type):
a = IntOption('a', '', 1)
b = IntOption('b', '', 2, properties=('hidden',))
od = OptionDescription('od', '', [a, b])
a.impl_add_consistency('not_equal', b)
cfg = Config(od)
cfg.property.read_write()
cfg.permissive.set(frozenset(['hidden']))
cfg = get_config(cfg, config_type)
cfg.option('a').value.set(1)
def test_consistency_disabled(config_type):
a = IntOption('a', '')
b = IntOption('b', '', properties=('disabled',))
od = OptionDescription('od', '', [a, b])
a.impl_add_consistency('not_equal', b)
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
raises(PropertiesOptionError, "cfg.option('a').value.set(1)")
def test_consistency_disabled_transitive(config_type):
a = IntOption('a', '')
b = IntOption('b', '', properties=('disabled',))
od = OptionDescription('od', '', [a, b])
a.impl_add_consistency('not_equal', b, transitive=False)
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('a').value.set(1)
def test_consistency_disabled_transitive_2(config_type):
a = IPOption('a', '')
b = IPOption('b', '')
c = NetworkOption('c', '', default='192.168.1.0')
d = NetmaskOption('d', '', default='255.255.255.0', properties=('disabled',))
od = OptionDescription('od', '', [a, b, c, d])
a.impl_add_consistency('not_equal', b)
a.impl_add_consistency('in_network', c, d, transitive=False)
cfg_ori = Config(od)
cfg_ori.property.read_write()
cfg = get_config(cfg_ori, config_type)
cfg.option('a').value.set('192.168.1.1')
raises(ValueError, "cfg.option('b').value.set('192.168.1.1')")
cfg.option('a').value.set('192.168.2.1')
#
cfg.option('a').value.set('192.168.1.1')
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.pop('disabled')
cfg = get_config(cfg_ori, config_type)
raises(ValueError, "cfg.option('a').value.set('192.168.2.1')")
#
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.add('demoting_error_warning')
cfg = get_config(cfg_ori, config_type)
with warnings.catch_warnings(record=True) as w:
cfg.option('a').value.set('192.168.2.1')
assert len(w) == 1
def return_val(*args, **kwargs):
return '192.168.1.1'
def test_consistency_with_callback(config_type):
a = NetworkOption('a', '', default='192.168.1.0')
b = NetmaskOption('b', '', default='255.255.255.0')
c = IPOption('c', '', Calculation(return_val, Params(ParamOption(a))))
od = OptionDescription('od', '', [a, b, c])
c.impl_add_consistency('in_network', a, b)
cfg = Config(od)
cfg = get_config(cfg, config_type)
cfg.option('c').value.get()
def test_consistency_warnings_only_options(config_type):
a = IPOption('a', '', warnings_only=True)
b = IPOption('b', '')
c = NetworkOption('c', '', default='192.168.1.0')
d = NetmaskOption('d', '', default='255.255.255.0', properties=('disabled',))
od = OptionDescription('od', '', [a, b, c, d])
a.impl_add_consistency('not_equal', b)
a.impl_add_consistency('in_network', c, d, transitive=False)
cfg_ori = Config(od)
cfg_ori.property.read_write()
cfg = get_config(cfg_ori, config_type)
cfg.option('a').value.set('192.168.1.1')
raises(ValueError, "cfg.option('b').value.set('192.168.1.1')")
cfg.option('a').value.set('192.168.2.1')
#
cfg.option('a').value.set('192.168.1.1')
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.pop('disabled')
cfg = get_config(cfg_ori, config_type)
with warnings.catch_warnings(record=True) as w:
cfg.option('a').value.set('192.168.2.1')
assert len(w) == 1
def test_consistency_warnings_only_options_callback(config_type):
a = IPOption('a', '', warnings_only=True)
b = IPOption('b', '')
c = NetworkOption('c', '', default='192.168.1.0')
d = NetmaskOption('d', '', Calculation(return_netmask2, Params(ParamOption(c))))
od = OptionDescription('od', '', [a, b, c, d])
a.impl_add_consistency('not_equal', b)
a.impl_add_consistency('in_network', c, d, transitive=False)
cfg_ori = Config(od)
cfg_ori.property.read_write()
cfg = get_config(cfg_ori, config_type)
cfg.option('a').value.set('192.168.1.1')
raises(ValueError, "cfg.option('b').value.set('192.168.1.1')")
with warnings.catch_warnings(record=True) as w:
cfg.option('a').value.set('192.168.2.1')
assert len(w) == 1
#
cfg.option('a').value.set('192.168.1.1')
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.pop('disabled')
cfg = get_config(cfg_ori, config_type)
with warnings.catch_warnings(record=True) as w:
cfg.option('a').value.set('192.168.2.1')
assert len(w) == 1
def test_consistency_double_warnings(config_type):
a = IntOption('a', '')
b = IntOption('b', '', 1)
c = IntOption('c', '', 1)
od = OptionDescription('od', '', [a, b, c])
warnings.simplefilter("always", ValueWarning)
a.impl_add_consistency('not_equal', b, warnings_only=True)
a.impl_add_consistency('not_equal', c, warnings_only=True)
od2 = OptionDescription('od2', '', [od])
cfg_ori = Config(od2)
cfg = get_config(cfg_ori, config_type)
with warnings.catch_warnings(record=True) as w:
cfg.option('od.a').value.set(1)
assert w != []
if config_type == 'tiramisu-api':
# in this case warnings is for '"a" and "b"'
assert len(w) == 1
else:
# in this cas one warnings is for "a" and the second for "b"
assert len(w) == 2
with warnings.catch_warnings(record=True) as w:
cfg.option('od.c').value.set(2)
assert len(w) == 0
with warnings.catch_warnings(record=True) as w:
cfg.option('od.a').value.set(2)
assert len(w) == 1
#
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.pop('warnings')
cfg = get_config(cfg_ori, config_type)
with warnings.catch_warnings(record=True) as w:
cfg.option('od.a').value.set(1)
assert w == []
def test_consistency_warnings_error(config_type):
a = IntOption('a', '')
b = IntOption('b', '', 1)
c = IntOption('c', '', 1)
od = OptionDescription('od', '', [a, b, c])
warnings.simplefilter("always", ValueWarning)
a.impl_add_consistency('not_equal', b, warnings_only=True)
a.impl_add_consistency('not_equal', c)
cfg = Config(od)
cfg = get_config(cfg, config_type)
with warnings.catch_warnings(record=True) as w:
raises(ValueError, "cfg.option('a').value.set(1)")
assert w == []
def test_consistency_network_netmask_mandatory(config_type):
a = NetworkOption('a', '', multi=True, properties=('mandatory',), default=[u'0.0.0.0'])
b = NetmaskOption('b', '', multi=True, properties=('mandatory',), default_multi=u'0.0.0.0')
od = Leadership('a', '', [a, b])
b.impl_add_consistency('network_netmask', a)
od2 = OptionDescription('od2', '', [od])
cfg = Config(od2)
cfg.property.read_only()
cfg.property.pop('mandatory')
cfg = get_config(cfg, config_type)
cfg.value.dict()
def test_consistency_has_dependency():
a = IPOption('a', '')
b = NetmaskOption('b', '')
od = OptionDescription('od', '', [a, b])
b.impl_add_consistency('ip_netmask', a)
cfg = Config(od)
assert cfg.option('a').option.has_dependency() is True
assert cfg.option('b').option.has_dependency() is True
assert cfg.option('a').option.has_dependency(False) is True
assert cfg.option('b').option.has_dependency(False) is True
def test_consistency_not_equal_has_dependency():
a = IntOption('a', '')
b = IntOption('b', '')
od = OptionDescription('od', '', [a, b])
a.impl_add_consistency('not_equal', b)
cfg = Config(od)
assert cfg.option('a').option.has_dependency() is False
assert cfg.option('b').option.has_dependency() is False
assert cfg.option('a').option.has_dependency(False) is True
assert cfg.option('b').option.has_dependency(False) is True

View File

@ -6,7 +6,7 @@ from .config import config_type, get_config
from py.test import raises from py.test import raises
from tiramisu.setting import owners from tiramisu.setting import owners
from tiramisu.error import PropertiesOptionError, ConfigError from tiramisu.error import PropertiesOptionError, ConfigError, LeadershipError
from tiramisu import IntOption, FloatOption, StrOption, ChoiceOption, \ from tiramisu import IntOption, FloatOption, StrOption, ChoiceOption, \
BoolOption, OptionDescription, Leadership, Config, undefined BoolOption, OptionDescription, Leadership, Config, undefined
from tiramisu.storage import list_sessions from tiramisu.storage import list_sessions
@ -163,7 +163,7 @@ def test_force_default_on_freeze_leader_frozen():
descr = Leadership("dummy1", "", [dummy1, dummy2]) descr = Leadership("dummy1", "", [dummy1, dummy2])
descr = OptionDescription("root", "", [descr]) descr = OptionDescription("root", "", [descr])
cfg = Config(descr) cfg = Config(descr)
raises(ConfigError, "cfg.option('dummy1.dummy1').property.pop('frozen')") raises(LeadershipError, "cfg.option('dummy1.dummy1').property.pop('frozen')")
def test_force_metaconfig_on_freeze_leader_frozen(): def test_force_metaconfig_on_freeze_leader_frozen():
@ -172,7 +172,7 @@ def test_force_metaconfig_on_freeze_leader_frozen():
descr = Leadership("dummy1", "", [dummy1, dummy2]) descr = Leadership("dummy1", "", [dummy1, dummy2])
descr = OptionDescription("root", "", [descr]) descr = OptionDescription("root", "", [descr])
cfg = Config(descr) cfg = Config(descr)
raises(ConfigError, "cfg.option('dummy1.dummy1').property.pop('frozen')") raises(LeadershipError, "cfg.option('dummy1.dummy1').property.pop('frozen')")
def test_force_default_on_freeze_follower(config_type): def test_force_default_on_freeze_follower(config_type):

View File

@ -10,9 +10,11 @@ from tiramisu.error import display_list, ConfigError
from tiramisu.setting import owners, groups from tiramisu.setting import owners, groups
from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \ from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \
StrOption, OptionDescription, Leadership, Config, undefined, \ StrOption, OptionDescription, Leadership, Config, undefined, \
Calculation, Params, ParamOption, ParamValue, ParamIndex, calc_value, calc_value_property_help Calculation, Params, ParamOption, ParamValue, ParamIndex, \
calc_value, calc_value_property_help
from tiramisu.error import PropertiesOptionError from tiramisu.error import PropertiesOptionError
from tiramisu.storage import list_sessions from tiramisu.storage import list_sessions
import warnings
def teardown_function(function): def teardown_function(function):

View File

@ -5,9 +5,13 @@ from .config import config_type, get_config
import warnings import warnings
from py.test import raises from py.test import raises
from tiramisu import BoolOption, StrOption, OptionDescription, Leadership, Config, Params, ParamValue, ParamOption, ParamContext from tiramisu import BoolOption, StrOption, IPOption, NetmaskOption, NetworkOption, BroadcastOption, \
IntOption, \
OptionDescription, Leadership, Config, Params, ParamValue, ParamOption, ParamContext, \
ParamSelfOption, ParamIndex, Calculation, valid_ip_netmask, valid_network_netmask, \
valid_in_network, valid_broadcast, valid_not_equal, undefined
from tiramisu.setting import groups from tiramisu.setting import groups
from tiramisu.error import ValueWarning, ConfigError from tiramisu.error import ValueWarning, ConfigError, PropertiesOptionError
from tiramisu.i18n import _ from tiramisu.i18n import _
from tiramisu.storage import list_sessions from tiramisu.storage import list_sessions
@ -82,15 +86,6 @@ def value_values_auto2(value, values, auto=False):
def value_values_index2(value, values, index, auto=False):
if auto != False:
raise ValueError('auto should be False')
if not (value == 'val1' and values == ['val1'] and index == 'val' or
value == 'val1' and values == ['val1', None] and index == 'val' or
value == 'val2' and values == ['val1', 'val2'] and index == 'val'):
raise ValueError('error')
def value_empty(value, empty, values): def value_empty(value, empty, values):
if not value == 'val' or empty is not False and not values == ['val']: if not value == 'val' or empty is not False and not values == ['val']:
raise ValueError('error') raise ValueError('error')
@ -103,9 +98,9 @@ def valid_from_config(value, config):
def test_validator(config_type): def test_validator(config_type):
opt1 = StrOption('opt1', '', validator=return_true, default='val') opt1 = StrOption('opt1', '', validators=[Calculation(return_true, Params(ParamSelfOption()))], default='val')
raises(ValueError, "StrOption('opt2', '', validator=return_false, default='val')") raises(ValueError, "StrOption('opt2', '', validators=[Calculation(return_false, Params(ParamSelfOption()))], default='val')")
opt2 = StrOption('opt2', '', validator=return_false) opt2 = StrOption('opt2', '', validators=[Calculation(return_false, Params(ParamSelfOption()))])
root = OptionDescription('root', '', [opt1, opt2]) root = OptionDescription('root', '', [opt1, opt2])
cfg_ori = Config(root) cfg_ori = Config(root)
cfg = get_config(cfg_ori, config_type) cfg = get_config(cfg_ori, config_type)
@ -138,9 +133,9 @@ def test_validator(config_type):
def test_validator_params(config_type): def test_validator_params(config_type):
opt1 = StrOption('opt1', '', validator=return_true, validator_params=Params(ParamValue('yes')), default='val') opt1 = StrOption('opt1', '', validators=[Calculation(return_true, Params((ParamSelfOption(), ParamValue('yes'))))], default='val')
raises(ValueError, "StrOption('opt2', '', validator=return_false, validator_params=Params(ParamValue('yes')), default='val')") raises(ValueError, "StrOption('opt2', '', validators=[Calculation(return_false, Params((ParamSelfOption(), ParamValue('yes'))))], default='val')")
opt2 = StrOption('opt2', '', validator=return_false, validator_params=Params(ParamValue('yes'))) opt2 = StrOption('opt2', '', validators=[Calculation(return_false, Params((ParamSelfOption(), ParamValue('yes'))))])
root = OptionDescription('root', '', [opt1, opt2]) root = OptionDescription('root', '', [opt1, opt2])
cfg_ori = Config(root) cfg_ori = Config(root)
cfg = get_config(cfg_ori, config_type) cfg = get_config(cfg_ori, config_type)
@ -157,7 +152,7 @@ def test_validator_params(config_type):
def test_validator_params_value_values(config_type): def test_validator_params_value_values(config_type):
opt1 = StrOption('opt1', '', validator=value_values, default=['val'], multi=True) opt1 = StrOption('opt1', '', validators=[Calculation(value_values, Params((ParamSelfOption(whole=False), ParamSelfOption())))], default=['val'], multi=True)
root = OptionDescription('root', '', [opt1]) root = OptionDescription('root', '', [opt1])
cfg = Config(root) cfg = Config(root)
cfg = get_config(cfg, config_type) cfg = get_config(cfg, config_type)
@ -166,7 +161,7 @@ def test_validator_params_value_values(config_type):
def test_validator_params_value_values_index(config_type): def test_validator_params_value_values_index(config_type):
opt1 = StrOption('opt1', '', validator=value_values_index, default=['val'], multi=True) opt1 = StrOption('opt1', '', validators=[Calculation(value_values_index, Params((ParamSelfOption(whole=False), ParamSelfOption(), ParamIndex())))], default=['val'], multi=True)
root = OptionDescription('root', '', [opt1]) root = OptionDescription('root', '', [opt1])
cfg = Config(root) cfg = Config(root)
cfg = get_config(cfg, config_type) cfg = get_config(cfg, config_type)
@ -175,7 +170,7 @@ def test_validator_params_value_values_index(config_type):
def test_validator_params_value_values_leader(config_type): def test_validator_params_value_values_leader(config_type):
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip reseau autorise", multi=True, validator=value_values) ip_admin_eth0 = StrOption('ip_admin_eth0', "ip reseau autorise", multi=True, validators=[Calculation(value_values, Params((ParamSelfOption(whole=False), ParamSelfOption())))])
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-reseau", multi=True) netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-reseau", multi=True)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
root = OptionDescription('root', '', [interface1]) root = OptionDescription('root', '', [interface1])
@ -186,7 +181,7 @@ def test_validator_params_value_values_leader(config_type):
def test_validator_params_value_values_index_leader(config_type): def test_validator_params_value_values_index_leader(config_type):
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip reseau autorise", multi=True, validator=value_values_index) ip_admin_eth0 = StrOption('ip_admin_eth0', "ip reseau autorise", multi=True, validators=[Calculation(value_values_index, Params((ParamSelfOption(whole=False), ParamSelfOption(), ParamIndex())))])
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-reseau", multi=True) netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-reseau", multi=True)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
root = OptionDescription('root', '', [interface1]) root = OptionDescription('root', '', [interface1])
@ -198,7 +193,7 @@ def test_validator_params_value_values_index_leader(config_type):
def test_validator_params_value_values_follower(config_type): def test_validator_params_value_values_follower(config_type):
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip reseau autorise", multi=True) ip_admin_eth0 = StrOption('ip_admin_eth0', "ip reseau autorise", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-reseau", multi=True, validator=value_values) netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-reseau", multi=True, validators=[Calculation(value_values, Params((ParamSelfOption(), ParamSelfOption(whole=True))))])
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
root = OptionDescription('root', '', [interface1]) root = OptionDescription('root', '', [interface1])
cfg = Config(root) cfg = Config(root)
@ -212,7 +207,7 @@ def test_validator_params_value_values_follower(config_type):
def test_validator_params_value_values_index_follower(config_type): def test_validator_params_value_values_index_follower(config_type):
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip reseau autorise", multi=True) ip_admin_eth0 = StrOption('ip_admin_eth0', "ip reseau autorise", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-reseau", multi=True, validator=value_values_index) netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-reseau", multi=True, validators=[Calculation(value_values_index, Params((ParamSelfOption(), ParamSelfOption(whole=True), ParamIndex())))])
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
root = OptionDescription('root', '', [interface1]) root = OptionDescription('root', '', [interface1])
cfg = Config(root) cfg = Config(root)
@ -224,18 +219,13 @@ def test_validator_params_value_values_index_follower(config_type):
cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.set('val2') cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.set('val2')
def test_validator_params_value_values_notmulti():
raises(ConfigError, "opt1 = StrOption('opt1', '', validator=value_values, default='val')")
def test_validator_params_value_values_kwargs_empty(config_type): def test_validator_params_value_values_kwargs_empty(config_type):
v = BoolOption('v', '', default=False) v = BoolOption('v', '', default=False)
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip reseau autorise", multi=True, default=["ip"]) ip_admin_eth0 = StrOption('ip_admin_eth0', "ip reseau autorise", multi=True, default=["ip"])
netmask_admin_eth0 = StrOption('netmask_admin_eth0', netmask_admin_eth0 = StrOption('netmask_admin_eth0',
"masque du sous-reseau", "masque du sous-reseau",
multi=True, multi=True,
validator=value_empty, validators=[Calculation(value_empty, Params((ParamSelfOption(), ParamOption(v))))])
validator_params=Params(ParamOption(v)))
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
root = OptionDescription('root', '', [v, interface1]) root = OptionDescription('root', '', [v, interface1])
cfg = Config(root) cfg = Config(root)
@ -252,8 +242,7 @@ def test_validator_params_value_values_kwargs(config_type):
netmask_admin_eth0 = StrOption('netmask_admin_eth0', netmask_admin_eth0 = StrOption('netmask_admin_eth0',
"masque du sous-reseau", "masque du sous-reseau",
multi=True, multi=True,
validator=value_values_auto, validators=[Calculation(value_values_auto, Params((ParamSelfOption(), ParamSelfOption(whole=True)), kwargs={'auto': ParamOption(v)}))])
validator_params=Params(kwargs={'auto': ParamOption(v)}))
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
root = OptionDescription('root', '', [v, interface1]) root = OptionDescription('root', '', [v, interface1])
cfg = Config(root) cfg = Config(root)
@ -269,43 +258,7 @@ def test_validator_params_value_values_kwargs_values(config_type):
netmask_admin_eth0 = StrOption('netmask_admin_eth0', netmask_admin_eth0 = StrOption('netmask_admin_eth0',
"masque du sous-reseau", "masque du sous-reseau",
multi=True, multi=True,
validator=value_values_auto2, validators=[Calculation(value_values_auto2, Params(ParamSelfOption(), kwargs={'values': ParamOption(ip_admin_eth0)}))])
validator_params=Params(kwargs={'values': ParamOption(ip_admin_eth0)}))
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
root = OptionDescription('root', '', [interface1])
cfg = Config(root)
cfg = get_config(cfg, config_type)
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['val'])
cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('val1')
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['val', 'val'])
cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.set('val2')
def test_validator_params_value_values_kwargs2(config_type):
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip reseau autorise", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0',
"masque du sous-reseau",
multi=True,
validator=value_values_index2,
validator_params=Params(ParamValue(['val1']), {'index': ParamOption(ip_admin_eth0)}))
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
root = OptionDescription('root', '', [interface1])
cfg = Config(root)
cfg = get_config(cfg, config_type)
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['val'])
cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('val1')
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['val', 'val'])
def test_validator_params_value_values_kwargs_index(config_type):
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip reseau autorise", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0',
"masque du sous-reseau",
multi=True,
validator=value_values_index2,
validator_params=Params(kwargs={'index': ParamOption(ip_admin_eth0)}))
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
root = OptionDescription('root', '', [interface1]) root = OptionDescription('root', '', [interface1])
cfg = Config(root) cfg = Config(root)
@ -318,7 +271,7 @@ def test_validator_params_value_values_kwargs_index(config_type):
def test_validator_params_context(): def test_validator_params_context():
opt1 = StrOption('opt1', '', validator=is_context, validator_params=Params(ParamContext()), default='val') opt1 = StrOption('opt1', '', validators=[Calculation(is_context, Params((ParamSelfOption(), ParamContext())))], default='val')
root = OptionDescription('root', '', [opt1]) root = OptionDescription('root', '', [opt1])
cfg = Config(root) cfg = Config(root)
# cfg = get_config(cfg, config_type) # ParamContext not supported # cfg = get_config(cfg, config_type) # ParamContext not supported
@ -329,7 +282,7 @@ def test_validator_params_context():
def test_validator_params_context_value(): def test_validator_params_context_value():
opt1 = StrOption('opt1', '', 'yes') opt1 = StrOption('opt1', '', 'yes')
opt2 = StrOption('opt2', '', validator=valid_from_config, validator_params=Params(ParamContext()), default='val') opt2 = StrOption('opt2', '', validators=[Calculation(valid_from_config, Params((ParamSelfOption(), ParamContext())))], default='val')
root = OptionDescription('root', '', [opt1, opt2]) root = OptionDescription('root', '', [opt1, opt2])
cfg = Config(root) cfg = Config(root)
# cfg = get_config(cfg_ori, config_type) # ParamContext not supported # cfg = get_config(cfg_ori, config_type) # ParamContext not supported
@ -347,8 +300,8 @@ def test_validator_params_context_value():
def test_validator_params_key(config_type): def test_validator_params_key(config_type):
opt1 = StrOption('opt1', '', validator=return_true, validator_params=Params(kwargs={'param': ParamValue('yes')}), default='val') opt1 = StrOption('opt1', '', validators=[Calculation(return_true, Params(ParamSelfOption(), kwargs={'param': ParamValue('yes')}))], default='val')
raises(ConfigError, "StrOption('opt2', '', validator=return_true, validator_params=Params(kwargs={'param_unknown': ParamValue('yes')}), default='val')") raises(ConfigError, "StrOption('opt2', '', validators=[Calculation(return_true, Params(ParamSelfOption(), kwargs={'param_unknown': ParamValue('yes')}))], default='val')")
root = OptionDescription('root', '', [opt1]) root = OptionDescription('root', '', [opt1])
cfg = Config(root) cfg = Config(root)
cfg = get_config(cfg, config_type) cfg = get_config(cfg, config_type)
@ -357,7 +310,7 @@ def test_validator_params_key(config_type):
def test_validator_params_option(config_type): def test_validator_params_option(config_type):
opt0 = StrOption('opt0', '', default='yes') opt0 = StrOption('opt0', '', default='yes')
opt1 = StrOption('opt1', '', validator=return_true, validator_params=Params(ParamOption(opt0)), default='val') opt1 = StrOption('opt1', '', validators=[Calculation(return_true, Params((ParamSelfOption(), ParamOption(opt0))))], default='val')
r = OptionDescription('root', '', [opt0, opt1]) r = OptionDescription('root', '', [opt0, opt1])
cfg_ori = Config(r) cfg_ori = Config(r)
cfg = get_config(cfg_ori, config_type) cfg = get_config(cfg_ori, config_type)
@ -375,7 +328,7 @@ def test_validator_params_option(config_type):
def test_validator_multi(config_type): def test_validator_multi(config_type):
opt1 = StrOption('opt1', '', validator=return_if_val, multi=True) opt1 = StrOption('opt1', '', validators=[Calculation(return_if_val, Params(ParamSelfOption(whole=False)))], multi=True)
root = OptionDescription('root', '', [opt1]) root = OptionDescription('root', '', [opt1])
cfg_ori = Config(root) cfg_ori = Config(root)
cfg = get_config(cfg_ori, config_type) cfg = get_config(cfg_ori, config_type)
@ -394,9 +347,9 @@ def test_validator_multi(config_type):
def test_validator_warning(config_type): def test_validator_warning(config_type):
opt1 = StrOption('opt1', '', validator=return_true, default='val', warnings_only=True) opt1 = StrOption('opt1', '', validators=[Calculation(return_true, Params(ParamSelfOption()), warnings_only=True)], default='val')
opt2 = StrOption('opt2', '', validator=return_false, warnings_only=True) opt2 = StrOption('opt2', '', validators=[Calculation(return_false, Params(ParamSelfOption()), warnings_only=True)])
opt3 = StrOption('opt3', '', validator=return_if_val, multi=True, warnings_only=True) opt3 = StrOption('opt3', '', validators=[Calculation(return_if_val, Params(ParamSelfOption(whole=False)), warnings_only=True)], multi=True)
root = OptionDescription('root', '', [opt1, opt2, opt3]) root = OptionDescription('root', '', [opt1, opt2, opt3])
cfg = Config(root) cfg = Config(root)
cfg = get_config(cfg, config_type) cfg = get_config(cfg, config_type)
@ -440,9 +393,9 @@ def test_validator_warning(config_type):
def test_validator_warning_disabled(config_type): def test_validator_warning_disabled(config_type):
opt1 = StrOption('opt1', '', validator=return_true, default='val', warnings_only=True) opt1 = StrOption('opt1', '', validators=[Calculation(return_true, Params(ParamSelfOption()), warnings_only=True)], default='val')
opt2 = StrOption('opt2', '', validator=return_false, warnings_only=True) opt2 = StrOption('opt2', '', validators=[Calculation(return_false, Params(ParamSelfOption()), warnings_only=True)])
opt3 = StrOption('opt3', '', validator=return_if_val, multi=True, warnings_only=True) opt3 = StrOption('opt3', '', validators=[Calculation(return_if_val, Params(ParamSelfOption(whole=False)), warnings_only=True)], multi=True)
root = OptionDescription('root', '', [opt1, opt2, opt3]) root = OptionDescription('root', '', [opt1, opt2, opt3])
cfg_ori = Config(root) cfg_ori = Config(root)
cfg_ori.property.pop('warnings') cfg_ori.property.pop('warnings')
@ -485,8 +438,8 @@ def test_validator_warning_disabled(config_type):
def test_validator_warning_leadership(config_type): def test_validator_warning_leadership(config_type):
display_name_ip = "ip reseau autorise" display_name_ip = "ip reseau autorise"
display_name_netmask = "masque du sous-reseau" display_name_netmask = "masque du sous-reseau"
ip_admin_eth0 = StrOption('ip_admin_eth0', display_name_ip, multi=True, validator=return_false, warnings_only=True) ip_admin_eth0 = StrOption('ip_admin_eth0', display_name_ip, multi=True, validators=[Calculation(return_false, Params(ParamSelfOption(whole=False)), warnings_only=True)])
netmask_admin_eth0 = StrOption('netmask_admin_eth0', display_name_netmask, multi=True, validator=return_if_val, warnings_only=True) netmask_admin_eth0 = StrOption('netmask_admin_eth0', display_name_netmask, multi=True, validators=[Calculation(return_if_val, Params(ParamSelfOption()), warnings_only=True)])
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
assert interface1.impl_get_group_type() == groups.leadership assert interface1.impl_get_group_type() == groups.leadership
root = OptionDescription('root', '', [interface1]) root = OptionDescription('root', '', [interface1])
@ -543,8 +496,7 @@ def test_validator_follower_param(config_type):
netmask_admin_eth0 = StrOption('netmask_admin_eth0', netmask_admin_eth0 = StrOption('netmask_admin_eth0',
"masque du sous-reseau", "masque du sous-reseau",
multi=True, multi=True,
validator=return_true, validators=[Calculation(return_true, Params(ParamSelfOption(), kwargs={'param': ParamOption(ip_admin_eth0)}))])
validator_params=Params(kwargs={'param': ParamOption(ip_admin_eth0)}))
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
root = OptionDescription('root', '', [interface1]) root = OptionDescription('root', '', [interface1])
cfg = Config(root) cfg = Config(root)
@ -560,9 +512,8 @@ def test_validator_dependencies():
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip reseau autorise") ip_admin_eth0 = StrOption('ip_admin_eth0', "ip reseau autorise")
netmask_admin_eth0 = StrOption('netmask_admin_eth0', netmask_admin_eth0 = StrOption('netmask_admin_eth0',
"masque du sous-reseau", "masque du sous-reseau",
validator=return_true, validators=[Calculation(return_true, Params(ParamSelfOption(whole=False), kwargs={'param': ParamOption(ip_admin_eth0)}))])
validator_params=Params(kwargs={'param': ParamOption(ip_admin_eth0)})) opt2 = StrOption('opt2', '', validators=[Calculation(return_false, Params(ParamSelfOption(whole=False)))])
opt2 = StrOption('opt2', '', validator=return_false)
root = OptionDescription('root', '', [ip_admin_eth0, netmask_admin_eth0, opt2]) root = OptionDescription('root', '', [ip_admin_eth0, netmask_admin_eth0, opt2])
cfg = Config(root) cfg = Config(root)
assert cfg.option('ip_admin_eth0').option.has_dependency() is False assert cfg.option('ip_admin_eth0').option.has_dependency() is False
@ -572,3 +523,611 @@ def test_validator_dependencies():
assert cfg.option('ip_admin_eth0').option.has_dependency(False) is True assert cfg.option('ip_admin_eth0').option.has_dependency(False) is True
assert cfg.option('netmask_admin_eth0').option.has_dependency(False) is False assert cfg.option('netmask_admin_eth0').option.has_dependency(False) is False
assert cfg.option('opt2').option.has_dependency(False) is False assert cfg.option('opt2').option.has_dependency(False) is False
def test_validator_ip_netmask(config_type):
a = IPOption('a', '')
b = NetmaskOption('b', '', validators=[Calculation(valid_ip_netmask, Params((ParamOption(a, todict=True), ParamSelfOption())))])
od = OptionDescription('od', '', [a, b])
cfg_ori = Config(od)
cfg = cfg_ori
cfg = get_config(cfg_ori, config_type)
cfg.option('a').value.set('192.168.1.1')
cfg.option('b').value.set('255.255.255.0')
cfg.option('a').value.set('192.168.1.2')
cfg.option('b').value.set('255.255.255.128')
cfg.option('b').value.set('255.255.255.0')
cfg.option('a').value.set('192.168.1.0')
raises(ValueError, "cfg.option('b').value.get()")
cfg.option('a').value.set('192.168.1.255')
raises(ValueError, "cfg.option('b').value.get()")
cfg.option('a').value.reset()
cfg.option('b').value.reset()
cfg.option('a').value.set('192.168.1.255')
raises(ValueError, "cfg.option('b').value.set('255.255.255.0')")
#
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.add('demoting_error_warning')
cfg = get_config(cfg_ori, config_type)
with warnings.catch_warnings(record=True) as w:
cfg.option('b').value.set('255.255.255.0')
assert len(w) == 1
def test_validator_network_netmask(config_type):
a = NetworkOption('a', '')
b = NetmaskOption('b', '', validators=[Calculation(valid_network_netmask, Params((ParamOption(a, todict=True), ParamSelfOption())))])
od = OptionDescription('od', '', [a, b])
cfg_ori = Config(od)
cfg = get_config(cfg_ori, config_type)
cfg.option('a').value.set('192.168.1.1')
cfg.option('b').value.set('255.255.255.255')
cfg.option('b').value.reset()
cfg.option('a').value.set('192.168.1.0')
cfg.option('b').value.set('255.255.255.0')
cfg.option('a').value.set('192.168.1.1')
raises(ValueError, "cfg.option('b').value.get()")
#
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.add('demoting_error_warning')
cfg = get_config(cfg_ori, config_type)
with warnings.catch_warnings(record=True) as w:
cfg.option('a').value.set('192.168.1.1')
assert len(w) == 0
with warnings.catch_warnings(record=True) as w:
cfg.option('b').value.get()
assert len(w) == 1
def test_validator_ip_in_network(config_type):
a = NetworkOption('a', '')
b = NetmaskOption('b', '')
c = IPOption('c', '', validators=[Calculation(valid_in_network, Params((ParamSelfOption(), ParamOption(a, todict=True), ParamOption(b, todict=True))))])
d = IPOption('d', '', validators=[Calculation(valid_in_network, Params((ParamSelfOption(), ParamOption(a, todict=True), ParamOption(b, todict=True))), warnings_only=True)])
od = OptionDescription('od', '', [a, b, c, d])
warnings.simplefilter("always", ValueWarning)
cfg = Config(od)
cfg = get_config(cfg, config_type)
cfg.option('a').value.set('192.168.1.0')
cfg.option('b').value.set('255.255.255.0')
cfg.option('c').value.set('192.168.1.1')
raises(ValueError, "cfg.option('c').value.set('192.168.2.1')")
raises(ValueError, "cfg.option('c').value.set('192.168.1.0')")
raises(ValueError, "cfg.option('c').value.set('192.168.1.255')")
with warnings.catch_warnings(record=True) as w:
cfg.option('d').value.set('192.168.2.1')
assert len(w) == 1
def test_validator_ip_in_network_cidr(config_type):
a = NetworkOption('a', '', cidr=True)
c = IPOption('c', '', validators=[Calculation(valid_in_network, Params((ParamSelfOption(), ParamOption(a, todict=True))))])
d = IPOption('d', '', validators=[Calculation(valid_in_network, Params((ParamSelfOption(), ParamOption(a, todict=True))), warnings_only=True)])
od = OptionDescription('od', '', [a, c, d])
warnings.simplefilter("always", ValueWarning)
cfg = Config(od)
cfg = get_config(cfg, config_type)
cfg.option('a').value.set('192.168.1.0/24')
cfg.option('c').value.set('192.168.1.1')
raises(ValueError, "cfg.option('c').value.set('192.168.2.1')")
raises(ValueError, "cfg.option('c').value.set('192.168.1.0')")
raises(ValueError, "cfg.option('c').value.set('192.168.1.255')")
with warnings.catch_warnings(record=True) as w:
cfg.option('d').value.set('192.168.2.1')
assert len(w) == 1
def test_validator_ip_netmask_multi(config_type):
a = IPOption('a', '', multi=True)
b = NetmaskOption('b', '', multi=True, validators=[Calculation(valid_ip_netmask, Params((ParamOption(a, todict=True), ParamSelfOption())))])
od = Leadership('a', '', [a, b])
od2 = OptionDescription('od2', '', [od])
cfg_ori = Config(od2)
cfg = get_config(cfg_ori, config_type)
cfg.option('a.a').value.set(['192.168.1.1'])
cfg.option('a.b', 0).value.set('255.255.255.0')
cfg.option('a.a').value.set(['192.168.1.2'])
cfg.option('a.b', 0).value.set('255.255.255.128')
cfg.option('a.b', 0).value.set('255.255.255.0')
cfg.option('a.a').value.set(['192.168.1.0'])
raises(ValueError, "cfg.option('a.b', 0).value.get()")
#
cfg.option('a.a').value.set(['192.168.1.2'])
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.add('demoting_error_warning')
cfg = get_config(cfg_ori, config_type)
cfg.option('a.a').value.set(['192.168.1.0'])
with warnings.catch_warnings(record=True) as w:
cfg.option('a.b', 0).value.get()
assert len(w) == 1
def test_validator_network_netmask_multi(config_type):
a = NetworkOption('a', '', multi=True)
b = NetmaskOption('b', '', multi=True, validators=[Calculation(valid_network_netmask, Params((ParamOption(a), ParamSelfOption())))])
od = Leadership('a', '', [a, b])
od2 = OptionDescription('od', '', [od])
cfg = Config(od2)
cfg = get_config(cfg, config_type)
cfg.option('a.a').value.set(['192.168.1.1'])
cfg.option('a.b', 0).value.set('255.255.255.255')
cfg.option('a.b', 0).value.reset()
cfg.option('a.a').value.set(['192.168.1.0'])
cfg.option('a.b', 0).value.set('255.255.255.0')
cfg.option('a.a').value.set(['192.168.1.1'])
raises(ValueError, "cfg.option('a.b', 0).value.get()")
def test_validator_network_netmask_multi_follower_default_multi(config_type):
a = NetworkOption('a', '', default_multi=u'192.168.1.0', multi=True, properties=('mandatory',))
b = NetmaskOption('b', '', default_multi=u'255.255.255.0', multi=True, properties=('mandatory',), validators=[Calculation(valid_network_netmask, Params((ParamOption(a), ParamSelfOption())))])
od = Leadership('a', '', [a, b])
od2 = OptionDescription('od2', '', [od])
cfg = Config(od2)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('a.a').value.set([undefined])
assert cfg.option('a.a').value.get() == ['192.168.1.0']
assert cfg.option('a.b', 0).value.get() == '255.255.255.0'
def test_validator_network_netmask_multi_follower_default(config_type):
a = NetworkOption('a', '', multi=True, properties=('mandatory',))
b = NetmaskOption('b', '', default_multi=u'255.255.255.0', multi=True, properties=('mandatory',), validators=[Calculation(valid_network_netmask, Params((ParamOption(a), ParamSelfOption())))])
od = Leadership('a', '', [a, b])
od2 = OptionDescription('od2', '', [od])
cfg_ori = Config(od2)
cfg_ori.property.read_write()
cfg_ori.property.pop('cache')
cfg = get_config(cfg_ori, config_type)
assert cfg.option('a.a').value.get() == []
cfg.option('a.a').value.set(['192.168.1.0'])
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.read_only()
cfg = get_config(cfg_ori, config_type)
assert cfg.option('a.a').value.get() == [u'192.168.1.0']
assert cfg.option('a.b', 0).value.get() == u'255.255.255.0'
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.read_write()
cfg = get_config(cfg_ori, config_type)
cfg.option('a.a').value.set([u'192.168.1.0', u'192.168.1.1'])
raises(ValueError, "cfg.option('a.b', 0).value.set([u'192.168.1.0'])")
raises(ValueError, "cfg.option('a.b', 1).value.set([u'192.168.1.1'])")
cfg.option('a.a').value.set(['192.168.1.0', undefined])
cfg.option('a.b', 0).value.set('255.255.255.0')
cfg.option('a.b', 1).value.set('255.255.255.255')
cfg.option('a.a').value.set([u'192.168.1.0', u'192.168.1.1'])
def return_netmask(*args, **kwargs):
return u'255.255.255.0'
def return_netmask2(leader):
if leader is not None:
if leader.endswith('2.1'):
return u'255.255.255.0'
if not leader.endswith('.0'):
return u'255.255.255.255'
return u'255.255.255.0'
def test_validator_network_netmask_multi_follower_callback(config_type):
a = NetworkOption('a', '', multi=True, properties=('mandatory',))
b = NetmaskOption('b', '', Calculation(return_netmask, Params(kwargs={'index': ParamIndex()})), multi=True, properties=('mandatory',), validators=[Calculation(valid_network_netmask, Params((ParamOption(a), ParamSelfOption())))])
od = Leadership('a', '', [a, b])
od2 = OptionDescription('od2', '', [od])
cfg_ori = Config(od2)
cfg_ori.property.read_write()
cfg_ori.property.pop('cache')
cfg = get_config(cfg_ori, config_type)
assert cfg.option('a.a').value.get() == []
cfg.option('a.a').value.set(['192.168.1.0'])
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.read_only()
cfg = get_config(cfg_ori, config_type)
assert cfg.option('a.a').value.get() == [u'192.168.1.0']
assert cfg.option('a.b', 0).value.get() == '255.255.255.0'
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.read_write()
cfg = get_config(cfg_ori, config_type)
cfg.option('a.a').value.set([u'192.168.1.0', u'192.168.1.1'])
cfg.option('a.b', 0).value.get()
raises(ValueError, "cfg.option('a.b', 1).value.get()")
cfg.option('a.a').value.set(['192.168.1.0', undefined])
cfg.option('a.b', 0).value.set('255.255.255.0')
cfg.option('a.b', 1).value.set('255.255.255.255')
cfg.option('a.a').value.set(['192.168.1.0', '192.168.1.1'])
def test_validator_network_netmask_multi_follower_callback_value(config_type):
a = NetworkOption('a', '', multi=True, properties=('mandatory',))
b = NetmaskOption('b', '', Calculation(return_netmask2, Params(ParamOption(a))), multi=True, properties=('mandatory',), validators=[Calculation(valid_network_netmask, Params((ParamOption(a), ParamSelfOption())))])
od = Leadership('a', '', [a, b])
od2 = OptionDescription('od2', '', [od])
cfg = Config(od2)
cfg.property.read_write()
cfg.property.pop('cache')
cfg = get_config(cfg, config_type)
assert cfg.option('a.a').value.get() == []
cfg.option('a.a').value.set(['192.168.1.0'])
assert cfg.option('a.a').value.get() == ['192.168.1.0']
assert cfg.option('a.b', 0).value.get() == '255.255.255.0'
cfg.option('a.a').value.set(['192.168.1.0', '192.168.2.1'])
assert cfg.option('a.b', 0).value.get() == '255.255.255.0'
raises(ValueError, "cfg.option('a.b', 1).value.get()")
cfg.option('a.a').value.pop(1)
#
assert cfg.option('a.a').value.get() == [u'192.168.1.0']
assert cfg.option('a.b', 0).value.get() == '255.255.255.0'
cfg.option('a.a').value.set(['192.168.2.1'])
raises(ValueError, "cfg.option('a.b', 0).value.get()")
cfg.option('a.a').value.set(['192.168.1.0'])
#
assert cfg.option('a.a').value.get() == [u'192.168.1.0']
assert cfg.option('a.b', 0).value.get() == '255.255.255.0'
cfg.option('a.a').value.set(['192.168.1.0', '192.168.1.1'])
cfg.option('a.b', 0).value.set('255.255.255.0')
cfg.option('a.b', 1).value.set('255.255.255.255')
def test_validator_ip_netmask_multi_leader(config_type):
a = IPOption('a', '', multi=True)
b = NetmaskOption('b', '', multi=True, validators=[Calculation(valid_ip_netmask, Params((ParamOption(a), ParamSelfOption())))])
od = Leadership('a', '', [a, b])
od2 = OptionDescription('od2', '', [od])
cfg = Config(od2)
cfg = get_config(cfg, config_type)
cfg.option('a.a').value.set(['192.168.1.1'])
cfg.option('a.b', 0).value.set('255.255.255.0')
cfg.option('a.a').value.set(['192.168.1.2'])
cfg.option('a.b', 0).value.set('255.255.255.128')
cfg.option('a.b', 0).value.set('255.255.255.0')
cfg.option('a.a').value.set(['192.168.1.0'])
raises(ValueError, "cfg.option('a.b', 0).value.get()")
cfg.option('a.a').value.set(['192.168.1.128'])
raises(ValueError, "cfg.option('a.b', 0).value.set('255.255.255.128')")
cfg.option('a.a').value.set(['192.168.1.2', '192.168.1.3'])
def test_validator_network_netmask_multi_leader(config_type):
a = NetworkOption('a', '', multi=True)
b = NetmaskOption('b', '', multi=True, validators=[Calculation(valid_network_netmask, Params((ParamOption(a), ParamSelfOption())))])
od = Leadership('a', '', [a, b])
od2 = OptionDescription('od2', '', [od])
cfg = Config(od2)
cfg = get_config(cfg, config_type)
cfg.option('a.a').value.set(['192.168.1.1'])
cfg.option('a.b', 0).value.set('255.255.255.255')
cfg.option('a.b', 0).value.reset()
cfg.option('a.a').value.set(['192.168.1.0'])
cfg.option('a.b', 0).value.set('255.255.255.0')
cfg.option('a.a').value.set(['192.168.1.1'])
raises(ValueError, "cfg.option('a.b', 0).value.get()")
def test_validator_broadcast(config_type):
a = NetworkOption('a', '', multi=True)
b = NetmaskOption('b', '', multi=True, validators=[Calculation(valid_network_netmask, Params((ParamOption(a), ParamSelfOption())))])
c = BroadcastOption('c', '', multi=True, validators=[Calculation(valid_broadcast, Params((ParamOption(a), ParamOption(b), ParamSelfOption())))])
od = Leadership('a', '', [a, b, c])
od2 = OptionDescription('od2', '', [od])
cfg = Config(od2)
cfg = get_config(cfg, config_type)
#first, test network_netmask
cfg.option('a.a').value.set(['192.168.1.128'])
raises(ValueError, "cfg.option('a.a').value.set(['255.255.255.0'])")
#
cfg.option('a.a').value.set(['192.168.1.0'])
cfg.option('a.b', 0).value.set('255.255.255.0')
cfg.option('a.c', 0).value.set('192.168.1.255')
cfg.option('a.a').value.set(['192.168.1.1'])
raises(ValueError, "cfg.option('a.b', 0).value.get()")
raises(ValueError, "cfg.option('a.c', 0).value.get()")
#
cfg.option('a.a').value.set(['192.168.1.0', '192.168.2.128'])
cfg.option('a.b', 0).value.set('255.255.255.0')
cfg.option('a.b', 1).value.set('255.255.255.128')
cfg.option('a.c', 0).value.set('192.168.1.255')
cfg.option('a.c', 1).value.set('192.168.2.255')
raises(ValueError, "cfg.option('a.c', 1).value.set('192.168.2.128')")
cfg.option('a.c', 1).value.set('192.168.2.255')
def test_validator_broadcast_warnings(config_type):
warnings.simplefilter("always", ValueWarning)
a = NetworkOption('a', '', properties=('mandatory', 'disabled'))
b = NetmaskOption('b', '', properties=('mandatory', 'disabled'), validators=[Calculation(valid_network_netmask, Params((ParamOption(a), ParamSelfOption())), warnings_only=True)])
od = OptionDescription('a', '', [a, b])
cfg_ori = Config(od)
cfg = get_config(cfg_ori, config_type)
with warnings.catch_warnings(record=True) as w:
cfg.option('a').value.set('192.168.1.4')
cfg.option('b').value.set('255.255.255.0')
assert len(w) == 1
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.read_write()
cfg = get_config(cfg_ori, config_type)
with warnings.catch_warnings(record=True) as w:
list(cfg.value.mandatory())
assert len(w) == 0
def test_validator_broadcast_default_1():
a = NetworkOption('a', '', '192.168.1.0')
b = NetmaskOption('b', '', '255.255.255.128')
c = BroadcastOption('c', '', '192.168.2.127', validators=[Calculation(valid_broadcast, Params((ParamOption(a), ParamOption(b), ParamSelfOption())))])
od = OptionDescription('a', '', [a, b, c])
cfg = Config(od)
raises(ValueError, "cfg.value.dict()")
def test_validator_broadcast_default_2():
a = NetworkOption('a', '', '192.168.1.0')
b = NetmaskOption('b', '', '255.255.255.128')
d = BroadcastOption('d', '', '192.168.1.127', validators=[Calculation(valid_broadcast, Params((ParamOption(a), ParamOption(b), ParamSelfOption())))])
od = OptionDescription('a', '', [a, b, d])
cfg = Config(od)
assert cfg.value.dict()
def test_validator_not_all(config_type):
a = NetworkOption('a', '', multi=True)
b = NetmaskOption('b', '', multi=True, validators=[Calculation(valid_network_netmask, Params((ParamOption(a), ParamSelfOption())))])
c = BroadcastOption('c', '', multi=True)
od = Leadership('a', '', [a, b, c])
od = OptionDescription('od2', '', [od])
cfg = Config(od)
cfg = get_config(cfg, config_type)
cfg.option('a.a').value.set(['192.168.1.0'])
cfg.option('a.b', 0).value.set('255.255.255.0')
cfg.option('a.c', 0).value.set('192.168.1.255')
def test_validator_network_netmask_mandatory(config_type):
a = NetworkOption('a', '', multi=True, properties=('mandatory',), default=[u'0.0.0.0'])
b = NetmaskOption('b', '', multi=True, properties=('mandatory',), default_multi=u'0.0.0.0', validators=[Calculation(valid_network_netmask, Params((ParamOption(a), ParamSelfOption())))])
od = Leadership('a', '', [a, b])
od2 = OptionDescription('od2', '', [od])
cfg = Config(od2)
cfg.property.read_only()
cfg = get_config(cfg, config_type)
cfg.value.dict()
def test_validator_has_dependency():
a = IPOption('a', '')
b = NetmaskOption('b', '', validators=[Calculation(valid_ip_netmask, Params((ParamOption(a), ParamSelfOption())))])
od = OptionDescription('od', '', [a, b])
cfg = Config(od)
assert cfg.option('a').option.has_dependency() is False
assert cfg.option('b').option.has_dependency() is True
assert cfg.option('a').option.has_dependency(False) is True
assert cfg.option('b').option.has_dependency(False) is False
def test_validator_warnings_only_more_option(config_type):
a = IntOption('a', '')
b = IntOption('b', '')
d = IntOption('d', '', validators=[Calculation(valid_not_equal, Params((ParamSelfOption(), ParamOption(a, todict=True), ParamOption(b, todict=True))), warnings_only=True)])
od = OptionDescription('od', '', [a, b, d])
cfg = Config(od)
cfg = get_config(cfg, config_type)
cfg.option('a').value.set(1)
cfg.option('b').value.set(1)
warnings.simplefilter("always", ValueWarning)
with warnings.catch_warnings(record=True) as w:
cfg.option('d').value.get()
assert w == []
with warnings.catch_warnings(record=True) as w:
cfg.option('d').value.set(1)
assert w != []
assert len(w) == 1
def test_validator_error_prefix():
a = IntOption('a', '')
b = IntOption('b', '', validators=[Calculation(valid_not_equal, Params((ParamSelfOption(), ParamOption(a, todict=True))))])
od = OptionDescription('od', '', [a, b])
cfg = Config(od)
cfg.option('a').value.set(1)
try:
cfg.option('b').value.set(1)
except Exception as err:
assert str(err) == _('"{0}" is an invalid {1} for "{2}"').format('1', _('integer'), 'b') + ', ' + _('value is identical to {}').format('"a"')
try:
cfg.option('b').value.set(1)
except Exception as err:
err.prefix = ''
assert str(err) == _('value is identical to {}').format('"a"')
def test_validator_warnings_only_option(config_type):
a = IntOption('a', '')
b = IntOption('b', '', warnings_only=True, validators=[Calculation(valid_not_equal, Params((ParamSelfOption(), ParamOption(a, todict=True))))])
od = OptionDescription('od', '', [a, b])
cfg_ori = Config(od)
cfg = get_config(cfg_ori, config_type)
cfg.option('a').value.set(1)
raises(ValueError, "cfg.option('b').value.set(1)")
def test_validator_not_equal(config_type):
a = IntOption('a', '')
b = IntOption('b', '', validators=[Calculation(valid_not_equal, Params((ParamSelfOption(), ParamOption(a))))])
od = OptionDescription('od', '', [a, b])
cfg_ori = Config(od)
cfg = get_config(cfg_ori, config_type)
assert cfg.option('a').value.get() is None
assert cfg.option('b').value.get() is None
cfg.option('a').value.set(1)
cfg.option('a').value.reset()
cfg.option('a').value.set(1)
raises(ValueError, "cfg.option('b').value.set(1)")
cfg.option('b').value.set(2)
#
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.add('demoting_error_warning')
cfg = get_config(cfg_ori, config_type)
warnings.simplefilter("always", ValueWarning)
with warnings.catch_warnings(record=True) as w:
cfg.option('b').value.set(1)
assert len(w) == 1
def test_validator_not_equal_leadership(config_type):
a = IntOption('a', '', multi=True)
b = IntOption('b', '', multi=True, validators=[Calculation(valid_not_equal, Params((ParamSelfOption(), ParamOption(a))))])
od = Leadership('a', '', [a, b])
od2 = OptionDescription('b', '', [od])
cfg = Config(od2)
cfg = get_config(cfg, config_type)
assert cfg.option('a.a').value.get() == []
cfg.option('a.a').value.set([1])
cfg.option('a.a').value.reset()
cfg.option('a.a').value.set([1])
raises(ValueError, "cfg.option('a.b', 0).value.set(1)")
cfg.option('a.b', 0).value.set(2)
cfg.option('a.a').value.reset()
cfg.option('a.a').value.set([1])
cfg.value.dict()
def test_validator_not_equal_leadership_default():
a = IntOption('a', '', multi=True)
b = IntOption('b', '', multi=True, default_multi=1, validators=[Calculation(valid_not_equal, Params((ParamSelfOption(), ParamOption(a))))])
od = Leadership('a', '', [a, b])
od2 = OptionDescription('a', '', [od])
cfg = Config(od2)
# FIXME cfg = get_config(cfg, config_type)
assert cfg.option('a.a').value.get() == []
cfg.option('a.a').value.set([1])
raises(ValueError, "cfg.option('a.b', 0).value.get()")
cfg.option('a.a').value.set([2])
cfg.option('a.a').value.reset()
cfg.option('a.a').value.set([2])
#
cfg.property.add('demoting_error_warning')
with warnings.catch_warnings(record=True) as w:
cfg.option('a.b', 0).value.set(2)
assert len(w) == 1
def test_validator_default_diff():
a = IntOption('a', '', 3)
b = IntOption('b', '', 1, validators=[Calculation(valid_not_equal, Params((ParamSelfOption(), ParamOption(a, todict=True))))])
od = OptionDescription('od', '', [a, b])
cfg = Config(od)
# FIXME cfg = get_config(cfg, config_type)
cfg.option('b').value.set(2)
cfg.option('a').value.set(1)
owner = cfg.owner.get()
assert cfg.option('b').owner.get() == owner
raises(ValueError, "cfg.option('b').value.reset()")
assert cfg.option('b').owner.get() == owner
#
cfg.property.add('demoting_error_warning')
with warnings.catch_warnings(record=True) as w:
cfg.option('b').value.reset()
assert len(w) == 1
def test_validator_permissive(config_type):
a = IntOption('a', '', 1, properties=('hidden',))
b = IntOption('b', '', 2, validators=[Calculation(valid_not_equal, Params((ParamSelfOption(), ParamOption(a, todict=True))))])
od = OptionDescription('od', '', [a, b])
cfg = Config(od)
cfg.property.read_write()
cfg.permissive.set(frozenset(['hidden']))
cfg = get_config(cfg, config_type)
raises(ValueError, "cfg.option('b').value.set(1)")
cfg.option('b').value.set(2)
def test_validator_disabled(config_type):
a = IntOption('a', '', 1, properties=('disabled',))
b = IntOption('b', '', 2, validators=[Calculation(valid_not_equal, Params((ParamSelfOption(), ParamOption(a, todict=True, raisepropertyerror=True))))])
od = OptionDescription('od', '', [a, b])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
raises(PropertiesOptionError, "cfg.option('b').value.set(1)")
def test_consistency_disabled_transitive(config_type):
a = IntOption('a', '', 1, properties=('disabled',))
b = IntOption('b', '', 2, validators=[Calculation(valid_not_equal, Params((ParamSelfOption(), ParamOption(a, todict=True, notraisepropertyerror=True))))])
od = OptionDescription('od', '', [a, b])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('b').value.set(1)
def test_consistency_double_warnings(config_type):
a = IntOption('a', '', 1)
b = IntOption('b', '', 1)
c = IntOption('c', '', validators=[Calculation(valid_not_equal, Params((ParamSelfOption(), ParamOption(a, todict=True))), warnings_only=True), Calculation(valid_not_equal, Params((ParamSelfOption(), ParamOption(b, todict=True))), warnings_only=True)])
od = OptionDescription('od', '', [a, b, c])
warnings.simplefilter("always", ValueWarning)
od2 = OptionDescription('od2', '', [od])
cfg_ori = Config(od2)
cfg = get_config(cfg_ori, config_type)
with warnings.catch_warnings(record=True) as w:
cfg.option('od.c').value.set(1)
assert w != []
if config_type == 'tiramisu-api':
# in this case warnings is for '"a" and "b"'
assert len(w) == 1
else:
# in this cas one warnings is for "a" and the second for "b"
assert len(w) == 2
cfg.option('od.a').value.set(2)
with warnings.catch_warnings(record=True) as w:
cfg.option('od.c').value.get()
assert len(w) == 1
#
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.pop('warnings')
cfg = get_config(cfg_ori, config_type)
with warnings.catch_warnings(record=True) as w:
cfg.option('od.c').value.set(1)
assert w == []
def test_consistency_warnings_error(config_type):
a = IntOption('a', '', 1)
b = IntOption('b', '', 1)
c = IntOption('c', '', validators=[
Calculation(valid_not_equal, Params((ParamSelfOption(), ParamOption(a, todict=True))), warnings_only=True),
Calculation(valid_not_equal, Params((ParamSelfOption(), ParamOption(b, todict=True))))
])
od = OptionDescription('od', '', [a, b, c])
warnings.simplefilter("always", ValueWarning)
cfg = Config(od)
cfg = get_config(cfg, config_type)
with warnings.catch_warnings(record=True) as w:
raises(ValueError, "cfg.option('c').value.set(1)")
assert w == []
def test_consistency_not_equal_has_dependency():
a = IntOption('a', '')
b = IntOption('b', '', )
b = IntOption('b', '', validators=[Calculation(valid_not_equal, Params((ParamSelfOption(), ParamOption(a, todict=True))))])
od = OptionDescription('od', '', [a, b])
cfg = Config(od)
assert cfg.option('a').option.has_dependency() is False
assert cfg.option('b').option.has_dependency() is True
assert cfg.option('a').option.has_dependency(False) is True
assert cfg.option('b').option.has_dependency(False) is False

View File

@ -11,7 +11,7 @@ setting.expires_time = 1
from tiramisu import IPOption, OptionDescription, BoolOption, IntOption, StrOption, \ from tiramisu import IPOption, OptionDescription, BoolOption, IntOption, StrOption, \
Leadership, Config, calc_value, Params, ParamOption, Calculation, ParamValue, ParamSelfOption, ParamIndex, \ Leadership, Config, calc_value, Params, ParamOption, Calculation, ParamValue, ParamSelfOption, ParamIndex, \
calc_value_property_help calc_value_property_help
from tiramisu.error import PropertiesOptionError, RequirementError, ConfigError, display_list from tiramisu.error import PropertiesOptionError, ConfigError, display_list
from py.test import raises from py.test import raises
from tiramisu.storage import list_sessions, delete_session from tiramisu.storage import list_sessions, delete_session
@ -55,28 +55,6 @@ def test_properties(config_type):
cfg_ori.unrestraint.option('ip_address_service').property.pop('disabled') cfg_ori.unrestraint.option('ip_address_service').property.pop('disabled')
def test_requires_legacy(config_type):
a = BoolOption('activate_service', '', True)
b = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b])
cfg = Config(od)
cfg.property.read_write()
assert not cfg.option('activate_service').option.requires()
assert cfg.option('ip_address_service').option.requires()
cfg = get_config(cfg, config_type)
cfg.option('ip_address_service').value.get()
cfg.option('activate_service').value.set(False)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
cfg.option('activate_service').value.set(True)
cfg.option('ip_address_service').value.get()
def test_requires(config_type): def test_requires(config_type):
a = BoolOption('activate_service', '', True) a = BoolOption('activate_service', '', True)
disabled_property = Calculation(calc_value, disabled_property = Calculation(calc_value,
@ -88,8 +66,6 @@ def test_requires(config_type):
od = OptionDescription('service', '', [a, b]) od = OptionDescription('service', '', [a, b])
cfg = Config(od) cfg = Config(od)
cfg.property.read_write() cfg.property.read_write()
assert not cfg.option('activate_service').option.requires()
assert not cfg.option('ip_address_service').option.requires()
cfg = get_config(cfg, config_type) cfg = get_config(cfg, config_type)
cfg.option('ip_address_service').value.get() cfg.option('ip_address_service').value.get()
cfg.option('activate_service').value.set(False) cfg.option('activate_service').value.set(False)
@ -103,52 +79,6 @@ def test_requires(config_type):
cfg.option('ip_address_service').value.get() cfg.option('ip_address_service').value.get()
def test_requires_callback_legacy(config_type):
a = BoolOption('activate_service', '', True)
b = IPOption('ip_address_service', '',
requires=[{'callback': calc_value, 'callback_params': Params(ParamOption(a)), 'expected': False, 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b])
cfg = Config(od)
cfg.property.read_write()
assert not cfg.option('activate_service').option.requires()
assert cfg.option('ip_address_service').option.requires()
cfg = get_config(cfg, config_type)
cfg.option('ip_address_service').value.get()
cfg.option('activate_service').value.set(False)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
cfg.option('activate_service').value.set(True)
cfg.option('ip_address_service').value.get()
def test_requires_inverse_legacy(config_type):
a = BoolOption('activate_service', '', True)
b = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': False, 'action': 'disabled', 'inverse': True}])
od = OptionDescription('service', '', [a, b])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
cfg.option('activate_service').value.set(False)
cfg.option('ip_address_service').value.get()
cfg.option('activate_service').value.set(True)
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
def test_requires_inverse(config_type): def test_requires_inverse(config_type):
a = BoolOption('activate_service', '', True) a = BoolOption('activate_service', '', True)
disabled_property = Calculation(calc_value, disabled_property = Calculation(calc_value,
@ -177,25 +107,6 @@ def test_requires_inverse(config_type):
assert frozenset(props) == frozenset(['disabled']) assert frozenset(props) == frozenset(['disabled'])
def test_requires_self_legacy(config_type):
a = StrOption('ip_address_service', '',
requires=[{'option': 'self', 'expected': 'b', 'action': 'disabled'}])
od = OptionDescription('service', '', [a])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('ip_address_service').value.get() == None
cfg.option('ip_address_service').value.set('a')
assert cfg.option('ip_address_service').value.get() == 'a'
cfg.option('ip_address_service').value.set('b')
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
def test_requires_self(config_type): def test_requires_self(config_type):
disabled_property = Calculation(calc_value, disabled_property = Calculation(calc_value,
Params(ParamValue('disabled'), Params(ParamValue('disabled'),
@ -218,27 +129,6 @@ def test_requires_self(config_type):
assert frozenset(props) == frozenset(['disabled']) assert frozenset(props) == frozenset(['disabled'])
def test_requires_with_requires_legacy(config_type):
a = BoolOption('activate_service', '', True)
b = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b])
cfg = Config(od)
cfg.property.read_write()
cfg.option('ip_address_service').property.add('test')
cfg = get_config(cfg, config_type)
cfg.option('ip_address_service').value.get()
cfg.option('activate_service').value.set(False)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
cfg.option('activate_service').value.set(True)
cfg.option('ip_address_service').value.get()
def test_requires_with_requires(config_type): def test_requires_with_requires(config_type):
a = BoolOption('activate_service', '', True) a = BoolOption('activate_service', '', True)
disabled_property = Calculation(calc_value, disabled_property = Calculation(calc_value,
@ -263,67 +153,6 @@ def test_requires_with_requires(config_type):
cfg.option('ip_address_service').value.get() cfg.option('ip_address_service').value.get()
def test_requires_invalid_legacy():
a = BoolOption('activate_service', '', True)
a
raises(ValueError, "IPOption('ip_address_service', '', requires='string')")
raises(ValueError, "IPOption('ip_address_service', '', requires=[{'option': a, 'expected': False, 'action': 'disabled', 'unknown': True}])")
raises(ValueError, "IPOption('ip_address_service', '', requires=[{'option': a, 'expected': False}])")
raises(ValueError, "IPOption('ip_address_service', '', requires=[{'option': a, 'action': 'disabled'}])")
raises(ValueError, "IPOption('ip_address_service', '', requires=[{'expected': False, 'action': 'disabled'}])")
raises(ValueError, "IPOption('ip_address_service', '', requires=[{'option': a, 'expected': False, 'action': 'disabled', 'inverse': 'string'}])")
raises(ValueError, "IPOption('ip_address_service', '', requires=[{'option': a, 'expected': False, 'action': 'disabled', 'transitive': 'string'}])")
raises(ValueError, "IPOption('ip_address_service', '', requires=[{'option': a, 'expected': False, 'action': 'disabled', 'same_action': 'string'}])")
raises(ValueError, "IPOption('ip_address_service', '', requires=[{'option': 'string', 'expected': False, 'action': 'disabled'}])")
raises(ValueError, "IPOption('ip_address_service', '', requires=[{'option': a, 'expected': 'string', 'action': 'disabled'}])")
def test_requires_same_action_legacy(config_type):
activate_service = BoolOption('activate_service', '', True)
activate_service_web = BoolOption('activate_service_web', '', True,
requires=[{'option': activate_service, 'expected': False,
'action': 'new'}])
ip_address_service_web = IPOption('ip_address_service_web', '',
requires=[{'option': activate_service_web, 'expected': False,
'action': 'disabled', 'inverse': False,
'transitive': True, 'same_action': False}])
od1 = OptionDescription('service', '', [activate_service, activate_service_web, ip_address_service_web])
cfg = Config(od1)
cfg.property.read_write()
cfg.property.add('new')
cfg = get_config(cfg, config_type)
cfg.option('activate_service').value.get()
cfg.option('activate_service_web').value.get()
cfg.option('ip_address_service_web').value.get()
cfg.option('activate_service').value.set(False)
#
props = []
try:
cfg.option('activate_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
if config_type == 'tiramisu':
assert frozenset(props) == frozenset(['new'])
else:
assert frozenset(props) == frozenset(['disabled'])
#
props = []
try:
cfg.option('ip_address_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
submsg = '"disabled" (' + _('the value of "{0}" is {1}').format('activate_service', '"False"') + ')'
if config_type == 'tiramisu':
assert str(err) == str(_('cannot access to {0} "{1}" because has {2} {3}').format('option', 'ip_address_service_web', _('property'), submsg))
#access to cache
assert str(err) == str(_('cannot access to {0} "{1}" because has {2} {3}').format('option', 'ip_address_service_web', _('property'), submsg))
else:
# FIXME
assert str(err) == 'error'
assert frozenset(props) == frozenset(['disabled'])
def test_requires_same_action(config_type): def test_requires_same_action(config_type):
activate_service = BoolOption('activate_service', '', True) activate_service = BoolOption('activate_service', '', True)
new_property = Calculation(calc_value, new_property = Calculation(calc_value,
@ -376,82 +205,6 @@ def test_requires_same_action(config_type):
assert frozenset(props) == frozenset(['disabled']) assert frozenset(props) == frozenset(['disabled'])
def test_requires_same_action_callback_legacy(config_type):
activate_service = BoolOption('activate_service', '', True)
activate_service_web = BoolOption('activate_service_web', '', True,
requires=[{'callback': calc_value, 'callback_params': Params(ParamOption(activate_service)), 'expected': False,
'action': 'new'}])
ip_address_service_web = IPOption('ip_address_service_web', '',
requires=[{'option': activate_service_web, 'expected': False,
'action': 'disabled', 'inverse': False,
'transitive': True, 'same_action': False}])
od1 = OptionDescription('service', '', [activate_service, activate_service_web, ip_address_service_web])
cfg = Config(od1)
cfg.property.read_write()
cfg.property.add('new')
cfg = get_config(cfg, config_type)
cfg.option('activate_service').value.get()
cfg.option('activate_service_web').value.get()
cfg.option('ip_address_service_web').value.get()
cfg.option('activate_service').value.set(False)
#
props = []
try:
cfg.option('activate_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
if config_type == 'tiramisu':
assert frozenset(props) == frozenset(['new'])
else:
assert frozenset(props) == frozenset(['disabled'])
#
props = []
try:
cfg.option('ip_address_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
submsg = '"disabled" (' + _('the calculated value is {0}').format('"False"') + ')'
if config_type == 'tiramisu':
assert str(err) == str(_('cannot access to {0} "{1}" because has {2} {3}').format('option', 'ip_address_service_web', _('property'), submsg))
#access to cache
assert str(err) == str(_('cannot access to {0} "{1}" because has {2} {3}').format('option', 'ip_address_service_web', _('property'), submsg))
else:
# FIXME
assert str(err) == 'error'
assert frozenset(props) == frozenset(['disabled'])
def test_multiple_requires_legacy(config_type):
a = StrOption('activate_service', '')
b = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': 'yes', 'action': 'disabled'},
{'option': a, 'expected': 'ok', 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('ip_address_service').value.get()
cfg.option('activate_service').value.set('yes')
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
cfg.option('activate_service').value.set('ok')
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
cfg.option('activate_service').value.set('no')
cfg.option('ip_address_service').value.get()
def test_multiple_requires(config_type): def test_multiple_requires(config_type):
a = StrOption('activate_service', '') a = StrOption('activate_service', '')
disabled_property = Calculation(calc_value, disabled_property = Calculation(calc_value,
@ -485,34 +238,6 @@ def test_multiple_requires(config_type):
cfg.option('ip_address_service').value.get() cfg.option('ip_address_service').value.get()
def test_multiple_requires_cumulative_legacy(config_type):
a = StrOption('activate_service', '')
b = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': 'yes', 'action': 'disabled'},
{'option': a, 'expected': 'yes', 'action': 'hidden'}])
od = OptionDescription('service', '', [a, b])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('ip_address_service').value.get()
cfg.option('activate_service').value.set('yes')
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
if config_type == 'tiramisu':
assert set(props) == {'hidden', 'disabled'}
else:
assert set(props) == {'disabled'}
cfg.option('activate_service').value.set('ok')
cfg.option('ip_address_service').value.get()
cfg.option('activate_service').value.set('no')
cfg.option('ip_address_service').value.get()
def test_multiple_requires_cumulative(config_type): def test_multiple_requires_cumulative(config_type):
a = StrOption('activate_service', '') a = StrOption('activate_service', '')
disabled_property = Calculation(calc_value, disabled_property = Calculation(calc_value,
@ -547,50 +272,6 @@ def test_multiple_requires_cumulative(config_type):
cfg.option('ip_address_service').value.get() cfg.option('ip_address_service').value.get()
def test_multiple_requires_cumulative_inverse_legacy(config_type):
a = StrOption('activate_service', '')
b = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': 'yes', 'action': 'disabled', 'inverse': True},
{'option': a, 'expected': 'yes', 'action': 'hidden', 'inverse': True}])
od = OptionDescription('service', '', [a, b])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
if config_type == 'tiramisu':
assert set(props) == {'hidden', 'disabled'}
else:
assert set(props) == {'disabled'}
cfg.option('activate_service').value.set('yes')
cfg.option('ip_address_service').value.get()
cfg.option('activate_service').value.set('ok')
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
if config_type == 'tiramisu':
assert set(props) == {'hidden', 'disabled'}
else:
assert set(props) == {'disabled'}
cfg.option('activate_service').value.set('no')
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
if config_type == 'tiramisu':
assert set(props) == {'hidden', 'disabled'}
else:
assert set(props) == {'disabled'}
def test_multiple_requires_cumulative_inverse(config_type): def test_multiple_requires_cumulative_inverse(config_type):
a = StrOption('activate_service', '') a = StrOption('activate_service', '')
disabled_property = Calculation(calc_value, disabled_property = Calculation(calc_value,
@ -643,37 +324,6 @@ def test_multiple_requires_cumulative_inverse(config_type):
assert set(props) == {'disabled'} assert set(props) == {'disabled'}
def test_multiple_requires_inverse_legacy(config_type):
a = StrOption('activate_service', '')
b = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': 'yes', 'action': 'disabled', 'inverse': True},
{'option': a, 'expected': 'ok', 'action': 'disabled', 'inverse': True}])
od = OptionDescription('service', '', [a, b])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
cfg.option('activate_service').value.set('yes')
cfg.option('ip_address_service').value.get()
cfg.option('activate_service').value.set('ok')
cfg.option('ip_address_service').value.get()
cfg.option('activate_service').value.set('no')
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
def test_multiple_requires_inverse(config_type): def test_multiple_requires_inverse(config_type):
a = StrOption('activate_service', '') a = StrOption('activate_service', '')
disabled_property = Calculation(calc_value, disabled_property = Calculation(calc_value,
@ -709,37 +359,6 @@ def test_multiple_requires_inverse(config_type):
assert frozenset(props) == frozenset(['disabled']) assert frozenset(props) == frozenset(['disabled'])
def test_requires_transitive_legacy(config_type):
a = BoolOption('activate_service', '', True)
b = BoolOption('activate_service_web', '', True,
requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
d = IPOption('ip_address_service_web', '',
requires=[{'option': b, 'expected': False, 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b, d])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('activate_service').value.get()
cfg.option('activate_service_web').value.get()
cfg.option('ip_address_service_web').value.get()
cfg.option('activate_service').value.set(False)
#
props = []
try:
cfg.option('activate_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
#
props = []
try:
cfg.option('ip_address_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
def test_requires_transitive(config_type): def test_requires_transitive(config_type):
a = BoolOption('activate_service', '', True) a = BoolOption('activate_service', '', True)
disabled_property = Calculation(calc_value, disabled_property = Calculation(calc_value,
@ -777,59 +396,6 @@ def test_requires_transitive(config_type):
assert frozenset(props) == frozenset(['disabled']) assert frozenset(props) == frozenset(['disabled'])
def test_requires_transitive_callback_legacy(config_type):
a = BoolOption('activate_service', '', True)
b = BoolOption('activate_service_web', '', True,
requires=[{'callback': calc_value, 'callback_params': Params(ParamOption(a)), 'expected': False, 'action': 'disabled'}])
d = IPOption('ip_address_service_web', '',
requires=[{'callback': calc_value, 'callback_params': Params(ParamOption(b)), 'expected': False, 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b, d])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('activate_service').value.get()
cfg.option('activate_service_web').value.get()
cfg.option('ip_address_service_web').value.get()
cfg.option('activate_service').value.set(False)
#
props = []
try:
cfg.option('activate_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
#
props = []
try:
cfg.option('ip_address_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
def test_requires_transitive_unrestraint_legacy(config_type):
a = BoolOption('activate_service', '', True)
b = BoolOption('activate_service_web', '', True,
requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
d = IPOption('ip_address_service_web', '',
requires=[{'option': b, 'expected': False, 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b, d])
cfg_ori = Config(od)
cfg_ori.property.read_write()
cfg = get_config(cfg_ori, config_type)
cfg.option('activate_service').value.get()
cfg.option('activate_service_web').value.get()
cfg.option('ip_address_service_web').value.get()
cfg.option('activate_service').value.set(False)
#
if config_type == 'tiramisu-api':
cfg.send()
assert cfg_ori.unrestraint.option('activate_service_web').property.get() == {'disabled'}
assert cfg_ori.unrestraint.option('ip_address_service_web').property.get() == {'disabled'}
def test_requires_transitive_unrestraint(config_type): def test_requires_transitive_unrestraint(config_type):
a = BoolOption('activate_service', '', True) a = BoolOption('activate_service', '', True)
disabled_property = Calculation(calc_value, disabled_property = Calculation(calc_value,
@ -857,31 +423,6 @@ def test_requires_transitive_unrestraint(config_type):
assert cfg_ori.unrestraint.option('ip_address_service_web').property.get() == {'disabled'} assert cfg_ori.unrestraint.option('ip_address_service_web').property.get() == {'disabled'}
def test_requires_transitive_owner_legacy(config_type):
a = BoolOption('activate_service', '', True)
b = BoolOption('activate_service_web', '', True,
requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
d = IPOption('ip_address_service_web', '',
requires=[{'option': b, 'expected': False, 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b, d])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('activate_service').value.get()
cfg.option('activate_service_web').value.get()
cfg.option('ip_address_service_web').value.get()
#no more default value
cfg.option('ip_address_service_web').value.set('1.1.1.1')
cfg.option('activate_service').value.set(False)
props = []
try:
cfg.option('ip_address_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
def test_requires_transitive_owner(config_type): def test_requires_transitive_owner(config_type):
a = BoolOption('activate_service', '', True) a = BoolOption('activate_service', '', True)
disabled_property = Calculation(calc_value, disabled_property = Calculation(calc_value,
@ -913,38 +454,6 @@ def test_requires_transitive_owner(config_type):
assert frozenset(props) == frozenset(['disabled']) assert frozenset(props) == frozenset(['disabled'])
def test_requires_transitive_bis_legacy(config_type):
a = BoolOption('activate_service', '', True)
abis = BoolOption('activate_service_bis', '', True)
b = BoolOption('activate_service_web', '', True,
requires=[{'option': a, 'expected': True, 'action': 'disabled', 'inverse': True}])
d = IPOption('ip_address_service_web', '',
requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}])
od = OptionDescription('service', '', [a, abis, b, d])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
#
cfg.option('activate_service_web').value.get()
cfg.option('ip_address_service_web').value.get()
cfg.option('activate_service').value.set(False)
#
props = []
try:
cfg.option('activate_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
#
props = []
try:
cfg.option('ip_address_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
def test_requires_transitive_bis(config_type): def test_requires_transitive_bis(config_type):
a = BoolOption('activate_service', '', True) a = BoolOption('activate_service', '', True)
abis = BoolOption('activate_service_bis', '', True) abis = BoolOption('activate_service_bis', '', True)
@ -984,24 +493,6 @@ def test_requires_transitive_bis(config_type):
assert frozenset(props) == frozenset(['disabled']) assert frozenset(props) == frozenset(['disabled'])
def test_requires_transitive_hidden_permissive_legacy():
a = BoolOption('activate_service', '', True)
b = BoolOption('activate_service_web', '', True,
requires=[{'option': a, 'expected': False, 'action': 'hidden'}])
d = IPOption('ip_address_service_web', '',
requires=[{'option': b, 'expected': False, 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b, d])
cfg = Config(od)
cfg.property.read_write()
# FIXME permissive cfg = get_config(cfg, config_type)
cfg.option('activate_service').value.get()
cfg.option('ip_address_service_web').value.get()
cfg.option('ip_address_service_web').value.get()
cfg.option('activate_service').value.set(False)
#
cfg.option('ip_address_service_web').value.get()
def test_requires_transitive_hidden_permissive(): def test_requires_transitive_hidden_permissive():
a = BoolOption('activate_service', '', True) a = BoolOption('activate_service', '', True)
hidden_property = Calculation(calc_value, hidden_property = Calculation(calc_value,
@ -1026,33 +517,6 @@ def test_requires_transitive_hidden_permissive():
cfg.option('ip_address_service_web').value.get() cfg.option('ip_address_service_web').value.get()
def test_requires_transitive_hidden_disabled_legacy(config_type):
a = BoolOption('activate_service', '', True)
b = BoolOption('activate_service_web', '', True,
requires=[{'option': a, 'expected': False, 'action': 'hidden'}])
d = IPOption('ip_address_service_web', '',
requires=[{'option': b, 'expected': False, 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b, d])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('activate_service').value.get()
cfg.option('activate_service_web').value.get()
cfg.option('ip_address_service_web').value.get()
cfg.option('activate_service').value.set(False)
#
props = []
try:
cfg.option('activate_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
if config_type == 'tiramisu-api':
assert frozenset(props) == frozenset(['disabled'])
else:
assert frozenset(props) == frozenset(['hidden'])
cfg.option('ip_address_service_web').value.get()
def test_requires_transitive_hidden_disabled(config_type): def test_requires_transitive_hidden_disabled(config_type):
a = BoolOption('activate_service', '', True) a = BoolOption('activate_service', '', True)
hidden_property = Calculation(calc_value, hidden_property = Calculation(calc_value,
@ -1086,69 +550,6 @@ def test_requires_transitive_hidden_disabled(config_type):
cfg.option('ip_address_service_web').value.get() cfg.option('ip_address_service_web').value.get()
def test_requires_transitive_hidden_disabled_multiple_legacy(config_type):
a = BoolOption('activate_service', '', True)
b = BoolOption('activate_service_web', '', True,
requires=[{'option': a, 'expected': False, 'action': 'hidden'},
{'option': a, 'expected': False, 'action': 'disabled'}])
d = IPOption('ip_address_service_web', '',
requires=[{'option': b, 'expected': False, 'action': 'mandatory'}])
od = OptionDescription('service', '', [a, b, d])
cfg_ori = Config(od)
cfg_ori.property.read_write()
cfg = get_config(cfg_ori, config_type)
cfg.option('activate_service').value.get()
cfg.option('activate_service_web').value.get()
cfg.option('ip_address_service_web').value.get()
req = None
if config_type == 'tiramisu-api':
try:
cfg.option('activate_service').value.set(False)
except ConfigError as err:
req = err
error_msg = str(_('unable to transform tiramisu object to dict: {}').format(_('cannot access to option "{0}" because required option "{1}" has {2} {3}').format('ip_address_service_web', 'activate_service_web', _('property'), '"disabled"')))
else:
cfg.option('activate_service').value.set(False)
#
props = []
try:
cfg.option('activate_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
if config_type == 'tiramisu-api':
assert set(props) == {'disabled',}
else:
assert set(props) == {'disabled', 'hidden'}
del props
#
try:
cfg.option('ip_address_service_web').value.get()
except RequirementError as err:
req = err
error_msg = str(_('cannot access to option "{0}" because required option "{1}" has {2} {3}').format('ip_address_service_web', 'activate_service_web', _('property'), '"disabled"'))
assert req, "ip_address_service_web should raise RequirementError"
assert str(req) == error_msg
del req
#
cfg_ori.permissive.set(frozenset())
if config_type == 'tiramisu-api':
try:
cfg = get_config(cfg_ori, config_type)
except ConfigError as err:
req = err
error_msg = str(_('unable to transform tiramisu object to dict: {}').format(_('cannot access to option "{0}" because required option "{1}" has {2} {3}').format('ip_address_service_web', 'activate_service_web', _('properties'), '"disabled" {} "hidden"'.format(_('and')))))
else:
cfg = get_config(cfg_ori, config_type)
try:
cfg.option('ip_address_service_web').value.get()
except RequirementError as err:
req = err
error_msg = str(_('cannot access to option "{0}" because required option "{1}" has {2} {3}').format('ip_address_service_web', 'activate_service_web', _('properties'), '"disabled" {} "hidden"'.format(_('and'))))
assert req, "ip_address_service_web should raise RequirementError"
assert str(req) == error_msg
del req
def test_requires_transitive_hidden_disabled_multiple(config_type): def test_requires_transitive_hidden_disabled_multiple(config_type):
a = BoolOption('activate_service', '', True) a = BoolOption('activate_service', '', True)
hidden_property = Calculation(calc_value, hidden_property = Calculation(calc_value,
@ -1216,37 +617,11 @@ def test_requires_transitive_hidden_disabled_multiple(config_type):
except ConfigError as err: except ConfigError as err:
req = err req = err
error_msg = str(_('unable to carry out a calculation for "{}", {}').format('ip_address_service_web', _('cannot access to {0} "{1}" because has {2} {3}').format('option', 'activate_service_web', _('properties'), display_list(['hidden', 'disabled'], add_quote=True)))) error_msg = str(_('unable to carry out a calculation for "{}", {}').format('ip_address_service_web', _('cannot access to {0} "{1}" because has {2} {3}').format('option', 'activate_service_web', _('properties'), display_list(['hidden', 'disabled'], add_quote=True))))
assert req, "ip_address_service_web should raise RequirementError" assert req, "ip_address_service_web should raise ConfigError"
assert str(req) == error_msg assert str(req) == error_msg
del req del req
def test_requires_not_transitive_legacy(config_type):
a = BoolOption('activate_service', '', True)
b = BoolOption('activate_service_web', '', True,
requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
d = IPOption('ip_address_service_web', '',
requires=[{'option': b, 'expected': False,
'action': 'disabled', 'transitive': False}])
od = OptionDescription('service', '', [a, b, d])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('activate_service').value.get()
cfg.option('activate_service_web').value.get()
cfg.option('ip_address_service_web').value.get()
cfg.option('activate_service').value.set(False)
#
props = []
try:
cfg.option('activate_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
#
cfg.option('ip_address_service_web').value.get()
def test_requires_not_transitive(config_type): def test_requires_not_transitive(config_type):
a = BoolOption('activate_service', '', True) a = BoolOption('activate_service', '', True)
disabled_property = Calculation(calc_value, disabled_property = Calculation(calc_value,
@ -1279,35 +654,6 @@ def test_requires_not_transitive(config_type):
cfg.option('ip_address_service_web').value.get() cfg.option('ip_address_service_web').value.get()
def test_requires_not_transitive_not_same_action_legacy(config_type):
a = BoolOption('activate_service', '', True)
b = BoolOption('activate_service_web', '', True,
requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
d = IPOption('ip_address_service_web', '',
requires=[{'option': b, 'expected': False,
'action': 'hidden', 'transitive': False}])
od = OptionDescription('service', '', [a, b, d])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('activate_service').value.get()
cfg.option('activate_service_web').value.get()
cfg.option('ip_address_service_web').value.get()
if config_type == 'tiramisu-api':
raises(ConfigError, "cfg.option('activate_service').value.set(False)")
else:
cfg.option('activate_service').value.set(False)
#
props = []
try:
cfg.option('activate_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
#
raises(RequirementError, "cfg.option('ip_address_service_web').value.get()")
def test_requires_not_transitive_not_same_action(config_type): def test_requires_not_transitive_not_same_action(config_type):
a = BoolOption('activate_service', '', True) a = BoolOption('activate_service', '', True)
disabled_property = Calculation(calc_value, disabled_property = Calculation(calc_value,
@ -1342,24 +688,6 @@ def test_requires_not_transitive_not_same_action(config_type):
raises(ConfigError, "cfg.option('ip_address_service_web').value.get()") raises(ConfigError, "cfg.option('ip_address_service_web').value.get()")
def test_requires_none_legacy(config_type):
a = BoolOption('activate_service', '')
b = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': None, 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
cfg.option('activate_service').value.set(False)
cfg.option('ip_address_service').value.get()
def test_requires_none(config_type): def test_requires_none(config_type):
a = BoolOption('activate_service', '') a = BoolOption('activate_service', '')
disabled_property = Calculation(calc_value, disabled_property = Calculation(calc_value,
@ -1381,47 +709,6 @@ def test_requires_none(config_type):
cfg.option('ip_address_service').value.get() cfg.option('ip_address_service').value.get()
def test_requires_multi_disabled_legacy(config_type):
a = BoolOption('activate_service', '')
b = IntOption('num_service', '')
c = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': True, 'action': 'disabled'},
{'option': b, 'expected': 1, 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b, c])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('ip_address_service').value.get()
cfg.option('activate_service').value.set(True)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
cfg.option('activate_service').value.set(False)
cfg.option('ip_address_service').value.get()
cfg.option('num_service').value.set(1)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
cfg.option('activate_service').value.set(True)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
def test_requires_multi_disabled(config_type): def test_requires_multi_disabled(config_type):
a = BoolOption('activate_service', '') a = BoolOption('activate_service', '')
b = IntOption('num_service', '') b = IntOption('num_service', '')
@ -1468,244 +755,6 @@ def test_requires_multi_disabled(config_type):
assert frozenset(props) == frozenset(['disabled']) assert frozenset(props) == frozenset(['disabled'])
def test_requires_multi_disabled_callback_legacy(config_type):
a = BoolOption('activate_service', '')
b = IntOption('num_service', '')
c = IPOption('ip_address_service', '',
requires=[{'callback': calc_value, 'callback_params': Params(ParamOption(a)), 'expected': True, 'action': 'disabled'},
{'callback': calc_value, 'callback_params': Params(ParamOption(b)), 'expected': 1, 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b, c])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('ip_address_service').value.get()
cfg.option('activate_service').value.set(True)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
cfg.option('activate_service').value.set(False)
cfg.option('ip_address_service').value.get()
cfg.option('num_service').value.set(1)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
cfg.option('activate_service').value.set(True)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
def test_requires_multi_disabled_new_format_legacy(config_type):
a = BoolOption('activate_service', '')
b = IntOption('num_service', '')
c = IPOption('ip_address_service', '',
requires=[{'expected': [{'option': a, 'value': True}, {'option': b, 'value': 1}], 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b, c])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('ip_address_service').value.get()
cfg.option('activate_service').value.set(True)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
cfg.option('activate_service').value.set(False)
cfg.option('ip_address_service').value.get()
cfg.option('num_service').value.set(1)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
cfg.option('activate_service').value.set(True)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
def test_requires_unknown_operator_legacy():
a = BoolOption('activate_service', '')
b = IntOption('num_service', '')
raises(ValueError, """IPOption('ip_address_service', '',
requires=[{'expected': [{'option': a, 'value': True}, {'option': b, 'value': 1}],
'action': 'disabled', 'operator': 'unknown'}])""")
def test_requires_keys_legacy():
a = BoolOption('activate_service', '')
b = IntOption('num_service', '')
raises(ValueError, """IPOption('ip_address_service', '',
requires=[{'expected': [{'option': a, 'value2': True}, {'option': b, 'value': 1}],
'action': 'disabled', 'operator': 'and'}])""")
def test_requires_unvalid_legacy():
a = BoolOption('activate_service', '')
b = IntOption('num_service', '')
raises(ValueError, """IPOption('ip_address_service', '',
requires=[{'expected': [{'option': a, 'value': 'unvalid'}, {'option': b, 'value': 1}],
'action': 'disabled', 'operator': 'and'}])""")
def test_requires_multi_disabled_new_format_and_legacy(config_type):
a = BoolOption('activate_service', '')
b = IntOption('num_service', '')
c = IPOption('ip_address_service', '',
requires=[{'expected': [{'option': a, 'value': True}, {'option': b, 'value': 1}], 'action': 'disabled', 'operator': 'and'}])
od = OptionDescription('service', '', [a, b, c])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('ip_address_service').value.get()
cfg.option('activate_service').value.set(True)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert props == []
cfg.option('activate_service').value.set(False)
cfg.option('ip_address_service').value.get()
cfg.option('num_service').value.set(1)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert props == []
cfg.option('activate_service').value.set(True)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
def test_requires_multi_disabled_new_format_and_2_legacy(config_type):
a = BoolOption('activate_service', '')
b = IntOption('num_service', '')
c = IPOption('ip_address_service', '',
requires=[{'expected': [{'option': a, 'value': True}, {'option': b, 'value': 1}], 'action': 'disabled', 'operator': 'and'},
{'expected': [{'option': a, 'value': False}, {'option': b, 'value': 1}], 'action': 'expert'}])
od = OptionDescription('service', '', [a, b, c])
cfg = Config(od)
cfg.property.add('expert')
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('ip_address_service').value.get()
cfg.option('activate_service').value.set(True)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert props == []
cfg.option('activate_service').value.set(False)
cfg.option('num_service').value.set(1)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
if config_type == 'tiramisu-api':
assert frozenset(props) == frozenset(['disabled'])
else:
assert frozenset(props) == frozenset(['expert'])
cfg.option('activate_service').value.set(True)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
if config_type == 'tiramisu-api':
assert frozenset(props) == frozenset(['disabled'])
else:
assert frozenset(props) == frozenset(['disabled', 'expert'])
def test_requires_multi_disabled_inverse_legacy(config_type):
a = BoolOption('activate_service', '')
b = IntOption('num_service', '')
c = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': True,
'action': 'disabled', 'inverse': True},
{'option': b, 'expected': 1,
'action': 'disabled', 'inverse': True}])
od = OptionDescription('service', '', [a, b, c])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
cfg.option('activate_service').value.set(True)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
cfg.option('activate_service').value.set(False)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
cfg.option('num_service').value.set(1)
props = []
try:
cfg.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
cfg.option('activate_service').value.set(True)
cfg.option('ip_address_service').value.get()
def test_requires_multi_disabled_inverse(config_type): def test_requires_multi_disabled_inverse(config_type):
a = BoolOption('activate_service', '') a = BoolOption('activate_service', '')
b = IntOption('num_service', '') b = IntOption('num_service', '')
@ -1759,54 +808,6 @@ def test_requires_multi_disabled_inverse(config_type):
cfg.option('ip_address_service').value.get() cfg.option('ip_address_service').value.get()
def test_requires_multi_disabled_2_legacy(config_type):
a = BoolOption('a', '')
b = BoolOption('b', '')
c = BoolOption('c', '')
d = BoolOption('d', '')
e = BoolOption('e', '')
f = BoolOption('f', '')
g = BoolOption('g', '')
h = BoolOption('h', '')
i = BoolOption('i', '')
j = BoolOption('j', '')
k = BoolOption('k', '')
l = BoolOption('l', '')
m = BoolOption('m', '')
list_bools = [a, b, c, d, e, f, g, h, i, j, k, l, m]
requires = []
for boo in list_bools:
requires.append({'option': boo, 'expected': True, 'action': 'disabled'})
z = IPOption('z', '', requires=requires)
y = copy(list_bools)
y.append(z)
od = OptionDescription('service', '', y)
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('z').value.get()
for boo in list_bools:
cfg.option(boo.impl_getname()).value.set(True)
props = []
try:
cfg.option('z').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
for boo in list_bools:
cfg.option(boo.impl_getname()).value.set(False)
if boo == m:
cfg.option('z').value.get()
else:
props = []
try:
cfg.option('z').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
def test_requires_multi_disabled_2(config_type): def test_requires_multi_disabled_2(config_type):
a = BoolOption('a', '') a = BoolOption('a', '')
b = BoolOption('b', '') b = BoolOption('b', '')
@ -1860,60 +861,6 @@ def test_requires_multi_disabled_2(config_type):
assert frozenset(props) == frozenset(['disabled']) assert frozenset(props) == frozenset(['disabled'])
def test_requires_multi_disabled_inverse_2_legacy(config_type):
a = BoolOption('a', '')
b = BoolOption('b', '')
c = BoolOption('c', '')
d = BoolOption('d', '')
e = BoolOption('e', '')
f = BoolOption('f', '')
g = BoolOption('g', '')
h = BoolOption('h', '')
i = BoolOption('i', '')
j = BoolOption('j', '')
k = BoolOption('k', '')
l = BoolOption('l', '')
m = BoolOption('m', '')
list_bools = [a, b, c, d, e, f, g, h, i, j, k, l, m]
requires = []
for boo in list_bools:
requires.append({'option': boo, 'expected': True, 'action': 'disabled',
'inverse': True})
z = IPOption('z', '', requires=requires)
y = copy(list_bools)
y.append(z)
od = OptionDescription('service', '', y)
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
props = []
try:
cfg.option('z').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
for boo in list_bools:
cfg.option(boo.impl_getname()).value.set(True)
if boo == m:
cfg.option('z').value.get()
else:
props = []
try:
cfg.option('z').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
for boo in list_bools:
cfg.option(boo.impl_getname()).value.set(False)
props = []
try:
cfg.option('z').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
def test_requires_multi_disabled_inverse_2(config_type): def test_requires_multi_disabled_inverse_2(config_type):
a = BoolOption('a', '') a = BoolOption('a', '')
b = BoolOption('b', '') b = BoolOption('b', '')
@ -1991,27 +938,6 @@ def test_requires_multi_disabled_inverse_2(config_type):
cfg.option('z').value.get() cfg.option('z').value.get()
def test_requires_requirement_append_legacy(config_type):
a = BoolOption('activate_service', '', True)
b = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b])
cfg_ori = Config(od)
cfg_ori.property.read_write()
cfg = get_config(cfg_ori, config_type)
cfg.property.get()
cfg.option('ip_address_service').property.get()
if config_type == 'tiramisu-api':
cfg.send()
#raises(ValueError, "cfg_ori.option('ip_address_service').property.add('disabled')")
cfg = get_config(cfg_ori, config_type)
cfg.option('activate_service').value.set(False)
# disabled is now set, test to remove disabled before store in storage
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.unrestraint.option('ip_address_service').property.add("test")
def test_requires_requirement_append(config_type): def test_requires_requirement_append(config_type):
a = BoolOption('activate_service', '', True) a = BoolOption('activate_service', '', True)
disabled_property = Calculation(calc_value, disabled_property = Calculation(calc_value,
@ -2036,20 +962,6 @@ def test_requires_requirement_append(config_type):
cfg_ori.unrestraint.option('ip_address_service').property.add("test") cfg_ori.unrestraint.option('ip_address_service').property.add("test")
def test_requires_different_inverse_legacy(config_type):
a = BoolOption('activate_service', '', True)
b = IPOption('ip_address_service', '', requires=[
{'option': a, 'expected': True, 'action': 'disabled', 'inverse': True},
{'option': a, 'expected': True, 'action': 'disabled', 'inverse': False}])
od = OptionDescription('service', '', [a, b])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
raises(PropertiesOptionError, "cfg.option('ip_address_service').value.get()")
cfg.option('activate_service').value.set(False)
raises(PropertiesOptionError, "cfg.option('ip_address_service').value.get()")
def test_requires_different_inverse(config_type): def test_requires_different_inverse(config_type):
a = BoolOption('activate_service', '', True) a = BoolOption('activate_service', '', True)
disabled_property = Calculation(calc_value, disabled_property = Calculation(calc_value,
@ -2070,27 +982,6 @@ def test_requires_different_inverse(config_type):
raises(PropertiesOptionError, "cfg.option('ip_address_service').value.get()") raises(PropertiesOptionError, "cfg.option('ip_address_service').value.get()")
def test_requires_different_inverse_unicode_legacy(config_type):
a = BoolOption('activate_service', '', True)
d = StrOption('activate_other_service', '', 'val2')
b = IPOption('ip_address_service', '', requires=[
{'option': a, 'expected': True, 'action': 'disabled', 'inverse': True},
{'option': d, 'expected': 'val1', 'action': 'disabled', 'inverse': False}])
od = OptionDescription('service', '', [a, d, b])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('ip_address_service').value.get() == None
cfg.option('activate_service').value.set(False)
raises(PropertiesOptionError, "cfg.option('ip_address_service').value.get()")
cfg.option('activate_service').value.set(True)
assert cfg.option('ip_address_service').value.get() == None
cfg.option('activate_other_service').value.set('val1')
raises(PropertiesOptionError, "cfg.option('ip_address_service').value.get()")
cfg.option('activate_service').value.set(False)
raises(PropertiesOptionError, "cfg.option('ip_address_service').value.get()")
def test_requires_different_inverse_unicode(config_type): def test_requires_different_inverse_unicode(config_type):
a = BoolOption('activate_service', '', True) a = BoolOption('activate_service', '', True)
d = StrOption('activate_other_service', '', 'val2') d = StrOption('activate_other_service', '', 'val2')
@ -2118,27 +1009,6 @@ def test_requires_different_inverse_unicode(config_type):
raises(PropertiesOptionError, "cfg.option('ip_address_service').value.get()") raises(PropertiesOptionError, "cfg.option('ip_address_service').value.get()")
def test_requires_recursive_path_legacy(config_type):
a = BoolOption('activate_service', '', True)
b = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
od1 = OptionDescription('service', '', [a, b], requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
od = OptionDescription('base', '', [od1])
cfg = Config(od)
cfg.property.read_write()
if config_type == 'tiramisu-api':
raises(ConfigError, "get_config(cfg, config_type)")
else:
cfg = get_config(cfg, config_type)
raises(RequirementError, "cfg.option('service.a').value.get()")
def test_optiondescription_requires_legacy():
a = BoolOption('activate_service', '', True)
b = BoolOption('ip_address_service', '', multi=True)
OptionDescription('service', '', [b], requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
def test_optiondescription_requires(): def test_optiondescription_requires():
a = BoolOption('activate_service', '', True) a = BoolOption('activate_service', '', True)
b = BoolOption('ip_address_service', '', multi=True) b = BoolOption('ip_address_service', '', multi=True)
@ -2149,72 +1019,6 @@ def test_optiondescription_requires():
OptionDescription('service', '', [b], properties=(disabled_property,)) OptionDescription('service', '', [b], properties=(disabled_property,))
def test_optiondescription_requires_multi_legacy():
# FIXME not legacy !!!
a = BoolOption('activate_service', '', True)
b = IPOption('ip_address_service', '', multi=True)
a, b
raises(ValueError, "OptionDescription('service', '', [a], requires=[{'option': b, 'expected': False, 'action': 'disabled'}])")
def test_properties_conflict_legacy():
a = BoolOption('activate_service', '', True)
a
raises(ValueError, "IPOption('ip_address_service', '', properties=('disabled',), requires=[{'option': a, 'expected': False, 'action': 'disabled'}])")
raises(ValueError, "od1 = OptionDescription('service', '', [a], properties=('disabled',), requires=[{'option': a, 'expected': False, 'action': 'disabled'}])")
def test_leadership_requires_legacy(config_type):
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True,
requires=[{'option': ip_admin_eth0, 'expected': '192.168.1.1', 'action': 'disabled'}])
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
od = OptionDescription('toto', '', [interface1])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2'])
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2']
#
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
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get()")
#
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2', '192.168.1.2'])
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
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']}
#
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
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']
#
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']
def test_leadership_requires(config_type): def test_leadership_requires(config_type):
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True) ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
disabled_property = Calculation(calc_value, disabled_property = Calculation(calc_value,
@ -2271,112 +1075,6 @@ def test_leadership_requires(config_type):
del ret['ip_admin_eth0.netmask_admin_eth0'] del ret['ip_admin_eth0.netmask_admin_eth0']
def test_leadership_requires_callback_legacy(config_type):
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True,
requires=[{'callback': calc_value, 'callback_params': Params(ParamOption(ip_admin_eth0)), 'expected': '192.168.1.1', 'action': 'disabled'}])
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
od = OptionDescription('toto', '', [interface1])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2'])
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2']
#
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
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get()")
#
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2', '192.168.1.2'])
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
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']}
#
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
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']
#
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']
def test_leadership_requires_both_legacy():
# FIXME ne devrait pas pouvoir mettre de propriété calculé sur une master ...
ip_admin = StrOption('ip_admin_eth0', "ip réseau autorisé")
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True,
requires=[{'option': ip_admin, 'expected': '192.168.1.1', 'action': 'disabled'}])
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
raises(RequirementError, "Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0], requires=[{'option': ip_admin, 'expected': '192.168.1.1', 'action': 'disabled'}])")
def test_leadership_requires_properties_invalid_legacy():
ip_admin = StrOption('ip_admin', "ip réseau autorisé")
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True,
requires=[{'option': ip_admin_eth0, 'expected': '192.168.1.1', 'action': 'disabled'}])
raises(ValueError, "Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0], properties=('disabled',), requires=[{'option': ip_admin, 'expected': '192.168.1.1', 'action': 'disabled'}])")
def test_leadership_requires_properties_legacy():
ip_admin = StrOption('ip_admin', "ip réseau autorisé")
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True,
requires=[{'option': ip_admin_eth0, 'expected': '192.168.1.1', 'action': 'disabled'}])
Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0], properties=('hidden',),
requires=[{'option': ip_admin, 'expected': '192.168.1.1', 'action': 'disabled'}])
def test_leadership_requires_leader_legacy(config_type):
activate = BoolOption('activate', "Activer l'accès au réseau", True)
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True,
requires=[{'option': activate, 'expected': False, 'action': 'disabled'}])
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
od = OptionDescription('toto', '', [activate, interface1])
cfg = Config(od)
cfg.property.read_write()
#
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2'])
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2']
#
cfg.option('activate').value.set(False)
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()")
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
#
cfg.option('activate').value.set(True)
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
#
cfg.option('activate').value.set(False)
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()")
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
assert cfg.value.dict() == {'activate': False}
def test_leadership_requires_leader(config_type): def test_leadership_requires_leader(config_type):
activate = BoolOption('activate', "Activer l'accès au réseau", True) activate = BoolOption('activate', "Activer l'accès au réseau", True)
disabled_property = Calculation(calc_value, disabled_property = Calculation(calc_value,
@ -2384,71 +1082,13 @@ def test_leadership_requires_leader(config_type):
kwargs={'condition': ParamOption(activate, notraisepropertyerror=True), kwargs={'condition': ParamOption(activate, notraisepropertyerror=True),
'expected': ParamValue(False), 'expected': ParamValue(False),
'index': ParamIndex()})) 'index': ParamIndex()}))
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True, properties=(disabled_property,))
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
od = OptionDescription('toto', '', [activate, interface1])
cfg = Config(od)
cfg.property.read_write()
#
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2'])
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2']
#
cfg.option('activate').value.set(False)
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()")
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
#
cfg.option('activate').value.set(True)
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
#
cfg.option('activate').value.set(False)
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()")
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
assert cfg.value.dict() == {'activate': False}
def test_leadership_requires_leader_callback_legacy(config_type):
activate = BoolOption('activate', "Activer l'accès au réseau", True)
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True,
requires=[{'callback': calc_value, 'callback_params': Params(ParamOption(activate)), 'expected': False, 'action': 'disabled'}])
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
od = OptionDescription('toto', '', [activate, interface1])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
#
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2'])
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2']
#
cfg.option('activate').value.set(False)
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()")
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
#
cfg.option('activate').value.set(True)
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
#
cfg.option('activate').value.set(False)
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()")
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
assert cfg.value.dict() == {'activate': False}
def test_leadership_requires_leadership_legacy(config_type):
activate = BoolOption('activate', "Activer l'accès au réseau", True)
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True) ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True) netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0], interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0], properties=(disabled_property,))
requires=[{'option': activate, 'expected': False, 'action': 'disabled'}])
od = OptionDescription('toto', '', [activate, interface1]) od = OptionDescription('toto', '', [activate, interface1])
cfg = Config(od) cfg = Config(od)
cfg.property.read_write() cfg.property.read_write()
cfg = get_config(cfg, config_type)
# #
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2']) cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2'])
@ -2456,8 +1096,6 @@ def test_leadership_requires_leadership_legacy(config_type):
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2'] assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2']
# #
cfg.option('activate').value.set(False) cfg.option('activate').value.set(False)
if config_type != 'tiramisu-api':
# FIXME
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()") raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()")
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()") raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
# #
@ -2465,8 +1103,6 @@ def test_leadership_requires_leadership_legacy(config_type):
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
# #
cfg.option('activate').value.set(False) cfg.option('activate').value.set(False)
if config_type != 'tiramisu-api':
# FIXME
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()") raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()")
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()") raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
assert cfg.value.dict() == {'activate': False} assert cfg.value.dict() == {'activate': False}
@ -2509,65 +1145,6 @@ def test_leadership_requires_leadership(config_type):
assert cfg.value.dict() == {'activate': False} assert cfg.value.dict() == {'activate': False}
def test_leadership_requires_leadership_callback_legacy(config_type):
activate = BoolOption('activate', "Activer l'accès au réseau", True)
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0],
requires=[{'callback': calc_value, 'callback_params': Params(ParamOption(activate)), 'expected': False, 'action': 'disabled'}])
od = OptionDescription('toto', '', [activate, interface1])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
#
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2'])
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2']
#
cfg.option('activate').value.set(False)
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()")
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
#
cfg.option('activate').value.set(True)
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
#
cfg.option('activate').value.set(False)
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()")
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
assert cfg.value.dict() == {'activate': False}
def test_leadership_requires_no_leader_legacy(config_type):
activate = BoolOption('activate', "Activer l'accès au réseau", True)
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True,
requires=[{'option': activate, 'expected': False, 'action': 'disabled'}])
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
od = OptionDescription('toto', '', [activate, interface1])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2'])
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2']
cfg.option('activate').value.set(False)
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2', '192.168.1.1'])
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2', '192.168.1.1']
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get()")
cfg.option('activate').value.set(True)
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
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'
cfg.option('activate').value.set(False)
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
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}
def test_leadership_requires_no_leader(config_type): def test_leadership_requires_no_leader(config_type):
activate = BoolOption('activate', "Activer l'accès au réseau", True) activate = BoolOption('activate', "Activer l'accès au réseau", True)
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True) ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
@ -2602,129 +1179,6 @@ def test_leadership_requires_no_leader(config_type):
assert cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': ['192.168.1.2', '192.168.1.1'], 'activate': False} assert cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': ['192.168.1.2', '192.168.1.1'], 'activate': False}
def test_leadership_requires_no_leader_callback_legacy(config_type):
activate = BoolOption('activate', "Activer l'accès au réseau", True)
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True,
requires=[{'callback': calc_value, 'callback_params': Params(ParamOption(activate)), 'expected': False, 'action': 'disabled'}])
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
od = OptionDescription('toto', '', [activate, interface1])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2'])
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2']
cfg.option('activate').value.set(False)
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2', '192.168.1.1'])
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2', '192.168.1.1']
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get()")
cfg.option('activate').value.set(True)
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
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'
cfg.option('activate').value.set(False)
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get()")
dico = cfg.value.dict()
assert set(dico.keys()) == {'activate', 'ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'}
dico['ip_admin_eth0.ip_admin_eth0'] == ['192.168.1.2', '192.168.1.1']
dico['activate'] == False
del dico['ip_admin_eth0.netmask_admin_eth0'][1]
del dico['ip_admin_eth0.netmask_admin_eth0'][0]
def test_leadership_requires_complet_legacy(config_type):
optiontoto = StrOption('unicodetoto', "Unicode")
option = StrOption('unicode', "Unicode leader", multi=True)
option1 = StrOption('unicode1', "Unicode follower 1", multi=True)
option2 = StrOption('unicode2', "Values 'test' must show 'Unicode follower 3'", multi=True)
option3 = StrOption('unicode3', "Unicode follower 3", requires=[{'option': option,
'expected': u'test',
'action': 'hidden',
'inverse': True}],
multi=True)
option4 = StrOption('unicode4', "Unicode follower 4", requires=[{'option': option2,
'expected': u'test',
'action': 'hidden',
'inverse': True}],
multi=True)
option5 = StrOption('unicode5', "Unicode follower 5", requires=[{'option': optiontoto,
'expected': u'test',
'action': 'hidden',
'inverse': True}],
multi=True)
option6 = StrOption('unicode6', "Unicode follower 6", requires=[{'option': optiontoto,
'expected': u'test',
'action': 'hidden',
'inverse': True},
{'option': option2,
'expected': u'test',
'action': 'hidden',
'inverse': True}],
multi=True)
option7 = StrOption('unicode7', "Unicode follower 7", requires=[{'option': option2,
'expected': u'test',
'action': 'hidden',
'inverse': True},
{'option': optiontoto,
'expected': u'test',
'action': 'hidden',
'inverse': True}],
multi=True)
descr1 = Leadership("unicode", "Common configuration 1",
[option, option1, option2, option3, option4, option5, option6, option7])
descr = OptionDescription("options", "Common configuration 2", [descr1, optiontoto])
descr = OptionDescription("unicode1_leadership_requires", "Leader followers with Unicode follower 3 hidden when Unicode follower 2 is test", [descr])
cfg = Config(descr)
cfg.property.read_write()
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.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.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']
#
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']
del dico['options.unicode.unicode7'][1]
del dico['options.unicode.unicode7']
def test_leadership_requires_complet(config_type): def test_leadership_requires_complet(config_type):
optiontoto = StrOption('unicodetoto', "Unicode") optiontoto = StrOption('unicodetoto', "Unicode")
option = StrOption('unicode', "Unicode leader", multi=True) option = StrOption('unicode', "Unicode leader", multi=True)
@ -2825,223 +1279,6 @@ def test_leadership_requires_complet(config_type):
del dico['options.unicode.unicode7'] del dico['options.unicode.unicode7']
def test_leadership_requires_complet_callback_legacy(config_type):
optiontoto = StrOption('unicodetoto', "Unicode leader")
option = StrOption('unicode', "Unicode leader", multi=True)
option1 = StrOption('unicode1', "Unicode follower 1", multi=True)
option2 = StrOption('unicode2', "Values 'test' must show 'Unicode follower 3'", multi=True)
option3 = StrOption('unicode3', "Unicode follower 3", requires=[{'callback': calc_value,
'callback_params': Params(ParamOption(option)),
'expected': u'test',
'action': 'hidden',
'inverse': True}],
multi=True)
option4 = StrOption('unicode4', "Unicode follower 4", requires=[{'callback': calc_value,
'callback_params': Params(ParamOption(option2)),
'expected': u'test',
'action': 'hidden',
'inverse': True}],
multi=True)
option5 = StrOption('unicode5', "Unicode follower 5", requires=[{'callback': calc_value,
'callback_params': Params(ParamOption(optiontoto)),
'expected': u'test',
'action': 'hidden',
'inverse': True}],
multi=True)
option6 = StrOption('unicode6', "Unicode follower 6", requires=[{'callback': calc_value,
'callback_params': Params(ParamOption(optiontoto)),
'expected': u'test',
'action': 'hidden',
'inverse': True},
{'callback': calc_value,
'callback_params': Params(ParamOption(option2)),
'expected': u'test',
'action': 'hidden',
'inverse': True}],
multi=True)
option7 = StrOption('unicode7', "Unicode follower 7", requires=[{'callback': calc_value,
'callback_params': Params(ParamOption(option2)),
'expected': u'test',
'action': 'hidden',
'inverse': True},
{'callback': calc_value,
'callback_params': Params(ParamOption(optiontoto)),
'expected': u'test',
'action': 'hidden',
'inverse': True}],
multi=True)
descr1 = Leadership("unicode", "Common configuration 1",
[option, option1, option2, option3, option4, option5, option6, option7])
descr = OptionDescription("options", "Common configuration 2", [descr1, optiontoto])
descr = OptionDescription("unicode1_leadership_requires", "Leader followers with Unicode follower 3 hidden when Unicode follower 2 is test", [descr])
cfg = Config(descr)
cfg.property.read_write()
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.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.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.unicode5'][0]
del dico['options.unicode.unicode5'][0]
del dico['options.unicode.unicode6'][0]
del dico['options.unicode.unicode6'][0]
del dico['options.unicode.unicode7'][0]
del dico['options.unicode.unicode7'][0]
#
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']
del dico['options.unicode.unicode7'][1]
del dico['options.unicode.unicode7']
def test_leadership_requires_transitive1_legacy(config_type):
optiontoto = StrOption('unicodetoto', "Simple unicode")
option = StrOption('unicode', "Unicode leader", multi=True)
option1 = StrOption('unicode1', "Unicode follower 1", multi=True)
option2 = StrOption('unicode2', "Unicode follower 2", requires=[{'option': optiontoto,
'expected': u'test',
'action': 'disabled',
'transitive': True,
'inverse': True}],
multi=True)
option3 = StrOption('unicode3', "Unicode follower 3", requires=[{'option': option2,
'expected': u'test',
'action': 'disabled',
'transitive': True,
'inverse': True}],
multi=True)
option4 = StrOption('unicode4', "Unicode follower 4", requires=[{'option': option3,
'expected': u'test',
'action': 'disabled',
'transitive': True,
'inverse': True}],
multi=True)
descr1 = Leadership("unicode", "Common configuration 1",
[option, option1, option2, option3, option4])
descr = OptionDescription("options", "Common configuration 2", [descr1, optiontoto])
descr = OptionDescription("unicode1", "", [descr])
cfg = Config(descr)
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}
#
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'}
#
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])
#
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])
#
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])
#
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])
def test_leadership_requires_transitive1(config_type): def test_leadership_requires_transitive1(config_type):
optiontoto = StrOption('unicodetoto', "Simple unicode") optiontoto = StrOption('unicodetoto', "Simple unicode")
option = StrOption('unicode', "Unicode leader", multi=True) option = StrOption('unicode', "Unicode leader", multi=True)
@ -3163,128 +1400,6 @@ def test_leadership_requires_transitive1(config_type):
del (dico['options.unicode.unicode4'][0]) del (dico['options.unicode.unicode4'][0])
def test_leadership_requires_transitive_callback_legacy(config_type):
optiontoto = StrOption('unicodetoto', "Unicode leader")
option = StrOption('unicode', "Unicode leader", multi=True)
option1 = StrOption('unicode1', "Unicode follower 1", multi=True)
option2 = StrOption('unicode2', "Unicode follower 2", requires=[{'callback': calc_value,
'callback_params': Params(ParamOption(optiontoto)),
'expected': u'test',
'action': 'disabled',
'transitive': True,
'inverse': True}],
multi=True)
option3 = StrOption('unicode3', "Unicode follower 3", requires=[{'callback': calc_value,
'callback_params': Params(ParamOption(option2)),
'expected': u'test',
'action': 'disabled',
'transitive': True,
'inverse': True}],
multi=True)
option4 = StrOption('unicode4', "Unicode follower 4", requires=[{'callback': calc_value,
'callback_params': Params(ParamOption(option3)),
'expected': u'test',
'action': 'disabled',
'transitive': True,
'inverse': True}],
multi=True)
descr1 = Leadership("unicode", "Common configuration 1",
[option, option1, option2, option3, option4])
descr = OptionDescription("options", "Common configuration 2", [descr1, optiontoto])
descr = OptionDescription("unicode1", "", [descr])
cfg = Config(descr)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
assert cfg.value.dict() == {'options.unicode.unicode': [], 'options.unicode.unicode1': [], 'options.unicode.unicode2': [], 'options.unicode.unicode3': [], 'options.unicode.unicode4': [], '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'}
#
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])
#
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])
#
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])
#
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.unicode2', '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.unicode2'][2])
del (dico['options.unicode.unicode2'][1])
del (dico['options.unicode.unicode2'][0])
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])
# FIXME tester l'ajout d'un Calculation # FIXME tester l'ajout d'un Calculation
# FIXME permissive peut etre in calcul ! # FIXME permissive peut etre in calcul !
# FIXME Calculation sur des multis ... # FIXME Calculation sur des multis ...

View File

@ -88,21 +88,21 @@ def test_slots_option_readonly():
p = URLOption('p', '') p = URLOption('p', '')
q = FilenameOption('q', '') q = FilenameOption('q', '')
m = OptionDescription('m', '', [a, b, c, d, e, g, h, i, j, k, l, o, p, q]) m = OptionDescription('m', '', [a, b, c, d, e, g, h, i, j, k, l, o, p, q])
a._requires = (((a,),),) a._name = 'a'
b._requires = (((a,),),) b._name = 'b'
c._requires = (((a,),),) c._name = 'c'
d._requires = (((a,),),) d._name = 'd'
e._requires = (((a,),),) e._name = 'e'
g._requires = (((a,),),) g._name = 'g'
h._requires = (((a,),),) h._name = 'h'
i._requires = (((a,),),) i._name = 'i'
j._requires = (((a,),),) j._name = 'j'
k._requires = (((a,),),) k._name = 'k'
l._requires = (((a,),),) l._name = 'l'
m._requires = (((a,),),) m._name = 'm'
o._requires = (((a,),),) o._name = 'o'
p._requires = (((a,),),) p._name = 'p'
q._requires = (((a,),),) q._name = 'q'
Config(m) Config(m)
raises(AttributeError, "a._requires = 'a'") raises(AttributeError, "a._requires = 'a'")
raises(AttributeError, "b._requires = 'b'") raises(AttributeError, "b._requires = 'b'")

View File

@ -14,8 +14,11 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Configuration management library written in python """Configuration management library written in python
""" """
from .function import tiramisu_copy, calc_value, calc_value_property_help from .function import calc_value, calc_value_property_help, valid_ip_netmask, \
from .autolib import Calculation, Params, ParamOption, ParamSelfOption, ParamValue, ParamIndex, ParamContext valid_network_netmask, valid_in_network, valid_broadcast, \
valid_not_equal
from .autolib import Calculation, Params, ParamOption, ParamSelfOption, ParamValue, \
ParamIndex, ParamContext, ParamSuffix
from .option import * from .option import *
from .error import APIError from .error import APIError
from .api import Config, MetaConfig, GroupConfig, MixConfig from .api import Config, MetaConfig, GroupConfig, MixConfig
@ -32,6 +35,7 @@ allfuncs = ['Calculation',
'ParamValue', 'ParamValue',
'ParamIndex', 'ParamIndex',
'ParamContext', 'ParamContext',
'ParamSuffix',
'MetaConfig', 'MetaConfig',
'MixConfig', 'MixConfig',
'GroupConfig', 'GroupConfig',
@ -44,9 +48,13 @@ allfuncs = ['Calculation',
'Storage', 'Storage',
'list_sessions', 'list_sessions',
'delete_session', 'delete_session',
'tiramisu_copy',
'calc_value', 'calc_value',
'calc_value_property_help'] 'calc_value_property_help',
'valid_ip_netmask',
'valid_network_netmask',
'valid_in_network',
'valid_broadcast',
]
allfuncs.extend(all_options) allfuncs.extend(all_options)
del(all_options) del(all_options)
__all__ = tuple(allfuncs) __all__ = tuple(allfuncs)

View File

@ -196,11 +196,6 @@ class _TiramisuOptionOptionDescription(CommonTiramisuOption):
option = self._option_bag.option option = self._option_bag.option
return option.impl_has_dependency(self_is_dep) return option.impl_has_dependency(self_is_dep)
def requires(self):
"""Get requires for an option"""
option = self._option_bag.option
return option.impl_getrequires()
def isoptiondescription(self): def isoptiondescription(self):
"""Test if option is an optiondescription""" """Test if option is an optiondescription"""
option = self._option_bag.option option = self._option_bag.option
@ -274,11 +269,6 @@ class _TiramisuOptionOption(_TiramisuOptionOptionDescription):
ret = value ret = value
return ret return ret
def consistencies(self):
"""Get consistencies for an option (not for optiondescription)"""
option = self._option_bag.option
return option.get_consistencies()
def callbacks(self): def callbacks(self):
"""Get callbacks for an option (not for optiondescription)""" """Get callbacks for an option (not for optiondescription)"""
option = self._option_bag.option option = self._option_bag.option

View File

@ -84,10 +84,14 @@ class ParamOption(Param):
class ParamSelfOption(Param): class ParamSelfOption(Param):
__slots__ = ('todict',) __slots__ = ('todict', 'whole')
def __init__(self, def __init__(self,
todict: bool=False) -> None: todict: bool=False,
whole: bool=undefined) -> None:
"""whole: send all value for a multi, not only indexed value"""
self.todict = todict self.todict = todict
if whole is not undefined:
self.whole = whole
class ParamValue(Param): class ParamValue(Param):
@ -104,15 +108,21 @@ class ParamIndex(Param):
__slots__ = tuple() __slots__ = tuple()
class ParamSuffix(Param):
__slots__ = tuple()
class Calculation: class Calculation:
__slots__ = ('function', __slots__ = ('function',
'params', 'params',
'help_function', 'help_function',
'has_index') 'has_index',
'warnings_only')
def __init__(self, def __init__(self,
function: Callable, function: Callable,
params: Params=Params(), params: Params=Params(),
help_function: Optional[Callable]=None): help_function: Optional[Callable]=None,
warnings_only: bool=False):
assert isinstance(function, Callable), _('first argument ({0}) must be a function').format(function) assert isinstance(function, Callable), _('first argument ({0}) must be a function').format(function)
if help_function: if help_function:
assert isinstance(help_function, Callable), _('help_function ({0}) must be a function').format(help_function) assert isinstance(help_function, Callable), _('help_function ({0}) must be a function').format(help_function)
@ -127,19 +137,22 @@ class Calculation:
break break
else: else:
self.has_index = False self.has_index = False
if warnings_only is True:
self.warnings_only = warnings_only
def execute(self, def execute(self,
option_bag: OptionBag, option_bag: OptionBag,
leadership_must_have_index: bool=False) -> Any: leadership_must_have_index: bool=False,
if leadership_must_have_index and not self.has_index: orig_value: Any=undefined,
leadership_must_have_index = False allow_raises=False) -> Any:
return carry_out_calculation(option_bag.option, return carry_out_calculation(option_bag.option,
callback=self.function, callback=self.function,
callback_params=self.params, callback_params=self.params,
index=option_bag.index, index=option_bag.index,
config_bag=option_bag.config_bag, config_bag=option_bag.config_bag,
fromconsistency=option_bag.fromconsistency, leadership_must_have_index=leadership_must_have_index,
leadership_must_have_index=leadership_must_have_index) orig_value=orig_value,
allow_raises=allow_raises)
def help(self, def help(self,
option_bag: OptionBag, option_bag: OptionBag,
@ -147,14 +160,11 @@ class Calculation:
if not self.help_function: if not self.help_function:
return self.execute(option_bag, return self.execute(option_bag,
leadership_must_have_index=leadership_must_have_index) leadership_must_have_index=leadership_must_have_index)
if leadership_must_have_index and not self.has_index:
leadership_must_have_index = False
return carry_out_calculation(option_bag.option, return carry_out_calculation(option_bag.option,
callback=self.help_function, callback=self.help_function,
callback_params=self.params, callback_params=self.params,
index=option_bag.index, index=option_bag.index,
config_bag=option_bag.config_bag, config_bag=option_bag.config_bag,
fromconsistency=option_bag.fromconsistency,
leadership_must_have_index=leadership_must_have_index) leadership_must_have_index=leadership_must_have_index)
@ -167,49 +177,58 @@ def manager_callback(callbk: Union[ParamOption, ParamValue],
index: Optional[int], index: Optional[int],
orig_value, orig_value,
config_bag: ConfigBag, config_bag: ConfigBag,
fromconsistency: List,
leadership_must_have_index: bool) -> Any: leadership_must_have_index: bool) -> Any:
"""replace Param by true value""" """replace Param by true value"""
if isinstance(callbk, ParamValue): def calc_index(callbk, index, same_leadership):
return callbk.value if index is not None:
if isinstance(callbk, ParamIndex): if hasattr(callbk, 'whole'):
whole = callbk.whole
else:
# if value is same_leadership, follower are isolate by default
# otherwise option is a whole option
whole = not same_leadership
if not whole:
return index return index
return None
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)
if value is undefined or (apply_index is None and is_follower):
if config_bag is undefined: if config_bag is undefined:
return undefined return undefined
if isinstance(callbk, ParamContext): path = option.impl_getpath()
# Not an option, set full context option_bag = get_option_bag(config_bag, option, path, apply_index)
return config_bag.context.duplicate(force_values=get_default_values_storages(), option_bag.config_bag.unrestraint()
force_settings=get_default_settings_storages()) option_bag.config_bag.remove_validation()
if isinstance(callbk, ParamSelfOption): # if we are in properties calculation, cannot calculated properties
opt = option option_bag.properties = config_bag.context.cfgimpl_get_settings().getproperties(option_bag,
else: apply_requires=False)
# it's ParamOption new_value = get_value(callbk, option_bag, path)
opt = callbk.option if apply_index is None and is_follower:
if opt.issubdyn(): new_value[index] = value
opt = opt.to_dynoption(option.rootpath, value = new_value
option.impl_getsuffix()) elif apply_index is not None and not is_follower:
path = opt.impl_getpath() value = value[apply_index]
is_follower = opt.impl_is_follower() return value
if leadership_must_have_index and opt.impl_get_leadership() and index is None:
raise Break() def get_value(callbk, option_bag, path):
if index is not None and opt.impl_get_leadership() and \ try:
opt.impl_get_leadership().in_same_group(option): # get value
if opt == option: value = config_bag.context.getattr(path,
index_ = None option_bag)
with_index = False except PropertiesOptionError as err:
elif is_follower: # raise PropertiesOptionError (which is catched) because must not add value None in carry_out_calculation
index_ = index if callbk.notraisepropertyerror or callbk.raisepropertyerror:
with_index = False raise err
else: raise ConfigError(_('unable to carry out a calculation for "{}"'
index_ = None ', {}').format(option.impl_get_display_name(), err), err)
with_index = True except ValueError as err:
else: raise ValueError(_('the option "{0}" is used in a calculation but is invalid ({1})').format(option_bag.option.impl_get_display_name(), err))
index_ = None return value
with_index = False
if opt == option and orig_value is not undefined and \ def get_option_bag(config_bag, opt, path, index_):
(not is_follower or index is None):
value = orig_value
else:
# don't validate if option is option that we tried to validate # don't validate if option is option that we tried to validate
config_bag = config_bag.copy() config_bag = config_bag.copy()
config_bag.properties = config_bag.true_properties - {'warnings'} config_bag.properties = config_bag.true_properties - {'warnings'}
@ -220,29 +239,64 @@ def manager_callback(callbk: Union[ParamOption, ParamValue],
path, path,
index_, index_,
config_bag) config_bag)
if fromconsistency: return option_bag
option_bag.fromconsistency = fromconsistency.copy()
if opt == option: if isinstance(callbk, ParamValue):
option_bag.config_bag.unrestraint() return callbk.value
option_bag.config_bag.remove_validation()
# if we are in properties calculation, cannot calculated properties if isinstance(callbk, ParamIndex):
option_bag.properties = config_bag.context.cfgimpl_get_settings().getproperties(option_bag, return index
apply_requires=False)
try: if isinstance(callbk, ParamSuffix):
# get value if not option.issubdyn():
value = config_bag.context.getattr(path, raise ConfigError('option "{}" is not in a dynoptiondescription'.format(option.impl_get_display_name()))
option_bag) return option.impl_getsuffix()
if with_index:
value = value[index] if isinstance(callbk, ParamContext):
except PropertiesOptionError as err: if config_bag is undefined:
# raise PropertiesOptionError (which is catched) because must not add value None in carry_out_calculation return undefined
if callbk.notraisepropertyerror or callbk.raisepropertyerror: # Not an option, set full context
raise err return config_bag.context.duplicate(force_values=get_default_values_storages(),
raise ConfigError(_('unable to carry out a calculation for "{}"' force_settings=get_default_settings_storages())
', {}').format(option.impl_get_display_name(), err), err) if isinstance(callbk, ParamSelfOption):
if leadership_must_have_index and option.impl_get_leadership() and index is None:
raise Break()
value = calc_self(callbk, option, index, orig_value, config_bag)
if not callbk.todict: if not callbk.todict:
return value return value
return {'name': opt.impl_get_display_name(), return {'name': option.impl_get_display_name(),
'value': value}
# it's ParamOption
callbk_option = callbk.option
if callbk_option.issubdyn():
callbk_option = callbk_option.to_dynoption(option.rootpath,
option.impl_getsuffix())
if leadership_must_have_index and callbk_option.impl_get_leadership() and index is None:
raise Break()
if config_bag is undefined:
return undefined
if index is not None and callbk_option.impl_get_leadership() and \
callbk_option.impl_get_leadership().in_same_group(option):
if not callbk_option.impl_is_follower():
# leader
index_ = None
with_index = True
else:
# follower
index_ = index
with_index = False
else:
index_ = None
with_index = False
path = callbk_option.impl_getpath()
option_bag = get_option_bag(config_bag, callbk_option, path, index_)
value = get_value(callbk, option_bag, path)
if with_index:
value = value[index]
if not callbk.todict:
return value
return {'name': callbk_option.impl_get_display_name(),
'value': value} 'value': value}
@ -251,10 +305,9 @@ def carry_out_calculation(option,
callback_params: Optional[Params], callback_params: Optional[Params],
index: Optional[int], index: Optional[int],
config_bag: Optional[ConfigBag], config_bag: Optional[ConfigBag],
fromconsistency: List,
orig_value=undefined, orig_value=undefined,
leadership_must_have_index: bool=False, leadership_must_have_index: bool=False,
is_validator: int=False): allow_raises: int=False):
"""a function that carries out a calculation for an option's value """a function that carries out a calculation for an option's value
:param option: the option :param option: the option
@ -265,109 +318,16 @@ def carry_out_calculation(option,
:type callback_params: dict :type callback_params: dict
:param index: if an option is multi, only calculates the nth value :param index: if an option is multi, only calculates the nth value
:type index: int :type index: int
:param is_validator: to know if carry_out_calculation is used to validate a value :param allow_raises: to know if carry_out_calculation is used to validate a value
The callback_params is a dict. Key is used to build args (if key is '') The callback_params is a dict. Key is used to build args (if key is '')
and kwargs (otherwise). Values are tuple of: and kwargs (otherwise). Values are tuple of:
- values - values
- tuple with option and boolean's force_permissive (True when don't raise - tuple with option and boolean's force_permissive (True when don't raise
if PropertiesOptionError) if PropertiesOptionError)
Values could have multiple values only when key is ''. Values could have multiple values only when key is ''."""
* if no callback_params:
=> calculate(<function func at 0x2092320>, [], {})
* if callback_params={'': ('yes',)}
=> calculate(<function func at 0x2092320>, ['yes'], {})
* if callback_params={'value': ('yes',)}
=> calculate(<function func at 0x165b320>, [], {'value': 'yes'})
* if callback_params={'': ('yes', 'no')}
=> calculate('yes', 'no')
* if callback_params={'value': ('yes', 'no')}
=> ValueError()
* if callback_params={'': (['yes', 'no'],)}
=> calculate(<function func at 0x176b320>, ['yes', 'no'], {})
* if callback_params={'value': ('yes', 'no')}
=> raises ValueError()
* if callback_params={'': ((opt1, False),)}
- a simple option:
opt1 == 11
=> calculate(<function func at 0x1cea320>, [11], {})
- a multi option and not leadership
opt1 == [1, 2, 3]
=> calculate(<function func at 0x223c320>, [[1, 2, 3]], {})
- option is leader or follower of opt1:
opt1 == [1, 2, 3]
=> calculate(<function func at 0x223c320>, [1], {})
=> calculate(<function func at 0x223c320>, [2], {})
=> calculate(<function func at 0x223c320>, [3], {})
- opt is a leader or follower but not related to option:
opt1 == [1, 2, 3]
=> calculate(<function func at 0x11b0320>, [[1, 2, 3]], {})
* if callback_params={'value': ((opt1, False),)}
- a simple option:
opt1 == 11
=> calculate(<function func at 0x17ff320>, [], {'value': 11})
- a multi option:
opt1 == [1, 2, 3]
=> calculate(<function func at 0x1262320>, [], {'value': [1, 2, 3]})
* if callback_params={'': ((opt1, False), (opt2, False))}
- two single options
opt1 = 11
opt2 = 12
=> calculate(<function func at 0x217a320>, [11, 12], {})
- a multi option with a simple option
opt1 == [1, 2, 3]
opt2 == 12
=> calculate(<function func at 0x2153320>, [[1, 2, 3], 12], {})
- a multi option with an other multi option but with same length
opt1 == [1, 2, 3]
opt2 == [11, 12, 13]
=> calculate(<function func at 0x1981320>, [[1, 2, 3], [11, 12, 13]], {})
- a multi option with an other multi option but with different length
opt1 == [1, 2, 3]
opt2 == [11, 12]
=> calculate(<function func at 0x2384320>, [[1, 2, 3], [11, 12]], {})
- a multi option without value with a simple option
opt1 == []
opt2 == 11
=> calculate(<function func at 0xb65320>, [[], 12], {})
* if callback_params={'value': ((opt1, False), (opt2, False))}
=> raises ValueError()
If index is not undefined, return a value, otherwise return:
* a list if one parameters have multi option
* a value otherwise
If calculate return list, this list is extend to return value.
"""
args = [] args = []
kwargs = {} kwargs = {}
# if callback_params has a callback, launch several time calculate()
if option.issubdyn():
#FIXME why here? should be a ParamSuffix !
kwargs['suffix'] = option.impl_getsuffix()
if callback_params: if callback_params:
for callbk in callback_params.args: for callbk in callback_params.args:
try: try:
@ -376,7 +336,6 @@ def carry_out_calculation(option,
index, index,
orig_value, orig_value,
config_bag, config_bag,
fromconsistency,
leadership_must_have_index) leadership_must_have_index)
if value is undefined: if value is undefined:
return undefined return undefined
@ -395,7 +354,6 @@ def carry_out_calculation(option,
index, index,
orig_value, orig_value,
config_bag, config_bag,
fromconsistency,
leadership_must_have_index) leadership_must_have_index)
if value is undefined: if value is undefined:
return undefined return undefined
@ -409,7 +367,7 @@ def carry_out_calculation(option,
continue continue
ret = calculate(option, ret = calculate(option,
callback, callback,
is_validator, allow_raises,
args, args,
kwargs) kwargs)
if isinstance(ret, list) and not option.impl_is_dynoptiondescription() and \ if isinstance(ret, list) and not option.impl_is_dynoptiondescription() and \
@ -434,7 +392,7 @@ def carry_out_calculation(option,
def calculate(option, def calculate(option,
callback: Callable, callback: Callable,
is_validator: bool, allow_raises: bool,
args, args,
kwargs): kwargs):
"""wrapper that launches the 'callback' """wrapper that launches the 'callback'
@ -447,7 +405,7 @@ def calculate(option,
try: try:
return callback(*args, **kwargs) return callback(*args, **kwargs)
except ValueError as err: except ValueError as err:
if is_validator: if allow_raises:
raise err raise err
error = err error = err
except Exception as err: except Exception as err:

View File

@ -48,8 +48,7 @@ class SubConfig(object):
descr, descr,
context, context,
config_bag, config_bag,
subpath=None, subpath=None):
fromconsistency=None):
""" Configuration option management class """ Configuration option management class
:param descr: describes the configuration schema :param descr: describes the configuration schema
@ -82,8 +81,6 @@ class SubConfig(object):
full_leaderpath, full_leaderpath,
None, None,
cconfig_bag) cconfig_bag)
if fromconsistency:
moption_bag.fromconsistency = fromconsistency
value = self.getattr(leaderpath, value = self.getattr(leaderpath,
moption_bag) moption_bag)
self._impl_length = len(value) self._impl_length = len(value)
@ -179,8 +176,7 @@ class SubConfig(object):
def cfgimpl_get_home_by_path(self, def cfgimpl_get_home_by_path(self,
path, path,
config_bag, config_bag):
fromconsistency=None):
""":returns: tuple (config, name)""" """:returns: tuple (config, name)"""
path = path.split('.') path = path.split('.')
for step in path[:-1]: for step in path[:-1]:
@ -193,8 +189,6 @@ class SubConfig(object):
subpath, subpath,
None, None,
config_bag) config_bag)
if fromconsistency is not None:
option_bag.fromconsistency = fromconsistency
self = self.get_subconfig(option_bag) self = self.get_subconfig(option_bag)
assert isinstance(self, SubConfig), _('unknown option {}').format(path[-1]) assert isinstance(self, SubConfig), _('unknown option {}').format(path[-1])
return self, path[-1] return self, path[-1]
@ -253,17 +247,11 @@ class SubConfig(object):
def get_subconfig(self, def get_subconfig(self,
option_bag): option_bag):
if option_bag.fromconsistency:
fromconsistency = option_bag.fromconsistency.copy()
else:
fromconsistency = None
self.cfgimpl_get_settings().validate_properties(option_bag) self.cfgimpl_get_settings().validate_properties(option_bag)
return SubConfig(option_bag.option, return SubConfig(option_bag.option,
self._impl_context, self._impl_context,
option_bag.config_bag, option_bag.config_bag,
option_bag.path, option_bag.path)
fromconsistency)
def getattr(self, def getattr(self,
name, name,
@ -276,13 +264,8 @@ class SubConfig(object):
""" """
config_bag = option_bag.config_bag config_bag = option_bag.config_bag
if '.' in name: if '.' in name:
if option_bag.fromconsistency:
fromconsistency = option_bag.fromconsistency.copy()
else:
fromconsistency = None
self, name = self.cfgimpl_get_home_by_path(name, self, name = self.cfgimpl_get_home_by_path(name,
config_bag, config_bag)
fromconsistency)
option = option_bag.option option = option_bag.option
if option.impl_is_symlinkoption(): if option.impl_is_symlinkoption():
@ -309,8 +292,7 @@ class SubConfig(object):
length, length,
option_bag.index)) option_bag.index))
if option.impl_is_follower() and option_bag.index is None: if option.impl_is_follower() and option_bag.index is None:
needs_re_verify_follower_properties = option_bag.option.impl_getrequires() or \ needs_re_verify_follower_properties = self.cfgimpl_get_settings().has_properties_index(option_bag)
self.cfgimpl_get_settings().has_properties_index(option_bag)
value = [] value = []
for idx in range(length): for idx in range(length):
soption_bag = OptionBag() soption_bag = OptionBag()
@ -318,7 +300,6 @@ class SubConfig(object):
option_bag.path, option_bag.path,
idx, idx,
config_bag) config_bag)
soption_bag.fromconsistency = option_bag.fromconsistency.copy()
try: try:
value.append(self.getattr(name, value.append(self.getattr(name,
soption_bag, soption_bag,
@ -860,7 +841,6 @@ class KernelGroupConfig(_CommonConfig):
err.proptype, err.proptype,
err._settings, err._settings,
err._opt_type, err._opt_type,
err._requires,
err._name, err._name,
err._orig_opt)) err._orig_opt))
except (ValueError, LeadershipError, AttributeError) as err: except (ValueError, LeadershipError, AttributeError) as err:
@ -1069,7 +1049,6 @@ class KernelMixConfig(KernelGroupConfig):
err.proptype, err.proptype,
err._settings, err._settings,
err._opt_type, err._opt_type,
err._requires,
err._name, err._name,
err._orig_opt)) err._orig_opt))
except (ValueError, LeadershipError, AttributeError) as err: except (ValueError, LeadershipError, AttributeError) as err:

View File

@ -58,12 +58,10 @@ class PropertiesOptionError(AttributeError):
proptype, proptype,
settings, settings,
opt_type=None, opt_type=None,
requires=None,
name=None, name=None,
orig_opt=None): orig_opt=None):
if opt_type: if opt_type:
self._opt_type = opt_type self._opt_type = opt_type
self._requires = requires
self._name = name self._name = name
self._orig_opt = orig_opt self._orig_opt = orig_opt
else: else:
@ -71,7 +69,6 @@ class PropertiesOptionError(AttributeError):
self._opt_type = 'optiondescription' self._opt_type = 'optiondescription'
else: else:
self._opt_type = 'option' self._opt_type = 'option'
self._requires = option_bag.option.impl_getrequires()
self._name = option_bag.option.impl_get_display_name() self._name = option_bag.option.impl_get_display_name()
self._orig_opt = None self._orig_opt = None
self._option_bag = option_bag self._option_bag = option_bag
@ -89,15 +86,6 @@ class PropertiesOptionError(AttributeError):
return self.msg return self.msg
if self._settings is None: if self._settings is None:
return 'error' return 'error'
req = self._settings.apply_requires(self._option_bag,
True)
if req != {}:
only_one = len(req) == 1
msg = []
for action, msg_ in req.items():
msg.append('"{0}" ({1})'.format(action, display_list(msg_, add_quote=False)))
msg = display_list(msg, add_quote=False)
else:
properties = list(self._settings.calc_raises_properties(self._option_bag, properties = list(self._settings.calc_raises_properties(self._option_bag,
apply_requires=False)) apply_requires=False))
for property_ in self._settings.get_calculated_properties(self._option_bag): for property_ in self._settings.get_calculated_properties(self._option_bag):
@ -125,7 +113,7 @@ class PropertiesOptionError(AttributeError):
self._name, self._name,
prop_msg, prop_msg,
msg)) msg))
del self._requires, self._opt_type, self._name del self._opt_type, self._name
del self._settings, self._orig_opt del self._settings, self._orig_opt
return self.msg return self.msg
@ -150,13 +138,6 @@ class ConflictError(Exception):
#____________________________________________________________ #____________________________________________________________
# miscellaneous exceptions # miscellaneous exceptions
class RequirementError(Exception):
"""a recursive loop occurs in the requirements tree
requires
"""
pass
class LeadershipError(Exception): class LeadershipError(Exception):
"problem with a leadership's value length" "problem with a leadership's value length"
pass pass

View File

@ -14,13 +14,144 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from typing import Any, List, Optional from typing import Any, List, Optional
from operator import add, mul, sub, truediv from operator import add, mul, sub, truediv
from ipaddress import ip_address, ip_interface, ip_network
from .i18n import _ from .i18n import _
from .setting import undefined from .setting import undefined
from .error import display_list from .error import display_list
def tiramisu_copy(val): # pragma: no cover def valid_network_netmask(network: str,
return val netmask: str):
"""FIXME
"""
if isinstance(network, dict):
network_value = network['value']
network_display_name = '({})'.format(network['name'])
else:
network_value = network
network_display_name = ''
if None in [network_value, netmask]:
return
try:
ip_network('{0}/{1}'.format(network_value, netmask))
except ValueError:
raise ValueError(_('network "{0}" {1}does not match with this netmask').format(network_value,
network_display_name))
def valid_ip_netmask(ip: str,
netmask: str):
if isinstance(ip, dict):
ip_value = ip['value']
ip_display_name = '({})'.format(ip['name'])
else:
ip_value = ip
ip_display_name = ''
if None in [ip_value, netmask]:
return
ip_netmask = ip_interface('{0}/{1}'.format(ip_value, netmask))
if ip_netmask.ip == ip_netmask.network.network_address:
raise ValueError(_('IP \"{0}\" {1}with this netmask is in fact a network address').format(ip_value, ip_display_name))
elif ip_netmask.ip == ip_netmask.network.broadcast_address:
raise ValueError(_('IP \"{0}\" {1}with this netmask is in fact a broacast address').format(ip_value, ip_display_name))
# FIXME CIDR ?
def valid_broadcast(network: 'NetworkOption',
netmask: 'NetmaskOption',
broadcast: 'BroadcastOption'):
if isinstance(network, dict):
network_value = network['value']
network_display_name = ' ({})'.format(network['name'])
else:
network_value = network
network_display_name = ''
if isinstance(netmask, dict):
netmask_value = netmask['value']
netmask_display_name = ' ({})'.format(netmask['name'])
else:
netmask_value = netmask
netmask_display_name = ''
if ip_network('{0}/{1}'.format(network, netmask)).broadcast_address != ip_address(broadcast):
raise ValueError(_('broadcast invalid with network {0}{1} and netmask {2}{3}'
'').format(network_value,
network_display_name,
netmask_value,
netmask_display_name))
def valid_in_network(ip,
network,
netmask=None):
if isinstance(network, dict):
network_value = network['value']
network_display_name = ' ({})'.format(network['name'])
else:
network_value = network
network_display_name = ''
if netmask is None:
network_obj = ip_network('{0}'.format(network_value))
else:
if isinstance(netmask, dict):
netmask_value = netmask['value']
netmask_display_name = ' ({})'.format(netmask['name'])
else:
netmask_value = netmask
netmask_display_name = ''
network_obj = ip_network('{0}/{1}'.format(network_value,
netmask_value))
if ip_interface(ip) not in network_obj:
if netmask is None:
msg = _('this IP is not in network {0}{1}').format(network_value,
network_display_name)
else:
msg = _('this IP is not in network {0}{1} with netmask {2}{3}').format(network_value,
network_display_name,
netmask_value,
netmask_display_name)
raise ValueError(msg)
# test if ip is not network/broadcast IP
ip_netmask = ip_interface('{0}/{1}'.format(ip, network_obj.netmask))
if ip_netmask.ip == ip_netmask.network.network_address:
if netmask is None:
msg = _('this IP with the network {0}{1} is in fact a network address').format(network_value,
network_display_name)
else:
msg = _('this IP with the netmask {0}{1} is in fact a network address').format(netmask_value,
netmask_display_name)
raise ValueError(msg)
elif ip_netmask.ip == ip_netmask.network.broadcast_address:
if netmask is None:
msg = _('this IP with the network {0}{1} is in fact a broadcast address').format(network_value,
network_display_name)
else:
msg = _('this IP with the netmask {0}{1} is in fact a broadcast address').format(netmask_value,
netmask_display_name)
raise ValueError(msg)
def valid_not_equal(*values):
equal = set()
for idx, val in enumerate(values[1:]):
if isinstance(val, dict):
if 'propertyerror' in val:
continue
tval = val['value']
else:
tval = val
if values[0] == tval is not None:
if isinstance(val, dict):
if equal is True:
equal = set()
equal.add(val['name'])
elif not equal:
equal = True
if equal:
if equal is not True:
msg = _('value is identical to {}').format(display_list(list(equal), add_quote=True))
else:
msg = _('value is identical')
raise ValueError(msg)
class CalcValue: class CalcValue:

View File

@ -51,14 +51,8 @@ class Base:
__slots__ = ('_name', __slots__ = ('_name',
'_path', '_path',
'_informations', '_informations',
#calcul
'_subdyn', '_subdyn',
'_requires',
'_properties', '_properties',
'_calc_properties',
#
'_consistencies',
#other
'_has_dependency', '_has_dependency',
'_dependencies', '_dependencies',
'_has_calc_context', '_has_calc_context',
@ -68,19 +62,10 @@ class Base:
def __init__(self, def __init__(self,
name: str, name: str,
doc: str, doc: str,
requires=None,
properties=None, properties=None,
is_multi: bool=False) -> None: is_multi: bool=False) -> None:
if not valid_name(name): if not valid_name(name):
raise ValueError(_('"{0}" is an invalid name for an option').format(name)) raise ValueError(_('"{0}" is an invalid name for an option').format(name))
if requires is not None:
calc_properties, requires = validate_requires_arg(self,
is_multi,
requires,
name)
else:
calc_properties = frozenset()
requires = undefined
if properties is None: if properties is None:
properties = frozenset() properties = frozenset()
elif isinstance(properties, tuple): elif isinstance(properties, tuple):
@ -92,153 +77,18 @@ class Base:
assert isinstance(properties, frozenset), _('invalid properties type {0} for {1},' assert isinstance(properties, frozenset), _('invalid properties type {0} for {1},'
' must be a frozenset').format(type(properties), ' must be a frozenset').format(type(properties),
name) name)
self.validate_properties(name,
calc_properties,
properties)
_setattr = object.__setattr__
_setattr(self, '_name', name)
_setattr(self, '_informations', {'doc': doc})
if calc_properties is not undefined:
_setattr(self, '_calc_properties', calc_properties)
if requires is not undefined:
_setattr(self, '_requires', requires)
if properties:
_setattr(self, '_properties', properties)
def validate_properties(self,
name: str,
calc_properties: FrozenSet[str],
properties: FrozenSet[str]) -> None:
set_forbidden_properties = calc_properties & properties
if set_forbidden_properties != frozenset():
raise ValueError(_('conflict: properties already set in requirement {0} for {1}'
'').format(display_list(set_forbidden_properties, add_quote=True),
name))
assert isinstance(properties, frozenset), _('invalid properties type {0} for {1},'
' must be a frozenset').format(type(properties),
name)
for prop in properties: for prop in properties:
if not isinstance(prop, str): if not isinstance(prop, str):
if not isinstance(prop, Calculation): if not isinstance(prop, Calculation):
raise ValueError(_('invalid property type {0} for {1}, must be a string or a Calculation').format(type(prop), name)) raise ValueError(_('invalid property type {0} for {1}, must be a string or a Calculation').format(type(prop), name))
params = prop.params for param in chain(prop.params.args, prop.params.kwargs.values()):
for param in chain(params.args, params.kwargs.values()):
if isinstance(param, ParamOption): if isinstance(param, ParamOption):
param.option._add_dependency(self) param.option._add_dependency(self)
_setattr = object.__setattr__
def _get_function_args(self, _setattr(self, '_name', name)
function: Callable) -> Tuple[Set[str], Set[str], bool, bool]: _setattr(self, '_informations', {'doc': doc})
args = set() if properties:
kwargs = set() _setattr(self, '_properties', properties)
positional = False
keyword = False
for param in signature(function).parameters.values():
if param.kind == param.VAR_POSITIONAL:
positional = True
elif param.kind == param.VAR_KEYWORD:
keyword = True
elif param.default is param.empty:
args.add(param.name)
else:
kwargs.add(param.name)
return args, kwargs, positional, keyword
def _get_parameters_args(self,
calculator_params: Optional[Params],
add_value: bool) -> Tuple[Set[str], Set[str]]:
args = set()
kwargs = set()
# add value as first argument
if add_value:
args.add('value')
if self.impl_is_dynoptiondescription():
kwargs.add('suffix')
if calculator_params:
for idx in range(len(calculator_params.args)):
# construct an appropriate name
args.add('param{}'.format(idx))
for param in calculator_params.kwargs:
kwargs.add(param)
return args, kwargs
def _build_calculator_params(self,
calculator: Callable,
calculator_params: Optional[Params],
type_: str,
add_value: bool=False) -> Union[None, Params]:
"""
:add_value: add value as first argument for validator
"""
assert isinstance(calculator, Callable), _('{0} must be a function').format(type_)
if calculator_params is not None:
assert isinstance(calculator_params, Params), _('{0}_params must be a params'
'').format(type_)
for param in chain(calculator_params.args, calculator_params.kwargs.values()):
if isinstance(param, ParamContext):
self._has_calc_context = True
elif isinstance(param, ParamOption):
param.option._add_dependency(self)
if type_ == 'validator':
self._has_dependency = True
is_multi = self.impl_is_optiondescription() or self.impl_is_multi()
func_args, func_kwargs, func_positional, func_keyword = self._get_function_args(calculator)
calculator_args, calculator_kwargs = self._get_parameters_args(calculator_params, add_value)
# remove knowned kwargs
common_kwargs = func_kwargs & calculator_kwargs
func_kwargs -= common_kwargs
calculator_kwargs -= common_kwargs
# remove knowned calculator's kwargs in func's args
common = func_args & calculator_kwargs
func_args -= common
calculator_kwargs -= common
# remove unknown calculator's args in func's args
for idx in range(min(len(calculator_args), len(func_args))):
func_args.pop()
calculator_args.pop()
# remove unknown calculator's args in func's kwargs
if is_multi:
func_kwargs_left = func_kwargs - {'index', 'self'}
else:
func_kwargs_left = func_kwargs
func_kwargs_pop = set()
for idx in range(min(len(calculator_args), len(func_kwargs_left))):
func_kwargs_pop.add(func_kwargs_left.pop())
calculator_args.pop()
func_kwargs -= func_kwargs_pop
# func_positional or keyword is True, so assume all args or kwargs are satisfy
if func_positional:
calculator_args = set()
if func_keyword:
calculator_kwargs = set()
if calculator_args or calculator_kwargs:
# there is more args/kwargs than expected!
raise ConfigError(_('cannot find those arguments "{}" in function "{}" for "{}"'
'').format(display_list(list(calculator_args | calculator_kwargs)),
calculator.__name__,
self.impl_get_display_name()))
has_index = False
if is_multi and func_args and not self.impl_is_dynoptiondescription():
if calculator_params is None:
calculator_params = Params()
params = list(calculator_params.args)
if add_value:
# only for validator
params.append(ParamOption(self))
func_args.pop()
if func_args:
has_index = True
params.append(ParamIndex())
func_args.pop()
calculator_params.args = tuple(params)
if func_args:
raise ConfigError(_('missing those arguments "{}" in function "{}" for "{}"'
'').format(display_list(list(func_args)),
calculator.__name__,
self.impl_get_display_name()))
if not self.impl_is_dynoptiondescription() and is_multi and \
not has_index and 'index' in func_kwargs:
calculator_params.kwargs['index'] = ParamIndex()
return calculator_params
def impl_has_dependency(self, def impl_has_dependency(self,
self_is_dep: bool=True) -> bool: self_is_dep: bool=True) -> bool:
@ -323,9 +173,6 @@ class Base:
def getsubdyn(self): def getsubdyn(self):
return self._subdyn() return self._subdyn()
def impl_getrequires(self):
return getattr(self, '_requires', STATIC_TUPLE)
def impl_get_callback(self): def impl_get_callback(self):
call = getattr(self, '_val_call', (None, None))[1] call = getattr(self, '_val_call', (None, None))[1]
if call is None: if call is None:
@ -373,7 +220,6 @@ class Base:
raise AttributeError(_("'{0}' ({1}) object attribute '{2}' is" raise AttributeError(_("'{0}' ({1}) object attribute '{2}' is"
" read-only").format(self.__class__.__name__, " read-only").format(self.__class__.__name__,
self, self,
#self.impl_getname(),
key)) key))
self._informations[key] = value self._informations[key] = value
@ -445,181 +291,3 @@ class BaseOption(Base):
def impl_is_symlinkoption(self) -> bool: def impl_is_symlinkoption(self) -> bool:
return False return False
def validate_requires_arg(new_option: BaseOption,
multi: bool,
requires: List[dict],
name: str) -> Tuple[FrozenSet, Tuple]:
"""check malformed requirements
and tranform dict to internal tuple
:param requires: have a look at the
:meth:`tiramisu.setting.Settings.apply_requires` method to
know more about
the description of the requires dictionary
"""
def get_option(require):
if 'option' in require:
option = require['option']
if option == 'self':
option = new_option
if __debug__:
if not isinstance(option, BaseOption):
raise ValueError(_('malformed requirements '
'must be an option in option {0}').format(name))
if not multi and option.impl_is_multi():
raise ValueError(_('malformed requirements '
'multi option must not set '
'as requires of non multi option {0}').format(name))
option._add_dependency(new_option)
else:
callback = require['callback']
callback_params = new_option._build_calculator_params(callback,
require.get('callback_params'),
'callback')
option = (callback, callback_params)
return option
def _set_expected(action,
inverse,
transitive,
same_action,
option,
expected,
operator):
if inverse not in ret_requires[action]:
ret_requires[action][inverse] = ([(option, [expected])], action, inverse, transitive, same_action, operator)
else:
for exp in ret_requires[action][inverse][0]:
if exp[0] == option:
exp[1].append(expected)
break
else:
ret_requires[action][inverse][0].append((option, [expected]))
def set_expected(require,
ret_requires):
expected = require['expected']
inverse = get_inverse(require)
transitive = get_transitive(require)
same_action = get_sameaction(require)
operator = get_operator(require)
if isinstance(expected, list):
for exp in expected:
if __debug__ and set(exp.keys()) != {'option', 'value'}:
raise ValueError(_('malformed requirements expected must have '
'option and value for option {0}').format(name))
option = get_option(exp)
if __debug__:
try:
option._validate(exp['value'], undefined)
except ValueError as err:
raise ValueError(_('malformed requirements expected value '
'must be valid for option {0}'
': {1}').format(name, err))
_set_expected(action,
inverse,
transitive,
same_action,
option,
exp['value'],
operator)
else:
option = get_option(require)
if __debug__ and not isinstance(option, tuple) and expected is not None:
try:
option._validate(expected, undefined)
except ValueError as err:
raise ValueError(_('malformed requirements expected value '
'must be valid for option {0}'
': {1}').format(name, err))
_set_expected(action,
inverse,
transitive,
same_action,
option,
expected,
operator)
def get_action(require):
action = require['action']
if action == 'force_store_value':
raise ValueError(_("malformed requirements for option: {0}"
" action cannot be force_store_value"
).format(name))
return action
def get_inverse(require):
inverse = require.get('inverse', False)
if inverse not in [True, False]:
raise ValueError(_('malformed requirements for option: {0}'
' inverse must be boolean'))
return inverse
def get_transitive(require):
transitive = require.get('transitive', True)
if transitive not in [True, False]:
raise ValueError(_('malformed requirements for option: {0}'
' transitive must be boolean'))
return transitive
def get_sameaction(require):
same_action = require.get('same_action', True)
if same_action not in [True, False]:
raise ValueError(_('malformed requirements for option: {0}'
' same_action must be boolean'))
return same_action
def get_operator(require):
operator = require.get('operator', 'or')
if operator not in ['and', 'or']:
raise ValueError(_('malformed requirements for option: "{0}"'
' operator must be "or" or "and"').format(operator))
return operator
ret_requires = {}
config_action = set()
# start parsing all requires given by user (has dict)
# transforme it to a tuple
for require in requires:
if __debug__:
if not isinstance(require, dict):
raise ValueError(_("malformed requirements type for option:"
" {0}, must be a dict").format(name))
valid_keys = ('option', 'expected', 'action', 'inverse', 'transitive',
'same_action', 'operator', 'callback', 'callback_params')
unknown_keys = frozenset(require.keys()) - frozenset(valid_keys)
if unknown_keys != frozenset():
raise ValueError(_('malformed requirements for option: {0}'
' unknown keys {1}, must only '
'{2}').format(name,
unknown_keys,
valid_keys))
# {'expected': ..., 'option': ..., 'action': ...}
# {'expected': [{'option': ..., 'value': ...}, ...}], 'action': ...}
# {'expected': ..., 'callback': ..., 'action': ...}
if not 'expected' in require or not 'action' in require or \
not (isinstance(require['expected'], list) or \
'option' in require or \
'callback' in require):
raise ValueError(_("malformed requirements for option: {0}"
" require must have option, expected and"
" action keys").format(name))
action = get_action(require)
config_action.add(action)
if action not in ret_requires:
ret_requires[action] = {}
set_expected(require, ret_requires)
# transform dict to tuple
ret = []
for requires in ret_requires.values():
ret_action = []
for require in requires.values():
ret_action.append((tuple(require[0]), require[1],
require[2], require[3], require[4], require[5]))
ret.append(tuple(ret_action))
return frozenset(config_action), tuple(ret)

View File

@ -46,22 +46,3 @@ class BroadcastOption(Option):
ip_address(value) ip_address(value)
except ValueError: except ValueError:
raise ValueError() raise ValueError()
def _cons_broadcast(self,
current_opt,
opts,
vals,
warnings_only,
context):
if len(vals) != 3:
raise ConfigError(_('invalid broadcast consistency, a network and a netmask are needed'))
if None in vals:
return
broadcast, network, netmask = vals
if ip_network('{0}/{1}'.format(network, netmask)).broadcast_address != ip_address(broadcast):
raise ValueError(_('broadcast "{4}" invalid with network {0}/{1} ("{2}"/"{3}")'
'').format(network,
netmask,
opts[1].impl_get_display_name(),
opts[2].impl_get_display_name(),
broadcast))

View File

@ -23,7 +23,7 @@ from types import FunctionType
from ..setting import undefined from ..setting import undefined
from ..i18n import _ from ..i18n import _
from .option import Option from .option import Option
from ..autolib import carry_out_calculation from ..autolib import carry_out_calculation, Calculation
from ..error import ConfigError, display_list from ..error import ConfigError, display_list
@ -41,69 +41,32 @@ class ChoiceOption(Option):
doc, doc,
values, values,
default=None, default=None,
values_params=None,
default_multi=None, default_multi=None,
requires=None,
multi=False, multi=False,
callback=None, validators=None,
callback_params=None,
validator=None,
validator_params=None,
properties=None, properties=None,
warnings_only=False): warnings_only=False):
""" """
:param values: is a list of values the option can possibly take :param values: is a list of values the option can possibly take
""" """
if isinstance(values, FunctionType): if not isinstance(values, (Calculation, tuple)):
values_params = self._build_calculator_params(values, raise TypeError(_('values must be a tuple or a calculation for {0}'
values_params,
'values')
if values_params:
self._choice_values_params = values_params
else:
if values_params is not None:
raise ValueError(_('values is not a function, so values_params must be None'))
if not isinstance(values, tuple):
raise TypeError(_('values must be a tuple or a function for {0}'
).format(name)) ).format(name))
self._choice_values = values self._choice_values = values
super(ChoiceOption, self).__init__(name, super(ChoiceOption, self).__init__(name,
doc, doc,
default=default, default=default,
default_multi=default_multi, default_multi=default_multi,
callback=callback,
callback_params=callback_params,
requires=requires,
multi=multi, multi=multi,
validator=validator, validators=validators,
validator_params=validator_params,
properties=properties, properties=properties,
warnings_only=warnings_only) warnings_only=warnings_only)
def get_callback(self):
values = self._choice_values
if isinstance(values, FunctionType):
return (values, getattr(self, '_choice_values_params', {}))
else:
return (None, None)
def impl_get_values(self, def impl_get_values(self,
option_bag, option_bag):
current_opt=undefined): if isinstance(self._choice_values, Calculation):
if current_opt is undefined: values = self._choice_values.execute(option_bag)
current_opt = self
values, values_params = self.get_callback()
if values is not None:
if option_bag is undefined:
values = undefined
else:
values = carry_out_calculation(current_opt,
callback=values,
callback_params=values_params,
index=None,
config_bag=option_bag.config_bag,
fromconsistency=[])
if values is not undefined and not isinstance(values, list): if values is not undefined and not isinstance(values, list):
raise ConfigError(_('calculated values for {0} is not a list' raise ConfigError(_('calculated values for {0} is not a list'
'').format(self.impl_getname())) '').format(self.impl_getname()))
@ -111,13 +74,11 @@ class ChoiceOption(Option):
values = self._choice_values values = self._choice_values
return values return values
def _validate(self, def _validate(self,
value, value,
option_bag, option_bag,
current_opt=undefined): current_opt=undefined):
values = self.impl_get_values(option_bag, values = self.impl_get_values(option_bag)
current_opt=current_opt)
if values is not undefined and value not in values: if values is not undefined and value not in values:
if len(values) == 1: if len(values) == 1:
raise ValueError(_('only "{0}" is allowed' raise ValueError(_('only "{0}" is allowed'

View File

@ -42,12 +42,8 @@ class DomainnameOption(IPOption):
doc, doc,
default=None, default=None,
default_multi=None, default_multi=None,
requires=None,
multi: bool=False, multi: bool=False,
callback=None, validators=None,
callback_params=None,
validator=None,
validator_params=None,
properties=None, properties=None,
allow_ip: bool=False, allow_ip: bool=False,
cidr: bool=False, cidr: bool=False,
@ -94,12 +90,8 @@ class DomainnameOption(IPOption):
doc, doc,
default=default, default=default,
default_multi=default_multi, default_multi=default_multi,
callback=callback,
callback_params=callback_params,
requires=requires,
multi=multi, multi=multi,
validator=validator, validators=validators,
validator_params=validator_params,
properties=properties, properties=properties,
warnings_only=warnings_only, warnings_only=warnings_only,
cidr=cidr, cidr=cidr,

View File

@ -41,13 +41,11 @@ class DynOptionDescription(OptionDescription):
doc: str, doc: str,
children: List[BaseOption], children: List[BaseOption],
suffixes: Calculation, suffixes: Calculation,
requires=None,
properties=None) -> None: properties=None) -> None:
super().__init__(name, super().__init__(name,
doc, doc,
children, children,
requires,
properties) properties)
# check children + set relation to this dynoptiondescription # check children + set relation to this dynoptiondescription
for child in children: for child in children:

View File

@ -18,15 +18,14 @@
# the rough pypy's guys: http://codespeak.net/svn/pypy/dist/pypy/config/ # the rough pypy's guys: http://codespeak.net/svn/pypy/dist/pypy/config/
# the whole pypy projet is under MIT licence # the whole pypy projet is under MIT licence
# ____________________________________________________________ # ____________________________________________________________
from ipaddress import ip_address, ip_interface, ip_network from ipaddress import ip_address, ip_interface
from ..error import ConfigError from ..error import ConfigError
from ..setting import undefined, Undefined, OptionBag from ..setting import undefined, Undefined, OptionBag
from ..i18n import _ from ..i18n import _
from .option import Option from .option import Option
from .stroption import StrOption from .stroption import StrOption
from .netmaskoption import NetmaskOption from ..function import valid_ip_netmask
from .networkoption import NetworkOption
class IPOption(StrOption): class IPOption(StrOption):
@ -40,12 +39,8 @@ class IPOption(StrOption):
doc, doc,
default=None, default=None,
default_multi=None, default_multi=None,
requires=None,
multi=False, multi=False,
callback=None, validators=None,
callback_params=None,
validator=None,
validator_params=None,
properties=None, properties=None,
private_only=False, private_only=False,
allow_reserved=False, allow_reserved=False,
@ -63,12 +58,8 @@ class IPOption(StrOption):
doc, doc,
default=default, default=default,
default_multi=default_multi, default_multi=default_multi,
callback=callback,
callback_params=callback_params,
requires=requires,
multi=multi, multi=multi,
validator=validator, validators=validators,
validator_params=validator_params,
properties=properties, properties=properties,
warnings_only=warnings_only, warnings_only=warnings_only,
extra=extra) extra=extra)
@ -98,9 +89,11 @@ class IPOption(StrOption):
if not cidr: if not cidr:
ip_address(value) ip_address(value)
else: else:
ip_interface(value) ip = ip_interface(value)
except ValueError: except ValueError:
raise ValueError() raise ValueError()
if cidr:
valid_ip_netmask(str(ip.ip), str(ip.netmask))
def _second_level_validation(self, def _second_level_validation(self,
value, value,
@ -118,68 +111,3 @@ class IPOption(StrOption):
else: else:
msg = _("must be private IP") msg = _("must be private IP")
raise ValueError(msg) raise ValueError(msg)
if '/' in value:
net = NetmaskOption(self.impl_getname(),
self.impl_get_display_name(),
str(ip.netmask))
net._cons_ip_netmask(self,
(net, self),
(str(ip.netmask), str(ip.ip)),
warnings_only,
None,
True)
def _cons_in_network(self,
current_opt,
opts,
vals,
warnings_only,
context):
if len(opts) == 2 and isinstance(opts[0], IPOption) and \
opts[0].impl_get_extra('_cidr') == False and \
isinstance(opts[1], NetworkOption) and \
opts[1].impl_get_extra('_cidr') == True:
if None in vals:
return
ip, network = vals
network_obj = ip_network(network)
if ip_interface(ip) not in network_obj:
msg = _('IP not in network "{0}" ("{1}")')
raise ValueError(msg.format(network,
opts[1].impl_get_display_name()))
# test if ip is not network/broadcast IP
netmask = NetmaskOption(self.impl_getname(),
self.impl_get_display_name(),
str(network_obj.netmask))
netmask._cons_ip_netmask(self,
(netmask, self),
(str(network_obj.netmask), str(ip)),
warnings_only,
None,
True)
else:
if len(vals) != 3 and context is undefined:
raise ConfigError(_('ip_network needs an IP, a network and a netmask'))
if len(vals) != 3 or None in vals:
return
ip, network, netmask = vals
if ip_interface(ip) not in ip_network('{0}/{1}'.format(network,
netmask)):
if current_opt == opts[0]:
msg = _('IP not in network "{2}"/"{4}" ("{3}"/"{5}")')
elif current_opt == opts[1]:
msg = _('the network doest not match with IP "{0}" ("{1}") and network "{4}" ("{5}")')
else:
msg = _('the netmask does not match with IP "{0}" ("{1}") and broadcast "{2}" ("{3}")')
raise ValueError(msg.format(ip,
opts[0].impl_get_display_name(),
network,
opts[1].impl_get_display_name(),
netmask,
opts[2].impl_get_display_name()))
# test if ip is not network/broadcast IP
opts[2]._cons_ip_netmask(current_opt,
(opts[2], opts[0]),
(netmask, ip),
warnings_only,
context)

View File

@ -25,13 +25,13 @@ from typing import List, Iterator, Optional, Any
from ..i18n import _ from ..i18n import _
from ..setting import groups, undefined, OptionBag, Settings from ..setting import groups, undefined, OptionBag, Settings, ALLOWED_LEADER_PROPERTIES
from ..value import Values from ..value import Values
from .optiondescription import OptionDescription from .optiondescription import OptionDescription
from .syndynoptiondescription import SynDynLeadership from .syndynoptiondescription import SynDynLeadership
from .baseoption import BaseOption from .baseoption import BaseOption
from .option import Option from .option import Option
from ..error import RequirementError from ..error import LeadershipError
from ..autolib import Calculation, ParamOption from ..autolib import Calculation, ParamOption
@ -43,12 +43,10 @@ class Leadership(OptionDescription):
name: str, name: str,
doc: str, doc: str,
children: List[BaseOption], children: List[BaseOption],
requires=None,
properties=None) -> None: properties=None) -> None:
super().__init__(name, super().__init__(name,
doc, doc,
children, children,
requires=requires,
properties=properties) properties=properties)
self._group_type = groups.leadership self._group_type = groups.leadership
followers = [] followers = []
@ -93,28 +91,9 @@ class Leadership(OptionDescription):
raise ValueError(_("callback of leader's option shall " raise ValueError(_("callback of leader's option shall "
"not refered to a follower's ones")) "not refered to a follower's ones"))
# leader should not have requires, only Leadership should have for prop in leader.impl_getproperties():
# so move requires to Leadership if prop not in ALLOWED_LEADER_PROPERTIES and not isinstance(prop, Calculation):
# if Leadership has requires too, cannot manage this move so raises raise LeadershipError(_('leader cannot have "{}" property').format(prop))
leader_requires = getattr(leader, '_requires', None)
if leader_requires:
if __debug__ and self.impl_getrequires():
raise RequirementError(_('leader {} have requirement, but Leadership {} too'
'').format(leader.impl_getname(),
self.impl_getname()))
leader_calproperties = getattr(leader, '_requires', None)
if leader_calproperties:
setattr(self, '_requires', leader_requires)
delattr(leader, '_requires')
if __debug__:
for requires_ in getattr(self, '_requires', ()):
for require in requires_:
for require_opt, values in require[0]:
if not isinstance(require_opt, tuple) and require_opt.impl_is_multi() and require_opt.impl_get_leadership():
raise ValueError(_('malformed requirements option "{0}" '
'must not be in follower for "{1}"').format(
require_opt.impl_getname(),
self.impl_getname()))
def is_leader(self, def is_leader(self,
opt: Option) -> bool: opt: Option) -> bool:

View File

@ -49,58 +49,3 @@ class NetmaskOption(StrOption):
ip_network('0.0.0.0/{0}'.format(value)) ip_network('0.0.0.0/{0}'.format(value))
except ValueError: except ValueError:
raise ValueError() raise ValueError()
def _cons_network_netmask(self,
current_opt: Option,
opts: List[Option],
vals: List[str],
warnings_only: bool,
context: 'Config'):
if context is undefined and len(vals) != 2:
raise ConfigError(_('network_netmask needs a network and a netmask'))
if None in vals or len(vals) != 2:
return
val_netmask, val_network = vals
opt_netmask, opt_network = opts
try:
ip_network('{0}/{1}'.format(val_network, val_netmask))
except ValueError:
if current_opt == opt_network:
raise ValueError(_('the netmask "{0}" ("{1}") does not match').format(val_netmask,
opt_netmask.impl_get_display_name()))
else:
raise ValueError(_('the network "{0}" ("{1}") does not match').format(val_network,
opt_network.impl_get_display_name()))
def _cons_ip_netmask(self,
current_opt: Option,
opts: List[Option],
vals: List[str],
warnings_only: bool,
context: 'config',
_cidr: bool=False):
if context is undefined and len(vals) != 2:
raise ConfigError(_('ip_netmask needs an IP and a netmask'))
if None in vals or len(vals) != 2:
return
val_netmask, val_ip = vals
opt_netmask, opt_ip = opts
ip = ip_interface('{0}/{1}'.format(val_ip, val_netmask))
if not _cidr and current_opt == opt_ip:
if ip.ip == ip.network.network_address:
raise ValueError( _('this is a network with netmask "{0}" ("{1}")'
'').format(val_netmask,
opt_netmask.impl_get_display_name()))
elif ip.ip == ip.network.broadcast_address:
raise ValueError(_('this is a broadcast with netmask "{0}" ("{1}")'
'').format(val_netmask,
opt_netmask.impl_get_display_name()))
else:
if ip.ip == ip.network.network_address:
raise ValueError(_('IP "{0}" ("{1}") is the network'
'').format(val_ip,
opt_ip.impl_get_display_name()))
elif ip.ip == ip.network.broadcast_address:
raise ValueError(_('IP "{0}" ("{1}") is the broadcast'
'').format(val_ip,
opt_ip.impl_get_display_name()))

View File

@ -36,12 +36,8 @@ class NetworkOption(Option):
doc, doc,
default=None, default=None,
default_multi=None, default_multi=None,
requires=None,
multi=False, multi=False,
callback=None, validators=None,
callback_params=None,
validator=None,
validator_params=None,
properties=None, properties=None,
warnings_only=False, warnings_only=False,
cidr=False): cidr=False):
@ -50,12 +46,8 @@ class NetworkOption(Option):
doc, doc,
default=default, default=default,
default_multi=default_multi, default_multi=default_multi,
callback=callback,
callback_params=callback_params,
requires=requires,
multi=multi, multi=multi,
validator=validator, validators=validators,
validator_params=validator_params,
properties=properties, properties=properties,
warnings_only=warnings_only, warnings_only=warnings_only,
extra=extra) extra=extra)

View File

@ -27,11 +27,11 @@ from itertools import chain
from .baseoption import BaseOption, submulti, STATIC_TUPLE from .baseoption import BaseOption, submulti, STATIC_TUPLE
from ..i18n import _ from ..i18n import _
from ..setting import undefined, OptionBag, Undefined from ..setting import undefined, OptionBag, Undefined
from ..autolib import Calculation, carry_out_calculation, Params, ParamValue, ParamContext, ParamOption from ..autolib import Calculation, Params, ParamValue, ParamContext, ParamOption
from ..error import (ConfigError, ValueWarning, ValueErrorWarning, PropertiesOptionError, from ..error import (ConfigError, ValueWarning, ValueErrorWarning, PropertiesOptionError,
ValueOptionError, display_list) ValueOptionError, display_list)
from .syndynoption import SynDynOption from .syndynoption import SynDynOption
ALLOWED_CONST_LIST = ['_cons_not_equal'] #ALLOWED_CONST_LIST = ['_cons_not_equal']
class Option(BaseOption): class Option(BaseOption):
@ -49,8 +49,8 @@ class Option(BaseOption):
# value # value
'_default', '_default',
'_default_multi', '_default_multi',
#calcul #
'_val_call', '_validators',
# #
'_leadership', '_leadership',
'_choice_values', '_choice_values',
@ -62,13 +62,9 @@ class Option(BaseOption):
doc: str, doc: str,
default: Any=undefined, default: Any=undefined,
default_multi: Any=None, default_multi: Any=None,
requires: List[Dict]=None,
multi: bool=False, multi: bool=False,
unique: bool=undefined, unique: bool=undefined,
callback: Optional[Callable]=None, validators: Optional[List[Calculation]]=None,
callback_params: Optional[Params]=None,
validator: Optional[Callable]=None,
validator_params: Optional[Params]=None,
properties: Optional[List[str]]=None, properties: Optional[List[str]]=None,
warnings_only: bool=False, warnings_only: bool=False,
extra: Optional[Dict]=None, extra: Optional[Dict]=None,
@ -99,19 +95,23 @@ class Option(BaseOption):
default = [] default = []
super().__init__(name, super().__init__(name,
doc, doc,
requires=requires,
properties=properties, properties=properties,
is_multi=is_multi) is_multi=is_multi)
if validator is not None: if __debug__:
validator_params = self._build_calculator_params(validator, if validators is not None:
validator_params, if not isinstance(validators, list):
'validator', raise ValueError(_('validators must be a list of Calculation for "{}"').format(name))
add_value=True) for validator in validators:
if not validator_params: if not isinstance(validator, Calculation):
val_call = (validator,) raise ValueError(_('validators must be a Calculation for "{}"').format(name))
else: for param in chain(validator.params.args, validator.params.kwargs.values()):
val_call = (validator, validator_params) if isinstance(param, ParamContext):
self._val_call = (val_call, None) self._has_calc_context = True
elif isinstance(param, ParamOption):
param.option._add_dependency(self)
self._has_dependency = True
self._validators = tuple(validators)
if extra is not None and extra != {}: if extra is not None and extra != {}:
_setattr(self, '_extra', extra) _setattr(self, '_extra', extra)
if unique != undefined and not isinstance(unique, bool): if unique != undefined and not isinstance(unique, bool):
@ -126,9 +126,14 @@ class Option(BaseOption):
def test_multi_value(value): def test_multi_value(value):
if isinstance(value, Calculation): if isinstance(value, Calculation):
return return
option_bag = OptionBag()
option_bag.set_option(self,
undefined,
None,
undefined)
try: try:
self._validate(value, self._validate(value,
undefined) option_bag)
except ValueError as err: except ValueError as err:
str_err = str(err) str_err = str(err)
if not str_err: if not str_err:
@ -168,9 +173,6 @@ class Option(BaseOption):
default = tuple(default) default = tuple(default)
_setattr(self, '_default', default) _setattr(self, '_default', default)
self._impl_set_callback(callback,
callback_params)
def value_dependencies(self, def value_dependencies(self,
value: Any) -> Any: value: Any) -> Any:
if isinstance(value, list): if isinstance(value, list):
@ -250,16 +252,6 @@ class Option(BaseOption):
#__________________________________________________________________________ #__________________________________________________________________________
# validator # validator
def impl_get_validator(self) -> Tuple[Callable, Params]:
val = getattr(self, '_val_call', (None,))[0]
if val is None:
ret_val = (None, None)
elif len(val) == 1:
ret_val = (val[0], None)
else:
ret_val = val
return ret_val
def impl_validate(self, def impl_validate(self,
value: Any, value: Any,
option_bag: OptionBag, option_bag: OptionBag,
@ -272,13 +264,9 @@ class Option(BaseOption):
if check_error and config_bag is not undefined and \ if check_error and config_bag is not undefined and \
not 'validator' in config_bag.properties: not 'validator' in config_bag.properties:
# just to check propertieserror
self.valid_consistency(option_bag,
value,
check_error,
is_warnings_only)
return return
def _is_not_unique(value): def _is_not_unique(value):
# if set(value) has not same length than value # if set(value) has not same length than value
if check_error and self.impl_is_unique() and \ if check_error and self.impl_is_unique() and \
@ -291,26 +279,33 @@ class Option(BaseOption):
def calculation_validator(val, def calculation_validator(val,
_index): _index):
validator, validator_params = self.impl_get_validator() for validator in getattr(self, '_validators', []):
if validator is not None: calc_is_warnings_only = hasattr(validator, 'warnings_only') and validator.warnings_only
#inject value in calculation if ((check_error and not calc_is_warnings_only) or
if validator_params is None: (not check_error and calc_is_warnings_only)):
args = [] try:
kwargs = None kwargs = {'allow_raises': True}
if _index is not None and option_bag.index == _index:
soption_bag = option_bag
else: else:
args = list(validator_params.args) soption_bag = option_bag.copy()
kwargs = validator_params.kwargs soption_bag.index = _index
args.insert(0, ParamValue(val)) kwargs['orig_value'] = value
validator_params_ = Params(tuple(args), kwargs)
# Raise ValueError if not valid validator.execute(soption_bag,
carry_out_calculation(option_bag.ori_option, leadership_must_have_index=True,
callback=validator, **kwargs)
callback_params=validator_params_, except ValueError as err:
index=_index, if calc_is_warnings_only:
config_bag=option_bag.config_bag, warnings.warn_explicit(ValueWarning(val,
fromconsistency=option_bag.fromconsistency, self._display_name,
orig_value=value, self,
is_validator=True) '{0}'.format(err),
_index),
ValueWarning,
self.__class__.__name__, 0)
else:
raise err
def do_validation(_value, def do_validation(_value,
_index): _index):
@ -328,8 +323,6 @@ class Option(BaseOption):
if ((check_error and not is_warnings_only) or if ((check_error and not is_warnings_only) or
(not check_error and is_warnings_only)): (not check_error and is_warnings_only)):
try: try:
calculation_validator(_value,
_index)
self._second_level_validation(_value, self._second_level_validation(_value,
is_warnings_only) is_warnings_only)
except ValueError as err: except ValueError as err:
@ -343,6 +336,8 @@ class Option(BaseOption):
self.__class__.__name__, 0) self.__class__.__name__, 0)
else: else:
raise err raise err
calculation_validator(_value,
_index)
try: try:
val = value val = value
err_index = force_index err_index = force_index
@ -379,12 +374,6 @@ class Option(BaseOption):
for err_index, val in enumerate(value): for err_index, val in enumerate(value):
do_validation(val, do_validation(val,
err_index) err_index)
if (not is_warnings_only or not check_error) and not isinstance(value, Calculation):
self.valid_consistency(option_bag,
value,
check_error,
is_warnings_only)
except ValueError as err: except ValueError as err:
if config_bag is undefined or \ if config_bag is undefined or \
'demoting_error_warning' not in config_bag.properties: 'demoting_error_warning' not in config_bag.properties:
@ -419,11 +408,6 @@ class Option(BaseOption):
warnings_only: bool) -> None: warnings_only: bool) -> None:
pass pass
#__________________________________________________________________________
# leadership
# def impl_is_leadership(self):
# return self.impl_get_leadership() is not None
def impl_is_leader(self): def impl_is_leader(self):
leadership = self.impl_get_leadership() leadership = self.impl_get_leadership()
if leadership is None: if leadership is None:
@ -442,327 +426,6 @@ class Option(BaseOption):
return leadership return leadership
return leadership() return leadership()
#____________________________________________________________
# consistencies
def impl_add_consistency(self,
func: str,
*other_opts,
**params) -> None:
"""Add consistency means that value will be validate with other_opts
option's values.
:param func: function's name
:type func: `str`
:param other_opts: options used to validate value
:type other_opts: `list` of `tiramisu.option.Option`
:param params: extra params (warnings_only and transitive are allowed)
"""
if self.impl_is_readonly():
raise AttributeError(_("'{0}' ({1}) cannot add consistency, option is"
" read-only").format(
self.__class__.__name__,
self.impl_getname()))
self._valid_consistencies(other_opts,
func=func)
func = '_cons_{0}'.format(func)
if func not in dir(self):
raise ConfigError(_('consistency {0} not available for this option').format(func))
options = [weakref.ref(self)]
for option in other_opts:
options.append(weakref.ref(option))
all_cons_opts = tuple(options)
unknown_params = set(params.keys()) - set(['warnings_only', 'transitive'])
if unknown_params != set():
raise ValueError(_('unknown parameter {0} in consistency').format(unknown_params))
self._add_consistency(func,
all_cons_opts,
params)
#validate default value when add consistency
option_bag = OptionBag()
option_bag.set_option(self,
undefined,
None,
undefined)
default = self.impl_getdefault()
if isinstance(default, tuple):
default = list(default)
self.impl_validate(default,
option_bag)
self.impl_validate(default,
option_bag,
check_error=False)
if func != '_cons_not_equal':
#consistency could generate warnings or errors
self._has_dependency = True
for wopt in all_cons_opts:
opt = wopt()
if func in ALLOWED_CONST_LIST:
if getattr(opt, '_unique', undefined) == undefined:
opt._unique = True
if opt != self:
self._add_dependency(opt)
opt._add_dependency(self)
def _add_consistency(self,
func: str,
all_cons_opts: List[BaseOption],
params: Dict) -> None:
cons = (-1, func, all_cons_opts, params)
consistencies = getattr(self, '_consistencies', None)
if consistencies is None:
self._consistencies = [cons]
else:
consistencies.append(cons)
def get_consistencies(self):
return getattr(self, '_consistencies', STATIC_TUPLE)
def has_consistencies(self, context) -> bool:
descr = context.cfgimpl_get_description()
if getattr(descr, '_cache_consistencies', None) is None:
return False
return self in descr._cache_consistencies
def valid_consistency(self,
option_bag: OptionBag,
value: Any,
check_error: bool,
option_warnings_only: bool) -> None:
if option_bag.config_bag is not undefined:
descr = option_bag.config_bag.context.cfgimpl_get_description()
# no consistency found at all
if getattr(descr, '_cache_consistencies', None) is None:
return
# get consistencies for this option
consistencies = descr._cache_consistencies.get(option_bag.option)
else:
# is no context, get consistencies in option
consistencies = option_bag.option.get_consistencies()
if consistencies:
if option_bag.config_bag is undefined:
coption_bag = option_bag.copy()
else:
cconfig_bag = option_bag.config_bag.copy()
cconfig_bag.remove_warnings()
cconfig_bag.set_permissive()
coption_bag = option_bag.copy()
coption_bag.config_bag = cconfig_bag
if not option_bag.fromconsistency:
fromconsistency_is_empty = True
option_bag.fromconsistency = [cons_id for cons_id, f, a, p in consistencies]
else:
fromconsistency_is_empty = False
for cons_id, func, all_cons_opts, params in consistencies:
if not fromconsistency_is_empty and cons_id in option_bag.fromconsistency:
continue
warnings_only = option_warnings_only or params.get('warnings_only', False)
if (warnings_only and not check_error) or (not warnings_only and check_error):
transitive = params.get('transitive', True)
#all_cons_opts[0] is the option where func is set
if option_bag.ori_option.impl_is_dynsymlinkoption():
opts = []
for opt in all_cons_opts:
opts.append(opt().to_dynoption(option_bag.ori_option.rootpath,
option_bag.ori_option.suffix))
wopt = opts[0]
else:
opts = all_cons_opts
wopt = opts[0]()
wopt.launch_consistency(self,
func,
cons_id,
coption_bag,
value,
opts,
warnings_only,
transitive)
if fromconsistency_is_empty:
option_bag.fromconsistency = []
def _valid_consistencies(self,
other_opts: List[BaseOption],
init: bool=True,
func: Optional[str]=None) -> None:
if self.issubdyn():
dynod = self.getsubdyn()
else:
dynod = None
if self.impl_is_submulti():
raise ConfigError(_('cannot add consistency with submulti option'))
is_multi = self.impl_is_multi()
for opt in other_opts:
if isinstance(opt, weakref.ReferenceType):
opt = opt()
assert not opt.impl_is_submulti(), _('cannot add consistency with submulti option')
assert isinstance(opt, Option), _('consistency must be set with an option, not {}').format(opt)
if opt.issubdyn():
if dynod is None:
raise ConfigError(_('almost one option in consistency is '
'in a dynoptiondescription but not all'))
subod = opt.getsubdyn()
if dynod != subod:
raise ConfigError(_('option in consistency must be in same'
' dynoptiondescription'))
dynod = subod
elif dynod is not None:
raise ConfigError(_('almost one option in consistency is in a '
'dynoptiondescription but not all'))
if self is opt:
raise ConfigError(_('cannot add consistency with itself'))
if is_multi != opt.impl_is_multi():
raise ConfigError(_('every options in consistency must be '
'multi or none'))
# FIXME
if init and func != 'not_equal':
opt._has_dependency = True
def launch_consistency(self,
current_opt: BaseOption,
func: Callable,
cons_id: int,
option_bag: OptionBag,
value: Any,
opts: List[BaseOption],
warnings_only: bool,
transitive: bool) -> None:
"""Launch consistency now
"""
all_cons_vals = []
all_cons_opts = []
length = None
for opt in opts:
if isinstance(opt, weakref.ReferenceType):
opt = opt()
try:
opt_value = self.get_consistency_value(option_bag,
opt,
cons_id,
value,
func)
except PropertiesOptionError as err:
if transitive:
err.set_orig_opt(option_bag.option)
raise err
else:
if opt.impl_is_multi() and option_bag.index is None and \
func not in ALLOWED_CONST_LIST:
len_value = len(opt_value)
if length is not None and length != len_value:
if option_bag.config_bag is undefined:
return
raise ValueError(_('unexpected length of "{}" in constency "{}", '
'should be "{}"').format(len(opt_value),
opt.impl_get_display_name(),
length)) # pragma: no cover
length = len_value
if isinstance(opt_value, list) and func in ALLOWED_CONST_LIST:
for value_ in opt_value:
all_cons_vals.append(value_)
all_cons_opts.append(opt)
else:
all_cons_vals.append(opt_value)
all_cons_opts.append(opt)
if option_bag.config_bag is not undefined and \
not 'validator' in option_bag.config_bag.properties:
return
all_values = []
if length is None:
all_values = [all_cons_vals]
elif length:
all_values = zip(*all_cons_vals)
try:
context = option_bag.config_bag if option_bag.config_bag is undefined else option_bag.config_bag.context
for values in all_values:
getattr(self, func)(current_opt,
all_cons_opts,
values,
warnings_only,
context)
except ValueError as err:
if warnings_only:
warnings.warn_explicit(ValueWarning(value,
self._display_name,
current_opt,
"{}".format(err),
option_bag.index),
ValueWarning,
self.__class__.__name__, 0)
else:
raise err
def get_consistency_value(self,
option_bag: OptionBag,
current_option: BaseOption,
cons_id: int,
value: Any,
func: str) -> Any:
if option_bag.ori_option == current_option:
# orig_option is current option
# we have already value, so use it
return value
if option_bag.config_bag is undefined:
#if no context get default value
return current_option.impl_getdefault()
if func in ALLOWED_CONST_LIST:
index = None
index_ = None
elif current_option.impl_is_leader():
index = option_bag.index
index_ = None
else:
index = option_bag.index
index_ = index
#otherwise calculate value
path = current_option.impl_getpath()
coption_bag = OptionBag()
coption_bag.set_option(current_option,
path,
index_,
option_bag.config_bag)
fromconsistency = option_bag.fromconsistency.copy()
fromconsistency.append(cons_id)
coption_bag.fromconsistency = fromconsistency
current_value = option_bag.config_bag.context.getattr(path,
coption_bag)
if index_ is None and index is not None:
#if self is a follower and current_option is a leader and func not in ALLOWED_CONST_LIST
#return only the value of the leader for isolate follower
current_value = current_value[index]
return current_value
def _cons_not_equal(self,
current_opt: BaseOption,
opts: List[BaseOption],
vals: List[Any],
warnings_only: bool,
context) -> None:
equal = []
is_current = False
for idx_inf, val_inf in enumerate(vals):
for idx_sup, val_sup in enumerate(vals[idx_inf + 1:]):
if val_inf == val_sup is not None:
for opt_ in [opts[idx_inf], opts[idx_inf + idx_sup + 1]]:
if opt_ == current_opt:
is_current = True
elif opt_ not in equal:
equal.append(opt_)
if equal:
if is_current:
if warnings_only:
msg = _('should be different from the value of {}')
else:
msg = _('must be different from the value of {}')
else:
if warnings_only:
msg = _('value for {} should be different')
else:
msg = _('value for {} must be different')
equal_name = []
for opt in equal:
equal_name.append(opt.impl_get_display_name())
raise ValueError(msg.format(display_list(list(equal_name), add_quote=True)))
def to_dynoption(self, def to_dynoption(self,
rootpath: str, rootpath: str,
suffix: str) -> SynDynOption: suffix: str) -> SynDynOption:

View File

@ -25,14 +25,12 @@ from typing import Optional, Iterator, Union, List
from ..i18n import _ from ..i18n import _
from ..setting import ConfigBag, OptionBag, groups, undefined, owners, Undefined from ..setting import ConfigBag, OptionBag, groups, undefined, owners, Undefined
from .baseoption import BaseOption from .baseoption import BaseOption
from .option import ALLOWED_CONST_LIST
from .syndynoptiondescription import SynDynOptionDescription, SynDynLeadership from .syndynoptiondescription import SynDynOptionDescription, SynDynLeadership
from ..error import ConfigError, ConflictError from ..error import ConfigError, ConflictError
class CacheOptionDescription(BaseOption): class CacheOptionDescription(BaseOption):
__slots__ = ('_cache_consistencies', __slots__ = ('_cache_force_store_values',)
'_cache_force_store_values')
def impl_already_build_caches(self) -> bool: def impl_already_build_caches(self) -> bool:
return self.impl_is_readonly() return self.impl_is_readonly()
@ -101,60 +99,10 @@ class CacheOptionDescription(BaseOption):
'"force_metaconfig_on_freeze" ' '"force_metaconfig_on_freeze" '
'property without "frozen"' 'property without "frozen"'
'').format(option.impl_get_display_name())) '').format(option.impl_get_display_name()))
for cons_id, func, all_cons_opts, params in option.get_consistencies():
option._valid_consistencies(all_cons_opts[1:], init=False)
if func not in ALLOWED_CONST_LIST and is_multi:
if __debug__ and not option.impl_get_leadership():
raise ConfigError(_('malformed consistency option "{0}" '
'must be in same leadership').format(
option.impl_getname()))
leadership = option.impl_get_leadership()
for weak_opt in all_cons_opts:
opt = weak_opt()
if __debug__ and func not in ALLOWED_CONST_LIST and is_multi:
if not opt.impl_get_leadership():
raise ConfigError(_('malformed consistency option "{0}" '
'must not be a multi for "{1}"').format(
option.impl_getname(), opt.impl_getname()))
elif leadership != opt.impl_get_leadership():
raise ConfigError(_('malformed consistency option "{0}" '
'must be in same leadership as "{1}"').format(
option.impl_getname(), opt.impl_getname()))
_consistencies.setdefault(weak_opt,
[]).append((_consistencies_id,
func,
all_cons_opts,
params))
_consistencies_id += 1
# if context is set to callback, must be reset each time a value change # if context is set to callback, must be reset each time a value change
if hasattr(option, '_has_calc_context'): if hasattr(option, '_has_calc_context'):
self._add_dependency(option) self._add_dependency(option)
if __debug__:
is_follower = None
if is_multi:
all_requires = option.impl_getrequires()
for requires in all_requires:
for require in requires:
#if option in require is a multi:
# * option in require must be a leader or a follower
# * current option must be a follower (and only a follower)
# * option in require and current option must be in same leadership
for require_opt, values in require[0]:
if not isinstance(require_opt, tuple) and require_opt.impl_is_multi():
if is_follower is None:
is_follower = option.impl_is_follower()
if is_follower:
leadership = option.impl_get_leadership()
if is_follower and require_opt.impl_get_leadership():
if leadership != require_opt.impl_get_leadership():
raise ValueError(_('malformed requirements option "{0}" '
'must be in same leadership for "{1}"').format(
require_opt.impl_getname(), option.impl_getname()))
else:
raise ValueError(_('malformed requirements option "{0}" '
'must not be a multi for "{1}"').format(
require_opt.impl_getname(), option.impl_getname()))
if option.impl_is_readonly(): if option.impl_is_readonly():
raise ConflictError(_('duplicate option: {0}').format(option)) raise ConflictError(_('duplicate option: {0}').format(option))
if not self.impl_is_readonly() and display_name: if not self.impl_is_readonly() and display_name:
@ -162,15 +110,6 @@ class CacheOptionDescription(BaseOption):
option._path = subpath option._path = subpath
option._set_readonly() option._set_readonly()
if init: if init:
if _consistencies != {}:
self._cache_consistencies = {}
for weak_opt, cons in _consistencies.items():
opt = weak_opt()
if __debug__ and opt not in cache_option:
raise ConfigError(_('consistency with option {0} '
'which is not in Config').format(
opt.impl_getname()))
self._cache_consistencies[opt] = tuple(cons)
self._cache_force_store_values = force_store_values self._cache_force_store_values = force_store_values
self._path = self._name self._path = self._name
self._set_readonly() self._set_readonly()
@ -275,7 +214,6 @@ class OptionDescription(OptionDescriptionWalk):
name: str, name: str,
doc: str, doc: str,
children: List[BaseOption], children: List[BaseOption],
requires=None,
properties=None) -> None: properties=None) -> None:
""" """
:param children: a list of options (including optiondescriptions) :param children: a list of options (including optiondescriptions)
@ -285,7 +223,6 @@ class OptionDescription(OptionDescriptionWalk):
'must be a list').format(name) 'must be a list').format(name)
super().__init__(name, super().__init__(name,
doc=doc, doc=doc,
requires=requires,
properties=properties) properties=properties)
child_names = [] child_names = []
if __debug__: if __debug__:

View File

@ -48,12 +48,8 @@ class PortOption(StrOption):
doc, doc,
default=None, default=None,
default_multi=None, default_multi=None,
requires=None,
multi=False, multi=False,
callback=None, validators=None,
callback_params=None,
validator=None,
validator_params=None,
properties=None, properties=None,
allow_range=False, allow_range=False,
allow_zero=False, allow_zero=False,
@ -89,12 +85,8 @@ class PortOption(StrOption):
doc, doc,
default=default, default=default,
default_multi=default_multi, default_multi=default_multi,
callback=callback,
callback_params=callback_params,
requires=requires,
multi=multi, multi=multi,
validator=validator, validators=validators,
validator_params=validator_params,
properties=properties, properties=properties,
warnings_only=warnings_only, warnings_only=warnings_only,
extra=extra) extra=extra)

View File

@ -58,6 +58,3 @@ class SymLinkOption(BaseOption):
def impl_getopt(self) -> BaseOption: def impl_getopt(self) -> BaseOption:
return self._opt return self._opt
def get_consistencies(self) -> tuple:
return ()

View File

@ -64,24 +64,11 @@ class SynDynOption:
def impl_getpath(self) -> str: def impl_getpath(self) -> str:
return self.rootpath + '.' + self.impl_getname() return self.rootpath + '.' + self.impl_getname()
def impl_validate(self,
value: Any,
option_bag: OptionBag,
check_error: bool=True) -> None:
soption_bag = OptionBag()
soption_bag.set_option(self.opt,
self.impl_getpath(),
option_bag.index,
option_bag.config_bag)
soption_bag.ori_option = option_bag.option
soption_bag.fromconsistency = option_bag.fromconsistency.copy()
self.opt.impl_validate(value,
soption_bag,
check_error=check_error)
def impl_is_dynsymlinkoption(self) -> bool: def impl_is_dynsymlinkoption(self) -> bool:
return True return True
def impl_get_leadership(self): def impl_get_leadership(self):
return self.opt.impl_get_leadership().to_dynoption(self.rootpath, leadership = self.opt.impl_get_leadership()
if leadership:
return leadership.to_dynoption(self.rootpath,
self.suffix) self.suffix)

View File

@ -15,8 +15,7 @@
# You should have received a copy of the GNU Lesser General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# ____________________________________________________________ # ____________________________________________________________
from .error import (RequirementError, PropertiesOptionError, from .error import PropertiesOptionError, ConstError, ConfigError, LeadershipError, display_list
ConstError, ConfigError, display_list)
from .i18n import _ from .i18n import _
@ -109,7 +108,12 @@ FORBIDDEN_SET_PROPERTIES = frozenset(['force_store_value'])
FORBIDDEN_SET_PERMISSIVES = frozenset(['force_default_on_freeze', FORBIDDEN_SET_PERMISSIVES = frozenset(['force_default_on_freeze',
'force_metaconfig_on_freeze', 'force_metaconfig_on_freeze',
'force_store_value']) 'force_store_value'])
ALLOWED_LEADER_PROPERTIES = frozenset(['empty',
'force_store_value',
'mandatory',
'force_default_on_freeze',
'force_metaconfig_on_freeze',
'frozen'])
static_set = frozenset() static_set = frozenset()
@ -123,12 +127,10 @@ class OptionBag:
'properties', # properties of current option 'properties', # properties of current option
'properties_setted', 'properties_setted',
'apply_requires', # apply requires or not for this option 'apply_requires', # apply requires or not for this option
'fromconsistency' # history for consistency
) )
def __init__(self): def __init__(self):
self.option = None self.option = None
self.fromconsistency = []
def set_option(self, def set_option(self,
option, option,
@ -235,9 +237,6 @@ class ConfigBag:
return return
raise KeyError('unknown key {} for ConfigBag'.format(key)) # pragma: no cover raise KeyError('unknown key {} for ConfigBag'.format(key)) # pragma: no cover
# def __setattr__(self, key, value):
# super().__setattr__(key, value)
def copy(self): def copy(self):
kwargs = {} kwargs = {}
for key in self.__slots__: for key in self.__slots__:
@ -447,24 +446,19 @@ class Settings(object):
if isinstance(prop, str): if isinstance(prop, str):
props.add(prop) props.add(prop)
elif apply_requires: elif apply_requires:
new_props = prop.execute(option_bag, new_prop = prop.execute(option_bag,
leadership_must_have_index=True) leadership_must_have_index=True)
if not new_props: if not new_prop:
continue continue
elif not isinstance(new_props, str): elif not isinstance(new_prop, str):
raise ValueError(_('invalid property type {} for {} with {} function').format(type(new_props), raise ValueError(_('invalid property type {} for {} with {} function').format(type(new_prop),
option_bag.option.impl_getname(), option_bag.option.impl_getname(),
prop.function.__name__)) prop.function.__name__))
props.add(new_props) if not option.impl_is_optiondescription() and option.impl_is_leader() and new_prop not in ALLOWED_LEADER_PROPERTIES:
# else: raise LeadershipError(_('leader cannot have "{}" property').format(new_prop))
# props.update(new_props) props.add(new_prop)
if apply_requires:
props |= self.apply_requires(option_bag,
False,
search_properties=search_properties)
props -= self.getpermissives(option, props -= self.getpermissives(option,
path) path)
#if apply_requires and config_bag.properties == config_bag.true_properties:
if apply_requires and not config_bag.is_unrestraint: if apply_requires and not config_bag.is_unrestraint:
cache.setcache(path, cache.setcache(path,
index, index,
@ -508,195 +502,6 @@ class Settings(object):
path = opt.impl_getpath() path = opt.impl_getpath()
return self._pp_.getpermissives(path) return self._pp_.getpermissives(path)
def apply_requires(self,
option_bag,
readable,
search_properties=None):
"""carries out the jit (just in time) requirements between options
a requirement is a tuple of this form that comes from the option's
requirements validation::
(option, expected, action, inverse, transitive, same_action)
let's have a look at all the tuple's items:
- **option** is the target option's
- **expected** is the target option's value that is going to trigger
an action
- **action** is the (property) action to be accomplished if the target
option happens to have the expected value
- if **inverse** is `True` and if the target option's value does not
apply, then the property action must be removed from the option's
properties list (wich means that the property is inverted)
- **transitive**: but what happens if the target option cannot be
accessed ? We don't kown the target option's value. Actually if some
property in the target option is not present in the permissive, the
target option's value cannot be accessed. In this case, the
**action** have to be applied to the option. (the **action** property
is then added to the option).
- **same_action**: actually, if **same_action** is `True`, the
transitivity is not accomplished. The transitivity is accomplished
only if the target option **has the same property** that the demanded
action. If the target option's value is not accessible because of
another reason, because of a property of another type, then an
exception :exc:`~error.RequirementError` is raised.
And at last, if no target option matches the expected values, the
action will not add to the option's properties list.
:param opt: the option on wich the requirement occurs
:type opt: `option.Option()`
:param path: the option's path in the config
:type path: str
"""
current_requires = option_bag.option.impl_getrequires()
# filters the callbacks
if readable:
calc_properties = {}
else:
calc_properties = set()
if not current_requires:
return calc_properties
context = option_bag.config_bag.context
all_properties = None
for requires in current_requires:
for require in requires:
exps, action, inverse, transitive, same_action, operator = require
#if search_properties and action not in search_properties:
# continue
breaked = False
for option, expected in exps:
if not isinstance(option, tuple):
if option.issubdyn():
option = option.to_dynoption(option_bag.option.rootpath,
option_bag.option.impl_getsuffix())
reqpath = option.impl_getpath()
if __debug__ and reqpath.startswith(option_bag.path + '.'):
# FIXME too later!
raise RequirementError(_("malformed requirements "
"imbrication detected for option:"
" '{0}' with requirement on: "
"'{1}'").format(option_bag.path, reqpath))
idx = None
is_indexed = False
if option.impl_is_follower():
idx = option_bag.index
if idx is None:
continue
elif option.impl_is_leader() and option_bag.index is None:
continue
elif option.impl_is_multi() and option_bag.index is not None:
is_indexed = True
config_bag = option_bag.config_bag.copy()
soption_bag = OptionBag()
soption_bag.set_option(option,
reqpath,
idx,
config_bag)
if option_bag.option == option:
soption_bag.config_bag.unrestraint()
soption_bag.config_bag.remove_validation()
soption_bag.apply_requires = False
else:
soption_bag.config_bag.properties = soption_bag.config_bag.true_properties
soption_bag.config_bag.set_permissive()
else:
if not option_bag.option.impl_is_optiondescription() and option_bag.option.impl_is_follower():
idx = option_bag.index
if idx is None:
continue
is_indexed = False
try:
if not isinstance(option, tuple):
value = context.getattr(reqpath,
soption_bag)
else:
value = context.cfgimpl_get_values().carry_out_calculation(option_bag,
option[0],
option[1])
except (PropertiesOptionError, ConfigError) as err:
if isinstance(err, ConfigError):
if not isinstance(err.ori_err, PropertiesOptionError):
raise err
err = err.ori_err
properties = err.proptype
# if not transitive, properties must be verify in current requires
# otherwise if same_action, property must be in properties
# otherwise add property in returned properties (if operator is 'and')
if not transitive:
if all_properties is None:
all_properties = []
for requires_ in current_requires:
for require_ in requires_:
all_properties.append(require_[1])
if not set(properties) - set(all_properties):
continue
if same_action and action not in properties:
if len(properties) == 1:
prop_msg = _('property')
else:
prop_msg = _('properties')
err = RequirementError(_('cannot access to option "{0}" because '
'required option "{1}" has {2} {3}'
'').format(option_bag.option.impl_get_display_name(),
option.impl_get_display_name(),
prop_msg,
display_list(list(properties), add_quote=True)))
err.proptype = properties
raise err
# transitive action, add action
if operator != 'and':
if readable:
for msg in self.apply_requires(err._option_bag,
True).values():
calc_properties.setdefault(action, []).extend(msg)
else:
calc_properties.add(action)
breaked = True
break
else:
if is_indexed:
value = value[option_bag.index]
if (not inverse and value in expected or
inverse and value not in expected):
if operator != 'and':
if readable:
display_value = display_list(expected, 'or', add_quote=True)
if isinstance(option, tuple):
if not inverse:
msg = _('the calculated value is {0}').format(display_value)
else:
msg = _('the calculated value is not {0}').format(display_value)
else:
name = option.impl_get_display_name()
if not inverse:
msg = _('the value of "{0}" is {1}').format(name, display_value)
else:
msg = _('the value of "{0}" is not {1}').format(name, display_value)
calc_properties.setdefault(action, []).append(msg)
else:
calc_properties.add(action)
breaked = True
break
elif operator == 'and':
break
else:
if operator == 'and':
calc_properties.add(action)
continue
if breaked:
break
return calc_properties
#____________________________________________________________ #____________________________________________________________
# set methods # set methods
def set_context_properties(self, def set_context_properties(self,
@ -715,21 +520,19 @@ class Settings(object):
(never save properties if same has option properties) (never save properties if same has option properties)
""" """
opt = option_bag.option opt = option_bag.option
if opt.impl_getrequires() is not None:
not_allowed_props = properties & \
getattr(opt, '_calc_properties', static_set)
if not_allowed_props:
raise ValueError(_('cannot set property {} for option "{}" this property is '
'calculated').format(display_list(list(not_allowed_props),
add_quote=True),
opt.impl_get_display_name()))
if opt.impl_is_symlinkoption(): if opt.impl_is_symlinkoption():
raise TypeError(_("can't assign property to the symlinkoption \"{}\"" raise TypeError(_("can't assign property to the symlinkoption \"{}\""
"").format(opt.impl_get_display_name())) "").format(opt.impl_get_display_name()))
if not opt.impl_is_optiondescription() and opt.impl_is_leader():
not_allowed_properties = properties - ALLOWED_LEADER_PROPERTIES
if not_allowed_properties:
if len(not_allowed_properties) == 1:
raise LeadershipError(_('leader cannot have "{}" property').format(list(not_allowed_properties)[0]))
else:
raise LeadershipError(_('leader cannot have {} properties').format(display_list(list(not_allowed_properties), add_quote=True)))
if ('force_default_on_freeze' in properties or 'force_metaconfig_on_freeze' in properties) and \ if ('force_default_on_freeze' in properties or 'force_metaconfig_on_freeze' in properties) and \
'frozen' not in properties and \ 'frozen' not in properties:
opt.impl_is_leader(): raise LeadershipError(_('a leader ({0}) cannot have '
raise ConfigError(_('a leader ({0}) cannot have '
'"force_default_on_freeze" or "force_metaconfig_on_freeze" property without "frozen"' '"force_default_on_freeze" or "force_metaconfig_on_freeze" property without "frozen"'
'').format(opt.impl_get_display_name())) '').format(opt.impl_get_display_name()))
self._p_.setproperties(path, self._p_.setproperties(path,

View File

@ -67,7 +67,7 @@ class Callbacks(object):
raise ValueError(_('context is not supported from now for {}').format(path)) raise ValueError(_('context is not supported from now for {}').format(path))
if isinstance(callback_param, ParamOption): if isinstance(callback_param, ParamOption):
has_option = True has_option = True
if callback.__name__ != 'tiramisu_copy' or 'expire' in childapi.option.properties(): if 'expire' in childapi.option.properties():
self.tiramisu_web.set_remotable(callback_param.option.impl_getpath(), form) self.tiramisu_web.set_remotable(callback_param.option.impl_getpath(), form)
if not has_option and form.get(path, {}).get('remote', False) == False: if not has_option and form.get(path, {}).get('remote', False) == False:
if 'expire' in childapi.option.properties(): if 'expire' in childapi.option.properties():
@ -79,14 +79,15 @@ class Callbacks(object):
form.setdefault(path, {})['clearable'] = True form.setdefault(path, {})['clearable'] = True
def manage_callbacks(self, form): def manage_callbacks(self, form):
for callback, callback_params, path, childapi, schema, force_store_value in self.callbacks: pass
if callback_params is not None: #for callback, callback_params, path, childapi, schema, force_store_value in self.callbacks:
for callback_param in chain(callback_params.args, callback_params.kwargs.values()): # if callback_params is not None:
if isinstance(callback_param, ParamOption) and callback.__name__ == 'tiramisu_copy': # for callback_param in chain(callback_params.args, callback_params.kwargs.values()):
opt_path = callback_param.option.impl_getpath() # if isinstance(callback_param, ParamOption) and callback.__name__ == 'tiramisu_copy':
if form.get(opt_path, {}).get('remote') is not True: # opt_path = callback_param.option.impl_getpath()
form.setdefault(opt_path, {}) # if form.get(opt_path, {}).get('remote') is not True:
form[opt_path].setdefault('copy', []).append(path) # form.setdefault(opt_path, {})
# form[opt_path].setdefault('copy', []).append(path)
def process(self, def process(self,
form): form):

View File

@ -17,7 +17,7 @@
# ____________________________________________________________ # ____________________________________________________________
import weakref import weakref
from typing import Optional, Any, Callable from typing import Optional, Any, Callable
from .error import ConfigError, PropertiesOptionError, RequirementError from .error import ConfigError, PropertiesOptionError
from .setting import owners, undefined, forbidden_owners, OptionBag, ConfigBag from .setting import owners, undefined, forbidden_owners, OptionBag, ConfigBag
from .autolib import Calculation, carry_out_calculation, Params from .autolib import Calculation, carry_out_calculation, Params
from .i18n import _ from .i18n import _
@ -78,7 +78,7 @@ class Values(object):
# store value in cache # store value in cache
properties = option_bag.config_bag.properties properties = option_bag.config_bag.properties
validator = 'validator' in properties and 'demoting_error_warning' not in properties validator = 'validator' in properties and 'demoting_error_warning' not in properties
if not option_bag.fromconsistency and (not is_cached or validator): if not is_cached or validator:
cache.setcache(option_bag.path, cache.setcache(option_bag.path,
option_bag.index, option_bag.index,
value, value,
@ -258,8 +258,7 @@ class Values(object):
callback=callback, callback=callback,
callback_params=callback_params, callback_params=callback_params,
index=option_bag.index, index=option_bag.index,
config_bag=option_bag.config_bag, config_bag=option_bag.config_bag)
fromconsistency=option_bag.fromconsistency)
def isempty(self, def isempty(self,
opt, opt,
value, value,
@ -289,22 +288,6 @@ class Values(object):
context = option_bag.config_bag.context context = option_bag.config_bag.context
owner = self.get_context_owner() owner = self.get_context_owner()
if 'validator' in option_bag.config_bag.properties: if 'validator' in option_bag.config_bag.properties:
if option_bag.index is not None or option_bag.option.has_consistencies(context):
# set value to a fake config when option has dependency
# validation will be complet in this case (consistency, ...)
tested_context = context._gen_fake_values()
config_bag = option_bag.config_bag.copy()
config_bag.unrestraint()
config_bag.context = tested_context
soption_bag = option_bag.copy()
soption_bag.config_bag = config_bag
tested_context.cfgimpl_get_values().setvalue(value,
soption_bag,
True)
soption_bag.config_bag.properties = option_bag.config_bag.properties
tested_context.getattr(soption_bag.path,
soption_bag)
else:
self.setvalue_validation(value, self.setvalue_validation(value,
option_bag) option_bag)
@ -622,7 +605,7 @@ class Values(object):
except PropertiesOptionError as err: except PropertiesOptionError as err:
if err.proptype == ['mandatory']: if err.proptype == ['mandatory']:
yield path yield path
except (RequirementError, ConfigError): except ConfigError:
pass pass
def mandatory_warnings(self, def mandatory_warnings(self,