Skip to content

Conversation

@riberk
Copy link
Contributor

@riberk riberk commented Oct 31, 2025

This PR introduces test helpers and new integration tests for watchers.

  • Adds a new test module containing reusable utilities (e.g., testdir(), channel(), TestWatcher, Receiver, expected()) to streamline writing and maintaining file-system event tests. I think it is the main point of an interest
  • Adds a collection of new tests covering creation, modification, renaming, deletion, hard-links, recursive directory creation and more - across multiple watcher backends (each backend has its own specific tests).
  • Adds some watcher-agnostic tests for RecommendedWatcher
  • There are no production code changes; almost all work is in test code and helpers. The only one is added fn poll_sender for the PollWatcher, but it has #[cfg(test)] either

The tests already have found bugs: #727, #729

Remark: surprisingly, poll watcher is the most flaky due to a slow file system - the file may still appear in an immediate readdir result. Because of that, I had to introduce a small helper I didn’t really want to: sleep_until.
PollWatcher tests follow the pattern watch -- do something -- wait for fs state -- detect changes -- check, which seems reliable enough.

@dfaust I think I've done it

The main point to check is test helpers in notify/src/test.rs, I tried to make it clear and simple, but I'm not sure.

The tests follow the pattern

  • creates testdir() - it is required due to macos behaviour, where the TempDir has non-canonicalized path, but we trigger it canonicalized in events
  • creates a TestWatcher + Receiver.
    • TestWatcher<W: Watcher> is a simple helper panicking on Err from watch calls
    • Receiver is a rx-part of the mpsc::channel and used to wait new events
  • calls some wait_ method on Receiver:
    • wait_ordered - wait events in the same order as its provided
    • wait_unordered - wait events in the same order as its provided
    • wait_..._exact - as above, but panics if encountered an unexpected one

The main idea to compare events is test::expect module. It introduces

  • ExpectedEvent - a helper, that can be used to PartialEq<Event>. It may be created in any way, like expected(path) matches any event with the specified path, expected(path).modify() matches an event with an equal paths and EventKind::Modify(_), expected(path).modify_content_any() matches path and Modify(Content(Any)) and so on
  • event(path) / event([path1, path2]) - fn to create expected event from something path-like (&Path, PathBuf, [&Path] etc.)
  • ExpectedState / trait ExpectedCollection are helpers to check a collection of ExpectedEvent.
    It may be ordered, may handle optional and multiple events and make well-read panic messages (The example from CI)

@riberk riberk force-pushed the main branch 3 times, most recently from c714b4d to 5746f9e Compare November 4, 2025 05:21
@riberk riberk changed the title Tests enhancement Enhance test coverage with helpers + platform-agnostic watcher tests Nov 4, 2025
@riberk riberk force-pushed the main branch 6 times, most recently from 3e1f9f8 to 286bccf Compare November 4, 2025 08:11
@riberk riberk marked this pull request as ready for review November 4, 2025 08:12
Copy link
Member

@JohnTitor JohnTitor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great hardening, thank you!

@JohnTitor JohnTitor merged commit 7658aaa into notify-rs:main Nov 5, 2025
17 checks passed
@JohnTitor JohnTitor mentioned this pull request Nov 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants