From 640a20296853d1b45cdeafdbba408f99b6289f95 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Wed, 9 Sep 2026 22:16:51 +0200 Subject: [PATCH 1/2] Stabilize Python streaming resume E2E test Wait for the detached session lock to release before cold-resuming it from a new CLI process, avoiding a timing race in merge-queue runs. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- python/e2e/test_streaming_fidelity_e2e.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/python/e2e/test_streaming_fidelity_e2e.py b/python/e2e/test_streaming_fidelity_e2e.py index a644acb838..ee9306c4a2 100644 --- a/python/e2e/test_streaming_fidelity_e2e.py +++ b/python/e2e/test_streaming_fidelity_e2e.py @@ -5,12 +5,15 @@ import pytest from copilot import CopilotClient, RuntimeConnection +from copilot.rpc import SessionsCheckInUseRequest from copilot.session import PermissionHandler -from .testharness import E2ETestContext +from .testharness import E2ETestContext, wait_for_condition pytestmark = pytest.mark.asyncio(loop_scope="module") +RESUME_LOCK_TIMEOUT = 60.0 + class TestStreamingFidelity: async def test_should_produce_delta_events_when_streaming_is_enabled(self, ctx: E2ETestContext): @@ -70,9 +73,22 @@ async def test_should_produce_deltas_after_session_resume(self, ctx: E2ETestCont session = await ctx.client.create_session( on_permission_request=PermissionHandler.approve_all, streaming=False ) + session_id = session.session_id await session.send_and_wait("What is 3 + 6?") await session.disconnect() + async def session_lock_is_released() -> bool: + result = await ctx.client.rpc.sessions.check_in_use( + SessionsCheckInUseRequest(session_ids=[session_id]) + ) + return session_id not in result.in_use + + await wait_for_condition( + session_lock_is_released, + timeout=RESUME_LOCK_TIMEOUT, + timeout_message=f"Timed out waiting for session '{session_id}' to release its lock.", + ) + # Resume using a new client github_token = ( "fake-token-for-e2e-tests" if os.environ.get("GITHUB_ACTIONS") == "true" else None @@ -86,7 +102,7 @@ async def test_should_produce_deltas_after_session_resume(self, ctx: E2ETestCont try: session2 = await new_client.resume_session( - session.session_id, + session_id, on_permission_request=PermissionHandler.approve_all, streaming=True, ) From f24e176456c3a24a0f933d80a6f9ebdf11e037b2 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Wed, 9 Sep 2026 22:21:44 +0200 Subject: [PATCH 2/2] Cover both Python streaming resume paths Reuse the session-lock release wait before every cold-resume path in the streaming fidelity E2E test. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- python/e2e/test_streaming_fidelity_e2e.py | 28 ++++++++++++++--------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/python/e2e/test_streaming_fidelity_e2e.py b/python/e2e/test_streaming_fidelity_e2e.py index ee9306c4a2..a25957df10 100644 --- a/python/e2e/test_streaming_fidelity_e2e.py +++ b/python/e2e/test_streaming_fidelity_e2e.py @@ -15,6 +15,20 @@ RESUME_LOCK_TIMEOUT = 60.0 +async def _wait_for_session_lock_release(ctx: E2ETestContext, session_id: str) -> None: + async def session_lock_is_released() -> bool: + result = await ctx.client.rpc.sessions.check_in_use( + SessionsCheckInUseRequest(session_ids=[session_id]) + ) + return session_id not in result.in_use + + await wait_for_condition( + session_lock_is_released, + timeout=RESUME_LOCK_TIMEOUT, + timeout_message=f"Timed out waiting for session '{session_id}' to release its lock.", + ) + + class TestStreamingFidelity: async def test_should_produce_delta_events_when_streaming_is_enabled(self, ctx: E2ETestContext): session = await ctx.client.create_session( @@ -77,17 +91,7 @@ async def test_should_produce_deltas_after_session_resume(self, ctx: E2ETestCont await session.send_and_wait("What is 3 + 6?") await session.disconnect() - async def session_lock_is_released() -> bool: - result = await ctx.client.rpc.sessions.check_in_use( - SessionsCheckInUseRequest(session_ids=[session_id]) - ) - return session_id not in result.in_use - - await wait_for_condition( - session_lock_is_released, - timeout=RESUME_LOCK_TIMEOUT, - timeout_message=f"Timed out waiting for session '{session_id}' to release its lock.", - ) + await _wait_for_session_lock_release(ctx, session_id) # Resume using a new client github_token = ( @@ -142,6 +146,8 @@ async def test_should_not_produce_deltas_after_session_resume_with_streaming_dis session_id = session.session_id await session.disconnect() + await _wait_for_session_lock_release(ctx, session_id) + # Resume with streaming disabled new_client = CopilotClient( connection=RuntimeConnection.for_stdio(path=ctx.cli_path),