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