...
Run Format

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  	type result struct {
   816  		n   int64
   817  		err error
   818  		d   time.Duration
   819  	}
   820  
   821  	ch := make(chan error, 1)
   822  	pasvch := make(chan result)
   823  	handler := func(ls *localServer, ln Listener) {
   824  		for {
   825  			c, err := ln.Accept()
   826  			if err != nil {
   827  				ch <- err
   828  				return
   829  			}
   830  			// The server, with no timeouts of its own,
   831  			// sending bytes to clients as fast as it can.
   832  			go func() {
   833  				t0 := time.Now()
   834  				n, err := io.Copy(c, neverEnding('a'))
   835  				dt := time.Since(t0)
   836  				c.Close()
   837  				pasvch <- result{n, err, dt}
   838  			}()
   839  		}
   840  	}
   841  	ls, err := newLocalServer("tcp")
   842  	if err != nil {
   843  		t.Fatal(err)
   844  	}
   845  	defer ls.teardown()
   846  	if err := ls.buildup(handler); err != nil {
   847  		t.Fatal(err)
   848  	}
   849  
   850  	for _, timeout := range []time.Duration{
   851  		1 * time.Nanosecond,
   852  		2 * time.Nanosecond,
   853  		5 * time.Nanosecond,
   854  		50 * time.Nanosecond,
   855  		100 * time.Nanosecond,
   856  		200 * time.Nanosecond,
   857  		500 * time.Nanosecond,
   858  		750 * time.Nanosecond,
   859  		1 * time.Microsecond,
   860  		5 * time.Microsecond,
   861  		25 * time.Microsecond,
   862  		250 * time.Microsecond,
   863  		500 * time.Microsecond,
   864  		1 * time.Millisecond,
   865  		5 * time.Millisecond,
   866  		100 * time.Millisecond,
   867  		250 * time.Millisecond,
   868  		500 * time.Millisecond,
   869  		1 * time.Second,
   870  	} {
   871  		numRuns := 3
   872  		if testing.Short() {
   873  			numRuns = 1
   874  			if timeout > 500*time.Microsecond {
   875  				continue
   876  			}
   877  		}
   878  		for run := 0; run < numRuns; run++ {
   879  			name := fmt.Sprintf("%v run %d/%d", timeout, run+1, numRuns)
   880  			t.Log(name)
   881  
   882  			c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
   883  			if err != nil {
   884  				t.Fatal(err)
   885  			}
   886  
   887  			tooLong := 5 * time.Second
   888  			max := time.NewTimer(tooLong)
   889  			defer max.Stop()
   890  			actvch := make(chan result)
   891  			go func() {
   892  				t0 := time.Now()
   893  				if err := c.SetDeadline(t0.Add(timeout)); err != nil {
   894  					t.Error(err)
   895  				}
   896  				n, err := io.Copy(ioutil.Discard, c)
   897  				dt := time.Since(t0)
   898  				c.Close()
   899  				actvch <- result{n, err, dt}
   900  			}()
   901  
   902  			select {
   903  			case res := <-actvch:
   904  				if nerr, ok := res.err.(Error); ok && nerr.Timeout() {
   905  					t.Logf("for %v, good client timeout after %v, reading %d bytes", name, res.d, res.n)
   906  				} else {
   907  					t.Fatalf("for %v, client Copy = %d, %v; want timeout", name, res.n, res.err)
   908  				}
   909  			case <-max.C:
   910  				t.Fatalf("for %v, timeout (%v) waiting for client to timeout (%v) reading", name, tooLong, timeout)
   911  			}
   912  
   913  			select {
   914  			case res := <-pasvch:
   915  				t.Logf("for %v, server in %v wrote %d: %v", name, res.d, res.n, res.err)
   916  			case err := <-ch:
   917  				t.Fatalf("for %v, Accept = %v", name, err)
   918  			case <-max.C:
   919  				t.Fatalf("for %v, timeout waiting for server to finish writing", name)
   920  			}
   921  		}
   922  	}
   923  }
   924  
   925  // TestReadWriteProlongedTimeout tests concurrent deadline
   926  // modification. Known to cause data races in the past.
   927  func TestReadWriteProlongedTimeout(t *testing.T) {
   928  	t.Parallel()
   929  
   930  	switch runtime.GOOS {
   931  	case "plan9":
   932  		t.Skipf("not supported on %s", runtime.GOOS)
   933  	}
   934  
   935  	handler := func(ls *localServer, ln Listener) {
   936  		c, err := ln.Accept()
   937  		if err != nil {
   938  			t.Error(err)
   939  			return
   940  		}
   941  		defer c.Close()
   942  
   943  		var wg sync.WaitGroup
   944  		wg.Add(2)
   945  		go func() {
   946  			defer wg.Done()
   947  			var b [1]byte
   948  			for {
   949  				if err := c.SetReadDeadline(time.Now().Add(time.Hour)); err != nil {
   950  					if perr := parseCommonError(err); perr != nil {
   951  						t.Error(perr)
   952  					}
   953  					t.Error(err)
   954  					return
   955  				}
   956  				if _, err := c.Read(b[:]); err != nil {
   957  					if perr := parseReadError(err); perr != nil {
   958  						t.Error(perr)
   959  					}
   960  					return
   961  				}
   962  			}
   963  		}()
   964  		go func() {
   965  			defer wg.Done()
   966  			var b [1]byte
   967  			for {
   968  				if err := c.SetWriteDeadline(time.Now().Add(time.Hour)); err != nil {
   969  					if perr := parseCommonError(err); perr != nil {
   970  						t.Error(perr)
   971  					}
   972  					t.Error(err)
   973  					return
   974  				}
   975  				if _, err := c.Write(b[:]); err != nil {
   976  					if perr := parseWriteError(err); perr != nil {
   977  						t.Error(perr)
   978  					}
   979  					return
   980  				}
   981  			}
   982  		}()
   983  		wg.Wait()
   984  	}
   985  	ls, err := newLocalServer("tcp")
   986  	if err != nil {
   987  		t.Fatal(err)
   988  	}
   989  	defer ls.teardown()
   990  	if err := ls.buildup(handler); err != nil {
   991  		t.Fatal(err)
   992  	}
   993  
   994  	c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
   995  	if err != nil {
   996  		t.Fatal(err)
   997  	}
   998  	defer c.Close()
   999  
  1000  	var b [1]byte
  1001  	for i := 0; i < 1000; i++ {
  1002  		c.Write(b[:])
  1003  		c.Read(b[:])
  1004  	}
  1005  }
  1006  
  1007  func TestReadWriteDeadlineRace(t *testing.T) {
  1008  	t.Parallel()
  1009  
  1010  	switch runtime.GOOS {
  1011  	case "nacl":
  1012  		t.Skipf("not supported on %s", runtime.GOOS)
  1013  	}
  1014  
  1015  	N := 1000
  1016  	if testing.Short() {
  1017  		N = 50
  1018  	}
  1019  
  1020  	ln, err := newLocalListener("tcp")
  1021  	if err != nil {
  1022  		t.Fatal(err)
  1023  	}
  1024  	defer ln.Close()
  1025  
  1026  	c, err := Dial(ln.Addr().Network(), ln.Addr().String())
  1027  	if err != nil {
  1028  		t.Fatal(err)
  1029  	}
  1030  	defer c.Close()
  1031  
  1032  	var wg sync.WaitGroup
  1033  	wg.Add(3)
  1034  	go func() {
  1035  		defer wg.Done()
  1036  		tic := time.NewTicker(2 * time.Microsecond)
  1037  		defer tic.Stop()
  1038  		for i := 0; i < N; i++ {
  1039  			if err := c.SetReadDeadline(time.Now().Add(2 * time.Microsecond)); err != nil {
  1040  				if perr := parseCommonError(err); perr != nil {
  1041  					t.Error(perr)
  1042  				}
  1043  				break
  1044  			}
  1045  			if err := c.SetWriteDeadline(time.Now().Add(2 * time.Microsecond)); err != nil {
  1046  				if perr := parseCommonError(err); perr != nil {
  1047  					t.Error(perr)
  1048  				}
  1049  				break
  1050  			}
  1051  			<-tic.C
  1052  		}
  1053  	}()
  1054  	go func() {
  1055  		defer wg.Done()
  1056  		var b [1]byte
  1057  		for i := 0; i < N; i++ {
  1058  			c.Read(b[:]) // ignore possible timeout errors
  1059  		}
  1060  	}()
  1061  	go func() {
  1062  		defer wg.Done()
  1063  		var b [1]byte
  1064  		for i := 0; i < N; i++ {
  1065  			c.Write(b[:]) // ignore possible timeout errors
  1066  		}
  1067  	}()
  1068  	wg.Wait() // wait for tester goroutine to stop
  1069  }
  1070  

View as plain text