Skip to content

fix(db): 流式缓存测试脱离 GPUI 调度器以消除调度竞态 - #231

Merged
feigeCode merged 1 commit into
devfrom
fix/db-streaming-cache-test-nondeterminism
Sep 18, 2026
Merged

feigeCode merged 1 commit into
devfrom
fix/db-streaming-cache-test-nondeterminism

Conversation

@feigeCode

Copy link
Copy Markdown
Owner

Description

CI's cargo test --all occasionally failed with

Detected activity on thread Some("tokio-rt-worker"), but test scheduler is running on Some("manager::tests::failed_transactional_streaming_conservatively_invalidates_connection_cache")
... Your test is not deterministic.

in db::manager::tests::failed_transactional_streaming_conservatively_invalidates_connection_cache (1300 passed; 1 failed).

Root cause. GlobalDbState::execute_streaming_cancellable hands the request to Tokio with Tokio::spawn(cx, request.run()), and Tokio::spawn (crates/core/src/gpui_tokio.rs) wraps that join handle in cx.background_spawn(...). When the request completes on a tokio worker thread, Trailer::wake_join wakes that GPUI background task from the worker thread, so TestScheduler::schedule_background_with_priority observes activity on a foreign thread, records it via assert_correct_thread, and end_test panics after the test body already succeeded. It is a load-dependent race: the test passes locally and only trips under the fully parallel CI run.

Fix (test-side only — the production call path is unchanged). The five streaming cache tests are converted from #[gpui::test] to #[tokio::test] and now build StreamingExecutionRequest directly on a real Tokio runtime, mirroring what the production call path does, so they no longer touch the GPUI scheduler. This matches the existing repo lesson that spawned background work should be covered with a plain #[tokio::test], and the same pattern already used by cancelling_streaming_execution_drops_query_and_closes_session in this file.

cx.executor().allow_parking() was considered and rejected: it would silence the determinism detector for the whole test instead of removing the dependency on the scheduler.

Also extracted streaming_exec_opts() so the production path and the tests share one ExecOptions normalization (file sources always stream) rather than duplicating it.

Net effect: 99 insertions, 136 deletions in crates/db/src/manager.rs.

How to Test

  • cargo test -p db --lib1301 passed; 0 failed
  • rustfmt --edition 2024 --check crates/db/src/manager.rs → clean
  • cargo clippy -p db --all-targets → exit 0, no new warnings (only pre-existing too_many_arguments / let_underscore_future items in manager.rs)
  • Mutation check: flipping StreamingExecutionOutcome::Error => had_successful_progress to false inside should_conservatively_invalidate_streaming makes the converted test fail with a clean assertion error (a failed transaction after successful progress has an ambiguous final state), confirming the rewritten tests still cover the invalidation semantics.

Checklist

  • I have read the CONTRIBUTING document and followed the guidelines.
  • Reviewed the changes in this PR and confirmed AI generated code (If any) is accurate.
  • Passed cargo run for story tests related to the changes.
  • Tested macOS, Windows and Linux platforms performance (if the change is platform-specific)

execute_streaming_cancellable 通过 Tokio::spawn 把请求交给 Tokio 执行,并在
GPUI 后台执行器上等待其 JoinHandle。请求在 tokio worker 线程完成后会在该线程
唤醒这个 GPUI 后台任务,TestScheduler 将其判为
"Detected activity on thread tokio-rt-worker",并在 end_test 处报错。这 5 个流式
缓存测试因此依赖真实 Tokio 的完成时序,在 CI 全量并行下偶发失败。

改为 #[tokio::test],直接构造 StreamingExecutionRequest 在 Tokio runtime 上运行,
不再经过 GPUI 调度器;同时抽出 streaming_exec_opts 让生产路径与测试共用 options
归一化逻辑,避免测试镜像漂移。

验证:
- cargo test -p db --lib:1301 passed / 0 failed
- rustfmt --edition 2024 --check crates/db/src/manager.rs:clean
- cargo clippy -p db --all-targets:无新增告警
- 变异验证:把 transactional + Error 分支的保守失效改回 false,该测试干净断言失败
@feigeCode
feigeCode merged commit 006b240 into dev Sep 18, 2026
4 checks passed
@feigeCode
feigeCode deleted the fix/db-streaming-cache-test-nondeterminism branch September 18, 2026 11:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant