12bfd35b8Sdan# 2020 June 30 22bfd35b8Sdan# 32bfd35b8Sdan# The author disclaims copyright to this source code. In place of 42bfd35b8Sdan# a legal notice, here is a blessing: 52bfd35b8Sdan# 62bfd35b8Sdan# May you do good and not evil. 72bfd35b8Sdan# May you find forgiveness for yourself and forgive others. 82bfd35b8Sdan# May you share freely, never taking more than you give. 92bfd35b8Sdan# 102bfd35b8Sdan#*********************************************************************** 112bfd35b8Sdan# This file test the busy handler 122bfd35b8Sdan# 13*cf2ad7aeSdan# TESTRUNNER: slow 142bfd35b8Sdan 152bfd35b8Sdan 162bfd35b8Sdanset testdir [file dirname $argv0] 172bfd35b8Sdansource $testdir/tester.tcl 182bfd35b8Sdansource $testdir/lock_common.tcl 192bfd35b8Sdanset testprefix busy2 202bfd35b8Sdan 212bfd35b8Sdando_multiclient_test tn { 222bfd35b8Sdan do_test 1.$tn.0 { 232bfd35b8Sdan sql2 { 242bfd35b8Sdan CREATE TABLE t1(a, b); 252bfd35b8Sdan PRAGMA journal_mode = wal; 262bfd35b8Sdan INSERT INTO t1 VALUES('A', 'B'); 272bfd35b8Sdan } 282bfd35b8Sdan } {wal} 292bfd35b8Sdan 302bfd35b8Sdan do_test 1.$tn.1 { 312bfd35b8Sdan code1 { db timeout 1000 } 322bfd35b8Sdan sql1 { SELECT * FROM t1 } 332bfd35b8Sdan } {A B} 342bfd35b8Sdan 352bfd35b8Sdan do_test 1.$tn.2 { 362bfd35b8Sdan sql2 { 372bfd35b8Sdan BEGIN; 382bfd35b8Sdan INSERT INTO t1 VALUES('C', 'D'); 392bfd35b8Sdan } 402bfd35b8Sdan } {} 412bfd35b8Sdan 422bfd35b8Sdan do_test 1.$tn.3 { 432bfd35b8Sdan set us [lindex [time { catch { sql1 { BEGIN EXCLUSIVE } } }] 0] 442bfd35b8Sdan expr {$us>950000 && $us<1500000} 452bfd35b8Sdan } {1} 462bfd35b8Sdan 472bfd35b8Sdan do_test 1.$tn.4 { 482bfd35b8Sdan sql2 { 492bfd35b8Sdan COMMIT 502bfd35b8Sdan } 512bfd35b8Sdan } {} 522bfd35b8Sdan} 532bfd35b8Sdan 543f1d0f56Sdan#------------------------------------------------------------------------- 553f1d0f56Sdan 563f1d0f56Sdando_multiclient_test tn { 573f1d0f56Sdan # Make the db a WAL mode db. And add a table and a row to it. Then open 583f1d0f56Sdan # a second connection within process 1. Process 1 now has connections 593f1d0f56Sdan # [db] and [db1.2], process 2 has connection [db2] only. 603f1d0f56Sdan # 613f1d0f56Sdan # Configure all connections to use a 1000 ms timeout. 623f1d0f56Sdan # 633f1d0f56Sdan do_test 2.$tn.0 { 6407066d90Sdan code1 { 6507066d90Sdan sqlite3 db1.2 test.db 6607066d90Sdan } 673f1d0f56Sdan sql1 { 6847d38e24Sdan PRAGMA auto_vacuum = off; 693f1d0f56Sdan PRAGMA journal_mode = wal; 703f1d0f56Sdan CREATE TABLE t1(a, b); 713f1d0f56Sdan INSERT INTO t1 VALUES(1, 2); 723f1d0f56Sdan } 733f1d0f56Sdan code2 { 743f1d0f56Sdan db2 timeout 1000 753f1d0f56Sdan } 763f1d0f56Sdan code1 { 773f1d0f56Sdan db1.2 timeout 1000 783f1d0f56Sdan db timeout 1000 793f1d0f56Sdan db1.2 eval {SELECT * FROM t1} 803f1d0f56Sdan } 813f1d0f56Sdan } {1 2} 823f1d0f56Sdan 833f1d0f56Sdan # Take a read lock with [db] in process 1. 843f1d0f56Sdan # 853f1d0f56Sdan do_test 2.$tn.1 { 863f1d0f56Sdan sql1 { 873f1d0f56Sdan BEGIN; 883f1d0f56Sdan SELECT * FROM t1; 893f1d0f56Sdan } 903f1d0f56Sdan } {1 2} 913f1d0f56Sdan 923f1d0f56Sdan # Insert a row using [db2] in process 2. Then try a passive checkpoint. 933f1d0f56Sdan # It fails to checkpoint the final frame (due to the readlock taken by 943f1d0f56Sdan # [db]), and returns in less than 250ms. 953f1d0f56Sdan do_test 2.$tn.2 { 963f1d0f56Sdan sql2 { INSERT INTO t1 VALUES(3, 4) } 973f1d0f56Sdan set us [lindex [time { 983f1d0f56Sdan set res [code2 { db2 eval { PRAGMA wal_checkpoint } }] 993f1d0f56Sdan }] 0] 1003f1d0f56Sdan list [expr $us < 250000] $res 1013f1d0f56Sdan } {1 {0 4 3}} 1023f1d0f56Sdan 1033f1d0f56Sdan # Now try a FULL checkpoint with [db2]. It returns SQLITE_BUSY. And takes 1043f1d0f56Sdan # over 950ms to do so. 1053f1d0f56Sdan do_test 2.$tn.3 { 1063f1d0f56Sdan set us [lindex [time { 1073f1d0f56Sdan set res [code2 { db2 eval { PRAGMA wal_checkpoint = FULL } }] 1083f1d0f56Sdan }] 0] 1093f1d0f56Sdan list [expr $us > 950000] $res 1103f1d0f56Sdan } {1 {1 4 3}} 1113f1d0f56Sdan 1123f1d0f56Sdan # Passive checkpoint with [db1.2] (process 1). No SQLITE_BUSY, returns 1133f1d0f56Sdan # in under 250ms. 1143f1d0f56Sdan do_test 2.$tn.4 { 1153f1d0f56Sdan set us [lindex [time { 1163f1d0f56Sdan set res [code1 { db1.2 eval { PRAGMA wal_checkpoint } }] 1173f1d0f56Sdan }] 0] 1183f1d0f56Sdan list [expr $us < 250000] $res 1193f1d0f56Sdan } {1 {0 4 3}} 1203f1d0f56Sdan 1213f1d0f56Sdan # Full checkpoint with [db1.2] (process 1). SQLITE_BUSY returned in 1223f1d0f56Sdan # a bit over 950ms. 1233f1d0f56Sdan do_test 2.$tn.5 { 1243f1d0f56Sdan set us [lindex [time { 1253f1d0f56Sdan set res [code1 { db1.2 eval { PRAGMA wal_checkpoint = FULL } }] 1263f1d0f56Sdan }] 0] 1273f1d0f56Sdan list [expr $us > 950000] $res 1283f1d0f56Sdan } {1 {1 4 3}} 1293f1d0f56Sdan 1303f1d0f56Sdan code1 { 1313f1d0f56Sdan db1.2 close 1323f1d0f56Sdan } 1333f1d0f56Sdan} 1343f1d0f56Sdan 1352b06b076Sdan#------------------------------------------------------------------------- 1362b06b076Sdan# Check that even if the busy-handler fails (returns zero) within a 1372b06b076Sdan# call to sqlite3_prepare() (or _v2(), or _v3()), it is still invoked 1382b06b076Sdan# the next time an SQLITE_BUSY is encountered. 1392b06b076Sdan# 1402b06b076Sdando_multiclient_test tn { 1412b06b076Sdan code1 { 1422b06b076Sdan set ::busy_called 0 1432b06b076Sdan proc busy {args} { 1442b06b076Sdan if {$::busy_called} { return 1 } 1452b06b076Sdan set ::busy_called 1 1462b06b076Sdan return 0 1472b06b076Sdan } 1482b06b076Sdan db busy busy 1492b06b076Sdan } 1502b06b076Sdan 1512b06b076Sdan do_test 3.$tn.1 { 1522b06b076Sdan sql2 { 1532b06b076Sdan CREATE TABLE t1(x); 1542b06b076Sdan BEGIN EXCLUSIVE; 1552b06b076Sdan INSERT INTO t1 VALUES('x'); 1562b06b076Sdan } 1572b06b076Sdan } {} 1582b06b076Sdan 1592b06b076Sdan do_test 3.$tn.2 { 1602b06b076Sdan set ::busy_called 0 16112c99946Sdan list [catch { sql1 { SELECT * FROM t1 } } msg] $::busy_called 16212c99946Sdan } {1 1} 1632b06b076Sdan 1642b06b076Sdan do_test 3.$tn.3 { 1652b06b076Sdan set ::busy_called 0 16612c99946Sdan list [catch { sql1 { SELECT * FROM t1 } } msg] $::busy_called 16712c99946Sdan } {1 1} 16812c99946Sdan 1692b06b076Sdan} 1702b06b076Sdan 1712bfd35b8Sdanfinish_test 172