254acf414ac8adc12cddde533b94af6cd7190da6
[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_callback_dyndescription():
1098     st1 = StrOption('st1', "", multi=True)
1099     st2 = StrOption('st2', "", multi=True, callback=return_dynval, callback_params={'value': ((st1, False),)})
1100     stm = OptionDescription('st1', '', [st1, st2])
1101     stm.impl_set_group_type(groups.master)
1102     st = DynOptionDescription('st', '', [stm], callback=return_list)
1103     od = OptionDescription('od', '', [st])
1104     od2 = OptionDescription('od', '', [od])
1105     cfg = Config(od2)
1106     owner = cfg.cfgimpl_get_settings().getowner()
1107     st1val1 = cfg.unwrap_from_path('od.stval1.st1val1.st1val1')
1108     st2val1 = cfg.unwrap_from_path('od.stval1.st1val1.st2val1')
1109     st1val2 = cfg.unwrap_from_path('od.stval2.st1val2.st1val2')
1110     st2val2 = cfg.unwrap_from_path('od.stval2.st1val2.st2val2')
1111     assert cfg.make_dict() == {'od.stval1.st1val1.st2val1': [], 'od.stval2.st1val2.st2val2': [], 'od.stval2.st1val2.st1val2': [], 'od.stval1.st1val1.st1val1': []}
1112     assert cfg.od.stval1.st1val1.st1val1 == []
1113     assert cfg.od.stval1.st1val1.st2val1 == []
1114     assert cfg.od.stval2.st1val2.st1val2 == []
1115     assert cfg.od.stval2.st1val2.st2val2 == []
1116     assert cfg.getowner(st1val1) == owners.default
1117     assert cfg.getowner(st1val2) == owners.default
1118     assert cfg.getowner(st2val1) == owners.default
1119     assert cfg.getowner(st2val2) == owners.default
1120     #
1121     cfg.od.stval1.st1val1.st1val1.append('yes')
1122     assert cfg.make_dict() == {'od.stval1.st1val1.st2val1': ['yes'], 'od.stval2.st1val2.st2val2': [], 'od.stval2.st1val2.st1val2': [], 'od.stval1.st1val1.st1val1': ['yes']}
1123     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
1124     assert cfg.od.stval1.st1val1.st2val1 == ['yes']
1125     assert cfg.od.stval2.st1val2.st1val2 == []
1126     assert cfg.od.stval2.st1val2.st2val2 == []
1127     assert cfg.getowner(st1val1) == owner
1128     assert cfg.getowner(st1val2) == owners.default
1129     assert cfg.getowner(st2val1) == owners.default
1130     assert cfg.getowner(st2val2) == owners.default
1131     #
1132     cfg.od.stval1.st1val1.st2val1 = ['no']
1133     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
1134     assert cfg.od.stval1.st1val1.st2val1 == ['no']
1135     assert cfg.od.stval2.st1val2.st1val2 == []
1136     assert cfg.od.stval2.st1val2.st2val2 == []
1137     assert cfg.getowner(st1val1) == owner
1138     assert cfg.getowner(st1val2) == owners.default
1139     assert cfg.getowner(st2val1, 0) == owner
1140 #    assert cfg.getowner(st2val2) == owners.default
1141     #
1142     cfg.od.stval1.st1val1.st1val1.pop(0)
1143     assert cfg.od.stval1.st1val1.st1val1 == []
1144     assert cfg.od.stval1.st1val1.st2val1 == []
1145     assert cfg.od.stval2.st1val2.st1val2 == []
1146     assert cfg.od.stval2.st1val2.st2val2 == []
1147     assert cfg.getowner(st1val1) == owner
1148     assert cfg.getowner(st1val2) == owners.default
1149 #    assert cfg.getowner(st2val1) == owner
1150 #    assert cfg.getowner(st2val2) == owners.default
1151     #
1152     cfg.od.stval1.st1val1.st1val1 = ['yes']
1153     cfg.od.stval1.st1val1.st2val1 = ['yes']
1154     assert cfg.getowner(st1val1) == owner
1155     assert cfg.getowner(st2val1, 0) == owner
1156     del(cfg.od.stval1.st1val1.st2val1)
1157     assert cfg.getowner(st1val1) == owner
1158     assert cfg.getowner(st1val2) == owners.default
1159     assert cfg.getowner(st2val1) == owners.default
1160     assert cfg.getowner(st2val2) == owners.default
1161     #
1162     cfg.od.stval1.st1val1.st1val1 = ['yes']
1163     cfg.od.stval1.st1val1.st2val1 = ['yes']
1164     del(cfg.od.stval1.st1val1.st1val1)
1165     assert cfg.od.stval1.st1val1.st1val1 == []
1166     assert cfg.od.stval1.st1val1.st2val1 == []
1167     assert cfg.od.stval2.st1val2.st1val2 == []
1168     assert cfg.od.stval2.st1val2.st2val2 == []
1169     assert cfg.getowner(st1val1) == owners.default
1170     assert cfg.getowner(st1val2) == owners.default
1171     assert cfg.getowner(st2val1) == owners.default
1172     assert cfg.getowner(st2val2) == owners.default
1173     #
1174     cfg.od.stval1.st1val1.st2val1 = []
1175     cfg.od.stval1.st1val1.st1val1 = ['yes']
1176     assert cfg.od.stval1.st1val1.st2val1 == ['yes']
1177
1178
1179 def test_masterslaves_callback_value_dyndescription():
1180     st1 = StrOption('st1', "", multi=True)
1181     st2 = StrOption('st2', "", multi=True, callback=return_dynval, callback_params={'value': ('val',)})
1182     stm = OptionDescription('st1', '', [st1, st2])
1183     stm.impl_set_group_type(groups.master)
1184     st = DynOptionDescription('st', '', [stm], callback=return_list)
1185     od = OptionDescription('od', '', [st])
1186     od2 = OptionDescription('od', '', [od])
1187     cfg = Config(od2)
1188     assert cfg.od.stval1.st1val1.st1val1 == []
1189     assert cfg.od.stval1.st1val1.st2val1 == []
1190     cfg.od.stval1.st1val1.st1val1.append('yes')
1191     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
1192     assert cfg.od.stval1.st1val1.st2val1[0] == 'val'
1193     assert cfg.od.stval1.st1val1.st2val1 == ['val']
1194
1195
1196 def test_masterslaves_callback_nomulti_dyndescription():
1197     v1 = StrOption('v1', '', "val")
1198     st1 = StrOption('st1', "", multi=True)
1199     st2 = StrOption('st2', "", multi=True, callback=return_dynval, callback_params={'': ((v1, False),)})
1200     stm = OptionDescription('st1', '', [st1, st2])
1201     stm.impl_set_group_type(groups.master)
1202     st = DynOptionDescription('st', '', [stm], callback=return_list)
1203     od = OptionDescription('od', '', [st])
1204     od2 = OptionDescription('od', '', [od, v1])
1205     cfg = Config(od2)
1206     assert cfg.od.stval1.st1val1.st1val1 == []
1207     assert cfg.od.stval1.st1val1.st2val1 == []
1208     cfg.od.stval1.st1val1.st1val1.append('yes')
1209     assert cfg.od.stval1.st1val1.st1val1 == ['yes']
1210     assert cfg.od.stval1.st1val1.st2val1 == ['val']
1211
1212
1213 def test_masterslaves_callback_samegroup_dyndescription():
1214     st1 = StrOption('st1', "", multi=True)
1215     st2 = StrOption('st2', "", multi=True)
1216     st3 = StrOption('st3', "", multi=True, callback=return_dynval, callback_params={'': ((st2, False),)})
1217     stm = OptionDescription('st1', '', [st1, st2, st3])
1218     stm.impl_set_group_type(groups.master)
1219     st = DynOptionDescription('st', '', [stm], callback=return_list)
1220     od = OptionDescription('od', '', [st])
1221     od2 = OptionDescription('od', '', [od])
1222     cfg = Config(od2)
1223     owner = cfg.cfgimpl_get_settings().getowner()
1224     st1val1 = cfg.unwrap_from_path('od.stval1.st1val1.st1val1')
1225     st2val1 = cfg.unwrap_from_path('od.stval1.st1val1.st2val1')
1226     st3val1 = cfg.unwrap_from_path('od.stval1.st1val1.st3val1')
1227     st1val2 = cfg.unwrap_from_path('od.stval2.st1val2.st1val2')
1228     st2val2 = cfg.unwrap_from_path('od.stval2.st1val2.st2val2')
1229     st3val2 = cfg.unwrap_from_path('od.stval2.st1val2.st3val2')
1230     assert cfg.make_dict() == {'od.stval1.st1val1.st1val1': [],
1231                                'od.stval1.st1val1.st2val1': [],
1232                                'od.stval1.st1val1.st3val1': [],
1233                                'od.stval2.st1val2.st1val2': [],
1234                                'od.stval2.st1val2.st2val2': [],
1235                                'od.stval2.st1val2.st3val2': []}
1236     assert cfg.od.stval1.st1val1.st1val1 == []
1237     assert cfg.od.stval1.st1val1.st2val1 == []
1238     assert cfg.od.stval1.st1val1.st3val1 == []
1239     assert cfg.od.stval2.st1val2.st1val2 == []
1240     assert cfg.od.stval2.st1val2.st2val2 == []
1241     assert cfg.od.stval2.st1val2.st3val2 == []
1242     assert cfg.getowner(st1val1) == owners.default
1243     assert cfg.getowner(st1val2) == owners.default
1244     assert cfg.getowner(st2val1) == owners.default
1245     assert cfg.getowner(st2val2) == owners.default
1246     assert cfg.getowner(st3val1) == owners.default
1247     assert cfg.getowner(st3val2) == owners.default
1248     ##
1249     cfg.od.stval1.st1val1.st1val1.append('yes')
1250     assert cfg.make_dict() == {'od.stval1.st1val1.st1val1': ['yes'],
1251                                'od.stval1.st1val1.st2val1': [None],
1252                                'od.stval1.st1val1.st3val1': [None],
1253                                'od.stval2.st1val2.st1val2': [],
1254                                'od.stval2.st1val2.st2val2': [],
1255                                'od.stval2.st1val2.st3val2': []}
1256     assert cfg.getowner(st1val1) == owner
1257     assert cfg.getowner(st1val2) == owners.default
1258     assert cfg.getowner(st2val1) == owners.default
1259     assert cfg.getowner(st2val2) == owners.default
1260     assert cfg.getowner(st3val1) == owners.default
1261     assert cfg.getowner(st3val2) == owners.default
1262     #
1263     cfg.od.stval1.st1val1.st2val1[0] = 'yes'
1264     assert cfg.make_dict() == {'od.stval1.st1val1.st1val1': ['yes'],
1265                                'od.stval1.st1val1.st2val1': ['yes'],
1266                                'od.stval1.st1val1.st3val1': ['yes'],
1267                                'od.stval2.st1val2.st1val2': [],
1268                                'od.stval2.st1val2.st2val2': [],
1269                                'od.stval2.st1val2.st3val2': []}
1270     assert cfg.getowner(st1val1) == owner
1271     assert cfg.getowner(st2val1, 0) == owner
1272     assert cfg.getowner(st3val1, 0) == owners.default
1273     assert cfg.getowner(st1val2) == owners.default
1274     #assert cfg.getowner(st2val2) == owners.default
1275     #assert cfg.getowner(st3val2) == owners.default
1276
1277
1278 def test_state_config():
1279     a = IPOption('a', '')
1280     b = NetmaskOption('b', '')
1281     dod1 = DynOptionDescription('dod1', '', [a, b], callback=return_list)
1282     b.impl_add_consistency('ip_netmask', a)
1283     od1 = OptionDescription('od1', '', [dod1])
1284     st1 = StrOption('st1', "", multi=True)
1285     st2 = StrOption('st2', "", multi=True)
1286     st3 = StrOption('st3', "", multi=True, callback=return_dynval, callback_params={'': ((st2, False),)})
1287     stm = OptionDescription('st1', '', [st1, st2, st3])
1288     stm.impl_set_group_type(groups.master)
1289     st = DynOptionDescription('st', '', [stm], callback=return_list)
1290     od = OptionDescription('od', '', [st])
1291     od2 = OptionDescription('od', '', [od, od1])
1292     try:
1293         cfg = Config(od2, persistent=True, session_id='29090938')
1294     except ValueError:
1295         cfg = Config(od2, session_id='29090938')
1296         cfg._impl_test = True
1297         a = dumps(cfg)
1298         q = loads(a)
1299         _diff_opts(cfg.cfgimpl_get_description(), q.cfgimpl_get_description())
1300         _diff_conf(cfg, q)
1301
1302     try:
1303         delete_session('config', '29090938')
1304     except ValueError:
1305         pass
1306
1307
1308 def test_invalid_conflict_dyndescription():
1309     st = StrOption('st', '')
1310     dod = DynOptionDescription('dod', '', [st], callback=return_list)
1311     dodinvalid = StrOption('dodinvalid', '')
1312     dod, dodinvalid
1313     raises(ConflictError, "OptionDescription('od', '', [dod, dodinvalid])")
1314
1315
1316 def test_invalid_subod_dyndescription():
1317     st2 = StrOption('st2', '')
1318     od1 = OptionDescription('od1', '', [st2])
1319     od1
1320     raises(ConfigError, "DynOptionDescription('dod', '', [od1], callback=return_list)")
1321
1322
1323 def test_invalid_subdynod_dyndescription():
1324     st2 = StrOption('st2', '')
1325     od1 = DynOptionDescription('od1', '', [st2], callback=return_list)
1326     od1
1327     raises(ConfigError, "DynOptionDescription('dod', '', [od1], callback=return_list)")
1328
1329
1330 def test_invalid_symlink_dyndescription():
1331     st = StrOption('st', '')
1332     st2 = SymLinkOption('st2', st)
1333     st2
1334     raises(ConfigError, "DynOptionDescription('dod', '', [st, st2], callback=return_list)")
1335
1336
1337 def test_nocallback_dyndescription():
1338     st = StrOption('st', '')
1339     st2 = StrOption('st2', '')
1340     st, st2
1341     raises(ConfigError, "DynOptionDescription('dod', '', [st, st2])")
1342
1343
1344 def test_invalid_samevalue_dyndescription():
1345     st = StrOption('st', '')
1346     dod = DynOptionDescription('dod', '', [st], callback=return_same_list)
1347     od = OptionDescription('od', '', [dod])
1348     cfg = Config(od)
1349     cfg
1350     raises(ConfigError, "print(cfg)")
1351
1352
1353 def test_invalid_name_dyndescription():
1354     st = StrOption('st', '')
1355     dod = DynOptionDescription('dod', '', [st], callback=return_wrong_list)
1356     od = OptionDescription('od', '', [dod])
1357     cfg = Config(od)
1358     cfg
1359     raises(ValueError, "print(cfg)")