github.com/dannin/go@v0.0.0-20161031215817-d35dfd405eaa/src/net/timeout_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  	"context"
     9  	"fmt"
    10  	"internal/testenv"
    11  	"io"
    12  	"io/ioutil"
    13  	"net/internal/socktest"
    14  	"runtime"
    15  	"sync"
    16  	"testing"
    17  	"time"
    18  )
    19  
    20  var dialTimeoutTests = []struct {
    21  	timeout time.Duration
    22  	delta   time.Duration // for deadline
    23  
    24  	guard time.Duration
    25  	max   time.Duration
    26  }{
    27  	// Tests that dial timeouts, deadlines in the past work.
    28  	{-5 * time.Second, 0, -5 * time.Second, 100 * time.Millisecond},
    29  	{0, -5 * time.Second, -5 * time.Second, 100 * time.Millisecond},
    30  	{-5 * time.Second, 5 * time.Second, -5 * time.Second, 100 * time.Millisecond}, // timeout over deadline
    31  	{-1 << 63, 0, time.Second, 100 * time.Millisecond},
    32  	{0, -1 << 63, time.Second, 100 * time.Millisecond},
    33  
    34  	{50 * time.Millisecond, 0, 100 * time.Millisecond, time.Second},
    35  	{0, 50 * time.Millisecond, 100 * time.Millisecond, time.Second},
    36  	{50 * time.Millisecond, 5 * time.Second, 100 * time.Millisecond, time.Second}, // timeout over deadline
    37  }
    38  
    39  func TestDialTimeout(t *testing.T) {
    40  	// Cannot use t.Parallel - modifies global hooks.
    41  	origTestHookDialChannel := testHookDialChannel
    42  	defer func() { testHookDialChannel = origTestHookDialChannel }()
    43  	defer sw.Set(socktest.FilterConnect, nil)
    44  
    45  	for i, tt := range dialTimeoutTests {
    46  		switch runtime.GOOS {
    47  		case "plan9", "windows":
    48  			testHookDialChannel = func() { time.Sleep(tt.guard) }
    49  			if runtime.GOOS == "plan9" {
    50  				break
    51  			}
    52  			fallthrough
    53  		default:
    54  			sw.Set(socktest.FilterConnect, func(so *socktest.Status) (socktest.AfterFilter, error) {
    55  				time.Sleep(tt.guard)
    56  				return nil, errTimedout
    57  			})
    58  		}
    59  
    60  		ch := make(chan error)
    61  		d := Dialer{Timeout: tt.timeout}
    62  		if tt.delta != 0 {
    63  			d.Deadline = time.Now().Add(tt.delta)
    64  		}
    65  		max := time.NewTimer(tt.max)
    66  		defer max.Stop()
    67  		go func() {
    68  			// This dial never starts to send any TCP SYN
    69  			// segment because of above socket filter and
    70  			// test hook.
    71  			c, err := d.Dial("tcp", "127.0.0.1:0")
    72  			if err == nil {
    73  				err = fmt.Errorf("unexpectedly established: tcp:%s->%s", c.LocalAddr(), c.RemoteAddr())
    74  				c.Close()
    75  			}
    76  			ch <- err
    77  		}()
    78  
    79  		select {
    80  		case <-max.C:
    81  			t.Fatalf("#%d: Dial didn't return in an expected time", i)
    82  		case err := <-ch:
    83  			if perr := parseDialError(err); perr != nil {
    84  				t.Errorf("#%d: %v", i, perr)
    85  			}
    86  			if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
    87  				t.Fatalf("#%d: %v", i, err)
    88  			}
    89  		}
    90  	}
    91  }
    92  
    93  var dialTimeoutMaxDurationTests = []struct {
    94  	timeout time.Duration
    95  	delta   time.Duration // for deadline
    96  }{
    97  	// Large timeouts that will overflow an int64 unix nanos.
    98  	{1<<63 - 1, 0},
    99  	{0, 1<<63 - 1},
   100  }
   101  
   102  func TestDialTimeoutMaxDuration(t *testing.T) {
   103  	if runtime.GOOS == "openbsd" {
   104  		testenv.SkipFlaky(t, 15157)
   105  	}
   106  
   107  	ln, err := newLocalListener("tcp")
   108  	if err != nil {
   109  		t.Fatal(err)
   110  	}
   111  	defer ln.Close()
   112  
   113  	for i, tt := range dialTimeoutMaxDurationTests {
   114  		ch := make(chan error)
   115  		max := time.NewTimer(250 * time.Millisecond)
   116  		defer max.Stop()
   117  		go func() {
   118  			d := Dialer{Timeout: tt.timeout}
   119  			if tt.delta != 0 {
   120  				d.Deadline = time.Now().Add(tt.delta)
   121  			}
   122  			c, err := d.Dial(ln.Addr().Network(), ln.Addr().String())
   123  			if err == nil {
   124  				c.Close()
   125  			}
   126  			ch <- err
   127  		}()
   128  
   129  		select {
   130  		case <-max.C:
   131  			t.Fatalf("#%d: Dial didn't return in an expected time", i)
   132  		case err := <-ch:
   133  			if perr := parseDialError(err); perr != nil {
   134  				t.Error(perr)
   135  			}
   136  			if err != nil {
   137  				t.Errorf("#%d: %v", i, err)
   138  			}
   139  		}
   140  	}
   141  }
   142  
   143  var acceptTimeoutTests = []struct {
   144  	timeout time.Duration
   145  	xerrs   [2]error // expected errors in transition
   146  }{
   147  	// Tests that accept deadlines in the past work, even if
   148  	// there's incoming connections available.
   149  	{-5 * time.Second, [2]error{errTimeout, errTimeout}},
   150  
   151  	{50 * time.Millisecond, [2]error{nil, errTimeout}},
   152  }
   153  
   154  func TestAcceptTimeout(t *testing.T) {
   155  	t.Parallel()
   156  
   157  	switch runtime.GOOS {
   158  	case "plan9":
   159  		t.Skipf("not supported on %s", runtime.GOOS)
   160  	}
   161  
   162  	ln, err := newLocalListener("tcp")
   163  	if err != nil {
   164  		t.Fatal(err)
   165  	}
   166  	defer ln.Close()
   167  
   168  	ctx, cancel := context.WithCancel(context.Background())
   169  	defer cancel()
   170  	for i, tt := range acceptTimeoutTests {
   171  		if tt.timeout < 0 {
   172  			go func() {
   173  				var d Dialer
   174  				c, err := d.DialContext(ctx, ln.Addr().Network(), ln.Addr().String())
   175  				if err != nil {
   176  					t.Error(err)
   177  					return
   178  				}
   179  				var b [1]byte
   180  				c.Read(b[:])
   181  				c.Close()
   182  			}()
   183  		}
   184  
   185  		if err := ln.(*TCPListener).SetDeadline(time.Now().Add(tt.timeout)); err != nil {
   186  			t.Fatalf("$%d: %v", i, err)
   187  		}
   188  		for j, xerr := range tt.xerrs {
   189  			for {
   190  				c, err := ln.Accept()
   191  				if xerr != nil {
   192  					if perr := parseAcceptError(err); perr != nil {
   193  						t.Errorf("#%d/%d: %v", i, j, perr)
   194  					}
   195  					if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
   196  						t.Fatalf("#%d/%d: %v", i, j, err)
   197  					}
   198  				}
   199  				if err == nil {
   200  					c.Close()
   201  					time.Sleep(tt.timeout / 3)
   202  					continue
   203  				}
   204  				break
   205  			}
   206  		}
   207  	}
   208  }
   209  
   210  func TestAcceptTimeoutMustReturn(t *testing.T) {
   211  	t.Parallel()
   212  
   213  	switch runtime.GOOS {
   214  	case "plan9":
   215  		t.Skipf("not supported on %s", runtime.GOOS)
   216  	}
   217  
   218  	ln, err := newLocalListener("tcp")
   219  	if err != nil {
   220  		t.Fatal(err)
   221  	}
   222  	defer ln.Close()
   223  
   224  	max := time.NewTimer(time.Second)
   225  	defer max.Stop()
   226  	ch := make(chan error)
   227  	go func() {
   228  		if err := ln.(*TCPListener).SetDeadline(noDeadline); err != nil {
   229  			t.Error(err)
   230  		}
   231  		if err := ln.(*TCPListener).SetDeadline(time.Now().Add(10 * time.Millisecond)); err != nil {
   232  			t.Error(err)
   233  		}
   234  		c, err := ln.Accept()
   235  		if err == nil {
   236  			c.Close()
   237  		}
   238  		ch <- err
   239  	}()
   240  
   241  	select {
   242  	case <-max.C:
   243  		ln.Close()
   244  		<-ch // wait for tester goroutine to stop
   245  		t.Fatal("Accept didn't return in an expected time")
   246  	case err := <-ch:
   247  		if perr := parseAcceptError(err); perr != nil {
   248  			t.Error(perr)
   249  		}
   250  		if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
   251  			t.Fatal(err)
   252  		}
   253  	}
   254  }
   255  
   256  func TestAcceptTimeoutMustNotReturn(t *testing.T) {
   257  	t.Parallel()
   258  
   259  	switch runtime.GOOS {
   260  	case "plan9":
   261  		t.Skipf("not supported on %s", runtime.GOOS)
   262  	}
   263  
   264  	ln, err := newLocalListener("tcp")
   265  	if err != nil {
   266  		t.Fatal(err)
   267  	}
   268  	defer ln.Close()
   269  
   270  	max := time.NewTimer(100 * time.Millisecond)
   271  	defer max.Stop()
   272  	ch := make(chan error)
   273  	go func() {
   274  		if err := ln.(*TCPListener).SetDeadline(time.Now().Add(-5 * time.Second)); err != nil {
   275  			t.Error(err)
   276  		}
   277  		if err := ln.(*TCPListener).SetDeadline(noDeadline); err != nil {
   278  			t.Error(err)
   279  		}
   280  		_, err := ln.Accept()
   281  		ch <- err
   282  	}()
   283  
   284  	select {
   285  	case err := <-ch:
   286  		if perr := parseAcceptError(err); perr != nil {
   287  			t.Error(perr)
   288  		}
   289  		t.Fatalf("expected Accept to not return, but it returned with %v", err)
   290  	case <-max.C:
   291  		ln.Close()
   292  		<-ch // wait for tester goroutine to stop
   293  	}
   294  }
   295  
   296  var readTimeoutTests = []struct {
   297  	timeout time.Duration
   298  	xerrs   [2]error // expected errors in transition
   299  }{
   300  	// Tests that read deadlines work, even if there's data ready
   301  	// to be read.
   302  	{-5 * time.Second, [2]error{errTimeout, errTimeout}},
   303  
   304  	{50 * time.Millisecond, [2]error{nil, errTimeout}},
   305  }
   306  
   307  func TestReadTimeout(t *testing.T) {
   308  	switch runtime.GOOS {
   309  	case "plan9":
   310  		t.Skipf("not supported on %s", runtime.GOOS)
   311  	}
   312  
   313  	handler := func(ls *localServer, ln Listener) {
   314  		c, err := ln.Accept()
   315  		if err != nil {
   316  			t.Error(err)
   317  			return
   318  		}
   319  		c.Write([]byte("READ TIMEOUT TEST"))
   320  		defer c.Close()
   321  	}
   322  	ls, err := newLocalServer("tcp")
   323  	if err != nil {
   324  		t.Fatal(err)
   325  	}
   326  	defer ls.teardown()
   327  	if err := ls.buildup(handler); err != nil {
   328  		t.Fatal(err)
   329  	}
   330  
   331  	c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
   332  	if err != nil {
   333  		t.Fatal(err)
   334  	}
   335  	defer c.Close()
   336  
   337  	for i, tt := range readTimeoutTests {
   338  		if err := c.SetReadDeadline(time.Now().Add(tt.timeout)); err != nil {
   339  			t.Fatalf("#%d: %v", i, err)
   340  		}
   341  		var b [1]byte
   342  		for j, xerr := range tt.xerrs {
   343  			for {
   344  				n, err := c.Read(b[:])
   345  				if xerr != nil {
   346  					if perr := parseReadError(err); perr != nil {
   347  						t.Errorf("#%d/%d: %v", i, j, perr)
   348  					}
   349  					if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
   350  						t.Fatalf("#%d/%d: %v", i, j, err)
   351  					}
   352  				}
   353  				if err == nil {
   354  					time.Sleep(tt.timeout / 3)
   355  					continue
   356  				}
   357  				if n != 0 {
   358  					t.Fatalf("#%d/%d: read %d; want 0", i, j, n)
   359  				}
   360  				break
   361  			}
   362  		}
   363  	}
   364  }
   365  
   366  func TestReadTimeoutMustNotReturn(t *testing.T) {
   367  	t.Parallel()
   368  
   369  	switch runtime.GOOS {
   370  	case "plan9":
   371  		t.Skipf("not supported on %s", runtime.GOOS)
   372  	}
   373  
   374  	ln, err := newLocalListener("tcp")
   375  	if err != nil {
   376  		t.Fatal(err)
   377  	}
   378  	defer ln.Close()
   379  
   380  	c, err := Dial(ln.Addr().Network(), ln.Addr().String())
   381  	if err != nil {
   382  		t.Fatal(err)
   383  	}
   384  	defer c.Close()
   385  
   386  	max := time.NewTimer(100 * time.Millisecond)
   387  	defer max.Stop()
   388  	ch := make(chan error)
   389  	go func() {
   390  		if err := c.SetDeadline(time.Now().Add(-5 * time.Second)); err != nil {
   391  			t.Error(err)
   392  		}
   393  		if err := c.SetWriteDeadline(time.Now().Add(-5 * time.Second)); err != nil {
   394  			t.Error(err)
   395  		}
   396  		if err := c.SetReadDeadline(noDeadline); err != nil {
   397  			t.Error(err)
   398  		}
   399  		var b [1]byte
   400  		_, err := c.Read(b[:])
   401  		ch <- err
   402  	}()
   403  
   404  	select {
   405  	case err := <-ch:
   406  		if perr := parseReadError(err); perr != nil {
   407  			t.Error(perr)
   408  		}
   409  		t.Fatalf("expected Read to not return, but it returned with %v", err)
   410  	case <-max.C:
   411  		c.Close()
   412  		err := <-ch // wait for tester goroutine to stop
   413  		if perr := parseReadError(err); perr != nil {
   414  			t.Error(perr)
   415  		}
   416  		if err == io.EOF && runtime.GOOS == "nacl" { // see golang.org/issue/8044
   417  			return
   418  		}
   419  		if nerr, ok := err.(Error); !ok || nerr.Timeout() || nerr.Temporary() {
   420  			t.Fatal(err)
   421  		}
   422  	}
   423  }
   424  
   425  var readFromTimeoutTests = []struct {
   426  	timeout time.Duration
   427  	xerrs   [2]error // expected errors in transition
   428  }{
   429  	// Tests that read deadlines work, even if there's data ready
   430  	// to be read.
   431  	{-5 * time.Second, [2]error{errTimeout, errTimeout}},
   432  
   433  	{50 * time.Millisecond, [2]error{nil, errTimeout}},
   434  }
   435  
   436  func TestReadFromTimeout(t *testing.T) {
   437  	switch runtime.GOOS {
   438  	case "nacl", "plan9":
   439  		t.Skipf("not supported on %s", runtime.GOOS) // see golang.org/issue/8916
   440  	}
   441  
   442  	ch := make(chan Addr)
   443  	defer close(ch)
   444  	handler := func(ls *localPacketServer, c PacketConn) {
   445  		if dst, ok := <-ch; ok {
   446  			c.WriteTo([]byte("READFROM TIMEOUT TEST"), dst)
   447  		}
   448  	}
   449  	ls, err := newLocalPacketServer("udp")
   450  	if err != nil {
   451  		t.Fatal(err)
   452  	}
   453  	defer ls.teardown()
   454  	if err := ls.buildup(handler); err != nil {
   455  		t.Fatal(err)
   456  	}
   457  
   458  	host, _, err := SplitHostPort(ls.PacketConn.LocalAddr().String())
   459  	if err != nil {
   460  		t.Fatal(err)
   461  	}
   462  	c, err := ListenPacket(ls.PacketConn.LocalAddr().Network(), JoinHostPort(host, "0"))
   463  	if err != nil {
   464  		t.Fatal(err)
   465  	}
   466  	defer c.Close()
   467  	ch <- c.LocalAddr()
   468  
   469  	for i, tt := range readFromTimeoutTests {
   470  		if err := c.SetReadDeadline(time.Now().Add(tt.timeout)); err != nil {
   471  			t.Fatalf("#%d: %v", i, err)
   472  		}
   473  		var b [1]byte
   474  		for j, xerr := range tt.xerrs {
   475  			for {
   476  				n, _, err := c.ReadFrom(b[:])
   477  				if xerr != nil {
   478  					if perr := parseReadError(err); perr != nil {
   479  						t.Errorf("#%d/%d: %v", i, j, perr)
   480  					}
   481  					if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
   482  						t.Fatalf("#%d/%d: %v", i, j, err)
   483  					}
   484  				}
   485  				if err == nil {
   486  					time.Sleep(tt.timeout / 3)
   487  					continue
   488  				}
   489  				if n != 0 {
   490  					t.Fatalf("#%d/%d: read %d; want 0", i, j, n)
   491  				}
   492  				break
   493  			}
   494  		}
   495  	}
   496  }
   497  
   498  var writeTimeoutTests = []struct {
   499  	timeout time.Duration
   500  	xerrs   [2]error // expected errors in transition
   501  }{
   502  	// Tests that write deadlines work, even if there's buffer
   503  	// space available to write.
   504  	{-5 * time.Second, [2]error{errTimeout, errTimeout}},
   505  
   506  	{10 * time.Millisecond, [2]error{nil, errTimeout}},
   507  }
   508  
   509  func TestWriteTimeout(t *testing.T) {
   510  	t.Parallel()
   511  
   512  	switch runtime.GOOS {
   513  	case "plan9":
   514  		t.Skipf("not supported on %s", runtime.GOOS)
   515  	}
   516  
   517  	ln, err := newLocalListener("tcp")
   518  	if err != nil {
   519  		t.Fatal(err)
   520  	}
   521  	defer ln.Close()
   522  
   523  	for i, tt := range writeTimeoutTests {
   524  		c, err := Dial(ln.Addr().Network(), ln.Addr().String())
   525  		if err != nil {
   526  			t.Fatal(err)
   527  		}
   528  		defer c.Close()
   529  
   530  		if err := c.SetWriteDeadline(time.Now().Add(tt.timeout)); err != nil {
   531  			t.Fatalf("#%d: %v", i, err)
   532  		}
   533  		for j, xerr := range tt.xerrs {
   534  			for {
   535  				n, err := c.Write([]byte("WRITE TIMEOUT TEST"))
   536  				if xerr != nil {
   537  					if perr := parseWriteError(err); perr != nil {
   538  						t.Errorf("#%d/%d: %v", i, j, perr)
   539  					}
   540  					if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
   541  						t.Fatalf("#%d/%d: %v", i, j, err)
   542  					}
   543  				}
   544  				if err == nil {
   545  					time.Sleep(tt.timeout / 3)
   546  					continue
   547  				}
   548  				if n != 0 {
   549  					t.Fatalf("#%d/%d: wrote %d; want 0", i, j, n)
   550  				}
   551  				break
   552  			}
   553  		}
   554  	}
   555  }
   556  
   557  func TestWriteTimeoutMustNotReturn(t *testing.T) {
   558  	t.Parallel()
   559  
   560  	switch runtime.GOOS {
   561  	case "plan9":
   562  		t.Skipf("not supported on %s", runtime.GOOS)
   563  	}
   564  
   565  	ln, err := newLocalListener("tcp")
   566  	if err != nil {
   567  		t.Fatal(err)
   568  	}
   569  	defer ln.Close()
   570  
   571  	c, err := Dial(ln.Addr().Network(), ln.Addr().String())
   572  	if err != nil {
   573  		t.Fatal(err)
   574  	}
   575  	defer c.Close()
   576  
   577  	max := time.NewTimer(100 * time.Millisecond)
   578  	defer max.Stop()
   579  	ch := make(chan error)
   580  	go func() {
   581  		if err := c.SetDeadline(time.Now().Add(-5 * time.Second)); err != nil {
   582  			t.Error(err)
   583  		}
   584  		if err := c.SetReadDeadline(time.Now().Add(-5 * time.Second)); err != nil {
   585  			t.Error(err)
   586  		}
   587  		if err := c.SetWriteDeadline(noDeadline); err != nil {
   588  			t.Error(err)
   589  		}
   590  		var b [1]byte
   591  		for {
   592  			if _, err := c.Write(b[:]); err != nil {
   593  				ch <- err
   594  				break
   595  			}
   596  		}
   597  	}()
   598  
   599  	select {
   600  	case err := <-ch:
   601  		if perr := parseWriteError(err); perr != nil {
   602  			t.Error(perr)
   603  		}
   604  		t.Fatalf("expected Write to not return, but it returned with %v", err)
   605  	case <-max.C:
   606  		c.Close()
   607  		err := <-ch // wait for tester goroutine to stop
   608  		if perr := parseWriteError(err); perr != nil {
   609  			t.Error(perr)
   610  		}
   611  		if nerr, ok := err.(Error); !ok || nerr.Timeout() || nerr.Temporary() {
   612  			t.Fatal(err)
   613  		}
   614  	}
   615  }
   616  
   617  var writeToTimeoutTests = []struct {
   618  	timeout time.Duration
   619  	xerrs   [2]error // expected errors in transition
   620  }{
   621  	// Tests that write deadlines work, even if there's buffer
   622  	// space available to write.
   623  	{-5 * time.Second, [2]error{errTimeout, errTimeout}},
   624  
   625  	{10 * time.Millisecond, [2]error{nil, errTimeout}},
   626  }
   627  
   628  func TestWriteToTimeout(t *testing.T) {
   629  	t.Parallel()
   630  
   631  	switch runtime.GOOS {
   632  	case "nacl", "plan9":
   633  		t.Skipf("not supported on %s", runtime.GOOS)
   634  	}
   635  
   636  	c1, err := newLocalPacketListener("udp")
   637  	if err != nil {
   638  		t.Fatal(err)
   639  	}
   640  	defer c1.Close()
   641  
   642  	host, _, err := SplitHostPort(c1.LocalAddr().String())
   643  	if err != nil {
   644  		t.Fatal(err)
   645  	}
   646  
   647  	for i, tt := range writeToTimeoutTests {
   648  		c2, err := ListenPacket(c1.LocalAddr().Network(), JoinHostPort(host, "0"))
   649  		if err != nil {
   650  			t.Fatal(err)
   651  		}
   652  		defer c2.Close()
   653  
   654  		if err := c2.SetWriteDeadline(time.Now().Add(tt.timeout)); err != nil {
   655  			t.Fatalf("#%d: %v", i, err)
   656  		}
   657  		for j, xerr := range tt.xerrs {
   658  			for {
   659  				n, err := c2.WriteTo([]byte("WRITETO TIMEOUT TEST"), c1.LocalAddr())
   660  				if xerr != nil {
   661  					if perr := parseWriteError(err); perr != nil {
   662  						t.Errorf("#%d/%d: %v", i, j, perr)
   663  					}
   664  					if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
   665  						t.Fatalf("#%d/%d: %v", i, j, err)
   666  					}
   667  				}
   668  				if err == nil {
   669  					time.Sleep(tt.timeout / 3)
   670  					continue
   671  				}
   672  				if n != 0 {
   673  					t.Fatalf("#%d/%d: wrote %d; want 0", i, j, n)
   674  				}
   675  				break
   676  			}
   677  		}
   678  	}
   679  }
   680  
   681  func TestReadTimeoutFluctuation(t *testing.T) {
   682  	t.Parallel()
   683  
   684  	switch runtime.GOOS {
   685  	case "plan9":
   686  		t.Skipf("not supported on %s", runtime.GOOS)
   687  	}
   688  
   689  	ln, err := newLocalListener("tcp")
   690  	if err != nil {
   691  		t.Fatal(err)
   692  	}
   693  	defer ln.Close()
   694  
   695  	c, err := Dial(ln.Addr().Network(), ln.Addr().String())
   696  	if err != nil {
   697  		t.Fatal(err)
   698  	}
   699  	defer c.Close()
   700  
   701  	max := time.NewTimer(time.Second)
   702  	defer max.Stop()
   703  	ch := make(chan error)
   704  	go timeoutReceiver(c, 100*time.Millisecond, 50*time.Millisecond, 250*time.Millisecond, ch)
   705  
   706  	select {
   707  	case <-max.C:
   708  		t.Fatal("Read took over 1s; expected 0.1s")
   709  	case err := <-ch:
   710  		if perr := parseReadError(err); perr != nil {
   711  			t.Error(perr)
   712  		}
   713  		if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
   714  			t.Fatal(err)
   715  		}
   716  	}
   717  }
   718  
   719  func TestReadFromTimeoutFluctuation(t *testing.T) {
   720  	t.Parallel()
   721  
   722  	switch runtime.GOOS {
   723  	case "plan9":
   724  		t.Skipf("not supported on %s", runtime.GOOS)
   725  	}
   726  
   727  	c1, err := newLocalPacketListener("udp")
   728  	if err != nil {
   729  		t.Fatal(err)
   730  	}
   731  	defer c1.Close()
   732  
   733  	c2, err := Dial(c1.LocalAddr().Network(), c1.LocalAddr().String())
   734  	if err != nil {
   735  		t.Fatal(err)
   736  	}
   737  	defer c2.Close()
   738  
   739  	max := time.NewTimer(time.Second)
   740  	defer max.Stop()
   741  	ch := make(chan error)
   742  	go timeoutPacketReceiver(c2.(PacketConn), 100*time.Millisecond, 50*time.Millisecond, 250*time.Millisecond, ch)
   743  
   744  	select {
   745  	case <-max.C:
   746  		t.Fatal("ReadFrom took over 1s; expected 0.1s")
   747  	case err := <-ch:
   748  		if perr := parseReadError(err); perr != nil {
   749  			t.Error(perr)
   750  		}
   751  		if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
   752  			t.Fatal(err)
   753  		}
   754  	}
   755  }
   756  
   757  func TestWriteTimeoutFluctuation(t *testing.T) {
   758  	t.Parallel()
   759  
   760  	switch runtime.GOOS {
   761  	case "plan9":
   762  		t.Skipf("not supported on %s", runtime.GOOS)
   763  	}
   764  
   765  	ln, err := newLocalListener("tcp")
   766  	if err != nil {
   767  		t.Fatal(err)
   768  	}
   769  	defer ln.Close()
   770  
   771  	c, err := Dial(ln.Addr().Network(), ln.Addr().String())
   772  	if err != nil {
   773  		t.Fatal(err)
   774  	}
   775  	defer c.Close()
   776  
   777  	d := time.Second
   778  	if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
   779  		d = 3 * time.Second // see golang.org/issue/10775
   780  	}
   781  	max := time.NewTimer(d)
   782  	defer max.Stop()
   783  	ch := make(chan error)
   784  	go timeoutTransmitter(c, 100*time.Millisecond, 50*time.Millisecond, 250*time.Millisecond, ch)
   785  
   786  	select {
   787  	case <-max.C:
   788  		t.Fatalf("Write took over %v; expected 0.1s", d)
   789  	case err := <-ch:
   790  		if perr := parseWriteError(err); perr != nil {
   791  			t.Error(perr)
   792  		}
   793  		if nerr, ok := err.(Error); !ok || !nerr.Timeout() {
   794  			t.Fatal(err)
   795  		}
   796  	}
   797  }
   798  
   799  func TestVariousDeadlines(t *testing.T) {
   800  	t.Parallel()
   801  	testVariousDeadlines(t)
   802  }
   803  
   804  func TestVariousDeadlines1Proc(t *testing.T) {
   805  	// Cannot use t.Parallel - modifies global GOMAXPROCS.
   806  	if testing.Short() {
   807  		t.Skip("skipping in short mode")
   808  	}
   809  	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1))
   810  	testVariousDeadlines(t)
   811  }
   812  
   813  func TestVariousDeadlines4Proc(t *testing.T) {
   814  	// Cannot use t.Parallel - modifies global GOMAXPROCS.
   815  	if testing.Short() {
   816  		t.Skip("skipping in short mode")
   817  	}
   818  	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
   819  	testVariousDeadlines(t)
   820  }
   821  
   822  type neverEnding byte
   823  
   824  func (b neverEnding) Read(p []byte) (int, error) {
   825  	for i := range p {
   826  		p[i] = byte(b)
   827  	}
   828  	return len(p), nil
   829  }
   830  
   831  func testVariousDeadlines(t *testing.T) {
   832  	switch runtime.GOOS {
   833  	case "plan9":
   834  		t.Skipf("not supported on %s", runtime.GOOS)
   835  	}
   836  
   837  	type result struct {
   838  		n   int64
   839  		err error
   840  		d   time.Duration
   841  	}
   842  
   843  	ch := make(chan error, 1)
   844  	pasvch := make(chan result)
   845  	handler := func(ls *localServer, ln Listener) {
   846  		for {
   847  			c, err := ln.Accept()
   848  			if err != nil {
   849  				ch <- err
   850  				return
   851  			}
   852  			// The server, with no timeouts of its own,
   853  			// sending bytes to clients as fast as it can.
   854  			go func() {
   855  				t0 := time.Now()
   856  				n, err := io.Copy(c, neverEnding('a'))
   857  				dt := time.Since(t0)
   858  				c.Close()
   859  				pasvch <- result{n, err, dt}
   860  			}()
   861  		}
   862  	}
   863  	ls, err := newLocalServer("tcp")
   864  	if err != nil {
   865  		t.Fatal(err)
   866  	}
   867  	defer ls.teardown()
   868  	if err := ls.buildup(handler); err != nil {
   869  		t.Fatal(err)
   870  	}
   871  
   872  	for _, timeout := range []time.Duration{
   873  		1 * time.Nanosecond,
   874  		2 * time.Nanosecond,
   875  		5 * time.Nanosecond,
   876  		50 * time.Nanosecond,
   877  		100 * time.Nanosecond,
   878  		200 * time.Nanosecond,
   879  		500 * time.Nanosecond,
   880  		750 * time.Nanosecond,
   881  		1 * time.Microsecond,
   882  		5 * time.Microsecond,
   883  		25 * time.Microsecond,
   884  		250 * time.Microsecond,
   885  		500 * time.Microsecond,
   886  		1 * time.Millisecond,
   887  		5 * time.Millisecond,
   888  		100 * time.Millisecond,
   889  		250 * time.Millisecond,
   890  		500 * time.Millisecond,
   891  		1 * time.Second,
   892  	} {
   893  		numRuns := 3
   894  		if testing.Short() {
   895  			numRuns = 1
   896  			if timeout > 500*time.Microsecond {
   897  				continue
   898  			}
   899  		}
   900  		for run := 0; run < numRuns; run++ {
   901  			name := fmt.Sprintf("%v run %d/%d", timeout, run+1, numRuns)
   902  			t.Log(name)
   903  
   904  			c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
   905  			if err != nil {
   906  				t.Fatal(err)
   907  			}
   908  
   909  			tooLong := 5 * time.Second
   910  			max := time.NewTimer(tooLong)
   911  			defer max.Stop()
   912  			actvch := make(chan result)
   913  			go func() {
   914  				t0 := time.Now()
   915  				if err := c.SetDeadline(t0.Add(timeout)); err != nil {
   916  					t.Error(err)
   917  				}
   918  				n, err := io.Copy(ioutil.Discard, c)
   919  				dt := time.Since(t0)
   920  				c.Close()
   921  				actvch <- result{n, err, dt}
   922  			}()
   923  
   924  			select {
   925  			case res := <-actvch:
   926  				if nerr, ok := res.err.(Error); ok && nerr.Timeout() {
   927  					t.Logf("for %v, good client timeout after %v, reading %d bytes", name, res.d, res.n)
   928  				} else {
   929  					t.Fatalf("for %v, client Copy = %d, %v; want timeout", name, res.n, res.err)
   930  				}
   931  			case <-max.C:
   932  				t.Fatalf("for %v, timeout (%v) waiting for client to timeout (%v) reading", name, tooLong, timeout)
   933  			}
   934  
   935  			select {
   936  			case res := <-pasvch:
   937  				t.Logf("for %v, server in %v wrote %d: %v", name, res.d, res.n, res.err)
   938  			case err := <-ch:
   939  				t.Fatalf("for %v, Accept = %v", name, err)
   940  			case <-max.C:
   941  				t.Fatalf("for %v, timeout waiting for server to finish writing", name)
   942  			}
   943  		}
   944  	}
   945  }
   946  
   947  // TestReadWriteProlongedTimeout tests concurrent deadline
   948  // modification. Known to cause data races in the past.
   949  func TestReadWriteProlongedTimeout(t *testing.T) {
   950  	t.Parallel()
   951  
   952  	switch runtime.GOOS {
   953  	case "plan9":
   954  		t.Skipf("not supported on %s", runtime.GOOS)
   955  	}
   956  
   957  	handler := func(ls *localServer, ln Listener) {
   958  		c, err := ln.Accept()
   959  		if err != nil {
   960  			t.Error(err)
   961  			return
   962  		}
   963  		defer c.Close()
   964  
   965  		var wg sync.WaitGroup
   966  		wg.Add(2)
   967  		go func() {
   968  			defer wg.Done()
   969  			var b [1]byte
   970  			for {
   971  				if err := c.SetReadDeadline(time.Now().Add(time.Hour)); err != nil {
   972  					if perr := parseCommonError(err); perr != nil {
   973  						t.Error(perr)
   974  					}
   975  					t.Error(err)
   976  					return
   977  				}
   978  				if _, err := c.Read(b[:]); err != nil {
   979  					if perr := parseReadError(err); perr != nil {
   980  						t.Error(perr)
   981  					}
   982  					return
   983  				}
   984  			}
   985  		}()
   986  		go func() {
   987  			defer wg.Done()
   988  			var b [1]byte
   989  			for {
   990  				if err := c.SetWriteDeadline(time.Now().Add(time.Hour)); err != nil {
   991  					if perr := parseCommonError(err); perr != nil {
   992  						t.Error(perr)
   993  					}
   994  					t.Error(err)
   995  					return
   996  				}
   997  				if _, err := c.Write(b[:]); err != nil {
   998  					if perr := parseWriteError(err); perr != nil {
   999  						t.Error(perr)
  1000  					}
  1001  					return
  1002  				}
  1003  			}
  1004  		}()
  1005  		wg.Wait()
  1006  	}
  1007  	ls, err := newLocalServer("tcp")
  1008  	if err != nil {
  1009  		t.Fatal(err)
  1010  	}
  1011  	defer ls.teardown()
  1012  	if err := ls.buildup(handler); err != nil {
  1013  		t.Fatal(err)
  1014  	}
  1015  
  1016  	c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
  1017  	if err != nil {
  1018  		t.Fatal(err)
  1019  	}
  1020  	defer c.Close()
  1021  
  1022  	var b [1]byte
  1023  	for i := 0; i < 1000; i++ {
  1024  		c.Write(b[:])
  1025  		c.Read(b[:])
  1026  	}
  1027  }
  1028  
  1029  func TestReadWriteDeadlineRace(t *testing.T) {
  1030  	t.Parallel()
  1031  
  1032  	switch runtime.GOOS {
  1033  	case "nacl", "plan9":
  1034  		t.Skipf("not supported on %s", runtime.GOOS)
  1035  	}
  1036  
  1037  	N := 1000
  1038  	if testing.Short() {
  1039  		N = 50
  1040  	}
  1041  
  1042  	ln, err := newLocalListener("tcp")
  1043  	if err != nil {
  1044  		t.Fatal(err)
  1045  	}
  1046  	defer ln.Close()
  1047  
  1048  	c, err := Dial(ln.Addr().Network(), ln.Addr().String())
  1049  	if err != nil {
  1050  		t.Fatal(err)
  1051  	}
  1052  	defer c.Close()
  1053  
  1054  	var wg sync.WaitGroup
  1055  	wg.Add(3)
  1056  	go func() {
  1057  		defer wg.Done()
  1058  		tic := time.NewTicker(2 * time.Microsecond)
  1059  		defer tic.Stop()
  1060  		for i := 0; i < N; i++ {
  1061  			if err := c.SetReadDeadline(time.Now().Add(2 * time.Microsecond)); err != nil {
  1062  				if perr := parseCommonError(err); perr != nil {
  1063  					t.Error(perr)
  1064  				}
  1065  				break
  1066  			}
  1067  			if err := c.SetWriteDeadline(time.Now().Add(2 * time.Microsecond)); err != nil {
  1068  				if perr := parseCommonError(err); perr != nil {
  1069  					t.Error(perr)
  1070  				}
  1071  				break
  1072  			}
  1073  			<-tic.C
  1074  		}
  1075  	}()
  1076  	go func() {
  1077  		defer wg.Done()
  1078  		var b [1]byte
  1079  		for i := 0; i < N; i++ {
  1080  			c.Read(b[:]) // ignore possible timeout errors
  1081  		}
  1082  	}()
  1083  	go func() {
  1084  		defer wg.Done()
  1085  		var b [1]byte
  1086  		for i := 0; i < N; i++ {
  1087  			c.Write(b[:]) // ignore possible timeout errors
  1088  		}
  1089  	}()
  1090  	wg.Wait() // wait for tester goroutine to stop
  1091  }