add unrestraint in option

This commit is contained in:
Emmanuel Garette 2017-10-25 08:46:22 +02:00
parent 22a4aa81dc
commit 582b0c027c
3 changed files with 171 additions and 98 deletions

View File

@ -6,7 +6,8 @@ from .autopath import do_autopath
do_autopath()
from tiramisu import Config, StrOption, OptionDescription, MasterSlaves, DynOptionDescription, \
getapi
from tiramisu.error import PropertiesOptionError
from tiramisu.error import PropertiesOptionError, APIError
from collections import OrderedDict
ICON = u'\u2937'
OPTIONS_TYPE = {'str': {'type': str,
@ -57,6 +58,7 @@ def autocheck_owner_without_value(api, path, **kwargs):
raises(PropertiesOptionError, "api.owner.get(path)")
else:
raises(PropertiesOptionError, "api.owner.get(path, 0)")
raises(APIError, "api.unrestraint.owner.get(path)")
if not kwargs.get('propertyerror', False):
if not isslave:
assert api.permissive.owner.get(path) == 'default'
@ -69,6 +71,7 @@ def autocheck_owner_without_value(api, path, **kwargs):
raises(PropertiesOptionError, "api.permissive.owner.get(path, 0)")
# check if default owner
raises(APIError, "api.unrestraint.owner.isdefault(path)")
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert api.owner.isdefault(path)
else:
@ -83,15 +86,6 @@ def autocheck_owner_without_value(api, path, **kwargs):
def autocheck_value(api, path, **kwargs):
"""set and get values
"""
print('=============')
try:
print(api.permissive.owner.get(path))
except Exception as pouet:
try:
print(api.permissive.owner.get(path, 0))
except Exception as pouet:
print(pouet)
pass
# check if is a multi, a master or a slave
if not kwargs.get('propertyerror', False):
multi = api.permissive.option.ismulti(path)
@ -99,9 +93,9 @@ def autocheck_value(api, path, **kwargs):
isslave = api.permissive.option.isslave(path)
else:
raises(PropertiesOptionError, "api.permissive.option.ismulti(path)")
multi = False
ismaster = False
isslave = False
multi = api.unrestraint.option.ismulti(path)
ismaster = api.unrestraint.option.ismaster(path)
isslave = api.unrestraint.option.isslave(path)
# set default value (different if value is multi or not)
if not multi:
@ -125,6 +119,7 @@ def autocheck_value(api, path, **kwargs):
# test default value (should be empty) with permissive
# cannot test for slave (we cannot get all values for a slave)
raises(APIError, "api.unrestraint.value.get(path)")
if not isslave:
if not kwargs.get('propertyerror', False):
assert api.permissive.value.get(path) == empty_value
@ -176,6 +171,12 @@ def autocheck_value(api, path, **kwargs):
raises(PropertiesOptionError, "api.permissive.value.get(path)")
# set a value with permissive
if ismaster:
raises(APIError, "api.unrestraint.value.set(path, second_value[1])")
elif isslave:
raises(APIError, "api.unrestraint.value.append(path, second_value[1])")
else:
raises(APIError, "api.unrestraint.value.set(path, second_value)")
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
if ismaster:
raises(IndexError, "api.permissive.value.set(path, 1, second_value[1])")
@ -228,15 +229,6 @@ def autocheck_value(api, path, **kwargs):
else:
raises(PropertiesOptionError, "api.value.get(path)")
raises(PropertiesOptionError, "api.permissive.value.get(path)")
print('=============')
try:
print(api.permissive.owner.get(path))
except Exception as pouet:
try:
print(api.permissive.owner.get(path, 0))
except Exception as pouet:
print(pouet)
pass
@autocheck
@ -248,9 +240,9 @@ def autocheck_reset_value(api, path, **kwargs):
isslave = api.permissive.option.isslave(path)
else:
raises(PropertiesOptionError, "api.permissive.option.ismulti(path)")
multi = False
ismaster = False
isslave = False
multi = api.unrestraint.option.ismulti(path)
ismaster = api.unrestraint.option.ismaster(path)
isslave = api.unrestraint.option.isslave(path)
# set default value (different if value is multi or not)
if not multi:
@ -345,8 +337,8 @@ def autocheck_property(api, path, **kwargs):
else:
raises(PropertiesOptionError, "api.permissive.option.ismulti(path)")
raises(PropertiesOptionError, "api.permissive.option.isslave(path)")
multi = False
isslave = False
multi = api.unrestraint.option.ismulti(path)
isslave = api.unrestraint.option.isslave(path)
# define properties
properties = ['prop1', 'prop2']
@ -372,6 +364,10 @@ def autocheck_property(api, path, **kwargs):
raises(PropertiesOptionError, "api.property.get(path)")
# get properties with permissive
if not isslave:
raises(APIError, "api.unrestraint.property.get(path)")
else:
raises(APIError, "api.unrestraint.property.get(path, 0)")
if not kwargs.get('propertyerror', False):
if not isslave:
assert set(api.permissive.property.get(path)) == set(default_props)
@ -455,8 +451,8 @@ def autocheck_reset_property(api, path, **kwargs):
else:
raises(PropertiesOptionError, "api.permissive.option.ismulti(path)")
raises(PropertiesOptionError, "api.permissive.option.isslave(path)")
multi = False
isslave = False
multi = api.unrestraint.option.ismulti(path)
isslave = api.unrestraint.option.isslave(path)
# define properties
properties = ['prop1', 'prop2']
@ -506,6 +502,8 @@ def autocheck_reset_property(api, path, **kwargs):
assert set(api.permissive.property.get(path, 1)) == set(properties)
# reset properties with permissive
raises(APIError, "api.unrestraint.property.set(path, properties)")
raises(APIError, "api.unrestraint.property.reset(path)")
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
api.permissive.property.set(path, properties)
api.permissive.property.reset(path)
@ -544,7 +542,7 @@ def autocheck_owner_with_value(api, path, **kwargs):
isslave = api.permissive.option.isslave(path)
else:
raises(PropertiesOptionError, "api.permissive.option.isslave(path)")
isslave = False
isslave = api.unrestraint.option.isslave(path)
# get owner without permissive
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
@ -565,9 +563,6 @@ def autocheck_owner_with_value(api, path, **kwargs):
if not isslave:
assert api.permissive.owner.get(path) == 'user'
else:
print('--------')
print(api.permissive.owner.get(path, 0))
print(api.permissive.value.get(path, 0))
assert api.permissive.owner.get(path, 0) == 'default'
assert api.permissive.owner.get(path, 1) == 'user'
else:
@ -645,6 +640,36 @@ def autocheck_set_owner(api, path, **kwargs):
assert api.permissive.owner.get(path, 1) == 'new_user1'
@autocheck
def autocheck_option(api, path, **kwargs):
expected_name = path.split('.')[-1]
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
current_name = api.option.getname(path)
assert current_name == api.permissive.option.getname(path)
assert current_name == api.unrestraint.option.getname(path)
doc = api.option.getdoc(path)
assert doc == api.permissive.option.getdoc(path)
assert doc == api.unrestraint.option.getdoc(path)
elif not kwargs.get('propertyerror', False):
raises(PropertiesOptionError, "api.option.getname(path)")
current_name = api.permissive.option.getname(path)
assert current_name == api.unrestraint.option.getname(path)
raises(PropertiesOptionError, "api.option.getdoc(path)")
doc = api.permissive.option.getdoc(path)
assert doc == api.unrestraint.option.getdoc(path)
else:
raises(PropertiesOptionError, "api.option.getname(path)")
raises(PropertiesOptionError, "api.permissive.option.getname(path)")
current_name = api.unrestraint.option.getname(path)
raises(PropertiesOptionError, "api.option.getdoc(path)")
raises(PropertiesOptionError, "api.permissive.option.getdoc(path)")
doc = api.unrestraint.option.getdoc(path)
assert current_name == expected_name
if expected_name.endswith('val1') or expected_name.endswith('val2'):
expected_name = expected_name[:-4]
assert doc == "{}'s option".format(expected_name)
def check_all(api, path, multi, **kwargs):
text = u' {} launch tests for {}'.format(ICON, path)
if multi:
@ -729,39 +754,39 @@ def make_api(options, multi):
DICT_PATHS = [
#test a config without optiondescription
{'first': 'first',
OrderedDict({'first': 'first',
'second': 'second_disabled',
'third': 'third_hidden'},
'third': 'third_hidden'}),
#test a config with an optiondescription
{'subod.first': 'subod.first',
OrderedDict({'subod.first': 'subod.first',
'subod.second': 'subod.second_disabled',
'subod.third': 'subod.third_hidden'},
'subod.third': 'subod.third_hidden'}),
#test a config with two optiondescription
{'subod.subsubod.first': 'subod.subsubod.first',
OrderedDict({'subod.subsubod.first': 'subod.subsubod.first',
'subod.subsubod.second': 'subod.subsubod.second_disabled',
'subod.subsubod.third': 'subod.subsubod.third_hidden'},
'subod.subsubod.third': 'subod.subsubod.third_hidden'}),
#test a config with mix of different optiondescription
{'first': 'first',
OrderedDict({'first': 'first',
'subod.second': 'subod.second_disabled',
'subod.subsubod.third': 'subod.subsubod.third_hidden'},
'subod.subsubod.third': 'subod.subsubod.third_hidden'}),
#test a config with masterslaves
{'first.first': 'first_master.first',
OrderedDict({'first.first': 'first_master.first',
'first.second': 'first_master.second_disabled',
'first.third': 'first_master.third_hidden'},
'first.third': 'first_master.third_hidden'}),
##test a config with dynoption
{'subodval1.firstval1': 'subod_dyn.first',
OrderedDict({'subodval1.firstval1': 'subod_dyn.first',
'subodval1.secondval1': 'subod_dyn.second_disabled',
'subodval1.thirdval1': 'subod_dyn.third_hidden',
'subodval2.firstval2': None,
'subodval2.secondval2': None,
'subodval2.thirdval2': None},
'subodval2.thirdval2': None}),
#test a config with dynoption subdir
{'subod.subodval1.firstval1': 'subod.subod_dyn.first',
OrderedDict({'subod.subodval1.firstval1': 'subod.subod_dyn.first',
'subod.subodval1.secondval1': 'subod.subod_dyn.second_disabled',
'subod.subodval1.thirdval1': 'subod.subod_dyn.third_hidden',
'subod.subodval2.firstval2': None,
'subod.subodval2.secondval2': None,
'subod.subodval2.thirdval2': None}
'subod.subodval2.thirdval2': None})
]
@ -794,16 +819,15 @@ def test_tree_od_permissive():
"""permissive when optiondescription is hidden
"""
tpaths = [
{'subod.subsubod.first': 'subod.subsubod_hidden.first',
OrderedDict({'subod.subsubod.first': 'subod.subsubod_hidden.first',
'subod.subsubod.second': 'subod.subsubod_hidden.second',
'subod.subsubod.third': 'subod.subsubod_hidden.third_hidden'},
{'subod.subodval1.firstval1': 'subod.subod_dyn_hidden.first',
'subod.subsubod.third': 'subod.subsubod_hidden.third_hidden'}),
OrderedDict({'subod.subodval1.firstval1': 'subod.subod_dyn_hidden.first',
'subod.subodval1.secondval1': 'subod.subod_dyn_hidden.second',
'subod.subodval1.thirdval1': 'subod.subod_dyn_hidden.third_hidden',
'subod.subodval2.firstval2': None,
'subod.subodval2.secondval2': None,
'subod.subodval2.thirdval2': None
}
'subod.subodval2.thirdval2': None})
]
for paths in tpaths:
lpaths = list(paths.keys())

View File

@ -57,9 +57,22 @@ def resetter(func):
class CommonTiramisu(object):
icon = '\u2937'
tmpl_help = u' {} {}: {}'
allow_unrestraint = False
def __init__(self, config, force_permissive, force_unrestraint):
if not self.allow_unrestraint:
self._unrestraint_not_allowed(force_unrestraint)
def _unrestraint_not_allowed(self, force_unrestraint):
if force_unrestraint:
name = self.__class__.__name__[11:].lower()
raise APIError(_('{} cannot be unrestraint').format(name))
def _get_obj_by_path(self, path, index=None):
validate = not self.force_unrestraint
return self.config.unwrap_from_path(path,
validate=validate,
validate_properties=validate,
force_permissive=self.force_permissive,
index=index)
@ -70,7 +83,7 @@ class CommonTiramisu(object):
if not hasattr(CommonTiramisu, name):
raise APIError(_('unknown method {}').format(name))
else:
super(CommonTiramisu).__getattribute__(name)
super(CommonTiramisu, self).__getattribute__(name)
def _help(self):
txt = []
@ -84,10 +97,13 @@ class CommonTiramisu(object):
class TiramisuAPIOption(CommonTiramisu):
"""get information from an option"""
allow_unrestraint = True
def __init__(self, config, force_permissive):
def __init__(self, config, force_permissive, force_unrestraint):
super(TiramisuAPIOption, self).__init__(config, force_permissive, force_unrestraint)
self.config = config
self.force_permissive = force_permissive
self.force_unrestraint = force_unrestraint
if config:
self.values = self.config.cfgimpl_get_values()
@ -111,13 +127,23 @@ class TiramisuAPIOption(CommonTiramisu):
opt = self._get_obj_by_path(path)
return opt.impl_is_master_slaves('slave')
def getname(self, path):
opt = self._get_obj_by_path(path)
return opt.impl_getname()
def getdoc(self, path):
opt = self._get_obj_by_path(path)
return opt.impl_get_display_name()
class TiramisuAPIOwner(CommonTiramisu):
"""manager option's owner"""
def __init__(self, config, force_permissive):
def __init__(self, config, force_permissive, force_unrestraint):
super(TiramisuAPIOwner, self).__init__(config, force_permissive, force_unrestraint)
self.config = config
self.force_permissive = force_permissive
self.force_unrestraint = force_unrestraint
if config:
self.values = self.config.cfgimpl_get_values()
@ -194,9 +220,11 @@ class TiramisuAPIOwner(CommonTiramisu):
class TiramisuAPIProperty(CommonTiramisu):
"""manager option's property"""
def __init__(self, config, force_permissive):
def __init__(self, config, force_permissive, force_unrestraint):
super(TiramisuAPIProperty, self).__init__(config, force_permissive, force_unrestraint)
self.config = config
self.force_permissive = force_permissive
self.force_unrestraint = force_unrestraint
if config:
self.settings = config.cfgimpl_get_settings()
@ -229,9 +257,11 @@ class TiramisuAPIProperty(CommonTiramisu):
class TiramisuAPIValue(CommonTiramisu):
"""manager option's value"""
def __init__(self, config, force_permissive):
def __init__(self, config, force_permissive, force_unrestraint):
super(TiramisuAPIValue, self).__init__(config, force_permissive, force_unrestraint)
self.config = config
self.force_permissive = force_permissive
self.force_unrestraint = force_unrestraint
def append(self, path, value=undefined):
opt = self._get_obj_by_path(path)
@ -288,19 +318,19 @@ class TiramisuAPIValue(CommonTiramisu):
force_permissive=self.force_permissive)
def _slave_reset(self, path, index):
#self._get_obj_by_path(path)
multi = self.config.getattr(path,
force_permissive=self.force_permissive)
del(multi[index])
self._get_obj_by_path(path)
#FIXME ... _p_ ...
self.config.cfgimpl_get_values()._p_.resetvalue_index(path, index)
class TiramisuAPI(object):
icon = '\u2937'
tmpl_help = ' {} {}: {}'
def __init__(self, config, force_permissive=False):
def __init__(self, config, force_permissive=False, force_unrestraint=False):
self.config = config
self.force_permissive = force_permissive
self.force_unrestraint = force_unrestraint
#FIXME ?
self.config.read_write()
self.config.cfgimpl_get_settings().setpermissive(('hidden',))
@ -316,9 +346,12 @@ class TiramisuAPI(object):
def __getattr__(self, subfunc):
if subfunc in self.registers:
return self.registers[subfunc](self.config,
self.force_permissive)
self.force_permissive,
self.force_unrestraint)
elif subfunc == 'permissive':
return TiramisuAPI(self.config, force_permissive=True)
return TiramisuAPI(self.config, force_permissive=True, force_unrestraint=self.force_unrestraint)
elif subfunc == 'unrestraint':
return TiramisuAPI(self.config, force_permissive=self.force_permissive, force_unrestraint=True)
elif subfunc == 'help':
return self._help()
else:

View File

@ -194,13 +194,15 @@ class SubConfig(object):
reset_all_cache()
def cfgimpl_get_home_by_path(self, path, force_permissive=False,
returns_raise=False, _setting_properties=undefined):
returns_raise=False, _setting_properties=undefined,
validate_properties=True):
""":returns: tuple (config, name)"""
path = path.split('.')
for step in path[:-1]:
self = self.getattr(step,
force_permissive=force_permissive,
returns_raise=returns_raise,
validate_properties=validate_properties,
_setting_properties=_setting_properties)
if isinstance(self, Exception):
return self, None
@ -382,7 +384,8 @@ class SubConfig(object):
def getattr(self, name, force_permissive=False, validate=True,
_setting_properties=undefined, _self_properties=undefined, index=None,
returns_raise=False, returns_option=False):
returns_raise=False, returns_option=False,
validate_properties=True):
"""
attribute notation mechanism for accessing the value of an option
:param name: attribute name
@ -397,6 +400,7 @@ class SubConfig(object):
if '.' in name:
homeconfig, name = self.cfgimpl_get_home_by_path(
name, force_permissive=force_permissive,
validate_properties=validate_properties,
returns_raise=returns_raise, _setting_properties=_setting_properties)
if isinstance(homeconfig, Exception):
cfg = homeconfig
@ -405,7 +409,8 @@ class SubConfig(object):
validate=validate,
_setting_properties=_setting_properties,
_self_properties=_self_properties,
index=index, returns_raise=returns_raise)
index=index, returns_raise=returns_raise,
validate_properties=validate_properties)
else:
option = self.cfgimpl_get_description().__getattr__(name,
context=context)
@ -417,6 +422,7 @@ class SubConfig(object):
force_permissive=force_permissive,
setting_properties=_setting_properties,
self_properties=_self_properties,
validate_properties=validate_properties,
index=index)
elif option._is_symlinkoption(): # pragma: no dynoptiondescription cover
path = context.cfgimpl_get_description().impl_get_path_by_opt(
@ -425,8 +431,10 @@ class SubConfig(object):
force_permissive=force_permissive,
_setting_properties=_setting_properties,
_self_properties=_self_properties,
validate_properties=validate_properties,
index=index, returns_raise=True)
elif option.impl_is_optiondescription():
if validate_properties:
props = self.cfgimpl_get_settings().validate_properties(
option, True, False, path=subpath,
force_permissive=force_permissive,
@ -454,6 +462,7 @@ class SubConfig(object):
force_permissive=force_permissive,
setting_properties=_setting_properties,
self_properties=_self_properties,
validate_properties=validate_properties,
index=index)
if not returns_raise and isinstance(cfg, Exception):
raise cfg
@ -727,7 +736,8 @@ class _CommonConfig(SubConfig):
return self.cfgimpl_get_values().getowner(opt, index=index,
force_permissive=force_permissive)
def unwrap_from_path(self, path, force_permissive=False, index=None):
def unwrap_from_path(self, path, force_permissive=False, index=None,
validate_properties=True, validate=True):
"""convenience method to extract and Option() object from the Config()
and it is **fast**: finds the option directly in the appropriate
namespace
@ -737,8 +747,14 @@ class _CommonConfig(SubConfig):
context = self._cfgimpl_get_context()
if '.' in path:
self, path = self.cfgimpl_get_home_by_path(path,
validate_properties=validate_properties,
force_permissive=force_permissive)
return self.getattr(path, force_permissive=force_permissive, index=index, returns_option=True)
return self.getattr(path,
validate_properties=validate_properties,
validate=validate,
force_permissive=force_permissive,
index=index,
returns_option=True)
def cfgimpl_get_path(self, dyn=True):
return None