Source file
src/net/file_test.go
1
2
3
4
5 package net
6
7 import (
8 "os"
9 "reflect"
10 "runtime"
11 "sync"
12 "testing"
13 )
14
15
16
17
18
19
20
21 var fileConnTests = []struct {
22 network string
23 }{
24 {"tcp"},
25 {"udp"},
26 {"unix"},
27 {"unixpacket"},
28 }
29
30 func TestFileConn(t *testing.T) {
31 switch runtime.GOOS {
32 case "plan9", "js", "wasip1":
33 t.Skipf("not supported on %s", runtime.GOOS)
34 }
35
36 for _, tt := range fileConnTests {
37 t.Run(tt.network, func(t *testing.T) {
38 if !testableNetwork(tt.network) {
39 t.Skipf("skipping %s test", tt.network)
40 }
41
42 var network, address string
43 switch tt.network {
44 case "udp":
45 c := newLocalPacketListener(t, tt.network)
46 defer c.Close()
47 network = c.LocalAddr().Network()
48 address = c.LocalAddr().String()
49 default:
50 handler := func(ls *localServer, ln Listener) {
51 c, err := ln.Accept()
52 if err != nil {
53 return
54 }
55 defer c.Close()
56 var b [1]byte
57 c.Read(b[:])
58 }
59 ls := newLocalServer(t, tt.network)
60 defer ls.teardown()
61 if err := ls.buildup(handler); err != nil {
62 t.Fatal(err)
63 }
64 network = ls.Listener.Addr().Network()
65 address = ls.Listener.Addr().String()
66 }
67
68 c1, err := Dial(network, address)
69 if err != nil {
70 if perr := parseDialError(err); perr != nil {
71 t.Error(perr)
72 }
73 t.Fatal(err)
74 }
75 addr := c1.LocalAddr()
76
77 var f *os.File
78 switch c1 := c1.(type) {
79 case *TCPConn:
80 f, err = c1.File()
81 case *UDPConn:
82 f, err = c1.File()
83 case *UnixConn:
84 f, err = c1.File()
85 }
86 if err := c1.Close(); err != nil {
87 if perr := parseCloseError(err, false); perr != nil {
88 t.Error(perr)
89 }
90 t.Error(err)
91 }
92 if err != nil {
93 if perr := parseCommonError(err); perr != nil {
94 t.Error(perr)
95 }
96 t.Fatal(err)
97 }
98
99 c2, err := FileConn(f)
100 if err := f.Close(); err != nil {
101 t.Error(err)
102 }
103 if err != nil {
104 if perr := parseCommonError(err); perr != nil {
105 t.Error(perr)
106 }
107 t.Fatal(err)
108 }
109 defer c2.Close()
110
111 if _, err := c2.Write([]byte("FILECONN TEST")); err != nil {
112 if perr := parseWriteError(err); perr != nil {
113 t.Error(perr)
114 }
115 t.Fatal(err)
116 }
117 if !reflect.DeepEqual(c2.LocalAddr(), addr) {
118 t.Fatalf("got %#v; want %#v", c2.LocalAddr(), addr)
119 }
120 })
121 }
122 }
123
124 var fileListenerTests = []struct {
125 network string
126 }{
127 {"tcp"},
128 {"unix"},
129 {"unixpacket"},
130 }
131
132 func TestFileListener(t *testing.T) {
133 switch runtime.GOOS {
134 case "plan9", "js", "wasip1":
135 t.Skipf("not supported on %s", runtime.GOOS)
136 }
137
138 for _, tt := range fileListenerTests {
139 t.Run(tt.network, func(t *testing.T) {
140 if !testableNetwork(tt.network) {
141 t.Skipf("skipping %s test", tt.network)
142 }
143
144 ln1 := newLocalListener(t, tt.network)
145 switch tt.network {
146 case "unix", "unixpacket":
147 defer os.Remove(ln1.Addr().String())
148 }
149 addr := ln1.Addr()
150
151 var (
152 f *os.File
153 err error
154 )
155 switch ln1 := ln1.(type) {
156 case *TCPListener:
157 f, err = ln1.File()
158 case *UnixListener:
159 f, err = ln1.File()
160 }
161 switch tt.network {
162 case "unix", "unixpacket":
163 defer ln1.Close()
164 default:
165 if err := ln1.Close(); err != nil {
166 t.Error(err)
167 }
168 }
169 if err != nil {
170 if perr := parseCommonError(err); perr != nil {
171 t.Error(perr)
172 }
173 t.Fatal(err)
174 }
175
176 ln2, err := FileListener(f)
177 if err := f.Close(); err != nil {
178 t.Error(err)
179 }
180 if err != nil {
181 if perr := parseCommonError(err); perr != nil {
182 t.Error(perr)
183 }
184 t.Fatal(err)
185 }
186 defer ln2.Close()
187
188 var wg sync.WaitGroup
189 wg.Add(1)
190 go func() {
191 defer wg.Done()
192 c, err := Dial(ln2.Addr().Network(), ln2.Addr().String())
193 if err != nil {
194 if perr := parseDialError(err); perr != nil {
195 t.Error(perr)
196 }
197 t.Error(err)
198 return
199 }
200 c.Close()
201 }()
202 c, err := ln2.Accept()
203 if err != nil {
204 if perr := parseAcceptError(err); perr != nil {
205 t.Error(perr)
206 }
207 t.Fatal(err)
208 }
209 c.Close()
210 wg.Wait()
211 if !reflect.DeepEqual(ln2.Addr(), addr) {
212 t.Fatalf("got %#v; want %#v", ln2.Addr(), addr)
213 }
214 })
215 }
216 }
217
218 var filePacketConnTests = []struct {
219 network string
220 }{
221 {"udp"},
222 {"unixgram"},
223 }
224
225 func TestFilePacketConn(t *testing.T) {
226 switch runtime.GOOS {
227 case "plan9", "js", "wasip1":
228 t.Skipf("not supported on %s", runtime.GOOS)
229 }
230
231 for _, tt := range filePacketConnTests {
232 t.Run(tt.network, func(t *testing.T) {
233 if !testableNetwork(tt.network) {
234 t.Skipf("skipping %s test", tt.network)
235 }
236
237 c1 := newLocalPacketListener(t, tt.network)
238 switch tt.network {
239 case "unixgram":
240 defer os.Remove(c1.LocalAddr().String())
241 }
242 addr := c1.LocalAddr()
243
244 var (
245 f *os.File
246 err error
247 )
248 switch c1 := c1.(type) {
249 case *UDPConn:
250 f, err = c1.File()
251 case *UnixConn:
252 f, err = c1.File()
253 }
254 if err := c1.Close(); err != nil {
255 if perr := parseCloseError(err, false); perr != nil {
256 t.Error(perr)
257 }
258 t.Error(err)
259 }
260 if err != nil {
261 if perr := parseCommonError(err); perr != nil {
262 t.Error(perr)
263 }
264 t.Fatal(err)
265 }
266
267 c2, err := FilePacketConn(f)
268 if err := f.Close(); err != nil {
269 t.Error(err)
270 }
271 if err != nil {
272 if perr := parseCommonError(err); perr != nil {
273 t.Error(perr)
274 }
275 t.Fatal(err)
276 }
277 defer c2.Close()
278
279 if _, err := c2.WriteTo([]byte("FILEPACKETCONN TEST"), addr); err != nil {
280 if perr := parseWriteError(err); perr != nil {
281 t.Error(perr)
282 }
283 t.Fatal(err)
284 }
285 if !reflect.DeepEqual(c2.LocalAddr(), addr) {
286 t.Fatalf("got %#v; want %#v", c2.LocalAddr(), addr)
287 }
288 })
289 }
290 }
291
292
293 func TestFileCloseRace(t *testing.T) {
294 switch runtime.GOOS {
295 case "plan9", "js", "wasip1":
296 t.Skipf("not supported on %s", runtime.GOOS)
297 }
298 if !testableNetwork("tcp") {
299 t.Skip("tcp not supported")
300 }
301
302 handler := func(ls *localServer, ln Listener) {
303 c, err := ln.Accept()
304 if err != nil {
305 return
306 }
307 defer c.Close()
308 var b [1]byte
309 c.Read(b[:])
310 }
311
312 ls := newLocalServer(t, "tcp")
313 defer ls.teardown()
314 if err := ls.buildup(handler); err != nil {
315 t.Fatal(err)
316 }
317
318 const tries = 100
319 for i := 0; i < tries; i++ {
320 c1, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
321 if err != nil {
322 t.Fatal(err)
323 }
324 tc := c1.(*TCPConn)
325
326 var wg sync.WaitGroup
327 wg.Add(2)
328 go func() {
329 defer wg.Done()
330 f, err := tc.File()
331 if err == nil {
332 f.Close()
333 }
334 }()
335 go func() {
336 defer wg.Done()
337 c1.Close()
338 }()
339 wg.Wait()
340 }
341 }
342
View as plain text