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

View as plain text