"""Tests for Lease2 (LS2 format with 4-byte second timestamps).""" import struct import time from i2p_data.lease import Lease2 def test_lease2_size_is_40(): assert Lease2.SIZE == 40 def test_lease2_roundtrip(): gw = b"\x01" * 32 tid = 12345 end_ms = int(time.time() * 1000) + 600_000 # 10 min from now lease = Lease2(gw, tid, end_ms) data = lease.to_bytes() assert len(data) == 40 restored = Lease2.from_bytes(data) assert restored.gateway_hash == gw assert restored.tunnel_id == tid # Roundtrip loses sub-second precision (ms → sec → ms) assert abs(restored.end_date - end_ms) < 1000 def test_lease2_timestamp_conversion(): """Wire format uses seconds, internal uses milliseconds.""" gw = b"\xab" * 32 end_sec = 1700000000 end_ms = end_sec * 1000 lease = Lease2(gw, 1, end_ms) data = lease.to_bytes() # Last 4 bytes should be the seconds value wire_sec = struct.unpack("!I", data[36:40])[0] assert wire_sec == end_sec def test_lease2_is_expired(): gw = b"\x00" * 32 past_ms = int(time.time() * 1000) - 60_000 lease = Lease2(gw, 1, past_ms) assert lease.is_expired() future_ms = int(time.time() * 1000) + 600_000 lease2 = Lease2(gw, 1, future_ms) assert not lease2.is_expired() def test_lease2_from_bytes_too_short(): import pytest with pytest.raises(ValueError, match="Lease2 requires 40 bytes"): Lease2.from_bytes(b"\x00" * 39)