"""Tests for Garlic encryption types.""" import os import struct import pytest class TestDeliveryInstructions: def test_enum_values(self): from i2p_data.garlic import DeliveryType assert DeliveryType.LOCAL == 0 assert DeliveryType.DESTINATION == 1 assert DeliveryType.ROUTER == 2 assert DeliveryType.TUNNEL == 3 def test_local_roundtrip(self): from i2p_data.garlic import DeliveryInstructions, DeliveryType di = DeliveryInstructions(DeliveryType.LOCAL) data = di.to_bytes() di2, consumed = DeliveryInstructions.from_bytes(data) assert di2.delivery_type == DeliveryType.LOCAL assert di2.destination is None assert di2.router is None assert di2.tunnel_id is None def test_destination_roundtrip(self): from i2p_data.garlic import DeliveryInstructions, DeliveryType dest = os.urandom(32) di = DeliveryInstructions(DeliveryType.DESTINATION, destination=dest) data = di.to_bytes() di2, consumed = DeliveryInstructions.from_bytes(data) assert di2.delivery_type == DeliveryType.DESTINATION assert di2.destination == dest def test_router_roundtrip(self): from i2p_data.garlic import DeliveryInstructions, DeliveryType router = os.urandom(32) di = DeliveryInstructions(DeliveryType.ROUTER, router=router) data = di.to_bytes() di2, consumed = DeliveryInstructions.from_bytes(data) assert di2.delivery_type == DeliveryType.ROUTER assert di2.router == router def test_tunnel_roundtrip(self): from i2p_data.garlic import DeliveryInstructions, DeliveryType router = os.urandom(32) di = DeliveryInstructions(DeliveryType.TUNNEL, router=router, tunnel_id=42) data = di.to_bytes() di2, consumed = DeliveryInstructions.from_bytes(data) assert di2.delivery_type == DeliveryType.TUNNEL assert di2.router == router assert di2.tunnel_id == 42 class TestGarlicClove: def test_construct(self): from i2p_data.garlic import GarlicClove, DeliveryInstructions, DeliveryType di = DeliveryInstructions(DeliveryType.LOCAL) msg_data = os.urandom(64) clove = GarlicClove(di, msg_data, clove_id=123, expiration=1710000000000) assert clove.delivery_instructions.delivery_type == DeliveryType.LOCAL assert clove.message_data == msg_data assert clove.clove_id == 123 assert clove.expiration == 1710000000000 def test_roundtrip_local(self): from i2p_data.garlic import GarlicClove, DeliveryInstructions, DeliveryType di = DeliveryInstructions(DeliveryType.LOCAL) msg = os.urandom(32) clove = GarlicClove(di, msg, clove_id=999, expiration=5000) data = clove.to_bytes() clove2 = GarlicClove.from_bytes(data) assert clove2.clove_id == 999 assert clove2.expiration == 5000 assert clove2.message_data == msg assert clove2.delivery_instructions.delivery_type == DeliveryType.LOCAL def test_roundtrip_tunnel(self): from i2p_data.garlic import GarlicClove, DeliveryInstructions, DeliveryType router = os.urandom(32) di = DeliveryInstructions(DeliveryType.TUNNEL, router=router, tunnel_id=777) msg = os.urandom(100) clove = GarlicClove(di, msg, clove_id=42, expiration=9999) data = clove.to_bytes() clove2 = GarlicClove.from_bytes(data) assert clove2.delivery_instructions.delivery_type == DeliveryType.TUNNEL assert clove2.delivery_instructions.router == router assert clove2.delivery_instructions.tunnel_id == 777 assert clove2.message_data == msg class TestGarlicMessage: def test_construct(self): from i2p_data.garlic import GarlicMessage, GarlicClove, DeliveryInstructions, DeliveryType di = DeliveryInstructions(DeliveryType.LOCAL) clove = GarlicClove(di, b"msg1", clove_id=1, expiration=1000) gm = GarlicMessage([clove]) assert gm.clove_count() == 1 def test_multiple_cloves_roundtrip(self): from i2p_data.garlic import GarlicMessage, GarlicClove, DeliveryInstructions, DeliveryType cloves = [] for i in range(3): di = DeliveryInstructions(DeliveryType.LOCAL) cloves.append(GarlicClove(di, os.urandom(16), clove_id=i, expiration=1000 + i)) gm = GarlicMessage(cloves) data = gm.to_bytes() gm2 = GarlicMessage.from_bytes(data) assert gm2.clove_count() == 3 for i in range(3): assert gm2.cloves[i].clove_id == i assert gm2.cloves[i].expiration == 1000 + i def test_empty_cloves(self): from i2p_data.garlic import GarlicMessage gm = GarlicMessage([]) assert gm.clove_count() == 0 data = gm.to_bytes() gm2 = GarlicMessage.from_bytes(data) assert gm2.clove_count() == 0 def test_mixed_delivery_types(self): from i2p_data.garlic import GarlicMessage, GarlicClove, DeliveryInstructions, DeliveryType cloves = [ GarlicClove(DeliveryInstructions(DeliveryType.LOCAL), b"local", clove_id=1, expiration=100), GarlicClove(DeliveryInstructions(DeliveryType.ROUTER, router=os.urandom(32)), b"router", clove_id=2, expiration=200), GarlicClove(DeliveryInstructions(DeliveryType.TUNNEL, router=os.urandom(32), tunnel_id=55), b"tunnel", clove_id=3, expiration=300), ] gm = GarlicMessage(cloves) data = gm.to_bytes() gm2 = GarlicMessage.from_bytes(data) assert gm2.cloves[0].delivery_instructions.delivery_type == DeliveryType.LOCAL assert gm2.cloves[1].delivery_instructions.delivery_type == DeliveryType.ROUTER assert gm2.cloves[2].delivery_instructions.delivery_type == DeliveryType.TUNNEL assert gm2.cloves[2].delivery_instructions.tunnel_id == 55