From cc7e455549ff3a70486db27dd6d8402625b762e9 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Mon, 8 Jun 2026 11:30:19 -0400 Subject: [PATCH] Fix flaky SessionFs workspace metadata E2E test The Should_Write_Workspace_Metadata_Via_SessionFs test waited only for workspace.yaml to exist before reading it, but the runtime creates the file (truncating to 0 bytes) before the content write completes. This let the test read an empty file and fail the session-id assertion. Wait for the expected content (not just existence) before asserting in both the .NET workspace.yaml and plan.md tests, and drop the now-redundant trailing asserts. Apply the same content-aware wait to the Python suite via its existing wait_for_content helper. Go already waits for content and Node uses an in-memory provider with atomic writes, so neither was affected. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- dotnet/test/E2E/SessionFsE2ETests.cs | 12 ++++++++---- python/e2e/test_session_fs_e2e.py | 8 ++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/dotnet/test/E2E/SessionFsE2ETests.cs b/dotnet/test/E2E/SessionFsE2ETests.cs index 1d0157658..b1b4848ad 100644 --- a/dotnet/test/E2E/SessionFsE2ETests.cs +++ b/dotnet/test/E2E/SessionFsE2ETests.cs @@ -410,8 +410,10 @@ public async Task Should_Write_Workspace_Metadata_Via_SessionFs() Assert.Contains("56", msg?.Data.Content ?? string.Empty); var workspaceYamlPath = GetStoredPath(providerRoot, session.SessionId, $"{SessionFsConfig.SessionStatePath}/workspace.yaml"); - await WaitForConditionAsync(() => File.Exists(workspaceYamlPath), TimeSpan.FromSeconds(30)); - Assert.Contains(session.SessionId, await ReadAllTextSharedAsync(workspaceYamlPath)); + await WaitForConditionAsync( + async () => File.Exists(workspaceYamlPath) + && (await ReadAllTextSharedAsync(workspaceYamlPath)).Contains(session.SessionId), + TimeSpan.FromSeconds(30)); var indexPath = GetStoredPath(providerRoot, session.SessionId, $"{SessionFsConfig.SessionStatePath}/checkpoints/index.md"); await WaitForConditionAsync(() => File.Exists(indexPath), TimeSpan.FromSeconds(30)); @@ -442,8 +444,10 @@ public async Task Should_Persist_Plan_Md_Via_SessionFs() await session.Rpc.Plan.UpdateAsync("# Test Plan\n\nThis is a test."); var planPath = GetStoredPath(providerRoot, session.SessionId, $"{SessionFsConfig.SessionStatePath}/plan.md"); - await WaitForConditionAsync(() => File.Exists(planPath), TimeSpan.FromSeconds(30)); - Assert.Contains("This is a test.", await ReadAllTextSharedAsync(planPath)); + await WaitForConditionAsync( + async () => File.Exists(planPath) + && (await ReadAllTextSharedAsync(planPath)).Contains("This is a test."), + TimeSpan.FromSeconds(30)); await session.DisposeAsync(); } diff --git a/python/e2e/test_session_fs_e2e.py b/python/e2e/test_session_fs_e2e.py index 0f71e3627..2fb99e5c4 100644 --- a/python/e2e/test_session_fs_e2e.py +++ b/python/e2e/test_session_fs_e2e.py @@ -235,9 +235,7 @@ async def test_should_write_workspace_metadata_via_sessionfs( workspace_yaml_path = provider_path( provider_root, session.session_id, f"{SESSION_STATE_PATH}/workspace.yaml" ) - await wait_for_path(workspace_yaml_path) - yaml_content = workspace_yaml_path.read_text(encoding="utf-8") - assert "id:" in yaml_content + await wait_for_content(workspace_yaml_path, "id:") # Checkpoint index should also exist index_path = provider_path( @@ -265,9 +263,7 @@ async def test_should_persist_plan_md_via_sessionfs( plan_path = provider_path( provider_root, session.session_id, f"{SESSION_STATE_PATH}/plan.md" ) - await wait_for_path(plan_path) - content = plan_path.read_text(encoding="utf-8") - assert "# Test Plan" in content + await wait_for_content(plan_path, "# Test Plan") await session.disconnect()