consistancies can have more than one option
[tiramisu.git] / test / test_state.py
1 from tiramisu.option import BoolOption, UnicodeOption, SymLinkOption, \
2     OptionDescription
3 from tiramisu.config import Config
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']:
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 test_diff_opt():
94     b = BoolOption('b', '')
95     u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}])
96     #u.impl_add_consistency('not_equal', b)
97     s = SymLinkOption('s', u)
98     o = OptionDescription('o', '', [b, u, s])
99     o1 = OptionDescription('o1', '', [o])
100
101     a = dumps(o1)
102     q = loads(a)
103     _diff_opt(o1, q)
104     _diff_opt(o1.o, q.o)
105     _diff_opt(o1.o.b, q.o.b)
106     _diff_opt(o1.o.u, q.o.u)
107     _diff_opt(o1.o.s, q.o.s)
108
109
110 def test_diff_opt_cache():
111     b = BoolOption('b', '')
112     u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}])
113     u.impl_add_consistency('not_equal', b)
114     s = SymLinkOption('s', u)
115     o = OptionDescription('o', '', [b, u, s])
116     o1 = OptionDescription('o1', '', [o])
117     o1.impl_build_cache()
118
119     a = dumps(o1)
120     q = loads(a)
121     _diff_opt(o1, q)
122     _diff_opt(o1.o, q.o)
123     _diff_opt(o1.o.b, q.o.b)
124     _diff_opt(o1.o.u, q.o.u)
125     _diff_opt(o1.o.s, q.o.s)
126
127
128 def test_diff_opt_callback():
129     b = BoolOption('b', '', callback=return_value)
130     b2 = BoolOption('b2', '', callback=return_value, callback_params={'': ('yes',)})
131     b3 = BoolOption('b3', '', callback=return_value, callback_params={'': ('yes', (b, False)), 'value': ('no',)})
132     o = OptionDescription('o', '', [b, b2, b3])
133     o1 = OptionDescription('o1', '', [o])
134     o1.impl_build_cache()
135
136     a = dumps(o1)
137     q = loads(a)
138     _diff_opt(o1, q)
139     _diff_opt(o1.o, q.o)
140     _diff_opt(o1.o.b, q.o.b)
141     _diff_opt(o1.o.b2, q.o.b2)
142     _diff_opt(o1.o.b3, q.o.b3)
143
144
145 def test_no_state_attr():
146     # all _state_xxx attributes should be deleted
147     b = BoolOption('b', '')
148     u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}])
149     s = SymLinkOption('s', u)
150     o = OptionDescription('o', '', [b, u, s])
151     o1 = OptionDescription('o1', '', [o])
152
153     a = dumps(o1)
154     q = loads(a)
155     _no_state(q)
156     _no_state(q.o)
157     _no_state(q.o.b)
158     _no_state(q.o.u)
159     _no_state(q.o.s)
160
161
162 def test_state_config():
163     val1 = BoolOption('val1', "")
164     maconfig = OptionDescription('rootconfig', '', [val1])
165     try:
166         cfg = Config(maconfig, persistent=True, session_id='29090931')
167     except ValueError:
168         cfg = Config(maconfig, session_id='29090931')
169         cfg._impl_test = True
170     a = dumps(cfg)
171     q = loads(a)
172     _diff_opt(maconfig, q.cfgimpl_get_description())
173     assert cfg.cfgimpl_get_values().get_modified_values() == q.cfgimpl_get_values().get_modified_values()
174     assert cfg.cfgimpl_get_settings().get_modified_properties() == q.cfgimpl_get_settings().get_modified_properties()
175     assert cfg.cfgimpl_get_settings().get_modified_permissives() == q.cfgimpl_get_settings().get_modified_permissives()
176     try:
177         delete_session('29090931')
178     except ConfigError:
179         pass
180
181
182 def test_state_properties():
183     val1 = BoolOption('val1', "")
184     maconfig = OptionDescription('rootconfig', '', [val1])
185     try:
186         cfg = Config(maconfig, persistent=True, session_id='29090932')
187     except ValueError:
188         cfg = Config(maconfig, session_id='29090932')
189         cfg._impl_test = True
190     cfg.read_write()
191     cfg.cfgimpl_get_settings()[val1].append('test')
192     a = dumps(cfg)
193     q = loads(a)
194     _diff_opt(maconfig, q.cfgimpl_get_description())
195     assert cfg.cfgimpl_get_values().get_modified_values() == q.cfgimpl_get_values().get_modified_values()
196     assert cfg.cfgimpl_get_settings().get_modified_properties() == q.cfgimpl_get_settings().get_modified_properties()
197     assert cfg.cfgimpl_get_settings().get_modified_permissives() == q.cfgimpl_get_settings().get_modified_permissives()
198     try:
199         delete_session('29090931')
200     except ConfigError:
201         pass
202
203
204 def test_state_values():
205     val1 = BoolOption('val1', "")
206     maconfig = OptionDescription('rootconfig', '', [val1])
207     try:
208         cfg = Config(maconfig, persistent=True, session_id='29090933')
209     except ValueError:
210         cfg = Config(maconfig, session_id='29090933')
211         cfg._impl_test = True
212     cfg.val1 = True
213     a = dumps(cfg)
214     q = loads(a)
215     _diff_opt(maconfig, q.cfgimpl_get_description())
216     assert cfg.cfgimpl_get_values().get_modified_values() == q.cfgimpl_get_values().get_modified_values()
217     assert cfg.cfgimpl_get_settings().get_modified_properties() == q.cfgimpl_get_settings().get_modified_properties()
218     assert cfg.cfgimpl_get_settings().get_modified_permissives() == q.cfgimpl_get_settings().get_modified_permissives()
219     q.val1 = False
220     #assert cfg.val1 is True
221     assert q.val1 is False
222     try:
223         delete_session('29090931')
224     except ConfigError:
225         pass
226
227
228 def test_state_values_owner():
229     val1 = BoolOption('val1', "")
230     maconfig = OptionDescription('rootconfig', '', [val1])
231     try:
232         cfg = Config(maconfig, persistent=True, session_id='29090934')
233     except ValueError:
234         cfg = Config(maconfig, session_id='29090934')
235         cfg._impl_test = True
236     owners.addowner('newowner')
237     cfg.cfgimpl_get_settings().setowner(owners.newowner)
238     cfg.val1 = True
239     a = dumps(cfg)
240     q = loads(a)
241     _diff_opt(maconfig, q.cfgimpl_get_description())
242     assert cfg.cfgimpl_get_values().get_modified_values() == q.cfgimpl_get_values().get_modified_values()
243     assert cfg.cfgimpl_get_settings().get_modified_properties() == q.cfgimpl_get_settings().get_modified_properties()
244     assert cfg.cfgimpl_get_settings().get_modified_permissives() == q.cfgimpl_get_settings().get_modified_permissives()
245     q.val1 = False
246     nval1 = q.cfgimpl_get_description().val1
247     assert q.getowner(nval1) == owners.newowner
248     try:
249         delete_session('29090931')
250     except ConfigError:
251         pass