blob: 56055810c8050c9c41a1ce3c636517ad5db50ac8 [file] [log] [blame]
danielk197707cb5602006-01-20 10:55:05 +00001# 2005 December 30
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# The focus of the tests in this file are IO errors that occur in a shared
13# cache context. What happens to connection B if one connection A encounters
14# an IO-error whilst reading or writing the file-system?
15#
drh77a2a5e2007-04-06 01:04:39 +000016# $Id: shared_err.test,v 1.11 2007/04/06 01:04:40 drh Exp $
danielk197707cb5602006-01-20 10:55:05 +000017
18proc skip {args} {}
19
20
21set testdir [file dirname $argv0]
22source $testdir/tester.tcl
23db close
24
25ifcapable !shared_cache||!subquery {
26 finish_test
27 return
28}
29set ::enable_shared_cache [sqlite3_enable_shared_cache 1]
30
danielk1977c4da5b92006-01-21 12:08:54 +000031# Todo: This is a copy of the [do_malloc_test] proc in malloc.test
32# It would be better if these were consolidated.
33
34# Usage: do_malloc_test <test number> <options...>
35#
36# The first argument, <test number>, is an integer used to name the
37# tests executed by this proc. Options are as follows:
38#
39# -tclprep TCL script to run to prepare test.
40# -sqlprep SQL script to run to prepare test.
41# -tclbody TCL script to run with malloc failure simulation.
42# -sqlbody TCL script to run with malloc failure simulation.
43# -cleanup TCL script to run after the test.
44#
45# This command runs a series of tests to verify SQLite's ability
46# to handle an out-of-memory condition gracefully. It is assumed
47# that if this condition occurs a malloc() call will return a
48# NULL pointer. Linux, for example, doesn't do that by default. See
49# the "BUGS" section of malloc(3).
50#
51# Each iteration of a loop, the TCL commands in any argument passed
52# to the -tclbody switch, followed by the SQL commands in any argument
53# passed to the -sqlbody switch are executed. Each iteration the
54# Nth call to sqliteMalloc() is made to fail, where N is increased
55# each time the loop runs starting from 1. When all commands execute
56# successfully, the loop ends.
57#
58proc do_malloc_test {tn args} {
59 array unset ::mallocopts
60 array set ::mallocopts $args
61
62 set ::go 1
63 for {set ::n 1} {$::go && $::n < 50000} {incr ::n} {
64 do_test shared_malloc-$tn.$::n {
65
66 # Remove all traces of database files test.db and test2.db from the files
67 # system. Then open (empty database) "test.db" with the handle [db].
68 #
69 sqlite_malloc_fail 0
70 catch {db close}
71 catch {file delete -force test.db}
72 catch {file delete -force test.db-journal}
73 catch {file delete -force test2.db}
74 catch {file delete -force test2.db-journal}
75 catch {sqlite3 db test.db}
76 set ::DB [sqlite3_connection_pointer db]
77
78 # Execute any -tclprep and -sqlprep scripts.
79 #
80 if {[info exists ::mallocopts(-tclprep)]} {
81 eval $::mallocopts(-tclprep)
82 }
83 if {[info exists ::mallocopts(-sqlprep)]} {
84 execsql $::mallocopts(-sqlprep)
85 }
86
87 # Now set the ${::n}th malloc() to fail and execute the -tclbody and
88 # -sqlbody scripts.
89 #
90 sqlite_malloc_fail $::n
91 set ::mallocbody {}
92 if {[info exists ::mallocopts(-tclbody)]} {
93 append ::mallocbody "$::mallocopts(-tclbody)\n"
94 }
95 if {[info exists ::mallocopts(-sqlbody)]} {
96 append ::mallocbody "db eval {$::mallocopts(-sqlbody)}"
97 }
98 set v [catch $::mallocbody msg]
99
100 set leftover [lindex [sqlite_malloc_stat] 2]
101 if {$leftover>0} {
102 if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"}
103 set ::go 0
104 if {$v} {
105 puts "\nError message returned: $msg"
106 } else {
107 set v {1 1}
108 }
109 } else {
110 set v2 [expr {$msg=="" || $msg=="out of memory"}]
111 if {!$v2} {puts "\nError message returned: $msg"}
112 lappend v $v2
113 }
114 } {1 1}
115
116 sqlite_malloc_fail 0
117 if {[info exists ::mallocopts(-cleanup)]} {
118 catch [list uplevel #0 $::mallocopts(-cleanup)] msg
119 }
120 }
121 unset ::mallocopts
122}
123
124
danielk197707cb5602006-01-20 10:55:05 +0000125do_ioerr_test shared_ioerr-1 -tclprep {
126 sqlite3 db2 test.db
127 execsql {
128 PRAGMA read_uncommitted = 1;
129 CREATE TABLE t1(a,b,c);
130 BEGIN;
131 SELECT * FROM sqlite_master;
132 } db2
133} -sqlbody {
134 SELECT * FROM sqlite_master;
135 INSERT INTO t1 VALUES(1,2,3);
136 BEGIN TRANSACTION;
137 INSERT INTO t1 VALUES(1,2,3);
138 INSERT INTO t1 VALUES(4,5,6);
139 ROLLBACK;
140 SELECT * FROM t1;
141 BEGIN TRANSACTION;
142 INSERT INTO t1 VALUES(1,2,3);
143 INSERT INTO t1 VALUES(4,5,6);
144 COMMIT;
145 SELECT * FROM t1;
146 DELETE FROM t1 WHERE a<100;
147} -cleanup {
danielk197797a227c2006-01-20 16:32:04 +0000148 do_test shared_ioerr-1.$n.cleanup.1 {
danielk197707cb5602006-01-20 10:55:05 +0000149 set res [catchsql {
150 SELECT * FROM t1;
151 } db2]
152 set possible_results [list \
153 "1 {disk I/O error}" \
154 "0 {1 2 3}" \
155 "0 {1 2 3 1 2 3 4 5 6}" \
156 "0 {1 2 3 1 2 3 4 5 6 1 2 3 4 5 6}" \
157 "0 {}" \
158 ]
159 set rc [expr [lsearch -exact $possible_results $res] >= 0]
160 if {$rc != 1} {
161 puts ""
162 puts "Result: $res"
163 }
164 set rc
165 } {1}
166 db2 close
167}
168
169do_ioerr_test shared_ioerr-2 -tclprep {
170 sqlite3 db2 test.db
171 execsql {
172 PRAGMA read_uncommitted = 1;
173 BEGIN;
174 CREATE TABLE t1(a, b);
175 INSERT INTO t1(oid) VALUES(NULL);
176 INSERT INTO t1(oid) SELECT NULL FROM t1;
177 INSERT INTO t1(oid) SELECT NULL FROM t1;
178 INSERT INTO t1(oid) SELECT NULL FROM t1;
179 INSERT INTO t1(oid) SELECT NULL FROM t1;
180 INSERT INTO t1(oid) SELECT NULL FROM t1;
181 INSERT INTO t1(oid) SELECT NULL FROM t1;
182 INSERT INTO t1(oid) SELECT NULL FROM t1;
183 INSERT INTO t1(oid) SELECT NULL FROM t1;
184 INSERT INTO t1(oid) SELECT NULL FROM t1;
185 INSERT INTO t1(oid) SELECT NULL FROM t1;
186 UPDATE t1 set a = oid, b = 'abcdefghijklmnopqrstuvwxyz0123456789';
187 CREATE INDEX i1 ON t1(a);
188 COMMIT;
189 BEGIN;
190 SELECT * FROM sqlite_master;
191 } db2
192} -tclbody {
193 set ::residx 0
194 execsql {DELETE FROM t1 WHERE 0 = (a % 2);}
195 incr ::residx
196
197 # When this transaction begins the table contains 512 entries. The
198 # two statements together add 512+146 more if it succeeds.
199 # (1024/7==146)
200 execsql {BEGIN;}
201 execsql {INSERT INTO t1 SELECT a+1, b FROM t1;}
202 execsql {INSERT INTO t1 SELECT 'string' || a, b FROM t1 WHERE 0 = (a%7);}
203 execsql {COMMIT;}
204
205 incr ::residx
206} -cleanup {
207 do_test shared_ioerr-2.$n.cleanup.1 {
208 set res [catchsql {
209 SELECT max(a), min(a), count(*) FROM (SELECT a FROM t1 order by a);
210 } db2]
211 set possible_results [list \
212 {0 {1024 1 1024}} \
213 {0 {1023 1 512}} \
214 {0 {string994 1 1170}} \
215 ]
216 set idx [lsearch -exact $possible_results $res]
217 set success [expr {$idx==$::residx || $res=="1 {disk I/O error}"}]
218 if {!$success} {
219 puts ""
220 puts "Result: \"$res\" ($::residx)"
221 }
222 set success
223 } {1}
224 db2 close
225}
226
danielk197797a227c2006-01-20 16:32:04 +0000227# This test is designed to provoke an IO error when a cursor position is
228# "saved" (because another cursor is going to modify the underlying table).
229#
230do_ioerr_test shared_ioerr-3 -tclprep {
231 sqlite3 db2 test.db
232 execsql {
233 PRAGMA read_uncommitted = 1;
danielk1977c4da5b92006-01-21 12:08:54 +0000234 PRAGMA cache_size = 10;
235 BEGIN;
236 CREATE TABLE t1(a, b, UNIQUE(a, b));
237 } db2
238 for {set i 0} {$i < 200} {incr i} {
239 set a [string range [string repeat "[format %03d $i]." 5] 0 end-1]
240
241 set b [string repeat $i 2000]
242 execsql {INSERT INTO t1 VALUES($a, $b)} db2
243 }
244 execsql {COMMIT} db2
245 set ::DB2 [sqlite3_connection_pointer db2]
246 set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY]
247 sqlite3_step $::STMT ;# Cursor points at 000.000.000.000
248 sqlite3_step $::STMT ;# Cursor points at 001.001.001.001
249
250} -tclbody {
251 execsql {
danielk197775bab7d2006-01-23 13:09:45 +0000252 BEGIN;
danielk1977c4da5b92006-01-21 12:08:54 +0000253 INSERT INTO t1 VALUES('201.201.201.201.201', NULL);
danielk197775bab7d2006-01-23 13:09:45 +0000254 UPDATE t1 SET a = '202.202.202.202.202' WHERE a LIKE '201%';
255 COMMIT;
danielk1977c4da5b92006-01-21 12:08:54 +0000256 }
257} -cleanup {
danielk1977b94bf852007-03-19 13:53:37 +0000258 set ::steprc [sqlite3_step $::STMT]
259 set ::column [sqlite3_column_text $::STMT 0]
260 set ::finalrc [sqlite3_finalize $::STMT]
261
262 # There are three possible outcomes here (assuming persistent IO errors):
263 #
264 # 1. If the [sqlite3_step] did not require any IO (required pages in
265 # the cache), then the next row ("002...") may be retrieved
266 # successfully.
267 #
268 # 2. If the [sqlite3_step] does require IO, then [sqlite3_step] returns
269 # SQLITE_ERROR and [sqlite3_finalize] returns IOERR.
270 #
271 # 3. If, after the initial IO error, SQLite tried to rollback the
272 # active transaction and a second IO error was encountered, then
273 # statement $::STMT will have been aborted. This means [sqlite3_stmt]
274 # returns SQLITE_ABORT, and the statement cursor does not move. i.e.
275 # [sqlite3_column] still returns the current row ("001...") and
276 # [sqlite3_finalize] returns SQLITE_OK.
277 #
278
danielk1977c4da5b92006-01-21 12:08:54 +0000279 do_test shared_ioerr-3.$n.cleanup.1 {
danielk1977b94bf852007-03-19 13:53:37 +0000280 expr {
281 $::steprc eq "SQLITE_ROW" ||
282 $::steprc eq "SQLITE_ERROR" ||
283 $::steprc eq "SQLITE_ABORT"
284 }
285 } {1}
danielk1977c4da5b92006-01-21 12:08:54 +0000286 do_test shared_ioerr-3.$n.cleanup.2 {
danielk1977b94bf852007-03-19 13:53:37 +0000287 expr {
288 ($::steprc eq "SQLITE_ROW" && $::column eq "002.002.002.002.002") ||
289 ($::steprc eq "SQLITE_ERROR" && $::column eq "") ||
290 ($::steprc eq "SQLITE_ABORT" && $::column eq "001.001.001.001.001")
291 }
292 } {1}
danielk1977c4da5b92006-01-21 12:08:54 +0000293 do_test shared_ioerr-3.$n.cleanup.3 {
danielk1977b94bf852007-03-19 13:53:37 +0000294 expr {
295 ($::steprc eq "SQLITE_ROW" && $::finalrc eq "SQLITE_OK") ||
296 ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_IOERR") ||
297 ($::steprc eq "SQLITE_ABORT" && $::finalrc eq "SQLITE_OK")
298 }
299 } {1}
300
danielk1977c4da5b92006-01-21 12:08:54 +0000301# db2 eval {select * from sqlite_master}
302 db2 close
303}
304
drh77a2a5e2007-04-06 01:04:39 +0000305# This is a repeat of the previous test except that this time we
306# are doing a reverse-order scan of the table when the cursor is
307# "saved".
308#
309do_ioerr_test shared_ioerr-3rev -tclprep {
310 sqlite3 db2 test.db
311 execsql {
312 PRAGMA read_uncommitted = 1;
313 PRAGMA cache_size = 10;
314 BEGIN;
315 CREATE TABLE t1(a, b, UNIQUE(a, b));
316 } db2
317 for {set i 0} {$i < 200} {incr i} {
318 set a [string range [string repeat "[format %03d $i]." 5] 0 end-1]
319
320 set b [string repeat $i 2000]
321 execsql {INSERT INTO t1 VALUES($a, $b)} db2
322 }
323 execsql {COMMIT} db2
324 set ::DB2 [sqlite3_connection_pointer db2]
325 set ::STMT [sqlite3_prepare $::DB2 \
326 "SELECT a FROM t1 ORDER BY a DESC" -1 DUMMY]
327 sqlite3_step $::STMT ;# Cursor points at 199.199.199.199.199
328 sqlite3_step $::STMT ;# Cursor points at 198.198.198.198.198
329
330} -tclbody {
331 execsql {
332 BEGIN;
333 INSERT INTO t1 VALUES('201.201.201.201.201', NULL);
334 UPDATE t1 SET a = '202.202.202.202.202' WHERE a LIKE '201%';
335 COMMIT;
336 }
337} -cleanup {
338 set ::steprc [sqlite3_step $::STMT]
339 set ::column [sqlite3_column_text $::STMT 0]
340 set ::finalrc [sqlite3_finalize $::STMT]
341
342 # There are three possible outcomes here (assuming persistent IO errors):
343 #
344 # 1. If the [sqlite3_step] did not require any IO (required pages in
345 # the cache), then the next row ("002...") may be retrieved
346 # successfully.
347 #
348 # 2. If the [sqlite3_step] does require IO, then [sqlite3_step] returns
349 # SQLITE_ERROR and [sqlite3_finalize] returns IOERR.
350 #
351 # 3. If, after the initial IO error, SQLite tried to rollback the
352 # active transaction and a second IO error was encountered, then
353 # statement $::STMT will have been aborted. This means [sqlite3_stmt]
354 # returns SQLITE_ABORT, and the statement cursor does not move. i.e.
355 # [sqlite3_column] still returns the current row ("001...") and
356 # [sqlite3_finalize] returns SQLITE_OK.
357 #
358
359 do_test shared_ioerr-3rev.$n.cleanup.1 {
360 expr {
361 $::steprc eq "SQLITE_ROW" ||
362 $::steprc eq "SQLITE_ERROR" ||
363 $::steprc eq "SQLITE_ABORT"
364 }
365 } {1}
366 do_test shared_ioerr-3rev.$n.cleanup.2 {
367 expr {
368 ($::steprc eq "SQLITE_ROW" && $::column eq "197.197.197.197.197") ||
369 ($::steprc eq "SQLITE_ERROR" && $::column eq "") ||
370 ($::steprc eq "SQLITE_ABORT" && $::column eq "198.198.198.198.198")
371 }
372 } {1}
373 do_test shared_ioerr-3rev.$n.cleanup.3 {
374 expr {
375 ($::steprc eq "SQLITE_ROW" && $::finalrc eq "SQLITE_OK") ||
376 ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_IOERR") ||
377 ($::steprc eq "SQLITE_ABORT" && $::finalrc eq "SQLITE_OK")
378 }
379 } {1}
380
381# db2 eval {select * from sqlite_master}
382 db2 close
383}
384
drh7b3822b2006-01-23 23:49:34 +0000385# Only run these tests if memory debugging is turned on.
386#
387if {[info command sqlite_malloc_stat]==""} {
388 puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..."
drh80d56822006-01-24 00:15:15 +0000389 db close
390 sqlite3_enable_shared_cache $::enable_shared_cache
drh7b3822b2006-01-23 23:49:34 +0000391 finish_test
392 return
393}
394
danielk1977c4da5b92006-01-21 12:08:54 +0000395# Provoke a malloc() failure when a cursor position is being saved. This
396# only happens with index cursors (because they malloc() space to save the
397# current key value). It does not happen with tables, because an integer
398# key does not require a malloc() to store.
399#
400# The library should return an SQLITE_NOMEM to the caller. The query that
401# owns the cursor (the one for which the position is not saved) should
402# continue unaffected.
403#
404do_malloc_test 4 -tclprep {
405 sqlite3 db2 test.db
406 execsql {
407 PRAGMA read_uncommitted = 1;
danielk197797a227c2006-01-20 16:32:04 +0000408 BEGIN;
409 CREATE TABLE t1(a, b, UNIQUE(a, b));
410 } db2
411 for {set i 0} {$i < 5} {incr i} {
412 set a [string repeat $i 10]
413 set b [string repeat $i 2000]
414 execsql {INSERT INTO t1 VALUES($a, $b)} db2
415 }
416 execsql {COMMIT} db2
417 set ::DB2 [sqlite3_connection_pointer db2]
418 set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY]
419 sqlite3_step $::STMT ;# Cursor points at 0000000000
420 sqlite3_step $::STMT ;# Cursor points at 1111111111
421} -tclbody {
422 execsql {
423 INSERT INTO t1 VALUES(6, NULL);
424 }
425} -cleanup {
danielk1977c4da5b92006-01-21 12:08:54 +0000426 do_test shared_malloc-4.$::n.cleanup.1 {
danielk19778d34dfd2006-01-24 16:37:57 +0000427 set ::rc [sqlite3_step $::STMT]
428 expr {$::rc=="SQLITE_ROW" || $::rc=="SQLITE_ABORT"}
429 } {1}
430 if {$::rc=="SQLITE_ROW"} {
431 do_test shared_malloc-4.$::n.cleanup.2 {
432 sqlite3_column_text $::STMT 0
433 } {2222222222}
434 }
danielk1977c4da5b92006-01-21 12:08:54 +0000435 do_test shared_malloc-4.$::n.cleanup.3 {
danielk197797a227c2006-01-20 16:32:04 +0000436 sqlite3_finalize $::STMT
437 } {SQLITE_OK}
438# db2 eval {select * from sqlite_master}
439 db2 close
440}
441
danielk19774b202ae2006-01-23 05:50:58 +0000442do_malloc_test 5 -tclbody {
443 sqlite3 dbX test.db
444 sqlite3 dbY test.db
445 dbX close
446 dbY close
447} -cleanup {
448 catch {dbX close}
449 catch {dbY close}
450}
451
danielk19777246f5b2006-01-24 11:30:27 +0000452do_malloc_test 6 -tclbody {
453 catch {db close}
454 sqlite3_thread_cleanup
455 sqlite3_enable_shared_cache 0
456} -cleanup {
457 sqlite3_enable_shared_cache 1
458}
459
460do_test shared_misuse-7.1 {
461 sqlite3 db test.db
462 catch {
463 sqlite3_enable_shared_cache 0
464 } msg
465 set msg
466} {library routine called out of sequence}
467
danielk19778d34dfd2006-01-24 16:37:57 +0000468# Again provoke a malloc() failure when a cursor position is being saved,
469# this time during a ROLLBACK operation by some other handle.
470#
471# The library should return an SQLITE_NOMEM to the caller. The query that
472# owns the cursor (the one for which the position is not saved) should
473# be aborted.
474#
475set ::aborted 0
476do_malloc_test 8 -tclprep {
477 sqlite3 db2 test.db
478 execsql {
479 PRAGMA read_uncommitted = 1;
480 BEGIN;
481 CREATE TABLE t1(a, b, UNIQUE(a, b));
482 } db2
483 for {set i 0} {$i < 2} {incr i} {
484 set a [string repeat $i 10]
485 set b [string repeat $i 2000]
486 execsql {INSERT INTO t1 VALUES($a, $b)} db2
487 }
488 execsql {COMMIT} db2
489 set ::DB2 [sqlite3_connection_pointer db2]
490 set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY]
491 sqlite3_step $::STMT ;# Cursor points at 0000000000
492 sqlite3_step $::STMT ;# Cursor points at 1111111111
493} -tclbody {
494 execsql {
495 BEGIN;
496 INSERT INTO t1 VALUES(6, NULL);
497 ROLLBACK;
498 }
499} -cleanup {
500 do_test shared_malloc-8.$::n.cleanup.1 {
501 lrange [execsql {
502 SELECT a FROM t1;
503 } db2] 0 1
504 } {0000000000 1111111111}
505 do_test shared_malloc-8.$::n.cleanup.2 {
506 set rc1 [sqlite3_step $::STMT]
507 set rc2 [sqlite3_finalize $::STMT]
508 if {$rc1=="SQLITE_ABORT"} {
509 incr ::aborted
510 }
511 expr {
512 ($rc1=="SQLITE_DONE" && $rc2=="SQLITE_OK") ||
513 ($rc1=="SQLITE_ABORT" && $rc2=="SQLITE_OK")
514 }
515 } {1}
516 db2 close
517}
518do_test shared_malloc-8.X {
519 # Test that one or more queries were aborted due to the malloc() failure.
520 expr $::aborted>=1
521} {1}
522
danielk197707cb5602006-01-20 10:55:05 +0000523catch {db close}
524sqlite3_enable_shared_cache $::enable_shared_cache
525finish_test