test(remote): a link still connecting is not forgotten with its profile

`link_alive_or_connecting` decides whether a machine entry survives its
SSH profile being deleted, and says why: the connection holds an
authenticated spec rather than a profile reference, so forgetting the
entry "would release the link under any window still attached to it".

It is two halves and only one was held. Dropping the `LinkState::Connecting`
arm left the suite green while a profile deleted mid-connect pulled the
link out from under a window that was in the middle of getting it.

That half cannot be reached by driving the app from here: opening a
remote link is GUI-only and `tty7 machine connect` reports itself
unimplemented, so the test is the entire safety net for it.

Found only after fixing the harness. A restore had failed silently
earlier — the replacement's anchor was no longer unique and the error was
suppressed — so a mutation stayed in the file and every later round was
"caught" by the leftover rather than by its own change. Re-run against a
verified-clean baseline, two of nine results reversed. The harness now
refuses to start on a dirty tree and checks the file is clean again
afterwards.
This commit is contained in:
l0ng-ai
2026-08-23 22:37:18 +08:00
parent bb73aacc7f
commit 6366ae131f
+67
View File
@@ -2115,6 +2115,73 @@ pub(crate) fn workspace_is_preempted(cx: &gpui::App, workspace: WorkspaceId) ->
mod tests {
use super::*;
/// A link still being made survives its profile being deleted.
///
/// `link_alive_or_connecting` says why: the connection holds an
/// authenticated spec, not a profile reference, so forgetting the entry
/// "would release the link under any window still attached to it" (#485).
/// Both halves matter and only one was held — dropping the
/// `LinkState::Connecting` arm left the suite green while a profile
/// deleted mid-connect pulled the link out from under a window that was
/// in the middle of getting it.
///
/// Neither half can be reached by driving the app from here: opening a
/// remote link is GUI-only, and `tty7 machine connect` says it is not
/// implemented. The test is the whole safety net.
#[gpui::test]
fn a_link_still_connecting_is_not_forgotten_with_its_profile(cx: &mut gpui::TestAppContext) {
cx.update(|cx| {
let host = HostId::from_connection_key("a-machine-under-test");
// Nothing recorded at all: there is no link to keep.
assert!(
!link_alive_or_connecting(cx, host),
"a machine with no entry has nothing to preserve"
);
let put = |cx: &mut gpui::App, state: LinkState, attempting: bool| {
let link = cx
.default_global::<RemoteLinks>()
.machines
.entry(host)
.or_insert(MachineLink {
state: LinkState::Reconnecting,
backoff: Backoff::default(),
next_attempt: None,
attempting: false,
last_error: None,
attach_sent: Default::default(),
});
link.state = state;
link.attempting = attempting;
};
// Mid-attempt, by either spelling. `attempting` is the flag the
// pump sets; `Connecting` is the state the UI reads, and they do
// not always move together.
put(cx, LinkState::Reconnecting, true);
assert!(
link_alive_or_connecting(cx, host),
"an attempt in flight holds the entry"
);
put(cx, LinkState::Connecting, false);
assert!(
link_alive_or_connecting(cx, host),
"a link being made holds it too — this is the half that was \
unheld, and losing it releases the link under a window that \
is still connecting"
);
// Settled and not attempting: nothing to protect.
put(cx, LinkState::Failed("no route".into()), false);
assert!(
!link_alive_or_connecting(cx, host),
"a failed link with no attempt in flight is forgettable"
);
});
}
#[gpui::test]
fn taking_back_marks_the_workspace_for_a_whole_rebuild(cx: &mut gpui::TestAppContext) {
cx.update(|cx| {