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", "windows", "js", "wasip1":
33 t.Skipf("not supported on %s", runtime.GOOS)
34 }
35
36 for _, tt := range fileConnTests {
37 if !testableNetwork(tt.network) {
38 t.Logf("skipping %s test", tt.network)
39 continue
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 var fileListenerTests = []struct {
124 network string
125 }{
126 {"tcp"},
127 {"unix"},
128 {"unixpacket"},
129 }
130
131 func TestFileListener(t *testing.T) {
132 switch runtime.GOOS {
133 case "plan9", "windows", "js", "wasip1":
134 t.Skipf("not supported on %s", runtime.GOOS)
135 }
136
137 for _, tt := range fileListenerTests {
138 if !testableNetwork(tt.network) {
139 t.Logf("skipping %s test", tt.network)
140 continue
141 }
142
143 ln1 := newLocalListener(t, tt.network)
144 switch tt.network {
145 case "unix", "unixpacket":
146 defer os.Remove(ln1.Addr().String())
147 }
148 addr := ln1.Addr()
149
150 var (
151 f *os.File
152 err error
153 )
154 switch ln1 := ln1.(type) {
155 case *TCPListener:
156 f, err = ln1.File()
157 case *UnixListener:
158 f, err = ln1.File()
159 }
160 switch tt.network {
161 case "unix", "unixpacket":
162 defer ln1.Close()
163 default:
164 if err := ln1.Close(); err != nil {
165 t.Error(err)
166 }
167 }
168 if err != nil {
169 if perr := parseCommonError(err); perr != nil {
170 t.Error(perr)
171 }
172 t.Fatal(err)
173 }
174
175 ln2, err := FileListener(f)
176 if err := f.Close(); err != nil {
177 t.Error(err)
178 }
179 if err != nil {
180 if perr := parseCommonError(err); perr != nil {
181 t.Error(perr)
182 }
183 t.Fatal(err)
184 }
185 defer ln2.Close()
186
187 var wg sync.WaitGroup
188 wg.Add(1)
189 go func() {
190 defer wg.Done()
191 c, err := Dial(ln2.Addr().Network(), ln2.Addr().String())
192 if err != nil {
193 if perr := parseDialError(err); perr != nil {
194 t.Error(perr)
195 }
196 t.Error(err)
197 return
198 }
199 c.Close()
200 }()
201 c, err := ln2.Accept()
202 if err != nil {
203 if perr := parseAcceptError(err); perr != nil {
204 t.Error(perr)
205 }
206 t.Fatal(err)
207 }
208 c.Close()
209 wg.Wait()
210 if !reflect.DeepEqual(ln2.Addr(), addr) {
211 t.Fatalf("got %#v; want %#v", ln2.Addr(), addr)
212 }
213 }
214 }
215
216 var filePacketConnTests = []struct {
217 network string
218 }{
219 {"udp"},
220 {"unixgram"},
221 }
222
223 func TestFilePacketConn(t *testing.T) {
224 switch runtime.GOOS {
225 case "plan9", "windows", "js", "wasip1":
226 t.Skipf("not supported on %s", runtime.GOOS)
227 }
228
229 for _, tt := range filePacketConnTests {
230 if !testableNetwork(tt.network) {
231 t.Logf("skipping %s test", tt.network)
232 continue
233 }
234
235 c1 := newLocalPacketListener(t, tt.network)
236 switch tt.network {
237 case "unixgram":
238 defer os.Remove(c1.LocalAddr().String())
239 }
240 addr := c1.LocalAddr()
241
242 var (
243 f *os.File
244 err error
245 )
246 switch c1 := c1.(type) {
247 case *UDPConn:
248 f, err = c1.File()
249 case *UnixConn:
250 f, err = c1.File()
251 }
252 if err := c1.Close(); err != nil {
253 if perr := parseCloseError(err, false); perr != nil {
254 t.Error(perr)
255 }
256 t.Error(err)
257 }
258 if err != nil {
259 if perr := parseCommonError(err); perr != nil {
260 t.Error(perr)
261 }
262 t.Fatal(err)
263 }
264
265 c2, err := FilePacketConn(f)
266 if err := f.Close(); err != nil {
267 t.Error(err)
268 }
269 if err != nil {
270 if perr := parseCommonError(err); perr != nil {
271 t.Error(perr)
272 }
273 t.Fatal(err)
274 }
275 defer c2.Close()
276
277 if _, err := c2.WriteTo([]byte("FILEPACKETCONN TEST"), addr); err != nil {
278 if perr := parseWriteError(err); perr != nil {
279 t.Error(perr)
280 }
281 t.Fatal(err)
282 }
283 if !reflect.DeepEqual(c2.LocalAddr(), addr) {
284 t.Fatalf("got %#v; want %#v", c2.LocalAddr(), addr)
285 }
286 }
287 }
288
289
290 func TestFileCloseRace(t *testing.T) {
291 switch runtime.GOOS {
292 case "plan9", "windows", "js", "wasip1":
293 t.Skipf("not supported on %s", runtime.GOOS)
294 }
295 if !testableNetwork("tcp") {
296 t.Skip("tcp not supported")
297 }
298
299 handler := func(ls *localServer, ln Listener) {
300 c, err := ln.Accept()
301 if err != nil {
302 return
303 }
304 defer c.Close()
305 var b [1]byte
306 c.Read(b[:])
307 }
308
309 ls := newLocalServer(t, "tcp")
310 defer ls.teardown()
311 if err := ls.buildup(handler); err != nil {
312 t.Fatal(err)
313 }
314
315 const tries = 100
316 for i := 0; i < tries; i++ {
317 c1, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
318 if err != nil {
319 t.Fatal(err)
320 }
321 tc := c1.(*TCPConn)
322
323 var wg sync.WaitGroup
324 wg.Add(2)
325 go func() {
326 defer wg.Done()
327 f, err := tc.File()
328 if err == nil {
329 f.Close()
330 }
331 }()
332 go func() {
333 defer wg.Done()
334 c1.Close()
335 }()
336 wg.Wait()
337 }
338 }
339
View as plain text