1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-05 15:55:57 +03:00

Add some fault-injection tests to improve coverage.

FossilOrigin-Name: 37b26d125f4b1d8e75bb38800fefd145611f94aa
This commit is contained in:
dan
2010-06-14 07:53:26 +00:00
parent 4280eb3004
commit 5d656852f7
5 changed files with 144 additions and 47 deletions

View File

@@ -1,5 +1,5 @@
C Fix\ssome\sproblems\swith\shandling\sIO\serrors\son\sthe\sexperimental\sbranch.
D 2010-06-12T12:02:36
C Add\ssome\sfault-injection\stests\sto\simprove\scoverage.
D 2010-06-14T07:53:26
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -209,7 +209,7 @@ F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0
F src/test_server.c bbba05c144b5fc4b52ff650a4328027b3fa5fcc6
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
F src/test_thread.c aa9919c885a1fe53eafc73492f0898ee6c0a0726
F src/test_vfs.c c3643e985b000e1f7555bd843a508512a33ab60e
F src/test_vfs.c 15bddcddf6b1bf6360130e09aee950f5f563d5f3
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/tokenize.c 25ceb0f0a746ea1d0f9553787f3f0a56853cfaeb
F src/trigger.c 8927588cb9e6d47f933b53bfe74200fbb504100d
@@ -226,7 +226,7 @@ F src/vdbeblob.c 5327132a42a91e8b7acfb60b9d2c3b1c5c863e0e
F src/vdbemem.c 2a82f455f6ca6f78b59fb312f96054c04ae0ead1
F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2
F src/vtab.c a0f8a40274e4261696ef57aa806de2776ab72cda
F src/wal.c ca3e0bf68c78005dee4e0d44d112e26975476d10
F src/wal.c 75c55049c0923418f10bbef842b846374637b595
F src/wal.h 4ace25262452d17e7d3ec970c89ee17794004008
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
F src/where.c 1c895bef33d0dfc7ed90fb1f74120435d210ea56
@@ -772,7 +772,7 @@ F test/walbak.test e7650a26eb4b8abeca9b145b1af1e63026dde432
F test/walcksum.test 4efa8fb88c32bed8288ea4385a9cc113a5c8f0bf
F test/walcrash.test f6d5fb2bb108876f04848720a488065d9deef69f
F test/walcrash2.test 14585ad1a2c85da2de721caa3b4deeea55213008
F test/walfault.test 0f9524cedbba0e5d48b58cabdc2dd7ae2c375476
F test/walfault.test f6c1d0eade34fd0102e083726092d9bebd48bf7b
F test/walhook.test 67e675127f4acb72f061a12667ce6e5460b06b78
F test/walmode.test 6ca9d710cc9f6545b913abcded6d6b0b15641048
F test/walslow.test d21625e2e99e11c032ce949e8a94661576548933
@@ -820,7 +820,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P ca68472db01c14a899892007d1cbaff5e86ae193
R 8c9eec4fce430c14365187b617d56771
P eade8bc238df580412f5cf1b91a91532ae671e46
R d24014573c5813c3e5f096c2f4031503
U dan
Z 808594079cf8cc56f07144318e40eca2
Z e43653a42fa5b8fa5bb9c7db25e1bbd8

View File

@@ -1 +1 @@
eade8bc238df580412f5cf1b91a91532ae671e46
37b26d125f4b1d8e75bb38800fefd145611f94aa

View File

@@ -659,6 +659,7 @@ static int tvfsShmPage(
if( p->pScript && p->mask&TESTVFS_SHMPAGE_MASK ){
Tcl_Obj *pArg = Tcl_NewObj();
Tcl_IncrRefCount(pArg);
Tcl_ListObjAppendElement(p->interp, pArg, Tcl_NewIntObj(iPage));
Tcl_ListObjAppendElement(p->interp, pArg, Tcl_NewIntObj(pgsz));
Tcl_ListObjAppendElement(p->interp, pArg, Tcl_NewIntObj(isWrite));
@@ -666,6 +667,7 @@ static int tvfsShmPage(
Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, pArg
);
tvfsResultCode(p, &rc);
Tcl_DecrRefCount(pArg);
}
if( rc==SQLITE_OK && p->mask&TESTVFS_SHMPAGE_MASK && tvfsInjectIoerr(p) ){
rc = SQLITE_IOERR;
@@ -828,12 +830,17 @@ static int testvfs_obj_cmd(
Tcl_WrongNumArgs(interp, 2, objv, "FILE ?VALUE?");
return TCL_ERROR;
}
zName = Tcl_GetString(objv[2]);
zName = ckalloc(p->pParent->mxPathname);
p->pParent->xFullPathname(
p->pParent, Tcl_GetString(objv[2]),
p->pParent->mxPathname, zName
);
for(pBuffer=p->pBuffer; pBuffer; pBuffer=pBuffer->pNext){
if( 0==strcmp(pBuffer->zFile, zName) ) break;
}
ckfree(zName);
if( !pBuffer ){
Tcl_AppendResult(interp, "no such file: ", zName, 0);
Tcl_AppendResult(interp, "no such file: ", Tcl_GetString(objv[2]), 0);
return TCL_ERROR;
}
if( objc==4 ){
@@ -870,6 +877,7 @@ static int testvfs_obj_cmd(
{ "xShmLock", TESTVFS_SHMLOCK_MASK },
{ "xShmBarrier", TESTVFS_SHMBARRIER_MASK },
{ "xShmClose", TESTVFS_SHMCLOSE_MASK },
{ "xShmPage", TESTVFS_SHMPAGE_MASK },
{ "xSync", TESTVFS_SYNC_MASK },
{ "xOpen", TESTVFS_OPEN_MASK },
};
@@ -911,6 +919,7 @@ static int testvfs_obj_cmd(
ckfree((char *)p->apScript);
p->apScript = 0;
p->nScript = 0;
p->pScript = 0;
}
Tcl_GetStringFromObj(objv[2], &nByte);
if( nByte>0 ){
@@ -1083,6 +1092,13 @@ static int testvfs_cmd(
p = (Testvfs *)ckalloc(nByte);
memset(p, 0, nByte);
/* Create the new object command before querying SQLite for a default VFS
** to use for 'real' IO operations. This is because creating the new VFS
** may delete an existing [testvfs] VFS of the same name. If such a VFS
** is currently the default, the new [testvfs] may end up calling the
** methods of a deleted object.
*/
Tcl_CreateObjCommand(interp, zVfs, testvfs_obj_cmd, p, testvfs_obj_del);
p->pParent = sqlite3_vfs_find(0);
p->interp = interp;
@@ -1099,7 +1115,6 @@ static int testvfs_cmd(
p->isNoshm = isNoshm;
p->mask = TESTVFS_ALL_MASK;
Tcl_CreateObjCommand(interp, zVfs, testvfs_obj_cmd, p, testvfs_obj_del);
sqlite3_vfs_register(pVfs, isDefault);
return TCL_OK;

View File

@@ -1281,6 +1281,13 @@ static void walMergesort(
#endif
}
/*
** Free an iterator allocated by walIteratorInit().
*/
static void walIteratorFree(WalIterator *p){
sqlite3_free(p);
}
/*
** Map the wal-index into memory owned by this thread, if it is not
** mapped already. Then construct a WalInterator object that can be
@@ -1337,6 +1344,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
rc = walHashGet(pWal, i, &aHash, &aPgno, &iZero);
if( rc!=SQLITE_OK ){
walIteratorFree(p);
return rc;
}
nEntry = ((i+1)==nSegment)?iLast-iZero:(u32 *)aHash-(u32 *)&aPgno[iZero+1];
@@ -1361,13 +1369,6 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
return SQLITE_OK ;
}
/*
** Free an iterator allocated by walIteratorInit().
*/
static void walIteratorFree(WalIterator *p){
sqlite3_free(p);
}
/*
** Copy as much content as we can from the WAL back into the database file
** in response to an sqlite3_wal_checkpoint() request or the equivalent.
@@ -2076,8 +2077,11 @@ int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx){
Pgno iMax = pWal->hdr.mxFrame;
Pgno iFrame;
rc = walIndexReadHdr(pWal, &unused);
if( rc==SQLITE_OK ){
/* Restore the clients cache of the wal-index header to the state it
** was in before the client began writing to the database.
*/
memcpy(&pWal->hdr, walIndexHdr(pWal), sizeof(WalIndexHdr));
for(iFrame=pWal->hdr.mxFrame+1;
ALWAYS(rc==SQLITE_OK) && iFrame<=iMax;
iFrame++
@@ -2099,7 +2103,7 @@ int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx){
}
walCleanupHash(pWal);
}
}
assert( rc==SQLITE_OK );
return rc;
}
@@ -2142,10 +2146,8 @@ int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){
pWal->hdr.mxFrame = aWalData[0];
pWal->hdr.aFrameCksum[0] = aWalData[1];
pWal->hdr.aFrameCksum[1] = aWalData[2];
if( rc==SQLITE_OK ){
walCleanupHash(pWal);
}
}
return rc;
}

View File

@@ -120,6 +120,7 @@ do_faultsim_test walfault-3 -prep {
faultsim_test_result {0 {}}
}
#--------------------------------------------------------------------------
#
faultsim_delete_and_reopen
@@ -152,7 +153,7 @@ do_test walfault-5-pre-1 {
do_faultsim_test walfault-5 -faults shmerr* -prep {
faultsim_restore_and_reopen
execsql { PRAGMA wal_autocheckpoint = 0 }
shmfault filter xShmSize
shmfault filter xShmPage
} -body {
execsql {
CREATE TABLE t1(x);
@@ -211,7 +212,7 @@ do_test walfault-6-pre-1 {
} {}
do_faultsim_test walfault-6 -faults shmerr* -prep {
faultsim_restore_and_reopen
shmfault filter xShmSize
shmfault filter xShmPage
} -body {
execsql { SELECT count(*) FROM t1 }
} -test {
@@ -326,7 +327,7 @@ do_test walfault-10-pre1 {
faultsim_delete_and_reopen
execsql {
PRAGMA journal_mode = WAL;
PRAGMA wal_checkpoint = 0;
PRAGMA wal_autocheckpoint = 0;
CREATE TABLE z(zz INTEGER PRIMARY KEY, zzz BLOB);
CREATE INDEX zzzz ON z(zzz);
INSERT INTO z VALUES(NULL, randomblob(800));
@@ -363,5 +364,84 @@ do_faultsim_test walfault-10 -prep {
if {$n != "64 51200"} { error "Incorrect data: $n" }
}
#--------------------------------------------------------------------------
# Test fault injection while checkpointing a large WAL file, if the
# checkpoint is the first operation run after opening the database.
# This means that some of the required wal-index pages are mapped as part of
# the checkpoint process, which means there are a few more opportunities
# for IO errors.
#
# To speed this up, IO errors are only simulated within xShmPage() calls.
#
do_test walfault-11-pre-1 {
sqlite3 db test.db
execsql {
PRAGMA journal_mode = WAL;
PRAGMA wal_autocheckpoint = 0;
BEGIN;
CREATE TABLE abc(a PRIMARY KEY);
INSERT INTO abc VALUES(randomblob(1500));
INSERT INTO abc VALUES(randomblob(1500));
INSERT INTO abc SELECT randomblob(1500) FROM abc; -- 4
INSERT INTO abc SELECT randomblob(1500) FROM abc; -- 8
INSERT INTO abc SELECT randomblob(1500) FROM abc; -- 16
INSERT INTO abc SELECT randomblob(1500) FROM abc; -- 32
INSERT INTO abc SELECT randomblob(1500) FROM abc; -- 64
INSERT INTO abc SELECT randomblob(1500) FROM abc; -- 128
INSERT INTO abc SELECT randomblob(1500) FROM abc; -- 256
INSERT INTO abc SELECT randomblob(1500) FROM abc; -- 512
INSERT INTO abc SELECT randomblob(1500) FROM abc; -- 1024
INSERT INTO abc SELECT randomblob(1500) FROM abc; -- 2048
INSERT INTO abc SELECT randomblob(1500) FROM abc; -- 4096
COMMIT;
}
faultsim_save_and_close
} {}
do_faultsim_test walfault-11 -faults shmerr* -prep {
catch { db2 close }
faultsim_restore_and_reopen
shmfault filter xShmPage
} -body {
db eval { SELECT count(*) FROM abc }
sqlite3 db2 test.db -vfs shmfault
db2 eval { PRAGMA wal_checkpoint }
} -test {
faultsim_test_result {0 {}}
}
#-------------------------------------------------------------------------
# Test the handling of the various IO/OOM/SHM errors that may occur during
# a log recovery operation undertaken as part of a call to
# sqlite3_wal_checkpoint().
#
do_test walfault-12-pre-1 {
faultsim_delete_and_reopen
execsql {
PRAGMA journal_mode = WAL;
PRAGMA wal_autocheckpoint = 0;
BEGIN;
CREATE TABLE abc(a PRIMARY KEY);
INSERT INTO abc VALUES(randomblob(1500));
INSERT INTO abc VALUES(randomblob(1500));
COMMIT;
}
faultsim_save_and_close
} {}
do_faultsim_test walfault-12 -prep {
if {[info commands shmfault] == ""} {
testvfs shmfault -default true
}
faultsim_restore_and_reopen
db eval { SELECT * FROM sqlite_master }
shmfault shm test.db [string repeat "\000" 40]
} -body {
set rc [sqlite3_wal_checkpoint db]
if {$rc != "SQLITE_OK"} { error [sqlite3_errmsg db] }
} -test {
db close
faultsim_test_result {0 {}}
}
finish_test