public void NewFileIsNoticed() { StorageManager.InTemporaryDirectory(directory => { //Given var filePath = Path.GetFullPath(Path.Combine(directory, "newfile")); var fsw = GetFileSystemWatcher(); FileSystemEventArgs fileSystemEventArgs = null; fsw.Created += (sender, args) => { fileSystemEventArgs = args; }; fsw.Start(directory); //When File.WriteAllText(filePath, "Some text"); Thread.Sleep(25); //Then fileSystemEventArgs.Should().NotBeNull(); fileSystemEventArgs.FullPath.Should().Be(filePath); }); }
private void When_buffer_overflows_it_must_discard_old_notifications_and_continue() { // Arrange const string directoryToWatch = @"c:\some"; string pathToFileToUpdateBefore = Path.Combine(directoryToWatch, "file-before.txt"); string pathToFileToUpdateAfter = Path.Combine(directoryToWatch, "file-after.txt"); FakeFileSystem fileSystem = new FakeFileSystemBuilder() .IncludingEmptyFile(pathToFileToUpdateBefore) .IncludingEmptyFile(pathToFileToUpdateAfter) .Build(); var lockObject = new object(); bool isAfterBufferOverflow = false; FileSystemEventArgs firstChangeArgsAfterBufferOverflow = null; int changeCount = 0; int sleepCount = 0; using (FakeFileSystemWatcher watcher = fileSystem.ConstructFileSystemWatcher(directoryToWatch)) { watcher.NotifyFilter = TestNotifyFilters.All; watcher.InternalBufferSize = 1; watcher.Changed += (sender, args) => { lock (lockObject) { // ReSharper disable once AccessToModifiedClosure if (!isAfterBufferOverflow) { // Block the change handler shortly, allowing the buffer to fill and overflow. Do not block // the handler indefinitely, because that would prevent the error handler from getting raised. Thread.Sleep(250); Interlocked.Increment(ref sleepCount); } else { // Capture the first args after buffer overflow, so we can assert on main thread. if (firstChangeArgsAfterBufferOverflow == null) { firstChangeArgsAfterBufferOverflow = args; } } } }; watcher.Error += (sender, args) => { lock (lockObject) { if (args.GetException() is InternalBufferOverflowException) { isAfterBufferOverflow = true; } } }; watcher.EnableRaisingEvents = true; DateTime startTime = DateTime.UtcNow; bool timedOut = false; // Act (cause buffer to overflow) while (!timedOut) { lock (lockObject) { if (!isAfterBufferOverflow) { for (int index = 0; index < 400; index++) { fileSystem.File.SetCreationTimeUtc(pathToFileToUpdateBefore, 1.January(2001)); Interlocked.Increment(ref changeCount); } } else { break; } } timedOut = startTime + TimeSpan.FromSeconds(10) <= DateTime.UtcNow; } timedOut.Should().BeFalse($"Timeout in test: changeCount={changeCount}, sleepCount={sleepCount}."); lock (lockObject) { isAfterBufferOverflow = true; } // Wait for watcher to flush its queue. Thread.Sleep(MaxTestDurationInMilliseconds); // Extra event after buffer overflow, which should be processed normally. fileSystem.File.SetCreationTimeUtc(pathToFileToUpdateAfter, 1.January(2001)); watcher.FinishAndWaitForFlushed(MaxTestDurationInMilliseconds); } lock (lockObject) { // Assert firstChangeArgsAfterBufferOverflow.Should().NotBeNull(); firstChangeArgsAfterBufferOverflow.Name.Should().Be("file-after.txt"); } }