-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Expand file tree
/
Copy pathtest_rpc_server_fixture.py
More file actions
97 lines (82 loc) · 3.5 KB
/
Copy pathtest_rpc_server_fixture.py
File metadata and controls
97 lines (82 loc) · 3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
"""Regression controls for the persisted-session E2E fixture's completion fence."""
from types import SimpleNamespace
from unittest.mock import AsyncMock
import pytest
from copilot.generated.session_events import AssistantMessageData
from copilot.rpc import LocalSessionMetadataValue, SessionContext
from e2e import test_rpc_server_e2e as scenario
@pytest.mark.asyncio
@pytest.mark.parametrize("disconnect_fails", [False, True])
async def test_persisted_session_fixture_observes_completion_before_save_and_cleanup(
tmp_path, monkeypatch, disconnect_fails
):
state = {}
calls = []
async def send(*args, **kwargs):
calls.append("send-without-completion")
async def send_and_wait(prompt, timeout):
assert prompt == "Record a turn for sessions.list discriminator coverage"
assert timeout == 60.0
calls.append("completed-turn")
return SimpleNamespace(
data=AssistantMessageData(
content=scenario.SYNTHETIC_TEXT, message_id="fixture-assistant"
)
)
async def save(request):
assert calls == ["completed-turn"], "persistence must follow observed turn completion"
assert request.session_id == state["session_id"]
calls.append("save")
return object()
async def listed(request):
assert calls == ["completed-turn", "save"]
return SimpleNamespace(
sessions=[
LocalSessionMetadataValue(
session_id=state["session_id"],
is_remote=False,
start_time="2026-01-01T00:00:00Z",
modified_time="2026-01-01T00:00:00Z",
context=SessionContext(cwd=state["working_directory"]),
)
]
)
async def disconnect():
calls.append("disconnect")
if disconnect_fails:
raise RuntimeError("controlled detach failure")
session = SimpleNamespace(send=send, send_and_wait=send_and_wait, disconnect=disconnect)
async def create_session(**kwargs):
state.update(kwargs)
return session
client = SimpleNamespace(
start=AsyncMock(),
stop=AsyncMock(),
create_session=create_session,
rpc=SimpleNamespace(
sessions=SimpleNamespace(
save=save,
list=listed,
find_by_prefix=AsyncMock(return_value=SimpleNamespace(session_id=None)),
find_by_task_id=AsyncMock(return_value=SimpleNamespace(session_id=None)),
get_last_for_context=AsyncMock(return_value=SimpleNamespace(session_id=None)),
get_sizes=AsyncMock(return_value=SimpleNamespace(sizes={})),
check_in_use=AsyncMock(return_value=SimpleNamespace(in_use=[])),
)
),
)
def make_client(ctx, token, **kwargs):
if "request_handler" in kwargs:
assert isinstance(kwargs["request_handler"], scenario._PersistedSessionRequestHandler)
return client
monkeypatch.setattr(scenario, "_configure_user", AsyncMock())
monkeypatch.setattr(scenario, "_make_authed_client", make_client)
run = scenario.TestRpcServer().test_should_list_find_and_inspect_persisted_session_state
ctx = SimpleNamespace(work_dir=str(tmp_path))
if disconnect_fails:
with pytest.raises(RuntimeError, match="controlled detach failure"):
await run(ctx)
else:
await run(ctx)
assert calls == ["completed-turn", "save", "disconnect"]
client.stop.assert_awaited_once()