2N/A
2N/A#pragma ident "%Z%%M% %I% %E% SMI"
2N/A
2N/A# 2001 September 15
2N/A#
2N/A# The author disclaims copyright to this source code. In place of
2N/A# a legal notice, here is a blessing:
2N/A#
2N/A# May you do good and not evil.
2N/A# May you find forgiveness for yourself and forgive others.
2N/A# May you share freely, never taking more than you give.
2N/A#
2N/A#***********************************************************************
2N/A# This file attempts to check the library in an out-of-memory situation.
2N/A# When compiled with -DMEMORY_DEBUG=1, the SQLite library accepts a special
2N/A# command (sqlite_malloc_fail N) which causes the N-th malloc to fail. This
2N/A# special feature is used to see what happens in the library if a malloc
2N/A# were to really fail due to an out-of-memory situation.
2N/A#
2N/A# $Id: malloc.test,v 1.6 2004/02/14 01:39:50 drh Exp $
2N/A
2N/Aset testdir [file dirname $argv0]
2N/Asource $testdir/tester.tcl
2N/A
2N/A# Only run these tests if memory debugging is turned on.
2N/A#
2N/Aif {[info command sqlite_malloc_stat]==""} {
2N/A puts "Skipping malloc tests: not compiled with -DMEMORY_DEBUG..."
2N/A finish_test
2N/A return
2N/A}
2N/A
2N/Afor {set go 1; set i 1} {$go} {incr i} {
2N/A do_test malloc-1.$i {
2N/A sqlite_malloc_fail 0
2N/A catch {db close}
2N/A catch {file delete -force test.db}
2N/A catch {file delete -force test.db-journal}
2N/A sqlite_malloc_fail $i
2N/A set v [catch {sqlite db test.db} msg]
2N/A if {$v} {
2N/A set msg ""
2N/A } else {
2N/A set v [catch {execsql {
2N/A CREATE TABLE t1(
2N/A a int, b float, c double, d text, e varchar(20),
2N/A primary key(a,b,c)
2N/A );
2N/A CREATE INDEX i1 ON t1(a,b);
2N/A INSERT INTO t1 VALUES(1,2.3,4.5,'hi','there');
2N/A INSERT INTO t1 VALUES(6,7.0,0.8,'hello','out yonder');
2N/A SELECT * FROM t1;
2N/A SELECT avg(b) FROM t1 GROUP BY a HAVING b>20.0;
2N/A DELETE FROM t1 WHERE a IN (SELECT min(a) FROM t1);
2N/A SELECT count(*) FROM t1;
2N/A }} msg]
2N/A }
2N/A set leftover [lindex [sqlite_malloc_stat] 2]
2N/A if {$leftover>0} {
2N/A if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"}
2N/A set ::go 0
2N/A set v {1 1}
2N/A } else {
2N/A set v2 [expr {$msg=="" || $msg=="out of memory"}]
2N/A if {!$v2} {puts "\nError message returned: $msg"}
2N/A lappend v $v2
2N/A }
2N/A } {1 1}
2N/A}
2N/A
2N/Aset fd [open ./data.tmp w]
2N/Afor {set i 1} {$i<=20} {incr i} {
2N/A puts $fd "$i\t[expr {$i*$i}]\t[expr {100-$i}] abcdefghijklmnopqrstuvwxyz"
2N/A}
2N/Aclose $fd
2N/A
2N/Afor {set go 1; set i 1} {$go} {incr i} {
2N/A do_test malloc-2.$i {
2N/A sqlite_malloc_fail 0
2N/A catch {db close}
2N/A catch {file delete -force test.db}
2N/A catch {file delete -force test.db-journal}
2N/A sqlite_malloc_fail $i
2N/A set v [catch {sqlite db test.db} msg]
2N/A if {$v} {
2N/A set msg ""
2N/A } else {
2N/A set v [catch {execsql {
2N/A CREATE TABLE t1(a int, b int, c int);
2N/A CREATE INDEX i1 ON t1(a,b);
2N/A COPY t1 FROM 'data.tmp';
2N/A SELECT 'stuff', count(*) as 'other stuff', max(a+10) FROM t1;
2N/A UPDATE t1 SET b=b||b||b||b;
2N/A UPDATE t1 SET b=a WHERE a in (10,12,22);
2N/A INSERT INTO t1(c,b,a) VALUES(20,10,5);
2N/A INSERT INTO t1 SELECT * FROM t1
2N/A WHERE a IN (SELECT a FROM t1 WHERE a<10);
2N/A DELETE FROM t1 WHERE a>=10;
2N/A DROP INDEX i1;
2N/A DELETE FROM t1;
2N/A }} msg]
2N/A }
2N/A set leftover [lindex [sqlite_malloc_stat] 2]
2N/A if {$leftover>0} {
2N/A if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"}
2N/A set ::go 0
2N/A set v {1 1}
2N/A } else {
2N/A set v2 [expr {$msg=="" || $msg=="out of memory"}]
2N/A if {!$v2} {puts "\nError message returned: $msg"}
2N/A lappend v $v2
2N/A }
2N/A } {1 1}
2N/A}
2N/A
2N/Aset fd [open ./data.tmp w]
2N/Afor {set i 1} {$i<=10} {incr i} {
2N/A puts $fd "$i\t[expr {$i*$i}]\t[expr {100-$i}]"
2N/A}
2N/Aclose $fd
2N/A
2N/Afor {set go 1; set i 1} {$go} {incr i} {
2N/A do_test malloc-3.$i {
2N/A sqlite_malloc_fail 0
2N/A catch {db close}
2N/A catch {file delete -force test.db}
2N/A catch {file delete -force test.db-journal}
2N/A sqlite_malloc_fail $i
2N/A set v [catch {sqlite db test.db} msg]
2N/A if {$v} {
2N/A set msg ""
2N/A } else {
2N/A set v [catch {execsql {
2N/A BEGIN TRANSACTION;
2N/A CREATE TABLE t1(a int, b int, c int);
2N/A CREATE INDEX i1 ON t1(a,b);
2N/A COPY t1 FROM 'data.tmp';
2N/A INSERT INTO t1(c,b,a) VALUES(20,10,5);
2N/A DELETE FROM t1 WHERE a>=10;
2N/A DROP INDEX i1;
2N/A DELETE FROM t1;
2N/A ROLLBACK;
2N/A }} msg]
2N/A }
2N/A set leftover [lindex [sqlite_malloc_stat] 2]
2N/A if {$leftover>0} {
2N/A if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"}
2N/A set ::go 0
2N/A set v {1 1}
2N/A } else {
2N/A set v2 [expr {$msg=="" || $msg=="out of memory"}]
2N/A if {!$v2} {puts "\nError message returned: $msg"}
2N/A lappend v $v2
2N/A }
2N/A } {1 1}
2N/A}
2N/Afor {set go 1; set i 1} {$go} {incr i} {
2N/A do_test malloc-4.$i {
2N/A sqlite_malloc_fail 0
2N/A catch {db close}
2N/A catch {file delete -force test.db}
2N/A catch {file delete -force test.db-journal}
2N/A sqlite_malloc_fail $i
2N/A set v [catch {sqlite db test.db} msg]
2N/A if {$v} {
2N/A set msg ""
2N/A } else {
2N/A set v [catch {execsql {
2N/A BEGIN TRANSACTION;
2N/A CREATE TABLE t1(a int, b int, c int);
2N/A CREATE INDEX i1 ON t1(a,b);
2N/A COPY t1 FROM 'data.tmp';
2N/A UPDATE t1 SET b=a WHERE a in (10,12,22);
2N/A INSERT INTO t1 SELECT * FROM t1
2N/A WHERE a IN (SELECT a FROM t1 WHERE a<10);
2N/A DROP INDEX i1;
2N/A DELETE FROM t1;
2N/A COMMIT;
2N/A }} msg]
2N/A }
2N/A set leftover [lindex [sqlite_malloc_stat] 2]
2N/A if {$leftover>0} {
2N/A if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"}
2N/A set ::go 0
2N/A set v {1 1}
2N/A } else {
2N/A set v2 [expr {$msg=="" || $msg=="out of memory"}]
2N/A if {!$v2} {puts "\nError message returned: $msg"}
2N/A lappend v $v2
2N/A }
2N/A } {1 1}
2N/A}
2N/Afor {set go 1; set i 1} {$go} {incr i} {
2N/A do_test malloc-5.$i {
2N/A sqlite_malloc_fail 0
2N/A catch {db close}
2N/A catch {file delete -force test.db}
2N/A catch {file delete -force test.db-journal}
2N/A sqlite_malloc_fail $i
2N/A set v [catch {sqlite db test.db} msg]
2N/A if {$v} {
2N/A set msg ""
2N/A } else {
2N/A set v [catch {execsql {
2N/A BEGIN TRANSACTION;
2N/A CREATE TABLE t1(a,b);
2N/A CREATE TABLE t2(x,y);
2N/A CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN
2N/A INSERT INTO t2(x,y) VALUES(new.rowid,1);
2N/A END;
2N/A INSERT INTO t1(a,b) VALUES(2,3);
2N/A COMMIT;
2N/A }} msg]
2N/A }
2N/A set leftover [lindex [sqlite_malloc_stat] 2]
2N/A if {$leftover>0} {
2N/A if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"}
2N/A set ::go 0
2N/A set v {1 1}
2N/A } else {
2N/A set v2 [expr {$msg=="" || $msg=="out of memory"}]
2N/A if {!$v2} {puts "\nError message returned: $msg"}
2N/A lappend v $v2
2N/A }
2N/A } {1 1}
2N/A}
2N/Asqlite_malloc_fail 0
2N/Afinish_test