diff options
Diffstat (limited to 'src/pkg/net/timeout_test.go')
-rw-r--r-- | src/pkg/net/timeout_test.go | 747 |
1 files changed, 0 insertions, 747 deletions
diff --git a/src/pkg/net/timeout_test.go b/src/pkg/net/timeout_test.go deleted file mode 100644 index 9ef0c4d15..000000000 --- a/src/pkg/net/timeout_test.go +++ /dev/null @@ -1,747 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package net - -import ( - "fmt" - "io" - "io/ioutil" - "runtime" - "testing" - "time" -) - -func isTimeout(err error) bool { - e, ok := err.(Error) - return ok && e.Timeout() -} - -type copyRes struct { - n int64 - err error - d time.Duration -} - -func TestAcceptTimeout(t *testing.T) { - switch runtime.GOOS { - case "plan9": - t.Skipf("skipping test on %q", runtime.GOOS) - } - - 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() - switch nerr := <-errc; err := nerr.(type) { - case *OpError: - if err.Err != errClosing { - t.Fatalf("Accept: expected err %v, got %v", errClosing, err) - } - default: - if err != errClosing { - t.Fatalf("Accept: expected err %v, got %v", errClosing, err) - } - } -} - -func TestReadTimeout(t *testing.T) { - switch runtime.GOOS { - case "plan9": - t.Skipf("skipping test on %q", runtime.GOOS) - } - - 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() - switch nerr := <-errc; err := nerr.(type) { - case *OpError: - if err.Err != errClosing { - t.Fatalf("Read: expected err %v, got %v", errClosing, err) - } - default: - if err == io.EOF && runtime.GOOS == "nacl" { // close enough; golang.org/issue/8044 - break - } - if err != errClosing { - t.Fatalf("Read: expected err %v, got %v", errClosing, err) - } - } -} - -func TestWriteTimeout(t *testing.T) { - switch runtime.GOOS { - case "plan9": - t.Skipf("skipping test on %q", runtime.GOOS) - } - - 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() - switch nerr := <-errc; err := nerr.(type) { - case *OpError: - if err.Err != errClosing { - t.Fatalf("Write: expected err %v, got %v", errClosing, err) - } - default: - if err != errClosing { - t.Fatalf("Write: expected err %v, got %v", errClosing, err) - } - } -} - -func testTimeout(t *testing.T, net, addr string, readFrom bool) { - c, err := Dial(net, addr) - if err != nil { - t.Errorf("Dial(%q, %q) failed: %v", net, addr, err) - return - } - defer c.Close() - what := "Read" - if readFrom { - what = "ReadFrom" - } - - errc := make(chan error, 1) - go func() { - t0 := time.Now() - c.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) - var b [100]byte - var n int - var err error - if readFrom { - n, _, err = c.(PacketConn).ReadFrom(b[0:]) - } else { - n, err = c.Read(b[0:]) - } - t1 := time.Now() - if n != 0 || err == nil || !err.(Error).Timeout() { - errc <- fmt.Errorf("%s(%q, %q) did not return 0, timeout: %v, %v", what, net, addr, n, err) - return - } - if dt := t1.Sub(t0); dt < 50*time.Millisecond || !testing.Short() && dt > 250*time.Millisecond { - errc <- fmt.Errorf("%s(%q, %q) took %s, expected 0.1s", what, net, addr, dt) - return - } - errc <- nil - }() - select { - case err := <-errc: - if err != nil { - t.Error(err) - } - case <-time.After(1 * time.Second): - t.Errorf("%s(%q, %q) took over 1 second, expected 0.1s", what, net, addr) - } -} - -func TestTimeoutUDP(t *testing.T) { - switch runtime.GOOS { - case "plan9": - t.Skipf("skipping test on %q", runtime.GOOS) - } - - // set up a listener that won't talk back - listening := make(chan string) - done := make(chan int) - go runDatagramPacketConnServer(t, "udp", "127.0.0.1:0", listening, done) - addr := <-listening - - testTimeout(t, "udp", addr, false) - testTimeout(t, "udp", addr, true) - <-done -} - -func TestTimeoutTCP(t *testing.T) { - switch runtime.GOOS { - case "plan9": - t.Skipf("skipping test on %q", runtime.GOOS) - } - - // set up a listener that won't talk back - listening := make(chan string) - done := make(chan int) - go runStreamConnServer(t, "tcp", "127.0.0.1:0", listening, done) - addr := <-listening - - testTimeout(t, "tcp", addr, false) - <-done -} - -func TestDeadlineReset(t *testing.T) { - switch runtime.GOOS { - case "plan9": - t.Skipf("skipping test on %q", runtime.GOOS) - } - ln, err := Listen("tcp", "127.0.0.1:0") - if err != nil { - t.Fatal(err) - } - defer ln.Close() - tl := ln.(*TCPListener) - tl.SetDeadline(time.Now().Add(1 * time.Minute)) - tl.SetDeadline(noDeadline) // reset it - errc := make(chan error, 1) - go func() { - _, err := ln.Accept() - errc <- err - }() - select { - case <-time.After(50 * time.Millisecond): - // Pass. - case err := <-errc: - // Accept should never return; we never - // connected to it. - t.Errorf("unexpected return from Accept; err=%v", err) - } -} - -func TestTimeoutAccept(t *testing.T) { - switch runtime.GOOS { - case "plan9": - t.Skipf("skipping test on %q", runtime.GOOS) - } - ln, err := Listen("tcp", "127.0.0.1:0") - if err != nil { - t.Fatal(err) - } - defer ln.Close() - tl := ln.(*TCPListener) - tl.SetDeadline(time.Now().Add(100 * time.Millisecond)) - errc := make(chan error, 1) - go func() { - _, err := ln.Accept() - errc <- err - }() - select { - case <-time.After(1 * time.Second): - // Accept shouldn't block indefinitely - t.Errorf("Accept didn't return in an expected time") - case <-errc: - // Pass. - } -} - -func TestReadWriteDeadline(t *testing.T) { - switch runtime.GOOS { - case "plan9": - t.Skipf("skipping test on %q", runtime.GOOS) - } - - const ( - readTimeout = 50 * time.Millisecond - writeTimeout = 250 * time.Millisecond - ) - checkTimeout := func(command string, start time.Time, should time.Duration) { - is := time.Now().Sub(start) - d := is - should - if d < -30*time.Millisecond || !testing.Short() && 150*time.Millisecond < d { - t.Errorf("%s timeout test failed: is=%v should=%v\n", command, is, should) - } - } - - ln, err := Listen("tcp", "127.0.0.1:0") - if err != nil { - t.Fatalf("ListenTCP on :0: %v", err) - } - defer ln.Close() - - lnquit := make(chan bool) - - go func() { - c, err := ln.Accept() - if err != nil { - t.Errorf("Accept: %v", err) - return - } - defer c.Close() - lnquit <- true - }() - - c, err := Dial("tcp", ln.Addr().String()) - if err != nil { - t.Fatalf("Dial: %v", err) - } - defer c.Close() - - start := time.Now() - err = c.SetReadDeadline(start.Add(readTimeout)) - if err != nil { - t.Fatalf("SetReadDeadline: %v", err) - } - err = c.SetWriteDeadline(start.Add(writeTimeout)) - if err != nil { - t.Fatalf("SetWriteDeadline: %v", err) - } - - quit := make(chan bool) - - go func() { - var buf [10]byte - _, err := c.Read(buf[:]) - if err == nil { - t.Errorf("Read should not succeed") - } - checkTimeout("Read", start, readTimeout) - quit <- true - }() - - go func() { - var buf [10000]byte - for { - _, err := c.Write(buf[:]) - if err != nil { - break - } - } - checkTimeout("Write", start, writeTimeout) - quit <- true - }() - - <-quit - <-quit - <-lnquit -} - -type neverEnding byte - -func (b neverEnding) Read(p []byte) (n int, err error) { - for i := range p { - p[i] = byte(b) - } - return len(p), nil -} - -func TestVariousDeadlines1Proc(t *testing.T) { - testVariousDeadlines(t, 1) -} - -func TestVariousDeadlines4Proc(t *testing.T) { - testVariousDeadlines(t, 4) -} - -func testVariousDeadlines(t *testing.T, maxProcs int) { - switch runtime.GOOS { - case "plan9": - t.Skipf("skipping test on %q", runtime.GOOS) - } - - defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs)) - ln := newLocalListener(t) - defer ln.Close() - acceptc := make(chan error, 1) - - // The server, with no timeouts of its own, sending bytes to clients - // as fast as it can. - servec := make(chan copyRes) - go func() { - for { - c, err := ln.Accept() - if err != nil { - acceptc <- err - return - } - go func() { - t0 := time.Now() - n, err := io.Copy(c, neverEnding('a')) - d := time.Since(t0) - c.Close() - servec <- copyRes{n, err, d} - }() - } - }() - - for _, timeout := range []time.Duration{ - 1 * time.Nanosecond, - 2 * time.Nanosecond, - 5 * time.Nanosecond, - 50 * time.Nanosecond, - 100 * time.Nanosecond, - 200 * time.Nanosecond, - 500 * time.Nanosecond, - 750 * time.Nanosecond, - 1 * time.Microsecond, - 5 * time.Microsecond, - 25 * time.Microsecond, - 250 * time.Microsecond, - 500 * time.Microsecond, - 1 * time.Millisecond, - 5 * time.Millisecond, - 100 * time.Millisecond, - 250 * time.Millisecond, - 500 * time.Millisecond, - 1 * time.Second, - } { - numRuns := 3 - if testing.Short() { - numRuns = 1 - if timeout > 500*time.Microsecond { - continue - } - } - for run := 0; run < numRuns; run++ { - name := fmt.Sprintf("%v run %d/%d", timeout, run+1, numRuns) - t.Log(name) - - c, err := Dial("tcp", ln.Addr().String()) - if err != nil { - t.Fatalf("Dial: %v", err) - } - clientc := make(chan copyRes) - go func() { - t0 := time.Now() - c.SetDeadline(t0.Add(timeout)) - n, err := io.Copy(ioutil.Discard, c) - d := time.Since(t0) - c.Close() - clientc <- copyRes{n, err, d} - }() - - tooLong := 5 * time.Second - select { - case res := <-clientc: - if isTimeout(res.err) { - t.Logf("for %v, good client timeout after %v, reading %d bytes", name, res.d, res.n) - } else { - t.Fatalf("for %v: client Copy = %d, %v (want timeout)", name, res.n, res.err) - } - case <-time.After(tooLong): - t.Fatalf("for %v: timeout (%v) waiting for client to timeout (%v) reading", name, tooLong, timeout) - } - - select { - case res := <-servec: - t.Logf("for %v: server in %v wrote %d, %v", name, res.d, res.n, res.err) - case err := <-acceptc: - t.Fatalf("for %v: server Accept = %v", name, err) - case <-time.After(tooLong): - t.Fatalf("for %v, timeout waiting for server to finish writing", name) - } - } - } -} - -// TestReadDeadlineDataAvailable tests that read deadlines work, even -// if there's data ready to be read. -func TestReadDeadlineDataAvailable(t *testing.T) { - switch runtime.GOOS { - case "plan9": - t.Skipf("skipping test on %q", runtime.GOOS) - } - - ln := newLocalListener(t) - defer ln.Close() - - servec := make(chan copyRes) - const msg = "data client shouldn't read, even though it'll be waiting" - go func() { - c, err := ln.Accept() - if err != nil { - t.Errorf("Accept: %v", err) - return - } - defer c.Close() - n, err := c.Write([]byte(msg)) - servec <- copyRes{n: int64(n), err: err} - }() - - c, err := Dial("tcp", ln.Addr().String()) - if err != nil { - t.Fatalf("Dial: %v", err) - } - defer c.Close() - if res := <-servec; res.err != nil || res.n != int64(len(msg)) { - t.Fatalf("unexpected server Write: n=%d, err=%v; want n=%d, err=nil", res.n, res.err, len(msg)) - } - c.SetReadDeadline(time.Now().Add(-5 * time.Second)) // in the psat. - buf := make([]byte, len(msg)/2) - n, err := c.Read(buf) - if n > 0 || !isTimeout(err) { - t.Fatalf("client read = %d (%q) err=%v; want 0, timeout", n, buf[:n], err) - } -} - -// TestWriteDeadlineBufferAvailable tests that write deadlines work, even -// if there's buffer space available to write. -func TestWriteDeadlineBufferAvailable(t *testing.T) { - switch runtime.GOOS { - case "plan9": - t.Skipf("skipping test on %q", runtime.GOOS) - } - - ln := newLocalListener(t) - defer ln.Close() - - servec := make(chan copyRes) - go func() { - c, err := ln.Accept() - if err != nil { - t.Errorf("Accept: %v", err) - return - } - defer c.Close() - c.SetWriteDeadline(time.Now().Add(-5 * time.Second)) // in the past - n, err := c.Write([]byte{'x'}) - servec <- copyRes{n: int64(n), err: err} - }() - - c, err := Dial("tcp", ln.Addr().String()) - if err != nil { - t.Fatalf("Dial: %v", err) - } - defer c.Close() - res := <-servec - if res.n != 0 { - t.Errorf("Write = %d; want 0", res.n) - } - if !isTimeout(res.err) { - t.Errorf("Write error = %v; want timeout", res.err) - } -} - -// TestAcceptDeadlineConnectionAvailable tests that accept deadlines work, even -// if there's incoming connections available. -func TestAcceptDeadlineConnectionAvailable(t *testing.T) { - switch runtime.GOOS { - case "plan9": - t.Skipf("skipping test on %q", runtime.GOOS) - } - - ln := newLocalListener(t).(*TCPListener) - defer ln.Close() - - go func() { - c, err := Dial("tcp", ln.Addr().String()) - if err != nil { - t.Errorf("Dial: %v", err) - return - } - defer c.Close() - var buf [1]byte - c.Read(buf[:]) // block until the connection or listener is closed - }() - time.Sleep(10 * time.Millisecond) - ln.SetDeadline(time.Now().Add(-5 * time.Second)) // in the past - c, err := ln.Accept() - if err == nil { - defer c.Close() - } - if !isTimeout(err) { - t.Fatalf("Accept: got %v; want timeout", err) - } -} - -// TestConnectDeadlineInThePast tests that connect deadlines work, even -// if the connection can be established w/o blocking. -func TestConnectDeadlineInThePast(t *testing.T) { - switch runtime.GOOS { - case "plan9": - t.Skipf("skipping test on %q", runtime.GOOS) - } - - ln := newLocalListener(t).(*TCPListener) - defer ln.Close() - - go func() { - c, err := ln.Accept() - if err == nil { - defer c.Close() - } - }() - time.Sleep(10 * time.Millisecond) - c, err := DialTimeout("tcp", ln.Addr().String(), -5*time.Second) // in the past - if err == nil { - defer c.Close() - } - if !isTimeout(err) { - t.Fatalf("DialTimeout: got %v; want timeout", err) - } -} - -// TestProlongTimeout tests concurrent deadline modification. -// Known to cause data races in the past. -func TestProlongTimeout(t *testing.T) { - switch runtime.GOOS { - case "plan9": - t.Skipf("skipping test on %q", runtime.GOOS) - } - - ln := newLocalListener(t) - defer ln.Close() - connected := make(chan bool) - go func() { - s, err := ln.Accept() - connected <- true - if err != nil { - t.Errorf("ln.Accept: %v", err) - return - } - defer s.Close() - s.SetDeadline(time.Now().Add(time.Hour)) - go func() { - var buf [4096]byte - for { - _, err := s.Write(buf[:]) - if err != nil { - break - } - s.SetDeadline(time.Now().Add(time.Hour)) - } - }() - buf := make([]byte, 1) - for { - _, err := s.Read(buf) - if err != nil { - break - } - s.SetDeadline(time.Now().Add(time.Hour)) - } - }() - c, err := Dial("tcp", ln.Addr().String()) - if err != nil { - t.Fatalf("DialTCP: %v", err) - } - defer c.Close() - <-connected - for i := 0; i < 1024; i++ { - var buf [1]byte - c.Write(buf[:]) - } -} - -func TestDeadlineRace(t *testing.T) { - switch runtime.GOOS { - case "nacl", "plan9": - t.Skipf("skipping test on %q", runtime.GOOS) - } - - N := 1000 - if testing.Short() { - N = 50 - } - defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4)) - ln := newLocalListener(t) - defer ln.Close() - c, err := Dial("tcp", ln.Addr().String()) - if err != nil { - t.Fatalf("Dial: %v", err) - } - defer c.Close() - done := make(chan bool) - go func() { - t := time.NewTicker(2 * time.Microsecond).C - for i := 0; i < N; i++ { - if err := c.SetDeadline(time.Now().Add(2 * time.Microsecond)); err != nil { - break - } - <-t - } - done <- true - }() - var buf [1]byte - for i := 0; i < N; i++ { - c.Read(buf[:]) // ignore possible timeout errors - } - c.Close() - <-done -} |