github.com/spotify/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/pkg/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 !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 TestUnixConnLocalAndRemoteNames(t *testing.T) {
   155  	for _, laddr := range []string{"", testUnixAddr()} {
   156  		laddr := laddr
   157  		taddr := testUnixAddr()
   158  		ta, err := ResolveUnixAddr("unix", taddr)
   159  		if err != nil {
   160  			t.Fatalf("ResolveUnixAddr failed: %v", err)
   161  		}
   162  		ln, err := ListenUnix("unix", ta)
   163  		if err != nil {
   164  			t.Fatalf("ListenUnix failed: %v", err)
   165  		}
   166  		defer func() {
   167  			ln.Close()
   168  			os.Remove(taddr)
   169  		}()
   170  
   171  		done := make(chan int)
   172  		go transponder(t, ln, done)
   173  
   174  		la, err := ResolveUnixAddr("unix", laddr)
   175  		if err != nil {
   176  			t.Fatalf("ResolveUnixAddr failed: %v", err)
   177  		}
   178  		c, err := DialUnix("unix", la, ta)
   179  		if err != nil {
   180  			t.Fatalf("DialUnix failed: %v", err)
   181  		}
   182  		defer func() {
   183  			c.Close()
   184  			if la != nil {
   185  				defer os.Remove(laddr)
   186  			}
   187  		}()
   188  		if _, err := c.Write([]byte("UNIXCONN LOCAL AND REMOTE NAME TEST")); err != nil {
   189  			t.Fatalf("UnixConn.Write failed: %v", err)
   190  		}
   191  
   192  		if runtime.GOOS == "linux" && laddr == "" {
   193  			laddr = "@" // autobind feature
   194  		}
   195  		var connAddrs = [3]struct{ got, want Addr }{
   196  			{ln.Addr(), ta},
   197  			{c.LocalAddr(), &UnixAddr{Name: laddr, Net: "unix"}},
   198  			{c.RemoteAddr(), ta},
   199  		}
   200  		for _, ca := range connAddrs {
   201  			if !reflect.DeepEqual(ca.got, ca.want) {
   202  				t.Fatalf("got %#v, expected %#v", ca.got, ca.want)
   203  			}
   204  		}
   205  
   206  		<-done
   207  	}
   208  }
   209  
   210  func TestUnixgramConnLocalAndRemoteNames(t *testing.T) {
   211  	for _, laddr := range []string{"", testUnixAddr()} {
   212  		laddr := laddr
   213  		taddr := testUnixAddr()
   214  		ta, err := ResolveUnixAddr("unixgram", taddr)
   215  		if err != nil {
   216  			t.Fatalf("ResolveUnixAddr failed: %v", err)
   217  		}
   218  		c1, err := ListenUnixgram("unixgram", ta)
   219  		if err != nil {
   220  			t.Fatalf("ListenUnixgram failed: %v", err)
   221  		}
   222  		defer func() {
   223  			c1.Close()
   224  			os.Remove(taddr)
   225  		}()
   226  
   227  		var la *UnixAddr
   228  		if laddr != "" {
   229  			if la, err = ResolveUnixAddr("unixgram", laddr); err != nil {
   230  				t.Fatalf("ResolveUnixAddr failed: %v", err)
   231  			}
   232  		}
   233  		c2, err := DialUnix("unixgram", la, ta)
   234  		if err != nil {
   235  			t.Fatalf("DialUnix failed: %v", err)
   236  		}
   237  		defer func() {
   238  			c2.Close()
   239  			if la != nil {
   240  				defer os.Remove(laddr)
   241  			}
   242  		}()
   243  
   244  		if runtime.GOOS == "linux" && laddr == "" {
   245  			laddr = "@" // autobind feature
   246  		}
   247  		var connAddrs = [4]struct{ got, want Addr }{
   248  			{c1.LocalAddr(), ta},
   249  			{c1.RemoteAddr(), nil},
   250  			{c2.LocalAddr(), &UnixAddr{Name: laddr, Net: "unixgram"}},
   251  			{c2.RemoteAddr(), ta},
   252  		}
   253  		for _, ca := range connAddrs {
   254  			if !reflect.DeepEqual(ca.got, ca.want) {
   255  				t.Fatalf("got %#v, expected %#v", ca.got, ca.want)
   256  			}
   257  		}
   258  	}
   259  }