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