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.
16 func skipServerTest(net
, unixsotype
, addr
string, ipv6
, ipv4map
, linuxOnly
bool) bool {
19 case "nacl", "plan9", "windows":
20 // "unix" sockets are not supported on Windows and Plan 9.
21 if net
== unixsotype
{
25 if net
== unixsotype
&& linuxOnly
{
30 case "", "0.0.0.0", "[::ffff:0.0.0.0]", "[::]":
31 if testing
.Short() ||
!*testExternal
{
35 if ipv6
&& !supportsIPv6
{
38 if ipv4map
&& !supportsIPv4map
{
44 var streamConnServerTests
= []struct {
45 snet
string // server side
47 cnet
string // client side
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
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},
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},
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},
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},
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},
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"},
82 {snet
: "tcp4", saddr
: "127.0.0.1", cnet
: "tcp4", caddr
: "127.0.0.1"},
84 {snet
: "tcp6", saddr
: "", cnet
: "tcp6", caddr
: "[::1]", ipv6
: true},
85 {snet
: "tcp6", saddr
: "[::]", cnet
: "tcp6", caddr
: "[::1]", ipv6
: true},
87 {snet
: "tcp6", saddr
: "[::1]", cnet
: "tcp6", caddr
: "[::1]", ipv6
: true},
89 {snet
: "unix", saddr
: testUnixAddr(), cnet
: "unix", caddr
: testUnixAddr()},
90 {snet
: "unix", saddr
: "@gotest2/net", cnet
: "unix", caddr
: "@gotest2/net.local", linuxOnly
: true},
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
) {
99 listening
:= make(chan string)
100 done
:= make(chan int)
102 case "tcp", "tcp4", "tcp6":
109 go runStreamConnServer(t
, tt
.snet
, tt
.saddr
, listening
, done
)
110 taddr
:= <-listening
// wait for server to start
113 case "tcp", "tcp4", "tcp6":
114 _
, port
, err
:= SplitHostPort(taddr
)
116 t
.Fatalf("SplitHostPort(%q) failed: %v", taddr
, err
)
118 taddr
= tt
.caddr
+ ":" + port
121 runStreamConnClient(t
, tt
.cnet
, taddr
, tt
.empty
)
122 <-done
// make sure server stopped
132 var seqpacketConnServerTests
= []struct {
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
139 {net
: "unixpacket", saddr
: testUnixAddr(), caddr
: testUnixAddr()},
140 {net
: "unixpacket", saddr
: "@gotest4/net", caddr
: "@gotest4/net.local", linuxOnly
: true},
143 func TestSeqpacketConnServer(t
*testing
.T
) {
144 switch runtime
.GOOS
{
145 case "darwin", "nacl", "openbsd", "plan9", "windows":
147 case "freebsd": // FreeBSD 8 doesn't support unixpacket
148 t
.Skipf("skipping test on %q", runtime
.GOOS
)
151 for _
, tt
:= range seqpacketConnServerTests
{
152 if runtime
.GOOS
!= "linux" && tt
.linuxOnly
{
155 listening
:= make(chan string)
156 done
:= make(chan int)
163 go runStreamConnServer(t
, tt
.net
, tt
.saddr
, listening
, done
)
164 taddr
:= <-listening
// wait for server to start
166 runStreamConnClient(t
, tt
.net
, taddr
, tt
.empty
)
167 <-done
// make sure server stopped
177 func runStreamConnServer(t
*testing
.T
, net
, laddr
string, listening
chan<- string, done
chan<- int) {
179 l
, err
:= Listen(net
, laddr
)
181 t
.Errorf("Listen(%q, %q) failed: %v", net
, laddr
, err
)
186 listening
<- l
.Addr().String()
188 echo
:= func(rw io
.ReadWriter
, done
chan<- int) {
189 buf
:= make([]byte, 1024)
191 n
, err
:= rw
.Read(buf
[0:])
192 if err
!= nil || n
== 0 ||
string(buf
[:n
]) == "END" {
204 t
.Logf("Accept failed: %v", err
)
207 echodone
:= make(chan int)
209 <-echodone
// make sure echo stopped
215 func runStreamConnClient(t
*testing
.T
, net
, taddr
string, isEmpty
bool) {
216 c
, err
:= Dial(net
, taddr
)
218 t
.Fatalf("Dial(%q, %q) failed: %v", net
, taddr
, err
)
221 c
.SetReadDeadline(time
.Now().Add(1 * time
.Second
))
225 wb
= []byte("StreamConnClient by Dial\n")
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
))
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
))
236 // Send explicit ending for unixpacket.
237 // Older Linux kernels do not stop reads on close.
240 c
.Write([]byte("END"))
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")
250 var datagramPacketConnServerTests
= []struct {
251 snet
string // server side
253 cnet
string // client side
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
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},
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},
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},
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},
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},
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"},
289 {snet
: "udp4", saddr
: "127.0.0.1", cnet
: "udp4", caddr
: "127.0.0.1"},
291 {snet
: "udp6", saddr
: "", cnet
: "udp6", caddr
: "[::1]", ipv6
: true},
292 {snet
: "udp6", saddr
: "[::]", cnet
: "udp6", caddr
: "[::1]", ipv6
: true},
294 {snet
: "udp6", saddr
: "[::1]", cnet
: "udp6", caddr
: "[::1]", ipv6
: true},
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},
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},
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},
309 {snet
: "unixgram", saddr
: "@gotest6/net", cnet
: "unixgram", caddr
: "@gotest6/net.local", linuxOnly
: true},
312 func TestDatagramPacketConnServer(t
*testing
.T
) {
317 for _
, tt
:= range datagramPacketConnServerTests
{
318 if skipServerTest(tt
.snet
, "unixgram", tt
.saddr
, tt
.ipv6
, tt
.ipv4map
, tt
.linuxOnly
) {
322 listening
:= make(chan string)
323 done
:= make(chan int)
325 case "udp", "udp4", "udp6":
332 go runDatagramPacketConnServer(t
, tt
.snet
, tt
.saddr
, listening
, done
)
333 taddr
:= <-listening
// wait for server to start
336 case "udp", "udp4", "udp6":
337 _
, port
, err
:= SplitHostPort(taddr
)
339 t
.Fatalf("SplitHostPort(%q) failed: %v", taddr
, err
)
341 taddr
= tt
.caddr
+ ":" + port
345 runDatagramConnClient(t
, tt
.cnet
, tt
.caddr
, taddr
, tt
.empty
)
347 runDatagramPacketConnClient(t
, tt
.cnet
, tt
.caddr
, taddr
, tt
.empty
)
349 <-done
// tell server to stop
350 <-done
// make sure server stopped
360 func runDatagramPacketConnServer(t
*testing
.T
, net
, laddr
string, listening
chan<- string, done
chan<- int) {
361 c
, err
:= ListenPacket(net
, laddr
)
363 t
.Errorf("ListenPacket(%q, %q) failed: %v", net
, laddr
, err
)
369 listening
<- c
.LocalAddr().String()
371 buf
:= make([]byte, 1024)
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() {
387 if _
, err
= c
.WriteTo(buf
[0:n
], ra
); err
!= nil {
388 t
.Errorf("WriteTo(%v) failed: %v", ra
, err
)
395 func runDatagramConnClient(t
*testing
.T
, net
, laddr
, taddr
string, isEmpty
bool) {
399 case "udp", "udp4", "udp6":
400 c
, err
= Dial(net
, taddr
)
402 t
.Fatalf("Dial(%q, %q) failed: %v", net
, taddr
, err
)
405 c
, err
= DialUnix(net
, &UnixAddr
{Name
: laddr
, Net
: net
}, &UnixAddr
{Name
: taddr
, Net
: net
})
407 t
.Fatalf("DialUnix(%q, {%q, %q}) failed: %v", net
, laddr
, taddr
, err
)
411 c
.SetReadDeadline(time
.Now().Add(1 * time
.Second
))
415 wb
= []byte("DatagramConnClient by Dial\n")
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
))
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
))
427 func runDatagramPacketConnClient(t
*testing
.T
, net
, laddr
, taddr
string, isEmpty
bool) {
431 case "udp", "udp4", "udp6":
432 ra
, err
= ResolveUDPAddr(net
, taddr
)
434 t
.Fatalf("ResolveUDPAddr(%q, %q) failed: %v", net
, taddr
, err
)
437 ra
, err
= ResolveUnixAddr(net
, taddr
)
439 t
.Fatalf("ResolveUxixAddr(%q, %q) failed: %v", net
, taddr
, err
)
442 c
, err
:= ListenPacket(net
, laddr
)
444 t
.Fatalf("ListenPacket(%q, %q) faild: %v", net
, laddr
, err
)
447 c
.SetReadDeadline(time
.Now().Add(1 * time
.Second
))
451 wb
= []byte("DatagramPacketConnClient by ListenPacket\n")
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
))
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
))