github.com/tcnksm/go@v0.0.0-20141208075154-439b32936367/src/net/unix_test.go (about)

     1  // Copyright 2013 The Go Authors.  All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build !nacl,!plan9,!windows
     6  
     7  package net
     8  
     9  import (
    10  	"bytes"
    11  	"os"
    12  	"reflect"
    13  	"runtime"
    14  	"syscall"
    15  	"testing"
    16  	"time"
    17  )
    18  
    19  func TestReadUnixgramWithUnnamedSocket(t *testing.T) {
    20  	addr := testUnixAddr()
    21  	la, err := ResolveUnixAddr("unixgram", addr)
    22  	if err != nil {
    23  		t.Fatalf("ResolveUnixAddr failed: %v", err)
    24  	}
    25  	c, err := ListenUnixgram("unixgram", la)
    26  	if err != nil {
    27  		t.Fatalf("ListenUnixgram failed: %v", err)
    28  	}
    29  	defer func() {
    30  		c.Close()
    31  		os.Remove(addr)
    32  	}()
    33  
    34  	off := make(chan bool)
    35  	data := [5]byte{1, 2, 3, 4, 5}
    36  	go func() {
    37  		defer func() { off <- true }()
    38  		s, err := syscall.Socket(syscall.AF_UNIX, syscall.SOCK_DGRAM, 0)
    39  		if err != nil {
    40  			t.Errorf("syscall.Socket failed: %v", err)
    41  			return
    42  		}
    43  		defer syscall.Close(s)
    44  		rsa := &syscall.SockaddrUnix{Name: addr}
    45  		if err := syscall.Sendto(s, data[:], 0, rsa); err != nil {
    46  			t.Errorf("syscall.Sendto failed: %v", err)
    47  			return
    48  		}
    49  	}()
    50  
    51  	<-off
    52  	b := make([]byte, 64)
    53  	c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
    54  	n, from, err := c.ReadFrom(b)
    55  	if err != nil {
    56  		t.Fatalf("UnixConn.ReadFrom failed: %v", err)
    57  	}
    58  	if from != nil {
    59  		t.Fatalf("neighbor address is %v", from)
    60  	}
    61  	if !bytes.Equal(b[:n], data[:]) {
    62  		t.Fatalf("got %v, want %v", b[:n], data[:])
    63  	}
    64  }
    65  
    66  func TestReadUnixgramWithZeroBytesBuffer(t *testing.T) {
    67  	// issue 4352: Recvfrom failed with "address family not
    68  	// supported by protocol family" if zero-length buffer provided
    69  
    70  	addr := testUnixAddr()
    71  	la, err := ResolveUnixAddr("unixgram", addr)
    72  	if err != nil {
    73  		t.Fatalf("ResolveUnixAddr failed: %v", err)
    74  	}
    75  	c, err := ListenUnixgram("unixgram", la)
    76  	if err != nil {
    77  		t.Fatalf("ListenUnixgram failed: %v", err)
    78  	}
    79  	defer func() {
    80  		c.Close()
    81  		os.Remove(addr)
    82  	}()
    83  
    84  	off := make(chan bool)
    85  	go func() {
    86  		defer func() { off <- true }()
    87  		c, err := DialUnix("unixgram", nil, la)
    88  		if err != nil {
    89  			t.Errorf("DialUnix failed: %v", err)
    90  			return
    91  		}
    92  		defer c.Close()
    93  		if _, err := c.Write([]byte{1, 2, 3, 4, 5}); err != nil {
    94  			t.Errorf("UnixConn.Write failed: %v", err)
    95  			return
    96  		}
    97  	}()
    98  
    99  	<-off
   100  	c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
   101  	_, from, err := c.ReadFrom(nil)
   102  	if err != nil {
   103  		t.Fatalf("UnixConn.ReadFrom failed: %v", err)
   104  	}
   105  	if from != nil {
   106  		t.Fatalf("neighbor address is %v", from)
   107  	}
   108  }
   109  
   110  func TestUnixgramAutobind(t *testing.T) {
   111  	if runtime.GOOS != "linux" {
   112  		t.Skip("skipping: autobind is linux only")
   113  	}
   114  
   115  	laddr := &UnixAddr{Name: "", Net: "unixgram"}
   116  	c1, err := ListenUnixgram("unixgram", laddr)
   117  	if err != nil {
   118  		t.Fatalf("ListenUnixgram failed: %v", err)
   119  	}
   120  	defer c1.Close()
   121  
   122  	// retrieve the autobind address
   123  	autoAddr := c1.LocalAddr().(*UnixAddr)
   124  	if len(autoAddr.Name) <= 1 {
   125  		t.Fatalf("invalid autobind address: %v", autoAddr)
   126  	}
   127  	if autoAddr.Name[0] != '@' {
   128  		t.Fatalf("invalid autobind address: %v", autoAddr)
   129  	}
   130  
   131  	c2, err := DialUnix("unixgram", nil, autoAddr)
   132  	if err != nil {
   133  		t.Fatalf("DialUnix failed: %v", err)
   134  	}
   135  	defer c2.Close()
   136  
   137  	if !reflect.DeepEqual(c1.LocalAddr(), c2.RemoteAddr()) {
   138  		t.Fatalf("expected autobind address %v, got %v", c1.LocalAddr(), c2.RemoteAddr())
   139  	}
   140  }
   141  
   142  func TestUnixAutobindClose(t *testing.T) {
   143  	if runtime.GOOS != "linux" {
   144  		t.Skip("skipping: autobind is linux only")
   145  	}
   146  	laddr := &UnixAddr{Name: "", Net: "unix"}
   147  	ln, err := ListenUnix("unix", laddr)
   148  	if err != nil {
   149  		t.Fatalf("ListenUnix failed: %v", err)
   150  	}
   151  	ln.Close()
   152  }
   153  
   154  func TestUnixgramWrite(t *testing.T) {
   155  	addr := testUnixAddr()
   156  	laddr, err := ResolveUnixAddr("unixgram", addr)
   157  	if err != nil {
   158  		t.Fatalf("ResolveUnixAddr failed: %v", err)
   159  	}
   160  	c, err := ListenPacket("unixgram", addr)
   161  	if err != nil {
   162  		t.Fatalf("ListenPacket failed: %v", err)
   163  	}
   164  	defer os.Remove(addr)
   165  	defer c.Close()
   166  
   167  	testUnixgramWriteConn(t, laddr)
   168  	testUnixgramWritePacketConn(t, laddr)
   169  }
   170  
   171  func testUnixgramWriteConn(t *testing.T, raddr *UnixAddr) {
   172  	c, err := Dial("unixgram", raddr.String())
   173  	if err != nil {
   174  		t.Fatalf("Dial failed: %v", err)
   175  	}
   176  	defer c.Close()
   177  
   178  	if _, err := c.(*UnixConn).WriteToUnix([]byte("Connection-oriented mode socket"), raddr); err == nil {
   179  		t.Fatal("WriteToUnix should fail")
   180  	} else if err.(*OpError).Err != ErrWriteToConnected {
   181  		t.Fatalf("WriteToUnix should fail as ErrWriteToConnected: %v", err)
   182  	}
   183  	if _, err = c.(*UnixConn).WriteTo([]byte("Connection-oriented mode socket"), raddr); err == nil {
   184  		t.Fatal("WriteTo should fail")
   185  	} else if err.(*OpError).Err != ErrWriteToConnected {
   186  		t.Fatalf("WriteTo should fail as ErrWriteToConnected: %v", err)
   187  	}
   188  	if _, _, err = c.(*UnixConn).WriteMsgUnix([]byte("Connection-oriented mode socket"), nil, raddr); err == nil {
   189  		t.Fatal("WriteTo should fail")
   190  	} else if err.(*OpError).Err != ErrWriteToConnected {
   191  		t.Fatalf("WriteMsgUnix should fail as ErrWriteToConnected: %v", err)
   192  	}
   193  	if _, err := c.Write([]byte("Connection-oriented mode socket")); err != nil {
   194  		t.Fatalf("Write failed: %v", err)
   195  	}
   196  }
   197  
   198  func testUnixgramWritePacketConn(t *testing.T, raddr *UnixAddr) {
   199  	addr := testUnixAddr()
   200  	c, err := ListenPacket("unixgram", addr)
   201  	if err != nil {
   202  		t.Fatalf("ListenPacket failed: %v", err)
   203  	}
   204  	defer os.Remove(addr)
   205  	defer c.Close()
   206  
   207  	if _, err := c.(*UnixConn).WriteToUnix([]byte("Connectionless mode socket"), raddr); err != nil {
   208  		t.Fatalf("WriteToUnix failed: %v", err)
   209  	}
   210  	if _, err := c.WriteTo([]byte("Connectionless mode socket"), raddr); err != nil {
   211  		t.Fatalf("WriteTo failed: %v", err)
   212  	}
   213  	if _, _, err := c.(*UnixConn).WriteMsgUnix([]byte("Connectionless mode socket"), nil, raddr); err != nil {
   214  		t.Fatalf("WriteMsgUnix failed: %v", err)
   215  	}
   216  	if _, err := c.(*UnixConn).Write([]byte("Connectionless mode socket")); err == nil {
   217  		t.Fatal("Write should fail")
   218  	}
   219  }
   220  
   221  func TestUnixConnLocalAndRemoteNames(t *testing.T) {
   222  	for _, laddr := range []string{"", testUnixAddr()} {
   223  		laddr := laddr
   224  		taddr := testUnixAddr()
   225  		ta, err := ResolveUnixAddr("unix", taddr)
   226  		if err != nil {
   227  			t.Fatalf("ResolveUnixAddr failed: %v", err)
   228  		}
   229  		ln, err := ListenUnix("unix", ta)
   230  		if err != nil {
   231  			t.Fatalf("ListenUnix failed: %v", err)
   232  		}
   233  		defer func() {
   234  			ln.Close()
   235  			os.Remove(taddr)
   236  		}()
   237  
   238  		done := make(chan int)
   239  		go transponder(t, ln, done)
   240  
   241  		la, err := ResolveUnixAddr("unix", laddr)
   242  		if err != nil {
   243  			t.Fatalf("ResolveUnixAddr failed: %v", err)
   244  		}
   245  		c, err := DialUnix("unix", la, ta)
   246  		if err != nil {
   247  			t.Fatalf("DialUnix failed: %v", err)
   248  		}
   249  		defer func() {
   250  			c.Close()
   251  			if la != nil {
   252  				defer os.Remove(laddr)
   253  			}
   254  		}()
   255  		if _, err := c.Write([]byte("UNIXCONN LOCAL AND REMOTE NAME TEST")); err != nil {
   256  			t.Fatalf("UnixConn.Write failed: %v", err)
   257  		}
   258  
   259  		switch runtime.GOOS {
   260  		case "android", "linux":
   261  			if laddr == "" {
   262  				laddr = "@" // autobind feature
   263  			}
   264  		}
   265  		var connAddrs = [3]struct{ got, want Addr }{
   266  			{ln.Addr(), ta},
   267  			{c.LocalAddr(), &UnixAddr{Name: laddr, Net: "unix"}},
   268  			{c.RemoteAddr(), ta},
   269  		}
   270  		for _, ca := range connAddrs {
   271  			if !reflect.DeepEqual(ca.got, ca.want) {
   272  				t.Fatalf("got %#v, expected %#v", ca.got, ca.want)
   273  			}
   274  		}
   275  
   276  		<-done
   277  	}
   278  }
   279  
   280  func TestUnixgramConnLocalAndRemoteNames(t *testing.T) {
   281  	for _, laddr := range []string{"", testUnixAddr()} {
   282  		laddr := laddr
   283  		taddr := testUnixAddr()
   284  		ta, err := ResolveUnixAddr("unixgram", taddr)
   285  		if err != nil {
   286  			t.Fatalf("ResolveUnixAddr failed: %v", err)
   287  		}
   288  		c1, err := ListenUnixgram("unixgram", ta)
   289  		if err != nil {
   290  			t.Fatalf("ListenUnixgram failed: %v", err)
   291  		}
   292  		defer func() {
   293  			c1.Close()
   294  			os.Remove(taddr)
   295  		}()
   296  
   297  		var la *UnixAddr
   298  		if laddr != "" {
   299  			if la, err = ResolveUnixAddr("unixgram", laddr); err != nil {
   300  				t.Fatalf("ResolveUnixAddr failed: %v", err)
   301  			}
   302  		}
   303  		c2, err := DialUnix("unixgram", la, ta)
   304  		if err != nil {
   305  			t.Fatalf("DialUnix failed: %v", err)
   306  		}
   307  		defer func() {
   308  			c2.Close()
   309  			if la != nil {
   310  				defer os.Remove(laddr)
   311  			}
   312  		}()
   313  
   314  		switch runtime.GOOS {
   315  		case "android", "linux":
   316  			if laddr == "" {
   317  				laddr = "@" // autobind feature
   318  			}
   319  		}
   320  
   321  		var connAddrs = [4]struct{ got, want Addr }{
   322  			{c1.LocalAddr(), ta},
   323  			{c1.RemoteAddr(), nil},
   324  			{c2.LocalAddr(), &UnixAddr{Name: laddr, Net: "unixgram"}},
   325  			{c2.RemoteAddr(), ta},
   326  		}
   327  		for _, ca := range connAddrs {
   328  			if !reflect.DeepEqual(ca.got, ca.want) {
   329  				t.Fatalf("got %#v, expected %#v", ca.got, ca.want)
   330  			}
   331  		}
   332  	}
   333  }