1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

Add fault-injection and other tests (and fixes) to improve coverage of vdbesort.c.

FossilOrigin-Name: 0e6defa6aa540b413ea3f4bb6dcd86364d547067
This commit is contained in:
dan
2011-08-08 16:44:25 +00:00
parent 01204728f1
commit 5279112ea3
6 changed files with 314 additions and 13 deletions

View File

@ -1,5 +1,5 @@
C Fix\sa\sproblem\swith\sbuilding\slarge\sindexes\sintroduced\sby\sthe\sprevious\scommit. C Add\sfault-injection\sand\sother\stests\s(and\sfixes)\sto\simprove\scoverage\sof\svdbesort.c.
D 2011-08-06T15:09:33.468 D 2011-08-08T16:44:25.654
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in c1d7a7f4fd8da6b1815032efca950e3d5125407e F Makefile.in c1d7a7f4fd8da6b1815032efca950e3d5125407e
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -245,7 +245,7 @@ F src/vdbeapi.c 11dc47987abacb76ad016dcf5abc0dc422482a98
F src/vdbeaux.c 8fb978eb73a97b34d352dd3ef3bff35b1b3fa7e9 F src/vdbeaux.c 8fb978eb73a97b34d352dd3ef3bff35b1b3fa7e9
F src/vdbeblob.c f024f0bf420f36b070143c32b15cc7287341ffd3 F src/vdbeblob.c f024f0bf420f36b070143c32b15cc7287341ffd3
F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b
F src/vdbesort.c 345235345a414bf387f1254fe3695bb566bf66d7 F src/vdbesort.c e9a7d969bd5a85fc7b9f42865a71b834d26442be
F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114 F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114
F src/vtab.c 901791a47318c0562cd0c676a2c6ff1bc530e582 F src/vtab.c 901791a47318c0562cd0c676a2c6ff1bc530e582
F src/wal.c 0c70ad7b1cac6005fa5e2cbefd23ee05e391c290 F src/wal.c 0c70ad7b1cac6005fa5e2cbefd23ee05e391c290
@ -511,8 +511,9 @@ F test/incrvacuum_ioerr.test 57d2f5777ab13fa03b87b262a4ea1bad5cfc0291
F test/index.test b5429732b3b983fa810e3ac867d7ca85dae35097 F test/index.test b5429732b3b983fa810e3ac867d7ca85dae35097
F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6 F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6
F test/index3.test 423a25c789fc8cc51aaf2a4370bbdde2d9e9eed7 F test/index3.test 423a25c789fc8cc51aaf2a4370bbdde2d9e9eed7
F test/index4.test 8d737e87536cba23d4567096b6432116e2ba896f F test/index4.test c82a59c9ae2ac01804bdb100162dca057318f40f
F test/indexedby.test be501e381b82b2f8ab406309ba7aac46e221f4ad F test/indexedby.test be501e381b82b2f8ab406309ba7aac46e221f4ad
F test/indexfault.test 758a11b2e0c00609c227fa10136e9edcd1200c7f
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
F test/insert.test aef273dd1cee84cc92407469e6bd1b3cdcb76908 F test/insert.test aef273dd1cee84cc92407469e6bd1b3cdcb76908
F test/insert2.test 4f3a04d168c728ed5ec2c88842e772606c7ce435 F test/insert2.test 4f3a04d168c728ed5ec2c88842e772606c7ce435
@ -618,7 +619,7 @@ F test/pageropt.test 8146bf448cf09e87bb1867c2217b921fb5857806
F test/pagesize.test 76aa9f23ecb0741a4ed9d2e16c5fa82671f28efb F test/pagesize.test 76aa9f23ecb0741a4ed9d2e16c5fa82671f28efb
F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16 F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16
F test/pcache2.test 0d85f2ab6963aee28c671d4c71bec038c00a1d16 F test/pcache2.test 0d85f2ab6963aee28c671d4c71bec038c00a1d16
F test/permutations.test aae89941ca0968b53633c97b5dd0d6f9f9899d27 F test/permutations.test bfe51414b7c355a6dfb8803176808dc2e00e3783
F test/pragma.test fdfc09067ea104a0c247a1a79d8093b56656f850 F test/pragma.test fdfc09067ea104a0c247a1a79d8093b56656f850
F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47 F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47
F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea
@ -954,7 +955,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5
F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
F tool/warnings.sh 2ebae31e1eb352696f3c2f7706a34c084b28c262 F tool/warnings.sh 2ebae31e1eb352696f3c2f7706a34c084b28c262
P 8051c1767c4386b0f14a66742d9fac41e001eb07 P 038ec9ea92f7661358580d999adc400da14d47f0
R 93dcea351d8a57ea1935b884e502f99e R bca0e64155bd4edc59b1ae2d567af815
U dan U dan
Z c870855eb410ccb3672032b9f318773d Z 7ff7f4144c189044a56c845ca9d84e7e

View File

@ -1 +1 @@
038ec9ea92f7661358580d999adc400da14d47f0 0e6defa6aa540b413ea3f4bb6dcd86364d547067

View File

@ -398,6 +398,8 @@ static int vdbeSorterBtreeToPMA(sqlite3 *db, VdbeCursor *pCsr){
aMalloc = sqlite3DbReallocOrFree(db, aMalloc, nKey); aMalloc = sqlite3DbReallocOrFree(db, aMalloc, nKey);
if( !aMalloc ){ if( !aMalloc ){
rc = SQLITE_NOMEM; rc = SQLITE_NOMEM;
}else{
nMalloc = nKey;
} }
} }
@ -410,9 +412,10 @@ static int vdbeSorterBtreeToPMA(sqlite3 *db, VdbeCursor *pCsr){
} }
} }
if( rc!=SQLITE_OK ) break;
} }
assert( pSorter->nBtree==( assert( rc!=SQLITE_OK || pSorter->nBtree==(
iWriteOff-pSorter->iWriteOff-sqlite3VarintLen(pSorter->nBtree) iWriteOff-pSorter->iWriteOff-sqlite3VarintLen(pSorter->nBtree)
)); ));
pSorter->iWriteOff = iWriteOff; pSorter->iWriteOff = iWriteOff;
@ -648,6 +651,13 @@ int sqlite3VdbeSorterRowkey(sqlite3 *db, VdbeCursor *pCsr, Mem *pOut){
VdbeSorterIter *pIter; VdbeSorterIter *pIter;
pIter = &pSorter->aIter[ pSorter->aTree[1] ]; pIter = &pSorter->aIter[ pSorter->aTree[1] ];
/* Coverage testing note: As things are currently, this call will always
** succeed. This is because the memory cell passed by the VDBE layer
** happens to be the same one as was used to assemble the keys before they
** were passed to the sorter - meaning it is always large enough for the
** largest key. But this could change very easily, so we leave the call
** to sqlite3VdbeMemGrow() in. */
if( sqlite3VdbeMemGrow(pOut, pIter->nKey, 0) ){ if( sqlite3VdbeMemGrow(pOut, pIter->nKey, 0) ){
return SQLITE_NOMEM; return SQLITE_NOMEM;
} }

View File

@ -67,4 +67,46 @@ ifcapable memorymanage {
} }
do_execsql_test 1.6 {
BEGIN;
DROP TABLE t1;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES('a');
INSERT INTO t1 VALUES('b');
INSERT INTO t1 VALUES('c');
INSERT INTO t1 VALUES('d');
INSERT INTO t1 VALUES('e');
INSERT INTO t1 VALUES('f');
INSERT INTO t1 VALUES('g');
INSERT INTO t1 VALUES(NULL);
INSERT INTO t1 SELECT randomblob(1202) FROM t1; -- 16
INSERT INTO t1 SELECT randomblob(2202) FROM t1; -- 32
INSERT INTO t1 SELECT randomblob(3202) FROM t1; -- 64
INSERT INTO t1 SELECT randomblob(4202) FROM t1; -- 128
INSERT INTO t1 SELECT randomblob(5202) FROM t1; -- 256
COMMIT;
CREATE INDEX i1 ON t1(x);
PRAGMA integrity_check
} {ok}
do_execsql_test 1.7 {
BEGIN;
DROP TABLE t1;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES('a');
COMMIT;
CREATE INDEX i1 ON t1(x);
PRAGMA integrity_check
} {ok}
do_execsql_test 1.8 {
BEGIN;
DROP TABLE t1;
CREATE TABLE t1(x);
COMMIT;
CREATE INDEX i1 ON t1(x);
PRAGMA integrity_check
} {ok}
finish_test finish_test

248
test/indexfault.test Normal file
View File

@ -0,0 +1,248 @@
# 2011 August 08
#
# 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.
#
#***********************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/lock_common.tcl
source $testdir/malloc_common.tcl
set testprefix indexfault
#-------------------------------------------------------------------------
# These tests - indexfault-1.* - Build an index on a smallish table with
# all different kinds of fault-injection. The CREATE INDEX is run once
# with default options and once with a 50KB soft-heap-limit.
#
do_execsql_test 1.0 {
BEGIN;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES(randomblob(202));
INSERT INTO t1 SELECT randomblob(202) FROM t1; -- 2
INSERT INTO t1 SELECT randomblob(202) FROM t1; -- 4
INSERT INTO t1 SELECT randomblob(202) FROM t1; -- 8
INSERT INTO t1 SELECT randomblob(202) FROM t1; -- 16
INSERT INTO t1 SELECT randomblob(202) FROM t1; -- 32
INSERT INTO t1 SELECT randomblob(202) FROM t1; -- 64
INSERT INTO t1 SELECT randomblob(202) FROM t1; -- 128
INSERT INTO t1 SELECT randomblob(202) FROM t1; -- 256
COMMIT;
}
faultsim_save_and_close
do_faultsim_test 1.1 -prep {
faultsim_restore_and_reopen
} -body {
execsql { CREATE INDEX i1 ON t1(x) }
faultsim_test_result {0 {}}
faultsim_integrity_check
}
ifcapable memorymanage {
set soft_limit [sqlite3_soft_heap_limit 50000]
do_faultsim_test 2.1 -prep {
faultsim_restore_and_reopen
} -body {
execsql { CREATE INDEX i1 ON t1(x) }
faultsim_test_result {0 {}}
}
sqlite3_soft_heap_limit $soft_limit
}
#-------------------------------------------------------------------------
# These are similar to the indexfault-1.* tests, except they create an
# index with more than one column.
#
sqlite3 db test.db
do_execsql_test 2.0 {
BEGIN;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(t,u,v,w,x,y,z);
INSERT INTO t1 VALUES(
randomblob(30), randomblob(30), randomblob(30), randomblob(30),
randomblob(30), randomblob(30), randomblob(30)
);
INSERT INTO t1 SELECT
randomblob(30), randomblob(30), randomblob(30), randomblob(30),
randomblob(30), randomblob(30), randomblob(30) FROM t1; -- 2
INSERT INTO t1 SELECT
randomblob(30), randomblob(30), randomblob(30), randomblob(30),
randomblob(30), randomblob(30), randomblob(30) FROM t1; -- 4
INSERT INTO t1 SELECT
randomblob(30), randomblob(30), randomblob(30), randomblob(30),
randomblob(30), randomblob(30), randomblob(30) FROM t1; -- 8
INSERT INTO t1 SELECT
randomblob(30), randomblob(30), randomblob(30), randomblob(30),
randomblob(30), randomblob(30), randomblob(30) FROM t1; -- 16
INSERT INTO t1 SELECT
randomblob(30), randomblob(30), randomblob(30), randomblob(30),
randomblob(30), randomblob(30), randomblob(30) FROM t1; -- 32
INSERT INTO t1 SELECT
randomblob(30), randomblob(30), randomblob(30), randomblob(30),
randomblob(30), randomblob(30), randomblob(30) FROM t1; -- 64
INSERT INTO t1 SELECT
randomblob(30), randomblob(30), randomblob(30), randomblob(30),
randomblob(30), randomblob(30), randomblob(30) FROM t1; -- 128
COMMIT;
}
faultsim_save_and_close
do_faultsim_test 2.1 -prep {
faultsim_restore_and_reopen
} -body {
execsql { CREATE INDEX i1 ON t1(t,u,v,w,x,y,z) }
faultsim_test_result {0 {}}
faultsim_integrity_check
}
ifcapable memorymanage {
set soft_limit [sqlite3_soft_heap_limit 50000]
do_faultsim_test 2.2 -prep {
faultsim_restore_and_reopen
} -body {
execsql { CREATE INDEX i1 ON t1(t,u,v,w,x,y,z) }
faultsim_test_result {0 {}}
}
sqlite3_soft_heap_limit $soft_limit
}
#-------------------------------------------------------------------------
# The following tests - indexfault-2.* - all attempt to build a index
# on table t1 in the main database with injected IO errors. Individual
# test cases work as follows:
#
# 3.1: IO errors injected into xOpen() calls.
# 3.2: As 7.1, but with a low (50KB) soft-heap-limit.
#
# 3.3: IO errors injected into the first 200 write() calls made on the
# second temporary file.
# 3.4: As 7.3, but with a low (50KB) soft-heap-limit.
#
#
# Set up the custom fault-injector. This is further configured by using
# different values for $::custom_filter and different implementations
# of Tcl proc [xCustom] for each test case.
#
set FAULTSIM(custom) [list \
-injectinstall custom_injectinstall \
-injectstart custom_injectstart \
-injectstop custom_injectstop \
-injecterrlist {{1 {disk I/O error}}} \
-injectuninstall custom_injectuninstall \
]
proc custom_injectinstall {} {
testvfs shmfault -default true
shmfault filter $::custom_filter
shmfault script xCustom
}
proc custom_injectuninstall {} {
catch {db close}
catch {db2 close}
shmfault delete
}
set ::custom_ifail -1
set ::custom_nfail -1
proc custom_injectstart {iFail} {
set ::custom_ifail $iFail
set ::custom_nfail 0
}
proc custom_injectstop {} {
set ::custom_ifail -1
return $::custom_nfail
}
# Set up a table to build indexes on. Save the setup using the
# [faultsim_save_and_close] mechanism.
#
sqlite3 db test.db
do_execsql_test 3.0 {
BEGIN;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES(randomblob(11000));
INSERT INTO t1 SELECT randomblob(11001) FROM t1; -- 2
INSERT INTO t1 SELECT randomblob(11002) FROM t1; -- 4
INSERT INTO t1 SELECT randomblob(11003) FROM t1; -- 8
INSERT INTO t1 SELECT randomblob(11004) FROM t1; -- 16
INSERT INTO t1 SELECT randomblob(11005) FROM t1; -- 32
INSERT INTO t1 SELECT randomblob(11006) FROM t1; -- 64
INSERT INTO t1 SELECT randomblob(11007) FROM t1; -- 128
INSERT INTO t1 SELECT randomblob(11008) FROM t1; -- 256
INSERT INTO t1 SELECT randomblob(11009) FROM t1; -- 512
COMMIT;
}
faultsim_save_and_close
set ::custom_filter xOpen
proc xCustom {args} {
incr ::custom_ifail -1
if {$::custom_ifail==0} {
incr ::custom_nfail
return "SQLITE_IOERR"
}
return "SQLITE_OK"
}
do_faultsim_test 3.1 -faults custom -prep {
faultsim_restore_and_reopen
} -body {
execsql { CREATE INDEX i1 ON t1(x) }
faultsim_test_result {0 {}}
}
ifcapable memorymanage {
set soft_limit [sqlite3_soft_heap_limit 50000]
do_faultsim_test 3.2 -faults custom -prep {
faultsim_restore_and_reopen
} -body {
execsql { CREATE INDEX i1 ON t1(x) }
faultsim_test_result {0 {}}
}
sqlite3_soft_heap_limit $soft_limit
}
set ::custom_filter {xOpen xWrite}
proc xCustom {method args} {
if {$method == "xOpen"} {
if {[lindex $args 0] == ""} {
incr ::nTmpOpen 1
if {$::nTmpOpen == 3} { return "failme" }
}
return "SQLITE_OK"
}
if {$::custom_ifail<200 && [lindex $args 1] == "failme"} {
incr ::custom_ifail -1
if {$::custom_ifail==0} {
incr ::custom_nfail
return "SQLITE_IOERR"
}
}
return "SQLITE_OK"
}
do_faultsim_test 3.3 -faults custom -prep {
faultsim_restore_and_reopen
set ::nTmpOpen 0
} -body {
execsql { CREATE INDEX i1 ON t1(x) }
faultsim_test_result {0 {}}
}
ifcapable memorymanage {
set soft_limit [sqlite3_soft_heap_limit 50000]
do_faultsim_test 3.4 -faults custom -prep {
faultsim_restore_and_reopen
set ::nTmpOpen 0
} -body {
execsql { CREATE INDEX i1 ON t1(x) }
faultsim_test_result {0 {}}
}
sqlite3_soft_heap_limit $soft_limit
}
finish_test

View File

@ -111,7 +111,7 @@ set allquicktests [test_set $alltests -exclude {
thread003.test thread004.test thread005.test trans2.test vacuum3.test thread003.test thread004.test thread005.test trans2.test vacuum3.test
incrvacuum_ioerr.test autovacuum_crash.test btree8.test shared_err.test incrvacuum_ioerr.test autovacuum_crash.test btree8.test shared_err.test
vtab_err.test walslow.test walcrash.test vtab_err.test walslow.test walcrash.test
walthread.test rtree3.test walthread.test rtree3.test indexfault.test
}] }]
if {[info exists ::env(QUICKTEST_INCLUDE)]} { if {[info exists ::env(QUICKTEST_INCLUDE)]} {
set allquicktests [concat $allquicktests $::env(QUICKTEST_INCLUDE)] set allquicktests [concat $allquicktests $::env(QUICKTEST_INCLUDE)]