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