From 3ff0701ef24ed689bdb399e89d14d66b081eb89d Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Wed, 3 Jan 2018 21:07:51 +0100 Subject: [PATCH] metaconfig --- test/new_api/test_metaconfig.py | 722 ++++++++++++++++++++++++++++++++ tiramisu/__init__.py | 3 +- tiramisu/api.py | 59 ++- tiramisu/config.py | 183 ++++---- tiramisu/setting.py | 8 +- tiramisu/value.py | 19 +- 6 files changed, 893 insertions(+), 101 deletions(-) create mode 100644 test/new_api/test_metaconfig.py diff --git a/test/new_api/test_metaconfig.py b/test/new_api/test_metaconfig.py new file mode 100644 index 0000000..8b72935 --- /dev/null +++ b/test/new_api/test_metaconfig.py @@ -0,0 +1,722 @@ +from .autopath import do_autopath +do_autopath() + +from py.test import raises + +from tiramisu.setting import groups, owners +from tiramisu import IntOption, StrOption, NetworkOption, NetmaskOption, \ + OptionDescription, MasterSlaves, Config, GroupConfig, MetaConfig, \ + getapi +from tiramisu.error import ConfigError, ConflictError, PropertiesOptionError + +owners.addowner('meta1') +owners.addowner('meta2') + + +def return_value(value=None): + return value + + +def raise_exception(): + raise Exception('test') + + +def make_description(): + i1 = IntOption('i1', '') + i2 = IntOption('i2', '', default=1) + i3 = IntOption('i3', '') + i4 = IntOption('i4', '', default=2) + i5 = IntOption('i5', '', default=[2], multi=True) + i6 = IntOption('i6', '', properties=('disabled',)) + od1 = OptionDescription('od1', '', [i1, i2, i3, i4, i5, i6]) + od2 = OptionDescription('od2', '', [od1]) + return od2 + + +def make_metaconfig(double=False): + od2 = make_description() + conf1 = Config(od2, session_id='conf1') + conf2 = Config(od2, session_id='conf2') + meta = MetaConfig([conf1, conf2], session_id='meta') + api = getapi(meta) + if double: + api.owner.set(owners.meta2) + meta = MetaConfig([meta]) + api = getapi(meta) + api.property.read_write() + api.owner.set(owners.meta1) + return api + + +#FIXME ne pas mettre 2 meta dans une config +#FIXME ne pas mettre 2 OD differents dans un meta +def test_none(): + api = make_metaconfig() + assert api.option('od1.i3').value.get() is api.config('conf1').option('od1.i3').value.get() is api.config('conf2').option('od1.i3').value.get() is None + assert api.option('od1.i3').owner.get() is api.config('conf1').option('od1.i3').owner.get() is api.config('conf2').option('od1.i3').owner.get() is owners.default + # + api.option('od1.i3').value.set(3) + assert api.option('od1.i3').value.get() == api.config('conf1').option('od1.i3').value.get() == api.config('conf2').option('od1.i3').value.get() == 3 + assert api.option('od1.i3').owner.get() is api.config('conf1').option('od1.i3').owner.get() is api.config('conf2').option('od1.i3').owner.get() is owners.meta1 + # + api.config('conf1').option('od1.i3').value.set(2) + assert api.option('od1.i3').value.get() == api.config('conf2').option('od1.i3').value.get() == 3 + assert api.config('conf1').option('od1.i3').value.get() == 2 + assert api.option('od1.i3').owner.get() is api.config('conf2').option('od1.i3').owner.get() is owners.meta1 + assert api.config('conf1').option('od1.i3').owner.get() is owners.user + # + api.option('od1.i3').value.set(4) + assert api.option('od1.i3').value.get() == api.config('conf2').option('od1.i3').value.get() == 4 + assert api.config('conf1').option('od1.i3').value.get() == 2 + assert api.option('od1.i3').owner.get() is api.config('conf2').option('od1.i3').owner.get() is owners.meta1 + assert api.config('conf1').option('od1.i3').owner.get() is owners.user + # + api.option('od1.i3').value.reset() + assert api.option('od1.i3').value.get() is api.config('conf2').option('od1.i3').value.get() is None + assert api.config('conf1').option('od1.i3').value.get() == 2 + assert api.option('od1.i3').owner.get() is api.config('conf2').option('od1.i3').owner.get() is owners.default + assert api.config('conf1').option('od1.i3').owner.get() is owners.user + # + api.config('conf1').option('od1.i3').value.reset() + assert api.option('od1.i3').value.get() is api.config('conf1').option('od1.i3').value.get() is api.config('conf2').option('od1.i3').value.get() is None + assert api.option('od1.i3').owner.get() is api.config('conf1').option('od1.i3').owner.get() is api.config('conf2').option('od1.i3').owner.get() is owners.default + #del(conf1) + #del(conf2) + + +def test_default(): + api = make_metaconfig() + assert api.option('od1.i2').value.get() == api.config('conf1').option('od1.i2').value.get() == api.config('conf2').option('od1.i2').value.get() == 1 + assert api.option('od1.i2').owner.get() is api.config('conf1').option('od1.i2').owner.get() is api.config('conf2').option('od1.i2').owner.get() is owners.default + # + api.option('od1.i2').value.set(3) + assert api.option('od1.i2').value.get() == api.config('conf1').option('od1.i2').value.get() == api.config('conf2').option('od1.i2').value.get() == 3 + assert api.option('od1.i2').owner.get() is api.config('conf1').option('od1.i2').owner.get() is api.config('conf2').option('od1.i2').owner.get() is owners.meta1 + # + api.config('conf1').option('od1.i2').value.set(2) + assert api.option('od1.i2').value.get() == api.config('conf2').option('od1.i2').value.get() == 3 + assert api.config('conf1').option('od1.i2').value.get() == 2 + assert api.option('od1.i2').owner.get() is api.config('conf2').option('od1.i2').owner.get() is owners.meta1 + assert api.config('conf1').option('od1.i2').owner.get() is owners.user + # + api.option('od1.i2').value.set(4) + assert api.option('od1.i2').value.get() == api.config('conf2').option('od1.i2').value.get() == 4 + assert api.config('conf1').option('od1.i2').value.get() == 2 + assert api.option('od1.i2').owner.get() is api.config('conf2').option('od1.i2').owner.get() is owners.meta1 + assert api.config('conf1').option('od1.i2').owner.get() is owners.user + # + api.option('od1.i2').value.reset() + assert api.option('od1.i2').value.get() == api.config('conf2').option('od1.i2').value.get() == 1 + assert api.config('conf1').option('od1.i2').value.get() == 2 + assert api.option('od1.i2').owner.get() is api.config('conf2').option('od1.i2').owner.get() is owners.default + assert api.config('conf1').option('od1.i2').owner.get() is owners.user + # + api.config('conf1').option('od1.i2').value.reset() + assert api.option('od1.i2').value.get() == api.config('conf1').option('od1.i2').value.get() == api.config('conf2').option('od1.i2').value.get() == 1 + assert api.option('od1.i2').owner.get() is api.config('conf1').option('od1.i2').owner.get() is api.config('conf2').option('od1.i2').owner.get() is owners.default + + +def test_contexts(): + api = make_metaconfig() + errors = api.value.set('od1.i2', 6, only_config=True) + assert api.option('od1.i2').value.get() == 1 + assert api.option('od1.i2').owner.get() == owners.default + assert api.config('conf1').option('od1.i2').value.get() == api.config('conf1').option('od1.i2').value.get() == 6 + assert api.config('conf1').option('od1.i2').owner.get() == api.config('conf1').option('od1.i2').owner.get() is owners.user + assert len(errors) == 0 + + +def test_find(): + api = make_metaconfig() + assert [1] == api.option.find('i2', type='value') + assert 1 == api.option.find_first('i2', type='value') + assert api.option.make_dict() == {'od1.i4': 2, 'od1.i1': None, 'od1.i3': None, + 'od1.i2': 1, 'od1.i5': [2]} + + +def test_group_error(): + raises(ValueError, "GroupConfig('str')") + raises(ValueError, "GroupConfig(['str'])") + + +def test_meta_meta(): + api = make_metaconfig(double=True) + assert api.option('od1.i2').value.get() == api.config('meta').option('od1.i2').value.get() == api.config('meta.conf1').option('od1.i2').value.get() == api.config('meta.conf2').option('od1.i2').value.get() == 1 + assert api.option('od1.i2').owner.get() is api.config('meta').option('od1.i2').owner.get() is api.config('meta.conf1').option('od1.i2').owner.get() is api.config('meta.conf2').option('od1.i2').owner.get() is owners.default + # + api.option('od1.i2').value.set(3) + assert api.option('od1.i2').value.get() == api.config('meta').option('od1.i2').value.get() == api.config('meta.conf1').option('od1.i2').value.get() == api.config('meta.conf2').option('od1.i2').value.get() == 3 + assert api.option('od1.i2').owner.get() is api.config('meta').option('od1.i2').owner.get() is api.config('meta.conf1').option('od1.i2').owner.get() is api.config('meta.conf2').option('od1.i2').owner.get() is owners.meta1 + # + api.config('meta.conf1').option('od1.i2').value.set(2) + assert api.option('od1.i2').value.get() == api.config('meta').option('od1.i2').value.get() == api.config('meta.conf2').option('od1.i2').value.get() == 3 + assert api.config('meta.conf1').option('od1.i2').value.get() == 2 + assert api.option('od1.i2').owner.get() is api.config('meta').option('od1.i2').owner.get() is api.config('meta.conf2').option('od1.i2').owner.get() is owners.meta1 + assert api.config('meta.conf1').option('od1.i2').owner.get() is owners.user + # + api.config('meta').option('od1.i2').value.set(4) + assert api.option('od1.i2').value.get() == 3 + assert api.config('meta').option('od1.i2').value.get() == api.config('meta.conf2').option('od1.i2').value.get() == 4 + assert api.config('meta.conf1').option('od1.i2').value.get() == 2 + assert api.option('od1.i2').owner.get() is owners.meta1 + assert api.config('meta').option('od1.i2').owner.get() is api.config('meta.conf2').option('od1.i2').owner.get() is owners.meta2 + assert api.config('meta.conf1').option('od1.i2').owner.get() is owners.user + # + api.config('meta').option('od1.i2').value.reset() + assert api.option('od1.i2').value.get() == api.config('meta').option('od1.i2').value.get() == api.config('meta.conf2').option('od1.i2').value.get() == 3 + assert api.config('meta.conf1').option('od1.i2').value.get() == 2 + assert api.option('od1.i2').owner.get() is api.config('meta').option('od1.i2').owner.get() is api.config('meta.conf2').option('od1.i2').owner.get() is owners.meta1 + assert api.config('meta.conf1').option('od1.i2').owner.get() is owners.user + # + api.option('od1.i2').value.reset() + assert api.option('od1.i2').value.get() == api.config('meta').option('od1.i2').value.get() == api.config('meta.conf2').option('od1.i2').value.get() == 1 + assert api.config('meta.conf1').option('od1.i2').value.get() == 2 + assert api.option('od1.i2').owner.get() is api.config('meta').option('od1.i2').owner.get() is api.config('meta.conf2').option('od1.i2').owner.get() is owners.default + assert api.config('meta.conf1').option('od1.i2').owner.get() is owners.user + # + api.config('meta.conf1').option('od1.i2').value.reset() + assert api.option('od1.i2').value.get() == api.config('meta').option('od1.i2').value.get() == api.config('meta.conf1').option('od1.i2').value.get() == api.config('meta.conf2').option('od1.i2').value.get() == 1 + assert api.option('od1.i2').owner.get() is api.config('meta').option('od1.i2').owner.get() is api.config('meta.conf1').option('od1.i2').owner.get() is api.config('meta.conf2').option('od1.i2').owner.get() is owners.default + + +def test_meta_new_config(): + od = make_description() + meta = MetaConfig(['name1', 'name2'], optiondescription=od) + assert len(meta.cfgimpl_get_children()) == 2 + meta.new_config('newconf1') + assert len(meta.cfgimpl_get_children()) == 3 + + +def test_meta_new_config_wrong_name(): + od = make_description() + meta = MetaConfig(['name1', 'name2'], optiondescription=od) + assert len(meta.cfgimpl_get_children()) == 2 + raises(ConflictError, "meta.new_config('name1')") + assert len(meta.cfgimpl_get_children()) == 2 + + +def test_meta_meta_set(): + api = make_metaconfig(double=True) + errors1 = api.value.set('od1.i1', 7, only_config=True) + errors2 = api.value.set('od1.i6', 7, only_config=True) + assert len(errors1) == 0 + assert len(errors2) == 2 + meta = api._config.getconfig('meta') + conf1 = meta.getconfig('conf1') + conf2 = meta.getconfig('conf2') + assert api.config('meta.conf1').option('od1.i1').value.get() == api.config('meta.conf2').option('od1.i1').value.get() == 7 + assert [conf1, conf2] == api.config.find_first('i1', byvalue=7).cfgimpl_get_children() + api.config('meta.conf1').option('od1.i1').value.set(8) + assert [conf1, conf2] == api.config.find_first('i1').cfgimpl_get_children() + assert [conf2] == api.config.find_first('i1', byvalue=7).cfgimpl_get_children() + assert [conf1] == api.config.find_first('i1', byvalue=8).cfgimpl_get_children() + assert [conf1, conf2] == api.config.find_first('i5', byvalue=2).cfgimpl_get_children() + raises(AttributeError, "api.config.find_first('i1', byvalue=10)") + raises(AttributeError, "api.config.find_first('not', byvalue=10)") + raises(AttributeError, "api.config.find_first('i6')") + #raises(ValueError, "api.value.set('od1.i6', 7, only_config=True, force_default=True)") + #raises(ValueError, "api.value.set('od1.i6', 7, only_config=True, force_default_if_same=True)") + #raises(ValueError, "api.value.set('od1.i6', 7, only_config=True, force_dont_change_value=True)") + + +def test_not_meta(): + i1 = IntOption('i1', '') + od1 = OptionDescription('od1', '', [i1]) + od2 = OptionDescription('od2', '', [od1]) + conf1 = Config(od2, session_id='conf1') + conf2 = Config(od2, session_id='conf2') + conf3 = Config(od2) + conf4 = Config(od2, session_id='conf4') + raises(ValueError, "GroupConfig(conf1)") + #same name + raises(ConflictError, "GroupConfig([conf2, conf4], session_id='conf2')") + grp = GroupConfig([conf1, conf2]) + api = getapi(grp) + raises(ConfigError, "api.option('od1.i1').value.get()") + conf1, conf2 = grp.cfgimpl_get_children() + errors = api.value.set('od1.i1', 7) + assert len(errors) == 0 + assert api.config('conf1').option('od1.i1').value.get() == api.config('conf2').option('od1.i1').value.get() == 7 + assert api.config('conf1').option('od1.i1').owner.get() is api.config('conf2').option('od1.i1').owner.get() is owners.user + + +def test_group_find_firsts(): + i1 = IntOption('i1', '') + od1 = OptionDescription('od1', '', [i1]) + od2 = OptionDescription('od2', '', [od1]) + conf1 = Config(od2, session_id='conf1') + conf2 = Config(od2, session_id='conf2') + grp = GroupConfig([conf1, conf2]) + api = getapi(grp) + assert [conf1, conf2] == api.config.find_first('i1').cfgimpl_get_children() + + +def test_group_group(): + i1 = IntOption('i1', '') + od1 = OptionDescription('od1', '', [i1]) + od2 = OptionDescription('od2', '', [od1]) + conf1 = Config(od2, session_id='conf9') + conf2 = Config(od2, session_id='conf10') + grp = GroupConfig([conf1, conf2], 'grp') + grp2 = GroupConfig([grp]) + api = getapi(grp2) + errors = api.value.set('od1.i1', 2) + assert len(errors) == 0 + assert api.config('grp.conf9').option('od1.i1').value.get() == 2 + assert api.config('grp.conf9').option('od1.i1').owner.get() is owners.user + + +def test_meta_unconsistent(): + i1 = IntOption('i1', '') + i2 = IntOption('i2', '', default=1) + i3 = IntOption('i3', '') + i4 = IntOption('i4', '', default=2) + od1 = OptionDescription('od1', '', [i1, i2, i3, i4]) + od2 = OptionDescription('od2', '', [od1]) + od3 = OptionDescription('od3', '', [od1]) + conf1 = Config(od2, session_id='conf1') + conf2 = Config(od2, session_id='conf2') + conf3 = Config(od2, session_id='conf3') + conf4 = Config(od3, session_id='conf4') + api = getapi(MetaConfig([conf1, conf2])) + api.owner.set(owners.meta1) + raises(TypeError, 'MetaConfig("string")') + #same descr but conf1 already in meta + raises(ValueError, "MetaConfig([conf1, conf3])") + #not same descr + raises(ValueError, "MetaConfig([conf3, conf4])") + raises(ConfigError, "api.config('conf1').property.read_only()") + + +def test_meta_master_slaves(): + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True) + netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',)) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od = OptionDescription('root', '', [interface1]) + conf1 = Config(od, session_id='conf1') + conf2 = Config(od, session_id='conf2') + api = getapi(MetaConfig([conf1, conf2])) + api.property.read_only() + assert [conf1, conf2] == api.config.find_first('ip_admin_eth0').cfgimpl_get_children() + assert [conf1, conf2] == api.config.find_first('netmask_admin_eth0').cfgimpl_get_children() + api.property.read_write() + raises(AttributeError, "api.config.find_first('netmask_admin_eth0')") + assert [conf1, conf2] == api.unrestraint.config.find_first('netmask_admin_eth0').cfgimpl_get_children() + api.property.read_only() + assert [conf1, conf2] == api.config.find_first('netmask_admin_eth0').cfgimpl_get_children() + + +def test_meta_master_slaves_value2(): + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True) + netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',)) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od = OptionDescription('root', '', [interface1]) + conf1 = Config(od, session_id='conf1') + conf2 = Config(od, session_id='conf2') + meta = MetaConfig([conf1, conf2], session_id="meta") + api = getapi(meta) + api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.8']) + assert api.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None + #FIXME devrait raise ! assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0', 0).value.get() == None + # + api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.reset() + # + api.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) + assert api.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None + api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('255.255.255.0') + assert api.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.255.0' + api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('255.255.0.0') + assert api.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.0.0' + # + api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) + assert api.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None + + +def test_meta_master_slaves_value_default(): + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1']) + netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od = OptionDescription('root', '', [interface1]) + conf1 = Config(od, session_id='conf1') + conf2 = Config(od, session_id='conf2') + api = getapi(MetaConfig([conf1, conf2])) + assert api.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None + # + api.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) + assert api.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None + # + api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('255.255.255.0') + assert api.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.255.0' + # + api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('255.255.0.0') + assert api.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.0.0' + # + api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) + assert api.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None + + +def test_meta_master_slaves_owners(): + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True) + netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',)) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od = OptionDescription('root', '', [interface1]) + conf1 = Config(od, session_id='conf1') + conf2 = Config(od, session_id='conf2') + api = getapi(MetaConfig([conf1, conf2])) + api.owner.set(owners.meta1) + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.isdefault() + assert api.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).owner.isdefault() + # + api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.user + assert api.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).owner.isdefault() + # + api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.reset() + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.isdefault() + assert api.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).owner.isdefault() + # + api.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.meta1 + assert api.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).owner.isdefault() + # + api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('255.255.255.0') + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.meta1 + assert api.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == owners.meta1 + # + api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('255.255.0.0') + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.meta1 + assert api.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == owners.meta1 + # + api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() == owners.user + assert api.config('conf1').option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == owners.default + + +def test_meta_force_default(): + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True) + netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',)) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od = OptionDescription('root', '', [interface1]) + conf1 = Config(od, session_id='conf1') + conf2 = Config(od, session_id='conf2') + api = getapi(MetaConfig([conf1, conf2])) + api.property.read_write() + api.owner.set('meta1') + assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + # + errors = api.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.1']) + assert len(errors) == 0 + assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] + # + api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2']) + assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2'] + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] + # + errors = api.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.3']) + assert len(errors) == 0 + assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.3'] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2'] + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.3'] + # + errors = api.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.4'], force_default=True) + assert len(errors) == 0 + assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + + +def test_meta_force_dont_change_value(): + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True) + netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',)) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od = OptionDescription('root', '', [interface1]) + conf1 = Config(od, session_id='conf1') + conf2 = Config(od, session_id='conf2') + api = getapi(MetaConfig([conf1, conf2])) + api.property.read_write() + api.owner.set('meta1') + assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.4']) + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').owner.isdefault() + errors = api.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.4'], force_dont_change_value=True) + assert len(errors) == 0 + assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user + + +def test_meta_force_default_if_same(): + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True) + netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',)) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od = OptionDescription('root', '', [interface1]) + conf1 = Config(od, session_id='conf1') + conf2 = Config(od, session_id='conf2') + api = getapi(MetaConfig([conf1, conf2])) + api.property.read_write() + api.owner.set('meta1') + # + assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + # + api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.4']) + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').owner.isdefault() + errors = api.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.4'], force_default_if_same=True) + assert len(errors) == 0 + assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.meta1 + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.meta1 + # + api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.3']) + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.3'] + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.meta1 + errors = api.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.5'], force_default_if_same=True) + assert len(errors) == 0 + assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.5'] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.3'] + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.5'] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.meta1 + + +def test_meta_force_default_if_same_and_dont_change(): + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True) + netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',)) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od = OptionDescription('root', '', [interface1]) + conf1 = Config(od, session_id='conf1') + conf2 = Config(od, session_id='conf2') + api = getapi(MetaConfig([conf1, conf2])) + api.property.read_write() + api.owner.set('meta1') + # + assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + # + api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.4']) + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').owner.isdefault() + errors = api.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.4'], force_default_if_same=True, force_dont_change_value=True) + assert len(errors) == 0 + assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.4'] + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.meta1 + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user + # + api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.3']) + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.3'] + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user + errors = api.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.5'], force_default_if_same=True, force_dont_change_value=True) + assert len(errors) == 0 + assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.5'] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.3'] + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').owner.get() is owners.user + + +def test_meta_force_default_and_dont_change(): + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True) + netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',)) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od = OptionDescription('root', '', [interface1]) + conf1 = Config(od, session_id='rconf1') + conf2 = Config(od, session_id='rconf2') + api = getapi(MetaConfig([conf1, conf2])) + api.property.read_write() + api.owner.set('meta1') + raises(ValueError, "api.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.4'], force_default=True, force_dont_change_value=True)") + + +def test_meta_properties_meta(): + 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.impl_add_consistency('network_netmask', ip_admin_eth0) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od = OptionDescription('root', '', [interface1]) + conf1 = Config(od, session_id='conf1') + conf2 = Config(od, session_id='conf2') + api = getapi(MetaConfig([conf1, conf2])) + api.property.read_write() + assert api.config('conf1').option.make_dict() == {} + + +def test_meta_exception_meta(): + 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, callback=raise_exception) + netmask_admin_eth0.impl_add_consistency('network_netmask', ip_admin_eth0) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od = OptionDescription('root', '', [interface1]) + conf1 = Config(od, session_id='conf1') + conf2 = Config(od, session_id='conf2') + api = getapi(MetaConfig([conf1, conf2])) + api.property.read_write() + raises(Exception, "conf1.make_dict()") + + +def test_meta_callback(): + val1 = StrOption('val1', "", 'val') + val2 = StrOption('val2', "", callback=return_value, callback_params={'': ((val1, False),)}) + val3 = StrOption('val3', "", callback=return_value, callback_params={'': ('yes',)}) + val4 = StrOption('val4', "", callback=return_value, callback_params={'value': ((val1, False),)}) + val5 = StrOption('val5', "", callback=return_value, callback_params={'value': ('yes',)}) + maconfig = OptionDescription('rootconfig', '', [val1, val2, val3, val4, val5]) + cfg = Config(maconfig, session_id='cfg') + api = getapi(MetaConfig([cfg])) + api.property.read_write() + assert api.config('cfg').option.make_dict() == {'val3': 'yes', 'val2': 'val', 'val1': 'val', 'val5': 'yes', 'val4': 'val'} + api.config('cfg').option('val1').value.set('new') + assert api.config('cfg').option.make_dict() == {'val3': 'yes', 'val2': 'new', 'val1': 'new', 'val5': 'yes', 'val4': 'new'} + api.config('cfg').option('val1').value.reset() + api.option('val1').value.set('new') + assert api.config('cfg').option.make_dict() == {'val3': 'yes', 'val2': 'new', 'val1': 'new', 'val5': 'yes', 'val4': 'new'} + api.config('cfg').option('val4').value.set('new1') + assert api.config('cfg').option.make_dict() == {'val3': 'yes', 'val2': 'new', 'val1': 'new', 'val5': 'yes', 'val4': 'new1'} + api.config('cfg').option('val4').value.reset() + api.option('val4').value.set('new1') + assert api.config('cfg').option.make_dict() == {'val3': 'yes', 'val2': 'new', 'val1': 'new', 'val5': 'yes', 'val4': 'new1'} + api.option('val4').value.reset() + + +def test_meta_callback_slave(): + val = StrOption('val', "", default='val') + val1 = StrOption('val1', "", multi=True, callback=return_value, callback_params={'': ((val, False),)}) + val3 = StrOption('val2', "", multi=True, callback=return_value, callback_params={'': ((val1, False),)}) + val4 = StrOption('val3', "", multi=True, callback=return_value, callback_params={'': ((val1, False),)}) + interface1 = MasterSlaves('val1', '', [val1, val3, val4]) + od = OptionDescription('root', '', [interface1]) + maconfig = OptionDescription('rootconfig', '', [val, interface1]) + cfg = Config(maconfig, session_id='cfg1') + api = getapi(MetaConfig([cfg])) + api.property.read_write() + assert api.config('cfg1').option.make_dict() == {'val1.val2': ['val'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'} + api.config('cfg1').option('val').value.set('val1') + assert api.config('cfg1').option.make_dict() == {'val1.val2': ['val1'], 'val1.val1': ['val1'], 'val1.val3': ['val1'], 'val': 'val1'} + api.config('cfg1').option('val').value.reset() + api.option('val').value.set('val1') + assert api.config('cfg1').option.make_dict() == {'val1.val2': ['val1'], 'val1.val1': ['val1'], 'val1.val3': ['val1'], 'val': 'val1'} + api.option('val').value.reset() + api.config('cfg1').option('val1.val2', 0).value.set('val2') + assert api.config('cfg1').option.make_dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'} + api.config('cfg1').option('val1.val2', 0).value.reset() + assert api.config('cfg1').option.make_dict() == {'val1.val2': ['val'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'} + api.option('val1.val2', 0).value.set('val2') + assert api.config('cfg1').option.make_dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'} + api.config('cfg1').option('val1.val3', 0).value.set('val6') + assert api.config('cfg1').option.make_dict() == {'val1.val2': ['val2'], 'val1.val1': ['val'], 'val1.val3': ['val6'], 'val': 'val'} + api.option('val1.val2', 0).value.reset() + api.config('cfg1').option('val1.val3', 0).value.reset() + api.config('cfg1').option('val1.val1').value.set(['val3']) + assert api.config('cfg1').option.make_dict() == {'val1.val2': ['val3'], 'val1.val1': ['val3'], 'val1.val3': ['val3'], 'val': 'val'} + api.config('cfg1').option('val1.val1').value.reset() + assert api.config('cfg1').option.make_dict() == {'val1.val2': ['val'], 'val1.val1': ['val'], 'val1.val3': ['val'], 'val': 'val'} + api.option('val1.val1').value.set(['val3']) + assert api.config('cfg1').option.make_dict() == {'val1.val2': ['val3'], 'val1.val1': ['val3'], 'val1.val3': ['val3'], 'val': 'val'} + api.config('cfg1').option('val1.val2', 0).value.set('val2') + assert api.config('cfg1').option.make_dict() == {'val1.val2': ['val2'], 'val1.val1': ['val3'], 'val1.val3': ['val3'], 'val': 'val'} + api.option('val1.val1').value.set(['val3', 'rah']) + assert api.config('cfg1').option.make_dict() == {'val1.val2': ['val2', 'rah'], 'val1.val1': ['val3', 'rah'], 'val1.val3': ['val3', 'rah'], 'val': 'val'} + api.option('val1.val1').value.pop(1) + api.option('val1.val1').value.set(['val4']) + assert api.config('cfg1').option.make_dict() == {'val1.val2': ['val2'], 'val1.val1': ['val4'], 'val1.val3': ['val4'], 'val': 'val'} + + +def test_meta_propreset(): + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True) + netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',)) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od = OptionDescription('root', '', [interface1]) + conf1 = Config(od, session_id='conf1') + conf2 = Config(od, session_id='conf2') + api = getapi(MetaConfig([conf1, conf2])) + api.property.read_write() + api.owner.set('meta1') + assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + errors = api.value.set('ip_admin_eth0.ip_admin_eth0', ['192.168.1.1']) + assert len(errors) == 0 + assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] + api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2']) + assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2'] + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] + api.value.reset('ip_admin_eth0.ip_admin_eth0') + assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert api.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + assert api.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] + + +def test_meta_properties_meta_set_value(): + 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',)) + interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + conf1 = Config(interface1, session_id='conf1') + conf2 = Config(interface1, session_id='conf2') + api = getapi(MetaConfig([conf1, conf2])) + api.property.read_write() + assert api.config('conf1').option.make_dict() == {'ip_admin_eth0': ['192.168.1.1']} + ret = api.value.set('netmask_admin_eth0', ['255.255.255.255'], only_config=True) + assert len(ret) == 2 + assert isinstance(ret[0], PropertiesOptionError) + assert isinstance(ret[1], PropertiesOptionError) + del(ret) + ret = api.value.set('netmask_admin_eth0', ['255.255.255.255'], force_default=True) + assert len(ret) == 1 + assert isinstance(ret[0], PropertiesOptionError) + del(ret) + ret = api.value.set('netmask_admin_eth0', ['255.255.255.255'], force_dont_change_value=True) + assert len(ret) == 3 + assert isinstance(ret[0], PropertiesOptionError) + assert isinstance(ret[1], PropertiesOptionError) + assert isinstance(ret[2], PropertiesOptionError) + del(ret) + ret = api.value.set('netmask_admin_eth0', ['255.255.255.255'], force_default_if_same=True) + assert len(ret) == 1 + assert isinstance(ret[0], PropertiesOptionError) + del(ret) + ret = api.value.set('ip_admin_eth0', '255.255.255.255', only_config=True) + assert len(ret) == 2 + assert isinstance(ret[0], ValueError) + assert isinstance(ret[1], ValueError) + del(ret) + ret = api.value.set('ip_admin_eth0', '255.255.255.255', force_default=True) + assert len(ret) == 1 + assert isinstance(ret[0], ValueError) + del(ret) + ret = api.value.set('ip_admin_eth0', '255.255.255.255', force_dont_change_value=True) + assert len(ret) == 1 + assert isinstance(ret[0], ValueError) + del(ret) + ret = api.value.set('ip_admin_eth0', '255.255.255.255', force_default_if_same=True) + assert len(ret) == 1 + assert isinstance(ret[0], ValueError) + del(ret) diff --git a/tiramisu/__init__.py b/tiramisu/__init__.py index 5a7821e..1813dfa 100644 --- a/tiramisu/__init__.py +++ b/tiramisu/__init__.py @@ -12,7 +12,7 @@ # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . -from .config import Config, MetaConfig +from .config import Config, MetaConfig, GroupConfig from .option import * from .error import APIError from .api import getapi @@ -21,6 +21,7 @@ from .setting import owners, undefined allfuncs = ['MetaConfig', + 'GroupConfig', 'Config' 'getapi', 'APIError', diff --git a/tiramisu/api.py b/tiramisu/api.py index a349ead..bbc2ba6 100644 --- a/tiramisu/api.py +++ b/tiramisu/api.py @@ -563,6 +563,33 @@ class TiramisuContextValue(TiramisuContext): def get_modified(self): return self.config_bag.config.cfgimpl_get_values().get_modified_values() + def set(self, + path, + value, + index=None, + only_config=undefined, + force_default=undefined, + force_default_if_same=undefined, + force_dont_change_value=undefined): + kwargs = {} + if only_config is not undefined: + kwargs['only_config'] = only_config + if force_default is not undefined: + kwargs['force_default'] = force_default + if force_default_if_same is not undefined: + kwargs['force_default_if_same'] = force_default_if_same + if force_dont_change_value is not undefined: + kwargs['force_dont_change_value'] = force_dont_change_value + return self.config_bag.config.set_value(path, + index, + value, + self.config_bag, + **kwargs) + + def reset(self, + path): + self.config_bag.config.reset(path, self.config_bag) + class TiramisuContextOwner(TiramisuContext): @count @@ -683,22 +710,36 @@ class TiramisuContextOption(TiramisuContext): raise APIError(_('unknown list type {}').format(type)) +class TiramisuContextConfig(TiramisuContext): + def find_first(self, + name, + byvalue=undefined): + return self.config_bag.config.find_firsts(byname=name, + byvalue=byvalue, + config_bag=self.config_bag) + + +class TiramisuDispatcherConfig(TiramisuContextConfig): + def __call__(self, path): + spaths = path.split('.') + config = self.config_bag.config + for spath in spaths: + config = config.getconfig(spath) + return TiramisuAPI(config, + force_permissive=self.config_bag.force_permissive, + force_unrestraint=self.config_bag.force_unrestraint) + + class TiramisuDispatcherOption(TiramisuContextOption): def __call__(self, path, index=None): config_bag = self.config_bag.copy() validate = not config_bag.force_unrestraint - config_bag.validate = validate - config_bag.validate_properties = validate + #config_bag.validate = validate + #config_bag.validate_properties = validate if not validate: config_bag.setting_properties = None subconfig, name = config_bag.config.cfgimpl_get_home_by_path(path, config_bag) - #opt = config_bag.config.unwrap_from_path(path, - # index, - # config_bag) - #config_bag.option = opt - #if index is not None and not opt.impl_is_master_slaves('slave'): - # raise APIError('index must be set only with a slave option') return TiramisuOption(name, path, index, @@ -726,7 +767,7 @@ class TiramisuAPI(object): return TiramisuAPI(config=self._config, force_permissive=True, force_unrestraint=self.force_unrestraint) - elif subfunc in ['unrestraint', 'config']: + elif subfunc == 'unrestraint': return TiramisuAPI(config=self._config, force_permissive=self.force_permissive, force_unrestraint=True) diff --git a/tiramisu/config.py b/tiramisu/config.py index 258a53b..e397514 100644 --- a/tiramisu/config.py +++ b/tiramisu/config.py @@ -71,7 +71,8 @@ class SubConfig(object): raise ValueError('context must be a Weakref') self._impl_context = context self._impl_path = subpath - if config_bag.setting_properties is not None and \ + if descr is not None and \ + config_bag.setting_properties is not None and \ descr.impl_get_group_type() == groups.master: master = descr.getmaster() masterpath = master.impl_getname() @@ -161,6 +162,8 @@ class SubConfig(object): self = self.getattr(step, None, sconfig_bag) + if not isinstance(self, SubConfig): + raise AttributeError(_('unknown option {}').format(path[-1])) return self, path[-1] # ______________________________________________________________________ @@ -300,9 +303,9 @@ class SubConfig(object): value) context = self._cfgimpl_get_context() if '.' in name: # pragma: optional cover - raise Exception('ah non ...') - #self, name = self.cfgimpl_get_home_by_path(name, - # config_bag) + # when set_value + self, name = self.cfgimpl_get_home_by_path(name, + config_bag) if config_bag.option is None: config_bag.option = self.cfgimpl_get_description().impl_getchild(name, config_bag, @@ -567,6 +570,9 @@ class SubConfig(object): self.unwrap_from_path(path, None, config_bag) + self.cfgimpl_get_settings().validate_properties(path, + None, + config_bag) except PropertiesOptionError: continue if type_ == 'value': @@ -962,12 +968,11 @@ class GroupConfig(_CommonConfig): properties, permissives) self._impl_values = Values(self, values) + self._impl_meta = None super(GroupConfig, self).__init__(_descr, weakref.ref(self), - undefined, - True, - False) - self._impl_meta = None + ConfigBag(self), + None) #undocumented option used only in test script self._impl_test = False self._impl_name = session_id @@ -993,40 +998,47 @@ class GroupConfig(_CommonConfig): path=path, resetted_opts=copy(resetted_opts)) - def set_value(self, path, value, _commit=True): + def set_value(self, + path, + index, + value, + config_bag, + only_config=False, + _commit=True): """Setattr not in current GroupConfig, but in each children """ ret = [] for child in self._impl_children: - if isinstance(child, MetaConfig): - ret.extend(child.set_value(path, - value, - only_config=True, - _commit=False)) - elif isinstance(child, GroupConfig): - ret.extend(child.set_value(path, - value, - _commit=False)) - else: - childret = child.setattr(path, - value, - not_raises=True, - _commit=False) - if childret is not None: - ret.append(childret) + try: + if isinstance(child, GroupConfig): + ret.extend(child.set_value(path, + index, + value, + config_bag, + only_config=only_config, + _commit=False)) + else: + nconfig_bag = config_bag.copy('nooption') + child.setattr(path, + index, + value, + nconfig_bag, + _commit=False) + except (PropertiesOptionError, ValueError, SlaveError) as err: + ret.append(err) if _commit: self.cfgimpl_get_values()._p_.commit() return ret def find_firsts(self, + config_bag, byname=None, bypath=undefined, byoption=undefined, byvalue=undefined, raise_if_not_found=True, - _sub=False, - check_properties=True): + _sub=False): """Find first not in current GroupConfig, but in each children """ ret = [] @@ -1040,19 +1052,21 @@ class GroupConfig(_CommonConfig): byvalue=undefined, byname=byname, first=True, + config_bag=config_bag, type_='path', - check_properties=None, raise_if_not_found=raise_if_not_found) byname = None byoption = self.cfgimpl_get_description().impl_get_opt_by_path(bypath) for child in self._impl_children: + nconfig_bag = config_bag.copy('nooption') + nconfig_bag.option = child if isinstance(child, GroupConfig): ret.extend(child.find_firsts(byname=byname, bypath=bypath, byoption=byoption, byvalue=byvalue, - check_properties=check_properties, + config_bag=config_bag, raise_if_not_found=False, _sub=True)) elif child._find(None, @@ -1060,8 +1074,8 @@ class GroupConfig(_CommonConfig): byvalue, first=True, type_='path', + config_bag=config_bag, raise_if_not_found=False, - check_properties=check_properties, only_path=bypath, only_option=byoption): ret.append(child) @@ -1071,15 +1085,17 @@ class GroupConfig(_CommonConfig): return GroupConfig(self._find_return_results(ret, raise_if_not_found)) - def __str__(self): - ret = '' - for child in self._impl_children: - ret += "({0})\n".format(child._impl_name) - if self._impl_descr is not None: - ret += super(GroupConfig, self).__str__() - return ret - - __repr__ = __str__ + def impl_getname(self): + return self._impl_name +# def __str__(self): +# ret = '' +# for child in self._impl_children: +# ret += "({0})\n".format(child._impl_name) +# if self._impl_descr is not None: +# ret += super(GroupConfig, self).__str__() +# return ret +# +# __repr__ = __str__ def getconfig(self, name): @@ -1128,7 +1144,9 @@ class MetaConfig(GroupConfig): def set_value(self, path, + index, value, + config_bag, force_default=False, force_dont_change_value=False, force_default_if_same=False, @@ -1143,7 +1161,10 @@ class MetaConfig(GroupConfig): 'force_dont_change_value cannot be set with' ' only_config')) return super(MetaConfig, self).set_value(path, + index, value, + config_bag, + only_config=only_config, _commit=_commit) ret = [] if force_default or force_default_if_same or force_dont_change_value: @@ -1151,52 +1172,60 @@ class MetaConfig(GroupConfig): raise ValueError(_('force_default and force_dont_change_value' ' cannot be set together')) opt = self.cfgimpl_get_description().impl_get_opt_by_path(path) - setting_properties = self.cfgimpl_get_settings()._getproperties(read_write=False) for child in self._impl_children: - if force_default_if_same or force_default: - if force_default_if_same: - if not child.cfgimpl_get_values()._contains(path): - child_value = undefined - else: - child_value = child.getattr(path) - if force_default or value == child_value: - child.cfgimpl_get_values().reset(opt, - path, - setting_properties, - validate=False, - _commit=False) - continue + nconfig_bag = config_bag.copy('nooption') + nconfig_bag.option = opt + if force_default_if_same: + if not child.cfgimpl_get_values()._p_.hasvalue(path): + child_value = undefined + else: + child_value = child.getattr(path, + None, + nconfig_bag) + if force_default or (force_default_if_same and value == child_value): + child.cfgimpl_get_values().reset(path, + nconfig_bag, + _commit=False) + continue if force_dont_change_value: - child_value = child.getattr(path, - setting_properties=setting_properties) - if isinstance(child_value, Exception): - ret.append(child_value) - elif value != child_value: - childret = child.setattr(path, - child_value, - _commit=False, - not_raises=True) - if childret is not None: # pragma: no cover - ret.append(childret) + try: + child_value = child.getattr(path, + None, + nconfig_bag) + if value != child_value: + child.setattr(path, + None, + child_value, + nconfig_bag, + _commit=False) + except (PropertiesOptionError, ValueError, SlaveError) as err: + ret.append(err) - self.setattr(path, - value, - _commit=_commit) + nconfig_bag = config_bag.copy('nooption') + try: + self.setattr(path, + index, + value, + nconfig_bag, + _commit=_commit) + except (PropertiesOptionError, ValueError, SlaveError) as err: + ret.append(err) return ret - def reset(self, path): + def reset(self, path, config_bag): + #FIXME not working with DynSymLinkOption + #FIXME fonctionne avec sous metaconfig ?? opt = self.cfgimpl_get_description().impl_get_opt_by_path(path) - setting_properties = self.cfgimpl_get_settings()._getproperties(read_write=False) + config_bag.option = opt + config_bag.validate = False for child in self._impl_children: - child.cfgimpl_get_values().reset(opt, - path, - setting_properties, - validate=False, + sconfig_bag = config_bag.copy('nooption') + sconfig_bag.option = opt + child.cfgimpl_get_values().reset(path, + sconfig_bag, _commit=False) - self.cfgimpl_get_values().reset(opt, - path, - setting_properties, - validate=False) + self.cfgimpl_get_values().reset(path, + config_bag) def new_config(self, session_id, diff --git a/tiramisu/setting.py b/tiramisu/setting.py index c5146af..355374c 100644 --- a/tiramisu/setting.py +++ b/tiramisu/setting.py @@ -125,7 +125,6 @@ class ConfigBag(object): 'ori_option', 'properties', 'validate', - 'validate_properties', 'setting_properties', 'force_permissive', 'force_unrestraint', @@ -136,8 +135,6 @@ class ConfigBag(object): def __init__(self, config, **kwargs): self.default = {'force_permissive': False, 'force_unrestraint': False, - 'validate': True, - 'validate_properties': True, 'display_warnings': True, 'trusted_cached_properties': True, } @@ -148,6 +145,8 @@ class ConfigBag(object): setattr(self, key, value) def __getattr__(self, key): + if key in ['validate', 'validate_properties']: + return not self.force_unrestraint if key == 'setting_properties': if self.force_unrestraint: return None @@ -364,8 +363,7 @@ class Settings(object): props = self._p_.getproperties(path, opt.impl_getproperties()) else: - props = meta.cfgimpl_get_settings().getproperties(opt, - path, + props = meta.cfgimpl_get_settings().getproperties(path, index, config_bag) props |= self.apply_requires(path, diff --git a/tiramisu/value.py b/tiramisu/value.py index 5f3f629..29b5229 100644 --- a/tiramisu/value.py +++ b/tiramisu/value.py @@ -437,7 +437,7 @@ class Values(object): masterp = master.impl_getpath(context) # slave could be a "meta" only if master hasn't value if self._p_.hasvalue(masterp, - index=index): + index=None): return False return not meta.cfgimpl_get_values().is_default_owner(path, index, @@ -478,7 +478,7 @@ class Values(object): path, index, config_bag, - validate_meta=undefined, + validate_meta=True, only_default=False): """get owner of an option """ @@ -508,13 +508,14 @@ class Values(object): owners.default, index=index) if owner is owners.default and validate_meta is not False: - if validate_meta is undefined: - validate_meta = self._is_meta(path, - index, - config_bag=config_bag, - force_owner_is_default=True) - if validate_meta: - owner = owners.meta + meta = context.cfgimpl_get_meta() + if meta is not None and self._is_meta(path, + index, + config_bag): + owner = meta.cfgimpl_get_values()._getowner(path, + index, + config_bag, + only_default=only_default) return owner def setowner(self,