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