xref: /sqlite-3.40.0/test/interrupt2.test (revision 7fb89906)
1# 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
155