github.com/aloncn/graphics-go@v0.0.1/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 "os" 10 "runtime" 11 "testing" 12 "time" 13 ) 14 15 func TestCloseRead(t *testing.T) { 16 switch runtime.GOOS { 17 case "nacl", "plan9": 18 t.Skipf("not supported on %s", runtime.GOOS) 19 } 20 21 for _, network := range []string{"tcp", "unix", "unixpacket"} { 22 if !testableNetwork(network) { 23 t.Logf("skipping %s test", network) 24 continue 25 } 26 27 ln, err := newLocalListener(network) 28 if err != nil { 29 t.Fatal(err) 30 } 31 switch network { 32 case "unix", "unixpacket": 33 defer os.Remove(ln.Addr().String()) 34 } 35 defer ln.Close() 36 37 c, err := Dial(ln.Addr().Network(), ln.Addr().String()) 38 if err != nil { 39 t.Fatal(err) 40 } 41 switch network { 42 case "unix", "unixpacket": 43 defer os.Remove(c.LocalAddr().String()) 44 } 45 defer c.Close() 46 47 switch c := c.(type) { 48 case *TCPConn: 49 err = c.CloseRead() 50 case *UnixConn: 51 err = c.CloseRead() 52 } 53 if err != nil { 54 if perr := parseCloseError(err); perr != nil { 55 t.Error(perr) 56 } 57 t.Fatal(err) 58 } 59 var b [1]byte 60 n, err := c.Read(b[:]) 61 if n != 0 || err == nil { 62 t.Fatalf("got (%d, %v); want (0, error)", n, err) 63 } 64 } 65 } 66 67 func TestCloseWrite(t *testing.T) { 68 switch runtime.GOOS { 69 case "nacl", "plan9": 70 t.Skipf("not supported on %s", runtime.GOOS) 71 } 72 73 handler := func(ls *localServer, ln Listener) { 74 c, err := ln.Accept() 75 if err != nil { 76 t.Error(err) 77 return 78 } 79 defer c.Close() 80 81 var b [1]byte 82 n, err := c.Read(b[:]) 83 if n != 0 || err != io.EOF { 84 t.Errorf("got (%d, %v); want (0, io.EOF)", n, err) 85 return 86 } 87 switch c := c.(type) { 88 case *TCPConn: 89 err = c.CloseWrite() 90 case *UnixConn: 91 err = c.CloseWrite() 92 } 93 if err != nil { 94 if perr := parseCloseError(err); perr != nil { 95 t.Error(perr) 96 } 97 t.Error(err) 98 return 99 } 100 n, err = c.Write(b[:]) 101 if err == nil { 102 t.Errorf("got (%d, %v); want (any, error)", n, err) 103 return 104 } 105 } 106 107 for _, network := range []string{"tcp", "unix", "unixpacket"} { 108 if !testableNetwork(network) { 109 t.Logf("skipping %s test", network) 110 continue 111 } 112 113 ls, err := newLocalServer(network) 114 if err != nil { 115 t.Fatal(err) 116 } 117 defer ls.teardown() 118 if err := ls.buildup(handler); err != nil { 119 t.Fatal(err) 120 } 121 122 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String()) 123 if err != nil { 124 t.Fatal(err) 125 } 126 switch network { 127 case "unix", "unixpacket": 128 defer os.Remove(c.LocalAddr().String()) 129 } 130 defer c.Close() 131 132 switch c := c.(type) { 133 case *TCPConn: 134 err = c.CloseWrite() 135 case *UnixConn: 136 err = c.CloseWrite() 137 } 138 if err != nil { 139 if perr := parseCloseError(err); perr != nil { 140 t.Error(perr) 141 } 142 t.Fatal(err) 143 } 144 var b [1]byte 145 n, err := c.Read(b[:]) 146 if n != 0 || err != io.EOF { 147 t.Fatalf("got (%d, %v); want (0, io.EOF)", n, err) 148 } 149 n, err = c.Write(b[:]) 150 if err == nil { 151 t.Fatalf("got (%d, %v); want (any, error)", n, err) 152 } 153 } 154 } 155 156 func TestConnClose(t *testing.T) { 157 for _, network := range []string{"tcp", "unix", "unixpacket"} { 158 if !testableNetwork(network) { 159 t.Logf("skipping %s test", network) 160 continue 161 } 162 163 ln, err := newLocalListener(network) 164 if err != nil { 165 t.Fatal(err) 166 } 167 switch network { 168 case "unix", "unixpacket": 169 defer os.Remove(ln.Addr().String()) 170 } 171 defer ln.Close() 172 173 c, err := Dial(ln.Addr().Network(), ln.Addr().String()) 174 if err != nil { 175 t.Fatal(err) 176 } 177 switch network { 178 case "unix", "unixpacket": 179 defer os.Remove(c.LocalAddr().String()) 180 } 181 defer c.Close() 182 183 if err := c.Close(); err != nil { 184 if perr := parseCloseError(err); perr != nil { 185 t.Error(perr) 186 } 187 t.Fatal(err) 188 } 189 var b [1]byte 190 n, err := c.Read(b[:]) 191 if n != 0 || err == nil { 192 t.Fatalf("got (%d, %v); want (0, error)", n, err) 193 } 194 } 195 } 196 197 func TestListenerClose(t *testing.T) { 198 for _, network := range []string{"tcp", "unix", "unixpacket"} { 199 if !testableNetwork(network) { 200 t.Logf("skipping %s test", network) 201 continue 202 } 203 204 ln, err := newLocalListener(network) 205 if err != nil { 206 t.Fatal(err) 207 } 208 switch network { 209 case "unix", "unixpacket": 210 defer os.Remove(ln.Addr().String()) 211 } 212 213 dst := ln.Addr().String() 214 if err := ln.Close(); err != nil { 215 if perr := parseCloseError(err); perr != nil { 216 t.Error(perr) 217 } 218 t.Fatal(err) 219 } 220 c, err := ln.Accept() 221 if err == nil { 222 c.Close() 223 t.Fatal("should fail") 224 } 225 226 if network == "tcp" { 227 // We will have two TCP FSMs inside the 228 // kernel here. There's no guarantee that a 229 // signal comes from the far end FSM will be 230 // delivered immediately to the near end FSM, 231 // especially on the platforms that allow 232 // multiple consumer threads to pull pending 233 // established connections at the same time by 234 // enabling SO_REUSEPORT option such as Linux, 235 // DragonFly BSD. So we need to give some time 236 // quantum to the kernel. 237 // 238 // Note that net.inet.tcp.reuseport_ext=1 by 239 // default on DragonFly BSD. 240 time.Sleep(time.Millisecond) 241 242 cc, err := Dial("tcp", dst) 243 if err == nil { 244 t.Error("Dial to closed TCP listener succeeded.") 245 cc.Close() 246 } 247 } 248 } 249 } 250 251 func TestPacketConnClose(t *testing.T) { 252 for _, network := range []string{"udp", "unixgram"} { 253 if !testableNetwork(network) { 254 t.Logf("skipping %s test", network) 255 continue 256 } 257 258 c, err := newLocalPacketListener(network) 259 if err != nil { 260 t.Fatal(err) 261 } 262 switch network { 263 case "unixgram": 264 defer os.Remove(c.LocalAddr().String()) 265 } 266 defer c.Close() 267 268 if err := c.Close(); err != nil { 269 if perr := parseCloseError(err); perr != nil { 270 t.Error(perr) 271 } 272 t.Fatal(err) 273 } 274 var b [1]byte 275 n, _, err := c.ReadFrom(b[:]) 276 if n != 0 || err == nil { 277 t.Fatalf("got (%d, %v); want (0, error)", n, err) 278 } 279 } 280 } 281 282 // nacl was previous failing to reuse an address. 283 func TestListenCloseListen(t *testing.T) { 284 const maxTries = 10 285 for tries := 0; tries < maxTries; tries++ { 286 ln, err := newLocalListener("tcp") 287 if err != nil { 288 t.Fatal(err) 289 } 290 addr := ln.Addr().String() 291 if err := ln.Close(); err != nil { 292 if perr := parseCloseError(err); perr != nil { 293 t.Error(perr) 294 } 295 t.Fatal(err) 296 } 297 ln, err = Listen("tcp", addr) 298 if err == nil { 299 // Success. nacl couldn't do this before. 300 ln.Close() 301 return 302 } 303 t.Errorf("failed on try %d/%d: %v", tries+1, maxTries, err) 304 } 305 t.Fatalf("failed to listen/close/listen on same address after %d tries", maxTries) 306 }