python 3.5 support
[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_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, suffix=None):
21     if value == 'val' and param in [None, 'yes']:
22         return
23     raise ValueError('no value')
24
25
26 def return_dynval(value='val', suffix=None):
27     return value
28
29
30 def return_list2(suffix):
31     return [str(suffix), 'val2']
32
33
34 def return_list(val=None, suffix=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']), str(['test2', 'test'])]
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 list(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']), str(['test2', 'test'])]
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 list(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     raises(AttributeError, "cfg.find(byname='strnotexists')")
650     assert len(opts) == 1
651     assert isinstance(opts[0], DynSymLinkOption)
652     assert opts[0].impl_getname() == 'stval1'
653
654
655 def test_iter_all_dyndescription_context():
656     val1 = StrOption('val1', '', ['val1', 'val2'], multi=True)
657     st = StrOption('st', '')
658     dod = DynOptionDescription('dod', '', [st], callback=return_list)
659     od = OptionDescription('od', '', [dod, val1])
660     od2 = OptionDescription('od', '', [od])
661     cfg = Config(od2)
662     for it in cfg.iter_all():
663         assert it[0] == 'od'
664         assert str(it[1]) == str(cfg.od)
665     #
666     list_od = []
667     for it in cfg.od.iter_all():
668         list_od.append(it[0])
669     assert list_od == ['dodval1', 'dodval2', 'val1']
670     #
671     list_od = []
672     for it in cfg.od.dodval1:
673         list_od.append(it[0])
674     assert list_od == ['stval1']
675
676
677 def test_information_dyndescription_context():
678     val1 = StrOption('val1', '', ['val1', 'val2'], multi=True)
679     st = StrOption('st', '')
680     dod = DynOptionDescription('dod', '', [st], callback=return_list)
681     od = OptionDescription('od', '', [dod, val1])
682     od2 = OptionDescription('od', '', [od])
683     dod.impl_set_information('testod', 'val1')
684     st.impl_set_information('testst', 'val2')
685     cfg = Config(od2)
686     cfg.impl_set_information('testcfgod', 'val3')
687     assert dod.impl_get_information('testod') == 'val1'
688     assert st.impl_get_information('testst') == 'val2'
689     assert cfg.impl_get_information('testcfgod') == 'val3'
690
691
692 def test_consistency_dyndescription():
693     st = StrOption('st', '')
694     st2 = StrOption('st2', '')
695     dod = DynOptionDescription('dod', '', [st, st2], callback=return_list)
696     od = OptionDescription('od', '', [dod])
697     st.impl_add_consistency('not_equal', st2)
698     od2 = OptionDescription('od', '', [od])
699     cfg = Config(od2)
700     cfg.od.dodval1.stval1 = 'yes'
701     raises(ValueError, "cfg.od.dodval1.st2val1 = 'yes'")
702     cfg.od.dodval2.stval2 = 'yes'
703     raises(ValueError, "cfg.od.dodval2.st2val2 = 'yes'")
704     raises(ValueError, "cfg.od.dodval1.st2val1 = 'yes'")
705     del(cfg.od.dodval2.stval2)
706     raises(ValueError, "cfg.od.dodval1.st2val1 = 'yes'")
707     cfg.od.dodval2.st2val2 = 'yes'
708     raises(ValueError, "cfg.od.dodval2.stval2 = 'yes'")
709
710
711 def test_consistency_dyndescription_default():
712     st = StrOption('st', '', 'yes')
713     st2 = StrOption('st2', '')
714     dod = DynOptionDescription('dod', '', [st, st2], callback=return_list)
715     od = OptionDescription('od', '', [dod])
716     st.impl_add_consistency('not_equal', st2)
717     od2 = OptionDescription('od', '', [od])
718     cfg = Config(od2)
719     cfg
720     raises(ValueError, "cfg.od.dodval1.st2val1 = 'yes'")
721     raises(ValueError, "cfg.od.dodval2.st2val2 = 'yes'")
722
723
724 def test_consistency_dyndescription_default_multi2():
725     st = StrOption('st', '', ['yes'], multi=True)
726     st2 = StrOption('st2', '', ['yes'], multi=True)
727     dod = DynOptionDescription('dod', '', [st, st2], callback=return_list)
728     dod
729     raises(ValueError, "st.impl_add_consistency('not_equal', st2)")
730
731
732 def test_consistency_only_one_dyndescription():
733     st = StrOption('st', '')
734     st
735     st2 = StrOption('st2', '')
736     DynOptionDescription('dod', '', [st2], callback=return_list)
737     raises(ConfigError, "st.impl_add_consistency('not_equal', st2)")
738     raises(ConfigError, "st2.impl_add_consistency('not_equal', st)")
739
740
741 def test_consistency_became_dyndescription():
742     st = StrOption('st', '')
743     st2 = StrOption('st2', '')
744     st2.impl_add_consistency('not_equal', st)
745     od = DynOptionDescription('dod', '', [st2], callback=return_list)
746     od2 = OptionDescription('od', '', [od, st])
747     od2
748     raises(ConfigError, "c = Config(od2)")
749
750
751 def test_consistency_became_dyndescription2():
752     st = StrOption('st', '')
753     st2 = StrOption('st2', '')
754     st.impl_add_consistency('not_equal', st2)
755     od = DynOptionDescription('dod', '', [st2], callback=return_list)
756     od2 = OptionDescription('od', '', [od, st])
757     od2
758     raises(ConfigError, "c = Config(od2)")
759
760
761 def test_consistency_external_dyndescription():
762     st = StrOption('st', '')
763     st1 = StrOption('st1', '')
764     st2 = StrOption('st2', '')
765     dod = DynOptionDescription('dod', '', [st1, st2], callback=return_list)
766     od = OptionDescription('od', '', [dod, st])
767     od
768     raises(ConfigError, "st.impl_add_consistency('not_equal', st2)")
769
770
771 def test_consistency_notsame_dyndescription():
772     st1 = StrOption('st1', '')
773     st2 = StrOption('st2', '')
774     dod = DynOptionDescription('dod', '', [st1, st2], callback=return_list)
775     tst1 = StrOption('tst1', '')
776     tst2 = StrOption('tst2', '')
777     tdod = DynOptionDescription('tdod', '', [tst1, tst2], callback=return_list)
778     od = OptionDescription('od', '', [dod, tdod])
779     od
780     raises(ConfigError, "st1.impl_add_consistency('not_equal', tst1)")
781
782
783 def test_all_dyndescription():
784     st = StrOption('st', '')
785     ip = IPOption('ip', '')
786     network = NetworkOption('network', '')
787     netmask = NetmaskOption('netmask', '')
788     ch = ChoiceOption('ch', '', ('val1', 'val2', 'val3'))
789     ch1 = ChoiceOption('ch1', '', return_list)
790     boo = BoolOption('boo', '')
791     intr = IntOption('intr', '')
792     floa = FloatOption('floa', '')
793     uni = UnicodeOption('uni', '')
794     port = PortOption('port', '')
795     broad = BroadcastOption('broad', '')
796     domain = DomainnameOption('domain', '')
797     email = EmailOption('email', '')
798     url = URLOption('url', '')
799     username = UsernameOption('username', '')
800     filename = FilenameOption('filename', '')
801     dod = DynOptionDescription('dod', '', [st, ip, network, netmask, ch, ch1,
802                                            boo, intr, floa, uni, port, broad,
803                                            domain, email, url, username,
804                                            filename], callback=return_list)
805     od = OptionDescription('od', '', [dod])
806     cfg = Config(od)
807     assert cfg.dodval1.stval1 is None
808     assert cfg.dodval1.ipval1 is None
809     assert cfg.dodval1.networkval1 is None
810     assert cfg.dodval1.netmaskval1 is None
811     assert cfg.dodval1.chval1 is None
812     assert cfg.dodval1.ch1val1 is None
813     assert cfg.dodval1.booval1 is None
814     assert cfg.dodval1.intrval1 is None
815     assert cfg.dodval1.floaval1 is None
816     assert cfg.dodval1.unival1 is None
817     assert cfg.dodval1.portval1 is None
818     assert cfg.dodval1.broadval1 is None
819     assert cfg.dodval1.domainval1 is None
820     assert cfg.dodval1.emailval1 is None
821     assert cfg.dodval1.urlval1 is None
822     assert cfg.dodval1.usernameval1 is None
823     assert cfg.dodval1.filenameval1 is None
824     #
825     cfg.dodval1.stval1 = "no"
826     cfg.dodval1.ipval1 = "1.1.1.1"
827     cfg.dodval1.networkval1 = "1.1.1.0"
828     cfg.dodval1.netmaskval1 = "255.255.255.0"
829     cfg.dodval1.chval1 = "val1"
830     cfg.dodval1.ch1val1 = "val2"
831     cfg.dodval1.booval1 = True
832     cfg.dodval1.intrval1 = 1
833     cfg.dodval1.floaval1 = 0.1
834     cfg.dodval1.unival1 = u"no"
835     cfg.dodval1.portval1 = 80
836     cfg.dodval1.broadval1 = "1.1.1.255"
837     cfg.dodval1.domainval1 = "test.com"
838     cfg.dodval1.emailval1 = "test@test.com"
839     cfg.dodval1.urlval1 = "http://test.com"
840     cfg.dodval1.usernameval1 = "user1"
841     cfg.dodval1.filenameval1 = "/tmp"
842     assert cfg.dodval1.stval1 == "no"
843     assert cfg.dodval1.ipval1 == "1.1.1.1"
844     assert cfg.dodval1.networkval1 == "1.1.1.0"
845     assert cfg.dodval1.netmaskval1 == "255.255.255.0"
846     assert cfg.dodval1.chval1 == "val1"
847     assert cfg.dodval1.ch1val1 == "val2"
848     assert cfg.dodval1.booval1 is True
849     assert cfg.dodval1.intrval1 == 1
850     assert cfg.dodval1.floaval1 == 0.1
851     assert cfg.dodval1.unival1 == u"no"
852     assert cfg.dodval1.portval1 == 80
853     assert cfg.dodval1.broadval1 == "1.1.1.255"
854     assert cfg.dodval1.domainval1 == "test.com"
855     assert cfg.dodval1.emailval1 == "test@test.com"
856     assert cfg.dodval1.urlval1 == "http://test.com"
857     assert cfg.dodval1.usernameval1 == "user1"
858     assert cfg.dodval1.filenameval1 == "/tmp"
859     #
860     assert cfg.dodval2.stval2 is None
861     assert cfg.dodval2.ipval2 is None
862     assert cfg.dodval2.networkval2 is None
863     assert cfg.dodval2.netmaskval2 is None
864     assert cfg.dodval2.chval2 is None
865     assert cfg.dodval2.ch1val2 is None
866     assert cfg.dodval2.booval2 is None
867     assert cfg.dodval2.intrval2 is None
868     assert cfg.dodval2.floaval2 is None
869     assert cfg.dodval2.unival2 is None
870     assert cfg.dodval2.portval2 is None
871     assert cfg.dodval2.broadval2 is None
872     assert cfg.dodval2.domainval2 is None
873     assert cfg.dodval2.emailval2 is None
874     assert cfg.dodval2.urlval2 is None
875     assert cfg.dodval2.usernameval2 is None
876     assert cfg.dodval2.filenameval2 is None
877
878
879 def test_consistency_ip_netmask_dyndescription():
880     a = IPOption('a', '')
881     b = NetmaskOption('b', '')
882     dod = DynOptionDescription('dod', '', [a, b], callback=return_list)
883     b.impl_add_consistency('ip_netmask', a)
884     od = OptionDescription('od', '', [dod])
885     c = Config(od)
886     c.dodval1.aval1 = '192.168.1.1'
887     c.dodval1.bval1 = '255.255.255.0'
888     c.dodval2.aval2 = '192.168.1.2'
889     c.dodval2.bval2 = '255.255.255.255'
890     c.dodval2.bval2 = '255.255.255.0'
891
892
893 def test_consistency_ip_in_network_dyndescription():
894     a = NetworkOption('a', '')
895     b = NetmaskOption('b', '')
896     c = IPOption('c', '')
897     dod = DynOptionDescription('dod', '', [a, b, c], callback=return_list)
898     c.impl_add_consistency('in_network', a, b)
899     od = OptionDescription('od', '', [dod])
900     cfg = Config(od)
901     cfg.dodval1.aval1 = '192.168.1.0'
902     cfg.dodval1.bval1 = '255.255.255.0'
903     cfg.dodval1.cval1 = '192.168.1.1'
904
905
906 def test_masterslaves_dyndescription():
907     st1 = StrOption('st1', "", multi=True)
908     st2 = StrOption('st2', "", multi=True)
909     stm = OptionDescription('st1', '', [st1, st2])
910     stm.impl_set_group_type(groups.master)
911     st = DynOptionDescription('st', '', [stm], callback=return_list)
912     od = OptionDescription('od', '', [st])
913     od2 = OptionDescription('od', '', [od])
914     cfg = Config(od2)
915     owner = cfg.cfgimpl_get_settings().getowner()
916     st1val1 = cfg.unwrap_from_path('od.stval1.st1val1.st1val1')
917     st2val1 = cfg.unwrap_from_path('od.stval1.st1val1.st2val1')
918     st1val2 = cfg.unwrap_from_path('od.stval2.st1val2.st1val2')
919     st2val2 = cfg.unwrap_from_path('od.stval2.st1val2.st2val2')
920     assert cfg.make_dict() == {'od.stval1.st1val1.st2val1': [], 'od.stval2.st1val2.st2val2': [], 'od.stval2.st1val2.st1val2': [], 'od.stval1.st1val1.st1val1': []}
921     assert cfg.od.stval1.st1val1.st1val1 == []
922     assert cfg.od.stval1.st1val1.st2val1 == []
923     assert cfg.od.stval2.st1val2.st1val2 == []
924     assert cfg.od.stval2.st1val2.st2val2 == []
925     assert cfg.getowner(st1val1) == owners.default
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.append('yes')
931     assert cfg.make_dict() == {'od.stval1.st1val1.st2val1': [None], 'od.stval2.st1val2.st2val2': [], 'od.stval2.st1val2.st1val2': [], 'od.stval1.st1val1.st1val1': ['yes']}
932     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
933     assert cfg.od.stval1.st1val1.st2val1 == [None]
934     assert cfg.od.stval2.st1val2.st1val2 == []
935     assert cfg.od.stval2.st1val2.st2val2 == []
936     assert cfg.getowner(st1val1) == owner
937     assert cfg.getowner(st1val2) == owners.default
938     assert cfg.getowner(st2val1) == owners.default
939     assert cfg.getowner(st2val2) == owners.default
940     #
941     cfg.od.stval1.st1val1.st1val1 = ['yes']
942     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
943     assert cfg.od.stval1.st1val1.st2val1 == [None]
944     assert cfg.od.stval2.st1val2.st1val2 == []
945     assert cfg.od.stval2.st1val2.st2val2 == []
946     assert cfg.getowner(st1val1) == owner
947     assert cfg.getowner(st1val2) == owners.default
948     assert cfg.getowner(st2val1) == owners.default
949     assert cfg.getowner(st2val2) == owners.default
950     #
951     cfg.od.stval1.st1val1.st2val1 = ['no']
952     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
953     assert cfg.od.stval1.st1val1.st2val1 == ['no']
954     assert cfg.od.stval2.st1val2.st1val2 == []
955     assert cfg.od.stval2.st1val2.st2val2 == []
956     assert cfg.getowner(st1val1) == owner
957     assert cfg.getowner(st1val2) == owners.default
958     assert cfg.getowner(st2val1, 0) == owner
959 #    assert cfg.getowner(st2val2) == owners.default
960     #
961     cfg.od.stval1.st1val1.st1val1.pop(0)
962     assert cfg.od.stval1.st1val1.st1val1 == []
963     assert cfg.od.stval1.st1val1.st2val1 == []
964     assert cfg.od.stval2.st1val2.st1val2 == []
965     assert cfg.od.stval2.st1val2.st2val2 == []
966     assert cfg.getowner(st1val1) == owner
967     assert cfg.getowner(st1val2) == owners.default
968 #    assert cfg.getowner(st2val1) == owner
969 #    assert cfg.getowner(st2val2) == owners.default
970     #
971     cfg.od.stval1.st1val1.st1val1 = ['yes']
972     cfg.od.stval1.st1val1.st2val1 = ['yes']
973     assert cfg.getowner(st1val1) == owner
974     assert cfg.getowner(st2val1, 0) == owner
975     del(cfg.od.stval1.st1val1.st2val1)
976     assert cfg.getowner(st1val1) == owner
977     assert cfg.getowner(st1val2) == owners.default
978 #    assert cfg.getowner(st2val1) == owners.default
979 #    assert cfg.getowner(st2val2) == owners.default
980     #
981     cfg.od.stval1.st1val1.st1val1 = ['yes']
982     cfg.od.stval1.st1val1.st2val1 = ['yes']
983     del(cfg.od.stval1.st1val1.st1val1)
984     assert cfg.od.stval1.st1val1.st1val1 == []
985     assert cfg.od.stval1.st1val1.st2val1 == []
986     assert cfg.od.stval2.st1val2.st1val2 == []
987     assert cfg.od.stval2.st1val2.st2val2 == []
988     assert cfg.getowner(st1val1) == owners.default
989     assert cfg.getowner(st1val2) == owners.default
990     assert cfg.getowner(st2val1) == owners.default
991     assert cfg.getowner(st2val2) == owners.default
992
993
994 def test_masterslaves_default_multi_dyndescription():
995     st1 = StrOption('st1', "", multi=True)
996     st2 = StrOption('st2', "", multi=True, default_multi='no')
997     stm = OptionDescription('st1', '', [st1, st2])
998     stm.impl_set_group_type(groups.master)
999     st = DynOptionDescription('st', '', [stm], callback=return_list)
1000     od = OptionDescription('od', '', [st])
1001     od2 = OptionDescription('od', '', [od])
1002     cfg = Config(od2)
1003     owner = cfg.cfgimpl_get_settings().getowner()
1004     st1val1 = cfg.unwrap_from_path('od.stval1.st1val1.st1val1')
1005     st2val1 = cfg.unwrap_from_path('od.stval1.st1val1.st2val1')
1006     st1val2 = cfg.unwrap_from_path('od.stval2.st1val2.st1val2')
1007     st2val2 = cfg.unwrap_from_path('od.stval2.st1val2.st2val2')
1008     assert cfg.od.stval1.st1val1.st1val1 == []
1009     assert cfg.od.stval1.st1val1.st2val1 == []
1010     assert cfg.od.stval2.st1val2.st1val2 == []
1011     assert cfg.od.stval2.st1val2.st2val2 == []
1012     assert cfg.getowner(st1val1) == owners.default
1013     assert cfg.getowner(st1val2) == owners.default
1014     assert cfg.getowner(st2val1) == owners.default
1015     assert cfg.getowner(st2val2) == owners.default
1016     cfg.od.stval1.st1val1.st1val1.append('yes')
1017     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
1018     assert cfg.od.stval1.st1val1.st2val1 == ['no']
1019     assert cfg.od.stval2.st1val2.st1val2 == []
1020     assert cfg.od.stval2.st1val2.st2val2 == []
1021     assert cfg.getowner(st1val1) == owner
1022     assert cfg.getowner(st1val2) == owners.default
1023     assert cfg.getowner(st2val1) == owners.default
1024     assert cfg.getowner(st2val2) == owners.default
1025
1026
1027 def test_masterslaves_submulti_dyndescription():
1028     st1 = StrOption('st1', "", multi=True)
1029     st2 = StrOption('st2', "", multi=submulti)
1030     stm = OptionDescription('st1', '', [st1, st2])
1031     stm.impl_set_group_type(groups.master)
1032     st = DynOptionDescription('st', '', [stm], callback=return_list)
1033     od = OptionDescription('od', '', [st])
1034     od2 = OptionDescription('od', '', [od])
1035     cfg = Config(od2)
1036     owner = cfg.cfgimpl_get_settings().getowner()
1037     st1val1 = cfg.unwrap_from_path('od.stval1.st1val1.st1val1')
1038     st2val1 = cfg.unwrap_from_path('od.stval1.st1val1.st2val1')
1039     st1val2 = cfg.unwrap_from_path('od.stval2.st1val2.st1val2')
1040     st2val2 = cfg.unwrap_from_path('od.stval2.st1val2.st2val2')
1041     assert cfg.od.stval1.st1val1.st1val1 == []
1042     assert cfg.od.stval1.st1val1.st2val1 == []
1043     assert cfg.od.stval2.st1val2.st1val2 == []
1044     assert cfg.od.stval2.st1val2.st2val2 == []
1045     assert cfg.getowner(st1val1) == owners.default
1046     assert cfg.getowner(st1val2) == owners.default
1047     assert cfg.getowner(st2val1) == owners.default
1048     assert cfg.getowner(st2val2) == owners.default
1049     cfg.od.stval1.st1val1.st1val1.append('yes')
1050     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
1051     assert cfg.od.stval1.st1val1.st2val1 == [[]]
1052     assert cfg.od.stval2.st1val2.st1val2 == []
1053     assert cfg.od.stval2.st1val2.st2val2 == []
1054     assert cfg.getowner(st1val1) == owner
1055     assert cfg.getowner(st1val2) == owners.default
1056     assert cfg.getowner(st2val1) == owners.default
1057     assert cfg.getowner(st2val2) == owners.default
1058     #
1059     cfg.od.stval1.st1val1.st2val1[0].append('no')
1060     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
1061     assert cfg.od.stval1.st1val1.st2val1 == [['no']]
1062     assert cfg.od.stval2.st1val2.st1val2 == []
1063     assert cfg.od.stval2.st1val2.st2val2 == []
1064     assert cfg.getowner(st1val1) == owner
1065     assert cfg.getowner(st1val2) == owners.default
1066     assert cfg.getowner(st2val1, 0) == owner
1067     assert cfg.getowner(st2val2) == owners.default
1068
1069
1070 def test_masterslaves_consistency_ip_dyndescription():
1071     a = NetworkOption('net', '', multi=True)
1072     b = NetmaskOption('mask', '', multi=True)
1073     c = BroadcastOption('broad', '', multi=True)
1074     b.impl_add_consistency('network_netmask', a)
1075     c.impl_add_consistency('broadcast', a, b)
1076     dod = DynOptionDescription('net', '', [a, b, c], callback=return_list)
1077     dod.impl_set_group_type(groups.master)
1078     od = OptionDescription('od', '', [dod])
1079     cfg = Config(od)
1080     cfg.netval1.netval1 = ['192.168.1.0']
1081     cfg.netval1.maskval1 = ['255.255.255.0']
1082     cfg.netval1.broadval1 = ['192.168.1.255']
1083
1084     cfg.netval1.netval1 = ['192.168.1.0', '192.168.2.128']
1085     cfg.netval1.maskval1 = ['255.255.255.0', '255.255.255.128']
1086     cfg.netval1.broadval1 = ['192.168.1.255', '192.168.2.255']
1087     cfg.netval1.broadval1[1] = '192.168.2.255'
1088     #
1089     assert cfg.netval1.netval1 == ['192.168.1.0', '192.168.2.128']
1090     assert cfg.netval1.maskval1 == ['255.255.255.0', '255.255.255.128']
1091     assert cfg.netval1.broadval1 == ['192.168.1.255', '192.168.2.255']
1092     assert cfg.netval2.netval2 == []
1093     assert cfg.netval2.maskval2 == []
1094     assert cfg.netval2.broadval2 == []
1095
1096
1097 def test_masterslaves_consistency_ip_dyndescription_propertyerror():
1098     a = NetworkOption('net', '', multi=True)
1099     b = NetmaskOption('mask', '', multi=True, properties=('mandatory',))
1100     c = BroadcastOption('broad', '', multi=True)
1101     b.impl_add_consistency('network_netmask', a)
1102     c.impl_add_consistency('broadcast', a, b)
1103     dod = DynOptionDescription('net', '', [a, b, c], callback=return_list)
1104     dod.impl_set_group_type(groups.master)
1105     od = OptionDescription('od', '', [dod])
1106     cfg = Config(od)
1107     cfg.read_write()
1108     cfg.netval1.netval1 = ['192.168.1.0']
1109     cfg.read_only()
1110     raises(PropertiesOptionError, "cfg.netval1.netval1")
1111
1112
1113 def test_masterslaves_callback_dyndescription():
1114     st1 = StrOption('st1', "", multi=True)
1115     st2 = StrOption('st2', "", multi=True, callback=return_dynval, callback_params={'value': ((st1, False),)})
1116     stm = OptionDescription('st1', '', [st1, st2])
1117     stm.impl_set_group_type(groups.master)
1118     st = DynOptionDescription('st', '', [stm], callback=return_list)
1119     od = OptionDescription('od', '', [st])
1120     od2 = OptionDescription('od', '', [od])
1121     cfg = Config(od2)
1122     owner = cfg.cfgimpl_get_settings().getowner()
1123     st1val1 = cfg.unwrap_from_path('od.stval1.st1val1.st1val1')
1124     st2val1 = cfg.unwrap_from_path('od.stval1.st1val1.st2val1')
1125     st1val2 = cfg.unwrap_from_path('od.stval2.st1val2.st1val2')
1126     st2val2 = cfg.unwrap_from_path('od.stval2.st1val2.st2val2')
1127     assert cfg.make_dict() == {'od.stval1.st1val1.st2val1': [], 'od.stval2.st1val2.st2val2': [], 'od.stval2.st1val2.st1val2': [], 'od.stval1.st1val1.st1val1': []}
1128     assert cfg.od.stval1.st1val1.st1val1 == []
1129     assert cfg.od.stval1.st1val1.st2val1 == []
1130     assert cfg.od.stval2.st1val2.st1val2 == []
1131     assert cfg.od.stval2.st1val2.st2val2 == []
1132     assert cfg.getowner(st1val1) == owners.default
1133     assert cfg.getowner(st1val2) == owners.default
1134     assert cfg.getowner(st2val1) == owners.default
1135     assert cfg.getowner(st2val2) == owners.default
1136     #
1137     cfg.od.stval1.st1val1.st1val1.append('yes')
1138     assert cfg.make_dict() == {'od.stval1.st1val1.st2val1': ['yes'], 'od.stval2.st1val2.st2val2': [], 'od.stval2.st1val2.st1val2': [], 'od.stval1.st1val1.st1val1': ['yes']}
1139     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
1140     assert cfg.od.stval1.st1val1.st2val1 == ['yes']
1141     assert cfg.od.stval2.st1val2.st1val2 == []
1142     assert cfg.od.stval2.st1val2.st2val2 == []
1143     assert cfg.getowner(st1val1) == owner
1144     assert cfg.getowner(st1val2) == owners.default
1145     assert cfg.getowner(st2val1) == owners.default
1146     assert cfg.getowner(st2val2) == owners.default
1147     #
1148     cfg.od.stval1.st1val1.st2val1 = ['no']
1149     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
1150     assert cfg.od.stval1.st1val1.st2val1 == ['no']
1151     assert cfg.od.stval2.st1val2.st1val2 == []
1152     assert cfg.od.stval2.st1val2.st2val2 == []
1153     assert cfg.getowner(st1val1) == owner
1154     assert cfg.getowner(st1val2) == owners.default
1155     assert cfg.getowner(st2val1, 0) == owner
1156 #    assert cfg.getowner(st2val2) == owners.default
1157     #
1158     cfg.od.stval1.st1val1.st1val1.pop(0)
1159     assert cfg.od.stval1.st1val1.st1val1 == []
1160     assert cfg.od.stval1.st1val1.st2val1 == []
1161     assert cfg.od.stval2.st1val2.st1val2 == []
1162     assert cfg.od.stval2.st1val2.st2val2 == []
1163     assert cfg.getowner(st1val1) == owner
1164     assert cfg.getowner(st1val2) == owners.default
1165 #    assert cfg.getowner(st2val1) == owner
1166 #    assert cfg.getowner(st2val2) == owners.default
1167     #
1168     cfg.od.stval1.st1val1.st1val1 = ['yes']
1169     cfg.od.stval1.st1val1.st2val1 = ['yes']
1170     assert cfg.getowner(st1val1) == owner
1171     assert cfg.getowner(st2val1, 0) == owner
1172     del(cfg.od.stval1.st1val1.st2val1)
1173     assert cfg.getowner(st1val1) == owner
1174     assert cfg.getowner(st1val2) == owners.default
1175     assert cfg.getowner(st2val1) == owners.default
1176     assert cfg.getowner(st2val2) == owners.default
1177     #
1178     cfg.od.stval1.st1val1.st1val1 = ['yes']
1179     cfg.od.stval1.st1val1.st2val1 = ['yes']
1180     del(cfg.od.stval1.st1val1.st1val1)
1181     assert cfg.od.stval1.st1val1.st1val1 == []
1182     assert cfg.od.stval1.st1val1.st2val1 == []
1183     assert cfg.od.stval2.st1val2.st1val2 == []
1184     assert cfg.od.stval2.st1val2.st2val2 == []
1185     assert cfg.getowner(st1val1) == owners.default
1186     assert cfg.getowner(st1val2) == owners.default
1187     assert cfg.getowner(st2val1) == owners.default
1188     assert cfg.getowner(st2val2) == owners.default
1189     #
1190     cfg.od.stval1.st1val1.st2val1 = []
1191     cfg.od.stval1.st1val1.st1val1 = ['yes']
1192     assert cfg.od.stval1.st1val1.st2val1 == ['yes']
1193
1194
1195 def test_masterslaves_callback_value_dyndescription():
1196     st1 = StrOption('st1', "", multi=True)
1197     st2 = StrOption('st2', "", multi=True, callback=return_dynval, callback_params={'value': ('val',)})
1198     stm = OptionDescription('st1', '', [st1, st2])
1199     stm.impl_set_group_type(groups.master)
1200     st = DynOptionDescription('st', '', [stm], callback=return_list)
1201     od = OptionDescription('od', '', [st])
1202     od2 = OptionDescription('od', '', [od])
1203     cfg = Config(od2)
1204     assert cfg.od.stval1.st1val1.st1val1 == []
1205     assert cfg.od.stval1.st1val1.st2val1 == []
1206     cfg.od.stval1.st1val1.st1val1.append('yes')
1207     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
1208     assert cfg.od.stval1.st1val1.st2val1[0] == 'val'
1209     assert cfg.od.stval1.st1val1.st2val1 == ['val']
1210
1211
1212 def test_masterslaves_callback_nomulti_dyndescription():
1213     v1 = StrOption('v1', '', "val")
1214     st1 = StrOption('st1', "", multi=True)
1215     st2 = StrOption('st2', "", multi=True, callback=return_dynval, callback_params={'': ((v1, False),)})
1216     stm = OptionDescription('st1', '', [st1, st2])
1217     stm.impl_set_group_type(groups.master)
1218     st = DynOptionDescription('st', '', [stm], callback=return_list)
1219     od = OptionDescription('od', '', [st])
1220     od2 = OptionDescription('od', '', [od, v1])
1221     cfg = Config(od2)
1222     assert cfg.od.stval1.st1val1.st1val1 == []
1223     assert cfg.od.stval1.st1val1.st2val1 == []
1224     cfg.od.stval1.st1val1.st1val1.append('yes')
1225     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
1226     assert cfg.od.stval1.st1val1.st2val1 == ['val']
1227
1228
1229 def test_masterslaves_callback_samegroup_dyndescription():
1230     st1 = StrOption('st1', "", multi=True)
1231     st2 = StrOption('st2', "", multi=True)
1232     st3 = StrOption('st3', "", multi=True, callback=return_dynval, callback_params={'': ((st2, False),)})
1233     stm = OptionDescription('st1', '', [st1, st2, st3])
1234     stm.impl_set_group_type(groups.master)
1235     st = DynOptionDescription('st', '', [stm], callback=return_list)
1236     od = OptionDescription('od', '', [st])
1237     od2 = OptionDescription('od', '', [od])
1238     cfg = Config(od2)
1239     owner = cfg.cfgimpl_get_settings().getowner()
1240     st1val1 = cfg.unwrap_from_path('od.stval1.st1val1.st1val1')
1241     st2val1 = cfg.unwrap_from_path('od.stval1.st1val1.st2val1')
1242     st3val1 = cfg.unwrap_from_path('od.stval1.st1val1.st3val1')
1243     st1val2 = cfg.unwrap_from_path('od.stval2.st1val2.st1val2')
1244     st2val2 = cfg.unwrap_from_path('od.stval2.st1val2.st2val2')
1245     st3val2 = cfg.unwrap_from_path('od.stval2.st1val2.st3val2')
1246     assert cfg.make_dict() == {'od.stval1.st1val1.st1val1': [],
1247                                'od.stval1.st1val1.st2val1': [],
1248                                'od.stval1.st1val1.st3val1': [],
1249                                'od.stval2.st1val2.st1val2': [],
1250                                'od.stval2.st1val2.st2val2': [],
1251                                'od.stval2.st1val2.st3val2': []}
1252     assert cfg.od.stval1.st1val1.st1val1 == []
1253     assert cfg.od.stval1.st1val1.st2val1 == []
1254     assert cfg.od.stval1.st1val1.st3val1 == []
1255     assert cfg.od.stval2.st1val2.st1val2 == []
1256     assert cfg.od.stval2.st1val2.st2val2 == []
1257     assert cfg.od.stval2.st1val2.st3val2 == []
1258     assert cfg.getowner(st1val1) == owners.default
1259     assert cfg.getowner(st1val2) == owners.default
1260     assert cfg.getowner(st2val1) == owners.default
1261     assert cfg.getowner(st2val2) == owners.default
1262     assert cfg.getowner(st3val1) == owners.default
1263     assert cfg.getowner(st3val2) == owners.default
1264     ##
1265     cfg.od.stval1.st1val1.st1val1.append('yes')
1266     assert cfg.make_dict() == {'od.stval1.st1val1.st1val1': ['yes'],
1267                                'od.stval1.st1val1.st2val1': [None],
1268                                'od.stval1.st1val1.st3val1': [None],
1269                                'od.stval2.st1val2.st1val2': [],
1270                                'od.stval2.st1val2.st2val2': [],
1271                                'od.stval2.st1val2.st3val2': []}
1272     assert cfg.getowner(st1val1) == owner
1273     assert cfg.getowner(st1val2) == owners.default
1274     assert cfg.getowner(st2val1) == owners.default
1275     assert cfg.getowner(st2val2) == owners.default
1276     assert cfg.getowner(st3val1) == owners.default
1277     assert cfg.getowner(st3val2) == owners.default
1278     #
1279     cfg.od.stval1.st1val1.st2val1[0] = 'yes'
1280     assert cfg.make_dict() == {'od.stval1.st1val1.st1val1': ['yes'],
1281                                'od.stval1.st1val1.st2val1': ['yes'],
1282                                'od.stval1.st1val1.st3val1': ['yes'],
1283                                'od.stval2.st1val2.st1val2': [],
1284                                'od.stval2.st1val2.st2val2': [],
1285                                'od.stval2.st1val2.st3val2': []}
1286     assert cfg.getowner(st1val1) == owner
1287     assert cfg.getowner(st2val1, 0) == owner
1288     assert cfg.getowner(st3val1, 0) == owners.default
1289     assert cfg.getowner(st1val2) == owners.default
1290     #assert cfg.getowner(st2val2) == owners.default
1291     #assert cfg.getowner(st3val2) == owners.default
1292
1293
1294 def test_state_config():
1295     a = IPOption('a', '')
1296     b = NetmaskOption('b', '')
1297     dod1 = DynOptionDescription('dod1', '', [a, b], callback=return_list)
1298     b.impl_add_consistency('ip_netmask', a)
1299     od1 = OptionDescription('od1', '', [dod1])
1300     st1 = StrOption('st1', "", multi=True)
1301     st2 = StrOption('st2', "", multi=True)
1302     st3 = StrOption('st3', "", multi=True, callback=return_dynval, callback_params={'': ((st2, False),)})
1303     stm = OptionDescription('st1', '', [st1, st2, st3])
1304     stm.impl_set_group_type(groups.master)
1305     st = DynOptionDescription('st', '', [stm], callback=return_list)
1306     od = OptionDescription('od', '', [st])
1307     od2 = OptionDescription('od', '', [od, od1])
1308     try:
1309         cfg = Config(od2, persistent=True, session_id='29090938')
1310     except ValueError:
1311         cfg = Config(od2, session_id='29090938')
1312         cfg._impl_test = True
1313         a = dumps(cfg)
1314         q = loads(a)
1315         _diff_opts(cfg.cfgimpl_get_description(), q.cfgimpl_get_description())
1316         _diff_conf(cfg, q)
1317
1318     try:
1319         delete_session('config', '29090938')
1320     except ValueError:
1321         pass
1322
1323
1324 def test_invalid_conflict_dyndescription():
1325     st = StrOption('st', '')
1326     dod = DynOptionDescription('dod', '', [st], callback=return_list)
1327     dodinvalid = StrOption('dodinvalid', '')
1328     dod, dodinvalid
1329     raises(ConflictError, "OptionDescription('od', '', [dod, dodinvalid])")
1330
1331
1332 def test_invalid_subod_dyndescription():
1333     st2 = StrOption('st2', '')
1334     od1 = OptionDescription('od1', '', [st2])
1335     od1
1336     raises(ConfigError, "DynOptionDescription('dod', '', [od1], callback=return_list)")
1337
1338
1339 def test_invalid_subdynod_dyndescription():
1340     st2 = StrOption('st2', '')
1341     od1 = DynOptionDescription('od1', '', [st2], callback=return_list)
1342     od1
1343     raises(ConfigError, "DynOptionDescription('dod', '', [od1], callback=return_list)")
1344
1345
1346 def test_invalid_symlink_dyndescription():
1347     st = StrOption('st', '')
1348     st2 = SymLinkOption('st2', st)
1349     st2
1350     raises(ConfigError, "DynOptionDescription('dod', '', [st, st2], callback=return_list)")
1351
1352
1353 def test_nocallback_dyndescription():
1354     st = StrOption('st', '')
1355     st2 = StrOption('st2', '')
1356     st, st2
1357     raises(ConfigError, "DynOptionDescription('dod', '', [st, st2])")
1358
1359
1360 def test_invalid_samevalue_dyndescription():
1361     st = StrOption('st', '')
1362     dod = DynOptionDescription('dod', '', [st], callback=return_same_list)
1363     od = OptionDescription('od', '', [dod])
1364     cfg = Config(od)
1365     cfg
1366     raises(ConfigError, "print(cfg)")
1367
1368
1369 def test_invalid_name_dyndescription():
1370     st = StrOption('st', '')
1371     dod = DynOptionDescription('dod', '', [st], callback=return_wrong_list)
1372     od = OptionDescription('od', '', [dod])
1373     cfg = Config(od)
1374     cfg
1375     raises(ValueError, "print(cfg)")