Record edge true/false value for gcov
[official-gcc.git] / libgo / go / net / net_test.go
blob76a9c8b1517cfbe77f1c0064787e74362661491e
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 //go:build !js
7 package net
9 import (
10 "errors"
11 "fmt"
12 "io"
13 "net/internal/socktest"
14 "os"
15 "runtime"
16 "testing"
17 "time"
20 func TestCloseRead(t *testing.T) {
21 switch runtime.GOOS {
22 case "plan9":
23 t.Skipf("not supported on %s", runtime.GOOS)
25 t.Parallel()
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)
33 t.Parallel()
35 ln := newLocalListener(t, network)
36 switch network {
37 case "unix", "unixpacket":
38 defer os.Remove(ln.Addr().String())
40 defer ln.Close()
42 c, err := Dial(ln.Addr().Network(), ln.Addr().String())
43 if err != nil {
44 t.Fatal(err)
46 switch network {
47 case "unix", "unixpacket":
48 defer os.Remove(c.LocalAddr().String())
50 defer c.Close()
52 switch c := c.(type) {
53 case *TCPConn:
54 err = c.CloseRead()
55 case *UnixConn:
56 err = c.CloseRead()
58 if err != nil {
59 if perr := parseCloseError(err, true); perr != nil {
60 t.Error(perr)
62 t.Fatal(err)
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)
73 func TestCloseWrite(t *testing.T) {
74 switch runtime.GOOS {
75 case "plan9":
76 t.Skipf("not supported on %s", runtime.GOOS)
79 t.Parallel()
80 deadline, _ := t.Deadline()
81 if !deadline.IsZero() {
82 // Leave 10% headroom on the deadline to report errors and clean up.
83 deadline = deadline.Add(-time.Until(deadline) / 10)
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)
92 t.Parallel()
94 handler := func(ls *localServer, ln Listener) {
95 c, err := ln.Accept()
96 if err != nil {
97 t.Error(err)
98 return
100 if !deadline.IsZero() {
101 c.SetDeadline(deadline)
103 defer c.Close()
105 var b [1]byte
106 n, err := c.Read(b[:])
107 if n != 0 || err != io.EOF {
108 t.Errorf("got (%d, %v); want (0, io.EOF)", n, err)
109 return
111 switch c := c.(type) {
112 case *TCPConn:
113 err = c.CloseWrite()
114 case *UnixConn:
115 err = c.CloseWrite()
117 if err != nil {
118 if perr := parseCloseError(err, true); perr != nil {
119 t.Error(perr)
121 t.Error(err)
122 return
124 n, err = c.Write(b[:])
125 if err == nil {
126 t.Errorf("got (%d, %v); want (any, error)", n, err)
127 return
131 ls := newLocalServer(t, network)
132 defer ls.teardown()
133 if err := ls.buildup(handler); err != nil {
134 t.Fatal(err)
137 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
138 if err != nil {
139 t.Fatal(err)
141 if !deadline.IsZero() {
142 c.SetDeadline(deadline)
144 switch network {
145 case "unix", "unixpacket":
146 defer os.Remove(c.LocalAddr().String())
148 defer c.Close()
150 switch c := c.(type) {
151 case *TCPConn:
152 err = c.CloseWrite()
153 case *UnixConn:
154 err = c.CloseWrite()
156 if err != nil {
157 if perr := parseCloseError(err, true); perr != nil {
158 t.Error(perr)
160 t.Fatal(err)
162 var b [1]byte
163 n, err := c.Read(b[:])
164 if n != 0 || err != io.EOF {
165 t.Fatalf("got (%d, %v); want (0, io.EOF)", n, err)
167 n, err = c.Write(b[:])
168 if err == nil {
169 t.Fatalf("got (%d, %v); want (any, error)", n, err)
175 func TestConnClose(t *testing.T) {
176 t.Parallel()
177 for _, network := range []string{"tcp", "unix", "unixpacket"} {
178 network := network
179 t.Run(network, func(t *testing.T) {
180 if !testableNetwork(network) {
181 t.Skipf("network %s is not testable on the current platform", network)
183 t.Parallel()
185 ln := newLocalListener(t, network)
186 switch network {
187 case "unix", "unixpacket":
188 defer os.Remove(ln.Addr().String())
190 defer ln.Close()
192 c, err := Dial(ln.Addr().Network(), ln.Addr().String())
193 if err != nil {
194 t.Fatal(err)
196 switch network {
197 case "unix", "unixpacket":
198 defer os.Remove(c.LocalAddr().String())
200 defer c.Close()
202 if err := c.Close(); err != nil {
203 if perr := parseCloseError(err, false); perr != nil {
204 t.Error(perr)
206 t.Fatal(err)
208 var b [1]byte
209 n, err := c.Read(b[:])
210 if n != 0 || err == nil {
211 t.Fatalf("got (%d, %v); want (0, error)", n, err)
217 func TestListenerClose(t *testing.T) {
218 t.Parallel()
219 for _, network := range []string{"tcp", "unix", "unixpacket"} {
220 network := network
221 t.Run(network, func(t *testing.T) {
222 if !testableNetwork(network) {
223 t.Skipf("network %s is not testable on the current platform", network)
225 t.Parallel()
227 ln := newLocalListener(t, network)
228 switch network {
229 case "unix", "unixpacket":
230 defer os.Remove(ln.Addr().String())
233 if err := ln.Close(); err != nil {
234 if perr := parseCloseError(err, false); perr != nil {
235 t.Error(perr)
237 t.Fatal(err)
239 c, err := ln.Accept()
240 if err == nil {
241 c.Close()
242 t.Fatal("should fail")
245 // Note: we cannot ensure that a subsequent Dial does not succeed, because
246 // we do not in general have any guarantee that ln.Addr is not immediately
247 // reused. (TCP sockets enter a TIME_WAIT state when closed, but that only
248 // applies to existing connections for the port — it does not prevent the
249 // port itself from being used for entirely new connections in the
250 // meantime.)
255 func TestPacketConnClose(t *testing.T) {
256 t.Parallel()
257 for _, network := range []string{"udp", "unixgram"} {
258 network := network
259 t.Run(network, func(t *testing.T) {
260 if !testableNetwork(network) {
261 t.Skipf("network %s is not testable on the current platform", network)
263 t.Parallel()
265 c := newLocalPacketListener(t, network)
266 switch network {
267 case "unixgram":
268 defer os.Remove(c.LocalAddr().String())
270 defer c.Close()
272 if err := c.Close(); err != nil {
273 if perr := parseCloseError(err, false); perr != nil {
274 t.Error(perr)
276 t.Fatal(err)
278 var b [1]byte
279 n, _, err := c.ReadFrom(b[:])
280 if n != 0 || err == nil {
281 t.Fatalf("got (%d, %v); want (0, error)", n, err)
287 func TestListenCloseListen(t *testing.T) {
288 const maxTries = 10
289 for tries := 0; tries < maxTries; tries++ {
290 ln := newLocalListener(t, "tcp")
291 addr := ln.Addr().String()
292 // TODO: This is racy. The selected address could be reused in between this
293 // Close and the subsequent Listen.
294 if err := ln.Close(); err != nil {
295 if perr := parseCloseError(err, false); perr != nil {
296 t.Error(perr)
298 t.Fatal(err)
300 ln, err := Listen("tcp", addr)
301 if err == nil {
302 // Success. (This test didn't always make it here earlier.)
303 ln.Close()
304 return
306 t.Errorf("failed on try %d/%d: %v", tries+1, maxTries, err)
308 t.Fatalf("failed to listen/close/listen on same address after %d tries", maxTries)
311 // See golang.org/issue/6163, golang.org/issue/6987.
312 func TestAcceptIgnoreAbortedConnRequest(t *testing.T) {
313 switch runtime.GOOS {
314 case "plan9":
315 t.Skipf("%s does not have full support of socktest", runtime.GOOS)
318 syserr := make(chan error)
319 go func() {
320 defer close(syserr)
321 for _, err := range abortedConnRequestErrors {
322 syserr <- err
325 sw.Set(socktest.FilterAccept, func(so *socktest.Status) (socktest.AfterFilter, error) {
326 if err, ok := <-syserr; ok {
327 return nil, err
329 return nil, nil
331 defer sw.Set(socktest.FilterAccept, nil)
333 operr := make(chan error, 1)
334 handler := func(ls *localServer, ln Listener) {
335 defer close(operr)
336 c, err := ln.Accept()
337 if err != nil {
338 if perr := parseAcceptError(err); perr != nil {
339 operr <- perr
341 operr <- err
342 return
344 c.Close()
346 ls := newLocalServer(t, "tcp")
347 defer ls.teardown()
348 if err := ls.buildup(handler); err != nil {
349 t.Fatal(err)
352 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
353 if err != nil {
354 t.Fatal(err)
356 c.Close()
358 for err := range operr {
359 t.Error(err)
363 func TestZeroByteRead(t *testing.T) {
364 t.Parallel()
365 for _, network := range []string{"tcp", "unix", "unixpacket"} {
366 network := network
367 t.Run(network, func(t *testing.T) {
368 if !testableNetwork(network) {
369 t.Skipf("network %s is not testable on the current platform", network)
371 t.Parallel()
373 ln := newLocalListener(t, network)
374 connc := make(chan Conn, 1)
375 go func() {
376 defer ln.Close()
377 c, err := ln.Accept()
378 if err != nil {
379 t.Error(err)
381 connc <- c // might be nil
383 c, err := Dial(network, ln.Addr().String())
384 if err != nil {
385 t.Fatal(err)
387 defer c.Close()
388 sc := <-connc
389 if sc == nil {
390 return
392 defer sc.Close()
394 if runtime.GOOS == "windows" {
395 // A zero byte read on Windows caused a wait for readability first.
396 // Rather than change that behavior, satisfy it in this test.
397 // See Issue 15735.
398 go io.WriteString(sc, "a")
401 n, err := c.Read(nil)
402 if n != 0 || err != nil {
403 t.Errorf("%s: zero byte client read = %v, %v; want 0, nil", network, n, err)
406 if runtime.GOOS == "windows" {
407 // Same as comment above.
408 go io.WriteString(c, "a")
410 n, err = sc.Read(nil)
411 if n != 0 || err != nil {
412 t.Errorf("%s: zero byte server read = %v, %v; want 0, nil", network, n, err)
418 // withTCPConnPair sets up a TCP connection between two peers, then
419 // runs peer1 and peer2 concurrently. withTCPConnPair returns when
420 // both have completed.
421 func withTCPConnPair(t *testing.T, peer1, peer2 func(c *TCPConn) error) {
422 ln := newLocalListener(t, "tcp")
423 defer ln.Close()
424 errc := make(chan error, 2)
425 go func() {
426 c1, err := ln.Accept()
427 if err != nil {
428 errc <- err
429 return
431 defer c1.Close()
432 errc <- peer1(c1.(*TCPConn))
434 go func() {
435 c2, err := Dial("tcp", ln.Addr().String())
436 if err != nil {
437 errc <- err
438 return
440 defer c2.Close()
441 errc <- peer2(c2.(*TCPConn))
443 for i := 0; i < 2; i++ {
444 if err := <-errc; err != nil {
445 t.Fatal(err)
450 // Tests that a blocked Read is interrupted by a concurrent SetReadDeadline
451 // modifying that Conn's read deadline to the past.
452 // See golang.org/cl/30164 which documented this. The net/http package
453 // depends on this.
454 func TestReadTimeoutUnblocksRead(t *testing.T) {
455 serverDone := make(chan struct{})
456 server := func(cs *TCPConn) error {
457 defer close(serverDone)
458 errc := make(chan error, 1)
459 go func() {
460 defer close(errc)
461 go func() {
462 // TODO: find a better way to wait
463 // until we're blocked in the cs.Read
464 // call below. Sleep is lame.
465 time.Sleep(100 * time.Millisecond)
467 // Interrupt the upcoming Read, unblocking it:
468 cs.SetReadDeadline(time.Unix(123, 0)) // time in the past
470 var buf [1]byte
471 n, err := cs.Read(buf[:1])
472 if n != 0 || err == nil {
473 errc <- fmt.Errorf("Read = %v, %v; want 0, non-nil", n, err)
476 select {
477 case err := <-errc:
478 return err
479 case <-time.After(5 * time.Second):
480 buf := make([]byte, 2<<20)
481 buf = buf[:runtime.Stack(buf, true)]
482 println("Stacks at timeout:\n", string(buf))
483 return errors.New("timeout waiting for Read to finish")
487 // Do nothing in the client. Never write. Just wait for the
488 // server's half to be done.
489 client := func(*TCPConn) error {
490 <-serverDone
491 return nil
493 withTCPConnPair(t, client, server)
496 // Issue 17695: verify that a blocked Read is woken up by a Close.
497 func TestCloseUnblocksRead(t *testing.T) {
498 t.Parallel()
499 server := func(cs *TCPConn) error {
500 // Give the client time to get stuck in a Read:
501 time.Sleep(20 * time.Millisecond)
502 cs.Close()
503 return nil
505 client := func(ss *TCPConn) error {
506 n, err := ss.Read([]byte{0})
507 if n != 0 || err != io.EOF {
508 return fmt.Errorf("Read = %v, %v; want 0, EOF", n, err)
510 return nil
512 withTCPConnPair(t, client, server)
515 // Issue 24808: verify that ECONNRESET is not temporary for read.
516 func TestNotTemporaryRead(t *testing.T) {
517 t.Parallel()
519 ln := newLocalListener(t, "tcp")
520 serverDone := make(chan struct{})
521 dialed := make(chan struct{})
522 go func() {
523 defer close(serverDone)
525 cs, err := ln.Accept()
526 if err != nil {
527 return
529 <-dialed
530 cs.(*TCPConn).SetLinger(0)
531 cs.Close()
533 ln.Close()
535 defer func() { <-serverDone }()
537 ss, err := Dial("tcp", ln.Addr().String())
538 if err != nil {
539 t.Fatal(err)
541 defer ss.Close()
542 close(dialed)
543 _, err = ss.Read([]byte{0})
544 if err == nil {
545 t.Fatal("Read succeeded unexpectedly")
546 } else if err == io.EOF {
547 // This happens on Plan 9, but for some reason (prior to CL 385314) it was
548 // accepted everywhere else too.
549 if runtime.GOOS == "plan9" {
550 return
552 // TODO: during an open development cycle, try making this a failure
553 // and see whether it causes the test to become flaky anywhere else.
554 return
556 if ne, ok := err.(Error); !ok {
557 t.Errorf("Read error does not implement net.Error: %v", err)
558 } else if ne.Temporary() {
559 t.Errorf("Read error is unexpectedly temporary: %v", err)
563 // The various errors should implement the Error interface.
564 func TestErrors(t *testing.T) {
565 var (
566 _ Error = &OpError{}
567 _ Error = &ParseError{}
568 _ Error = &AddrError{}
569 _ Error = UnknownNetworkError("")
570 _ Error = InvalidAddrError("")
571 _ Error = &timeoutError{}
572 _ Error = &DNSConfigError{}
573 _ Error = &DNSError{}
576 // ErrClosed was introduced as type error, so we can't check
577 // it using a declaration.
578 if _, ok := ErrClosed.(Error); !ok {
579 t.Fatal("ErrClosed does not implement Error")