3 # The author disclaims copyright to this source code. In place of
4 # a legal notice, here is a blessing:
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.
10 #***********************************************************************
12 # The focus of this file is testing the session module.
15 if {![info exists testdir]} {
16 set testdir [file join [file dirname [info script]] .. .. test]
18 source [file join [file dirname [info script]] session_common.tcl]
19 source $testdir/tester.tcl
20 ifcapable !session {finish_test; return}
21 set testprefix sessionfault2
25 do_execsql_test 1.0.0 {
26 CREATE TABLE t1(a PRIMARY KEY, b UNIQUE);
27 INSERT INTO t1 VALUES(1, 1);
28 INSERT INTO t1 VALUES(2, 2);
29 INSERT INTO t1 VALUES(3, 3);
31 CREATE TABLE t2(a PRIMARY KEY, b UNIQUE);
32 INSERT INTO t2 VALUES(1, 1);
33 INSERT INTO t2 VALUES(2, 2);
34 INSERT INTO t2 VALUES(3, 3);
36 faultsim_save_and_close
38 faultsim_restore_and_reopen
40 set ::C [changeset_from_sql {
41 UPDATE t1 SET b=4 WHERE a=3;
42 UPDATE t1 SET b=3 WHERE a=2;
43 UPDATE t1 SET b=2 WHERE a=1;
44 UPDATE t2 SET b=0 WHERE a=1;
45 UPDATE t2 SET b=1 WHERE a=2;
46 UPDATE t2 SET b=2 WHERE a=3;
51 proc xConflict args { return "OMIT" }
53 do_faultsim_test 1 -faults oom-p* -prep {
54 faultsim_restore_and_reopen
56 sqlite3changeset_apply db $::C xConflict
58 faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
59 faultsim_integrity_check
61 catch { db eval ROLLBACK }
68 if {$res != "1 2 2 3 3 4 1 0 2 1 3 2"} { error "data error" }
71 $res != "1 2 2 3 3 4 1 0 2 1 3 2"
72 && $res != "1 1 2 2 3 3 1 1 2 2 3 3"
73 } { error "data error!! $res" }
77 #-------------------------------------------------------------------------
78 # OOM when applying a changeset for which one of the tables has a name
79 # 99 bytes in size. This happens to cause an extra malloc in within the
80 # sessions_strm permutation.
83 set nm [string repeat t 99]
84 do_execsql_test 2.0.0 [string map "%TBL% $nm" {
85 CREATE TABLE %TBL%(a PRIMARY KEY, b UNIQUE);
87 faultsim_save_and_close
89 faultsim_restore_and_reopen
91 set ::C [changeset_from_sql [string map "%TBL% $nm" {
92 INSERT INTO %TBL% VALUES(1, 2);
93 INSERT INTO %TBL% VALUES(3, 4);
98 proc xConflict args { return "OMIT" }
99 do_faultsim_test 2 -faults oom-p* -prep {
100 faultsim_restore_and_reopen
102 sqlite3changeset_apply db $::C xConflict
104 faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
105 faultsim_integrity_check
108 #-------------------------------------------------------------------------
109 # OOM when collecting and apply a changeset that uses sqlite_stat1.
115 CREATE TABLE t1(a PRIMARY KEY, b UNIQUE, c);
116 CREATE INDEX i1 ON t1(c);
117 INSERT INTO t1 VALUES(1, 2, 3);
118 INSERT INTO t1 VALUES(4, 5, 6);
119 INSERT INTO t1 VALUES(7, 8, 9);
120 CREATE TABLE t2(a, b, c);
121 INSERT INTO t2 VALUES(1, 2, 3);
122 INSERT INTO t2 VALUES(4, 5, 6);
123 INSERT INTO t2 VALUES(7, 8, 9);
126 faultsim_save_and_close
129 do_faultsim_test 1.1 -faults oom-* -prep {
132 faultsim_restore_and_reopen
135 do_then_apply_sql -ignorenoop {
136 INSERT INTO sqlite_stat1 VALUES('x', 'y', 45);
137 UPDATE sqlite_stat1 SET stat = 123 WHERE tbl='t1' AND idx='i1';
138 UPDATE sqlite_stat1 SET stat = 456 WHERE tbl='t2';
141 faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
142 faultsim_integrity_check
143 if {$testrc==0} { compare_db db db2 }
146 #-------------------------------------------------------------------------
147 # OOM when collecting and using a rebase changeset.
150 do_execsql_test 2.0 {
151 CREATE TABLE t3(a, b, c, PRIMARY KEY(b, c));
152 CREATE TABLE t4(x PRIMARY KEY, y, z);
154 INSERT INTO t3 VALUES(1, 2, 3);
155 INSERT INTO t3 VALUES(4, 2, 5);
156 INSERT INTO t3 VALUES(7, 2, 9);
158 INSERT INTO t4 VALUES('a', 'b', 'c');
159 INSERT INTO t4 VALUES('d', 'e', 'f');
160 INSERT INTO t4 VALUES('g', 'h', 'i');
162 faultsim_save_and_close
165 proc xConflict {ret args} { return $ret }
168 faultsim_restore_and_reopen
169 set C1 [changeset_from_sql {
170 INSERT INTO t3 VALUES(10, 11, 12);
171 UPDATE t4 SET y='j' WHERE x='g';
172 DELETE FROM t4 WHERE x='a';
175 faultsim_restore_and_reopen
176 set C2 [changeset_from_sql {
177 INSERT INTO t3 VALUES(1000, 11, 12);
178 DELETE FROM t4 WHERE x='g';
181 faultsim_restore_and_reopen
182 sqlite3changeset_apply db $C1 [list xConflict OMIT]
183 faultsim_save_and_close
186 do_faultsim_test 2.2 -faults oom* -prep {
189 faultsim_restore_and_reopen
192 set rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict OMIT]]
195 faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
197 do_faultsim_test 2.3 -faults oom* -prep {
200 faultsim_restore_and_reopen
203 set rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict REPLACE]]
206 faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
208 do_faultsim_test 2.4 -faults oom* -prep {
211 faultsim_restore_and_reopen
212 set ::rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict REPLACE]]
214 sqlite3rebaser_create R
215 R configure $::rebase
220 faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
222 do_faultsim_test 2.5 -faults oom* -prep {
225 faultsim_restore_and_reopen
226 set ::rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict OMIT]]
228 sqlite3rebaser_create R
229 R configure $::rebase
234 faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
240 do_execsql_test 3.0 {
241 CREATE TABLE t1(x PRIMARY KEY, y, z);
242 INSERT INTO t1 VALUES(3, 1, 4);
243 INSERT INTO t1 VALUES(1, 5, 9);
245 faultsim_save_and_close
247 proc xConflict {ret args} { return $ret }
250 faultsim_restore_and_reopen
252 execsql { BEGIN; UPDATE t1 SET z=11; }
253 set C1 [changeset_from_sql {
254 UPDATE t1 SET z=10 WHERE x=1;
258 execsql { BEGIN; UPDATE t1 SET z=11; }
259 set C2 [changeset_from_sql {
260 UPDATE t1 SET z=55 WHERE x=1;
264 set ::rebase1 [sqlite3changeset_apply_v2 db $::C1 [list xConflict OMIT]]
265 set ::rebase2 [sqlite3changeset_apply_v2 db $::C2 [list xConflict OMIT]]
267 execsql { SELECT * FROM t1 }
271 do_faultsim_test 3.2 -faults oom* -prep {
272 faultsim_restore_and_reopen
274 sqlite3rebaser_create R
275 R configure $::rebase1
276 R configure $::rebase2
280 faultsim_test_result {0 {}} {1 SQLITE_NOMEM}