Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

namespace System.IO.Tests
{
[ActiveIssue("https://github.com/dotnet/runtime/issues/103584", TestPlatforms.Windows)]
public class Directory_Changed_Tests : FileSystemWatcherTest
{
[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

namespace System.IO.Tests
{
[ActiveIssue("https://github.com/dotnet/runtime/issues/103584", TestPlatforms.Windows)]
public class Directory_Create_Tests : FileSystemWatcherTest
{
[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

namespace System.IO.Tests
{
[ActiveIssue("https://github.com/dotnet/runtime/issues/103584", TestPlatforms.Windows)]
public class Directory_Delete_Tests : FileSystemWatcherTest
{
[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

namespace System.IO.Tests
{
[ActiveIssue("https://github.com/dotnet/runtime/issues/103584", TestPlatforms.Windows)]
public class Directory_Move_Tests : FileSystemWatcherTest
{
[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

namespace System.IO.Tests
{
[ActiveIssue("https://github.com/dotnet/runtime/issues/103584", TestPlatforms.Windows)]
public partial class Directory_NotifyFilter_Tests : FileSystemWatcherTest
{
[LibraryImport("advapi32.dll", EntryPoint = "SetNamedSecurityInfoW", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

namespace System.IO.Tests
{
[ActiveIssue("https://github.com/dotnet/runtime/issues/103584", TestPlatforms.Windows)]
public class File_Changed_Tests : FileSystemWatcherTest
{
[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

namespace System.IO.Tests
{
[ActiveIssue("https://github.com/dotnet/runtime/issues/103584", TestPlatforms.Windows)]
public class File_Create_Tests : FileSystemWatcherTest
{
[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

namespace System.IO.Tests
{
[ActiveIssue("https://github.com/dotnet/runtime/issues/103584", TestPlatforms.Windows)]
public class File_Delete_Tests : FileSystemWatcherTest
{
[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

namespace System.IO.Tests
{
[ActiveIssue("https://github.com/dotnet/runtime/issues/103584", TestPlatforms.Windows)]
public class File_Move_Tests : FileSystemWatcherTest
{
[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

namespace System.IO.Tests
{
[ActiveIssue("https://github.com/dotnet/runtime/issues/103584", TestPlatforms.Windows)]
public partial class File_NotifyFilter_Tests : FileSystemWatcherTest
{
[LibraryImport("advapi32.dll", EntryPoint = "SetNamedSecurityInfoW", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

namespace System.IO.Tests
{
[ActiveIssue("https://github.com/dotnet/runtime/issues/103584", TestPlatforms.Windows)]
public class InternalBufferSizeTests : FileSystemWatcherTest
{
Comment thread
danmoseley marked this conversation as resolved.
// FSW works by calling ReadDirectoryChanges asynchronously, processing the changes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public void FileSystemWatcher_DirectorySymbolicLink_TargetsSelf_Fails()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/103584", TestPlatforms.Windows)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/53366", TestPlatforms.Windows)]
public void FileSystemWatcher_SymbolicLink_TargetsDirectory_Create()
{
// Arrange
Expand Down Expand Up @@ -123,7 +123,7 @@ public void FileSystemWatcher_SymbolicLink_TargetsDirectory_Create_IncludeSubdir

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/70450", TestPlatforms.OSX)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/103584", TestPlatforms.Windows)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/53366", TestPlatforms.Windows)]
public void FileSystemWatcher_SymbolicLink_IncludeSubdirectories_DoNotDereferenceChildLink()
{
// Arrange
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@ public void BeginInit_PausesEnableRaisingEvents()
[Theory]
[InlineData(true)]
[InlineData(false)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/103584", TestPlatforms.Windows)]
public void EndInit_ResumesPausedEnableRaisingEvents(bool setBeforeBeginInit)
{
FileSystemWatcherTest.Execute(() =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,6 @@ public void FileSystemWatcher_IncludeSubdirectories()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/103584", TestPlatforms.Windows)]
public void FileSystemWatcher_InternalBufferSize()
{
FileSystemWatcher watcher = new FileSystemWatcher();
Expand Down Expand Up @@ -363,7 +362,6 @@ public void FileSystemWatcher_OnCreated()

[Fact]
[PlatformSpecific(TestPlatforms.OSX | TestPlatforms.Windows)] // Casing matters on Linux
[ActiveIssue("https://github.com/dotnet/runtime/issues/103584", TestPlatforms.Windows)]
public void FileSystemWatcher_OnCreatedWithMismatchedCasingGivesExpectedFullPath()
{
using (var fsw = new FileSystemWatcher(TestDirectory))
Expand Down Expand Up @@ -456,7 +454,6 @@ public void FileSystemWatcher_OnRenamed()

[Fact]
[PlatformSpecific(TestPlatforms.Windows)] // Unix FSW don't trigger on a file rename.
[ActiveIssue("https://github.com/dotnet/runtime/issues/103584", TestPlatforms.Windows)]
public void FileSystemWatcher_Windows_OnRenameGivesExpectedFullPath()
{
string file = CreateTestFile(TestDirectory, "file");
Expand Down Expand Up @@ -570,7 +567,6 @@ public void FileSystemWatcher_StopCalledOnBackgroundThreadDoesNotDeadlock()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/103584", TestPlatforms.Windows)]
public void FileSystemWatcher_WatchingAliasedFolderResolvesToRealPathWhenWatching()
{
string dir = CreateTestDirectory(TestDirectory, "dir");
Expand Down Expand Up @@ -934,7 +930,6 @@ public void SetAndGetFiltersProperty()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/103584", TestPlatforms.Windows)]
public void FileSystemWatcher_File_Delete_MultipleFilters()
{
// Check delete events against multiple filters
Expand All @@ -959,7 +954,6 @@ public void FileSystemWatcher_File_Delete_MultipleFilters()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/103584", TestPlatforms.Windows)]
public void FileSystemWatcher_Directory_Create_MultipleFilters()
{
FileSystemWatcherTest.Execute(() =>
Expand All @@ -976,15 +970,14 @@ public void FileSystemWatcher_Directory_Create_MultipleFilters()
watcher.Filters.Add(Path.GetFileName(directoryOne));
watcher.Filters.Add(Path.GetFileName(directoryTwo));

ExpectEvent(watcher, WatcherChangeTypes.Created, () => Directory.CreateDirectory(directoryOne), cleanup: null, expectedPath: directoryOne);
ExpectEvent(watcher, WatcherChangeTypes.Created, () => Directory.CreateDirectory(directoryTwo), cleanup: null, expectedPath: directoryTwo);
ExpectNoEvent(watcher, WatcherChangeTypes.Created, () => Directory.CreateDirectory(directoryThree), cleanup: null, expectedPath: directoryThree);
ExpectEvent(watcher, WatcherChangeTypes.Created, () => Directory.CreateDirectory(directoryOne), cleanup: () => Directory.Delete(directoryOne), expectedPath: directoryOne);
ExpectEvent(watcher, WatcherChangeTypes.Created, () => Directory.CreateDirectory(directoryTwo), cleanup: () => Directory.Delete(directoryTwo), expectedPath: directoryTwo);
Comment thread
danmoseley marked this conversation as resolved.
Outdated
ExpectNoEvent(watcher, WatcherChangeTypes.Created, () => Directory.CreateDirectory(directoryThree), cleanup: () => { if (Directory.Exists(directoryThree)) Directory.Delete(directoryThree); }, expectedPath: directoryThree);
}
}, maxAttempts: DefaultAttemptsForExpectedEvent, backoffFunc: (iteration) => RetryDelayMilliseconds, retryWhen: e => e is XunitException);
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/103584", TestPlatforms.Windows)]
public void FileSystemWatcher_Directory_Create_Filter_Ctor()
{
FileSystemWatcherTest.Execute(() =>
Expand All @@ -1000,15 +993,14 @@ public void FileSystemWatcher_Directory_Create_Filter_Ctor()
{
watcher.Filters.Add(Path.GetFileName(directoryTwo));

ExpectEvent(watcher, WatcherChangeTypes.Created, () => Directory.CreateDirectory(directoryOne), cleanup: null, expectedPath: directoryOne);
ExpectEvent(watcher, WatcherChangeTypes.Created, () => Directory.CreateDirectory(directoryTwo), cleanup: null, expectedPath: directoryTwo);
ExpectNoEvent(watcher, WatcherChangeTypes.Created, () => Directory.CreateDirectory(directoryThree), cleanup: null, expectedPath: directoryThree);
ExpectEvent(watcher, WatcherChangeTypes.Created, () => Directory.CreateDirectory(directoryOne), cleanup: () => Directory.Delete(directoryOne), expectedPath: directoryOne);
ExpectEvent(watcher, WatcherChangeTypes.Created, () => Directory.CreateDirectory(directoryTwo), cleanup: () => Directory.Delete(directoryTwo), expectedPath: directoryTwo);
ExpectNoEvent(watcher, WatcherChangeTypes.Created, () => Directory.CreateDirectory(directoryThree), cleanup: () => { if (Directory.Exists(directoryThree)) Directory.Delete(directoryThree); }, expectedPath: directoryThree);
}
}, maxAttempts: DefaultAttemptsForExpectedEvent, backoffFunc: (iteration) => RetryDelayMilliseconds, retryWhen: e => e is XunitException);
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/103584", TestPlatforms.Windows)]
public void FileSystemWatcher_Directory_Delete_MultipleFilters()
{
using var tempDir = new TempDirectory();
Expand All @@ -1028,7 +1020,6 @@ public void FileSystemWatcher_Directory_Delete_MultipleFilters()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/103584", TestPlatforms.Windows)]
public void FileSystemWatcher_File_Create_MultipleFilters()
{
FileSystemWatcherTest.Execute(() =>
Expand All @@ -1043,15 +1034,14 @@ public void FileSystemWatcher_File_Create_MultipleFilters()
watcher.Filters.Add(fileOne.Name);
watcher.Filters.Add(fileTwo.Name);

ExpectEvent(watcher, WatcherChangeTypes.Created, () => fileOne.Create().Dispose(), cleanup: null, expectedPath: fileOne.FullName);
ExpectEvent(watcher, WatcherChangeTypes.Created, () => fileTwo.Create().Dispose(), cleanup: null, expectedPath: fileTwo.FullName);
ExpectNoEvent(watcher, WatcherChangeTypes.Created, () => fileThree.Create().Dispose(), cleanup: null, expectedPath: fileThree.FullName);
ExpectEvent(watcher, WatcherChangeTypes.Created, () => fileOne.Create().Dispose(), cleanup: () => fileOne.Delete(), expectedPath: fileOne.FullName);
ExpectEvent(watcher, WatcherChangeTypes.Created, () => fileTwo.Create().Dispose(), cleanup: () => fileTwo.Delete(), expectedPath: fileTwo.FullName);
ExpectNoEvent(watcher, WatcherChangeTypes.Created, () => fileThree.Create().Dispose(), cleanup: () => fileThree.Delete(), expectedPath: fileThree.FullName);
}
}, maxAttempts: DefaultAttemptsForExpectedEvent, backoffFunc: (iteration) => RetryDelayMilliseconds, retryWhen: e => e is XunitException);
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsMultithreadingSupported))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/103584", TestPlatforms.Windows)]
public void FileSystemWatcher_ModifyFiltersConcurrentWithEvents()
{
FileSystemWatcherTest.Execute(() =>
Expand Down Expand Up @@ -1079,9 +1069,9 @@ public void FileSystemWatcher_ModifyFiltersConcurrentWithEvents()
thread.IsBackground = true;
thread.Start();

ExpectEvent(watcher, WatcherChangeTypes.Created, () => fileOne.Create().Dispose(), cleanup: null, expectedPath: fileOne.FullName);
ExpectEvent(watcher, WatcherChangeTypes.Created, () => fileTwo.Create().Dispose(), cleanup: null, expectedPath: fileTwo.FullName);
ExpectNoEvent(watcher, WatcherChangeTypes.Created, () => fileThree.Create().Dispose(), cleanup: null, expectedPath: fileThree.FullName);
ExpectEvent(watcher, WatcherChangeTypes.Created, () => fileOne.Create().Dispose(), cleanup: () => fileOne.Delete(), expectedPath: fileOne.FullName);
ExpectEvent(watcher, WatcherChangeTypes.Created, () => fileTwo.Create().Dispose(), cleanup: () => fileTwo.Delete(), expectedPath: fileTwo.FullName);
ExpectNoEvent(watcher, WatcherChangeTypes.Created, () => fileThree.Create().Dispose(), cleanup: () => fileThree.Delete(), expectedPath: fileThree.FullName);

cts.Cancel();
waitForThread();
Expand All @@ -1103,7 +1093,6 @@ public DangerousFileSystemWatcherTests(ITestOutputHelper output)
[PlatformSpecific(TestPlatforms.Linux)] // Reads MaxUsersWatches from Linux OS files
[OuterLoop("This test will use all available watchers and can cause failures in other concurrent tests or system processes.")]
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/103584", TestPlatforms.Windows)]
public void FileSystemWatcher_CreateManyConcurrentWatches()
{
int maxUserWatches = int.Parse(File.ReadAllText("/proc/sys/fs/inotify/max_user_watches"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ public abstract partial class FileSystemWatcherTest : FileCleanupTestBase
// going to fail the test. If we don't expect an event to occur, then we need
// to keep the timeout short, as in a successful run we'll end up waiting for
// the entire timeout specified.
public const int WaitForExpectedEventTimeout = 1000; // ms to wait for an event to happen
public const int WaitForExpectedEventTimeout = 2000; // ms to wait for an event to happen
Comment thread
danmoseley marked this conversation as resolved.
Outdated
public const int LongWaitTimeout = 50000; // ms to wait for an event that takes a longer time than the average operation
public const int SubsequentExpectedWait = 10; // ms to wait for checks that occur after the first.
public const int WaitForExpectedEventTimeout_NoRetry = 3000;// ms to wait for an event that isn't surrounded by a retry.
public const int SubsequentExpectedWait = 500; // ms to wait for checks that occur after the first.
public const int WaitForExpectedEventTimeout_NoRetry = 5000;// ms to wait for an event that isn't surrounded by a retry.
public const int WaitForUnexpectedEventTimeout = 150; // ms to wait for a non-expected event.
Comment thread
danmoseley marked this conversation as resolved.
Outdated
public const int DefaultAttemptsForExpectedEvent = 3; // Number of times an expected event should be retried if failing.
public const int DefaultAttemptsForUnExpectedEvent = 2; // Number of times an unexpected event should be retried if failing.
Expand Down Expand Up @@ -195,7 +195,12 @@ public static void ExpectEvent(FileSystemWatcher watcher, WatcherChangeTypes exp
Thread.Sleep(RetryDelayMilliseconds);
}

result = ExecuteAndVerifyEvents(newWatcher, expectedEvents, action, attemptsCompleted == attempts, expectedPaths, timeout);
// Use progressively longer timeouts on retries. The first attempt uses the base timeout
// for fast failure in normal conditions. Subsequent attempts double the timeout to tolerate
Comment thread
danmoseley marked this conversation as resolved.
Outdated
// transient delays (thread pool starvation, slow CI machines, etc.).
Comment thread
danmoseley marked this conversation as resolved.
Outdated
int effectiveTimeout = timeout * attemptsCompleted;

result = ExecuteAndVerifyEvents(newWatcher, expectedEvents, action, attemptsCompleted == attempts, expectedPaths, effectiveTimeout);

if (cleanup != null)
cleanup();
Comment thread
danmoseley marked this conversation as resolved.
Outdated
Expand Down Expand Up @@ -272,7 +277,7 @@ public static void Execute(Action test, int maxAttempts = 5, Func<int, int> back
/// <param name="action">The Action that will trigger events.</param>
/// <param name="cleanup">Optional. Undoes the action and cleans up the watcher so the test may be run again if necessary.</param>
/// <param name="expectedPath">Optional. Adds path verification to all expected events.</param>
public static void ExpectNoEvent(FileSystemWatcher watcher, WatcherChangeTypes unExpectedEvents, Action action, Action cleanup = null, string expectedPath = null, int timeout = WaitForExpectedEventTimeout)
public static void ExpectNoEvent(FileSystemWatcher watcher, WatcherChangeTypes unExpectedEvents, Action action, Action cleanup = null, string expectedPath = null, int timeout = WaitForUnexpectedEventTimeout)
{
bool result = ExecuteAndVerifyEvents(watcher, unExpectedEvents, action, false, expectedPath == null ? null : new string[] { expectedPath }, timeout);
Assert.False(result, "Expected Event occurred");
Expand Down Expand Up @@ -306,6 +311,11 @@ public static bool ExecuteAndVerifyEvents(FileSystemWatcher watcher, WatcherChan
renamed = WatchRenamed(watcher, expectedPaths);

watcher.EnableRaisingEvents = true;

// Allow the OS-specific watcher implementation to finish async startup
// (e.g., ReadDirectoryChangesW registration on Windows, inotify thread on Linux).
Thread.Sleep(50);
Comment thread
danmoseley marked this conversation as resolved.
Outdated

action();

Comment thread
danmoseley marked this conversation as resolved.
// Verify Changed
Expand Down Expand Up @@ -430,8 +440,11 @@ public static bool TryErrorEvent(FileSystemWatcher watcher, Action action, Actio
watcher.EnableRaisingEvents = true;
}

// Allow the OS-specific watcher implementation to finish async startup.
Thread.Sleep(50);

action();
result = errorOccurred.WaitOne(WaitForExpectedEventTimeout);
result = errorOccurred.WaitOne(WaitForExpectedEventTimeout * attemptsCompleted);
watcher.EnableRaisingEvents = false;
cleanup();
Comment thread
danmoseley marked this conversation as resolved.
Outdated
}
Expand Down Expand Up @@ -529,10 +542,13 @@ internal static List<FiredEvent> ExpectEvents(FileSystemWatcher watcher, int exp
bool raisingEvent = watcher.EnableRaisingEvents;
watcher.EnableRaisingEvents = true;

// Allow the OS-specific watcher implementation to finish async startup.
Thread.Sleep(50);

try
{
action();
Comment thread
danmoseley marked this conversation as resolved.
eventsOccurred.WaitOne(new TimeSpan(0, 0, 5));
eventsOccurred.WaitOne(new TimeSpan(0, 0, 10));
}
Comment thread
danmoseley marked this conversation as resolved.
finally
{
Expand Down
Loading