From 352a361d79af132b1c36d45e1d7300593f4b203a Mon Sep 17 00:00:00 2001 From: Frank O'Hara Date: Sun, 9 Aug 2026 08:34:32 -0600 Subject: [PATCH] test(watcher): stop dropping_handle_stops_events flaking on macOS The test asserts that no events arrive after the watcher handle is dropped, but it was also catching events queued before the drop. macOS FSEvents reports changes from shortly before the stream opened, so the `initial` write the fixture makes before starting the watcher could still be sitting in the channel, and the assertion failed with a single stray `tasks.md`. Draining the channel before the drop keeps what the test is actually for. The point is that `drop` joins the debouncer thread so the channel is inert when it returns, and that still gets asserted against the ten writes made after the drop. There is deliberately still no settling sleep after the drop, since that would hide a regression back to detached shutdown. Seen on two unrelated PRs on macos-latest within an hour, so this was blocking merges rather than being a curiosity. --- crates/lash-core/src/watcher.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/crates/lash-core/src/watcher.rs b/crates/lash-core/src/watcher.rs index ccba3bb..b596163 100644 --- a/crates/lash-core/src/watcher.rs +++ b/crates/lash-core/src/watcher.rs @@ -387,6 +387,14 @@ mod tests { let handle = start_with_debounce(root, tx, Duration::from_millis(50)).unwrap(); std::thread::sleep(Duration::from_millis(80)); + // Clear anything the watcher queued before the drop. macOS FSEvents + // reports changes from shortly before the stream opened, so the + // `initial` write above can still be sitting in the channel here, and + // the assertion below is about events caused *after* the drop. Without + // this the test failed intermittently on macOS runners with a single + // stray `tasks.md`. + drain_events(&rx, Duration::from_millis(150)); + // No settling sleep after this point on purpose: `drop` joins the // debouncer thread, so the channel must already be inert when it // returns. A sleep here would hide a regression back to detached