2 To check that common dangerous operations are not allowed by the safe_eval mechanism, attempt to
3 evaluate unauthorized expressions, and verify that they trigger an error.
5 1. Try a few common expressions to verify they work with safe_eval
7 !python {model: ir.model}: |
8 from tools.safe_eval import safe_eval
9 expected = (1, {"a": 9 * 2}, (True, False, None))
10 actual = safe_eval('(1, {"a": 9 * 2}, (True, False, None))')
11 assert actual == expected, "Simple python expressions are not working with safe_eval"
13 2. Try simple literal definition to verify it works with literal_eval
15 !python {model: ir.model}: |
16 from tools.safe_eval import literal_eval
17 expected = (1, {"a": 9}, (True, False, None))
18 actual = literal_eval('(1, {"a": 9}, (True, False, None))')
19 assert actual == expected, "Simple python expressions are not working with literal_eval"
21 3. Try arithmetic expression in literal_eval to verify it does not work
23 !python {model: ir.model}: |
24 from tools.safe_eval import literal_eval
26 literal_eval('(1, {"a": 2*9}, (True, False, None))')
27 assert False, "literal_eval should not accept arithmetic expressions"
31 4. Try forbidden expressions in literal_eval to verify they are not allowed
33 !python {model: ir.model}: |
34 from tools.safe_eval import literal_eval
36 literal_eval('{"a": True.__class__}')
37 assert False, "literal_eval should accept only literals"
41 5. Try forbidden expressions in safe_eval to verify they are not allowed (open)
43 !python {model: ir.model}: |
44 from tools.safe_eval import safe_eval
46 safe_eval('open("/etc/passwd","r")')
47 assert False, "safe_eval should not allow calling open() builtin"
51 # NameError should be raised because open() builtin is not found,
52 # but other exceptions probably indicate that open() was executed!
53 assert False, "safe_eval should not allow calling open() builtin"
56 "ORM test: verify that parent_store computation are going right"
58 0. Emulate normal behavior of tree structure storing
60 !python {model: res.partner.category}: |
61 # pretend the pool has finished loading to avoid deferring parent_store computation
62 self.pool._init = False
64 "1.0 Setup test partner categories: parent root"
66 !record {model: res.partner.category, id: test_categ_root}:
69 "1.1 Setup test partner categories: parent category"
71 !record {model: res.partner.category, id: test_categ_0}:
73 parent_id: test_categ_root
75 "1.2 Setup test partner categories: child 1"
77 !record {model: res.partner.category, id: test_categ_1}:
79 parent_id: test_categ_0
81 "1.3 Setup test partner categories: child 2"
83 !record {model: res.partner.category, id: test_categ_2}:
85 parent_id: test_categ_0
87 "1.4 Setup test partner categories: child 2-1"
89 !record {model: res.partner.category, id: test_categ_21}:
91 parent_id: test_categ_2
93 2. Duplicate the parent category and verify that the children have been duplicated too and are below the new parent
95 !python {model: res.partner.category}: |
96 new_id = self.copy(cr, uid, ref('test_categ_0'))
97 new_struct = self.search(cr, uid, [('parent_id', 'child_of', new_id)])
98 assert len(new_struct) == 4, "After duplication, the new object must have the childs records"
99 old_struct = self.search(cr, uid, [('parent_id', 'child_of', ref('test_categ_0'))])
100 assert len(old_struct) == 4, "After duplication, previous record must have old childs records only"
101 assert (not set(new_struct).intersection(old_struct)), "After duplication, nodes should not be mixed"
103 3. Duplicate the children then reassign them to the new parent (1st method) and check the parent_store structure.
105 !python {model: res.partner.category}: |
106 new_child1_id = self.copy(cr, uid, ref('test_categ_1'))
107 new_child2_id = self.copy(cr, uid, ref('test_categ_2'))
108 new_id = self.copy(cr, uid, ref('test_categ_0'), {'child_ids': []})
109 self.write(cr, uid, [new_child1_id, new_child2_id], {'parent_id': new_id})
110 new_struct = self.search(cr, uid, [('parent_id', 'child_of', new_id)])
111 assert len(new_struct) == 4, "After duplication, the new object must have the childs records"
112 old_struct = self.search(cr, uid, [('parent_id', 'child_of', ref('test_categ_0'))])
113 assert len(old_struct) == 4, "After duplication, previous record must have old childs records only"
114 assert (not set(new_struct).intersection(old_struct)), "After duplication, nodes should not be mixed"
116 4. Duplicate the children then reassign them to the new parent (2nd method) and check the parent_store structure.
118 !python {model: res.partner.category}: |
119 new_child1_id = self.copy(cr, uid, ref('test_categ_1'))
120 new_child2_id = self.copy(cr, uid, ref('test_categ_2'))
121 old_struct = self.search(cr, uid, [('parent_id', 'child_of', ref('test_categ_0'))])
122 new_id = self.copy(cr, uid, ref('test_categ_0'), {'child_ids': [(6,0,[new_child1_id, new_child2_id])]})
123 new_struct = self.search(cr, uid, [('parent_id', 'child_of', new_id)])
124 assert len(new_struct) == 4, "After duplication, the new object must have the childs records"
125 old_struct = self.search(cr, uid, [('parent_id', 'child_of', ref('test_categ_0'))])
126 assert len(old_struct) == 4, "After duplication, previous record must have old childs records only"
127 assert (not set(new_struct).intersection(old_struct)), "After duplication, nodes should not be mixed"
129 5. Duplicate the children then reassign them to the new parent (3rd method) and make sure the parent_store structure is still right.
131 !python {model: res.partner.category}: |
132 new_child1_id = self.copy(cr, uid, ref('test_categ_1'))
133 new_child2_id = self.copy(cr, uid, ref('test_categ_2'))
134 new_id = self.copy(cr, uid, ref('test_categ_0'), {'child_ids': []})
135 self.write(cr, uid, [new_id], {'child_ids': [(4,new_child1_id), (4,new_child2_id)]})
136 new_struct = self.search(cr, uid, [('parent_id', 'child_of', new_id)])
137 assert len(new_struct) == 4, "After duplication, the new object must have the childs records"
138 old_struct = self.search(cr, uid, [('parent_id', 'child_of', ref('test_categ_0'))])
139 assert len(old_struct) == 4, "After duplication, previous record must have old childs records only"
140 assert (not set(new_struct).intersection(old_struct)), "After duplication, nodes should not be mixed"
142 6. Restore pool state after the test
144 !python {model: res.partner.category}: |
145 self.pool._init = True
148 "OSV Memory: Verify that osv_memory properly handles large data allocation"
150 1. No "count-based" auto-vaccuum when max_count is disabled
152 !python {model: base.language.export}: |
153 # setup special limits for the test, these will be reset at next pool reload anyway
154 self._max_count = None
156 for i in xrange(num_recs):
157 self.create(cr, uid, {'format':'po'})
158 assert (len(self.datas) >= num_recs), "OSV Memory must not auto-vaccum records from the current transaction if max_count is not set"
160 2. Auto-vaccuum should be enabled when max_count is set
162 !python {model: base.language.export}: |
163 # setup special limits for the test, these will be reset at next pool reload anyway
164 self._max_count = 100
166 for i in xrange(num_recs):
167 self.create(cr, uid, {'name': i, 'format':'po'})
168 assert (self._max_count <= len(self.datas) < self._max_count + self._check_time), "OSV Memory must auto-expire records when max_count is reached"
169 for k,v in self.datas.iteritems():
170 assert (int(v['name']) >= (num_recs - (self._max_count + self._check_time))), "OSV Memory must auto-expire records based on age"
172 3. Auto-vaccuum should be based on age only when max_count is not set
174 !python {model: base.language.export}: |
175 # setup special limits for the test, these will be reset at next pool reload anyway
176 self._max_count = None
177 self._max_hours = 0.01 #36 seconds
179 for i in xrange(num_recs):
180 self.create(cr, uid, {'format':'po'})
181 assert (len(self.datas) >= num_recs), "OSV Memory must not auto-expire records from the current transaction"
184 for k,v in self.datas.iteritems():
185 v['internal.date_access'] = 0
186 self.vaccum(cr, 1, force=True)
188 assert (len(self.datas) == 0), "OSV Memory must expire old records after vaccuum"