Imported Upstream version 4.7.3
[platform/upstream/gcc48.git] / libgo / go / io / pipe_test.go
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.
4
5 package io_test
6
7 import (
8         "fmt"
9         . "io"
10         "testing"
11         "time"
12 )
13
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)
18         }
19         if n != len(data) {
20                 t.Errorf("short write: %d != %d", n, len(data))
21         }
22         c <- 0
23 }
24
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])
36         }
37         <-c
38         r.Close()
39         w.Close()
40 }
41
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
49                 }
50                 if err != nil {
51                         t.Errorf("read: %v", err)
52                 }
53                 c <- n
54         }
55 }
56
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)
68                 }
69                 if err != nil {
70                         t.Errorf("write: %v", err)
71                 }
72                 nn := <-c
73                 if nn != n {
74                         t.Errorf("wrote %d, read got %d", n, nn)
75                 }
76         }
77         w.Close()
78         nn := <-c
79         if nn != 0 {
80                 t.Errorf("final read got %d", nn)
81         }
82 }
83
84 type pipeReturn struct {
85         n   int
86         err error
87 }
88
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}
94 }
95
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)
102         }
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)
110                 }
111
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)
120                         }
121                 }
122                 if nn != expect {
123                         t.Fatalf("read %d, expected %d, got %d", n, expect, nn)
124                 }
125                 tot += nn
126         }
127         pr := <-c
128         if pr.n != 128 || pr.err != nil {
129                 t.Fatalf("write 128: %d, %v", pr.n, pr.err)
130         }
131         if tot != 128 {
132                 t.Fatalf("total read %d != 128", tot)
133         }
134         for i := 0; i < 128; i++ {
135                 if rdat[i] != byte(i) {
136                         t.Fatalf("rdat[%d] = %d", i, rdat[i])
137                 }
138         }
139 }
140
141 // Test read after/before writer close.
142
143 type closer interface {
144         CloseWithError(error) error
145         Close() error
146 }
147
148 type pipeTest struct {
149         async          bool
150         err            error
151         closeWithError bool
152 }
153
154 func (p pipeTest) String() string {
155         return fmt.Sprintf("async=%v err=%v closeWithError=%v", p.async, p.err, p.closeWithError)
156 }
157
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},
165 }
166
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()
174         }
175         if err != nil {
176                 t.Errorf("delayClose: %v", err)
177         }
178         ch <- 0
179 }
180
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)
189                 }
190                 var buf = make([]byte, 64)
191                 n, err := r.Read(buf)
192                 <-c
193                 want := tt.err
194                 if want == nil {
195                         want = EOF
196                 }
197                 if err != want {
198                         t.Errorf("read from closed pipe: %v want %v", err, want)
199                 }
200                 if n != 0 {
201                         t.Errorf("read on closed pipe returned %d", n)
202                 }
203                 if err = r.Close(); err != nil {
204                         t.Errorf("r.Close: %v", err)
205                 }
206         }
207 }
208
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))
215         <-c
216         if n != 0 || err != ErrClosedPipe {
217                 t.Errorf("read from closed pipe: %v, %v want %v, %v", n, err, 0, ErrClosedPipe)
218         }
219 }
220
221 // Test write after/before reader close.
222
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)
231                 }
232                 n, err := WriteString(w, "hello, world")
233                 <-c
234                 expect := tt.err
235                 if expect == nil {
236                         expect = ErrClosedPipe
237                 }
238                 if err != expect {
239                         t.Errorf("write on closed pipe: %v want %v", err, expect)
240                 }
241                 if n != 0 {
242                         t.Errorf("write on closed pipe returned %d", n)
243                 }
244                 if err = w.Close(); err != nil {
245                         t.Errorf("w.Close: %v", err)
246                 }
247         }
248 }
249
250 func TestWriteEmpty(t *testing.T) {
251         r, w := Pipe()
252         go func() {
253                 w.Write([]byte{})
254                 w.Close()
255         }()
256         var b [2]byte
257         ReadFull(r, b[0:2])
258         r.Close()
259 }
260
261 func TestWriteNil(t *testing.T) {
262         r, w := Pipe()
263         go func() {
264                 w.Write(nil)
265                 w.Close()
266         }()
267         var b [2]byte
268         ReadFull(r, b[0:2])
269         r.Close()
270 }