xref: /sqlite-3.40.0/test/malloc.test (revision b5f70c2e)
1b19a2bc6Sdrh# 2001 September 15
2ed7c855cSdrh#
3b19a2bc6Sdrh# The author disclaims copyright to this source code.  In place of
4b19a2bc6Sdrh# a legal notice, here is a blessing:
5ed7c855cSdrh#
6b19a2bc6Sdrh#    May you do good and not evil.
7b19a2bc6Sdrh#    May you find forgiveness for yourself and forgive others.
8b19a2bc6Sdrh#    May you share freely, never taking more than you give.
9ed7c855cSdrh#
10ed7c855cSdrh#***********************************************************************
11ed7c855cSdrh# This file attempts to check the library in an out-of-memory situation.
12ed7c855cSdrh# When compiled with -DMEMORY_DEBUG=1, the SQLite library accepts a special
136d4abfbeSdrh# command (sqlite_malloc_fail N) which causes the N-th malloc to fail.  This
14ed7c855cSdrh# special feature is used to see what happens in the library if a malloc
15ed7c855cSdrh# were to really fail due to an out-of-memory situation.
16ed7c855cSdrh#
17*b5f70c2eSdrh# $Id: malloc.test,v 1.6 2004/02/14 01:39:50 drh Exp $
18ed7c855cSdrh
19ed7c855cSdrhset testdir [file dirname $argv0]
20ed7c855cSdrhsource $testdir/tester.tcl
21ed7c855cSdrh
22ed7c855cSdrh# Only run these tests if memory debugging is turned on.
23ed7c855cSdrh#
24*b5f70c2eSdrhif {[info command sqlite_malloc_stat]==""} {
25ed7c855cSdrh   puts "Skipping malloc tests: not compiled with -DMEMORY_DEBUG..."
26ed7c855cSdrh   finish_test
27ed7c855cSdrh   return
28ed7c855cSdrh}
29ed7c855cSdrh
30ed7c855cSdrhfor {set go 1; set i 1} {$go} {incr i} {
31ed7c855cSdrh  do_test malloc-1.$i {
32ed7c855cSdrh     sqlite_malloc_fail 0
336d4abfbeSdrh     catch {db close}
346d4abfbeSdrh     catch {file delete -force test.db}
356d4abfbeSdrh     catch {file delete -force test.db-journal}
36ed7c855cSdrh     sqlite_malloc_fail $i
376d4abfbeSdrh     set v [catch {sqlite db test.db} msg]
386d4abfbeSdrh     if {$v} {
396d4abfbeSdrh       set msg ""
406d4abfbeSdrh     } else {
41ed7c855cSdrh       set v [catch {execsql {
42ed7c855cSdrh          CREATE TABLE t1(
43ed7c855cSdrh             a int, b float, c double, d text, e varchar(20),
44ed7c855cSdrh             primary key(a,b,c)
45ed7c855cSdrh          );
46ed7c855cSdrh          CREATE INDEX i1 ON t1(a,b);
47ed7c855cSdrh          INSERT INTO t1 VALUES(1,2.3,4.5,'hi','there');
48ed7c855cSdrh          INSERT INTO t1 VALUES(6,7.0,0.8,'hello','out yonder');
49ed7c855cSdrh          SELECT * FROM t1;
50d400728aSdrh          SELECT avg(b) FROM t1 GROUP BY a HAVING b>20.0;
516d4abfbeSdrh          DELETE FROM t1 WHERE a IN (SELECT min(a) FROM t1);
52ed7c855cSdrh          SELECT count(*) FROM t1;
53ed7c855cSdrh       }} msg]
546d4abfbeSdrh     }
556d4abfbeSdrh     set leftover [lindex [sqlite_malloc_stat] 2]
566d4abfbeSdrh     if {$leftover>0} {
576d4abfbeSdrh       if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v  Message=$msg"}
58ed7c855cSdrh       set ::go 0
59ed7c855cSdrh       set v {1 1}
60ed7c855cSdrh     } else {
616d4abfbeSdrh       set v2 [expr {$msg=="" || $msg=="out of memory"}]
626d4abfbeSdrh       if {!$v2} {puts "\nError message returned: $msg"}
636d4abfbeSdrh       lappend v $v2
64ed7c855cSdrh     }
65ed7c855cSdrh  } {1 1}
66ed7c855cSdrh}
67d400728aSdrh
68d400728aSdrhset fd [open ./data.tmp w]
696d4abfbeSdrhfor {set i 1} {$i<=20} {incr i} {
706d4abfbeSdrh  puts $fd "$i\t[expr {$i*$i}]\t[expr {100-$i}] abcdefghijklmnopqrstuvwxyz"
71d400728aSdrh}
72d400728aSdrhclose $fd
73d400728aSdrh
74d400728aSdrhfor {set go 1; set i 1} {$go} {incr i} {
75d400728aSdrh  do_test malloc-2.$i {
76d400728aSdrh     sqlite_malloc_fail 0
776d4abfbeSdrh     catch {db close}
786d4abfbeSdrh     catch {file delete -force test.db}
796d4abfbeSdrh     catch {file delete -force test.db-journal}
80d400728aSdrh     sqlite_malloc_fail $i
816d4abfbeSdrh     set v [catch {sqlite db test.db} msg]
826d4abfbeSdrh     if {$v} {
836d4abfbeSdrh       set msg ""
846d4abfbeSdrh     } else {
85d400728aSdrh       set v [catch {execsql {
86d400728aSdrh         CREATE TABLE t1(a int, b int, c int);
87d400728aSdrh         CREATE INDEX i1 ON t1(a,b);
88d400728aSdrh         COPY t1 FROM 'data.tmp';
896d4abfbeSdrh         SELECT 'stuff', count(*) as 'other stuff', max(a+10) FROM t1;
906d4abfbeSdrh         UPDATE t1 SET b=b||b||b||b;
91d400728aSdrh         UPDATE t1 SET b=a WHERE a in (10,12,22);
926d4abfbeSdrh         INSERT INTO t1(c,b,a) VALUES(20,10,5);
936d4abfbeSdrh         INSERT INTO t1 SELECT * FROM t1
946d4abfbeSdrh             WHERE a IN (SELECT a FROM t1 WHERE a<10);
956d4abfbeSdrh         DELETE FROM t1 WHERE a>=10;
96d400728aSdrh         DROP INDEX i1;
976d4abfbeSdrh         DELETE FROM t1;
98d400728aSdrh       }} msg]
996d4abfbeSdrh     }
1006d4abfbeSdrh     set leftover [lindex [sqlite_malloc_stat] 2]
1016d4abfbeSdrh     if {$leftover>0} {
1026d4abfbeSdrh       if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v  Message=$msg"}
103d400728aSdrh       set ::go 0
104d400728aSdrh       set v {1 1}
105d400728aSdrh     } else {
1066d4abfbeSdrh       set v2 [expr {$msg=="" || $msg=="out of memory"}]
1076d4abfbeSdrh       if {!$v2} {puts "\nError message returned: $msg"}
1086d4abfbeSdrh       lappend v $v2
1096d4abfbeSdrh     }
1106d4abfbeSdrh  } {1 1}
1116d4abfbeSdrh}
1126d4abfbeSdrh
1136d4abfbeSdrhset fd [open ./data.tmp w]
1146d4abfbeSdrhfor {set i 1} {$i<=10} {incr i} {
1156d4abfbeSdrh  puts $fd "$i\t[expr {$i*$i}]\t[expr {100-$i}]"
1166d4abfbeSdrh}
1176d4abfbeSdrhclose $fd
1186d4abfbeSdrh
1196d4abfbeSdrhfor {set go 1; set i 1} {$go} {incr i} {
1206d4abfbeSdrh  do_test malloc-3.$i {
1216d4abfbeSdrh     sqlite_malloc_fail 0
1226d4abfbeSdrh     catch {db close}
1236d4abfbeSdrh     catch {file delete -force test.db}
1246d4abfbeSdrh     catch {file delete -force test.db-journal}
1256d4abfbeSdrh     sqlite_malloc_fail $i
1266d4abfbeSdrh     set v [catch {sqlite db test.db} msg]
1276d4abfbeSdrh     if {$v} {
1286d4abfbeSdrh       set msg ""
1296d4abfbeSdrh     } else {
1306d4abfbeSdrh       set v [catch {execsql {
1316d4abfbeSdrh         BEGIN TRANSACTION;
1326d4abfbeSdrh         CREATE TABLE t1(a int, b int, c int);
1336d4abfbeSdrh         CREATE INDEX i1 ON t1(a,b);
1346d4abfbeSdrh         COPY t1 FROM 'data.tmp';
1356d4abfbeSdrh         INSERT INTO t1(c,b,a) VALUES(20,10,5);
1366d4abfbeSdrh         DELETE FROM t1 WHERE a>=10;
1376d4abfbeSdrh         DROP INDEX i1;
1386d4abfbeSdrh         DELETE FROM t1;
1396d4abfbeSdrh         ROLLBACK;
1406d4abfbeSdrh       }} msg]
1416d4abfbeSdrh     }
1426d4abfbeSdrh     set leftover [lindex [sqlite_malloc_stat] 2]
1436d4abfbeSdrh     if {$leftover>0} {
1446d4abfbeSdrh       if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v  Message=$msg"}
1456d4abfbeSdrh       set ::go 0
1466d4abfbeSdrh       set v {1 1}
1476d4abfbeSdrh     } else {
1486d4abfbeSdrh       set v2 [expr {$msg=="" || $msg=="out of memory"}]
1496d4abfbeSdrh       if {!$v2} {puts "\nError message returned: $msg"}
1506d4abfbeSdrh       lappend v $v2
1516d4abfbeSdrh     }
1526d4abfbeSdrh  } {1 1}
1536d4abfbeSdrh}
1546d4abfbeSdrhfor {set go 1; set i 1} {$go} {incr i} {
1556d4abfbeSdrh  do_test malloc-4.$i {
1566d4abfbeSdrh     sqlite_malloc_fail 0
1576d4abfbeSdrh     catch {db close}
1586d4abfbeSdrh     catch {file delete -force test.db}
1596d4abfbeSdrh     catch {file delete -force test.db-journal}
1606d4abfbeSdrh     sqlite_malloc_fail $i
1616d4abfbeSdrh     set v [catch {sqlite db test.db} msg]
1626d4abfbeSdrh     if {$v} {
1636d4abfbeSdrh       set msg ""
1646d4abfbeSdrh     } else {
1656d4abfbeSdrh       set v [catch {execsql {
1666d4abfbeSdrh         BEGIN TRANSACTION;
1676d4abfbeSdrh         CREATE TABLE t1(a int, b int, c int);
1686d4abfbeSdrh         CREATE INDEX i1 ON t1(a,b);
1696d4abfbeSdrh         COPY t1 FROM 'data.tmp';
1706d4abfbeSdrh         UPDATE t1 SET b=a WHERE a in (10,12,22);
1716d4abfbeSdrh         INSERT INTO t1 SELECT * FROM t1
1726d4abfbeSdrh             WHERE a IN (SELECT a FROM t1 WHERE a<10);
1736d4abfbeSdrh         DROP INDEX i1;
1746d4abfbeSdrh         DELETE FROM t1;
1756d4abfbeSdrh         COMMIT;
1766d4abfbeSdrh       }} msg]
1776d4abfbeSdrh     }
1786d4abfbeSdrh     set leftover [lindex [sqlite_malloc_stat] 2]
1796d4abfbeSdrh     if {$leftover>0} {
1806d4abfbeSdrh       if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v  Message=$msg"}
1816d4abfbeSdrh       set ::go 0
1826d4abfbeSdrh       set v {1 1}
1836d4abfbeSdrh     } else {
1846d4abfbeSdrh       set v2 [expr {$msg=="" || $msg=="out of memory"}]
1856d4abfbeSdrh       if {!$v2} {puts "\nError message returned: $msg"}
1866d4abfbeSdrh       lappend v $v2
187d400728aSdrh     }
188d400728aSdrh  } {1 1}
189d400728aSdrh}
190e4697f5eSdrhfor {set go 1; set i 1} {$go} {incr i} {
191e4697f5eSdrh  do_test malloc-5.$i {
192e4697f5eSdrh     sqlite_malloc_fail 0
193e4697f5eSdrh     catch {db close}
194e4697f5eSdrh     catch {file delete -force test.db}
195e4697f5eSdrh     catch {file delete -force test.db-journal}
196e4697f5eSdrh     sqlite_malloc_fail $i
197e4697f5eSdrh     set v [catch {sqlite db test.db} msg]
198e4697f5eSdrh     if {$v} {
199e4697f5eSdrh       set msg ""
200e4697f5eSdrh     } else {
201e4697f5eSdrh       set v [catch {execsql {
202e4697f5eSdrh         BEGIN TRANSACTION;
203e4697f5eSdrh         CREATE TABLE t1(a,b);
204e4697f5eSdrh         CREATE TABLE t2(x,y);
205e4697f5eSdrh         CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN
206e4697f5eSdrh           INSERT INTO t2(x,y) VALUES(new.rowid,1);
207e4697f5eSdrh         END;
208e4697f5eSdrh         INSERT INTO t1(a,b) VALUES(2,3);
209e4697f5eSdrh         COMMIT;
210e4697f5eSdrh       }} msg]
211e4697f5eSdrh     }
212e4697f5eSdrh     set leftover [lindex [sqlite_malloc_stat] 2]
213e4697f5eSdrh     if {$leftover>0} {
214e4697f5eSdrh       if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v  Message=$msg"}
215e4697f5eSdrh       set ::go 0
216e4697f5eSdrh       set v {1 1}
217e4697f5eSdrh     } else {
218e4697f5eSdrh       set v2 [expr {$msg=="" || $msg=="out of memory"}]
219e4697f5eSdrh       if {!$v2} {puts "\nError message returned: $msg"}
220e4697f5eSdrh       lappend v $v2
221e4697f5eSdrh     }
222e4697f5eSdrh  } {1 1}
223e4697f5eSdrh}
224ed7c855cSdrhsqlite_malloc_fail 0
225ed7c855cSdrhfinish_test
226