github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/p2p/net/swarm/dial_test.go (about) 1 package swarm 2 3 import ( 4 "net" 5 "sync" 6 "testing" 7 "time" 8 9 addrutil "github.com/ipfs/go-ipfs/p2p/net/swarm/addr" 10 peer "github.com/ipfs/go-ipfs/p2p/peer" 11 12 testutil "github.com/ipfs/go-ipfs/util/testutil" 13 ci "github.com/ipfs/go-ipfs/util/testutil/ci" 14 15 ma "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr" 16 manet "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net" 17 context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context" 18 ) 19 20 func acceptAndHang(l net.Listener) { 21 conns := make([]net.Conn, 0, 10) 22 for { 23 c, err := l.Accept() 24 if err != nil { 25 break 26 } 27 if c != nil { 28 conns = append(conns, c) 29 } 30 } 31 for _, c := range conns { 32 c.Close() 33 } 34 } 35 36 func TestSimultDials(t *testing.T) { 37 // t.Skip("skipping for another test") 38 t.Parallel() 39 40 ctx := context.Background() 41 swarms := makeSwarms(ctx, t, 2) 42 43 // connect everyone 44 { 45 var wg sync.WaitGroup 46 connect := func(s *Swarm, dst peer.ID, addr ma.Multiaddr) { 47 // copy for other peer 48 log.Debugf("TestSimultOpen: connecting: %s --> %s (%s)", s.local, dst, addr) 49 s.peers.AddAddr(dst, addr, peer.TempAddrTTL) 50 if _, err := s.Dial(ctx, dst); err != nil { 51 t.Fatal("error swarm dialing to peer", err) 52 } 53 wg.Done() 54 } 55 56 ifaceAddrs0, err := swarms[0].InterfaceListenAddresses() 57 if err != nil { 58 t.Fatal(err) 59 } 60 ifaceAddrs1, err := swarms[1].InterfaceListenAddresses() 61 if err != nil { 62 t.Fatal(err) 63 } 64 65 log.Info("Connecting swarms simultaneously.") 66 for i := 0; i < 10; i++ { // connect 10x for each. 67 wg.Add(2) 68 go connect(swarms[0], swarms[1].local, ifaceAddrs1[0]) 69 go connect(swarms[1], swarms[0].local, ifaceAddrs0[0]) 70 } 71 wg.Wait() 72 } 73 74 // should still just have 1, at most 2 connections :) 75 c01l := len(swarms[0].ConnectionsToPeer(swarms[1].local)) 76 if c01l > 2 { 77 t.Error("0->1 has", c01l) 78 } 79 c10l := len(swarms[1].ConnectionsToPeer(swarms[0].local)) 80 if c10l > 2 { 81 t.Error("1->0 has", c10l) 82 } 83 84 for _, s := range swarms { 85 s.Close() 86 } 87 } 88 89 func newSilentPeer(t *testing.T) (peer.ID, ma.Multiaddr, net.Listener) { 90 dst := testutil.RandPeerIDFatal(t) 91 lst, err := net.Listen("tcp", ":0") 92 if err != nil { 93 t.Fatal(err) 94 } 95 addr, err := manet.FromNetAddr(lst.Addr()) 96 if err != nil { 97 t.Fatal(err) 98 } 99 addrs := []ma.Multiaddr{addr} 100 addrs, err = addrutil.ResolveUnspecifiedAddresses(addrs, nil) 101 if err != nil { 102 t.Fatal(err) 103 } 104 t.Log("new silent peer:", dst, addrs[0]) 105 return dst, addrs[0], lst 106 } 107 108 func TestDialWait(t *testing.T) { 109 // t.Skip("skipping for another test") 110 t.Parallel() 111 112 ctx := context.Background() 113 swarms := makeSwarms(ctx, t, 1) 114 s1 := swarms[0] 115 defer s1.Close() 116 117 s1.dialT = time.Millisecond * 300 // lower timeout for tests. 118 if ci.IsRunning() { 119 s1.dialT = time.Second 120 } 121 122 // dial to a non-existent peer. 123 s2p, s2addr, s2l := newSilentPeer(t) 124 go acceptAndHang(s2l) 125 defer s2l.Close() 126 s1.peers.AddAddr(s2p, s2addr, peer.PermanentAddrTTL) 127 128 before := time.Now() 129 if c, err := s1.Dial(ctx, s2p); err == nil { 130 defer c.Close() 131 t.Fatal("error swarm dialing to unknown peer worked...", err) 132 } else { 133 t.Log("correctly got error:", err) 134 } 135 duration := time.Now().Sub(before) 136 137 dt := s1.dialT 138 if duration < dt*dialAttempts { 139 t.Error("< DialTimeout * dialAttempts not being respected", duration, dt*dialAttempts) 140 } 141 if duration > 2*dt*dialAttempts { 142 t.Error("> 2*DialTimeout * dialAttempts not being respected", duration, 2*dt*dialAttempts) 143 } 144 145 if !s1.backf.Backoff(s2p) { 146 t.Error("s2 should now be on backoff") 147 } 148 } 149 150 func TestDialBackoff(t *testing.T) { 151 // t.Skip("skipping for another test") 152 if ci.IsRunning() { 153 t.Skip("travis and jenkins will never have fun with this test") 154 } 155 156 t.Parallel() 157 158 ctx := context.Background() 159 swarms := makeSwarms(ctx, t, 2) 160 s1 := swarms[0] 161 s2 := swarms[1] 162 defer s1.Close() 163 defer s2.Close() 164 165 s1.dialT = time.Second // lower timeout for tests. 166 s2.dialT = time.Second // lower timeout for tests. 167 168 s2addrs, err := s2.InterfaceListenAddresses() 169 if err != nil { 170 t.Fatal(err) 171 } 172 s1.peers.AddAddrs(s2.local, s2addrs, peer.PermanentAddrTTL) 173 174 // dial to a non-existent peer. 175 s3p, s3addr, s3l := newSilentPeer(t) 176 go acceptAndHang(s3l) 177 defer s3l.Close() 178 s1.peers.AddAddr(s3p, s3addr, peer.PermanentAddrTTL) 179 180 // in this test we will: 181 // 1) dial 10x to each node. 182 // 2) all dials should hang 183 // 3) s1->s2 should succeed. 184 // 4) s1->s3 should not (and should place s3 on backoff) 185 // 5) disconnect entirely 186 // 6) dial 10x to each node again 187 // 7) s3 dials should all return immediately (except 1) 188 // 8) s2 dials should all hang, and succeed 189 // 9) last s3 dial ends, unsuccessful 190 191 dialOnlineNode := func(dst peer.ID, times int) <-chan bool { 192 ch := make(chan bool) 193 for i := 0; i < times; i++ { 194 go func() { 195 if _, err := s1.Dial(ctx, dst); err != nil { 196 t.Error("error dialing", dst, err) 197 ch <- false 198 } else { 199 ch <- true 200 } 201 }() 202 } 203 return ch 204 } 205 206 dialOfflineNode := func(dst peer.ID, times int) <-chan bool { 207 ch := make(chan bool) 208 for i := 0; i < times; i++ { 209 go func() { 210 if c, err := s1.Dial(ctx, dst); err != nil { 211 ch <- false 212 } else { 213 t.Error("succeeded in dialing", dst) 214 ch <- true 215 c.Close() 216 } 217 }() 218 } 219 return ch 220 } 221 222 { 223 // 1) dial 10x to each node. 224 N := 10 225 s2done := dialOnlineNode(s2.local, N) 226 s3done := dialOfflineNode(s3p, N) 227 228 // when all dials should be done by: 229 dialTimeout1x := time.After(s1.dialT) 230 // dialTimeout1Ax := time.After(s1.dialT * 2) // dialAttempts) 231 dialTimeout10Ax := time.After(s1.dialT * 2 * 10) // dialAttempts * 10) 232 233 // 2) all dials should hang 234 select { 235 case <-s2done: 236 t.Error("s2 should not happen immediately") 237 case <-s3done: 238 t.Error("s3 should not happen yet") 239 case <-time.After(time.Millisecond): 240 // s2 may finish very quickly, so let's get out. 241 } 242 243 // 3) s1->s2 should succeed. 244 for i := 0; i < N; i++ { 245 select { 246 case r := <-s2done: 247 if !r { 248 t.Error("s2 should not fail") 249 } 250 case <-s3done: 251 t.Error("s3 should not happen yet") 252 case <-dialTimeout1x: 253 t.Error("s2 took too long") 254 } 255 } 256 257 select { 258 case <-s2done: 259 t.Error("s2 should have no more") 260 case <-s3done: 261 t.Error("s3 should not happen yet") 262 case <-dialTimeout1x: // let it pass 263 } 264 265 // 4) s1->s3 should not (and should place s3 on backoff) 266 // N-1 should finish before dialTimeout1x * 2 267 for i := 0; i < N; i++ { 268 select { 269 case <-s2done: 270 t.Error("s2 should have no more") 271 case r := <-s3done: 272 if r { 273 t.Error("s3 should not succeed") 274 } 275 case <-(dialTimeout1x): 276 if i < (N - 1) { 277 t.Fatal("s3 took too long") 278 } 279 t.Log("dialTimeout1x * 1.3 hit for last peer") 280 case <-dialTimeout10Ax: 281 t.Fatal("s3 took too long") 282 } 283 } 284 285 // check backoff state 286 if s1.backf.Backoff(s2.local) { 287 t.Error("s2 should not be on backoff") 288 } 289 if !s1.backf.Backoff(s3p) { 290 t.Error("s3 should be on backoff") 291 } 292 293 // 5) disconnect entirely 294 295 for _, c := range s1.Connections() { 296 c.Close() 297 } 298 for i := 0; i < 100 && len(s1.Connections()) > 0; i++ { 299 <-time.After(time.Millisecond) 300 } 301 if len(s1.Connections()) > 0 { 302 t.Fatal("s1 conns must exit") 303 } 304 } 305 306 { 307 // 6) dial 10x to each node again 308 N := 10 309 s2done := dialOnlineNode(s2.local, N) 310 s3done := dialOfflineNode(s3p, N) 311 312 // when all dials should be done by: 313 dialTimeout1x := time.After(s1.dialT) 314 // dialTimeout1Ax := time.After(s1.dialT * 2) // dialAttempts) 315 dialTimeout10Ax := time.After(s1.dialT * 2 * 10) // dialAttempts * 10) 316 317 // 7) s3 dials should all return immediately (except 1) 318 for i := 0; i < N-1; i++ { 319 select { 320 case <-s2done: 321 t.Error("s2 should not succeed yet") 322 case r := <-s3done: 323 if r { 324 t.Error("s3 should not succeed") 325 } 326 case <-dialTimeout1x: 327 t.Fatal("s3 took too long") 328 } 329 } 330 331 // 8) s2 dials should all hang, and succeed 332 for i := 0; i < N; i++ { 333 select { 334 case r := <-s2done: 335 if !r { 336 t.Error("s2 should succeed") 337 } 338 // case <-s3done: 339 case <-(dialTimeout1x): 340 t.Fatal("s3 took too long") 341 } 342 } 343 344 // 9) the last s3 should return, failed. 345 select { 346 case <-s2done: 347 t.Error("s2 should have no more") 348 case r := <-s3done: 349 if r { 350 t.Error("s3 should not succeed") 351 } 352 case <-dialTimeout10Ax: 353 t.Fatal("s3 took too long") 354 } 355 356 // check backoff state (the same) 357 if s1.backf.Backoff(s2.local) { 358 t.Error("s2 should not be on backoff") 359 } 360 if !s1.backf.Backoff(s3p) { 361 t.Error("s3 should be on backoff") 362 } 363 364 } 365 } 366 367 func TestDialBackoffClears(t *testing.T) { 368 // t.Skip("skipping for another test") 369 t.Parallel() 370 371 ctx := context.Background() 372 swarms := makeSwarms(ctx, t, 2) 373 s1 := swarms[0] 374 s2 := swarms[1] 375 defer s1.Close() 376 defer s2.Close() 377 s1.dialT = time.Millisecond * 300 // lower timeout for tests. 378 s2.dialT = time.Millisecond * 300 // lower timeout for tests. 379 if ci.IsRunning() { 380 s1.dialT = 2 * time.Second 381 s2.dialT = 2 * time.Second 382 } 383 384 // use another address first, that accept and hang on conns 385 _, s2bad, s2l := newSilentPeer(t) 386 go acceptAndHang(s2l) 387 defer s2l.Close() 388 389 // phase 1 -- dial to non-operational addresses 390 s1.peers.AddAddr(s2.local, s2bad, peer.PermanentAddrTTL) 391 392 before := time.Now() 393 if c, err := s1.Dial(ctx, s2.local); err == nil { 394 t.Fatal("dialing to broken addr worked...", err) 395 defer c.Close() 396 } else { 397 t.Log("correctly got error:", err) 398 } 399 duration := time.Now().Sub(before) 400 401 dt := s1.dialT 402 if duration < dt*dialAttempts { 403 t.Error("< DialTimeout * dialAttempts not being respected", duration, dt*dialAttempts) 404 } 405 if duration > 2*dt*dialAttempts { 406 t.Error("> 2*DialTimeout * dialAttempts not being respected", duration, 2*dt*dialAttempts) 407 } 408 409 if !s1.backf.Backoff(s2.local) { 410 t.Error("s2 should now be on backoff") 411 } else { 412 t.Log("correctly added to backoff") 413 } 414 415 // phase 2 -- add the working address. dial should succeed. 416 ifaceAddrs1, err := swarms[1].InterfaceListenAddresses() 417 if err != nil { 418 t.Fatal(err) 419 } 420 s1.peers.AddAddrs(s2.local, ifaceAddrs1, peer.PermanentAddrTTL) 421 422 before = time.Now() 423 if c, err := s1.Dial(ctx, s2.local); err != nil { 424 t.Fatal(err) 425 } else { 426 c.Close() 427 t.Log("correctly connected") 428 } 429 duration = time.Now().Sub(before) 430 431 if duration >= dt { 432 // t.Error("took too long", duration, dt) 433 } 434 435 if s1.backf.Backoff(s2.local) { 436 t.Error("s2 should no longer be on backoff") 437 } else { 438 t.Log("correctly cleared backoff") 439 } 440 }