Skip to content

MockFileSystem Directory.EnumerateFiles returns incorrect results, based on input pattern. #596

Description

@pianomanjh

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`

Activity

  1. fgreinacher commented on Jun 12, 2020

    @fgreinacher
    Contributor

    Thanks for reporting! Am I right assuming result.rreq.001.afd is a file (rather than a directory)?

  2. added
    state: ready to pickIssues that are ready for being worked on
    and removed on Jun 12, 2020
  3. pianomanjh commented on Jun 15, 2020

    @pianomanjh
    ContributorAuthor

    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`
    
  4. fgreinacher commented on Jun 16, 2020

    @fgreinacher
    Contributor

    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")
    }));
  5. fgreinacher commented on Jun 16, 2020

    @fgreinacher
    Contributor

    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")
    }));
  6. fgreinacher commented on Jun 18, 2020

    @fgreinacher
    Contributor

    @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
    
  7. added
    state: in workIssues that are currently worked on
    and removed
    state: ready to pickIssues that are ready for being worked on
    on Jun 18, 2020
  8. pianomanjh commented on Jun 18, 2020

    @pianomanjh
    ContributorAuthor

    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)

  9. fgreinacher commented on Jun 20, 2020

    @fgreinacher
    Contributor

    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.

  10. added and removed
    state: in workIssues that are currently worked on
    on Jun 20, 2020
  11. github-actions commented on Aug 20, 2020

    @github-actions

    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.

  12. github-actions commented on Oct 27, 2020

    @github-actions

    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.

  13. themcoo commented on Feb 8, 2021

    @themcoo

    There are more differences in behaviour of Directory.EnumerateFiles between mock and real file system:

    • the string path parameter is case sensitive in the mock, while in real fs it isn't
    • real file system enumerates all files for the searchPattern value of string.Empty, while mock's enumeration yields no results
  14. fgreinacher commented on Feb 9, 2021

    @fgreinacher
    Contributor

    There are more differences in behaviour of Directory.EnumerateFiles between mock and real file system:

    • the string path parameter is case sensitive in the mock, while in real fs it isn't
    • real file system enumerates all files for the searchPattern value of string.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?

  15. friketrike commented on Nov 24, 2022

    @friketrike

    Another pattern that works in the real filesystem and not on the MockFileSystem is "someDirectory\\*.txt", this includes ".\\*.txt"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions