fix: resolve .NET E2E race conditions in cancellation and multi-client tests#1034
Conversation
There was a problem hiding this comment.
Pull request overview
Stabilizes .NET E2E tests by adding explicit event synchronization to avoid cross-test leakage after cancellation and to remove a race in multi-client permission propagation.
Changes:
- In
SessionTests, adds aSessionIdleEventwaiter after cancelingSendAndWaitAsyncto ensure the agent becomes idle before the test ends. - In
MultiClientTests, sets up and awaitsPermissionCompletedEventon the second client before asserting both clients observed the completed permission.
Show a summary per file
| File | Description |
|---|---|
| dotnet/test/SessionTests.cs | Adds waiting for session.idle after cancellation to prevent in-flight work leaking into the next test. |
| dotnet/test/MultiClientTests.cs | Waits for client2’s PermissionCompletedEvent before asserting, reducing a race between clients. |
Copilot's findings
- Files reviewed: 2/2 changed files
- Comments generated: 2
| // Set up wait for tool execution to start BEFORE sending | ||
| var toolStartTask = TestHelper.GetNextEventOfTypeAsync<ToolExecutionStartEvent>(session); | ||
| var sessionIdleTask = TestHelper.GetNextEventOfTypeAsync<SessionIdleEvent>(session); | ||
|
|
There was a problem hiding this comment.
sessionIdleTask is created immediately after CreateSessionAsync(). Because session events are dispatched asynchronously, this waiter can race and capture an already-queued initial session.idle from session creation/resume rather than the post-cancellation idle you intend to wait for. To make this deterministic, set up the SessionIdleEvent waiter after you’ve observed ToolExecutionStartEvent (and before calling cts.Cancel()), so it can only match the idle corresponding to this in-flight operation.
This comment has been minimized.
This comment has been minimized.
…t tests SessionTests: SendAndWait_Throws_OperationCanceledException_When_Token_Cancelled did not wait for the agent to go idle after cancellation, leaking proxy requests into subsequent tests (causing Customized_SystemMessage_Config to fail). MultiClientTests: One_Client_Approves_Permission_And_Both_See_The_Result asserted PermissionCompletedEvent on client2 immediately after session1 went idle, but event propagation to client2 is async and may not have arrived yet.
a6e33ac to
90e5214
Compare
Cross-SDK Consistency Review ✅This PR only modifies Changes reviewed:
These are .NET-specific test stability improvements. No features were added or modified, so there's nothing requiring equivalent changes in the Node.js, Python, or Go SDKs. No cross-SDK consistency issues identified.
|
Hopefully fixes two flaky .NET E2E test failures:
1.
SendAndWait_Throws_OperationCanceledException_When_Token_Cancelled→Should_Create_A_Session_With_Customized_SystemMessage_ConfigCI failure (Windows)
The cancellation test cancelled the token but never waited for the agent to go idle. The agent's in-flight
sleep 10request leaked into the proxy during the next test, hitting the wrong snapshot and causing a 500 error.Fix: Wait for
SessionIdleEventafter the cancellation assertion, and verifyAborted == true.2.
One_Client_Approves_Permission_And_Both_See_The_ResultCI failure (macOS)
SendAndWaitAsyncreturns when session1 goes idle, but client2'sPermissionCompletedEventmay not have propagated yet. The immediateAssert.Containswas a race.Fix: Set up
GetNextEventOfTypeAsync<PermissionCompletedEvent>(session2)before sending, then await it before asserting.