diff --git a/auth_brute_force/tests/test_brute_force.py b/auth_brute_force/tests/test_brute_force.py index 2e21b534d..19da05482 100644 --- a/auth_brute_force/tests/test_brute_force.py +++ b/auth_brute_force/tests/test_brute_force.py @@ -46,6 +46,65 @@ def skip_unless_addons_installed(*addons): return _wrapper +def patch_cursor(func): + """ Decorator that patches the current TestCursor for nested savepoint + support """ + def acquire(cursor): + cursor._depth += 1 + cursor._lock.acquire() + cursor.execute("SAVEPOINT test_cursor%d" % cursor._depth) + + def release(cursor): + cursor.execute("RELEASE SAVEPOINT test_cursor%d" % cursor._depth) + cursor._depth -= 1 + cursor._lock.release() + + def close(cursor): + cursor.release() + + def commit(cursor): + cursor.execute("RELEASE SAVEPOINT test_cursor%d" % cursor._depth) + cursor.execute("SAVEPOINT test_cursor%d" % cursor._depth) + + def rollback(cursor): + cursor.execute( + "ROLLBACK TO SAVEPOINT test_cursor%d" % cursor._depth) + cursor.execute("SAVEPOINT test_cursor%d" % cursor._depth) + + def wrap(func, *args): + + def wrapped_function(self, *args): + with self.cursor() as cursor: + cursor.execute("SAVEPOINT test_cursor0") + cursor._depth = 1 + cursor.execute("SAVEPOINT test_cursor%d" % cursor._depth) + + cursor.__acquire = cursor.acquire + cursor.__release = cursor.release + cursor.__commit = cursor.commit + cursor.__rollback = cursor.rollback + cursor.__close = cursor.close + cursor.acquire = lambda: acquire(cursor) + cursor.release = lambda: release(cursor) + cursor.commit = lambda: commit(cursor) + cursor.rollback = lambda: rollback(cursor) + cursor.close = lambda: close(cursor) + + try: + func(self, *args) + finally: + with self.cursor() as cursor: + cursor.acquire = cursor.__acquire + cursor.release = cursor.__release + cursor.commit = cursor.__commit + cursor.rollback = cursor.__rollback + cursor.close = cursor.__close + + return wrapped_function + + return wrap + + @at_install(False) @post_install(True) # Skip CSRF validation on tests @@ -96,6 +155,7 @@ class BruteForceCase(HttpCase): @skip_unless_addons_installed("web") @mute_logger(*GARBAGE_LOGGERS) + @patch_cursor def test_web_login_existing(self, *args): """Remote is banned with real user on web login form.""" data1 = { @@ -165,6 +225,7 @@ class BruteForceCase(HttpCase): @skip_unless_addons_installed("web") @mute_logger(*GARBAGE_LOGGERS) + @patch_cursor def test_web_login_unexisting(self, *args): """Remote is banned with fake user on web login form.""" data1 = { @@ -225,6 +286,7 @@ class BruteForceCase(HttpCase): self.assertEqual(len(banned), 0) @mute_logger(*GARBAGE_LOGGERS) + @patch_cursor def test_xmlrpc_login_existing(self, *args): """Remote is banned with real user on XML-RPC login.""" data1 = { @@ -284,6 +346,7 @@ class BruteForceCase(HttpCase): self.env.cr.dbname, data1["login"], data1["password"], {})) @mute_logger(*GARBAGE_LOGGERS) + @patch_cursor def test_xmlrpc_login_unexisting(self, *args): """Remote is banned with fake user on XML-RPC login.""" data1 = {