mirror of
https://github.com/golang/go
synced 2024-11-18 11:14:39 -07:00
net: convert many Close tests to use parallel subtests
Also set a deadline in TestCloseWrite so that we can more easily determine which kind of connection is getting stuck on the darwin-arm64-corellium builder (#34837). Change-Id: I8ccacbf436e8e493fb2298a79b17e0af8fc6eb81 Reviewed-on: https://go-review.googlesource.com/c/go/+/227588 Run-TryBot: Bryan C. Mills <bcmills@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
98b6c6aca6
commit
c1f0edae04
@ -23,50 +23,54 @@ func TestCloseRead(t *testing.T) {
|
|||||||
case "plan9":
|
case "plan9":
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
t.Skipf("not supported on %s", runtime.GOOS)
|
||||||
}
|
}
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
for _, network := range []string{"tcp", "unix", "unixpacket"} {
|
for _, network := range []string{"tcp", "unix", "unixpacket"} {
|
||||||
if !testableNetwork(network) {
|
network := network
|
||||||
t.Logf("skipping %s test", network)
|
t.Run(network, func(t *testing.T) {
|
||||||
continue
|
if !testableNetwork(network) {
|
||||||
}
|
t.Skipf("network %s is not testable on the current platform", network)
|
||||||
|
|
||||||
ln, err := newLocalListener(network)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
switch network {
|
|
||||||
case "unix", "unixpacket":
|
|
||||||
defer os.Remove(ln.Addr().String())
|
|
||||||
}
|
|
||||||
defer ln.Close()
|
|
||||||
|
|
||||||
c, err := Dial(ln.Addr().Network(), ln.Addr().String())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
switch network {
|
|
||||||
case "unix", "unixpacket":
|
|
||||||
defer os.Remove(c.LocalAddr().String())
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
switch c := c.(type) {
|
|
||||||
case *TCPConn:
|
|
||||||
err = c.CloseRead()
|
|
||||||
case *UnixConn:
|
|
||||||
err = c.CloseRead()
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
if perr := parseCloseError(err, true); perr != nil {
|
|
||||||
t.Error(perr)
|
|
||||||
}
|
}
|
||||||
t.Fatal(err)
|
t.Parallel()
|
||||||
}
|
|
||||||
var b [1]byte
|
ln, err := newLocalListener(network)
|
||||||
n, err := c.Read(b[:])
|
if err != nil {
|
||||||
if n != 0 || err == nil {
|
t.Fatal(err)
|
||||||
t.Fatalf("got (%d, %v); want (0, error)", n, err)
|
}
|
||||||
}
|
switch network {
|
||||||
|
case "unix", "unixpacket":
|
||||||
|
defer os.Remove(ln.Addr().String())
|
||||||
|
}
|
||||||
|
defer ln.Close()
|
||||||
|
|
||||||
|
c, err := Dial(ln.Addr().Network(), ln.Addr().String())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
switch network {
|
||||||
|
case "unix", "unixpacket":
|
||||||
|
defer os.Remove(c.LocalAddr().String())
|
||||||
|
}
|
||||||
|
defer c.Close()
|
||||||
|
|
||||||
|
switch c := c.(type) {
|
||||||
|
case *TCPConn:
|
||||||
|
err = c.CloseRead()
|
||||||
|
case *UnixConn:
|
||||||
|
err = c.CloseRead()
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
if perr := parseCloseError(err, true); perr != nil {
|
||||||
|
t.Error(perr)
|
||||||
|
}
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
var b [1]byte
|
||||||
|
n, err := c.Read(b[:])
|
||||||
|
if n != 0 || err == nil {
|
||||||
|
t.Fatalf("got (%d, %v); want (0, error)", n, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,212 +80,240 @@ func TestCloseWrite(t *testing.T) {
|
|||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
t.Skipf("not supported on %s", runtime.GOOS)
|
||||||
}
|
}
|
||||||
|
|
||||||
handler := func(ls *localServer, ln Listener) {
|
t.Parallel()
|
||||||
c, err := ln.Accept()
|
deadline, _ := t.Deadline()
|
||||||
if err != nil {
|
if !deadline.IsZero() {
|
||||||
t.Error(err)
|
// Leave 10% headroom on the deadline to report errors and clean up.
|
||||||
return
|
deadline = deadline.Add(-time.Until(deadline) / 10)
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
var b [1]byte
|
|
||||||
n, err := c.Read(b[:])
|
|
||||||
if n != 0 || err != io.EOF {
|
|
||||||
t.Errorf("got (%d, %v); want (0, io.EOF)", n, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch c := c.(type) {
|
|
||||||
case *TCPConn:
|
|
||||||
err = c.CloseWrite()
|
|
||||||
case *UnixConn:
|
|
||||||
err = c.CloseWrite()
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
if perr := parseCloseError(err, true); perr != nil {
|
|
||||||
t.Error(perr)
|
|
||||||
}
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
n, err = c.Write(b[:])
|
|
||||||
if err == nil {
|
|
||||||
t.Errorf("got (%d, %v); want (any, error)", n, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, network := range []string{"tcp", "unix", "unixpacket"} {
|
for _, network := range []string{"tcp", "unix", "unixpacket"} {
|
||||||
if !testableNetwork(network) {
|
network := network
|
||||||
t.Logf("skipping %s test", network)
|
t.Run(network, func(t *testing.T) {
|
||||||
continue
|
if !testableNetwork(network) {
|
||||||
}
|
t.Skipf("network %s is not testable on the current platform", network)
|
||||||
|
|
||||||
ls, err := newLocalServer(network)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer ls.teardown()
|
|
||||||
if err := ls.buildup(handler); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
switch network {
|
|
||||||
case "unix", "unixpacket":
|
|
||||||
defer os.Remove(c.LocalAddr().String())
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
switch c := c.(type) {
|
|
||||||
case *TCPConn:
|
|
||||||
err = c.CloseWrite()
|
|
||||||
case *UnixConn:
|
|
||||||
err = c.CloseWrite()
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
if perr := parseCloseError(err, true); perr != nil {
|
|
||||||
t.Error(perr)
|
|
||||||
}
|
}
|
||||||
t.Fatal(err)
|
t.Parallel()
|
||||||
}
|
|
||||||
var b [1]byte
|
handler := func(ls *localServer, ln Listener) {
|
||||||
n, err := c.Read(b[:])
|
c, err := ln.Accept()
|
||||||
if n != 0 || err != io.EOF {
|
if err != nil {
|
||||||
t.Fatalf("got (%d, %v); want (0, io.EOF)", n, err)
|
t.Error(err)
|
||||||
}
|
return
|
||||||
n, err = c.Write(b[:])
|
}
|
||||||
if err == nil {
|
if !deadline.IsZero() {
|
||||||
t.Fatalf("got (%d, %v); want (any, error)", n, err)
|
c.SetDeadline(deadline)
|
||||||
}
|
}
|
||||||
|
defer c.Close()
|
||||||
|
|
||||||
|
var b [1]byte
|
||||||
|
n, err := c.Read(b[:])
|
||||||
|
if n != 0 || err != io.EOF {
|
||||||
|
t.Errorf("got (%d, %v); want (0, io.EOF)", n, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch c := c.(type) {
|
||||||
|
case *TCPConn:
|
||||||
|
err = c.CloseWrite()
|
||||||
|
case *UnixConn:
|
||||||
|
err = c.CloseWrite()
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
if perr := parseCloseError(err, true); perr != nil {
|
||||||
|
t.Error(perr)
|
||||||
|
}
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
n, err = c.Write(b[:])
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("got (%d, %v); want (any, error)", n, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ls, err := newLocalServer(network)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer ls.teardown()
|
||||||
|
if err := ls.buildup(handler); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !deadline.IsZero() {
|
||||||
|
c.SetDeadline(deadline)
|
||||||
|
}
|
||||||
|
switch network {
|
||||||
|
case "unix", "unixpacket":
|
||||||
|
defer os.Remove(c.LocalAddr().String())
|
||||||
|
}
|
||||||
|
defer c.Close()
|
||||||
|
|
||||||
|
switch c := c.(type) {
|
||||||
|
case *TCPConn:
|
||||||
|
err = c.CloseWrite()
|
||||||
|
case *UnixConn:
|
||||||
|
err = c.CloseWrite()
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
if perr := parseCloseError(err, true); perr != nil {
|
||||||
|
t.Error(perr)
|
||||||
|
}
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
var b [1]byte
|
||||||
|
n, err := c.Read(b[:])
|
||||||
|
if n != 0 || err != io.EOF {
|
||||||
|
t.Fatalf("got (%d, %v); want (0, io.EOF)", n, err)
|
||||||
|
}
|
||||||
|
n, err = c.Write(b[:])
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("got (%d, %v); want (any, error)", n, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConnClose(t *testing.T) {
|
func TestConnClose(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
for _, network := range []string{"tcp", "unix", "unixpacket"} {
|
for _, network := range []string{"tcp", "unix", "unixpacket"} {
|
||||||
if !testableNetwork(network) {
|
network := network
|
||||||
t.Logf("skipping %s test", network)
|
t.Run(network, func(t *testing.T) {
|
||||||
continue
|
if !testableNetwork(network) {
|
||||||
}
|
t.Skipf("network %s is not testable on the current platform", network)
|
||||||
|
|
||||||
ln, err := newLocalListener(network)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
switch network {
|
|
||||||
case "unix", "unixpacket":
|
|
||||||
defer os.Remove(ln.Addr().String())
|
|
||||||
}
|
|
||||||
defer ln.Close()
|
|
||||||
|
|
||||||
c, err := Dial(ln.Addr().Network(), ln.Addr().String())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
switch network {
|
|
||||||
case "unix", "unixpacket":
|
|
||||||
defer os.Remove(c.LocalAddr().String())
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
if err := c.Close(); err != nil {
|
|
||||||
if perr := parseCloseError(err, false); perr != nil {
|
|
||||||
t.Error(perr)
|
|
||||||
}
|
}
|
||||||
t.Fatal(err)
|
t.Parallel()
|
||||||
}
|
|
||||||
var b [1]byte
|
ln, err := newLocalListener(network)
|
||||||
n, err := c.Read(b[:])
|
if err != nil {
|
||||||
if n != 0 || err == nil {
|
t.Fatal(err)
|
||||||
t.Fatalf("got (%d, %v); want (0, error)", n, err)
|
}
|
||||||
}
|
switch network {
|
||||||
|
case "unix", "unixpacket":
|
||||||
|
defer os.Remove(ln.Addr().String())
|
||||||
|
}
|
||||||
|
defer ln.Close()
|
||||||
|
|
||||||
|
c, err := Dial(ln.Addr().Network(), ln.Addr().String())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
switch network {
|
||||||
|
case "unix", "unixpacket":
|
||||||
|
defer os.Remove(c.LocalAddr().String())
|
||||||
|
}
|
||||||
|
defer c.Close()
|
||||||
|
|
||||||
|
if err := c.Close(); err != nil {
|
||||||
|
if perr := parseCloseError(err, false); perr != nil {
|
||||||
|
t.Error(perr)
|
||||||
|
}
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
var b [1]byte
|
||||||
|
n, err := c.Read(b[:])
|
||||||
|
if n != 0 || err == nil {
|
||||||
|
t.Fatalf("got (%d, %v); want (0, error)", n, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestListenerClose(t *testing.T) {
|
func TestListenerClose(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
for _, network := range []string{"tcp", "unix", "unixpacket"} {
|
for _, network := range []string{"tcp", "unix", "unixpacket"} {
|
||||||
if !testableNetwork(network) {
|
network := network
|
||||||
t.Logf("skipping %s test", network)
|
t.Run(network, func(t *testing.T) {
|
||||||
continue
|
if !testableNetwork(network) {
|
||||||
}
|
t.Skipf("network %s is not testable on the current platform", network)
|
||||||
|
|
||||||
ln, err := newLocalListener(network)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
switch network {
|
|
||||||
case "unix", "unixpacket":
|
|
||||||
defer os.Remove(ln.Addr().String())
|
|
||||||
}
|
|
||||||
|
|
||||||
dst := ln.Addr().String()
|
|
||||||
if err := ln.Close(); err != nil {
|
|
||||||
if perr := parseCloseError(err, false); perr != nil {
|
|
||||||
t.Error(perr)
|
|
||||||
}
|
}
|
||||||
t.Fatal(err)
|
t.Parallel()
|
||||||
}
|
|
||||||
c, err := ln.Accept()
|
|
||||||
if err == nil {
|
|
||||||
c.Close()
|
|
||||||
t.Fatal("should fail")
|
|
||||||
}
|
|
||||||
|
|
||||||
if network == "tcp" {
|
ln, err := newLocalListener(network)
|
||||||
// We will have two TCP FSMs inside the
|
if err != nil {
|
||||||
// kernel here. There's no guarantee that a
|
t.Fatal(err)
|
||||||
// signal comes from the far end FSM will be
|
}
|
||||||
// delivered immediately to the near end FSM,
|
switch network {
|
||||||
// especially on the platforms that allow
|
case "unix", "unixpacket":
|
||||||
// multiple consumer threads to pull pending
|
defer os.Remove(ln.Addr().String())
|
||||||
// established connections at the same time by
|
}
|
||||||
// enabling SO_REUSEPORT option such as Linux,
|
|
||||||
// DragonFly BSD. So we need to give some time
|
|
||||||
// quantum to the kernel.
|
|
||||||
//
|
|
||||||
// Note that net.inet.tcp.reuseport_ext=1 by
|
|
||||||
// default on DragonFly BSD.
|
|
||||||
time.Sleep(time.Millisecond)
|
|
||||||
|
|
||||||
cc, err := Dial("tcp", dst)
|
dst := ln.Addr().String()
|
||||||
|
if err := ln.Close(); err != nil {
|
||||||
|
if perr := parseCloseError(err, false); perr != nil {
|
||||||
|
t.Error(perr)
|
||||||
|
}
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
c, err := ln.Accept()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("Dial to closed TCP listener succeeded.")
|
c.Close()
|
||||||
cc.Close()
|
t.Fatal("should fail")
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if network == "tcp" {
|
||||||
|
// We will have two TCP FSMs inside the
|
||||||
|
// kernel here. There's no guarantee that a
|
||||||
|
// signal comes from the far end FSM will be
|
||||||
|
// delivered immediately to the near end FSM,
|
||||||
|
// especially on the platforms that allow
|
||||||
|
// multiple consumer threads to pull pending
|
||||||
|
// established connections at the same time by
|
||||||
|
// enabling SO_REUSEPORT option such as Linux,
|
||||||
|
// DragonFly BSD. So we need to give some time
|
||||||
|
// quantum to the kernel.
|
||||||
|
//
|
||||||
|
// Note that net.inet.tcp.reuseport_ext=1 by
|
||||||
|
// default on DragonFly BSD.
|
||||||
|
time.Sleep(time.Millisecond)
|
||||||
|
|
||||||
|
cc, err := Dial("tcp", dst)
|
||||||
|
if err == nil {
|
||||||
|
t.Error("Dial to closed TCP listener succeeded.")
|
||||||
|
cc.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPacketConnClose(t *testing.T) {
|
func TestPacketConnClose(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
for _, network := range []string{"udp", "unixgram"} {
|
for _, network := range []string{"udp", "unixgram"} {
|
||||||
if !testableNetwork(network) {
|
network := network
|
||||||
t.Logf("skipping %s test", network)
|
t.Run(network, func(t *testing.T) {
|
||||||
continue
|
if !testableNetwork(network) {
|
||||||
}
|
t.Skipf("network %s is not testable on the current platform", network)
|
||||||
|
|
||||||
c, err := newLocalPacketListener(network)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
switch network {
|
|
||||||
case "unixgram":
|
|
||||||
defer os.Remove(c.LocalAddr().String())
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
if err := c.Close(); err != nil {
|
|
||||||
if perr := parseCloseError(err, false); perr != nil {
|
|
||||||
t.Error(perr)
|
|
||||||
}
|
}
|
||||||
t.Fatal(err)
|
t.Parallel()
|
||||||
}
|
|
||||||
var b [1]byte
|
c, err := newLocalPacketListener(network)
|
||||||
n, _, err := c.ReadFrom(b[:])
|
if err != nil {
|
||||||
if n != 0 || err == nil {
|
t.Fatal(err)
|
||||||
t.Fatalf("got (%d, %v); want (0, error)", n, err)
|
}
|
||||||
}
|
switch network {
|
||||||
|
case "unixgram":
|
||||||
|
defer os.Remove(c.LocalAddr().String())
|
||||||
|
}
|
||||||
|
defer c.Close()
|
||||||
|
|
||||||
|
if err := c.Close(); err != nil {
|
||||||
|
if perr := parseCloseError(err, false); perr != nil {
|
||||||
|
t.Error(perr)
|
||||||
|
}
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
var b [1]byte
|
||||||
|
n, _, err := c.ReadFrom(b[:])
|
||||||
|
if n != 0 || err == nil {
|
||||||
|
t.Fatalf("got (%d, %v); want (0, error)", n, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,56 +398,60 @@ func TestAcceptIgnoreAbortedConnRequest(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestZeroByteRead(t *testing.T) {
|
func TestZeroByteRead(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
for _, network := range []string{"tcp", "unix", "unixpacket"} {
|
for _, network := range []string{"tcp", "unix", "unixpacket"} {
|
||||||
if !testableNetwork(network) {
|
network := network
|
||||||
t.Logf("skipping %s test", network)
|
t.Run(network, func(t *testing.T) {
|
||||||
continue
|
if !testableNetwork(network) {
|
||||||
}
|
t.Skipf("network %s is not testable on the current platform", network)
|
||||||
|
|
||||||
ln, err := newLocalListener(network)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
connc := make(chan Conn, 1)
|
|
||||||
go func() {
|
|
||||||
defer ln.Close()
|
|
||||||
c, err := ln.Accept()
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
}
|
||||||
connc <- c // might be nil
|
t.Parallel()
|
||||||
}()
|
|
||||||
c, err := Dial(network, ln.Addr().String())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
sc := <-connc
|
|
||||||
if sc == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
defer sc.Close()
|
|
||||||
|
|
||||||
if runtime.GOOS == "windows" {
|
ln, err := newLocalListener(network)
|
||||||
// A zero byte read on Windows caused a wait for readability first.
|
if err != nil {
|
||||||
// Rather than change that behavior, satisfy it in this test.
|
t.Fatal(err)
|
||||||
// See Issue 15735.
|
}
|
||||||
go io.WriteString(sc, "a")
|
connc := make(chan Conn, 1)
|
||||||
}
|
go func() {
|
||||||
|
defer ln.Close()
|
||||||
|
c, err := ln.Accept()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
connc <- c // might be nil
|
||||||
|
}()
|
||||||
|
c, err := Dial(network, ln.Addr().String())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer c.Close()
|
||||||
|
sc := <-connc
|
||||||
|
if sc == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer sc.Close()
|
||||||
|
|
||||||
n, err := c.Read(nil)
|
if runtime.GOOS == "windows" {
|
||||||
if n != 0 || err != nil {
|
// A zero byte read on Windows caused a wait for readability first.
|
||||||
t.Errorf("%s: zero byte client read = %v, %v; want 0, nil", network, n, err)
|
// Rather than change that behavior, satisfy it in this test.
|
||||||
}
|
// See Issue 15735.
|
||||||
|
go io.WriteString(sc, "a")
|
||||||
|
}
|
||||||
|
|
||||||
if runtime.GOOS == "windows" {
|
n, err := c.Read(nil)
|
||||||
// Same as comment above.
|
if n != 0 || err != nil {
|
||||||
go io.WriteString(c, "a")
|
t.Errorf("%s: zero byte client read = %v, %v; want 0, nil", network, n, err)
|
||||||
}
|
}
|
||||||
n, err = sc.Read(nil)
|
|
||||||
if n != 0 || err != nil {
|
if runtime.GOOS == "windows" {
|
||||||
t.Errorf("%s: zero byte server read = %v, %v; want 0, nil", network, n, err)
|
// Same as comment above.
|
||||||
}
|
go io.WriteString(c, "a")
|
||||||
|
}
|
||||||
|
n, err = sc.Read(nil)
|
||||||
|
if n != 0 || err != nil {
|
||||||
|
t.Errorf("%s: zero byte server read = %v, %v; want 0, nil", network, n, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user