openocd-python/tests/test_session.py
Ryan Malloy 7e1eac5e2d Add openocd-python: typed async-first Python bindings for OpenOCD
Standalone PyPI package providing structured access to the full OpenOCD
command surface via the TCL RPC protocol (port 6666). Async-first API
with sync wrappers for every method.

Subsystems: target control, memory read/write, CPU registers, flash
programming, JTAG chain/scan/boundary, breakpoints/watchpoints, SVD
peripheral decoding, RTT channels, transport/adapter config.

79 tests passing against a mock TCL RPC server.
2026-02-12 17:55:58 -07:00

99 lines
3.1 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.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_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