-
Notifications
You must be signed in to change notification settings - Fork 256
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
MockFileSystem.AddFile() does not update MockFileInfo.Exists #899
Comments
Edited due to the fix in the code example above
https://learn.microsoft.com/en-us/dotnet/api/system.io.fileinfo.exists?view=net-6.0#remarks |
I apologize, I pieced together an example without actually compiling it. I have corrected it. Also I don't think there's a 1-to-1 comparison here with a real filesystem because I'm talking about mock-specific behavior. In other words, a real filesystem doesn't have |
Maybe a good solution here is to create an overload of |
I am away from my machine, so I cant test, but from what I see, you are creating the FileInfi before the actual file. To my understanding, this would also happen in the real filesystem. Whenever the FileInfo is created, it caches the results. Try moving line 2 after you create the file |
It caches the results conditionally. There's a dirty flag that gets triggered in many conditions. Again if you could please check the issue I linked in my OP you would see what I'm talking about. |
Any clue when it actually is considered dirty? I believe that deleting or moving a file via a static async Task TestIt(bool checkExistenceBeforeCreation)
{
Console.WriteLine("{0} = {1}", nameof(checkExistenceBeforeCreation), checkExistenceBeforeCreation);
string fileName = Path.ChangeExtension(Guid.NewGuid().ToString(), ".txt");
FileInfo initiallyCachedFileInfo = new (fileName);
FileInfo notInitiallyCachedFileInfo = new (fileName);
Console.WriteLine("Cached exists: {0}", initiallyCachedFileInfo.Exists);
FileInfo creatingFileInfo = new (fileName);
if (checkExistenceBeforeCreation)
{
Console.WriteLine("Exists according to creator: {0}", creatingFileInfo.Exists);
}
using (StreamWriter w = creatingFileInfo.CreateText())
{
await w.WriteLineAsync("foobar").ConfigureAwait(false);
}
Console.WriteLine("File {0} was created.", fileName);
Console.WriteLine("Cached exists: {0}", initiallyCachedFileInfo.Exists);
Console.WriteLine("Non-cached exists: {0}", notInitiallyCachedFileInfo.Exists);
Console.WriteLine("Exists according to creator: {0}", creatingFileInfo.Exists);
FileInfo renewedFileInfo = new (fileName);
Console.WriteLine("Up-to-date exists: {0}", renewedFileInfo.Exists);
Console.WriteLine(new string('-', Console.WindowWidth));
}
await TestIt(false).ConfigureAwait(false);
await TestIt(true).ConfigureAwait(false); Output (note how
|
There's a lot of gaps for sure. For creation, you have to invoke |
Ouch.
Can't call |
Based on dotnet/runtime#34229, the behaviour might actually differ between .NET Framework 4.8 and .NET 6. 🤔 |
The whole thing is a mess for sure. I'm not sure what the right answer is. Ultimately I think the whole system needs to be refactored for consistency and to handle a wider range of corner cases. |
To sum it up (at least to my understanding): Other properties inherited from FileSystemInfo also have specific semantics. To get the latest value, the Refresh method must be called. To my understanding MockFileInfo.Refresh() need to be called in the above equivalent methods in this library |
That this isn't true for all methods/properties from .NET 5 any more. According to dotnet/dotnet-api-docs#4061, the docs still need to be updated.
I wonder if/how we want to support the differences between .NET Framework and .NET.
|
Similar to #822, except I'm not invoking
MockFileInfo.Create()
. I basically do this:Without the
Refresh()
,Exists
yieldsfalse
. Having peaked at the code, I don't really see an easy way to solve this. My first thought is an event subscription between the FileSystem object and any MockFileInfo / MockDirectoryInfo objects created, so that when AddFile is called, it can notify them to set their dirty flags. But I'm sure that creates other issues like circular dependencies, issues during cleanup, etc.What do you think the best solution is here?
I'm using version
17.2.3
.The text was updated successfully, but these errors were encountered: