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