optimise mandatory_warnings
[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 #valeur vide : None, '', u'', ...
130 def test_mandatory_none():
131     descr = make_description()
132     config = Config(descr)
133     config.str1 = None
134     assert config.getowner(config.unwrap_from_path('str1')) == 'user'
135     config.read_only()
136     prop = []
137     try:
138         config.str1
139     except PropertiesOptionError as err:
140         prop = err.proptype
141     assert 'mandatory' in prop
142
143
144 def test_mandatory_empty():
145     descr = make_description()
146     config = Config(descr)
147     config.str1 = ''
148     assert config.getowner(config.unwrap_from_path('str1')) == 'user'
149     config.read_only()
150     prop = []
151     try:
152         config.str1
153     except PropertiesOptionError as err:
154         prop = err.proptype
155     assert 'mandatory' in prop
156
157
158 def test_mandatory_multi_none():
159     descr = make_description()
160     config = Config(descr)
161     config.str3 = [None]
162     assert config.getowner(config.unwrap_from_path('str3')) == 'user'
163     config.read_only()
164     prop = []
165     try:
166         config.str3
167     except PropertiesOptionError as err:
168         prop = err.proptype
169     assert 'mandatory' in prop
170     config.read_write()
171     config.str3 = ['yes', None]
172     assert config.getowner(config.unwrap_from_path('str3')) == 'user'
173     config.read_only()
174     prop = []
175     try:
176         config.str3
177     except PropertiesOptionError as err:
178         prop = err.proptype
179     assert 'mandatory' in prop
180
181
182 def test_mandatory_multi_empty():
183     descr = make_description()
184     config = Config(descr)
185     config.str3 = []
186     assert config.getowner(config.unwrap_from_path('str3')) == 'user'
187     config.read_only()
188     prop = []
189     try:
190         config.str3
191     except PropertiesOptionError as err:
192         prop = err.proptype
193     assert 'mandatory' in prop
194     #
195     config.read_write()
196     config.str3 = ['']
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     config.read_write()
207     config.str3 = ['yes', '']
208     assert config.getowner(config.unwrap_from_path('str3')) == 'user'
209     config.read_only()
210     prop = []
211     try:
212         config.str3
213     except PropertiesOptionError as err:
214         prop = err.proptype
215     assert 'mandatory' in prop
216
217
218 def test_mandatory_multi_empty_allow_empty_list():
219     descr = make_description()
220     config = Config(descr)
221     config.str4 = []
222     assert config.getowner(config.unwrap_from_path('str4')) == 'user'
223     config.read_only()
224     prop = []
225     config.str4
226     #
227     config.read_write()
228     config.str4 = ['']
229     assert config.getowner(config.unwrap_from_path('str4')) == 'user'
230     config.read_only()
231     prop = []
232     try:
233         config.str4
234     except PropertiesOptionError as err:
235         prop = err.proptype
236     assert 'mandatory' in prop
237     #
238     config.read_write()
239     config.str4 = ['yes', '']
240     assert config.getowner(config.unwrap_from_path('str4')) == 'user'
241     config.read_only()
242     prop = []
243     try:
244         config.str4
245     except PropertiesOptionError as err:
246         prop = err.proptype
247     assert 'mandatory' in prop
248
249
250 def test_mandatory_multi_append():
251     descr = make_description()
252     config = Config(descr)
253     config.str3 = ['yes']
254     config.read_write()
255     config.str3.append(None)
256
257
258 def test_mandatory_disabled():
259     descr = make_description()
260     config = Config(descr)
261     setting = config.cfgimpl_get_settings()
262     config.str1
263     config.read_only()
264     prop = []
265     try:
266         config.str1
267     except PropertiesOptionError as err:
268         prop = err.proptype
269     assert prop == ['mandatory']
270     setting[descr.str1].append('disabled')
271     prop = []
272     try:
273         config.str1
274     except PropertiesOptionError as err:
275         prop = err.proptype
276     assert set(prop) == set(['disabled', 'mandatory'])
277
278
279 def test_mandatory_unicode():
280     descr = make_description()
281     config = Config(descr)
282     config.unicode2
283     config.read_only()
284     prop = []
285     try:
286         config.unicode2
287     except PropertiesOptionError as err:
288         prop = err.proptype
289     assert prop == ['mandatory']
290     config.read_write()
291     config.unicode2 = u''
292     config.read_only()
293     prop = []
294     try:
295         config.unicode2
296     except PropertiesOptionError as err:
297         prop = err.proptype
298     assert prop == ['mandatory']
299
300
301 def test_mandatory_warnings_ro():
302     descr = make_description()
303     config = Config(descr)
304     config.str = ''
305     config.read_only()
306     proc = []
307     try:
308         config.str
309     except PropertiesOptionError as err:
310         proc = err.proptype
311     assert proc == ['mandatory']
312     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3']
313     config.read_write()
314     config.str = 'a'
315     config.read_only()
316     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
317     assert list(config.cfgimpl_get_values().mandatory_warnings(force_permissive=True)) == ['str1', 'unicode2', 'str3']
318
319
320 def test_mandatory_warnings_rw():
321     descr = make_description()
322     config = Config(descr)
323     config.str = ''
324     config.read_write()
325     config.str
326     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3']
327     config.str = 'a'
328     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
329     assert list(config.cfgimpl_get_values().mandatory_warnings(force_permissive=True)) == ['str1', 'unicode2', 'str3']
330
331
332 def test_mandatory_warnings_disabled():
333     descr = make_description()
334     config = Config(descr)
335     config.str = ''
336     setting = config.cfgimpl_get_settings()
337     config.read_write()
338     config.str
339     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3']
340     setting[descr.str].append('disabled')
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_hidden():
346     descr = make_description()
347     config = Config(descr)
348     config.str = ''
349     setting = config.cfgimpl_get_settings()
350     config.read_write()
351     config.cfgimpl_get_settings().setpermissive(('hidden',))
352     config.str
353     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3']
354     setting[descr.str].append('hidden')
355     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
356     assert list(config.cfgimpl_get_values().mandatory_warnings(force_permissive=True)) == ['str', 'str1', 'unicode2', 'str3']
357
358
359 def test_mandatory_warnings_frozen():
360     descr = make_description()
361     config = Config(descr)
362     config.str = ''
363     setting = config.cfgimpl_get_settings()
364     config.read_write()
365     config.str
366     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3']
367     setting[descr.str].append('frozen')
368     config.read_only()
369     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3']
370
371
372 def test_mandatory_master():
373     ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True,
374                               properties=('mandatory', ))
375     netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau",
376                                    multi=True)
377     interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
378     interface1.impl_set_group_type(groups.master)
379     o = OptionDescription('o', '', [interface1])
380     config = Config(o)
381     config.read_only()
382     raises(PropertiesOptionError, 'config.ip_admin_eth0.ip_admin_eth0')
383     raises(PropertiesOptionError, 'config.ip_admin_eth0.netmask_admin_eth0')
384
385
386 def test_mandatory_master_empty():
387     ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
388     netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau",
389                                    multi=True)
390     interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
391     interface1.impl_set_group_type(groups.master)
392     o = OptionDescription('o', '', [interface1])
393     config = Config(o)
394     config.read_write()
395     assert config.ip_admin_eth0.ip_admin_eth0 == []
396     assert config.ip_admin_eth0.netmask_admin_eth0 == []
397     #
398     config.ip_admin_eth0.ip_admin_eth0.append()
399     assert config.ip_admin_eth0.ip_admin_eth0 == [None]
400     assert config.ip_admin_eth0.netmask_admin_eth0 == [None]
401     config.read_only()
402     raises(PropertiesOptionError, "config.ip_admin_eth0.ip_admin_eth0")
403     raises(PropertiesOptionError, "config.ip_admin_eth0.netmask_admin_eth0")
404     config.read_write()
405     del(config.ip_admin_eth0.ip_admin_eth0)
406     del(config.ip_admin_eth0.netmask_admin_eth0)
407     assert config.ip_admin_eth0.ip_admin_eth0 == []
408     assert config.ip_admin_eth0.netmask_admin_eth0 == []
409     #
410     config.ip_admin_eth0.ip_admin_eth0.append('')
411     assert config.ip_admin_eth0.ip_admin_eth0 == ['']
412     assert config.ip_admin_eth0.netmask_admin_eth0 == [None]
413     config.read_only()
414     raises(PropertiesOptionError, "config.ip_admin_eth0.ip_admin_eth0")
415     raises(PropertiesOptionError, "config.ip_admin_eth0.netmask_admin_eth0")
416     config.read_write()
417     #
418     config.read_write()
419     config.ip_admin_eth0.ip_admin_eth0 = ['ip']
420     config.read_only()
421     assert config.ip_admin_eth0.ip_admin_eth0 == ['ip']
422     assert config.ip_admin_eth0.netmask_admin_eth0 == [None]
423
424
425 def test_mandatory_slave():
426     ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
427     netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau",
428                                    multi=True, properties=('mandatory', ))
429     interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
430     interface1.impl_set_group_type(groups.master)
431     o = OptionDescription('o', '', [interface1])
432     config = Config(o)
433     config.read_only()
434     assert config.ip_admin_eth0.ip_admin_eth0 == []
435     assert config.ip_admin_eth0.netmask_admin_eth0 == []
436     #
437     config.read_write()
438     config.ip_admin_eth0.ip_admin_eth0.append('ip')
439     config.read_only()
440     assert config.ip_admin_eth0.ip_admin_eth0 == ['ip']
441     raises(PropertiesOptionError, 'config.ip_admin_eth0.netmask_admin_eth0')
442     #
443     config.read_write()
444     config.ip_admin_eth0.netmask_admin_eth0 = ['']
445     config.read_only()
446     assert config.ip_admin_eth0.ip_admin_eth0 == ['ip']
447     raises(PropertiesOptionError, 'config.ip_admin_eth0.netmask_admin_eth0')
448     #
449     config.read_write()
450     config.ip_admin_eth0.netmask_admin_eth0 = ['ip']
451     config.read_only()
452     assert config.ip_admin_eth0.ip_admin_eth0 == ['ip']
453     assert config.ip_admin_eth0.netmask_admin_eth0 == ['ip']
454
455
456 def test_mandatory_warnings_symlink():
457     descr = make_description_sym()
458     config = Config(descr)
459     config.str = ''
460     setting = config.cfgimpl_get_settings()
461     config.read_write()
462     config.str
463     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3']
464     setting[descr.str].append('frozen')
465     config.read_only()
466     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3']
467
468
469 def test_mandatory_warnings_validate():
470     descr = make_description3()
471     config = Config(descr)
472     config.str = ''
473     raises(ValueError, "list(config.cfgimpl_get_values().mandatory_warnings())")
474     assert list(config.cfgimpl_get_values().mandatory_warnings(validate=False)) == ['str', 'str1', 'unicode2', 'str3', 'unicode1', 'int1']
475     config.str = 'test'
476     raises(ValueError, "list(config.cfgimpl_get_values().mandatory_warnings())")
477     assert list(config.cfgimpl_get_values().mandatory_warnings(validate=False)) == ['str1', 'unicode2', 'str3']
478
479
480 def test_mandatory_warnings_validate_empty():
481     descr = make_description2()
482     config = Config(descr)
483     config.str = ''
484     config.read_only()
485     raises(ConfigError, "list(config.cfgimpl_get_values().mandatory_warnings())")
486     assert list(config.cfgimpl_get_values().mandatory_warnings(validate=False)) == ['str', 'str1', 'unicode2', 'str3', 'unicode1']
487
488
489 def test_mandatory_warnings_requires():
490     descr = make_description4()
491     config = Config(descr)
492     config.str = ''
493     config.read_write()
494     config.str
495     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2']
496     config.read_only()
497     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2']
498     config.read_write()
499     config.str = 'yes'
500     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
501
502
503 def test_mandatory_od_disabled():
504     descr = make_description()
505     od = OptionDescription('od', '', [descr])
506     config = Config(od)
507     config.read_only()
508     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['tiram.str1', 'tiram.unicode2', 'tiram.str3']
509     config.cfgimpl_get_settings()[descr].append('disabled')
510     assert list(config.cfgimpl_get_values().mandatory_warnings()) == []