github.com/mh-cbon/go@v0.0.0-20160603070303-9e112a3fe4c0/src/net/net_test.go (about) 1 // Copyright 2009 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 package net 6 7 import ( 8 "io" 9 "net/internal/socktest" 10 "os" 11 "runtime" 12 "testing" 13 "time" 14 ) 15 16 func TestCloseRead(t *testing.T) { 17 switch runtime.GOOS { 18 case "nacl", "plan9": 19 t.Skipf("not supported on %s", runtime.GOOS) 20 } 21 22 for _, network := range []string{"tcp", "unix", "unixpacket"} { 23 if !testableNetwork(network) { 24 t.Logf("skipping %s test", network) 25 continue 26 } 27 28 ln, err := newLocalListener(network) 29 if err != nil { 30 t.Fatal(err) 31 } 32 switch network { 33 case "unix", "unixpacket": 34 defer os.Remove(ln.Addr().String()) 35 } 36 defer ln.Close() 37 38 c, err := Dial(ln.Addr().Network(), ln.Addr().String()) 39 if err != nil { 40 t.Fatal(err) 41 } 42 switch network { 43 case "unix", "unixpacket": 44 defer os.Remove(c.LocalAddr().String()) 45 } 46 defer c.Close() 47 48 switch c := c.(type) { 49 case *TCPConn: 50 err = c.CloseRead() 51 case *UnixConn: 52 err = c.CloseRead() 53 } 54 if err != nil { 55 if perr := parseCloseError(err); perr != nil { 56 t.Error(perr) 57 } 58 t.Fatal(err) 59 } 60 var b [1]byte 61 n, err := c.Read(b[:]) 62 if n != 0 || err == nil { 63 t.Fatalf("got (%d, %v); want (0, error)", n, err) 64 } 65 } 66 } 67 68 func TestCloseWrite(t *testing.T) { 69 switch runtime.GOOS { 70 case "nacl", "plan9": 71 t.Skipf("not supported on %s", runtime.GOOS) 72 } 73 74 handler := func(ls *localServer, ln Listener) { 75 c, err := ln.Accept() 76 if err != nil { 77 t.Error(err) 78 return 79 } 80 defer c.Close() 81 82 var b [1]byte 83 n, err := c.Read(b[:]) 84 if n != 0 || err != io.EOF { 85 t.Errorf("got (%d, %v); want (0, io.EOF)", n, err) 86 return 87 } 88 switch c := c.(type) { 89 case *TCPConn: 90 err = c.CloseWrite() 91 case *UnixConn: 92 err = c.CloseWrite() 93 } 94 if err != nil { 95 if perr := parseCloseError(err); perr != nil { 96 t.Error(perr) 97 } 98 t.Error(err) 99 return 100 } 101 n, err = c.Write(b[:]) 102 if err == nil { 103 t.Errorf("got (%d, %v); want (any, error)", n, err) 104 return 105 } 106 } 107 108 for _, network := range []string{"tcp", "unix", "unixpacket"} { 109 if !testableNetwork(network) { 110 t.Logf("skipping %s test", network) 111 continue 112 } 113 114 ls, err := newLocalServer(network) 115 if err != nil { 116 t.Fatal(err) 117 } 118 defer ls.teardown() 119 if err := ls.buildup(handler); err != nil { 120 t.Fatal(err) 121 } 122 123 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String()) 124 if err != nil { 125 t.Fatal(err) 126 } 127 switch network { 128 case "unix", "unixpacket": 129 defer os.Remove(c.LocalAddr().String()) 130 } 131 defer c.Close() 132 133 switch c := c.(type) { 134 case *TCPConn: 135 err = c.CloseWrite() 136 case *UnixConn: 137 err = c.CloseWrite() 138 } 139 if err != nil { 140 if perr := parseCloseError(err); perr != nil { 141 t.Error(perr) 142 } 143 t.Fatal(err) 144 } 145 var b [1]byte 146 n, err := c.Read(b[:]) 147 if n != 0 || err != io.EOF { 148 t.Fatalf("got (%d, %v); want (0, io.EOF)", n, err) 149 } 150 n, err = c.Write(b[:]) 151 if err == nil { 152 t.Fatalf("got (%d, %v); want (any, error)", n, err) 153 } 154 } 155 } 156 157 func TestConnClose(t *testing.T) { 158 for _, network := range []string{"tcp", "unix", "unixpacket"} { 159 if !testableNetwork(network) { 160 t.Logf("skipping %s test", network) 161 continue 162 } 163 164 ln, err := newLocalListener(network) 165 if err != nil { 166 t.Fatal(err) 167 } 168 switch network { 169 case "unix", "unixpacket": 170 defer os.Remove(ln.Addr().String()) 171 } 172 defer ln.Close() 173 174 c, err := Dial(ln.Addr().Network(), ln.Addr().String()) 175 if err != nil { 176 t.Fatal(err) 177 } 178 switch network { 179 case "unix", "unixpacket": 180 defer os.Remove(c.LocalAddr().String()) 181 } 182 defer c.Close() 183 184 if err := c.Close(); err != nil { 185 if perr := parseCloseError(err); perr != nil { 186 t.Error(perr) 187 } 188 t.Fatal(err) 189 } 190 var b [1]byte 191 n, err := c.Read(b[:]) 192 if n != 0 || err == nil { 193 t.Fatalf("got (%d, %v); want (0, error)", n, err) 194 } 195 } 196 } 197 198 func TestListenerClose(t *testing.T) { 199 for _, network := range []string{"tcp", "unix", "unixpacket"} { 200 if !testableNetwork(network) { 201 t.Logf("skipping %s test", network) 202 continue 203 } 204 205 ln, err := newLocalListener(network) 206 if err != nil { 207 t.Fatal(err) 208 } 209 switch network { 210 case "unix", "unixpacket": 211 defer os.Remove(ln.Addr().String()) 212 } 213 214 dst := ln.Addr().String() 215 if err := ln.Close(); err != nil { 216 if perr := parseCloseError(err); perr != nil { 217 t.Error(perr) 218 } 219 t.Fatal(err) 220 } 221 c, err := ln.Accept() 222 if err == nil { 223 c.Close() 224 t.Fatal("should fail") 225 } 226 227 if network == "tcp" { 228 // We will have two TCP FSMs inside the 229 // kernel here. There's no guarantee that a 230 // signal comes from the far end FSM will be 231 // delivered immediately to the near end FSM, 232 // especially on the platforms that allow 233 // multiple consumer threads to pull pending 234 // established connections at the same time by 235 // enabling SO_REUSEPORT option such as Linux, 236 // DragonFly BSD. So we need to give some time 237 // quantum to the kernel. 238 // 239 // Note that net.inet.tcp.reuseport_ext=1 by 240 // default on DragonFly BSD. 241 time.Sleep(time.Millisecond) 242 243 cc, err := Dial("tcp", dst) 244 if err == nil { 245 t.Error("Dial to closed TCP listener succeeded.") 246 cc.Close() 247 } 248 } 249 } 250 } 251 252 func TestPacketConnClose(t *testing.T) { 253 for _, network := range []string{"udp", "unixgram"} { 254 if !testableNetwork(network) { 255 t.Logf("skipping %s test", network) 256 continue 257 } 258 259 c, err := newLocalPacketListener(network) 260 if err != nil { 261 t.Fatal(err) 262 } 263 switch network { 264 case "unixgram": 265 defer os.Remove(c.LocalAddr().String()) 266 } 267 defer c.Close() 268 269 if err := c.Close(); err != nil { 270 if perr := parseCloseError(err); perr != nil { 271 t.Error(perr) 272 } 273 t.Fatal(err) 274 } 275 var b [1]byte 276 n, _, err := c.ReadFrom(b[:]) 277 if n != 0 || err == nil { 278 t.Fatalf("got (%d, %v); want (0, error)", n, err) 279 } 280 } 281 } 282 283 // nacl was previous failing to reuse an address. 284 func TestListenCloseListen(t *testing.T) { 285 const maxTries = 10 286 for tries := 0; tries < maxTries; tries++ { 287 ln, err := newLocalListener("tcp") 288 if err != nil { 289 t.Fatal(err) 290 } 291 addr := ln.Addr().String() 292 if err := ln.Close(); err != nil { 293 if perr := parseCloseError(err); perr != nil { 294 t.Error(perr) 295 } 296 t.Fatal(err) 297 } 298 ln, err = Listen("tcp", addr) 299 if err == nil { 300 // Success. nacl couldn't do this before. 301 ln.Close() 302 return 303 } 304 t.Errorf("failed on try %d/%d: %v", tries+1, maxTries, err) 305 } 306 t.Fatalf("failed to listen/close/listen on same address after %d tries", maxTries) 307 } 308 309 // See golang.org/issue/6163, golang.org/issue/6987. 310 func TestAcceptIgnoreAbortedConnRequest(t *testing.T) { 311 switch runtime.GOOS { 312 case "plan9": 313 t.Skipf("%s does not have full support of socktest", runtime.GOOS) 314 } 315 316 syserr := make(chan error) 317 go func() { 318 defer close(syserr) 319 for _, err := range abortedConnRequestErrors { 320 syserr <- err 321 } 322 }() 323 sw.Set(socktest.FilterAccept, func(so *socktest.Status) (socktest.AfterFilter, error) { 324 if err, ok := <-syserr; ok { 325 return nil, err 326 } 327 return nil, nil 328 }) 329 defer sw.Set(socktest.FilterAccept, nil) 330 331 operr := make(chan error, 1) 332 handler := func(ls *localServer, ln Listener) { 333 defer close(operr) 334 c, err := ln.Accept() 335 if err != nil { 336 if perr := parseAcceptError(err); perr != nil { 337 operr <- perr 338 } 339 operr <- err 340 return 341 } 342 c.Close() 343 } 344 ls, err := newLocalServer("tcp") 345 if err != nil { 346 t.Fatal(err) 347 } 348 defer ls.teardown() 349 if err := ls.buildup(handler); err != nil { 350 t.Fatal(err) 351 } 352 353 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String()) 354 if err != nil { 355 t.Fatal(err) 356 } 357 c.Close() 358 359 for err := range operr { 360 t.Error(err) 361 } 362 } 363 364 func TestZeroByteRead(t *testing.T) { 365 for _, network := range []string{"tcp", "unix", "unixpacket"} { 366 if !testableNetwork(network) { 367 t.Logf("skipping %s test", network) 368 continue 369 } 370 371 ln, err := newLocalListener(network) 372 if err != nil { 373 t.Fatal(err) 374 } 375 connc := make(chan Conn, 1) 376 go func() { 377 defer ln.Close() 378 c, err := ln.Accept() 379 if err != nil { 380 t.Error(err) 381 } 382 connc <- c // might be nil 383 }() 384 c, err := Dial(network, ln.Addr().String()) 385 if err != nil { 386 t.Fatal(err) 387 } 388 defer c.Close() 389 sc := <-connc 390 if sc == nil { 391 continue 392 } 393 defer sc.Close() 394 395 if runtime.GOOS == "windows" { 396 // A zero byte read on Windows caused a wait for readability first. 397 // Rather than change that behavior, satisfy it in this test. 398 // See Issue 15735. 399 go io.WriteString(sc, "a") 400 } 401 402 n, err := c.Read(nil) 403 if n != 0 || err != nil { 404 t.Errorf("%s: zero byte client read = %v, %v; want 0, nil", network, n, err) 405 } 406 407 if runtime.GOOS == "windows" { 408 // Same as comment above. 409 go io.WriteString(c, "a") 410 } 411 n, err = sc.Read(nil) 412 if n != 0 || err != nil { 413 t.Errorf("%s: zero byte server read = %v, %v; want 0, nil", network, n, err) 414 } 415 } 416 }