1 # Commands tested in this file: socket.
3 # This file contains a collection of tests for one or more of the Tcl
4 # built-in commands. Sourcing this file into Tcl runs the tests and
5 # generates output for errors. No output means no errors were found.
7 # Copyright (c) 1994-1996 Sun Microsystems, Inc.
8 # Copyright (c) 1998-2000 Ajuba Solutions.
10 # See the file "license.terms" for information on usage and redistribution
11 # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
15 # Running socket tests with a remote server:
16 # ------------------------------------------
18 # Some tests in socket.test depend on the existence of a remote server to
19 # which they connect. The remote server must be an instance of tcltest and it
20 # must run the script found in the file "remote.tcl" in this directory. You
21 # can start the remote server on any machine reachable from the machine on
22 # which you want to run the socket tests, by issuing:
24 # tcltest remote.tcl -port 2048 # Or choose another port number.
26 # If the machine you are running the remote server on has several IP
27 # interfaces, you can choose which interface the server listens on for
28 # connections by specifying the -address command line flag, so:
30 # tcltest remote.tcl -address your.machine.com
32 # These options can also be set by environment variables. On Unix, you can
33 # type these commands to the shell from which the remote server is started:
35 # shell% setenv serverPort 2048
36 # shell% setenv serverAddress your.machine.com
38 # and subsequently you can start the remote server with:
42 # to have it listen on port 2048 on the interface your.machine.com.
44 # When the server starts, it prints out a detailed message containing its
45 # configuration information, and it will block until killed with a Ctrl-C.
46 # Once the remote server exists, you can run the tests in socket.test with
47 # the server by setting two Tcl variables:
49 # % set remoteServerIP <name or address of machine on which server runs>
50 # % set remoteServerPort 2048
52 # These variables are also settable from the environment. On Unix, you can:
54 # shell% setenv remoteServerIP machine.where.server.runs
55 # shell% senetv remoteServerPort 2048
57 # The preamble of the socket.test file checks to see if the variables are set
58 # either in Tcl or in the environment; if they are, it attempts to connect to
59 # the server. If the connection is successful, the tests using the remote
60 # server will be performed; otherwise, it will attempt to start the remote
61 # server (via exec) on platforms that support this, on the local host,
62 # listening at port 2048. If all fails, a message is printed and the tests
63 # using the remote server are not performed.
65 if {[lsearch [namespace children] ::tcltest] == -1} {
66 package require tcltest
67 namespace import -force ::tcltest::*
70 # Some tests require the testthread and exec commands
72 set ::tcltest::testConstraints(testthread) \
73 [expr {[info commands testthread] != {}}]
74 set ::tcltest::testConstraints(exec) [expr {[info commands exec] != {}}]
77 # If remoteServerIP or remoteServerPort are not set, check in the
78 # environment variables for externally set values.
81 if {![info exists remoteServerIP]} {
82 if {[info exists env(remoteServerIP)]} {
83 set remoteServerIP $env(remoteServerIP)
86 if {![info exists remoteServerPort]} {
87 if {[info exists env(remoteServerIP)]} {
88 set remoteServerPort $env(remoteServerPort)
90 if {[info exists remoteServerIP]} {
91 set remoteServerPort 2048
97 # Check if we're supposed to do tests against the remote server
100 set doTestsWithRemoteServer 1
101 if {![info exists remoteServerIP] && ($tcl_platform(platform) != "macintosh")} {
102 set remoteServerIP 127.0.0.1
104 if {($doTestsWithRemoteServer == 1) && (![info exists remoteServerPort])} {
105 set remoteServerPort 2048
108 # Attempt to connect to a remote server if one is already running. If it
109 # is not running or for some other reason the connect fails, attempt to
110 # start the remote server on the local host listening on port 2048. This
111 # is only done on platforms that support exec (i.e. not on the Mac). On
112 # platforms that do not support exec, the remote server must be started
113 # by the user before running the tests.
115 set remoteProcChan ""
117 if {$doTestsWithRemoteServer} {
118 catch {close $commandSocket}
119 if {[catch {set commandSocket [socket $remoteServerIP \
120 $remoteServerPort]}] != 0} {
121 if {[info commands exec] == ""} {
122 set noRemoteTestReason "can't exec"
123 set doTestsWithRemoteServer 0
125 set remoteServerIP 127.0.0.1
126 set remoteFile [file join [pwd] remote.tcl]
127 if {[catch {set remoteProcChan \
128 [open "|[list $::tcltest::tcltest $remoteFile \
130 -port $remoteServerPort \
131 -address $remoteServerIP]" \
135 if {[catch {set commandSocket [socket $remoteServerIP \
136 $remoteServerPort]} msg] == 0} {
137 fconfigure $commandSocket -translation crlf -buffering line
139 set noRemoteTestReason $msg
140 set doTestsWithRemoteServer 0
143 set noRemoteTestReason "$msg $::tcltest::tcltest"
144 set doTestsWithRemoteServer 0
148 fconfigure $commandSocket -translation crlf -buffering line
152 # Some tests are run only if we are doing testing against a remote server.
153 set ::tcltest::testConstraints(doTestsWithRemoteServer) $doTestsWithRemoteServer
154 if {$doTestsWithRemoteServer == 0} {
155 if {[string first s $::tcltest::verbose] != -1} {
156 puts "Skipping tests with remote server. See tests/socket.test for"
157 puts "information on how to run remote server."
158 puts "Reason for not doing remote tests: $noRemoteTestReason"
163 # If we do the tests, define a command to send a command to the
167 if {$doTestsWithRemoteServer == 1} {
168 proc sendCommand {c} {
171 if {[eof $commandSocket]} {
172 error "remote server disappeared"
175 if {[catch {puts $commandSocket $c} msg]} {
176 error "remote server disappaered: $msg"
178 if {[catch {puts $commandSocket "--Marker--Marker--Marker--"} msg]} {
179 error "remote server disappeared: $msg"
184 set line [gets $commandSocket]
185 if {[eof $commandSocket]} {
186 error "remote server disappaered"
188 if {[string compare $line "--Marker--Marker--Marker--"] == 0} {
189 if {[string compare [lindex $resp 0] error] == 0} {
190 error [lindex $resp 1]
192 return [lindex $resp 1]
195 append resp $line "\n"
201 test socket-1.1 {arg parsing for socket command} {socket} {
202 list [catch {socket -server} msg] $msg
203 } {1 {no argument given for -server option}}
204 test socket-1.2 {arg parsing for socket command} {socket} {
205 list [catch {socket -server foo} msg] $msg
206 } {1 {wrong # args: should be either:
207 socket ?-myaddr addr? ?-myport myport? ?-async? host port
208 socket -server command ?-myaddr addr? port}}
209 test socket-1.3 {arg parsing for socket command} {socket} {
210 list [catch {socket -myaddr} msg] $msg
211 } {1 {no argument given for -myaddr option}}
212 test socket-1.4 {arg parsing for socket command} {socket} {
213 list [catch {socket -myaddr 127.0.0.1} msg] $msg
214 } {1 {wrong # args: should be either:
215 socket ?-myaddr addr? ?-myport myport? ?-async? host port
216 socket -server command ?-myaddr addr? port}}
217 test socket-1.5 {arg parsing for socket command} {socket} {
218 list [catch {socket -myport} msg] $msg
219 } {1 {no argument given for -myport option}}
220 test socket-1.6 {arg parsing for socket command} {socket} {
221 list [catch {socket -myport xxxx} msg] $msg
222 } {1 {expected integer but got "xxxx"}}
223 test socket-1.7 {arg parsing for socket command} {socket} {
224 list [catch {socket -myport 2522} msg] $msg
225 } {1 {wrong # args: should be either:
226 socket ?-myaddr addr? ?-myport myport? ?-async? host port
227 socket -server command ?-myaddr addr? port}}
228 test socket-1.8 {arg parsing for socket command} {socket} {
229 list [catch {socket -froboz} msg] $msg
230 } {1 {bad option "-froboz": must be -async, -myaddr, -myport, or -server}}
231 test socket-1.9 {arg parsing for socket command} {socket} {
232 list [catch {socket -server foo -myport 2521 3333} msg] $msg
233 } {1 {Option -myport is not valid for servers}}
234 test socket-1.10 {arg parsing for socket command} {socket} {
235 list [catch {socket host 2528 -junk} msg] $msg
236 } {1 {wrong # args: should be either:
237 socket ?-myaddr addr? ?-myport myport? ?-async? host port
238 socket -server command ?-myaddr addr? port}}
239 test socket-1.11 {arg parsing for socket command} {socket} {
240 list [catch {socket -server callback 2520 --} msg] $msg
241 } {1 {wrong # args: should be either:
242 socket ?-myaddr addr? ?-myport myport? ?-async? host port
243 socket -server command ?-myaddr addr? port}}
244 test socket-1.12 {arg parsing for socket command} {socket} {
245 list [catch {socket foo badport} msg] $msg
246 } {1 {expected integer but got "badport"}}
248 test socket-2.1 {tcp connection} {socket stdio} {
250 set f [open script w]
252 set timer [after 2000 "set x timed_out"]
253 set f [socket -server accept 2828]
254 proc accept {file addr port} {
266 set f [open "|[list $::tcltest::tcltest script]" r]
268 if {[catch {socket 127.0.0.1 2828} msg]} {
279 if [info exists port] {
282 set port [expr 2048 + [pid]%1024]
284 test socket-2.2 {tcp connection with client port specified} {socket stdio} {
286 set f [open script w]
288 set timer [after 2000 "set x done"]
289 set f [socket -server accept 2829]
290 proc accept {file addr port} {
292 puts "[gets $file] $port"
302 set f [open "|[list $::tcltest::tcltest script]" r]
305 if {[catch {socket -myport $port 127.0.0.1 2829} sock]} {
307 close [socket 127.0.0.1 2829]
317 } [list ready "hello $port"]
318 test socket-2.3 {tcp connection with client interface specified} {socket stdio} {
320 set f [open script w]
322 set timer [after 2000 "set x done"]
323 set f [socket -server accept 2830]
324 proc accept {file addr port} {
326 puts "[gets $file] $addr"
336 set f [open "|[list $::tcltest::tcltest script]" r]
338 if {[catch {socket -myaddr 127.0.0.1 127.0.0.1 2830} sock]} {
348 } {ready {hello 127.0.0.1}}
349 test socket-2.4 {tcp connection with server interface specified} {socket stdio} {
351 set f [open script w]
353 set timer [after 2000 "set x done"]
354 set f [socket -server accept -myaddr [info hostname] 2831]
355 proc accept {file addr port} {
367 set f [open "|[list $::tcltest::tcltest script]" r]
369 if {[catch {socket [info hostname] 2831} sock]} {
380 test socket-2.5 {tcp connection with redundant server port} {socket stdio} {
382 set f [open script w]
384 set timer [after 2000 "set x done"]
385 set f [socket -server accept 2832]
386 proc accept {file addr port} {
398 set f [open "|[list $::tcltest::tcltest script]" r]
400 if {[catch {socket 127.0.0.1 2832} sock]} {
411 test socket-2.6 {tcp connection} {socket} {
413 if {![catch {set sock [socket 127.0.0.1 2833]}]} {
414 if {![catch {gets $sock}]} {
421 test socket-2.7 {echo server, one line} {socket stdio} {
423 set f [open script w]
425 set timer [after 2000 "set x done"]
426 set f [socket -server accept 2834]
427 proc accept {s a p} {
428 fileevent $s readable [list echo $s]
429 fconfigure $s -translation lf -buffering line
448 set f [open "|[list $::tcltest::tcltest script]" r]
450 set s [socket 127.0.0.1 2834]
451 fconfigure $s -buffering line -translation lf
452 puts $s "hello abcdefghijklmnop"
459 } {{hello abcdefghijklmnop} done}
460 test socket-2.8 {echo server, loop 50 times, single connection} {socket stdio} {
462 set f [socket -server accept 2835]
463 proc accept {s a p} {
464 fileevent $s readable [list echo $s]
465 fconfigure $s -buffering line
481 set timer [after 20000 "set x done"]
487 set f [open "|[list $::tcltest::tcltest script]" r]
489 set s [socket 127.0.0.1 2835]
490 fconfigure $s -buffering line
492 for {set x 0} {$x < 50} {incr x} {
493 puts $s "hello abcdefghijklmnop"
498 catch {set x [gets $f]}
502 test socket-2.9 {socket conflict} {socket stdio} {
503 set s [socket -server accept 2828]
505 set f [open script w]
506 puts -nonewline $f {socket -server accept 2828}
508 set f [open "|[list $::tcltest::tcltest script]" r]
511 set x [list [catch {close $f} msg] $msg]
514 } {1 {couldn't open socket: address already in use
516 "socket -server accept 2828"
517 (file "script" line 1)}}
518 test socket-2.10 {close on accept, accepted socket lives} {socket} {
520 set timer [after 20000 "set done timed_out"]
521 set ss [socket -server accept 2830]
522 proc accept {s a p} {
525 fileevent $s readable "readit $s"
526 fconfigure $s -trans lf
534 set cs [socket [info hostname] 2830]
541 test socket-2.11 {detecting new data} {socket} {
542 proc accept {s a p} {
547 set s [socket -server accept 2400]
549 set s2 [socket 127.0.0.1 2400]
554 fconfigure $sock -blocking 0
555 set result a:[gets $sock]
556 lappend result b:[gets $sock]
557 fconfigure $sock -blocking 1
560 fconfigure $sock -blocking 0
561 lappend result c:[gets $sock]
562 fconfigure $sock -blocking 1
570 test socket-3.1 {socket conflict} {socket stdio} {
572 set f [open script w]
574 set f [socket -server accept 2828]
580 set f [open "|[list $::tcltest::tcltest script]" r+]
582 set x [list [catch {socket -server accept 2828} msg] \
587 } {1 {couldn't open socket: address already in use}}
588 test socket-3.2 {server with several clients} {socket stdio} {
590 set f [open script w]
592 set t1 [after 30000 "set x timed_out"]
593 set t2 [after 31000 "set x timed_out"]
594 set t3 [after 32000 "set x timed_out"]
596 set s [socket -server accept 2828]
597 proc accept {s a p} {
598 fileevent $s readable [list echo $s]
599 fconfigure $s -buffering line
622 set f [open "|[list $::tcltest::tcltest script]" r+]
624 set s1 [socket 127.0.0.1 2828]
625 fconfigure $s1 -buffering line
626 set s2 [socket 127.0.0.1 2828]
627 fconfigure $s2 -buffering line
628 set s3 [socket 127.0.0.1 2828]
629 fconfigure $s3 -buffering line
630 for {set i 0} {$i < 100} {incr i} {
646 test socket-4.1 {server with several clients} {socket stdio} {
648 set f [open script w]
651 set s [socket 127.0.0.1 2828]
652 fconfigure $s -buffering line
653 for {set i 0} {$i < 100} {incr i} {
662 set p1 [open "|[list $::tcltest::tcltest script]" r+]
663 fconfigure $p1 -buffering line
664 set p2 [open "|[list $::tcltest::tcltest script]" r+]
665 fconfigure $p2 -buffering line
666 set p3 [open "|[list $::tcltest::tcltest script]" r+]
667 fconfigure $p3 -buffering line
668 proc accept {s a p} {
669 fconfigure $s -buffering line
670 fileevent $s readable [list echo $s]
682 set t1 [after 30000 "set x timed_out"]
683 set t2 [after 31000 "set x timed_out"]
684 set t3 [after 32000 "set x timed_out"]
685 set s [socket -server accept 2828]
697 lappend l [list p1 [gets $p1] $x]
698 lappend l [list p2 [gets $p2] $x]
699 lappend l [list p3 [gets $p3] $x]
707 } {{p1 bye done} {p2 bye done} {p3 bye done}}
708 test socket-4.2 {byte order problems, socket numbers, htons} {socket} {
710 if {[catch {socket -server dodo 0x3000} msg]} {
718 test socket-5.1 {byte order problems, socket numbers, htons} \
719 {socket unixOnly notRoot} {
720 set x {couldn't open socket: not owner}
721 if {![catch {socket -server dodo 0x1} msg]} {
722 set x {htons problem, should be disallowed, are you running as SU?}
726 } {couldn't open socket: not owner}
727 test socket-5.2 {byte order problems, socket numbers, htons} {socket} {
728 set x {couldn't open socket: port number too high}
729 if {![catch {socket -server dodo 0x10000} msg]} {
730 set x {port resolution problem, should be disallowed}
734 } {couldn't open socket: port number too high}
735 test socket-5.3 {byte order problems, socket numbers, htons} \
736 {socket unixOnly notRoot} {
737 set x {couldn't open socket: not owner}
738 if {![catch {socket -server dodo 21} msg]} {
739 set x {htons problem, should be disallowed, are you running as SU?}
743 } {couldn't open socket: not owner}
745 test socket-6.1 {accept callback error} {socket stdio} {
747 set f [open script w]
750 socket 127.0.0.1 2848
753 set f [open "|[list $::tcltest::tcltest script]" r+]
758 proc accept {s a p} {expr 10 / 0}
759 set s [socket -server accept 2848]
762 set timer [after 10000 "set x timed_out"]
770 test socket-7.1 {testing socket specific options} {socket stdio} {
772 set f [open script w]
774 socket -server accept 2820
780 set timer [after 10000 "set x timed_out"]
785 set f [open "|[list $::tcltest::tcltest script]" r]
787 set s [socket 127.0.0.1 2820]
788 set p [fconfigure $s -peername]
792 lappend l [string compare [lindex $p 0] 127.0.0.1]
793 lappend l [string compare [lindex $p 2] 2820]
794 lappend l [llength $p]
796 test socket-7.2 {testing socket specific options} {socket stdio} {
798 set f [open script w]
800 socket -server accept 2821
806 set timer [after 10000 "set x timed_out"]
811 set f [open "|[list $::tcltest::tcltest script]" r]
813 set s [socket 127.0.0.1 2821]
814 set p [fconfigure $s -sockname]
818 lappend l [llength $p]
819 lappend l [lindex $p 0]
820 lappend l [expr [lindex $p 2] == 2821]
822 test socket-7.3 {testing socket specific options} {socket} {
823 set s [socket -server accept 2822]
824 set l [fconfigure $s]
829 test socket-7.4 {testing socket specific options} {socket} {
830 set s [socket -server accept 2823]
831 proc accept {s a p} {
833 set x [fconfigure $s -sockname]
836 set s1 [socket [info hostname] 2823]
837 set timer [after 10000 "set x timed_out"]
843 lappend l [lindex $x 2] [llength $x]
845 test socket-7.5 {testing socket specific options} {socket unixOrPc} {
846 set s [socket -server accept 2829]
847 proc accept {s a p} {
849 set x [fconfigure $s -sockname]
852 set s1 [socket 127.0.0.1 2829]
853 set timer [after 10000 "set x timed_out"]
859 lappend l [lindex $x 0] [lindex $x 2] [llength $x]
862 test socket-8.1 {testing -async flag on sockets} {socket} {
863 # NOTE: This test may fail on some Solaris 2.4 systems. If it does,
864 # check that you have these patches installed (using showrev -p):
866 # 101907-05, 101925-02, 101945-14, 101959-03, 101969-05, 101973-03,
867 # 101977-03, 101981-02, 101985-01, 102001-03, 102003-01, 102007-01,
868 # 102011-02, 102024-01, 102039-01, 102044-01, 102048-01, 102062-03,
869 # 102066-04, 102070-01, 102105-01, 102153-03, 102216-01, 102232-01,
870 # 101878-03, 101879-01, 101880-03, 101933-01, 101950-01, 102030-01,
871 # 102057-08, 102140-01, 101920-02, 101921-09, 101922-07, 101923-03
873 # If after installing these patches you are still experiencing a
874 # problem, please email jyl@eng.sun.com. We have not observed this
875 # failure on Solaris 2.5, so another option (instead of installing
876 # these patches) is to upgrade to Solaris 2.5.
877 set s [socket -server accept 2830]
878 proc accept {s a p} {
884 set s1 [socket -async [info hostname] 2830]
892 test socket-9.1 {testing spurious events} {socket} {
896 proc readlittle {s} {
897 global spurious done len
899 if {[string length $l] == 0} {
907 incr len [string length $l]
910 proc accept {s a p} {
911 fconfigure $s -buffering none -blocking off
912 fileevent $s readable [list readlittle $s]
914 set s [socket -server accept 2831]
915 set c [socket [info hostname] 2831]
916 puts -nonewline $c 01234567890123456789012345678901234567890123456789
918 set timer [after 10000 "set done timed_out"]
924 test socket-9.2 {testing async write, fileevents, flush on close} {socket} {
926 for {set i 0} {$i < 5} {incr i} {set firstblock "a$firstblock$firstblock"}
928 for {set i 0} {$i < 16} {incr i} {
929 set secondblock "b$secondblock$secondblock"
931 set l [socket -server accept 2832]
932 proc accept {s a p} {
933 fconfigure $s -blocking 0 -translation lf -buffersize 16384 \
935 fileevent $s readable "readable $s"
939 fileevent $s readable {}
940 after 1000 respond $s
944 puts -nonewline $s $firstblock
945 after 1000 writedata $s
949 puts -nonewline $s $secondblock
952 set s [socket [info hostname] 2832]
953 fconfigure $s -blocking 0 -trans lf -buffering line
959 incr count [string length $l]
965 fileevent $s readable "readit $s"
966 set timer [after 10000 "set done timed_out"]
972 test socket-9.3 {testing EOF stickyness} {socket} {
973 proc count_to_eof {s} {
974 global count done timer
981 set count {eof is sticky}
989 set count {timer went off, eof is not sticky}
994 proc write_then_close {s} {
998 proc accept {s a p} {
999 fconfigure $s -buffering line -translation lf
1000 fileevent $s writable "write_then_close $s"
1002 set s [socket -server accept 2833]
1003 set c [socket [info hostname] 2833]
1004 fconfigure $c -blocking off -buffering line -translation lf
1005 fileevent $c readable "count_to_eof $c"
1006 set timer [after 1000 timerproc]
1014 test socket-10.1 {testing socket accept callback error handling} {socket} {
1016 proc bgerror args {global goterror; set goterror 1}
1017 set s [socket -server accept 2898]
1018 proc accept {s a p} {close $s; error}
1019 set c [socket 127.0.0.1 2898]
1026 test socket-11.1 {tcp connection} {socket doTestsWithRemoteServer} {
1028 set socket9_1_test_server [socket -server accept 2834]
1029 proc accept {s a p} {
1034 set s [socket $remoteServerIP 2834]
1037 sendCommand {close $socket9_1_test_server}
1040 test socket-11.2 {client specifies its port} {socket doTestsWithRemoteServer} {
1041 if {[info exists port]} {
1044 set port [expr 2048 + [pid]%1024]
1047 set socket9_2_test_server [socket -server accept 2835]
1048 proc accept {s a p} {
1053 set s [socket -myport $port $remoteServerIP 2835]
1056 sendCommand {close $socket9_2_test_server}
1064 test socket-11.3 {trying to connect, no server} {socket doTestsWithRemoteServer} {
1066 if {![catch {set s [socket $remoteServerIp 2836]}]} {
1067 if {![catch {gets $s}]} {
1074 test socket-11.4 {remote echo, one line} {socket doTestsWithRemoteServer} {
1076 set socket10_6_test_server [socket -server accept 2836]
1077 proc accept {s a p} {
1078 fileevent $s readable [list echo $s]
1079 fconfigure $s -buffering line -translation crlf
1090 set f [socket $remoteServerIP 2836]
1091 fconfigure $f -translation crlf -buffering line
1095 sendCommand {close $socket10_6_test_server}
1098 test socket-11.5 {remote echo, 50 lines} {socket doTestsWithRemoteServer} {
1100 set socket10_7_test_server [socket -server accept 2836]
1101 proc accept {s a p} {
1102 fileevent $s readable [list echo $s]
1103 fconfigure $s -buffering line -translation crlf
1114 set f [socket $remoteServerIP 2836]
1115 fconfigure $f -translation crlf -buffering line
1116 for {set cnt 0} {$cnt < 50} {incr cnt} {
1117 puts $f "hello, $cnt"
1118 if {[string compare [gets $f] "hello, $cnt"] != 0} {
1123 sendCommand {close $socket10_7_test_server}
1126 # Macintosh sockets can have more than one server per port
1127 if {$tcl_platform(platform) == "macintosh"} {
1128 set conflictResult {0 2836}
1130 set conflictResult {1 {couldn't open socket: address already in use}}
1132 test socket-11.6 {socket conflict} {socket doTestsWithRemoteServer} {
1133 set s1 [socket -server accept 2836]
1134 if {[catch {set s2 [socket -server accept 2836]} msg]} {
1135 set result [list 1 $msg]
1137 set result [list 0 [lindex [fconfigure $s2 -sockname] 2]]
1143 test socket-11.7 {server with several clients} {socket doTestsWithRemoteServer} {
1145 set socket10_9_test_server [socket -server accept 2836]
1146 proc accept {s a p} {
1147 fconfigure $s -buffering line
1148 fileevent $s readable [list echo $s]
1159 set s1 [socket $remoteServerIP 2836]
1160 fconfigure $s1 -buffering line
1161 set s2 [socket $remoteServerIP 2836]
1162 fconfigure $s2 -buffering line
1163 set s3 [socket $remoteServerIP 2836]
1164 fconfigure $s3 -buffering line
1165 for {set i 0} {$i < 100} {incr i} {
1176 sendCommand {close $socket10_9_test_server}
1179 test socket-11.8 {client with several servers} {socket doTestsWithRemoteServer} {
1181 set s1 [socket -server "accept 4003" 4003]
1182 set s2 [socket -server "accept 4004" 4004]
1183 set s3 [socket -server "accept 4005" 4005]
1184 proc accept {mp s a p} {
1189 set s1 [socket $remoteServerIP 4003]
1190 set s2 [socket $remoteServerIP 4004]
1191 set s3 [socket $remoteServerIP 4005]
1193 lappend l [gets $s1] [gets $s1] [eof $s1] [gets $s2] [gets $s2] [eof $s2] \
1194 [gets $s3] [gets $s3] [eof $s3]
1204 } {4003 {} 1 4004 {} 1 4005 {} 1}
1205 test socket-11.9 {accept callback error} {socket doTestsWithRemoteServer} {
1206 set s [socket -server accept 2836]
1207 proc accept {s a p} {expr 10 / 0}
1212 if {[catch {sendCommand {
1213 set peername [fconfigure $callerSocket -peername]
1214 set s [socket [lindex $peername 0] 2836]
1220 set timer [after 10000 "set x timed_out"]
1226 } {{divide by zero}}
1227 test socket-11.10 {testing socket specific options} {socket doTestsWithRemoteServer} {
1229 set socket10_12_test_server [socket -server accept 2836]
1230 proc accept {s a p} {close $s}
1232 set s [socket $remoteServerIP 2836]
1233 set p [fconfigure $s -peername]
1234 set n [fconfigure $s -sockname]
1236 lappend l [lindex $p 2] [llength $p] [llength $p]
1238 sendCommand {close $socket10_12_test_server}
1241 test socket-11.11 {testing spurious events} {socket doTestsWithRemoteServer} {
1243 set socket10_13_test_server [socket -server accept 2836]
1244 proc accept {s a p} {
1245 fconfigure $s -translation "auto lf"
1246 after 100 writesome $s
1248 proc writesome {s} {
1249 for {set i 0} {$i < 100} {incr i} {
1250 puts $s "line $i from remote server"
1258 proc readlittle {s} {
1259 global spurious done len
1261 if {[string length $l] == 0} {
1269 incr len [string length $l]
1272 set c [socket $remoteServerIP 2836]
1273 fileevent $c readable "readlittle $c"
1274 set timer [after 10000 "set done timed_out"]
1277 sendCommand {close $socket10_13_test_server}
1281 test socket-11.12 {testing EOF stickyness} {socket doTestsWithRemoteServer} {
1285 global counter done after_id
1290 set done {EOF is sticky}
1291 after cancel $after_id
1298 set done {timed_out, EOF is not sticky}
1302 set socket10_14_test_server [socket -server accept 2836]
1303 proc accept {s a p} {
1307 set c [socket $remoteServerIP 2836]
1308 fileevent $c readable [list count_up $c]
1309 set after_id [after 1000 timed_out]
1311 sendCommand {close $socket10_14_test_server}
1315 test socket-11.13 {testing async write, async flush, async close} \
1316 {socket doTestsWithRemoteServer} {
1320 incr count [string length $l]
1328 for {set i 0} {$i < 5} {incr i} {
1329 set firstblock "a$firstblock$firstblock"
1332 for {set i 0} {$i < 16} {incr i} {
1333 set secondblock "b$secondblock$secondblock"
1335 set l [socket -server accept 2845]
1336 proc accept {s a p} {
1337 fconfigure $s -blocking 0 -translation lf -buffersize 16384 \
1339 fileevent $s readable "readable $s"
1343 fileevent $s readable {}
1344 after 1000 respond $s
1348 puts -nonewline $s $firstblock
1349 after 1000 writedata $s
1351 proc writedata {s} {
1353 puts -nonewline $s $secondblock
1357 set s [socket $remoteServerIP 2845]
1358 fconfigure $s -blocking 0 -trans lf -buffering line
1361 fileevent $s readable "readit $s"
1362 set timer [after 10000 "set done timed_out"]
1365 sendCommand {close $l}
1369 test socket-12.1 {testing inheritance of server sockets} {socket exec} {
1373 # Script1 is just a 10 second delay. If the server socket
1374 # is inherited, it will be held open for 10 seconds
1376 set f [open script1 w]
1383 # Script2 creates the server socket, launches script1,
1384 # waits a second, and exits. The server socket will now
1385 # be closed unless script1 inherited it.
1387 set f [open script2 w]
1388 puts $f [list set tclsh $::tcltest::tcltest]
1390 set f [socket -server accept 2828]
1391 proc accept { file addr port } {
1394 exec $tclsh script1 &
1401 # Launch script2 and wait 5 seconds
1403 exec $::tcltest::tcltest script2 &
1404 after 5000 { set ok_to_proceed 1 }
1407 # If we can still connect to the server, the socket got inherited.
1409 if {[catch {socket 127.0.0.1 2828} msg]} {
1410 set x {server socket was not inherited}
1413 set x {server socket was inherited}
1419 } {server socket was not inherited}
1420 test socket-12.2 {testing inheritance of client sockets} {socket exec} {
1424 # Script1 is just a 10 second delay. If the server socket
1425 # is inherited, it will be held open for 10 seconds
1427 set f [open script1 w]
1434 # Script2 opens the client socket and writes to it. It then
1435 # launches script1 and exits. If the child process inherited the
1436 # client socket, the socket will still be open.
1438 set f [open script2 w]
1439 puts $f [list set tclsh $::tcltest::tcltest]
1441 set f [socket 127.0.0.1 2829]
1442 exec $tclsh script1 &
1450 # Create the server socket
1452 set server [socket -server accept 2829]
1453 proc accept { file host port } {
1454 # When the client connects, establish the read handler
1457 fileevent $file readable [list getdata $file]
1458 fconfigure $file -buffering line -blocking 0
1461 proc getdata { file } {
1462 # Read handler on the accepted socket.
1465 set status [catch {read $file} data]
1467 set x {read failed, error was $data}
1468 catch { close $file }
1469 } elseif {[string compare {} $data]} {
1470 } elseif {[fblocked $file]} {
1471 } elseif {[eof $file]} {
1473 set x {client socket was inherited}
1475 set x {client socket was not inherited}
1477 catch { close $file }
1479 set x {impossible case}
1480 catch { close $file }
1485 # If the socket doesn't hit end-of-file in 5 seconds, the
1486 # script1 process must have inherited the client.
1489 after 5000 [list set failed 1]
1491 # Launch the script2 process
1493 exec $::tcltest::tcltest script2 &
1502 } {client socket was not inherited}
1503 test socket-12.3 {testing inheritance of accepted sockets} {socket exec} {
1507 set f [open script1 w]
1514 set f [open script2 w]
1515 puts $f [list set tclsh $::tcltest::tcltest]
1517 set server [socket -server accept 2931]
1518 proc accept { file host port } {
1520 puts $file {test data on socket}
1521 exec $tclsh script1 &
1528 # Launch the script2 process and connect to it. See how long
1529 # the socket stays open
1531 exec $::tcltest::tcltest script2 &
1533 after 1000 set ok_to_proceed 1
1536 set f [socket 127.0.0.1 2931]
1537 fconfigure $f -buffering full -blocking 0
1538 fileevent $f readable [list getdata $f]
1540 # If the socket is still open after 5 seconds, the script1 process
1541 # must have inherited the accepted socket.
1544 after 5000 set failed 1
1546 proc getdata { file } {
1547 # Read handler on the client socket.
1550 set status [catch {read $file} data]
1552 set x {read failed, error was $data}
1553 catch { close $file }
1554 } elseif {[string compare {} $data]} {
1555 } elseif {[fblocked $file]} {
1556 } elseif {[eof $file]} {
1558 set x {accepted socket was inherited}
1560 set x {accepted socket was not inherited}
1562 catch { close $file }
1564 set x {impossible case}
1565 catch { close $file }
1575 } {accepted socket was not inherited}
1577 test socket-13.1 {Testing use of shared socket between two threads} \
1578 {socket testthread} {
1584 set f [socket -server accept 2828]
1585 proc accept {s a p} {
1586 fileevent $s readable [list echo $s]
1587 fconfigure $s -buffering line
1605 # thread cleans itself up.
1610 set serverthread [testthread create { source script } ]
1614 set s [socket 127.0.0.1 2828]
1615 fconfigure $s -buffering line
1625 lappend result [threadReap]
1632 if {[string match sock* $commandSocket] == 1} {
1633 puts $commandSocket exit
1634 flush $commandSocket
1636 catch {close $commandSocket}
1637 catch {close $remoteProcChan}
1638 ::tcltest::cleanupTests