Merge branch '2.0'
[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_in_config_1():
121     a = IntOption('a', '')
122     b = IntOption('b', '')
123     a.impl_add_consistency('not_equal', b)
124     od1 = OptionDescription('od1', '', [a])
125     od = OptionDescription('root', '', [od1])
126     od
127     raises(ConfigError, "Config(od)")
128
129
130 def test_consistency_not_in_config_2():
131     a = IntOption('a', '')
132     b = IntOption('b', '')
133     a.impl_add_consistency('not_equal', b)
134     od1 = OptionDescription('od1', '', [a])
135     od2 = OptionDescription('od2', '', [b])
136     od = OptionDescription('root', '', [od1, od2])
137     Config(od)
138
139
140 def test_consistency_not_in_config_3():
141     a = IntOption('a', '')
142     b = IntOption('b', '')
143     a.impl_add_consistency('not_equal', b)
144     od1 = OptionDescription('od1', '', [a])
145     od2 = OptionDescription('od2', '', [b])
146     od = OptionDescription('root', '', [od1, od2])
147     od
148     #with subconfig
149     raises(ConfigError, "Config(od.od1)")
150
151
152 def test_consistency_after_config():
153     a = IntOption('a', '')
154     b = IntOption('b', '')
155     od1 = OptionDescription('od1', '', [a])
156     od2 = OptionDescription('od2', '', [b])
157     od = OptionDescription('root', '', [od1, od2])
158     Config(od)
159     raises(AttributeError, "a.impl_add_consistency('not_equal', b)")
160
161
162 def test_consistency_not_equal_symlink():
163     a = IntOption('a', '')
164     b = IntOption('b', '')
165     c = SymLinkOption('c', a)
166     od = OptionDescription('od', '', [a, b, c])
167     a.impl_add_consistency('not_equal', b)
168     c = Config(od)
169     assert set(od._cache_consistencies.keys()) == set([a, b])
170
171
172 def test_consistency_not_equal_submulti():
173     a = IntOption('a', '', multi=submulti)
174     b = IntOption('b', '', multi=submulti)
175     od = OptionDescription('a', '', [a, b])
176     od.impl_set_group_type(groups.master)
177     raises(ConfigError, 'a.impl_add_consistency("not_equal", b)')
178
179
180 def test_consistency_not_equal_default_submulti():
181     a = IntOption('a', '', [[1, 2]], multi=submulti)
182     b = IntOption('b', '', [[1]], multi=submulti)
183     od = OptionDescription('od', '', [a, b])
184     od
185     raises(ConfigError, "a.impl_add_consistency('not_equal', b)")
186
187
188 def test_consistency_not_equal_multi():
189     a = IntOption('a', '', multi=True)
190     b = IntOption('b', '', multi=True)
191     od = OptionDescription('a', '', [a, b])
192     od.impl_set_group_type(groups.master)
193     a.impl_add_consistency('not_equal', b)
194     c = Config(od)
195     assert c.a == []
196     assert c.b == []
197     c.a = [1]
198     del(c.a)
199     c.a = [1]
200     raises(ValueError, "c.b = [1]")
201     c.b = [2]
202
203
204 def test_consistency_not_equal_multi_default():
205     a = IntOption('a', '', multi=True)
206     b = IntOption('b', '', multi=True, default_multi=1)
207     od = OptionDescription('a', '', [a, b])
208     od.impl_set_group_type(groups.master)
209     a.impl_add_consistency('not_equal', b)
210     c = Config(od)
211     assert c.a == []
212     assert c.b == []
213     raises(ValueError, 'c.a = [1]')
214     c.a = [2]
215     del(c.a)
216
217
218 def test_consistency_default():
219     a = IntOption('a', '', 1)
220     b = IntOption('b', '', 1)
221     a, b
222     raises(ValueError, "a.impl_add_consistency('not_equal', b)")
223
224
225 def test_consistency_default_multi():
226     a = IntOption('a', '', [2, 1], multi=True)
227     b = IntOption('b', '', [1, 1], multi=True)
228     c = IntOption('c', '', [1, 2], multi=True)
229     b
230     raises(ValueError, "a.impl_add_consistency('not_equal', b)")
231     a.impl_add_consistency('not_equal', c)
232
233
234 def test_consistency_default_diff():
235     a = IntOption('a', '', 3)
236     b = IntOption('b', '', 1)
237     od = OptionDescription('od', '', [a, b])
238     a.impl_add_consistency('not_equal', b)
239     c = Config(od)
240     raises(ValueError, "c.a = 1")
241     c.a = 2
242     c.b = 3
243     assert c.getowner(a) is owners.user
244     raises(ValueError, "del(c.a)")
245     assert c.getowner(a) is owners.user
246
247
248 def test_consistency_ip_netmask():
249     a = IPOption('a', '')
250     b = NetmaskOption('b', '')
251     od = OptionDescription('od', '', [a, b])
252     b.impl_add_consistency('ip_netmask', a)
253     c = Config(od)
254     c.a = '192.168.1.1'
255     c.b = '255.255.255.0'
256     c.a = '192.168.1.2'
257     c.b = '255.255.255.255'
258     c.b = '255.255.255.0'
259     raises(ValueError, "c.a = '192.168.1.0'")
260     raises(ValueError, "c.a = '192.168.1.255'")
261
262
263 def test_consistency_network_netmask():
264     a = NetworkOption('a', '')
265     b = NetmaskOption('b', '')
266     od = OptionDescription('od', '', [a, b])
267     b.impl_add_consistency('network_netmask', a)
268     c = Config(od)
269     c.a = '192.168.1.1'
270     c.b = '255.255.255.255'
271     del(c.b)
272     c.a = '192.168.1.0'
273     c.b = '255.255.255.0'
274     raises(ValueError, "c.a = '192.168.1.1'")
275
276
277 def test_consistency_ip_in_network():
278     a = NetworkOption('a', '')
279     b = NetmaskOption('b', '')
280     c = IPOption('c', '')
281     d = IPOption('d', '')
282     od = OptionDescription('od', '', [a, b, c, d])
283     c.impl_add_consistency('in_network', a, b)
284     d.impl_add_consistency('in_network', a, b, warnings_only=True)
285     warnings.simplefilter("always", ValueWarning)
286     cfg = Config(od)
287     cfg.a = '192.168.1.0'
288     cfg.b = '255.255.255.0'
289     cfg.c = '192.168.1.1'
290     raises(ValueError, "cfg.c = '192.168.2.1'")
291     raises(ValueError, "cfg.c = '192.168.1.0'")
292     raises(ValueError, "cfg.c = '192.168.1.255'")
293     with warnings.catch_warnings(record=True) as w:
294         cfg.d = '192.168.2.1'
295     assert len(w) == 1
296
297
298 def test_consistency_ip_in_network_len_error():
299     a = NetworkOption('a', '')
300     b = NetmaskOption('b', '')
301     c = IPOption('c', '')
302     od = OptionDescription('od', '', [a, b, c])
303     raises(ConfigError, "c.impl_add_consistency('in_network', a)")
304
305
306 def test_consistency_ip_netmask_network_error():
307     a = IPOption('a', '')
308     b = NetworkOption('b', '')
309     c = NetmaskOption('c', '')
310     od = OptionDescription('od', '', [a, b, c])
311     c.impl_add_consistency('ip_netmask', a, b)
312     c = Config(od)
313     c.a = '192.168.1.1'
314     c.b = '192.168.1.0'
315     raises(ConfigError, "c.c = '255.255.255.0'")
316
317
318 def test_consistency_ip_netmask_error_multi():
319     a = IPOption('a', '', multi=True)
320     b = NetmaskOption('b', '')
321     OptionDescription('od', '', [a, b])
322     raises(ConfigError, "b.impl_add_consistency('ip_netmask', a)")
323
324
325 def test_consistency_ip_netmask_multi():
326     a = IPOption('a', '', multi=True)
327     b = NetmaskOption('b', '', multi=True)
328     od = OptionDescription('a', '', [a, b])
329     b.impl_add_consistency('ip_netmask', a)
330     od.impl_set_group_type(groups.master)
331     c = Config(od)
332     c.a = ['192.168.1.1']
333     c.b = ['255.255.255.0']
334     c.a = ['192.168.1.2']
335     c.b = ['255.255.255.255']
336     c.b = ['255.255.255.0']
337     raises(ValueError, "c.a = ['192.168.1.0']")
338
339
340 def test_consistency_network_netmask_multi():
341     a = NetworkOption('a', '', multi=True)
342     b = NetmaskOption('b', '', multi=True)
343     od = OptionDescription('a', '', [a, b])
344     od.impl_set_group_type(groups.master)
345     b.impl_add_consistency('network_netmask', a)
346     c = Config(od)
347     c.a = ['192.168.1.1']
348     c.b = ['255.255.255.255']
349     del(c.b)
350     c.a = ['192.168.1.0']
351     c.b = ['255.255.255.0']
352     raises(ValueError, "c.a = ['192.168.1.1']")
353
354
355 def test_consistency_network_netmask_multi_slave_default_multi():
356     a = NetworkOption('a', '', default_multi=u'192.168.1.0', multi=True, properties=('mandatory',))
357     b = NetmaskOption('b', '', default_multi=u'255.255.255.0', multi=True, properties=('mandatory',))
358     od = OptionDescription('a', '', [a, b])
359     od.impl_set_group_type(groups.master)
360     b.impl_add_consistency('network_netmask', a)
361     c = Config(od)
362     c.read_write()
363     c.a.append()
364
365
366 def test_consistency_network_netmask_multi_slave_default():
367     a = NetworkOption('a', '', multi=True, properties=('mandatory',))
368     b = NetmaskOption('b', '', default_multi=u'255.255.255.0', multi=True, properties=('mandatory',))
369     od = OptionDescription('a', '', [a, b])
370     od.impl_set_group_type(groups.master)
371     b.impl_add_consistency('network_netmask', a)
372     c = Config(od)
373     c.read_write()
374     c.cfgimpl_get_settings().remove('cache')
375     assert c.a == []
376     assert c.b == []
377     c.a.append(u'192.168.1.0')
378     c.read_only()
379     assert c.a == [u'192.168.1.0']
380     assert c.b == [u'255.255.255.0']
381     c.read_write()
382     raises(ValueError, "c.a[0] = u'192.168.1.2'")
383     raises(ValueError, "c.a.append(u'192.168.1.1')")
384     raises(ValueError, "c.a = [u'192.168.1.0', u'192.168.1.1']")
385     c.a.append()
386     c.b = [u'255.255.255.0', u'255.255.255.255']
387     c.a = [u'192.168.1.0', u'192.168.1.1']
388
389
390 def return_netmask(*args, **kwargs):
391     return u'255.255.255.0'
392
393
394 def return_netmask2(master):
395     if master is not None:
396         if master.endswith('2.1'):
397             return u'255.255.255.0'
398         if not master.endswith('.0'):
399             return u'255.255.255.255'
400     return u'255.255.255.0'
401
402
403 def test_consistency_network_netmask_multi_slave_callback():
404     a = NetworkOption('a', '', multi=True, properties=('mandatory',))
405     b = NetmaskOption('b', '', callback=return_netmask, multi=True, properties=('mandatory',))
406     od = OptionDescription('a', '', [a, b])
407     od.impl_set_group_type(groups.master)
408     b.impl_add_consistency('network_netmask', a)
409     c = Config(od)
410     c.read_write()
411     c.cfgimpl_get_settings().remove('cache')
412     assert c.a == []
413     assert c.b == []
414     c.a.append(u'192.168.1.0')
415     c.read_only()
416     assert c.a == [u'192.168.1.0']
417     assert c.b == [u'255.255.255.0']
418     c.read_write()
419     raises(ValueError, "c.a[0] = u'192.168.1.2'")
420     raises(ValueError, "c.a.append(u'192.168.1.1')")
421     raises(ValueError, "c.a = [u'192.168.1.0', u'192.168.1.1']")
422     c.a.append()
423     c.b = [u'255.255.255.0', u'255.255.255.255']
424     c.a = [u'192.168.1.0', u'192.168.1.1']
425
426
427 def test_consistency_network_netmask_multi_slave_callback_value():
428     a = NetworkOption('a', '', multi=True, properties=('mandatory',))
429     b = NetmaskOption('b', '', callback=return_netmask2, callback_params={'': ((a, False),)}, multi=True, properties=('mandatory',))
430     od = OptionDescription('a', '', [a, b])
431     od.impl_set_group_type(groups.master)
432     b.impl_add_consistency('network_netmask', a)
433     c = Config(od)
434     c.read_write()
435     c.cfgimpl_get_settings().remove('cache')
436     assert c.a == []
437     assert c.b == []
438     c.a.append(u'192.168.1.0')
439     assert c.a == [u'192.168.1.0']
440     assert c.b == [u'255.255.255.0']
441     raises(ValueError, "c.a[0] = u'192.168.2.1'")
442     assert c.a == [u'192.168.1.0']
443     assert c.b == [u'255.255.255.0']
444     raises(ValueError, "c.a = [u'192.168.2.1']")
445     assert c.a == [u'192.168.1.0']
446     assert c.b == [u'255.255.255.0']
447     c.a.append(u'192.168.1.1')
448     c.a = [u'192.168.1.0', u'192.168.1.1']
449     c.b = [u'255.255.255.0', u'255.255.255.255']
450
451
452 def test_consistency_ip_netmask_multi_master():
453     a = IPOption('a', '', multi=True)
454     b = NetmaskOption('b', '', multi=True)
455     od = OptionDescription('a', '', [a, b])
456     od.impl_set_group_type(groups.master)
457     b.impl_add_consistency('ip_netmask', a)
458     c = Config(od)
459     c.a = ['192.168.1.1']
460     c.b = ['255.255.255.0']
461     c.a = ['192.168.1.2']
462     c.b = ['255.255.255.255']
463     c.b = ['255.255.255.0']
464     raises(ValueError, "c.a = ['192.168.1.0']")
465     c.a = ['192.168.1.128']
466     raises(ValueError, "c.b = ['255.255.255.128']")
467     c.a = ['192.168.1.2', '192.168.1.3']
468
469
470 def test_consistency_network_netmask_multi_master():
471     a = NetworkOption('a', '', multi=True)
472     b = NetmaskOption('b', '', multi=True)
473     od = OptionDescription('a', '', [a, b])
474     od.impl_set_group_type(groups.master)
475     b.impl_add_consistency('network_netmask', a)
476     c = Config(od)
477     c.a = ['192.168.1.1']
478     c.b = ['255.255.255.255']
479     del(c.b)
480     c.a = ['192.168.1.0']
481     c.b = ['255.255.255.0']
482     raises(ValueError, "c.a = ['192.168.1.1']")
483
484
485 def test_consistency_broadcast():
486     a = NetworkOption('a', '', multi=True)
487     b = NetmaskOption('b', '', multi=True)
488     c = BroadcastOption('c', '', multi=True)
489     od = OptionDescription('a', '', [a, b, c])
490     od.impl_set_group_type(groups.master)
491     b.impl_add_consistency('network_netmask', a)
492     c.impl_add_consistency('broadcast', a, b)
493     c = Config(od)
494     #first, test network_netmask
495     c.a = ['192.168.1.128']
496     raises(ValueError, "c.b = ['255.255.255.0']")
497     #
498     c.a = ['192.168.1.0']
499     c.b = ['255.255.255.0']
500     c.c = ['192.168.1.255']
501     raises(ValueError, "c.a = ['192.168.1.1']")
502     #
503     c.a = ['192.168.1.0', '192.168.2.128']
504     c.b = ['255.255.255.0', '255.255.255.128']
505     c.c = ['192.168.1.255', '192.168.2.255']
506     raises(ValueError, "c.c[1] = '192.168.2.128'")
507     c.c[1] = '192.168.2.255'
508
509
510 def test_consistency_broadcast_error():
511     a = NetworkOption('a', '', multi=True)
512     b = NetmaskOption('b', '', multi=True)
513     c = BroadcastOption('c', '', multi=True)
514     od = OptionDescription('a', '', [a, b, c])
515     od.impl_set_group_type(groups.master)
516     b.impl_add_consistency('network_netmask', a)
517     c.impl_add_consistency('broadcast', a)
518     c = Config(od)
519     raises(ConfigError, "c.a = ['192.168.1.0']")
520
521
522 def test_consistency_broadcast_default_1():
523     a = NetworkOption('a', '', '192.168.1.0')
524     b = NetmaskOption('b', '', '255.255.255.128')
525     c = BroadcastOption('c', '', '192.168.2.127')
526     od = OptionDescription('a', '', [a, b, c])
527     od
528     raises(ValueError, "c.impl_add_consistency('broadcast', a, b)")
529
530
531 def test_consistency_broadcast_default_2():
532     a = NetworkOption('a', '', '192.168.1.0')
533     b = NetmaskOption('b', '', '255.255.255.128')
534     d = BroadcastOption('d', '', '192.168.1.127')
535     od2 = OptionDescription('a', '', [a, b, d])
536     od2
537     d.impl_add_consistency('broadcast', a, b)
538
539
540 def test_consistency_not_all():
541     #_cache_consistencies is not None by not options has consistencies
542     a = NetworkOption('a', '', multi=True)
543     b = NetmaskOption('b', '', multi=True)
544     c = BroadcastOption('c', '', multi=True)
545     od = OptionDescription('a', '', [a, b, c])
546     od.impl_set_group_type(groups.master)
547     b.impl_add_consistency('network_netmask', a)
548     c = Config(od)
549     c.a = ['192.168.1.0']
550     c.b = ['255.255.255.0']
551     c.c = ['192.168.1.255']
552
553
554 def test_consistency_permissive():
555     a = IntOption('a', '', 1)
556     b = IntOption('b', '', 2, properties=('hidden',))
557     od = OptionDescription('od', '', [a, b])
558     a.impl_add_consistency('not_equal', b)
559     c = Config(od)
560     c.cfgimpl_get_settings().setpermissive(('hidden',))
561     c.read_write()
562     c.a = 1
563
564
565 def test_consistency_disabled():
566     a = IntOption('a', '')
567     b = IntOption('b', '', properties=('disabled',))
568     od = OptionDescription('od', '', [a, b])
569     a.impl_add_consistency('not_equal', b)
570     c = Config(od)
571     c.read_write()
572     raises(PropertiesOptionError, "c.a = 1")
573
574
575 def test_consistency_disabled_transitive():
576     a = IntOption('a', '')
577     b = IntOption('b', '', properties=('disabled',))
578     od = OptionDescription('od', '', [a, b])
579     a.impl_add_consistency('not_equal', b, transitive=False)
580     c = Config(od)
581     c.read_write()
582     c.a = 1
583
584
585 def test_consistency_disabled_transitive_2():
586     a = IPOption('a', '')
587     b = IPOption('b', '')
588     c = NetworkOption('c', '', default='192.168.1.0')
589     d = NetmaskOption('d', '', default='255.255.255.0', properties=('disabled',))
590     od = OptionDescription('od', '', [a, b, c, d])
591     a.impl_add_consistency('not_equal', b)
592     a.impl_add_consistency('in_network', c, d, transitive=False)
593     c = Config(od)
594     c.read_write()
595     c.a = '192.168.1.1'
596     raises(ValueError, "c.b = '192.168.1.1'")
597     c.a = '192.168.2.1'
598     #
599     c.a = '192.168.1.1'
600     c.cfgimpl_get_settings().remove('disabled')
601     raises(ValueError, "c.a = '192.168.2.1'")
602
603
604 def return_val(*args, **kwargs):
605     return '192.168.1.1'
606
607
608 def test_consistency_with_callback():
609     a = NetworkOption('a', '', default='192.168.1.0')
610     b = NetmaskOption('b', '', default='255.255.255.0')
611     c = IPOption('c', '', callback=return_val, callback_params={'': ((a, False),)})
612     od = OptionDescription('od', '', [a, b, c])
613     c.impl_add_consistency('in_network', a, b)
614     cfg = Config(od)
615     cfg.c