1
2
3
4
5 package net
6
7 import (
8 "flag"
9 "io"
10 "os"
11 "strings"
12 "syscall"
13 "testing"
14 "runtime"
15 )
16
17
18
19
20
21 var testUDP = flag.Bool("udp", false, "whether to test UDP datagrams")
22
23 func runEcho(fd io.ReadWriter, done chan<- int) {
24 var buf [1024]byte
25
26 for {
27 n, err := fd.Read(buf[0:])
28 if err != nil || n == 0 || string(buf[:n]) == "END" {
29 break
30 }
31 fd.Write(buf[0:n])
32 }
33 done <- 1
34 }
35
36 func runServe(t *testing.T, network, addr string, listening chan<- string, done chan<- int) {
37 l, err := Listen(network, addr)
38 if err != nil {
39 t.Fatalf("net.Listen(%q, %q) = _, %v", network, addr, err)
40 }
41 listening <- l.Addr().String()
42
43 for {
44 fd, err := l.Accept()
45 if err != nil {
46 break
47 }
48 echodone := make(chan int)
49 go runEcho(fd, echodone)
50 <-echodone
51 l.Close()
52 }
53 done <- 1
54 }
55
56 func connect(t *testing.T, network, addr string, isEmpty bool) {
57 var fd Conn
58 var err os.Error
59 if network == "unixgram" {
60 fd, err = DialUnix(network, &UnixAddr{addr + ".local", network}, &UnixAddr{addr, network})
61 } else {
62 fd, err = Dial(network, addr)
63 }
64 if err != nil {
65 t.Fatalf("net.Dial(%q, %q) = _, %v", network, addr, err)
66 }
67 fd.SetReadTimeout(1e9)
68
69 var b []byte
70 if !isEmpty {
71 b = []byte("hello, world\n")
72 }
73 var b1 [100]byte
74
75 n, err1 := fd.Write(b)
76 if n != len(b) {
77 t.Fatalf("fd.Write(%q) = %d, %v", b, n, err1)
78 }
79
80 n, err1 = fd.Read(b1[0:])
81 if n != len(b) || err1 != nil {
82 t.Fatalf("fd.Read() = %d, %v (want %d, nil)", n, err1, len(b))
83 }
84
85
86
87 if network == "unixpacket" {
88 fd.Write([]byte("END"))
89 }
90
91 fd.Close()
92 }
93
94 func doTest(t *testing.T, network, listenaddr, dialaddr string) {
95 t.Logf("Test %q %q %q\n", network, listenaddr, dialaddr)
96 switch listenaddr {
97 case "", "0.0.0.0", "[::]", "[::ffff:0.0.0.0]":
98 if testing.Short() || avoidMacFirewall {
99 t.Logf("skip wildcard listen during short test")
100 return
101 }
102 }
103 listening := make(chan string)
104 done := make(chan int)
105 if network == "tcp" || network == "tcp4" || network == "tcp6" {
106 listenaddr += ":0"
107 }
108 go runServe(t, network, listenaddr, listening, done)
109 addr := <-listening
110 if network == "tcp" || network == "tcp4" || network == "tcp6" {
111 dialaddr += addr[strings.LastIndex(addr, ":"):]
112 }
113 connect(t, network, dialaddr, false)
114 <-done
115 }
116
117 func TestTCPServer(t *testing.T) {
118 doTest(t, "tcp", "", "127.0.0.1")
119 doTest(t, "tcp", "0.0.0.0", "127.0.0.1")
120 doTest(t, "tcp", "127.0.0.1", "127.0.0.1")
121 doTest(t, "tcp4", "", "127.0.0.1")
122 doTest(t, "tcp4", "0.0.0.0", "127.0.0.1")
123 doTest(t, "tcp4", "127.0.0.1", "127.0.0.1")
124 if supportsIPv6 {
125 doTest(t, "tcp", "", "[::1]")
126 doTest(t, "tcp", "[::]", "[::1]")
127 doTest(t, "tcp", "[::1]", "[::1]")
128 doTest(t, "tcp6", "", "[::1]")
129 doTest(t, "tcp6", "[::]", "[::1]")
130 doTest(t, "tcp6", "[::1]", "[::1]")
131 }
132 if supportsIPv6 && supportsIPv4map {
133 doTest(t, "tcp", "[::ffff:0.0.0.0]", "127.0.0.1")
134 doTest(t, "tcp", "[::]", "127.0.0.1")
135 doTest(t, "tcp4", "[::ffff:0.0.0.0]", "127.0.0.1")
136 doTest(t, "tcp6", "", "127.0.0.1")
137 doTest(t, "tcp6", "[::ffff:0.0.0.0]", "127.0.0.1")
138 doTest(t, "tcp6", "[::]", "127.0.0.1")
139 doTest(t, "tcp", "127.0.0.1", "[::ffff:127.0.0.1]")
140 doTest(t, "tcp", "[::ffff:127.0.0.1]", "127.0.0.1")
141 doTest(t, "tcp4", "127.0.0.1", "[::ffff:127.0.0.1]")
142 doTest(t, "tcp4", "[::ffff:127.0.0.1]", "127.0.0.1")
143 doTest(t, "tcp6", "127.0.0.1", "[::ffff:127.0.0.1]")
144 doTest(t, "tcp6", "[::ffff:127.0.0.1]", "127.0.0.1")
145 }
146 }
147
148 func TestUnixServer(t *testing.T) {
149
150 if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
151 return
152 }
153 os.Remove("/tmp/gotest.net")
154 doTest(t, "unix", "/tmp/gotest.net", "/tmp/gotest.net")
155 os.Remove("/tmp/gotest.net")
156 if syscall.OS == "linux" {
157 doTest(t, "unixpacket", "/tmp/gotest.net", "/tmp/gotest.net")
158 os.Remove("/tmp/gotest.net")
159
160 doTest(t, "unix", "@gotest/net", "@gotest/net")
161 doTest(t, "unixpacket", "@gotest/net", "@gotest/net")
162 }
163 }
164
165 func runPacket(t *testing.T, network, addr string, listening chan<- string, done chan<- int) {
166 c, err := ListenPacket(network, addr)
167 if err != nil {
168 t.Fatalf("net.ListenPacket(%q, %q) = _, %v", network, addr, err)
169 }
170 listening <- c.LocalAddr().String()
171 c.SetReadTimeout(10e6)
172 var buf [1000]byte
173 Run:
174 for {
175 n, addr, err := c.ReadFrom(buf[0:])
176 if e, ok := err.(Error); ok && e.Timeout() {
177 select {
178 case done <- 1:
179 break Run
180 default:
181 continue Run
182 }
183 }
184 if err != nil {
185 break
186 }
187 if _, err = c.WriteTo(buf[0:n], addr); err != nil {
188 t.Fatalf("WriteTo %v: %v", addr, err)
189 }
190 }
191 c.Close()
192 done <- 1
193 }
194
195 func doTestPacket(t *testing.T, network, listenaddr, dialaddr string, isEmpty bool) {
196 t.Logf("TestPacket %s %s %s\n", network, listenaddr, dialaddr)
197 listening := make(chan string)
198 done := make(chan int)
199 if network == "udp" {
200 listenaddr += ":0"
201 }
202 go runPacket(t, network, listenaddr, listening, done)
203 addr := <-listening
204 if network == "udp" {
205 dialaddr += addr[strings.LastIndex(addr, ":"):]
206 }
207 connect(t, network, dialaddr, isEmpty)
208 <-done
209 <-done
210 }
211
212 func TestUDPServer(t *testing.T) {
213 if !*testUDP {
214 return
215 }
216 for _, isEmpty := range []bool{false, true} {
217 doTestPacket(t, "udp", "0.0.0.0", "127.0.0.1", isEmpty)
218 doTestPacket(t, "udp", "", "127.0.0.1", isEmpty)
219 if supportsIPv6 && supportsIPv4map {
220 doTestPacket(t, "udp", "[::]", "[::ffff:127.0.0.1]", isEmpty)
221 doTestPacket(t, "udp", "[::]", "127.0.0.1", isEmpty)
222 doTestPacket(t, "udp", "0.0.0.0", "[::ffff:127.0.0.1]", isEmpty)
223 }
224 }
225 }
226
227 func TestUnixDatagramServer(t *testing.T) {
228
229 if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
230 return
231 }
232 for _, isEmpty := range []bool{false} {
233 os.Remove("/tmp/gotest1.net")
234 os.Remove("/tmp/gotest1.net.local")
235 doTestPacket(t, "unixgram", "/tmp/gotest1.net", "/tmp/gotest1.net", isEmpty)
236 os.Remove("/tmp/gotest1.net")
237 os.Remove("/tmp/gotest1.net.local")
238 if syscall.OS == "linux" {
239
240 doTestPacket(t, "unixgram", "@gotest1/net", "@gotest1/net", isEmpty)
241 }
242 }
243 }