Repository navigation
Conversation
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Adopted handles need a non-mutating mode to avoid create/truncate behavior, with coverage for those modes.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 1
What changed in this PR
Updates FileStreamFactoryMock to adopt SafeFileHandle instances without acquiring a second file share.
Changes:
- Centralizes handle overloads through one helper.
- Adds adopted-handle behavior bypassing new share registration.
- Adds Windows-simulation tests for sharing and async behavior.
| File | Summary |
|---|---|
Tests/Testably.Abstractions.Testing.Tests/FileSystem/FileStreamFactoryMockTests.AdoptHandle.cs |
Tests handle adoption across overloads, sharing, and async behavior. |
Source/Testably.Abstractions.Testing/FileSystem/FileStreamMock.cs |
Supports streams that do not acquire a new share. |
Source/Testably.Abstractions.Testing/FileSystem/FileStreamFactoryMock.cs |
Centralizes handle-based stream creation. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| safeFileHandleMock.Mode, | ||
| access, | ||
| safeFileHandleMock.Share, |
A real `FileStream` constructed from a `SafeFileHandle` adopts it: the file is not opened again, no new file share is taken, and the stream can never conflict with whatever already holds the file open. `FileStreamFactoryMock` resolved the handle to a path and opened that path again, taking a fresh share, so layering a stream on a handle could fail with a sharing violation where the real file system succeeds. All three handle overloads now open without taking a share. The existing `ignoreFileShare` parameter was not used for this: it is inert on Windows and three call sites in `InMemoryStorage` depend on its current meaning. Fixes Testably#1086 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
8f275a2 to
88f7fd0
Compare
|
Trimmed the comments here after your note on #1091: the same explanation appeared twice, once as No behaviour change; CI was green before and the diff is comment-only. |
|
No code change — correcting the verification note in the description. It quoted Debug numbers, and Debug leaves the real file system out of the test matrix: |
|
Closing this, since it is covered by what shipped in 7.1.0:
Thanks, @vbreuss. |

Fixes #1086.
A real
FileStreambuilt from aSafeFileHandleadopts it — the file is not opened again and no new file share is taken — so it can never conflict with whatever already holds the file open.FileStreamFactoryMockresolved the handle to a path and opened that path again with a fresh share, so the mock could throw a sharing violation where the real file system succeeds.All three handle overloads now go through one helper that opens without taking a share, using the existing
FileHandle.Ignore.I did not use
ignoreFileSharefor this, although it looks like the obvious lever. It is inert on Windows —FileHandle.GrantAccessonly consults it insideif (!_fileSystem.Execute.IsWindows)— and three call sites inInMemoryStoragedepend on its current meaning, so widening it seemed like your call rather than a side effect of this fix. Whether that is itself a bug is noted in #1086.Tests cover all three overloads against a file already held exclusively, plus that
isAsync: truereally does produce an asynchronous stream. They simulate Windows, since that is where the file share is enforced, so they are behindCAN_SIMULATE_OTHER_OS.Independent of #1081, #1082 and #1083 — this branches from
main. I ran into the divergence there and raised it separately per your note.Run in Release, which is what puts the real file system into the test matrix:
Testably.Abstractions.Tests12075 on net8.0 and 12584 on net10.0, andTesting.Tests1313 including the five new ones. All pass.Happy to rework it however you prefer.
🤖 Generated with Claude Code