From 3afc95abdd7dbadd5132e496e245541252c6bae4 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp <19+brynary@users.noreply.github.com> Date: Sun, 17 May 2026 02:06:57 -0700 Subject: [PATCH] test(server): isolate storage in streaming_session_turn_updates_runtime_context test (#293) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Fixes the flaky nightly release-pipeline failure observed on tag `v0.235.0-nightly.1` ([run 25975240763](https://github.com/fabro-sh/fabro/actions/runs/25975240763/job/76354137058)). - `streaming_session_turn_updates_runtime_context_without_copying_prior_history_to_turn` was using the default test server settings, which means every parallel test shares the default session storage directory (`$HOME/.fabro/storage`). - `session_store::write_json` writes via `fs::write`, which truncates the file before writing. A concurrent reader from another test's `AppState` session lookup can observe the empty file mid-write and fail to deserialize. The deserialization error bubbled up as a `turn.failed` SSE event carrying `Serialization error: EOF while parsing a value at line 1 column 0`. - Apply the same isolation pattern used in `e9387bf62` for `interrupt_active_session_turn_cancels_runtime_and_persists_interrupted`: give this test its own storage root under `std::env::temp_dir()`. ## Test plan - [x] `cargo nextest run -p fabro-server -- streaming_session_turn` passes locally - [x] `cargo nextest run -p fabro-server` (full suite, 552 tests) passes locally - [x] `cargo +nightly-2026-04-14 clippy -p fabro-server --all-targets -- -D warnings` clean - [ ] CI green 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) --- lib/crates/fabro-server/src/server/tests.rs | 34 +++++++++++++++------ 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/lib/crates/fabro-server/src/server/tests.rs b/lib/crates/fabro-server/src/server/tests.rs index e4ab4d210..cb2225375 100644 --- a/lib/crates/fabro-server/src/server/tests.rs +++ b/lib/crates/fabro-server/src/server/tests.rs @@ -2529,15 +2529,31 @@ async fn streaming_session_turn_updates_runtime_context_without_copying_prior_hi }) .await; let openai_base_url = llm.url("/v1"); - let state = test_app_state_with_env_lookup( - default_test_server_settings(), - RunLayer::default(), - 5, - move |name| match name { - "OPENAI_BASE_URL" => Some(openai_base_url.clone()), - _ => None, - }, - ); + // Use an isolated storage root so parallel tests do not race on the + // shared default session storage directory. `session_store` writes + // `session.json` via `fs::write`, which truncates before writing; a + // concurrent reader can observe the empty file and fail to deserialize. + let storage_dir = std::env::temp_dir().join(format!("fabro-server-test-{}", Ulid::new())); + std::fs::create_dir_all(&storage_dir).expect("test storage dir should be creatable"); + let server_settings = server_settings_from_toml(&format!( + r#" +_version = 1 + +[server.storage] +root = "{}" + +[server.auth] +methods = ["dev-token"] +"#, + storage_dir.display() + )); + let state = + test_app_state_with_env_lookup(server_settings, RunLayer::default(), 5, move |name| { + match name { + "OPENAI_BASE_URL" => Some(openai_base_url.clone()), + _ => None, + } + }); state .vault .write()