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 55*c7991bdfSdan# A [testvfs] callback for the VFS created by [do_shmfault_test]. This 56*c7991bdfSdan# callback injects SQLITE_IOERR faults into the following methods: 57*c7991bdfSdan# 58*c7991bdfSdan# xShmOpen 59*c7991bdfSdan# xShmSize 60*c7991bdfSdan# xShmGet 61*c7991bdfSdan# 62*c7991bdfSdan# Faults are not injected into xShmRelease, xShmClose or xShmLock method 63*c7991bdfSdan# calls. The global tcl variables used are: 64*c7991bdfSdan# 65*c7991bdfSdan# $::shmfault_ioerr_countdown 66*c7991bdfSdan# $::shmfault_ioerr_persist 67*c7991bdfSdan# 68*c7991bdfSdanproc shmfault_vfs_cb {method args} { 69*c7991bdfSdan 70*c7991bdfSdan # If ::shmfault_ioerr_countdown is not set, always return SQLITE_OK. 71*c7991bdfSdan # 72*c7991bdfSdan if {[info exists ::shmfault_ioerr_countdown]==0} { return SQLITE_OK } 73*c7991bdfSdan 74*c7991bdfSdan if {$method == "xShmOpen" 75*c7991bdfSdan || $method == "xShmSize" 76*c7991bdfSdan || $method == "xShmGet" 77*c7991bdfSdan } { 78*c7991bdfSdan incr ::shmfault_ioerr_countdown -1 79*c7991bdfSdan if { ($::shmfault_ioerr_countdown==0) 80*c7991bdfSdan || ($::shmfault_ioerr_countdown<=0 && $::shmfault_ioerr_persist) 81*c7991bdfSdan } { 82*c7991bdfSdan return SQLITE_IOERR 83*c7991bdfSdan } 84*c7991bdfSdan } 85*c7991bdfSdan return SQLITE_OK 86*c7991bdfSdan} 87*c7991bdfSdan 88*c7991bdfSdanproc do_shmfault_test {name args} { 89*c7991bdfSdan array set A $args 90*c7991bdfSdan 91*c7991bdfSdan # Create a VFS to use: 92*c7991bdfSdan testvfs shmfault shmfault_vfs_cb 93*c7991bdfSdan 94*c7991bdfSdan foreach mode {transient persistent} { 95*c7991bdfSdan set ::shmfault_ioerr_persist [expr {$mode == "persistent"}] 96*c7991bdfSdan for {set nDelay 1} {$nDelay < 10000} {incr nDelay} { 97*c7991bdfSdan set ::shmfault_ioerr_countdown $nDelay 98*c7991bdfSdan 99*c7991bdfSdan file delete -force test.db test.db-wal test.db-journal 100*c7991bdfSdan 101*c7991bdfSdan set rc [catch { 102*c7991bdfSdan sqlite3 db test.db -vfs shmfault 103*c7991bdfSdan db eval $A(-sqlbody) 104*c7991bdfSdan } msg] 105*c7991bdfSdan set hit_error [expr {$::shmfault_ioerr_countdown<=0}] 106*c7991bdfSdan unset ::shmfault_ioerr_countdown 107*c7991bdfSdan catch { db close } 108*c7991bdfSdan 109*c7991bdfSdan do_test $name-$mode.$nDelay.1 [list set {} $hit_error] $rc 110*c7991bdfSdan 111*c7991bdfSdan if {$hit_error==0} break 112*c7991bdfSdan } 113*c7991bdfSdan } 114*c7991bdfSdan 115*c7991bdfSdan shmfault delete 116*c7991bdfSdan} 117*c7991bdfSdan 118*c7991bdfSdando_shmfault_test walfault-shm-1 -sqlbody { 119*c7991bdfSdan PRAGMA journal_mode = WAL; 120*c7991bdfSdan CREATE TABLE t1(a PRIMARY KEY, b); 121*c7991bdfSdan INSERT INTO t1 VALUES('a', 'b'); 122*c7991bdfSdan PRAGMA wal_checkpoint; 123*c7991bdfSdan} 12476ed3bc0Sdan 12576ed3bc0Sdanfinish_test 126*c7991bdfSdan 127