176ed3bc0Sdan# 2010 May 03 276ed3bc0Sdan# 376ed3bc0Sdan# The author disclaims copyright to this source code. In place of 476ed3bc0Sdan# a legal notice, here is a blessing: 576ed3bc0Sdan# 676ed3bc0Sdan# May you do good and not evil. 776ed3bc0Sdan# May you find forgiveness for yourself and forgive others. 876ed3bc0Sdan# May you share freely, never taking more than you give. 976ed3bc0Sdan# 1076ed3bc0Sdan#*********************************************************************** 1176ed3bc0Sdan# This file implements regression tests for SQLite library. The 1276ed3bc0Sdan# focus of this file is testing the operation of the library in 1376ed3bc0Sdan# "PRAGMA journal_mode=WAL" mode. 1476ed3bc0Sdan# 1576ed3bc0Sdan 1676ed3bc0Sdanset testdir [file dirname $argv0] 1776ed3bc0Sdansource $testdir/tester.tcl 1876ed3bc0Sdansource $testdir/malloc_common.tcl 1976ed3bc0Sdan 2076ed3bc0Sdanifcapable !wal {finish_test ; return } 2176ed3bc0Sdan 2276ed3bc0Sdando_malloc_test walfault-oom-1 -sqlbody { 2376ed3bc0Sdan PRAGMA journal_mode = WAL; 2476ed3bc0Sdan CREATE TABLE t1(a, b); 2576ed3bc0Sdan INSERT INTO t1 VALUES(1, 2); 26ef378025Sdan PRAGMA wal_checkpoint; 2776ed3bc0Sdan} 2876ed3bc0Sdan 295e9e482fSdando_malloc_test walfault-oom-2 -tclprep { 305e9e482fSdan execsql { 315e9e482fSdan PRAGMA journal_mode = WAL; 325e9e482fSdan BEGIN; 335e9e482fSdan CREATE TABLE x(y, z, UNIQUE(y, z)); 345e9e482fSdan INSERT INTO x VALUES(randomblob(100), randomblob(100)); 355e9e482fSdan COMMIT; 365e9e482fSdan PRAGMA wal_checkpoint; 375e9e482fSdan 385e9e482fSdan INSERT INTO x SELECT randomblob(100), randomblob(100) FROM x; 395e9e482fSdan INSERT INTO x SELECT randomblob(100), randomblob(100) FROM x; 405e9e482fSdan INSERT INTO x SELECT randomblob(100), randomblob(100) FROM x; 415e9e482fSdan } 425e9e482fSdan file copy -force test.db testX.db 435e9e482fSdan file copy -force test.db-wal testX.db-wal 445e9e482fSdan db close 455e9e482fSdan file rename -force testX.db test.db 465e9e482fSdan file rename -force testX.db-wal test.db-wal 475e9e482fSdan 485e9e482fSdan sqlite3 db test.db 495e9e482fSdan sqlite3_extended_result_codes db 1 505e9e482fSdan sqlite3_db_config_lookaside db 0 0 0 515e9e482fSdan} -sqlbody { 525e9e482fSdan SELECT count(*) FROM x; 535e9e482fSdan} 545e9e482fSdan 559a6b4e9aSdando_ioerr_test walfault-ioerr-1 -sqlprep { 569a6b4e9aSdan PRAGMA auto_vacuum = 1; 579a6b4e9aSdan PRAGMA journal_mode = WAL; 589a6b4e9aSdan CREATE TABLE abc(a PRIMARY KEY); 599a6b4e9aSdan INSERT INTO abc VALUES(randomblob(1500)); 609a6b4e9aSdan} -sqlbody { 619a6b4e9aSdan DELETE FROM abc; 629a6b4e9aSdan PRAGMA wal_checkpoint; 639a6b4e9aSdan} 649a6b4e9aSdan 65c7991bdfSdan# A [testvfs] callback for the VFS created by [do_shmfault_test]. This 668f6097c2Sdan# callback injects SQLITE_IOERR faults into methods for which an entry 678f6097c2Sdan# in array ::shmfault_ioerr_methods is defined. For example, to enable 688f6097c2Sdan# errors in xShmOpen: 69c7991bdfSdan# 708f6097c2Sdan# set ::shmfault_ioerr_methods(xShmOpen) 1 71c7991bdfSdan# 72c7991bdfSdan# Faults are not injected into xShmRelease, xShmClose or xShmLock method 73c7991bdfSdan# calls. The global tcl variables used are: 74c7991bdfSdan# 75c7991bdfSdan# $::shmfault_ioerr_countdown 76c7991bdfSdan# $::shmfault_ioerr_persist 778f6097c2Sdan# $::shmfault_ioerr_methods 78c7991bdfSdan# 79c7991bdfSdanproc shmfault_vfs_cb {method args} { 80c7991bdfSdan 81c7991bdfSdan # If ::shmfault_ioerr_countdown is not set, always return SQLITE_OK. 82c7991bdfSdan # 83c7991bdfSdan if {[info exists ::shmfault_ioerr_countdown]==0} { return SQLITE_OK } 84c7991bdfSdan 858f6097c2Sdan if {[info exists ::shmfault_ioerr_methods($method)]} { 86c7991bdfSdan incr ::shmfault_ioerr_countdown -1 87c7991bdfSdan if { ($::shmfault_ioerr_countdown==0) 88c7991bdfSdan || ($::shmfault_ioerr_countdown<=0 && $::shmfault_ioerr_persist) 89c7991bdfSdan } { 90c7991bdfSdan return SQLITE_IOERR 91c7991bdfSdan } 92c7991bdfSdan } 93c7991bdfSdan return SQLITE_OK 94c7991bdfSdan} 95c7991bdfSdan 968f6097c2Sdan# Options are: 978f6097c2Sdan# 988f6097c2Sdan# -tclprep TCL 998f6097c2Sdan# -sqlprep SQL 1008f6097c2Sdan# -sqlbody SQL 1018f6097c2Sdan# 102c7991bdfSdanproc do_shmfault_test {name args} { 1038f6097c2Sdan 1048f6097c2Sdan set A(-tclprep) "sqlite3 db test.db -vfs shmfault" 1058f6097c2Sdan set A(-sqlprep) "" 1068f6097c2Sdan set A(-sqlbody) "" 1078f6097c2Sdan set A(-methods) [list xShmGet xShmOpen xShmSize] 108c7991bdfSdan array set A $args 109c7991bdfSdan 110c7991bdfSdan # Create a VFS to use: 111c7991bdfSdan testvfs shmfault shmfault_vfs_cb 112c7991bdfSdan 1138f6097c2Sdan unset -nocomplain ::shmfault_ioerr_methods 1148f6097c2Sdan foreach m $A(-methods) { set ::shmfault_ioerr_methods($m) 1 } 1158f6097c2Sdan 116c7991bdfSdan foreach mode {transient persistent} { 117c7991bdfSdan set ::shmfault_ioerr_persist [expr {$mode == "persistent"}] 1188f6097c2Sdan 119c7991bdfSdan for {set nDelay 1} {$nDelay < 10000} {incr nDelay} { 120c7991bdfSdan 121c7991bdfSdan file delete -force test.db test.db-wal test.db-journal 122c7991bdfSdan 1238f6097c2Sdan eval $A(-tclprep) 1248f6097c2Sdan db eval $A(-sqlprep) 1258f6097c2Sdan 1268f6097c2Sdan set ::shmfault_ioerr_countdown $nDelay 1278f6097c2Sdan set rc [catch { db eval $A(-sqlbody) } msg] 128c7991bdfSdan set hit_error [expr {$::shmfault_ioerr_countdown<=0}] 129c7991bdfSdan unset ::shmfault_ioerr_countdown 1308f6097c2Sdan 131c7991bdfSdan catch { db close } 132c7991bdfSdan 133c7991bdfSdan do_test $name-$mode.$nDelay.1 [list set {} $hit_error] $rc 134c7991bdfSdan 135c7991bdfSdan if {$hit_error==0} break 136c7991bdfSdan } 137c7991bdfSdan } 138c7991bdfSdan 139c7991bdfSdan shmfault delete 140c7991bdfSdan} 141c7991bdfSdan 1428f6097c2Sdan 143c7991bdfSdando_shmfault_test walfault-shm-1 -sqlbody { 144c7991bdfSdan PRAGMA journal_mode = WAL; 145c7991bdfSdan CREATE TABLE t1(a PRIMARY KEY, b); 146c7991bdfSdan INSERT INTO t1 VALUES('a', 'b'); 147c7991bdfSdan PRAGMA wal_checkpoint; 148c7991bdfSdan} 14976ed3bc0Sdan 1508f6097c2Sdando_shmfault_test walfault-shm-2 -methods xShmSize -sqlprep { 1518f6097c2Sdan PRAGMA page_size = 512; 1528f6097c2Sdan PRAGMA journal_mode = WAL; 1538f6097c2Sdan PRAGMA wal_autocheckpoint = 0; 1548f6097c2Sdan} -sqlbody { 1558f6097c2Sdan CREATE TABLE t1(x); 1568f6097c2Sdan BEGIN; 1578f6097c2Sdan INSERT INTO t1 VALUES(randomblob(400)); /* 1 */ 1588f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 2 */ 1598f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 4 */ 1608f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 8 */ 1618f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 16 */ 1628f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 32 */ 1638f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 64 */ 1648f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 128 */ 1658f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 256 */ 1668f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 512 */ 1678f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 1024 */ 1688f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 2048 */ 1698f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 4096 */ 1708f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 8192 */ 1718f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 16384 */ 1728f6097c2Sdan COMMIT; 1738f6097c2Sdan} 1748f6097c2Sdan 1758f6097c2Sdando_shmfault_test walfault-shm-3 -methods xShmSize -tclprep { 1768f6097c2Sdan sqlite3 db test.db -vfs shmfault 1778f6097c2Sdan unset -nocomplain ::shmfault_ioerr_countdown 1788f6097c2Sdan db eval { 1798f6097c2Sdan PRAGMA page_size = 512; 1808f6097c2Sdan PRAGMA journal_mode = WAL; 1818f6097c2Sdan PRAGMA wal_autocheckpoint = 0; 1828f6097c2Sdan CREATE TABLE t1(x); 1838f6097c2Sdan BEGIN; 1848f6097c2Sdan INSERT INTO t1 VALUES(randomblob(400)); /* 1 */ 1858f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 2 */ 1868f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 4 */ 1878f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 8 */ 1888f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 16 */ 1898f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 32 */ 1908f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 64 */ 1918f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 128 */ 1928f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 256 */ 1938f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 512 */ 1948f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 1024 */ 1958f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 2048 */ 1968f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 4096 */ 1978f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 8192 */ 1988f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 16384 */ 1998f6097c2Sdan COMMIT; 2008f6097c2Sdan } 2018f6097c2Sdan 2028f6097c2Sdan set ::shmfault_ioerr_countdown 1 2038f6097c2Sdan set ::shmfault_ioerr_methods(xShmGet) 1 2048f6097c2Sdan db close 2058f6097c2Sdan unset ::shmfault_ioerr_methods(xShmGet) 2068f6097c2Sdan if {[file exists test.db-wal]==0} {error "Failed to create WAL file!"} 2078f6097c2Sdan 2088f6097c2Sdan sqlite3 db test.db -vfs shmfault 2098f6097c2Sdan} -sqlbody { 2108f6097c2Sdan SELECT count(*) FROM t1; 2118f6097c2Sdan} 2128f6097c2Sdan 213*a861469aSdando_shmfault_test walfault-shm-4 -tclprep { 214*a861469aSdan sqlite3 db test.db -vfs shmfault 215*a861469aSdan unset -nocomplain ::shmfault_ioerr_countdown 216*a861469aSdan db eval { 217*a861469aSdan PRAGMA page_size = 512; 218*a861469aSdan PRAGMA journal_mode = WAL; 219*a861469aSdan PRAGMA wal_autocheckpoint = 0; 220*a861469aSdan CREATE TABLE t1(x); 221*a861469aSdan BEGIN; 222*a861469aSdan INSERT INTO t1 VALUES(randomblob(400)); /* 1 */ 223*a861469aSdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 2 */ 224*a861469aSdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 4 */ 225*a861469aSdan COMMIT; 226*a861469aSdan } 227*a861469aSdan 228*a861469aSdan set ::shmfault_ioerr_countdown 1 229*a861469aSdan set ::shmfault_ioerr_methods(xShmGet) 1 230*a861469aSdan db close 231*a861469aSdan unset ::shmfault_ioerr_methods(xShmGet) 232*a861469aSdan if {[file exists test.db-wal]==0} {error "Failed to create WAL file!"} 233*a861469aSdan sqlite3 db test.db -vfs shmfault 234*a861469aSdan} -sqlbody { 235*a861469aSdan SELECT count(*) FROM t1; 236*a861469aSdan} 237*a861469aSdan 23876ed3bc0Sdanfinish_test 239c7991bdfSdan 240