github.com/rafaeltorres324/go/src@v0.0.0-20210519164414-9fdf653a9838/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  // +build !js
     6  
     7  package net
     8  
     9  import (
    10  	"errors"
    11  	"fmt"
    12  	"internal/testenv"
    13  	"io"
    14  	"net/internal/socktest"
    15  	"os"
    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{os.ErrDeadlineExceeded, os.ErrDeadlineExceeded}},
   152  
   153  	{50 * time.Millisecond, [2]error{nil, os.ErrDeadlineExceeded}},
   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 !isDeadlineExceeded(err) {
   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 !isDeadlineExceeded(err) {
   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{os.ErrDeadlineExceeded, os.ErrDeadlineExceeded}},
   306  
   307  	{50 * time.Millisecond, [2]error{nil, os.ErrDeadlineExceeded}},
   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 !isDeadlineExceeded(err) {
   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 nerr, ok := err.(Error); !ok || nerr.Timeout() || nerr.Temporary() {
   415  			t.Fatal(err)
   416  		}
   417  	}
   418  }
   419  
   420  var readFromTimeoutTests = []struct {
   421  	timeout time.Duration
   422  	xerrs   [2]error // expected errors in transition
   423  }{
   424  	// Tests that read deadlines work, even if there's data ready
   425  	// to be read.
   426  	{-5 * time.Second, [2]error{os.ErrDeadlineExceeded, os.ErrDeadlineExceeded}},
   427  
   428  	{50 * time.Millisecond, [2]error{nil, os.ErrDeadlineExceeded}},
   429  }
   430  
   431  func TestReadFromTimeout(t *testing.T) {
   432  	ch := make(chan Addr)
   433  	defer close(ch)
   434  	handler := func(ls *localPacketServer, c PacketConn) {
   435  		if dst, ok := <-ch; ok {
   436  			c.WriteTo([]byte("READFROM TIMEOUT TEST"), dst)
   437  		}
   438  	}
   439  	ls, err := newLocalPacketServer("udp")
   440  	if err != nil {
   441  		t.Fatal(err)
   442  	}
   443  	defer ls.teardown()
   444  	if err := ls.buildup(handler); err != nil {
   445  		t.Fatal(err)
   446  	}
   447  
   448  	host, _, err := SplitHostPort(ls.PacketConn.LocalAddr().String())
   449  	if err != nil {
   450  		t.Fatal(err)
   451  	}
   452  	c, err := ListenPacket(ls.PacketConn.LocalAddr().Network(), JoinHostPort(host, "0"))
   453  	if err != nil {
   454  		t.Fatal(err)
   455  	}
   456  	defer c.Close()
   457  	ch <- c.LocalAddr()
   458  
   459  	for i, tt := range readFromTimeoutTests {
   460  		if err := c.SetReadDeadline(time.Now().Add(tt.timeout)); err != nil {
   461  			t.Fatalf("#%d: %v", i, err)
   462  		}
   463  		var b [1]byte
   464  		for j, xerr := range tt.xerrs {
   465  			for {
   466  				n, _, err := c.ReadFrom(b[:])
   467  				if xerr != nil {
   468  					if perr := parseReadError(err); perr != nil {
   469  						t.Errorf("#%d/%d: %v", i, j, perr)
   470  					}
   471  					if !isDeadlineExceeded(err) {
   472  						t.Fatalf("#%d/%d: %v", i, j, err)
   473  					}
   474  				}
   475  				if err == nil {
   476  					time.Sleep(tt.timeout / 3)
   477  					continue
   478  				}
   479  				if nerr, ok := err.(Error); ok && nerr.Timeout() && n != 0 {
   480  					t.Fatalf("#%d/%d: read %d; want 0", i, j, n)
   481  				}
   482  				break
   483  			}
   484  		}
   485  	}
   486  }
   487  
   488  var writeTimeoutTests = []struct {
   489  	timeout time.Duration
   490  	xerrs   [2]error // expected errors in transition
   491  }{
   492  	// Tests that write deadlines work, even if there's buffer
   493  	// space available to write.
   494  	{-5 * time.Second, [2]error{os.ErrDeadlineExceeded, os.ErrDeadlineExceeded}},
   495  
   496  	{10 * time.Millisecond, [2]error{nil, os.ErrDeadlineExceeded}},
   497  }
   498  
   499  func TestWriteTimeout(t *testing.T) {
   500  	t.Parallel()
   501  
   502  	ln, err := newLocalListener("tcp")
   503  	if err != nil {
   504  		t.Fatal(err)
   505  	}
   506  	defer ln.Close()
   507  
   508  	for i, tt := range writeTimeoutTests {
   509  		c, err := Dial(ln.Addr().Network(), ln.Addr().String())
   510  		if err != nil {
   511  			t.Fatal(err)
   512  		}
   513  		defer c.Close()
   514  
   515  		if err := c.SetWriteDeadline(time.Now().Add(tt.timeout)); err != nil {
   516  			t.Fatalf("#%d: %v", i, err)
   517  		}
   518  		for j, xerr := range tt.xerrs {
   519  			for {
   520  				n, err := c.Write([]byte("WRITE TIMEOUT TEST"))
   521  				if xerr != nil {
   522  					if perr := parseWriteError(err); perr != nil {
   523  						t.Errorf("#%d/%d: %v", i, j, perr)
   524  					}
   525  					if !isDeadlineExceeded(err) {
   526  						t.Fatalf("#%d/%d: %v", i, j, err)
   527  					}
   528  				}
   529  				if err == nil {
   530  					time.Sleep(tt.timeout / 3)
   531  					continue
   532  				}
   533  				if n != 0 {
   534  					t.Fatalf("#%d/%d: wrote %d; want 0", i, j, n)
   535  				}
   536  				break
   537  			}
   538  		}
   539  	}
   540  }
   541  
   542  func TestWriteTimeoutMustNotReturn(t *testing.T) {
   543  	t.Parallel()
   544  
   545  	switch runtime.GOOS {
   546  	case "plan9":
   547  		t.Skipf("not supported on %s", runtime.GOOS)
   548  	}
   549  
   550  	ln, err := newLocalListener("tcp")
   551  	if err != nil {
   552  		t.Fatal(err)
   553  	}
   554  	defer ln.Close()
   555  
   556  	c, err := Dial(ln.Addr().Network(), ln.Addr().String())
   557  	if err != nil {
   558  		t.Fatal(err)
   559  	}
   560  	defer c.Close()
   561  
   562  	max := time.NewTimer(100 * time.Millisecond)
   563  	defer max.Stop()
   564  	ch := make(chan error)
   565  	go func() {
   566  		if err := c.SetDeadline(time.Now().Add(-5 * time.Second)); err != nil {
   567  			t.Error(err)
   568  		}
   569  		if err := c.SetReadDeadline(time.Now().Add(-5 * time.Second)); err != nil {
   570  			t.Error(err)
   571  		}
   572  		if err := c.SetWriteDeadline(noDeadline); err != nil {
   573  			t.Error(err)
   574  		}
   575  		var b [1]byte
   576  		for {
   577  			if _, err := c.Write(b[:]); err != nil {
   578  				ch <- err
   579  				break
   580  			}
   581  		}
   582  	}()
   583  
   584  	select {
   585  	case err := <-ch:
   586  		if perr := parseWriteError(err); perr != nil {
   587  			t.Error(perr)
   588  		}
   589  		t.Fatalf("expected Write to not return, but it returned with %v", err)
   590  	case <-max.C:
   591  		c.Close()
   592  		err := <-ch // wait for tester goroutine to stop
   593  		if perr := parseWriteError(err); perr != nil {
   594  			t.Error(perr)
   595  		}
   596  		if nerr, ok := err.(Error); !ok || nerr.Timeout() || nerr.Temporary() {
   597  			t.Fatal(err)
   598  		}
   599  	}
   600  }
   601  
   602  var writeToTimeoutTests = []struct {
   603  	timeout time.Duration
   604  	xerrs   [2]error // expected errors in transition
   605  }{
   606  	// Tests that write deadlines work, even if there's buffer
   607  	// space available to write.
   608  	{-5 * time.Second, [2]error{os.ErrDeadlineExceeded, os.ErrDeadlineExceeded}},
   609  
   610  	{10 * time.Millisecond, [2]error{nil, os.ErrDeadlineExceeded}},
   611  }
   612  
   613  func TestWriteToTimeout(t *testing.T) {
   614  	t.Parallel()
   615  
   616  	c1, err := newLocalPacketListener("udp")
   617  	if err != nil {
   618  		t.Fatal(err)
   619  	}
   620  	defer c1.Close()
   621  
   622  	host, _, err := SplitHostPort(c1.LocalAddr().String())
   623  	if err != nil {
   624  		t.Fatal(err)
   625  	}
   626  
   627  	for i, tt := range writeToTimeoutTests {
   628  		c2, err := ListenPacket(c1.LocalAddr().Network(), JoinHostPort(host, "0"))
   629  		if err != nil {
   630  			t.Fatal(err)
   631  		}
   632  		defer c2.Close()
   633  
   634  		if err := c2.SetWriteDeadline(time.Now().Add(tt.timeout)); err != nil {
   635  			t.Fatalf("#%d: %v", i, err)
   636  		}
   637  		for j, xerr := range tt.xerrs {
   638  			for {
   639  				n, err := c2.WriteTo([]byte("WRITETO TIMEOUT TEST"), c1.LocalAddr())
   640  				if xerr != nil {
   641  					if perr := parseWriteError(err); perr != nil {
   642  						t.Errorf("#%d/%d: %v", i, j, perr)
   643  					}
   644  					if !isDeadlineExceeded(err) {
   645  						t.Fatalf("#%d/%d: %v", i, j, err)
   646  					}
   647  				}
   648  				if err == nil {
   649  					time.Sleep(tt.timeout / 3)
   650  					continue
   651  				}
   652  				if n != 0 {
   653  					t.Fatalf("#%d/%d: wrote %d; want 0", i, j, n)
   654  				}
   655  				break
   656  			}
   657  		}
   658  	}
   659  }
   660  
   661  func TestReadTimeoutFluctuation(t *testing.T) {
   662  	t.Parallel()
   663  
   664  	ln, err := newLocalListener("tcp")
   665  	if err != nil {
   666  		t.Fatal(err)
   667  	}
   668  	defer ln.Close()
   669  
   670  	c, err := Dial(ln.Addr().Network(), ln.Addr().String())
   671  	if err != nil {
   672  		t.Fatal(err)
   673  	}
   674  	defer c.Close()
   675  
   676  	max := time.NewTimer(time.Second)
   677  	defer max.Stop()
   678  	ch := make(chan error)
   679  	go timeoutReceiver(c, 100*time.Millisecond, 50*time.Millisecond, 250*time.Millisecond, ch)
   680  
   681  	select {
   682  	case <-max.C:
   683  		t.Fatal("Read took over 1s; expected 0.1s")
   684  	case err := <-ch:
   685  		if perr := parseReadError(err); perr != nil {
   686  			t.Error(perr)
   687  		}
   688  		if !isDeadlineExceeded(err) {
   689  			t.Fatal(err)
   690  		}
   691  	}
   692  }
   693  
   694  func TestReadFromTimeoutFluctuation(t *testing.T) {
   695  	t.Parallel()
   696  
   697  	c1, err := newLocalPacketListener("udp")
   698  	if err != nil {
   699  		t.Fatal(err)
   700  	}
   701  	defer c1.Close()
   702  
   703  	c2, err := Dial(c1.LocalAddr().Network(), c1.LocalAddr().String())
   704  	if err != nil {
   705  		t.Fatal(err)
   706  	}
   707  	defer c2.Close()
   708  
   709  	max := time.NewTimer(time.Second)
   710  	defer max.Stop()
   711  	ch := make(chan error)
   712  	go timeoutPacketReceiver(c2.(PacketConn), 100*time.Millisecond, 50*time.Millisecond, 250*time.Millisecond, ch)
   713  
   714  	select {
   715  	case <-max.C:
   716  		t.Fatal("ReadFrom took over 1s; expected 0.1s")
   717  	case err := <-ch:
   718  		if perr := parseReadError(err); perr != nil {
   719  			t.Error(perr)
   720  		}
   721  		if !isDeadlineExceeded(err) {
   722  			t.Fatal(err)
   723  		}
   724  	}
   725  }
   726  
   727  func TestWriteTimeoutFluctuation(t *testing.T) {
   728  	t.Parallel()
   729  
   730  	switch runtime.GOOS {
   731  	case "plan9":
   732  		t.Skipf("not supported on %s", runtime.GOOS)
   733  	}
   734  
   735  	ln, err := newLocalListener("tcp")
   736  	if err != nil {
   737  		t.Fatal(err)
   738  	}
   739  	defer ln.Close()
   740  
   741  	c, err := Dial(ln.Addr().Network(), ln.Addr().String())
   742  	if err != nil {
   743  		t.Fatal(err)
   744  	}
   745  	defer c.Close()
   746  
   747  	d := time.Second
   748  	if iOS() {
   749  		d = 3 * time.Second // see golang.org/issue/10775
   750  	}
   751  	max := time.NewTimer(d)
   752  	defer max.Stop()
   753  	ch := make(chan error)
   754  	go timeoutTransmitter(c, 100*time.Millisecond, 50*time.Millisecond, 250*time.Millisecond, ch)
   755  
   756  	select {
   757  	case <-max.C:
   758  		t.Fatalf("Write took over %v; expected 0.1s", d)
   759  	case err := <-ch:
   760  		if perr := parseWriteError(err); perr != nil {
   761  			t.Error(perr)
   762  		}
   763  		if !isDeadlineExceeded(err) {
   764  			t.Fatal(err)
   765  		}
   766  	}
   767  }
   768  
   769  func TestVariousDeadlines(t *testing.T) {
   770  	t.Parallel()
   771  	testVariousDeadlines(t)
   772  }
   773  
   774  func TestVariousDeadlines1Proc(t *testing.T) {
   775  	// Cannot use t.Parallel - modifies global GOMAXPROCS.
   776  	if testing.Short() {
   777  		t.Skip("skipping in short mode")
   778  	}
   779  	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1))
   780  	testVariousDeadlines(t)
   781  }
   782  
   783  func TestVariousDeadlines4Proc(t *testing.T) {
   784  	// Cannot use t.Parallel - modifies global GOMAXPROCS.
   785  	if testing.Short() {
   786  		t.Skip("skipping in short mode")
   787  	}
   788  	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
   789  	testVariousDeadlines(t)
   790  }
   791  
   792  type neverEnding byte
   793  
   794  func (b neverEnding) Read(p []byte) (int, error) {
   795  	for i := range p {
   796  		p[i] = byte(b)
   797  	}
   798  	return len(p), nil
   799  }
   800  
   801  func testVariousDeadlines(t *testing.T) {
   802  	if runtime.GOOS == "plan9" {
   803  		t.Skip("skipping test on plan9; see golang.org/issue/26945")
   804  	}
   805  	type result struct {
   806  		n   int64
   807  		err error
   808  		d   time.Duration
   809  	}
   810  
   811  	handler := func(ls *localServer, ln Listener) {
   812  		for {
   813  			c, err := ln.Accept()
   814  			if err != nil {
   815  				break
   816  			}
   817  			c.Read(make([]byte, 1)) // wait for client to close connection
   818  			c.Close()
   819  		}
   820  	}
   821  	ls, err := newLocalServer("tcp")
   822  	if err != nil {
   823  		t.Fatal(err)
   824  	}
   825  	defer ls.teardown()
   826  	if err := ls.buildup(handler); err != nil {
   827  		t.Fatal(err)
   828  	}
   829  
   830  	for _, timeout := range []time.Duration{
   831  		1 * time.Nanosecond,
   832  		2 * time.Nanosecond,
   833  		5 * time.Nanosecond,
   834  		50 * time.Nanosecond,
   835  		100 * time.Nanosecond,
   836  		200 * time.Nanosecond,
   837  		500 * time.Nanosecond,
   838  		750 * time.Nanosecond,
   839  		1 * time.Microsecond,
   840  		5 * time.Microsecond,
   841  		25 * time.Microsecond,
   842  		250 * time.Microsecond,
   843  		500 * time.Microsecond,
   844  		1 * time.Millisecond,
   845  		5 * time.Millisecond,
   846  		100 * time.Millisecond,
   847  		250 * time.Millisecond,
   848  		500 * time.Millisecond,
   849  		1 * time.Second,
   850  	} {
   851  		numRuns := 3
   852  		if testing.Short() {
   853  			numRuns = 1
   854  			if timeout > 500*time.Microsecond {
   855  				continue
   856  			}
   857  		}
   858  		for run := 0; run < numRuns; run++ {
   859  			name := fmt.Sprintf("%v %d/%d", timeout, run, numRuns)
   860  			t.Log(name)
   861  
   862  			tooSlow := time.NewTimer(5 * time.Second)
   863  			defer tooSlow.Stop()
   864  
   865  			c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
   866  			if err != nil {
   867  				t.Fatal(err)
   868  			}
   869  
   870  			ch := make(chan result, 1)
   871  			go func() {
   872  				t0 := time.Now()
   873  				if err := c.SetDeadline(t0.Add(timeout)); err != nil {
   874  					t.Error(err)
   875  				}
   876  				n, err := io.Copy(io.Discard, c)
   877  				dt := time.Since(t0)
   878  				c.Close()
   879  				ch <- result{n, err, dt}
   880  			}()
   881  
   882  			select {
   883  			case res := <-ch:
   884  				if nerr, ok := res.err.(Error); ok && nerr.Timeout() {
   885  					t.Logf("%v: good timeout after %v; %d bytes", name, res.d, res.n)
   886  				} else {
   887  					t.Fatalf("%v: Copy = %d, %v; want timeout", name, res.n, res.err)
   888  				}
   889  			case <-tooSlow.C:
   890  				t.Fatalf("%v: client stuck in Dial+Copy", name)
   891  			}
   892  		}
   893  	}
   894  }
   895  
   896  // TestReadWriteProlongedTimeout tests concurrent deadline
   897  // modification. Known to cause data races in the past.
   898  func TestReadWriteProlongedTimeout(t *testing.T) {
   899  	t.Parallel()
   900  
   901  	switch runtime.GOOS {
   902  	case "plan9":
   903  		t.Skipf("not supported on %s", runtime.GOOS)
   904  	}
   905  
   906  	handler := func(ls *localServer, ln Listener) {
   907  		c, err := ln.Accept()
   908  		if err != nil {
   909  			t.Error(err)
   910  			return
   911  		}
   912  		defer c.Close()
   913  
   914  		var wg sync.WaitGroup
   915  		wg.Add(2)
   916  		go func() {
   917  			defer wg.Done()
   918  			var b [1]byte
   919  			for {
   920  				if err := c.SetReadDeadline(time.Now().Add(time.Hour)); err != nil {
   921  					if perr := parseCommonError(err); perr != nil {
   922  						t.Error(perr)
   923  					}
   924  					t.Error(err)
   925  					return
   926  				}
   927  				if _, err := c.Read(b[:]); err != nil {
   928  					if perr := parseReadError(err); perr != nil {
   929  						t.Error(perr)
   930  					}
   931  					return
   932  				}
   933  			}
   934  		}()
   935  		go func() {
   936  			defer wg.Done()
   937  			var b [1]byte
   938  			for {
   939  				if err := c.SetWriteDeadline(time.Now().Add(time.Hour)); err != nil {
   940  					if perr := parseCommonError(err); perr != nil {
   941  						t.Error(perr)
   942  					}
   943  					t.Error(err)
   944  					return
   945  				}
   946  				if _, err := c.Write(b[:]); err != nil {
   947  					if perr := parseWriteError(err); perr != nil {
   948  						t.Error(perr)
   949  					}
   950  					return
   951  				}
   952  			}
   953  		}()
   954  		wg.Wait()
   955  	}
   956  	ls, err := newLocalServer("tcp")
   957  	if err != nil {
   958  		t.Fatal(err)
   959  	}
   960  	defer ls.teardown()
   961  	if err := ls.buildup(handler); err != nil {
   962  		t.Fatal(err)
   963  	}
   964  
   965  	c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
   966  	if err != nil {
   967  		t.Fatal(err)
   968  	}
   969  	defer c.Close()
   970  
   971  	var b [1]byte
   972  	for i := 0; i < 1000; i++ {
   973  		c.Write(b[:])
   974  		c.Read(b[:])
   975  	}
   976  }
   977  
   978  func TestReadWriteDeadlineRace(t *testing.T) {
   979  	t.Parallel()
   980  
   981  	N := 1000
   982  	if testing.Short() {
   983  		N = 50
   984  	}
   985  
   986  	ln, err := newLocalListener("tcp")
   987  	if err != nil {
   988  		t.Fatal(err)
   989  	}
   990  	defer ln.Close()
   991  
   992  	c, err := Dial(ln.Addr().Network(), ln.Addr().String())
   993  	if err != nil {
   994  		t.Fatal(err)
   995  	}
   996  	defer c.Close()
   997  
   998  	var wg sync.WaitGroup
   999  	wg.Add(3)
  1000  	go func() {
  1001  		defer wg.Done()
  1002  		tic := time.NewTicker(2 * time.Microsecond)
  1003  		defer tic.Stop()
  1004  		for i := 0; i < N; i++ {
  1005  			if err := c.SetReadDeadline(time.Now().Add(2 * time.Microsecond)); err != nil {
  1006  				if perr := parseCommonError(err); perr != nil {
  1007  					t.Error(perr)
  1008  				}
  1009  				break
  1010  			}
  1011  			if err := c.SetWriteDeadline(time.Now().Add(2 * time.Microsecond)); err != nil {
  1012  				if perr := parseCommonError(err); perr != nil {
  1013  					t.Error(perr)
  1014  				}
  1015  				break
  1016  			}
  1017  			<-tic.C
  1018  		}
  1019  	}()
  1020  	go func() {
  1021  		defer wg.Done()
  1022  		var b [1]byte
  1023  		for i := 0; i < N; i++ {
  1024  			c.Read(b[:]) // ignore possible timeout errors
  1025  		}
  1026  	}()
  1027  	go func() {
  1028  		defer wg.Done()
  1029  		var b [1]byte
  1030  		for i := 0; i < N; i++ {
  1031  			c.Write(b[:]) // ignore possible timeout errors
  1032  		}
  1033  	}()
  1034  	wg.Wait() // wait for tester goroutine to stop
  1035  }
  1036  
  1037  // Issue 35367.
  1038  func TestConcurrentSetDeadline(t *testing.T) {
  1039  	ln, err := newLocalListener("tcp")
  1040  	if err != nil {
  1041  		t.Fatal(err)
  1042  	}
  1043  	defer ln.Close()
  1044  
  1045  	const goroutines = 8
  1046  	const conns = 10
  1047  	const tries = 100
  1048  
  1049  	var c [conns]Conn
  1050  	for i := 0; i < conns; i++ {
  1051  		c[i], err = Dial(ln.Addr().Network(), ln.Addr().String())
  1052  		if err != nil {
  1053  			t.Fatal(err)
  1054  		}
  1055  		defer c[i].Close()
  1056  	}
  1057  
  1058  	var wg sync.WaitGroup
  1059  	wg.Add(goroutines)
  1060  	now := time.Now()
  1061  	for i := 0; i < goroutines; i++ {
  1062  		go func(i int) {
  1063  			defer wg.Done()
  1064  			// Make the deadlines steadily earlier,
  1065  			// to trigger runtime adjusttimers calls.
  1066  			for j := tries; j > 0; j-- {
  1067  				for k := 0; k < conns; k++ {
  1068  					c[k].SetReadDeadline(now.Add(2*time.Hour + time.Duration(i*j*k)*time.Second))
  1069  					c[k].SetWriteDeadline(now.Add(1*time.Hour + time.Duration(i*j*k)*time.Second))
  1070  				}
  1071  			}
  1072  		}(i)
  1073  	}
  1074  	wg.Wait()
  1075  }
  1076  
  1077  // isDeadlineExceeded reports whether err is or wraps os.ErrDeadlineExceeded.
  1078  // We also check that the error implements net.Error, and that the
  1079  // Timeout method returns true.
  1080  func isDeadlineExceeded(err error) bool {
  1081  	nerr, ok := err.(Error)
  1082  	if !ok {
  1083  		return false
  1084  	}
  1085  	if !nerr.Timeout() {
  1086  		return false
  1087  	}
  1088  	if !errors.Is(err, os.ErrDeadlineExceeded) {
  1089  		return false
  1090  	}
  1091  	return true
  1092  }