...

Source file src/net/net_test.go

Documentation: net

		 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  //go:build !js
		 6  // +build !js
		 7  
		 8  package net
		 9  
		10  import (
		11  	"errors"
		12  	"fmt"
		13  	"internal/testenv"
		14  	"io"
		15  	"net/internal/socktest"
		16  	"os"
		17  	"runtime"
		18  	"testing"
		19  	"time"
		20  )
		21  
		22  func TestCloseRead(t *testing.T) {
		23  	switch runtime.GOOS {
		24  	case "plan9":
		25  		t.Skipf("not supported on %s", runtime.GOOS)
		26  	}
		27  	t.Parallel()
		28  
		29  	for _, network := range []string{"tcp", "unix", "unixpacket"} {
		30  		network := network
		31  		t.Run(network, func(t *testing.T) {
		32  			if !testableNetwork(network) {
		33  				t.Skipf("network %s is not testable on the current platform", network)
		34  			}
		35  			t.Parallel()
		36  
		37  			ln, err := newLocalListener(network)
		38  			if err != nil {
		39  				t.Fatal(err)
		40  			}
		41  			switch network {
		42  			case "unix", "unixpacket":
		43  				defer os.Remove(ln.Addr().String())
		44  			}
		45  			defer ln.Close()
		46  
		47  			c, err := Dial(ln.Addr().Network(), ln.Addr().String())
		48  			if err != nil {
		49  				t.Fatal(err)
		50  			}
		51  			switch network {
		52  			case "unix", "unixpacket":
		53  				defer os.Remove(c.LocalAddr().String())
		54  			}
		55  			defer c.Close()
		56  
		57  			switch c := c.(type) {
		58  			case *TCPConn:
		59  				err = c.CloseRead()
		60  			case *UnixConn:
		61  				err = c.CloseRead()
		62  			}
		63  			if err != nil {
		64  				if perr := parseCloseError(err, true); perr != nil {
		65  					t.Error(perr)
		66  				}
		67  				t.Fatal(err)
		68  			}
		69  			var b [1]byte
		70  			n, err := c.Read(b[:])
		71  			if n != 0 || err == nil {
		72  				t.Fatalf("got (%d, %v); want (0, error)", n, err)
		73  			}
		74  		})
		75  	}
		76  }
		77  
		78  func TestCloseWrite(t *testing.T) {
		79  	switch runtime.GOOS {
		80  	case "plan9":
		81  		t.Skipf("not supported on %s", runtime.GOOS)
		82  	}
		83  
		84  	t.Parallel()
		85  	deadline, _ := t.Deadline()
		86  	if !deadline.IsZero() {
		87  		// Leave 10% headroom on the deadline to report errors and clean up.
		88  		deadline = deadline.Add(-time.Until(deadline) / 10)
		89  	}
		90  
		91  	for _, network := range []string{"tcp", "unix", "unixpacket"} {
		92  		network := network
		93  		t.Run(network, func(t *testing.T) {
		94  			if !testableNetwork(network) {
		95  				t.Skipf("network %s is not testable on the current platform", network)
		96  			}
		97  			t.Parallel()
		98  
		99  			handler := func(ls *localServer, ln Listener) {
	 100  				c, err := ln.Accept()
	 101  				if err != nil {
	 102  					t.Error(err)
	 103  					return
	 104  				}
	 105  				if !deadline.IsZero() {
	 106  					c.SetDeadline(deadline)
	 107  				}
	 108  				defer c.Close()
	 109  
	 110  				var b [1]byte
	 111  				n, err := c.Read(b[:])
	 112  				if n != 0 || err != io.EOF {
	 113  					t.Errorf("got (%d, %v); want (0, io.EOF)", n, err)
	 114  					return
	 115  				}
	 116  				switch c := c.(type) {
	 117  				case *TCPConn:
	 118  					err = c.CloseWrite()
	 119  				case *UnixConn:
	 120  					err = c.CloseWrite()
	 121  				}
	 122  				if err != nil {
	 123  					if perr := parseCloseError(err, true); perr != nil {
	 124  						t.Error(perr)
	 125  					}
	 126  					t.Error(err)
	 127  					return
	 128  				}
	 129  				n, err = c.Write(b[:])
	 130  				if err == nil {
	 131  					t.Errorf("got (%d, %v); want (any, error)", n, err)
	 132  					return
	 133  				}
	 134  			}
	 135  
	 136  			ls, err := newLocalServer(network)
	 137  			if err != nil {
	 138  				t.Fatal(err)
	 139  			}
	 140  			defer ls.teardown()
	 141  			if err := ls.buildup(handler); err != nil {
	 142  				t.Fatal(err)
	 143  			}
	 144  
	 145  			c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
	 146  			if err != nil {
	 147  				t.Fatal(err)
	 148  			}
	 149  			if !deadline.IsZero() {
	 150  				c.SetDeadline(deadline)
	 151  			}
	 152  			switch network {
	 153  			case "unix", "unixpacket":
	 154  				defer os.Remove(c.LocalAddr().String())
	 155  			}
	 156  			defer c.Close()
	 157  
	 158  			switch c := c.(type) {
	 159  			case *TCPConn:
	 160  				err = c.CloseWrite()
	 161  			case *UnixConn:
	 162  				err = c.CloseWrite()
	 163  			}
	 164  			if err != nil {
	 165  				if perr := parseCloseError(err, true); perr != nil {
	 166  					t.Error(perr)
	 167  				}
	 168  				t.Fatal(err)
	 169  			}
	 170  			var b [1]byte
	 171  			n, err := c.Read(b[:])
	 172  			if n != 0 || err != io.EOF {
	 173  				t.Fatalf("got (%d, %v); want (0, io.EOF)", n, err)
	 174  			}
	 175  			n, err = c.Write(b[:])
	 176  			if err == nil {
	 177  				t.Fatalf("got (%d, %v); want (any, error)", n, err)
	 178  			}
	 179  		})
	 180  	}
	 181  }
	 182  
	 183  func TestConnClose(t *testing.T) {
	 184  	t.Parallel()
	 185  	for _, network := range []string{"tcp", "unix", "unixpacket"} {
	 186  		network := network
	 187  		t.Run(network, func(t *testing.T) {
	 188  			if !testableNetwork(network) {
	 189  				t.Skipf("network %s is not testable on the current platform", network)
	 190  			}
	 191  			t.Parallel()
	 192  
	 193  			ln, err := newLocalListener(network)
	 194  			if err != nil {
	 195  				t.Fatal(err)
	 196  			}
	 197  			switch network {
	 198  			case "unix", "unixpacket":
	 199  				defer os.Remove(ln.Addr().String())
	 200  			}
	 201  			defer ln.Close()
	 202  
	 203  			c, err := Dial(ln.Addr().Network(), ln.Addr().String())
	 204  			if err != nil {
	 205  				t.Fatal(err)
	 206  			}
	 207  			switch network {
	 208  			case "unix", "unixpacket":
	 209  				defer os.Remove(c.LocalAddr().String())
	 210  			}
	 211  			defer c.Close()
	 212  
	 213  			if err := c.Close(); err != nil {
	 214  				if perr := parseCloseError(err, false); perr != nil {
	 215  					t.Error(perr)
	 216  				}
	 217  				t.Fatal(err)
	 218  			}
	 219  			var b [1]byte
	 220  			n, err := c.Read(b[:])
	 221  			if n != 0 || err == nil {
	 222  				t.Fatalf("got (%d, %v); want (0, error)", n, err)
	 223  			}
	 224  		})
	 225  	}
	 226  }
	 227  
	 228  func TestListenerClose(t *testing.T) {
	 229  	t.Parallel()
	 230  	for _, network := range []string{"tcp", "unix", "unixpacket"} {
	 231  		network := network
	 232  		t.Run(network, func(t *testing.T) {
	 233  			if !testableNetwork(network) {
	 234  				t.Skipf("network %s is not testable on the current platform", network)
	 235  			}
	 236  			t.Parallel()
	 237  
	 238  			ln, err := newLocalListener(network)
	 239  			if err != nil {
	 240  				t.Fatal(err)
	 241  			}
	 242  			switch network {
	 243  			case "unix", "unixpacket":
	 244  				defer os.Remove(ln.Addr().String())
	 245  			}
	 246  
	 247  			dst := ln.Addr().String()
	 248  			if err := ln.Close(); err != nil {
	 249  				if perr := parseCloseError(err, false); perr != nil {
	 250  					t.Error(perr)
	 251  				}
	 252  				t.Fatal(err)
	 253  			}
	 254  			c, err := ln.Accept()
	 255  			if err == nil {
	 256  				c.Close()
	 257  				t.Fatal("should fail")
	 258  			}
	 259  
	 260  			if network == "tcp" {
	 261  				// We will have two TCP FSMs inside the
	 262  				// kernel here. There's no guarantee that a
	 263  				// signal comes from the far end FSM will be
	 264  				// delivered immediately to the near end FSM,
	 265  				// especially on the platforms that allow
	 266  				// multiple consumer threads to pull pending
	 267  				// established connections at the same time by
	 268  				// enabling SO_REUSEPORT option such as Linux,
	 269  				// DragonFly BSD. So we need to give some time
	 270  				// quantum to the kernel.
	 271  				//
	 272  				// Note that net.inet.tcp.reuseport_ext=1 by
	 273  				// default on DragonFly BSD.
	 274  				time.Sleep(time.Millisecond)
	 275  
	 276  				cc, err := Dial("tcp", dst)
	 277  				if err == nil {
	 278  					t.Error("Dial to closed TCP listener succeeded.")
	 279  					cc.Close()
	 280  				}
	 281  			}
	 282  		})
	 283  	}
	 284  }
	 285  
	 286  func TestPacketConnClose(t *testing.T) {
	 287  	t.Parallel()
	 288  	for _, network := range []string{"udp", "unixgram"} {
	 289  		network := network
	 290  		t.Run(network, func(t *testing.T) {
	 291  			if !testableNetwork(network) {
	 292  				t.Skipf("network %s is not testable on the current platform", network)
	 293  			}
	 294  			t.Parallel()
	 295  
	 296  			c, err := newLocalPacketListener(network)
	 297  			if err != nil {
	 298  				t.Fatal(err)
	 299  			}
	 300  			switch network {
	 301  			case "unixgram":
	 302  				defer os.Remove(c.LocalAddr().String())
	 303  			}
	 304  			defer c.Close()
	 305  
	 306  			if err := c.Close(); err != nil {
	 307  				if perr := parseCloseError(err, false); perr != nil {
	 308  					t.Error(perr)
	 309  				}
	 310  				t.Fatal(err)
	 311  			}
	 312  			var b [1]byte
	 313  			n, _, err := c.ReadFrom(b[:])
	 314  			if n != 0 || err == nil {
	 315  				t.Fatalf("got (%d, %v); want (0, error)", n, err)
	 316  			}
	 317  		})
	 318  	}
	 319  }
	 320  
	 321  func TestListenCloseListen(t *testing.T) {
	 322  	const maxTries = 10
	 323  	for tries := 0; tries < maxTries; tries++ {
	 324  		ln, err := newLocalListener("tcp")
	 325  		if err != nil {
	 326  			t.Fatal(err)
	 327  		}
	 328  		addr := ln.Addr().String()
	 329  		if err := ln.Close(); err != nil {
	 330  			if perr := parseCloseError(err, false); perr != nil {
	 331  				t.Error(perr)
	 332  			}
	 333  			t.Fatal(err)
	 334  		}
	 335  		ln, err = Listen("tcp", addr)
	 336  		if err == nil {
	 337  			// Success. (This test didn't always make it here earlier.)
	 338  			ln.Close()
	 339  			return
	 340  		}
	 341  		t.Errorf("failed on try %d/%d: %v", tries+1, maxTries, err)
	 342  	}
	 343  	t.Fatalf("failed to listen/close/listen on same address after %d tries", maxTries)
	 344  }
	 345  
	 346  // See golang.org/issue/6163, golang.org/issue/6987.
	 347  func TestAcceptIgnoreAbortedConnRequest(t *testing.T) {
	 348  	switch runtime.GOOS {
	 349  	case "plan9":
	 350  		t.Skipf("%s does not have full support of socktest", runtime.GOOS)
	 351  	}
	 352  
	 353  	syserr := make(chan error)
	 354  	go func() {
	 355  		defer close(syserr)
	 356  		for _, err := range abortedConnRequestErrors {
	 357  			syserr <- err
	 358  		}
	 359  	}()
	 360  	sw.Set(socktest.FilterAccept, func(so *socktest.Status) (socktest.AfterFilter, error) {
	 361  		if err, ok := <-syserr; ok {
	 362  			return nil, err
	 363  		}
	 364  		return nil, nil
	 365  	})
	 366  	defer sw.Set(socktest.FilterAccept, nil)
	 367  
	 368  	operr := make(chan error, 1)
	 369  	handler := func(ls *localServer, ln Listener) {
	 370  		defer close(operr)
	 371  		c, err := ln.Accept()
	 372  		if err != nil {
	 373  			if perr := parseAcceptError(err); perr != nil {
	 374  				operr <- perr
	 375  			}
	 376  			operr <- err
	 377  			return
	 378  		}
	 379  		c.Close()
	 380  	}
	 381  	ls, err := newLocalServer("tcp")
	 382  	if err != nil {
	 383  		t.Fatal(err)
	 384  	}
	 385  	defer ls.teardown()
	 386  	if err := ls.buildup(handler); err != nil {
	 387  		t.Fatal(err)
	 388  	}
	 389  
	 390  	c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
	 391  	if err != nil {
	 392  		t.Fatal(err)
	 393  	}
	 394  	c.Close()
	 395  
	 396  	for err := range operr {
	 397  		t.Error(err)
	 398  	}
	 399  }
	 400  
	 401  func TestZeroByteRead(t *testing.T) {
	 402  	t.Parallel()
	 403  	for _, network := range []string{"tcp", "unix", "unixpacket"} {
	 404  		network := network
	 405  		t.Run(network, func(t *testing.T) {
	 406  			if !testableNetwork(network) {
	 407  				t.Skipf("network %s is not testable on the current platform", network)
	 408  			}
	 409  			t.Parallel()
	 410  
	 411  			ln, err := newLocalListener(network)
	 412  			if err != nil {
	 413  				t.Fatal(err)
	 414  			}
	 415  			connc := make(chan Conn, 1)
	 416  			go func() {
	 417  				defer ln.Close()
	 418  				c, err := ln.Accept()
	 419  				if err != nil {
	 420  					t.Error(err)
	 421  				}
	 422  				connc <- c // might be nil
	 423  			}()
	 424  			c, err := Dial(network, ln.Addr().String())
	 425  			if err != nil {
	 426  				t.Fatal(err)
	 427  			}
	 428  			defer c.Close()
	 429  			sc := <-connc
	 430  			if sc == nil {
	 431  				return
	 432  			}
	 433  			defer sc.Close()
	 434  
	 435  			if runtime.GOOS == "windows" {
	 436  				// A zero byte read on Windows caused a wait for readability first.
	 437  				// Rather than change that behavior, satisfy it in this test.
	 438  				// See Issue 15735.
	 439  				go io.WriteString(sc, "a")
	 440  			}
	 441  
	 442  			n, err := c.Read(nil)
	 443  			if n != 0 || err != nil {
	 444  				t.Errorf("%s: zero byte client read = %v, %v; want 0, nil", network, n, err)
	 445  			}
	 446  
	 447  			if runtime.GOOS == "windows" {
	 448  				// Same as comment above.
	 449  				go io.WriteString(c, "a")
	 450  			}
	 451  			n, err = sc.Read(nil)
	 452  			if n != 0 || err != nil {
	 453  				t.Errorf("%s: zero byte server read = %v, %v; want 0, nil", network, n, err)
	 454  			}
	 455  		})
	 456  	}
	 457  }
	 458  
	 459  // withTCPConnPair sets up a TCP connection between two peers, then
	 460  // runs peer1 and peer2 concurrently. withTCPConnPair returns when
	 461  // both have completed.
	 462  func withTCPConnPair(t *testing.T, peer1, peer2 func(c *TCPConn) error) {
	 463  	ln, err := newLocalListener("tcp")
	 464  	if err != nil {
	 465  		t.Fatal(err)
	 466  	}
	 467  	defer ln.Close()
	 468  	errc := make(chan error, 2)
	 469  	go func() {
	 470  		c1, err := ln.Accept()
	 471  		if err != nil {
	 472  			errc <- err
	 473  			return
	 474  		}
	 475  		defer c1.Close()
	 476  		errc <- peer1(c1.(*TCPConn))
	 477  	}()
	 478  	go func() {
	 479  		c2, err := Dial("tcp", ln.Addr().String())
	 480  		if err != nil {
	 481  			errc <- err
	 482  			return
	 483  		}
	 484  		defer c2.Close()
	 485  		errc <- peer2(c2.(*TCPConn))
	 486  	}()
	 487  	for i := 0; i < 2; i++ {
	 488  		if err := <-errc; err != nil {
	 489  			t.Fatal(err)
	 490  		}
	 491  	}
	 492  }
	 493  
	 494  // Tests that a blocked Read is interrupted by a concurrent SetReadDeadline
	 495  // modifying that Conn's read deadline to the past.
	 496  // See golang.org/cl/30164 which documented this. The net/http package
	 497  // depends on this.
	 498  func TestReadTimeoutUnblocksRead(t *testing.T) {
	 499  	serverDone := make(chan struct{})
	 500  	server := func(cs *TCPConn) error {
	 501  		defer close(serverDone)
	 502  		errc := make(chan error, 1)
	 503  		go func() {
	 504  			defer close(errc)
	 505  			go func() {
	 506  				// TODO: find a better way to wait
	 507  				// until we're blocked in the cs.Read
	 508  				// call below. Sleep is lame.
	 509  				time.Sleep(100 * time.Millisecond)
	 510  
	 511  				// Interrupt the upcoming Read, unblocking it:
	 512  				cs.SetReadDeadline(time.Unix(123, 0)) // time in the past
	 513  			}()
	 514  			var buf [1]byte
	 515  			n, err := cs.Read(buf[:1])
	 516  			if n != 0 || err == nil {
	 517  				errc <- fmt.Errorf("Read = %v, %v; want 0, non-nil", n, err)
	 518  			}
	 519  		}()
	 520  		select {
	 521  		case err := <-errc:
	 522  			return err
	 523  		case <-time.After(5 * time.Second):
	 524  			buf := make([]byte, 2<<20)
	 525  			buf = buf[:runtime.Stack(buf, true)]
	 526  			println("Stacks at timeout:\n", string(buf))
	 527  			return errors.New("timeout waiting for Read to finish")
	 528  		}
	 529  
	 530  	}
	 531  	// Do nothing in the client. Never write. Just wait for the
	 532  	// server's half to be done.
	 533  	client := func(*TCPConn) error {
	 534  		<-serverDone
	 535  		return nil
	 536  	}
	 537  	withTCPConnPair(t, client, server)
	 538  }
	 539  
	 540  // Issue 17695: verify that a blocked Read is woken up by a Close.
	 541  func TestCloseUnblocksRead(t *testing.T) {
	 542  	t.Parallel()
	 543  	server := func(cs *TCPConn) error {
	 544  		// Give the client time to get stuck in a Read:
	 545  		time.Sleep(20 * time.Millisecond)
	 546  		cs.Close()
	 547  		return nil
	 548  	}
	 549  	client := func(ss *TCPConn) error {
	 550  		n, err := ss.Read([]byte{0})
	 551  		if n != 0 || err != io.EOF {
	 552  			return fmt.Errorf("Read = %v, %v; want 0, EOF", n, err)
	 553  		}
	 554  		return nil
	 555  	}
	 556  	withTCPConnPair(t, client, server)
	 557  }
	 558  
	 559  // Issue 24808: verify that ECONNRESET is not temporary for read.
	 560  func TestNotTemporaryRead(t *testing.T) {
	 561  	if runtime.GOOS == "freebsd" {
	 562  		testenv.SkipFlaky(t, 25289)
	 563  	}
	 564  	if runtime.GOOS == "aix" {
	 565  		testenv.SkipFlaky(t, 29685)
	 566  	}
	 567  	t.Parallel()
	 568  	server := func(cs *TCPConn) error {
	 569  		cs.SetLinger(0)
	 570  		// Give the client time to get stuck in a Read.
	 571  		time.Sleep(50 * time.Millisecond)
	 572  		cs.Close()
	 573  		return nil
	 574  	}
	 575  	client := func(ss *TCPConn) error {
	 576  		_, err := ss.Read([]byte{0})
	 577  		if err == nil {
	 578  			return errors.New("Read succeeded unexpectedly")
	 579  		} else if err == io.EOF {
	 580  			// This happens on Plan 9.
	 581  			return nil
	 582  		} else if ne, ok := err.(Error); !ok {
	 583  			return fmt.Errorf("unexpected error %v", err)
	 584  		} else if ne.Temporary() {
	 585  			return fmt.Errorf("unexpected temporary error %v", err)
	 586  		}
	 587  		return nil
	 588  	}
	 589  	withTCPConnPair(t, client, server)
	 590  }
	 591  
	 592  // The various errors should implement the Error interface.
	 593  func TestErrors(t *testing.T) {
	 594  	var (
	 595  		_ Error = &OpError{}
	 596  		_ Error = &ParseError{}
	 597  		_ Error = &AddrError{}
	 598  		_ Error = UnknownNetworkError("")
	 599  		_ Error = InvalidAddrError("")
	 600  		_ Error = &timeoutError{}
	 601  		_ Error = &DNSConfigError{}
	 602  		_ Error = &DNSError{}
	 603  	)
	 604  
	 605  	// ErrClosed was introduced as type error, so we can't check
	 606  	// it using a declaration.
	 607  	if _, ok := ErrClosed.(Error); !ok {
	 608  		t.Fatal("ErrClosed does not implement Error")
	 609  	}
	 610  }
	 611  

View as plain text