func TestNumGoroutine(t *testing.T) { baseNum := numGoroutine() var num int sw := mock.ProtoNetSwarm{} p := &mock.Peer{ID: "peer0"} c := New(p, 20, 10, sw.DialListener(p)) c.Start(time.Second) c.Stop() ticker := time.NewTicker(10 * time.Millisecond) defer ticker.Stop() timeout := time.After(time.Second) for { select { case <-ticker.C: num = numGoroutine() if num == baseNum { return } case <-timeout: t.Fatalf("%d goroutines are leaking", num-baseNum) } } }
func TestNeighbourDiscard(t *testing.T) { sw := mock.ProtoNetSwarm{} numNodes := 4 b, ch := make([]*Broadcast, numNodes), make([]chan pnet.Peer, numNodes) for i, _ := range b { name := fmt.Sprintf("p%d", i) b[i] = New(1, time.Minute, sw.DialListener(name)) b[i].Str = name ch[i] = make(chan pnet.Peer) b[i].Start(ch[i], 2) defer b[i].Stop() } ch[0] <- &mock.Peer{"p2", map[string]interface{}{bday: 2}} // keep ch[0] <- &mock.Peer{"p1", map[string]interface{}{bday: 0}} // discard ch[0] <- &mock.Peer{"p3", map[string]interface{}{bday: 1}} // keep b[0].In() <- "hello world" testReceive(t, map[*Broadcast]int{b[0]: 0, b[1]: 0, b[2]: 1, b[3]: 1}, timeToWait, ) }
func TestDelayedResponse(t *testing.T) { sw := mock.ProtoNetSwarm{} // ponger pn := sw.DialListener("peer0") ln := pn.Listen() defer ln.Close() // pinger ping := &Ping{ProtoNet: sw.DialListener("peer1")} done := make(chan error) go func() { done <- ping.Ping(&mock.Peer{ID: "peer0"}, nil) }() // accept and respond after a delay c, err := ln.Accept() if err != nil { t.Fatal(err) } defer c.Close() time.Sleep(100 * time.Millisecond) c.Write([]byte(msg)) err = <-done if err != nil { t.Fatalf("expected no error, got '%v'", err) } }
func TestMsgForward(t *testing.T) { sw := mock.ProtoNetSwarm{} numNodes := 4 b, ch := make([]*Broadcast, numNodes), make([]chan pnet.Peer, numNodes) for i, _ := range b { name := fmt.Sprintf("p%d", i) b[i] = New(1, time.Minute, sw.DialListener(name)) b[i].Str = name ch[i] = make(chan pnet.Peer) b[i].Start(ch[i], 2) defer b[i].Stop() } ch[0] <- &mock.Peer{ID: "p1"} ch[1] <- &mock.Peer{ID: "p2"} ch[2] <- &mock.Peer{ID: "p0"} ch[3] <- &mock.Peer{ID: "p2"} b[0].In() <- "hello world" testReceive(t, map[*Broadcast]int{b[0]: 0, b[1]: 1, b[2]: 1, b[3]: 1}, timeToWait, ) }
func TestTimeout(t *testing.T) { sw := mock.ProtoNetSwarm{} // ponger pn := sw.DialListener("peer0") ln := pn.Listen() defer ln.Close() // pinger ping := &Ping{ProtoNet: sw.DialListener("peer1")} done := make(chan error) stop := make(chan bool) go func() { done <- ping.Ping(&mock.Peer{ID: "peer0"}, stop) }() // accept, but don't respond c, err := ln.Accept() if err != nil { t.Fatal(err) } defer c.Close() close(stop) err = <-done if err == nil { t.Fatal("expected an error, got nil") } }
func TestFail(t *testing.T) { sw := mock.ProtoNetSwarm{} ping0 := &Ping{ProtoNet: sw.DialListener("peer0")} err := ping0.Ping(&mock.Peer{ID: "peer1"}, nil) if err == nil { t.Fatal("expected an error, got nil") } }
func TestNoAnswer(t *testing.T) { sw := mock.ProtoNetSwarm{} p := &mock.Peer{ID: "peer0"} c := New(p, 20, 10, sw.DialListener(p)) gob.Register(&mock.Peer{}) c.Add(&mock.Peer{ID: "peer1"}) c.Shuffle() if len(c.neighbs) > 0 { t.Fatalf("expected no neighbours, got %v", c.neighbs) } }
func TestSucceed(t *testing.T) { sw := mock.ProtoNetSwarm{} ping0 := &Ping{ProtoNet: sw.DialListener("peer0")} // pinger ping1 := &Ping{ProtoNet: sw.DialListener("peer1")} // ponger ping1.Serve() defer ping1.Stop() err := ping0.Ping(&mock.Peer{ID: "peer1"}, nil) if err != nil { t.Fatalf("expected no error, got '%v'", err) } }
func TestConservation(t *testing.T) { sw := mock.ProtoNetSwarm{} p0 := &mock.Peer{ID: "p0"} p1 := &mock.Peer{ID: "p1"} c0 := New(p0, 5, 3, sw.DialListener(p0.Id())) c1 := New(p1, 5, 3, sw.DialListener(p1.Id())) c0.neighbs = PeerSet{ "p2": &mock.Peer{"p2", map[string]interface{}{age: 2}}, "p3": &mock.Peer{"p3", map[string]interface{}{age: 2}}, "p4": &mock.Peer{"p4", map[string]interface{}{age: 2}}, "p5": &mock.Peer{"p5", map[string]interface{}{age: 2}}, "p6": &mock.Peer{"p6", map[string]interface{}{age: 2}}, } c1.neighbs = PeerSet{ "p0": &mock.Peer{"p0", map[string]interface{}{age: 3}}, "p7": &mock.Peer{"p7", map[string]interface{}{age: 2}}, "p8": &mock.Peer{"p8", map[string]interface{}{age: 2}}, "p9": &mock.Peer{"p9", map[string]interface{}{age: 2}}, "p10": &mock.Peer{"p10", map[string]interface{}{age: 2}}, } c0.Start(0) defer c0.Stop() c1.Shuffle() // We expect p0 to be selected for shuffling, thus removed from the pool. // p1 should be added to p0's cache, because p1 is initiating the shuffle. // All other peer profiles should be conserved. expected := []interface{}{"p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10"} got := make([]interface{}, 0, 10) for p, _ := range c0.neighbs { got = append(got, p) } for p, _ := range c1.neighbs { got = append(got, p) } if !equalSets(expected, got) { t.Fatalf("expected %v, got %v", expected, got) } }
func TestMsg(t *testing.T) { sw := mock.ProtoNetSwarm{} b0 := New(2, time.Minute, sw.DialListener("p0")) b1 := New(2, time.Minute, sw.DialListener("p1")) ps0, ps1 := make(chan pnet.Peer), make(chan pnet.Peer) b0.Start(ps0, 0) b1.Start(ps1, 0) ps0 <- &mock.Peer{ID: "p1"} b0.In() <- "hello world" select { case msg := <-b1.Out(): if msg != "hello world" { t.Fatalf("expected \"hello world\", got %s", msg) } case <-time.After(timeToWait): t.Fatal("timeout") } }
func TestReverseEdge(t *testing.T) { sw := mock.ProtoNetSwarm{} p0 := &mock.Peer{ID: "peer0"} p1 := &mock.Peer{ID: "peer1"} c0 := New(p0, 20, 10, sw.DialListener(p0.Id())) c1 := New(p1, 20, 10, sw.DialListener(p1.Id())) c0.Add(p1) c1.Start(0) defer c1.Stop() c0.Shuffle() select { case p := <-c1.Out(): if p.Id() != p0.Id() { t.Fatalf("expected %v, got %v", p0, p) } case <-time.After(time.Second): t.Fatal("timed out") } }
func TestAgeSelect(t *testing.T) { sw := mock.ProtoNetSwarm{} p := &mock.Peer{ID: "peer0"} c := New(p, 20, 10, sw.DialListener(p)) c.neighbs = PeerSet{ "peer1": &mock.Peer{"peer1", map[string]interface{}{age: 2}}, "peer2": &mock.Peer{"peer2", map[string]interface{}{age: 4}}, "peer3": &mock.Peer{"peer3", map[string]interface{}{age: 3}}, } c.Shuffle() expected := []interface{}{"peer1", "peer3"} got := make([]interface{}, 0, 3) for p, _ := range c.neighbs { got = append(got, p) } if !equalSets(expected, got) { t.Fatalf("expected %v, got %v", expected, got) } }
func TestBday(t *testing.T) { sw := mock.ProtoNetSwarm{} c0 := New(&mock.Peer{ID: "p0"}, 3, 2, sw.DialListener("p0")) c1 := New(&mock.Peer{ID: "p1"}, 3, 2, sw.DialListener("p1")) c0.Start(0) defer c0.Stop() c1.Start(0) defer c1.Stop() c0.neighbs = PeerSet{ "p1": &mock.Peer{"p1", map[string]interface{}{age: 10}}, "p2": &mock.Peer{"p2", map[string]interface{}{age: 0}}, } c1.neighbs = PeerSet{ "p0": &mock.Peer{"p0", map[string]interface{}{age: 10}}, } c0.Shuffle() c1.Shuffle() c0.neighbs = PeerSet{ "p1": &mock.Peer{"p1", map[string]interface{}{age: 10}}, "p3": &mock.Peer{"p3", map[string]interface{}{age: 0}}, } c0.Shuffle() set := make(map[interface{}]int64) for i := 0; i < 3; i++ { p := <-c1.Out() set[p.Id()] = p.Get(bday).(int64) } diff := set["p3"] - set["p2"] if diff != 1 { t.Fatalf("expected birth to be 1 apart, got %v", diff) } }
func TestIncreaseAge(t *testing.T) { sw := mock.ProtoNetSwarm{} p0 := &mock.Peer{ID: "p0"} p1 := &mock.Peer{ID: "p1"} c0 := New(p0, 3, 2, sw.DialListener(p0.Id())) c1 := New(p1, 3, 2, sw.DialListener(p0.Id())) c0.neighbs = PeerSet{ "p2": &mock.Peer{"p2", map[string]interface{}{age: 2}}, "p3": &mock.Peer{"p3", map[string]interface{}{age: 2}}, "p4": &mock.Peer{"p4", map[string]interface{}{age: 2}}, } c1.neighbs = PeerSet{ "p0": &mock.Peer{"p0", map[string]interface{}{age: 3}}, "p5": &mock.Peer{"p5", map[string]interface{}{age: 2}}, "p6": &mock.Peer{"p6", map[string]interface{}{age: 2}}, } c0.Start(0) defer c0.Stop() c1.Shuffle() union := make(map[interface{}]pnet.Peer) for s, p := range c0.neighbs { union[s] = p } for s, p := range c1.neighbs { union[s] = p } expected := map[string]int{"p1": 0, "p2": 2, "p3": 2, "p4": 2, "p5": 3, "p6": 3} for s, a := range expected { if union[s].Get(age) != a { t.Fatalf("expected %s.age %d, got %d", s, a, union[s].Get(age)) } } }
func TestNumGoroutine(t *testing.T) { baseNum := numGoroutine() var num int sw := mock.ProtoNetSwarm{} b := New(2, time.Minute, sw.DialListener("p0")) b.Start(nil, 0) b.Stop() ticker := time.NewTicker(timeToWait / 100) defer ticker.Stop() timeout := time.After(timeToWait) for { select { case <-ticker.C: num = numGoroutine() if num == baseNum { return } case <-timeout: t.Fatalf("%d goroutines are leaking", num-baseNum) } } }