...

Source file src/net/mockserver_test.go

Documentation: net

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

View as plain text