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] 108*d41a29a6Sdan set A(-coverageonly) 0 109c7991bdfSdan array set A $args 110c7991bdfSdan 111c7991bdfSdan # Create a VFS to use: 112c7991bdfSdan testvfs shmfault shmfault_vfs_cb 113c7991bdfSdan 1148f6097c2Sdan unset -nocomplain ::shmfault_ioerr_methods 1158f6097c2Sdan foreach m $A(-methods) { set ::shmfault_ioerr_methods($m) 1 } 1168f6097c2Sdan 117c7991bdfSdan foreach mode {transient persistent} { 118c7991bdfSdan set ::shmfault_ioerr_persist [expr {$mode == "persistent"}] 1198f6097c2Sdan 120c7991bdfSdan for {set nDelay 1} {$nDelay < 10000} {incr nDelay} { 121c7991bdfSdan 122c7991bdfSdan file delete -force test.db test.db-wal test.db-journal 123c7991bdfSdan 1248f6097c2Sdan eval $A(-tclprep) 1258f6097c2Sdan db eval $A(-sqlprep) 1268f6097c2Sdan 1278f6097c2Sdan set ::shmfault_ioerr_countdown $nDelay 1288f6097c2Sdan set rc [catch { db eval $A(-sqlbody) } msg] 129c7991bdfSdan set hit_error [expr {$::shmfault_ioerr_countdown<=0}] 130c7991bdfSdan unset ::shmfault_ioerr_countdown 1318f6097c2Sdan 132c7991bdfSdan catch { db close } 133c7991bdfSdan 134*d41a29a6Sdan if {$A(-coverageonly)} { set rc $hit_error } 135c7991bdfSdan do_test $name-$mode.$nDelay.1 [list set {} $hit_error] $rc 136c7991bdfSdan 137c7991bdfSdan if {$hit_error==0} break 138c7991bdfSdan } 139c7991bdfSdan } 140c7991bdfSdan 141c7991bdfSdan shmfault delete 142c7991bdfSdan} 143c7991bdfSdan 144c7991bdfSdando_shmfault_test walfault-shm-1 -sqlbody { 145c7991bdfSdan PRAGMA journal_mode = WAL; 146c7991bdfSdan CREATE TABLE t1(a PRIMARY KEY, b); 147c7991bdfSdan INSERT INTO t1 VALUES('a', 'b'); 148c7991bdfSdan PRAGMA wal_checkpoint; 149c7991bdfSdan} 15076ed3bc0Sdan 1518f6097c2Sdando_shmfault_test walfault-shm-2 -methods xShmSize -sqlprep { 1528f6097c2Sdan PRAGMA page_size = 512; 1538f6097c2Sdan PRAGMA journal_mode = WAL; 1548f6097c2Sdan PRAGMA wal_autocheckpoint = 0; 1558f6097c2Sdan} -sqlbody { 1568f6097c2Sdan CREATE TABLE t1(x); 1578f6097c2Sdan BEGIN; 1588f6097c2Sdan INSERT INTO t1 VALUES(randomblob(400)); /* 1 */ 1598f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 2 */ 1608f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 4 */ 1618f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 8 */ 1628f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 16 */ 1638f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 32 */ 1648f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 64 */ 1658f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 128 */ 1668f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 256 */ 1678f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 512 */ 1688f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 1024 */ 1698f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 2048 */ 1708f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 4096 */ 1718f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 8192 */ 1728f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 16384 */ 1738f6097c2Sdan COMMIT; 1748f6097c2Sdan} 1758f6097c2Sdan 1768f6097c2Sdando_shmfault_test walfault-shm-3 -methods xShmSize -tclprep { 1778f6097c2Sdan sqlite3 db test.db -vfs shmfault 1788f6097c2Sdan unset -nocomplain ::shmfault_ioerr_countdown 1798f6097c2Sdan db eval { 1808f6097c2Sdan PRAGMA page_size = 512; 1818f6097c2Sdan PRAGMA journal_mode = WAL; 1828f6097c2Sdan PRAGMA wal_autocheckpoint = 0; 1838f6097c2Sdan CREATE TABLE t1(x); 1848f6097c2Sdan BEGIN; 1858f6097c2Sdan INSERT INTO t1 VALUES(randomblob(400)); /* 1 */ 1868f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 2 */ 1878f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 4 */ 1888f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 8 */ 1898f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 16 */ 1908f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 32 */ 1918f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 64 */ 1928f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 128 */ 1938f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 256 */ 1948f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 512 */ 1958f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 1024 */ 1968f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 2048 */ 1978f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 4096 */ 1988f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 8192 */ 1998f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 16384 */ 2008f6097c2Sdan COMMIT; 2018f6097c2Sdan } 2028f6097c2Sdan 2038f6097c2Sdan set ::shmfault_ioerr_countdown 1 2048f6097c2Sdan set ::shmfault_ioerr_methods(xShmGet) 1 2058f6097c2Sdan db close 2068f6097c2Sdan unset ::shmfault_ioerr_methods(xShmGet) 2078f6097c2Sdan if {[file exists test.db-wal]==0} {error "Failed to create WAL file!"} 2088f6097c2Sdan 2098f6097c2Sdan sqlite3 db test.db -vfs shmfault 2108f6097c2Sdan} -sqlbody { 2118f6097c2Sdan SELECT count(*) FROM t1; 2128f6097c2Sdan} 2138f6097c2Sdan 214a861469aSdando_shmfault_test walfault-shm-4 -tclprep { 215a861469aSdan sqlite3 db test.db -vfs shmfault 216a861469aSdan unset -nocomplain ::shmfault_ioerr_countdown 217a861469aSdan db eval { 218a861469aSdan PRAGMA page_size = 512; 219a861469aSdan PRAGMA journal_mode = WAL; 220a861469aSdan PRAGMA wal_autocheckpoint = 0; 221a861469aSdan CREATE TABLE t1(x); 222a861469aSdan BEGIN; 223a861469aSdan INSERT INTO t1 VALUES(randomblob(400)); /* 1 */ 224a861469aSdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 2 */ 225a861469aSdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 4 */ 226a861469aSdan COMMIT; 227a861469aSdan } 228a861469aSdan 229a861469aSdan set ::shmfault_ioerr_countdown 1 230a861469aSdan set ::shmfault_ioerr_methods(xShmGet) 1 231a861469aSdan db close 232a861469aSdan unset ::shmfault_ioerr_methods(xShmGet) 233a861469aSdan if {[file exists test.db-wal]==0} {error "Failed to create WAL file!"} 234a861469aSdan sqlite3 db test.db -vfs shmfault 235a861469aSdan} -sqlbody { 236a861469aSdan SELECT count(*) FROM t1; 237a861469aSdan} 238a861469aSdan 239*d41a29a6Sdando_shmfault_test walfault-shm-5 -coverageonly 1 -sqlprep { 240*d41a29a6Sdan PRAGMA cache_size = 10; 241*d41a29a6Sdan PRAGMA journal_mode = WAL; 242*d41a29a6Sdan CREATE TABLE abc(a PRIMARY KEY); 243*d41a29a6Sdan INSERT INTO abc VALUES(randomblob(900)); 244*d41a29a6Sdan} -sqlbody { 245*d41a29a6Sdan BEGIN; 246*d41a29a6Sdan INSERT INTO abc SELECT randomblob(900) FROM abc; /* 1 */ 247*d41a29a6Sdan INSERT INTO abc SELECT randomblob(900) FROM abc; /* 2 */ 248*d41a29a6Sdan INSERT INTO abc SELECT randomblob(900) FROM abc; /* 4 */ 249*d41a29a6Sdan INSERT INTO abc SELECT randomblob(900) FROM abc; /* 8 */ 250*d41a29a6Sdan ROLLBACK; 251*d41a29a6Sdan} 252*d41a29a6Sdan 25376ed3bc0Sdanfinish_test 254c7991bdfSdan 255