func TestAnnouncersCanCommunicate(t *testing.T) { a1, _, err := getAnnouncer() if err != nil { t.Fatal(err) } a2, p2, err := getAnnouncer() if err != nil { t.Fatal(err) } if len(a1.peers.Peers) != 1 { t.Fatalf("Announcer had %d peers, expected 1", len(a1.peers.Peers)) } if len(a2.peers.Peers) != 1 { t.Fatalf("Announcer had %d peers, expected 1", len(a2.peers.Peers)) } a1.addPeer(p2.Addresses[0]) err = a1.runAnnounceRound() if err != nil { t.Fatalf("Error from runAnnounceRound: %v", err) } if len(a1.peers.Peers) != 2 { t.Fatalf("Announcer had %d peers, expected 2", len(a1.peers.Peers)) } ok := util.WaitUntilTrue(func() bool { return len(a2.peers.Peers) == 2 }, time.Second*5) if !ok { t.Fatalf("Announcer didn't receive announcement within 5 seconds") } peers := a2.unicastConnection.GetPeerList() if len(peers) != 1 { t.Fatalf("Announcer got announcement but underlying connection reports %d peers instead of 1", len(peers)) } a2.runAnnounceRound() ok = util.WaitUntilTrue(func() bool { return len(a1.peers.Peers) == 2 }, time.Second*5) if !ok { t.Fatalf("Announcer didn't receive announcement within 5 seconds") } }
func TestPacketGetsAcked(t *testing.T) { r1, err := NewReliableConnection() if err != nil { t.Errorf("NewReliableConnection() returned error: %q", err) } if r1 == nil { t.Errorf("NewReliableConnection() returned nil connection") } r2, err := NewReliableConnection() if err != nil { t.Errorf("NewReliableConnection() returned error: %q", err) } if r2 == nil { t.Errorf("NewReliableConnection() returned nil connection") } p := r1.FindOrAddPeer(&net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: r2.Port}) if p == nil { t.Errorf("ConnectPeer() returned nil peer") } packet := newPacketWithRetries(p, nil, 0, opPing) r1.queuePacketForSend(packet) ok := util.WaitUntilTrue(func() bool { return p.GetPacketIsPacketUnacked(packet) }, time.Millisecond*2000) if !ok { t.Errorf("Queued packet missing from unacked packets") } ok = util.WaitUntilTrue(func() bool { return !p.GetPacketIsPacketUnacked(packet) }, time.Millisecond*2000) if !ok { t.Errorf("Packet not acked after 2 seconds") } r1.Close() r2.Close() }
func TestDeadPeerGetsDropped(t *testing.T) { r1, err := NewReliableConnection() if err != nil { t.Errorf("NewReliableConnection() returned error: %q", err) } if r1 == nil { t.Errorf("NewReliableConnection() returned nil connection") } r1.connectionTimeout = time.Millisecond * 1000 r1.packetTimeout = time.Millisecond * 300 r2, err := NewReliableConnection() if err != nil { t.Errorf("NewReliableConnection() returned error: %q", err) } if r2 == nil { t.Errorf("NewReliableConnection() returned nil connection") } r1.EnableKeepalive(false) r2.EnableKeepalive(false) p := r1.FindOrAddPeer(&net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: r2.Port}) if p == nil { t.Errorf("ConnectPeer() returned nil peer") } r1.sendKeepaliveToPeer(p) isAlive := p.IsAlive(time.Millisecond * 2000) if !isAlive { t.Errorf("peer.IsAlive(2000ms) returned false") } r2.Close() ok := util.WaitUntilTrue(func() bool { enumReq := r1.getEnumeratePeersChan() for p2 := range enumReq.RespChan { if p2 == p { close(enumReq.AbortChan) return false } } return true }, r1.connectionTimeout*3) if !ok { t.Errorf("peer was not removed after 3 * connection timeout") } r1.Close() }
func TestPeerDispatchesPackets(t *testing.T) { c := &dummyCon{ sendPacketChan: make(chan *packet), } p := NewPeer(nil, c) n := 10 go func() { for i := 0; i < n; i++ { pkt := newPacketWithRetries(p, nil, 0, opData) p.SendPacket(pkt) } }() got := 0 go func() { for got < n { p.dispatch(time.Now()) } }() go func() { ok := util.WaitUntilTrue(func() bool { return got == n }, time.Second*10) if !ok { t.Errorf("Peer hasn't dispatched packets after 10 seconds") close(c.sendPacketChan) } }() for got < n { <-c.sendPacketChan got++ } p.Close() }
func TestPacketKeepaliveIncreasesSeq(t *testing.T) { r1, err := NewReliableConnection() if err != nil { t.Errorf("NewReliableConnection() returned error: %q", err) } if r1 == nil { t.Errorf("NewReliableConnection() returned nil connection") } r2, err := NewReliableConnection() if err != nil { t.Errorf("NewReliableConnection() returned error: %q", err) } if r2 == nil { t.Errorf("NewReliableConnection() returned nil connection") } p := r1.FindOrAddPeer(&net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: r2.Port}) if p == nil { t.Errorf("ConnectPeer() returned nil peer") } s := p.Seq r1.sendKeepaliveToPeer(p) ok := util.WaitUntilTrue(func() bool { return p.Seq > s+1 }, r1.packetTimeout*2) if !ok { t.Errorf("Peer's Seq didn't increment after send keepalive") } r1.Close() r2.Close() }
func TestPeersFindOutAboutEachOtherViaThirdParty(t *testing.T) { a1, _, err := getAnnouncer() if err != nil { t.Fatal(err) } a2, p2, err := getAnnouncer() if err != nil { t.Fatal(err) } a3, _, err := getAnnouncer() if err != nil { t.Fatal(err) } if len(a1.peers.Peers) != 1 { t.Fatalf("Announcer had %d peers, expected 1", len(a1.peers.Peers)) } if len(a2.peers.Peers) != 1 { t.Fatalf("Announcer had %d peers, expected 1", len(a2.peers.Peers)) } if len(a3.peers.Peers) != 1 { t.Fatalf("Announcer had %d peers, expected 1", len(a3.peers.Peers)) } a1.addPeer(p2.Addresses[0]) err = a1.runAnnounceRound() if err != nil { t.Fatalf("Error from runAnnounceRound: %v", err) } if len(a1.peers.Peers) != 2 { t.Fatalf("Announcer had %d peers, expected 2", len(a1.peers.Peers)) } a3.addPeer(p2.Addresses[0]) err = a3.runAnnounceRound() if err != nil { t.Fatalf("Error from runAnnounceRound: %v", err) } if len(a3.peers.Peers) != 2 { t.Fatalf("Announcer had %d peers, expected 2", len(a3.peers.Peers)) } ok := util.WaitUntilTrue(func() bool { return len(a2.peers.Peers) == 3 }, time.Second*5) if !ok { t.Fatalf("Announcer didn't receive announcements within 5 seconds") } ok = util.WaitUntilTrue(func() bool { return len(a1.peers.Peers) == 3 && len(a3.peers.Peers) == 3 }, time.Second*5) if !ok { t.Fatalf("Announcers didn't recieve announcements about peers via 3rd party within 5 seconds") } }
func TestPacketsDroppedAfterRetriesExpired(t *testing.T) { r1, err := NewReliableConnection() if err != nil { t.Fatalf("NewReliableConnection() returned error: %q", err) } r2 := &con{} gotPacketCount := uint32(0) buf := []byte("Hello I'm some data") lossyHandler := func(incomingPackets chan *encodedPacket) { innerChan := make(chan *encodedPacket) defer close(innerChan) go r2.handlePackets(innerChan) for p := range incomingPackets { pkt, err := p.toOutgoingPacket() if err != nil { t.Fatalf("Error converting to outgoingPacket: %v", err) return } if pkt.OpCode&opData == opData && len(buf) == len(pkt.Payload) { same := true for i, v := range buf { v2 := pkt.Payload[i] if v != v2 { same = false break } } if same { gotPacketCount++ continue } } innerChan <- p } } _, err = newReliableConnectionWithListenerHandlers(r2, lossyHandler, r2.dispatchPackets) if err != nil { t.Fatalf("newReliableConnectionWithListenerHandlers() returned error: %q", err) } r1.packetTimeout = time.Millisecond * 200 r2.packetTimeout = time.Millisecond * 200 p := r1.FindOrAddPeer(&net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: r2.Port}) if p == nil { t.Fatalf("ConnectPeer() returned nil peer") } isAlive := p.IsAlive(time.Millisecond * 2000) if !isAlive { t.Fatalf("peer.IsAlive(2000ms) returned false") } retries := uint32(4) packet := newPacketWithRetries(p, buf, retries, opData) r1.queuePacketForSend(packet) ok := util.WaitUntilTrue(func() bool { return len(p.GetUnackedPacketList()) == 0 || gotPacketCount >= retries }, p.connectionTimeout*2) if !ok { t.Fatalf("peer had %d unacked packets after 2 * connection timeout and we didn't get the packet we were expecting the correct number of times", len(p.GetUnackedPacketList())) } if gotPacketCount != retries { t.Fatalf("We got the packet we wanted %d times, expected %d", gotPacketCount, retries) } time.Sleep(default_packet_timeout) r1.Close() r2.Close() }