From 78fc49ce6252e8a45aa314b079c3720c193b3403 Mon Sep 17 00:00:00 2001 From: Leo Li Date: Sun, 18 Oct 2026 21:46:34 -0700 Subject: [PATCH] test(cmux-tui): an orphan-ended terminal respawns under a new incarnation (cx-6so.49) host_orphan's respawn check only asked for a running terminal with a surface, which an adoption of the old incarnation would also pass. It now records the incarnation before the daemon dies and waits for a new one. Co-Authored-By: Claude Opus 5.5 --- .../tests/terminal_host_recovery/host_orphan.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/cmux-tui/crates/cmux-tui/tests/terminal_host_recovery/host_orphan.rs b/cmux-tui/crates/cmux-tui/tests/terminal_host_recovery/host_orphan.rs index 3b42a3a807a6..b605bf1c7e9a 100644 --- a/cmux-tui/crates/cmux-tui/tests/terminal_host_recovery/host_orphan.rs +++ b/cmux-tui/crates/cmux-tui/tests/terminal_host_recovery/host_orphan.rs @@ -170,6 +170,13 @@ fn an_orphaned_host_exits_after_the_grace_and_a_served_one_does_not() { ); assert!(wait_for_screen(&harness.socket, surface, "still-served").contains("still-served")); + let before = request( + &harness.socket, + serde_json::json!({"cmd":"resolve-terminal","terminal_id":&terminal_id}), + ); + let incarnation = before["terminal_incarnation"].as_str().unwrap_or_default().to_string(); + assert!(!incarnation.is_empty(), "the served terminal has no incarnation: {before}"); + // Owner gone: the host ends its terminal after the grace, cleanly. let killed = Instant::now(); kill_daemon(&mut harness); @@ -192,7 +199,13 @@ fn an_orphaned_host_exits_after_the_grace_and_a_served_one_does_not() { &harness.socket, serde_json::json!({"cmd":"resolve-terminal","terminal_id":&terminal_id}), ); - if resolved["lifecycle"] == "running" && resolved["surface"].as_u64().is_some() { + // A new incarnation: the old one adopted again would also read running. + let current = resolved["terminal_incarnation"].as_str().unwrap_or_default(); + if resolved["lifecycle"] == "running" + && resolved["surface"].as_u64().is_some() + && !current.is_empty() + && current != incarnation + { break; } assert!(Instant::now() < deadline, "the orphan-ended terminal did not respawn: {resolved}");