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
15if {![info exists testdir]} {
16  set testdir [file join [file dirname [info script]] .. .. test]
17}
18source [file join [file dirname [info script]] session_common.tcl]
19source $testdir/tester.tcl
20
21set testprefix sessionfault
22
23forcedelete test.db2
24sqlite3 db2 test.db2
25
26do_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}
31faultsim_save_and_close
32db2 close
33
34# Test OOM error handling when collecting and applying a simple changeset.
35#
36do_faultsim_test pagerfault-1 -faults oom-* -prep {
37  catch {db2 close}
38  catch {db close}
39  faultsim_restore_and_reopen
40  sqlite3 db2 test.db2
41} -body {
42  do_then_apply_sql {
43    INSERT INTO t1 VALUES(7, 8, 9);
44    UPDATE t1 SET c = 10 WHERE a = 1;
45    DELETE FROM t1 WHERE a = 4;
46  }
47} -test {
48  faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
49  faultsim_integrity_check
50  if {$testrc==0} { compare_db db db2 }
51}
52
53# This test case is designed so that a malloc() failure occurs while
54# resizing the session object hash-table from 256 to 512 buckets. This
55# is not an error, just a sub-optimal condition.
56#
57do_faultsim_test pagerfault-2 -faults oom-* -prep {
58  catch {db2 close}
59  catch {db close}
60  faultsim_restore_and_reopen
61  sqlite3 db2 test.db2
62
63  sqlite3session S db main
64  S attach t1
65  execsql { BEGIN }
66  for {set i 0} {$i < 125} {incr i} {
67    execsql {INSERT INTO t1 VALUES(10+$i, 10+$i, 10+$i)}
68  }
69} -body {
70  for {set i 125} {$i < 133} {incr i} {
71    execsql {INSERT INTO t1 VALUES(10+$i, 10+$i, 1-+$i)}
72  }
73  S changeset
74  set {} {}
75} -test {
76  faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
77  if {$testrc==0} {
78    sqlite3changeset_apply db2 [S changeset] xConflict
79    compare_db db db2
80  }
81  catch { S delete }
82  faultsim_integrity_check
83}
84
85catch { db close }
86catch { db2 close }
87forcedelete test.db2 test.db
88sqlite3 db2 test.db2
89sqlite3 db test.db
90
91proc xConflict {op tbl type args} {
92  if { $type=="CONFLICT" || $type=="DATA" } {
93    return "REPLACE"
94  }
95  return "OMIT"
96}
97
98do_test 3.0 {
99  execsql {
100    PRAGMA encoding = 'utf16';
101    CREATE TABLE t1(a PRIMARY KEY, b);
102    INSERT INTO t1 VALUES(5, 32);
103  }
104  execsql {
105    PRAGMA encoding = 'utf16';
106    CREATE TABLE t1(a PRIMARY KEY, b NOT NULL);
107    INSERT INTO t1 VALUES(1, 2);
108    INSERT INTO t1 VALUES(2, 4);
109    INSERT INTO t1 VALUES(4, 16);
110  } db2
111} {}
112
113faultsim_save_and_close
114db2 close
115
116do_faultsim_test pagerfault-3 -faults oom-transient -prep {
117  catch {db2 close}
118  catch {db close}
119  faultsim_restore_and_reopen
120  sqlite3 db2 test.db2
121  sqlite3session S db main
122  S attach t1
123  execsql {
124    INSERT INTO t1 VALUES(1, 45);
125    INSERT INTO t1 VALUES(2, 55);
126    INSERT INTO t1 VALUES(3, 55);
127    UPDATE t1 SET a = 4 WHERE a = 5;
128  }
129} -body {
130  sqlite3changeset_apply db2 [S changeset] xConflict
131} -test {
132  catch { S delete }
133  faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
134  if {$testrc==0} { compare_db db db2 }
135}
136
137finish_test
138