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 1983f42d1bSdansource $testdir/lock_common.tcl 2076ed3bc0Sdan 2176ed3bc0Sdanifcapable !wal {finish_test ; return } 2276ed3bc0Sdan 23a4bc123fSdan#------------------------------------------------------------------------- 24a4bc123fSdan# This test case, walfault-1-*, simulates faults while executing a 25a4bc123fSdan# 26a4bc123fSdan# PRAGMA journal_mode = WAL; 27a4bc123fSdan# 28a4bc123fSdan# statement immediately after creating a new database. 29a4bc123fSdan# 30a4bc123fSdando_test walfault-1-pre-1 { 31459564f4Sdan faultsim_delete_and_reopen 32a4bc123fSdan faultsim_save_and_close 33a4bc123fSdan} {} 34a4bc123fSdando_faultsim_test walfault-1 -prep { 35a4bc123fSdan faultsim_restore_and_reopen 368521abfdSdan} -body { 378521abfdSdan db eval { PRAGMA main.journal_mode = WAL } 388521abfdSdan} -test { 398521abfdSdan 408521abfdSdan faultsim_test_result {0 wal} 418521abfdSdan 428521abfdSdan # Test that the connection that encountered an error as part of 438521abfdSdan # "PRAGMA journal_mode = WAL" and a new connection use the same 448521abfdSdan # journal mode when accessing the database. 458521abfdSdan # 468521abfdSdan # If "PRAGMA journal_mode" is executed immediately, connection [db] (the 478521abfdSdan # one that hit the error in journal_mode="WAL") might return "wal" even 488521abfdSdan # if it failed to switch the database to WAL mode. This is not considered 498521abfdSdan # a problem. When it tries to read the database, connection [db] correctly 508521abfdSdan # recognizes that it is a rollback database and switches back to a 518521abfdSdan # rollback compatible journal mode. 528521abfdSdan # 53b3f4351fSdan if {[permutation] != "inmemory_journal"} { 548521abfdSdan set jm [db one {SELECT * FROM sqlite_master ; PRAGMA main.journal_mode}] 558521abfdSdan sqlite3 db2 test.db 568521abfdSdan set jm2 [db2 one {SELECT * FROM sqlite_master ; PRAGMA main.journal_mode}] 578521abfdSdan db2 close 588521abfdSdan 598521abfdSdan if { $jm!=$jm2 } { error "Journal modes do not match: $jm $jm2" } 608521abfdSdan if { $testrc==0 && $jm!="wal" } { error "Journal mode is not WAL" } 6176ed3bc0Sdan } 62b3f4351fSdan} 6376ed3bc0Sdan 64a4bc123fSdan#-------------------------------------------------------------------------- 65a4bc123fSdan# Test case walfault-2-* tests fault injection during recovery of a 66a4bc123fSdan# short WAL file (a dozen frames or thereabouts). 67a4bc123fSdan# 68a4bc123fSdando_test walfault-2-pre-1 { 69a4bc123fSdan sqlite3 db test.db 705e9e482fSdan execsql { 715e9e482fSdan PRAGMA journal_mode = WAL; 725e9e482fSdan BEGIN; 735e9e482fSdan CREATE TABLE x(y, z, UNIQUE(y, z)); 745e9e482fSdan INSERT INTO x VALUES(randomblob(100), randomblob(100)); 755e9e482fSdan COMMIT; 765e9e482fSdan PRAGMA wal_checkpoint; 775e9e482fSdan 785e9e482fSdan INSERT INTO x SELECT randomblob(100), randomblob(100) FROM x; 795e9e482fSdan INSERT INTO x SELECT randomblob(100), randomblob(100) FROM x; 805e9e482fSdan INSERT INTO x SELECT randomblob(100), randomblob(100) FROM x; 815e9e482fSdan } 82a4bc123fSdan execsql { 83a4bc123fSdan SELECT count(*) FROM x 84a4bc123fSdan } 85a4bc123fSdan} {8} 86a4bc123fSdando_test walfault-2-pre-2 { 87a4bc123fSdan faultsim_save_and_close 88a4bc123fSdan faultsim_restore_and_reopen 89a4bc123fSdan execsql { SELECT count(*) FROM x } 90a4bc123fSdan} {8} 91a4bc123fSdando_faultsim_test walfault-2 -prep { 92a4bc123fSdan faultsim_restore_and_reopen 93a4bc123fSdan} -body { 94a4bc123fSdan execsql { SELECT count(*) FROM x } 95a4bc123fSdan} -test { 96a4bc123fSdan faultsim_test_result {0 8} 971f55e28dSdan faultsim_integrity_check 985e9e482fSdan} 995e9e482fSdan 100a4bc123fSdan#-------------------------------------------------------------------------- 101a4bc123fSdan# Test fault injection while writing and checkpointing a small WAL file. 102a4bc123fSdan# 103a4bc123fSdando_test walfault-3-pre-1 { 104a4bc123fSdan sqlite3 db test.db 105a4bc123fSdan execsql { 1069a6b4e9aSdan PRAGMA auto_vacuum = 1; 1079a6b4e9aSdan PRAGMA journal_mode = WAL; 1089a6b4e9aSdan CREATE TABLE abc(a PRIMARY KEY); 1099a6b4e9aSdan INSERT INTO abc VALUES(randomblob(1500)); 110a4bc123fSdan } 111a4bc123fSdan db close 112a4bc123fSdan faultsim_save_and_close 113a4bc123fSdan} {} 114a4bc123fSdando_faultsim_test walfault-3 -prep { 115a4bc123fSdan faultsim_restore_and_reopen 116a4bc123fSdan} -body { 117a4bc123fSdan db eval { 1189a6b4e9aSdan DELETE FROM abc; 1199a6b4e9aSdan PRAGMA wal_checkpoint; 1209a6b4e9aSdan } 12128f9b0b5Sdan set {} {} 122a4bc123fSdan} -test { 123a4bc123fSdan faultsim_test_result {0 {}} 124a4bc123fSdan} 1259a6b4e9aSdan 126459564f4Sdan#-------------------------------------------------------------------------- 127459564f4Sdan# 128b3f4351fSdanif {[permutation] != "inmemory_journal"} { 129459564f4Sdan faultsim_delete_and_reopen 1301f55e28dSdan faultsim_save_and_close 1311f55e28dSdan do_faultsim_test walfault-4 -prep { 1321f55e28dSdan faultsim_restore_and_reopen 1331f55e28dSdan } -body { 1341f55e28dSdan execsql { 135de17f948Sdan PRAGMA auto_vacuum = 0; 136c7991bdfSdan PRAGMA journal_mode = WAL; 137c7991bdfSdan CREATE TABLE t1(a PRIMARY KEY, b); 138c7991bdfSdan INSERT INTO t1 VALUES('a', 'b'); 139c7991bdfSdan PRAGMA wal_checkpoint; 1401f55e28dSdan SELECT * FROM t1; 1411f55e28dSdan } 1421f55e28dSdan } -test { 1439d69c5d1Sdan # Update: The following changed from {0 {wal 0 7 7 a b}} as a result 1449d69c5d1Sdan # of PSOW being set by default. 1459d69c5d1Sdan faultsim_test_result {0 {wal 0 5 5 a b}} 1461f55e28dSdan faultsim_integrity_check 147c7991bdfSdan } 148b3f4351fSdan} 14976ed3bc0Sdan 150459564f4Sdan#-------------------------------------------------------------------------- 151459564f4Sdan# 1521f55e28dSdando_test walfault-5-pre-1 { 153459564f4Sdan faultsim_delete_and_reopen 1541f55e28dSdan execsql { 1558f6097c2Sdan PRAGMA page_size = 512; 1568f6097c2Sdan PRAGMA journal_mode = WAL; 1571f55e28dSdan } 1581f55e28dSdan faultsim_save_and_close 1591f55e28dSdan} {} 1601f55e28dSdando_faultsim_test walfault-5 -faults shmerr* -prep { 1611f55e28dSdan faultsim_restore_and_reopen 1621f55e28dSdan execsql { PRAGMA wal_autocheckpoint = 0 } 163f886b4f8Sdrh shmfault filter xShmMap 1641f55e28dSdan} -body { 1651f55e28dSdan execsql { 1668f6097c2Sdan CREATE TABLE t1(x); 1678f6097c2Sdan BEGIN; 1688f6097c2Sdan INSERT INTO t1 VALUES(randomblob(400)); /* 1 */ 1698f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 2 */ 1708f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 4 */ 1718f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 8 */ 1728f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 16 */ 1738f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 32 */ 1748f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 64 */ 1758f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 128 */ 1768f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 256 */ 1778f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 512 */ 1788f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 1024 */ 1798f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 2048 */ 1808f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 4096 */ 1818f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 8192 */ 1828f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 16384 */ 1838f6097c2Sdan COMMIT; 1841f55e28dSdan SELECT count(*) FROM t1; 1851f55e28dSdan } 1861f55e28dSdan} -test { 1871f55e28dSdan faultsim_test_result {0 16384} 1881f55e28dSdan faultsim_integrity_check 1898f6097c2Sdan} 1908f6097c2Sdan 191459564f4Sdan#-------------------------------------------------------------------------- 192459564f4Sdan# 1931f55e28dSdando_test walfault-6-pre-1 { 194459564f4Sdan faultsim_delete_and_reopen 1951f55e28dSdan execsql { 1968f6097c2Sdan PRAGMA page_size = 512; 1978f6097c2Sdan PRAGMA journal_mode = WAL; 1988f6097c2Sdan PRAGMA wal_autocheckpoint = 0; 1998f6097c2Sdan CREATE TABLE t1(x); 2008f6097c2Sdan BEGIN; 2018f6097c2Sdan INSERT INTO t1 VALUES(randomblob(400)); /* 1 */ 2028f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 2 */ 2038f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 4 */ 2048f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 8 */ 2058f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 16 */ 2068f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 32 */ 2078f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 64 */ 2088f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 128 */ 2098f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 256 */ 2108f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 512 */ 2118f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 1024 */ 2128f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 2048 */ 2138f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 4096 */ 2148f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 8192 */ 2158f6097c2Sdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 16384 */ 2168f6097c2Sdan COMMIT; 2178f6097c2Sdan } 2181f55e28dSdan faultsim_save_and_close 2191f55e28dSdan} {} 2201f55e28dSdando_faultsim_test walfault-6 -faults shmerr* -prep { 2211f55e28dSdan faultsim_restore_and_reopen 222f886b4f8Sdrh shmfault filter xShmMap 2231f55e28dSdan} -body { 2241f55e28dSdan execsql { SELECT count(*) FROM t1 } 2251f55e28dSdan} -test { 2261f55e28dSdan faultsim_test_result {0 16384} 2271f55e28dSdan faultsim_integrity_check 2281f55e28dSdan set n [db one {SELECT count(*) FROM t1}] 2291f55e28dSdan if {$n != 16384 && $n != 0} { error "Incorrect number of rows: $n" } 2308f6097c2Sdan} 2318f6097c2Sdan 232459564f4Sdan#-------------------------------------------------------------------------- 233459564f4Sdan# 2341f55e28dSdando_test walfault-7-pre-1 { 2351f55e28dSdan faultsim_delete_and_reopen 2361f55e28dSdan execsql { 237a861469aSdan PRAGMA page_size = 512; 238a861469aSdan PRAGMA journal_mode = WAL; 239a861469aSdan PRAGMA wal_autocheckpoint = 0; 240a861469aSdan CREATE TABLE t1(x); 241a861469aSdan BEGIN; 242a861469aSdan INSERT INTO t1 VALUES(randomblob(400)); /* 1 */ 243a861469aSdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 2 */ 244a861469aSdan INSERT INTO t1 SELECT randomblob(400) FROM t1; /* 4 */ 245a861469aSdan COMMIT; 246a861469aSdan } 2471f55e28dSdan faultsim_save_and_close 2481f55e28dSdan} {} 2491f55e28dSdando_faultsim_test walfault-7 -prep { 2501f55e28dSdan faultsim_restore_and_reopen 2511f55e28dSdan} -body { 2521f55e28dSdan execsql { SELECT count(*) FROM t1 } 2531f55e28dSdan} -test { 2541f55e28dSdan faultsim_test_result {0 4} 2551f55e28dSdan set n [db one {SELECT count(*) FROM t1}] 2561f55e28dSdan if {$n != 4 && $n != 0} { error "Incorrect number of rows: $n" } 257a861469aSdan} 258a861469aSdan 259459564f4Sdan#-------------------------------------------------------------------------- 260459564f4Sdan# 2611f55e28dSdando_test walfault-8-pre-1 { 2621f55e28dSdan faultsim_delete_and_reopen 2631f55e28dSdan execsql { 264d41a29a6Sdan PRAGMA journal_mode = WAL; 265d41a29a6Sdan CREATE TABLE abc(a PRIMARY KEY); 266d41a29a6Sdan INSERT INTO abc VALUES(randomblob(900)); 2671f55e28dSdan } 2681f55e28dSdan faultsim_save_and_close 2691f55e28dSdan} {} 2701f55e28dSdando_faultsim_test walfault-8 -prep { 2711f55e28dSdan faultsim_restore_and_reopen 2721f55e28dSdan execsql { PRAGMA cache_size = 10 } 2731f55e28dSdan} -body { 2741f55e28dSdan execsql { 275d41a29a6Sdan BEGIN; 276d41a29a6Sdan INSERT INTO abc SELECT randomblob(900) FROM abc; /* 1 */ 2771f55e28dSdan --INSERT INTO abc SELECT randomblob(900) FROM abc; /* 2 */ 2781f55e28dSdan --INSERT INTO abc SELECT randomblob(900) FROM abc; /* 4 */ 2791f55e28dSdan --INSERT INTO abc SELECT randomblob(900) FROM abc; /* 8 */ 280d41a29a6Sdan ROLLBACK; 2811f55e28dSdan SELECT count(*) FROM abc; 2821f55e28dSdan } 2831f55e28dSdan} -test { 2841f55e28dSdan faultsim_test_result {0 1} 2851f55e28dSdan 2861f55e28dSdan faultsim_integrity_check 2871f55e28dSdan catch { db eval ROLLBACK } 2881f55e28dSdan faultsim_integrity_check 2891f55e28dSdan 2901f55e28dSdan set n [db one {SELECT count(*) FROM abc}] 2911f55e28dSdan if {$n != 1} { error "Incorrect number of rows: $n" } 292d41a29a6Sdan} 293d41a29a6Sdan 294459564f4Sdan#-------------------------------------------------------------------------- 295459564f4Sdan# 2961f55e28dSdando_test walfault-9-pre-1 { 2971f55e28dSdan faultsim_delete_and_reopen 2981f55e28dSdan execsql { 2998067adbcSdan PRAGMA journal_mode = WAL; 3008067adbcSdan CREATE TABLE abc(a PRIMARY KEY); 3018067adbcSdan INSERT INTO abc VALUES(randomblob(900)); 3021f55e28dSdan } 3031f55e28dSdan faultsim_save_and_close 3041f55e28dSdan} {} 3051f55e28dSdando_faultsim_test walfault-9 -prep { 3061f55e28dSdan #if {$iFail<73} { set iFail 73 } 3071f55e28dSdan #if {$iFail>73} { exit } 3081f55e28dSdan 3091f55e28dSdan faultsim_restore_and_reopen 3101f55e28dSdan execsql { PRAGMA cache_size = 10 } 3111f55e28dSdan} -body { 3121f55e28dSdan execsql { 3138067adbcSdan BEGIN; 3148067adbcSdan INSERT INTO abc SELECT randomblob(900) FROM abc; /* 1 */ 3158067adbcSdan SAVEPOINT spoint; 3168067adbcSdan INSERT INTO abc SELECT randomblob(900) FROM abc; /* 2 */ 3178067adbcSdan INSERT INTO abc SELECT randomblob(900) FROM abc; /* 4 */ 3188067adbcSdan INSERT INTO abc SELECT randomblob(900) FROM abc; /* 8 */ 3198067adbcSdan ROLLBACK TO spoint; 3208067adbcSdan COMMIT; 3211f55e28dSdan SELECT count(*) FROM abc; 3221f55e28dSdan } 3231f55e28dSdan} -test { 3241f55e28dSdan faultsim_test_result {0 2} 3251f55e28dSdan faultsim_integrity_check 3261f55e28dSdan 3271f55e28dSdan catch { db eval { ROLLBACK TO spoint } } 3281f55e28dSdan catch { db eval { COMMIT } } 3291f55e28dSdan set n [db one {SELECT count(*) FROM abc}] 3301f55e28dSdan if {$n != 1 && $n != 2} { error "Incorrect number of rows: $n" } 3318067adbcSdan} 3328067adbcSdan 333ef4ee8f2Sdando_test walfault-10-pre1 { 334ef4ee8f2Sdan faultsim_delete_and_reopen 335ef4ee8f2Sdan execsql { 336ef4ee8f2Sdan PRAGMA journal_mode = WAL; 3375d656852Sdan PRAGMA wal_autocheckpoint = 0; 338ef4ee8f2Sdan CREATE TABLE z(zz INTEGER PRIMARY KEY, zzz BLOB); 339ef4ee8f2Sdan CREATE INDEX zzzz ON z(zzz); 340ef4ee8f2Sdan INSERT INTO z VALUES(NULL, randomblob(800)); 341ef4ee8f2Sdan INSERT INTO z VALUES(NULL, randomblob(800)); 342ef4ee8f2Sdan INSERT INTO z SELECT NULL, randomblob(800) FROM z; 343ef4ee8f2Sdan INSERT INTO z SELECT NULL, randomblob(800) FROM z; 344ef4ee8f2Sdan INSERT INTO z SELECT NULL, randomblob(800) FROM z; 345ef4ee8f2Sdan INSERT INTO z SELECT NULL, randomblob(800) FROM z; 346ef4ee8f2Sdan INSERT INTO z SELECT NULL, randomblob(800) FROM z; 347ef4ee8f2Sdan } 348ef4ee8f2Sdan faultsim_save_and_close 349ef4ee8f2Sdan} {} 350ef4ee8f2Sdando_faultsim_test walfault-10 -prep { 351ef4ee8f2Sdan faultsim_restore_and_reopen 352ef4ee8f2Sdan execsql { 353ef4ee8f2Sdan PRAGMA cache_size = 10; 354ef4ee8f2Sdan BEGIN; 355ef4ee8f2Sdan UPDATE z SET zzz = randomblob(799); 356ef4ee8f2Sdan } 357ef4ee8f2Sdan 358ef4ee8f2Sdan set ::stmt [sqlite3_prepare db "SELECT zzz FROM z WHERE zz IN (1, 2, 3)" -1] 359ef4ee8f2Sdan sqlite3_step $::stmt 360ef4ee8f2Sdan} -body { 361ef4ee8f2Sdan execsql { INSERT INTO z VALUES(NULL, NULL) } 362ef4ee8f2Sdan} -test { 363ef4ee8f2Sdan sqlite3_finalize $::stmt 364ef4ee8f2Sdan faultsim_integrity_check 365ef4ee8f2Sdan 366ef4ee8f2Sdan faultsim_test_result {0 {}} 367ef4ee8f2Sdan catch { db eval { ROLLBACK } } 368ef4ee8f2Sdan faultsim_integrity_check 369ef4ee8f2Sdan 370ef4ee8f2Sdan set n [db eval {SELECT count(*), sum(length(zzz)) FROM z}] 371ef4ee8f2Sdan if {$n != "64 51200"} { error "Incorrect data: $n" } 372ef4ee8f2Sdan} 373ef4ee8f2Sdan 3745d656852Sdan#-------------------------------------------------------------------------- 3755d656852Sdan# Test fault injection while checkpointing a large WAL file, if the 3765d656852Sdan# checkpoint is the first operation run after opening the database. 3775d656852Sdan# This means that some of the required wal-index pages are mapped as part of 3785d656852Sdan# the checkpoint process, which means there are a few more opportunities 3795d656852Sdan# for IO errors. 3805d656852Sdan# 381f886b4f8Sdrh# To speed this up, IO errors are only simulated within xShmMap() calls. 3825d656852Sdan# 3835d656852Sdando_test walfault-11-pre-1 { 3845d656852Sdan sqlite3 db test.db 3855d656852Sdan execsql { 3865d656852Sdan PRAGMA journal_mode = WAL; 3875d656852Sdan PRAGMA wal_autocheckpoint = 0; 3885d656852Sdan BEGIN; 3895d656852Sdan CREATE TABLE abc(a PRIMARY KEY); 3905d656852Sdan INSERT INTO abc VALUES(randomblob(1500)); 3915d656852Sdan INSERT INTO abc VALUES(randomblob(1500)); 3925d656852Sdan INSERT INTO abc SELECT randomblob(1500) FROM abc; -- 4 3935d656852Sdan INSERT INTO abc SELECT randomblob(1500) FROM abc; -- 8 3945d656852Sdan INSERT INTO abc SELECT randomblob(1500) FROM abc; -- 16 3955d656852Sdan INSERT INTO abc SELECT randomblob(1500) FROM abc; -- 32 3965d656852Sdan INSERT INTO abc SELECT randomblob(1500) FROM abc; -- 64 3975d656852Sdan INSERT INTO abc SELECT randomblob(1500) FROM abc; -- 128 3985d656852Sdan INSERT INTO abc SELECT randomblob(1500) FROM abc; -- 256 3995d656852Sdan INSERT INTO abc SELECT randomblob(1500) FROM abc; -- 512 4005d656852Sdan INSERT INTO abc SELECT randomblob(1500) FROM abc; -- 1024 4015d656852Sdan INSERT INTO abc SELECT randomblob(1500) FROM abc; -- 2048 4025d656852Sdan INSERT INTO abc SELECT randomblob(1500) FROM abc; -- 4096 4035d656852Sdan COMMIT; 4045d656852Sdan } 4055d656852Sdan faultsim_save_and_close 4065d656852Sdan} {} 4075d656852Sdando_faultsim_test walfault-11 -faults shmerr* -prep { 4085d656852Sdan catch { db2 close } 4095d656852Sdan faultsim_restore_and_reopen 410f886b4f8Sdrh shmfault filter xShmMap 4115d656852Sdan} -body { 4125d656852Sdan db eval { SELECT count(*) FROM abc } 4135d656852Sdan sqlite3 db2 test.db -vfs shmfault 4145d656852Sdan db2 eval { PRAGMA wal_checkpoint } 41528f9b0b5Sdan set {} {} 4165d656852Sdan} -test { 4175d656852Sdan faultsim_test_result {0 {}} 4185d656852Sdan} 4195d656852Sdan 4205d656852Sdan#------------------------------------------------------------------------- 4215d656852Sdan# Test the handling of the various IO/OOM/SHM errors that may occur during 4225d656852Sdan# a log recovery operation undertaken as part of a call to 4235d656852Sdan# sqlite3_wal_checkpoint(). 4245d656852Sdan# 4255d656852Sdando_test walfault-12-pre-1 { 4265d656852Sdan faultsim_delete_and_reopen 4275d656852Sdan execsql { 4285d656852Sdan PRAGMA journal_mode = WAL; 4295d656852Sdan PRAGMA wal_autocheckpoint = 0; 4305d656852Sdan BEGIN; 4315d656852Sdan CREATE TABLE abc(a PRIMARY KEY); 4325d656852Sdan INSERT INTO abc VALUES(randomblob(1500)); 4335d656852Sdan INSERT INTO abc VALUES(randomblob(1500)); 4345d656852Sdan COMMIT; 4355d656852Sdan } 4365d656852Sdan faultsim_save_and_close 4375d656852Sdan} {} 4385d656852Sdando_faultsim_test walfault-12 -prep { 4395d656852Sdan if {[info commands shmfault] == ""} { 4405d656852Sdan testvfs shmfault -default true 4415d656852Sdan } 4425d656852Sdan faultsim_restore_and_reopen 4435d656852Sdan db eval { SELECT * FROM sqlite_master } 4445d656852Sdan shmfault shm test.db [string repeat "\000" 40] 4455d656852Sdan} -body { 4465d656852Sdan set rc [sqlite3_wal_checkpoint db] 4475d656852Sdan if {$rc != "SQLITE_OK"} { error [sqlite3_errmsg db] } 4485d656852Sdan} -test { 4495d656852Sdan db close 4505d656852Sdan faultsim_test_result {0 {}} 4515d656852Sdan} 4525d656852Sdan 4538c408004Sdan#------------------------------------------------------------------------- 4548c408004Sdan# Test simple recovery, reading and writing a database file using a 4558c408004Sdan# heap-memory wal-index. 4568c408004Sdan# 4578c408004Sdando_test walfault-13-pre-1 { 4588c408004Sdan faultsim_delete_and_reopen 4598c408004Sdan execsql { 4608c408004Sdan PRAGMA journal_mode = WAL; 4618c408004Sdan PRAGMA wal_autocheckpoint = 0; 4628c408004Sdan BEGIN; 4638c408004Sdan CREATE TABLE abc(a PRIMARY KEY); 4648c408004Sdan INSERT INTO abc VALUES(randomblob(1500)); 4658c408004Sdan INSERT INTO abc VALUES(randomblob(1500)); 4668c408004Sdan COMMIT; 4678c408004Sdan } 4688c408004Sdan faultsim_save_and_close 469fda06befSmistachkin delete_file sv_test.db-shm 4708c408004Sdan} {} 4718c408004Sdan 4728c408004Sdando_faultsim_test walfault-13.1 -prep { 4738c408004Sdan faultsim_restore_and_reopen 4748c408004Sdan} -body { 4758c408004Sdan db eval { PRAGMA locking_mode = exclusive } 4768c408004Sdan db eval { SELECT count(*) FROM abc } 4778c408004Sdan} -test { 4788c408004Sdan faultsim_test_result {0 2} 4798c408004Sdan if {[file exists test.db-shm]} { error "Not using heap-memory mode" } 4808c408004Sdan faultsim_integrity_check 4818c408004Sdan} 4828c408004Sdan 4838c408004Sdando_faultsim_test walfault-13.2 -prep { 4848c408004Sdan faultsim_restore_and_reopen 4858c408004Sdan db eval { PRAGMA locking_mode = exclusive } 4868c408004Sdan} -body { 4878c408004Sdan db eval { PRAGMA journal_mode = delete } 4888c408004Sdan} -test { 4898c408004Sdan faultsim_test_result {0 delete} 4908c408004Sdan if {[file exists test.db-shm]} { error "Not using heap-memory mode" } 4918c408004Sdan faultsim_integrity_check 4928c408004Sdan} 4938c408004Sdan 4948c408004Sdando_test walfault-13-pre-2 { 4958c408004Sdan faultsim_delete_and_reopen 4968c408004Sdan execsql { 4978c408004Sdan BEGIN; 4988c408004Sdan CREATE TABLE abc(a PRIMARY KEY); 4998c408004Sdan INSERT INTO abc VALUES(randomblob(1500)); 5008c408004Sdan INSERT INTO abc VALUES(randomblob(1500)); 5018c408004Sdan COMMIT; 5028c408004Sdan } 5038c408004Sdan faultsim_save_and_close 5048c408004Sdan} {} 5058c408004Sdan 5068c408004Sdando_faultsim_test walfault-13.3 -prep { 5078c408004Sdan faultsim_restore_and_reopen 5088c408004Sdan} -body { 5098c408004Sdan db eval { 5108c408004Sdan PRAGMA locking_mode = exclusive; 5118c408004Sdan PRAGMA journal_mode = WAL; 5128c408004Sdan INSERT INTO abc VALUES(randomblob(1500)); 5138c408004Sdan } 5148c408004Sdan} -test { 5158c408004Sdan faultsim_test_result {0 {exclusive wal}} 5168c408004Sdan if {[file exists test.db-shm]} { error "Not using heap-memory mode" } 5178c408004Sdan faultsim_integrity_check 5188c408004Sdan set nRow [db eval {SELECT count(*) FROM abc}] 5198c408004Sdan if {!(($nRow==2 && $testrc) || $nRow==3)} { error "Bad db content" } 5208c408004Sdan} 5215d656852Sdan 522e08c2066Sdan#------------------------------------------------------------------------- 523e08c2066Sdan# Test fault-handling when wrapping around to the start of a WAL file. 524e08c2066Sdan# 525e08c2066Sdando_test walfault-14-pre { 526e08c2066Sdan faultsim_delete_and_reopen 527e08c2066Sdan execsql { 528de17f948Sdan PRAGMA auto_vacuum = 0; 529e08c2066Sdan PRAGMA journal_mode = WAL; 530e08c2066Sdan BEGIN; 531e08c2066Sdan CREATE TABLE abc(a PRIMARY KEY); 532e08c2066Sdan INSERT INTO abc VALUES(randomblob(1500)); 533e08c2066Sdan INSERT INTO abc VALUES(randomblob(1500)); 534e08c2066Sdan COMMIT; 535e08c2066Sdan } 536e08c2066Sdan faultsim_save_and_close 537e08c2066Sdan} {} 538e08c2066Sdando_faultsim_test walfault-14 -prep { 539e08c2066Sdan faultsim_restore_and_reopen 540e08c2066Sdan} -body { 541e08c2066Sdan db eval { 54228f9b0b5Sdan PRAGMA wal_checkpoint = full; 543e08c2066Sdan INSERT INTO abc VALUES(randomblob(1500)); 544e08c2066Sdan } 545e08c2066Sdan} -test { 5469d69c5d1Sdan faultsim_test_result {0 {0 9 9}} 547e08c2066Sdan faultsim_integrity_check 548e08c2066Sdan set nRow [db eval {SELECT count(*) FROM abc}] 549e08c2066Sdan if {!(($nRow==2 && $testrc) || $nRow==3)} { error "Bad db content" } 550e08c2066Sdan} 551d7a558a9Sdan 552d7a558a9Sdan#------------------------------------------------------------------------- 553d7a558a9Sdan# Test fault-handling when switching out of exclusive-locking mode. 554d7a558a9Sdan# 555*824f2842Smistachkindo_test walfault-15-pre { 556d7a558a9Sdan faultsim_delete_and_reopen 557d7a558a9Sdan execsql { 558d7a558a9Sdan PRAGMA auto_vacuum = 0; 559d7a558a9Sdan PRAGMA journal_mode = WAL; 560d7a558a9Sdan BEGIN; 561d7a558a9Sdan CREATE TABLE abc(a PRIMARY KEY); 562d7a558a9Sdan INSERT INTO abc VALUES(randomblob(1500)); 563d7a558a9Sdan INSERT INTO abc VALUES(randomblob(1500)); 564d7a558a9Sdan COMMIT; 565d7a558a9Sdan } 566d7a558a9Sdan faultsim_save_and_close 567d7a558a9Sdan} {} 568*824f2842Smistachkindo_faultsim_test walfault-15 -prep { 569d7a558a9Sdan faultsim_restore_and_reopen 570d7a558a9Sdan execsql { 571d7a558a9Sdan SELECT count(*) FROM abc; 572d7a558a9Sdan PRAGMA locking_mode = exclusive; 573d7a558a9Sdan BEGIN; 574d7a558a9Sdan INSERT INTO abc VALUES(randomblob(1500)); 575d7a558a9Sdan COMMIT; 576d7a558a9Sdan } 577d7a558a9Sdan} -body { 578d7a558a9Sdan db eval { 579d7a558a9Sdan PRAGMA locking_mode = normal; 580d7a558a9Sdan BEGIN; 581d7a558a9Sdan INSERT INTO abc VALUES(randomblob(1500)); 582d7a558a9Sdan COMMIT; 583d7a558a9Sdan } 584d7a558a9Sdan} -test { 585d7a558a9Sdan faultsim_integrity_check 586d7a558a9Sdan set nRow [db eval {SELECT count(*) FROM abc}] 587d7a558a9Sdan if {$nRow!=3 && $nRow!=4} { error "Bad db content" } 588d7a558a9Sdan} 589e08c2066Sdan 59076ed3bc0Sdanfinish_test 591