separate baseoption and option
[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     raises(ConfigError, 'a.impl_add_consistency("not_equal", b)')
219
220
221 def test_consistency_not_equal_default_submulti():
222     a = IntOption('a', '', [[1, 2]], multi=submulti)
223     b = IntOption('b', '', [[1]], multi=submulti)
224     od = OptionDescription('od', '', [a, b])
225     od
226     raises(ConfigError, "a.impl_add_consistency('not_equal', b)")
227
228
229 def test_consistency_not_equal_masterslave():
230     a = IntOption('a', '', multi=True)
231     b = IntOption('b', '', multi=True)
232     od = OptionDescription('a', '', [a, b])
233     od.impl_set_group_type(groups.master)
234     a.impl_add_consistency('not_equal', b)
235     c = Config(od)
236     assert c.a == []
237     assert c.b == []
238     c.a = [1]
239     del(c.a)
240     c.a = [1]
241     raises(ValueError, "c.b = [1]")
242     c.b = [2]
243     del(c.a)
244     c.a.append(1)
245     c.make_dict()
246     c.b[0] = 3
247     c.a.append(2)
248     c.b[0] = 3
249     raises(ValueError, "c.b[1] = 3")
250
251
252 def test_consistency_not_equal_masterslave_error_multi1():
253     a = IPOption('a', '', multi=True)
254     b = NetmaskOption('b', '', multi=True)
255     c = NetmaskOption('c', '', multi=True)
256     od = OptionDescription('a', '', [a, b])
257     od.impl_set_group_type(groups.master)
258     od2 = OptionDescription('b', '', [od, c])
259     c.impl_add_consistency('ip_netmask', a)
260     raises(ConfigError, "Config(od2)")
261
262
263 def test_consistency_not_equal_masterslave_error_multi2():
264     a = IPOption('a', '', multi=True)
265     b = NetmaskOption('b', '', multi=True)
266     c = IPOption('c', '', multi=True)
267     od = OptionDescription('a', '', [a, b])
268     od.impl_set_group_type(groups.master)
269     od2 = OptionDescription('b', '', [od, c])
270     b.impl_add_consistency('ip_netmask', c)
271     raises(ConfigError, "Config(od2)")
272
273
274 def test_consistency_not_equal_masterslave_error_othermaster():
275     a = IPOption('a', '', multi=True)
276     b = NetmaskOption('b', '', multi=True)
277     c = IPOption('c', '', multi=True)
278     d = NetmaskOption('d', '', multi=True)
279     od = OptionDescription('a', '', [a, b])
280     od.impl_set_group_type(groups.master)
281     od2 = OptionDescription('c', '', [c, d])
282     od2.impl_set_group_type(groups.master)
283     od3 = OptionDescription('b', '', [od, od2])
284     d.impl_add_consistency('ip_netmask', a)
285     raises(ConfigError, "Config(od2)")
286
287
288 def test_consistency_not_equal_masterslaves_default():
289     a = IntOption('a', '', multi=True)
290     b = IntOption('b', '', multi=True, default_multi=1)
291     od = OptionDescription('a', '', [a, b])
292     od.impl_set_group_type(groups.master)
293     a.impl_add_consistency('not_equal', b)
294     c = Config(od)
295     assert c.a == []
296     assert c.b == []
297     raises(ValueError, 'c.a = [1]')
298     c.a = [2]
299     del(c.a)
300
301
302 def test_consistency_not_equal_multi():
303     a = IntOption('a', '', multi=True)
304     b = IntOption('b', '', multi=True)
305     od = OptionDescription('a', '', [a, b])
306     a.impl_add_consistency('not_equal', b)
307     c = Config(od)
308     assert c.a == []
309     assert c.b == []
310     c.a = [1]
311     del(c.a)
312     c.a = [1]
313     raises(ValueError, "c.b = [1]")
314     c.b = [2]
315     raises(ValueError, "c.b = [2, 1]")
316     raises(ValueError, "c.b.append(1)")
317     c.b.append(3)
318     raises(ValueError, "c.b.append(3)")
319     raises(ValueError, "c.a.append(3)")
320     raises(ValueError, "c.a.append(3)")
321
322
323 def test_consistency_not_equal_multi_default():
324     a = IntOption('a', '', multi=True, default=[1])
325     b = IntOption('b', '', multi=True, default=[1, 2])
326     od = OptionDescription('a', '', [a, b])
327     raises(ValueError, "a.impl_add_consistency('not_equal', b)")
328
329
330 def test_consistency_not_equal_multi_default_modif():
331     a = IntOption('a', '', multi=True)
332     b = IntOption('b', '', multi=True, default=[1, 2])
333     od = OptionDescription('a', '', [a, b])
334     a.impl_add_consistency('not_equal', b)
335     c = Config(od)
336     assert c.a == []
337     assert c.b == [1, 2]
338     raises(ValueError, 'c.a.append(1)')
339     raises(ValueError, 'c.b.append(1)')
340
341
342 def test_consistency_default():
343     a = IntOption('a', '', 1)
344     b = IntOption('b', '', 1)
345     a, b
346     raises(ValueError, "a.impl_add_consistency('not_equal', b)")
347
348
349 def test_consistency_default_multi():
350     a = IntOption('a', '', [2, 1], multi=True)
351     b = IntOption('b', '', [1, 1], multi=True)
352     c = IntOption('c', '', [1, 2], multi=True)
353     b
354     raises(ValueError, "a.impl_add_consistency('not_equal', b)")
355     a.impl_add_consistency('not_equal', c)
356
357
358 def test_consistency_default_diff():
359     a = IntOption('a', '', 3)
360     b = IntOption('b', '', 1)
361     od = OptionDescription('od', '', [a, b])
362     a.impl_add_consistency('not_equal', b)
363     c = Config(od)
364     raises(ValueError, "c.a = 1")
365     c.a = 2
366     c.b = 3
367     assert c.getowner(a) is owners.user
368     raises(ValueError, "del(c.a)")
369     assert c.getowner(a) is owners.user
370
371
372 def test_consistency_ip_netmask():
373     a = IPOption('a', '')
374     b = NetmaskOption('b', '')
375     od = OptionDescription('od', '', [a, b])
376     b.impl_add_consistency('ip_netmask', a)
377     c = Config(od)
378     c.a = '192.168.1.1'
379     c.b = '255.255.255.0'
380     c.a = '192.168.1.2'
381     c.b = '255.255.255.255'
382     c.b = '255.255.255.0'
383     raises(ValueError, "c.a = '192.168.1.0'")
384     raises(ValueError, "c.a = '192.168.1.255'")
385
386
387 def test_consistency_network_netmask():
388     a = NetworkOption('a', '')
389     b = NetmaskOption('b', '')
390     od = OptionDescription('od', '', [a, b])
391     b.impl_add_consistency('network_netmask', a)
392     c = Config(od)
393     c.a = '192.168.1.1'
394     c.b = '255.255.255.255'
395     del(c.b)
396     c.a = '192.168.1.0'
397     c.b = '255.255.255.0'
398     raises(ValueError, "c.a = '192.168.1.1'")
399
400
401 def test_consistency_ip_in_network():
402     a = NetworkOption('a', '')
403     b = NetmaskOption('b', '')
404     c = IPOption('c', '')
405     d = IPOption('d', '')
406     od = OptionDescription('od', '', [a, b, c, d])
407     c.impl_add_consistency('in_network', a, b)
408     d.impl_add_consistency('in_network', a, b, warnings_only=True)
409     warnings.simplefilter("always", ValueWarning)
410     cfg = Config(od)
411     cfg.a = '192.168.1.0'
412     cfg.b = '255.255.255.0'
413     cfg.c = '192.168.1.1'
414     raises(ValueError, "cfg.c = '192.168.2.1'")
415     raises(ValueError, "cfg.c = '192.168.1.0'")
416     raises(ValueError, "cfg.c = '192.168.1.255'")
417     with warnings.catch_warnings(record=True) as w:
418         cfg.d = '192.168.2.1'
419     assert len(w) == 1
420
421
422 def test_consistency_ip_in_network_len_error():
423     a = NetworkOption('a', '')
424     b = NetmaskOption('b', '')
425     c = IPOption('c', '')
426     od = OptionDescription('od', '', [a, b, c])
427     raises(ConfigError, "c.impl_add_consistency('in_network', a)")
428
429
430 def test_consistency_ip_netmask_network_error():
431     a = IPOption('a', '')
432     b = NetworkOption('b', '')
433     c = NetmaskOption('c', '')
434     od = OptionDescription('od', '', [a, b, c])
435     c.impl_add_consistency('ip_netmask', a, b)
436     c = Config(od)
437     c.a = '192.168.1.1'
438     c.b = '192.168.1.0'
439     raises(ConfigError, "c.c = '255.255.255.0'")
440
441
442 def test_consistency_ip_netmask_error_multi():
443     a = IPOption('a', '', multi=True)
444     b = NetmaskOption('b', '')
445     OptionDescription('od', '', [a, b])
446     raises(ConfigError, "b.impl_add_consistency('ip_netmask', a)")
447
448
449 def test_consistency_ip_netmask_multi():
450     a = IPOption('a', '', multi=True)
451     b = NetmaskOption('b', '', multi=True)
452     od = OptionDescription('a', '', [a, b])
453     b.impl_add_consistency('ip_netmask', a)
454     od.impl_set_group_type(groups.master)
455     c = Config(od)
456     c.a = ['192.168.1.1']
457     c.b = ['255.255.255.0']
458     c.a = ['192.168.1.2']
459     c.b = ['255.255.255.255']
460     c.b = ['255.255.255.0']
461     raises(ValueError, "c.a = ['192.168.1.0']")
462
463
464 def test_consistency_network_netmask_multi():
465     a = NetworkOption('a', '', multi=True)
466     b = NetmaskOption('b', '', multi=True)
467     od = OptionDescription('a', '', [a, b])
468     od.impl_set_group_type(groups.master)
469     b.impl_add_consistency('network_netmask', a)
470     c = Config(od)
471     c.a = ['192.168.1.1']
472     c.b = ['255.255.255.255']
473     del(c.b)
474     c.a = ['192.168.1.0']
475     c.b = ['255.255.255.0']
476     raises(ValueError, "c.a = ['192.168.1.1']")
477
478
479 def test_consistency_network_netmask_multi_slave_default_multi():
480     a = NetworkOption('a', '', default_multi=u'192.168.1.0', multi=True, properties=('mandatory',))
481     b = NetmaskOption('b', '', default_multi=u'255.255.255.0', multi=True, properties=('mandatory',))
482     od = OptionDescription('a', '', [a, b])
483     od.impl_set_group_type(groups.master)
484     b.impl_add_consistency('network_netmask', a)
485     c = Config(od)
486     c.read_write()
487     c.a.append()
488
489
490 def test_consistency_network_netmask_multi_slave_default():
491     a = NetworkOption('a', '', multi=True, properties=('mandatory',))
492     b = NetmaskOption('b', '', default_multi=u'255.255.255.0', multi=True, properties=('mandatory',))
493     od = OptionDescription('a', '', [a, b])
494     od.impl_set_group_type(groups.master)
495     b.impl_add_consistency('network_netmask', a)
496     c = Config(od)
497     c.read_write()
498     c.cfgimpl_get_settings().remove('cache')
499     assert c.a == []
500     assert c.b == []
501     c.a.append(u'192.168.1.0')
502     c.read_only()
503     assert c.a == [u'192.168.1.0']
504     assert c.b == [u'255.255.255.0']
505     c.read_write()
506     raises(ValueError, "c.a[0] = u'192.168.1.2'")
507     raises(ValueError, "c.a.append(u'192.168.1.1')")
508     raises(ValueError, "c.a = [u'192.168.1.0', u'192.168.1.1']")
509     c.a.append()
510     c.b = [u'255.255.255.0', u'255.255.255.255']
511     c.a = [u'192.168.1.0', u'192.168.1.1']
512
513
514 def return_netmask(*args, **kwargs):
515     return u'255.255.255.0'
516
517
518 def return_netmask2(master):
519     if master is not None:
520         if master.endswith('2.1'):
521             return u'255.255.255.0'
522         if not master.endswith('.0'):
523             return u'255.255.255.255'
524     return u'255.255.255.0'
525
526
527 def test_consistency_network_netmask_multi_slave_callback():
528     a = NetworkOption('a', '', multi=True, properties=('mandatory',))
529     b = NetmaskOption('b', '', callback=return_netmask, multi=True, properties=('mandatory',))
530     od = OptionDescription('a', '', [a, b])
531     od.impl_set_group_type(groups.master)
532     b.impl_add_consistency('network_netmask', a)
533     c = Config(od)
534     c.read_write()
535     c.cfgimpl_get_settings().remove('cache')
536     assert c.a == []
537     assert c.b == []
538     c.a.append(u'192.168.1.0')
539     c.read_only()
540     assert c.a == [u'192.168.1.0']
541     assert c.b == [u'255.255.255.0']
542     c.read_write()
543     raises(ValueError, "c.a[0] = u'192.168.1.2'")
544     raises(ValueError, "c.a.append(u'192.168.1.1')")
545     raises(ValueError, "c.a = [u'192.168.1.0', u'192.168.1.1']")
546     c.a.append()
547     c.b = [u'255.255.255.0', u'255.255.255.255']
548     c.a = [u'192.168.1.0', u'192.168.1.1']
549
550
551 def test_consistency_network_netmask_multi_slave_callback_value():
552     a = NetworkOption('a', '', multi=True, properties=('mandatory',))
553     b = NetmaskOption('b', '', callback=return_netmask2, callback_params={'': ((a, False),)}, multi=True, properties=('mandatory',))
554     od = OptionDescription('a', '', [a, b])
555     od.impl_set_group_type(groups.master)
556     b.impl_add_consistency('network_netmask', a)
557     c = Config(od)
558     c.read_write()
559     c.cfgimpl_get_settings().remove('cache')
560     assert c.a == []
561     assert c.b == []
562     c.a.append(u'192.168.1.0')
563     assert c.a == [u'192.168.1.0']
564     assert c.b == [u'255.255.255.0']
565     raises(ValueError, "c.a[0] = u'192.168.2.1'")
566     assert c.a == [u'192.168.1.0']
567     assert c.b == [u'255.255.255.0']
568     raises(ValueError, "c.a = [u'192.168.2.1']")
569     assert c.a == [u'192.168.1.0']
570     assert c.b == [u'255.255.255.0']
571     c.a.append(u'192.168.1.1')
572     c.a = [u'192.168.1.0', u'192.168.1.1']
573     c.b = [u'255.255.255.0', u'255.255.255.255']
574
575
576 def test_consistency_ip_netmask_multi_master():
577     a = IPOption('a', '', multi=True)
578     b = NetmaskOption('b', '', multi=True)
579     od = OptionDescription('a', '', [a, b])
580     od.impl_set_group_type(groups.master)
581     b.impl_add_consistency('ip_netmask', a)
582     c = Config(od)
583     c.a = ['192.168.1.1']
584     c.b = ['255.255.255.0']
585     c.a = ['192.168.1.2']
586     c.b = ['255.255.255.255']
587     c.b = ['255.255.255.0']
588     raises(ValueError, "c.a = ['192.168.1.0']")
589     c.a = ['192.168.1.128']
590     raises(ValueError, "c.b = ['255.255.255.128']")
591     c.a = ['192.168.1.2', '192.168.1.3']
592
593
594 def test_consistency_network_netmask_multi_master():
595     a = NetworkOption('a', '', multi=True)
596     b = NetmaskOption('b', '', multi=True)
597     od = OptionDescription('a', '', [a, b])
598     od.impl_set_group_type(groups.master)
599     b.impl_add_consistency('network_netmask', a)
600     c = Config(od)
601     c.a = ['192.168.1.1']
602     c.b = ['255.255.255.255']
603     del(c.b)
604     c.a = ['192.168.1.0']
605     c.b = ['255.255.255.0']
606     raises(ValueError, "c.a = ['192.168.1.1']")
607
608
609 def test_consistency_broadcast():
610     a = NetworkOption('a', '', multi=True)
611     b = NetmaskOption('b', '', multi=True)
612     c = BroadcastOption('c', '', multi=True)
613     od = OptionDescription('a', '', [a, b, c])
614     od.impl_set_group_type(groups.master)
615     b.impl_add_consistency('network_netmask', a)
616     c.impl_add_consistency('broadcast', a, b)
617     c = Config(od)
618     #first, test network_netmask
619     c.a = ['192.168.1.128']
620     raises(ValueError, "c.b = ['255.255.255.0']")
621     #
622     c.a = ['192.168.1.0']
623     c.b = ['255.255.255.0']
624     c.c = ['192.168.1.255']
625     raises(ValueError, "c.a = ['192.168.1.1']")
626     #
627     c.a = ['192.168.1.0', '192.168.2.128']
628     c.b = ['255.255.255.0', '255.255.255.128']
629     c.c = ['192.168.1.255', '192.168.2.255']
630     raises(ValueError, "c.c[1] = '192.168.2.128'")
631     c.c[1] = '192.168.2.255'
632
633
634 def test_consistency_broadcast_error():
635     a = NetworkOption('a', '', multi=True)
636     b = NetmaskOption('b', '', multi=True)
637     c = BroadcastOption('c', '', multi=True)
638     od = OptionDescription('a', '', [a, b, c])
639     od.impl_set_group_type(groups.master)
640     b.impl_add_consistency('network_netmask', a)
641     c.impl_add_consistency('broadcast', a)
642     c = Config(od)
643     raises(ConfigError, "c.a = ['192.168.1.0']")
644
645
646 def test_consistency_broadcast_warnings():
647     warnings.simplefilter("always", ValueWarning)
648     a = NetworkOption('a', '', properties=('mandatory', 'disabled'))
649     b = NetmaskOption('b', '', properties=('mandatory', 'disabled'))
650     c = NetmaskOption('c', '', properties=('mandatory', 'disabled'))
651     od = OptionDescription('a', '', [a, b, c])
652     b.impl_add_consistency('network_netmask', a, warnings_only=True)
653     c = Config(od)
654     with warnings.catch_warnings(record=True) as w:
655         c.a = '192.168.1.4'
656         c.b = '255.255.255.0'
657     assert len(w) == 1
658     c.read_write()
659     with warnings.catch_warnings(record=True) as w:
660         list(c.cfgimpl_get_values().mandatory_warnings())
661     assert len(w) == 0
662
663
664 def test_consistency_broadcast_default_1():
665     a = NetworkOption('a', '', '192.168.1.0')
666     b = NetmaskOption('b', '', '255.255.255.128')
667     c = BroadcastOption('c', '', '192.168.2.127')
668     od = OptionDescription('a', '', [a, b, c])
669     od
670     raises(ValueError, "c.impl_add_consistency('broadcast', a, b)")
671
672
673 def test_consistency_broadcast_default_2():
674     a = NetworkOption('a', '', '192.168.1.0')
675     b = NetmaskOption('b', '', '255.255.255.128')
676     d = BroadcastOption('d', '', '192.168.1.127')
677     od2 = OptionDescription('a', '', [a, b, d])
678     od2
679     d.impl_add_consistency('broadcast', a, b)
680
681
682 def test_consistency_not_all():
683     #_cache_consistencies is not None by not options has consistencies
684     a = NetworkOption('a', '', multi=True)
685     b = NetmaskOption('b', '', multi=True)
686     c = BroadcastOption('c', '', multi=True)
687     od = OptionDescription('a', '', [a, b, c])
688     od.impl_set_group_type(groups.master)
689     b.impl_add_consistency('network_netmask', a)
690     c = Config(od)
691     c.a = ['192.168.1.0']
692     c.b = ['255.255.255.0']
693     c.c = ['192.168.1.255']
694
695
696 def test_consistency_permissive():
697     a = IntOption('a', '', 1)
698     b = IntOption('b', '', 2, properties=('hidden',))
699     od = OptionDescription('od', '', [a, b])
700     a.impl_add_consistency('not_equal', b)
701     c = Config(od)
702     c.cfgimpl_get_settings().setpermissive(('hidden',))
703     c.read_write()
704     c.a = 1
705
706
707 def test_consistency_disabled():
708     a = IntOption('a', '')
709     b = IntOption('b', '', properties=('disabled',))
710     od = OptionDescription('od', '', [a, b])
711     a.impl_add_consistency('not_equal', b)
712     c = Config(od)
713     c.read_write()
714     raises(PropertiesOptionError, "c.a = 1")
715
716
717 def test_consistency_disabled_transitive():
718     a = IntOption('a', '')
719     b = IntOption('b', '', properties=('disabled',))
720     od = OptionDescription('od', '', [a, b])
721     a.impl_add_consistency('not_equal', b, transitive=False)
722     c = Config(od)
723     c.read_write()
724     c.a = 1
725
726
727 def test_consistency_disabled_transitive_2():
728     a = IPOption('a', '')
729     b = IPOption('b', '')
730     c = NetworkOption('c', '', default='192.168.1.0')
731     d = NetmaskOption('d', '', default='255.255.255.0', properties=('disabled',))
732     od = OptionDescription('od', '', [a, b, c, d])
733     a.impl_add_consistency('not_equal', b)
734     a.impl_add_consistency('in_network', c, d, transitive=False)
735     c = Config(od)
736     c.read_write()
737     c.a = '192.168.1.1'
738     raises(ValueError, "c.b = '192.168.1.1'")
739     c.a = '192.168.2.1'
740     #
741     c.a = '192.168.1.1'
742     c.cfgimpl_get_settings().remove('disabled')
743     raises(ValueError, "c.a = '192.168.2.1'")
744
745
746 def return_val(*args, **kwargs):
747     return '192.168.1.1'
748
749
750 def test_consistency_with_callback():
751     a = NetworkOption('a', '', default='192.168.1.0')
752     b = NetmaskOption('b', '', default='255.255.255.0')
753     c = IPOption('c', '', callback=return_val, callback_params={'': ((a, False),)})
754     od = OptionDescription('od', '', [a, b, c])
755     c.impl_add_consistency('in_network', a, b)
756     cfg = Config(od)
757     cfg.c
758
759
760 def test_consistency_double_warnings():
761     a = IntOption('a', '')
762     b = IntOption('b', '', 1)
763     c = IntOption('c', '', 1)
764     od = OptionDescription('od', '', [a, b, c])
765     warnings.simplefilter("always", ValueWarning)
766     a.impl_add_consistency('not_equal', b, warnings_only=True)
767     a.impl_add_consistency('not_equal', c, warnings_only=True)
768     cfg = Config(od)
769     with warnings.catch_warnings(record=True) as w:
770         cfg.a = 1
771     assert w != []
772     assert len(w) == 2
773     with warnings.catch_warnings(record=True) as w:
774         cfg.c = 2
775     assert w == []
776     with warnings.catch_warnings(record=True) as w:
777         cfg.a = 2
778     assert w != []
779     assert len(w) == 1
780     cfg.cfgimpl_get_settings().remove('warnings')
781     with warnings.catch_warnings(record=True) as w:
782         cfg.a = 1
783     assert w == []
784
785
786 def test_consistency_warnings_error():
787     a = IntOption('a', '')
788     b = IntOption('b', '', 1)
789     c = IntOption('c', '', 1)
790     od = OptionDescription('od', '', [a, b, c])
791     warnings.simplefilter("always", ValueWarning)
792     a.impl_add_consistency('not_equal', b, warnings_only=True)
793     a.impl_add_consistency('not_equal', c)
794     cfg = Config(od)
795     with warnings.catch_warnings(record=True) as w:
796         raises(ValueError, "cfg.a = 1")
797     assert w == []
798
799
800 def test_consistency_network_netmask_mandatory():
801     a = NetworkOption('a', '', multi=True, properties=('mandatory',), default=[u'0.0.0.0'])
802     b = NetmaskOption('b', '', multi=True, properties=('mandatory',), default_multi=u'0.0.0.0')
803     od = OptionDescription('a', '', [a, b])
804     od.impl_set_group_type(groups.master)
805     b.impl_add_consistency('network_netmask', a)
806     c = Config(od)
807     c.read_only()
808     c.cfgimpl_get_settings().remove('mandatory')
809     c.make_dict()