github.com/spotify/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/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 "strconv" 13 "testing" 14 "time" 15 ) 16 17 func skipServerTest(net, unixsotype, addr string, ipv6, ipv4map, linuxonly bool) bool { 18 switch runtime.GOOS { 19 case "linux": 20 case "plan9", "windows": 21 // "unix" sockets are not supported on Windows and Plan 9. 22 if net == unixsotype { 23 return true 24 } 25 default: 26 if net == unixsotype && linuxonly { 27 return true 28 } 29 } 30 switch addr { 31 case "", "0.0.0.0", "[::ffff:0.0.0.0]", "[::]": 32 if testing.Short() || !*testExternal { 33 return true 34 } 35 } 36 if ipv6 && !supportsIPv6 { 37 return true 38 } 39 if ipv4map && !supportsIPv4map { 40 return true 41 } 42 return false 43 } 44 45 func tempfile(filename string) string { 46 // use /tmp in case it is prohibited to create 47 // UNIX sockets in TMPDIR 48 return "/tmp/" + filename + "." + strconv.Itoa(os.Getpid()) 49 } 50 51 var streamConnServerTests = []struct { 52 snet string // server side 53 saddr string 54 cnet string // client side 55 caddr string 56 ipv6 bool // test with underlying AF_INET6 socket 57 ipv4map bool // test with IPv6 IPv4-mapping functionality 58 empty bool // test with empty data 59 linux bool // test with abstract unix domain socket, a Linux-ism 60 }{ 61 {snet: "tcp", saddr: "", cnet: "tcp", caddr: "127.0.0.1"}, 62 {snet: "tcp", saddr: "0.0.0.0", cnet: "tcp", caddr: "127.0.0.1"}, 63 {snet: "tcp", saddr: "[::ffff:0.0.0.0]", cnet: "tcp", caddr: "127.0.0.1"}, 64 {snet: "tcp", saddr: "[::]", cnet: "tcp", caddr: "[::1]", ipv6: true}, 65 66 {snet: "tcp", saddr: "", cnet: "tcp", caddr: "[::1]", ipv4map: true}, 67 {snet: "tcp", saddr: "0.0.0.0", cnet: "tcp", caddr: "[::1]", ipv4map: true}, 68 {snet: "tcp", saddr: "[::ffff:0.0.0.0]", cnet: "tcp", caddr: "[::1]", ipv4map: true}, 69 {snet: "tcp", saddr: "[::]", cnet: "tcp", caddr: "127.0.0.1", ipv4map: true}, 70 71 {snet: "tcp", saddr: "", cnet: "tcp4", caddr: "127.0.0.1"}, 72 {snet: "tcp", saddr: "0.0.0.0", cnet: "tcp4", caddr: "127.0.0.1"}, 73 {snet: "tcp", saddr: "[::ffff:0.0.0.0]", cnet: "tcp4", caddr: "127.0.0.1"}, 74 {snet: "tcp", saddr: "[::]", cnet: "tcp6", caddr: "[::1]", ipv6: true}, 75 76 {snet: "tcp", saddr: "", cnet: "tcp6", caddr: "[::1]", ipv4map: true}, 77 {snet: "tcp", saddr: "0.0.0.0", cnet: "tcp6", caddr: "[::1]", ipv4map: true}, 78 {snet: "tcp", saddr: "[::ffff:0.0.0.0]", cnet: "tcp6", caddr: "[::1]", ipv4map: true}, 79 {snet: "tcp", saddr: "[::]", cnet: "tcp4", caddr: "127.0.0.1", ipv4map: true}, 80 81 {snet: "tcp", saddr: "127.0.0.1", cnet: "tcp", caddr: "127.0.0.1"}, 82 {snet: "tcp", saddr: "[::ffff:127.0.0.1]", cnet: "tcp", caddr: "127.0.0.1"}, 83 {snet: "tcp", saddr: "[::1]", cnet: "tcp", caddr: "[::1]", ipv6: true}, 84 85 {snet: "tcp4", saddr: "", cnet: "tcp4", caddr: "127.0.0.1"}, 86 {snet: "tcp4", saddr: "0.0.0.0", cnet: "tcp4", caddr: "127.0.0.1"}, 87 {snet: "tcp4", saddr: "[::ffff:0.0.0.0]", cnet: "tcp4", caddr: "127.0.0.1"}, 88 89 {snet: "tcp4", saddr: "127.0.0.1", cnet: "tcp4", caddr: "127.0.0.1"}, 90 91 {snet: "tcp6", saddr: "", cnet: "tcp6", caddr: "[::1]", ipv6: true}, 92 {snet: "tcp6", saddr: "[::]", cnet: "tcp6", caddr: "[::1]", ipv6: true}, 93 94 {snet: "tcp6", saddr: "[::1]", cnet: "tcp6", caddr: "[::1]", ipv6: true}, 95 96 {snet: "unix", saddr: tempfile("gotest1.net"), cnet: "unix", caddr: tempfile("gotest1.net.local")}, 97 {snet: "unix", saddr: "@gotest2/net", cnet: "unix", caddr: "@gotest2/net.local", linux: true}, 98 } 99 100 func TestStreamConnServer(t *testing.T) { 101 for _, tt := range streamConnServerTests { 102 if skipServerTest(tt.snet, "unix", tt.saddr, tt.ipv6, tt.ipv4map, tt.linux) { 103 continue 104 } 105 106 listening := make(chan string) 107 done := make(chan int) 108 switch tt.snet { 109 case "tcp", "tcp4", "tcp6": 110 tt.saddr += ":0" 111 case "unix": 112 os.Remove(tt.saddr) 113 os.Remove(tt.caddr) 114 } 115 116 go runStreamConnServer(t, tt.snet, tt.saddr, listening, done) 117 taddr := <-listening // wait for server to start 118 119 switch tt.cnet { 120 case "tcp", "tcp4", "tcp6": 121 _, port, err := SplitHostPort(taddr) 122 if err != nil { 123 t.Fatalf("SplitHostPort(%q) failed: %v", taddr, err) 124 } 125 taddr = tt.caddr + ":" + port 126 } 127 128 runStreamConnClient(t, tt.cnet, taddr, tt.empty) 129 <-done // make sure server stopped 130 131 switch tt.snet { 132 case "unix": 133 os.Remove(tt.saddr) 134 os.Remove(tt.caddr) 135 } 136 } 137 } 138 139 var seqpacketConnServerTests = []struct { 140 net string 141 saddr string // server address 142 caddr string // client address 143 empty bool // test with empty data 144 }{ 145 {net: "unixpacket", saddr: tempfile("/gotest3.net"), caddr: tempfile("gotest3.net.local")}, 146 {net: "unixpacket", saddr: "@gotest4/net", caddr: "@gotest4/net.local"}, 147 } 148 149 func TestSeqpacketConnServer(t *testing.T) { 150 if runtime.GOOS != "linux" { 151 t.Skipf("skipping test on %q", runtime.GOOS) 152 } 153 154 for _, tt := range seqpacketConnServerTests { 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 linux 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: tempfile("gotest5.net"), cnet: "unixgram", caddr: tempfile("gotest5.net.local")}, 305 {snet: "unixgram", saddr: tempfile("gotest5.net"), cnet: "unixgram", caddr: tempfile("gotest5.net.local"), dial: true}, 306 {snet: "unixgram", saddr: tempfile("gotest5.net"), cnet: "unixgram", caddr: tempfile("gotest5.net.local"), empty: true}, 307 {snet: "unixgram", saddr: tempfile("gotest5.net"), cnet: "unixgram", caddr: tempfile("gotest5.net.local"), dial: true, empty: true}, 308 309 {snet: "unixgram", saddr: "@gotest6/net", cnet: "unixgram", caddr: "@gotest6/net.local", linux: 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.linux) { 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 }