]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Improve tests for resuming ota updates following power failures. Fix a problem reveal...
authordan <dan@noemail.net>
Mon, 23 Feb 2015 12:22:55 +0000 (12:22 +0000)
committerdan <dan@noemail.net>
Mon, 23 Feb 2015 12:22:55 +0000 (12:22 +0000)
FossilOrigin-Name: 1cb675e5392f179516d8e7a52760922a6c7df4d0

ext/ota/otacrash.test
ext/ota/sqlite3ota.c
manifest
manifest.uuid

index 50784f4e5a4f43ef755eb91d9714f50618621b1c..9474a991524f2b762a38168901e149311c8e2a46 100644 (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
+  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
-  do_test 2.$i.1 {
-    crashsql -file test.db2 -delay 3 -tclbody {
+  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
-      ota close
 
-      sqlite3ota ota test.db file:test.db2?vfs=crash
-      ota step
-      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
-    } {}
-  } {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
index 07d941d04823de63a51fa569dbf0b7c8776aea04..d2f8d99ec8537d63fcfdefbce13b53c1a8c9b755 100644 (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 ){
index 0f80d215b45cd681c14a3cabbabbe0b076cc2ece..3e7fe6ced6478c869415e842c798ab6cd76329c1 100644 (file)
--- a/manifest
+++ b/manifest
@@ -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
index b39bfd65f92a3f65f28f3370d4f6ba8f96fa9acf..2e369faa1bebea65a231d4e3edcca5aeb94b8203 100644 (file)
@@ -1 +1 @@
-6d5ed70d0dbabe9c2ab2f2dba47747d17d937781
\ No newline at end of file
+1cb675e5392f179516d8e7a52760922a6c7df4d0
\ No newline at end of file