xref: /sqlite-3.40.0/test/interrupt2.test (revision 218c66e0)
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