aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Tudor Călin <mail@acln.ro>2018-08-30 06:55:05 +0200
committerIan Lance Taylor <iant@golang.org>2018-08-30 23:15:51 +0000
commitad116f72b96530edeece030da4ee3f7f7d711ddd (patch)
treef749deaa9d83e754424214caa851fef5abbc8442
parent359a02b0fc4e195fb0be41ba5b74beb2842139ad (diff)
downloadgo-ad116f72b96530edeece030da4ee3f7f7d711ddd.tar.gz
go-ad116f72b96530edeece030da4ee3f7f7d711ddd.zip
[release-branch.go1.11] net: refactor readerAtEOF splice test
Refactor TestSplice/readerAtEOF to handle cases where we disable splice on older kernels better. If splice is disabled, net.splice and poll.Splice do not get to observe EOF on the reader, because poll.Splice returns immediately with EINVAL. The test fails unexpectedly, because the splice operation is reported as not handled. This change refactors the test to handle the aforementioned case correctly, by not calling net.splice directly, but using a higher level check. Fixes #27355. Change-Id: I0d5606b4775213f2dbbb84ef82ddfc3bab662a31 Reviewed-on: https://go-review.googlesource.com/132096 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org> (cherry picked from commit bd49b3d580731d8f391e40fb9e2f17301651cede) Reviewed-on: https://go-review.googlesource.com/132281 Reviewed-by: Andrew Bonventre <andybons@golang.org>
-rw-r--r--src/net/splice_test.go57
1 files changed, 50 insertions, 7 deletions
diff --git a/src/net/splice_test.go b/src/net/splice_test.go
index 44a5c00ba8..ffe71ae384 100644
--- a/src/net/splice_test.go
+++ b/src/net/splice_test.go
@@ -122,6 +122,7 @@ func testSpliceBig(t *testing.T) {
func testSpliceHonorsLimitedReader(t *testing.T) {
t.Run("stopsAfterN", testSpliceStopsAfterN)
t.Run("updatesN", testSpliceUpdatesN)
+ t.Run("readerAtLimit", testSpliceReaderAtLimit)
}
func testSpliceStopsAfterN(t *testing.T) {
@@ -208,7 +209,7 @@ func testSpliceUpdatesN(t *testing.T) {
}
}
-func testSpliceReaderAtEOF(t *testing.T) {
+func testSpliceReaderAtLimit(t *testing.T) {
clientUp, serverUp, err := spliceTestSocketPair("tcp")
if err != nil {
t.Fatal(err)
@@ -222,21 +223,63 @@ func testSpliceReaderAtEOF(t *testing.T) {
defer clientDown.Close()
defer serverDown.Close()
- serverUp.Close()
- _, err, handled := splice(serverDown.(*TCPConn).fd, serverUp)
- if !handled {
- t.Errorf("closed connection: got err = %v, handled = %t, want handled = true", err, handled)
- }
lr := &io.LimitedReader{
N: 0,
R: serverUp,
}
- _, err, handled = splice(serverDown.(*TCPConn).fd, lr)
+ _, err, handled := splice(serverDown.(*TCPConn).fd, lr)
if !handled {
t.Errorf("exhausted LimitedReader: got err = %v, handled = %t, want handled = true", err, handled)
}
}
+func testSpliceReaderAtEOF(t *testing.T) {
+ clientUp, serverUp, err := spliceTestSocketPair("tcp")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer clientUp.Close()
+ clientDown, serverDown, err := spliceTestSocketPair("tcp")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer clientDown.Close()
+
+ serverUp.Close()
+
+ // We'd like to call net.splice here and check the handled return
+ // value, but we disable splice on old Linux kernels.
+ //
+ // In that case, poll.Splice and net.splice return a non-nil error
+ // and handled == false. We'd ideally like to see handled == true
+ // because the source reader is at EOF, but if we're running on an old
+ // kernel, and splice is disabled, we won't see EOF from net.splice,
+ // because we won't touch the reader at all.
+ //
+ // Trying to untangle the errors from net.splice and match them
+ // against the errors created by the poll package would be brittle,
+ // so this is a higher level test.
+ //
+ // The following ReadFrom should return immediately, regardless of
+ // whether splice is disabled or not. The other side should then
+ // get a goodbye signal. Test for the goodbye signal.
+ msg := "bye"
+ go func() {
+ serverDown.(*TCPConn).ReadFrom(serverUp)
+ io.WriteString(serverDown, msg)
+ serverDown.Close()
+ }()
+
+ buf := make([]byte, 3)
+ _, err = io.ReadFull(clientDown, buf)
+ if err != nil {
+ t.Errorf("clientDown: %v", err)
+ }
+ if string(buf) != msg {
+ t.Errorf("clientDown got %q, want %q", buf, msg)
+ }
+}
+
func testSpliceIssue25985(t *testing.T) {
front, err := newLocalListener("tcp")
if err != nil {