diff options
| author | Raphael Collet <rco@openerp.com> | 2014-04-08 17:17:36 +0200 |
|---|---|---|
| committer | Raphael Collet <rco@openerp.com> | 2014-04-08 17:17:36 +0200 |
| commit | f0fd48c44a9e9a9fd124e3413040227ab95aefd6 (patch) | |
| tree | 9d15f28c8067ff3651c610b0b708de5b1f38fab0 /openerp/sql_db.py | |
| parent | 6bc60505f4e25d5ce7181f30d33692a8e7d08fe0 (diff) | |
[IMP] http tests: implement a test cursor that keeps a transaction open accross requests
- TestCursor subclasses Cursor, and simulates commit and rollback with savepoints
- the registry manages a test mode, in which it only uses the test cursor
- a reentrant lock forces the serialization of parallel requests
bzr revid: rco@openerp.com-20140408151736-j0guy68i2wjexy3d
Diffstat (limited to 'openerp/sql_db.py')
| -rw-r--r-- | openerp/sql_db.py | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/openerp/sql_db.py b/openerp/sql_db.py index 59841656d8c..be20af40367 100644 --- a/openerp/sql_db.py +++ b/openerp/sql_db.py @@ -364,6 +364,47 @@ class Cursor(object): def __getattr__(self, name): return getattr(self._obj, name) +class TestCursor(Cursor): + """ A cursor to be used for tests. It keeps the transaction open across + several requests, and simulates committing, rolling back, and closing. + """ + def __init__(self, *args, **kwargs): + # in order to simulate commit and rollback, the cursor maintains a + # savepoint at its last commit + super(TestCursor, self).__init__(*args, **kwargs) + super(TestCursor, self).execute("SAVEPOINT test_cursor") + self._lock = threading.RLock() + self._auto_commit = False + + def acquire(self): + self._lock.acquire() + + def release(self): + self._lock.release() + + def execute(self, *args, **kwargs): + super(TestCursor, self).execute(*args, **kwargs) + if self._auto_commit: + self.commit() + + def close(self, force=False): + self.rollback() # for stuff that has not been committed + if force: + super(TestCursor, self).close() + else: + self.release() + + def autocommit(self, on): + self._auto_commit = on + + def commit(self): + super(TestCursor, self).execute("RELEASE SAVEPOINT test_cursor") + super(TestCursor, self).execute("SAVEPOINT test_cursor") + + def rollback(self): + super(TestCursor, self).execute("ROLLBACK TO SAVEPOINT test_cursor") + super(TestCursor, self).execute("SAVEPOINT test_cursor") + class PsycoConnection(psycopg2.extensions.connection): pass @@ -491,6 +532,11 @@ class Connection(object): _logger.debug('create %scursor to %r', cursor_type, self.dbname) return Cursor(self._pool, self.dbname, serialized=serialized) + def test_cursor(self, serialized=True): + cursor_type = serialized and 'serialized ' or '' + _logger.debug('create test %scursor to %r', cursor_type, self.dbname) + return TestCursor(self._pool, self.dbname, serialized=serialized) + # serialized_cursor is deprecated - cursors are serialized by default serialized_cursor = cursor |
