xref: /sqlite-3.40.0/test/pager1.test (revision de4996e2)
1e91a54e1Sdan# 2010 June 15
2e91a54e1Sdan#
3e91a54e1Sdan# The author disclaims copyright to this source code.  In place of
4e91a54e1Sdan# a legal notice, here is a blessing:
5e91a54e1Sdan#
6e91a54e1Sdan#    May you do good and not evil.
7e91a54e1Sdan#    May you find forgiveness for yourself and forgive others.
8e91a54e1Sdan#    May you share freely, never taking more than you give.
9e91a54e1Sdan#
10e91a54e1Sdan#***********************************************************************
11e91a54e1Sdan#
12e91a54e1Sdan
13e91a54e1Sdanset testdir [file dirname $argv0]
14e91a54e1Sdansource $testdir/tester.tcl
15e91a54e1Sdansource $testdir/lock_common.tcl
16e91a54e1Sdansource $testdir/malloc_common.tcl
17e91a54e1Sdan
18b0ac3e3aSdan#
19b0ac3e3aSdan# pager1-1.*: Test inter-process locking (clients in multiple processes).
20b0ac3e3aSdan#
21b0ac3e3aSdan# pager1-2.*: Test intra-process locking (multiple clients in this process).
22b0ac3e3aSdan#
23b0ac3e3aSdan# pager1-3.*: Savepoint related tests.
24b0ac3e3aSdan#
251f4cb65aSdan# pager1-4.*: Hot-journal related tests.
261f4cb65aSdan#
27*de4996e2Sdan# pager1-5.*: Cases related to multi-file commits.
28*de4996e2Sdan#
29b0ac3e3aSdan
30b0ac3e3aSdanproc do_execsql_test {testname sql result} {
31b0ac3e3aSdan  uplevel do_test $testname [list "execsql {$sql}"] [list $result]
32b0ac3e3aSdan}
33b0ac3e3aSdanproc do_catchsql_test {testname sql result} {
34b0ac3e3aSdan  uplevel do_test $testname [list "catchsql {$sql}"] [list $result]
35b0ac3e3aSdan}
36b0ac3e3aSdan
3753f04f3bSdanset a_string_counter 1
3853f04f3bSdanproc a_string {n} {
3953f04f3bSdan  global a_string_counter
4053f04f3bSdan  incr a_string_counter
4153f04f3bSdan  string range [string repeat "${a_string_counter}." $n] 1 $n
4253f04f3bSdan}
4353f04f3bSdandb func a_string a_string
4453f04f3bSdan
45a4a9095eSdando_multiclient_test tn {
46e91a54e1Sdan
47e91a54e1Sdan  # Create and populate a database table using connection [db]. Check
48e91a54e1Sdan  # that connections [db2] and [db3] can see the schema and content.
49e91a54e1Sdan  #
50e91a54e1Sdan  do_test pager1-$tn.1 {
51e91a54e1Sdan    sql1 {
52e91a54e1Sdan      CREATE TABLE t1(a PRIMARY KEY, b);
53e91a54e1Sdan      CREATE INDEX i1 ON t1(b);
54e91a54e1Sdan      INSERT INTO t1 VALUES(1, 'one');
55e91a54e1Sdan      INSERT INTO t1 VALUES(2, 'two');
56e91a54e1Sdan    }
57e91a54e1Sdan  } {}
58e91a54e1Sdan  do_test pager1-$tn.2 { sql2 { SELECT * FROM t1 } } {1 one 2 two}
59e91a54e1Sdan  do_test pager1-$tn.3 { sql3 { SELECT * FROM t1 } } {1 one 2 two}
60e91a54e1Sdan
61e91a54e1Sdan  # Open a transaction and add a row using [db]. This puts [db] in
62e91a54e1Sdan  # RESERVED state. Check that connections [db2] and [db3] can still
63e91a54e1Sdan  # read the database content as it was before the transaction was
64e91a54e1Sdan  # opened. [db] should see the inserted row.
65e91a54e1Sdan  #
66e91a54e1Sdan  do_test pager1-$tn.4 {
67e91a54e1Sdan    sql1 {
68e91a54e1Sdan      BEGIN;
69e91a54e1Sdan        INSERT INTO t1 VALUES(3, 'three');
70e91a54e1Sdan    }
71e91a54e1Sdan  } {}
72e91a54e1Sdan  do_test pager1-$tn.5 { sql2 { SELECT * FROM t1 } } {1 one 2 two}
73e91a54e1Sdan  do_test pager1-$tn.7 { sql1 { SELECT * FROM t1 } } {1 one 2 two 3 three}
74e91a54e1Sdan
75e91a54e1Sdan  # [db] still has an open write transaction. Check that this prevents
76e91a54e1Sdan  # other connections (specifically [db2]) from writing to the database.
77e91a54e1Sdan  #
78e91a54e1Sdan  # Even if [db2] opens a transaction first, it may not write to the
79e91a54e1Sdan  # database. After the attempt to write the db within a transaction,
80e91a54e1Sdan  # [db2] is left with an open transaction, but not a read-lock on
81e91a54e1Sdan  # the main database. So it does not prevent [db] from committing.
82e91a54e1Sdan  #
83e91a54e1Sdan  do_test pager1-$tn.8 {
84e91a54e1Sdan    csql2 { UPDATE t1 SET a = a + 10 }
85e91a54e1Sdan  } {1 {database is locked}}
86e91a54e1Sdan  do_test pager1-$tn.9 {
87e91a54e1Sdan    csql2 {
88e91a54e1Sdan      BEGIN;
89e91a54e1Sdan      UPDATE t1 SET a = a + 10;
90e91a54e1Sdan    }
91e91a54e1Sdan  } {1 {database is locked}}
92e91a54e1Sdan
93e91a54e1Sdan  # Have [db] commit its transactions. Check the other connections can
94e91a54e1Sdan  # now see the new database content.
95e91a54e1Sdan  #
96e91a54e1Sdan  do_test pager1-$tn.10 { sql1 { COMMIT } } {}
97e91a54e1Sdan  do_test pager1-$tn.11 { sql1 { SELECT * FROM t1 } } {1 one 2 two 3 three}
98e91a54e1Sdan  do_test pager1-$tn.12 { sql2 { SELECT * FROM t1 } } {1 one 2 two 3 three}
99e91a54e1Sdan  do_test pager1-$tn.13 { sql3 { SELECT * FROM t1 } } {1 one 2 two 3 three}
100e91a54e1Sdan
101e91a54e1Sdan  # Check that, as noted above, [db2] really did keep an open transaction
102e91a54e1Sdan  # after the attempt to write the database failed.
103e91a54e1Sdan  #
104e91a54e1Sdan  do_test pager1-$tn.14 {
105e91a54e1Sdan    csql2 { BEGIN }
106e91a54e1Sdan  } {1 {cannot start a transaction within a transaction}}
107e91a54e1Sdan  do_test pager1-$tn.15 { sql2 { ROLLBACK } } {}
108e91a54e1Sdan
109e91a54e1Sdan  # Have [db2] open a transaction and take a read-lock on the database.
110e91a54e1Sdan  # Check that this prevents [db] from writing to the database (outside
111e91a54e1Sdan  # of any transaction). After this fails, check that [db3] can read
112e91a54e1Sdan  # the db (showing that [db] did not take a PENDING lock etc.)
113e91a54e1Sdan  #
114e91a54e1Sdan  do_test pager1-$tn.15 {
115e91a54e1Sdan    sql2 { BEGIN; SELECT * FROM t1; }
116e91a54e1Sdan  } {1 one 2 two 3 three}
117e91a54e1Sdan  do_test pager1-$tn.16 {
118e91a54e1Sdan    csql1 { UPDATE t1 SET a = a + 10 }
119e91a54e1Sdan  } {1 {database is locked}}
120e91a54e1Sdan  do_test pager1-$tn.17 { sql3 { SELECT * FROM t1 } } {1 one 2 two 3 three}
121e91a54e1Sdan
122e91a54e1Sdan  # This time, have [db] open a transaction before writing the database.
123e91a54e1Sdan  # This works - [db] gets a RESERVED lock which does not conflict with
124e91a54e1Sdan  # the SHARED lock [db2] is holding.
125e91a54e1Sdan  #
126e91a54e1Sdan  do_test pager1-$tn.18 {
127e91a54e1Sdan    sql1 {
128e91a54e1Sdan      BEGIN;
129e91a54e1Sdan      UPDATE t1 SET a = a + 10;
130e91a54e1Sdan    }
131e91a54e1Sdan  } {}
132e91a54e1Sdan  do_test pager1-$tn-19 {
133e91a54e1Sdan    sql1 { PRAGMA lock_status }
134e91a54e1Sdan  } {main reserved temp closed}
135e91a54e1Sdan  do_test pager1-$tn-20 {
136e91a54e1Sdan    sql2 { PRAGMA lock_status }
137e91a54e1Sdan  } {main shared temp closed}
138e91a54e1Sdan
139e91a54e1Sdan  # Check that all connections can still read the database. Only [db] sees
140e91a54e1Sdan  # the updated content (as the transaction has not been committed yet).
141e91a54e1Sdan  #
142e91a54e1Sdan  do_test pager1-$tn.21 { sql1 { SELECT * FROM t1 } } {11 one 12 two 13 three}
143e91a54e1Sdan  do_test pager1-$tn.22 { sql2 { SELECT * FROM t1 } } {1 one 2 two 3 three}
144e91a54e1Sdan  do_test pager1-$tn.23 { sql3 { SELECT * FROM t1 } } {1 one 2 two 3 three}
145e91a54e1Sdan
146e91a54e1Sdan  # Because [db2] still has the SHARED lock, [db] is unable to commit the
147e91a54e1Sdan  # transaction. If it tries, an error is returned and the connection
148e91a54e1Sdan  # upgrades to a PENDING lock.
149e91a54e1Sdan  #
150e91a54e1Sdan  # Once this happens, [db] can read the database and see the new content,
151e91a54e1Sdan  # [db2] (still holding SHARED) can still read the old content, but [db3]
152e91a54e1Sdan  # (not holding any lock) is prevented by [db]'s PENDING from reading
153e91a54e1Sdan  # the database.
154e91a54e1Sdan  #
155e91a54e1Sdan  do_test pager1-$tn.24 { csql1 { COMMIT } } {1 {database is locked}}
156e91a54e1Sdan  do_test pager1-$tn-25 {
157e91a54e1Sdan    sql1 { PRAGMA lock_status }
158e91a54e1Sdan  } {main pending temp closed}
159e91a54e1Sdan  do_test pager1-$tn.26 { sql1 { SELECT * FROM t1  } } {11 one 12 two 13 three}
160e91a54e1Sdan  do_test pager1-$tn.27 { sql2 { SELECT * FROM t1  } } {1 one 2 two 3 three}
161e91a54e1Sdan  do_test pager1-$tn.28 { csql3 { SELECT * FROM t1 } } {1 {database is locked}}
162e91a54e1Sdan
163e91a54e1Sdan  # Have [db2] commit its read transaction, releasing the SHARED lock it
164e91a54e1Sdan  # is holding. Now, neither [db2] nor [db3] may read the database (as [db]
165e91a54e1Sdan  # is still holding a PENDING).
166e91a54e1Sdan  #
167e91a54e1Sdan  do_test pager1-$tn.29 { sql2 { COMMIT } } {}
168e91a54e1Sdan  do_test pager1-$tn.30 { csql2 { SELECT * FROM t1 } } {1 {database is locked}}
169e91a54e1Sdan  do_test pager1-$tn.31 { csql3 { SELECT * FROM t1 } } {1 {database is locked}}
170e91a54e1Sdan
171e91a54e1Sdan  # [db] is now able to commit the transaction. Once the transaction is
172e91a54e1Sdan  # committed, all three connections can read the new content.
173e91a54e1Sdan  #
174e91a54e1Sdan  do_test pager1-$tn.25 { sql1 { UPDATE t1 SET a = a+10 } } {}
175e91a54e1Sdan  do_test pager1-$tn.26 { sql1 { COMMIT } } {}
176e91a54e1Sdan  do_test pager1-$tn.27 { sql1 { SELECT * FROM t1 } } {21 one 22 two 23 three}
177e91a54e1Sdan  do_test pager1-$tn.27 { sql2 { SELECT * FROM t1 } } {21 one 22 two 23 three}
178e91a54e1Sdan  do_test pager1-$tn.28 { sql3 { SELECT * FROM t1 } } {21 one 22 two 23 three}
179e91a54e1Sdan}
180e91a54e1Sdan
18153f04f3bSdan#-------------------------------------------------------------------------
18253f04f3bSdan# Savepoint related test cases.
18353f04f3bSdan#
184b0ac3e3aSdando_test pager1-3.1 {
185b0ac3e3aSdan  faultsim_delete_and_reopen
186b0ac3e3aSdan  execsql {
187b0ac3e3aSdan    CREATE TABLE t1(a PRIMARY KEY, b);
188b0ac3e3aSdan    CREATE TABLE counter(
189b0ac3e3aSdan      i CHECK (i<5),
190b0ac3e3aSdan      u CHECK (u<10)
191b0ac3e3aSdan    );
192b0ac3e3aSdan    INSERT INTO counter VALUES(0, 0);
193b0ac3e3aSdan    CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
194b0ac3e3aSdan      UPDATE counter SET i = i+1;
195b0ac3e3aSdan    END;
196b0ac3e3aSdan    CREATE TRIGGER tr2 AFTER UPDATE ON t1 BEGIN
197b0ac3e3aSdan      UPDATE counter SET u = u+1;
198b0ac3e3aSdan    END;
199b0ac3e3aSdan  }
200b0ac3e3aSdan  execsql { SELECT * FROM counter }
201b0ac3e3aSdan} {0 0}
202b0ac3e3aSdan
203b0ac3e3aSdando_execsql_test pager1-3.2 {
204b0ac3e3aSdan  BEGIN;
205b0ac3e3aSdan    INSERT INTO t1 VALUES(1, randomblob(1500));
206b0ac3e3aSdan    INSERT INTO t1 VALUES(2, randomblob(1500));
207b0ac3e3aSdan    INSERT INTO t1 VALUES(3, randomblob(1500));
208b0ac3e3aSdan    SELECT * FROM counter;
209b0ac3e3aSdan} {3 0}
210b0ac3e3aSdando_catchsql_test pager1-3.3 {
211b0ac3e3aSdan    INSERT INTO t1 SELECT a+3, randomblob(1500) FROM t1
212b0ac3e3aSdan} {1 {constraint failed}}
213b0ac3e3aSdando_execsql_test pager1-3.4 { SELECT * FROM counter } {3 0}
214b0ac3e3aSdando_execsql_test pager1-3.5 { SELECT a FROM t1 } {1 2 3}
215b0ac3e3aSdando_execsql_test pager1-3.6 { COMMIT } {}
216b0ac3e3aSdan
217*de4996e2Sdanset otn 0
2181f4cb65aSdantestvfs tv -default 1
2191f4cb65aSdanforeach code [list {
2201f4cb65aSdan  set s 512
2211f4cb65aSdan} {
2221f4cb65aSdan  set s 1024
2231f4cb65aSdan  set sql { PRAGMA journal_mode = memory }
2241f4cb65aSdan} {
2251f4cb65aSdan  set s 2048
2261f4cb65aSdan  tv devchar safe_append
2271f4cb65aSdan} {
2281f4cb65aSdan  set s 4096
229*de4996e2Sdan} {
230*de4996e2Sdan  set s 4096
2311f4cb65aSdan  set sql { PRAGMA journal_mode = WAL }
232*de4996e2Sdan} {
233*de4996e2Sdan  set s 8192
234*de4996e2Sdan  set sql { PRAGMA synchronous = off }
2351f4cb65aSdan}] {
236*de4996e2Sdan
237*de4996e2Sdan  incr otn
238*de4996e2Sdan  set sql ""
239*de4996e2Sdan  tv devchar {}
2401f4cb65aSdan  eval $code
2411f4cb65aSdan  tv sectorsize $s
2421f4cb65aSdan
243*de4996e2Sdan  do_test pager1-3.7.$otn.0 {
2441f4cb65aSdan    faultsim_delete_and_reopen
2451f4cb65aSdan    execsql $sql
2461f4cb65aSdan    execsql {
2471f4cb65aSdan      PRAGMA cache_size = 10;
2481f4cb65aSdan      CREATE TABLE t1(i INTEGER PRIMARY KEY, j blob);
2491f4cb65aSdan    }
2501f4cb65aSdan  } {}
2511f4cb65aSdan
2521f4cb65aSdan  set tn 0
2531f4cb65aSdan  set lowpoint 0
2541f4cb65aSdan  foreach x {
255*de4996e2Sdan    100 x 0 100
256*de4996e2Sdan  x
2571f4cb65aSdan    70 22 96 59 96 50 22 56 21 16 37 64 43 40  0 38 22 38 55  0  6
2581f4cb65aSdan    43 62 32 93 54 18 13 29 45 66 29 25 61 31 53 82 75 25 96 86 10 69
2591f4cb65aSdan     2 29  6 60 80 95 42 82 85 50 68 96 90 39 78 69 87 97 48 74 65 43
2601f4cb65aSdan  x
2611f4cb65aSdan    86 34 26 50 41 85 58 44 89 22  6 51 45 46 58 32 97  6  1 12 32  2
2621f4cb65aSdan    69 39 48 71 33 31  5 58 90 43 24 54 12  9 18 57  4 38 91 42 27 45
2631f4cb65aSdan    50 38 56 29 10  0 26 37 83  1 78 15 47 30 75 62 46 29 68  5 30  4
2641f4cb65aSdan    27 96 33 95 79 75 56 10 29 70 32 75 52 88  5 36 50 57 46 63 88 65
2651f4cb65aSdan  x
2661f4cb65aSdan    44 95 64 20 24 35 69 61 61  2 35 92 42 46 23 98 78  1 38 72 79 35
2671f4cb65aSdan    94 37 13 59  5 93 27 58 80 75 58  7 67 13 10 76 84  4  8 70 81 45
2681f4cb65aSdan     8 41 98  5 60 26 92 29 91 90  2 62 40  4  5 22 80 15 83 76 52 88
2691f4cb65aSdan    29  5 68 73 72  7 54 17 89 32 81 94 51 28 53 71  8 42 54 59 70 79
2701f4cb65aSdan  x
2711f4cb65aSdan  } {
2721f4cb65aSdan    incr tn
2731f4cb65aSdan    set now [db one {SELECT count(i) FROM t1}]
2741f4cb65aSdan    if {$x == "x"} {
2751f4cb65aSdan      execsql { COMMIT ; BEGIN }
2761f4cb65aSdan      set lowpoint $now
277*de4996e2Sdan      do_test pager1.3.7.$otn.$tn {
2781f4cb65aSdan        sqlite3 db2 test.db
2791f4cb65aSdan        execsql {
2801f4cb65aSdan          SELECT COALESCE(max(i), 0) FROM t1;
2811f4cb65aSdan          PRAGMA integrity_check;
2821f4cb65aSdan        }
2831f4cb65aSdan      } [list $lowpoint ok]
2841f4cb65aSdan      db2 close
2851f4cb65aSdan    } else {
2861f4cb65aSdan      if {$now > $x } {
2871f4cb65aSdan        if { $x>=$lowpoint } {
2881f4cb65aSdan          execsql "ROLLBACK TO sp_$x"
2891f4cb65aSdan        } else {
2901f4cb65aSdan          execsql "DELETE FROM t1 WHERE i>$x"
2911f4cb65aSdan          set lowpoint $x
2921f4cb65aSdan        }
2931f4cb65aSdan      } elseif {$now < $x} {
2941f4cb65aSdan        for {set k $now} {$k < $x} {incr k} {
2951f4cb65aSdan          execsql "SAVEPOINT sp_$k"
2961f4cb65aSdan          execsql { INSERT INTO t1(j) VALUES(randomblob(1500)) }
2971f4cb65aSdan        }
2981f4cb65aSdan      }
299*de4996e2Sdan      do_execsql_test pager1.3.7.$otn.$tn {
3001f4cb65aSdan        SELECT COALESCE(max(i), 0) FROM t1;
3011f4cb65aSdan        PRAGMA integrity_check;
3021f4cb65aSdan      } [list $x ok]
3031f4cb65aSdan    }
3041f4cb65aSdan  }
3051f4cb65aSdan}
3061f4cb65aSdandb close
3071f4cb65aSdantv delete
3081f4cb65aSdan
30953f04f3bSdan#-------------------------------------------------------------------------
31053f04f3bSdan# Hot journal rollback related test cases.
31153f04f3bSdan#
31253f04f3bSdan# pager1.4.1.*: Test that the pager module deletes very small invalid
31353f04f3bSdan#               journal files.
31453f04f3bSdan#
31553f04f3bSdan# pager1.4.2.*: Test that if the master journal pointer at the end of a
31653f04f3bSdan#               hot-journal file appears to be corrupt (checksum does not
31753f04f3bSdan#               compute) the associated journal is rolled back (and no
31853f04f3bSdan#               xAccess() call to check for the presence of any master
31953f04f3bSdan#               journal file is made).
32053f04f3bSdan#
321*de4996e2Sdan# pager1.4.3.*: Test that the contents of a hot-journal are ignored if the
322*de4996e2Sdan#               page-size or sector-size in the journal header appear to
323*de4996e2Sdan#               be invalid (too large, too small or not a power of 2).
324*de4996e2Sdan#
32553f04f3bSdando_test pager1.4.1.1 {
32653f04f3bSdan  faultsim_delete_and_reopen
32753f04f3bSdan  execsql {
32853f04f3bSdan    CREATE TABLE x(y, z);
32953f04f3bSdan    INSERT INTO x VALUES(1, 2);
33053f04f3bSdan  }
33153f04f3bSdan  set fd [open test.db-journal w]
33253f04f3bSdan  puts -nonewline $fd "helloworld"
33353f04f3bSdan  close $fd
33453f04f3bSdan  file exists test.db-journal
33553f04f3bSdan} {1}
33653f04f3bSdando_test pager1.4.1.2 { execsql { SELECT * FROM x } } {1 2}
33753f04f3bSdando_test pager1.4.1.3 { file exists test.db-journal } {0}
33853f04f3bSdan
33953f04f3bSdan# Set up a [testvfs] to snapshot the file-system just before SQLite
34053f04f3bSdan# deletes the master-journal to commit a multi-file transaction.
34153f04f3bSdan#
34253f04f3bSdan# In subsequent test cases, invoking [faultsim_restore_and_reopen] sets
34353f04f3bSdan# up the file system to contain two databases, two hot-journal files and
34453f04f3bSdan# a master-journal.
34553f04f3bSdan#
34653f04f3bSdando_test pager1.4.2.1 {
34753f04f3bSdan  testvfs tstvfs -default 1
34853f04f3bSdan  tstvfs filter xDelete
34953f04f3bSdan  tstvfs script xDeleteCallback
35053f04f3bSdan  proc xDeleteCallback {method file args} {
35153f04f3bSdan    set file [file tail $file]
35253f04f3bSdan    if { [string match *mj* $file] } { faultsim_save }
35353f04f3bSdan  }
35453f04f3bSdan  faultsim_delete_and_reopen
35553f04f3bSdan  db func a_string a_string
35653f04f3bSdan  execsql {
35753f04f3bSdan    ATTACH 'test.db2' AS aux;
35853f04f3bSdan    PRAGMA journal_mode = DELETE;
35953f04f3bSdan    PRAGMA main.cache_size = 10;
36053f04f3bSdan    PRAGMA aux.cache_size = 10;
36153f04f3bSdan    CREATE TABLE t1(a UNIQUE, b UNIQUE);
36253f04f3bSdan    CREATE TABLE aux.t2(a UNIQUE, b UNIQUE);
36353f04f3bSdan    INSERT INTO t1 VALUES(a_string(200), a_string(300));
36453f04f3bSdan    INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
36553f04f3bSdan    INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
36653f04f3bSdan    INSERT INTO t2 SELECT * FROM t1;
36753f04f3bSdan    BEGIN;
36853f04f3bSdan      INSERT INTO t1 SELECT a_string(201), a_string(301) FROM t1;
36953f04f3bSdan      INSERT INTO t1 SELECT a_string(202), a_string(302) FROM t1;
37053f04f3bSdan      INSERT INTO t1 SELECT a_string(203), a_string(303) FROM t1;
37153f04f3bSdan      INSERT INTO t1 SELECT a_string(204), a_string(304) FROM t1;
37253f04f3bSdan      REPLACE INTO t2 SELECT * FROM t1;
37353f04f3bSdan    COMMIT;
37453f04f3bSdan  }
37553f04f3bSdan  db close
37653f04f3bSdan  tstvfs delete
37753f04f3bSdan} {}
37853f04f3bSdando_test pager1.4.2.2 {
37953f04f3bSdan  faultsim_restore_and_reopen
38053f04f3bSdan  execsql {
38153f04f3bSdan    SELECT count(*) FROM t1;
38253f04f3bSdan    PRAGMA integrity_check;
38353f04f3bSdan  }
38453f04f3bSdan} {4 ok}
38553f04f3bSdando_test pager1.4.2.3 {
38653f04f3bSdan  faultsim_restore_and_reopen
38753f04f3bSdan  foreach f [glob test.db-mj*] { file delete -force $f }
38853f04f3bSdan  execsql {
38953f04f3bSdan    SELECT count(*) FROM t1;
39053f04f3bSdan    PRAGMA integrity_check;
39153f04f3bSdan  }
39253f04f3bSdan} {64 ok}
39353f04f3bSdando_test pager1.4.2.4 {
39453f04f3bSdan  faultsim_restore_and_reopen
39553f04f3bSdan  hexio_write test.db-journal [expr [file size test.db-journal]-20] 123456
39653f04f3bSdan  execsql {
39753f04f3bSdan    SELECT count(*) FROM t1;
39853f04f3bSdan    PRAGMA integrity_check;
39953f04f3bSdan  }
40053f04f3bSdan} {4 ok}
40153f04f3bSdando_test pager1.4.2.5 {
40253f04f3bSdan  faultsim_restore_and_reopen
40353f04f3bSdan  hexio_write test.db-journal [expr [file size test.db-journal]-20] 123456
40453f04f3bSdan  foreach f [glob test.db-mj*] { file delete -force $f }
40553f04f3bSdan  execsql {
40653f04f3bSdan    SELECT count(*) FROM t1;
40753f04f3bSdan    PRAGMA integrity_check;
40853f04f3bSdan  }
40953f04f3bSdan} {4 ok}
41053f04f3bSdan
411*de4996e2Sdando_test pager1.4.3.1 {
412*de4996e2Sdan  testvfs tstvfs -default 1
413*de4996e2Sdan  tstvfs filter xSync
414*de4996e2Sdan  tstvfs script xSyncCallback
415*de4996e2Sdan  proc xSyncCallback {method file args} {
416*de4996e2Sdan    set file [file tail $file]
417*de4996e2Sdan    if { 0==[string match *journal $file] } { faultsim_save }
418*de4996e2Sdan  }
419*de4996e2Sdan  faultsim_delete_and_reopen
420*de4996e2Sdan  execsql {
421*de4996e2Sdan    PRAGMA journal_mode = DELETE;
422*de4996e2Sdan    CREATE TABLE t1(a, b);
423*de4996e2Sdan    INSERT INTO t1 VALUES(1, 2);
424*de4996e2Sdan    INSERT INTO t1 VALUES(3, 4);
425*de4996e2Sdan  }
426*de4996e2Sdan  db close
427*de4996e2Sdan  tstvfs delete
428*de4996e2Sdan} {}
429*de4996e2Sdan
430*de4996e2Sdanforeach {tn ofst value result} {
431*de4996e2Sdan          2   20    31       {1 2 3 4}
432*de4996e2Sdan          3   20    32       {1 2 3 4}
433*de4996e2Sdan          4   20    33       {1 2 3 4}
434*de4996e2Sdan          5   20    65536    {1 2 3 4}
435*de4996e2Sdan          6   20    131072   {1 2 3 4}
436*de4996e2Sdan
437*de4996e2Sdan          7   24    511      {1 2 3 4}
438*de4996e2Sdan          8   24    513      {1 2 3 4}
439*de4996e2Sdan          9   24    65536    {1 2 3 4}
440*de4996e2Sdan
441*de4996e2Sdan         10   32    65536    {1 2}
442*de4996e2Sdan} {
443*de4996e2Sdan  do_test pager1.4.3.$tn {
444*de4996e2Sdan    faultsim_restore_and_reopen
445*de4996e2Sdan    hexio_write test.db-journal $ofst [format %.8x $value]
446*de4996e2Sdan    execsql { SELECT * FROM t1 }
447*de4996e2Sdan  } $result
448*de4996e2Sdan}
449*de4996e2Sdandb close
450*de4996e2Sdan
451*de4996e2Sdan#-------------------------------------------------------------------------
452*de4996e2Sdan#
453*de4996e2Sdan
454e91a54e1Sdanfinish_test
455e91a54e1Sdan
456