public void NoopChangeTokenForFilterThatNavigatesAboveRoot() { using (var root = new DisposableFileSystem()) { using (var provider = new PhysicalFileProvider(root.RootPath)) { var token = provider.Watch(Path.Combine("a", "..", "..", root.DirectoryInfo.Name, "b")); Assert.Same(NullChangeToken.Singleton, token); } } }
public void NoopChangeTokenForNullFilter() { using (var root = new DisposableFileSystem()) { using (var provider = new PhysicalFileProvider(root.RootPath)) { var token = provider.Watch(null); Assert.Same(NullChangeToken.Singleton, token); } } }
public void TokenForWhitespaceFilters() { using (var root = new DisposableFileSystem()) { using (var provider = new PhysicalFileProvider(root.RootPath)) { var token = provider.Watch(" "); Assert.False(token.HasChanged); Assert.True(token.ActiveChangeCallbacks); } } }
public void GetFileInfoReturnsNotFoundFileInfoForRelativePathThatNavigatesAboveRoot() { using (var root = new DisposableFileSystem()) { File.Create(Path.Combine(root.RootPath, "b")); using (var provider = new PhysicalFileProvider(root.RootPath)) { var info = provider.GetFileInfo(Path.Combine("a", "..", "..", root.DirectoryInfo.Name, "b")); Assert.IsType(typeof(NotFoundFileInfo), info); } } }
public void TokensWithForwardAndBackwardSlashesAreSame() { using (var root = new DisposableFileSystem()) { using (var provider = new PhysicalFileProvider(root.RootPath)) { var token1 = provider.Watch(@"a/b\c"); var token2 = provider.Watch(@"a\b/c"); Assert.Equal(token1, token2); } } }
public void TokenIsSameForSamePathCaseInsensitive() { using (var root = new DisposableFileSystem()) { using (var provider = new PhysicalFileProvider(root.RootPath)) { var fileName = Guid.NewGuid().ToString(); var token = provider.Watch(fileName); var lowerCaseToken = provider.Watch(fileName.ToLowerInvariant()); Assert.Equal(token, lowerCaseToken); } } }
public void GetDirectoryContentsReturnsNotFoundDirectoryContentsForPathThatNavigatesAboveRoot() { using (var root = new DisposableFileSystem()) { Directory.CreateDirectory(Path.Combine(root.RootPath, "b")); using (var provider = new PhysicalFileProvider(root.RootPath)) { var contents = provider.GetDirectoryContents(Path.Combine("a", "..", "..", root.DirectoryInfo.Name, "b")); Assert.IsType(typeof(NotFoundDirectoryContents), contents); } } }
public void GetFileInfoReturnsNotFoundFileInfoForRelativePathWithEmptySegmentsThatNavigates() { using (var root = new DisposableFileSystem()) { File.Create(Path.Combine(root.RootPath, "b")); using (var provider = new PhysicalFileProvider(root.RootPath)) { var info = provider.GetFileInfo("a///../../" + root.DirectoryInfo.Name + "/b"); Assert.IsType(typeof(NotFoundFileInfo), info); } } }
public void NoopChangeTokenForAbsolutePathFilters() { using (var root = new DisposableFileSystem()) { using (var provider = new PhysicalFileProvider(root.RootPath)) { var path = Path.Combine(root.RootPath, Guid.NewGuid().ToString()); var token = provider.Watch(path); Assert.Same(NoopChangeToken.Singleton, token); } } }
public void GetFileInfoReturnsNotFoundFileInfoForFileNameStartingWithPeriod() { using (var root = new DisposableFileSystem()) { using (var provider = new PhysicalFileProvider(root.RootPath)) { var fileName = "." + Guid.NewGuid().ToString(); var filePath = Path.Combine(root.RootPath, fileName); var info = provider.GetFileInfo(fileName); Assert.IsType(typeof(NotFoundFileInfo), info); } } }
public void GetDirectoryContentsReturnsRootDirectoryContentsForEmptyPath() { using (var root = new DisposableFileSystem()) { File.Create(Path.Combine(root.RootPath, "File" + Guid.NewGuid().ToString())); Directory.CreateDirectory(Path.Combine(root.RootPath, "Dir" + Guid.NewGuid().ToString())); using (var provider = new PhysicalFileProvider(root.RootPath)) { var contents = provider.GetDirectoryContents(string.Empty); Assert.Collection(contents.OrderBy(c => c.Name), item => Assert.IsType <PhysicalDirectoryInfo>(item), item => Assert.IsType <PhysicalFileInfo>(item)); } } }
public void GetFileInfoReturnsNotFoundFileInfoForHiddenFile() { using (var root = new DisposableFileSystem()) { using (var provider = new PhysicalFileProvider(root.RootPath)) { var fileName = Guid.NewGuid().ToString(); var filePath = Path.Combine(root.RootPath, fileName); File.Create(filePath); var fileInfo = new FileInfo(filePath); File.SetAttributes(filePath, fileInfo.Attributes | FileAttributes.Hidden); var info = provider.GetFileInfo(fileName); Assert.IsType(typeof(NotFoundFileInfo), info); } } }
public async Task UsePollingFileWatcher_UseActivePolling_HasChanged_SymbolicLink_TargetChanged(bool useWildcard, bool linkWasBroken) { // Arrange using var rootOfFile = new DisposableFileSystem(); // Create file 2 first as we want to verify that the change is reported regardless of the timestamp being older. string file2Path = Path.Combine(rootOfFile.RootPath, Path.GetRandomFileName()); File.WriteAllText(file2Path, "v2.1"); string file1Path = Path.Combine(rootOfFile.RootPath, Path.GetRandomFileName()); if (!linkWasBroken) { await Task.Delay(1000); // Wait a second before writing again, see https://github.com/dotnet/runtime/issues/55951. File.WriteAllText(file1Path, "v1.1"); } using var rootOfLink = new DisposableFileSystem(); string linkName = Path.GetRandomFileName(); string linkPath = Path.Combine(rootOfLink.RootPath, linkName); File.CreateSymbolicLink(linkPath, file1Path); string filter = useWildcard ? "*" : linkName; using var provider = new PhysicalFileProvider(rootOfLink.RootPath) { UsePollingFileWatcher = true, UseActivePolling = true }; IChangeToken token = provider.Watch(filter); var tcs = new TaskCompletionSource(); token.RegisterChangeCallback(_ => { tcs.TrySetResult(); }, null); // Act - Change link target to file 2. File.Delete(linkPath); File.CreateSymbolicLink(linkPath, file2Path); // Assert - It should report the change regardless of the timestamp being older. Assert.True(tcs.Task.Wait(TimeSpan.FromSeconds(30)), $"Change event was not raised - current time: {DateTime.UtcNow:O}, file1 LastWriteTimeUtc: {File.GetLastWriteTimeUtc(file1Path):O}, file2 LastWriteTime: {File.GetLastWriteTimeUtc(file2Path):O}."); }
public void GetDirectoryContentsDoesNotReturnFileInfoForFileNameStartingWithPeriod() { using (var root = new DisposableFileSystem()) { var directoryName = Guid.NewGuid().ToString(); var directoryPath = Path.Combine(root.RootPath, directoryName); Directory.CreateDirectory(directoryPath); var fileName = "." + Guid.NewGuid().ToString(); var filePath = Path.Combine(directoryPath, fileName); File.Create(filePath); using (var provider = new PhysicalFileProvider(root.RootPath)) { var contents = provider.GetDirectoryContents(directoryName); Assert.Empty(contents); } } }
public void TokenIsSameForSamePath() { using (var root = new DisposableFileSystem()) { var fileName = Guid.NewGuid().ToString(); var fileLocation = Path.Combine(root.RootPath, fileName); using (var provider = new PhysicalFileProvider(root.RootPath)) { var fileInfo = provider.GetFileInfo(fileName); var token1 = provider.Watch(fileName); var token2 = provider.Watch(fileName); Assert.NotNull(token1); Assert.NotNull(token2); Assert.Equal(token2, token1); } } }
public void GetDirectoryContentsDoesNotReturnFileInfoForSystemFile() { using (var root = new DisposableFileSystem()) { var directoryName = Guid.NewGuid().ToString(); var directoryPath = Path.Combine(root.RootPath, directoryName); Directory.CreateDirectory(directoryPath); var fileName = Guid.NewGuid().ToString(); var filePath = Path.Combine(directoryPath, fileName); File.Create(filePath); var fileInfo = new FileInfo(filePath); File.SetAttributes(filePath, fileInfo.Attributes | FileAttributes.System); using (var provider = new PhysicalFileProvider(root.RootPath)) { var contents = provider.GetDirectoryContents(directoryName); Assert.Empty(contents); } } }
public async Task TokensNotFiredForHiddenAndSystemFiles() { using (var root = new DisposableFileSystem()) { var hiddenFileName = Guid.NewGuid().ToString(); var hiddenFilePath = Path.Combine(root.RootPath, hiddenFileName); File.Create(hiddenFilePath); var fileInfo = new FileInfo(hiddenFilePath); File.SetAttributes(hiddenFilePath, fileInfo.Attributes | FileAttributes.Hidden); var systemFileName = Guid.NewGuid().ToString(); var systemFilePath = Path.Combine(root.RootPath, systemFileName); File.Create(systemFilePath); fileInfo = new FileInfo(systemFilePath); File.SetAttributes(systemFilePath, fileInfo.Attributes | FileAttributes.System); using (var fileSystemWatcher = new MockFileSystemWatcher(root.RootPath)) { using (var physicalFilesWatcher = new PhysicalFilesWatcher(root.RootPath + Path.DirectorySeparatorChar, fileSystemWatcher, pollForChanges: false)) { using (var provider = new PhysicalFileProvider(root.RootPath, physicalFilesWatcher)) { var hiddenFiletoken = provider.Watch(Path.GetFileName(hiddenFileName)); var systemFiletoken = provider.Watch(Path.GetFileName(systemFileName)); fileSystemWatcher.CallOnChanged(new FileSystemEventArgs(WatcherChangeTypes.Changed, root.RootPath, hiddenFileName)); await Task.Delay(WaitTimeForTokenToFire); Assert.False(hiddenFiletoken.HasChanged); fileSystemWatcher.CallOnChanged(new FileSystemEventArgs(WatcherChangeTypes.Changed, root.RootPath, systemFileName)); await Task.Delay(WaitTimeForTokenToFire); Assert.False(systemFiletoken.HasChanged); } } } } }
public async Task TokenNotFiredForFileNameStartingWithPeriod() { using (var root = new DisposableFileSystem()) { using (var fileSystemWatcher = new MockFileSystemWatcher(root.RootPath)) { using (var physicalFilesWatcher = new PhysicalFilesWatcher(root.RootPath + Path.DirectorySeparatorChar, fileSystemWatcher, pollForChanges: false)) { using (var provider = new PhysicalFileProvider(root.RootPath, physicalFilesWatcher)) { var fileName = "." + Guid.NewGuid().ToString(); var token = provider.Watch(Path.GetFileName(fileName)); fileSystemWatcher.CallOnChanged(new FileSystemEventArgs(WatcherChangeTypes.Changed, root.RootPath, fileName)); await Task.Delay(WaitTimeForTokenToFire); Assert.False(token.HasChanged); } } } } }
public async Task TokenFiredOnDeletion() { using (var root = new DisposableFileSystem()) { using (var fileSystemWatcher = new MockFileSystemWatcher(root.RootPath)) { using (var physicalFilesWatcher = new PhysicalFilesWatcher(root.RootPath + Path.DirectorySeparatorChar, fileSystemWatcher, pollForChanges: false)) { using (var provider = new PhysicalFileProvider(root.RootPath, physicalFilesWatcher)) { var name = Guid.NewGuid().ToString(); var token = provider.Watch(name); fileSystemWatcher.CallOnDeleted(new FileSystemEventArgs(WatcherChangeTypes.Deleted, root.RootPath, name)); await Task.Delay(WaitTimeForTokenToFire); Assert.True(token.HasChanged); } } } } }
public async Task UsePollingFileWatcher_UseActivePolling_HasChanged_SymbolicLink_TargetDeleted(bool useWildcard) { // Arrange using var rootOfFile = new DisposableFileSystem(); string filePath = Path.Combine(rootOfFile.RootPath, Path.GetRandomFileName()); File.WriteAllText(filePath, "v1.1"); using var rootOfLink = new DisposableFileSystem(); string linkName = Path.GetRandomFileName(); string linkPath = Path.Combine(rootOfLink.RootPath, linkName); File.CreateSymbolicLink(linkPath, filePath); string filter = useWildcard ? "*" : linkName; using var provider = new PhysicalFileProvider(rootOfLink.RootPath) { UsePollingFileWatcher = true, UseActivePolling = true }; IChangeToken token = provider.Watch(filter); var tcs = new TaskCompletionSource <bool>(); token.RegisterChangeCallback(_ => { tcs.TrySetResult(true); }, null); var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30)); cts.Token.Register(() => tcs.TrySetCanceled()); // Act File.Delete(linkPath); // Assert Assert.True(await tcs.Task, $"Change event was not raised - current time: {DateTime.UtcNow:O}, file LastWriteTimeUtc: {File.GetLastWriteTimeUtc(filePath):O}."); }
public void UsePollingFileWatcher_UseActivePolling_HasChanged_SymbolicLink_TargetNotExists(bool useWildcard) { // Arrange using var rootOfLink = new DisposableFileSystem(); string linkName = Path.GetRandomFileName(); string linkPath = Path.Combine(rootOfLink.RootPath, linkName); File.CreateSymbolicLink(linkPath, "not-existent-file"); // Act using var provider = new PhysicalFileProvider(rootOfLink.RootPath) { UsePollingFileWatcher = true, UseActivePolling = true }; IChangeToken token = provider.Watch(useWildcard ? "*" : linkName); var tcs = new TaskCompletionSource(); token.RegisterChangeCallback(_ => { tcs.TrySetResult(); }, null); // Assert Assert.False(tcs.Task.Wait(TimeSpan.FromSeconds(30)), "Change event was raised when it was not expected."); }
public async Task WatcherWithPolling_ReturnsTrueForFileChangedWhenFileSystemWatcherDoesNotRaiseEvents() { using (var root = new DisposableFileSystem()) { var fileName = Path.GetRandomFileName(); var fileLocation = Path.Combine(root.RootPath, fileName); PollingFileChangeToken.PollingInterval = TimeSpan.FromMilliseconds(10); using (var fileSystemWatcher = new MockFileSystemWatcher(root.RootPath)) { using (var physicalFilesWatcher = new PhysicalFilesWatcher(root.RootPath + Path.DirectorySeparatorChar, fileSystemWatcher, pollForChanges: true)) { using (var provider = new PhysicalFileProvider(root.RootPath, physicalFilesWatcher)) { var token = provider.Watch(fileName); File.WriteAllText(fileLocation, "some-content"); await Task.Delay(WaitTimeForTokenToFire); Assert.True(token.HasChanged); } } } } }