Skip to content

Commit edcc2c7

Browse files
Pin cycle 22's wire-decode-failed prefix on StmtResponse db_id-mismatch ProtocolError
Cycle 22 prefixed the ``StmtResponse`` ``db_id`` mismatch ``ProtocolError`` with the canonical ``"wire decode failed:"`` phrase so SA's ``is_disconnect`` substring matcher routes the registry-drift event through the pool-invalidate path. Without the prefix the broken slot was silently retained. Add a test pinning the prefix on the ``DqliteProtocol.prepare`` round-trip — feed a ``StmtResponse`` with a ``db_id`` that differs from the prepare-call's ``db_id`` and assert the ``ProtocolError`` message starts with the load-bearing phrase. A future refactor that drops the prefix or rephrases the message breaks the test deliberately. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 35f7a09 commit edcc2c7

1 file changed

Lines changed: 32 additions & 0 deletions

File tree

tests/test_protocol.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,38 @@ async def test_prepare(
626626
assert stmt_id == 1
627627
assert num_params == 2
628628

629+
async def test_prepare_db_id_mismatch_raises_protocol_error_with_wire_decode_prefix(
630+
self,
631+
protocol: DqliteProtocol,
632+
mock_reader: AsyncMock,
633+
) -> None:
634+
"""Pin: a server-emitted ``StmtResponse`` whose ``db_id``
635+
does not match the prepare's ``db_id`` argument indicates
636+
prepared-statement registry drift. The cycle 22 fix
637+
prefixes the resulting ``ProtocolError`` with the
638+
canonical ``"wire decode failed:"`` phrase so SA's
639+
``is_disconnect`` substring matcher routes it through
640+
the pool-invalidate path. Without the prefix, the
641+
registry-drift event would surface as a non-disconnect
642+
ProtocolError and the SA pool would keep the broken
643+
slot."""
644+
from dqlitewire.messages import StmtResponse
645+
646+
# Request prepare against db_id=1 but server returns db_id=99
647+
# — the registry-drift signal.
648+
mock_reader.read.return_value = StmtResponse(db_id=99, stmt_id=42, num_params=0).encode()
649+
650+
with pytest.raises(ProtocolError) as exc_info:
651+
await protocol.prepare(1, "SELECT 1")
652+
653+
message = str(exc_info.value)
654+
assert message.startswith("wire decode failed:"), (
655+
f"Cycle 22 prefix is load-bearing for SA's is_disconnect "
656+
f"substring matcher. Got message: {message!r}"
657+
)
658+
assert "db_id 99" in message
659+
assert "db_id 1" in message
660+
629661
async def test_finalize(
630662
self,
631663
protocol: DqliteProtocol,

0 commit comments

Comments
 (0)