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