1# 2016 March 31 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 20ifcapable !session {finish_test; return} 21set testprefix sessionfault2 22 23if 1 { 24 25do_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); 30 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); 35} 36faultsim_save_and_close 37 38faultsim_restore_and_reopen 39do_test 1.0.1 { 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; 47 }] 48 set {} {} 49} {} 50 51proc xConflict args { return "OMIT" } 52 53do_faultsim_test 1 -faults oom-p* -prep { 54 faultsim_restore_and_reopen 55} -body { 56 sqlite3changeset_apply db $::C xConflict 57} -test { 58 faultsim_test_result {0 {}} {1 SQLITE_NOMEM} 59 faultsim_integrity_check 60 61 catch { db eval ROLLBACK } 62 set res [db eval { 63 SELECT * FROM t1; 64 SELECT * FROM t2; 65 }] 66 67 if {$testrc==0} { 68 if {$res != "1 2 2 3 3 4 1 0 2 1 3 2"} { error "data error" } 69 } else { 70 if { 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" } 74 } 75} 76 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. 81# 82reset_db 83set nm [string repeat t 99] 84do_execsql_test 2.0.0 [string map "%TBL% $nm" { 85 CREATE TABLE %TBL%(a PRIMARY KEY, b UNIQUE); 86}] 87faultsim_save_and_close 88 89faultsim_restore_and_reopen 90do_test 1.0.1 { 91 set ::C [changeset_from_sql [string map "%TBL% $nm" { 92 INSERT INTO %TBL% VALUES(1, 2); 93 INSERT INTO %TBL% VALUES(3, 4); 94 }]] 95 set {} {} 96} {} 97 98proc xConflict args { return "OMIT" } 99do_faultsim_test 2 -faults oom-p* -prep { 100 faultsim_restore_and_reopen 101} -body { 102 sqlite3changeset_apply db $::C xConflict 103} -test { 104 faultsim_test_result {0 {}} {1 SQLITE_NOMEM} 105 faultsim_integrity_check 106} 107 108#------------------------------------------------------------------------- 109# OOM when collecting and apply a changeset that uses sqlite_stat1. 110# 111reset_db 112forcedelete test.db2 113sqlite3 db2 test.db2 114do_common_sql { 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); 124 ANALYZE; 125} 126faultsim_save_and_close 127db2 close 128 129do_faultsim_test 1.1 -faults oom-* -prep { 130 catch {db2 close} 131 catch {db close} 132 faultsim_restore_and_reopen 133 sqlite3 db2 test.db2 134} -body { 135 do_then_apply_sql { 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'; 139 } 140} -test { 141 faultsim_test_result {0 {}} {1 SQLITE_NOMEM} 142 faultsim_integrity_check 143 if {$testrc==0} { compare_db db db2 } 144} 145 146} 147 148#------------------------------------------------------------------------- 149# OOM when collecting and using a rebase changeset. 150# 151reset_db 152do_execsql_test 2.0 { 153 CREATE TABLE t3(a, b, c, PRIMARY KEY(b, c)); 154 CREATE TABLE t4(x PRIMARY KEY, y, z); 155 156 INSERT INTO t3 VALUES(1, 2, 3); 157 INSERT INTO t3 VALUES(4, 2, 5); 158 INSERT INTO t3 VALUES(7, 2, 9); 159 160 INSERT INTO t4 VALUES('a', 'b', 'c'); 161 INSERT INTO t4 VALUES('d', 'e', 'f'); 162 INSERT INTO t4 VALUES('g', 'h', 'i'); 163} 164faultsim_save_and_close 165 166proc xConflict {ret args} { return $ret } 167 168do_test 2.1 { 169 faultsim_restore_and_reopen 170 set C1 [changeset_from_sql { 171 INSERT INTO t3 VALUES(10, 11, 12); 172 UPDATE t4 SET y='j' WHERE x='g'; 173 DELETE FROM t4 WHERE x='a'; 174 }] 175 176 faultsim_restore_and_reopen 177 set C2 [changeset_from_sql { 178 INSERT INTO t3 VALUES(1000, 11, 12); 179 DELETE FROM t4 WHERE x='g'; 180 }] 181 182 faultsim_restore_and_reopen 183 sqlite3changeset_apply db $C1 [list xConflict OMIT] 184 faultsim_save_and_close 185} {} 186 187do_faultsim_test 2.2 -faults oom* -prep { 188 catch {db2 close} 189 catch {db close} 190 faultsim_restore_and_reopen 191 sqlite3 db2 test.db2 192} -body { 193 set rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict OMIT]] 194 set {} {} 195} -test { 196 faultsim_test_result {0 {}} {1 SQLITE_NOMEM} 197} 198do_faultsim_test 2.3 -faults oom* -prep { 199 catch {db2 close} 200 catch {db close} 201 faultsim_restore_and_reopen 202 sqlite3 db2 test.db2 203} -body { 204 set rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict REPLACE]] 205 set {} {} 206} -test { 207 faultsim_test_result {0 {}} {1 SQLITE_NOMEM} 208} 209do_faultsim_test 2.4 -faults oom* -prep { 210 catch {db2 close} 211 catch {db close} 212 faultsim_restore_and_reopen 213 set ::rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict REPLACE]] 214} -body { 215 sqlite3rebaser_create R 216 R configure $::rebase 217 R rebase $::C1 218 set {} {} 219} -test { 220 catch { R delete } 221 faultsim_test_result {0 {}} {1 SQLITE_NOMEM} 222} 223do_faultsim_test 2.5 -faults oom* -prep { 224 catch {db2 close} 225 catch {db close} 226 faultsim_restore_and_reopen 227 set ::rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict OMIT]] 228} -body { 229 sqlite3rebaser_create R 230 R configure $::rebase 231 R rebase $::C1 232 set {} {} 233} -test { 234 catch { R delete } 235 faultsim_test_result {0 {}} {1 SQLITE_NOMEM} 236} 237 238 239finish_test 240 241