github.com/q45/go@v0.0.0-20151101211701-a4fb8c13db3f/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.Fatal(err) 28 } 29 c, err := ListenUnixgram("unixgram", la) 30 if err != nil { 31 t.Fatal(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.Error(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.Error(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.Fatal(err) 61 } 62 if from != nil { 63 t.Fatalf("unexpected peer address: %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 TestUnixgramZeroBytePayload(t *testing.T) { 71 if !testableNetwork("unixgram") { 72 t.Skip("unixgram test") 73 } 74 75 c1, err := newLocalPacketListener("unixgram") 76 if err != nil { 77 t.Fatal(err) 78 } 79 defer os.Remove(c1.LocalAddr().String()) 80 defer c1.Close() 81 82 c2, err := Dial("unixgram", c1.LocalAddr().String()) 83 if err != nil { 84 t.Fatal(err) 85 } 86 defer os.Remove(c2.LocalAddr().String()) 87 defer c2.Close() 88 89 for _, genericRead := range []bool{false, true} { 90 n, err := c2.Write(nil) 91 if err != nil { 92 t.Fatal(err) 93 } 94 if n != 0 { 95 t.Errorf("got %d; want 0", n) 96 } 97 c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) 98 var b [1]byte 99 var peer Addr 100 if genericRead { 101 _, err = c1.(Conn).Read(b[:]) 102 } else { 103 _, peer, err = c1.ReadFrom(b[:]) 104 } 105 switch err { 106 case nil: // ReadFrom succeeds 107 if peer != nil { // peer is connected-mode 108 t.Fatalf("unexpected peer address: %v", peer) 109 } 110 default: // Read may timeout, it depends on the platform 111 if nerr, ok := err.(Error); !ok || !nerr.Timeout() { 112 t.Fatal(err) 113 } 114 } 115 } 116 } 117 118 func TestUnixgramZeroByteBuffer(t *testing.T) { 119 if !testableNetwork("unixgram") { 120 t.Skip("unixgram test") 121 } 122 // issue 4352: Recvfrom failed with "address family not 123 // supported by protocol family" if zero-length buffer provided 124 125 c1, err := newLocalPacketListener("unixgram") 126 if err != nil { 127 t.Fatal(err) 128 } 129 defer os.Remove(c1.LocalAddr().String()) 130 defer c1.Close() 131 132 c2, err := Dial("unixgram", c1.LocalAddr().String()) 133 if err != nil { 134 t.Fatal(err) 135 } 136 defer os.Remove(c2.LocalAddr().String()) 137 defer c2.Close() 138 139 b := []byte("UNIXGRAM ZERO BYTE BUFFER TEST") 140 for _, genericRead := range []bool{false, true} { 141 n, err := c2.Write(b) 142 if err != nil { 143 t.Fatal(err) 144 } 145 if n != len(b) { 146 t.Errorf("got %d; want %d", n, len(b)) 147 } 148 c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) 149 var peer Addr 150 if genericRead { 151 _, err = c1.(Conn).Read(nil) 152 } else { 153 _, peer, err = c1.ReadFrom(nil) 154 } 155 switch err { 156 case nil: // ReadFrom succeeds 157 if peer != nil { // peer is connected-mode 158 t.Fatalf("unexpected peer address: %v", peer) 159 } 160 default: // Read may timeout, it depends on the platform 161 if nerr, ok := err.(Error); !ok || !nerr.Timeout() { 162 t.Fatal(err) 163 } 164 } 165 } 166 } 167 168 func TestUnixgramAutobind(t *testing.T) { 169 if runtime.GOOS != "linux" { 170 t.Skip("autobind is linux only") 171 } 172 173 laddr := &UnixAddr{Name: "", Net: "unixgram"} 174 c1, err := ListenUnixgram("unixgram", laddr) 175 if err != nil { 176 t.Fatal(err) 177 } 178 defer c1.Close() 179 180 // retrieve the autobind address 181 autoAddr := c1.LocalAddr().(*UnixAddr) 182 if len(autoAddr.Name) <= 1 { 183 t.Fatalf("invalid autobind address: %v", autoAddr) 184 } 185 if autoAddr.Name[0] != '@' { 186 t.Fatalf("invalid autobind address: %v", autoAddr) 187 } 188 189 c2, err := DialUnix("unixgram", nil, autoAddr) 190 if err != nil { 191 t.Fatal(err) 192 } 193 defer c2.Close() 194 195 if !reflect.DeepEqual(c1.LocalAddr(), c2.RemoteAddr()) { 196 t.Fatalf("expected autobind address %v, got %v", c1.LocalAddr(), c2.RemoteAddr()) 197 } 198 } 199 200 func TestUnixAutobindClose(t *testing.T) { 201 if runtime.GOOS != "linux" { 202 t.Skip("autobind is linux only") 203 } 204 205 laddr := &UnixAddr{Name: "", Net: "unix"} 206 ln, err := ListenUnix("unix", laddr) 207 if err != nil { 208 t.Fatal(err) 209 } 210 ln.Close() 211 } 212 213 func TestUnixgramWrite(t *testing.T) { 214 if !testableNetwork("unixgram") { 215 t.Skip("unixgram test") 216 } 217 218 addr := testUnixAddr() 219 laddr, err := ResolveUnixAddr("unixgram", addr) 220 if err != nil { 221 t.Fatal(err) 222 } 223 c, err := ListenPacket("unixgram", addr) 224 if err != nil { 225 t.Fatal(err) 226 } 227 defer os.Remove(addr) 228 defer c.Close() 229 230 testUnixgramWriteConn(t, laddr) 231 testUnixgramWritePacketConn(t, laddr) 232 } 233 234 func testUnixgramWriteConn(t *testing.T, raddr *UnixAddr) { 235 c, err := Dial("unixgram", raddr.String()) 236 if err != nil { 237 t.Fatal(err) 238 } 239 defer c.Close() 240 241 b := []byte("CONNECTED-MODE SOCKET") 242 if _, err := c.(*UnixConn).WriteToUnix(b, raddr); err == nil { 243 t.Fatal("should fail") 244 } else if err.(*OpError).Err != ErrWriteToConnected { 245 t.Fatalf("should fail as ErrWriteToConnected: %v", err) 246 } 247 if _, err = c.(*UnixConn).WriteTo(b, raddr); err == nil { 248 t.Fatal("should fail") 249 } else if err.(*OpError).Err != ErrWriteToConnected { 250 t.Fatalf("should fail as ErrWriteToConnected: %v", err) 251 } 252 if _, _, err = c.(*UnixConn).WriteMsgUnix(b, nil, raddr); err == nil { 253 t.Fatal("should fail") 254 } else if err.(*OpError).Err != ErrWriteToConnected { 255 t.Fatalf("should fail as ErrWriteToConnected: %v", err) 256 } 257 if _, err := c.Write(b); err != nil { 258 t.Fatal(err) 259 } 260 } 261 262 func testUnixgramWritePacketConn(t *testing.T, raddr *UnixAddr) { 263 addr := testUnixAddr() 264 c, err := ListenPacket("unixgram", addr) 265 if err != nil { 266 t.Fatal(err) 267 } 268 defer os.Remove(addr) 269 defer c.Close() 270 271 b := []byte("UNCONNECTED-MODE SOCKET") 272 if _, err := c.(*UnixConn).WriteToUnix(b, raddr); err != nil { 273 t.Fatal(err) 274 } 275 if _, err := c.WriteTo(b, raddr); err != nil { 276 t.Fatal(err) 277 } 278 if _, _, err := c.(*UnixConn).WriteMsgUnix(b, nil, raddr); err != nil { 279 t.Fatal(err) 280 } 281 if _, err := c.(*UnixConn).Write(b); err == nil { 282 t.Fatal("should fail") 283 } 284 } 285 286 func TestUnixConnLocalAndRemoteNames(t *testing.T) { 287 if !testableNetwork("unix") { 288 t.Skip("unix test") 289 } 290 291 handler := func(ls *localServer, ln Listener) {} 292 for _, laddr := range []string{"", testUnixAddr()} { 293 laddr := laddr 294 taddr := testUnixAddr() 295 ta, err := ResolveUnixAddr("unix", taddr) 296 if err != nil { 297 t.Fatal(err) 298 } 299 ln, err := ListenUnix("unix", ta) 300 if err != nil { 301 t.Fatal(err) 302 } 303 ls, err := (&streamListener{Listener: ln}).newLocalServer() 304 if err != nil { 305 t.Fatal(err) 306 } 307 defer ls.teardown() 308 if err := ls.buildup(handler); err != nil { 309 t.Fatal(err) 310 } 311 312 la, err := ResolveUnixAddr("unix", laddr) 313 if err != nil { 314 t.Fatal(err) 315 } 316 c, err := DialUnix("unix", la, ta) 317 if err != nil { 318 t.Fatal(err) 319 } 320 defer func() { 321 c.Close() 322 if la != nil { 323 defer os.Remove(laddr) 324 } 325 }() 326 if _, err := c.Write([]byte("UNIXCONN LOCAL AND REMOTE NAME TEST")); err != nil { 327 t.Fatal(err) 328 } 329 330 switch runtime.GOOS { 331 case "android", "linux": 332 if laddr == "" { 333 laddr = "@" // autobind feature 334 } 335 } 336 var connAddrs = [3]struct{ got, want Addr }{ 337 {ln.Addr(), ta}, 338 {c.LocalAddr(), &UnixAddr{Name: laddr, Net: "unix"}}, 339 {c.RemoteAddr(), ta}, 340 } 341 for _, ca := range connAddrs { 342 if !reflect.DeepEqual(ca.got, ca.want) { 343 t.Fatalf("got %#v, expected %#v", ca.got, ca.want) 344 } 345 } 346 } 347 } 348 349 func TestUnixgramConnLocalAndRemoteNames(t *testing.T) { 350 if !testableNetwork("unixgram") { 351 t.Skip("unixgram test") 352 } 353 354 for _, laddr := range []string{"", testUnixAddr()} { 355 laddr := laddr 356 taddr := testUnixAddr() 357 ta, err := ResolveUnixAddr("unixgram", taddr) 358 if err != nil { 359 t.Fatal(err) 360 } 361 c1, err := ListenUnixgram("unixgram", ta) 362 if err != nil { 363 t.Fatal(err) 364 } 365 defer func() { 366 c1.Close() 367 os.Remove(taddr) 368 }() 369 370 var la *UnixAddr 371 if laddr != "" { 372 if la, err = ResolveUnixAddr("unixgram", laddr); err != nil { 373 t.Fatal(err) 374 } 375 } 376 c2, err := DialUnix("unixgram", la, ta) 377 if err != nil { 378 t.Fatal(err) 379 } 380 defer func() { 381 c2.Close() 382 if la != nil { 383 defer os.Remove(laddr) 384 } 385 }() 386 387 switch runtime.GOOS { 388 case "android", "linux": 389 if laddr == "" { 390 laddr = "@" // autobind feature 391 } 392 } 393 394 var connAddrs = [4]struct{ got, want Addr }{ 395 {c1.LocalAddr(), ta}, 396 {c1.RemoteAddr(), nil}, 397 {c2.LocalAddr(), &UnixAddr{Name: laddr, Net: "unixgram"}}, 398 {c2.RemoteAddr(), ta}, 399 } 400 for _, ca := range connAddrs { 401 if !reflect.DeepEqual(ca.got, ca.want) { 402 t.Fatalf("got %#v; want %#v", ca.got, ca.want) 403 } 404 } 405 } 406 } 407 408 // forceGoDNS forces the resolver configuration to use the pure Go resolver 409 // and returns a fixup function to restore the old settings. 410 func forceGoDNS() func() { 411 c := systemConf() 412 oldGo := c.netGo 413 oldCgo := c.netCgo 414 fixup := func() { 415 c.netGo = oldGo 416 c.netCgo = oldCgo 417 } 418 c.netGo = true 419 c.netCgo = false 420 return fixup 421 } 422 423 // forceCgoDNS forces the resolver configuration to use the cgo resolver 424 // and returns true to indicate that it did so. 425 // (On non-Unix systems forceCgoDNS returns false.) 426 func forceCgoDNS() bool { 427 c := systemConf() 428 c.netGo = false 429 c.netCgo = true 430 return true 431 }