mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Add tests to pager1.test and pagerfault.test.
FossilOrigin-Name: 008513ee6115f8d6f4b4e1428c1c638282b971a3
This commit is contained in:
16
manifest
16
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Add\sextra\spager\stests.
|
C Add\stests\sto\spager1.test\sand\spagerfault.test.
|
||||||
D 2010-06-28T19:04:02
|
D 2010-06-29T10:30:24
|
||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||||
F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3
|
F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@@ -209,7 +209,7 @@ F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0
|
|||||||
F src/test_server.c bbba05c144b5fc4b52ff650a4328027b3fa5fcc6
|
F src/test_server.c bbba05c144b5fc4b52ff650a4328027b3fa5fcc6
|
||||||
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
|
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
|
||||||
F src/test_thread.c aa9919c885a1fe53eafc73492f0898ee6c0a0726
|
F src/test_thread.c aa9919c885a1fe53eafc73492f0898ee6c0a0726
|
||||||
F src/test_vfs.c 90d51963dfe2aa28a9408b461cb06f48921be8e8
|
F src/test_vfs.c 2291fd22726e499830e9958563e760effaf9e9af
|
||||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||||
F src/tokenize.c 25ceb0f0a746ea1d0f9553787f3f0a56853cfaeb
|
F src/tokenize.c 25ceb0f0a746ea1d0f9553787f3f0a56853cfaeb
|
||||||
F src/trigger.c 67e95c76d625b92d43409ace771c8e0d02a09ac2
|
F src/trigger.c 67e95c76d625b92d43409ace771c8e0d02a09ac2
|
||||||
@@ -534,9 +534,9 @@ F test/notify2.test 195a467e021f74197be2c4fb02d6dee644b8d8db
|
|||||||
F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347
|
F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347
|
||||||
F test/null.test a8b09b8ed87852742343b33441a9240022108993
|
F test/null.test a8b09b8ed87852742343b33441a9240022108993
|
||||||
F test/openv2.test af02ed0a9cbc0d2a61b8f35171d4d117e588e4ec
|
F test/openv2.test af02ed0a9cbc0d2a61b8f35171d4d117e588e4ec
|
||||||
F test/pager1.test 634c62f8c321fb5b72b4c8fa27340bd8e9db9089
|
F test/pager1.test 28709653e83ce9557a983cce251ff02112d5ecca
|
||||||
F test/pager2.test f5c757c271ce642d36a393ecbfb3aef1c240dcef
|
F test/pager2.test f5c757c271ce642d36a393ecbfb3aef1c240dcef
|
||||||
F test/pagerfault.test 210fae669249a06ef0c08da1e75b9bda7e9bf66b
|
F test/pagerfault.test e7fd4e54fb362ec16ce3474842ed7af390d88de0
|
||||||
F test/pagerfault2.test 1287f123bd5d20452113739ed7755fd254e502f1
|
F test/pagerfault2.test 1287f123bd5d20452113739ed7755fd254e502f1
|
||||||
F test/pageropt.test 8146bf448cf09e87bb1867c2217b921fb5857806
|
F test/pageropt.test 8146bf448cf09e87bb1867c2217b921fb5857806
|
||||||
F test/pagesize.test 76aa9f23ecb0741a4ed9d2e16c5fa82671f28efb
|
F test/pagesize.test 76aa9f23ecb0741a4ed9d2e16c5fa82671f28efb
|
||||||
@@ -828,7 +828,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
|||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||||
P 3b68cb9c656db8c5c481199919a98f5764f7ebfa
|
P 6b7e419ddc241f457dd69878f09f5c51c70aa379
|
||||||
R 3cf749e0c461e6688a0dd44d86bc37c3
|
R d8452c9c3029633c6ea47d4358dc9dd2
|
||||||
U dan
|
U dan
|
||||||
Z cd8f9170613084e79dc0108e44d902f9
|
Z 673ae6c021fa890a23c09b0dc8b30087
|
||||||
|
@@ -1 +1 @@
|
|||||||
6b7e419ddc241f457dd69878f09f5c51c70aa379
|
008513ee6115f8d6f4b4e1428c1c638282b971a3
|
111
src/test_vfs.c
111
src/test_vfs.c
@@ -13,6 +13,21 @@
|
|||||||
*/
|
*/
|
||||||
#if SQLITE_TEST /* This file is used for testing only */
|
#if SQLITE_TEST /* This file is used for testing only */
|
||||||
|
|
||||||
|
/*
|
||||||
|
** This file contains the implementation of the Tcl [testvfs] command,
|
||||||
|
** used to create SQLite VFS implementations with various properties and
|
||||||
|
** instrumentation to support testing SQLite.
|
||||||
|
**
|
||||||
|
** testvfs VFSNAME ?OPTIONS?
|
||||||
|
**
|
||||||
|
** Available options are:
|
||||||
|
**
|
||||||
|
** -noshm BOOLEAN (True to omit shm methods. Default false)
|
||||||
|
** -default BOOLEAN (True to make the vfs default. Default false)
|
||||||
|
** -szosfile INTEGER (Value for sqlite3_vfs.szOsFile)
|
||||||
|
** -mxpathname INTEGER (Value for sqlite3_vfs.mxPathname)
|
||||||
|
*/
|
||||||
|
|
||||||
#include "sqlite3.h"
|
#include "sqlite3.h"
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -20,12 +35,18 @@ typedef struct Testvfs Testvfs;
|
|||||||
typedef struct TestvfsShm TestvfsShm;
|
typedef struct TestvfsShm TestvfsShm;
|
||||||
typedef struct TestvfsBuffer TestvfsBuffer;
|
typedef struct TestvfsBuffer TestvfsBuffer;
|
||||||
typedef struct TestvfsFile TestvfsFile;
|
typedef struct TestvfsFile TestvfsFile;
|
||||||
|
typedef struct TestvfsFd TestvfsFd;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** An open file handle.
|
** An open file handle.
|
||||||
*/
|
*/
|
||||||
struct TestvfsFile {
|
struct TestvfsFile {
|
||||||
sqlite3_file base; /* Base class. Must be first */
|
sqlite3_file base; /* Base class. Must be first */
|
||||||
|
TestvfsFd *pFd; /* File data */
|
||||||
|
};
|
||||||
|
#define tvfsGetFd(pFile) (((TestvfsFile *)pFile)->pFd)
|
||||||
|
|
||||||
|
struct TestvfsFd {
|
||||||
sqlite3_vfs *pVfs; /* The VFS */
|
sqlite3_vfs *pVfs; /* The VFS */
|
||||||
const char *zFilename; /* Filename as passed to xOpen() */
|
const char *zFilename; /* Filename as passed to xOpen() */
|
||||||
sqlite3_file *pReal; /* The real, underlying file descriptor */
|
sqlite3_file *pReal; /* The real, underlying file descriptor */
|
||||||
@@ -34,9 +55,10 @@ struct TestvfsFile {
|
|||||||
TestvfsBuffer *pShm; /* Shared memory buffer */
|
TestvfsBuffer *pShm; /* Shared memory buffer */
|
||||||
u32 excllock; /* Mask of exclusive locks */
|
u32 excllock; /* Mask of exclusive locks */
|
||||||
u32 sharedlock; /* Mask of shared locks */
|
u32 sharedlock; /* Mask of shared locks */
|
||||||
TestvfsFile *pNext; /* Next handle opened on the same file */
|
TestvfsFd *pNext; /* Next handle opened on the same file */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define FAULT_INJECT_NONE 0
|
#define FAULT_INJECT_NONE 0
|
||||||
#define FAULT_INJECT_TRANSIENT 1
|
#define FAULT_INJECT_TRANSIENT 1
|
||||||
#define FAULT_INJECT_PERSISTENT 2
|
#define FAULT_INJECT_PERSISTENT 2
|
||||||
@@ -118,7 +140,7 @@ struct TestvfsBuffer {
|
|||||||
char *zFile; /* Associated file name */
|
char *zFile; /* Associated file name */
|
||||||
int pgsz; /* Page size */
|
int pgsz; /* Page size */
|
||||||
u8 *aPage[TESTVFS_MAX_PAGES]; /* Array of ckalloc'd pages */
|
u8 *aPage[TESTVFS_MAX_PAGES]; /* Array of ckalloc'd pages */
|
||||||
TestvfsFile *pFile; /* List of open handles */
|
TestvfsFd *pFile; /* List of open handles */
|
||||||
TestvfsBuffer *pNext; /* Next in linked list of all buffers */
|
TestvfsBuffer *pNext; /* Next in linked list of all buffers */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -296,7 +318,9 @@ static void tvfsExecTcl(
|
|||||||
** Close an tvfs-file.
|
** Close an tvfs-file.
|
||||||
*/
|
*/
|
||||||
static int tvfsClose(sqlite3_file *pFile){
|
static int tvfsClose(sqlite3_file *pFile){
|
||||||
TestvfsFile *pFd = (TestvfsFile *)pFile;
|
int rc;
|
||||||
|
TestvfsFile *pTestfile = (TestvfsFile *)pFile;
|
||||||
|
TestvfsFd *pFd = pTestfile->pFd;
|
||||||
Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
|
Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
|
||||||
|
|
||||||
if( p->pScript && p->mask&TESTVFS_CLOSE_MASK ){
|
if( p->pScript && p->mask&TESTVFS_CLOSE_MASK ){
|
||||||
@@ -312,7 +336,10 @@ static int tvfsClose(sqlite3_file *pFile){
|
|||||||
if( pFile->pMethods ){
|
if( pFile->pMethods ){
|
||||||
ckfree((char *)pFile->pMethods);
|
ckfree((char *)pFile->pMethods);
|
||||||
}
|
}
|
||||||
return sqlite3OsClose(pFd->pReal);
|
rc = sqlite3OsClose(pFd->pReal);
|
||||||
|
ckfree((char *)pFd);
|
||||||
|
pTestfile->pFd = 0;
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -324,7 +351,7 @@ static int tvfsRead(
|
|||||||
int iAmt,
|
int iAmt,
|
||||||
sqlite_int64 iOfst
|
sqlite_int64 iOfst
|
||||||
){
|
){
|
||||||
TestvfsFile *p = (TestvfsFile *)pFile;
|
TestvfsFd *p = tvfsGetFd(pFile);
|
||||||
return sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst);
|
return sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,7 +365,7 @@ static int tvfsWrite(
|
|||||||
sqlite_int64 iOfst
|
sqlite_int64 iOfst
|
||||||
){
|
){
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
TestvfsFile *pFd = (TestvfsFile *)pFile;
|
TestvfsFd *pFd = tvfsGetFd(pFile);
|
||||||
Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
|
Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
|
||||||
|
|
||||||
if( p->pScript && p->mask&TESTVFS_WRITE_MASK ){
|
if( p->pScript && p->mask&TESTVFS_WRITE_MASK ){
|
||||||
@@ -366,7 +393,7 @@ static int tvfsWrite(
|
|||||||
*/
|
*/
|
||||||
static int tvfsTruncate(sqlite3_file *pFile, sqlite_int64 size){
|
static int tvfsTruncate(sqlite3_file *pFile, sqlite_int64 size){
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
TestvfsFile *pFd = (TestvfsFile *)pFile;
|
TestvfsFd *pFd = tvfsGetFd(pFile);
|
||||||
Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
|
Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
|
||||||
|
|
||||||
if( p->pScript && p->mask&TESTVFS_TRUNCATE_MASK ){
|
if( p->pScript && p->mask&TESTVFS_TRUNCATE_MASK ){
|
||||||
@@ -387,7 +414,7 @@ static int tvfsTruncate(sqlite3_file *pFile, sqlite_int64 size){
|
|||||||
*/
|
*/
|
||||||
static int tvfsSync(sqlite3_file *pFile, int flags){
|
static int tvfsSync(sqlite3_file *pFile, int flags){
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
TestvfsFile *pFd = (TestvfsFile *)pFile;
|
TestvfsFd *pFd = tvfsGetFd(pFile);
|
||||||
Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
|
Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
|
||||||
|
|
||||||
if( p->pScript && p->mask&TESTVFS_SYNC_MASK ){
|
if( p->pScript && p->mask&TESTVFS_SYNC_MASK ){
|
||||||
@@ -430,7 +457,7 @@ static int tvfsSync(sqlite3_file *pFile, int flags){
|
|||||||
** Return the current file-size of an tvfs-file.
|
** Return the current file-size of an tvfs-file.
|
||||||
*/
|
*/
|
||||||
static int tvfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
|
static int tvfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
|
||||||
TestvfsFile *p = (TestvfsFile *)pFile;
|
TestvfsFd *p = tvfsGetFd(pFile);
|
||||||
return sqlite3OsFileSize(p->pReal, pSize);
|
return sqlite3OsFileSize(p->pReal, pSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,7 +465,7 @@ static int tvfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
|
|||||||
** Lock an tvfs-file.
|
** Lock an tvfs-file.
|
||||||
*/
|
*/
|
||||||
static int tvfsLock(sqlite3_file *pFile, int eLock){
|
static int tvfsLock(sqlite3_file *pFile, int eLock){
|
||||||
TestvfsFile *p = (TestvfsFile *)pFile;
|
TestvfsFd *p = tvfsGetFd(pFile);
|
||||||
return sqlite3OsLock(p->pReal, eLock);
|
return sqlite3OsLock(p->pReal, eLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,7 +473,7 @@ static int tvfsLock(sqlite3_file *pFile, int eLock){
|
|||||||
** Unlock an tvfs-file.
|
** Unlock an tvfs-file.
|
||||||
*/
|
*/
|
||||||
static int tvfsUnlock(sqlite3_file *pFile, int eLock){
|
static int tvfsUnlock(sqlite3_file *pFile, int eLock){
|
||||||
TestvfsFile *p = (TestvfsFile *)pFile;
|
TestvfsFd *p = tvfsGetFd(pFile);
|
||||||
return sqlite3OsUnlock(p->pReal, eLock);
|
return sqlite3OsUnlock(p->pReal, eLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -454,7 +481,7 @@ static int tvfsUnlock(sqlite3_file *pFile, int eLock){
|
|||||||
** Check if another file-handle holds a RESERVED lock on an tvfs-file.
|
** Check if another file-handle holds a RESERVED lock on an tvfs-file.
|
||||||
*/
|
*/
|
||||||
static int tvfsCheckReservedLock(sqlite3_file *pFile, int *pResOut){
|
static int tvfsCheckReservedLock(sqlite3_file *pFile, int *pResOut){
|
||||||
TestvfsFile *p = (TestvfsFile *)pFile;
|
TestvfsFd *p = tvfsGetFd(pFile);
|
||||||
return sqlite3OsCheckReservedLock(p->pReal, pResOut);
|
return sqlite3OsCheckReservedLock(p->pReal, pResOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -462,7 +489,7 @@ static int tvfsCheckReservedLock(sqlite3_file *pFile, int *pResOut){
|
|||||||
** File control method. For custom operations on an tvfs-file.
|
** File control method. For custom operations on an tvfs-file.
|
||||||
*/
|
*/
|
||||||
static int tvfsFileControl(sqlite3_file *pFile, int op, void *pArg){
|
static int tvfsFileControl(sqlite3_file *pFile, int op, void *pArg){
|
||||||
TestvfsFile *p = (TestvfsFile *)pFile;
|
TestvfsFd *p = tvfsGetFd(pFile);
|
||||||
return sqlite3OsFileControl(p->pReal, op, pArg);
|
return sqlite3OsFileControl(p->pReal, op, pArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -470,7 +497,7 @@ static int tvfsFileControl(sqlite3_file *pFile, int op, void *pArg){
|
|||||||
** Return the sector-size in bytes for an tvfs-file.
|
** Return the sector-size in bytes for an tvfs-file.
|
||||||
*/
|
*/
|
||||||
static int tvfsSectorSize(sqlite3_file *pFile){
|
static int tvfsSectorSize(sqlite3_file *pFile){
|
||||||
TestvfsFile *pFd = (TestvfsFile *)pFile;
|
TestvfsFd *pFd = tvfsGetFd(pFile);
|
||||||
Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
|
Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
|
||||||
if( p->iSectorsize>=0 ){
|
if( p->iSectorsize>=0 ){
|
||||||
return p->iSectorsize;
|
return p->iSectorsize;
|
||||||
@@ -482,7 +509,7 @@ static int tvfsSectorSize(sqlite3_file *pFile){
|
|||||||
** Return the device characteristic flags supported by an tvfs-file.
|
** Return the device characteristic flags supported by an tvfs-file.
|
||||||
*/
|
*/
|
||||||
static int tvfsDeviceCharacteristics(sqlite3_file *pFile){
|
static int tvfsDeviceCharacteristics(sqlite3_file *pFile){
|
||||||
TestvfsFile *pFd = (TestvfsFile *)pFile;
|
TestvfsFd *pFd = tvfsGetFd(pFile);
|
||||||
Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
|
Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
|
||||||
if( p->iDevchar>=0 ){
|
if( p->iDevchar>=0 ){
|
||||||
return p->iDevchar;
|
return p->iDevchar;
|
||||||
@@ -501,15 +528,19 @@ static int tvfsOpen(
|
|||||||
int *pOutFlags
|
int *pOutFlags
|
||||||
){
|
){
|
||||||
int rc;
|
int rc;
|
||||||
TestvfsFile *pFd = (TestvfsFile *)pFile;
|
TestvfsFile *pTestfile = (TestvfsFile *)pFile;
|
||||||
|
TestvfsFd *pFd;
|
||||||
Tcl_Obj *pId = 0;
|
Tcl_Obj *pId = 0;
|
||||||
Testvfs *p = (Testvfs *)pVfs->pAppData;
|
Testvfs *p = (Testvfs *)pVfs->pAppData;
|
||||||
|
|
||||||
|
pFd = (TestvfsFd *)ckalloc(sizeof(TestvfsFd) + PARENTVFS(pVfs)->szOsFile);
|
||||||
|
memset(pFd, 0, sizeof(TestvfsFd) + PARENTVFS(pVfs)->szOsFile);
|
||||||
pFd->pShm = 0;
|
pFd->pShm = 0;
|
||||||
pFd->pShmId = 0;
|
pFd->pShmId = 0;
|
||||||
pFd->zFilename = zName;
|
pFd->zFilename = zName;
|
||||||
pFd->pVfs = pVfs;
|
pFd->pVfs = pVfs;
|
||||||
pFd->pReal = (sqlite3_file *)&pFd[1];
|
pFd->pReal = (sqlite3_file *)&pFd[1];
|
||||||
|
pTestfile->pFd = pFd;
|
||||||
|
|
||||||
/* Evaluate the Tcl script:
|
/* Evaluate the Tcl script:
|
||||||
**
|
**
|
||||||
@@ -541,7 +572,6 @@ static int tvfsOpen(
|
|||||||
pFd->pShmId = pId;
|
pFd->pShmId = pId;
|
||||||
Tcl_ResetResult(p->interp);
|
Tcl_ResetResult(p->interp);
|
||||||
|
|
||||||
|
|
||||||
rc = sqlite3OsOpen(PARENTVFS(pVfs), zName, pFd->pReal, flags, pOutFlags);
|
rc = sqlite3OsOpen(PARENTVFS(pVfs), zName, pFd->pReal, flags, pOutFlags);
|
||||||
if( pFd->pReal->pMethods ){
|
if( pFd->pReal->pMethods ){
|
||||||
sqlite3_io_methods *pMethods;
|
sqlite3_io_methods *pMethods;
|
||||||
@@ -682,15 +712,13 @@ static int tvfsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
|
|||||||
return PARENTVFS(pVfs)->xCurrentTime(PARENTVFS(pVfs), pTimeOut);
|
return PARENTVFS(pVfs)->xCurrentTime(PARENTVFS(pVfs), pTimeOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tvfsShmOpen(
|
static int tvfsShmOpen(sqlite3_file *pFile){
|
||||||
sqlite3_file *pFileDes
|
|
||||||
){
|
|
||||||
Testvfs *p;
|
Testvfs *p;
|
||||||
int rc = SQLITE_OK; /* Return code */
|
int rc = SQLITE_OK; /* Return code */
|
||||||
TestvfsBuffer *pBuffer; /* Buffer to open connection to */
|
TestvfsBuffer *pBuffer; /* Buffer to open connection to */
|
||||||
TestvfsFile *pFd; /* The testvfs file structure */
|
TestvfsFd *pFd; /* The testvfs file structure */
|
||||||
|
|
||||||
pFd = (TestvfsFile*)pFileDes;
|
pFd = tvfsGetFd(pFile);
|
||||||
p = (Testvfs *)pFd->pVfs->pAppData;
|
p = (Testvfs *)pFd->pVfs->pAppData;
|
||||||
assert( pFd->pShmId && pFd->pShm==0 && pFd->pNext==0 );
|
assert( pFd->pShmId && pFd->pShm==0 && pFd->pNext==0 );
|
||||||
|
|
||||||
@@ -749,7 +777,7 @@ static int tvfsShmMap(
|
|||||||
void volatile **pp /* OUT: Mapped memory */
|
void volatile **pp /* OUT: Mapped memory */
|
||||||
){
|
){
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
TestvfsFile *pFd = (TestvfsFile *)pFile;
|
TestvfsFd *pFd = tvfsGetFd(pFile);
|
||||||
Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData);
|
Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData);
|
||||||
|
|
||||||
if( p->pScript && p->mask&TESTVFS_SHMMAP_MASK ){
|
if( p->pScript && p->mask&TESTVFS_SHMMAP_MASK ){
|
||||||
@@ -784,7 +812,7 @@ static int tvfsShmLock(
|
|||||||
int flags
|
int flags
|
||||||
){
|
){
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
TestvfsFile *pFd = (TestvfsFile *)pFile;
|
TestvfsFd *pFd = tvfsGetFd(pFile);
|
||||||
Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData);
|
Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData);
|
||||||
int nLock;
|
int nLock;
|
||||||
char zLock[80];
|
char zLock[80];
|
||||||
@@ -819,7 +847,7 @@ static int tvfsShmLock(
|
|||||||
int isExcl = (flags & SQLITE_SHM_EXCLUSIVE);
|
int isExcl = (flags & SQLITE_SHM_EXCLUSIVE);
|
||||||
u32 mask = (((1<<n)-1) << ofst);
|
u32 mask = (((1<<n)-1) << ofst);
|
||||||
if( isLock ){
|
if( isLock ){
|
||||||
TestvfsFile *p2;
|
TestvfsFd *p2;
|
||||||
for(p2=pFd->pShm->pFile; p2; p2=p2->pNext){
|
for(p2=pFd->pShm->pFile; p2; p2=p2->pNext){
|
||||||
if( p2==pFd ) continue;
|
if( p2==pFd ) continue;
|
||||||
if( (p2->excllock&mask) || (isExcl && p2->sharedlock&mask) ){
|
if( (p2->excllock&mask) || (isExcl && p2->sharedlock&mask) ){
|
||||||
@@ -841,7 +869,7 @@ static int tvfsShmLock(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void tvfsShmBarrier(sqlite3_file *pFile){
|
static void tvfsShmBarrier(sqlite3_file *pFile){
|
||||||
TestvfsFile *pFd = (TestvfsFile *)pFile;
|
TestvfsFd *pFd = tvfsGetFd(pFile);
|
||||||
Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData);
|
Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData);
|
||||||
|
|
||||||
if( p->pScript && p->mask&TESTVFS_SHMBARRIER_MASK ){
|
if( p->pScript && p->mask&TESTVFS_SHMBARRIER_MASK ){
|
||||||
@@ -856,10 +884,10 @@ static int tvfsShmClose(
|
|||||||
int deleteFlag
|
int deleteFlag
|
||||||
){
|
){
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
TestvfsFile *pFd = (TestvfsFile *)pFile;
|
TestvfsFd *pFd = tvfsGetFd(pFile);
|
||||||
Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData);
|
Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData);
|
||||||
TestvfsBuffer *pBuffer = pFd->pShm;
|
TestvfsBuffer *pBuffer = pFd->pShm;
|
||||||
TestvfsFile **ppFd;
|
TestvfsFd **ppFd;
|
||||||
|
|
||||||
assert( pFd->pShmId && pFd->pShm );
|
assert( pFd->pShmId && pFd->pShm );
|
||||||
|
|
||||||
@@ -1234,7 +1262,7 @@ static int testvfs_cmd(
|
|||||||
){
|
){
|
||||||
static sqlite3_vfs tvfs_vfs = {
|
static sqlite3_vfs tvfs_vfs = {
|
||||||
2, /* iVersion */
|
2, /* iVersion */
|
||||||
sizeof(TestvfsFile), /* szOsFile */
|
0, /* szOsFile */
|
||||||
0, /* mxPathname */
|
0, /* mxPathname */
|
||||||
0, /* pNext */
|
0, /* pNext */
|
||||||
0, /* zName */
|
0, /* zName */
|
||||||
@@ -1270,13 +1298,15 @@ static int testvfs_cmd(
|
|||||||
int i;
|
int i;
|
||||||
int isNoshm = 0; /* True if -noshm is passed */
|
int isNoshm = 0; /* True if -noshm is passed */
|
||||||
int isDefault = 0; /* True if -default is passed */
|
int isDefault = 0; /* True if -default is passed */
|
||||||
|
int szOsFile = 0; /* Value passed to -szosfile */
|
||||||
|
int mxPathname = -1; /* Value passed to -mxpathname */
|
||||||
|
|
||||||
if( objc<2 || 0!=(objc%2) ) goto bad_args;
|
if( objc<2 || 0!=(objc%2) ) goto bad_args;
|
||||||
for(i=2; i<objc; i += 2){
|
for(i=2; i<objc; i += 2){
|
||||||
int nSwitch;
|
int nSwitch;
|
||||||
char *zSwitch;
|
char *zSwitch;
|
||||||
|
|
||||||
zSwitch = Tcl_GetStringFromObj(objv[i], &nSwitch);
|
zSwitch = Tcl_GetStringFromObj(objv[i], &nSwitch);
|
||||||
|
|
||||||
if( nSwitch>2 && 0==strncmp("-noshm", zSwitch, nSwitch) ){
|
if( nSwitch>2 && 0==strncmp("-noshm", zSwitch, nSwitch) ){
|
||||||
if( Tcl_GetBooleanFromObj(interp, objv[i+1], &isNoshm) ){
|
if( Tcl_GetBooleanFromObj(interp, objv[i+1], &isNoshm) ){
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
@@ -1287,11 +1317,25 @@ static int testvfs_cmd(
|
|||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if( nSwitch>2 && 0==strncmp("-szosfile", zSwitch, nSwitch) ){
|
||||||
|
if( Tcl_GetIntFromObj(interp, objv[i+1], &szOsFile) ){
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( nSwitch>2 && 0==strncmp("-mxpathname", zSwitch, nSwitch) ){
|
||||||
|
if( Tcl_GetIntFromObj(interp, objv[i+1], &mxPathname) ){
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
else{
|
else{
|
||||||
goto bad_args;
|
goto bad_args;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( szOsFile<sizeof(TestvfsFile) ){
|
||||||
|
szOsFile = sizeof(TestvfsFile);
|
||||||
|
}
|
||||||
|
|
||||||
zVfs = Tcl_GetString(objv[1]);
|
zVfs = Tcl_GetString(objv[1]);
|
||||||
nByte = sizeof(Testvfs) + strlen(zVfs)+1;
|
nByte = sizeof(Testvfs) + strlen(zVfs)+1;
|
||||||
p = (Testvfs *)ckalloc(nByte);
|
p = (Testvfs *)ckalloc(nByte);
|
||||||
@@ -1317,7 +1361,10 @@ static int testvfs_cmd(
|
|||||||
pVfs->pAppData = (void *)p;
|
pVfs->pAppData = (void *)p;
|
||||||
pVfs->zName = p->zName;
|
pVfs->zName = p->zName;
|
||||||
pVfs->mxPathname = p->pParent->mxPathname;
|
pVfs->mxPathname = p->pParent->mxPathname;
|
||||||
pVfs->szOsFile += p->pParent->szOsFile;
|
if( mxPathname>=0 && mxPathname<pVfs->mxPathname ){
|
||||||
|
pVfs->mxPathname = mxPathname;
|
||||||
|
}
|
||||||
|
pVfs->szOsFile = szOsFile;
|
||||||
p->pVfs = pVfs;
|
p->pVfs = pVfs;
|
||||||
p->isNoshm = isNoshm;
|
p->isNoshm = isNoshm;
|
||||||
p->mask = TESTVFS_ALL_MASK;
|
p->mask = TESTVFS_ALL_MASK;
|
||||||
@@ -1327,7 +1374,7 @@ static int testvfs_cmd(
|
|||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
|
|
||||||
bad_args:
|
bad_args:
|
||||||
Tcl_WrongNumArgs(interp, 1, objv, "VFSNAME ?-noshm BOOL? ?-default BOOL?");
|
Tcl_WrongNumArgs(interp, 1, objv, "VFSNAME ?-noshm BOOL? ?-default BOOL? ?-mxpathname INT? ?-szosfile INT?");
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
245
test/pager1.test
245
test/pager1.test
@@ -49,6 +49,15 @@ do_not_use_codec
|
|||||||
#
|
#
|
||||||
# pager1-14.*: Cases specific to "PRAGMA journal_mode=OFF"
|
# pager1-14.*: Cases specific to "PRAGMA journal_mode=OFF"
|
||||||
#
|
#
|
||||||
|
# pager1-15.*: Varying sqlite3_vfs.szOsFile
|
||||||
|
#
|
||||||
|
# pager1-16.*: Varying sqlite3_vfs.mxPathname
|
||||||
|
#
|
||||||
|
# pager1-17.*: Tests related to "PRAGMA omit_readlock"
|
||||||
|
#
|
||||||
|
# pager1-18.*: Test that the pager layer responds correctly if the b-tree
|
||||||
|
# requests an invalid page number (due to db corruption).
|
||||||
|
#
|
||||||
|
|
||||||
set a_string_counter 1
|
set a_string_counter 1
|
||||||
proc a_string {n} {
|
proc a_string {n} {
|
||||||
@@ -358,6 +367,10 @@ foreach {tn sql tcl} {
|
|||||||
# pager1.4.6.*: Test that when rolling back a hot-journal that contains a
|
# pager1.4.6.*: Test that when rolling back a hot-journal that contains a
|
||||||
# master journal pointer, the master journal file is deleted
|
# master journal pointer, the master journal file is deleted
|
||||||
# after all the hot-journals that refer to it are deleted.
|
# after all the hot-journals that refer to it are deleted.
|
||||||
|
#
|
||||||
|
# pager1.4.7.*: Test that if a hot-journal file exists but a client can
|
||||||
|
# open it for reading only, the database cannot be accessed and
|
||||||
|
# SQLITE_CANTOPEN is returned.
|
||||||
#
|
#
|
||||||
do_test pager1.4.1.1 {
|
do_test pager1.4.1.1 {
|
||||||
faultsim_delete_and_reopen
|
faultsim_delete_and_reopen
|
||||||
@@ -635,7 +648,6 @@ testvfs tv -default 1
|
|||||||
tv sectorsize 512
|
tv sectorsize 512
|
||||||
tv script copy_on_journal_delete
|
tv script copy_on_journal_delete
|
||||||
tv filter xDelete
|
tv filter xDelete
|
||||||
set ::mj_filename_length 0
|
|
||||||
proc copy_on_journal_delete {method filename args} {
|
proc copy_on_journal_delete {method filename args} {
|
||||||
if {[string match *journal $filename]} faultsim_save
|
if {[string match *journal $filename]} faultsim_save
|
||||||
return SQLITE_OK
|
return SQLITE_OK
|
||||||
@@ -806,6 +818,43 @@ do_test pager1.4.6.15 { file exists $::mj_filename } {0}
|
|||||||
db close
|
db close
|
||||||
tv delete
|
tv delete
|
||||||
|
|
||||||
|
testvfs tv -default 1
|
||||||
|
tv sectorsize 512
|
||||||
|
tv script copy_on_journal_delete
|
||||||
|
tv filter xDelete
|
||||||
|
proc copy_on_journal_delete {method filename args} {
|
||||||
|
if {[string match *journal $filename]} faultsim_save
|
||||||
|
return SQLITE_OK
|
||||||
|
}
|
||||||
|
faultsim_delete_and_reopen
|
||||||
|
do_execsql_test pager1.4.7.1 {
|
||||||
|
CREATE TABLE t1(x PRIMARY KEY, y);
|
||||||
|
CREATE INDEX i1 ON t1(y);
|
||||||
|
INSERT INTO t1 VALUES('I', 'one');
|
||||||
|
INSERT INTO t1 VALUES('II', 'four');
|
||||||
|
INSERT INTO t1 VALUES('III', 'nine');
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO t1 VALUES('IV', 'sixteen');
|
||||||
|
INSERT INTO t1 VALUES('V' , 'twentyfive');
|
||||||
|
COMMIT;
|
||||||
|
} {}
|
||||||
|
tv filter {}
|
||||||
|
db close
|
||||||
|
tv delete
|
||||||
|
do_test pager1.4.7.2 {
|
||||||
|
faultsim_restore_and_reopen
|
||||||
|
catch {file attributes test.db-journal -permissions r--------}
|
||||||
|
catch {file attributes test.db-journal -readonly 1}
|
||||||
|
catchsql { SELECT * FROM t1 }
|
||||||
|
} {1 {unable to open database file}}
|
||||||
|
do_test pager1.4.7.3 {
|
||||||
|
db close
|
||||||
|
catch {file attributes test.db-journal -permissions rw-rw-rw-}
|
||||||
|
catch {file attributes test.db-journal -readonly 0}
|
||||||
|
file delete test.db-journal
|
||||||
|
file exists test.db-journal
|
||||||
|
} {0}
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
# The following tests deal with multi-file commits.
|
# The following tests deal with multi-file commits.
|
||||||
#
|
#
|
||||||
@@ -1055,6 +1104,7 @@ foreach {tn filename} {
|
|||||||
db close
|
db close
|
||||||
sqlite3 db $filename
|
sqlite3 db $filename
|
||||||
execsql {
|
execsql {
|
||||||
|
PRAGMA auto_vacuum = 1;
|
||||||
CREATE TABLE x1(x);
|
CREATE TABLE x1(x);
|
||||||
INSERT INTO x1 VALUES('Charles');
|
INSERT INTO x1 VALUES('Charles');
|
||||||
INSERT INTO x1 VALUES('James');
|
INSERT INTO x1 VALUES('James');
|
||||||
@@ -1378,4 +1428,197 @@ do_execsql_test pager1-14.1.5 {
|
|||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
} {1 2 3 4 2 2 4 4}
|
} {1 2 3 4 2 2 4 4}
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
# Test opening and closing the pager sub-system with different values
|
||||||
|
# for the sqlite3_vfs.szOsFile variable.
|
||||||
|
#
|
||||||
|
faultsim_delete_and_reopen
|
||||||
|
do_execsql_test pager1-15.0 {
|
||||||
|
CREATE TABLE tx(y, z);
|
||||||
|
INSERT INTO tx VALUES('Ayutthaya', 'Beijing');
|
||||||
|
INSERT INTO tx VALUES('London', 'Tokyo');
|
||||||
|
} {}
|
||||||
|
db close
|
||||||
|
for {set i 0} {$i<513} {incr i 3} {
|
||||||
|
testvfs tv -default 1 -szosfile $i
|
||||||
|
sqlite3 db test.db
|
||||||
|
do_execsql_test pager1-15.$i.1 {
|
||||||
|
SELECT * FROM tx;
|
||||||
|
} {Ayutthaya Beijing London Tokyo}
|
||||||
|
db close
|
||||||
|
tv delete
|
||||||
|
}
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
# Check that it is not possible to open a database file if the full path
|
||||||
|
# to the associated journal file will be longer than sqlite3_vfs.mxPathname.
|
||||||
|
#
|
||||||
|
testvfs tv -default 1
|
||||||
|
tv script xOpenCb
|
||||||
|
tv filter xOpen
|
||||||
|
proc xOpenCb {method filename} {
|
||||||
|
set ::file_len [string length $filename]
|
||||||
|
}
|
||||||
|
sqlite3 db test.db
|
||||||
|
db close
|
||||||
|
tv delete
|
||||||
|
|
||||||
|
for {set ii [expr $::file_len-5]} {$ii < [expr $::file_len+20]} {incr ii} {
|
||||||
|
testvfs tv -default 1 -mxpathname $ii
|
||||||
|
|
||||||
|
# The length of the full path to file "test.db-journal" is ($::file_len+8).
|
||||||
|
# If the configured sqlite3_vfs.mxPathname value greater than or equal to
|
||||||
|
# this, then the file can be opened. Otherwise, it cannot.
|
||||||
|
#
|
||||||
|
if {$ii >= [expr $::file_len+8]} {
|
||||||
|
set res {0 {}}
|
||||||
|
} else {
|
||||||
|
set res {1 {unable to open database file}}
|
||||||
|
}
|
||||||
|
|
||||||
|
do_test pager1-16.1.$ii {
|
||||||
|
list [catch { sqlite3 db test.db } msg] $msg
|
||||||
|
} $res
|
||||||
|
|
||||||
|
catch {db close}
|
||||||
|
tv delete
|
||||||
|
}
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
# Test "PRAGMA omit_readlock".
|
||||||
|
#
|
||||||
|
# pager1-17.$tn.1.*: Test that if a second connection has an open
|
||||||
|
# read-transaction, it is not usually possible to write
|
||||||
|
# the database.
|
||||||
|
#
|
||||||
|
# pager1-17.$tn.2.*: Test that if the second connection was opened with
|
||||||
|
# the SQLITE_OPEN_READONLY flag, and
|
||||||
|
# "PRAGMA omit_readlock = 1" is executed before attaching
|
||||||
|
# the database and opening a read-transaction on it, it is
|
||||||
|
# possible to write the db.
|
||||||
|
#
|
||||||
|
# pager1-17.$tn.3.*: Test that if the second connection was *not* opened with
|
||||||
|
# the SQLITE_OPEN_READONLY flag, executing
|
||||||
|
# "PRAGMA omit_readlock = 1" has no effect.
|
||||||
|
#
|
||||||
|
do_multiclient_test tn {
|
||||||
|
do_test pager1-17.$tn.1.1 {
|
||||||
|
sql1 {
|
||||||
|
CREATE TABLE t1(a, b);
|
||||||
|
INSERT INTO t1 VALUES(1, 2);
|
||||||
|
}
|
||||||
|
sql2 {
|
||||||
|
BEGIN;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
}
|
||||||
|
} {1 2}
|
||||||
|
do_test pager1-17.$tn.1.2 {
|
||||||
|
csql1 { INSERT INTO t1 VALUES(3, 4) }
|
||||||
|
} {1 {database is locked}}
|
||||||
|
do_test pager1-17.$tn.1.3 {
|
||||||
|
sql2 { COMMIT }
|
||||||
|
sql1 { INSERT INTO t1 VALUES(3, 4) }
|
||||||
|
} {}
|
||||||
|
|
||||||
|
do_test pager1-17.$tn.2.1 {
|
||||||
|
code2 {
|
||||||
|
db2 close
|
||||||
|
sqlite3 db2 :memory: -readonly 1
|
||||||
|
}
|
||||||
|
sql2 {
|
||||||
|
PRAGMA omit_readlock = 1;
|
||||||
|
ATTACH 'test.db' AS two;
|
||||||
|
BEGIN;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
}
|
||||||
|
} {1 2 3 4}
|
||||||
|
do_test pager1-17.$tn.2.2 { sql1 "INSERT INTO t1 VALUES(5, 6)" } {}
|
||||||
|
do_test pager1-17.$tn.2.3 { sql2 "SELECT * FROM t1" } {1 2 3 4}
|
||||||
|
do_test pager1-17.$tn.2.4 { sql2 "COMMIT ; SELECT * FROM t1" } {1 2 3 4 5 6}
|
||||||
|
|
||||||
|
do_test pager1-17.$tn.3.1 {
|
||||||
|
code2 {
|
||||||
|
db2 close
|
||||||
|
sqlite3 db2 :memory:
|
||||||
|
}
|
||||||
|
sql2 {
|
||||||
|
PRAGMA omit_readlock = 1;
|
||||||
|
ATTACH 'test.db' AS two;
|
||||||
|
BEGIN;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
}
|
||||||
|
} {1 2 3 4 5 6}
|
||||||
|
do_test pager1-17.$tn.3.2 {
|
||||||
|
csql1 { INSERT INTO t1 VALUES(3, 4) }
|
||||||
|
} {1 {database is locked}}
|
||||||
|
do_test pager1-17.$tn.3.3 { sql2 COMMIT } {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
# Test the pagers response to the b-tree layer requesting illegal page
|
||||||
|
# numbers:
|
||||||
|
#
|
||||||
|
# + The locking page,
|
||||||
|
# + Page 0,
|
||||||
|
# + A page with a page number greater than (2^31-1).
|
||||||
|
#
|
||||||
|
do_test pager1-18.1 {
|
||||||
|
faultsim_delete_and_reopen
|
||||||
|
db func a_string a_string
|
||||||
|
execsql {
|
||||||
|
PRAGMA page_size = 1024;
|
||||||
|
CREATE TABLE t1(a, b);
|
||||||
|
INSERT INTO t1 VALUES(a_string(500), a_string(200));
|
||||||
|
INSERT INTO t1 SELECT a_string(500), a_string(200) FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a_string(500), a_string(200) FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a_string(500), a_string(200) FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a_string(500), a_string(200) FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a_string(500), a_string(200) FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a_string(500), a_string(200) FROM t1;
|
||||||
|
INSERT INTO t1 SELECT a_string(500), a_string(200) FROM t1;
|
||||||
|
}
|
||||||
|
} {}
|
||||||
|
do_test pager1-18.2 {
|
||||||
|
set root [db one "SELECT rootpage FROM sqlite_master"]
|
||||||
|
set lockingpage [expr (0x10000/1024) + 1]
|
||||||
|
execsql {
|
||||||
|
PRAGMA writable_schema = 1;
|
||||||
|
UPDATE sqlite_master SET rootpage = $lockingpage;
|
||||||
|
}
|
||||||
|
sqlite3 db2 test.db
|
||||||
|
catchsql { SELECT count(*) FROM t1 } db2
|
||||||
|
} {1 {database disk image is malformed}}
|
||||||
|
db2 close
|
||||||
|
do_test pager1-18.3 {
|
||||||
|
execsql {
|
||||||
|
CREATE TABLE t2(x);
|
||||||
|
INSERT INTO t2 VALUES(a_string(5000));
|
||||||
|
}
|
||||||
|
set pgno [expr ([file size test.db] / 1024)-2]
|
||||||
|
hexio_write test.db [expr ($pgno-1)*1024] 00000000
|
||||||
|
sqlite3 db2 test.db
|
||||||
|
catchsql { SELECT length(x) FROM t2 } db2
|
||||||
|
} {1 {database disk image is malformed}}
|
||||||
|
db2 close
|
||||||
|
do_test pager1-18.4 {
|
||||||
|
hexio_write test.db [expr ($pgno-1)*1024] 90000000
|
||||||
|
sqlite3 db2 test.db
|
||||||
|
catchsql { SELECT length(x) FROM t2 } db2
|
||||||
|
} {1 {database disk image is malformed}}
|
||||||
|
db2 close
|
||||||
|
do_test pager1-18.5 {
|
||||||
|
sqlite3 db ""
|
||||||
|
execsql {
|
||||||
|
CREATE TABLE t1(a, b);
|
||||||
|
CREATE TABLE t2(a, b);
|
||||||
|
PRAGMA writable_schema = 1;
|
||||||
|
UPDATE sqlite_master SET rootpage=5 WHERE tbl_name = 't1';
|
||||||
|
PRAGMA writable_schema = 0;
|
||||||
|
ALTER TABLE t1 RENAME TO x1;
|
||||||
|
}
|
||||||
|
catchsql { SELECT * FROM x1 }
|
||||||
|
} {}
|
||||||
|
db close
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
|
||||||
|
@@ -473,26 +473,29 @@ do_faultsim_test pagerfault-9.1 -prep {
|
|||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
# Test fault injection with a temporary database file.
|
# Test fault injection with a temporary database file.
|
||||||
#
|
#
|
||||||
do_faultsim_test pagerfault-10 -prep {
|
foreach v {a b} {
|
||||||
sqlite3 db ""
|
do_faultsim_test pagerfault-10$v -prep {
|
||||||
db func a_string a_string;
|
sqlite3 db ""
|
||||||
execsql {
|
db func a_string a_string;
|
||||||
PRAGMA cache_size = 10;
|
execsql {
|
||||||
BEGIN;
|
PRAGMA cache_size = 10;
|
||||||
CREATE TABLE xx(a, b, UNIQUE(a, b));
|
BEGIN;
|
||||||
INSERT INTO xx VALUES(a_string(200), a_string(200));
|
CREATE TABLE xx(a, b, UNIQUE(a, b));
|
||||||
INSERT INTO xx SELECT a_string(200), a_string(200) FROM xx;
|
INSERT INTO xx VALUES(a_string(200), a_string(200));
|
||||||
INSERT INTO xx SELECT a_string(200), a_string(200) FROM xx;
|
INSERT INTO xx SELECT a_string(200), a_string(200) FROM xx;
|
||||||
INSERT INTO xx SELECT a_string(200), a_string(200) FROM xx;
|
INSERT INTO xx SELECT a_string(200), a_string(200) FROM xx;
|
||||||
INSERT INTO xx SELECT a_string(200), a_string(200) FROM xx;
|
INSERT INTO xx SELECT a_string(200), a_string(200) FROM xx;
|
||||||
COMMIT;
|
INSERT INTO xx SELECT a_string(200), a_string(200) FROM xx;
|
||||||
|
COMMIT;
|
||||||
|
}
|
||||||
|
} -body {
|
||||||
|
execsql { UPDATE xx SET a = a_string(300) }
|
||||||
|
} -test {
|
||||||
|
faultsim_test_result {0 {}}
|
||||||
|
if {$::v == "b"} { execsql { PRAGMA journal_mode = TRUNCATE } }
|
||||||
|
faultsim_integrity_check
|
||||||
|
faultsim_integrity_check
|
||||||
}
|
}
|
||||||
} -body {
|
|
||||||
execsql { UPDATE xx SET a = a_string(300) }
|
|
||||||
} -test {
|
|
||||||
faultsim_test_result {0 {}}
|
|
||||||
faultsim_integrity_check
|
|
||||||
faultsim_integrity_check
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
@@ -542,8 +545,10 @@ do_faultsim_test pagerfault-11 -prep {
|
|||||||
faultsim_integrity_check
|
faultsim_integrity_check
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
#-------------------------------------------------------------------------
|
||||||
|
# Test fault injection when writing to a database file that resides on
|
||||||
|
# a file-system with a sector-size larger than the database page-size.
|
||||||
|
#
|
||||||
do_test pagerfault-12-pre1 {
|
do_test pagerfault-12-pre1 {
|
||||||
testvfs ss_layer -default 1
|
testvfs ss_layer -default 1
|
||||||
ss_layer sectorsize 4096
|
ss_layer sectorsize 4096
|
||||||
@@ -580,5 +585,31 @@ do_faultsim_test pagerfault-12 -prep {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
do_test pagerfault-13-pre1 {
|
||||||
|
faultsim_delete_and_reopen
|
||||||
|
db func a_string a_string;
|
||||||
|
execsql {
|
||||||
|
PRAGMA journal_mode = PERSIST;
|
||||||
|
BEGIN;
|
||||||
|
CREATE TABLE t1(x, y UNIQUE);
|
||||||
|
INSERT INTO t1 VALUES(a_string(333), a_string(444));
|
||||||
|
COMMIT;
|
||||||
|
}
|
||||||
|
db close
|
||||||
|
file delete -force test.db
|
||||||
|
faultsim_save
|
||||||
|
} {}
|
||||||
|
do_faultsim_test pagerfault-13 -prep {
|
||||||
|
faultsim_restore_and_reopen
|
||||||
|
} -body {
|
||||||
|
execsql { CREATE TABLE xx(a, b) }
|
||||||
|
} -test {
|
||||||
|
faultsim_test_result {0 {}}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
Reference in New Issue
Block a user