1# 2007 April 6 2# 3# The author disclaims copyright to this source code. In place of 4# a legal notice, here is a blessing: 5# 6# May you do good and not evil. 7# May you find forgiveness for yourself and forgive others. 8# May you share freely, never taking more than you give. 9# 10#*********************************************************************** 11# This file implements regression tests for SQLite library. The 12# focus of this script is database locks. 13# 14# $Id: lock4.test,v 1.8 2008/03/14 08:57:42 danielk1977 Exp $ 15 16 17set testdir [file dirname $argv0] 18source $testdir/tester.tcl 19 20# Initialize the test.db database so that it is non-empty 21# 22do_test lock4-1.1 { 23 db eval { 24 PRAGMA auto_vacuum=OFF; 25 CREATE TABLE t1(x); 26 } 27 file delete -force test2.db test2.db-journal 28 sqlite3 db2 test2.db 29 db2 eval { 30 PRAGMA auto_vacuum=OFF; 31 CREATE TABLE t2(x) 32 } 33 db2 close 34 list [file size test.db] [file size test2.db] 35} {2048 2048} 36 37# Create a script to drive a separate process that will 38# 39# 1. Create a second database test2.db 40# 2. Get an exclusive lock on test2.db 41# 3. Add an entry to test.db in table t1, waiting as necessary. 42# 4. Commit the change to test2.db. 43# 44# Meanwhile, this process will: 45# 46# A. Get an exclusive lock on test.db 47# B. Attempt to read from test2.db but get an SQLITE_BUSY error. 48# C. Commit the changes to test.db thus alloing the other process 49# to continue. 50# 51do_test lock4-1.2 { 52 53 # Create a script for the second process to run. 54 # 55 set out [open test2-script.tcl w] 56 puts $out "set sqlite_pending_byte [set sqlite_pending_byte]" 57 puts $out { 58 sqlite3 db2 test2.db 59 db2 eval { 60 BEGIN; 61 INSERT INTO t2 VALUES(2); 62 } 63 sqlite3 db test.db 64 db timeout 1000000 65 db eval { 66 INSERT INTO t1 VALUES(2); 67 } 68 db close 69 db2 eval COMMIT 70 exit 71 } 72 close $out 73 74 # Begin a transaction on test.db. 75 db eval { 76 BEGIN EXCLUSIVE; 77 INSERT INTO t1 VALUES(1); 78 } 79 80 # Kick off the second process. 81 exec [info nameofexec] ./test2-script.tcl & 82 83 # Wait until the second process has started its transaction on test2.db. 84 while {![file exists test2.db-journal]} { 85 after 10 86 } 87 88 # Try to write to test2.db. We are locked out. 89 sqlite3 db2 test2.db 90 catchsql { 91 INSERT INTO t2 VALUES(1) 92 } db2 93} {1 {database is locked}} 94do_test lock4-1.3 { 95 db eval { 96 COMMIT; 97 } 98 while {[file exists test2.db-journal]} { 99 after 10 100 } 101 # The other process has committed its transaction on test2.db by 102 # deleting the journal file. But it might retain the lock for a 103 # fraction longer 104 # 105 db2 eval { 106 SELECT * FROM t2 107 } 108} {2} 109 110 111do_test lock4-999.1 { 112 rename db2 {} 113} {} 114 115finish_test 116