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 5package net 6 7import ( 8 "fmt" 9 "os" 10 "testing" 11) 12 13var tcpServerTests = []struct { 14 snet, saddr string // server endpoint 15 tnet, taddr string // target endpoint for client 16}{ 17 {snet: "tcp", saddr: ":0", tnet: "tcp", taddr: "127.0.0.1"}, 18 {snet: "tcp", saddr: "0.0.0.0:0", tnet: "tcp", taddr: "127.0.0.1"}, 19 {snet: "tcp", saddr: "[::ffff:0.0.0.0]:0", tnet: "tcp", taddr: "127.0.0.1"}, 20 {snet: "tcp", saddr: "[::]:0", tnet: "tcp", taddr: "::1"}, 21 22 {snet: "tcp", saddr: ":0", tnet: "tcp", taddr: "::1"}, 23 {snet: "tcp", saddr: "0.0.0.0:0", tnet: "tcp", taddr: "::1"}, 24 {snet: "tcp", saddr: "[::ffff:0.0.0.0]:0", tnet: "tcp", taddr: "::1"}, 25 {snet: "tcp", saddr: "[::]:0", tnet: "tcp", taddr: "127.0.0.1"}, 26 27 {snet: "tcp", saddr: ":0", tnet: "tcp4", taddr: "127.0.0.1"}, 28 {snet: "tcp", saddr: "0.0.0.0:0", tnet: "tcp4", taddr: "127.0.0.1"}, 29 {snet: "tcp", saddr: "[::ffff:0.0.0.0]:0", tnet: "tcp4", taddr: "127.0.0.1"}, 30 {snet: "tcp", saddr: "[::]:0", tnet: "tcp6", taddr: "::1"}, 31 32 {snet: "tcp", saddr: ":0", tnet: "tcp6", taddr: "::1"}, 33 {snet: "tcp", saddr: "0.0.0.0:0", tnet: "tcp6", taddr: "::1"}, 34 {snet: "tcp", saddr: "[::ffff:0.0.0.0]:0", tnet: "tcp6", taddr: "::1"}, 35 {snet: "tcp", saddr: "[::]:0", tnet: "tcp4", taddr: "127.0.0.1"}, 36 37 {snet: "tcp", saddr: "127.0.0.1:0", tnet: "tcp", taddr: "127.0.0.1"}, 38 {snet: "tcp", saddr: "[::ffff:127.0.0.1]:0", tnet: "tcp", taddr: "127.0.0.1"}, 39 {snet: "tcp", saddr: "[::1]:0", tnet: "tcp", taddr: "::1"}, 40 41 {snet: "tcp4", saddr: ":0", tnet: "tcp4", taddr: "127.0.0.1"}, 42 {snet: "tcp4", saddr: "0.0.0.0:0", tnet: "tcp4", taddr: "127.0.0.1"}, 43 {snet: "tcp4", saddr: "[::ffff:0.0.0.0]:0", tnet: "tcp4", taddr: "127.0.0.1"}, 44 45 {snet: "tcp4", saddr: "127.0.0.1:0", tnet: "tcp4", taddr: "127.0.0.1"}, 46 47 {snet: "tcp6", saddr: ":0", tnet: "tcp6", taddr: "::1"}, 48 {snet: "tcp6", saddr: "[::]:0", tnet: "tcp6", taddr: "::1"}, 49 50 {snet: "tcp6", saddr: "[::1]:0", tnet: "tcp6", taddr: "::1"}, 51} 52 53// TestTCPServer tests concurrent accept-read-write servers. 54func TestTCPServer(t *testing.T) { 55 const N = 3 56 57 for i, tt := range tcpServerTests { 58 t.Run(tt.snet+" "+tt.saddr+"<-"+tt.taddr, func(t *testing.T) { 59 if !testableListenArgs(tt.snet, tt.saddr, tt.taddr) { 60 t.Skip("not testable") 61 } 62 63 ln, err := Listen(tt.snet, tt.saddr) 64 if err != nil { 65 if perr := parseDialError(err); perr != nil { 66 t.Error(perr) 67 } 68 t.Fatal(err) 69 } 70 71 var lss []*localServer 72 var tpchs []chan error 73 defer func() { 74 for _, ls := range lss { 75 ls.teardown() 76 } 77 }() 78 for i := 0; i < N; i++ { 79 ls := (&streamListener{Listener: ln}).newLocalServer() 80 lss = append(lss, ls) 81 tpchs = append(tpchs, make(chan error, 1)) 82 } 83 for i := 0; i < N; i++ { 84 ch := tpchs[i] 85 handler := func(ls *localServer, ln Listener) { ls.transponder(ln, ch) } 86 if err := lss[i].buildup(handler); err != nil { 87 t.Fatal(err) 88 } 89 } 90 91 var trchs []chan error 92 for i := 0; i < N; i++ { 93 _, port, err := SplitHostPort(lss[i].Listener.Addr().String()) 94 if err != nil { 95 t.Fatal(err) 96 } 97 d := Dialer{Timeout: someTimeout} 98 c, err := d.Dial(tt.tnet, JoinHostPort(tt.taddr, port)) 99 if err != nil { 100 if perr := parseDialError(err); perr != nil { 101 t.Error(perr) 102 } 103 t.Fatal(err) 104 } 105 defer c.Close() 106 trchs = append(trchs, make(chan error, 1)) 107 go transceiver(c, []byte("TCP SERVER TEST"), trchs[i]) 108 } 109 110 for _, ch := range trchs { 111 for err := range ch { 112 t.Errorf("#%d: %v", i, err) 113 } 114 } 115 for _, ch := range tpchs { 116 for err := range ch { 117 t.Errorf("#%d: %v", i, err) 118 } 119 } 120 }) 121 } 122} 123 124// TestUnixAndUnixpacketServer tests concurrent accept-read-write 125// servers 126func TestUnixAndUnixpacketServer(t *testing.T) { 127 var unixAndUnixpacketServerTests = []struct { 128 network, address string 129 }{ 130 {"unix", testUnixAddr(t)}, 131 {"unix", "@nettest/go/unix"}, 132 133 {"unixpacket", testUnixAddr(t)}, 134 {"unixpacket", "@nettest/go/unixpacket"}, 135 } 136 137 const N = 3 138 139 for i, tt := range unixAndUnixpacketServerTests { 140 if !testableListenArgs(tt.network, tt.address, "") { 141 t.Logf("skipping %s test", tt.network+" "+tt.address) 142 continue 143 } 144 145 ln, err := Listen(tt.network, tt.address) 146 if err != nil { 147 if perr := parseDialError(err); perr != nil { 148 t.Error(perr) 149 } 150 t.Fatal(err) 151 } 152 153 var lss []*localServer 154 var tpchs []chan error 155 defer func() { 156 for _, ls := range lss { 157 ls.teardown() 158 } 159 }() 160 for i := 0; i < N; i++ { 161 ls := (&streamListener{Listener: ln}).newLocalServer() 162 lss = append(lss, ls) 163 tpchs = append(tpchs, make(chan error, 1)) 164 } 165 for i := 0; i < N; i++ { 166 ch := tpchs[i] 167 handler := func(ls *localServer, ln Listener) { ls.transponder(ln, ch) } 168 if err := lss[i].buildup(handler); err != nil { 169 t.Fatal(err) 170 } 171 } 172 173 var trchs []chan error 174 for i := 0; i < N; i++ { 175 d := Dialer{Timeout: someTimeout} 176 c, err := d.Dial(lss[i].Listener.Addr().Network(), lss[i].Listener.Addr().String()) 177 if err != nil { 178 if perr := parseDialError(err); perr != nil { 179 t.Error(perr) 180 } 181 t.Fatal(err) 182 } 183 184 if addr := c.LocalAddr(); addr != nil { 185 t.Logf("connected %s->%s", addr, lss[i].Listener.Addr()) 186 } 187 188 defer c.Close() 189 trchs = append(trchs, make(chan error, 1)) 190 go transceiver(c, []byte("UNIX AND UNIXPACKET SERVER TEST"), trchs[i]) 191 } 192 193 for _, ch := range trchs { 194 for err := range ch { 195 t.Errorf("#%d: %v", i, err) 196 } 197 } 198 for _, ch := range tpchs { 199 for err := range ch { 200 t.Errorf("#%d: %v", i, err) 201 } 202 } 203 } 204} 205 206var udpServerTests = []struct { 207 snet, saddr string // server endpoint 208 tnet, taddr string // target endpoint for client 209 dial bool // test with Dial 210}{ 211 {snet: "udp", saddr: ":0", tnet: "udp", taddr: "127.0.0.1"}, 212 {snet: "udp", saddr: "0.0.0.0:0", tnet: "udp", taddr: "127.0.0.1"}, 213 {snet: "udp", saddr: "[::ffff:0.0.0.0]:0", tnet: "udp", taddr: "127.0.0.1"}, 214 {snet: "udp", saddr: "[::]:0", tnet: "udp", taddr: "::1"}, 215 216 {snet: "udp", saddr: ":0", tnet: "udp", taddr: "::1"}, 217 {snet: "udp", saddr: "0.0.0.0:0", tnet: "udp", taddr: "::1"}, 218 {snet: "udp", saddr: "[::ffff:0.0.0.0]:0", tnet: "udp", taddr: "::1"}, 219 {snet: "udp", saddr: "[::]:0", tnet: "udp", taddr: "127.0.0.1"}, 220 221 {snet: "udp", saddr: ":0", tnet: "udp4", taddr: "127.0.0.1"}, 222 {snet: "udp", saddr: "0.0.0.0:0", tnet: "udp4", taddr: "127.0.0.1"}, 223 {snet: "udp", saddr: "[::ffff:0.0.0.0]:0", tnet: "udp4", taddr: "127.0.0.1"}, 224 {snet: "udp", saddr: "[::]:0", tnet: "udp6", taddr: "::1"}, 225 226 {snet: "udp", saddr: ":0", tnet: "udp6", taddr: "::1"}, 227 {snet: "udp", saddr: "0.0.0.0:0", tnet: "udp6", taddr: "::1"}, 228 {snet: "udp", saddr: "[::ffff:0.0.0.0]:0", tnet: "udp6", taddr: "::1"}, 229 {snet: "udp", saddr: "[::]:0", tnet: "udp4", taddr: "127.0.0.1"}, 230 231 {snet: "udp", saddr: "127.0.0.1:0", tnet: "udp", taddr: "127.0.0.1"}, 232 {snet: "udp", saddr: "[::ffff:127.0.0.1]:0", tnet: "udp", taddr: "127.0.0.1"}, 233 {snet: "udp", saddr: "[::1]:0", tnet: "udp", taddr: "::1"}, 234 235 {snet: "udp4", saddr: ":0", tnet: "udp4", taddr: "127.0.0.1"}, 236 {snet: "udp4", saddr: "0.0.0.0:0", tnet: "udp4", taddr: "127.0.0.1"}, 237 {snet: "udp4", saddr: "[::ffff:0.0.0.0]:0", tnet: "udp4", taddr: "127.0.0.1"}, 238 239 {snet: "udp4", saddr: "127.0.0.1:0", tnet: "udp4", taddr: "127.0.0.1"}, 240 241 {snet: "udp6", saddr: ":0", tnet: "udp6", taddr: "::1"}, 242 {snet: "udp6", saddr: "[::]:0", tnet: "udp6", taddr: "::1"}, 243 244 {snet: "udp6", saddr: "[::1]:0", tnet: "udp6", taddr: "::1"}, 245 246 {snet: "udp", saddr: "127.0.0.1:0", tnet: "udp", taddr: "127.0.0.1", dial: true}, 247 248 {snet: "udp", saddr: "[::1]:0", tnet: "udp", taddr: "::1", dial: true}, 249} 250 251func TestUDPServer(t *testing.T) { 252 for i, tt := range udpServerTests { 253 i, tt := i, tt 254 t.Run(fmt.Sprint(i), func(t *testing.T) { 255 if !testableListenArgs(tt.snet, tt.saddr, tt.taddr) { 256 t.Skipf("skipping %s %s<-%s test", tt.snet, tt.saddr, tt.taddr) 257 } 258 t.Logf("%s %s<-%s", tt.snet, tt.saddr, tt.taddr) 259 260 c1, err := ListenPacket(tt.snet, tt.saddr) 261 if err != nil { 262 if perr := parseDialError(err); perr != nil { 263 t.Error(perr) 264 } 265 t.Fatal(err) 266 } 267 268 ls := (&packetListener{PacketConn: c1}).newLocalServer() 269 defer ls.teardown() 270 tpch := make(chan error, 1) 271 handler := func(ls *localPacketServer, c PacketConn) { packetTransponder(c, tpch) } 272 if err := ls.buildup(handler); err != nil { 273 t.Fatal(err) 274 } 275 276 trch := make(chan error, 1) 277 _, port, err := SplitHostPort(ls.PacketConn.LocalAddr().String()) 278 if err != nil { 279 t.Fatal(err) 280 } 281 if tt.dial { 282 d := Dialer{Timeout: someTimeout} 283 c2, err := d.Dial(tt.tnet, JoinHostPort(tt.taddr, port)) 284 if err != nil { 285 if perr := parseDialError(err); perr != nil { 286 t.Error(perr) 287 } 288 t.Fatal(err) 289 } 290 defer c2.Close() 291 go transceiver(c2, []byte("UDP SERVER TEST"), trch) 292 } else { 293 c2, err := ListenPacket(tt.tnet, JoinHostPort(tt.taddr, "0")) 294 if err != nil { 295 if perr := parseDialError(err); perr != nil { 296 t.Error(perr) 297 } 298 t.Fatal(err) 299 } 300 defer c2.Close() 301 dst, err := ResolveUDPAddr(tt.tnet, JoinHostPort(tt.taddr, port)) 302 if err != nil { 303 t.Fatal(err) 304 } 305 go packetTransceiver(c2, []byte("UDP SERVER TEST"), dst, trch) 306 } 307 308 for trch != nil || tpch != nil { 309 select { 310 case err, ok := <-trch: 311 if !ok { 312 trch = nil 313 } 314 if err != nil { 315 t.Errorf("client: %v", err) 316 } 317 case err, ok := <-tpch: 318 if !ok { 319 tpch = nil 320 } 321 if err != nil { 322 t.Errorf("server: %v", err) 323 } 324 } 325 } 326 }) 327 } 328} 329 330func TestUnixgramServer(t *testing.T) { 331 var unixgramServerTests = []struct { 332 saddr string // server endpoint 333 caddr string // client endpoint 334 dial bool // test with Dial 335 }{ 336 {saddr: testUnixAddr(t), caddr: testUnixAddr(t)}, 337 {saddr: testUnixAddr(t), caddr: testUnixAddr(t), dial: true}, 338 339 {saddr: "@nettest/go/unixgram/server", caddr: "@nettest/go/unixgram/client"}, 340 } 341 342 for i, tt := range unixgramServerTests { 343 i, tt := i, tt 344 t.Run(fmt.Sprint(i), func(t *testing.T) { 345 if !testableListenArgs("unixgram", tt.saddr, "") { 346 t.Skipf("skipping unixgram %s<-%s test", tt.saddr, tt.caddr) 347 } 348 t.Logf("unixgram %s<-%s", tt.saddr, tt.caddr) 349 350 c1, err := ListenPacket("unixgram", tt.saddr) 351 if err != nil { 352 if perr := parseDialError(err); perr != nil { 353 t.Error(perr) 354 } 355 t.Fatal(err) 356 } 357 358 ls := (&packetListener{PacketConn: c1}).newLocalServer() 359 defer ls.teardown() 360 tpch := make(chan error, 1) 361 handler := func(ls *localPacketServer, c PacketConn) { packetTransponder(c, tpch) } 362 if err := ls.buildup(handler); err != nil { 363 t.Fatal(err) 364 } 365 366 trch := make(chan error, 1) 367 if tt.dial { 368 d := Dialer{Timeout: someTimeout, LocalAddr: &UnixAddr{Net: "unixgram", Name: tt.caddr}} 369 c2, err := d.Dial("unixgram", ls.PacketConn.LocalAddr().String()) 370 if err != nil { 371 if perr := parseDialError(err); perr != nil { 372 t.Error(perr) 373 } 374 t.Fatal(err) 375 } 376 defer os.Remove(c2.LocalAddr().String()) 377 defer c2.Close() 378 go transceiver(c2, []byte(c2.LocalAddr().String()), trch) 379 } else { 380 c2, err := ListenPacket("unixgram", tt.caddr) 381 if err != nil { 382 if perr := parseDialError(err); perr != nil { 383 t.Error(perr) 384 } 385 t.Fatal(err) 386 } 387 defer os.Remove(c2.LocalAddr().String()) 388 defer c2.Close() 389 go packetTransceiver(c2, []byte("UNIXGRAM SERVER TEST"), ls.PacketConn.LocalAddr(), trch) 390 } 391 392 for trch != nil || tpch != nil { 393 select { 394 case err, ok := <-trch: 395 if !ok { 396 trch = nil 397 } 398 if err != nil { 399 t.Errorf("client: %v", err) 400 } 401 case err, ok := <-tpch: 402 if !ok { 403 tpch = nil 404 } 405 if err != nil { 406 t.Errorf("server: %v", err) 407 } 408 } 409 } 410 }) 411 } 412} 413