Improve tests for resuming ota updates following power failures. Fix a problem revealed by the same.

FossilOrigin-Name: 1cb675e5392f179516d8e7a52760922a6c7df4d0
This commit is contained in:
dan 2015-02-23 12:22:55 +00:00
parent ee9fa4af15
commit 882b8e0974
4 changed files with 110 additions and 38 deletions

View File

@ -36,35 +36,105 @@ do_execsql_test 1.0 {
db_save_and_close
for {set i 0} {$i < 10} {incr i} {
forcedelete test.db2 test.db2-journal test.db test.db-oal test.db-wal
# Determine the number of steps in applying the ota update to the test
# target database created above. Set $::ota_num_steps accordingly
#
# Check that the same number of steps are required to apply the ota
# update using many calls to sqlite3ota_step() on a single ota handle
# as required to apply it using a series of ota handles, on each of
# which sqlite3ota_step() is called once.
#
do_test 1.1 {
db_restore
do_test 2.$i.1 {
crashsql -file test.db2 -delay 3 -tclbody {
sqlite3ota ota test.db test.db2
breakpoint
set nStep 0
while {[ota step]=="SQLITE_OK"} { incr nStep }
ota close
} {SQLITE_DONE}
set ota_num_steps $nStep
do_test 1.2 {
db_restore
set nStep 0
while {1} {
sqlite3ota ota test.db test.db2
ota step
if {[ota close]=="SQLITE_DONE"} break
incr nStep
}
set nStep
} $ota_num_steps
sqlite3ota ota test.db file:test.db2?vfs=crash
ota step
# Run one or more tests using the target (test.db) and ota (test.db2)
# databases created above. As follows:
#
# 1. This process starts the ota update and calls sqlite3ota_step()
# $nPre times. Then closes the ota update handle.
#
# 2. A second process resumes the ota update and attempts to call
# sqlite3ota_step() $nStep times before closing the handle. A
# crash is simulated during each xSync() of file test.db2.
#
# 3. This process attempts to resume the ota update from whatever
# state it was left in by step (2). Test that it is successful
# in doing so and that the final target database is as expected.
#
# In total (nSync+1) tests are run, where nSync is the number of times
# xSync() is called on test.db2.
#
proc do_ota_crash_test {tn nPre nStep} {
set script [subst -nocommands {
sqlite3ota ota test.db file:test.db2?vfs=crash
set i 0
while {[set i] < $nStep} {
if {[ota step]!="SQLITE_OK"} break
incr i
}
ota close
}]
set bDone 0
for {set iDelay 1} {$bDone==0} {incr iDelay} {
forcedelete test.db2 test.db2-journal test.db test.db-oal test.db-wal
db_restore
if {$nPre>0} {
sqlite3ota ota test.db file:test.db2
set i 0
for {set i 0} {$i < $nPre} {incr i} {
if {[ota step]!="SQLITE_OK"} break
}
ota close
}
sqlite3ota ota test.db file:test.db2?vfs=crash
ota step
ota step
ota close
} {}
} {1 {child process exited abnormally}}
set res [crashsql -file test.db2 -delay $iDelay -tclbody $script {}]
set bDone 1
if {$res == "1 {child process exited abnormally}"} {
set bDone 0
} elseif {$res != "0 {}"} {
error "unexected catchsql result: $res"
}
do_test 2.$i.2 {
sqlite3ota ota test.db test.db2
while {[ota step]=="SQLITE_OK"} {}
ota close
} {SQLITE_DONE}
sqlite3 db test.db
do_execsql_test 2.$i.3 {
SELECT * FROM t1;
} {1 2 100 7 8 9 10 11 12 13 14 15}
do_execsql_test 2.$i.4 { PRAGMA integrity_check } {ok}
db close
sqlite3 db test.db
do_execsql_test $tn.delay=$iDelay {
SELECT * FROM t1;
PRAGMA integrity_check;
} {1 2 100 7 8 9 10 11 12 13 14 15 ok}
db close
}
}
for {set nPre 0} {$nPre < $ota_num_steps} {incr nPre} {
for {set is 1} {$is <= ($ota_num_steps - $nPre)} {incr is} {
do_ota_crash_test 2.pre=$nPre.step=$is $nPre $is
}
}
finish_test

View File

@ -2587,24 +2587,26 @@ sqlite3ota *sqlite3ota_open(const char *zTarget, const char *zOta){
}
assert( p->rc!=SQLITE_OK || p->eStage!=0 );
if( p->rc==SQLITE_OK
&& (p->eStage==OTA_STAGE_OAL || p->eStage==OTA_STAGE_MOVE)
){
/* Check that this is not a wal mode database. If it is, it cannot
** be updated. */
if( p->pTargetFd->pWalFd ){
if( p->rc==SQLITE_OK && p->pTargetFd->pWalFd ){
if( p->eStage==OTA_STAGE_OAL ){
p->rc = SQLITE_ERROR;
p->zErrmsg = sqlite3_mprintf("cannot update wal mode database");
}else if( p->eStage==OTA_STAGE_MOVE ){
p->eStage = OTA_STAGE_CKPT;
p->nStep = 0;
}
}
if( p->rc==SQLITE_OK
&& (p->eStage==OTA_STAGE_OAL || p->eStage==OTA_STAGE_MOVE)
&& pState->eStage!=0 && p->pTargetFd->iCookie!=pState->iCookie
){
/* At this point (pTargetFd->iCookie) contains the value of the
** change-counter cookie (the thing that gets incremented when a
** transaction is committed in rollback mode) currently stored on
** page 1 of the database file. */
else if( pState->eStage!=0 && p->pTargetFd->iCookie!=pState->iCookie ){
p->rc = SQLITE_BUSY;
p->zErrmsg = sqlite3_mprintf("database modified during ota update");
}
p->rc = SQLITE_BUSY;
p->zErrmsg = sqlite3_mprintf("database modified during ota update");
}
if( p->rc==SQLITE_OK ){

View File

@ -1,5 +1,5 @@
C Fix\ssome\sproblems\swith\sresuming\sota\supdates\sif\ssaving\sthe\sstate\sis\sinterrupted\sby\sa\spower\sfailure\sor\ssystem\scrash.
D 2015-02-21T20:08:25.212
C Improve\stests\sfor\sresuming\sota\supdates\sfollowing\spower\sfailures.\sFix\sa\sproblem\srevealed\sby\sthe\ssame.
D 2015-02-23T12:22:55.407
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 6b9e7677829aa94b9f30949656e27312aefb9a46
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -135,10 +135,10 @@ F ext/ota/ota7.test 1fe2c5761705374530e29f70c39693076028221a
F ext/ota/ota8.test cd70e63a0c29c45c0906692827deafa34638feda
F ext/ota/ota9.test d3eee95dd836824d07a22e5efcdb7bf6e869358b
F ext/ota/otaA.test ef4bfa8cfd4ed814ae86f7457b64aa2f18c90171
F ext/ota/otacrash.test dc036d06dc711ffc4c359851258a2f9ab64135e5
F ext/ota/otacrash.test a078d34e2edbcedac5f894e3e7d08d452a327007
F ext/ota/otafault.test 8c43586c2b96ca16bbce00b5d7e7d67316126db8
F ext/ota/otafault2.test fa202a98ca221faec318f3e5c5f39485b1256561
F ext/ota/sqlite3ota.c 3ee4de29a1fec09e8923d39246b72e9b79ff50bc
F ext/ota/sqlite3ota.c 7949ecd5b100da558a073bc7800971e3da822fb2
F ext/ota/sqlite3ota.h 052d87068751810a9dfba1a48954271501bb728f
F ext/ota/test_ota.c 9ec6ea945282f65f67f0e0468dad79a489818f44
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
@ -1258,7 +1258,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 718fd8b673d6557dd0eaad03e6a3332b5490afbf
R 7a06fb426588c48f2ea734b4acf1f016
P 6d5ed70d0dbabe9c2ab2f2dba47747d17d937781
R 4c48a15e3fb052167c1c2cb6db2c19fe
U dan
Z fe836bec0d39c3ec7b14b6776ea334a3
Z 4ecb7af4e3b45df7793dc31c4cb806df

View File

@ -1 +1 @@
6d5ed70d0dbabe9c2ab2f2dba47747d17d937781
1cb675e5392f179516d8e7a52760922a6c7df4d0