github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/p2p/net/mock/mock_test.go (about) 1 package mocknet 2 3 import ( 4 "bytes" 5 "io" 6 "math" 7 "math/rand" 8 "sync" 9 "testing" 10 "time" 11 12 inet "github.com/ipfs/go-ipfs/p2p/net" 13 peer "github.com/ipfs/go-ipfs/p2p/peer" 14 protocol "github.com/ipfs/go-ipfs/p2p/protocol" 15 testutil "github.com/ipfs/go-ipfs/util/testutil" 16 17 detectrace "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-detect-race" 18 context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context" 19 ) 20 21 func randPeer(t *testing.T) peer.ID { 22 p, err := testutil.RandPeerID() 23 if err != nil { 24 t.Fatal(err) 25 } 26 return p 27 } 28 29 func TestNetworkSetup(t *testing.T) { 30 31 ctx := context.Background() 32 sk1, _, err := testutil.RandTestKeyPair(512) 33 if err != nil { 34 t.Fatal(t) 35 } 36 sk2, _, err := testutil.RandTestKeyPair(512) 37 if err != nil { 38 t.Fatal(t) 39 } 40 sk3, _, err := testutil.RandTestKeyPair(512) 41 if err != nil { 42 t.Fatal(t) 43 } 44 mn := New(ctx) 45 // peers := []peer.ID{p1, p2, p3} 46 47 // add peers to mock net 48 49 a1 := testutil.RandLocalTCPAddress() 50 a2 := testutil.RandLocalTCPAddress() 51 a3 := testutil.RandLocalTCPAddress() 52 53 h1, err := mn.AddPeer(sk1, a1) 54 if err != nil { 55 t.Fatal(err) 56 } 57 p1 := h1.ID() 58 59 h2, err := mn.AddPeer(sk2, a2) 60 if err != nil { 61 t.Fatal(err) 62 } 63 p2 := h2.ID() 64 65 h3, err := mn.AddPeer(sk3, a3) 66 if err != nil { 67 t.Fatal(err) 68 } 69 p3 := h3.ID() 70 71 // check peers and net 72 if mn.Host(p1) != h1 { 73 t.Error("host for p1.ID != h1") 74 } 75 if mn.Host(p2) != h2 { 76 t.Error("host for p2.ID != h2") 77 } 78 if mn.Host(p3) != h3 { 79 t.Error("host for p3.ID != h3") 80 } 81 82 n1 := h1.Network() 83 if mn.Net(p1) != n1 { 84 t.Error("net for p1.ID != n1") 85 } 86 n2 := h2.Network() 87 if mn.Net(p2) != n2 { 88 t.Error("net for p2.ID != n1") 89 } 90 n3 := h3.Network() 91 if mn.Net(p3) != n3 { 92 t.Error("net for p3.ID != n1") 93 } 94 95 // link p1<-->p2, p1<-->p1, p2<-->p3, p3<-->p2 96 97 l12, err := mn.LinkPeers(p1, p2) 98 if err != nil { 99 t.Fatal(err) 100 } 101 if !(l12.Networks()[0] == n1 && l12.Networks()[1] == n2) && 102 !(l12.Networks()[0] == n2 && l12.Networks()[1] == n1) { 103 t.Error("l12 networks incorrect") 104 } 105 106 l11, err := mn.LinkPeers(p1, p1) 107 if err != nil { 108 t.Fatal(err) 109 } 110 if !(l11.Networks()[0] == n1 && l11.Networks()[1] == n1) { 111 t.Error("l11 networks incorrect") 112 } 113 114 l23, err := mn.LinkPeers(p2, p3) 115 if err != nil { 116 t.Fatal(err) 117 } 118 if !(l23.Networks()[0] == n2 && l23.Networks()[1] == n3) && 119 !(l23.Networks()[0] == n3 && l23.Networks()[1] == n2) { 120 t.Error("l23 networks incorrect") 121 } 122 123 l32, err := mn.LinkPeers(p3, p2) 124 if err != nil { 125 t.Fatal(err) 126 } 127 if !(l32.Networks()[0] == n2 && l32.Networks()[1] == n3) && 128 !(l32.Networks()[0] == n3 && l32.Networks()[1] == n2) { 129 t.Error("l32 networks incorrect") 130 } 131 132 // check things 133 134 links12 := mn.LinksBetweenPeers(p1, p2) 135 if len(links12) != 1 { 136 t.Errorf("should be 1 link bt. p1 and p2 (found %d)", len(links12)) 137 } 138 if links12[0] != l12 { 139 t.Error("links 1-2 should be l12.") 140 } 141 142 links11 := mn.LinksBetweenPeers(p1, p1) 143 if len(links11) != 1 { 144 t.Errorf("should be 1 link bt. p1 and p1 (found %d)", len(links11)) 145 } 146 if links11[0] != l11 { 147 t.Error("links 1-1 should be l11.") 148 } 149 150 links23 := mn.LinksBetweenPeers(p2, p3) 151 if len(links23) != 2 { 152 t.Errorf("should be 2 link bt. p2 and p3 (found %d)", len(links23)) 153 } 154 if !((links23[0] == l23 && links23[1] == l32) || 155 (links23[0] == l32 && links23[1] == l23)) { 156 t.Error("links 2-3 should be l23 and l32.") 157 } 158 159 // unlinking 160 161 if err := mn.UnlinkPeers(p2, p1); err != nil { 162 t.Error(err) 163 } 164 165 // check only one link affected: 166 167 links12 = mn.LinksBetweenPeers(p1, p2) 168 if len(links12) != 0 { 169 t.Errorf("should be 0 now...", len(links12)) 170 } 171 172 links11 = mn.LinksBetweenPeers(p1, p1) 173 if len(links11) != 1 { 174 t.Errorf("should be 1 link bt. p1 and p1 (found %d)", len(links11)) 175 } 176 if links11[0] != l11 { 177 t.Error("links 1-1 should be l11.") 178 } 179 180 links23 = mn.LinksBetweenPeers(p2, p3) 181 if len(links23) != 2 { 182 t.Errorf("should be 2 link bt. p2 and p3 (found %d)", len(links23)) 183 } 184 if !((links23[0] == l23 && links23[1] == l32) || 185 (links23[0] == l32 && links23[1] == l23)) { 186 t.Error("links 2-3 should be l23 and l32.") 187 } 188 189 // check connecting 190 191 // first, no conns 192 if len(n2.Conns()) > 0 || len(n3.Conns()) > 0 { 193 t.Error("should have 0 conn. Got: (%d, %d)", len(n2.Conns()), len(n3.Conns())) 194 } 195 196 // connect p2->p3 197 if _, err := n2.DialPeer(ctx, p3); err != nil { 198 t.Error(err) 199 } 200 201 if len(n2.Conns()) != 1 || len(n3.Conns()) != 1 { 202 t.Errorf("should have (1,1) conn. Got: (%d, %d)", len(n2.Conns()), len(n3.Conns())) 203 } 204 205 // p := PrinterTo(os.Stdout) 206 // p.NetworkConns(n1) 207 // p.NetworkConns(n2) 208 // p.NetworkConns(n3) 209 210 // can create a stream 2->3, 3->2, 211 if _, err := n2.NewStream(p3); err != nil { 212 t.Error(err) 213 } 214 if _, err := n3.NewStream(p2); err != nil { 215 t.Error(err) 216 } 217 218 // but not 1->2 nor 2->2 (not linked), nor 1->1 (not connected) 219 if _, err := n1.NewStream(p2); err == nil { 220 t.Error("should not be able to connect") 221 } 222 if _, err := n2.NewStream(p2); err == nil { 223 t.Error("should not be able to connect") 224 } 225 if _, err := n1.NewStream(p1); err == nil { 226 t.Error("should not be able to connect") 227 } 228 229 // connect p1->p1 (should work) 230 if _, err := n1.DialPeer(ctx, p1); err != nil { 231 t.Error("p1 should be able to dial self.", err) 232 } 233 234 // and a stream too 235 if _, err := n1.NewStream(p1); err != nil { 236 t.Error(err) 237 } 238 239 // connect p1->p2 240 if _, err := n1.DialPeer(ctx, p2); err == nil { 241 t.Error("p1 should not be able to dial p2, not connected...") 242 } 243 244 // connect p3->p1 245 if _, err := n3.DialPeer(ctx, p1); err == nil { 246 t.Error("p3 should not be able to dial p1, not connected...") 247 } 248 249 // relink p1->p2 250 251 l12, err = mn.LinkPeers(p1, p2) 252 if err != nil { 253 t.Fatal(err) 254 } 255 if !(l12.Networks()[0] == n1 && l12.Networks()[1] == n2) && 256 !(l12.Networks()[0] == n2 && l12.Networks()[1] == n1) { 257 t.Error("l12 networks incorrect") 258 } 259 260 // should now be able to connect 261 262 // connect p1->p2 263 if _, err := n1.DialPeer(ctx, p2); err != nil { 264 t.Error(err) 265 } 266 267 // and a stream should work now too :) 268 if _, err := n2.NewStream(p3); err != nil { 269 t.Error(err) 270 } 271 272 } 273 274 func TestStreams(t *testing.T) { 275 276 mn, err := FullMeshConnected(context.Background(), 3) 277 if err != nil { 278 t.Fatal(err) 279 } 280 281 handler := func(s inet.Stream) { 282 b := make([]byte, 4) 283 if _, err := io.ReadFull(s, b); err != nil { 284 panic(err) 285 } 286 if !bytes.Equal(b, []byte("beep")) { 287 panic("bytes mismatch") 288 } 289 if _, err := s.Write([]byte("boop")); err != nil { 290 panic(err) 291 } 292 s.Close() 293 } 294 295 hosts := mn.Hosts() 296 for _, h := range mn.Hosts() { 297 h.SetStreamHandler(protocol.TestingID, handler) 298 } 299 300 s, err := hosts[0].NewStream(protocol.TestingID, hosts[1].ID()) 301 if err != nil { 302 t.Fatal(err) 303 } 304 305 if _, err := s.Write([]byte("beep")); err != nil { 306 panic(err) 307 } 308 b := make([]byte, 4) 309 if _, err := io.ReadFull(s, b); err != nil { 310 panic(err) 311 } 312 if !bytes.Equal(b, []byte("boop")) { 313 panic("bytes mismatch 2") 314 } 315 316 } 317 318 func makePinger(st string, n int) func(inet.Stream) { 319 return func(s inet.Stream) { 320 go func() { 321 defer s.Close() 322 323 for i := 0; i < n; i++ { 324 b := make([]byte, 4+len(st)) 325 if _, err := s.Write([]byte("ping" + st)); err != nil { 326 panic(err) 327 } 328 if _, err := io.ReadFull(s, b); err != nil { 329 panic(err) 330 } 331 if !bytes.Equal(b, []byte("pong"+st)) { 332 panic("bytes mismatch") 333 } 334 } 335 }() 336 } 337 } 338 339 func makePonger(st string) func(inet.Stream) { 340 return func(s inet.Stream) { 341 go func() { 342 defer s.Close() 343 344 for { 345 b := make([]byte, 4+len(st)) 346 if _, err := io.ReadFull(s, b); err != nil { 347 if err == io.EOF { 348 return 349 } 350 panic(err) 351 } 352 if !bytes.Equal(b, []byte("ping"+st)) { 353 panic("bytes mismatch") 354 } 355 if _, err := s.Write([]byte("pong" + st)); err != nil { 356 panic(err) 357 } 358 } 359 }() 360 } 361 } 362 363 func TestStreamsStress(t *testing.T) { 364 nnodes := 100 365 if detectrace.WithRace() { 366 nnodes = 50 367 } 368 369 mn, err := FullMeshConnected(context.Background(), nnodes) 370 if err != nil { 371 t.Fatal(err) 372 } 373 374 hosts := mn.Hosts() 375 for _, h := range hosts { 376 ponger := makePonger(string(protocol.TestingID)) 377 h.SetStreamHandler(protocol.TestingID, ponger) 378 } 379 380 var wg sync.WaitGroup 381 for i := 0; i < 1000; i++ { 382 wg.Add(1) 383 go func(i int) { 384 defer wg.Done() 385 from := rand.Intn(len(hosts)) 386 to := rand.Intn(len(hosts)) 387 s, err := hosts[from].NewStream(protocol.TestingID, hosts[to].ID()) 388 if err != nil { 389 log.Debugf("%d (%s) %d (%s)", from, hosts[from], to, hosts[to]) 390 panic(err) 391 } 392 393 log.Infof("%d start pinging", i) 394 makePinger("pingpong", rand.Intn(100))(s) 395 log.Infof("%d done pinging", i) 396 }(i) 397 } 398 399 wg.Wait() 400 } 401 402 func TestAdding(t *testing.T) { 403 404 mn := New(context.Background()) 405 406 peers := []peer.ID{} 407 for i := 0; i < 3; i++ { 408 sk, _, err := testutil.RandTestKeyPair(512) 409 if err != nil { 410 t.Fatal(err) 411 } 412 413 a := testutil.RandLocalTCPAddress() 414 h, err := mn.AddPeer(sk, a) 415 if err != nil { 416 t.Fatal(err) 417 } 418 419 peers = append(peers, h.ID()) 420 } 421 422 p1 := peers[0] 423 p2 := peers[1] 424 425 // link them 426 for _, p1 := range peers { 427 for _, p2 := range peers { 428 if _, err := mn.LinkPeers(p1, p2); err != nil { 429 t.Error(err) 430 } 431 } 432 } 433 434 // set the new stream handler on p2 435 h2 := mn.Host(p2) 436 if h2 == nil { 437 t.Fatalf("no host for %s", p2) 438 } 439 h2.SetStreamHandler(protocol.TestingID, func(s inet.Stream) { 440 defer s.Close() 441 442 b := make([]byte, 4) 443 if _, err := io.ReadFull(s, b); err != nil { 444 panic(err) 445 } 446 if string(b) != "beep" { 447 panic("did not beep!") 448 } 449 450 if _, err := s.Write([]byte("boop")); err != nil { 451 panic(err) 452 } 453 }) 454 455 // connect p1 to p2 456 if _, err := mn.ConnectPeers(p1, p2); err != nil { 457 t.Fatal(err) 458 } 459 460 // talk to p2 461 h1 := mn.Host(p1) 462 if h1 == nil { 463 t.Fatalf("no network for %s", p1) 464 } 465 466 s, err := h1.NewStream(protocol.TestingID, p2) 467 if err != nil { 468 t.Fatal(err) 469 } 470 471 if _, err := s.Write([]byte("beep")); err != nil { 472 t.Error(err) 473 } 474 b := make([]byte, 4) 475 if _, err := io.ReadFull(s, b); err != nil { 476 t.Error(err) 477 } 478 if !bytes.Equal(b, []byte("boop")) { 479 t.Error("bytes mismatch 2") 480 } 481 482 } 483 484 func TestRateLimiting(t *testing.T) { 485 rl := NewRatelimiter(10) 486 487 if !within(rl.Limit(10), time.Duration(float32(time.Second)), time.Millisecond/10) { 488 t.Fail() 489 } 490 if !within(rl.Limit(10), time.Duration(float32(time.Second*2)), time.Millisecond) { 491 t.Fail() 492 } 493 if !within(rl.Limit(10), time.Duration(float32(time.Second*3)), time.Millisecond) { 494 t.Fail() 495 } 496 497 if within(rl.Limit(10), time.Duration(float32(time.Second*3)), time.Millisecond) { 498 t.Fail() 499 } 500 501 rl.UpdateBandwidth(50) 502 if !within(rl.Limit(75), time.Duration(float32(time.Second)*1.5), time.Millisecond/10) { 503 t.Fail() 504 } 505 506 if within(rl.Limit(75), time.Duration(float32(time.Second)*1.5), time.Millisecond/10) { 507 t.Fail() 508 } 509 510 rl.UpdateBandwidth(100) 511 if !within(rl.Limit(1), time.Duration(time.Millisecond*10), time.Millisecond/10) { 512 t.Fail() 513 } 514 515 if within(rl.Limit(1), time.Duration(time.Millisecond*10), time.Millisecond/10) { 516 t.Fail() 517 } 518 } 519 520 func within(t1 time.Duration, t2 time.Duration, tolerance time.Duration) bool { 521 return math.Abs(float64(t1)-float64(t2)) < float64(tolerance) 522 } 523 524 func TestLimitedStreams(t *testing.T) { 525 mn, err := FullMeshConnected(context.Background(), 2) 526 if err != nil { 527 t.Fatal(err) 528 } 529 530 var wg sync.WaitGroup 531 messages := 4 532 messageSize := 500 533 handler := func(s inet.Stream) { 534 b := make([]byte, messageSize) 535 for i := 0; i < messages; i++ { 536 if _, err := io.ReadFull(s, b); err != nil { 537 log.Fatal(err) 538 } 539 if !bytes.Equal(b[:4], []byte("ping")) { 540 log.Fatal("bytes mismatch") 541 } 542 wg.Done() 543 } 544 s.Close() 545 } 546 547 hosts := mn.Hosts() 548 for _, h := range mn.Hosts() { 549 h.SetStreamHandler(protocol.TestingID, handler) 550 } 551 552 peers := mn.Peers() 553 links := mn.LinksBetweenPeers(peers[0], peers[1]) 554 // 1000 byte per second bandwidth 555 bps := float64(1000) 556 opts := links[0].Options() 557 opts.Bandwidth = bps 558 for _, link := range links { 559 link.SetOptions(opts) 560 } 561 562 s, err := hosts[0].NewStream(protocol.TestingID, hosts[1].ID()) 563 if err != nil { 564 t.Fatal(err) 565 } 566 567 filler := make([]byte, messageSize-4) 568 data := append([]byte("ping"), filler...) 569 before := time.Now() 570 for i := 0; i < messages; i++ { 571 wg.Add(1) 572 if _, err := s.Write(data); err != nil { 573 panic(err) 574 } 575 } 576 577 wg.Wait() 578 if !within(time.Since(before), time.Duration(time.Second*2), time.Second/3) { 579 t.Fatal("Expected 2ish seconds but got ", time.Since(before)) 580 } 581 }