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