github.com/code-reading/golang@v0.0.0-20220303082512-ba5bc0e589a3/go/src/net/file_test.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build !js 6 // +build !js 7 8 package net 9 10 import ( 11 "os" 12 "reflect" 13 "runtime" 14 "sync" 15 "testing" 16 ) 17 18 // The full stack test cases for IPConn have been moved to the 19 // following: 20 // golang.org/x/net/ipv4 21 // golang.org/x/net/ipv6 22 // golang.org/x/net/icmp 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() // UnixListener.Close calls syscall.Unlink internally 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 // Issue 24483. 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 }