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