libgo: update to Go 1.11
[official-gcc.git] / libgo / go / net / net_test.go
blob692f269e0c29b87af044b62afad6e285d1cf93d8
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 // +build !js
7 package net
9 import (
10 "errors"
11 "fmt"
12 "internal/testenv"
13 "io"
14 "net/internal/socktest"
15 "os"
16 "runtime"
17 "testing"
18 "time"
21 func TestCloseRead(t *testing.T) {
22 switch runtime.GOOS {
23 case "plan9":
24 t.Skipf("not supported on %s", runtime.GOOS)
27 for _, network := range []string{"tcp", "unix", "unixpacket"} {
28 if !testableNetwork(network) {
29 t.Logf("skipping %s test", network)
30 continue
33 ln, err := newLocalListener(network)
34 if err != nil {
35 t.Fatal(err)
37 switch network {
38 case "unix", "unixpacket":
39 defer os.Remove(ln.Addr().String())
41 defer ln.Close()
43 c, err := Dial(ln.Addr().Network(), ln.Addr().String())
44 if err != nil {
45 t.Fatal(err)
47 switch network {
48 case "unix", "unixpacket":
49 defer os.Remove(c.LocalAddr().String())
51 defer c.Close()
53 switch c := c.(type) {
54 case *TCPConn:
55 err = c.CloseRead()
56 case *UnixConn:
57 err = c.CloseRead()
59 if err != nil {
60 if perr := parseCloseError(err, true); perr != nil {
61 t.Error(perr)
63 t.Fatal(err)
65 var b [1]byte
66 n, err := c.Read(b[:])
67 if n != 0 || err == nil {
68 t.Fatalf("got (%d, %v); want (0, error)", n, err)
73 func TestCloseWrite(t *testing.T) {
74 switch runtime.GOOS {
75 case "nacl", "plan9":
76 t.Skipf("not supported on %s", runtime.GOOS)
79 handler := func(ls *localServer, ln Listener) {
80 c, err := ln.Accept()
81 if err != nil {
82 t.Error(err)
83 return
85 defer c.Close()
87 var b [1]byte
88 n, err := c.Read(b[:])
89 if n != 0 || err != io.EOF {
90 t.Errorf("got (%d, %v); want (0, io.EOF)", n, err)
91 return
93 switch c := c.(type) {
94 case *TCPConn:
95 err = c.CloseWrite()
96 case *UnixConn:
97 err = c.CloseWrite()
99 if err != nil {
100 if perr := parseCloseError(err, true); perr != nil {
101 t.Error(perr)
103 t.Error(err)
104 return
106 n, err = c.Write(b[:])
107 if err == nil {
108 t.Errorf("got (%d, %v); want (any, error)", n, err)
109 return
113 for _, network := range []string{"tcp", "unix", "unixpacket"} {
114 if !testableNetwork(network) {
115 t.Logf("skipping %s test", network)
116 continue
119 ls, err := newLocalServer(network)
120 if err != nil {
121 t.Fatal(err)
123 defer ls.teardown()
124 if err := ls.buildup(handler); err != nil {
125 t.Fatal(err)
128 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
129 if err != nil {
130 t.Fatal(err)
132 switch network {
133 case "unix", "unixpacket":
134 defer os.Remove(c.LocalAddr().String())
136 defer c.Close()
138 switch c := c.(type) {
139 case *TCPConn:
140 err = c.CloseWrite()
141 case *UnixConn:
142 err = c.CloseWrite()
144 if err != nil {
145 if perr := parseCloseError(err, true); perr != nil {
146 t.Error(perr)
148 t.Fatal(err)
150 var b [1]byte
151 n, err := c.Read(b[:])
152 if n != 0 || err != io.EOF {
153 t.Fatalf("got (%d, %v); want (0, io.EOF)", n, err)
155 n, err = c.Write(b[:])
156 if err == nil {
157 t.Fatalf("got (%d, %v); want (any, error)", n, err)
162 func TestConnClose(t *testing.T) {
163 for _, network := range []string{"tcp", "unix", "unixpacket"} {
164 if !testableNetwork(network) {
165 t.Logf("skipping %s test", network)
166 continue
169 ln, err := newLocalListener(network)
170 if err != nil {
171 t.Fatal(err)
173 switch network {
174 case "unix", "unixpacket":
175 defer os.Remove(ln.Addr().String())
177 defer ln.Close()
179 c, err := Dial(ln.Addr().Network(), ln.Addr().String())
180 if err != nil {
181 t.Fatal(err)
183 switch network {
184 case "unix", "unixpacket":
185 defer os.Remove(c.LocalAddr().String())
187 defer c.Close()
189 if err := c.Close(); err != nil {
190 if perr := parseCloseError(err, false); perr != nil {
191 t.Error(perr)
193 t.Fatal(err)
195 var b [1]byte
196 n, err := c.Read(b[:])
197 if n != 0 || err == nil {
198 t.Fatalf("got (%d, %v); want (0, error)", n, err)
203 func TestListenerClose(t *testing.T) {
204 for _, network := range []string{"tcp", "unix", "unixpacket"} {
205 if !testableNetwork(network) {
206 t.Logf("skipping %s test", network)
207 continue
210 ln, err := newLocalListener(network)
211 if err != nil {
212 t.Fatal(err)
214 switch network {
215 case "unix", "unixpacket":
216 defer os.Remove(ln.Addr().String())
219 dst := ln.Addr().String()
220 if err := ln.Close(); err != nil {
221 if perr := parseCloseError(err, false); perr != nil {
222 t.Error(perr)
224 t.Fatal(err)
226 c, err := ln.Accept()
227 if err == nil {
228 c.Close()
229 t.Fatal("should fail")
232 if network == "tcp" {
233 // We will have two TCP FSMs inside the
234 // kernel here. There's no guarantee that a
235 // signal comes from the far end FSM will be
236 // delivered immediately to the near end FSM,
237 // especially on the platforms that allow
238 // multiple consumer threads to pull pending
239 // established connections at the same time by
240 // enabling SO_REUSEPORT option such as Linux,
241 // DragonFly BSD. So we need to give some time
242 // quantum to the kernel.
244 // Note that net.inet.tcp.reuseport_ext=1 by
245 // default on DragonFly BSD.
246 time.Sleep(time.Millisecond)
248 cc, err := Dial("tcp", dst)
249 if err == nil {
250 t.Error("Dial to closed TCP listener succeeded.")
251 cc.Close()
257 func TestPacketConnClose(t *testing.T) {
258 for _, network := range []string{"udp", "unixgram"} {
259 if !testableNetwork(network) {
260 t.Logf("skipping %s test", network)
261 continue
264 c, err := newLocalPacketListener(network)
265 if err != nil {
266 t.Fatal(err)
268 switch network {
269 case "unixgram":
270 defer os.Remove(c.LocalAddr().String())
272 defer c.Close()
274 if err := c.Close(); err != nil {
275 if perr := parseCloseError(err, false); perr != nil {
276 t.Error(perr)
278 t.Fatal(err)
280 var b [1]byte
281 n, _, err := c.ReadFrom(b[:])
282 if n != 0 || err == nil {
283 t.Fatalf("got (%d, %v); want (0, error)", n, err)
288 // nacl was previous failing to reuse an address.
289 func TestListenCloseListen(t *testing.T) {
290 const maxTries = 10
291 for tries := 0; tries < maxTries; tries++ {
292 ln, err := newLocalListener("tcp")
293 if err != nil {
294 t.Fatal(err)
296 addr := ln.Addr().String()
297 if err := ln.Close(); err != nil {
298 if perr := parseCloseError(err, false); perr != nil {
299 t.Error(perr)
301 t.Fatal(err)
303 ln, err = Listen("tcp", addr)
304 if err == nil {
305 // Success. nacl couldn't do this before.
306 ln.Close()
307 return
309 t.Errorf("failed on try %d/%d: %v", tries+1, maxTries, err)
311 t.Fatalf("failed to listen/close/listen on same address after %d tries", maxTries)
314 // See golang.org/issue/6163, golang.org/issue/6987.
315 func TestAcceptIgnoreAbortedConnRequest(t *testing.T) {
316 switch runtime.GOOS {
317 case "plan9":
318 t.Skipf("%s does not have full support of socktest", runtime.GOOS)
321 syserr := make(chan error)
322 go func() {
323 defer close(syserr)
324 for _, err := range abortedConnRequestErrors {
325 syserr <- err
328 sw.Set(socktest.FilterAccept, func(so *socktest.Status) (socktest.AfterFilter, error) {
329 if err, ok := <-syserr; ok {
330 return nil, err
332 return nil, nil
334 defer sw.Set(socktest.FilterAccept, nil)
336 operr := make(chan error, 1)
337 handler := func(ls *localServer, ln Listener) {
338 defer close(operr)
339 c, err := ln.Accept()
340 if err != nil {
341 if perr := parseAcceptError(err); perr != nil {
342 operr <- perr
344 operr <- err
345 return
347 c.Close()
349 ls, err := newLocalServer("tcp")
350 if err != nil {
351 t.Fatal(err)
353 defer ls.teardown()
354 if err := ls.buildup(handler); err != nil {
355 t.Fatal(err)
358 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
359 if err != nil {
360 t.Fatal(err)
362 c.Close()
364 for err := range operr {
365 t.Error(err)
369 func TestZeroByteRead(t *testing.T) {
370 for _, network := range []string{"tcp", "unix", "unixpacket"} {
371 if !testableNetwork(network) {
372 t.Logf("skipping %s test", network)
373 continue
376 ln, err := newLocalListener(network)
377 if err != nil {
378 t.Fatal(err)
380 connc := make(chan Conn, 1)
381 go func() {
382 defer ln.Close()
383 c, err := ln.Accept()
384 if err != nil {
385 t.Error(err)
387 connc <- c // might be nil
389 c, err := Dial(network, ln.Addr().String())
390 if err != nil {
391 t.Fatal(err)
393 defer c.Close()
394 sc := <-connc
395 if sc == nil {
396 continue
398 defer sc.Close()
400 if runtime.GOOS == "windows" {
401 // A zero byte read on Windows caused a wait for readability first.
402 // Rather than change that behavior, satisfy it in this test.
403 // See Issue 15735.
404 go io.WriteString(sc, "a")
407 n, err := c.Read(nil)
408 if n != 0 || err != nil {
409 t.Errorf("%s: zero byte client read = %v, %v; want 0, nil", network, n, err)
412 if runtime.GOOS == "windows" {
413 // Same as comment above.
414 go io.WriteString(c, "a")
416 n, err = sc.Read(nil)
417 if n != 0 || err != nil {
418 t.Errorf("%s: zero byte server read = %v, %v; want 0, nil", network, n, err)
423 // withTCPConnPair sets up a TCP connection between two peers, then
424 // runs peer1 and peer2 concurrently. withTCPConnPair returns when
425 // both have completed.
426 func withTCPConnPair(t *testing.T, peer1, peer2 func(c *TCPConn) error) {
427 ln, err := newLocalListener("tcp")
428 if err != nil {
429 t.Fatal(err)
431 defer ln.Close()
432 errc := make(chan error, 2)
433 go func() {
434 c1, err := ln.Accept()
435 if err != nil {
436 errc <- err
437 return
439 defer c1.Close()
440 errc <- peer1(c1.(*TCPConn))
442 go func() {
443 c2, err := Dial("tcp", ln.Addr().String())
444 if err != nil {
445 errc <- err
446 return
448 defer c2.Close()
449 errc <- peer2(c2.(*TCPConn))
451 for i := 0; i < 2; i++ {
452 if err := <-errc; err != nil {
453 t.Fatal(err)
458 // Tests that a blocked Read is interrupted by a concurrent SetReadDeadline
459 // modifying that Conn's read deadline to the past.
460 // See golang.org/cl/30164 which documented this. The net/http package
461 // depends on this.
462 func TestReadTimeoutUnblocksRead(t *testing.T) {
463 serverDone := make(chan struct{})
464 server := func(cs *TCPConn) error {
465 defer close(serverDone)
466 errc := make(chan error, 1)
467 go func() {
468 defer close(errc)
469 go func() {
470 // TODO: find a better way to wait
471 // until we're blocked in the cs.Read
472 // call below. Sleep is lame.
473 time.Sleep(100 * time.Millisecond)
475 // Interrupt the upcoming Read, unblocking it:
476 cs.SetReadDeadline(time.Unix(123, 0)) // time in the past
478 var buf [1]byte
479 n, err := cs.Read(buf[:1])
480 if n != 0 || err == nil {
481 errc <- fmt.Errorf("Read = %v, %v; want 0, non-nil", n, err)
484 select {
485 case err := <-errc:
486 return err
487 case <-time.After(5 * time.Second):
488 buf := make([]byte, 2<<20)
489 buf = buf[:runtime.Stack(buf, true)]
490 println("Stacks at timeout:\n", string(buf))
491 return errors.New("timeout waiting for Read to finish")
495 // Do nothing in the client. Never write. Just wait for the
496 // server's half to be done.
497 client := func(*TCPConn) error {
498 <-serverDone
499 return nil
501 withTCPConnPair(t, client, server)
504 // Issue 17695: verify that a blocked Read is woken up by a Close.
505 func TestCloseUnblocksRead(t *testing.T) {
506 t.Parallel()
507 server := func(cs *TCPConn) error {
508 // Give the client time to get stuck in a Read:
509 time.Sleep(20 * time.Millisecond)
510 cs.Close()
511 return nil
513 client := func(ss *TCPConn) error {
514 n, err := ss.Read([]byte{0})
515 if n != 0 || err != io.EOF {
516 return fmt.Errorf("Read = %v, %v; want 0, EOF", n, err)
518 return nil
520 withTCPConnPair(t, client, server)
523 // Issue 24808: verify that ECONNRESET is not temporary for read.
524 func TestNotTemporaryRead(t *testing.T) {
525 if runtime.GOOS == "freebsd" {
526 testenv.SkipFlaky(t, 25289)
528 t.Parallel()
529 server := func(cs *TCPConn) error {
530 cs.SetLinger(0)
531 // Give the client time to get stuck in a Read.
532 time.Sleep(20 * time.Millisecond)
533 cs.Close()
534 return nil
536 client := func(ss *TCPConn) error {
537 _, err := ss.Read([]byte{0})
538 if err == nil {
539 return errors.New("Read succeeded unexpectedly")
540 } else if err == io.EOF {
541 // This happens on NaCl and Plan 9.
542 return nil
543 } else if ne, ok := err.(Error); !ok {
544 return fmt.Errorf("unexpected error %v", err)
545 } else if ne.Temporary() {
546 return fmt.Errorf("unexpected temporary error %v", err)
548 return nil
550 withTCPConnPair(t, client, server)