-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Make polling use the symbolic link target's LastWriteTime #55664
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
f515710
08233ba
d780995
ac4a845
b4895ad
ebb0326
1164e33
98b737a
75fcf96
144335a
9c50a3a
b2f9bad
d8d143a
c7e28d4
5b85631
5c27cae
19dd9c3
8c1b3a2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,146 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| using System; | ||
| using System.IO; | ||
| using System.Threading; | ||
| using Microsoft.Extensions.FileProviders.Physical; | ||
| using Microsoft.Extensions.Primitives; | ||
| using Xunit; | ||
|
|
||
| namespace Microsoft.Extensions.FileProviders | ||
| { | ||
| public partial class PhysicalFileProviderTests | ||
| { | ||
| [Theory] | ||
| [InlineData(false)] | ||
| [InlineData(true)] | ||
| public void UsePollingFileWatcher_UseActivePolling_HasChanged(bool useWildcard) | ||
| { | ||
| // Arrange | ||
| using var root = new DisposableFileSystem(); | ||
| string fileName = Path.GetRandomFileName(); | ||
| string filePath = Path.Combine(root.RootPath, fileName); | ||
| File.WriteAllText(filePath, "v1.1"); | ||
|
|
||
| using var provider = new PhysicalFileProvider(root.RootPath) { UsePollingFileWatcher = true, UseActivePolling = true }; | ||
| IChangeToken token = provider.Watch(useWildcard ? "*" : fileName); | ||
| Assert.False(token.HasChanged); | ||
|
|
||
| // Act | ||
| File.WriteAllText(filePath, "v1.2"); | ||
| Thread.Sleep(GetTokenPollingInterval(token)); | ||
|
|
||
| // Assert | ||
| Assert.True(token.HasChanged); | ||
| } | ||
|
|
||
| [Theory] | ||
| [InlineData(false)] | ||
| [InlineData(true)] | ||
| public void UsePollingFileWatcher_UseActivePolling_HasChanged_SymbolicLink(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); | ||
|
|
||
| using var provider = new PhysicalFileProvider(rootOfLink.RootPath) { UsePollingFileWatcher = true, UseActivePolling = true }; | ||
| IChangeToken token = provider.Watch(useWildcard ? "*" : linkName); | ||
| Assert.False(token.HasChanged); | ||
|
|
||
| // Act | ||
| File.WriteAllText(filePath, "v1.2"); | ||
| Thread.Sleep(GetTokenPollingInterval(token)); | ||
|
|
||
| // Assert | ||
| Assert.True(token.HasChanged); | ||
| } | ||
|
|
||
| [Theory] | ||
| [InlineData(false)] | ||
| [InlineData(true)] | ||
| 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); | ||
|
|
||
| // Assert | ||
| Assert.False(token.HasChanged); | ||
| } | ||
|
|
||
| [Theory] | ||
| [InlineData(false)] | ||
| [InlineData(true)] | ||
| public void UsePollingFileWatcher_UseActivePolling_HasChanged_SymbolicLink_TargetChanged(bool useWildcard) | ||
| { | ||
| // Arrange | ||
| using var rootOfFile = new DisposableFileSystem(); | ||
| string file1Path = Path.Combine(rootOfFile.RootPath, Path.GetRandomFileName()); | ||
| File.WriteAllText(file1Path, "v1.1"); | ||
|
|
||
| string file2Path = Path.Combine(rootOfFile.RootPath, Path.GetRandomFileName()); | ||
| File.WriteAllText(file2Path, "v2.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); | ||
| Assert.False(token.HasChanged); | ||
|
|
||
| // Act 1 - Change file 1's content. | ||
| File.WriteAllText(file1Path, "v1.2"); | ||
| Thread.Sleep(GetTokenPollingInterval(token)); | ||
|
|
||
| // Assert 1 | ||
| Assert.True(token.HasChanged); | ||
|
|
||
| // Act 2 - Change link target to file 2. | ||
| token = provider.Watch(filter); // Once HasChanged is true, the value will always be true. Get a new change token. | ||
| Assert.False(token.HasChanged); | ||
| File.Delete(linkPath); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it possible to reset the target without deleting the link?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Through For Unix, I know that you can use the -f switch in
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ln.html says that |
||
| File.CreateSymbolicLink(linkPath, file2Path); | ||
| Thread.Sleep(GetTokenPollingInterval(token)); | ||
|
|
||
| // Assert 2 | ||
| Assert.True(token.HasChanged); // It should report the change regardless of the timestamp being older. | ||
|
|
||
| // Act 3 - Change file 2's content. | ||
| token = provider.Watch(filter); | ||
| Assert.False(token.HasChanged); | ||
| File.WriteAllText(file2Path, "v2.2"); | ||
| Thread.Sleep(GetTokenPollingInterval(token)); | ||
jozkee marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| // Assert 3 | ||
| Assert.True(token.HasChanged); | ||
| } | ||
|
|
||
| private int GetTokenPollingInterval(IChangeToken changeToken) | ||
| { | ||
| TimeSpan pollingInterval = (changeToken as CompositeChangeToken).ChangeTokens[1] switch | ||
| { | ||
| PollingWildCardChangeToken wildcardChangeToken => wildcardChangeToken.PollingInterval, | ||
| PollingFileChangeToken => PollingFileChangeToken.PollingInterval, | ||
| _ => throw new InvalidOperationException() | ||
| }; | ||
|
|
||
| return (int)pollingInterval.TotalMilliseconds; | ||
| } | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.