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:
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user