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