diff options
-rw-r--r-- | manifest | 14 | ||||
-rw-r--r-- | manifest.uuid | 2 | ||||
-rw-r--r-- | src/test_vfs.c | 175 | ||||
-rw-r--r-- | test/walfault.test | 29 |
4 files changed, 154 insertions, 66 deletions
@@ -1,5 +1,5 @@ -C Change\sthe\sOOM\sand\sIO\serror\stest\scases\sin\swalfault.test\sso\sthat\seach\stest\scase\sruns\sboth\stypes\sof\serror\ssimulation. -D 2010-06-01T17:46:38 +C Changes\sto\sthe\sway\sfaults\sare\sinjected\sinto\sxShmXXX\sVFS\scalls. +D 2010-06-01T19:15:19 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -207,7 +207,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 4f4f121f7d508101a2b33d166567f4ccd226b5ad +F src/test_vfs.c fe1eda8d3910823d9edc26113f91bb292369850a F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c 25ceb0f0a746ea1d0f9553787f3f0a56853cfaeb F src/trigger.c 8927588cb9e6d47f933b53bfe74200fbb504100d @@ -767,7 +767,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 c3c5478d23742ef887bec54fe7de9b0c1de07e1e +F test/walfault.test 9015004b56bc2cb8cf5c96183853f1157e61ff70 F test/walhook.test 67e675127f4acb72f061a12667ce6e5460b06b78 F test/walmode.test 6ca9d710cc9f6545b913abcded6d6b0b15641048 F test/walslow.test d21625e2e99e11c032ce949e8a94661576548933 @@ -815,7 +815,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P b1abfaaf5309cc0d0dda4fb2c237862c8cf83261 -R 0d10d60aa1f988cbb877d394e9ed3639 +P b627e1536822bb7e3ef91867661a53be0efc13ef +R 61962739bee4b134d51f0c50b54806e9 U dan -Z c5ae99887497d633a8a1fd47de534f18 +Z 398c600fb787a366135f57477d6a61d0 diff --git a/manifest.uuid b/manifest.uuid index dde174137..470c2bba3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b627e1536822bb7e3ef91867661a53be0efc13ef
\ No newline at end of file +716d99f3929b466c7a17190e0f18de8ab0e7f1fa
\ No newline at end of file diff --git a/src/test_vfs.c b/src/test_vfs.c index d5e8ea1fa..fda44a725 100644 --- a/src/test_vfs.c +++ b/src/test_vfs.c @@ -48,6 +48,10 @@ struct Testvfs { Tcl_Obj **apScript; /* Script to execute */ TestvfsBuffer *pBuffer; /* List of shared buffers */ int isNoshm; + + int mask; + int iIoerrCnt; + int ioerr; }; /* @@ -61,6 +65,16 @@ struct TestvfsBuffer { TestvfsBuffer *pNext; /* Next in linked list of all buffers */ }; +#define TESTVFS_SHMOPEN_MASK 0x00000001 +#define TESTVFS_SHMSIZE_MASK 0x00000002 +#define TESTVFS_SHMGET_MASK 0x00000004 +#define TESTVFS_SHMRELEASE_MASK 0x00000008 +#define TESTVFS_SHMLOCK_MASK 0x00000010 +#define TESTVFS_SHMBARRIER_MASK 0x00000020 +#define TESTVFS_SHMCLOSE_MASK 0x00000040 + +#define TESTVFS_ALL_MASK 0x0000007F + #define PARENTVFS(x) (((Testvfs *)((x)->pAppData))->pParent) @@ -459,7 +473,10 @@ static int tvfsShmOpen( ** connection is named "anon". Otherwise, the value returned by the ** script is used as the connection name. */ - tvfsExecTcl(p, "xShmOpen", Tcl_NewStringObj(pFd->zFilename, -1), 0, 0); + Tcl_ResetResult(p->interp); + if( p->mask&TESTVFS_SHMOPEN_MASK ){ + tvfsExecTcl(p, "xShmOpen", Tcl_NewStringObj(pFd->zFilename, -1), 0, 0); + } if( tvfsResultCode(p, &rc) ){ if( rc!=SQLITE_OK ) return rc; pId = Tcl_NewStringObj("anon", -1); @@ -498,10 +515,12 @@ static int tvfsShmSize( TestvfsFile *pFd = (TestvfsFile *)pFile; Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData); - tvfsExecTcl(p, "xShmSize", - Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, 0 - ); - tvfsResultCode(p, &rc); + if( p->mask&TESTVFS_SHMSIZE_MASK ){ + tvfsExecTcl(p, "xShmSize", + Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, 0 + ); + tvfsResultCode(p, &rc); + } if( rc==SQLITE_OK ){ tvfsGrowBuffer(pFd, reqSize, pNewSize); } @@ -518,10 +537,12 @@ static int tvfsShmGet( TestvfsFile *pFd = (TestvfsFile *)pFile; Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData); - tvfsExecTcl(p, "xShmGet", - Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, 0 - ); - tvfsResultCode(p, &rc); + if( p->mask&TESTVFS_SHMGET_MASK ){ + tvfsExecTcl(p, "xShmGet", + Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, 0 + ); + tvfsResultCode(p, &rc); + } if( rc==SQLITE_OK ){ tvfsGrowBuffer(pFd, reqMapSize, pMapSize); *pp = pFd->pShm->a; @@ -534,10 +555,12 @@ static int tvfsShmRelease(sqlite3_file *pFile){ TestvfsFile *pFd = (TestvfsFile *)pFile; Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData); - tvfsExecTcl(p, "xShmRelease", - Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, 0 - ); - tvfsResultCode(p, &rc); + if( p->mask&TESTVFS_SHMRELEASE_MASK ){ + tvfsExecTcl(p, "xShmRelease", + Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, 0 + ); + tvfsResultCode(p, &rc); + } return rc; } @@ -554,36 +577,38 @@ static int tvfsShmLock( int nLock; char zLock[80]; - sqlite3_snprintf(sizeof(zLock), zLock, "%d %d", ofst, n); - nLock = strlen(zLock); - if( flags & SQLITE_SHM_LOCK ){ - strcpy(&zLock[nLock], " lock"); - }else{ - strcpy(&zLock[nLock], " unlock"); - } - nLock += strlen(&zLock[nLock]); - if( flags & SQLITE_SHM_SHARED ){ - strcpy(&zLock[nLock], " shared"); - }else{ - strcpy(&zLock[nLock], " exclusive"); + if( p->mask&TESTVFS_SHMLOCK_MASK ){ + sqlite3_snprintf(sizeof(zLock), zLock, "%d %d", ofst, n); + nLock = strlen(zLock); + if( flags & SQLITE_SHM_LOCK ){ + strcpy(&zLock[nLock], " lock"); + }else{ + strcpy(&zLock[nLock], " unlock"); + } + nLock += strlen(&zLock[nLock]); + if( flags & SQLITE_SHM_SHARED ){ + strcpy(&zLock[nLock], " shared"); + }else{ + strcpy(&zLock[nLock], " exclusive"); + } + tvfsExecTcl(p, "xShmLock", + Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, + Tcl_NewStringObj(zLock, -1) + ); + tvfsResultCode(p, &rc); } - tvfsExecTcl(p, "xShmLock", - Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, - Tcl_NewStringObj(zLock, -1) - ); - tvfsResultCode(p, &rc); return rc; } static void tvfsShmBarrier(sqlite3_file *pFile){ - int rc = SQLITE_OK; TestvfsFile *pFd = (TestvfsFile *)pFile; Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData); - tvfsExecTcl(p, "xShmBarrier", - Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, 0 - ); - tvfsResultCode(p, &rc); + if( p->mask&TESTVFS_SHMBARRIER_MASK ){ + tvfsExecTcl(p, "xShmBarrier", + Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, 0 + ); + } } static int tvfsShmClose( @@ -600,10 +625,12 @@ static int tvfsShmClose( assert( (deleteFlag!=0)==(pBuffer->nRef==1) ); #endif - tvfsExecTcl(p, "xShmClose", - Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, 0 - ); - tvfsResultCode(p, &rc); + if( p->mask&TESTVFS_SHMCLOSE_MASK ){ + tvfsExecTcl(p, "xShmClose", + Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, 0 + ); + tvfsResultCode(p, &rc); + } pBuffer->nRef--; if( pBuffer->nRef==0 ){ @@ -628,8 +655,8 @@ static int testvfs_obj_cmd( ){ Testvfs *p = (Testvfs *)cd; - static const char *CMD_strs[] = { "shm", "delete", 0 }; - enum DB_enum { CMD_SHM, CMD_DELETE }; + static const char *CMD_strs[] = { "shm", "delete", "filter", "ioerr", 0 }; + enum DB_enum { CMD_SHM, CMD_DELETE, CMD_FILTER, CMD_IOERR }; int i; if( objc<2 ){ @@ -667,6 +694,71 @@ static int testvfs_obj_cmd( Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pBuffer->a, pBuffer->n)); break; } + + case CMD_FILTER: { + static struct VfsMethod { + char *zName; + int mask; + } vfsmethod [] = { + { "xShmOpen", TESTVFS_SHMOPEN_MASK }, + { "xShmSize", TESTVFS_SHMSIZE_MASK }, + { "xShmGet", TESTVFS_SHMGET_MASK }, + { "xShmRelease", TESTVFS_SHMRELEASE_MASK }, + { "xShmLock", TESTVFS_SHMLOCK_MASK }, + { "xShmBarrier", TESTVFS_SHMBARRIER_MASK }, + { "xShmClose", TESTVFS_SHMCLOSE_MASK }, + }; + Tcl_Obj **apElem = 0; + int nElem = 0; + int i; + int mask = 0; + if( objc!=3 ){ + Tcl_WrongNumArgs(interp, 2, objv, "LIST"); + return TCL_ERROR; + } + if( Tcl_ListObjGetElements(interp, objv[2], &nElem, &apElem) ){ + return TCL_ERROR; + } + Tcl_ResetResult(interp); + for(i=0; i<nElem; i++){ + int iMethod; + char *zElem = Tcl_GetString(apElem[i]); + for(iMethod=0; iMethod<ArraySize(vfsmethod); iMethod++){ + if( strcmp(zElem, vfsmethod[iMethod].zName)==0 ){ + mask |= vfsmethod[iMethod].mask; + break; + } + } + if( iMethod==ArraySize(vfsmethod) ){ + Tcl_AppendResult(interp, "unknown method: ", zElem, 0); + return TCL_ERROR; + } + } + p->mask = mask; + break; + } + + case CMD_IOERR: { + int iRet = ((p->iIoerrCnt<0) ? (1+(p->iIoerrCnt*-1)) : 0); + if( objc==2 ){ + p->ioerr = 0; + p->iIoerrCnt = 0; + }else if( objc==4 ){ + int iCnt, iPersist; + if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iCnt) + || TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &iPersist) + ){ + return TCL_ERROR; + } + p->ioerr = (iPersist!=0) + 1; + p->iIoerrCnt = iCnt; + }else{ + Tcl_AppendResult(interp, "Bad args", 0); + } + Tcl_SetObjResult(interp, Tcl_NewIntObj(iRet)); + break; + } + case CMD_DELETE: { Tcl_DeleteCommand(interp, Tcl_GetString(objv[0])); break; @@ -804,6 +896,7 @@ static int testvfs_cmd( pVfs->szOsFile += p->pParent->szOsFile; p->pVfs = pVfs; p->isNoshm = isNoshm; + p->mask = TESTVFS_ALL_MASK; Tcl_CreateObjCommand(interp, zVfs, testvfs_obj_cmd, p, testvfs_obj_del); sqlite3_vfs_register(pVfs, 0); diff --git a/test/walfault.test b/test/walfault.test index 05b26dad6..499f794bb 100644 --- a/test/walfault.test +++ b/test/walfault.test @@ -92,10 +92,10 @@ do_faultsim_test walfault-2 -prep { execsql { SELECT count(*) FROM x } } -test { - # Test that all the rows in the WAL were recovered. faultsim_test_result {0 8} # Run the integrity_check to make sure nothing strange has occurred. + # set ic [db eval { PRAGMA integrity_check }] if {$ic != "ok"} { error "Integrity check: $ic" } } @@ -138,7 +138,6 @@ do_faultsim_test walfault-3 -prep { # # $::shmfault_ioerr_countdown # $::shmfault_ioerr_persist -# $::shmfault_ioerr_methods # proc shmfault_vfs_cb {method args} { @@ -146,13 +145,11 @@ proc shmfault_vfs_cb {method args} { # if {[info exists ::shmfault_ioerr_countdown]==0} { return SQLITE_OK } - if {[info exists ::shmfault_ioerr_methods($method)]} { - incr ::shmfault_ioerr_countdown -1 - if { ($::shmfault_ioerr_countdown==0) - || ($::shmfault_ioerr_countdown<=0 && $::shmfault_ioerr_persist) - } { - return SQLITE_IOERR - } + incr ::shmfault_ioerr_countdown -1 + if { ($::shmfault_ioerr_countdown==0) + || ($::shmfault_ioerr_countdown<=0 && $::shmfault_ioerr_persist) + } { + return SQLITE_IOERR } return SQLITE_OK } @@ -174,9 +171,7 @@ proc do_shmfault_test {name args} { # Create a VFS to use: testvfs shmfault shmfault_vfs_cb - - unset -nocomplain ::shmfault_ioerr_methods - foreach m $A(-methods) { set ::shmfault_ioerr_methods($m) 1 } + shmfault filter $A(-methods) foreach mode {transient persistent} { set ::shmfault_ioerr_persist [expr {$mode == "persistent"}] @@ -239,7 +234,7 @@ do_shmfault_test walfault-shm-2 -methods xShmSize -sqlprep { do_shmfault_test walfault-shm-3 -methods xShmSize -tclprep { sqlite3 db test.db -vfs shmfault - unset -nocomplain ::shmfault_ioerr_countdown + shmfault filter {} db eval { PRAGMA page_size = 512; PRAGMA journal_mode = WAL; @@ -265,9 +260,9 @@ do_shmfault_test walfault-shm-3 -methods xShmSize -tclprep { } set ::shmfault_ioerr_countdown 1 - set ::shmfault_ioerr_methods(xShmGet) 1 + shmfault filter xShmGet db close - unset ::shmfault_ioerr_methods(xShmGet) + shmfault filter {} if {[file exists test.db-wal]==0} {error "Failed to create WAL file!"} sqlite3 db test.db -vfs shmfault @@ -291,9 +286,9 @@ do_shmfault_test walfault-shm-4 -tclprep { } set ::shmfault_ioerr_countdown 1 - set ::shmfault_ioerr_methods(xShmGet) 1 + shmfault filter xShmGet db close - unset ::shmfault_ioerr_methods(xShmGet) + shmfault filter {} if {[file exists test.db-wal]==0} {error "Failed to create WAL file!"} sqlite3 db test.db -vfs shmfault } -sqlbody { |