Skip to content

e2e: fix CI hang — TUI tests send the retired q quit (now C-x C-c)#389

Merged
edwin-zvs merged 1 commit into
mainfrom
fix-restart-e2e-hang
Jun 7, 2026
Merged

e2e: fix CI hang — TUI tests send the retired q quit (now C-x C-c)#389
edwin-zvs merged 1 commit into
mainfrom
fix-restart-e2e-hang

Conversation

@edwin-zvs

Copy link
Copy Markdown
Contributor

Main's CI has hung on every run since the rename (#385) — the restart and tui_smoke e2e binaries never finish, so the Test step runs until the 6h job limit. This blocks all PRs (including #386). Diagnosed by reproducing locally (the restart binary ran 10+ min) and bisecting the CI history (everything ≤ #384 passed; everything ≥ #385 hangs).

Root cause

  • Update welcome screen quit shortcut #382 retired q as a quit key — the global quit chord is now C-x C-c (keymap.rs). key_latency.rs was updated; restart.rs + tui_smoke.rs were missed and still send(b"q").
  • The e2e config disables the orchestrator, so the TUI sits on the empty-fleet welcome screen where only C-x C-c quits. q now does nothing → the TUI never exits → wait_exit times out.
  • Tui::wait_exit leaked the child on timeout: it moved the process into a detached wait-thread, and on timeout returned without killing it. Drop can't help (self.child is already take()n), so the process leaks, the PTY reader task stays parked, and the tokio runtime can't shut down → cargo test hangs forever instead of failing.

Fix (two parts)

  1. Correctnessrestart.rs + tui_smoke.rs (×2) send \x18\x03 (C-x C-c) to quit.
  2. RobustnessTui::wait_exit grabs a clone_killer() up front and kills the child on timeout, so a TUI that won't quit becomes a fast failure, never an infinite hang. This defends against the whole class recurring (a future quit-key change can fail a test, but can't wedge CI).

Verified locally

Built the workspace, then ran both previously-hanging binaries under watchdogs:

  • restart: 3 passed (3.46s)
  • tui_smoke: 2 passed (0.57s)

Both complete in seconds with no hang. This unblocks CI for main and every open PR (e.g. #386).

CI has hung on every run since the rename (#385): the `restart` and
`tui_smoke` e2e test binaries never finish. Root cause:

- #382 retired `q` as a quit key; the global quit chord is now C-x C-c
  (keymap.rs). key_latency.rs was updated; restart.rs + tui_smoke.rs were
  not — they still `send(b"q")`.
- The e2e config disables the orchestrator, so the TUI sits on the empty-
  fleet welcome screen where only C-x C-c quits. `q` does nothing → the
  TUI never exits → `wait_exit` times out.
- `Tui::wait_exit` moved the child into a detached wait-thread and, on
  timeout, returned without killing it. `Drop` can't help (`self.child`
  is already taken), so the process leaks, the PTY reader stays parked,
  and the tokio runtime can't shut down → `cargo test` hangs forever
  instead of failing.

Fixes:
1. restart.rs + tui_smoke.rs (x2): send `\x18\x03` (C-x C-c) to quit.
2. Tui::wait_exit: grab a clone_killer() up front and kill the child on
   timeout, so a TUI that won't quit becomes a fast failure, never an
   infinite hang. Defense against this whole class recurring.

Verified locally: restart (3) + tui_smoke (2) now pass and complete in
seconds. This unblocks CI for main and all open PRs.
@edwin-zvs
edwin-zvs merged commit 1d18862 into main Jun 7, 2026
1 check passed
@edwin-zvs
edwin-zvs deleted the fix-restart-e2e-hang branch June 7, 2026 17:56
@edwin-zvs edwin-zvs mentioned this pull request Jun 16, 2026
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