Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(347)

Side by Side Diff: third_party/sqlite/src/ext/session/sessionfault.test

Issue 2751253002: [sql] Import SQLite 3.17.0. (Closed)
Patch Set: also clang on Linux i386 Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # 2011 Mar 21
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 this file is testing the session module.
13 #
14
15 if {![info exists testdir]} {
16 set testdir [file join [file dirname [info script]] .. .. test]
17 }
18 source [file join [file dirname [info script]] session_common.tcl]
19 source $testdir/tester.tcl
20 ifcapable !session {finish_test; return}
21
22 set testprefix sessionfault
23
24 forcedelete test.db2
25 sqlite3 db2 test.db2
26 do_common_sql {
27 CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b));
28 INSERT INTO t1 VALUES(1, 2, 3);
29 INSERT INTO t1 VALUES(4, 5, 6);
30 }
31 faultsim_save_and_close
32 db2 close
33
34 #-------------------------------------------------------------------------
35 # Test OOM error handling when collecting and applying a simple changeset.
36 #
37 # Test 1.1 attaches tables individually by name to the session object.
38 # Whereas test 1.2 passes NULL to sqlite3session_attach() to attach all
39 # tables.
40 #
41 do_faultsim_test 1.1 -faults oom-* -prep {
42 catch {db2 close}
43 catch {db close}
44 faultsim_restore_and_reopen
45 sqlite3 db2 test.db2
46 } -body {
47 do_then_apply_sql {
48 INSERT INTO t1 VALUES('a string value', 8, 9);
49 UPDATE t1 SET c = 10 WHERE a = 1;
50 DELETE FROM t1 WHERE a = 4;
51 }
52 } -test {
53 faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
54 faultsim_integrity_check
55 if {$testrc==0} { compare_db db db2 }
56 }
57
58 do_faultsim_test 1.2 -faults oom-* -prep {
59 catch {db2 close}
60 catch {db close}
61 faultsim_restore_and_reopen
62 } -body {
63 sqlite3session S db main
64 S attach *
65 execsql {
66 INSERT INTO t1 VALUES('a string value', 8, 9);
67 UPDATE t1 SET c = 10 WHERE a = 1;
68 DELETE FROM t1 WHERE a = 4;
69 }
70 set ::changeset [S changeset]
71 set {} {}
72 } -test {
73 catch { S delete }
74 faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
75 faultsim_integrity_check
76 if {$testrc==0} {
77 proc xConflict {args} { return "OMIT" }
78 sqlite3 db2 test.db2
79 sqlite3changeset_apply db2 $::changeset xConflict
80 compare_db db db2
81 }
82 }
83
84 #-------------------------------------------------------------------------
85 # The following block of tests - 2.* - are designed to check
86 # the handling of faults in the sqlite3changeset_apply() function.
87 #
88 catch {db close}
89 catch {db2 close}
90 forcedelete test.db2 test.db
91 sqlite3 db2 test.db2
92 sqlite3 db test.db
93 do_common_sql {
94 CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b));
95 INSERT INTO t1 VALUES('apple', 'orange', 'pear');
96
97 CREATE TABLE t2(x PRIMARY KEY, y);
98 }
99 db2 close
100 faultsim_save_and_close
101
102
103 foreach {tn conflict_policy sql sql2} {
104 1 OMIT { INSERT INTO t1 VALUES('one text', 'two text', X'00ff00') } {}
105 2 OMIT { DELETE FROM t1 WHERE a = 'apple' } {}
106 3 OMIT { UPDATE t1 SET c = 'banana' WHERE b = 'orange' } {}
107 4 REPLACE { INSERT INTO t2 VALUES('keyvalue', 'value 1') } {
108 INSERT INTO t2 VALUES('keyvalue', 'value 2');
109 }
110 } {
111 proc xConflict args [list return $conflict_policy]
112
113 do_faultsim_test 2.$tn -faults oom-transient -prep {
114 catch {db2 close}
115 catch {db close}
116 faultsim_restore_and_reopen
117 set ::changeset [changeset_from_sql $::sql]
118 sqlite3 db2 test.db2
119 sqlite3_db_config_lookaside db2 0 0 0
120 execsql $::sql2 db2
121 } -body {
122 sqlite3changeset_apply db2 $::changeset xConflict
123 } -test {
124 faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
125 faultsim_integrity_check
126 if {$testrc==0} { compare_db db db2 }
127 }
128 }
129
130 #-------------------------------------------------------------------------
131 # This test case is designed so that a malloc() failure occurs while
132 # resizing the session object hash-table from 256 to 512 buckets. This
133 # is not an error, just a sub-optimal condition.
134 #
135 do_faultsim_test 3 -faults oom-* -prep {
136 catch {db2 close}
137 catch {db close}
138 faultsim_restore_and_reopen
139 sqlite3 db2 test.db2
140
141 sqlite3session S db main
142 S attach t1
143 execsql { BEGIN }
144 for {set i 0} {$i < 125} {incr i} {
145 execsql {INSERT INTO t1 VALUES(10+$i, 10+$i, 10+$i)}
146 }
147 } -body {
148 for {set i 125} {$i < 133} {incr i} {
149 execsql {INSERT INTO t1 VALUES(10+$i, 10+$i, 1-+$i)}
150 }
151 S changeset
152 set {} {}
153 } -test {
154 faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
155 if {$testrc==0} {
156 sqlite3changeset_apply db2 [S changeset] xConflict
157 compare_db db db2
158 }
159 catch { S delete }
160 faultsim_integrity_check
161 }
162
163 catch { db close }
164 catch { db2 close }
165 forcedelete test.db2 test.db
166 sqlite3 db2 test.db2
167 sqlite3 db test.db
168
169 proc xConflict {op tbl type args} {
170 if { $type=="CONFLICT" || $type=="DATA" } {
171 return "REPLACE"
172 }
173 return "OMIT"
174 }
175
176 do_test 4.0 {
177 execsql {
178 PRAGMA encoding = 'utf16';
179 CREATE TABLE t1(a PRIMARY KEY, b);
180 INSERT INTO t1 VALUES(5, 32);
181 }
182 execsql {
183 PRAGMA encoding = 'utf16';
184 CREATE TABLE t1(a PRIMARY KEY, b NOT NULL);
185 INSERT INTO t1 VALUES(1, 2);
186 INSERT INTO t1 VALUES(2, 4);
187 INSERT INTO t1 VALUES(4, 16);
188 } db2
189 } {}
190
191 faultsim_save_and_close
192 db2 close
193
194 do_faultsim_test 4 -faults oom-* -prep {
195 catch {db2 close}
196 catch {db close}
197 faultsim_restore_and_reopen
198 sqlite3 db2 test.db2
199 sqlite3session S db main
200 S attach t1
201 execsql {
202 INSERT INTO t1 VALUES(1, 45);
203 INSERT INTO t1 VALUES(2, 55);
204 INSERT INTO t1 VALUES(3, 55);
205 UPDATE t1 SET a = 4 WHERE a = 5;
206 }
207 } -body {
208 sqlite3changeset_apply db2 [S changeset] xConflict
209 } -test {
210 catch { S delete }
211 faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
212 if {$testrc==0} { compare_db db db2 }
213 }
214
215 #-------------------------------------------------------------------------
216 # This block of tests verifies that OOM faults in the
217 # sqlite3changeset_invert() function are handled correctly.
218 #
219 catch {db close}
220 catch {db2 close}
221 forcedelete test.db
222 sqlite3 db test.db
223 execsql {
224 CREATE TABLE t1(a, b, PRIMARY KEY(b));
225 CREATE TABLE t2(a PRIMARY KEY, b);
226 INSERT INTO t1 VALUES('string', 1);
227 INSERT INTO t1 VALUES(4, 2);
228 INSERT INTO t1 VALUES(X'FFAAFFAAFFAA', 3);
229 }
230 set changeset [changeset_from_sql {
231 INSERT INTO t1 VALUES('xxx', 'yyy');
232 DELETE FROM t1 WHERE a = 'string';
233 UPDATE t1 SET a = 20 WHERE b = 2;
234 }]
235 db close
236
237 do_faultsim_test 5.1 -faults oom* -body {
238 set ::inverse [sqlite3changeset_invert $::changeset]
239 set {} {}
240 } -test {
241 faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
242 if {$testrc==0} {
243 set x [list]
244 sqlite3session_foreach c $::inverse { lappend x $c }
245 foreach c {
246 {DELETE t1 0 .X {t xxx t yyy} {}}
247 {INSERT t1 0 .X {} {t string i 1}}
248 {UPDATE t1 0 .X {i 20 i 2} {i 4 {} {}}}
249 } { lappend y $c }
250 if {$x != $y} { error "changeset no good" }
251 }
252 }
253
254 catch {db close}
255 catch {db2 close}
256 forcedelete test.db
257 sqlite3 db test.db
258 execsql {
259 CREATE TABLE t2(a PRIMARY KEY, b);
260 INSERT INTO t2 VALUES(1, 'abc');
261 INSERT INTO t2 VALUES(2, 'def');
262 }
263 set changeset [changeset_from_sql {
264 UPDATE t2 SET b = (b || b || b || b);
265 UPDATE t2 SET b = (b || b || b || b);
266 UPDATE t2 SET b = (b || b || b || b);
267 UPDATE t2 SET b = (b || b || b || b);
268 }]
269 db close
270 set abc [string repeat abc 256]
271 set def [string repeat def 256]
272
273 do_faultsim_test 5.2 -faults oom-tra* -body {
274 set ::inverse [sqlite3changeset_invert $::changeset]
275 set {} {}
276 } -test {
277 faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
278 if {$testrc==0} {
279 set x [list]
280 sqlite3session_foreach c $::inverse { lappend x $c }
281 foreach c "
282 {UPDATE t2 0 X. {i 1 t $::abc} {{} {} t abc}}
283 {UPDATE t2 0 X. {i 2 t $::def} {{} {} t def}}
284 " { lappend y $c }
285 if {$x != $y} { error "changeset no good" }
286 }
287 }
288
289 catch {db close}
290 catch {db2 close}
291 forcedelete test.db
292 sqlite3 db test.db
293 set abc [string repeat abc 256]
294 set def [string repeat def 256]
295 execsql "
296 CREATE TABLE t2(a PRIMARY KEY, b);
297 INSERT INTO t2 VALUES(1, '$abc');
298 "
299 set changeset [changeset_from_sql "
300 INSERT INTO t2 VALUES(2, '$def');
301 DELETE FROM t2 WHERE a = 1;
302 "]
303 db close
304
305 do_faultsim_test 5.3 -faults oom-tra* -body {
306 set ::inverse [sqlite3changeset_invert $::changeset]
307 set {} {}
308 } -test {
309 faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
310 if {$testrc==0} {
311 set x [list]
312 sqlite3session_foreach c $::inverse { lappend x $c }
313 foreach c "
314 {INSERT t2 0 X. {} {i 1 t $::abc}}
315 {DELETE t2 0 X. {i 2 t $::def} {}}
316 " { lappend y $c }
317 if {$x != $y} { error "changeset no good" }
318 }
319 }
320
321 #-------------------------------------------------------------------------
322 # Test that OOM errors in sqlite3changeset_concat() are handled correctly.
323 #
324 catch {db close}
325 forcedelete test.db
326 sqlite3 db test.db
327 do_execsql_test 5.prep1 {
328 CREATE TABLE t1(a, b, PRIMARY KEY(b));
329 CREATE TABLE t2(a PRIMARY KEY, b);
330 INSERT INTO t1 VALUES('string', 1);
331 INSERT INTO t1 VALUES(4, 2);
332 INSERT INTO t1 VALUES(X'FFAAFFAAFFAA', 3);
333 }
334
335 do_test 6.prep2 {
336 sqlite3session M db main
337 M attach *
338 set ::c2 [changeset_from_sql {
339 INSERT INTO t2 VALUES(randomblob(1000), randomblob(1000));
340 INSERT INTO t2 VALUES('one', 'two');
341 INSERT INTO t2 VALUES(1, NULL);
342 UPDATE t1 SET a = 5 WHERE a = 2;
343 }]
344 set ::c1 [changeset_from_sql {
345 DELETE FROM t2 WHERE a = 1;
346 UPDATE t1 SET a = 4 WHERE a = 2;
347 INSERT INTO t2 VALUES('x', 'y');
348 }]
349 set ::total [changeset_to_list [M changeset]]
350 M delete
351 } {}
352
353 do_faultsim_test 6 -faults oom-* -body {
354 set ::result [sqlite3changeset_concat $::c1 $::c2]
355 set {} {}
356 } -test {
357 faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
358 if {$testrc==0} {
359 set v [changeset_to_list $::result]
360 if {$v != $::total} { error "result no good" }
361 }
362 }
363
364 faultsim_delete_and_reopen
365 do_execsql_test 7.prep1 {
366 CREATE TABLE t1(a, b, PRIMARY KEY(a));
367 }
368 faultsim_save_and_close
369
370 set res [list]
371 for {set ::i 0} {$::i < 480} {incr ::i 4} {
372 lappend res "INSERT t1 0 X. {} {i $::i i $::i}"
373 }
374 set res [lsort $res]
375 do_faultsim_test 7 -faults oom-transient -prep {
376 catch { S delete }
377 faultsim_restore_and_reopen
378 sqlite3session S db main
379 S attach *
380 } -body {
381 for {set ::i 0} {$::i < 480} {incr ::i 4} {
382 execsql {INSERT INTO t1 VALUES($::i, $::i)}
383 }
384 } -test {
385 faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
386 if {$testrc==0} {
387 set cres [list [catch {changeset_to_list [S changeset]} msg] $msg]
388 S delete
389 if {$cres != "1 SQLITE_NOMEM" && $cres != "0 {$::res}"} {
390 error "Expected {0 $::res} Got {$cres}"
391 }
392 } else {
393 catch { S changeset }
394 catch { S delete }
395 }
396 }
397
398 faultsim_delete_and_reopen
399 do_test 8.prep {
400 sqlite3session S db main
401 S attach *
402 execsql {
403 CREATE TABLE t1(a, b, PRIMARY KEY(a));
404 INSERT INTO t1 VALUES(1, 2);
405 INSERT INTO t1 VALUES(3, 4);
406 INSERT INTO t1 VALUES(5, 6);
407 }
408 set ::changeset [S changeset]
409 S delete
410 } {}
411
412 set expected [normalize_list {
413 {INSERT t1 0 X. {} {i 1 i 2}}
414 {INSERT t1 0 X. {} {i 3 i 4}}
415 {INSERT t1 0 X. {} {i 5 i 6}}
416 }]
417 do_faultsim_test 8.1 -faults oom* -body {
418 set ::res [list]
419 sqlite3session_foreach -next v $::changeset { lappend ::res $v }
420 normalize_list $::res
421 } -test {
422 faultsim_test_result [list 0 $::expected] {1 SQLITE_NOMEM}
423 }
424 do_faultsim_test 8.2 -faults oom* -body {
425 set ::res [list]
426 sqlite3session_foreach v $::changeset { lappend ::res $v }
427 normalize_list $::res
428 } -test {
429 faultsim_test_result [list 0 $::expected] {1 SQLITE_NOMEM}
430 }
431
432 faultsim_delete_and_reopen
433 do_test 9.1.prep {
434 execsql {
435 PRAGMA encoding = 'utf16';
436 CREATE TABLE t1(a PRIMARY KEY, b);
437 }
438 } {}
439 faultsim_save_and_close
440
441 set answers [list {0 {}} {1 SQLITE_NOMEM} \
442 {1 {callback requested query abort}} \
443 {1 {abort due to ROLLBACK}}]
444 do_faultsim_test 9.1 -faults oom-transient -prep {
445 catch { unset ::c }
446 faultsim_restore_and_reopen
447 sqlite3session S db main
448 S attach *
449 } -body {
450 execsql {
451 INSERT INTO t1 VALUES('abcdefghijklmnopqrstuv', 'ABCDEFGHIJKLMNOPQRSTUV');
452 }
453 set ::c [S changeset]
454 set {} {}
455 } -test {
456 S delete
457 eval faultsim_test_result $::answers
458 if {[info exists ::c]} {
459 set expected [normalize_list {
460 {INSERT t1 0 X. {} {t abcdefghijklmnopqrstuv t ABCDEFGHIJKLMNOPQRSTUV}}
461 }]
462 if { [changeset_to_list $::c] != $expected } {
463 error "changeset mismatch"
464 }
465 }
466 }
467
468 faultsim_delete_and_reopen
469 do_test 9.2.prep {
470 execsql {
471 PRAGMA encoding = 'utf16';
472 CREATE TABLE t1(a PRIMARY KEY, b);
473 INSERT INTO t1 VALUES('abcdefghij', 'ABCDEFGHIJKLMNOPQRSTUV');
474 }
475 } {}
476 faultsim_save_and_close
477
478 set answers [list {0 {}} {1 SQLITE_NOMEM} \
479 {1 {callback requested query abort}} \
480 {1 {abort due to ROLLBACK}}]
481 do_faultsim_test 9.2 -faults oom-transient -prep {
482 catch { unset ::c }
483 faultsim_restore_and_reopen
484 sqlite3session S db main
485 S attach *
486 } -body {
487 execsql {
488 UPDATE t1 SET b = 'xyz';
489 }
490 set ::c [S changeset]
491 set {} {}
492 } -test {
493 S delete
494 eval faultsim_test_result $::answers
495 if {[info exists ::c]} {
496 set expected [normalize_list {
497 {UPDATE t1 0 X. {t abcdefghij t ABCDEFGHIJKLMNOPQRSTUV} {{} {} t xyz}}
498 }]
499 if { [changeset_to_list $::c] != $expected } {
500 error "changeset mismatch"
501 }
502 }
503 }
504
505 #-------------------------------------------------------------------------
506 # Test that if a conflict-handler encounters an OOM in
507 # sqlite3_value_text() but goes on to return SQLITE_CHANGESET_REPLACE
508 # anyway, the OOM is picked up by the sessions module.
509 set bigstr [string repeat abcdefghij 100]
510 faultsim_delete_and_reopen
511 do_test 10.prep.1 {
512 execsql {
513 CREATE TABLE t1(a PRIMARY KEY, b);
514 INSERT INTO t1 VALUES($bigstr, $bigstr);
515 }
516
517 sqlite3session S db main
518 S attach *
519 execsql { UPDATE t1 SET b = b||'x' }
520 set C [S changeset]
521 S delete
522 execsql { UPDATE t1 SET b = b||'xyz' }
523 } {}
524 faultsim_save_and_close
525
526 faultsim_restore_and_reopen
527 do_test 10.prep.2 {
528 proc xConflict {args} { return "ABORT" }
529 list [catch { sqlite3changeset_apply db $C xConflict } msg] $msg
530 } {1 SQLITE_ABORT}
531 do_execsql_test 10.prep.3 { SELECT b=$bigstr||'x' FROM t1 } 0
532 do_test 10.prep.4 {
533 proc xConflict {args} { return "REPLACE" }
534 list [catch { sqlite3changeset_apply db $C xConflict } msg] $msg
535 } {0 {}}
536 do_execsql_test 10.prep.5 { SELECT b=$bigstr||'x' FROM t1 } 1
537 db close
538
539 do_faultsim_test 10 -faults oom-tra* -prep {
540 faultsim_restore_and_reopen
541 } -body {
542 sqlite3changeset_apply_replace_all db $::C
543 } -test {
544 faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
545 if {$testrc==0} {
546 if {[db one {SELECT b=$bigstr||'x' FROM t1}]==0} {
547 error "data does not look right"
548 }
549 }
550 }
551
552 #-------------------------------------------------------------------------
553 # Test an OOM with an sqlite3changeset_apply() filter callback.
554 #
555 reset_db
556 do_test 11.prep {
557 execsql {
558 CREATE TABLE t1(a PRIMARY KEY, b);
559 CREATE TABLE t2(x PRIMARY KEY, y);
560 BEGIN;
561 }
562
563 set ::cs [changeset_from_sql {
564 INSERT INTO t1 VALUES(1, 2);
565 INSERT INTO t2 VALUES('x', 'y');
566 }]
567
568 execsql ROLLBACK
569 set {} {}
570 } {}
571
572 proc filter {x} { return [string equal t1 $x] }
573 faultsim_save_and_close
574
575 do_faultsim_test 11 -faults oom-tra* -prep {
576 faultsim_restore_and_reopen
577 } -body {
578 sqlite3changeset_apply db $::cs {} filter
579 } -test {
580 faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
581 if {$testrc==0} {
582 if {[db eval {SELECT * FROM t1 UNION ALL SELECT * FROM t2}] != "1 2"} {
583 error "data does not look right"
584 }
585 }
586 }
587
588
589 finish_test
OLDNEW
« no previous file with comments | « third_party/sqlite/src/ext/session/sessionat.test ('k') | third_party/sqlite/src/ext/session/sessionfault2.test » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698