python 3.5 support
[tiramisu.git] / test / test_config_api.py
1 "configuration objects global API"
2 from .autopath import do_autopath
3 do_autopath()
4
5 from py.test import raises
6
7 from tiramisu.config import Config
8 from tiramisu.option import IntOption, FloatOption, StrOption, ChoiceOption, \
9     BoolOption, FilenameOption, UnicodeOption, SymLinkOption, IPOption, \
10     PortOption, NetworkOption, NetmaskOption, BroadcastOption, \
11     DomainnameOption, OptionDescription
12 from tiramisu.error import PropertiesOptionError
13
14
15 def make_description():
16     gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref')
17     gcdummy = BoolOption('dummy', 'dummy', default=False)
18     prop = BoolOption('prop', '', properties=('disabled',))
19     prop2 = BoolOption('prop', '', properties=('hidden',))
20     objspaceoption = ChoiceOption('objspace', 'Object space',
21                                   ('std', 'thunk'), 'std')
22     booloption = BoolOption('bool', 'Test boolean option', default=True)
23     booloption2 = BoolOption('bool', 'Test boolean option', default=False)
24     intoption = IntOption('int', 'Test int option', default=0)
25     floatoption2 = FloatOption('float', 'Test float option', default=2.3)
26     floatoption = FloatOption('float', 'Test float option', default=2.3)
27     stroption = StrOption('str', 'Test string option', default="abc")
28     boolop = BoolOption('boolop', 'Test boolean option op', default=True)
29     wantref_option = BoolOption('wantref', 'Tests', default=False)
30     wantframework_option = BoolOption('wantframework', 'Test', default=False)
31     gcgroup2 = OptionDescription('gc2', '', [booloption2, prop])
32     gcgroup = OptionDescription('gc', '', [gcgroup2, gcoption, gcdummy, floatoption, prop2])
33     descr = OptionDescription('tiramisu', '', [gcgroup, booloption, objspaceoption,
34                                                wantref_option, stroption,
35                                                wantframework_option,
36                                                intoption, boolop, floatoption2])
37     return descr
38
39
40 def _is_same_opt(opt1, opt2):
41     if "id" in dir(opt1):
42         assert opt1.id == opt2.id
43     else:
44         assert opt1 == opt2
45
46
47 def test_iter_config():
48     "iteration on config object"
49     s = StrOption("string", "", default="string")
50     s2 = StrOption("string2", "", default="string2")
51     descr = OptionDescription("options", "", [s, s2])
52     config = Config(descr)
53     assert [(name, value) for name, value in config] == \
54         [('string', 'string'), ('string2', 'string2')]
55
56
57 def test_iter_config_property():
58     "iteration on config object"
59     s = StrOption("string", "", default="string", properties=('disabled',))
60     s2 = StrOption("string2", "", default="string2")
61     descr = OptionDescription("options", "", [s, s2])
62     config = Config(descr)
63     config.read_only()
64     assert [(name, value) for name, value in config] == \
65         [('string2', 'string2')]
66
67
68 def test_iter_subconfig():
69     "iteration on config sub object"
70     descr = make_description()
71     conf = Config(descr)
72     for (name, value), (gname, gvalue) in \
73             zip(conf.gc, [("name", "ref"), ("dummy", False)]):
74         assert name == gname
75         assert value == gvalue
76
77
78 def test_str():
79     descr = make_description()
80     c = Config(descr)
81     c  # does not crash
82
83
84 def test_make_dict():
85     "serialization of the whole config to a dict"
86     descr = OptionDescription("opt", "", [
87         OptionDescription("s1", "", [
88             BoolOption("a", "", default=False),
89             BoolOption("b", "", default=False, properties=('hidden',))]),
90         IntOption("int", "", default=42)])
91     config = Config(descr)
92     config.read_write()
93     config.cfgimpl_get_settings().setpermissive(('hidden',))
94     d = config.make_dict()
95     assert d == {"s1.a": False, "int": 42}
96     config.int = 43
97     config.s1.a = True
98     d = config.make_dict()
99     assert d == {"s1.a": True, "int": 43}
100     d2 = config.make_dict(flatten=True)
101     assert d2 == {'a': True, 'int': 43}
102     raises(ValueError, 'd2 = config.make_dict(withvalue="3")')
103     d = config.make_dict(force_permissive=True)
104     assert d == {"s1.a": True, "s1.b": False, "int": 43}
105
106
107 def test_make_dict_with_disabled():
108     descr = OptionDescription("opt", "", [
109         OptionDescription("s1", "", [
110             BoolOption("a", "", default=False),
111             BoolOption("b", "", default=False, properties=('disabled',))]),
112         OptionDescription("s2", "", [
113             BoolOption("a", "", default=False),
114             BoolOption("b", "", default=False)], properties=('disabled',)),
115         IntOption("int", "", default=42)])
116     config = Config(descr)
117     config.read_only()
118     d = config.make_dict()
119     assert d == {"s1.a": False, "int": 42}
120
121
122 def test_make_dict_with_disabled_in_callback():
123     descr = OptionDescription("opt", "", [
124         OptionDescription("s1", "", [
125             BoolOption("a", "", default=False),
126             BoolOption("b", "", default=False, properties=('disabled',))]),
127         OptionDescription("s2", "", [
128             BoolOption("a", "", default=False),
129             BoolOption("b", "", default=False)], properties=('disabled',)),
130         IntOption("int", "", default=42)])
131     config = Config(descr)
132     config.read_only()
133     d = config.make_dict()
134     assert d == {"s1.a": False, "int": 42}
135
136
137 def test_make_dict_fullpath():
138     descr = OptionDescription("root", "", [
139         OptionDescription("opt", "", [
140             OptionDescription("s1", "", [
141                 BoolOption("a", "", default=False),
142                 BoolOption("b", "", default=False, properties=('disabled',))]),
143             OptionDescription("s2", "", [
144                 BoolOption("a", "", default=False),
145                 BoolOption("b", "", default=False)], properties=('disabled',)),
146             IntOption("int", "", default=42)]),
147         IntOption("introot", "", default=42)])
148     config = Config(descr)
149     config.read_only()
150     assert config.make_dict() == {"opt.s1.a": False, "opt.int": 42, "introot": 42}
151     assert config.opt.make_dict() == {"s1.a": False, "int": 42}
152     assert config.make_dict(fullpath=True) == {"opt.s1.a": False, "opt.int": 42, "introot": 42}
153     assert config.opt.make_dict(fullpath=True) == {"opt.s1.a": False, "opt.int": 42}
154
155
156 def test_find_in_config():
157     "finds option in config"
158     descr = make_description()
159     conf = Config(descr)
160     conf.read_only()
161     conf.cfgimpl_get_settings().setpermissive(('hidden',))
162     ret = conf.find(byname='dummy')
163     assert len(ret) == 1
164     _is_same_opt(ret[0], conf.unwrap_from_path('gc.dummy'))
165     #
166     ret = conf.find_first(byname='dummy')
167     _is_same_opt(ret, conf.unwrap_from_path('gc.dummy'))
168     #
169     ret = conf.find(byname='float')
170     assert len(ret) == 2
171     _is_same_opt(ret[0], conf.unwrap_from_path('gc.float'))
172     _is_same_opt(ret[1], conf.unwrap_from_path('float'))
173     _is_same_opt(conf.find_first(byname='bool'), conf.unwrap_from_path('gc.gc2.bool'))
174     _is_same_opt(conf.find_first(byname='bool', byvalue=True), conf.unwrap_from_path('bool'))
175     _is_same_opt(conf.find_first(byname='dummy'), conf.unwrap_from_path('gc.dummy'))
176     _is_same_opt(conf.find_first(byname='float'), conf.unwrap_from_path('gc.float'))
177     ret = conf.find(bytype=ChoiceOption)
178     assert len(ret) == 2
179     _is_same_opt(ret[0], conf.unwrap_from_path('gc.name'))
180     _is_same_opt(ret[1], conf.unwrap_from_path('objspace'))
181     _is_same_opt(conf.find_first(bytype=ChoiceOption), conf.unwrap_from_path('gc.name'))
182     ret = conf.find(byvalue='ref')
183     assert len(ret) == 1
184     _is_same_opt(ret[0], conf.unwrap_from_path('gc.name'))
185     _is_same_opt(conf.find_first(byvalue='ref'), conf.unwrap_from_path('gc.name'))
186     ret = conf.find(byname='prop')
187     assert len(ret) == 1
188     _is_same_opt(ret[0], conf.unwrap_from_path('gc.prop'))
189     conf.read_write()
190     raises(AttributeError, "assert conf.find(byname='prop')")
191     ret = conf.find(byname='prop', check_properties=False)
192     assert len(ret) == 2
193     _is_same_opt(ret[0], conf.unwrap_from_path('gc.gc2.prop'))
194     _is_same_opt(ret[1], conf.unwrap_from_path('gc.prop'))
195     ret = conf.find(byname='prop', force_permissive=True)
196     assert len(ret) == 1
197     _is_same_opt(ret[0], conf.unwrap_from_path('gc.prop'))
198     _is_same_opt(conf.find_first(byname='prop', force_permissive=True), conf.unwrap_from_path('gc.prop'))
199     #assert conf.find_first(byname='prop') == conf.unwrap_from_path('gc.prop')
200     # combinaison of filters
201     ret = conf.find(bytype=BoolOption, byname='dummy')
202     assert len(ret) == 1
203     _is_same_opt(ret[0], conf.unwrap_from_path('gc.dummy'))
204     _is_same_opt(conf.find_first(bytype=BoolOption, byname='dummy'), conf.unwrap_from_path('gc.dummy'))
205     ret = conf.find(byvalue=False, byname='dummy')
206     assert len(ret) == 1
207     _is_same_opt(ret[0], conf.unwrap_from_path('gc.dummy'))
208     _is_same_opt(conf.find_first(byvalue=False, byname='dummy'), conf.unwrap_from_path('gc.dummy'))
209     #subconfig
210     ret = conf.gc.find(byname='dummy')
211     assert len(ret) == 1
212     _is_same_opt(ret[0], conf.unwrap_from_path('gc.dummy'))
213     ret = conf.gc.find(byname='float')
214     assert len(ret) == 1
215     _is_same_opt(ret[0], conf.unwrap_from_path('gc.float'))
216     ret = conf.gc.find(byname='bool')
217     assert len(ret) == 1
218     _is_same_opt(ret[0], conf.unwrap_from_path('gc.gc2.bool'))
219     _is_same_opt(conf.gc.find_first(byname='bool', byvalue=False), conf.unwrap_from_path('gc.gc2.bool'))
220     raises(AttributeError, "assert conf.gc.find_first(byname='bool', byvalue=True)")
221     raises(AttributeError, "conf.gc.find(byname='wantref').first()")
222     ret = conf.gc.find(byname='prop', check_properties=False)
223     assert len(ret) == 2
224     _is_same_opt(ret[0], conf.unwrap_from_path('gc.gc2.prop'))
225     _is_same_opt(ret[1], conf.unwrap_from_path('gc.prop'))
226     conf.read_only()
227     ret = conf.gc.find(byname='prop')
228     assert len(ret) == 1
229     _is_same_opt(ret[0], conf.unwrap_from_path('gc.prop'))
230     # not OptionDescription
231     raises(AttributeError, "conf.find_first(byname='gc')")
232     raises(AttributeError, "conf.gc.find_first(byname='gc2')")
233     raises(ValueError, "conf.find(byname='bool', type_='unknown')")
234
235
236 def test_find_multi():
237     b = BoolOption('bool', '', multi=True)
238     o = OptionDescription('od', '', [b])
239     conf = Config(o)
240     raises(AttributeError, "conf.find(byvalue=True)")
241     raises(AttributeError, "conf.find_first(byvalue=True)")
242     conf.bool.append(False)
243     raises(AttributeError, "conf.find(byvalue=True)")
244     raises(AttributeError, "conf.find_first(byvalue=True)")
245     conf.bool.append(False)
246     raises(AttributeError, "conf.find(byvalue=True)")
247     raises(AttributeError, "conf.find_first(byvalue=True)")
248     conf.bool.append(True)
249     ret = conf.find(byvalue=True)
250     assert len(ret) == 1
251     _is_same_opt(ret[0], b)
252     _is_same_opt(conf.find_first(byvalue=True), b)
253
254
255 def test_does_not_find_in_config():
256     descr = make_description()
257     conf = Config(descr)
258     conf
259     raises(AttributeError, "conf.find(byname='IDontExist')")
260
261
262 def test_filename():
263     a = FilenameOption('a', '')
264     o = OptionDescription('o', '', [a])
265     c = Config(o)
266     c.a = u'/'
267     c.a = u'/tmp'
268     c.a = u'/tmp/'
269     c.a = u'/tmp/text.txt'
270     c.a = u'tmp'
271     c.a = u'tmp/'
272     c.a = u'tmp/text.txt'
273     raises(ValueError, "c.a = u'/tmp/with space.txt'")
274     raises(ValueError, "c.a = u'/tmp/with$.txt'")
275
276
277 def test_iter_all():
278     s = StrOption("string", "", default="string")
279     s2 = StrOption("string2", "", default="string2")
280     descr = OptionDescription("options", "", [s, s2])
281     config = Config(descr)
282     assert list(config.iter_all()) == [('string', 'string'), ('string2', 'string2')]
283     for i in config.iter_all():
284         #test StopIteration
285         break
286
287
288 def test_iter_all_force_permissive():
289     s = StrOption("string", "", default="string")
290     s2 = StrOption("string2", "", default="string2")
291     s3 = StrOption("string3", "", default="string3", properties=('hidden',))
292     descr = OptionDescription("options", "", [s, s2, s3])
293     config = Config(descr)
294     config.read_write()
295     config.cfgimpl_get_settings().setpermissive(('hidden',))
296     assert list(config.iter_all()) == [('string', 'string'), ('string2', 'string2')]
297     assert list(config.iter_all(force_permissive=True)) == [('string', 'string'),
298                                                             ('string2', 'string2'),
299                                                             ('string3', 'string3')]
300
301
302 def test_iter_all_prop():
303     s = StrOption("string", "", default="string", properties=('disabled',))
304     s2 = StrOption("string2", "", default="string2")
305     descr = OptionDescription("options", "", [s, s2])
306     config = Config(descr)
307     config.read_only()
308     assert list(config.iter_all()) == [('string2', 'string2')]
309
310
311 def test_impl_getpaths():
312     s = StrOption("string", "", default="string", properties=('disabled',))
313     s2 = StrOption("string2", "", default="string2")
314     s3 = StrOption("string3", "", default="string3")
315     s4 = StrOption("string4", "", default="string4", properties=('hidden',))
316     od = OptionDescription('od', '', [s3, s4])
317     descr = OptionDescription("options", "", [s, s2, od])
318     config = Config(descr)
319     assert ['string', 'string2', 'od.string3', 'od.string4'] == config.cfgimpl_get_description().impl_getpaths()
320     assert ['string', 'string2', 'od', 'od.string3', 'od.string4'] == config.cfgimpl_get_description().impl_getpaths(include_groups=True)
321     config.read_write()
322     raises(PropertiesOptionError, "config.od.string4")
323     assert ['string', 'string2', 'od.string3', 'od.string4'] == config.cfgimpl_get_description().impl_getpaths()
324     assert ['string', 'string2', 'od', 'od.string3', 'od.string4'] == config.cfgimpl_get_description().impl_getpaths(include_groups=True)
325
326
327 def test_invalid_option():
328     ChoiceOption('a', '', ('1', '2'))
329     raises(TypeError, "ChoiceOption('a', '', [1, 2])")
330     raises(TypeError, "ChoiceOption('a', '', 1)")
331     raises(ValueError, "ChoiceOption('a', '', (1,), 3)")
332     FloatOption('a', '')
333     raises(ValueError, "FloatOption('a', '', 'string')")
334     UnicodeOption('a', '')
335     raises(ValueError, "UnicodeOption('a', '', 1)")
336     u = UnicodeOption('a', '')
337     SymLinkOption('a', u)
338     raises(ValueError, "SymLinkOption('a', 'string')")
339     IPOption('a', '')
340     raises(ValueError, "IPOption('a', '', 1)")
341     raises(ValueError, "IPOption('a', '', 'string')")
342     PortOption('a', '')
343     raises(ValueError, "PortOption('a', '', 'string')")
344     raises(ValueError, "PortOption('a', '', '11:12:13', allow_range=True)")
345     raises(ValueError, "PortOption('a', '', 11111111111111111111)")
346     raises(ValueError, "PortOption('a', '', allow_zero=True, allow_wellknown=False, allow_registred=True, allow_private=False)")
347     raises(ValueError, "PortOption('a', '', allow_zero=True, allow_wellknown=True, allow_registred=False, allow_private=True)")
348     raises(ValueError, "PortOption('a', '', allow_zero=True, allow_wellknown=False, allow_registred=False, allow_private=True)")
349     raises(ValueError, "PortOption('a', '', allow_zero=True, allow_wellknown=False, allow_registred=True, allow_private=True)")
350     raises(ValueError, "PortOption('a', '', allow_zero=False, allow_wellknown=False, allow_registred=False, allow_private=False)")
351     NetworkOption('a', '')
352     raises(ValueError, "NetworkOption('a', '', 'string')")
353     NetmaskOption('a', '')
354     raises(ValueError, "NetmaskOption('a', '', 'string')")
355     BroadcastOption('a', '')
356     raises(ValueError, "BroadcastOption('a', '', 'string')")
357     DomainnameOption('a', '')
358     raises(ValueError, "DomainnameOption('a', '', 'string')")
359     raises(ValueError, "DomainnameOption('a', '', type_='string')")
360     raises(ValueError, "DomainnameOption('a', '', allow_ip='string')")
361     raises(ValueError, "DomainnameOption('a', '', allow_without_dot='string')")
362     raises(ValueError, "DomainnameOption('a', '', 1)")
363     #
364     ChoiceOption('a', '', (1,), multi=True, default_multi=1)
365     raises(ValueError, "ChoiceOption('a', '', (1,), default_multi=1)")
366     raises(ValueError, "ChoiceOption('a', '', (1,), multi=True, default=[1,], default_multi=2)")
367     raises(ValueError, "FloatOption('a', '', multi=True, default_multi='string')")
368     raises(ValueError, "UnicodeOption('a', '', multi=True, default_multi=1)")
369     raises(ValueError, "IPOption('a', '', multi=True, default_multi=1)")
370     raises(ValueError, "IPOption('a', '', multi=True, default_multi='string')")
371     raises(ValueError, "PortOption('a', '', multi=True, default_multi='string')")
372     raises(ValueError, "PortOption('a', '', multi=True, default_multi='11:12:13', allow_range=True)")
373     raises(ValueError, "PortOption('a', '', multi=True, default_multi=11111111111111111111)")
374     raises(ValueError, "NetworkOption('a', '', multi=True, default_multi='string')")
375     raises(ValueError, "NetmaskOption('a', '', multi=True, default_multi='string')")
376     raises(ValueError, "BroadcastOption('a', '', multi=True, default_multi='string')")
377     raises(ValueError, "DomainnameOption('a', '', multi=True, default_multi='string')")
378     raises(ValueError, "DomainnameOption('a', '', multi=True, default_multi=1)")