github.com/rafaeltorres324/go/src@v0.0.0-20210519164414-9fdf653a9838/net/mockserver_test.go (about)

     1  // Copyright 2013 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  	"os"
    13  	"sync"
    14  	"testing"
    15  	"time"
    16  )
    17  
    18  // testUnixAddr uses os.CreateTemp to get a name that is unique.
    19  func testUnixAddr() string {
    20  	f, err := os.CreateTemp("", "go-nettest")
    21  	if err != nil {
    22  		panic(err)
    23  	}
    24  	addr := f.Name()
    25  	f.Close()
    26  	os.Remove(addr)
    27  	return addr
    28  }
    29  
    30  func newLocalListener(network string) (Listener, error) {
    31  	switch network {
    32  	case "tcp":
    33  		if supportsIPv4() {
    34  			if ln, err := Listen("tcp4", "127.0.0.1:0"); err == nil {
    35  				return ln, nil
    36  			}
    37  		}
    38  		if supportsIPv6() {
    39  			return Listen("tcp6", "[::1]:0")
    40  		}
    41  	case "tcp4":
    42  		if supportsIPv4() {
    43  			return Listen("tcp4", "127.0.0.1:0")
    44  		}
    45  	case "tcp6":
    46  		if supportsIPv6() {
    47  			return Listen("tcp6", "[::1]:0")
    48  		}
    49  	case "unix", "unixpacket":
    50  		return Listen(network, testUnixAddr())
    51  	}
    52  	return nil, fmt.Errorf("%s is not supported", network)
    53  }
    54  
    55  func newDualStackListener() (lns []*TCPListener, err error) {
    56  	var args = []struct {
    57  		network string
    58  		TCPAddr
    59  	}{
    60  		{"tcp4", TCPAddr{IP: IPv4(127, 0, 0, 1)}},
    61  		{"tcp6", TCPAddr{IP: IPv6loopback}},
    62  	}
    63  	for i := 0; i < 64; i++ {
    64  		var port int
    65  		var lns []*TCPListener
    66  		for _, arg := range args {
    67  			arg.TCPAddr.Port = port
    68  			ln, err := ListenTCP(arg.network, &arg.TCPAddr)
    69  			if err != nil {
    70  				continue
    71  			}
    72  			port = ln.Addr().(*TCPAddr).Port
    73  			lns = append(lns, ln)
    74  		}
    75  		if len(lns) != len(args) {
    76  			for _, ln := range lns {
    77  				ln.Close()
    78  			}
    79  			continue
    80  		}
    81  		return lns, nil
    82  	}
    83  	return nil, errors.New("no dualstack port available")
    84  }
    85  
    86  type localServer struct {
    87  	lnmu sync.RWMutex
    88  	Listener
    89  	done chan bool // signal that indicates server stopped
    90  	cl   []Conn    // accepted connection list
    91  }
    92  
    93  func (ls *localServer) buildup(handler func(*localServer, Listener)) error {
    94  	go func() {
    95  		handler(ls, ls.Listener)
    96  		close(ls.done)
    97  	}()
    98  	return nil
    99  }
   100  
   101  func (ls *localServer) teardown() error {
   102  	ls.lnmu.Lock()
   103  	defer ls.lnmu.Unlock()
   104  	if ls.Listener != nil {
   105  		network := ls.Listener.Addr().Network()
   106  		address := ls.Listener.Addr().String()
   107  		ls.Listener.Close()
   108  		for _, c := range ls.cl {
   109  			if err := c.Close(); err != nil {
   110  				return err
   111  			}
   112  		}
   113  		<-ls.done
   114  		ls.Listener = nil
   115  		switch network {
   116  		case "unix", "unixpacket":
   117  			os.Remove(address)
   118  		}
   119  	}
   120  	return nil
   121  }
   122  
   123  func newLocalServer(network string) (*localServer, error) {
   124  	ln, err := newLocalListener(network)
   125  	if err != nil {
   126  		return nil, err
   127  	}
   128  	return &localServer{Listener: ln, done: make(chan bool)}, nil
   129  }
   130  
   131  type streamListener struct {
   132  	network, address string
   133  	Listener
   134  	done chan bool // signal that indicates server stopped
   135  }
   136  
   137  func (sl *streamListener) newLocalServer() (*localServer, error) {
   138  	return &localServer{Listener: sl.Listener, done: make(chan bool)}, nil
   139  }
   140  
   141  type dualStackServer struct {
   142  	lnmu sync.RWMutex
   143  	lns  []streamListener
   144  	port string
   145  
   146  	cmu sync.RWMutex
   147  	cs  []Conn // established connections at the passive open side
   148  }
   149  
   150  func (dss *dualStackServer) buildup(handler func(*dualStackServer, Listener)) error {
   151  	for i := range dss.lns {
   152  		go func(i int) {
   153  			handler(dss, dss.lns[i].Listener)
   154  			close(dss.lns[i].done)
   155  		}(i)
   156  	}
   157  	return nil
   158  }
   159  
   160  func (dss *dualStackServer) teardownNetwork(network string) error {
   161  	dss.lnmu.Lock()
   162  	for i := range dss.lns {
   163  		if network == dss.lns[i].network && dss.lns[i].Listener != nil {
   164  			dss.lns[i].Listener.Close()
   165  			<-dss.lns[i].done
   166  			dss.lns[i].Listener = nil
   167  		}
   168  	}
   169  	dss.lnmu.Unlock()
   170  	return nil
   171  }
   172  
   173  func (dss *dualStackServer) teardown() error {
   174  	dss.lnmu.Lock()
   175  	for i := range dss.lns {
   176  		if dss.lns[i].Listener != nil {
   177  			dss.lns[i].Listener.Close()
   178  			<-dss.lns[i].done
   179  		}
   180  	}
   181  	dss.lns = dss.lns[:0]
   182  	dss.lnmu.Unlock()
   183  	dss.cmu.Lock()
   184  	for _, c := range dss.cs {
   185  		c.Close()
   186  	}
   187  	dss.cs = dss.cs[:0]
   188  	dss.cmu.Unlock()
   189  	return nil
   190  }
   191  
   192  func newDualStackServer() (*dualStackServer, error) {
   193  	lns, err := newDualStackListener()
   194  	if err != nil {
   195  		return nil, err
   196  	}
   197  	_, port, err := SplitHostPort(lns[0].Addr().String())
   198  	if err != nil {
   199  		lns[0].Close()
   200  		lns[1].Close()
   201  		return nil, err
   202  	}
   203  	return &dualStackServer{
   204  		lns: []streamListener{
   205  			{network: "tcp4", address: lns[0].Addr().String(), Listener: lns[0], done: make(chan bool)},
   206  			{network: "tcp6", address: lns[1].Addr().String(), Listener: lns[1], done: make(chan bool)},
   207  		},
   208  		port: port,
   209  	}, nil
   210  }
   211  
   212  func (ls *localServer) transponder(ln Listener, ch chan<- error) {
   213  	defer close(ch)
   214  
   215  	switch ln := ln.(type) {
   216  	case *TCPListener:
   217  		ln.SetDeadline(time.Now().Add(someTimeout))
   218  	case *UnixListener:
   219  		ln.SetDeadline(time.Now().Add(someTimeout))
   220  	}
   221  	c, err := ln.Accept()
   222  	if err != nil {
   223  		if perr := parseAcceptError(err); perr != nil {
   224  			ch <- perr
   225  		}
   226  		ch <- err
   227  		return
   228  	}
   229  	ls.cl = append(ls.cl, c)
   230  
   231  	network := ln.Addr().Network()
   232  	if c.LocalAddr().Network() != network || c.RemoteAddr().Network() != network {
   233  		ch <- fmt.Errorf("got %v->%v; expected %v->%v", c.LocalAddr().Network(), c.RemoteAddr().Network(), network, network)
   234  		return
   235  	}
   236  	c.SetDeadline(time.Now().Add(someTimeout))
   237  	c.SetReadDeadline(time.Now().Add(someTimeout))
   238  	c.SetWriteDeadline(time.Now().Add(someTimeout))
   239  
   240  	b := make([]byte, 256)
   241  	n, err := c.Read(b)
   242  	if err != nil {
   243  		if perr := parseReadError(err); perr != nil {
   244  			ch <- perr
   245  		}
   246  		ch <- err
   247  		return
   248  	}
   249  	if _, err := c.Write(b[:n]); err != nil {
   250  		if perr := parseWriteError(err); perr != nil {
   251  			ch <- perr
   252  		}
   253  		ch <- err
   254  		return
   255  	}
   256  }
   257  
   258  func transceiver(c Conn, wb []byte, ch chan<- error) {
   259  	defer close(ch)
   260  
   261  	c.SetDeadline(time.Now().Add(someTimeout))
   262  	c.SetReadDeadline(time.Now().Add(someTimeout))
   263  	c.SetWriteDeadline(time.Now().Add(someTimeout))
   264  
   265  	n, err := c.Write(wb)
   266  	if err != nil {
   267  		if perr := parseWriteError(err); perr != nil {
   268  			ch <- perr
   269  		}
   270  		ch <- err
   271  		return
   272  	}
   273  	if n != len(wb) {
   274  		ch <- fmt.Errorf("wrote %d; want %d", n, len(wb))
   275  	}
   276  	rb := make([]byte, len(wb))
   277  	n, err = c.Read(rb)
   278  	if err != nil {
   279  		if perr := parseReadError(err); perr != nil {
   280  			ch <- perr
   281  		}
   282  		ch <- err
   283  		return
   284  	}
   285  	if n != len(wb) {
   286  		ch <- fmt.Errorf("read %d; want %d", n, len(wb))
   287  	}
   288  }
   289  
   290  func timeoutReceiver(c Conn, d, min, max time.Duration, ch chan<- error) {
   291  	var err error
   292  	defer func() { ch <- err }()
   293  
   294  	t0 := time.Now()
   295  	if err = c.SetReadDeadline(time.Now().Add(d)); err != nil {
   296  		return
   297  	}
   298  	b := make([]byte, 256)
   299  	var n int
   300  	n, err = c.Read(b)
   301  	t1 := time.Now()
   302  	if n != 0 || err == nil || !err.(Error).Timeout() {
   303  		err = fmt.Errorf("Read did not return (0, timeout): (%d, %v)", n, err)
   304  		return
   305  	}
   306  	if dt := t1.Sub(t0); min > dt || dt > max && !testing.Short() {
   307  		err = fmt.Errorf("Read took %s; expected %s", dt, d)
   308  		return
   309  	}
   310  }
   311  
   312  func timeoutTransmitter(c Conn, d, min, max time.Duration, ch chan<- error) {
   313  	var err error
   314  	defer func() { ch <- err }()
   315  
   316  	t0 := time.Now()
   317  	if err = c.SetWriteDeadline(time.Now().Add(d)); err != nil {
   318  		return
   319  	}
   320  	var n int
   321  	for {
   322  		n, err = c.Write([]byte("TIMEOUT TRANSMITTER"))
   323  		if err != nil {
   324  			break
   325  		}
   326  	}
   327  	t1 := time.Now()
   328  	if err == nil || !err.(Error).Timeout() {
   329  		err = fmt.Errorf("Write did not return (any, timeout): (%d, %v)", n, err)
   330  		return
   331  	}
   332  	if dt := t1.Sub(t0); min > dt || dt > max && !testing.Short() {
   333  		err = fmt.Errorf("Write took %s; expected %s", dt, d)
   334  		return
   335  	}
   336  }
   337  
   338  func newLocalPacketListener(network string) (PacketConn, error) {
   339  	switch network {
   340  	case "udp":
   341  		if supportsIPv4() {
   342  			return ListenPacket("udp4", "127.0.0.1:0")
   343  		}
   344  		if supportsIPv6() {
   345  			return ListenPacket("udp6", "[::1]:0")
   346  		}
   347  	case "udp4":
   348  		if supportsIPv4() {
   349  			return ListenPacket("udp4", "127.0.0.1:0")
   350  		}
   351  	case "udp6":
   352  		if supportsIPv6() {
   353  			return ListenPacket("udp6", "[::1]:0")
   354  		}
   355  	case "unixgram":
   356  		return ListenPacket(network, testUnixAddr())
   357  	}
   358  	return nil, fmt.Errorf("%s is not supported", network)
   359  }
   360  
   361  func newDualStackPacketListener() (cs []*UDPConn, err error) {
   362  	var args = []struct {
   363  		network string
   364  		UDPAddr
   365  	}{
   366  		{"udp4", UDPAddr{IP: IPv4(127, 0, 0, 1)}},
   367  		{"udp6", UDPAddr{IP: IPv6loopback}},
   368  	}
   369  	for i := 0; i < 64; i++ {
   370  		var port int
   371  		var cs []*UDPConn
   372  		for _, arg := range args {
   373  			arg.UDPAddr.Port = port
   374  			c, err := ListenUDP(arg.network, &arg.UDPAddr)
   375  			if err != nil {
   376  				continue
   377  			}
   378  			port = c.LocalAddr().(*UDPAddr).Port
   379  			cs = append(cs, c)
   380  		}
   381  		if len(cs) != len(args) {
   382  			for _, c := range cs {
   383  				c.Close()
   384  			}
   385  			continue
   386  		}
   387  		return cs, nil
   388  	}
   389  	return nil, errors.New("no dualstack port available")
   390  }
   391  
   392  type localPacketServer struct {
   393  	pcmu sync.RWMutex
   394  	PacketConn
   395  	done chan bool // signal that indicates server stopped
   396  }
   397  
   398  func (ls *localPacketServer) buildup(handler func(*localPacketServer, PacketConn)) error {
   399  	go func() {
   400  		handler(ls, ls.PacketConn)
   401  		close(ls.done)
   402  	}()
   403  	return nil
   404  }
   405  
   406  func (ls *localPacketServer) teardown() error {
   407  	ls.pcmu.Lock()
   408  	if ls.PacketConn != nil {
   409  		network := ls.PacketConn.LocalAddr().Network()
   410  		address := ls.PacketConn.LocalAddr().String()
   411  		ls.PacketConn.Close()
   412  		<-ls.done
   413  		ls.PacketConn = nil
   414  		switch network {
   415  		case "unixgram":
   416  			os.Remove(address)
   417  		}
   418  	}
   419  	ls.pcmu.Unlock()
   420  	return nil
   421  }
   422  
   423  func newLocalPacketServer(network string) (*localPacketServer, error) {
   424  	c, err := newLocalPacketListener(network)
   425  	if err != nil {
   426  		return nil, err
   427  	}
   428  	return &localPacketServer{PacketConn: c, done: make(chan bool)}, nil
   429  }
   430  
   431  type packetListener struct {
   432  	PacketConn
   433  }
   434  
   435  func (pl *packetListener) newLocalServer() (*localPacketServer, error) {
   436  	return &localPacketServer{PacketConn: pl.PacketConn, done: make(chan bool)}, nil
   437  }
   438  
   439  func packetTransponder(c PacketConn, ch chan<- error) {
   440  	defer close(ch)
   441  
   442  	c.SetDeadline(time.Now().Add(someTimeout))
   443  	c.SetReadDeadline(time.Now().Add(someTimeout))
   444  	c.SetWriteDeadline(time.Now().Add(someTimeout))
   445  
   446  	b := make([]byte, 256)
   447  	n, peer, err := c.ReadFrom(b)
   448  	if err != nil {
   449  		if perr := parseReadError(err); perr != nil {
   450  			ch <- perr
   451  		}
   452  		ch <- err
   453  		return
   454  	}
   455  	if peer == nil { // for connected-mode sockets
   456  		switch c.LocalAddr().Network() {
   457  		case "udp":
   458  			peer, err = ResolveUDPAddr("udp", string(b[:n]))
   459  		case "unixgram":
   460  			peer, err = ResolveUnixAddr("unixgram", string(b[:n]))
   461  		}
   462  		if err != nil {
   463  			ch <- err
   464  			return
   465  		}
   466  	}
   467  	if _, err := c.WriteTo(b[:n], peer); err != nil {
   468  		if perr := parseWriteError(err); perr != nil {
   469  			ch <- perr
   470  		}
   471  		ch <- err
   472  		return
   473  	}
   474  }
   475  
   476  func packetTransceiver(c PacketConn, wb []byte, dst Addr, ch chan<- error) {
   477  	defer close(ch)
   478  
   479  	c.SetDeadline(time.Now().Add(someTimeout))
   480  	c.SetReadDeadline(time.Now().Add(someTimeout))
   481  	c.SetWriteDeadline(time.Now().Add(someTimeout))
   482  
   483  	n, err := c.WriteTo(wb, dst)
   484  	if err != nil {
   485  		if perr := parseWriteError(err); perr != nil {
   486  			ch <- perr
   487  		}
   488  		ch <- err
   489  		return
   490  	}
   491  	if n != len(wb) {
   492  		ch <- fmt.Errorf("wrote %d; want %d", n, len(wb))
   493  	}
   494  	rb := make([]byte, len(wb))
   495  	n, _, err = c.ReadFrom(rb)
   496  	if err != nil {
   497  		if perr := parseReadError(err); perr != nil {
   498  			ch <- perr
   499  		}
   500  		ch <- err
   501  		return
   502  	}
   503  	if n != len(wb) {
   504  		ch <- fmt.Errorf("read %d; want %d", n, len(wb))
   505  	}
   506  }
   507  
   508  func timeoutPacketReceiver(c PacketConn, d, min, max time.Duration, ch chan<- error) {
   509  	var err error
   510  	defer func() { ch <- err }()
   511  
   512  	t0 := time.Now()
   513  	if err = c.SetReadDeadline(time.Now().Add(d)); err != nil {
   514  		return
   515  	}
   516  	b := make([]byte, 256)
   517  	var n int
   518  	n, _, err = c.ReadFrom(b)
   519  	t1 := time.Now()
   520  	if n != 0 || err == nil || !err.(Error).Timeout() {
   521  		err = fmt.Errorf("ReadFrom did not return (0, timeout): (%d, %v)", n, err)
   522  		return
   523  	}
   524  	if dt := t1.Sub(t0); min > dt || dt > max && !testing.Short() {
   525  		err = fmt.Errorf("ReadFrom took %s; expected %s", dt, d)
   526  		return
   527  	}
   528  }