1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
17 func checkWrite(t
*testing
.T
, w Writer
, data
[]byte, c
chan int) {
18 n
, err
:= w
.Write(data
)
20 t
.Errorf("write: %v", err
)
23 t
.Errorf("short write: %d != %d", n
, len(data
))
28 // Test a single read/write pair.
29 func TestPipe1(t
*testing
.T
) {
32 var buf
= make([]byte, 64)
33 go checkWrite(t
, w
, []byte("hello, world"), c
)
36 t
.Errorf("read: %v", err
)
37 } else if n
!= 12 ||
string(buf
[0:12]) != "hello, world" {
38 t
.Errorf("bad read: got %q", buf
[0:n
])
45 func reader(t
*testing
.T
, r Reader
, c
chan int) {
46 var buf
= make([]byte, 64)
54 t
.Errorf("read: %v", err
)
60 // Test a sequence of read/write pairs.
61 func TestPipe2(t
*testing
.T
) {
65 var buf
= make([]byte, 64)
66 for i
:= 0; i
< 5; i
++ {
70 t
.Errorf("wrote %d, got %d", len(p
), n
)
73 t
.Errorf("write: %v", err
)
77 t
.Errorf("wrote %d, read got %d", n
, nn
)
83 t
.Errorf("final read got %d", nn
)
87 type pipeReturn
struct {
92 // Test a large write that requires multiple reads to satisfy.
93 func writer(w WriteCloser
, buf
[]byte, c
chan pipeReturn
) {
94 n
, err
:= w
.Write(buf
)
96 c
<- pipeReturn
{n
, err
}
99 func TestPipe3(t
*testing
.T
) {
100 c
:= make(chan pipeReturn
)
102 var wdat
= make([]byte, 128)
103 for i
:= 0; i
< len(wdat
); i
++ {
106 go writer(w
, wdat
, c
)
107 var rdat
= make([]byte, 1024)
109 for n
:= 1; n
<= 256; n
*= 2 {
110 nn
, err
:= r
.Read(rdat
[tot
: tot
+n
])
111 if err
!= nil && err
!= EOF
{
112 t
.Fatalf("read: %v", err
)
115 // only final two reads should be short - 1 byte, then 0
122 t
.Fatalf("read at end: %v", err
)
126 t
.Fatalf("read %d, expected %d, got %d", n
, expect
, nn
)
131 if pr
.n
!= 128 || pr
.err
!= nil {
132 t
.Fatalf("write 128: %d, %v", pr
.n
, pr
.err
)
135 t
.Fatalf("total read %d != 128", tot
)
137 for i
:= 0; i
< 128; i
++ {
138 if rdat
[i
] != byte(i
) {
139 t
.Fatalf("rdat[%d] = %d", i
, rdat
[i
])
144 // Test read after/before writer close.
146 type closer
interface {
147 CloseWithError(error
) error
151 type pipeTest
struct {
157 func (p pipeTest
) String() string {
158 return fmt
.Sprintf("async=%v err=%v closeWithError=%v", p
.async
, p
.err
, p
.closeWithError
)
161 var pipeTests
= []pipeTest
{
164 {true, ErrShortWrite
, true},
167 {false, ErrShortWrite
, true},
170 func delayClose(t
*testing
.T
, cl closer
, ch
chan int, tt pipeTest
) {
171 time
.Sleep(1 * time
.Millisecond
)
173 if tt
.closeWithError
{
174 err
= cl
.CloseWithError(tt
.err
)
179 t
.Errorf("delayClose: %v", err
)
184 func TestPipeReadClose(t
*testing
.T
) {
185 for _
, tt
:= range pipeTests
{
186 c
:= make(chan int, 1)
189 go delayClose(t
, w
, c
, tt
)
191 delayClose(t
, w
, c
, tt
)
193 var buf
= make([]byte, 64)
194 n
, err
:= r
.Read(buf
)
201 t
.Errorf("read from closed pipe: %v want %v", err
, want
)
204 t
.Errorf("read on closed pipe returned %d", n
)
206 if err
= r
.Close(); err
!= nil {
207 t
.Errorf("r.Close: %v", err
)
212 // Test close on Read side during Read.
213 func TestPipeReadClose2(t
*testing
.T
) {
214 c
:= make(chan int, 1)
216 go delayClose(t
, r
, c
, pipeTest
{})
217 n
, err
:= r
.Read(make([]byte, 64))
219 if n
!= 0 || err
!= ErrClosedPipe
{
220 t
.Errorf("read from closed pipe: %v, %v want %v, %v", n
, err
, 0, ErrClosedPipe
)
224 // Test write after/before reader close.
226 func TestPipeWriteClose(t
*testing
.T
) {
227 for _
, tt
:= range pipeTests
{
228 c
:= make(chan int, 1)
231 go delayClose(t
, r
, c
, tt
)
233 delayClose(t
, r
, c
, tt
)
235 n
, err
:= WriteString(w
, "hello, world")
239 expect
= ErrClosedPipe
242 t
.Errorf("write on closed pipe: %v want %v", err
, expect
)
245 t
.Errorf("write on closed pipe returned %d", n
)
247 if err
= w
.Close(); err
!= nil {
248 t
.Errorf("w.Close: %v", err
)
253 // Test close on Write side during Write.
254 func TestPipeWriteClose2(t
*testing
.T
) {
255 c
:= make(chan int, 1)
257 go delayClose(t
, w
, c
, pipeTest
{})
258 n
, err
:= w
.Write(make([]byte, 64))
260 if n
!= 0 || err
!= ErrClosedPipe
{
261 t
.Errorf("write to closed pipe: %v, %v want %v, %v", n
, err
, 0, ErrClosedPipe
)
265 func TestWriteEmpty(t
*testing
.T
) {
276 func TestWriteNil(t
*testing
.T
) {
287 func TestWriteAfterWriterClose(t
*testing
.T
) {
290 done
:= make(chan bool)
293 _
, err
:= w
.Write([]byte("hello"))
295 t
.Errorf("got error: %q; expected none", err
)
298 _
, writeErr
= w
.Write([]byte("world"))
302 buf
:= make([]byte, 100)
304 n
, err
:= ReadFull(r
, buf
)
305 if err
!= nil && err
!= ErrUnexpectedEOF
{
306 t
.Fatalf("got: %q; want: %q", err
, ErrUnexpectedEOF
)
308 result
= string(buf
[0:n
])
311 if result
!= "hello" {
312 t
.Errorf("got: %q; want: %q", result
, "hello")
314 if writeErr
!= ErrClosedPipe
{
315 t
.Errorf("got: %q; want: %q", writeErr
, ErrClosedPipe
)
319 func TestPipeCloseError(t
*testing
.T
) {
320 type testError1
struct{ error
}
321 type testError2
struct{ error
}
324 r
.CloseWithError(testError1
{})
325 if _
, err
:= w
.Write(nil); err
!= (testError1
{}) {
326 t
.Errorf("Write error: got %T, want testError1", err
)
328 r
.CloseWithError(testError2
{})
329 if _
, err
:= w
.Write(nil); err
!= (testError1
{}) {
330 t
.Errorf("Write error: got %T, want testError1", err
)
334 w
.CloseWithError(testError1
{})
335 if _
, err
:= r
.Read(nil); err
!= (testError1
{}) {
336 t
.Errorf("Read error: got %T, want testError1", err
)
338 w
.CloseWithError(testError2
{})
339 if _
, err
:= r
.Read(nil); err
!= (testError1
{}) {
340 t
.Errorf("Read error: got %T, want testError1", err
)
344 func TestPipeConcurrent(t
*testing
.T
) {
346 input
= "0123456789abcdef"
351 t
.Run("Write", func(t
*testing
.T
) {
354 for i
:= 0; i
< count
; i
++ {
356 time
.Sleep(time
.Millisecond
) // Increase probability of race
357 if n
, err
:= w
.Write([]byte(input
)); n
!= len(input
) || err
!= nil {
358 t
.Errorf("Write() = (%d, %v); want (%d, nil)", n
, err
, len(input
))
363 buf
:= make([]byte, count
*len(input
))
364 for i
:= 0; i
< len(buf
); i
+= readSize
{
365 if n
, err
:= r
.Read(buf
[i
: i
+readSize
]); n
!= readSize || err
!= nil {
366 t
.Errorf("Read() = (%d, %v); want (%d, nil)", n
, err
, readSize
)
370 // Since each Write is fully gated, if multiple Read calls were needed,
371 // the contents of Write should still appear together in the output.
373 want
:= strings
.Repeat(input
, count
)
375 t
.Errorf("got: %q; want: %q", got
, want
)
379 t
.Run("Read", func(t
*testing
.T
) {
382 c
:= make(chan []byte, count
*len(input
)/readSize
)
383 for i
:= 0; i
< cap(c
); i
++ {
385 time
.Sleep(time
.Millisecond
) // Increase probability of race
386 buf
:= make([]byte, readSize
)
387 if n
, err
:= r
.Read(buf
); n
!= readSize || err
!= nil {
388 t
.Errorf("Read() = (%d, %v); want (%d, nil)", n
, err
, readSize
)
394 for i
:= 0; i
< count
; i
++ {
395 if n
, err
:= w
.Write([]byte(input
)); n
!= len(input
) || err
!= nil {
396 t
.Errorf("Write() = (%d, %v); want (%d, nil)", n
, err
, len(input
))
400 // Since each read is independent, the only guarantee about the output
401 // is that it is a permutation of the input in readSized groups.
402 got
:= make([]byte, 0, count
*len(input
))
403 for i
:= 0; i
< cap(c
); i
++ {
404 got
= append(got
, (<-c
)...)
406 got
= sortBytesInGroups(got
, readSize
)
407 want
:= bytes
.Repeat([]byte(input
), count
)
408 want
= sortBytesInGroups(want
, readSize
)
409 if string(got
) != string(want
) {
410 t
.Errorf("got: %q; want: %q", got
, want
)
415 func sortBytesInGroups(b
[]byte, n
int) []byte {
418 groups
= append(groups
, b
[:n
])
421 sort
.Slice(groups
, func(i
, j
int) bool { return bytes
.Compare(groups
[i
], groups
[j
]) < 0 })
422 return bytes
.Join(groups
, nil)