1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-05 15:55:57 +03:00

Add test file pager1.test, containing tests of inter-process locking in non-wal mode.

FossilOrigin-Name: 6e43eed9310bae9ca5e91f8fd9eafc45a16b7019
This commit is contained in:
dan
2010-06-15 17:44:47 +00:00
parent 3a3803b61a
commit e91a54e1be
6 changed files with 235 additions and 27 deletions

View File

@@ -1,5 +1,5 @@
C Run\sextra\siterations\sin\swal3.test\sto\sensure\stest\scoverage.
D 2010-06-15T14:21:17
C Add\stest\sfile\spager1.test,\scontaining\stests\sof\sinter-process\slocking\sin\snon-wal\smode.
D 2010-06-15T17:44:48
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -484,7 +484,7 @@ F test/lock4.test f4f36271aa5ae1da449646bf43c7341f6b2b4c4e
F test/lock5.test 6b1f78f09ad1522843dad571b76b321e6f439bf7
F test/lock6.test 8df56060f396151777390982422c800d026e1722
F test/lock7.test 64006c84c1c616657e237c7ad6532b765611cf64
F test/lock_common.tcl 69d6b67f2ba63968ec2173bcd7310c5c7eca00a2
F test/lock_common.tcl c03802ef77c3864f1a7d812b0760b59563f2613b
F test/lookaside.test 1dd350dc6dff015c47c07fcc5a727a72fc5bae02
F test/main.test 2be2352ac77ac5b238c6337a5469aeeef57677e6
F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
@@ -533,17 +533,18 @@ F test/notify2.test 195a467e021f74197be2c4fb02d6dee644b8d8db
F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347
F test/null.test a8b09b8ed87852742343b33441a9240022108993
F test/openv2.test af02ed0a9cbc0d2a61b8f35171d4d117e588e4ec
F test/pager1.test dcc50ea9c4fc8d6d7101733644655c8395826e9b
F test/pageropt.test 8146bf448cf09e87bb1867c2217b921fb5857806
F test/pagesize.test 76aa9f23ecb0741a4ed9d2e16c5fa82671f28efb
F test/pcache.test eebc4420b37cb07733ae9b6e99c9da7c40dd6d58
F test/pcache2.test 0d85f2ab6963aee28c671d4c71bec038c00a1d16
F test/permutations.test 28f46dfcc880e15ec7ab1ff36d12af765a0e3bc4
F test/permutations.test 403099a8e191b43e5df19b8199b80178b3ece1d6
F test/pragma.test 6960f9efbce476f70ba9ee2171daf5042f9e3d8a
F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47
F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea
F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
F test/quick.test d2a697cf6d6db2725649670859365ef601289f96
F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6
F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459
F test/randexpr1.test 1084050991e9ba22c1c10edd8d84673b501cc25a
@@ -820,7 +821,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P 03c0f4fd9cbb655477b63ebbb6af7822715644aa
R a2075e9740cf75b8937129b9cbcda629
P ea80cbe51e33d6a3f15a4ad56f360fc5323866de
R 2d037491154b033cfc4dcca7e9e50afd
U dan
Z 73996e320eea715ffc64316616623fba
Z 2d173a77ac2cf0416b30cd54aeed8e9e

View File

@@ -1 +1 @@
ea80cbe51e33d6a3f15a4ad56f360fc5323866de
6e43eed9310bae9ca5e91f8fd9eafc45a16b7019

View File

@@ -30,6 +30,7 @@ proc launch_testfixture {} {
# Execute a command in a child testfixture process, connected by two-way
# channel $chan. Return the result of the command, or an error message.
#
proc testfixture {chan cmd} {
puts $chan $cmd
puts $chan OVER
@@ -37,7 +38,9 @@ proc testfixture {chan cmd} {
while { 1 } {
set line [gets $chan]
if { $line == "OVER" } {
return $r
set res [lindex $r 1]
if { [lindex $r 0] } { error $res }
return $res
}
if {[eof $chan]} {
return "ERROR: Child process hung up"
@@ -55,7 +58,7 @@ proc testfixture_nb_cb {varname chan} {
}
if { $line == "OVER" } {
set $varname $::tfnb($chan)
set $varname [lindex $::tfnb($chan) 1]
unset ::tfnb($chan)
close $chan
} else {
@@ -89,8 +92,8 @@ puts $f {
puts $l "READ $line"
if { $line == "OVER" } {
set rc [catch {eval $script} result]
puts $result
puts $l "WRITE $result"
puts [list $rc $result]
puts $l "WRITE [list $rc $result]"
puts OVER
puts $l "WRITE OVER"
flush stdout

194
test/pager1.test Normal file
View File

@@ -0,0 +1,194 @@
# 2010 June 15
#
# 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
source $testdir/lock_common.tcl
source $testdir/malloc_common.tcl
foreach code [list {
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
} {
proc code2 {tcl} { uplevel #0 $tcl }
proc code3 {tcl} { uplevel #0 $tcl }
set tn 2
}] {
faultsim_delete_and_reopen
# Open connections [db2] and [db3]. Depending on which iteration this
# is, the connections may be created in this interpreter, or in
# interpreters running in other OS processes. As such, the [db2] and [db3]
# commands should only be accessed within [code2] and [code3] blocks,
# respectively.
#
eval $code
code2 { sqlite3 db2 test.db }
code3 { sqlite3 db3 test.db }
# Shorthand commands. Execute SQL using database connection [db2] or
# [db3]. Return the results.
#
proc sql1 {sql} { db eval $sql }
proc sql2 {sql} { code2 [list db2 eval $sql] }
proc sql3 {sql} { code3 [list db3 eval $sql] }
proc csql1 {sql} { list [catch { sql1 $sql } msg] $msg }
proc csql2 {sql} { list [catch { sql2 $sql } msg] $msg }
proc csql3 {sql} { list [catch { sql3 $sql } msg] $msg }
# Create and populate a database table using connection [db]. Check
# that connections [db2] and [db3] can see the schema and content.
#
do_test pager1-$tn.1 {
sql1 {
CREATE TABLE t1(a PRIMARY KEY, b);
CREATE INDEX i1 ON t1(b);
INSERT INTO t1 VALUES(1, 'one');
INSERT INTO t1 VALUES(2, 'two');
}
} {}
do_test pager1-$tn.2 { sql2 { SELECT * FROM t1 } } {1 one 2 two}
do_test pager1-$tn.3 { sql3 { SELECT * FROM t1 } } {1 one 2 two}
# Open a transaction and add a row using [db]. This puts [db] in
# RESERVED state. Check that connections [db2] and [db3] can still
# read the database content as it was before the transaction was
# opened. [db] should see the inserted row.
#
do_test pager1-$tn.4 {
sql1 {
BEGIN;
INSERT INTO t1 VALUES(3, 'three');
}
} {}
do_test pager1-$tn.5 { sql2 { SELECT * FROM t1 } } {1 one 2 two}
do_test pager1-$tn.6 { sql3 { SELECT * FROM t1 } } {1 one 2 two}
do_test pager1-$tn.7 { sql1 { SELECT * FROM t1 } } {1 one 2 two 3 three}
# [db] still has an open write transaction. Check that this prevents
# other connections (specifically [db2]) from writing to the database.
#
# Even if [db2] opens a transaction first, it may not write to the
# database. After the attempt to write the db within a transaction,
# [db2] is left with an open transaction, but not a read-lock on
# the main database. So it does not prevent [db] from committing.
#
do_test pager1-$tn.8 {
csql2 { UPDATE t1 SET a = a + 10 }
} {1 {database is locked}}
do_test pager1-$tn.9 {
csql2 {
BEGIN;
UPDATE t1 SET a = a + 10;
}
} {1 {database is locked}}
# Have [db] commit its transactions. Check the other connections can
# now see the new database content.
#
do_test pager1-$tn.10 { sql1 { COMMIT } } {}
do_test pager1-$tn.11 { sql1 { SELECT * FROM t1 } } {1 one 2 two 3 three}
do_test pager1-$tn.12 { sql2 { SELECT * FROM t1 } } {1 one 2 two 3 three}
do_test pager1-$tn.13 { sql3 { SELECT * FROM t1 } } {1 one 2 two 3 three}
# Check that, as noted above, [db2] really did keep an open transaction
# after the attempt to write the database failed.
#
do_test pager1-$tn.14 {
csql2 { BEGIN }
} {1 {cannot start a transaction within a transaction}}
do_test pager1-$tn.15 { sql2 { ROLLBACK } } {}
# Have [db2] open a transaction and take a read-lock on the database.
# Check that this prevents [db] from writing to the database (outside
# of any transaction). After this fails, check that [db3] can read
# the db (showing that [db] did not take a PENDING lock etc.)
#
do_test pager1-$tn.15 {
sql2 { BEGIN; SELECT * FROM t1; }
} {1 one 2 two 3 three}
do_test pager1-$tn.16 {
csql1 { UPDATE t1 SET a = a + 10 }
} {1 {database is locked}}
do_test pager1-$tn.17 { sql3 { SELECT * FROM t1 } } {1 one 2 two 3 three}
# This time, have [db] open a transaction before writing the database.
# This works - [db] gets a RESERVED lock which does not conflict with
# the SHARED lock [db2] is holding.
#
do_test pager1-$tn.18 {
sql1 {
BEGIN;
UPDATE t1 SET a = a + 10;
}
} {}
do_test pager1-$tn-19 {
sql1 { PRAGMA lock_status }
} {main reserved temp closed}
do_test pager1-$tn-20 {
sql2 { PRAGMA lock_status }
} {main shared temp closed}
# Check that all connections can still read the database. Only [db] sees
# the updated content (as the transaction has not been committed yet).
#
do_test pager1-$tn.21 { sql1 { SELECT * FROM t1 } } {11 one 12 two 13 three}
do_test pager1-$tn.22 { sql2 { SELECT * FROM t1 } } {1 one 2 two 3 three}
do_test pager1-$tn.23 { sql3 { SELECT * FROM t1 } } {1 one 2 two 3 three}
# Because [db2] still has the SHARED lock, [db] is unable to commit the
# transaction. If it tries, an error is returned and the connection
# upgrades to a PENDING lock.
#
# Once this happens, [db] can read the database and see the new content,
# [db2] (still holding SHARED) can still read the old content, but [db3]
# (not holding any lock) is prevented by [db]'s PENDING from reading
# the database.
#
do_test pager1-$tn.24 { csql1 { COMMIT } } {1 {database is locked}}
do_test pager1-$tn-25 {
sql1 { PRAGMA lock_status }
} {main pending temp closed}
do_test pager1-$tn.26 { sql1 { SELECT * FROM t1 } } {11 one 12 two 13 three}
do_test pager1-$tn.27 { sql2 { SELECT * FROM t1 } } {1 one 2 two 3 three}
do_test pager1-$tn.28 { csql3 { SELECT * FROM t1 } } {1 {database is locked}}
# Have [db2] commit its read transaction, releasing the SHARED lock it
# is holding. Now, neither [db2] nor [db3] may read the database (as [db]
# is still holding a PENDING).
#
do_test pager1-$tn.29 { sql2 { COMMIT } } {}
do_test pager1-$tn.30 { csql2 { SELECT * FROM t1 } } {1 {database is locked}}
do_test pager1-$tn.31 { csql3 { SELECT * FROM t1 } } {1 {database is locked}}
# [db] is now able to commit the transaction. Once the transaction is
# committed, all three connections can read the new content.
#
do_test pager1-$tn.25 { sql1 { UPDATE t1 SET a = a+10 } } {}
do_test pager1-$tn.26 { sql1 { COMMIT } } {}
do_test pager1-$tn.27 { sql1 { SELECT * FROM t1 } } {21 one 22 two 23 three}
do_test pager1-$tn.27 { sql2 { SELECT * FROM t1 } } {21 one 22 two 23 three}
do_test pager1-$tn.28 { sql3 { SELECT * FROM t1 } } {21 one 22 two 23 three}
code2 { db2 close }
code3 { db3 close }
catch { close $::code2_chan }
catch { close $::code3_chan }
}
finish_test

View File

@@ -9,7 +9,6 @@
#
#***********************************************************************
#
# $Id: permutations.test,v 1.51 2009/07/01 18:09:02 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@@ -48,6 +47,7 @@ proc test_suite {name args} {
set ::testspec($name) [array get options]
lappend ::testsuitelist $name
}
#-------------------------------------------------------------------------
@@ -120,6 +120,7 @@ set allquicktests [test_set $alltests -exclude {
# full
# veryquick_plus_notify2
#
lappend ::testsuitelist xxx
test_suite "veryquick" -description {
"Very" quick test suite. Runs in less than 5 minutes on a workstation.
@@ -150,11 +151,11 @@ test_suite "full" -description {
unset -nocomplain ::G(isquick)
}
lappend ::testsuitelist xxx
#-------------------------------------------------------------------------
# Define the coverage related test suites:
#
# coverage-wal
# coverage-fkey
#
test_suite "coverage-wal" -description {
Coverage tests for file wal.c.
@@ -164,8 +165,14 @@ test_suite "coverage-wal" -description {
walfault.test
}
test_suite "coverage-pager" -description {
Coverage tests for file pager.c.
} -files {
pager1.test
}
lappend ::testsuitelist xxx
#-------------------------------------------------------------------------
# Define the permutation test suites:
#
@@ -803,7 +810,14 @@ proc run_test_suite {name} {
}
proc help {} {
puts "Usage: $::argv0 TESTSUITE ?TESTFILE?"
puts ""
puts "Available test-suites are:"
foreach k $::testsuitelist {
if {[info exists ::testspec($k)]==0} {
puts " ----------------------------------------"
puts ""
} else {
array set o $::testspec($k)
puts "Test suite: \"$k\""
set d [string trim $o(-description)]
@@ -811,6 +825,7 @@ proc help {} {
puts " $d"
puts ""
}
}
exit -1
}

View File

@@ -10,11 +10,6 @@
set testdir [file dirname $argv0]
source $testdir/permutations.test
if {[info exists env(QUICKTEST_INCLUDE]} {
# A hack so that releasetest.tcl keeps working.
run_test_suite quick_plus_notify2
} else {
run_test_suite quick
}
run_test_suite quick
finish_test