mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Copy some extra test infrastructure from the mutexfree-shmlock branch to trunk.
FossilOrigin-Name: 883337ffdb434b6856ceaada121c0be67e2fdec7b447675f45e85568ef28d7d9
This commit is contained in:
@@ -15,18 +15,20 @@
|
||||
|
||||
proc do_multiclient_test {varname script} {
|
||||
|
||||
foreach code [list {
|
||||
foreach {tn code} [list 1 {
|
||||
if {[info exists ::G(valgrind)]} { db close ; continue }
|
||||
set ::code2_chan [launch_testfixture]
|
||||
set ::code3_chan [launch_testfixture]
|
||||
proc code2 {tcl} { testfixture $::code2_chan $tcl }
|
||||
proc code3 {tcl} { testfixture $::code3_chan $tcl }
|
||||
set tn 1
|
||||
} {
|
||||
} 2 {
|
||||
proc code2 {tcl} { uplevel #0 $tcl }
|
||||
proc code3 {tcl} { uplevel #0 $tcl }
|
||||
set tn 2
|
||||
}] {
|
||||
# Do not run multi-process tests with the unix-excl VFS.
|
||||
#
|
||||
if {$tn==1 && [permutation]=="unix-excl"} continue
|
||||
|
||||
faultsim_delete_and_reopen
|
||||
|
||||
proc code1 {tcl} { uplevel #0 $tcl }
|
||||
|
||||
173
test/shmlock.test
Normal file
173
test/shmlock.test
Normal file
@@ -0,0 +1,173 @@
|
||||
# 2018 December 6
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
set testprefix shmlock
|
||||
|
||||
ifcapable !wal {finish_test ; return }
|
||||
|
||||
sqlite3 db2 test.db
|
||||
sqlite3 db3 test.db
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
PRAGMA journal_mode = wal;
|
||||
CREATE TABLE t1(a, b);
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
} {wal}
|
||||
do_test 1.1 { execsql { SELECT * FROM t1 } db2 } {1 2}
|
||||
do_test 1.2 { execsql { SELECT * FROM t1 } db3 } {1 2}
|
||||
|
||||
foreach {tn dbhandle cmd res} {
|
||||
1 db {shared lock 7 1} OK
|
||||
2 db2 {exclusive lock 7 1} BUSY
|
||||
3 db {shared unlock 7 1} OK
|
||||
4 db2 {exclusive lock 7 1} OK
|
||||
5 db {shared lock 7 1} BUSY
|
||||
6 db {exclusive lock 7 1} BUSY
|
||||
7 db2 {exclusive unlock 7 1} OK
|
||||
|
||||
8 db {exclusive lock 0 8} OK
|
||||
9 db {exclusive unlock 0 8} OK
|
||||
10 db2 {exclusive lock 0 8} OK
|
||||
11 db2 {exclusive unlock 0 8} OK
|
||||
|
||||
12 db {shared lock 0 1} OK
|
||||
13 db2 {shared lock 0 1} OK
|
||||
14 db3 {shared lock 0 1} OK
|
||||
15 db3 {shared unlock 0 1} OK
|
||||
16 db3 {exclusive lock 0 1} BUSY
|
||||
17 db2 {shared unlock 0 1} OK
|
||||
18 db3 {exclusive lock 0 1} BUSY
|
||||
19 db {shared unlock 0 1} OK
|
||||
20 db3 {exclusive lock 0 1} OK
|
||||
21 db3 {exclusive unlock 0 1} OK
|
||||
|
||||
22 db {shared lock 3 1} OK
|
||||
23 db2 {exclusive lock 2 2} BUSY
|
||||
24 db {shared lock 2 1} OK
|
||||
25 db2 {exclusive lock 0 5} BUSY
|
||||
26 db2 {exclusive lock 0 4} BUSY
|
||||
27 db2 {exclusive lock 0 3} BUSY
|
||||
28 db {shared unlock 3 1} OK
|
||||
29 db2 {exclusive lock 2 2} BUSY
|
||||
28 db {shared unlock 2 1} OK
|
||||
29 db2 {exclusive lock 2 2} OK
|
||||
29 db2 {exclusive unlock 2 2} OK
|
||||
} {
|
||||
do_test 1.3.$tn [list vfs_shmlock $dbhandle main {*}$cmd] "SQLITE_$res"
|
||||
}
|
||||
|
||||
db close
|
||||
db2 close
|
||||
db3 close
|
||||
|
||||
if {[permutation]=="unix-excl"} {
|
||||
do_test 2.0 {
|
||||
for {set i 0} {$i < 256} {incr i} {
|
||||
sqlite3 db$i test.db
|
||||
execsql { SELECT * FROM t1 } db$i
|
||||
}
|
||||
for {set i 0} {$i < 255} {incr i} {
|
||||
set rc [vfs_shmlock db$i main shared lock 4 1]
|
||||
if {$rc != "SQLITE_OK"} { error $rc }
|
||||
}
|
||||
|
||||
vfs_shmlock db255 main shared lock 4 1
|
||||
} {SQLITE_BUSY}
|
||||
|
||||
do_test 2.1 { vfs_shmlock db255 main exclusive lock 4 1 } SQLITE_BUSY
|
||||
do_test 2.2 { vfs_shmlock db0 main shared unlock 4 1 } SQLITE_OK
|
||||
do_test 2.3 { vfs_shmlock db255 main shared lock 4 1 } SQLITE_OK
|
||||
do_test 2.4 { vfs_shmlock db255 main shared unlock 4 1 } SQLITE_OK
|
||||
do_test 2.5 { vfs_shmlock db255 main exclusive lock 4 1 } SQLITE_BUSY
|
||||
|
||||
do_test 2.6 {
|
||||
for {set i 1} {$i < 255} {incr i} {
|
||||
set rc [vfs_shmlock db255 main exclusive lock 4 1]
|
||||
if {$rc != "SQLITE_BUSY"} { error $rc }
|
||||
set rc [vfs_shmlock db$i main shared unlock 4 1]
|
||||
if {$rc != "SQLITE_OK"} { error $rc }
|
||||
}
|
||||
|
||||
vfs_shmlock db255 main exclusive lock 4 1
|
||||
} {SQLITE_OK}
|
||||
|
||||
vfs_shmlock db255 main exclusive unlock 4 1
|
||||
|
||||
for {set i 0} {$i < 256} {incr i} {
|
||||
db$i close
|
||||
}
|
||||
}
|
||||
|
||||
sqlite3 db0 test.db
|
||||
sqlite3 db1 test.db
|
||||
do_test 3.1 { execsql { SELECT * FROM t1 } db0 } {1 2}
|
||||
do_test 3.2 { execsql { SELECT * FROM t1 } db1 } {1 2}
|
||||
|
||||
set L(0) {n n n n n n n n}
|
||||
set L(1) {n n n n n n n n}
|
||||
proc random_lock_test {idx} {
|
||||
global L
|
||||
set iSlot [expr int(rand()*8)]
|
||||
if {[expr int(rand()*2)]} {
|
||||
# Unlock operation
|
||||
if {[lindex $L($idx) $iSlot]!="n"} {
|
||||
vfs_shmlock db$idx main [lindex $L($idx) $iSlot] unlock $iSlot 1
|
||||
lset L($idx) $iSlot n
|
||||
}
|
||||
} else {
|
||||
# Lock operation
|
||||
if {[lindex $L($idx) $iSlot]=="n"} {
|
||||
set locktype [lindex {e s} [expr int(rand()*2)]]
|
||||
set n 1
|
||||
if {$locktype=="e"} {
|
||||
for {set l $iSlot} {$l<8 && [lindex $L($idx) $l]=="n"} {incr l} {}
|
||||
set n [expr int(rand()*($l-$iSlot))+1]
|
||||
# puts "iSlot=$iSlot l=$l L=$L($idx)"
|
||||
# puts "$iSlot $n"
|
||||
}
|
||||
set res [vfs_shmlock db$idx main $locktype lock $iSlot $n]
|
||||
|
||||
set bBusy 0
|
||||
for {set i $iSlot} {$i<($iSlot+$n)} {incr i} {
|
||||
set other [lindex $L([expr ($idx+1)%2]) $i]
|
||||
if {($other!="n" && $locktype=="e")||($other=="e" && $locktype=="s")} {
|
||||
if {$res != "SQLITE_BUSY"} { error "BUSY not detected" }
|
||||
set bBusy 1
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if {$bBusy==0} {
|
||||
if {$res != "SQLITE_OK"} { error "BUSY false-positive" }
|
||||
for {set i $iSlot} {$i<($iSlot+$n)} {incr i} {
|
||||
lset L($idx) $i $locktype
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set nStep 100000
|
||||
for {set i 0} {$i < $nStep} {incr i} {
|
||||
random_lock_test 0
|
||||
random_lock_test 1
|
||||
}
|
||||
|
||||
db0 close
|
||||
db1 close
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -1297,51 +1297,53 @@ do_test wal-19.4 {
|
||||
# At one point, SQLite was failing to grow the mapping of the wal-index
|
||||
# file in step 3 and the checkpoint was corrupting the database file.
|
||||
#
|
||||
do_test wal-20.1 {
|
||||
catch {db close}
|
||||
forcedelete test.db test.db-wal test.db-journal
|
||||
sqlite3 db test.db
|
||||
execsql {
|
||||
PRAGMA journal_mode = WAL;
|
||||
CREATE TABLE t1(x);
|
||||
INSERT INTO t1 VALUES(randomblob(900));
|
||||
SELECT count(*) FROM t1;
|
||||
}
|
||||
} {wal 1}
|
||||
do_test wal-20.2 {
|
||||
set ::buddy [launch_testfixture]
|
||||
testfixture $::buddy {
|
||||
if {[permutation]!="unix-excl"} {
|
||||
do_test wal-20.1 {
|
||||
catch {db close}
|
||||
forcedelete test.db test.db-wal test.db-journal
|
||||
sqlite3 db test.db
|
||||
db transaction { db eval {
|
||||
PRAGMA wal_autocheckpoint = 0;
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 2 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 4 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 8 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 16 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 32 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 64 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 128 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 256 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 512 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 1024 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 2048 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 4096 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 8192 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 16384 */
|
||||
} }
|
||||
}
|
||||
} {0}
|
||||
do_test wal-20.3 {
|
||||
close $::buddy
|
||||
execsql { PRAGMA wal_checkpoint }
|
||||
execsql { SELECT count(*) FROM t1 }
|
||||
} {16384}
|
||||
do_test wal-20.4 {
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
execsql { SELECT count(*) FROM t1 }
|
||||
} {16384}
|
||||
integrity_check wal-20.5
|
||||
execsql {
|
||||
PRAGMA journal_mode = WAL;
|
||||
CREATE TABLE t1(x);
|
||||
INSERT INTO t1 VALUES(randomblob(900));
|
||||
SELECT count(*) FROM t1;
|
||||
}
|
||||
} {wal 1}
|
||||
do_test wal-20.2 {
|
||||
set ::buddy [launch_testfixture]
|
||||
testfixture $::buddy {
|
||||
sqlite3 db test.db
|
||||
db transaction { db eval {
|
||||
PRAGMA wal_autocheckpoint = 0;
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 2 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 4 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 8 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 16 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 32 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 64 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 128 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 256 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 512 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 1024 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 2048 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 4096 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 8192 */
|
||||
INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 16384 */
|
||||
} }
|
||||
}
|
||||
} {0}
|
||||
do_test wal-20.3 {
|
||||
close $::buddy
|
||||
execsql { PRAGMA wal_checkpoint }
|
||||
execsql { SELECT count(*) FROM t1 }
|
||||
} {16384}
|
||||
do_test wal-20.4 {
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
execsql { SELECT count(*) FROM t1 }
|
||||
} {16384}
|
||||
integrity_check wal-20.5
|
||||
}
|
||||
|
||||
catch { db2 close }
|
||||
catch { db close }
|
||||
|
||||
Reference in New Issue
Block a user