Closed
Labels
flag: good-first-issueIssues that are good for first time contributorsIssues that are good for first time contributorsstate: releasedIssues that are releasedIssues that are releasedtype: bugIssues that describe misbehaving functionalityIssues that describe misbehaving functionality
Description
Describe the bug
According to C#'s filesystem API, if you open a file with FileShare.None then it should not be possible to create other file streams to that file. If you do this using the "real" file system on Windows, it will throw an IOException with the message: "The process cannot access the file '-local file path-' because it is being used by another process.". But using the MockFileSystem this does not produce any error, which seems wrong.
To Reproduce
Run this code:
MockFileSystem mockFileSystem = new();
mockFileSystem.FileStream.New("SomeFile.txt", FileMode.Create, FileAccess.ReadWrite, FileShare.None); // Should cause open to fail
// mockFileSystem.File.Create("SomeFile.txt"); // Does not fail either
mockFileSystem.FileStream.New("SomeFile.txt", FileMode.Open, FileAccess.Read);
FileSystem realFileSystem = new();
realFileSystem.FileStream.New("SomeFile.txt", FileMode.Create, FileAccess.ReadWrite, FileShare.None); // Causes open to fail
// realFileSystem.File.Create("SomeFile.txt"); Also fails
realFileSystem.FileStream.New("SomeFile.txt", FileMode.Open, FileAccess.Read);Expected behavior
It should fail when creating the "open" stream on the MockFileSystem, but it does not.
Additional context
- TestableIO version: 22.0.16
- .NET: net8.0-windows
- Windows version: Microsoft Windows 11 Enterprise (10.0.22631 Build 22631)
Reacted by coursin hill
Metadata
Metadata
Assignees
Labels
flag: good-first-issueIssues that are good for first time contributorsIssues that are good for first time contributorsstate: releasedIssues that are releasedIssues that are releasedtype: bugIssues that describe misbehaving functionalityIssues that describe misbehaving functionality
Activity
vbreuss commentedon Oct 18, 2025
Thanks for reporting, @maltebp. Do you want to take over this issue?
HarrisonTCodes commentedon Oct 18, 2025
I was messing around with potential solutions to this, thought I would share one that might be useful and I got working. I pushed it up on my fork, on this branch.
I added proper handling/parsing of the
shareargs in the file stream factory methods,Then created a static hash set of opened and unshared file streams' paths (ie those that are currently open and were opened with
FileShare.None),Handled adding to this set on stream creation, and removing from it on disposal,
Then added a check in the constructor which throws a like-for-like exception with the real filesystem if a second stream is opened.
Haven't extensively tested this, and not sure if its the desired approach here - its a bit of a hack I put together quickly for experimentation in its current form. But might be useful in solving this!
maltebp commentedon Oct 24, 2025
@vbreuss I won't have time to fix it in the near future unfortunately. But if it hasn't been fixed until when I'll get the time to look at it, I might take a peek.
vbreuss commentedon Oct 25, 2025
Thanks for letting me know, @maltebp 👍
I leave the issue open, maybe someone wants to pick it up...
HarrisonTCodes commentedon Oct 25, 2025
@vbreuss If the approach in my above comment is how we want to tackle this, I'd be happy to pick this up and refine my implementation. Unsure if I'm overlooking something and open to feedback on it - I'm quite new to this package!
vbreuss commentedon Oct 30, 2025
I just had a quick glance over it and it does indeed look promising. Please ensure that it also works with concurrent access (so you should probably replace the
HashSetwith aConcurrentDictionary, as suggested in this answer on StackOverflow).I will assign this issue to you, @HarrisonTCodes
HarrisonTCodes commentedon Oct 30, 2025
Thanks @vbreuss, I will look into concurrency (thanks for the pointer) and get a PR up for this.
github-actions commentedon Nov 22, 2025
This is addressed in release v22.1.0.