github.com/mtsmfm/go/src@v0.0.0-20221020090648-44bdcb9f8fde/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 7 package net 8 9 import ( 10 "os" 11 "reflect" 12 "runtime" 13 "sync" 14 "testing" 15 ) 16 17 // The full stack test cases for IPConn have been moved to the 18 // following: 19 // golang.org/x/net/ipv4 20 // golang.org/x/net/ipv6 21 // golang.org/x/net/icmp 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 := newLocalPacketListener(t, tt.network) 48 defer c.Close() 49 network = c.LocalAddr().Network() 50 address = c.LocalAddr().String() 51 default: 52 handler := func(ls *localServer, ln Listener) { 53 c, err := ln.Accept() 54 if err != nil { 55 return 56 } 57 defer c.Close() 58 var b [1]byte 59 c.Read(b[:]) 60 } 61 ls := newLocalServer(t, tt.network) 62 defer ls.teardown() 63 if err := ls.buildup(handler); err != nil { 64 t.Fatal(err) 65 } 66 network = ls.Listener.Addr().Network() 67 address = ls.Listener.Addr().String() 68 } 69 70 c1, err := Dial(network, address) 71 if err != nil { 72 if perr := parseDialError(err); perr != nil { 73 t.Error(perr) 74 } 75 t.Fatal(err) 76 } 77 addr := c1.LocalAddr() 78 79 var f *os.File 80 switch c1 := c1.(type) { 81 case *TCPConn: 82 f, err = c1.File() 83 case *UDPConn: 84 f, err = c1.File() 85 case *UnixConn: 86 f, err = c1.File() 87 } 88 if err := c1.Close(); err != nil { 89 if perr := parseCloseError(err, false); perr != nil { 90 t.Error(perr) 91 } 92 t.Error(err) 93 } 94 if err != nil { 95 if perr := parseCommonError(err); perr != nil { 96 t.Error(perr) 97 } 98 t.Fatal(err) 99 } 100 101 c2, err := FileConn(f) 102 if err := f.Close(); err != nil { 103 t.Error(err) 104 } 105 if err != nil { 106 if perr := parseCommonError(err); perr != nil { 107 t.Error(perr) 108 } 109 t.Fatal(err) 110 } 111 defer c2.Close() 112 113 if _, err := c2.Write([]byte("FILECONN TEST")); err != nil { 114 if perr := parseWriteError(err); perr != nil { 115 t.Error(perr) 116 } 117 t.Fatal(err) 118 } 119 if !reflect.DeepEqual(c2.LocalAddr(), addr) { 120 t.Fatalf("got %#v; want %#v", c2.LocalAddr(), addr) 121 } 122 } 123 } 124 125 var fileListenerTests = []struct { 126 network string 127 }{ 128 {"tcp"}, 129 {"unix"}, 130 {"unixpacket"}, 131 } 132 133 func TestFileListener(t *testing.T) { 134 switch runtime.GOOS { 135 case "plan9", "windows": 136 t.Skipf("not supported on %s", runtime.GOOS) 137 } 138 139 for _, tt := range fileListenerTests { 140 if !testableNetwork(tt.network) { 141 t.Logf("skipping %s test", tt.network) 142 continue 143 } 144 145 ln1 := newLocalListener(t, tt.network) 146 switch tt.network { 147 case "unix", "unixpacket": 148 defer os.Remove(ln1.Addr().String()) 149 } 150 addr := ln1.Addr() 151 152 var ( 153 f *os.File 154 err error 155 ) 156 switch ln1 := ln1.(type) { 157 case *TCPListener: 158 f, err = ln1.File() 159 case *UnixListener: 160 f, err = ln1.File() 161 } 162 switch tt.network { 163 case "unix", "unixpacket": 164 defer ln1.Close() // UnixListener.Close calls syscall.Unlink internally 165 default: 166 if err := ln1.Close(); err != nil { 167 t.Error(err) 168 } 169 } 170 if err != nil { 171 if perr := parseCommonError(err); perr != nil { 172 t.Error(perr) 173 } 174 t.Fatal(err) 175 } 176 177 ln2, err := FileListener(f) 178 if err := f.Close(); err != nil { 179 t.Error(err) 180 } 181 if err != nil { 182 if perr := parseCommonError(err); perr != nil { 183 t.Error(perr) 184 } 185 t.Fatal(err) 186 } 187 defer ln2.Close() 188 189 var wg sync.WaitGroup 190 wg.Add(1) 191 go func() { 192 defer wg.Done() 193 c, err := Dial(ln2.Addr().Network(), ln2.Addr().String()) 194 if err != nil { 195 if perr := parseDialError(err); perr != nil { 196 t.Error(perr) 197 } 198 t.Error(err) 199 return 200 } 201 c.Close() 202 }() 203 c, err := ln2.Accept() 204 if err != nil { 205 if perr := parseAcceptError(err); perr != nil { 206 t.Error(perr) 207 } 208 t.Fatal(err) 209 } 210 c.Close() 211 wg.Wait() 212 if !reflect.DeepEqual(ln2.Addr(), addr) { 213 t.Fatalf("got %#v; want %#v", ln2.Addr(), addr) 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", "windows": 228 t.Skipf("not supported on %s", runtime.GOOS) 229 } 230 231 for _, tt := range filePacketConnTests { 232 if !testableNetwork(tt.network) { 233 t.Logf("skipping %s test", tt.network) 234 continue 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 // Issue 24483. 292 func TestFileCloseRace(t *testing.T) { 293 switch runtime.GOOS { 294 case "plan9", "windows": 295 t.Skipf("not supported on %s", runtime.GOOS) 296 } 297 if !testableNetwork("tcp") { 298 t.Skip("tcp not supported") 299 } 300 301 handler := func(ls *localServer, ln Listener) { 302 c, err := ln.Accept() 303 if err != nil { 304 return 305 } 306 defer c.Close() 307 var b [1]byte 308 c.Read(b[:]) 309 } 310 311 ls := newLocalServer(t, "tcp") 312 defer ls.teardown() 313 if err := ls.buildup(handler); err != nil { 314 t.Fatal(err) 315 } 316 317 const tries = 100 318 for i := 0; i < tries; i++ { 319 c1, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String()) 320 if err != nil { 321 t.Fatal(err) 322 } 323 tc := c1.(*TCPConn) 324 325 var wg sync.WaitGroup 326 wg.Add(2) 327 go func() { 328 defer wg.Done() 329 f, err := tc.File() 330 if err == nil { 331 f.Close() 332 } 333 }() 334 go func() { 335 defer wg.Done() 336 c1.Close() 337 }() 338 wg.Wait() 339 } 340 }