From 4f4ecfd3a8b2c47310d03e1ef41b897858a2307c Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Wed, 31 Oct 2018 16:08:22 +0100 Subject: [PATCH] reset for pathconfig --- test/test_metaconfig.py | 2 +- test/test_pathconfig.py | 61 +++++++++-- test/test_storage.py | 1 + tiramisu/api.py | 33 +++--- tiramisu/config.py | 149 +++++++++++++++++++-------- tiramisu/option/masterslaves.py | 3 +- tiramisu/setting.py | 2 +- tiramisu/storage/dictionary/value.py | 5 +- tiramisu/value.py | 10 +- 9 files changed, 185 insertions(+), 81 deletions(-) diff --git a/test/test_metaconfig.py b/test/test_metaconfig.py index 8cd3493..c461b25 100644 --- a/test/test_metaconfig.py +++ b/test/test_metaconfig.py @@ -746,7 +746,7 @@ def test_meta_reset(): assert meta.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] assert meta.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2'] assert meta.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] - meta.option('ip_admin_eth0.ip_admin_eth0').value.reset(children=True) + meta.value.reset('ip_admin_eth0.ip_admin_eth0') assert meta.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] assert meta.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] assert meta.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] diff --git a/test/test_pathconfig.py b/test/test_pathconfig.py index 52176d6..604ebe0 100644 --- a/test/test_pathconfig.py +++ b/test/test_pathconfig.py @@ -746,7 +746,7 @@ def test_meta_reset(): assert meta.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] assert meta.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2'] assert meta.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.1'] - meta.option('ip_admin_eth0.ip_admin_eth0').value.reset(children=True) + meta.value.reset('ip_admin_eth0.ip_admin_eth0') assert meta.option('ip_admin_eth0.ip_admin_eth0').value.get() == [] assert meta.config('conf1').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] assert meta.config('conf2').option('ip_admin_eth0.ip_admin_eth0').value.get() == [] @@ -986,11 +986,12 @@ def test_path_different_default(): path = PathConfig(interface3, [path], session_id='subpath2') path = PathConfig(interface4, [path]) path.property.read_write() - path.value.dict() == {'ip_admin_eth0': ['192.168.1.6']} - path.config('subpath2').value.dict() == {'ip_admin_eth0': ['192.168.1.4'], 'ip_admin_eth1': ['192.168.1.5']} - path.config('subpath2.subpath1').value.dict() == {'ip_admin_eth1': ['192.168.1.3']} - path.config('subpath2.subpath1.conf2').value.dict() == {'ip_admin_eth1': ['192.168.1.2']} - path.config('subpath2.subpath1.conf1').value.dict() == {'ip_admin_eth0': ['192.168.1.1']} + # + assert path.value.dict() == {'ip_admin_eth0': ['192.168.1.6']} + assert path.config('subpath2').value.dict() == {'ip_admin_eth0': ['192.168.1.4'], 'ip_admin_eth1': ['192.168.1.5']} + assert path.config('subpath2.subpath1').value.dict() == {'ip_admin_eth1': ['192.168.1.3']} + assert path.config('subpath2.subpath1.conf2').value.dict() == {'ip_admin_eth1': ['192.168.1.2']} + assert path.config('subpath2.subpath1.conf1').value.dict() == {'ip_admin_eth0': ['192.168.1.1']} # path.option('ip_admin_eth0').value.set(['192.168.1.7']) assert path.value.dict() == {'ip_admin_eth0': ['192.168.1.7']} @@ -1061,3 +1062,51 @@ def test_path_different_default(): assert path.config('subpath2.subpath1').value.dict() == {'ip_admin_eth1': ['192.168.1.11']} assert path.config('subpath2.subpath1.conf2').value.dict() == {'ip_admin_eth1': ['192.168.1.12']} assert path.config('subpath2.subpath1.conf1').value.dict() == {'ip_admin_eth0': ['192.168.1.9']} + + +def test_path_different_default_reset(): + ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1']) + interface0 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0]) + ip_admin_eth0 = NetworkOption('ip_admin_eth1', "ip", multi=True, default=['192.168.1.2']) + interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0]) + ip_admin_eth0 = NetworkOption('ip_admin_eth1', "ip", multi=True, default=['192.168.1.3']) + interface2 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0]) + ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.4']) + ip_admin_eth1 = NetworkOption('ip_admin_eth1', "ip", multi=True, default=['192.168.1.5']) + interface3 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, ip_admin_eth1]) + ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.6']) + interface4 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0]) + conf1 = Config(interface0, session_id='conf1') + conf1.property.read_write() + conf2 = Config(interface1, session_id='conf2') + conf2.property.read_write() + path = PathConfig(interface2, [conf1, conf2], session_id='subpath1') + path = PathConfig(interface3, [path], session_id='subpath2') + path = PathConfig(interface4, [path]) + path.property.read_write() + # + path.option('ip_admin_eth0').value.set(['192.168.1.7']) + path.config('subpath2').option('ip_admin_eth0').value.set(['192.168.1.8']) + path.config('subpath2').option('ip_admin_eth1').value.set(['192.168.1.10']) + path.config('subpath2.subpath1').option('ip_admin_eth1').value.set(['192.168.1.11']) + path.config('subpath2.subpath1.conf2').option('ip_admin_eth1').value.set(['192.168.1.12']) + path.config('subpath2.subpath1.conf1').option('ip_admin_eth0').value.set(['192.168.1.9']) + assert path.value.dict() == {'ip_admin_eth0': ['192.168.1.7']} + assert path.config('subpath2').value.dict() == {'ip_admin_eth0': ['192.168.1.8'], 'ip_admin_eth1': ['192.168.1.10']} + assert path.config('subpath2.subpath1').value.dict() == {'ip_admin_eth1': ['192.168.1.11']} + assert path.config('subpath2.subpath1.conf2').value.dict() == {'ip_admin_eth1': ['192.168.1.12']} + assert path.config('subpath2.subpath1.conf1').value.dict() == {'ip_admin_eth0': ['192.168.1.9']} + # + path.value.reset('ip_admin_eth0') + assert path.value.dict() == {'ip_admin_eth0': ['192.168.1.6']} + assert path.config('subpath2').value.dict() == {'ip_admin_eth0': ['192.168.1.4'], 'ip_admin_eth1': ['192.168.1.10']} + assert path.config('subpath2.subpath1').value.dict() == {'ip_admin_eth1': ['192.168.1.11']} + assert path.config('subpath2.subpath1.conf2').value.dict() == {'ip_admin_eth1': ['192.168.1.12']} + assert path.config('subpath2.subpath1.conf1').value.dict() == {'ip_admin_eth0': ['192.168.1.1']} + # + path.value.reset('ip_admin_eth1') + assert path.value.dict() == {'ip_admin_eth0': ['192.168.1.6']} + assert path.config('subpath2').value.dict() == {'ip_admin_eth0': ['192.168.1.4'], 'ip_admin_eth1': ['192.168.1.5']} + assert path.config('subpath2.subpath1').value.dict() == {'ip_admin_eth1': ['192.168.1.3']} + assert path.config('subpath2.subpath1.conf2').value.dict() == {'ip_admin_eth1': ['192.168.1.2']} + assert path.config('subpath2.subpath1.conf1').value.dict() == {'ip_admin_eth0': ['192.168.1.1']} diff --git a/test/test_storage.py b/test/test_storage.py index c17e762..5c8c4cc 100644 --- a/test/test_storage.py +++ b/test/test_storage.py @@ -36,6 +36,7 @@ def test_delete_not_persisten(): o = OptionDescription('od', '', [b]) try: Config(o, session_id='test_persistent', persistent=True) + delete_session('test_persistent') except: c = Config(o, session_id='not_test_persistent') assert 'not_test_persistent' in list_sessions() diff --git a/tiramisu/api.py b/tiramisu/api.py index a2c4a28..665d478 100644 --- a/tiramisu/api.py +++ b/tiramisu/api.py @@ -451,20 +451,6 @@ class _TiramisuOptionValueMaster: return self._length -class _TiramisuOptionValueMeta: - def reset(self, - itself: bool=True, - children: bool=False): - """Reset value""" - if children: - config_bag = self._option_bag.config_bag - config_bag.context.reset(self._option_bag.path, - config_bag) - if itself: - self._test_slave_index() - self._subconfig.delattr(self._option_bag) - - class _TiramisuOptionValueGroup: def reset(self): """Reset value""" @@ -537,9 +523,6 @@ class TiramisuOptionValue(CommonTiramisuOption): types.append(_TiramisuOptionValueMaster) elif option.impl_is_master_slaves('slave'): types.append(_TiramisuOptionValueSlave) - if option_bag.config_bag.context.impl_type in ('meta', 'path'): - # only if not an optiondescription - types.insert(0, _TiramisuOptionValueMeta) if option_bag.config_bag.context.impl_type == 'group': types.append(_TiramisuOptionValueGroup) new_type_dict = {'_allow_optiondescription': cls._allow_optiondescription, @@ -795,10 +778,18 @@ class TiramisuContextValue(TiramisuContext): if force_dont_change_value is not undefined: kwargs['force_dont_change_value'] = force_dont_change_value return self._config_bag.context.set_value(path, - index, - value, - self._config_bag, - **kwargs) + index, + value, + self._config_bag, + **kwargs) + + def reset(self, + path: str, + only_children: bool=False): + """Reset value""" + self._config_bag.context.reset(path, + only_children, + self._config_bag) def dict(self, flatten=False, diff --git a/tiramisu/config.py b/tiramisu/config.py index 9001baa..cc84c90 100644 --- a/tiramisu/config.py +++ b/tiramisu/config.py @@ -244,15 +244,18 @@ class SubConfig(object): _commit) def delattr(self, - option_bag): + option_bag, + _commit=True): option = option_bag.option if option.impl_is_symlinkoption(): raise TypeError(_("can't delete a SymLinkOption")) values = self.cfgimpl_get_values() if option_bag.index is not None: - values.reset_slave(option_bag) + values.reset_slave(option_bag, + _commit) else: - values.reset(option_bag) + values.reset(option_bag, + _commit) def _get_subpath(self, name): if self._impl_path is None: @@ -827,9 +830,10 @@ class KernelGroupConfig(_CommonConfig): """ ret = [] if self.impl_type == 'group': + # No value so cannot commit only one time commit = True else: - #Commit only one time + # Commit only one time commit = False for child in self._impl_children: cconfig_bag = config_bag.copy() @@ -928,7 +932,8 @@ class KernelGroupConfig(_CommonConfig): return self._impl_name def reset(self, - path): + path, + _commit=True): for child in self._impl_children: config_bag = ConfigBag(child) config_bag.remove_validation() @@ -944,7 +949,7 @@ class KernelGroupConfig(_CommonConfig): config_bag) option_bag.config_bag.context = child child.cfgimpl_get_values().reset(option_bag, - _commit=True) + _commit=_commit) def getconfig(self, name): @@ -1015,42 +1020,56 @@ class KernelPathConfig(KernelGroupConfig): only_config=only_config, _commit=_commit) ret = [] + subconfig, name = self.cfgimpl_get_home_by_path(path, + config_bag) + option = subconfig.cfgimpl_get_description().impl_getchild(name, + config_bag, + self.cfgimpl_get_path()) + option_bag = OptionBag() + option_bag.set_option(option, + path, + index, + config_bag) if force_default or force_default_if_same or force_dont_change_value: if force_default and force_dont_change_value: raise ValueError(_('force_default and force_dont_change_value' ' cannot be set together')) - #opt = self.cfgimpl_get_description().impl_get_opt_by_path(path, - # config_bag) for child in self._impl_children: cconfig_bag = config_bag.copy() cconfig_bag.context = child try: - subconfig, name = child.cfgimpl_get_home_by_path(path, - cconfig_bag) - option = subconfig.cfgimpl_get_description().impl_getchild(name, - cconfig_bag, - child.cfgimpl_get_path()) - option_bag = OptionBag() - option_bag.set_option(option, - path, - index, - cconfig_bag) + if self.impl_type == 'meta': + moption_bag = option_bag + del moption_bag.properties + del moption_bag.permissives + moption_bag.config_bag = cconfig_bag + else: + subconfig, name = child.cfgimpl_get_home_by_path(path, + cconfig_bag) + option = subconfig.cfgimpl_get_description().impl_getchild(name, + cconfig_bag, + child.cfgimpl_get_path()) + moption_bag = OptionBag() + moption_bag.set_option(option, + path, + index, + cconfig_bag) if force_default_if_same: if not child.cfgimpl_get_values()._p_.hasvalue(path): child_value = undefined else: child_value = child.getattr(name, - option_bag) + moption_bag) if force_default or (force_default_if_same and value == child_value): - child.cfgimpl_get_values().reset(option_bag, + child.cfgimpl_get_values().reset(moption_bag, _commit=False) continue if force_dont_change_value: child_value = child.getattr(name, - option_bag) + moption_bag) if value != child_value: child.setattr(child_value, - option_bag, + moption_bag, _commit=False) except PropertiesOptionError as err: ret.append(PropertiesOptionError(err._option_bag, @@ -1064,16 +1083,10 @@ class KernelPathConfig(KernelGroupConfig): ret.append(err) try: - subconfig, name = self.cfgimpl_get_home_by_path(path, - config_bag) - option = subconfig.cfgimpl_get_description().impl_getchild(name, - config_bag, - self.cfgimpl_get_path()) - option_bag = OptionBag() - option_bag.set_option(option, - path, - index, - config_bag) + if self.impl_type == 'meta': + del option_bag.properties + del option_bag.permissives + option_bag.config_bag = config_bag self.setattr(value, option_bag, _commit=False) @@ -1083,22 +1096,68 @@ class KernelPathConfig(KernelGroupConfig): def reset(self, path, - config_bag): + only_children, + config_bag, + commit=True): rconfig_bag = config_bag.copy() rconfig_bag.remove_validation() - subconfig, name = self.cfgimpl_get_home_by_path(path, - config_bag) - option = subconfig.cfgimpl_get_description().impl_getchild(name, - config_bag, - subconfig.cfgimpl_get_path()) - option_bag = OptionBag() - option_bag.set_option(option, - path, - option, - rconfig_bag) + if self.impl_type == 'meta': + subconfig, name = self.cfgimpl_get_home_by_path(path, + config_bag) + option = subconfig.cfgimpl_get_description().impl_getchild(name, + config_bag, + subconfig.cfgimpl_get_path()) + option_bag = OptionBag() + option_bag.set_option(option, + path, + None, + rconfig_bag) + elif not only_children: + try: + subconfig, name = self.cfgimpl_get_home_by_path(path, + config_bag) + option = subconfig.cfgimpl_get_description().impl_getchild(name, + config_bag, + subconfig.cfgimpl_get_path()) + option_bag = OptionBag() + option_bag.set_option(option, + path, + None, + rconfig_bag) + except AttributeError: + only_children = True for child in self._impl_children: - option_bag.config_bag.context = child - child.cfgimpl_get_values().reset(option_bag) + rconfig_bag.context = child + try: + if self.impl_type == 'meta': + moption_bag = option_bag + moption_bag.config_bag = rconfig_bag + else: + subconfig, name = child.cfgimpl_get_home_by_path(path, + rconfig_bag) + option = subconfig.cfgimpl_get_description().impl_getchild(name, + rconfig_bag, + child.cfgimpl_get_path()) + moption_bag = OptionBag() + moption_bag.set_option(option, + path, + None, + rconfig_bag) + child.cfgimpl_get_values().reset(moption_bag, + _commit=False) + except AttributeError: + pass + if isinstance(child, KernelPathConfig): + child.reset(path, + False, + rconfig_bag, + commit=False) + if not only_children: + option_bag.config_bag = config_bag + self.cfgimpl_get_values().reset(option_bag, + _commit=False) + if commit: + self.cfgimpl_get_values()._p_.commit() class KernelMetaConfig(KernelPathConfig): diff --git a/tiramisu/option/masterslaves.py b/tiramisu/option/masterslaves.py index 8c6aadf..fd13297 100644 --- a/tiramisu/option/masterslaves.py +++ b/tiramisu/option/masterslaves.py @@ -169,7 +169,8 @@ class MasterSlaves(OptionDescription): validate_meta=False): if slavelen > index: values._p_.resetvalue_index(slave_path, - index) + index, + True) if slavelen > index + 1: for idx in range(index + 1, slavelen): if values._p_.hasvalue(slave_path, idx): diff --git a/tiramisu/setting.py b/tiramisu/setting.py index 65c448e..6e1f3a7 100644 --- a/tiramisu/setting.py +++ b/tiramisu/setting.py @@ -156,7 +156,7 @@ class OptionBag: raise KeyError('unknown key {} for OptionBag'.format(key)) # pragma: no cover def __delattr__(self, key): - if key == 'properties': + if key in ['properties', 'permissives']: return raise KeyError('unknown key {} for ConfigBag'.format(key)) # pragma: no cover diff --git a/tiramisu/storage/dictionary/value.py b/tiramisu/storage/dictionary/value.py index 764be96..7a29260 100644 --- a/tiramisu/storage/dictionary/value.py +++ b/tiramisu/storage/dictionary/value.py @@ -131,7 +131,10 @@ class Values(Cache): values[1] = tuple(values_idx) self._values = tuple(values) - def resetvalue_index(self, path, index): + def resetvalue_index(self, + path, + index, + commit): if DEBUG: print('resetvalue_index', path, index, id(self)) def _resetvalue(nb): diff --git a/tiramisu/value.py b/tiramisu/value.py index af7a576..caec421 100644 --- a/tiramisu/value.py +++ b/tiramisu/value.py @@ -445,13 +445,11 @@ class Values(object): else: self._p_.resetvalue(option_bag.path, _commit) - if not opt.impl_is_master_slaves('master'): - # if master, already reset behind - pass context.cfgimpl_reset_cache(option_bag) def reset_slave(self, - option_bag): + option_bag, + _commit=True): if self._p_.hasvalue(option_bag.path, index=option_bag.index): context = option_bag.config_bag.context @@ -467,7 +465,9 @@ class Values(object): value = fake_value.getdefaultvalue(soption_bag) fake_value.setvalue_validation(value, soption_bag) - self._p_.resetvalue_index(option_bag.path, option_bag.index) + self._p_.resetvalue_index(option_bag.path, + option_bag.index, + _commit) context.cfgimpl_reset_cache(option_bag) def reset_master(self,