diff --git a/manifest b/manifest index ced8a2cef1..c8542df443 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reduce\sthe\saverage\s(but\snot\smaximum)\ssize\sof\sthe\sallocations\smade\sas\spart\sof\sa\scheckpoint. -D 2010-06-25T16:34:32 +C Further\stest\scases\sfor\spager1.test\sand\spagerfault.test. +D 2010-06-25T19:09:48 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 d001a4e64ceed35e480f1cb1aa7cc8b48eab1c29 +F src/test_vfs.c 90d51963dfe2aa28a9408b461cb06f48921be8e8 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c 25ceb0f0a746ea1d0f9553787f3f0a56853cfaeb F src/trigger.c 8927588cb9e6d47f933b53bfe74200fbb504100d @@ -509,7 +509,7 @@ F test/mallocH.test 79b65aed612c9b3ed2dcdaa727c85895fd1bfbdb F test/mallocI.test e3ea401904d010cb7c1e4b2ee8803f4a9f5b999d F test/mallocJ.test b5d1839da331d96223e5f458856f8ffe1366f62e F test/mallocK.test d79968641d1b70d88f6c01bdb9a7eb4a55582cc9 -F test/malloc_common.tcl c5a4688c3744f69450d88909d2a6cd2644f76803 +F test/malloc_common.tcl d5cf479545104c0aa2e60a3a94802e128a57ebb7 F test/manydb.test b3d3bc4c25657e7f68d157f031eb4db7b3df0d3c F test/memdb.test 0825155b2290e900264daaaf0334b6dfe69ea498 F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2 @@ -534,9 +534,9 @@ F test/notify2.test 195a467e021f74197be2c4fb02d6dee644b8d8db F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347 F test/null.test a8b09b8ed87852742343b33441a9240022108993 F test/openv2.test af02ed0a9cbc0d2a61b8f35171d4d117e588e4ec -F test/pager1.test b7099656ae9162fd192b13fafab0361c2a910022 +F test/pager1.test dfb695c91652559302530319cccb608c4ed23a59 F test/pager2.test f5c757c271ce642d36a393ecbfb3aef1c240dcef -F test/pagerfault.test a48c4ed81ab7ebb11a65d97a7332026d19beb2a4 +F test/pagerfault.test d90859967eda59b53074498846d142a81d7e29ff F test/pageropt.test 8146bf448cf09e87bb1867c2217b921fb5857806 F test/pagesize.test 76aa9f23ecb0741a4ed9d2e16c5fa82671f28efb F test/pcache.test 4118a183908ecaed343a06fcef3ba82e87e0129d @@ -825,7 +825,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 29887487ed549f97c3c9b37f852bae179b6ea9a9 -R 0d354ce5ca0d0be1f06510bbeac66ab5 +P 4a7fd91b7ab2c5d21fbac7f6f123820c8f4ec7f6 +R ecb04b890fe63f676fa227ca5f46f9c3 U dan -Z 4ef8c49b4f2e94b4894a55fae3b39c83 +Z 46acbd8eac91574d70d09df9d19b8578 diff --git a/manifest.uuid b/manifest.uuid index 10328ee61f..454cd290b5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4a7fd91b7ab2c5d21fbac7f6f123820c8f4ec7f6 \ No newline at end of file +bfd563c4714d86805fa09ce9f4f807e5d502a99b \ No newline at end of file diff --git a/src/test_vfs.c b/src/test_vfs.c index 5d92e9d43f..8ae55e7d46 100644 --- a/src/test_vfs.c +++ b/src/test_vfs.c @@ -37,6 +37,16 @@ struct TestvfsFile { TestvfsFile *pNext; /* Next handle opened on the same file */ }; +#define FAULT_INJECT_NONE 0 +#define FAULT_INJECT_TRANSIENT 1 +#define FAULT_INJECT_PERSISTENT 2 + +typedef struct TestFaultInject TestFaultInject; +struct TestFaultInject { + int iCnt; /* Remaining calls before fault injection */ + int eFault; /* A FAULT_INJECT_* value */ + int nFail; /* Number of faults injected */ +}; /* ** An instance of this structure is allocated for each VFS created. The @@ -54,14 +64,20 @@ struct Testvfs { TestvfsBuffer *pBuffer; /* List of shared buffers */ int isNoshm; - int mask; + int mask; /* Mask controlling [script] and [ioerr] */ + + TestFaultInject ioerr_err; + TestFaultInject full_err; + TestFaultInject cantopen_err; + +#if 0 int iIoerrCnt; int ioerr; int nIoerrFail; - int iFullCnt; int fullerr; int nFullFail; +#endif int iDevchar; int iSectorsize; @@ -87,7 +103,8 @@ struct Testvfs { #define TESTVFS_CLOSE_MASK 0x00000800 #define TESTVFS_WRITE_MASK 0x00001000 #define TESTVFS_TRUNCATE_MASK 0x00002000 -#define TESTVFS_ALL_MASK 0x00003FFF +#define TESTVFS_ACCESS_MASK 0x00004000 +#define TESTVFS_ALL_MASK 0x00007FFF #define TESTVFS_MAX_PAGES 1024 @@ -197,28 +214,28 @@ static int tvfsResultCode(Testvfs *p, int *pRc){ return 0; } -static int tvfsInjectIoerr(Testvfs *p){ +static int tvfsInjectFault(TestFaultInject *p){ int ret = 0; - if( p->ioerr ){ - p->iIoerrCnt--; - if( p->iIoerrCnt==0 || (p->iIoerrCnt<0 && p->ioerr==2) ){ + if( p->eFault ){ + p->iCnt--; + if( p->iCnt==0 || (p->iCnt<0 && p->eFault==FAULT_INJECT_PERSISTENT ) ){ ret = 1; - p->nIoerrFail++; + p->nFail++; } } return ret; } + +static int tvfsInjectIoerr(Testvfs *p){ + return tvfsInjectFault(&p->ioerr_err); +} + static int tvfsInjectFullerr(Testvfs *p){ - int ret = 0; - if( p->fullerr ){ - p->iFullCnt--; - if( p->iFullCnt<=0 ){ - ret = 1; - p->nFullFail++; - } - } - return ret; + return tvfsInjectFault(&p->full_err); +} +static int tvfsInjectCantopenerr(Testvfs *p){ + return tvfsInjectFault(&p->cantopen_err); } @@ -512,6 +529,11 @@ static int tvfsOpen( pId = Tcl_GetObjResult(p->interp); } } + + if( (p->mask&TESTVFS_OPEN_MASK) && tvfsInjectIoerr(p) ) return SQLITE_IOERR; + if( tvfsInjectCantopenerr(p) ) return SQLITE_CANTOPEN; + if( tvfsInjectFullerr(p) ) return SQLITE_FULL; + if( !pId ){ pId = Tcl_NewStringObj("anon", -1); } @@ -519,6 +541,7 @@ static int tvfsOpen( pFd->pShmId = pId; Tcl_ResetResult(p->interp); + rc = sqlite3OsOpen(PARENTVFS(pVfs), zName, pFd->pReal, flags, pOutFlags); if( pFd->pReal->pMethods ){ sqlite3_io_methods *pMethods; @@ -568,6 +591,25 @@ static int tvfsAccess( int flags, int *pResOut ){ + Testvfs *p = (Testvfs *)pVfs->pAppData; + if( p->pScript && p->mask&TESTVFS_ACCESS_MASK ){ + int rc; + char *zArg = 0; + if( flags==SQLITE_ACCESS_EXISTS ) zArg = "SQLITE_ACCESS_EXISTS"; + if( flags==SQLITE_ACCESS_READWRITE ) zArg = "SQLITE_ACCESS_READWRITE"; + if( flags==SQLITE_ACCESS_READ ) zArg = "SQLITE_ACCESS_READ"; + tvfsExecTcl(p, "xAccess", + Tcl_NewStringObj(zPath, -1), Tcl_NewStringObj(zArg, -1), 0 + ); + if( tvfsResultCode(p, &rc) ){ + if( rc!=SQLITE_OK ) return rc; + }else{ + Tcl_Interp *interp = p->interp; + if( TCL_OK==Tcl_GetBooleanFromObj(0, Tcl_GetObjResult(interp), pResOut) ){ + return SQLITE_OK; + } + } + } return sqlite3OsAccess(PARENTVFS(pVfs), zPath, flags, pResOut); } @@ -857,20 +899,21 @@ static int testvfs_obj_cmd( enum DB_enum { CMD_SHM, CMD_DELETE, CMD_FILTER, CMD_IOERR, CMD_SCRIPT, - CMD_DEVCHAR, CMD_SECTORSIZE, CMD_FULLERR + CMD_DEVCHAR, CMD_SECTORSIZE, CMD_FULLERR, CMD_CANTOPENERR }; struct TestvfsSubcmd { char *zName; enum DB_enum eCmd; } aSubcmd[] = { - { "shm", CMD_SHM }, - { "delete", CMD_DELETE }, - { "filter", CMD_FILTER }, - { "ioerr", CMD_IOERR }, - { "fullerr", CMD_FULLERR }, - { "script", CMD_SCRIPT }, - { "devchar", CMD_DEVCHAR }, - { "sectorsize", CMD_SECTORSIZE }, + { "shm", CMD_SHM }, + { "delete", CMD_DELETE }, + { "filter", CMD_FILTER }, + { "ioerr", CMD_IOERR }, + { "fullerr", CMD_FULLERR }, + { "cantopenerr", CMD_CANTOPENERR }, + { "script", CMD_SCRIPT }, + { "devchar", CMD_DEVCHAR }, + { "sectorsize", CMD_SECTORSIZE }, { 0, 0 } }; int i; @@ -950,6 +993,7 @@ static int testvfs_obj_cmd( { "xTruncate", TESTVFS_TRUNCATE_MASK }, { "xOpen", TESTVFS_OPEN_MASK }, { "xClose", TESTVFS_CLOSE_MASK }, + { "xAccess", TESTVFS_ACCESS_MASK }, }; Tcl_Obj **apElem = 0; int nElem = 0; @@ -1007,45 +1051,27 @@ static int testvfs_obj_cmd( break; } - /* - ** TESTVFS fullerr ?IFAIL? - ** - ** Where IFAIL is an integer. - */ - case CMD_FULLERR: { - int iRet = p->nFullFail; - - p->nFullFail = 0; - p->fullerr = 0; - p->iFullCnt = 0; - - if( objc==3 ){ - int iCnt; - if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iCnt) ){ - return TCL_ERROR; - } - p->fullerr = (iCnt>0); - p->iFullCnt = iCnt; - }else if( objc!=2 ){ - Tcl_AppendResult(interp, "Bad args", 0); - return TCL_ERROR; - } - - Tcl_SetObjResult(interp, Tcl_NewIntObj(iRet)); - break; - } - /* ** TESTVFS ioerr ?IFAIL PERSIST? ** ** Where IFAIL is an integer and PERSIST is boolean. */ - case CMD_IOERR: { - int iRet = p->nIoerrFail; + case CMD_CANTOPENERR: + case CMD_IOERR: + case CMD_FULLERR: { + TestFaultInject *pTest; + int iRet; - p->nIoerrFail = 0; - p->ioerr = 0; - p->iIoerrCnt = 0; + switch( aSubcmd[i].eCmd ){ + case CMD_IOERR: pTest = &p->ioerr_err; break; + case CMD_FULLERR: pTest = &p->full_err; break; + case CMD_CANTOPENERR: pTest = &p->cantopen_err; break; + default: assert(0); + } + iRet = pTest->nFail; + pTest->nFail = 0; + pTest->eFault = 0; + pTest->iCnt = 0; if( objc==4 ){ int iCnt, iPersist; @@ -1054,10 +1080,10 @@ static int testvfs_obj_cmd( ){ return TCL_ERROR; } - p->ioerr = (iCnt>0) + iPersist; - p->iIoerrCnt = iCnt; + pTest->eFault = iPersist?FAULT_INJECT_PERSISTENT:FAULT_INJECT_TRANSIENT; + pTest->iCnt = iCnt; }else if( objc!=2 ){ - Tcl_AppendResult(interp, "Bad args", 0); + Tcl_WrongNumArgs(interp, 2, objv, "?CNT PERSIST?"); return TCL_ERROR; } Tcl_SetObjResult(interp, Tcl_NewIntObj(iRet)); diff --git a/test/malloc_common.tcl b/test/malloc_common.tcl index e03a6359d9..a452a519eb 100644 --- a/test/malloc_common.tcl +++ b/test/malloc_common.tcl @@ -76,6 +76,23 @@ set FAULTSIM(shmerr-persistent) [list \ -injectuninstall shmerr_injectuninstall \ ] +# Transient and persistent CANTOPEN errors: +# +set FAULTSIM(cantopen-transient) [list \ + -injectinstall cantopen_injectinstall \ + -injectstart {cantopen_injectstart 0} \ + -injectstop cantopen_injectstop \ + -injecterrlist {{1 {unable to open database file}}} \ + -injectuninstall cantopen_injectuninstall \ +] +set FAULTSIM(cantopen-persistent) [list \ + -injectinstall cantopen_injectinstall \ + -injectstart {cantopen_injectstart 1} \ + -injectstop cantopen_injectstop \ + -injecterrlist {{1 {unable to open database file}}} \ + -injectuninstall cantopen_injectuninstall \ +] + #-------------------------------------------------------------------------- @@ -203,7 +220,7 @@ proc shmerr_injectstart {persist iFail} { shmfault ioerr $iFail $persist } proc shmerr_injectstop {} { - shmfault ioerr 0 0 + shmfault ioerr } # The following procs are used as [do_one_faultsim_test] callbacks when @@ -218,10 +235,28 @@ proc fullerr_injectuninstall {} { shmfault delete } proc fullerr_injectstart {iFail} { - shmfault full $iFail + shmfault full $iFail 1 } proc fullerr_injectstop {} { - shmfault full 0 + shmfault full +} + +# The following procs are used as [do_one_faultsim_test] callbacks when +# injecting SQLITE_CANTOPEN error faults into test cases. +# +proc cantopen_injectinstall {} { + testvfs shmfault -default true +} +proc cantopen_injectuninstall {} { + catch {db close} + catch {db2 close} + shmfault delete +} +proc cantopen_injectstart {persist iFail} { + shmfault cantopen $iFail $persist +} +proc cantopen_injectstop {} { + shmfault cantopen } # This command is not called directly. It is used by the diff --git a/test/pager1.test b/test/pager1.test index d636273160..cca26c1278 100644 --- a/test/pager1.test +++ b/test/pager1.test @@ -1125,7 +1125,40 @@ do_test pager1-11.4 { } {0} breakpoint do_execsql_test pager1-11.5 { SELECT count(*) FROM zz } {32} +db close +tv delete +#------------------------------------------------------------------------- +# Test "PRAGMA page_size" +# +foreach pagesize { + 512 1024 2048 4096 8192 16384 32768 +} { + faultsim_delete_and_reopen + + do_test pager1-12.$pagesize.1 { + sqlite3 db2 test.db + execsql " + PRAGMA page_size = $pagesize; + CREATE VIEW v AS SELECT * FROM sqlite_master; + " db2 + file size test.db + } $pagesize + do_test pager1-12.$pagesize.2 { + sqlite3 db2 test.db + execsql { + SELECT count(*) FROM v; + PRAGMA main.page_size; + } db2 + } [list 1 $pagesize] + do_test pager1-12.$pagesize.3 { + execsql { + SELECT count(*) FROM v; + PRAGMA main.page_size; + } + } [list 1 $pagesize] + db2 close +} finish_test diff --git a/test/pagerfault.test b/test/pagerfault.test index e7415f064a..d6a01fec85 100644 --- a/test/pagerfault.test +++ b/test/pagerfault.test @@ -246,7 +246,6 @@ do_faultsim_test pagerfault-5.3 -faults oom-transient -prep { if {$rc!=0 || $res != "ok"} {error "integrity-check problem:$rc $res"} } - #------------------------------------------------------------------------- # Test fault-injection as part of a commit when using # journal_mode=TRUNCATE. @@ -260,12 +259,37 @@ do_test pagerfault-6-pre1 { } faultsim_save_and_close } {} + do_faultsim_test pagerfault-6.1 -prep { faultsim_restore_and_reopen db func a_string a_string execsql { PRAGMA journal_mode = TRUNCATE } } -body { execsql { INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1 } + execsql { INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1 } +} -test { + faultsim_test_result {0 {}} + faultsim_integrity_check +} + +# The unix vfs xAccess() method considers a file zero bytes in size to +# "not exist". This proc overrides that behaviour so that a zero length +# file is considered to exist. +# +proc xAccess {method filename op args} { + if {$op != "SQLITE_ACCESS_EXISTS"} { return "" } + return [file exists $filename] +} +do_faultsim_test pagerfault-6.2 -faults cantopen-* -prep { + shmfault filter xAccess + shmfault script xAccess + + faultsim_restore_and_reopen + db func a_string a_string + execsql { PRAGMA journal_mode = TRUNCATE } +} -body { + execsql { INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1 } + execsql { INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1 } } -test { faultsim_test_result {0 {}} faultsim_integrity_check