Skip to content

Commit d00eb01

Browse files
test(lsp): tolerate slow recovery cold-start in cancel-refresh test (#255)
`broker_cancels_partial_refresh_without_poisoning_warm_client` asserts that aborting a partial refresh does not poison the broker: a subsequent refresh must spin up a clean client. On a loaded macOS CI runner the recovery client's `python3` cold-start intermittently exceeds the 3s initialize floor, surfacing a transient "initialize timed out" — a slow start, not a poisoned broker — which failed the test on two consecutive unrelated PRs (#253, #254). Retry the recovery refresh a bounded number of times (5, 50ms apart), tolerating only the transient initialize-timeout error and still failing fast on any other error. The Ready/total_errors assertions are unchanged. Co-authored-by: Claude <noreply@anthropic.com>
1 parent bc63387 commit d00eb01

1 file changed

Lines changed: 31 additions & 7 deletions

File tree

tests/hooks_lsp_suite/lsp_code_diagnostics_test.rs

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -598,13 +598,37 @@ async fn broker_cancels_partial_refresh_without_poisoning_warm_client() {
598598
let _ = handle.await;
599599

600600
std::fs::write(&script_path, fake_lsp_script()).unwrap();
601-
broker
602-
.refresh_documents(
603-
FAKE_LANGUAGE,
604-
vec![fake_document(FAKE_LANGUAGE, FAKE_PATH, "let nope")],
605-
FAKE_LSP_TIMEOUT,
606-
)
607-
.await
601+
// The property under test is that aborting a partial refresh does not
602+
// poison the broker: a *subsequent* refresh must spin up a clean client.
603+
// On a loaded CI runner the recovery client's `python3` cold-start can
604+
// exceed the initialize floor and surface a transient "initialize timed
605+
// out" — that is a slow start, not a poisoned broker — so retry the
606+
// recovery a bounded number of times before asserting.
607+
let mut recovery = None;
608+
for attempt in 0..5 {
609+
let result = broker
610+
.refresh_documents(
611+
FAKE_LANGUAGE,
612+
vec![fake_document(FAKE_LANGUAGE, FAKE_PATH, "let nope")],
613+
FAKE_LSP_TIMEOUT,
614+
)
615+
.await;
616+
match &result {
617+
Ok(()) => {
618+
recovery = Some(result);
619+
break;
620+
}
621+
Err(err) if err.to_string().contains("initialize timed out") => {
622+
recovery = Some(result);
623+
if attempt + 1 < 5 {
624+
tokio::time::sleep(std::time::Duration::from_millis(50)).await;
625+
}
626+
}
627+
Err(err) => panic!("recovery refresh failed unexpectedly: {err}"),
628+
}
629+
}
630+
recovery
631+
.expect("recovery refresh should have been attempted")
608632
.expect("next refresh should start a clean client and recover");
609633

610634
let snapshot = broker.snapshot();

0 commit comments

Comments
 (0)