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