15f5663dcSdan# 2016 March 31
25f5663dcSdan#
35f5663dcSdan# The author disclaims copyright to this source code.  In place of
45f5663dcSdan# a legal notice, here is a blessing:
55f5663dcSdan#
65f5663dcSdan#    May you do good and not evil.
75f5663dcSdan#    May you find forgiveness for yourself and forgive others.
85f5663dcSdan#    May you share freely, never taking more than you give.
95f5663dcSdan#
105f5663dcSdan#***********************************************************************
115f5663dcSdan#
125f5663dcSdan# The focus of this file is testing the session module.
135f5663dcSdan#
145f5663dcSdan
155f5663dcSdanif {![info exists testdir]} {
165f5663dcSdan  set testdir [file join [file dirname [info script]] .. .. test]
175f5663dcSdan}
185f5663dcSdansource [file join [file dirname [info script]] session_common.tcl]
195f5663dcSdansource $testdir/tester.tcl
2005accd22Sdanifcapable !session {finish_test; return}
215f5663dcSdanset testprefix sessionfault2
225f5663dcSdan
23bd45374cSdanif 1 {
24bd45374cSdan
255f5663dcSdando_execsql_test 1.0.0 {
265f5663dcSdan  CREATE TABLE t1(a PRIMARY KEY, b UNIQUE);
275f5663dcSdan  INSERT INTO t1 VALUES(1, 1);
285f5663dcSdan  INSERT INTO t1 VALUES(2, 2);
295f5663dcSdan  INSERT INTO t1 VALUES(3, 3);
305f5663dcSdan
315f5663dcSdan  CREATE TABLE t2(a PRIMARY KEY, b UNIQUE);
325f5663dcSdan  INSERT INTO t2 VALUES(1, 1);
335f5663dcSdan  INSERT INTO t2 VALUES(2, 2);
345f5663dcSdan  INSERT INTO t2 VALUES(3, 3);
355f5663dcSdan}
365f5663dcSdanfaultsim_save_and_close
375f5663dcSdan
385f5663dcSdanfaultsim_restore_and_reopen
395f5663dcSdando_test 1.0.1 {
405f5663dcSdan  set ::C [changeset_from_sql {
415f5663dcSdan    UPDATE t1 SET b=4 WHERE a=3;
425f5663dcSdan    UPDATE t1 SET b=3 WHERE a=2;
435f5663dcSdan    UPDATE t1 SET b=2 WHERE a=1;
445f5663dcSdan    UPDATE t2 SET b=0 WHERE a=1;
455f5663dcSdan    UPDATE t2 SET b=1 WHERE a=2;
465f5663dcSdan    UPDATE t2 SET b=2 WHERE a=3;
475f5663dcSdan  }]
485f5663dcSdan  set {} {}
495f5663dcSdan} {}
505f5663dcSdan
515f5663dcSdanproc xConflict args { return "OMIT" }
525f5663dcSdan
535f5663dcSdando_faultsim_test 1 -faults oom-p* -prep {
545f5663dcSdan  faultsim_restore_and_reopen
555f5663dcSdan} -body {
565f5663dcSdan  sqlite3changeset_apply db $::C xConflict
575f5663dcSdan} -test {
585f5663dcSdan  faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
595f5663dcSdan  faultsim_integrity_check
605f5663dcSdan
615f5663dcSdan  catch { db eval ROLLBACK }
625f5663dcSdan  set res [db eval {
635f5663dcSdan    SELECT * FROM t1;
645f5663dcSdan    SELECT * FROM t2;
655f5663dcSdan  }]
665f5663dcSdan
675f5663dcSdan  if {$testrc==0} {
685f5663dcSdan    if {$res != "1 2 2 3 3 4 1 0 2 1 3 2"} { error "data error" }
695f5663dcSdan  } else {
705f5663dcSdan    if {
715f5663dcSdan         $res != "1 2 2 3 3 4 1 0 2 1 3 2"
725f5663dcSdan      && $res != "1 1 2 2 3 3 1 1 2 2 3 3"
735f5663dcSdan    } { error "data error!! $res" }
745f5663dcSdan  }
755f5663dcSdan}
765f5663dcSdan
770d0a2abcSdan#-------------------------------------------------------------------------
780d0a2abcSdan# OOM when applying a changeset for which one of the tables has a name
790d0a2abcSdan# 99 bytes in size. This happens to cause an extra malloc in within the
800d0a2abcSdan# sessions_strm permutation.
810d0a2abcSdan#
820d0a2abcSdanreset_db
830d0a2abcSdanset nm [string repeat t 99]
840d0a2abcSdando_execsql_test 2.0.0 [string map "%TBL% $nm" {
850d0a2abcSdan  CREATE TABLE %TBL%(a PRIMARY KEY, b UNIQUE);
860d0a2abcSdan}]
870d0a2abcSdanfaultsim_save_and_close
880d0a2abcSdan
890d0a2abcSdanfaultsim_restore_and_reopen
900d0a2abcSdando_test 1.0.1 {
910d0a2abcSdan  set ::C [changeset_from_sql [string map "%TBL% $nm" {
920d0a2abcSdan    INSERT INTO %TBL% VALUES(1, 2);
930d0a2abcSdan    INSERT INTO %TBL% VALUES(3, 4);
940d0a2abcSdan  }]]
950d0a2abcSdan  set {} {}
960d0a2abcSdan} {}
970d0a2abcSdan
980d0a2abcSdanproc xConflict args { return "OMIT" }
990d0a2abcSdando_faultsim_test 2 -faults oom-p* -prep {
1000d0a2abcSdan  faultsim_restore_and_reopen
1010d0a2abcSdan} -body {
1020d0a2abcSdan  sqlite3changeset_apply db $::C xConflict
1030d0a2abcSdan} -test {
1040d0a2abcSdan  faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
1050d0a2abcSdan  faultsim_integrity_check
1060d0a2abcSdan}
1070d0a2abcSdan
108bd45374cSdan#-------------------------------------------------------------------------
109bd45374cSdan# OOM when collecting and apply a changeset that uses sqlite_stat1.
110bd45374cSdan#
111bd45374cSdanreset_db
112bd45374cSdanforcedelete test.db2
113bd45374cSdansqlite3 db2 test.db2
114bd45374cSdando_common_sql {
115bd45374cSdan  CREATE TABLE t1(a PRIMARY KEY, b UNIQUE, c);
116bd45374cSdan  CREATE INDEX i1 ON t1(c);
117bd45374cSdan  INSERT INTO t1 VALUES(1, 2, 3);
118bd45374cSdan  INSERT INTO t1 VALUES(4, 5, 6);
119bd45374cSdan  INSERT INTO t1 VALUES(7, 8, 9);
120bd45374cSdan  CREATE TABLE t2(a, b, c);
121bd45374cSdan  INSERT INTO t2 VALUES(1, 2, 3);
122bd45374cSdan  INSERT INTO t2 VALUES(4, 5, 6);
123bd45374cSdan  INSERT INTO t2 VALUES(7, 8, 9);
124bd45374cSdan  ANALYZE;
125bd45374cSdan}
126bd45374cSdanfaultsim_save_and_close
127bd45374cSdandb2 close
128bd45374cSdan
129bd45374cSdando_faultsim_test 1.1 -faults oom-* -prep {
130bd45374cSdan  catch {db2 close}
131bd45374cSdan  catch {db close}
132bd45374cSdan  faultsim_restore_and_reopen
133bd45374cSdan  sqlite3 db2 test.db2
134bd45374cSdan} -body {
135bd45374cSdan  do_then_apply_sql {
136bd45374cSdan    INSERT INTO sqlite_stat1 VALUES('x', 'y', 45);
137bd45374cSdan    UPDATE sqlite_stat1 SET stat = 123 WHERE tbl='t1' AND idx='i1';
138bd45374cSdan    UPDATE sqlite_stat1 SET stat = 456 WHERE tbl='t2';
139bd45374cSdan  }
140bd45374cSdan} -test {
141bd45374cSdan  faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
142bd45374cSdan  faultsim_integrity_check
143bd45374cSdan  if {$testrc==0} { compare_db db db2 }
144bd45374cSdan}
145bd45374cSdan
146bd45374cSdan#-------------------------------------------------------------------------
147bd45374cSdan# OOM when collecting and using a rebase changeset.
148bd45374cSdan#
149bd45374cSdanreset_db
150bd45374cSdando_execsql_test 2.0 {
151bd45374cSdan  CREATE TABLE t3(a, b, c, PRIMARY KEY(b, c));
152bd45374cSdan  CREATE TABLE t4(x PRIMARY KEY, y, z);
153bd45374cSdan
154bd45374cSdan  INSERT INTO t3 VALUES(1, 2, 3);
155bd45374cSdan  INSERT INTO t3 VALUES(4, 2, 5);
156bd45374cSdan  INSERT INTO t3 VALUES(7, 2, 9);
157bd45374cSdan
158bd45374cSdan  INSERT INTO t4 VALUES('a', 'b', 'c');
159bd45374cSdan  INSERT INTO t4 VALUES('d', 'e', 'f');
160bd45374cSdan  INSERT INTO t4 VALUES('g', 'h', 'i');
161bd45374cSdan}
162bd45374cSdanfaultsim_save_and_close
163*43ff906dSmistachkindb2 close
164bd45374cSdan
165bd45374cSdanproc xConflict {ret args} { return $ret }
166bd45374cSdan
167bd45374cSdando_test 2.1 {
168bd45374cSdan  faultsim_restore_and_reopen
169bd45374cSdan  set C1 [changeset_from_sql {
170bd45374cSdan    INSERT INTO t3 VALUES(10, 11, 12);
171bd45374cSdan    UPDATE t4 SET y='j' WHERE x='g';
172bd45374cSdan    DELETE FROM t4 WHERE x='a';
173bd45374cSdan  }]
174bd45374cSdan
175bd45374cSdan  faultsim_restore_and_reopen
176bd45374cSdan  set C2 [changeset_from_sql {
177bd45374cSdan    INSERT INTO t3 VALUES(1000, 11, 12);
178bd45374cSdan    DELETE FROM t4 WHERE x='g';
179bd45374cSdan  }]
180bd45374cSdan
181bd45374cSdan  faultsim_restore_and_reopen
182bd45374cSdan  sqlite3changeset_apply db $C1 [list xConflict OMIT]
183bd45374cSdan  faultsim_save_and_close
184bd45374cSdan} {}
185bd45374cSdan
186bd45374cSdando_faultsim_test 2.2 -faults oom* -prep {
187bd45374cSdan  catch {db2 close}
188bd45374cSdan  catch {db close}
189bd45374cSdan  faultsim_restore_and_reopen
190bd45374cSdan  sqlite3 db2 test.db2
191bd45374cSdan} -body {
192bd45374cSdan  set rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict OMIT]]
193bd45374cSdan  set {} {}
194bd45374cSdan} -test {
195bd45374cSdan  faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
196bd45374cSdan}
197bd45374cSdando_faultsim_test 2.3 -faults oom* -prep {
198bd45374cSdan  catch {db2 close}
199bd45374cSdan  catch {db close}
200bd45374cSdan  faultsim_restore_and_reopen
201bd45374cSdan  sqlite3 db2 test.db2
202bd45374cSdan} -body {
203bd45374cSdan  set rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict REPLACE]]
204bd45374cSdan  set {} {}
205bd45374cSdan} -test {
206bd45374cSdan  faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
207bd45374cSdan}
208bd45374cSdando_faultsim_test 2.4 -faults oom* -prep {
209bd45374cSdan  catch {db2 close}
210bd45374cSdan  catch {db close}
211bd45374cSdan  faultsim_restore_and_reopen
212bd45374cSdan  set ::rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict REPLACE]]
213bd45374cSdan} -body {
214bd45374cSdan  sqlite3rebaser_create R
215bd45374cSdan  R configure $::rebase
216bd45374cSdan  R rebase $::C1
217bd45374cSdan  set {} {}
218bd45374cSdan} -test {
219bd45374cSdan  catch { R delete }
220bd45374cSdan  faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
221bd45374cSdan}
222bd45374cSdando_faultsim_test 2.5 -faults oom* -prep {
223bd45374cSdan  catch {db2 close}
224bd45374cSdan  catch {db close}
225bd45374cSdan  faultsim_restore_and_reopen
226bd45374cSdan  set ::rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict OMIT]]
227bd45374cSdan} -body {
228bd45374cSdan  sqlite3rebaser_create R
229bd45374cSdan  R configure $::rebase
230bd45374cSdan  R rebase $::C1
231bd45374cSdan  set {} {}
232bd45374cSdan} -test {
233bd45374cSdan  catch { R delete }
234bd45374cSdan  faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
235bd45374cSdan}
236bd45374cSdan
237f231e18cSdan}
238f231e18cSdan
239f231e18cSdanreset_db
240f231e18cSdando_execsql_test 3.0 {
241f231e18cSdan  CREATE TABLE t1(x PRIMARY KEY, y, z);
242f231e18cSdan  INSERT INTO t1 VALUES(3, 1, 4);
243f231e18cSdan  INSERT INTO t1 VALUES(1, 5, 9);
244f231e18cSdan}
245f231e18cSdanfaultsim_save_and_close
246f231e18cSdan
247f231e18cSdanproc xConflict {ret args} { return $ret }
248f231e18cSdan
249f231e18cSdando_test 3.1 {
250f231e18cSdan  faultsim_restore_and_reopen
251f231e18cSdan
252f231e18cSdan  execsql { BEGIN; UPDATE t1 SET z=11; }
253f231e18cSdan  set C1 [changeset_from_sql {
254f231e18cSdan    UPDATE t1 SET z=10 WHERE x=1;
255f231e18cSdan  }]
256f231e18cSdan  execsql { ROLLBACK }
257f231e18cSdan
258f231e18cSdan  execsql { BEGIN; UPDATE t1 SET z=11; }
259f231e18cSdan  set C2 [changeset_from_sql {
260f231e18cSdan    UPDATE t1 SET z=55 WHERE x=1;
261f231e18cSdan  }]
262f231e18cSdan  execsql { ROLLBACK }
263f231e18cSdan
264f231e18cSdan  set ::rebase1 [sqlite3changeset_apply_v2 db $::C1 [list xConflict OMIT]]
265f231e18cSdan  set ::rebase2 [sqlite3changeset_apply_v2 db $::C2 [list xConflict OMIT]]
266f231e18cSdan  set {} {}
267f231e18cSdan  execsql { SELECT * FROM t1 }
268f231e18cSdan} {3 1 4 1 5 9}
269f231e18cSdan
270f231e18cSdan
271f231e18cSdando_faultsim_test 3.2 -faults oom* -prep {
272f231e18cSdan  faultsim_restore_and_reopen
273f231e18cSdan} -body {
274f231e18cSdan  sqlite3rebaser_create R
275f231e18cSdan  R configure $::rebase1
276f231e18cSdan  R configure $::rebase2
277f231e18cSdan  set {} {}
278f231e18cSdan} -test {
279f231e18cSdan  catch { R delete }
280f231e18cSdan  faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
281f231e18cSdan}
282f231e18cSdan
283bd45374cSdan
2845f5663dcSdanfinish_test
285