[FIX] test_ir_sequence: reduce the number of call to next() (to reduce test time).
[odoo/odoo.git] / openerp / tests / test_ir_sequence.py
1 # -*- coding: utf-8 -*-
2 # Run with one of these commands:
3 #    > OPENERP_ADDONS_PATH='../../addons/trunk' OPENERP_PORT=8069 \
4 #      OPENERP_DATABASE=yy PYTHONPATH=. python tests/test_ir_sequence.py
5 #    > OPENERP_ADDONS_PATH='../../addons/trunk' OPENERP_PORT=8069 \
6 #      OPENERP_DATABASE=yy nosetests tests/test_ir_sequence.py
7 #    > OPENERP_ADDONS_PATH='../../../addons/trunk' OPENERP_PORT=8069 \
8 #      OPENERP_DATABASE=yy PYTHONPATH=../:. unit2 test_ir_sequence
9 # This assume an existing database.
10 import psycopg2
11 import unittest2
12
13 import openerp
14 import common
15
16 DB = common.DB
17 ADMIN_USER_ID = common.ADMIN_USER_ID
18
19 def registry(model):
20     return openerp.modules.registry.RegistryManager.get(DB)[model]
21
22 def cursor():
23     return openerp.modules.registry.RegistryManager.get(DB).db.cursor()
24
25
26 def drop_sequence(code):
27     cr = cursor()
28     for model in ['ir.sequence', 'ir.sequence.type']:
29         s = registry(model)
30         ids = s.search(cr, ADMIN_USER_ID, [('code', '=', code)])
31         s.unlink(cr, ADMIN_USER_ID, ids)
32     cr.commit()
33     cr.close()
34
35 class test_ir_sequence_standard(unittest2.TestCase):
36     """ A few tests for a 'Standard' (i.e. PostgreSQL) sequence. """
37
38     def test_ir_sequence_create(self):
39         """ Try to create a sequence object. """
40         cr = cursor()
41         d = dict(code='test_sequence_type', name='Test sequence type')
42         c = registry('ir.sequence.type').create(cr, ADMIN_USER_ID, d, {})
43         assert c
44         d = dict(code='test_sequence_type', name='Test sequence')
45         c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {})
46         assert c
47         cr.commit()
48         cr.close()
49
50     def test_ir_sequence_search(self):
51         """ Try a search. """
52         cr = cursor()
53         ids = registry('ir.sequence').search(cr, ADMIN_USER_ID, [], {})
54         assert ids
55         cr.commit()
56         cr.close()
57
58     def test_ir_sequence_draw(self):
59         """ Try to draw a number. """
60         cr = cursor()
61         n = registry('ir.sequence').next_by_code(cr, ADMIN_USER_ID, 'test_sequence_type', {})
62         assert n
63         cr.commit()
64         cr.close()
65
66     def test_ir_sequence_draw_twice(self):
67         """ Try to draw a number from two transactions. """
68         cr0 = cursor()
69         cr1 = cursor()
70         n0 = registry('ir.sequence').next_by_code(cr0, ADMIN_USER_ID, 'test_sequence_type', {})
71         assert n0
72         n1 = registry('ir.sequence').next_by_code(cr1, ADMIN_USER_ID, 'test_sequence_type', {})
73         assert n1
74         cr0.commit()
75         cr1.commit()
76         cr0.close()
77         cr1.close()
78
79     @classmethod
80     def tearDownClass(cls):
81         drop_sequence('test_sequence_type')
82
83 class test_ir_sequence_no_gap(unittest2.TestCase):
84     """ Copy of the previous tests for a 'No gap' sequence. """
85
86     def test_ir_sequence_create_no_gap(self):
87         """ Try to create a sequence object. """
88         cr = cursor()
89         d = dict(code='test_sequence_type_2', name='Test sequence type')
90         c = registry('ir.sequence.type').create(cr, ADMIN_USER_ID, d, {})
91         assert c
92         d = dict(code='test_sequence_type_2', name='Test sequence',
93             implementation='no_gap')
94         c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {})
95         assert c
96         cr.commit()
97         cr.close()
98
99     def test_ir_sequence_draw_no_gap(self):
100         """ Try to draw a number. """
101         cr = cursor()
102         n = registry('ir.sequence').next_by_code(cr, ADMIN_USER_ID, 'test_sequence_type_2', {})
103         assert n
104         cr.commit()
105         cr.close()
106
107     def test_ir_sequence_draw_twice_no_gap(self):
108         """ Try to draw a number from two transactions.
109         This is expected to not work.
110         """
111         cr0 = cursor()
112         cr1 = cursor()
113         cr1._default_log_exceptions = False # Prevent logging a traceback
114         msg_re = '^could not obtain lock on row in relation "ir_sequence"$'
115         with self.assertRaisesRegexp(psycopg2.OperationalError, msg_re):
116             n0 = registry('ir.sequence').next_by_code(cr0, ADMIN_USER_ID, 'test_sequence_type_2', {})
117             assert n0
118             n1 = registry('ir.sequence').next_by_code(cr1, ADMIN_USER_ID, 'test_sequence_type_2', {})
119         cr0.close()
120         cr1.close()
121
122     @classmethod
123     def tearDownClass(cls):
124         drop_sequence('test_sequence_type_2')
125
126 class test_ir_sequence_change_implementation(unittest2.TestCase):
127     """ Create sequence objects and change their ``implementation`` field. """
128
129     def test_ir_sequence_1_create(self):
130         """ Try to create a sequence object. """
131         cr = cursor()
132         d = dict(code='test_sequence_type_3', name='Test sequence type')
133         c = registry('ir.sequence.type').create(cr, ADMIN_USER_ID, d, {})
134         assert c
135         d = dict(code='test_sequence_type_3', name='Test sequence')
136         c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {})
137         assert c
138         d = dict(code='test_sequence_type_4', name='Test sequence type')
139         c = registry('ir.sequence.type').create(cr, ADMIN_USER_ID, d, {})
140         assert c
141         d = dict(code='test_sequence_type_4', name='Test sequence',
142             implementation='no_gap')
143         c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {})
144         assert c
145         cr.commit()
146         cr.close()
147
148     def test_ir_sequence_2_write(self):
149         cr = cursor()
150         ids = registry('ir.sequence').search(cr, ADMIN_USER_ID,
151             [('code', 'in', ['test_sequence_type_3', 'test_sequence_type_4'])], {})
152         registry('ir.sequence').write(cr, ADMIN_USER_ID, ids,
153             {'implementation': 'standard'}, {})
154         registry('ir.sequence').write(cr, ADMIN_USER_ID, ids,
155             {'implementation': 'no_gap'}, {})
156         cr.commit()
157         cr.close()
158
159     def test_ir_sequence_3_unlink(self):
160         cr = cursor()
161         ids = registry('ir.sequence').search(cr, ADMIN_USER_ID,
162             [('code', 'in', ['test_sequence_type_3', 'test_sequence_type_4'])], {})
163         registry('ir.sequence').unlink(cr, ADMIN_USER_ID, ids, {})
164         cr.commit()
165         cr.close()
166
167     @classmethod
168     def tearDownClass(cls):
169         drop_sequence('test_sequence_type_3')
170         drop_sequence('test_sequence_type_4')
171
172 class test_ir_sequence_generate(unittest2.TestCase):
173     """ Create sequence objects and generate some values. """
174
175     def test_ir_sequence_create(self):
176         """ Try to create a sequence object. """
177         cr = cursor()
178         d = dict(code='test_sequence_type_5', name='Test sequence type')
179         c = registry('ir.sequence.type').create(cr, ADMIN_USER_ID, d, {})
180         assert c
181         d = dict(code='test_sequence_type_5', name='Test sequence')
182         c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {})
183         assert c
184         cr.commit()
185         cr.close()
186
187         cr = cursor()
188         f = lambda *a: registry('ir.sequence').next_by_code(cr, ADMIN_USER_ID, 'test_sequence_type_5', {})
189         assert all(str(x) == f() for x in xrange(1,10))
190         cr.commit()
191         cr.close()
192
193     def test_ir_sequence_create_no_gap(self):
194         """ Try to create a sequence object. """
195         cr = cursor()
196         d = dict(code='test_sequence_type_6', name='Test sequence type')
197         c = registry('ir.sequence.type').create(cr, ADMIN_USER_ID, d, {})
198         assert c
199         d = dict(code='test_sequence_type_6', name='Test sequence')
200         c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {})
201         assert c
202         cr.commit()
203         cr.close()
204
205         cr = cursor()
206         f = lambda *a: registry('ir.sequence').next_by_code(cr, ADMIN_USER_ID, 'test_sequence_type_6', {})
207         assert all(str(x) == f() for x in xrange(1,10))
208         cr.commit()
209         cr.close()
210
211     @classmethod
212     def tearDownClass(cls):
213         drop_sequence('test_sequence_type_5')
214         drop_sequence('test_sequence_type_6')
215
216
217 if __name__ == '__main__':
218     unittest2.main()
219
220
221 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: