we can pickle object
[tiramisu.git] / test / test_state.py
1 import autopath
2
3 from tiramisu.option import BoolOption, UnicodeOption, SymLinkOption, \
4     IntOption, OptionDescription
5 from tiramisu.config import Config, GroupConfig, MetaConfig
6 from tiramisu.setting import owners
7 from tiramisu.storage import delete_session
8 from tiramisu.error import ConfigError
9 from pickle import dumps, loads
10 from py.test import raises
11
12
13 def return_value(value=None):
14         return value
15
16
17 def _get_slots(opt):
18     slots = set()
19     for subclass in opt.__class__.__mro__:
20         if subclass is not object:
21             slots.update(subclass.__slots__)
22     return slots
23
24
25 def _no_state(opt):
26     for attr in _get_slots(opt):
27         if 'state' in attr:
28             try:
29                 getattr(opt, attr)
30             except:
31                 pass
32             else:
33                 raise Exception('opt should have already attribute {0}'.format(attr))
34
35
36 def _diff_opt(opt1, opt2):
37     attr1 = set(_get_slots(opt1))
38     attr2 = set(_get_slots(opt2))
39     diff1 = attr1 - attr2
40     diff2 = attr2 - attr1
41     if diff1 != set():
42         raise Exception('more attribute in opt1 {0}'.format(list(diff1)))
43     if diff2 != set():
44         raise Exception('more attribute in opt2 {0}'.format(list(diff2)))
45     for attr in attr1:
46         if attr in ['_cache_paths', '_cache_consistencies']:
47             continue
48         err1 = False
49         err2 = False
50         val1 = None
51         val2 = None
52         try:
53             val1 = getattr(opt1, attr)
54         except:
55             err1 = True
56
57         try:
58             val2 = getattr(opt2, attr)
59         except:
60             err2 = True
61         assert err1 == err2
62         if val1 is None:
63             assert val1 == val2
64         elif attr == '_children':
65             assert val1[0] == val2[0]
66             for index, _opt in enumerate(val1[1]):
67                 assert _opt._name == val2[1][index]._name
68         elif attr == '_requires':
69             if val1 == val2 == []:
70                 pass
71             else:
72                 assert val1[0][0][0]._name == val2[0][0][0]._name
73                 assert val1[0][0][1:] == val2[0][0][1:]
74         elif attr == '_opt':
75             assert val1._name == val2._name
76         elif attr == '_consistencies':
77             # dict is only a cache
78             if isinstance(val1, list):
79                 for index, consistency in enumerate(val1):
80                     assert consistency[0] == val2[index][0]
81                     for idx, opt in enumerate(consistency[1]):
82                         assert opt._name == val2[index][1][idx]._name
83         elif attr == '_callback':
84             assert val1 == val2
85         elif attr == '_callback_params':
86             if val1 is not None:
87                 for key, values in val1.items():
88                     for idx, value in enumerate(values):
89                         if isinstance(value, tuple):
90                             assert val1[key][idx][0]._name == val2[key][idx][0]._name
91                             assert val1[key][idx][1] == val2[key][idx][1]
92                         else:
93                             assert val1[key][idx] == val2[key][idx]
94             else:
95                 assert val1 == val2
96         else:
97             assert val1 == val2
98
99
100 def _diff_conf(cfg1, cfg2):
101     attr1 = set(_get_slots(cfg1))
102     attr2 = set(_get_slots(cfg2))
103     diff1 = attr1 - attr2
104     diff2 = attr2 - attr1
105     if diff1 != set():
106         raise Exception('more attribute in cfg1 {0}'.format(list(diff1)))
107     if diff2 != set():
108         raise Exception('more attribute in cfg2 {0}'.format(list(diff2)))
109     for attr in attr1:
110         if attr in ('_impl_context', '__weakref__'):
111             continue
112         err1 = False
113         err2 = False
114         val1 = None
115         val2 = None
116         try:
117             val1 = getattr(cfg1, attr)
118         except:
119             err1 = True
120
121         try:
122             val2 = getattr(cfg2, attr)
123         except:
124             err2 = True
125         assert err1 == err2
126         if val1 is None:
127             assert val1 == val2
128         elif attr == '_impl_values':
129             assert cfg1.cfgimpl_get_values().get_modified_values() == cfg2.cfgimpl_get_values().get_modified_values()
130         elif attr == '_impl_settings':
131             assert cfg1.cfgimpl_get_settings().get_modified_properties() == cfg2.cfgimpl_get_settings().get_modified_properties()
132             assert cfg1.cfgimpl_get_settings().get_modified_permissives() == cfg2.cfgimpl_get_settings().get_modified_permissives()
133         elif attr == '_impl_descr':
134             _diff_opt(cfg1.cfgimpl_get_description(), cfg2.cfgimpl_get_description())
135         elif attr == '_impl_children':
136             for index, _opt in enumerate(val1):
137                 _diff_conf(_opt, val2[index])
138         else:
139             assert val1 == val2
140
141
142 def test_diff_opt():
143     b = BoolOption('b', '')
144     u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}])
145     s = SymLinkOption('s', u)
146     o = OptionDescription('o', '', [b, u, s])
147     o1 = OptionDescription('o1', '', [o])
148
149     a = dumps(o1)
150     q = loads(a)
151     _diff_opt(o1, q)
152     _diff_opt(o1.o, q.o)
153     _diff_opt(o1.o.b, q.o.b)
154     _diff_opt(o1.o.u, q.o.u)
155     _diff_opt(o1.o.s, q.o.s)
156
157
158 def test_only_optiondescription():
159     b = BoolOption('b', '')
160     raises(SystemError, "a = dumps(b)")
161
162
163 def test_diff_opt_cache():
164     b = BoolOption('b', '')
165     u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}])
166     u.impl_add_consistency('not_equal', b)
167     s = SymLinkOption('s', u)
168     o = OptionDescription('o', '', [b, u, s])
169     o1 = OptionDescription('o1', '', [o])
170     o1.impl_build_cache_consistency()
171     o1.impl_build_cache_option()
172
173     a = dumps(o1)
174     q = loads(a)
175     _diff_opt(o1, q)
176     _diff_opt(o1.o, q.o)
177     _diff_opt(o1.o.b, q.o.b)
178     _diff_opt(o1.o.u, q.o.u)
179     _diff_opt(o1.o.s, q.o.s)
180
181
182 def test_diff_opt_callback():
183     b = BoolOption('b', '', callback=return_value)
184     b2 = BoolOption('b2', '', callback=return_value, callback_params={'': ('yes',)})
185     b3 = BoolOption('b3', '', callback=return_value, callback_params={'': ('yes', (b, False)), 'value': ('no',)})
186     o = OptionDescription('o', '', [b, b2, b3])
187     o1 = OptionDescription('o1', '', [o])
188     o1.impl_build_cache_consistency()
189     o1.impl_build_cache_option()
190
191     a = dumps(o1)
192     q = loads(a)
193     _diff_opt(o1, q)
194     _diff_opt(o1.o, q.o)
195     _diff_opt(o1.o.b, q.o.b)
196     _diff_opt(o1.o.b2, q.o.b2)
197     _diff_opt(o1.o.b3, q.o.b3)
198
199
200 def test_no_state_attr():
201     # all _state_xxx attributes should be deleted
202     b = BoolOption('b', '')
203     u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}])
204     s = SymLinkOption('s', u)
205     o = OptionDescription('o', '', [b, u, s])
206     o1 = OptionDescription('o1', '', [o])
207
208     a = dumps(o1)
209     q = loads(a)
210     _no_state(q)
211     _no_state(q.o)
212     _no_state(q.o.b)
213     _no_state(q.o.u)
214     _no_state(q.o.s)
215
216
217 def test_state_config():
218     val1 = BoolOption('val1', "")
219     maconfig = OptionDescription('rootconfig', '', [val1])
220     try:
221         cfg = Config(maconfig, persistent=True, session_id='29090931')
222     except ValueError:
223         cfg = Config(maconfig, session_id='29090931')
224         cfg._impl_test = True
225     a = dumps(cfg)
226     q = loads(a)
227     _diff_conf(cfg, q)
228     try:
229         delete_session('config', '29090931')
230     except ConfigError:
231         pass
232
233
234 def test_state_properties():
235     val1 = BoolOption('val1', "")
236     maconfig = OptionDescription('rootconfig', '', [val1])
237     try:
238         cfg = Config(maconfig, persistent=True, session_id='29090932')
239     except ValueError:
240         cfg = Config(maconfig, session_id='29090932')
241         cfg._impl_test = True
242     cfg.read_write()
243     cfg.cfgimpl_get_settings()[val1].append('test')
244     a = dumps(cfg)
245     q = loads(a)
246     _diff_conf(cfg, q)
247     try:
248         delete_session('config', '29090932')
249     except ConfigError:
250         pass
251
252
253 def test_state_values():
254     val1 = BoolOption('val1', "")
255     maconfig = OptionDescription('rootconfig', '', [val1])
256     try:
257         cfg = Config(maconfig, persistent=True, session_id='29090933')
258     except ValueError:
259         cfg = Config(maconfig, session_id='29090933')
260         cfg._impl_test = True
261     cfg.val1 = True
262     a = dumps(cfg)
263     q = loads(a)
264     _diff_conf(cfg, q)
265     q.val1 = False
266     assert cfg.val1 is True
267     assert q.val1 is False
268     try:
269         delete_session('config', '29090933')
270     except ConfigError:
271         pass
272
273
274 def test_state_values_owner():
275     val1 = BoolOption('val1', "")
276     maconfig = OptionDescription('rootconfig', '', [val1])
277     try:
278         cfg = Config(maconfig, persistent=True, session_id='29090934')
279     except ValueError:
280         cfg = Config(maconfig, session_id='29090934')
281         cfg._impl_test = True
282     owners.addowner('newowner')
283     cfg.cfgimpl_get_settings().setowner(owners.newowner)
284     cfg.val1 = True
285     a = dumps(cfg)
286     q = loads(a)
287     _diff_conf(cfg, q)
288     q.val1 = False
289     nval1 = q.cfgimpl_get_description().val1
290     assert q.getowner(nval1) == owners.newowner
291     try:
292         delete_session('config', '29090934')
293     except ConfigError:
294         pass
295
296
297 def test_state_metaconfig():
298     i1 = IntOption('i1', '')
299     od1 = OptionDescription('od1', '', [i1])
300     od2 = OptionDescription('od2', '', [od1])
301     conf1 = Config(od2, session_id='29090935')
302     conf1._impl_test = True
303     conf2 = Config(od2, session_id='29090936')
304     conf2._impl_test = True
305     meta = MetaConfig([conf1, conf2], session_id='29090937')
306     meta._impl_test = True
307     raises(ConfigError, "dumps(meta)")
308     try:
309         delete_session('config', '29090935')
310         delete_session('config', '29090936')
311         delete_session('config', '29090937')
312     except ConfigError:
313         pass
314
315
316 def test_state_groupconfig():
317     i1 = IntOption('i1', '')
318     od1 = OptionDescription('od1', '', [i1])
319     od2 = OptionDescription('od2', '', [od1])
320     conf1 = Config(od2, session_id='29090935')
321     conf1._impl_test = True
322     conf2 = Config(od2, session_id='29090936')
323     conf2._impl_test = True
324     meta = GroupConfig([conf1, conf2], session_id='29090937')
325     meta._impl_test = True
326     a = dumps(meta)
327     q = loads(a)
328     _diff_conf(meta, q)
329     try:
330         delete_session('config', '29090935')
331         delete_session('config', '29090936')
332         delete_session('config', '29090937')
333     except ConfigError:
334         pass
335
336
337 def test_state_unkown_setting_owner():
338     """load an unknow _owner, should create it"""
339     assert not 'supernewuser' in owners.__dict__
340     loads("""ccopy_reg
341 _reconstructor
342 p0
343 (ctiramisu.setting
344 Settings
345 p1
346 c__builtin__
347 object
348 p2
349 Ntp3
350 Rp4
351 (dp5
352 S'_owner'
353 p6
354 S'supernewuser'
355 p7
356 sS'_p_'
357 p8
358 g0
359 (ctiramisu.storage.dictionary.setting
360 Settings
361 p9
362 g2
363 Ntp10
364 Rp11
365 (dp12
366 S'_cache'
367 p13
368 (dp14
369 sS'_permissives'
370 p15
371 (dp16
372 sS'_properties'
373 p17
374 (dp18
375 sbsb.
376 .""")
377     assert 'supernewuser' in owners.__dict__