aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/lock_common.tcl10
-rw-r--r--test/shmlock.test173
-rw-r--r--test/wal.test90
3 files changed, 225 insertions, 48 deletions
diff --git a/test/lock_common.tcl b/test/lock_common.tcl
index a758e7af2..3e1821bab 100644
--- a/test/lock_common.tcl
+++ b/test/lock_common.tcl
@@ -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 }
diff --git a/test/shmlock.test b/test/shmlock.test
new file mode 100644
index 000000000..6910758b8
--- /dev/null
+++ b/test/shmlock.test
@@ -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
+
+
diff --git a/test/wal.test b/test/wal.test
index bb164bb76..a003b6ad2 100644
--- a/test/wal.test
+++ b/test/wal.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 }