📄 socket.test
字号:
# Commands tested in this file: socket.## This file contains a collection of tests for one or more of the Tcl# built-in commands. Sourcing this file into Tcl runs the tests and# generates output for errors. No output means no errors were found.## Copyright (c) 1994-1996 Sun Microsystems, Inc.# Copyright (c) 1998-2000 Ajuba Solutions.## See the file "license.terms" for information on usage and redistribution# of this file, and for a DISCLAIMER OF ALL WARRANTIES.## RCS: @(#) $Id: socket.test,v 1.26 2002/07/10 11:56:45 dgp Exp $# Running socket tests with a remote server:# ------------------------------------------# # Some tests in socket.test depend on the existence of a remote server to# which they connect. The remote server must be an instance of tcltest and it# must run the script found in the file "remote.tcl" in this directory. You# can start the remote server on any machine reachable from the machine on# which you want to run the socket tests, by issuing:# # tcltest remote.tcl -port 2048 # Or choose another port number.# # If the machine you are running the remote server on has several IP# interfaces, you can choose which interface the server listens on for# connections by specifying the -address command line flag, so:# # tcltest remote.tcl -address your.machine.com# # These options can also be set by environment variables. On Unix, you can# type these commands to the shell from which the remote server is started:# # shell% setenv serverPort 2048# shell% setenv serverAddress your.machine.com# # and subsequently you can start the remote server with:# # tcltest remote.tcl# # to have it listen on port 2048 on the interface your.machine.com.# # When the server starts, it prints out a detailed message containing its# configuration information, and it will block until killed with a Ctrl-C.# Once the remote server exists, you can run the tests in socket.test with# the server by setting two Tcl variables:# # % set remoteServerIP <name or address of machine on which server runs># % set remoteServerPort 2048# # These variables are also settable from the environment. On Unix, you can:# # shell% setenv remoteServerIP machine.where.server.runs# shell% senetv remoteServerPort 2048# # The preamble of the socket.test file checks to see if the variables are set# either in Tcl or in the environment; if they are, it attempts to connect to# the server. If the connection is successful, the tests using the remote# server will be performed; otherwise, it will attempt to start the remote# server (via exec) on platforms that support this, on the local host,# listening at port 2048. If all fails, a message is printed and the tests# using the remote server are not performed.package require tcltest 2namespace import -force ::tcltest::*# Some tests require the testthread and exec commandstestConstraint testthread [llength [info commands testthread]]testConstraint exec [llength [info commands exec]]# If remoteServerIP or remoteServerPort are not set, check in the# environment variables for externally set values.#if {![info exists remoteServerIP]} { if {[info exists env(remoteServerIP)]} { set remoteServerIP $env(remoteServerIP) }}if {![info exists remoteServerPort]} { if {[info exists env(remoteServerIP)]} { set remoteServerPort $env(remoteServerPort) } else { if {[info exists remoteServerIP]} { set remoteServerPort 2048 } }}## Check if we're supposed to do tests against the remote server#set doTestsWithRemoteServer 1if {![info exists remoteServerIP] && ($tcl_platform(platform) != "macintosh")} { set remoteServerIP 127.0.0.1}if {($doTestsWithRemoteServer == 1) && (![info exists remoteServerPort])} { set remoteServerPort 2048}# Attempt to connect to a remote server if one is already running. If it# is not running or for some other reason the connect fails, attempt to# start the remote server on the local host listening on port 2048. This# is only done on platforms that support exec (i.e. not on the Mac). On# platforms that do not support exec, the remote server must be started# by the user before running the tests.set remoteProcChan ""set commandSocket ""if {$doTestsWithRemoteServer} { catch {close $commandSocket} if {[catch {set commandSocket [socket $remoteServerIP \ $remoteServerPort]}] != 0} { if {[info commands exec] == ""} { set noRemoteTestReason "can't exec" set doTestsWithRemoteServer 0 } else { set remoteServerIP 127.0.0.1 # Be *extra* careful in case this file is sourced from # a directory other than the current one... set remoteFile [file join [pwd] [file dirname [info script]] \ remote.tcl] if {[catch {set remoteProcChan \ [open "|[list [interpreter] $remoteFile \ -serverIsSilent \ -port $remoteServerPort \ -address $remoteServerIP]" \ w+]} \ msg] == 0} { after 1000 if {[catch {set commandSocket [socket $remoteServerIP \ $remoteServerPort]} msg] == 0} { fconfigure $commandSocket -translation crlf -buffering line } else { set noRemoteTestReason $msg set doTestsWithRemoteServer 0 } } else { set noRemoteTestReason "$msg [interpreter]" set doTestsWithRemoteServer 0 } } } else { fconfigure $commandSocket -translation crlf -buffering line }}# Some tests are run only if we are doing testing against a remote server.set ::tcltest::testConstraints(doTestsWithRemoteServer) $doTestsWithRemoteServerif {$doTestsWithRemoteServer == 0} { if {[string first s $::tcltest::verbose] != -1} { puts "Skipping tests with remote server. See tests/socket.test for" puts "information on how to run remote server." puts "Reason for not doing remote tests: $noRemoteTestReason" }}## If we do the tests, define a command to send a command to the# remote server.#if {$doTestsWithRemoteServer == 1} { proc sendCommand {c} { global commandSocket if {[eof $commandSocket]} { error "remote server disappeared" } if {[catch {puts $commandSocket $c} msg]} { error "remote server disappaered: $msg" } if {[catch {puts $commandSocket "--Marker--Marker--Marker--"} msg]} { error "remote server disappeared: $msg" } set resp "" while {1} { set line [gets $commandSocket] if {[eof $commandSocket]} { error "remote server disappaered" } if {[string compare $line "--Marker--Marker--Marker--"] == 0} { if {[string compare [lindex $resp 0] error] == 0} { error [lindex $resp 1] } else { return [lindex $resp 1] } } else { append resp $line "\n" } } }}test socket-1.1 {arg parsing for socket command} {socket} { list [catch {socket -server} msg] $msg} {1 {no argument given for -server option}}test socket-1.2 {arg parsing for socket command} {socket} { list [catch {socket -server foo} msg] $msg} {1 {wrong # args: should be either:socket ?-myaddr addr? ?-myport myport? ?-async? host portsocket -server command ?-myaddr addr? port}}test socket-1.3 {arg parsing for socket command} {socket} { list [catch {socket -myaddr} msg] $msg} {1 {no argument given for -myaddr option}}test socket-1.4 {arg parsing for socket command} {socket} { list [catch {socket -myaddr 127.0.0.1} msg] $msg} {1 {wrong # args: should be either:socket ?-myaddr addr? ?-myport myport? ?-async? host portsocket -server command ?-myaddr addr? port}}test socket-1.5 {arg parsing for socket command} {socket} { list [catch {socket -myport} msg] $msg} {1 {no argument given for -myport option}}test socket-1.6 {arg parsing for socket command} {socket} { list [catch {socket -myport xxxx} msg] $msg} {1 {expected integer but got "xxxx"}}test socket-1.7 {arg parsing for socket command} {socket} { list [catch {socket -myport 2522} msg] $msg} {1 {wrong # args: should be either:socket ?-myaddr addr? ?-myport myport? ?-async? host portsocket -server command ?-myaddr addr? port}}test socket-1.8 {arg parsing for socket command} {socket} { list [catch {socket -froboz} msg] $msg} {1 {bad option "-froboz": must be -async, -myaddr, -myport, or -server}}test socket-1.9 {arg parsing for socket command} {socket} { list [catch {socket -server foo -myport 2521 3333} msg] $msg} {1 {Option -myport is not valid for servers}}test socket-1.10 {arg parsing for socket command} {socket} { list [catch {socket host 2528 -junk} msg] $msg} {1 {wrong # args: should be either:socket ?-myaddr addr? ?-myport myport? ?-async? host portsocket -server command ?-myaddr addr? port}}test socket-1.11 {arg parsing for socket command} {socket} { list [catch {socket -server callback 2520 --} msg] $msg} {1 {wrong # args: should be either:socket ?-myaddr addr? ?-myport myport? ?-async? host portsocket -server command ?-myaddr addr? port}}test socket-1.12 {arg parsing for socket command} {socket} { list [catch {socket foo badport} msg] $msg} {1 {expected integer but got "badport"}}set path(script) [makeFile {} script]test socket-2.1 {tcp connection} {socket stdio} { removeFile script set f [open $path(script) w] puts $f { set timer [after 10000 "set x timed_out"] set f [socket -server accept 0] proc accept {file addr port} { global x set x done close $file } puts ready puts [lindex [fconfigure $f -sockname] 2] vwait x after cancel $timer close $f puts $x } close $f set f [open "|[list [interpreter] $path(script)]" r] gets $f x gets $f listen if {[catch {socket 127.0.0.1 $listen} msg]} { set x $msg } else { lappend x [gets $f] close $msg } lappend x [gets $f] close $f set x} {ready done {}}if [info exists port] { incr port} else { set port [expr 2048 + [pid]%1024]}test socket-2.2 {tcp connection with client port specified} {socket stdio} { removeFile script set f [open $path(script) w] puts $f { set timer [after 10000 "set x timeout"] set f [socket -server accept 0] proc accept {file addr port} { global x puts "[gets $file] $port" close $file set x done } puts ready puts [lindex [fconfigure $f -sockname] 2] vwait x after cancel $timer close $f } close $f set f [open "|[list [interpreter] $path(script)]" r] gets $f x gets $f listen global port if {[catch {socket -myport $port 127.0.0.1 $listen} sock]} { set x $sock close [socket 127.0.0.1 $listen] puts stderr $sock } else { puts $sock hello flush $sock lappend x [gets $f] close $sock } close $f set x} [list ready "hello $port"]test socket-2.3 {tcp connection with client interface specified} {socket stdio} { removeFile script set f [open $path(script) w] puts $f { set timer [after 2000 "set x done"] set f [socket -server accept 2830] proc accept {file addr port} { global x puts "[gets $file] $addr" close $file set x done } puts ready vwait x after cancel $timer close $f } close $f set f [open "|[list [interpreter] $path(script)]" r] gets $f x if {[catch {socket -myaddr 127.0.0.1 127.0.0.1 2830} sock]} { set x $sock } else { puts $sock hello flush $sock lappend x [gets $f] close $sock } close $f set x} {ready {hello 127.0.0.1}}test socket-2.4 {tcp connection with server interface specified} {socket stdio} { removeFile script set f [open $path(script) w] puts $f { set timer [after 2000 "set x done"] set f [socket -server accept -myaddr 127.0.0.1 0] proc accept {file addr port} { global x puts "[gets $file]" close $file set x done } puts ready puts [lindex [fconfigure $f -sockname] 2] vwait x after cancel $timer close $f } close $f set f [open "|[list [interpreter] $path(script)]" r] gets $f x gets $f listen if {[catch {socket 127.0.0.1 $listen} sock]} { set x $sock } else { puts $sock hello flush $sock lappend x [gets $f] close $sock } close $f set x} {ready hello}test socket-2.5 {tcp connection with redundant server port} {socket stdio} { removeFile script set f [open $path(script) w] puts $f { set timer [after 10000 "set x timeout"] set f [socket -server accept 0] proc accept {file addr port} { global x puts "[gets $file]" close $file set x done } puts ready puts [lindex [fconfigure $f -sockname] 2] vwait x after cancel $timer close $f } close $f set f [open "|[list [interpreter] $path(script)]" r] gets $f x gets $f listen if {[catch {socket 127.0.0.1 $listen} sock]} { set x $sock } else { puts $sock hello flush $sock lappend x [gets $f] close $sock } close $f set x} {ready hello}test socket-2.6 {tcp connection} {socket} { set status ok if {![catch {set sock [socket 127.0.0.1 2833]}]} { if {![catch {gets $sock}]} { set status broken } close $sock } set status} oktest socket-2.7 {echo server, one line} {socket stdio} { removeFile script set f [open $path(script) w] puts $f { set timer [after 10000 "set x timeout"] set f [socket -server accept 0] proc accept {s a p} { fileevent $s readable [list echo $s] fconfigure $s -translation lf -buffering line } proc echo {s} { set l [gets $s] if {[eof $s]} { global x close $s set x done } else { puts $s $l } } puts ready puts [lindex [fconfigure $f -sockname] 2] vwait x after cancel $timer close $f puts $x } close $f set f [open "|[list [interpreter] $path(script)]" r] gets $f gets $f listen set s [socket 127.0.0.1 $listen] fconfigure $s -buffering line -translation lf puts $s "hello abcdefghijklmnop" after 1000 set x [gets $s] close $s set y [gets $f] close $f list $x $y} {{hello abcdefghijklmnop} done}test socket-2.8 {echo server, loop 50 times, single connection} {socket stdio} { makeFile { set f [socket -server accept 0] proc accept {s a p} { fileevent $s readable [list echo $s] fconfigure $s -buffering line } proc echo {s} { global i set l [gets $s] if {[eof $s]} { global x close $s set x done } else { incr i puts $s $l } } set i 0 puts ready puts [lindex [fconfigure $f -sockname] 2] set timer [after 20000 "set x done"] vwait x after cancel $timer close $f puts "done $i" } script set f [open "|[list [interpreter] $path(script)]" r] gets $f gets $f listen set s [socket 127.0.0.1 $listen] fconfigure $s -buffering line catch { for {set x 0} {$x < 50} {incr x} { puts $s "hello abcdefghijklmnop" gets $s } } close $s catch {set x [gets $f]} close $f set x} {done 50}test socket-2.9 {socket conflict} {socket stdio} { set s [socket -server accept 0] removeFile script set f [open $path(script) w] puts -nonewline $f "socket -server accept [lindex [fconfigure $s -sockname] 2]" close $f set f [open "|[list [interpreter] $path(script)]" r] gets $f after 100 set x [list [catch {close $f} msg]] regsub "\n.*$" $msg {} msg ; # cut part of the error message containing the port number lappend x $msg close $s set x} {1 {couldn't open socket: address already in use}}test socket-2.10 {close on accept, accepted socket lives} {socket} { set done 0 set timer [after 20000 "set done timed_out"] set ss [socket -server accept 0] proc accept {s a p} { global ss close $ss fileevent $s readable "readit $s" fconfigure $s -trans lf } proc readit {s} { global done gets $s close $s set done 1 } set cs [socket [info hostname] [lindex [fconfigure $ss -sockname] 2]] puts $cs hello close $cs vwait done after cancel $timer set done} 1test socket-2.11 {detecting new data} {socket} { proc accept {s a p} { global sock set sock $s } set s [socket -server accept 0] set sock "" set s2 [socket 127.0.0.1 [lindex [fconfigure $s -sockname] 2]] vwait sock
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -