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 "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 linux
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
: "/tmp/gotest1.net", cnet
: "unix", caddr
: "/tmp/gotest1.net.local"},
90 {snet
: "unix", saddr
: "@gotest2/net", cnet
: "unix", caddr
: "@gotest2/net.local", linux
: 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
.linux
) {
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
.Errorf("SplitHostPort(%q) failed: %v", taddr
, err
)
119 taddr
= tt
.caddr
+ ":" + port
122 runStreamConnClient(t
, tt
.cnet
, taddr
, tt
.empty
)
123 <-done
// make sure server stopped
133 var seqpacketConnServerTests
= []struct {
135 saddr
string // server address
136 caddr
string // client address
137 empty
bool // test with empty data
139 {net
: "unixpacket", saddr
: "/tmp/gotest3.net", caddr
: "/tmp/gotest3.net.local"},
140 {net
: "unixpacket", saddr
: "@gotest4/net", caddr
: "@gotest4/net.local"},
143 func TestSeqpacketConnServer(t
*testing
.T
) {
144 if runtime
.GOOS
!= "linux" {
145 t
.Skipf("skipping test on %q", runtime
.GOOS
)
148 for _
, tt
:= range seqpacketConnServerTests
{
149 listening
:= make(chan string)
150 done
:= make(chan int)
157 go runStreamConnServer(t
, tt
.net
, tt
.saddr
, listening
, done
)
158 taddr
:= <-listening
// wait for server to start
160 runStreamConnClient(t
, tt
.net
, taddr
, tt
.empty
)
161 <-done
// make sure server stopped
171 func runStreamConnServer(t
*testing
.T
, net
, laddr
string, listening
chan<- string, done
chan<- int) {
172 l
, err
:= Listen(net
, laddr
)
174 t
.Errorf("Listen(%q, %q) failed: %v", net
, laddr
, err
)
180 listening
<- l
.Addr().String()
182 echo
:= func(rw io
.ReadWriter
, done
chan<- int) {
183 buf
:= make([]byte, 1024)
185 n
, err
:= rw
.Read(buf
[0:])
186 if err
!= nil || n
== 0 ||
string(buf
[:n
]) == "END" {
200 echodone
:= make(chan int)
202 <-echodone
// make sure echo stopped
209 func runStreamConnClient(t
*testing
.T
, net
, taddr
string, isEmpty
bool) {
210 c
, err
:= Dial(net
, taddr
)
212 t
.Errorf("Dial(%q, %q) failed: %v", net
, taddr
, err
)
216 c
.SetReadDeadline(time
.Now().Add(1 * time
.Second
))
220 wb
= []byte("StreamConnClient by Dial\n")
222 if n
, err
:= c
.Write(wb
); err
!= nil || n
!= len(wb
) {
223 t
.Errorf("Write failed: %v, %v; want %v, <nil>", n
, err
, len(wb
))
227 rb
:= make([]byte, 1024)
228 if n
, err
:= c
.Read(rb
[0:]); err
!= nil || n
!= len(wb
) {
229 t
.Errorf("Read failed: %v, %v; want %v, <nil>", n
, err
, len(wb
))
233 // Send explicit ending for unixpacket.
234 // Older Linux kernels do not stop reads on close.
237 c
.Write([]byte("END"))
241 // Do not test empty datagrams by default.
242 // It causes unexplained timeouts on some systems,
243 // including Snow Leopard. I think that the kernel
244 // doesn't quite expect them.
245 var testDatagram
= flag
.Bool("datagram", false, "whether to test udp and unixgram")
247 var datagramPacketConnServerTests
= []struct {
248 snet
string // server side
250 cnet
string // client side
252 ipv6
bool // test with underlying AF_INET6 socket
253 ipv4map
bool // test with IPv6 IPv4-mapping functionality
254 dial
bool // test with Dial or DialUnix
255 empty
bool // test with empty data
256 linux
bool // test with abstract unix domain socket, a Linux-ism
258 {snet
: "udp", saddr
: "", cnet
: "udp", caddr
: "127.0.0.1"},
259 {snet
: "udp", saddr
: "0.0.0.0", cnet
: "udp", caddr
: "127.0.0.1"},
260 {snet
: "udp", saddr
: "[::ffff:0.0.0.0]", cnet
: "udp", caddr
: "127.0.0.1"},
261 {snet
: "udp", saddr
: "[::]", cnet
: "udp", caddr
: "[::1]", ipv6
: true},
263 {snet
: "udp", saddr
: "", cnet
: "udp", caddr
: "[::1]", ipv4map
: true},
264 {snet
: "udp", saddr
: "0.0.0.0", cnet
: "udp", caddr
: "[::1]", ipv4map
: true},
265 {snet
: "udp", saddr
: "[::ffff:0.0.0.0]", cnet
: "udp", caddr
: "[::1]", ipv4map
: true},
266 {snet
: "udp", saddr
: "[::]", cnet
: "udp", caddr
: "127.0.0.1", ipv4map
: true},
268 {snet
: "udp", saddr
: "", cnet
: "udp4", caddr
: "127.0.0.1"},
269 {snet
: "udp", saddr
: "0.0.0.0", cnet
: "udp4", caddr
: "127.0.0.1"},
270 {snet
: "udp", saddr
: "[::ffff:0.0.0.0]", cnet
: "udp4", caddr
: "127.0.0.1"},
271 {snet
: "udp", saddr
: "[::]", cnet
: "udp6", caddr
: "[::1]", ipv6
: true},
273 {snet
: "udp", saddr
: "", cnet
: "udp6", caddr
: "[::1]", ipv4map
: true},
274 {snet
: "udp", saddr
: "0.0.0.0", cnet
: "udp6", caddr
: "[::1]", ipv4map
: true},
275 {snet
: "udp", saddr
: "[::ffff:0.0.0.0]", cnet
: "udp6", caddr
: "[::1]", ipv4map
: true},
276 {snet
: "udp", saddr
: "[::]", cnet
: "udp4", caddr
: "127.0.0.1", ipv4map
: true},
278 {snet
: "udp", saddr
: "127.0.0.1", cnet
: "udp", caddr
: "127.0.0.1"},
279 {snet
: "udp", saddr
: "[::ffff:127.0.0.1]", cnet
: "udp", caddr
: "127.0.0.1"},
280 {snet
: "udp", saddr
: "[::1]", cnet
: "udp", caddr
: "[::1]", ipv6
: true},
282 {snet
: "udp4", saddr
: "", cnet
: "udp4", caddr
: "127.0.0.1"},
283 {snet
: "udp4", saddr
: "0.0.0.0", cnet
: "udp4", caddr
: "127.0.0.1"},
284 {snet
: "udp4", saddr
: "[::ffff:0.0.0.0]", cnet
: "udp4", caddr
: "127.0.0.1"},
286 {snet
: "udp4", saddr
: "127.0.0.1", cnet
: "udp4", caddr
: "127.0.0.1"},
288 {snet
: "udp6", saddr
: "", cnet
: "udp6", caddr
: "[::1]", ipv6
: true},
289 {snet
: "udp6", saddr
: "[::]", cnet
: "udp6", caddr
: "[::1]", ipv6
: true},
291 {snet
: "udp6", saddr
: "[::1]", cnet
: "udp6", caddr
: "[::1]", ipv6
: true},
293 {snet
: "udp", saddr
: "127.0.0.1", cnet
: "udp", caddr
: "127.0.0.1", dial
: true},
294 {snet
: "udp", saddr
: "127.0.0.1", cnet
: "udp", caddr
: "127.0.0.1", empty
: true},
295 {snet
: "udp", saddr
: "127.0.0.1", cnet
: "udp", caddr
: "127.0.0.1", dial
: true, empty
: true},
297 {snet
: "udp", saddr
: "[::1]", cnet
: "udp", caddr
: "[::1]", ipv6
: true, dial
: true},
298 {snet
: "udp", saddr
: "[::1]", cnet
: "udp", caddr
: "[::1]", ipv6
: true, empty
: true},
299 {snet
: "udp", saddr
: "[::1]", cnet
: "udp", caddr
: "[::1]", ipv6
: true, dial
: true, empty
: true},
301 {snet
: "unixgram", saddr
: "/tmp/gotest5.net", cnet
: "unixgram", caddr
: "/tmp/gotest5.net.local"},
302 {snet
: "unixgram", saddr
: "/tmp/gotest5.net", cnet
: "unixgram", caddr
: "/tmp/gotest5.net.local", dial
: true},
303 {snet
: "unixgram", saddr
: "/tmp/gotest5.net", cnet
: "unixgram", caddr
: "/tmp/gotest5.net.local", empty
: true},
304 {snet
: "unixgram", saddr
: "/tmp/gotest5.net", cnet
: "unixgram", caddr
: "/tmp/gotest5.net.local", dial
: true, empty
: true},
306 {snet
: "unixgram", saddr
: "@gotest6/net", cnet
: "unixgram", caddr
: "@gotest6/net.local", linux
: true},
309 func TestDatagramPacketConnServer(t
*testing
.T
) {
314 for _
, tt
:= range datagramPacketConnServerTests
{
315 if skipServerTest(tt
.snet
, "unixgram", tt
.saddr
, tt
.ipv6
, tt
.ipv4map
, tt
.linux
) {
319 listening
:= make(chan string)
320 done
:= make(chan int)
322 case "udp", "udp4", "udp6":
329 go runDatagramPacketConnServer(t
, tt
.snet
, tt
.saddr
, listening
, done
)
330 taddr
:= <-listening
// wait for server to start
333 case "udp", "udp4", "udp6":
334 _
, port
, err
:= SplitHostPort(taddr
)
336 t
.Errorf("SplitHostPort(%q) failed: %v", taddr
, err
)
339 taddr
= tt
.caddr
+ ":" + port
343 runDatagramConnClient(t
, tt
.cnet
, tt
.caddr
, taddr
, tt
.empty
)
345 runDatagramPacketConnClient(t
, tt
.cnet
, tt
.caddr
, taddr
, tt
.empty
)
347 <-done
// tell server to stop
348 <-done
// make sure server stopped
358 func runDatagramPacketConnServer(t
*testing
.T
, net
, laddr
string, listening
chan<- string, done
chan<- int) {
359 c
, err
:= ListenPacket(net
, laddr
)
361 t
.Errorf("ListenPacket(%q, %q) failed: %v", net
, laddr
, err
)
367 listening
<- c
.LocalAddr().String()
369 buf
:= make([]byte, 1024)
372 c
.SetReadDeadline(time
.Now().Add(10 * time
.Millisecond
))
373 n
, ra
, err
:= c
.ReadFrom(buf
[0:])
374 if nerr
, ok
:= err
.(Error
); ok
&& nerr
.Timeout() {
385 if _
, err
= c
.WriteTo(buf
[0:n
], ra
); err
!= nil {
386 t
.Errorf("WriteTo(%v) failed: %v", ra
, err
)
393 func runDatagramConnClient(t
*testing
.T
, net
, laddr
, taddr
string, isEmpty
bool) {
397 case "udp", "udp4", "udp6":
398 c
, err
= Dial(net
, taddr
)
400 t
.Errorf("Dial(%q, %q) failed: %v", net
, taddr
, err
)
404 c
, err
= DialUnix(net
, &UnixAddr
{laddr
, net
}, &UnixAddr
{taddr
, net
})
406 t
.Errorf("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
.Errorf("Write failed: %v, %v; want %v, <nil>", n
, err
, len(wb
))
422 rb
:= make([]byte, 1024)
423 if n
, err
:= c
.Read(rb
[0:]); err
!= nil || n
!= len(wb
) {
424 t
.Errorf("Read failed: %v, %v; want %v, <nil>", n
, err
, len(wb
))
429 func runDatagramPacketConnClient(t
*testing
.T
, net
, laddr
, taddr
string, isEmpty
bool) {
433 case "udp", "udp4", "udp6":
434 ra
, err
= ResolveUDPAddr(net
, taddr
)
436 t
.Errorf("ResolveUDPAddr(%q, %q) failed: %v", net
, taddr
, err
)
440 ra
, err
= ResolveUnixAddr(net
, taddr
)
442 t
.Errorf("ResolveUxixAddr(%q, %q) failed: %v", net
, taddr
, err
)
446 c
, err
:= ListenPacket(net
, laddr
)
448 t
.Errorf("ListenPacket(%q, %q) faild: %v", net
, laddr
, err
)
452 c
.SetReadDeadline(time
.Now().Add(1 * time
.Second
))
456 wb
= []byte("DatagramPacketConnClient by ListenPacket\n")
458 if n
, err
:= c
.WriteTo(wb
[0:], ra
); err
!= nil || n
!= len(wb
) {
459 t
.Errorf("WriteTo(%v) failed: %v, %v; want %v, <nil>", ra
, n
, err
, len(wb
))
463 rb
:= make([]byte, 1024)
464 if n
, _
, err
:= c
.ReadFrom(rb
[0:]); err
!= nil || n
!= len(wb
) {
465 t
.Errorf("ReadFrom failed: %v, %v; want %v, <nil>", n
, err
, len(wb
))