Skip to content

Commit

Permalink
fix: copying a file throws if a file handle with ReadWrite share is…
Browse files Browse the repository at this point in the history
… open (#550)

* Fix copy access
* Adapt tests for Linux/MacOS to handle the different behaviour:
  When FileShare.Write is used for the FileStream, it throws only on Windows, but not on Linux or MacOS.
  • Loading branch information
vbreuss authored Apr 7, 2024
1 parent e504434 commit 48bc087
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public InMemoryStorage(MockFileSystem fileSystem)
throw ExceptionFactory.AccessToPathDenied(source.FullPath);
}

using (_ = sourceContainer.RequestAccess(FileAccess.ReadWrite, FileShare.None))
using (_ = sourceContainer.RequestAccess(FileAccess.Read, FileShare.ReadWrite))
{
if (overwrite &&
_containers.TryRemove(destination,
Expand Down
39 changes: 37 additions & 2 deletions Tests/Testably.Abstractions.Tests/FileSystem/File/CopyTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,37 @@ public void Copy_ShouldCopyFileWithContent(
.Which.HasContent(contents);
}

[SkippableTheory]
[InlineAutoData(FileAccess.Read, FileShare.Read)]
[InlineAutoData(FileAccess.Read, FileShare.ReadWrite)]
[InlineAutoData(FileAccess.Read, FileShare.Write)]
[InlineAutoData(FileAccess.ReadWrite, FileShare.Read)]
[InlineAutoData(FileAccess.ReadWrite, FileShare.ReadWrite)]
[InlineAutoData(FileAccess.ReadWrite, FileShare.Write)]
[InlineAutoData(FileAccess.Write, FileShare.Read)]
[InlineAutoData(FileAccess.Write, FileShare.ReadWrite)]
[InlineAutoData(FileAccess.Write, FileShare.Write)]
public void Copy_SourceAccessedWithReadShare_ShouldNotThrow(
FileAccess fileAccess,
FileShare fileShare,
string sourcePath,
string destinationPath,
string sourceContents)
{
Skip.If(Test.RunsOnWindows && fileShare == FileShare.Write);

FileSystem.Initialize().WithFile(sourcePath)
.Which(f => f.HasStringContent(sourceContents));
using (FileSystem.FileStream
.New(sourcePath, FileMode.Open, fileAccess, fileShare))
{
FileSystem.File.Copy(sourcePath, destinationPath);
}

FileSystem.File.Exists(destinationPath).Should().BeTrue();
FileSystem.File.ReadAllText(destinationPath).Should().Be(sourceContents);
}

[SkippableTheory]
[AutoData]
public void Copy_SourceIsDirectory_ShouldThrowUnauthorizedAccessException_AndNotCopyFile(
Expand All @@ -286,14 +317,18 @@ public void Copy_SourceIsDirectory_ShouldThrowUnauthorizedAccessException_AndNot
}

[SkippableTheory]
[AutoData]
[InlineAutoData(FileShare.None)]
[InlineAutoData(FileShare.Write)]
public void Copy_SourceLocked_ShouldThrowIOException(
FileShare fileShare,
string sourceName,
string destinationName)
{
Skip.If(!Test.RunsOnWindows && fileShare == FileShare.Write);

FileSystem.File.WriteAllText(sourceName, null);
using FileSystemStream stream = FileSystem.File.Open(sourceName, FileMode.Open,
FileAccess.Read, FileShare.None);
FileAccess.Read, fileShare);

Exception? exception = Record.Exception(() =>
{
Expand Down

0 comments on commit 48bc087

Please sign in to comment.