diff options
| author | Vo Minh Thu <vmt@openerp.com> | 2011-10-03 17:35:09 +0200 |
|---|---|---|
| committer | Vo Minh Thu <vmt@openerp.com> | 2011-10-03 17:35:09 +0200 |
| commit | d9b6f5e2d0d0c30e4e55bc72454b6ec4b720232c (patch) | |
| tree | 14eb229c961e3413abd06b6ad1a86d64d2d3a2ab /tests | |
| parent | fbb6e5e56aaf36ff652edbec0181a0fcb95a3601 (diff) | |
| parent | bf3d0d604c89edfd709603c8ca261d020e9ac748 (diff) | |
[MERGE] merged trunk.
bzr revid: vmt@openerp.com-20111003153509-8mbfg1t8hm92pult
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/__init__.py | 2 | ||||
| -rw-r--r-- | tests/addons/test_exceptions/__init__.py | 3 | ||||
| -rw-r--r-- | tests/addons/test_exceptions/__openerp__.py | 15 | ||||
| -rw-r--r-- | tests/addons/test_exceptions/models.py | 33 | ||||
| -rw-r--r-- | tests/addons/test_exceptions/view.xml | 68 | ||||
| -rw-r--r-- | tests/common.py | 63 | ||||
| -rw-r--r-- | tests/test_ir_sequence.py | 198 | ||||
| -rw-r--r-- | tests/test_xmlrpc.py | 66 |
8 files changed, 448 insertions, 0 deletions
diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000000..396284efaf7 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +import test_xmlrpc diff --git a/tests/addons/test_exceptions/__init__.py b/tests/addons/test_exceptions/__init__.py new file mode 100644 index 00000000000..fe4487156b1 --- /dev/null +++ b/tests/addons/test_exceptions/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- +import models +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/tests/addons/test_exceptions/__openerp__.py b/tests/addons/test_exceptions/__openerp__.py new file mode 100644 index 00000000000..bac853e301a --- /dev/null +++ b/tests/addons/test_exceptions/__openerp__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +{ + 'name': 'test-exceptions', + 'version': '0.1', + 'category': 'Tests', + 'description': """A module to generate exceptions.""", + 'author': 'OpenERP SA', + 'maintainer': 'OpenERP SA', + 'website': 'http://www.openerp.com', + 'depends': ['base'], + 'data': ['view.xml'], + 'installable': True, + 'active': False, +} +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/tests/addons/test_exceptions/models.py b/tests/addons/test_exceptions/models.py new file mode 100644 index 00000000000..45f0e6dbd47 --- /dev/null +++ b/tests/addons/test_exceptions/models.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +import openerp + +class m(openerp.osv.osv.Model): + """ This model exposes a few methods that will raise the different + exceptions that must be handled by the server (and its RPC layer) + and the clients. + """ + _name = 'test.exceptions.model' + + def generate_except_osv(self, cr, uid, ids, context=None): + # title is ignored in the new (6.1) exceptions + raise openerp.osv.osv.except_osv('title', 'description') + + def generate_except_orm(self, cr, uid, ids, context=None): + # title is ignored in the new (6.1) exceptions + raise openerp.osv.orm.except_orm('title', 'description') + + def generate_warning(self, cr, uid, ids, context=None): + raise openerp.exceptions.Warning('description') + + def generate_access_denied(self, cr, uid, ids, context=None): + raise openerp.exceptions.AccessDenied() + + def generate_access_error(self, cr, uid, ids, context=None): + raise openerp.exceptions.AccessError('description') + + def generate_exc_access_denied(self, cr, uid, ids, context=None): + raise Exception('AccessDenied') + + def generate_undefined(self, cr, uid, ids, context=None): + self.surely_undefined_sumbol +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/tests/addons/test_exceptions/view.xml b/tests/addons/test_exceptions/view.xml new file mode 100644 index 00000000000..296f862aec4 --- /dev/null +++ b/tests/addons/test_exceptions/view.xml @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="utf-8"?> +<openerp> + <data> + + <record id="view_test_exceptions_model" model="ir.ui.view"> + <field name="name">Test exceptions</field> + <field name="model">test.exceptions.model</field> + <field name="type">form</field> + <field name="arch" type="xml"> + <form string="Test exceptions"> + <label string="Each button generates a specific exception on the server. The text on the right is the expected representation of the exception when displayed on the client."/> + <group colspan="8" col="8"> + <separator string="" colspan="8"/> + <button name="generate_except_osv" string="except_osv" type="object" icon="gtk-ok" colspan="1"/> + <label string="Warning-description"/> + </group> + <group colspan="8" col="8"> + <button name="generate_except_orm" string="except_orm" type="object" icon="gtk-ok" colspan="1"/> + <label string="Warning-description"/> + </group> + <group colspan="8" col="8"> + <button name="generate_warning" string="Warning" type="object" icon="gtk-ok" colspan="1"/> + <label string="Warning-description"/> + </group> + <group colspan="8" col="8"> + <button name="generate_access_denied" string="AccessDenied" type="object" icon="gtk-ok" colspan="1"/> + <label string="Access denied-traceback"/> + </group> + <group colspan="8" col="8"> + <button name="generate_access_error" string="AccessError" type="object" icon="gtk-ok" colspan="1"/> + <label string="Access rights error-description"/> + </group> + <group colspan="8" col="8"> + <button name="generate_exc_access_denied" string="Exc AccessDenied" type="object" icon="gtk-ok" colspan="1"/> + <label string="Access denied-traceback"/> + </group> + <group colspan="8" col="8"> + <button name="generate_undefined" string="Undefined" type="object" icon="gtk-ok" colspan="1"/> + <label string="Server error-traceback"/> + </group> + <group colspan="8" col="8"> + <separator string="" colspan="8"/> + <label colspan="6" width="220"/> + <button special="cancel" string="Cancel" icon="gtk-cancel" colspan="1"/> + </group> + </form> + </field> + </record> + + <record id="action_test_exceptions" model="ir.actions.act_window"> + <field name="name">Test exceptions</field> + <field name="type">ir.actions.act_window</field> + <field name="res_model">test.exceptions.model</field> + <field name="view_type">form</field> + <field name="view_mode">form</field> + <field name="target">new</field> + </record> + + <menuitem icon="STOCK_PREFERENCES" id="base.menu_tests" name="Tests"/> + + <menuitem id="menu_test_exceptions" parent="base.menu_tests" name="Test exceptions"/> + + <menuitem id="menu_test_exceptions_leaf" + name="Test exceptions" + action="action_test_exceptions" + parent="menu_test_exceptions"/> + </data> +</openerp> diff --git a/tests/common.py b/tests/common.py new file mode 100644 index 00000000000..116898dc7ef --- /dev/null +++ b/tests/common.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +import os +import time +import unittest2 +import xmlrpclib + +import openerp + +ADDONS_PATH = os.environ['OPENERP_ADDONS_PATH'] +PORT = int(os.environ['OPENERP_PORT']) +DB = os.environ['OPENERP_DATABASE'] + +HOST = '127.0.0.1' + +ADMIN_USER = 'admin' +ADMIN_USER_ID = 1 +ADMIN_PASSWORD = 'admin' + +common_proxy_60 = None +db_proxy_60 = None +object_proxy_60 = None + +common_proxy_61 = None +db_proxy_61 = None +model_proxy_61 = None +model_uri_61 = None + +def setUpModule(): + """ + Start the OpenERP server similary to the openerp-server script and + setup some xmlrpclib proxies. + """ + openerp.tools.config['addons_path'] = ADDONS_PATH + openerp.tools.config['xmlrpc_port'] = PORT + openerp.service.start_services() + + global common_proxy_60 + global db_proxy_60 + global object_proxy_60 + + # Use the old (pre 6.1) API. + url = 'http://%s:%d/xmlrpc/' % (HOST, PORT) + common_proxy_60 = xmlrpclib.ServerProxy(url + 'common') + db_proxy_60 = xmlrpclib.ServerProxy(url + 'db') + object_proxy_60 = xmlrpclib.ServerProxy(url + 'object') + + global common_proxy_61 + global db_proxy_61 + global model_proxy_61 + global model_uri_61 + + # Use the new (6.1) API. + model_uri_61 = 'http://%s:%d/openerp/xmlrpc/1/' % (HOST, PORT) + common_proxy_61 = xmlrpclib.ServerProxy(model_uri_61 + 'common') + db_proxy_61 = xmlrpclib.ServerProxy(model_uri_61 + 'db') + model_proxy_61 = xmlrpclib.ServerProxy(model_uri_61 + 'model/' + DB) + + # Ugly way to ensure the server is listening. + time.sleep(2) + +def tearDownModule(): + """ Shutdown the OpenERP server similarly to a single ctrl-c. """ + openerp.service.stop_services() diff --git a/tests/test_ir_sequence.py b/tests/test_ir_sequence.py new file mode 100644 index 00000000000..8a4731d524f --- /dev/null +++ b/tests/test_ir_sequence.py @@ -0,0 +1,198 @@ +# -*- coding: utf-8 -*- +# Run with one of these commands: +# > OPENERP_ADDONS_PATH='../../addons/trunk' OPENERP_PORT=8069 \ +# OPENERP_DATABASE=yy PYTHONPATH=. python tests/test_ir_sequence.py +# > OPENERP_ADDONS_PATH='../../addons/trunk' OPENERP_PORT=8069 \ +# OPENERP_DATABASE=yy nosetests tests/test_ir_sequence.py +# > OPENERP_ADDONS_PATH='../../../addons/trunk' OPENERP_PORT=8069 \ +# OPENERP_DATABASE=yy PYTHONPATH=../:. unit2 test_ir_sequence +# This assume an existing database. +import os +import psycopg2 +import time +import unittest2 +import xmlrpclib + +import openerp +import common + +DB = common.DB +ADMIN_USER_ID = common.ADMIN_USER_ID + +setUpModule = common.setUpModule +tearDownModule = common.tearDownModule + +def registry(model): + return openerp.modules.registry.RegistryManager.get(DB)[model] + +def cursor(): + return openerp.modules.registry.RegistryManager.get(DB).db.cursor() + +class test_ir_sequence_standard(unittest2.TestCase): + """ A few tests for a 'Standard' (i.e. PostgreSQL) sequence. """ + + def test_ir_sequence_create(self): + """ Try to create a sequence object. """ + cr = cursor() + d = dict(code='test_sequence_type', name='Test sequence type') + c = registry('ir.sequence.type').create(cr, ADMIN_USER_ID, d, {}) + assert c + d = dict(code='test_sequence_type', name='Test sequence') + c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {}) + assert c + cr.commit() + cr.close() + + def test_ir_sequence_search(self): + """ Try a search. """ + cr = cursor() + ids = registry('ir.sequence').search(cr, ADMIN_USER_ID, [], {}) + assert ids + cr.commit() + cr.close() + + def test_ir_sequence_draw(self): + """ Try to draw a number. """ + cr = cursor() + n = registry('ir.sequence').get(cr, ADMIN_USER_ID, 'test_sequence_type', {}) + assert n + cr.commit() + cr.close() + + def test_ir_sequence_draw_twice(self): + """ Try to draw a number from two transactions. """ + cr0 = cursor() + cr1 = cursor() + n0 = registry('ir.sequence').get(cr0, ADMIN_USER_ID, 'test_sequence_type', {}) + assert n0 + n1 = registry('ir.sequence').get(cr1, ADMIN_USER_ID, 'test_sequence_type', {}) + assert n1 + cr0.commit() + cr1.commit() + cr0.close() + cr1.close() + +class test_ir_sequence_no_gap(unittest2.TestCase): + """ Copy of the previous tests for a 'No gap' sequence. """ + + def test_ir_sequence_create_no_gap(self): + """ Try to create a sequence object. """ + cr = cursor() + d = dict(code='test_sequence_type_2', name='Test sequence type') + c = registry('ir.sequence.type').create(cr, ADMIN_USER_ID, d, {}) + assert c + d = dict(code='test_sequence_type_2', name='Test sequence', + implementation='no_gap') + c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {}) + assert c + cr.commit() + cr.close() + + def test_ir_sequence_draw_no_gap(self): + """ Try to draw a number. """ + cr = cursor() + n = registry('ir.sequence').get(cr, ADMIN_USER_ID, 'test_sequence_type_2', {}) + assert n + cr.commit() + cr.close() + + def test_ir_sequence_draw_twice_no_gap(self): + """ Try to draw a number from two transactions. + This is expected to not work. + """ + cr0 = cursor() + cr1 = cursor() + msg_re = '^could not obtain lock on row in relation "ir_sequence"$' + with self.assertRaisesRegexp(psycopg2.OperationalError, msg_re): + n0 = registry('ir.sequence').get(cr0, ADMIN_USER_ID, 'test_sequence_type_2', {}) + assert n0 + n1 = registry('ir.sequence').get(cr1, ADMIN_USER_ID, 'test_sequence_type_2', {}) + cr0.close() + cr1.close() + +class test_ir_sequence_change_implementation(unittest2.TestCase): + """ Create sequence objects and change their ``implementation`` field. """ + + def test_ir_sequence_1_create(self): + """ Try to create a sequence object. """ + cr = cursor() + d = dict(code='test_sequence_type_3', name='Test sequence type') + c = registry('ir.sequence.type').create(cr, ADMIN_USER_ID, d, {}) + assert c + d = dict(code='test_sequence_type_3', name='Test sequence') + c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {}) + assert c + d = dict(code='test_sequence_type_4', name='Test sequence type') + c = registry('ir.sequence.type').create(cr, ADMIN_USER_ID, d, {}) + assert c + d = dict(code='test_sequence_type_4', name='Test sequence', + implementation='no_gap') + c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {}) + assert c + cr.commit() + cr.close() + + def test_ir_sequence_2_write(self): + cr = cursor() + ids = registry('ir.sequence').search(cr, ADMIN_USER_ID, + [('code', 'in', ['test_sequence_type_3', 'test_sequence_type_4'])], {}) + registry('ir.sequence').write(cr, ADMIN_USER_ID, ids, + {'implementation': 'standard'}, {}) + registry('ir.sequence').write(cr, ADMIN_USER_ID, ids, + {'implementation': 'no_gap'}, {}) + cr.commit() + cr.close() + + def test_ir_sequence_3_unlink(self): + cr = cursor() + ids = registry('ir.sequence').search(cr, ADMIN_USER_ID, + [('code', 'in', ['test_sequence_type_3', 'test_sequence_type_4'])], {}) + registry('ir.sequence').unlink(cr, ADMIN_USER_ID, ids, {}) + cr.commit() + cr.close() + +class test_ir_sequence_generate(unittest2.TestCase): + """ Create sequence objects and generate some values. """ + + def test_ir_sequence_create(self): + """ Try to create a sequence object. """ + cr = cursor() + d = dict(code='test_sequence_type_5', name='Test sequence type') + c = registry('ir.sequence.type').create(cr, ADMIN_USER_ID, d, {}) + assert c + d = dict(code='test_sequence_type_5', name='Test sequence') + c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {}) + assert c + cr.commit() + cr.close() + + cr = cursor() + f = lambda *a: registry('ir.sequence').get(cr, ADMIN_USER_ID, 'test_sequence_type_5', {}) + assert all(str(x) == f() for x in xrange(1,1000)) + cr.commit() + cr.close() + + def test_ir_sequence_create_no_gap(self): + """ Try to create a sequence object. """ + cr = cursor() + d = dict(code='test_sequence_type_6', name='Test sequence type', + implementation='no_gap') + c = registry('ir.sequence.type').create(cr, ADMIN_USER_ID, d, {}) + assert c + d = dict(code='test_sequence_type_6', name='Test sequence') + c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {}) + assert c + cr.commit() + cr.close() + + cr = cursor() + f = lambda *a: registry('ir.sequence').get(cr, ADMIN_USER_ID, 'test_sequence_type_6', {}) + assert all(str(x) == f() for x in xrange(1,1000)) + cr.commit() + cr.close() + + + +if __name__ == '__main__': + unittest2.main() + diff --git a/tests/test_xmlrpc.py b/tests/test_xmlrpc.py new file mode 100644 index 00000000000..4ad530cbeda --- /dev/null +++ b/tests/test_xmlrpc.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- +# Run with one of these commands: +# > OPENERP_ADDONS_PATH='../../addons/trunk' OPENERP_PORT=8069 \ +# OPENERP_DATABASE=yy PYTHONPATH=. python tests/test_xmlrpc.py +# > OPENERP_ADDONS_PATH='../../addons/trunk' OPENERP_PORT=8069 \ +# OPENERP_DATABASE=yy nosetests tests/test_xmlrpc.py +# > OPENERP_ADDONS_PATH='../../../addons/trunk' OPENERP_PORT=8069 \ +# OPENERP_DATABASE=yy PYTHONPATH=../:. unit2 test_xmlrpc +import os +import time +import unittest2 +import xmlrpclib + +import openerp +import common + +DB = common.DB +ADMIN_USER = common.ADMIN_USER +ADMIN_USER_ID = common.ADMIN_USER_ID +ADMIN_PASSWORD = common.ADMIN_PASSWORD + +setUpModule = common.setUpModule +tearDownModule = common.tearDownModule + +class test_xmlrpc(unittest2.TestCase): + + def test_00_xmlrpc_create_database_polling(self): + """ + Simulate a OpenERP client requesting the creation of a database and + polling the server until the creation is complete. + """ + progress_id = common.db_proxy_60.create(ADMIN_PASSWORD, DB, True, + False, ADMIN_PASSWORD) + while True: + time.sleep(1) + progress, users = common.db_proxy_60.get_progress(ADMIN_PASSWORD, + progress_id) + if progress == 1.0: + break + + def test_xmlrpc_login(self): + """ Try to login on the common service. """ + uid = common.common_proxy_60.login(DB, ADMIN_USER, ADMIN_PASSWORD) + assert uid == ADMIN_USER_ID + + def test_xmlrpc_ir_model_search(self): + """ Try a search on the object service. """ + ids = common.object_proxy_60.execute(DB, ADMIN_USER_ID, ADMIN_PASSWORD, + 'ir.model', 'search', []) + assert ids + ids = common.object_proxy_60.execute(DB, ADMIN_USER_ID, ADMIN_PASSWORD, + 'ir.model', 'search', [], {}) + assert ids + + def test_xmlrpc_61_ir_model_search(self): + """ Try a search on the object service. """ + + proxy = xmlrpclib.ServerProxy(common.model_uri_61 + 'model/' + DB + '/ir.model') + ids = proxy.execute(ADMIN_USER_ID, ADMIN_PASSWORD, 'search', []) + assert ids + ids = proxy.execute(ADMIN_USER_ID, ADMIN_PASSWORD, 'search', [], {}) + assert ids + +if __name__ == '__main__': + unittest2.main() + |
