.NET: Fix abort recovery test event subscription race - #2635
Conversation
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The focused test-only changes preserve existing behavior while reliably covering the reported race.
Review tier: Balanced
Findings: None
What changed in this PR
Fixes a .NET abort-recovery E2E race by subscribing before sending the recovery prompt.
Changes:
- Uses
SendAndWaitAsyncand explicitly disposes the session. - Adds deterministic fake-RPC coverage for early and late recovery-idle ordering.
- Models idle events as ephemeral in fake history.
| File | Description |
|---|---|
dotnet/test/E2E/SessionE2ETests.cs |
Removes the recovery subscription race. |
dotnet/test/Unit/ClientSessionLifetimeTests.cs |
Adds deterministic regression coverage and fake event history. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This comment has been minimized.
This comment has been minimized.
Subscribe before sending the recovery prompt so an ephemeral session.idle cannot be lost. Exercise the shared abort scenario through the fake RPC server with events delivered before replies, retaining the original ordering and timeout budget. Co-authored-by: Copilot App <[email protected]>
d764b81 to
daedce3
Compare
SDK Consistency Review — PR #2635Scope of changes: Only 2 files were modified, both under Findings:
Conclusion: No cross-SDK consistency issues found. No action needed for other language SDKs.
|
Summary
Fix the recovery wait in
SessionE2ETests.Should_Abort_A_Session. The test previously awaitedSendAsyncbefore subscribing throughGetFinalAssistantMessageAsync. A fast recovery turn can deliversession.idlebefore that subscription; because idle is ephemeral, the helper cannot recover it fromGetEventsAsyncand times out even when the assistant message is present.Use the existing
SendAndWaitAsyncAPI to subscribe before sending. Preserve the tool-start/send/abort/aborted-idle ordering, the original 120-second timeout, and both recovery assertions. Explicitly dispose the session.Add deterministic fake-RPC coverage that exercises the same abort/recovery scenario as the E2E test. Event fences force tool-start, abort idle, and recovery messages to be processed before RPC replies; recovery idle is covered both before and after the send reply. Fake event history excludes idle.
This is a test-only change. The shared image-replay fix is separate and is not included here.
Validation
Timeout waiting for assistant message; the other case passed.net8.0(20 total).dotnet test .\dotnet\test\GitHub.Copilot.SDK.Test.csproj -f net8.0 --no-restore -p:CopilotSkipCliDownload=true -m:1 --filter "FullyQualifiedName~Abort_Recovery_Observes_Early_Events|FullyQualifiedName~SendAndWaitAsync_MessageSource_Completes_On_Idle".The lost-idle ordering is deterministically reproduced. It is consistent with the abort-test timeout seen in github/copilot-agent-runtime#19858, but that specific CI occurrence cannot be conclusively attributed without its recovery event trace. No runtime build or full E2E rerun was performed for this change.
Generated by Copilot