PageRenderTime 65ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/jni/tcl8.6a3/tests/socket.test

https://github.com/LeifAndersen/TuxRider
Unknown | 1666 lines | 1633 code | 33 blank | 0 comment | 0 complexity | 2dd57c8fe54b7af955e4c816cc4480be MD5 | raw file
Possible License(s): AGPL-3.0, GPL-2.0
  1. # Commands tested in this file: socket.
  2. #
  3. # This file contains a collection of tests for one or more of the Tcl built-in
  4. # commands. Sourcing this file into Tcl runs the tests and generates output
  5. # for errors. No output means no errors were found.
  6. #
  7. # Copyright (c) 1994-1996 Sun Microsystems, Inc.
  8. # Copyright (c) 1998-2000 Ajuba Solutions.
  9. #
  10. # See the file "license.terms" for information on usage and redistribution of
  11. # this file, and for a DISCLAIMER OF ALL WARRANTIES.
  12. #
  13. # RCS: @(#) $Id: socket.test,v 1.42 2008/09/02 15:49:25 dkf Exp $
  14. # Running socket tests with a remote server:
  15. # ------------------------------------------
  16. #
  17. # Some tests in socket.test depend on the existence of a remote server to
  18. # which they connect. The remote server must be an instance of tcltest and it
  19. # must run the script found in the file "remote.tcl" in this directory. You
  20. # can start the remote server on any machine reachable from the machine on
  21. # which you want to run the socket tests, by issuing:
  22. #
  23. # tcltest remote.tcl -port 2048 # Or choose another port number.
  24. #
  25. # If the machine you are running the remote server on has several IP
  26. # interfaces, you can choose which interface the server listens on for
  27. # connections by specifying the -address command line flag, so:
  28. #
  29. # tcltest remote.tcl -address your.machine.com
  30. #
  31. # These options can also be set by environment variables. On Unix, you can
  32. # type these commands to the shell from which the remote server is started:
  33. #
  34. # shell% setenv serverPort 2048
  35. # shell% setenv serverAddress your.machine.com
  36. #
  37. # and subsequently you can start the remote server with:
  38. #
  39. # tcltest remote.tcl
  40. #
  41. # to have it listen on port 2048 on the interface your.machine.com.
  42. #
  43. # When the server starts, it prints out a detailed message containing its
  44. # configuration information, and it will block until killed with a Ctrl-C.
  45. # Once the remote server exists, you can run the tests in socket.test with the
  46. # server by setting two Tcl variables:
  47. #
  48. # % set remoteServerIP <name or address of machine on which server runs>
  49. # % set remoteServerPort 2048
  50. #
  51. # These variables are also settable from the environment. On Unix, you can:
  52. #
  53. # shell% setenv remoteServerIP machine.where.server.runs
  54. # shell% senetv remoteServerPort 2048
  55. #
  56. # The preamble of the socket.test file checks to see if the variables are set
  57. # either in Tcl or in the environment; if they are, it attempts to connect to
  58. # the server. If the connection is successful, the tests using the remote
  59. # server will be performed; otherwise, it will attempt to start the remote
  60. # server (via exec) on platforms that support this, on the local host,
  61. # listening at port 2048. If all fails, a message is printed and the tests
  62. # using the remote server are not performed.
  63. package require tcltest 2
  64. namespace import -force ::tcltest::*
  65. # Some tests require the testthread and exec commands
  66. testConstraint testthread [llength [info commands testthread]]
  67. testConstraint exec [llength [info commands exec]]
  68. # If remoteServerIP or remoteServerPort are not set, check in the environment
  69. # variables for externally set values.
  70. #
  71. if {![info exists remoteServerIP]} {
  72. if {[info exists env(remoteServerIP)]} {
  73. set remoteServerIP $env(remoteServerIP)
  74. }
  75. }
  76. if {![info exists remoteServerPort]} {
  77. if {[info exists env(remoteServerIP)]} {
  78. set remoteServerPort $env(remoteServerPort)
  79. } else {
  80. if {[info exists remoteServerIP]} {
  81. set remoteServerPort 2048
  82. }
  83. }
  84. }
  85. #
  86. # Check if we're supposed to do tests against the remote server
  87. #
  88. set doTestsWithRemoteServer 1
  89. if {![info exists remoteServerIP]} {
  90. set remoteServerIP 127.0.0.1
  91. }
  92. if {($doTestsWithRemoteServer == 1) && (![info exists remoteServerPort])} {
  93. set remoteServerPort 2048
  94. }
  95. # Attempt to connect to a remote server if one is already running. If it is
  96. # not running or for some other reason the connect fails, attempt to start the
  97. # remote server on the local host listening on port 2048. This is only done on
  98. # platforms that support exec (i.e. not on the Mac). On platforms that do not
  99. # support exec, the remote server must be started by the user before running
  100. # the tests.
  101. set remoteProcChan ""
  102. set commandSocket ""
  103. if {$doTestsWithRemoteServer} {
  104. catch {close $commandSocket}
  105. if {![catch {
  106. set commandSocket [socket $remoteServerIP $remoteServerPort]
  107. }]} then {
  108. fconfigure $commandSocket -translation crlf -buffering line
  109. } elseif {![testConstraint exec]} {
  110. set noRemoteTestReason "can't exec"
  111. set doTestsWithRemoteServer 0
  112. } else {
  113. set remoteServerIP 127.0.0.1
  114. # Be *extra* careful in case this file is sourced from
  115. # a directory other than the current one...
  116. set remoteFile [file join [pwd] [file dirname [info script]] \
  117. remote.tcl]
  118. if {![catch {
  119. set remoteProcChan [open "|[list \
  120. [interpreter] $remoteFile -serverIsSilent \
  121. -port $remoteServerPort -address $remoteServerIP]" w+]
  122. } msg]} then {
  123. after 1000
  124. if {[catch {
  125. set commandSocket [socket $remoteServerIP $remoteServerPort]
  126. } msg] == 0} then {
  127. fconfigure $commandSocket -translation crlf -buffering line
  128. } else {
  129. set noRemoteTestReason $msg
  130. set doTestsWithRemoteServer 0
  131. }
  132. } else {
  133. set noRemoteTestReason "$msg [interpreter]"
  134. set doTestsWithRemoteServer 0
  135. }
  136. }
  137. }
  138. # Some tests are run only if we are doing testing against a remote server.
  139. testConstraint doTestsWithRemoteServer $doTestsWithRemoteServer
  140. if {!$doTestsWithRemoteServer} {
  141. if {[string first s $::tcltest::verbose] != -1} {
  142. puts "Skipping tests with remote server. See tests/socket.test for"
  143. puts "information on how to run remote server."
  144. puts "Reason for not doing remote tests: $noRemoteTestReason"
  145. }
  146. }
  147. #
  148. # If we do the tests, define a command to send a command to the remote server.
  149. #
  150. if {[testConstraint doTestsWithRemoteServer]} {
  151. proc sendCommand {c} {
  152. global commandSocket
  153. if {[eof $commandSocket]} {
  154. error "remote server disappeared"
  155. }
  156. if {[catch {puts $commandSocket $c} msg]} {
  157. error "remote server disappaered: $msg"
  158. }
  159. if {[catch {puts $commandSocket "--Marker--Marker--Marker--"} msg]} {
  160. error "remote server disappeared: $msg"
  161. }
  162. set resp ""
  163. while {1} {
  164. set line [gets $commandSocket]
  165. if {[eof $commandSocket]} {
  166. error "remote server disappaered"
  167. }
  168. if {[string compare $line "--Marker--Marker--Marker--"] == 0} {
  169. if {[string compare [lindex $resp 0] error] == 0} {
  170. error [lindex $resp 1]
  171. } else {
  172. return [lindex $resp 1]
  173. }
  174. } else {
  175. append resp $line "\n"
  176. }
  177. }
  178. }
  179. }
  180. # ----------------------------------------------------------------------
  181. test socket-1.1 {arg parsing for socket command} -constraints socket -body {
  182. socket -server
  183. } -returnCodes error -result {no argument given for -server option}
  184. test socket-1.2 {arg parsing for socket command} -constraints socket -body {
  185. socket -server foo
  186. } -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-myaddr addr? port"}
  187. test socket-1.3 {arg parsing for socket command} -constraints socket -body {
  188. socket -myaddr
  189. } -returnCodes error -result {no argument given for -myaddr option}
  190. test socket-1.4 {arg parsing for socket command} -constraints socket -body {
  191. socket -myaddr 127.0.0.1
  192. } -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-myaddr addr? port"}
  193. test socket-1.5 {arg parsing for socket command} -constraints socket -body {
  194. socket -myport
  195. } -returnCodes error -result {no argument given for -myport option}
  196. test socket-1.6 {arg parsing for socket command} -constraints socket -body {
  197. socket -myport xxxx
  198. } -returnCodes error -result {expected integer but got "xxxx"}
  199. test socket-1.7 {arg parsing for socket command} -constraints socket -body {
  200. socket -myport 2522
  201. } -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-myaddr addr? port"}
  202. test socket-1.8 {arg parsing for socket command} -constraints socket -body {
  203. socket -froboz
  204. } -returnCodes error -result {bad option "-froboz": must be -async, -myaddr, -myport, or -server}
  205. test socket-1.9 {arg parsing for socket command} -constraints socket -body {
  206. socket -server foo -myport 2521 3333
  207. } -returnCodes error -result {option -myport is not valid for servers}
  208. test socket-1.10 {arg parsing for socket command} -constraints socket -body {
  209. socket host 2528 -junk
  210. } -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-myaddr addr? port"}
  211. test socket-1.11 {arg parsing for socket command} -constraints socket -body {
  212. socket -server callback 2520 --
  213. } -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-myaddr addr? port"}
  214. test socket-1.12 {arg parsing for socket command} -constraints socket -body {
  215. socket foo badport
  216. } -returnCodes error -result {expected integer but got "badport"}
  217. test socket-1.13 {arg parsing for socket command} -constraints socket -body {
  218. socket -async -server
  219. } -returnCodes error -result {cannot set -async option for server sockets}
  220. test socket-1.14 {arg parsing for socket command} -constraints socket -body {
  221. socket -server foo -async
  222. } -returnCodes error -result {cannot set -async option for server sockets}
  223. set path(script) [makeFile {} script]
  224. test socket-2.1 {tcp connection} -constraints {socket stdio} -setup {
  225. file delete $path(script)
  226. set f [open $path(script) w]
  227. puts $f {
  228. set timer [after 10000 "set x timed_out"]
  229. set f [socket -server accept 0]
  230. proc accept {file addr port} {
  231. global x
  232. set x done
  233. close $file
  234. }
  235. puts ready
  236. puts [lindex [fconfigure $f -sockname] 2]
  237. vwait x
  238. after cancel $timer
  239. close $f
  240. puts $x
  241. }
  242. close $f
  243. set f [open "|[list [interpreter] $path(script)]" r]
  244. gets $f x
  245. gets $f listen
  246. } -body {
  247. # $x == "ready" at this point
  248. set sock [socket 127.0.0.1 $listen]
  249. lappend x [gets $f]
  250. close $sock
  251. lappend x [gets $f]
  252. } -cleanup {
  253. close $f
  254. } -result {ready done {}}
  255. if {[info exists port]} {
  256. incr port
  257. } else {
  258. set port [expr {2048 + [pid]%1024}]
  259. }
  260. test socket-2.2 {tcp connection with client port specified} -setup {
  261. file delete $path(script)
  262. set f [open $path(script) w]
  263. puts $f {
  264. set timer [after 10000 "set x timeout"]
  265. set f [socket -server accept 0]
  266. proc accept {file addr port} {
  267. global x
  268. puts "[gets $file] $port"
  269. close $file
  270. set x done
  271. }
  272. puts ready
  273. puts [lindex [fconfigure $f -sockname] 2]
  274. vwait x
  275. after cancel $timer
  276. close $f
  277. }
  278. close $f
  279. set f [open "|[list [interpreter] $path(script)]" r]
  280. gets $f x
  281. gets $f listen
  282. } -constraints {socket stdio} -body {
  283. # $x == "ready" at this point
  284. global port
  285. set sock [socket -myport $port 127.0.0.1 $listen]
  286. puts $sock hello
  287. flush $sock
  288. lappend x [gets $f]
  289. close $sock
  290. return $x
  291. } -cleanup {
  292. catch {close [socket 127.0.0.1 $listen]}
  293. close $f
  294. } -result [list ready "hello $port"]
  295. test socket-2.3 {tcp connection with client interface specified} -setup {
  296. file delete $path(script)
  297. set f [open $path(script) w]
  298. puts $f {
  299. set timer [after 2000 "set x done"]
  300. set f [socket -server accept 2830]
  301. proc accept {file addr port} {
  302. global x
  303. puts "[gets $file] $addr"
  304. close $file
  305. set x done
  306. }
  307. puts ready
  308. vwait x
  309. after cancel $timer
  310. close $f
  311. }
  312. close $f
  313. set f [open "|[list [interpreter] $path(script)]" r]
  314. gets $f x
  315. } -constraints {socket stdio} -body {
  316. # $x == "ready" at this point
  317. set sock [socket -myaddr 127.0.0.1 127.0.0.1 2830]
  318. puts $sock hello
  319. flush $sock
  320. lappend x [gets $f]
  321. close $sock
  322. return $x
  323. } -cleanup {
  324. close $f
  325. } -result {ready {hello 127.0.0.1}}
  326. test socket-2.4 {tcp connection with server interface specified} -setup {
  327. file delete $path(script)
  328. set f [open $path(script) w]
  329. puts $f {
  330. set timer [after 2000 "set x done"]
  331. set f [socket -server accept -myaddr 127.0.0.1 0]
  332. proc accept {file addr port} {
  333. global x
  334. puts "[gets $file]"
  335. close $file
  336. set x done
  337. }
  338. puts ready
  339. puts [lindex [fconfigure $f -sockname] 2]
  340. vwait x
  341. after cancel $timer
  342. close $f
  343. }
  344. close $f
  345. set f [open "|[list [interpreter] $path(script)]" r]
  346. gets $f x
  347. gets $f listen
  348. } -constraints {socket stdio} -body {
  349. # $x == "ready" at this point
  350. set sock [socket 127.0.0.1 $listen]
  351. puts $sock hello
  352. flush $sock
  353. lappend x [gets $f]
  354. close $sock
  355. return $x
  356. } -cleanup {
  357. close $f
  358. } -result {ready hello}
  359. test socket-2.5 {tcp connection with redundant server port} -setup {
  360. file delete $path(script)
  361. set f [open $path(script) w]
  362. puts $f {
  363. set timer [after 10000 "set x timeout"]
  364. set f [socket -server accept 0]
  365. proc accept {file addr port} {
  366. global x
  367. puts "[gets $file]"
  368. close $file
  369. set x done
  370. }
  371. puts ready
  372. puts [lindex [fconfigure $f -sockname] 2]
  373. vwait x
  374. after cancel $timer
  375. close $f
  376. }
  377. close $f
  378. set f [open "|[list [interpreter] $path(script)]" r]
  379. gets $f x
  380. gets $f listen
  381. } -constraints {socket stdio} -body {
  382. # $x == "ready" at this point
  383. set sock [socket 127.0.0.1 $listen]
  384. puts $sock hello
  385. flush $sock
  386. lappend x [gets $f]
  387. close $sock
  388. return $x
  389. } -cleanup {
  390. close $f
  391. } -result {ready hello}
  392. test socket-2.6 {tcp connection} -constraints socket -body {
  393. set status ok
  394. if {![catch {set sock [socket 127.0.0.1 2833]}]} {
  395. if {![catch {gets $sock}]} {
  396. set status broken
  397. }
  398. close $sock
  399. }
  400. set status
  401. } -result ok
  402. test socket-2.7 {echo server, one line} -constraints {socket stdio} -setup {
  403. file delete $path(script)
  404. set f [open $path(script) w]
  405. puts $f {
  406. set timer [after 10000 "set x timeout"]
  407. set f [socket -server accept 0]
  408. proc accept {s a p} {
  409. fileevent $s readable [list echo $s]
  410. fconfigure $s -translation lf -buffering line
  411. }
  412. proc echo {s} {
  413. set l [gets $s]
  414. if {[eof $s]} {
  415. global x
  416. close $s
  417. set x done
  418. } else {
  419. puts $s $l
  420. }
  421. }
  422. puts ready
  423. puts [lindex [fconfigure $f -sockname] 2]
  424. vwait x
  425. after cancel $timer
  426. close $f
  427. puts $x
  428. }
  429. close $f
  430. set f [open "|[list [interpreter] $path(script)]" r]
  431. gets $f
  432. gets $f listen
  433. } -body {
  434. set s [socket 127.0.0.1 $listen]
  435. fconfigure $s -buffering line -translation lf
  436. puts $s "hello abcdefghijklmnop"
  437. after 1000
  438. set x [gets $s]
  439. close $s
  440. list $x [gets $f]
  441. } -cleanup {
  442. close $f
  443. } -result {{hello abcdefghijklmnop} done}
  444. removeFile script
  445. test socket-2.8 {echo server, loop 50 times, single connection} -setup {
  446. set path(script) [makeFile {
  447. set f [socket -server accept 0]
  448. proc accept {s a p} {
  449. fileevent $s readable [list echo $s]
  450. fconfigure $s -buffering line
  451. }
  452. proc echo {s} {
  453. global i
  454. set l [gets $s]
  455. if {[eof $s]} {
  456. global x
  457. close $s
  458. set x done
  459. } else {
  460. incr i
  461. puts $s $l
  462. }
  463. }
  464. set i 0
  465. puts ready
  466. puts [lindex [fconfigure $f -sockname] 2]
  467. set timer [after 20000 "set x done"]
  468. vwait x
  469. after cancel $timer
  470. close $f
  471. puts "done $i"
  472. } script]
  473. set f [open "|[list [interpreter] $path(script)]" r]
  474. gets $f
  475. gets $f listen
  476. } -constraints {socket stdio} -body {
  477. set s [socket 127.0.0.1 $listen]
  478. fconfigure $s -buffering line
  479. catch {
  480. for {set x 0} {$x < 50} {incr x} {
  481. puts $s "hello abcdefghijklmnop"
  482. gets $s
  483. }
  484. }
  485. close $s
  486. catch {set x [gets $f]}
  487. return $x
  488. } -cleanup {
  489. close $f
  490. removeFile script
  491. } -result {done 50}
  492. set path(script) [makeFile {} script]
  493. test socket-2.9 {socket conflict} -constraints {socket stdio} -body {
  494. set s [socket -server accept 0]
  495. file delete $path(script)
  496. set f [open $path(script) w]
  497. puts -nonewline $f "socket -server accept [lindex [fconfigure $s -sockname] 2]"
  498. close $f
  499. set f [open "|[list [interpreter] $path(script)]" r]
  500. gets $f
  501. after 100
  502. close $f
  503. } -returnCodes error -cleanup {
  504. close $s
  505. } -match glob -result {couldn't open socket: address already in use*}
  506. test socket-2.10 {close on accept, accepted socket lives} -setup {
  507. set done 0
  508. set timer [after 20000 "set done timed_out"]
  509. } -constraints socket -body {
  510. set ss [socket -server accept 0]
  511. proc accept {s a p} {
  512. global ss
  513. close $ss
  514. fileevent $s readable "readit $s"
  515. fconfigure $s -trans lf
  516. }
  517. proc readit {s} {
  518. global done
  519. gets $s
  520. close $s
  521. set done 1
  522. }
  523. set cs [socket [info hostname] [lindex [fconfigure $ss -sockname] 2]]
  524. puts $cs hello
  525. close $cs
  526. vwait done
  527. return $done
  528. } -cleanup {
  529. after cancel $timer
  530. } -result 1
  531. test socket-2.11 {detecting new data} -constraints socket -setup {
  532. proc accept {s a p} {
  533. global sock
  534. set sock $s
  535. }
  536. set s [socket -server accept 0]
  537. set sock ""
  538. } -body {
  539. set s2 [socket 127.0.0.1 [lindex [fconfigure $s -sockname] 2]]
  540. vwait sock
  541. puts $s2 one
  542. flush $s2
  543. after 500
  544. fconfigure $sock -blocking 0
  545. set result a:[gets $sock]
  546. lappend result b:[gets $sock]
  547. fconfigure $sock -blocking 1
  548. puts $s2 two
  549. flush $s2
  550. after 500
  551. fconfigure $sock -blocking 0
  552. lappend result c:[gets $sock]
  553. } -cleanup {
  554. fconfigure $sock -blocking 1
  555. close $s2
  556. close $s
  557. close $sock
  558. } -result {a:one b: c:two}
  559. test socket-3.1 {socket conflict} -constraints {socket stdio} -setup {
  560. file delete $path(script)
  561. set f [open $path(script) w]
  562. puts $f {
  563. set f [socket -server accept -myaddr 127.0.0.1 0]
  564. puts ready
  565. puts [lindex [fconfigure $f -sockname] 2]
  566. gets stdin
  567. close $f
  568. }
  569. close $f
  570. set f [open "|[list [interpreter] $path(script)]" r+]
  571. gets $f
  572. gets $f listen
  573. } -body {
  574. socket -server accept -myaddr 127.0.0.1 $listen
  575. } -cleanup {
  576. puts $f bye
  577. close $f
  578. } -returnCodes error -result {couldn't open socket: address already in use}
  579. test socket-3.2 {server with several clients} -setup {
  580. file delete $path(script)
  581. set f [open $path(script) w]
  582. puts $f {
  583. set t1 [after 30000 "set x timed_out"]
  584. set t2 [after 31000 "set x timed_out"]
  585. set t3 [after 32000 "set x timed_out"]
  586. set counter 0
  587. set s [socket -server accept -myaddr 127.0.0.1 0]
  588. proc accept {s a p} {
  589. fileevent $s readable [list echo $s]
  590. fconfigure $s -buffering line
  591. }
  592. proc echo {s} {
  593. global x
  594. set l [gets $s]
  595. if {[eof $s]} {
  596. close $s
  597. set x done
  598. } else {
  599. puts $s $l
  600. }
  601. }
  602. puts ready
  603. puts [lindex [fconfigure $s -sockname] 2]
  604. vwait x
  605. after cancel $t1
  606. vwait x
  607. after cancel $t2
  608. vwait x
  609. after cancel $t3
  610. close $s
  611. puts $x
  612. }
  613. close $f
  614. set f [open "|[list [interpreter] $path(script)]" r+]
  615. set x [gets $f]
  616. gets $f listen
  617. } -constraints {socket stdio} -body {
  618. # $x == "ready" here
  619. set s1 [socket 127.0.0.1 $listen]
  620. fconfigure $s1 -buffering line
  621. set s2 [socket 127.0.0.1 $listen]
  622. fconfigure $s2 -buffering line
  623. set s3 [socket 127.0.0.1 $listen]
  624. fconfigure $s3 -buffering line
  625. for {set i 0} {$i < 100} {incr i} {
  626. puts $s1 hello,s1
  627. gets $s1
  628. puts $s2 hello,s2
  629. gets $s2
  630. puts $s3 hello,s3
  631. gets $s3
  632. }
  633. close $s1
  634. close $s2
  635. close $s3
  636. lappend x [gets $f]
  637. } -cleanup {
  638. close $f
  639. } -result {ready done}
  640. test socket-4.1 {server with several clients} -setup {
  641. file delete $path(script)
  642. set f [open $path(script) w]
  643. puts $f {
  644. set port [gets stdin]
  645. set s [socket 127.0.0.1 $port]
  646. fconfigure $s -buffering line
  647. for {set i 0} {$i < 100} {incr i} {
  648. puts $s hello
  649. gets $s
  650. }
  651. close $s
  652. puts bye
  653. gets stdin
  654. }
  655. close $f
  656. set p1 [open "|[list [interpreter] $path(script)]" r+]
  657. fconfigure $p1 -buffering line
  658. set p2 [open "|[list [interpreter] $path(script)]" r+]
  659. fconfigure $p2 -buffering line
  660. set p3 [open "|[list [interpreter] $path(script)]" r+]
  661. fconfigure $p3 -buffering line
  662. } -constraints {socket stdio} -body {
  663. proc accept {s a p} {
  664. fconfigure $s -buffering line
  665. fileevent $s readable [list echo $s]
  666. }
  667. proc echo {s} {
  668. global x
  669. set l [gets $s]
  670. if {[eof $s]} {
  671. close $s
  672. set x done
  673. } else {
  674. puts $s $l
  675. }
  676. }
  677. set t1 [after 30000 "set x timed_out"]
  678. set t2 [after 31000 "set x timed_out"]
  679. set t3 [after 32000 "set x timed_out"]
  680. set s [socket -server accept -myaddr 127.0.0.1 0]
  681. set listen [lindex [fconfigure $s -sockname] 2]
  682. puts $p1 $listen
  683. puts $p2 $listen
  684. puts $p3 $listen
  685. vwait x
  686. vwait x
  687. vwait x
  688. after cancel $t1
  689. after cancel $t2
  690. after cancel $t3
  691. close $s
  692. set l ""
  693. lappend l [list p1 [gets $p1] $x]
  694. lappend l [list p2 [gets $p2] $x]
  695. lappend l [list p3 [gets $p3] $x]
  696. } -cleanup {
  697. puts $p1 bye
  698. puts $p2 bye
  699. puts $p3 bye
  700. close $p1
  701. close $p2
  702. close $p3
  703. } -result {{p1 bye done} {p2 bye done} {p3 bye done}}
  704. test socket-4.2 {byte order problems, socket numbers, htons} -body {
  705. close [socket -server dodo -myaddr 127.0.0.1 0x3000]
  706. return ok
  707. } -constraints socket -result ok
  708. test socket-5.1 {byte order problems, socket numbers, htons} -body {
  709. if {![catch {socket -server dodo 0x1} msg]} {
  710. close $msg
  711. return {htons problem, should be disallowed, are you running as SU?}
  712. }
  713. return {couldn't open socket: not owner}
  714. } -constraints {socket unix notRoot} -result {couldn't open socket: not owner}
  715. test socket-5.2 {byte order problems, socket numbers, htons} -body {
  716. if {![catch {socket -server dodo 0x10000} msg]} {
  717. close $msg
  718. return {port resolution problem, should be disallowed}
  719. }
  720. return {couldn't open socket: port number too high}
  721. } -constraints socket -result {couldn't open socket: port number too high}
  722. test socket-5.3 {byte order problems, socket numbers, htons} -body {
  723. if {![catch {socket -server dodo 21} msg]} {
  724. close $msg
  725. return {htons problem, should be disallowed, are you running as SU?}
  726. }
  727. return {couldn't open socket: not owner}
  728. } -constraints {socket unix notRoot} -result {couldn't open socket: not owner}
  729. test socket-6.1 {accept callback error} -constraints {socket stdio} -setup {
  730. proc myHandler {msg options} {
  731. variable x $msg
  732. }
  733. set handler [interp bgerror {}]
  734. interp bgerror {} [namespace which myHandler]
  735. file delete $path(script)
  736. } -body {
  737. set f [open $path(script) w]
  738. puts $f {
  739. gets stdin port
  740. socket 127.0.0.1 $port
  741. }
  742. close $f
  743. set f [open "|[list [interpreter] $path(script)]" r+]
  744. proc accept {s a p} {expr 10 / 0}
  745. set s [socket -server accept -myaddr 127.0.0.1 0]
  746. puts $f [lindex [fconfigure $s -sockname] 2]
  747. close $f
  748. set timer [after 10000 "set x timed_out"]
  749. vwait x
  750. after cancel $timer
  751. close $s
  752. return $x
  753. } -cleanup {
  754. interp bgerror {} $handler
  755. } -result {divide by zero}
  756. test socket-7.1 {testing socket specific options} -setup {
  757. file delete $path(script)
  758. set f [open $path(script) w]
  759. puts $f {
  760. set ss [socket -server accept 0]
  761. proc accept args {
  762. global x
  763. set x done
  764. }
  765. puts ready
  766. puts [lindex [fconfigure $ss -sockname] 2]
  767. set timer [after 10000 "set x timed_out"]
  768. vwait x
  769. after cancel $timer
  770. }
  771. close $f
  772. set f [open "|[list [interpreter] $path(script)]" r]
  773. gets $f
  774. gets $f listen
  775. set l ""
  776. } -constraints {socket stdio} -body {
  777. set s [socket 127.0.0.1 $listen]
  778. set p [fconfigure $s -peername]
  779. close $s
  780. lappend l [string compare [lindex $p 0] 127.0.0.1]
  781. lappend l [string compare [lindex $p 2] $listen]
  782. lappend l [llength $p]
  783. } -cleanup {
  784. close $f
  785. } -result {0 0 3}
  786. test socket-7.2 {testing socket specific options} -setup {
  787. file delete $path(script)
  788. set f [open $path(script) w]
  789. puts $f {
  790. set ss [socket -server accept 2821]
  791. proc accept args {
  792. global x
  793. set x done
  794. }
  795. puts ready
  796. puts [lindex [fconfigure $ss -sockname] 2]
  797. set timer [after 10000 "set x timed_out"]
  798. vwait x
  799. after cancel $timer
  800. }
  801. close $f
  802. set f [open "|[list [interpreter] $path(script)]" r]
  803. gets $f
  804. gets $f listen
  805. } -constraints {socket stdio} -body {
  806. set s [socket 127.0.0.1 $listen]
  807. set p [fconfigure $s -sockname]
  808. close $s
  809. list [llength $p] \
  810. [regexp {^(127\.0\.0\.1|0\.0\.0\.0)$} [lindex $p 0]] \
  811. [expr {[lindex $p 2] == $listen}]
  812. } -cleanup {
  813. close $f
  814. } -result {3 1 0}
  815. test socket-7.3 {testing socket specific options} -constraints socket -body {
  816. set s [socket -server accept -myaddr 127.0.0.1 0]
  817. set l [fconfigure $s]
  818. close $s
  819. update
  820. llength $l
  821. } -result 14
  822. test socket-7.4 {testing socket specific options} -constraints socket -setup {
  823. set timer [after 10000 "set x timed_out"]
  824. set l ""
  825. } -body {
  826. set s [socket -server accept -myaddr 127.0.0.1 0]
  827. proc accept {s a p} {
  828. global x
  829. set x [fconfigure $s -sockname]
  830. close $s
  831. }
  832. set listen [lindex [fconfigure $s -sockname] 2]
  833. set s1 [socket 127.0.0.1 $listen]
  834. vwait x
  835. lappend l [expr {[lindex $x 2] == $listen}] [llength $x]
  836. } -cleanup {
  837. after cancel $timer
  838. close $s
  839. close $s1
  840. } -result {1 3}
  841. test socket-7.5 {testing socket specific options} -setup {
  842. set timer [after 10000 "set x timed_out"]
  843. set l ""
  844. } -constraints {socket unixOrPc} -body {
  845. set s [socket -server accept 0]
  846. proc accept {s a p} {
  847. global x
  848. set x [fconfigure $s -sockname]
  849. close $s
  850. }
  851. set listen [lindex [fconfigure $s -sockname] 2]
  852. set s1 [socket 127.0.0.1 $listen]
  853. vwait x
  854. lappend l [lindex $x 0] [expr {[lindex $x 2] == $listen}] [llength $x]
  855. } -cleanup {
  856. after cancel $timer
  857. close $s
  858. close $s1
  859. } -result {127.0.0.1 1 3}
  860. test socket-8.1 {testing -async flag on sockets} -constraints socket -body {
  861. # NOTE: This test may fail on some Solaris 2.4 systems. If it does, check
  862. # that you have these patches installed (using showrev -p):
  863. #
  864. # 101907-05, 101925-02, 101945-14, 101959-03, 101969-05, 101973-03,
  865. # 101977-03, 101981-02, 101985-01, 102001-03, 102003-01, 102007-01,
  866. # 102011-02, 102024-01, 102039-01, 102044-01, 102048-01, 102062-03,
  867. # 102066-04, 102070-01, 102105-01, 102153-03, 102216-01, 102232-01,
  868. # 101878-03, 101879-01, 101880-03, 101933-01, 101950-01, 102030-01,
  869. # 102057-08, 102140-01, 101920-02, 101921-09, 101922-07, 101923-03
  870. #
  871. # If after installing these patches you are still experiencing a problem,
  872. # please email jyl@eng.sun.com. We have not observed this failure on
  873. # Solaris 2.5, so another option (instead of installing these patches) is
  874. # to upgrade to Solaris 2.5.
  875. set s [socket -server accept -myaddr 127.0.0.1 0]
  876. proc accept {s a p} {
  877. global x
  878. puts $s bye
  879. close $s
  880. set x done
  881. }
  882. set s1 [socket -async 127.0.0.1 [lindex [fconfigure $s -sockname] 2]]
  883. vwait x
  884. gets $s1
  885. } -cleanup {
  886. close $s
  887. close $s1
  888. } -result bye
  889. test socket-9.1 {testing spurious events} -constraints socket -setup {
  890. set len 0
  891. set spurious 0
  892. set done 0
  893. set timer [after 10000 "set done timed_out"]
  894. } -body {
  895. proc readlittle {s} {
  896. global spurious done len
  897. set l [read $s 1]
  898. if {[string length $l] == 0} {
  899. if {![eof $s]} {
  900. incr spurious
  901. } else {
  902. close $s
  903. set done 1
  904. }
  905. } else {
  906. incr len [string length $l]
  907. }
  908. }
  909. proc accept {s a p} {
  910. fconfigure $s -buffering none -blocking off
  911. fileevent $s readable [list readlittle $s]
  912. }
  913. set s [socket -server accept -myaddr 127.0.0.1 0]
  914. set c [socket 127.0.0.1 [lindex [fconfigure $s -sockname] 2]]
  915. puts -nonewline $c 01234567890123456789012345678901234567890123456789
  916. close $c
  917. vwait done
  918. close $s
  919. list $spurious $len
  920. } -cleanup {
  921. after cancel $timer
  922. } -result {0 50}
  923. test socket-9.2 {testing async write, fileevents, flush on close} -constraints socket -setup {
  924. set firstblock ""
  925. for {set i 0} {$i < 5} {incr i} {set firstblock "a$firstblock$firstblock"}
  926. set secondblock ""
  927. for {set i 0} {$i < 16} {incr i} {
  928. set secondblock "b$secondblock$secondblock"
  929. }
  930. set timer [after 10000 "set done timed_out"]
  931. set l [socket -server accept -myaddr 127.0.0.1 0]
  932. proc accept {s a p} {
  933. fconfigure $s -blocking 0 -translation lf -buffersize 16384 \
  934. -buffering line
  935. fileevent $s readable "readable $s"
  936. }
  937. proc readable {s} {
  938. set l [gets $s]
  939. fileevent $s readable {}
  940. after 1000 respond $s
  941. }
  942. proc respond {s} {
  943. global firstblock
  944. puts -nonewline $s $firstblock
  945. after 1000 writedata $s
  946. }
  947. proc writedata {s} {
  948. global secondblock
  949. puts -nonewline $s $secondblock
  950. close $s
  951. }
  952. } -body {
  953. set s [socket 127.0.0.1 [lindex [fconfigure $l -sockname] 2]]
  954. fconfigure $s -blocking 0 -trans lf -buffering line
  955. set count 0
  956. puts $s hello
  957. proc readit {s} {
  958. global count done
  959. set l [read $s]
  960. incr count [string length $l]
  961. if {[eof $s]} {
  962. close $s
  963. set done 1
  964. }
  965. }
  966. fileevent $s readable "readit $s"
  967. vwait done
  968. return $count
  969. } -cleanup {
  970. close $l
  971. after cancel $timer
  972. } -result 65566
  973. test socket-9.3 {testing EOF stickyness} -constraints socket -setup {
  974. set count 0
  975. set done false
  976. proc write_then_close {s} {
  977. puts $s bye
  978. close $s
  979. }
  980. proc accept {s a p} {
  981. fconfigure $s -buffering line -translation lf
  982. fileevent $s writable "write_then_close $s"
  983. }
  984. set s [socket -server accept -myaddr 127.0.0.1 0]
  985. } -body {
  986. proc count_to_eof {s} {
  987. global count done
  988. set l [gets $s]
  989. if {[eof $s]} {
  990. incr count
  991. if {$count > 9} {
  992. close $s
  993. set done true
  994. set count {eof is sticky}
  995. }
  996. }
  997. }
  998. proc timerproc {s} {
  999. global done count
  1000. set done true
  1001. set count {timer went off, eof is not sticky}
  1002. close $s
  1003. }
  1004. set c [socket 127.0.0.1 [lindex [fconfigure $s -sockname] 2]]
  1005. fconfigure $c -blocking off -buffering line -translation lf
  1006. fileevent $c readable "count_to_eof $c"
  1007. set timer [after 1000 timerproc $c]
  1008. vwait done
  1009. return $count
  1010. } -cleanup {
  1011. close $s
  1012. after cancel $timer
  1013. } -result {eof is sticky}
  1014. removeFile script
  1015. test socket-10.1 {testing socket accept callback error handling} -constraints {
  1016. socket
  1017. } -setup {
  1018. variable goterror 0
  1019. proc myHandler {msg options} {
  1020. variable goterror 1
  1021. }
  1022. set handler [interp bgerror {}]
  1023. interp bgerror {} [namespace which myHandler]
  1024. } -body {
  1025. set s [socket -server accept -myaddr 127.0.0.1 0]
  1026. proc accept {s a p} {close $s; error}
  1027. set c [socket 127.0.0.1 [lindex [fconfigure $s -sockname] 2]]
  1028. vwait goterror
  1029. close $s
  1030. close $c
  1031. return $goterror
  1032. } -cleanup {
  1033. interp bgerror {} $handler
  1034. } -result 1
  1035. test socket-11.1 {tcp connection} -setup {
  1036. sendCommand {
  1037. set socket9_1_test_server [socket -server accept 2834]
  1038. proc accept {s a p} {
  1039. puts $s done
  1040. close $s
  1041. }
  1042. }
  1043. } -constraints {socket doTestsWithRemoteServer} -body {
  1044. set s [socket $remoteServerIP 2834]
  1045. gets $s
  1046. } -cleanup {
  1047. close $s
  1048. sendCommand {close $socket9_1_test_server}
  1049. } -result done
  1050. test socket-11.2 {client specifies its port} -setup {
  1051. if {[info exists port]} {
  1052. incr port
  1053. } else {
  1054. set port [expr 2048 + [pid]%1024]
  1055. }
  1056. sendCommand {
  1057. set socket9_2_test_server [socket -server accept 2835]
  1058. proc accept {s a p} {
  1059. puts $s $p
  1060. close $s
  1061. }
  1062. }
  1063. } -constraints {socket doTestsWithRemoteServer} -body {
  1064. set s [socket -myport $port $remoteServerIP 2835]
  1065. set r [gets $s]
  1066. expr {$r==$port ? "ok" : "broken: $r != $port"}
  1067. } -cleanup {
  1068. close $s
  1069. sendCommand {close $socket9_2_test_server}
  1070. } -result ok
  1071. test socket-11.3 {trying to connect, no server} -body {
  1072. set status ok
  1073. if {![catch {set s [socket $remoteServerIp 2836]}]} {
  1074. if {![catch {gets $s}]} {
  1075. set status broken
  1076. }
  1077. close $s
  1078. }
  1079. return $status
  1080. } -constraints {socket doTestsWithRemoteServer} -result ok
  1081. test socket-11.4 {remote echo, one line} -setup {
  1082. sendCommand {
  1083. set socket10_6_test_server [socket -server accept 2836]
  1084. proc accept {s a p} {
  1085. fileevent $s readable [list echo $s]
  1086. fconfigure $s -buffering line -translation crlf
  1087. }
  1088. proc echo {s} {
  1089. set l [gets $s]
  1090. if {[eof $s]} {
  1091. close $s
  1092. } else {
  1093. puts $s $l
  1094. }
  1095. }
  1096. }
  1097. } -constraints {socket doTestsWithRemoteServer} -body {
  1098. set f [socket $remoteServerIP 2836]
  1099. fconfigure $f -translation crlf -buffering line
  1100. puts $f hello
  1101. gets $f
  1102. } -cleanup {
  1103. catch {close $f}
  1104. sendCommand {close $socket10_6_test_server}
  1105. } -result hello
  1106. test socket-11.5 {remote echo, 50 lines} -setup {
  1107. sendCommand {
  1108. set socket10_7_test_server [socket -server accept 2836]
  1109. proc accept {s a p} {
  1110. fileevent $s readable [list echo $s]
  1111. fconfigure $s -buffering line -translation crlf
  1112. }
  1113. proc echo {s} {
  1114. set l [gets $s]
  1115. if {[eof $s]} {
  1116. close $s
  1117. } else {
  1118. puts $s $l
  1119. }
  1120. }
  1121. }
  1122. } -constraints {socket doTestsWithRemoteServer} -body {
  1123. set f [socket $remoteServerIP 2836]
  1124. fconfigure $f -translation crlf -buffering line
  1125. for {set cnt 0} {$cnt < 50} {incr cnt} {
  1126. puts $f "hello, $cnt"
  1127. if {[gets $f] != "hello, $cnt"} {
  1128. break
  1129. }
  1130. }
  1131. return $cnt
  1132. } -cleanup {
  1133. close $f
  1134. sendCommand {close $socket10_7_test_server}
  1135. } -result 50
  1136. test socket-11.6 {socket conflict} -setup {
  1137. set s1 [socket -server accept -myaddr 127.0.0.1 2836]
  1138. } -constraints {socket doTestsWithRemoteServer} -body {
  1139. set s2 [socket -server accept -myaddr 127.0.0.1 2836]
  1140. list [lindex [fconfigure $s2 -sockname] 2] [close $s2]
  1141. } -cleanup {
  1142. close $s1
  1143. } -returnCodes error -result {couldn't open socket: address already in use}
  1144. test socket-11.7 {server with several clients} -setup {
  1145. sendCommand {
  1146. set socket10_9_test_server [socket -server accept 2836]
  1147. proc accept {s a p} {
  1148. fconfigure $s -buffering line
  1149. fileevent $s readable [list echo $s]
  1150. }
  1151. proc echo {s} {
  1152. set l [gets $s]
  1153. if {[eof $s]} {
  1154. close $s
  1155. } else {
  1156. puts $s $l
  1157. }
  1158. }
  1159. }
  1160. } -constraints {socket doTestsWithRemoteServer} -body {
  1161. set s1 [socket $remoteServerIP 2836]
  1162. fconfigure $s1 -buffering line
  1163. set s2 [socket $remoteServerIP 2836]
  1164. fconfigure $s2 -buffering line
  1165. set s3 [socket $remoteServerIP 2836]
  1166. fconfigure $s3 -buffering line
  1167. for {set i 0} {$i < 100} {incr i} {
  1168. puts $s1 hello,s1
  1169. gets $s1
  1170. puts $s2 hello,s2
  1171. gets $s2
  1172. puts $s3 hello,s3
  1173. gets $s3
  1174. }
  1175. return $i
  1176. } -cleanup {
  1177. close $s1
  1178. close $s2
  1179. close $s3
  1180. sendCommand {close $socket10_9_test_server}
  1181. } -result 100
  1182. test socket-11.8 {client with several servers} -setup {
  1183. sendCommand {
  1184. set s1 [socket -server "accept 4003" 4003]
  1185. set s2 [socket -server "accept 4004" 4004]
  1186. set s3 [socket -server "accept 4005" 4005]
  1187. proc accept {mp s a p} {
  1188. puts $s $mp
  1189. close $s
  1190. }
  1191. }
  1192. } -constraints {socket doTestsWithRemoteServer} -body {
  1193. set s1 [socket $remoteServerIP 4003]
  1194. set s2 [socket $remoteServerIP 4004]
  1195. set s3 [socket $remoteServerIP 4005]
  1196. list [gets $s1] [gets $s1] [eof $s1] [gets $s2] [gets $s2] [eof $s2] \
  1197. [gets $s3] [gets $s3] [eof $s3]
  1198. } -cleanup {
  1199. close $s1
  1200. close $s2
  1201. close $s3
  1202. sendCommand {
  1203. close $s1
  1204. close $s2
  1205. close $s3
  1206. }
  1207. } -result {4003 {} 1 4004 {} 1 4005 {} 1}
  1208. test socket-11.9 {accept callback error} -constraints {
  1209. socket doTestsWithRemoteServer
  1210. } -setup {
  1211. proc myHandler {msg options} {
  1212. variable x $msg
  1213. }
  1214. set handler [interp bgerror {}]
  1215. interp bgerror {} [namespace which myHandler]
  1216. set timer [after 10000 "set x timed_out"]
  1217. } -body {
  1218. set s [socket -server accept 2836]
  1219. proc accept {s a p} {expr 10 / 0}
  1220. if {[catch {
  1221. sendCommand {
  1222. set peername [fconfigure $callerSocket -peername]
  1223. set s [socket [lindex $peername 0] 2836]
  1224. close $s
  1225. }
  1226. } msg]} then {
  1227. close $s
  1228. error $msg
  1229. }
  1230. vwait x
  1231. return $x
  1232. } -cleanup {
  1233. close $s
  1234. after cancel $timer
  1235. interp bgerror {} $handler
  1236. } -result {divide by zero}
  1237. test socket-11.10 {testing socket specific options} -setup {
  1238. sendCommand {
  1239. set socket10_12_test_server [socket -server accept 2836]
  1240. proc accept {s a p} {close $s}
  1241. }
  1242. } -constraints {socket doTestsWithRemoteServer} -body {
  1243. set s [socket $remoteServerIP 2836]
  1244. set p [fconfigure $s -peername]
  1245. set n [fconfigure $s -sockname]
  1246. list [lindex $p 2] [llength $p] [llength $n]
  1247. } -cleanup {
  1248. close $s
  1249. sendCommand {close $socket10_12_test_server}
  1250. } -result {2836 3 3}
  1251. test socket-11.11 {testing spurious events} -setup {
  1252. sendCommand {
  1253. set socket10_13_test_server [socket -server accept 2836]
  1254. proc accept {s a p} {
  1255. fconfigure $s -translation "auto lf"
  1256. after 100 writesome $s
  1257. }
  1258. proc writesome {s} {
  1259. for {set i 0} {$i < 100} {incr i} {
  1260. puts $s "line $i from remote server"
  1261. }
  1262. close $s
  1263. }
  1264. }
  1265. set len 0
  1266. set spurious 0
  1267. set done 0
  1268. set timer [after 40000 "set done timed_out"]
  1269. } -constraints {socket doTestsWithRemoteServer} -body {
  1270. proc readlittle {s} {
  1271. global spurious done len
  1272. set l [read $s 1]
  1273. if {[string length $l] == 0} {
  1274. if {![eof $s]} {
  1275. incr spurious
  1276. } else {
  1277. close $s
  1278. set done 1
  1279. }
  1280. } else {
  1281. incr len [string length $l]
  1282. }
  1283. }
  1284. set c [socket $remoteServerIP 2836]
  1285. fileevent $c readable "readlittle $c"
  1286. vwait done
  1287. list $spurious $len $done
  1288. } -cleanup {
  1289. after cancel $timer
  1290. sendCommand {close $socket10_13_test_server}
  1291. } -result {0 2690 1}
  1292. test socket-11.12 {testing EOF stickyness} -constraints {socket doTestsWithRemoteServer} -setup {
  1293. set counter 0
  1294. set done 0
  1295. sendCommand {
  1296. set socket10_14_test_server [socket -server accept 2836]
  1297. proc accept {s a p} {
  1298. after 100 close $s
  1299. }
  1300. }
  1301. proc timed_out {} {
  1302. global c done
  1303. set done {timed_out, EOF is not sticky}
  1304. close $c
  1305. }
  1306. set after_id [after 1000 timed_out]
  1307. } -body {
  1308. proc count_up {s} {
  1309. global counter done
  1310. set l [gets $s]
  1311. if {[eof $s]} {
  1312. incr counter
  1313. if {$counter > 9} {
  1314. set done {EOF is sticky}
  1315. close $s
  1316. }
  1317. }
  1318. }
  1319. set c [socket $remoteServerIP 2836]
  1320. fileevent $c readable [list count_up $c]
  1321. vwait done
  1322. return $done
  1323. } -cleanup {
  1324. after cancel $after_id
  1325. sendCommand {close $socket10_14_test_server}
  1326. } -result {EOF is sticky}
  1327. test socket-11.13 {testing async write, async flush, async close} -setup {
  1328. sendCommand {
  1329. set firstblock ""
  1330. for {set i 0} {$i < 5} {incr i} {
  1331. set firstblock "a$firstblock$firstblock"
  1332. }
  1333. set secondblock ""
  1334. for {set i 0} {$i < 16} {incr i} {
  1335. set secondblock "b$secondblock$secondblock"
  1336. }
  1337. set l [socket -server accept 2845]
  1338. proc accept {s a p} {
  1339. fconfigure $s -blocking 0 -translation lf -buffersize 16384 \
  1340. -buffering line
  1341. fileevent $s readable "readable $s"
  1342. }
  1343. proc readable {s} {
  1344. set l [gets $s]
  1345. fileevent $s readable {}
  1346. after 1000 respond $s
  1347. }
  1348. proc respond {s} {
  1349. global firstblock
  1350. puts -nonewline $s $firstblock
  1351. after 1000 writedata $s
  1352. }
  1353. proc writedata {s} {
  1354. global secondblock
  1355. puts -nonewline $s $secondblock
  1356. close $s
  1357. }
  1358. }
  1359. set timer [after 10000 "set done timed_out"]
  1360. } -constraints {socket doTestsWithRemoteServer} -body {
  1361. proc readit {s} {
  1362. global count done
  1363. set l [read $s]
  1364. incr count [string length $l]
  1365. if {[eof $s]} {
  1366. close $s
  1367. set done 1
  1368. }
  1369. }
  1370. set s [socket $remoteServerIP 2845]
  1371. fconfigure $s -blocking 0 -trans lf -buffering line
  1372. set count 0
  1373. puts $s hello
  1374. fileevent $s readable "readit $s"
  1375. vwait done
  1376. return $count
  1377. } -cleanup {
  1378. after cancel $timer
  1379. sendCommand {close $l}
  1380. } -result 65566
  1381. set path(script1) [makeFile {} script1]
  1382. set path(script2) [makeFile {} script2]
  1383. test socket-12.1 {testing inheritance of server sockets} -setup {
  1384. file delete $path(script1)
  1385. file delete $path(script2)
  1386. # Script1 is just a 10 second delay. If the server socket is inherited, it
  1387. # will be held open for 10 seconds
  1388. set f [open $path(script1) w]
  1389. puts $f {
  1390. after 10000 exit
  1391. vwait forever
  1392. }
  1393. close $f
  1394. # Script2 creates the server socket, launches script1, waits a second, and
  1395. # exits. The server socket will now be closed unless script1 inherited it.
  1396. set f [open $path(script2) w]
  1397. puts $f [list set tcltest [interpreter]]
  1398. puts $f [list set delay $path(script1)]
  1399. puts $f {
  1400. set f [socket -server accept -myaddr 127.0.0.1 0]
  1401. puts [lindex [fconfigure $f -sockname] 2]
  1402. proc accept { file addr port } {
  1403. close $file
  1404. }
  1405. exec $tcltest $delay &
  1406. close $f
  1407. after 1000 exit
  1408. vwait forever
  1409. }
  1410. close $f
  1411. } -constraints {socket stdio exec} -body {
  1412. # Launch script2 and wait 5 seconds
  1413. ### exec [interpreter] script2 &
  1414. set p [open "|[list [interpreter] $path(script2)]" r]
  1415. gets $p listen
  1416. after 5000 { set ok_to_proceed 1 }
  1417. vwait ok_to_proceed
  1418. # If we can still connect to the server, the socket got inherited.
  1419. if {[catch {close [socket 127.0.0.1 $listen]}]} {
  1420. return {server socket was not inherited}
  1421. } else {
  1422. return {server socket was inherited}
  1423. }
  1424. } -cleanup {
  1425. close $p
  1426. } -result {server socket was not inherited}
  1427. test socket-12.2 {testing inheritance of client sockets} -setup {
  1428. file delete $path(script1)
  1429. file delete $path(script2)
  1430. # Script1 is just a 20 second delay. If the server socket is inherited, it
  1431. # will be held open for 20 seconds
  1432. set f [open $path(script1) w]
  1433. puts $f {
  1434. after 20000 exit
  1435. vwait forever
  1436. }
  1437. close $f
  1438. # Script2 opens the client socket and writes to it. It then launches
  1439. # script1 and exits. If the child process inherited the client socket, the
  1440. # socket will still be open.
  1441. set f [open $path(script2) w]
  1442. puts $f [list set tcltest [interpreter]]
  1443. puts $f [list set delay $path(script1)]
  1444. puts $f {
  1445. gets stdin port
  1446. set f [socket 127.0.0.1 $port]
  1447. exec $tcltest $delay &
  1448. puts $f testing
  1449. flush $f
  1450. after 1000 exit
  1451. vwait forever
  1452. }
  1453. close $f
  1454. # If the socket doesn't hit end-of-file in 10 seconds, the script1 process
  1455. # must have inherited the client.
  1456. set failed 0
  1457. after 10000 [list set failed 1]
  1458. } -constraints {socket stdio exec} -body {
  1459. # Create the server socket
  1460. set server [socket -server accept -myaddr 127.0.0.1 0]
  1461. proc accept { file host port } {
  1462. # When the client connects, establish the read handler
  1463. global server
  1464. close $server
  1465. fileevent $file readable [list getdata $file]
  1466. fconfigure $file -buffering line -blocking 0
  1467. }
  1468. proc getdata { file } {
  1469. # Read handler on the accepted socket.
  1470. global x failed
  1471. set status [catch {read $file} data]
  1472. if {$status != 0} {
  1473. set x {read failed, error was $data}
  1474. catch { close $file }
  1475. } elseif {$data ne ""} {
  1476. } elseif {[fblocked $file]} {
  1477. } elseif {[eof $file]} {
  1478. if {$failed} {
  1479. set x {client socket was inherited}
  1480. } else {
  1481. set x {client socket was not inherited}
  1482. }
  1483. catch { close $file }
  1484. } else {
  1485. set x {impossible case}
  1486. catch { close $file }
  1487. }
  1488. }
  1489. # Launch the script2 process
  1490. ### exec [interpreter] script2 &
  1491. set p [open "|[list [interpreter] $path(script2)]" w]
  1492. puts $p [lindex [fconfigure $server -sockname] 2] ; flush $p
  1493. vwait x
  1494. return $x
  1495. } -cleanup {
  1496. if {!$failed} {
  1497. vwait failed
  1498. }
  1499. close $p
  1500. } -result {client socket was not inherited}
  1501. test socket-12.3 {testing inheritance of accepted sockets} -setup {
  1502. file delete $path(script1)
  1503. file delete $path(script2)
  1504. set f [open $path(script1) w]
  1505. puts $f {
  1506. after 10000 exit
  1507. vwait forever
  1508. }
  1509. close $f
  1510. set f [open $path(script2) w]
  1511. puts $f [list set tcltest [interpreter]]
  1512. puts $f [list set delay $path(script1)]
  1513. puts $f {
  1514. set server [socket -server accept -myaddr 127.0.0.1 0]
  1515. puts stdout [lindex [fconfigure $server -sockname] 2]
  1516. proc accept { file host port } {
  1517. global tcltest delay
  1518. puts $file {test data on socket}
  1519. exec $tcltest $delay &
  1520. after 1000 exit
  1521. }
  1522. vwait forever
  1523. }
  1524. close $f
  1525. } -constraints {socket stdio exec} -body {
  1526. # Launch the script2 process and connect to it. See how long the socket
  1527. # stays open
  1528. ## exec [interpreter] script2 &
  1529. set p [open "|[list [interpreter] $path(script2)]" r]
  1530. gets $p listen
  1531. after 1000 set ok_to_proceed 1
  1532. vwait ok_to_proceed
  1533. set f [socket 127.0.0.1 $listen]
  1534. fconfigure $f -buffering full -blocking 0
  1535. fileevent $f readable [list getdata $f]
  1536. # If the socket is still open after 5 seconds, the script1 process must
  1537. # have inherited the accepted socket.
  1538. set failed 0
  1539. after 5000 set failed 1
  1540. proc getdata { file } {
  1541. # Read handler on the client socket.
  1542. global x
  1543. global failed
  1544. set status [catch {read $file} data]
  1545. if {$status != 0} {
  1546. set x {read failed, error was $data}
  1547. catch { close $file }
  1548. } elseif {[string compare {} $data]} {
  1549. } elseif {[fblocked $file]} {
  1550. } elseif {[eof $file]} {
  1551. if {$failed} {
  1552. set x {accepted socket was inherited}
  1553. } else {
  1554. set x {accepted socket was not inherited}
  1555. }
  1556. catch { close $file }
  1557. } else {
  1558. set x {impossible case}
  1559. catch { close $file }
  1560. }
  1561. return
  1562. }
  1563. vwait x
  1564. return $x
  1565. } -cleanup {
  1566. catch {close $p}
  1567. } -result {accepted socket was not inherited}
  1568. test socket-13.1 {Testing use of shared socket between two threads} -setup {
  1569. threadReap
  1570. set path(script) [makeFile {
  1571. set f [socket -server accept -myaddr 127.0.0.1 0]
  1572. set listen [lindex [fconfigure $f -sockname] 2]
  1573. proc accept {s a p} {
  1574. fileevent $s readable [list echo $s]
  1575. fconfigure $s -buffering line
  1576. }
  1577. proc echo {s} {
  1578. global i
  1579. set l [gets $s]
  1580. if {[eof $s]} {
  1581. global x
  1582. close $s
  1583. set x done
  1584. } else {
  1585. incr i
  1586. puts $s $l
  1587. }
  1588. }
  1589. set i 0
  1590. vwait x
  1591. close $f
  1592. # thread cleans itself up.
  1593. testthread exit
  1594. } script]
  1595. } -constraints {socket testthread} -body {
  1596. # create a thread
  1597. set serverthread [testthread create [list source $path(script) ] ]
  1598. update
  1599. set port [testthread send $serverthread {set listen}]
  1600. update
  1601. after 1000
  1602. set s [socket 127.0.0.1 $port]
  1603. fconfigure $s -buffering line
  1604. catch {
  1605. puts $s "hello"
  1606. gets $s result
  1607. }
  1608. close $s
  1609. update
  1610. after 2000
  1611. append result " " [threadReap]
  1612. } -cleanup {
  1613. removeFile script
  1614. } -result {hello 1}
  1615. # ----------------------------------------------------------------------
  1616. removeFile script1
  1617. removeFile script2
  1618. # cleanup
  1619. if {[string match sock* $commandSocket] == 1} {
  1620. puts $commandSocket exit
  1621. flush $commandSocket
  1622. }
  1623. catch {close $commandSocket}
  1624. catch {close $remoteProcChan}
  1625. ::tcltest::cleanupTests
  1626. flush stdout
  1627. return
  1628. # Local Variables:
  1629. # mode: tcl
  1630. # fill-column: 78
  1631. # End: