openocd-python/tests/test_session.py
Ryan Malloy d17037f2a1 Add SWD/DAP subsystem with DP/AP register access and AP enumeration
10th subsystem: session.swd provides DAP discovery, DP/AP register
read/write, AP enumeration, and convenience methods (dpidr, target_id).
Includes SWDError, DAPInfo, APInfo types, input validation, ADIv5/v6
AP classification, and 24 mock-only tests covering happy and error paths.
2026-02-15 16:36:25 -07:00

107 lines
3.3 KiB
Python

"""Tests for the Session class."""
from __future__ import annotations
import pytest
from openocd.breakpoints import BreakpointManager
from openocd.flash import Flash
from openocd.jtag import JTAGController
from openocd.memory import Memory
from openocd.registers import Registers
from openocd.rtt import RTTManager
from openocd.session import Session
from openocd.svd import SVDManager
from openocd.swd import SWDController
from openocd.target import Target
from openocd.transport import Transport
async def test_connect_to_mock(mock_ocd):
"""Session.connect() should successfully connect to the mock server."""
host, port, _server = mock_ocd
sess = await Session.connect(host, port, timeout=5.0)
assert sess is not None
await sess.close()
async def test_raw_command(session):
"""session.command() should pass through to the underlying connection."""
resp = await session.command("targets")
assert "stm32f1x.cpu" in resp
async def test_context_manager(mock_ocd):
"""Session should work as an async context manager."""
host, port, _server = mock_ocd
async with await Session.connect(host, port, timeout=5.0) as sess:
resp = await sess.command("halt")
assert resp == ""
# After exiting the context, the connection is closed.
# Attempting to send should raise.
from openocd.errors import ConnectionError
with pytest.raises(ConnectionError):
await sess.command("targets")
async def test_subsystem_target_type(session):
"""session.target should return a Target instance."""
assert isinstance(session.target, Target)
async def test_subsystem_memory_type(session):
"""session.memory should return a Memory instance."""
assert isinstance(session.memory, Memory)
async def test_subsystem_registers_type(session):
"""session.registers should return a Registers instance."""
assert isinstance(session.registers, Registers)
async def test_subsystem_flash_type(session):
"""session.flash should return a Flash instance."""
assert isinstance(session.flash, Flash)
async def test_subsystem_jtag_type(session):
"""session.jtag should return a JTAGController instance."""
assert isinstance(session.jtag, JTAGController)
async def test_subsystem_swd_type(session):
"""session.swd should return an SWDController instance."""
assert isinstance(session.swd, SWDController)
async def test_subsystem_breakpoints_type(session):
"""session.breakpoints should return a BreakpointManager instance."""
assert isinstance(session.breakpoints, BreakpointManager)
async def test_subsystem_rtt_type(session):
"""session.rtt should return an RTTManager instance."""
assert isinstance(session.rtt, RTTManager)
async def test_subsystem_svd_type(session):
"""session.svd should return an SVDManager instance."""
assert isinstance(session.svd, SVDManager)
async def test_subsystem_transport_type(session):
"""session.transport should return a Transport instance."""
assert isinstance(session.transport, Transport)
async def test_subsystem_lazy_initialization(session):
"""Accessing the same property twice should return the same object."""
t1 = session.target
t2 = session.target
assert t1 is t2
m1 = session.memory
m2 = session.memory
assert m1 is m2