1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-29 08:01:23 +03:00

Add tests for the RBU module.

FossilOrigin-Name: a194e53670e25a48c2bb51b54755abff88ed6ae2596c5858fb4aac16cb452bdf
This commit is contained in:
dan
2019-05-10 20:44:10 +00:00
parent 2240bb88f8
commit 90255b8149
6 changed files with 152 additions and 43 deletions

View File

@ -52,6 +52,15 @@ do_faultsim_test 1 -faults oom* -prep {
}
sqlite3rbu_create_vfs -default rbu ""
sqlite3 db test.db
set ::vfsname [file_control_vfsname db]
do_faultsim_test 2 -faults oom* -prep {
} -body {
file_control_vfsname db
}
db close
sqlite3rbu_destroy_vfs rbu
finish_test

View File

@ -18,14 +18,7 @@ sqlite3_shutdown
sqlite3_config_uri 1
reset_db
#-------------------------------------------------------------------------
# Ensure that RBU is not confused by oddly named tables in an RBU
# database.
#
do_execsql_test 1.0 {
CREATE TABLE x1(a, b, c INTEGER PRIMARY KEY);
}
do_test 1.1 {
proc populate_rbu_db {} {
forcedelete rbu.db
sqlite3 rbu rbu.db
rbu eval {
@ -44,6 +37,17 @@ do_test 1.1 {
INSERT INTO dat VALUES(3, 3, 3, 0);
}
rbu close
}
#-------------------------------------------------------------------------
# Ensure that RBU is not confused by oddly named tables in an RBU
# database.
#
do_execsql_test 1.0 {
CREATE TABLE x1(a, b, c INTEGER PRIMARY KEY);
}
do_test 1.1 {
populate_rbu_db
} {}
do_test 1.2 {
@ -62,9 +66,7 @@ do_test 1.3 {
do_test 1.4 {
db eval { DELETE FROM x1 }
sqlite3 rbu rbu.db
rbu eval { DELETE FROM rbu_state }
rbu close
populate_rbu_db
sqlite3rbu rbu test.db rbu.db
rbu step
@ -77,4 +79,102 @@ do_test 1.4 {
list [catch { rbu close } msg] $msg
} {1 {SQLITE_ERROR - cannot update wal mode database}}
#-------------------------------------------------------------------------
# Test the effect of a wal file appearing after the target database has
# been opened, but before it has been locked.
#
catch { db close }
testvfs tvfs -default 1
for {set N 1} {$N < 10} {incr N} {
reset_db
populate_rbu_db
do_execsql_test 2.$N.0 {
CREATE TABLE x1(a, b, c INTEGER PRIMARY KEY);
}
set nAccessCnt 0
do_test 2.$N.1 {
sqlite3rbu rbu test.db rbu.db
rbu step
rbu step
rbu close
} {SQLITE_OK}
tvfs script xAccess
tvfs filter xAccess
set nAccessCnt 0
proc xAccess {method file args} {
global nAccessCnt
if {[file tail $file]=="test.db-wal"} {
incr nAccessCnt -1
if {$nAccessCnt==0} {
set fd [open test.db-wal w]
puts -nonewline $fd [string repeat 0 2000]
close $fd
}
}
return SQLITE_OK
}
foreach r {
{1 {SQLITE_ERROR - cannot update wal mode database}}
{0 SQLITE_OK}
{1 {SQLITE_CANTOPEN - unable to open database file}}
} {
set RES($r) 1
}
do_test 2.$N.2 {
set ::nAccessCnt $N
set res [list [catch {
sqlite3rbu rbu test.db rbu.db
rbu step
rbu close
} msg ] $msg]
set RES($res)
} {1}
catch {rbu close}
}
catch {db close}
catch {tvfs delete}
#-------------------------------------------------------------------------
testvfs tvfs -default 1
reset_db
populate_rbu_db
do_execsql_test 3.0 {
CREATE TABLE x1(a, b, c INTEGER PRIMARY KEY);
}
tvfs script xFileControl
tvfs filter xFileControl
proc xFileControl {method file verb args} {
if {$verb=="ZIPVFS" && [info exists ::zipvfs_filecontrol]} {
return $::zipvfs_filecontrol
}
return "SQLITE_NOTFOUND"
}
breakpoint
foreach {tn ret err} {
1 SQLITE_OK 0
2 SQLITE_ERROR 1
3 SQLITE_NOTFOUND 0
4 SQLITE_OMIT 1
} {
set ::zipvfs_filecontrol $ret
do_test 3.$tn.1 {
catch {
sqlite3rbu rbu test.db rbu.db
rbu step
rbu close
}
} $err
}
catch {db close}
catch {tvfs delete}
#-------------------------------------------------------------------------
finish_test

View File

@ -4707,9 +4707,7 @@ static int rbuVfsFileControl(sqlite3_file *pFile, int op, void *pArg){
}else if( rc==SQLITE_NOTFOUND ){
pRbu->pTargetFd = p;
p->pRbu = pRbu;
if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
rbuMainlistAdd(p);
}
rbuMainlistAdd(p);
if( p->pWalFd ) p->pWalFd->pRbu = pRbu;
rc = SQLITE_OK;
}
@ -4772,10 +4770,7 @@ static int rbuVfsShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
if( ofst==WAL_LOCK_CKPT && n==1 ) rc = SQLITE_BUSY;
}else{
int bCapture = 0;
if( n==1 && (flags & SQLITE_SHM_EXCLUSIVE)
&& pRbu && pRbu->eStage==RBU_STAGE_CAPTURE
&& (ofst==WAL_LOCK_WRITE || ofst==WAL_LOCK_CKPT || ofst==WAL_LOCK_READ0)
){
if( pRbu && pRbu->eStage==RBU_STAGE_CAPTURE ){
bCapture = 1;
}
@ -4808,20 +4803,24 @@ static int rbuVfsShmMap(
** rbu is in the RBU_STAGE_OAL state, use heap memory for *-shm space
** instead of a file on disk. */
assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
if( eStage==RBU_STAGE_OAL || eStage==RBU_STAGE_MOVE ){
if( iRegion<=p->nShm ){
sqlite3_int64 nByte = (iRegion+1) * sizeof(char*);
char **apNew = (char**)sqlite3_realloc64(p->apShm, nByte);
if( apNew==0 ){
rc = SQLITE_NOMEM;
}else{
memset(&apNew[p->nShm], 0, sizeof(char*) * (1 + iRegion - p->nShm));
p->apShm = apNew;
p->nShm = iRegion+1;
}
if( eStage==RBU_STAGE_OAL ){
sqlite3_int64 nByte = (iRegion+1) * sizeof(char*);
char **apNew = (char**)sqlite3_realloc64(p->apShm, nByte);
/* This is an RBU connection that uses its own heap memory for the
** pages of the *-shm file. Since no other process can have run
** recovery, the connection must request *-shm pages in order
** from start to finish. */
assert( iRegion==p->nShm );
if( apNew==0 ){
rc = SQLITE_NOMEM;
}else{
memset(&apNew[p->nShm], 0, sizeof(char*) * (1 + iRegion - p->nShm));
p->apShm = apNew;
p->nShm = iRegion+1;
}
if( rc==SQLITE_OK && p->apShm[iRegion]==0 ){
if( rc==SQLITE_OK ){
char *pNew = (char*)sqlite3_malloc64(szRegion);
if( pNew==0 ){
rc = SQLITE_NOMEM;