]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Further test cases for pager1.test and pagerfault.test.
authordan <dan@noemail.net>
Fri, 25 Jun 2010 19:09:48 +0000 (19:09 +0000)
committerdan <dan@noemail.net>
Fri, 25 Jun 2010 19:09:48 +0000 (19:09 +0000)
FossilOrigin-Name: bfd563c4714d86805fa09ce9f4f807e5d502a99b

manifest
manifest.uuid
src/test_vfs.c
test/malloc_common.tcl
test/pager1.test
test/pagerfault.test

index ced8a2cef14948a8d06172c10587686f60089875..c8542df443d2b676fb3d34a3c1a3933011f7c63e 100644 (file)
--- 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
index 10328ee61f49904f53645d5999c713569337d734..454cd290b58e9ac87a23ec24225d9a2297db3f5d 100644 (file)
@@ -1 +1 @@
-4a7fd91b7ab2c5d21fbac7f6f123820c8f4ec7f6
\ No newline at end of file
+bfd563c4714d86805fa09ce9f4f807e5d502a99b
\ No newline at end of file
index 5d92e9d43f8c5b10e10a408ef045cc4817b30666..8ae55e7d46d1f0ffb5d42221c045f4b0fd5b3824 100644 (file)
@@ -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;
-
-      p->nIoerrFail = 0;
-      p->ioerr = 0;
-      p->iIoerrCnt = 0;
+    case CMD_CANTOPENERR:
+    case CMD_IOERR:
+    case CMD_FULLERR: {
+      TestFaultInject *pTest;
+      int iRet;
+
+      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));
index e03a6359d9f14ba7f87ed654ffdc2f815cc8456b..a452a519ebcaa85284e018579e90cb354c8929b9 100644 (file)
@@ -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 
index d6362731603cdd296811b88f55406036dfa29610..cca26c127849e394729836a395e787882983ba5b 100644 (file)
@@ -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
 
index e7415f064acb91d4dea3093eb2adab4d3c20b4dd..d6a01fec85dd3e6823d95804daa203372afee3a4 100644 (file)
@@ -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