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 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} | |
100 } | |
101 | |
102 finish_test | |
OLD | NEW |