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