Commit 4f38ef81 authored by Mikio Hara's avatar Mikio Hara

net: add missing Close tests

This change adds missing CloseRead test and Close tests on Conn,
Listener and PacketConn with various networks.

Change-Id: Iadf99eaf526a323f853d203edc7c8d0577f67972
Reviewed-on: https://go-review.googlesource.com/9469Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent 1ab60c29
...@@ -6,229 +6,251 @@ package net ...@@ -6,229 +6,251 @@ package net
import ( import (
"io" "io"
"io/ioutil"
"os" "os"
"runtime" "runtime"
"testing" "testing"
"time"
) )
func TestShutdown(t *testing.T) { func TestCloseRead(t *testing.T) {
if runtime.GOOS == "plan9" { switch runtime.GOOS {
t.Skipf("skipping test on %q", runtime.GOOS) case "nacl", "plan9":
t.Skipf("not supported on %s", runtime.GOOS)
} }
ln, err := Listen("tcp", "127.0.0.1:0")
if err != nil { for _, network := range []string{"tcp", "unix", "unixpacket"} {
if ln, err = Listen("tcp6", "[::1]:0"); err != nil { if !testableNetwork(network) {
t.Fatalf("ListenTCP on :0: %v", err) t.Logf("skipping %s test", network)
continue
} }
}
go func() { ln, err := newLocalListener(network)
defer ln.Close()
c, err := ln.Accept()
if err != nil { if err != nil {
t.Errorf("Accept: %v", err) t.Fatal(err)
return
} }
var buf [10]byte switch network {
n, err := c.Read(buf[:]) case "unix", "unixpacket":
if perr := parseReadError(err); perr != nil { defer os.Remove(ln.Addr().String())
t.Error(perr)
} }
if n != 0 || err != io.EOF { defer ln.Close()
t.Errorf("server Read = %d, %v; want 0, io.EOF", n, err)
return
}
c.Write([]byte("response"))
c.Close()
}()
c, err := Dial("tcp", ln.Addr().String()) c, err := Dial(ln.Addr().Network(), ln.Addr().String())
if err != nil { if err != nil {
t.Fatalf("Dial: %v", err) t.Fatal(err)
} }
defer c.Close() switch network {
case "unix", "unixpacket":
defer os.Remove(c.LocalAddr().String())
}
defer c.Close()
err = c.(*TCPConn).CloseWrite() switch c := c.(type) {
if err != nil { case *TCPConn:
t.Fatalf("CloseWrite: %v", err) err = c.CloseRead()
} case *UnixConn:
var buf [10]byte err = c.CloseRead()
n, err := c.Read(buf[:]) }
if err != nil { if err != nil {
t.Fatalf("client Read: %d, %v", n, err) if perr := parseCloseError(err); perr != nil {
} t.Error(perr)
got := string(buf[:n]) }
if got != "response" { t.Fatal(err)
t.Errorf("read = %q, want \"response\"", got) }
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 TestShutdownUnix(t *testing.T) { func TestCloseWrite(t *testing.T) {
if !testableNetwork("unix") { switch runtime.GOOS {
t.Skip("unix test") case "nacl", "plan9":
} t.Skipf("not supported on %s", runtime.GOOS)
f, err := ioutil.TempFile("", "go_net_unixtest")
if err != nil {
t.Fatalf("TempFile: %s", err)
}
f.Close()
tmpname := f.Name()
os.Remove(tmpname)
ln, err := Listen("unix", tmpname)
if err != nil {
t.Fatalf("ListenUnix on %s: %s", tmpname, err)
} }
defer func() {
ln.Close()
os.Remove(tmpname)
}()
go func() { handler := func(ls *localServer, ln Listener) {
c, err := ln.Accept() c, err := ln.Accept()
if err != nil { if err != nil {
t.Errorf("Accept: %v", err) t.Error(err)
return return
} }
var buf [10]byte defer c.Close()
n, err := c.Read(buf[:])
if perr := parseReadError(err); perr != nil { var b [1]byte
t.Error(perr) n, err := c.Read(b[:])
}
if n != 0 || err != io.EOF { if n != 0 || err != io.EOF {
t.Errorf("server Read = %d, %v; want 0, io.EOF", n, err) 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); 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 return
} }
c.Write([]byte("response"))
c.Close()
}()
c, err := Dial("unix", tmpname)
if err != nil {
t.Fatalf("Dial: %v", err)
} }
defer c.Close()
err = c.(*UnixConn).CloseWrite() for _, network := range []string{"tcp", "unix", "unixpacket"} {
if err != nil { if !testableNetwork(network) {
t.Fatalf("CloseWrite: %v", err) t.Logf("skipping %s test", network)
} continue
var buf [10]byte }
n, err := c.Read(buf[:])
if err != nil {
t.Fatalf("client Read: %d, %v", n, err)
}
got := string(buf[:n])
if got != "response" {
t.Errorf("read = %q, want \"response\"", got)
}
}
func TestTCPListenClose(t *testing.T) { ls, err := newLocalServer(network)
ln, err := Listen("tcp", "127.0.0.1:0") if err != nil {
if err != nil { t.Fatal(err)
t.Fatalf("Listen failed: %v", err) }
} defer ls.teardown()
if err := ls.buildup(handler); err != nil {
t.Fatal(err)
}
done := make(chan bool, 1) c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
go func() { if err != nil {
time.Sleep(100 * time.Millisecond) t.Fatal(err)
ln.Close() }
}() switch network {
go func() { case "unix", "unixpacket":
c, err := ln.Accept() 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); 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 { if err == nil {
c.Close() t.Fatalf("got (%d, %v); want (any, error)", n, err)
t.Error("Accept succeeded") }
} else {
t.Logf("Accept timeout error: %s (any error is fine)", err)
}
done <- true
}()
select {
case <-done:
case <-time.After(2 * time.Second):
t.Fatal("timeout waiting for TCP close")
} }
} }
func TestUDPListenClose(t *testing.T) { func TestConnClose(t *testing.T) {
switch runtime.GOOS { for _, network := range []string{"tcp", "unix", "unixpacket"} {
case "plan9": if !testableNetwork(network) {
t.Skipf("skipping test on %q", runtime.GOOS) t.Logf("skipping %s test", network)
} continue
ln, err := ListenPacket("udp", "127.0.0.1:0") }
if err != nil {
t.Fatalf("Listen failed: %v", err)
}
buf := make([]byte, 1000) ln, err := newLocalListener(network)
done := make(chan bool, 1) if err != nil {
go func() { t.Fatal(err)
time.Sleep(100 * time.Millisecond)
ln.Close()
}()
go func() {
_, _, err = ln.ReadFrom(buf)
if perr := parseReadError(err); perr != nil {
t.Error(perr)
} }
if err == nil { switch network {
t.Error("ReadFrom succeeded") case "unix", "unixpacket":
} else { defer os.Remove(ln.Addr().String())
t.Logf("ReadFrom timeout error: %s (any error is fine)", err) }
} defer ln.Close()
done <- true
}()
select {
case <-done:
case <-time.After(2 * time.Second):
t.Fatal("timeout waiting for UDP close")
}
}
func TestTCPClose(t *testing.T) { c, err := Dial(ln.Addr().Network(), ln.Addr().String())
switch runtime.GOOS { if err != nil {
case "plan9": t.Fatal(err)
t.Skipf("skipping test on %q", runtime.GOOS) }
} switch network {
l, err := Listen("tcp", "127.0.0.1:0") case "unix", "unixpacket":
if err != nil { defer os.Remove(c.LocalAddr().String())
t.Fatal(err) }
} defer c.Close()
defer l.Close()
read := func(r io.Reader) error { if err := c.Close(); err != nil {
var m [1]byte if perr := parseCloseError(err); perr != nil {
_, err := r.Read(m[:]) t.Error(perr)
return err }
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)
}
} }
}
go func() { func TestListenerClose(t *testing.T) {
c, err := Dial("tcp", l.Addr().String()) for _, network := range []string{"tcp", "unix", "unixpacket"} {
if !testableNetwork(network) {
t.Logf("skipping %s test", network)
continue
}
ln, err := newLocalListener(network)
if err != nil { if err != nil {
t.Errorf("Dial: %v", err) t.Fatal(err)
return
} }
switch network {
case "unix", "unixpacket":
defer os.Remove(ln.Addr().String())
}
defer ln.Close()
go read(c) if err := ln.Close(); err != nil {
if perr := parseCloseError(err); perr != nil {
t.Error(perr)
}
t.Fatal(err)
}
c, err := ln.Accept()
if err == nil {
c.Close()
t.Fatal("should fail")
}
}
}
time.Sleep(10 * time.Millisecond) func TestPacketConnClose(t *testing.T) {
c.Close() for _, network := range []string{"udp", "unixgram"} {
}() if !testableNetwork(network) {
t.Logf("skipping %s test", network)
continue
}
c, err := l.Accept() c, err := newLocalPacketListener(network)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer c.Close() switch network {
case "unixgram":
defer os.Remove(c.LocalAddr().String())
}
defer c.Close()
for err == nil { if err := c.Close(); err != nil {
err = read(c) if perr := parseCloseError(err); perr != nil {
} t.Error(perr)
if err != nil && err != io.EOF { }
t.Fatal(err) 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)
}
} }
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment