Home | History | Annotate | Download | only in net
      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 	"os"
      9 	"testing"
     10 )
     11 
     12 var tcpServerTests = []struct {
     13 	snet, saddr string // server endpoint
     14 	tnet, taddr string // target endpoint for client
     15 }{
     16 	{snet: "tcp", saddr: ":0", tnet: "tcp", taddr: "127.0.0.1"},
     17 	{snet: "tcp", saddr: "0.0.0.0:0", tnet: "tcp", taddr: "127.0.0.1"},
     18 	{snet: "tcp", saddr: "[::ffff:0.0.0.0]:0", tnet: "tcp", taddr: "127.0.0.1"},
     19 	{snet: "tcp", saddr: "[::]:0", tnet: "tcp", taddr: "::1"},
     20 
     21 	{snet: "tcp", saddr: ":0", tnet: "tcp", taddr: "::1"},
     22 	{snet: "tcp", saddr: "0.0.0.0:0", tnet: "tcp", taddr: "::1"},
     23 	{snet: "tcp", saddr: "[::ffff:0.0.0.0]:0", tnet: "tcp", taddr: "::1"},
     24 	{snet: "tcp", saddr: "[::]:0", tnet: "tcp", taddr: "127.0.0.1"},
     25 
     26 	{snet: "tcp", saddr: ":0", tnet: "tcp4", taddr: "127.0.0.1"},
     27 	{snet: "tcp", saddr: "0.0.0.0:0", tnet: "tcp4", taddr: "127.0.0.1"},
     28 	{snet: "tcp", saddr: "[::ffff:0.0.0.0]:0", tnet: "tcp4", taddr: "127.0.0.1"},
     29 	{snet: "tcp", saddr: "[::]:0", tnet: "tcp6", taddr: "::1"},
     30 
     31 	{snet: "tcp", saddr: ":0", tnet: "tcp6", taddr: "::1"},
     32 	{snet: "tcp", saddr: "0.0.0.0:0", tnet: "tcp6", taddr: "::1"},
     33 	{snet: "tcp", saddr: "[::ffff:0.0.0.0]:0", tnet: "tcp6", taddr: "::1"},
     34 	{snet: "tcp", saddr: "[::]:0", tnet: "tcp4", taddr: "127.0.0.1"},
     35 
     36 	{snet: "tcp", saddr: "127.0.0.1:0", tnet: "tcp", taddr: "127.0.0.1"},
     37 	{snet: "tcp", saddr: "[::ffff:127.0.0.1]:0", tnet: "tcp", taddr: "127.0.0.1"},
     38 	{snet: "tcp", saddr: "[::1]:0", tnet: "tcp", taddr: "::1"},
     39 
     40 	{snet: "tcp4", saddr: ":0", tnet: "tcp4", taddr: "127.0.0.1"},
     41 	{snet: "tcp4", saddr: "0.0.0.0:0", tnet: "tcp4", taddr: "127.0.0.1"},
     42 	{snet: "tcp4", saddr: "[::ffff:0.0.0.0]:0", tnet: "tcp4", taddr: "127.0.0.1"},
     43 
     44 	{snet: "tcp4", saddr: "127.0.0.1:0", tnet: "tcp4", taddr: "127.0.0.1"},
     45 
     46 	{snet: "tcp6", saddr: ":0", tnet: "tcp6", taddr: "::1"},
     47 	{snet: "tcp6", saddr: "[::]:0", tnet: "tcp6", taddr: "::1"},
     48 
     49 	{snet: "tcp6", saddr: "[::1]:0", tnet: "tcp6", taddr: "::1"},
     50 }
     51 
     52 // TestTCPServer tests concurrent accept-read-write servers.
     53 func TestTCPServer(t *testing.T) {
     54 	const N = 3
     55 
     56 	for i, tt := range tcpServerTests {
     57 		if !testableListenArgs(tt.snet, tt.saddr, tt.taddr) {
     58 			t.Logf("skipping %s test", tt.snet+" "+tt.saddr+"<-"+tt.taddr)
     59 			continue
     60 		}
     61 
     62 		ln, err := Listen(tt.snet, tt.saddr)
     63 		if err != nil {
     64 			if perr := parseDialError(err); perr != nil {
     65 				t.Error(perr)
     66 			}
     67 			t.Fatal(err)
     68 		}
     69 
     70 		var lss []*localServer
     71 		var tpchs []chan error
     72 		defer func() {
     73 			for _, ls := range lss {
     74 				ls.teardown()
     75 			}
     76 		}()
     77 		for i := 0; i < N; i++ {
     78 			ls, err := (&streamListener{Listener: ln}).newLocalServer()
     79 			if err != nil {
     80 				t.Fatal(err)
     81 			}
     82 			lss = append(lss, ls)
     83 			tpchs = append(tpchs, make(chan error, 1))
     84 		}
     85 		for i := 0; i < N; i++ {
     86 			ch := tpchs[i]
     87 			handler := func(ls *localServer, ln Listener) { transponder(ln, ch) }
     88 			if err := lss[i].buildup(handler); err != nil {
     89 				t.Fatal(err)
     90 			}
     91 		}
     92 
     93 		var trchs []chan error
     94 		for i := 0; i < N; i++ {
     95 			_, port, err := SplitHostPort(lss[i].Listener.Addr().String())
     96 			if err != nil {
     97 				t.Fatal(err)
     98 			}
     99 			d := Dialer{Timeout: someTimeout}
    100 			c, err := d.Dial(tt.tnet, JoinHostPort(tt.taddr, port))
    101 			if err != nil {
    102 				if perr := parseDialError(err); perr != nil {
    103 					t.Error(perr)
    104 				}
    105 				t.Fatal(err)
    106 			}
    107 			defer c.Close()
    108 			trchs = append(trchs, make(chan error, 1))
    109 			go transceiver(c, []byte("TCP SERVER TEST"), trchs[i])
    110 		}
    111 
    112 		for _, ch := range trchs {
    113 			for err := range ch {
    114 				t.Errorf("#%d: %v", i, err)
    115 			}
    116 		}
    117 		for _, ch := range tpchs {
    118 			for err := range ch {
    119 				t.Errorf("#%d: %v", i, err)
    120 			}
    121 		}
    122 	}
    123 }
    124 
    125 var unixAndUnixpacketServerTests = []struct {
    126 	network, address string
    127 }{
    128 	{"unix", testUnixAddr()},
    129 	{"unix", "@nettest/go/unix"},
    130 
    131 	{"unixpacket", testUnixAddr()},
    132 	{"unixpacket", "@nettest/go/unixpacket"},
    133 }
    134 
    135 // TestUnixAndUnixpacketServer tests concurrent accept-read-write
    136 // servers
    137 func TestUnixAndUnixpacketServer(t *testing.T) {
    138 	const N = 3
    139 
    140 	for i, tt := range unixAndUnixpacketServerTests {
    141 		if !testableListenArgs(tt.network, tt.address, "") {
    142 			t.Logf("skipping %s test", tt.network+" "+tt.address)
    143 			continue
    144 		}
    145 
    146 		ln, err := Listen(tt.network, tt.address)
    147 		if err != nil {
    148 			if perr := parseDialError(err); perr != nil {
    149 				t.Error(perr)
    150 			}
    151 			t.Fatal(err)
    152 		}
    153 
    154 		var lss []*localServer
    155 		var tpchs []chan error
    156 		defer func() {
    157 			for _, ls := range lss {
    158 				ls.teardown()
    159 			}
    160 		}()
    161 		for i := 0; i < N; i++ {
    162 			ls, err := (&streamListener{Listener: ln}).newLocalServer()
    163 			if err != nil {
    164 				t.Fatal(err)
    165 			}
    166 			lss = append(lss, ls)
    167 			tpchs = append(tpchs, make(chan error, 1))
    168 		}
    169 		for i := 0; i < N; i++ {
    170 			ch := tpchs[i]
    171 			handler := func(ls *localServer, ln Listener) { transponder(ln, ch) }
    172 			if err := lss[i].buildup(handler); err != nil {
    173 				t.Fatal(err)
    174 			}
    175 		}
    176 
    177 		var trchs []chan error
    178 		for i := 0; i < N; i++ {
    179 			d := Dialer{Timeout: someTimeout}
    180 			c, err := d.Dial(lss[i].Listener.Addr().Network(), lss[i].Listener.Addr().String())
    181 			if err != nil {
    182 				if perr := parseDialError(err); perr != nil {
    183 					t.Error(perr)
    184 				}
    185 				t.Fatal(err)
    186 			}
    187 			defer os.Remove(c.LocalAddr().String())
    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 
    206 var 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 
    251 func TestUDPServer(t *testing.T) {
    252 	for i, tt := range udpServerTests {
    253 		if !testableListenArgs(tt.snet, tt.saddr, tt.taddr) {
    254 			t.Logf("skipping %s test", tt.snet+" "+tt.saddr+"<-"+tt.taddr)
    255 			continue
    256 		}
    257 
    258 		c1, err := ListenPacket(tt.snet, tt.saddr)
    259 		if err != nil {
    260 			if perr := parseDialError(err); perr != nil {
    261 				t.Error(perr)
    262 			}
    263 			t.Fatal(err)
    264 		}
    265 
    266 		ls, err := (&packetListener{PacketConn: c1}).newLocalServer()
    267 		if err != nil {
    268 			t.Fatal(err)
    269 		}
    270 		defer ls.teardown()
    271 		tpch := make(chan error, 1)
    272 		handler := func(ls *localPacketServer, c PacketConn) { packetTransponder(c, tpch) }
    273 		if err := ls.buildup(handler); err != nil {
    274 			t.Fatal(err)
    275 		}
    276 
    277 		trch := make(chan error, 1)
    278 		_, port, err := SplitHostPort(ls.PacketConn.LocalAddr().String())
    279 		if err != nil {
    280 			t.Fatal(err)
    281 		}
    282 		if tt.dial {
    283 			d := Dialer{Timeout: someTimeout}
    284 			c2, err := d.Dial(tt.tnet, JoinHostPort(tt.taddr, port))
    285 			if err != nil {
    286 				if perr := parseDialError(err); perr != nil {
    287 					t.Error(perr)
    288 				}
    289 				t.Fatal(err)
    290 			}
    291 			defer c2.Close()
    292 			go transceiver(c2, []byte("UDP SERVER TEST"), trch)
    293 		} else {
    294 			c2, err := ListenPacket(tt.tnet, JoinHostPort(tt.taddr, "0"))
    295 			if err != nil {
    296 				if perr := parseDialError(err); perr != nil {
    297 					t.Error(perr)
    298 				}
    299 				t.Fatal(err)
    300 			}
    301 			defer c2.Close()
    302 			dst, err := ResolveUDPAddr(tt.tnet, JoinHostPort(tt.taddr, port))
    303 			if err != nil {
    304 				t.Fatal(err)
    305 			}
    306 			go packetTransceiver(c2, []byte("UDP SERVER TEST"), dst, trch)
    307 		}
    308 
    309 		for err := range trch {
    310 			t.Errorf("#%d: %v", i, err)
    311 		}
    312 		for err := range tpch {
    313 			t.Errorf("#%d: %v", i, err)
    314 		}
    315 	}
    316 }
    317 
    318 var unixgramServerTests = []struct {
    319 	saddr string // server endpoint
    320 	caddr string // client endpoint
    321 	dial  bool   // test with Dial
    322 }{
    323 	{saddr: testUnixAddr(), caddr: testUnixAddr()},
    324 	{saddr: testUnixAddr(), caddr: testUnixAddr(), dial: true},
    325 
    326 	{saddr: "@nettest/go/unixgram/server", caddr: "@nettest/go/unixgram/client"},
    327 }
    328 
    329 func TestUnixgramServer(t *testing.T) {
    330 	for i, tt := range unixgramServerTests {
    331 		if !testableListenArgs("unixgram", tt.saddr, "") {
    332 			t.Logf("skipping %s test", "unixgram "+tt.saddr+"<-"+tt.caddr)
    333 			continue
    334 		}
    335 
    336 		c1, err := ListenPacket("unixgram", tt.saddr)
    337 		if err != nil {
    338 			if perr := parseDialError(err); perr != nil {
    339 				t.Error(perr)
    340 			}
    341 			t.Fatal(err)
    342 		}
    343 
    344 		ls, err := (&packetListener{PacketConn: c1}).newLocalServer()
    345 		if err != nil {
    346 			t.Fatal(err)
    347 		}
    348 		defer ls.teardown()
    349 		tpch := make(chan error, 1)
    350 		handler := func(ls *localPacketServer, c PacketConn) { packetTransponder(c, tpch) }
    351 		if err := ls.buildup(handler); err != nil {
    352 			t.Fatal(err)
    353 		}
    354 
    355 		trch := make(chan error, 1)
    356 		if tt.dial {
    357 			d := Dialer{Timeout: someTimeout, LocalAddr: &UnixAddr{Net: "unixgram", Name: tt.caddr}}
    358 			c2, err := d.Dial("unixgram", ls.PacketConn.LocalAddr().String())
    359 			if err != nil {
    360 				if perr := parseDialError(err); perr != nil {
    361 					t.Error(perr)
    362 				}
    363 				t.Fatal(err)
    364 			}
    365 			defer os.Remove(c2.LocalAddr().String())
    366 			defer c2.Close()
    367 			go transceiver(c2, []byte(c2.LocalAddr().String()), trch)
    368 		} else {
    369 			c2, err := ListenPacket("unixgram", tt.caddr)
    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 packetTransceiver(c2, []byte("UNIXGRAM SERVER TEST"), ls.PacketConn.LocalAddr(), trch)
    379 		}
    380 
    381 		for err := range trch {
    382 			t.Errorf("#%d: %v", i, err)
    383 		}
    384 		for err := range tpch {
    385 			t.Errorf("#%d: %v", i, err)
    386 		}
    387 	}
    388 }
    389