"""Tests for peer profiles.""" import os import time import pytest class TestPeerProfile: def test_construct(self): from i2p_peer.profile import PeerProfile h = os.urandom(32) p = PeerProfile(router_hash=h) assert p.router_hash == h assert p.capacity == 0.0 assert p.integration == 0.0 def test_update_capacity(self): from i2p_peer.profile import PeerProfile p = PeerProfile(os.urandom(32)) p.record_success() assert p.capacity > 0 def test_record_failure(self): from i2p_peer.profile import PeerProfile p = PeerProfile(os.urandom(32)) p.record_success() old = p.capacity p.record_failure() assert p.capacity < old def test_tunnel_build_success(self): from i2p_peer.profile import PeerProfile p = PeerProfile(os.urandom(32)) p.tunnel_build_success() assert p.tunnel_builds_succeeded == 1 assert p.tunnel_builds_failed == 0 def test_tunnel_build_failure(self): from i2p_peer.profile import PeerProfile p = PeerProfile(os.urandom(32)) p.tunnel_build_failure() assert p.tunnel_builds_failed == 1 def test_tunnel_success_rate(self): from i2p_peer.profile import PeerProfile p = PeerProfile(os.urandom(32)) p.tunnel_build_success() p.tunnel_build_success() p.tunnel_build_failure() assert abs(p.tunnel_success_rate - 2/3) < 0.01 def test_tunnel_success_rate_no_builds(self): from i2p_peer.profile import PeerProfile p = PeerProfile(os.urandom(32)) assert p.tunnel_success_rate == 0.0 def test_last_heard_from(self): from i2p_peer.profile import PeerProfile p = PeerProfile(os.urandom(32)) now = int(time.time() * 1000) p.update_last_heard(now) assert p.last_heard_from == now def test_decay(self): from i2p_peer.profile import PeerProfile p = PeerProfile(os.urandom(32)) for _ in range(10): p.record_success() old_cap = p.capacity p.decay(factor=0.5) assert p.capacity < old_cap def test_score(self): from i2p_peer.profile import PeerProfile p = PeerProfile(os.urandom(32)) p.record_success() p.tunnel_build_success() score = p.score() assert score > 0.0 class TestPeerSelector: def test_select_best(self): from i2p_peer.profile import PeerProfile, PeerSelector profiles = [] for _ in range(5): p = PeerProfile(os.urandom(32)) for _ in range(3): p.record_success() profiles.append(p) # Make one clearly better for _ in range(20): profiles[2].record_success() profiles[2].tunnel_build_success() selector = PeerSelector(profiles) best = selector.select_best(n=2) assert len(best) == 2 assert profiles[2].router_hash in [p.router_hash for p in best] def test_select_with_exclusions(self): from i2p_peer.profile import PeerProfile, PeerSelector profiles = [PeerProfile(os.urandom(32)) for _ in range(5)] for p in profiles: p.record_success() selector = PeerSelector(profiles) excluded = {profiles[0].router_hash, profiles[1].router_hash} result = selector.select_best(n=5, exclude=excluded) for p in result: assert p.router_hash not in excluded def test_select_empty(self): from i2p_peer.profile import PeerSelector selector = PeerSelector([]) assert selector.select_best(n=3) == [] class TestBanManager: def test_ban_peer(self): from i2p_peer.profile import BanManager bm = BanManager() h = os.urandom(32) bm.ban(h, reason="protocol violation", duration_ms=60000) assert bm.is_banned(h) def test_not_banned(self): from i2p_peer.profile import BanManager bm = BanManager() assert not bm.is_banned(os.urandom(32)) def test_ban_expires(self): from i2p_peer.profile import BanManager bm = BanManager() h = os.urandom(32) bm.ban(h, reason="test", duration_ms=1000, now_ms=0) assert bm.is_banned(h, now_ms=500) assert not bm.is_banned(h, now_ms=2000) def test_unban(self): from i2p_peer.profile import BanManager bm = BanManager() h = os.urandom(32) bm.ban(h, reason="test", duration_ms=60000) bm.unban(h) assert not bm.is_banned(h) def test_ban_count(self): from i2p_peer.profile import BanManager bm = BanManager() for _ in range(3): bm.ban(os.urandom(32), reason="test", duration_ms=60000) assert bm.ban_count() == 3 def test_cleanup_expired(self): from i2p_peer.profile import BanManager bm = BanManager() bm.ban(os.urandom(32), reason="test", duration_ms=100, now_ms=0) bm.ban(os.urandom(32), reason="test", duration_ms=99999, now_ms=0) bm.cleanup(now_ms=500) assert bm.ban_count() == 1