OLD | NEW |
| (Empty) |
1 # 2007 August 23 | |
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 tests that verify that SQLite can correctly rollback | |
13 # databases after crashes when using the special IO modes triggered | |
14 # by device IOCAP flags. | |
15 # | |
16 # $Id: crash3.test,v 1.4 2008/07/12 14:52:20 drh Exp $ | |
17 | |
18 set testdir [file dirname $argv0] | |
19 source $testdir/tester.tcl | |
20 | |
21 ifcapable !crashtest { | |
22 finish_test | |
23 return | |
24 } | |
25 | |
26 proc do_test2 {name tcl res1 res2} { | |
27 set script [subst -nocommands { | |
28 do_test $name { | |
29 set res1 {$res1} | |
30 set res2 {$res2} | |
31 set res [eval {$tcl}] | |
32 if {[set res] eq [set res1] || [set res] eq [set res2]} { | |
33 set res "{[set res1]} or {[set res2]}" | |
34 } | |
35 set res | |
36 } {{$res1} or {$res2}} | |
37 }] | |
38 uplevel $script | |
39 } | |
40 | |
41 # This block tests crash-recovery when the IOCAP_ATOMIC flags is set. | |
42 # | |
43 # Each iteration of the following loop sets up the database to contain | |
44 # the following schema and data: | |
45 # | |
46 # CREATE TABLE abc(a, b, c); | |
47 # INSERT INTO abc VALUES(1, 2, 3); | |
48 # | |
49 # Then execute the SQL statement, scheduling a crash for part-way through | |
50 # the first sync() of either the database file or the journal file (often | |
51 # the journal file is not required - meaning no crash occurs). | |
52 # | |
53 # After the crash (or absence of a crash), open the database and | |
54 # verify that: | |
55 # | |
56 # * The integrity check passes, and | |
57 # * The contents of table abc is either {1 2 3} or the value specified | |
58 # to the right of the SQL statement below. | |
59 # | |
60 # The procedure is repeated 10 times for each SQL statement. Five times | |
61 # with the crash scheduled for midway through the first journal sync (if | |
62 # any), and five times with the crash midway through the database sync. | |
63 # | |
64 set tn 1 | |
65 foreach {sql res2} [list \ | |
66 {INSERT INTO abc VALUES(4, 5, 6)} {1 2 3 4 5 6} \ | |
67 {DELETE FROM abc} {} \ | |
68 {INSERT INTO abc SELECT * FROM abc} {1 2 3 1 2 3} \ | |
69 {UPDATE abc SET a = 2} {2 2 3} \ | |
70 {INSERT INTO abc VALUES(4, 5, randstr(1000,1000))} {n/a} \ | |
71 {CREATE TABLE def(d, e, f)} {n/a} \ | |
72 ] { | |
73 for {set ii 0} {$ii < 10} {incr ii} { | |
74 | |
75 db close | |
76 forcedelete test.db test.db-journal | |
77 sqlite3 db test.db | |
78 do_test crash3-1.$tn.1 { | |
79 execsql { | |
80 PRAGMA page_size = 1024; | |
81 BEGIN; | |
82 CREATE TABLE abc(a, b, c); | |
83 INSERT INTO abc VALUES(1, 2, 3); | |
84 COMMIT; | |
85 } | |
86 } {} | |
87 db close | |
88 | |
89 set crashfile test.db | |
90 if {($ii%2)==0} { append crashfile -journal } | |
91 set rand "SELECT randstr($tn,$tn);" | |
92 do_test crash3-1.$tn.2 [subst { | |
93 crashsql -file $crashfile -char atomic {$rand $sql} | |
94 sqlite3 db test.db | |
95 execsql { PRAGMA integrity_check; } | |
96 }] {ok} | |
97 | |
98 do_test2 crash3-1.$tn.3 { | |
99 execsql { SELECT * FROM abc } | |
100 } {1 2 3} $res2 | |
101 | |
102 incr tn | |
103 } | |
104 } | |
105 | |
106 # This block tests both the IOCAP_SEQUENTIAL and IOCAP_SAFE_APPEND flags. | |
107 # | |
108 db close | |
109 forcedelete test.db test.db-journal | |
110 sqlite3 db test.db | |
111 do_test crash3-2.0 { | |
112 execsql { | |
113 BEGIN; | |
114 CREATE TABLE abc(a PRIMARY KEY, b, c); | |
115 CREATE TABLE def(d PRIMARY KEY, e, f); | |
116 PRAGMA default_cache_size = 10; | |
117 INSERT INTO abc VALUES(randstr(10,1000),randstr(10,1000),randstr(10,1000)); | |
118 INSERT INTO abc | |
119 SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc; | |
120 INSERT INTO abc | |
121 SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc; | |
122 INSERT INTO abc | |
123 SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc; | |
124 INSERT INTO abc | |
125 SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc; | |
126 INSERT INTO abc | |
127 SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc; | |
128 INSERT INTO abc | |
129 SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc; | |
130 COMMIT; | |
131 } | |
132 } {} | |
133 | |
134 set tn 1 | |
135 foreach {::crashfile ::delay ::char} { | |
136 test.db 1 sequential | |
137 test.db 1 safe_append | |
138 test.db-journal 1 sequential | |
139 test.db-journal 1 safe_append | |
140 test.db-journal 2 safe_append | |
141 test.db-journal 2 sequential | |
142 test.db-journal 3 sequential | |
143 test.db-journal 3 safe_append | |
144 } { | |
145 for {set ii 0} {$ii < 100} {incr ii} { | |
146 set ::SQL [subst { | |
147 SELECT randstr($ii,$ii+10); | |
148 BEGIN; | |
149 DELETE FROM abc WHERE random()%5; | |
150 INSERT INTO abc | |
151 SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) | |
152 FROM abc | |
153 WHERE (random()%5)==0; | |
154 DELETE FROM def WHERE random()%5; | |
155 INSERT INTO def | |
156 SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) | |
157 FROM def | |
158 WHERE (random()%5)==0; | |
159 COMMIT; | |
160 }] | |
161 | |
162 do_test crash3-2.$tn.$ii { | |
163 crashsql -file $::crashfile -delay $::delay -char $::char $::SQL | |
164 db close | |
165 sqlite3 db test.db | |
166 execsql {PRAGMA integrity_check} | |
167 } {ok} | |
168 } | |
169 incr tn | |
170 } | |
171 | |
172 # The following block tests an interaction between IOCAP_ATOMIC and | |
173 # IOCAP_SEQUENTIAL. At one point, if both flags were set, small | |
174 # journal files that contained only a single page, but were required | |
175 # for some other reason (i.e. nTrunk) were not being written to | |
176 # disk. | |
177 # | |
178 for {set ii 0} {$ii < 10} {incr ii} { | |
179 db close | |
180 forcedelete test.db test.db-journal | |
181 crashsql -file test.db -char {sequential atomic} { | |
182 CREATE TABLE abc(a, b, c); | |
183 } | |
184 sqlite3 db test.db | |
185 do_test crash3-3.$ii { | |
186 execsql {PRAGMA integrity_check} | |
187 } {ok} | |
188 } | |
189 | |
190 finish_test | |
OLD | NEW |