Source file
src/net/net_test.go
1
2
3
4
5
6
7 package net
8
9 import (
10 "errors"
11 "fmt"
12 "io"
13 "net/internal/socktest"
14 "os"
15 "runtime"
16 "testing"
17 "time"
18 )
19
20 func TestCloseRead(t *testing.T) {
21 switch runtime.GOOS {
22 case "plan9":
23 t.Skipf("not supported on %s", runtime.GOOS)
24 }
25 t.Parallel()
26
27 for _, network := range []string{"tcp", "unix", "unixpacket"} {
28 network := network
29 t.Run(network, func(t *testing.T) {
30 if !testableNetwork(network) {
31 t.Skipf("network %s is not testable on the current platform", network)
32 }
33 t.Parallel()
34
35 ln := newLocalListener(t, network)
36 switch network {
37 case "unix", "unixpacket":
38 defer os.Remove(ln.Addr().String())
39 }
40 defer ln.Close()
41
42 c, err := Dial(ln.Addr().Network(), ln.Addr().String())
43 if err != nil {
44 t.Fatal(err)
45 }
46 switch network {
47 case "unix", "unixpacket":
48 defer os.Remove(c.LocalAddr().String())
49 }
50 defer c.Close()
51
52 switch c := c.(type) {
53 case *TCPConn:
54 err = c.CloseRead()
55 case *UnixConn:
56 err = c.CloseRead()
57 }
58 if err != nil {
59 if perr := parseCloseError(err, true); perr != nil {
60 t.Error(perr)
61 }
62 t.Fatal(err)
63 }
64 var b [1]byte
65 n, err := c.Read(b[:])
66 if n != 0 || err == nil {
67 t.Fatalf("got (%d, %v); want (0, error)", n, err)
68 }
69 })
70 }
71 }
72
73 func TestCloseWrite(t *testing.T) {
74 switch runtime.GOOS {
75 case "plan9":
76 t.Skipf("not supported on %s", runtime.GOOS)
77 }
78
79 t.Parallel()
80 deadline, _ := t.Deadline()
81 if !deadline.IsZero() {
82
83 deadline = deadline.Add(-time.Until(deadline) / 10)
84 }
85
86 for _, network := range []string{"tcp", "unix", "unixpacket"} {
87 network := network
88 t.Run(network, func(t *testing.T) {
89 if !testableNetwork(network) {
90 t.Skipf("network %s is not testable on the current platform", network)
91 }
92 t.Parallel()
93
94 handler := func(ls *localServer, ln Listener) {
95 c, err := ln.Accept()
96 if err != nil {
97 t.Error(err)
98 return
99 }
100 if !deadline.IsZero() {
101 c.SetDeadline(deadline)
102 }
103 defer c.Close()
104
105 var b [1]byte
106 n, err := c.Read(b[:])
107 if n != 0 || err != io.EOF {
108 t.Errorf("got (%d, %v); want (0, io.EOF)", n, err)
109 return
110 }
111 switch c := c.(type) {
112 case *TCPConn:
113 err = c.CloseWrite()
114 case *UnixConn:
115 err = c.CloseWrite()
116 }
117 if err != nil {
118 if perr := parseCloseError(err, true); perr != nil {
119 t.Error(perr)
120 }
121 t.Error(err)
122 return
123 }
124 n, err = c.Write(b[:])
125 if err == nil {
126 t.Errorf("got (%d, %v); want (any, error)", n, err)
127 return
128 }
129 }
130
131 ls := newLocalServer(t, network)
132 defer ls.teardown()
133 if err := ls.buildup(handler); err != nil {
134 t.Fatal(err)
135 }
136
137 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
138 if err != nil {
139 t.Fatal(err)
140 }
141 if !deadline.IsZero() {
142 c.SetDeadline(deadline)
143 }
144 switch network {
145 case "unix", "unixpacket":
146 defer os.Remove(c.LocalAddr().String())
147 }
148 defer c.Close()
149
150 switch c := c.(type) {
151 case *TCPConn:
152 err = c.CloseWrite()
153 case *UnixConn:
154 err = c.CloseWrite()
155 }
156 if err != nil {
157 if perr := parseCloseError(err, true); perr != nil {
158 t.Error(perr)
159 }
160 t.Fatal(err)
161 }
162 var b [1]byte
163 n, err := c.Read(b[:])
164 if n != 0 || err != io.EOF {
165 t.Fatalf("got (%d, %v); want (0, io.EOF)", n, err)
166 }
167 n, err = c.Write(b[:])
168 if err == nil {
169 t.Fatalf("got (%d, %v); want (any, error)", n, err)
170 }
171 })
172 }
173 }
174
175 func TestConnClose(t *testing.T) {
176 t.Parallel()
177 for _, network := range []string{"tcp", "unix", "unixpacket"} {
178 network := network
179 t.Run(network, func(t *testing.T) {
180 if !testableNetwork(network) {
181 t.Skipf("network %s is not testable on the current platform", network)
182 }
183 t.Parallel()
184
185 ln := newLocalListener(t, network)
186 switch network {
187 case "unix", "unixpacket":
188 defer os.Remove(ln.Addr().String())
189 }
190 defer ln.Close()
191
192 c, err := Dial(ln.Addr().Network(), ln.Addr().String())
193 if err != nil {
194 t.Fatal(err)
195 }
196 switch network {
197 case "unix", "unixpacket":
198 defer os.Remove(c.LocalAddr().String())
199 }
200 defer c.Close()
201
202 if err := c.Close(); err != nil {
203 if perr := parseCloseError(err, false); perr != nil {
204 t.Error(perr)
205 }
206 t.Fatal(err)
207 }
208 var b [1]byte
209 n, err := c.Read(b[:])
210 if n != 0 || err == nil {
211 t.Fatalf("got (%d, %v); want (0, error)", n, err)
212 }
213 })
214 }
215 }
216
217 func TestListenerClose(t *testing.T) {
218 t.Parallel()
219 for _, network := range []string{"tcp", "unix", "unixpacket"} {
220 network := network
221 t.Run(network, func(t *testing.T) {
222 if !testableNetwork(network) {
223 t.Skipf("network %s is not testable on the current platform", network)
224 }
225 t.Parallel()
226
227 ln := newLocalListener(t, network)
228 switch network {
229 case "unix", "unixpacket":
230 defer os.Remove(ln.Addr().String())
231 }
232
233 if err := ln.Close(); err != nil {
234 if perr := parseCloseError(err, false); perr != nil {
235 t.Error(perr)
236 }
237 t.Fatal(err)
238 }
239 c, err := ln.Accept()
240 if err == nil {
241 c.Close()
242 t.Fatal("should fail")
243 }
244
245
246
247
248
249
250
251 })
252 }
253 }
254
255 func TestPacketConnClose(t *testing.T) {
256 t.Parallel()
257 for _, network := range []string{"udp", "unixgram"} {
258 network := network
259 t.Run(network, func(t *testing.T) {
260 if !testableNetwork(network) {
261 t.Skipf("network %s is not testable on the current platform", network)
262 }
263 t.Parallel()
264
265 c := newLocalPacketListener(t, network)
266 switch network {
267 case "unixgram":
268 defer os.Remove(c.LocalAddr().String())
269 }
270 defer c.Close()
271
272 if err := c.Close(); err != nil {
273 if perr := parseCloseError(err, false); perr != nil {
274 t.Error(perr)
275 }
276 t.Fatal(err)
277 }
278 var b [1]byte
279 n, _, err := c.ReadFrom(b[:])
280 if n != 0 || err == nil {
281 t.Fatalf("got (%d, %v); want (0, error)", n, err)
282 }
283 })
284 }
285 }
286
287 func TestListenCloseListen(t *testing.T) {
288 const maxTries = 10
289 for tries := 0; tries < maxTries; tries++ {
290 ln := newLocalListener(t, "tcp")
291 addr := ln.Addr().String()
292
293
294 if err := ln.Close(); err != nil {
295 if perr := parseCloseError(err, false); perr != nil {
296 t.Error(perr)
297 }
298 t.Fatal(err)
299 }
300 ln, err := Listen("tcp", addr)
301 if err == nil {
302
303 ln.Close()
304 return
305 }
306 t.Errorf("failed on try %d/%d: %v", tries+1, maxTries, err)
307 }
308 t.Fatalf("failed to listen/close/listen on same address after %d tries", maxTries)
309 }
310
311
312 func TestAcceptIgnoreAbortedConnRequest(t *testing.T) {
313 switch runtime.GOOS {
314 case "plan9":
315 t.Skipf("%s does not have full support of socktest", runtime.GOOS)
316 }
317
318 syserr := make(chan error)
319 go func() {
320 defer close(syserr)
321 for _, err := range abortedConnRequestErrors {
322 syserr <- err
323 }
324 }()
325 sw.Set(socktest.FilterAccept, func(so *socktest.Status) (socktest.AfterFilter, error) {
326 if err, ok := <-syserr; ok {
327 return nil, err
328 }
329 return nil, nil
330 })
331 defer sw.Set(socktest.FilterAccept, nil)
332
333 operr := make(chan error, 1)
334 handler := func(ls *localServer, ln Listener) {
335 defer close(operr)
336 c, err := ln.Accept()
337 if err != nil {
338 if perr := parseAcceptError(err); perr != nil {
339 operr <- perr
340 }
341 operr <- err
342 return
343 }
344 c.Close()
345 }
346 ls := newLocalServer(t, "tcp")
347 defer ls.teardown()
348 if err := ls.buildup(handler); err != nil {
349 t.Fatal(err)
350 }
351
352 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
353 if err != nil {
354 t.Fatal(err)
355 }
356 c.Close()
357
358 for err := range operr {
359 t.Error(err)
360 }
361 }
362
363 func TestZeroByteRead(t *testing.T) {
364 t.Parallel()
365 for _, network := range []string{"tcp", "unix", "unixpacket"} {
366 network := network
367 t.Run(network, func(t *testing.T) {
368 if !testableNetwork(network) {
369 t.Skipf("network %s is not testable on the current platform", network)
370 }
371 t.Parallel()
372
373 ln := newLocalListener(t, network)
374 connc := make(chan Conn, 1)
375 go func() {
376 defer ln.Close()
377 c, err := ln.Accept()
378 if err != nil {
379 t.Error(err)
380 }
381 connc <- c
382 }()
383 c, err := Dial(network, ln.Addr().String())
384 if err != nil {
385 t.Fatal(err)
386 }
387 defer c.Close()
388 sc := <-connc
389 if sc == nil {
390 return
391 }
392 defer sc.Close()
393
394 if runtime.GOOS == "windows" {
395
396
397
398 go io.WriteString(sc, "a")
399 }
400
401 n, err := c.Read(nil)
402 if n != 0 || err != nil {
403 t.Errorf("%s: zero byte client read = %v, %v; want 0, nil", network, n, err)
404 }
405
406 if runtime.GOOS == "windows" {
407
408 go io.WriteString(c, "a")
409 }
410 n, err = sc.Read(nil)
411 if n != 0 || err != nil {
412 t.Errorf("%s: zero byte server read = %v, %v; want 0, nil", network, n, err)
413 }
414 })
415 }
416 }
417
418
419
420
421 func withTCPConnPair(t *testing.T, peer1, peer2 func(c *TCPConn) error) {
422 ln := newLocalListener(t, "tcp")
423 defer ln.Close()
424 errc := make(chan error, 2)
425 go func() {
426 c1, err := ln.Accept()
427 if err != nil {
428 errc <- err
429 return
430 }
431 defer c1.Close()
432 errc <- peer1(c1.(*TCPConn))
433 }()
434 go func() {
435 c2, err := Dial("tcp", ln.Addr().String())
436 if err != nil {
437 errc <- err
438 return
439 }
440 defer c2.Close()
441 errc <- peer2(c2.(*TCPConn))
442 }()
443 for i := 0; i < 2; i++ {
444 if err := <-errc; err != nil {
445 t.Fatal(err)
446 }
447 }
448 }
449
450
451
452
453
454 func TestReadTimeoutUnblocksRead(t *testing.T) {
455 serverDone := make(chan struct{})
456 server := func(cs *TCPConn) error {
457 defer close(serverDone)
458 errc := make(chan error, 1)
459 go func() {
460 defer close(errc)
461 go func() {
462
463
464
465 time.Sleep(100 * time.Millisecond)
466
467
468 cs.SetReadDeadline(time.Unix(123, 0))
469 }()
470 var buf [1]byte
471 n, err := cs.Read(buf[:1])
472 if n != 0 || err == nil {
473 errc <- fmt.Errorf("Read = %v, %v; want 0, non-nil", n, err)
474 }
475 }()
476 select {
477 case err := <-errc:
478 return err
479 case <-time.After(5 * time.Second):
480 buf := make([]byte, 2<<20)
481 buf = buf[:runtime.Stack(buf, true)]
482 println("Stacks at timeout:\n", string(buf))
483 return errors.New("timeout waiting for Read to finish")
484 }
485
486 }
487
488
489 client := func(*TCPConn) error {
490 <-serverDone
491 return nil
492 }
493 withTCPConnPair(t, client, server)
494 }
495
496
497 func TestCloseUnblocksRead(t *testing.T) {
498 t.Parallel()
499 server := func(cs *TCPConn) error {
500
501 time.Sleep(20 * time.Millisecond)
502 cs.Close()
503 return nil
504 }
505 client := func(ss *TCPConn) error {
506 n, err := ss.Read([]byte{0})
507 if n != 0 || err != io.EOF {
508 return fmt.Errorf("Read = %v, %v; want 0, EOF", n, err)
509 }
510 return nil
511 }
512 withTCPConnPair(t, client, server)
513 }
514
515
516 func TestNotTemporaryRead(t *testing.T) {
517 t.Parallel()
518
519 ln := newLocalListener(t, "tcp")
520 serverDone := make(chan struct{})
521 dialed := make(chan struct{})
522 go func() {
523 defer close(serverDone)
524
525 cs, err := ln.Accept()
526 if err != nil {
527 return
528 }
529 <-dialed
530 cs.(*TCPConn).SetLinger(0)
531 cs.Close()
532
533 ln.Close()
534 }()
535 defer func() { <-serverDone }()
536
537 ss, err := Dial("tcp", ln.Addr().String())
538 if err != nil {
539 t.Fatal(err)
540 }
541 defer ss.Close()
542 close(dialed)
543 _, err = ss.Read([]byte{0})
544 if err == nil {
545 t.Fatal("Read succeeded unexpectedly")
546 } else if err == io.EOF {
547
548
549 if runtime.GOOS == "plan9" {
550 return
551 }
552
553
554 return
555 }
556 if ne, ok := err.(Error); !ok {
557 t.Errorf("Read error does not implement net.Error: %v", err)
558 } else if ne.Temporary() {
559 t.Errorf("Read error is unexpectedly temporary: %v", err)
560 }
561 }
562
563
564 func TestErrors(t *testing.T) {
565 var (
566 _ Error = &OpError{}
567 _ Error = &ParseError{}
568 _ Error = &AddrError{}
569 _ Error = UnknownNetworkError("")
570 _ Error = InvalidAddrError("")
571 _ Error = &timeoutError{}
572 _ Error = &DNSConfigError{}
573 _ Error = &DNSError{}
574 )
575
576
577
578 if _, ok := ErrClosed.(Error); !ok {
579 t.Fatal("ErrClosed does not implement Error")
580 }
581 }
582
View as plain text