OLD | NEW |
| (Empty) |
1 # 2010 February 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 # This file implements regression tests for SQLite library. The | |
12 # focus of this file is testing the operation of the library when | |
13 # recovering a database following a simulated system failure in | |
14 # "PRAGMA journal_mode=WAL" mode. | |
15 # | |
16 | |
17 # | |
18 # These are 'warm-body' tests of database recovery used while developing | |
19 # the WAL code. They serve to prove that a few really simple cases work: | |
20 # | |
21 # walcrash-1.*: Recover a database. | |
22 # walcrash-2.*: Recover a database where the failed transaction spanned more | |
23 # than one page. | |
24 # walcrash-3.*: Recover multiple databases where the failed transaction | |
25 # was a multi-file transaction. | |
26 # | |
27 | |
28 set testdir [file dirname $argv0] | |
29 source $testdir/tester.tcl | |
30 ifcapable !wal {finish_test ; return } | |
31 | |
32 db close | |
33 | |
34 set seed 0 | |
35 set REPEATS 100 | |
36 | |
37 # walcrash-1.* | |
38 # | |
39 for {set i 1} {$i < $REPEATS} {incr i} { | |
40 forcedelete test.db test.db-wal | |
41 do_test walcrash-1.$i.1 { | |
42 crashsql -delay 4 -file test.db-wal -seed [incr seed] { | |
43 PRAGMA journal_mode = WAL; | |
44 CREATE TABLE t1(a, b); | |
45 INSERT INTO t1 VALUES(1, 1); | |
46 INSERT INTO t1 VALUES(2, 3); | |
47 INSERT INTO t1 VALUES(3, 6); | |
48 } | |
49 } {1 {child process exited abnormally}} | |
50 do_test walcrash-1.$i.2 { | |
51 sqlite3 db test.db | |
52 execsql { SELECT sum(a)==max(b) FROM t1 } | |
53 } {1} | |
54 integrity_check walcrash-1.$i.3 | |
55 db close | |
56 | |
57 do_test walcrash-1.$i.4 { | |
58 crashsql -delay 2 -file test.db-wal -seed [incr seed] { | |
59 INSERT INTO t1 VALUES(4, (SELECT sum(a) FROM t1) + 4); | |
60 INSERT INTO t1 VALUES(5, (SELECT sum(a) FROM t1) + 5); | |
61 } | |
62 } {1 {child process exited abnormally}} | |
63 do_test walcrash-1.$i.5 { | |
64 sqlite3 db test.db | |
65 execsql { SELECT sum(a)==max(b) FROM t1 } | |
66 } {1} | |
67 integrity_check walcrash-1.$i.6 | |
68 do_test walcrash-1.$i.7 { | |
69 execsql { PRAGMA main.journal_mode } | |
70 } {wal} | |
71 db close | |
72 } | |
73 | |
74 # walcrash-2.* | |
75 # | |
76 for {set i 1} {$i < $REPEATS} {incr i} { | |
77 forcedelete test.db test.db-wal | |
78 do_test walcrash-2.$i.1 { | |
79 crashsql -delay 5 -file test.db-wal -seed [incr seed] { | |
80 PRAGMA journal_mode = WAL; | |
81 CREATE TABLE t1(a PRIMARY KEY, b); | |
82 INSERT INTO t1 VALUES(1, 2); | |
83 INSERT INTO t1 VALUES(3, 4); | |
84 INSERT INTO t1 VALUES(5, 9); | |
85 } | |
86 } {1 {child process exited abnormally}} | |
87 do_test walcrash-2.$i.2 { | |
88 sqlite3 db test.db | |
89 execsql { SELECT sum(a)==max(b) FROM t1 } | |
90 } {1} | |
91 integrity_check walcrash-2.$i.3 | |
92 db close | |
93 | |
94 do_test walcrash-2.$i.4 { | |
95 crashsql -delay 2 -file test.db-wal -seed [incr seed] { | |
96 INSERT INTO t1 VALUES(6, (SELECT sum(a) FROM t1) + 6); | |
97 INSERT INTO t1 VALUES(7, (SELECT sum(a) FROM t1) + 7); | |
98 } | |
99 } {1 {child process exited abnormally}} | |
100 do_test walcrash-2.$i.5 { | |
101 sqlite3 db test.db | |
102 execsql { SELECT sum(a)==max(b) FROM t1 } | |
103 } {1} | |
104 integrity_check walcrash-2.$i.6 | |
105 do_test walcrash-2.$i.6 { | |
106 execsql { PRAGMA main.journal_mode } | |
107 } {wal} | |
108 db close | |
109 } | |
110 | |
111 # walcrash-3.* | |
112 # | |
113 # for {set i 1} {$i < $REPEATS} {incr i} { | |
114 # forcedelete test.db test.db-wal | |
115 # forcedelete test2.db test2.db-wal | |
116 # | |
117 # do_test walcrash-3.$i.1 { | |
118 # crashsql -delay 2 -file test2.db-wal -seed [incr seed] { | |
119 # PRAGMA journal_mode = WAL; | |
120 # ATTACH 'test2.db' AS aux; | |
121 # CREATE TABLE t1(a PRIMARY KEY, b); | |
122 # CREATE TABLE aux.t2(a PRIMARY KEY, b); | |
123 # BEGIN; | |
124 # INSERT INTO t1 VALUES(1, 2); | |
125 # INSERT INTO t2 VALUES(1, 2); | |
126 # COMMIT; | |
127 # } | |
128 # } {1 {child process exited abnormally}} | |
129 # | |
130 # do_test walcrash-3.$i.2 { | |
131 # sqlite3_wal db test.db | |
132 # execsql { | |
133 # ATTACH 'test2.db' AS aux; | |
134 # SELECT * FROM t1 EXCEPT SELECT * FROM t2; | |
135 # } | |
136 # } {} | |
137 # do_test walcrash-3.$i.3 { execsql { PRAGMA main.integrity_check } } {ok} | |
138 # do_test walcrash-3.$i.4 { execsql { PRAGMA aux.integrity_check } } {ok} | |
139 # | |
140 # db close | |
141 # } | |
142 | |
143 # walcrash-4.* | |
144 # | |
145 for {set i 1} {$i < $REPEATS} {incr i} { | |
146 forcedelete test.db test.db-wal | |
147 forcedelete test2.db test2.db-wal | |
148 | |
149 do_test walcrash-4.$i.1 { | |
150 crashsql -delay 4 -file test.db-wal -seed [incr seed] -blocksize 4096 { | |
151 PRAGMA journal_mode = WAL; | |
152 PRAGMA page_size = 1024; | |
153 CREATE TABLE t1(a PRIMARY KEY, b); | |
154 INSERT INTO t1 VALUES(1, 2); | |
155 INSERT INTO t1 VALUES(3, 4); | |
156 } | |
157 } {1 {child process exited abnormally}} | |
158 | |
159 do_test walcrash-4.$i.2 { | |
160 sqlite3 db test.db | |
161 execsql { | |
162 SELECT * FROM t1 WHERE a = 1; | |
163 } | |
164 } {1 2} | |
165 do_test walcrash-4.$i.3 { execsql { PRAGMA main.integrity_check } } {ok} | |
166 do_test walcrash-4.$i.4 { execsql { PRAGMA main.journal_mode } } {wal} | |
167 | |
168 db close | |
169 } | |
170 | |
171 # walcrash-5.* | |
172 # | |
173 for {set i 1} {$i < $REPEATS} {incr i} { | |
174 forcedelete test.db test.db-wal | |
175 forcedelete test2.db test2.db-wal | |
176 | |
177 do_test walcrash-5.$i.1 { | |
178 crashsql -delay 13 -file test.db-wal -seed [incr seed] -blocksize 4096 { | |
179 PRAGMA journal_mode = WAL; | |
180 PRAGMA page_size = 1024; | |
181 BEGIN; | |
182 CREATE TABLE t1(x PRIMARY KEY); | |
183 INSERT INTO t1 VALUES(randomblob(900)); | |
184 INSERT INTO t1 VALUES(randomblob(900)); | |
185 INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 4 */ | |
186 COMMIT; | |
187 INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4; /* 8 */ | |
188 INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4; /* 12 */ | |
189 INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4; /* 16 */ | |
190 INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4; /* 20 */ | |
191 INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4; /* 24 */ | |
192 INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4; /* 28 */ | |
193 INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4; /* 32 */ | |
194 | |
195 PRAGMA wal_checkpoint; | |
196 INSERT INTO t1 VALUES(randomblob(900)); | |
197 INSERT INTO t1 VALUES(randomblob(900)); | |
198 INSERT INTO t1 VALUES(randomblob(900)); | |
199 } | |
200 } {1 {child process exited abnormally}} | |
201 | |
202 do_test walcrash-5.$i.2 { | |
203 sqlite3 db test.db | |
204 execsql { SELECT count(*)==33 OR count(*)==34 FROM t1 WHERE x != 1 } | |
205 } {1} | |
206 do_test walcrash-5.$i.3 { execsql { PRAGMA main.integrity_check } } {ok} | |
207 do_test walcrash-5.$i.4 { execsql { PRAGMA main.journal_mode } } {wal} | |
208 | |
209 db close | |
210 } | |
211 | |
212 # walcrash-6.* | |
213 # | |
214 for {set i 1} {$i < $REPEATS} {incr i} { | |
215 forcedelete test.db test.db-wal | |
216 forcedelete test2.db test2.db-wal | |
217 | |
218 do_test walcrash-6.$i.1 { | |
219 crashsql -delay 14 -file test.db-wal -seed [incr seed] -blocksize 512 { | |
220 PRAGMA journal_mode = WAL; | |
221 PRAGMA page_size = 1024; | |
222 BEGIN; | |
223 CREATE TABLE t1(x PRIMARY KEY); | |
224 INSERT INTO t1 VALUES(randomblob(900)); | |
225 INSERT INTO t1 VALUES(randomblob(900)); | |
226 INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 4 */ | |
227 COMMIT; | |
228 INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4; /* 8 */ | |
229 INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4; /* 12 */ | |
230 INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4; /* 16 */ | |
231 INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4; /* 20 */ | |
232 INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4; /* 24 */ | |
233 INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4; /* 28 */ | |
234 INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4; /* 32 */ | |
235 | |
236 PRAGMA wal_checkpoint; | |
237 INSERT INTO t1 VALUES(randomblob(9000)); | |
238 INSERT INTO t1 VALUES(randomblob(9000)); | |
239 INSERT INTO t1 VALUES(randomblob(9000)); | |
240 } | |
241 } {1 {child process exited abnormally}} | |
242 | |
243 do_test walcrash-6.$i.2 { | |
244 sqlite3 db test.db | |
245 execsql { SELECT count(*)==34 OR count(*)==35 FROM t1 WHERE x != 1 } | |
246 } {1} | |
247 do_test walcrash-6.$i.3 { execsql { PRAGMA main.integrity_check } } {ok} | |
248 do_test walcrash-6.$i.4 { execsql { PRAGMA main.journal_mode } } {wal} | |
249 | |
250 db close | |
251 } | |
252 | |
253 #------------------------------------------------------------------------- | |
254 # This test case simulates a crash while checkpointing the database. Page | |
255 # 1 is one of the pages overwritten by the checkpoint. This is a special | |
256 # case because it means the content of page 1 may be damaged. SQLite will | |
257 # have to determine: | |
258 # | |
259 # (a) that the database is a WAL database, and | |
260 # (b) the database page-size | |
261 # | |
262 # based on the log file. | |
263 # | |
264 for {set i 1} {$i < $REPEATS} {incr i} { | |
265 forcedelete test.db test.db-wal | |
266 | |
267 # Select a page-size for this test. | |
268 # | |
269 set pgsz [lindex {512 1024 2048 4096 8192 16384} [expr $i%6]] | |
270 | |
271 do_test walcrash-7.$i.1 { | |
272 crashsql -delay 3 -file test.db -seed [incr seed] -blocksize 512 " | |
273 PRAGMA page_size = $pgsz; | |
274 PRAGMA journal_mode = wal; | |
275 BEGIN; | |
276 CREATE TABLE t1(a, b); | |
277 INSERT INTO t1 VALUES(1, 2); | |
278 COMMIT; | |
279 PRAGMA wal_checkpoint; | |
280 CREATE INDEX i1 ON t1(a); | |
281 PRAGMA wal_checkpoint; | |
282 " | |
283 } {1 {child process exited abnormally}} | |
284 | |
285 do_test walcrash-7.$i.2 { | |
286 sqlite3 db test.db | |
287 execsql { SELECT b FROM t1 WHERE a = 1 } | |
288 } {2} | |
289 do_test walcrash-7.$i.3 { execsql { PRAGMA main.integrity_check } } {ok} | |
290 do_test walcrash-7.$i.4 { execsql { PRAGMA main.journal_mode } } {wal} | |
291 | |
292 db close | |
293 } | |
294 | |
295 finish_test | |
OLD | NEW |