diff --git a/test/test_config_api.py b/test/test_config_api.py index f76895a..ad33bcf 100644 --- a/test/test_config_api.py +++ b/test/test_config_api.py @@ -5,7 +5,9 @@ from py.test import raises from tiramisu.config import Config from tiramisu.option import IntOption, FloatOption, StrOption, ChoiceOption, \ BoolOption, FilenameOption, UnicodeOption, SymLinkOption, IPOption, \ - PortOption, OptionDescription + PortOption, NetworkOption, NetmaskOption, BroadcastOption, \ + DomainnameOption, OptionDescription +from tiramisu.error import PropertiesOptionError def make_description(): @@ -212,6 +214,22 @@ def test_iter_all_prop(): 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)") @@ -225,3 +243,15 @@ def test_invalid_option(): 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')") diff --git a/test/test_config_domain.py b/test/test_config_domain.py index f4579a6..8fcf1f1 100644 --- a/test/test_config_domain.py +++ b/test/test_config_domain.py @@ -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_domainname_netbios(): @@ -56,6 +62,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(): @@ -76,3 +83,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'") diff --git a/test/test_option_consistency.py b/test/test_option_consistency.py index f7040e4..6c736c1 100644 --- a/test/test_option_consistency.py +++ b/test/test_option_consistency.py @@ -186,6 +186,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', '') @@ -234,6 +246,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'] @@ -277,6 +291,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_1(): a = NetworkOption('a', '', '192.168.1.0') b = NetmaskOption('b', '', '255.255.255.128') @@ -307,3 +335,14 @@ def test_consistency_not_all(): c.a = ['192.168.1.0'] c.b = ['255.255.255.0'] c.c = ['192.168.1.255'] + + +def test_consistency_permissive(): + a = IntOption('a', '', 1) + b = IntOption('b', '', 2, properties=('hidden',)) + od = OptionDescription('od', '', [a, b]) + a.impl_add_consistency('not_equal', b) + c = Config(od) + c.cfgimpl_get_settings().setpermissive(('hidden',)) + c.read_write() + c.a = 1 diff --git a/test/test_state.py b/test/test_state.py index 07639c8..03be06e 100644 --- a/test/test_state.py +++ b/test/test_state.py @@ -1,362 +1,368 @@ -#from tiramisu.option import BoolOption, UnicodeOption, SymLinkOption, \ -# 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): -# return value -# -# -#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: -# if attr in ['_cache_paths', '_cache_consistencies']: -# continue -# err1 = False -# err2 = False -# val1 = None -# val2 = None -# try: -# val1 = getattr(opt1, attr) -# except: -# err1 = True -# -# try: -# val2 = getattr(opt2, attr) -# except: -# err2 = True -# assert err1 == err2 -# 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': -# assert val1[0][0][0]._name == val2[0][0][0]._name -# assert val1[0][0][1:] == val2[0][0][1:] -# 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] -# for idx, opt in enumerate(consistency[1]): -# assert opt._name == val2[index][1][idx]._name -# elif attr == '_callback': -# assert val1[0] == val2[0] -# if val1[1] is not None: -# for key, values in val1[1].items(): -# for idx, value in enumerate(values): -# if isinstance(value, tuple): -# assert val1[1][key][idx][0]._name == val2[1][key][idx][0]._name -# assert val1[1][key][idx][1] == val2[1][key][idx][1] -# else: -# assert val1[1][key][idx] == val2[1][key][idx] -# else: -# assert val1[1] == val2[1] -# else: -# 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]) -# -# a = dumps(o1) -# q = loads(a) -# _diff_opt(o1, q) -# _diff_opt(o1.o, q.o) -# _diff_opt(o1.o.b, q.o.b) -# _diff_opt(o1.o.u, q.o.u) -# _diff_opt(o1.o.s, q.o.s) -# -# -#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() -# -# a = dumps(o1) -# q = loads(a) -# _diff_opt(o1, q) -# _diff_opt(o1.o, q.o) -# _diff_opt(o1.o.b, q.o.b) -# _diff_opt(o1.o.u, q.o.u) -# _diff_opt(o1.o.s, q.o.s) -# -# -#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() -# -# a = dumps(o1) -# q = loads(a) -# _diff_opt(o1, q) -# _diff_opt(o1.o, q.o) -# _diff_opt(o1.o.b, q.o.b) -# _diff_opt(o1.o.b2, q.o.b2) -# _diff_opt(o1.o.b3, q.o.b3) -# -# -#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) -# _diff_conf(cfg, q) -# try: -# delete_session('29090931') -# except ConfigError: -# pass -# -# -#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('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('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('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__ +import autopath + +from tiramisu.option import BoolOption, UnicodeOption, SymLinkOption, \ + 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): + return value + + +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: + if attr in ['_cache_paths', '_cache_consistencies']: + continue + err1 = False + err2 = False + val1 = None + val2 = None + try: + val1 = getattr(opt1, attr) + except: + err1 = True + + try: + val2 = getattr(opt2, attr) + except: + err2 = True + assert err1 == err2 + 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': + assert val1[0][0][0]._name == val2[0][0][0]._name + assert val1[0][0][1:] == val2[0][0][1:] + 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] + for idx, opt in enumerate(consistency[1]): + assert opt._name == val2[index][1][idx]._name + elif attr == '_callback': + assert val1[0] == val2[0] + if val1[1] is not None: + for key, values in val1[1].items(): + for idx, value in enumerate(values): + if isinstance(value, tuple): + assert val1[1][key][idx][0]._name == val2[1][key][idx][0]._name + assert val1[1][key][idx][1] == val2[1][key][idx][1] + else: + assert val1[1][key][idx] == val2[1][key][idx] + else: + assert val1[1] == val2[1] + else: + 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}]) + s = SymLinkOption('s', u) + o = OptionDescription('o', '', [b, u, s]) + o1 = OptionDescription('o1', '', [o]) + + a = dumps(o1) + q = loads(a) + _diff_opt(o1, q) + _diff_opt(o1.o, q.o) + _diff_opt(o1.o.b, q.o.b) + _diff_opt(o1.o.u, q.o.u) + _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}]) + 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() + + a = dumps(o1) + q = loads(a) + _diff_opt(o1, q) + _diff_opt(o1.o, q.o) + _diff_opt(o1.o.b, q.o.b) + _diff_opt(o1.o.u, q.o.u) + _diff_opt(o1.o.s, q.o.s) + + +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() + + a = dumps(o1) + q = loads(a) + _diff_opt(o1, q) + _diff_opt(o1.o, q.o) + _diff_opt(o1.o.b, q.o.b) + _diff_opt(o1.o.b2, q.o.b2) + _diff_opt(o1.o.b3, q.o.b3) + + +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) + _diff_conf(cfg, q) + try: + delete_session('29090931') + except ConfigError: + pass + + +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('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('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('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__ diff --git a/tiramisu/option.py b/tiramisu/option.py index 32465c2..98204de 100644 --- a/tiramisu/option.py +++ b/tiramisu/option.py @@ -400,9 +400,6 @@ class Option(OnlyOption): """ 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: @@ -413,7 +410,8 @@ class Option(OnlyOption): #if context, calculate value, otherwise get default value if context is not None: opt_value = context._getattr( - descr.impl_get_path_by_opt(opt), validate=False) + descr.impl_get_path_by_opt(opt), validate=False, + force_permissive=True) else: opt_value = opt.impl_getdefault() @@ -641,31 +639,15 @@ class Option(OnlyOption): 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 @@ -921,8 +903,8 @@ class PortOption(Option): for val in value: try: if not self._extra['_min_value'] <= int(val) <= self._extra['_max_value']: - raise ValueError('invalid port, must be an between {0} ' - 'and {1}'.format( + raise ValueError(_('invalid port, must be an between {0} ' + 'and {1}').format( self._extra['_min_value'], self._extra['_max_value'])) except ValueError: @@ -979,19 +961,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].impl_getname(), @@ -1080,8 +1057,8 @@ class DomainnameOption(Option): if self._dom_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): @@ -1338,13 +1315,10 @@ class OptionDescription(BaseOption, StorageOptionDescription): 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) # ____________________________________________________________ # serialize object