Skip to content

Commit

Permalink
Ignore FileShare for Linux and MacOS when calling Move or Replace met…
Browse files Browse the repository at this point in the history
…hods
  • Loading branch information
vbreuss committed Apr 9, 2024
1 parent 71dba3e commit 139a94e
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ internal interface IStorageContainer : IFileSystemEntity, ITimeSystemEntity
/// <returns>An <see cref="IStorageAccessHandle" /> that is used to release the access lock on dispose.</returns>
IStorageAccessHandle RequestAccess(FileAccess access, FileShare share,
bool deleteAccess = false,
bool ignoreFileShare = false,
bool ignoreMetadataErrors = true,
int? hResult = null);

Expand Down
16 changes: 10 additions & 6 deletions Source/Testably.Abstractions.Testing/Storage/InMemoryContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,10 @@ public void Encrypt()
/// <inheritdoc cref="IStorageContainer.GetBytes()" />
public byte[] GetBytes() => _bytes;

/// <inheritdoc cref="IStorageContainer.RequestAccess(FileAccess, FileShare, bool, bool, int?)" />
/// <inheritdoc cref="IStorageContainer.RequestAccess(FileAccess, FileShare, bool, bool, bool, int?)" />
public IStorageAccessHandle RequestAccess(FileAccess access, FileShare share,
bool deleteAccess = false,
bool ignoreFileShare = false,
bool ignoreMetadataErrors = true,
int? hResult = null)
{
Expand All @@ -163,7 +164,7 @@ public IStorageAccessHandle RequestAccess(FileAccess access, FileShare share,
throw ExceptionFactory.AclAccessToPathDenied(_location.FullPath);
}

if (CanGetAccess(access, share, deleteAccess))
if (CanGetAccess(access, share, deleteAccess, ignoreFileShare))
{
Guid guid = Guid.NewGuid();
FileHandle fileHandle =
Expand Down Expand Up @@ -289,11 +290,11 @@ internal FileAttributes AdjustAttributes(FileAttributes attributes)
return attributes;
}

private bool CanGetAccess(FileAccess access, FileShare share, bool deleteAccess)
private bool CanGetAccess(FileAccess access, FileShare share, bool deleteAccess, bool ignoreFileShare)
{
foreach (KeyValuePair<Guid, FileHandle> fileHandle in _fileHandles)
{
if (!fileHandle.Value.GrantAccess(access, share, deleteAccess))
if (!fileHandle.Value.GrantAccess(access, share, deleteAccess, ignoreFileShare))
{
return false;
}
Expand Down Expand Up @@ -385,17 +386,20 @@ public void Dispose()

#endregion

public bool GrantAccess(FileAccess access, FileShare share, bool deleteAccess)
public bool GrantAccess(FileAccess access, FileShare share, bool deleteAccess, bool ignoreFileShare)
{
FileShare usedShare = share;
FileShare currentShare = Share;
_fileSystem.Execute.NotOnWindows(()
=> usedShare = FileShare.ReadWrite);
_fileSystem.Execute.NotOnWindowsIf(ignoreFileShare, ()
=> currentShare = FileShare.ReadWrite);
if (deleteAccess)
{
return !_fileSystem.Execute.IsWindows || Share == FileShare.Delete;
}

return CheckAccessWithShare(access, Share) &&
return CheckAccessWithShare(access, currentShare) &&
CheckAccessWithShare(Access, usedShare);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -409,12 +409,14 @@ public IStorageContainer GetOrCreateContainer(
using (_ = sourceContainer.RequestAccess(
FileAccess.ReadWrite,
FileShare.None,
ignoreMetadataErrors: ignoreMetadataErrors))
ignoreMetadataErrors: ignoreMetadataErrors,
ignoreFileShare: true))
{
using (_ = destinationContainer.RequestAccess(
FileAccess.ReadWrite,
FileShare.None,
ignoreMetadataErrors: ignoreMetadataErrors))
ignoreMetadataErrors: ignoreMetadataErrors,
ignoreFileShare: true))
{
if (_containers.TryRemove(destination,
out IStorageContainer? existingDestinationContainer))
Expand Down Expand Up @@ -663,7 +665,8 @@ private void CreateParents(MockFileSystem fileSystem, IStorageLocation location)
throw ExceptionFactory.DirectoryNotEmpty(_fileSystem.Execute, source.FullPath);
}

using (container.RequestAccess(FileAccess.Write, FileShare.None,
using (container.RequestAccess(FileAccess.Write, FileShare.ReadWrite,
ignoreFileShare: true,
hResult: sourceType == FileSystemTypes.Directory ? -2147024891 : -2147024864))
{
if (children.Any() && recursive)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,10 @@ public void Encrypt()
public byte[] GetBytes()
=> Array.Empty<byte>();

/// <inheritdoc cref="IStorageContainer.RequestAccess(FileAccess, FileShare, bool, bool, int?)" />
/// <inheritdoc cref="IStorageContainer.RequestAccess(FileAccess, FileShare, bool, bool, bool, int?)" />
public IStorageAccessHandle RequestAccess(FileAccess access, FileShare share,
bool deleteAccess = false,
bool ignoreFileShare = false,
bool ignoreMetadataErrors = true,
int? hResult = null)
=> new NullStorageAccessHandle(access, share, deleteAccess);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Testably.Abstractions.Testing.Tests.TestHelpers;
/// A <see cref="IStorageContainer" /> for testing purposes.
/// <para />
/// Set <see cref="IsLocked" /> to <see langword="true" /> to simulate a locked file
/// (<see cref="RequestAccess(FileAccess, FileShare, bool, bool, int?)" /> throws an <see cref="IOException" />).
/// (<see cref="RequestAccess(FileAccess, FileShare, bool, bool, bool, int?)" /> throws an <see cref="IOException" />).
/// </summary>
internal sealed class LockableContainer(
MockFileSystem fileSystem,
Expand All @@ -24,7 +24,7 @@ internal sealed class LockableContainer(

/// <summary>
/// Simulate a locked file, if set to <see langword="true" />.<br />
/// In this case <see cref="RequestAccess(FileAccess, FileShare, bool, bool, int?)" /> throws
/// In this case <see cref="RequestAccess(FileAccess, FileShare, bool, bool, bool, int?)" /> throws
/// an <see cref="IOException" />, otherwise it will succeed.
/// </summary>
public bool IsLocked { get; set; }
Expand Down Expand Up @@ -89,9 +89,10 @@ public void Encrypt()
public byte[] GetBytes()
=> _bytes;

/// <inheritdoc cref="IStorageContainer.RequestAccess(FileAccess, FileShare, bool, bool, int?)" />
/// <inheritdoc cref="IStorageContainer.RequestAccess(FileAccess, FileShare, bool, bool, bool, int?)" />
public IStorageAccessHandle RequestAccess(FileAccess access, FileShare share,
bool deleteAccess = false,
bool ignoreFileShare = false,
bool ignoreMetadataErrors = true,
int? hResult = null)
{
Expand Down

0 comments on commit 139a94e

Please sign in to comment.