1116 lines
43 KiB
Python
1116 lines
43 KiB
Python
"""test API
|
|
"""
|
|
#import weakref
|
|
import pytest
|
|
#import warnings
|
|
#from copy import copy
|
|
#from py.test import raises
|
|
#from collections import OrderedDict
|
|
#from .autopath import do_autopath
|
|
#do_autopath()
|
|
#from tiramisu import Config, MetaConfig, \
|
|
# StrOption, SymLinkOption, OptionDescription, Leadership, DynOptionDescription, \
|
|
# submulti, undefined, owners, Params, ParamOption, Calculation
|
|
from tiramisu import Config, DynOptionDescription, OptionDescription, Leadership, \
|
|
StrOption, IntOption, ChoiceOption, SymLinkOption, \
|
|
Calculation, Params, ParamValue, ParamOption, ParamSelfOption, ParamInformation, ParamSelfInformation, ParamIndex, ParamSuffix, \
|
|
submulti, calc_value, owners
|
|
from tiramisu.i18n import _
|
|
from tiramisu.option.baseoption import BaseOption
|
|
from tiramisu.error import ConfigError, ConstError, PropertiesOptionError, LeadershipError
|
|
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
|
|
|
|
|
|
def return_var(val=None):
|
|
return val
|
|
|
|
|
|
def return_var_disabled(multi, p=None):
|
|
if p is not None:
|
|
multi = p
|
|
if multi:
|
|
return []
|
|
return None
|
|
|
|
|
|
def return_val(multi):
|
|
if multi:
|
|
return ['val']
|
|
return 'val'
|
|
|
|
|
|
def return_property():
|
|
return 'prop'
|
|
|
|
|
|
def return_disabled(var=None):
|
|
return 'disabled'
|
|
|
|
|
|
def return_validator(self, other):
|
|
return self == other
|
|
|
|
|
|
def build_variables(*,
|
|
mandatory=False,
|
|
multi=False,
|
|
leadership=False,
|
|
dynoptiondescription=False,
|
|
parent_variables=[],
|
|
dynamic=False,
|
|
hidden=False,
|
|
):
|
|
base_name = 'str_'
|
|
if mandatory:
|
|
properties = ['mandatory']
|
|
base_name += 'mandatory_'
|
|
else:
|
|
properties = []
|
|
if multi is True:
|
|
base_name += 'multi_'
|
|
elif multi is submulti:
|
|
base_name += 'submulti_'
|
|
if leadership:
|
|
param_multi = multi is submulti
|
|
else:
|
|
param_multi = multi
|
|
if not param_multi:
|
|
str1_5_informations = {'info': 'value'}
|
|
cfg_informations = Calculation(return_var, Params(ParamInformation('cfg_key')))
|
|
else:
|
|
str1_5_informations = {'info': ['value']}
|
|
cfg_informations = [Calculation(return_var, Params(ParamInformation('cfg_key')))]
|
|
if leadership:
|
|
base_name += 'deps_follower_0_'
|
|
if dynamic or dynoptiondescription:
|
|
base_name += 'dynamic_'
|
|
if hidden:
|
|
base_name += 'hidden_'
|
|
str1 = StrOption(base_name + 'information_deps',
|
|
'',
|
|
multi=multi,
|
|
properties=tuple(properties),
|
|
informations=str1_5_informations,
|
|
)
|
|
str2 = StrOption(base_name + 'disabled_deps',
|
|
'',
|
|
multi=multi,
|
|
properties=tuple(properties + ['disabled']),
|
|
)
|
|
str3_name = base_name + 'calc_property_param_disabled'
|
|
if not leadership:
|
|
str3_name += '_deps'
|
|
str3 = StrOption(str3_name,
|
|
'',
|
|
multi=multi,
|
|
properties=tuple(properties + [Calculation(return_disabled, Params(ParamOption(str2, notraisepropertyerror=True)))]),
|
|
)
|
|
choice = ChoiceOption(base_name + 'choice_deps',
|
|
'',
|
|
values=('val1', 'val2'),
|
|
multi=multi,
|
|
properties=tuple(properties),
|
|
)
|
|
variables = [str1,
|
|
str2,
|
|
StrOption(base_name + 'calc_default',
|
|
'',
|
|
Calculation(return_val, Params(ParamValue(param_multi))),
|
|
multi=multi,
|
|
properties=tuple(properties),
|
|
),
|
|
StrOption(base_name + 'calc_default_param',
|
|
'',
|
|
Calculation(return_var, Params(ParamOption(str1))),
|
|
multi=multi,
|
|
properties=tuple(properties)
|
|
),
|
|
StrOption(base_name + 'calc_default_param_disable',
|
|
'',
|
|
Calculation(return_var_disabled, Params((ParamOption(str2, notraisepropertyerror=True), ParamValue(param_multi)))),
|
|
multi=multi,
|
|
properties=tuple(properties),
|
|
),
|
|
StrOption(base_name + 'calc_property',
|
|
'',
|
|
multi=multi,
|
|
properties=tuple(properties + [Calculation(return_property)]),
|
|
),
|
|
StrOption(base_name + 'calc_property_disabled',
|
|
'',
|
|
multi=multi,
|
|
properties=tuple(properties + [Calculation(return_disabled, Params(ParamOption(str1)))]),
|
|
),
|
|
StrOption(base_name + 'calc_property_disabled_self',
|
|
'',
|
|
multi=multi,
|
|
properties=tuple(properties + [Calculation(return_disabled, Params(ParamSelfOption()))]),
|
|
),
|
|
StrOption(base_name + 'validator',
|
|
'',
|
|
multi=multi,
|
|
properties=tuple(properties),
|
|
validators=[Calculation(return_validator, Params((ParamSelfOption(), ParamOption(str1))))],
|
|
),
|
|
StrOption(base_name + 'calc_default_information',
|
|
'',
|
|
Calculation(return_var, Params(ParamInformation('info', option=str1))),
|
|
multi=multi,
|
|
properties=tuple(properties),
|
|
),
|
|
StrOption(base_name + 'calc_default_information_cfg',
|
|
'',
|
|
cfg_informations,
|
|
multi=multi,
|
|
properties=tuple(properties),
|
|
),
|
|
str3,
|
|
StrOption(base_name + 'calc_default_information_self',
|
|
'',
|
|
Calculation(return_var, Params(ParamSelfInformation('info'))),
|
|
multi=multi,
|
|
properties=tuple(properties),
|
|
informations=str1_5_informations,
|
|
),
|
|
choice,
|
|
]
|
|
if not leadership:
|
|
sym1 = SymLinkOption(base_name + 'symlink_information_deps', str1)
|
|
sym2 = SymLinkOption(base_name + 'symlink_disabled_deps', str2)
|
|
variables.extend([sym1,
|
|
sym2,
|
|
SymLinkOption(base_name + 'symlink_calc_property_disabled_deps', str3),
|
|
SymLinkOption(base_name + 'symlink_choice_deps', choice),
|
|
StrOption(base_name + 'calc_default_param_sym',
|
|
'',
|
|
Calculation(return_var, Params(ParamOption(sym1))),
|
|
multi=multi,
|
|
properties=tuple(properties)
|
|
),
|
|
StrOption(base_name + 'calc_default_param_disable_sym',
|
|
'',
|
|
Calculation(return_var_disabled, Params((ParamOption(sym2, notraisepropertyerror=True), ParamValue(param_multi)))),
|
|
multi=multi,
|
|
properties=tuple(properties),
|
|
),
|
|
StrOption(base_name + 'calc_property_param_disabled_sym',
|
|
'',
|
|
multi=multi,
|
|
properties=tuple(properties + [Calculation(return_disabled, Params(ParamOption(sym2, notraisepropertyerror=True)))]),
|
|
)
|
|
])
|
|
else:
|
|
default = Calculation(calc_value, Params(ParamIndex()))
|
|
if param_multi:
|
|
default = [default]
|
|
variables.append(IntOption(base_name + 'calc_default_index',
|
|
'',
|
|
default,
|
|
multi=multi,
|
|
properties=tuple(properties),
|
|
)
|
|
)
|
|
if dynoptiondescription:
|
|
default = Calculation(calc_value, Params(ParamSuffix()))
|
|
if param_multi:
|
|
default = [default]
|
|
variables.append(StrOption(base_name + 'calc_default_suffix',
|
|
'',
|
|
default,
|
|
multi=multi,
|
|
properties=tuple(properties),
|
|
)
|
|
)
|
|
if not leadership:
|
|
for idx, parent in enumerate(parent_variables):
|
|
if not parent:
|
|
continue
|
|
base_name_2 = 'parent_'
|
|
if dynamic or dynoptiondescription:
|
|
base_name_2 += 'dynamic_'
|
|
if hidden:
|
|
base_name_2 += 'hidden_'
|
|
base_name_3 = base_name_2
|
|
if mandatory:
|
|
base_name_2 += 'mandatory_'
|
|
variables.extend([
|
|
StrOption(f'{base_name_2}calc_default_param_{idx}',
|
|
'',
|
|
Calculation(return_var, Params(ParamOption(parent[0]))),
|
|
properties=tuple(properties),
|
|
),
|
|
StrOption(f'{base_name_2}calc_property_disabled_{idx}',
|
|
'',
|
|
properties=tuple(properties + [Calculation(return_disabled, Params(ParamOption(parent[0])))]),
|
|
),
|
|
StrOption(f'{base_name_2}validator_{idx}',
|
|
'',
|
|
properties=tuple(properties),
|
|
validators=[Calculation(return_validator, Params((ParamSelfOption(), ParamOption(parent[0]))))],
|
|
),
|
|
StrOption(f'{base_name_2}calc_default_information_{idx}',
|
|
'',
|
|
Calculation(return_var, Params(ParamInformation('info', option=parent[0]))),
|
|
properties=tuple(properties),
|
|
),
|
|
SymLinkOption(f'{base_name_3}symlink_information_deps_{idx}', parent[0]),
|
|
#
|
|
StrOption(f'{base_name_2}calc_property_param_disabled_{idx}',
|
|
'',
|
|
properties=tuple(properties + [Calculation(return_disabled, Params(ParamOption(parent[1], notraisepropertyerror=True)))]),
|
|
),
|
|
StrOption(f'{base_name_2}calc_default_param_disable_{idx}',
|
|
'',
|
|
Calculation(return_var_disabled, Params((ParamOption(parent[1], notraisepropertyerror=True), ParamValue(False)))),
|
|
properties=tuple(properties),
|
|
),
|
|
SymLinkOption(f'{base_name_3}symlink_disabled_deps_{idx}', parent[1]),
|
|
])
|
|
return variables
|
|
|
|
|
|
def build_options_for_parent(dynoptiondescription,
|
|
hidden,
|
|
):
|
|
base_name = 'parent_'
|
|
if dynoptiondescription:
|
|
base_name += 'dynamic_'
|
|
if hidden:
|
|
base_name += 'hidden_'
|
|
return (StrOption(base_name + 'information_deps', '', informations={'info': 'parent_value'}),
|
|
StrOption(base_name + 'disabled_deps',
|
|
'',
|
|
properties=('disabled',),
|
|
),
|
|
)
|
|
|
|
|
|
def build_root_variables(*,
|
|
tree,
|
|
**kwargs,
|
|
):
|
|
parent_variables = []
|
|
dynamic = False
|
|
hidden = False
|
|
hidden_idx = 0
|
|
for t in tree:
|
|
if hidden:
|
|
hidden_idx += 1
|
|
if t.startswith('h'):
|
|
t = t[1:]
|
|
hidden = True
|
|
if t == 'dod':
|
|
dynamic=True
|
|
parent_variables.append(build_options_for_parent(dynamic, hidden))
|
|
variables = build_variables(**kwargs, parent_variables=parent_variables, dynamic=dynamic, hidden=hidden)
|
|
follower_params = kwargs.copy()
|
|
follower_params['leadership'] = True
|
|
if 'multi' in follower_params and follower_params['multi']:
|
|
follower_params['multi'] = submulti
|
|
else:
|
|
follower_params['multi'] = True
|
|
suffix = ''
|
|
if dynamic:
|
|
suffix += '_dynamic'
|
|
lsuffix = suffix
|
|
if hidden:
|
|
lsuffix += '_hidden'
|
|
variables.append(Leadership('leadership' + lsuffix, '', [StrOption('leader_multi_deps' + lsuffix,
|
|
'',
|
|
default=['l1', 'l2'],
|
|
multi=True,
|
|
),
|
|
] + build_variables(**follower_params, parent_variables=parent_variables, dynamic=dynamic, hidden=hidden),
|
|
))
|
|
suffixes = StrOption('suffixes_multi_deps' + lsuffix, '', ['d1', 'd2'], multi=True)
|
|
variables.append(suffixes)
|
|
dynamic_name = 'dynamic_'
|
|
if hidden:
|
|
dynamic_name += 'hidden_'
|
|
variables.append(DynOptionDescription(dynamic_name, '', build_variables(**kwargs, dynoptiondescription=True, parent_variables=parent_variables, dynamic=dynamic, hidden=hidden), Calculation(return_var, Params(ParamOption(suffixes)))))
|
|
tree.reverse()
|
|
for idx, t in enumerate(tree):
|
|
lsuffix = suffix
|
|
variables.extend(parent_variables.pop(-1))
|
|
if hidden and idx <= hidden_idx:
|
|
lsuffix = '_hidden' + suffix
|
|
if t.startswith('h'):
|
|
t = t[1:]
|
|
properties = frozenset(['hidden'])
|
|
else:
|
|
properties = frozenset()
|
|
if t == 'dod':
|
|
variables = [DynOptionDescription('tree_dynamic' + lsuffix, '', variables, Calculation(return_var, Params(ParamValue(['var1', 'var2']))), properties=properties)]
|
|
else:
|
|
variables = [OptionDescription('tree' + lsuffix, '', variables, properties=properties)]
|
|
od = OptionDescription('root', 'root', variables, informations={'cfg_key': 'cfg_info'})
|
|
return od
|
|
|
|
|
|
PARAMS = [{},
|
|
{'mandatory': True},
|
|
{'multi': True},
|
|
{'mandatory': True, 'multi': True},
|
|
]
|
|
OD = [
|
|
[],
|
|
['od'],
|
|
['od', 'od'],
|
|
['hod'],
|
|
['hod', 'od'],
|
|
['od', 'hod'],
|
|
['dod'],
|
|
['hdod'],
|
|
['dod', 'dod'],
|
|
['hdod', 'dod'],
|
|
['dod', 'hdod'],
|
|
['dod', 'od'],
|
|
['dod', 'od', 'dod'],
|
|
['dod', 'od', 'dod', 'od'],
|
|
['dod', 'od', 'dod', 'hod'],
|
|
['dod', 'od', 'hdod', 'od'],
|
|
]
|
|
|
|
|
|
SCENARII = []
|
|
for od in OD:
|
|
SCENARII.append({'tree': od})
|
|
for params in PARAMS:
|
|
SCENARII[-1].update(params)
|
|
|
|
|
|
@pytest.fixture(scope="function", params=SCENARII)
|
|
def root_variables(request):
|
|
try:
|
|
owners.addowner('test')
|
|
except ConstError:
|
|
pass
|
|
ALLOWED_LEADER_PROPERTIES.add('new')
|
|
return build_root_variables(**request.param)
|
|
|
|
from pprint import pprint as pprint2
|
|
#pprint = pprint2
|
|
def pprint(a):
|
|
print()
|
|
def p(b):
|
|
ret = {}
|
|
for i, j in b.items():
|
|
k = i.name()
|
|
if isinstance(j, dict):
|
|
ret[k] = p(j)
|
|
else:
|
|
ret[k] = j
|
|
return ret
|
|
c = p(a)
|
|
|
|
pprint2(c)
|
|
|
|
|
|
def walk(cfg, idx=0):
|
|
yield cfg
|
|
for opt in cfg.list():
|
|
# print(' ' * idx, opt.path())
|
|
if opt.isoptiondescription():
|
|
yield from walk(opt, idx + 2)
|
|
else:
|
|
yield(opt)
|
|
|
|
|
|
def _test_option(option, without_index=False):
|
|
# optiondescription and option
|
|
name = option.name()
|
|
opt = option.get()
|
|
if opt is None:
|
|
# it's a 'root' object
|
|
assert name is None
|
|
assert option.isoptiondescription()
|
|
assert not option.isleadership()
|
|
assert not option.isdynamic()
|
|
assert option.doc() is 'root'
|
|
assert option.description() == 'root'
|
|
assert option.path() is None
|
|
assert not option.has_dependency()
|
|
else:
|
|
assert isinstance(name, str)
|
|
assert isinstance(opt, BaseOption)
|
|
assert (isinstance(opt, OptionDescription) and option.isoptiondescription()) or (not isinstance(opt, OptionDescription) and not option.isoptiondescription())
|
|
if option.isoptiondescription():
|
|
assert ('leadership' not in name and not option.isleadership()) or ('leadership' in name and option.isleadership())
|
|
if option.isleadership():
|
|
assert 'leader_' in option.leader().name()
|
|
else:
|
|
with pytest.raises(ConfigError):
|
|
option.leader()
|
|
else:
|
|
with pytest.raises(ConfigError):
|
|
option.leadership()
|
|
assert option.isdynamic() == ('dynamic' in name)
|
|
if option.isdynamic():
|
|
suffixes = []
|
|
for path in option.path().split('.'):
|
|
if 'dynamicvar1' in path:
|
|
suffixes.append('var1')
|
|
if 'dynamicvar2' in path:
|
|
suffixes.append('var2')
|
|
if 'd1' in path:
|
|
suffixes.append('d1')
|
|
if 'd2' in path:
|
|
suffixes.append('d2')
|
|
assert option.suffixes() == suffixes
|
|
assert isinstance(option.doc(), str) and option.doc() == name
|
|
assert isinstance(option.description(), str) and option.description() == ''
|
|
assert isinstance(option.path(), str) and (option.path() == name or option.path().endswith(f'.{name}'))
|
|
if '_deps' in name:
|
|
assert option.has_dependency(False)
|
|
assert option.dependencies()
|
|
else:
|
|
assert not option.has_dependency(False)
|
|
assert not option.dependencies()
|
|
if option.isoptiondescription():
|
|
assert option.type() == 'optiondescription'
|
|
elif 'index' in name:
|
|
assert option.type() == _('integer')
|
|
elif 'choice' in name:
|
|
assert option.type() == _('choice')
|
|
else:
|
|
assert option.type() == _('string')
|
|
# only option
|
|
if option.isoptiondescription():
|
|
with pytest.raises(ConfigError):
|
|
option.ismulti()
|
|
with pytest.raises(ConfigError):
|
|
option.issubmulti()
|
|
with pytest.raises(ConfigError):
|
|
option.isleader()
|
|
with pytest.raises(ConfigError):
|
|
option.isfollower()
|
|
with pytest.raises(ConfigError):
|
|
option.issymlinkoption()
|
|
with pytest.raises(ConfigError):
|
|
option.default()
|
|
with pytest.raises(ConfigError):
|
|
option.defaultmulti()
|
|
with pytest.raises(ConfigError):
|
|
option.pattern()
|
|
with pytest.raises(ConfigError):
|
|
option.index()
|
|
else:
|
|
assert 'symlink' in name and option.issymlinkoption() or 'symlink' not in name and not option.issymlinkoption()
|
|
try:
|
|
assert 'multi' in name and option.ismulti() or 'multi' not in name and not option.ismulti()
|
|
except Exception as err:
|
|
print(err)
|
|
print(option.value.get())
|
|
raise Exception('err')
|
|
assert 'submulti' in name and option.issubmulti() or 'submulti' not in name and not option.issubmulti()
|
|
if option.issymlinkoption():
|
|
assert not option.isleader()
|
|
assert not option.isfollower()
|
|
with pytest.raises(ConfigError):
|
|
option.pattern()
|
|
assert option.index() is None
|
|
else:
|
|
assert 'leader' in name and option.isleader() or 'leader' not in name and not option.isleader()
|
|
assert 'follower' in name and option.isfollower() or 'follower' not in name and not option.isfollower()
|
|
if option.isfollower() and not without_index:
|
|
assert option.index() in [0, 1]
|
|
else:
|
|
assert option.index() is None
|
|
if option.type() == _('integer'):
|
|
assert option.pattern() == '^[0-9]+$'
|
|
else:
|
|
assert not option.pattern()
|
|
default = option.default()
|
|
if 'calc_default' in name:
|
|
assert isinstance(default, Calculation) or (isinstance(default, list) and len(default) == 1 and isinstance(default[0], Calculation))
|
|
elif 'suffixes_multi' in name:
|
|
assert default == ['d1', 'd2']
|
|
elif 'leader_multi' in name:
|
|
assert default == ['l1', 'l2']
|
|
elif 'multi' in name:
|
|
assert default == []
|
|
else:
|
|
assert default is None
|
|
if option.issubmulti():
|
|
assert option.defaultmulti() == []
|
|
elif option.ismulti():
|
|
assert option.defaultmulti() is None
|
|
|
|
|
|
def _test_information(cfg, option, without_index=False):
|
|
name = option.name()
|
|
# list
|
|
lst = option.information.list()
|
|
if name is None:
|
|
assert lst == {'cfg_key', 'doc'}
|
|
elif 'information' in name and ('information_self' in name or 'calc_default' not in name):
|
|
assert lst == {'doc', 'info'}
|
|
else:
|
|
assert lst == {'doc'}
|
|
# get
|
|
assert option.information.get('unknown', 'no_value') == 'no_value'
|
|
if name is None:
|
|
assert option.information.get('doc') == 'root'
|
|
else:
|
|
assert option.information.get('doc') == ''
|
|
if 'cfg_key' in lst:
|
|
assert option.information.get('cfg_key') == 'cfg_info'
|
|
if 'info' in lst:
|
|
if 'parent' in name:
|
|
value = 'parent_value'
|
|
else:
|
|
value = 'value'
|
|
if 'multi' in name:
|
|
value = [value]
|
|
assert option.information.get('info') == value
|
|
# set
|
|
if not option.isoptiondescription() and option.issymlinkoption():
|
|
with pytest.raises(ConfigError):
|
|
option.information.set('new', 'value')
|
|
with pytest.raises(ConfigError):
|
|
option.information.reset('new')
|
|
return
|
|
if not option.isoptiondescription() and option.isfollower() and not without_index:
|
|
# index is not allowed
|
|
with pytest.raises(ConfigError):
|
|
option.information.set('new', 'value')
|
|
with pytest.raises(ConfigError):
|
|
option.information.reset('new')
|
|
option.information.get('doc')
|
|
with pytest.raises(ConfigError):
|
|
option.information.set('new', 'value')
|
|
option.information.list()
|
|
with pytest.raises(ConfigError):
|
|
option.information.remove('new')
|
|
else:
|
|
option.information.set('new', 'value')
|
|
assert option.information.get('new') == 'value'
|
|
assert option.information.list() == lst | {'new'}
|
|
option.information.set('new', 'value2')
|
|
assert option.information.get('new') == 'value2'
|
|
assert option.information.list() == lst | {'new'}
|
|
# remove
|
|
option.information.remove('new')
|
|
assert option.information.list() == lst
|
|
with pytest.raises(ValueError):
|
|
option.information.remove('doc')
|
|
|
|
# Value
|
|
def _test_value(cfg, option, unrestraint=False, without_index=False):
|
|
#owner
|
|
name = option.name()
|
|
if option.isoptiondescription():
|
|
_test_owner_optiondescription(name, option)
|
|
_test_value_optiondescription(name, option, unrestraint)
|
|
elif not unrestraint and 'disabled' in name:
|
|
if not without_index or 'calc_property' not in name or 'hidden' in name:
|
|
_test_owner_disabled(name, option, without_index)
|
|
_test_value_disabled(name, option, without_index)
|
|
else:
|
|
_test_owner_without_index(option)
|
|
_test_value_without_index(option)
|
|
elif not unrestraint and 'hidden' in name:
|
|
_test_owner_disabled(name, option, without_index)
|
|
_test_value_disabled(name, option, without_index)
|
|
elif without_index:
|
|
_test_owner_without_index(option)
|
|
_test_value_without_index(option)
|
|
else:
|
|
_test_owner(option, without_index)
|
|
_test_value_normal(name, cfg, option, unrestraint, without_index)
|
|
|
|
|
|
def _test_owner_optiondescription(name, option):
|
|
with pytest.raises((AttributeError, ConfigError)):
|
|
option.owner.isdefault()
|
|
if name is None:
|
|
assert option.owner.get() == owners.user
|
|
option.owner.set(owners.test)
|
|
assert option.owner.get() == owners.test
|
|
option.owner.set(owners.user)
|
|
assert option.owner.get() == owners.user
|
|
else:
|
|
with pytest.raises(ConfigError):
|
|
option.owner.get()
|
|
with pytest.raises(ConfigError):
|
|
option.owner.set(owners.test)
|
|
|
|
|
|
def _test_value_optiondescription(name, option, unrestraint):
|
|
if not unrestraint and name and 'hidden' in name:
|
|
with pytest.raises(PropertiesOptionError):
|
|
option.value.get()
|
|
else:
|
|
assert isinstance(option.value.get(), dict)
|
|
if name != None:
|
|
with pytest.raises(ConfigError):
|
|
option.value.set('value')
|
|
with pytest.raises(ConfigError):
|
|
option.value.reset()
|
|
with pytest.raises(ConfigError):
|
|
option.value.default()
|
|
with pytest.raises(ConfigError):
|
|
option.value.valid()
|
|
with pytest.raises(ConfigError):
|
|
option.value.list()
|
|
with pytest.raises(ConfigError):
|
|
option.value.pop(1)
|
|
with pytest.raises(ConfigError):
|
|
option.value.len()
|
|
|
|
|
|
def _test_owner_disabled(name, option, without_index):
|
|
if without_index:
|
|
errtype = ConfigError
|
|
else:
|
|
errtype = PropertiesOptionError
|
|
with pytest.raises(errtype):
|
|
option.owner.isdefault()
|
|
with pytest.raises(errtype):
|
|
option.owner.get()
|
|
if 'symlink' in name:
|
|
with pytest.raises(ConfigError):
|
|
option.owner.set(owners.test)
|
|
else:
|
|
with pytest.raises(errtype):
|
|
option.owner.set(owners.test)
|
|
|
|
|
|
def _test_owner_without_index(option):
|
|
with pytest.raises(ConfigError):
|
|
option.owner.isdefault()
|
|
with pytest.raises(ConfigError):
|
|
option.owner.get()
|
|
with pytest.raises(ConfigError):
|
|
option.owner.set(owners.test)
|
|
|
|
|
|
def _test_owner(option, without_index):
|
|
if without_index:
|
|
with pytest.raises(ConfigError):
|
|
assert option.owner.isdefault()
|
|
with pytest.raises(ConfigError):
|
|
assert option.owner.get()
|
|
else:
|
|
assert option.owner.isdefault()
|
|
assert option.owner.get() == owners.default
|
|
with pytest.raises(ConfigError):
|
|
# not availlable for symlink or without index or option has default value
|
|
option.owner.set(owners.test)
|
|
|
|
|
|
def _test_value_disabled(name, option, without_index):
|
|
if without_index:
|
|
errtype = ConfigError
|
|
else:
|
|
errtype = PropertiesOptionError
|
|
with pytest.raises(errtype):
|
|
option.value.get()
|
|
if 'symlink' in name:
|
|
with pytest.raises(ConfigError):
|
|
option.value.set('val')
|
|
with pytest.raises(ConfigError):
|
|
option.value.reset()
|
|
with pytest.raises(ConfigError):
|
|
option.value.valid()
|
|
else:
|
|
with pytest.raises(errtype):
|
|
option.value.set('val')
|
|
with pytest.raises(errtype):
|
|
option.value.reset()
|
|
with pytest.raises(errtype):
|
|
option.value.valid()
|
|
#if without_index:
|
|
# assert option.value.len() == 2
|
|
# if 'choice' in name:
|
|
# assert option.value.list() == ('val1', 'val2')
|
|
# else:
|
|
# with pytest.raises(ConfigError):
|
|
# option.value.list()
|
|
#else:
|
|
if 'leader' in name or 'follower' in name:
|
|
with pytest.raises(PropertiesOptionError):
|
|
option.value.len()
|
|
else:
|
|
with pytest.raises(ConfigError):
|
|
option.value.len()
|
|
if 'choice' in name and 'symlink' not in name:
|
|
with pytest.raises(errtype):
|
|
option.value.list()
|
|
else:
|
|
with pytest.raises(ConfigError):
|
|
option.value.list()
|
|
|
|
|
|
def _test_value_without_index(option):
|
|
with pytest.raises(ConfigError):
|
|
option.value.get()
|
|
with pytest.raises(ConfigError):
|
|
option.value.set('val')
|
|
with pytest.raises(ConfigError):
|
|
option.value.reset()
|
|
with pytest.raises(ConfigError):
|
|
option.value.valid()
|
|
with pytest.raises(ConfigError):
|
|
option.value.list()
|
|
assert option.value.len() == 2
|
|
|
|
|
|
def _get_value(name, option, unrestraint):
|
|
if 'calc_default_information' in name:
|
|
if 'calc_default_information_cfg' in name:
|
|
value = 'cfg_info'
|
|
elif 'parent' in name:
|
|
value = 'parent_value'
|
|
else:
|
|
value = 'value'
|
|
if 'multi' in name:
|
|
value = [value]
|
|
elif 'calc_default_suffix' in name:
|
|
value = option.suffixes()[-1]
|
|
if 'multi' in name:
|
|
value = [value]
|
|
elif 'calc_default_index' in name:
|
|
value = option.index()
|
|
if 'multi' in name:
|
|
value = [value]
|
|
elif 'calc_default' in name and 'calc_default_param' not in name:
|
|
value = 'val'
|
|
if 'multi' in name:
|
|
value = [value]
|
|
elif 'suffixes_multi' in name:
|
|
value = ['d1', 'd2']
|
|
elif 'leader_multi_deps' in name:
|
|
value = ['l1', 'l2']
|
|
elif 'multi' in name:
|
|
value = []
|
|
else:
|
|
value = None
|
|
return value
|
|
|
|
|
|
def _test_value_normal(name, cfg, option, unrestraint, without_index):
|
|
#value
|
|
value = _get_value(name, option, unrestraint)
|
|
if without_index:
|
|
with pytest.raises(ConfigError):
|
|
option.value.get()
|
|
else:
|
|
assert option.value.get() == value
|
|
#set
|
|
if option.issymlinkoption() or without_index:
|
|
with pytest.raises(ConfigError):
|
|
option.value.set(owners.test)
|
|
with pytest.raises(ConfigError):
|
|
option.value.reset()
|
|
with pytest.raises(ConfigError):
|
|
option.value.valid()
|
|
if without_index:
|
|
assert option.value.len() == 2
|
|
if 'choice' in name:
|
|
assert option.value.list() == ('val1', 'val2')
|
|
else:
|
|
with pytest.raises(ConfigError):
|
|
option.value.list()
|
|
else:
|
|
with pytest.raises(ConfigError):
|
|
option.value.len()
|
|
with pytest.raises(ConfigError):
|
|
option.value.list()
|
|
else:
|
|
if option.type() == _('string'):
|
|
new_value = 'new_value'
|
|
new_value2 = 'new_value1'
|
|
new_value3 = 'new_value2'
|
|
elif option.type() == _('integer'):
|
|
new_value = 10
|
|
new_value2 = 11
|
|
new_value3 = 12
|
|
elif 'choice' in name:
|
|
new_value = 'val2'
|
|
new_value2 = 'val1'
|
|
if 'multi' in name:
|
|
new_value = [new_value, new_value2]
|
|
option.value.set(new_value)
|
|
assert option.value.get() == new_value
|
|
assert not option.owner.isdefault()
|
|
assert option.owner.get() == owners.user
|
|
#
|
|
option.owner.set(owners.test)
|
|
assert option.owner.get() == owners.test
|
|
option.value.set(new_value)
|
|
assert option.owner.get() == owners.user
|
|
cfg.owner.set(owners.test)
|
|
option.value.set(new_value)
|
|
assert option.owner.get() == owners.test
|
|
cfg.owner.set(owners.user)
|
|
#
|
|
if 'leader' in name:
|
|
option.value.set(new_value + [new_value3])
|
|
assert option.value.len() == 3
|
|
with pytest.raises(LeadershipError):
|
|
option.value.set(new_value)
|
|
assert option.value.len() == 3
|
|
option.value.pop(2)
|
|
assert option.value.get() == new_value
|
|
#
|
|
assert option.value.default() == value
|
|
#
|
|
option.value.reset()
|
|
assert option.value.get() == value
|
|
assert option.owner.isdefault()
|
|
assert option.owner.get() == owners.default
|
|
# valid
|
|
assert option.value.valid() is True
|
|
# list
|
|
if 'choice' in name:
|
|
assert option.value.list() == ['val1', 'val2']
|
|
else:
|
|
with pytest.raises(ConfigError):
|
|
option.value.list()
|
|
if 'leader' in name or 'follower' in name:
|
|
assert option.value.len() == 2
|
|
else:
|
|
with pytest.raises(ConfigError):
|
|
option.value.len()
|
|
|
|
|
|
def _test_property(cfg, option, unrestraint=False, without_index=False):
|
|
name = option.name()
|
|
properties = []
|
|
properties_only_raises = []
|
|
properties_apply_requires = []
|
|
properties_uncalculated = []
|
|
if not option.isoptiondescription() and option.issymlinkoption():
|
|
name = option.option().name()
|
|
if name is None:
|
|
if unrestraint:
|
|
properties.append('cache')
|
|
properties_apply_requires.append('cache')
|
|
properties_uncalculated.append('cache')
|
|
else:
|
|
properties.extend(['disabled', 'frozen', 'validator', 'cache', 'force_store_value', 'hidden'])
|
|
properties_apply_requires.extend(['disabled', 'frozen', 'validator', 'cache', 'force_store_value', 'hidden'])
|
|
properties_uncalculated.extend(['disabled', 'frozen', 'validator', 'cache', 'force_store_value', 'hidden'])
|
|
if name and 'disabled' in name:
|
|
properties.append('disabled')
|
|
if not unrestraint:
|
|
properties_only_raises.append('disabled')
|
|
if not 'calc_property' in name:
|
|
properties_apply_requires.append('disabled')
|
|
properties_uncalculated.append('disabled')
|
|
else:
|
|
properties_uncalculated.append('calculation')
|
|
if name and ('hidden' in name or 'hidden' in option.name()):
|
|
properties.append('hidden')
|
|
if not unrestraint:
|
|
properties_only_raises.append('hidden')
|
|
properties_apply_requires.append('hidden')
|
|
properties_uncalculated.append('hidden')
|
|
if name and 'mandatory' in name:
|
|
properties.append('mandatory')
|
|
properties_apply_requires.append('mandatory')
|
|
properties_uncalculated.append('mandatory')
|
|
if name and 'submulti' in name:
|
|
# it's a follower
|
|
pass
|
|
elif name and 'multi' in name and not option.isfollower():
|
|
properties.append('unique')
|
|
properties.append('empty')
|
|
properties_apply_requires.append('unique')
|
|
properties_apply_requires.append('empty')
|
|
properties_uncalculated.append('unique')
|
|
properties_uncalculated.append('empty')
|
|
if name and 'calc_property' in name and not 'calc_property_disabled' in name and not 'property_param_disabled' in name:
|
|
properties.append('prop')
|
|
properties_uncalculated.append('calculation')
|
|
|
|
if not without_index:
|
|
assert option.property.get() == set(properties)
|
|
assert option.property.get(only_raises=True) == set(properties_only_raises)
|
|
assert option.property.get(apply_requires=False) == set(properties_apply_requires)
|
|
option_property = option.property.get(uncalculated=True)
|
|
if "calculation" in properties_uncalculated:
|
|
new_option_property = set()
|
|
for p in option_property:
|
|
if isinstance(p, Calculation):
|
|
properties_uncalculated.remove('calculation')
|
|
else:
|
|
new_option_property.add(p)
|
|
assert new_option_property == set(properties_uncalculated)
|
|
else:
|
|
assert option_property == set(properties_uncalculated)
|
|
#
|
|
if (name is not None or not unrestraint) and (option.isoptiondescription() or not option.issymlinkoption()):
|
|
assert 'new' not in option.property.get()
|
|
option.property.add('new')
|
|
assert 'new' in option.property.get()
|
|
option.property.remove('new')
|
|
assert 'new' not in option.property.get()
|
|
if properties:
|
|
if option.path() is not None:
|
|
for prop in properties:
|
|
with pytest.raises(ConfigError):
|
|
option.property.remove(prop)
|
|
assert option.property.get() == set(properties)
|
|
#
|
|
option.property.add('new')
|
|
option.property.reset()
|
|
else:
|
|
for prop in properties:
|
|
option.property.remove(prop)
|
|
assert option.property.get() == set()
|
|
for prop in properties:
|
|
option.property.add(prop)
|
|
assert option.property.get() == set(properties)
|
|
#
|
|
option.property.reset()
|
|
assert option.property.get() == set()
|
|
for prop in properties:
|
|
option.property.add(prop)
|
|
with pytest.raises(ConfigError):
|
|
option.property.remove('unknown')
|
|
else:
|
|
for prop in properties:
|
|
with pytest.raises(ConfigError):
|
|
option.property.remove(prop)
|
|
with pytest.raises(ConfigError):
|
|
option.property.add('unknown')
|
|
with pytest.raises(ConfigError):
|
|
option.property.reset()
|
|
assert option.property.get() == set(properties)
|
|
else:
|
|
with pytest.raises(ConfigError):
|
|
option.property.get()
|
|
with pytest.raises(ConfigError):
|
|
option.property.get(only_raises=True)
|
|
with pytest.raises(ConfigError):
|
|
option.property.get(apply_requires=False)
|
|
with pytest.raises(ConfigError):
|
|
option.property.get(uncalculated=True)
|
|
#with pytest.raises(ConfigError):
|
|
option.property.add('new')
|
|
#with pytest.raises(ConfigError):
|
|
option.property.remove('new')
|
|
#with pytest.raises(ConfigError):
|
|
option.property.reset()
|
|
#
|
|
|
|
|
|
def _test_permissive(cfg, option, unrestraint=False, without_index=False):
|
|
name = option.name()
|
|
if name is None:
|
|
default_permissives = {'hidden'}
|
|
else:
|
|
default_permissives = set()
|
|
assert option.permissive.get() == default_permissives
|
|
if (name is not None or not unrestraint) and (option.isoptiondescription() or not option.issymlinkoption()):
|
|
option.permissive.add('new')
|
|
assert option.permissive.get() == default_permissives | {'new'}
|
|
option.permissive.remove('new')
|
|
assert option.permissive.get() == default_permissives
|
|
#
|
|
with pytest.raises(ConfigError):
|
|
option.permissive.remove('unknown')
|
|
#
|
|
option.permissive.add('new')
|
|
option.permissive.reset()
|
|
assert option.permissive.get() == default_permissives
|
|
#
|
|
if name and not unrestraint:
|
|
props = set()
|
|
if 'disabled' in name:
|
|
props.add('disabled')
|
|
if 'hidden' in name:
|
|
props.add('hidden')
|
|
if props:
|
|
for p in props:
|
|
if not without_index:
|
|
assert option.property.get(only_raises=True) == props
|
|
option.permissive.add(p)
|
|
assert option.property.get(only_raises=True) == props - set([p])
|
|
option.permissive.remove(p)
|
|
assert option.property.get(only_raises=True) == props
|
|
else:
|
|
with pytest.raises(ConfigError):
|
|
option.property.get(only_raises=True)
|
|
#
|
|
else:
|
|
with pytest.raises(ConfigError):
|
|
option.permissive.add('new')
|
|
with pytest.raises(ConfigError):
|
|
option.permissive.remove('new')
|
|
with pytest.raises(ConfigError):
|
|
option.permissive.reset()
|
|
|
|
|
|
def test_auto_root(root_variables):
|
|
cfg = Config(root_variables)
|
|
cfg.property.read_write()
|
|
for option in walk(cfg.unrestraint):
|
|
# we are in unrestraint mode, set option with property
|
|
_test_option(option)
|
|
_test_information(cfg, option)
|
|
_test_value(cfg, option, True)
|
|
_test_property(cfg, option, True)
|
|
_test_permissive(cfg, option, True)
|
|
if not option.isoptiondescription() and option.isfollower():
|
|
follower_without_index_option = cfg.unrestraint.option(option.path())
|
|
_test_option(follower_without_index_option, without_index=True)
|
|
_test_information(cfg, follower_without_index_option, without_index=True)
|
|
_test_value(cfg, follower_without_index_option, True, without_index=True)
|
|
_test_property(cfg, follower_without_index_option, True, without_index=True)
|
|
_test_permissive(cfg, follower_without_index_option, True, without_index=True)
|
|
if option.path() is None:
|
|
continue
|
|
elif option.isoptiondescription():
|
|
new_option = cfg.option(option.path())
|
|
else:
|
|
new_option = cfg.option(option.path(), option.index())
|
|
_test_option(new_option)
|
|
_test_information(cfg, new_option)
|
|
_test_value(cfg, new_option)
|
|
_test_property(cfg, new_option)
|
|
_test_permissive(cfg, new_option)
|
|
if not option.isoptiondescription() and option.isfollower():
|
|
follower_without_index_option = cfg.option(option.path())
|
|
_test_option(follower_without_index_option, without_index=True)
|
|
_test_information(cfg, follower_without_index_option, without_index=True)
|
|
_test_value(cfg, follower_without_index_option, without_index=True)
|
|
_test_property(cfg, follower_without_index_option, without_index=True)
|
|
_test_permissive(cfg, follower_without_index_option, without_index=True)
|
|
##
|
|
##
|
|
##def test_auto_root_ro(root_variables):
|
|
## cfg = Config(root_variables)
|
|
## cfg.information.set('cfg_key', 'cfg_info')
|
|
## cfg.property.read_only()
|
|
## mandatories = cfg.value.mandatory()
|
|
## if not mandatories:
|
|
## pprint(cfg.value.get())
|
|
#
|
|
#
|
|
#def test_auto_root_without_cache(root_variables):
|
|
# cfg = Config(root_variables)
|
|
# cfg.information.set('cfg_key', 'cfg_info')
|
|
# cfg.property.read_write()
|
|
# cfg.property.remove('cache')
|
|
# pprint(cfg.value.get())
|
|
##
|
|
##
|
|
##def test_auto_root_without_cache_ro(root_variables):
|
|
## cfg = Config(root_variables)
|
|
## cfg.information.set('cfg_key', 'cfg_info')
|
|
## cfg.property.read_only()
|
|
## cfg.property.remove('cache')
|
|
## mandatories = cfg.value.mandatory()
|
|
## if not mandatories:
|
|
## pprint(cfg.value.get())
|
|
#FIXME
|
|
#class ParamDynOption()
|
|
#leadership property, ...
|
|
#tester leader !
|
|
#FIXME dependencies doit contenir _dependencies_information
|
|
|
|
#Choice
|
|
#Choice calculé
|