diff options
author | Tianon Gravi <admwiggin@gmail.com> | 2015-01-15 11:54:00 -0700 |
---|---|---|
committer | Tianon Gravi <admwiggin@gmail.com> | 2015-01-15 11:54:00 -0700 |
commit | f154da9e12608589e8d5f0508f908a0c3e88a1bb (patch) | |
tree | f8255d51e10c6f1e0ed69702200b966c9556a431 /src/net/unix_test.go | |
parent | 8d8329ed5dfb9622c82a9fbec6fd99a580f9c9f6 (diff) | |
download | golang-upstream/1.4.tar.gz |
Imported Upstream version 1.4upstream/1.4
Diffstat (limited to 'src/net/unix_test.go')
-rw-r--r-- | src/net/unix_test.go | 333 |
1 files changed, 333 insertions, 0 deletions
diff --git a/src/net/unix_test.go b/src/net/unix_test.go new file mode 100644 index 000000000..1cdff3908 --- /dev/null +++ b/src/net/unix_test.go @@ -0,0 +1,333 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !nacl,!plan9,!windows + +package net + +import ( + "bytes" + "os" + "reflect" + "runtime" + "syscall" + "testing" + "time" +) + +func TestReadUnixgramWithUnnamedSocket(t *testing.T) { + addr := testUnixAddr() + la, err := ResolveUnixAddr("unixgram", addr) + if err != nil { + t.Fatalf("ResolveUnixAddr failed: %v", err) + } + c, err := ListenUnixgram("unixgram", la) + if err != nil { + t.Fatalf("ListenUnixgram failed: %v", err) + } + defer func() { + c.Close() + os.Remove(addr) + }() + + off := make(chan bool) + data := [5]byte{1, 2, 3, 4, 5} + go func() { + defer func() { off <- true }() + s, err := syscall.Socket(syscall.AF_UNIX, syscall.SOCK_DGRAM, 0) + if err != nil { + t.Errorf("syscall.Socket failed: %v", err) + return + } + defer syscall.Close(s) + rsa := &syscall.SockaddrUnix{Name: addr} + if err := syscall.Sendto(s, data[:], 0, rsa); err != nil { + t.Errorf("syscall.Sendto failed: %v", err) + return + } + }() + + <-off + b := make([]byte, 64) + c.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) + n, from, err := c.ReadFrom(b) + if err != nil { + t.Fatalf("UnixConn.ReadFrom failed: %v", err) + } + if from != nil { + t.Fatalf("neighbor address is %v", from) + } + if !bytes.Equal(b[:n], data[:]) { + t.Fatalf("got %v, want %v", b[:n], data[:]) + } +} + +func TestReadUnixgramWithZeroBytesBuffer(t *testing.T) { + // issue 4352: Recvfrom failed with "address family not + // supported by protocol family" if zero-length buffer provided + + addr := testUnixAddr() + la, err := ResolveUnixAddr("unixgram", addr) + if err != nil { + t.Fatalf("ResolveUnixAddr failed: %v", err) + } + c, err := ListenUnixgram("unixgram", la) + if err != nil { + t.Fatalf("ListenUnixgram failed: %v", err) + } + defer func() { + c.Close() + os.Remove(addr) + }() + + off := make(chan bool) + go func() { + defer func() { off <- true }() + c, err := DialUnix("unixgram", nil, la) + if err != nil { + t.Errorf("DialUnix failed: %v", err) + return + } + defer c.Close() + if _, err := c.Write([]byte{1, 2, 3, 4, 5}); err != nil { + t.Errorf("UnixConn.Write failed: %v", err) + return + } + }() + + <-off + c.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) + _, from, err := c.ReadFrom(nil) + if err != nil { + t.Fatalf("UnixConn.ReadFrom failed: %v", err) + } + if from != nil { + t.Fatalf("neighbor address is %v", from) + } +} + +func TestUnixgramAutobind(t *testing.T) { + if runtime.GOOS != "linux" { + t.Skip("skipping: autobind is linux only") + } + + laddr := &UnixAddr{Name: "", Net: "unixgram"} + c1, err := ListenUnixgram("unixgram", laddr) + if err != nil { + t.Fatalf("ListenUnixgram failed: %v", err) + } + defer c1.Close() + + // retrieve the autobind address + autoAddr := c1.LocalAddr().(*UnixAddr) + if len(autoAddr.Name) <= 1 { + t.Fatalf("invalid autobind address: %v", autoAddr) + } + if autoAddr.Name[0] != '@' { + t.Fatalf("invalid autobind address: %v", autoAddr) + } + + c2, err := DialUnix("unixgram", nil, autoAddr) + if err != nil { + t.Fatalf("DialUnix failed: %v", err) + } + defer c2.Close() + + if !reflect.DeepEqual(c1.LocalAddr(), c2.RemoteAddr()) { + t.Fatalf("expected autobind address %v, got %v", c1.LocalAddr(), c2.RemoteAddr()) + } +} + +func TestUnixAutobindClose(t *testing.T) { + if runtime.GOOS != "linux" { + t.Skip("skipping: autobind is linux only") + } + laddr := &UnixAddr{Name: "", Net: "unix"} + ln, err := ListenUnix("unix", laddr) + if err != nil { + t.Fatalf("ListenUnix failed: %v", err) + } + ln.Close() +} + +func TestUnixgramWrite(t *testing.T) { + addr := testUnixAddr() + laddr, err := ResolveUnixAddr("unixgram", addr) + if err != nil { + t.Fatalf("ResolveUnixAddr failed: %v", err) + } + c, err := ListenPacket("unixgram", addr) + if err != nil { + t.Fatalf("ListenPacket failed: %v", err) + } + defer os.Remove(addr) + defer c.Close() + + testUnixgramWriteConn(t, laddr) + testUnixgramWritePacketConn(t, laddr) +} + +func testUnixgramWriteConn(t *testing.T, raddr *UnixAddr) { + c, err := Dial("unixgram", raddr.String()) + if err != nil { + t.Fatalf("Dial failed: %v", err) + } + defer c.Close() + + if _, err := c.(*UnixConn).WriteToUnix([]byte("Connection-oriented mode socket"), raddr); err == nil { + t.Fatal("WriteToUnix should fail") + } else if err.(*OpError).Err != ErrWriteToConnected { + t.Fatalf("WriteToUnix should fail as ErrWriteToConnected: %v", err) + } + if _, err = c.(*UnixConn).WriteTo([]byte("Connection-oriented mode socket"), raddr); err == nil { + t.Fatal("WriteTo should fail") + } else if err.(*OpError).Err != ErrWriteToConnected { + t.Fatalf("WriteTo should fail as ErrWriteToConnected: %v", err) + } + if _, _, err = c.(*UnixConn).WriteMsgUnix([]byte("Connection-oriented mode socket"), nil, raddr); err == nil { + t.Fatal("WriteTo should fail") + } else if err.(*OpError).Err != ErrWriteToConnected { + t.Fatalf("WriteMsgUnix should fail as ErrWriteToConnected: %v", err) + } + if _, err := c.Write([]byte("Connection-oriented mode socket")); err != nil { + t.Fatalf("Write failed: %v", err) + } +} + +func testUnixgramWritePacketConn(t *testing.T, raddr *UnixAddr) { + addr := testUnixAddr() + c, err := ListenPacket("unixgram", addr) + if err != nil { + t.Fatalf("ListenPacket failed: %v", err) + } + defer os.Remove(addr) + defer c.Close() + + if _, err := c.(*UnixConn).WriteToUnix([]byte("Connectionless mode socket"), raddr); err != nil { + t.Fatalf("WriteToUnix failed: %v", err) + } + if _, err := c.WriteTo([]byte("Connectionless mode socket"), raddr); err != nil { + t.Fatalf("WriteTo failed: %v", err) + } + if _, _, err := c.(*UnixConn).WriteMsgUnix([]byte("Connectionless mode socket"), nil, raddr); err != nil { + t.Fatalf("WriteMsgUnix failed: %v", err) + } + if _, err := c.(*UnixConn).Write([]byte("Connectionless mode socket")); err == nil { + t.Fatal("Write should fail") + } +} + +func TestUnixConnLocalAndRemoteNames(t *testing.T) { + for _, laddr := range []string{"", testUnixAddr()} { + laddr := laddr + taddr := testUnixAddr() + ta, err := ResolveUnixAddr("unix", taddr) + if err != nil { + t.Fatalf("ResolveUnixAddr failed: %v", err) + } + ln, err := ListenUnix("unix", ta) + if err != nil { + t.Fatalf("ListenUnix failed: %v", err) + } + defer func() { + ln.Close() + os.Remove(taddr) + }() + + done := make(chan int) + go transponder(t, ln, done) + + la, err := ResolveUnixAddr("unix", laddr) + if err != nil { + t.Fatalf("ResolveUnixAddr failed: %v", err) + } + c, err := DialUnix("unix", la, ta) + if err != nil { + t.Fatalf("DialUnix failed: %v", err) + } + defer func() { + c.Close() + if la != nil { + defer os.Remove(laddr) + } + }() + if _, err := c.Write([]byte("UNIXCONN LOCAL AND REMOTE NAME TEST")); err != nil { + t.Fatalf("UnixConn.Write failed: %v", err) + } + + switch runtime.GOOS { + case "android", "linux": + if laddr == "" { + laddr = "@" // autobind feature + } + } + var connAddrs = [3]struct{ got, want Addr }{ + {ln.Addr(), ta}, + {c.LocalAddr(), &UnixAddr{Name: laddr, Net: "unix"}}, + {c.RemoteAddr(), ta}, + } + for _, ca := range connAddrs { + if !reflect.DeepEqual(ca.got, ca.want) { + t.Fatalf("got %#v, expected %#v", ca.got, ca.want) + } + } + + <-done + } +} + +func TestUnixgramConnLocalAndRemoteNames(t *testing.T) { + for _, laddr := range []string{"", testUnixAddr()} { + laddr := laddr + taddr := testUnixAddr() + ta, err := ResolveUnixAddr("unixgram", taddr) + if err != nil { + t.Fatalf("ResolveUnixAddr failed: %v", err) + } + c1, err := ListenUnixgram("unixgram", ta) + if err != nil { + t.Fatalf("ListenUnixgram failed: %v", err) + } + defer func() { + c1.Close() + os.Remove(taddr) + }() + + var la *UnixAddr + if laddr != "" { + if la, err = ResolveUnixAddr("unixgram", laddr); err != nil { + t.Fatalf("ResolveUnixAddr failed: %v", err) + } + } + c2, err := DialUnix("unixgram", la, ta) + if err != nil { + t.Fatalf("DialUnix failed: %v", err) + } + defer func() { + c2.Close() + if la != nil { + defer os.Remove(laddr) + } + }() + + switch runtime.GOOS { + case "android", "linux": + if laddr == "" { + laddr = "@" // autobind feature + } + } + + var connAddrs = [4]struct{ got, want Addr }{ + {c1.LocalAddr(), ta}, + {c1.RemoteAddr(), nil}, + {c2.LocalAddr(), &UnixAddr{Name: laddr, Net: "unixgram"}}, + {c2.RemoteAddr(), ta}, + } + for _, ca := range connAddrs { + if !reflect.DeepEqual(ca.got, ca.want) { + t.Fatalf("got %#v, expected %#v", ca.got, ca.want) + } + } + } +} |