Skip to content

Commit 27c66de

Browse files
test(dbapi): pin cursor behavior after external connection close (ISSUE-103)
Previously tests covered operations on an explicitly-closed cursor but not on a live cursor whose connection was closed externally (via conn.close()). Both the sync and async cursor must raise InterfaceError on execute / executemany in this state, and cursor.close() must remain idempotent.
1 parent ea35ee5 commit 27c66de

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

tests/test_cycle3_tests_pinning.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
"""Cycle-3 bundle E: regression tests pinning previously-untested edges.
2+
3+
Covers:
4+
- ISSUE-103: cursor.execute() on a cursor whose connection was closed
5+
externally (not via cursor.close()) raises InterfaceError.
6+
"""
7+
8+
import asyncio
9+
10+
import pytest
11+
12+
from dqlitedbapi.aio.connection import AsyncConnection
13+
from dqlitedbapi.aio.cursor import AsyncCursor
14+
from dqlitedbapi.exceptions import InterfaceError
15+
16+
17+
class TestCursorAfterExternalConnectionClose:
18+
"""ISSUE-103: operations on a live cursor whose connection was
19+
closed externally must raise InterfaceError rather than hanging
20+
or surfacing a cryptic lower-layer error.
21+
"""
22+
23+
def test_sync_cursor_execute_after_connection_close(self) -> None:
24+
import dqlitedbapi
25+
26+
conn = dqlitedbapi.connect("localhost:19001")
27+
cursor = conn.cursor()
28+
conn.close()
29+
30+
with pytest.raises(InterfaceError):
31+
cursor.execute("SELECT 1")
32+
33+
with pytest.raises(InterfaceError):
34+
cursor.executemany("SELECT ?", [(1,), (2,)])
35+
36+
# cursor.close() remains idempotent even after the connection is gone.
37+
cursor.close()
38+
cursor.close()
39+
40+
def test_async_cursor_execute_after_connection_close(self) -> None:
41+
async def _run() -> None:
42+
conn = AsyncConnection("localhost:19001")
43+
# Don't actually connect — keep this a pure state-machine test
44+
# so it doesn't depend on the cluster being up.
45+
cursor = AsyncCursor(conn)
46+
await conn.close()
47+
48+
with pytest.raises(InterfaceError):
49+
await cursor.execute("SELECT 1")
50+
51+
with pytest.raises(InterfaceError):
52+
await cursor.executemany("SELECT ?", [(1,), (2,)])
53+
54+
asyncio.run(_run())

0 commit comments

Comments
 (0)