1# 2001 September 15 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# This file attempts to check the library in an out-of-memory situation. 12# When compiled with -DMEMORY_DEBUG=1, the SQLite library accepts a special 13# command (sqlite_malloc_fail N) which causes the N-th malloc to fail. This 14# special feature is used to see what happens in the library if a malloc 15# were to really fail due to an out-of-memory situation. 16# 17# $Id: malloc.test,v 1.5 2002/05/23 02:09:05 drh Exp $ 18 19set testdir [file dirname $argv0] 20source $testdir/tester.tcl 21 22# Only run these tests if memory debugging is turned on. 23# 24if {[info command sqlite_malloc_fail]==""} { 25 puts "Skipping malloc tests: not compiled with -DMEMORY_DEBUG..." 26 finish_test 27 return 28} 29 30for {set go 1; set i 1} {$go} {incr i} { 31 do_test malloc-1.$i { 32 sqlite_malloc_fail 0 33 catch {db close} 34 catch {file delete -force test.db} 35 catch {file delete -force test.db-journal} 36 sqlite_malloc_fail $i 37 set v [catch {sqlite db test.db} msg] 38 if {$v} { 39 set msg "" 40 } else { 41 set v [catch {execsql { 42 CREATE TABLE t1( 43 a int, b float, c double, d text, e varchar(20), 44 primary key(a,b,c) 45 ); 46 CREATE INDEX i1 ON t1(a,b); 47 INSERT INTO t1 VALUES(1,2.3,4.5,'hi','there'); 48 INSERT INTO t1 VALUES(6,7.0,0.8,'hello','out yonder'); 49 SELECT * FROM t1; 50 SELECT avg(b) FROM t1 GROUP BY a HAVING b>20.0; 51 DELETE FROM t1 WHERE a IN (SELECT min(a) FROM t1); 52 SELECT count(*) FROM t1; 53 }} msg] 54 } 55 set leftover [lindex [sqlite_malloc_stat] 2] 56 if {$leftover>0} { 57 if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"} 58 set ::go 0 59 set v {1 1} 60 } else { 61 set v2 [expr {$msg=="" || $msg=="out of memory"}] 62 if {!$v2} {puts "\nError message returned: $msg"} 63 lappend v $v2 64 } 65 } {1 1} 66} 67 68set fd [open ./data.tmp w] 69for {set i 1} {$i<=20} {incr i} { 70 puts $fd "$i\t[expr {$i*$i}]\t[expr {100-$i}] abcdefghijklmnopqrstuvwxyz" 71} 72close $fd 73 74for {set go 1; set i 1} {$go} {incr i} { 75 do_test malloc-2.$i { 76 sqlite_malloc_fail 0 77 catch {db close} 78 catch {file delete -force test.db} 79 catch {file delete -force test.db-journal} 80 sqlite_malloc_fail $i 81 set v [catch {sqlite db test.db} msg] 82 if {$v} { 83 set msg "" 84 } else { 85 set v [catch {execsql { 86 CREATE TABLE t1(a int, b int, c int); 87 CREATE INDEX i1 ON t1(a,b); 88 COPY t1 FROM 'data.tmp'; 89 SELECT 'stuff', count(*) as 'other stuff', max(a+10) FROM t1; 90 UPDATE t1 SET b=b||b||b||b; 91 UPDATE t1 SET b=a WHERE a in (10,12,22); 92 INSERT INTO t1(c,b,a) VALUES(20,10,5); 93 INSERT INTO t1 SELECT * FROM t1 94 WHERE a IN (SELECT a FROM t1 WHERE a<10); 95 DELETE FROM t1 WHERE a>=10; 96 DROP INDEX i1; 97 DELETE FROM t1; 98 }} msg] 99 } 100 set leftover [lindex [sqlite_malloc_stat] 2] 101 if {$leftover>0} { 102 if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"} 103 set ::go 0 104 set v {1 1} 105 } else { 106 set v2 [expr {$msg=="" || $msg=="out of memory"}] 107 if {!$v2} {puts "\nError message returned: $msg"} 108 lappend v $v2 109 } 110 } {1 1} 111} 112 113set fd [open ./data.tmp w] 114for {set i 1} {$i<=10} {incr i} { 115 puts $fd "$i\t[expr {$i*$i}]\t[expr {100-$i}]" 116} 117close $fd 118 119for {set go 1; set i 1} {$go} {incr i} { 120 do_test malloc-3.$i { 121 sqlite_malloc_fail 0 122 catch {db close} 123 catch {file delete -force test.db} 124 catch {file delete -force test.db-journal} 125 sqlite_malloc_fail $i 126 set v [catch {sqlite db test.db} msg] 127 if {$v} { 128 set msg "" 129 } else { 130 set v [catch {execsql { 131 BEGIN TRANSACTION; 132 CREATE TABLE t1(a int, b int, c int); 133 CREATE INDEX i1 ON t1(a,b); 134 COPY t1 FROM 'data.tmp'; 135 INSERT INTO t1(c,b,a) VALUES(20,10,5); 136 DELETE FROM t1 WHERE a>=10; 137 DROP INDEX i1; 138 DELETE FROM t1; 139 ROLLBACK; 140 }} msg] 141 } 142 set leftover [lindex [sqlite_malloc_stat] 2] 143 if {$leftover>0} { 144 if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"} 145 set ::go 0 146 set v {1 1} 147 } else { 148 set v2 [expr {$msg=="" || $msg=="out of memory"}] 149 if {!$v2} {puts "\nError message returned: $msg"} 150 lappend v $v2 151 } 152 } {1 1} 153} 154for {set go 1; set i 1} {$go} {incr i} { 155 do_test malloc-4.$i { 156 sqlite_malloc_fail 0 157 catch {db close} 158 catch {file delete -force test.db} 159 catch {file delete -force test.db-journal} 160 sqlite_malloc_fail $i 161 set v [catch {sqlite db test.db} msg] 162 if {$v} { 163 set msg "" 164 } else { 165 set v [catch {execsql { 166 BEGIN TRANSACTION; 167 CREATE TABLE t1(a int, b int, c int); 168 CREATE INDEX i1 ON t1(a,b); 169 COPY t1 FROM 'data.tmp'; 170 UPDATE t1 SET b=a WHERE a in (10,12,22); 171 INSERT INTO t1 SELECT * FROM t1 172 WHERE a IN (SELECT a FROM t1 WHERE a<10); 173 DROP INDEX i1; 174 DELETE FROM t1; 175 COMMIT; 176 }} msg] 177 } 178 set leftover [lindex [sqlite_malloc_stat] 2] 179 if {$leftover>0} { 180 if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"} 181 set ::go 0 182 set v {1 1} 183 } else { 184 set v2 [expr {$msg=="" || $msg=="out of memory"}] 185 if {!$v2} {puts "\nError message returned: $msg"} 186 lappend v $v2 187 } 188 } {1 1} 189} 190for {set go 1; set i 1} {$go} {incr i} { 191 do_test malloc-5.$i { 192 sqlite_malloc_fail 0 193 catch {db close} 194 catch {file delete -force test.db} 195 catch {file delete -force test.db-journal} 196 sqlite_malloc_fail $i 197 set v [catch {sqlite db test.db} msg] 198 if {$v} { 199 set msg "" 200 } else { 201 set v [catch {execsql { 202 BEGIN TRANSACTION; 203 CREATE TABLE t1(a,b); 204 CREATE TABLE t2(x,y); 205 CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN 206 INSERT INTO t2(x,y) VALUES(new.rowid,1); 207 END; 208 INSERT INTO t1(a,b) VALUES(2,3); 209 COMMIT; 210 }} msg] 211 } 212 set leftover [lindex [sqlite_malloc_stat] 2] 213 if {$leftover>0} { 214 if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"} 215 set ::go 0 216 set v {1 1} 217 } else { 218 set v2 [expr {$msg=="" || $msg=="out of memory"}] 219 if {!$v2} {puts "\nError message returned: $msg"} 220 lappend v $v2 221 } 222 } {1 1} 223} 224sqlite_malloc_fail 0 225finish_test 226