Skip to content

Fix flaky File_Move_Multiple_From_Watched_To_Unwatched_Mac test caused by duplicate FSEvents#125779

Open
Copilot wants to merge 2 commits intomainfrom
copilot/fix-file-move-tests
Open

Fix flaky File_Move_Multiple_From_Watched_To_Unwatched_Mac test caused by duplicate FSEvents#125779
Copilot wants to merge 2 commits intomainfrom
copilot/fix-file-move-tests

Conversation

Copy link
Contributor

Copilot AI commented Mar 19, 2026

Description

macOS FSEvents can deliver duplicate Deleted events when moving files/directories from a watched to an unwatched directory. The existing isFilteredOut filter (Mac path, skipOldEvents=true) only discarded stale Created/Changed events—not duplicate Deleted events—causing ExpectEvents to signal completion prematurely and collect an extra event:

Expected: [Deleted file0, Deleted file1]
Actual:   [Deleted file0, Deleted file0, Deleted file1]

Changes:

  • FileSystemWatcher.File.Move.cs / FileSystemWatcher.Directory.Move.cs: When skipOldEvents=true, replace the single-line lambda isFilteredOut with a ConcurrentDictionary<FiredEvent, bool>-backed deduplicator. TryAdd is atomic: first occurrence passes through, subsequent duplicates of the same (EventType, Path) are filtered out.

Changes

  • Modified FileMove_Multiple_FromWatchedToUnwatched and DirectoryMove_Multiple_FromWatchedToUnwatched to deduplicate events via ConcurrentDictionary.TryAdd in addition to the existing stale-event filtering.

Testing

Existing tests cover the changed paths. The fix directly addresses the observed failure mode (duplicate Deleted events inflating the collected event list).

Original prompt

This section details on the original issue you should resolve

<issue_title>System.IO.Tests.File_Move_Tests.File_Move_Multiple_From_Watched_To_Unwatched_Mac test failure</issue_title>
<issue_description>```
Discovered: System.IO.FileSystem.Watcher.Tests (found 166 of 210 test cases)
Starting: System.IO.FileSystem.Watcher.Tests (parallel test collections = on [6 threads], stop on fail = off)
System.IO.Tests.File_Move_Tests.File_Move_Multiple_From_Watched_To_Unwatched_Mac(filesCount: 2) [FAIL]
Assert.Equal() Failure: Collections differ
↓ (pos 1)
Expected: ArraySelectIterator<<>f__AnonymousType1<string, string>, FiredEvent> [Deleted /tmp/helix/working/9FEF0885/t/#File_Move_Tests_r5rmsjek.mw5/dir_watched/file0 , Deleted /tmp/helix/working/9FEF0885/t/#File_Move_Tests_r5rmsjek.mw5/dir_watched/file1 ]
Actual: List [Deleted /tmp/helix/working/9FEF0885/t/#File_Move_Tests_r5rmsjek.mw5/dir_watched/file0 , Deleted /tmp/helix/working/9FEF0885/t/#File_Move_Tests_r5rmsjek.mw5/dir_watched/file0 , Deleted /tmp/helix/working/9FEF0885/t/#File_Move_Tests_r5rmsjek.mw5/dir_watched/file1 ]
↑ (pos 1)
Stack Trace:
//src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.File.Move.cs(234,0): at System.IO.Tests.File_Move_Tests.FileMove_Multiple_FromWatchedToUnwatched(Int32 filesCount, Boolean skipOldEvents)
/
/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.File.Move.cs(48,0): at System.IO.Tests.File_Move_Tests.File_Move_Multiple_From_Watched_To_Unwatched_Mac(Int32 filesCount)
at System.Object.InvokeStub_File_Move_Tests.File_Move_Multiple_From_Watched_To_Unwatched_Mac(Object, Span`1)
/_/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBaseInvoker.cs(95,0): at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
System.IO.Tests.FileSystemWatcherTests_netstandard17.DroppedWatcher_Collectible [SKIP]
Condition(s) not met: "IsPreciseGcSupported"
Finished: System.IO.FileSystem.Watcher.Tests


## Build Information
Build: https://dev.azure.com/dnceng-public/cbb18261-c48f-4abb-8651-8cdcb5474649/_build/results?buildId=1314668
Build error leg or test failing: System.IO.Tests.File_Move_Tests.File_Move_Multiple_From_Watched_To_Unwatched_Mac
Pull request: https://github.com/dotnet/runtime/pull/125014
<!-- Error message template  -->
## Error Message

Fill the error message using [step by step known issues guidance](https://github.com/dotnet/arcade/blob/main/Documentation/Projects/Build%20Analysis/KnownIssueJsonStepByStep.md).

<!-- Use ErrorMessage for String.Contains matches. Use ErrorPattern for regex matches (single line/no backtracking). Set BuildRetry to `true` to retry builds with this error. Set ExcludeConsoleLog to `true` to skip helix logs analysis. -->

```json
{
  "ErrorMessage": "",
  "ErrorPattern": "System.IO.Tests.File_Move_Tests.File_Move_Multiple_From_Watched_To_Unwatched_Mac.*FAIL",
  "BuildRetry": false,
  "ExcludeConsoleLog": false
}

Known issue validation

Build: 🔎 https://dev.azure.com/dnceng-public/public/_build/results?buildId=1314668
Error message validated: [System.IO.Tests.File_Move_Tests.File_Move_Multiple_From_Watched_To_Unwatched_Mac.*FAIL]
Result validation: ✅ Known issue matched with the provided build.
Validation performed at: 3/1/2026 12:32:32 AM UTC

Report

Build Definition Test Pull Request
1338073 dotnet/runtime System.IO.Tests.File_Move_Tests.File_Move_Multiple_From_Watched_To_Unwatched_Mac #125634
1330792 dotnet/runtime System.IO.Tests.File_Move_Tests.File_Move_Multiple_From_Watched_To_Unwatched_Mac #125283
1324517 dotnet/runtime [System.IO.Tests.File_Move_Tests.File_Move_Multiple_From_Watched_To_Unwatc...

🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

…duplicating FSEvents on Mac

On macOS, FSEvents can deliver duplicate Deleted events when moving
files/directories from a watched to an unwatched directory. The
existing isFilteredOut filter only handles stale Created/Changed
events, but not duplicate Deleted events.

Fix by using a ConcurrentDictionary to track seen events and filter
out duplicates when skipOldEvents=true (the Mac code path).

Co-authored-by: jtschuster <36744439+jtschuster@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix File_Move_Multiple_From_Watched_To_Unwatched_Mac test failure Fix flaky File_Move_Multiple_From_Watched_To_Unwatched_Mac test caused by duplicate FSEvents Mar 19, 2026
Copilot AI requested a review from jtschuster March 19, 2026 16:52
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-io
See info in area-owners.md if you want to be subscribed.

@jtschuster jtschuster marked this pull request as ready for review March 19, 2026 17:33
Copilot AI review requested due to automatic review settings March 19, 2026 17:33
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a macOS-specific flakiness in System.IO.FileSystem.Watcher move tests by preventing duplicate FSEvents Deleted notifications from causing ExpectEvents to complete early and record extra events.

Changes:

  • Add a ConcurrentDictionary<FiredEvent, bool>-backed deduplication filter (via TryAdd) when skipOldEvents=true.
  • Apply the same deduplication approach to both file-move and directory-move “watched → unwatched” multi-item tests on macOS.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.File.Move.cs When skipOldEvents is enabled (macOS path), filters duplicate fired events (same (EventType, Path[, OldPath])) to avoid premature completion.
src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.Directory.Move.cs Same deduplication strategy applied to directory move tests under the macOS skipOldEvents configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

System.IO.Tests.File_Move_Tests.File_Move_Multiple_From_Watched_To_Unwatched_Mac test failure

3 participants