-
Notifications
You must be signed in to change notification settings - Fork 5
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
How to simulate File System on other platform #460
Comments
Hello @markusschaber, That's a very interesting use case, I never thought about. Currently we mostly distinguish between file systems via the
The primary goal of this library is to behave (as much as possible) the same as the real file system on the corresponding platform, so removing the attributes or relaxing some requirements, would not really be an option. Do you have any ideas, how to overcome these challenges? |
The platform identification would neet to be instance members of the MockFileSystem, instead of statically accessing the Execute class. The default values would still reflect the current platform, so everything is strictly opt-in. I had been falsely assuming that the mock implementation actually does not depend on any underlying file system code. You're right, some methods like Path would need reimplementation, so they can switch between behaviours at runtime. I guess the actual platform specific implementations could be gathered together from .NET itself (with appropriate attribution), as both projects use MIT license. As far as I can see, the SupportedOSPlatformAttribute and UnsupportedOSPlatformAttribute are just for compile time analysis - I think their diagnostics could be suppressed for the test projects. The exceptions at runtime are actually thrown by the implementation, which could emulate the platform specific behaviour instead. |
Let's talk about a possible approach:
Would you be willing to help with such a large change? |
We should have the Tests run in 4 modes: Windows, MacOS, Linux and "native" - which is the OS we're actually running on. I'm not exactly sure what's the best way to achieve this, as xUnit does not support parametrizing on the assembly/project level. The approach I use is to write the tests in an abstract class, and then create a derived class per platform, where I just inject the platform in the base class via constructor. I saw that there's quite some generated code, so maybe the multiplication could be wired into the code generator. I'll check with my employer whether I get some permission to contribute some work. |
I don't know the exact relationship between TestableIO and Testably projects. Which project would be the better place for this kind of contribution? I've been under the impression that the Testably implementation might be the more advanced and "closer" to native FS behaviour, but we now have some unit tests which pass with native Windows and Linux FS, as well as the MockFileSystem from TestableIO 20.0.15, while they fail with Testably.Abstractions.Testing 2.6.1. (I did not have time to investigate any details yet.) |
I wrote the Testably file system, because I had some requirements, that were not really feasible in the TestableIO testing helper. My main goal was to be as close as possible to the real file system, which is why all unit tests in The change you are proposing, is probably easier to implement here, even if it is still a huge change! |
I would be really interested in these failing tests. Could you create issues for them, so that I can help investigating? |
As a prerequisite to #460 refactor how to handle OS-specific use cases: - Make the `Execute` class non-static and a property of the `MockFileSystem` - Replace all calls to the `Execute` methods to use the property on the `MockFileSystem` instead - Move the [`StringComparisonMode`](https://github.com/Testably/Testably.Abstractions/blob/c42bd527e3795677136d1af787f3c5a243ff6c3f/Source/Testably.Abstractions.Testing/Storage/InMemoryLocation.cs#L9) from `InMemoryLocation` to the `Execute` class --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
As a prerequisite to #460 refactor how to handle OS-specific use cases in tests: - Make the `Test` class non-static and a property of the source-generated test classes - Replace all calls to the `Test` methods to use the property instead --------- Co-authored-by: Valentin <valentin.breuss@baur.at>
@markusschaber |
Thanks a lot. I still got no reply to my inquiry, but I intend to contribute. |
As a starting point, you can look at this commit, which adapts the tests to run against all platforms. The test run, but currently fail (probably due to the incorrect |
Sorry for keeping you hanging for so long. I now have the official permission to contribute. I'm a bit under water right now, but I'll be able to work on this soon. thanks for your patience. |
Thanks for the information. No worries 😄 |
I finished the implementation of this feature with #576.
I added a short explanation to the README.md Limitations:
@markusschaber: Could you please have a look, if this solves your use-case? |
This is addressed in release v3.2.0. |
@vbreuss Sorry for being silent so long, I've been quite busy and distracted with other problems. I'll definitely come back to this issue, but it might take one or two more weeks. |
I finally got around to test the code, and the platform abstraction part seems to work fine. I could successfully adapt our tests to run on the simulated platforms after adapting some code in our tests to consider MockFS.SimulationMode when trying to determine platform dependent behavior. I also could implement central workarounds for our failing unit tests, so they're not a blocker anymore. This allowed me to run all platform independent test cases on all simulation targets. Apparently, the MockFS still has some problems when directories are created (or renamed to) a name ending in slash or backslash, and it also doesn't throw exceptions when calling EnumerateFileSystemInfos() on a file. I stripped down our tests for some minimal repro tests below: If you're interested, I could try to prepare a fix and pull request for those problems. But so far, it seems to be a success, allowing us to test (most of) our Windows specific file handling code in the Linux based CI/CD pipeline, and the Linux specific code on the Windows develomer machines. Thank you very much! There are some other minor differences, e. G. when trying to read a directory as file, where the platforms throw different exceptions, and it seems that, sometimes, the Mock throws a different exception. Investigation pending, and low priority. I did not yet investigate our explicit platform dependent tests, which rely on implementation details like concurrent access behaviour - Windows tends to throw Exceptions when someone tries to write, move, replace or delete a file which has open file handles (or folders containing such files), while Linux doesn't. Some of our tests verify the handling of those exceptions in our code, and I did not check yet whether they can be simulated on Linux with MockFS. |
@markusschaber: Great to hear, that the solution works for you!
Yes, a pull request would be welcome.
Also here I would be interested in more details, if you can share them. There is quite some OS-dependent logic for concurrent file access in |
Hi,
As far as I can see, your mocked file system implementation supports the semantics of Windows, Linux and MacOS.
However, I could not find how to tell which semantics I want when creating an instance of the mock.
Our use case would be to test our code against a file system with Windows and MacOS semantics in the CI pipeline which currently only runs on Linux.
The text was updated successfully, but these errors were encountered: