463ae8856d2c57b274fb390a99de4ebb425518d6
[platform/upstream/gcc.git] / libgo / go / net / net_test.go
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.
4
5 // +build !js
6
7 package net
8
9 import (
10         "errors"
11         "fmt"
12         "internal/testenv"
13         "io"
14         "net/internal/socktest"
15         "os"
16         "runtime"
17         "testing"
18         "time"
19 )
20
21 func TestCloseRead(t *testing.T) {
22         switch runtime.GOOS {
23         case "plan9":
24                 t.Skipf("not supported on %s", runtime.GOOS)
25         }
26
27         for _, network := range []string{"tcp", "unix", "unixpacket"} {
28                 if !testableNetwork(network) {
29                         t.Logf("skipping %s test", network)
30                         continue
31                 }
32
33                 ln, err := newLocalListener(network)
34                 if err != nil {
35                         t.Fatal(err)
36                 }
37                 switch network {
38                 case "unix", "unixpacket":
39                         defer os.Remove(ln.Addr().String())
40                 }
41                 defer ln.Close()
42
43                 c, err := Dial(ln.Addr().Network(), ln.Addr().String())
44                 if err != nil {
45                         t.Fatal(err)
46                 }
47                 switch network {
48                 case "unix", "unixpacket":
49                         defer os.Remove(c.LocalAddr().String())
50                 }
51                 defer c.Close()
52
53                 switch c := c.(type) {
54                 case *TCPConn:
55                         err = c.CloseRead()
56                 case *UnixConn:
57                         err = c.CloseRead()
58                 }
59                 if err != nil {
60                         if perr := parseCloseError(err, true); perr != nil {
61                                 t.Error(perr)
62                         }
63                         t.Fatal(err)
64                 }
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)
69                 }
70         }
71 }
72
73 func TestCloseWrite(t *testing.T) {
74         switch runtime.GOOS {
75         case "nacl", "plan9":
76                 t.Skipf("not supported on %s", runtime.GOOS)
77         }
78
79         handler := func(ls *localServer, ln Listener) {
80                 c, err := ln.Accept()
81                 if err != nil {
82                         t.Error(err)
83                         return
84                 }
85                 defer c.Close()
86
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
92                 }
93                 switch c := c.(type) {
94                 case *TCPConn:
95                         err = c.CloseWrite()
96                 case *UnixConn:
97                         err = c.CloseWrite()
98                 }
99                 if err != nil {
100                         if perr := parseCloseError(err, true); perr != nil {
101                                 t.Error(perr)
102                         }
103                         t.Error(err)
104                         return
105                 }
106                 n, err = c.Write(b[:])
107                 if err == nil {
108                         t.Errorf("got (%d, %v); want (any, error)", n, err)
109                         return
110                 }
111         }
112
113         for _, network := range []string{"tcp", "unix", "unixpacket"} {
114                 if !testableNetwork(network) {
115                         t.Logf("skipping %s test", network)
116                         continue
117                 }
118
119                 ls, err := newLocalServer(network)
120                 if err != nil {
121                         t.Fatal(err)
122                 }
123                 defer ls.teardown()
124                 if err := ls.buildup(handler); err != nil {
125                         t.Fatal(err)
126                 }
127
128                 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
129                 if err != nil {
130                         t.Fatal(err)
131                 }
132                 switch network {
133                 case "unix", "unixpacket":
134                         defer os.Remove(c.LocalAddr().String())
135                 }
136                 defer c.Close()
137
138                 switch c := c.(type) {
139                 case *TCPConn:
140                         err = c.CloseWrite()
141                 case *UnixConn:
142                         err = c.CloseWrite()
143                 }
144                 if err != nil {
145                         if perr := parseCloseError(err, true); perr != nil {
146                                 t.Error(perr)
147                         }
148                         t.Fatal(err)
149                 }
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)
154                 }
155                 n, err = c.Write(b[:])
156                 if err == nil {
157                         t.Fatalf("got (%d, %v); want (any, error)", n, err)
158                 }
159         }
160 }
161
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
167                 }
168
169                 ln, err := newLocalListener(network)
170                 if err != nil {
171                         t.Fatal(err)
172                 }
173                 switch network {
174                 case "unix", "unixpacket":
175                         defer os.Remove(ln.Addr().String())
176                 }
177                 defer ln.Close()
178
179                 c, err := Dial(ln.Addr().Network(), ln.Addr().String())
180                 if err != nil {
181                         t.Fatal(err)
182                 }
183                 switch network {
184                 case "unix", "unixpacket":
185                         defer os.Remove(c.LocalAddr().String())
186                 }
187                 defer c.Close()
188
189                 if err := c.Close(); err != nil {
190                         if perr := parseCloseError(err, false); perr != nil {
191                                 t.Error(perr)
192                         }
193                         t.Fatal(err)
194                 }
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)
199                 }
200         }
201 }
202
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
208                 }
209
210                 ln, err := newLocalListener(network)
211                 if err != nil {
212                         t.Fatal(err)
213                 }
214                 switch network {
215                 case "unix", "unixpacket":
216                         defer os.Remove(ln.Addr().String())
217                 }
218
219                 dst := ln.Addr().String()
220                 if err := ln.Close(); err != nil {
221                         if perr := parseCloseError(err, false); perr != nil {
222                                 t.Error(perr)
223                         }
224                         t.Fatal(err)
225                 }
226                 c, err := ln.Accept()
227                 if err == nil {
228                         c.Close()
229                         t.Fatal("should fail")
230                 }
231
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.
243                         //
244                         // Note that net.inet.tcp.reuseport_ext=1 by
245                         // default on DragonFly BSD.
246                         time.Sleep(time.Millisecond)
247
248                         cc, err := Dial("tcp", dst)
249                         if err == nil {
250                                 t.Error("Dial to closed TCP listener succeeded.")
251                                 cc.Close()
252                         }
253                 }
254         }
255 }
256
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
262                 }
263
264                 c, err := newLocalPacketListener(network)
265                 if err != nil {
266                         t.Fatal(err)
267                 }
268                 switch network {
269                 case "unixgram":
270                         defer os.Remove(c.LocalAddr().String())
271                 }
272                 defer c.Close()
273
274                 if err := c.Close(); err != nil {
275                         if perr := parseCloseError(err, false); perr != nil {
276                                 t.Error(perr)
277                         }
278                         t.Fatal(err)
279                 }
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)
284                 }
285         }
286 }
287
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)
295                 }
296                 addr := ln.Addr().String()
297                 if err := ln.Close(); err != nil {
298                         if perr := parseCloseError(err, false); perr != nil {
299                                 t.Error(perr)
300                         }
301                         t.Fatal(err)
302                 }
303                 ln, err = Listen("tcp", addr)
304                 if err == nil {
305                         // Success. nacl couldn't do this before.
306                         ln.Close()
307                         return
308                 }
309                 t.Errorf("failed on try %d/%d: %v", tries+1, maxTries, err)
310         }
311         t.Fatalf("failed to listen/close/listen on same address after %d tries", maxTries)
312 }
313
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)
319         }
320
321         syserr := make(chan error)
322         go func() {
323                 defer close(syserr)
324                 for _, err := range abortedConnRequestErrors {
325                         syserr <- err
326                 }
327         }()
328         sw.Set(socktest.FilterAccept, func(so *socktest.Status) (socktest.AfterFilter, error) {
329                 if err, ok := <-syserr; ok {
330                         return nil, err
331                 }
332                 return nil, nil
333         })
334         defer sw.Set(socktest.FilterAccept, nil)
335
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
343                         }
344                         operr <- err
345                         return
346                 }
347                 c.Close()
348         }
349         ls, err := newLocalServer("tcp")
350         if err != nil {
351                 t.Fatal(err)
352         }
353         defer ls.teardown()
354         if err := ls.buildup(handler); err != nil {
355                 t.Fatal(err)
356         }
357
358         c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
359         if err != nil {
360                 t.Fatal(err)
361         }
362         c.Close()
363
364         for err := range operr {
365                 t.Error(err)
366         }
367 }
368
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
374                 }
375
376                 ln, err := newLocalListener(network)
377                 if err != nil {
378                         t.Fatal(err)
379                 }
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)
386                         }
387                         connc <- c // might be nil
388                 }()
389                 c, err := Dial(network, ln.Addr().String())
390                 if err != nil {
391                         t.Fatal(err)
392                 }
393                 defer c.Close()
394                 sc := <-connc
395                 if sc == nil {
396                         continue
397                 }
398                 defer sc.Close()
399
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")
405                 }
406
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)
410                 }
411
412                 if runtime.GOOS == "windows" {
413                         // Same as comment above.
414                         go io.WriteString(c, "a")
415                 }
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)
419                 }
420         }
421 }
422
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)
430         }
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
438                 }
439                 defer c1.Close()
440                 errc <- peer1(c1.(*TCPConn))
441         }()
442         go func() {
443                 c2, err := Dial("tcp", ln.Addr().String())
444                 if err != nil {
445                         errc <- err
446                         return
447                 }
448                 defer c2.Close()
449                 errc <- peer2(c2.(*TCPConn))
450         }()
451         for i := 0; i < 2; i++ {
452                 if err := <-errc; err != nil {
453                         t.Fatal(err)
454                 }
455         }
456 }
457
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)
474
475                                 // Interrupt the upcoming Read, unblocking it:
476                                 cs.SetReadDeadline(time.Unix(123, 0)) // time in the past
477                         }()
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)
482                         }
483                 }()
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")
492                 }
493
494         }
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
500         }
501         withTCPConnPair(t, client, server)
502 }
503
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
512         }
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)
517                 }
518                 return nil
519         }
520         withTCPConnPair(t, client, server)
521 }
522
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)
527         }
528         if runtime.GOOS == "aix" {
529                 testenv.SkipFlaky(t, 29685)
530         }
531         t.Parallel()
532         server := func(cs *TCPConn) error {
533                 cs.SetLinger(0)
534                 // Give the client time to get stuck in a Read.
535                 time.Sleep(50 * time.Millisecond)
536                 cs.Close()
537                 return nil
538         }
539         client := func(ss *TCPConn) error {
540                 _, err := ss.Read([]byte{0})
541                 if err == nil {
542                         return errors.New("Read succeeded unexpectedly")
543                 } else if err == io.EOF {
544                         // This happens on NaCl and Plan 9.
545                         return nil
546                 } else if ne, ok := err.(Error); !ok {
547                         return fmt.Errorf("unexpected error %v", err)
548                 } else if ne.Temporary() {
549                         return fmt.Errorf("unexpected temporary error %v", err)
550                 }
551                 return nil
552         }
553         withTCPConnPair(t, client, server)
554 }