| OLD | NEW | 
 | (Empty) | 
|    1 # 2008 January 8 |  | 
|    2 # |  | 
|    3 # The author disclaims copyright to this source code.  In place of |  | 
|    4 # a legal notice, here is a blessing: |  | 
|    5 # |  | 
|    6 #    May you do good and not evil. |  | 
|    7 #    May you find forgiveness for yourself and forgive others. |  | 
|    8 #    May you share freely, never taking more than you give. |  | 
|    9 # |  | 
|   10 #*********************************************************************** |  | 
|   11 # |  | 
|   12 # This file contains additional tests to verify that SQLite database |  | 
|   13 # file survive a power loss or OS crash. |  | 
|   14 # |  | 
|   15 # $Id: crash4.test,v 1.3 2008/01/16 17:46:38 drh Exp $ |  | 
|   16  |  | 
|   17 set testdir [file dirname $argv0] |  | 
|   18 source $testdir/tester.tcl |  | 
|   19  |  | 
|   20 ifcapable !crashtest { |  | 
|   21   finish_test |  | 
|   22   return |  | 
|   23 } |  | 
|   24  |  | 
|   25  |  | 
|   26 # A sequence of SQL commands: |  | 
|   27 # |  | 
|   28 set sql_cmd_list { |  | 
|   29   {CREATE TABLE a(id INTEGER, name CHAR(50))} |  | 
|   30   {INSERT INTO a(id,name) VALUES(1,'one')} |  | 
|   31   {INSERT INTO a(id,name) VALUES(2,'two')} |  | 
|   32   {INSERT INTO a(id,name) VALUES(3,'three')} |  | 
|   33   {INSERT INTO a(id,name) VALUES(4,'four')} |  | 
|   34   {INSERT INTO a(id,name) VALUES(5,'five')} |  | 
|   35   {INSERT INTO a(id,name) VALUES(6,'six')} |  | 
|   36   {INSERT INTO a(id,name) VALUES(7,'seven')} |  | 
|   37   {INSERT INTO a(id,name) VALUES(8,'eight')} |  | 
|   38   {INSERT INTO a(id,name) VALUES(9,'nine')} |  | 
|   39   {INSERT INTO a(id,name) VALUES(10,'ten')} |  | 
|   40   {UPDATE A SET name='new text for row 3' WHERE id=3} |  | 
|   41 } |  | 
|   42  |  | 
|   43 # Assume that a database is created by evaluating the SQL statements |  | 
|   44 # in $sql_cmd_list.  Compute a set of checksums that capture the state |  | 
|   45 # of the database after each statement.  Also include a checksum for |  | 
|   46 # the state of the database prior to any of these statements. |  | 
|   47 # |  | 
|   48 set crash4_cksum_set {} |  | 
|   49 lappend crash4_cksum_set [allcksum db] |  | 
|   50 foreach cmd $sql_cmd_list { |  | 
|   51   db eval $cmd |  | 
|   52   lappend crash4_cksum_set [allcksum db] |  | 
|   53 } |  | 
|   54  |  | 
|   55 # Run the sequence of SQL statements shown above repeatedly. |  | 
|   56 # Close and reopen the database right before the UPDATE statement. |  | 
|   57 # On each repetition, introduce database corruption typical of |  | 
|   58 # what might be seen in a power loss or OS crash.   |  | 
|   59 # |  | 
|   60 # Slowly increase the delay before the crash, repeating the test |  | 
|   61 # over and over.  Stop testing when the entire sequence of SQL |  | 
|   62 # statements runs to completing without hitting the crash. |  | 
|   63 # |  | 
|   64 for {set cnt 1; set fin 0} {!$fin} {incr cnt} { |  | 
|   65   db close |  | 
|   66   file delete -force test.db test.db-journal |  | 
|   67   do_test crash4-1.$cnt.1 { |  | 
|   68     set seed [expr {int(abs(rand()*10000))}] |  | 
|   69     set delay [expr {int($cnt/50)+1}] |  | 
|   70     set file [expr {($cnt&1)?"test.db":"test.db-journal"}] |  | 
|   71     set c [crashsql -delay $delay -file $file -seed $seed -tclbody { |  | 
|   72       db eval {CREATE TABLE a(id INTEGER, name CHAR(50))} |  | 
|   73       db eval {INSERT INTO a(id,name) VALUES(1,'one')} |  | 
|   74       db eval {INSERT INTO a(id,name) VALUES(2,'two')} |  | 
|   75       db eval {INSERT INTO a(id,name) VALUES(3,'three')} |  | 
|   76       db eval {INSERT INTO a(id,name) VALUES(4,'four')} |  | 
|   77       db eval {INSERT INTO a(id,name) VALUES(5,'five')} |  | 
|   78       db eval {INSERT INTO a(id,name) VALUES(6,'six')} |  | 
|   79       db eval {INSERT INTO a(id,name) VALUES(7,'seven')} |  | 
|   80       db eval {INSERT INTO a(id,name) VALUES(8,'eight')} |  | 
|   81       db eval {INSERT INTO a(id,name) VALUES(9,'nine')} |  | 
|   82       db eval {INSERT INTO a(id,name) VALUES(10,'ten')} |  | 
|   83       db close |  | 
|   84       sqlite3 db test.db |  | 
|   85       db eval {UPDATE A SET name='new text for row 3' WHERE id=3} |  | 
|   86       db close |  | 
|   87     } {}] |  | 
|   88     if {$c==[list 0 {}]} { |  | 
|   89       set ::fin 1 |  | 
|   90       set c [list 1 {child process exited abnormally}] |  | 
|   91     } |  | 
|   92     set c |  | 
|   93   } {1 {child process exited abnormally}} |  | 
|   94   sqlite3 db test.db |  | 
|   95   integrity_check crash4-1.$cnt.2 |  | 
|   96   do_test crash4-1.$cnt.3 { |  | 
|   97     set x [lsearch $::crash4_cksum_set [allcksum db]] |  | 
|   98     expr {$x>=0} |  | 
|   99   } {1} |  | 
|  100 } |  | 
|  101  |  | 
|  102 finish_test |  | 
| OLD | NEW |