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