summaryrefslogtreecommitdiff
path: root/libgo/go/net/sendfile_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/net/sendfile_test.go')
-rw-r--r--libgo/go/net/sendfile_test.go126
1 files changed, 115 insertions, 11 deletions
diff --git a/libgo/go/net/sendfile_test.go b/libgo/go/net/sendfile_test.go
index 3b982774b02..911e6139c57 100644
--- a/libgo/go/net/sendfile_test.go
+++ b/libgo/go/net/sendfile_test.go
@@ -12,14 +12,18 @@ import (
"encoding/hex"
"fmt"
"io"
+ "io/ioutil"
"os"
+ "runtime"
+ "sync"
"testing"
+ "time"
)
const (
- twain = "testdata/Mark.Twain-Tom.Sawyer.txt"
- twainLen = 387851
- twainSHA256 = "461eb7cb2d57d293fc680c836464c9125e4382be3596f7d415093ae9db8fcb0e"
+ newton = "../testdata/Isaac.Newton-Opticks.txt"
+ newtonLen = 567198
+ newtonSHA256 = "d4a9ac22462b35e7821a4f2706c211093da678620a8f9997989ee7cf8d507bbd"
)
func TestSendfile(t *testing.T) {
@@ -43,7 +47,7 @@ func TestSendfile(t *testing.T) {
defer close(errc)
defer conn.Close()
- f, err := os.Open(twain)
+ f, err := os.Open(newton)
if err != nil {
errc <- err
return
@@ -58,8 +62,8 @@ func TestSendfile(t *testing.T) {
return
}
- if sbytes != twainLen {
- errc <- fmt.Errorf("sent %d bytes; expected %d", sbytes, twainLen)
+ if sbytes != newtonLen {
+ errc <- fmt.Errorf("sent %d bytes; expected %d", sbytes, newtonLen)
return
}
}()
@@ -79,11 +83,11 @@ func TestSendfile(t *testing.T) {
t.Error(err)
}
- if rbytes != twainLen {
- t.Errorf("received %d bytes; expected %d", rbytes, twainLen)
+ if rbytes != newtonLen {
+ t.Errorf("received %d bytes; expected %d", rbytes, newtonLen)
}
- if res := hex.EncodeToString(h.Sum(nil)); res != twainSHA256 {
+ if res := hex.EncodeToString(h.Sum(nil)); res != newtonSHA256 {
t.Error("retrieved data hash did not match")
}
@@ -113,7 +117,7 @@ func TestSendfileParts(t *testing.T) {
defer close(errc)
defer conn.Close()
- f, err := os.Open(twain)
+ f, err := os.Open(newton)
if err != nil {
errc <- err
return
@@ -174,7 +178,7 @@ func TestSendfileSeeked(t *testing.T) {
defer close(errc)
defer conn.Close()
- f, err := os.Open(twain)
+ f, err := os.Open(newton)
if err != nil {
errc <- err
return
@@ -210,3 +214,103 @@ func TestSendfileSeeked(t *testing.T) {
t.Error(err)
}
}
+
+// Test that sendfile doesn't put a pipe into blocking mode.
+func TestSendfilePipe(t *testing.T) {
+ switch runtime.GOOS {
+ case "nacl", "plan9", "windows":
+ // These systems don't support deadlines on pipes.
+ t.Skipf("skipping on %s", runtime.GOOS)
+ }
+
+ t.Parallel()
+
+ ln, err := newLocalListener("tcp")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer ln.Close()
+
+ r, w, err := os.Pipe()
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer w.Close()
+ defer r.Close()
+
+ copied := make(chan bool)
+
+ var wg sync.WaitGroup
+ wg.Add(1)
+ go func() {
+ // Accept a connection and copy 1 byte from the read end of
+ // the pipe to the connection. This will call into sendfile.
+ defer wg.Done()
+ conn, err := ln.Accept()
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ defer conn.Close()
+ _, err = io.CopyN(conn, r, 1)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ // Signal the main goroutine that we've copied the byte.
+ close(copied)
+ }()
+
+ wg.Add(1)
+ go func() {
+ // Write 1 byte to the write end of the pipe.
+ defer wg.Done()
+ _, err := w.Write([]byte{'a'})
+ if err != nil {
+ t.Error(err)
+ }
+ }()
+
+ wg.Add(1)
+ go func() {
+ // Connect to the server started two goroutines up and
+ // discard any data that it writes.
+ defer wg.Done()
+ conn, err := Dial("tcp", ln.Addr().String())
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ defer conn.Close()
+ io.Copy(ioutil.Discard, conn)
+ }()
+
+ // Wait for the byte to be copied, meaning that sendfile has
+ // been called on the pipe.
+ <-copied
+
+ // Set a very short deadline on the read end of the pipe.
+ if err := r.SetDeadline(time.Now().Add(time.Microsecond)); err != nil {
+ t.Fatal(err)
+ }
+
+ wg.Add(1)
+ go func() {
+ // Wait for much longer than the deadline and write a byte
+ // to the pipe.
+ defer wg.Done()
+ time.Sleep(50 * time.Millisecond)
+ w.Write([]byte{'b'})
+ }()
+
+ // If this read does not time out, the pipe was incorrectly
+ // put into blocking mode.
+ _, err = r.Read(make([]byte, 1))
+ if err == nil {
+ t.Error("Read did not time out")
+ } else if !os.IsTimeout(err) {
+ t.Errorf("got error %v, expected a time out", err)
+ }
+
+ wg.Wait()
+}