github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/src/pkg/net/server_test.go (about) 1 // Copyright 2009 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 package net 6 7 import ( 8 "flag" 9 "io" 10 "os" 11 "runtime" 12 "testing" 13 "time" 14 ) 15 16 func skipServerTest(net, unixsotype, addr string, ipv6, ipv4map, linuxOnly bool) bool { 17 switch runtime.GOOS { 18 case "linux": 19 case "nacl", "plan9", "windows": 20 // "unix" sockets are not supported on Windows and Plan 9. 21 if net == unixsotype { 22 return true 23 } 24 default: 25 if net == unixsotype && linuxOnly { 26 return true 27 } 28 } 29 switch addr { 30 case "", "0.0.0.0", "[::ffff:0.0.0.0]", "[::]": 31 if testing.Short() || !*testExternal { 32 return true 33 } 34 } 35 if ipv6 && !supportsIPv6 { 36 return true 37 } 38 if ipv4map && !supportsIPv4map { 39 return true 40 } 41 return false 42 } 43 44 var streamConnServerTests = []struct { 45 snet string // server side 46 saddr string 47 cnet string // client side 48 caddr string 49 ipv6 bool // test with underlying AF_INET6 socket 50 ipv4map bool // test with IPv6 IPv4-mapping functionality 51 empty bool // test with empty data 52 linuxOnly bool // test with abstract unix domain socket, a Linux-ism 53 }{ 54 {snet: "tcp", saddr: "", cnet: "tcp", caddr: "127.0.0.1"}, 55 {snet: "tcp", saddr: "0.0.0.0", cnet: "tcp", caddr: "127.0.0.1"}, 56 {snet: "tcp", saddr: "[::ffff:0.0.0.0]", cnet: "tcp", caddr: "127.0.0.1"}, 57 {snet: "tcp", saddr: "[::]", cnet: "tcp", caddr: "[::1]", ipv6: true}, 58 59 {snet: "tcp", saddr: "", cnet: "tcp", caddr: "[::1]", ipv4map: true}, 60 {snet: "tcp", saddr: "0.0.0.0", cnet: "tcp", caddr: "[::1]", ipv4map: true}, 61 {snet: "tcp", saddr: "[::ffff:0.0.0.0]", cnet: "tcp", caddr: "[::1]", ipv4map: true}, 62 {snet: "tcp", saddr: "[::]", cnet: "tcp", caddr: "127.0.0.1", ipv4map: true}, 63 64 {snet: "tcp", saddr: "", cnet: "tcp4", caddr: "127.0.0.1"}, 65 {snet: "tcp", saddr: "0.0.0.0", cnet: "tcp4", caddr: "127.0.0.1"}, 66 {snet: "tcp", saddr: "[::ffff:0.0.0.0]", cnet: "tcp4", caddr: "127.0.0.1"}, 67 {snet: "tcp", saddr: "[::]", cnet: "tcp6", caddr: "[::1]", ipv6: true}, 68 69 {snet: "tcp", saddr: "", cnet: "tcp6", caddr: "[::1]", ipv4map: true}, 70 {snet: "tcp", saddr: "0.0.0.0", cnet: "tcp6", caddr: "[::1]", ipv4map: true}, 71 {snet: "tcp", saddr: "[::ffff:0.0.0.0]", cnet: "tcp6", caddr: "[::1]", ipv4map: true}, 72 {snet: "tcp", saddr: "[::]", cnet: "tcp4", caddr: "127.0.0.1", ipv4map: true}, 73 74 {snet: "tcp", saddr: "127.0.0.1", cnet: "tcp", caddr: "127.0.0.1"}, 75 {snet: "tcp", saddr: "[::ffff:127.0.0.1]", cnet: "tcp", caddr: "127.0.0.1"}, 76 {snet: "tcp", saddr: "[::1]", cnet: "tcp", caddr: "[::1]", ipv6: true}, 77 78 {snet: "tcp4", saddr: "", cnet: "tcp4", caddr: "127.0.0.1"}, 79 {snet: "tcp4", saddr: "0.0.0.0", cnet: "tcp4", caddr: "127.0.0.1"}, 80 {snet: "tcp4", saddr: "[::ffff:0.0.0.0]", cnet: "tcp4", caddr: "127.0.0.1"}, 81 82 {snet: "tcp4", saddr: "127.0.0.1", cnet: "tcp4", caddr: "127.0.0.1"}, 83 84 {snet: "tcp6", saddr: "", cnet: "tcp6", caddr: "[::1]", ipv6: true}, 85 {snet: "tcp6", saddr: "[::]", cnet: "tcp6", caddr: "[::1]", ipv6: true}, 86 87 {snet: "tcp6", saddr: "[::1]", cnet: "tcp6", caddr: "[::1]", ipv6: true}, 88 89 {snet: "unix", saddr: testUnixAddr(), cnet: "unix", caddr: testUnixAddr()}, 90 {snet: "unix", saddr: "@gotest2/net", cnet: "unix", caddr: "@gotest2/net.local", linuxOnly: true}, 91 } 92 93 func TestStreamConnServer(t *testing.T) { 94 for _, tt := range streamConnServerTests { 95 if skipServerTest(tt.snet, "unix", tt.saddr, tt.ipv6, tt.ipv4map, tt.linuxOnly) { 96 continue 97 } 98 99 listening := make(chan string) 100 done := make(chan int) 101 switch tt.snet { 102 case "tcp", "tcp4", "tcp6": 103 tt.saddr += ":0" 104 case "unix": 105 os.Remove(tt.saddr) 106 os.Remove(tt.caddr) 107 } 108 109 go runStreamConnServer(t, tt.snet, tt.saddr, listening, done) 110 taddr := <-listening // wait for server to start 111 112 switch tt.cnet { 113 case "tcp", "tcp4", "tcp6": 114 _, port, err := SplitHostPort(taddr) 115 if err != nil { 116 t.Fatalf("SplitHostPort(%q) failed: %v", taddr, err) 117 } 118 taddr = tt.caddr + ":" + port 119 } 120 121 runStreamConnClient(t, tt.cnet, taddr, tt.empty) 122 <-done // make sure server stopped 123 124 switch tt.snet { 125 case "unix": 126 os.Remove(tt.saddr) 127 os.Remove(tt.caddr) 128 } 129 } 130 } 131 132 var seqpacketConnServerTests = []struct { 133 net string 134 saddr string // server address 135 caddr string // client address 136 empty bool // test with empty data 137 linuxOnly bool // test with abstract unix domain socket, a Linux-ism 138 }{ 139 {net: "unixpacket", saddr: testUnixAddr(), caddr: testUnixAddr()}, 140 {net: "unixpacket", saddr: "@gotest4/net", caddr: "@gotest4/net.local", linuxOnly: true}, 141 } 142 143 func TestSeqpacketConnServer(t *testing.T) { 144 switch runtime.GOOS { 145 case "darwin", "nacl", "openbsd", "plan9", "windows": 146 fallthrough 147 case "freebsd": // FreeBSD 8 doesn't support unixpacket 148 t.Skipf("skipping test on %q", runtime.GOOS) 149 } 150 151 for _, tt := range seqpacketConnServerTests { 152 if runtime.GOOS != "linux" && tt.linuxOnly { 153 continue 154 } 155 listening := make(chan string) 156 done := make(chan int) 157 switch tt.net { 158 case "unixpacket": 159 os.Remove(tt.saddr) 160 os.Remove(tt.caddr) 161 } 162 163 go runStreamConnServer(t, tt.net, tt.saddr, listening, done) 164 taddr := <-listening // wait for server to start 165 166 runStreamConnClient(t, tt.net, taddr, tt.empty) 167 <-done // make sure server stopped 168 169 switch tt.net { 170 case "unixpacket": 171 os.Remove(tt.saddr) 172 os.Remove(tt.caddr) 173 } 174 } 175 } 176 177 func runStreamConnServer(t *testing.T, net, laddr string, listening chan<- string, done chan<- int) { 178 defer close(done) 179 l, err := Listen(net, laddr) 180 if err != nil { 181 t.Errorf("Listen(%q, %q) failed: %v", net, laddr, err) 182 listening <- "<nil>" 183 return 184 } 185 defer l.Close() 186 listening <- l.Addr().String() 187 188 echo := func(rw io.ReadWriter, done chan<- int) { 189 buf := make([]byte, 1024) 190 for { 191 n, err := rw.Read(buf[0:]) 192 if err != nil || n == 0 || string(buf[:n]) == "END" { 193 break 194 } 195 rw.Write(buf[0:n]) 196 } 197 close(done) 198 } 199 200 run: 201 for { 202 c, err := l.Accept() 203 if err != nil { 204 t.Logf("Accept failed: %v", err) 205 continue run 206 } 207 echodone := make(chan int) 208 go echo(c, echodone) 209 <-echodone // make sure echo stopped 210 c.Close() 211 break run 212 } 213 } 214 215 func runStreamConnClient(t *testing.T, net, taddr string, isEmpty bool) { 216 c, err := Dial(net, taddr) 217 if err != nil { 218 t.Fatalf("Dial(%q, %q) failed: %v", net, taddr, err) 219 } 220 defer c.Close() 221 c.SetReadDeadline(time.Now().Add(1 * time.Second)) 222 223 var wb []byte 224 if !isEmpty { 225 wb = []byte("StreamConnClient by Dial\n") 226 } 227 if n, err := c.Write(wb); err != nil || n != len(wb) { 228 t.Fatalf("Write failed: %v, %v; want %v, <nil>", n, err, len(wb)) 229 } 230 231 rb := make([]byte, 1024) 232 if n, err := c.Read(rb[0:]); err != nil || n != len(wb) { 233 t.Fatalf("Read failed: %v, %v; want %v, <nil>", n, err, len(wb)) 234 } 235 236 // Send explicit ending for unixpacket. 237 // Older Linux kernels do not stop reads on close. 238 switch net { 239 case "unixpacket": 240 c.Write([]byte("END")) 241 } 242 } 243 244 // Do not test empty datagrams by default. 245 // It causes unexplained timeouts on some systems, 246 // including Snow Leopard. I think that the kernel 247 // doesn't quite expect them. 248 var testDatagram = flag.Bool("datagram", false, "whether to test udp and unixgram") 249 250 var datagramPacketConnServerTests = []struct { 251 snet string // server side 252 saddr string 253 cnet string // client side 254 caddr string 255 ipv6 bool // test with underlying AF_INET6 socket 256 ipv4map bool // test with IPv6 IPv4-mapping functionality 257 dial bool // test with Dial or DialUnix 258 empty bool // test with empty data 259 linuxOnly bool // test with abstract unix domain socket, a Linux-ism 260 }{ 261 {snet: "udp", saddr: "", cnet: "udp", caddr: "127.0.0.1"}, 262 {snet: "udp", saddr: "0.0.0.0", cnet: "udp", caddr: "127.0.0.1"}, 263 {snet: "udp", saddr: "[::ffff:0.0.0.0]", cnet: "udp", caddr: "127.0.0.1"}, 264 {snet: "udp", saddr: "[::]", cnet: "udp", caddr: "[::1]", ipv6: true}, 265 266 {snet: "udp", saddr: "", cnet: "udp", caddr: "[::1]", ipv4map: true}, 267 {snet: "udp", saddr: "0.0.0.0", cnet: "udp", caddr: "[::1]", ipv4map: true}, 268 {snet: "udp", saddr: "[::ffff:0.0.0.0]", cnet: "udp", caddr: "[::1]", ipv4map: true}, 269 {snet: "udp", saddr: "[::]", cnet: "udp", caddr: "127.0.0.1", ipv4map: true}, 270 271 {snet: "udp", saddr: "", cnet: "udp4", caddr: "127.0.0.1"}, 272 {snet: "udp", saddr: "0.0.0.0", cnet: "udp4", caddr: "127.0.0.1"}, 273 {snet: "udp", saddr: "[::ffff:0.0.0.0]", cnet: "udp4", caddr: "127.0.0.1"}, 274 {snet: "udp", saddr: "[::]", cnet: "udp6", caddr: "[::1]", ipv6: true}, 275 276 {snet: "udp", saddr: "", cnet: "udp6", caddr: "[::1]", ipv4map: true}, 277 {snet: "udp", saddr: "0.0.0.0", cnet: "udp6", caddr: "[::1]", ipv4map: true}, 278 {snet: "udp", saddr: "[::ffff:0.0.0.0]", cnet: "udp6", caddr: "[::1]", ipv4map: true}, 279 {snet: "udp", saddr: "[::]", cnet: "udp4", caddr: "127.0.0.1", ipv4map: true}, 280 281 {snet: "udp", saddr: "127.0.0.1", cnet: "udp", caddr: "127.0.0.1"}, 282 {snet: "udp", saddr: "[::ffff:127.0.0.1]", cnet: "udp", caddr: "127.0.0.1"}, 283 {snet: "udp", saddr: "[::1]", cnet: "udp", caddr: "[::1]", ipv6: true}, 284 285 {snet: "udp4", saddr: "", cnet: "udp4", caddr: "127.0.0.1"}, 286 {snet: "udp4", saddr: "0.0.0.0", cnet: "udp4", caddr: "127.0.0.1"}, 287 {snet: "udp4", saddr: "[::ffff:0.0.0.0]", cnet: "udp4", caddr: "127.0.0.1"}, 288 289 {snet: "udp4", saddr: "127.0.0.1", cnet: "udp4", caddr: "127.0.0.1"}, 290 291 {snet: "udp6", saddr: "", cnet: "udp6", caddr: "[::1]", ipv6: true}, 292 {snet: "udp6", saddr: "[::]", cnet: "udp6", caddr: "[::1]", ipv6: true}, 293 294 {snet: "udp6", saddr: "[::1]", cnet: "udp6", caddr: "[::1]", ipv6: true}, 295 296 {snet: "udp", saddr: "127.0.0.1", cnet: "udp", caddr: "127.0.0.1", dial: true}, 297 {snet: "udp", saddr: "127.0.0.1", cnet: "udp", caddr: "127.0.0.1", empty: true}, 298 {snet: "udp", saddr: "127.0.0.1", cnet: "udp", caddr: "127.0.0.1", dial: true, empty: true}, 299 300 {snet: "udp", saddr: "[::1]", cnet: "udp", caddr: "[::1]", ipv6: true, dial: true}, 301 {snet: "udp", saddr: "[::1]", cnet: "udp", caddr: "[::1]", ipv6: true, empty: true}, 302 {snet: "udp", saddr: "[::1]", cnet: "udp", caddr: "[::1]", ipv6: true, dial: true, empty: true}, 303 304 {snet: "unixgram", saddr: testUnixAddr(), cnet: "unixgram", caddr: testUnixAddr()}, 305 {snet: "unixgram", saddr: testUnixAddr(), cnet: "unixgram", caddr: testUnixAddr(), dial: true}, 306 {snet: "unixgram", saddr: testUnixAddr(), cnet: "unixgram", caddr: testUnixAddr(), empty: true}, 307 {snet: "unixgram", saddr: testUnixAddr(), cnet: "unixgram", caddr: testUnixAddr(), dial: true, empty: true}, 308 309 {snet: "unixgram", saddr: "@gotest6/net", cnet: "unixgram", caddr: "@gotest6/net.local", linuxOnly: true}, 310 } 311 312 func TestDatagramPacketConnServer(t *testing.T) { 313 if !*testDatagram { 314 return 315 } 316 317 for _, tt := range datagramPacketConnServerTests { 318 if skipServerTest(tt.snet, "unixgram", tt.saddr, tt.ipv6, tt.ipv4map, tt.linuxOnly) { 319 continue 320 } 321 322 listening := make(chan string) 323 done := make(chan int) 324 switch tt.snet { 325 case "udp", "udp4", "udp6": 326 tt.saddr += ":0" 327 case "unixgram": 328 os.Remove(tt.saddr) 329 os.Remove(tt.caddr) 330 } 331 332 go runDatagramPacketConnServer(t, tt.snet, tt.saddr, listening, done) 333 taddr := <-listening // wait for server to start 334 335 switch tt.cnet { 336 case "udp", "udp4", "udp6": 337 _, port, err := SplitHostPort(taddr) 338 if err != nil { 339 t.Fatalf("SplitHostPort(%q) failed: %v", taddr, err) 340 } 341 taddr = tt.caddr + ":" + port 342 tt.caddr += ":0" 343 } 344 if tt.dial { 345 runDatagramConnClient(t, tt.cnet, tt.caddr, taddr, tt.empty) 346 } else { 347 runDatagramPacketConnClient(t, tt.cnet, tt.caddr, taddr, tt.empty) 348 } 349 <-done // tell server to stop 350 <-done // make sure server stopped 351 352 switch tt.snet { 353 case "unixgram": 354 os.Remove(tt.saddr) 355 os.Remove(tt.caddr) 356 } 357 } 358 } 359 360 func runDatagramPacketConnServer(t *testing.T, net, laddr string, listening chan<- string, done chan<- int) { 361 c, err := ListenPacket(net, laddr) 362 if err != nil { 363 t.Errorf("ListenPacket(%q, %q) failed: %v", net, laddr, err) 364 listening <- "<nil>" 365 done <- 1 366 return 367 } 368 defer c.Close() 369 listening <- c.LocalAddr().String() 370 371 buf := make([]byte, 1024) 372 run: 373 for { 374 c.SetReadDeadline(time.Now().Add(10 * time.Millisecond)) 375 n, ra, err := c.ReadFrom(buf[0:]) 376 if nerr, ok := err.(Error); ok && nerr.Timeout() { 377 select { 378 case done <- 1: 379 break run 380 default: 381 continue run 382 } 383 } 384 if err != nil { 385 break run 386 } 387 if _, err = c.WriteTo(buf[0:n], ra); err != nil { 388 t.Errorf("WriteTo(%v) failed: %v", ra, err) 389 break run 390 } 391 } 392 done <- 1 393 } 394 395 func runDatagramConnClient(t *testing.T, net, laddr, taddr string, isEmpty bool) { 396 var c Conn 397 var err error 398 switch net { 399 case "udp", "udp4", "udp6": 400 c, err = Dial(net, taddr) 401 if err != nil { 402 t.Fatalf("Dial(%q, %q) failed: %v", net, taddr, err) 403 } 404 case "unixgram": 405 c, err = DialUnix(net, &UnixAddr{Name: laddr, Net: net}, &UnixAddr{Name: taddr, Net: net}) 406 if err != nil { 407 t.Fatalf("DialUnix(%q, {%q, %q}) failed: %v", net, laddr, taddr, err) 408 } 409 } 410 defer c.Close() 411 c.SetReadDeadline(time.Now().Add(1 * time.Second)) 412 413 var wb []byte 414 if !isEmpty { 415 wb = []byte("DatagramConnClient by Dial\n") 416 } 417 if n, err := c.Write(wb[0:]); err != nil || n != len(wb) { 418 t.Fatalf("Write failed: %v, %v; want %v, <nil>", n, err, len(wb)) 419 } 420 421 rb := make([]byte, 1024) 422 if n, err := c.Read(rb[0:]); err != nil || n != len(wb) { 423 t.Fatalf("Read failed: %v, %v; want %v, <nil>", n, err, len(wb)) 424 } 425 } 426 427 func runDatagramPacketConnClient(t *testing.T, net, laddr, taddr string, isEmpty bool) { 428 var ra Addr 429 var err error 430 switch net { 431 case "udp", "udp4", "udp6": 432 ra, err = ResolveUDPAddr(net, taddr) 433 if err != nil { 434 t.Fatalf("ResolveUDPAddr(%q, %q) failed: %v", net, taddr, err) 435 } 436 case "unixgram": 437 ra, err = ResolveUnixAddr(net, taddr) 438 if err != nil { 439 t.Fatalf("ResolveUxixAddr(%q, %q) failed: %v", net, taddr, err) 440 } 441 } 442 c, err := ListenPacket(net, laddr) 443 if err != nil { 444 t.Fatalf("ListenPacket(%q, %q) faild: %v", net, laddr, err) 445 } 446 defer c.Close() 447 c.SetReadDeadline(time.Now().Add(1 * time.Second)) 448 449 var wb []byte 450 if !isEmpty { 451 wb = []byte("DatagramPacketConnClient by ListenPacket\n") 452 } 453 if n, err := c.WriteTo(wb[0:], ra); err != nil || n != len(wb) { 454 t.Fatalf("WriteTo(%v) failed: %v, %v; want %v, <nil>", ra, n, err, len(wb)) 455 } 456 457 rb := make([]byte, 1024) 458 if n, _, err := c.ReadFrom(rb[0:]); err != nil || n != len(wb) { 459 t.Fatalf("ReadFrom failed: %v, %v; want %v, <nil>", n, err, len(wb)) 460 } 461 }