17fb89906Sdan# 2016 Aug 12 27fb89906Sdan# 37fb89906Sdan# The author disclaims copyright to this source code. In place of 47fb89906Sdan# a legal notice, here is a blessing: 57fb89906Sdan# 67fb89906Sdan# May you do good and not evil. 77fb89906Sdan# May you find forgiveness for yourself and forgive others. 87fb89906Sdan# May you share freely, never taking more than you give. 97fb89906Sdan# 107fb89906Sdan#*********************************************************************** 117fb89906Sdan# This file implements regression tests for SQLite library. The 127fb89906Sdan# focus of this script is using the sqlite_interrupt() API to 137fb89906Sdan# interrupt WAL checkpoint operations. 147fb89906Sdan# 157fb89906Sdan 167fb89906Sdanset testdir [file dirname $argv0] 177fb89906Sdansource $testdir/tester.tcl 187fb89906Sdansource $testdir/wal_common.tcl 197fb89906Sdanset testprefix interrupt2 207fb89906Sdan 21*218c66e0Sdrhif {[permutation]=="journaltest" || [permutation]=="inmemory_journal"} { 22*218c66e0Sdrh finish_test 23*218c66e0Sdrh return 24*218c66e0Sdrh} 25*218c66e0Sdrh 267fb89906Sdandb close 277fb89906Sdantestvfs tvfs -default 1 287fb89906Sdan 297fb89906Sdantvfs filter xWrite 307fb89906Sdantvfs script write_cb 317fb89906Sdan 327fb89906Sdanset ::trigger_interrupt 0 337fb89906Sdanproc write_cb {method args} { 347fb89906Sdan set filename [lindex $args 0] 357fb89906Sdan if {[file tail $filename]=="test.db" && $::trigger_interrupt} { 367fb89906Sdan if {$::trigger_interrupt} { 377fb89906Sdan incr ::trigger_interrupt -1 387fb89906Sdan if {$::trigger_interrupt==0} { sqlite3_interrupt db } 397fb89906Sdan } 407fb89906Sdan } 417fb89906Sdan return 0 427fb89906Sdan} 437fb89906Sdan 447fb89906Sdansqlite3 db test.db 457fb89906Sdando_execsql_test 1.0 { 467fb89906Sdan CREATE TABLE t1(a, b); 477fb89906Sdan CREATE INDEX t1a ON t1(a); 487fb89906Sdan CREATE INDEX t1b ON t1(b); 497fb89906Sdan PRAGMA journal_mode = wal; 507fb89906Sdan 517fb89906Sdan WITH ii(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM ii WHERE i<1000 ) 527fb89906Sdan INSERT INTO t1 SELECT i, i FROM ii; 537fb89906Sdan} {wal} 547fb89906Sdan 557fb89906Sdanforeach idelay { 567fb89906Sdan 5 577fb89906Sdan 10 587fb89906Sdan 15 597fb89906Sdan 20 607fb89906Sdan} { 617fb89906Sdan 627fb89906Sdan set ::trigger_interrupt $idelay 637fb89906Sdan do_catchsql_test 1.$idelay.1 { PRAGMA wal_checkpoint; } {1 interrupted} 647fb89906Sdan do_execsql_test 1.$idelay.2 { SELECT count(*) FROM t1 } 1000 657fb89906Sdan 667fb89906Sdan set ::trigger_interrupt $idelay 677fb89906Sdan do_test 1.$idelay.3 { 687fb89906Sdan list [catch { sqlite3_wal_checkpoint_v2 db truncate } msg] $msg 697fb89906Sdan } {1 {SQLITE_INTERRUPT - interrupted}} 707fb89906Sdan do_execsql_test 1.$idelay.4 { SELECT count(*) FROM t1 } 1000 717fb89906Sdan} 727fb89906Sdan 737fb89906Sdan#------------------------------------------------------------------------- 747fb89906Sdan# Check that if there are other SQL statements running, a checkpoint does 757fb89906Sdan# not clear the isInterrupted flag. 767fb89906Sdan# 777fb89906Sdando_execsql_test 2.0 { 787fb89906Sdan CREATE TEMP TABLE z1(a, b); 797fb89906Sdan INSERT INTO z1 SELECT * FROM t1; 807fb89906Sdan} 817fb89906Sdan 827fb89906Sdando_test 2.1 { 837fb89906Sdan set i 10 847fb89906Sdan set res [list [catch { 857fb89906Sdan set i 10 867fb89906Sdan db eval {SELECT * FROM z1} { 877fb89906Sdan incr i -1 887fb89906Sdan if {$i==0} { 897fb89906Sdan set ::trigger_interrupt 10 907fb89906Sdan set cres [catch { sqlite3_wal_checkpoint_v2 db truncate } msg] 917fb89906Sdan lappend cres $msg 927fb89906Sdan } 937fb89906Sdan } 947fb89906Sdan } msg] $msg] 957fb89906Sdan 967fb89906Sdan list $cres $res 977fb89906Sdan} {{1 {SQLITE_INTERRUPT - interrupted}} {1 interrupted}} 987fb89906Sdan 997fb89906Sdando_execsql_test 2.0 { 1007fb89906Sdan SELECT count(*) FROM t1 1017fb89906Sdan UNION ALL 1027fb89906Sdan SELECT count(*) FROM z1 1037fb89906Sdan} {1000 1000} 1047fb89906Sdan 1057fb89906Sdan#------------------------------------------------------------------------- 1067fb89906Sdan# Check the effect of an interrupt during sqlite3_close(). 1077fb89906Sdan# 1087fb89906Sdandb_save_and_close 1097fb89906Sdan 1107fb89906Sdandb_restore_and_reopen 1117fb89906Sdando_test 3.1.1 { 1127fb89906Sdan set ::trigger_interrupt 10 1137fb89906Sdan db eval { SELECT * FROM sqlite_master } 1147fb89906Sdan db close 1157fb89906Sdan set {} {} 1167fb89906Sdan} {} 1177fb89906Sdando_test 3.1.2 { 1187fb89906Sdan list [file exists test.db] [file exists test.db-wal] 1197fb89906Sdan} {1 1} 1207fb89906Sdan 1217fb89906Sdandb_restore_and_reopen 1227fb89906Sdando_test 3.2.1 { 1237fb89906Sdan db eval { SELECT * FROM sqlite_master } 1247fb89906Sdan db close 1257fb89906Sdan set {} {} 1267fb89906Sdan} {} 1277fb89906Sdando_test 3.2.2 { 1287fb89906Sdan list [file exists test.db] [file exists test.db-wal] 1297fb89906Sdan} {1 0} 1307fb89906Sdan 1317fb89906Sdan#------------------------------------------------------------------------- 1327fb89906Sdan# Check the effect of an interrupt during an automatic checkpoint 1337fb89906Sdan# 1347fb89906Sdandb_restore_and_reopen 1357fb89906Sdando_test 4.0 { 1367fb89906Sdan execsql { PRAGMA wal_autocheckpoint = 10 } 1377fb89906Sdan set ::trigger_interrupt 10 1387fb89906Sdan execsql { CREATE TABLE t2(x, y) } 1397fb89906Sdan} {} 1407fb89906Sdan 1417fb89906Sdan# The auto-checkpoint in test 4.0 should have been interrupted. So this 1427fb89906Sdan# db write should cause the wal file to grow. 1437fb89906Sdando_test 4.1 { 1447fb89906Sdan set nFrame1 [wal_frame_count test.db-wal 1024] 1457fb89906Sdan execsql { CREATE TABLE t3(x, y) } 1467fb89906Sdan set nFrame2 [wal_frame_count test.db-wal 1024] 1477fb89906Sdan expr $nFrame2 > $nFrame1 1487fb89906Sdan} {1} 1497fb89906Sdan 1507fb89906Sdan# The auto-checkpoint in test 4.0 should not have been interrupted. So 1517fb89906Sdan# this db write should not cause the wal file to grow. 1527fb89906Sdando_test 4.2 { 1537fb89906Sdan set nFrame1 [wal_frame_count test.db-wal 1024] 1547fb89906Sdan execsql { CREATE TABLE t4(x, y) } 1557fb89906Sdan set nFrame2 [wal_frame_count test.db-wal 1024] 1567fb89906Sdan expr $nFrame2 == $nFrame1 1577fb89906Sdan} {1} 1587fb89906Sdan 1597fb89906Sdanfinish_test 160