Source file
src/net/sendfile_test.go
Documentation: net
1
2
3
4
5
6
7
8 package net
9
10 import (
11 "bytes"
12 "crypto/sha256"
13 "encoding/hex"
14 "errors"
15 "fmt"
16 "io"
17 "os"
18 "runtime"
19 "sync"
20 "testing"
21 "time"
22 )
23
24 const (
25 newton = "../testdata/Isaac.Newton-Opticks.txt"
26 newtonLen = 567198
27 newtonSHA256 = "d4a9ac22462b35e7821a4f2706c211093da678620a8f9997989ee7cf8d507bbd"
28 )
29
30 func TestSendfile(t *testing.T) {
31 ln, err := newLocalListener("tcp")
32 if err != nil {
33 t.Fatal(err)
34 }
35 defer ln.Close()
36
37 errc := make(chan error, 1)
38 go func(ln Listener) {
39
40 conn, err := ln.Accept()
41 if err != nil {
42 errc <- err
43 close(errc)
44 return
45 }
46
47 go func() {
48 defer close(errc)
49 defer conn.Close()
50
51 f, err := os.Open(newton)
52 if err != nil {
53 errc <- err
54 return
55 }
56 defer f.Close()
57
58
59
60 sbytes, err := io.Copy(conn, f)
61 if err != nil {
62 errc <- err
63 return
64 }
65
66 if sbytes != newtonLen {
67 errc <- fmt.Errorf("sent %d bytes; expected %d", sbytes, newtonLen)
68 return
69 }
70 }()
71 }(ln)
72
73
74
75 c, err := Dial("tcp", ln.Addr().String())
76 if err != nil {
77 t.Fatal(err)
78 }
79 defer c.Close()
80
81 h := sha256.New()
82 rbytes, err := io.Copy(h, c)
83 if err != nil {
84 t.Error(err)
85 }
86
87 if rbytes != newtonLen {
88 t.Errorf("received %d bytes; expected %d", rbytes, newtonLen)
89 }
90
91 if res := hex.EncodeToString(h.Sum(nil)); res != newtonSHA256 {
92 t.Error("retrieved data hash did not match")
93 }
94
95 for err := range errc {
96 t.Error(err)
97 }
98 }
99
100 func TestSendfileParts(t *testing.T) {
101 ln, err := newLocalListener("tcp")
102 if err != nil {
103 t.Fatal(err)
104 }
105 defer ln.Close()
106
107 errc := make(chan error, 1)
108 go func(ln Listener) {
109
110 conn, err := ln.Accept()
111 if err != nil {
112 errc <- err
113 close(errc)
114 return
115 }
116
117 go func() {
118 defer close(errc)
119 defer conn.Close()
120
121 f, err := os.Open(newton)
122 if err != nil {
123 errc <- err
124 return
125 }
126 defer f.Close()
127
128 for i := 0; i < 3; i++ {
129
130
131 _, err = io.CopyN(conn, f, 3)
132 if err != nil {
133 errc <- err
134 return
135 }
136 }
137 }()
138 }(ln)
139
140 c, err := Dial("tcp", ln.Addr().String())
141 if err != nil {
142 t.Fatal(err)
143 }
144 defer c.Close()
145
146 buf := new(bytes.Buffer)
147 buf.ReadFrom(c)
148
149 if want, have := "Produced ", buf.String(); have != want {
150 t.Errorf("unexpected server reply %q, want %q", have, want)
151 }
152
153 for err := range errc {
154 t.Error(err)
155 }
156 }
157
158 func TestSendfileSeeked(t *testing.T) {
159 ln, err := newLocalListener("tcp")
160 if err != nil {
161 t.Fatal(err)
162 }
163 defer ln.Close()
164
165 const seekTo = 65 << 10
166 const sendSize = 10 << 10
167
168 errc := make(chan error, 1)
169 go func(ln Listener) {
170
171 conn, err := ln.Accept()
172 if err != nil {
173 errc <- err
174 close(errc)
175 return
176 }
177
178 go func() {
179 defer close(errc)
180 defer conn.Close()
181
182 f, err := os.Open(newton)
183 if err != nil {
184 errc <- err
185 return
186 }
187 defer f.Close()
188 if _, err := f.Seek(seekTo, os.SEEK_SET); err != nil {
189 errc <- err
190 return
191 }
192
193 _, err = io.CopyN(conn, f, sendSize)
194 if err != nil {
195 errc <- err
196 return
197 }
198 }()
199 }(ln)
200
201 c, err := Dial("tcp", ln.Addr().String())
202 if err != nil {
203 t.Fatal(err)
204 }
205 defer c.Close()
206
207 buf := new(bytes.Buffer)
208 buf.ReadFrom(c)
209
210 if buf.Len() != sendSize {
211 t.Errorf("Got %d bytes; want %d", buf.Len(), sendSize)
212 }
213
214 for err := range errc {
215 t.Error(err)
216 }
217 }
218
219
220 func TestSendfilePipe(t *testing.T) {
221 switch runtime.GOOS {
222 case "plan9", "windows":
223
224 t.Skipf("skipping on %s", runtime.GOOS)
225 }
226
227 t.Parallel()
228
229 ln, err := newLocalListener("tcp")
230 if err != nil {
231 t.Fatal(err)
232 }
233 defer ln.Close()
234
235 r, w, err := os.Pipe()
236 if err != nil {
237 t.Fatal(err)
238 }
239 defer w.Close()
240 defer r.Close()
241
242 copied := make(chan bool)
243
244 var wg sync.WaitGroup
245 wg.Add(1)
246 go func() {
247
248
249 defer wg.Done()
250 conn, err := ln.Accept()
251 if err != nil {
252 t.Error(err)
253 return
254 }
255 defer conn.Close()
256 _, err = io.CopyN(conn, r, 1)
257 if err != nil {
258 t.Error(err)
259 return
260 }
261
262 close(copied)
263 }()
264
265 wg.Add(1)
266 go func() {
267
268 defer wg.Done()
269 _, err := w.Write([]byte{'a'})
270 if err != nil {
271 t.Error(err)
272 }
273 }()
274
275 wg.Add(1)
276 go func() {
277
278
279 defer wg.Done()
280 conn, err := Dial("tcp", ln.Addr().String())
281 if err != nil {
282 t.Error(err)
283 return
284 }
285 defer conn.Close()
286 io.Copy(io.Discard, conn)
287 }()
288
289
290
291 <-copied
292
293
294 if err := r.SetDeadline(time.Now().Add(time.Microsecond)); err != nil {
295 t.Fatal(err)
296 }
297
298 wg.Add(1)
299 go func() {
300
301
302 defer wg.Done()
303 time.Sleep(50 * time.Millisecond)
304 w.Write([]byte{'b'})
305 }()
306
307
308
309 _, err = r.Read(make([]byte, 1))
310 if err == nil {
311 t.Error("Read did not time out")
312 } else if !os.IsTimeout(err) {
313 t.Errorf("got error %v, expected a time out", err)
314 }
315
316 wg.Wait()
317 }
318
319
320 func TestSendfileOnWriteTimeoutExceeded(t *testing.T) {
321 ln, err := newLocalListener("tcp")
322 if err != nil {
323 t.Fatal(err)
324 }
325 defer ln.Close()
326
327 errc := make(chan error, 1)
328 go func(ln Listener) (retErr error) {
329 defer func() {
330 errc <- retErr
331 close(errc)
332 }()
333
334 conn, err := ln.Accept()
335 if err != nil {
336 return err
337 }
338 defer conn.Close()
339
340
341
342 if err := conn.SetWriteDeadline(time.Now().Add(-1 * time.Hour)); err != nil {
343 return err
344 }
345
346 f, err := os.Open(newton)
347 if err != nil {
348 return err
349 }
350 defer f.Close()
351
352 _, err = io.Copy(conn, f)
353 if errors.Is(err, os.ErrDeadlineExceeded) {
354 return nil
355 }
356
357 if err == nil {
358 err = fmt.Errorf("expected ErrDeadlineExceeded, but got nil")
359 }
360 return err
361 }(ln)
362
363 conn, err := Dial("tcp", ln.Addr().String())
364 if err != nil {
365 t.Fatal(err)
366 }
367 defer conn.Close()
368
369 n, err := io.Copy(io.Discard, conn)
370 if err != nil {
371 t.Fatalf("expected nil error, but got %v", err)
372 }
373 if n != 0 {
374 t.Fatalf("expected receive zero, but got %d byte(s)", n)
375 }
376
377 if err := <-errc; err != nil {
378 t.Fatal(err)
379 }
380 }
381
View as plain text