d5db882abab277bad17794a877c505613a7ce594
[tiramisu.git] / test / test_dyn_optiondescription.py
1 # coding: utf-8
2 import autopath
3
4 from tiramisu.setting import groups, owners
5 from tiramisu.option import BoolOption, StrOption, ChoiceOption, IPOption, \
6     NetworkOption, NetmaskOption, IntOption, FloatOption, \
7     UnicodeOption, PortOption, BroadcastOption, DomainnameOption, \
8     EmailOption, URLOption, UsernameOption, FilenameOption, SymLinkOption, \
9     OptionDescription, DynOptionDescription, DynSymLinkOption, submulti
10 from tiramisu.config import Config
11 from tiramisu.error import PropertiesOptionError, ConfigError, ConflictError
12 from tiramisu.storage import delete_session
13 from test.test_state import _diff_opts, _diff_conf
14
15 from py.test import raises
16 from pickle import dumps, loads
17
18
19 def return_true(value, param=None):
20     if value == 'val' and param in [None, 'yes']:
21         return
22     raise ValueError('no value')
23
24
25 def return_dynval(suffix, value='val'):
26     return value
27
28
29 def return_list2(suffix):
30     return [str(suffix), 'val2']
31
32
33 def return_list(val=None):
34     if val:
35         return val
36     else:
37         return ['val1', 'val2']
38
39
40 def return_same_list():
41     return ['val1', 'val1']
42
43
44 def return_wrong_list():
45     return ['---', ' ']
46
47
48 def test_build_dyndescription():
49     st = StrOption('st', '')
50     dod = DynOptionDescription('dod', '', [st], callback=return_list)
51     od = OptionDescription('od', '', [dod])
52     cfg = Config(od)
53     assert str(cfg) == """[dodval1]
54 [dodval2]"""
55     assert str(cfg.dodval1) == "stval1 = None"
56     assert str(cfg.dodval2) == "stval2 = None"
57
58
59 def test_subpath_dyndescription():
60     st = StrOption('st', '')
61     dod = DynOptionDescription('dod', '', [st], callback=return_list)
62     od = OptionDescription('od', '', [dod])
63     od2 = OptionDescription('od', '', [od])
64     cfg = Config(od2)
65     assert str(cfg) == "[od]"
66     assert str(cfg.od) == """[dodval1]
67 [dodval2]"""
68     assert str(cfg.od.dodval1) == "stval1 = None"
69     assert str(cfg.od.dodval2) == "stval2 = None"
70
71
72 def test_list_dyndescription():
73     st = StrOption('st', '')
74     dod = DynOptionDescription('dod', '', [st], callback=return_list)
75     od = OptionDescription('od', '', [dod])
76     od2 = OptionDescription('od', '', [od])
77     cfg = Config(od2)
78     assert cfg.od.dodval1.stval1 is None
79     assert cfg.od.dodval2.stval2 is None
80
81
82 def test_unknown_dyndescription():
83     st = StrOption('st', '')
84     dod = DynOptionDescription('dod', '', [st], callback=return_list)
85     od = OptionDescription('od', '', [dod])
86     od2 = OptionDescription('od', '', [od])
87     cfg = Config(od2)
88     raises(AttributeError, "cfg.od.dodval3")
89     raises(AttributeError, "cfg.od.dodval1.novalue")
90
91
92 def test_getdoc_dyndescription():
93     st = StrOption('st', 'doc1')
94     dod = DynOptionDescription('dod', 'doc2', [st], callback=return_list)
95     od = OptionDescription('od', '', [dod])
96     od2 = OptionDescription('od', '', [od])
97     cfg = Config(od2)
98     stval1 = cfg.unwrap_from_path('od.dodval1.stval1')
99     stval2 = cfg.unwrap_from_path('od.dodval2.stval2')
100     dodval1 = cfg.unwrap_from_path('od.dodval1')
101     dodval2 = cfg.unwrap_from_path('od.dodval2')
102     assert stval1.impl_getname() == 'stval1'
103     assert stval2.impl_getname() == 'stval2'
104     assert dodval1.impl_getname() == 'dodval1'
105     assert dodval2.impl_getname() == 'dodval2'
106     assert stval1.impl_getdoc() == 'doc1'
107     assert stval2.impl_getdoc() == 'doc1'
108     assert dodval1.impl_getdoc() == 'doc2'
109     assert dodval2.impl_getdoc() == 'doc2'
110
111
112 def test_getpaths_dyndescription():
113     st = StrOption('st', '')
114     dod = DynOptionDescription('dod', '', [st], callback=return_list)
115     od = OptionDescription('od', '', [dod])
116     od2 = OptionDescription('od', '', [od])
117     cfg = Config(od2)
118     assert cfg.cfgimpl_get_description().impl_getpaths() == ['od.dodval1.stval1', 'od.dodval2.stval2']
119     assert cfg.cfgimpl_get_description().impl_getpaths(include_groups=True) == ['od', 'od.dodval1', 'od.dodval1.stval1', 'od.dodval2', 'od.dodval2.stval2']
120
121
122 def test_mod_dyndescription():
123     st = StrOption('st', '')
124     dod = DynOptionDescription('dod', '', [st], callback=return_list)
125     od = OptionDescription('od', '', [dod])
126     od2 = OptionDescription('od', '', [od])
127     cfg = Config(od2)
128     owner = cfg.cfgimpl_get_settings().getowner()
129     stval1 = cfg.unwrap_from_path('od.dodval1.stval1')
130     stval2 = cfg.unwrap_from_path('od.dodval2.stval2')
131     assert cfg.od.dodval1.stval1 is None
132     assert cfg.od.dodval2.stval2 is None
133     assert cfg.getowner(stval1) == owners.default
134     assert cfg.getowner(stval2) == owners.default
135     cfg.od.dodval1.stval1 = 'yes'
136     assert cfg.od.dodval1.stval1 == 'yes'
137     assert cfg.od.dodval2.stval2 is None
138     assert cfg.getowner(stval1) == owner
139     assert cfg.getowner(stval2) == owners.default
140     cfg.od.dodval2.stval2 = 'no'
141     assert cfg.od.dodval1.stval1 == 'yes'
142     assert cfg.od.dodval2.stval2 == 'no'
143     assert cfg.getowner(st) == owners.default
144     assert cfg.getowner(stval1) == owner
145     assert cfg.getowner(stval2) == owner
146
147
148 def test_del_dyndescription():
149     st = StrOption('st', '')
150     dod = DynOptionDescription('dod', '', [st], callback=return_list)
151     od = OptionDescription('od', '', [dod])
152     od2 = OptionDescription('od', '', [od])
153     cfg = Config(od2)
154     owner = cfg.cfgimpl_get_settings().getowner()
155     stval1 = cfg.unwrap_from_path('od.dodval1.stval1')
156     assert cfg.od.dodval1.stval1 is None
157     assert cfg.od.dodval2.stval2 is None
158     cfg.od.dodval1.stval1 = 'yes'
159     assert cfg.getowner(stval1) == owner
160     del(cfg.od.dodval1.stval1)
161     assert cfg.getowner(stval1) == owners.default
162
163
164 def test_multi_dyndescription():
165     st = StrOption('st', '', multi=True)
166     dod = DynOptionDescription('dod', '', [st], callback=return_list)
167     od = OptionDescription('od', '', [dod])
168     od2 = OptionDescription('od', '', [od])
169     cfg = Config(od2)
170     owner = cfg.cfgimpl_get_settings().getowner()
171     stval1 = cfg.unwrap_from_path('od.dodval1.stval1')
172     stval2 = cfg.unwrap_from_path('od.dodval2.stval2')
173     assert cfg.od.dodval1.stval1 == []
174     assert cfg.od.dodval2.stval2 == []
175     assert cfg.getowner(stval1) == owners.default
176     assert cfg.getowner(stval2) == owners.default
177     cfg.od.dodval1.stval1.append('yes')
178     assert cfg.od.dodval1.stval1 == ['yes']
179     assert cfg.od.dodval2.stval2 == []
180     assert cfg.getowner(stval1) == owner
181     assert cfg.getowner(stval2) == owners.default
182     cfg.od.dodval2.stval2 = ['no']
183     assert cfg.od.dodval1.stval1 == ['yes']
184     assert cfg.od.dodval2.stval2 == ['no']
185     assert cfg.getowner(st) == owners.default
186     assert cfg.getowner(stval1) == owner
187     assert cfg.getowner(stval2) == owner
188     cfg.od.dodval1.stval1.append('yes')
189     assert cfg.od.dodval1.stval1 == ['yes', 'yes']
190     cfg.od.dodval1.stval1.pop(0)
191     assert cfg.od.dodval1.stval1 == ['yes']
192
193
194 def test_prop_dyndescription():
195     st = StrOption('st', '', properties=('test',))
196     dod = DynOptionDescription('dod', '', [st], callback=return_list)
197     od = OptionDescription('od', '', [dod])
198     od2 = OptionDescription('od', '', [od])
199     cfg = Config(od2)
200     stval1 = cfg.unwrap_from_path('od.dodval1.stval1')
201     stval2 = cfg.unwrap_from_path('od.dodval2.stval2')
202     dodval1 = cfg.unwrap_from_path('od.dodval1')
203     dodval2 = cfg.unwrap_from_path('od.dodval2')
204     assert str(cfg.cfgimpl_get_settings()[stval1]) in [str(['test']), str([u'test'])]
205     assert str(cfg.cfgimpl_get_settings()[stval2]) in [str(['test']), str([u'test'])]
206     cfg.cfgimpl_get_settings()[stval2].append('test2')
207     assert str(cfg.cfgimpl_get_settings()[stval1]) in [str(['test']), str([u'test'])]
208     assert str(cfg.cfgimpl_get_settings()[stval2]) in [str(['test', 'test2']), str([u'test', 'test2'])]
209     cfg.cfgimpl_get_settings()[stval1].remove('test')
210     assert str(cfg.cfgimpl_get_settings()[stval1]) == str([])
211     #
212     assert str(cfg.cfgimpl_get_settings()[dodval1]) == str([])
213     assert str(cfg.cfgimpl_get_settings()[dodval2]) == str([])
214     cfg.cfgimpl_get_settings()[dodval1].append('test1')
215     assert str(cfg.cfgimpl_get_settings()[dodval1]) in [str(['test1']), str([u'test1'])]
216     assert str(cfg.cfgimpl_get_settings()[dodval2]) == str([])
217     cfg.cfgimpl_get_settings()[dodval1].remove('test1')
218     assert str(cfg.cfgimpl_get_settings()[dodval1]) == str([])
219     assert str(cfg.cfgimpl_get_settings()[dodval2]) == str([])
220
221
222 def test_callback_dyndescription():
223     st = StrOption('st', '', callback=return_dynval)
224     dod = DynOptionDescription('dod', '', [st], callback=return_list)
225     od = OptionDescription('od', '', [dod])
226     od2 = OptionDescription('od', '', [od])
227     cfg = Config(od2)
228     owner = cfg.cfgimpl_get_settings().getowner()
229     stval1 = cfg.unwrap_from_path('od.dodval1.stval1')
230     stval2 = cfg.unwrap_from_path('od.dodval2.stval2')
231     assert cfg.od.dodval1.stval1 == 'val'
232     assert cfg.od.dodval2.stval2 == 'val'
233     assert cfg.getowner(stval1) == owners.default
234     assert cfg.getowner(stval2) == owners.default
235     cfg.od.dodval1.stval1 = 'val2'
236     assert cfg.od.dodval1.stval1 == 'val2'
237     assert cfg.od.dodval2.stval2 == 'val'
238     assert cfg.getowner(stval1) == owner
239     assert cfg.getowner(stval2) == owners.default
240     del(cfg.od.dodval1.stval1)
241     assert cfg.od.dodval1.stval1 == 'val'
242     assert cfg.od.dodval2.stval2 == 'val'
243     assert cfg.getowner(stval1) == owners.default
244     assert cfg.getowner(stval2) == owners.default
245
246
247 def test_callback_list_dyndescription():
248     st = StrOption('st', '', callback=return_list2, multi=True)
249     dod = DynOptionDescription('dod', '', [st], callback=return_list)
250     od = OptionDescription('od', '', [dod])
251     od2 = OptionDescription('od', '', [od])
252     cfg = Config(od2)
253     owner = cfg.cfgimpl_get_settings().getowner()
254     stval1 = cfg.unwrap_from_path('od.dodval1.stval1')
255     stval2 = cfg.unwrap_from_path('od.dodval2.stval2')
256     assert cfg.od.dodval1.stval1 == ['val1', 'val2']
257     assert cfg.od.dodval2.stval2 == ['val2', 'val2']
258     assert cfg.getowner(stval1) == owners.default
259     assert cfg.getowner(stval2) == owners.default
260     cfg.od.dodval1.stval1 = ['val3', 'val2']
261     assert cfg.od.dodval1.stval1 == ['val3', 'val2']
262     assert cfg.od.dodval2.stval2 == ['val2', 'val2']
263     assert cfg.getowner(stval1) == owner
264     assert cfg.getowner(stval2) == owners.default
265
266
267 def test_mandatory_dyndescription():
268     st = StrOption('st', '', properties=('mandatory',))
269     dod = DynOptionDescription('dod', '', [st], callback=return_list)
270     od = OptionDescription('od', '', [dod])
271     od2 = OptionDescription('od', '', [od])
272     cfg = Config(od2)
273     cfg.read_only()
274     raises(PropertiesOptionError, "cfg.od.dodval1.stval1")
275     raises(PropertiesOptionError, "cfg.od.dodval2.stval2")
276     cfg.read_write()
277     cfg.od.dodval1.stval1 = 'val'
278     cfg.read_only()
279     assert cfg.od.dodval1.stval1 == 'val'
280     raises(PropertiesOptionError, "cfg.od.dodval2.stval2")
281     cfg.read_write()
282     del(cfg.od.dodval1.stval1)
283     cfg.read_only()
284     raises(PropertiesOptionError, "cfg.od.dodval1.stval1")
285     assert cfg.cfgimpl_get_values().mandatory_warnings() == ['od.dodval1.stval1', 'od.dodval2.stval2']
286
287
288 def test_build_dyndescription_context():
289     val1 = StrOption('val1', '', ['val1', 'val2'], multi=True)
290     st = StrOption('st', '')
291     dod = DynOptionDescription('dod', '', [st], callback=return_list, callback_params={'': ((val1, False),)})
292     od = OptionDescription('od', '', [dod, val1])
293     cfg = Config(od)
294     assert str(cfg) == """[dodval1]
295 [dodval2]
296 val1 = ['val1', 'val2']"""
297     assert str(cfg.dodval1) == "stval1 = None"
298     assert str(cfg.dodval2) == "stval2 = None"
299     cfg.unwrap_from_path('dodval2')
300
301
302 def test_subpath_dyndescription_context():
303     val1 = StrOption('val1', '', ['val1', 'val2'], multi=True)
304     st = StrOption('st', '')
305     dod = DynOptionDescription('dod', '', [st], callback=return_list, callback_params={'': ((val1, False),)})
306     od = OptionDescription('od', '', [dod, val1])
307     od2 = OptionDescription('od', '', [od])
308     cfg = Config(od2)
309     assert str(cfg) == "[od]"
310     assert str(cfg.od) == """[dodval1]
311 [dodval2]
312 val1 = ['val1', 'val2']"""
313     assert str(cfg.od.dodval1) == "stval1 = None"
314     assert str(cfg.od.dodval2) == "stval2 = None"
315
316
317 def test_list_dyndescription_context():
318     val1 = StrOption('val1', '', ['val1', 'val2'], multi=True)
319     st = StrOption('st', '')
320     dod = DynOptionDescription('dod', '', [st], callback=return_list, callback_params={'': ((val1, False),)})
321     od = OptionDescription('od', '', [dod, val1])
322     od2 = OptionDescription('od', '', [od])
323     cfg = Config(od2)
324     assert cfg.od.dodval1.stval1 is None
325     assert cfg.od.dodval2.stval2 is None
326     raises(AttributeError, "cfg.od.dodval3")
327
328
329 def test_mod_dyndescription_context():
330     val1 = StrOption('val1', '', ['val1', 'val2'], multi=True)
331     st = StrOption('st', '')
332     dod = DynOptionDescription('dod', '', [st], callback=return_list, callback_params={'': ((val1, False),)})
333     od = OptionDescription('od', '', [dod, val1])
334     od2 = OptionDescription('od', '', [od])
335     cfg = Config(od2)
336     owner = cfg.cfgimpl_get_settings().getowner()
337     stval1 = cfg.unwrap_from_path('od.dodval1.stval1')
338     stval2 = cfg.unwrap_from_path('od.dodval2.stval2')
339     assert cfg.od.dodval1.stval1 is None
340     assert cfg.od.dodval2.stval2 is None
341     assert cfg.getowner(stval1) == owners.default
342     assert cfg.getowner(stval2) == owners.default
343     cfg.od.dodval1.stval1 = 'yes'
344     assert cfg.od.dodval1.stval1 == 'yes'
345     assert cfg.od.dodval2.stval2 is None
346     assert cfg.getowner(stval1) == owner
347     assert cfg.getowner(stval2) == owners.default
348     cfg.od.dodval2.stval2 = 'no'
349     assert cfg.od.dodval1.stval1 == 'yes'
350     assert cfg.od.dodval2.stval2 == 'no'
351     assert cfg.getowner(st) == owners.default
352     assert cfg.getowner(stval1) == owner
353     assert cfg.getowner(stval2) == owner
354
355
356 def test_del_dyndescription_context():
357     val1 = StrOption('val1', '', ['val1', 'val2'], multi=True)
358     st = StrOption('st', '')
359     dod = DynOptionDescription('dod', '', [st], callback=return_list, callback_params={'': ((val1, False),)})
360     od = OptionDescription('od', '', [dod, val1])
361     od2 = OptionDescription('od', '', [od])
362     cfg = Config(od2)
363     owner = cfg.cfgimpl_get_settings().getowner()
364     stval1 = cfg.unwrap_from_path('od.dodval1.stval1')
365     assert cfg.od.dodval1.stval1 is None
366     assert cfg.od.dodval2.stval2 is None
367     cfg.od.dodval1.stval1 = 'yes'
368     assert cfg.getowner(stval1) == owner
369     del(cfg.od.dodval1.stval1)
370     assert cfg.getowner(stval1) == owners.default
371
372
373 def test_multi_dyndescription_context():
374     val1 = StrOption('val1', '', ['val1', 'val2'], multi=True)
375     st = StrOption('st', '', multi=True)
376     dod = DynOptionDescription('dod', '', [st], callback=return_list, callback_params={'': ((val1, False),)})
377     od = OptionDescription('od', '', [dod, val1])
378     od2 = OptionDescription('od', '', [od])
379     cfg = Config(od2)
380     owner = cfg.cfgimpl_get_settings().getowner()
381     stval1 = cfg.unwrap_from_path('od.dodval1.stval1')
382     stval2 = cfg.unwrap_from_path('od.dodval2.stval2')
383     assert cfg.od.dodval1.stval1 == []
384     assert cfg.od.dodval2.stval2 == []
385     assert cfg.getowner(stval1) == owners.default
386     assert cfg.getowner(stval2) == owners.default
387     cfg.od.dodval1.stval1.append('yes')
388     assert cfg.od.dodval1.stval1 == ['yes']
389     assert cfg.od.dodval2.stval2 == []
390     assert cfg.getowner(stval1) == owner
391     assert cfg.getowner(stval2) == owners.default
392     cfg.od.dodval2.stval2 = ['no']
393     assert cfg.od.dodval1.stval1 == ['yes']
394     assert cfg.od.dodval2.stval2 == ['no']
395     assert cfg.getowner(st) == owners.default
396     assert cfg.getowner(stval1) == owner
397     assert cfg.getowner(stval2) == owner
398     cfg.od.dodval1.stval1.append('yes')
399     assert cfg.od.dodval1.stval1 == ['yes', 'yes']
400     cfg.od.dodval1.stval1.pop(0)
401     assert cfg.od.dodval1.stval1 == ['yes']
402
403
404 def test_prop_dyndescription_context():
405     val1 = StrOption('val1', '', ['val1', 'val2'], multi=True)
406     st = StrOption('st', '', properties=('test',))
407     dod = DynOptionDescription('dod', '', [st], callback=return_list, callback_params={'': ((val1, False),)})
408     od = OptionDescription('od', '', [dod, val1])
409     od2 = OptionDescription('od', '', [od])
410     cfg = Config(od2)
411     stval1 = cfg.unwrap_from_path('od.dodval1.stval1')
412     stval2 = cfg.unwrap_from_path('od.dodval2.stval2')
413     assert str(cfg.cfgimpl_get_settings()[stval1]) in [str(['test']), str([u'test'])]
414     assert str(cfg.cfgimpl_get_settings()[stval2]) in [str(['test']), str([u'test'])]
415     cfg.cfgimpl_get_settings()[stval2].append('test2')
416     assert str(cfg.cfgimpl_get_settings()[stval1]) in [str(['test']), str([u'test'])]
417     assert str(cfg.cfgimpl_get_settings()[stval2]) in [str(['test', 'test2']), str([u'test', 'test2'])]
418     cfg.cfgimpl_get_settings()[stval1].remove('test')
419     assert str(cfg.cfgimpl_get_settings()[stval1]) == str([])
420
421
422 def test_callback_dyndescription_context():
423     val1 = StrOption('val1', '', ['val1', 'val2'], multi=True)
424     st = StrOption('st', '', callback=return_dynval)
425     dod = DynOptionDescription('dod', '', [st], callback=return_list)
426     od = OptionDescription('od', '', [dod, val1])
427     od2 = OptionDescription('od', '', [od])
428     cfg = Config(od2)
429     owner = cfg.cfgimpl_get_settings().getowner()
430     stval1 = cfg.unwrap_from_path('od.dodval1.stval1')
431     stval2 = cfg.unwrap_from_path('od.dodval2.stval2')
432     assert cfg.od.dodval1.stval1 == 'val'
433     assert cfg.od.dodval2.stval2 == 'val'
434     assert cfg.getowner(stval1) == owners.default
435     assert cfg.getowner(stval2) == owners.default
436     cfg.od.dodval1.stval1 = 'val2'
437     assert cfg.od.dodval1.stval1 == 'val2'
438     assert cfg.od.dodval2.stval2 == 'val'
439     assert cfg.getowner(stval1) == owner
440     assert cfg.getowner(stval2) == owners.default
441     del(cfg.od.dodval1.stval1)
442     assert cfg.od.dodval1.stval1 == 'val'
443     assert cfg.od.dodval2.stval2 == 'val'
444     assert cfg.getowner(stval1) == owners.default
445     assert cfg.getowner(stval2) == owners.default
446
447
448 def test_mandatory_dyndescription_context():
449     val1 = StrOption('val1', '', ['val1', 'val2'], multi=True)
450     st = StrOption('st', '', properties=('mandatory',))
451     dod = DynOptionDescription('dod', '', [st], callback=return_list, callback_params={'': ((val1, False),)})
452     od = OptionDescription('od', '', [dod, val1])
453     od2 = OptionDescription('od', '', [od])
454     cfg = Config(od2)
455     cfg.read_only()
456     raises(PropertiesOptionError, "cfg.od.dodval1.stval1")
457     raises(PropertiesOptionError, "cfg.od.dodval2.stval2")
458     cfg.read_write()
459     cfg.od.dodval1.stval1 = 'val'
460     cfg.read_only()
461     assert cfg.od.dodval1.stval1 == 'val'
462     raises(PropertiesOptionError, "cfg.od.dodval2.stval2")
463     cfg.read_write()
464     del(cfg.od.dodval1.stval1)
465     cfg.read_only()
466     raises(PropertiesOptionError, "cfg.od.dodval1.stval1")
467     assert cfg.cfgimpl_get_values().mandatory_warnings() == ['od.dodval1.stval1', 'od.dodval2.stval2']
468
469
470 def test_increase_dyndescription_context():
471     val1 = StrOption('val1', '', ['val1', 'val2'], multi=True)
472     st = StrOption('st', '', properties=('mandatory',))
473     dod = DynOptionDescription('dod', '', [st], callback=return_list, callback_params={'': ((val1, False),)})
474     od = OptionDescription('od', '', [dod, val1])
475     od2 = OptionDescription('od', '', [od])
476     cfg = Config(od2)
477     cfg.read_write()
478     assert cfg.od.dodval1.stval1 is None
479     assert cfg.od.dodval2.stval2 is None
480     raises(AttributeError, "cfg.od.dodval3")
481     cfg.od.val1 = ['val1', 'val2', 'val3']
482     assert cfg.od.dodval1.stval1 is None
483     assert cfg.od.dodval2.stval2 is None
484     assert cfg.od.dodval3.stval3 is None
485
486
487 def test_decrease_dyndescription_context():
488     val1 = StrOption('val1', '', ['val1', 'val2'], multi=True)
489     st = StrOption('st', '', properties=('mandatory',))
490     dod = DynOptionDescription('dod', '', [st], callback=return_list, callback_params={'': ((val1, False),)})
491     od = OptionDescription('od', '', [dod, val1])
492     od2 = OptionDescription('od', '', [od])
493     cfg = Config(od2)
494     owner = cfg.cfgimpl_get_settings().getowner()
495     stval1 = cfg.unwrap_from_path('od.dodval1.stval1')
496     stval2 = cfg.unwrap_from_path('od.dodval2.stval2')
497     cfg.read_write()
498     assert cfg.od.dodval1.stval1 is None
499     assert cfg.od.dodval2.stval2 is None
500     cfg.od.dodval2.stval2 = 'yes'
501     assert cfg.od.dodval1.stval1 is None
502     assert cfg.od.dodval2.stval2 == 'yes'
503     assert cfg.getowner(stval1) == owners.default
504     assert cfg.getowner(stval2) == owner
505     raises(AttributeError, "cfg.od.dodval3")
506     cfg.od.val1 = ['val1']
507     assert cfg.od.dodval1.stval1 is None
508     raises(AttributeError, "cfg.od.dodval2")
509     raises(AttributeError, "cfg.od.dodval3")
510     assert cfg.getowner(stval1) == owners.default
511     #FIXME
512 #    raises(AttributeError, "cfg.getowner(stval2)")
513     raises(AttributeError, "cfg.unwrap_from_path('od.dodval2.stval2')")
514
515
516 def test_requires_dyndescription():
517     boolean = BoolOption('boolean', '', True)
518     st = StrOption('st', '', requires=[{'option': boolean, 'expected': False,
519                                         'action': 'disabled'}])
520     dod = DynOptionDescription('dod', '', [st], callback=return_list)
521     od = OptionDescription('od', '', [dod])
522     od2 = OptionDescription('od', '', [od, boolean])
523     cfg = Config(od2)
524     cfg.read_write()
525     assert cfg.od.dodval1.stval1 is None
526     assert cfg.od.dodval2.stval2 is None
527     #
528     cfg.boolean = False
529     props = []
530     try:
531         cfg.od.dodval1.stval1
532     except PropertiesOptionError as err:
533         props = err.proptype
534     assert props == ['disabled']
535     props = []
536     try:
537         cfg.od.dodval2.stval2
538     except PropertiesOptionError as err:
539         props = err.proptype
540     assert props == ['disabled']
541     #
542     cfg.boolean = True
543     assert cfg.od.dodval1.stval1 is None
544     assert cfg.od.dodval2.stval2 is None
545     #transitive
546     cfg.cfgimpl_get_settings()[boolean].append('disabled')
547     props = []
548     try:
549         cfg.od.dodval1.stval1
550     except PropertiesOptionError as err:
551         props = err.proptype
552     assert props == ['disabled']
553     props = []
554     try:
555         cfg.od.dodval2.stval2
556     except PropertiesOptionError as err:
557         props = err.proptype
558     assert props == ['disabled']
559
560
561 def test_requires_dyndescription2():
562     boolean = BoolOption('boolean', '', True)
563     st = StrOption('st', '')
564     dod = DynOptionDescription('dod', '', [st], callback=return_list,
565                                requires=[{'option': boolean, 'expected': False,
566                                           'action': 'disabled'}])
567     od = OptionDescription('od', '', [dod])
568     od2 = OptionDescription('od', '', [od, boolean])
569     cfg = Config(od2)
570     cfg.read_write()
571     assert cfg.od.dodval1.stval1 is None
572     assert cfg.od.dodval2.stval2 is None
573     #
574     cfg.boolean = False
575     props = []
576     try:
577         cfg.od.dodval1.stval1
578     except PropertiesOptionError as err:
579         props = err.proptype
580     assert props == ['disabled']
581     props = []
582     try:
583         cfg.od.dodval2.stval2
584     except PropertiesOptionError as err:
585         props = err.proptype
586     assert props == ['disabled']
587     #
588     cfg.boolean = True
589     assert cfg.od.dodval1.stval1 is None
590     assert cfg.od.dodval2.stval2 is None
591     #transitive
592     cfg.cfgimpl_get_settings()[boolean].append('disabled')
593     props = []
594     try:
595         cfg.od.dodval1.stval1
596     except PropertiesOptionError as err:
597         props = err.proptype
598     assert props == ['disabled']
599     props = []
600     try:
601         cfg.od.dodval2.stval2
602     except PropertiesOptionError as err:
603         props = err.proptype
604     assert props == ['disabled']
605
606
607 def test_validator_dyndescription():
608     val1 = StrOption('val1', '', ['val1', 'val2'], multi=True)
609     st = StrOption('st', '', validator=return_true, validator_params={'': ('yes',)}, default='val')
610     dod = DynOptionDescription('dod', '', [st], callback=return_list)
611     od = OptionDescription('od', '', [dod, val1])
612     od2 = OptionDescription('od', '', [od])
613     cfg = Config(od2)
614     assert cfg.od.dodval1.stval1 == 'val'
615     raises(ValueError, "cfg.od.dodval1.stval1 = 'no'")
616     cfg.od.dodval1.stval1 = 'val'
617
618
619 def test_makedict_dyndescription_context():
620     val1 = StrOption('val1', '', ['val1', 'val2'], multi=True)
621     st = StrOption('st', '')
622     dod = DynOptionDescription('dod', '', [st], callback=return_list)
623     od = OptionDescription('od', '', [dod, val1])
624     od2 = OptionDescription('od', '', [od])
625     cfg = Config(od2)
626     cfg.od.dodval1.stval1 = 'yes'
627     assert cfg.make_dict() == {'od.val1': ['val1', 'val2'], 'od.dodval1.stval1': 'yes', 'od.dodval2.stval2': None}
628     assert cfg.make_dict(flatten=True) == {'val1': ['val1', 'val2'], 'stval1': 'yes', 'stval2': None}
629     assert cfg.make_dict(withoption='stval1') == {'od.dodval1.stval1': 'yes'}
630     assert cfg.od.make_dict(withoption='stval1') == {'dodval1.stval1': 'yes'}
631     assert cfg.od.dodval1.make_dict(withoption='stval1') == {'stval1': 'yes'}
632
633
634 def test_find_dyndescription_context():
635     val1 = StrOption('val1', '', ['val1', 'val2'], multi=True)
636     st = StrOption('st', '')
637     dod = DynOptionDescription('dod', '', [st], callback=return_list)
638     od = OptionDescription('od', '', [dod, val1])
639     od2 = OptionDescription('od', '', [od])
640     cfg = Config(od2)
641     cfg.od.dodval1.stval1 = 'yes'
642     assert cfg.find_first(byname='stval1', type_='value') == "yes"
643     assert isinstance(cfg.find_first(byname='stval1', type_='option'), DynSymLinkOption)
644     assert cfg.find(bytype=StrOption, type_='path') == ['od.dodval1.stval1', 'od.dodval2.stval2', 'od.val1']
645     opts = cfg.find(byvalue='yes')
646     assert len(opts) == 1
647     assert isinstance(opts[0], DynSymLinkOption)
648     assert opts[0].impl_getname() == 'stval1'
649
650
651 def test_iter_all_dyndescription_context():
652     val1 = StrOption('val1', '', ['val1', 'val2'], multi=True)
653     st = StrOption('st', '')
654     dod = DynOptionDescription('dod', '', [st], callback=return_list)
655     od = OptionDescription('od', '', [dod, val1])
656     od2 = OptionDescription('od', '', [od])
657     cfg = Config(od2)
658     for it in cfg.iter_all():
659         assert it[0] == 'od'
660         assert str(it[1]) == str(cfg.od)
661     #
662     list_od = []
663     for it in cfg.od.iter_all():
664         list_od.append(it[0])
665     assert list_od == ['dodval1', 'dodval2', 'val1']
666     #
667     list_od = []
668     for it in cfg.od.dodval1:
669         list_od.append(it[0])
670     assert list_od == ['stval1']
671
672
673 def test_information_dyndescription_context():
674     val1 = StrOption('val1', '', ['val1', 'val2'], multi=True)
675     st = StrOption('st', '')
676     dod = DynOptionDescription('dod', '', [st], callback=return_list)
677     od = OptionDescription('od', '', [dod, val1])
678     od2 = OptionDescription('od', '', [od])
679     dod.impl_set_information('testod', 'val1')
680     st.impl_set_information('testst', 'val2')
681     cfg = Config(od2)
682     cfg.impl_set_information('testcfgod', 'val3')
683     assert dod.impl_get_information('testod') == 'val1'
684     assert st.impl_get_information('testst') == 'val2'
685     assert cfg.impl_get_information('testcfgod') == 'val3'
686
687
688 def test_consistency_dyndescription():
689     st = StrOption('st', '')
690     st2 = StrOption('st2', '')
691     dod = DynOptionDescription('dod', '', [st, st2], callback=return_list)
692     od = OptionDescription('od', '', [dod])
693     st.impl_add_consistency('not_equal', st2)
694     od2 = OptionDescription('od', '', [od])
695     cfg = Config(od2)
696     cfg.od.dodval1.stval1 = 'yes'
697     raises(ValueError, "cfg.od.dodval1.st2val1 = 'yes'")
698     cfg.od.dodval2.stval2 = 'yes'
699     raises(ValueError, "cfg.od.dodval2.st2val2 = 'yes'")
700     raises(ValueError, "cfg.od.dodval1.st2val1 = 'yes'")
701     del(cfg.od.dodval2.stval2)
702     raises(ValueError, "cfg.od.dodval1.st2val1 = 'yes'")
703     cfg.od.dodval2.st2val2 = 'yes'
704     raises(ValueError, "cfg.od.dodval2.stval2 = 'yes'")
705
706
707 def test_consistency_external_dyndescription():
708     st = StrOption('st', '')
709     st1 = StrOption('st1', '')
710     st2 = StrOption('st2', '')
711     dod = DynOptionDescription('dod', '', [st1, st2], callback=return_list)
712     od = OptionDescription('od', '', [dod, st])
713     raises(ConfigError, "st.impl_add_consistency('not_equal', st2)")
714
715
716 def test_consistency_notsame_dyndescription():
717     st1 = StrOption('st1', '')
718     st2 = StrOption('st2', '')
719     dod = DynOptionDescription('dod', '', [st1, st2], callback=return_list)
720     tst1 = StrOption('tst1', '')
721     tst2 = StrOption('tst2', '')
722     tdod = DynOptionDescription('tdod', '', [tst1, tst2], callback=return_list)
723     od = OptionDescription('od', '', [dod, tdod])
724     raises(ConfigError, "st1.impl_add_consistency('not_equal', tst1)")
725
726
727 def test_all_dyndescription():
728     st = StrOption('st', '')
729     ip = IPOption('ip', '')
730     network = NetworkOption('network', '')
731     netmask = NetmaskOption('netmask', '')
732     ch = ChoiceOption('ch', '', ('val1', 'val2', 'val3'))
733     ch1 = ChoiceOption('ch1', '', return_list)
734     boo = BoolOption('boo', '')
735     intr = IntOption('intr', '')
736     floa = FloatOption('floa', '')
737     uni = UnicodeOption('uni', '')
738     port = PortOption('port', '')
739     broad = BroadcastOption('broad', '')
740     domain = DomainnameOption('domain', '')
741     email = EmailOption('email', '')
742     url = URLOption('url', '')
743     username = UsernameOption('username', '')
744     filename = FilenameOption('filename', '')
745     dod = DynOptionDescription('dod', '', [st, ip, network, netmask, ch, ch1,
746                                            boo, intr, floa, uni, port, broad,
747                                            domain, email, url, username,
748                                            filename], callback=return_list)
749     od = OptionDescription('od', '', [dod])
750     cfg = Config(od)
751     assert cfg.dodval1.stval1 is None
752     assert cfg.dodval1.ipval1 is None
753     assert cfg.dodval1.networkval1 is None
754     assert cfg.dodval1.netmaskval1 is None
755     assert cfg.dodval1.chval1 is None
756     assert cfg.dodval1.ch1val1 is None
757     assert cfg.dodval1.booval1 is None
758     assert cfg.dodval1.intrval1 is None
759     assert cfg.dodval1.floaval1 is None
760     assert cfg.dodval1.unival1 is None
761     assert cfg.dodval1.portval1 is None
762     assert cfg.dodval1.broadval1 is None
763     assert cfg.dodval1.domainval1 is None
764     assert cfg.dodval1.emailval1 is None
765     assert cfg.dodval1.urlval1 is None
766     assert cfg.dodval1.usernameval1 is None
767     assert cfg.dodval1.filenameval1 is None
768     #
769     cfg.dodval1.stval1 = "no"
770     cfg.dodval1.ipval1 = "1.1.1.1"
771     cfg.dodval1.networkval1 = "1.1.1.0"
772     cfg.dodval1.netmaskval1 = "255.255.255.0"
773     cfg.dodval1.chval1 = "val1"
774     cfg.dodval1.ch1val1 = "val2"
775     cfg.dodval1.booval1 = True
776     cfg.dodval1.intrval1 = 1
777     cfg.dodval1.floaval1 = 0.1
778     cfg.dodval1.unival1 = u"no"
779     cfg.dodval1.portval1 = 80
780     cfg.dodval1.broadval1 = "1.1.1.255"
781     cfg.dodval1.domainval1 = "test.com"
782     cfg.dodval1.emailval1 = "test@test.com"
783     cfg.dodval1.urlval1 = "http://test.com"
784     cfg.dodval1.usernameval1 = "user1"
785     cfg.dodval1.filenameval1 = "/tmp"
786     assert cfg.dodval1.stval1 == "no"
787     assert cfg.dodval1.ipval1 == "1.1.1.1"
788     assert cfg.dodval1.networkval1 == "1.1.1.0"
789     assert cfg.dodval1.netmaskval1 == "255.255.255.0"
790     assert cfg.dodval1.chval1 == "val1"
791     assert cfg.dodval1.ch1val1 == "val2"
792     assert cfg.dodval1.booval1 is True
793     assert cfg.dodval1.intrval1 == 1
794     assert cfg.dodval1.floaval1 == 0.1
795     assert cfg.dodval1.unival1 == u"no"
796     assert cfg.dodval1.portval1 == 80
797     assert cfg.dodval1.broadval1 == "1.1.1.255"
798     assert cfg.dodval1.domainval1 == "test.com"
799     assert cfg.dodval1.emailval1 == "test@test.com"
800     assert cfg.dodval1.urlval1 == "http://test.com"
801     assert cfg.dodval1.usernameval1 == "user1"
802     assert cfg.dodval1.filenameval1 == "/tmp"
803     #
804     assert cfg.dodval2.stval2 is None
805     assert cfg.dodval2.ipval2 is None
806     assert cfg.dodval2.networkval2 is None
807     assert cfg.dodval2.netmaskval2 is None
808     assert cfg.dodval2.chval2 is None
809     assert cfg.dodval2.ch1val2 is None
810     assert cfg.dodval2.booval2 is None
811     assert cfg.dodval2.intrval2 is None
812     assert cfg.dodval2.floaval2 is None
813     assert cfg.dodval2.unival2 is None
814     assert cfg.dodval2.portval2 is None
815     assert cfg.dodval2.broadval2 is None
816     assert cfg.dodval2.domainval2 is None
817     assert cfg.dodval2.emailval2 is None
818     assert cfg.dodval2.urlval2 is None
819     assert cfg.dodval2.usernameval2 is None
820     assert cfg.dodval2.filenameval2 is None
821
822
823 def test_consistency_ip_netmask_dyndescription():
824     a = IPOption('a', '')
825     b = NetmaskOption('b', '')
826     dod = DynOptionDescription('dod', '', [a, b], callback=return_list)
827     b.impl_add_consistency('ip_netmask', a)
828     od = OptionDescription('od', '', [dod])
829     c = Config(od)
830     c.dodval1.aval1 = '192.168.1.1'
831     c.dodval1.bval1 = '255.255.255.0'
832     c.dodval2.aval2 = '192.168.1.2'
833     c.dodval2.bval2 = '255.255.255.255'
834     c.dodval2.bval2 = '255.255.255.0'
835
836
837 def test_consistency_ip_in_network_dyndescription():
838     a = NetworkOption('a', '')
839     b = NetmaskOption('b', '')
840     c = IPOption('c', '')
841     dod = DynOptionDescription('dod', '', [a, b, c], callback=return_list)
842     c.impl_add_consistency('in_network', a, b)
843     od = OptionDescription('od', '', [dod])
844     cfg = Config(od)
845     cfg.dodval1.aval1 = '192.168.1.0'
846     cfg.dodval1.bval1 = '255.255.255.0'
847     cfg.dodval1.cval1 = '192.168.1.1'
848
849
850 def test_masterslaves_dyndescription():
851     st1 = StrOption('st1', "", multi=True)
852     st2 = StrOption('st2', "", multi=True)
853     stm = OptionDescription('st1', '', [st1, st2])
854     stm.impl_set_group_type(groups.master)
855     st = DynOptionDescription('st', '', [stm], callback=return_list)
856     od = OptionDescription('od', '', [st])
857     od2 = OptionDescription('od', '', [od])
858     cfg = Config(od2)
859     owner = cfg.cfgimpl_get_settings().getowner()
860     st1val1 = cfg.unwrap_from_path('od.stval1.st1val1.st1val1')
861     st2val1 = cfg.unwrap_from_path('od.stval1.st1val1.st2val1')
862     st1val2 = cfg.unwrap_from_path('od.stval2.st1val2.st1val2')
863     st2val2 = cfg.unwrap_from_path('od.stval2.st1val2.st2val2')
864     assert cfg.make_dict() == {'od.stval1.st1val1.st2val1': [], 'od.stval2.st1val2.st2val2': [], 'od.stval2.st1val2.st1val2': [], 'od.stval1.st1val1.st1val1': []}
865     assert cfg.od.stval1.st1val1.st1val1 == []
866     assert cfg.od.stval1.st1val1.st2val1 == []
867     assert cfg.od.stval2.st1val2.st1val2 == []
868     assert cfg.od.stval2.st1val2.st2val2 == []
869     assert cfg.getowner(st1val1) == owners.default
870     assert cfg.getowner(st1val2) == owners.default
871     assert cfg.getowner(st2val1) == owners.default
872     assert cfg.getowner(st2val2) == owners.default
873     #
874     cfg.od.stval1.st1val1.st1val1.append('yes')
875     assert cfg.make_dict() == {'od.stval1.st1val1.st2val1': [None], 'od.stval2.st1val2.st2val2': [], 'od.stval2.st1val2.st1val2': [], 'od.stval1.st1val1.st1val1': ['yes']}
876     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
877     assert cfg.od.stval1.st1val1.st2val1 == [None]
878     assert cfg.od.stval2.st1val2.st1val2 == []
879     assert cfg.od.stval2.st1val2.st2val2 == []
880     assert cfg.getowner(st1val1) == owner
881     assert cfg.getowner(st1val2) == owners.default
882     assert cfg.getowner(st2val1) == owners.default
883     assert cfg.getowner(st2val2) == owners.default
884     #
885     cfg.od.stval1.st1val1.st1val1 = ['yes']
886     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
887     assert cfg.od.stval1.st1val1.st2val1 == [None]
888     assert cfg.od.stval2.st1val2.st1val2 == []
889     assert cfg.od.stval2.st1val2.st2val2 == []
890     assert cfg.getowner(st1val1) == owner
891     assert cfg.getowner(st1val2) == owners.default
892     assert cfg.getowner(st2val1) == owners.default
893     assert cfg.getowner(st2val2) == owners.default
894     #
895     cfg.od.stval1.st1val1.st2val1 = ['no']
896     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
897     assert cfg.od.stval1.st1val1.st2val1 == ['no']
898     assert cfg.od.stval2.st1val2.st1val2 == []
899     assert cfg.od.stval2.st1val2.st2val2 == []
900     assert cfg.getowner(st1val1) == owner
901     assert cfg.getowner(st1val2) == owners.default
902     assert cfg.getowner(st2val1) == owner
903     assert cfg.getowner(st2val2) == owners.default
904     #
905     cfg.od.stval1.st1val1.st1val1.pop(0)
906     assert cfg.od.stval1.st1val1.st1val1 == []
907     assert cfg.od.stval1.st1val1.st2val1 == []
908     assert cfg.od.stval2.st1val2.st1val2 == []
909     assert cfg.od.stval2.st1val2.st2val2 == []
910     assert cfg.getowner(st1val1) == owner
911     assert cfg.getowner(st1val2) == owners.default
912     assert cfg.getowner(st2val1) == owner
913     assert cfg.getowner(st2val2) == owners.default
914     #
915     cfg.od.stval1.st1val1.st1val1 = ['yes']
916     cfg.od.stval1.st1val1.st2val1 = ['yes']
917     assert cfg.getowner(st1val1) == owner
918     assert cfg.getowner(st2val1) == owner
919     del(cfg.od.stval1.st1val1.st2val1)
920     assert cfg.getowner(st1val1) == owner
921     assert cfg.getowner(st1val2) == owners.default
922     assert cfg.getowner(st2val1) == owners.default
923     assert cfg.getowner(st2val2) == owners.default
924     #
925     cfg.od.stval1.st1val1.st1val1 = ['yes']
926     cfg.od.stval1.st1val1.st2val1 = ['yes']
927     del(cfg.od.stval1.st1val1.st1val1)
928     assert cfg.od.stval1.st1val1.st1val1 == []
929     assert cfg.od.stval1.st1val1.st2val1 == []
930     assert cfg.od.stval2.st1val2.st1val2 == []
931     assert cfg.od.stval2.st1val2.st2val2 == []
932     assert cfg.getowner(st1val1) == owners.default
933     assert cfg.getowner(st1val2) == owners.default
934     assert cfg.getowner(st2val1) == owners.default
935     assert cfg.getowner(st2val2) == owners.default
936
937
938 def test_masterslaves_default_multi_dyndescription():
939     st1 = StrOption('st1', "", multi=True)
940     st2 = StrOption('st2', "", multi=True, default_multi='no')
941     stm = OptionDescription('st1', '', [st1, st2])
942     stm.impl_set_group_type(groups.master)
943     st = DynOptionDescription('st', '', [stm], callback=return_list)
944     od = OptionDescription('od', '', [st])
945     od2 = OptionDescription('od', '', [od])
946     cfg = Config(od2)
947     owner = cfg.cfgimpl_get_settings().getowner()
948     st1val1 = cfg.unwrap_from_path('od.stval1.st1val1.st1val1')
949     st2val1 = cfg.unwrap_from_path('od.stval1.st1val1.st2val1')
950     st1val2 = cfg.unwrap_from_path('od.stval2.st1val2.st1val2')
951     st2val2 = cfg.unwrap_from_path('od.stval2.st1val2.st2val2')
952     assert cfg.od.stval1.st1val1.st1val1 == []
953     assert cfg.od.stval1.st1val1.st2val1 == []
954     assert cfg.od.stval2.st1val2.st1val2 == []
955     assert cfg.od.stval2.st1val2.st2val2 == []
956     assert cfg.getowner(st1val1) == owners.default
957     assert cfg.getowner(st1val2) == owners.default
958     assert cfg.getowner(st2val1) == owners.default
959     assert cfg.getowner(st2val2) == owners.default
960     cfg.od.stval1.st1val1.st1val1.append('yes')
961     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
962     assert cfg.od.stval1.st1val1.st2val1 == ['no']
963     assert cfg.od.stval2.st1val2.st1val2 == []
964     assert cfg.od.stval2.st1val2.st2val2 == []
965     assert cfg.getowner(st1val1) == owner
966     assert cfg.getowner(st1val2) == owners.default
967     assert cfg.getowner(st2val1) == owners.default
968     assert cfg.getowner(st2val2) == owners.default
969
970
971 def test_masterslaves_submulti_dyndescription():
972     st1 = StrOption('st1', "", multi=True)
973     st2 = StrOption('st2', "", multi=submulti)
974     stm = OptionDescription('st1', '', [st1, st2])
975     stm.impl_set_group_type(groups.master)
976     st = DynOptionDescription('st', '', [stm], callback=return_list)
977     od = OptionDescription('od', '', [st])
978     od2 = OptionDescription('od', '', [od])
979     cfg = Config(od2)
980     owner = cfg.cfgimpl_get_settings().getowner()
981     st1val1 = cfg.unwrap_from_path('od.stval1.st1val1.st1val1')
982     st2val1 = cfg.unwrap_from_path('od.stval1.st1val1.st2val1')
983     st1val2 = cfg.unwrap_from_path('od.stval2.st1val2.st1val2')
984     st2val2 = cfg.unwrap_from_path('od.stval2.st1val2.st2val2')
985     assert cfg.od.stval1.st1val1.st1val1 == []
986     assert cfg.od.stval1.st1val1.st2val1 == []
987     assert cfg.od.stval2.st1val2.st1val2 == []
988     assert cfg.od.stval2.st1val2.st2val2 == []
989     assert cfg.getowner(st1val1) == owners.default
990     assert cfg.getowner(st1val2) == owners.default
991     assert cfg.getowner(st2val1) == owners.default
992     assert cfg.getowner(st2val2) == owners.default
993     cfg.od.stval1.st1val1.st1val1.append('yes')
994     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
995     assert cfg.od.stval1.st1val1.st2val1 == [[]]
996     assert cfg.od.stval2.st1val2.st1val2 == []
997     assert cfg.od.stval2.st1val2.st2val2 == []
998     assert cfg.getowner(st1val1) == owner
999     assert cfg.getowner(st1val2) == owners.default
1000     assert cfg.getowner(st2val1) == owners.default
1001     assert cfg.getowner(st2val2) == owners.default
1002     #
1003     cfg.od.stval1.st1val1.st2val1[0].append('no')
1004     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
1005     assert cfg.od.stval1.st1val1.st2val1 == [['no']]
1006     assert cfg.od.stval2.st1val2.st1val2 == []
1007     assert cfg.od.stval2.st1val2.st2val2 == []
1008     assert cfg.getowner(st1val1) == owner
1009     assert cfg.getowner(st1val2) == owners.default
1010     assert cfg.getowner(st2val1) == owner
1011     assert cfg.getowner(st2val2) == owners.default
1012
1013
1014 def test_masterslaves_consistency_ip_dyndescription():
1015     a = NetworkOption('net', '', multi=True)
1016     b = NetmaskOption('mask', '', multi=True)
1017     c = BroadcastOption('broad', '', multi=True)
1018     b.impl_add_consistency('network_netmask', a)
1019     c.impl_add_consistency('broadcast', a, b)
1020     dod = DynOptionDescription('net', '', [a, b, c], callback=return_list)
1021     dod.impl_set_group_type(groups.master)
1022     od = OptionDescription('od', '', [dod])
1023     cfg = Config(od)
1024     cfg.netval1.netval1 = ['192.168.1.0']
1025     cfg.netval1.maskval1 = ['255.255.255.0']
1026     cfg.netval1.broadval1 = ['192.168.1.255']
1027
1028     cfg.netval1.netval1 = ['192.168.1.0', '192.168.2.128']
1029     cfg.netval1.maskval1 = ['255.255.255.0', '255.255.255.128']
1030     cfg.netval1.broadval1 = ['192.168.1.255', '192.168.2.255']
1031     cfg.netval1.broadval1[1] = '192.168.2.255'
1032     #
1033     assert cfg.netval1.netval1 == ['192.168.1.0', '192.168.2.128']
1034     assert cfg.netval1.maskval1 == ['255.255.255.0', '255.255.255.128']
1035     assert cfg.netval1.broadval1 == ['192.168.1.255', '192.168.2.255']
1036     assert cfg.netval2.netval2 == []
1037     assert cfg.netval2.maskval2 == []
1038     assert cfg.netval2.broadval2 == []
1039
1040
1041 def test_masterslaves_callback_dyndescription():
1042     st1 = StrOption('st1', "", multi=True)
1043     st2 = StrOption('st2', "", multi=True, callback=return_dynval, callback_params={'value': ((st1, False),)})
1044     stm = OptionDescription('st1', '', [st1, st2])
1045     stm.impl_set_group_type(groups.master)
1046     st = DynOptionDescription('st', '', [stm], callback=return_list)
1047     od = OptionDescription('od', '', [st])
1048     od2 = OptionDescription('od', '', [od])
1049     cfg = Config(od2)
1050     owner = cfg.cfgimpl_get_settings().getowner()
1051     st1val1 = cfg.unwrap_from_path('od.stval1.st1val1.st1val1')
1052     st2val1 = cfg.unwrap_from_path('od.stval1.st1val1.st2val1')
1053     st1val2 = cfg.unwrap_from_path('od.stval2.st1val2.st1val2')
1054     st2val2 = cfg.unwrap_from_path('od.stval2.st1val2.st2val2')
1055     assert cfg.make_dict() == {'od.stval1.st1val1.st2val1': [], 'od.stval2.st1val2.st2val2': [], 'od.stval2.st1val2.st1val2': [], 'od.stval1.st1val1.st1val1': []}
1056     assert cfg.od.stval1.st1val1.st1val1 == []
1057     assert cfg.od.stval1.st1val1.st2val1 == []
1058     assert cfg.od.stval2.st1val2.st1val2 == []
1059     assert cfg.od.stval2.st1val2.st2val2 == []
1060     assert cfg.getowner(st1val1) == owners.default
1061     assert cfg.getowner(st1val2) == owners.default
1062     assert cfg.getowner(st2val1) == owners.default
1063     assert cfg.getowner(st2val2) == owners.default
1064     #
1065     cfg.od.stval1.st1val1.st1val1.append('yes')
1066     assert cfg.make_dict() == {'od.stval1.st1val1.st2val1': ['yes'], 'od.stval2.st1val2.st2val2': [], 'od.stval2.st1val2.st1val2': [], 'od.stval1.st1val1.st1val1': ['yes']}
1067     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
1068     assert cfg.od.stval1.st1val1.st2val1 == ['yes']
1069     assert cfg.od.stval2.st1val2.st1val2 == []
1070     assert cfg.od.stval2.st1val2.st2val2 == []
1071     assert cfg.getowner(st1val1) == owner
1072     assert cfg.getowner(st1val2) == owners.default
1073     assert cfg.getowner(st2val1) == owners.default
1074     assert cfg.getowner(st2val2) == owners.default
1075     #
1076     cfg.od.stval1.st1val1.st2val1 = ['no']
1077     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
1078     assert cfg.od.stval1.st1val1.st2val1 == ['no']
1079     assert cfg.od.stval2.st1val2.st1val2 == []
1080     assert cfg.od.stval2.st1val2.st2val2 == []
1081     assert cfg.getowner(st1val1) == owner
1082     assert cfg.getowner(st1val2) == owners.default
1083     assert cfg.getowner(st2val1) == owner
1084     assert cfg.getowner(st2val2) == owners.default
1085     #
1086     cfg.od.stval1.st1val1.st1val1.pop(0)
1087     assert cfg.od.stval1.st1val1.st1val1 == []
1088     assert cfg.od.stval1.st1val1.st2val1 == []
1089     assert cfg.od.stval2.st1val2.st1val2 == []
1090     assert cfg.od.stval2.st1val2.st2val2 == []
1091     assert cfg.getowner(st1val1) == owner
1092     assert cfg.getowner(st1val2) == owners.default
1093     assert cfg.getowner(st2val1) == owner
1094     assert cfg.getowner(st2val2) == owners.default
1095     #
1096     cfg.od.stval1.st1val1.st1val1 = ['yes']
1097     cfg.od.stval1.st1val1.st2val1 = ['yes']
1098     assert cfg.getowner(st1val1) == owner
1099     assert cfg.getowner(st2val1) == owner
1100     del(cfg.od.stval1.st1val1.st2val1)
1101     assert cfg.getowner(st1val1) == owner
1102     assert cfg.getowner(st1val2) == owners.default
1103     assert cfg.getowner(st2val1) == owners.default
1104     assert cfg.getowner(st2val2) == owners.default
1105     #
1106     cfg.od.stval1.st1val1.st1val1 = ['yes']
1107     cfg.od.stval1.st1val1.st2val1 = ['yes']
1108     del(cfg.od.stval1.st1val1.st1val1)
1109     assert cfg.od.stval1.st1val1.st1val1 == []
1110     assert cfg.od.stval1.st1val1.st2val1 == []
1111     assert cfg.od.stval2.st1val2.st1val2 == []
1112     assert cfg.od.stval2.st1val2.st2val2 == []
1113     assert cfg.getowner(st1val1) == owners.default
1114     assert cfg.getowner(st1val2) == owners.default
1115     assert cfg.getowner(st2val1) == owners.default
1116     assert cfg.getowner(st2val2) == owners.default
1117     #
1118     cfg.od.stval1.st1val1.st2val1 = []
1119     cfg.od.stval1.st1val1.st1val1 = ['yes']
1120     assert cfg.od.stval1.st1val1.st2val1 == ['yes']
1121
1122
1123 def test_masterslaves_callback_value_dyndescription():
1124     st1 = StrOption('st1', "", multi=True)
1125     st2 = StrOption('st2', "", multi=True, callback=return_dynval, callback_params={'value': ('val',)})
1126     stm = OptionDescription('st1', '', [st1, st2])
1127     stm.impl_set_group_type(groups.master)
1128     st = DynOptionDescription('st', '', [stm], callback=return_list)
1129     od = OptionDescription('od', '', [st])
1130     od2 = OptionDescription('od', '', [od])
1131     cfg = Config(od2)
1132     assert cfg.od.stval1.st1val1.st1val1 == []
1133     assert cfg.od.stval1.st1val1.st2val1 == []
1134     cfg.od.stval1.st1val1.st1val1.append('yes')
1135     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
1136     assert cfg.od.stval1.st1val1.st2val1[0] == 'val'
1137     assert cfg.od.stval1.st1val1.st2val1 == ['val']
1138
1139
1140 def test_masterslaves_callback_nomulti_dyndescription():
1141     v1 = StrOption('v1', '', "val")
1142     st1 = StrOption('st1', "", multi=True)
1143     st2 = StrOption('st2', "", multi=True, callback=return_dynval, callback_params={'': ((v1, False),)})
1144     stm = OptionDescription('st1', '', [st1, st2])
1145     stm.impl_set_group_type(groups.master)
1146     st = DynOptionDescription('st', '', [stm], callback=return_list)
1147     od = OptionDescription('od', '', [st])
1148     od2 = OptionDescription('od', '', [od, v1])
1149     cfg = Config(od2)
1150     assert cfg.od.stval1.st1val1.st1val1 == []
1151     assert cfg.od.stval1.st1val1.st2val1 == []
1152     cfg.od.stval1.st1val1.st1val1.append('yes')
1153     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
1154     assert cfg.od.stval1.st1val1.st2val1 == ['val']
1155
1156
1157 def test_masterslaves_callback_multi_dyndescription():
1158     v1 = StrOption('v1', '', multi=True)
1159     st1 = StrOption('st1', "", multi=True)
1160     st2 = StrOption('st2', "", multi=True, callback=return_dynval, callback_params={'': ((v1, False),)})
1161     stm = OptionDescription('st1', '', [st1, st2])
1162     stm.impl_set_group_type(groups.master)
1163     st = DynOptionDescription('st', '', [stm], callback=return_list)
1164     od = OptionDescription('od', '', [st])
1165     od2 = OptionDescription('od', '', [od, v1])
1166     cfg = Config(od2)
1167     assert cfg.od.stval1.st1val1.st1val1 == []
1168     assert cfg.od.stval1.st1val1.st2val1 == []
1169     cfg.od.stval1.st1val1.st1val1.append('yes')
1170     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
1171     assert cfg.od.stval1.st1val1.st2val1 == [None]
1172     cfg.od.stval1.st1val1.st2val1 = ['no']
1173     cfg.v1 = ['no', 'no', 'no']
1174     cfg.od.stval1.st1val1.st1val1.append('yes')
1175     assert cfg.od.stval1.st1val1.st1val1 == ['yes', 'yes']
1176     assert cfg.od.stval1.st1val1.st2val1 == ['no', 'no']
1177     cfg.od.stval1.st1val1.st1val1.pop(1)
1178     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
1179     assert cfg.od.stval1.st1val1.st2val1 == ['no']
1180
1181
1182 def test_masterslaves_callback_samegroup_dyndescription():
1183     st1 = StrOption('st1', "", multi=True)
1184     st2 = StrOption('st2', "", multi=True)
1185     st3 = StrOption('st3', "", multi=True, callback=return_dynval, callback_params={'': ((st2, False),)})
1186     stm = OptionDescription('st1', '', [st1, st2, st3])
1187     stm.impl_set_group_type(groups.master)
1188     st = DynOptionDescription('st', '', [stm], callback=return_list)
1189     od = OptionDescription('od', '', [st])
1190     od2 = OptionDescription('od', '', [od])
1191     cfg = Config(od2)
1192     owner = cfg.cfgimpl_get_settings().getowner()
1193     st1val1 = cfg.unwrap_from_path('od.stval1.st1val1.st1val1')
1194     st2val1 = cfg.unwrap_from_path('od.stval1.st1val1.st2val1')
1195     st3val1 = cfg.unwrap_from_path('od.stval1.st1val1.st3val1')
1196     st1val2 = cfg.unwrap_from_path('od.stval2.st1val2.st1val2')
1197     st2val2 = cfg.unwrap_from_path('od.stval2.st1val2.st2val2')
1198     st3val2 = cfg.unwrap_from_path('od.stval2.st1val2.st3val2')
1199     assert cfg.make_dict() == {'od.stval1.st1val1.st1val1': [],
1200                                'od.stval1.st1val1.st2val1': [],
1201                                'od.stval1.st1val1.st3val1': [],
1202                                'od.stval2.st1val2.st1val2': [],
1203                                'od.stval2.st1val2.st2val2': [],
1204                                'od.stval2.st1val2.st3val2': []}
1205     assert cfg.od.stval1.st1val1.st1val1 == []
1206     assert cfg.od.stval1.st1val1.st2val1 == []
1207     assert cfg.od.stval1.st1val1.st3val1 == []
1208     assert cfg.od.stval2.st1val2.st1val2 == []
1209     assert cfg.od.stval2.st1val2.st2val2 == []
1210     assert cfg.od.stval2.st1val2.st3val2 == []
1211     assert cfg.getowner(st1val1) == owners.default
1212     assert cfg.getowner(st1val2) == owners.default
1213     assert cfg.getowner(st2val1) == owners.default
1214     assert cfg.getowner(st2val2) == owners.default
1215     assert cfg.getowner(st3val1) == owners.default
1216     assert cfg.getowner(st3val2) == owners.default
1217     ##
1218     cfg.od.stval1.st1val1.st1val1.append('yes')
1219     assert cfg.make_dict() == {'od.stval1.st1val1.st1val1': ['yes'],
1220                                'od.stval1.st1val1.st2val1': [None],
1221                                'od.stval1.st1val1.st3val1': [None],
1222                                'od.stval2.st1val2.st1val2': [],
1223                                'od.stval2.st1val2.st2val2': [],
1224                                'od.stval2.st1val2.st3val2': []}
1225     assert cfg.getowner(st1val1) == owner
1226     assert cfg.getowner(st1val2) == owners.default
1227     assert cfg.getowner(st2val1) == owners.default
1228     assert cfg.getowner(st2val2) == owners.default
1229     assert cfg.getowner(st3val1) == owners.default
1230     assert cfg.getowner(st3val2) == owners.default
1231     #
1232     cfg.od.stval1.st1val1.st2val1[0] = 'yes'
1233     assert cfg.make_dict() == {'od.stval1.st1val1.st1val1': ['yes'],
1234                                'od.stval1.st1val1.st2val1': ['yes'],
1235                                'od.stval1.st1val1.st3val1': ['yes'],
1236                                'od.stval2.st1val2.st1val2': [],
1237                                'od.stval2.st1val2.st2val2': [],
1238                                'od.stval2.st1val2.st3val2': []}
1239     assert cfg.getowner(st1val1) == owner
1240     assert cfg.getowner(st1val2) == owners.default
1241     assert cfg.getowner(st2val1) == owner
1242     assert cfg.getowner(st2val2) == owners.default
1243     assert cfg.getowner(st3val1) == owners.default
1244     assert cfg.getowner(st3val2) == owners.default
1245
1246
1247 def test_state_config():
1248     a = IPOption('a', '')
1249     b = NetmaskOption('b', '')
1250     dod1 = DynOptionDescription('dod1', '', [a, b], callback=return_list)
1251     b.impl_add_consistency('ip_netmask', a)
1252     od1 = OptionDescription('od1', '', [dod1])
1253     st1 = StrOption('st1', "", multi=True)
1254     st2 = StrOption('st2', "", multi=True)
1255     st3 = StrOption('st3', "", multi=True, callback=return_dynval, callback_params={'': ((st2, False),)})
1256     stm = OptionDescription('st1', '', [st1, st2, st3])
1257     stm.impl_set_group_type(groups.master)
1258     st = DynOptionDescription('st', '', [stm], callback=return_list)
1259     od = OptionDescription('od', '', [st])
1260     od2 = OptionDescription('od', '', [od, od1])
1261     try:
1262         cfg = Config(od2, persistent=True, session_id='29090938')
1263     except ValueError:
1264         cfg = Config(od2, session_id='29090938')
1265         cfg._impl_test = True
1266     a = dumps(cfg)
1267     q = loads(a)
1268     _diff_opts(cfg.cfgimpl_get_description(), q.cfgimpl_get_description())
1269     _diff_conf(cfg, q)
1270
1271     try:
1272         delete_session('config', '29090938')
1273     except ConfigError:
1274         pass
1275
1276
1277 def test_invalid_conflict_dyndescription():
1278     st = StrOption('st', '')
1279     dod = DynOptionDescription('dod', '', [st], callback=return_list)
1280     dodinvalid = StrOption('dodinvalid', '')
1281     raises(ConflictError, "OptionDescription('od', '', [dod, dodinvalid])")
1282
1283
1284 def test_invalid_subod_dyndescription():
1285     st2 = StrOption('st2', '')
1286     od1 = OptionDescription('od1', '', [st2])
1287     raises(ConfigError, "DynOptionDescription('dod', '', [od1], callback=return_list)")
1288
1289
1290 def test_invalid_subdynod_dyndescription():
1291     st2 = StrOption('st2', '')
1292     od1 = DynOptionDescription('od1', '', [st2], callback=return_list)
1293     raises(ConfigError, "DynOptionDescription('dod', '', [od1], callback=return_list)")
1294
1295
1296 def test_invalid_symlink_dyndescription():
1297     st = StrOption('st', '')
1298     st2 = SymLinkOption('st2', st)
1299     raises(ConfigError, "DynOptionDescription('dod', '', [st, st2], callback=return_list)")
1300
1301
1302 def test_nocallback_dyndescription():
1303     st = StrOption('st', '')
1304     st2 = StrOption('st2', '')
1305     raises(ConfigError, "DynOptionDescription('dod', '', [st, st2])")
1306
1307
1308 def test_invalid_samevalue_dyndescription():
1309     st = StrOption('st', '')
1310     dod = DynOptionDescription('dod', '', [st], callback=return_same_list)
1311     od = OptionDescription('od', '', [dod])
1312     cfg = Config(od)
1313     raises(ConfigError, "print cfg")
1314
1315
1316 def test_invalid_name_dyndescription():
1317     st = StrOption('st', '')
1318     dod = DynOptionDescription('dod', '', [st], callback=return_wrong_list)
1319     od = OptionDescription('od', '', [dod])
1320     cfg = Config(od)
1321     raises(ValueError, "print cfg")