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