1e264d983Sdan# 2010 April 14 2e264d983Sdan# 3e264d983Sdan# The author disclaims copyright to this source code. In place of 4e264d983Sdan# a legal notice, here is a blessing: 5e264d983Sdan# 6e264d983Sdan# May you do good and not evil. 7e264d983Sdan# May you find forgiveness for yourself and forgive others. 8e264d983Sdan# May you share freely, never taking more than you give. 9e264d983Sdan# 10e264d983Sdan#*********************************************************************** 11e264d983Sdan# This file contains code used by several different test scripts. The 12e264d983Sdan# code in this file allows testfixture to control another process (or 13e264d983Sdan# processes) to test locking. 14e264d983Sdan# 15e264d983Sdan 16e264d983Sdan# Launch another testfixture process to be controlled by this one. A 17e264d983Sdan# channel name is returned that may be passed as the first argument to proc 18e264d983Sdan# 'testfixture' to execute a command. The child testfixture process is shut 19e264d983Sdan# down by closing the channel. 20e264d983Sdanproc launch_testfixture {} { 21e264d983Sdan set prg [info nameofexec] 22e264d983Sdan if {$prg eq ""} { 23e264d983Sdan set prg [file join . testfixture] 24e264d983Sdan } 25e264d983Sdan set chan [open "|$prg tf_main.tcl" r+] 26e264d983Sdan fconfigure $chan -buffering line 2731f98fc8Sdan testfixture $chan "sqlite3_test_control_pending_byte $::sqlite_pending_byte" 28e264d983Sdan return $chan 29e264d983Sdan} 30e264d983Sdan 31e264d983Sdan# Execute a command in a child testfixture process, connected by two-way 32e264d983Sdan# channel $chan. Return the result of the command, or an error message. 33*e91a54e1Sdan# 34e264d983Sdanproc testfixture {chan cmd} { 35e264d983Sdan puts $chan $cmd 36e264d983Sdan puts $chan OVER 37e264d983Sdan set r "" 38e264d983Sdan while { 1 } { 39e264d983Sdan set line [gets $chan] 40e264d983Sdan if { $line == "OVER" } { 41*e91a54e1Sdan set res [lindex $r 1] 42*e91a54e1Sdan if { [lindex $r 0] } { error $res } 43*e91a54e1Sdan return $res 44e264d983Sdan } 45e264d983Sdan if {[eof $chan]} { 46e264d983Sdan return "ERROR: Child process hung up" 47e264d983Sdan } 48e264d983Sdan append r $line 49e264d983Sdan } 50e264d983Sdan} 51e264d983Sdan 525e0ce87aSdanproc testfixture_nb_cb {varname chan} { 53f9b76710Sdan if {[eof $chan]} { 54f9b76710Sdan append ::tfnb($chan) "ERROR: Child process hung up" 55f9b76710Sdan set line "OVER" 56f9b76710Sdan } else { 575e0ce87aSdan set line [gets $chan] 58f9b76710Sdan } 59f9b76710Sdan 605e0ce87aSdan if { $line == "OVER" } { 61*e91a54e1Sdan set $varname [lindex $::tfnb($chan) 1] 625e0ce87aSdan unset ::tfnb($chan) 635e0ce87aSdan close $chan 645e0ce87aSdan } else { 655e0ce87aSdan append ::tfnb($chan) $line 665e0ce87aSdan } 675e0ce87aSdan} 685e0ce87aSdan 695e0ce87aSdanproc testfixture_nb {varname cmd} { 705e0ce87aSdan set chan [launch_testfixture] 715e0ce87aSdan set ::tfnb($chan) "" 725e0ce87aSdan fconfigure $chan -blocking 0 -buffering none 735e0ce87aSdan puts $chan $cmd 745e0ce87aSdan puts $chan OVER 755e0ce87aSdan fileevent $chan readable [list testfixture_nb_cb $varname $chan] 765e0ce87aSdan return "" 775e0ce87aSdan} 785e0ce87aSdan 79e264d983Sdan# Write the main loop for the child testfixture processes into file 80e264d983Sdan# tf_main.tcl. The parent (this script) interacts with the child processes 81e264d983Sdan# via a two way pipe. The parent writes a script to the stdin of the child 82e264d983Sdan# process, followed by the word "OVER" on a line of its own. The child 83e264d983Sdan# process evaluates the script and writes the results to stdout, followed 84e264d983Sdan# by an "OVER" of its own. 85e264d983Sdanset f [open tf_main.tcl w] 86e264d983Sdanputs $f { 87e264d983Sdan set l [open log w] 88e264d983Sdan set script "" 89e264d983Sdan while {![eof stdin]} { 90e264d983Sdan flush stdout 91e264d983Sdan set line [gets stdin] 92e264d983Sdan puts $l "READ $line" 93e264d983Sdan if { $line == "OVER" } { 945e0ce87aSdan set rc [catch {eval $script} result] 95*e91a54e1Sdan puts [list $rc $result] 96*e91a54e1Sdan puts $l "WRITE [list $rc $result]" 97e264d983Sdan puts OVER 98e264d983Sdan puts $l "WRITE OVER" 99e264d983Sdan flush stdout 100e264d983Sdan set script "" 101e264d983Sdan } else { 102e264d983Sdan append script $line 1035e0ce87aSdan append script "\n" 104e264d983Sdan } 105e264d983Sdan } 106e264d983Sdan close $l 107e264d983Sdan} 108e264d983Sdanclose $f 109