test: harden two load-sensitive tests against CPU oversubscription#85
test: harden two load-sensitive tests against CPU oversubscription#85leszek3737 wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Sorry @leszek3737, your pull request is larger than the review limit of 150000 diff characters
There was a problem hiding this comment.
Code Review
This pull request refactors the input event dispatching layer by introducing an EventContext struct to consolidate multiple mutable state arguments, cleans up the public API surface in src/lib.rs, and optimizes various UI and helper components, such as caching function bar cells in a thread-local storage. Feedback on the changes suggests using recv_timeout with a generous timeout instead of an indefinite blocking recv() in the viewer tests to prevent potential hangs in CI/CD pipelines.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| done_rx | ||
| .recv_timeout(std::time::Duration::from_secs(TEST_CHANNEL_TIMEOUT_SECS)) | ||
| .unwrap(); | ||
| .recv() | ||
| .expect("worker should send done after observing cancel"); |
There was a problem hiding this comment.
Using an indefinite blocking recv() in tests can cause the entire test suite to hang indefinitely in CI/CD pipelines if the worker thread panics or fails to send the cancellation signal. To prevent potential test hangs while remaining robust against CPU starvation, consider using recv_timeout with a generous timeout (e.g., 5 seconds).
| done_rx | |
| .recv_timeout(std::time::Duration::from_secs(TEST_CHANNEL_TIMEOUT_SECS)) | |
| .unwrap(); | |
| .recv() | |
| .expect("worker should send done after observing cancel"); | |
| done_rx | |
| .recv_timeout(std::time::Duration::from_secs(5)) | |
| .expect("worker should send done after observing cancel"); |
Greptile SummaryThis PR hardens two load-sensitive tests against CPU oversubscription — switching
Confidence Score: 4/5The two described test fixes are correct and safe; the undescribed production refactor is broadly logic-preserving but its scale warrants a careful read before merging. The test hardening changes are sound: blocking recv() is safe because a thread-panic drops done_tx making recv() return Err rather than hang, and the debug-log retry count is a reasonable defensive increase. The production refactor is clean but the undisclosed scope — opt-level=1 touching every cargo test run, removal of crate-root re-exports, and the new EventContext/AppLoop/InputOutcome abstractions — introduces surface area that a reviewer relying on the description would miss entirely. Cargo.toml (profile changes affect all contributors and CI), src/input/dialogs.rs (input trimming behavior change), src/main.rs (AppLoop/init_app_state refactor). Important Files Changed
Sequence DiagramsequenceDiagram
participant EL as Event Loop (main.rs)
participant EC as EventContext (input/mod.rs)
participant DH as dispatch_event
participant DG as handle_dialog (dialogs.rs)
Note over EL,EC: Before this PR
EL->>DH: dispatch_event(state, viewer_state, viewer_loader, image_preview_loader, running_job, terminal, size, event)
DH->>DG: handle_dialog(state, viewer_state, running_job, input, terminal_height)
Note over EL,EC: After this PR
EL->>EC: Build EventContext grouping all mutable handles
EC->>DH: "dispatch_event(&mut ctx, terminal, event)"
DH->>DG: handle_dialog(ctx, key) returns InputOutcome
Reviews (1): Last reviewed commit: "test: harden two load-sensitive tests ag..." | Re-trigger Greptile |
| # LTO + a single codegen unit let the optimizer inline across crate | ||
| # boundaries (slower link, faster/smaller binary). | ||
| [profile.release] | ||
| lto = true | ||
| codegen-units = 1 | ||
|
|
||
| # Dev: light optimization keeps TUI interaction responsive while | ||
| # preserving full debug info and fast incremental rebuilds. |
There was a problem hiding this comment.
PR scope far exceeds description
The PR title uses the test: conventional-commit prefix and the description states "production code is untouched," but 25 of 28 changed files are production code with 2000+ non-test net insertions. The actual scope includes: a new EventContext struct replacing the 7-argument dispatch_event signature, a new AppLoop struct grouping watcher/viewer state in main.rs, refactored InputOutcome enum and extracted handler functions in dialogs.rs/normal.rs, visibility narrowing of input/ submodules to pub(crate), and removal of crate-root re-exports in lib.rs. These are real behavioral and API-surface changes whose review is obscured by the description.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| # Dev: light optimization keeps TUI interaction responsive while | ||
| # preserving full debug info and fast incremental rebuilds. | ||
| [profile.dev] | ||
| opt-level = 1 |
There was a problem hiding this comment.
opt-level = 1 changes test-run semantics and build ergonomics for all contributors
cargo test uses the dev profile by default, so this immediately raises optimization for every CI and local test run. The trade-off is intentional (faster execution → fewer load-sensitive races), but it also slows incremental test compilation and can mask unoptimized-only memory-ordering bugs. AGENTS.md lists cargo test --locked in the CI gate; now every CI compilation is heavier. If the goal is faster test-binary execution, consider instead targeting the bespoke test profile ([profile.test]) so debug and test-compilation are not coupled.
| # Dev: light optimization keeps TUI interaction responsive while | |
| # preserving full debug info and fast incremental rebuilds. | |
| [profile.dev] | |
| opt-level = 1 | |
| # Dev: light optimization keeps TUI interaction responsive while | |
| # preserving full debug info and fast incremental rebuilds. | |
| # NOTE: `cargo test` uses this profile; raising opt-level here slows incremental | |
| # test-compilation. Consider `[profile.test] opt-level = 1` to scope the | |
| # trade-off to test binaries only, leaving plain debug builds unaffected. | |
| [profile.dev] | |
| opt-level = 1 |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Code Review:
|
| Check | Result |
|---|---|
cargo fmt --check |
Pass |
cargo clippy --locked --all-targets -- -D warnings |
Pass |
cargo test --locked (294 tests) |
All pass |
| Both modified tests individually | Pass |
Verdict
The actual code changes are sound and well-reasoned. The two concerns are minor (fail-fast safety net, retry effectiveness). Recommend rebasing to drop the 3 stale commits before merge — the misleading diff size is the only real blocker.
Both are test-only changes; production code is untouched. An investigation (1220 suite runs under CPU saturation, zero failures) showed the suite is deterministic under a normal single-cargo run — the "flake" seen during a parallel-agent wave was shared-worktree cargo contention, not test logic. These two latent fragilities are hardened defensively: - viewer: test_viewer_loader_drop_cancels_worker waited on a detached busy-wait (yield_now) worker with recv_timeout(1s).unwrap(); under heavy load the starved worker could miss the 1s deadline. Drop sets the cancel flag, so the worker is guaranteed to send — switch to a blocking recv() and drop the now-dead TEST_CHANNEL_TIMEOUT_SECS constant. - debug_log: log_truncates_oversized_file shares process-global LOG_FILE/CHECK_COUNTER/TEST_CACHE_HOME with concurrent production log() calls from other parallel tests. Widen the retry budget (20 -> 50) and document why the loop must not be collapsed into a single attempt.
|
Both modified tests pass. Here is my review. Code Review:
|
| Check | Result |
|---|---|
cargo fmt --check |
Pass |
cargo clippy --locked --all-targets -- -D warnings |
Pass |
test_viewer_loader_drop_cancels_worker |
Pass |
log_truncates_oversized_file |
Pass |
Verdict
Approve. The changes are sound, minimal, correctly scoped, and well-reasoned. The commit message's diagnostic methodology (1220 runs under saturation) is thorough. Project conventions are respected (inline #[cfg(test)], explanatory comments, no production code touched). The single optional improvement is a generous recv_timeout instead of an indefinite recv(), but this is a stylistic preference that does not block merge.


Both are test-only changes; production code is untouched. An investigation
(1220 suite runs under CPU saturation, zero failures) showed the suite is
deterministic under a normal single-cargo run — the "flake" seen during a
parallel-agent wave was shared-worktree cargo contention, not test logic.
These two latent fragilities are hardened defensively:
viewer: test_viewer_loader_drop_cancels_worker waited on a detached
busy-wait (yield_now) worker with recv_timeout(1s).unwrap(); under heavy
load the starved worker could miss the 1s deadline. Drop sets the cancel
flag, so the worker is guaranteed to send — switch to a blocking recv()
and drop the now-dead TEST_CHANNEL_TIMEOUT_SECS constant.
debug_log: log_truncates_oversized_file shares process-global
LOG_FILE/CHECK_COUNTER/TEST_CACHE_HOME with concurrent production log()
calls from other parallel tests. Widen the retry budget (20 -> 50) and