a1a9fd11059c08134fcf70b73a262eb58a897176
[tiramisu.git] / test / test_option_calculation.py
1 import autopath
2 from py.test import raises
3
4 from tiramisu.setting import groups
5 from tiramisu.config import Config
6 from tiramisu.option import ChoiceOption, BoolOption, IntOption, FloatOption, \
7     StrOption, OptionDescription, SymLinkOption
8 from tiramisu.error import PropertiesOptionError, ConflictError, SlaveError, ConfigError
9
10
11 def return_val():
12     return 'val'
13
14
15 def return_concat(*args):
16     return '.'.join(list(args))
17
18
19 def return_list(value=None):
20     return ['val', 'val']
21
22
23 def return_list2(*args):
24     return list(args)
25
26
27 def return_value(value=None):
28     return value
29
30
31 def return_value2(*args, **kwargs):
32     value = list(args)
33     value.extend(kwargs.values())
34     return value
35
36
37 def make_description():
38     gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref')
39     gcdummy = BoolOption('dummy', 'dummy', default=False)
40     objspaceoption = ChoiceOption('objspace', 'Object space',
41                                   ('std', 'thunk'), 'std')
42     booloption = BoolOption('bool', 'Test boolean option', default=True)
43     intoption = IntOption('int', 'Test int option', default=0)
44     intoption2 = IntOption('int', 'Test int option', default=0)
45     floatoption = FloatOption('float', 'Test float option', default=2.3)
46     stroption = StrOption('str', 'Test string option', default="abc")
47     boolop = BoolOption('boolop', 'Test boolean option op', default=True)
48     wantref_option = BoolOption('wantref', 'Test requires', default=False,
49                                 requires=({'option': boolop, 'expected': True, 'action': 'hidden'},))
50     wantframework_option = BoolOption('wantframework', 'Test requires',
51                                       default=False,
52                                       requires=({'option': boolop, 'expected': True, 'action': 'hidden'},))
53     gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption, intoption2])
54     descr = OptionDescription('constraints', '', [gcgroup, booloption, objspaceoption,
55                               wantref_option, stroption,
56                               wantframework_option,
57                               intoption, boolop])
58     return descr
59
60
61 def make_description_duplicates():
62     gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref')
63     ## dummy 1
64     gcdummy = BoolOption('dummy', 'dummy', default=False)
65     objspaceoption = ChoiceOption('objspace', 'Object space',
66                                   ('std', 'thunk'), 'std')
67     booloption = BoolOption('bool', 'Test boolean option', default=True)
68     intoption = IntOption('int', 'Test int option', default=0)
69     floatoption = FloatOption('float', 'Test float option', default=2.3)
70     stroption = StrOption('str', 'Test string option', default="abc")
71     boolop = BoolOption('boolop', 'Test boolean option op', default=True)
72     wantref_option = BoolOption('wantref', 'Test requires', default=False,
73                                 requires=({'option': boolop, 'expected': True, 'action': 'hidden'},))
74     wantframework_option = BoolOption('wantframework', 'Test requires',
75                                       default=False,
76                                       requires=({'option': boolop, 'expected': True, 'action': 'hidden'},))
77     # dummy2 (same path)
78     gcdummy2 = BoolOption('dummy', 'dummy2', default=True)
79     # dummy3 (same name)
80     gcdummy3 = BoolOption('dummy', 'dummy2', default=True)
81     gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, gcdummy2, floatoption])
82     descr = OptionDescription('constraints', '', [gcgroup, booloption, objspaceoption,
83                               wantref_option, stroption,
84                               wantframework_option,
85                               intoption, boolop, gcdummy3])
86     return descr
87
88
89 def test_identical_paths():
90     """If in the schema (the option description) there is something that
91     have the same name, an exection is raised
92     """
93     raises(ConflictError, "make_description_duplicates()")
94
95
96 def make_description2():
97     gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
98     gcdummy = BoolOption('dummy', 'dummy', default=False)
99
100     floatoption = FloatOption('float', 'Test float option', default=2.3)
101
102     objspaceoption = ChoiceOption('objspace', 'Object space',
103                                   ['std', 'thunk'], 'std')
104     booloption = BoolOption('bool', 'Test boolean option', default=True)
105     intoption = IntOption('int', 'Test int option', default=0)
106     stroption = StrOption('str', 'Test string option', default="abc")
107     # first multi
108     boolop = BoolOption('boolop', 'Test boolean option op', default=True)
109     boolop.enable_multi()
110     wantref_option = BoolOption('wantref', 'Test requires', default=False,
111                                 requires=({'option': boolop, 'expected': True, 'action': 'hidden'},))
112     # second multi
113     wantframework_option = BoolOption('wantframework', 'Test requires',
114                                       default=False,
115                                       requires=({'option': boolop, 'expected': True, 'action': 'hidden'},))
116     wantframework_option.enable_multi()
117
118     gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption])
119     descr = OptionDescription('constraints', '', [gcgroup, booloption, objspaceoption,
120                               wantref_option, stroption,
121                               wantframework_option,
122                               intoption, boolop])
123     return descr
124
125
126 # FIXME: il faudra tester les validations sur les multis
127 #def test_multi_constraints():
128 #    "a multi in a constraint has to have the same length"
129 #    descr = make_description2()
130 #    cfg = Config(descr)
131 #    cfg.boolop = [True, True, False]
132 #    cfg.wantframework = [False, False, True]
133 #
134 #def test_multi_raise():
135 #    "a multi in a constraint has to have the same length"
136 #    # FIXME fusionner les deux tests, MAIS PROBLEME :
137 #    # il ne devrait pas etre necessaire de refaire une config
138 #    # si la valeur est modifiee une deuxieme fois ->
139 #    #raises(ConflictConfigError, "cfg.wantframework = [False, False, True]")
140 #    #   ExceptionFailure: 'DID NOT RAISE'
141 #    descr = make_description2()
142 #    cfg = Config(descr)
143 #    cfg.boolop = [True]
144 #    raises(ConflictConfigError, "cfg.wantframework = [False, False, True]")
145 # ____________________________________________________________
146 # adding dynamically new options description schema
147 #def test_newoption_add_in_descr():
148 #    descr = make_description()
149 #    newoption = BoolOption('newoption', 'dummy twoo', default=False)
150 #    descr.add_child(newoption)
151 #    config = Config(descr)
152 #    assert config.newoption == False
153
154 #def test_newoption_add_in_subdescr():
155 #    descr = make_description()
156 #    newoption = BoolOption('newoption', 'dummy twoo', default=False)
157 #    descr.gc.add_child(newoption)
158 #    config = Config(descr)
159 #    config.bool = False
160 #    assert config.gc.newoption == False
161
162 #def test_newoption_add_in_config():
163 #    descr = make_description()
164 #    config = Config(descr)
165 #    config.bool = False
166 #    newoption = BoolOption('newoption', 'dummy twoo', default=False)
167 #    descr.add_child(newoption)
168 #    config.cfgimpl_update()
169 #    assert config.newoption == False
170 # ____________________________________________________________
171
172
173 def make_description_requires():
174     gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref')
175     gcdummy = BoolOption('dummy', 'dummy', default=False)
176
177     floatoption = FloatOption('float', 'Test float option', default=2.3)
178
179     objspaceoption = ChoiceOption('objspace', 'Object space',
180                                   ('std', 'thunk'), 'std')
181     booloption = BoolOption('bool', 'Test boolean option', default=True)
182     intoption = IntOption('int', 'Test int option', default=0)
183     stroption = StrOption('str', 'Test string option', default="abc",
184                           requires=({'option': intoption, 'expected': 1, 'action': 'hidden'},))
185
186     gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption])
187     descr = OptionDescription('constraints', '', [gcgroup, booloption, objspaceoption,
188                               stroption, intoption])
189     return descr
190
191
192 def test_hidden_if_in():
193     descr = make_description_requires()
194     cfg = Config(descr)
195     setting = cfg.cfgimpl_get_settings()
196     cfg.read_write()
197     stroption = cfg.unwrap_from_path('str')
198     assert not 'hidden' in setting[stroption]
199     cfg.int = 1
200     raises(PropertiesOptionError, "cfg.str")
201     raises(PropertiesOptionError, 'cfg.str="uvw"')
202     assert 'hidden' in setting[stroption]
203
204
205 def test_hidden_if_in_with_group():
206     gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref')
207     gcdummy = BoolOption('dummy', 'dummy', default=False)
208
209     floatoption = FloatOption('float', 'Test float option', default=2.3)
210
211     objspaceoption = ChoiceOption('objspace', 'Object space',
212                                   ('std', 'thunk'), 'std')
213     booloption = BoolOption('bool', 'Test boolean option', default=True)
214     intoption = IntOption('int', 'Test int option', default=0)
215     stroption = StrOption('str', 'Test string option', default="abc")
216     gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption],
217                                 requires=({'option': intoption, 'expected': 1, 'action': 'hidden'},))
218     descr = OptionDescription('constraints', '', [gcgroup, booloption,
219                               objspaceoption, stroption, intoption])
220     cfg = Config(descr)
221     setting = cfg.cfgimpl_get_settings()
222     cfg.read_write()
223     assert not 'hidden' in setting[stroption]
224     cfg.int = 1
225     raises(PropertiesOptionError, "cfg.gc.name")
226
227
228 def test_disabled_with_group():
229     gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref')
230     gcdummy = BoolOption('dummy', 'dummy', default=False)
231
232     floatoption = FloatOption('float', 'Test float option', default=2.3)
233
234     objspaceoption = ChoiceOption('objspace', 'Object space',
235                                   ('std', 'thunk'), 'std')
236     booloption = BoolOption('bool', 'Test boolean option', default=True)
237     intoption = IntOption('int', 'Test int option', default=0)
238     stroption = StrOption('str', 'Test string option', default="abc")
239     gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption],
240                                 requires=({'option': intoption, 'expected': 1, 'action': 'disabled'},))
241     descr = OptionDescription('constraints', '', [gcgroup, booloption,
242                               objspaceoption, stroption, intoption])
243     cfg = Config(descr)
244     cfg.read_write()
245     assert cfg.gc.name
246     cfg.int = 1
247     raises(PropertiesOptionError, "cfg.gc.name")
248 #____________________________________________________________
249
250
251 def make_description_callback():
252     gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref')
253     gcdummy = BoolOption('dummy', 'dummy')
254     objspaceoption = ChoiceOption('objspace', 'Object space',
255                                   ('std', 'thunk'), 'std')
256     booloption = BoolOption('bool', 'Test boolean option', default=True)
257     intoption = IntOption('int', 'Test int option', default=0)
258     floatoption = FloatOption('float', 'Test float option', default=2.3)
259     stroption = StrOption('str', 'Test string option', default="abc")
260     boolop = BoolOption('boolop', 'Test boolean option op', default=True)
261     wantref_option = BoolOption('wantref', 'Test requires', default=False,
262                                 requires=({'option': boolop, 'expected': True, 'action': 'hidden'},))
263     wantframework_option = BoolOption('wantframework', 'Test requires',
264                                       default=False,
265                                       requires=({'option': boolop, 'expected': True, 'action': 'hidden'},))
266     gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption])
267     descr = OptionDescription('constraints', '', [gcgroup, booloption, objspaceoption,
268                               wantref_option, stroption,
269                               wantframework_option,
270                               intoption, boolop])
271     return descr
272
273
274 def test_has_callback():
275     descr = make_description_callback()
276     # here the owner is 'default'
277     config = Config(descr)
278     setting = config.cfgimpl_get_settings()
279     config.read_write()
280     config.bool = False
281     # because dummy has a callback
282     dummy = config.unwrap_from_path('gc.dummy')
283     setting.append('freeze')
284     setting[dummy].append('frozen')
285     raises(PropertiesOptionError, "config.gc.dummy = True")
286
287
288 def test_freeze_and_has_callback():
289     descr = make_description_callback()
290     config = Config(descr)
291     setting = config.cfgimpl_get_settings()
292     config.read_write()
293     config.bool = False
294     setting = config.cfgimpl_get_settings()
295     setting.append('freeze')
296     dummy = config.unwrap_from_path('gc.dummy')
297     setting[dummy].append('frozen')
298     raises(PropertiesOptionError, "config.gc.dummy = True")
299
300
301 def test_callback():
302     val1 = StrOption('val1', "", callback=return_val)
303     maconfig = OptionDescription('rootconfig', '', [val1])
304     cfg = Config(maconfig)
305     cfg.read_write()
306     assert cfg.val1 == 'val'
307     cfg.val1 = 'new-val'
308     assert cfg.val1 == 'new-val'
309     del(cfg.val1)
310     assert cfg.val1 == 'val'
311
312
313 def test_callback_value():
314     val1 = StrOption('val1', "", 'val')
315     val2 = StrOption('val2', "", callback=return_value, callback_params={'': ((val1, False),)})
316     val3 = StrOption('val3', "", callback=return_value, callback_params={'': ('yes',)})
317     val4 = StrOption('val4', "", callback=return_value, callback_params={'value': ((val1, False),)})
318     val5 = StrOption('val5', "", callback=return_value, callback_params={'value': ('yes',)})
319     maconfig = OptionDescription('rootconfig', '', [val1, val2, val3, val4, val5])
320     cfg = Config(maconfig)
321     cfg.read_write()
322     assert cfg.val1 == 'val'
323     assert cfg.val2 == 'val'
324     assert cfg.val4 == 'val'
325     cfg.val1 = 'new-val'
326     assert cfg.val1 == 'new-val'
327     assert cfg.val2 == 'new-val'
328     assert cfg.val4 == 'new-val'
329     del(cfg.val1)
330     assert cfg.val1 == 'val'
331     assert cfg.val2 == 'val'
332     assert cfg.val3 == 'yes'
333     assert cfg.val4 == 'val'
334     assert cfg.val5 == 'yes'
335
336
337 def test_callback_value_tuple():
338     val1 = StrOption('val1', "", 'val1')
339     val2 = StrOption('val2', "", 'val2')
340     val3 = StrOption('val3', "", callback=return_concat, callback_params={'': ((val1, False), (val2, False))})
341     val4 = StrOption('val4', "", callback=return_concat, callback_params={'': ('yes', 'no')})
342     raises(ValueError, "StrOption('val4', '', callback=return_concat, callback_params={'value': ('yes', 'no')})")
343     maconfig = OptionDescription('rootconfig', '', [val1, val2, val3, val4])
344     cfg = Config(maconfig)
345     cfg.read_write()
346     assert cfg.val1 == 'val1'
347     assert cfg.val2 == 'val2'
348     assert cfg.val3 == 'val1.val2'
349     assert cfg.val4 == 'yes.no'
350     cfg.val1 = 'new-val'
351     assert cfg.val3 == 'new-val.val2'
352     del(cfg.val1)
353     assert cfg.val3 == 'val1.val2'
354
355
356 def test_callback_value_force_permissive():
357     val1 = StrOption('val1', "", 'val', properties=('disabled',))
358     val2 = StrOption('val2', "", callback=return_value, callback_params={'': ((val1, False),)})
359     val3 = StrOption('val3', "", callback=return_value, callback_params={'': ((val1, True),)})
360     maconfig = OptionDescription('rootconfig', '', [val1, val2, val3])
361     cfg = Config(maconfig)
362     cfg.read_only()
363     raises(ConfigError, "cfg.val2")
364     assert cfg.val3 is None
365
366
367 def test_callback_symlink():
368     val1 = StrOption('val1', "", 'val')
369     val2 = SymLinkOption('val2', val1)
370     val3 = StrOption('val3', "", callback=return_value, callback_params={'': ((val2, False),)})
371     maconfig = OptionDescription('rootconfig', '', [val1, val2, val3])
372     cfg = Config(maconfig)
373     cfg.read_write()
374     assert cfg.val1 == 'val'
375     assert cfg.val2 == 'val'
376     assert cfg.val3 == 'val'
377     cfg.val1 = 'new-val'
378     assert cfg.val1 == 'new-val'
379     assert cfg.val3 == 'new-val'
380     del(cfg.val1)
381     assert cfg.val1 == 'val'
382     assert cfg.val3 == 'val'
383
384
385 def test_callback_list():
386     val1 = StrOption('val1', "", callback=return_list)
387     maconfig = OptionDescription('rootconfig', '', [val1])
388     cfg = Config(maconfig)
389     cfg.read_write()
390     raises(ValueError, "cfg.val1")
391
392
393 def test_callback_multi():
394     val1 = StrOption('val1', "", callback=return_val, multi=True)
395     maconfig = OptionDescription('rootconfig', '', [val1])
396     cfg = Config(maconfig)
397     cfg.read_write()
398     assert cfg.val1 == ['val']
399     cfg.val1 = ['new-val']
400     assert cfg.val1 == ['new-val']
401     cfg.val1.append('new-val2')
402     assert cfg.val1 == ['new-val', 'new-val2']
403     del(cfg.val1)
404     assert cfg.val1 == ['val']
405
406
407 def test_callback_multi_value():
408     val1 = StrOption('val1', "", ['val'], multi=True)
409     val2 = StrOption('val2', "", multi=True, callback=return_value, callback_params={'': ((val1, False),)})
410     val3 = StrOption('val3', "", multi=True, callback=return_value, callback_params={'': ('yes',)})
411     val4 = StrOption('val4', "", multi=True, callback=return_list2, callback_params={'': ((val1, False), 'yes')})
412     maconfig = OptionDescription('rootconfig', '', [val1, val2, val3, val4])
413     cfg = Config(maconfig)
414     cfg.read_write()
415     assert cfg.val1 == ['val']
416     assert cfg.val2 == ['val']
417     assert cfg.val4 == ['val', 'yes']
418     cfg.val1 = ['new-val']
419     assert cfg.val1 == ['new-val']
420     assert cfg.val2 == ['new-val']
421     assert cfg.val4 == ['new-val', 'yes']
422     cfg.val1.append('new-val2')
423     assert cfg.val1 == ['new-val', 'new-val2']
424     assert cfg.val2 == ['new-val', 'new-val2']
425     assert cfg.val4 == ['new-val', 'yes', 'new-val2', 'yes']
426     del(cfg.val1)
427     assert cfg.val1 == ['val']
428     assert cfg.val2 == ['val']
429     assert cfg.val3 == ['yes']
430     assert cfg.val4 == ['val', 'yes']
431
432
433 def test_callback_multi_list():
434     val1 = StrOption('val1', "", callback=return_list, multi=True)
435     maconfig = OptionDescription('rootconfig', '', [val1])
436     cfg = Config(maconfig)
437     cfg.read_write()
438     assert cfg.val1 == ['val', 'val']
439     cfg.val1 = ['new-val']
440     assert cfg.val1 == ['new-val']
441     cfg.val1.append('new-val2')
442     assert cfg.val1 == ['new-val', 'new-val2']
443     del(cfg.val1)
444     assert cfg.val1 == ['val', 'val']
445
446
447 def test_callback_master_and_slaves_master():
448     val1 = StrOption('val1', "", multi=True, callback=return_val)
449     val2 = StrOption('val2', "", multi=True)
450     interface1 = OptionDescription('val1', '', [val1, val2])
451     interface1.impl_set_group_type(groups.master)
452     maconfig = OptionDescription('rootconfig', '', [interface1])
453     cfg = Config(maconfig)
454     cfg.read_write()
455     assert cfg.val1.val1 == ['val']
456     cfg.val1.val1.append(None)
457     assert cfg.val1.val1 == ['val', 'val']
458     assert cfg.val1.val2 == [None, None]
459
460
461 def test_callback_master_and_slaves_master_list():
462     val1 = StrOption('val1', "", multi=True, callback=return_list)
463     val2 = StrOption('val2', "", multi=True)
464     interface1 = OptionDescription('val1', '', [val1, val2])
465     interface1.impl_set_group_type(groups.master)
466     maconfig = OptionDescription('rootconfig', '', [interface1])
467     cfg = Config(maconfig)
468     cfg.read_write()
469     assert cfg.val1.val1 == ['val', 'val']
470     assert cfg.val1.val2 == [None, None]
471     cfg.val1.val1.append(None)
472     assert cfg.val1.val1 == ['val', 'val', None]
473     assert cfg.val1.val2 == [None, None, None]
474     del(cfg.val1.val1)
475     assert cfg.val1.val1 == ['val', 'val']
476     assert cfg.val1.val2 == [None, None]
477     assert cfg.val1.val1.pop(1)
478     assert cfg.val1.val1 == ['val']
479     assert cfg.val1.val2 == [None]
480
481
482 def test_callback_master_and_slaves_slave():
483     val1 = StrOption('val1', "", multi=True)
484     val2 = StrOption('val2', "", multi=True, callback=return_val)
485     interface1 = OptionDescription('val1', '', [val1, val2])
486     interface1.impl_set_group_type(groups.master)
487     maconfig = OptionDescription('rootconfig', '', [interface1])
488     cfg = Config(maconfig)
489     cfg.read_write()
490     assert cfg.val1.val1 == []
491     assert cfg.val1.val2 == []
492     #
493     cfg.val1.val1 = ['val1']
494     assert cfg.val1.val1 == ['val1']
495     assert cfg.val1.val2 == ['val']
496     #
497     cfg.val1.val1.append('val2')
498     assert cfg.val1.val1 == ['val1', 'val2']
499     assert cfg.val1.val2 == ['val', 'val']
500     #
501     cfg.val1.val1 = ['val1', 'val2', 'val3']
502     assert cfg.val1.val1 == ['val1', 'val2', 'val3']
503     assert cfg.val1.val2 == ['val', 'val', 'val']
504     #
505     cfg.val1.val1.pop(2)
506     assert cfg.val1.val1 == ['val1', 'val2']
507     assert cfg.val1.val2 == ['val', 'val']
508     #
509     cfg.val1.val2 = ['val2', 'val2']
510     assert cfg.val1.val2 == ['val2', 'val2']
511     #
512     cfg.val1.val1.append('val3')
513     assert cfg.val1.val2 == ['val2', 'val2', 'val']
514
515
516 def test_callback_master_and_slaves_slave_list():
517     val1 = StrOption('val1', "", multi=True)
518     val2 = StrOption('val2', "", multi=True, callback=return_list)
519     interface1 = OptionDescription('val1', '', [val1, val2])
520     interface1.impl_set_group_type(groups.master)
521     maconfig = OptionDescription('rootconfig', '', [interface1])
522     cfg = Config(maconfig)
523     cfg.read_write()
524     assert cfg.val1.val2 == []
525     cfg.val1.val1 = ['val1', 'val2']
526     assert cfg.val1.val1 == ['val1', 'val2']
527     assert cfg.val1.val2 == ['val', 'val']
528     cfg.val1.val1 = ['val1']
529     #wrong len
530     raises(SlaveError, 'cfg.val1.val2')
531
532
533 def test_callback_master_and_slaves_value():
534     val1 = StrOption('val1', "", multi=True)
535     val2 = StrOption('val2', "", multi=True, callback=return_value, callback_params={'': ((val1, False),)})
536     val3 = StrOption('val3', "", multi=True, callback=return_value, callback_params={'': ('yes',)})
537     val4 = StrOption('val4', '', multi=True, default=['val10', 'val11'])
538     val5 = StrOption('val5', "", multi=True, callback=return_value, callback_params={'': ((val4, False),)})
539     interface1 = OptionDescription('val1', '', [val1, val2, val3, val5])
540     interface1.impl_set_group_type(groups.master)
541     maconfig = OptionDescription('rootconfig', '', [interface1, val4])
542     cfg = Config(maconfig)
543     cfg.read_write()
544     assert cfg.val1.val1 == []
545     assert cfg.val1.val2 == []
546     assert cfg.val1.val3 == []
547     assert cfg.val1.val5 == []
548     #
549     cfg.val1.val1 = ['val1']
550     assert cfg.val1.val1 == ['val1']
551     assert cfg.val1.val2 == ['val1']
552     assert cfg.val1.val3 == ['yes']
553     assert cfg.val1.val5 == ['val10']
554     #
555     cfg.val1.val1.append('val2')
556     assert cfg.val1.val1 == ['val1', 'val2']
557     assert cfg.val1.val2 == ['val1', 'val2']
558     assert cfg.val1.val3 == ['yes', 'yes']
559     assert cfg.val1.val5 == ['val10', 'val11']
560     #
561     cfg.val1.val1 = ['val1', 'val2', 'val3']
562     assert cfg.val1.val1 == ['val1', 'val2', 'val3']
563     assert cfg.val1.val2 == ['val1', 'val2', 'val3']
564     assert cfg.val1.val3 == ['yes', 'yes', 'yes']
565     assert cfg.val1.val5 == ['val10', 'val11', None]
566     #
567     cfg.val1.val1.pop(2)
568     assert cfg.val1.val1 == ['val1', 'val2']
569     assert cfg.val1.val2 == ['val1', 'val2']
570     assert cfg.val1.val3 == ['yes', 'yes']
571     assert cfg.val1.val5 == ['val10', 'val11']
572     #
573     cfg.val1.val2 = ['val2', 'val2']
574     cfg.val1.val3 = ['val2', 'val2']
575     cfg.val1.val5 = ['val2', 'val2']
576     assert cfg.val1.val2 == ['val2', 'val2']
577     assert cfg.val1.val3 == ['val2', 'val2']
578     assert cfg.val1.val5 == ['val2', 'val2']
579     #
580     cfg.val1.val1.append('val3')
581     assert cfg.val1.val2 == ['val2', 'val2', 'val3']
582     assert cfg.val1.val3 == ['val2', 'val2', 'yes']
583     assert cfg.val1.val5 == ['val2', 'val2', None]
584     cfg.cfgimpl_get_settings().remove('cache')
585     cfg.val4 = ['val10', 'val11', 'val12']
586     #if value is already set, not updated !
587     cfg.val1.val1.pop(2)
588     cfg.val1.val1.append('val3')
589     cfg.val1.val1 = ['val1', 'val2', 'val3']
590     assert cfg.val1.val5 == ['val2', 'val2', 'val12']
591
592
593 def test_callback_hidden():
594     opt1 = BoolOption('opt1', '')
595     opt2 = BoolOption('opt2', '', callback=return_value, callback_params={'': ((opt1, False),)})
596     od1 = OptionDescription('od1', '', [opt1], properties=('hidden',))
597     od2 = OptionDescription('od2', '', [opt2])
598     maconfig = OptionDescription('rootconfig', '', [od1, od2])
599     cfg = Config(maconfig)
600     cfg.cfgimpl_get_settings().setpermissive(('hidden',))
601     cfg.read_write()
602     raises(PropertiesOptionError, 'cfg.od1.opt1')
603     cfg.od2.opt2
604
605
606 def test_callback_two_disabled():
607     opt1 = BoolOption('opt1', '', properties=('disabled',))
608     opt2 = BoolOption('opt2', '', callback=return_value, callback_params={'': ((opt1, False),)}, properties=('disabled',))
609     od1 = OptionDescription('od1', '', [opt1])
610     od2 = OptionDescription('od2', '', [opt2])
611     maconfig = OptionDescription('rootconfig', '', [od1, od2])
612     cfg = Config(maconfig)
613     cfg.read_write()
614     raises(PropertiesOptionError, 'cfg.od2.opt2')
615
616
617 def test_callback_calculating_disabled():
618     opt1 = BoolOption('opt1', '', properties=('disabled',))
619     opt2 = BoolOption('opt2', '', callback=return_value, callback_params={'': ((opt1, False),)})
620     od1 = OptionDescription('od1', '', [opt1])
621     od2 = OptionDescription('od2', '', [opt2])
622     maconfig = OptionDescription('rootconfig', '', [od1, od2])
623     cfg = Config(maconfig)
624     cfg.read_write()
625     raises(ConfigError, 'cfg.od2.opt2')
626
627
628 def test_callback_calculating_mandatory():
629     opt1 = BoolOption('opt1', '', properties=('disabled',))
630     opt2 = BoolOption('opt2', '', callback=return_value, callback_params={'': ((opt1, False),)}, properties=('mandatory',))
631     od1 = OptionDescription('od1', '', [opt1])
632     od2 = OptionDescription('od2', '', [opt2])
633     maconfig = OptionDescription('rootconfig', '', [od1, od2])
634     cfg = Config(maconfig)
635     cfg.read_only()
636     raises(ConfigError, 'cfg.od2.opt2')
637
638
639 def test_callback_two_disabled_multi():
640     opt1 = BoolOption('opt1', '', properties=('disabled',))
641     opt2 = BoolOption('opt2', '', callback=return_value, callback_params={'': ((opt1, False),)}, properties=('disabled',), multi=True)
642     od1 = OptionDescription('od1', '', [opt1])
643     od2 = OptionDescription('od2', '', [opt2])
644     maconfig = OptionDescription('rootconfig', '', [od1, od2])
645     cfg = Config(maconfig)
646     cfg.read_write()
647     raises(PropertiesOptionError, 'cfg.od2.opt2')
648
649
650 def test_callback_multi_list_params():
651     val1 = StrOption('val1', "", multi=True, default=['val1', 'val2'])
652     val2 = StrOption('val2', "", multi=True, callback=return_list, callback_params={'': ((val1, False),)})
653     oval2 = OptionDescription('val2', '', [val2])
654     maconfig = OptionDescription('rootconfig', '', [val1, oval2])
655     cfg = Config(maconfig)
656     cfg.read_write()
657     assert cfg.val2.val2 == ['val', 'val', 'val', 'val']
658
659
660 def test_callback_multi_list_params_key():
661     val1 = StrOption('val1', "", multi=True, default=['val1', 'val2'])
662     val2 = StrOption('val2', "", multi=True, callback=return_list, callback_params={'value': ((val1, False),)})
663     oval2 = OptionDescription('val2', '', [val2])
664     maconfig = OptionDescription('rootconfig', '', [val1, oval2])
665     cfg = Config(maconfig)
666     cfg.read_write()
667     assert cfg.val2.val2 == ['val', 'val', 'val', 'val']
668
669
670 def test_callback_multi_multi():
671     val1 = StrOption('val1', "", multi=True, default=['val1', 'val2', 'val3'])
672     val2 = StrOption('val2', "", multi=True, default=['val11', 'val12'])
673     val3 = StrOption('val3', "", default='val4')
674     val4 = StrOption('val4', "", multi=True, callback=return_list2, callback_params={'': ((val1, False), (val2, False))})
675     val5 = StrOption('val5', "", multi=True, callback=return_list2, callback_params={'': ((val1, False), (val3, False))})
676     val6 = StrOption('val6', "", multi=True, default=['val21', 'val22', 'val23'])
677     val7 = StrOption('val7', "", multi=True, callback=return_list2, callback_params={'': ((val1, False), (val6, False))})
678     raises(ValueError, "StrOption('val8', '', multi=True, callback=return_list2, callback_params={'value': ((val1, False), (val6, False))})")
679     maconfig = OptionDescription('rootconfig', '', [val1, val2, val3, val4, val5, val6, val7])
680     cfg = Config(maconfig)
681     cfg.read_write()
682     raises(ConfigError, "cfg.val4")
683     assert cfg.val5 == ['val1', 'val4', 'val2', 'val4', 'val3', 'val4']
684     assert cfg.val7 == ['val1', 'val21', 'val2', 'val22', 'val3', 'val23']
685
686
687 def test_multi_with_no_value():
688     #First option return [] (so without value)
689     val1 = StrOption('val1', "", ['val'], multi=True)
690     val2 = StrOption('val2', "", multi=True)
691     val3 = StrOption('val3', '', multi=True, callback=return_value, callback_params={'': ((val2, False),), 'value': ((val1, False),)})
692     od = OptionDescription('od', '', [val1, val2, val3])
693     c = Config(od)
694     raises(ConfigError, "c.val3")