update todict support and tests

This commit is contained in:
Emmanuel Garette 2019-06-21 23:04:04 +02:00
parent 55da00f131
commit 83f05197fb
21 changed files with 2820 additions and 2296 deletions

View file

@ -3,12 +3,12 @@ from py.test import raises
from .autopath import do_autopath
do_autopath()
from .config import config_type, get_config, value_list, global_owner
from tiramisu.setting import owners
from tiramisu import ChoiceOption, StrOption, OptionDescription, Config
from tiramisu.error import ConfigError
from tiramisu import undefined, Params, ParamValue, ParamOption
from tiramisu.api import TIRAMISU_VERSION
from tiramisu.storage import list_sessions
@ -32,12 +32,13 @@ def return_error(*args, **kwargs):
raise Exception('test')
def test_choiceoption():
def test_choiceoption(config_type):
choice = ChoiceOption('choice', '', values=('val1', 'val2'))
odesc = OptionDescription('od', '', [choice])
cfg = Config(odesc)
cfg.property.read_write()
owner = cfg.owner.get()
cfg = get_config(cfg, config_type)
owner = global_owner(cfg, config_type)
assert cfg.option('choice').owner.get() == owners.default
assert cfg.option('choice').owner.isdefault()
#
@ -53,15 +54,16 @@ def test_choiceoption():
assert cfg.option('choice').owner.get() == owners.default
assert cfg.option('choice').owner.isdefault()
#
assert cfg.option('choice').value.list() == ('val1', 'val2')
assert value_list(cfg.option('choice').value.list()) == ('val1', 'val2')
def test_choiceoption_function():
def test_choiceoption_function(config_type):
choice = ChoiceOption('choice', '', values=return_list)
odesc = OptionDescription('od', '', [choice])
cfg = Config(odesc)
cfg.property.read_write()
owner = cfg.owner.get()
cfg = get_config(cfg, config_type)
owner = global_owner(cfg, config_type)
assert cfg.option('choice').owner.isdefault()
#
cfg.option('choice').value.set('val1')
@ -73,7 +75,7 @@ def test_choiceoption_function():
raises(ValueError, "cfg.option('choice').value.set('no')")
assert cfg.option('choice').owner.isdefault()
#
assert cfg.option('choice').value.list() == ['val1', 'val2']
assert value_list(cfg.option('choice').value.list()) == ('val1', 'val2')
def test_choiceoption_function_error():
@ -100,12 +102,13 @@ def test_choiceoption_function_error_kwargs():
raises(ConfigError, "cfg.option('choice').value.set('val1')")
def test_choiceoption_calc_function():
def test_choiceoption_calc_function(config_type):
choice = ChoiceOption('choice', "", values=return_calc_list, values_params=Params((ParamValue('val1'),)))
odesc = OptionDescription('od', '', [choice])
cfg = Config(odesc)
cfg.property.read_write()
owner = cfg.owner.get()
cfg = get_config(cfg, config_type)
owner = global_owner(cfg, config_type)
assert cfg.option('choice').owner.isdefault()
#
cfg.option('choice').value.set('val1')
@ -118,7 +121,7 @@ def test_choiceoption_calc_function():
assert cfg.option('choice').owner.isdefault()
def test_choiceoption_calc_opt_function():
def test_choiceoption_calc_opt_function(config_type):
str_ = StrOption('str', '', 'val1')
choice = ChoiceOption('choice',
"",
@ -128,6 +131,7 @@ def test_choiceoption_calc_opt_function():
cfg = Config(odesc)
cfg.property.read_write()
owner = cfg.owner.get()
cfg = get_config(cfg, config_type)
assert cfg.option('choice').owner.isdefault()
#
cfg.option('choice').value.set('val1')
@ -149,13 +153,13 @@ def test_choiceoption_calc_opt_function_propertyerror():
odesc = OptionDescription('od', '', [str_, choice])
cfg = Config(odesc)
cfg.property.read_write()
if TIRAMISU_VERSION == 2:
raises(ValueError, "cfg.option('choice').value.set('no')")
else:
raises(ConfigError, "cfg.option('choice').value.set('no')")
raises(ConfigError, "cfg.option('choice').value.set('no')")
#def test_choiceoption_calc_opt_multi_function(config_type):
def test_choiceoption_calc_opt_multi_function():
# FIXME
config_type = 'tiramisu'
str_ = StrOption('str', '', ['val1'], multi=True)
choice = ChoiceOption('choice',
"",
@ -173,6 +177,7 @@ def test_choiceoption_calc_opt_multi_function():
cfg = Config(odesc)
cfg.property.read_write()
owner = cfg.owner.get()
cfg = get_config(cfg, config_type, True)
assert cfg.option('choice').owner.isdefault()
assert cfg.option('choice').value.get() == []
#
@ -193,7 +198,7 @@ def test_choiceoption_calc_opt_multi_function():
raises(ValueError, "cfg.option('ch2').value.get()")
def test_choiceoption_calc_opt_multi_function_kwargs():
def test_choiceoption_calc_opt_multi_function_kwargs(config_type):
str_ = StrOption('str', '', ['val1'], multi=True)
choice = ChoiceOption('choice',
"",
@ -211,6 +216,7 @@ def test_choiceoption_calc_opt_multi_function_kwargs():
cfg = Config(odesc)
cfg.property.read_write()
owner = cfg.owner.get()
# FIXME cfg = get_config(cfg, config_type)
assert cfg.option('choice').owner.isdefault()
assert cfg.option('choice').value.get() == []
#

View file

@ -7,6 +7,7 @@ import weakref
from .autopath import do_autopath
do_autopath()
from .config import config_type, get_config, value_list, global_owner
from tiramisu import Config
from tiramisu.config import SubConfig
@ -44,13 +45,14 @@ def make_description():
return descr
def test_base_config():
def test_base_config(config_type):
"""making a :class:`tiramisu.config.Config()` object
and a :class:`tiramisu.option.OptionDescription()` object
"""
gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy])
cfg = Config(descr)
cfg = get_config(cfg, config_type)
assert cfg.option('dummy').value.get() is False
#dmo = cfg.unwrap_from_path('dummy')
#assert dmo.impl_getname() == 'dummy'
@ -87,9 +89,12 @@ def test_base_config_force_permissive():
def test_base_config_in_a_tree():
# FIXME
config_type = 'tiramisu'
"how options are organized into a tree, see :ref:`tree`"
descr = make_description()
config = Config(descr)
config = get_config(config, config_type)
#
config.option('bool').value.set(False)
#
@ -216,11 +221,12 @@ def test_get_modified_values():
assert to_tuple(config.value.exportation()) == (('od.g5', 'od.g6'), (None, None), ('yes', tuple()), ('user', 'user'))
def test_get_modified_values_not_modif():
def test_get_modified_values_not_modif(config_type):
g1 = StrOption('g1', '', multi=True)
d1 = OptionDescription('od', '', [g1])
root = OptionDescription('root', '', [d1])
config = Config(root)
config = get_config(config, config_type)
assert config.option('od.g1').value.get() == []
value = config.option('od.g1').value.get()
value.append('val')
@ -249,12 +255,13 @@ def test_cannot_assign_value_to_option_description():
raises(APIError, "cfg.option('gc').value.set(3)")
def test_config_multi():
def test_config_multi(config_type):
i1 = IntOption('test1', '', multi=True)
i2 = IntOption('test2', '', multi=True, default_multi=1)
i3 = IntOption('test3', '', default=[2], multi=True, default_multi=1)
od = OptionDescription('test', '', [i1, i2, i3])
config = Config(od)
config = get_config(config, config_type)
assert config.option('test1').value.get() == []
assert config.option('test2').value.get() == []
config.option('test2').value.set([undefined])
@ -282,20 +289,24 @@ def test_prefix_error():
def test_no_validation():
# FIXME
config_type = 'tiramisu'
i1 = IntOption('test1', '')
od = OptionDescription('test', '', [i1])
config = Config(od)
config.property.read_write()
config.option('test1').value.set(1)
raises(ValueError, "config.option('test1').value.set('yes')")
assert config.option('test1').value.get() == 1
cfg = get_config(config, config_type)
cfg.option('test1').value.set(1)
raises(ValueError, "cfg.option('test1').value.set('yes')")
assert cfg.option('test1').value.get() == 1
config.property.pop('validator')
config.option('test1').value.set('yes')
assert config.option('test1').value.get() == 'yes'
config.property.add('validator')
raises(ValueError, "config.option('test1').value.get()")
config.option('test1').value.reset()
assert config.option('test1').value.get() is None
cfg = get_config(config, config_type)
cfg.option('test1').value.set('yes')
assert cfg.option('test1').value.get() == 'yes'
cfg.property.add('validator')
raises(ValueError, "cfg.option('test1').value.get()")
cfg.option('test1').value.reset()
assert cfg.option('test1').value.get() is None
def test_subconfig():
@ -325,30 +336,33 @@ def test_config_invalidsession():
raises(ValueError, 'Config(o2, session_id=2)')
def test_config_od_name():
def test_config_od_name(config_type):
i = IntOption('i', '')
s = SymLinkOption('s', i)
o = OptionDescription('val', '', [i, s])
o2 = OptionDescription('val', '', [o])
c = Config(o2)
c = get_config(c, config_type)
assert c.option('val.i').option.name() == 'i'
assert c.option('val.s').option.name() == 's'
assert c.option('val.s').option.name(follow_symlink=True) == 'i'
def test_config_od_type():
def test_config_od_type(config_type):
i = IntOption('i', '')
o = OptionDescription('val', '', [i])
o2 = OptionDescription('val', '', [o])
c = Config(o2)
c = get_config(c, config_type)
assert c.option('val.i').option.type() == 'integer'
def test_config_default():
def test_config_default(config_type):
i = IntOption('i', '', 8)
o = OptionDescription('val', '', [i])
o2 = OptionDescription('val', '', [o])
c = Config(o2)
c = get_config(c, config_type)
assert c.option('val.i').value.default() == 8
c.option('val.i').value.set(9)
assert c.option('val.i').value.get() == 9

View file

@ -3,6 +3,7 @@ from py.test import raises
from .autopath import do_autopath
do_autopath()
from .config import config_type, get_config, value_list, global_owner
from tiramisu import Config, IntOption, FloatOption, StrOption, ChoiceOption, \
BoolOption, FilenameOption, UnicodeOption, SymLinkOption, IPOption, \
@ -59,7 +60,7 @@ def test_str():
c # does not crash
def test_make_dict():
def test_make_dict(config_type):
"serialization of the whole config to a dict"
descr = OptionDescription("opt", "", [
OptionDescription("s1", "", [
@ -69,6 +70,7 @@ def test_make_dict():
config = Config(descr)
config.property.read_write()
config.permissive.set(frozenset(['hidden']))
config = get_config(config, config_type)
d = config.value.dict()
assert d == {"s1.a": False, "int": 42}
config.option('int').value.set(43)
@ -77,12 +79,14 @@ def test_make_dict():
assert d == {"s1.a": True, "int": 43}
d2 = config.value.dict(flatten=True)
assert d2 == {'a': True, 'int': 43}
raises(ValueError, 'd2 = config.value.dict(withvalue="3")')
d = config.forcepermissive.value.dict()
assert d == {"s1.a": True, "s1.b": False, "int": 43}
if config_type == 'tiramisu':
# FIXME
raises(ValueError, 'd2 = config.value.dict(withvalue="3")')
d = config.forcepermissive.value.dict()
assert d == {"s1.a": True, "s1.b": False, "int": 43}
def test_make_dict_with_disabled():
def test_make_dict_with_disabled(config_type):
descr = OptionDescription("opt", "", [
OptionDescription("s1", "", [
BoolOption("a", "", default=False),
@ -93,9 +97,11 @@ def test_make_dict_with_disabled():
IntOption("int", "", default=42)])
config = Config(descr)
config.property.read_only()
config = get_config(config, config_type)
assert config.value.dict() == {"s1.a": False, "int": 42}
assert config.forcepermissive.value.dict() == {"s1.a": False, "int": 42}
assert config.unrestraint.value.dict() == {"int": 42, "s1.a": False, "s1.b": False, "s2.a": False, "s2.b": False}
if config_type == 'tiramisu':
assert config.forcepermissive.value.dict() == {"s1.a": False, "int": 42}
assert config.unrestraint.value.dict() == {"int": 42, "s1.a": False, "s1.b": False, "s2.a": False, "s2.b": False}
def test_make_dict_with_disabled_withoption():
@ -114,7 +120,7 @@ def test_make_dict_with_disabled_withoption():
assert config.unrestraint.value.dict(withoption="a") == {"s1.a": False, "s1.b": False, "s2.a": False, "s2.b": False}
def test_make_dict_with_disabled_in_callback():
def test_make_dict_with_disabled_in_callback(config_type):
descr = OptionDescription("opt", "", [
OptionDescription("s1", "", [
BoolOption("a", "", default=False),
@ -125,11 +131,12 @@ def test_make_dict_with_disabled_in_callback():
IntOption("int", "", default=42)])
config = Config(descr)
config.property.read_only()
config = get_config(config, config_type)
d = config.value.dict()
assert d == {"s1.a": False, "int": 42}
def test_make_dict_fullpath():
def test_make_dict_fullpath(config_type):
descr = OptionDescription("root", "", [
OptionDescription("opt", "", [
OptionDescription("s1", "", [
@ -142,10 +149,15 @@ def test_make_dict_fullpath():
IntOption("introot", "", default=42)])
config = Config(descr)
config.property.read_only()
config = get_config(config, config_type)
assert config.value.dict() == {"opt.s1.a": False, "opt.int": 42, "introot": 42}
assert config.option('opt').value.dict() == {"s1.a": False, "int": 42}
if config_type == 'tiramisu':
# FIXME
assert config.option('opt').value.dict() == {"s1.a": False, "int": 42}
assert config.value.dict(fullpath=True) == {"opt.s1.a": False, "opt.int": 42, "introot": 42}
assert config.option('opt').value.dict(fullpath=True) == {"opt.s1.a": False, "opt.int": 42}
if config_type == 'tiramisu':
# FIXME
assert config.option('opt').value.dict(fullpath=True) == {"opt.s1.a": False, "opt.int": 42}
def test_find_in_config():
@ -273,10 +285,11 @@ def test_does_not_find_in_config():
raises(AttributeError, "list(conf.option.find('IDontExist'))")
def test_filename():
def test_filename(config_type):
a = FilenameOption('a', '')
o = OptionDescription('o', '', [a])
cfg = Config(o)
# FIXME cfg = get_config(cfg, config_type)
cfg.option('a').value.set('/')
cfg.option('a').value.set('/tmp')
cfg.option('a').value.set('/tmp/')

View file

@ -1,5 +1,6 @@
from .autopath import do_autopath
do_autopath()
from .config import config_type, get_config, value_list, global_owner
import warnings, sys
from py.test import raises
@ -14,7 +15,7 @@ def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def test_domainname():
def test_domainname(config_type):
d = DomainnameOption('d', '')
f = DomainnameOption('f', '', allow_without_dot=True)
g = DomainnameOption('g', '', allow_ip=True)
@ -22,6 +23,7 @@ def test_domainname():
od = OptionDescription('a', '', [d, f, g, h])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
#
cfg.option('d').value.set('toto.com')
raises(ValueError, "cfg.option('d').value.set('toto')")
@ -40,7 +42,9 @@ def test_domainname():
cfg.option('f').value.set('d')
cfg.option('f').value.set('d.t')
#
raises(ValueError, "cfg.option('f').value.set('192.168.1.1')")
if config_type != 'tiramisu-api':
# FIXME
raises(ValueError, "cfg.option('f').value.set('192.168.1.1')")
raises(ValueError, "cfg.option('f').value.set('192.168.1.0/24')")
#
cfg.option('g').value.set('toto.com')
@ -49,35 +53,42 @@ def test_domainname():
raises(ValueError, "cfg.option('g').value.set('192.168.1.0/24')")
#
cfg.option('h').value.set('toto.com')
raises(ValueError, "cfg.option('h').value.set('192.168.1.0')")
raises(ValueError, "cfg.option('h').value.set('192.168.1.29')")
if config_type != 'tiramisu-api':
# FIXME
raises(ValueError, "cfg.option('h').value.set('192.168.1.0')")
raises(ValueError, "cfg.option('h').value.set('192.168.1.29')")
cfg.option('h').value.set('192.168.1.0/24')
def test_domainname_upper():
def test_domainname_upper(config_type):
d = DomainnameOption('d', '')
od = OptionDescription('a', '', [d])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('d').value.set('toto.com')
msg = _('some characters are uppercase')
has_error = False
try:
cfg.option('d').value.set('TOTO.COM')
except ValueError as err:
assert msg in str(err)
if config_type != 'tiramisu-api':
# FIXME
assert msg in str(err)
has_error = True
assert has_error is True
has_error = False
try:
cfg.option('d').value.set('toTo.com')
except ValueError as err:
assert msg in str(err)
if config_type != 'tiramisu-api':
# FIXME
assert msg in str(err)
has_error = True
assert has_error is True
def test_domainname_warning():
def test_domainname_warning(config_type):
d = DomainnameOption('d', '', warnings_only=True)
f = DomainnameOption('f', '', allow_without_dot=True, warnings_only=True)
g = DomainnameOption('g', '', allow_ip=True, warnings_only=True)
@ -85,12 +96,15 @@ def test_domainname_warning():
warnings.simplefilter("always", ValueWarning)
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('d').value.set('toto.com')
raises(ValueError, "cfg.option('d').value.set('toto')")
cfg.option('d').value.set('toto3.com')
with warnings.catch_warnings(record=True) as w:
cfg.option('d').value.set('toto_super.com')
assert len(w) == 1
if config_type != 'tiramisu-api':
# FIXME
with warnings.catch_warnings(record=True) as w:
cfg.option('d').value.set('toto_super.com')
assert len(w) == 1
with warnings.catch_warnings(record=True) as w:
cfg.option('d').value.set('toto-.com')
assert len(w) == 0
@ -102,17 +116,21 @@ def test_domainname_warning():
raises(ValueError, "cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamean')")
cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nd')
cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nditsnoteasytogeneratesolongdomainnamewithoutrepeatdomainnameto.olongthathavemorethanmaximumsizeforatruedomainnameanditsnoteas.ytogeneratesolongdomainnamewithoutrepeatbutimnotabletodoitnowie')
raises(ValueError, "cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainname.nditsnoteasytogeneratesolongdomainnamewithoutrepeatdomainnamet.olongthathavemorethanmaximumsizeforatruedomainnameanditsnotea.ytogeneratesolongdomainnamewithoutrepeatbutimnotabletodoitnowie.xxxx')")
if config_type != 'tiramisu-api':
# FIXME
raises(ValueError, "cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainname.nditsnoteasytogeneratesolongdomainnamewithoutrepeatdomainnamet.olongthathavemorethanmaximumsizeforatruedomainnameanditsnotea.ytogeneratesolongdomainnamewithoutrepeatbutimnotabletodoitnowie.xxxx')")
cfg.option('f').value.set('d')
cfg.option('f').value.set('d.t')
#
raises(ValueError, "cfg.option('f').value.set('192.168.1.1')")
if config_type != 'tiramisu-api':
# FIXME
raises(ValueError, "cfg.option('f').value.set('192.168.1.1')")
cfg.option('g').value.set('toto.com')
cfg.option('g').value.set('192.168.1.0')
cfg.option('g').value.set('192.168.1.29')
def test_special_domain_name():
def test_special_domain_name(config_type):
"""domain name option that starts with a number or not
"""
d = DomainnameOption('d', '')
@ -120,39 +138,43 @@ def test_special_domain_name():
od = OptionDescription('a', '', [d, e])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('d').value.set('1toto.com')
cfg.option('d').value.set('123toto.com')
cfg.option('e').value.set('toto')
cfg.option('e').value.set('1toto')
def test_domainname_netbios():
def test_domainname_netbios(config_type):
d = DomainnameOption('d', '', type_='netbios')
e = DomainnameOption('e', '', "toto", type_='netbios')
od = OptionDescription('a', '', [d, e])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
raises(ValueError, "cfg.option('d').value.set('toto.com')")
cfg.option('d').value.set('toto')
raises(ValueError, "cfg.option('d').value.set('domainnametoolong')")
def test_domainname_hostname():
def test_domainname_hostname(config_type):
d = DomainnameOption('d', '', type_='hostname')
e = DomainnameOption('e', '', "toto", type_='hostname')
od = OptionDescription('a', '', [d, e])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
raises(ValueError, "cfg.option('d').value.set('toto.com')")
cfg.option('d').value.set('toto')
cfg.option('d').value.set('domainnametoolong')
def test_email():
def test_email(config_type):
e = EmailOption('e', '')
od = OptionDescription('a', '', [e])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('e').value.set('foo-bar.baz@example.com')
cfg.option('e').value.set('root@foo.com')
cfg.option('e').value.set('root@domain')
@ -161,25 +183,34 @@ def test_email():
raises(ValueError, "cfg.option('e').value.set('root[]@domain')")
def test_url():
def test_url(config_type):
u = URLOption('u', '')
od = OptionDescription('a', '', [u])
cfg = Config(od)
cfg.property.read_write()
cfg = get_config(cfg, config_type)
cfg.option('u').value.set('http://foo.com')
cfg.option('u').value.set('https://foo.com')
cfg.option('u').value.set('https://foo.com/')
raises(ValueError, "cfg.option('u').value.set(1)")
raises(ValueError, "cfg.option('u').value.set('ftp://foo.com')")
raises(ValueError, "cfg.option('u').value.set('foo.com')")
raises(ValueError, "cfg.option('u').value.set(':/foo.com')")
raises(ValueError, "cfg.option('u').value.set('foo.com/http://')")
if config_type != 'tiramisu-api':
# FIXME
raises(ValueError, "cfg.option('u').value.set('ftp://foo.com')")
raises(ValueError, "cfg.option('u').value.set('foo.com')")
raises(ValueError, "cfg.option('u').value.set(':/foo.com')")
raises(ValueError, "cfg.option('u').value.set('foo.com/http://')")
cfg.option('u').value.set('https://foo.com/index.html')
cfg.option('u').value.set('https://foo.com/index.html?var=value&var2=val2')
raises(ValueError, "cfg.option('u').value.set('https://foo.com/index\\n.html')")
if config_type != 'tiramisu-api':
# FIXME
raises(ValueError, "cfg.option('u').value.set('https://foo.com/index\\n.html')")
cfg.option('u').value.set('https://foo.com:8443')
cfg.option('u').value.set('https://foo.com:8443/')
cfg.option('u').value.set('https://foo.com:8443/index.html')
raises(ValueError, "cfg.option('u').value.set('https://foo.com:84438989')")
if config_type != 'tiramisu-api':
# FIXME
raises(ValueError, "cfg.option('u').value.set('https://foo.com:84438989')")
cfg.option('u').value.set('https://foo.com:8443/INDEX')
raises(ValueError, "cfg.option('u').value.set('https://FOO.COM:8443')")
if config_type != 'tiramisu-api':
# FIXME
raises(ValueError, "cfg.option('u').value.set('https://FOO.COM:8443')")

View file

@ -1,5 +1,6 @@
from .autopath import do_autopath
do_autopath()
from .config import config_type, get_config, value_list, global_owner
import warnings
from py.test import raises
@ -13,29 +14,38 @@ def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def test_ip():
def test_ip(config_type):
a = IPOption('a', '')
b = IPOption('b', '', private_only=True)
d = IPOption('d', '', warnings_only=True, private_only=True)
warnings.simplefilter("always", ValueWarning)
od = OptionDescription('od', '', [a, b, d])
config = Config(od)
config = get_config(config, config_type)
config.option('a').value.set('192.168.1.1')
config.option('a').value.set('192.168.1.0')
config.option('a').value.set('88.88.88.88')
config.option('a').value.set('0.0.0.0')
raises(ValueError, "config.option('a').value.set('255.255.255.0')")
if config_type != 'tiramisu-api':
# FIXME
raises(ValueError, "config.option('a').value.set('255.255.255.0')")
config.option('b').value.set('192.168.1.1')
config.option('b').value.set('192.168.1.0')
raises(ValueError, "config.option('b').value.set('88.88.88.88')")
if config_type != 'tiramisu-api':
# FIXME
raises(ValueError, "config.option('b').value.set('88.88.88.88')")
config.option('b').value.set('0.0.0.0')
raises(ValueError, "config.option('b').value.set('255.255.255.0')")
if config_type != 'tiramisu-api':
# FIXME
raises(ValueError, "config.option('b').value.set('255.255.255.0')")
raises(ValueError, "config.option('a').value.set('333.0.1.20')")
raises(ValueError, "IPOption('a', 'ip', default='192.000.023.01')")
with warnings.catch_warnings(record=True) as w:
config.option('d').value.set('88.88.88.88')
assert len(w) == 1
if config_type != 'tiramisu-api':
# FIXME
raises(ValueError, "IPOption('a', 'ip', default='192.000.023.01')")
with warnings.catch_warnings(record=True) as w:
config.option('d').value.set('88.88.88.88')
assert len(w) == 1
def test_ip_cidr():
@ -60,44 +70,55 @@ def test_ip_default():
c.option('a').value.get() == '88.88.88.88'
def test_ip_reserved():
def test_ip_reserved(config_type):
a = IPOption('a', '')
b = IPOption('b', '', allow_reserved=True)
c = IPOption('c', '', warnings_only=True)
od = OptionDescription('od', '', [a, b, c])
warnings.simplefilter("always", ValueWarning)
cfg = Config(od)
raises(ValueError, "cfg.option('a').value.set('240.94.1.1')")
cfg = get_config(cfg, config_type)
if config_type != 'tiramisu-api':
# FIXME
raises(ValueError, "cfg.option('a').value.set('240.94.1.1')")
cfg.option('b').value.set('240.94.1.1')
with warnings.catch_warnings(record=True) as w:
cfg.option('c').value.set('240.94.1.1')
assert len(w) == 1
if config_type != 'tiramisu-api':
# FIXME
with warnings.catch_warnings(record=True) as w:
cfg.option('c').value.set('240.94.1.1')
assert len(w) == 1
def test_network():
def test_network(config_type):
a = NetworkOption('a', '')
b = NetworkOption('b', '', warnings_only=True)
od = OptionDescription('od', '', [a, b])
warnings.simplefilter("always", ValueWarning)
cfg = Config(od)
cfg = get_config(cfg, config_type)
cfg.option('a').value.set('192.168.1.1')
cfg.option('a').value.set('192.168.1.0')
cfg.option('a').value.set('88.88.88.88')
cfg.option('a').value.set('0.0.0.0')
raises(ValueError, "cfg.option('a').value.set(1)")
raises(ValueError, "cfg.option('a').value.set('1.1.1.1.1')")
raises(ValueError, "cfg.option('a').value.set('255.255.255.0')")
raises(ValueError, "cfg.option('a').value.set('192.168.001.0')")
if config_type != 'tiramisu-api':
# FIXME
raises(ValueError, "cfg.option('a').value.set('255.255.255.0')")
raises(ValueError, "cfg.option('a').value.set('192.168.001.0')")
raises(ValueError, "cfg.option('a').value.set('333.168.1.1')")
with warnings.catch_warnings(record=True) as w:
cfg.option('b').value.set('255.255.255.0')
assert len(w) == 1
if config_type != 'tiramisu-api':
# FIXME
with warnings.catch_warnings(record=True) as w:
cfg.option('b').value.set('255.255.255.0')
assert len(w) == 1
def test_network_cidr():
def test_network_cidr(config_type):
a = NetworkOption('a', '', cidr=True)
od = OptionDescription('od', '', [a])
cfg = Config(od)
# FIXME cfg = get_config(cfg, config_type)
cfg.option('a').value.set('192.168.1.1/32')
cfg.option('a').value.set('192.168.1.0/24')
cfg.option('a').value.set('88.88.88.88/32')
@ -111,24 +132,28 @@ def test_network_invalid():
raises(ValueError, "NetworkOption('a', '', default='toto')")
def test_netmask():
def test_netmask(config_type):
a = NetmaskOption('a', '')
od = OptionDescription('od', '', [a])
cfg = Config(od)
cfg = get_config(cfg, config_type)
raises(ValueError, "cfg.option('a').value.set('192.168.1.1.1')")
raises(ValueError, "cfg.option('a').value.set('192.168.1.1')")
raises(ValueError, "cfg.option('a').value.set('192.168.1.0')")
raises(ValueError, "cfg.option('a').value.set('88.88.88.88')")
raises(ValueError, "cfg.option('a').value.set('255.255.255.000')")
if config_type != 'tiramisu-api':
# FIXME
raises(ValueError, "cfg.option('a').value.set('192.168.1.1')")
raises(ValueError, "cfg.option('a').value.set('192.168.1.0')")
raises(ValueError, "cfg.option('a').value.set('88.88.88.88')")
raises(ValueError, "cfg.option('a').value.set('255.255.255.000')")
raises(ValueError, "cfg.option('a').value.set(2)")
cfg.option('a').value.set('0.0.0.0')
cfg.option('a').value.set('255.255.255.0')
def test_broadcast():
def test_broadcast(config_type):
a = BroadcastOption('a', '')
od = OptionDescription('od', '', [a])
cfg = Config(od)
# FIXME cfg = get_config(cfg, config_type)
raises(ValueError, "cfg.option('a').value.set('192.168.1.255.1')")
raises(ValueError, "cfg.option('a').value.set('192.168.001.255')")
raises(ValueError, "cfg.option('a').value.set('192.168.0.300')")
@ -139,7 +164,7 @@ def test_broadcast():
cfg.option('a').value.set('255.255.255.0')
def test_port():
def test_port(config_type):
a = PortOption('a', '')
b = PortOption('b', '', allow_zero=True)
c = PortOption('c', '', allow_zero=True, allow_registred=False)
@ -148,6 +173,7 @@ def test_port():
f = PortOption('f', '', allow_private=True)
od = OptionDescription('od', '', [a, b, c, d, e, f])
cfg = Config(od)
# FIXME cfg = get_config(cfg, config_type)
raises(ValueError, "cfg.option('a').value.set('0')")
cfg.option('a').value.set('1')
cfg.option('a').value.set('1023')
@ -202,7 +228,7 @@ def test_port():
raises(ValueError, "cfg.option('f').value.set('65536')")
def test_port_range():
def test_port_range(config_type):
a = PortOption('a', '', allow_range=True)
b = PortOption('b', '', allow_range=True, allow_zero=True)
c = PortOption('c', '', allow_range=True, allow_zero=True, allow_registred=False)
@ -211,6 +237,7 @@ def test_port_range():
f = PortOption('f', '', allow_range=True, allow_private=True)
od = OptionDescription('od', '', [a, b, c, d, e, f])
cfg = Config(od)
# FIXME cfg = get_config(cfg, config_type)
raises(ValueError, "cfg.option('a').value.set('0')")
cfg.option('a').value.set('1')
cfg.option('a').value.set('1023')

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,9 @@
# coding: utf-8
from .autopath import do_autopath
do_autopath()
# FIXME from .config import config_type, get_config
from py.test import raises
from tiramisu.api import TIRAMISU_VERSION
from tiramisu import Config
from tiramisu import IntOption, StrOption, UnicodeOption, OptionDescription, \
SymLinkOption, Leadership, undefined, Params, ParamOption
@ -78,71 +78,71 @@ def make_description3():
def test_mandatory_ro():
descr = make_description()
api = Config(descr)
api.property.read_only()
cfg = Config(descr)
cfg.property.read_only()
prop = []
try:
api.option('str1').value.get()
cfg.option('str1').value.get()
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
api.property.read_write()
api.option('str1').value.set('yes')
api.property.read_only()
assert api.option('str1').value.get() == 'yes'
cfg.property.read_write()
cfg.option('str1').value.set('yes')
cfg.property.read_only()
assert cfg.option('str1').value.get() == 'yes'
def test_mandatory_ro_dict():
descr = make_description()
api = Config(descr)
api.property.read_only()
cfg = Config(descr)
cfg.property.read_only()
prop = []
try:
api.value.dict()
cfg.value.dict()
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
api.property.read_write()
api.option('str1').value.set('yes')
api.option('unicode2').value.set('yes')
api.property.read_only()
cfg.property.read_write()
cfg.option('str1').value.set('yes')
cfg.option('unicode2').value.set('yes')
cfg.property.read_only()
try:
api.value.dict()
cfg.value.dict()
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
api.property.read_write()
api.option('str3').value.set(['yes'])
api.property.read_only()
assert api.value.dict() == {'str': 'abc', 'str1': 'yes', 'str3': ['yes'], 'str4': [], 'unicode2': 'yes'}
cfg.property.read_write()
cfg.option('str3').value.set(['yes'])
cfg.property.read_only()
assert cfg.value.dict() == {'str': 'abc', 'str1': 'yes', 'str3': ['yes'], 'str4': [], 'unicode2': 'yes'}
def test_mandatory_rw():
descr = make_description()
api = Config(descr)
api.property.read_write()
cfg = Config(descr)
cfg.property.read_write()
# not mandatory in rw
api.option('str1').value.get()
api.option('str1').value.set('yes')
assert api.option('str1').value.get() == 'yes'
cfg.option('str1').value.get()
cfg.option('str1').value.set('yes')
assert cfg.option('str1').value.get() == 'yes'
def test_mandatory_default():
descr = make_description()
api = Config(descr)
api.property.read_only()
cfg = Config(descr)
cfg.property.read_only()
#not mandatory in rw
api.option('str').value.get()
api.property.read_write()
api.option('str').value.set('yes')
api.property.read_only()
api.option('str').value.get()
api.property.read_write()
api.option('str').value.set(None)
api.property.read_only()
cfg.option('str').value.get()
cfg.property.read_write()
cfg.option('str').value.set('yes')
cfg.property.read_only()
cfg.option('str').value.get()
cfg.property.read_write()
cfg.option('str').value.set(None)
cfg.property.read_only()
prop = []
try:
api.option('str').value.get()
cfg.option('str').value.get()
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
@ -150,40 +150,40 @@ def test_mandatory_default():
def test_mandatory_delete():
descr = make_description()
api = Config(descr)
api.property.read_only()
api.option('str').value.get()
cfg = Config(descr)
cfg.property.read_only()
cfg.option('str').value.get()
try:
api.option('str1').value.get()
cfg.option('str1').value.get()
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
api.property.read_write()
api.option('str1').value.set('yes')
api.property.read_only()
assert api.option('str1').value.get() == 'yes'
api.property.pop('everything_frozen')
cfg.property.read_write()
cfg.option('str1').value.set('yes')
cfg.property.read_only()
assert cfg.option('str1').value.get() == 'yes'
cfg.property.pop('everything_frozen')
prop = []
try:
api.option('str1').value.reset()
cfg.option('str1').value.reset()
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
api.option('str').value.reset()
cfg.option('str').value.reset()
assert api.option('str1').value.get() == 'yes'
assert cfg.option('str1').value.get() == 'yes'
#valeur vide : None, '', u'', ...
def test_mandatory_none():
descr = make_description()
api = Config(descr)
api.option('str1').value.set(None)
assert api.option('str1').owner.get() == 'user'
api.property.read_only()
cfg = Config(descr)
cfg.option('str1').value.set(None)
assert cfg.option('str1').owner.get() == 'user'
cfg.property.read_only()
prop = []
try:
api.option('str1').value.get()
cfg.option('str1').value.get()
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
@ -191,13 +191,13 @@ def test_mandatory_none():
def test_mandatory_empty():
descr = make_description()
api = Config(descr)
api.option('str1').value.set('')
assert api.option('str1').owner.get() == 'user'
api.property.read_only()
cfg = Config(descr)
cfg.option('str1').value.set('')
assert cfg.option('str1').owner.get() == 'user'
cfg.property.read_only()
prop = []
try:
api.option('str1').value.get()
cfg.option('str1').value.get()
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
@ -205,23 +205,23 @@ def test_mandatory_empty():
def test_mandatory_multi_none():
descr = make_description()
api = Config(descr)
api.option('str3').value.set([None])
assert api.option('str3').owner.get() == 'user'
api.property.read_only()
cfg = Config(descr)
cfg.option('str3').value.set([None])
assert cfg.option('str3').owner.get() == 'user'
cfg.property.read_only()
prop = []
try:
api.option('str3').value.get()
cfg.option('str3').value.get()
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
api.property.read_write()
api.option('str3').value.set(['yes', None])
assert api.option('str3').owner.get() == 'user'
api.property.read_only()
cfg.property.read_write()
cfg.option('str3').value.set(['yes', None])
assert cfg.option('str3').owner.get() == 'user'
cfg.property.read_only()
prop = []
try:
api.option('str3').value.get()
cfg.option('str3').value.get()
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
@ -229,35 +229,35 @@ def test_mandatory_multi_none():
def test_mandatory_multi_empty():
descr = make_description()
api = Config(descr)
api.option('str3').value.set([])
assert api.option('str3').owner.get() == 'user'
api.property.read_only()
cfg = Config(descr)
cfg.option('str3').value.set([])
assert cfg.option('str3').owner.get() == 'user'
cfg.property.read_only()
prop = []
try:
api.option('str3').value.get()
cfg.option('str3').value.get()
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
#
api.property.read_write()
api.option('str3').value.set([''])
assert api.option('str3').owner.get() == 'user'
api.property.read_only()
cfg.property.read_write()
cfg.option('str3').value.set([''])
assert cfg.option('str3').owner.get() == 'user'
cfg.property.read_only()
prop = []
try:
api.option('str3').value.get()
cfg.option('str3').value.get()
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
#
api.property.read_write()
api.option('str3').value.set(['yes', ''])
assert api.option('str3').owner.get() == 'user'
api.property.read_only()
cfg.property.read_write()
cfg.option('str3').value.set(['yes', ''])
assert cfg.option('str3').owner.get() == 'user'
cfg.property.read_only()
prop = []
try:
api.option('str3').value.get()
cfg.option('str3').value.get()
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
@ -265,31 +265,31 @@ def test_mandatory_multi_empty():
def test_mandatory_multi_empty_allow_empty_list():
descr = make_description()
api = Config(descr)
api.option('str4').value.set([])
assert api.option('str4').owner.get() == 'user'
api.property.read_only()
cfg = Config(descr)
cfg.option('str4').value.set([])
assert cfg.option('str4').owner.get() == 'user'
cfg.property.read_only()
prop = []
api.option('str4').value.get()
cfg.option('str4').value.get()
#
api.property.read_write()
api.option('str4').value.set([''])
assert api.option('str4').owner.get() == 'user'
api.property.read_only()
cfg.property.read_write()
cfg.option('str4').value.set([''])
assert cfg.option('str4').owner.get() == 'user'
cfg.property.read_only()
prop = []
try:
api.option('str4').value.get()
cfg.option('str4').value.get()
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
#
api.property.read_write()
api.option('str4').value.set(['yes', ''])
assert api.option('str4').owner.get() == 'user'
api.property.read_only()
cfg.property.read_write()
cfg.option('str4').value.set(['yes', ''])
assert cfg.option('str4').owner.get() == 'user'
cfg.property.read_only()
prop = []
try:
api.option('str4').value.get()
cfg.option('str4').value.get()
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
@ -297,47 +297,44 @@ def test_mandatory_multi_empty_allow_empty_list():
def test_mandatory_multi_append():
descr = make_description()
api = Config(descr)
api.option('str3').value.set(['yes'])
api.property.read_write()
api.option('str3').value.get().append(None)
cfg = Config(descr)
cfg.option('str3').value.set(['yes'])
cfg.property.read_write()
cfg.option('str3').value.get().append(None)
def test_mandatory_disabled():
descr = make_description()
api = Config(descr)
api.option('str1').value.get()
api.option('str1').property.add('disabled')
api.property.read_only()
cfg = Config(descr)
cfg.option('str1').value.get()
cfg.option('str1').property.add('disabled')
cfg.property.read_only()
pop = []
try:
api.option('str1').value.get()
cfg.option('str1').value.get()
except PropertiesOptionError as err:
prop = err.proptype
if TIRAMISU_VERSION == 2:
search_prop = {'disabled', 'mandatory'}
else:
search_prop = {'disabled'}
search_prop = {'disabled'}
assert set(prop) == search_prop
def test_mandatory_unicode():
descr = make_description()
api = Config(descr)
api.option('unicode2').value.get()
api.property.read_only()
cfg = Config(descr)
cfg.option('unicode2').value.get()
cfg.property.read_only()
prop = []
try:
api.option('unicode2').value.get()
cfg.option('unicode2').value.get()
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
api.property.read_write()
api.option('unicode2').value.set(u'')
api.property.read_only()
cfg.property.read_write()
cfg.option('unicode2').value.set(u'')
cfg.property.read_only()
prop = []
try:
api.option('unicode2').value.get()
cfg.option('unicode2').value.get()
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
@ -345,66 +342,66 @@ def test_mandatory_unicode():
def test_mandatory_warnings_ro():
descr = make_description()
api = Config(descr)
api.option('str').value.set('')
api.property.read_only()
cfg = Config(descr)
cfg.option('str').value.set('')
cfg.property.read_only()
proc = []
try:
api.option('str').value.get()
cfg.option('str').value.get()
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
assert list(api.value.mandatory()) == ['str', 'str1', 'unicode2', 'str3']
api.property.read_write()
api.option('str').value.set('a')
api.property.read_only()
assert list(api.value.mandatory()) == ['str1', 'unicode2', 'str3']
assert list(cfg.value.mandatory()) == ['str', 'str1', 'unicode2', 'str3']
cfg.property.read_write()
cfg.option('str').value.set('a')
cfg.property.read_only()
assert list(cfg.value.mandatory()) == ['str1', 'unicode2', 'str3']
def test_mandatory_warnings_rw():
descr = make_description()
api = Config(descr)
api.option('str').value.set('')
api.property.read_write()
api.option('str').value.get()
assert list(api.value.mandatory()) == ['str', 'str1', 'unicode2', 'str3']
api.option('str').value.set('a')
assert list(api.value.mandatory()) == ['str1', 'unicode2', 'str3']
cfg = Config(descr)
cfg.option('str').value.set('')
cfg.property.read_write()
cfg.option('str').value.get()
assert list(cfg.value.mandatory()) == ['str', 'str1', 'unicode2', 'str3']
cfg.option('str').value.set('a')
assert list(cfg.value.mandatory()) == ['str1', 'unicode2', 'str3']
def test_mandatory_warnings_disabled():
descr = make_description()
api = Config(descr)
api.option('str').value.set('')
api.property.read_write()
api.option('str').value.get()
assert set(api.value.mandatory()) == {'str', 'str1', 'unicode2', 'str3'}
api.option('str').property.add('disabled')
assert set(api.value.mandatory()) == {'str1', 'unicode2', 'str3'}
cfg = Config(descr)
cfg.option('str').value.set('')
cfg.property.read_write()
cfg.option('str').value.get()
assert set(cfg.value.mandatory()) == {'str', 'str1', 'unicode2', 'str3'}
cfg.option('str').property.add('disabled')
assert set(cfg.value.mandatory()) == {'str1', 'unicode2', 'str3'}
def test_mandatory_warnings_hidden():
descr = make_description()
api = Config(descr)
api.option('str').value.set('')
api.property.read_write()
api.permissive.set(frozenset(['hidden']))
api.option('str').value.get()
assert set(api.value.mandatory()) == {'str', 'str1', 'unicode2', 'str3'}
api.option('str').property.add('hidden')
assert set(api.value.mandatory()) == {'str', 'str1', 'unicode2', 'str3'}
cfg = Config(descr)
cfg.option('str').value.set('')
cfg.property.read_write()
cfg.permissive.set(frozenset(['hidden']))
cfg.option('str').value.get()
assert set(cfg.value.mandatory()) == {'str', 'str1', 'unicode2', 'str3'}
cfg.option('str').property.add('hidden')
assert set(cfg.value.mandatory()) == {'str', 'str1', 'unicode2', 'str3'}
def test_mandatory_warnings_frozen():
descr = make_description()
api = Config(descr)
api.option('str').value.set('')
api.property.read_write()
api.option('str').value.get()
assert set(api.value.mandatory()) == {'str', 'str1', 'unicode2', 'str3'}
api.option('str').property.add('frozen')
api.property.read_only()
assert set(api.value.mandatory()) == {'str', 'str1', 'unicode2', 'str3'}
cfg = Config(descr)
cfg.option('str').value.set('')
cfg.property.read_write()
cfg.option('str').value.get()
assert set(cfg.value.mandatory()) == {'str', 'str1', 'unicode2', 'str3'}
cfg.option('str').property.add('frozen')
cfg.property.read_only()
assert set(cfg.value.mandatory()) == {'str', 'str1', 'unicode2', 'str3'}
def test_mandatory_leader():
@ -414,10 +411,10 @@ def test_mandatory_leader():
multi=True)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
descr = OptionDescription('o', '', [interface1])
api = Config(descr)
api.property.read_only()
raises(PropertiesOptionError, "api.option('ip_admin_eth0.ip_admin_eth0').value.get()")
raises(PropertiesOptionError, "api.value.dict()")
cfg = Config(descr)
cfg.property.read_only()
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()")
raises(PropertiesOptionError, "cfg.value.dict()")
def test_mandatory_warnings_leader():
@ -427,8 +424,8 @@ def test_mandatory_warnings_leader():
multi=True)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
descr = OptionDescription('o', '', [interface1])
api = Config(descr)
assert list(api.value.mandatory()) == ['ip_admin_eth0.ip_admin_eth0']
cfg = Config(descr)
assert list(cfg.value.mandatory()) == ['ip_admin_eth0.ip_admin_eth0']
def test_mandatory_leader_empty():
@ -437,40 +434,40 @@ def test_mandatory_leader_empty():
multi=True)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
descr = OptionDescription('o', '', [interface1])
api = Config(descr)
api.property.read_write()
assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
cfg = Config(descr)
cfg.property.read_write()
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
#
api.option('ip_admin_eth0.ip_admin_eth0').value.set([undefined])
assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == [None]
assert api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
api.property.read_only()
raises(PropertiesOptionError, "api.option('ip_admin_eth0.ip_admin_eth0').value.get()")
raises(PropertiesOptionError, "api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
api.property.read_write()
api.option('ip_admin_eth0.ip_admin_eth0').value.reset()
assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set([undefined])
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == [None]
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
cfg.property.read_only()
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()")
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
cfg.property.read_write()
cfg.option('ip_admin_eth0.ip_admin_eth0').value.reset()
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
#
api.option('ip_admin_eth0.ip_admin_eth0').value.set([''])
assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['']
assert api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
api.property.read_only()
raises(PropertiesOptionError, "api.option('ip_admin_eth0.ip_admin_eth0').value.get()")
raises(PropertiesOptionError, "api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
api.property.read_write()
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set([''])
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['']
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
cfg.property.read_only()
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()")
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
cfg.property.read_write()
#
api.property.read_write()
api.option('ip_admin_eth0.ip_admin_eth0').value.set(['ip'])
api.property.read_only()
assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['ip']
assert api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
cfg.property.read_write()
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['ip'])
cfg.property.read_only()
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['ip']
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
#
api.property.read_write()
api.option('ip_admin_eth0.ip_admin_eth0').value.set(['ip2'])
api.property.read_only()
raises(PropertiesOptionError, "api.option('ip_admin_eth0.ip_admin_eth0').value.reset()")
api.property.read_write()
api.option('ip_admin_eth0.ip_admin_eth0').value.reset()
cfg.property.read_write()
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['ip2'])
cfg.property.read_only()
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.ip_admin_eth0').value.reset()")
cfg.property.read_write()
cfg.option('ip_admin_eth0.ip_admin_eth0').value.reset()
def test_mandatory_warnings_leader_empty():
@ -479,22 +476,22 @@ def test_mandatory_warnings_leader_empty():
multi=True)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
descr = OptionDescription('o', '', [interface1])
api = Config(descr)
api.property.read_write()
api.option('ip_admin_eth0.ip_admin_eth0').value.set([undefined])
assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == [None]
assert api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
assert list(api.value.mandatory()) == ['ip_admin_eth0.ip_admin_eth0']
api.option('ip_admin_eth0.ip_admin_eth0').value.reset()
cfg = Config(descr)
cfg.property.read_write()
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set([undefined])
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == [None]
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
assert list(cfg.value.mandatory()) == ['ip_admin_eth0.ip_admin_eth0']
cfg.option('ip_admin_eth0.ip_admin_eth0').value.reset()
#
api.option('ip_admin_eth0.ip_admin_eth0').value.set([''])
assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['']
assert api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
assert list(api.value.mandatory()) == ['ip_admin_eth0.ip_admin_eth0']
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set([''])
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['']
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
assert list(cfg.value.mandatory()) == ['ip_admin_eth0.ip_admin_eth0']
#
api.property.read_write()
api.option('ip_admin_eth0.ip_admin_eth0').value.set(['ip'])
assert list(api.value.mandatory()) == []
cfg.property.read_write()
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['ip'])
assert list(cfg.value.mandatory()) == []
def test_mandatory_follower():
@ -503,27 +500,27 @@ def test_mandatory_follower():
multi=True, properties=('mandatory', ))
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
descr = OptionDescription('o', '', [interface1])
api = Config(descr)
api.property.read_only()
assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
cfg = Config(descr)
cfg.property.read_only()
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
#
api.property.read_write()
api.option('ip_admin_eth0.ip_admin_eth0').value.set(['ip'])
api.property.read_only()
assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['ip']
raises(PropertiesOptionError, "api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
cfg.property.read_write()
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['ip'])
cfg.property.read_only()
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['ip']
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
#
api.property.read_write()
api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('')
api.property.read_only()
assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['ip']
raises(PropertiesOptionError, "api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
cfg.property.read_write()
cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('')
cfg.property.read_only()
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['ip']
raises(PropertiesOptionError, "cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
#
api.property.read_write()
api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('ip')
api.property.read_only()
assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['ip']
assert api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == 'ip'
cfg.property.read_write()
cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('ip')
cfg.property.read_only()
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['ip']
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == 'ip'
def test_mandatory_warnings_follower():
@ -532,43 +529,43 @@ def test_mandatory_warnings_follower():
multi=True, properties=('mandatory', ))
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
descr = OptionDescription('o', '', [interface1])
api = Config(descr)
api.property.read_only()
assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
cfg = Config(descr)
cfg.property.read_only()
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
#
api.property.read_write()
assert list(api.value.mandatory()) == []
api.option('ip_admin_eth0.ip_admin_eth0').value.set(['ip'])
assert list(api.value.mandatory()) == ['ip_admin_eth0.netmask_admin_eth0']
cfg.property.read_write()
assert list(cfg.value.mandatory()) == []
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['ip'])
assert list(cfg.value.mandatory()) == ['ip_admin_eth0.netmask_admin_eth0']
def test_mandatory_warnings_symlink():
descr = make_description_sym()
api = Config(descr)
api.option('str').value.set('')
api.property.read_write()
api.option('str').value.get()
assert list(api.value.mandatory()) == ['str', 'str1', 'str3']
api.option('str').property.add('frozen')
api.property.read_only()
assert list(api.value.mandatory()) == ['str', 'str1', 'str3']
cfg = Config(descr)
cfg.option('str').value.set('')
cfg.property.read_write()
cfg.option('str').value.get()
assert list(cfg.value.mandatory()) == ['str', 'str1', 'str3']
cfg.option('str').property.add('frozen')
cfg.property.read_only()
assert list(cfg.value.mandatory()) == ['str', 'str1', 'str3']
#def test_mandatory_warnings_validate():
# descr = make_description3()
# api = Config(descr)
# api.option('str').value.set('')
# raises(ValueError, "list(api.value.mandatory())")
# api.option('str').value.set('test')
# raises(ValueError, "list(api.value.mandatory())")
# cfg = Config(descr)
# cfg.option('str').value.set('')
# raises(ValueError, "list(cfg.value.mandatory())")
# cfg.option('str').value.set('test')
# raises(ValueError, "list(cfg.value.mandatory())")
def test_mandatory_warnings_validate_empty():
descr = make_description2()
api = Config(descr)
api.option('str').value.set('')
api.property.read_only()
assert list(api.value.mandatory()) == ['str', 'str1', 'str3', 'unicode1']
cfg = Config(descr)
cfg.option('str').value.set('')
cfg.property.read_only()
assert list(cfg.value.mandatory()) == ['str', 'str1', 'str3', 'unicode1']
def test_mandatory_warnings_requires():
@ -580,16 +577,16 @@ def test_mandatory_warnings_requires():
properties=('mandatory', ))
stroption3 = StrOption('str3', 'Test string option', multi=True, requires=[{'option': stroption, 'expected': 'yes', 'action': 'mandatory', 'transitive': False}])
descr = OptionDescription('tiram', '', [stroption, stroption1, stroption2, stroption3])
api = Config(descr)
api.option('str').value.set('')
api.property.read_write()
api.option('str').value.get()
assert list(api.value.mandatory()) == ['str', 'str1', 'unicode2']
api.property.read_only()
assert list(api.value.mandatory()) == ['str', 'str1', 'unicode2']
api.property.read_write()
api.option('str').value.set('yes')
assert list(api.value.mandatory()) == ['str1', 'unicode2', 'str3']
cfg = Config(descr)
cfg.option('str').value.set('')
cfg.property.read_write()
cfg.option('str').value.get()
assert list(cfg.value.mandatory()) == ['str', 'str1', 'unicode2']
cfg.property.read_only()
assert list(cfg.value.mandatory()) == ['str', 'str1', 'unicode2']
cfg.property.read_write()
cfg.option('str').value.set('yes')
assert list(cfg.value.mandatory()) == ['str1', 'unicode2', 'str3']
def test_mandatory_warnings_requires_leadership():
@ -599,12 +596,12 @@ def test_mandatory_warnings_requires_leadership():
stroption2 = StrOption('str2', 'Test string option', multi=True, requires=[{'option': stroption, 'expected': 'yes', 'action': 'mandatory', 'transitive': False}])
leadership = Leadership('leader', 'leadership', [stroption1, stroption2])
descr = OptionDescription('tiram', '', [stroption, leadership])
api = Config(descr)
api.option('str').value.set('')
api.option('leader.str1').value.set(['str'])
assert list(api.value.mandatory()) == ['str']
api.option('str').value.set('yes')
assert list(api.value.mandatory()) == ['leader.str2']
cfg = Config(descr)
cfg.option('str').value.set('')
cfg.option('leader.str1').value.set(['str'])
assert list(cfg.value.mandatory()) == ['str']
cfg.option('str').value.set('yes')
assert list(cfg.value.mandatory()) == ['leader.str2']
def test_mandatory_warnings_requires_leadership_follower():
@ -613,18 +610,18 @@ def test_mandatory_warnings_requires_leadership_follower():
stroption2 = StrOption('str2', 'Test string option', multi=True, requires=[{'option': stroption1, 'expected': 'yes', 'action': 'mandatory', 'transitive': False}])
leadership = Leadership('leader', 'leadership', [stroption, stroption1, stroption2])
descr = OptionDescription('tiram', '', [leadership])
api = Config(descr)
api.option('leader.str').value.set(['str'])
assert list(api.value.mandatory()) == []
api.option('leader.str1', 0).value.set('yes')
assert list(api.value.mandatory()) == ['leader.str2']
cfg = Config(descr)
cfg.option('leader.str').value.set(['str'])
assert list(cfg.value.mandatory()) == []
cfg.option('leader.str1', 0).value.set('yes')
assert list(cfg.value.mandatory()) == ['leader.str2']
def test_mandatory_od_disabled():
descr = make_description()
descr = OptionDescription('od', '', [descr])
api = Config(descr)
api.property.read_only()
assert list(api.value.mandatory()) == ['tiram.str1', 'tiram.unicode2', 'tiram.str3']
api.option('tiram').property.add('disabled')
assert list(api.value.mandatory()) == []
cfg = Config(descr)
cfg.property.read_only()
assert list(cfg.value.mandatory()) == ['tiram.str1', 'tiram.unicode2', 'tiram.str3']
cfg.option('tiram').property.add('disabled')
assert list(cfg.value.mandatory()) == []

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,7 @@
"test all types of option default values for options, add new option in a descr"
from .autopath import do_autopath
do_autopath()
from .config import config_type, get_config
from py.test import raises
@ -11,6 +12,9 @@ from tiramisu import IntOption, FloatOption, StrOption, ChoiceOption, \
from tiramisu.storage import list_sessions
owners.addowner("frozenmultifollower")
def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
@ -41,7 +45,7 @@ def make_description():
#____________________________________________________________
# default values
def test_default_is_none():
def test_default_is_none(config_type):
"""
Most constructors take a ``default`` argument that specifies the default
value of the option. If this argument is not supplied the default value is
@ -50,10 +54,11 @@ def test_default_is_none():
dummy1 = BoolOption('dummy1', 'doc dummy')
dummy2 = BoolOption('dummy2', 'doc dummy')
group = OptionDescription('group', '', [dummy1, dummy2])
api = Config(group)
cfg = Config(group)
cfg = get_config(cfg, config_type)
# so when the default value is not set, there is actually a default value
assert api.option('dummy1').value.get() is None
assert api.option('dummy2').value.get() is None
assert cfg.option('dummy1').value.get() is None
assert cfg.option('dummy2').value.get() is None
def test_set_defaut_value_from_option_object():
@ -67,49 +72,73 @@ def test_force_default_on_freeze():
dummy1 = BoolOption('dummy1', 'doc dummy', default=False, properties=('force_default_on_freeze',))
dummy2 = BoolOption('dummy2', 'doc dummy', default=True)
group = OptionDescription('group', '', [dummy1, dummy2])
api = Config(group)
api.property.read_write()
owner = api.owner.get()
api.option('dummy1').value.set(True)
api.option('dummy2').value.set(False)
assert api.option('dummy1').owner.get() == owner
assert api.option('dummy2').owner.get() == owner
api.option('dummy1').property.add('frozen')
api.option('dummy2').property.add('frozen')
assert api.option('dummy1').value.get() is False
assert api.option('dummy2').value.get() is False
assert api.option('dummy1').owner.isdefault()
assert api.option('dummy2').owner.get() == owner
raises(PropertiesOptionError, "api.option('dummy2').owner.set('frozen')")
raises(PropertiesOptionError, "api.option('dummy1').value.reset()")
api.option('dummy1').property.pop('frozen')
api.option('dummy1').value.reset()
api.option('dummy1').property.add('frozen')
raises(PropertiesOptionError, "api.option('dummy2').owner.set('frozen')")
cfg_ori = Config(group)
cfg_ori.property.read_write()
cfg = cfg_ori
# FIXME cfg = get_config(cfg_ori, config_type)
owner = cfg.owner.get()
cfg.option('dummy1').value.set(True)
cfg.option('dummy2').value.set(False)
assert cfg.option('dummy1').owner.get() == owner
assert cfg.option('dummy2').owner.get() == owner
# if config_type == 'tiramisu-api':
# cfg.send()
cfg_ori.option('dummy1').property.add('frozen')
cfg_ori.option('dummy2').property.add('frozen')
# cfg = get_config(cfg_ori, config_type)
assert cfg.option('dummy1').value.get() is False
assert cfg.option('dummy2').value.get() is False
assert cfg.option('dummy1').owner.isdefault()
assert cfg.option('dummy2').owner.get() == owner
# if config_type == 'tiramisu-api':
# cfg.send()
raises(PropertiesOptionError, "cfg_ori.option('dummy2').owner.set('frozen')")
# cfg = get_config(cfg_ori, config_type)
raises(PropertiesOptionError, "cfg.option('dummy1').value.reset()")
# if config_type == 'tiramisu-api':
# cfg.send()
cfg_ori.option('dummy1').property.pop('frozen')
# cfg = get_config(cfg_ori, config_type)
cfg.option('dummy1').value.reset()
# if config_type == 'tiramisu-api':
# cfg.send()
cfg.option('dummy1').property.add('frozen')
# cfg = get_config(cfg_ori, config_type)
raises(PropertiesOptionError, "cfg.option('dummy2').owner.set('frozen')")
def test_force_default_on_freeze_multi():
dummy1 = BoolOption('dummy1', 'doc dummy', default=[False], properties=('force_default_on_freeze',), multi=True)
dummy2 = BoolOption('dummy2', 'doc dummy', default=[True], multi=True)
group = OptionDescription('group', '', [dummy1, dummy2])
api = Config(group)
api.property.read_write()
api.option('dummy1').value.set([undefined, True])
api.option('dummy2').value.set([undefined, False])
owner = api.owner.get()
assert api.option('dummy1').owner.get() == owner
assert api.option('dummy2').owner.get() == owner
api.option('dummy1').property.add('frozen')
api.option('dummy2').property.add('frozen')
assert api.option('dummy1').value.get() == [False]
assert api.option('dummy2').value.get() == [True, False]
assert api.option('dummy1').owner.isdefault()
assert api.option('dummy2').owner.get() == owner
raises(PropertiesOptionError, "api.option('dummy2').owner.set('owner')")
raises(PropertiesOptionError, "api.option('dummy2').value.reset()")
api.option('dummy1').property.pop('frozen')
api.option('dummy1').value.reset()
api.option('dummy1').property.add('frozen')
cfg_ori = Config(group)
cfg_ori.property.read_write()
cfg = cfg_ori
# FIXME cfg = get_config(cfg_ori, config_type)
cfg.option('dummy1').value.set([undefined, True])
cfg.option('dummy2').value.set([undefined, False])
owner = cfg.owner.get()
assert cfg.option('dummy1').owner.get() == owner
assert cfg.option('dummy2').owner.get() == owner
# if config_type == 'tiramisu-api':
# cfg.send()
cfg_ori.option('dummy1').property.add('frozen')
cfg_ori.option('dummy2').property.add('frozen')
# cfg = get_config(cfg_ori, config_type)
assert cfg.option('dummy1').value.get() == [False]
assert cfg.option('dummy2').value.get() == [True, False]
assert cfg.option('dummy1').owner.isdefault()
assert cfg.option('dummy2').owner.get() == owner
# if config_type == 'tiramisu-api':
# cfg.send()
raises(PropertiesOptionError, "cfg_ori.option('dummy2').owner.set('owner')")
# cfg = get_config(cfg_ori, config_type)
raises(PropertiesOptionError, "cfg.option('dummy2').value.reset()")
# if config_type == 'tiramisu-api':
# cfg.send()
cfg_ori.option('dummy1').property.pop('frozen')
# cfg = get_config(cfg_ori, config_type)
cfg.option('dummy1').value.reset()
def test_force_default_on_freeze_leader():
@ -133,8 +162,8 @@ def test_force_default_on_freeze_leader_frozen():
dummy2 = BoolOption('dummy2', 'Test string option', multi=True)
descr = Leadership("dummy1", "", [dummy1, dummy2])
descr = OptionDescription("root", "", [descr])
api = Config(descr)
raises(ConfigError, "api.option('dummy1.dummy1').property.pop('frozen')")
cfg = Config(descr)
raises(ConfigError, "cfg.option('dummy1.dummy1').property.pop('frozen')")
def test_force_metaconfig_on_freeze_leader_frozen():
@ -142,75 +171,93 @@ def test_force_metaconfig_on_freeze_leader_frozen():
dummy2 = BoolOption('dummy2', 'Test string option', multi=True)
descr = Leadership("dummy1", "", [dummy1, dummy2])
descr = OptionDescription("root", "", [descr])
api = Config(descr)
raises(ConfigError, "api.option('dummy1.dummy1').property.pop('frozen')")
cfg = Config(descr)
raises(ConfigError, "cfg.option('dummy1.dummy1').property.pop('frozen')")
def test_force_default_on_freeze_follower():
def test_force_default_on_freeze_follower(config_type):
dummy1 = BoolOption('dummy1', 'Test int option', multi=True)
dummy2 = BoolOption('dummy2', 'Test string option', multi=True, properties=('force_default_on_freeze',))
descr = Leadership("dummy1", "", [dummy1, dummy2])
descr = OptionDescription("root", "", [descr])
api = Config(descr)
api.property.read_write()
owners.addowner("frozenmultifollower2")
api.option('dummy1.dummy1').value.set([True])
api.option('dummy1.dummy2', 0).value.set(False)
assert api.option('dummy1.dummy1').value.get() == [True]
assert api.option('dummy1.dummy2', 0).value.get() == False
assert api.option('dummy1.dummy1').owner.get() == 'user'
assert api.option('dummy1.dummy2', 0).owner.get() == 'user'
cfg_ori = Config(descr)
cfg_ori.property.read_write()
cfg = get_config(cfg_ori, config_type)
cfg.option('dummy1.dummy1').value.set([True])
cfg.option('dummy1.dummy2', 0).value.set(False)
assert cfg.option('dummy1.dummy1').value.get() == [True]
assert cfg.option('dummy1.dummy2', 0).value.get() == False
assert cfg.option('dummy1.dummy1').owner.get() == 'user'
assert cfg.option('dummy1.dummy2', 0).owner.get() == 'user'
#
api.option('dummy1.dummy2').property.add('frozen')
assert api.option('dummy1.dummy1').value.get() == [True]
assert api.option('dummy1.dummy2', 0).value.get() == None
assert api.option('dummy1.dummy1').owner.get() == 'user'
assert api.option('dummy1.dummy2', 0).owner.isdefault()
raises(PropertiesOptionError, "api.option('dummy1.dummy2', 0).owner.set('frozenmultifollower2')")
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.option('dummy1.dummy2').property.add('frozen')
cfg = get_config(cfg_ori, config_type)
assert cfg.option('dummy1.dummy1').value.get() == [True]
assert cfg.option('dummy1.dummy2', 0).value.get() == None
assert cfg.option('dummy1.dummy1').owner.get() == 'user'
assert cfg.option('dummy1.dummy2', 0).owner.isdefault()
if config_type == 'tiramisu-api':
cfg.send()
raises(PropertiesOptionError, "cfg_ori.option('dummy1.dummy2', 0).owner.set('frozenmultifollower')")
cfg = get_config(cfg_ori, config_type)
#
api.option('dummy1.dummy2').property.pop('frozen')
api.option('dummy1.dummy1').value.set([True, True])
api.option('dummy1.dummy2', 1).value.set(False)
assert api.option('dummy1.dummy1').value.get() == [True, True]
assert api.option('dummy1.dummy2', 0).value.get() == False
assert api.option('dummy1.dummy2', 1).value.get() == False
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.option('dummy1.dummy2').property.pop('frozen')
cfg = get_config(cfg_ori, config_type)
cfg.option('dummy1.dummy1').value.set([True, True])
cfg.option('dummy1.dummy2', 1).value.set(False)
assert cfg.option('dummy1.dummy1').value.get() == [True, True]
assert cfg.option('dummy1.dummy2', 0).value.get() == False
assert cfg.option('dummy1.dummy2', 1).value.get() == False
#
api.option('dummy1.dummy2').property.add('frozen')
assert api.option('dummy1.dummy1').value.get() == [True, True]
assert api.option('dummy1.dummy2', 0).value.get() == None
assert api.option('dummy1.dummy2', 1).value.get() == None
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.option('dummy1.dummy2').property.add('frozen')
cfg = get_config(cfg_ori, config_type)
assert cfg.option('dummy1.dummy1').value.get() == [True, True]
assert cfg.option('dummy1.dummy2', 0).value.get() == None
assert cfg.option('dummy1.dummy2', 1).value.get() == None
#
api.option('dummy1.dummy1').value.pop(1)
assert api.option('dummy1.dummy1').value.get() == [True]
assert api.option('dummy1.dummy2', 0).value.get() == None
cfg.option('dummy1.dummy1').value.pop(1)
assert cfg.option('dummy1.dummy1').value.get() == [True]
assert cfg.option('dummy1.dummy2', 0).value.get() == None
#
api.option('dummy1.dummy2').property.pop('frozen')
assert api.option('dummy1.dummy1').value.get() == [True]
assert api.option('dummy1.dummy2', 0).value.get() == False
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.option('dummy1.dummy2').property.pop('frozen')
cfg = get_config(cfg_ori, config_type)
assert cfg.option('dummy1.dummy1').value.get() == [True]
assert cfg.option('dummy1.dummy2', 0).value.get() == False
#
api.option('dummy1.dummy1').value.set([True, True])
assert api.option('dummy1.dummy2', 0).value.get() == False
assert api.option('dummy1.dummy2', 1).value.get() == None
cfg.option('dummy1.dummy1').value.set([True, True])
assert cfg.option('dummy1.dummy2', 0).value.get() == False
assert cfg.option('dummy1.dummy2', 1).value.get() == None
def test_overrides_changes_option_value():
def test_overrides_changes_option_value(config_type):
"with config.override(), the default is changed and the value is changed"
descr = OptionDescription("test", "", [
BoolOption("b", "", default=False)])
api = Config(descr)
api.option('b').value.set(True)
cfg = Config(descr)
cfg = get_config(cfg, config_type)
cfg.option('b').value.set(True)
def test_choice_with_no_default():
def test_choice_with_no_default(config_type):
descr = OptionDescription("test", "", [
ChoiceOption("backend", "", ("c", "cli"))])
api = Config(descr)
assert api.option('backend').value.get() is None
api.option('backend').value.set('c')
cfg = Config(descr)
cfg = get_config(cfg, config_type)
assert cfg.option('backend').value.get() is None
cfg.option('backend').value.set('c')
def test_choice_with_default():
def test_choice_with_default(config_type):
descr = OptionDescription("test", "", [
ChoiceOption("backend", "", ("c", "cli"), default="cli")])
api = Config(descr)
assert api.option('backend').value.get() == 'cli'
cfg = Config(descr)
cfg = get_config(cfg, config_type)
assert cfg.option('backend').value.get() == 'cli'

View file

@ -1,5 +1,6 @@
from .autopath import do_autopath
do_autopath()
from .config import config_type, get_config
from py.test import raises
@ -10,6 +11,10 @@ from tiramisu.error import ConfigError, ConstError, PropertiesOptionError, APIEr
from tiramisu.storage import list_sessions
owners.addowner("readonly2")
owners.addowner("new2")
def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
@ -36,41 +41,46 @@ def make_description():
return descr
def test_default_owner():
def test_default_owner(config_type):
gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy])
api = Config(descr)
assert api.option('dummy').value.get() is False
assert api.option('dummy').owner.get() == 'default'
api.option('dummy').value.set(True)
owner = api.owner.get()
assert api.option('dummy').owner.get() == owner
cfg = Config(descr)
cfg = get_config(cfg, config_type)
assert cfg.option('dummy').value.get() is False
assert cfg.option('dummy').owner.get() == 'default'
cfg.option('dummy').value.set(True)
owner = cfg.owner.get()
assert cfg.option('dummy').owner.get() == owner
def test_hidden_owner():
gcdummy = BoolOption('dummy', 'dummy', default=False, properties=('hidden',))
descr = OptionDescription('tiramisu', '', [gcdummy])
api = Config(descr)
api.property.read_write()
#raises(PropertiesOptionError, "api.forcepermissive.option('dummy').owner.get()")
#raises(PropertiesOptionError, "api.option('dummy').owner.isdefault()")
#raises(PropertiesOptionError, "api.forcepermissive.option('dummy').owner.isdefault()")
api.permissive.set(frozenset(['hidden']))
api.forcepermissive.option('dummy').value.get()
api.forcepermissive.option('dummy').owner.isdefault()
cfg = Config(descr)
cfg.property.read_write()
#raises(PropertiesOptionError, "cfg.forcepermissive.option('dummy').owner.get()")
#raises(PropertiesOptionError, "cfg.option('dummy').owner.isdefault()")
#raises(PropertiesOptionError, "cfg.forcepermissive.option('dummy').owner.isdefault()")
cfg.permissive.set(frozenset(['hidden']))
cfg.forcepermissive.option('dummy').value.get()
cfg.forcepermissive.option('dummy').owner.isdefault()
def test_addowner():
def test_addowner(config_type):
gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy])
api = Config(descr)
assert api.option('dummy').value.get() is False
assert api.option('dummy').owner.get() == 'default'
assert api.option('dummy').owner.isdefault()
api.owner.set('gen_config')
api.option('dummy').value.set(True)
assert api.option('dummy').owner.get() == owners.gen_config
assert not api.option('dummy').owner.isdefault()
cfg_ori = Config(descr)
cfg = get_config(cfg_ori, config_type)
assert cfg.option('dummy').value.get() is False
assert cfg.option('dummy').owner.get() == 'default'
assert cfg.option('dummy').owner.isdefault()
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.owner.set('gen_config')
cfg = get_config(cfg_ori, config_type)
cfg.option('dummy').value.set(True)
assert cfg.option('dummy').owner.get() == owners.gen_config
assert not cfg.option('dummy').owner.isdefault()
def test_addowner_multiple_time():
@ -83,102 +93,128 @@ def test_delete_owner():
raises(ConstError, 'del(owners.deleted2)')
def test_owner_is_not_a_string():
def test_owner_is_not_a_string(config_type):
gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy])
api = Config(descr)
assert api.option('dummy').value.get() is False
assert api.option('dummy').owner.get() == owners.default
assert api.option('dummy').owner.get() == 'default'
assert isinstance(api.option('dummy').owner.get(), owners.Owner)
api.option('dummy').value.set(True)
assert api.option('dummy').owner.get() == 'user'
cfg = Config(descr)
cfg = get_config(cfg, config_type)
assert cfg.option('dummy').value.get() is False
assert cfg.option('dummy').owner.get() == owners.default
assert cfg.option('dummy').owner.get() == 'default'
assert isinstance(cfg.option('dummy').owner.get(), owners.Owner)
cfg.option('dummy').value.set(True)
assert cfg.option('dummy').owner.get() == 'user'
def test_setowner_without_valid_owner():
def test_setowner_without_valid_owner(config_type):
gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy])
api = Config(descr)
assert api.option('dummy').value.get() is False
assert api.option('dummy').owner.get() == 'default'
cfg = Config(descr)
cfg = get_config(cfg, config_type)
assert cfg.option('dummy').value.get() is False
assert cfg.option('dummy').owner.get() == 'default'
def test_setowner_for_value():
def test_setowner_for_value(config_type):
gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy])
api = Config(descr)
assert api.option('dummy').value.get() is False
assert api.option('dummy').owner.get() == 'default'
owners.addowner("new2")
raises(ConfigError, "api.option('dummy').owner.set('new2')")
api.option('dummy').value.set(False)
assert api.option('dummy').owner.get() == owners.user
api.option('dummy').owner.set('new2')
assert api.option('dummy').owner.get() == owners.new2
cfg_ori = Config(descr)
cfg = get_config(cfg_ori, config_type)
assert cfg.option('dummy').value.get() is False
assert cfg.option('dummy').owner.get() == 'default'
if config_type == 'tiramisu-api':
cfg.send()
raises(ConfigError, "cfg_ori.option('dummy').owner.set('new2')")
cfg = get_config(cfg_ori, config_type)
cfg.option('dummy').value.set(False)
assert cfg.option('dummy').owner.get() == owners.user
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.option('dummy').owner.set('new2')
cfg = get_config(cfg_ori, config_type)
assert cfg.option('dummy').owner.get() == owners.new2
def test_setowner_forbidden():
def test_setowner_forbidden(config_type):
gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy])
api = Config(descr)
assert api.option('dummy').value.get() is False
assert api.option('dummy').owner.get() == 'default'
raises(ValueError, "api.owner.set('default')")
api.option('dummy').value.set(False)
raises(ValueError, "api.option('dummy').owner.set('default')")
cfg_ori = Config(descr)
cfg = get_config(cfg_ori, config_type)
assert cfg.option('dummy').value.get() is False
assert cfg.option('dummy').owner.get() == 'default'
if config_type == 'tiramisu-api':
cfg.send()
raises(ValueError, "cfg_ori.owner.set('default')")
cfg = get_config(cfg_ori, config_type)
cfg.option('dummy').value.set(False)
if config_type == 'tiramisu-api':
cfg.send()
raises(ValueError, "cfg_ori.option('dummy').owner.set('default')")
cfg = get_config(cfg_ori, config_type)
def test_setowner_read_only():
def test_setowner_read_only(config_type):
gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy])
api = Config(descr)
api.property.read_write()
assert api.option('dummy').value.get() is False
assert api.option('dummy').owner.get() == 'default'
owners.addowner("readonly2")
api.option('dummy').value.set(False)
assert api.option('dummy').owner.get() == owners.user
api.property.read_only()
cfg_ori = Config(descr)
cfg_ori.property.read_write()
cfg = get_config(cfg_ori, config_type)
assert cfg.option('dummy').value.get() is False
assert cfg.option('dummy').owner.get() == 'default'
cfg.option('dummy').value.set(False)
assert cfg.option('dummy').owner.get() == owners.user
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.property.read_only()
raises(PropertiesOptionError,
"api.option('dummy').owner.set('readonly2')")
assert api.option('dummy').owner.get() == owners.user
"cfg_ori.option('dummy').owner.set('readonly2')")
cfg = get_config(cfg_ori, config_type)
assert cfg.option('dummy').owner.get() == owners.user
def test_setowner_optiondescription():
def test_setowner_optiondescription(config_type):
gcdummy = BoolOption('dummy', 'dummy', default=False)
descr1 = OptionDescription('tiramisu', '', [gcdummy])
descr = OptionDescription('tiramisu', '', [descr1])
api = Config(descr)
raises(APIError, "api.option('tiramisu').owner.get()")
raises(APIError, "api.option('tiramisu').owner.set('user')")
cfg = Config(descr)
cfg = get_config(cfg, config_type)
raises(APIError, "cfg.option('tiramisu').owner.get()")
raises(APIError, "cfg.option('tiramisu').owner.set('user')")
def test_setowner_symlinkoption():
def test_setowner_symlinkoption(config_type):
gcdummy = BoolOption('dummy', 'dummy', default=False)
s = SymLinkOption('symdummy', gcdummy)
descr1 = OptionDescription('tiramisu', '', [gcdummy, s])
descr = OptionDescription('tiramisu', '', [descr1])
api = Config(descr)
assert api.option('tiramisu.symdummy').owner.isdefault()
api.option('tiramisu.dummy').value.set(True)
assert not api.option('tiramisu.symdummy').owner.isdefault()
raises(ConfigError, "api.option('tiramisu.symdummy').owner.set('user')")
cfg_ori = Config(descr)
cfg = get_config(cfg_ori, config_type)
assert cfg.option('tiramisu.symdummy').owner.isdefault()
cfg.option('tiramisu.dummy').value.set(True)
assert not cfg.option('tiramisu.symdummy').owner.isdefault()
if config_type == 'tiramisu-api':
cfg.send()
raises(ConfigError, "cfg_ori.option('tiramisu.symdummy').owner.set('user')")
def test_owner_leadership():
def test_owner_leadership(config_type):
b = IntOption('int', 'Test int option', default=[0], multi=True)
c = StrOption('str', 'Test string option', multi=True)
descr = Leadership("int", "", [b, c])
od = OptionDescription('od', '', [descr])
api = Config(od)
raises(ConfigError, "api.option('int.str', 0).owner.set('user')")
cfg_ori = Config(od)
raises(ConfigError, "cfg_ori.option('int.str', 0).owner.set('user')")
cfg = get_config(cfg_ori, config_type)
api.option('int.int').value.set([0, 1])
api.option('int.str', 0).value.set('yes')
assert not api.option('int.str', 0).owner.isdefault()
assert api.option('int.str', 1).owner.isdefault()
api.option('int.str', 0).owner.set('user')
assert api.option('int.str', 0).owner.get() == owners.user
assert api.option('int.str', 1).owner.isdefault()
assert api.option('int.str', 0).value.get() == 'yes'
assert api.option('int.str', 1).value.get() == None
cfg.option('int.int').value.set([0, 1])
cfg.option('int.str', 0).value.set('yes')
assert not cfg.option('int.str', 0).owner.isdefault()
assert cfg.option('int.str', 1).owner.isdefault()
if config_type == 'tiramisu-api':
cfg.send()
cfg_ori.option('int.str', 0).owner.set('user')
cfg = get_config(cfg_ori, config_type)
assert cfg.option('int.str', 0).owner.get() == owners.user
assert cfg.option('int.str', 1).owner.isdefault()
assert cfg.option('int.str', 0).value.get() == 'yes'
assert cfg.option('int.str', 1).value.get() == None

View file

@ -1,6 +1,7 @@
"config.set() or config.setoption() or option.setoption()"
from .autopath import do_autopath
do_autopath()
from .config import config_type, get_config
from py.test import raises
@ -40,14 +41,15 @@ def make_description():
#____________________________________________________________
# change with __setattr__
def test_attribute_access():
def test_attribute_access(config_type):
"Once set, option values can't be changed again by attribute access"
s = StrOption("string", "", default="string")
descr = OptionDescription("options", "", [s])
api = Config(descr)
cfg = Config(descr)
cfg = get_config(cfg, config_type)
# let's try to change it again
api.option('string').value.set('foo')
assert api.option('string').value.get() == 'foo'
cfg.option('string').value.set('foo')
assert cfg.option('string').value.get() == 'foo'
def test_mod_read_only_write():
@ -122,42 +124,45 @@ def test_mod_read_only_write():
raises(ValueError, "config2.property.getdefault('read_write', 'unknown')")
def test_setitem():
def test_setitem(config_type):
s = StrOption("string", "", default=["string", "sdfsdf"], default_multi="prout", multi=True)
descr = OptionDescription("options", "", [s])
api = Config(descr)
api.option('string').value.set([undefined, 'foo'])
assert api.option('string').value.get() == ['string', 'foo']
cfg = Config(descr)
cfg = get_config(cfg, config_type)
cfg.option('string').value.set([undefined, 'foo'])
assert cfg.option('string').value.get() == ['string', 'foo']
def test_reset():
def test_reset(config_type):
"if value is None, resets to default owner"
s = StrOption("string", "", default="string")
descr = OptionDescription("options", "", [s])
api = Config(descr)
api.option('string').value.set('foo')
assert api.option('string').value.get() == "foo"
assert api.option('string').owner.get() ==owners.user
api.option('string').value.reset()
assert api.option('string').value.get() == 'string'
assert api.option('string').owner.get() ==owners.default
cfg = Config(descr)
cfg = get_config(cfg, config_type)
cfg.option('string').value.set('foo')
assert cfg.option('string').value.get() == "foo"
assert cfg.option('string').owner.get() ==owners.user
cfg.option('string').value.reset()
assert cfg.option('string').value.get() == 'string'
assert cfg.option('string').owner.get() ==owners.default
def test_reset_with_multi():
def test_reset_with_multi(config_type):
s = StrOption("string", "", default=["string"], default_multi="string", multi=True)
descr = OptionDescription("options", "", [s])
api = Config(descr)
# api.option('string').value.set([])
api.option('string').value.reset()
assert api.option('string').value.get() == ["string"]
assert api.option('string').owner.get() =='default'
api.option('string').value.set(["eggs", "spam", "foo"])
assert api.option('string').owner.get() =='user'
api.option('string').value.set([])
api.option('string').value.reset()
# assert api.option('string').value.get() == ["string"]
assert api.option('string').owner.get() =='default'
raises(ValueError, "api.option('string').value.set(None)")
cfg = Config(descr)
cfg = get_config(cfg, config_type)
# cfg.option('string').value.set([])
cfg.option('string').value.reset()
assert cfg.option('string').value.get() == ["string"]
assert cfg.option('string').owner.get() =='default'
cfg.option('string').value.set(["eggs", "spam", "foo"])
assert cfg.option('string').owner.get() =='user'
cfg.option('string').value.set([])
cfg.option('string').value.reset()
# assert cfg.option('string').value.get() == ["string"]
assert cfg.option('string').owner.get() =='default'
raises(ValueError, "cfg.option('string').value.set(None)")
def test_property_only_raises():
@ -166,58 +171,61 @@ def test_property_only_raises():
stroption = StrOption('str', 'Test string option', default=["abc"], default_multi="abc",
requires=[{'option': intoption, 'expected': 1, 'action': 'hidden'}], multi=True)
descr = OptionDescription("options", "", [s, intoption, stroption])
api = Config(descr)
api.property.read_write()
assert api.option('str').property.get() == {'empty'}
assert api.option('str').property.get(only_raises=True) == set()
cfg = Config(descr)
cfg.property.read_write()
assert cfg.option('str').property.get() == {'empty'}
assert cfg.option('str').property.get(only_raises=True) == set()
def test_default_with_multi():
"default with multi is a list"
s = StrOption("string", "", default=[], default_multi="string", multi=True)
descr = OptionDescription("options", "", [s])
api = Config(descr)
assert api.option('string').value.get() == []
cfg = Config(descr)
assert cfg.option('string').value.get() == []
s = StrOption("string", "", default=None, default_multi="string", multi=True)
descr = OptionDescription("options", "", [s])
api = Config(descr)
assert api.option('string').value.get() == []
cfg = Config(descr)
assert cfg.option('string').value.get() == []
def test_idontexist():
descr = make_description()
api = Config(descr)
api.value.dict()
raises(AttributeError, "api.option('idontexist').value.get()")
cfg = Config(descr)
cfg.value.dict()
raises(AttributeError, "cfg.option('idontexist').value.get()")
# ____________________________________________________________
def test_attribute_access_with_multi():
def test_attribute_access_with_multi(config_type):
s = StrOption("string", "", default=["string"], default_multi="string", multi=True)
descr = OptionDescription("options", "", [s])
api = Config(descr)
api.option('string').value.set(["foo", "bar"])
assert api.option('string').value.get() == ["foo", "bar"]
cfg = Config(descr)
cfg = get_config(cfg, config_type)
cfg.option('string').value.set(["foo", "bar"])
assert cfg.option('string').value.get() == ["foo", "bar"]
def test_item_access_with_multi():
def test_item_access_with_multi(config_type):
s = StrOption("string", "", default=["string"], multi=True)
descr = OptionDescription("options", "", [s])
api = Config(descr)
api.option('string').value.set(["foo", "bar"])
assert api.option('string').value.get() == ["foo", "bar"]
api.option('string').value.set(["changetest", "bar"])
assert api.option('string').value.get() == ["changetest", "bar"]
cfg = Config(descr)
cfg = get_config(cfg, config_type)
cfg.option('string').value.set(["foo", "bar"])
assert cfg.option('string').value.get() == ["foo", "bar"]
cfg.option('string').value.set(["changetest", "bar"])
assert cfg.option('string').value.get() == ["changetest", "bar"]
def test_access_with_multi_default():
def test_access_with_multi_default(config_type):
s = StrOption("string", "", default=["string"], multi=True)
descr = OptionDescription("options", "", [s])
api = Config(descr)
assert api.option('string').owner.get() =='default'
api.option('string').value.set(["foo", "bar"])
assert api.option('string').value.get() == ["foo", "bar"]
assert api.option('string').owner.get() =='user'
cfg = Config(descr)
cfg = get_config(cfg, config_type)
assert cfg.option('string').owner.get() =='default'
cfg.option('string').value.set(["foo", "bar"])
assert cfg.option('string').value.get() == ["foo", "bar"]
assert cfg.option('string').owner.get() =='user'
def test_multi_with_requires():
@ -226,12 +234,12 @@ def test_multi_with_requires():
stroption = StrOption('str', 'Test string option', default=["abc"], default_multi="abc",
requires=[{'option': intoption, 'expected': 1, 'action': 'hidden'}], multi=True)
descr = OptionDescription("options", "", [s, intoption, stroption])
api = Config(descr)
api.property.read_write()
assert not 'hidden' in api.option('str').property.get()
api.option('int').value.set(1)
raises(PropertiesOptionError, "api.option('str').value.set(['a', 'b'])")
assert 'hidden' in api.forcepermissive.option('str').property.get()
cfg = Config(descr)
cfg.property.read_write()
assert not 'hidden' in cfg.option('str').property.get()
cfg.option('int').value.set(1)
raises(PropertiesOptionError, "cfg.option('str').value.set(['a', 'b'])")
assert 'hidden' in cfg.forcepermissive.option('str').property.get()
def test__requires_with_inverted():
@ -240,10 +248,10 @@ def test__requires_with_inverted():
stroption = StrOption('str', 'Test string option', default=["abc"], default_multi="abc",
requires=[{'option': intoption, 'expected': 1, 'action': 'hide', 'inverse': True}], multi=True)
descr = OptionDescription("options", "", [s, intoption, stroption])
api = Config(descr)
assert not 'hidden' in api.option('str').property.get()
api.option('int').value.set(1)
assert not 'hidden' in api.option('str').property.get()
cfg = Config(descr)
assert not 'hidden' in cfg.option('str').property.get()
cfg.option('int').value.set(1)
assert not 'hidden' in cfg.option('str').property.get()
def test_multi_with_requires_in_another_group():
@ -253,12 +261,12 @@ def test_multi_with_requires_in_another_group():
requires=[{'option': intoption, 'expected': 1, 'action': 'hidden'}], multi=True)
descr = OptionDescription("opt", "", [stroption])
descr2 = OptionDescription("opt2", "", [intoption, s, descr])
api = Config(descr2)
api.property.read_write()
assert not 'hidden' in api.option('opt.str').property.get()
api.option('int').value.set(1)
raises(PropertiesOptionError, "api.option('opt.str').value.set(['a', 'b'])")
assert 'hidden' in api.forcepermissive.option('opt.str').property.get()
cfg = Config(descr2)
cfg.property.read_write()
assert not 'hidden' in cfg.option('opt.str').property.get()
cfg.option('int').value.set(1)
raises(PropertiesOptionError, "cfg.option('opt.str').value.set(['a', 'b'])")
assert 'hidden' in cfg.forcepermissive.option('opt.str').property.get()
def test_multi_with_requires_in_another_group_inverse():
@ -268,12 +276,12 @@ def test_multi_with_requires_in_another_group_inverse():
requires=[{'option': intoption, 'expected': 0, 'action': 'hidden', 'inverse': True}], multi=True)
descr = OptionDescription("opt", "", [stroption])
descr2 = OptionDescription("opt2", "", [intoption, s, descr])
api = Config(descr2)
api.property.read_write()
assert not 'hidden' in api.option('opt.str').property.get()
api.option('int').value.set(1)
raises(PropertiesOptionError, "api.option('opt.str').value.set(['a', 'b'])")
assert 'hidden' in api.forcepermissive.option('opt.str').property.get()
cfg = Config(descr2)
cfg.property.read_write()
assert not 'hidden' in cfg.option('opt.str').property.get()
cfg.option('int').value.set(1)
raises(PropertiesOptionError, "cfg.option('opt.str').value.set(['a', 'b'])")
assert 'hidden' in cfg.forcepermissive.option('opt.str').property.get()
def test_apply_requires_from_config():
@ -283,14 +291,14 @@ def test_apply_requires_from_config():
requires=[{'option': intoption, 'expected': 1, 'action': 'hidden'}], multi=True)
descr = OptionDescription("opt", "", [stroption])
descr2 = OptionDescription("opt2", "", [intoption, s, descr])
api = Config(descr2)
api.property.read_write()
assert not 'hidden' in api.option('opt.str').property.get()
api.option('int').value.set(1)
raises(PropertiesOptionError, "api.option('opt.str').value.get()")
assert 'hidden' in api.forcepermissive.option('opt.str').property.get()
assert 'hidden' not in api.forcepermissive.option('opt.str').option.properties()
assert 'hidden' not in api.forcepermissive.option('opt.str').option.properties(only_raises=True)
cfg = Config(descr2)
cfg.property.read_write()
assert not 'hidden' in cfg.option('opt.str').property.get()
cfg.option('int').value.set(1)
raises(PropertiesOptionError, "cfg.option('opt.str').value.get()")
assert 'hidden' in cfg.forcepermissive.option('opt.str').property.get()
assert 'hidden' not in cfg.forcepermissive.option('opt.str').option.properties()
assert 'hidden' not in cfg.forcepermissive.option('opt.str').option.properties(only_raises=True)
def test_apply_requires_with_disabled():
@ -300,14 +308,14 @@ def test_apply_requires_with_disabled():
requires=[{'option': intoption, 'expected': 1, 'action': 'disabled'}], multi=True)
descr = OptionDescription("opt", "", [stroption])
descr2 = OptionDescription("opt2", "", [intoption, s, descr])
api = Config(descr2)
api.property.read_write()
assert not 'disabled' in api.option('opt.str').property.get()
api.option('int').value.set(1)
raises(PropertiesOptionError, "api.option('opt.str').value.get()")
assert 'disabled' not in api.unrestraint.option('opt.str').option.properties()
assert 'disabled' not in api.unrestraint.option('opt.str').option.properties(only_raises=True)
assert 'disabled' in api.unrestraint.option('opt.str').property.get()
cfg = Config(descr2)
cfg.property.read_write()
assert not 'disabled' in cfg.option('opt.str').property.get()
cfg.option('int').value.set(1)
raises(PropertiesOptionError, "cfg.option('opt.str').value.get()")
assert 'disabled' not in cfg.unrestraint.option('opt.str').option.properties()
assert 'disabled' not in cfg.unrestraint.option('opt.str').option.properties(only_raises=True)
assert 'disabled' in cfg.unrestraint.option('opt.str').property.get()
def test_multi_with_requires_with_disabled_in_another_group():
@ -317,12 +325,12 @@ def test_multi_with_requires_with_disabled_in_another_group():
requires=[{'option': intoption, 'expected': 1, 'action': 'disabled'}], multi=True)
descr = OptionDescription("opt", "", [stroption])
descr2 = OptionDescription("opt2", "", [intoption, s, descr])
api = Config(descr2)
api.property.read_write()
assert not 'disabled' in api.option('opt.str').property.get()
api.option('int').value.set(1)
raises(PropertiesOptionError, "api.option('opt.str').value.set(['a', 'b'])")
assert 'disabled' in api.unrestraint.option('opt.str').property.get()
cfg = Config(descr2)
cfg.property.read_write()
assert not 'disabled' in cfg.option('opt.str').property.get()
cfg.option('int').value.set(1)
raises(PropertiesOptionError, "cfg.option('opt.str').value.set(['a', 'b'])")
assert 'disabled' in cfg.unrestraint.option('opt.str').property.get()
def test_multi_with_requires_that_is_multi():
@ -361,24 +369,24 @@ def test_multi_with_requires_that_is_leadership_follower():
d = StrOption('str1', 'Test string option', requires=[{'option': c, 'expected': '1', 'action': 'hidden'}], multi=True)
descr = Leadership("int", "", [b, c, d])
descr2 = OptionDescription('od', '', [descr])
api = Config(descr2)
api.property.read_write()
assert api.option('int.int').value.get() == [0]
assert api.option('int.str', 0).value.get() == None
assert api.option('int.str1', 0).value.get() == None
api.option('int.int').value.set([0, 1])
assert api.option('int.int').value.get() == [0, 1]
assert api.option('int.str', 0).value.get() == None
assert api.option('int.str', 1).value.get() == None
assert api.option('int.str1', 0).value.get() == None
assert api.option('int.str1', 1).value.get() == None
api.option('int.str', 1).value.set('1')
api.property.read_only()
assert api.option('int.str1', 0).value.get() == None
assert api.option('int.str1', 1).value.get() == None
api.property.read_write()
assert api.option('int.str1', 0).value.get() == None
raises(PropertiesOptionError, "api.option('int.str1', 1).value.get()")
cfg = Config(descr2)
cfg.property.read_write()
assert cfg.option('int.int').value.get() == [0]
assert cfg.option('int.str', 0).value.get() == None
assert cfg.option('int.str1', 0).value.get() == None
cfg.option('int.int').value.set([0, 1])
assert cfg.option('int.int').value.get() == [0, 1]
assert cfg.option('int.str', 0).value.get() == None
assert cfg.option('int.str', 1).value.get() == None
assert cfg.option('int.str1', 0).value.get() == None
assert cfg.option('int.str1', 1).value.get() == None
cfg.option('int.str', 1).value.set('1')
cfg.property.read_only()
assert cfg.option('int.str1', 0).value.get() == None
assert cfg.option('int.str1', 1).value.get() == None
cfg.property.read_write()
assert cfg.option('int.str1', 0).value.get() == None
raises(PropertiesOptionError, "cfg.option('int.str1', 1).value.get()")
def test_multi_with_requires_that_is_leadership_follower_inverse():
@ -387,24 +395,24 @@ def test_multi_with_requires_that_is_leadership_follower_inverse():
d = StrOption('str1', 'Test string option', requires=[{'option': c, 'expected': None, 'action': 'hidden', 'inverse': True}], multi=True)
descr = Leadership("int", "", [b, c, d])
descr2 = OptionDescription('od', '', [descr])
api = Config(descr2)
api.property.read_write()
assert api.option('int.int').value.get() == [0]
assert api.option('int.str', 0).value.get() is None
assert api.option('int.str1', 0).value.get() is None
api.option('int.int').value.set([0, 1])
assert api.option('int.int').value.get() == [0, 1]
assert api.option('int.str', 0).value.get() is None
assert api.option('int.str', 1).value.get() is None
assert api.option('int.str1', 0).value.get() is None
assert api.option('int.str1', 1).value.get() is None
api.option('int.str', 1).value.set('1')
api.property.read_only()
assert api.option('int.str1', 0).value.get() is None
assert api.option('int.str1', 1).value.get() is None
api.property.read_write()
assert api.option('int.str1', 0).value.get() is None
raises(PropertiesOptionError, "api.option('int.str1', 1).value.get()")
cfg = Config(descr2)
cfg.property.read_write()
assert cfg.option('int.int').value.get() == [0]
assert cfg.option('int.str', 0).value.get() is None
assert cfg.option('int.str1', 0).value.get() is None
cfg.option('int.int').value.set([0, 1])
assert cfg.option('int.int').value.get() == [0, 1]
assert cfg.option('int.str', 0).value.get() is None
assert cfg.option('int.str', 1).value.get() is None
assert cfg.option('int.str1', 0).value.get() is None
assert cfg.option('int.str1', 1).value.get() is None
cfg.option('int.str', 1).value.set('1')
cfg.property.read_only()
assert cfg.option('int.str1', 0).value.get() is None
assert cfg.option('int.str1', 1).value.get() is None
cfg.property.read_write()
assert cfg.option('int.str1', 0).value.get() is None
raises(PropertiesOptionError, "cfg.option('int.str1', 1).value.get()")
def test_multi_with_requires_that_is_not_same_leadership():
@ -422,32 +430,32 @@ def test_multi_with_requires_that_is_not_same_leadership():
def test_multi_with_bool():
s = BoolOption("bool", "", default=[False], multi=True)
descr = OptionDescription("options", "", [s])
api = Config(descr)
api.option('bool').value.set([True, False])
assert api.option('bool').value.get() == [True, False]
cfg = Config(descr)
cfg.option('bool').value.set([True, False])
assert cfg.option('bool').value.get() == [True, False]
def test_choice_access_with_multi():
ch = ChoiceOption("t1", "", ("a", "b"), default=["a"], multi=True)
descr = OptionDescription("options", "", [ch])
api = Config(descr)
api.option('t1').value.set(["a", "b", "a", "b"])
assert api.option('t1').value.get() == ["a", "b", "a", "b"]
cfg = Config(descr)
cfg.option('t1').value.set(["a", "b", "a", "b"])
assert cfg.option('t1').value.get() == ["a", "b", "a", "b"]
#____________________________________________________________
def test_accepts_multiple_changes_from_option():
s = StrOption("string", "", default="string")
descr = OptionDescription("options", "", [s])
api = Config(descr)
api.option('string').value.set("egg")
assert api.option('string').option.default() == "string"
assert api.option('string').value.get() == "egg"
api.option('string').value.set('blah')
assert api.option('string').option.default() == "string"
assert api.option('string').value.get() == "blah"
api.option('string').value.set('bol')
assert api.option('string').value.get() == 'bol'
cfg = Config(descr)
cfg.option('string').value.set("egg")
assert cfg.option('string').option.default() == "string"
assert cfg.option('string').value.get() == "egg"
cfg.option('string').value.set('blah')
assert cfg.option('string').option.default() == "string"
assert cfg.option('string').value.get() == "blah"
cfg.option('string').value.set('bol')
assert cfg.option('string').value.get() == 'bol'
def test_allow_multiple_changes_from_config():
@ -459,21 +467,21 @@ def test_allow_multiple_changes_from_config():
s2 = StrOption("string2", "", default="string")
suboption = OptionDescription("bip", "", [s2])
descr = OptionDescription("options", "", [s, suboption])
api = Config(descr)
api.option('string').value.set("oh")
assert api.option('string').value.get() == "oh"
api.option('string').value.set("blah")
assert api.option('string').value.get() == "blah"
cfg = Config(descr)
cfg.option('string').value.set("oh")
assert cfg.option('string').value.get() == "oh"
cfg.option('string').value.set("blah")
assert cfg.option('string').value.get() == "blah"
# ____________________________________________________________
# accessing a value by the get method
def test_access_by_get():
descr = make_description()
api = Config(descr)
raises(AttributeError, "list(api.option.find('idontexist'))")
assert api.option.find('wantref', first=True).value.get() is False
assert api.option.find('dummy', first=True).value.get() is False
cfg = Config(descr)
raises(AttributeError, "list(cfg.option.find('idontexist'))")
assert cfg.option.find('wantref', first=True).value.get() is False
assert cfg.option.find('dummy', first=True).value.get() is False
def test_access_by_get_whith_hide():
@ -484,74 +492,74 @@ def test_access_by_get_whith_hide():
BoolOption("d1", "")]),
BoolOption("b2", ""),
BoolOption("d1", "")])
api = Config(descr)
api.property.read_write()
raises(AttributeError, "api.option.find('b1').value.get()")
cfg = Config(descr)
cfg.property.read_write()
raises(AttributeError, "cfg.option.find('b1').value.get()")
def test_append_properties():
descr = make_description()
api = Config(descr)
assert api.option('gc.dummy').property.get() == set()
api.option('gc.dummy').property.add('test')
assert api.option('gc.dummy').property.get() == {'test'}
raises(ConfigError, "api.option('gc.dummy').property.add('force_store_value')")
assert api.option('gc.dummy').property.get() == {'test'}
cfg = Config(descr)
assert cfg.option('gc.dummy').property.get() == set()
cfg.option('gc.dummy').property.add('test')
assert cfg.option('gc.dummy').property.get() == {'test'}
raises(ConfigError, "cfg.option('gc.dummy').property.add('force_store_value')")
assert cfg.option('gc.dummy').property.get() == {'test'}
def test_reset_properties():
descr = make_description()
api = Config(descr)
assert api.option('gc.dummy').property.get() == set()
api.option('gc.dummy').property.add('frozen')
assert api.option('gc.dummy').property.get() == {'frozen'}
api.option('gc.dummy').property.reset()
assert api.option('gc.dummy').property.get() == set()
cfg = Config(descr)
assert cfg.option('gc.dummy').property.get() == set()
cfg.option('gc.dummy').property.add('frozen')
assert cfg.option('gc.dummy').property.get() == {'frozen'}
cfg.option('gc.dummy').property.reset()
assert cfg.option('gc.dummy').property.get() == set()
def test_properties_cached():
b1 = BoolOption("b1", "", properties=('test',))
descr = OptionDescription("opt", "", [OptionDescription("sub", "", [b1])])
api = Config(descr)
api.property.read_write()
assert api.option('sub.b1').property.get() == {'test'}
cfg = Config(descr)
cfg.property.read_write()
assert cfg.option('sub.b1').property.get() == {'test'}
def test_append_properties_force_store_value():
gcdummy = BoolOption('dummy', 'dummy', default=False, properties=('force_store_value',))
gcgroup = OptionDescription('gc', '', [gcdummy])
descr = OptionDescription('tiramisu', '', [gcgroup])
api = Config(descr)
assert api.option('gc.dummy').property.get() == {'force_store_value'}
api.option('gc.dummy').property.add('test')
assert api.option('gc.dummy').property.get() == {'force_store_value', 'test'}
cfg = Config(descr)
assert cfg.option('gc.dummy').property.get() == {'force_store_value'}
cfg.option('gc.dummy').property.add('test')
assert cfg.option('gc.dummy').property.get() == {'force_store_value', 'test'}
def test_reset_properties_force_store_value():
gcdummy = BoolOption('dummy', 'dummy', default=False, properties=('force_store_value',))
gcgroup = OptionDescription('gc', '', [gcdummy])
descr = OptionDescription('tiramisu', '', [gcgroup])
api = Config(descr)
assert api.property.exportation() == {}
api.property.add('frozen')
assert api.property.exportation() == \
cfg = Config(descr)
assert cfg.property.exportation() == {}
cfg.property.add('frozen')
assert cfg.property.exportation() == \
{None: set(('frozen', 'cache', 'validator', 'warnings'))}
api.property.reset()
assert api.property.exportation() == {}
api.option('gc.dummy').property.add('test')
assert api.property.exportation() == {'gc.dummy': set(('test', 'force_store_value'))}
api.property.reset()
assert api.property.exportation() == {'gc.dummy': set(('test', 'force_store_value'))}
api.property.add('frozen')
assert api.property.exportation() == \
cfg.property.reset()
assert cfg.property.exportation() == {}
cfg.option('gc.dummy').property.add('test')
assert cfg.property.exportation() == {'gc.dummy': set(('test', 'force_store_value'))}
cfg.property.reset()
assert cfg.property.exportation() == {'gc.dummy': set(('test', 'force_store_value'))}
cfg.property.add('frozen')
assert cfg.property.exportation() == \
{None: set(('frozen', 'validator', 'cache', 'warnings')),
'gc.dummy': set(('test', 'force_store_value'))}
api.property.add('frozen')
assert api.property.exportation() == \
cfg.property.add('frozen')
assert cfg.property.exportation() == \
{None: set(('frozen', 'validator', 'cache', 'warnings')),
'gc.dummy': set(('test', 'force_store_value'))}
api.option('gc.dummy').property.add('test')
assert api.property.exportation() == \
cfg.option('gc.dummy').property.add('test')
assert cfg.property.exportation() == \
{None: set(('frozen', 'validator', 'cache', 'warnings')),
'gc.dummy': set(('test', 'force_store_value'))}
@ -580,10 +588,10 @@ def test_set_modified_value():
gcdummy = BoolOption('dummy', 'dummy', default=False, properties=('force_store_value',))
gcgroup = OptionDescription('gc', '', [gcdummy])
descr = OptionDescription('tiramisu', '', [gcgroup])
api = Config(descr)
assert api.property.exportation() == {}
api.property.importation({None: set(('frozen', 'cache', 'validator', 'warnings'))})
assert api.property.exportation() == \
cfg = Config(descr)
assert cfg.property.exportation() == {}
cfg.property.importation({None: set(('frozen', 'cache', 'validator', 'warnings'))})
assert cfg.property.exportation() == \
{None: set(('frozen', 'cache', 'validator', 'warnings'))}
@ -611,12 +619,12 @@ def test_pprint():
val3 = StrOption('val3', "", requires=[{'option': stroption, 'expected': '2', 'action': 'hidden', 'inverse': True}])
descr = OptionDescription("options", "", [s, s2, s3, intoption, stroption, descr2, val3])
api = Config(descr)
api.property.read_write()
api.option('int').value.set(1)
cfg = Config(descr)
cfg.property.read_write()
cfg.option('int').value.set(1)
err = None
try:
api.option('str').value.get()
cfg.option('str').value.get()
except PropertiesOptionError as error:
err = error
@ -627,7 +635,7 @@ def test_pprint():
err = None
try:
api.option('options.val2').value.get()
cfg.option('options.val2').value.get()
except PropertiesOptionError as error:
err = error
@ -635,7 +643,7 @@ def test_pprint():
#err = None
#try:
# api.option('val3').value.get()
# cfg.option('val3').value.get()
#except PropertiesOptionError as error:
# err = error
@ -648,7 +656,7 @@ def test_pprint():
err = None
try:
api.option('string').value.get()
cfg.option('string').value.get()
except Exception as error:
err = error
@ -657,7 +665,7 @@ def test_pprint():
err = None
try:
api.option('string3').value.get()
cfg.option('string3').value.get()
except Exception as error:
err = error

View file

@ -257,7 +257,16 @@ class _TiramisuOptionOption(_TiramisuOptionOptionDescription):
def defaultmulti(self):
"""Get default value when added a value for a multi option (not for optiondescription)"""
option = self._option_bag.option
return option.impl_getdefault_multi()
ret = option.impl_getdefault_multi()
if ret is None and option.impl_is_multi() and option.impl_has_callback() and not self.isfollower():
callback, callback_params = option.impl_get_callback()
values = self._option_bag.config_bag.context.cfgimpl_get_values()
value = values.carry_out_calculation(self._option_bag,
callback,
callback_params)
if not isinstance(value, list):
ret = value
return ret
def consistencies(self):
"""Get consistencies for an option (not for optiondescription)"""
@ -556,6 +565,11 @@ class _TiramisuOptionValueChoiceOption:
option = self._option_bag.option
return option.impl_get_values(self._option_bag)
def callbacks(self):
"""Get callbacks for a values"""
option = self._option_bag.option
return option.get_callback()
class _TiramisuOptionValueOptionDescription:

View file

@ -78,7 +78,7 @@ class PropertiesOptionError(AttributeError):
self.proptype = proptype
self._settings = settings
self.msg = None
super(PropertiesOptionError, self).__init__(None)
super().__init__(None)
def set_orig_opt(self, opt):
self._orig_opt = opt
@ -168,6 +168,7 @@ class _CommonError:
self.val = val
self.display_type = display_type
self.opt = weakref.ref(opt)
self.name = opt.impl_get_display_name()
self.err_msg = err_msg
self.index = index
super().__init__(self.err_msg)
@ -178,7 +179,7 @@ class _CommonError:
except AttributeError:
self.prefix = self.tmpl.format(self.val,
self.display_type,
self.opt().impl_get_display_name())
self.name)
msg = self.prefix
if self.err_msg:
if msg:

View file

@ -75,7 +75,7 @@ msgstr "group_type inconnu: {0}"
#: tiramisu/api.py:753 tiramisu/api.py:1208
msgid "please use .dict() before .updates()"
msgstr "faire .dico() avant .updates()"
msgstr "faire .dict() avant .updates()"
#: tiramisu/api.py:1000
msgid "properties must be a set"

View file

@ -81,25 +81,34 @@ class ChoiceOption(Option):
properties=properties,
warnings_only=warnings_only)
def get_callback(self):
values = self._choice_values
if isinstance(values, FunctionType):
return (values, getattr(self, '_choice_values_params', {}))
else:
return (None, None)
def impl_get_values(self,
option_bag,
current_opt=undefined):
if current_opt is undefined:
current_opt = self
values = self._choice_values
if isinstance(values, FunctionType):
values, values_params = self.get_callback()
if values is not None:
if option_bag is undefined:
values = undefined
else:
values = carry_out_calculation(current_opt,
callback=values,
callback_params=getattr(self, '_choice_values_params', {}),
callback_params=values_params,
index=None,
config_bag=option_bag.config_bag,
fromconsistency=[])
if values is not undefined and not isinstance(values, list):
raise ConfigError(_('calculated values for {0} is not a list'
'').format(self.impl_getname()))
else:
values = self._choice_values
return values

View file

@ -359,10 +359,10 @@ class Option(BaseOption):
'{0}'.format(err),
err_index)
warnings.warn_explicit(ValueErrorWarning(val,
self._display_name,
option_bag.ori_option,
'{0}'.format(err),
err_index),
self._display_name,
option_bag.ori_option,
'{0}'.format(err),
err_index),
ValueErrorWarning,
self.__class__.__name__, 0)
@ -707,9 +707,8 @@ class Option(BaseOption):
for opt_ in [opts[idx_inf], opts[idx_inf + idx_sup + 1]]:
if opt_ == current_opt:
is_current = True
else:
if opt_ not in equal:
equal.append(opt_)
elif opt_ not in equal:
equal.append(opt_)
if equal:
if is_current:
if warnings_only:

View file

@ -406,7 +406,8 @@ class Settings(object):
def getproperties(self,
option_bag,
apply_requires=True):
apply_requires=True,
search_properties=None):
"""
"""
opt = option_bag.option
@ -432,7 +433,8 @@ class Settings(object):
opt.impl_getproperties())
if apply_requires:
props |= self.apply_requires(option_bag,
False)
False,
search_properties=search_properties)
props -= self.getpermissives(opt,
path)
if apply_requires:
@ -457,7 +459,8 @@ class Settings(object):
def apply_requires(self,
option_bag,
readable):
readable,
search_properties=None):
"""carries out the jit (just in time) requirements between options
a requirement is a tuple of this form that comes from the option's
@ -517,6 +520,8 @@ class Settings(object):
for requires in current_requires:
for require in requires:
exps, action, inverse, transitive, same_action, operator = require
#if search_properties and action not in search_properties:
# continue
breaked = False
for option, expected in exps:
if not isinstance(option, tuple):

View file

@ -65,6 +65,14 @@ class Values(Cache):
# follower
self._values[nb].append([value])
def _add_new_value(self, index, nb, value):
if index is None or nb == 0:
# not follower or path
self._values[nb].append(value)
else:
# follower
self._values[nb].append([value])
# value
def setvalue(self,
path,

View file

@ -3,8 +3,9 @@
import warnings
import sys
from copy import copy
from collections import OrderedDict
from .error import ValueWarning, ValueErrorWarning, PropertiesOptionError
from itertools import chain
from .error import ValueWarning, ValueErrorWarning, PropertiesOptionError, ConfigError
from .setting import undefined
from . import SynDynOption, RegexpOption, ChoiceOption, ParamContext, ParamOption
from .i18n import _
@ -57,23 +58,21 @@ class Callbacks(object):
def process_properties(self, form):
for callback, callback_params, path, childapi, schema, force_store_value in self.callbacks:
if childapi.option.isfollower():
self.tiramisu_web.set_remotable(path, form, childapi)
continue
has_option = False
if callback_params is not None:
for callback_param in callback_params.args:
for callback_param in chain(callback_params.args, callback_params.kwargs.values()):
if isinstance(callback_param, ParamContext):
raise ValueError(_('context is not supported from now for {}').format(path))
if isinstance(callback_param, ParamOption):
has_option = True
if callback.__name__ != 'tiramisu_copy' or 'expire' in childapi.option.properties():
if self.remotable == 'none':
raise ValueError(_('option {} only works when remotable is not "none"').format(path))
form[callback_param.option.impl_getpath()]['remote'] = True
remote = True
if not has_option and form.get(path, {}).get('remote') == False:
self.tiramisu_web.set_remotable(callback_param.option.impl_getpath(), form)
if not has_option and form.get(path, {}).get('remote', False) == False:
if 'expire' in childapi.option.properties():
if self.remotable == 'none':
raise ValueError(_('option {} only works when remotable is not "none"').format(path))
form.setdefault(path, {})['remote'] = True
self.tiramisu_web.set_remotable(path, form, childapi)
elif childapi.owner.isdefault():
# get calculated value and set clearable
schema[path]['value'] = childapi.value.get()
@ -83,7 +82,7 @@ class Callbacks(object):
def manage_callbacks(self, form):
for callback, callback_params, path, childapi, schema, force_store_value in self.callbacks:
if callback_params is not None:
for callback_param in callback_params.args:
for callback_param in chain(callback_params.args, callback_params.kwargs.values()):
if isinstance(callback_param, ParamOption) and callback.__name__ == 'tiramisu_copy':
opt_path = callback_param.option.impl_getpath()
if form.get(opt_path, {}).get('remote') is not True:
@ -98,41 +97,39 @@ class Callbacks(object):
class Consistencies(object):
def __init__(self, tiramisu_web):
self.not_equal = []
self.options = {}
self.not_equal = {}
self.tiramisu_web = tiramisu_web
def add(self, path, childapi):
child = childapi.option.get()
if isinstance(child, SynDynOption):
child = child._impl_getopt()
self.options[child] = path
def add(self, path, childapi, form):
if not childapi.option.isoptiondescription():
for consistency in childapi.option.consistencies():
cons_id, func, all_cons_opts, params = consistency
if func == '_cons_not_equal':
options = []
if func == '_cons_not_equal' and params.get('transitive', True) is True:
options_path = []
for option in all_cons_opts:
options_path.append(option()._path)
for idx, option in enumerate(all_cons_opts):
option = option()
options.append(option)
# FIXME transitive
self.not_equal.append((options, params.get('warnings_only')))
paths = options_path.copy()
paths.pop(idx)
warnings_only = params.get('warnings_only') or getattr(option, '_warnings_only', False)
self.not_equal.setdefault(option._path, {}).setdefault(warnings_only, []).extend(paths)
else:
for option in all_cons_opts:
self.tiramisu_web.set_remotable(option()._path, form)
def process(self, form):
for not_equal, warnings_only in self.not_equal:
not_equal_option = []
for option in not_equal:
not_equal_option.append(self.options[option])
for idx, path in enumerate(not_equal_option):
if form.get(path, {}).get('remote') is True:
continue
options = copy(not_equal_option)
options.pop(idx)
form.setdefault(path, {}).setdefault('not_equal',
{'options': []})
form[path]['not_equal']['options'].extend(options)
if warnings_only or getattr(option, '_warnings_only', False):
form[path]['not_equal']['warnings'] = True
for path in self.not_equal:
for warnings_only in self.not_equal[path]:
options = self.not_equal[path][warnings_only]
if path not in form:
form[path] = {}
if 'not_equal' not in form[path]:
form[path]['not_equal'] = []
obj = {'options': options}
if warnings_only:
obj['warnings'] = True
form[path]['not_equal'].append(obj)
class Requires(object):
@ -140,8 +137,6 @@ class Requires(object):
self.requires = {}
self.options = {}
self.tiramisu_web = tiramisu_web
self.config = tiramisu_web.config
self.remotable = tiramisu_web.remotable
def manage_requires(self,
childapi,
@ -153,37 +148,36 @@ class Requires(object):
for require in requires:
options, action, inverse, \
transitive, same_action, operator = require
if transitive is False:
if transitive is False or same_action is False or operator == 'and':
# transitive to "False" not supported yet for a requirement
if self.remotable == 'none':
raise ValueError('require set for {} but remotable is "none"'
''.format(path))
form.setdefault(path, {'key': path})['remote'] = True
return
if same_action is False:
# same_action to "False" not supported yet for a requirement
if self.remotable == 'none':
raise ValueError('require set for {} but remotable is "none"'
''.format(path))
form.setdefault(path, {'key': path})['remote'] = True
return
if operator == 'and':
# operator "and" not supported yet for a requirement
if self.remotable == 'none':
raise ValueError('require set for {} but remotable is "none"'
''.format(path))
form.setdefault(path, {'key': path})['remote'] = True
self.tiramisu_web.set_remotable(path, form, childapi)
return
for option, expected in options:
option_path = self.options.get(option)
if option_path is not None and action in action_hide:
option_path = option.impl_getpath()
if action in action_hide:
if isinstance(option, ChoiceOption):
choice_obj = self.tiramisu_web.config.unrestraint.option(option_path)
if choice_obj.value.is_values_callback():
self.tiramisu_web.set_remotable(option_path, form, choice_obj)
return
else:
values = self.tiramisu_web.get_enum(choice_obj,
choice_obj.option.ismulti(),
option_path,
choice_obj.option.properties())
for value in values:
if value not in expected:
self.requires.setdefault(path,
{'expected': {}}
)['expected'].setdefault(value,
{}).setdefault(inv_act,
[]).append(option_path)
if current_action is None:
current_action = action
elif current_action != action:
if self.remotable == 'none':
raise ValueError('require set for {} but remotable is "none"'
''.format(path))
form.setdefault(option_path, {'key': option_path})['remote'] = True
self.tiramisu_web.set_remotable(option_path, form)
if inverse:
act = 'show'
inv_act = 'hide'
@ -196,25 +190,9 @@ class Requires(object):
)['expected'].setdefault(exp,
{}).setdefault(act,
[]).append(option_path)
if isinstance(option, ChoiceOption):
choice_obj = self.config.unrestraint.option(option_path)
values = self.tiramisu_web.get_enum(choice_obj,
choice_obj.option.ismulti(),
option_path,
choice_obj.option.properties())
for value in values:
if value not in expected:
self.requires.setdefault(path,
{'expected': {}}
)['expected'].setdefault(value,
{}).setdefault(inv_act,
[]).append(option_path)
self.requires[path].setdefault('default', {}).setdefault(inv_act, []).append(option_path)
else:
if self.remotable == 'none':
raise ValueError('require set for {} but remotable est "none"'
''.format(path))
form.setdefault(option_path, {'key': option_path})['remote'] = True
self.tiramisu_web.set_remotable(option_path, form)
def add(self, path, childapi, form):
#collect id of all options
@ -231,7 +209,7 @@ class Requires(object):
current_action)
def is_remote(self, path, form):
if self.remotable == 'all':
if self.tiramisu_web.remotable == 'all':
return True
else:
return form.get(path) and form[path].get('remote', False)
@ -244,7 +222,7 @@ class Requires(object):
if 'default' in values:
for option in values['default'].get('show', []):
if path == option:
form.setdefault(path, {'key': path})['remote'] = True
self.tiramisu_web.set_remotable(path, form)
if not self.is_remote(option, form):
dependencies.setdefault(option,
{'default': {}, 'expected': {}}
@ -253,7 +231,7 @@ class Requires(object):
dependencies[option]['default']['show'].append(path)
for option in values['default'].get('hide', []):
if path == option:
form.setdefault(path, {'key': path})['remote'] = True
self.tiramisu_web.set_remotable(path, form)
if not self.is_remote(option, form):
dependencies.setdefault(option,
{'default': {}, 'expected': {}}
@ -265,7 +243,7 @@ class Requires(object):
expected = ''
for option in actions.get('show', []):
if path == option:
form.setdefault(path, {'key': path})['remote'] = True
self.tiramisu_web.set_remotable(path, form)
if not self.is_remote(option, form):
dependencies.setdefault(option,
{'expected': {}}
@ -275,7 +253,7 @@ class Requires(object):
dependencies[option]['expected'][expected]['show'].append(path)
for option in actions.get('hide', []):
if path == option:
form.setdefault(path, {'key': path})['remote'] = True
self.tiramisu_web.set_remotable(path, form)
if not self.is_remote(option, form):
dependencies.setdefault(option,
{'expected': {}}
@ -336,6 +314,18 @@ class TiramisuDict:
path = root + '.' + childname
yield path, childapi
def set_remotable(self, path, form, childapi=None):
if self.remotable == 'none':
raise ValueError(_('option {} only works when remotable is not "none"').format(path))
form.setdefault(path, {})['remote'] = True
if childapi is None:
childapi = self.config.unrestraint.option(path)
if childapi.option.isfollower():
parent_path = path.rsplit('.', 1)[0]
parent = self.config.unrestraint.option(parent_path)
leader = next(parent.list())
form.setdefault(leader.option.path(), {})['remote'] = True
def walk(self,
root,
subchildapi,
@ -345,6 +335,7 @@ class TiramisuDict:
order,
updates_status,
init=False):
error = None
if init:
if form is not None:
self.requires = Requires(self)
@ -352,113 +343,120 @@ class TiramisuDict:
self.callbacks = Callbacks(self)
else:
init = False
if subchildapi is None:
if root is None:
subchildapi = self.config.unrestraint.option
try:
if subchildapi is None:
if root is None:
subchildapi = self.config.unrestraint.option
else:
subchildapi = self.config.unrestraint.option(root)
isleadership = False
else:
subchildapi = self.config.unrestraint.option(root)
isleadership = False
else:
isleadership = subchildapi.option.isleadership()
leader_len = None
for path, childapi in self.get_list(root, subchildapi):
if isleadership and leader_len is None:
leader_len = childapi.value.len()
props_no_requires = set(childapi.option.properties())
if form is not None:
self.requires.add(path,
childapi,
form)
self.consistencies.add(path,
childapi)
self.callbacks.add(path,
childapi,
schema,
'force_store_value' in props_no_requires)
childapi_option = childapi.option
if model is not None and childapi.option.isoptiondescription() or not childapi_option.issymlinkoption():
self.gen_model(model,
childapi,
path,
leader_len,
props_no_requires,
updates_status)
if order is not None:
order.append(path)
if childapi.option.isoptiondescription():
web_type = 'optiondescription'
if childapi_option.isleadership():
type_ = 'array'
else:
type_ = 'object'
if schema is not None:
schema[path] = {'properties': OrderedDict(),
'type': type_}
subschema = schema[path]['properties']
else:
subschema = schema
self.walk(path,
childapi,
subschema,
model,
form,
order,
updates_status)
else:
child = childapi_option.get()
childtype = child.__class__.__name__
if childtype == 'SynDynOption':
childtype = child._impl_getopt().__class__.__name__
if childapi_option.issymlinkoption():
web_type = 'symlink'
else:
web_type = childapi_option.type()
value = childapi.option.default()
if value not in [[], None]:
has_value = True
else:
value = None
has_value = False
is_multi = childapi_option.ismulti()
if is_multi:
default = childapi_option.defaultmulti()
if default not in [None, []]:
has_value = True
else:
default = None
else:
default = None
if schema is not None:
self.gen_schema(schema,
childapi,
childapi_option,
path,
props_no_requires,
value,
default,
is_multi,
web_type)
isleadership = subchildapi.option.isleadership()
leader_len = None
for path, childapi in self.get_list(root, subchildapi):
if isleadership and leader_len is None:
leader_len = childapi.value.len()
one_is_remote = False
props_no_requires = set(childapi.option.properties())
if form is not None:
self.gen_form(form,
web_type,
path,
child,
childapi_option,
childtype,
has_value)
if schema is not None:
if web_type != 'symlink':
schema[path]['title'] = childapi_option.doc()
self.add_help(schema[path],
childapi)
self.requires.add(path,
childapi,
form)
self.consistencies.add(path,
childapi,
form)
self.callbacks.add(path,
childapi,
schema,
'force_store_value' in props_no_requires)
childapi_option = childapi.option
if model is not None and childapi.option.isoptiondescription() or not childapi_option.issymlinkoption():
self.gen_model(model,
childapi,
path,
leader_len,
props_no_requires,
updates_status)
if order is not None:
order.append(path)
if childapi.option.isoptiondescription():
web_type = 'optiondescription'
if childapi_option.isleadership():
type_ = 'array'
else:
type_ = 'object'
if schema is not None:
schema[path] = {'properties': {},
'type': type_}
subschema = schema[path]['properties']
else:
subschema = schema
self.walk(path,
childapi,
subschema,
model,
form,
order,
updates_status)
else:
child = childapi_option.get()
childtype = child.__class__.__name__
if childtype == 'SynDynOption':
childtype = child._impl_getopt().__class__.__name__
if childapi_option.issymlinkoption():
web_type = 'symlink'
else:
web_type = childapi_option.type()
value = childapi.option.default()
if value == []:
value = None
is_multi = childapi_option.ismulti()
if is_multi:
defaultmulti = childapi_option.defaultmulti()
if defaultmulti == []:
defaultmulti = None
else:
defaultmulti = None
if schema is not None:
self.gen_schema(schema,
childapi,
childapi_option,
path,
props_no_requires,
value,
defaultmulti,
is_multi,
web_type,
form)
if form is not None:
self.gen_form(form,
web_type,
path,
child,
childapi_option,
childtype)
if schema is not None:
if web_type != 'symlink':
schema[path]['title'] = childapi_option.doc()
self.add_help(schema[path],
childapi)
except Exception as err:
if not init:
raise err
error = err
if init and form is not None:
self.callbacks.process(form)
self.requires.process(form)
self.consistencies.process(form)
del self.requires
del self.consistencies
del self.callbacks
if error:
msg = str(error)
del error
raise ConfigError(_('unable to transform tiramisu object to dict: {}').format(msg))
def gen_schema(self,
@ -468,9 +466,10 @@ class TiramisuDict:
path,
props_no_requires,
value,
default,
defaultmulti,
is_multi,
web_type):
web_type,
form):
schema[path] = {'type': web_type}
if childapi_option.issymlinkoption():
schema[path]['opt_path'] = childapi_option.get().impl_getopt().impl_getpath()
@ -478,8 +477,8 @@ class TiramisuDict:
if value is not None:
schema[path]['value'] = value
if default is not None:
schema[path]['default'] = default
if defaultmulti is not None:
schema[path]['defaultmulti'] = defaultmulti
if is_multi:
schema[path]['isMulti'] = is_multi
@ -491,6 +490,12 @@ class TiramisuDict:
schema[path]['autoFreeze'] = True
if web_type == 'choice':
values, values_params = childapi.value.callbacks()
if values_params:
for values_param in chain(values_params.args, values_params.kwargs.values()):
if isinstance(values_param, ParamOption):
self.set_remotable(path, form, childapi)
return
schema[path]['enum'] = self.get_enum(childapi,
is_multi,
path,
@ -514,26 +519,28 @@ class TiramisuDict:
path,
child,
childapi_option,
childtype,
has_value):
childtype):
obj_form = {}
if path in form:
obj_form.update(form[path])
if not childapi_option.issymlinkoption():
if self.clearable == 'all':
obj_form['clearable'] = True
if has_value and self.clearable != 'none':
if self.clearable != 'none':
obj_form['clearable'] = True
if self.remotable == 'all' or childapi_option.has_dependency():
obj_form['remote'] = True
pattern = childapi_option.pattern()
if pattern is not None:
obj_form['pattern'] = pattern
if childtype == 'IPOption' and (child.impl_get_extra('_private_only') or not child.impl_get_extra('_allow_reserved') or child.impl_get_extra('_cidr')):
obj_form['remote'] = True
if not obj_form.get('remote', False):
pattern = childapi_option.pattern()
if pattern is not None:
obj_form['pattern'] = pattern
if childtype == 'PortOption':
obj_form['min'] = child.impl_get_extra('_min_value')
obj_form['max'] = child.impl_get_extra('_max_value')
if childtype == 'FloatOption':
obj_form['step'] = 'any'
if childtype == 'PortOption':
obj_form['min'] = child.impl_get_extra('_min_value')
obj_form['max'] = child.impl_get_extra('_max_value')
if web_type == 'choice':
obj_form['type'] = 'choice'
elif web_type in INPUTS:
@ -541,50 +548,67 @@ class TiramisuDict:
if obj_form:
form[path] = obj_form
def calc_raises_properties(self, childapi):
def calc_raises_properties(self,
obj,
childapi):
old_properties = childapi._option_bag.config_bag.properties
del childapi._option_bag.config_bag.properties
ret = childapi.option.properties(only_raises=True)
if 'permissive' not in childapi._option_bag.config_bag.properties:
childapi._option_bag.config_bag.properties = childapi._option_bag.config_bag.properties | {'permissive'}
# 'display=False' means cannot access only without permissive option
# 'hidden=True' means cannot access with or without permissive option
if childapi.option.properties(only_raises=True):
obj['hidden'] = True
childapi._option_bag.config_bag.properties = childapi._option_bag.config_bag.properties - {'permissive'}
if childapi.option.properties(only_raises=True):
obj['display'] = False
childapi._option_bag.config_bag.properties = old_properties
return ret
def _gen_model_properties(self,
childapi,
path,
index,
props_no_requires):
obj = {}
isfollower = childapi.option.isfollower()
if index is None and isfollower:
# cannot calculated requires with follower without index
props = props_no_requires
else:
props = set(childapi.property.get())
if self.calc_raises_properties(childapi):
obj['display'] = False
if not isfollower and childapi.option.ismulti():
if 'empty' in props:
obj = self.gen_properties(props,
isfollower,
childapi.option.ismulti())
self.calc_raises_properties(obj, childapi)
return obj
def gen_properties(self,
properties,
isfollower=False,
ismulti=False):
obj = {}
if not isfollower and ismulti:
if 'empty' in properties:
obj['required'] = True
props.remove('empty')
if 'mandatory' in props:
properties.remove('empty')
if 'mandatory' in properties:
obj['needs_len'] = True
props.remove('mandatory')
elif 'mandatory' in props:
properties.remove('mandatory')
elif 'mandatory' in properties:
obj['required'] = True
props.remove('mandatory')
if 'frozen' in props:
properties.remove('mandatory')
if 'frozen' in properties:
obj['readOnly'] = True
props.remove('frozen')
if 'hidden' in props:
obj['hidden'] = True
props.remove('hidden')
if 'disabled' in props:
obj['hidden'] = True
props.remove('disabled')
if props:
lprops = list(props)
properties.remove('frozen')
#if 'hidden' in properties:
# obj['hidden'] = True
# properties.remove('hidden')
#if 'disabled' in properties:
# obj['hidden'] = True
# properties.remove('disabled')
if properties:
lprops = list(properties)
lprops.sort()
obj['properties'] = lprops
obj['props'] = lprops
return obj
def gen_model(self,
@ -597,14 +621,11 @@ class TiramisuDict:
if childapi.option.isoptiondescription():
props = set(childapi.property.get())
obj = {}
if self.calc_raises_properties(childapi):
obj['display'] = False
self.calc_raises_properties(obj, childapi)
if props:
lprops = list(props)
lprops.sort()
obj['properties'] = lprops
if 'hidden' in props or 'disabled' in props:
obj['hidden'] = True
try:
self.config.option(path).option.get()
except PropertiesOptionError:
@ -646,17 +667,27 @@ class TiramisuDict:
obj,
index,
updates_status):
# FIXME unrestraint ...
try:
nchildapi = self.config.option(path, index=index)
with warnings.catch_warnings(record=True) as warns:
value = nchildapi.value.get()
if path in updates_status and index in updates_status[path]:
value = childapi.value.get()
self._get_value_with_exception(obj,
childapi,
warns)
except PropertiesOptionError:
value = childapi.value.get()
warns = []
updates_status[path][index])
del updates_status[path][index]
else:
try:
nchildapi = self.config.option(path, index=index)
with warnings.catch_warnings(record=True) as warns:
value = nchildapi.value.get()
self._get_value_with_exception(obj,
childapi,
warns)
except ValueError as err:
self._get_value_with_exception(obj,
childapi,
[err])
value = self.config.unrestraint.option(path, index=index).value.get()
except PropertiesOptionError as err:
value = childapi.value.get()
if value is not None and value != []:
obj['value'] = value
obj['owner'] = childapi.owner.get()
@ -666,9 +697,13 @@ class TiramisuDict:
childapi,
values):
for value in values:
if isinstance(value.message, ValueErrorWarning):
if isinstance(value, ValueError):
obj.setdefault('error', [])
obj['error'].append(str(value))
obj['invalid'] = True
elif isinstance(value.message, ValueErrorWarning):
value.message.prefix = ''
if childapi.option.isleader():
if childapi.option.isfollower():
obj.setdefault('invalid', [])
obj['invalid'].append({'error': str(value.message),
'index': value.message.index})
@ -681,10 +716,19 @@ class TiramisuDict:
obj['warnings'].append(str(value.message))
obj['hasWarnings'] = True
def gen_global(self):
ret = {}
ret['owner'] = self.config.owner.get()
ret['properties'] = list(self.config.property.get())
ret['properties'].sort()
ret['permissives'] = list(self.config.permissive.get())
ret['permissives'].sort()
return ret
def get_form(self, form):
ret = []
buttons = []
dict_form = OrderedDict()
dict_form = {}
for form_ in form:
if 'key' in form_:
dict_form[form_['key']] = form_
@ -723,7 +767,7 @@ class TiramisuDict:
childapi.value.set(value)
else:
multi = childapi.value.get()
if not multi and index == 0:
if len(multi) < index + 1:
multi.append(value)
else:
multi[index] = value
@ -744,26 +788,25 @@ class TiramisuDict:
if childapi_option.isfollower():
childapi = self.config.option(path, index)
with warnings.catch_warnings(record=True) as warns:
#try:
if update['action'] == 'modify':
self.mod_value(childapi,
path,
index,
update.get('value'))
elif update['action'] == 'delete':
self.del_value(childapi,
path,
index)
elif update['action'] == 'add':
if childapi_option.ismulti():
self.add_value(childapi, path, update['value'])
try:
if update['action'] == 'modify':
self.mod_value(childapi,
path,
index,
update.get('value', undefined))
elif update['action'] == 'delete':
self.del_value(childapi,
path,
index)
elif update['action'] == 'add':
if childapi_option.ismulti():
self.add_value(childapi, path, update['value'])
else:
raise ValueError(_('only multi option can have action "add", but "{}" is not a multi').format(path))
else:
raise ValueError(_('only multi option can have action "add", but "{}" is not a multi').format(path))
else:
raise ValueError(_('unknown action'))
#except ValueError as err:
# updates_status.setdefault(path, {})[index] = err
# continue
raise ValueError(_('unknown action'))
except ValueError as err:
updates_status.setdefault(path, {})[index] = [err]
if warns != []:
updates_status.setdefault(path, {}).setdefault(index, []).extend(warns)
return updates_status
@ -797,7 +840,7 @@ class TiramisuDict:
updates_status={}):
rootpath = self.root
if build_schema:
schema = OrderedDict()
schema = {}
else:
schema = None
if build_model:
@ -809,6 +852,7 @@ class TiramisuDict:
buttons = []
else:
form = None
ret = {}
self.walk(rootpath,
None,
schema,
@ -832,6 +876,7 @@ class TiramisuDict:
ret['schema'] = schema
if build_model:
ret['model'] = model
ret['global'] = self.gen_global()
if build_form:
ret['form'] = form
ret['version'] = '1.0'

View file

@ -77,7 +77,7 @@ class Values(object):
check_error=True)
# store value in cache
validator = 'validator' in option_bag.config_bag.properties
if not is_cached or validator:
if not option_bag.fromconsistency and (not is_cached or validator):
self._p_.setcache(option_bag.path,
option_bag.index,
value,