TiramisuOption.list() with follower
This commit is contained in:
parent
ad31fc85bb
commit
3641eb39d8
6 changed files with 51 additions and 21 deletions
|
@ -268,7 +268,7 @@ def test_cache_leadership():
|
||||||
assert set(cache.keys()) == set([None, 'ip_admin_eth0', 'ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
|
assert set(cache.keys()) == set([None, 'ip_admin_eth0', 'ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
|
||||||
assert set(cache['ip_admin_eth0'].keys()) == set([None])
|
assert set(cache['ip_admin_eth0'].keys()) == set([None])
|
||||||
assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None])
|
assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None])
|
||||||
assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == set([0, None])
|
assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == {0}
|
||||||
#
|
#
|
||||||
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2', '192.168.1.1'])
|
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2', '192.168.1.1'])
|
||||||
cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()
|
cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()
|
||||||
|
@ -286,7 +286,7 @@ def test_cache_leadership():
|
||||||
assert set(cache.keys()) == set([None, 'ip_admin_eth0', 'ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
|
assert set(cache.keys()) == set([None, 'ip_admin_eth0', 'ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
|
||||||
assert set(cache['ip_admin_eth0'].keys()) == set([None])
|
assert set(cache['ip_admin_eth0'].keys()) == set([None])
|
||||||
assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None])
|
assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None])
|
||||||
assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == set([None, 0, 1])
|
assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == set([0, 1])
|
||||||
#DEL, insert, ...
|
#DEL, insert, ...
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
@ -398,19 +398,20 @@ def test_cache_leader_and_followers():
|
||||||
val_val2_props = {idx_val2: (val1_val2_props, None), None: (set(), None)}
|
val_val2_props = {idx_val2: (val1_val2_props, None), None: (set(), None)}
|
||||||
compare(settings.get_cached(), {None: {None: (set(global_props), None)},
|
compare(settings.get_cached(), {None: {None: (set(global_props), None)},
|
||||||
'val1.val1': {None: (val1_val1_props, None)},
|
'val1.val1': {None: (val1_val1_props, None)},
|
||||||
'val1.val2': val_val2_props})
|
})
|
||||||
compare(values.get_cached(), {'val1.val1': {None: ([None], None, True)}})
|
compare(values.get_cached(), {'val1.val1': {None: ([None], None, True)}})
|
||||||
cfg.value.dict()
|
cfg.value.dict()
|
||||||
#has value
|
#has value
|
||||||
idx_val2 = 0
|
idx_val2 = 0
|
||||||
val_val2 = None
|
val_val2 = None
|
||||||
val_val2_props = {idx_val2: (val1_val2_props, None), None: (set(), None)}
|
val_val2_props = {idx_val2: (val1_val2_props, None)}
|
||||||
compare(settings.get_cached(), {None: {None: (global_props, None)},
|
compare(settings.get_cached(), {None: {None: (global_props, None)},
|
||||||
'val1': {None: (val1_props, None)},
|
'val1': {None: (val1_props, None)},
|
||||||
'val1.val1': {None: (val1_val1_props, None)},
|
'val1.val1': {None: (val1_val1_props, None)},
|
||||||
'val1.val2': val_val2_props})
|
'val1.val2': val_val2_props})
|
||||||
compare(values.get_cached(), {'val1.val1': {None: ([None], None)},
|
compare(values.get_cached(), {'val1.val1': {None: ([None], None)},
|
||||||
'val1.val2': {idx_val2: (val_val2, None)}})
|
'val1.val2': {idx_val2: (val_val2, None)},
|
||||||
|
})
|
||||||
cfg.option('val1.val1').value.set([undefined, undefined])
|
cfg.option('val1.val1').value.set([undefined, undefined])
|
||||||
cfg.value.dict()
|
cfg.value.dict()
|
||||||
cfg.option('val1.val2', 1).value.set('oui')
|
cfg.option('val1.val2', 1).value.set('oui')
|
||||||
|
@ -446,7 +447,7 @@ def test_cache_leader_callback():
|
||||||
cfg.option('val1.val1').value.set([undefined])
|
cfg.option('val1.val1').value.set([undefined])
|
||||||
compare(settings.get_cached(), {None: {None: (set(global_props), None)},
|
compare(settings.get_cached(), {None: {None: (set(global_props), None)},
|
||||||
'val1.val1': {None: (val1_val1_props, None)},
|
'val1.val1': {None: (val1_val1_props, None)},
|
||||||
'val1.val2': {None: (val1_val2_props, None)}})
|
})
|
||||||
|
|
||||||
compare(values.get_cached(), {'val1.val1': {None: ([None], None, True)}})
|
compare(values.get_cached(), {'val1.val1': {None: ([None], None, True)}})
|
||||||
cfg.value.dict()
|
cfg.value.dict()
|
||||||
|
|
|
@ -880,3 +880,17 @@ def test_pprint_not_todict():
|
||||||
def test_property_invalid_type():
|
def test_property_invalid_type():
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
s3 = StrOption("string3", "", default=["string"], default_multi="string", multi=True, properties=(1,))
|
s3 = StrOption("string3", "", default=["string"], default_multi="string", multi=True, properties=(1,))
|
||||||
|
|
||||||
|
|
||||||
|
def test_settings_list_with_follower():
|
||||||
|
leader = StrOption("leader", "leader", default=['leader'], multi=True)
|
||||||
|
option = StrOption("str", "str", default_multi="dhcp", multi=True, properties=frozenset({'disabled'}))
|
||||||
|
ip = StrOption(name="ip",
|
||||||
|
doc="ip",
|
||||||
|
multi=True,
|
||||||
|
properties=frozenset({"basic", "mandatory", Calculation(calc_value, Params(ParamValue('disabled'), kwargs={'condition': ParamOption(option, notraisepropertyerror=True), 'expected': ParamValue("ipv4"), 'reverse_condition': ParamValue(True)}), calc_value_property_help)}),
|
||||||
|
)
|
||||||
|
descr = Leadership("root", "", [leader, option, ip])
|
||||||
|
cfg = Config(OptionDescription('root', 'root', [descr]))
|
||||||
|
cfg.property.read_write()
|
||||||
|
assert len(cfg.option('root').list('all')) == 2
|
||||||
|
|
|
@ -89,12 +89,15 @@ class TiramisuHelp:
|
||||||
class CommonTiramisu(TiramisuHelp):
|
class CommonTiramisu(TiramisuHelp):
|
||||||
_validate_properties = True
|
_validate_properties = True
|
||||||
|
|
||||||
def _get_options_bag(self) -> OptionBag:
|
def _get_options_bag(self,
|
||||||
|
follower_not_apply_requires: bool,
|
||||||
|
) -> OptionBag:
|
||||||
try:
|
try:
|
||||||
options_bag = self._config_bag.context.get_sub_option_bag(self._config_bag,
|
options_bag = self._config_bag.context.get_sub_option_bag(self._config_bag,
|
||||||
self._path,
|
self._path,
|
||||||
self._index,
|
self._index,
|
||||||
self._validate_properties,
|
self._validate_properties,
|
||||||
|
follower_not_apply_requires=follower_not_apply_requires,
|
||||||
)
|
)
|
||||||
except AssertionError as err:
|
except AssertionError as err:
|
||||||
raise ConfigError(str(err))
|
raise ConfigError(str(err))
|
||||||
|
@ -122,7 +125,7 @@ def option_type(typ):
|
||||||
)]
|
)]
|
||||||
kwargs['is_group'] = True
|
kwargs['is_group'] = True
|
||||||
return func(self, options_bag, *args[1:], **kwargs)
|
return func(self, options_bag, *args[1:], **kwargs)
|
||||||
options_bag = self._get_options_bag()
|
options_bag = self._get_options_bag('with_index' not in types)
|
||||||
option = options_bag[-1].option
|
option = options_bag[-1].option
|
||||||
if option.impl_is_optiondescription() and 'optiondescription' in types or \
|
if option.impl_is_optiondescription() and 'optiondescription' in types or \
|
||||||
not option.impl_is_optiondescription() and (
|
not option.impl_is_optiondescription() and (
|
||||||
|
@ -135,12 +138,13 @@ def option_type(typ):
|
||||||
if not option.impl_is_optiondescription() and \
|
if not option.impl_is_optiondescription() and \
|
||||||
not option.impl_is_symlinkoption() and \
|
not option.impl_is_symlinkoption() and \
|
||||||
option.impl_is_follower():
|
option.impl_is_follower():
|
||||||
|
# default is "without_index"
|
||||||
if 'with_index' not in types and 'with_or_without_index' not in types and \
|
if 'with_index' not in types and 'with_or_without_index' not in types and \
|
||||||
self._index is not None:
|
self._index is not None:
|
||||||
msg = _('please do not specify index '
|
msg = _('please do not specify index '
|
||||||
f'({self.__class__.__name__}.{func.__name__})')
|
f'({self.__class__.__name__}.{func.__name__})')
|
||||||
raise ConfigError(_(msg))
|
raise ConfigError(_(msg))
|
||||||
if 'with_index' in types and self._index is None:
|
if self._index is None and 'with_index' in types:
|
||||||
msg = _('please specify index with a follower option '
|
msg = _('please specify index with a follower option '
|
||||||
f'({self.__class__.__name__}.{func.__name__})')
|
f'({self.__class__.__name__}.{func.__name__})')
|
||||||
raise ConfigError(msg)
|
raise ConfigError(msg)
|
||||||
|
@ -251,7 +255,7 @@ class _TiramisuOptionOptionDescription:
|
||||||
option_bag = options_bag[-1]
|
option_bag = options_bag[-1]
|
||||||
return option_bag.path
|
return option_bag.path
|
||||||
|
|
||||||
@option_type(['optiondescription', 'option', 'symlink'])
|
@option_type(['optiondescription', 'option', 'symlink', 'with_or_without_index'])
|
||||||
def has_dependency(self,
|
def has_dependency(self,
|
||||||
options_bag: List[OptionBag],
|
options_bag: List[OptionBag],
|
||||||
self_is_dep=True,
|
self_is_dep=True,
|
||||||
|
@ -355,7 +359,7 @@ class _TiramisuOptionOption(_TiramisuOptionOptionDescription):
|
||||||
return 'optiondescription'
|
return 'optiondescription'
|
||||||
return option_bag.option.get_type()
|
return option_bag.option.get_type()
|
||||||
|
|
||||||
@option_type('option')
|
@option_type(['option', 'with_or_without_index'])
|
||||||
def pattern(self, options_bag: List[OptionBag]) -> str:
|
def pattern(self, options_bag: List[OptionBag]) -> str:
|
||||||
"""Get the option pattern"""
|
"""Get the option pattern"""
|
||||||
option_bag = options_bag[-1]
|
option_bag = options_bag[-1]
|
||||||
|
|
|
@ -539,6 +539,8 @@ def carry_out_calculation(option,
|
||||||
- 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 not option.impl_is_optiondescription() and option.impl_is_follower() and index is None:
|
||||||
|
raise Exception('follower must have index in carry_out_calculation!')
|
||||||
def fake_items(iterator):
|
def fake_items(iterator):
|
||||||
return ((None, i) for i in iterator)
|
return ((None, i) for i in iterator)
|
||||||
args = []
|
args = []
|
||||||
|
|
|
@ -342,6 +342,7 @@ class _SubConfig:
|
||||||
opt.impl_getpath(),
|
opt.impl_getpath(),
|
||||||
None,
|
None,
|
||||||
True,
|
True,
|
||||||
|
follower_not_apply_requires=flatten_leadership,
|
||||||
)[-1],
|
)[-1],
|
||||||
types=types,
|
types=types,
|
||||||
recursive=recursive,
|
recursive=recursive,
|
||||||
|
@ -721,6 +722,7 @@ class _CommonConfig(_SubConfig):
|
||||||
validate_properties: bool,
|
validate_properties: bool,
|
||||||
leadership_length: int=None,
|
leadership_length: int=None,
|
||||||
properties=undefined,
|
properties=undefined,
|
||||||
|
follower_not_apply_requires: bool=False,
|
||||||
) -> List[OptionBag]:
|
) -> List[OptionBag]:
|
||||||
"""Get the suboption for path and the name of the option
|
"""Get the suboption for path and the name of the option
|
||||||
:returns: tuple (config, name)"""
|
:returns: tuple (config, name)"""
|
||||||
|
@ -734,12 +736,12 @@ class _CommonConfig(_SubConfig):
|
||||||
option_bag = bag
|
option_bag = bag
|
||||||
if option_bag.option != option_bag.config_bag.context.get_description():
|
if option_bag.option != option_bag.config_bag.context.get_description():
|
||||||
path = path[len(option_bag.path) + 1:]
|
path = path[len(option_bag.path) + 1:]
|
||||||
path = path.split('.')
|
split_path = path.split('.')
|
||||||
last_idx = len(path) - 1
|
last_idx = len(split_path) - 1
|
||||||
suboption = option_bag.option
|
suboption = option_bag.option
|
||||||
options_bag = []
|
options_bag = []
|
||||||
sub_option_bag = option_bag
|
sub_option_bag = option_bag
|
||||||
for idx, step in enumerate(path):
|
for idx, step in enumerate(split_path):
|
||||||
if not suboption.impl_is_optiondescription():
|
if not suboption.impl_is_optiondescription():
|
||||||
raise TypeError(f'{suboption.impl_getpath()} is not an optiondescription')
|
raise TypeError(f'{suboption.impl_getpath()} is not an optiondescription')
|
||||||
|
|
||||||
|
@ -753,9 +755,9 @@ class _CommonConfig(_SubConfig):
|
||||||
)
|
)
|
||||||
if idx == last_idx:
|
if idx == last_idx:
|
||||||
option_index = index
|
option_index = index
|
||||||
else:
|
apply_requires = not follower_not_apply_requires or \
|
||||||
option_index = None
|
option.impl_is_optiondescription() or \
|
||||||
if idx == last_idx:
|
not option.impl_is_follower()
|
||||||
if option_index is not None:
|
if option_index is not None:
|
||||||
if option.impl_is_optiondescription() or \
|
if option.impl_is_optiondescription() or \
|
||||||
option.impl_is_symlinkoption() or \
|
option.impl_is_symlinkoption() or \
|
||||||
|
@ -771,11 +773,14 @@ class _CommonConfig(_SubConfig):
|
||||||
f'"{option.impl_get_display_name()}"'))
|
f'"{option.impl_get_display_name()}"'))
|
||||||
option_properties = properties
|
option_properties = properties
|
||||||
else:
|
else:
|
||||||
|
option_index = None
|
||||||
|
apply_requires = True
|
||||||
option_properties = undefined
|
option_properties = undefined
|
||||||
sub_option_bag = OptionBag(option,
|
sub_option_bag = OptionBag(option,
|
||||||
option_index,
|
option_index,
|
||||||
option_bag.config_bag,
|
option_bag.config_bag,
|
||||||
properties=option_properties,
|
properties=option_properties,
|
||||||
|
apply_requires=apply_requires,
|
||||||
)
|
)
|
||||||
if validate_properties:
|
if validate_properties:
|
||||||
self.get_settings().validate_properties(sub_option_bag)
|
self.get_settings().validate_properties(sub_option_bag)
|
||||||
|
|
|
@ -165,16 +165,20 @@ class Leadership(OptionDescription):
|
||||||
dyn = self
|
dyn = self
|
||||||
values = config_bag.context.get_values()
|
values = config_bag.context.get_values()
|
||||||
for idx, follower in enumerate(dyn.get_children(config_bag)):
|
for idx, follower in enumerate(dyn.get_children(config_bag)):
|
||||||
|
if not idx:
|
||||||
|
# it's a master
|
||||||
|
apply_requires = True
|
||||||
|
indexes = [None]
|
||||||
|
else:
|
||||||
|
apply_requires = False
|
||||||
|
indexes = range(len(value))
|
||||||
foption_bag = OptionBag(follower,
|
foption_bag = OptionBag(follower,
|
||||||
None,
|
None,
|
||||||
config_bag,
|
config_bag,
|
||||||
|
apply_requires=apply_requires,
|
||||||
)
|
)
|
||||||
if 'force_store_value' not in foption_bag.properties:
|
if 'force_store_value' not in foption_bag.properties:
|
||||||
continue
|
continue
|
||||||
if idx == 0:
|
|
||||||
indexes = [None]
|
|
||||||
else:
|
|
||||||
indexes = range(len(value))
|
|
||||||
for index in indexes:
|
for index in indexes:
|
||||||
foption_bag_index = OptionBag(follower,
|
foption_bag_index = OptionBag(follower,
|
||||||
index,
|
index,
|
||||||
|
|
Loading…
Reference in a new issue