xref: /sqlite-3.40.0/test/walfault.test (revision 824f2842)
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