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