github.com/aloncn/graphics-go@v0.0.1/src/net/net_test.go (about)

     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  package net
     6  
     7  import (
     8  	"io"
     9  	"os"
    10  	"runtime"
    11  	"testing"
    12  	"time"
    13  )
    14  
    15  func TestCloseRead(t *testing.T) {
    16  	switch runtime.GOOS {
    17  	case "nacl", "plan9":
    18  		t.Skipf("not supported on %s", runtime.GOOS)
    19  	}
    20  
    21  	for _, network := range []string{"tcp", "unix", "unixpacket"} {
    22  		if !testableNetwork(network) {
    23  			t.Logf("skipping %s test", network)
    24  			continue
    25  		}
    26  
    27  		ln, err := newLocalListener(network)
    28  		if err != nil {
    29  			t.Fatal(err)
    30  		}
    31  		switch network {
    32  		case "unix", "unixpacket":
    33  			defer os.Remove(ln.Addr().String())
    34  		}
    35  		defer ln.Close()
    36  
    37  		c, err := Dial(ln.Addr().Network(), ln.Addr().String())
    38  		if err != nil {
    39  			t.Fatal(err)
    40  		}
    41  		switch network {
    42  		case "unix", "unixpacket":
    43  			defer os.Remove(c.LocalAddr().String())
    44  		}
    45  		defer c.Close()
    46  
    47  		switch c := c.(type) {
    48  		case *TCPConn:
    49  			err = c.CloseRead()
    50  		case *UnixConn:
    51  			err = c.CloseRead()
    52  		}
    53  		if err != nil {
    54  			if perr := parseCloseError(err); perr != nil {
    55  				t.Error(perr)
    56  			}
    57  			t.Fatal(err)
    58  		}
    59  		var b [1]byte
    60  		n, err := c.Read(b[:])
    61  		if n != 0 || err == nil {
    62  			t.Fatalf("got (%d, %v); want (0, error)", n, err)
    63  		}
    64  	}
    65  }
    66  
    67  func TestCloseWrite(t *testing.T) {
    68  	switch runtime.GOOS {
    69  	case "nacl", "plan9":
    70  		t.Skipf("not supported on %s", runtime.GOOS)
    71  	}
    72  
    73  	handler := func(ls *localServer, ln Listener) {
    74  		c, err := ln.Accept()
    75  		if err != nil {
    76  			t.Error(err)
    77  			return
    78  		}
    79  		defer c.Close()
    80  
    81  		var b [1]byte
    82  		n, err := c.Read(b[:])
    83  		if n != 0 || err != io.EOF {
    84  			t.Errorf("got (%d, %v); want (0, io.EOF)", n, err)
    85  			return
    86  		}
    87  		switch c := c.(type) {
    88  		case *TCPConn:
    89  			err = c.CloseWrite()
    90  		case *UnixConn:
    91  			err = c.CloseWrite()
    92  		}
    93  		if err != nil {
    94  			if perr := parseCloseError(err); perr != nil {
    95  				t.Error(perr)
    96  			}
    97  			t.Error(err)
    98  			return
    99  		}
   100  		n, err = c.Write(b[:])
   101  		if err == nil {
   102  			t.Errorf("got (%d, %v); want (any, error)", n, err)
   103  			return
   104  		}
   105  	}
   106  
   107  	for _, network := range []string{"tcp", "unix", "unixpacket"} {
   108  		if !testableNetwork(network) {
   109  			t.Logf("skipping %s test", network)
   110  			continue
   111  		}
   112  
   113  		ls, err := newLocalServer(network)
   114  		if err != nil {
   115  			t.Fatal(err)
   116  		}
   117  		defer ls.teardown()
   118  		if err := ls.buildup(handler); err != nil {
   119  			t.Fatal(err)
   120  		}
   121  
   122  		c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
   123  		if err != nil {
   124  			t.Fatal(err)
   125  		}
   126  		switch network {
   127  		case "unix", "unixpacket":
   128  			defer os.Remove(c.LocalAddr().String())
   129  		}
   130  		defer c.Close()
   131  
   132  		switch c := c.(type) {
   133  		case *TCPConn:
   134  			err = c.CloseWrite()
   135  		case *UnixConn:
   136  			err = c.CloseWrite()
   137  		}
   138  		if err != nil {
   139  			if perr := parseCloseError(err); perr != nil {
   140  				t.Error(perr)
   141  			}
   142  			t.Fatal(err)
   143  		}
   144  		var b [1]byte
   145  		n, err := c.Read(b[:])
   146  		if n != 0 || err != io.EOF {
   147  			t.Fatalf("got (%d, %v); want (0, io.EOF)", n, err)
   148  		}
   149  		n, err = c.Write(b[:])
   150  		if err == nil {
   151  			t.Fatalf("got (%d, %v); want (any, error)", n, err)
   152  		}
   153  	}
   154  }
   155  
   156  func TestConnClose(t *testing.T) {
   157  	for _, network := range []string{"tcp", "unix", "unixpacket"} {
   158  		if !testableNetwork(network) {
   159  			t.Logf("skipping %s test", network)
   160  			continue
   161  		}
   162  
   163  		ln, err := newLocalListener(network)
   164  		if err != nil {
   165  			t.Fatal(err)
   166  		}
   167  		switch network {
   168  		case "unix", "unixpacket":
   169  			defer os.Remove(ln.Addr().String())
   170  		}
   171  		defer ln.Close()
   172  
   173  		c, err := Dial(ln.Addr().Network(), ln.Addr().String())
   174  		if err != nil {
   175  			t.Fatal(err)
   176  		}
   177  		switch network {
   178  		case "unix", "unixpacket":
   179  			defer os.Remove(c.LocalAddr().String())
   180  		}
   181  		defer c.Close()
   182  
   183  		if err := c.Close(); err != nil {
   184  			if perr := parseCloseError(err); perr != nil {
   185  				t.Error(perr)
   186  			}
   187  			t.Fatal(err)
   188  		}
   189  		var b [1]byte
   190  		n, err := c.Read(b[:])
   191  		if n != 0 || err == nil {
   192  			t.Fatalf("got (%d, %v); want (0, error)", n, err)
   193  		}
   194  	}
   195  }
   196  
   197  func TestListenerClose(t *testing.T) {
   198  	for _, network := range []string{"tcp", "unix", "unixpacket"} {
   199  		if !testableNetwork(network) {
   200  			t.Logf("skipping %s test", network)
   201  			continue
   202  		}
   203  
   204  		ln, err := newLocalListener(network)
   205  		if err != nil {
   206  			t.Fatal(err)
   207  		}
   208  		switch network {
   209  		case "unix", "unixpacket":
   210  			defer os.Remove(ln.Addr().String())
   211  		}
   212  
   213  		dst := ln.Addr().String()
   214  		if err := ln.Close(); err != nil {
   215  			if perr := parseCloseError(err); perr != nil {
   216  				t.Error(perr)
   217  			}
   218  			t.Fatal(err)
   219  		}
   220  		c, err := ln.Accept()
   221  		if err == nil {
   222  			c.Close()
   223  			t.Fatal("should fail")
   224  		}
   225  
   226  		if network == "tcp" {
   227  			// We will have two TCP FSMs inside the
   228  			// kernel here. There's no guarantee that a
   229  			// signal comes from the far end FSM will be
   230  			// delivered immediately to the near end FSM,
   231  			// especially on the platforms that allow
   232  			// multiple consumer threads to pull pending
   233  			// established connections at the same time by
   234  			// enabling SO_REUSEPORT option such as Linux,
   235  			// DragonFly BSD. So we need to give some time
   236  			// quantum to the kernel.
   237  			//
   238  			// Note that net.inet.tcp.reuseport_ext=1 by
   239  			// default on DragonFly BSD.
   240  			time.Sleep(time.Millisecond)
   241  
   242  			cc, err := Dial("tcp", dst)
   243  			if err == nil {
   244  				t.Error("Dial to closed TCP listener succeeded.")
   245  				cc.Close()
   246  			}
   247  		}
   248  	}
   249  }
   250  
   251  func TestPacketConnClose(t *testing.T) {
   252  	for _, network := range []string{"udp", "unixgram"} {
   253  		if !testableNetwork(network) {
   254  			t.Logf("skipping %s test", network)
   255  			continue
   256  		}
   257  
   258  		c, err := newLocalPacketListener(network)
   259  		if err != nil {
   260  			t.Fatal(err)
   261  		}
   262  		switch network {
   263  		case "unixgram":
   264  			defer os.Remove(c.LocalAddr().String())
   265  		}
   266  		defer c.Close()
   267  
   268  		if err := c.Close(); err != nil {
   269  			if perr := parseCloseError(err); perr != nil {
   270  				t.Error(perr)
   271  			}
   272  			t.Fatal(err)
   273  		}
   274  		var b [1]byte
   275  		n, _, err := c.ReadFrom(b[:])
   276  		if n != 0 || err == nil {
   277  			t.Fatalf("got (%d, %v); want (0, error)", n, err)
   278  		}
   279  	}
   280  }
   281  
   282  // nacl was previous failing to reuse an address.
   283  func TestListenCloseListen(t *testing.T) {
   284  	const maxTries = 10
   285  	for tries := 0; tries < maxTries; tries++ {
   286  		ln, err := newLocalListener("tcp")
   287  		if err != nil {
   288  			t.Fatal(err)
   289  		}
   290  		addr := ln.Addr().String()
   291  		if err := ln.Close(); err != nil {
   292  			if perr := parseCloseError(err); perr != nil {
   293  				t.Error(perr)
   294  			}
   295  			t.Fatal(err)
   296  		}
   297  		ln, err = Listen("tcp", addr)
   298  		if err == nil {
   299  			// Success. nacl couldn't do this before.
   300  			ln.Close()
   301  			return
   302  		}
   303  		t.Errorf("failed on try %d/%d: %v", tries+1, maxTries, err)
   304  	}
   305  	t.Fatalf("failed to listen/close/listen on same address after %d tries", maxTries)
   306  }