reset for groupconfig works

This commit is contained in:
Emmanuel Garette 2018-09-29 18:52:13 +02:00
parent 996a6c7303
commit 33e68dbebf
6 changed files with 84 additions and 59 deletions

View file

@ -195,7 +195,9 @@ def test_get_modified_values():
assert not config.option('od.g5').option.issubmulti() assert not config.option('od.g5').option.issubmulti()
config.option('od.g5').value.set('yes') config.option('od.g5').value.set('yes')
assert to_tuple(config.value.exportation()) == (('od.g5',), (None,), ('yes',), ('user',)) assert to_tuple(config.value.exportation()) == (('od.g5',), (None,), ('yes',), ('user',))
config.option('od.g4').value.set(True) config.option('od.g4').value.set(False)
assert to_tuple(config.value.exportation()) == (('od.g5', 'od.g4'), (None, None), ('yes', False), ('user', 'user'))
config.option('od.g4').value.set(undefined)
assert to_tuple(config.value.exportation()) == (('od.g5', 'od.g4'), (None, None), ('yes', True), ('user', 'user')) assert to_tuple(config.value.exportation()) == (('od.g5', 'od.g4'), (None, None), ('yes', True), ('user', 'user'))
config.option('od.g4').value.reset() config.option('od.g4').value.reset()
assert to_tuple(config.value.exportation()) == (('od.g5',), (None,), ('yes',), ('user',)) assert to_tuple(config.value.exportation()) == (('od.g5',), (None,), ('yes',), ('user',))

View file

@ -118,6 +118,12 @@ def test_iter_on_groups():
group_type=groups.family): group_type=groups.family):
#test StopIteration #test StopIteration
break break
result = api.option('creole').list('option',
group_type=groups.family)
assert list(result) == []
result = api.option('creole.general').list('optiondescription',
group_type=groups.family)
assert list(result) == []
def test_list_recursive(): def test_list_recursive():
descr = make_description() descr = make_description()
@ -130,6 +136,9 @@ def test_list_recursive():
result = list(api.option.list(recursive=True)) result = list(api.option.list(recursive=True))
group_names = [res.option.name() for res in result] group_names = [res.option.name() for res in result]
assert group_names == ['numero_etab', 'nom_machine', 'nombre_interfaces', 'activer_proxy_client', 'mode_conteneur_actif', 'serveur_ntp', 'time_zone', 'ip_admin_eth0', 'netmask_admin_eth0'] assert group_names == ['numero_etab', 'nom_machine', 'nombre_interfaces', 'activer_proxy_client', 'mode_conteneur_actif', 'serveur_ntp', 'time_zone', 'ip_admin_eth0', 'netmask_admin_eth0']
result = list(api.option.list(recursive=True, type='optiondescription'))
group_names = [res.option.name() for res in result]
assert group_names == ['general', 'ip_admin_eth0', 'interface1', 'creole']
def test_iter_on_groups_force_permissive(): def test_iter_on_groups_force_permissive():

View file

@ -7,7 +7,7 @@ from tiramisu.setting import groups, owners
from tiramisu import IntOption, StrOption, NetworkOption, NetmaskOption, \ from tiramisu import IntOption, StrOption, NetworkOption, NetmaskOption, \
OptionDescription, MasterSlaves, Config, GroupConfig, MetaConfig, \ OptionDescription, MasterSlaves, Config, GroupConfig, MetaConfig, \
Params, ParamOption, ParamValue Params, ParamOption, ParamValue
from tiramisu.error import ConfigError, ConflictError, PropertiesOptionError, SlaveError from tiramisu.error import ConfigError, ConflictError, PropertiesOptionError, SlaveError, APIError
owners.addowner('meta1') owners.addowner('meta1')
owners.addowner('meta2') owners.addowner('meta2')
@ -286,12 +286,14 @@ def test_not_meta():
#raises(ConflictError, "GroupConfig([conf2, conf4], session_id='conf2')") #raises(ConflictError, "GroupConfig([conf2, conf4], session_id='conf2')")
raises(ConflictError, "GroupConfig([conf2, conf2], session_id='conf8')") raises(ConflictError, "GroupConfig([conf2, conf2], session_id='conf8')")
grp = GroupConfig([conf1, conf2]) grp = GroupConfig([conf1, conf2])
raises(ConfigError, "grp.option('od1.i1').value.get()") raises(APIError, "grp.option('od1.i1').value.get()")
conf1, conf2 = grp.config.list() conf1, conf2 = grp.config.list()
errors = grp.value.set('od1.i1', 7) errors = grp.value.set('od1.i1', 7)
assert len(errors) == 0 assert len(errors) == 0
assert grp.config('conf1').option('od1.i1').value.get() == grp.config('conf2').option('od1.i1').value.get() == 7 assert grp.config('conf1').option('od1.i1').value.get() == grp.config('conf2').option('od1.i1').value.get() == 7
assert grp.config('conf1').option('od1.i1').owner.get() is grp.config('conf2').option('od1.i1').owner.get() is owners.user assert grp.config('conf1').option('od1.i1').owner.get() is grp.config('conf2').option('od1.i1').owner.get() is owners.user
grp.option('od1.i1').value.reset()
assert grp.config('conf1').option('od1.i1').owner.get() is grp.config('conf2').option('od1.i1').owner.get() is owners.default
def test_group_find_firsts(): def test_group_find_firsts():

View file

@ -145,7 +145,7 @@ class CommonTiramisuOption(CommonTiramisu):
self._name = name self._name = name
self.subconfig = subconfig self.subconfig = subconfig
# for help() # for help()
if option_bag is not None: if option_bag is not None and self.option_bag.config_bag.context.impl_type != 'group':
self._get_option() self._get_option()
if option_bag.config_bag is not None and self.slave_need_index: if option_bag.config_bag is not None and self.slave_need_index:
self._test_slave_index() self._test_slave_index()
@ -436,8 +436,7 @@ class TiramisuOptionValue(CommonTiramisuOption):
def _m_pop(self, index): def _m_pop(self, index):
"""pop value for a master option (only for master option)""" """pop value for a master option (only for master option)"""
if self.option_bag.option.impl_is_symlinkoption(): assert not self.option_bag.option.impl_is_symlinkoption(), _("can't delete a SymLinkOption")
raise TypeError(_("can't delete a SymLinkOption"))
self.option_bag.config_bag.context.cfgimpl_get_values().reset_master(index, self.option_bag.config_bag.context.cfgimpl_get_values().reset_master(index,
self.option_bag, self.option_bag,
self.subconfig) self.subconfig)
@ -447,28 +446,21 @@ class TiramisuOptionValue(CommonTiramisuOption):
self._test_slave_index() self._test_slave_index()
self.subconfig.delattr(self.option_bag) self.subconfig.delattr(self.option_bag)
def _g_reset(self, def _m_reset(self,
itself=None, itself: bool=True,
children=None): children: bool=False):
"""reset value for a GroupConfig or a MetaConfig""" """reset value for a MetaConfig"""
config_bag = self.option_bag.config_bag
if isinstance(config_bag.context, KernelMetaConfig):
if children is None:
children = False
if itself is None:
itself = True
else:
if children is None:
children = True
if itself is True:
raise APIError(_('cannot remove value in a GroupConfig'))
itself = False
if children: if children:
config_bag = self.option_bag.config_bag
config_bag.context.reset(self.option_bag.path, config_bag.context.reset(self.option_bag.path,
config_bag) config_bag)
if itself: if itself:
self._o_reset() self._o_reset()
def _g_reset(self):
"""reset value for a GroupConfig"""
self.option_bag.config_bag.context.reset(self.option_bag.path)
def _m_len_master(self): def _m_len_master(self):
"""length of master option (only for slave option)""" """length of master option (only for slave option)"""
option = self.option_bag.option option = self.option_bag.option
@ -526,9 +518,14 @@ class TiramisuOptionValue(CommonTiramisuOption):
return self._m_len_master return self._m_len_master
elif name == 'dict' and option.impl_is_optiondescription(): elif name == 'dict' and option.impl_is_optiondescription():
return self._od_dict return self._od_dict
elif not option.impl_is_optiondescription(): elif name == 'reset':
if name == 'reset' and isinstance(self.option_bag.config_bag.context, KernelGroupConfig): if self.option_bag.config_bag.context.impl_type == 'group':
return getattr(self, '_g_' + name) return getattr(self, '_g_' + name)
elif not option.impl_is_optiondescription():
if self.option_bag.config_bag.context.impl_type == 'meta':
return getattr(self, '_m_' + name)
return getattr(self, '_o_' + name)
elif option and not option.impl_is_optiondescription():
return getattr(self, '_o_' + name) return getattr(self, '_o_' + name)
raise APIError(_('{} is unknown').format(name)) raise APIError(_('{} is unknown').format(name))
@ -1049,11 +1046,11 @@ class TiramisuContextConfig(TiramisuContext):
name: str) -> Callable: name: str) -> Callable:
if not name.startswith('_'): if not name.startswith('_'):
try: try:
if isinstance(self.config_bag.context, KernelMetaConfig): if self.config_bag.context.impl_type == 'meta':
return getattr(self, '_m_' + name) return getattr(self, '_m_' + name)
elif isinstance(self.config_bag.context, KernelGroupConfig): elif self.config_bag.context.impl_type == 'group':
return getattr(self, '_g_' + name) return getattr(self, '_g_' + name)
elif isinstance(self.config_bag.context, KernelConfig): elif self.config_bag.context.impl_type == 'config':
return getattr(self, '_c_' + name) return getattr(self, '_c_' + name)
except APIError: # pragma: no cover except APIError: # pragma: no cover
raise APIError(_('{} is unknown').format(name)) raise APIError(_('{} is unknown').format(name))
@ -1112,8 +1109,12 @@ class TiramisuDispatcherOption(TiramisuDispatcher, TiramisuContextOption):
path: str, path: str,
index: Optional[int]=None) -> TiramisuOption: index: Optional[int]=None) -> TiramisuOption:
"""select a option (index only for slave option)""" """select a option (index only for slave option)"""
subconfig, name = self.config_bag.context.cfgimpl_get_home_by_path(path, if self.config_bag.context.impl_type == 'group':
self.config_bag) subpath, name = path.rsplit('.', 1)
subconfig = None
else:
subconfig, name = self.config_bag.context.cfgimpl_get_home_by_path(path,
self.config_bag)
return TiramisuOption(name, return TiramisuOption(name,
path, path,
index, index,

View file

@ -217,11 +217,9 @@ class SubConfig(object):
return self._impl_context() return self._impl_context()
def cfgimpl_get_description(self): def cfgimpl_get_description(self):
if self._impl_descr is None: assert self._impl_descr is not None, _('there is no option description for this config'
raise ConfigError(_('there is no option description for this config' ' (may be GroupConfig)')
' (may be GroupConfig)')) return self._impl_descr
else:
return self._impl_descr
def cfgimpl_get_settings(self): def cfgimpl_get_settings(self):
return self.cfgimpl_get_context()._impl_settings return self.cfgimpl_get_context()._impl_settings
@ -612,7 +610,8 @@ class _CommonConfig(SubConfig):
"abstract base class for the Config, KernelGroupConfig and the KernelMetaConfig" "abstract base class for the Config, KernelGroupConfig and the KernelMetaConfig"
__slots__ = ('_impl_values', __slots__ = ('_impl_values',
'_impl_settings', '_impl_settings',
'_impl_meta') '_impl_meta',
'impl_type')
def _impl_build_all_caches(self): def _impl_build_all_caches(self):
descr = self.cfgimpl_get_description() descr = self.cfgimpl_get_description()
@ -709,7 +708,9 @@ class _CommonConfig(SubConfig):
# ____________________________________________________________ # ____________________________________________________________
class KernelConfig(_CommonConfig): class KernelConfig(_CommonConfig):
"main configuration management entry" "main configuration management entry"
__slots__ = ('__weakref__', '_impl_name') __slots__ = ('__weakref__',
'_impl_name')
impl_type = 'config'
def __init__(self, def __init__(self,
descr, descr,
@ -769,6 +770,7 @@ class KernelGroupConfig(_CommonConfig):
__slots__ = ('__weakref__', __slots__ = ('__weakref__',
'_impl_children', '_impl_children',
'_impl_name') '_impl_name')
impl_type = 'group'
def __init__(self, def __init__(self,
children, children,
@ -822,6 +824,11 @@ class KernelGroupConfig(_CommonConfig):
"""Setattr not in current KernelGroupConfig, but in each children """Setattr not in current KernelGroupConfig, but in each children
""" """
ret = [] ret = []
if isinstance(self, KernelGroupConfig):
commit = True
else:
#Commit only one time
commit = False
for child in self._impl_children: for child in self._impl_children:
cconfig_bag = config_bag.copy() cconfig_bag = config_bag.copy()
cconfig_bag.context = child cconfig_bag.context = child
@ -832,7 +839,7 @@ class KernelGroupConfig(_CommonConfig):
value, value,
cconfig_bag, cconfig_bag,
only_config=only_config, only_config=only_config,
_commit=_commit)) _commit=commit))
else: else:
subconfig, name = child.cfgimpl_get_home_by_path(path, subconfig, name = child.cfgimpl_get_home_by_path(path,
cconfig_bag) cconfig_bag)
@ -846,7 +853,7 @@ class KernelGroupConfig(_CommonConfig):
cconfig_bag) cconfig_bag)
child.setattr(value, child.setattr(value,
option_bag, option_bag,
_commit=_commit) _commit=commit)
except PropertiesOptionError as err: except PropertiesOptionError as err:
ret.append(PropertiesOptionError(err._option_bag, ret.append(PropertiesOptionError(err._option_bag,
err.proptype, err.proptype,
@ -857,9 +864,8 @@ class KernelGroupConfig(_CommonConfig):
err._orig_opt)) err._orig_opt))
except (ValueError, SlaveError) as err: except (ValueError, SlaveError) as err:
ret.append(err) ret.append(err)
#FIXME should commit only here if _commit and not isinstance(self, KernelGroupConfig):
#if _commit: self.cfgimpl_get_values()._p_.commit()
# self._impl_children[0].cfgimpl_get_values()._p_.commit()
return ret return ret
@ -921,6 +927,25 @@ class KernelGroupConfig(_CommonConfig):
def impl_getname(self): def impl_getname(self):
return self._impl_name return self._impl_name
def reset(self,
path):
for child in self._impl_children:
config_bag = ConfigBag(child)
config_bag.remove_validation()
subconfig, name = child.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,
config_bag)
option_bag.config_bag.context = child
child.cfgimpl_get_values().reset(option_bag,
_commit=True)
def getconfig(self, def getconfig(self,
name): name):
for child in self._impl_children: for child in self._impl_children:
@ -931,6 +956,7 @@ class KernelGroupConfig(_CommonConfig):
class KernelMetaConfig(KernelGroupConfig): class KernelMetaConfig(KernelGroupConfig):
__slots__ = tuple() __slots__ = tuple()
impl_type = 'meta'
def __init__(self, def __init__(self,
children, children,
@ -1073,7 +1099,7 @@ class KernelMetaConfig(KernelGroupConfig):
config_bag) config_bag)
option = subconfig.cfgimpl_get_description().impl_getchild(name, option = subconfig.cfgimpl_get_description().impl_getchild(name,
config_bag, config_bag,
self.cfgimpl_get_path()) subconfig.cfgimpl_get_path())
option_bag = OptionBag() option_bag = OptionBag()
option_bag.set_option(option, option_bag.set_option(option,
path, path,
@ -1081,8 +1107,7 @@ class KernelMetaConfig(KernelGroupConfig):
rconfig_bag) rconfig_bag)
for child in self._impl_children: for child in self._impl_children:
option_bag.config_bag.context = child option_bag.config_bag.context = child
child.cfgimpl_get_values().reset(option_bag, child.cfgimpl_get_values().reset(option_bag)
_commit=False)
def new_config(self, def new_config(self,
session_id, session_id,

View file

@ -21,8 +21,6 @@ The storage is the system Tiramisu uses to communicate with various DB.
You can specified a persistent storage. You can specified a persistent storage.
Storage is basic components used to set Config informations in DB. Storage is basic components used to set Config informations in DB.
The primary "entry point" class is the StorageType and it's public
configurator ``set_storage()``.
""" """
@ -84,18 +82,6 @@ memory_storage = StorageType()
memory_storage.set(MEMORY_STORAGE) memory_storage.set(MEMORY_STORAGE)
def set_storage(type_, name): # pragma: optional cover
"""Change storage's configuration
:params name: is the storage name. If storage is already set, cannot
reset storage name
Other attributes are differents according to the selected storage's name
"""
storage_type.set(name)
setting = storage_type.get().setting
def gen_storage_id(session_id, def gen_storage_id(session_id,
config): config):
if session_id is not None: if session_id is not None:
@ -152,4 +138,4 @@ def delete_session(session_id): # pragma: optional cover
del(session) del(session)
__all__ = ('set_storage', 'list_sessions', 'delete_session') __all__ = ('list_sessions', 'delete_session')