2014-02-06 22:17:20 +01:00
|
|
|
import autopath
|
|
|
|
|
2013-09-06 23:15:28 +02:00
|
|
|
from tiramisu.option import BoolOption, UnicodeOption, SymLinkOption, \
|
2014-06-19 23:22:39 +02:00
|
|
|
IntOption, IPOption, NetmaskOption, StrOption, OptionDescription, \
|
|
|
|
DynOptionDescription
|
2013-09-30 16:22:08 +02:00
|
|
|
from tiramisu.config import Config, GroupConfig, MetaConfig
|
2014-06-19 23:22:39 +02:00
|
|
|
from tiramisu.setting import groups, owners
|
2013-09-22 20:57:52 +02:00
|
|
|
from tiramisu.storage import delete_session
|
|
|
|
from tiramisu.error import ConfigError
|
2013-09-06 23:15:28 +02:00
|
|
|
from pickle import dumps, loads
|
2014-02-02 18:33:21 +01:00
|
|
|
from py.test import raises
|
2013-09-06 23:15:28 +02:00
|
|
|
|
|
|
|
|
2013-09-20 23:47:40 +02:00
|
|
|
def return_value(value=None):
|
2014-10-25 22:11:31 +02:00
|
|
|
return value
|
2013-09-20 23:47:40 +02:00
|
|
|
|
|
|
|
|
2013-09-06 23:15:28 +02:00
|
|
|
def _get_slots(opt):
|
|
|
|
slots = set()
|
|
|
|
for subclass in opt.__class__.__mro__:
|
|
|
|
if subclass is not object:
|
|
|
|
slots.update(subclass.__slots__)
|
|
|
|
return slots
|
|
|
|
|
|
|
|
|
|
|
|
def _no_state(opt):
|
|
|
|
for attr in _get_slots(opt):
|
|
|
|
if 'state' in attr:
|
|
|
|
try:
|
|
|
|
getattr(opt, attr)
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
else:
|
|
|
|
raise Exception('opt should have already attribute {0}'.format(attr))
|
|
|
|
|
|
|
|
|
|
|
|
def _diff_opt(opt1, opt2):
|
|
|
|
attr1 = set(_get_slots(opt1))
|
|
|
|
attr2 = set(_get_slots(opt2))
|
|
|
|
diff1 = attr1 - attr2
|
|
|
|
diff2 = attr2 - attr1
|
|
|
|
if diff1 != set():
|
|
|
|
raise Exception('more attribute in opt1 {0}'.format(list(diff1)))
|
|
|
|
if diff2 != set():
|
|
|
|
raise Exception('more attribute in opt2 {0}'.format(list(diff2)))
|
|
|
|
for attr in attr1:
|
2013-09-28 17:05:01 +02:00
|
|
|
if attr in ['_cache_paths', '_cache_consistencies']:
|
2013-09-06 23:15:28 +02:00
|
|
|
continue
|
|
|
|
err1 = False
|
|
|
|
err2 = False
|
|
|
|
val1 = None
|
|
|
|
val2 = None
|
|
|
|
try:
|
|
|
|
val1 = getattr(opt1, attr)
|
2014-10-25 22:11:31 +02:00
|
|
|
msg1 = "exists"
|
|
|
|
except Exception, err:
|
2013-09-06 23:15:28 +02:00
|
|
|
err1 = True
|
2014-10-25 22:11:31 +02:00
|
|
|
msg1 = "not exists"
|
2013-09-06 23:15:28 +02:00
|
|
|
|
|
|
|
try:
|
|
|
|
val2 = getattr(opt2, attr)
|
2014-10-25 22:11:31 +02:00
|
|
|
msg2 = "exists"
|
2013-09-06 23:15:28 +02:00
|
|
|
except:
|
|
|
|
err2 = True
|
2014-10-25 22:11:31 +02:00
|
|
|
msg2 = "not exists"
|
|
|
|
|
|
|
|
if not err1 == err2:
|
|
|
|
raise ValueError("{0} {1} before but {2} after for {3}".format(attr, msg1, msg2, opt1.impl_getname()))
|
2013-09-06 23:15:28 +02:00
|
|
|
if val1 is None:
|
|
|
|
assert val1 == val2
|
|
|
|
elif attr == '_children':
|
|
|
|
assert val1[0] == val2[0]
|
|
|
|
for index, _opt in enumerate(val1[1]):
|
|
|
|
assert _opt._name == val2[1][index]._name
|
|
|
|
elif attr == '_requires':
|
2014-04-14 22:53:40 +02:00
|
|
|
if val1 == val2 == []:
|
|
|
|
pass
|
|
|
|
else:
|
|
|
|
assert val1[0][0][0]._name == val2[0][0][0]._name
|
|
|
|
assert val1[0][0][1:] == val2[0][0][1:]
|
2013-09-06 23:15:28 +02:00
|
|
|
elif attr == '_opt':
|
|
|
|
assert val1._name == val2._name
|
|
|
|
elif attr == '_consistencies':
|
|
|
|
# dict is only a cache
|
|
|
|
if isinstance(val1, list):
|
|
|
|
for index, consistency in enumerate(val1):
|
|
|
|
assert consistency[0] == val2[index][0]
|
2013-09-27 23:26:10 +02:00
|
|
|
for idx, opt in enumerate(consistency[1]):
|
|
|
|
assert opt._name == val2[index][1][idx]._name
|
2014-10-25 22:11:31 +02:00
|
|
|
elif attr == '_val_call':
|
|
|
|
for idx, v in enumerate(val1):
|
|
|
|
if v is None:
|
|
|
|
assert val2[idx] is None
|
|
|
|
else:
|
|
|
|
assert v[0] == val2[idx][0]
|
|
|
|
if len(v) == 2:
|
|
|
|
if v[1] is not None:
|
|
|
|
for key, values in v[1].items():
|
|
|
|
for i, value in enumerate(values):
|
|
|
|
if isinstance(value, tuple):
|
|
|
|
assert v[1][key][i][0].impl_getname() == val2[idx][1][key][i][0].impl_getname()
|
|
|
|
assert v[1][key][i][1] == val2[idx][1][key][i][1]
|
|
|
|
else:
|
|
|
|
assert v[1][key][i] == val2[idx][1][key][i]
|
2013-09-20 23:47:40 +02:00
|
|
|
else:
|
2014-10-25 22:11:31 +02:00
|
|
|
assert v[1] == val2[idx][1]
|
2014-06-19 23:22:39 +02:00
|
|
|
elif attr == '_master_slaves':
|
|
|
|
assert val1.master.impl_getname() == val2.master.impl_getname()
|
|
|
|
sval1 = [opt.impl_getname() for opt in val1.slaves]
|
|
|
|
sval2 = [opt.impl_getname() for opt in val2.slaves]
|
|
|
|
assert sval1 == sval2
|
|
|
|
elif attr == '_subdyn':
|
|
|
|
try:
|
|
|
|
assert val1.impl_getname() == val2.impl_getname()
|
|
|
|
except AttributeError:
|
|
|
|
assert val1 == val2
|
2013-09-06 23:15:28 +02:00
|
|
|
else:
|
|
|
|
assert val1 == val2
|
|
|
|
|
|
|
|
|
2014-06-19 23:22:39 +02:00
|
|
|
def _diff_opts(opt1, opt2):
|
|
|
|
_diff_opt(opt1, opt2)
|
|
|
|
if isinstance(opt1, OptionDescription) or isinstance(opt1, DynOptionDescription):
|
|
|
|
children1 = set([opt.impl_getname() for opt in opt1._impl_getchildren(dyn=False)])
|
|
|
|
children2 = set([opt.impl_getname() for opt in opt2._impl_getchildren(dyn=False)])
|
|
|
|
diff1 = children1 - children2
|
|
|
|
diff2 = children2 - children1
|
|
|
|
if diff1 != set():
|
|
|
|
raise Exception('more attribute in opt1 {0}'.format(list(diff1)))
|
|
|
|
if diff2 != set():
|
|
|
|
raise Exception('more attribute in opt2 {0}'.format(list(diff2)))
|
|
|
|
for child in children1:
|
|
|
|
_diff_opts(opt1._getattr(child, dyn=False), opt2._getattr(child, dyn=False))
|
|
|
|
|
|
|
|
|
2013-09-30 16:22:08 +02:00
|
|
|
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())
|
2014-04-14 22:53:40 +02:00
|
|
|
elif attr == '_impl_children':
|
|
|
|
for index, _opt in enumerate(val1):
|
|
|
|
_diff_conf(_opt, val2[index])
|
2013-09-30 16:22:08 +02:00
|
|
|
else:
|
|
|
|
assert val1 == val2
|
|
|
|
|
|
|
|
|
2014-04-14 22:53:40 +02:00
|
|
|
def test_diff_opt():
|
|
|
|
b = BoolOption('b', '')
|
|
|
|
u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}])
|
|
|
|
s = SymLinkOption('s', u)
|
|
|
|
o = OptionDescription('o', '', [b, u, s])
|
|
|
|
o1 = OptionDescription('o1', '', [o])
|
|
|
|
|
|
|
|
a = dumps(o1)
|
|
|
|
q = loads(a)
|
2014-06-19 23:22:39 +02:00
|
|
|
_diff_opts(o1, q)
|
2014-04-14 22:53:40 +02:00
|
|
|
|
|
|
|
|
|
|
|
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}])
|
|
|
|
u.impl_add_consistency('not_equal', b)
|
|
|
|
s = SymLinkOption('s', u)
|
|
|
|
o = OptionDescription('o', '', [b, u, s])
|
|
|
|
o1 = OptionDescription('o1', '', [o])
|
|
|
|
o1.impl_build_cache_consistency()
|
|
|
|
o1.impl_build_cache_option()
|
|
|
|
|
|
|
|
a = dumps(o1)
|
|
|
|
q = loads(a)
|
2014-06-19 23:22:39 +02:00
|
|
|
_diff_opts(o1, q)
|
2014-04-14 22:53:40 +02:00
|
|
|
|
|
|
|
|
|
|
|
def test_diff_opt_callback():
|
|
|
|
b = BoolOption('b', '', callback=return_value)
|
|
|
|
b2 = BoolOption('b2', '', callback=return_value, callback_params={'': ('yes',)})
|
|
|
|
b3 = BoolOption('b3', '', callback=return_value, callback_params={'': ('yes', (b, False)), 'value': ('no',)})
|
|
|
|
o = OptionDescription('o', '', [b, b2, b3])
|
|
|
|
o1 = OptionDescription('o1', '', [o])
|
|
|
|
o1.impl_build_cache_consistency()
|
|
|
|
o1.impl_build_cache_option()
|
|
|
|
|
|
|
|
a = dumps(o1)
|
|
|
|
q = loads(a)
|
2014-06-19 23:22:39 +02:00
|
|
|
_diff_opts(o1, q)
|
2014-04-14 22:53:40 +02:00
|
|
|
|
|
|
|
|
|
|
|
def test_no_state_attr():
|
|
|
|
# all _state_xxx attributes should be deleted
|
|
|
|
b = BoolOption('b', '')
|
|
|
|
u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}])
|
|
|
|
s = SymLinkOption('s', u)
|
|
|
|
o = OptionDescription('o', '', [b, u, s])
|
|
|
|
o1 = OptionDescription('o1', '', [o])
|
|
|
|
|
|
|
|
a = dumps(o1)
|
|
|
|
q = loads(a)
|
|
|
|
_no_state(q)
|
|
|
|
_no_state(q.o)
|
|
|
|
_no_state(q.o.b)
|
|
|
|
_no_state(q.o.u)
|
|
|
|
_no_state(q.o.s)
|
|
|
|
|
|
|
|
|
|
|
|
def test_state_config():
|
|
|
|
val1 = BoolOption('val1', "")
|
|
|
|
maconfig = OptionDescription('rootconfig', '', [val1])
|
|
|
|
try:
|
|
|
|
cfg = Config(maconfig, persistent=True, session_id='29090931')
|
|
|
|
except ValueError:
|
|
|
|
cfg = Config(maconfig, session_id='29090931')
|
|
|
|
cfg._impl_test = True
|
|
|
|
a = dumps(cfg)
|
|
|
|
q = loads(a)
|
2014-06-19 23:22:39 +02:00
|
|
|
_diff_opts(cfg.cfgimpl_get_description(), q.cfgimpl_get_description())
|
2014-04-14 22:53:40 +02:00
|
|
|
_diff_conf(cfg, q)
|
|
|
|
try:
|
|
|
|
delete_session('config', '29090931')
|
|
|
|
except ConfigError:
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
2014-06-19 23:22:39 +02:00
|
|
|
def test_state_config2():
|
|
|
|
a = IPOption('a', '')
|
|
|
|
b = NetmaskOption('b', '')
|
|
|
|
dod1 = OptionDescription('dod1', '', [a, b])
|
|
|
|
b.impl_add_consistency('ip_netmask', a)
|
|
|
|
od1 = OptionDescription('od1', '', [dod1])
|
|
|
|
st1 = StrOption('st1', "", multi=True)
|
|
|
|
st2 = StrOption('st2', "", multi=True)
|
|
|
|
st3 = StrOption('st3', "", multi=True, callback=return_value, callback_params={'': ((st2, False),)})
|
|
|
|
stm = OptionDescription('st1', '', [st1, st2, st3])
|
|
|
|
stm.impl_set_group_type(groups.master)
|
|
|
|
st = OptionDescription('st', '', [stm])
|
|
|
|
od = OptionDescription('od', '', [st])
|
|
|
|
od2 = OptionDescription('od', '', [od, od1])
|
|
|
|
try:
|
|
|
|
cfg = Config(od2, persistent=True, session_id='29090939')
|
|
|
|
except ValueError:
|
|
|
|
cfg = Config(od2, session_id='29090939')
|
|
|
|
cfg._impl_test = True
|
|
|
|
a = dumps(cfg)
|
|
|
|
q = loads(a)
|
|
|
|
_diff_opts(cfg.cfgimpl_get_description(), q.cfgimpl_get_description())
|
|
|
|
_diff_conf(cfg, q)
|
|
|
|
try:
|
|
|
|
delete_session('config', '29090939')
|
|
|
|
except ConfigError:
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
2014-04-14 22:53:40 +02:00
|
|
|
def test_state_properties():
|
|
|
|
val1 = BoolOption('val1', "")
|
|
|
|
maconfig = OptionDescription('rootconfig', '', [val1])
|
|
|
|
try:
|
|
|
|
cfg = Config(maconfig, persistent=True, session_id='29090932')
|
|
|
|
except ValueError:
|
|
|
|
cfg = Config(maconfig, session_id='29090932')
|
|
|
|
cfg._impl_test = True
|
|
|
|
cfg.read_write()
|
|
|
|
cfg.cfgimpl_get_settings()[val1].append('test')
|
|
|
|
a = dumps(cfg)
|
|
|
|
q = loads(a)
|
|
|
|
_diff_conf(cfg, q)
|
|
|
|
try:
|
|
|
|
delete_session('config', '29090932')
|
|
|
|
except ConfigError:
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
def test_state_values():
|
|
|
|
val1 = BoolOption('val1', "")
|
|
|
|
maconfig = OptionDescription('rootconfig', '', [val1])
|
|
|
|
try:
|
|
|
|
cfg = Config(maconfig, persistent=True, session_id='29090933')
|
|
|
|
except ValueError:
|
|
|
|
cfg = Config(maconfig, session_id='29090933')
|
|
|
|
cfg._impl_test = True
|
|
|
|
cfg.val1 = True
|
|
|
|
a = dumps(cfg)
|
|
|
|
q = loads(a)
|
|
|
|
_diff_conf(cfg, q)
|
|
|
|
q.val1 = False
|
|
|
|
assert cfg.val1 is True
|
|
|
|
assert q.val1 is False
|
|
|
|
try:
|
|
|
|
delete_session('config', '29090933')
|
|
|
|
except ConfigError:
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
def test_state_values_owner():
|
|
|
|
val1 = BoolOption('val1', "")
|
|
|
|
maconfig = OptionDescription('rootconfig', '', [val1])
|
|
|
|
try:
|
|
|
|
cfg = Config(maconfig, persistent=True, session_id='29090934')
|
|
|
|
except ValueError:
|
|
|
|
cfg = Config(maconfig, session_id='29090934')
|
|
|
|
cfg._impl_test = True
|
|
|
|
owners.addowner('newowner')
|
|
|
|
cfg.cfgimpl_get_settings().setowner(owners.newowner)
|
|
|
|
cfg.val1 = True
|
|
|
|
a = dumps(cfg)
|
|
|
|
q = loads(a)
|
|
|
|
_diff_conf(cfg, q)
|
|
|
|
q.val1 = False
|
|
|
|
nval1 = q.cfgimpl_get_description().val1
|
|
|
|
assert q.getowner(nval1) == owners.newowner
|
|
|
|
try:
|
|
|
|
delete_session('config', '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('config', '29090935')
|
|
|
|
delete_session('config', '29090936')
|
|
|
|
delete_session('config', '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('config', '29090935')
|
|
|
|
delete_session('config', '29090936')
|
|
|
|
delete_session('config', '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__
|