From: Dmitriy Vyukov Date: Sun, 25 Nov 2012 09:27:32 +0000 (+0400) Subject: net: add unit tests for read/write deadlines X-Git-Tag: go1.1rc2~1809 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=74fcf82dd9c551fb0e2c2f8c323bba5b91da60bf;p=gostls13.git net: add unit tests for read/write deadlines The tests verify that deadlines are "persistent", read/write deadlines do not interfere, can be reset, read deadline can be set with both SetDeadline() and SetReadDeadline(), etc. R=golang-dev, bradfitz, dave CC=golang-dev https://golang.org/cl/6850070 --- diff --git a/src/pkg/net/timeout_test.go b/src/pkg/net/timeout_test.go index b5b2fa2896..c72758dc06 100644 --- a/src/pkg/net/timeout_test.go +++ b/src/pkg/net/timeout_test.go @@ -24,6 +24,151 @@ type copyRes struct { d time.Duration } +func TestAcceptTimeout(t *testing.T) { + switch runtime.GOOS { + case "plan9": + t.Logf("skipping test on %q", runtime.GOOS) + return + } + + ln := newLocalListener(t).(*TCPListener) + defer ln.Close() + ln.SetDeadline(time.Now().Add(-1 * time.Second)) + if _, err := ln.Accept(); !isTimeout(err) { + t.Fatalf("Accept: expected err %v, got %v", errTimeout, err) + } + if _, err := ln.Accept(); !isTimeout(err) { + t.Fatalf("Accept: expected err %v, got %v", errTimeout, err) + } + ln.SetDeadline(time.Now().Add(100 * time.Millisecond)) + if _, err := ln.Accept(); !isTimeout(err) { + t.Fatalf("Accept: expected err %v, got %v", errTimeout, err) + } + if _, err := ln.Accept(); !isTimeout(err) { + t.Fatalf("Accept: expected err %v, got %v", errTimeout, err) + } + ln.SetDeadline(noDeadline) + errc := make(chan error) + go func() { + _, err := ln.Accept() + errc <- err + }() + time.Sleep(100 * time.Millisecond) + select { + case err := <-errc: + t.Fatalf("Expected Accept() to not return, but it returned with %v\n", err) + default: + } + ln.Close() + if err := <-errc; err.(*OpError).Err != errClosing { + t.Fatalf("Accept: expected err %v, got %v", errClosing, err.(*OpError).Err) + } +} + +func TestReadTimeout(t *testing.T) { + switch runtime.GOOS { + case "plan9": + t.Logf("skipping test on %q", runtime.GOOS) + return + } + + ln := newLocalListener(t) + defer ln.Close() + c, err := DialTCP("tcp", nil, ln.Addr().(*TCPAddr)) + if err != nil { + t.Fatalf("Connect: %v", err) + } + defer c.Close() + c.SetDeadline(time.Now().Add(time.Hour)) + c.SetReadDeadline(time.Now().Add(-1 * time.Second)) + buf := make([]byte, 1) + if _, err = c.Read(buf); !isTimeout(err) { + t.Fatalf("Read: expected err %v, got %v", errTimeout, err) + } + if _, err = c.Read(buf); !isTimeout(err) { + t.Fatalf("Read: expected err %v, got %v", errTimeout, err) + } + c.SetDeadline(time.Now().Add(100 * time.Millisecond)) + if _, err = c.Read(buf); !isTimeout(err) { + t.Fatalf("Read: expected err %v, got %v", errTimeout, err) + } + if _, err = c.Read(buf); !isTimeout(err) { + t.Fatalf("Read: expected err %v, got %v", errTimeout, err) + } + c.SetReadDeadline(noDeadline) + c.SetWriteDeadline(time.Now().Add(-1 * time.Second)) + errc := make(chan error) + go func() { + _, err := c.Read(buf) + errc <- err + }() + time.Sleep(100 * time.Millisecond) + select { + case err := <-errc: + t.Fatalf("Expected Read() to not return, but it returned with %v\n", err) + default: + } + c.Close() + if err := <-errc; err.(*OpError).Err != errClosing { + t.Fatalf("Read: expected err %v, got %v", errClosing, err.(*OpError).Err) + } +} + +func TestWriteTimeout(t *testing.T) { + switch runtime.GOOS { + case "plan9": + t.Logf("skipping test on %q", runtime.GOOS) + return + } + + ln := newLocalListener(t) + defer ln.Close() + c, err := DialTCP("tcp", nil, ln.Addr().(*TCPAddr)) + if err != nil { + t.Fatalf("Connect: %v", err) + } + defer c.Close() + c.SetDeadline(time.Now().Add(time.Hour)) + c.SetWriteDeadline(time.Now().Add(-1 * time.Second)) + buf := make([]byte, 4096) + writeUntilTimeout := func() { + for { + _, err := c.Write(buf) + if err != nil { + if isTimeout(err) { + return + } + t.Fatalf("Write: expected err %v, got %v", errTimeout, err) + } + } + } + writeUntilTimeout() + c.SetDeadline(time.Now().Add(10 * time.Millisecond)) + writeUntilTimeout() + writeUntilTimeout() + c.SetWriteDeadline(noDeadline) + c.SetReadDeadline(time.Now().Add(-1 * time.Second)) + errc := make(chan error) + go func() { + for { + _, err := c.Write(buf) + if err != nil { + errc <- err + } + } + }() + time.Sleep(100 * time.Millisecond) + select { + case err := <-errc: + t.Fatalf("Expected Write() to not return, but it returned with %v\n", err) + default: + } + c.Close() + if err := <-errc; err.(*OpError).Err != errClosing { + t.Fatalf("Write: expected err %v, got %v", errClosing, err.(*OpError).Err) + } +} + func testTimeout(t *testing.T, net, addr string, readFrom bool) { c, err := Dial(net, addr) if err != nil { @@ -117,7 +262,7 @@ func TestDeadlineReset(t *testing.T) { defer ln.Close() tl := ln.(*TCPListener) tl.SetDeadline(time.Now().Add(1 * time.Minute)) - tl.SetDeadline(time.Time{}) // reset it + tl.SetDeadline(noDeadline) // reset it errc := make(chan error, 1) go func() { _, err := ln.Accept()