OSDN Git Service

Add Go frontend, libgo library, and Go testsuite.
[pf3gnuchains/gcc-fork.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         "os"
11         "testing"
12         "time"
13 )
14
15 func checkWrite(t *testing.T, w Writer, data []byte, c chan int) {
16         n, err := w.Write(data)
17         if err != nil {
18                 t.Errorf("write: %v", err)
19         }
20         if n != len(data) {
21                 t.Errorf("short write: %d != %d", n, len(data))
22         }
23         c <- 0
24 }
25
26 // Test a single read/write pair.
27 func TestPipe1(t *testing.T) {
28         c := make(chan int)
29         r, w := Pipe()
30         var buf = make([]byte, 64)
31         go checkWrite(t, w, []byte("hello, world"), c)
32         n, err := r.Read(buf)
33         if err != nil {
34                 t.Errorf("read: %v", err)
35         } else if n != 12 || string(buf[0:12]) != "hello, world" {
36                 t.Errorf("bad read: got %q", buf[0:n])
37         }
38         <-c
39         r.Close()
40         w.Close()
41 }
42
43 func reader(t *testing.T, r Reader, c chan int) {
44         var buf = make([]byte, 64)
45         for {
46                 n, err := r.Read(buf)
47                 if err == os.EOF {
48                         c <- 0
49                         break
50                 }
51                 if err != nil {
52                         t.Errorf("read: %v", err)
53                 }
54                 c <- n
55         }
56 }
57
58 // Test a sequence of read/write pairs.
59 func TestPipe2(t *testing.T) {
60         c := make(chan int)
61         r, w := Pipe()
62         go reader(t, r, c)
63         var buf = make([]byte, 64)
64         for i := 0; i < 5; i++ {
65                 p := buf[0 : 5+i*10]
66                 n, err := w.Write(p)
67                 if n != len(p) {
68                         t.Errorf("wrote %d, got %d", len(p), n)
69                 }
70                 if err != nil {
71                         t.Errorf("write: %v", err)
72                 }
73                 nn := <-c
74                 if nn != n {
75                         t.Errorf("wrote %d, read got %d", n, nn)
76                 }
77         }
78         w.Close()
79         nn := <-c
80         if nn != 0 {
81                 t.Errorf("final read got %d", nn)
82         }
83 }
84
85 type pipeReturn struct {
86         n   int
87         err os.Error
88 }
89
90 // Test a large write that requires multiple reads to satisfy.
91 func writer(w WriteCloser, buf []byte, c chan pipeReturn) {
92         n, err := w.Write(buf)
93         w.Close()
94         c <- pipeReturn{n, err}
95 }
96
97 func TestPipe3(t *testing.T) {
98         c := make(chan pipeReturn)
99         r, w := Pipe()
100         var wdat = make([]byte, 128)
101         for i := 0; i < len(wdat); i++ {
102                 wdat[i] = byte(i)
103         }
104         go writer(w, wdat, c)
105         var rdat = make([]byte, 1024)
106         tot := 0
107         for n := 1; n <= 256; n *= 2 {
108                 nn, err := r.Read(rdat[tot : tot+n])
109                 if err != nil && err != os.EOF {
110                         t.Fatalf("read: %v", err)
111                 }
112
113                 // only final two reads should be short - 1 byte, then 0
114                 expect := n
115                 if n == 128 {
116                         expect = 1
117                 } else if n == 256 {
118                         expect = 0
119                         if err != os.EOF {
120                                 t.Fatalf("read at end: %v", err)
121                         }
122                 }
123                 if nn != expect {
124                         t.Fatalf("read %d, expected %d, got %d", n, expect, nn)
125                 }
126                 tot += nn
127         }
128         pr := <-c
129         if pr.n != 128 || pr.err != nil {
130                 t.Fatalf("write 128: %d, %v", pr.n, pr.err)
131         }
132         if tot != 128 {
133                 t.Fatalf("total read %d != 128", tot)
134         }
135         for i := 0; i < 128; i++ {
136                 if rdat[i] != byte(i) {
137                         t.Fatalf("rdat[%d] = %d", i, rdat[i])
138                 }
139         }
140 }
141
142 // Test read after/before writer close.
143
144 type closer interface {
145         CloseWithError(os.Error) os.Error
146         Close() os.Error
147 }
148
149 type pipeTest struct {
150         async          bool
151         err            os.Error
152         closeWithError bool
153 }
154
155 func (p pipeTest) String() string {
156         return fmt.Sprintf("async=%v err=%v closeWithError=%v", p.async, p.err, p.closeWithError)
157 }
158
159 var pipeTests = []pipeTest{
160         {true, nil, false},
161         {true, nil, true},
162         {true, ErrShortWrite, true},
163         {false, nil, false},
164         {false, nil, true},
165         {false, ErrShortWrite, true},
166 }
167
168 func delayClose(t *testing.T, cl closer, ch chan int, tt pipeTest) {
169         time.Sleep(1e6) // 1 ms
170         var err os.Error
171         if tt.closeWithError {
172                 err = cl.CloseWithError(tt.err)
173         } else {
174                 err = cl.Close()
175         }
176         if err != nil {
177                 t.Errorf("delayClose: %v", err)
178         }
179         ch <- 0
180 }
181
182 func TestPipeReadClose(t *testing.T) {
183         for _, tt := range pipeTests {
184                 c := make(chan int, 1)
185                 r, w := Pipe()
186                 if tt.async {
187                         go delayClose(t, w, c, tt)
188                 } else {
189                         delayClose(t, w, c, tt)
190                 }
191                 var buf = make([]byte, 64)
192                 n, err := r.Read(buf)
193                 <-c
194                 want := tt.err
195                 if want == nil {
196                         want = os.EOF
197                 }
198                 if err != want {
199                         t.Errorf("read from closed pipe: %v want %v", err, want)
200                 }
201                 if n != 0 {
202                         t.Errorf("read on closed pipe returned %d", n)
203                 }
204                 if err = r.Close(); err != nil {
205                         t.Errorf("r.Close: %v", err)
206                 }
207         }
208 }
209
210 // Test close on Read side during Read.
211 func TestPipeReadClose2(t *testing.T) {
212         c := make(chan int, 1)
213         r, _ := Pipe()
214         go delayClose(t, r, c, pipeTest{})
215         n, err := r.Read(make([]byte, 64))
216         <-c
217         if n != 0 || err != os.EINVAL {
218                 t.Errorf("read from closed pipe: %v, %v want %v, %v", n, err, 0, os.EINVAL)
219         }
220 }
221
222 // Test write after/before reader close.
223
224 func TestPipeWriteClose(t *testing.T) {
225         for _, tt := range pipeTests {
226                 c := make(chan int, 1)
227                 r, w := Pipe()
228                 if tt.async {
229                         go delayClose(t, r, c, tt)
230                 } else {
231                         delayClose(t, r, c, tt)
232                 }
233                 n, err := WriteString(w, "hello, world")
234                 <-c
235                 expect := tt.err
236                 if expect == nil {
237                         expect = os.EPIPE
238                 }
239                 if err != expect {
240                         t.Errorf("write on closed pipe: %v want %v", err, expect)
241                 }
242                 if n != 0 {
243                         t.Errorf("write on closed pipe returned %d", n)
244                 }
245                 if err = w.Close(); err != nil {
246                         t.Errorf("w.Close: %v", err)
247                 }
248         }
249 }
250
251 func TestWriteEmpty(t *testing.T) {
252         r, w := Pipe()
253         go func() {
254                 w.Write([]byte{})
255                 w.Close()
256         }()
257         var b [2]byte
258         ReadFull(r, b[0:2])
259         r.Close()
260 }
261
262 func TestWriteNil(t *testing.T) {
263         r, w := Pipe()
264         go func() {
265                 w.Write(nil)
266                 w.Close()
267         }()
268         var b [2]byte
269         ReadFull(r, b[0:2])
270         r.Close()
271 }