Home | History | Annotate | Download | only in test
      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
    103