Add extra coverage test cases for wal.c. No changes to production code.

FossilOrigin-Name: f9d4ae0e8cc5d32c52eb78799f7959dd236ea9de
This commit is contained in:
dan
2010-06-05 11:53:34 +00:00
parent 3cac5dc9bc
commit ef4ee8f274
5 changed files with 192 additions and 19 deletions
+101 -1
View File
@@ -316,10 +316,110 @@ do_test wal3-4.4 {
sqlite3 db test.db -vfs T
catchsql { SELECT * FROM x }
} {1 {locking protocol}}
db close
T delete
#-------------------------------------------------------------------------
# Only one client may run recovery at a time. Test this mechanism.
#
# When client-2 tries to open a read transaction while client-1 is
# running recovery, it fails to obtain a lock on an aReadMark[] slot
# (because they are all locked by recovery). It then tries to obtain
# a shared lock on the RECOVER lock to see if there really is a
# recovery running or not.
#
# This block of tests checks the effect of an SQLITE_BUSY or SQLITE_IOERR
# being returned when client-2 attempts a shared lock on the RECOVER byte.
#
# An SQLITE_BUSY should be converted to an SQLITE_BUSY_RECOVERY. An
# SQLITE_IOERR should be returned to the caller.
#
do_test wal3-5.1 {
faultsim_delete_and_reopen
execsql {
PRAGMA journal_mode = WAL;
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1, 2);
INSERT INTO t1 VALUES(3, 4);
}
faultsim_save_and_close
} {}
testvfs T -default 1
T script method_callback
proc method_callback {method args} {
if {$method == "xShmBarrier"} {
incr ::barrier_count
if {$::barrier_count == 1} {
# This code is executed within the xShmBarrier() callback invoked
# by the client running recovery as part of writing the recovered
# wal-index header. If a second client attempts to access the
# database now, it reads a corrupt (partially written) wal-index
# header. But it cannot even get that far, as the first client
# is still holding all the locks (recovery takes an exclusive lock
# on *all* db locks, preventing access by any other client).
#
# If global variable ::wal3_do_lockfailure is non-zero, then set
# things up so that an IO error occurs within an xShmLock() callback
# made by the second client (aka [db2]).
#
sqlite3 db2 test.db
if { $::wal3_do_lockfailure } { T filter xShmLock }
set ::testrc [ catch { db2 eval "SELECT * FROM t1" } ::testmsg ]
T filter {}
db2 close
}
}
if {$method == "xShmLock"} {
foreach {file handle spec} $args break
if { $spec == "2 1 lock shared" } {
return SQLITE_IOERR
}
}
return SQLITE_OK
}
# Test a normal SQLITE_BUSY return.
#
T filter xShmBarrier
set testrc ""
set testmsg ""
set barrier_count 0
set wal3_do_lockfailure 0
do_test wal3-5.2 {
faultsim_restore_and_reopen
execsql { SELECT * FROM t1 }
} {1 2 3 4}
do_test wal3-5.3 {
list $::testrc $::testmsg
} {1 {database is locked}}
db close
# Test an SQLITE_IOERR return.
#
T filter xShmBarrier
set barrier_count 0
set wal3_do_lockfailure 1
set testrc ""
set testmsg ""
do_test wal3-5.4 {
faultsim_restore_and_reopen
execsql { SELECT * FROM t1 }
} {1 2 3 4}
do_test wal3-5.5 {
list $::testrc $::testmsg
} {1 {disk I/O error}}
db close
T delete
#-------------------------------------------------------------------------
# When opening a read-transaction on a database
#
finish_test