private void When_changing_InternalBufferSize_on_running_watcher_it_must_discard_old_notifications_and_restart() { // Arrange const string directoryToWatch = @"c:\some"; string pathToFileToUpdate1 = Path.Combine(directoryToWatch, "file1.txt"); string pathToFileToUpdate2 = Path.Combine(directoryToWatch, "file2.txt"); FakeFileSystem fileSystem = new FakeFileSystemBuilder() .IncludingEmptyFile(pathToFileToUpdate1) .IncludingEmptyFile(pathToFileToUpdate2) .Build(); var lockObject = new object(); bool isFirstEventInvocation = true; FileSystemEventArgs argsAfterRestart = null; var resumeEventHandlerWaitHandle = new ManualResetEventSlim(false); var testCompletionWaitHandle = new ManualResetEventSlim(false); using (FakeFileSystemWatcher watcher = fileSystem.ConstructFileSystemWatcher(directoryToWatch)) { watcher.NotifyFilter = TestNotifyFilters.All; watcher.Changed += (sender, args) => { lock (lockObject) { if (isFirstEventInvocation) { // Wait for all change notifications on file1.txt and file2.txt to queue up. resumeEventHandlerWaitHandle.Wait(MaxTestDurationInMilliseconds); isFirstEventInvocation = false; } else { // After event handler for first change on file1 has completed, no additional // changes on file1.txt should be raised because they have become outdated. argsAfterRestart = args; testCompletionWaitHandle.Set(); } } }; watcher.EnableRaisingEvents = true; fileSystem.File.SetAttributes(pathToFileToUpdate1, FileAttributes.Hidden); fileSystem.File.SetAttributes(pathToFileToUpdate1, FileAttributes.ReadOnly); fileSystem.File.SetAttributes(pathToFileToUpdate1, FileAttributes.System); Thread.Sleep(SleepTimeToEnsureOperationHasArrivedAtWatcherConsumerLoop); // Act watcher.InternalBufferSize = watcher.InternalBufferSize * 2; fileSystem.File.SetAttributes(pathToFileToUpdate2, FileAttributes.Hidden); resumeEventHandlerWaitHandle.Set(); bool signaled = testCompletionWaitHandle.Wait(MaxTestDurationInMilliseconds); signaled.Should().BeTrue(); lock (lockObject) { // Assert FileSystemEventArgs argsAfterRestartNotNull = argsAfterRestart.ShouldNotBeNull(); argsAfterRestartNotNull.Name.Should().Be("file2.txt"); } } }
private void When_changing_notify_filter_on_running_watcher_it_must_discard_old_notifications_and_restart() { // Arrange const string directoryToWatch = @"c:\some"; string pathToFileToDelete1 = Path.Combine(directoryToWatch, "file1.txt"); string pathToFileToDelete2 = Path.Combine(directoryToWatch, "file2.txt"); string pathToFileToDelete3 = Path.Combine(directoryToWatch, "file3.txt"); FakeFileSystem fileSystem = new FakeFileSystemBuilder() .IncludingEmptyFile(pathToFileToDelete1) .IncludingEmptyFile(pathToFileToDelete2) .IncludingEmptyFile(pathToFileToDelete3) .Build(); var lockObject = new object(); bool isFirstEventInvocation = true; FileSystemEventArgs argsAfterRestart = null; var resumeEventHandlerWaitHandle = new ManualResetEventSlim(false); var testCompletionWaitHandle = new ManualResetEventSlim(false); using (FakeFileSystemWatcher watcher = fileSystem.ConstructFileSystemWatcher(directoryToWatch)) { watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Attributes; watcher.Deleted += (sender, args) => { lock (lockObject) { if (isFirstEventInvocation) { // Wait for delete notifications on all files to queue up. resumeEventHandlerWaitHandle.Wait(MaxTestDurationInMilliseconds); isFirstEventInvocation = false; } else { // After event handler for file1 has completed, no event for // file2 should be raised because it has become outdated. argsAfterRestart = args; testCompletionWaitHandle.Set(); } } }; watcher.EnableRaisingEvents = true; fileSystem.File.Delete(pathToFileToDelete1); fileSystem.File.Delete(pathToFileToDelete2); Thread.Sleep(SleepTimeToEnsureOperationHasArrivedAtWatcherConsumerLoop); // Act watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.DirectoryName; fileSystem.File.Delete(pathToFileToDelete3); resumeEventHandlerWaitHandle.Set(); testCompletionWaitHandle.Wait(MaxTestDurationInMilliseconds); lock (lockObject) { // Assert FileSystemEventArgs argsAfterRestartNotNull = argsAfterRestart.ShouldNotBeNull(); argsAfterRestartNotNull.Name.Should().Be("file3.txt"); } } }