diff --git a/src/pkg/net/protoconn_test.go b/src/pkg/net/protoconn_test.go index 5cdceb7721c..f249372f392 100644 --- a/src/pkg/net/protoconn_test.go +++ b/src/pkg/net/protoconn_test.go @@ -13,6 +13,101 @@ import ( "time" ) +var condErrorf = func() func(*testing.T, string, ...interface{}) { + // A few APIs are not implemented yet on both Plan 9 and Windows. + switch runtime.GOOS { + case "plan9", "windows": + return (*testing.T).Logf + } + return (*testing.T).Errorf +}() + +func TestTCPListenerSpecificMethods(t *testing.T) { + la, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:0") + if err != nil { + t.Fatalf("net.ResolveTCPAddr failed: %v", err) + } + ln, err := net.ListenTCP("tcp4", la) + if err != nil { + t.Fatalf("net.ListenTCP failed: %v", err) + } + ln.Addr() + ln.SetDeadline(time.Now().Add(30 * time.Nanosecond)) + defer ln.Close() + + if c, err := ln.Accept(); err != nil { + if !err.(net.Error).Timeout() { + t.Errorf("net.TCPListener.Accept failed: %v", err) + return + } + } else { + c.Close() + } + if c, err := ln.AcceptTCP(); err != nil { + if !err.(net.Error).Timeout() { + t.Errorf("net.TCPListener.AcceptTCP failed: %v", err) + return + } + } else { + c.Close() + } + + if f, err := ln.File(); err != nil { + condErrorf(t, "net.TCPListener.File failed: %v", err) + return + } else { + f.Close() + } +} + +func TestTCPConnSpecificMethods(t *testing.T) { + la, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:0") + if err != nil { + t.Fatalf("net.ResolveTCPAddr failed: %v", err) + } + ln, err := net.ListenTCP("tcp4", la) + if err != nil { + t.Fatalf("net.ListenTCP failed: %v", err) + } + ln.Addr() + defer ln.Close() + + done := make(chan int) + go transponder(t, ln, done) + + ra, err := net.ResolveTCPAddr("tcp4", ln.Addr().String()) + if err != nil { + t.Errorf("net.ResolveTCPAddr failed: %v", err) + return + } + c, err := net.DialTCP("tcp4", nil, ra) + if err != nil { + t.Errorf("net.DialTCP failed: %v", err) + return + } + c.SetKeepAlive(false) + c.SetLinger(0) + c.SetNoDelay(false) + c.LocalAddr() + c.RemoteAddr() + c.SetDeadline(time.Now().Add(100 * time.Millisecond)) + c.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) + c.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)) + defer c.Close() + + if _, err := c.Write([]byte("TCPCONN TEST")); err != nil { + t.Errorf("net.TCPConn.Write failed: %v", err) + return + } + rb := make([]byte, 128) + if _, err := c.Read(rb); err != nil { + t.Errorf("net.TCPConn.Read failed: %v", err) + return + } + + <-done +} + func TestUDPConnSpecificMethods(t *testing.T) { la, err := net.ResolveUDPAddr("udp4", "127.0.0.1:0") if err != nil { @@ -22,7 +117,6 @@ func TestUDPConnSpecificMethods(t *testing.T) { if err != nil { t.Fatalf("net.ListenUDP failed: %v", err) } - c.File() c.LocalAddr() c.RemoteAddr() c.SetDeadline(time.Now().Add(100 * time.Millisecond)) @@ -33,12 +127,29 @@ func TestUDPConnSpecificMethods(t *testing.T) { defer c.Close() wb := []byte("UDPCONN TEST") - if _, err := c.WriteToUDP(wb, c.LocalAddr().(*net.UDPAddr)); err != nil { - t.Fatalf("net.UDPConn.WriteToUDP failed: %v", err) - } rb := make([]byte, 128) + if _, err := c.WriteToUDP(wb, c.LocalAddr().(*net.UDPAddr)); err != nil { + t.Errorf("net.UDPConn.WriteToUDP failed: %v", err) + return + } if _, _, err := c.ReadFromUDP(rb); err != nil { - t.Fatalf("net.UDPConn.ReadFromUDP failed: %v", err) + t.Errorf("net.UDPConn.ReadFromUDP failed: %v", err) + return + } + if _, _, err := c.WriteMsgUDP(wb, nil, c.LocalAddr().(*net.UDPAddr)); err != nil { + condErrorf(t, "net.UDPConn.WriteMsgUDP failed: %v", err) + return + } + if _, _, _, _, err := c.ReadMsgUDP(rb, nil); err != nil { + condErrorf(t, "net.UDPConn.ReadMsgUDP failed: %v", err) + return + } + + if f, err := c.File(); err != nil { + condErrorf(t, "net.UDPConn.File failed: %v", err) + return + } else { + f.Close() } } @@ -61,7 +172,6 @@ func TestIPConnSpecificMethods(t *testing.T) { if err != nil { t.Fatalf("net.ListenIP failed: %v", err) } - c.File() c.LocalAddr() c.RemoteAddr() c.SetDeadline(time.Now().Add(100 * time.Millisecond)) @@ -73,16 +183,79 @@ func TestIPConnSpecificMethods(t *testing.T) { id := os.Getpid() & 0xffff wb := newICMPEchoRequest(id, 1, 128, []byte("IPCONN TEST ")) - if _, err := c.WriteToIP(wb, c.LocalAddr().(*net.IPAddr)); err != nil { - t.Fatalf("net.IPConn.WriteToIP failed: %v", err) - } rb := make([]byte, 20+128) + if _, err := c.WriteToIP(wb, c.LocalAddr().(*net.IPAddr)); err != nil { + t.Errorf("net.IPConn.WriteToIP failed: %v", err) + return + } if _, _, err := c.ReadFromIP(rb); err != nil { - t.Fatalf("net.IPConn.ReadFromIP failed: %v", err) + t.Errorf("net.IPConn.ReadFromIP failed: %v", err) + return + } + if _, _, err := c.WriteMsgIP(wb, nil, c.LocalAddr().(*net.IPAddr)); err != nil { + condErrorf(t, "net.UDPConn.WriteMsgIP failed: %v", err) + return + } + if _, _, _, _, err := c.ReadMsgIP(rb, nil); err != nil { + condErrorf(t, "net.UDPConn.ReadMsgIP failed: %v", err) + return + } + + if f, err := c.File(); err != nil { + condErrorf(t, "net.IPConn.File failed: %v", err) + return + } else { + f.Close() + } +} + +func TestUnixListenerSpecificMethods(t *testing.T) { + switch runtime.GOOS { + case "plan9", "windows": + t.Logf("skipping read test on %q", runtime.GOOS) + return + } + + p := "/tmp/gotest.net" + os.Remove(p) + la, err := net.ResolveUnixAddr("unix", p) + if err != nil { + t.Fatalf("net.ResolveUnixAddr failed: %v", err) + } + ln, err := net.ListenUnix("unix", la) + if err != nil { + t.Fatalf("net.ListenUnix failed: %v", err) + } + ln.Addr() + ln.SetDeadline(time.Now().Add(30 * time.Nanosecond)) + defer ln.Close() + defer os.Remove(p) + + if c, err := ln.Accept(); err != nil { + if !err.(net.Error).Timeout() { + t.Errorf("net.TCPListener.AcceptTCP failed: %v", err) + return + } + } else { + c.Close() + } + if c, err := ln.AcceptUnix(); err != nil { + if !err.(net.Error).Timeout() { + t.Errorf("net.TCPListener.AcceptTCP failed: %v", err) + return + } + } else { + c.Close() + } + + if f, err := ln.File(); err != nil { + t.Errorf("net.UnixListener.File failed: %v", err) + return + } else { + f.Close() } } -// TODO: Find out the use case of ListenUnixgram, I have no idea. func TestUnixConnSpecificMethods(t *testing.T) { switch runtime.GOOS { case "plan9", "windows": @@ -102,7 +275,6 @@ func TestUnixConnSpecificMethods(t *testing.T) { if err != nil { t.Fatalf("net.DialUnix failed: %v", err) } - c1.File() c1.LocalAddr() c1.RemoteAddr() c1.SetDeadline(time.Now().Add(100 * time.Millisecond)) @@ -115,13 +287,14 @@ func TestUnixConnSpecificMethods(t *testing.T) { a2, err := net.ResolveUnixAddr("unixgram", p2) if err != nil { - t.Fatalf("net.ResolveUnixAddr failed: %v", err) + t.Errorf("net.ResolveUnixAddr failed: %v", err) + return } c2, err := net.DialUnix("unixgram", a2, nil) if err != nil { - t.Fatalf("net.DialUnix failed: %v", err) + t.Errorf("net.DialUnix failed: %v", err) + return } - c2.File() c2.LocalAddr() c2.RemoteAddr() c2.SetDeadline(time.Now().Add(100 * time.Millisecond)) @@ -133,19 +306,33 @@ func TestUnixConnSpecificMethods(t *testing.T) { defer os.Remove(p2) wb := []byte("UNIXCONN TEST") - if _, _, err := c1.WriteMsgUnix(wb, nil, a2); err != nil { - t.Fatalf("net.UnixConn.WriteMsgUnix failed: %v", err) - } + rb1 := make([]byte, 128) rb2 := make([]byte, 128) + if _, _, err := c1.WriteMsgUnix(wb, nil, a2); err != nil { + t.Errorf("net.UnixConn.WriteMsgUnix failed: %v", err) + return + } if _, _, _, _, err := c2.ReadMsgUnix(rb2, nil); err != nil { - t.Fatalf("net.UnixConn.ReadMsgUnix failed: %v", err) + t.Errorf("net.UnixConn.ReadMsgUnix failed: %v", err) + return } if _, err := c2.WriteToUnix(wb, a1); err != nil { - t.Fatalf("net.UnixConn.WriteToUnix failed: %v", err) + t.Errorf("net.UnixConn.WriteToUnix failed: %v", err) + return } - rb1 := make([]byte, 128) if _, _, err := c1.ReadFromUnix(rb1); err != nil { - t.Fatalf("net.UnixConn.ReadFromUnix failed: %v", err) + t.Errorf("net.UnixConn.ReadFromUnix failed: %v", err) + return + } + + // TODO: http://golang.org/issue/3875 + net.ListenUnixgram("unixgram", nil) + + if f, err := c1.File(); err != nil { + t.Errorf("net.UnixConn.File failed: %v", err) + return + } else { + f.Close() } }