1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-29 08:01:23 +03:00

Modifications to the malloc failure tests to test transient and persistent failures. (CVS 4321)

FossilOrigin-Name: e38ef81b85feb5bff2ad8448f3438ff0ab36571e
This commit is contained in:
danielk1977
2007-08-29 12:31:25 +00:00
parent 1fee73e74a
commit a1644fd863
40 changed files with 519 additions and 308 deletions

View File

@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The
# focus of this script testing the callback-free C/C++ API.
#
# $Id: capi3.test,v 1.53 2007/08/25 13:37:49 danielk1977 Exp $
# $Id: capi3.test,v 1.54 2007/08/29 12:31:29 danielk1977 Exp $
#
set testdir [file dirname $argv0]
@ -754,7 +754,7 @@ if {[info command sqlite3_memdebug_fail]!=""} {
do_test capi3-10-1 {
sqlite3 db test.db
set DB [sqlite3_connection_pointer db]
sqlite3_memdebug_fail 0 0
sqlite3_memdebug_fail 0
catchsql {
select * from sqlite_master;
}
@ -768,7 +768,7 @@ if {[info command sqlite3_memdebug_fail]!=""} {
} {out of memory}
}
db close
sqlite3_memdebug_fail -1 0
sqlite3_memdebug_fail -1
}
# The following tests - capi3-11.* - test that a COMMIT or ROLLBACK

View File

@ -13,7 +13,7 @@
# This is a copy of the capi3.test file that has been adapted to
# test the new sqlite3_prepare_v2 interface.
#
# $Id: capi3c.test,v 1.10 2007/08/25 13:37:49 danielk1977 Exp $
# $Id: capi3c.test,v 1.11 2007/08/29 12:31:29 danielk1977 Exp $
#
set testdir [file dirname $argv0]
@ -749,7 +749,7 @@ if {[info command sqlite3_memdebug_fail]!=""} {
do_test capi3c-10-1 {
sqlite3 db test.db
set DB [sqlite3_connection_pointer db]
sqlite3_memdebug_fail 0 0
sqlite3_memdebug_fail 0
catchsql {
select * from sqlite_master;
}
@ -763,7 +763,7 @@ if {[info command sqlite3_memdebug_fail]!=""} {
} {out of memory}
}
db close
sqlite3_memdebug_fail -1 0
sqlite3_memdebug_fail -1
}
# The following tests - capi3c-11.* - test that a COMMIT or ROLLBACK

View File

@ -9,7 +9,7 @@
#
#***********************************************************************
#
# $Id: incrblob_err.test,v 1.5 2007/08/27 23:48:24 drh Exp $
# $Id: incrblob_err.test,v 1.6 2007/08/29 12:31:29 danielk1977 Exp $
#
set testdir [file dirname $argv0]
@ -79,7 +79,7 @@ do_malloc_test 3 -tclprep {
error "out of memory"
}
}
sqlite3_memdebug_fail -1 0
sqlite3_memdebug_fail -1
do_ioerr_test incrblob_err-4 -cksum 1 -sqlprep {
CREATE TABLE blobs(k, v BLOB);

View File

@ -16,7 +16,7 @@
# to see what happens in the library if a malloc were to really fail
# due to an out-of-memory situation.
#
# $Id: malloc.test,v 1.44 2007/08/22 20:18:22 drh Exp $
# $Id: malloc.test,v 1.45 2007/08/29 12:31:29 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@ -215,7 +215,8 @@ if {$::sqlite_options(utf16)} {
sqlite3_column_int $::STMT 0
sqlite3_column_text16 $::STMT 1
sqlite3_column_double $::STMT 1
sqlite3_reset $::STMT
set rc [sqlite3_reset $::STMT]
if {$rc eq "SQLITE_NOMEM"} {error "out of memory"}
sqlite3_bind_text16 $::STMT 1 $::bomstr 60
#catch {sqlite3_finalize $::STMT}
#if {[lindex [sqlite_malloc_stat] 2]<=0} {

View File

@ -16,7 +16,7 @@
# Recovery from malloc() failures is automatic. But we keep these
# tests around because you can never have too many test cases.
#
# $Id: malloc2.test,v 1.6 2007/08/22 22:04:37 drh Exp $
# $Id: malloc2.test,v 1.7 2007/08/29 12:31:29 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@ -65,7 +65,7 @@ proc do_malloc2_test {tn args} {
# Run the SQL. Malloc number $::n is set to fail. A malloc() failure
# may or may not be reported.
sqlite3_memdebug_fail $::n 1
sqlite3_memdebug_fail $::n -repeat 1
do_test malloc2-$tn.$::n.2 {
set res [catchsql [string trim $::mallocopts(-sql)]]
set rc [expr {
@ -80,7 +80,7 @@ proc do_malloc2_test {tn args} {
# If $::n is greater than the number of malloc() calls required to
# execute the SQL, then this test is finished. Break out of the loop.
set nFail [sqlite3_memdebug_fail -1 -1]
set nFail [sqlite3_memdebug_fail -1]
if {$nFail==0} break
# Nothing should work now, because the allocator should refuse to

View File

@ -13,7 +13,7 @@
# correctly. The emphasis of these tests are the _prepare(), _step() and
# _finalize() calls.
#
# $Id: malloc3.test,v 1.11 2007/08/22 22:04:37 drh Exp $
# $Id: malloc3.test,v 1.12 2007/08/29 12:31:29 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@ -560,7 +560,7 @@ proc run_test {arglist {pcstart 0} {iFailStart 1}} {
set ::rollback_hook_count 0
set ac [sqlite3_get_autocommit $::DB] ;# Auto-Commit
sqlite3_memdebug_fail $iFail 1
sqlite3_memdebug_fail $iFail -repeat 1
set rc [catch {db eval [lindex $v 1]} msg] ;# True error occurs
set nac [sqlite3_get_autocommit $::DB] ;# New Auto-Commit
@ -575,7 +575,7 @@ proc run_test {arglist {pcstart 0} {iFailStart 1}} {
} {1}
}
set nFail [sqlite3_memdebug_fail -1 -1]
set nFail [sqlite3_memdebug_fail -1]
if {$rc == 0} {
# Successful execution of sql. Our "mallocs-until-failure"
# count should be greater than 0. Otherwise a malloc() failed
@ -639,7 +639,7 @@ db cache size 0
run_test $::run_test_script 9 1
# run_test [lrange $::run_test_script 0 3] 0 63
sqlite3_memdebug_fail -1 -1
sqlite3_memdebug_fail -1
db close
finish_test

View File

@ -12,7 +12,7 @@
# This file contains tests to ensure that the library handles malloc() failures
# correctly. The emphasis in this file is on sqlite3_column_XXX() APIs.
#
# $Id: malloc4.test,v 1.5 2007/08/23 02:47:53 drh Exp $
# $Id: malloc4.test,v 1.6 2007/08/29 12:31:29 danielk1977 Exp $
#---------------------------------------------------------------------------
# NOTES ON EXPECTED BEHAVIOUR
@ -51,7 +51,7 @@ proc do_stmt_test {id sql} {
} {1}
# Set the Nth malloc() to fail.
sqlite3_memdebug_fail $n 1
sqlite3_memdebug_fail $n -repeat 1
# Test malloc failure in the _name(), _name16(), decltype() and
# decltype16() APIs. Calls that occur after the malloc() failure should

View File

@ -10,7 +10,7 @@
#***********************************************************************
# This file contains additional out-of-memory checks (see malloc.tcl).
#
# $Id: mallocA.test,v 1.3 2007/08/22 22:04:37 drh Exp $
# $Id: mallocA.test,v 1.4 2007/08/29 12:31:29 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@ -41,19 +41,19 @@ db close
file copy test.db test.db.bu
do_malloc_test 1 -testdb test.db.bu -sqlbody {
do_malloc_test mallocA-1 -testdb test.db.bu -sqlbody {
ANALYZE
}
do_malloc_test 2 -testdb test.db.bu -sqlbody {
do_malloc_test mallocA-2 -testdb test.db.bu -sqlbody {
REINDEX;
}
do_malloc_test 3 -testdb test.db.bu -sqlbody {
do_malloc_test mallocA-3 -testdb test.db.bu -sqlbody {
REINDEX t1;
}
do_malloc_test 4 -testdb test.db.bu -sqlbody {
do_malloc_test mallocA-4 -testdb test.db.bu -sqlbody {
REINDEX main.t1;
}
do_malloc_test 5 -testdb test.db.bu -sqlbody {
do_malloc_test mallocA-5 -testdb test.db.bu -sqlbody {
REINDEX nocase;
}

View File

@ -12,7 +12,7 @@
# This file tests aspects of the malloc failure while parsing
# CREATE TABLE statements in auto_vacuum mode.
#
# $Id: mallocC.test,v 1.3 2007/08/22 22:04:37 drh Exp $
# $Id: mallocC.test,v 1.4 2007/08/29 12:31:29 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@ -61,7 +61,7 @@ proc do_mallocC_test {tn args} {
# Run the SQL. Malloc number $::n is set to fail. A malloc() failure
# may or may not be reported.
sqlite3_memdebug_fail $::n 1
sqlite3_memdebug_fail $::n -repeat 1
do_test mallocC-$tn.$::n.1 {
set res [catchsql [string trim $::mallocopts(-sql)]]
set rc [expr {
@ -76,7 +76,7 @@ proc do_mallocC_test {tn args} {
# If $::n is greater than the number of malloc() calls required to
# execute the SQL, then this test is finished. Break out of the loop.
set nFail [sqlite3_memdebug_fail -1 -1]
set nFail [sqlite3_memdebug_fail -1]
if {$nFail==0} {
break
}

View File

@ -42,68 +42,90 @@ proc do_malloc_test {tn args} {
set start 1
}
set ::go 1
for {set ::n $start} {$::go && $::n < 50000} {incr ::n} {
do_test $tn.$::n {
foreach ::iRepeat {0 1} {
set ::go 1
for {set ::n $start} {$::go && $::n < 50000} {incr ::n} {
# Remove all traces of database files test.db and test2.db from the files
# system. Then open (empty database) "test.db" with the handle [db].
#
catch {db close}
catch {file delete -force test.db}
catch {file delete -force test.db-journal}
catch {file delete -force test2.db}
catch {file delete -force test2.db-journal}
if {[info exists ::mallocopts(-testdb)]} {
file copy $::mallocopts(-testdb) test.db
}
catch {sqlite3 db test.db}
# Execute any -tclprep and -sqlprep scripts.
# If $::iRepeat is 0, then the malloc() failure is transient - it
# fails and then subsequent calls succeed. If $::iRepeat is 1,
# then the failure is persistent - once malloc() fails it keeps
# failing.
#
if {[info exists ::mallocopts(-tclprep)]} {
eval $::mallocopts(-tclprep)
}
if {[info exists ::mallocopts(-sqlprep)]} {
execsql $::mallocopts(-sqlprep)
}
set zRepeat "transient"
if {$::iRepeat} {set zRepeat "persistent"}
# Now set the ${::n}th malloc() to fail and execute the -tclbody and
# -sqlbody scripts.
#
sqlite3_memdebug_fail $::n 1
set ::mallocbody {}
if {[info exists ::mallocopts(-tclbody)]} {
append ::mallocbody "$::mallocopts(-tclbody)\n"
}
if {[info exists ::mallocopts(-sqlbody)]} {
append ::mallocbody "db eval {$::mallocopts(-sqlbody)}"
}
set v [catch $::mallocbody msg]
set failFlag [sqlite3_memdebug_fail -1 0]
set go [expr {$failFlag>0}]
if {$failFlag==0} {
if {$v} {
set v2 $msg
} else {
set v 1
set v2 1
do_test ${tn}.${zRepeat}.${::n} {
# Remove all traces of database files test.db and test2.db
# from the file-system. Then open (empty database) "test.db"
# with the handle [db].
#
catch {db close}
catch {file delete -force test.db}
catch {file delete -force test.db-journal}
catch {file delete -force test2.db}
catch {file delete -force test2.db-journal}
if {[info exists ::mallocopts(-testdb)]} {
file copy $::mallocopts(-testdb) test.db
}
catch {sqlite3 db test.db}
# Execute any -tclprep and -sqlprep scripts.
#
if {[info exists ::mallocopts(-tclprep)]} {
eval $::mallocopts(-tclprep)
}
if {[info exists ::mallocopts(-sqlprep)]} {
execsql $::mallocopts(-sqlprep)
}
# Now set the ${::n}th malloc() to fail and execute the -tclbody
# and -sqlbody scripts.
#
sqlite3_memdebug_fail $::n -repeat $::iRepeat
set ::mallocbody {}
if {[info exists ::mallocopts(-tclbody)]} {
append ::mallocbody "$::mallocopts(-tclbody)\n"
}
if {[info exists ::mallocopts(-sqlbody)]} {
append ::mallocbody "db eval {$::mallocopts(-sqlbody)}"
}
} elseif {!$v} {
set v2 $msg
} elseif {[info command db]=="" || [db errorcode]==7
|| $msg=="out of memory"} {
set v2 1
} else {
set v2 $msg
}
lappend v $v2
} {1 1}
if {[info exists ::mallocopts(-cleanup)]} {
catch [list uplevel #0 $::mallocopts(-cleanup)] msg
# The following block sets local variables as follows:
#
# isFail - True if an error (any error) was reported by sqlite.
# nFail - The total number of simulated malloc() failures.
# nBenign - The number of benign simulated malloc() failures.
#
set isFail [catch $::mallocbody msg]
set nFail [sqlite3_memdebug_fail -1 -benigncnt nBenign]
#puts "isFail=$isFail nFail=$nFail nBenign=$nBenign msg=$msg"
# If one or more mallocs failed, run this loop body again.
#
set go [expr {$nFail>0}]
if {($nFail-$nBenign)==0} {
if {$isFail} {
set v2 $msg
} else {
set isFail 1
set v2 1
}
} elseif {!$isFail} {
set v2 $msg
} elseif {[info command db]=="" || [db errorcode]==7
|| $msg=="out of memory"} {
set v2 1
} else {
set v2 $msg
}
lappend isFail $v2
} {1 1}
if {[info exists ::mallocopts(-cleanup)]} {
catch [list uplevel #0 $::mallocopts(-cleanup)] msg
}
}
}
unset ::mallocopts

View File

@ -9,7 +9,7 @@
#
#***********************************************************************
#
# $Id: vtab_err.test,v 1.6 2007/08/25 13:37:49 danielk1977 Exp $
# $Id: vtab_err.test,v 1.7 2007/08/29 12:31:29 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@ -40,7 +40,7 @@ do_ioerr_test vtab_err-1 -tclprep {
COMMIT;
}
do_malloc_test vtab_err-2 -tclprep {
do_malloc_test vtab_err-2 -tclprep {
register_echo_module [sqlite3_connection_pointer db]
} -sqlbody {
BEGIN;
@ -58,6 +58,6 @@ do_malloc_test vtab_err-2 -tclprep {
COMMIT;
}
sqlite3_memdebug_fail -1 0
sqlite3_memdebug_fail -1
finish_test