/ Check-in [a194e536]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add tests for the RBU module.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: a194e53670e25a48c2bb51b54755abff88ed6ae2596c5858fb4aac16cb452bdf
User & Date: dan 2019-05-10 20:44:10
Context
2019-05-11
13:04
Do not assume that "x IS NOT ?" implies "x NOT NULL" when considering partial indexes. Fix for ticket [8025674847]. check-in: 0ba6d709 user: dan tags: trunk
2019-05-10
20:44
Add tests for the RBU module. check-in: a194e536 user: dan tags: trunk
17:54
Fix harmless compiler warnings. check-in: 956ca2a4 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

Changes to ext/rbu/rbufault2.test.

    48     48         {1 SQLITE_CONSTRAINT} \
    49     49         {1 SQLITE_NOMEM} \
    50     50         {1 {SQLITE_NOMEM - unable to open a temporary database file for storing temporary tables}} \
    51     51         {1 {SQLITE_NOMEM - out of memory}} 
    52     52   }
    53     53   
    54     54   
           55  +sqlite3rbu_create_vfs -default rbu ""
           56  +sqlite3 db test.db
           57  +set ::vfsname [file_control_vfsname db]
           58  +do_faultsim_test 2 -faults oom* -prep {
           59  +} -body {
           60  +  file_control_vfsname db
           61  +} 
           62  +db close
           63  +sqlite3rbu_destroy_vfs rbu
    55     64   
    56     65   
    57     66   finish_test

Changes to ext/rbu/rbumisc.test.

    14     14   set ::testprefix rbumisc
    15     15   
    16     16   db close
    17     17   sqlite3_shutdown
    18     18   sqlite3_config_uri 1
    19     19   reset_db
    20     20   
    21         -#-------------------------------------------------------------------------
    22         -# Ensure that RBU is not confused by oddly named tables in an RBU 
    23         -# database.
    24         -#
    25         -do_execsql_test 1.0 {
    26         -  CREATE TABLE x1(a, b, c INTEGER PRIMARY KEY);
    27         -}
    28         -do_test 1.1 {
           21  +proc populate_rbu_db {} {
    29     22     forcedelete rbu.db
    30     23     sqlite3 rbu rbu.db
    31     24     rbu eval {
    32     25       CREATE TABLE data_x1(a, b, c, rbu_control);
    33     26       INSERT INTO data_x1 VALUES(1, 1, 1, 0);
    34     27       INSERT INTO data_x1 VALUES(2, 2, 2, 0);
    35     28   
................................................................................
    40     33   
    41     34       INSERT INTO "data x1" VALUES(3, 3, 3, 0);
    42     35       INSERT INTO datax1 VALUES(3, 3, 3, 0);
    43     36       INSERT INTO data_ VALUES(3, 3, 3, 0);
    44     37       INSERT INTO dat VALUES(3, 3, 3, 0);
    45     38     }
    46     39     rbu close
           40  +}
           41  +
           42  +#-------------------------------------------------------------------------
           43  +# Ensure that RBU is not confused by oddly named tables in an RBU 
           44  +# database.
           45  +#
           46  +do_execsql_test 1.0 {
           47  +  CREATE TABLE x1(a, b, c INTEGER PRIMARY KEY);
           48  +}
           49  +do_test 1.1 {
           50  +  populate_rbu_db
    47     51   } {}
    48     52   
    49     53   do_test 1.2 {
    50     54     step_rbu test.db rbu.db
    51     55     db eval { SELECT * FROM x1 }
    52     56   } {1 1 1 2 2 2}
    53     57   
................................................................................
    58     62     rbu close
    59     63     step_rbu test.db rbu.db
    60     64     db eval { SELECT * FROM x1 }
    61     65   } {1 1 1 2 2 2}
    62     66   
    63     67   do_test 1.4 {
    64     68     db eval { DELETE FROM x1 }
    65         -  sqlite3 rbu rbu.db
    66         -  rbu eval { DELETE FROM rbu_state }
    67         -  rbu close
           69  +  populate_rbu_db
    68     70   
    69     71     sqlite3rbu rbu test.db rbu.db
    70     72     rbu step
    71     73     rbu step
    72     74     rbu close
    73     75   
    74     76     forcecopy test.db-oal test.db-wal
    75     77     sqlite3rbu rbu test.db rbu.db
    76     78     rbu step
    77     79     list [catch { rbu close } msg] $msg
    78     80   } {1 {SQLITE_ERROR - cannot update wal mode database}}
           81  +
           82  +#-------------------------------------------------------------------------
           83  +# Test the effect of a wal file appearing after the target database has
           84  +# been opened, but before it has been locked.
           85  +#
           86  +catch { db close }
           87  +testvfs tvfs -default 1
           88  +
           89  +for {set N 1} {$N < 10} {incr N} {
           90  +  reset_db
           91  +  populate_rbu_db
           92  +  do_execsql_test 2.$N.0 {
           93  +    CREATE TABLE x1(a, b, c INTEGER PRIMARY KEY);
           94  +  }
           95  +  
           96  +  set nAccessCnt 0
           97  +  do_test 2.$N.1 {
           98  +    sqlite3rbu rbu test.db rbu.db
           99  +    rbu step
          100  +    rbu step
          101  +    rbu close
          102  +  } {SQLITE_OK}
          103  +  
          104  +  tvfs script xAccess
          105  +  tvfs filter xAccess
          106  +  set nAccessCnt 0
          107  +  proc xAccess {method file args} {
          108  +    global nAccessCnt
          109  +    if {[file tail $file]=="test.db-wal"} {
          110  +      incr nAccessCnt -1
          111  +      if {$nAccessCnt==0} {
          112  +        set fd [open test.db-wal w]
          113  +        puts -nonewline $fd [string repeat 0 2000]
          114  +        close $fd
          115  +      }
          116  +    }
          117  +    return SQLITE_OK
          118  +  }
          119  +
          120  +  foreach r {
          121  +     {1 {SQLITE_ERROR - cannot update wal mode database}}
          122  +     {0 SQLITE_OK}
          123  +     {1 {SQLITE_CANTOPEN - unable to open database file}}
          124  +  } {
          125  +    set RES($r) 1
          126  +  }
          127  +  do_test 2.$N.2 {
          128  +    set ::nAccessCnt $N
          129  +    set res [list [catch {
          130  +      sqlite3rbu rbu test.db rbu.db
          131  +      rbu step
          132  +      rbu close
          133  +    } msg ] $msg]
          134  +    set RES($res)
          135  +  } {1}
          136  +  catch {rbu close}
          137  +}
          138  +catch {db close}
          139  +catch {tvfs delete}
          140  +
          141  +#-------------------------------------------------------------------------
          142  +testvfs tvfs -default 1
          143  +reset_db
          144  +populate_rbu_db
          145  +do_execsql_test 3.0 {
          146  +  CREATE TABLE x1(a, b, c INTEGER PRIMARY KEY);
          147  +}
          148  +  
          149  +tvfs script xFileControl
          150  +tvfs filter xFileControl
          151  +
          152  +proc xFileControl {method file verb args} {
          153  +  if {$verb=="ZIPVFS" && [info exists ::zipvfs_filecontrol]} {
          154  +    return $::zipvfs_filecontrol 
          155  +  }
          156  +  return "SQLITE_NOTFOUND"
          157  +}
          158  +
          159  +breakpoint
          160  +foreach {tn ret err} {
          161  +  1 SQLITE_OK           0
          162  +  2 SQLITE_ERROR        1
          163  +  3 SQLITE_NOTFOUND     0
          164  +  4 SQLITE_OMIT         1
          165  +} {
          166  +  set ::zipvfs_filecontrol $ret
          167  +  do_test 3.$tn.1 {
          168  +    catch {
          169  +      sqlite3rbu rbu test.db rbu.db
          170  +      rbu step
          171  +      rbu close
          172  +    }
          173  +  } $err
          174  +}
          175  +catch {db close}
          176  +catch {tvfs delete}
          177  +
          178  +#-------------------------------------------------------------------------
    79    179   
    80    180   finish_test

Changes to ext/rbu/sqlite3rbu.c.

  4703   4703         rc = xControl(p->pReal, SQLITE_FCNTL_ZIPVFS, &dummy);
  4704   4704         if( rc==SQLITE_OK ){
  4705   4705           rc = SQLITE_ERROR;
  4706   4706           pRbu->zErrmsg = sqlite3_mprintf("rbu/zipvfs setup error");
  4707   4707         }else if( rc==SQLITE_NOTFOUND ){
  4708   4708           pRbu->pTargetFd = p;
  4709   4709           p->pRbu = pRbu;
  4710         -        if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
  4711   4710             rbuMainlistAdd(p);
  4712         -        }
  4713   4711           if( p->pWalFd ) p->pWalFd->pRbu = pRbu;
  4714   4712           rc = SQLITE_OK;
  4715   4713         }
  4716   4714       }
  4717   4715       return rc;
  4718   4716     }
  4719   4717     else if( op==SQLITE_FCNTL_RBUCNT ){
................................................................................
  4768   4766       /* Magic number 1 is the WAL_CKPT_LOCK lock. Preventing SQLite from
  4769   4767       ** taking this lock also prevents any checkpoints from occurring. 
  4770   4768       ** todo: really, it's not clear why this might occur, as 
  4771   4769       ** wal_autocheckpoint ought to be turned off.  */
  4772   4770       if( ofst==WAL_LOCK_CKPT && n==1 ) rc = SQLITE_BUSY;
  4773   4771     }else{
  4774   4772       int bCapture = 0;
  4775         -    if( n==1 && (flags & SQLITE_SHM_EXCLUSIVE)
  4776         -     && pRbu && pRbu->eStage==RBU_STAGE_CAPTURE
  4777         -     && (ofst==WAL_LOCK_WRITE || ofst==WAL_LOCK_CKPT || ofst==WAL_LOCK_READ0)
  4778         -    ){
         4773  +    if( pRbu && pRbu->eStage==RBU_STAGE_CAPTURE ){
  4779   4774         bCapture = 1;
  4780   4775       }
  4781   4776   
  4782   4777       if( bCapture==0 || 0==(flags & SQLITE_SHM_UNLOCK) ){
  4783   4778         rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags);
  4784   4779         if( bCapture && rc==SQLITE_OK ){
  4785   4780           pRbu->mLock |= (1 << ofst);
................................................................................
  4804   4799     int rc = SQLITE_OK;
  4805   4800     int eStage = (p->pRbu ? p->pRbu->eStage : 0);
  4806   4801   
  4807   4802     /* If not in RBU_STAGE_OAL, allow this call to pass through. Or, if this
  4808   4803     ** rbu is in the RBU_STAGE_OAL state, use heap memory for *-shm space 
  4809   4804     ** instead of a file on disk.  */
  4810   4805     assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
  4811         -  if( eStage==RBU_STAGE_OAL || eStage==RBU_STAGE_MOVE ){
  4812         -    if( iRegion<=p->nShm ){
         4806  +  if( eStage==RBU_STAGE_OAL ){
  4813   4807         sqlite3_int64 nByte = (iRegion+1) * sizeof(char*);
  4814   4808         char **apNew = (char**)sqlite3_realloc64(p->apShm, nByte);
         4809  +
         4810  +    /* This is an RBU connection that uses its own heap memory for the
         4811  +    ** pages of the *-shm file. Since no other process can have run
         4812  +    ** recovery, the connection must request *-shm pages in order
         4813  +    ** from start to finish.  */
         4814  +    assert( iRegion==p->nShm );
  4815   4815         if( apNew==0 ){
  4816   4816           rc = SQLITE_NOMEM;
  4817   4817         }else{
  4818   4818           memset(&apNew[p->nShm], 0, sizeof(char*) * (1 + iRegion - p->nShm));
  4819   4819           p->apShm = apNew;
  4820   4820           p->nShm = iRegion+1;
  4821   4821         }
  4822         -    }
  4823   4822   
  4824         -    if( rc==SQLITE_OK && p->apShm[iRegion]==0 ){
         4823  +    if( rc==SQLITE_OK ){
  4825   4824         char *pNew = (char*)sqlite3_malloc64(szRegion);
  4826   4825         if( pNew==0 ){
  4827   4826           rc = SQLITE_NOMEM;
  4828   4827         }else{
  4829   4828           memset(pNew, 0, szRegion);
  4830   4829           p->apShm[iRegion] = pNew;
  4831   4830         }

Changes to src/test_vfs.c.

   231    231       { SQLITE_OK,       "SQLITE_OK"     },
   232    232       { SQLITE_ERROR,    "SQLITE_ERROR"  },
   233    233       { SQLITE_IOERR,    "SQLITE_IOERR"  },
   234    234       { SQLITE_LOCKED,   "SQLITE_LOCKED" },
   235    235       { SQLITE_BUSY,     "SQLITE_BUSY"   },
   236    236       { SQLITE_READONLY, "SQLITE_READONLY"   },
   237    237       { SQLITE_READONLY_CANTINIT, "SQLITE_READONLY_CANTINIT"   },
          238  +    { SQLITE_NOTFOUND, "SQLITE_NOTFOUND"   },
   238    239       { -1,              "SQLITE_OMIT"   },
   239    240     };
   240    241   
   241    242     const char *z;
   242    243     int i;
   243    244   
   244    245     z = Tcl_GetStringResult(p->interp);
................................................................................
   548    549     if( p->pScript && (p->mask&TESTVFS_FCNTL_MASK) ){
   549    550       struct Fcntl {
   550    551         int iFnctl;
   551    552         const char *zFnctl;
   552    553       } aF[] = {
   553    554         { SQLITE_FCNTL_BEGIN_ATOMIC_WRITE, "BEGIN_ATOMIC_WRITE" },
   554    555         { SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, "COMMIT_ATOMIC_WRITE" },
          556  +      { SQLITE_FCNTL_ZIPVFS, "ZIPVFS" },
   555    557       };
   556    558       int i;
   557    559       for(i=0; i<sizeof(aF)/sizeof(aF[0]); i++){
   558    560         if( op==aF[i].iFnctl ) break;
   559    561       }
   560    562       if( i<sizeof(aF)/sizeof(aF[0]) ){
   561    563         int rc = 0;
   562    564         tvfsExecTcl(p, "xFileControl", 
   563    565             Tcl_NewStringObj(pFd->zFilename, -1), 
   564    566             Tcl_NewStringObj(aF[i].zFnctl, -1),
   565    567             0, 0
   566    568         );
   567    569         tvfsResultCode(p, &rc);
   568         -      if( rc ) return rc;
          570  +      if( rc ) return (rc<0 ? SQLITE_OK : rc);
   569    571       }
   570    572     }
   571    573     return sqlite3OsFileControl(pFd->pReal, op, pArg);
   572    574   }
   573    575   
   574    576   /*
   575    577   ** Return the sector-size in bytes for an tvfs-file.