1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/sqlite3api/TEST/TclScript/lock2.test Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,169 @@
1.4 +# 2001 September 15
1.5 +#
1.6 +# The author disclaims copyright to this source code. In place of
1.7 +# a legal notice, here is a blessing:
1.8 +#
1.9 +# May you do good and not evil.
1.10 +# May you find forgiveness for yourself and forgive others.
1.11 +# May you share freely, never taking more than you give.
1.12 +#
1.13 +#***********************************************************************
1.14 +# This file implements regression tests for SQLite library. The
1.15 +# focus of this script is database locks between competing processes.
1.16 +#
1.17 +# $Id: lock2.test,v 1.9 2007/12/13 21:54:11 drh Exp $
1.18 +
1.19 +
1.20 +set testdir [file dirname $argv0]
1.21 +source $testdir/tester.tcl
1.22 +
1.23 +# Launch another testfixture process to be controlled by this one. A
1.24 +# channel name is returned that may be passed as the first argument to proc
1.25 +# 'testfixture' to execute a command. The child testfixture process is shut
1.26 +# down by closing the channel.
1.27 +proc launch_testfixture {} {
1.28 + set prg [info nameofexec]
1.29 + if {$prg eq ""} {
1.30 + set prg [file join . testfixture]
1.31 + }
1.32 + set chan [open "|$prg tf_main.tcl" r+]
1.33 + fconfigure $chan -buffering line
1.34 + return $chan
1.35 +}
1.36 +
1.37 +# Execute a command in a child testfixture process, connected by two-way
1.38 +# channel $chan. Return the result of the command, or an error message.
1.39 +proc testfixture {chan cmd} {
1.40 + puts $chan $cmd
1.41 + puts $chan OVER
1.42 + set r ""
1.43 + while { 1 } {
1.44 + set line [gets $chan]
1.45 + if { $line == "OVER" } {
1.46 + return $r
1.47 + }
1.48 + append r $line
1.49 + }
1.50 +}
1.51 +
1.52 +# Write the main loop for the child testfixture processes into file
1.53 +# tf_main.tcl. The parent (this script) interacts with the child processes
1.54 +# via a two way pipe. The parent writes a script to the stdin of the child
1.55 +# process, followed by the word "OVER" on a line of its own. The child
1.56 +# process evaluates the script and writes the results to stdout, followed
1.57 +# by an "OVER" of its own.
1.58 +set f [open tf_main.tcl w]
1.59 +puts $f {
1.60 + set l [open log w]
1.61 + set script ""
1.62 + while {![eof stdin]} {
1.63 + flush stdout
1.64 + set line [gets stdin]
1.65 + puts $l "READ $line"
1.66 + if { $line == "OVER" } {
1.67 + catch {eval $script} result
1.68 + puts $result
1.69 + puts $l "WRITE $result"
1.70 + puts OVER
1.71 + puts $l "WRITE OVER"
1.72 + flush stdout
1.73 + set script ""
1.74 + } else {
1.75 + append script $line
1.76 + append script " ; "
1.77 + }
1.78 + }
1.79 + close $l
1.80 +}
1.81 +close $f
1.82 +
1.83 +# Simple locking test case:
1.84 +#
1.85 +# lock2-1.1: Connect a second process to the database.
1.86 +# lock2-1.2: Establish a RESERVED lock with this process.
1.87 +# lock2-1.3: Get a SHARED lock with the second process.
1.88 +# lock2-1.4: Try for a RESERVED lock with process 2. This fails.
1.89 +# lock2-1.5: Try to upgrade the first process to EXCLUSIVE, this fails so
1.90 +# it gets PENDING.
1.91 +# lock2-1.6: Release the SHARED lock held by the second process.
1.92 +# lock2-1.7: Attempt to reaquire a SHARED lock with the second process.
1.93 +# this fails due to the PENDING lock.
1.94 +# lock2-1.8: Ensure the first process can now upgrade to EXCLUSIVE.
1.95 +#
1.96 +do_test lock2-1.1 {
1.97 + set ::tf1 [launch_testfixture]
1.98 + testfixture $::tf1 "set sqlite_pending_byte $::sqlite_pending_byte"
1.99 + testfixture $::tf1 {
1.100 + sqlite3 db test.db -key xyzzy
1.101 + db eval {select * from sqlite_master}
1.102 + }
1.103 +} {}
1.104 +do_test lock2-1.1.1 {
1.105 + execsql {pragma lock_status}
1.106 +} {main unlocked temp closed}
1.107 +sqlite3_soft_heap_limit 0
1.108 +do_test lock2-1.2 {
1.109 + execsql {
1.110 + BEGIN;
1.111 + CREATE TABLE abc(a, b, c);
1.112 + }
1.113 +} {}
1.114 +do_test lock2-1.3 {
1.115 + testfixture $::tf1 {
1.116 + db eval {
1.117 + BEGIN;
1.118 + SELECT * FROM sqlite_master;
1.119 + }
1.120 + }
1.121 +} {}
1.122 +do_test lock2-1.4 {
1.123 + testfixture $::tf1 {
1.124 + db eval {
1.125 + CREATE TABLE def(d, e, f)
1.126 + }
1.127 + }
1.128 +} {database is locked}
1.129 +do_test lock2-1.5 {
1.130 + catchsql {
1.131 + COMMIT;
1.132 + }
1.133 +} {1 {database is locked}}
1.134 +do_test lock2-1.6 {
1.135 + testfixture $::tf1 {
1.136 + db eval {
1.137 + SELECT * FROM sqlite_master;
1.138 + COMMIT;
1.139 + }
1.140 + }
1.141 +} {}
1.142 +do_test lock2-1.7 {
1.143 + testfixture $::tf1 {
1.144 + db eval {
1.145 + BEGIN;
1.146 + SELECT * FROM sqlite_master;
1.147 + }
1.148 + }
1.149 +} {database is locked}
1.150 +do_test lock2-1.8 {
1.151 + catchsql {
1.152 + COMMIT;
1.153 + }
1.154 +} {0 {}}
1.155 +do_test lock2-1.9 {
1.156 + execsql {
1.157 + SELECT * FROM sqlite_master;
1.158 + }
1.159 +} "table abc abc [expr $AUTOVACUUM?3:2] {CREATE TABLE abc(a, b, c)}"
1.160 +do_test lock2-1.10 {
1.161 + testfixture $::tf1 {
1.162 + db eval {
1.163 + SELECT * FROM sqlite_master;
1.164 + }
1.165 + }
1.166 +} "table abc abc [expr $AUTOVACUUM?3:2] {CREATE TABLE abc(a, b, c)}"
1.167 +
1.168 +catch {testfixture $::tf1 {db close}}
1.169 +catch {close $::tf1}
1.170 +sqlite3_soft_heap_limit $soft_limit
1.171 +
1.172 +finish_test