summaryrefslogtreecommitdiff
path: root/openerp/sql_db.py
diff options
context:
space:
mode:
authorRaphael Collet <rco@openerp.com>2014-04-08 17:17:36 +0200
committerRaphael Collet <rco@openerp.com>2014-04-08 17:17:36 +0200
commitf0fd48c44a9e9a9fd124e3413040227ab95aefd6 (patch)
tree9d15f28c8067ff3651c610b0b708de5b1f38fab0 /openerp/sql_db.py
parent6bc60505f4e25d5ce7181f30d33692a8e7d08fe0 (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.py46
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