"""Tests for tunnel building types.""" import os import pytest class TestBuildRecord: def test_construct(self): from i2p_tunnel.builder import BuildRecord rec = BuildRecord( receive_tunnel_id=1, our_ident=os.urandom(32), next_tunnel_id=2, next_ident=os.urandom(32), layer_key=os.urandom(32), iv_key=os.urandom(32), reply_key=os.urandom(32), reply_iv=os.urandom(16), is_gateway=False, is_endpoint=False, ) assert rec.receive_tunnel_id == 1 assert rec.next_tunnel_id == 2 def test_roundtrip(self): from i2p_tunnel.builder import BuildRecord rec = BuildRecord( receive_tunnel_id=100, our_ident=os.urandom(32), next_tunnel_id=200, next_ident=os.urandom(32), layer_key=os.urandom(32), iv_key=os.urandom(32), reply_key=os.urandom(32), reply_iv=os.urandom(16), is_gateway=True, is_endpoint=False, ) data = rec.to_bytes() assert len(data) == 222 # Fixed record size rec2 = BuildRecord.from_bytes(data) assert rec2.receive_tunnel_id == 100 assert rec2.next_tunnel_id == 200 assert rec2.is_gateway assert not rec2.is_endpoint def test_endpoint_flag(self): from i2p_tunnel.builder import BuildRecord rec = BuildRecord( receive_tunnel_id=1, our_ident=os.urandom(32), next_tunnel_id=0, next_ident=os.urandom(32), layer_key=os.urandom(32), iv_key=os.urandom(32), reply_key=os.urandom(32), reply_iv=os.urandom(16), is_gateway=False, is_endpoint=True, ) data = rec.to_bytes() rec2 = BuildRecord.from_bytes(data) assert rec2.is_endpoint assert not rec2.is_gateway class TestBuildReplyRecord: def test_accepted(self): from i2p_tunnel.builder import BuildReplyRecord rec = BuildReplyRecord(status=0, reply_data=os.urandom(495)) assert rec.is_accepted() def test_rejected(self): from i2p_tunnel.builder import BuildReplyRecord rec = BuildReplyRecord(status=30, reply_data=os.urandom(495)) assert not rec.is_accepted() def test_roundtrip(self): from i2p_tunnel.builder import BuildReplyRecord reply_data = os.urandom(495) rec = BuildReplyRecord(status=0, reply_data=reply_data) data = rec.to_bytes() rec2 = BuildReplyRecord.from_bytes(data) assert rec2.status == 0 assert rec2.reply_data == reply_data class TestTunnelPool: def test_construct(self): from i2p_tunnel.builder import TunnelPool pool = TunnelPool(name="exploratory") assert pool.name == "exploratory" assert pool.tunnel_count() == 0 def test_add_tunnel(self): from i2p_tunnel.builder import TunnelPool, TunnelEntry from i2p_data.tunnel import TunnelId pool = TunnelPool(name="test") entry = TunnelEntry( tunnel_id=TunnelId(42), gateway=os.urandom(32), length=3, creation_time=1000, expiration=9999999999999, ) pool.add(entry) assert pool.tunnel_count() == 1 def test_get_tunnel(self): from i2p_tunnel.builder import TunnelPool, TunnelEntry from i2p_data.tunnel import TunnelId pool = TunnelPool(name="test") tid = TunnelId(55) entry = TunnelEntry(tid, os.urandom(32), 2, 1000, 9999999999999) pool.add(entry) found = pool.get(tid) assert found is not None assert int(found.tunnel_id) == 55 def test_remove_expired(self): from i2p_tunnel.builder import TunnelPool, TunnelEntry from i2p_data.tunnel import TunnelId pool = TunnelPool(name="test") pool.add(TunnelEntry(TunnelId(1), os.urandom(32), 2, 1000, 500)) # expired pool.add(TunnelEntry(TunnelId(2), os.urandom(32), 2, 1000, 9999999999999)) # active pool.remove_expired(now_ms=1000) assert pool.tunnel_count() == 1 def test_select_random(self): from i2p_tunnel.builder import TunnelPool, TunnelEntry from i2p_data.tunnel import TunnelId pool = TunnelPool(name="test") for i in range(5): pool.add(TunnelEntry(TunnelId(i), os.urandom(32), 2, 1000, 9999999999999)) selected = pool.select_random() assert selected is not None def test_select_random_empty(self): from i2p_tunnel.builder import TunnelPool pool = TunnelPool(name="test") assert pool.select_random() is None