Source file
src/net/unixsock_test.go
Documentation: net
1
2
3
4
5
6
7
8 package net
9
10 import (
11 "bytes"
12 "internal/testenv"
13 "os"
14 "reflect"
15 "runtime"
16 "syscall"
17 "testing"
18 "time"
19 )
20
21 func TestReadUnixgramWithUnnamedSocket(t *testing.T) {
22 if !testableNetwork("unixgram") {
23 t.Skip("unixgram test")
24 }
25 if runtime.GOOS == "openbsd" {
26 testenv.SkipFlaky(t, 15157)
27 }
28
29 addr := testUnixAddr()
30 la, err := ResolveUnixAddr("unixgram", addr)
31 if err != nil {
32 t.Fatal(err)
33 }
34 c, err := ListenUnixgram("unixgram", la)
35 if err != nil {
36 t.Fatal(err)
37 }
38 defer func() {
39 c.Close()
40 os.Remove(addr)
41 }()
42
43 off := make(chan bool)
44 data := [5]byte{1, 2, 3, 4, 5}
45 go func() {
46 defer func() { off <- true }()
47 s, err := syscall.Socket(syscall.AF_UNIX, syscall.SOCK_DGRAM, 0)
48 if err != nil {
49 t.Error(err)
50 return
51 }
52 defer syscall.Close(s)
53 rsa := &syscall.SockaddrUnix{Name: addr}
54 if err := syscall.Sendto(s, data[:], 0, rsa); err != nil {
55 t.Error(err)
56 return
57 }
58 }()
59
60 <-off
61 b := make([]byte, 64)
62 c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
63 n, from, err := c.ReadFrom(b)
64 if err != nil {
65 t.Fatal(err)
66 }
67 if from != nil {
68 t.Fatalf("unexpected peer address: %v", from)
69 }
70 if !bytes.Equal(b[:n], data[:]) {
71 t.Fatalf("got %v; want %v", b[:n], data[:])
72 }
73 }
74
75 func TestUnixgramZeroBytePayload(t *testing.T) {
76 if !testableNetwork("unixgram") {
77 t.Skip("unixgram test")
78 }
79
80 c1, err := newLocalPacketListener("unixgram")
81 if err != nil {
82 t.Fatal(err)
83 }
84 defer os.Remove(c1.LocalAddr().String())
85 defer c1.Close()
86
87 c2, err := Dial("unixgram", c1.LocalAddr().String())
88 if err != nil {
89 t.Fatal(err)
90 }
91 defer os.Remove(c2.LocalAddr().String())
92 defer c2.Close()
93
94 for _, genericRead := range []bool{false, true} {
95 n, err := c2.Write(nil)
96 if err != nil {
97 t.Fatal(err)
98 }
99 if n != 0 {
100 t.Errorf("got %d; want 0", n)
101 }
102 c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
103 var b [1]byte
104 var peer Addr
105 if genericRead {
106 _, err = c1.(Conn).Read(b[:])
107 } else {
108 _, peer, err = c1.ReadFrom(b[:])
109 }
110 switch err {
111 case nil:
112 if peer != nil {
113 t.Fatalf("unexpected peer address: %v", peer)
114 }
115 default:
116 if !isDeadlineExceeded(err) {
117 t.Fatal(err)
118 }
119 }
120 }
121 }
122
123 func TestUnixgramZeroByteBuffer(t *testing.T) {
124 if !testableNetwork("unixgram") {
125 t.Skip("unixgram test")
126 }
127
128
129
130 c1, err := newLocalPacketListener("unixgram")
131 if err != nil {
132 t.Fatal(err)
133 }
134 defer os.Remove(c1.LocalAddr().String())
135 defer c1.Close()
136
137 c2, err := Dial("unixgram", c1.LocalAddr().String())
138 if err != nil {
139 t.Fatal(err)
140 }
141 defer os.Remove(c2.LocalAddr().String())
142 defer c2.Close()
143
144 b := []byte("UNIXGRAM ZERO BYTE BUFFER TEST")
145 for _, genericRead := range []bool{false, true} {
146 n, err := c2.Write(b)
147 if err != nil {
148 t.Fatal(err)
149 }
150 if n != len(b) {
151 t.Errorf("got %d; want %d", n, len(b))
152 }
153 c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
154 var peer Addr
155 if genericRead {
156 _, err = c1.(Conn).Read(nil)
157 } else {
158 _, peer, err = c1.ReadFrom(nil)
159 }
160 switch err {
161 case nil:
162 if peer != nil {
163 t.Fatalf("unexpected peer address: %v", peer)
164 }
165 default:
166 if !isDeadlineExceeded(err) {
167 t.Fatal(err)
168 }
169 }
170 }
171 }
172
173 func TestUnixgramWrite(t *testing.T) {
174 if !testableNetwork("unixgram") {
175 t.Skip("unixgram test")
176 }
177
178 addr := testUnixAddr()
179 laddr, err := ResolveUnixAddr("unixgram", addr)
180 if err != nil {
181 t.Fatal(err)
182 }
183 c, err := ListenPacket("unixgram", addr)
184 if err != nil {
185 t.Fatal(err)
186 }
187 defer os.Remove(addr)
188 defer c.Close()
189
190 testUnixgramWriteConn(t, laddr)
191 testUnixgramWritePacketConn(t, laddr)
192 }
193
194 func testUnixgramWriteConn(t *testing.T, raddr *UnixAddr) {
195 c, err := Dial("unixgram", raddr.String())
196 if err != nil {
197 t.Fatal(err)
198 }
199 defer c.Close()
200
201 b := []byte("CONNECTED-MODE SOCKET")
202 if _, err := c.(*UnixConn).WriteToUnix(b, raddr); err == nil {
203 t.Fatal("should fail")
204 } else if err.(*OpError).Err != ErrWriteToConnected {
205 t.Fatalf("should fail as ErrWriteToConnected: %v", err)
206 }
207 if _, err = c.(*UnixConn).WriteTo(b, raddr); err == nil {
208 t.Fatal("should fail")
209 } else if err.(*OpError).Err != ErrWriteToConnected {
210 t.Fatalf("should fail as ErrWriteToConnected: %v", err)
211 }
212 if _, _, err = c.(*UnixConn).WriteMsgUnix(b, nil, raddr); err == nil {
213 t.Fatal("should fail")
214 } else if err.(*OpError).Err != ErrWriteToConnected {
215 t.Fatalf("should fail as ErrWriteToConnected: %v", err)
216 }
217 if _, err := c.Write(b); err != nil {
218 t.Fatal(err)
219 }
220 }
221
222 func testUnixgramWritePacketConn(t *testing.T, raddr *UnixAddr) {
223 addr := testUnixAddr()
224 c, err := ListenPacket("unixgram", addr)
225 if err != nil {
226 t.Fatal(err)
227 }
228 defer os.Remove(addr)
229 defer c.Close()
230
231 b := []byte("UNCONNECTED-MODE SOCKET")
232 if _, err := c.(*UnixConn).WriteToUnix(b, raddr); err != nil {
233 t.Fatal(err)
234 }
235 if _, err := c.WriteTo(b, raddr); err != nil {
236 t.Fatal(err)
237 }
238 if _, _, err := c.(*UnixConn).WriteMsgUnix(b, nil, raddr); err != nil {
239 t.Fatal(err)
240 }
241 if _, err := c.(*UnixConn).Write(b); err == nil {
242 t.Fatal("should fail")
243 }
244 }
245
246 func TestUnixConnLocalAndRemoteNames(t *testing.T) {
247 if !testableNetwork("unix") {
248 t.Skip("unix test")
249 }
250
251 handler := func(ls *localServer, ln Listener) {}
252 for _, laddr := range []string{"", testUnixAddr()} {
253 laddr := laddr
254 taddr := testUnixAddr()
255 ta, err := ResolveUnixAddr("unix", taddr)
256 if err != nil {
257 t.Fatal(err)
258 }
259 ln, err := ListenUnix("unix", ta)
260 if err != nil {
261 t.Fatal(err)
262 }
263 ls, err := (&streamListener{Listener: ln}).newLocalServer()
264 if err != nil {
265 t.Fatal(err)
266 }
267 defer ls.teardown()
268 if err := ls.buildup(handler); err != nil {
269 t.Fatal(err)
270 }
271
272 la, err := ResolveUnixAddr("unix", laddr)
273 if err != nil {
274 t.Fatal(err)
275 }
276 c, err := DialUnix("unix", la, ta)
277 if err != nil {
278 t.Fatal(err)
279 }
280 defer func() {
281 c.Close()
282 if la != nil {
283 defer os.Remove(laddr)
284 }
285 }()
286 if _, err := c.Write([]byte("UNIXCONN LOCAL AND REMOTE NAME TEST")); err != nil {
287 t.Fatal(err)
288 }
289
290 switch runtime.GOOS {
291 case "android", "linux":
292 if laddr == "" {
293 laddr = "@"
294 }
295 }
296 var connAddrs = [3]struct{ got, want Addr }{
297 {ln.Addr(), ta},
298 {c.LocalAddr(), &UnixAddr{Name: laddr, Net: "unix"}},
299 {c.RemoteAddr(), ta},
300 }
301 for _, ca := range connAddrs {
302 if !reflect.DeepEqual(ca.got, ca.want) {
303 t.Fatalf("got %#v, expected %#v", ca.got, ca.want)
304 }
305 }
306 }
307 }
308
309 func TestUnixgramConnLocalAndRemoteNames(t *testing.T) {
310 if !testableNetwork("unixgram") {
311 t.Skip("unixgram test")
312 }
313
314 for _, laddr := range []string{"", testUnixAddr()} {
315 laddr := laddr
316 taddr := testUnixAddr()
317 ta, err := ResolveUnixAddr("unixgram", taddr)
318 if err != nil {
319 t.Fatal(err)
320 }
321 c1, err := ListenUnixgram("unixgram", ta)
322 if err != nil {
323 t.Fatal(err)
324 }
325 defer func() {
326 c1.Close()
327 os.Remove(taddr)
328 }()
329
330 var la *UnixAddr
331 if laddr != "" {
332 if la, err = ResolveUnixAddr("unixgram", laddr); err != nil {
333 t.Fatal(err)
334 }
335 }
336 c2, err := DialUnix("unixgram", la, ta)
337 if err != nil {
338 t.Fatal(err)
339 }
340 defer func() {
341 c2.Close()
342 if la != nil {
343 defer os.Remove(laddr)
344 }
345 }()
346
347 switch runtime.GOOS {
348 case "android", "linux":
349 if laddr == "" {
350 laddr = "@"
351 }
352 }
353
354 var connAddrs = [4]struct{ got, want Addr }{
355 {c1.LocalAddr(), ta},
356 {c1.RemoteAddr(), nil},
357 {c2.LocalAddr(), &UnixAddr{Name: laddr, Net: "unixgram"}},
358 {c2.RemoteAddr(), ta},
359 }
360 for _, ca := range connAddrs {
361 if !reflect.DeepEqual(ca.got, ca.want) {
362 t.Fatalf("got %#v; want %#v", ca.got, ca.want)
363 }
364 }
365 }
366 }
367
368 func TestUnixUnlink(t *testing.T) {
369 if !testableNetwork("unix") {
370 t.Skip("unix test")
371 }
372 name := testUnixAddr()
373
374 listen := func(t *testing.T) *UnixListener {
375 l, err := Listen("unix", name)
376 if err != nil {
377 t.Fatal(err)
378 }
379 return l.(*UnixListener)
380 }
381 checkExists := func(t *testing.T, desc string) {
382 if _, err := os.Stat(name); err != nil {
383 t.Fatalf("unix socket does not exist %s: %v", desc, err)
384 }
385 }
386 checkNotExists := func(t *testing.T, desc string) {
387 if _, err := os.Stat(name); err == nil {
388 t.Fatalf("unix socket does exist %s: %v", desc, err)
389 }
390 }
391
392
393 t.Run("Listen", func(t *testing.T) {
394 l := listen(t)
395 checkExists(t, "after Listen")
396 l.Close()
397 checkNotExists(t, "after Listener close")
398 })
399
400
401 t.Run("FileListener", func(t *testing.T) {
402 l := listen(t)
403 f, _ := l.File()
404 l1, _ := FileListener(f)
405 checkExists(t, "after FileListener")
406 f.Close()
407 checkExists(t, "after File close")
408 l1.Close()
409 checkExists(t, "after FileListener close")
410 l.Close()
411 checkNotExists(t, "after Listener close")
412 })
413
414
415 t.Run("SecondClose", func(t *testing.T) {
416 l := listen(t)
417 checkExists(t, "after Listen")
418 l.Close()
419 checkNotExists(t, "after Listener close")
420 if err := os.WriteFile(name, []byte("hello world"), 0666); err != nil {
421 t.Fatalf("cannot recreate socket file: %v", err)
422 }
423 checkExists(t, "after writing temp file")
424 l.Close()
425 checkExists(t, "after second Listener close")
426 os.Remove(name)
427 })
428
429
430
431 t.Run("Listen/SetUnlinkOnClose(true)", func(t *testing.T) {
432 l := listen(t)
433 checkExists(t, "after Listen")
434 l.SetUnlinkOnClose(true)
435 l.Close()
436 checkNotExists(t, "after Listener close")
437 })
438
439 t.Run("Listen/SetUnlinkOnClose(false)", func(t *testing.T) {
440 l := listen(t)
441 checkExists(t, "after Listen")
442 l.SetUnlinkOnClose(false)
443 l.Close()
444 checkExists(t, "after Listener close")
445 os.Remove(name)
446 })
447
448 t.Run("FileListener/SetUnlinkOnClose(true)", func(t *testing.T) {
449 l := listen(t)
450 f, _ := l.File()
451 l1, _ := FileListener(f)
452 checkExists(t, "after FileListener")
453 l1.(*UnixListener).SetUnlinkOnClose(true)
454 f.Close()
455 checkExists(t, "after File close")
456 l1.Close()
457 checkNotExists(t, "after FileListener close")
458 l.Close()
459 })
460
461 t.Run("FileListener/SetUnlinkOnClose(false)", func(t *testing.T) {
462 l := listen(t)
463 f, _ := l.File()
464 l1, _ := FileListener(f)
465 checkExists(t, "after FileListener")
466 l1.(*UnixListener).SetUnlinkOnClose(false)
467 f.Close()
468 checkExists(t, "after File close")
469 l1.Close()
470 checkExists(t, "after FileListener close")
471 l.Close()
472 })
473 }
474
View as plain text