1be7721d1Sdan# 2016 February 4 2be7721d1Sdan# 3be7721d1Sdan# The author disclaims copyright to this source code. In place of 4be7721d1Sdan# a legal notice, here is a blessing: 5be7721d1Sdan# 6be7721d1Sdan# May you do good and not evil. 7be7721d1Sdan# May you find forgiveness for yourself and forgive others. 8be7721d1Sdan# May you share freely, never taking more than you give. 9be7721d1Sdan# 10be7721d1Sdan#*********************************************************************** 11be7721d1Sdan# This file implements regression tests for SQLite library. The 12be7721d1Sdan# focus of this file is testing the operation of the library in 13be7721d1Sdan# "PRAGMA journal_mode=WAL" mode. 14be7721d1Sdan# 15be7721d1Sdan# More specifically, it tests "locking protocol" errors - errors that 16be7721d1Sdan# may be caused if one or more SQLite clients does not follow the expected 17be7721d1Sdan# locking protocol when accessing a wal-mode database. These tests take 18be7721d1Sdan# quite a while to run. 19be7721d1Sdan# 20be7721d1Sdan 21be7721d1Sdanset testdir [file dirname $argv0] 22be7721d1Sdansource $testdir/tester.tcl 23be7721d1Sdansource $testdir/lock_common.tcl 24be7721d1Sdansource $testdir/wal_common.tcl 25be7721d1Sdanifcapable !wal {finish_test ; return } 26be7721d1Sdan 27be7721d1Sdanset testprefix walprotocol 28be7721d1Sdan 29be7721d1Sdan#------------------------------------------------------------------------- 30be7721d1Sdan# When recovering the contents of a WAL file, a process obtains the WRITER 31be7721d1Sdan# lock, then locks all other bytes before commencing recovery. If it fails 32be7721d1Sdan# to lock all other bytes (because some other process is holding a read 33be7721d1Sdan# lock) it should retry up to 100 times. Then return SQLITE_PROTOCOL to the 34be7721d1Sdan# caller. Test this (test case 1.3). 35be7721d1Sdan# 36be7721d1Sdan# Also test the effect of hitting an SQLITE_BUSY while attempting to obtain 37be7721d1Sdan# the WRITER lock (should be the same). Test case 1.4. 38be7721d1Sdan# 39be7721d1Sdando_execsql_test 1.0 { 40be7721d1Sdan PRAGMA journal_mode = wal; 41be7721d1Sdan CREATE TABLE x(y); 42be7721d1Sdan INSERT INTO x VALUES('z'); 43be7721d1Sdan} {wal} 44be7721d1Sdan 45be7721d1Sdanproc lock_callback {method filename handle lock} { 46be7721d1Sdan lappend ::locks $lock 47be7721d1Sdan} 48be7721d1Sdando_test 1.1 { 49be7721d1Sdan testvfs T 50be7721d1Sdan T filter xShmLock 51be7721d1Sdan T script lock_callback 52be7721d1Sdan set ::locks [list] 53be7721d1Sdan sqlite3 db test.db -vfs T 54be7721d1Sdan execsql { SELECT * FROM x } 55*cddfc392Sdan lrange $::locks 0 11 56*cddfc392Sdan} [list {0 1 lock exclusive} {1 2 lock exclusive} \ 57*cddfc392Sdan {4 1 lock exclusive} {4 1 unlock exclusive} \ 58*cddfc392Sdan {5 1 lock exclusive} {5 1 unlock exclusive} \ 59*cddfc392Sdan {6 1 lock exclusive} {6 1 unlock exclusive} \ 60*cddfc392Sdan {7 1 lock exclusive} {7 1 unlock exclusive} \ 61*cddfc392Sdan {1 2 unlock exclusive} \ 62*cddfc392Sdan {0 1 unlock exclusive} \ 63be7721d1Sdan] 64be7721d1Sdando_test 1.2 { 65be7721d1Sdan db close 66be7721d1Sdan set ::locks [list] 67be7721d1Sdan sqlite3 db test.db -vfs T 68be7721d1Sdan execsql { SELECT * FROM x } 69*cddfc392Sdan lrange $::locks 0 11 70*cddfc392Sdan} [list {0 1 lock exclusive} {1 2 lock exclusive} \ 71*cddfc392Sdan {4 1 lock exclusive} {4 1 unlock exclusive} \ 72*cddfc392Sdan {5 1 lock exclusive} {5 1 unlock exclusive} \ 73*cddfc392Sdan {6 1 lock exclusive} {6 1 unlock exclusive} \ 74*cddfc392Sdan {7 1 lock exclusive} {7 1 unlock exclusive} \ 75*cddfc392Sdan {1 2 unlock exclusive} \ 76*cddfc392Sdan {0 1 unlock exclusive} \ 77be7721d1Sdan] 78be7721d1Sdanproc lock_callback {method filename handle lock} { 7963025906Sdan if {$lock == "1 2 lock exclusive"} { return SQLITE_BUSY } 80be7721d1Sdan return SQLITE_OK 81be7721d1Sdan} 82d62c07d4Smistachkinputs "# Warning: This next test case causes SQLite to call xSleep(1) 100 times." 83be7721d1Sdanputs "# Normally this equates to a delay of roughly 10 seconds, but if SQLite" 84be7721d1Sdanputs "# is built on unix without HAVE_USLEEP defined, it may be much longer." 85be7721d1Sdando_test 1.3 { 86be7721d1Sdan db close 87be7721d1Sdan set ::locks [list] 88be7721d1Sdan sqlite3 db test.db -vfs T 89be7721d1Sdan catchsql { SELECT * FROM x } 90be7721d1Sdan} {1 {locking protocol}} 91be7721d1Sdan 92be7721d1Sdanputs "# Warning: Same again!" 93be7721d1Sdanproc lock_callback {method filename handle lock} { 94be7721d1Sdan if {$lock == "0 1 lock exclusive"} { return SQLITE_BUSY } 95be7721d1Sdan return SQLITE_OK 96be7721d1Sdan} 97be7721d1Sdando_test 1.4 { 98be7721d1Sdan db close 99be7721d1Sdan set ::locks [list] 100be7721d1Sdan sqlite3 db test.db -vfs T 101be7721d1Sdan catchsql { SELECT * FROM x } 102be7721d1Sdan} {1 {locking protocol}} 10363025906Sdan 10463025906Sdanputs "# Warning: Third time!" 10563025906Sdanproc lock_callback {method filename handle lock} { 10663025906Sdan if {$lock == "4 4 lock exclusive"} { return SQLITE_BUSY } 10763025906Sdan return SQLITE_OK 10863025906Sdan} 10963025906Sdando_test 1.5 { 11063025906Sdan db close 11163025906Sdan set ::locks [list] 11263025906Sdan sqlite3 db test.db -vfs T 11363025906Sdan catchsql { SELECT * FROM x } 114*cddfc392Sdan} {0 z} 115be7721d1Sdandb close 116be7721d1SdanT delete 117be7721d1Sdan 118be7721d1Sdan#------------------------------------------------------------------------- 119be7721d1Sdan# 120be7721d1Sdando_test 2.1 { 121be7721d1Sdan forcedelete test.db test.db-journal test.db wal 122be7721d1Sdan sqlite3 db test.db 123be7721d1Sdan sqlite3 db2 test.db 124be7721d1Sdan execsql { 125be7721d1Sdan PRAGMA auto_vacuum = off; 126be7721d1Sdan PRAGMA journal_mode = WAL; 127be7721d1Sdan CREATE TABLE b(c); 128be7721d1Sdan INSERT INTO b VALUES('Tehran'); 129be7721d1Sdan INSERT INTO b VALUES('Qom'); 130be7721d1Sdan INSERT INTO b VALUES('Markazi'); 131be7721d1Sdan PRAGMA wal_checkpoint; 132be7721d1Sdan } 133be7721d1Sdan} {wal 0 5 5} 134be7721d1Sdando_test 2.2 { 135be7721d1Sdan execsql { SELECT * FROM b } 136be7721d1Sdan} {Tehran Qom Markazi} 137be7721d1Sdando_test 2.3 { 138be7721d1Sdan db eval { SELECT * FROM b } { 139be7721d1Sdan db eval { INSERT INTO b VALUES('Qazvin') } 140be7721d1Sdan set r [db2 eval { SELECT * FROM b }] 141be7721d1Sdan break 142be7721d1Sdan } 143be7721d1Sdan set r 144be7721d1Sdan} {Tehran Qom Markazi Qazvin} 145be7721d1Sdando_test 2.4 { 146be7721d1Sdan execsql { 147be7721d1Sdan INSERT INTO b VALUES('Gilan'); 148be7721d1Sdan INSERT INTO b VALUES('Ardabil'); 149be7721d1Sdan } 150be7721d1Sdan} {} 151be7721d1Sdandb2 close 152be7721d1Sdan 153be7721d1Sdanfaultsim_save_and_close 154be7721d1Sdantestvfs T -default 1 155be7721d1Sdanfaultsim_restore_and_reopen 156be7721d1SdanT filter xShmLock 157be7721d1SdanT script lock_callback 158be7721d1Sdan 159be7721d1Sdanproc lock_callback {method file handle spec} { 16063025906Sdan if {$spec == "1 2 unlock exclusive"} { 161be7721d1Sdan T filter {} 162be7721d1Sdan set ::r [catchsql { SELECT * FROM b } db2] 163be7721d1Sdan } 164be7721d1Sdan} 165be7721d1Sdansqlite3 db test.db 166be7721d1Sdansqlite3 db2 test.db 16763025906Sdanputs "# Warning: Another slow test!" 168be7721d1Sdando_test 2.5 { 169be7721d1Sdan execsql { SELECT * FROM b } 170be7721d1Sdan} {Tehran Qom Markazi Qazvin Gilan Ardabil} 171be7721d1Sdando_test 2.6 { 172be7721d1Sdan set ::r 173*cddfc392Sdan} {0 {Tehran Qom Markazi Qazvin Gilan Ardabil}} 174be7721d1Sdan 175be7721d1Sdandb close 176be7721d1Sdandb2 close 177be7721d1Sdan 178be7721d1Sdanfaultsim_restore_and_reopen 179be7721d1Sdansqlite3 db2 test.db 180be7721d1SdanT filter xShmLock 181be7721d1SdanT script lock_callback 182be7721d1Sdanproc lock_callback {method file handle spec} { 18363025906Sdan if {$spec == "1 2 unlock exclusive"} { 184be7721d1Sdan T filter {} 185be7721d1Sdan set ::r [catchsql { SELECT * FROM b } db2] 186be7721d1Sdan } 187be7721d1Sdan} 188be7721d1Sdanunset ::r 18963025906Sdanputs "# Warning: Last one!" 190be7721d1Sdando_test 2.7 { 191be7721d1Sdan execsql { SELECT * FROM b } 192be7721d1Sdan} {Tehran Qom Markazi Qazvin Gilan Ardabil} 193be7721d1Sdando_test 2.8 { 194be7721d1Sdan set ::r 195*cddfc392Sdan} {0 {Tehran Qom Markazi Qazvin Gilan Ardabil}} 196be7721d1Sdan 197be7721d1Sdandb close 198be7721d1Sdandb2 close 199be7721d1SdanT delete 200be7721d1Sdan 201be7721d1Sdanfinish_test 202