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.1.1.1 2012/02/21 17:04:16 misho 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
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>