os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/tests/iogt.test
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 # -*- tcl -*-
     2 # Commands covered:  transform, and stacking in general
     3 #
     4 # This file contains a collection of tests for Giot
     5 #
     6 # See the file "license.terms" for information on usage and redistribution
     7 # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
     8 # 
     9 # Copyright (c) 2000 Ajuba Solutions.
    10 # Copyright (c) 2000 Andreas Kupries.
    11 # All rights reserved.
    12 # 
    13 # RCS: @(#) $Id: iogt.test,v 1.7.2.1 2005/04/14 07:10:57 davygrvy Exp $
    14 
    15 if {[catch {package require tcltest 2.1}]} {
    16     puts stderr "Skipping tests in [info script].  tcltest 2.1 required."
    17     return
    18 }
    19 namespace eval ::tcl::test::iogt {
    20 
    21     namespace import ::tcltest::cleanupTests
    22     namespace import ::tcltest::makeFile
    23     namespace import ::tcltest::removeFile
    24     namespace import ::tcltest::test
    25     namespace import ::tcltest::testConstraint
    26 
    27     testConstraint testchannel [llength [info commands testchannel]]
    28 
    29 set path(dummy) [makeFile {abcdefghijklmnopqrstuvwxyz0123456789,./?><;'\|":[]\}\{`~!@#$%^&*()_+-=
    30 } dummy]
    31 
    32 # " capture coloring of quotes
    33 
    34 set path(dummyout) [makeFile {} dummyout]
    35 
    36 set path(__echo_srv__.tcl) [makeFile {
    37 #!/usr/local/bin/tclsh
    38 # -*- tcl -*-
    39 # echo server
    40 #
    41 # arguments, options: port to listen on for connections.
    42 #                     delay till echo of first block
    43 #                     delay between blocks
    44 #                     blocksize ...
    45 
    46 set port   [lindex $argv 0]
    47 set fdelay [lindex $argv 1]
    48 set idelay [lindex $argv 2]
    49 set bsizes [lrange $argv 3 end]
    50 set c      0
    51 
    52 proc newconn {sock rhost rport} {
    53     variable fdelay
    54     variable c
    55     incr   c
    56     variable c$c
    57 
    58     #puts stdout "C $sock $rhost $rport / $fdelay" ; flush stdout
    59 
    60     upvar 0 c$c conn
    61     set conn(after) {}
    62     set conn(state) 0
    63     set conn(size)  0
    64     set conn(data)  ""
    65     set conn(delay) $fdelay
    66 
    67     fileevent  $sock readable [list echoGet $c $sock]
    68     fconfigure $sock -translation binary -buffering none -blocking 0
    69 }
    70 
    71 proc echoGet {c sock} {
    72     variable fdelay
    73     variable c$c
    74     upvar 0 c$c conn
    75 
    76     if {[eof $sock]} {
    77 	# one-shot echo
    78 	exit
    79     }
    80 
    81     append conn(data) [read $sock]
    82 
    83     #puts stdout "G $c $sock $conn(data) <<$conn(data)>>" ; flush stdout
    84 
    85     if {$conn(after) == {}} {
    86 	set conn(after) [after $conn(delay) [list echoPut $c $sock]]
    87     }
    88 }
    89 
    90 proc echoPut {c sock} {
    91     variable idelay
    92     variable fdelay
    93     variable bsizes
    94     variable c$c
    95     upvar 0 c$c conn
    96 
    97     if {[string length $conn(data)] == 0} {
    98 	#puts stdout "C $c $sock" ; flush stdout
    99 	# auto terminate
   100 	close $sock
   101 	exit
   102 	#set conn(delay) $fdelay
   103 	return
   104     }
   105 
   106 
   107     set conn(delay) $idelay
   108 
   109     set n [lindex $bsizes $conn(size)]
   110 
   111     #puts stdout "P $c $sock $n >>" ; flush stdout
   112 
   113     #puts __________________________________________
   114     #parray conn
   115     #puts n=<$n>
   116 
   117 
   118     if {[string length $conn(data)] >= $n} {
   119 	puts -nonewline $sock [string range $conn(data) 0 $n]
   120 	set conn(data) [string range $conn(data) [incr n] end]
   121     }
   122 
   123     incr conn(size)
   124     if {$conn(size) >= [llength $bsizes]} {
   125 	set conn(size) [expr {[llength $bsizes]-1}]
   126     }
   127 
   128     set conn(after) [after $conn(delay) [list echoPut $c $sock]]
   129 }
   130 
   131 #fileevent stdin readable {exit ;#cut}
   132 
   133 # main
   134 socket -server newconn $port
   135 vwait forever
   136 } __echo_srv__.tcl]
   137 
   138 
   139 ########################################################################
   140 
   141 proc fevent {fdelay idelay blocks script data} {
   142     # start and initialize an echo server, prepare data
   143     # transmission, then hand over to the test script.
   144     # this has to start real transmission via 'flush'.
   145     # The server is stopped after completion of the test.
   146 
   147     # fixed port, not so good. lets hope for the best, for now.
   148     set port 4000
   149 
   150     eval exec tclsh __echo_srv__.tcl \
   151 	    $port $fdelay $idelay $blocks >@stdout &
   152 
   153     after 500
   154 
   155     #puts stdout "> $port" ; flush stdout
   156 
   157     set         sk [socket localhost $port]
   158     fconfigure $sk           \
   159 	    -blocking   0    \
   160 	    -buffering  full \
   161 	    -buffersize [expr {10+[llength $data]}]
   162 
   163     puts -nonewline $sk $data
   164 
   165     # The channel is prepared to go off.
   166 
   167     #puts stdout ">>>>>" ; flush stdout
   168 
   169     uplevel #0 set sock $sk
   170     set res [uplevel #0 $script]
   171 
   172     catch {close $sk}
   173     return $res
   174 }
   175 
   176 # --------------------------------------------------------------
   177 # utility transformations ...
   178 
   179 proc id {op data} {
   180     switch -- $op {
   181 	create/write -
   182 	create/read  -
   183 	delete/write -
   184 	delete/read  -
   185 	clear_read   {;#ignore}
   186 	flush/write -
   187 	flush/read  -
   188 	write       -
   189 	read        {
   190 	    return $data
   191 	}
   192 	query/maxRead {return -1}
   193     }
   194 }
   195 
   196 proc id_optrail {var op data} {
   197     variable $var
   198     upvar 0 $var trail
   199 
   200     lappend trail $op
   201 
   202     switch -- $op {
   203 	create/write	-	create/read	-
   204 	delete/write	-	delete/read	-
   205 	flush/read	-
   206 	clear/read	{ #ignore }
   207 	flush/write	-
   208 	write		-
   209 	read		{
   210 	    return $data
   211 	}
   212 	query/maxRead	{
   213 	    return -1
   214 	}
   215 	default		{
   216 	    lappend trail "error $op"
   217 	    error $op
   218 	}
   219     }
   220 }
   221 
   222 
   223 proc id_fulltrail {var op data} {
   224     variable $var
   225     upvar 0 $var trail
   226 
   227     #puts stdout ">> $var $op $data" ; flush stdout
   228 
   229     switch -- $op {
   230 	create/write -	create/read  -
   231 	delete/write -	delete/read  -
   232 	clear_read   {
   233 	    set res *ignored*
   234 	}
   235 	flush/write -	flush/read  -
   236 	write       -
   237 	read        {
   238 	    set res $data
   239 	}
   240 	query/maxRead {
   241 	    set res -1
   242 	}
   243     }
   244 
   245     #catch {puts stdout "\t>* $res" ; flush stdout}
   246     #catch {puts stdout "x$res"} msg
   247 
   248     lappend trail [list $op $data $res]
   249     return $res
   250 }
   251 
   252 proc counter {var op data} {
   253     variable $var
   254     upvar 0 $var n
   255 
   256     switch -- $op {
   257 	create/write -	create/read  -
   258 	delete/write -	delete/read  -
   259 	clear_read   {;#ignore}
   260 	flush/write  -	flush/read   {return {}}
   261 	write {
   262 	    return $data
   263 	}
   264 	read  {
   265 	    if {$n > 0} {
   266 		incr n -[string length $data]
   267 		if {$n < 0} {
   268 		    set n 0
   269 		}
   270 	    }
   271 	    return $data
   272 	}
   273 	query/maxRead {
   274 	    return $n
   275 	}
   276     }
   277 }
   278 
   279 
   280 proc counter_audit {var vtrail op data} {
   281     variable $var
   282     variable $vtrail
   283     upvar 0 $var n $vtrail trail
   284 
   285     switch -- $op {
   286 	create/write -	create/read  -
   287 	delete/write -	delete/read  -
   288 	clear_read   {
   289 	    set res {}
   290 	}
   291 	flush/write  -	flush/read   {
   292 	    set res {}
   293 	}
   294 	write {
   295 	    set res $data
   296 	}
   297 	read  {
   298 	    if {$n > 0} {
   299 		incr n -[string length $data]
   300 		if {$n < 0} {
   301 		    set n 0
   302 		}
   303 	    }
   304 	    set res $data
   305 	}
   306 	query/maxRead {
   307 	    set res $n
   308 	}
   309     }
   310 
   311     lappend trail [list counter:$op $data $res]
   312     return $res
   313 }
   314 
   315 
   316 proc rblocks {var vtrail n op data} {
   317     variable $var
   318     variable $vtrail
   319     upvar 0 $var buf $vtrail trail
   320 
   321     set res {}
   322 
   323     switch -- $op {
   324 	create/write -	create/read  -
   325 	delete/write -	delete/read  -
   326 	clear_read   {
   327 	    set buf {}
   328 	}
   329 	flush/write {
   330 	}
   331 	flush/read  {
   332 	    set res $buf
   333 	    set buf {}
   334 	}
   335 	write       {
   336 	    set data
   337 	}
   338 	read        {
   339 	    append buf $data
   340 
   341 	    set b [expr {$n * ([string length $buf] / $n)}]
   342 
   343 	    append op " $n [string length $buf] :- $b"
   344 
   345 	    set res [string range $buf 0 [incr b -1]]
   346 	    set buf [string range $buf [incr b] end]
   347 	    #return $res
   348 	}
   349 	query/maxRead {
   350 	    set res -1
   351 	}
   352     }
   353 
   354     lappend trail [list rblock | $op $data $res | $buf]
   355     return $res
   356 }
   357 
   358 
   359 # --------------------------------------------------------------
   360 # ... and convenience procedures to stack them
   361 
   362 proc identity {-attach channel} {
   363     testchannel transform $channel -command [namespace code id]
   364 }
   365 
   366 proc audit_ops {var -attach channel} {
   367     testchannel transform $channel -command [namespace code [list id_optrail $var]]
   368 }
   369 
   370 proc audit_flow {var -attach channel} {
   371     testchannel transform $channel -command [namespace code [list id_fulltrail $var]]
   372 }
   373 
   374 proc stopafter {var n -attach channel} {
   375     variable $var
   376     upvar 0 $var vn
   377     set vn $n
   378     testchannel transform $channel -command [namespace code [list counter $var]]
   379 }
   380 
   381 proc stopafter_audit {var trail n -attach channel} {
   382     variable $var
   383     upvar 0 $var vn
   384     set vn $n
   385     testchannel transform $channel -command [namespace code [list counter_audit $var $trail]]
   386 }
   387 
   388 proc rblocks_t {var trail n -attach channel} {
   389     testchannel transform $channel -command [namespace code [list rblocks $var $trail $n]]
   390 }
   391 
   392 # --------------------------------------------------------------
   393 # serialize an array, with keys in sorted order.
   394 
   395 proc array_sget {v} {
   396     upvar $v a
   397 
   398     set res [list]
   399     foreach n [lsort [array names a]] {
   400 	lappend res $n $a($n)
   401     }
   402     set res
   403 }
   404 
   405 proc asort {alist} {
   406     # sort a list of key/value pairs by key, removes duplicates too.
   407 
   408     array set  a $alist
   409     array_sget a
   410 }
   411 
   412 ########################################################################
   413 
   414 test iogt-1.1 {stack/unstack} testchannel {
   415     set fh [open $path(dummy) r]
   416     identity -attach $fh
   417     testchannel unstack $fh
   418     close   $fh
   419 } {}
   420 
   421 test iogt-1.2 {stack/close} testchannel {
   422     set fh [open $path(dummy) r]
   423     identity -attach $fh
   424     close   $fh
   425 } {}
   426 
   427 test iogt-1.3 {stack/unstack, configuration, options} testchannel {
   428     set fh [open $path(dummy) r]
   429     set ca [asort [fconfigure $fh]]
   430     identity -attach $fh
   431     set cb [asort [fconfigure $fh]]
   432     testchannel unstack $fh
   433     set cc [asort [fconfigure $fh]]
   434     close $fh
   435 
   436     # With this system none of the buffering, translation and
   437     # encoding option may change their values with channels
   438     # stacked upon each other or not.
   439 
   440     # cb == ca == cc
   441 
   442     list [string equal $ca $cb] [string equal $cb $cc] [string equal $ca $cc]
   443 } {1 1 1}
   444 
   445 test iogt-1.4 {stack/unstack, configuration} testchannel {
   446     set fh [open $path(dummy) r]
   447     set ca [asort [fconfigure $fh]]
   448     identity -attach $fh
   449     fconfigure $fh \
   450 	    -buffering   line \
   451 	    -translation cr   \
   452 	    -encoding    shiftjis
   453     testchannel unstack $fh
   454     set cc [asort [fconfigure $fh]]
   455 
   456     set res [list \
   457 	    [string equal $ca $cc]   \
   458 	    [fconfigure $fh -buffering]  \
   459 	    [fconfigure $fh -translation] \
   460 	    [fconfigure $fh -encoding]    \
   461 	    ]
   462 
   463     close $fh
   464     set res
   465 } {0 line cr shiftjis}
   466 
   467 test iogt-2.0 {basic I/O going through transform} testchannel {
   468     set fin  [open $path(dummy)    r]
   469     set fout [open $path(dummyout) w]
   470 
   471     identity -attach $fin
   472     identity -attach $fout
   473 
   474     fcopy $fin $fout
   475 
   476     close $fin
   477     close $fout
   478 
   479     set fin  [open $path(dummy)    r]
   480     set fout [open $path(dummyout) r]
   481 
   482     set res     [string equal [set in [read $fin]] [set out [read $fout]]]
   483     lappend res [string length $in] [string length $out]
   484 
   485     close $fin
   486     close $fout
   487 
   488     set res
   489 } {1 71 71}
   490 
   491 
   492 test iogt-2.1 {basic I/O, operation trail} {testchannel unixOnly} {
   493     set fin  [open $path(dummy)    r]
   494     set fout [open $path(dummyout) w]
   495 
   496     set ain [list] ; set aout [list]
   497     audit_ops ain  -attach $fin
   498     audit_ops aout -attach $fout
   499 
   500     fconfigure $fin  -buffersize 10
   501     fconfigure $fout -buffersize 10
   502 
   503     fcopy $fin $fout
   504 
   505     close $fin
   506     close $fout
   507 
   508     set res "[join $ain \n]\n--------\n[join $aout \n]"
   509 } {create/read
   510 query/maxRead
   511 read
   512 query/maxRead
   513 read
   514 query/maxRead
   515 read
   516 query/maxRead
   517 read
   518 query/maxRead
   519 read
   520 query/maxRead
   521 read
   522 query/maxRead
   523 read
   524 query/maxRead
   525 read
   526 query/maxRead
   527 flush/read
   528 delete/read
   529 --------
   530 create/write
   531 write
   532 write
   533 write
   534 write
   535 write
   536 write
   537 write
   538 write
   539 flush/write
   540 delete/write}
   541 
   542 test iogt-2.2 {basic I/O, data trail} {testchannel unixOnly} {
   543     set fin  [open $path(dummy)    r]
   544     set fout [open $path(dummyout) w]
   545 
   546     set ain [list] ; set aout [list]
   547     audit_flow ain  -attach $fin
   548     audit_flow aout -attach $fout
   549 
   550     fconfigure $fin  -buffersize 10
   551     fconfigure $fout -buffersize 10
   552 
   553     fcopy $fin $fout
   554 
   555     close $fin
   556     close $fout
   557 
   558     set res "[join $ain \n]\n--------\n[join $aout \n]"
   559 } {create/read {} *ignored*
   560 query/maxRead {} -1
   561 read abcdefghij abcdefghij
   562 query/maxRead {} -1
   563 read klmnopqrst klmnopqrst
   564 query/maxRead {} -1
   565 read uvwxyz0123 uvwxyz0123
   566 query/maxRead {} -1
   567 read 456789,./? 456789,./?
   568 query/maxRead {} -1
   569 read {><;'\|":[]} {><;'\|":[]}
   570 query/maxRead {} -1
   571 read {\}\{`~!@#$} {\}\{`~!@#$}
   572 query/maxRead {} -1
   573 read %^&*()_+-= %^&*()_+-=
   574 query/maxRead {} -1
   575 read {
   576 } {
   577 }
   578 query/maxRead {} -1
   579 flush/read {} {}
   580 delete/read {} *ignored*
   581 --------
   582 create/write {} *ignored*
   583 write abcdefghij abcdefghij
   584 write klmnopqrst klmnopqrst
   585 write uvwxyz0123 uvwxyz0123
   586 write 456789,./? 456789,./?
   587 write {><;'\|":[]} {><;'\|":[]}
   588 write {\}\{`~!@#$} {\}\{`~!@#$}
   589 write %^&*()_+-= %^&*()_+-=
   590 write {
   591 } {
   592 }
   593 flush/write {} {}
   594 delete/write {} *ignored*}
   595 
   596 
   597 test iogt-2.3 {basic I/O, mixed trail} {testchannel unixOnly} {
   598     set fin  [open $path(dummy)    r]
   599     set fout [open $path(dummyout) w]
   600 
   601     set trail [list]
   602     audit_flow trail -attach $fin
   603     audit_flow trail -attach $fout
   604 
   605     fconfigure $fin  -buffersize 20
   606     fconfigure $fout -buffersize 10
   607 
   608     fcopy $fin $fout
   609 
   610     close $fin
   611     close $fout
   612 
   613     join $trail \n
   614 } {create/read {} *ignored*
   615 create/write {} *ignored*
   616 query/maxRead {} -1
   617 read abcdefghijklmnopqrst abcdefghijklmnopqrst
   618 write abcdefghij abcdefghij
   619 write klmnopqrst klmnopqrst
   620 query/maxRead {} -1
   621 read uvwxyz0123456789,./? uvwxyz0123456789,./?
   622 write uvwxyz0123 uvwxyz0123
   623 write 456789,./? 456789,./?
   624 query/maxRead {} -1
   625 read {><;'\|":[]\}\{`~!@#$} {><;'\|":[]\}\{`~!@#$}
   626 write {><;'\|":[]} {><;'\|":[]}
   627 write {\}\{`~!@#$} {\}\{`~!@#$}
   628 query/maxRead {} -1
   629 read {%^&*()_+-=
   630 } {%^&*()_+-=
   631 }
   632 query/maxRead {} -1
   633 flush/read {} {}
   634 write %^&*()_+-= %^&*()_+-=
   635 write {
   636 } {
   637 }
   638 delete/read {} *ignored*
   639 flush/write {} {}
   640 delete/write {} *ignored*}
   641 
   642 
   643 test iogt-3.0 {Tcl_Channel valid after stack/unstack, fevent handling} \
   644 	{testchannel unknownFailure} {
   645     # This test to check the validity of aquired Tcl_Channel references is
   646     # not possible because even a backgrounded fcopy will immediately start
   647     # to copy data, without waiting for the event loop. This is done only in
   648     # case of an underflow on the read size!. So stacking transforms after the
   649     # fcopy will miss information, or are not used at all.
   650     #
   651     # I was able to circumvent this by using the echo.tcl server with a big
   652     # delay, causing the fcopy to underflow immediately.
   653 
   654     proc DoneCopy {n {err {}}} {
   655 	variable copy ; set copy 1
   656     }
   657 
   658     set fin  [open $path(dummy) r]
   659 
   660     fevent 1000 500 {20 20 20 10 1 1} {
   661 	close $fin
   662 
   663 	set          fout [open dummyout w]
   664 
   665 	flush $sock ; # now, or fcopy will error us out
   666 	# But the 1 second delay should be enough to
   667 	# initialize everything else here.
   668 
   669 	fcopy $sock $fout -command [namespace code DoneCopy]
   670 
   671 	# transform after fcopy got its handles !
   672 	# They should be still valid for fcopy.
   673 
   674 	set trail [list]
   675 	audit_ops trail -attach $fout
   676 
   677 	vwait [namespace which -variable copy]
   678     } [read $fin] ; # {}
   679 
   680     close $fout
   681 
   682     rename DoneCopy {}
   683 
   684     # Check result of copy.
   685 
   686     set fin  [open $path(dummy)    r]
   687     set fout [open $path(dummyout) r]
   688 
   689     set res [string equal [read $fin] [read $fout]]
   690 
   691     close $fin
   692     close $fout
   693 
   694     list $res $trail
   695 } {1 {create/write create/read write flush/write flush/read delete/write delete/read}}
   696 
   697 
   698 test iogt-4.0 {fileevent readable, after transform} {testchannel unknownFailure} {
   699     set fin  [open $path(dummy) r]
   700     set data [read $fin]
   701     close $fin
   702 
   703     set trail [list]
   704     set got   [list]
   705 
   706     proc Done {args} {
   707 	variable stop
   708 	set    stop 1
   709     }
   710 
   711     proc Get {sock} {
   712 	variable trail
   713 	variable got
   714 	if {[eof $sock]} {
   715 	    Done
   716 	    lappend trail "xxxxxxxxxxxxx"
   717 	    close $sock
   718 	    return
   719 	}
   720 	lappend trail "vvvvvvvvvvvvv"
   721 	lappend trail "\tgot: [lappend got "\[\[[read $sock]\]\]"]"
   722 	lappend trail "============="
   723 	#puts stdout $__ ; flush stdout
   724 	#read $sock
   725     }
   726 
   727     fevent 1000 500 {20 20 20 10 1} {
   728 	audit_flow trail   -attach $sock
   729 	rblocks_t  rbuf trail 23 -attach $sock
   730 
   731 	fileevent $sock readable [list Get $sock]
   732 
   733 	flush $sock ; # now, or fcopy will error us out
   734 	# But the 1 second delay should be enough to
   735 	# initialize everything else here.
   736 
   737 	vwait [namespace which -variable stop]
   738     } $data
   739 
   740 
   741     rename Done {}
   742     rename Get {}
   743 
   744     join [list [join $got \n] ~~~~~~~~ [join $trail \n]] \n
   745 } {[[]]
   746 [[abcdefghijklmnopqrstuvw]]
   747 [[xyz0123456789,./?><;'\|]]
   748 [[]]
   749 [[]]
   750 [[":[]\}\{`~!@#$%^&*()]]
   751 [[]]
   752 ~~~~~~~~
   753 create/write {} *ignored*
   754 create/read {} *ignored*
   755 rblock | create/write {} {} | {}
   756 rblock | create/read {} {} | {}
   757 vvvvvvvvvvvvv
   758 rblock | query/maxRead {} -1 | {}
   759 query/maxRead {} -1
   760 read abcdefghijklmnopqrstu abcdefghijklmnopqrstu
   761 query/maxRead {} -1
   762 rblock | {read 23 21 :- 0} abcdefghijklmnopqrstu {} | abcdefghijklmnopqrstu
   763 rblock | query/maxRead {} -1 | abcdefghijklmnopqrstu
   764 query/maxRead {} -1
   765 	got: {[[]]}
   766 =============
   767 vvvvvvvvvvvvv
   768 rblock | query/maxRead {} -1 | abcdefghijklmnopqrstu
   769 query/maxRead {} -1
   770 read vwxyz0123456789,./?>< vwxyz0123456789,./?><
   771 query/maxRead {} -1
   772 rblock | {read 23 42 :- 23} vwxyz0123456789,./?>< abcdefghijklmnopqrstuvw | xyz0123456789,./?><
   773 rblock | query/maxRead {} -1 | xyz0123456789,./?><
   774 query/maxRead {} -1
   775 	got: {[[]]} {[[abcdefghijklmnopqrstuvw]]}
   776 =============
   777 vvvvvvvvvvvvv
   778 rblock | query/maxRead {} -1 | xyz0123456789,./?><
   779 query/maxRead {} -1
   780 read {;'\|":[]\}\{`~!@#$%^&} {;'\|":[]\}\{`~!@#$%^&}
   781 query/maxRead {} -1
   782 rblock | {read 23 40 :- 23} {;'\|":[]\}\{`~!@#$%^&} {xyz0123456789,./?><;'\|} | {":[]\}\{`~!@#$%^&}
   783 rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&}
   784 query/maxRead {} -1
   785 	got: {[[]]} {[[abcdefghijklmnopqrstuvw]]} {[[xyz0123456789,./?><;'\|]]}
   786 =============
   787 vvvvvvvvvvvvv
   788 rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&}
   789 query/maxRead {} -1
   790 read *( *(
   791 query/maxRead {} -1
   792 rblock | {read 23 19 :- 0} *( {} | {":[]\}\{`~!@#$%^&*(}
   793 rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&*(}
   794 query/maxRead {} -1
   795 	got: {[[]]} {[[abcdefghijklmnopqrstuvw]]} {[[xyz0123456789,./?><;'\|]]} {[[]]}
   796 =============
   797 vvvvvvvvvvvvv
   798 rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&*(}
   799 query/maxRead {} -1
   800 read ) )
   801 query/maxRead {} -1
   802 rblock | {read 23 20 :- 0} ) {} | {":[]\}\{`~!@#$%^&*()}
   803 rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&*()}
   804 query/maxRead {} -1
   805 	got: {[[]]} {[[abcdefghijklmnopqrstuvw]]} {[[xyz0123456789,./?><;'\|]]} {[[]]} {[[]]}
   806 =============
   807 vvvvvvvvvvvvv
   808 rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&*()}
   809 query/maxRead {} -1
   810 flush/read {} {}
   811 rblock | flush/read {} {":[]\}\{`~!@#$%^&*()} | {}
   812 rblock | query/maxRead {} -1 | {}
   813 query/maxRead {} -1
   814 	got: {[[]]} {[[abcdefghijklmnopqrstuvw]]} {[[xyz0123456789,./?><;'\|]]} {[[]]} {[[]]} {[[":[]\}\{`~!@#$%^&*()]]}
   815 =============
   816 vvvvvvvvvvvvv
   817 rblock | query/maxRead {} -1 | {}
   818 query/maxRead {} -1
   819 	got: {[[]]} {[[abcdefghijklmnopqrstuvw]]} {[[xyz0123456789,./?><;'\|]]} {[[]]} {[[]]} {[[":[]\}\{`~!@#$%^&*()]]} {[[]]}
   820 xxxxxxxxxxxxx
   821 rblock | flush/write {} {} | {}
   822 rblock | delete/write {} {} | {}
   823 rblock | delete/read {} {} | {}
   824 flush/write {} {}
   825 delete/write {} *ignored*
   826 delete/read {} *ignored*}  ; # catch unescaped quote "
   827 
   828 
   829 test iogt-5.0 {EOF simulation} {testchannel unknownFailure} {
   830     set fin  [open $path(dummy)    r]
   831     set fout [open $path(dummyout) w]
   832 
   833     set trail [list]
   834 
   835     audit_flow trail -attach $fin
   836     stopafter_audit d trail 20 -attach   $fin
   837     audit_flow trail -attach $fout
   838 
   839     fconfigure $fin  -buffersize 20
   840     fconfigure $fout -buffersize 10
   841 
   842     fcopy   $fin $fout
   843     testchannel unstack $fin
   844 
   845     # now copy the rest in the channel
   846     lappend trail {**after unstack**}
   847 
   848     fcopy $fin $fout
   849 
   850     close $fin
   851     close $fout
   852 
   853     join $trail \n
   854 } {create/read {} *ignored*
   855 counter:create/read {} {}
   856 create/write {} *ignored*
   857 counter:query/maxRead {} 20
   858 query/maxRead {} -1
   859 read {abcdefghijklmnopqrstuvwxyz0123456789,./?><;'\|":[]\}\{`~!@#$%^&*()_+-=
   860 } {abcdefghijklmnopqrstuvwxyz0123456789,./?><;'\|":[]\}\{`~!@#$%^&*()_+-=
   861 }
   862 query/maxRead {} -1
   863 flush/read {} {}
   864 counter:read abcdefghijklmnopqrst abcdefghijklmnopqrst
   865 write abcdefghij abcdefghij
   866 write klmnopqrst klmnopqrst
   867 counter:query/maxRead {} 0
   868 counter:flush/read {} {}
   869 counter:delete/read {} {}
   870 **after unstack**
   871 query/maxRead {} -1
   872 write uvwxyz0123 uvwxyz0123
   873 write 456789,./? 456789,./?
   874 write {><;'\|":[]} {><;'\|":[]}
   875 write {\}\{`~!@#$} {\}\{`~!@#$}
   876 write %^&*()_+-= %^&*()_+-=
   877 write {
   878 } {
   879 }
   880 query/maxRead {} -1
   881 delete/read {} *ignored*
   882 flush/write {} {}
   883 delete/write {} *ignored*}
   884 
   885 
   886 
   887 
   888 
   889 proc constX {op data} {
   890     # replace anything coming in with a same-length string of x'es.
   891     switch -- $op {
   892 	create/write -	create/read  -
   893 	delete/write -	delete/read  -
   894 	clear_read   {;#ignore}
   895 	flush/write -	flush/read  -
   896 	write       -
   897 	read        {
   898 	    return [string repeat x [string length $data]]
   899 	}
   900 	query/maxRead {return -1}
   901     }
   902 }
   903 
   904 proc constx {-attach channel} {
   905     testchannel transform $channel -command [namespace code constX]
   906 }
   907 
   908 test iogt-6.0 {Push back} testchannel {
   909     set f [open $path(dummy) r]
   910 
   911     # contents of dummy = "abcdefghi..."
   912     read $f 3 ; # skip behind "abc"
   913 
   914     constx -attach $f
   915 
   916     # expect to get "xxx" from the transform because
   917     # of unread "def" input to transform which returns "xxx".
   918     #
   919     # Actually the IO layer pre-read the whole file and will
   920     # read "def" directly from the buffer without bothering
   921     # to consult the newly stacked transformation. This is
   922     # wrong.
   923 
   924     set res [read $f 3]
   925     close $f
   926     set res
   927 } {xxx}
   928 
   929 test iogt-6.1 {Push back and up} {testchannel knownBug} {
   930     set f [open $path(dummy) r]
   931 
   932     # contents of dummy = "abcdefghi..."
   933     read $f 3 ; # skip behind "abc"
   934 
   935     constx -attach $f
   936     set res [read $f 3]
   937 
   938     testchannel unstack $f
   939     append res [read $f 3]
   940     close $f
   941     set res
   942 } {xxxghi}
   943 
   944 
   945 # cleanup
   946 foreach file [list dummy dummyout __echo_srv__.tcl] {
   947     removeFile $file
   948 }
   949 cleanupTests
   950 }
   951 namespace delete ::tcl::test::iogt
   952 return