2023-08-18 22:09:02 +00:00
|
|
|
import unittest
|
|
|
|
|
|
|
|
import std/times
|
|
|
|
import std/algorithm
|
|
|
|
import sequtils
|
|
|
|
import sugar
|
|
|
|
|
|
|
|
import pkg/swarmsim/engine/eventdrivenengine
|
|
|
|
import pkg/swarmsim/engine/peer
|
|
|
|
import pkg/swarmsim/engine/network
|
|
|
|
import pkg/swarmsim/codex/dhttracker
|
|
|
|
import pkg/swarmsim/timeutils
|
|
|
|
|
|
|
|
proc getPeerArray(tracker: Peer): seq[PeerDescriptor] =
|
|
|
|
DHTTracker(
|
2023-08-25 18:46:38 +00:00
|
|
|
tracker.getProtocol(DHTTracker.typeId).get()).peers
|
2023-08-18 22:09:02 +00:00
|
|
|
|
|
|
|
proc getPeerIdArray(tracker: Peer): seq[int] =
|
|
|
|
getPeerArray(tracker).map(p => p.peerId)
|
|
|
|
|
|
|
|
proc announcePeer(network: Network, tracker: Peer, peerId: int,
|
|
|
|
delay: uint64 = 0) =
|
|
|
|
network.send(
|
2023-08-24 16:29:00 +00:00
|
|
|
PeerAnnouncement(receiver: tracker, peerId: peerId),
|
2023-08-18 22:09:02 +00:00
|
|
|
delay.some).doAwait()
|
|
|
|
|
|
|
|
suite "tracker node":
|
|
|
|
|
|
|
|
setup:
|
|
|
|
let engine = EventDrivenEngine()
|
|
|
|
|
|
|
|
let trackerPeer = Peer.new(
|
|
|
|
protocols = @[
|
|
|
|
Protocol DHTTracker.new(maxPeers = 5)
|
|
|
|
]
|
|
|
|
)
|
|
|
|
|
|
|
|
let network = Network.new(engine = engine)
|
|
|
|
|
|
|
|
test "should retain published descriptors":
|
|
|
|
announcePeer(network, trackerPeer, 25)
|
|
|
|
|
|
|
|
let peers = getPeerArray(trackerPeer)
|
|
|
|
|
|
|
|
check(len(peers) == 1)
|
|
|
|
check(peers[0].peerId == 25)
|
|
|
|
|
|
|
|
test "should not include the same peer more than once":
|
|
|
|
announcePeer(network, trackerPeer, 25)
|
|
|
|
announcePeer(network, trackerPeer, 25)
|
|
|
|
|
|
|
|
let peers = getPeerArray(trackerPeer)
|
|
|
|
|
|
|
|
check(len(peers) == 1)
|
|
|
|
check(peers[0].peerId == 25)
|
|
|
|
|
|
|
|
test "should drop descriptors after expiry time":
|
|
|
|
announcePeer(network, trackerPeer, 25)
|
|
|
|
|
|
|
|
check(len(getPeerArray(trackerPeer)) == 1)
|
|
|
|
engine.runUntil(DHTTracker.defaultExpiry + 1.dseconds)
|
|
|
|
|
|
|
|
check(len(getPeerArray(trackerPeer)) == 0)
|
|
|
|
|
|
|
|
test "should renew expiry time if peer republishes its record":
|
|
|
|
announcePeer(network, trackerPeer, 25)
|
|
|
|
|
|
|
|
check(len(getPeerArray(trackerPeer)) == 1)
|
|
|
|
engine.runUntil(DHTTracker.defaultExpiry - 1.dseconds)
|
|
|
|
|
|
|
|
announcePeer(network, trackerPeer, 25)
|
|
|
|
|
|
|
|
engine.runUntil(DHTTracker.defaultExpiry + 15.dseconds)
|
|
|
|
check(len(getPeerArray(trackerPeer)) == 1)
|
|
|
|
|
|
|
|
engine.runUntil(2*DHTTracker.defaultExpiry + 1.dseconds)
|
|
|
|
check(len(getPeerArray(trackerPeer)) == 0)
|
|
|
|
|
2023-08-21 12:51:38 +00:00
|
|
|
test "should drop least recently seen peer when table is full":
|
2023-08-18 22:09:02 +00:00
|
|
|
announcePeer(network, trackerPeer, 25, delay = 0)
|
|
|
|
announcePeer(network, trackerPeer, 35, delay = 1)
|
|
|
|
announcePeer(network, trackerPeer, 45, delay = 2)
|
|
|
|
announcePeer(network, trackerPeer, 55, delay = 3)
|
|
|
|
announcePeer(network, trackerPeer, 65, delay = 4)
|
|
|
|
|
|
|
|
check(getPeerIdArray(trackerPeer).sorted == @[25, 35, 45, 55, 65])
|
|
|
|
|
2023-08-21 12:51:38 +00:00
|
|
|
announcePeer(network, trackerPeer, 25, delay = 1)
|
2023-08-18 22:09:02 +00:00
|
|
|
announcePeer(network, trackerPeer, 75, delay = 1)
|
|
|
|
|
2023-08-21 12:51:38 +00:00
|
|
|
check(getPeerIdArray(trackerPeer).sorted == @[25, 45, 55, 65, 75])
|