blob: 59ad7b389383ec647a3b4b236b97dee11d4ffff6 [file] [log] [blame]
dan7fb89902016-08-12 16:21:15 +00001# 2016 Aug 12
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 using the sqlite_interrupt() API to
13# interrupt WAL checkpoint operations.
14#
15
16set testdir [file dirname $argv0]
17source $testdir/tester.tcl
18source $testdir/wal_common.tcl
19set testprefix interrupt2
20
21db close
22testvfs tvfs -default 1
23
24tvfs filter xWrite
25tvfs script write_cb
26
27set ::trigger_interrupt 0
28proc write_cb {method args} {
29 set filename [lindex $args 0]
30 if {[file tail $filename]=="test.db" && $::trigger_interrupt} {
31 if {$::trigger_interrupt} {
32 incr ::trigger_interrupt -1
33 if {$::trigger_interrupt==0} { sqlite3_interrupt db }
34 }
35 }
36 return 0
37}
38
39sqlite3 db test.db
40do_execsql_test 1.0 {
41 CREATE TABLE t1(a, b);
42 CREATE INDEX t1a ON t1(a);
43 CREATE INDEX t1b ON t1(b);
44 PRAGMA journal_mode = wal;
45
46 WITH ii(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM ii WHERE i<1000 )
47 INSERT INTO t1 SELECT i, i FROM ii;
48} {wal}
49
50foreach idelay {
51 5
52 10
53 15
54 20
55} {
56
57 set ::trigger_interrupt $idelay
58 do_catchsql_test 1.$idelay.1 { PRAGMA wal_checkpoint; } {1 interrupted}
59 do_execsql_test 1.$idelay.2 { SELECT count(*) FROM t1 } 1000
60
61 set ::trigger_interrupt $idelay
62 do_test 1.$idelay.3 {
63 list [catch { sqlite3_wal_checkpoint_v2 db truncate } msg] $msg
64 } {1 {SQLITE_INTERRUPT - interrupted}}
65 do_execsql_test 1.$idelay.4 { SELECT count(*) FROM t1 } 1000
66}
67
68#-------------------------------------------------------------------------
69# Check that if there are other SQL statements running, a checkpoint does
70# not clear the isInterrupted flag.
71#
72do_execsql_test 2.0 {
73 CREATE TEMP TABLE z1(a, b);
74 INSERT INTO z1 SELECT * FROM t1;
75}
76
77do_test 2.1 {
78 set i 10
79 set res [list [catch {
80 set i 10
81 db eval {SELECT * FROM z1} {
82 incr i -1
83 if {$i==0} {
84 set ::trigger_interrupt 10
85 set cres [catch { sqlite3_wal_checkpoint_v2 db truncate } msg]
86 lappend cres $msg
87 }
88 }
89 } msg] $msg]
90
91 list $cres $res
92} {{1 {SQLITE_INTERRUPT - interrupted}} {1 interrupted}}
93
94do_execsql_test 2.0 {
95 SELECT count(*) FROM t1
96 UNION ALL
97 SELECT count(*) FROM z1
98} {1000 1000}
99
100#-------------------------------------------------------------------------
101# Check the effect of an interrupt during sqlite3_close().
102#
103db_save_and_close
104
105db_restore_and_reopen
106do_test 3.1.1 {
107 set ::trigger_interrupt 10
108 db eval { SELECT * FROM sqlite_master }
109 db close
110 set {} {}
111} {}
112do_test 3.1.2 {
113 list [file exists test.db] [file exists test.db-wal]
114} {1 1}
115
116db_restore_and_reopen
117do_test 3.2.1 {
118 db eval { SELECT * FROM sqlite_master }
119 db close
120 set {} {}
121} {}
122do_test 3.2.2 {
123 list [file exists test.db] [file exists test.db-wal]
124} {1 0}
125
126#-------------------------------------------------------------------------
127# Check the effect of an interrupt during an automatic checkpoint
128#
129db_restore_and_reopen
130do_test 4.0 {
131 execsql { PRAGMA wal_autocheckpoint = 10 }
132 set ::trigger_interrupt 10
133 execsql { CREATE TABLE t2(x, y) }
134} {}
135
136# The auto-checkpoint in test 4.0 should have been interrupted. So this
137# db write should cause the wal file to grow.
138do_test 4.1 {
139 set nFrame1 [wal_frame_count test.db-wal 1024]
140 execsql { CREATE TABLE t3(x, y) }
141 set nFrame2 [wal_frame_count test.db-wal 1024]
142 expr $nFrame2 > $nFrame1
143} {1}
144
145# The auto-checkpoint in test 4.0 should not have been interrupted. So
146# this db write should not cause the wal file to grow.
147do_test 4.2 {
148 set nFrame1 [wal_frame_count test.db-wal 1024]
149 execsql { CREATE TABLE t4(x, y) }
150 set nFrame2 [wal_frame_count test.db-wal 1024]
151 expr $nFrame2 == $nFrame1
152} {1}
153
154finish_test