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