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