Merge sqlite-release(3.43.1) into prerelease-integration
[sqlcipher.git] / test / crash4.test
blobf68caecdef3eeb4252907264201666a8ccd83388
1 # 2008 January 8
3 # The author disclaims copyright to this source code.  In place of
4 # a legal notice, here is a blessing:
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.
10 #***********************************************************************
12 # This file contains additional tests to verify that SQLite database
13 # file survive a power loss or OS crash.
15 # $Id: crash4.test,v 1.3 2008/01/16 17:46:38 drh Exp $
17 set testdir [file dirname $argv0]
18 source $testdir/tester.tcl
20 ifcapable !crashtest {
21   finish_test
22   return
26 # A sequence of SQL commands:
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}
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.
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]
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.  
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.
64 for {set cnt 1; set fin 0} {!$fin} {incr cnt} {
65   db close
66   forcedelete 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}
102 finish_test