diff options
author | dan <dan@noemail.net> | 2010-06-01 19:15:18 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2010-06-01 19:15:18 +0000 |
commit | 0235ab99446dcd772402e82c69871f6fc16b38ef (patch) | |
tree | c058255b00ecc40eaf314a879d81c4e23d66aeb3 /src | |
parent | a4bc123f832b2636f5240c150c9a7f8d6fadab05 (diff) | |
download | sqlite-0235ab99446dcd772402e82c69871f6fc16b38ef.tar.gz sqlite-0235ab99446dcd772402e82c69871f6fc16b38ef.zip |
Changes to the way faults are injected into xShmXXX VFS calls.
FossilOrigin-Name: 716d99f3929b466c7a17190e0f18de8ab0e7f1fa
Diffstat (limited to 'src')
-rw-r--r-- | src/test_vfs.c | 175 |
1 files changed, 134 insertions, 41 deletions
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); |