ba165457ee12345c6ba9111ad3fa677eb3435287
[tiramisu.git] / test / test_config.py
1 # -*- coding: utf-8 -*-
2
3 """theses tests are much more to test that config, option description, vs...
4 **it's there** and answers via attribute access"""
5
6 import autopath
7 from py.test import raises
8
9 from tiramisu.config import Config, SubConfig
10 from tiramisu.option import IntOption, FloatOption, StrOption, ChoiceOption, \
11     BoolOption, UnicodeOption, OptionDescription
12 from tiramisu.error import ConflictError, ConfigError, PropertiesOptionError
13 import weakref
14
15
16 def make_description():
17     gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref')
18     gcdummy = BoolOption('dummy', 'dummy', default=False)
19     objspaceoption = ChoiceOption('objspace', 'Object space',
20                                   ('std', 'thunk'), 'std')
21     booloption = BoolOption('bool', 'Test boolean option', default=True)
22     intoption = IntOption('int', 'Test int option', default=0)
23     floatoption = FloatOption('float', 'Test float option', default=2.3)
24     stroption = StrOption('str', 'Test string option', default="abc", properties=('mandatory', ))
25     boolop = BoolOption('boolop', 'Test boolean option op', default=True, properties=('hidden',))
26     wantref_option = BoolOption('wantref', 'Test requires', default=False)
27     wantframework_option = BoolOption('wantframework', 'Test requires',
28                                       default=False)
29
30     gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption])
31     descr = OptionDescription('tiram', '', [gcgroup, booloption, objspaceoption,
32                                             wantref_option, stroption,
33                                             wantframework_option,
34                                             intoption, boolop])
35     return descr
36
37
38 def test_base_config():
39     """making a :class:`tiramisu.config.Config()` object
40     and a :class:`tiramisu.option.OptionDescription()` object
41     """
42     gcdummy = BoolOption('dummy', 'dummy', default=False)
43     descr = OptionDescription('tiramisu', '', [gcdummy])
44     cfg = Config(descr)
45     assert cfg.dummy is False
46     dm = cfg.unwrap_from_path('dummy')
47     assert dm.impl_getname() == 'dummy'
48
49
50 def test_not_config():
51     assert raises(TypeError, "Config('str')")
52
53
54 def test_base_path():
55     gcdummy = BoolOption('dummy', 'dummy', default=False)
56     descr = OptionDescription('tiramisu', '', [gcdummy])
57     cfg = Config(descr)
58     assert cfg._impl_path is None
59     base = OptionDescription('config', '', [descr])
60     cfg = Config(base)
61     assert cfg._impl_path is None
62     assert cfg.tiramisu._impl_path == 'tiramisu'
63     nbase = OptionDescription('baseconfig', '', [base])
64     cfg = Config(nbase)
65     assert cfg._impl_path is None
66     assert cfg.config._impl_path == 'config'
67     assert cfg.config.tiramisu._impl_path == 'config.tiramisu'
68
69
70 def test_reset_value():
71     descr = make_description()
72     cfg = Config(descr)
73     assert cfg.gc.dummy is False
74     cfg.gc.dummy = True
75     assert cfg.gc.dummy is True
76
77
78 def test_base_config_and_groups():
79     descr = make_description()
80     # overrides the booloption default value
81     config = Config(descr)
82     config.bool = False
83     assert config.gc.name == 'ref'
84     assert config.bool is False
85     nm = config.unwrap_from_path('gc.name')
86     assert nm.impl_getname() == 'name'
87     gc = config.unwrap_from_path('gc')
88     assert gc.impl_getname() == 'gc'
89     #nm = config.unwrap_from_name('name')
90     #assert nm.impl_getname() == 'name'
91
92
93 def test_base_config_force_permissive():
94     descr = make_description()
95     config = Config(descr)
96     config.read_write()
97     config.cfgimpl_get_settings().setpermissive(('hidden',))
98     raises(PropertiesOptionError, "config.getattr('boolop')")
99     assert config.getattr('boolop', force_permissive=True) is True
100
101
102 def test_base_config_in_a_tree():
103     "how options are organized into a tree, see :ref:`tree`"
104     descr = make_description()
105     config = Config(descr)
106     config.bool = False
107     assert config.gc.name == 'ref'
108     config.gc.name = 'framework'
109     assert config.gc.name == 'framework'
110     assert getattr(config, "gc.name") == 'framework'
111
112     assert config.objspace == 'std'
113     config.objspace = 'thunk'
114     assert config.objspace == 'thunk'
115
116     assert config.gc.float == 2.3
117     assert config.int == 0
118     config.gc.float = 3.4
119     config.int = 123
120     assert config.gc.float == 3.4
121     assert config.int == 123
122
123     assert not config.wantref
124
125     assert config.str == "abc"
126     config.str = "def"
127     assert config.str == "def"
128
129     raises(AttributeError, 'config.gc.foo = "bar"')
130
131     config = Config(descr)
132     config.bool = False
133     assert config.gc.name == 'ref'
134     config.wantframework = True
135
136
137 def test_cfgimpl_get_home_by_path():
138     " :meth:`tiramisu.config.SubConfig.cfgimpl_get_home_by_path()` to retrieve a path"
139     descr = make_description()
140     config = Config(descr)
141     config.bool = False
142     assert config.cfgimpl_get_home_by_path('gc.dummy')[1] == 'dummy'
143     assert config.cfgimpl_get_home_by_path('dummy')[1] == 'dummy'
144
145
146 def test_not_valid_properties():
147     raises(TypeError, "stroption = StrOption('str', 'Test string option', default='abc', properties=['mandatory',])")
148
149
150 def test_information_config():
151     descr = make_description()
152     config = Config(descr)
153     string = 'some informations'
154     config.impl_set_information('info', string)
155     assert config.impl_get_information('info') == string
156     raises(ValueError, "config.impl_get_information('noinfo')")
157     assert config.impl_get_information('noinfo', 'default') == 'default'
158
159
160 #FIXME test impl_get_xxx pour OD ou ne pas cacher
161 def test_config_impl_get_path_by_opt():
162     descr = make_description()
163     config = Config(descr)
164     dummy = config.unwrap_from_path('gc.dummy')
165     boo = config.unwrap_from_path('bool')
166     unknown = IntOption('test', '')
167     assert config.cfgimpl_get_description().impl_get_path_by_opt(boo) == 'bool'
168     assert config.cfgimpl_get_description().impl_get_path_by_opt(dummy) == 'gc.dummy'
169     raises(AttributeError, "config.cfgimpl_get_description().impl_get_path_by_opt(unknown)")
170
171
172 def test_config_impl_get_opt_by_path():
173     descr = make_description()
174     config = Config(descr)
175     dummy = config.unwrap_from_path('gc.dummy')
176     boo = config.unwrap_from_path('bool')
177     assert config.cfgimpl_get_description().impl_get_opt_by_path('bool') == boo
178     assert config.cfgimpl_get_description().impl_get_opt_by_path('gc.dummy') == dummy
179     raises(AttributeError, "config.cfgimpl_get_description().impl_get_opt_by_path('gc.unknown')")
180
181
182 def test_information_display():
183     g1 = IntOption('g1', '', 1)
184     g2 = StrOption('g2', '', 'héhé')
185     g3 = UnicodeOption('g3', '', u'héhé')
186     g4 = BoolOption('g4', '', True)
187     g5 = StrOption('g5', '')
188     d1 = OptionDescription('od', '', [g1, g2, g3, g4, g5])
189     root = OptionDescription('root', '', [d1])
190     config = Config(root)
191     config.od == """g1 = 1
192 g2 = héhé
193 g3 = héhé
194 g4 = True
195 g5 = None"""
196     config == '[od]'
197
198
199 def test_get_modified_values():
200     g1 = IntOption('g1', '', 1)
201     g2 = StrOption('g2', '', 'héhé')
202     g3 = UnicodeOption('g3', '', u'héhé')
203     g4 = BoolOption('g4', '', True)
204     g5 = StrOption('g5', '')
205     d1 = OptionDescription('od', '', [g1, g2, g3, g4, g5])
206     root = OptionDescription('root', '', [d1])
207     config = Config(root)
208     assert config.cfgimpl_get_values().get_modified_values() == {}
209     config.od.g5 = 'yes'
210     assert config.cfgimpl_get_values().get_modified_values() == {'od.g5': ('user', 'yes')}
211     config.od.g4 = True
212     assert config.cfgimpl_get_values().get_modified_values() == {'od.g5': ('user', 'yes'), 'od.g4': ('user', True)}
213
214
215 def test_has_value():
216     g1 = IntOption('g1', '', 1)
217     g2 = StrOption('g2', '', 'héhé')
218     g3 = UnicodeOption('g3', '', u'héhé')
219     g4 = BoolOption('g4', '', True)
220     g5 = StrOption('g5', '')
221     d1 = OptionDescription('od', '', [g1, g2, g3, g4, g5])
222     root = OptionDescription('root', '', [d1])
223     config = Config(root)
224     assert not g5 in config.cfgimpl_get_values()
225     config.od.g5 = 'yes'
226     assert g5 in config.cfgimpl_get_values()
227
228
229 def test_values_not_setitem():
230     g1 = IntOption('g1', '', 1)
231     g2 = StrOption('g2', '', 'héhé')
232     g3 = UnicodeOption('g3', '', u'héhé')
233     g4 = BoolOption('g4', '', True)
234     g5 = StrOption('g5', '')
235     d1 = OptionDescription('od', '', [g1, g2, g3, g4, g5])
236     root = OptionDescription('root', '', [d1])
237     config = Config(root)
238     raises(ValueError, "config.cfgimpl_get_values()[g1] = 2")
239
240
241 def test_duplicated_option():
242     g1 = IntOption('g1', '', 1)
243     #in same OptionDescription
244     raises(ConflictError, "d1 = OptionDescription('od', '', [g1, g1])")
245
246
247 def test_duplicated_option_diff_od():
248     g1 = IntOption('g1', '', 1)
249     d1 = OptionDescription('od1', '', [g1])
250     #in different OptionDescription
251     d2 = OptionDescription('od2', '', [g1, d1])
252     raises(ConflictError, 'Config(d2)')
253
254
255 def test_cannot_assign_value_to_option_description():
256     descr = make_description()
257     cfg = Config(descr)
258     raises(TypeError, "cfg.gc = 3")
259
260
261 def test_config_multi():
262     i1 = IntOption('test1', '', multi=True)
263     i2 = IntOption('test2', '', multi=True, default_multi=1)
264     i3 = IntOption('test3', '', default=[2], multi=True, default_multi=1)
265     od = OptionDescription('test', '', [i1, i2, i3])
266     config = Config(od)
267     assert config.test1 == []
268     assert config.test2 == []
269     config.test2.append()
270     assert config.test2 == [1]
271     assert config.test3 == [2]
272     config.test3.append()
273     assert config.test3 == [2, 1]
274
275
276 def test_no_validation():
277     i1 = IntOption('test1', '')
278     od = OptionDescription('test', '', [i1])
279     c = Config(od)
280     setting = c.cfgimpl_get_settings()
281     c.test1 = 1
282     raises(ValueError, 'c.test1 = "yes"')
283     assert c.test1 == 1
284     setting.remove('validator')
285     c.test1 = "yes"
286     assert c.test1 == "yes"
287     setting.append('validator')
288     raises(ValueError, 'c.test1')
289     del(c.test1)
290     assert c.test1 is None
291
292
293 def test_delete_config_with_subconfig():
294     test = IntOption('test', '')
295     multi = IntOption('multi', '', multi=True)
296     od = OptionDescription('od', '', [test, multi])
297     odroot = OptionDescription('odroot', '', [od])
298     c = Config(odroot)
299     sub = c.od
300     val = c.cfgimpl_get_values()
301     setting = c.cfgimpl_get_settings()
302     val[test]
303     val[multi]
304     setting[test]
305     sub.make_dict()
306     del(c)
307     raises(ConfigError, 'val[test]')
308     raises(ConfigError, 'val[multi]')
309     raises(ConfigError, 'setting[test]')
310     raises(ConfigError, 'sub.make_dict()')
311
312
313 def test_config_weakref():
314     o = OptionDescription('val', '', [])
315     o2 = OptionDescription('val', '', [o])
316     c = Config(o2)
317     SubConfig(o, weakref.ref(c))
318     raises(ValueError, "SubConfig(o, c)")
319     s = SubConfig(o, weakref.ref(c))
320     assert s._cfgimpl_get_context() == c
321     del(c)
322     raises(ConfigError, "s._cfgimpl_get_context()")
323
324
325 def test_config_str():
326     gcdummy = BoolOption('dummy', 'dummy', default=False)
327     gcdummy1 = BoolOption('dummy1', 'dummy', default=False, properties=('disabled',))
328     o = OptionDescription('o', '', [gcdummy, gcdummy1])
329     descr = OptionDescription('tiramisu', '', [o])
330     cfg = Config(descr)
331     cfg.read_only()
332     str(cfg)
333     str(cfg.o)
334
335
336 def test_config_od_function():
337     gcdummy = BoolOption('dummy', 'dummy', default=False)
338     gcdummy1 = BoolOption('dummy1', 'dummy', default=False, properties=('disabled',))
339     o = OptionDescription('o', '', [gcdummy, gcdummy1])
340     descr = OptionDescription('tiramisu', '', [o])
341     cfg = Config(descr)
342     try:
343         print cfg.impl_get_opt_by_path()
344     except AttributeError, err:
345         assert str(err) == _('unknown Option {0} in OptionDescription {1}'
346                              '').format('impl_get_opt_by_path', descr.impl_getname())