...

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

View as plain text