consistency is now check not_equal if one option has PropertiesOptionError
[tiramisu.git] / test / test_option_consistency.py
1 from autopath import do_autopath
2 do_autopath()
3
4 from py.test import raises
5
6 from tiramisu.setting import owners, groups
7 from tiramisu.config import Config
8 from tiramisu.option import IPOption, NetworkOption, NetmaskOption, IntOption,\
9     BroadcastOption, SymLinkOption, OptionDescription, submulti
10 from tiramisu.error import ConfigError, ValueWarning, PropertiesOptionError
11 import warnings
12
13
14 def test_consistency():
15     a = IntOption('a', '')
16     b = IntOption('b', '')
17     a.impl_add_consistency('not_equal', b)
18     #consistency to itself
19     raises(ConfigError, "a.impl_add_consistency('not_equal', a)")
20
21
22 def test_consistency_not_exists():
23     a = IntOption('a', '')
24     b = IntOption('b', '')
25     a, b
26     raises(ConfigError, "a.impl_add_consistency('not_exists', b)")
27
28
29 def test_consistency_unknown_params():
30     a = IntOption('a', '')
31     b = IntOption('b', '')
32     a, b
33     raises(ValueError, "a.impl_add_consistency('not_equal', b, unknown=False)")
34
35
36 def test_consistency_warnings_only_default():
37     a = IntOption('a', '', 1)
38     b = IntOption('b', '', 1)
39     warnings.simplefilter("always", ValueWarning)
40     with warnings.catch_warnings(record=True) as w:
41         a.impl_add_consistency('not_equal', b, warnings_only=True)
42     assert w != []
43
44
45 def test_consistency_warnings_only():
46     a = IntOption('a', '')
47     b = IntOption('b', '')
48     od = OptionDescription('od', '', [a, b])
49     a.impl_add_consistency('not_equal', b, warnings_only=True)
50     c = Config(od)
51     c.a = 1
52     warnings.simplefilter("always", ValueWarning)
53     with warnings.catch_warnings(record=True) as w:
54         c.b = 1
55     assert w != []
56
57
58 def test_consistency_warnings_only_more_option():
59     a = IntOption('a', '')
60     b = IntOption('b', '')
61     d = IntOption('d', '')
62     od = OptionDescription('od', '', [a, b, d])
63     a.impl_add_consistency('not_equal', b, d, warnings_only=True)
64     c = Config(od)
65     c.a = 1
66     warnings.simplefilter("always", ValueWarning)
67     with warnings.catch_warnings(record=True) as w:
68         c.b = 1
69     assert w != []
70     with warnings.catch_warnings(record=True) as w:
71         c.d = 1
72     assert w != []
73
74
75 def test_consistency_not_equal():
76     a = IntOption('a', '')
77     b = IntOption('b', '')
78     od = OptionDescription('od', '', [a, b])
79     a.impl_add_consistency('not_equal', b)
80     c = Config(od)
81     assert c.a is None
82     assert c.b is None
83     c.a = 1
84     del(c.a)
85     c.a = 1
86     raises(ValueError, "c.b = 1")
87     c.b = 2
88
89
90 def test_consistency_not_equal_many_opts():
91     a = IntOption('a', '')
92     b = IntOption('b', '')
93     c = IntOption('c', '')
94     d = IntOption('d', '')
95     e = IntOption('e', '')
96     f = IntOption('f', '')
97     od = OptionDescription('od', '', [a, b, c, d, e, f])
98     a.impl_add_consistency('not_equal', b, c, d, e, f)
99     c = Config(od)
100     assert c.a is None
101     assert c.b is None
102     #
103     c.a = 1
104     del(c.a)
105     #
106     c.a = 1
107     raises(ValueError, "c.b = 1")
108     #
109     c.b = 2
110     raises(ValueError, "c.f = 2")
111     raises(ValueError, "c.f = 1")
112     #
113     c.d = 3
114     raises(ValueError, "c.f = 3")
115     raises(ValueError, "c.a = 3")
116     raises(ValueError, "c.c = 3")
117     raises(ValueError, "c.e = 3")
118
119
120 def test_consistency_not_equal_many_opts_one_disabled():
121     a = IntOption('a', '')
122     b = IntOption('b', '')
123     c = IntOption('c', '')
124     d = IntOption('d', '')
125     e = IntOption('e', '')
126     f = IntOption('f', '')
127     g = IntOption('g', '', properties=('disabled',))
128     od = OptionDescription('od', '', [a, b, c, d, e, f, g])
129     a.impl_add_consistency('not_equal', b, c, d, e, f, g, transitive=False)
130     c = Config(od)
131     c.read_write()
132     assert c.a is None
133     assert c.b is None
134     #
135     c.a = 1
136     del(c.a)
137     #
138     c.a = 1
139     raises(ValueError, "c.b = 1")
140     #
141     c.b = 2
142     raises(ValueError, "c.f = 2")
143     raises(ValueError, "c.f = 1")
144     #
145     c.d = 3
146     raises(ValueError, "c.f = 3")
147     raises(ValueError, "c.a = 3")
148     raises(ValueError, "c.c = 3")
149     raises(ValueError, "c.e = 3")
150
151
152 def test_consistency_not_in_config_1():
153     a = IntOption('a', '')
154     b = IntOption('b', '')
155     a.impl_add_consistency('not_equal', b)
156     od1 = OptionDescription('od1', '', [a])
157     od = OptionDescription('root', '', [od1])
158     od
159     raises(ConfigError, "Config(od)")
160
161
162 def test_consistency_not_in_config_2():
163     a = IntOption('a', '')
164     b = IntOption('b', '')
165     a.impl_add_consistency('not_equal', b)
166     od1 = OptionDescription('od1', '', [a])
167     od2 = OptionDescription('od2', '', [b])
168     od = OptionDescription('root', '', [od1, od2])
169     Config(od)
170
171
172 def test_consistency_not_in_config_3():
173     a = IntOption('a', '')
174     b = IntOption('b', '')
175     a.impl_add_consistency('not_equal', b)
176     od1 = OptionDescription('od1', '', [a])
177     od2 = OptionDescription('od2', '', [b])
178     od = OptionDescription('root', '', [od1, od2])
179     od
180     #with subconfig
181     raises(ConfigError, "Config(od.od1)")
182
183
184 def test_consistency_after_config():
185     a = IntOption('a', '')
186     b = IntOption('b', '')
187     od1 = OptionDescription('od1', '', [a])
188     od2 = OptionDescription('od2', '', [b])
189     od = OptionDescription('root', '', [od1, od2])
190     Config(od)
191     raises(AttributeError, "a.impl_add_consistency('not_equal', b)")
192
193
194 def test_consistency_not_equal_symlink():
195     a = IntOption('a', '')
196     b = IntOption('b', '')
197     c = SymLinkOption('c', a)
198     od = OptionDescription('od', '', [a, b, c])
199     a.impl_add_consistency('not_equal', b)
200     c = Config(od)
201     assert set(od._cache_consistencies.keys()) == set([a, b])
202
203
204 def test_consistency_not_equal_submulti():
205     a = IntOption('a', '', multi=submulti)
206     b = IntOption('b', '', multi=submulti)
207     od = OptionDescription('a', '', [a, b])
208     od.impl_set_group_type(groups.master)
209     raises(ConfigError, 'a.impl_add_consistency("not_equal", b)')
210
211
212 def test_consistency_not_equal_default_submulti():
213     a = IntOption('a', '', [[1, 2]], multi=submulti)
214     b = IntOption('b', '', [[1]], multi=submulti)
215     od = OptionDescription('od', '', [a, b])
216     od
217     raises(ConfigError, "a.impl_add_consistency('not_equal', b)")
218
219
220 def test_consistency_not_equal_multi():
221     a = IntOption('a', '', multi=True)
222     b = IntOption('b', '', multi=True)
223     od = OptionDescription('a', '', [a, b])
224     od.impl_set_group_type(groups.master)
225     a.impl_add_consistency('not_equal', b)
226     c = Config(od)
227     assert c.a == []
228     assert c.b == []
229     c.a = [1]
230     del(c.a)
231     c.a = [1]
232     raises(ValueError, "c.b = [1]")
233     c.b = [2]
234
235
236 def test_consistency_not_equal_multi_default():
237     a = IntOption('a', '', multi=True)
238     b = IntOption('b', '', multi=True, default_multi=1)
239     od = OptionDescription('a', '', [a, b])
240     od.impl_set_group_type(groups.master)
241     a.impl_add_consistency('not_equal', b)
242     c = Config(od)
243     assert c.a == []
244     assert c.b == []
245     raises(ValueError, 'c.a = [1]')
246     c.a = [2]
247     del(c.a)
248
249
250 def test_consistency_default():
251     a = IntOption('a', '', 1)
252     b = IntOption('b', '', 1)
253     a, b
254     raises(ValueError, "a.impl_add_consistency('not_equal', b)")
255
256
257 def test_consistency_default_multi():
258     a = IntOption('a', '', [2, 1], multi=True)
259     b = IntOption('b', '', [1, 1], multi=True)
260     c = IntOption('c', '', [1, 2], multi=True)
261     b
262     raises(ValueError, "a.impl_add_consistency('not_equal', b)")
263     a.impl_add_consistency('not_equal', c)
264
265
266 def test_consistency_default_diff():
267     a = IntOption('a', '', 3)
268     b = IntOption('b', '', 1)
269     od = OptionDescription('od', '', [a, b])
270     a.impl_add_consistency('not_equal', b)
271     c = Config(od)
272     raises(ValueError, "c.a = 1")
273     c.a = 2
274     c.b = 3
275     assert c.getowner(a) is owners.user
276     raises(ValueError, "del(c.a)")
277     assert c.getowner(a) is owners.user
278
279
280 def test_consistency_ip_netmask():
281     a = IPOption('a', '')
282     b = NetmaskOption('b', '')
283     od = OptionDescription('od', '', [a, b])
284     b.impl_add_consistency('ip_netmask', a)
285     c = Config(od)
286     c.a = '192.168.1.1'
287     c.b = '255.255.255.0'
288     c.a = '192.168.1.2'
289     c.b = '255.255.255.255'
290     c.b = '255.255.255.0'
291     raises(ValueError, "c.a = '192.168.1.0'")
292     raises(ValueError, "c.a = '192.168.1.255'")
293
294
295 def test_consistency_network_netmask():
296     a = NetworkOption('a', '')
297     b = NetmaskOption('b', '')
298     od = OptionDescription('od', '', [a, b])
299     b.impl_add_consistency('network_netmask', a)
300     c = Config(od)
301     c.a = '192.168.1.1'
302     c.b = '255.255.255.255'
303     del(c.b)
304     c.a = '192.168.1.0'
305     c.b = '255.255.255.0'
306     raises(ValueError, "c.a = '192.168.1.1'")
307
308
309 def test_consistency_ip_in_network():
310     a = NetworkOption('a', '')
311     b = NetmaskOption('b', '')
312     c = IPOption('c', '')
313     d = IPOption('d', '')
314     od = OptionDescription('od', '', [a, b, c, d])
315     c.impl_add_consistency('in_network', a, b)
316     d.impl_add_consistency('in_network', a, b, warnings_only=True)
317     warnings.simplefilter("always", ValueWarning)
318     cfg = Config(od)
319     cfg.a = '192.168.1.0'
320     cfg.b = '255.255.255.0'
321     cfg.c = '192.168.1.1'
322     raises(ValueError, "cfg.c = '192.168.2.1'")
323     raises(ValueError, "cfg.c = '192.168.1.0'")
324     raises(ValueError, "cfg.c = '192.168.1.255'")
325     with warnings.catch_warnings(record=True) as w:
326         cfg.d = '192.168.2.1'
327     assert len(w) == 1
328
329
330 def test_consistency_ip_in_network_len_error():
331     a = NetworkOption('a', '')
332     b = NetmaskOption('b', '')
333     c = IPOption('c', '')
334     od = OptionDescription('od', '', [a, b, c])
335     raises(ConfigError, "c.impl_add_consistency('in_network', a)")
336
337
338 def test_consistency_ip_netmask_network_error():
339     a = IPOption('a', '')
340     b = NetworkOption('b', '')
341     c = NetmaskOption('c', '')
342     od = OptionDescription('od', '', [a, b, c])
343     c.impl_add_consistency('ip_netmask', a, b)
344     c = Config(od)
345     c.a = '192.168.1.1'
346     c.b = '192.168.1.0'
347     raises(ConfigError, "c.c = '255.255.255.0'")
348
349
350 def test_consistency_ip_netmask_error_multi():
351     a = IPOption('a', '', multi=True)
352     b = NetmaskOption('b', '')
353     OptionDescription('od', '', [a, b])
354     raises(ConfigError, "b.impl_add_consistency('ip_netmask', a)")
355
356
357 def test_consistency_ip_netmask_multi():
358     a = IPOption('a', '', multi=True)
359     b = NetmaskOption('b', '', multi=True)
360     od = OptionDescription('a', '', [a, b])
361     b.impl_add_consistency('ip_netmask', a)
362     od.impl_set_group_type(groups.master)
363     c = Config(od)
364     c.a = ['192.168.1.1']
365     c.b = ['255.255.255.0']
366     c.a = ['192.168.1.2']
367     c.b = ['255.255.255.255']
368     c.b = ['255.255.255.0']
369     raises(ValueError, "c.a = ['192.168.1.0']")
370
371
372 def test_consistency_network_netmask_multi():
373     a = NetworkOption('a', '', multi=True)
374     b = NetmaskOption('b', '', multi=True)
375     od = OptionDescription('a', '', [a, b])
376     od.impl_set_group_type(groups.master)
377     b.impl_add_consistency('network_netmask', a)
378     c = Config(od)
379     c.a = ['192.168.1.1']
380     c.b = ['255.255.255.255']
381     del(c.b)
382     c.a = ['192.168.1.0']
383     c.b = ['255.255.255.0']
384     raises(ValueError, "c.a = ['192.168.1.1']")
385
386
387 def test_consistency_network_netmask_multi_slave_default_multi():
388     a = NetworkOption('a', '', default_multi=u'192.168.1.0', multi=True, properties=('mandatory',))
389     b = NetmaskOption('b', '', default_multi=u'255.255.255.0', multi=True, properties=('mandatory',))
390     od = OptionDescription('a', '', [a, b])
391     od.impl_set_group_type(groups.master)
392     b.impl_add_consistency('network_netmask', a)
393     c = Config(od)
394     c.read_write()
395     c.a.append()
396
397
398 def test_consistency_network_netmask_multi_slave_default():
399     a = NetworkOption('a', '', multi=True, properties=('mandatory',))
400     b = NetmaskOption('b', '', default_multi=u'255.255.255.0', multi=True, properties=('mandatory',))
401     od = OptionDescription('a', '', [a, b])
402     od.impl_set_group_type(groups.master)
403     b.impl_add_consistency('network_netmask', a)
404     c = Config(od)
405     c.read_write()
406     c.cfgimpl_get_settings().remove('cache')
407     assert c.a == []
408     assert c.b == []
409     c.a.append(u'192.168.1.0')
410     c.read_only()
411     assert c.a == [u'192.168.1.0']
412     assert c.b == [u'255.255.255.0']
413     c.read_write()
414     raises(ValueError, "c.a[0] = u'192.168.1.2'")
415     raises(ValueError, "c.a.append(u'192.168.1.1')")
416     raises(ValueError, "c.a = [u'192.168.1.0', u'192.168.1.1']")
417     c.a.append()
418     c.b = [u'255.255.255.0', u'255.255.255.255']
419     c.a = [u'192.168.1.0', u'192.168.1.1']
420
421
422 def return_netmask(*args, **kwargs):
423     return u'255.255.255.0'
424
425
426 def return_netmask2(master):
427     if master is not None:
428         if master.endswith('2.1'):
429             return u'255.255.255.0'
430         if not master.endswith('.0'):
431             return u'255.255.255.255'
432     return u'255.255.255.0'
433
434
435 def test_consistency_network_netmask_multi_slave_callback():
436     a = NetworkOption('a', '', multi=True, properties=('mandatory',))
437     b = NetmaskOption('b', '', callback=return_netmask, multi=True, properties=('mandatory',))
438     od = OptionDescription('a', '', [a, b])
439     od.impl_set_group_type(groups.master)
440     b.impl_add_consistency('network_netmask', a)
441     c = Config(od)
442     c.read_write()
443     c.cfgimpl_get_settings().remove('cache')
444     assert c.a == []
445     assert c.b == []
446     c.a.append(u'192.168.1.0')
447     c.read_only()
448     assert c.a == [u'192.168.1.0']
449     assert c.b == [u'255.255.255.0']
450     c.read_write()
451     raises(ValueError, "c.a[0] = u'192.168.1.2'")
452     raises(ValueError, "c.a.append(u'192.168.1.1')")
453     raises(ValueError, "c.a = [u'192.168.1.0', u'192.168.1.1']")
454     c.a.append()
455     c.b = [u'255.255.255.0', u'255.255.255.255']
456     c.a = [u'192.168.1.0', u'192.168.1.1']
457
458
459 def test_consistency_network_netmask_multi_slave_callback_value():
460     a = NetworkOption('a', '', multi=True, properties=('mandatory',))
461     b = NetmaskOption('b', '', callback=return_netmask2, callback_params={'': ((a, False),)}, multi=True, properties=('mandatory',))
462     od = OptionDescription('a', '', [a, b])
463     od.impl_set_group_type(groups.master)
464     b.impl_add_consistency('network_netmask', a)
465     c = Config(od)
466     c.read_write()
467     c.cfgimpl_get_settings().remove('cache')
468     assert c.a == []
469     assert c.b == []
470     c.a.append(u'192.168.1.0')
471     assert c.a == [u'192.168.1.0']
472     assert c.b == [u'255.255.255.0']
473     raises(ValueError, "c.a[0] = u'192.168.2.1'")
474     assert c.a == [u'192.168.1.0']
475     assert c.b == [u'255.255.255.0']
476     raises(ValueError, "c.a = [u'192.168.2.1']")
477     assert c.a == [u'192.168.1.0']
478     assert c.b == [u'255.255.255.0']
479     c.a.append(u'192.168.1.1')
480     c.a = [u'192.168.1.0', u'192.168.1.1']
481     c.b = [u'255.255.255.0', u'255.255.255.255']
482
483
484 def test_consistency_ip_netmask_multi_master():
485     a = IPOption('a', '', multi=True)
486     b = NetmaskOption('b', '', multi=True)
487     od = OptionDescription('a', '', [a, b])
488     od.impl_set_group_type(groups.master)
489     b.impl_add_consistency('ip_netmask', a)
490     c = Config(od)
491     c.a = ['192.168.1.1']
492     c.b = ['255.255.255.0']
493     c.a = ['192.168.1.2']
494     c.b = ['255.255.255.255']
495     c.b = ['255.255.255.0']
496     raises(ValueError, "c.a = ['192.168.1.0']")
497     c.a = ['192.168.1.128']
498     raises(ValueError, "c.b = ['255.255.255.128']")
499     c.a = ['192.168.1.2', '192.168.1.3']
500
501
502 def test_consistency_network_netmask_multi_master():
503     a = NetworkOption('a', '', multi=True)
504     b = NetmaskOption('b', '', multi=True)
505     od = OptionDescription('a', '', [a, b])
506     od.impl_set_group_type(groups.master)
507     b.impl_add_consistency('network_netmask', a)
508     c = Config(od)
509     c.a = ['192.168.1.1']
510     c.b = ['255.255.255.255']
511     del(c.b)
512     c.a = ['192.168.1.0']
513     c.b = ['255.255.255.0']
514     raises(ValueError, "c.a = ['192.168.1.1']")
515
516
517 def test_consistency_broadcast():
518     a = NetworkOption('a', '', multi=True)
519     b = NetmaskOption('b', '', multi=True)
520     c = BroadcastOption('c', '', multi=True)
521     od = OptionDescription('a', '', [a, b, c])
522     od.impl_set_group_type(groups.master)
523     b.impl_add_consistency('network_netmask', a)
524     c.impl_add_consistency('broadcast', a, b)
525     c = Config(od)
526     #first, test network_netmask
527     c.a = ['192.168.1.128']
528     raises(ValueError, "c.b = ['255.255.255.0']")
529     #
530     c.a = ['192.168.1.0']
531     c.b = ['255.255.255.0']
532     c.c = ['192.168.1.255']
533     raises(ValueError, "c.a = ['192.168.1.1']")
534     #
535     c.a = ['192.168.1.0', '192.168.2.128']
536     c.b = ['255.255.255.0', '255.255.255.128']
537     c.c = ['192.168.1.255', '192.168.2.255']
538     raises(ValueError, "c.c[1] = '192.168.2.128'")
539     c.c[1] = '192.168.2.255'
540
541
542 def test_consistency_broadcast_error():
543     a = NetworkOption('a', '', multi=True)
544     b = NetmaskOption('b', '', multi=True)
545     c = BroadcastOption('c', '', multi=True)
546     od = OptionDescription('a', '', [a, b, c])
547     od.impl_set_group_type(groups.master)
548     b.impl_add_consistency('network_netmask', a)
549     c.impl_add_consistency('broadcast', a)
550     c = Config(od)
551     raises(ConfigError, "c.a = ['192.168.1.0']")
552
553
554 def test_consistency_broadcast_default_1():
555     a = NetworkOption('a', '', '192.168.1.0')
556     b = NetmaskOption('b', '', '255.255.255.128')
557     c = BroadcastOption('c', '', '192.168.2.127')
558     od = OptionDescription('a', '', [a, b, c])
559     od
560     raises(ValueError, "c.impl_add_consistency('broadcast', a, b)")
561
562
563 def test_consistency_broadcast_default_2():
564     a = NetworkOption('a', '', '192.168.1.0')
565     b = NetmaskOption('b', '', '255.255.255.128')
566     d = BroadcastOption('d', '', '192.168.1.127')
567     od2 = OptionDescription('a', '', [a, b, d])
568     od2
569     d.impl_add_consistency('broadcast', a, b)
570
571
572 def test_consistency_not_all():
573     #_cache_consistencies is not None by not options has consistencies
574     a = NetworkOption('a', '', multi=True)
575     b = NetmaskOption('b', '', multi=True)
576     c = BroadcastOption('c', '', multi=True)
577     od = OptionDescription('a', '', [a, b, c])
578     od.impl_set_group_type(groups.master)
579     b.impl_add_consistency('network_netmask', a)
580     c = Config(od)
581     c.a = ['192.168.1.0']
582     c.b = ['255.255.255.0']
583     c.c = ['192.168.1.255']
584
585
586 def test_consistency_permissive():
587     a = IntOption('a', '', 1)
588     b = IntOption('b', '', 2, properties=('hidden',))
589     od = OptionDescription('od', '', [a, b])
590     a.impl_add_consistency('not_equal', b)
591     c = Config(od)
592     c.cfgimpl_get_settings().setpermissive(('hidden',))
593     c.read_write()
594     c.a = 1
595
596
597 def test_consistency_disabled():
598     a = IntOption('a', '')
599     b = IntOption('b', '', properties=('disabled',))
600     od = OptionDescription('od', '', [a, b])
601     a.impl_add_consistency('not_equal', b)
602     c = Config(od)
603     c.read_write()
604     raises(PropertiesOptionError, "c.a = 1")
605
606
607 def test_consistency_disabled_transitive():
608     a = IntOption('a', '')
609     b = IntOption('b', '', properties=('disabled',))
610     od = OptionDescription('od', '', [a, b])
611     a.impl_add_consistency('not_equal', b, transitive=False)
612     c = Config(od)
613     c.read_write()
614     c.a = 1
615
616
617 def test_consistency_disabled_transitive_2():
618     a = IPOption('a', '')
619     b = IPOption('b', '')
620     c = NetworkOption('c', '', default='192.168.1.0')
621     d = NetmaskOption('d', '', default='255.255.255.0', properties=('disabled',))
622     od = OptionDescription('od', '', [a, b, c, d])
623     a.impl_add_consistency('not_equal', b)
624     a.impl_add_consistency('in_network', c, d, transitive=False)
625     c = Config(od)
626     c.read_write()
627     c.a = '192.168.1.1'
628     raises(ValueError, "c.b = '192.168.1.1'")
629     c.a = '192.168.2.1'
630     #
631     c.a = '192.168.1.1'
632     c.cfgimpl_get_settings().remove('disabled')
633     raises(ValueError, "c.a = '192.168.2.1'")
634
635
636 def return_val(*args, **kwargs):
637     return '192.168.1.1'
638
639
640 def test_consistency_with_callback():
641     a = NetworkOption('a', '', default='192.168.1.0')
642     b = NetmaskOption('b', '', default='255.255.255.0')
643     c = IPOption('c', '', callback=return_val, callback_params={'': ((a, False),)})
644     od = OptionDescription('od', '', [a, b, c])
645     c.impl_add_consistency('in_network', a, b)
646     cfg = Config(od)
647     cfg.c