#!/usr/bin/env python # # Copyright (c) 2004-2005 rPath, Inc. # import testsupport import os, sys, tempfile, time, unittest import sqlite3 as sqlite class Waiter: def wait(self, data, count): self.count = count if count > 5: return 0 return 1 def __init__(self): self.count = 0 class ConcurrencyTests(unittest.TestCase): def CheckSingleProcessTimeoutsDeferred(self): fd, dbfile = tempfile.mkstemp() os.close(fd) # 2 second timeout db1 = sqlite.connect(dbfile, timeout=2000) db2 = sqlite.connect(dbfile) cu2 = db2.cursor() cu1 = db1.cursor() cu1.execute('CREATE TABLE foo (bar)') db1.commit() cu2.execute('BEGIN DEFERRED') cu2.execute('INSERT INTO foo VALUES(1)') t1 = time.time() try: cu1.execute('BEGIN DEFERRED') cu1.execute('INSERT INTO foo VALUES(2)') except sqlite.InternalError, e: assert(str(e) == "database is locked") t2 = time.time() # make sure we slept 2 seconds assert(t2 - t1 >= 2 and t2 - t1 <= 3) db2.commit() cu1.stmt.step() assert [ x for x in cu1.execute('select * from foo') ] == [(1,), (2,)] def CheckSingleProcessTimeoutsOnBeginImmediate(self): fd, dbfile = tempfile.mkstemp() os.close(fd) # 2 second timeout db1 = sqlite.connect(dbfile, timeout=2000) db2 = sqlite.connect(dbfile) cu1 = db1.cursor() cu2 = db2.cursor() cu2.execute('BEGIN IMMEDIATE') t1 = time.time() try: cu1.execute('BEGIN IMMEDIATE') except sqlite.InternalError, e: assert(str(e) == "database is locked") t2 = time.time() # make sure we slept 2 seconds assert(t2 - t1 >= 2 and t2 - t1 <= 3) # unlock the database db2.rollback() # make sure that re-trying the BEGIN works cu1.stmt.step() db1.rollback() def CheckSingleProcessCallbacksDeferred(self): fd, dbfile = tempfile.mkstemp() os.close(fd) db1 = sqlite.connect(dbfile) waiter = Waiter() db1.db.sqlite_busy_handler(waiter.wait) db2 = sqlite.connect(dbfile) cu2 = db2.cursor() cu1 = db1.cursor() cu1.execute('CREATE TABLE foo (bar)') db1.commit() cu2.execute('BEGIN DEFERRED') cu2.execute('INSERT INTO foo VALUES(1)') t1 = time.time() try: cu1.execute('BEGIN DEFERRED') cu1.execute('INSERT INTO foo VALUES(2)') except sqlite.InternalError, e: assert(str(e) == "database is locked") t2 = time.time() assert(waiter.count == 6) db2.commit() cu1.stmt.step() assert [ x for x in cu1.execute('select * from foo') ] == [(1,), (2,)] def suite(): concurrency_suite = unittest.makeSuite(ConcurrencyTests, "Check") test_suite = unittest.TestSuite((concurrency_suite,)) return test_suite def main(): runner = unittest.TextTestRunner() runner.run(suite()) if __name__ == "__main__": main()