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