Skip to content

Commit 538c8b2

Browse files
Your Nameclaude
andcommitted
fix(test): tolerate transient re-acquire failure in instance_lock flake
first_acquirer_succeeds_second_fails_until_first_drops flaked in CI's heavier all-languages job (panicked: "lock must be acquirable after release") but never in the lighter verify job running the identical test/code on the same runner type, and didn't reproduce locally (30/30 isolated runs, 802/802 under the identical feature set, even with ulimit -n cut to 10). try_acquire_named collapses any transient open()/try_lock_exclusive IO error into the same None a genuine "still locked" result produces, and this assertion had zero retry tolerance for that — unlike its sibling acquire_blocking_waits_for_release_then_succeeds, which already budgets 200ms/2s for the same class of timing slop. Give the final re-acquire the same tolerance instead of asserting on the first attempt. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1 parent e0ef430 commit 538c8b2

1 file changed

Lines changed: 23 additions & 1 deletion

File tree

crates/calm-core/src/db/instance_lock.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,29 @@ mod tests {
173173
);
174174

175175
drop(first);
176-
let third = try_acquire(dir.path());
176+
// A bare, single re-attempt right after `drop` has zero tolerance for
177+
// anything other than the lock itself — but `try_acquire_named`
178+
// collapses ANY `open()`/`try_lock_exclusive` error into the same
179+
// `None` a genuine "still locked" result would produce (see its doc
180+
// comment). This flaked once in CI's heavier `all-languages` job (11
181+
// extra language backends + lsp-overlay, some of which spawn real
182+
// LSP subprocesses) but never in the lighter `verify` job running
183+
// the identical test/code on the same runner type, and couldn't be
184+
// reproduced locally (30/30 in isolation, 802/802 under the
185+
// identical feature set, even with `ulimit -n` cut to 10) — most
186+
// likely a transient EMFILE from fd pressure elsewhere in that
187+
// heavier shared test binary racing this exact instant, not the
188+
// lock itself being slow to release. Retry briefly rather than
189+
// asserting on the very first attempt, matching the tolerance the
190+
// sibling `acquire_blocking_waits_for_release_then_succeeds` test
191+
// already budgets (200ms/2s) for this same class of slop.
192+
let third = (0..20).find_map(|_| {
193+
let lock = try_acquire(dir.path());
194+
if lock.is_none() {
195+
std::thread::sleep(std::time::Duration::from_millis(25));
196+
}
197+
lock
198+
});
177199
assert!(third.is_some(), "lock must be acquirable after release");
178200
}
179201

0 commit comments

Comments
 (0)