PR tree-optimization/82929
[official-gcc.git] / libgo / go / io / pipe_test.go
blob95930e86a4ebbd134da26b5f6f663bcfdb16c306
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.
5 package io_test
7 import (
8 "fmt"
9 . "io"
10 "testing"
11 "time"
14 func checkWrite(t *testing.T, w Writer, data []byte, c chan int) {
15 n, err := w.Write(data)
16 if err != nil {
17 t.Errorf("write: %v", err)
19 if n != len(data) {
20 t.Errorf("short write: %d != %d", n, len(data))
22 c <- 0
25 // Test a single read/write pair.
26 func TestPipe1(t *testing.T) {
27 c := make(chan int)
28 r, w := Pipe()
29 var buf = make([]byte, 64)
30 go checkWrite(t, w, []byte("hello, world"), c)
31 n, err := r.Read(buf)
32 if err != nil {
33 t.Errorf("read: %v", err)
34 } else if n != 12 || string(buf[0:12]) != "hello, world" {
35 t.Errorf("bad read: got %q", buf[0:n])
37 <-c
38 r.Close()
39 w.Close()
42 func reader(t *testing.T, r Reader, c chan int) {
43 var buf = make([]byte, 64)
44 for {
45 n, err := r.Read(buf)
46 if err == EOF {
47 c <- 0
48 break
50 if err != nil {
51 t.Errorf("read: %v", err)
53 c <- n
57 // Test a sequence of read/write pairs.
58 func TestPipe2(t *testing.T) {
59 c := make(chan int)
60 r, w := Pipe()
61 go reader(t, r, c)
62 var buf = make([]byte, 64)
63 for i := 0; i < 5; i++ {
64 p := buf[0 : 5+i*10]
65 n, err := w.Write(p)
66 if n != len(p) {
67 t.Errorf("wrote %d, got %d", len(p), n)
69 if err != nil {
70 t.Errorf("write: %v", err)
72 nn := <-c
73 if nn != n {
74 t.Errorf("wrote %d, read got %d", n, nn)
77 w.Close()
78 nn := <-c
79 if nn != 0 {
80 t.Errorf("final read got %d", nn)
84 type pipeReturn struct {
85 n int
86 err error
89 // Test a large write that requires multiple reads to satisfy.
90 func writer(w WriteCloser, buf []byte, c chan pipeReturn) {
91 n, err := w.Write(buf)
92 w.Close()
93 c <- pipeReturn{n, err}
96 func TestPipe3(t *testing.T) {
97 c := make(chan pipeReturn)
98 r, w := Pipe()
99 var wdat = make([]byte, 128)
100 for i := 0; i < len(wdat); i++ {
101 wdat[i] = byte(i)
103 go writer(w, wdat, c)
104 var rdat = make([]byte, 1024)
105 tot := 0
106 for n := 1; n <= 256; n *= 2 {
107 nn, err := r.Read(rdat[tot : tot+n])
108 if err != nil && err != EOF {
109 t.Fatalf("read: %v", err)
112 // only final two reads should be short - 1 byte, then 0
113 expect := n
114 if n == 128 {
115 expect = 1
116 } else if n == 256 {
117 expect = 0
118 if err != EOF {
119 t.Fatalf("read at end: %v", err)
122 if nn != expect {
123 t.Fatalf("read %d, expected %d, got %d", n, expect, nn)
125 tot += nn
127 pr := <-c
128 if pr.n != 128 || pr.err != nil {
129 t.Fatalf("write 128: %d, %v", pr.n, pr.err)
131 if tot != 128 {
132 t.Fatalf("total read %d != 128", tot)
134 for i := 0; i < 128; i++ {
135 if rdat[i] != byte(i) {
136 t.Fatalf("rdat[%d] = %d", i, rdat[i])
141 // Test read after/before writer close.
143 type closer interface {
144 CloseWithError(error) error
145 Close() error
148 type pipeTest struct {
149 async bool
150 err error
151 closeWithError bool
154 func (p pipeTest) String() string {
155 return fmt.Sprintf("async=%v err=%v closeWithError=%v", p.async, p.err, p.closeWithError)
158 var pipeTests = []pipeTest{
159 {true, nil, false},
160 {true, nil, true},
161 {true, ErrShortWrite, true},
162 {false, nil, false},
163 {false, nil, true},
164 {false, ErrShortWrite, true},
167 func delayClose(t *testing.T, cl closer, ch chan int, tt pipeTest) {
168 time.Sleep(1 * time.Millisecond)
169 var err error
170 if tt.closeWithError {
171 err = cl.CloseWithError(tt.err)
172 } else {
173 err = cl.Close()
175 if err != nil {
176 t.Errorf("delayClose: %v", err)
178 ch <- 0
181 func TestPipeReadClose(t *testing.T) {
182 for _, tt := range pipeTests {
183 c := make(chan int, 1)
184 r, w := Pipe()
185 if tt.async {
186 go delayClose(t, w, c, tt)
187 } else {
188 delayClose(t, w, c, tt)
190 var buf = make([]byte, 64)
191 n, err := r.Read(buf)
193 want := tt.err
194 if want == nil {
195 want = EOF
197 if err != want {
198 t.Errorf("read from closed pipe: %v want %v", err, want)
200 if n != 0 {
201 t.Errorf("read on closed pipe returned %d", n)
203 if err = r.Close(); err != nil {
204 t.Errorf("r.Close: %v", err)
209 // Test close on Read side during Read.
210 func TestPipeReadClose2(t *testing.T) {
211 c := make(chan int, 1)
212 r, _ := Pipe()
213 go delayClose(t, r, c, pipeTest{})
214 n, err := r.Read(make([]byte, 64))
216 if n != 0 || err != ErrClosedPipe {
217 t.Errorf("read from closed pipe: %v, %v want %v, %v", n, err, 0, ErrClosedPipe)
221 // Test write after/before reader close.
223 func TestPipeWriteClose(t *testing.T) {
224 for _, tt := range pipeTests {
225 c := make(chan int, 1)
226 r, w := Pipe()
227 if tt.async {
228 go delayClose(t, r, c, tt)
229 } else {
230 delayClose(t, r, c, tt)
232 n, err := WriteString(w, "hello, world")
234 expect := tt.err
235 if expect == nil {
236 expect = ErrClosedPipe
238 if err != expect {
239 t.Errorf("write on closed pipe: %v want %v", err, expect)
241 if n != 0 {
242 t.Errorf("write on closed pipe returned %d", n)
244 if err = w.Close(); err != nil {
245 t.Errorf("w.Close: %v", err)
250 // Test close on Write side during Write.
251 func TestPipeWriteClose2(t *testing.T) {
252 c := make(chan int, 1)
253 _, w := Pipe()
254 go delayClose(t, w, c, pipeTest{})
255 n, err := w.Write(make([]byte, 64))
257 if n != 0 || err != ErrClosedPipe {
258 t.Errorf("write to closed pipe: %v, %v want %v, %v", n, err, 0, ErrClosedPipe)
262 func TestWriteEmpty(t *testing.T) {
263 r, w := Pipe()
264 go func() {
265 w.Write([]byte{})
266 w.Close()
268 var b [2]byte
269 ReadFull(r, b[0:2])
270 r.Close()
273 func TestWriteNil(t *testing.T) {
274 r, w := Pipe()
275 go func() {
276 w.Write(nil)
277 w.Close()
279 var b [2]byte
280 ReadFull(r, b[0:2])
281 r.Close()
284 func TestWriteAfterWriterClose(t *testing.T) {
285 r, w := Pipe()
287 done := make(chan bool)
288 var writeErr error
289 go func() {
290 _, err := w.Write([]byte("hello"))
291 if err != nil {
292 t.Errorf("got error: %q; expected none", err)
294 w.Close()
295 _, writeErr = w.Write([]byte("world"))
296 done <- true
299 buf := make([]byte, 100)
300 var result string
301 n, err := ReadFull(r, buf)
302 if err != nil && err != ErrUnexpectedEOF {
303 t.Fatalf("got: %q; want: %q", err, ErrUnexpectedEOF)
305 result = string(buf[0:n])
306 <-done
308 if result != "hello" {
309 t.Errorf("got: %q; want: %q", result, "hello")
311 if writeErr != ErrClosedPipe {
312 t.Errorf("got: %q; want: %q", writeErr, ErrClosedPipe)