AryaWu/sqlite
0
1# 2020 June 302#3# The author disclaims copyright to this source code. In place of4# 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 test the busy handler12#13# TESTRUNNER: slow14 15 16set testdir [file dirname $argv0]17source $testdir/tester.tcl18source $testdir/lock_common.tcl19set testprefix busy220 21do_multiclient_test tn {22 do_test 1.$tn.0 {23 sql2 {24 CREATE TABLE t1(a, b);25 PRAGMA journal_mode = wal;26 INSERT INTO t1 VALUES('A', 'B');27 }28 } {wal}29 30 do_test 1.$tn.1 {31 code1 { db timeout 1000 }32 sql1 { SELECT * FROM t1 }33 } {A B}34 35 do_test 1.$tn.2 {36 sql2 {37 BEGIN;38 INSERT INTO t1 VALUES('C', 'D');39 }40 } {}41 42 do_test 1.$tn.3 {43 set us [lindex [time { catch { sql1 { BEGIN EXCLUSIVE } } }] 0]44 expr {$us>950000 && $us<1500000}45 } {1}46 47 do_test 1.$tn.4 {48 sql2 {49 COMMIT50 }51 } {}52}53 54#-------------------------------------------------------------------------55 56do_multiclient_test tn {57 # Make the db a WAL mode db. And add a table and a row to it. Then open58 # a second connection within process 1. Process 1 now has connections59 # [db] and [db1.2], process 2 has connection [db2] only.60 #61 # Configure all connections to use a 1000 ms timeout.62 #63 do_test 2.$tn.0 {64 code1 {65 sqlite3 db1.2 test.db66 }67 sql1 {68 PRAGMA auto_vacuum = off;69 PRAGMA journal_mode = wal;70 CREATE TABLE t1(a, b);71 INSERT INTO t1 VALUES(1, 2);72 }73 code2 {74 db2 timeout 100075 }76 code1 {77 db1.2 timeout 100078 db timeout 100079 db1.2 eval {SELECT * FROM t1}80 }81 } {1 2}82 83 # Take a read lock with [db] in process 1.84 #85 do_test 2.$tn.1 {86 sql1 {87 BEGIN;88 SELECT * FROM t1;89 }90 } {1 2}91 92 # Insert a row using [db2] in process 2. Then try a passive checkpoint.93 # It fails to checkpoint the final frame (due to the readlock taken by94 # [db]), and returns in less than 250ms.95 do_test 2.$tn.2 {96 sql2 { INSERT INTO t1 VALUES(3, 4) }97 set us [lindex [time {98 set res [code2 { db2 eval { PRAGMA wal_checkpoint } }]99 }] 0]100 list [expr $us < 250000] $res101 } {1 {0 4 3}}102 103 # Now try a FULL checkpoint with [db2]. It returns SQLITE_BUSY. And takes104 # over 950ms to do so.105 do_test 2.$tn.3 {106 set us [lindex [time {107 set res [code2 { db2 eval { PRAGMA wal_checkpoint = FULL } }]108 }] 0]109 list [expr $us > 950000] $res110 } {1 {1 4 3}}111 112 # Passive checkpoint with [db1.2] (process 1). No SQLITE_BUSY, returns113 # in under 250ms.114 do_test 2.$tn.4 {115 set us [lindex [time {116 set res [code1 { db1.2 eval { PRAGMA wal_checkpoint } }]117 }] 0]118 list [expr $us < 250000] $res119 } {1 {0 4 3}}120 121 # Full checkpoint with [db1.2] (process 1). SQLITE_BUSY returned in122 # a bit over 950ms.123 do_test 2.$tn.5 {124 set us [lindex [time {125 set res [code1 { db1.2 eval { PRAGMA wal_checkpoint = FULL } }]126 }] 0]127 list [expr $us > 950000] $res128 } {1 {1 4 3}}129 130 code1 {131 db1.2 close132 }133}134 135#-------------------------------------------------------------------------136# Check that even if the busy-handler fails (returns zero) within a137# call to sqlite3_prepare() (or _v2(), or _v3()), it is still invoked138# the next time an SQLITE_BUSY is encountered.139#140do_multiclient_test tn {141 code1 {142 set ::busy_called 0143 proc busy {args} {144 if {$::busy_called} { return 1 }145 set ::busy_called 1146 return 0147 }148 db busy busy149 }150 151 do_test 3.$tn.1 {152 sql2 {153 CREATE TABLE t1(x);154 BEGIN EXCLUSIVE;155 INSERT INTO t1 VALUES('x');156 }157 } {}158 159 do_test 3.$tn.2 {160 set ::busy_called 0161 list [catch { sql1 { SELECT * FROM t1 } } msg] $::busy_called162 } {1 1}163 164 do_test 3.$tn.3 {165 set ::busy_called 0166 list [catch { sql1 { SELECT * FROM t1 } } msg] $::busy_called167 } {1 1}168 169}170 171finish_test172 