Browse Source

[326] improve test, and add optional shorter timeout to open()

Jelte Jansen 13 years ago
parent
commit
a176724d99

+ 4 - 2
src/lib/python/isc/datasrc/sqlite3_ds.py

@@ -76,18 +76,20 @@ def create(cur):
     cur.execute("COMMIT TRANSACTION")
     return row
 
-def open(dbfile):
+def open(dbfile, connect_timeout=5.0):
     """ Open a database, if the database is not yet set up, call create
     to do so. It may raise Sqlite3DSError if failed to open sqlite3
     database file or find bad database schema version in the database.
 
     Arguments:
         dbfile - the filename for the sqlite3 database.
+        connect_timeout - timeout for opening the database or acquiring locks
+                          defaults to sqlite3 module's default of 5.0 seconds
 
     Return sqlite3 connection, sqlite3 cursor.
     """
     try:
-        conn = sqlite3.connect(dbfile)
+        conn = sqlite3.connect(dbfile, timeout=connect_timeout)
         cur = conn.cursor()
     except Exception as e:
         fail = "Failed to open " + dbfile + ": " + e.args[0]

+ 17 - 6
src/lib/python/isc/datasrc/tests/sqlite3_ds_test.py

@@ -106,19 +106,20 @@ class NewDBFile(unittest.TestCase):
 
     def test_new_db(self):
         self.assertFalse(os.path.exists(NEW_DB_FILE))
-        sqlite3_ds.load(NEW_DB_FILE, ".", example_reader)
+        sqlite3_ds.open(NEW_DB_FILE)
         self.assertTrue(os.path.exists(NEW_DB_FILE))
 
     def test_new_db_locked(self):
         self.assertFalse(os.path.exists(NEW_DB_FILE))
         con = sqlite3.connect(NEW_DB_FILE);
-        cur = con.cursor()
         con.isolation_level = None
-        cur.execute("BEGIN EXCLUSIVE TRANSACTION")
+        cur = con.cursor()
+        cur.execute("BEGIN IMMEDIATE TRANSACTION")
 
-        # load should now fail, since the database is locked
+        # load should now fail, since the database is locked,
+        # and the open() call needs an exclusive lock
         self.assertRaises(sqlite3.OperationalError,
-                          sqlite3_ds.load, NEW_DB_FILE, ".", example_reader)
+                          sqlite3_ds.open, NEW_DB_FILE, 0.1)
 
         con.rollback()
         cur.close()
@@ -126,7 +127,17 @@ class NewDBFile(unittest.TestCase):
         self.assertTrue(os.path.exists(NEW_DB_FILE))
 
         # now that we closed our connection, load should work again
-        sqlite3_ds.load(NEW_DB_FILE, ".", example_reader)
+        sqlite3_ds.open(NEW_DB_FILE)
+
+        # the database should now have been created, and a new load should
+        # not require an exclusive lock anymore, so we lock it again
+        con = sqlite3.connect(NEW_DB_FILE);
+        cur = con.cursor()
+        cur.execute("BEGIN IMMEDIATE TRANSACTION")
+        sqlite3_ds.open(NEW_DB_FILE, 0.1)
+        con.rollback()
+        cur.close()
+        con.close()
 
 if __name__ == '__main__':
     unittest.main()