|
2 | 2 |
|
3 | 3 | from __future__ import annotations |
4 | 4 |
|
| 5 | +from types import SimpleNamespace |
| 6 | +from unittest.mock import AsyncMock |
| 7 | + |
5 | 8 | import acp.schema |
6 | 9 | import pytest |
7 | 10 |
|
@@ -34,14 +37,30 @@ async def test_initialize_advertises_terminal_auth_method(): |
34 | 37 | assert auth_method.env == {} |
35 | 38 |
|
36 | 39 |
|
37 | | -async def test_close_session_drops_session_from_registry(): |
38 | | - """ACP 0.10 session/close removes the session from the in-memory registry.""" |
| 40 | +async def test_close_session_cancels_and_releases_resources(): |
| 41 | + """ACP 0.10 session/close must cancel in-flight work and free per-session |
| 42 | + resources before dropping the session. |
| 43 | +
|
| 44 | + The spec mandates the agent "must cancel any ongoing work related to the |
| 45 | + session (treat it as if ``session/cancel`` was called) and then free up any |
| 46 | + resources associated with the session." |
| 47 | + """ |
39 | 48 | server = ACPServer() |
40 | | - server.sessions["sess-1"] = ("placeholder",) # type: ignore[assignment] |
| 49 | + cli = SimpleNamespace(cleanup_runtime_resources=AsyncMock()) |
| 50 | + acp_session = SimpleNamespace(cancel=AsyncMock(), cli=cli) |
| 51 | + # Registry stores ``tuple[ACPSession, _ModelIDConv]``. |
| 52 | + server.sessions["sess-1"] = (acp_session, object()) # type: ignore[assignment] |
41 | 53 |
|
42 | 54 | result = await server.close_session("sess-1") |
43 | 55 |
|
44 | 56 | assert result is None |
45 | 57 | assert "sess-1" not in server.sessions |
46 | | - # Closing an unknown session is a no-op (must not raise). |
| 58 | + acp_session.cancel.assert_awaited_once() |
| 59 | + cli.cleanup_runtime_resources.assert_awaited_once() |
| 60 | + |
| 61 | + |
| 62 | +async def test_close_session_unknown_is_noop(): |
| 63 | + """Closing an unknown session must be a no-op (no raise, no cleanup).""" |
| 64 | + server = ACPServer() |
| 65 | + |
47 | 66 | assert await server.close_session("missing") is None |
0 commit comments