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