4590d4247b966363e76b285abacf4081ba6141cf
[tiramisu.git] / test / test_mandatory.py
1 # coding: utf-8
2 from autopath import do_autopath
3 do_autopath()
4
5 from py.test import raises
6 from tiramisu.config import Config
7 from tiramisu.option import IntOption, StrOption, UnicodeOption, OptionDescription, SymLinkOption
8 from tiramisu.error import PropertiesOptionError, ConfigError
9 from tiramisu.setting import groups
10
11
12 def make_description():
13     stroption = StrOption('str', 'Test string option', default="abc",
14                           properties=('mandatory', ))
15     stroption1 = StrOption('str1', 'Test string option',
16                            properties=('mandatory', ))
17     stroption2 = UnicodeOption('unicode2', 'Test string option',
18                                properties=('mandatory', ))
19     stroption3 = StrOption('str3', 'Test string option', multi=True,
20                            properties=('mandatory', ))
21     stroption4 = StrOption('str4', 'Test string option', multi=True,
22                            properties=('mandatory', ), allow_empty_list=True)
23     descr = OptionDescription('tiram', '', [stroption, stroption1, stroption2, stroption3, stroption4])
24     return descr
25
26
27 def return_value(value):
28     return value
29
30
31 def make_description2():
32     stroption = StrOption('str', 'Test string option', default="abc",
33                           properties=('mandatory', ))
34     stroption1 = StrOption('str1', 'Test string option',
35                            properties=('mandatory', ))
36     stroption2 = SymLinkOption('unicode2', stroption1)
37     stroption3 = StrOption('str3', 'Test string option', multi=True,
38                            properties=('mandatory', ))
39     unicode1 = UnicodeOption('unicode1', 'Test string option', callback=return_value, callback_params={'': ((stroption, False),)},  properties=('mandatory', ))
40     descr = OptionDescription('tiram', '', [stroption, stroption1, stroption2, stroption3, unicode1])
41     return descr
42
43
44 def make_description_sym():
45     stroption = StrOption('str', 'Test string option', default="abc",
46                           properties=('mandatory', ))
47     stroption1 = StrOption('str1', 'Test string option',
48                            properties=('mandatory', ))
49     stroption2 = SymLinkOption('unicode2', stroption1)
50     stroption3 = StrOption('str3', 'Test string option', multi=True,
51                            properties=('mandatory', ))
52     descr = OptionDescription('tiram', '', [stroption, stroption1, stroption2, stroption3])
53     return descr
54
55
56 def make_description3():
57     stroption = StrOption('str', 'Test string option', default="abc",
58                           properties=('mandatory', ))
59     stroption1 = StrOption('str1', 'Test string option',
60                            properties=('mandatory', ))
61     stroption2 = SymLinkOption('unicode2', stroption1)
62     stroption3 = StrOption('str3', 'Test string option', multi=True,
63                            properties=('mandatory', ))
64     unicode1 = UnicodeOption('unicode1', 'Test string option', callback=return_value, callback_params={'': ((stroption, False),)},  properties=('mandatory', ))
65     int1 = IntOption('int1', '', callback=return_value, callback_params={'': ((stroption, False),)},  properties=('mandatory', ))
66     descr = OptionDescription('tiram', '', [stroption, stroption1, stroption2, stroption3, unicode1, int1])
67     return descr
68
69
70 def make_description4():
71     stroption = StrOption('str', 'Test string option', default="abc",
72                           properties=('mandatory', ))
73     stroption1 = StrOption('str1', 'Test string option',
74                            properties=('mandatory', ))
75     stroption2 = UnicodeOption('unicode2', 'Test string option',
76                                properties=('mandatory', ))
77     stroption3 = StrOption('str3', 'Test string option', multi=True, requires=[{'option': stroption, 'expected': 'yes', 'action': 'mandatory', 'transitive': False}])
78     descr = OptionDescription('tiram', '', [stroption, stroption1, stroption2, stroption3])
79     return descr
80
81
82 def test_mandatory_ro():
83     descr = make_description()
84     config = Config(descr)
85     config.read_only()
86     prop = []
87     try:
88         config.str1
89     except PropertiesOptionError as err:
90         prop = err.proptype
91     assert 'mandatory' in prop
92     config.read_write()
93     config.str1 = 'yes'
94     config.read_only()
95     assert config.str1 == 'yes'
96
97
98 def test_mandatory_rw():
99     descr = make_description()
100     config = Config(descr)
101     config.read_write()
102     #not mandatory in rw
103     config.str1
104     config.str1 = 'yes'
105     assert config.str1 == 'yes'
106
107
108 def test_mandatory_default():
109     descr = make_description()
110     config = Config(descr)
111     config.read_only()
112     #not mandatory in rw
113     config.str
114     config.read_write()
115     config.str = 'yes'
116     config.read_only()
117     config.str
118     config.read_write()
119     config.str = None
120     config.read_only()
121     prop = []
122     try:
123         config.str
124     except PropertiesOptionError as err:
125         prop = err.proptype
126     assert 'mandatory' in prop
127
128
129 def test_mandatory_delete():
130     descr = make_description()
131     config = Config(descr)
132     config.read_only()
133     config.str
134     try:
135         config.str1
136     except PropertiesOptionError as err:
137         prop = err.proptype
138     assert 'mandatory' in prop
139     config.read_write()
140     config.str1 = 'yes'
141     config.read_only()
142     assert config.str1 == 'yes'
143     config.cfgimpl_get_settings().remove('frozen')
144     prop = []
145     try:
146         del(config.str1)
147     except PropertiesOptionError as err:
148         prop = err.proptype
149     assert 'mandatory' in prop
150     del(config.str)
151     assert config.str1 == 'yes'
152
153
154 #valeur vide : None, '', u'', ...
155 def test_mandatory_none():
156     descr = make_description()
157     config = Config(descr)
158     config.str1 = None
159     assert config.getowner(config.unwrap_from_path('str1')) == 'user'
160     config.read_only()
161     prop = []
162     try:
163         config.str1
164     except PropertiesOptionError as err:
165         prop = err.proptype
166     assert 'mandatory' in prop
167
168
169 def test_mandatory_empty():
170     descr = make_description()
171     config = Config(descr)
172     config.str1 = ''
173     assert config.getowner(config.unwrap_from_path('str1')) == 'user'
174     config.read_only()
175     prop = []
176     try:
177         config.str1
178     except PropertiesOptionError as err:
179         prop = err.proptype
180     assert 'mandatory' in prop
181
182
183 def test_mandatory_multi_none():
184     descr = make_description()
185     config = Config(descr)
186     config.str3 = [None]
187     assert config.getowner(config.unwrap_from_path('str3')) == 'user'
188     config.read_only()
189     prop = []
190     try:
191         config.str3
192     except PropertiesOptionError as err:
193         prop = err.proptype
194     assert 'mandatory' in prop
195     config.read_write()
196     config.str3 = ['yes', None]
197     assert config.getowner(config.unwrap_from_path('str3')) == 'user'
198     config.read_only()
199     prop = []
200     try:
201         config.str3
202     except PropertiesOptionError as err:
203         prop = err.proptype
204     assert 'mandatory' in prop
205
206
207 def test_mandatory_multi_empty():
208     descr = make_description()
209     config = Config(descr)
210     config.str3 = []
211     assert config.getowner(config.unwrap_from_path('str3')) == 'user'
212     config.read_only()
213     prop = []
214     try:
215         config.str3
216     except PropertiesOptionError as err:
217         prop = err.proptype
218     assert 'mandatory' in prop
219     #
220     config.read_write()
221     config.str3 = ['']
222     assert config.getowner(config.unwrap_from_path('str3')) == 'user'
223     config.read_only()
224     prop = []
225     try:
226         config.str3
227     except PropertiesOptionError as err:
228         prop = err.proptype
229     assert 'mandatory' in prop
230     #
231     config.read_write()
232     config.str3 = ['yes', '']
233     assert config.getowner(config.unwrap_from_path('str3')) == 'user'
234     config.read_only()
235     prop = []
236     try:
237         config.str3
238     except PropertiesOptionError as err:
239         prop = err.proptype
240     assert 'mandatory' in prop
241
242
243 def test_mandatory_multi_empty_allow_empty_list():
244     descr = make_description()
245     config = Config(descr)
246     config.str4 = []
247     assert config.getowner(config.unwrap_from_path('str4')) == 'user'
248     config.read_only()
249     prop = []
250     config.str4
251     #
252     config.read_write()
253     config.str4 = ['']
254     assert config.getowner(config.unwrap_from_path('str4')) == 'user'
255     config.read_only()
256     prop = []
257     try:
258         config.str4
259     except PropertiesOptionError as err:
260         prop = err.proptype
261     assert 'mandatory' in prop
262     #
263     config.read_write()
264     config.str4 = ['yes', '']
265     assert config.getowner(config.unwrap_from_path('str4')) == 'user'
266     config.read_only()
267     prop = []
268     try:
269         config.str4
270     except PropertiesOptionError as err:
271         prop = err.proptype
272     assert 'mandatory' in prop
273
274
275 def test_mandatory_multi_append():
276     descr = make_description()
277     config = Config(descr)
278     config.str3 = ['yes']
279     config.read_write()
280     config.str3.append(None)
281
282
283 def test_mandatory_disabled():
284     descr = make_description()
285     config = Config(descr)
286     setting = config.cfgimpl_get_settings()
287     config.str1
288     config.read_only()
289     prop = []
290     try:
291         config.str1
292     except PropertiesOptionError as err:
293         prop = err.proptype
294     assert prop == ['mandatory']
295     setting[descr.str1].append('disabled')
296     prop = []
297     try:
298         config.str1
299     except PropertiesOptionError as err:
300         prop = err.proptype
301     assert set(prop) == set(['disabled', 'mandatory'])
302
303
304 def test_mandatory_unicode():
305     descr = make_description()
306     config = Config(descr)
307     config.unicode2
308     config.read_only()
309     prop = []
310     try:
311         config.unicode2
312     except PropertiesOptionError as err:
313         prop = err.proptype
314     assert prop == ['mandatory']
315     config.read_write()
316     config.unicode2 = u''
317     config.read_only()
318     prop = []
319     try:
320         config.unicode2
321     except PropertiesOptionError as err:
322         prop = err.proptype
323     assert prop == ['mandatory']
324
325
326 def test_mandatory_warnings_ro():
327     descr = make_description()
328     config = Config(descr)
329     config.str = ''
330     config.read_only()
331     proc = []
332     try:
333         config.str
334     except PropertiesOptionError as err:
335         proc = err.proptype
336     assert proc == ['mandatory']
337     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3']
338     config.read_write()
339     config.str = 'a'
340     config.read_only()
341     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
342     assert list(config.cfgimpl_get_values().mandatory_warnings(force_permissive=True)) == ['str1', 'unicode2', 'str3']
343
344
345 def test_mandatory_warnings_rw():
346     descr = make_description()
347     config = Config(descr)
348     config.str = ''
349     config.read_write()
350     config.str
351     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3']
352     config.str = 'a'
353     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
354     assert list(config.cfgimpl_get_values().mandatory_warnings(force_permissive=True)) == ['str1', 'unicode2', 'str3']
355
356
357 def test_mandatory_warnings_disabled():
358     descr = make_description()
359     config = Config(descr)
360     config.str = ''
361     setting = config.cfgimpl_get_settings()
362     config.read_write()
363     config.str
364     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3']
365     setting[descr.str].append('disabled')
366     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
367     assert list(config.cfgimpl_get_values().mandatory_warnings(force_permissive=True)) == ['str1', 'unicode2', 'str3']
368
369
370 def test_mandatory_warnings_hidden():
371     descr = make_description()
372     config = Config(descr)
373     config.str = ''
374     setting = config.cfgimpl_get_settings()
375     config.read_write()
376     config.cfgimpl_get_settings().setpermissive(('hidden',))
377     config.str
378     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3']
379     setting[descr.str].append('hidden')
380     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
381     assert list(config.cfgimpl_get_values().mandatory_warnings(force_permissive=True)) == ['str', 'str1', 'unicode2', 'str3']
382
383
384 def test_mandatory_warnings_frozen():
385     descr = make_description()
386     config = Config(descr)
387     config.str = ''
388     setting = config.cfgimpl_get_settings()
389     config.read_write()
390     config.str
391     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3']
392     setting[descr.str].append('frozen')
393     config.read_only()
394     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3']
395
396
397 def test_mandatory_master():
398     ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True,
399                               properties=('mandatory', ))
400     netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau",
401                                    multi=True)
402     interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
403     interface1.impl_set_group_type(groups.master)
404     o = OptionDescription('o', '', [interface1])
405     config = Config(o)
406     config.read_only()
407     raises(PropertiesOptionError, 'config.ip_admin_eth0.ip_admin_eth0')
408     raises(PropertiesOptionError, 'config.ip_admin_eth0.netmask_admin_eth0')
409
410
411 def test_mandatory_master_empty():
412     ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
413     netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau",
414                                    multi=True)
415     interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
416     interface1.impl_set_group_type(groups.master)
417     o = OptionDescription('o', '', [interface1])
418     config = Config(o)
419     config.read_write()
420     assert config.ip_admin_eth0.ip_admin_eth0 == []
421     assert config.ip_admin_eth0.netmask_admin_eth0 == []
422     #
423     config.ip_admin_eth0.ip_admin_eth0.append()
424     assert config.ip_admin_eth0.ip_admin_eth0 == [None]
425     assert config.ip_admin_eth0.netmask_admin_eth0 == [None]
426     config.read_only()
427     raises(PropertiesOptionError, "config.ip_admin_eth0.ip_admin_eth0")
428     raises(PropertiesOptionError, "config.ip_admin_eth0.netmask_admin_eth0")
429     config.read_write()
430     del(config.ip_admin_eth0.ip_admin_eth0)
431     del(config.ip_admin_eth0.netmask_admin_eth0)
432     assert config.ip_admin_eth0.ip_admin_eth0 == []
433     assert config.ip_admin_eth0.netmask_admin_eth0 == []
434     #
435     config.ip_admin_eth0.ip_admin_eth0.append('')
436     assert config.ip_admin_eth0.ip_admin_eth0 == ['']
437     assert config.ip_admin_eth0.netmask_admin_eth0 == [None]
438     config.read_only()
439     raises(PropertiesOptionError, "config.ip_admin_eth0.ip_admin_eth0")
440     raises(PropertiesOptionError, "config.ip_admin_eth0.netmask_admin_eth0")
441     config.read_write()
442     #
443     config.read_write()
444     config.ip_admin_eth0.ip_admin_eth0 = ['ip']
445     config.read_only()
446     assert config.ip_admin_eth0.ip_admin_eth0 == ['ip']
447     assert config.ip_admin_eth0.netmask_admin_eth0 == [None]
448
449
450 def test_mandatory_slave():
451     ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
452     netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau",
453                                    multi=True, properties=('mandatory', ))
454     interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
455     interface1.impl_set_group_type(groups.master)
456     o = OptionDescription('o', '', [interface1])
457     config = Config(o)
458     config.read_only()
459     assert config.ip_admin_eth0.ip_admin_eth0 == []
460     assert config.ip_admin_eth0.netmask_admin_eth0 == []
461     #
462     config.read_write()
463     config.ip_admin_eth0.ip_admin_eth0.append('ip')
464     config.read_only()
465     assert config.ip_admin_eth0.ip_admin_eth0 == ['ip']
466     raises(PropertiesOptionError, 'config.ip_admin_eth0.netmask_admin_eth0')
467     #
468     config.read_write()
469     config.ip_admin_eth0.netmask_admin_eth0 = ['']
470     config.read_only()
471     assert config.ip_admin_eth0.ip_admin_eth0 == ['ip']
472     raises(PropertiesOptionError, 'config.ip_admin_eth0.netmask_admin_eth0')
473     #
474     config.read_write()
475     config.ip_admin_eth0.netmask_admin_eth0 = ['ip']
476     config.read_only()
477     assert config.ip_admin_eth0.ip_admin_eth0 == ['ip']
478     assert config.ip_admin_eth0.netmask_admin_eth0 == ['ip']
479
480
481 def test_mandatory_warnings_symlink():
482     descr = make_description_sym()
483     config = Config(descr)
484     config.str = ''
485     setting = config.cfgimpl_get_settings()
486     config.read_write()
487     config.str
488     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'str3']
489     setting[descr.str].append('frozen')
490     config.read_only()
491     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'str3']
492
493
494 def test_mandatory_warnings_validate():
495     descr = make_description3()
496     config = Config(descr)
497     config.str = ''
498     raises(ValueError, "list(config.cfgimpl_get_values().mandatory_warnings())")
499     assert list(config.cfgimpl_get_values().mandatory_warnings(validate=False)) == ['str', 'str1', 'str3', 'unicode1', 'int1']
500     config.str = 'test'
501     raises(ValueError, "list(config.cfgimpl_get_values().mandatory_warnings())")
502     assert list(config.cfgimpl_get_values().mandatory_warnings(validate=False)) == ['str1', 'str3']
503
504
505 def test_mandatory_warnings_validate_empty():
506     descr = make_description2()
507     config = Config(descr)
508     config.str = ''
509     config.read_only()
510     raises(ConfigError, "list(config.cfgimpl_get_values().mandatory_warnings())")
511     assert list(config.cfgimpl_get_values().mandatory_warnings(validate=False)) == ['str', 'str1', 'str3', 'unicode1']
512
513
514 def test_mandatory_warnings_requires():
515     descr = make_description4()
516     config = Config(descr)
517     config.str = ''
518     config.read_write()
519     config.str
520     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2']
521     config.read_only()
522     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2']
523     config.read_write()
524     config.str = 'yes'
525     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
526
527
528 def test_mandatory_od_disabled():
529     descr = make_description()
530     od = OptionDescription('od', '', [descr])
531     config = Config(od)
532     config.read_only()
533     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['tiram.str1', 'tiram.unicode2', 'tiram.str3']
534     config.cfgimpl_get_settings()[descr].append('disabled')
535     assert list(config.cfgimpl_get_values().mandatory_warnings()) == []