1
0
mirror of https://github.com/signalwire/freeswitch.git synced 2025-08-13 17:38:59 +00:00
Files
build
cmake_modules
conf
debian
docs
dtd
freeswitch.xcodeproj
fscomm
htdocs
libs
apr
apr-util
broadvoice
curl
esl
freetdm
iksemel
ilbc
js
libcodec2
libdingaling
libedit
libg722_1
libnatpmp
libsndfile
libteletone
miniupnpc
openzap
pcre
portaudio
silk
sofia-sip
spandsp
speex
sqlite
art
contrib
ext
notes
src
test
aggerror.test
all.test
alter.test
alter2.test
alter3.test
altermalloc.test
analyze.test
async.test
async2.test
attach.test
attach2.test
attach3.test
attachmalloc.test
auth.test
auth2.test
autoinc.test
autovacuum.test
autovacuum_crash.test
autovacuum_ioerr.test
autovacuum_ioerr2.test
avtrans.test
between.test
bigfile.test
bigrow.test
bind.test
bindxfer.test
blob.test
btree.test
btree2.test
btree4.test
btree5.test
btree6.test
btree7.test
btree8.test
busy.test
capi2.test
capi3.test
capi3b.test
capi3c.test
cast.test
check.test
collate1.test
collate2.test
collate3.test
collate4.test
collate5.test
collate6.test
colmeta.test
conflict.test
corrupt.test
corrupt2.test
crash.test
date.test
default.test
delete.test
delete2.test
delete3.test
descidx1.test
descidx2.test
descidx3.test
diskfull.test
distinctagg.test
enc.test
enc2.test
enc3.test
expr.test
fkey1.test
format4.test
fts1a.test
fts1b.test
fts1c.test
fts1d.test
fts1e.test
fts1f.test
fts1i.test
fts1j.test
fts1porter.test
fts2a.test
fts2b.test
fts2c.test
fts2d.test
fts2e.test
fts2f.test
fts2g.test
fts2h.test
fts2i.test
fts2j.test
func.test
hook.test
in.test
index.test
index2.test
index3.test
insert.test
insert2.test
insert3.test
interrupt.test
intpkey.test
ioerr.test
join.test
join2.test
join3.test
join4.test
join5.test
journal1.test
lastinsert.test
laststmtchanges.test
like.test
limit.test
loadext.test
loadext2.test
lock.test
lock2.test
lock3.test
main.test
malloc.test
malloc2.test
malloc3.test
malloc4.test
malloc5.test
malloc6.test
malloc7.test
manydb.test
memdb.test
memleak.test
minmax.test
misc1.test
misc2.test
misc3.test
misc4.test
misc5.test
misc6.test
misuse.test
notnull.test
null.test
pager.test
pager2.test
pager3.test
pagesize.test
pragma.test
printf.test
progress.test
quick.test
quote.test
reindex.test
rollback.test
rowid.test
safety.test
schema.test
schema2.test
select1.test
select2.test
select3.test
select4.test
select5.test
select6.test
select7.test
server1.test
shared.test
shared2.test
shared3.test
shared_err.test
sort.test
speed1.test
subquery.test
subselect.test
sync.test
table.test
tableapi.test
tclsqlite.test
temptable.test
tester.tcl
thread1.test
thread2.test
threadtest1.c
threadtest2.c
tkt1435.test
tkt1443.test
tkt1444.test
tkt1449.test
tkt1473.test
tkt1501.test
tkt1512.test
tkt1514.test
tkt1536.test
tkt1537.test
tkt1567.test
tkt1644.test
tkt1667.test
tkt1873.test
tkt2141.test
tkt2192.test
tkt2213.test
trace.test
trans.test
trigger1.test
trigger2.test
trigger3.test
trigger4.test
trigger5.test
trigger6.test
trigger7.test
trigger8.test
types.test
types2.test
types3.test
unique.test
update.test
utf16.test
utf16align.test
vacuum.test
vacuum2.test
varint.test
view.test
vtab1.test
vtab2.test
vtab3.test
vtab4.test
vtab5.test
vtab6.test
vtab7.test
vtab9.test
vtab_err.test
where.test
where2.test
where3.test
where4.test
tool
www
.update
Makefile.in
Makefile.linux-gcc
README
VERSION
addopcodes.awk
configure.ac
configure.gnu
main.mk
mkdll.sh
mkopcodec.awk
mkopcodeh.awk
mkso.sh
publish.sh
spec.template
sqlite.pc.in
sqlite3.1
sqlite3.pc.in
tclinstaller.tcl
srtp
stfu
tiff-3.8.2
udns
unimrcp
win32
xmlrpc-c
yaml
.gitignore
patches
scripts
src
support-d
w32
web
.gitignore
.version.in
CMakeLists.txt
Freeswitch.2005.unsupported.sln
Freeswitch.2008.express.sln
Freeswitch.2008.sln
Freeswitch.2008.sln.debug.bat
Freeswitch.2008.sln.release.bat
Freeswitch.2010.express.sln
Freeswitch.2010.sln
INSTALL
Makefile.am
acinclude.m4
bootstrap.sh
configure.in
devel-bootstrap.sh
freeswitch.spec
freeswitch/libs/sqlite/test/shared_err.test

413 lines
12 KiB
Plaintext
Raw Normal View History

# 2005 December 30
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# The focus of the tests in this file are IO errors that occur in a shared
# cache context. What happens to connection B if one connection A encounters
# an IO-error whilst reading or writing the file-system?
#
# $Id: shared_err.test,v 1.9 2006/01/24 16:37:59 danielk1977 Exp $
proc skip {args} {}
set testdir [file dirname $argv0]
source $testdir/tester.tcl
db close
ifcapable !shared_cache||!subquery {
finish_test
return
}
set ::enable_shared_cache [sqlite3_enable_shared_cache 1]
# Todo: This is a copy of the [do_malloc_test] proc in malloc.test
# It would be better if these were consolidated.
# Usage: do_malloc_test <test number> <options...>
#
# The first argument, <test number>, is an integer used to name the
# tests executed by this proc. Options are as follows:
#
# -tclprep TCL script to run to prepare test.
# -sqlprep SQL script to run to prepare test.
# -tclbody TCL script to run with malloc failure simulation.
# -sqlbody TCL script to run with malloc failure simulation.
# -cleanup TCL script to run after the test.
#
# This command runs a series of tests to verify SQLite's ability
# to handle an out-of-memory condition gracefully. It is assumed
# that if this condition occurs a malloc() call will return a
# NULL pointer. Linux, for example, doesn't do that by default. See
# the "BUGS" section of malloc(3).
#
# Each iteration of a loop, the TCL commands in any argument passed
# to the -tclbody switch, followed by the SQL commands in any argument
# passed to the -sqlbody switch are executed. Each iteration the
# Nth call to sqliteMalloc() is made to fail, where N is increased
# each time the loop runs starting from 1. When all commands execute
# successfully, the loop ends.
#
proc do_malloc_test {tn args} {
array unset ::mallocopts
array set ::mallocopts $args
set ::go 1
for {set ::n 1} {$::go && $::n < 50000} {incr ::n} {
do_test shared_malloc-$tn.$::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].
#
sqlite_malloc_fail 0
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}
catch {sqlite3 db test.db}
set ::DB [sqlite3_connection_pointer 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.
#
sqlite_malloc_fail $::n
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 leftover [lindex [sqlite_malloc_stat] 2]
if {$leftover>0} {
if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"}
set ::go 0
if {$v} {
puts "\nError message returned: $msg"
} else {
set v {1 1}
}
} else {
set v2 [expr {$msg=="" || $msg=="out of memory"}]
if {!$v2} {puts "\nError message returned: $msg"}
lappend v $v2
}
} {1 1}
sqlite_malloc_fail 0
if {[info exists ::mallocopts(-cleanup)]} {
catch [list uplevel #0 $::mallocopts(-cleanup)] msg
}
}
unset ::mallocopts
}
do_ioerr_test shared_ioerr-1 -tclprep {
sqlite3 db2 test.db
execsql {
PRAGMA read_uncommitted = 1;
CREATE TABLE t1(a,b,c);
BEGIN;
SELECT * FROM sqlite_master;
} db2
} -sqlbody {
SELECT * FROM sqlite_master;
INSERT INTO t1 VALUES(1,2,3);
BEGIN TRANSACTION;
INSERT INTO t1 VALUES(1,2,3);
INSERT INTO t1 VALUES(4,5,6);
ROLLBACK;
SELECT * FROM t1;
BEGIN TRANSACTION;
INSERT INTO t1 VALUES(1,2,3);
INSERT INTO t1 VALUES(4,5,6);
COMMIT;
SELECT * FROM t1;
DELETE FROM t1 WHERE a<100;
} -cleanup {
do_test shared_ioerr-1.$n.cleanup.1 {
set res [catchsql {
SELECT * FROM t1;
} db2]
set possible_results [list \
"1 {disk I/O error}" \
"0 {1 2 3}" \
"0 {1 2 3 1 2 3 4 5 6}" \
"0 {1 2 3 1 2 3 4 5 6 1 2 3 4 5 6}" \
"0 {}" \
]
set rc [expr [lsearch -exact $possible_results $res] >= 0]
if {$rc != 1} {
puts ""
puts "Result: $res"
}
set rc
} {1}
db2 close
}
do_ioerr_test shared_ioerr-2 -tclprep {
sqlite3 db2 test.db
execsql {
PRAGMA read_uncommitted = 1;
BEGIN;
CREATE TABLE t1(a, b);
INSERT INTO t1(oid) VALUES(NULL);
INSERT INTO t1(oid) SELECT NULL FROM t1;
INSERT INTO t1(oid) SELECT NULL FROM t1;
INSERT INTO t1(oid) SELECT NULL FROM t1;
INSERT INTO t1(oid) SELECT NULL FROM t1;
INSERT INTO t1(oid) SELECT NULL FROM t1;
INSERT INTO t1(oid) SELECT NULL FROM t1;
INSERT INTO t1(oid) SELECT NULL FROM t1;
INSERT INTO t1(oid) SELECT NULL FROM t1;
INSERT INTO t1(oid) SELECT NULL FROM t1;
INSERT INTO t1(oid) SELECT NULL FROM t1;
UPDATE t1 set a = oid, b = 'abcdefghijklmnopqrstuvwxyz0123456789';
CREATE INDEX i1 ON t1(a);
COMMIT;
BEGIN;
SELECT * FROM sqlite_master;
} db2
} -tclbody {
set ::residx 0
execsql {DELETE FROM t1 WHERE 0 = (a % 2);}
incr ::residx
# When this transaction begins the table contains 512 entries. The
# two statements together add 512+146 more if it succeeds.
# (1024/7==146)
execsql {BEGIN;}
execsql {INSERT INTO t1 SELECT a+1, b FROM t1;}
execsql {INSERT INTO t1 SELECT 'string' || a, b FROM t1 WHERE 0 = (a%7);}
execsql {COMMIT;}
incr ::residx
} -cleanup {
do_test shared_ioerr-2.$n.cleanup.1 {
set res [catchsql {
SELECT max(a), min(a), count(*) FROM (SELECT a FROM t1 order by a);
} db2]
set possible_results [list \
{0 {1024 1 1024}} \
{0 {1023 1 512}} \
{0 {string994 1 1170}} \
]
set idx [lsearch -exact $possible_results $res]
set success [expr {$idx==$::residx || $res=="1 {disk I/O error}"}]
if {!$success} {
puts ""
puts "Result: \"$res\" ($::residx)"
}
set success
} {1}
db2 close
}
# This test is designed to provoke an IO error when a cursor position is
# "saved" (because another cursor is going to modify the underlying table).
#
do_ioerr_test shared_ioerr-3 -tclprep {
sqlite3 db2 test.db
execsql {
PRAGMA read_uncommitted = 1;
PRAGMA cache_size = 10;
BEGIN;
CREATE TABLE t1(a, b, UNIQUE(a, b));
} db2
for {set i 0} {$i < 200} {incr i} {
set a [string range [string repeat "[format %03d $i]." 5] 0 end-1]
set b [string repeat $i 2000]
execsql {INSERT INTO t1 VALUES($a, $b)} db2
}
execsql {COMMIT} db2
set ::DB2 [sqlite3_connection_pointer db2]
set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY]
sqlite3_step $::STMT ;# Cursor points at 000.000.000.000
sqlite3_step $::STMT ;# Cursor points at 001.001.001.001
} -tclbody {
execsql {
BEGIN;
INSERT INTO t1 VALUES('201.201.201.201.201', NULL);
UPDATE t1 SET a = '202.202.202.202.202' WHERE a LIKE '201%';
COMMIT;
}
} -cleanup {
do_test shared_ioerr-3.$n.cleanup.1 {
sqlite3_step $::STMT
} {SQLITE_ROW}
do_test shared_ioerr-3.$n.cleanup.2 {
sqlite3_column_text $::STMT 0
} {002.002.002.002.002}
do_test shared_ioerr-3.$n.cleanup.3 {
sqlite3_finalize $::STMT
} {SQLITE_OK}
# db2 eval {select * from sqlite_master}
db2 close
}
# Only run these tests if memory debugging is turned on.
#
if {[info command sqlite_malloc_stat]==""} {
puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..."
db close
sqlite3_enable_shared_cache $::enable_shared_cache
finish_test
return
}
# Provoke a malloc() failure when a cursor position is being saved. This
# only happens with index cursors (because they malloc() space to save the
# current key value). It does not happen with tables, because an integer
# key does not require a malloc() to store.
#
# The library should return an SQLITE_NOMEM to the caller. The query that
# owns the cursor (the one for which the position is not saved) should
# continue unaffected.
#
do_malloc_test 4 -tclprep {
sqlite3 db2 test.db
execsql {
PRAGMA read_uncommitted = 1;
BEGIN;
CREATE TABLE t1(a, b, UNIQUE(a, b));
} db2
for {set i 0} {$i < 5} {incr i} {
set a [string repeat $i 10]
set b [string repeat $i 2000]
execsql {INSERT INTO t1 VALUES($a, $b)} db2
}
execsql {COMMIT} db2
set ::DB2 [sqlite3_connection_pointer db2]
set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY]
sqlite3_step $::STMT ;# Cursor points at 0000000000
sqlite3_step $::STMT ;# Cursor points at 1111111111
} -tclbody {
execsql {
INSERT INTO t1 VALUES(6, NULL);
}
} -cleanup {
do_test shared_malloc-4.$::n.cleanup.1 {
set ::rc [sqlite3_step $::STMT]
expr {$::rc=="SQLITE_ROW" || $::rc=="SQLITE_ABORT"}
} {1}
if {$::rc=="SQLITE_ROW"} {
do_test shared_malloc-4.$::n.cleanup.2 {
sqlite3_column_text $::STMT 0
} {2222222222}
}
do_test shared_malloc-4.$::n.cleanup.3 {
sqlite3_finalize $::STMT
} {SQLITE_OK}
# db2 eval {select * from sqlite_master}
db2 close
}
do_malloc_test 5 -tclbody {
sqlite3 dbX test.db
sqlite3 dbY test.db
dbX close
dbY close
} -cleanup {
catch {dbX close}
catch {dbY close}
}
do_malloc_test 6 -tclbody {
catch {db close}
sqlite3_thread_cleanup
sqlite3_enable_shared_cache 0
} -cleanup {
sqlite3_enable_shared_cache 1
}
do_test shared_misuse-7.1 {
sqlite3 db test.db
catch {
sqlite3_enable_shared_cache 0
} msg
set msg
} {library routine called out of sequence}
# Again provoke a malloc() failure when a cursor position is being saved,
# this time during a ROLLBACK operation by some other handle.
#
# The library should return an SQLITE_NOMEM to the caller. The query that
# owns the cursor (the one for which the position is not saved) should
# be aborted.
#
set ::aborted 0
do_malloc_test 8 -tclprep {
sqlite3 db2 test.db
execsql {
PRAGMA read_uncommitted = 1;
BEGIN;
CREATE TABLE t1(a, b, UNIQUE(a, b));
} db2
for {set i 0} {$i < 2} {incr i} {
set a [string repeat $i 10]
set b [string repeat $i 2000]
execsql {INSERT INTO t1 VALUES($a, $b)} db2
}
execsql {COMMIT} db2
set ::DB2 [sqlite3_connection_pointer db2]
set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY]
sqlite3_step $::STMT ;# Cursor points at 0000000000
sqlite3_step $::STMT ;# Cursor points at 1111111111
} -tclbody {
execsql {
BEGIN;
INSERT INTO t1 VALUES(6, NULL);
ROLLBACK;
}
} -cleanup {
do_test shared_malloc-8.$::n.cleanup.1 {
lrange [execsql {
SELECT a FROM t1;
} db2] 0 1
} {0000000000 1111111111}
do_test shared_malloc-8.$::n.cleanup.2 {
set rc1 [sqlite3_step $::STMT]
set rc2 [sqlite3_finalize $::STMT]
if {$rc1=="SQLITE_ABORT"} {
incr ::aborted
}
expr {
($rc1=="SQLITE_DONE" && $rc2=="SQLITE_OK") ||
($rc1=="SQLITE_ABORT" && $rc2=="SQLITE_OK")
}
} {1}
db2 close
}
do_test shared_malloc-8.X {
# Test that one or more queries were aborted due to the malloc() failure.
expr $::aborted>=1
} {1}
catch {db close}
sqlite3_enable_shared_cache $::enable_shared_cache
finish_test