"""Tests for SSU2 transport protocol types.""" import os import struct import pytest class TestSSU2Header: def test_construct(self): from i2p_transport.ssu2 import SSU2Header h = SSU2Header(dest_conn_id=0xDEADBEEF, pkt_num=42, header_type=0, version=2) assert h.dest_conn_id == 0xDEADBEEF assert h.pkt_num == 42 def test_short_header_roundtrip(self): from i2p_transport.ssu2 import SSU2Header h = SSU2Header(dest_conn_id=12345, pkt_num=100, header_type=0, version=2) data = h.to_bytes() h2 = SSU2Header.from_bytes(data) assert h2.dest_conn_id == 12345 assert h2.pkt_num == 100 def test_header_size(self): from i2p_transport.ssu2 import SSU2Header h = SSU2Header(dest_conn_id=0, pkt_num=0, header_type=0, version=2) data = h.to_bytes() assert len(data) == 16 # dest_id(8) + pkt_num(4) + type(1) + version(1) + net_id(2) class TestSSU2Block: def test_construct(self): from i2p_transport.ssu2 import SSU2Block, BlockType block = SSU2Block(block_type=BlockType.DATA, payload=b"test") assert block.block_type == BlockType.DATA assert block.payload == b"test" def test_roundtrip(self): from i2p_transport.ssu2 import SSU2Block, BlockType block = SSU2Block(block_type=BlockType.DATA, payload=os.urandom(64)) data = block.to_bytes() block2 = SSU2Block.from_bytes(data) assert block2.block_type == block.block_type assert block2.payload == block.payload def test_ack_block(self): from i2p_transport.ssu2 import SSU2Block, BlockType # ACK: ack_through(4) + num_ranges(1) + ranges ack_payload = struct.pack("!IB", 100, 0) block = SSU2Block(BlockType.ACK, ack_payload) data = block.to_bytes() block2 = SSU2Block.from_bytes(data) assert block2.block_type == BlockType.ACK def test_address_block(self): from i2p_transport.ssu2 import SSU2Block, BlockType block = SSU2Block(BlockType.ADDRESS, b"\x04\x01\x02\x03\x04\x30\x39") data = block.to_bytes() block2 = SSU2Block.from_bytes(data) assert block2.block_type == BlockType.ADDRESS def test_termination_block(self): from i2p_transport.ssu2 import SSU2Block, BlockType block = SSU2Block(BlockType.TERMINATION, struct.pack("!BQ", 0, 50)) data = block.to_bytes() block2 = SSU2Block.from_bytes(data) assert block2.block_type == BlockType.TERMINATION def test_padding_block(self): from i2p_transport.ssu2 import SSU2Block, BlockType block = SSU2Block(BlockType.PADDING, os.urandom(32)) data = block.to_bytes() block2 = SSU2Block.from_bytes(data) assert block2.block_type == BlockType.PADDING def test_multiple_blocks(self): import io from i2p_transport.ssu2 import SSU2Block, BlockType b1 = SSU2Block(BlockType.DATA, b"first") b2 = SSU2Block(BlockType.DATA, b"second") buf = b1.to_bytes() + b2.to_bytes() stream = io.BytesIO(buf) r1 = SSU2Block.from_stream(stream) r2 = SSU2Block.from_stream(stream) assert r1.payload == b"first" assert r2.payload == b"second" class TestSSU2SessionState: def test_initial_state(self): from i2p_transport.ssu2 import SSU2SessionState, SSU2State state = SSU2SessionState() assert state.state == SSU2State.UNKNOWN def test_token_request_flow(self): from i2p_transport.ssu2 import SSU2SessionState, SSU2State state = SSU2SessionState() state.send_token_request() assert state.state == SSU2State.TOKEN_REQUEST_SENT def test_session_request_flow(self): from i2p_transport.ssu2 import SSU2SessionState, SSU2State state = SSU2SessionState() state.send_session_request() assert state.state == SSU2State.SESSION_REQUEST_SENT def test_established(self): from i2p_transport.ssu2 import SSU2SessionState, SSU2State state = SSU2SessionState() state.send_session_request() state.receive_session_created() assert state.state == SSU2State.SESSION_CONFIRMED state.confirm() assert state.state == SSU2State.ESTABLISHED def test_terminate(self): from i2p_transport.ssu2 import SSU2SessionState, SSU2State state = SSU2SessionState() state.send_session_request() state.receive_session_created() state.confirm() state.terminate() assert state.state == SSU2State.TERMINATED def test_peer_test(self): from i2p_transport.ssu2 import SSU2SessionState state = SSU2SessionState() state.send_session_request() state.receive_session_created() state.confirm() state.start_peer_test() assert state.peer_test_active def test_path_validation(self): from i2p_transport.ssu2 import SSU2SessionState state = SSU2SessionState() state.send_session_request() state.receive_session_created() state.confirm() nonce = state.start_path_validation() assert nonce is not None assert state.path_challenge_pending