MockFileSystem Directory.EnumerateFiles returns incorrect results, based on input pattern.
When calling Directory.EnumerateFiles on MockFileSystem, incorrect matching occurs, that differs from the real FileSystem.
Mock FileSystem
var results = Directory.EnumerateFiles(@"c:\jobfolder\result.rreq.001.afd", "*.rreq.*.*.*");
// results has no entries
Real FileSystem
var results = Directory.EnumerateFiles(@"c:\jobfolder\result.rreq.001.afd", "*.rreq.*.*.*");
// results has the entry `c:\jobfolder\result.rreq.001.afd`
Thanks for reporting! Am I right assuming result.rreq.001.afd is a file (rather than a directory)?
my apologies, the sample is not right. Here is something more representative.
mockFileSystem.AddFile(@"c:\test\result.rreq.001.afd", MockFileData.NullObject);
var results = mockFileSystem.Directory.EnumerateFiles(@"c:\test", "*.rreq.*.*.*");
// results has no entries, but should have `c:\test\result.rreq.001.afd`
my apologies, the sample is not right. Here is something more representative.
mockFileSystem.AddFile(@"c:\test\result.rreq.001.afd", MockFileData.NullObject); var results = mockFileSystem.Directory.EnumerateFiles(@"c:\test", "*.rreq.*.*.*"); // results has no entries, but should have `c:\test\result.rreq.001.afd`
This sample does also not look correct to me, the pattern has one asterisk too much:
result.rreq.001.afd
* .rreq.* .* .*
The following test is passing:
// Arrange
var fileSystem = new MockFileSystem(new Dictionary<string, MockFileData>
{
{ XFS.Path(@"c:\test\result.rreq.001.afd"), MockFileData.NullObject }
});
// Act
var result = fileSystem.Directory.EnumerateFiles(XFS.Path(@"c:\test"), "*.rreq.*.*");
// Assert
Assert.That(result, Is.EquivalentTo(new[]
{
XFS.Path(@"c:\test\result.rreq.001.afd")
}));
Now I get the problem. It seems like the real implementation ignores the .* elements at the end. This test case also succeeds 😩
// Arrange
var fileSystem = new FileSystem();
// var fileSystem = new MockFileSystem();
// fileSystem.Directory.CreateDirectory(XFS.Path(@"c:\tmp\"));
fileSystem.File.CreateText(XFS.Path(@"c:\tmp\result.rreq.001.afd")).Close();
// Act
var result = fileSystem.Directory.EnumerateFiles(XFS.Path(@"c:\tmp"), "*.rreq.*.*.*.*.*.*.*.*.*");
// Assert
Assert.That(result, Is.EquivalentTo(new[]
{
XFS.Path(@"c:\tmp\result.rreq.001.afd")
}));
@pianomanjh Please check whether the issue goes away once you use the "correct" pattern:
mockFileSystem.AddFile(@"c:\test\result.rreq.001.afd", MockFileData.NullObject);
mockFileSystem.Directory.EnumerateFiles(@"c:\test", "*.rreq.*.*"); // one `.*` pair less
If I use a different pattern, the one you describe, the issue no longer reproduces, yes. However, using a different pattern doesn't fix the bug ;) (we need that pattern in production)
Why do you need that exact pattern? It seems wrong to me 🤔 .NET behavior seems to be much more complex than we anticipated when implementing this logic 🐙
https://github.com/dotnet/runtime/blob/cd02b0612b3c758037eac9f85faa4ec91b1fbbda/src/libraries/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemName.cs has some of the logic - we might want to reuse (parts of) it.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
There are more differences in behaviour of Directory.EnumerateFiles between mock and real file system:
- the
string pathparameter is case sensitive in the mock, while in real fs it isn't - real file system enumerates all files for the
searchPatternvalue ofstring.Empty, while mock's enumeration yields no results
There are more differences in behaviour of Directory.EnumerateFiles between mock and real file system:
- the
string pathparameter is case sensitive in the mock, while in real fs it isn't- real file system enumerates all files for the
searchPatternvalue ofstring.Empty, while mock's enumeration yields no results
Thanks for the additional input here @themcoo. Would you mind creating new issues for the problems so that we can tackle them separately?
Another pattern that works in the real filesystem and not on the MockFileSystem is "someDirectory\\*.txt", this includes ".\\*.txt"