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