Merge branch 'master' of ssh://git.labs.libre-entreprise.org/gitroot/tiramisu
This commit is contained in:
commit
f3a826a8d7
@ -6,10 +6,11 @@
|
||||
import autopath
|
||||
from py.test import raises
|
||||
|
||||
from tiramisu.config import Config
|
||||
from tiramisu.config import Config, SubConfig
|
||||
from tiramisu.option import IntOption, FloatOption, StrOption, ChoiceOption, \
|
||||
BoolOption, UnicodeOption, OptionDescription
|
||||
from tiramisu.error import ConflictError, ConfigError
|
||||
import weakref
|
||||
|
||||
|
||||
def make_description():
|
||||
@ -294,3 +295,26 @@ def test_delete_config_with_subconfig():
|
||||
raises(ConfigError, 'val[multi]')
|
||||
raises(ConfigError, 'setting[test]')
|
||||
raises(ConfigError, 'sub.make_dict()')
|
||||
|
||||
|
||||
def test_config_weakref():
|
||||
o = OptionDescription('val', '', [])
|
||||
o2 = OptionDescription('val', '', [o])
|
||||
c = Config(o2)
|
||||
SubConfig(o, weakref.ref(c))
|
||||
raises(ValueError, "SubConfig(o, c)")
|
||||
s = SubConfig(o, weakref.ref(c))
|
||||
assert s._cfgimpl_get_context() == c
|
||||
del(c)
|
||||
raises(ConfigError, "s._cfgimpl_get_context()")
|
||||
|
||||
|
||||
def test_config_str():
|
||||
gcdummy = BoolOption('dummy', 'dummy', default=False)
|
||||
gcdummy1 = BoolOption('dummy1', 'dummy', default=False, properties=('disabled',))
|
||||
o = OptionDescription('o', '', [gcdummy, gcdummy1])
|
||||
descr = OptionDescription('tiramisu', '', [o])
|
||||
cfg = Config(descr)
|
||||
cfg.read_only()
|
||||
str(cfg)
|
||||
str(cfg.o)
|
||||
|
@ -4,26 +4,34 @@ from py.test import raises
|
||||
|
||||
from tiramisu.config import Config
|
||||
from tiramisu.option import IntOption, FloatOption, StrOption, ChoiceOption, \
|
||||
BoolOption, FilenameOption, OptionDescription
|
||||
BoolOption, FilenameOption, UnicodeOption, SymLinkOption, IPOption, \
|
||||
PortOption, NetworkOption, NetmaskOption, BroadcastOption, \
|
||||
DomainnameOption, OptionDescription
|
||||
from tiramisu.error import PropertiesOptionError
|
||||
|
||||
|
||||
def make_description():
|
||||
gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref')
|
||||
gcdummy = BoolOption('dummy', 'dummy', default=False)
|
||||
prop = BoolOption('prop', '', properties=('disabled',))
|
||||
prop2 = BoolOption('prop', '', properties=('hidden',))
|
||||
objspaceoption = ChoiceOption('objspace', 'Object space',
|
||||
('std', 'thunk'), 'std')
|
||||
booloption = BoolOption('bool', 'Test boolean option', default=True)
|
||||
booloption2 = BoolOption('bool', 'Test boolean option', default=False)
|
||||
intoption = IntOption('int', 'Test int option', default=0)
|
||||
floatoption2 = FloatOption('float', 'Test float option', default=2.3)
|
||||
floatoption = FloatOption('float', 'Test float option', default=2.3)
|
||||
stroption = StrOption('str', 'Test string option', default="abc")
|
||||
boolop = BoolOption('boolop', 'Test boolean option op', default=True)
|
||||
wantref_option = BoolOption('wantref', 'Tests', default=False)
|
||||
wantframework_option = BoolOption('wantframework', 'Test', default=False)
|
||||
gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption])
|
||||
gcgroup2 = OptionDescription('gc2', '', [booloption2, prop])
|
||||
gcgroup = OptionDescription('gc', '', [gcgroup2, gcoption, gcdummy, floatoption, prop2])
|
||||
descr = OptionDescription('tiramisu', '', [gcgroup, booloption, objspaceoption,
|
||||
wantref_option, stroption,
|
||||
wantframework_option,
|
||||
intoption, boolop])
|
||||
intoption, boolop, floatoption2])
|
||||
return descr
|
||||
|
||||
|
||||
@ -62,6 +70,17 @@ def test_iter_config():
|
||||
[('string', 'string'), ('string2', 'string2')]
|
||||
|
||||
|
||||
def test_iter_config_property():
|
||||
"iteration on config object"
|
||||
s = StrOption("string", "", default="string", properties=('disabled',))
|
||||
s2 = StrOption("string2", "", default="string2")
|
||||
descr = OptionDescription("options", "", [s, s2])
|
||||
config = Config(descr)
|
||||
config.read_only()
|
||||
assert [(name, value) for name, value in config] == \
|
||||
[('string2', 'string2')]
|
||||
|
||||
|
||||
def test_iter_subconfig():
|
||||
"iteration on config sub object"
|
||||
descr = make_description()
|
||||
@ -100,20 +119,41 @@ def test_find_in_config():
|
||||
"finds option in config"
|
||||
descr = make_description()
|
||||
conf = Config(descr)
|
||||
conf.read_only()
|
||||
assert conf.find(byname='dummy') == [conf.unwrap_from_path('gc.dummy')]
|
||||
assert conf.find(byname='float') == [conf.unwrap_from_path('gc.float'), conf.unwrap_from_path('float')]
|
||||
assert conf.find_first(byname='bool') == conf.unwrap_from_path('gc.gc2.bool')
|
||||
assert conf.find_first(byname='bool', byvalue=True) == conf.unwrap_from_path('bool')
|
||||
assert conf.find_first(byname='dummy') == conf.unwrap_from_path('gc.dummy')
|
||||
assert conf.find_first(byname='float') == conf.unwrap_from_path('gc.float')
|
||||
assert conf.find(bytype=ChoiceOption) == [conf.unwrap_from_path('gc.name'), conf.unwrap_from_path('objspace')]
|
||||
assert conf.find_first(bytype=ChoiceOption) == conf.unwrap_from_path('gc.name')
|
||||
assert conf.find(byvalue='ref') == [conf.unwrap_from_path('gc.name')]
|
||||
assert conf.find_first(byvalue='ref') == conf.unwrap_from_path('gc.name')
|
||||
assert conf.find(byname='prop') == [conf.unwrap_from_path('gc.prop')]
|
||||
conf.read_write()
|
||||
raises(AttributeError, "assert conf.find(byname='prop')")
|
||||
assert conf.find(byname='prop', check_properties=False) == [conf.unwrap_from_path('gc.gc2.prop'), conf.unwrap_from_path('gc.prop')]
|
||||
#assert conf.find_first(byname='prop') == conf.unwrap_from_path('gc.prop')
|
||||
# combinaison of filters
|
||||
assert conf.find(bytype=BoolOption, byname='dummy') == [conf.unwrap_from_path('gc.dummy')]
|
||||
assert conf.find_first(bytype=BoolOption, byname='dummy') == conf.unwrap_from_path('gc.dummy')
|
||||
assert conf.find(byvalue=False, byname='dummy') == [conf.unwrap_from_path('gc.dummy')]
|
||||
assert conf.find_first(byvalue=False, byname='dummy') == conf.unwrap_from_path('gc.dummy')
|
||||
## byattrs
|
||||
#assert conf.find_first(byattrs= dict(default=2.3)) == conf.unwrap_from_path('gc.float')
|
||||
#assert conf.find_first(byvalue=False, byname='dummy', byattrs=dict(default=False)) == conf.unwrap_from_path('gc.dummy')
|
||||
#subconfig
|
||||
assert conf.gc.find(byname='dummy') == [conf.unwrap_from_path('gc.dummy')]
|
||||
assert conf.gc.find(byname='float') == [conf.unwrap_from_path('gc.float')]
|
||||
assert conf.gc.find(byname='bool') == [conf.unwrap_from_path('gc.gc2.bool')]
|
||||
assert conf.gc.find_first(byname='bool', byvalue=False) == conf.unwrap_from_path('gc.gc2.bool')
|
||||
raises(AttributeError, "assert conf.gc.find_first(byname='bool', byvalue=True)")
|
||||
raises(AttributeError, "conf.gc.find(byname='wantref').first()")
|
||||
assert conf.gc.find(byname='prop', check_properties=False) == [conf.unwrap_from_path('gc.gc2.prop'), conf.unwrap_from_path('gc.prop')]
|
||||
conf.read_only()
|
||||
assert conf.gc.find(byname='prop') == [conf.unwrap_from_path('gc.prop')]
|
||||
# not OptionDescription
|
||||
raises(AttributeError, "conf.find_first(byname='gc')")
|
||||
raises(AttributeError, "conf.gc.find_first(byname='gc2')")
|
||||
raises(ValueError, "conf.find(byname='bool', type_='unknown')")
|
||||
|
||||
|
||||
def test_find_multi():
|
||||
@ -152,3 +192,66 @@ def test_filename():
|
||||
c.a = u'tmp/text.txt'
|
||||
raises(ValueError, "c.a = u'/tmp/with space.txt'")
|
||||
raises(ValueError, "c.a = u'/tmp/with$.txt'")
|
||||
|
||||
|
||||
def test_iter_all():
|
||||
s = StrOption("string", "", default="string")
|
||||
s2 = StrOption("string2", "", default="string2")
|
||||
descr = OptionDescription("options", "", [s, s2])
|
||||
config = Config(descr)
|
||||
assert list(config.iter_all()) == [('string', 'string'), ('string2', 'string2')]
|
||||
for i in config.iter_all():
|
||||
#test StopIteration
|
||||
break
|
||||
|
||||
|
||||
def test_iter_all_prop():
|
||||
s = StrOption("string", "", default="string", properties=('disabled',))
|
||||
s2 = StrOption("string2", "", default="string2")
|
||||
descr = OptionDescription("options", "", [s, s2])
|
||||
config = Config(descr)
|
||||
config.read_only()
|
||||
assert list(config.iter_all()) == [('string2', 'string2')]
|
||||
|
||||
|
||||
def test_impl_getpaths():
|
||||
s = StrOption("string", "", default="string", properties=('disabled',))
|
||||
s2 = StrOption("string2", "", default="string2")
|
||||
s3 = StrOption("string3", "", default="string3")
|
||||
s4 = StrOption("string4", "", default="string4", properties=('hidden',))
|
||||
od = OptionDescription('od', '', [s3, s4])
|
||||
descr = OptionDescription("options", "", [s, s2, od])
|
||||
config = Config(descr)
|
||||
assert ['string', 'string2', 'od.string3', 'od.string4'] == config.cfgimpl_get_description().impl_getpaths()
|
||||
assert ['string', 'string2', 'od', 'od.string3', 'od.string4'] == config.cfgimpl_get_description().impl_getpaths(include_groups=True)
|
||||
config.read_write()
|
||||
raises(PropertiesOptionError, "config.od.string4")
|
||||
assert ['string', 'string2', 'od.string3', 'od.string4'] == config.cfgimpl_get_description().impl_getpaths()
|
||||
assert ['string', 'string2', 'od', 'od.string3', 'od.string4'] == config.cfgimpl_get_description().impl_getpaths(include_groups=True)
|
||||
|
||||
|
||||
def test_invalid_option():
|
||||
raises(TypeError, "ChoiceOption('a', '', [1, 2])")
|
||||
raises(TypeError, "ChoiceOption('a', '', 1)")
|
||||
raises(TypeError, "ChoiceOption('a', '', (1,), open_values='string')")
|
||||
raises(ValueError, "ChoiceOption('a', '', (1,), 3)")
|
||||
raises(ValueError, "FloatOption('a', '', 'string')")
|
||||
raises(ValueError, "UnicodeOption('a', '', 1)")
|
||||
raises(ValueError, "SymLinkOption('a', 'string')")
|
||||
raises(ValueError, "IPOption('a', '', 1)")
|
||||
raises(ValueError, "IPOption('a', '', 'string')")
|
||||
raises(ValueError, "PortOption('a', '', 'string')")
|
||||
raises(ValueError, "PortOption('a', '', '11:12:13', allow_range=True)")
|
||||
raises(ValueError, "PortOption('a', '', 11111111111111111111)")
|
||||
raises(ValueError, "PortOption('a', '', allow_zero=True, allow_wellknown=False, allow_registred=True, allow_private=False)")
|
||||
raises(ValueError, "PortOption('a', '', allow_zero=True, allow_wellknown=True, allow_registred=False, allow_private=True)")
|
||||
raises(ValueError, "PortOption('a', '', allow_zero=True, allow_wellknown=False, allow_registred=False, allow_private=True)")
|
||||
raises(ValueError, "PortOption('a', '', allow_zero=True, allow_wellknown=False, allow_registred=True, allow_private=True)")
|
||||
raises(ValueError, "PortOption('a', '', allow_zero=False, allow_wellknown=False, allow_registred=False, allow_private=False)")
|
||||
raises(ValueError, "NetworkOption('a', '', 'string')")
|
||||
raises(ValueError, "NetmaskOption('a', '', 'string')")
|
||||
raises(ValueError, "BroadcastOption('a', '', 'string')")
|
||||
raises(ValueError, "DomainnameOption('a', '', 'string')")
|
||||
raises(ValueError, "DomainnameOption('a', '', type_='string')")
|
||||
raises(ValueError, "DomainnameOption('a', '', allow_ip='string')")
|
||||
raises(ValueError, "DomainnameOption('a', '', allow_without_dot='string')")
|
||||
|
@ -7,9 +7,9 @@ from tiramisu.option import DomainnameOption, EmailOption, URLOption, OptionDesc
|
||||
|
||||
def test_domainname():
|
||||
d = DomainnameOption('d', '')
|
||||
e = DomainnameOption('e', '', "toto.com")
|
||||
f = DomainnameOption('f', '', allow_without_dot=True)
|
||||
od = OptionDescription('a', '', [d, f])
|
||||
g = DomainnameOption('g', '', allow_ip=True)
|
||||
od = OptionDescription('a', '', [d, f, g])
|
||||
c = Config(od)
|
||||
c.read_write()
|
||||
c.d = 'toto.com'
|
||||
@ -24,6 +24,12 @@ def test_domainname():
|
||||
#
|
||||
c.f = 'toto.com'
|
||||
c.f = 'toto'
|
||||
raises(ValueError, "c.f = 'domainnametoolongthathavemorethanmaximumsizeforatruedomainnameanditsnoteasytogeneratesolongdomainnamewithoutrepeatdomainnametoolongthathavemorethanmaximumsizeforatruedomainnameanditsnoteasytogeneratesolongdomainnamewithoutrepeatbutimnotabletodoitnowiendityeah'")
|
||||
raises(ValueError, "c.f = 'd'")
|
||||
#
|
||||
c.g = 'toto.com'
|
||||
c.g = '192.168.1.0'
|
||||
c.g = '192.168.1.29'
|
||||
|
||||
def test_special_domain_name():
|
||||
"""domain name option that starts with a number or not
|
||||
@ -69,6 +75,7 @@ def test_email():
|
||||
c.e = 'root@foo.com'
|
||||
raises(ValueError, "c.e = 'root'")
|
||||
raises(ValueError, "c.e = 'root@domain'")
|
||||
raises(ValueError, "c.e = 'root[]@domain'")
|
||||
|
||||
|
||||
def test_url():
|
||||
@ -89,3 +96,4 @@ def test_url():
|
||||
c.u = 'https://foo.com:8443'
|
||||
c.u = 'https://foo.com:8443/'
|
||||
c.u = 'https://foo.com:8443/index.html'
|
||||
raises(ValueError, "c.u = 'https://foo.com:84438989'")
|
||||
|
@ -2,8 +2,8 @@
|
||||
import autopath
|
||||
#from py.test import raises
|
||||
|
||||
from tiramisu.config import Config
|
||||
from tiramisu.option import BoolOption, OptionDescription
|
||||
from tiramisu.config import Config, GroupConfig, MetaConfig
|
||||
from tiramisu.option import BoolOption, IntOption, OptionDescription
|
||||
import weakref
|
||||
|
||||
|
||||
@ -109,3 +109,31 @@ def test_deref_optiondescription_config():
|
||||
assert w() is not None
|
||||
del(c)
|
||||
assert w() is None
|
||||
|
||||
|
||||
def test_deref_groupconfig():
|
||||
i1 = IntOption('i1', '')
|
||||
od1 = OptionDescription('od1', '', [i1])
|
||||
od2 = OptionDescription('od2', '', [od1])
|
||||
conf1 = Config(od2)
|
||||
conf2 = Config(od2)
|
||||
meta = GroupConfig([conf1, conf2])
|
||||
w = weakref.ref(conf1)
|
||||
del(conf1)
|
||||
assert w() is not None
|
||||
del(meta)
|
||||
assert w() is None
|
||||
|
||||
|
||||
def test_deref_metaconfig():
|
||||
i1 = IntOption('i1', '')
|
||||
od1 = OptionDescription('od1', '', [i1])
|
||||
od2 = OptionDescription('od2', '', [od1])
|
||||
conf1 = Config(od2)
|
||||
conf2 = Config(od2)
|
||||
meta = MetaConfig([conf1, conf2])
|
||||
w = weakref.ref(conf1)
|
||||
del(conf1)
|
||||
assert w() is not None
|
||||
del(meta)
|
||||
assert w() is None
|
||||
|
@ -1,172 +1,203 @@
|
||||
#import autopath
|
||||
import autopath
|
||||
|
||||
#from py.test import raises
|
||||
from py.test import raises
|
||||
|
||||
#from tiramisu.setting import owners
|
||||
#from tiramisu.config import Config, MetaConfig
|
||||
#from tiramisu.option import IntOption, OptionDescription
|
||||
#from tiramisu.error import ConfigError
|
||||
from tiramisu.setting import owners
|
||||
from tiramisu.config import Config, GroupConfig, MetaConfig
|
||||
from tiramisu.option import IntOption, OptionDescription
|
||||
from tiramisu.error import ConfigError, PropertiesOptionError
|
||||
|
||||
#owners.addowner('meta')
|
||||
owners.addowner('meta')
|
||||
|
||||
|
||||
#def make_description():
|
||||
# i1 = IntOption('i1', '')
|
||||
# i2 = IntOption('i2', '', default=1)
|
||||
# i3 = IntOption('i3', '')
|
||||
# i4 = IntOption('i4', '', default=2)
|
||||
# od1 = OptionDescription('od1', '', [i1, i2, i3, i4])
|
||||
# od2 = OptionDescription('od2', '', [od1])
|
||||
# conf1 = Config(od2)
|
||||
# conf2 = Config(od2)
|
||||
# meta = MetaConfig([conf1, conf2])
|
||||
# meta.cfgimpl_get_settings().setowner(owners.meta)
|
||||
# return meta
|
||||
def make_description():
|
||||
i1 = IntOption('i1', '')
|
||||
i2 = IntOption('i2', '', default=1)
|
||||
i3 = IntOption('i3', '')
|
||||
i4 = IntOption('i4', '', default=2)
|
||||
i5 = IntOption('i5', '', default=[2], multi=True)
|
||||
i6 = IntOption('i6', '', properties=('disabled',))
|
||||
od1 = OptionDescription('od1', '', [i1, i2, i3, i4, i5, i6])
|
||||
od2 = OptionDescription('od2', '', [od1])
|
||||
conf1 = Config(od2)
|
||||
conf2 = Config(od2)
|
||||
conf1.read_write()
|
||||
conf2.read_write()
|
||||
meta = MetaConfig([conf1, conf2])
|
||||
meta.cfgimpl_get_settings().setowner(owners.meta)
|
||||
return meta
|
||||
|
||||
|
||||
##FIXME ne pas mettre 2 meta dans une config
|
||||
##FIXME ne pas mettre 2 OD differents dans un meta
|
||||
#def test_none():
|
||||
# meta = make_description()
|
||||
# conf1, conf2 = meta._impl_children
|
||||
# assert conf1.od1.i3 is conf2.od1.i3 is None
|
||||
# assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.default
|
||||
# meta.od1.i3 = 3
|
||||
# assert conf1.od1.i3 == conf2.od1.i3 == 3
|
||||
# assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.meta
|
||||
# meta.od1.i3 = 3
|
||||
# conf1.od1.i3 = 2
|
||||
# assert conf1.od1.i3 == 2
|
||||
# assert conf2.od1.i3 == 3
|
||||
# assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is owners.user
|
||||
# assert conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.meta
|
||||
# meta.od1.i3 = 4
|
||||
# assert conf1.od1.i3 == 2
|
||||
# assert conf2.od1.i3 == 4
|
||||
# assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is owners.user
|
||||
# assert conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.meta
|
||||
# del(meta.od1.i3)
|
||||
# assert conf1.od1.i3 == 2
|
||||
# assert conf2.od1.i3 is None
|
||||
# assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is owners.user
|
||||
# assert conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.default
|
||||
# del(conf1.od1.i3)
|
||||
# assert conf1.od1.i3 is conf2.od1.i3 is None
|
||||
# assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.default
|
||||
#FIXME ne pas mettre 2 meta dans une config
|
||||
#FIXME ne pas mettre 2 OD differents dans un meta
|
||||
#FIXME serialization
|
||||
def test_none():
|
||||
meta = make_description()
|
||||
conf1, conf2 = meta.cfgimpl_get_children()
|
||||
assert conf1.od1.i3 is conf2.od1.i3 is None
|
||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.default
|
||||
meta.od1.i3 = 3
|
||||
assert conf1.od1.i3 == conf2.od1.i3 == 3
|
||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.meta
|
||||
meta.od1.i3 = 3
|
||||
conf1.od1.i3 = 2
|
||||
assert conf1.od1.i3 == 2
|
||||
assert conf2.od1.i3 == 3
|
||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is owners.user
|
||||
assert conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.meta
|
||||
meta.od1.i3 = 4
|
||||
assert conf1.od1.i3 == 2
|
||||
assert conf2.od1.i3 == 4
|
||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is owners.user
|
||||
assert conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.meta
|
||||
del(meta.od1.i3)
|
||||
assert conf1.od1.i3 == 2
|
||||
assert conf2.od1.i3 is None
|
||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is owners.user
|
||||
assert conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.default
|
||||
del(conf1.od1.i3)
|
||||
assert conf1.od1.i3 is conf2.od1.i3 is None
|
||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.default
|
||||
|
||||
|
||||
#def test_default():
|
||||
# meta = make_description()
|
||||
# conf1, conf2 = meta._impl_children
|
||||
# assert conf1.od1.i2 == conf2.od1.i2 == 1
|
||||
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
|
||||
# meta.od1.i2 = 3
|
||||
# assert conf1.od1.i2 == conf2.od1.i2 == 3
|
||||
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
|
||||
# meta.od1.i2 = 3
|
||||
# conf1.od1.i2 = 2
|
||||
# assert conf1.od1.i2 == 2
|
||||
# assert conf2.od1.i2 == 3
|
||||
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user
|
||||
# assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
|
||||
# meta.od1.i2 = 4
|
||||
# assert conf1.od1.i2 == 2
|
||||
# assert conf2.od1.i2 == 4
|
||||
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user
|
||||
# assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
|
||||
# del(meta.od1.i2)
|
||||
# assert conf1.od1.i2 == 2
|
||||
# assert conf2.od1.i2 == 1
|
||||
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user
|
||||
# assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
|
||||
# del(conf1.od1.i2)
|
||||
# assert conf1.od1.i2 == conf2.od1.i2 == 1
|
||||
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
|
||||
def test_default():
|
||||
meta = make_description()
|
||||
conf1, conf2 = meta.cfgimpl_get_children()
|
||||
assert conf1.od1.i2 == conf2.od1.i2 == 1
|
||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
|
||||
meta.od1.i2 = 3
|
||||
assert conf1.od1.i2 == conf2.od1.i2 == 3
|
||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
|
||||
meta.od1.i2 = 3
|
||||
conf1.od1.i2 = 2
|
||||
assert conf1.od1.i2 == 2
|
||||
assert conf2.od1.i2 == 3
|
||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user
|
||||
assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
|
||||
meta.od1.i2 = 4
|
||||
assert conf1.od1.i2 == 2
|
||||
assert conf2.od1.i2 == 4
|
||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user
|
||||
assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
|
||||
del(meta.od1.i2)
|
||||
assert conf1.od1.i2 == 2
|
||||
assert conf2.od1.i2 == 1
|
||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user
|
||||
assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
|
||||
del(conf1.od1.i2)
|
||||
assert conf1.od1.i2 == conf2.od1.i2 == 1
|
||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
|
||||
|
||||
|
||||
#def test_contexts():
|
||||
# meta = make_description()
|
||||
# conf1, conf2 = meta._impl_children
|
||||
# assert conf1.od1.i2 == conf2.od1.i2 == 1
|
||||
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
|
||||
# meta.set_contexts('od1.i2', 6)
|
||||
# assert meta.od1.i2 == 1
|
||||
# assert conf1.od1.i2 == conf2.od1.i2 == 6
|
||||
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.user
|
||||
def test_contexts():
|
||||
meta = make_description()
|
||||
conf1, conf2 = meta.cfgimpl_get_children()
|
||||
assert conf1.od1.i2 == conf2.od1.i2 == 1
|
||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
|
||||
meta.setattrs('od1.i2', 6)
|
||||
assert meta.od1.i2 == 1
|
||||
assert conf1.od1.i2 == conf2.od1.i2 == 6
|
||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.user
|
||||
|
||||
|
||||
#def test_find():
|
||||
# meta = make_description()
|
||||
# i2 = meta.unwrap_from_path('od1.i2')
|
||||
# assert [i2] == meta.find(byname='i2')
|
||||
# assert i2 == meta.find_first(byname='i2')
|
||||
# assert meta.make_dict() == {'od1.i4': 2, 'od1.i1': None, 'od1.i3': None, 'od1.i2': 1}
|
||||
def test_find():
|
||||
meta = make_description()
|
||||
i2 = meta.unwrap_from_path('od1.i2')
|
||||
assert [i2] == meta.find(byname='i2')
|
||||
assert i2 == meta.find_first(byname='i2')
|
||||
assert meta.make_dict() == {'od1.i4': 2, 'od1.i1': None, 'od1.i3': None,
|
||||
'od1.i2': 1, 'od1.i5': [2], 'od1.i6': None}
|
||||
|
||||
|
||||
#def test_meta_meta():
|
||||
# meta1 = make_description()
|
||||
# meta2 = MetaConfig([meta1])
|
||||
# meta2.cfgimpl_get_settings().setowner(owners.meta)
|
||||
# conf1, conf2 = meta1._impl_children
|
||||
# assert conf1.od1.i2 == conf2.od1.i2 == 1
|
||||
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
|
||||
# meta2.od1.i2 = 3
|
||||
# assert conf1.od1.i2 == conf2.od1.i2 == 3
|
||||
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
|
||||
# meta2.od1.i2 = 3
|
||||
# conf1.od1.i2 = 2
|
||||
# assert conf1.od1.i2 == 2
|
||||
# assert conf2.od1.i2 == 3
|
||||
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user
|
||||
# assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
|
||||
# meta2.od1.i2 = 4
|
||||
# assert conf1.od1.i2 == 2
|
||||
# assert conf2.od1.i2 == 4
|
||||
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user
|
||||
# assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
|
||||
# del(meta2.od1.i2)
|
||||
# assert conf1.od1.i2 == 2
|
||||
# assert conf2.od1.i2 == 1
|
||||
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user
|
||||
# assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
|
||||
# del(conf1.od1.i2)
|
||||
# assert conf1.od1.i2 == conf2.od1.i2 == 1
|
||||
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
|
||||
# meta1.od1.i2 = 6
|
||||
# assert conf1.od1.i2 == conf2.od1.i2 == 6
|
||||
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
|
||||
def test_meta_meta():
|
||||
meta1 = make_description()
|
||||
meta2 = MetaConfig([meta1])
|
||||
meta2.cfgimpl_get_settings().setowner(owners.meta)
|
||||
conf1, conf2 = meta1.cfgimpl_get_children()
|
||||
assert conf1.od1.i2 == conf2.od1.i2 == 1
|
||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
|
||||
meta2.od1.i2 = 3
|
||||
assert conf1.od1.i2 == conf2.od1.i2 == 3
|
||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
|
||||
meta2.od1.i2 = 3
|
||||
conf1.od1.i2 = 2
|
||||
assert conf1.od1.i2 == 2
|
||||
assert conf2.od1.i2 == 3
|
||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user
|
||||
assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
|
||||
meta2.od1.i2 = 4
|
||||
assert conf1.od1.i2 == 2
|
||||
assert conf2.od1.i2 == 4
|
||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user
|
||||
assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
|
||||
del(meta2.od1.i2)
|
||||
assert conf1.od1.i2 == 2
|
||||
assert conf2.od1.i2 == 1
|
||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user
|
||||
assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
|
||||
del(conf1.od1.i2)
|
||||
assert conf1.od1.i2 == conf2.od1.i2 == 1
|
||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
|
||||
meta1.od1.i2 = 6
|
||||
assert conf1.od1.i2 == conf2.od1.i2 == 6
|
||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
|
||||
|
||||
|
||||
#def test_meta_meta_set():
|
||||
# meta1 = make_description()
|
||||
# meta2 = MetaConfig([meta1])
|
||||
# meta2.cfgimpl_get_settings().setowner(owners.meta)
|
||||
# conf1, conf2 = meta1._impl_children
|
||||
# meta2.set_contexts('od1.i1', 7)
|
||||
# assert conf1.od1.i1 == conf2.od1.i1 == 7
|
||||
# assert conf1.getowner(conf1.unwrap_from_path('od1.i1')) is conf2.getowner(conf2.unwrap_from_path('od1.i1')) is owners.user
|
||||
# assert [conf1, conf2] == meta2.find_first_contexts(byname='i1', byvalue=7)
|
||||
# conf1.od1.i1 = 8
|
||||
# assert [conf2] == meta2.find_first_contexts(byname='i1', byvalue=7)
|
||||
# assert [conf1] == meta2.find_first_contexts(byname='i1', byvalue=8)
|
||||
# raises(AttributeError, "meta2.find_first_contexts(byname='i1', byvalue=10)")
|
||||
def test_meta_meta_set():
|
||||
meta1 = make_description()
|
||||
meta2 = MetaConfig([meta1])
|
||||
meta2.cfgimpl_get_settings().setowner(owners.meta)
|
||||
conf1, conf2 = meta1.cfgimpl_get_children()
|
||||
meta2.setattrs('od1.i1', 7)
|
||||
#PropertiesOptionError
|
||||
meta2.setattrs('od1.i6', 7)
|
||||
assert conf1.od1.i1 == conf2.od1.i1 == 7
|
||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i1')) is conf2.getowner(conf2.unwrap_from_path('od1.i1')) is owners.user
|
||||
assert [conf1, conf2] == meta2.find_firsts(byname='i1', byvalue=7)
|
||||
conf1.od1.i1 = 8
|
||||
assert [conf1, conf2] == meta2.find_firsts(byname='i1')
|
||||
assert [conf2] == meta2.find_firsts(byname='i1', byvalue=7)
|
||||
assert [conf1] == meta2.find_firsts(byname='i1', byvalue=8)
|
||||
assert [conf1, conf2] == meta2.find_firsts(byname='i5', byvalue=2)
|
||||
raises(AttributeError, "meta2.find_firsts(byname='i1', byvalue=10)")
|
||||
raises(AttributeError, "meta2.find_firsts(byname='not', byvalue=10)")
|
||||
raises(AttributeError, "meta2.find_firsts(byname='i6')")
|
||||
|
||||
|
||||
#def test_not_meta():
|
||||
# i1 = IntOption('i1', '')
|
||||
# od1 = OptionDescription('od1', '', [i1])
|
||||
# od2 = OptionDescription('od2', '', [od1])
|
||||
# conf1 = Config(od2)
|
||||
# conf2 = Config(od2)
|
||||
# meta = MetaConfig([conf1, conf2], False)
|
||||
# raises(ConfigError, 'meta.od1.i1')
|
||||
# conf1, conf2 = meta._impl_children
|
||||
# meta.set_contexts('od1.i1', 7)
|
||||
# assert conf1.od1.i1 == conf2.od1.i1 == 7
|
||||
# assert conf1.getowner(conf1.unwrap_from_path('od1.i1')) is conf2.getowner(conf2.unwrap_from_path('od1.i1')) is owners.user
|
||||
def test_not_meta():
|
||||
i1 = IntOption('i1', '')
|
||||
od1 = OptionDescription('od1', '', [i1])
|
||||
od2 = OptionDescription('od2', '', [od1])
|
||||
conf1 = Config(od2)
|
||||
conf2 = Config(od2)
|
||||
raises(ValueError, "GroupConfig(conf1)")
|
||||
meta = GroupConfig([conf1, conf2])
|
||||
raises(ConfigError, 'meta.od1.i1')
|
||||
conf1, conf2 = meta.cfgimpl_get_children()
|
||||
meta.setattrs('od1.i1', 7)
|
||||
assert conf1.od1.i1 == conf2.od1.i1 == 7
|
||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i1')) is conf2.getowner(conf2.unwrap_from_path('od1.i1')) is owners.user
|
||||
|
||||
|
||||
#def test_meta_path():
|
||||
# meta = make_description()
|
||||
# assert meta._impl_path is None
|
||||
# assert meta.od1._impl_path == 'od1'
|
||||
def test_meta_path():
|
||||
meta = make_description()
|
||||
assert meta._impl_path is None
|
||||
assert meta.od1._impl_path == 'od1'
|
||||
|
||||
|
||||
def test_meta_unconsistent():
|
||||
i1 = IntOption('i1', '')
|
||||
i2 = IntOption('i2', '', default=1)
|
||||
i3 = IntOption('i3', '')
|
||||
i4 = IntOption('i4', '', default=2)
|
||||
od1 = OptionDescription('od1', '', [i1, i2, i3, i4])
|
||||
od2 = OptionDescription('od2', '', [od1])
|
||||
conf1 = Config(od2)
|
||||
conf2 = Config(od2)
|
||||
conf3 = Config(od2)
|
||||
conf4 = Config(od1)
|
||||
meta = MetaConfig([conf1, conf2])
|
||||
meta.cfgimpl_get_settings().setowner(owners.meta)
|
||||
raises(TypeError, 'MetaConfig("string")')
|
||||
raises(ValueError, "MetaConfig([conf1, conf3])")
|
||||
raises(ValueError, "MetaConfig([conf3, conf4])")
|
||||
|
21
test/test_multi.py
Normal file
21
test/test_multi.py
Normal file
@ -0,0 +1,21 @@
|
||||
# coding: utf-8
|
||||
import autopath
|
||||
from tiramisu.value import Multi
|
||||
from tiramisu.option import IntOption, OptionDescription
|
||||
from tiramisu.config import Config
|
||||
from tiramisu.error import ConfigError
|
||||
|
||||
import weakref
|
||||
from py.test import raises
|
||||
|
||||
|
||||
def test_multi():
|
||||
i = IntOption('int', '', multi=True)
|
||||
o = OptionDescription('od', '', [i])
|
||||
c = Config(o)
|
||||
multi = Multi([1,2,3], weakref.ref(c), i, 'int')
|
||||
raises(ValueError, "Multi([1,2,3], c, i, 'int')")
|
||||
raises(ValueError, "Multi(multi, weakref.ref(c), i, 'int')")
|
||||
assert c is multi._getcontext()
|
||||
del(c)
|
||||
raises(ConfigError, "multi._getcontext()")
|
@ -373,6 +373,9 @@ def test_callback_multi_value():
|
||||
assert cfg.val2 == ['val']
|
||||
assert cfg.val3 == ['yes']
|
||||
assert cfg.val4 == ['val', 'yes']
|
||||
cfg.val2.append('new')
|
||||
assert cfg.val1 == ['val']
|
||||
assert cfg.val2 == ['val', 'new']
|
||||
|
||||
|
||||
def test_callback_multi_list():
|
||||
@ -466,6 +469,66 @@ def test_callback_master_and_slaves_slave():
|
||||
assert cfg.val1.val2 == ['val2', 'val2', 'val']
|
||||
|
||||
|
||||
def test_callback_master_and_slaves_slave_cal():
|
||||
val3 = StrOption('val3', "", multi=True)
|
||||
val1 = StrOption('val1', "", multi=True, callback=return_value, callback_params={'': ((val3, False),)})
|
||||
val2 = StrOption('val2', "", multi=True, callback=return_val)
|
||||
interface1 = OptionDescription('val1', '', [val1, val2])
|
||||
interface1.impl_set_group_type(groups.master)
|
||||
maconfig = OptionDescription('rootconfig', '', [interface1, val3])
|
||||
cfg = Config(maconfig)
|
||||
cfg.read_write()
|
||||
assert cfg.val3 == []
|
||||
assert cfg.val1.val1 == []
|
||||
assert cfg.val1.val2 == []
|
||||
cfg.val1.val1 = ['val1']
|
||||
cfg.val3 = ['val1']
|
||||
assert cfg.val1.val1 == ['val1']
|
||||
assert cfg.val1.val2 == ['val']
|
||||
assert cfg.val1.val1 == ['val1']
|
||||
assert cfg.val1.val2 == ['val']
|
||||
del(cfg.val1.val1)
|
||||
cfg.val1.val2 = ['val']
|
||||
cfg.val3 = ['val1', 'val2']
|
||||
assert cfg.val1.val2 == ['val', 'val']
|
||||
assert cfg.val1.val1 == ['val1', 'val2']
|
||||
cfg.val1.val2 = ['val1', 'val2']
|
||||
cfg.val3.pop(1)
|
||||
# cannot remove slave's value because master is calculated
|
||||
# so raise
|
||||
raises(SlaveError, "cfg.val1.val1")
|
||||
raises(SlaveError, "cfg.val1.val2")
|
||||
cfg.val3 = ['val1', 'val2', 'val3']
|
||||
assert cfg.val1.val2 == ['val1', 'val2', 'val']
|
||||
|
||||
|
||||
def test_callback_master_and_slaves_slave_cal2():
|
||||
val3 = StrOption('val3', "", ['val', 'val'], multi=True)
|
||||
val1 = StrOption('val1', "", multi=True, callback=return_value, callback_params={'': ((val3, False),)})
|
||||
val2 = StrOption('val2', "", ['val2', 'val2'], multi=True)
|
||||
interface1 = OptionDescription('val1', '', [val1, val2])
|
||||
interface1.impl_set_group_type(groups.master)
|
||||
maconfig = OptionDescription('rootconfig', '', [interface1, val3])
|
||||
cfg = Config(maconfig)
|
||||
cfg.read_write()
|
||||
assert cfg.val3 == ['val', 'val']
|
||||
assert cfg.val1.val1 == ['val', 'val']
|
||||
assert cfg.val1.val2 == ['val2', 'val2']
|
||||
cfg.val3.pop(1)
|
||||
# # cannot remove slave's value because master is calculated
|
||||
# # so raise
|
||||
raises(SlaveError, "cfg.val1.val1")
|
||||
raises(SlaveError, "cfg.val1.val2")
|
||||
cfg.val3 = ['val', 'val']
|
||||
assert cfg.val3 == ['val', 'val']
|
||||
assert cfg.val1.val1 == ['val', 'val']
|
||||
assert cfg.val1.val2 == ['val2', 'val2']
|
||||
raises(SlaveError, "cfg.val1.val1 = ['val']")
|
||||
assert cfg.val3 == ['val', 'val']
|
||||
assert cfg.val1.val1 == ['val', 'val']
|
||||
assert cfg.val1.val2 == ['val2', 'val2']
|
||||
|
||||
|
||||
def test_callback_master_and_slaves_slave_list():
|
||||
val1 = StrOption('val1', "", multi=True)
|
||||
val2 = StrOption('val2', "", multi=True, callback=return_list)
|
||||
|
@ -169,6 +169,18 @@ def test_consistency_network_netmask():
|
||||
raises(ValueError, "c.a = '192.168.1.1'")
|
||||
|
||||
|
||||
def test_consistency_ip_netmask_network_error():
|
||||
a = IPOption('a', '')
|
||||
b = NetworkOption('b', '')
|
||||
c = NetmaskOption('c', '')
|
||||
od = OptionDescription('od', '', [a, b, c])
|
||||
c.impl_add_consistency('ip_netmask', a, b)
|
||||
c = Config(od)
|
||||
c.a = '192.168.1.1'
|
||||
c.b = '192.168.1.0'
|
||||
raises(ConfigError, "c.c = '255.255.255.0'")
|
||||
|
||||
|
||||
def test_consistency_ip_netmask_error_multi():
|
||||
a = IPOption('a', '', multi=True)
|
||||
b = NetmaskOption('b', '')
|
||||
@ -217,6 +229,8 @@ def test_consistency_ip_netmask_multi_master():
|
||||
c.b = ['255.255.255.255']
|
||||
c.b = ['255.255.255.0']
|
||||
raises(ValueError, "c.a = ['192.168.1.0']")
|
||||
c.a = ['192.168.1.128']
|
||||
raises(ValueError, "c.b = ['255.255.255.128']")
|
||||
c.a = ['192.168.1.2', '192.168.1.3']
|
||||
|
||||
|
||||
@ -260,6 +274,20 @@ def test_consistency_broadcast():
|
||||
c.c[1] = '192.168.2.255'
|
||||
|
||||
|
||||
def test_consistency_broadcast_error():
|
||||
a = NetworkOption('a', '', multi=True)
|
||||
b = NetmaskOption('b', '', multi=True)
|
||||
c = BroadcastOption('c', '', multi=True)
|
||||
od = OptionDescription('a', '', [a, b, c])
|
||||
od.impl_set_group_type(groups.master)
|
||||
b.impl_add_consistency('network_netmask', a)
|
||||
c.impl_add_consistency('broadcast', a)
|
||||
c = Config(od)
|
||||
c.a = ['192.168.1.0']
|
||||
c.b = ['255.255.255.0']
|
||||
raises(ConfigError, "c.c = ['192.168.1.255']")
|
||||
|
||||
|
||||
def test_consistency_broadcast_default():
|
||||
a = NetworkOption('a', '', '192.168.1.0')
|
||||
b = NetmaskOption('b', '', '255.255.255.128')
|
||||
|
@ -36,6 +36,7 @@ def test_default_owner():
|
||||
cfg = Config(descr)
|
||||
assert cfg.dummy is False
|
||||
assert cfg.getowner(gcdummy) == 'default'
|
||||
raises(TypeError, "cfg.getowner('gcdummy')")
|
||||
cfg.dummy = True
|
||||
assert cfg.getowner(gcdummy) == owners.user
|
||||
|
||||
|
@ -94,6 +94,19 @@ def test_iter_on_groups():
|
||||
result = list(config.creole.iter_groups(group_type=groups.family))
|
||||
group_names = [res[0] for res in result]
|
||||
assert group_names == ['general', 'interface1']
|
||||
for i in config.creole.iter_groups(group_type=groups.family):
|
||||
#test StopIteration
|
||||
break
|
||||
|
||||
|
||||
def test_iter_on_groups_props():
|
||||
descr = make_description()
|
||||
config = Config(descr)
|
||||
config.read_write()
|
||||
config.cfgimpl_get_settings()[descr.creole.interface1].append('disabled')
|
||||
result = list(config.creole.iter_groups(group_type=groups.family))
|
||||
group_names = [res[0] for res in result]
|
||||
assert group_names == ['general']
|
||||
|
||||
|
||||
def test_iter_on_empty_group():
|
||||
|
@ -1,10 +1,13 @@
|
||||
import autopath
|
||||
|
||||
from tiramisu.option import BoolOption, UnicodeOption, SymLinkOption, \
|
||||
OptionDescription
|
||||
from tiramisu.config import Config
|
||||
IntOption, OptionDescription
|
||||
from tiramisu.config import Config, GroupConfig, MetaConfig
|
||||
from tiramisu.setting import owners
|
||||
from tiramisu.storage import delete_session
|
||||
from tiramisu.error import ConfigError
|
||||
from pickle import dumps, loads
|
||||
from py.test import raises
|
||||
|
||||
|
||||
def return_value(value=None):
|
||||
@ -90,10 +93,48 @@ def _diff_opt(opt1, opt2):
|
||||
assert val1 == val2
|
||||
|
||||
|
||||
def _diff_conf(cfg1, cfg2):
|
||||
attr1 = set(_get_slots(cfg1))
|
||||
attr2 = set(_get_slots(cfg2))
|
||||
diff1 = attr1 - attr2
|
||||
diff2 = attr2 - attr1
|
||||
if diff1 != set():
|
||||
raise Exception('more attribute in cfg1 {0}'.format(list(diff1)))
|
||||
if diff2 != set():
|
||||
raise Exception('more attribute in cfg2 {0}'.format(list(diff2)))
|
||||
for attr in attr1:
|
||||
if attr in ('_impl_context', '__weakref__'):
|
||||
continue
|
||||
err1 = False
|
||||
err2 = False
|
||||
val1 = None
|
||||
val2 = None
|
||||
try:
|
||||
val1 = getattr(cfg1, attr)
|
||||
except:
|
||||
err1 = True
|
||||
|
||||
try:
|
||||
val2 = getattr(cfg2, attr)
|
||||
except:
|
||||
err2 = True
|
||||
assert err1 == err2
|
||||
if val1 is None:
|
||||
assert val1 == val2
|
||||
elif attr == '_impl_values':
|
||||
assert cfg1.cfgimpl_get_values().get_modified_values() == cfg2.cfgimpl_get_values().get_modified_values()
|
||||
elif attr == '_impl_settings':
|
||||
assert cfg1.cfgimpl_get_settings().get_modified_properties() == cfg2.cfgimpl_get_settings().get_modified_properties()
|
||||
assert cfg1.cfgimpl_get_settings().get_modified_permissives() == cfg2.cfgimpl_get_settings().get_modified_permissives()
|
||||
elif attr == '_impl_descr':
|
||||
_diff_opt(cfg1.cfgimpl_get_description(), cfg2.cfgimpl_get_description())
|
||||
else:
|
||||
assert val1 == val2
|
||||
|
||||
|
||||
def test_diff_opt():
|
||||
b = BoolOption('b', '')
|
||||
u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}])
|
||||
#u.impl_add_consistency('not_equal', b)
|
||||
s = SymLinkOption('s', u)
|
||||
o = OptionDescription('o', '', [b, u, s])
|
||||
o1 = OptionDescription('o1', '', [o])
|
||||
@ -107,6 +148,11 @@ def test_diff_opt():
|
||||
_diff_opt(o1.o.s, q.o.s)
|
||||
|
||||
|
||||
def test_only_optiondescription():
|
||||
b = BoolOption('b', '')
|
||||
raises(SystemError, "a = dumps(b)")
|
||||
|
||||
|
||||
def test_diff_opt_cache():
|
||||
b = BoolOption('b', '')
|
||||
u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}])
|
||||
@ -169,10 +215,7 @@ def test_state_config():
|
||||
cfg._impl_test = True
|
||||
a = dumps(cfg)
|
||||
q = loads(a)
|
||||
_diff_opt(maconfig, q.cfgimpl_get_description())
|
||||
assert cfg.cfgimpl_get_values().get_modified_values() == q.cfgimpl_get_values().get_modified_values()
|
||||
assert cfg.cfgimpl_get_settings().get_modified_properties() == q.cfgimpl_get_settings().get_modified_properties()
|
||||
assert cfg.cfgimpl_get_settings().get_modified_permissives() == q.cfgimpl_get_settings().get_modified_permissives()
|
||||
_diff_conf(cfg, q)
|
||||
try:
|
||||
delete_session('29090931')
|
||||
except ConfigError:
|
||||
@ -191,12 +234,9 @@ def test_state_properties():
|
||||
cfg.cfgimpl_get_settings()[val1].append('test')
|
||||
a = dumps(cfg)
|
||||
q = loads(a)
|
||||
_diff_opt(maconfig, q.cfgimpl_get_description())
|
||||
assert cfg.cfgimpl_get_values().get_modified_values() == q.cfgimpl_get_values().get_modified_values()
|
||||
assert cfg.cfgimpl_get_settings().get_modified_properties() == q.cfgimpl_get_settings().get_modified_properties()
|
||||
assert cfg.cfgimpl_get_settings().get_modified_permissives() == q.cfgimpl_get_settings().get_modified_permissives()
|
||||
_diff_conf(cfg, q)
|
||||
try:
|
||||
delete_session('29090931')
|
||||
delete_session('29090932')
|
||||
except ConfigError:
|
||||
pass
|
||||
|
||||
@ -212,15 +252,12 @@ def test_state_values():
|
||||
cfg.val1 = True
|
||||
a = dumps(cfg)
|
||||
q = loads(a)
|
||||
_diff_opt(maconfig, q.cfgimpl_get_description())
|
||||
assert cfg.cfgimpl_get_values().get_modified_values() == q.cfgimpl_get_values().get_modified_values()
|
||||
assert cfg.cfgimpl_get_settings().get_modified_properties() == q.cfgimpl_get_settings().get_modified_properties()
|
||||
assert cfg.cfgimpl_get_settings().get_modified_permissives() == q.cfgimpl_get_settings().get_modified_permissives()
|
||||
_diff_conf(cfg, q)
|
||||
q.val1 = False
|
||||
#assert cfg.val1 is True
|
||||
assert q.val1 is False
|
||||
try:
|
||||
delete_session('29090931')
|
||||
delete_session('29090933')
|
||||
except ConfigError:
|
||||
pass
|
||||
|
||||
@ -238,14 +275,94 @@ def test_state_values_owner():
|
||||
cfg.val1 = True
|
||||
a = dumps(cfg)
|
||||
q = loads(a)
|
||||
_diff_opt(maconfig, q.cfgimpl_get_description())
|
||||
assert cfg.cfgimpl_get_values().get_modified_values() == q.cfgimpl_get_values().get_modified_values()
|
||||
assert cfg.cfgimpl_get_settings().get_modified_properties() == q.cfgimpl_get_settings().get_modified_properties()
|
||||
assert cfg.cfgimpl_get_settings().get_modified_permissives() == q.cfgimpl_get_settings().get_modified_permissives()
|
||||
_diff_conf(cfg, q)
|
||||
q.val1 = False
|
||||
nval1 = q.cfgimpl_get_description().val1
|
||||
assert q.getowner(nval1) == owners.newowner
|
||||
try:
|
||||
delete_session('29090931')
|
||||
delete_session('29090934')
|
||||
except ConfigError:
|
||||
pass
|
||||
|
||||
|
||||
def test_state_metaconfig():
|
||||
i1 = IntOption('i1', '')
|
||||
od1 = OptionDescription('od1', '', [i1])
|
||||
od2 = OptionDescription('od2', '', [od1])
|
||||
conf1 = Config(od2, session_id='29090935')
|
||||
conf1._impl_test = True
|
||||
conf2 = Config(od2, session_id='29090936')
|
||||
conf2._impl_test = True
|
||||
meta = MetaConfig([conf1, conf2], session_id='29090937')
|
||||
meta._impl_test = True
|
||||
raises(ConfigError, "dumps(meta)")
|
||||
try:
|
||||
delete_session('29090935')
|
||||
delete_session('29090936')
|
||||
delete_session('29090937')
|
||||
except ConfigError:
|
||||
pass
|
||||
|
||||
|
||||
def test_state_groupconfig():
|
||||
i1 = IntOption('i1', '')
|
||||
od1 = OptionDescription('od1', '', [i1])
|
||||
od2 = OptionDescription('od2', '', [od1])
|
||||
conf1 = Config(od2, session_id='29090935')
|
||||
conf1._impl_test = True
|
||||
conf2 = Config(od2, session_id='29090936')
|
||||
conf2._impl_test = True
|
||||
meta = GroupConfig([conf1, conf2], session_id='29090937')
|
||||
meta._impl_test = True
|
||||
a = dumps(meta)
|
||||
q = loads(a)
|
||||
_diff_conf(meta, q)
|
||||
try:
|
||||
delete_session('29090935')
|
||||
delete_session('29090936')
|
||||
delete_session('29090937')
|
||||
except ConfigError:
|
||||
pass
|
||||
|
||||
|
||||
def test_state_unkown_setting_owner():
|
||||
"""load an unknow _owner, should create it"""
|
||||
assert not 'supernewuser' in owners.__dict__
|
||||
loads("""ccopy_reg
|
||||
_reconstructor
|
||||
p0
|
||||
(ctiramisu.setting
|
||||
Settings
|
||||
p1
|
||||
c__builtin__
|
||||
object
|
||||
p2
|
||||
Ntp3
|
||||
Rp4
|
||||
(dp5
|
||||
S'_owner'
|
||||
p6
|
||||
S'supernewuser'
|
||||
p7
|
||||
sS'_p_'
|
||||
p8
|
||||
g0
|
||||
(ctiramisu.storage.dictionary.setting
|
||||
Settings
|
||||
p9
|
||||
g2
|
||||
Ntp10
|
||||
Rp11
|
||||
(dp12
|
||||
S'_cache'
|
||||
p13
|
||||
(dp14
|
||||
sS'_permissives'
|
||||
p15
|
||||
(dp16
|
||||
sS'_properties'
|
||||
p17
|
||||
(dp18
|
||||
sbsb.
|
||||
.""")
|
||||
assert 'supernewuser' in owners.__dict__
|
||||
|
@ -152,7 +152,10 @@ def carry_out_calculation(option, config, callback, callback_params,
|
||||
opt)
|
||||
# get value
|
||||
try:
|
||||
value = config._getattr(path, force_permissive=True)
|
||||
value = config._getattr(path, force_permissive=True, validate=False)
|
||||
# convert to list, not modifie this multi
|
||||
if value.__class__.__name__ == 'Multi':
|
||||
value = list(value)
|
||||
except PropertiesOptionError as err:
|
||||
if force_permissive:
|
||||
continue
|
||||
|
@ -48,7 +48,7 @@ class SubConfig(object):
|
||||
:type subpath: `str` with the path name
|
||||
"""
|
||||
# main option description
|
||||
if not isinstance(descr, OptionDescription):
|
||||
if descr is not None and not isinstance(descr, OptionDescription):
|
||||
raise TypeError(_('descr must be an optiondescription, not {0}'
|
||||
).format(type(descr)))
|
||||
self._impl_descr = descr
|
||||
@ -149,8 +149,6 @@ class SubConfig(object):
|
||||
except UnicodeEncodeError:
|
||||
lines.append("{0} = {1}".format(name,
|
||||
value.encode(default_encoding)))
|
||||
except PropertiesOptionError:
|
||||
pass
|
||||
return '\n'.join(lines)
|
||||
|
||||
__repr__ = __str__
|
||||
@ -169,7 +167,7 @@ class SubConfig(object):
|
||||
def cfgimpl_get_description(self):
|
||||
if self._impl_descr is None:
|
||||
raise ConfigError(_('no option description found for this config'
|
||||
' (may be metaconfig without meta)'))
|
||||
' (may be GroupConfig)'))
|
||||
else:
|
||||
return self._impl_descr
|
||||
|
||||
@ -298,12 +296,9 @@ class SubConfig(object):
|
||||
:return: find list or an exception if nothing has been found
|
||||
"""
|
||||
def _filter_by_name():
|
||||
try:
|
||||
if byname is None or path == byname or \
|
||||
path.endswith('.' + byname):
|
||||
return True
|
||||
except IndexError:
|
||||
pass
|
||||
if byname is None or path == byname or \
|
||||
path.endswith('.' + byname):
|
||||
return True
|
||||
return False
|
||||
|
||||
def _filter_by_value():
|
||||
@ -454,22 +449,16 @@ class SubConfig(object):
|
||||
|
||||
def _make_sub_dict(self, opt, path, pathsvalues, _currpath, flatten):
|
||||
if isinstance(opt, OptionDescription):
|
||||
try:
|
||||
pathsvalues += getattr(self, path).make_dict(flatten,
|
||||
_currpath +
|
||||
path.split('.'))
|
||||
except PropertiesOptionError:
|
||||
pass # this just a hidden or disabled option
|
||||
pathsvalues += getattr(self, path).make_dict(flatten,
|
||||
_currpath +
|
||||
path.split('.'))
|
||||
else:
|
||||
try:
|
||||
value = self._getattr(opt._name)
|
||||
if flatten:
|
||||
name = opt._name
|
||||
else:
|
||||
name = '.'.join(_currpath + [opt._name])
|
||||
pathsvalues.append((name, value))
|
||||
except PropertiesOptionError:
|
||||
pass # this just a hidden or disabled option
|
||||
value = self._getattr(opt._name)
|
||||
if flatten:
|
||||
name = opt._name
|
||||
else:
|
||||
name = '.'.join(_currpath + [opt._name])
|
||||
pathsvalues.append((name, value))
|
||||
|
||||
def cfgimpl_get_path(self):
|
||||
descr = self.cfgimpl_get_description()
|
||||
@ -477,9 +466,9 @@ class SubConfig(object):
|
||||
return context_descr.impl_get_path_by_opt(descr)
|
||||
|
||||
|
||||
class CommonConfig(SubConfig):
|
||||
"abstract base class for the Config and the MetaConfig"
|
||||
__slots__ = ('_impl_values', '_impl_settings', '_impl_meta')
|
||||
class _CommonConfig(SubConfig):
|
||||
"abstract base class for the Config, GroupConfig and the MetaConfig"
|
||||
__slots__ = ('_impl_values', '_impl_settings', '_impl_meta', '_impl_test')
|
||||
|
||||
def _impl_build_all_paths(self):
|
||||
self.cfgimpl_get_description().impl_build_cache()
|
||||
@ -518,7 +507,8 @@ class CommonConfig(SubConfig):
|
||||
return None
|
||||
|
||||
def cfgimpl_get_meta(self):
|
||||
return self._impl_meta
|
||||
if self._impl_meta is not None:
|
||||
return self._impl_meta()
|
||||
|
||||
# information
|
||||
def impl_set_information(self, key, value):
|
||||
@ -536,11 +526,48 @@ class CommonConfig(SubConfig):
|
||||
"""
|
||||
return self._impl_values.get_information(key, default)
|
||||
|
||||
# ----- state
|
||||
def __getstate__(self):
|
||||
if self._impl_meta is not None:
|
||||
raise ConfigError(_('cannot serialize Config with MetaConfig'))
|
||||
slots = set()
|
||||
for subclass in self.__class__.__mro__:
|
||||
if subclass is not object:
|
||||
slots.update(subclass.__slots__)
|
||||
slots -= frozenset(['_impl_context', '_impl_meta', '__weakref__'])
|
||||
state = {}
|
||||
for slot in slots:
|
||||
try:
|
||||
state[slot] = getattr(self, slot)
|
||||
except AttributeError:
|
||||
pass
|
||||
storage = self._impl_values._p_._storage
|
||||
if not storage.serializable:
|
||||
raise ConfigError(_('this storage is not serialisable, could be a '
|
||||
'none persistent storage'))
|
||||
state['_storage'] = {'session_id': storage.session_id,
|
||||
'persistent': storage.persistent}
|
||||
state['_impl_setting'] = _impl_getstate_setting()
|
||||
return state
|
||||
|
||||
def __setstate__(self, state):
|
||||
for key, value in state.items():
|
||||
if key not in ['_storage', '_impl_setting']:
|
||||
setattr(self, key, value)
|
||||
set_storage(**state['_impl_setting'])
|
||||
self._impl_context = weakref.ref(self)
|
||||
self._impl_settings.context = weakref.ref(self)
|
||||
self._impl_values.context = weakref.ref(self)
|
||||
storage = get_storage(test=self._impl_test, **state['_storage'])
|
||||
self._impl_values._impl_setstate(storage)
|
||||
self._impl_settings._impl_setstate(storage)
|
||||
self._impl_meta = None
|
||||
|
||||
|
||||
# ____________________________________________________________
|
||||
class Config(CommonConfig):
|
||||
class Config(_CommonConfig):
|
||||
"main configuration management entry"
|
||||
__slots__ = ('__weakref__', '_impl_test')
|
||||
__slots__ = ('__weakref__',)
|
||||
|
||||
def __init__(self, descr, session_id=None, persistent=False):
|
||||
""" Configuration option management master class
|
||||
@ -564,41 +591,6 @@ class Config(CommonConfig):
|
||||
#undocumented option used only in test script
|
||||
self._impl_test = False
|
||||
|
||||
def __getstate__(self):
|
||||
if self._impl_meta is not None:
|
||||
raise ConfigError('cannot serialize Config with meta')
|
||||
slots = set()
|
||||
for subclass in self.__class__.__mro__:
|
||||
if subclass is not object:
|
||||
slots.update(subclass.__slots__)
|
||||
slots -= frozenset(['_impl_context', '__weakref__'])
|
||||
state = {}
|
||||
for slot in slots:
|
||||
try:
|
||||
state[slot] = getattr(self, slot)
|
||||
except AttributeError:
|
||||
pass
|
||||
storage = self._impl_values._p_._storage
|
||||
if not storage.serializable:
|
||||
raise ConfigError('this storage is not serialisable, could be a '
|
||||
'none persistent storage')
|
||||
state['_storage'] = {'session_id': storage.session_id,
|
||||
'persistent': storage.persistent}
|
||||
state['_impl_setting'] = _impl_getstate_setting()
|
||||
return state
|
||||
|
||||
def __setstate__(self, state):
|
||||
for key, value in state.items():
|
||||
if key not in ['_storage', '_impl_setting']:
|
||||
setattr(self, key, value)
|
||||
set_storage(**state['_impl_setting'])
|
||||
self._impl_context = weakref.ref(self)
|
||||
self._impl_settings.context = weakref.ref(self)
|
||||
self._impl_values.context = weakref.ref(self)
|
||||
storage = get_storage(test=self._impl_test, **state['_storage'])
|
||||
self._impl_values._impl_setstate(storage)
|
||||
self._impl_settings._impl_setstate(storage)
|
||||
|
||||
def cfgimpl_reset_cache(self,
|
||||
only_expired=False,
|
||||
only=('values', 'settings')):
|
||||
@ -608,99 +600,119 @@ class Config(CommonConfig):
|
||||
self.cfgimpl_get_settings().reset_cache(only_expired=only_expired)
|
||||
|
||||
|
||||
#class MetaConfig(CommonConfig):
|
||||
# __slots__ = ('_impl_children',)
|
||||
class GroupConfig(_CommonConfig):
|
||||
__slots__ = ('_impl_children', '__weakref__')
|
||||
|
||||
# def __init__(self, children, meta=True, session_id=None, persistent=False):
|
||||
# if not isinstance(children, list):
|
||||
# raise ValueError(_("metaconfig's children must be a list"))
|
||||
# self._impl_descr = None
|
||||
# self._impl_path = None
|
||||
# if meta:
|
||||
# for child in children:
|
||||
# if not isinstance(child, CommonConfig):
|
||||
# raise TypeError(_("metaconfig's children "
|
||||
# "must be config, not {0}"
|
||||
# ).format(type(child)))
|
||||
# if self._impl_descr is None:
|
||||
# self._impl_descr = child.cfgimpl_get_description()
|
||||
# elif not self._impl_descr is child.cfgimpl_get_description():
|
||||
# raise ValueError(_('all config in metaconfig must '
|
||||
# 'have the same optiondescription'))
|
||||
# if child.cfgimpl_get_meta() is not None:
|
||||
# raise ValueError(_("child has already a metaconfig's"))
|
||||
# child._impl_meta = self
|
||||
def __init__(self, children, session_id=None, persistent=False,
|
||||
_descr=None):
|
||||
if not isinstance(children, list):
|
||||
raise ValueError(_("metaconfig's children must be a list"))
|
||||
self._impl_children = children
|
||||
settings, values = get_storages(self, session_id, persistent)
|
||||
self._impl_settings = Settings(self, settings)
|
||||
self._impl_values = Values(self, values)
|
||||
super(GroupConfig, self).__init__(_descr, weakref.ref(self))
|
||||
self._impl_meta = None
|
||||
#undocumented option used only in test script
|
||||
self._impl_test = False
|
||||
|
||||
# self._impl_children = children
|
||||
# settings, values = get_storages(self, session_id, persistent)
|
||||
# self._impl_settings = Settings(self, settings)
|
||||
# self._impl_values = Values(self, values)
|
||||
# self._impl_meta = None
|
||||
def cfgimpl_get_children(self):
|
||||
return self._impl_children
|
||||
|
||||
# def cfgimpl_get_children(self):
|
||||
# return self._impl_children
|
||||
#def cfgimpl_get_context(self):
|
||||
# "a meta config is a config which has a setting, that is itself"
|
||||
# return self
|
||||
#
|
||||
def cfgimpl_reset_cache(self,
|
||||
only_expired=False,
|
||||
only=('values', 'settings')):
|
||||
if 'values' in only:
|
||||
self.cfgimpl_get_values().reset_cache(only_expired=only_expired)
|
||||
if 'settings' in only:
|
||||
self.cfgimpl_get_settings().reset_cache(only_expired=only_expired)
|
||||
for child in self._impl_children:
|
||||
child.cfgimpl_reset_cache(only_expired=only_expired, only=only)
|
||||
|
||||
# def cfgimpl_get_context(self):
|
||||
# "a meta config is a config wich has a setting, that is itself"
|
||||
# return self
|
||||
def setattrs(self, path, value):
|
||||
"""Setattr not in current GroupConfig, but in each children
|
||||
"""
|
||||
for child in self._impl_children:
|
||||
try:
|
||||
if not isinstance(child, GroupConfig):
|
||||
setattr(child, path, value)
|
||||
else:
|
||||
child.setattrs(path, value)
|
||||
except PropertiesOptionError:
|
||||
pass
|
||||
|
||||
# def cfgimpl_reset_cache(self,
|
||||
# only_expired=False,
|
||||
# only=('values', 'settings')):
|
||||
# if 'values' in only:
|
||||
# self.cfgimpl_get_values().reset_cache(only_expired=only_expired)
|
||||
# if 'settings' in only:
|
||||
# self.cfgimpl_get_settings().reset_cache(only_expired=only_expired)
|
||||
# for child in self._impl_children:
|
||||
# child.cfgimpl_reset_cache(only_expired=only_expired, only=only)
|
||||
def find_firsts(self, byname=None, bypath=None, byvalue=None,
|
||||
type_='path', display_error=True):
|
||||
"""Find first not in current GroupConfig, but in each children
|
||||
"""
|
||||
ret = []
|
||||
#if MetaConfig, all children have same OptionDescription as context
|
||||
#so search only one time for all children
|
||||
try:
|
||||
if bypath is None and byname is not None and \
|
||||
isinstance(self, MetaConfig):
|
||||
bypath = self._find(bytype=None, byvalue=None, byname=byname,
|
||||
first=True, type_='path',
|
||||
check_properties=False,
|
||||
display_error=display_error)
|
||||
byname = None
|
||||
except AttributeError:
|
||||
pass
|
||||
for child in self._impl_children:
|
||||
try:
|
||||
if not isinstance(child, MetaConfig):
|
||||
if bypath is not None:
|
||||
#if byvalue is None, try if not raise
|
||||
value = getattr(child, bypath)
|
||||
if byvalue is not None:
|
||||
if isinstance(value, Multi):
|
||||
if byvalue in value:
|
||||
ret.append(child)
|
||||
else:
|
||||
if value == byvalue:
|
||||
ret.append(child)
|
||||
else:
|
||||
ret.append(child)
|
||||
else:
|
||||
ret.append(child.find_first(byname=byname,
|
||||
byvalue=byvalue,
|
||||
type_=type_,
|
||||
display_error=False))
|
||||
else:
|
||||
ret.extend(child.find_firsts(byname=byname,
|
||||
bypath=bypath,
|
||||
byvalue=byvalue,
|
||||
type_=type_,
|
||||
display_error=False))
|
||||
except AttributeError:
|
||||
pass
|
||||
return self._find_return_results(ret, display_error)
|
||||
|
||||
# def set_contexts(self, path, value):
|
||||
# for child in self._impl_children:
|
||||
# try:
|
||||
# if not isinstance(child, MetaConfig):
|
||||
# setattr(child, path, value)
|
||||
# else:
|
||||
# child.set_contexts(path, value)
|
||||
# except PropertiesOptionError:
|
||||
# pass
|
||||
|
||||
# def find_first_contexts(self, byname=None, bypath=None, byvalue=None,
|
||||
# type_='path', display_error=True):
|
||||
# ret = []
|
||||
# try:
|
||||
# if bypath is None and byname is not None and \
|
||||
# self.cfgimpl_get_description() is not None:
|
||||
# bypath = self._find(bytype=None, byvalue=None, byname=byname,
|
||||
# first=True, type_='path',
|
||||
# check_properties=False,
|
||||
# display_error=display_error)
|
||||
# except ConfigError:
|
||||
# pass
|
||||
# for child in self._impl_children:
|
||||
# try:
|
||||
# if not isinstance(child, MetaConfig):
|
||||
# if bypath is not None:
|
||||
# if byvalue is not None:
|
||||
# if getattr(child, bypath) == byvalue:
|
||||
# ret.append(child)
|
||||
# else:
|
||||
# #not raise
|
||||
# getattr(child, bypath)
|
||||
# ret.append(child)
|
||||
# else:
|
||||
# ret.append(child.find_first(byname=byname,
|
||||
# byvalue=byvalue,
|
||||
# type_=type_,
|
||||
# display_error=False))
|
||||
# else:
|
||||
# ret.extend(child.find_first_contexts(byname=byname,
|
||||
# bypath=bypath,
|
||||
# byvalue=byvalue,
|
||||
# type_=type_,
|
||||
# display_error=False))
|
||||
# except AttributeError:
|
||||
# pass
|
||||
# return self._find_return_results(ret, display_error)
|
||||
class MetaConfig(GroupConfig):
|
||||
__slots__ = tuple()
|
||||
|
||||
def __init__(self, children, session_id=None, persistent=False):
|
||||
descr = None
|
||||
for child in children:
|
||||
if not isinstance(child, _CommonConfig):
|
||||
raise TypeError(_("metaconfig's children "
|
||||
"should be config, not {0}"
|
||||
).format(type(child)))
|
||||
if child.cfgimpl_get_meta() is not None:
|
||||
raise ValueError(_("child has already a metaconfig's"))
|
||||
if descr is None:
|
||||
descr = child.cfgimpl_get_description()
|
||||
elif not descr is child.cfgimpl_get_description():
|
||||
raise ValueError(_('all config in metaconfig must '
|
||||
'have the same optiondescription'))
|
||||
child._impl_meta = weakref.ref(self)
|
||||
|
||||
super(MetaConfig, self).__init__(children, session_id, persistent, descr)
|
||||
|
||||
|
||||
def mandatory_warnings(config):
|
||||
@ -719,6 +731,4 @@ def mandatory_warnings(config):
|
||||
except PropertiesOptionError as err:
|
||||
if err.proptype == ['mandatory']:
|
||||
yield path
|
||||
except ConfigError:
|
||||
pass
|
||||
config.cfgimpl_reset_cache(only=('values',))
|
||||
|
@ -354,9 +354,6 @@ class Option(BaseOption):
|
||||
"""
|
||||
if context is not None:
|
||||
descr = context.cfgimpl_get_description()
|
||||
#option is also in all_cons_opts
|
||||
if option not in all_cons_opts:
|
||||
raise ConfigError(_('option not in all_cons_opts'))
|
||||
|
||||
all_cons_vals = []
|
||||
for opt in all_cons_opts:
|
||||
@ -587,31 +584,15 @@ class Option(BaseOption):
|
||||
consistencies = self._state_consistencies
|
||||
else:
|
||||
consistencies = self._consistencies
|
||||
if isinstance(consistencies, list):
|
||||
new_value = []
|
||||
for consistency in consistencies:
|
||||
values = []
|
||||
for obj in consistency[1]:
|
||||
if load:
|
||||
values.append(descr.impl_get_opt_by_path(obj))
|
||||
else:
|
||||
values.append(descr.impl_get_path_by_opt(obj))
|
||||
new_value.append((consistency[0], tuple(values)))
|
||||
|
||||
else:
|
||||
new_value = {}
|
||||
for key, _consistencies in consistencies.items():
|
||||
new_value[key] = []
|
||||
for key_cons, _cons in _consistencies:
|
||||
_list_cons = []
|
||||
for _con in _cons:
|
||||
if load:
|
||||
_list_cons.append(
|
||||
descr.impl_get_opt_by_path(_con))
|
||||
else:
|
||||
_list_cons.append(
|
||||
descr.impl_get_path_by_opt(_con))
|
||||
new_value[key].append((key_cons, tuple(_list_cons)))
|
||||
new_value = []
|
||||
for consistency in consistencies:
|
||||
values = []
|
||||
for obj in consistency[1]:
|
||||
if load:
|
||||
values.append(descr.impl_get_opt_by_path(obj))
|
||||
else:
|
||||
values.append(descr.impl_get_path_by_opt(obj))
|
||||
new_value.append((consistency[0], tuple(values)))
|
||||
if load:
|
||||
del(self._state_consistencies)
|
||||
self._consistencies = new_value
|
||||
@ -663,7 +644,7 @@ class ChoiceOption(Option):
|
||||
return self._open_values
|
||||
|
||||
def _validate(self, value):
|
||||
if not self._open_values and not value in self._values:
|
||||
if not self.impl_is_openvalues() and not value in self.impl_get_values():
|
||||
raise ValueError(_('value {0} is not permitted, '
|
||||
'only {1} is allowed'
|
||||
'').format(value, self._values))
|
||||
@ -783,9 +764,13 @@ class IPOption(Option):
|
||||
def _validate(self, value):
|
||||
# sometimes an ip term starts with a zero
|
||||
# but this does not fit in some case, for example bind does not like it
|
||||
for val in value.split('.'):
|
||||
if val.startswith("0") and len(val) > 1:
|
||||
raise ValueError(_('invalid IP'))
|
||||
try:
|
||||
for val in value.split('.'):
|
||||
if val.startswith("0") and len(val) > 1:
|
||||
raise ValueError(_('invalid IP'))
|
||||
except AttributeError:
|
||||
#if integer for example
|
||||
raise ValueError(_('invalid IP'))
|
||||
# 'standard' validation
|
||||
try:
|
||||
IP('{0}/32'.format(value))
|
||||
@ -857,18 +842,23 @@ class PortOption(Option):
|
||||
if self._allow_range and ":" in str(value):
|
||||
value = str(value).split(':')
|
||||
if len(value) != 2:
|
||||
raise ValueError('invalid part, range must have two values '
|
||||
'only')
|
||||
raise ValueError(_('invalid part, range must have two values '
|
||||
'only'))
|
||||
if not value[0] < value[1]:
|
||||
raise ValueError('invalid port, first port in range must be'
|
||||
' smaller than the second one')
|
||||
raise ValueError(_('invalid port, first port in range must be'
|
||||
' smaller than the second one'))
|
||||
else:
|
||||
value = [value]
|
||||
|
||||
for val in value:
|
||||
try:
|
||||
int(val)
|
||||
except ValueError:
|
||||
raise ValueError(_('invalid port'))
|
||||
if not self._min_value <= int(val) <= self._max_value:
|
||||
raise ValueError('invalid port, must be an between {0} and {1}'
|
||||
''.format(self._min_value, self._max_value))
|
||||
raise ValueError(_('invalid port, must be an between {0} '
|
||||
'and {1}').format(self._min_value,
|
||||
self._max_value))
|
||||
|
||||
|
||||
class NetworkOption(Option):
|
||||
@ -924,19 +914,14 @@ class NetmaskOption(Option):
|
||||
IP('{0}/{1}'.format(val_ipnetwork, val_netmask),
|
||||
make_net=not make_net)
|
||||
except ValueError:
|
||||
if not make_net:
|
||||
msg = _("invalid network {0} ({1}) "
|
||||
"with netmask {2},"
|
||||
" this network is an IP")
|
||||
pass
|
||||
else:
|
||||
if make_net:
|
||||
msg = _("invalid IP {0} ({1}) with netmask {2},"
|
||||
" this IP is a network")
|
||||
|
||||
except ValueError:
|
||||
if make_net:
|
||||
msg = _('invalid IP {0} ({1}) with netmask {2}')
|
||||
else:
|
||||
if not make_net:
|
||||
msg = _('invalid network {0} ({1}) with netmask {2}')
|
||||
if msg is not None:
|
||||
raise ValueError(msg.format(val_ipnetwork, opts[1]._name,
|
||||
@ -1032,8 +1017,8 @@ class DomainnameOption(Option):
|
||||
if self._type == 'domainname' and not self._allow_without_dot and \
|
||||
'.' not in value:
|
||||
raise ValueError(_("invalid domainname, must have dot"))
|
||||
if len(value) > 255:
|
||||
raise ValueError(_("invalid domainname's length (max 255)"))
|
||||
if len(value) > 255:
|
||||
raise ValueError(_("invalid domainname's length (max 255)"))
|
||||
if len(value) < 2:
|
||||
raise ValueError(_("invalid domainname's length (min 2)"))
|
||||
if not self._domain_re.search(value):
|
||||
@ -1310,13 +1295,10 @@ class OptionDescription(BaseOption):
|
||||
if consistencies is not None:
|
||||
for func, all_cons_opts in consistencies:
|
||||
#all_cons_opts[0] is the option where func is set
|
||||
ret = all_cons_opts[0]._launch_consistency(func, option,
|
||||
value,
|
||||
context, index,
|
||||
all_cons_opts)
|
||||
if ret is False:
|
||||
return False
|
||||
return True
|
||||
all_cons_opts[0]._launch_consistency(func, option,
|
||||
value,
|
||||
context, index,
|
||||
all_cons_opts)
|
||||
|
||||
def _impl_getstate(self, descr=None):
|
||||
"""enables us to export into a dict
|
||||
|
@ -66,6 +66,8 @@ class Values(object):
|
||||
meta = self._getcontext().cfgimpl_get_meta()
|
||||
if meta is not None:
|
||||
value = meta.cfgimpl_get_values()[opt]
|
||||
if isinstance(value, Multi):
|
||||
value = list(value)
|
||||
else:
|
||||
value = opt.impl_getdefault()
|
||||
if opt.impl_is_multi():
|
||||
@ -73,7 +75,7 @@ class Values(object):
|
||||
else:
|
||||
return value
|
||||
|
||||
def _getvalue(self, opt, path, validate=True):
|
||||
def _getvalue(self, opt, path):
|
||||
"""actually retrieves the value
|
||||
|
||||
:param opt: the `option.Option()` object
|
||||
@ -82,14 +84,9 @@ class Values(object):
|
||||
if not self._p_.hasvalue(path):
|
||||
# if there is no value
|
||||
value = self._getdefault(opt)
|
||||
if opt.impl_is_multi():
|
||||
value = Multi(value, self.context, opt, path, validate)
|
||||
else:
|
||||
# if there is a value
|
||||
value = self._p_.getvalue(path)
|
||||
if opt.impl_is_multi() and not isinstance(value, Multi):
|
||||
# load value so don't need to validate if is not a Multi
|
||||
value = Multi(value, self.context, opt, path, validate=False)
|
||||
return value
|
||||
|
||||
def get_modified_values(self):
|
||||
@ -198,7 +195,7 @@ class Values(object):
|
||||
# ConfigError if properties did not raise.
|
||||
config_error = None
|
||||
force_permissives = None
|
||||
# if value is callback and is not set
|
||||
# if value has callback and is not set
|
||||
# or frozen with force_default_on_freeze
|
||||
if opt.impl_has_callback() and (
|
||||
self._is_default_owner(path) or
|
||||
@ -208,7 +205,7 @@ class Values(object):
|
||||
if (opt.impl_is_multi() and
|
||||
opt.impl_get_multitype() == multitypes.slave):
|
||||
masterp = self._get_opt_path(opt.impl_get_master_slaves())
|
||||
mastervalue = getattr(context, masterp)
|
||||
mastervalue = context._getattr(masterp, validate=validate)
|
||||
lenmaster = len(mastervalue)
|
||||
if lenmaster == 0:
|
||||
value = []
|
||||
@ -240,7 +237,10 @@ class Values(object):
|
||||
if opt.impl_is_multi():
|
||||
value = Multi(value, self.context, opt, path, validate)
|
||||
else:
|
||||
value = self._getvalue(opt, path, validate)
|
||||
value = self._getvalue(opt, path)
|
||||
if opt.impl_is_multi():
|
||||
# load value so don't need to validate if is not a Multi
|
||||
value = Multi(value, self.context, opt, path, validate=validate)
|
||||
if config_error is None and validate:
|
||||
opt.impl_validate(value, context, 'validator' in setting)
|
||||
if config_error is None and self._is_default_owner(path) and \
|
||||
@ -266,10 +266,27 @@ class Values(object):
|
||||
context = self._getcontext()
|
||||
opt.impl_validate(value, context,
|
||||
'validator' in context.cfgimpl_get_settings())
|
||||
if opt.impl_is_multi() and not isinstance(value, Multi):
|
||||
if opt.impl_is_multi():
|
||||
value = Multi(value, self.context, opt, path, setitem=True)
|
||||
# Save old value
|
||||
if opt.impl_get_multitype() == multitypes.master and \
|
||||
self._p_.hasvalue(path):
|
||||
old_value = self._p_.getvalue(path)
|
||||
old_owner = self._p_.getowner(path, None)
|
||||
else:
|
||||
old_value = undefined
|
||||
old_owner = undefined
|
||||
self._setvalue(opt, path, value, force_permissive=force_permissive,
|
||||
is_write=is_write)
|
||||
if opt.impl_is_multi() and opt.impl_get_multitype() == multitypes.master:
|
||||
try:
|
||||
value._valid_master()
|
||||
except Exception, err:
|
||||
if old_value is not undefined:
|
||||
self._p_.setvalue(path, old_value, old_owner)
|
||||
else:
|
||||
self._p_.resetvalue(path)
|
||||
raise err
|
||||
|
||||
def _setvalue(self, opt, path, value, force_permissive=False,
|
||||
force_properties=None,
|
||||
@ -283,6 +300,8 @@ class Values(object):
|
||||
force_permissive=force_permissive,
|
||||
force_properties=force_properties)
|
||||
owner = context.cfgimpl_get_settings().getowner()
|
||||
if isinstance(value, Multi):
|
||||
value = list(value)
|
||||
self._p_.setvalue(path, value, owner)
|
||||
|
||||
def getowner(self, opt):
|
||||
@ -403,6 +422,8 @@ class Multi(list):
|
||||
:param opt: the option object that have this Multi value
|
||||
:param setitem: only if set a value
|
||||
"""
|
||||
if isinstance(value, Multi):
|
||||
raise ValueError(_('{0} is already a Multi ').format(opt._name))
|
||||
self.opt = opt
|
||||
self.path = path
|
||||
if not isinstance(context, weakref.ReferenceType):
|
||||
@ -412,8 +433,9 @@ class Multi(list):
|
||||
value = [value]
|
||||
if validate and self.opt.impl_get_multitype() == multitypes.slave:
|
||||
value = self._valid_slave(value, setitem)
|
||||
elif validate and self.opt.impl_get_multitype() == multitypes.master:
|
||||
self._valid_master(value)
|
||||
elif not setitem and validate and \
|
||||
self.opt.impl_get_multitype() == multitypes.master:
|
||||
self._valid_master()
|
||||
super(Multi, self).__init__(value)
|
||||
|
||||
def _getcontext(self):
|
||||
@ -433,12 +455,10 @@ class Multi(list):
|
||||
values = context.cfgimpl_get_values()
|
||||
masterp = context.cfgimpl_get_description().impl_get_path_by_opt(
|
||||
self.opt.impl_get_master_slaves())
|
||||
mastervalue = getattr(context, masterp)
|
||||
mastervalue = context._getattr(masterp, validate=False)
|
||||
masterlen = len(mastervalue)
|
||||
valuelen = len(value)
|
||||
is_default_owner = not values._is_default_owner(self.path) or setitem
|
||||
if valuelen > masterlen or (valuelen < masterlen and
|
||||
is_default_owner):
|
||||
if valuelen > masterlen or (valuelen < masterlen and setitem):
|
||||
raise SlaveError(_("invalid len for the slave: {0}"
|
||||
" which has {1} as master").format(
|
||||
self.opt._name, masterp))
|
||||
@ -455,30 +475,12 @@ class Multi(list):
|
||||
#else: same len so do nothing
|
||||
return value
|
||||
|
||||
def _valid_master(self, value):
|
||||
masterlen = len(value)
|
||||
def _valid_master(self):
|
||||
#masterlen = len(value)
|
||||
values = self._getcontext().cfgimpl_get_values()
|
||||
for slave in self.opt._master_slaves:
|
||||
path = values._get_opt_path(slave)
|
||||
if not values._is_default_owner(path):
|
||||
value_slave = values._getvalue(slave, path)
|
||||
if len(value_slave) > masterlen:
|
||||
raise SlaveError(_("invalid len for the master: {0}"
|
||||
" which has {1} as slave with"
|
||||
" greater len").format(
|
||||
self.opt._name, slave._name))
|
||||
elif len(value_slave) < masterlen:
|
||||
for num in range(0, masterlen - len(value_slave)):
|
||||
if slave.impl_has_callback():
|
||||
# if callback add a value, but this value will not
|
||||
# change anymore automaticly (because this value
|
||||
# has owner)
|
||||
index = value_slave.__len__()
|
||||
value_slave.append(
|
||||
values._getcallback_value(slave, index=index),
|
||||
force=True)
|
||||
else:
|
||||
value_slave.append(undefined, force=True)
|
||||
Multi(values._getvalue(slave, path), self.context, slave, path)
|
||||
|
||||
def __setitem__(self, index, value):
|
||||
self._validate(value, index)
|
||||
@ -518,16 +520,15 @@ class Multi(list):
|
||||
dvalue = values._getcallback_value(slave, index=index)
|
||||
else:
|
||||
dvalue = slave.impl_getdefault_multi()
|
||||
old_value = values.getitem(slave, path,
|
||||
old_value = values.getitem(slave, path, validate=False,
|
||||
validate_properties=False)
|
||||
if len(old_value) < self.__len__():
|
||||
values.getitem(slave, path,
|
||||
validate_properties=False).append(
|
||||
dvalue, force=True)
|
||||
else:
|
||||
values.getitem(slave, path,
|
||||
validate_properties=False)[
|
||||
index] = dvalue
|
||||
if len(old_value) + 1 != self.__len__():
|
||||
raise SlaveError(_("invalid len for the slave: {0}"
|
||||
" which has {1} as master").format(
|
||||
self.opt._name, self.__len__()))
|
||||
values.getitem(slave, path, validate=False,
|
||||
validate_properties=False).append(
|
||||
dvalue, force=True)
|
||||
|
||||
def sort(self, cmp=None, key=None, reverse=False):
|
||||
if self.opt.impl_get_multitype() in [multitypes.slave,
|
||||
@ -592,12 +593,12 @@ class Multi(list):
|
||||
if self.opt.impl_get_multitype() == multitypes.slave:
|
||||
raise SlaveError(_("cannot pop a value on a multi option {0}"
|
||||
" which is a slave").format(self.opt._name))
|
||||
elif self.opt.impl_get_multitype() == multitypes.master:
|
||||
if self.opt.impl_get_multitype() == multitypes.master:
|
||||
for slave in self.opt.impl_get_master_slaves():
|
||||
values = context.cfgimpl_get_values()
|
||||
if not values.is_default_owner(slave):
|
||||
#get multi without valid properties
|
||||
values.getitem(slave,
|
||||
values.getitem(slave, validate=False,
|
||||
validate_properties=False
|
||||
).pop(index, force=True)
|
||||
#set value without valid properties
|
||||
|
@ -79,7 +79,7 @@ msgstr "l'attribut {2} de l'objet '{0}' ({1}) est en lecture seule"
|
||||
|
||||
#: tiramisu/option.py:141 tiramisu/value.py:376
|
||||
msgid "information's item not found: {0}"
|
||||
msgstr "aucune config spécifié alors que c'est nécessaire"
|
||||
msgstr "aucune config spécifiée alors que c'est nécessaire"
|
||||
|
||||
#: tiramisu/option.py:203
|
||||
msgid "cannot serialize Option, only in OptionDescription"
|
||||
|
Loading…
Reference in New Issue
Block a user